3

我对 Tau-Prolog 和 Javascript 还很陌生。一开始我想在浏览器中展示一些由 Tau-Prolog 引擎计算的结果。

到目前为止,我只想展示我的 Prolog 数据库中包含的一些信息:

  • 数据库中的所有机器人以及与夹具/传感器等连接的接口。

  • 数据库中的所有夹具/传感器以及连接到机器人的接口。

序言输出将类似于:“机器人 A 适合夹爪 C(相同的接口 Z)。” 我已经在 SWI-Prolog 中对此进行了编程,到目前为止它运行良好。

现在我想在 HTML 元素中显示结果:

<div class="example-result" id="show_result1"></div>

这是我到目前为止提出的:

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);
}

我可以在控制台中看到所有(正确的)结果,但我无法让它们在网站上可见。谢谢你的帮助!

编辑:

在@CapelliC 的帮助下,我现在想出了这个版本。我仍然有预期结果显示在控制台中的问题,但没有出现在网站上:

<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>
4

1 回答 1

2

只是一个处理多个结果的例子,我制作了它在下载了“tau-prolog.js”的同一个文件夹中创建了一个页面“tau-prolog.html”,并在我的浏览器中本地打开。然后使用开发人员工具(控制台、调试器)查看了 Tau Prolog 的内部工作原理。

注意细节,比如

  • 你如何加载 Prolog 文件?在我的示例中,我选择了更简单的方法,将“程序”传递给字符串
  • 你如何开始与口译员的互动?在我的示例中,我选择了一个按钮,以及最基本的处理程序 onclick="..."循环提取所有答案。显然并不适合所有场景,但它说明了 Javascript 允许的特殊递归。特别注意,变量 session在调用之间保持在范围内。
  • 当你得到答案时,只有回调才能决定是循环还是退出......
<!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>

点击【点击运行】的结果如预期:

results show here...
X = banana ;
X = apple ;
DONE, #answers=2

高温高压

编辑 您的查询实际上是一个“故障驱动循环”,通常仅用于其“副作用”,因为它会在故障点撤消变量绑定。问题变成了,显然,他们没有记录如何正确更改 IO 处理程序。至少,我没有发现任何有用的东西。然后快速破解:重新绑定 put 函数,在之后立即添加此行function inform(msg){...}

      session.current_output.stream.put = inform

现在,很明显inform(msg)应该重新考虑,因为它不理解纯文本流。也许您可以将 inform(msg){} 更改为输出 a<span>msg</msg>而不是 a <div>,检查 \n 并在其上调用 flush ,然后在 a 中绑定该组<span>s的刷新处理程序(当前未定义) <div>

注意:检查代码,很明显 IO 流不是 Tau-Prolog 的主要优先级。事实上,在 tau-prolog.js 的第 1670 行发现了这个错字:

        return new Stram( this.stream, this.mode, this.alias, this.type, this.reposition, this.eof_action );

显然,Stram应该是Stream

编辑

无需处理即可获得可读输出的更好主意flush():简化

    function inform(msg){
       show_result1.innerHTML += msg
    }

并更改标记:

    <h3>results show here...</h3>
    <pre id=show_result1>
    </pre>
于 2020-03-29T11:08:54.083 回答