Next: Memory Organisation And Garbage
Up: More About Suspension
Previous: Waiting for Binding
  Index
Waiting for other Constraints
The constrained list in the suspend attribute
is used for instance in generic predicates which have to be
notified about the possible change of the state of a variable,
especially its unifyability with other terms.
Our example with the dif predicate could be for instance
extended to work with finite domain or other constrained
variables.
The modification is fairly simple:
- When a variable in one term is matched against a subterm of the
other term, it might not necessarily be unifyable with it, because
there might be other constraints imposed on it.
Therefore, not_unify/2 must be used to test it explicitly.
- The suspension should be woken not only on binding, but
on any constraining and thus the constrained list
has to be used.
The predicate compare_args/5 is thus changed as follows:
compare_args(_, _, _, _, Yes) :-
nonvar(Yes).
compare_args(A1, A2, Link, NewLink, Yes) :-
var(Yes),
(A1 == A2 ->
Link = NewLink
;
(var(A1);var(A2)) ->
(not_unify(A1, A2) ->
Yes = yes
;
suspend(compare_args(A1, A2, Link, NewLink, Yes), 3,
[[A1|A2]->constrained, Yes->inst])
)
;
compare_terms(A1, A2, Link, NewLink, Yes)
).
Now our dif3/4 predicate yields correct results even for
constrained variables:
[eclipse 1]: dif3(A, B, Y, N), A::1..10, B::20..30.
Y = yes
N = N
A = A{[1..10]}
B = B{[20..30]}
yes.
[eclipse 2]: dif3(A, B, Y, N), A::1..10, B = 5, A ## 5.
Y = yes
N = N
B = 5
A = A{[1..4, 6..10]}
yes.
[eclipse 18]: dif3(A, B, Y, N), A + B $= 1, A $= 1/2.
Y = Y
N = no
B = 1 / 2
A = 1 / 2
yes.
Warwick Harvey
2004-08-07