12.3.11 SP_define_c_predicate()


#include <sicstus/sicstus.h>

typedef int 
SP_CPredFun(SP_term_ref goal,
            void *stash);

SP_define_c_predicate(char *name, 
                      int arity, 
                      char *module,
                      SP_CPredFun *proc, 
                      void *stash);

Defines a Prolog predicate such that when the Prolog predicate is called it will call a C function with a term corresponding to the Prolog goal.



The predicate name.


The predicate arity.


The predicate module name.


The function.


See below.

Return Value

Nonzero on success, and 0 otherwise.


The Prolog predicate module:name/arity will be defined (the module module must already exist). The stash argument can be anything and is simply passed as the second argument to the C function proc.

The C function should return SP_SUCCESS for success and SP_FAILURE for failure. The C function may also call SP_fail() or SP_raise_exception() in which case the return value will be ignored.


Here is an end-to-end example of the above:

% square.pl
foreign_resource(square, [init(square_init)]).
:- load_foreign_resource(square).
// square.c
#include <sicstus/sicstus.h>

static int square_it(SP_term_ref goal, void *stash)
  SP_WORD arg1;
  SP_term_ref tmp = SP_new_term_ref();
  SP_term_ref square_term = SP_new_term_ref();

  // goal will be a term like square(42,X)
  SP_get_arg(1,goal,tmp); // extract first arg
  if (!SP_get_integer(tmp,&arg1))
    return SP_FAILURE;   // type check first arg

  SP_put_integer(square_term, arg1*arg1);
  SP_get_arg(2,goal,tmp); // extract second arg

  // Unify output argument.  
  // SP_put_integer(tmp,…) would *not* work!
  return (SP_unify(tmp, square_term) ? SP_SUCCESS : SP_FAILURE);

void square_init(int when)
  (void)when;                   // unused
  // Install square_it as user:square/2
  SP_define_c_predicate("square", 2, "user", square_it, NULL);
# terminal
% splfr square.pl square.c
% sicstus -f -l square
% compiling /home/matsc/tmp/square.pl...
%  loading foreign resource /home/matsc/tmp/square.so in module user
% compiled /home/matsc/tmp/square.pl in module user, 0 msec 816 bytes
SICStus 4.3.2 …
Licensed to SICS
| ?- square(4711, X).
X = 22193521 ?
| ?- square(not_an_int, X).

See Also

See Calling C from Prolog.

Send feedback on this subject.