Next: The Variable-length String Data
Up: Calling XSB from C
Previous: Calling XSB from C
  Contents
  Index
XSB provides several C functions (declared in XSB/emu/cinterf.h
and defined in
XSB/emu/cinterf.c), which can be called from C
to interact with XSB as a subroutine. These functions allow a
C program to initialize XSB (most easily with a call to xsb_init_string(options)) and then to interact with XSB to have it
execute commands or queries. A command is a deterministic
query which simply succeeds or fails (without returning any
interesting data value.) A non-deterministic query can be evaluated
so that its answers are retrieved one at a time, as they are
produced. There are several levels of interface provided. The highest
level interface uses the XSB-specific C-type definition for
variable-length strings (Section 3.2), to communicate
queries to XSB and to get answers back. The xsb_command_string(cmd) function allows you to pass a command as a
(period-terminated) string to XSB. The xsb_query_string_string(query,buff,sep) function allows you to
pass a query to XSB as a string, and have its (first) answer returned
as a string. Subsequent answers can be calculated and retrieved using
xsb_next_string(buff,sep).
The second level provides routines that return answers with an
interface that does not require variable-length strings. The routines
at this level are:
- xsb_query_string_string_b(query,buff,bufflen,anslen,sep),
- xsb_next_string_b(buff,bufflen,anslen,sep), and
- xsb_get_last_answer(buff,bufflen,anslen).
They are normally intended to be used with the initialization routines
above.
There are lower-level interfaces that allow you to manipulate directly
the XSB data structures (both to construct queries and to retrieve
answers) and thus avoid the overhead of converting to and from
strings. See the detailed descriptions of the routines below to see
how to use the lower level interface.
Currently, only one query can be active at a time.
I.e., one must completely finish processing one query (either by
retrieving all the answers for it, or by issuing a call to xsb_close_query(), before trying to evaluate another. The
routines to perform all these functions are described below:
- int xsb_init(int argc, char *argv[])
-
This is a C-callable function that initializes XSB. It must be
called before any other calls can be made. argc is the count of
the number of arguments in the argv vector. The argv
vector is exactly as would be passed from the command line to
XSB. It must contain at least the following two things:
-
must be an absolute or relative path name of the XSB
installation directory (i.e., $XSB_DIR. Here is an
example, which assumes that we invoke the C program from the XSB
installation directory.
int main(int argc, char *argv[])
{
int myargc = 2;
char *myargv[2];
/* XSB_init relies on the calling program to pass the addr of the XSB
installation directory. From here, it will find all the libraries */
myargv[0] = ".";
myargv[1] = "-n";
/* Initialize xsb */
xsb_init(myargc,myargv);
-
must be the -n flag. This flag tells
XSB not to start the read-eval-print top loop, but to act as a
subroutine to a calling C routine.
Other flags are optional, but can be used to modify sizes of the various
spaces used in XSB. xsb_init returns 0 if initialization is
completed, and 1 if an error is encountered.
- int xsb_init_string(char *options)
-
This is a variant of xsb_init which takes the command line as a
string argument (rather than as a argc/argv pair.) For example, a call
could be
xsb_init_string(". -n");
Note that just as with xsb_init, you must pass the path name of the
XSB installation directory. In the above, we pass ``.'', assuming that we
are invoking the C program from the XSB installation directory. The
parameters following the file name are just as those that could appear on a
command line. The function of this subroutine is exactly the same as xsb_init, and its return codes are the same.
- int xsb_command()
-
This function passes a command to XSB. No query can be active
when this command is called. Before calling xsb_command, the
calling program must construct the XSB term representing the
command in register 1 in XSB's space. This can be done by
using the c2p_* (and p2p_*) routines, which are
described in Section 2.3.2 below. Register 2 may also be
set before the call to xsb_query (using xsb_make_vars(int) and xsb_set_var_*()) in which case any
variables set to values in the ret/n term will be so bound in
the call to the command goal. xsb_command invokes the command
represented in register 1 and returns 0 if the command succeeds and 1
if it fails. In either case it resets register 1 back to a free
variable. If there is an error, it returns 2.
- int xsb_command_string(char *cmd)
-
This function passes a command to XSB. The command is a
string consisting of a term that can be read by the XSB reader. The string must be terminated by a period (.). Any previous
query must have already been closed. In all other respects, xsb_command_string is similar to xsb_command.
- int xsb_query()
-
This function passes a query to XSB. Any previous query must
have already been closed. A query is expected to return possibly
multiple data answers. The first is found and made available to the
caller as a result of this call. To get subsequent answers, xsb_next must be called. Before calling xsb_query the caller
must construct the term representing the query in XSB's
register 1 (using routines described in Section 2.3.2
below.) If the query has no answers (i.e., just fails), register 1 is
set back to a free variable and xsb_query returns 1. If the
query has at least one answer, the variables in the query term in
register 1 are bound to those answers and xsb_query returns 0.
In addition, register 2 is bound to a term whose main functor symbol
is ret/n, where n is the number of variables in the query. The
main subfields of this term are set to the variable values for the
first answer. (These fields can be accessed by the functions p2c_*, or the functions xsb_var_*, described in Section
2.3.2 below.) Thus there are two places the answers are
returned. Register 2 is used to make it easier to access them. To get
subsequent answers, xsb_next must be called. Register 2 may
also be set before the call to xsb_query (using xsb_make_vars(int) and xsb_set_var_*()) in which case any
variables set to values in the ret/n term will be so bound in
the call to the goal.
- int xsb_query_string(char *query)
-
This function passes a query to XSB. The query is a string
consisting of a term that can be read by the XSB reader. The
string must be terminated with a period (.). Any previous query must
have already been closed. In all other respects, xsb_query_string
is similar to xsb_query, except the only way to retrieve answers is
through Register 2. The ability to create the return structure and
bind variables in it is particularly useful in this function.
- int xsb_query_string_string(char *query, VarString *buff,
char *sep)
-
This function
is a variant of xsb_query_string that returns its answer (if
there is one) as a string. An example call is:
rc = xsb_query_string_string("append(X,Y,[a,b,c]).",buff,";");
The first argument is the period-terminated query string. The second
argument is a variable string buffer in which the subroutine returns the answer
(if any.) The variable string data type VarString is explained in
Section 3.2. (Use the following function if you cannot
declare a parameter of this type in your programming language.)
The last argument is a string
provided by the caller, which is used to separate fields in the returned
answer. For the example query, buff would be set to the string:
[];[a,b,c]
which is the first answer to the append query. There are two fields of
this answer, corresponding to the two variables in the query, X
and Y
. The bindings of those variables make up the answer and
the individual fields are separated by the sep
string, here the
semicolon (;
). Its returns are
just as for xsb_query_string. In the answer string, XSB atoms are printed in their in their standard print form (without
quotes). Complex terms are printed in a canonical form, with atoms
quoted if necessary, and lists produced in the normal list notation.
- int xsb_query_string_string_b(char *query, char *buff,
int bufflen, int *anslen, char *sep)
-
This function provides a lower-level
interface to xsb_query_string_string (not using the VarString type), which makes it easier for non-C callers (such as
Visual Basic or Delphi) to access XSB functionality. The first and
last arguments are the same as in xsb_query_string_string.
The buff
, bufflen
, and anslen
parameters are used
to pass the answer (if any) back to the caller. buff
is a
buffer provided by the caller in which the answer is returned.
bufflen
is the length of the buffer (buff
) and is
provided by the caller. anslen
is returned by this routine and
is the length of the computed answer. If that length is less than
bufflen
, then the answer is put in buff
(and
null-terminated). If the answer is longer than will fit in the buffer
(with the null terminator), then the answer is not copied to the
buffer and 3 is returned. In this case the caller can retrieve the
answer by providing a bigger buffer (of size greater than the returned
anslen
) in a call to xsb_get_last_answer_string.
- int xsb_get_last_answer_string(char *buff, int bufflen,
int *anslen)
-
This
function is used only when a call to xsb_query_string_string_b or to xsb_next_string_b
returns a 3, indicating that the buffer provided was not big enough to
contain the computed answer. In that case the user may allocate a
larger buffer and then call this routine to retrieve the answer (that
had been saved.) Only one answer is saved, so this routine must
called immediately after the failing call in order to get the right
answer. The parameters are the same as the 2nd through 4th parameters
of xsb_query_string_string_b.
- int xsb_next()
-
This routine is called after xsb_query (which must have
returned 0) to retrieve more answers. It rebinds the query variables
in the term in register 1 and rebinds the argument fields of the ret/n answer term in register 2 to reflect the next answer to the
query. It returns 0 if an answer is found, and returns 1 if there are
no more answers and no answer is returned. On a return of 1, the query
has been closed. After a query is closed, another xsb_command
or xsb_query invocation can be made.
- int xsb_next_string(VarString *buff,char *sep)
-
This routine is a variant of xsb_next that
returns its answer (if there is one) as a string. Its treatment of
answers is just as xsb_query_string_string. For example after
the example call
rc = xsb_query_string_string("append(X,Y,[a,b,c]).",buff,";");
which returns with buff set to
[];[a,b,c]
Then a call:
rc = xsb_next_string(buff,";");
returns with buff set to
[a];[b,c]
the second answer to the indicated query. xsb_next_string
returns codes just as xsb_next.
- int xsb_next_string_b(char *buff, int bufflen, int
*anslen, char *sep)
-
This routine is a
variant of xsb_next_string that does not use the VarString type. Its parameters are the same as the 2nd through 5th
parameters of xsb_query_string_string_b. The next answer to
the current query is returned in buff
, if there is enough
space. If the buffer would overflow, this routine returns 3, and the
answer can be retrieved by providing a larger buffer in a call to xsb_get_last_answer_string_b. In any case, the length of the
answer is returned in anslen
.
- int xsb_close_query()
-
This routine closes a query, before all its answers have been
retrieved. Since XSB is (usually) a tuple-at-a-time system,
answers that are not retrieved are not computed.
It is an error to call xsb_query again without
first either retrieving all the answers to the previous query or
calling xsb_close_query to close it.
- int xsb_close()
-
This routine closes the entire connection to XSB. After this,
no more calls can be made (including calls to xsb_init.)
Next: The Variable-length String Data
Up: Calling XSB from C
Previous: Calling XSB from C
  Contents
  Index
Luis Fernando P. de Castro
2003-06-27