有限存储的计算机等价于有限自动机(DFA、NFA)

B = { 0 n 1 n | n 0 }

  • Michael Sipser 的 Introduction to the Theory of Computation 的1.4提到一个非正则语言的例子, B = { 0 n 1 n | n 0 } ,并用Pumping lemma证明了其是非正则的,无法被DFA识别
  • 但是我们的计算机似乎可以识别以上语言,所以,为什么我们的计算机还是DFA呢
  • 事实上,我们的计算机只能识别n处于一定范围的B,而不能识别n为任意值的B。如果n过大,我们的计算机的存储单元无法表达,则会发生溢出,导致识别了另一个语言 C = { 0 n 1 m | n   m o d   m a x = m   m o d   m a x } ,其中,max是我们的计算机的存储单元可以表达的最大值
  • 如果是n处于一定范围内,容易构造出一台DFA识别B:
    • 设有两个变量a、b,a、b都可以取值 [ 0 , 1000 ] ,a表示0的数量,b表示1的数量
    • 那么,a、b的所有笛卡尔积组成的集合的一个子集就是该DFA的状态集
    • 转移方程为
    • 首先: < 0 , 0 >→< 1 , 0 >→< 2 , 0 >→ . . . →< 1000 , 0 >
    • 然后:从任意 < n , 0 > 都可以转移到 < n , 1 >
    • 然后:一旦转移到 < n , 1 > ,就不能转移到 < n + k , m > , ( k > 0 ) ,也就是不能增长n的值
    • 最后:一旦转移到 < n , n > 就accept

为什么现实中的计算机有可能是DFA

  • 计算机只有有限存储,such as,某计算机有 2 32 个8bit的cell,每个cell有 2 8 种取值,所以,所有存储的取值有 ( 2 8 ) 2 32 种,也就是,这台计算机的存储只能有 ( 2 8 ) 2 32 种状态,这就使得把计算机转为DFA变为可能

对任意一段代码构造等价的NFA

NFA构造方法描述
  • 假设该段代码的运行过程会改变的存储cell有c1、c2、c3、c4、c5,其中,c1到c5的取值范围都是[0,0xFF],那么就可以构造 ( 2 8 ) 5 < c 1 , c 2 , c 3 , c 4 , c 5 > ,作为该NFA的状态集合

  • 其读入的所有外部信息组成的集合就是字母表,consider that,此处的字母表不局限于英文字母表,此处字母表的每个字母都表示单次读入可能读入的信息,比如,某次读入读入了355abc,则355abc 就是一个字母。这样的字母表是有限的——因为读入的信息必然要可以被计算机表示,而计算机只能表示有限数量的信息,所以,即使在无限时间上持续读入,其读入的信息仍然是有限集合里的东西

  • 假设该代码起始时,c1到c5的取值为 0 , 0 , 0 , 0 , 0 ,则 < 0 , 0 , 0 , 0 , 0 > 就是起始态

  • 假设该段代码处于accept状态时,c1到c5的取值分别为 1 , 2 , 3 , 4 , 5 ,那么, < 1 , 2 , 3 , 4 , 5 > 就是该NFA的accept state
  • 该代码可以有输入,也可以无输入,可以在多个时候输入,也可以只在一个时候输入。假设其某次输入处于 < d 1 , d 2 , d 3 , d 4 , d 5 > ,输入后处于 < d 6 , d 7 , d 8 , d 9 , d 10 > ,则在从 < d 1 , d 2 , d 3 , d 4 , d 5 > < d 6 , d 7 , d 8 , d 9 , d 10 > 是一个转移,转移使用的字符就是读入的字符。该代码也可以在无输入情况下由cpu作用,从一个状态转移到另一个状态,则在这两个状态之间使用 ε
为什么该NFA只接受允许的字符串,而不会接受多余的字符串
  • 首先,可以使用以上方法对于每个接受的字符串都构造NFA,则该NFA只接受允许的那个字符串
  • 设置一个新的起始态,该起始态有 ε 到所有为每个字符串构造的NFA
  • 则最终的NFA只接受允许的字符串
是否会出现情况:代码两次处于某状态但是行为不一样
  • 答案是肯定不会
  • 计算机的行为由当前状态决定——下一步要执行什么代码,取决于正在被执行的代码段,以及ip寄存器的值,如果text段的内容相同,cs:ip寄存器的相同,指令使用的值也相同,那么下一步的行为就是确定的

对任意一台计算机构造等价的DFA

  • 对于一台确定的计算机可以构造出确定的DFA,执行该计算机可以做的任何计算
  • 先说明一些前置情况:
    • 现实中计算机使用源码处理特定的输入
    • 把现实中计算机处理该输入的源码编码成确定长度(统一取最大长度M——M是该计算机可以存储的最长比特串长度,比如 2 40 比特)的字符串,每个字符表示一个指令——这个其实等价于把源码编译成机器码(每个机器指令由一样的长度的比特串表示),然后把这个比特串补全成统一长度M
  • 因为源码是M比特长,所以最多有 2 M 种不同的源码,根据上文,可以为每种源码构造一个DFA
  • 然后开始构造DFA
    • 该DFA分为两个部分:第一个部分解释输入的源码字符串,第二个部分实际运行输入的源码来跑输入的数据——即实际运行 2 M 个不同的DFA中的一个
    • DFA第一个部分,其读入长度M的字符串(也就是源码),从而把该台DFA导向某个状态,这个状态是 2 M 个实际运行代码的DFA中的一个的起始态
    • 第二部分就是那 2 M 台DFA,其接受输入,并最终停在某个状态——accept态或者是其他状态
  • 从而该DFA接受 A i ,其中 A i 是该计算机可以运行的任意一段代码接受的字符串集合

计算机可以死循环,DFA不会死循环,为什么

  • consider that,死循环指的是无输入情况下,不停机,而不是无限输入导致的不停机。

  • 因为计算机的状态是有限的,所以,如果计算机死循环,那么其必然会重复处于某个状态,进而导致行为的重复——因为计算机的当前状态唯一确定了以后的行为。

  • 在NFA,这种情况死循环的状况也会发生——一组状态以 ε 连接在一起形成环,从而导致无限读入 ε ,无限循环

  • 截断导致NFA死循环的那个环,并不会影响接受的语言。假设该环是s1、s2、s3、s1,那么我们可以把其变成三条路:“s1、s2、s3”,“s2、s3、s1”,“s3、s1、s2” ,非形式化来说,因为这不会改变该图的连通性,所以接受的字符串集合不变

  • 而按照Introduction to the Theory of Computation 的1.2节的*EQUIVALENCE OF NFAS AND DFAS*DFA 描述的方法,其正是去掉了这种 ε 环,所以不会死循环,具体去掉的方法如下(截图来自书本英文第三版P56):

    这里写图片描述

    E ( R ) 是一个集合,集合中元素不重复,而 ε 环所到达的状态必然是重复的,所以就把 ε 环断开了

猜你喜欢

转载自blog.csdn.net/h_zx_h_zx/article/details/80381607