next up previous contents index
Next: The Variable-length String Data Up: Calling XSB from C Previous: Calling XSB from C   Contents   Index

C Functions for Calling XSB

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:

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: 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 up previous contents index
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