证明依赖类型实例之间的平等

时间:2017-12-26 16:54:55

标签: coq

当试图形成与代数结构相对应的类(例如所有幺半群的类)时,自然设计是创建一个类型monoid (a:Type)作为产品类型,它模拟所有必需的字段(元素e:a,一个运算符app : a -> a -> a,证明幺半群定律得到满足等等。在这样做时,我们正在创建地图monoid: Type -> Type。这种方法的一个可能的缺点是给定一个幺半群m:monoid a(一个支持类型a的幺半群)和m':monoid b(一个支持类型为b的幺半群),我们甚至不能写等式m = m'(更不用说证明它)因为它是错误的类型。另一种设计是创建一个类型monoid,其中支持类型只是另一个字段a:Type,因此给定m m':monoid,询问m = m'是否总是有意义的。不知何故,有人想说如果mm'具有相同的支持(a m = a m)并且运算符等于(app m = app m',这可能是由于某些扩展等式公理,并且证明字段无关紧要(因为我们有一些证明不相关公理)等,然后是m = m'。不幸的是,我们无法表达平等app m = app m',因为它是错误的...

为了简化问题,假设我们有:

Inductive myType : Type :=
| make : forall (a:Type), a -> myType.
.

我希望得到以下表格的结果:

forall (a b:Type) (x:a) (y:b), a = b -> x = y -> make a x = make b y.

这种说法是错误的,所以我们不能拥有它。

我可能有公理允许我证明两种类型ab是相同的,我可以证明xy确实是同样也是,但我希望有一个工具让我得出结论make a x = make b y。任何建议都是受欢迎的。

1 个答案:

答案 0 :(得分:3)

证明这一点的低技术方法是使用提供的相等性来插入手动类型转换。也就是说,您没有假设x = y,而是假设(CAST q x) = y。下面我明确地将转换编写为匹配,但你也可以通过定义一个函数来使它看起来更好。

Inductive myType : Type :=
| make : forall (a:Type), a -> myType.

Lemma ex : forall (a b:Type) (x:a) (y:b) (q: a = b), (match q in _ = T return T with eq_refl => x end) = y -> make a x = make b y.
Proof.
  destruct q.
  intros q.
  congruence.
Qed.

通过使用"异类平等"(也称为JMeq),可以更好地隐藏大部分机器。我建议the Equality chapter of CPDT进行详细介绍。你的例子变成了

Require Import  Coq.Logic.JMeq.

Infix "==" := JMeq (at level 70, no associativity).

Inductive myType : Type :=
| make : forall (a:Type), a -> myType.

Lemma ex : forall (a b:Type) (x:a) (y:b), a = b -> x == y -> make a x = make b y.
Proof.
  intros.
  rewrite H0.
  reflexivity.
Qed.

一般来说,虽然这个特定定理可以在没有公理的情况下得到证明,但如果你以这种方式进行形式化,你很可能会遇到无法在没有关于平等的公理的情况下在Coq中证明的目标。特别是,这种依赖记录的注入性是不可证明的。 JMEq库将自动使用关于异构相等的公理JMeq_eq,这使得它非常方便。