2012-04-27 13 views
1

複数の回答を返すプロローグ定義があります。私は代わりに、すべての可能な回答を含む単一のリストを返すことを望みます。プロローグで(複数の個別の回答ではなく)回答のリストを返す方法は?

など。

alpha; 
beta; 
gamma; 
delta; 

[alpha, beta, gamma, delta]; 

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

+0

定義はどうなっていますか? – geekosaur

答えて

1

注意今

test(L, E) :- 
    member(E, L), 
    var(E). 

は、のは言わせてこの述語を使ってリストのすべての自由変数を探したいとします(実際にそれをやりたければ、それは正しい方法ではありません)。

?- 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システムにも当てはまります。

ここに対応するdoc pageです。

+0

非常に興味深く便利です。私はこれが好きです – noted

+0

これはSWI特有の問題ではありません。 3つはすべてISO組み込みです。しかし、 'bagof/3'と' setof/3'はもっと詳しく調べています。 – false

+0

これは質問によると間違った答えです。私は私の答えを更新しました。 –

0

findallを使用します。あなたはsomepred(X)を持っていて、あなたが指定した通り答えが得られます。今度はfindall(X,somepred(X),List)を実行して、Listをすべての回答のリストと統合してみてください。

編集:尋ねたとしてsetofまたはbagofの代わりfindallを使用しては、質問の文脈で間違っています。

setofは明らかに重複している有効なソリューションをスキップするので間違っています。 bagofは、解決策がない場合にに失敗しますが、findallは正しくです。空リスト:[](OPが要求するとおり)を返します。 OPは明らかにするソリューションつのリストを求めたのに対し、ああ、との両方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が返される「すべての可能な答えを含む単一のリスト」を求めました。

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

は自由変数ですLのメンバーとEを統一述語test/2 : test(+L, -E)考えてみましょう:あなたの特定のニーズに応じて、findall/3はフィットではないかもしれません

+0

ああええ、findall()を忘れてしまった。 @willNessの編集に関しては – noted

+0

ありがとうございます。bagofとsetofには必要に応じてバックトラックしないように制御機構( '^')があり、正確なセマンティクスがOPに与えられていないので、間違った主張解決策に失敗したことに関して適切に議論されていない。 – m09

+0

@Mogよく私は、「可能なすべての解決策を含む1つのリスト」が必要な場合、空のリストは当然の解決策のリストを表していると仮定しました。 –

関連する問題