1

コード スニペットについてお聞きしたいことがあります。

insert_pq(State, [], [State]) :- !.
insert_pq(State, [H|Tail], [State, H|Tail]) :-
    precedes(State, H).
insert_pq(State, [H|T], [H|Tnew]) :-
    insert_pq(State, T, Tnew).
precedes(X, Y) :- X < Y.  % < needs to be defined depending on problem

この関数は、アイテムをプライオリティ キューに明確に追加します。私が抱えている問題は、最初の行のカットオフ演算子です。おそらく、呼び出しがこのコード行に到達するたびに、これがクエリに対する唯一の可能な解決策であり、関数呼び出しは単純に巻き戻されます (または巻き上げられますか?)。後戻りして別の解決策を検索する必要はありません。クエリ。

したがって、ここでのこのカットオフは不要です。私の推論は正しいですか?

4

3 に答える 3

1

はい、半分まともな Prolog コンパイラは、2 番目の引数が空のリストである句が他にないことに気付くでしょう。

2 番目と 3 番目の節を組み合わせて、ローカル カット (precedes(...) -> ... ; ...) を使用したいのですが、2 番目の節の末尾の方が便利です。

于 2009-11-13T20:21:12.443 に答える
1

マッチングの候補述語を除去するためにコンパイラーが使用する特定の手法は、引数の索引付けと呼ばれます。プロローグの実装が異なれば、デフォルトで異なる数の引数を索引付けする可能性があります。

したがって、引数がインデックス化されているかどうかが心配な場合は、プロローグでインデックスを使用している引数の数を確認する必要があります。SWI リファレンス マニュアルによると、デフォルトでは最初の引数のみにインデックスが付けられます。したがって、あなたの場合、カットは実際には冗長ではありません。index/1ただし、述語を使用してどの引数にインデックスを付ける必要があり、どの引数hash/1が上記のリンクにリンクされているかを明示的に規定できます。

または、引数を並べ替えるか、カットをそのままにしておくこともできます。

于 2009-11-14T04:05:15.560 に答える
0

はい。それで合っています。たとえコンパイラが中途半端でなくても (SWI Prolog は確かにそうです)、2 番目と 3 番目の句を照合することは最悪の場合であり、すぐに失敗します。

ただし、2 番目の句が一致する場合、3 番目の句も一致します。これは意図した動作ですか?

于 2009-11-13T22:26:08.830 に答える