Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Учебное пособие Функциональное и логическое программирование.docx
Скачиваний:
4
Добавлен:
01.07.2025
Размер:
309.57 Кб
Скачать

Циклические вычисления.

Самым общим итерационным или циклическим предложением в Лиспе является DO:

(DO ((var1 знач1 шаг1-форма) (var2 знач2 шаг2-форма) ...)

(условие-окончания форма11 форма12 ...)

форма21 форма22 ...)

С помощью формы DO можно задать:

  • набор внутренних статических переменных с их начальными значениями, как в предложениях LET, LET*;

  • ряд форм, вычисляемых последовательно в цикле.

  • изменения внутренних переменных после каждой итерации, например наращивание счетчиков;

  • условие окончание цикла и выражение, значение которого будет значением всего предложения.

Первый аргумент описывает внутренние переменные var1, var2, ...; их начальные значения - знач1, знач2, ... ; и формы обновления - шаг1-форма, шаг2-форма, ... .

Вначале вычисления внутренним переменным присваиваются начальные значения, если начальные значения не заданы, то по умолчанию переменным присваивается NIL.

Затем проверяется условие-окончания. Если значение условия-окончания равно T, то последовательно выполняются формы1i и значение последней возвращается в качестве значения всего предложения DO, иначе последовательно вычисляются формы2 i, и значение последней возвращается в качестве значения всего предложения DO.

На следующем цикле переменным vari одновременно присваиваются значения форм шагi, вычисляемых в текущем контексте, проверяется условие-окончания и цикл повторяется.

(DO ((x 5 (+ x 1)) (y 8 (+ y 2)) (рез 0))

((> x 10) рез)

(SETQ рез (+ рез x y))) => 123

Определим функцию, вычисляющую n-ю степень числа:

(defun a (x n)

(do ((rez 1 (* rez x))(raz n (- raz 1)))

((= raz 0) rez))) => a

(a 3 4) => 81

Форма DO* последовательно вычисляет свои переменные.

Передача управления.

На Лиспе можно писать программы и в обычном операторном стиле с использованием предложений передачи управления.

Однако, эти предложения использовать не рекомендуется, так как их можно заменить другими предложениями (например, DO) в более понятной форме.

Предложение передачи управления:

(PROG (m1 m2 ... mn) или PROG (m1 значение ... mn значение)

форма_1 или метка_1

...

форма_n или метка_n)

Это предложение называют PROG-механизмом с метками перехода. Переменные mi вычисляются одновременно - это локальные статические переменные формы, которые можно использовать для хранения промежуточных результатов. Перед вычислениями им присваивается значение NIL. Если переменных нет, то на месте списка переменных нужно ставить NIL.

PROG* - также как и PROG, но переменные mi вычисляются последовательно.

Если форма является числом или символом , то это метка перехода. Метка перехода (метка_i) является символом или целым числом. На такую метку можно передать управление оператором GO:

(GO метка)

GO не вычисляет значение своего «аргумента».

Кроме этого, в PROG-механизм входит оператор окончания вычисления и возврата значения:

(RETURN результат)

Операторы предложения PROG вычисляются слева направо (сверху вниз), пропуская метки перехода:

  • оператор RETURN прекращает выполнение предложения PROG;

  • в качестве значения всего предложения возвращается значение аргумента оператора RETURN;

  • если во время вычисления оператор RETURN не встретился, то значением PROG после вычисления его последнего оператора станет NIL;

  • после вычисления предложения значения статических переменных возвращаются к своим исходным значениям.

Примеры.

prog* ((y z) (x (car y)))

(return x)) – возвращает голову z.

(setq a 1) => 1

(prog ((a 2) (b a)) (return (if (= a b) '= '/=))) => /=

(prog* ((a 2) (b a)) (return (if (= a b) '= '/=))) => =

(prog () 'no-return-value) => NIL

Вычисление . Функция спрашивает число, степень и выводит результат:

(defun stepen ()

(prog (x n r)

(print “основание: ”) (setq x (read))

(print “показатель: ”) (setq n (read))

(setq r x ) (if (= n 0) (return 1))

metka (if (= n 1)(return r)) (setq r (* r x)) (setq n (- n 1)) (go metka) ) ) => (stepen)

"основание: " 5

"показатель: " 3

=> 125