【问题标题】:Prolog: Order of clauses for finding path in graphProlog:在图中查找路径的子句顺序
【发布时间】:2018-11-26 08:29:17
【问题描述】:

我有一个带有入口和出口节点的循环图,我想找出从任何入口到任何出口节点的所有路径。

entry(a).
exit(e).
exit(f).

next(a, b).
next(b, c).
next(b, d).
next(c, e).
next(d, f).

/* Cycle */
next(c, d).
next(d, b). 

/* path(entrynode, exitnode, pathtrace) */
path(X, Y, P)       :- entry(X), path2(X, Y, P).
path2(X, Y, [Y])    :- next(X, Y), exit(Y).
path2(X, Y, [P|PS]) :- next(X, P), path2(P, Y, PS).

我的 path2 谓词在非循环图上效果很好。现在我想把它扩展到循环的。我所要做的就是检查一个新的可能节点是否已经在我的访问节点列表中。为此,我会将not(member(X, PS)) 添加到我的最后一条规则中。

如果我在递归之前添加它,它总是返回 false。如果我在递归 Prolog 尝试首先找到路径并用完堆栈之后添加它。它返回正确的答案,但它试图找到更多并卡住了。

因此:我应该在哪里添加支票或者我做错了什么/我可以做得更好?

【问题讨论】:

    标签: prolog


    【解决方案1】:

    您的path2/3 谓词需要一个额外的参数,因为您的第三个参数是已构建 的路径,而不是已访问节点的列表。 IE。您不能简单地将\+ member(X,Ps) 目标添加到谓词的最后一条规则,因为Ps 受递归调用的约束。试试吧:

    path(X, Y, P) :-
        entry(X),
        path2(X, Y, [], P).
    
    path2(X, Y, _Visited, [Y]) :-
        next(X, Y),
        exit(Y).
    path2(X, Y, Visited, [P|PS]) :-
        next(X, P),
        \+ member(P, Visited),
        path2(P, Y, [P| Visited], PS).
    

    示例调用:

    | ?- path(X, Y, P).                        
    
    P = [b,c,e]
    X = a
    Y = e ? ;
    
    P = [b,c,d,f]
    X = a
    Y = f ? ;
    
    P = [b,d,f]
    X = a
    Y = f ? ;
    
    no
    

    【讨论】:

      猜你喜欢
      • 2012-11-18
      • 1970-01-01
      • 1970-01-01
      • 2011-11-30
      • 1970-01-01
      • 2023-04-10
      • 1970-01-01
      • 2023-01-23
      • 2018-10-10
      相关资源
      最近更新 更多