Prolog では、テンプレート (変数を含む構造体) を提供し、それに対する一連の制約を満たすことで問題を解決することがよくあります。些細な例は次のとおりです。
go(T) :-
T = [_, _, _],
member(cat, T),
member(dog, T),
member(mouse, T).
実際には、一連の制約は修正されるのではなく、別の方法で生成されます。各制約を順に満たすために、再帰的な述語を記述する必要があります。
go(T) :-
T = [_, _, _],
findall(A, animal(A), As),
% satisy member(A, T) for each A in As
fill_in_animals(T, As)
fill_in_animals(T, []).
fill_in_animals(T, [A|Rest]) :-
member(A, T),
fill_in_animals(T, Rest).
私の質問はリスト関連の制約に関するものではなく、制約へのパラメーターでさえ、上記で使用されている比較的単純なヘルパー述語に渡されるリストとして常に簡単に生成できるとは限らないことに注意してください。実際には、ヘルパーは、私が毎回書くかなり不格好な述語であることがわかりました。
- テンプレート、制約に使用されるいくつかのパラメーター (したがって、テンプレートの変数を有用な値にバインドするため)、およびそれがどの制約に従っているかを示すための変数を受け入れます。
- この反復で満たす制約を生成し、それをテンプレートに適用します。
- 残りの制約を満たすことができるように、再帰的に自分自身を呼び出します。
私が探しているのはfindall
、一連の目標を次々と満たす、などの行に沿った述語です。何かのようなもの:
% satisfyall(:Goal)
% backtracks on Goal but keeps all bindings from each fully satisfied goal.
satisfyall((animal(A), member(A, T)))
私が探している答えは、この形である必要はありません。実際には、目標をバックトラックすることと、そこから生じるバインディングの各セットを維持することの間には矛盾があるかもしれません。
何が役立つかが合理的に明確になるように、私の問題を説明できたことを願っています。(そうでない場合はお知らせください。)長々とした質問を事前にお詫びします!
更新(2年後)
今日の後半に試して、質問を更新します。
を試したのと同じ日に質問を更新するとは決して言わなかったことに注意してください。;-)
@CapelliC は私を正しい方向に導いてくれました。かなりうまく機能しているように見えるパターンを見つけました。
?- Gs = [member(red),member(blue)], T = [_,_], foreach(member(G, Gs), call(G, T)).
T = [red, blue] ;
T = [blue, red] ;