[ Non-logical Variables, Arrays, Bags, Shelves and Stores | Reference Manual | Alphabetic Index ]

local reference(+Name, ++Init)

Creates a named reference called Name with intial value Init.
Name
An atom.
Init
A ground term

Description

This creates a named reference with the atomic name Name and initial value Init. Usually, this would be done in a directive.

A named reference can be used to hold a reference to a term in the same way as a logical variable. Unlike a non-logical variable, the value of a reference is not a copy, but identical to the original term it was set to. This implies that the value behaves logically, i.e. it disappears on backtracking, bindings to the variables inside it are undone on backtracking etc. A typical example of its use is global state that a set of predicates wants to share without having to pass an argument pair through all the predicate invocations.

Changing the value of a reference is similar to changing an argument of a compound term using setarg/3.

The initial value of the reference is Init, which must be a ground term.

There are no arrays of references, but the same effect can be achieved by storing a structure in a reference and using the structure's arguments. The arguments can then be accessed and modified using arg/3 and setarg/3 respectively.

Reference names are visible in the module where they are declared. Furthermore every ECLiPSe engine has its own reference store, meaning that the values are engine/thread-local and cannot be shared.

Side note: When a reference is re-declared with a different Init value during execution, the effect only becomes visible once execution fails back to the reference's initial state. A current value that is the result of a setref/2 is not affected.

Modes and Determinism

Exceptions

(4) instantiation fault
Name is not instantiated.
(4) instantiation fault
Init is not a ground term.
(5) type error
Name is not an atom.

Examples

% declaring a reference

      :- local reference(a,0).
      yes.

% values of references are subject to backtracking:

      ?- ( getref(a, Old), setref(a, 27), getref(a, New)
	 ; getref(a, Then)
	 ).
      Old = 0
      New = 27
      Then = Then
      Yes (0.00s cpu, solution 1, maybe more) ? ;

      Old = Old
      New = New
      Then = 0
      Yes (0.00s cpu, solution 2)


% comparison between references and nonlogical variables.

      :- local reference(r), variable(v).
      yes.

% references are subject to backtracking, nonlogical variables survive:

      ?- ( setref(r, 27), fail
         ; getref(r, New)
	 ).
      New = 0
      Yes (0.00s cpu)

      ?- ( setval(v, 27), fail
         ; getval(v, New)
	 ).
      New = 27
      Yes (0.00s cpu)

% references refer to the original term, nonlogical variables to copies:

      ?- Term = p(X), setref(r, Term), getref(r, Y), Y == Term.
      X = X
      Y = p(X)
      Term = p(X)
      yes.

      ?- Term = p(X), setval(v, Term), getval(v, Y), Y == Term.
      no (more) solution.

See Also

setref / 2, getref / 2, setarg / 3, arg / 3