Did you know ... | Search Documentation: |
![]() | The life of a PREDICATE (version 2) |
A foreign predicate is defined using the PREDICATE() macro, plus a
few variations on this, such as PREDICATE_NONDET(), NAMED_PREDICATE(),
and NAMED_PREDICATE_NONDET(). These define an internal name for the
function, register it with the SWI-Prolog runtime (where it will be
picked up by the use_foreign_library/1
directive), and define the names A1
, A2
, etc.
for the arguments.7You can define
your own names for the arguments, for example: auto dir=A1, db=A2,
options=A3;
. If a non-deterministic predicate is
being defined, an additional parameter handle
is defined
(of type
PlControl
).
The foreign predicate returns a value:
true
- successfalse
- failure or an error (see section
2.18 and Prolog
exceptions in foreign code).
The following three snippets do essentially the same thing (for
implementing the equivalent of =/2); however the forst option (with
PlTerm::unify_term()) and third option (with Plx_unify()) throw a C++
PlExceptionFail
exception if there's an error and return
true
or false
; the second option (with
PlCheckFail()) throws a PlFail
exception for both failure
and an error and otherwise returns true
- the PREDICATE()
wrapper handles all of these appropriately and reports the same result
back to Prolog; but you might wish to distinguish the two situations in
more complex code.
PREDICATE(eq, 2) { return A1.unify_term(A2); }
PREDICATE(eq, 2) { PlCheckFail(A1.unify_term(A2)); return true; }
PREDICATE(eq, 2) { return Plx_unify(A1.unwrap(), A2.unwrap())); }