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

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/h_zx_h_zx/article/details/80381607

B={0n1n|n0}

  • Michael Sipser 的 Introduction to the Theory of Computation 的1.4提到一个非正则语言的例子,B={0n1n|n0} ,并用Pumping lemma证明了其是非正则的,无法被DFA识别
  • 但是我们的计算机似乎可以识别以上语言,所以,为什么我们的计算机还是DFA呢
  • 事实上,我们的计算机只能识别n处于一定范围的B,而不能识别n为任意值的B。如果n过大,我们的计算机的存储单元无法表达,则会发生溢出,导致识别了另一个语言 C={0n1m|n mod max=m mod max} ,其中,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,某计算机有232 个8bit的cell,每个cell有 28 种取值,所以,所有存储的取值有 (28)232 种,也就是,这台计算机的存储只能有 (28)232 种状态,这就使得把计算机转为DFA变为可能

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

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

  • 输入字符表是{0,1} ,将所有计算机接受的输入全部编码成bit 串后读入该DFA,每次读一个0或者一个1

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

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

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

计算机可以死循环,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) 是一个集合,集合中元素不重复,而ε 环所到达的状态必然是重复的,所以就把ε 环断开了

阅读更多
换一批

没有更多推荐了,返回首页