从编译器充分就业定理谈一下停机问题

Posted 放不下筷子的程序员

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了从编译器充分就业定理谈一下停机问题相关的知识,希望对你有一定的参考价值。

前几天看到的一个非常有意思的定理就是题目所说的编译器充分就业定理,这个定理是这么说的,假设存在一个完美的编译器和一个存在死循环的程序,那么这个编译器应该可以把该程序中的死循环优化成while(true),显然,这样的编译器就解决了停机问题,但停机问题从数学上证明是不能用计算机解决的,所以不存在完美的编译器,即编译器永远有进步的空间,所以永远都需要从事编译器工作的程序员

那么什么是停机问题呢?说停机问题之前,我想先说一下图灵完备。图灵完备的机器可以解决所有可解问题,即任何图灵完备的机器逻辑上是等价。那么是否存在一类问题不能通过图灵机解决呢?即是否存在不可解问题呢?这种问题显然是存在的,上面提到的停机问题就是这类问题中其中最为著名的一个。停机问题是说判断一个程序能否在有限的时间之内结束的问题,这也就等价于存在一个程序H他能够判断一段程序P在有限时间内结束或者死循环。所以如果存在一个完美的编译器,他若想把一个死循环优化成while(true),他首先要识别出死循环,这显然就解决了停机问题。而停机又是不能够被计算机解决的,所以...!禁止套娃!所以停机问题到底是怎么证明的呢?下面给出一个我认为比较好理解的一个证明。(以下证明过程抄自该篇博客 [1] ,害,因为原博主写的实在是太好了,实在不知道该怎么用自己话说出来。虽然没人看,我也加一句侵删吧...


假设存在这样的一个函数H来判断一个程序P在输入为I情况下是否会停机,最后使用反证法,证明不存在这样的H

int H(P, I){ if(P停机) return 0; else return 1;}

这段伪代码是说如果P在输入I的情况下停机函数H返回0,如果死循环返回1。


下面的这个概念对理解这段证明至关重要,即程序本身也是一种数据,因此他也可以作为输入。原博主给出的例子是Pascal的编译器本身就可以用Pascal所写成。其实不仅Pascal这样,理论上所有语言的编译器都可以如此。用一个名词来说就是编译器的自举,改天有时间再写一写关于编译器自举的问题。


扯远了,因为程序本身也是一种数据,它也可以作为输入,所以H应该可以判定在将P作为P的输入时,P是否会停机,即int H(P,  P);

然后我们再定义一个过程U(P),其流程如下:

如果H(P,P)判断结果为死循环,U(P)就停机。

如果H(P,P)判断结果为停机,U(P)就是进入死循环。

以下是U的伪代码:
int U(P){ if (H(P,P) == 1){ // 如果H死循环 return 0; // 此时U会停机 }else{ // 否则 while(1){} // 此时U会死循环 }}
如果我们把上面的P换成U呢?即:
int U(U){ if (H(U, U) == 1){ // 如果H死循环 return 0; // 此时U会停机 }else{ // 否则 while(1){} // 此时U会死循环 }}

    

此时矛盾就出现了,H函数判断U在输入为U情况下是死循环时,U却会停机。而当H判断U是停机时,U却进入了死循环。所以,不存在这么牛逼的程序H。即停机问题为不可解问题。

呜呜呜,写到这里我又去百度百科看了停机问题,原来原博主的证明思路出自Kenneth H. Rosen著的《离散数学及其应用》,这难道就是传说中的天下文章一大抄,算了算了睡觉去了,不改了就这样吧。

[1]https://blog.csdn.net/u014073556/article/details/86382019

以上是关于从编译器充分就业定理谈一下停机问题的主要内容,如果未能解决你的问题,请参考以下文章

浅谈欧拉定理及乘法逆元

千锋Java就业老师分享 程序员面试谈薪技巧

从c++标准库指针萃取器谈一下traits技法

从c++标准库指针萃取器谈一下traits技法

从c++标准库指针萃取器谈一下traits技法

从“杀鸡焉用宰牛刀”谈充分必要条件