On 15/09/16 10:20, Julio Di Egidio wrote:
> On Thursday, September 15, 2016 at 9:26:27 AM UTC+2, Jan Wielemaker
> wrote:
>
> On 09/15/2016 09:15 AM, Julio Di Egidio wrote:
>> Hello guys, a question if you won't mind:
>>
>> I am trying to collect terms with findall but I am losing the
> bindings.
>>
>> Does findall/[3-4] duplicate terms before collecting?
>
> Yes. There isn't much else it can do. In *theory* it could share
> terms that predate the findall call and are not instantiated by it.
> Finding that a term predates a call isn't too hard (it is just
> further down the stack), but figuring out whether or not it has been
> instantiated will be rather hard (=slow). Without that, copying is
> the only option.
>
>
> I have had look into pl-bag.c, but the code itself does not make
> clear why that must be the case, i.e. why findall cannot just keep
> generated terms as they are. Any way you can explain it, I mean
> unless it requires writing a little treatise? :)
It is fairly easy: after the goal generates a solution, the system
backtracks for the next solution. Any term created while running
the goal is thus destroyed. If the term is older than the findall
goal this is of course not true, but any instantiation done by the
goal will be lost.
In general, variations of findall(X, member(X, List), XL) is not a
very good idea. You typically can get the same results using
library(apply) and library(yall) without copying anything. That
is often faster and at least as important it avoids all semantic
issues around copying (and saves memory).
Cheers --- Jan
>
> In any case, thank you both, Jan and Carlo, for your answers.
>
> Julio
>
> bagof/3 also copies all variables from the goal with each copy of the
> template and restores these. That has its own problems.
>
> Cheers --- Jan
>
>> Example:
>>
>> | ?-L0 =[X,y(Y),z],findall(E,member(E,L0),L). L0 =[X,y(Y),z], L
>> =[_G2443,y(_G2438),z]. |
>>
>> If so, is there any other built-in I could use, or is coding a
>> custom predicate the only way to keep bindings?
>
>
>