
- •Введение
- •Принципы логического программирования
- •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.3. Бэктрекинг
Система Пролог обладает встроенным механизмом логического вывода (перебора), благодаря чему от пользователя требуется только описание своей задачи с помощью аппарата логики предикатов первого порядка, а поиск решения система берет на себя. При этом Пролог – строго последовательный язык. Процедуры выполняются в нем строго по очереди, в том порядке, в котором они записаны. Если вызов процедуры завершен успешно, Пролог продвигается вперед, чтобы попытаться выполнить следующую процедуру. При этом в стеке запоминаются все возможные разветвления. Если вызов неудачен, происходит отход назад к ближайшему из предыдущих вызовов процедуры с целью найти другое решение, при этом отменяются результаты всех подстановок, сделанных после последнего разветвления. Такой же возврат осуществляется и после завершения успешного вычисления – для получения других ответов. При поиске новых решений теряются решения, сгенерированные на предыдущих шагах.
Рассмотрим простую программу на Прологе в виде предикатов без аргументов:
p
:– q, s.
p :– r, t.
Эту программу можно прочитать следующим образом. При выполнении процедуры p выполняются процедуры q и s. Если они завершаются успешно, то и процедура p считается успешно завершенной. Если это не так, то выполняются процедуры r и t. В этом случае процедура успешно завершается, если r и t завершены успешно. В противном случае процедура p терпит неудачу. Этот процесс возврата к поиску других решений называется бэктрекингом (backtracking).
Такой алгоритм работы можно представить в виде И-ИЛИ-дерева. В прологе применяется стратегия поиска в глубину, т.е. обход дерева сверху вниз слева направо. Если при обходе вершины ИЛИ какой-либо потомок разрешается успешно, то обработка остальных дочерних вершин приостанавливается, и считается, что вершина ИЛИ разрешается успешно. Если какой-либо из потомков И–вершины терпит неудачу, то обработка остальных ее потомков полностью прекращается и данная вершина терпит неудачу.
Приостановка обработки ИЛИ-вершины означает, что впоследствии возможно повторное обращение к этой вершине для поиска других решений (бэктрекинг).
Основными механизмами поиска решения задачи в Прологе является сопоставление и унификация, что позволяет решать широкий класс задач наиболее простым способом: путем перебора всех возможных состояний. Сначала находится предикат, который сопоставляется с целью, а затем выполняется унификация аргументов предиката. Унификация – это процесс подстановок переменных с целью приведения в соответствие двух выражений исчисления предикатов. Таким образом, унификация аналогична передаче параметров процедуры в алгоритмическом языке и в некотором смысле соответствует присваиванию.
Однако в ряде случаев требуется управлять этим процессом и реализовывать другие стратегии вывода, встраивая их в режим естественного обратного вывода Пролога. Несмотря на то, что в Прологе отсутствуют традиционные управляющие конструкции типа оператора перехода, условного оператора, оператора цикла, язык логического программирования позволяет создавать такие механизмы своими методами.
Реализация разветвляющегося процесса осуществляется довольно просто: каждой ветви вычислений соответствует отдельная статья предиката. Пролог также прекрасно приспособлен для организации циклов. Основные механизмы реализации процесса повторений – использование рекурсии и механизма бэктрекинга. Примеры возможных способов реализации алгоритмов рассмотрены ниже.