17.12 Simulating other System's Delay-Primitives
It is relatively easy to simulate similar constructs from other
systems by using delay clauses,
for example, MU-Prolog's sound negation predicate ~
/1
can be in ECLiPSe simply implemented as
delay ~ X if nonground(X).
~ X :- \+ X .
MU-Prolog's wait declarations can be in most cases
simulated using delay clauses.
Although it is not possible to convert all wait declarations
to delay clauses, in the real life examples
this can usually be achieved.
The block declarations of SICStus Prolog can be easily expressed
as delay clauses with var/1 and nonground/1 conditions.
The freeze/2 predicate (e.g. from SICStus Prolog, same as
geler/2 in Prolog-II) can be expressed as
delay freeze(X, _) if var(X).
freeze(_, Goal) :- call(Goal).
The transcription of when declarations from NU_Prolog
basically involves negating them:
for instance, the when declarations
?- flatten([], _) when ever.
?- flatten(A._, _) when A.
can be rewritten as
delay flatten(A, _) if var(A).
delay flatten([A|_], _) if var(A).
Note that in contrast to when declarations,
there are no syntactic restrictions on the head of a delay clause,
in particular, it can contain any compound terms and repeated variables.
In the clause body, a delay clause allows more flexibility by supporting
programming with (a subset of) builtins.
In general, it is a matter of taste whether specifying delay-conditions
or execute-conditions is more straightforward.
However, the semantics of delay clauses is certainly more intuitive in
that missing delay clauses simply imply no delay, while missing
when-declarations imply a most general 'when ever' declaration.