证明Coq中的共归纳性质(词汇顺序是可传递的)

证明Coq中的共归纳性质(词汇顺序是可传递的),coq,coinduction,Coq,Coinduction,我试图证明Coq中的第一个例子。第一个例子是证明无限整数流上的字典序是可传递的 我还没能提出证据来绕开这个问题 这是我到目前为止的发展。首先是无限流的一般定义。然后,字典顺序的定义称为lex。最后是传递性定理的失败证明 Require Import Omega. Section stream. Variable A:Set. CoInductive Stream : Set := | Cons : A -> Stream -> Stream. Definitio

我试图证明Coq中的第一个例子。第一个例子是证明无限整数流上的字典序是可传递的

我还没能提出证据来绕开这个问题

这是我到目前为止的发展。首先是无限流的一般定义。然后,字典顺序的定义称为
lex
。最后是传递性定理的失败证明

Require Import Omega.

Section stream.
  Variable A:Set.

  CoInductive Stream : Set :=
  | Cons : A -> Stream -> Stream.

  Definition head (s : Stream) :=
    match s with Cons a s' => a end.

  Definition tail (s : Stream) :=
    match s with Cons a s' => s' end.

  Lemma cons_ht: forall s, Cons (head s) (tail s) = s.
    intros. destruct s. reflexivity. Qed.

End stream.

Implicit Arguments Cons [A].
Implicit Arguments head [A].
Implicit Arguments tail [A].
Implicit Arguments cons_ht [A].

CoInductive lex s1 s2 : Prop :=
  is_le :   head s1 <= head s2 ->
            (head s1 = head s2 -> lex (tail s1) (tail s2)) ->
            lex s1 s2.


Lemma lex_helper: forall s1 s2,  
        head s1 = head s2 -> 
        lex (Cons (head s1) (tail s1)) (Cons (head s2) (tail s2)) -> 
        lex (tail s1) (tail s2).
Proof. intros; inversion H0; auto. Qed.
我如何从这里开始?谢谢你的提示

  • 编辑
多亏了亚瑟(一如既往)的帮助和启发性的回答,我也能完成这个证明。我在下面给出我的版本以供参考

Lemma lex_lemma : forall s1 s2 s3, lex s1 s2 -> lex s2 s3 -> lex s1 s3.
  cofix.
  intros s1 s2 s3 lex12 lex23.
  inversion lex12; inversion lex23.
  rewrite  <- (cons_ht s1).
  rewrite  <- (cons_ht s3).
  constructor; simpl.
  inversion lex12; inversion lex23; omega.
  intros; eapply lex_lemma; [apply H0 | apply H2]; omega.
Qed.
引理lex_引理:对于所有s1 s2 s3,lex s1 s2->lex s2 s3->lex s1 s3。 科菲克斯。 介绍s1 s2 s3 lex12 lex23。 倒置lex12;第23条。
重写你的证明的一个问题是,在引入
s1s2 s3
之后,你调用
cofix
太晚了。因此,您得到的共导假设,
lex s1 s2
,不是很有用:为了在保护的同时应用它,正如您所提到的,我们需要在应用了
lex
的构造函数之后再这样做。然而,在这样做之后,我们需要在某个点上证明
lex(tail s1)(tail s3)
是成立的,而
cofix
引入的假设不能起到任何作用

为了解决这个问题,我们需要在引入变量之前调用
cofix
,这样它产生的假设就足够一般。我冒昧地重新制定了您对
lex
的定义,以便在这样的证明中更容易操作:

CoInductive lex : Stream nat -> Stream nat -> Prop :=
| le_head n1 n2 s1 s2 : n1 < n2 -> lex (Cons n1 s1) (Cons n2 s2)
| le_tail n s1 s2 : lex s1 s2 -> lex (Cons n s1) (Cons n s2).

Lemma lex_trans : forall s1 s2 s3, lex s1 s2 -> lex s2 s3 -> lex s1 s3.
Proof.
  cofix.
  intros s1 s2 s3 lex12 lex23.
  inversion lex12; subst; clear lex12;
  inversion lex23; subst; clear lex23;
  try (apply le_head; omega).
  apply le_tail; eauto.
Qed.
conductive-lex:Stream-nat->Stream-nat->Prop:=
|le_头n1 n2 s1 s2:n1lex(Cons n1 s1)(Cons n2 s2)
|le_tail n s1s2:lex s1s2->lex(Cons n s1)(Cons n s2)。
引理lex_trans:forall s1 s2 s3,lex s1 s2->lex s2 s3->lex s1 s3。
证明。
科菲克斯。
介绍s1 s2 s3 lex12 lex23。
倒置lex12;subst;清除lex12;
倒置lex23;subst;清除lex23;
试试(涂上勒乌头;欧米茄)。
应用leu尾;奥托。
Qed。
现在,假设的形式是

对于所有s1 s2 s3,lex s1 s2->lex s2 s3->lex s1 s3

只要生成的应用程序受到保护,就可以很容易地应用到流的尾部

CoInductive lex : Stream nat -> Stream nat -> Prop :=
| le_head n1 n2 s1 s2 : n1 < n2 -> lex (Cons n1 s1) (Cons n2 s2)
| le_tail n s1 s2 : lex s1 s2 -> lex (Cons n s1) (Cons n s2).

Lemma lex_trans : forall s1 s2 s3, lex s1 s2 -> lex s2 s3 -> lex s1 s3.
Proof.
  cofix.
  intros s1 s2 s3 lex12 lex23.
  inversion lex12; subst; clear lex12;
  inversion lex23; subst; clear lex23;
  try (apply le_head; omega).
  apply le_tail; eauto.
Qed.