The value of a non-logical variable is set using the setval/2 predicate. This has the format
setval(Name, Value)For instance, the goal
setval(firm, 3)gives the non-logical variable firm the value 3. The value of a non-logical variable is retrieved using the getval/2 predicate. The goal
getval(firm, X)will unify X to the value of the non-logical variable firm, which has been previously set by setval/2. If no value has been previously set, the call raises an exception. If the value of a non-logical variable is an integer, the predicates incval/1 and decval/1 may be used to increment and decrement the value of the variable, respectively. The predicates incval/1 and decval/1 may be used e.g. in a failure-driven loop to provide an incremental count across failures as in the example:
count_solutions(Goal, _) :-
setval(count, 0),
call(Goal),
incval(count),
fail.
count_solutions(_, N) :-
getval(count, N).
However, code like this should be used carefully.
Apart from being a non-logical feature, it also causes the code to be
not reentrant. I.e. if count_solutions/2 would be called recursively from
inside Goal, this would smash the counter and yield incorrect
results9.2.
The visibility of a non-logical variable is local to the module where it is first set. It is good style to declare them using local/1 variable/1 declarations. E.g. in the above example one should use
:- local variable(count).If it is necessary to access the value of a variable in other modules, exported access predicates should be provided.