В чем разница между == и = в Prolog?
Может кто-нибудь объяснить разницу между оператором ==
и =
в Prolog? Я знаю, что X = Y
означает, что X объединяется с Y и является истинным, если X уже объединяется с Y или может быть сделано, но я не понимаю, как это отличается от ==
.
Followup: Это (см. принятый ответ) имеет смысл. Еще один вопрос: существует ли когда-либо ситуация, когда X \= Y
истинна, а X \== Y
является ложным (или наоборот)? То есть, проверяет X \= Y
, если они не могут быть объединены или если они в настоящее время не объединены?
Ответы
Ответ 1
The = "operator" в Prolog на самом деле является предикатом (с инфиксной нотацией) =/2, который преуспевает, когда эти два члена унифицированы. Таким образом, X = 2
или 2 = X
составляют одно и то же, цель унификации X
с 2.
Оператор == отличается тем, что он преуспевает только в том случае, если два члена уже идентичны без дальнейшей унификации. Таким образом, X == 2
истинно, только если переменной X
ранее было присвоено значение 2.
Добавлено: Интересно работать через то, что происходит, когда "не" смешивается с этими целями в соответствии с комментарием JohnS ниже. См. Хороший набор примеров в Amzi! Документация Prolog.
\=
означает, что два члена не могут быть унифицированы, т.е. что унификация терпит неудачу. Как и при всех применениях отрицания как отказа, "не унифицированный" не (и не может) привести к унификации между терминами.
\==
означает, что два члена не идентичны. Здесь также не происходит объединения, даже если это удается.
Наконец подумайте о том, что сделает not(not(X = Y))
. Внутренняя цель преуспевает, если X и Y (которые могут быть произвольными членами) могут быть унифицированы, и это будет двойное отрицание этого. Однако обертывание внутренней цели внутри двойного отрицания создает цель, которая преуспевает, если два члена могут быть унифицированы, но без объединения этих членов.
В качестве упражнения для читателя рассматривается вопрос о том, имеет ли not(not(X == Y))
какую-либо аналогичную утилиту.
Ответ 2
= означает унификацию, это означает, что он попытается связать свободные переменные, чтобы они соответствовали другим членам.
например:
A = h (X) превратит A в член h (X), если A свободен, и потерпит неудачу, если A обязана сказать 5.
объединение велика, потому что вы можете с ним сопоставлять шаблоны, например:
X-Y:Z = 5-[a, b, c]:y
предоставит вам
X = 5, Y = [a, b, c] and Z = y
потому что пролог пытается сделать X-Y: Z соответствует выражению 5- [a, b, c]: y.
Это очень полезно.
Обратите внимание, что унификация используется, когда вы вызываете предикат, и некоторые методы следуют:
скажем, вы хотите вернуть значение аккумулятора в рекурсивный предикат, вы можете сделать это:
recursive_predicate([], Accumulator, Accumulator).
recursive_predicate(Input, Accumulator, Output) :- %recursive stuff.
первое предложение будет пытаться объединить третий и второй аргументы, поэтому, если третий является бесплатным, он имеет то же значение, что и второе.
== - это равенство, не пытаясь связать переменные.