Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Path: utzoo!mnetor!seismo!mcvax!ukc!cstvax!edcaad!ramesh From: ramesh@edcaad.UUCP (Ramesh Krishnamurti) Newsgroups: net.lang.prolog Subject: Re: Dave Plummer's bagof query Message-ID: <700@edcaad.UUCP> Date: Wed, 20-Aug-86 10:10:37 EDT Article-I.D.: edcaad.700 Posted: Wed Aug 20 10:10:37 1986 Date-Received: Thu, 21-Aug-86 21:24:46 EDT References: PROLOG DIGEST V4 #34 Reply-To: ramesh@edcaad.UUCP (Ramesh Krishnamurti) Organization: Architecture, Edinburgh U., Scotland Lines: 82 In reponse to Dave Plummer's query, the way bag_of(X,P,B) works in C-Prolog and hence (?) ought to in DEC-10 Prolog is to find to all instances of X such that P is provable with the condition that any variables in P not X are bound. Thus for the program, p(1,2). p(1,1). p(2,_). p(3,_). p(4,4). bagof(X,p(X,Y),B) will, on backtracking, successively generate the lists [3,2,1] with Y bound to 2 [1] with Y bound to 1 [4] with Y bound to 4 Ideally, it should produce the lists [3,2,1] with Y bound to 2 [3,2,1] with Y bound to 1 [4,3,2] with Y bound to 4 But thats asking too much of Prolog ! If you want the variables in P not in X to remain free then they must be explicitly bound by an existential quantifier ^. That is, bagof(X,Y^p(X,Y),B) will generate the list [4,3,2,1,1] with Y bound to _ If you dont want to be bothered with specifying the free variables the following version of bagof works. %---------------------------------------------------------------- bag(_,_,_):- asserta($bag(base,_)), fail. bag(X,P,B):- Pred, asserta($bag(item,X)), fail. bag(_,_,B):- $gather([],B). $gather(C,B):- retract($bag(Tag,X)), !, $gather(Tag,X,C,B). $gather(base,_,B,B):- !. $gather(item,X,C,B):- !, $gather([X|C],B). %---------------------------------------------------------------- However, for the database: drinks(tom,lager). drinks(dick,bitter). drinks(harry,bitter). drinks(bill,lager). drinks(jack,lager). drinks(bill,bitter). bag(X,drinks(X,Y),B) will produce B = [tom,dick,harry,bill,jack,bill] with Y bound to _ whereas bagof(X,drinks(X,Y),B) will successively produce B = [jack,bill,tom] with Y = lager B = [bill,harry,dick] with Y = bitter Take your pick. -- Ramesh