我已经定义了一个类似于:
的Sygma-Type{ R : nat -> nat -> bool | Reflexive R }
我有两个元素r1 r2 : { R : nat -> nat -> bool | Reflexive R }
,我要证明r1 = r2
。我怎么能这样做?
答案 0 :(得分:3)
如果要显示这样的相等性,则需要(1)显示基础函数相等(即,sigma类型的R
组件),以及(2)显示相应的证明是平等的。但是有两个问题。
第一个是Coq中函数的相等性太弱。根据常见的数学实践,如果任何输入产生相同的结果,我们期望两个函数相等。这个原则称为功能扩展性:
Axiom functional_extensionality :
forall A (B : A -> Type)
(f g : forall a, B a),
(forall x, f x = g x) ->
f = g.
然而,听起来很自然,这个原则在Coq的逻辑中是不可证明的!粗略地说,两个函数可以相等的唯一方法是它们是否可以根据逻辑的计算规则转换为语法上相等的术语。例如,我们可以证明fun n : nat => 0 + n
和fun n : nat => n
是相等的,因为+
是通过第一个参数上的模式匹配在Coq中定义的,而第一个参数上的第一个参数是{{ 1}}。
0
我们可以通过类似的方式表明Goal (fun n : nat => 0 + n) = (fun n : nat => n). reflexivity. Qed.
和fun n => n + 0
相等。但是,Coq不接受这一点,因为当第一个参数是变量时,fun n => n
不能简化。
另一个问题是证明上的平等概念也不是很有趣。能够证明两个证明相等的唯一方法是语法上的平等。然而,直觉地,人们想通过证明无关来争论,这个原则表明同一事物的证据总是相等的:
+
但是,同样,这个原则在逻辑上是不可证明的。幸运的是,Coq的逻辑设计允许人们以合理的方式将这些原则作为公理添加。然后得到以下证据:
Axiom proof_irrelevance :
forall (P : Prop) (p q : P), p = q.
尽管公理可能有用,但人们可能希望避免它们。在这种情况下,实际上可以用功能扩展性证明这个引理,但你至少需要它。如果您想避免使用公理,并且Axiom functional_extensionality :
forall A (B : A -> Type)
(f g : forall a, B a),
(forall a, f a = g a) ->
f = g.
Axiom proof_irrelevance :
forall (P : Prop) (p q : P), p = q.
Lemma l (r1 r2 : { R : nat -> nat -> bool |
forall n, R n n = true }) :
(forall n1 n2, proj1_sig r1 n1 n2 = proj1_sig r2 n1 n2) ->
r1 = r2.
Proof.
destruct r1 as [r1 H1], r2 as [r2 H2].
simpl.
intros H.
assert (H' : r1 = r2).
{ apply functional_extensionality.
intros n1.
apply functional_extensionality.
intros n2.
apply H. }
subst r2.
rename r1 into r.
f_equal.
apply proof_irrelevance.
Qed.
和r1
等于计算,则您必须在类型上使用差异等价关系,并使用该关系进行形式化,例如
r2
standard library很好地支持用等价关系重写;比照例如this。