【问题标题】:Prolog: I keep getting errors when trying to compile a simple programProlog:尝试编译简单程序时不断出错
【发布时间】:2020-11-16 21:43:04
【问题描述】:

我正在尝试制作一个简单的语法解析器来检查特定句型是否有效。语法规则如下:

接线端:circleplus, circleor, 1, 0

非终结符:S; T

开始符号:S

制作规则:S --> S circleplus T | S 圆环 T | T, 和: T --> 0 | 1

sentence([]).
sentence([a, b, c|Tail]) :- checkHead(a), checkC(b), checkT(c), sentenceCheck(Tail).

sentenceCheck([]).
sentenceCheck([b, c|Tail]) :- checkC(b), checkT(c), sentenceCheck(Tail).


checkT(c) :- T(c).
checkC(b) :- C(b).
checkHead(a) :- Head(a).

C(circleor).
C(circleplus).
Head(0).
Head(1).
T(0).
T (1).



% ?- sentence ([[0 , circleor ,1] , circleplus ,1]) .
%       ==> true


底部的 cmets 是示例输入 --> 输出的样子。 感谢任何帮助。

编辑:(根据我的问题的回答)

sentence([]).
sentence([A, B, C|Tail]) :- checkHead(A), checkC(B), checkT(C), sentenceCheck(Tail).

sentenceCheck([]).
sentenceCheck([B, C|Tail]) :- checkC(B), checkT(C), sentenceCheck(Tail).


checkT(C) :- t(C).
checkC(B) :- c(B).
checkHead(A) :- head(A).

c(circleor).
c(circleplus).
head(0).
head(1).
t(0).
t(1).

现在查询 sentence([0, circleor, 1]). 返回 false,而它应该是 true。有什么想法吗?

【问题讨论】:

  • 正如我回答的那样,您已经编辑了您的问题。我应该编辑我的答案还是就足够了?
  • 这就够了,我会把它改成你所拥有的,因为它更干净,更符合 Prolog 的规则:)

标签: prolog dcg


【解决方案1】:

在 prolog 中,变量以大写字母开头,常量项以小写字母开头。您收到错误是因为 prolog 期望谓词是常数项而不是变量。

sentence([]).
sentence([A, B, C|Tail]) :- checkHead(A), checkC(B), checkT(C), sentenceCheck(Tail).

sentenceCheck([]).
sentenceCheck([B, C|Tail]) :- checkC(B), checkT(C), sentenceCheck(Tail).


checkT(C) :- t(C).
checkC(B) :- c(B).
checkHead(A) :- head(A).

c(circleor).
c(circleplus).
head(0).
head(1).
t(0).
t(1).

上述更改将有所帮助,但您的示例输入、输出在您嵌套列表时将不起作用。如果您不按以下方式嵌套列表,它将起作用。

?- sentence([0, circleor, 1, circleplus, 1]).
true.

即使输入没有展平,解决方案是:

sentence(A) :- t(A).
sentence([A, B, C]) :-
    sentence(A),
    c(B),
    t(C).

c(circleor).
c(circleplus).
t(0).
t(1).

【讨论】:

  • 我不知道它们必须大写,而且我想我正在修复我的代码,而你正在响应,大声笑,所以我现在有点工作,但不幸的是它不适用于嵌套列表,不幸的是我有点需要。我认为sentenceCheck(Tail) 可以解决这个问题,不是吗?
  • @ESM : 再给我一些你需要它如何工作的示例。
  • sentence ([]) = 真,sentence ([[0 , circleor ,1] , circleplus ,1]) . = 真,sentence ([[[0 , circleplus ,0] , circleor ,1] , circleplus ,1]) . = 真,sentence ([[[0 , circleplus ,0] , circleor ,[1 , circleor ,0]] , circleplus ,1]) . = 假
  • @ESM :您的代码只检查双重嵌套。它不适用于任何更深的人。你需要一个更通用的递归解析器。
  • sentenceCheck([]).sentenceCheck([B, C|Tail]) :- checkC(B), checkT(C), sentenceCheck(Tail). 行不负责递归吗?因为它一直在调用自己直到它为空?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-09-11
  • 1970-01-01
  • 1970-01-01
  • 2012-03-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多