Prolog 解析树生成失败

标签 prolog dcg

我有以下序言规则。

b(b(true)) --> [true].
b(b(false)) --> [false].
b(b(E,[=],E)) --> e(E),[=],e(E).
b(b([not],B)) --> [not],b(B).
e(e(I)) --> i(I).
e(e(N)) --> n(N).
e(e(N,O,E)) --> n(N),o(O),e(E).
e(e(I,O,E)) --> i(I),o(O),e(E).
o(o(+)) --> [+].
o(o(-))--> [-].
o(o(*))--> [*].
o(o(/)) --> [/].
i(i(x)) --> [x].
i(i(y)) --> [y].
i(i(z)) --> [z].
i(i(u)) --> [u].
i(i(v)) --> [v].
n(n(0)) --> [0].
n(n(1)) --> [1].
n(n(2)) --> [2].
n(n(3)) --> [3].
n(n(4)) --> [4].
n(n(5)) --> [5].
n(n(6)) --> [6].
n(n(7)) --> [7].
n(n(8)) --> [8].
n(n(9)) --> [9].

但我不知道为什么

[6] 26 ?- b(A,[x,=,4],[]).
false

失败。我尝试调试代码。 4 未与 n(n(4)) 匹配。我不明白问题出在哪里。

最佳答案

(如果您使用 标签,您会更早收到答案)

那么,我们如何定位错误呢?让我们从您的查询开始:

?- phrase(b(A),[x,=,4]).
   false.

糟糕!
我真的应该启动跟踪/调试器吗?
您当前要问的是:对于一个结构良好的句子,A 的解决方案是什么。
唉,没有。

我们不能问 Prolog 一个更一般的问题吗?
那么,亲爱的 Prolog - 至少 - 你知道任何句子吗?
请说一句话!

?- phrase(b(A),L).
   A = b(true), L = [true]
;  A = b(false), L = [false]
;  ... .

所以有一些东西 - 我将删除 A,因为我们想首先看到句子。

?- phrase(b(_),L).
   L = [true]
;  L = [false]
;  L = [x,=,x]
;  L = [y,=,y]
;  L = [z,=,z]
;  L = [u,=,u]
;  L = [v,=,v]
;  L = [0,=,0]
;  L = [1,=,1]
;  L = [2,=,2]
;  L = [3,=,3]
;  L = [4,=,4]
;  L = [5,=,5]
;  L = [6,=,6]
;  L = [7,=,7]
;  L = [8,=,8]
;  L = [9,=,9]
;  L = [0,+,x,=,0,+,x]
;  ... .

你在这里看到某种模式了吗?
也许我们可以改进这个。
你知道哪些长度为 3 的句子?

?- L = [_,_,_], phrase(b(_),L).
  L = [x,=,x]
;  L = [y,=,y]
;  L = [z,=,z]
;  L = [u,=,u]
;  L = [v,=,v]
;  L = [0,=,0]
;  L = [1,=,1]
;  L = [2,=,2]
;  L = [3,=,3]
;  L = [4,=,4]
;  L = [5,=,5]
;  L = [6,=,6]
;  L = [7,=,7]
;  L = [8,=,8]
;  L = [9,=,9]
;  L = [not,not,true]
;  L = [not,not,false]
;  false.

换句话说:除了这些之外,没有其他三个单词的句子。
现在,你明白了吗?
带有 = 的句子有一个规则:

b(b(E,[=],E)) -->
   e(E),[=],e(E).

它要求左侧的表达式与右侧的表达式相同。因此只有上面的那些句子。


调试 Prolog 程序时,与其他语言相比,(在键盘上)键入测试数据的需要要少得多。相反,使用变量让 Prolog 填充变量。毕竟,Prolog 在这方面比我们快得多;并且它不会遭受 CTS。

关于Prolog 解析树生成失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13097079/

相关文章:

prolog - (\+)//1 的合法使用

algorithm - SWI Prolog 中的 Hangman 游戏

prolog - 我很好奇逻辑程序是否可以做代数

prolog - 更改工作目录 swi-Prolog

prolog - 给定谓词和列表的 Prolog 基础

list - 反向/回文的递归Prolog谓词

prolog - Prolog 中的 % 符号是什么意思?

parsing - 如何在Prolog中做解析器?

list - 识别 DCG 中的模式

prolog - 将整个文本文件读入 Prolog 变量