From ok@atlas.otago.ac.nz  Thu Mar 23 05:33:07 2000
Received: from atlas.otago.ac.nz (atlas.otago.ac.nz [139.80.32.250])
	by swi.psy.uva.nl (8.9.3/8.9.3) with ESMTP id FAA25462
	for <prolog@swi.psy.uva.nl>; Thu, 23 Mar 2000 05:33:05 +0100 (MET)
Received: (from ok@localhost)
	by atlas.otago.ac.nz (8.9.3/8.9.3) id QAA06324;
	Thu, 23 Mar 2000 16:33:11 +1200 (NZST)
Date: Thu, 23 Mar 2000 16:33:11 +1200 (NZST)
From: "Richard A. O'Keefe" <ok@atlas.otago.ac.nz>
Message-Id: <200003230433.QAA06324@atlas.otago.ac.nz>
To: prolog@swi.psy.uva.nl, waseem@isk.kth.se
Subject: Re:  setof

Waseem Besada <waseem@isk.kth.se> asked
	Why doesn't ?-setof(X, course(_,_,X), L).
	give a sorted list L of teachx from the following facts.
	
	course(java,time(monday,10,12),name(teach1)).
	course(prog, time(friday,13,15), name(teach2)).
	course(math, time(thrusday,8,10), name(teach3)).
	course(c,time(wednesday,13,15), name(teach2)).
	course(prolog, time(friday,10,12), name(teach4)).
	
The key trap here is that the anonymous variables don't do what you
_think_ they do here.  It's a common trap, for some reason, but Prolog
is being rigorously consistent here.  A rule of thumb to keep you
out of trouble:
    *NEVER* have an anonymous variable in the generator of an
    all-solutions goal.

Here's another one:
    if an all-solutions goal is giving you trouble, define a new
    predicate with exactly the arguments you want and call that
    instead.
Here we might do

    teacher(TName) :-
        course(_Topic, _Time, TName).

    ?- setof(X, teacher(X), Xs).

But that *still* wouldn't work, because the desired result was a set of
'teachx' terms.  This will give you [name(teach1),name(teach2),...].

There are two ways to fix that.  First, there appears to be no good reason
for having the name/1 wrappers around the teacher names in the first place.
Correct the course/3 facts to

	course(java,   time(monday,   10,12), teach1).
	course(prog,   time(friday,   13,15), teach2).
	course(math,   time(thursday,  8,10), teach3).  % fixed thursday
	course(c,      time(wednesday,13,15), teach2).
	course(prolog, time(friday,   10,12), teach4).

(it's a table, so lay it out like a table).  The other approach leaves
the table alone (although 'thrusday' will need fixing anyway) and
patches the table bug in the new wrapper:

    teacher(TName) :-
	course(_Topic, _Time, name(TName)).

