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
            • Constructors
            • Casting PlTerm to native C-types
            • Unification
            • Comparison
            • Analysing compound terms
            • Miscellaneous
            • The class PlString
            • The class PlCodeList
            • The class PlCharList
            • The class PlCompound
            • The class PlTail
          • The class PlTermv
          • Supporting Prolog constants
          • The class PlRegister
          • The class PlQuery
          • The PREDICATE macro
          • Exceptions
          • Embedded applications
          • Considerations
          • Conclusions

1.4 The class PlTerm

As we have seen from the examples, the PlTerm class plays a central role in conversion and operating on Prolog data. This section provides complete documentation of this class.

1.4.1 Constructors

PlTerm :: PlTerm()
Creates a new initialised term (holding a Prolog variable).
PlTerm :: PlTerm(term_t t)
Converts between the C-interface and the C++ interface by turning the term-reference into an instance of PlTerm. Note that, being a lightweight class, this is a no-op at the machine-level!
PlTerm :: PlTerm(const char *text)
Creates a term-references holding a Prolog atom representing text.
PlTerm :: PlTerm(const wchar_t *text)
Creates a term-references holding a Prolog atom representing text.
PlTerm :: PlTerm(const PlAtom &atom)
Creates a term-references holding a Prolog atom from an atom-handle.
PlTerm :: PlTerm(long n)
Creates a term-references holding a Prolog integer representing n.
PlTerm :: PlTerm(double f)
Creates a term-references holding a Prolog float representing f.
PlTerm :: PlTerm(void *ptr)
Creates a term-references holding a Prolog pointer. A pointer is represented in Prolog as a mangled integer. The mangling is designed to make most pointers fit into a tagged-integer. Any valid pointer can be represented. This mechanism can be used to represent pointers to C++ objects in Prolog. Please note that‘myclass' should define conversion to and from void *.
PREDICATE(make_my_object, 1)
{ myclass *myobj = new myclass();

  return A1 = (void *)myobj;
}

PREDICATE(free_my_object, 1)
{ myclass *myobj = (void *)A1;

  delete(myobj);
  return TRUE;
}

1.4.2 Casting PlTerm to native C-types

PlTerm can be cast to the following types:

PlTerm ::operator term_t(void)
This cast is used for integration with the C-interface primitives.
PlTerm ::operator long(void)
Yields a long if the PlTerm is a Prolog integer or float that can be converted without loss to a long. throws a type_error exception otherwise.
PlTerm ::operator int(void)
Same as for long, but might represent fewer bits.
PlTerm ::operator double(void)
Yields the value as a C double if PlTerm represents a Prolog integer or float.
PlTerm ::operator wchar_t *(void)
PlTerm ::operator char *(void)
Converts the Prolog argument using PL_get_chars() using the flags CVT_ALL|CVT_WRITE|BUF_RING, which implies Prolog atoms and strings are converted to the represented text. All other data is handed to write/1. If the text is static in Prolog, a direct pointer to the string is returned. Otherwise the text is saved in a ring of 16 buffers and must be copied to avoid overwriting.
PlTerm ::operator void *(void)
Extracts pointer value from a term. The term should have been created by PlTerm::PlTerm(void*).

1.4.3 Unification

int PlTerm::operator =(Type)
The operator = is defined for the Types PlTerm, long, double, char *, wchar_t* and PlAtom. It performs Prolog unification and returns TRUE if successful and FALSE otherwise.

The boolean return-value leads to somewhat unconventional-looking code as normally, assignment returns the value assigned in C. Unification however is fundamentally different to assignment as it can succeed or fail. Here is a common example.

PREDICATE(hostname, 1)
{ char buf[32];

  if ( gethostname(buf, sizeof(buf)) == 0 )
    return A1 = buf;

  return FALSE;
}

1.4.4 Comparison

int PlTerm::operator ==(const PlTerm &)
int PlTerm::operator !=(const PlTerm &)
int PlTerm::operator <(const PlTerm &)
int PlTerm::operator >(const PlTerm &)
int PlTerm::operator <=(const PlTerm &)
int PlTerm::operator >=(const PlTerm &)
Compare the instance with t and return the result according to the Prolog defined standard order of terms.
int PlTerm::operator ==(long num)
int PlTerm::operator !=(long num)
int PlTerm::operator <(long num)
int PlTerm::operator >(long num)
int PlTerm::operator <=(long num)
int PlTerm::operator >=(long num)
Convert PlTerm to a long and perform standard C-comparison between the two long integers. If PlTerm cannot be converted a type_error is raised.
int PlTerm::operator ==(const wchar_t *)
int PlTerm::operator ==(const char *)
Yields TRUE if the PlTerm is an atom or string representing the same text as the argument, FALSE if the conversion was successful, but the strings are not equal and an type_error exception if the conversion failed.

Below are some typical examples. See section 1.6 for direct manipulation of atoms in their internal representation.

A1 < 0Test A1 to hold a Prolog integer or float that can be transformed lossless to an integer less than zero.
A1 < PlTerm(0)A1 is before the term‘0' in the‘standard order of terms'. This means that if A1 represents an atom, this test yields TRUE.
A1 == PlCompound("a(1)")Test A1 to represent the term a(1).
A1 == "now"Test A1 to be an atom or string holding the text “now''.

1.4.5 Analysing compound terms

Compound terms can be viewed as an array of terms with a name and arity (length). This view is expressed by overloading the [] operator.

A type_error is raised if the argument is not compound and a domain_error if the index is out of range.

In addition, the following functions are defined:

PlTerm PlTerm::operator[](int arg)
If the PlTerm is a compound term and arg is between 1 and the arity of the term, return a new PlTerm representing the arg-th argument of the term. If PlTerm is not compound, a type_error is raised. Id arg is out of range, a domain_error is raised. Please note the counting from 1 which is consistent to Prolog's arg/3 predicate, but inconsistent to C's normal view on an array. See also class PlCompound. The following example tests x to represent a term with first-argument an atom or string equal to gnat.
   ...,
   if ( x[1] == "gnat" )
     ...
const char * PlTerm::name()
Return a const char * holding the name of the functor of the compound term. Raises a type_error if the argument is not compound.
int PlTerm::arity()
Returns the arity of the compound term. Raises a type_error if the argument is not compound.

1.4.6 Miscellaneous

int PlTerm::type()
Yields the actual type of the term as PL_term_type(). Return values are PL_VARIABLE, PL_FLOAT, PL_INTEGER, PL_ATOM, PL_STRING or PL_TERM

To avoid very confusing combinations of constructors and therefore possible undesirable effects a number of subclasses of PlTerm have been defined that provide constructors for creating special Prolog terms. These subclasses are defined below.

1.4.7 The class PlString

A SWI-Prolog string represents a byte-string on the global stack. It's lifetime is the same as for compound terms and other data living on the global stack. Strings are not only a compound representation of text that is garbage-collected, but as they can contain 0-bytes, they can be used to contain arbitrary C-data structures.

PlString :: PlString(const wchar_t *text)
PlString :: PlString(const char *text)
Create a SWI-Prolog string object from a 0-terminated C-string. The text is copied.
PlString :: PlString(const wchar_t *text, size_t len)
PlString :: PlString(const char *text, size_t len)
Create a SWI-Prolog string object from a C-string with specified length. The text may contain 0-characters and is copied.

1.4.8 The class PlCodeList

PlCodeList :: PlCodeList(const wchar_t *text)
PlCodeList :: PlCodeList(const char *text)
Create a Prolog list of ASCII codes from a 0-terminated C-string.

1.4.9 The class PlCharList

Character lists are compliant to Prolog's atom_chars/2 predicate.

PlCharList :: PlCharList(const wchar_t *text)
PlCharList :: PlCharList(const char *text)
Create a Prolog list of one-character atoms from a 0-terminated C-string.

1.4.10 The class PlCompound

PlCompound :: PlCompound(const wchar_t *text)
PlCompound :: PlCompound(const char *text)
Create a term by parsing (as read/1) the text. If the text is not valid Prolog syntax, a syntax_error exception is raised. Otherwise a new term-reference holding the parsed text is created.
PlCompound :: PlCompound(const wchar_t *functor, PlTermv args)
PlCompound :: PlCompound(const char *functor, PlTermv args)
Create a compound term with the given name from the given vector of arguments. See PlTermv for details. The example below creates the Prolog term hello(world).
PlCompound("hello", PlTermv("world"))

1.4.11 The class PlTail

The class PlTail is both for analysing and constructing lists. It is called PlTail as enumeration-steps make the term-reference follow the‘tail' of the list.

PlTail :: PlTail(PlTerm list)
A PlTail is created by making a new term-reference pointing to the same object. As PlTail is used to enumerate or build a Prolog list, the initial list term-reference keeps pointing to the head of the list.
int PlTail::append(const PlTerm &element)
Appends element to the list and make the PlTail reference point to the new variable tail. If A is a variable, and this function is called on it using the argument "gnat", a list of the form [gnat|B] is created and the PlTail object now points to the new variable B.

This function returns TRUE if the unification succeeded and FALSE otherwise. No exceptions are generated.

The example below translates the main() argument vector to Prolog and calls the prolog predicate entry/1 with it.

int
main(int argc, char **argv)
{ PlEngine e(argv[0]);
  PlTermv av(1);
  PlTail l(av[0]);

  for(int i=0; i<argc; i++)
    l.append(argv[i]);
  l.close();

  PlQuery q("entry", av);
  return q.next_solution() ? 0 : 1;
}
int PlTail::close()
Unifies the term with [] and returns the result of the unification.
int PlTail::next(PlTerm &)
Bind t to the next element of the list PlTail and advance PlTail. Returns TRUE on success and FALSE if PlTail represents the empty list. If PlTail is neither a list nor the empty list, a type_error is thrown. The example below prints the elements of a list.
PREDICATE(write_list, 1)
{ PlTail tail(A1);
  PlTerm e;

  while(tail.next(e))
    cout << (char *)e << endl;

  return TRUE;
}