
- •Глава 1. Введение в пролог
- •1. Декларативные и процедурные языки программирования
- •2. Пролог и логика предикатов. Внешние цели
- •3. Управление программой. Подцели. Механизм сопоставления
- •4. Внутренние подпрограммы унификации
- •Глава 2. Внутренние цели. Механизм возврата
- •1. Структура пролог-программы
- •2. Использование внутренних целей
- •3. Встроенный предикат fail
- •4. Сокращенные варианты внутренних запросов
- •5. Использование в запросах анонимных переменных
- •6. Механизм возврата
- •Глава 3. Типы данных и арифметика Turbo Prolog
- •1. Стандартные типы данных
- •2. Структуры, простые и составные
- •3. Структурные диаграммы
- •4. Использование в запросах анонимных переменных
- •5. Использование альтернативных доменов
- •6. Арифметика в Turbo Prolog
- •Глава 4. Предикат отсечения (!). Программирование альтернатив. Правила повтора
- •1. Повторения и возвраты
- •2. Отсечение (!)
- •3. Программирование альтернатив
- •4. Правило повтора
- •Глава 5. Методы организации рекурсии
- •1. Простая рекурсия
- •2. Метод обобщенного правила рекурсии
- •3. Граничное условие рекурсии. Нисходящая и восходящая рекурсии
- •4. Программа о подсчете числа точек
- •Глава 6. Списки
- •1. Основные понятия
- •2. Списки и турбо-пролог
- •3. Атрибуты списка
- •4. Внутреннее представление списков
- •5. Применение списков в программе
- •6. Метод разделения списка на голову и хвост
- •7. Поиск элемента в списке
- •8. Присоединение списка
- •9. Добавление и удаление элемента
- •10. Подсписок
- •11. Перестановки списка
- •Глава 7. Сортировка списков
- •1. Разделение списка на два
- •2. Сортировка списков методом вставки
- •3. Быстрая сортировка
- •4. Быстрая сортировка_1
- •5. Компоновка данных в список
- •Глава 8. Программирование алгоритмов с возвратом. Представление графов в turbo prolog
- •1. Задача о весах
- •2. Представление графов в turbo prolog
- •3. Поиск пути на неориентированном графе
- •4. Поиск гамильтоновых циклов
- •5. Поиск пути минимальной стоимости
- •Глава 9. Динамическая база данных
- •1. Турбо-пролог и реляционные базы данных
- •2. Описание предикатов динамических бд
- •3. Встроенные предикаты asserta, assertz, retract, retractall, save, consult
- •4. Создание динамической базы данных
- •5. Обсуждение проекта базы данных
- •6. Создание базы данных
- •7. Написание программных модулей
- •Глава 10. Глобальные переменные в turbo prolog
- •1. Модификация базы данных
- •2. Накопление результатов с помощью вынуждаемого возврата
- •3. Подсчет членов парторганизации
- •4. Поиск пути минимальной стоимости от a до z
- •Библиографический список
- •Оглавление
Глава 2. Внутренние цели. Механизм возврата
1. Структура пролог-программы
Любая программа, написанная на Турбо-Прологе, состоит из пяти разделов. Таковыми являются раздел описания доменов, раздел базы данных, раздел описания предикатов, раздел описания цели и раздел описания утверждений. Ключевые слова constants, domains, database, predicates, goal и clauses отмечают начала соответствующих разделов.
Назначение этих разделов таково:
— Раздел constants содержит описание констант.
— Раздел domains содержит определения доменов, которые описывают типы данных объектов, используемых в программе.
— Раздел database содержит описания предикатов динамической базы данных. Если программа такой базы данных не требует, то этот раздел может быть опущен.
— Раздел predicates служит для описания используемых программой предикатов.
— В разделе goal на языке Турбо-Пролога формулируется цель. Составными частями при этом могут являться некие подцели, из которых формируется единая цель программы. Такая цель называется внутренней.
— В раздел clauses заносятся факты и правила. О содержимом этого раздела можно говорить как о данных, необходимых для работы программы.
Турбо-Пролог обеспечивает возможность включения в программу комментариев, которые обрамляются символами /* */. Комментарии можно помещать в любом месте программы, причем на их длину нет практически никаких ограничений. Для того, чтобы служить своему назначению, комментарии должны содержать информацию о самой программе, имени программного файла, компиляторе, базе данных, а также о назначении каждого из предикатов и правил, которые не являются в достаточной степени очевидными.
/* комментарии */
constants
< описание констант >
domains
< описание доменов >
database
< описание предикатов динамической базы данных >
predicates
< описание предикатов >
goal
< целевое утверждение >
clauses
< утверждения >
2. Использование внутренних целей
Если цель поиска задается в самой программе, в разделе goal, то она является внутренней. Само предложение, определяющее цель, может состоять из подцелей, разделенных связками. Предложение, описывающее цель, должно оканчиваться точкой.
При доказательстве внутренней цели система найдет ровно одно решение, удовлетворяющее данный запрос.
Если в качестве связок используется конъюнкция, то ответ будет найден в результате выполнения всей совокупности целевых утверждений.
Вернемся к примеру из главы 1, описывающему дерево родственных отношений (рис. 1.2).
Goal
sister(ann,X),write(”Ann — сестра ”,X), nl
Вначале будет согласован предикат sister и переменная X означена значением pat, затем встроенный предикат write напечатает Ann — сестра pat, затем предикат nl переведет строку, и на этом выполнение программы завершится.
Рассмотрим подробно применение дизъюнкции в качестве связки между подцелями.
Пусть дизъюнкция разделяет подцели в теле правила:
ancestor(X,Y):-
pearent(X,Y);
pearent(X,Z), ancestor(Z,Y).
Конъюнкция связывает сильнее, чем дизъюнкция, поэтому это равносильно
pearent(X,Y);
(pearent(X,Z), ancestor(Z,Y))
и, в свою очередь, равносильно двум правилам:
ancestor(X,Y):-
pearent(X,Y).
ancestor(X,Y):-
pearent(X,Z), ancestor(Z,Y).
Если дизъюнкция разделяет подцели внешней цели:
Goal: sister(ann,X); pearent(X,ann)
то это будет аналогично последовательному выполнению двух разных запросов: вначале система найдет всех, для кого ann сестра, затем родителей ann.
Если бы предыдущий запрос был переформулирован как внутренняя цель (с добавлением предикатов write), то система не стала бы согласовывать цель о родителях ann, так как остановка произошла поcле первого успешного согласования подцели sister.
Из предыдущего примера видно, что свойство внутренней цели находить ровно одно решение не всегда является удобным.