- •Функциональное и логическое программирование
- •Глава 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. Программирование на языке пролог
- •Общие сведения о языке Пролог. Язык Пролог как система, реализующая логический вывод в исчислении предикатов первого порядка.
- •Фразы Хорна как средство представления знаний.
- •Синтаксис языка Пролог.
- •Фразы, термы, факты, правила.
- •Константы:
- •Простейшая программа на Прологе
- •Выполнение запроса в Прологе.
- •Неудача запроса и возврат назад.
- •Декларативная и процедурная семантика Пролога.
- •Рекурсивные процедуры.
- •Списки.
- •Операторы.
- •Средства управления ходом выполнения программы. Предикат сократить (отсечение).
- •Отрицание как неудача запроса.
- •Встроенные предикаты.
- •Типы отношений.
- •Ограничения, обеспечивающие целостность отношений.
- •Свойства отношений.
- •Подходы к программированию на языке Пролог.
Простейшая программа на Прологе
Программа состоит из множества фраз (прдложений). Каждая фраза - это факт, правило или вопрос.
Факт - это утверждение о том, что соблюдается некоторое конкретное отношение между объектами. Факт - это фраза без условий, т.е. это утверждение, которое всегда истинно. Факт состоит из имени предиката и списка аргументов(термов), заключенного в скобки.
Предикат - это абстрактный смысл существующего отношения между некоторым количеством аргументов. Предикат отражает множество объектов на множество {истина, ложь}. Обычно выбирается такое имя предиката, чтобы оно отражало вид взаимосвязи между аргументами. Предикат может обладать произвольным количеством аргументов. Одноместный предикат просто указывает свойство объекта.
Вопрос – цель выполнения программы: ?- Факт с переменными.
Простейшая Пролог-программа - это множество фактов, которое неформально называют базой данных. Пример базы данных, состоящей из фактов «знает»:
знает(маша, паша).
знает(коля, оля).
знает(паша, оля).
Совокупность этих фактов определяет двуместный (бинарный) предикат «знает».
Правило - это факт (заголовок правила), истинность которого зависит от истинности условий, указанных в его условной части (тело правила). Заголовок правила имеет такую же форму, как и факт, затем стоит обозначение ":-" (если), за которым располагается тело правила. Каждое условие, входящее в правило, называется подцелью. Условия разделяются знаком « , », означающим логическое И. Для того чтобы заголовок правила был истинным, необходимо, чтобы каждое условие, входящее в тело правила (каждая подцель), была истинной. Правило, в которое входят переменные, можно рассматривать как неявное определение множества фактов. Предположим, создана база данных «проживает»:
проживает ( петров, кирова, 41, 5).
проживает ( сидоров, ленина, 15, 18).
проживает ( иванов, мира, 21, 6).
проживает ( федоров, мира, 21, 8).
Следующее правило позволяет установить, что два человека знают друг друга, если они живут в одном доме:
знает(X, Y):-
проживает(X, Z1, Z2, _ ),
проживает(Y, Z1, Z2, _ ).
Рассмотрим отношение «родитель». Введем отношения «мужчина» и «женщина». Запишем факты этих отношений. Теперь введем новые правила в программу:
отпрыск (А, В):-
родитель(В, А).
мать (А, В):-
родитель(А, В),
женщина(А).
дедушка (А, В):-
родитель(А, С),
родитель(С, В),
мужчина(А).
сестра (А, В):-
родитель(С, А),
родитель(С, В),
женщина(А),
различны(А, В).
родитель_родителя(А, В):-
родитель(А, С),
родитель(С, В).
Теперь системе можно задавать вопросы, называемые запросами. Простой запрос состоит из имени предиката, за которым располагается список аргументов. Запрос - это всегда последовательность одной или нескольких целей. Чтобы выполнить запрос, система пытается достичь всех целей. Достичь цели - значит показать, что утверждения, содержащиеся в запросе, истинны в предположении, что все отношения программы истинны, т.е. целевое утверждение логически следует из фактов и правил программы.
Система рассматривает множество фактов и правил программы как аксиомы, а запрос как теорему, и пытается доказать теорему, т.е. показать, что ее можно логически вывести из аксиом.
Если в запрос не входят переменные, то система ответит «да» или «нет». Ответ «да» говорит о том, что интерпретатор смог доказать истинность запроса в соответствии с множеством фраз программы - цель достижима. «Нет» означает, что интерпретатор не смог доказать истинность запроса - цель недостижима.
Если в запрос входят переменные, то система должна найти конкретные объекты, которые, будучи подставлены на место переменных, позволяют достичь цели. Если такие конкретные объекты найдены, то говорят, что переменные конкретизируются, а их конкретные значения сообщаются пользователю. Переменные запроса существуют столько же, сколько и сам запрос. Системе можно задавать составные запросы:
?- родитель(миша, А), родитель(маша, А ). есть ли общий ребенок ?
?- родитель(А, коля), родитель(А, петя). есть ли общий родитель ?
?- родитель(А, _ ). выдает все значения первого аргумента вне зависимости от того, какие значения будет принимать второй аргумент.
Пример. Структура "клиент" и структура "дата" являются аргументами факта "сделка":
сделка ( клиент ( смит, 29 , 4 ), дата ( 86 , 4 , 22 ) ).
Факт «сделка» связывает информацию о сделке с клиентом и дату, когда эта сделка была заключена.
Составим правило, в котором аргументом служит структура "клиент". В результате обработки правила подсчитывается общая сумма, которую должен заплатить клиент (т.е. суточный тариф, умноженный на количество дней):
итого (клиент(_, Тариф,Дни), Сумма):-
Сумма is Тариф * Дни.
Фамилия не требуется для вычисления суммы оплаты, поэтому первый аргумент структуры «клиент» обозначен символом "_". Запрос к правилу может быть таким:
?- итого ( клиент ( смит , 29 , 4) , С).
Ответ: С=116
