
- •Введение
- •Принципы логического программирования
- •1.2. Математическая основа языка Пролог
- •1.2. Организация вычислительного процесса
- •1.2.2. Использование переменных
- •1.2.1. Синтаксис фактов и правил
- •1.3. Бэктрекинг
- •2. Основные элементы языка
- •2.1. Имена
- •2.2. Типы данных
- •2.3. Константы и переменные
- •2.4. Программные секции Пролога
- •2.4.1. Секция Domains
- •2.4.2. Секция Predicates
- •2.4.3. Секция Database
- •2.4.4. Секция Clauses
- •2.4.5. Секция Goal
- •3. Язык Пролог в задачах и примерах
- •3.1. Программирование с помощью фактов и правил
- •3.1.2. Первая формулировка задачи поиска в пространстве состояний 51 ад
- •3.1.3. Реализация на Прологе простой вопросно-ответной системы
- •It_is(“отказать в приеме на работу”):- not(this(“есть диплом”)).
- •It_is(“должность научного сотрудника”):- this(“есть диплом”),
- •3.2. Рекурсии
- •Упражнения
- •3.3. Программирование циклических процессов
- •3.4. Работа со списками
- •3.4.1. Описание списков в программе
- •3.4.2. Добавление элемента в список
- •3.4.3. Удаление элемента
- •3.4.4. Принадлежность элемента списку
- •3.4.5. Сцепление (конкатенация) списков
- •3.4.6. Удаление из списка повторяющихся элементов
- •3.4.7. Вычисление суммы элементов списка
- •3.4.8. Обращение списка
- •3.4.9. Нахождение максимального элемента списка
- •3.4.10. Перестановки
- •3.4.11. Примеры использования списков
- •Упражнения
- •3.5. Виды рекурсии
- •3.6. Поиск в пространстве состояний
- •Vshir ( [ [ V | Way ] | _ ], [ V | Way ] ) :- % Голова списка – полученное решение
- •Vshir ( Ways, Resh ). % Продолжение поиска в случае тупикового пути
- •Упражнения
- •3.6. Использование структур
- •3.6.1. Объявление структур
- •База данных с использованием структур.
- •Vife(X) :– family( _ , X , _ ). % X – жена
- •3.6.4. Планирование воздушного путешествия (143 Бр)
- •3.6.5. Реализация Планировщика в терминах структур
- •3.6.6. Задача «Зебра»
- •Упражнения
- •3.7. Динамическая база данных
- •3.7.1. Использование стандартных предикатов динамической базы данных
- •Упражнения
- •3.8. Средства управления
- •3.9. Представление множеств двоичными деревьями
- •3.9. Программы классификации
- •3.9.1. Программа классификации с обратной цепочкой рассуждений
- •Xpositive( X, y ), !. % в базе данных
- •Xnegative( X, y ), !, fail. % Отрицательный ответ обнаружен в базе данных
- •Xpositive("имеет","перья").
- •3.9.2. Программы классификации с прямой цепочкой рассуждений.
- •It_is( X ) :- write( X, “?”), % Механизм диалога
- •3.9. Обработка текстов
- •Verb( string ) % Глагол
- •Упражнения
- •4. Стандартные предикаты
- •4.1. Ввод/вывод
- •4.2. Управление экраном и оконная система
- •4.3. Обработка строк
- •4.4. Преобразование типов
- •4.5. Работа с базой данных
- •4.6. Управляющие предикаты
- •4.7. Прочие стандартные предикаты
- •4.8. Арифметические и логические предикаты
- •Приложение Приложение 1. Примерные варианты лабораторных заданий
- •1. Родословное дерево
- •2. Вопросно-ответная система
- •3. Работа со списками
- •4. Поиск пути на графе.
- •5. Разработайте прототип классификационной экспертной системы
- •6. Построение синтаксического анализатора
- •Рекомендуемая литература
1.2.1. Синтаксис фактов и правил
Для того, чтобы начать писать Пролог-программу, следует определиться, какие отношения (предикаты) в ней будут. Имена предикатов выбираем согласно смыслу программы. В синтаксисе Пролога предикат имеет следующий вид:
functor(d1,d2,...) :– cond1, cond2,... .
Здесь functor – имя предиката;
functor(d1,d2,...) – голова дизъюнкта;
d1, d2,... – аргументы предиката;
cond1, cond2,... – условия истинности дизъюнкта (в свою очередь, предикаты), где запятые обозначают связку “ И ”;
":–" - обозначение "ЕСЛИ".
Важно понимать, что имена предикатов и их размерность («арность») произвольны и зависят только от целей их использования.
Рассмотрим конкретное предложение:
P :- Q, R.
где P, Q, R – некоторые предикаты. Для выяснения истинности P следует сначала выяснить истинность Q, затем истинность R. Таким образом, запятая между целями обозначает конъюнкцию целей. Однако в Прологе возможна и дизъюнкция целей: должна быть истинной по крайней мере, одна из целей. Дизъюнкция обозначается точкой с запятой:
P :- Q; R.
Смысл такого предложения тот же, что и смысл следующей пары предложений:
P :- Q.
P :- R.
Таким образом, логическая функция «ИЛИ» может быть записана двумя способами.
Для обозначения логических связок можно также использовать более привычные: if, and, or, но в этом случае запись программы получится длиннее.
Если опущены условия, то functor(d1,d2,...) описывает факт.
В качестве первого примера рассмотрим следующую задачу. Опишем мир увлечений некоторого круга лиц. Следующим утверждениям на английском языке:
Ellen likes reading.
John likes football.
Tom likes baseball.
Eric likes reading.
Mark likes tennis.
соответствуют факты Пролога:
likes( ellen, reading ).
likes( john, football ).
likes( tom, baseball ).
likes( eric, reading ).
likes( mark, tennis ).
Имена людей записали строчными буквами, чтобы отличить их от имен переменных, которые в Прологе начинаются с прописной буквы. Разумеется, как будет видно далее, в Прологе есть возможность записывать имена как они того заслуживают. Некоторое множество фактов, задающих объекты и отношения между ними, уже образует простую программу на Прологе. Таким образом, вопрос: "Что любит Джон?" сводится к поиску объекта X, который отношение likes (нравится) связывает с Джоном; этот объект и будет служить ответом на запрос:
? likes( john, X ).
X = football.
(В языке PDC Prolog вместо знака вопроса, обозначающего цель, записывается ключевое слово Goal).
Отметим, что при определении отношения между объектами существенен порядок, в котором эти объекты входят в отношение:
likes( john, football ) отличается от likes( football, john ).
Факты – важная часть программы искусственного интеллекта, без них нельзя достичь цели. Можно сказать, что каждая цель опирается на свои факты. После записи фактов обычно следуют правила. Правило всегда выражает некоторый общий закон. Попробуем добавить один такой закон: «Всякий Х, любящий читать – умный». Его запись в виде правила:
clever ( X ) :- likes ( X, reading ).
Если значением факта всегда является «истина», то правило содержит условие истинности, записанное в его правой части. Если задаться целью найти всех умных людей среди имеющихся фактов, введем запрос:
? clever (X).
Система найдет два решения:
X=ellen
X= eric
Правило Пролога можно представить как небольшую процедуру с локальными переменными. Основное отличие такой процедуры от процедуры, написанной на процедурном языке: предикат может выполнять несколько функций, в зависимости от состояния аргументов (конкретизированы они или нет). Одно и то же отношение может быть использовано несколькими способами: если его аргументы известны, то проверяется выполнимость отношения на этих аргументах; если же некоторые аргументы неизвестны. То вычисляется множество наборов значений этих переменных, которые удовлетворяют отношению. Например, если имеется предикат square («площадь»), связывающий длину и высоту геометрической фигуры с третьим значением (например, площадью прямоугольника):
square( A, B, S ),
то вовсе необязательно этот предикат всегда будет вычислять только площадь S:
? square( 5, 4, S ),
Можно задавать и другие цели:
? square( X, 4, S ),
? square( X, Y, 20 ).
Разумеется, должны быть запрограммированы все альтернативы вычислений, т.е. при этом каждому такому состоянию аргументов соответствует своя статья предиката.