本文非原创,附原文链接http://www.ituring.com.cn/article/128275
一、设计进行逻辑运算的图灵机
M=(Q,Σ,Γ,δ,q0,qaccept,qreject)
其中Σ={0,1,+, *, !};Γ={□,0,1,+,*,!}
符号“+”、“*”“!”分别表示或、与、非逻辑运算。带子Γ的书写格式为“!x” “+xy”“*xy”,即先写运算符,后写参加运算的数。还要求运算式之间以“□□□□”间隔。下表是我们建立的图灵机状态变化表。表中的L、R表示读写头左移一格或右移一格。每个字符占用一格。运算结束后,至少要读入一个空格,再进入下一计算的开始状态。
我们设计的图灵机状态转换表如下表所示。从表中我们可以看到,这个图灵机的状态集合Q={x,y,z,z0,z1,f,f0,f1,end,erro},其中x是初始状态,end是运算结束状态,erro是停机拒绝状态。表中symbol是读写头每次读入的内容,它与m-config一起构成了定义域元素,而经过操作行为Behaviour,其中包括移动读写头和输出(打印)数据,而转化为最终状态Final m-config。这一前一后的状态转换,形成了有序的运算操作,最终在不出现错误的情况下,得到运算的结果。注意,operations一栏P0,P1,P*分别表示读写头往当前格子上写0、1和*字符,移动R或L与它们排在一起,表明了动作,同时也标明了先后顺序。
查表基本方法,应从起始状态x开始,找输入字符symbol的那一行,经过operations的操作,得到Final m-config栏的新状态;然后再以新状态为依据,在左面的m-config栏找到它,然后进行下一次的状态变换。
m-config | symbol | operations | Final m-config |
---|---|---|---|
x(确定运算) | □ | R | x |
x | ! | R | y |
x | * | R | z |
x | + | R | f |
x | 0 | R,P*,R,P*,R | erro |
x | 1 | R,P*,R,P*,R | erro |
y(逻辑非) | □ | R,P*,R,P*,R | erro |
y | 0 | R,P1 | end |
y | 1 | R,P0 | end |
y | ! | R,P*,R,P*,R | erro |
y | * | R,P*,R,P*,R | erro |
y | + | R,P*,R,P*,R | erro |
z(逻辑与) | □ | R,P*,R,P*,R | erro |
z | 0 | R | z0 |
z | 1 | R | z1 |
z | ! | R,P*,R,P*,R | erro |
z | * | R,P*,R,P*,R | erro |
z | + | R,P*,R,P*,R | erro |
z0(逻辑与) | □ | R,P*,R,P*,R | erro |
z0 | 0 | R,P0 | end |
z0 | 1 | R,P0 | end |
z0 | ! | R,P*,R,P*,R | erro |
z0 | * | R,P*,R,P*,R | erro |
z0 | + | R,P*,R,P*,R | erro |
z1(逻辑与) | □ | R,P*,R,P*,R | erro |
z1 | 0 | R,P0 | end |
z1 | 1 | R,P1 | end |
z1 | ! | R,P*,R,P*,R | erro |
z1 | * | R,P*,R,P*,R | erro |
z1 | + | R,P*,R,P*,R | erro |
f(逻辑或) | □ | R,P*,R,P*,R | erro |
f | 0 | R | f0 |
f | 1 | R | f1 |
f | ! | R,P*,R,P*,R | erro |
f | * | R,P*,R,P*,R | erro |
f | + | R,P*,R,P*,R | erro |
f0(逻辑或) | □ | R,P*,R,P*,R | erro |
f0 | 0 | R,P0 | end |
f0 | 1 | R,P1 | end |
f0 | ! | R,P*,R,P*,R | erro |
f0 | * | R,P*,R,P*,R | erro |
f0 | + | R,P*,R,P*,R | erro |
f1(逻辑或) | □ | R,P*,R,P*,R | erro |
f1 | 0 | R,P1 | end |
f1 | 1 | R,P1 | end |
f1 | ! | R,P*,R,P*,R | erro |
f1 | * | R,P*,R,P*,R | erro |
f1 | + | R,P*,R,P*,R | erro |
end(正常结束) | □ | R,L,R | x |
end | 0 | erro | |
end | 1 | erro | |
end | ! | erro | |
end | * | erro | |
end | + | erro | |
erro(错误) | □ | erro | |
erro | 0 | erro | |
erro | 1 | erro | |
erro | ! | erro | |
erro | * | erro | |
erro | + | erro |
二、计算实例
如何通过这张状态转换表来进行逻辑运算?
例如,我们要计算逻辑值1和0的与运算和或运算结果。先可以在带子上安格写入:
□□□□*10□□□□+10□□□□
这里要用4个空格区分两组运算,这是设计的规定。
第一步:初始化时读写头定在最左边的位置。开始状态是x,读写头会读入的一个空格“□”,组成Q×Γ上的一组“x和 □”,向右查找,在operations栏有R,这是让读写头右移一格,移动后进入了下一个状态x。
第二步:从表上看,“x和 □”成为查找条件的得到下一个状态仍然是x的情况,要重复4次。
第三步:读写头将读到“*”,根据表中“x和*”状态的选择规定,应现将读写头右移,并决定出下一个状态“z”。
第四步:要到左边状态栏找到“z”,这时读写头会读入“1”。依据“z 和1”向右面操作栏见到“R”,这是将读写头右移一位的控制操作,并在下一个状态栏找到状态z1。
第五步:回头再到左边栏找到状态“z1”,这时读写头将读到“0”。这要依据“z1和0”一行的操作“R,P0”现将读写头右移一位,然后在空格位置写上“0”,并进入到“end”状态。
第六步:左面的“end”状态若有读写头读进空格,则依“end和□”行,可见到操作项是“R,L,R”,这是晃动读写头,表示运算结束,前面写出的“0”就是1和0做与运算的结果。此次变换得到的状态是x。
第七步:End状态并不是停机状态,从转换的新状态x开始,又返回到图灵机开始运行的状态,进入了下一个运算过程。
以上七步是进行逻辑与运算的过程。逻辑或运算的过程步基本相同。逻辑非运算因为只有一个数参加运算,故步骤少一些。
从这个逻辑运算的图灵机来看,停机和拒绝是一个概念,而图灵机的接受概念与计算得到结果,或计算完成是同一概念。
此图灵机对拒绝的问题采用连续输出两个星号表示。具体是:如果读写头读入的是的数据和状态组成的二元组找不到下一个状态,那么会连续打印出“**”,表明带子上的输入有误,并且会进入“erro”状态,拒绝继续执行,同时停机。