
- •Предисловие
- •Глава 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. Установка контрольных точек
- •Возможные действия в контрольной точке
- •Включение и выключение режима контрольных точек
- •Необязательные параметры режима контрольных точек
- •Предикаты для работы с контрольными точками
- •Режимы, связанные с контрольными точками
- •Основные отладочные предикаты
- •Статистическая информация
Глава 11 Отладка
В данной главе рассматриваются процесс отладки программ и способ получения пользователем информации о внутренних функциях системы Пролог. Приведены основные характеристики отладочных предикатов trace и spy. Описывается использование предиката statistics для получения статистической информации.
Написав программу на Прологе, пользователь сталкивается со следующей проблемой: как заставить ее работать. В большинстве случаев при первой попытке запуска программы Пролог - система фиксирует состояние неудачи и возвращает ответ <<нет>>.
Однако такой ответ ничего не объясняет. Необходимо средство для отслеживания работы программы.
Во многих реализациях Пролога пользователь располагает двумя методами проверки работы программы:
а) трассировка;
б) контрольные точки.
11.1. Трассировка
Трассировка позволяет пользователю наблюдать за ходом выполнения программы во время ее работы. При попытке Пролога доказать некоторое целевое утверждение на экране появляется сообщение, содержащее имя цели и состояние связанных с ней параметров. Предположим, мы написали следующую программу:
степень (N,Р) :- integer (N),
integer (Р),!.
ст (N,Р,А),
write (N),
write ('возведенное в степень'),
write (Р),
write ('есть'),
write (A),
nl.
степень (_,_) :- write ('оба параметра не являются целыми').
степ (N,0,1) :-!
степ (N,P,R) :- M is P-l,
степ (N,M,Q),
R is Q*N.
Теперь мы выдаем запрос степень(2,4) и ожидаем получить ответ «16». Однако система отвечает «нет». Для получения информации об ошибках в программе мы рекомендуем использовать трассировку.
Опуская вопрос включения механизма трассировки, остановимся на рассмотрении информации, которая будет отображаться каждый раз при вводе целевого утверждения.
Снова напечатаем степень(2,4). На этот раз на экране появятся следующие сообщения:
CALL: степень (2,4)
CALL: integer (2)
CALL: integer (4)
CALL: ст (2,4,A)
FAIL: ст (2,4,A)
нет.
Сообщение означает, что наша программа работала нормально, но при попытке согласовать целевое утверждение ст (2,4,А) возникло состояние неудачи. При проверке оказалось, что утверждение ст (2,4,А) набрано ошибочно вместо утверждения степ (2,4,А). Исправим программу и повторим запуск. Сопоставление утверждения степ (2,4,А) проходит успешно и программа продолжает работать. Допустим, что больше ошибок нет и мы получаем верный ответ «16».
Другой часто встречающейся ошибкой является неверное задание числа параметров у предиката. Предположим, мы записали программу таким образом:
степень (N,P) :- integer(N),
integer(P),
степ(N,P),
write(N),
write('возведенное в степень'),
writeP),
write('есть'),
write(A),
nl.
степень (_,_) :- write('o6a параметра не являются целыми числами'), nl.
степ (N,0,1):-!
степ (N,P,R) :- M is P-l,
степ(N,M,Q),
R is Q*N.
Тогда попытка сопоставить целевое утверждение степ(N,P) арности два с процедурой степ арности три закончится неудачей. Как и раньше, будет получен ответ «нет». Ошибку можно найти, воспользовавшись механизмом трассировки, как это было сделано в предыдущем примере.
Мы рассмотрели случаи поиска простых ошибок. Тот же метод трассировки применяется и для сложных программ, содержащих возвраты и рекурсию.