理解图灵机及其边界-----------BrainFuck之道

本文参考于知乎上的RanC前辈
相关内容地址:https://www.zhihu.com/question/20115374/answer/288346717

=============================正文==================================
本文主要探讨5个问题:
1.什么是图灵机
2.图灵机可以解决什么问题
3.图灵机不能解决什么问题
4.什么是图灵完备
5.直观理解图灵完备——Brainfuck语言

1.什么是图灵机?

图灵机(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,并向右移一格。此外,令下一状态为运行。”这样的命令。其实某种意义上,这个指令集就对应着程序员所写下的程序了。
    理解图灵机及其边界-----------BrainFuck之道_第1张图片
    在计算开始前,纸带可以是完全空白,也可以在某些格子里预先就有写上部分字符作为输入。运算开始时,读写头从某一位置开始,严格按照此刻的配置(configuration),即:
  • 当前所处位置
  • 当前格子内容
    来一步步的对照着指令集去进行操作,直到状态变为停止,运算结束。而后纸带上留下的信息,即字符的序列(比如类似“…011001…”)便作为输出,由人来解码为自然语言。
    要重申一下,以上只是图灵机模型的内容,而非具体的实现。所谓的纸带和读写头都只是图灵提出的抽象概念。为便于理解 打一个比方。算盘虽然不是图灵机(因为它没有无限长的纸带,即无限的存储空间),但它的行为与图灵机一致。每一串算珠都是纸带上的一格,一串算珠上展示的数字便记录着当前格中的字符(可以是空白,可以是 12345 )。人类的手即是读写头,可以更改每串算珠的状态。算盘的运行遵循人脑中的算法,当算法结束,算盘停机。

2.图灵机可以解决什么问题?

在文章中,图灵所做的事是证明了,假设上述模型里所说的功能都能被以某种形式物理实现,那么任意可计算问题都可以被解决。这里所说的可计算问题,涉及到计算理论(Computation Theory)的概念。这个领域的概念很繁杂,先简单梳理一下。
在计算机领域,或者说自动机领域,我们研究的一切问题都是计算问题(Computational Problem)。它泛指一切与计算相关的问题。

在计算机领域,或者说自动机领域,我们研究的一切问题都是计算问题(Computational Problem)。它泛指一切与计算相关的问题。
计算问题的一些举例:

  1. 给定一个正整数 n,判断它是否是质数
  2. 给定一个 01 序列,把它们按位取反
  3. 给定一个字符串,判断某个字符是否存在,及查找存在位置
  4. 给定一个逻辑蕴含的命题,求它的逆否命题
    并且从对文法的表现力上看:Turing Machine > Pushdown automaton > NFA

3.图灵机不能解决什么问题?

https://www.youtube.com/watch?v=92WHN-pAFCs
【这个视频是关于图灵机不能解决的问题】
大名鼎鼎的关于图灵机不能表达的一个问题是停机问题(Halting Problem)
看完的朋友就不用看我的解释了
首先假设有一台图灵机A,他能接受数字Input然后output:that‘s a number
又有一台图灵机B,他能接受字符串input然后output:that‘s a string
如果给A,B标准输入不同的输入类型,那么输入错误类型的图灵机就会Stuck(机器嗡嗡嗡卡住了)
好,那么咋办呢?
又有了一台图灵机C,他能给定两个输入一个是图灵机的类型,一个是图灵机的输入,判定给定的图灵机的输入是否会造成这个图灵机类型Stuck,如果会则输出一个Stuck,否则输出一个Not Stuck
好了,让我们开始演示这个Halting Problem

实验器材:图灵机C,图灵机D,图灵机E

图灵机C就是上面提到的图灵机C,图灵机D接受一个输入然后输出两个相同的输入,图灵机E为输入一个Stuck输出:),或者输入一个Not Stuck,此时图灵机E就进入了Stuck(嗡嗡嗡的卡住了)

实验步骤:
  1. 将图灵机C,图灵机D,图灵机E连接起来,顺序为InputD->OutputD->InputC->OutputC->InputE->OutputE,
    ->的意思是连接比如OutputD->InputC是指将输出D作为输入给C
  2. 将上述连接打包(wrap),命名为图灵机F
  3. 此时图灵机F有一个输入一个输出(原图灵机D的输入,图灵机E的输出),此时输入一个图灵机类型F
  4. 类型F经过图灵机D输出为两个图灵机F类型,用以输入图灵机C,图灵机C分析输入的第一个参数是图灵机类型F,第二个参数是针对该类型机器的输入,在这里是图灵机F类型。此时假设输出的是Stuck,那么图灵机E就会输出一个:),这与图灵机C的分析不符合,假设输出的是Not Stuck,那么图灵机E就会Stuck,这也与图灵机C的分析不符合,至此证明结束,不存在这样的图灵机使得给定一个描述和一个有效输入判定程序最终会正常停止还是会陷入Stuck
    诸如此类的Undecidable Problem是无法通过图灵机解决的。

4.什么是图灵完备?

Formal definitions[edit]
In computability theory, several closely related terms are used to describe the computational power of a computational system (such as an abstract machine or programming language):

Turing completeness
A computational system that can compute every Turing-computable function is called Turing-complete (or Turing-powerful). Alternatively, such a system is one that can simulate a universal Turing machine.
Turing equivalence
A Turing-complete system is called Turing equivalent if every function it can compute is also Turing computable; i.e., it computes precisely the same class of functions as do Turing machines. Alternatively, a Turing-equivalent system is one that can simulate, and be simulated by, a universal Turing machine. (All known Turing-complete systems are Turing equivalent, which adds support to the Church–Turing thesis.)
(Computational) universality
A system is called universal with respect to a class of systems if it can compute every function computable by systems in that class (or can simulate each of those systems). Typically, the term universality is tacitly used with respect to a Turing-complete class of systems. The term “weakly universal” is sometimes used to distinguish a system (e.g. a cellular automaton) whose universality is achieved only by modifying the standard definition of Turing machine so as to include input streams with infinitely many 1s.

以上是wikipedia的定义
我的理解是图灵完备是对数据规则的描述。比如各种图灵完备语言C、Java、C++等以及CPU指令集是访问和修改数据的正式规则系统的例子。只要这些规则可以用来模拟图灵的假想计算机,那么这些规则就被图灵完备。而图灵完备的系统可以通过数学证明能够访问任何可能的计算或计算机程序。

有一类图灵完备的系统称作lambda calcullas,是图灵的导师Alonzo Church,相信对各位熟悉函数式编程的朋友一定不陌生。

5.直观理解图灵完备——Brainfuck语言

首先介绍一下语言的语法,很简单,就8个字符(实现编译器也比较轻量级),简单介绍一下语法(用于对应图灵机中的有限指令集)

> 指针加一
< 指针减一
+ 指针指向的字节的值加一
– 指针指向的字节的值减一
. 输出指针指向的单元内容(ASCII码)
, 输入内容到指针指向的单元(ASCII码)
[ 如果指针指向的单元值为零,向前跳转到对应的]指令的次一指令处
] 如果指针指向的单元值不为零,向回跳转到对应的[指令的次一指令处

++++++++[>++++[>++>+++>+++>+<<<<-]>+>+>->>+[<]<-]>>.>---.+++++++..+++.>>.<-.<.+++.------.--------.>>+.>++.

上面这段代码的运行结果是Hello World!
为什么说它和图灵机工作方式高度一致?
首先它存储数据的方式是一个不限长的一维整数数组(用于模拟图灵机无限长的纸带),里面的数值全部初始化为 0。此外,有一数据指针(模拟读写头),每一时刻都指向数组的某一任意元素。指针可以向左/右移动,也可以读取/修改当前值。(状态寄存器的模拟可以由编译器提供,后续有时间我会试着写一个)
这里有知乎一位ID名为贺小钿的前辈提供的演示地址
http://fatiherikli.github.io/brainfuck-visualizer/
这个项目可以演示指针的读取,流程的分支的控制
这里为不方便看的朋友一个demo

+++++

[
>+++++++++++++
<-
]

>.

这里写图片描述
简要描述一下这段代码:
首先初始化所有格子并设置value为0,将第一个格子命名为cell0,cell0右边的依次命名加1,第一句+++++,将cell0设置为5,然后右移指针将cell1递增13次,然后左移指针递减一次,因为在“]”时,cell0的值不为0所以跳转到”[“处,依次类推5次,直到将cell1的值设置为A,然后跳出循环,通过>.右移指针到cell1并输出asell编码下的65 (‘A’)
至此,各位朋友是否对图灵机的模拟有点感觉了呢?

你可能感兴趣的:(----------编程语言)