Bagof gives only one item, although several items are suitable

This code works as expected:

 ?- bagof(R,member(r(R),[r(a),r(b),r(c),r(d)]),Rs).
Rs = [a, b, c, d].

but the similar call that I really want does not:

?- bagof(R,member(r(_,R),[r(_,a), r(_,b), r(_,c), r(_,d)]),Rs).
Rs = [a] 

;gives me more answers, but I want to [a,b,c,d]. What is my fix?

+4
source share
3 answers

You need to existentially qualify arguments that you are not interested in, instead of using anonymous variables:

?- bagof(R,A^A1^A2^A3^A4^member(r(A,R),[r(A1,a), r(A2,b), r(A3,c), r(A4,d)]),Rs).
Rs = [a, b, c, d].

This is necessary because bagof/3(and setof/3) will return a package (set) of solutions for each instance of free variables (i.e. variables in the target that are not in the template). Alternatively, you can use a predicate findall/3(which ignores free variables):

?- findall(R,member(r(A,R),[r(A1,a), r(A2,b), r(A3,c), r(A4,d)]),Rs).
Rs = [a, b, c, d].

, findall/3 , , bagof/3 ( setof/3) , .

, bagof/3 setof/3, , . :

r(R) :-
    member(r(_,R),[r(_,a), r(_,b), r(_,c), r(_,d)]).

?- bagof(R, r(R), Rs).
Rs = [a, b, c, d].
+2

bagof/3 _ . setof/3.

, , , , library(lambda):

?- bagof(R,R+\member(r(_,R),[r(_,a), r(_,b), r(_,c), r(_,d)]),Rs).
Rs = [a,b,c,d].
+3

(yall), SWI-Prolog. Yall ( ) :

?- bagof(R, {R}/member(r(_,R),[r(_,a), r(_,b), r(_,c), r(_,d)]),Rs).
Rs = [a, b, c, d].
+1

Source: https://habr.com/ru/post/1648143/


All Articles