LOOP - это язык, который точно передает примитивно-рекурсивные функции. Единственные операции, поддерживаемые в языке, - это присваивание, сложение и повторение цикла, которое фиксируется до начала выполнения цикла.
Язык LOOP был представлен в статье 1967 года Альбертом Р. Мейером и Деннисом М. Ричи. Мейер и Ричи показали соответствие между языком LOOP и примитивными рекурсивными функциями..
Деннис М. Ричи сформулировал язык LOOP, который также был темой его неопубликованной докторской диссертации. тезис.
Он также был представлен Уве Шёнинг вместе с и WHILE.
Каждая примитивно-рекурсивная функция вычислима LOOP и наоборот.
В отличие от программ и программ, программы LOOP всегда завершаются. Следовательно, набор функций, вычисляемых программами LOOP, является надлежащим подмножеством вычислимых функций (и, следовательно, подмножеством вычисляемых программными функциями WHILE и GOTO).
Пример Общая вычислимая функция, которая не является вычислимой LOOP, - это функция Аккермана.
LOOP-программы состоят из символов LOOP
, DO
, END
, :=
, +
, -
и ;
, а также любое количество переменных и констант. LOOP-программы имеют следующий синтаксис в модифицированной форме Бэкуса – Наура :
Здесь, - имена переменных и - константы.
Если P - программа LOOP, P эквивалентна функции . Переменные с по в программе LOOP соответствуют аргументам function , и инициализируются перед выполнением программы соответствующими значениями. Все остальные переменные получают нулевое начальное значение. Переменная соответствует значению, которое принимает при заданных значениях аргументов из через .
оператор формы
xi: = 0
означает, что значение переменной установлено на 0.
. Оператор формы
xi: = x i + 1
означает, что значение переменной увеличивается на 1.
. Оператор формы
P1; P 2
представляет собой последовательное выполнение подпрограмм и , именно в таком порядке.
. Оператор вида
LOOP x DO P END
означает повторное выполнение частичной программы всего раз, где используется значение, которое имеет в начале выполнения оператора. Даже если изменит значение , это не повлияет на то, сколько раз выполняется в цикле. Если имеет нулевое значение, то не выполняется внутри оператора LOOP
. Это позволяет использовать ветки в программах LOOP, где условное выполнение частичной программы зависит от того, имеет ли переменная значение ноль или единицу.
Следующая программа LOOP присваивает значение переменной x i переменной x j.
xj: = 0; LOOP x i DO x j : = x j + 1 END
В своей основополагающей статье Мейер и Ричи сделали назначение базовый оператор. Как показывает приведенная выше программа, присвоение является избыточным и может быть удалено из списка основных операторов. Его можно использовать как подпрограмму в других программах LOOP. Синтаксис LOOP может быть расширен с помощью следующего оператора, эквивалентного вызову вышеупомянутой подпрограммы:
xj: = x i
Замечание : Следует помнить, что все переменные являются глобальными. То, что новый оператор эквивалентен подпрограмме, не означает, что это подпрограмма. Обычно запись об активации предотвращает все побочные эффекты. Однако в этом случае никакая другая переменная, кроме x j не затрагивается, поэтому побочные эффекты не возникают, при условии, что x j, который на этом этапе выполнения программы может содержать ненулевое значение, инициализируется 0.
Частным случаем программы присваивания является программа (мы используем расширенную запись):
x0: = x i
Эта программа вычисляет k-арную функцию проекции , который извлекает i-ю координату из упорядоченного кортежа k.
Функция предшественника определяется как
Эта функция может быть вычислена с помощью следующей программы LOOP, которая устанавливает для переменной значение .
/ * предварительное условие: x 2 = 0 * / LOOP x 1 DO x 0 : = 0; LOOP x 2 DO x 0 : = x 0 + 1 END; x 2 : = x 2 + 1 END
Эту программу можно использовать как подпрограмму в других программах LOOP. Синтаксис LOOP может быть расширен с помощью следующего оператора, эквивалентного вызову вышеуказанной подпрограммы:
x0: = x 1 ∸ 1
Замечание : снова нужно помнить о стороне последствия. Программа-предшественник изменяет переменную x 2, которая может использоваться где-то еще. Чтобы развернуть оператор x 0 : = x 1 ∸ 1, можно инициализировать переменные x n, x n + 1 и x n + 2 (для достаточно большого n) в 0, x 1 и 0 соответственно, запустите код для этих переменных и скопируйте результат (x n) до x 0. Компилятор может это сделать.
В следующей программе переменная устанавливается равной сумме переменных и .
LOOP x 1 DO x 0 : = x 0 + 1 КОНЕЦ; LOOP x 2 DO x 0 : = x 0 + 1 END
Эту программу можно использовать как подпрограмму в других программах LOOP. Синтаксис LOOP может быть расширен с помощью следующего оператора, эквивалентного вызову вышеуказанной подпрограммы:
x0: = x 1 + x 2
Если в программа 'сложения' над вторым циклом уменьшает x 0 вместо увеличения, программа вычисляет разность (отсекается на 0) переменных и .
x0: = x 1 LOOP x 2 DO x 0 : = x 0 ∸ 1 END
Как и раньше, мы можем расширить синтаксис LOOP с помощью оператора:
x0: = x 1 ∸ x 2
Следующая программа LOOP устанавливает значение переменной равным произведению переменных и .
LOOP x 1 DO x 0 : = x 0 + x 2 END
Эта программа умножения использует синтаксис, введенный подпрограммой сложения из предыдущего примера. Здесь умножение выполняется путем добавления значения в сумме раз, сохранение результатов в .
Оператор if-then-else с if x 1>x2then P1 else P2:
xn1: = x 1 ∸ x 2 ; х n2 : = 0; х n3 : = 1; LOOP x n1 DO x n2 : = 1; x n3 : = 0 КОНЕЦ; LOOP x n2 DO P1 END; LOOP x n3 DO P2 END;