Waiting for other Constraints

## 18.3 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.