Reputation: 55
I'm fairly new to Tau-Prolog and Javascript. At the beginning I would like to show some results computed by the Tau-Prolog engine in a Browser.
So far, all I want to show is some information contained in my Prolog-database:
All robots in the database and the interface to connect with a gripper/sensor etc.
All grippers/sensors in the database and the interface to connect to the robot.
The prolog-output would be something like: "Robot A fits with Gripper C (Same interface Z)." I've programmed this in SWI-Prolog and it works fine so far.
Now I would like to show the results in a HTML-Element:
<div class="example-result" id="show_result1"></div>
This is what I've come up so far:
function queryRG() {
var session = pl.create(1000);
var parsed = session.consult("code.pl");
//if (parsed !== true) { console.log(pl.format_answer(parsed)) }
var query1 = session.query("queryRG.");
var callback = function(answer){
var result1 = document.getElementById("show_result1");
console.log( pl.format_answer( answer ));
if (pl.type.is_substitution(answer)){
var ab = answer.toString();
result.innerHTML = result.innerHTML + ab;
}
}
session.answer(callback);
}
I can see all the (correct) results in the console, but I fail to make them visible on the website. Thanks for your help!
Edited:
After the the help of @CapelliC i came up with this version now. Still I have the problem that the expected result show up in the Console, but not on the site:
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Playground</title>
</head>
<body>
<script type="text/javascript" src="tau-prolog.js"></script>
<h1>Playground4</h1>
<script>
function queryRG() {
var session = pl.create(1000)
var code_pl = `
robot('Robot1','A', 1, 550).
robot('Robot2','C', 2, 340).
robot('Robot3','A', 2, 200).
robot('Robot4','B', 3, 260).
gripper('Gripper1', 'B', 50).
gripper('Gripper2', 'A', 60).
gripper('Gripper3', 'C', 30).
gripper('Gripper4', 'C', 80).
gripper('Gripper5', 'A', 20).
gripper('Gripper6', 'B', 30).
gripper('Gripper7', 'C', 90).
query_robots :-robot(Name,Interface,Size,Price), write('The database contains: '),write(Name), write(', with Interface: '), write(Interface), write(', Size: '), write(Size) , write(', Price: '), write(Price), nl, fail.
`
var parsed = session.consult(code_pl)
var query = session.query('query_robots.')
function inform(msg) {
show_result1.innerHTML += '<div>' + msg + '</div>'
}
var count_answers = 0
var callback = function(answer) {
if (answer === false) {
inform('DONE, #answers='+count_answers)
return
}
if (answer === null) {
inform('TIMEOUT, #answers='+count_answers)
return
}
// loop
++count_answers
inform(pl.format_answer(answer))
session.answer(callback)
}
// start the query loop
session.answer(callback)
}
</script>
<div id=show_result1>
<h3>results show here...</h3>
</div>
<button onclick="queryRG()">Click to run</button>
</body>
</html>
Upvotes: 3
Views: 539
Reputation: 60034
Just an example of handling multiple result, I crafted it creating a page 'tau-prolog.html' in the same folder where had downloaded 'tau-prolog.js', and opened locally in my browser. Then using the developer tools (console, debugger) had a look at inner workings of Tau Prolog.
Beware of details, like
session
remain in scope among calls.<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>test tau-prolog</title>
<script src=tau-prolog.js></script>
</head>
<body>
<script>
function queryRG() {
var session = pl.create(1000)
var code_pl = `
:- use_module(library(lists)).
fruit(apple).
fruit(pear).
fruit(banana).
fruits_in(Xs, X) :- member(X, Xs), fruit(X).
`
var parsed = session.consult(code_pl)
var query = session.query('fruits_in([banana,lemon,apple],X).')
function inform(msg) {
show_result1.innerHTML += '<div>' + msg + '</div>'
}
var count_answers = 0
var callback = function(answer) {
if (answer === false) {
inform('DONE, #answers='+count_answers)
return
}
if (answer === null) {
inform('TIMEOUT, #answers='+count_answers)
return
}
// loop
++count_answers
inform(pl.format_answer(answer))
session.answer(callback)
}
// start the query loop
session.answer(callback)
}
</script>
<div id=show_result1>
<h3>results show here...</h3>
</div>
<button onclick="queryRG()">Click to run</button>
</body>
</html>
The result of click on [Click to run] is as expected:
results show here...
X = banana ;
X = apple ;
DONE, #answers=2
HTH
edit
Your query is really a 'failure driven loop', typically used only for its 'side effects', since it undoes variables bindings at failure point.
The problem becomes that, apparently, they didn't documented how to properly change IO handlers. At least, I haven't found anything useful. A quick hack then: rebind the put function, adding this line immediately after function inform(msg){...}
session.current_output.stream.put = inform
Now, it's clear that inform(msg)
should be rethinked, because it doesn't understand plain text streaming. Maybe you could change inform(msg){} to output a <span>msg</msg>
instead of a <div>
, inspect for \n and call flush on that, and then bind a flush handler (currently undefined) that group <span>
s in a <div>
.
Note: inspecting the code, it's rather clear that IO streams are not the main priority of Tau-Prolog. Indeed, at line 1670 of tau-prolog.js have found this typo:
return new Stram( this.stream, this.mode, this.alias, this.type, this.reposition, this.eof_action );
Clearly, Stram
should be Stream
.
edit
A better idea to get readable output without handling flush()
: simplify
function inform(msg){
show_result1.innerHTML += msg
}
and change the markup:
<h3>results show here...</h3>
<pre id=show_result1>
</pre>
Upvotes: 2