从Coq中的流中提取有限性证据

从Coq中的流中提取有限性证据,coq,Coq,我正在努力实现,但是遇到了一些技术问题 首先,我定义了流,定义为 CoInductive Stream (D : Type) := Eps : Stream D -> Stream D | Val : D -> Stream D. 带有限命题 Inductive Finite (D : Type) : Stream D -> Prop := | Finite_Val : forall d, Finite D (Val D d) | Finite_Eps :

我正在努力实现,但是遇到了一些技术问题

首先,我定义了流,定义为

CoInductive Stream (D : Type) := 
  Eps : Stream D -> Stream D |
  Val : D -> Stream D.
带有限命题

Inductive Finite (D : Type) : Stream D -> Prop :=
  | Finite_Val : forall d, Finite D (Val D d)
  | Finite_Eps : forall d, Finite D (d) -> Finite D (Eps D d).
我的目标是找到一些证据,证明某个有限流实际上是有限的,它在下面的引理中构造返回n和d'的函数

Lemma finite_pred_nth (D : Type) :
  forall d, Finite D d -> exists n d', pred_nth d n = Val D d'.
Proof.
  intros. induction H.
  - exists 0. exists d. reflexivity.
  - destruct IHFinite as [n [d' IHF]].
    exists (S n). exists d'. simpl. apply IHF.
  Qed.
而pred\n的定义为

Fixpoint pred_nth {D : Type} (x : Stream D) (n : nat) : Stream D :=
  match x, n with
  | Eps _ x', S n' => pred_nth x' n'
  | Val _ d, _ => x
  | Eps _ x', 0 => x
  end.
这些是我的一些方法

使用记录作为返回类型

Record fin_evid := mk_fin_evid 
  { 
    T :> Type;
    d : Stream T;
    n : nat;
    v : T;
    H : pred_nth d n = Val T d' }.
Class finite_evidence (D : cpo) (d : Stream D) := {pred_n : nat; pred_d' : D; pred : pred_nth d pred_n = Val D pred_d'}.

Fixpoint extract_evidence (D : cpo) (d : Stream D) (H : Finite D d) : finite_evidence D d.
Proof.
  destruct d.
- apply eps_finite_finite in H. apply extract_evidence in H.
  destruct H.
  exists (S pred_n0) (pred_d'0). simpl. apply pred0.
- exists 0 t. reflexivity.
Defined.
在这种情况下,我无法构造函数

使用typeclass作为返回类型

Record fin_evid := mk_fin_evid 
  { 
    T :> Type;
    d : Stream T;
    n : nat;
    v : T;
    H : pred_nth d n = Val T d' }.
Class finite_evidence (D : cpo) (d : Stream D) := {pred_n : nat; pred_d' : D; pred : pred_nth d pred_n = Val D pred_d'}.

Fixpoint extract_evidence (D : cpo) (d : Stream D) (H : Finite D d) : finite_evidence D d.
Proof.
  destruct d.
- apply eps_finite_finite in H. apply extract_evidence in H.
  destruct H.
  exists (S pred_n0) (pred_d'0). simpl. apply pred0.
- exists 0 t. reflexivity.
Defined.
这个函数创建工作得很好,但是我找不到如何模式匹配typeclass,所以我可以在定义其他函数时提取pred_n,pred_d'

这些都是最简单的示例,完整的代码可以在第598行(流的定义)和第817行(使用typeclass)附近查看。 使用此技术是为了在不破坏coq停止保证的情况下创建最小上限(第716行)。
更具体地说,给定流的单调递增序列并证明第一个元素是有限的(大于有限流的流也是有限的),为每个元素提取封装元素,然后返回提取的封装元素的lub。

您的
提取证据
函数在我看来很好。您可以直接使用类方法
pred_n
pred_d'
提取这些证人。例如:

Definition get_evidence (D : cpo) (d : Stream D) (H : Finite D d) :=
  @pred_n _ _ (extract_evidence D d H).
注意
@
,它允许您指定您正在谈论的类实例。在这里,您可能不需要类型类解析机制,因此可以安全地将
有限证据
声明为
记录
,而不是