[comp.lang.prolog] setof/bagof

sn@otter.hple.hp.com (Srinivas Nedunuri) (04/08/88)

/ otter:comp.lang.prolog / george@utah-cs.UUCP (Lal George) / 10:22 pm  Apr  7, 1988 /

>	Here is  what seems to be an anomalous behaviour related
>to the bagof predicate. This test case was run under quintus prolog.

>	The database used is:
>supplier(foo, wine, 12.00).
>supplier(foo, champagne, 13.00).
>supplier(foo, vodka, 13.00).

>Sample session:

>| ?- bagof(Drink, supplier(foo, Drink, _), Ans).

>Drink = _395,
>Ans = [wine] 		

>| ?- 
>| ?- bagof([Drink,Price], supplier(foo, Drink, Price), Ans).

>Drink = _399,
>Price = _416,
>Ans = [[wine,12.0],[champagne,13.0],[vodka,13.0]] 

>	The first query returned only one answer, whereas there are
>3 solutions to the predicate 'supplier(foo, Drink, _)'. The second 
>query did find all of them however. Does anyone know what is going
>on?

------------------------------------------------------------------------
	As far as I can tell it seems that the only anomolous behaviour was that your
Prolog interpreter did not offer you "more(y/n)?" in the first case which would have givother
you the other solution

Drink = _nnn
Ans = [champagne,vodka]

	My understanding of Prolog is that free variables in a *query* are existentially
quantified (becoming universally quantified when the query is negated and added to the db
in the resolution proof procedure). When the Prolog interpreter backtracks for alternative
solutions it looks for alternative instantiations for these exist. quant. varaiables. Based 
this and an empirical(!) observation of setof I would say that the query 
	setof(X, P(X,Y), S)
is equivalent to
	S = {X : existsY, forallX  P(X,Y)}
In your second example the Price variable is effectively universally quantified
also which gives the set of all solutions.
(setof gives identical results to bagof in your case as you have no multiset solns)
Correspondingly, using the so-called `existential quantification' just switches the prenex
	setof(X, Y^P(X,Y), S)
is equivalent to
	S = {X : forallX, existsY P(X,Y)}
giving all the X's for each of which there exists *some* Y

The following gives you the required solution:

?- bagof(D, P^supplier(foo,D,P), A).

D = _nnn
P = _nnn
A = [wine,champagne,vodka]