ramesh@edcaad.UUCP (Ramesh Krishnamurti) (08/20/86)
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
cdsm@doc.ic.ac.uk (Chris Moss) (08/22/86)
>>Date: Wed 6 Aug 86 14:38:43-CDT >>From: Dave Plummer <ATP.PLUMMER@R20.UTEXAS.EDU> >>Subject: DEC-10 Bagof - Bug? >> >>Given the program: >> >>p(1,_). p(2,_). p(3,3). p(4,4). >> >>and the goal bagof(X, p(X,Y), S). Edinburgh DEC-10 Prolog >>returns, >> >>S = [1,2,3] X = _ Y = 3 >>S = [4] X = _ Y = 4 >> >>This behaviour doesn't agree with my reading of the >>documentation Poplog produces the solutions: S=[4] X =_1 Y=4 S=[3] X =_1 Y=3 S=[1,2] X=_1 Y=_2 which is _slightly_ more consistent. The problem has been dealt with in: Lee Naish: All solutions predicates in Prolog. Tech Report 84/4, Dept of Comp. Sc., Univ of Melbourne. (it's been published I think, but I forget where) He has a 'hard-line' solution which involves coroutining and never returning variables if they can be subsequently bound. Chris Moss. cdsm@doc.ic.ac.uk cdsm@icdoc.uucp