Newsgroups: comp.lang.prolog
Path: cantaloupe.srv.cs.cmu.edu!rochester!udel!gatech!howland.reston.ans.net!ix.netcom.com!netcom.com!ludemann
From: ludemann@netcom.com (Peter Ludemann)
Subject: Re: problems with bagof
Message-ID: <ludemannDBIvv5.KCG@netcom.com>
Organization: NETCOM On-line Communication Services (408 261-4700 guest)
References: <3tbv33$7ps@due.unit.no> <3tpqts$t1b@goanna.cs.rmit.edu.au>
Date: Mon, 10 Jul 1995 22:59:29 GMT
Lines: 47
Sender: ludemann@netcom9.netcom.com

In article <3tpqts$t1b@goanna.cs.rmit.edu.au>,
Richard A. O'Keefe <ok@goanna.cs.rmit.edu.au> wrote:
>Passani Luca <passani@idt.unit.no> writes:
>> I thought the semantics of bagof was clear to me by now, but:
>>make_list_of_products(List) :-
>> bagof(Product, Name^(product(Product, Name, _)), List).
>>doesn't work.
>
>Here's a tip:   ***NEVER*** put an anonymous variable in the
>generator argument of bagof/3 or setof/3.

I've made this same mistake enough times to have developed my
own techniques (which might help you):
1. avoid using existential quantifiers with bagof/setof.
2. never put compound goals in bagof/setof.
3. use setof unless there's a good reason not to.

So, using rule 1, I would write your query as:

make_list_of_products(List) :-
	bagof(Product, is_product(Product), List).
is_product(Product) :- product(Product, _, _).

This technique works nicely, runs fast, and spares my supplies of
Aspirin.

The reason for rule 2 is that many Prologs create awful code for
something like:
	fs_and_gs(L) :- bagof(X, (f(X),g(X)), L).
... much better code is generated if you do:
	fs_and_gs(L) :- bagof(X, f_and_g(X), L).
	f_and_g(X) :- f(X), g(X).

Besides, the compound goals can be hard to read, with the extra
parentheses.

[The bad implementations evaluate (f(X),g(X)) as call(f(X),g(X)),
invoking the interpreter, typically 10-times or more slower than using
compiled code.]

The reason for rule 3 is that setof eliminates duplicates; the
resulting list doesn't depend on the ordering of the clauses used to
compute it.  This forces me to be a bit more "logical" in my programming.


-- 
Peter Ludemann                      ludemann@netcom.com
