
- •Предисловие
- •Глава 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. Установка контрольных точек
- •Возможные действия в контрольной точке
- •Включение и выключение режима контрольных точек
- •Необязательные параметры режима контрольных точек
- •Предикаты для работы с контрольными точками
- •Режимы, связанные с контрольными точками
- •Основные отладочные предикаты
- •Статистическая информация
9.3. Особенности ввода и вывода чтение символов
Системные предикаты get(X), get0(X), skip(X) служат для ввода символов с терминала пользователя. Коды символов различаются в зависимости от используемой реализации Пролога. В микрокомпьютерах в основном применяется код ASCII, а в больших ЭВМ (таких, как ICL2900) - код EBDIC.
Перечисленные предикаты определяются следующим образом.
get0(X)
Предикат вызывает считывание одного символа с клавиатуры. Если переменная Х неконкретизирована, то Х принимает значение кода символа. Если же переменная Х конкретизирована, то вводимый символ сопоставляется с X. Целевое утверждение будет успешно доказано только в том случае, если символ сопоставим с X.
get(X)
Предикат вызывает считывание одного или нескольких символов с клавиатуры до тех пор, пока не будет считан символ пробела. Если переменная Х неконкретизирована, то код символа отождествляется с Х и доказательство утверждения заканчивается успехом. Если же переменная Х конкретизирована, целевое утверждение будет доказано только в случае, если вводимый символ сопоставим с X.
skip(X)
Предикат считывает символы с клавиатуры или из текущего входного файла, пока не встретится символ с кодом X, тогда доказательство цели заканчивается успешно. Переменная Х может быть целочисленным выражением.
Запись символов
Для вывода символов используются системные предикаты:
put(X), tab(X) и nl.
Они определяются следующим образом.
put(X)
Символ с кодом Х записывается на терминал. Допускается, чтобы Х был целочисленным выражением. Доказательство целевого утверждения put(X) всегда заканчивается успехом. Х может быть кодом как управляющего, так и алфавитно-цифрового символа.
tab(X)
На терминал выводится Х пробелов. Х может быть целочисленным выражением.
nl
Происходит переход на новую строку терминала.
Рассмотрим примеры:
put(65) на терминал выводится символ A
(подразумевается ASCII код)
put(66+32) выводится символ b
put('C') выводится символ С
put([100]) выводится символ d
put('e'+'A'-'a') выводится символ E
put(a(b)) выдается сообщение об ошибке
Считывание термов Предикаты
read(X), readb(X) и read(X,Y)
служат для считывания термов. Приведем их определение.
read(X)
Если переменная неконкретизирована, то она означивается термом, считанным с терминала. Попытка пользователя напечатать выражение, не являющееся термом, приведет к ошибке. Вводимая информация должна заканчиваться точкой. В случае, если переменная Х конкретизирована термом, попытка доказать целевое утверждение заканчивается успехом только при условии, что вводимый с терминала терм сопоставим с X. В противном случае попытка доказательства завершается неудачей.
readb(X)
Данный предикат аналогичен предикату read(X), но вводимый терм не должен заканчиваться точкой.
read(X,Y)
Доказательство предиката завершается успехом, если считываемый терм отождествляется с X, и неудачей в противном случае. При успешном доказательстве переменная Y становится списком, состоящим из имен переменных, входящих в терм X. Пролог переименовывает переменные, встретившиеся в вводимом терме. Таким образом, когда попытка доказать целевое утверждение read(X,Y) заканчивается успехом, список Y содержит внутренние имена переменных, входящих в терм X. Как и при использовании предиката read(X), после вводимого терма должна стоять точка.
readb(X,Y)
Предикат аналогичен предикату read(X,Y). Различие состоит в том, что пользователь не должен печатать точку после ввода терма.
Примеры:
После запроса:
?- read(X).
система ожидает ввода. Если пользователь напечатает:
test(5).
то в результате переменная Х получит значение
X=test(5)
Задав вопрос
?- read (джек(мужчина)).
и введя терм
test.
получим ответ:
нет.
При запросе:
?- read(X,Y).
вводим терм
fred(P,a(Q)).
в результате получаем
X=fred(_55,a(_57))
Y=[[P | _55],[Q | _57]],
где _55 - внутреннее имя переменной Р, а _57 - внутреннее имя переменной Q.