1

複数の回答を返すプロローグ定義があります。これの代わりに、可能なすべての回答を含む単一のリストを返したいと思います。

例えば

alpha;
beta;
gamma;
delta;

[alpha, beta, gamma, delta];

これはプロローグでどのように行うことができますか?

4

2 に答える 2

1

特定のニーズによってはfindall/3、適合しない場合があることに注意してください。

自由変数のメンバーと統合する述語test/2 : test(+L, -E)を考えてみましょう。EL

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 システムに当てはまるかどうかはわかりません。

対応するドキュメントページは次のとおりです。

于 2012-04-27T09:35:10.093 に答える
0

を使用してfindall。指定したとおりの答えがsomepred(X)得られます。ここで実行して、すべての回答のリストと統合されているfindall(X,somepred(X),List)ことを確認してください。List

編集:尋ねられたように、質問の文脈ではsetoforbagofの代わりに使用findall

setofたまたま重複している有効なソリューションをスキップするため、明らかに間違っています。解決策がない場合はbagof 失敗しますが、空のリストをfindall正しく「返す」[] (OP の要求に従って)。ああ、両方とも、自由変数の代替バインディングでバックトラックしますが、OP はソリューションの 1 つのリストを「返す」ように明確に要求しましたbagofsetof つまりバックトラックはありません。ウィット:

?- [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は「考えられるすべての回答を含む単一のリスト」を返すように求めました。

編集:回答がない場合のすべての回答のリストは空のリストです。

于 2012-04-27T08:24:55.837 に答える