Did you know ... | Search Documentation: |
Standalone Mode: Debugging Prolog Code Used in an Application |
When using the Machine Query Interface from another language, debugging the Prolog code itself can often be done by viewing traces from the Prolog native writeln/1 or debug/3 predicates. Their output will be shown in the debugger of the native language used. Sometimes an issue surfaces deep in an application. When this happens, running the application in the native language while setting breakpoints and viewing traces in Prolog itself is often the best debugging approach. Standalone mode is designed for this scenario.
As the MQI is a multithreaded application, debugging the running code requires using the multithreaded debugging features of SWI Prolog as described in the section on "Debugging Threads" in the SWI Prolog documentation. A typical flow for Standalone Mode is:
tdebug, mqi_start([port(4242), password(debugnow)])
.In Python this would look like:
% From the SWI Prolog top level ?- tdebug, mqi_start([port(4242), password(debugnow)]). % The graphical front-end will be used for subsequent tracing true.
# Python using the swiplserver library {#mqi-library} from swiplserver import PrologMQI, PrologThread with PrologMQI(launch_mqi=False, port=4242, password="debugnow") as mqi: with mqi.create_thread() as prolog_thread: # Your code to be debugged here
At this point, all of the multi-threaded debugging tools in SWI Prolog are available for debugging the problem. If the issue is an unexpected exception, the exception debugging features of SWI Prolog can be used to break on the exception and examine the state of the application. If it is a logic error, breakpoints can be set to halt at the point where the problem appears, etc.
Note that, while using an MQI library to access Prolog will normally end and restart the process between runs of the code, running the server in standalone mode doesn't clear state between launches of the application. You'll either need to relaunch between runs or build your application so that it does the initialization at startup.