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)
。然后我不知道。
请有人指出我的想法存在缺陷。
答案 0 :(得分:0)
鉴于你的代码,Prolog会尝试将目标与他的第一个事实likes(alice, sports).
统一起来,并且它会成功。 X
将与sports
统一。
如果您要求Prolog继续,那么接下来将X
与music
统一起来(第二个事实)。
如果你再次继续,它会跳过接下来的三个事实/规则,并试图证明likes(alice,X) :- likes(david,X).
。这会导致尝试证明likes(david,X)
成功与likes(david,animals)
成功,因此X
在原始目标中会与animals
统一。
如果你要求它再次继续,你会发现它试图证明likes(david,X) :- likes(X,sports).
导致X
与alice
统一,所以最初的目标会建议{{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.
然后执行查询来逐步执行。
请注意,使用这些简单的规则和事实可以很好地表现出来。在更复杂的情况下,您必须小心以同样的方式命名规则和事实,因为它可能导致无限的逻辑循环。