I have predicate P1 that returns values one after the other like this:
-? P1(ARGUMENTS, RETURN).
-? RETURN = 1;
-? RETURN = 2;
-? RETURN = 3;
-? fail.
I also have another predicate called P2:
P2(ARGUMENTS, LIST) :- P1(ARGUMENTS, RETURN),... % SOMEHOW HERE I NEED TO INSERT ALL VALUES OF RETURN TO LIST.
How do find all of the values of RETURN
and assign them to LIST
?
An all-solutions predicate like findall/3 might do the trick: list_parents(P, L) :- findall(Parent, parent(Parent, P), L). Simply put, findall/3 finds all bindings for Parent in the 'backtrack-able' goal parent(Parent, P) , and puts all bindings of Parent into the list L .
Prolog findall is a predicate function of the programming language to work with list, goal, and template. It is a metapredicate that works with a list of the templates and achieves the required goal. It is a built-in function to collect a list of the items using a template and bind the list to get a required goal.
setof. The built-in Prolog predicate setof(+Template, +Goal, -Set) binds Set to the list of all instances of Template satisfying the goal Goal .
Use findall
to accomplish this:
P2(ARGUMENTS, LIST) :- findall(X, P1(ARGUMENTS, X), LIST).
This is related to the bagof
function mentioned in the question linked to by Anders Lindahl. There is a good explanation on the relationship between the two functions (and a third function setof
) here:
To illustrate the differences consider a little example:
listing(p). p(1,3,5). p(2,4,1). p(3,5,2). p(4,3,1). p(5,2,4).
Try the following goals. (The answer displays have been modified to save space.)
?- bagof(Z,p(X,Y,Z),Bag). Z = _G182 X = 1 Y = 3 Bag = [5] ; Z = _G182 X = 2 Y = 4 Bag = [1] ; Z = _G182 X = 3 Y = 5 Bag = [2] ; Z = _G182 X = 4 Y = 3 Bag = [1] ; Z = _G182 X = 5 Y = 2 Bag = [4] ; No ?- findall(Z,p(X,Y,Z),Bag). Z = _G182 X = _G180 Y = _G181 Bag = [5, 1, 2, 1, 4] ; No ?- bagof(Z,X^Y^p(X,Y,Z),Bag). Z = _G182 X = _G180 Y = _G181 Bag = [5, 1, 2, 1, 4] ; No ?- setof(Z,X^Y^p(X,Y,Z),Bag). Z = _G182 X = _G180 Y = _G181 Bag = [1, 2, 4, 5] ; No
The predicates
bagof
andsetof
yield collections for individual bindings of the free variables in the goal.setof
yields a sorted version of the collection without duplicates. To avoid binding variables, use an existential quantifier expression. For example the goalbagof(Z,X^Y^p(X,Y,Z),Bag)
asks for "the Bag ofZ
's such that there exists anX
and there exists aY
such thatp(X,Y,Z)
".findall
acts likebagof
with all free variables automatically existentially quantified. In additionfindall
returns an empty list[]
there is no goal satisfaction, whereasbagof
fails.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With