0

Prolog 问题:刚开始学习 Prolog,这是我们收到的练习测验之一。

鉴于:

avenger(thor).
avenger(captainAmerica).
sibling(thor,loki).
asgardian(thor).
asgardian(X) :- sibling(Y,X),asgardian(Y).
train1(X,Y) :- avenger(X),!,avenger(Y).
train2(X,Y) :- avenger(X),X\=Y,avenger(Y). 

列出以下查询返回的所有答案。

train2(A, captainAmerica). %returns A=thor.
train2(captainAmerica, A). %returns false.

我的问题是关于第二个查询。为什么不返回 A=thor。? 我搞砸了一点,如果我将 train2 更改为

train2(X,Y) :- avenger(X),avenger(Y),X\=Y.

当我运行第二个查询时,我得到

A=thor. 

在这里快速解释一下为什么查询中的规则顺序很重要。谢谢。

4

2 回答 2

2

\=是一个奇怪的谓词......它说,“如果两个参数的统一成功,则失败;如果统一失败,则成功”。因此,由于自由变量与原子的统一总是会成功,但它失败了。

一旦 与Y统一,与的thor统一失败,所以成功。captainAmericathorX \= Y

无论如何,您不应该\=在这种情况下使用。相反,使用dif/2. 尝试使用定义为的谓词搞乱:

train3(X, Y) :-
    dif(X, Y),
    avenger(X),
    avenger(Y).

在几个方面优于其他两个。您可以使用 搜索 SO 以查找其他问题dif/2

于 2014-12-05T14:55:08.743 回答
0

\=/2参数不统一时,标准谓词为真。因此,它需要绑定两个参数(即不是变量)才有意义。您的解决方案:

train2(X,Y) :- avenger(X), avenger(Y), X \= Y.

是正确的,因为对谓词的两个继续调用avenger/1确保在调用谓词之前两者都XY被充分实例化\=/2

正如鲍里斯在他的回答中解释的那样,使用dif/2谓词的替代方法具有使上述子句中的目标顺序无关紧要的优点。但是,有一个警告。dif/2谓词不是标准谓词,并非所有 Prolog 实现都提供它。

于 2014-12-05T15:16:55.920 回答