
:-dynamic p/1.

/* bagof1(O,P,L) construit la liste L des objets O verifiant la 
   propriete P. O est un terme qui contient des variables liees
   a celles de P */
mybagof(O,P,L):-
	assert(mylist(L-L)),
	mybagof0(O,P,L).

mybagof0(O,P,L):-
	P,
	add_mylist(O),
	fail.

mybagof0(_,_,L) :- !,
	retract(mylist(L-[])).

add_mylist(O) :- 
	retract(mylist(L-S)),
	S=[O|S1], 
	assert(mylist(L-S1)).
	

mysetof(O,P,L) :-
	mybagof(O,P,L1),
	sort(L1,L).


/* tests */

p(b).
p(a).
p(c).
p(a).
p(d).

a([b,[c,d1],e]).
a([b1,[c,d2],e]).
a([b2,[c,d2],e]).
a([b,[c,d4],e]).

t1(L):-
	mybagof(O,p(O),L).
t2(L):- assert(p(f)),
	mybagof(O,p(O),L).
t3(L):-
	mybagof(O,a([_,[_,O],_]),L).

t4(L):-
	mysetof(O,p(O),L).
t5(L):-
	mysetof(O,a([_,[_,O],_]),L).

/*
reconsult('set_and_bag').

File set_and_bag consulted

true
| ?- mybagof(O,p(O),L).


L = [b,a,c,a,d]

true
| ?- mybagof(O,a([_,[_,O],_]),L).


L = [d1,d2,d2,d4]

true
| ?- mysetof(O,p(O),L).


L = [a,b,c,d]

true
*/







