是否有一部分程序可以避免停顿问题


21

我只是在阅读有关停止问题的另一种解释,这使我想到我所看到的所有示例中涉及的问题都涉及无限序列。但是我从不在程序中使用无限序列-它们花费的时间太长。现实世界中的所有应用程序都有上限和下限。甚至实数也不是真正的实数-它们是存储为32/64位等的近似值。

因此,问题是,是否存在可以确定程序是否暂停的子集?对于大多数程序来说足够好了吗?我可以建立一套可以确定程序的“可暂停性”的语言结构吗?我敢肯定,这已经在某处研究过,所以任何指针都将不胜感激。语言不会完全完成,但是是否有几乎完全完成这件事呢?

很自然地,这样的构造必须排除递归和无边界的while循环,但是我可以编写一个没有那么容易的程序。

作为示例,从标准输入中读取内容必须是一定范围的,但这很容易-根据问题域的不同,我将输入限制为10,000,000个字符,以此类推。

tia

[更新]

阅读评论和答案后,也许我应该重申我的问题。

对于所有输入都受限的给定程序,您可以确定该程序是否暂停。如果是这样,语言的约束是什么,输入集的极限是什么。这些构造的最大集合将确定可以推论为停止或不停止的语言。是否对此进行了一些研究?

[更新2]

答案是肯定的,可以回溯到1967年,网址是http://www.isp.uni-luebeck.de/kps07/files/papers/kirner.pdf

明斯基已经在1967年提出论点,认为至少可以在理论上解决有限状态系统的停顿问题[4]:“ ...任何有限状态机,如果完全留给自己,最终将陷入一个完美的周期重复模式。这种重复模式的持续时间不能超过机器内部状态的数量……”

(因此,如果您坚持使用有限的图灵机,则可以构建一个oracle)


13
“无限序列...需要太长时间”。让我大笑。
布莱恩·奥克利

3
我相信SQL92和正则表达式是可以保证停止的语言示例。
Elian Ebbing 2011年

2
请发布“ Update2 ...”作为答案。
S.Lott

2
您不需要排除递归。如果将递归限制为被调用方参数的严格子条款,则始终可以证明已终止。这是一个足够的要求-只要您使用教堂数字,就不需要“有界循环”之类的东西。
SK-logic

1
Idris语言使用依赖类型和证明检查器来证明您的程序在运行之前已终止。它类似于Haskell,并且允许递归,但不允许进行一般递归-只有递归可以证明(通过依赖类型)才能导致某些终端状态。
杰克

Answers:


8

问题不在于输入(显然,对于无限制的输入,您可以有无限的运行时间来读取输入),而是内部状态的数量。

当内部状态的数量有界时,从理论上讲,您可以在所有情况下解决停止问题(只需模拟它直到达到停止或状态的重复),否则就无法解决该问题。 。但是,即使内部状态的数量实际上是有界的,它也是如此巨大,以至于依赖内部状态数量的界的方法无法证明除最琐碎的程序之外的任何程序的终止。

有更多实用的方法来检查程序的终止。例如,用既没有递归也没有goto的编程语言来表达它们,其循环结构对必须在循环的入口处指定的迭代次数具有所有限制。(请注意,边界并不一定与有效的迭代次数真正相关,证明循环终止的标准方法是拥有一个函数,证明该函数严格从一个迭代减少到另一个,并且您的进入条件确保是肯定的,您可以将第一个评估作为约束)。


10

首先,考虑一下如果我们有一个停止的探测器会发生什么。从对角线论点我们知道,至少有一个程序会导致停止检测器永远不会停止或给出错误的答案。但这是一个奇怪且不太可能的程序。

尽管还有另一个论点,那就是停止检测器是不可能的,而更直观的论点是,停止检测器将是神奇的。假设您想知道费马的最后定理是对还是错。您只需编写一个程序,如果它为true则暂停,如果它为false则永久运行,然后在其上运行停止检测器。您不运行该程序,只需在该程序上运行停止检测器。停止检测器将使我们能够通过编写程序立即解决数论中的大量未解决问题。

因此,您可以编写一种编程语言来保证产生总是可以确定停止的程序吗?当然。它只是不能有循环,条件而要使用大量存储空间。如果您愿意不存在任何循环,没有“ if”语句或没有严格限制的存储量,那么可以肯定地说,您可以编写一种语言,该语言的停止总是可以确定的。


2
如果跳转总是必须向前而不是向后跳转,则可以使用if语句。我正在考虑一种BASIC语言的受限子集,其中“ GOTO X”表示转到行号currentLine + X,并且X必须大于0。如果该行无效,则暂停。这将增加存储需求,但将允许一些非平凡的逻辑。这可能等效于一个有限状态机,其中的顶点形成一个图,并且该图可能没有任何循环,否则FSM无效。同样,任何死胡同的状态都必须是接受状态。
Job

3
它可能有界循环-例如,对于i = 1到10,同样表现良好的迭代器。因此,有一类可以解决的有限问题-费马定理再次涉及实数的无限序列。但是,如果我们将域的数量限制为小于1000000,则它会停止。
daven11

2
为什么没有条件?似乎没有跳跃的情况总是可以停止的……
Billy ONeal

2
@nikie:当然这是一个很弱的论点。关键是,这种停止检测器将能够证明或反驳这种陈述,而不必找到证明。我打算让读者在这里发展的直觉是,可以编写微不足道的检测器的语言是一种语言,甚至不能代表费马最后定理或哥德巴赫猜想等数论中的简单问题,因此可能不是一种非常有用的语言。
埃里克·利珀特

3
@EricLippert:错误。这种语言将具有循环,适当的存储和许多其他有用的功能。几乎可以在其中编写任何代码。看哪,这里是:coq.inria.fr
SK-logic

6

我建议您阅读Gödel,Escher,Bach。这是一本非常有趣且很有启发性的书,其中涉及哥德尔的不完备性定理和停顿问题。

简而言之回答您的问题:暂停问题是可以确定的,只要您的程序不包含while循环(或其任何可能的表现形式)即可。


对不起,我看错了你。我删除了我的评论,但我将重申GEB的建议。
2011年

@zvrba这一直是我的阅读清单上一段时间-也许是时候潜水英寸
daven11

5

对于在有限数量的内存(包括各种存储)上运行的每个程序,都可以解决暂停问题;即,一个不确定的程序必然会占用越来越多的内存。

但是即使如此,这种见识并不意味着它可以用于现实世界中的问题,因为仅需要几千字节内存的暂停程序就很容易花费比宇宙剩余寿命更长的时间来暂停。


3

要(部分)回答您的问题“是否有一部分程序可以避免暂停问题”:是的,实际上已经存在。但是,这个子集非常有用(请注意,我正在谈论的子集是暂停程序的严格子集)。

对“大多数输入”问题的复杂性的研究称为通用案例复杂性。您定义一些可能的输入的子集,证明该子集涵盖“大多数输入”,并给出解决该子集问题的算法。

例如,对于大多数输入,暂停问题可以在多项式时间内解决(实际上,如果我对纸张的理解正确,则可以在线性时间内解决)。

但是,由于以下三个方面的原因,此结果是毫无用处的:首先,我们谈论的是具有单个磁带的Turing机器,而不是真实计算机上的真实计算机程序。据我所知,没有人知道现实世界计算机是否同样适用(即使现实世界计算机可能能够计算出与图灵机相同的功能,允许的程序数量,它们的长度以及是否暂停)完全不同)。

其次,您必须注意“大多数输入”的含义。这意味着当n趋于无穷大时,此算法可以检查“ length” n个随机程序的概率趋于1。换句话说,如果n足够大,则该算法几乎可以确定地检查长度为n的随机程序。

本文介绍的方法可以检查哪些程序?本质上,所有重复一个状态(其中“状态”大致对应于程序中的代码行)之前停止的程序。

即使几乎所有程序都可以通过这种方式进行检查,但没有一种可以以这种方式进行检查的程序非常有趣,而且通常不会由人来设计,因此这没有任何实用价值。

这也表明一般情况下的复杂性可能无法帮助我们解决暂停问题,因为几乎所有有趣的程序(显然)都难以检查。或者用另一种说法:几乎所有程序都不有趣,但易于检查。


2
-1,这在很多级别上都是错误的……
user281377 2011年

1
首先,现实世界的计算机无法计算图灵机无法计算的任何东西。到目前为止,还没有人显示出比图灵机更强大的功能(就可计算性而言)。其次,如果程序重复其状态,则不会暂停,因此该程序和输入的暂停问题得以解决。请记住:暂停问题是关于确定程序是否将在给定的输入上暂停。一旦确定地检测到无限循环,就可以了。最后:有大量有用的程序可以解决暂停问题:这些程序在有限的存储上运行。
user281377 2011年

关于您的第一个问题:如本文所述,表明某种计算模型是Turing完整的,并不保留确切地暂停了多少个程序,因此,它们证明的结果对其他计算模型没有任何直接意义。我非常了解Turing的完整性,而且我也不完全知道为什么它使我的答案“错了”。
亚历克斯(Alex)10 Brink

至于你的第二个问题:我所谈论的状态与通常谈论的“机器状态”不同(它涉及可以具有状态的所有事物的状态),而是有限状态自动机的状态。用于控制图灵机的位置,它大致对应于程序在执行过程中随时执行的代码行。重复执行一行代码后,内存的内容可能会有所不同,因此这并不意味着立即暂停。我将更新我的答案以使其更清楚。
亚历克斯(Alex)10 Brink

@ammoQ:不,如果您谈论的是存储空间有限的现实世界系统,那么停顿问题是无法解决的,因为这意味着构建一个可以处理状态组合的现实世界系统。由于大多数CPU中可能的寄存器状态数超过了Universe中的原子数,因此您将无法做到这一点。
David Thornley

3

实际上,确实有一些程序可以始终解决其他问题的停止问题。它们是您正在运行计算机的操作系统的一部分。不确定性是一个奇怪的说法,它只说没有一个适用于所有其他程序的程序。

一个人正确地指出,暂停证明似乎是唯一无法解决的程序,因为它像镜子一样无限地追踪自己。该同一个人还说,如果有一台停机机器,那将是神奇的,因为它将通过提前告诉我们其求解器算法是否停止而告诉我们难题。

在这两种情况下,都假定停止机器不跟踪,因为没有证据表明它可以跟踪。但是,实际上,它确实会跟踪/运行使用给定输入运行的程序。

逻辑证明至少很简单。如果它不需要至少跟踪第一步,则不需要输入以及运行它的程序。为了充分利用信息,它必须至少跟踪第一步,然后再尝试分析该路径的去向。

最高答案中提到的硬数学问题是您无法快速找出答案的问题,这意味着暂停问题将不得不继续跟踪,直到可以识别出某种模式为止。

因此,从停止问题中得出的唯一实用论据是,停止机器无法确定优化的问题解决者的结果的速度快于问题解决者完成的速度。

为这种推理提供正式的证明会比较困难,尽管我相信我可以,但是试图向任何一个学术界人士解释它会导致他们抛出像发脾气的类人猿并从枝形吊灯摆动。最好不要与那些人争论。


1

答案是肯定的,可以回溯到1967年,网址是http://www.isp.uni-luebeck.de/kps07/files/papers/kirner.pdf

明斯基已经在1967年提出论点,认为至少可以在理论上解决有限状态系统的停顿问题[4]:“ ...任何有限状态机,如果完全留给自己,最终将陷入一个完美的周期重复模式。这种重复模式的持续时间不能超过机器内部状态的数量……”

(因此,如果您坚持使用有限的图灵机,则可以构建一个oracle)

当然这需要多长时间是另一个问题


0

是否可以确定程序的子集是否停止?

是。

对于大多数程序来说足够好了吗?

定义“最”。

我可以建立一套可以确定程序的“可暂停性”的语言结构吗?

是。

是否有一个几乎完整的巡回演出就足够了?

定义“接近”。

许多人在不使用while语句或递归的情况下编写Python 。

许多人只使用for带有简单迭代器或计数器的语句来编写Java,这些语句可以轻易地证明可以终止。他们写而没有递归。

避免while和递归很容易。


对于所有输入都受限的给定程序,您可以确定该程序是否暂停?

没有。

如果是这样,语言的约束是什么,输入集的极限是什么。

嗯 暂停问题意味着程序永远无法确定与程序本身一样复杂的事物。您可以添加大量约束中的任何一个来克服暂停问题。

解决暂停问题的标准方法是允许使用比编程语言中可用的稍微“丰富”的数学形式主义进行证明。

扩展证明系统比限制语言要容易。任何限制都会导致针对一个算法的论点,由于该限制而难以表达。

这些构造的最大集合将确定可以推论为停止或不停止的语言。是否对此进行了一些研究?

是。它被称为“群体理论”。一组值在一组操作下关闭。相当了解的东西。


我要问的是“几乎”。是否存在可以说程序停止的有限类问题,问题集的限制程度如何?例如,语句if(i <10)然后print(i)确实停止了所有i。如果我将i的域限制为32位整数,则它会停止。
daven11

请记住,一个for循环一个while循环,人们通常在条件项中放入比just更复杂的东西x < 42
Billy ONeal

@BillyONeal:好点。在Python中,for循环非常严格地限制为通过迭代器工作。for但是,Java中的一个更通用的循环可能包含额外的条件,这些条件会使迭代器的简单使用无效。
S.Lott

“是否存在可以说程序停止的有限类问题?” 答案仍然是。“问题的范围如何?” 嗯 有限是有限的。如果您放弃尝试逼近实数并坚持自然数(在所有数学运算下均封闭),那么您正在执行普通的群论。模块化算术。没什么特别的。不清楚你在问什么。您在问什么是模块化算术?
S.Lott

@ S.Lott我的意思是机器中表示的数字,而不是抽象意义上的数字。因此,将数字视为固定位数。这些数字的规则与整数和实数略有不同。希望有道理。
daven11
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.