Erreur "assertion fail" lors de l'appel de pyswip en python

venant d"installer pyswip et ayant fait import pyswip
j’ai l’erreur
Assertion failed: 0, file /home/swipl/src/swipl-devel/src/pl-fli.c, line 2637

from pyswip import Prolog
print(“bbb”)
prolog = Prolog()
print(“ccc”)
for solution in prolog.query(“mortel(X)”):
print("solution ",solution)
print(“ddd”)
solution et ddd ne s’affichent pas

Replicated with SWI-Prolog version 9.1.16 for x86_64-linux
Every query I tried got a similar crash (e.g., goal assert(mortel(foo)), [solution for solution in prolog.query("current_prolog_flag(X), writeln(X)")])
The problem seems to happen when printing the term.

>>> for solution in prolog.query("mortel(X)"):
...   print("solution ", solution)
... 
[Thread 1 (main) at Thu Oct  5 11:26:23 2023] ../src/pl-fli.c:2665: PL_put_chars: Assertion failed: 0
C-stack trace labeled "assert_fail":
  [0] save_backtrace() at /home/peter/src/swipl-devel/build/../src/os/pl-cstack.c:337 [0x7c54ba3ad3e4]
  [1] __assert_fail() at /home/peter/src/swipl-devel/build/../src/pl-assert.c:105 [0x7c54ba375fe6]
  [2] PL_put_chars() at /home/peter/src/swipl-devel/build/../src/pl-fli.c:2667 [0x7c54ba391884]
  [3] ffi_prep_go_closure() at ??:? [0x7c54ba51fd1d]
  [4] ffi_closure_free() at ??:? [0x7c54ba51f289]
  [5] _call_function_pointer() at /home/peter/src/cpython/Modules/_ctypes/callproc.c:938 [0x7c54ba54b7e6]
  [6] PyCFuncPtr_call() at /home/peter/src/cpython/Modules/_ctypes/_ctypes.c:4201 [0x7c54ba546d78]
  [7] python3(_PyObject_MakeTpCall+0x6b) [0x50254b]
  [8] python3(_PyEval_EvalFrameDefault+0x6b4) [0x55bf94]
  [9] python3(+0x108867) [0x508867]
  [10] python3(_PyEval_EvalFrameDefault+0x4cb) [0x55bdab]
  [11] python3(+0x15aa7b) [0x55aa7b]
  [12] python3(PyEval_EvalCode+0x9a) [0x5d2e5a]
  [13] python3(+0x1e7113) [0x5e7113]
  [14] python3(+0x1e709a) [0x5e709a]
  [15] python3(+0xae73f) [0x4ae73f]
  [16] python3(_PyRun_InteractiveLoopObject+0xd7) [0x4aea9a]
  [17] python3(+0xacd48) [0x4acd48]
  [18] python3(PyRun_AnyFileExFlags+0x49) [0x4aeb99]
  [19] python3(+0xb841d) [0x4b841d]
  [20] python3(Py_BytesMain+0x27) [0x5ee957]
  [21] __libc_start_main() at ./csu/../csu/libc-start.c:308 [0x7c54badbdd0a]
  [22] python3(_start+0x2a) [0x58f2ca]
Prolog stack:
(null)
Aborted (core dumped)

Correction: evaluating the generator from Prolog.query() crashed:

for i in prolog.query("current_prolog_flag(X,Y)"): pass

I think it is a problem with the PyPi package. Using the git version from GitHub - yuce/pyswip: PySwip is a Python - SWI-Prolog bridge enabling to query SWI-Prolog in your Python programs. It features an (incomplete) SWI-Prolog foreign language interface, a utility class that makes it easy querying with Prolog and also a Pythonic interface., this works fine for me.

pyswip uses Python ctypes. This duplicates the declarations from SWI-Prolog.h in the Python package. With SWI-Prolog, we are keen to keep C sources compatible and to a lesser extend maintain binary compatibility. Since a few years we provide better binary compatibility and a better interface to deal with incompatibilities. There are surprisingly old versions of SWI-Prolog floating around :frowning:

You can also install the latest SWI-Prolog development release (9.1.16) and either use Python from Prolog (easiest) or install the Janus Python package as described in SWI-Prolog -- Janus as a Python package. Janus provides a richer and faster interface between Prolog and Python.

he same happens with new swu prolog 9.1.16

Yes, because pyswip on PyPi is old and incompatible with the current SWI-Prolog binaries. Either install pyswip from Github or switch to the (now) bundled Janus interface between Prolog and Python. Janus can do a lot more :slight_smile: As is, there is no PyPi package. The other side of the interface, embedding Python in Prolog should be ready to use in most Prolog binaries.

and when i do pip install januspy
i get : cannot find a version that satisfy the requirement
so, no solution !

As I said, there is no PyPi package (yet). To install the package (called janus_swi), see

This worked for me:

git clone --recurs https://github.com/SWI-Prolog/swipl-devel.git
cd swipl-devel/packages/swipy/
pip3 uninstall pyswip
pip3 uninstall janus-swi
pip3 install janus-swi
>>> from janus_swi import *
>>> for i in janus.Query("assert(mortel(bar))"): print(i)
... 
{'truth': True}
>>> for i in janus.Query("assert(mortel(qqsv))"): print(i)
... 
{'truth': True}
>>> for i in janus.Query("mortel(X)"): print(i)
... 
{'truth': True, 'X': 'bar'}
{'truth': True, 'X': 'qqsv'}

There is no need to clone the whole thing. Just cloning GitHub - SWI-Prolog/packages-swipy: Python interface for SWI-Prolog is enough to install the Python janus_swi package. Also running

pip install .

in the cloned repo should be enough. Janus first conflicted with pyswip, but that is resolved (I have both installed) and there is no need to uninstall the target package because pip does so before installing.

We’ll try to make this really easy. Eventually we want a PyPi and Conda package. I’m still unsure how portable that is/can be. Help on this is welcome. As is, the package installs fine from source on Linux, MacOS and Windows given a properly installed pip with a C compiler. I also have a Conda package for SWI-Prolog, which works on Linux, MacOS and almost on Windows ( :frowning: ). I’m not very familiar with what Python users expect and use for adding Python packages. I have the impression that many not pure Python packages are not that easy to install :frowning:

hello

i am now experimenting with swiplserver and i have good results
what i want to do is consult a database file - ok
and then send some queries -ik
and some modifications, using retract (nok) and assert (ok)

two problems remain:

1- cannot retract fact, getting “no query” error retract (homme(moi)) or retract(home(_)) do noting (erroe no query)
i added :- dynamic homme/1. , no change, error no query
2- do not understand the find_all=true or false option
test example:

from swiplserver import PrologMQI, PrologThread
with PrologMQI() as mqi:
with mqi.create_thread() as prolog_thread:
prolog_thread.query_async("consult('c:/web/[essai.pl](http://essai.pl)')")

while True:
result = prolog_thread.query_async_result()
if result is None:
break
else:
print("cc",result)
#ok, print tcc true
prolog_thread.query_async("retract(homme(moi))",find_all=False)
while True:
result = prolog_thread.query_async_result()
if result is None:
break
else:
print("bb",result)
#nok, di nit write bb but error no query
prolog_thread.query_async("mortel(X)",find_all=False)

while True:
result = prolog_thread.query_async_result()
if result is None:
break
else:
print("aa",result)

# ok if retract is commented

My problem is solved using swiplserver
My mistake concernict retract was the way i catch the results, it is necessary to do a loop while trie only for query involving variables, that can take multiple value, retract is not on this situation, so now i can work .
Only what is the meaning of query option findall=false? Is it an other strange way to use the cut !

hello
i have a little swi prolog test program doing stupid things, with one consult containing few facts
then the program do some queries, ok
and the program end with a consult that end with a write
curiously, the write is writed first, before the ok result to the queries
as if all consut was analysed before rening the programm
but the consult could be created by the program itself

from swiplserver import PrologMQI

with PrologMQI() as mqi:
with mqi.create_thread() as prolog_thread:
prolog_thread.query_async(“consult(‘c:/web/essai.pl’)”)
while True:
result = prolog_thread.query_async_result()
if result is None:
break
else:
print(“cc”,result)
break

prolog_thread.query_async(“assertz(homme(moi))”)
print(“eee”)
while True:
print(“hhh”)
result = prolog_thread.query_async_result()
print(“iii”)
if result is None:
break
else:
print(“ff”,result)
break
prolog_thread.query_async(“mortel(_x)”,find_all=False)

while True:
result = prolog_thread.query_async_result()
if result is None:
break
else:
print(“aa”,result)

prolog_thread.query_async(“retractall(homme(_))”)
print(“a2”)
prolog_thread.query_async(“assertz(homme(xyz))”)
print(“a3”)

prolog_thread.query_async(“homme(_x)”,find_all=False)
while True:
result = prolog_thread.query_async_result()
if result is None:
break
else:
print(“ff”,result)
print(“dddddd”)

a consult ending with a write (or containing a syntax error)

prolog_thread.query_async(“consult(‘f:/pierre/prolog/dico/franpy.pl’)”)
result = prolog_thread.query_async_result()
print(“ww”,result)
prolog_thread.query_async(“par(_x)”,find_all=False)
#the wtite or syntax error is written BEFORE the ok results ti query
while True:
result = prolog_thread.query_async_result()
if result is None:
break
else:
print(“bb”,result)
prolog_thread.delete()