# Janus-swi: a bi-directional interface between SWI-Prolog and Python
This code implements a ready-to-use bi-directional interface to
Python. As motivated by Theresa Swift, Python opens many doors for
accessing resources such as graphics, machine learning and many more.
The API defined in this interface has been established as a PIP,
_Prolog Improvement Proposal_. When the PIP is finished and published
we will properly reference it. The main predicates and Python
functions of this interface are compatible with the XSB Python package
`janus_xsb`. Both `janus_swi` and `janus_xsb` implement extensions
upon the agreed interface. For example, `janus_swi` supports
SWI-Prolog dicts and defines thread synchronization between Prolog and
Python.
## Documentation
See [SWI-Prolog manual](https://www.swi-prolog.org/pldoc/package/janus)
## Bi-directional
This GIT repository is a GIT _submodule_ of the SWI-Prolog source
repository. As part of the SWI-Prolog source distribution it is used
to build `library(janus)`, a Prolog library that embeds Python. This
same module can be used stand-alone to build the Python package
`janus_swi` that embeds Prolog into Python. Loaded either way, Janus
is the same and allows for mutually recursive calls between Prolog and
Python.
## Embedding Prolog into Python: the Python janus_swi package
If this repository is used to build the Python pip package
`janus_swi`, we can load SWI-Prolog into Python and call predicates.
For example:
python
>>> import janus_swi as janus
>>> janus.query_once("writeln('Hello world!')")
Hello world!
{'truth': True}
>>>
The Python package is available from __PyPi__ as
[janus-swi](https://pypi.org/project/janus-swi/). We currently
provide a few _wheels_ for Windows. The binaries in the Windows
_wheel_ probably supports all Python and Prolog versions that are also
supported by the source. The package can be installed using `pip`
from source on any system with CPython 3.6 or later, SWI-Prolog 9.1.12
or later and a C compiler. For compiling the C code, GCC, Clang and
VS2022 have been tested. Thus, normally the package can be installed
using
pip install janus-swi
SWI-Prolog is selected from the environment variable `SWIPL` or by
finding `swipl` on the executable search path. On Windows, if neither
of the above work, the Windows registry is examined to find the
installed SWI-Prolog system (by default `C:\Program
Files\swipl\bin\swipl.exe`).
If you installed SWI-Prolog from source, it is advised to install
Janus from the `packages/swipy` directory in the Prolog source. The
package can be installed from within this directory using
pip install .
## Embedding Python into Prolog: library(janus)
Configuration and installation of `library(janus)` which embeds Python
into Prolog is handled by the normal Prolog configuration. Building
the interface requires the libraries and C headers for Python
embedding to be installed. Below are the commands for installing the
embedded Python engine for Ubuntu and Fedora Linux.
apt install python3 libpython3-dev # Ubuntu
dnf install python3-devel # Fedora
On __MacOS__, these files are included in the Homebrew and Macports
versions of Python
On Windows, these files are included in the default installer.
Configuration requires Python to appear in ``%PATH%``.
After successful installation, running `py_version/0` should result in
printing relevant information on the embedded Python system.
?- py_version.
% Janus embeds Python 3.10.12 (main, Jun 11 2023, 05:26:28) [GCC 11.4.0
## Using Conda
Ongoing work to get SWI-Prolog working under Conda can be found at
https://github.com/SWI-Prolog/swi-prolog-feedstock. Eventually, this
work shall be merged with https://anaconda.org/conda-forge/swi-prolog
As is, https://github.com/SWI-Prolog/swi-prolog-feedstock has been
used to build the full SWI-Prolog system with Janus interface on
Linux, MacOS and Windows.
## Alternatives
### MQI (Machine Query Interface)
SWI-Prolog comes bundled with
[MQI](https://www.swi-prolog.org/pldoc/package/mqi). MQI is initiated
from Python and starts SWI-Prolog as a server. It allows calling
Prolog from Python. Separated using networking, this approach is easy
to install and runs with any Python version. It does not allow
calling Python from Prolog, the primary reason for the existence of
this package. Using networking, the latency is relatively high.
### pyswip
The [pyswip](https://github.com/yuce/pyswip) interface uses the
[Python ctypes](https://docs.python.org/3/library/ctypes.html) to
embed Prolog into Python. Only relying on _ctypes_, the package is a
fully portable Python package that supports a wide range of Python and
Prolog versions.
Unlike this package, embedding Python into Prolog is not possible.
_pyswip_ calls Prolog, similarly than janus, using a string. However,
where janus allows passing input to the goal as a _dict_ that is
transferred using the C API rather than strings, _pyswip_ also passes
the input as a string. This is slower, sensitive to _injection
attacks_ and complicated because the user is responsible for
generating valid Prolog syntax. Calls from Prolog to Python are
possible by defining a Prolog predicate from Python. This only seems
to support deterministic predicates and it cannot pass data back to
Prolog. Janus supports calling Python functions and methods directly
and supports enumerating Python _iterators_ and _generators_ as
non-deterministic goals using py_iter/2.
The overhead of Janus is roughly 5 times less than _pyswip_. As
_pyswip_ still sustains over 100K calls per second this is irrelevant
to many applications.
Raw data
{
"_id": null,
"home_page": "https://github.com/SWI-Prolog/packages-swipy",
"name": "janus-swi",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.6",
"maintainer_email": null,
"keywords": "prolog, logic",
"author": "Jan Wielemaker",
"author_email": "Jan Wielemaker <jan@swi-prolog.org>",
"download_url": "https://files.pythonhosted.org/packages/a4/3e/cb5f1d793c4f13627e57df04ac388de2b9b10797857dcbda749df8f11bfc/janus_swi-1.5.2.tar.gz",
"platform": null,
"description": "# Janus-swi: a bi-directional interface between SWI-Prolog and Python\n\nThis code implements a ready-to-use bi-directional interface to\nPython. As motivated by Theresa Swift, Python opens many doors for\naccessing resources such as graphics, machine learning and many more.\n\nThe API defined in this interface has been established as a PIP,\n_Prolog Improvement Proposal_. When the PIP is finished and published\nwe will properly reference it. The main predicates and Python\nfunctions of this interface are compatible with the XSB Python package\n`janus_xsb`. Both `janus_swi` and `janus_xsb` implement extensions\nupon the agreed interface. For example, `janus_swi` supports\nSWI-Prolog dicts and defines thread synchronization between Prolog and\nPython.\n\n## Documentation\n\nSee [SWI-Prolog manual](https://www.swi-prolog.org/pldoc/package/janus)\n\n## Bi-directional\n\nThis GIT repository is a GIT _submodule_ of the SWI-Prolog source\nrepository. As part of the SWI-Prolog source distribution it is used\nto build `library(janus)`, a Prolog library that embeds Python. This\nsame module can be used stand-alone to build the Python package\n`janus_swi` that embeds Prolog into Python. Loaded either way, Janus\nis the same and allows for mutually recursive calls between Prolog and\nPython.\n\n\n## Embedding Prolog into Python: the Python janus_swi package\n\nIf this repository is used to build the Python pip package\n`janus_swi`, we can load SWI-Prolog into Python and call predicates.\nFor example:\n\n python\n\t>>> import janus_swi as janus\n\t>>> janus.query_once(\"writeln('Hello world!')\")\n\tHello world!\n\t{'truth': True}\n\t>>>\n\nThe Python package is available from __PyPi__ as\n[janus-swi](https://pypi.org/project/janus-swi/). We currently\nprovide a few _wheels_ for Windows. The binaries in the Windows\n_wheel_ probably supports all Python and Prolog versions that are also\nsupported by the source. The package can be installed using `pip`\nfrom source on any system with CPython 3.6 or later, SWI-Prolog 9.1.12\nor later and a C compiler. For compiling the C code, GCC, Clang and\nVS2022 have been tested. Thus, normally the package can be installed\nusing\n\n pip install janus-swi\n\nSWI-Prolog is selected from the environment variable `SWIPL` or by\nfinding `swipl` on the executable search path. On Windows, if neither\nof the above work, the Windows registry is examined to find the\ninstalled SWI-Prolog system (by default `C:\\Program\nFiles\\swipl\\bin\\swipl.exe`).\n\nIf you installed SWI-Prolog from source, it is advised to install\nJanus from the `packages/swipy` directory in the Prolog source. The\npackage can be installed from within this directory using\n\n pip install .\n\n\n## Embedding Python into Prolog: library(janus)\n\nConfiguration and installation of `library(janus)` which embeds Python\ninto Prolog is handled by the normal Prolog configuration. Building\nthe interface requires the libraries and C headers for Python\nembedding to be installed. Below are the commands for installing the\nembedded Python engine for Ubuntu and Fedora Linux.\n\n apt install python3 libpython3-dev # Ubuntu\n dnf install python3-devel # Fedora\n\nOn __MacOS__, these files are included in the Homebrew and Macports\nversions of Python\n\nOn Windows, these files are included in the default installer.\nConfiguration requires Python to appear in ``%PATH%``.\n\nAfter successful installation, running `py_version/0` should result in\nprinting relevant information on the embedded Python system.\n\n ?- py_version.\n\t% Janus embeds Python 3.10.12 (main, Jun 11 2023, 05:26:28) [GCC 11.4.0\n\n\n## Using Conda\n\nOngoing work to get SWI-Prolog working under Conda can be found at\nhttps://github.com/SWI-Prolog/swi-prolog-feedstock. Eventually, this\nwork shall be merged with https://anaconda.org/conda-forge/swi-prolog\n\nAs is, https://github.com/SWI-Prolog/swi-prolog-feedstock has been\nused to build the full SWI-Prolog system with Janus interface on\nLinux, MacOS and Windows.\n\n\n## Alternatives\n\n### MQI (Machine Query Interface)\n\nSWI-Prolog comes bundled with\n[MQI](https://www.swi-prolog.org/pldoc/package/mqi). MQI is initiated\nfrom Python and starts SWI-Prolog as a server. It allows calling\nProlog from Python. Separated using networking, this approach is easy\nto install and runs with any Python version. It does not allow\ncalling Python from Prolog, the primary reason for the existence of\nthis package. Using networking, the latency is relatively high.\n\n### pyswip\n\nThe [pyswip](https://github.com/yuce/pyswip) interface uses the\n[Python ctypes](https://docs.python.org/3/library/ctypes.html) to\nembed Prolog into Python. Only relying on _ctypes_, the package is a\nfully portable Python package that supports a wide range of Python and\nProlog versions.\n\nUnlike this package, embedding Python into Prolog is not possible.\n_pyswip_ calls Prolog, similarly than janus, using a string. However,\nwhere janus allows passing input to the goal as a _dict_ that is\ntransferred using the C API rather than strings, _pyswip_ also passes\nthe input as a string. This is slower, sensitive to _injection\nattacks_ and complicated because the user is responsible for\ngenerating valid Prolog syntax. Calls from Prolog to Python are\npossible by defining a Prolog predicate from Python. This only seems\nto support deterministic predicates and it cannot pass data back to\nProlog. Janus supports calling Python functions and methods directly\nand supports enumerating Python _iterators_ and _generators_ as\nnon-deterministic goals using py_iter/2.\n\nThe overhead of Janus is roughly 5 times less than _pyswip_. As\n_pyswip_ still sustains over 100K calls per second this is irrelevant\nto many applications.\n",
"bugtrack_url": null,
"license": "BSD-2-Clause",
"summary": "Janus library to call SWI-Prolog",
"version": "1.5.2",
"project_urls": {
"Documentation": "https://www.swi-prolog.org/pldoc/package/janus",
"Homepage": "https://www.swi-prolog.org",
"Repository": "https://github.com/SWI-Prolog/packages-swipy.git"
},
"split_keywords": [
"prolog",
" logic"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "f3057d7e634dfa721523e1d95f852db3297d2ef6f1a28047c493eb3b383b589a",
"md5": "9aefdead353090b3efa2e7a3a9e97bc1",
"sha256": "7802fc1d9671ed2341f266ac88d37c75770fdad9c936f3ef17bac2226d4caf81"
},
"downloads": -1,
"filename": "janus_swi-1.5.2-cp313-cp313-win_amd64.whl",
"has_sig": false,
"md5_digest": "9aefdead353090b3efa2e7a3a9e97bc1",
"packagetype": "bdist_wheel",
"python_version": "cp313",
"requires_python": ">=3.6",
"size": 76540,
"upload_time": "2025-01-11T13:30:04",
"upload_time_iso_8601": "2025-01-11T13:30:04.182750Z",
"url": "https://files.pythonhosted.org/packages/f3/05/7d7e634dfa721523e1d95f852db3297d2ef6f1a28047c493eb3b383b589a/janus_swi-1.5.2-cp313-cp313-win_amd64.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "a43ecb5f1d793c4f13627e57df04ac388de2b9b10797857dcbda749df8f11bfc",
"md5": "acf85be059674d5de22697015221ed4b",
"sha256": "bfdea2e4933a35744412def927d6e748184a935076e2e51b1fdbbfbdf48d0e47"
},
"downloads": -1,
"filename": "janus_swi-1.5.2.tar.gz",
"has_sig": false,
"md5_digest": "acf85be059674d5de22697015221ed4b",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.6",
"size": 89652,
"upload_time": "2025-01-11T13:10:26",
"upload_time_iso_8601": "2025-01-11T13:10:26.861805Z",
"url": "https://files.pythonhosted.org/packages/a4/3e/cb5f1d793c4f13627e57df04ac388de2b9b10797857dcbda749df8f11bfc/janus_swi-1.5.2.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-01-11 13:10:26",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "SWI-Prolog",
"github_project": "packages-swipy",
"travis_ci": false,
"coveralls": false,
"github_actions": false,
"lcname": "janus-swi"
}