
- •Введение
- •Принципы логического программирования
- •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, В2, ... , Вn. ,
которая интерпретируется : "А является истинным, если В1, В2, ..., Вn являются истинными". Таким образом, значок “ :- “ соответствует обозначению «если». Предикат, содержащий условия истинности, является правилом. Когда n=0, т.е. говорят, что отсутствуют условия истинности, то такое предложение выражает факт, и это записывается "А." (точка в конце записи предиката обязательна). Поскольку факт не содержит условий истинности, в Прологе факт всегда является истинным.
В данной форме записи часть выражения, стоящая слева от знака “ :- “, называется головой дизъюнкта (в нашем примере "А"), а выражение, стоящее после этого значка, называется телом дизъюнкта, т.е. В1, В2, ... , Вn – это тело, или хвост дизъюнкта.
Пролог-программа должна иметь цель, поскольку вычисление такой программы всегда начинается от цели. Достичь цели всегда означает, что она логически следует из правил программы. Можно рассматривать программу как запись аксиом, а цель – теорему, которую следует доказать. Если получен запрос (т.е. цель, которую нужно удовлетворить), Пролог пытается определить его истинность двумя способами. Во-первых, цель успешно удовлетворяется (т.е. считается истинной), если она сопоставляется с существующим фактом (так как факты всегда являются истинными). Во-вторых, цель считается истинной, если она сопоставляется с головой “А” правила " А, если В1, ... , Вn " и если подцели В1, ... , Вn могут быть завершены успешно. В случае успешного сопоставления Пролог выдает ответ "yes", т.е. цель согласована. Термин «сопоставление» обозначает совпадение цели с головой факта или правила и относится к одному из двух базовых механизмов логического вывода. Другой базовой операцией является унификация.
Унификация она применяется в том случае, если предикат имеет аргументы.
Если попытка сопоставить подцель с фактами в базе данных завершается неудачей и остаются альтернативные (еще не применявшиеся правила или факты), Пролог будет осуществлять возврат и использовать эти альтернативы. Если все альтернативы закончились неудачно, то считается, что начальная цель неудовлетворительна. В этом случае выдается ответ "no".
1.2.2. Использование переменных
В Пролог-программе нет никаких выражений, кроме предикатов, и цель тоже представляет собой некоторый предикат (или последовательность предикатов). В качестве аргументов цель может содержать константы или переменные. Переменная представляет собой неконкретизированную величину, которую Пролог должен конкретизировать, т.е. найти объекты-константы, которые при их подстановке вместо переменных обеспечивают достижение цели. Неконкретизированная переменная считается свободной, а если выполнена подстановка константой, то связанной. После того, как цель, содержащая переменные, будет согласована, Пролог выдаст значения, которыми будут заменены переменные, входящие в цель.
Рассмотрим вышеприведенный пример:
родитель(«царь Петр I», «царевич Алексей»).
Спросим эту небольшую программу, чьим родителем является царь Петр I:
? родитель( «царь Петр I», X ).
Чтобы ответить на вопрос, нужно вместо X подставит константу «царевич Алексей». В этом случае переменная X конкретизируется константой. В этом примере имела место унификация. Понятие унификации пришло из математической логики, где ему соответствует подстановка значений вместо переменных при выводе логической формулы. В Прологе унификация представляет собой универсальный механизм сопоставления с образцом для передачи параметров2. В результате унификации переменная Х получила конкретное значение.
Внутренние механизмы использования переменных в Прологе весьма различаются от таковых в алгоритмических языках. В процедурном программировании акцент делается на применение оператора присваивания для перемещения данных из фиксированных, поименованных мест их в памяти. Эти поименованные места являются переменными программы.
Программы символьного языка используют переменные, которые существуют скорее виртуально в стеке компьютера, а не фиксированных местах памяти. Управление данными осуществляется посредством сравнения с образцом, и в результате этого сравнения переменная может получить конкретное значение (конкретизироваться), пока работает предикат. Если переменная получила свое значение, то все вхождения такой переменной в некоторый предикат получают одно и то же значение и уже не могут переконкретизироваться Можно сказать, что все переменные в Прологе локальные. Переменная может переконкретизироваться только при возврате к поиску других решений (бэктрекинге). Поскольку программы искусственного интеллекта предполагают такой возврат, переменная может многократно переконкретизироваться с целью вычисления всех наборов значений аргументов.
Немного о присваивании. Читатель уже понял, что один из способов придать значение переменной – передать ее как параметр (аргумент) предиката. Другой способ похож на классическое присваивание, поскольку использует знак равенства. Но все-таки следует помнить, что в Прологе нет оператора присваивания, а есть похожий на него предикат логического сравнения, обозначаемый знаком равенства. Поэтому понятно, что сопоставление вида N = N + 1 бессмысленно: величина никогда не может быть равной самой себе, увеличенной на единицу. Надо использовать другую переменную: N1= N + 1, но зато можно записать: N + 1 = N1.
Рассмотрим, как выполняется сопоставление в последнем случае. Пусть N конкретизировано числом 3, N1 – числом 4. В этом случае сопоставление закончится «истинно». Если N конкретизировано тем же числом, а N1 не конкретизировано, то в результате сопоставления N1 получит значение 4, и предикат тоже завершится «истинно». Несложно сообразить, какие конкретизации переменных дадут ложное сопоставление.
Отметим также, что поскольку в Прологе отсутствуют глобальные переменные, одни и те же имена переменных можно употреблять во многих правилах программы, при этом между такими переменными будет отсутствовать какая-либо связь.