Prolog で目標に対するすべての解決策を見つけるにはどうすればよいですか?
-
13-09-2019 - |
質問
次のように値を次々に返す述語 P1 があります。
-? P1(ARGUMENTS, RETURN).
-? RETURN = 1;
-? RETURN = 2;
-? RETURN = 3;
-? fail.
P2 と呼ばれる別の述語もあります。
P2(ARGUMENTS, LIST) :- P1(ARGUMENTS, RETURN),... % SOMEHOW HERE I NEED TO INSERT ALL VALUES OF RETURN TO LIST.
すべての値を見つけるにはどうすればよいですか RETURN
そしてそれらをに割り当てます LIST
?
解決
使用 findall
これを達成するには:
P2(ARGUMENTS, LIST) :- findall(X, P1(ARGUMENTS, X), LIST).
これは、 bagof
質問に記載されている関数 アンダース・リンダールによってリンクされています。2 つの関数 (および 3 番目の関数) の関係については十分な説明があります。 setof
) ここ:
違いを説明するには、少しの例を考えてみましょう。
listing(p). p(1,3,5). p(2,4,1). p(3,5,2). p(4,3,1). p(5,2,4).
次の目標を試してみてください。(回答ディスプレイは、スペースを節約するために変更されました。)
?- bagof(Z,p(X,Y,Z),Bag). Z = _G182 X = 1 Y = 3 Bag = [5] ; Z = _G182 X = 2 Y = 4 Bag = [1] ; Z = _G182 X = 3 Y = 5 Bag = [2] ; Z = _G182 X = 4 Y = 3 Bag = [1] ; Z = _G182 X = 5 Y = 2 Bag = [4] ; No ?- findall(Z,p(X,Y,Z),Bag). Z = _G182 X = _G180 Y = _G181 Bag = [5, 1, 2, 1, 4] ; No ?- bagof(Z,X^Y^p(X,Y,Z),Bag). Z = _G182 X = _G180 Y = _G181 Bag = [5, 1, 2, 1, 4] ; No ?- setof(Z,X^Y^p(X,Y,Z),Bag). Z = _G182 X = _G180 Y = _G181 Bag = [1, 2, 4, 5] ; No
述語
bagof
そしてsetof
目標の自由変数の個々のバインディングの収集コレクション。setof
複製せずにコレクションのソートバージョンを生成します。結合変数を避けるために、実存的な量子式を使用します。たとえば、目標bagof(Z,X^Y^p(X,Y,Z),Bag)
「の袋」を求めますZ
存在するようなものですX
そして存在しますY
そのようなp(X,Y,Z)
".findall
のように動作しますbagof
すべての自由変数が自動的に実存的に定量化されています。加えてfindall
空のリストを返します[]
目標の満足度はありませんがbagof
失敗します。
所属していません StackOverflow