## 6.2 Coroutining

Coroutining deals with having Prolog goals scheduled for execution as soon as some conditions is fulfilled. In Prolog the most commonly used conditions is the instantiation (binding) of a variable. Scheduling a goal to execute immediately after a variable is bound allows may be used to avoid instantiation errors for some built-in predicates (e.g. arithmetic), do work lazy, prevent the binding of a variable to a particular value, etc. Using freeze/2 for example we can define a variable can only be assigned an even number:

    ?- freeze(X, X mod 2 =:= 0), X = 3

    No

freeze(+Var, :Goal)
  Delay the execution of Goal until Var is bound (i.e. is not a variable or attributed variable). If Var is bound on entry freeze/2 is equivalent to call/1. The freeze/2 predicate is realised using an attributed variable associated with the module `freeze`, so `get_attr(Var, freeze, AttVal)` can be used to find out whether and which goals are delayed on Var.
frozen(@Var, -Goal)
  Unify Goal with the goal or conjunction of goals delayed on Var. If no goals are frozen on Var, Goal is unified to `true`.
when(@Condition, :Goal)
  Execute Goal when Condition becomes true. Condition is one of `?=(X, Y)`, `nonvar(X)`, `ground(X)`, ``,`(Cond1, Cond2)` or ``;`(Cond1, Cond2)`. See also freeze/2 and dif/2. The implementation can deal with cyclic terms.

  The when/2 predicate is realised using attributed variable associated with the module `when`. It is defined in the autoload library `library(when)`.

dif(@A, @B)
  The dif/2 predicate provides a constraint stating that A and B are different terms. If A and B can never unify dif/2 succeeds deterministically. If A and B are identical it fails immediately and finally, if A and B can unify, goals are delayed that prevent A and B to become equal. The dif/2 predicate behaves as if defined by `dif(X, Y) :- when(?=(X, Y), X \== Y)`. See also ?=/2. The implementation can deal with cyclic terms.

  The dif/2 predicate is realised using attributed variable associated with the module `dif`. It is defined in the autoload library `library(dif)`.