关于 Prolog 中的平等和统一,我缺少什么?
What am I missing about equality and unification in Prolog?
我正在通过 Clocksin 和 Mellish 努力尝试并最终超越仅仅涉足 Prolog。 FWIW,我是 运行 SWI-Prolog:
SWI-Prolog version 7.2.3 for x86_64-linux
无论如何,我在练习 1.4 中实现了一个 diff/2 谓词。谓词很简单:
diff(X,Y) :- X \== Y.
它在 sister_of 谓词中使用时有效,如下所示:
sister_of(X,Y) :-
female(X),
diff(X,Y),
parents(X, Mum, Dad ),
parents(Y, Mum, Dad ).
其中,假设必要的额外事实,这样做:
?- sister_of(alice,alice).
returns 如预期的那样错误。但这就是问题所在。如果我这样做:
?- sister_of(alice, Who).
(同样,考虑到必要的额外事实)
我得到
Who = edward ;
Who = alice;
false
尽管如前所述,sister_of 谓词并未将 alice 视为自己的姐妹。
另一方面,如果我使用 SWI 提供的 dif/2 谓词,那么一切都会按照我天真地期望的方式进行。
任何人都可以解释为什么会这样,以及为什么我的 diff 实现没有按照我期望的方式工作,如果我从该查询中请求额外的统一?
可以找到我正在使用的整个源文件here
非常感谢任何帮助。
如您所见,问题源于平等(或更确切地说,不平等)与统一之间的相互作用。请注意,在 sister_of
的定义中,您首先找到 X
、 的候选值,然后 尝试约束 Y
不同,但是 Y
仍然是一个未实例化的逻辑变量,并且检查总是会成功,就像 diff(alice, Y)
一样。以下约束,包括最后一个为 Y
赋予具体值的约束,来得太晚了。
一般来说,您需要做的是确保在您到达不等式时检查所有变量都已实例化。否定是 Prolog 的非逻辑特征,因此具有潜在危险,但检查两个 ground terms 是否不相等是安全的。
我正在通过 Clocksin 和 Mellish 努力尝试并最终超越仅仅涉足 Prolog。 FWIW,我是 运行 SWI-Prolog:
SWI-Prolog version 7.2.3 for x86_64-linux
无论如何,我在练习 1.4 中实现了一个 diff/2 谓词。谓词很简单:
diff(X,Y) :- X \== Y.
它在 sister_of 谓词中使用时有效,如下所示:
sister_of(X,Y) :-
female(X),
diff(X,Y),
parents(X, Mum, Dad ),
parents(Y, Mum, Dad ).
其中,假设必要的额外事实,这样做:
?- sister_of(alice,alice).
returns 如预期的那样错误。但这就是问题所在。如果我这样做:
?- sister_of(alice, Who).
(同样,考虑到必要的额外事实) 我得到
Who = edward ;
Who = alice;
false
尽管如前所述,sister_of 谓词并未将 alice 视为自己的姐妹。
另一方面,如果我使用 SWI 提供的 dif/2 谓词,那么一切都会按照我天真地期望的方式进行。
任何人都可以解释为什么会这样,以及为什么我的 diff 实现没有按照我期望的方式工作,如果我从该查询中请求额外的统一?
可以找到我正在使用的整个源文件here
非常感谢任何帮助。
如您所见,问题源于平等(或更确切地说,不平等)与统一之间的相互作用。请注意,在 sister_of
的定义中,您首先找到 X
、 的候选值,然后 尝试约束 Y
不同,但是 Y
仍然是一个未实例化的逻辑变量,并且检查总是会成功,就像 diff(alice, Y)
一样。以下约束,包括最后一个为 Y
赋予具体值的约束,来得太晚了。
一般来说,您需要做的是确保在您到达不等式时检查所有变量都已实例化。否定是 Prolog 的非逻辑特征,因此具有潜在危险,但检查两个 ground terms 是否不相等是安全的。