文章目录
前瞻
在上下文无关文法与下推自动机章节,有一些知识点着重掌握:
- 上下文无关文法的定义,以及语法分析树
- 语言文法的推导,如何化繁为简,拆分文法
- 乔姆斯基范式的改写
- 泵引理,以及区分证明是上下文无关(构造法)与证明不是上下文无关(反证法)的思路
- 语言封闭性,上下文无关语言对交运算不封闭,该证明是用特例证的;而在交、链接、星运算下是封闭的,使用构造法证明;补的封闭性证明,以及正则与上下文无关之间的封闭性证明,不做要求。
上下文无关文法
在正则语言章节,我们首先学习了有穷状态机,然后学习的正则表达式;这是因为有穷状态机较正则表达式更加直观。
而对于上下文无关语言,使用上下文无关文法表述相对更加简洁和易懂(四元组),而下推自动机会显得更复杂些。
因此,本章将遵循黑书的逻辑,从上下文无关文法入手。
如果一个语言能够被上下文无关文法(context-free grammar, CFG)接受,则称该语言为上下文无关语言(context-free language, CFL),对应下推自动机(pushdown automaton, PDA)。
上下文无关文法的形式化定义为一个4元组: ( V , Σ , R , S ) (V, \Sigma, R, S) (V,Σ,R,S),分别为:
- 有穷的变元(variable)集合 V V V;
- 与 V V V不相交的符号集 Σ \Sigma Σ,称终结符集(terminals);
- 有穷规则集(rules) R R R;
- 起始变元 S ∈ V S \in V S∈V。
上下文无关文法由多条替换规则(substitution rules)构成,每条规则包含箭头左侧的变元和右侧的替换串,例如
S → a S ∣ ϵ S \to aS|\epsilon S→aS∣ϵ
就是一条替换规则,其变元为 S S S,替换串为 a S ∣ ϵ aS|\epsilon aS∣ϵ, a ∣ ϵ a|\epsilon a∣ϵ为终结符,该规则代表的语言为 { a n ∣ n ≥ 0 } \{a^n|n\ge 0\} {an∣n≥0}。从上面这条规则也可以看出,上下文无关语言允许正则化的定义,这使得语言拥有更高的表示能力。
使用上下文无关文法派生字符串的过程称为语法分析(parse),可用语法分析树(parse tree)表示,后文简称语法树。例如,对下面的语言:
A
→
0
A
1
A
→
B
B
→
#
A \to 0A1\\ A \to B\\ B \to \#
A→0A1A→BB→#
其派生字符串
000
#
111
000\#111
000#111的过程可以表示为:
CFG的设计
设计上下文无关文法,可以参考以下思路:
- 化繁为简,利用封闭运算(并补星)进行构造
- 利用正则,先构造DFA,然后将这个DFA转换为CFG
- 考量子串
- 利用递归
例题
例1:构造 { 0 , 1 } ∗ \{0, 1\}^* {0,1}∗
解: A → ε ∣ 0 A ∣ 1 A A \to \varepsilon | 0A | 1A A→ε∣0A∣1A
例2:构造 { w ∣ w 至少包含 3 个 1 , Σ = { 0 , 1 } } \{w|w至少包含3个1, \Sigma = \{0, 1\}\} {w∣w至少包含3个1,Σ={0,1}}
解:
3个1有4个空位可以填任意数量0,1, { 0 , 1 } ∗ \{0, 1\}^* {0,1}∗填进去就行
A → B 1 B 1 B 1 B B → ε ∣ 0 B ∣ 1 B A \to B1B1B1B\\ B \to \varepsilon|0B|1B A→B1B1B1BB→ε∣0B∣1B
例3:构造 { w ∣ w 长度为奇数 , 正中间为 0 , Σ = { 0 , 1 } } \{w|w长度为奇数,正中间为0,\Sigma = \{0,1\}\} {w∣w长度为奇数,正中间为0,Σ={0,1}}
解:
先构造最简单的情况—— 0 0 0,然后两边递归补等长字符。
A → B ∣ 0 A 0 ∣ 0 A 1 ∣ 1 A 0 ∣ 1 A 1 B → 0 A \to B|0A0|0A1|1A0|1A1\\ B \to 0\\ A→B∣0A0∣0A1∣1A0∣1A1B→0
例4:构造 { w ∣ w 中 1 比 0 多 } \{w|w中1比0多\} {w∣w中1比0多}
解:
先构造0和1一样多,然后构造多1
A → 1 B ∣ 1 A ∣ A B ∣ B A B → ε ∣ 01 B ∣ 10 B ∣ 0 B 1 ∣ 1 B 0 A \to 1B|1A|AB|BA\\ B \to \varepsilon|01B|10B|0B1|1B0 A→1B∣1A∣AB∣BAB→ε∣01B∣10B∣0B1∣1B0
例5:构造 { w ∣ w = w R } \{w|w = w^\mathcal R\} {w∣w=wR},即回文
解
A
→
ε
∣
0
A
0
∣
1
A
1
A \to \varepsilon|0A0|1A1
A→ε∣0A0∣1A1
乔姆斯基范式
通过乔式派生长度为n的串,应该刚好需要2n - 1步,可据此进行穷举,判断可识别性。
乔式给出了上下文无关文法的简化表示,乔式的基本形式包含两类规则:
A
→
B
C
A
→
a
A\to BC\\ A\to a
A→BCA→a
分别代表一个变元到两个变元的变换,以及一个变元映射到一个终结符的变换;只有起始变元可以存在规则
S
→
ϵ
S\to \epsilon
S→ϵ,且起始变元只能出现在左侧。
转换过程:
-
添加起始变元 S 0 → S S_0 \to S S0→S
-
剔除 ϵ \epsilon ϵ,例如 B → 00 ∣ ϵ B \to 00|\epsilon B→00∣ϵ
-
B 如果不取空,则不做处理
-
B 取空,则在任何右侧存在B的规则的字符串中,加入B取空后的字符串
例如 A → B A B ∣ B A \to BAB|B A→BAB∣B,要变为 A → B A B ∣ B ∣ B A ∣ A B ∣ A ∣ ϵ A \to BAB|B|BA|AB|A|\epsilon A→BAB∣B∣BA∣AB∣A∣ϵ
-
-
剔除单一的变元映射,例如 A → B A\to B A→B,并将右侧的变元对应的字符串补到左侧变元字符串中
例如 A → B A B ∣ B ∣ B A ∣ A B ∣ A ∣ ϵ , B → b A \to BAB|B|BA|AB|A|\epsilon, B \to b A→BAB∣B∣BA∣AB∣A∣ϵ,B→b,要变为 A → B A B ∣ B A ∣ A B ∣ ϵ ∣ b , B → b A \to BAB|BA|AB|\epsilon|b, B \to b A→BAB∣BA∣AB∣ϵ∣b,B→b.
-
整理终结符映射,例如补充 U → u U \to u U→u
-
拆分子串大于2的变换,例如 A → B A B A \to BAB A→BAB
要变为 A → C B , C → B A A \to CB, C\to BA A→CB,C→BA
2n-1定理证明
已知,乔式每步只会进行两种可能的变换
A
→
B
C
−
(
1
)
A
→
a
−
(
2
)
\begin{array}{l} A\to BC & - (1)\\ A\to a & - (2) \end{array}
A→BCA→a−(1)−(2)
一个长度为
n
n
n的派生串,包含
n
n
n个终止符,需要经历
n
n
n步
(
2
)
(2)
(2),和
n
−
1
n-1
n−1步
(
1
)
(1)
(1)。终止符变换很好理解,另一种可以使用归纳法进行推导。
设串长
n
对应的变换,证明:使用乔姆斯基范式进行派生,包含
n
−
1
步
(
1
)
式。
1.
n
=
1
时,显然成立
2.
n
=
2
时,需要经过
1
次形如
A
→
B
C
的变换,成立
3.
设
n
=
k
时,需要
k
−
1
次变换成立
4.
当
n
=
k
+
1
时,由于增加了一个终止,则必定在某处,存在一个新增的形如
A
→
B
C
的变换,
使得语法树可以多一个叶子,此时需要
k
=
(
k
+
1
)
−
1
次变换,成立
\begin{array}{l} 设串长n对应的变换,证明:使用乔姆斯基范式进行派生,包含n - 1步(1)式。\\ \begin{array}{ll} 1.&n = 1时,显然成立\\ 2.&n = 2时,需要经过1次形如 A \to BC的变换,成立\\ 3.&设n = k时,需要k - 1次变换成立\\ 4.&当n = k + 1时,由于增加了一个终止,则必定在某处,存在一个新增的形如 A \to BC的变换,\\ &使得语法树可以多一个叶子,此时需要k = (k + 1) - 1次变换,成立 \end{array} \end{array}
设串长n对应的变换,证明:使用乔姆斯基范式进行派生,包含n−1步(1)式。1.2.3.4.n=1时,显然成立n=2时,需要经过1次形如A→BC的变换,成立设n=k时,需要k−1次变换成立当n=k+1时,由于增加了一个终止,则必定在某处,存在一个新增的形如A→BC的变换,使得语法树可以多一个叶子,此时需要k=(k+1)−1次变换,成立
综上,可知如果一个CFG为乔姆斯基范式,则其派生长度为
n
n
n的串,需要经过
2
n
−
1
2n - 1
2n−1步
这个定理在可判定性章节还会用到,用于证明CFG的派生可判定性 A C F G = { ( G , w ) ∣ G 为 C F G , w 可被 G 派生 } A_{CFG} = \{(G, w)|G为CFG, w可被G派生\} ACFG={(G,w)∣G为CFG,w可被G派生}
例题
例题:转换下面的上下文无关文法到乔姆斯基范式。
S
→
A
S
A
∣
a
B
A
→
B
∣
S
B
→
b
∣
ϵ
S \to ASA|aB\\ A \to B|S\\ B \to b|\epsilon
S→ASA∣aBA→B∣SB→b∣ϵ
解:
-
添加起始变元
S 0 → S S → A S A ∣ a B A → B ∣ S B → b ∣ ϵ S_0 \to S\\ S \to ASA|aB\\ A \to B|S\\ B \to b|\epsilon S0→SS→ASA∣aBA→B∣SB→b∣ϵ -
剔除 ϵ \epsilon ϵ,首先剔除B中的
S 0 → S S → A S A ∣ a B ∣ a A → B ∣ S ∣ ϵ B → b S_0 \to S\\ S \to ASA|aB|a\\ A \to B|S|\epsilon\\ B \to b S0→SS→ASA∣aB∣aA→B∣S∣ϵB→b
然后剔除A中的
S 0 → S S → A S A ∣ a B ∣ a ∣ A S ∣ S A ∣ S A → B ∣ S B → b S_0 \to S\\ S \to ASA|aB|a|AS|SA|S\\ A \to B|S\\ B \to b S0→SS→ASA∣aB∣a∣AS∣SA∣SA→B∣SB→b -
剔除单射,剔除 A → B A \to B A→B
S 0 → S S → A S A ∣ a B ∣ a ∣ A S ∣ S A ∣ S A → S ∣ b B → b S_0 \to S\\ S \to ASA|aB|a|AS|SA|S\\ A \to S|b\\ B \to b S0→SS→ASA∣aB∣a∣AS∣SA∣SA→S∣bB→b
S → S , S 0 → S , A → S S \to S, S_0 \to S, A \to S S→S,S0→S,A→S
S 0 → A S A ∣ a B ∣ a ∣ A S ∣ S A S → A S A ∣ a B ∣ a ∣ A S ∣ S A A → b ∣ A S A ∣ a B ∣ a ∣ A S ∣ S A B → b S_0 \to ASA|aB|a|AS|SA\\ S \to ASA|aB|a|AS|SA\\ A \to b|ASA|aB|a|AS|SA\\ B \to b S0→ASA∣aB∣a∣AS∣SAS→ASA∣aB∣a∣AS∣SAA→b∣ASA∣aB∣a∣AS∣SAB→b -
整理终结符,注意不要引入新的单射
S 0 → A S A ∣ U B ∣ a ∣ A S ∣ S A S → A S A ∣ U B ∣ a ∣ A S ∣ S A A → b ∣ A S A ∣ U B ∣ a ∣ A S ∣ S A B → b U → a S_0 \to ASA|UB|a|AS|SA\\ S \to ASA|UB|a|AS|SA\\ A \to b|ASA|UB|a|AS|SA\\ B \to b\\ U \to a S0→ASA∣UB∣a∣AS∣SAS→ASA∣UB∣a∣AS∣SAA→b∣ASA∣UB∣a∣AS∣SAB→bU→a -
整理大于2的字串
S 0 → A 1 A ∣ U B ∣ a ∣ A S ∣ S A S → A 1 A ∣ U B ∣ a ∣ A S ∣ S A A → b ∣ A 1 A ∣ U B ∣ a ∣ A S ∣ S A B → b U → a A 1 = A S S_0 \to A_1A|UB|a|AS|SA\\ S \to A_1A|UB|a|AS|SA\\ A \to b|A_1A|UB|a|AS|SA\\ B \to b\\ U \to a\\ A_1 = AS S0→A1A∣UB∣a∣AS∣SAS→A1A∣UB∣a∣AS∣SAA→b∣A1A∣UB∣a∣AS∣SAB→bU→aA1=AS
下推自动机
相较于有穷自动机,下推自动机拥有一个能够存储的栈,因而拥有更强的表现能力。例如,DFA无法识别 { 0 n 1 n ∣ n ≥ 0 } \{0^n1^n|n\ge 0\} {0n1n∣n≥0},但下推自动机能够通过栈记忆0的个数,从而接受该语言。
可以根据哪边更好构造,选择使用CFG还是PDA构造CFL。
形式化定义
下推自动机(pushdown automata, PDA)可以被表示为6元组 ( Q , Σ , Γ , δ , q 0 , F ) (Q, \Sigma, \Gamma, \delta, q_0, F) (Q,Σ,Γ,δ,q0,F):
- Q Q Q为状态集
- Σ \Sigma Σ为输入字母表
- Γ \Gamma Γ为栈字母表(stack alphabet)
- δ \delta δ为转移函数
- q 0 ∈ Q q_0\in Q q0∈Q为初始状态
- F ⊆ Q F\sube Q F⊆Q为接受状态集
注意下PDA状态转移的写法: ( q i + 1 , b ) = δ ( q i , w i + 1 , a ) (q_{i +1},b) = \delta(q_i, w_{i+1}, a) (qi+1,b)=δ(qi,wi+1,a),其中, w i + 1 w_{i + 1} wi+1为输入字符, a → b a\to b a→b为栈顶元素变化, q i → q i + 1 q_i \to q_{i + 1} qi→qi+1为状态迁移。在更广义的定义中, w i + 1 w_{i+1} wi+1可以是任意长度的未读字符串,用 u u u表示,例如 ( q 1 , 1111 , $ ) (q_1, 1111, \text{\textdollar}) (q1,1111,$)。
相比DFA/NFA的状态转移: q i + 1 = δ ( q i , w i + 1 ) q_{i + 1} = \delta(q_i, w_{i + 1}) qi+1=δ(qi,wi+1),PDA的状态转移多了栈元素的变化。
设栈顶元素为 a a a,如果需要弹栈,记 a → ε a \to \varepsilon a→ε;如果不需要改变栈,则记 a → a a \to a a→a。
PDA的形式化定义没有包含如何判断空栈的说明,一般是在最开始压栈一个特殊字符,例如 $ \text{\textdollar} $。
可以使用状态图或转移表(矩阵)来描述一个PDA,例如描述上述的 { 0 n 1 n ∣ n ≥ 0 } \{0^n1^n|n\ge 0\} {0n1n∣n≥0}的状态图。
形式 w , a → b w, a\to b w,a→b用于在状态图中表示读入 w w w,将栈顶元素从 a a a替换为 b b b。
转移矩阵
因为PDA画状态图也不是很复杂,有的时候反而更直观。
等价性证明
没要求,但是很有意思,有兴趣可以看看。
证明等价仍然遵循两边证的思路。
CFG可以被转化为一台PDA
设待转化的CFG 为 G G G,转化的PDA为 P P P,首先给出 P P P的非形式化定义:
- 将空栈标记 $ \text{\textdollar} $和起始变元 S S S压栈。
- 重复以下步骤
- 若栈顶为变元 A A A,则非确定地选择 A A A的一个替换规则,将 A A A替换为右侧的字符串并压栈。
- 若栈顶为终结符 a a a,则读入一个输入字符 s s s,判断 a a a与 c c c是否匹配。若匹配,则继续重复下去;否则拒绝该分支
- 若栈顶为 $ \text{\textdollar} $,进入接受状态,若此时输入已经读完,则接受。
形式化证明:
首先给定一种简化的表示方法,使得PDA可以在弹栈之后,将整个字符串压栈;设状态为
q
,
r
q, r
q,r,
a
∈
Σ
ε
a \in \Sigma_\varepsilon
a∈Σε,
s
∈
Γ
ε
s \in \Gamma_\varepsilon
s∈Γε,待压栈的规则右侧字符串为
u
=
u
1
u
2
…
u = u_1u_2\dots
u=u1u2…,定义这种转移关系为:
(
r
,
u
)
∈
δ
(
q
,
a
,
s
)
(r, u) \in \delta(q, a, s)
(r,u)∈δ(q,a,s)
上式意为,处于状态
q
q
q的PDA
P
P
P读入输入字符
a
a
a,弹出栈顶的
s
s
s,迁移到状态
r
r
r,并将字符串
u
u
u压栈。如果按状态图表示,则状态
p
,
r
p, r
p,r之间的箭头应标注
a
,
s
→
u
a, s\to u
a,s→u。
这种简化的表示方法,可以被展开为从状态 q q q到 r r r经过多个子状态的迁移,如下图所示, s → x y z s \to xyz s→xyz被表示为 s → z , ε → y , ε → x s\to z, \varepsilon \to y, \varepsilon \to x s→z,ε→y,ε→x.
利用这种简化的表示方法,可以使用三个状态 { q s t a r t , q l o o p , q a c c e p t } \{q_{start}, q_{loop}, q_{accept}\} {qstart,qloop,qaccept},来表示上文中非形式化的PDA:
压栈 $ \text{\textdollar} $和初始变元 S S S,有迁移 ( q l o o p , S $ ) ∈ δ ( q l o o p , ε , ε ) (q_{loop}, S\text{\textdollar}) \in \delta(q_{loop}, \varepsilon, \varepsilon) (qloop,S$)∈δ(qloop,ε,ε)
- 对栈顶为变元 A A A,有迁移 ( q l o o p , w ) ∈ δ ( q l o o p , ε , A ) (q_{loop}, w) \in \delta(q_{loop}, \varepsilon, A) (qloop,w)∈δ(qloop,ε,A),状态图中记 ε , A → w \varepsilon, A \to w ε,A→w
- 对栈顶为终结符 a a a,有迁移 ( q l o o p , ε ) ∈ δ ( q l o o p , a , a ) (q_{loop}, \varepsilon) \in \delta(q_{loop}, a, a) (qloop,ε)∈δ(qloop,a,a),状态图中记 a , a → ε a, a \to \varepsilon a,a→ε
- 对栈顶为 $ \text{\textdollar} $,有迁移 ( q a c c e p t , ε ) ∈ δ ( q l o o p , ε , $ ) (q_{accept}, \varepsilon) \in \delta(q_{loop}, \varepsilon, \text{\textdollar}) (qaccept,ε)∈δ(qloop,ε,$),状态图中记 ε , $ → ϵ \varepsilon, \text{\textdollar} \to \epsilon ε,$→ϵ
整理为状态图:
一台PDA可以被转化为CFG
待证为:对PDA P P P,存在CFG G G G中的变元序列 A q 0 q a c c e p t A_{q_0q_{accept}} Aq0qaccept,能够将状态机从 q 0 q_0 q0迁移到接受状态 q a c c e p t q_{accept} qaccept,且前后都保证栈空。
保证栈空是因为PDA接受必须是栈空的。
证明:
首先证明,上述变元序列,能够被切分为变元序列 A p q A_{pq} Apq,该序列能够将状态机从状态 p p p迁移到状态 q q q,且只有首尾状态栈空。
- 若变元序列 A p q A_{pq} Apq,只在开始和结束的时候,出现栈空的情况,则记为规则 A p q → a A r s b A_{pq} \to aA_{rs}b Apq→aArsb。其中, A r s A_{rs} Ars是所有栈不为空的变元序列。
- 若变元序列 A p q A_{pq} Apq,不满足上一条情况,在序列中间存在栈空状态 r r r,则可从 r r r进行划分,记为 A p q → A p r A r q A_{pq} \to A_{pr}A_{rq} Apq→AprArq,按此进行划分,指导满足上一条的情况。
由此可将状态机序列划分为一个个由空栈状态分割的序列。
接下来通过两个断言说明变元序列与状态集迁移的等价性,从而得证PDA可以转化为CFG。
断言1:若变元序列 A p q → x A_{pq} \to x Apq→x,则派生 x x x能够将PDA P P P,从状态 p p p迁移到状态 q q q。
(归纳法)
- 若一步派生,则显然 A p p → ε A_{pp} \to \varepsilon App→ε,成立;
- 若多步派生,设对小于
k
k
k步的派生成立,且
A
p
q
→
x
A_{pq} \to x
Apq→x需要
k
+
1
k + 1
k+1步派生,且:
- 若 A p q → a A r s b A_{pq} \to aA_{rs}b Apq→aArsb,对应序列 x = a y b x = ayb x=ayb,因为 y y y需要 k k k步,所以 x x x能够将状态迁移,成立;
- 若 A p q → A p r A r q A_{pq} \to A_{pr}A_{rq} Apq→AprArq,对应序列 x = y , z x= y, z x=y,z,因为 y , z y, z y,z都小于 k k k步,成立。
综上,得证 A p q → x A_{pq} \to x Apq→x, x x x能够将 P P P从 p p p迁移到 q q q。
断言2:若派生 x x x能够将PDA P P P,从状态 p p p迁移到状态 q q q,则变元序列 A p q → x A_{pq} \to x Apq→x。
(归纳法)
-
若开始和结束都在同一状态 p p p,则PDA P P P只能读入 ε \varepsilon ε, x = ε x = \varepsilon x=ε,而 G G G存在规则 A p p → ε A_{pp} \to \varepsilon App→ε,成立
-
若开始和结束的状态不同,设断言对长度不超过 k ≥ 0 k \ge 0 k≥0的计算成立,证明对 k + 1 k + 1 k+1成立:
-
只在开始和结束的时候栈空。设状态集 { p , r , s , q } \{p, r, s, q\} {p,r,s,q}, r , s r, s r,s对应串 u u u,两端输入为 a , b a, b a,b,则有
( r , u ) ∈ δ ( p , a , ε ) ( q , ε ) ∈ δ ( s , b , u ) (r, u) \in \delta(p, a, \varepsilon)\\ (q, \varepsilon) \in \delta(s, b, u) (r,u)∈δ(p,a,ε)(q,ε)∈δ(s,b,u)
其中, r , s r,s r,s的长度为 k − 1 k - 1 k−1,从而得到文法规则 A p q → a A r s b A_{pq} \to aA_{rs}b Apq→aArsb. -
中间有栈空。设状态集 { p , r , q } \{p, r, q\} {p,r,q}, p , r p, r p,r对应串 y y y, r , q r, q r,q对应串 z z z,都不超过 k k k步,得到 A p q → A p r A r q A_{pq} \to A_{pr}A_{rq} Apq→AprArq,成立
-
综上,得证。
整理:
设PDA P = { Q , Σ , Γ , δ , q 0 , { q a c c e p t } } P = \{Q, \Sigma, \Gamma, \delta, q_0, \{q_{accept}\}\} P={Q,Σ,Γ,δ,q0,{qaccept}},构造上下文无关文法 G = { V , Σ , R , S G = \{V, \Sigma, R, S G={V,Σ,R,S。
-
V = { A p , q ∣ p , q ∈ Q } V = \{A_{p, q}|p, q \in Q\} V={Ap,q∣p,q∈Q}
-
Σ = Σ \Sigma = \Sigma Σ=Σ
-
S = A q 0 q a c c e p t } S = A_{q_0q_{accept}}\} S=Aq0qaccept}
-
R R R:
∀ p ∈ Q , A p p → ε ∀ p , q , r ∈ Q , A p q → A p r A r q ∀ p , r , s , q ∈ Q , A p q → a A r s b { ( r , u ) ∈ δ ( p , a , ε ) ( q , ε ) ∈ δ ( s , b , u ) \begin{array}{l} \forall\ p\in Q, A_{pp} \to \varepsilon\\ \forall\ p, q, r \in Q, A_{pq} \to A_{pr}A_{rq}\\ \forall\ p, r, s, q \in Q, A_{pq} \to aA_{rs}b\\ \left\{\begin{array}{l} (r, u) \in \delta(p, a, \varepsilon)\\ (q, \varepsilon) \in \delta(s, b, u) \end{array} \right. \end{array} ∀ p∈Q,App→ε∀ p,q,r∈Q,Apq→AprArq∀ p,r,s,q∈Q,Apq→aArsb{(r,u)∈δ(p,a,ε)(q,ε)∈δ(s,b,u)
例题:将下述CFG转化为PDA
S
→
a
T
b
∣
b
T
→
T
a
∣
ε
S \to aTb|b\\ T \to Ta|\varepsilon
S→aTb∣bT→Ta∣ε
思路:
- 画出 q s t a r t , q l o o p , q a c c e p t q_{start}, q_{loop}, q_{accept} qstart,qloop,qaccept
- 写压栈条件
- 写loop条件,可先写为字符串简式,然后展开
- 写accept条件
泵引理
上下文无关文法的泵引理,需要通过树的思想来理解。
引理:若 A A A为CFL,则存在数 p p p,为泵长度,使得 A A A中任意长度不小于 p p p的字符串 s s s,都可以被划分为5段 s = u v x y z s = uvxyz s=uvxyz,且满足:
- ∀ i ≥ 0 , u v i x y i z ∈ A \forall i \ge 0, uv^ixy^iz \in A ∀i≥0,uvixyiz∈A
- ∣ v y ∣ > 0 |vy| > 0 ∣vy∣>0
- ∣ v x y ∣ ≤ p |vxy|\le p ∣vxy∣≤p
引理证明
设CFG G G G为识别CFL A A A的文法, b b b为 → \to →右侧符号数的最大值,意味着对语法树中任意一个结点,该节点最多有 b b b个子。
根据树模型的性质,可知从起始变元 s . v . s.v. s.v.出发,走1步最多可以有 b b b个叶子(字符),走2步最多可以有 b 2 b^2 b2个字符……走 h h h步最多可以有 b h b^h bh个字符。
因此,对树高不超过 h h h的树,字符串的长度不会超过 b h b ^ h bh;‘反之,如果字符串的长度不小于 b h + 1 b^h + 1 bh+1,则树高至少为 h + 1 h + 1 h+1。
设 G G G中变元的数量为 ∣ V ∣ |V| ∣V∣,令泵长度为 p = b ∣ V ∣ + 1 p = b^{|V| + 1} p=b∣V∣+1,此时任意长度不小于 p p p的字串,其树高一定不小于 ∣ V ∣ + 1 |V| + 1 ∣V∣+1,因为 b ∣ V ∣ + 1 ≥ b ∣ V ∣ + 1 b^{|V| + 1} \ge b^{|V|} + 1 b∣V∣+1≥b∣V∣+1。
这里之所以设 p = b ∣ V ∣ + 1 p = b^{|V| + 1} p=b∣V∣+1,是为了满足鸽巢定理的使用条件,构造比变元数 ∣ V ∣ |V| ∣V∣至少多一个的变元序列,进而推出至少存在一个重复变元。
在正则语言的证明中, p = 状态数 p = 状态数 p=状态数,此时对任何不长度 n ≥ p n \ge p n≥p的字符串,都有不小于 n + 1 n + 1 n+1个状态序列,从而满足了鸽巢定理的使用条件。
假设使用节点数最少的语法树,由于树的高度不小于 ∣ V ∣ + 1 |V| + 1 ∣V∣+1,则从语法树的根节点出发,最长路径的节点数应该为 ∣ V ∣ + 2 |V| + 2 ∣V∣+2;因为叶子是终结符,所以这条路径上包含不少于 ∣ V ∣ + 1 |V| + 1 ∣V∣+1个变元,根据鸽巢定理,在这条最长路径上,至少存在一个重复的变元。为方便表示,选择位于最下面的 ∣ V ∣ + 1 |V| + 1 ∣V∣+1个变元中重复的变元,记为 R R R,则可以切分语法树,并将s划分为如下5段。
与正则语言一样,这个重复的变元,应当具有 ∀ i ≥ 0 , u v i x y i z ∈ A \forall i \ge 0, uv^ixy^iz \in A ∀i≥0,uvixyiz∈A的可重复性。
使用泵引理证明非上下文无关
泵引理的条件3是非常好用的约束条件,可以利用这一条件,构造长度为 p p p的滑窗,然后分段讨论。
例1:证明 { a n b n c n ∣ n ≥ 0 } \{a^nb^nc^n|n \ge 0\} {anbncn∣n≥0}非上下文无关。
证明:设 s = a p b p c p s = a^pb^pc^p s=apbpcp, v x y vxy vxy为长度 p p p的滑窗,考虑不同的滑动情况,如下图所示
可以观察到, v , y v, y v,y中的字符存在两种情况:1. 包含两种不同的字符;2. 包含一种字符
- 存在两种字符时,设 i = 2 i = 2 i=2,会出现逆序
- 存在一种字符时,设 i = 0 i = 0 i=0,会导致 a , b , c a,b,c a,b,c个数不等
综上两种情况,可知 { a n b n c n ∣ n ≥ 0 } \{a^nb^nc^n|n \ge 0\} {anbncn∣n≥0}不是上下文无关语言
上下文无关语言封闭性
上下文无关的封闭证明,主要关注如何构造新的初始变元。
不封闭的证明,则要记住反例。
并
上下文无关语言对并运算封闭,通过构造法证明。
设文法 G 1 : { V 1 , Σ 1 , S 1 , R 1 } G_1: \{V_1, \Sigma_1, S_1, R_1\} G1:{V1,Σ1,S1,R1}, G 2 : { V 2 , Σ 2 , S 2 , R 2 } G_2: \{V_2, \Sigma_2, S_2, R_2\} G2:{V2,Σ2,S2,R2},为便于证明,且设 V 1 ∩ V 2 = ∅ V_1 \cap V_2 = \empty V1∩V2=∅
设
G
=
G
1
∪
G
2
G = G_1 \cup G_2
G=G1∪G2,构造
G
G
G:
V
=
V
1
∪
V
2
∪
S
0
Σ
=
Σ
1
∪
Σ
2
S
0
R
=
R
1
∪
R
2
∪
{
S
0
→
S
1
∣
S
2
}
V= V_1\cup V_2 \cup S_0\\ \Sigma = \Sigma_1 \cup \Sigma_2\\ S_0\\ R = R_1\cup R_2 \cup \{S_0 \to S_1|S_2\}
V=V1∪V2∪S0Σ=Σ1∪Σ2S0R=R1∪R2∪{S0→S1∣S2}
理解这段证明的关键在于 S 0 → S 1 ∣ S 2 S_0 \to S_1 | S_2 S0→S1∣S2,即增加一个新的起始,该起始可以变换为 S 1 S_1 S1或者 S 2 S_2 S2。
连接
上下文无关语言对连接运算封闭,使用构造法证明。
设文法 G 1 : { V 1 , Σ 1 , S 1 , R 1 } G_1: \{V_1, \Sigma_1, S_1, R_1\} G1:{V1,Σ1,S1,R1}, G 2 : { V 2 , Σ 2 , S 2 , R 2 } G_2: \{V_2, \Sigma_2, S_2, R_2\} G2:{V2,Σ2,S2,R2},为便于证明,且设 V 1 ∩ V 2 = ∅ V_1 \cap V_2 = \empty V1∩V2=∅
设
G
=
G
1
∪
G
2
G = G_1 \cup G_2
G=G1∪G2,构造
G
G
G:
V
=
V
1
∪
V
2
∪
S
0
Σ
=
Σ
1
∪
Σ
2
S
0
R
=
R
1
∪
R
2
∪
{
S
0
→
S
1
S
2
}
V= V_1\cup V_2 \cup S_0\\ \Sigma = \Sigma_1 \cup \Sigma_2\\ S_0\\ R = R_1\cup R_2 \cup \{S_0 \to S_1S_2\}
V=V1∪V2∪S0Σ=Σ1∪Σ2S0R=R1∪R2∪{S0→S1S2}
星
上下文无关语言对星运算封闭,构造方法和连接类似。
设文法
G
1
:
{
V
1
,
Σ
1
,
S
1
,
R
1
}
G_1: \{V_1, \Sigma_1, S_1, R_1\}
G1:{V1,Σ1,S1,R1},设
G
=
G
1
∗
G = G_1^*
G=G1∗,构造
G
G
G:
V
=
V
1
∪
V
2
∪
S
0
Σ
=
Σ
1
∪
Σ
2
S
0
R
=
R
1
∪
R
2
∪
{
S
0
→
S
1
∣
S
0
S
0
}
V= V_1\cup V_2 \cup S_0\\ \Sigma = \Sigma_1 \cup \Sigma_2\\ S_0\\ R = R_1\cup R_2 \cup \{S_0 \to S_1|S_0S_0\}
V=V1∪V2∪S0Σ=Σ1∪Σ2S0R=R1∪R2∪{S0→S1∣S0S0}
交
上下文无关语言对交运算不封闭,可以使用反证法证明。
已知上下文无关语言对连接运算封闭,故可构造
{
a
n
b
n
c
m
∣
n
,
m
≥
0
}
,
{
a
m
b
n
c
n
∣
n
,
m
≥
0
}
\{a^nb^nc^m|n, m \ge 0\},\{a^mb^nc^n|n, m \ge 0\}
{anbncm∣n,m≥0},{ambncn∣n,m≥0}
∵
{
a
n
b
n
}
有上下文无关文法
A
→
a
A
b
∣
ε
{
c
m
}
有上下文无关文法
S
→
c
S
∣
ε
∴
{
a
n
b
n
c
m
}
=
{
a
n
b
n
}
∘
{
c
m
}
,为上下文无关语言
同理可证
{
a
m
b
n
c
n
}
为上下文无关语言
\because \{a^nb^n\}有上下文无关文法\\ A \to aAb|\varepsilon\\ \{c^m\}有上下文无关文法\\ S \to cS|\varepsilon\\ \therefore \{a^nb^nc^m\} = \{a^nb^n\} \circ \{c^m\},为上下文无关语言\\ 同理可证\{a^mb^nc^n\}为上下文无关语言
∵{anbn}有上下文无关文法A→aAb∣ε{cm}有上下文无关文法S→cS∣ε∴{anbncm}={anbn}∘{cm},为上下文无关语言同理可证{ambncn}为上下文无关语言
但这两种语言的交集,
{
a
n
b
n
c
n
∣
n
≥
0
}
\{a^nb^nc^n|n \ge 0\}
{anbncn∣n≥0}不是上下文无关语言,上文已用泵引理证明。
补
已知上下文无关语言对交运算不封闭,而 L 1 ∩ L 2 = L 1 ‾ ∪ L 2 ‾ ‾ L_1 \cap L_2 = \overline {\overline {L_1} \cup \overline {L_2}} L1∩L2=L1∪L2,因为并运算是封闭的,可知补运算不封闭。
正则与上下文无关语言的交封闭性
设 L L L为上下文无关语言, R R R为正则语言,则 L ∩ R L \cap R L∩R为上下文无关语言。
证明的思路和前面证明正则并封闭性的一种方法类似,即构造二元的状态对作为新的PDA的状态。
我们可以简单地将DFA理解为不需要处理栈的PDA,对应状态转移 ( q i + 1 , a ) = δ ( q i , w i + 1 , a ) (q_{i + 1}, a) = \delta(q_i, w_{i+1}, a) (qi+1,a)=δ(qi,wi+1,a)
证明:设DFA
D
=
{
Q
1
,
Σ
,
δ
1
,
p
1
,
F
1
}
D = \{Q_1, \Sigma, \delta_1, p_1, F_1\}
D={Q1,Σ,δ1,p1,F1}识别
R
R
R,PDA
P
=
{
Q
2
,
Σ
,
Γ
,
δ
2
,
q
2
,
F
2
}
P = \{Q_2, \Sigma, \Gamma, \delta_2,q_2, F_2\}
P={Q2,Σ,Γ,δ2,q2,F2}识别
L
L
L,构造PDA
P
′
=
{
Q
1
×
Q
2
,
Σ
,
Γ
,
δ
,
[
q
1
,
q
2
]
,
F
1
×
F
2
}
P' = \{Q_1 \times Q_2, \Sigma, \Gamma, \delta, [q_1, q_2],F_1\times F_2\}
P′={Q1×Q2,Σ,Γ,δ,[q1,q2],F1×F2}
其中,
δ
\delta
δ为
δ
(
[
p
i
,
q
i
]
,
w
i
+
1
,
a
)
=
(
[
p
i
+
1
,
q
i
+
1
]
,
b
)
;
要求
δ
1
(
p
i
,
w
i
+
1
)
=
p
i
+
1
,
δ
2
(
q
i
,
w
i
+
1
,
a
)
=
(
q
i
+
1
,
b
)
w
i
+
1
∈
Σ
,
a
,
b
∈
Γ
\delta([p_i, q_i], w_{i+1}, a) = ([p_{i+1}, q_{i+1}], b);\\ 要求\delta_1(p_i, w_{i+1}) = p_{i+1},\ \delta_2(q_i, w_{i+1}, a) = (q_{i+1}, b)\\ w_{i+1} \in \Sigma,\ a,b \in \Gamma
δ([pi,qi],wi+1,a)=([pi+1,qi+1],b);要求δ1(pi,wi+1)=pi+1, δ2(qi,wi+1,a)=(qi+1,b)wi+1∈Σ, a,b∈Γ
参考
- 《计算理论导引》第二版,机械工业出版社