Good_standard( francesco)

reasonable СRestaurant) ;- ftРесторан с приемлемымиценами

not expensiveCRestaurant}. i - это недорогой ресторан! Если после ввода этой программы будет задан вопрос ?- 9ood_etaadard( X), reasonable £ X).

для определения того, какие рестораны характеризуютсявысоким уровнем обслужи­вания и приемлемыми ценами, то система Prolog ответит X = francesco

Если же будет задан, на первый взгляд, такой же вопрос ?- reasonable ( X) , good_atandard ( х). то система Prolog ответит

II:

Рекомендуем читателю выполнить трассировку программы, чтобы понять причи­ны получения разных ответов. Ключевая разница между обоими вопросами состоит в том, что в первом случае при выполнении терма reasonable ( X} переменная х уже конкретизирована, а во втором случае — еще не конкретизирована. В качестве общей рекомендации можно указать следующее: оператор not Goal выполняется безопас­но, если переменные в цели Goalуже конкретизированы ко времени вызова цели notGoal. Б противном случае могут быть получены непредсказуемые результатыпо причинам, описанным ниже.

Проблема, связанная с кеконкретизировашзымиотрицаемыми целями, является результатом неблагоприятного изменения квантификациипеременных при использо­вании отрицания как недостижения цели. При обычной интерпретации в системе Prolog вопрос ?- expensive! X).

означает: "Существует ли такой X, что цель expensive { X) является истинной? Ес­ли да, то каков этот X?" Поэтому к X применяется квантор существования. В соот­ветствии с этим система Prolog отвечает, что X = jeanluis. Но вопрос

?-not expensive ( X).

не интерпретируется так: "Существует ли такой X, что достигается цель notexpensive (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 также требует особой осторожности.