For delaying calls to user-defined Prolog predicates, ECLiPSe provides several alternatives, the first being delay clauses. Delay clauses are a declarative means (they are in fact meta-clauses) to specify the conditions under which the predicate should delay. The semantics of delay clauses is thus cleaner than many alternative approaches to delay primitives.
A delay clause is very similar to a normal Prolog clause. It has the form
delay <Head> if <Body>.
A predicate may have one or more delay clauses. They have to be textually before and consecutive with the normal clauses of the predicate they belong to. The simplest example for a delay clause is one that checks if a variable is instantiated:
delay report_binding(X) if var(X). report_binding(X) :- printf("Variable has been bound to %w\n", [X]).
The operational semantics of the delay clauses is as follows: when a procedure with delay clauses is called, then the delay clauses are executed before executing the procedure itself. If one of the delay clauses succeeds, the call is suspended, otherwise they are all tried in sequence and, if all delay clauses fail, the procedure is executed as usual.
The mechanism of executing a delay clause is similar to normal Prolog clauses with two exceptions:
does not match the goal p(A, b) but it matches the goal p(a, b).delay p(a, X) if var(X).
The reason for using pattern matching instead of unification is to avoid a possible mixing of meta-level control with the object level, similarly to [4].
The form of the head of a delay clause is not restricted. For the body, the following conditions hold:
delay integer_list(L) if var(L). delay integer_list([X|_]) if var(X). integer_list([]). integer_list([X|T]) :- integer(X), integer_list(T).
delay p(X, X, Y) if var(Y).
delay p(X) if compound(X), arg(1, X, Y), nonground(Y).
delay p(X) if nonground(2, X).
executed with the call ?- p(a, b) of course succeeds and the call delays forever, since no variable binding can wake it.delay p(X, Y) if X \== Y.
CAUTION: It may happen that the symbol :- is erroneously used instead of if in the delay clause. To indicate this error, the compiler complains about redefinition of the built-in predicate delay/1.