合同与依存类型之间的关系


31

我一直在阅读一些有关依赖类型和编程合同的文章。从我所阅读的大部分内容来看,似乎合同是动态检查的约束,而依赖类型是静态检查的。

有一些论文使我认为可以对合同进行部分静态检查:

这样,似乎有很多重叠,而我对合同和依存类型的分类就开始消失了。

在我所缺少的两个概念中,还有更深入的东西吗?还是这些只是代表相同基础概念的模糊类别?

Answers:


26

在实践上,合同就是断言。它们使您可以检查(无量化)程序单个执行的属性。合同检查的核心思想是怪罪-基本上,您想知道谁是违反合同的错。这可以是实现(不计算承诺的值)或调用方(向函数传递错误类型的值)。

关键的见解是,您可以在域理论的逆极限构造中使用与嵌入-投影对相同的机制来跟踪责任。基本上,您从使用断言切换为使用成对断言,其中一对断言归咎于程序上下文,而另一个则归咎于程序。然后,这可以让您用协定包装高阶函数,因为您可以通过交换断言对来建模函数空间的矛盾。(例如,参见Nick Benton的论文“ Undoing Dynamic Typing”。)

从属类型是类型。类型指定用于断言某些程序是否可接受的规则。结果,它们不包含诸如怪罪之类的东西,因为它们的功能是首先防止行为不端的程序存在。没什么可怪的,因为只有格式正确的程序甚至是语法话语。实用上,这意味着使用从属类型来用量词来表达术语的属性非常容易(例如,一个函数可用于所有输入)。

这两种观点并不相同,但是它们是相关的。基本上,关键是合同是从价值的通用域开始的,并使用合同来缩减成本。但是,当我们使用类型时,我们会尝试预先指定较小​​的值域(具有所需的属性)。因此,我们可以通过类型导向的关系族(即逻辑关系)将两者联系起来。例如,请参见艾哈迈德(Ahmed),芬德勒(Findler),锡克(Siek)和沃德勒(Wadler)的最新著作《全民责备》,或雷诺兹(Reynolds)的《类型的意义:从内在语义到外在语义》


为什么说合同是无量词的?
Radu GRIGore 2011年

3
因为通常不能使用测试来建立函数的通用量化属性,仅此而已。
Neel Krishnaswami

3
除非量词的范围超过有限域,否则在这种情况下,它们可以被视为大的合取和析取。或者,如果您想花哨的话,可以检查某些定量的语句,前提是该变量的范围在Martin Escardo的可搜索类型(可以是无限的)范围内。
安德烈·鲍尔

2
@Radu:我称JML&co之类的“程序逻辑”。程序逻辑的断言语言不限于来自程序语言的术语。这使您可以排除诸如非终止或副作用断言之类的事情,这些事情没有很好的逻辑解释。(但是,这样的事情对于合同检查确实很重要-请参阅Pucella和Tove在ESOP上有关使用有状态的命令式合同来跟踪线性属性的最新工作。)
Neel Krishnaswami

2
那是因为我拼错了Tov的姓氏。请参见“仿射类型的有状态合同”,ccs.neu.edu / home / tov / pubs / affine
Neel Krishnaswami

13

类型和契约攻击的(相当抽象的)问题是“如何确保程序具有某些属性?”。在能够表达更广泛的属性类别与能够检查程序是否具有属性之间存在着内在的张力。类型系统通常确保非常特定的属性(程序绝不会以某些方式崩溃)并具有类型检查算法。另一方面,合同允许您指定非常广泛的属性(例如,该程序的输出是质数),但不附带检查算法。

但是,没有合同检查算法(始终有效)这一事实并不意味着几乎没有合同检查算法(在实践中往往有效)。我建议您查看Spec#Frama-CJessie插件。他们俩都通过验证条件生成,以一阶逻辑的形式将“该程序遵守该合同”表示为工作,然后询问SMT求解器去尝试查找证明。如果求解器无法找到证明,则程序是错误的,或者,求解器无法找到存在的证明。(这就是为什么这是“几乎”合同检查算法的原因。)还有一些基于符号执行的工具,这大致意味着“该程序遵守此合同”被表达为一堆命题(在某种逻辑上)。参见,例如jStar

弗拉纳根(Flanagan)的工作试图从两个方面汲取最大的益处,以便您可以快速检查类似类型的属性,然后为其余部分工作。我对混合类型不是很熟悉,但是我确实记得作者说过他的动机是想出一种需要更少注释的解决方案(比他以前在ESC / Java上所做的工作)。但是,从某种意义上说,ESC / Java(和Spec#)中的类型和契约之间也存在一些松散的集成:检查契约时,告诉求解器成功进行类型检查,以便它可以获取该信息。


7

可以静态检查合同。如果您看一下Dana Xu在ESC / Haskell上的老著作,她能够在编译时实现完全合同检查,仅依靠定理证明者进行算术运算即可。如果我没记错的话,终止可以通过一个简单的深度限制来解决:


6

合同和类型都允许您在函数上表示Hoare风格(前后条件)规范。两者都可以在编译时静态检查,也可以在运行时动态检查。

依赖类型允许您在类型系统中编码非常广泛的属性,这是合同程序员期望的属性类型。这是因为它们可以取决于类型的值。尽管我相信您引用的论文着眼于替代方法,但是从属类型有被静态检查的趋势。

最终,差异不大。我认为,依赖类型是可以表达规范的逻辑,而契约是可以表达规范的编程方法,这更多。


说可以静态检查Hoare样式的注释有点误导。如果逻辑像往常一样是FO,那么问题肯定是不确定的。但是,是的,我知道您的意思是,在许多情况下,人们都可以尝试甚至取得成功。
Radu GRIGore 2011年

1
我的印象是,生成证明可能不确定,但应该检查证明。许多依赖类型的语言都依赖用户来提供定理类型居住性的证明值。
杰森·赖希

你是对的。但是我生活在自动化的世界中,通常不会要求用户提供证明。
Radu GRIGore 2011年
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.