Next: Stream Example, Previous: Building for a Target Machine, Up: Mixing C and Prolog Examples [Contents][Index]
Consider, for example, a function returning the square root of its argument after checking that the argument is valid. If the argument is invalid, then the function should raise an exception instead.
/* math.c */
#include <math.h>
#include <stdio.h>
#include <sicstus/sicstus.h>
/* math_glue.h is generated by splfr from the foreign/[2,3] facts.
Always include the glue header in your foreign resource code.
*/
#include "math_glue.h"
extern double sqrt_check(double d);
double sqrt_check(double d)
{
if (d < 0.0) { /* build a domain_error/4 exception term */
SP_term_ref culprit=SP_new_term_ref();
SP_term_ref argno=SP_new_term_ref();
SP_term_ref expdomain=SP_new_term_ref();
SP_term_ref t1=SP_new_term_ref();
SP_put_float(culprit, d);
SP_put_integer(argno, 1);
SP_put_string(expdomain, ">=0.0");
SP_cons_functor(t1, SP_atom_from_string("sqrt"), 1, culprit);
SP_cons_functor(t1, SP_atom_from_string("domain_error"), 4,
t1, argno, expdomain, culprit);
SP_raise_exception(t1); /* raise the exception */
return 0.0;
}
return sqrt(d);
}
The Prolog interface to this function is defined in a file
math.pl. The function uses the sqrt() library function,
and so the math library -lm has to be included:
% math.pl
foreign_resource(math, [sqrt_check]). foreign(sqrt_check, c, sqrt(+float, [-float])). :- load_foreign_resource(math).
A linked foreign resource is created:
% splfr math.pl math.c -lm
A simple session using this function could be:
$ sicstus SICStus 4.10.1 … Licensed to SICS | ?- [math]. % compiling …/math.pl... % loading foreign resource …/math.so in module user % compiled …/math.pl in module user, 0 msec 2400 bytes yes | ?- sqrt(5.0,X). X = 2.23606797749979 ? yes | ?- sqrt(a,X). ! Type error in argument 1 of user:sqrt/2 ! expected a number, but found a ! goal: user:sqrt(a,_110) | ?- sqrt(-5,X). ! Domain error in argument 1 of user:sqrt/1 ! expected '>=0.0', but found -5.0 ! goal: sqrt(-5.0)