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.