複数の回答を返すプロローグ定義があります。これの代わりに、可能なすべての回答を含む単一のリストを返したいと思います。
例えば
alpha;
beta;
gamma;
delta;
に
[alpha, beta, gamma, delta];
これはプロローグでどのように行うことができますか?
複数の回答を返すプロローグ定義があります。これの代わりに、可能なすべての回答を含む単一のリストを返したいと思います。
例えば
alpha;
beta;
gamma;
delta;
に
[alpha, beta, gamma, delta];
これはプロローグでどのように行うことができますか?
特定のニーズによってはfindall/3
、適合しない場合があることに注意してください。
自由変数のメンバーと統合する述語test/2 : test(+L, -E)
を考えてみましょう。E
L
test(L, E) :-
member(E, L),
var(E).
ここで、この述語を使用してリストの自由変数をすべて見つけたいとしましょう (注: 本当にそうしたいのであれば、それは正しい方法ではありません。findall/3
動作を指摘するだけです):
?- findall(X, test([A, 3, C], X), Xs).
Xs = [_G32, _G29].
findall/3
良い答えであなたに答えますが、モジュラスは変数の名前変更です!
?- bagof(X, test([A, 3, C], X), Xs).
Xs = [A, C].
また
?- setof(X, test([A, 3, C], X), Xs).
Xs = [A, C].
しかし、トリックを行います。
ここで述べたことが SWI-Prolog 以外の Prolog システムに当てはまるかどうかはわかりません。
対応するドキュメントページは次のとおりです。
を使用してfindall
。指定したとおりの答えがsomepred(X)
得られます。ここで実行して、すべての回答のリストと統合されているfindall(X,somepred(X),List)
ことを確認してください。List
編集:尋ねられたように、質問の文脈ではsetof
orbagof
の代わりに使用findall
setof
たまたま重複している有効なソリューションをスキップするため、明らかに間違っています。解決策がない場合はbagof
失敗しますが、空のリストをfindall
正しく「返す」[]
(OP の要求に従って)。ああ、両方とも、自由変数の代替バインディングでバックトラックしますが、OP はソリューションの 1 つのリストを「返す」ように明確に要求しましたbagof
。setof
つまり、バックトラックはありません。ウィット:
?- [user].
|: test(L,E):- member(E,L),var(E).
|:
% user://2 compiled 0.00 sec, 124 bytes
Yes
?- findall(X, (test([A,3,A],X) , member(A,[1,2]) ) , Xs).
X = _G546
A = _G536
Xs = [1, 2, 1, 2] ;
No
?- bagof(X, (test([A,3,A],X) , member(A,[1,2]) ) , Xs).
X = _G534
A = 1
Xs = [1, 1] ;
X = _G534
A = 2
Xs = [2, 2] ;
No
?-
しかし、OPは「考えられるすべての回答を含む単一のリスト」を返すように求めました。
編集:回答がない場合のすべての回答のリストは空のリストです。