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.