Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
VPKS_v2_UKR_new.doc
Скачиваний:
21
Добавлен:
11.09.2019
Размер:
2.31 Mб
Скачать

10. Цикли і масиви процесів

У мові Оккам є два види циклів: необмежений WHILE і обмежений, або розмножник процесів FOR.

Необмежені цикли є послідовним механізмом мови Оккам, що дозволяє програмувати регулярне поновлення роботи процесу в Оккам-програмі до досягнення деякої умови, що виробляється всередині поновлюваного процесу (тіла циклу). Коли кількість поновлень роботи процесу відомо заздалегідь, використовують розмножник процесів FOR (обмежений цикл). Він робить рівно стільки копій процесу з послідовно зростаючим параметром, скільки замовив користувач у своїй програмі.

Необмежений цикл вводиться за допомогою ключового слова WHILE, за яким іде логічний вираз (умова наступного виконання тіла циклу). Починаючи з наступного рядка, записується тіло циклу, що представляє собою Оккам-процес зі своєю ієрархічною структурою. Ієрархія процесів у тексті Оккам-програм відображається у вигляді структури відступів.

Спочатку, при відпрацьовуванні конструкції WHILE, перевіряється умова виконання тіла циклу. Тіло циклу виконується тоді й тільки тоді, коли умова його виконання істинна. Якщо умова виконання тіла циклу ложно, керування передається наступному процесу, а процес, утворений конструктором WHILE, закінчується:

VAR char: - буфер для введення символу із клавіатури

SEQ

number := 0

keyboard ? char

WHILE ('0' <= char) AND (char <= '9')

SEQ

number := (number * 10) + (char - '0')

keyboard ? char

Цей фрагмент програми перетворить рядок символів, що зображує число в десятковій системі відліку, у внутрішнє (машинне) представлення. Як тільки знову отриманий символ із клавіатури термінала буде відрізнятися від зображення якої-небудь цифри, процес, утворений конструктором необмеженого циклу WHILE, закінчить свою роботу.

Обмежений цикл можна розглядати як масив процесів. Конструктор масиву процесів FOR можна використати разом з конструкторами ALT, IF, PAR і SEQ у вигляді:

ім'я_конструктора ім'я_змін_циклу = [база FOR лічильник]

Ім'я змінної циклу описувати не треба. База й лічильник – вирази, які означають, що нижченаведений процес, варто розмножити на лічильник копій з відповідними зростаючими значеннями параметра ім'я_змін_циклу, а саме: база, база + 1, ... , база + лічильник - 1:

SEQ i = [1 FOR siring [BYTE 0 ]]

out ! string [BYTE i]

Цей запис еквівалентний наступному фрагменту:

SEQ

out ! string [BYTE 1]

out ! string [BYTE 2]

out ! string [BYTE n-1]

out ! string [BYTE n]

Таким чином, SEQ-FOR-цикл аналогічн FOR-циклу в алголоподібних мовах програмування. Слід зазначити, що в наведеному вище прикладі індексна змінна i не описується і є локальною змінною усередині тіла циклу. Природно, що усередині тіла циклу значення індексної змінної i не повинне модифікуватися програмістами.

Умовний цикл IF-FOR може виконувати, зокрема, обмежений пошук у масиві:

SEQ

v[n] := key

IF i = [0 FOR n]

v[i] = key

x := i

SEQ

v[n] := key

IF

v[0] = key

x := 0

v[1] = key

x := 1

v[n] = key

x := n

Цей фрагмент Оккам-программы здійснює пошук значення key у масиві v, з використанням "порогу" (v [n]) .

Конструкцію IF-FOR також зручно застосовувати для пошуку деякого ключового слова:

IF

IF i = [1 FOR string [BYTE 0]]

String [BYTE i] object [BYTE i]

found := FALSE

TRUE

found := TRUE

У цьому прикладі string - деяке ключове слово, a object - слово, обране для порівняння. Змінна found зберігає результат порівняння.

Нехай string [BYTE 0] дорівнює 4, тобто необхідно знайти слово, що складається із чотирьох літер. Тоді розглянутий фрагмент еквівалентний більше розгорнутому:

IF

IF

string [BYTE 1] <>

object[BYTE 1]

found := FALSE

string[BYTE 2] <>

object[BYTE 2]

found := FALSE

string[BYTE 3] <>

object[BYTE 3]

found := FALSE

string[BYTE 4] <>

object[BYTE 4]

found := FALSE

TRUE

found := true

IF

string[BYTE 1] <>

object[BYTE 1]

found := FALSE

string[BYTE 2] <>

object[BYTE 2]

found := FALSE

string[BYTE 3] <>

object[BYTE 3]

found :- FALSE

string[BYTE 4] <>

object [BYTE 4]

found := FALSE

TRUE

found := true

Тіла PAR-FOR-циклів виконуються паралельно, так що такі цикли поводяться подібно масивам паралельно працюючих процесів:

PAR i = [0 FOR n ]

produce.a(i, north.south[i])

Особливо цікаві вкладені PAR-FOR-цикли, що дозволяють програмувати складні обчислювальні процеси. Наприклад:

PAR I = [0 FOR n]

PAR j = [0 FOR n]

IF

i = j

summ.of.two.bits (north.south[(n * i) + j],

norlh.south [(n * (i + l)) + j],

west.east[i + (n * j)],

west.east[i + (n * (j + 1))],

carry [i], carry [i+1])

i <> j

buffer (north.south [ (n * i) + j],

north.south [(n * (i + l)) + j],

west.east [i + (n * j)],

west.east [i + (n *(j + l))])

Цей приклад моделює обчислювальну матрицю розміром n*n, по головній діагоналі якої розташовані однобітові суматори, а вся матриця являє собою паралельний суматор двох n-розрядних слів.

Використання розмножника процесів FOR з конструктором ALT дозволяє успішно програмувати досить складні завдання системного програмування, наприклад класичне завдання "взаємного виключення":

WHILE TRUE

ALT i = [0 FOR n]

request [i] ? ANY

release [i] ? ANY

Цей фрагмент програми дозволяє n-процесам управляти доступом до деякого ресурсу так, щоб тільки один процес працював з даним ресурсом у довільний момент часу.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]