With the repair library each variable can be given a tentative value. This is different from instantiating the variable.
Rather the tentative value is a piece of updatable information
associated with the variable.
The tentative value can be changed repeatedly during search, not just
on backtracking.
The value is set using the syntax tent_set
, and retrieved using
tent_get
.
For example the following query writes first 1 and then 2:
?- X tent_set 1, X tent_get Tent1, writeln(Tent1), X tent_set 2, X tent_get Tent2, writeln(Tent2).
Throughout this query X remains a variable.
A tentative variable may violate constraints.
The following query writes succeed
, because
setting the tentative value to 1 does not cause a failure:
?- X $> 2, X tent_set 1, writeln(succeed).
The relation between constraints and tentative values can be maintained in two ways. The first method is by monitoring a constraint for conflicts.
?- X $> 2 r_conflict myset, X tent_set 1, writeln(succeed).
This query also succeeds - but additionally it creates a conflict
set named
myset
. Because X $> 2 is violated by the tentative value of
X, the constraint is recorded in the conflict set. The conflict set
written out by the following query is [X{1} $> 2]
:
?- X $> 2 r_conflict myset, X tent_set 1, conflict_constraints(myset,Conflicts), writeln(Conflicts).
The conflict can be repaired by changing the tentative value of the variable which causes it:
?- X $> 2 r_conflict myset, X tent_set 1, conflict_constraints(myset,Conflicts), X tent_set 3, conflict_constraints(myset,NoConflicts). |
This program instantiates Conflicts
to [X{1} $> 2]
,
but NoConflicts
is instantiated to []
.
Arithmetic equality (=:=
, $=
) constraints, instead of
monitoring for conflicts,
can be maintained by propagating tentative values.
To do so, they must be rewritten in a functional syntax.
Consider the constraint X =:= Y+1
.
For propagation of tentative values, this must
be rewritten in the form X tent_is Y+1
.
If the tentative value of Y is set to 1, then this will be
propagated to the tentative value
of X. The following query writes out the value 2.
?- X tent_is Y+1, Y tent_set 1, X tent_get(TentX), writeln(TentX).
Each time the tentative value of Y is changed, the value of X is kept in step, so the following writes out the value 3:
?- X tent_is Y+1, Y tent_set 1, Y tent_set 2, X tent_get(TentX), writeln(TentX).
Repair supports the following primitives: (and some others that are not covered in this tutorial).
- tent_set/2
- tent_get/2
- r_conflict/2
- conflict_constraints/2
- tent_is/2