问题
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
?
回答1:
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.
来源:https://stackoverflow.com/questions/1468150/how-do-i-find-all-solutions-to-a-goal-in-prolog