Давайте попробуем! Шаблон, который вы даете:
pred(X) :-
( guard(X) ->
...
; ...
).
Теперь я использую (*->)/2
и заполняю "..." следующим образом:
pred(X) :-
( guard(X) <b>*-></b>
<b>false</b>
; <b>true</b>
).
Далее, как guard/1
, я определяю очевидно pure предикат:
<b>guard(a).</b>
Теперь давайте спросим pred/1
самый общий запрос : Есть ли какие-нибудь решения вообще?
?- pred(X).
<b>false.</b>
Итак, согласно предикату, не существует термина X
, такого, что pred(X)
является истинным .
Но это неправильно , потому что на самом деле существует такой термин:
?- pred(b).
<b>true.</b>
На самом деле, pred/1
имеет бесконечно много решений . Приемлемо ли в такой ситуации, что предикатные состояния вообще отсутствуют? Конечно, потому что ответ был вычислен чрезвычайно эффективно , не так ли?
Мы заключаем, что (*->)/2
имеет важный недостаток (->)/2
: он может неверно зафиксировать одну из ветвей в тех случаях, когда другая ветка будет применима, если только переменные, которые встречаются в условии, были дополнительно созданы. Предикат, который зависит от создания его аргументов таким образом, никогда не может быть чистым, потому что он противодействует монотонному рассуждению, которое мы ожидаем применить к программам с чистой логикой. В частности, с логической точки зрения, поскольку pred(b)
имеет место, мы ожидаем, что pred(X)
, который является обобщением из pred(b)
, , не должен завершиться ошибкой . Когда это свойство нарушается, вы больше не можете применять декларативную отладку и другие важные подходы, которые позволяют вам более легко понимать, рассуждать о программах Prolog и управлять ими, и которые в первую очередь представляют большую привлекательность декларативного программирования.
Вы упомянули вопрос, вероятно, Для чего используется if_3/
имеет ? .