From ok@atlas.otago.ac.nz  Mon Nov 27 22:45:54 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 WAA27525
	for <prolog@swi.psy.uva.nl>; Mon, 27 Nov 2000 22:45:52 +0100 (MET)
Received: (from ok@localhost)
	by atlas.otago.ac.nz (8.9.3/8.9.3) id KAA21733;
	Tue, 28 Nov 2000 10:45:43 +1300 (NZDT)
Date: Tue, 28 Nov 2000 10:45:43 +1300 (NZDT)
From: "Richard A. O'Keefe" <ok@atlas.otago.ac.nz>
Message-Id: <200011272145.KAA21733@atlas.otago.ac.nz>
To: dima@solvo.ru, prolog@swi.psy.uva.nl
Subject: Re:  please, answer on my FAQ (fwd)

What is the *point* of the n_times/2 predicate?

	%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
	% times counters
	%--------------------------------------------------------------------------
	% count +Goal success in ?Times or try +Goal +Times
	n_times(Goal, Times) :-
		gensym(n_times,Name),
		flag(Name, _N, 0),!,
		repeat,
		( Goal,
			flag(Name, N, N+1),
			fail
		; flag(Name, Times, _N)
		).

I can't figure out what it is supposed to do, and using "_N" twice doesn't
help (you are supposed to put "_" in front of variables that you only mean
to mention once).

If you want to execute a command N times, ignoring whether it succeeds
or fails, just do

    do_exactly_n_times(N, Goal) :-
	( between(1, N, _), call(Goal), fail ; true ).

If you want to repeatedly execute a command until it fails, and return
the number of times it succeeded, do

    count_successes(Goal, S) :-
	count_successes(Goal, 0, S).

    count_successes(G, S0, S) :-
        (   \+(G) -> S = S0
	;   S1 is S0 + 1,            
	    count_successes(G, S1, S)
	).

If you want to execute a command exactly N times, and return the
number of times it succeeded, do

    do_n_times_counting_successes(N, Goal, S) :-
	N >= 0,
        do_n_times_counting_successes(N, Goal, S0, S).

    do_n_times_counting_successes(N0, Goal, S0, S) :-
        (   N =:= 0 -> S = S0
        ;   \+(G) ->
	    N1 is N0 - 1,
	    do_n_times_counting_successes(N1, Goal, S0, S)
	;/* G succeeded */
	    N1 is N0 - 1,
	    S1 is S0 + 1,
	    do_n_times_counting_successes(N1, Goal, S1, S)
	).

Why program with clumsy side effects when you can say what you mean
faster and better without them?

If the documentation of flag/3 has the effect of discouraging people
from using it, then WONDERFUL, say I.  Perhaps people will learn how
to write Prolog instead.

