最初に同様のクエリを考えてみましょう:[編集:独自の定義を追加せずにこれを実行します; member/2
すでに定義されています]
?- member(a,[b,a]).
true.
この場合、最適な答えが得られます。解決策は1つだけです。しかし、リスト内の要素を交換すると、次のようになります。
?- member(a,[a,b]).
true ;
false.
論理的には、どちらもクエリが真であるという単なる肯定です。
違いの理由は、2番目のクエリで、リストの要素としてtrue
見つかった直後に回答が与えられるためです。a
残りのリスト[b]
には適切な要素が含まれていませんが、これはまだ調査されていません。要求(ヒットSPACEまたは;)があった場合にのみ、リストの残りの部分が試され、それ以上の解決策はありません。
基本的に、この小さな違いは、計算が完全に終了したときと、まだやるべきことがあるときのヒントを提供します。単純なクエリの場合、これは違いを生みませんが、より複雑なクエリでは、これらのオープンな選択肢(選択ポイント)が蓄積され、メモリを使い果たす可能性があります。
古いトップレベルは、解決策がなかったとしても、それ以上の解決策を見たいかどうかを常に尋ねてきました。
編集:
次の答えがない場合にそれを求めないようにする機能は、実装の詳細に大きく依存します。同じシステム内で、同じプログラムがロードされている場合でも、異なる結果が得られる可能性があります。ただし、この場合、SWIの組み込み定義member/2
を使用していましたが、組み込み定義を上書きする独自の定義を使用しました。
SWIは、次の定義を組み込みとして使用します。これは、論理的には同等ですが、SWIにとって不要な選択ポイントを回避しやすくなりますが、他の多くのシステムはこれから利益を得ることができません。
member(B, [C|A]) :-
member_(A, B, C).
member_(_, A, A).
member_([C|A], B, _) :-
member_(A, B, C).
さらに複雑にするために:多くのプロローグには異なるトップレベルがあり、クエリに変数が含まれていない場合、それ以上の回答を要求することはありません。したがって、これらのシステム(YAPなど)では、間違った印象を与えます。
これを確認するには、次のクエリを試してください。
?- member(X,[1]).
X = 1.
SWIは、これが唯一の答えであると再び判断できます。しかし、たとえば、YAPはそうではありません。