这是大一下学期某次计科导的思考题把这个问题拿来给大一学生思考真是很难想象开课老师的精神状态
首先吐槽一句资料真的难找。网上有关这方面的资料少之又少,顶多介绍了2DFA的定义和结论,但是没有给出2DFA和DFA的等价性证明的。为了填补国内对于这一问题的资料的空白,我决定写这么一篇文章把这个问题讲清楚。
根据目前资料来看,这个成果最早见于上古时期1959年的一篇论文《Finite Automata and Their Decision Problems》中,作者是M.Rabin和Dana Scott。两位因此获得了1976年的图灵奖。当然我刚开始去找的时候发现这篇论文没地方白嫖,购买要33刀太贵了。
现在的计算理论教材介绍这个内容的貌似很少了,主要原因可能是原始论文中的构造过于复杂。但是这里要感谢神通广大的计算理论老师给我提供了一份1979年的 “计算理论早期的一本标准参考书” Introduction to Automata Theory 的第一版(第二版,第三版太简单了) 的英文原版(中译本有,但是很难找到了) 的 djvu影印版本(pdf版没找到),作者是John.E.Hopcroft和Jeffrey.D.Ullman,算是本上古奇书。这篇文章的内容基本全部翻译自原书的2.6节。
感谢vfk给了一份原始论文虽然我不知道他是怎么找到的,也还没怎么看
1.前置
2DFA的定义网上都能找到,这里不多说,符号基本上也是全世界通用的。2DFA的五元组定义中与DFA唯一的不同是2DFA的δ定义为Q×Σ→Q×{L,R}。
在描述DFA的行为的时候,我们将δ函数的定义域扩展至了Q×Σ∗,用以描述DFA从某个状态出发接受一个字符串以后到达的状态。但是对于2DFA这种技巧不再奏效,因为是可以向左移动的。
我们定义2DFA的格局I∈Σ∗QΣ∗,I可写作wqx,w,x∈Σ∗,q∈Q。代表含义如下:
-
wx是输入串
-
$ q $是当前状态
-
2DFA的读入端正在读取x的第一个字符
特别的,x=ϵ表示2DFA的读入端已经移出了输入串的右边界。
我们定义二元关系 ⊢M,I1⊢MI2当且仅当通过读入端的一次移动可以格局I1转移至格局I2
我们由此可以对⊢M(以下简记作⊢)给出形式化的定义:
-
a1a2...ai−1qai...an⊢a1a2...ai−1aipai+1...an,whenever δ(q,ai)=(p,R)
-
a1a2...ai−2ai−1qai...an⊢a1a2...ai−2pai−1ai...an,whenever δ(q,ai)=(p,L)
i>1防止移出左端,而i=n+1时没有可用的移动。
我们定义 $\vdash^\ast 为\vdash$的传递闭包。利用上面的记号我们就可以写出 2DFA M接受的语言L(M)的形式化定义: L(M)={w∣q0w⊢∗wp,p∈F}
2.crossing sequence
对于2DFA的行为的一个有用的描述是读取输入时读入端移动的路径,以及每一次读入端穿过两个字符的边界时的状态(也就相当于每一次移动的起始状态)。对于我们每一次穿过的边界,都对该边界记录下穿过该边界时的状态,那么对于每个边界我们都将得到一个状态序列,被称作crossing sequence(我也不知道中文是什么)。
需要注意的是,如果2DFA接受了输入串,那么产生的所有crossing sequence中都不会存在移动方向相同的重复状态。容易知道这样必定会在同一个边界处左右横跳产生死循环。
另一个重要的观察结果是,当一个边界第一次被穿过的时候,读入端一定在向右移动。而且后续再次穿过该边界的时候的移动方向一定是与前一次访问时的移动方向相反。因此在一个crossing sequence中,下标为奇数的元素一定代表着向右移动,而下标为偶数的元素一定代表着向左移动。如果输入串被接受,那么产生的所有crossing sequence一定长为奇数。由此,如果一个crossing sequence q1,q2,...,qk长度为奇数,我们称这个crossing sequence是有效的。
老师的提示:“每个这种序列本质上是从状态集Q到状态集Q的函数f:Q→Q,输入是向右移动时的状态,输出是向左回来时的状态,这两个状态就是该序列中相邻的两项。构造的DFA本质上用这种f作为状态。”
原书中构造的是NFA,当然也是等价的,用的也是crossing sequence作为状态。为此,我们首先需要分析相邻的crossing sequence的性质。
3.左右匹配crossing sequence对
考虑输入字符串上的一个字符a,设在a的左边界和右边界处分别给出有效的crossing sequence q1,q2,...qk和p1,p2,...,pl。我们可以用如下方法检测这两个crossing sequence是否是相容的(一致的),或者说,我们在计算过程中能否在a的左右边界上分别产生这两个crossing sequence。
如果读入端以状态qi从a字符处向左移动,那么我们以qi+1为起始状态,从a处开始,重新启动自动机,这样相当于我们从crossing sequence中的下一个状态开始继续运行来检测后续序列的相容性。类似的,如果读入端以状态pi从a字符处向右移动,那么我们以pi+1为起始状态,从a处开始,重新启动自动机,来检测后续序列的相容性。这样的想法给出了下面的两个定义。
定义:我们以如下5个条件递归地给出左匹配和右匹配crossing sequence对的概念。假设我们初始时以状态q1向右移动到达a,若q1,q2,...qk和p1,p2,...,pl是相容的,称q1,q2,...,qk于a处右匹配p1,p2,...,pl。假定我们初始时以状态p1向左移动到达a以状态p1向左移动到达a,若q1,q2,...qk和p1,p2,...,pl是相容的,则称q1,q2,...,qk于a处左匹配p1,p2,...,pl。这里q1,q2,...qk和p1,p2,...,pl分别是我们在a的左右边界处取的crossing sequence 。
注意,因为第一次进入a时肯定是向右移动,因此理论上说只有右匹配对我们是有意义的,但是为了递归地考虑右匹配我们需要对应地给出左匹配的概念。
接下来给出左右匹配的递归判定条件。
-
空序列与空序列左右匹配。也就是说,如果我们根本无法到达a,那么a的左右两侧都是空序列。
-
如果q3,...,qk右匹配p1,...,pl,并且δ(q1,a)=(q2,L),那么q1,...,qk右匹配p1,...,pl。亦即,第一次穿过左边界时以状态q1进入状态q2,并且读入端立刻以状态q2左移进入状态q3。如果我们从q3出发得到了一对匹配的crossing sequence,那么说明我们从q1出发得到的一对crossing sequence也是相容的。
-
如果q2,...,qk左匹配p2,...,pl并且δ(q1,a)=(p1,R),那么q1,...,qk右匹配p1,...,pl。亦即,第一次穿过左边界时以状态q1进入状态p1,并且立即以状态p1右移穿过右边界。
这里需要注意的是,我们下一次回到a时,肯定是以p2左移到达a的,以此为起点考虑接下来的计算过程,这可以看作是原计算过程的一个子过程。在子过程中,我们在左右边界记录下的序列分别是q2,...,qk和p2,...,pl(开头是q2,是因为q1是我们第一次到达a时记下的,不在接下来的计算过程中)。因为这个子过程是以q2向左进入a开始的,因此如果q2,...,qk左匹配p2,...,pl我们就能得到q1,...,qk右匹配p1,...,pl。
-
如果q1,...,qk左匹配p3,...,pl并且δ(p1,a)=(p2,R),那么q1,...,qk左匹配p1,...,pl。这个的解释和第2条类似。
-
如果q2,...,qk右匹配p2,...,pl并且δ(p1,a)=(q1,L),那么q1,...,qk左匹配p1,...,pl。这个的解释和第3条类似。
4.等价性证明
定理:如果语言L被一个2DFA接受,那么L是正则语言
Proof:
我们设$ M=(Q,\Sigma,\delta,q_0,F)是一个\text{2DFA}$。下面构造一个 NFA M′=(Q′,Σ,δ′,q0′,F′) 使得 M′接受L(M),这里(Q′,Σ,δ′,q0′,F′)满足如下条件:
-
Q′由M产生的所有有效的crossing sequence组成。
我们说过,crossing sequence长度是有限的,因此所有有效的crossing sequence集合的大小也是有限的。
-
q0′是仅包含q0的crossing sequence
-
F′是所有仅包含F中的状态的长度为1的crossing sequence组成的集合
形式化的说,F′={[qf]∣qf∈F}
-
δ′(c,a)={d∣d是于a处右匹配c的有效crossing sequence}
这里的d既然是有效的,肯定长度为奇数。注意由于我们构造的是一个NFA,转移函数的像是状态的集合。
因为下面马上会用方括号来表示序列,所以这里F′的形式化定义我也用了方括号表示序列。
我们的想法是让M′把M的计算拼在一起。这是通过猜测接下来的crossing sequence来实现的。如果M′猜测c是在某个边界上产生的crossing sequence,并且a是下一个输入字符,所有于a处被c右匹配的crossing sequence都是可能的下一步,如果我们运气好跑出了输入串的右边界,那M′就接受了这个字符串。
我们下面来证明L(M′)=L(M)。先证L(M)⊂L(M′)。
∀w∈L(M),考虑M在w上的一次接受计算产生的所有crossing sequence。每个crossing sequence都右匹配下一个边界处的crossing sequence,所以我们顺着这些crossing sequence猜就能一路转移到接受状态。
反过来,我们再证明L(M′)⊂L(M)。
∀w∈L(M′),考虑M′计算w=a1a2...an时产生的crossing sequence序列c0,c1,...,cn。那么根据δ′的定义,对于每个i∈[0,n−1],ci右匹配ci+1于ai+1。我们可以通过决定读入端转向的时机来构造M在w上的合法的计算。具体而言,假设M′在读取a1a2...ai,我们对i用归纳法,来证明如下结论。
若M′能进入状态ci=[q1,...,qk],则:
(1) M以q0启动计算a1a2...ai时在i处会首先以q1状态右移,并且
(2) 对于j=2,4,...,若M在i处以状态qj启动,M最终会以状态qj+1向右移出第i位。这也说明k必须为奇数。
原书在此处用[q1,...,qk]表达crossing sequence。这里的符号和原书保持一致。
归纳基础(i=0):
c0=[q0]时(1)自动满足,因为M在0处(相当于字符串还没读入)可以看成是“向右移动”读取了a1。(2)也显然满足。
归纳证明:
假设结论对i−1成立。假定M′会在读取a1a2...ai后从ci−1=[q1,...,qk]进入状态ci=[p1,...,pl]。
因为k和l都是奇数,并且ci−1于ai处右匹配ci,必定存在一个奇数j使得在状态qj读取ai后M向右移动(如果这样的j全部是偶数,那么只可能是让读写头在ai的左边界处反复横跳,那显然是不可能的)。让j1是最小的这样的j(这样我们先去掉了没有作用的反复横跳的情况)。于是根据右匹配的定义,δ(qj1,a1)=(p1,R)。
这一结论无需使用前面给出的递归判定条件,但也不是很显然。由于j1是奇数(注意,奇数的条件控制的是在读取ai之前读入端右移穿过左边界的行为),从qj1读取ai向右的转移一定是穿过ai的左边界到达一个新状态,根据我们对j和j1的约定,读写头这时一定会向右移动穿出ai的右边界(注意,这是由j的约定控制的读入端读取ai以后向右移动穿过右边界的行为,这和上面那一次右移的原因不一样),由j1的最小性,以新状态向右移动一定是第一次穿出ai的右边界,那么ci的第一个元素p1一定是这时产生的。于是我们有δ(qj1,a1)=(p1,R)。
这就证明了(1)。
由前面右匹配定义的第3条,我们有[qj1+1,...,qk]左匹配[p2,...,pl]。
如果对于所有偶数j都有δ(pj,ai)=(pj+1,R)那么(2)显然成立。否则,我们取最小的偶数j2使得δ(pj2,ai)=(qx,L)。目前qx不确定,但可以肯定的是,qx是ai左边界的crossing sequence中的的元素,因为我们在读取ai之后立刻向左移动穿出了左边界。
这样,根据前面左匹配的定义的第5条,qx一定是qj1+1并且[qj1+2,...,qk]右匹配[pj2+1,...,pl]。
这一结论又不是很显然。j2为偶数控制了这一步的移动是穿过ai右边界向左移动,到达了新状态qx。qx又向左移动穿出了左边界。根据前面对于j1的定义,qj1的移动是在状态转移至ci中的状态之前最后一次穿越左边界(在这之后,读入端马上向右移动穿出右边界了)。由于j2的最小性,这一次移动一定是第一次从ci中的状态转移到了ci−1中的状态,并且穿出了左边界。因此,可以知道我们在pj2转移后,一定是转移到了qj1+1。那么qx就是qj1+1。在此基础上直接使用左匹配的定义的第5条就可以得到[qj1+2,...,qk]右匹配[pj2+1,...,pl]。
因此我们肯定会从pj2+1穿出右边界移出i。(2)得证。虽然我们也有可能在穿出去之后再左移回来,但是我们只要重复这个过程,不断消去ci和ci−1中的元素,对于M来说它会在这样的pj和qj之间来回移动直到最终剩下所有偶数j都有δ(pj,ai)=(pj+1,R),这是肯定能达成的,最终否则如果读取了ai都是向左移动那么就不会穿出ai的右边界,w也就不会被接受了。这时M会继续转移到下一个crossing sequence中的状态。换言之我们不会停在第i位之前走不出去。
由于cn非空,最后一定能走到cn=[p],这里p∈F。于是M接受a1a2...an,有L(M)⊂L(M′)。
于是L(M)=L(M′)。定理得证。
5.总结
总结个寂寞,累死了。