处理序言上下文无关语法

发布于 2024-12-19 00:57:36 字数 438 浏览 1 评论 0原文

给定一个 CFG,

S --> a S b | c | d

生成所有可能的谓词

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

我想编写一个谓词,例如 grammar('S', Sentence) ,如果遇到的符号是 终结符,则使用最左推导 它应该打印出该终端,如果遇到的符号是非终端 'S',它应该回溯并替换语法之一 a S b 或 c 或 d 并重复 过程。

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

Given a CFG

S --> a S b | c | d

I wanna write a predicate like, grammar('S', sentence) which generates all possible

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

Using left most derivation, if the encountered symbol is terminal it should print out that terminal, and if the encountered symbol is non terminal 'S', it should backtrack and substitute and one of the grammar a S b or c or d and repeat the process.

I dont want any code...just help me with some tips how to start with

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

ぺ禁宫浮华殁 2024-12-26 00:57:36

让我们使用 DCG 按字面意思对语法进行编码!

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

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

看来这个查询不会终止。即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]:请参阅此答案以获取解释并到 库(double_quotes)

Let's use DCGs to encode your grammar literally!

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

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

Seems that this query does not terminate. I.e. Prolog's very simple execution strategy did not find a solution. On the other hand, think of it: Your grammar describes an infinite set of sentences. If you are enumerating an infinite set it is easy to start "at the wrong end". That's what Prolog actually does here.

But things are not that bad at all. What about enumerating all sentences of a fixed length. I will try 5:

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

In this case, all sentences are found and Prolog even assures us that there are no further sentences.

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

There are no sentences of length 4.

We can now enumerate all sentences, by length.

?- 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
; ... .

What kind of derivation did we use here? Honestly, I don't know and I don't care. What is important to know is when Prolog will terminate. In this case, it will terminate, if the length is known. And that is all we need to know to guarantee that we have a fair enumeration of the infinite set. Things are even slightly better: s//0 will also terminate in cases where the length is not known like

?- 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.

Edit: I got some questions about the toplevel answers using "acb" for a list [a,c,b]: Please refer to this answer for an explanation and to library(double_quotes).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文