博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

不可解问题—停机问题证明

Posted on 2018-10-04 21:49  MwingFly  阅读(6947)  评论(0编辑  收藏  举报

图灵在1936年就指出,图灵机并不是什么都能计算。最著名的例子就是停机问题,即没有计算机能通过查看一段代码就知道自己是会永远执行下去还是会最终停止。——摘自《可能与不可能的边界:P/NP问题趣史》

前言

  我们都见过计算机屏幕上出现一个代表忙碌的小沙漏,不知道这是代表计算机死机了,还是在进行长时间的计算。用户该马上重启机器呢,还是再等一会儿?如果能有一个算法,告诉我们计算机是不是陷入了某种无穷循环该有多好!那是很好,但那也是不可能的。——摘自《可能与不可能的边界:P/NP问题趣史》

概念

  不可解问题(Undecidable Decision Problem)指的是这样一种问题:它无论如何也不可能有一个正确的算法来解决。虽然不可思议,但这种问题被证明确实是存在的。图灵在1936年提出了第一个不可解问题的实例:停机问题(The Halting Problem)。

  停机问题(The Halting Problem)是问,输入一段程序代码和一个针对此程序的输入,能否编程判断运行这个程序后程序是否会终止。
  这个问题的答案是否定的。也就是说,不可能有一种算法可以正确判断一个指定的程序运行后,给予指定的输入,程序最后出不出得来。换句话说,停机问题(The Halting Problem)是一个不可解问题。

停机问题的直观解释

  不可能设计这样一个万能程序,它能判定一切程序(包括它自己)会不会死循环。

证明

   证明过程非常简单,假设The Halting Problem是有解的,并且已经用程序实现了,那么我们只需要再编写一个程序Program Bug,就会发现存在矛盾。

  反证:既然解决The Halting Problem的算法已经实现了,那么我们一定能定义一个函数

Function Halting(a,b:input_type):boolean;

  其中,a是读入的程序源码,b是输入数据。这个函数的功能就是返回对于指定的程序源码和输入数据,程序是否能顺利退出。等价为“输入一段代码A和一个针对A的输入a,能否编程B判断A(a)是否是死循环”。
  下面编写一个程序:

Program Bug;
var
    code:input_type;
begin
   get(code);   //读入code
   if halting(code,code) then repeat until false
      else halt;
end.

  现在运行Bug这个程序,并且输入Bug这个程序本身的代码。这样,halting(code,code)其实质就是在判断这个Bug程序本身了。如果The Halting Problem认为Bug程序会正常退出,那么就让程序进入一个死循环,否则立即退出程序。矛盾产生。

造一个图灵机D  描述 
       “永远的在野派”   它 “反对 一切 当权派”
这个D 总与 当局唱 对台戏,
     它自己当权时, 自己也反对自己, 引起矛盾

图灵停机问题

问题:能不能设计一个程序P,判断出任意一个程序X是否会在输入Y的情况下陷入死循环?
设P(X,Y)表示P判断程序X在输入为Y时的结果。如果X存在死循环,那么P(X,Y)就输出一个yes。如果X不存在死循环,那么P(X,Y)就输出一个no。这样的P(X,Y)存在吗?
某个程序X在输入Y上停机,就是说X不存在着死循环;

如果不停机就是存在着死循环。

假设程序P存在。那么我们可以根据P设计一个新的程序Q如下,其中X是任何一段程序的编码:

Program Q(X){
    m=P(X,X)
    do while(m==no)//m=no意味着X不存在死循环
    ……
    ……
    enddo
    if m==yes then return;//m=yes意味着X不存在死循环
}
输入任何一段程序X,调用函数P(X,X)并得到返回值m,如果m=no,意味着P判断出程序X作用到X自身不存在死循环。那么Q就不停的做do while和enddo之间的语句。如果m=yes,表示P判断出程序X在以X为输入时存在死循环,此时,函数Q运行结束。

问Q这个程序作用到Q自身的编码上也就是Q(Q)会不会死循环呢?

假设Q(Q)会发生死循环,那么P(Q,Q)就会返回yes.也就是m=yes,因此Q函数马上结束,也就是程序Q(Q)没有发生死循环。→矛盾!

假设Q(Q)不发生死循环,那么P(Q,Q)应该返回no,也就是m=no,这样程序就会进入do while循环,而这个循环显然是一个死循环。因而Q(Q)发生了死循环。→矛盾!

无论Q(Q)会不会发生死循环,都会产生矛盾。

假设P(X,Y)能够判断任意程序X在输入Y的时候是否死循环是错误的。也就是说这样的程序P(X,Y)不存在

停机问题与停机定理

停机问题:任给图灵机程序P和一组输入数据I,是否存在单个程序,接受P和I作为其输入,并在有限步后停机,并在带上的最后做出说明,P在处理I时是否将在有限步后停止?

停机定理(1936):给定一任意的图灵机程序P和一组任意的输入数据I,不存在单个的图灵机程序,它在有限多步后停机,并告诉我们P是否结束输入数据I的处理。

证明:反证假设,存在这样一个图灵机TM(P,I),它可以判定程序P在输入I的情况下是否可停机:若P在输入I时可停机,TM(P,I)输出“停机”,否则,TM(P,I)输出“死循环”。

  显然,TM(P,I)本身可被视程序PTM,也可作为输入ITM,故TM(P,I)可以判定当将ITM作为PTM的输入时,PTM是否会停机。

  现考虑一个与TM(P,I)相反的图灵机TM-bar(P,I):首先,它调用TM(PTM,ITM)。若TM(PTM,ITM)输出“死循环”,则输出“停机”,否则输出“死循环”。

  再考虑运行TM(PTM-bar,ITM-bar)时的情形。若TM(PTM-bar,ITM-bar)输出“停机”,则它输出“死循环”若TM(PTM-bar,ITM-bar)输出“死循环”,则它输出“停机”。总产生矛盾

哥德尔定理和停机定理之间有什么关系?

  参考:康托尔、哥德尔、图灵——永恒的金色对角线

参考文献:

https://wenku.baidu.com/view/ad82e57b31b765ce05081490.html?sxts=1540116131874

http://www.matrix67.com/blog/archives/55