【发布时间】:2018-09-03 18:28:06
【问题描述】:
我在 Coq 的 SSReflect 扩展中发现了两个约定,它们看起来特别有用,但我还没有看到它们在较新的依赖类型语言(Lean、Agda、Idris)中被广泛采用。
首先,在可能的情况下,谓词表示为布尔返回函数,而不是归纳定义的数据类型。这在默认情况下带来了可判定性,为计算证明开辟了更多机会,并通过避免证明引擎需要携带大量证明条款来提高检查性能。我看到的主要缺点是在证明时需要使用反射引理来操纵这些布尔谓词。
其次,具有不变量的数据类型被定义为包含简单数据类型和不变量证明的相关记录。例如,固定长度的序列在 SSReflect 中定义如下:
Structure tuple_of : Type := Tuple {tval :> seq T; _ : size tval == n}.
seq 和该序列长度为特定值的证明。这与例如Idris 定义了这种类型:
data Vect : (len : Nat) -> (elem : Type) -> Type
一种依赖类型的数据结构,其中不变量是其类型的一部分。 SSReflect 方法的一个优点是它允许重用,因此例如为seq 定义的许多函数以及关于它们的证明仍然可以与tuple 一起使用(通过对底层seq 进行操作),而与Idris 一起使用' 像reverse、append 之类的方法需要为Vect 重写。 Lean 实际上在其标准库vector 中有一个等效的 SSReflect 样式,但它也有一个 Idris 样式的 array,它似乎在运行时有一个优化的实现。
一个SSReflect-oriented book 甚至声称Vect n A 风格的方法是一种反模式:
依赖类型语言和 Coq 中的一个常见反模式是将这些代数属性编码到数据类型和函数本身的定义中(一个规范的例子 这种方法中的一种是长度索引列表)。虽然这种方法看起来很吸引人,但正如它所展示的那样 依赖类型捕获数据类型和函数的某些属性的能力,它 本质上是不可扩展的,因为总会有另一个感兴趣的属性,它还没有被 由数据类型/函数的设计者预见,因此必须将其编码为外部事实 反正。这就是为什么我们提倡这种方法,其中数据类型和函数被定义为 close 程序员尽可能定义它们的方式,以及它们的所有必要属性 分别证明。
因此,我的问题是,为什么这些方法没有被更广泛地采用。是否有我遗漏的缺点,或者它们的优点在对依赖模式匹配的支持比 Coq 更好的语言中不那么重要?
【问题讨论】:
标签: coq agda idris dependent-type lean