我们为什么不对编译时间保证进行更多研究?


12

我喜欢所有的编译时间,我喜欢这样的想法:一旦您编译了程序,就可以保证程序的执行。一般来说,静态类型系统(Haskell,C ++等)似乎比任何动态类型系统都提供了更强大的编译时保证。

据我了解,Ada在编译时间检查方面走得更远,并且能够在执行之前检测到更大范围的错误。考虑到在某个时间点,它被选用于脆弱的领域(编程错误可能会导致人员伤亡),因此它也被认为是相当安全的。

现在,我想知道:如果更强大的静态保证导致代码更完整,更安全,那么我们为什么不朝这个方向进行更多研究呢?

一种似乎缺少的东西的例子是一种语言,它不是定义int具有由基础体系结构的位数确定的范围的通用类型,而是可以具有范围(在下面的示例中Int [a..b]描述了一个介于包括a和b):

a : Int [1..24]
b : Int [1..12]
a + b : Int [2..36]
a - b : Int [-11..23]
b - a : Int [-23..11]

或(从Ada那里获得):

a : Int [mod 24]
b : Int [mod 24]
a + b : Int [mod 24]

该语言将为范围选择最佳的基础类型,并对表达式进行编译时检查。因此,例如,给出:

a : Int [-3..24]
b : Int [3..10]

然后:

a / b

永远不会被定义。

这只是一个例子,但我觉得我们在编译时还有很多可以执行的事情。那么,为什么对此的研究很少?描述这个想法的技术术语是什么(以便我可以找到有关此主题的更多信息)?有什么限制?


2
Pascal具有整数子范围类型(​​即1960s),但是不幸的是,大多数实现只在运行时检查它们(int(-1..4)在编译时与int(100..200)兼容)。这样做的好处是有限的,并且基于合同的编程将想法向更好的方向扩展(例如,埃菲尔)。诸如C#之类的语言试图通过属性获得某些好处,但我没有使用过它们,因此不确定它们在实践中有多有用。

1
@Ӎσᶎ:C#中的属性只是元数据类,因此任何数据验证都将在运行时进行。
罗伯特·哈维

8
您怎么知道对此没有什么研究?尝试使用谷歌搜索dependent typerefinement type
Phil

3
我同意前提似乎有缺陷。这无疑是一个活跃的研究领域。工作从未完成。因此,我不太明白如何回答这个问题。
拉斐尔

1
@Robert Harvey:ADA提供更多保证的事实并不意味着编译器会捕获所有错误,只会使错误发生的可能性降低。
Giorgio 2014年

Answers:


11

我不是在一个位置,告诉多少应研究的课题做,但我可以告诉你,有正在做的研究,例如Verisoft XT由德国政府资助的计划。

我认为您正在寻找的概念称为形式验证基于合同的编程,其中后者是程序员友好的前一种方法。在基于合同的编程中,您首先要正常编写代码,然后将所谓的合同插入代码中。基于此范例的一种易于使用的语言是Microsoft Research的Spec#,以及功能相似但不太漂亮的C#代码合同扩展,您都可以在网上进行尝试(对于其他语言,它们也有类似的工具,请查看rise4fun )。您提到的“具有范围类型的整数”将通过函数中的两个协定来反映:

Contract.Requires(-3 <= a && a <= 24);
Contract.Requires( 3 <= b && b <= 10);

如果要调用该函数,则必须使用确保满足这些条件的参数,否则会出现编译时错误。以上是非常简单的合同,您可以插入可能想到的关于变量或表达式及其关系的几乎任何假设或要求,并且编译器将检查每个要求是否都包含在假设或可以确保的范围内,即派生从假设。这就是名称源于此的原因:被调用方提出要求,而调用方确保满足要求,就像在商业合同中一样。

P(x1,x2,...,xn)nP用来。从CS方面来看,这两个是过程的关键部分-验证条件的生成很棘手,而SMT是NP完全或不确定的问题,具体取决于所考虑的理论。SMT求解器甚至存在竞争,因此肯定会对此进行一些研究。此外,还有其他方法可以使用SMT进行形式验证,例如状态空间枚举,符号模型检查,有界模型检查等等。尽管SMT是afaik,但目前仍是最“现代”的方法。

关于一般思想的局限性:

  • 如前所述,证明程序的正确性是一个计算上的难题,因此,有合同(或另一种形式的规范)的程序的编译时间检查可能会花费很长时间甚至是不可能的。最好在大多数情况下应用启发式方法是最好的方法。
  • 您对程序指定的内容越多,则说明本身存在错误的可能性就越高。这可能会导致误报(即使所有内容都没有错误,编译时间检查也会失败),或者即使您的程序仍然存在错误,也可能会带来安全隐患。
  • 编写合同或规格书确实是乏味的工作,并且大多数程序员都懒得这样做。尝试编写随处可见代码契约的C#程序,过一会儿您会认为“来吧,这真的有必要吗?”。这就是为什么形式验证通常仅用于硬件设计和安全关键系统,例如控制飞机或汽车的软件。

最后值得一提的是,这与上面的解释不太吻合,例如,本文称为“隐式复杂性理论” 。它旨在表征编程语言,在该语言中,您可以编写的每个程序都属于特定的复杂度类,例如P。以这种语言,您编写的每个程序都会自动“确保”具有多项式运行时,可以“对其进行检查”。在编译时,只需编译程序即可。我不知道这项研究有任何实际可用的结果,但是我距离专家还很远。


给定可以根据您的项目选择的某种“策略”,难道不可能通过示例测试和无类型代码的组合生成依赖类型或契约吗?
aoeu256
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.