在计算理论中,为了建立一个易于处理的数学理论,我们采用称为计算模型(computational model)的理想计算机来描述。本文从最简单的模型开始,它称为有穷状态机(finite state machine)或有穷自动机(finite automaton)。
如果想进一步了解本文所述知识,可以参阅机械工业出版社《计算理论导引》第一部分第一章。
有穷自动机
有穷自动机是描述能力和资源极其有限的计算机的模型。但是一台存储如此少的计算机也能完成很多有用的事情了。事实上,我们的日常生活中处处都有它的应用场景。
如下图所示,假设我们有一扇门,门只能向右侧单向打开。左侧是门的前缓冲区,右侧是门的后缓冲区。当前缓冲区检测到有人的时候,门就会打开以允许人流通过。当后缓冲区检测有人的时候,门会保持当前的状态以防止碰到后面的人。
现在有一个控制器去控制这一扇门。控制器有且仅有两个状态:开(OPEN)、关(CLOSED)。我们有四种可能的输入:FRONT(仅前缓冲区有人)、REAR(仅后缓冲区有人)、BOTH(前后缓冲区都有人)、NEITHER(前后缓冲区都没人)。
控制器根据它的输入从一个状态转移到另一个状态。当它处于CLOSE状态且接收到输入FRONT时,转到OPEN状态,否则仍处于CLOSED状态;当它处于OPEN状态且接收到输入NEITHER时,转到CLOSED状态,否则保持OPEN状态。
用有穷自动机理论来处理这一控制器是很好的方法。下图是用有穷状态机表述的控制器。它是一台存储器只有一位的计算机,因为这就足以记录其所处的状态了。而另外一些设备可能具有容量稍微大一点的存储器,比如电梯的控制器等等。
下面用一个更加抽象化的例子来描述一个有穷状态机,我们假设它叫 MMM 。下图被称为 MMM 的状态图(state diagram),它有三个状态,记作 q1,q2,q3q_1,q_2,q_3q1,q2,q3 。起始状态(start state) q1q_1q1 用一个指向它的无出发点的箭头表示,接受状态(accept state) q2q_2q2 带有双圈。从一个状态指向另一个状态的箭头称为转移(transition)。
当这个自动机接收到输入字符串,例如 110111011101 时,它处理这个字符串并且产生一个输出。输出是接受或拒绝。处理从 MMM 的起始状态开始。自动机从左至右一个接一个地接收输入字符串的所有符号。读到一个符号之后, MMM 沿着标有该符号的转移从一个状态移动到另一个状态。当读到最后一个符号时产生输出。
例如,输入 110111011101 , MMM 的处理步骤如下:
- 开始时处于状态 q1q_1q1 。
- 读到 111 ,状态从 q1q_1q1 转移到 q2q_2q2 。
- 读到 111 ,状态从 q2q_2q2 转移到 q2q_2q2 。
- 读到 000 ,状态从 q2q_2q2 转移到 q3q_3q3 。
- 读到 111 ,状态从 q3q_3q3 转移到 q2q_2q2 。
- 输出接受,因为在输入字符串的末端 MMM 处于接受状态 q2q_2q2 。
用这台机器对各式各样的输入字符串进行检验,得知它接受且仅接受在最后一个 111 的后面接偶数个 000 的 010101 串。若 AAA 是 MMM 接受的全部字符串集合,则称 AAA 是机器 MMM 的语言,记作 L(M)=AL(M)=AL(M)=A 。又称 MMM 识别 AAA 。一台机器可能接受若干字符串,但是它永远只能识别一个语言。如果机器不接受任何字符串,那么它仍然识别一个语言,即空语言 ∅\varnothing∅ 。
下面给出有穷自动机的形式化定义。
有穷自动机是一个五元组 (Q,Σ,δ,q0,F)(Q,\Sigma,\delta,q_0,F)(Q,Σ,δ,q0,F) ,其中
- QQQ 是一个有穷集合,称为状态集。
- Σ\SigmaΣ 是一个有穷集合,称为字母表。
- δ:Q×Σ→Q\delta:Q\times \Sigma\rightarrow Qδ:Q×Σ→Q 是状态转移函数。
- q0∈Qq_0\in Qq0∈Q 是初始状态。
- F⊆QF\subseteq QF⊆Q 是接受状态集合。
设 M=(Q,Σ,δ,q0,F)M=(Q,\Sigma,\delta,q_0,F)M=(Q,Σ,δ,q0,F) 是一台有穷自动机, w=w1w2⋯wnw=w_1w_2\cdots w_nw=w1w2⋯wn 是一个字符串且 wi∈Σ,∀iw_i\in \Sigma,\forall iwi∈Σ,∀i 。如果存在状态序列 r0,r1,⋯ ,rn∈Qr_0,r_1,\cdots,r_n\in Qr0,r1,⋯,rn∈Q 满足下述条件:
- r0=q0r_0=q_0r0=q0
- δ(ri,wi+1)=ri+1,i=0,⋯ ,n−1\delta(r_i,w_{i+1})=r_{i+1},i=0,\cdots,n-1δ(ri,wi+1)=ri+1,i=0,⋯,n−1
- rn∈Fr_n\in Frn∈F
则称 MMM 接受 www 。
如果 A={ w∣M 接受 w}A=\{w\vert M\text{ 接受 }w\}A={ w∣M 接受 w} ,则称 MMM 识别语言 AAA 。
如果一个语言被一台有穷自动机识别,则称它是正则语言(regular language)。
下面介绍正则语言上的运算。
设 AAA 和 BBB 是两个语言,定义正则运算并(union)、连接(concatenation)和星号(star)如下:
- 并:A∪B={ x∣x∈A∨x∈B}A\cup B=\{x\vert x\in A \vee x \in B\}A∪B={ x∣x∈A∨x∈B}
- 连接: A∘B={ xy∣x∈A∧y∈B}A\circ B=\{xy \vert x \in A \wedge y \in B\}A∘B={ xy∣x∈A∧y∈B}
- 星号: A∗={ x1x2⋯xk∣k∈N∗∧(∀i)(xi∈A)}A^*=\{x_1x_2\cdots x_k \vert k\in\mathbb{N}^*\wedge (\forall i)(x_i\in A)\}A∗={ x1x2⋯xk∣k∈N∗∧(∀i)(xi∈A)}
并运算就是把 AAA 和 BBB 中的所有字符串合并在一个语言中。连接运算以所有可能的方式把 AAA 中的一个字符串接在 BBB 中的一个字符串前面,从而产生新语言中的所有字符串。星号运算把 AAA 中的任意个字符串以任意顺序连接在一起得到新语言中的一个字符串。不管 AAA 是什么,空串 ε\varepsilonε 总是 A∗A^*A∗ 的一个成员。
正则运算都是封闭的。其中并运算的封闭性可以用构造性证明,证明过程如下:
证明:
设 M1=(Q1,Σ,δ1,q1,F1)M_1=(Q_1,\Sigma,\delta_1,q_1,F_1)M1=(Q1,Σ,δ1,q1,F1) 识别语言 A1A_1A1 , M2=(Q2,Σ,δ2,q2,F2)M_2=(Q_2,\Sigma,\delta_2,q_2,F_2)M2=(Q2,Σ,δ2,q2,F2) 识别语言 A2A_2A2 。下面我们将构造一个识别 A1∪A2A_1\cup A_2A1∪A2 的自动机 M=(Q,Σ,δ,q0,F)M=(Q,\Sigma,\delta,q_0,F)M=(Q,Σ,δ,q0,F) 。
令 Q=Q1×Q2δ(⟨r1,r2⟩,a)=⟨δ1(r1,a),δ2(r2,a)⟩q0=⟨q1,q2⟩F={ ⟨r1,r2⟩∣r1∈F1∨r2∈F2}Q=Q_1 \times Q_2 \\ \delta(\langle r_1,r_2 \rangle,a)=\langle \delta_1(r_1,a),\delta_2(r_2,a) \rangle \\ q_0=\langle q_1,q_2 \rangle \\ F=\{\langle r_1,r_2 \rangle \vert r_1\in F_1 \vee r_2 \in F_2\}Q=Q1×Q2δ(⟨r1,r2