Prolog - 帮助理解规则

时间:2012-01-15 14:14:20

标签: prolog nodes

我有一个充满事实的数据库,例如:

checkpoint(checkpoint1,checkpoint2,2).
checkpoint(checkpoint2,checkpoint3,3).
checkpoint(checkpoint3,checkpoint4,4).
checkpoint(checkpoint4,checkpoint5,2).
checkpoint(checkpoint5,checkpoint6,2).

例如checkpoint(firstcheckpoint,secondcheckpoint,timeinminutes)。

然后,以下规则测试是否可以在比赛中的两个检查点之间进行旅程:

journey(X,Y):- checkpoint(X,_,_), checkpoint(_,Y,_),!; checkpoint(Y,_,_), checkpoint(_,X,_),!.

journey(X,Y):- checkpoint(X,Z,_), journey(Z,Y).
journey(X,Y):- checkpoint(Z2,Y,_), journey(X,Z2).

请注意,你不能跳过检查站,你只能先到1,2然后3到达checkpoint4。然而你可以倒退,例如从检查站4回到3。

我知道如果在X和Y之间有一个中间检查点,这个代码检查两个检查点之间是否可以进行旅行,在这种情况下是Z.但是我不太明白Z2在做什么。我认为它只是被用作Z之类的另一个中间体,但为什么它被命名为另一个变量呢?不能将Z2改为Z,它仍然可以工作吗?

2 个答案:

答案 0 :(得分:1)

Z2绝对可以在最后一条规则中重命名为Z,并且规则的逻辑不会改变。作者犹豫使用Z的原因可能是因为该变量并不表示Z在第一条规则中所做的“中点”。

就个人而言,我会使用更具描述性的变量名称 - FromTo听起来像是好人选:

journey(From,To):- checkpoint(From,Mid,_), journey(Mid,To).
journey(From,To):- checkpoint(Someplace,To,_), journey(From,Someplace).

答案 1 :(得分:1)

如果您以相同的方式重命名 all ,则可以重命名变量而不更改规则的含义。

但是第一次旅程规则对我来说是错误的:你期望削减有什么影响? 分离没有机会,导致第一次削减。

只留下第一条规则,然后尝试?- findall((X,Y),journey(X,Y),L). 您将看到唯一的答案L = [ (checkpoint1, checkpoint2)].

所以,来自@dasblinklight(+1)的答案建议更深层次修正变量重命名:只需删除第一个旅程规则......

修改

此程序(没有剪切)扩展了原始规范,允许枚举所有可能的旅程,并且可以匹配原始定义:

journey(X, Y):-
    journey([], X, Y).
journey(Visited, X, Y) :-
    ( checkpoint(X, I, _) ; checkpoint(I, X, _) ),
    \+ memberchk(I, Visited),
    ( I = Y ; journey([X|Visited], I, Y) ).