Skip to content

Commit

Permalink
Added the initial value exchange doc
Browse files Browse the repository at this point in the history
  • Loading branch information
yuce committed Oct 27, 2024
1 parent ee4008c commit 8311671
Show file tree
Hide file tree
Showing 5 changed files with 77 additions and 5 deletions.
3 changes: 2 additions & 1 deletion docs/source/get_started.rst
Original file line number Diff line number Diff line change
Expand Up @@ -153,8 +153,9 @@ SWI-Prolog can be installed using ``pkg``::
Test Drive
----------

Run a quick test by running following code at your Python console::
Run a quick test by running following code at your Python console:

.. code-block:: python
from pyswip import Prolog
Prolog.assertz("father(michael,john)")
Expand Down
1 change: 1 addition & 0 deletions docs/source/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ It features an SWI-Prolog foreign language interface, a utility class that makes
:caption: Contents:

get_started
value_exchange
api/modules

Indices and Tables
Expand Down
65 changes: 65 additions & 0 deletions docs/source/value_exchange.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
Value Exchange Between Python and Prolog
========================================

String Interpolation from Python to Prolog
------------------------------------------

Currently there's limited support for converting Python values automatically to Prolog via a string interpolation mechanism.
This mechanism is available to be used with the following ``Prolog`` class methods:

* ``assertz``
* ``asserta``
* ``retract``
* ``query``

These methods take one string format argument, and zero or more arguments to replace placeholders with in the format to produce the final string.
Placeholder is ``%p`` for all types.

The following types are recognized:

* String
* Integer
* Float
* Boolean
* ``pyswip.Atom``
* ``pyswip.Variable``
* Lists of the types above

Other types are converted to strings using the ``str`` function.

.. list-table:: String Interpolation to Prolog
:widths: 50 50
:header-rows: 1

* - Python Value
- String
* - str ``"Some value"``
- ``"Some value"``
* - int ``38``
- ``38``
* - float ``38.42``
- ``38.42``
* - bool ``True``
- ``1``
* - bool ``False``
- ``0``
* - ``pyswip.Atom("carrot")``
- ``'carrot'``
* - ``pyswip.Variable("Width")``
- ``Width``
* - list ``["string", 12, 12.34, Atom("jill")]``
- ``["string", 12, 12.34, 'jill']``
* - Other ``value``
- ``str(value)``


The placeholders are set using ``%p``.

Example:

.. code-block:: python
ids = [1, 2, 3]
joe = Atom("joe")
Prolog.assertz("user(%p,%p)", joe, ids)
list(Prolog.query("user(%p,IDs)", joe))
4 changes: 4 additions & 0 deletions src/pyswip/prolog.py
Original file line number Diff line number Diff line change
Expand Up @@ -534,6 +534,10 @@ def make_prolog_str(value) -> str:
elif isinstance(value, Variable):
# TODO: escape variable name
return value.chars
elif value is True:
return "1"
elif value is False:
return "0"
return str(value)


Expand Down
9 changes: 5 additions & 4 deletions tests/test_prolog.py
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ def test_placeholder_2(self):
joe = Atom("joe")
ids = [1, 2, 3]
Prolog.assertz("user(%p,%p)", joe, ids)
result = list(Prolog.query("user(%p, IDs)", joe))
result = list(Prolog.query("user(%p,IDs)", joe))
self.assertEqual([{"IDs": [1, 2, 3]}], result)


Expand All @@ -140,6 +140,8 @@ def test_placeholder_2(self):
("before%pafter", (123.45,), "before123.45after"),
("before%pafter", (Atom("foo"),), "before'foo'after"),
("before%pafter", (Variable(name="Foo"),), "beforeFooafter"),
("before%pafter", (False,), "before0after"),
("before%pafter", (True,), "before1after"),
(
"before%pafter",
(["foo", 38, 45.897, [1, 2, 3]],),
Expand All @@ -148,7 +150,6 @@ def test_placeholder_2(self):
]


@pytest.mark.parametrize("fixture", format_prolog_fixture)
def test_convert_to_prolog(fixture):
format, args, target = fixture
@pytest.mark.parametrize("format, args, target", format_prolog_fixture)
def test_convert_to_prolog(format, args, target):
assert format_prolog(format, args) == target

0 comments on commit 8311671

Please sign in to comment.