Skip to content

定理Theorem

CFG–PDA 等价定理

CFG–PDA equivalence

上下文无关文法与非确定性下推自动机刻画同一语言类;三元变量描述受保护的弹栈段,完整八变量例子及双向归纳将运行转换为推导。

形式陈述 ​

CFG–PDA 等价定理断言:语言 L 能由某个上下文无关文法生成,当且仅当存在非确定性下推自动机接受 L。等价的是语言表达能力,不是推导树、运行次数或表示大小。下面给出双向构造的核心。

从 CFG 到 PDA,可把开始符号压栈;栈顶为非终结符 A 时,机器用 ε 转移非确定选择产生式 A→α,以 α 替换 A;栈顶为终结符 a 时,只有下一输入也是 a 才读取并弹出。输入与栈同时耗尽时接受。

三元变量与全部规则 ​

反向构造固定按空栈接受的 NPDA P,初态 q0、初始栈符号 Z0。接受要求输入读完且栈为空,终点控制状态不限。沿用 PDA 页的模型:一步检查并替换一个栈顶符号,空栈后没有可执行动作;栈顶在左。

为每个 u,v∈Q 和 X∈Γ 引入变量 [uXv],它要满足

[uXv]⇒∗w⟺(u,w,X)⊢∗(v,ε,ε).

将任意输入后缀 z 与栈后缀 β 补回,右侧等价于一段从 (u,wz,Xβ) 到 (v,z,β) 的运行,其中终点是首次露出指定原后缀 β的时刻。此前栈均为 ηβ、η≠ε,且没有检查或改写 β 中的符号。这不是允许中途弹入 β、后来再把同样字符压回去的任意运行。

先考虑每步替换串长度至多二的机器。若 (r,α)∈δ(u,a,X),a∈Σ∪{ε},加入以下规则:

动作的替换串 α 文法规则 需要枚举的状态
ε [uXr]→a 只有动作实际到达的 r
Y [uXv]→a[rYv] 所有 v∈Q
YZ [uXv]→a[rYs][sZv] 所有 s,v∈Q

若 a=ε,右侧不写出终结符前缀。最后加新开始符号 S,对每个 v∈Q 加入 S→[q0Z0v]。这就是完整构造;没有另加“猜到正确状态就接受”的规则。

长度二的规则先完成去掉 Y 的子任务,在中间状态 s 首次露出 Z,再完成去掉 Z 的子任务。一般替换 α=Y1⋯Yk 也可直接使用

[uXvk]→a[rY1v1][v1Y2v2]⋯[vk−1Ykvk],

遍历全部 v1,…,vk。因此长度二规范化不是定理成立的必要条件,只是让规则与证明更易展开。下面给出一个完全列出的规范例子,随后证明变量语义的两个方向。

对 NPDA,按终态接受与按空栈接受可经新初态、受保护的底标记与清栈阶段转换。构造保证语言相同,通常会增加状态或文法变量,不保证运行条数、歧义或表示大小不变,也不保证保持确定性。

直觉

文法与 PDA 是同一种嵌套机制的生成、识别两面。文法推导把尚未展开的非终结符当作待办结构,PDA 栈也保存尚待匹配或展开的任务;产生式选择对应栈顶替换,终结符匹配对应消费输入。反向构造较复杂,是因为文法必须预先概括一段运行“从某状态压着某符号开始,到哪个状态恰好弹掉它”的所有可能。非确定性承担选择产生式或猜测分解的角色。

CFG–PDA 嵌套对应
例子与边界

对文法 S→aSb∣ε,PDA 初始栈为 S。选择第一条规则把栈顶替换为 aSb,随后匹配输入 a,递归处理 S,最后匹配 b;选择 ε 规则结束嵌套,因此接受恰好 anbn。按“剩余输入,栈顶在左的栈”记录,图中 aabb 的完整对应为

(aabb,S)⊢(aabb,aSb)⊢(abb,Sb)⊢(abb,aSbb)⊢(bb,Sbb)⊢(bb,bb)⊢(b,b)⊢(ε,ε).

展开规则不消费输入,匹配终结符才消费输入。实现替换 S↦aSb 时若逐个压入,就要依次压 b,S,a,使 a 留在栈顶。每一步均保持“已读前缀加上当前栈串,是文法能导出的句型”这一不变式;栈和输入同时为空,才得到完整推导。

边界是确定性:CFG 到 PDA 的直接构造会在一个非终结符有多条产生式时非确定选择,不能据此得到 DPDA。全部 CFL 都有 NPDA,但只有严格子类有确定 PDA;文法无歧义也不自动保证对应语言是确定性上下文无关的。

从六个动作列出全部八个变量 ​

现在从机器出发。取 Q={p,q}、Γ={Z,A}、初态 p、初始栈 Z,恰有以下六个动作:

当前状态 读取 栈顶 新状态 替换串
p a Z p AZ
p a A p AA
p b A q ε
q b A q ε
p ε Z q ε
q ε Z q ε

没有列出的动作均不存在。状态 p 可连续读 a 压入 A;首个 b 进入 q,以后只能读 b 弹栈。按空栈接受,输入仍须读完。尤其在初始时立即弹掉 Z 的分支只接受空字,不能在还有输入时凭空结束。

三元变量恰有 2⋅2⋅2=8 个。下表逐行列出全部右侧;同一行的“或”表示不同规则,无产生式不表示产生空字:

变量 全部产生式右侧
[pZp] a[pAp][pZp] 或 a[pAq][qZp]
[pZq] a[pAp][pZq] 或 a[pAq][qZq] 或 ε
[pAp] a[pAp][pAp] 或 a[pAq][qAp]
[pAq] a[pAp][pAq] 或 a[pAq][qAq] 或 b
[qZp] 无产生式
[qZq] ε
[qAp] 无产生式
[qAq] b

另有 S→[pZp] 与 S→[pZq],共十二条变量规则和两条开始规则。例如第一动作把 Z 换成 AZ,所以对两个中间状态、两个终点状态各生成一条规则,正好贡献表中前两行的四条带 a 规则。

在 aabb 上,机器接受运行是

(p,aabb,Z)⊢(p,abb,AZ)⊢(p,bb,AAZ)⊢(q,b,AZ)⊢(q,ε,Z)⊢(q,ε,ε).

完整文法中的最左推导与它对应:

S⇒[pZq]⇒a[pAq][qZq]⇒aa[pAq][qAq][qZq]⇒aab[qAq][qZq]⇒aabb[qZq]⇒aabb.

最后的 [qZq]→ε 对应真实的底符号弹出动作,不能删掉这一步而宣称栈已经空了。开始规则只选终点状态;其后五次展开才对应五个机器动作。

有规则不等于能产生终结字 ​

[qZp]、[qAp] 没有规则;[pAp] 的规则或者继续依赖自己,或者依赖 [qAp],没有有限推导的终结基例。因此这三个变量都不能生成终结字,[pZp] 也因依赖它们而不能生成。其余四个变量都有直接的终结右侧。

删去这四个不生成变量以及含它们的规则,保留下来的文法为

S→[pZq],[pZq]→a[pAq][qZq]∣ε,[pAq]→a[pAq][qAq]∣b,[qZq]→ε,[qAq]→b.

代入后两项并令 B=[pAq],可写成 S→aB∣ε、B→aBb∣b。B 每次递归同时增加一个 a 与一个 b,最后用 b 结束,故生成 akbk+1;S 恰好生成 anbn。这与前面的单变量文法等价,但不是说“删无用变量”一步便直接得到 S→aSb∣ε。

机器上也可独立核对:读过 an 后栈为 AnZ,每个 b 恰好去掉一个 A,且进入 q 后不能再读 a。短一个 b 会留栈,多一个 b 没有可用动作,交错输入也无法通过。两种描述得到相同语言,而不只是恰好都接受 aabb。

推论与应用

为什么三元变量与受保护栈段等价 ​

先证运行推出推导,对受保护栈段的动作数作强归纳。零个动作不能去掉顶部的 X,所以没有零步情形。设首动作读取 a,把 X 换成 α,并进入 r;a 可以为空。

若 α=ε,这一步已首次露出 β,由栈段定义运行必须就在此结束。因此终点是 r、所读字是 a,直接使用 [uXr]→a。

若 α=Y,首动作后剩余运行恰是去掉 Y 的较短受保护段。设它消费 x 并到达 v,归纳得到 [rYv]⇒∗x,再用 [uXv]→a[rYv]。

若 α=YZ,后续运行终将去掉这两个原栈位置。考虑首次露出未触动的 Zβ的时刻:设状态为 s,此前在首动作之后消费 x,此后消费 y。于是运行分成

(r,xyz,YZβ)⊢∗(s,yz,Zβ)⊢∗(v,z,β).

一栈顶动作不能越过尚未去掉的 Y 而直接修改原 Z,所以这个切点存在。两段分别去掉 Y、Z,都是比原段短的受保护段;归纳得到 [rYs]⇒∗x 和 [sZv]⇒∗y,再使用长度二规则,生成 axy。切点跟踪的是原有栈位置,不是碰巧出现相同字母的任意时刻。

反向证推导推出运行,对有限推导树作结构归纳。叶规则 [uXr]→a 本身就是一个真实弹栈动作。一子树规则先执行首动作,再把子树给出的运行放在 β 上;两子树规则先把 X 换成 YZ,把第一子树的运行放在后缀 Zβ 上,首次露出该后缀后,再把第二子树的运行放在 β 上。它们在规则写出的中间状态 s 接续,且终点之前不会触碰原 β。

这两个归纳证明所有变量的语义。取 β=z=ε,再由开始规则枚举终点,便有 L(G)=N(P)。证明不能简单改成按输入字长归纳:ε 动作可能让非空子运行消费零个符号,字长未必严格下降。

任意机器怎样进入这个规范接口 ​

若原机器按终态接受,加入新初态 i、清栈态 d 和新底标记 ⊥。新机器初始栈为 ⊥,先用 ε 动作替换为 Z0⊥ 并进入原 q0。原动作照旧,但它们不能匹配新增 ⊥。

从每个原终态 f,对每个 X∈Γ∪{⊥},允许 ε 弹出 X 并进入 d;d 再以 ε 动作逐个弹栈,没有读字符动作或返回旧状态的出口。只有这个阶段能弹掉新底标记。原来在非终态弹空旧栈不会误收;原来在终态且旧栈已空,也可以通过弹 ⊥ 接受。

原接受运行后接清栈,就得到新接受运行。反之,新接受运行必须从某个原终态进入清栈,而清栈不消费输入;既然最终输入读完,进入时便已读完,之前的模拟就是原接受运行。允许提前猜测进入清栈不会误收,因为剩余输入无法再被消费。这一证明没有假设机器能主动检测“输入已经结束”。

若某动作替换为 Y1⋯Yk、k≥3,可以为它增加专用控制状态 ck−1,…,c2,记 c1=r。第一步按原动作读取 a,把 X 换成 Yk−1Yk 并进入 ck−1;随后对 j=k−1,…,2,仅允许

(cj,ε,Yj)↦(cj−1,Yj−1Yj).

栈依次成为 Yk−1Ykβ,…,Y1⋯Ykβ,输入只在首步消费。新状态没有别的出口,中间也不会露出 β,所以整个链恰好模拟一个旧动作。每步替换长度不超过二,无需凭空在空栈上压入符号。

若规范化后有 n 个状态、g 个栈符号和 t 个动作,三元变量数为 n2g,加上新开始符号;每个长度二动作产生 n2 条规则,长度一产生 n 条,弹栈动作只产生一条。这解释了为什么语言等价不意味着表示大小相近。

定理把上下文无关文法的生成视角与下推自动机的运行视角统一起来。可用文法闭包与范式证明语言性质,也可用栈机器设计识别算法。

编译原理中,语法规格被转换为带栈解析器;在理论上,该等价支撑 CFL 的成员判定、闭包分析和与确定 PDA子类的比较。

终点自测:从六动作表独立列出十四条规则,标出四个不能生成终结字的变量,写出 aabb 的运行及最左推导;再说明二符号替换的中间状态对应哪个首次弹栈边界,以及为何 ε 动作迫使证明采用运行步数而非输入长度。

参考资料
  • John E. Hopcroft, Rajeev Motwani, and Jeffrey D. Ullman, Introduction to Automata Theory, Languages, and Computation, 3rd ed., Pearson, 2006,Chs. 5–6, pushdown automata and context-free grammars。
  • Michael Sipser, Introduction to the Theory of Computation, 3rd ed., Cengage, 2013,Ch. 2, equivalence of pushdown automata and context-free grammars。
  • Old Dominion University CS390, Pushdown Automata, Fall 2024 course notes,§§2.1–2.2,双向构造。
  • Alfred V. Aho, Columbia COMS W3261, Lecture 9: CFG's and PDA's,§2 给出一般长度的三元变量构造与单栈符号运行命题,§3 讨论不生成与不可达变量。上面的八变量表、规范化链和双向栈段归纳按本页模型展开,不将讲义中未展开的归纳冒称为原文完整证明。
关系图谱12 个相邻概念 · 2 类关系

拖动节点调整位置。

显示关系

显示:依赖

  1. 前置三跳
  2. 前置二跳
  3. 前置一跳
  4. 当前条目
  5. 后续一跳
  6. 后续二跳
  7. 后续三跳
文字版关系按与当前条目的最短距离分组
类型化关系