658 Приложение. Обзоры языков
цируется терм q
1
(возможно, путем обращения к определению q
1
в базе данных);
если он истинен, то терм q
2
унифицируется с помощью своего определения. Если в
какойлибо точке процесс унификации сообщает об отказе, то он возвращается к
предыдущему правильному выбору и пробует альтернативный путь, как описано
в разделе 8.4.3.
Правила могут быть скомбинированы в сложные запросы. Например, вопрос
«Кто работает в NASA и написал книгу, которая издана в „ПрентисХолл“» может
быть выражен с помощью запроса:
employer(X,nasa),publisher(X,prenticehall).
X = pratt?
yes
Хотя и zelkowitz, и pratt унифицируют предикат publisher(X,prenticehall), только
pratt унифицирует предикат employer(X,nasa).
Отсечение. Процесс вычисления запросов часто требует выполнения значи
тельного числа откатов. Для экономии времени было предложено отсечение. От
сечение (обозначается символом «!») предписывает, что если в запросе необходи
мо применить откат, то мы получаем отказ в данном запросе. Действие отсечения
заключается в том, чтобы ограничить пространство поиска для нахождения реше
ния. Использование отсечения никогда не добавит решения, которое могло бы быть
найдено без отсечения, но может исключить некоторые верные решения.
Например, если бы предыдущий запрос был записан в виде
employer(X,nasa),!,publisher(X,prenticehall).
тогда мы получили бы для него отказ. Сначала был бы унифицирован предикат
employer(X,nasa), но получили бы отказ при унификации предиката èçäàòåëü(X,Ïðåíòèñ-
Õîëë)
атомом smith. Обычно в такой ситуации Prolog выполнил бы откат и начал
поиск другой подстановки для унификации предиката employer(X,nasa), но отсече
ние запрещает это делать. Отсечения не имеют никакого действия в прямом на
правлении.
Проблемы с отрицанием. Отрицание определяется следующим образом:
not(X):- X,!,fail.
not(_).
Заметим, это не соответствует тому, что следует возвратить истину, если X лож
но. Если X истинно, то not(X) вычислит X как èñòèíà, откажет на fail, но отсечение
приведет к отказу этого правила. Если X ложно, то при вычислении первого прави
ла получим отказ, но not(_)выполнится успешно. Однако при вычислении перво
го правила можно получить отказ, если X ëîæíî или просто отсутствует в базе дан
ных. Разницу можно увидеть на примере следующих двух запросов:
X is 5, not(X=10).
not(X=10),X is 5
В первом случае X унифицируется целым 5 и not(X=10) выполнится успешно. Во
втором случае X сначала унифицируется целым 10 и возникает отказ при вычисле
нии not(X=10), так что унификация целым 5 никогда не выполняется.
Ввод и вывод
Для большинства простых запросов, чтобы записать ответы, вполне достаточно
вывода по умолчанию унифицированных переменных. Тем не менее в Prolog су