2014-12-06 106 views
0

我刚开始尝试自学Prolog,在七周内同时使用七种语言和现在学习Prolog!我遇到了一些困惑。在SLSW有一天它呈现以下知识库:Prolog顺序的统一

cat(lion). 
cat(tiger). 

dorothy(X,Y,Z):- X = lion, Y = tiger, Z = bear. 
twin_cats(X,Y):- cat(X), cat(Y). 

当与twin_cats(X,Y).问,它生产的所有的可能性两只猫,包括X = lion, Y = lionX = tiger, Y = tiger。乱七八糟的是我试图给twin_cats(X,Y)规则添加一个目标,以便它只报告两只不同的猫。起初,我试图

cat(lion). 
cat(tiger). 

dorothy(X,Y,Z):- X = lion, Y = tiger, Z = bear. 
twin_cats(X,Y):- \+(X = Y), cat(X), cat(Y). 

要其序言回应notwin_cats(X,Y).然而,当我刚换的目标,为了

cat(lion). 
cat(tiger). 

dorothy(X,Y,Z):- X = lion, Y = tiger, Z = bear. 
twin_cats(X,Y):- cat(X), cat(Y), \+(X = Y). 

序言现在给我什么,我一直在寻找,两个答案X = lion, Y = tigerX = tiger, Y = lion

所以这是我的问题,Prolog统一变量的方式是否存在一些固有的顺序?这似乎是因为目标的顺序(即使它们全部由and分开)都会改变查询的结果。在第二个工作KB中,我想我知道它是如何统一的。首先统一为cat(X),然后cat(Y)然后检查它们是否相同。如果他们移动到下一个组合等,直到没有组合,并报告通过所有三个目标的两个案例。但是对于第一个KB,当它首先检查是否X = Y时,该目标是否应该是真的,因为变量尚未统一?

+0

Prolog统一**术语**,其中变量只是一个重要的情况 – CapelliC 2014-12-06 19:00:53

+0

[在Prolog查询中带有变量的\\ \\ \\问题]的可能重复(http://stackoverflow.com/questions/5971967 /带有变量的序列查询问题) – celeriko 2014-12-06 19:18:06

+0

'\ +(X = Y)'表示“'X'不能与'Y'统一。 - 变量统一是匹配的一部分,这是一种证明目标的机制,它按照从左到右的顺序完成,就像它们被写入一样。 – 2014-12-06 21:49:32

回答

1

所以这是我的问题,是否有一些固有的排序方式,Prolog统一变量?

是,序言试图在你写的为了统一(和失败,如果不能够):

clause:- 
    <unifies first>, 
    <unifies second>… 

您尤其可以看到,经过trace.(这是SWI),变量名称由内部名称改为:

[trace] ?- twin_cats(X,Y). 

true. 

    Call: (6) twin_cats(_G970, _G971) ? creep 
    Call: (7) cat(_G970) ? creep 
    Exit: (7) cat(lion) ? creep 
    Call: (7) cat(_G971) ? creep 
    Exit: (7) cat(lion) ? creep 
    Call: (7) lion=lion ? creep 
    Exit: (7) lion=lion ? creep 
    Redo: (7) cat(_G971) ? creep 
    Exit: (7) cat(tiger) ? creep 
    Call: (7) lion=tiger ? creep 
    Fail: (7) lion=tiger ? creep 
    Redo: (6) twin_cats(lion, tiger) ? creep 
    Exit: (6) twin_cats(lion, tiger) ? creep 
X = lion, 
Y = tiger ; % first redo 
    Redo: (7) cat(_G970) ? creep 
    Exit: (7) cat(tiger) ? creep 
    Call: (7) cat(_G971) ? creep 
    Exit: (7) cat(lion) ? creep 
    Call: (7) tiger=lion ? creep 
    Fail: (7) tiger=lion ? creep 
    Redo: (6) twin_cats(tiger, lion) ? creep 
    Exit: (6) twin_cats(tiger, lion) ? creep 
X = tiger, 
Y = lion ; % second redo 
    Redo: (7) cat(_G971) ? creep 
    Exit: (7) cat(tiger) ? creep 
    Call: (7) tiger=tiger ? creep 
    Exit: (7) tiger=tiger ? creep 
    Fail: (6) twin_cats(_G970, _G971) ? 
false. 

Furhermore,\+不unifiy。它也没有对变量设置任何限制,以便他们以后可以统一。它只是调用后来发生的事情,如果它真的发生了,就会失败