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
, a 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.
Please note: the effect of unifying two mutables is undefined.