Passing Prolog Terms

This section describes passing Prolog terms to a foreign function and receiving Prolog terms from a foreign function. For the current release this interface is supported only for C.

There is a difference between passing atomic objects (atoms, floats, db_reference and integers) and generic Prolog terms through the foreign interface. Generic Prolog terms passed to a C function (using +term) are not converted to any representation in C. Instead the foreign function in C gets a reference to the Prolog term, which is of type QP_term_ref (defined in <quintus/quintus.h>). Similarly when a generic term is returned (using -term or [-term]) from a foreign function there is no conversion of any data structures in the foreign language into an equivalent Prolog representation. The foreign function has to return a reference to a Prolog term, which it originally got from Prolog or from one of the functions/macros provided to manipulate Prolog terms such as the QP_put* and QP_cons* families of functions.

When Prolog terms are referred to from C, what the C function holds is an indirect reference to the Prolog term. There is a reason for this indirection. Prolog terms live in the Prolog global stack, and migrate when Prolog does garbage collection or stack shifting. If the C function held onto a direct reference to a Prolog term it would become invalid after one of these memory management operations. Prolog cannot update and relocate these references that C is holding onto since it is impossible to distinguish between Prolog references and other integers and pointers that C holds onto.

The C code should also be aware of the scope (or lifetime) of the references to Prolog terms passed to it. Once you return to Prolog from a call to a foreign function, all the references to Prolog terms passed to the foreign function are invalid. All references to terms created by the foreign function are also invalid.

WARNING: You should not store references to prolog terms into global variables in the foreign language.

The scope of references to terms are more restricted when C calls Prolog. If Prolog returns a term as a result of a C call to a Prolog predicate, that term is valid only till the call for the next solution from that Prolog predicate (using QP_next_solution()). This also holds true for terms created in C. If you create a term after one call to a Prolog predicate then the reference to that term is only valid till the call for next solution from that Prolog predicate. .