如何在Prolog递归中避免这个陷阱?

时间:2017-01-31 04:35:36

标签: recursion prolog

我的目标是能够遍历图中的节点并在Prolog中输出路径的长度。我正在使用递归,我坚持这个问题。这是我到目前为止的尝试。

edge(a,b).
edge(b,c).
edge(a,d).
edge(d,f).

distance(X,Y,1) :- edge(X,Y).
distance(X,Y,Dis) :- edge(X,Z), distance(Z, Y, D), Dis is D +1.

问题:如果路径无效,我希望能说Dis = 0.如同,没有边连接两个节点,Dis = 0.目前我的代码对于无效路径说false。我在这方面的努力导致我打破了递归。谢谢你的帮助。

1 个答案:

答案 0 :(得分:4)

正如@Hashcut在他的评论中所说,如果Dis = 0,那么X = Y更有意义。事实上,如果路径无效,您的谓词就会失败,这是完全符合逻辑的。

现在,如果你真的想做你说的话,你可以这样做:

distance_(X,Y,1) :- edge(X,Y).
distance_(X,Y,Dis) :- edge(X,Z), distance_(Z, Y, D), Dis is D + 1.

distance(X,Y,D) :- distance_(X,Y,D) -> true ; D = 0.

我们只需将您的原始谓词重命名为distance_,然后创建谓词distance,如果路径存在,则与之前相同,或者将D0统一起来如果失败了如果路径有效,->用于放弃选择D = 0

请注意,您有以下行为:

?- distance(a,a,X).
X = 0.

?- distance(b,f,X).
X = 0.

这有点奇怪,但是因为你想要的而预期。