众所周知,暂停问题不能有明确的解决方案,a)返回true< ==>程序确实停止了,b)处理任何输入,但我想知道是否有足够好的解决方案来解决问题,那些可以完美地处理某些类型的程序流程,或者能够确定什么时候不能正确解决问题,或者确定哪个时间很长,等等......
如果是这样,他们有多好,他们依赖什么想法/限制?
答案 0 :(得分:4)
正常的方法是将程序行为约束为effectively calculable算法。例如,simply typed lambda calculus可用于确定算法始终停止。这意味着简单类型的lambda演算不是图灵完备,但它仍然足以代表许多有趣的算法。
答案 1 :(得分:1)
可以完美处理某些类型的程序流程
这很简单,“特定类型”越窄越容易。原始示例:确定以下代码段是否终止,对于x
的任意起始值:
void run(int x)
{
while(x != 0)
{
x = x > 0 ? x-2 : x+2;
}
}
解决方案比代码本身短。
或能够识别何时无法正确解决问题
再次简单:当程序不适合固定的窄架构时,取上面的程序,使其回复“否”。
或者是一个很高的百分比
如何在无限的可能输入上定义“高”百分比?
答案 2 :(得分:1)
证明循环停止的一种方法是识别一些整数变量(不一定在程序中明确地表示),每次循环执行时总是减少,并且一旦该变量小于零,循环就会终止。我们可以将此变量称为循环变量。
考虑以下小片段:
var x := 20;
while (x >= 0) {
x := x - 1
}
在这里,我们可以看到每次执行循环时x都会减小,并且循环将在x< 0(显然,这不是很严格,但你明白了)。因此,我们可以使用x作为变体。
一个更复杂的例子怎么样?考虑有限的整数列表,L = [L [0],L [1],...,L [n]]。如果x是L的成员,则in(L, x)
为真。现在考虑以下程序:
var x := 0;
while (in(L, x)) {
x := x + 1
}
这将搜索自然数字(0,1,2,...),并在找到不在L中的x值后停止。那么,我们如何证明这会终止? L中有一个最大值 - 称之为max(L)。然后我们可以将我们的变体定义为max(L) - x
。为了证明终止,我们首先必须证明max(L) - x
总是在减少 - 不是太难,因为我们可以证明x总是在增加。然后我们证明循环将在max(L) - x < 0
时终止。如果是max(L) - x < 0
,那么max(L) < x
,这意味着x不可能在L中,因此循环将终止。
答案 3 :(得分:0)
答案 4 :(得分:0)
有时机器是否会停止显而易见,即使机器非常大。一旦你识别出一个模式,比如存在一个“倒计时”变量,你就可以编写一个适用于拥有它的任何机器的小型机器。这是一个无限的家庭,但是所有可能的机器都可以忽略不计。大多数人工编写的机器对于它们的大小都有非常简单的行为,所以如果在实际时间/空间中可以解决很多这些机器并不会让我感到惊讶,但是我不知道如何测量它。
为了让您了解“它们有多好”问题有多么艰难,这是一个具有重大理论意义的问题:对于给定的尺寸N,有多少N型机器停止运转?这是不可计算的(因为可以计算它的机器可用于解决暂停问题)并且对于N> 4不知道。
答案 5 :(得分:0)
是的,只需使状态空间有限,并且(理论上)所有输入都可以。 (简单地迭代所有可能性。)
因此,理论上可以在真实计算机上运行任何程序。 (您可能必须使用比执行程序更大的RAM的计算机来进行分析。当然,分析将花费相当长的时间。)
可能你想要更实用的东西。在这种情况下,请考虑语言。语法正确/不正确的问题可以很快确定(取决于语言的种类和输入长度),尽管你可以提供无数的程序作为输入。 (注意:我们不是在讨论执行输入程序,只是确定它是否在语法上正确。)