相关对类型

时间:2018-06-27 01:35:46

标签: types coq

在软件基础Logic in Coq中,我们介绍了参数化的命题:

Definition is_three (n : nat) : Prop :=
n = 3.
Check is_three.
(* ===> nat -> Prop *)

这让我想起了依赖对类型,从Reading HoTT in Coq中我们定义了依赖对类型:

Inductive sigT {A:Type} (P:A -> Type) : Type :=
existT : forall x :A, P x -> sigT P.

有人可以解释他们之间的区别吗?在Coq的HoTT阅读中,它说:“由于我们尚未定义命题相等性,因此我们不能 这里有很多有趣的事情”,为什么没有命题相等性我们就不能做任何有趣的事情?

1 个答案:

答案 0 :(得分:4)

现在让我们假装,HoTT代码使用A -> Prop而不是A -> Type;两者之间的差异与您的问题正交。

参数化命题P : A -> Prop只是类型A的元素的属性。除了上面简单的is_three命题之外,我们还可以用这种方式表达自然数的更复杂的属性。例如:

Definition even (n : nat) : Prop :=
  exists p, n = 2 * p.

Definition prime (n : nat) : Prop :=
  n >= 2 /\
  forall p q, n = p * q -> p = n \/ p = 1.

类型sigT A P的类型允许我们将类型A限制为满足属性P的元素。例如,sigT nat even是所有偶数的类型,sigT nat prime是所有质数的类型,等等。在Coq中,属性是更原始的概念,而子集类型是sigT是一个衍生概念。

在传统数学中,属性和子集的概念几乎可以混为一谈:说2是质数等于说它属于所有质数的集合。在Coq的类型理论中,情况并非如此,因为作为类型的元素不是是命题:例如,您不能陈述定理说2是{{1 }}。以下代码段引发错误:

sigT nat prime

Lemma bogus : (2 : {x : nat & prime x}). (* Error: *) (* The term "2" has type "nat" while it is expected to have type *) (* "{x : nat & prime x}". *) 是Coq标准库中定义的{ ... & ... }类型的语法糖。)

我们可以得到的最接近的意思是可以从该类型中提取2:

sigT

其中Lemma fixed : exists x : {x : nat & prime x}, 2 = projT1 x. 是提取依赖对的第一个分量的函数。但是,这比简单地说2是质数更为麻烦:

projT1

通常,参数化命题在Coq中更有用,但是在某些情况下Lemma prime_two : prime 2. 类型派上用场;例如,当我们只关心满足某种属性的类型的元素时。假设您使用一种二叉搜索树在Coq中实现了一个关联映射。您可能首先定义任意树的类型sigT

tree

此类型定义一个二叉树,其节点存储自然数的键值对。要使用此类型实现用于查找元素,更新值等的功能,我们可以保持对树的键进行排序的不变性(即,左子树上的键小于的子键)。一个节点,右边的子树则相反。由于该树的用户不想考虑不满足该不变式的树,因此我们可以改用类型Inductive tree : | Leaf : tree | Node : tree -> nat -> nat -> tree -> tree. ,其中sigT tree well_formed表示上述不变式。主要优点是,这简化了库的接口:与其说引物函数保留了不变式,还不如说一个独立的引理,它会自动以插入函数本身的类型表示;用户甚至无需费心争论使用接口构造的树就尊重不变性。

关于第二个问题,相等性是如此基础,以至于没有它就很难定义有趣的属性。例如,上面的属性well_formed : tree -> Propeven都是使用相等定义的。

相关问题