如何在Prolog中找到目标的所有解决方案?

时间:2009-09-23 19:37:42

标签: prolog prolog-setof

我有谓词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

1 个答案:

答案 0 :(得分:17)

使用findall来完成此任务:

P2(ARGUMENTS, LIST) :- findall(X, P1(ARGUMENTS, X), LIST).

这与Anders Lindahl关联的bagof function mentioned in the question有关。关于两个函数之间的关系有很好的解释(第三个函数setofhere

  

说明差异考虑   一个小例子:

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
     

谓词bagofsetof会产生   个人绑定的集合   目标中的自由变量。 setof   产生一个排序版本   没有重复的集合。至   避免绑定变量,使用   存在量词表达。对于   示例目标   bagof(Z,X^Y^p(X,Y,Z),Bag)要求   “Z的袋子就是存在的   一个X,并且存在Y   p(X,Y,Z)“。findall就像bagof一样   自动包含所有自由变量   存在量化的。此外   findall会在那里返回一个空列表[]   没有目标满意度,而bagof   失败。