以下Prolog程序中出现意外行为

时间:2017-12-04 04:03:36

标签: prolog

我试图理解Prolog中的递归是如何工作的。请考虑以下计划。

edge(a,b).
edge(b,c).
edge(c,d).
edge(a,d).
edge(c,e).
path(d).
path(Vertex) :-  edge(Vertex, Next), write(Next), path(Next).

运行路径(a)。

输出:

?- path(a).
bcd
true ;
ed
true;
false

我不明白的是这个程序的循环部分。所以我们从a开始然后转到b,c和d。一旦我们看到我们就停止了。我无法理解第四行的输出'ed'。为什么它会转到e,d然后返回true。我也不明白运营商是怎么';'查询另一个结果时有效。这是否意味着获得下一个可能的结果?

另一个示例:以下程序将所有可能的路径从一个节点写入另一个节点。我不明白循环如何在这个程序中工作以显示不同的路径列表。

 link( a, b ).
    link( a, d ).
    link( b, c ).
    link( d, e ).
    link( e, c ).
    link( e, f ).
    link( f, a ).
    link( f, g ).
    link( f, j ).
    link( g, h ).
    link( h, i ).
    link( i, j ).


not( X ) :- X, !, fail.
not( _ ).

writeallpaths( Node, Node ) :-
   write( Node ), write( ' is ' ), write( Node ), nl.
writeallpaths( Node, Next ) :-
   listpath( Node, Next, [Node], List ),
   write( Node ), write( ' to ' ), write( Next ), write( ' is ' ),
   writepath( List ),
   fail.

writepath( [] ) :-
   nl.
writepath( [Head|Tail] ) :-
   write( ' ' ), write( Head ), writepath( Tail ).

listpath( Node, End, Outlist ) :-
   listpath( Node, End, [Node], Outlist ).

listpath( Node, Node, _, [Node] ).
listpath( Node, End, Tried, [Node|List] ) :-
   link( Node, Next ),
   not( member( Next, Tried )),
   listpath( Next, End, [Next|Tried], List ).

1 个答案:

答案 0 :(得分:0)

  

我也不了解运营商的情况&#39 ;;'查询另一个结果时有效。这是否意味着获得下一个可能的结果?

是。当你进入时会发生什么?找到解决方案" bcd"后,Prolog试图找到替代解决方案。在你的情况下,它会回归" (回溯)到" c"因为它有另一条通往" e"并继续从那里搜索,直到它到达" d"。显然,它并没有打印出整个解决方案,因为Prolog不会回到最开始,而只是回到" c",所以只有节点之后" C"印刷。

此外,您始终可以使用trace / 0谓词,它可以让您详细了解Prolog如何执行您的代码。