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に行く。いったんdを見ると、私たちはやめます。私は4行目の出力 'ed'を理解できません。なぜそれがe、dになるのか、真実に戻るのか。私はまた、どのように演算子 ';'を理解していない別の結果を照会するときに機能します。それは次の結果を得ることを意味しますか?
別の例:次のプログラムは、あるノードから別のノードへのすべての可能なパスを書き込みます。私は、このプログラムでどのようにループが動作して、異なるパスのリストを表示するのか理解していません。
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).
基本的な教科書が必要です。プロローグの芸術は良いです。多分今はもっと良いものがあるでしょう。 –
'path(d)'が達成された場合、バックトラックは停止しません。それは継続して、 'ce'パスを見つけます。 'd'で終了しないので失敗しますが、述部で' write'が使用されるため、最終的な成功または失敗が判断される前にパスが出力に書き込まれます。 @TomasByが示唆しているように、 ';'が何をしているのかわからないのであれば、テキストブックを入手するか、オンラインのPrologのドキュメントをもっと読む必要があります。 – lurker
@TomasBy私はこの例を基本的な教科書から取っています。 – patzi