究竟是什么停机问题?究竟是什么停机问题?(What exactly is the halting p

2019-06-02 13:07发布

每当人们问停机问题,因为它涉及到编程,人们回应:“如果你只需要添加一个循环,你已经得到了制止程序,因此你不能自动任务

说得通。 如果你的程序有一个无限循环,那么当你的程序运行时,你有没有办法知道程序是否仍捣弄输入,或者如果它仅仅是无限循环的方式。

但一些,这似乎与直觉相反。 如果我正在写一停机问题解决者,这需要的源代码作为其输入。 rascher@localhost$ ./haltingSolver source.c

如果我的代码(由source.c)看起来是这样的:

for (;;) {  /* infinite loop */  }

现在看来似乎会是很容易为我的程序看到这一点。 “看循环,并期待在条件,如果条件正是基于文字,并没有变量,那么你总是知道循环的结果。如果有变量(例如同时(X <10)),看是否这些变量是不断修改。如果没有,那么你总是知道循环的结果“。

诚然,这些检查将不会是微不足道的(计算指针算术等),但它似乎没有不可能。 例如:

int x = 0
while (x < 10) {}

可以被检测到。 随着 - 尽管不平凡:

int x = 0
while (x < 10)
{
   x++;
   if (x == 10)
   {
      x = 0
   }
}

现在关于用户输入的是什么? 这是踢球,这是什么使一个程序难以预测。

int x = 0;
while (x < 10) 
{
   scanf("%d", &x); /* ignoring infinite scanf loop oddities */
}

现在我的计划可以说:“如果用户输入10或更大,程序将停止在其他所有输入,它再次将循环。”

这意味着,即使有数百输入一个人应该能够列出在其上的程序将停止条件。 事实上,当我写一个程序,我始终确保有人来终止它的能力! 我并不是说所产生的条件清单是微不足道的创造,但它似乎没有不可能给我。 你可以采取由用户输入,使用它们来计算指针索引,等等 - 但只是增加了条件,以确保该计划将终止数,并不能使它不可能一一列举。

那么究竟是什么停机问题? 什么是我不理解有关的想法,我们不能写检测无限循环的问题吗? 或者说,为什么是“循环”这样一个经常被引用的例子吗?

UPDATE

所以,让我改变的问题一点点: 因为它适用于计算机是什么停机问题 然后,我会的一些评论作出回应:

很多人说,该方案必须能够处理“任意输入。” 但在电脑,没有过任何任意输入。 如果我只输入数据的单个字节,比我只有2 ^ 8个可能的输入。 所以,作为一个例子:

int c = getchar()

switch (c) {
   case 'q':
      /* quit the program */
}

突然之间,我刚才占了所有的可能性。 如果c有位模式0x71,它做的一件事。 对于所有其他模式,它别的东西。 即使是接受任意字符串输入一个程序是从来没有真正“任意”,因为资源是有限的,这意味着,而“任意”的理论适用......这不是正好有一个一对一的做法。

另一个例子人引用是这样的:

while (n != 1)
    if (n & 1 == 1) 
        n = 3 * n + 1;
    else 
        n /= 2;

如果n是一个32位整数...那么我可以直观地告诉你,这是否将暂停。

我想这编辑是不是要求什么,但我见过的最有说服力的例子是这一个 :

假设你有你的神奇计划/方法来确定一个程序暂停。

public bool DeterminesHalt(string filename, string[] args){
    //runs whatever program you tell it do, passing any args
    //returns true if the program halts, false if it doesn't
}

现在让我们说我们写一小段代码,如...

public static void Main(string[] args){
    string filename = Console.ReadLine(); //read in file to run from user
    if(DeterminesHalt(filename, args))
        for(;;);
    else
        return;
}

所以在这个例子中,我们可以写一个程序来做我们的神奇制止方法做的正好相反。 如果我们以某种方式确定给定程序将停止,我们刚刚跳进一个无限循环; 否则,如果我们确定该方案是一个无限循环,我们结束程序。

话又说回来,如果你故意写一个程序,它包含一个无限循环...“解决停机问题”是一种没有实际意义的,不是吗?

Answer 1:

编辑(比原来的答案更晚):的MarkCC 好数学,数学不好最近写了一个精彩讨论停机问题结合具体实例。

停机问题是基本要求,如果你能告诉一个任意程序是否会最终停止的正规途径。

换句话说,你可以写一个程序,称为甲骨文停止,HaltingOracle(程序,输入),如果程序(输入)将最终阻止其返回true,并且如果它不会返回false?

答案是:不,你不能。

关于是否输入到停机问题问题跟进的相关性或红鲱鱼:是的,输入是非常重要的。 此外,还有似乎是正在使用中的一些困惑我看到“无限”,其中“乱”是比较正确的。

实际的例子 :假设你是在一个QA岗位工作,你写一个停止检查程序(也称为一个Oracle),将确认为通过年底提供的开发团队(d)和任意输入写任意程序 - 用户(我),给定的输入一当程序d将最终停止

提示管理器的声音 :“嗬嗬,那些愚蠢的用户,让我们确保,无论他们是什么类型的垃圾,我们的服务器任务将永远不会在一个无限循环最终使它所以,代码猴子!”

这似乎是一个好主意,对吧? 你不希望你的服务器挂了,对不对?

什么停机问题告诉你的是,你被交给一个无法解决的任务。 相反,在这种特殊情况下,你需要计划运行超过阈值的时间,并准备取消这些任务。

马克使用的,而不是输入代码来说明这个问题:

def Deciever(i):
  oracle = i[0]
  in = i[1]
  if oracle(Deceiver, i):
    while True:
      continue
  else:
    return i

在我的意见的讨论,我去恶意输入操作的路线,迫使一个无法解决的问题。 马克的例子是更为优雅,采用停止甲骨文击败本身:

因此,输入骗子实际上是两个元素的列表:第一个是建议暂停预言。 第二个是另一输入。 什么停止杀手确实是要求甲骨文:“你觉得我会停止输入我”。 如果Oracle说,“是的,你会停止”,然后程序进入一个无限循环。 如果Oracle说“不,你不会暂停”,那么它会暂停。 所以无论甲骨文说什么,这是错误的。

所述另一种方式,没有欺骗,重新格式化的输入,可数/不可数无穷大或任何其他干扰,马克写了一段代码,可以击败任何停止oracle的程序。 你不能写一个oracle ,回答的是否问题Deceiver永远停止。

原来的答案:

从大百科 :

在可计算性理论,停机问题是一个决策问题,可以作如下规定:给定一个程序的描述和有限的输入,决定给予该输入的程序是否结束运行或将永远运行。

阿兰·图灵在1936年证明了通用算法,解决了停机问题的所有可能的程序输入对不能存在。 我们说停机问题是在图灵机判定的。 科普兰(2004)属性的实际长期停机问题,马丁·戴维斯。

其中一个关键点是,你必须在节目或输入无法控制。 你都交给那些和它的你来回答这个问题。

还需要注意的是图灵机是可计算的有效模式的基础。 换句话说,一切,你在现代计算机语言一样可以被映射回这些原型图灵机。 其结果是,停机问题是任何有用的现代语言判定的。



Answer 2:

为了解决停机问题,你就必须开发一种算法,可以判断任意程序是否停止对任意输入 ,不只是比较简单的情况下,在你的例子。



Answer 3:

下面是停机问题是不可判定的证明一个简单的解释。

假设你有一个程序,H,其计算程序是否停止。 h耗时两个参数,第一是节目,P的说明,第二个是一个输入,I. h如果P的输入I和假停止,否则返回true。

现在写一个程序,P2,这需要它的输入另一程序,P3的描述。 P2调用H(P3,P3),然后循环若H返回true,否则停止。

当我们运行P2(P2)会发生什么?

它必须循环和停止的同时,使宇宙爆炸。



Answer 4:

这已被殴打致死这么好,其实是有一个诗意的证据 ,写在刘易斯·卡罗尔苏斯博士杰弗里·Pullum的风格(他的语言登录成名)。

有趣的事情。 这里是一个味道:

下面是我使用的伎俩 - 这是简单的事。
我将定义一个程序,我将称之为Q,
将使用停止成功的普的预测
挑起一个可怕的逻辑混乱。

...

无论P可能取得的效果,Q将舀:
Q采用普的输出,使P看起来愚蠢。
无论P说,它无法预知问:
P是权当它是错的,是假的,当它是真的!



Answer 5:

这里有一个OK证明停机问题上的维基百科。

为了说明,究竟为什么只把它运用一些技巧,以循环不足,考虑下面的程序(伪代码):

int main()
{
  //Unbounded length integer
  Number i = 3;

  while(true)
  {
    //example: GetUniquePositiveDivisiors(6) = [1, 2, 3], ...(5) = 1, ...(10) = 1, 2, 5, etc.
    Number[] divisiors = GetUniquePositiveDivisiors(i);
    Number sum = 0;
    foreach(Number divisor in divisiors) sum += divisor;

    if(sum == i) break;

    i+=2;
  }
}

你能想到的方法,如果这个代码暂停,将返回true,否则为假的?

仔细想想 。

如果碰巧你在菲尔茨奖严重争的时候,想象一些代码, 这些问题在地方上的。



Answer 6:

“如果你只需要添加一个循环,你已经得到了制止程序,因此你不能自动任务”

听起来像是有人在推广停机问题的应用。 有很多特别的循环,你可以证明终止。 存在可以执行终止检查宽类的项目研究。 例如,在勒柯克你是有限的,你能证明终止程序。 微软有一个名为终结者的一个研究项目,利用各种近似,证明程序将终止。

但是,请记住,停机问题不只是玩具的例子。 无论是那些解决了一般的“停机问题”,因为它们并不适用于所有的程序工作。

问题是,停机问题,说有存在,你有没有办法知道他们是否会不运行它们,这意味着你可能永远不会做,如果他们决定停止终止程序。

其可以或可以不(在Haskell)停止的程序的一个示例:

collatz 1 = ()
collatz !n | odd n     = collatz (3 * n + 1)
           | otherwise = collatz (n `div` 2)

或者更多的东西访问:

while (n != 1)
    if (n & 1 == 1) 
        n = 3 * n + 1;
    else 
        n /= 2;

鉴于每个整数> = 1,将在程序停止? 那么,它至今已工作,但没有任何定理是说,将停止对每个整数。 我们因猜想 洛塔尔·科拉茨可以追溯到1937年,它拥有的,但没有证据。



Answer 7:

图灵的很好的例子是自我指涉的 - 假设有一个可以检验另一个和确定它是否会暂停的程序。 饲料本身暂停程序检查程序到停止程序,检查程序 - 我应该怎么做呢?



Answer 8:

在参考分点“的人回答‘如果你只需要添加一个循环,你已经得到了制止程序,因此你不能自动任务’”,我会添加这个细节:

是说,你不能算法计算任意程序是否会停止职位是图灵机完全正确的。

问题是,不是所有的程序需要图灵机。 这些都可以用一个概念“弱”机器计算的程序---比如,正则表达式可以完全由一个有限状态机,它总是停止输入体现。 这不是很好吗?

我敢打赌,当人们说“加一个循环”,他们试图表达的是,当一个程序就够复杂的,它需要一个图灵机的想法,因此,停机问题(如一个想法)适用。

这可能会稍微切的问题,但我相信,鉴于该问题的细节,这是值得指出的。 :)



Answer 9:

这里是一个程序,停机问题将永远无法解决。

假设你有你的神奇计划/方法来确定一个程序暂停。

public bool DeterminesHalt(string filename, string[] args){
    //runs whatever program you tell it do, passing any args
    //returns true if the program halts, false if it doesn't
}

现在让我们说我们写一小段代码,如...

public static void Main(string[] args){
    string filename = Console.ReadLine(); //read in file to run from user
    if(DeterminesHalt(filename, args))
        for(;;);
    else
        return;
}

所以在这个例子中,我们可以写一个程序来做我们的神奇制止方法做的正好相反。 如果我们以某种方式确定给定程序将停止,我们刚刚跳进一个无限循环; 否则,如果我们确定该方案是一个无限循环,我们结束程序。

不管你有多少输入检查呢,有没有可行的解决方案,以确定每个程序是否写暂停与否。



Answer 10:

很多有意思的具体例子/类比至今。 如果你想读更深的背景,有一本好书图灵的原始论文, 附注的图灵 ,由Charles Petzold的。

在一个相关的,横盘八九不离十,静脉,有一个非常整洁的文章放在网上,关于谁可以命名较大的那个数? 其刷在图灵机上和阿克曼功能。



Answer 11:

有很多很好的答案已经,但我还没有看到任何解决的事实是,在一种理论性和实用性的选择性混合的,停机问题确实是可以解决的。

因此首先,停机问题基本上是写一个程序来任意第二程序和判定二次节目是否将停止在任意的输入的任务。 所以你说“是的,这程序将停止在此输入”或“没有也不会”。 而事实上,这是在一般情况下无法解决的(其他人似乎已经提供了本已样张)在图灵机。 真正的问题是,你可以种找出事情是否会通过运行它停止(只是等待,直到它停止),但你不能真正找到了一些东西是否会无法通过运行它停止(你会只是永远保持等待)。

这是对图灵机,根据定义,具有存储器的无限量,从而无限多的状态的问题。 然而,我们的计算机只有一个内存有限的。 只有在计算机上这么多的位。 所以,如果你能以某种方式跟踪所有正在运行的程序,而你已经看到了以前的状态(位配置)的,你能保证你的检查会不会进入一个无限循环。 如果辅助程序最终停止,你说“是的,这个程序将停止在此输入”。 如果你看到同样的比特配置才会停止两次,你就知道“没有也不会”。 也许没有多大的技术意义,但它是很好的了解,很多时候,我们面临的真正“硬”问题的理论而不是实际困难。



Answer 12:

这是一个变种停止狗的问题 ,除了与程序,而不是狗,而是停止吠叫的。



Answer 13:

从另一个角度的证明

假设我们有一个CPU与像MOV,增加,JMP指令,但没有也不向外翻。 而我们得到的内存。 不象其他的CPU,这其中有另一个寄存器,称为paraReg。 该寄存器就像一个文件,我们可以无限MOV内容到它,得到它的大小,寻求它的中间,删除一些从它的内容,它是通过一些额外的指令实现的。

在我们开始之前,让我们来定义一些话。 一种程序是一串指令,它是一个字符串。 之前,我们运行一个程序,我们清除所有的寄存器和存储器,除了paraReg,其持有的参数(字符串)零,然后把程序装入内存的位置为零,IP寄存器设置为零。 在程序运行时,一个进程是。

现在的停机问题可以这样说:给定的任何程序,称为proObj(如果它需要一个参数para0,我们在它的第一行添加一个指令:MOV paraReg,para0),是有一个程序来proObj作为参数,可以决定何时开始proObj上运行paraReg设置为零proObj是否会停止?

假设我们有这样一个程序,称为P1。 然后,我们可以创建另一个程序,这需要一个参数para0称为P2。 通过P1,可以告诉我们,如果一个节目,其内容是para0,其参数为para0,将停止或没有。(我们这样来做。构造了第一行[MOV paraReg,para0],其余为para0的程序。命名此程序pro0。然后我们设置paraReg到pro0和呼叫P1)。如果将停止,我们让P2进入一个无限循环,否则我们让P2停止。

如果我们把P2到paraReg和运行P2,将过程停止或者不是? 如果停止,从P2的定义,我们知道当我们把P2到paraReg和运行P2,它不应该制止; 同样,如果不停止,我们知道什么时候放P2到paraReg和运行P2,就应该停止。 那么我们可以说,没有P2,并没有P1。



Answer 14:

您列出了一些简单的情况。

现在,想想所有的情况下,其余的思考。

有可能scenrios无限多的,你就必须将它们全部列出。

当然,除非你可以概括它。

这就是停机问题的用武之地你怎么概括呢?



Answer 15:

请问你的程序解决在Collat​​z猜想 ?



Answer 16:

从编程珍珠 ,由Jon宾利

4.6问题

5.证明当其输入x是一个正整数此程序终止。

while x != 1 do
    if even(x)
        x = x/2
    else
        x = 3*x +1


Answer 17:

我建议阅读本: http://en.wikipedia.org/wiki/Halting_problem ,尤其是http://en.wikipedia.org/wiki/Halting_problem#Sketch_of_proof为了理解为什么这个问题不能要解决算法的方式。



Answer 18:

假设你写一个算法,可以检查代码的任意部分,并判断它停止。

现在给你algoritm本身进行检查。



Answer 19:

问题的精确定义是,你需要编写一个程序,执行以下操作: - 取任意方案 - 确定该程序暂停给定的任意有限输入到程序

然而,这是一个非常高吧。 有到停机问题很多部分解决方案,但没有通用的解决方案。 更糟的是,即使发现部分解决停机问题的方案是已知的困难:

在停机问题BBC H2G2文章

如果你已经真正解决了停机问题,有工作的网站像rentacoder.com你。 几个月前,有关于他们的一个职位从一个名为ATuring用户谁提供了一份合同,解决停机问题。 :)



Answer 20:

您可能会发现它有助于考虑谁刈谁不割自己的草坪草坪的家伙的故事,并问自己是否他刈自己的草坪。



Answer 21:

另一个例子。 我最近遇到了一些所谓的冰雹号码。 这些数字形成这些规则的顺序

f(n) is odd  -  f(n+1) = 3*f(n)+1
f(n) is even -  f(n+1) = f(n)/2

目前,假定所有的出发点最终会到达1,然后重复4,2,1,4,2,1,4,2,1...然而,有这个没有证据。 所以,现在确定了一些终止时送入冰雹序列是实际计算它 ,直到你在到达1的唯一途径。

这是关键, 所理解的停机问题。 我怎么知道那就是你不能肯定地知道一个程序会/不会停止,除非你实际运行的程序 。 所以,你写的,可以给你一个答案是肯定的停机问题的任何程序,就必须实际运行程序。



Answer 22:

停机问题的意义不在于问题本身的重要性; 相反,自动化测试是在软件工程中没有什么实际用处的(证明程序暂停并不能证明它是正确的 ,并且在任何情况下,假设算法只提供证明对于给定的有限的输入,而现实生活中的软件开发者会更感兴趣的是测试所有可能的有限投入)。

相反,停机问题是第一个被证明不可判定的 ,这意味着不存在算法在一般情况下,它的工作原理。 换句话说,图灵证明了超过70年前,有一些问题,电脑无法解决 - 不仅仅是因为正确的算法尚未被发现,但因为这种算法不能在逻辑上存在。



文章来源: What exactly is the halting problem?