“真实”计算机程序的计算难度


10

我经常听到有人说过,由于赖斯定理,您无法编写程序来捕获Web浏览器,文字处理器或操作系统中的错误:赖斯定理的任何语义属性都是不确定的。

但是,我不确定这在多大程度上适用于像操作系统这样的真实程序。这些类型的程序是否需要图灵完整性的全部力量?是否可以使用这些应用程序编写更简单的计算模型(例如PR)?如果是这样,在何种程度上可以确定程序正确性?


您不能检查弱得多的模型的非平凡的通用属性(例如,对于所有输入而言都是固定的),例如,您不能检查两个可乘以可计算的TM是否正在计算相同的功能(尽管由于可乘以TM总是会停止,所以对于它们而言可以决定是否停止)。另一方面,如果输入域是有界的,则可以检查某些模型中的某些属性,例如,至少在理论上,程序不会在大小小于1,000的输入上崩溃(实际上,这可能很棘手)。
卡夫

轻度相关的问题
Artem Kaznatcheev

Answers:


14

您当然可以编写捕获错误的程序-有大量活跃的人编写程序来实现此目的。然而,赖斯定理阻止您进行的工作是编写既完善又完整的bug捕捉程序(即,捕获某个类的所有bug且没有误报)。

也就是说,对计算模型的幼稚限制实际上对改善程序分析的实用性没有太大帮助。原因是您可以通过翻转while循环来获得执行“几乎相同的事情”的程序

while P do 
   C

进入具有较大迭代常数的for循环中:

for i = 0 to BIGNUM do 
  if P then 
    C
  else
    break

现在,该程序甚至不需要原始递归的全部功能(因为可以将for循环宏扩展为巨大的嵌套if-then-else语句),但是在大多数实际情况下,它的行为与以前相同。请注意,它确实在理论上有助于确定性-该程序是完整程序,因此您可以通过运行该程序并查看会发生什么来回答问题。这不是我们真正想要的,它比运行程序更快地获得答案-引入的人工终止实际上并没有在实践中帮助程序分析,因为由于实际程序逻辑中的错误而导致错误发生,并且我们没有一点都没有触及。

此外,在编程语言中添加抽象工具可能从根本上加剧分析问题的复杂性,同时使在实践中验证程序更容易。例如,用自然数证明简单类型的lambda演算的终止要求归纳为,但是通过添加类型多态性,您可以获得System F,其终止证明与二阶算术的一致性一样强。但是,实际上,用F编写的程序更容易验证,因为二阶量化的模块化特性使编写结构化程序和正确性证明变得更加容易。ϵ0


“该程序甚至不是原始递归”是什么意思?
瑞安·威廉姆斯

@RyanWilliams可能只是可以在允许少于原始递归函数的完整数组的系统中编写代码,例如,在循环上需要显式(编译时)界限的程序。
科迪

您可以宏扩展循环,而无需执行分支程序(即仅使用if-then-else和顺序合成)。
Neel Krishnaswami

说出类似“该程序甚至不需要原始递归的全部力量”之类的东西也许会更清楚。
马克斯

@Max:接受建议!
Neel Krishnaswami

5

由于您询问了诸如操作系统之类的真实程序的程序正确性,您可能会对seL4项目(journalpdfConference)感兴趣。

NICTA团队采用了第三代微内核,该内核由8700行C语言和600行汇编程序组成,这些内核是根据Haskell中的抽象规范实现的。他们提供了经过机器检查的正式证明(在Isabelle / HOL中),证明该实现严格遵循规范。从而证明他们的程序没有错误。

因此,就像暂停问题一样,尽管通常无法解决该问题,但可以针对某些特定情况解决它。在这种情况下,尽管您不能证明任意C代码都没有错误,但是在seL4微内核的情况下,他们可以做到。


请注意,经过认证的代码仍然容易受到规范错误的影响,因此您只能说代码相对于规范而言是没有错误的。
nponeccop

@nponeccop绝对正确,但是当您开始怀疑规范时,您也会开始模糊臭名昭著的Bug功能。要称其为“错误”,您必须牢记一些隐式规范,捕获此类隐式规范背后的直觉开始深入探讨,直到您在数学哲学的基础上遇到问题(采用Brouwer与Hilbert的风格) 。
Artem Kaznatcheev

“规范”是指形式规范,即您证明的形式定理。在将文本要求转化为定理时,您仍然可能会犯错误。获得认证的唯一好处就是减少了受信任的代码库(您应该仅信任定理,而不是代码或证明),并使代码与定理保持一致。
nponeccop

这是来自seL4网站的引文:“ seL4微内核的C代码正确实现了其抽象规范中描述的行为,仅此而已。”
nponeccop 2011年

2

您提出的问题实际上是完全不同的。

但是,我不确定这在多大程度上适用于像操作系统这样的真实程序。这些类型的程序是否需要图灵完整性的全部力量?

图灵完整的计算模型几乎不需要花费什么。例如,带有计数器的各种模型可以模拟图灵机。如果您认为您的软件需要两个以上可以任意操作的计数器,则您使用的是图灵完整语言。尽管机器整数是先验有界的,但堆分配的数据结构通常不是。如果您的软件需要列表,树和其他动态分配的数据,则您使用的是图灵完整语言。

是否可以使用这些应用程序编写更简单的计算模型(例如PR)?如果是这样,在何种程度上可以确定程序正确性?

重要的是要认识到我们不想检查软件的任意属性。检查非常具体,狭窄的属性(没有缓冲区溢出,没有空指针取消引用,没有无限循环等)极大地提高了软件的质量和可用性。从理论上讲,此类问题仍无法确定。在实践中,专注于特定属性使我们能够发现程序中经常可以用来解决问题的结构。

特别是,您可以将原始问题修改为

是否可以在非图灵完整模型中有效分析我的软件?

抽象是一个模型,其中包括原始软件的行为以及可能的许多其他行为。有一些模型,例如单柜台机器或下推系统,它们的图灵功能还不完善,我们可以进行分析。使用自动化工具进行程序验证的标准方法是在这种模型中构造一个抽象,并对其进行算法检查。

在某些应用程序中,人们会关心其硬件或软件的复杂特性。硬件公司希望其芯片正确执行算术算法,而汽车和航空电子公司则希望得到可证明正确的软件。如果那么重要,那么最好是使用(训练有素的)人。


我认为您已经回答了相反的问题,即文字处理器是否可以完成图灵处理?通过适当地处理寄存器,可以做到。但是,可以施加寄存器操纵规则来破坏图灵完整性。我的问题是,您可以在这些狭窄的约束条件下实际编程多少。
大卫·哈里斯

我在回答有关编写操作系统和其他应用程序软件是否需要图灵完整编程语言的问题。如果需要多个计数器或无限制的数据结构,则将需要图灵完整的编程语言。
维杰·D

@Vijay:不,这不是真的。有很多类型理论(例如,Agda和Coq)都极具表现力,并且不允许无限制的递归。
Neel Krishnaswami

@Neel:澄清一下,我只是在谈论图灵完整性。在这些理论中不可能模拟图灵机吗?
Vijay D

没错-他们的图灵还不完整。在构造逻辑中,图灵完备性允许对罗素悖论进行模拟。
Neel Krishnaswami
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.