Использование предиката fail
Листинг 5.1.Программа, использующая ОПН
domains
name=symbol
predicates
country(name)
print_countries
clauses
country(england).
country(france).
country(germany).
country(denmark).
print_countries:-
country(X),
write(X),
nl,
fail.
print_countries.
Пояснения к программе:
Поставим перед программой две разные цели:
1)country(X);
2)print_countries.
Как поведет себя каждая из этих целей, если мы сделаем ее сначала внешней, а потом внутренней?
Внешняя цель
Для country(X) c fail и без fail внешняя цель даст одинаковый ответ – все 4 решения. Fail для внешней цели в этом случае просто избыточна, потому что внешняя цель заставит ее получить все ответы и без fail.
Для print_countries внешняя цель без fail даст одно решение- england-, потому что откат для получения других решений просто некуда выполнить. В разделе clauses нет больше предиката с таким именем (print_countries). Без fail у нас нет повода обратиться к country, даже если цель внешняя.
Для print_countries внешняя цель с fail даст все 4 решения. Print_countries использует поиск с возвратом с тем, чтобы получить все решения для country, заставляя Пролог выполнять поиск с возвратом черезправило print_countries. При этом Прологвозвратится к той подцели в правиле, которая может дать множественные решения, то есть к недетерминированной подцели. Предикаты nl и write не могут быть согласованы повторно, так как они не в состоянии дать нам новые решения, поэтому Пролог вынужден откатиться к предыдущей подцели, то есть к country.
|
|
Внутренняя цель
Для цели country(X) с fail и без fail результат одинаков – ответ будет один. Это происходит потому, что fail стоит в правиле print_countries,а в country fail не задействован.
Для цели print_countries c fail мы получим все 4 ответа, а без fail –один ответ.
Замечание:
Помещать подцель после fail в теле правила бесполезно, так как fail – всегда неудача, а значит, нет возможности для достижения подцели, расположенной после fail.
Вывод
Метод ОПН - откат после неудачи –позволяет управлять вычислением цели при поиске всех возможных ее решений. Для этого используется встроенный предикат fail.