0

ルーティング関数を作成しようとしていますが、必要な結果が得られないようです。これがこれまでのコードです。先行者は、N にリンクされているノードを見つけて、それを P として返します。

traceroute(_,L) :- member((A,A),L).
traceroute(N,L) :-
   predecessor(N,P),
   append(N,L,L1),
   traceroute(P,L1).

実行すると、traceroute(placeA, Y).このデータが返されます.. Y = [ (_G575, _G575)|_G579] .

基本的に、traceroute の最初の行では、いずれかのメンバーがそれ自体の先行者である場合、再帰を終了しようとしています。2 番目の部分は、すべてのノードをループし、それらをリスト (L) に追加する必要があります。

ノードは [(placeA,placeB),(placeB,placeC)] のように保存され、リストは [placeA,placeB,placeC] のように保存する必要があります

なぜこれらの結果が得られるのか理解できません。

4

1 に答える 1

2

このように見える解決策 (正しくない場合) は、通常、必要な場所で用語を接地 (インスタンス化) していないことを意味します。

コードがどのように機能するのか完全にはわかりませんが、主な問題は、traceroute の 2 番目の引数に非グラウンド変数を渡していることです。

メンバー呼び出しでは、L は非グラウンドであるため、実際には、完全にインスタンス化されていないリストの要素であるフォーム (A,A) のアイテムを返すようにプロローグに要求しています。これはあまり意味がありませんが、この種のことを行うことが役立つ場合があるため、プロローグは忠実に準拠し、(バックトラック時に) 増加する長さのリストを生成します (どこにも長さを指定していないため) 非接地のある時点で項目 (A,A) を持つ変数。すなわち:

?- traceroute(placeA, Y).
Y = [ (_G271, _G271)|_G275] ;
Y = [_G274, (_G271, _G271)|_G278] ;
Y = [_G274, _G277, (_G271, _G271)|_G281] ;
Y = [_G274, _G277, _G280, (_G271, _G271)|_G284] ;

グラウンドである Y の値を渡すか、述語内で受け取る値をさらに制限するか、場合によってはその両方を行う必要があります。

また、2 番目の節は実際には実行されませんが、同様の問題があります。再び非グラウンドである L が N に追加されて、非グラウンドでもある L1 が生成されます。この述語はこれを再帰的に行うため、最終的なリストは常に根拠のないものになります。

于 2009-12-10T23:57:15.000 に答える