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.
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; }
4.2 Casting PlTerm to native C-types
PlTerm can be casted 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 atype_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*).
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 returnsTRUE
if successful andFALSE
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; }
4.4 Comparison
- int PlTerm::operator ==(const PlTerm &t)
- int PlTerm::operator !=(const PlTerm &t)
- int PlTerm::operator <(const PlTerm &t)
- int PlTerm::operator >(const PlTerm &t)
- int PlTerm::operator <=(const PlTerm &t)
- int PlTerm::operator >=(const PlTerm &t)
- 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 atype_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 antype_error
exception if the conversion failed.
Below are some typical examples. See section 6 for direct manipulation of atoms in their internal representation.
A1 < 0 | Test 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''. |
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, adomain_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 tognat
...., if ( x[1] == "gnat" ) ...
- const char * PlTerm::name()
- Return a
const char *
holding the name of the functor of the compound term. Raises atype_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.
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
orPL_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.
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.
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.
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.
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"))
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 andFALSE
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 &t)
- Bind t to the next element of the list PlTail
and advance
PlTail. Returns
TRUE
on success andFALSE
if PlTail represents the empty list. If PlTail is neither a list nor the empty list, atype_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; }