I have the following python/prolog program on a Linux(current Fedora) started in a bash:
import janus_swi as janus
for result in janus.query("length(_, X), X = []"):
print(f'{result}')
Obviously this does not terminate.
So I tried to stop it typing Ctrl-C (sending Signal SIGINT).
But this does not work.
(It is possible to kill the program with sending SIGTERM.)
My expectation - as a python progammer - would be that I can kill running python programs with Ctrl-C.
Is it possible to implement stopping with Ctrl-C?
This will make development more convenient and in-line not only with python development, but also most Unix programs.
I don’t know. SWI-Prolog can handle SIGINT gracefully, but if Python is the main program, Python is handling the signal. It would have to defer that to Prolog if Prolog is in control when the signal arrives.
You can get something “kind of” running using this code
sig.py
import janus_swi as janus
import signal
def my_abort(sig, frame):
print("Aborting by raising an exception")
raise Exception("Aborting")
signal.signal(signal.SIGINT, my_abort)
def heartbeat():
i = 1
janus.consult("heartbeat", """
prolog:heartbeat :-
py_call('__main__':heartbeat()).
""")
def loop():
janus.query_once("set_prolog_flag(heartbeat, 10000)")
janus.query_once("between(1, 100 000 000, _),fail")
loop()
The idea is a bit similar to async yielding. We use the heartbeat facility (added to get yields to JavaScripts) to make a call to Python. That is enough to get Python byte code executed regularly and thus get Python signal handling executed. Now, to get out, we generate an exception.
This looks really ugly. Possibly we can call sys.exit(), which raises a SystemExit exception. Now if Prolog catches this it can raise an abort and if Python catches that it can do sys.exit() again, etc. Would that work?