- •Функциональное и логическое программирование
- •Глава 1. Классификация языков и стилей программирования 3
- •Глава 2. Программирование на языКе лисп 16
- •Глава 3. Программирование на языке пролог 89
- •Глава 1. Классификация языков и стилей программирования
- •Основные парадигмы программирования
- •Процедурное (императивное, директивное) программирование.
- •Объектно-ориентированное программирование.
- •Декларативное программирование
- •Логическое программирование.
- •Функциональное программирование.
- •Классификация языков программирования
- •Функциональные языки
- •Логические языки
- •Глава 2. Программирование на языКе лисп
- •История создания языка Лисп
- •Диалекты языка Лисп
- •Лисп-машины
- •Область применения языка Лисп
- •Особенности языка Лисп Одинаковая форма данных и программ
- •Хранение данных, не зависящее от места
- •Автоматическое и динамическое управление памятью
- •Функциональная направленность
- •Динамическая проверка типов
- •Интерпретирующий и компилирующий режимы работы;
- •Пошаговое программирование
- •Единый системный и прикладной язык программирования
- •Основы языка Лисп
- •Понятие функции.
- •Quote блокирует вычисления
- •Базовые функции языка.
- •Функция car возвращает в качестве значения первый элемент списка.
- •Функция cdr - возвращает в качестве значения хвостовую часть списка, т. Е. Список, получаемый из исходного списка после удаления из него головного элемента:
- •Функция cons включает новый элемент в начало списка:
- •Предикат equal проверяет идентичность записей:
- •Предикат equalp проверяет наиболее общее логическое равенство:
- •Другие простейшие встроенные функции Лиспа. Функция null проверяет, является ли аргумент пустым списком:
- •Комбинации вызовов car и cdr позволяют получить любой элемент списка:
- •Наиболее общая функция, выделяющая n-й элемент списка (при этом индексация начинается с 0):
- •Функция last позволяет выделить последний элемент списка:
- •Функция list - создает список из элементов:
- •Функция setq – невычисляющее присваивание:
- •Функция setf - обобщенная функция присваивания:
- •Функции, обладающие побочным эффектом, называются псевдофункциями.
- •С символом можно связать именованные свойства:
- •Функция get - возвращает значение свойства, связанного с символом:
- •Псевдофункция remprop удаляет свойство и его значение:
- •Вызов интерпретатора eval вычисляет значение выражения.
- •Ввод и вывод.
- •Использование файлов.
- •Определение функций
- •Задание параметров в лямбда-списке.
- •Передача параметров и область их действия.
- •Вычисления в лисПе.
- •Предложение let создает локальную связь внутри формы:
- •Последовательные вычисления.
- •Разветвление вычислений.
- •Циклические вычисления.
- •Передача управления.
- •Другие циклические структуры.
- •Динамическое управление из другого контекста
- •Внутреннее представление списков
- •Функциональное программирование Рекурсия. Различные виды рекурсии.
- •Функции более высокого порядка.
- •Применяющие функционалы.
- •Отображающие функционалы.
- •Макросы
- •Типы данных
- •Основные типы данных:
- •Глава 3. Программирование на языке пролог
- •Общие сведения о языке Пролог. Язык Пролог как система, реализующая логический вывод в исчислении предикатов первого порядка.
- •Фразы Хорна как средство представления знаний.
- •Синтаксис языка Пролог.
- •Фразы, термы, факты, правила.
- •Константы:
- •Простейшая программа на Прологе
- •Выполнение запроса в Прологе.
- •Неудача запроса и возврат назад.
- •Декларативная и процедурная семантика Пролога.
- •Рекурсивные процедуры.
- •Списки.
- •Операторы.
- •Средства управления ходом выполнения программы. Предикат сократить (отсечение).
- •Отрицание как неудача запроса.
- •Встроенные предикаты.
- •Типы отношений.
- •Ограничения, обеспечивающие целостность отношений.
- •Свойства отношений.
- •Подходы к программированию на языке Пролог.
Циклические вычисления.
Самым общим итерационным или циклическим предложением в Лиспе является 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
