2016-04-06 32 views
0
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变成aliceProlog如何回答此查询?

另一条路线:

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

可能有人请指出我的想法是错误的。

+0

变量永远不会“实例化” - 它们是**统一的**。 – Enigmativity

+0

*目标*不会变成“喜欢(大卫,运动)”。在'like(alice,X)'的谓词体中,* goal *是'likes(david,X)',当'X'与'sports'统一时,它是真实的,所以'X = sports'是或者至少是“a”)解决方案,“喜欢(大卫,X)”。由于这是'likes(alice,X)'的谓词子句的结尾,那么这意味着'likes(alice,X)'用'X = sports'成功。 – lurker

+0

@lurker - 我不确定这是否更清晰。变量在统一之前已经存在 - 统一之前它是一个自由变量,但之后它与现有原子或变量简单相同。统一时实际上没有任何东西。如果一个变量与一个原子统一,那么这个变量就会有效地成为对原子的引用 - 没有任何东西被实例化。如果一个变量与另一个(自由)变量统一起来,这变得更加复杂,因为你根本不能说任何事情都被实例化了。 – Enigmativity

回答

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).导致X统一与alice,所以原来的目标将表明alicelikesalice

当我跑到你的代码这一目标:

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

...我得到这样的输出:

 
sports 
music 
animals 
alice 
No. 

随着最后No.所造成的,因为我在目标有fail谓词。这是总是将失败的一个目标,但它通过输出X中间结果所产生的副作用。

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, X). 
X = sports ; 
X = music. 

爱丽丝喜欢运动和音乐。

现在,让我们在规则中添加:

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

这是说,大卫有喜欢的人(X)如果有人(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.来执行分步执行,然后执行您的查询。

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