2

The following codes give these results:

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

But when I want that all elements will share the same unbound variable (instead of a), then things are not working as it is supposed:

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

Why _G1918, _G1912, and _G1906 are not bound to each other? is that a bug in swi-prolog?

Fibo Kowalsky
  • 1,198
  • 12
  • 23
  • Duplicate of http://stackoverflow.com/questions/5305833/correct-use-of-findall-3-especially-the-first-template-argument ? –  Jul 01 '16 at 14:01

2 Answers2

2

You can use bagof/3 for that:

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

From SWI-Prolog's documentation:

findall/3 is equivalent to bagof/3 with all free variables bound with the existential operator (^), except that bagof/3 fails when Goal has no solutions.

In your query X is a free variable, so the result you get is the same with the one for bagof/3 with 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].
Tudor Berariu
  • 4,910
  • 2
  • 18
  • 29
  • Thanks for noting a connection between findall/3 and bagof/3. Working all the time with findall/3 now bagof/3 seems very unintuitive. – Fibo Kowalsky Dec 07 '14 at 19:16
1

it's not a bug, the 'all solutions' builtins differs in variable quantification handling.

findall/3 it's the simpler model. For your case, bagof/3 will work, but you'll need to indicate the aggregation variable:

?- X = Y, bagof(Element, Z^( member(Z, [a,b,c]), Element = Z:X  ), Set).
X = Y,
Set = [a:Y, b:Y, c:Y].
CapelliC
  • 59,646
  • 5
  • 47
  • 90
  • Thanks it works. The output is what I need but don't understand how it works. http://www.swi-prolog.org/pldoc/man?section=allsolutions says that: +Var^Goal tells bagof/3 not to bind Var in Goal. Also unclear. The problem was in X that it was not bind; and it is solved by telling not to bind Z? but binding of Z was ok. Please could you explain more? – Fibo Kowalsky Dec 07 '14 at 19:07
  • Ok, I got the answer from @Tudor Berariu 's answer on the question. – Fibo Kowalsky Dec 07 '14 at 19:15
  • 1
    yes, Tudor explained a bit more. The documentation could be more clear. I think of this problem as a different term copying behaviour (findall doesn't keep 'external to goal' variables sharing) – CapelliC Dec 07 '14 at 19:25