图灵完备(Turing completeness)
在可计算性理论中,如果一个数据操作规则系统(如计算机的指令集、编程语言或细胞自动机)可以用来模拟任何图灵机器(由英国数学家和计算机科学家阿兰·图灵(Alan Turing)设计),则称其为图灵完备(Turing-complete)或计算通用的。
图灵等价(Turing equivalence)
若P可以模拟Q,Q可以模拟P,那个么这两个数据操作规则系统P和Q就是图灵等价的。
图灵机(Turing machine)
图灵机(Turing Machine)是图灵在1936年发表的 《论可计算数及其在判定性问题上的应用》(《On Computable Numbers, with an Application to the Entscheidungsproblem》)中提出的数学模型。
图灵机的结构包括以下几个部分:
- 一条无限长的纸带(tape),纸带被分成一个个相邻的格子(square),每个格子都可以写上至多一个字符(symbol)。
- 一个字符表(alphabet),即字符的集合,它包含纸带上可能出现的所有字符。其中包含一个特殊的空白字符(blank),意思是此格子没有任何字符。
- 一个读写头(head),可理解为指向其中一个格子的指针。它可以读取/擦除/写入当前格子的内容,此外也可以每次向左/右移动一个格子。
- 一个状态寄存器(state register),它追踪着每一步运算过程中,整个机器所处的状态(运行/终止)。当这个状态从运行变为终止,则运算结束,机器停机并交回控制权。如果你了解有限状态机,它便对应着有限状态机里的状态。
- 一个有限的指令集(instructions table),它记录着读写头在特定情况下应该执行的行为。可以想象读写头随身有一本操作指南,里面记录着很多条类似于“当你身处编号53的格子并看到其内容为0时,擦除,改写为1,并向右移一格。此外,令下一状态为运行。”这样的命令。其实某种意义上,这个指令集就对应着程序员所写下的程序了。
在计算开始前,纸带可以是完全空白,也可以在某些格子里预先就有写上部分字符作为输入。运算开始时,读写头从某一位置开始,严格按照此刻的配置(configuration),即:
- 当前所处位置
- 当前格子内容
来一步步的对照着指令集去进行操作,直到状态变为停止,运算结束。而后纸带上留下的信息,即字符的序列(比如类似“…011001…”)便作为输出,由人来解码为自然语言。
停机问题(Halting Problem)
在可计算性理论中,停机问题是根据对任意计算机程序和输入的描述,确定程序是否将完成运行,还是将永远继续运行的问题。阿兰·图灵在1936年证明,解决所有可能的程序输入对的停机问题的通用算法不存在。
自动机(Automation)
自动机是有限状态自动机(Finite State Machine,FSM)的数学模型。有限状态自动机是给定符号输入,依据(可表达为一个表格的)转移函数“跳转”过一系列状态的一种机器。
- 有限状态自动机(Finite Automata,FA)
- 确定有限自动机(Deterministic Finite Automata,DFA)
自动机的每个状态都有对字母表中所有符号的转移。 - 非确定有限自动机(Non-deterministic Finite Automata,NFA)
自动机的状态对字母表中的每个符号可以有也可以没有转移,对一个符号甚至可以有多个转移。
上述自动机接受的语言家族被称为正规表达式(Regular Expression)
- 确定有限自动机(Deterministic Finite Automata,DFA)
- 下推自动机(Pushdown Automation,PDA)
下推自动机额外的装备了栈形式的内存。下推自动机是一种实现上下文无关语法的方式。 - 线性有界自动机(Linear Bounded Automation,LBA)
线性有界自动机是有限制的 图灵机;不使用无限磁带,它的磁带有同输入字元串成正比的空间。线性有界自动机接受上下文有关语言。 - 图灵机(Turing Machine)
图灵机是最强力的自动机。图灵机拥有磁带形式的无限内存,和可以读取和变更磁带的磁头,它可在磁带上向任何方向移动。图灵机等价于演算法,可以用来判定递归语言并识别递归可枚举语言。
Brainfuck 语言
在1993年,Urban Müller 发明了 Brainfuck 语言。这门语言可以说是编程语言界的 helloworld 了——它一共只含有 8 个有效字符,每个有效字符就是一条指令。语言虽然极致轻量,它却是一门图灵完备的编程语言。
语言里的 8 个有效字符分别是:
>
指针向右移动一格<
指针向左移动一格+
使指针当前格数值加一-
使指针当前格数值减一.
把当前格数值按 ASCII 表输出到终端,
从终端接受 1 byte 的数据,存储其 ASCII 数值到当前格[
当指针当前值为 0 时,程序跳转至与之对应的]
之后;否则程序正常执行]
程序跳转回与之对应的[
处
brainfuck-visualizer 提供了 Brainfuck 的可视化解析过程。
Brainfuck 的 8 个指令可以等价的转换为 C/C++ 语言语法:
Brainfuck | C |
---|---|
> |
++ptr; |
< |
--ptr; |
+ |
++*ptr; |
- |
--*ptr; |
. |
putchar(*ptr); |
, |
*ptr=getch(); |
[ |
while(*ptr){ |
] |
} |
1 | string translate(char c) { |