The janus API for Python Calling Prolog

Contents

Truth Values

Some janus Python functions return a truth value along with any Prolog bindings they may make. In this document the domain of such truth values is identified by Truth. Failure of a Prolog goal is denoted by the Python boolean false. In Prologs that don’t support the well-founded semantics, success of a Prolog goal is represented the Python booolean value true. For those Prologs that do support the well-founded semantics, success may also be represented by class janus.undefined which is a unique instance of the class janus.Undefined().

Python Function janus.cmd

  • janus.cmd(module, pred, *args)_

Returns an element of Truth. This function allows Python to execute a Prolog goal containing no variables. module and pred are strings, while each positional argument in *args is a Python object that is translatable to a Prolog term. The Prolog goal is formed over the predicate pred/n where n is the number of positional arguments in *args, and each argument of the goal corresponds to an element in *args. I.e., the input is translated to the Prolog goal

$module.pred(\overrightarrow{args})$

where $\overrightarrow{args}$ is an argument vector.

For instance the Python call

jns.cmd(’user’,’current_prolog_flag’,’bounded’,'true)`

calls

user:current_prolog_flag(bounded,true)

If an error occurred during Prolog execution a Python error is set and the value None is returned.

Python Function `janus.apply_once

  • janus.apply_once_(module, pred, *args, fail=obj)_
    returns a Python janus object. This function allows Python to call a Prolog goal using functional notation, where the function’s return is unified with the last argument of the goal is a variable. Unlike with jns.apply(). The query should be deterimistic: otherwise only the query’s first answer is returned

More specifically, if the number of positional arguments in *args is n, a call will be made to module:pred/(n+1) in which the first n arguments correspond to the arguments in *args while the binding of the final argument is returned to Python as a Python object, i.e. a call $module.pred(\overrightarrow{args},Ret)$ is created, and the binding of Ret is returned. For example: the call f janus.apply_once('lists’,’reverse’,[1,2,3,``’a’:``’b’:’c’``]))

executes the Prolog goal

basics.reverse([1,2,3,’a’:’b’:’c’],Ret)

and returns to Python the binding to Ret

[’a’:’b’:’c’,3,2,1]

(Also cf. Example 2.5 for examples of using a varying number of arguments.)

jns.apply_once() is designed to be very fast, so by default it does not return a truth value if the Prolog goal succeeds; and the function raises a janus.Prolog_Error() if the goal fails. If the keyword parameter fail is set to the Python object obj then obj is returned upon failure. Typically, fail would be set to the Python boolean false.

Python Function janus.query_once

janus.query_once(query_string, **kwargs)

Calls the Prolog goal query_string which must be a well-formed Prolog atom Atom or the term Module:Atom where Module is a Prolog module name. (No ending period should be a part of query_string.) As discussed in Example 2.6, query_string is parsed by Prolog. If there is a dictionary Dict associated with an inputs keyword argument, then for any logical variable Vi in query_string and Python data structure Ai such that Vi : Ai is an item in Dict, Ai is translated to a Prolog term and unified with Vi. All other logical variables in query_string are taken to be (uninstantiated) output variables. Upon the success of query_string their bindings are represented in the return dictionary, which also by default contains the truth value of the answer to query_string.

kwargs allows the following types of keyword arguments.

  • truth_vals determines whether and how each answer in the collection is associated with its truth value. (Cf. Example 2.7 for examples of how the truth_vals options affects returns.)

    Values can be:

    • PLAIN_TRUTHVALS which associates each answer with its truth value as described in Section 1.
    • NO_TRUTHVALS does not associate an answer with any truth value. This option is the default for jns.apply_once and jns.apply(). In systems that support the well-founded semantics, this option should only be used in situations where it is know that no answers will be undefined.
  • Inputs which contains input bindings (in Python syntax) to one or more logical variables in jns.query_string as explained in Example 2.6.

SWI-Prolog version

  • dict query_once(query, bindings={}, keep=False, truth_vals=TruthVals.PLAIN_TRUTHVALS)
    Call query using bindings as once/1, returning a dict with the resulting bindings. If bindings is omitted, no variables are bound. The keep parameter determines whether or not Prolog discards all backtrackable changes. By default, such changes are discarded and as a result, changes to backtrackable global variables are lost. Using True, such changes are preserved.

    >>> query_once("b_setval(a, 1)", keep=True)
    {'truth': 'True'}
    >>> query_once("b_getval(a, X)")
    {'truth': 'True', 'X': 1}

    If query fails, the variables of the query are bound to the Python constant None. The bindings object includes a key truth6As this name is not a valid Prolog variable name, this cannot be ambiguous. that has the value False (query failed, all bindings are None), True (query succeeded, variables are bound to the result converting Prolog data to Python) or an instance of the class janus.Undefined(). The information carried by this instance is determined by the truth parameter. Below is an example. See section 5.4 for details.

    >>> import janus_swi as janus
    >>> janus.query_once("undefined")
    {'truth': Undefined}

    See also janus.cmd() and janus.apply_once(), which provide a fast but more limited alternative for making ground queries (janus.cmd()) or queries with leading ground arguments followed by a single output variable.

    • Compatibility PIP.

Python function apply

XSB version

  • `**apply**(module, pred, *args)<br>jns.apply()is called in the same manner as jns.apply_once()but creates an instance of an iterator class that is used to backtrack through all solutions to the constructed goal. The Prolog goal invoked is automatically closed after iterating through all solutions, or when an explicitjns.close_query()` is called. See Section 2.2.2.1 for examples of its use.

SWI-Prolog version

  • apply apply(module, predicate, *input)
    As janus.apply_once(), returning an iterator that returns individual answers. The example below uses Python list comprehension to create a list of integers from the Prolog built-in between/3.

    >>> [*janus.apply("user", "between", 1, 6)]
    [1, 2, 3, 4, 5, 6]
    • Compatibility PIP.
  • any|None janus.apply.next() Explicitly ask for the next solution of the iterator. Normally, using the apply as an iterator is to be preferred. See discussion above. Note that this calling convention cannot distinguish between the Prolog predicate returning @none and reaching the end of the iteration.

  • None janus.apply.close() Close the query. Closing a query is obligatory. When used as an iterator, the Python destructor (del()) takes care of closing the query.

    • Compatibility PIP.

Python function query

XSB version

  • `**query**(query_string, **kwargs)<br> The string-basedjns.query()is called in the same manner asjns.query_once()but creates an instance of an iterator class that is used to backtrack through all solutions to the constructed goal. The Prolog goal invoked is automatically closed after iterating through all solutions, or when an explicitjns.close_query()` is called. See Section 2.2.2.2 for examples of its use.

SWI-Prolog version

  • query query(query, bindings={}, keep=False)
    As janus.query_once(), returning an iterator that provides an answer dict as janus.query_once() for each answer to query. Answers never have truth False. See discussion above.
    • Compatibility PIP. The keep is a SWI-Prolog extension.
  • Query janus.Query(query, bindings={}, keep=False) Deprecated. This class was renamed to janus.query(.)
  • dict|None janus.query.next() Explicitly ask for the next solution of the iterator. Normally, using the query as an iterator is to be preferred. See discussion above.
  • None janus.query.close() Close the query. Closing a query is obligatory. When used as an iterator, the Python destructor (del()) takes care of closing the query.
    • Compatibility PIP.

Python function consult, ensure_loaded

XSB version

  • `**consult**(file`)
  • `**ensure_loaded**(file`)
    Convenience functions for loading and/or compiling Prolog files. In XSB, they are defined as

jns.cmd(’consult’,’consult’,File)

and

jns.cmd(’consult’,’ensure_loaded’,File).[^28]

Note that a given Prolog file can be compiled and/or loaded into the running Python-Prolog session (via consult() or ensure_loaded()), edited and then repeatedly recompiled and reloaded without problems.

SWI-Prolog version

  • None consult(file, data=None, module='user')
    Load Prolog text into the Prolog database. By default, data is None and the text is read from file. If data is a string, it provides the Prolog text that is loaded and file is used as identifier for source locations and error messages. The module argument denotes the target module. That is where the clauses are added to if the Prolog text does not define a module or where the exported predicates of the module are imported into.

    If data is not provided and file is not accessible this raises a Prolog exception. Errors that occur during the compilation are printed using print_message/2 and can currently not be captured easily. The script below prints the train connections as a list of Python tuples.

        import janus_swi as janus
    
        janus.consult("trains", """
        train('Amsterdam', 'Haarlem').
        train('Amsterdam', 'Schiphol').
        """)
    
        print([d['Tuple'] for d in
               janus.query("train(_From,_To),Tuple=_From-_To")])
    
    • Compatibility PIP. The data and module keyword arguments are SWI-Prolog extensions.


The Prolog Implementers Forum is a part of the "All Things Prolog" online Prolog community, an initiative of the Association for Logic Programming stemming from the Year of Prolog activities.