图灵机及图灵完备性

黄文睿

221180115 计算机拔尖班

确定性图灵机与非确定性图灵机[1]

DTM

确定性图灵机(DTM):六元组 $M=\langle Q, \Sigma, \iota, \sqcup, A, \delta\rangle$

  • $Q$ 是读写头的状态集合。
  • $\Sigma$ 是纸带字符集。
  • $\iota\in Q$ 是读写头初始状态。
  • $\sqcup \in \Sigma$ 表示空符号。
  • $A\subseteq Q$ 是结束状态。
  • $\delta: (Q\setminus A \times \Sigma)\to (Q\times \Sigma \times \lbrace L, S, R\rbrace)$ 为状态转移函数

使用形式语言的范畴,可以认为 DTM 是一个有存储结构(纸带)的有限状态自动机。

NTM

非确定性图灵机(NTM):六元组 $M=\langle Q, \Sigma, \iota, \sqcup, A, \delta\rangle$

  • $Q$ 是读写头的状态集合。
  • $\Sigma$ 是纸带字符集。
  • $\iota\in Q$ 是读写头初始状态。
  • $\sqcup \in \Sigma$ 表示空符号。
  • $A\subseteq Q$ 是结束状态。
  • $\delta\subseteq(Q\setminus A \times \Sigma)\times (Q\times \Sigma \times \lbrace L, S, R\rbrace)$ 为状态转移关系

可以发现 DTM 和 NTM 的区别仅在于 $\delta$ 是函数还是关系。

图灵完备性

如果一个计算模型/指令系统具有模拟一台图灵机的能力,则称它具有图灵完备性。

以下给出两种具有图灵完备性的计算模型。

Lambda 演算

Lambda 演算[2]

Lambda 演算由 Alonzo Church (Alan Turing 的博导)提出,被证明具有图灵完备性。

现在很多语言都支持函数式编程,Lambda 演算是其中的重要一环。

Lambda 演算的基本规则

Lambda 演算主要内容是“函数抽象”和“函数应用”

  • 变量:如 $x$, $y$ 等,用来表示函数参数。
  • 函数抽象:或是函数定义,如 (lambda x. (* x x)) 是一个单个参数的函数,返回参数的平方。
  • 函数应用:或是函数调用,如 ((lambda x. (* x x)) 233) 将 233 带入左边函数的参数 $x$,得到 $233^2$.

Lambda 演算 - 多元函数[3]

Lambda 演算基础版本中只提供一元函数,但是多元函数可以使用“返回函数的函数”来完成。如计算加法的二元函数:

(lambda x y. (+ x y))

可以用“函数的函数”来完成:

(lambda x. (lambda y. (+ x y)))

在应用时,可以方便地后接两个参数:

(((lambda x. (lambda y. (+ x y))), 2) 3)
or
((lambda x. (lambda y. (+ x y))), 2 3)

Lambda 与编程语言[3]

可以使用函数来编码编程语言中的基本概念,如 Boolean 和条件:

true = lambda x. lambda y. x
false = lambda x. lambda y. y
if E1 then E2 else E3 (一个三元函数) = E1 E2 E3

解释:

if false then a else b
-> false a b
-> (lambda x. lambda y. y) a b
-> (lambda y.y) b
-> b

使用 Lambda 演算

C++, Python 等许多现代编程语言均提供 Lambda 演算,更不用说一些专门的函数式语言。

相信许多同学这样写过(充当匿名函数):

sort(a, a + n, [] (int x, int y) -> bool {return x > y;});

python 中写得更顺畅一点,如加法:

>>> f = lambda x: lambda y: x + y
>>> f(2)(3)
5

Brainf**k

Brainf**k

Brainf**k 由 Urban Müller 创立,仅使用 8 种符号创立的及其简单的语言。

该机器由内存 M 和字节指针 p 构成,初始化内存全为 0。

符号 意义 符号 意义
> ++p . 输出 *p
< --p , 输入 *p
+ ++(*p) [ 下详
- --(*p) ] 下详

Brainf**k

其中 Brainf**k 提供循环格式为

A[B]C 表示

A;
while (*p) { // here meets [
    B;
} // here meets ]
C;

它是图灵完备的。

比如使用 Brainf**k 来写 Hello world

++++++++               Set Cell #0 to 8
[
    >++++               Add 4 to Cell #1; this will always set Cell #1 to 4
    [                   as the cell will be cleared by the loop
        >++             Add 2 to Cell #2
        >+++            Add 3 to Cell #3
        >+++            Add 3 to Cell #4
        >+              Add 1 to Cell #5
        <<<<-           Decrement the loop counter in Cell #1
    ]                   Loop until Cell #1 is zero; number of iterations is 4
    >+                  Add 1 to Cell #2
    >+                  Add 1 to Cell #3
    >-                  Subtract 1 from Cell #4
    >>+                 Add 1 to Cell #6
    [<]                 Move back to the first zero cell you find; this will
                        be Cell #1 which was cleared by the previous loop
    <-                  Decrement the loop Counter in Cell #0
]                       Loop until Cell #0 is zero; number of iterations is 8
>>.                     Cell #2 has value 72 which is 'H'
>---.                   Subtract 3 from Cell #3 to get 101 which is 'e'
+++++++..+++.           Likewise for 'llo' from Cell #3
>>.                     Cell #5 is 32 for the space
<-.                     Subtract 1 from Cell #4 for 87 to give a 'W'
<.                      Cell #3 was set to 'o' from the end of 'Hello'
+++.------.--------.    Cell #3 for 'rl' and 'd'
>>+.                    Add 1 to Cell #5 gives us an exclamation point
>++.                    And finally a newline from Cell #6

图灵机与 P 和 NP

  • P: 在确定性图灵机上可以在多项式步内判定的语言。
  • NP: 在非确定性图灵机上可以在多项式步内判定的语言。

此处,非确定性图灵机可以认为是能够“神奇地选择最易方式”,或是“在遇到分支形成副本”,从而也就和 TC 中 NP 定义中的 certificate 不谋而合。存在的 certificate 指引确定性图灵机模拟一台非确定性图灵机走正确道路的那条分支的结果。

参考文献

[1] https://en.wikipedia.org/wiki/Turing_machine

[2] https://en.wikipedia.org/wiki/Lambda_calculus

[3] https://liujiacai.net/blog/2014/10/12/lambda-calculus-introduction/

谢谢大家!