Re: seeking findall that preserves variables.

Jan Wielemaker <[email protected]> Thu, 24 Apr 2014 17:03:57 +0200
Newsgroups gmane.comp.ai.prolog.swi
Message-ID <[email protected]>
On 04/24/2014 04:48 PM, Alan Baljeu wrote:
> Can you explain why bagof appears to work better than this?  I
> understand there are limitations there as well.

What do you mean with `better'?  They do different things.  bagof/3
has the existential variable stuff and its results are basically
copies of the instantiated template where the original variables
are unified with their copies.  In the nice and clean Prolog world,
this has no semantic consequences and only costs space.  In the ugly
world of attributed variables (which are basically mutable terms),
this may have consequences, depending on what assumptions are made
about the behavior of the attributes by the constraint handling
code.  Even if there are no semantic consequences, the space
consequences can be prohibitive as there can be a quite complex
network hidden inside the attribute values.

find_parts does not copy the template, which also means that the
results are subject to the backtracking behavior in the failure
driven loop.

	Cheers --- Jan

> Alan Baljeu
> ------------------------------------------------------------------------
> *From:* Jan Wielemaker <[email protected]>
> *To:* Alan Baljeu <[email protected]>; Prolog
> <[email protected]>
> *Sent:* Thursday, April 24, 2014 4:48:31 AM
> *Subject:* Re: [SWIPL] seeking findall that preserves variables.
>
> On 04/23/2014 10:07 PM, Alan Baljeu wrote:
>  > I have a notion that there's something out there that uses attributed
> variables�
>  > or something so that I can collect the solutions of a predicate without�
>  > destroying the variables in that solution. �
>  > �
>  > E.g. �nice_findall(X, member(X-1, [A-1, B-2, C-1], Xs), Xs == [A, C].
>
> More or less.  You can hack a little with predicates that have lots
> of warnings in their documentation, and come with this:
>
> :- meta_predicate
>      find_parts(?, 0, -).
>
> find_parts(T, G, L) :-
>      L0 = [dummy|_],
>      Result = list(L0),
>      (  call(G),
>          NewLastCell = [T|_],
>          arg(1, Result, LastCell),
>          nb_linkarg(2, LastCell, NewLastCell),
>          nb_linkarg(1, Result, NewLastCell),
>          fail
>      ;  arg(1, Result, [_]),
>          L0 = [_|L]
>      ).
>
> Now, the above doesn't get the right results, bet gets this:
>
> 1 ?- find_parts(X, member(X-1, [A-1, B-2, C-1]), Xs).
> Xs = [X, X].
>
> If however the result is not a plain variable, we get this:
>
> 2 ?- find_parts(X, member(X-1, [a(A)-1, b(B)-2, b(B)-1]), Xs).
> Xs = [a(A), b(B)].
>
> Here, the a(A) from the result is really the same not copied term a(A)
> from the input list.  `Fixing' (1) is probably possible using some more
> careful hacking, although my first few attempts were wrong.
>
> But, the only thing you can do with this primitive is to select parts
> from compound terms. It only works if the template is a plain variable
> and any attempt to create new terms or further instantiate terms in the
> generator is pointless because the backtracking will destroy these
> instantiations. If you want some computation on the found terms, you
> need a maplist *after* find_parts/3.
>
> I wonder whether it is possible to give this beast a sensible
> description and whether or not it solves practical problems.
>
>
>  > Does it exist/can it be easily done? �(The actual source is not a list,�
>  > so filter predicates aren't the answer.)
>
>
> The alternative to the above is of course to define a filter predicate
> to whatever your data structure is.
>
>      Cheers --- Jan
>
> _______________________________________________
> SWI-Prolog mailing list
> [email protected] <mailto:[email protected]>
> https://lists.iai.uni-bonn.de/mailman/listinfo.cgi/swi-prolog
>
>
>

_______________________________________________
SWI-Prolog mailing list
[email protected]
https://lists.iai.uni-bonn.de/mailman/listinfo.cgi/swi-prolog