Did you know ... | Search Documentation: |
Data conversion |
The bi-directional conversion between Prolog and Python terms is
summarized in the table below. For compatibility with Prolog
implementations without native dicts we support converting the
{k1:v1, k2:v2, ...}
to dicts. Note that {k1:v1, k2:v2}
is syntactic sugar for {}(','(:(k1,v1), :(k2,v2)))
. We
allow for embedding this in a py(Term)
such that, with py
defined as prefix operator, py{k1:v1, k2:v2}
is
both valid syntax as SWI-Prolog dict as as ISO Prolog compliant term and
both are translated into the same Python dict. Note that {}
translates to a Python string, while py({})
translates into
an empty Python dict.
By default we translate Python strings into Prolog atoms. Given we
support strings, this is somewhat dubious. There are two reasons for
this choice. One is the pragmatic reason that Python uses strings both
for identifiers and arbitrary text. Ideally we'd have the first
translated to Prolog atoms and the latter to Prolog strings, but,
because we do not know which strings act as identifier and which as just
text, this is not possible. The second is to improve compatibility with
Prolog systems that do not support strings. Note that py_call/3
and py_iter/3
provide the option
py_string_as(Type)
to obtain strings in an alternative
format, where Type is one of atom
, string
, codes
or chars
.
Prolog | Python | Notes | |
Variable | ⟶ | - | (instantiation error) |
Integer | ⟺ | int | Supports big integers |
Rational | ⟺ | fractions.Fraction() | |
Float | ⟺ | float | |
@(none) | ⟺ | None | |
@(true) | ⟺ | True | |
@(false) | ⟺ | False | |
Atom | ⟵ | enum.Enum() | Name of Enum instance |
Atom | ⟺ | String | Depending
on py_string_as option |
String | ⟶ | String | |
string(Text) | ⟶ | String | Text is an atom, string, code- or char list |
#(Term) | ⟶ | String | stringify using write_canonical/1 if not atomic |
prolog(Term) | ⟶ | janus.Term() | Represents any Prolog term |
Term | ⟵ | janus.Term() | |
List | ⟶ | List | |
List | ⟵ | Sequence | |
List | ⟵ | Iterator | Note that a Python Generator is an Iterator |
py_set(List) | ⟺ | Set | |
-() | ⟺ | () | Python empty Tuple |
-(a,b, ... ) | ⟺ | (a,b, ... ) | Python Tuples. Note that a Prolog pair A-B
maps to a Python (binary) tuple. |
Dict | ⟺ | Dict | Default for SWI-Prolog |
{k:v, ...} | ⟺ | Dict | Compatibility
when using py_dict_as( |
py({}) | ⟵ | {} | Empty
dict when using py_dict_as( |
{k:v, ...} | ⟶ | Dict | Compatibility (see above) |
py({k:v, ...}) | ⟶ | Dict | Compatibility (see above) |
eval(Term) | ⟶ | Object | Evaluate Term as first argument of py_call/2 |
py_obj blob | ⟺ | Object | Used for any Python object not above |
Compound | ⟶ | - | for any term not above (type error) |
The interface supports unbounded integers and rational numbers. Large integers (> 64 bits) are converted using a hexadecimal string as intermediate. SWI-Prolog rational numbers are mapped to the Python class fractions:Fraction.1Currently, mapping rational numbers to fractions uses a string as intermediate representation and may thus be slow.
The conversion #(Term) allows passing anything as a Python string. If
Term is an atom or string, this is the same as passing the
atom or string. Any other Prolog term is converted as defined by
write_canonical/1.
The conversion prolog(Term)
creates an instance of janus.Term().
This class encapsulates a copy of an arbitrary Prolog term. The
SWI-Prolog implementation uses the
PL_record() and PL_recorded() functions to store and
retrieve the term. Term may be any Prolog term, including blobs,
attributed variables. Cycles and subterm sharing in
Term are preserved. Internally, janus.Term()
is used to represent Prolog exeptions that are raised during the
execution of
janus.query_once() or janus.query().
Python Tuples are array-like objects and thus map best to a Prolog
compound term. There are two problems with this. One is that few systems
support compound terms with arity zero, e.g., f
and many
systems have a limit on the arity of compound terms. Using
Prolog comma lists, e.g., (a,b,c)
does not
implement array semantics, cannot represent empty tuples and cannot
disambiguate tuples with one element from the element itself. We settled
with compound terms using the
as functor to
make the common binary tuple map to a Prolog pair.
-