Prolog如何回答这个问题?

时间:2016-04-06 23:46:59

标签: prolog backtracking unification

likes(alice, sports).
likes(alice, music).
likes(carol, music).
likes(david,animals).
likes(david,X) :- likes(X,sports).
likes(alice,X) :- likes(david,X).

?- likes(alice,X).

我几天前一直在努力学习prolog,当我尝试这个问题时,我意识到我并不完全理解变量的实例化和使用时间。最初的目标是:likes(alice , X)。在那之后,下一个要证明的目标是likes(david , X)?然后是likes(X, sports)。那么X会变成alice吗?

另一条路线:

最初的目标是:likes(alice , X)。在那之后,下一个要证明的目标是likes(david , X)?然后X变为sports。然后目标变为likes(david , sports)。然后我不知道。

请有人指出我的想法存在缺陷。

2 个答案:

答案 0 :(得分:0)

鉴于你的代码,Prolog会尝试将目标与他的第一个事实likes(alice, sports).统一起来,并且它会成功。 X将与sports统一。

如果您要求Prolog继续,那么接下来将Xmusic统一起来(第二个事实)。

如果你再次继续,它会跳过接下来的三个事实/规则,并试图证明likes(alice,X) :- likes(david,X).。这会导致尝试证明likes(david,X)成功与likes(david,animals)成功,因此X在原始目标中会与animals统一。

如果你要求它再次继续,你会发现它试图证明likes(david,X) :- likes(X,sports).导致Xalice统一,所以最初的目标会建议{{1} }} alice likes

当我使用此目标运行代码时:

?- likes(alice,X), write(X), nl, fail.

......我得到了这个输出:

sports
music
animals
alice
No.

由于我的目标中有alice谓词,导致最终No.。这是一个总会失败的目标,但它通过输出fail的中间结果产生了副作用。

答案 1 :(得分:0)

让我们分解代码。首先,你有一些事实:

likes(alice, sports).    % Alice likes sports
likes(alice, music).     % Alice likes music
likes(carol, music).     % Carol likes music
likes(david, animals).   % David likes animals

只要给出这些事实,您就可以进行基本查询:

?- likes(alice, sports).   % Does Alice like sports?
true ;
false.  % no more solutions

所以,是的,爱丽丝喜欢运动(结果是true)。爱丽丝喜欢动物吗?

?- likes(alice, animals).
false.

显然不是。至少,根据我们的数据,我们无法证明爱丽丝喜欢动物。 (请记住,到目前为止我们只有事实,但没有规则,如下所示。)

那么,根据事实,爱丽丝喜欢什么?

?- likes(alice, X).
X = sports ;
X = music.

爱丽丝喜欢运动和音乐。

现在让我们添加您的规则:

likes(david, X) :- likes(X, sports).

这就是说,如果某人(X)喜欢体育, David会喜欢某人(X)。

让我们看看大卫喜欢谁/

?- likes(david, X).
X = animals ;
X = alice ;
false  % no more solutions

所以大卫喜欢动物(因为事实就是如此),大卫喜欢爱丽丝(因为我们有一条规则,如果X喜欢运动,大卫喜欢X,而爱丽丝喜欢运动)。

你的其他规则:

likes(alice, X) :- likes(david, X).

如果大卫喜欢同一个人(X爱丽丝喜欢某人(X)。

添加新规则后,让我们看看爱丽丝喜欢谁:

?- likes(alice, X).
X = sports ;
X = music ;
X = animals ;
X = alice ;
false

爱丽丝喜欢运动和音乐(因为事实是这样说的)。爱丽丝喜欢动物,因为大卫喜欢动物,规则说如果大卫喜欢X,那么爱丽丝喜欢X.爱丽丝也显然喜欢自己,因为根据第一条规则,我们表明大卫喜欢爱丽丝。根据第二条规则,爱丽丝喜欢大卫喜欢的任何人。因此,爱丽丝喜欢爱丽丝。

您可以通过运行trace.然后执行查询来逐步执行。

请注意,使用这些简单的规则和事实可以很好地表现出来。在更复杂的情况下,您必须小心以同样的方式命名规则和事实,因为它可能导致无限的逻辑循环。