1/*****************************************************************************
    2 * This file is part of the Prolog Development Tool (PDT)
    3 * 
    4 * Author: G�nter Kniesel (among others)
    5 * WWW: http://sewiki.iai.uni-bonn.de/research/pdt/start
    6 * Mail: pdt@lists.iai.uni-bonn.de
    7 * Copyright (C): 2004-2012, CS Dept. III, University of Bonn
    8 * 
    9 * All rights reserved. This program is  made available under the terms
   10 * of the Eclipse Public License v1.0 which accompanies this distribution,
   11 * and is available at http://www.eclipse.org/legal/epl-v10.html
   12 * 
   13 ****************************************************************************/
   14
   15% Different implementations of predicates that call another predicate 
   16% a fixed number of times.
   17	
   18
   19% ?-time(run_n_times(true,1000000)).
   20% 3,000,008 inferences, 0.296 CPU in 0.297 seconds (100% CPU, 10121420 Lips)
   21
   22:- meta_predicate call_n_times(0, -).   23
   24call_n_times(Goal, N) :-
   25	repeatN(N),
   26	  Goal,
   27	fail.
   28call_n_times(_Goal, _N).
   29    
   30repeatN(_).
   31repeatN(N) :-
   32	N > 1,
   33	N2 is N - 1,
   34	repeatN(N2).    
   35
   36% The following flag-basede version is slower than the one with repeatN (above):
   37% ?- time(call_n_times_slow(true,1000000)).
   38% 3,000,010 inferences, 0.515 CPU in 0.513 seconds (100% CPU, 5827488 Lips)
   39
   40:- meta_predicate call_n_times_slow(0, -). 
   41
   42call_n_times_slow(Goal,N) :-
   43    flag( xxx_run_n_times, _,1),   % Counter = 1
   44    repeat,
   45       flag( xxx_run_n_times, Calls,Calls+1),
   46       call(Goal),
   47    Calls >= N,
   48    !.
   49
   50
   51:- meta_predicate succeeds_n_times(0, -).           
   52                                           
   53succeeds_n_times(Goal, Times) :-          
   54   Counter = counter(0),             
   55   (   Goal,                         
   56          arg(1, Counter, N0),          
   57          N is N0 + 1,                  
   58          nb_setarg(1, Counter, N),
   59       fail                          
   60   ;   arg(1, Counter, Times)        
   61   )