跳转至

Lecture 4. Turing Machines 图灵机

图灵机与有穷自动机的区别

  1. 图灵机既能读也能写
  2. 图灵机的读写头,可以向左右两边移动(但是只能挪一个格子)
  3. 图灵机的带子长度无限
  4. 图灵机进入接受状态或拒绝状态则立即停机
  5. 图灵机在任意时刻都可以进入接受或拒绝状态,不一定是要在输入结束的时候

图灵机形式化定义

图灵机是一个七元组 $\left( Q, \Sigma, \Gamma, \delta, q_0, q_{\text{accept}}, q_{\text{reject}} \right)$,其中,$Q, \Sigma, \Gamma$ 都是有穷集,且:

  1. $Q$ 是状态集
  2. $\Sigma$ 是输入字母表。特殊空白符号 $\sqcup \not \in \Sigma$
  3. $\Gamma$ 是纸带的字母表。输入字母表是纸带字母表的子集,即 $\Sigma \subseteq \Gamma$ 且特殊空白符号 $\sqcup \in \Gamma$(于是应该能推出 $\Sigma \subset \Gamma$)。
  4. $\delta: Q \times \Gamma \rightarrow Q \times \Gamma \times \{L, R\}$ 是转移函数。即:当机器处于状态 $q$,读写头所在的带子位置的符号是 $a$,则当 $\delta(q, a) = (r, b, L/R)$ 时,机器写下符号 $b$ 来取代 $a$,进入状态 $r$,并让 读写头 向左或者向右移动。更进一步:如果要弄一个非确定性的图灵机,把转移函数改成 $\delta: Q \times \Gamma \rightarrow \mathcal{P}\left(Q \times \Gamma \times \{L, R\}\right)$,也就是像 DFA 到 NFA 或者 PDA 到 NPDA 的转变一样,弄一个幂集出来,这样每一步的转移都可以是一个集合,意味着有多个分支。
  5. $q_0 \in Q$ 是起始状态,$q_{\text{accept}} \in Q$ 是接受状态,$q_{\text{reject}} \in Q$ 是拒绝状态,且 $q_{\text{accept}} \not= q_{\text{reject}}$

初始状态下,图灵机带子上从左到右前 $n$ 个格子填写了输入串 $w_1w_2 \cdots w_n \in \Sigma ^ $,其余部分保持空白。然后读写头从 最左边 的位置开始移动(根据转移函数描述的规则)。如果读写头已经处于最左边但是还有向左移动的指令,则停在原地不动。一旦进入接受状态或拒绝状态则立即 停机(halt)*,否则永远持续运行(永远运行,即永不进入接受状态,相当于拒绝了)。

不过图灵机的这种形式化定义显得太麻烦了,所以有时候直接用自然语言描述会更简单。比如,刚刚证明过的 $B=\{0^k 1^k 2^k \mid k≥0\}$ 不是 CFL,这里设计一个图灵机来识别它。这个图灵机的工作流程可以用自然语言描述如下:

  1. 从左到右读完整个输入,直到遇到第一个 $\sqcup$ 代表输入结束。读的时候检查这个读入是否是 $0^*1^*2^*$ 的形式。如果不是,立即拒绝
  2. 读写头回到左端点
  3. 从左往右扫描。将第一个 $a, b, c$ 划掉(即用 $\not a, \not b, \not c$ 来代替,不是擦除):
  4. 如果替换的 $a, b, c$ 都是最后一个,则进入接受状态
  5. 如果 $a, b, c$ 当中,有的是最后一个,有的不是最后一个,意味着数量不相等,进入拒绝状态
  6. 如果 $a, b, c$ 都还有剩余,则重复这个过程

一点新概念

图灵机 $M$ 接受的字符串的集合,就是被 $M$ 识别的语言,记作 $L(M)$。

如果一个语言能被图灵机识别,则称这个语言是 图灵可识别的(Turing-recognizable)。此外,一个语言是图灵可识别的,当且仅当存在一台 队列自动机(queue automaton) 识别(类似下推自动机,栈换成了队列)它。此外,还有的课本,把图灵可识别的语言称为递归可枚举语言,因为一个语言是图灵可识别的,当且仅当它是递归可枚举的。

如果一个图灵机对于任何输入,都永不无限运行,则这个图灵机称为 判定器(decider)。假如判定器 $M$ 可以识别语言 $A$,则称 $M$ 判定 $A$。如果一个语言能被某个判定器判定,则称这个语言是 图灵可判定的(Turing-decidable),简称 可判定的(decidable)

图灵可判定比图灵可识别的定义更加严格,因此图灵可判定的语言的集合,是图灵可识别的语言的集合的子集。同时,CFL 也是图灵可判定的集合的子集,正则语言是 CFL 的子集。

image-20221021121735158

这张关系图会在「可判定性」章节中继续讨论。

格局

图灵机有一个新的概念叫做 格局(configuration),是指(当前状态、当前纸带内容、读写头位置)三者的结合。

格局可以用 $u, q, v$ 表示:$q$ 表示当前状态,$uv$ 是当前纸带上的字符串(即 $u$ 连接 $v$),当前的读写头在 $v$ 的第一个符号的位置,$v$ 以后的内容全都是空白符。

比如格局:$1011q_701111$ 表示:当前纸带内容是 $101101111$,状态是 $q_7$,读写头位于第二个出现的 $0$ 上。

image-20221110232923162

如果图灵机能合法的从格局 $C_1$ 一步进入格局 $C_2$,则称格局 $C_1$ 产生(yields) 格局 $C_2$。

一个图灵机 $M$ 接受输入 $w$ 的条件是,存在一个格局的序列 $C_1, C_2, \cdots, C_k$,满足以下条件:

  1. $C_1$ 是 $M$ 对于输入 $w$ 的起始格局($q_0w$)
  2. $\forall i < k, C_i$ 产生 $C_{i+1}$
  3. $C_k$ 是接受格局($uq_{\text{accept}}v$)

图灵机示例

语言 $A = \{0^{2^n} | n \geq 0\}$,即所有长度是 $2$ 的幂的仅含 $0$ 的串串。

识别这个语言的图灵机的自然语言描述如下:

  1. 从左往右扫描,每隔一个字符就划掉一个零
  2. 如果一个零都划不动,说明是 $0^{2^0}$ 的形式,接受
  3. 如果划完一遍之后,剩下奇数个零,拒绝
  4. 返回左端点,重复前三步

image-20221017105411732

  • $q_1$ 既是起始状态,也类似递归的终止条件:必须遇到至少一个$0$,否则直接拒绝;一旦遇到 $0$ 就进入 $q_2$
  • $q_2$:$q_2$ 这个状态没有确定的是奇数还是偶数。第一次走到 $q_2$ 状态意味着当前已经遇到了确切的一个 $0$,所以不停往右边走,如果被叉掉了就跳过,一旦遇到 $0$ 就进入偶数状态 $q_3$;遇到右端点说明 $0$ 的个数是恰好一个,符合递归终止条件,接受。如果是从 $q_5$ 回来的,这时候 $q_2$ 的状态就变成了偶数个零,因为 $q_5$ 是从 $q_3$ 来的。
  • $q_3, q_4$:$q_3$ 是已经遇到偶数个 $0$ 的状态,$q_4$ 是奇数个 $0$ 的状态,两个奇偶互补,每隔一个 $0$ 叉掉一个,同时右移;$q_3$ 如果叉掉一个之后遇到右端点则进入 $q_5$,$q_4$ 遇到右端点说明 $0$ 的个数不是偶数,拒绝
  • $q_5$:$q_5$ 不管读到什么东西,都一直往左边跑,直到回到最左端点,进入 $q_2$ 状态

格局表如下。要记得格局的表示形式:$q_x$ 后面紧跟的才是当前读写头的位置。

image-20221017105421482

图灵机的变形

多带图灵机 Multi-tape Turing Machine

转移函数发生变化。对于 $k$ 条纸带的图灵机,转移函数是:$\delta: Q \times \Gamma^k \rightarrow Q\times \Gamma^k \times \{L,R,S\}^k$,其中 $S$ 是 stay 的意思,就是保持不动。也有的教材认为 $\delta: Q \times \Gamma^k \rightarrow Q\times \Gamma^k \times \{L,R\}^k$,就是必须挪走。

定理:每一个多带图灵机,都等价于一个单带图灵机。也就是可以用一个单带图灵机去模拟多带图灵机

单带图灵机当中,用 $\#$ 来作为分隔符(delimiter),分割所有的纸带;头顶上有一圆点的表示每个纸带的读写头所在的字符。

image-20221017110629248

然而单带图灵机的控制器 S 会比多带图灵机的控制器 M 麻烦不少。

推论:一个语言是图灵可识别的,当且仅当存在一个多带图灵机识别它。

非确定性图灵机 Nondeterministic Turing Machine

转移函数变成了:$\delta: Q \times \Gamma \rightarrow \mathcal{P}\left(Q \times \Gamma \times \{L, R\}\right)$,幂集表示非确定性

像 NFA 一样,非确定性图灵机的计算过程,也可以想象为一棵多叉树。不仅如此,每个非确定性图灵机和确定性图灵机也是等价的,即:每个非确定性图灵机也可以转化为一个确定性图灵机(状态个数变成 2 的幂)。

下图表示用确定性图灵机模拟非确定性图灵机。

image-20221017111401029

推论:一个语言是图灵可识别的,当且仅当存在一个非确定性图灵机识别它。

推论:一个语言是可判定的,当且仅当存在一个非确定性图灵机判定它。

枚举器 Enumerator

枚举器就是附带了一个打印机的图灵机。打印机相当于一个输出设备。

枚举器的工作过程:

  1. 以空白输入的纸带开始运行
  2. 如果不停机,可能会打印出来无限多个串
  3. 枚举器 $E$ 所枚举的语言是最终打印出的所有串串的集合
  4. $E$ 生成的串是任意顺序的,可能会有重复

定理:一个语言是图灵可识别的,当且仅当存在一个枚举器可以枚举它

要证明当且仅当,需要从两个方向证明。

  • 首先正向证明:如果有一个枚举器 $E$ 枚举语言 $A$,则能找到一个图灵机 $M$,识别这个枚举器枚举的语言。这个图灵机 $M$ 是这样的(对于输入串 $w$)

  • 运行枚举器 $E$。每当 $E$ 打印了一个串,则与输入比较

  • 一旦找到相同的,就接受

于是很显然的,$M$ 接受所有能被 $E$ 打印的串。证毕。

  • 然后反向证明:如果有一台图灵机识别语言 $M$,则能找到一个枚举器 $E$ 可以枚举 $A$。这个枚举器的构造如下(忽略掉输入串):

  • 假设 $s_1, s_2, s_3, \cdots, s_i \in \Sigma ^*$ 是所有可能的串串,对于 $i=1, 2, 3, \cdots$,重复以下步骤:

  • 对于 $s_1, s_2, s_3, \cdots$ 当中的每一个,$M$ 以其作为输入串,运行 $i$ 步。这大概是为了避免图灵机死循环
  • 如果有计算接受,则打印出相应的 $s_j$
  • 刚才这一坨看起来很麻烦,反正大概意思就是对于所有串串都运行一下图灵机 $M$,接受的全都输出

算法的定义

丘奇使用称为 $\lambda$ 演算($\lambda$-calculus)的记号系统(notation system)来定义算法,图灵用图灵机来定义算法。这两个定义事实上是等价的。这两者之间的联系,叫做 丘奇图灵论题 Church-Turing Thesis

令 $D = \{p \mid p \text{ 是有整数根的多项式}\}$,希尔伯特第十题要求设计一个算法,检测一个多项式是否具有整数根,相当于提问:$D$ 是否是可判定的。答案是,不存在检测多项式是否具有整数根的算法,因此 $D$ 不可判定。然而,$D$ 是图灵可识别的。

先考虑简单的情形。令 $D_1 = \{p \mid p \text{ 是有整数根 } x \text{ 的多项式}\}$,下面设计一个图灵机 $M_1$ 识别 $D_1$:

  • $M_1$ 的输入是一个关于变量 $x$ 的多项式 $p$,注意多项式是可以用字符串的形式来表示的
  • 将 $x$ 赋值为 $0, 1, -1, 2, -2, 3, -3, \cdots$,不断地检查是否满足 $p=0$。如果满足,就接受。否则继续。

于是图灵机 $M_1$ 就设计出来了,因此 $D_1$ 是可识别的。然而这个图灵机可能会无限运行下去,因此不符合判定器的定义,于是 $D_1$ 不是可识别的。

假如多项式 $p$ 的变量个数不止一个,那也是类似,反正就不停的赋值然后试一下~

描述图灵机的术语 Terminology for Describing Turing Machine

描述图灵机有三种不同的级别。

  • 最低等级是形式化的描述,就一堆数学式子,写出状态和转移函数,不过是最详细的
  • 中档等级,称为 实现描述(implementation description),就是用自然语言描述图灵机怎么移动啊、怎么存储数据啊之类的,不指定状态和转移的细节
  • 最高等级,是 高层次描述(high level description),同样是用自然语言来描述,但是连实现的细节都忽略了,也就是不提及如何管理纸带和读写头,相当于描述了一个算法

图灵机的记号

图灵机输入的都是字符串。如果要以其他对象(比如多项式、图)作为输入,就需要编码成字符串。

对象 $O$ 的字符串编码,用 $\langle O \rangle$ 表示。例如:$\{ \langle G \rangle \mid G \text{ is a connected undirected graph} \}$ 表示一个语言,包含所有的联通的无向图的编码串。

这里可以使用的无向图的编码格式是:(节点列表)((边), (边), (边), ...))

image-20221020122004090

判定无向图是否联通的图灵机(判定器)的高层次描述是:

  1. 标记节点列表当中的第一个节点
  2. 重复第三步,直到无法再标记新的节点
  3. 任选一个节点,如果这个节点的一条边连接到一个已经被标记的节点,就把这个节点也标记上
  4. 检查,是否所有节点都被标记过。如果是,则接受,否则拒绝。