Subject: Re: setof

From: "Richard A. O'Keefe" <[email-masked]>
Date: Thu, 23 Mar 2000 16:33:11 +1200 (NZST)

Waseem Besada <[email-masked]> 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)).