SWI-Prolog Python interface
All Application Manual Name SummaryHelp

  • Documentation
    • Reference manual
    • Packages
      • SWI-Prolog Python interface
        • Introduction
        • Data conversion
        • Janus by example - Prolog calling Python
        • library(janus): Call Python from Prolog
        • Calling Prolog from Python
        • Janus and threads
        • Janus and signals
        • Janus versions
        • Janus as a Python package
        • Prolog and Python
        • Janus performance evaluation
        • Python or C/C++ for accessing resources?
        • Janus platforms notes
        • Compatibility to the XSB Janus implementation
          • Writing portable Janus modules
        • Status of Janus

14 Compatibility to the XSB Janus implementation

We aim to provide an interface that is close enough to allow developing Prolog code that uses Python and visa versa. Differences between the two Prolog implementation make this non-trivial. SWI-Prolog has native support for dicts, strings, unbounded integers, rational numbers and blobs that provide safe pointers to external objects that are subject to (atom) garbage collection.

We try to find a compromise to make the data conversion as close as possible while supporting both systems as good as possible. For this reason we support creating a Python dict both from a SWI-Prolog dict and from the Prolog term py({k1:v1, k2:v2, ...}). With py defined as a prefix operator, this may be written without parenthesis and is thus equivalent to the SWI-Prolog dict syntax. The library(janus) library provides access predicates that are supported by both systems and where the SWI-Prolog version supports both SWI-Prolog dicts and the above Prolog representation. See items/2, values/3, key/2 and items/2.

Calling Python from Prolog provides a low-level and a more high level interface. The high level interface is realized by py_call/[2,3] and py_iter/[2,3]. We realize the low level interfaces py_func/[3,4] and py_dot/[4,5] on top of py_call/2. The interface for calling Prolog from Python is settled on the five primitives described in section 5.

We are discussing to minimize the differences. Below we summarize the known differences.

  • SWI-Prolog represents Phyton dicts as Prolog dicts. XSB uses a term py({k:v, ...}), where the py() wrapper is optional. The predicate py_is_dict/1 may be used to test that a Prolog term represents a Python dict. The predicates values/3, keys/2, key/2 and items/2 can be used to access either representation.
  • SWI-Prolog allows for prolog(Term) to be sent to Python, creating an instance of janus.Term().
  • SWI-Prolog represents Python object references as a blob. XSB uses a term. The predicate py_is_object/1 may be used to test that a Prolog term refers to a Python object. In XSB, the user must call py_free/1 when done with some object. In SWI-Prolog, either py_free/1 may be used or the object may be left to the Prolog (atom) garbage collector.
  • Prolog exceptions passed to Python are represented differently.
  • When calling Prolog from Python and relying on well founded semantics, only plain truth values (i.e., janus.undefined) are supported in a portable way. Delay lists, providing details on why the result is undefined, are represented differently.

14.1 Writing portable Janus modules

This section will be written after the dust has settled. Topics

  • Dealing with Python dicts
  • Dealing with Prolog modules
  • Dealing with Prolog references to Python objects
  • More?