On the source language level, the access of LL functions from
relations is performed by a generalized is builtin: in addition
to arithmetical builtins, functions defined in LL may be used
on the right-hand side of is premises. Furthermore,
LL (test) predicates can be used as guards
in relational
clauses.
An LL predicate is a boolean-valued function for which a returned
nil is interpreted as false (failure) and any other
value as true.
The following example illustrates this:
On the abstract machine level,
the accessibility of LL functions
(which are compiled
into LLAMA code)
from predicates (which
are compiled into WAM code) is achieved by extending the WAM with
two new instructions:
Both ll and llp, when executing an -ary LL function/predicate,
push the first
WAM argument registers
on the stack
(this is
necessary since the abstract machine behind LL, the LLAMA, is
a stack machine; see chapter 5). Note that
by simply copying the contents of WAM registers only the toplevel
representation (pointers) of complex data structures (lists and structures)
are copied, not the data structures themselves.
After executing the LLAMA code, the result, which is the topmost
element on the stack, is stored in the first WAM argument register X1
which is then unified with the left-hand side of
the is call.
In case of an LL predicate, a fail is generated if the
return value is nil.