1 A C++ interface to SWI-Prolog (Version 1)
AllApplicationManualNameSummaryHelp

  • Documentation
    • Reference manual
    • Packages
      • A C++ interface to SWI-Prolog
        • A C++ interface to SWI-Prolog (Version 1)
          • Introduction
          • Overview
          • Examples
          • The class PlTerm
          • The class PlTermv
          • Supporting Prolog constants
          • The class PlRegister
          • The class PlQuery
            • The class PlFrame
          • The PREDICATE macro
          • Exceptions
          • Embedded applications
          • Considerations
          • Conclusions

1.8 The class PlQuery

This class encapsulates the call-backs onto Prolog.

PlQuery :: PlQuery(const char *name, const PlTermv &av)
Create a query where name defines the name of the predicate and av the argument vector. The arity is deduced from av. The predicate is located in the Prolog module user.
PlQuery :: PlQuery(const char *module, const char *name, const PlTermv &av)
Same, but performs the predicate lookup in the indicated module.
int PlQuery::next_solution()
Provide the next solution to the query. Yields TRUE if successful and FALSE if there are no (more) solutions. Prolog exceptions are mapped to C++ exceptions.

Below is an example listing the currently defined Prolog modules to the terminal.

PREDICATE(list_modules, 0)
{ PlTermv av(1);

  PlQuery q("current_module", av);
  while( q.next_solution() )
    cout << (char *)av[0] << endl;

  return TRUE;
}

In addition to the above, the following functions have been defined.

int PlCall(const char *predicate, const PlTermv &av)
Creates a PlQuery from the arguments generates the first next_solution() and destroys the query. Returns the result of next_solution() or an exception.
int PlCall(const char *module, const char *predicate, const PlTermv &av)
Same, locating the predicate in the named module.
int PlCall(const wchar_t *goal)
int PlCall(const char *goal)
Translates goal into a term and calls this term as the other PlCall() variations. Especially suitable for simple goals such as making Prolog load a file.

1.8.1 The class PlFrame

The class PlFrame provides an interface to discard unused term-references as well as rewinding unifications (data-backtracking). Reclaiming unused term-references is automatically performed after a call to a C++-defined predicate has finished and returns control to Prolog. In this scenario PlFrame is rarely of any use. This class comes into play if the toplevel program is defined in C++ and calls Prolog multiple times. Setting up arguments to a query requires term-references and using PlFrame is the only way to reclaim them.

PlFrame :: PlFrame()
Creating an instance of this class marks all term-references created afterwards to be valid only in the scope of this instance.
~ PlFrame()
Reclaims all term-references created after constructing the instance.
void PlFrame::rewind()
Discards all term-references and global-stack data created as well as undoing all unifications after the instance was created.

A typical use for PlFrame is the definition of C++ functions that call Prolog and may be called repeatedly from C++. Consider the definition of assertWord(), adding a fact to word/1:

void
assertWord(const char *word)
{ PlFrame fr;
  PlTermv av(1);

  av[0] = PlCompound("word", PlTermv(word));
  PlQuery q("assert", av);
  q.next_solution();
}

This example shows the most sensible use of PlFrame if it is used in the context of a foreign predicate. The predicate's thruth-value is the same as for the Prolog unification (=/2), but has no side effects. In Prolog one would use double negation to achieve this.

PREDICATE(can_unify, 2)
{ PlFrame fr;

  int rval = (A1=A2);
  fr.rewind();
  return rval;
}