【问题标题】:How can I avoid this pitfall in my Prolog recursion?在我的 Prolog 递归中如何避免这个陷阱?
【发布时间】:2017-06-16 10:11:23
【问题描述】:

我的目标是能够遍历图中的节点并在 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。我在这方面的尝试导致我打破了递归。感谢您的帮助。

【问题讨论】:

  • 你确定距离的语义吗? Dis = 0 是否意味着两个节点相同?这可以编码为距离(X,X,0)。

标签: recursion prolog


【解决方案1】:

正如@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.

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-16
    • 2015-04-08
    • 1970-01-01
    • 1970-01-01
    • 2020-05-28
    • 2019-07-14
    相关资源
    最近更新 更多