:- use_module(library(delay)). % define helper predicates here :- use_module(library(tap)). % add tests showing common usage 'atom_codes/2 forwards' :- delay(atom_codes(A,C)), A = foo, C == [0'f, 0'o, 0'o]. 'atom_codes/2 backwards' :- delay(atom_codes(A,C)), C = "foo", A == foo. 'length/2 forwards' :- delay(length(L, Len)), L = [H|T], % partially constructing the list ... var(Len), % ... does not trigger the coroutine H = a, var(Len), T = [rest,goes,here], % fully constructing it ... Len =:= 4. % ... does 'length/2 backwards' :- delay(length(L, Len)), Len = 3, L = [_,_,_]. 'univ forwards' :- delay(univ(Term, Name, Args)), Term = a(b,c,d), Name == a, Args == [b,c,d]. 'univ backwards' :- delay(univ(Term, Name, Args)), Name = a, var(Term), % not enough info to instantiate yet Args = [b,c,d], Term == a(b,c,d). 'univ backwards: piecewise arguments' :- delay(univ(Term, Name, Args)), Name = a, var(Term), % not enough info to instantiate yet Args = [b|Tail], var(Term), % still not enough info Tail = [c,d], Term == a(b,c,d).