Types 函数返回子集类型的Coq案例分析与重写

Types 函数返回子集类型的Coq案例分析与重写,types,case,subset,analysis,coq,Types,Case,Subset,Analysis,Coq,我正在做的是一个关于使用子集类型编写认证函数的简单练习。其思想是首先编写一个前置函数 pred : forall (n : {n : nat | n > 0}), {m : nat | S m = n.1}. 然后用这个定义给出一个函数 pred2 : forall (n : {n : nat | n > 1}), {m : nat | S (S m) = n.1}. 我对第一个没问题。这是我的密码 Program Definition pred (n : {n : nat |

我正在做的是一个关于使用子集类型编写认证函数的简单练习。其思想是首先编写一个前置函数

pred : forall  (n : {n : nat | n > 0}), {m : nat | S m = n.1}.
然后用这个定义给出一个函数

pred2 : forall (n : {n : nat | n > 1}), {m : nat | S (S m) = n.1}.
我对第一个没问题。这是我的密码

Program Definition pred (n : {n : nat | n > 0}) : {m : nat | S m = n.1} :=
  match n with
  | O => _
  | S n' => n'
  end.
Next Obligation. elimtype False. compute in H. inversion H. Qed.
但我无法确定第二个定义。我试图写下这些定义

Program Definition pred2 (n : {n : nat | n > 1}) : {m : nat | S (S m) = n.1} 
:= pred (pred n).
我设法证明了这两项首要义务

Next Obligation. apply (gt_trans n 1 0). assumption. auto. Qed.
Next Obligation. 
  destruct pred.  
  simpl.
  simpl in e. 
  rewrite <- e in H.
  apply gt_S_n in H; assumption.
Qed.

我知道我可以直接编写pred2,但是我的想法是使用和编写函数pred。

原因
destruct
没有任何效果,可能是因为您试图对其进行案例分析的内容没有在目标中发生。该术语的隐式参数可能与目标中该术语的隐式参数不匹配。无论哪种方式,你都无法在不将目标输入错误的情况下对该术语进行案例分析

但您可以通过对
n
的案例分析来证明这一义务

Next Obligation.
destruct n.
inversion H.
destruct n.
inversion H.
subst.
inversion H1.
cbn.
eauto.
Qed.
我还能够证明一些helper定理,但由于所有类型依赖性,我无法使用它们

Theorem T1 : forall s1, S (` (pred s1)) = ` s1.
Proof. intros [[| n1] H1]. inversion H1. cbn. eauto. Qed.

Theorem T2 : forall T1 (P1 : T1 -> Prop) s1 H1, (forall x1 (H1 H2 : P1 x1), H1 = H2) -> exist P1 (` s1) H1 = s1.
Proof. intros ? ? [x1 H1] H2 H3. cbn in *. rewrite (H3 _ H1 H2). eauto. Qed.

我从未在函数上使用过
destruct
。我很惊讶Coq没有抱怨这个函数不是归纳定义的。

我对你那里的练习集感兴趣。他们可以在网上的某个地方找到吗?你能发布一个链接或谷歌搜索词吗?我正在做这个练习,谢谢。我认为在n上做案例分析是一个更好的方法。然而,我仍然不明白为什么我的aproach不起作用。在函数上使用析构函数时,它会在函数的返回值中进行案例分析。当我使用refine“definitionpred2(n:{n:nat|n>1}):{m:nat|S(sm)=n.1}.refine((pred((pred(n.1;)).1;))).1;))定义函数时,它工作得非常好。这是我使用的证明。“destruct n.apply(gt_trans x 10)、假设、自动破坏、e中的destruct pred.siml.siml.重写@NicoLehmann结论中的术语
pred(n;pred2_义务_1(n;H))
和术语
pred(n;pred2_义务_1(n;H))
你试图解构的是不同的。要看到这一点,请关闭所有符号。结论中的术语涉及
gt
,而你试图解构的术语涉及
lt
。无论如何,你都不能解构它,因为
pred2\u 2(n;H)
取决于它。谢谢,现在我明白了:-)
Theorem T1 : forall s1, S (` (pred s1)) = ` s1.
Proof. intros [[| n1] H1]. inversion H1. cbn. eauto. Qed.

Theorem T2 : forall T1 (P1 : T1 -> Prop) s1 H1, (forall x1 (H1 H2 : P1 x1), H1 = H2) -> exist P1 (` s1) H1 = s1.
Proof. intros ? ? [x1 H1] H2 H3. cbn in *. rewrite (H3 _ H1 H2). eauto. Qed.