Поиск третьего ответа

Предположим, что пользователь ввел еще раз символ ; , отказываясь тем самым от последнего решения. Это заставит интерпретатор приступить к поиску еще одного ответа. Такое действие пользователя приведет к неудаче подцели "отец", конкретизация переменной 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 получит при конкретизации значение «стив».

Бесполезный поиск другого возраста

Заметьте, как много времени тратит интерпретатор впустую в поисках еще одного возраста Брайена. Интуитивно мы понимаем, что взаимосвязь между лицом и его возрастом - это отношение вида многие-к-одному, поэтому мы и не предполагаем найти второе значение возраста для Брайена. Однако интерпретатор языка Пролог чисто механически просматривает всю оставшуюся часть базы данных "возраст" уже после того, как возраст Брайена был определен. Если база данных "возраст" будет иметь большой объем, то этот поиск может занять значительное время. В следующем разделе рассказывается о том, как при помощи встроенного предиката "сократить" можно избавиться от такого рода бесполезного поиска.

Соседние файлы в папке Гл.0,1,2,3,4,5,Предисловие