【发布时间】:2017-12-04 16:59:29
【问题描述】:
我试图了解递归在 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。一旦我们看到 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 ).
【问题讨论】:
-
你应该得到一本基础教科书。 Prolog的艺术很好。也许现在有更好的。
-
当
path(d)达到目标时,回溯不会停止。它继续并找到ce路径。它失败是因为它没有终止于d,而是因为谓词使用write,所以在确定最终成功或失败之前将路径写入输出。正如@TomasBy 建议的那样,如果你不确定;做了什么,你需要买一本教科书或多阅读在线Prolog 文档。 -
@TomasBy 我是从一本基础教科书中举这个例子的。
标签: prolog