Answers to queries not written to stdout on WASM + Node

For what I can gather from the source, the WASM shell example relies on the on_output function both for showing SWI-Prolog messages and answers to queries (the latter are sent to the stdout stream).

Running on Node, answers to queries do not seem to be handed to the on_output function. I’m only getting messages such as the initial console banner or things written directly to output with queries like writeln(...).

I need help, as I’m writing a SWI-Prolog Pseudoterminal console for Visual Studio Code and I would like to show answers to queries the way the regular console does (I could build them from Prolog.query() results, but that’s less reliable re to giving the same experience to users).

I don’t know how this is supposed to work in your context. The browser version starts wasm_query_loop/0 from library(wasm). This runs the system such that it yields when it requires input. This allows the browser event loop to do its job.

If you do not have to worry about an event loop you might be able to use synchronous read and you can simply call the normal Prolog toplevel defined by prolog/0.

on_output should be called for all output. If you call a query through the Prolog.query() method you do not get any I/O interaction though. That interface is there for submitting queries from JavaScript and use the results in JavaScript. For stream based interaction you need the toplevel that is defined in boot/toplevel.pl.

Thanks for the reply.

I saw that wasm_query_loop/0 predicate in the source, but I couldn’t get to its definition so I tried to follow the JS code through by inputting a simple query like between(1, 3, X).
When I saw that answers to queries were also passed to print_output (hence to the Module’s on_output) with a stdout stream, I guessed that that could be the way I could get the answers in their “regular” console format.

Here’s a pic:
print_output

To explain better where I stand, I’m building a VSC extension for SWI-Prolog and I’m trying to switch from an integrated swipl terminal (which was working fine) to a Pseudoterminal with a WASM swipl instance underneath.
This mainly to give users code completion and other features focused on loaded code (say: that append call can only be from such libraries as are currently visible and things like that). Using WASM I can issue queries and retrieve results much more easily.
Also, basing the extension on the WASM version of swipl could make it work on instances of Visual Studio Code run on the cloud (which is not an objective of mine really, but still a plus).

Using a Pseudoterminal has me rebuild the entire console interaction from scratch.
I’m doing that now, but regarding query answers (and possibly tracing/debugging) I would like to show the output that swipl normally shows.
E.g. “X = 1, Y = 1” giving “X = Y, Y = 1”

So, I’m in Node and the problems faced in the browser implementation are not there.
To retrieve results of queries I’m currently looping the Query object returned by Prolog.query(), calling.next() at each subsequent answer request. Is that okay?

Download the source and you find it in library/wasm.pl. It is (of course) only installed with the wasm version. wasm_query_loop/0 runs the normal Prolog query loop (prolog/0) in a way that yields control when input is needed. With yield, I mean that PL_next_solution() returns with a special YIELD code, the browser can do what it wants and resume Prolog by calling PL_next_solution() again. That stuff has some more high level support from prolog.js. Might be wise to get the source anyway to understand how things are supposed to work.

The Prolog REPL (Read, Eval, Print Loop) is defined by prolog/0 and does exactly this: call read/1 to read a query, evaluate it and print the result. The browser version uses this loop. It requires reading the normal synchronous way or implement the yield-based approach. You can use parts of the REPL loop by simply calling into the module '$toplevel'. If you decide that is the proper approach, please sync such that we can make the required stuff public such that it won’t disappear by accident in a later version. By default, predicates that are not exported or declared public as well as predicates that start with ‘$’ are not documented and can change without notice.

Finally, be aware that the WASM version is limited. 32 bits, no threads and a lot of missing libraries.

1 Like

Thanks, that should point me in the right direction.

And yes, those limitations of the WASM version are certainly something to weigh up in the end (thanks for reminding me about them).