BinProlog 3.30 supports direct manipulation of binary clauses denoted
Head ::- Body.
We can use them to write programs like:
member_cont(X,Cont)::- strip_cont(Cont,X,NewCont,true(NewCont)). member_cont(X,Cont)::- strip_cont(Cont,_,NewCont,member_cont(X,NewCont)). test(X):-member_cont(X),a,b,c.
?-test(X).
X=a; X=b; X=c; X=
whatever follows from the calling point of test(X)
.
catch(Goal,Name,Cont)::- lval(catch_throw,Name,Cont,call(Goal,Cont)). throw(Name,_)::- lval(catch_throw,Name,Cont,nonvar(Cont,Cont)).
lval(K1,K2,Val)
is a BinProlog
primitive which unifies Val
with a backtrackable global logical
variable accessed by hashing on two (constant or variable)
keys K1,K2
.
This allows for instance to avoid execution of the infinite loop
from inside the predicate b/1
.
loop:-loop. c(X):-b(X),loop. b(hello):-throw(here). b(bye). go:-catch(c(X),here),write(X),nl.
Notice that due to its simple translation semantics this program
still has a first order reading and that BinProlog's lval/3
is not essential as it can be emulated by an extra argument passed
to all predicates.
Although implementation of catch
and throw
requires full-blown
continuations, we can see that at user level, ordinary
clause notation is enough.