/usr/local/lib/swipl/library/ext/swipy/janus.pl
All Application Manual Name SummaryHelp

  • swipy
    • janus.pl -- Call Python from Prolog
      • py_version/0
      • py_call/1
      • py_call/2
      • py_call/3
      • py_iter/2
      • py_iter/3
      • py_setattr/3
      • py_is_object/1
      • py_is_dict/1
      • py_free/1
      • py_with_gil/1
      • py_gil_owner/1
      • py_func/3
      • py_func/4
      • py_dot/3
      • py_dot/4
      • values/3
      • keys/2
      • key/2
      • items/2
      • py_shell/0
      • py_pp/1
      • py_pp/2
      • py_pp/3
      • py_object_dir/2
      • py_object_dict/2
      • py_obj_dir/2
      • py_obj_dict/2
      • py_type/2
      • py_isinstance/2
      • py_module_exists/1
      • py_hasattr/2
      • py_import/2
      • py_module/2
      • py_initialize/3
      • py_lib_dirs/1
      • py_add_lib_dir/1
      • py_add_lib_dir/2
 py_iter(+Iterator, -Value) is nondet
 py_iter(+Iterator, -Value, +Options) is nondet
True when Value is returned by the Python Iterator. Python iterators may be used to implement non-deterministic foreign predicates. The implementation uses these steps:
  1. Evaluate Iterator as py_call/2 evaluates its first argument, except the Obj:Attr = Value construct is not accepted.
  2. Call __iter__ on the result to get the iterator itself.
  3. Get the __next__ function of the iterator.
  4. Loop over the return values of the next function. If the Python return value unifies with Value, succeed with a choicepoint. Abort on Python or unification exceptions.
  5. Re-satisfaction continues at (4).

The example below uses the built-in iterator range():

?- py_iter(range(1,3), X).
X = 1 ;
X = 2.

Note that the implementation performs a look ahead, i.e., after successful unification it calls `next()` again. On failure the Prolog predicate succeeds deterministically. On success, the next candidate is stored.

Note that a Python generator is a Python iterator. Therefore, given the Python generator expression below, we can use py_iter(squares(1,5),X) to generate the squares on backtracking.

def squares(start, stop):
     for i in range(start, stop):
         yield i * i
Arguments:
Options- is processed as with py_call/3.
Compatibility
- PIP. The same remarks as for py_call/2 apply.
bug
- Iterator may not depend on janus.query(), i.e., it is not possible to iterate over a Python iterator that under the hoods relies on a Prolog non-deterministic predicate.