Re: seeking findall that preserves variables.

Jan Wielemaker <[email protected]> Thu, 24 Apr 2014 10:48:31 +0200
Newsgroups gmane.comp.ai.prolog.swi
Message-ID <[email protected]>
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]
https://lists.iai.uni-bonn.de/mailman/listinfo.cgi/swi-prolog