recursion - 我怎样才能避免 Prolog 递归中的这个陷阱?

标签 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。我在这方面的尝试导致我打破了递归。感谢您的帮助。

最佳答案

正如 @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,如果路径存在,它的作用与之前相同,或者统一 D<如果失败,0-> 用于在路径有效的情况下放弃选择 D = 0

请注意,您有以下行为:

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

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

这有点奇怪,但因为你想要什么而在意料之中。

关于recursion - 我怎样才能避免 Prolog 递归中的这个陷阱?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41949701/

相关文章:

c++ - "invalid initialization of non-const reference of type ‘int&’ 来自类型为 ‘int’ 的右值 ": Recursive pass-by-reference function

python - 如何递归遍历树并在python中创建访问节点列表

javascript - 原型(prototype)函数内的递归调用

list - 我如何跟踪 Prolog 中的值?

prolog - 将列表转换为仿函数参数

prolog - 插入(I,[],[I,[],[]])。如何向二叉树插入一个值?

list - 从给定索引和多个元素的列表创建子列表。序言

c - 在 C 中使用预递增递归

javascript - 如何理解 JavaScript 中的蹦床?

prolog - 在 Prolog 中寻找最年长的人