为什么在swi-prolog中findall / 3忽略变量绑定?

时间:2014-12-07 18:46:18

标签: prolog prolog-setof prolog-findall

以下代码给出了以下结果:

?- X = a, findall(Element, ( member(Z, [a,b,c]), Element = Z:X  ), Set).
X = a,
Set = [a:a, b:a, c:a].

但是,当我想要所有元素将共享相同的未绑定变量(而不是a)时,事情就不会像预期的那样工作:

?- X = Y, findall(Element, ( member(Z, [a,b,c]), Element = Z:X  ), Set).
X = Y,
Set = [a:_G1918, b:_G1912, c:_G1906]. 

为什么_G1918,_G1912和_G1906没有相互绑定? 这是swi-prolog中的一个错误吗?

2 个答案:

答案 0 :(得分:2)

您可以使用bagof/3

?- X = Y, bagof(Element, Z^( member(Z, [a,b,c]), Element = Z:X  ), Set).
X = Y,
Set = [a:Y, b:Y, c:Y].

来自SWI-Prolog的文档:

  

findall / 3相当于bagof / 3,所有自由变量都与之绑定   存在运算符(^),除了当目标有bagof / 3失败   没有解决方案。

在您的查询中,X是一个自由变量,因此您获得的结果与bagof/3 X^的结果相同:

?- X = Y, bagof(Element, X^Z^( member(Z, [a,b,c]), Element = Z:X  ), Set).
X = Y,
Set = [a:_G2115, b:_G2109, c:_G2103].

答案 1 :(得分:1)

它不是一个错误,所有的解决方案' builtins在变量量化处理方面有所不同。

findall / 3它是更简单的模型。对于您的情况,bagof / 3将起作用,但您需要指出聚合变量:

?- X = Y, bagof(Element, Z^( member(Z, [a,b,c]), Element = Z:X  ), Set).
X = Y,
Set = [a:Y, b:Y, c:Y].