reasonable С Restaurant);- ft Ресторан с приемлемыми ценами
not expensiveC Restaurant}. i - это не дорогой ресторан! Если после ввода этой программы будет задан вопрос?- 9ood_etaadard(X), reasonable £ X).
для определения того, какие рестораны характеризуются высоким уровнем обслуживания и приемлемыми ценами, то система Prolog ответит X = francesco
Если же будет задан, на первый взгляд, такой же вопрос?- reasonable (X), good_atandard (х). то система Prolog ответит
II:
Рекомендуем читателю выполнить трассировку программы, чтобы понять причины получения разных ответов. Ключевая разница между обоими вопросами состоит в том, что в первом случае при выполнении терма reasonable (X} переменная х уже конкретизирована, а во втором случае — еще не конкретизирована. В качестве общей рекомендации можно указать следующее: оператор not Goal выполняется безопасно, если переменные в цели Goal уже конкретизированы ко времени вызова цели not Goal. Б противном случае могут быть получены непредсказуемые результаты по причинам, описанным ниже.
Проблема, связанная с кеконкретизировашзыми отрицаемыми целями, является результатом неблагоприятного изменения квантификации переменных при использовании отрицания как недостижения цели. При обычной интерпретации в системе Prolog вопрос?- expensive! X).
означает: "Существует ли такой X, что цель expensive { X) является истинной? Если да, то каков этот X?" Поэтому к X применяется квантор существования. В соответствии с этим система Prolog отвечает, что X = jeanluis. Но вопрос
?- not expensive (X).
не интерпретируется так: "Существует ли такой X, что достигается цель not expensive (X!?" Если бы это было действительно так, то можно было рассчитывать на получение ответа X = francesco. Но Prolog отвечает "по", поскольку при использовании отрицания как недостижения цели квантор существования заменяется квантором всеобщности. Вопрос nor. expensive1! X) интерпретируется следующим образом: not i существует X, такой, что достигается цель expensive (К))
Это равносильно следующему утверждению: Для всех X утверждение expensive (XJ является ложным
134 Часть I. Язык Prolog
В этой главе подробно рассматриваются проблемы, связанные с использованием оператора отсечения, которые также косвенно касаются и оператора not. Автор поставил перед собой задачу предупредить читателей о необходимости соблюдать осторожность при работе с оператором отсечения, а ие полностью отказаться от его применения. Оператор отсечения является полезным и часто необходимым. Кроме того, сложности, аналогичные тем, которые связаны с использованием оператора отсечения в языке Prolog, часто наблюдаются и при разработке программ на других языках.
Резюме
• Оператор отсечения позволяет предотвратить перебор с возвратами. Он ис
пользуется, во-первых, для повышения эффективности программ, а во-вторых,
для усиления выразительной мощи языка.
• Повышение эффективности достигается благодаря тому, что системе Prolog можно явно передать указание (с помощью оператора отсечения), что не нужно проверять альтернативные цели, о которых заранее известно, что попытка их достижения окончится неудачей.
• Оператор отсечения позволяет сформулировать взаимоисключающие заключения с помощью правил, имеющих следующую форму:
если Условие, то Заключение 1, в противном случае Заключение2
• Оператор отсечения позволяет ввести в программу конструкцию отрицания как недостижения цели; оператор not Goal определяется как неудача при достижении цели Goal.
• В программе иногда возникает необходимость в использовании двухспециаль ных целей, true и fail; первая всегда достигается, а последняя никогда не достигается.
• Имеются также некоторые предпосылки, препятствующие использованию оператора отсечения, связанные с тем, что вставка оператора отсечения может нарушить соответствие между декларативным и процедурным значениями программы. Поэтому признаком хорошего стиля программирования является соблюдение осторожности при использовании оператора отсечения и отказ от его применения без достаточных оснований.
• Определение оператора not как недостижения цели не полностью соответствует понятию отрицания в математической логике. Поэтому использование оператора not также требует особой осторожности.