From ok@atlas.otago.ac.nz Tue Mar 27 04:10:06 2001
Received: from atlas.otago.ac.nz (atlas.otago.ac.nz [139.80.32.250])
	by swi.psy.uva.nl (8.11.2/8.11.2) with ESMTP id f2R2A4325777
	for <prolog@swi.psy.uva.nl>; Tue, 27 Mar 2001 04:10:05 +0200 (MET DST)
Received: (from ok@localhost)
	by atlas.otago.ac.nz (8.9.3/8.9.3) id OAA07630;
	Tue, 27 Mar 2001 14:09:58 +1200 (NZST)
Date: Tue, 27 Mar 2001 14:09:58 +1200 (NZST)
From: "Richard A. O'Keefe" <ok@atlas.otago.ac.nz>
Message-Id: <200103270209.OAA07630@atlas.otago.ac.nz>
To: prolog@swi.psy.uva.nl, saibaryo@excite.com
Subject: Re:  [SWIPL] I need help about my code

Ryo Saeba <saibaryo@excite.com> has some facts for
    course_name(CourseCode, NameAsAtom)
    person_course(PersonID, Year, Semester, CourseCode)
and wants a predicate
    p(PersonID)
that lists all the courses that person has taken.

	p(N) :- repeat, query.., print.., fail.

keeps on repeating the same output over and over.
But that's precisely what repeat/0 is SUPPOSED to do.

	p(N) :- query.., print.. .

writes just the first course, again doing EXACTLY what it should.

However,

    p(N) :-
	person_course(N, _, _, C),
	course_name(C, CT),
	write(C), write(' '), write(CT), nl,
	fail ; true.

uses a "failure-driven loop" to backtrack over all ways of satisfying
the query, printing each.

Better style would be to package this up like so:
	
    % forall(+Generator: void, +Test: void)
    % succeeds when there is no proof of Generator for which
    % the corresponding instance of Test fails.
    % Unbound variables are (again) unbound on exit.

    forall(Generator, Test) :-
        call(( Generator, ( Test -> fail ; true ) -> fail ; true )).

    print_course(C) :-
	course_name(C, CT),
	write(C), write(' '), write(CT), nl.
	
    p(N) :-
	forall(person_course(N, _, _, C), print_course(C)).

