[Up] [Contents] [Index] [Summary]

5.6.6.2 Initiating a query from C

This section discusses the functions for creating and manipulating queries from C. Note that a foreign context can have at most one active query. This implies it is allowed to make strictly nested calls between C and Prolog (Prolog calls C, calls Prolog, calls C, etc., but it is not allowed to open multiple queries and start generating solutions for each of them by calling PL_next_solution(). Be sure to call PL_cut_query() or PL_close_query() on any query you opened before opening the next or returning control back to Prolog.

qid_t PL_open_query(module_t ctx, int debug, predicate_t p, term_t +t0)
Opens a query and returns an identifier for it. This function always succeeds, regardless whether the predicate is defined or not. ctx is the context module of the goal. When NULL, the context module of the calling context will be used, or user if there is no calling context (as may happen in embedded systems). Note that the context module only matters for module_transparent predicates. See context_module/1 and module_transparent/1. The debug argument is normally TRUE. If FALSE is specified, the goal is run in `nodebug' mode, regardless of the current debug mode. The p argument specifies the predicate, and should be the result of a call to PL_pred() or PL_predicate(). Note that it is allowed to store this handle as global data and reuse it for future queries. The term-reference t0 is the first of a vector of term-references as returned by PL_new_term_refs(n).

The example below opens a query to the predicate is_a/2 to find the ancestor of for some name.

char * ancestor(const char *me) { term_t a0 = PL_new_term_refs(2); static predicate_t p; if ( !p ) p = PL_predicate("is_a", 2, "database"); PL_put_atom_chars(a0, me); PL_open_query(NULL, TRUE, p, a0); ... }

int PL_next_solution(qid_t qid)
Generate the first (next) solution for the given query. The return value is TRUE if a solution was found, or FALSE to indicate the query could not be proven. This function may be called repeatedly until it fails to generate all solutions to the query.

void PL_cut_query(qid)
Discards the query, but does not delete any of the data created by the query. It just invalidate qid, allowing for a new call to PL_open_query() in this context.

void PL_close_query(qid)
As PL_cut_query(), but all data and bindings created by the query are destroyed.

int PL_call_predicate(module_t m, int debug, predicate_t pred, term_t +t0)
Shorthand for PL_open_query(), PL_next_solution(), PL_cut_query(), generating a single solution. The arguments are the same as for PL_open_query(), the return value is the same as PL_next_solution().

int PL_call(term_t, module_t)
Call term just like the Prolog predicate once/1. Term is called in the specified module, or in the context module if module_t = NULL. Returns TRUE if the call succeeds, FALSE otherwise. Figure 9 shows an example to obtain the number of defined atoms. All checks are omitted to improve readability.