library(ctr)

library(ctr) provides an array of 32 global integer variables. It was written some time ago for compatibility with another dialect of Prolog. The operations provided on these variables are


ctr_set(+Ctr, +N)
ctr[Ctr] := N
ctr_set(+Ctr, +N, ?Old)
Old is ctr[Ctr], ctr[Ctr] := N
ctr_inc(+Ctr)
ctr[Ctr] := ctr[Ctr] + 1
ctr_inc(+Ctr, +N)
ctr[Ctr] := ctr[Ctr] + N
ctr_inc(+Ctr, +N, ?Old)
Old is ctr[Ctr], ctr[Ctr] := ctr[Ctr] + N
ctr_dec(+Ctr)
ctr[Ctr] := ctr[Ctr] - 1
ctr_dec(+Ctr, +N)
ctr[Ctr] := ctr[Ctr] - N
ctr_dec(+Ctr, +N, ?Old)
Old is ctr[Ctr], ctr[Ctr] := ctr[Ctr] - N
ctr_is(+Ctr, ?Old)
Old is ctr[Ctr]

If you want to use these counters in a nestable construct, remember to reset them properly; for example,

     count_solutions(Goal, Count) :-
             ctr_set(17, 0, Old),
             (call(Goal), ctr_inc(17), fail ; true),
             ctr_set(17, Old, X),
             Count = X.
     

This will work even if Goal contains a call to count_solutions/2, because the old counter value is saved on entry to the clause, and restored on exit. Contrast this with the following example:

     count_solutions(Goal, Count) :-
             ctr_set(17, 0),
             (call(Goal), ctr_inc(17), fail ; true),
             ctr_set(17, X),
             Count = X.
     

In this example, if Goal contains a call to count_solutions/2, the inner call will clobber the counter of the outer call, and the predicate will not work.

This file is provided mainly to allow you to experience (by doing your own timing tests) that the foreign interface, not the database, is the tool for hacking global variables in Prolog, provided that the global variables take only constants as values.