
- •Предисловие
- •Глава 1 Введение в Пролог
- •Глава 2 Синтаксис и унификация
- •2.1. Синтаксис термы
- •Константы
- •Переменные
- •Область действия переменных
- •Сложные термы, или структуры
- •Синтаксис операторов
- •Синтаксис списков
- •Синтаксис строк
- •Утверждения
- •Запросы
- •Ввод программ
- •2.2 Унификация
- •Глава 3 Арифметические выражения
- •3.1. Введение
- •3.2. Арифметические выражения
- •3.3. Арифметические операторы
- •3.4. Вычисление арифметических выражений
- •3.5. Сравнение результатов арифметических выражений
- •Глава 4 Рекурсия
- •4.1. Стратегия «разделяй и властвуй»
- •Пример 4.1.1
- •Фаза разбиения
- •Фаза решения задачи
- •4.2. Восходящая стратегия
- •4.3. Рекурсия и эффективность
- •Пример 4.3.2
- •Глава 5 Структуры данных
- •5.1. Списки списковая форма записи
- •А на запрос
- •Некоторые стандартные целевые утверждения для обработки списков
- •5.2. Бинарные деревья представление бинарных деревьев
- •Бинарное дерево на рис.5.2.1 имеет левое поддерево
- •Представление множеств с помощью бинарных деревьев
- •Будем называть линейным представление такого вида, как на рис.5.2.3, и сбалансированным - такое, как на рис.5.2.2.
- •Левому поддереву соответствует отсортированный список
- •Глава 6 Операторы
- •6.1. Операторы и структуры синтаксис операторов
- •Свойства операторов
- •6.2. Позиция операторов
- •6.3. Приоритет операторов
- •6.4. Ассоциативность операторов
- •6.5. Спецификаторы
- •6.6. Операторы объявления
- •6.7. Пример: вычисление многочленов
- •6.8. Системные операторы
- •Глава 7 Механизм возврата и процедурная семантика
- •7.1. Механизм возврата
- •7.2. Пример: задача поиска пути в лабиринте
- •Целевое утверждение не удается согласовать с первым утверждением
- •Если мы введем
- •Если затем мы введем
- •7.3. Обработка фактов с помощью механизма возврата
- •7.4. Предикат repeat
- •7.5. Декларативная и процедурная семантики
- •Характеристики процедуры
- •7.6. Вопросы эффективности
- •Глава 8 Отсечение
- •8.1. Почему используют отсечение?
- •8.2. Использование отсечения
- •Выдав запрос
- •Обратившись к системе с запросом
- •8.3. Ловушки отсечения
- •Глава 9 Встроенные предикаты
- •9.1. Встроенные предикаты
- •9.2. Обновление базы данных Пролога
- •Добавление и удаление утверждений
- •Считывание утверждений в базу данных
- •Предикаты сохранения и восстановления
- •9.3. Особенности ввода и вывода чтение символов
- •Запись символов
- •Считывание термов Предикаты
- •Запись термов
- •9.4. Обработка файлов
- •Редактирование программ на прологе
- •Распечатка предикатов
- •Глава 10 Модули. Пример разработки системы
- •10.1. Модули
- •Пример 10.1.1
- •10.2. Пример разработки системы: деревья решений
- •Описание дерева решений
- •Разработка системы
- •Целевое утверждение
- •Глава 11 Отладка
- •11.1. Трассировка
- •Включение и выключение механизма трассировки
- •Необязательные параметры трассировки
- •Предикаты трассировки
- •Режимы трассировки
- •11.2. Установка контрольных точек
- •Возможные действия в контрольной точке
- •Включение и выключение режима контрольных точек
- •Необязательные параметры режима контрольных точек
- •Предикаты для работы с контрольными точками
- •Режимы, связанные с контрольными точками
- •Основные отладочные предикаты
- •Статистическая информация
Обратившись к системе с запросом
?- оценка(90,G).
узнаем верный ответ
G='А'
другие решения (да/нет) ? да
Ответив «да», получим дополнительные решения:
G='B'
другие решения (да/нет) ? да
G='C'
другие решения (да/нет) ? да
G='D'
Для устранения альтернативных решений введем отсечение:
степень(М,'A') :- М >= 80,!.
степень(М,'В') :- М >= 60,!.
степень(М,'С') :- М >= 50,!.
степень(М,'D').
При таком определении процедуры на запрос:
?-оценка (90,G).
получим:
G='А'
другие решения (да/нет) ? да
Ответ «да» приведет к результату:
Других решений нет
Заметим, что отсечения стоят после условия. Помещение их перед условиями имело бы нежелательный эффект: первое утверждение было бы согласовано в любом случае, даже если оно и неверно, и остальные три предложения никогда бы не использовались.
Пример 8.3. Неудачное завершение доказательства цели. В примере 8.2 мы предполагали, что оценка находится в правильном диапазоне. Задав вопрос программе
?- степень(900,G).
получим ответ:
G='A'.
Допустим, что выполнение процедуры степень закончится неудачей, если оценка не принадлежит ожидаемому интервалу. Мы можем добиться этого, расширив описание первого и последнего утверждений:
степень(М,'А') :- М >= 80,!,М <= 100.
степень(М,'В') :- М >= 60,!.
степень(М,'С') :- М >= 50,!.
степень(М,'D') :- М >= 0.
Другой вариант решения заключается в том, чтобы ввести в утверждение случай возникновения неудачи, используя комбинацию отсечение - fail.
степень(М,_) :- (М < 0; М > 100),!,fail.
степень(М,'А') :- М >= 80,!.
степень(М,'В') :- М >= 60,!.
степень(М,'С') :- М >= 40,!.
степень(М.'D').
Зададим вопрос:
?-степень(900,G).
имея в виду приведенное определение процедуры. Сначала произойдет сопоставление запроса с головой первого утверждения. Цель (М<0; М>100) будет достигнута. Затем будет доказана цель-отсечение. Но когда встретится предикат fail, стоящий перед ним предикат отсечение остановит работу механизма возврата, и в результате ответом на запрос будет «нет».
Преимущество введения предиката fail заключается в том, что выделяются случаи, когда доказательство утверждений должно закончиться неудачей, и проясняется смысл остальных утверждений.
8.3. Ловушки отсечения
При использовании отсечения возможно возникновение двух видов ловушек:
а) отсечение исключает необходимые альтернативы;
б) отсечение разрушает декларативное восприятие программы.
В качестве примера ловушки первого типа рассмотрим применение предиката присоединить (разл. 5.1.2) для разделения списка:
присоединить([],Q,Q).
присоединить[HP | ТР],Q,[HP | TR]) :-
присоединить (TP,Q,TR).
Запрос
?- присоединить(X,Y,[a,b,c,d]).
приведет к
X=[]
Y=[a,b,c,d]
другие решения (да/нет)? да
Х=[а]
Y=[b,c,d]
другие решения (да/нет)? да
Х=[а,b]
Y=[c,d]
и так далее.
Введем отсечение в граничное условие предиката присоединить:
присоединить([],Q,Q) :-!.
присоединить([НP | TP],Q,[HP | TR]) :-
присоединить(TP,Q,TR).
тогда в результате запроса
?- присоединить([a,b],[c,d],L).
будет определено значение
L=[a,b,c,d].
Ответом на запрос
?- присоединить(Х,Y,[a,b,c,d].
будет
Х=[]
Y=[a,b,c,d]
Однако мы не получим альтернативных разбиений:
другие решения (да/нет)? да
Других решений нет
Пример 8.2 иллюстрирует ту ситуацию, когда введение отсечения приводит к потере декларативности утверждения.
При определении процедуры степень без использования отсечения некоторое утверждение, скажем, второе, читается следующим образом: «степень принимает значение В, если оценка больше или равна 60, но меньше 80». В случае с отсечением декларативное восприятие утверждения: «степень принимает значение В, если оценка больше 60», неверно, так как оценка 90 также удовлетворяет условию.
Применять отсечение следует осторожно, соразмеряя выгоду от повышения эффективности программы с опасностью возникновения нежелательных эффектов.