- •Глава 3 управление ходом выполнения программы
- •3. 1. Как выполняется запрос в прологе
- •Три семантические модели
- •Выполнение запроса
- •Правила, описывающие унификацию термов
- •Пример с программой "дядя"
- •Активация запроса
- •Унификация запроса
- •Обработка тела фразы
- •Обработка подцели "брат"
- •Обработка подцели "отец"
- •Неудача запроса и возврат назад
- •Поиск третьего ответа
- •Поиск несуществующих ответов
- •Выполнение запроса к правилу "регистрация"
- •Автоматический просмотр выполнения программы
- •3.2. Предикат "сократить" Пространство поиска запроса
- •Предикат "сократить" останавливает возврат назад
- •Влияние предиката "сократить" на составной запрос
- •Влияние предиката "сократить" на процедуру
- •Предикат "сократить" как подцель в составном запросе
- •Использование предиката "сократить" для того, чтобы сделать процедуру детерминированной
- •Применение предиката "сократить" для отбрасывания части пространства поиска
- •Ограничение сферы действия предиката "сократить"
- •Общее правило ограничения сферы действия предиката "сократить"
- •3. 3. Отрицание как неудача запроса Негативная информация
- •Предположение о замкнутости мира
- •Тогда и только тогда, когда
- •Предположение об открытости мира
- •Отрицание в явной форме
- •Пример процедуры, поведение которой соответствует предположению об открытости мира
- •3. 4. Встроенные предикаты, предназначенные для обеспечения ввода-вывода Побочные эффекты ввода-вывода
- •Пример запроса, в котором используется предикат "read"
- •3. 5. Встроенные предикаты, предназначенные для управления файлами
- •3. 6. Проверка типа терма
- •Использование предикатов "var" и "nonvar"
- •3. 7. Действия с текущей программой
- •Изменение значения факта
- •Алгоритм поиска с возрастом, в котором используется предикат "assert"
- •Процедура, которая учится у пользователя
- •Программа, которая модифицирует сама себя
- •3. 8. Компараторы
- •3. 9. Прочие встроенные предикаты
- •Программа ввода "вводполя"
- •3. 10. Операции Расширяемость синтаксиса языка Пролог
- •Инфиксная операция ",", обладающая правой ассоциативностью
- •Инфиксная операция, не обладающая свойством ассоциативности
- •Объявление операций
- •3. 11. Преобразование процедурного алгоритма в программу на языке пролог Сравнение поиска с возвратом и рекурсии
- •Цикл "пока"
- •Рекурсия
- •Поиск с возвратом
- •Применение предиката "findall"
- •Библиографические заметки
- •Упражнения
Поиск третьего ответа
Предположим, что пользователь ввел еще раз символ ; , отказываясь тем самым от последнего решения. Это заставит интерпретатор приступить к поиску еще одного ответа. Такое действие пользователя приведет к неудаче подцели "отец", конкретизация переменной W, имевшей значение «кеннет», ликвидируется. Но теперь уже подцель "отец" достигла конца множества фраз "отец":
(11)
- Активные запросы - - Фразы программы -
? - дядя (джон, W). ------> дядя (джон, W): -
брат (джон, билл),
отец (билл, W).
брат(даниэль, кеннет).
? - брат (джон, билл). -----> брат (джон, билл).
отец (билл, даниэль). отец (билл, кеннет).
?-отец (билл, W). ------>
В этом месте запрос "отец" терпит неудачу и удаляется из стека. Затем интерпретатор возвращается назад к предыдущей подцели составного запроса, т. е. к «брат (джон, В)». Возврат вызывает замену последнего успеха подцели "брат" на неудачу, при этом конкретизация переменной В теряет свою силу. Однако же теперь запрос "брат" достиг конца множества фраз "брат":
(12)
- Активные запросы - - Фразы программы -
? -дядя (джон, W). ------> дядя(джон,W): -
брат (джон, В),
отец (В, W).
брат (даниэль, кеннет).
брат (джон, билл).
? - брат (джон, В). ———>
Поэтому подцель "брат" терпит неудачу и удаляется из стека. Поскольку она являлась первой подцелью в теле правила "дядя", то и все правило "дядя" терпит неудачу. Интерпретатор возвращается назад и ищет другую фразу "дядя". Но в этом месте запрос "дядя" уже достиг конца множества фраз "дядя":
(13)
— Активные запросы — — Фразы программы —
дядя (джон, W): -
брат (джон, В),
отец (В, W).
? -дядя (джон, W). ------->
В итоге получается, что запрос "дядя" терпит неудачу и удаляется из стека.
Интерпретатор выдает ответ:
нет
Это означает, что он больше не может отыскать позитивного ответа на запрос. Далее интерпретатор возвращается к сообщению-подсказке верхнего уровня.
Поиск несуществующих ответов
Продемонстрируем на более сложном примере то, как интерпретатор иногда теряет время впустую на поиски несуществующих ответов. Правило "регистрация", приводимое ниже, специфицирует, какие лица должны зарегистрироваться для прохождения обязательной воинской службы.
возраст (брайен, 18).
возраст (майк, 17).
возраст (стив, 18).
мужчина (брайен).
мужчина (майк).
мужчина (стив),
регистрация (Х): -
мужчина (X), возраст (X, Y), Y = 18.
Выполнение запроса к правилу "регистрация"
Предположим, что пользователь ввел запрос:
|? -регистрация (W).
Диаграммы, приводимые далее, иллюстрируют шаги, которые будет выполнять интерпретатор при обработке данного запроса.
(1)
- Активные запросы - - Фразы программы -
? - регистрация (W). -------> регистрация (W): -
мужчина (W), возраст (W, Y), Y=18.
(2)
— Активные запросы — — Фразы программы -
? - регистрация (W). ——--> регистрация (W): -
мужчина (W), возраст (W, Y), Y=18.
? -мужчина (W). ------> мужчина (брайен).
мужчина (майк).
муж чина (стив).
(3)
— Активные запросы - - Фразы программы -
? -регистрация (брайен). -------> регистрация (брайен): -
мужчина (брайен),
возраст (брайен, Y), Y = 18.
? - мужчина (брайен). --------> мужчина (брайен).
мужчина (майк).
мужчина (стив).
? - возраст (брайен, Y). --- - --> возраст (брайен, 18).
возраст (майк, 17).
возраст (стив, 18).
(4)
— Активные запросы — — Фразы программы —
? -регистрация (брайен). —-----> регистрация (брайен): -
мужчина (брайен),
возраст (брайен, 18),
18=18.
? - мужчина (брайен). -------> мужчина (брайен).
мужчина (майк).
мужчина (стив).
?—возраст (брайен, 18) . —-----> возраст (брайен, 18).
возраст (майк, 17).
возраст (стив, 18).
? -18=18.
В этом месте запрос оказывается успешным, и интерпретатор выводит
W= брайен
Другой ответ
Но посмотрим, что произойдет, если пользователь введет символ ; , запрашивая иной ответ:
(5)
— Активные запросы — — Фразы программы —
? -регистрация (брайен). ———> регистрация (брайен):—
мужчина (брайен),
возраст ( брайен, Y),
Y=18.
? - мужчина (брайен). ---------> мужчина (брайен).
мужчина (майк).
мужчина (стив).
возраст(брайен,18).
? - возраст (брайен, Y). ---------> возраст (майк, 17).
возраст (став, 18).
(6}
- Активные запросы - - Фразы программы -
? - регистрация (брайен). ---—----> регистрация (брайен): -
мужчина (брайен),
возраст (брайен, Y),
Y=18.
? - мужчина (брайен) ----------> мужчина (брайен).
мужчина (майк).
мужчина (стив).
возраст (брайен, 18).
возраст (майк, 17).
? -возраст (брайен,Y) -----------> возраст (стив, 18).
(7)
- Активные запросы - - Фразы программы -
? -регистрация (брайен). ------> регистрация (брайен): -
мужчина (брайен),
возраст (брайен, Y),
Y=18.
? - мужчина (брайен) ----- -> мужчина (брайен).
мужчина (майк).
мужчина (стив).
возраст (брайен, 18).
возраст (майк, 17).
возраст (стив, 18).
? -возраст (брайен, Y). ------->
(8)
- Активные запросы - - Фразы программы -
? -регистрация (W). -------> регистрация (W): -
мужчина (W),
возраст (W, Y), Y= 18.
мужчина (брайен).
? -мyжчинa (W). --------> мужчина (майк).
мужчина (стив).
Теперь при конкретизации переменной W значением «майк» запрос потер. пит неудачу, так как Майку лишь 17 лет. Однако запрос будет вновь успешным, когда переменная W получит при конкретизации значение «стив».
Бесполезный поиск другого возраста
Заметьте, как много времени тратит интерпретатор впустую в поисках еще одного возраста Брайена. Интуитивно мы понимаем, что взаимосвязь между лицом и его возрастом - это отношение вида многие-к-одному, поэтому мы и не предполагаем найти второе значение возраста для Брайена. Однако интерпретатор языка Пролог чисто механически просматривает всю оставшуюся часть базы данных "возраст" уже после того, как возраст Брайена был определен. Если база данных "возраст" будет иметь большой объем, то этот поиск может занять значительное время. В следующем разделе рассказывается о том, как при помощи встроенного предиката "сократить" можно избавиться от такого рода бесполезного поиска.
