After several hours of trying to get wss:// and nginx to play nicely, I’ve conceded defeat and got JavaScript in the browser and SWI Prolog server to communicate via JSON like so:
:- use_module(library(http/http_server)).
:- use_module(library(http/http_files)).
:- use_module(library(http/http_unix_daemon)).
:- initialization http_daemon.
:- http_handler(root(.), http_reply_from_files('.', [indexes(['./index.html'])]), [prefix]).
:- http_handler(root(prolog), prolog_handler, []).
prolog_handler(Request) :-
http_read_json_dict(Request, DictIn),
request_handler(DictIn.request, DictIn, DictOut),
reply_json_dict(DictOut).
request_handler("ping", _Dict, json{reply: pong}).
Browser code:
function prologServer(Request) {
return fetch("prolog",
{ method: "POST"
, headers: { "Content-Type": "application/json"}
, body: JSON.stringify(Request)
}
);
}
prologServer({"request": "ping"})
.then(response => response.json())
.then(data => document.querySelector("#message").innerText = data.reply);
The next interesting question is how to format the Json values so that Prolog and Javascript can use it as a lingua franca.
Using the introductory example from Bratko as an example by initial thought is if the Prolog looks like:
parent(pam, bob).
parent(tom, bob).
parent(tom, liz).
parent(bob, pat).
parent(pat, jim).
Then the Json should be
[ ["parent", "pam", "bob"],
["parent", "tom", "bob"],
["parent", "tom", "liz"],
["parent", "bob", "pat"],
["parent", "pat", "jim"]
]
which the Prolog script could then iteratively translate with term_string (?Term, ?String) and then Term =.. List
to translate, and then do the reverse in the reply to the browser.
Though not difficult, I wondered if there’s already a convention and libraries to do this?