Before going into a detailed description of the C++ classes we
present a few examples illustrating the‘feel’of the
interface.
This simple example shows the basic definition of the predicate hello/1
and how a Prolog argument is converted to C-data:
PREDICATE(hello, 1)
{ cout << "Hello " << (char *)A1 << endl;
return TRUE;
}
The arguments to PREDICATE()
are the name and arity of the predicate. The macros A<n>
provide access to the predicate arguments by position and are of the
type PlTerm. Casting a PlTerm
to a
char *
or wchar_t *
provides the natural
type-conversion for most Prolog data-types, using the output of write/1
otherwise:
?- hello(world).
Hello world
Yes
?- hello(X)
Hello _G170
X = _G170
This example shows arithmetic using the C++ interface, including
unification, type-checking and conversion. The predicate add/3
adds the two first arguments and unifies the last with the result.
PREDICATE(add, 3)
{ return A3 = (long)A1 + (long)A2;
}
Casting a PlTerm to a long
performs a PL_get_long() and throws a C++ exception if the Prolog
argument is not a Prolog integer or float that can be converted without
loss to a long
. The
=
operator of PlTerm
is defined to perform unification and returns TRUE
or FALSE
depending on the result.
?- add(1, 2, X).
X = 3.
?- add(a, 2, X).
[ERROR: Type error: `integer' expected, found `a']
Exception: ( 7) add(a, 2, _G197) ?
This example is a bit harder. The predicate average/3
is defined to take the template average(+Var, :Goal, -Average) , where Goal
binds Var and will unify Average with average of
the (integer) results.
PlQuery takes the name of a
predicate and the goal-argument vector as arguments. From this
information it deduces the arity and locates the predicate. the
member-function next_solution() yields
TRUE
if there was a solution and FALSE
otherwise. If the goal yielded a Prolog exception it is mapped into a
C++ exception.
PREDICATE(average, 3)
{ long sum = 0;
long n = 0;
PlQuery q("call", PlTermv(A2));
while( q.next_solution() )
{ sum += (long)A1;
n++;
}
return A3 = (double)sum/(double)n;
}