【问题标题】:Handling prolog context free grammar处理 prolog 上下文无关语法
【发布时间】:2012-01-10 01:15:18
【问题描述】:

给定一个 CFG

S --> a S b | c | d

我想写一个谓词,如 grammar('S', sentence) 生成所有可能的

sentences like
sentence=acb,
sentence=acd,
sentence=c,
sentence=ab......................

使用最左推导,如果遇到的符号是终端,它应该打印出那个终端,如果遇到的符号是非终端 'S',它应该回溯并替换语法a S b or c or d之一并重复该过程。

我不想要任何代码...只是帮助我一些提示如何开始

【问题讨论】:

  • SO 不是“为我编写代码”网站。
  • 你不必“写代码”你可以给他一些指点
  • @mah 我不希望有任何代码......但是一些提示或任何带有一些好的示例的链接

标签: prolog context-free-grammar dcg prolog-dif


【解决方案1】:

让我们使用 DCG 对您的语法进行逐字编码!

s --> [a], s, [b] | [c] | [d].

?- phrase(s,Xs).
ERROR: Out of local stack

这个查询似乎没有终止。 IE。 Prolog 非常简单的执行策略没有找到解决方案。另一方面,想一想:你的语法描述了无限的句子集。如果您要枚举一个无限集,则很容易“从错误的一端”开始。这就是 Prolog 在这里实际所做的。

但事情并没有那么糟糕。枚举所有固定长度的句子怎么样。我会尝试5:

?- length(Xs,5), phrase(s,Xs).
Xs = "aacbb" ;
Xs = "aadbb" ;
false.

在这种情况下,所有句子都找到了,Prolog 甚至向我们保证没有其他句子。

?- length(Xs,4), phrase(s,Xs).
false.

没有长度为 4 的句子。

我们现在可以枚举所有个句子,按长度

?- length(Xs,N), phrase(s,Xs).
Xs = "c",
N = 1 ;
Xs = "d",
N = 1 ;
Xs = "acb",
N = 3 ;
Xs = "adb",
N = 3 ;
Xs = "aacbb",
N = 5 ;
Xs = "aadbb",
N = 5 ;
Xs = "aaacbbb",
N = 7

我们在这里使用了什么样的推导?老实说,我不知道,我也不在乎。重要的是要知道 Prolog 何时终止。在这种情况下,如果长度已知,它将终止。这就是我们需要知道的所有信息,以保证我们有一个无限集的公平枚举。情况稍微好一点:s//0 也会在长度未知的情况下终止,例如

?- Xs = [a,a,b|_], phrase(s,Xs).
false.

?- Xs = [a,a,c|_], phrase(s,Xs).
Xs = "aacbb" ;
false.

?- dif(X,Y), Xs = [X,Y|_], phrase(s,Xs).
X = a,
Y = c,
Xs = "acb" ;
X = a,
Y = d,
Xs = "adb" ;
false.

编辑:我有一些关于使用"acb" 列表[a,c,b] 的顶级答案的问题:请参阅this answer 以获得解释和library(double_quotes)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-01-04
    • 2014-04-26
    • 2013-02-23
    • 2012-06-19
    • 2014-09-08
    • 1970-01-01
    相关资源
    最近更新 更多