The coroutining facility can be accessed by a number of built-in predicates. This makes it possible to use coroutines in a dynamic way, without having to rely on block declarations:
when(
+Condition,
:Goal)
Blocks Goal until the Condition is true, where Condition is a Prolog goal with the restricted syntax:
nonvar(
X)
ground(
X)
?=(
X,
Y)
Condition,
Condition
Condition;
Condition
For example:
| ?- when(((nonvar(X);?=(X,Y)),ground(T)), process(X,Y,T)).
freeze(
?X,
:Goal)
Blocks Goal until nonvar(
X)
(see Meta Logic)
holds. This is defined as if by:
freeze(X, Goal) :- when(nonvar(X), Goal).
or
:- block freeze(-, ?). freeze(_, Goal) :- Goal.
frozen(
-Var,
?Goal)
If some goal is blocked on the variable Var, or Var has
attributes that can be interpreted as a goal (see Attributes),
then that goal is unified with Goal. If no goals are blocked,
Goal is unified with the atom true
. If more than one
goal is blocked, a conjunction is unified with Goal.
dif(
?X,
?Y)
Constrains X and Y to represent different terms i.e. to be
non-unifiable. Calls to dif/2
either succeed, fail, or are
blocked depending on whether X and Y are sufficiently
instantiated. It is defined as if by:
dif(X, Y) :- when(?=(X,Y), X\==Y).
call_residue(
:Goal,
?Residue)
The Goal is executed as if by call/1
. If during the
execution some attributes or blocked goals were attached to some
variables, then Residue is unified with a list of
VariableSet-Goal pairs, and those variables no longer have
attributes or blocked goals attached to them. Otherwise,
Residue is unified with the empty list []
.
VariableSet is a set of variables such that when any of the variables is bound, Goal gets unblocked. Usually, a goal is blocked on a single variable, in which case VariableSet is a singleton.
Goal is an ordinary goal, sometimes module prefixed. For example:
| ?- call_residue((dif(X,f(Y)), X=f(Z)), Res). X = f(Z), Res = [[Y,Z]-(prolog:dif(f(Z),f(Y)))]