- •Функциональное и логическое программирование
- •Глава 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. Программирование на языке пролог
- •Общие сведения о языке Пролог. Язык Пролог как система, реализующая логический вывод в исчислении предикатов первого порядка.
- •Фразы Хорна как средство представления знаний.
- •Синтаксис языка Пролог.
- •Фразы, термы, факты, правила.
- •Константы:
- •Простейшая программа на Прологе
- •Выполнение запроса в Прологе.
- •Неудача запроса и возврат назад.
- •Декларативная и процедурная семантика Пролога.
- •Рекурсивные процедуры.
- •Списки.
- •Операторы.
- •Средства управления ходом выполнения программы. Предикат сократить (отсечение).
- •Отрицание как неудача запроса.
- •Встроенные предикаты.
- •Типы отношений.
- •Ограничения, обеспечивающие целостность отношений.
- •Свойства отношений.
- •Подходы к программированию на языке Пролог.
Последовательные вычисления.
Предложения PROG1 и PROGN позволяют работать с несколькими вычисляемыми формами:
(PROG1 форма1 ... формаN)
(PROGN форма1 ... формаN).
Эти специальные формы последовательно вычисляют свои аргументы и в качестве значения возвращают значение первого (PROG1) или последнего (PROGN) аргумента.
Это формы для вычислений, поэтому связи переменных, возникшие при выполнении форм, сохраняются после выхода из PROG:
(PROG1 (SETQ x 1) (SETQ y 5)) => 1
(PROGN (SETQ j 8) (SETQ z (+ x j))) => 9
Эти формы не содержат механизма определения внутренних переменных. Связи, созданные при выполнении форм, сохраняются после завершения вычисления формы.
Разветвление вычислений.
Наиболее общей условной структурой для организации разветвления вычислений является условное предложение COND:
(COND (p1 а11 а12..) ... (pn аn1 аn2…)).
Выражения pi являются предикатами, значением предиката является T или NIL. Результирующими выражениями aij могут быть произвольные формы.
Предикаты pi вычисляются последовательно до тех пор, пока не встретится выражение, значением которого является T. Вычисляются результирующие выражения aij, соответствующие этому предикату. Перечислим правила выполнения предложения COND:
если истинного предиката нет, то значением COND будет NIL;
рекомендуется в качестве последнего предиката использовать символ T. Тогда соответствующие ему aij будут вычисляться в том случае, если другие условия не выполняются;
если условию не ставится в соответствие результирующее выражение, то в качестве результата выдается само значение предиката;
если же условию соответствуют несколько форм, то при его истинности формы вычисляются последовательно слева направо и результатом предложения COND будет значение последней формы.
Определим функцию, устанавливающую тип выражения:
(defun tip (a)
(cond ((null 'a) 'пусто)
((atom 'a) 'атом)
(t 'список))) => tip
(tip 'a) => атом
Определим логические действия логики высказываний И и ИЛИ:
(defun i (x y)
(cond (x y)
(t nil))) => i
(i t nil) => nil
(defun ili (x y)
(cond (x t)
(t y))) => ili
(ili t nil) => t
(ili nil nil) => nil
Предложения COND можно комбинировать таким же образом, как и и вызовы функций. Например, предикат «исключающее или», который ложен, если оба аргумента одновременно либо истинны либо ложны, можно определить следующим образом:
(defun xor (x y)
(cond (x (COND (y NIL)
(t T)))
(T y))) => xor
(xor t nil) => T
(xor NIL NIL) => NIL
В Лиспе используются и другие условные предложения В простых случаях можно воспользоваться содержащей мало скобок формой IF:
(IF условие то-форма иначе-форма).
Примеры:
(progn (setq x 1)(if (> x 0) 'x>0 'x<0)) => x>0
(progn (setq x -1)(if (> x 0) 'x>0 'x<0)) => x<0
(IF (> x 0) (SETQ y (+ y x)) (SETQ y (- y x))) - к значению y прибавляется абсолютное значение х
Вычисление формы, если условие выполнено:
(WHEN условие форма1 форма2 ... ).
(progn (setq x '(c d)) (when (not (atom x)) (cons x x)) ) =>
((c d) c d)
Вычисление формы, если условие не выполнено:
(UNLESS условие форма1 форма2 ... ).
(progn (setq x (read)) (unless (< x 0) (princ “ok”)))
7 - ввод
ok – значение формы
"ok" – вывод
Выбирающее предложение CASE:
(CASE ключ
(список-ключей1 m11 m12 ... )
(список-ключей2 m21 m22 ... )
....)
Сначала вычисляется значение ключевой формы - ключ. Затем его сравнивают с элементами списка-ключей. Когда в списке найдено значение ключевой формы, начинают вычисляться соответствующие формы mi1, mi2, ... . Значение последней формы возвращается в качестве значения всего предложения CASE.
(SETQ ключ 3) => 3
(CASE ключ
(1 ‘one)
(2 ‘(one + one) ‘two)
(3 ‘(two + one) ‘three) => three
(setq k 1) => 1
(case x (2 3 4 (setq y 2) (setq z 3)) (1 2 3 (setq y 3) (setq z 4))) => 4
(case x (k (setq y 3)) (t nil)) => NIL
(setq x 'k) => к
(case x (k (setq y 3)) (t nil)) => 3
