One of the tenets of logic programming is that terms are immutable objects of the Herbrand universe, and the only sense in which they can be modified is by means of instantiating non-ground parts. There are, however, algorithms where destructive assignment is essential for performance. Although alien to the ideals of logic programming, this feature can be defended on practical grounds.
SICStus Prolog provides an abstract datatype and three operations for efficient backtrackable destructive assignment. In other words, any destructive assignments are transparently undone on backtracking. Modifications that are intended to survive backtracking must be done by asserting or retracting dynamic program clauses instead. Unlike previous releases of SICStus Prolog, destructive assignment of arbitrary terms is not allowed.
A mutable term is represented as a compound terms with a reserved
functor: '$mutable'(
Value,
Timestamp)
where Value
is the current value and Timestamp is reserved for bookkeeping
purposes [Aggoun & Beldiceanu 90].
Any copy of a mutable term created by copy_term/2
, assert
,
retract
, an internal database predicate, or an all solutions
predicate, is an independent copy of the original mutable term. Any
destructive assignment done to one of the copies will not affect the
other copy.
The following operations are provided:
create_mutable(
+Datum,
-Mutable)
Mutable is a new mutable term with initial value Datum.
Datum must not be an unbound variable.
get_mutable(
?Datum,
+Mutable)
Datum is the current value of the mutable term Mutable.
update_mutable(
+Datum,
+Mutable)
Updates the current value of the mutable term Mutable to become
Datum. Datum must not be an unbound variable.
is_mutable(
?Mutable)
Checks that Mutable is currently instantiated to a mutable term.
NOTE: the effect of unifying two mutables is undefined.