- Documentation
- Reference manual
- Packages
- A C++ interface to SWI-Prolog
- A C++ interface to SWI-Prolog (Version 2)
- Summary of changes between Versions 1 and 2
- Sample code (version 2)
- Introduction (version 2)
- The life of a PREDICATE (version 2)
- Overview (version 2)
- Examples (version 2)
- Rationale for changes from version 1 (version 2)
- Porting from version 1 to version 2
- The class PlFail (version 2)
- The class PlTerm (version 2)
- The class PlTermv (version 2)
- The class PlAtom - Supporting Prolog constants (version 2)
- Classes for the recorded database: PlRecord and PlRecordExternalCopy
- Unification and foreign frames (version 2)
- The class PlRegister (version 2)
- The class PlQuery (version 2)
- The PREDICATE and PREDICATE_NONDET macros (version 2)
- Exceptions (version 2)
- Embedded applications (version 2)
- Considerations (version 2)
- Conclusions (version 2)
- A C++ interface to SWI-Prolog (Version 2)
- A C++ interface to SWI-Prolog
2.4 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).- "retry" - for non-deterministic predicates, gives a "context" for backtracking / redoing the call for the next solution.
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.C_, A2.C_));
}