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 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)))]