Coq中sig类型元素的相等性

Coq中sig类型元素的相等性,coq,subtype,Coq,Subtype,sig类型定义如下: Inductive A: Set := mkA : nat-> A. Function getId (a: A) : nat := match a with mkA n => n end. Function filter (a: A) : bool := if (beq_nat (getId a) 0) then true else false. Coercion is_true : bool >-> Sortclass. Definition su

sig类型定义如下:

Inductive A: Set := mkA : nat-> A.
Function getId (a: A) : nat := match a with mkA n => n end.
Function filter (a: A) : bool := if (beq_nat (getId a) 0) then true else false.
Coercion is_true : bool >-> Sortclass.
Definition subsetA : Set := { a : A | filter a }.
我试图证明它的投影是内射的:

Lemma projection_injective : 
  forall t1 t2: subsetA, proj1_sig t1 = proj1_sig t2 -> t1 = t2.
Proof.
 destruct t1.
 destruct t2.
 simpl.
 intros.
 rewrite -> H. (* <- stuck here *)
Abort.

我试着重写,但没有成功。例如,为什么我不能重写
I
H
来给出Coq a
i0
?请问我错过了什么?谢谢。

在你陷入困境时,你的目标大致如下:

exist x i = exist x0 i0
如果您键入的重写成功,您将获得以下目标:

exist x0 i = exist x0 i0
在这里,您可以看到Coq抱怨的原因:重写会产生一个类型错误的术语。问题是子项
exist x0 i
使用
i
作为类型
filter x0
的一个术语,而实际上它具有类型
filter x
。为了让Coq相信这不是一个问题,您需要在重写之前稍微调整一下您的目标:

Lemma projection_injective : 
  forall t1 t2: subsetA, proj1_sig t1 = proj1_sig t2 -> t1 = t2.
Proof.
 destruct t1.
 destruct t2.
 simpl.
 intros.
 revert i. (* <- this is new *)
 rewrite -> H. (* and now the tactic succeeds *)
 intros i.
Abort.
之后您可能会遇到另一个问题:显示
filter x0
类型的任意两个项相等。一般来说,你需要证明无关性公理来证明这一点;但是,由于
过滤器
被定义为具有可判定等式的类型的两个项之间的等式,因此您可以将此属性证明为一个定理(该定理已经为您做了)

作为补充说明,该库已经有一个包含您的属性的名为
val_inj
。举个例子,我们可以这样使用它:

From mathcomp Require Import ssreflect ssrfun ssrbool eqtype.

Inductive A: Set := mkA : nat-> A.
Function getId (a: A) : nat := match a with mkA n => n end.
Function filter (a: A) : bool := if (Nat.eqb (getId a) 0) then true else false.
Definition subsetA : Set := { a : A | filter a }.

Lemma projection_injective :
  forall t1 t2: subsetA, proj1_sig t1 = proj1_sig t2 -> t1 = t2.
Proof.
  intros t1 t2.
  apply val_inj.
Qed.

对于第一个问题,
subst
是一种在涉及依赖类型时非常有用的策略(cf)。
Lemma projection_injective :
  forall t1 t2: subsetA, proj1_sig t1 = proj1_sig t2 -> t1 = t2.
Proof.
  intros [x1 i1] [x2 i2]; simpl; intros e.
  subst.
Abort.
From mathcomp Require Import ssreflect ssrfun ssrbool eqtype.

Inductive A: Set := mkA : nat-> A.
Function getId (a: A) : nat := match a with mkA n => n end.
Function filter (a: A) : bool := if (Nat.eqb (getId a) 0) then true else false.
Definition subsetA : Set := { a : A | filter a }.

Lemma projection_injective :
  forall t1 t2: subsetA, proj1_sig t1 = proj1_sig t2 -> t1 = t2.
Proof.
  intros t1 t2.
  apply val_inj.
Qed.