关于coq:关于相互归纳命题的证明

A proof about a mutually inductive proposition

考虑以下代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
Require Import List.

Set Implicit Arguments.

Inductive even_length {A : Type} : list A -> Prop:=
| e_nil : even_length nil
| e_cons : forall e l, odd_length l -> even_length (e::l)
with
  odd_length {A : Type} : list A -> Prop :=
  | o_cons : forall e l, even_length l -> odd_length (e::l).

Lemma map_even : forall A B (f : A -> B) (l : list A),
    even_length l -> even_length (map f l).
Proof.
  induction l.
  (** nil *)
  - intros. simpl. econstructor.
  (** cons *)
  - intros. simpl.
    inversion_clear H.
    econstructor.
    Abort. (** odd_length l -> odd_length (map f l) would help *)

请注意,我希望通过对列表l的归纳来证明这一点。

如此处所述,默认情况下,Coq仅生成非互归原理,并且要获取互归原理,必须使用Scheme命令。
这就是我所做的:

1
2
3
4
5
6
7
8
9
10
11
Scheme even_length_mut := Induction for even_length Sort Prop
with odd_length_mut := Induction for odd_length Sort Prop.

Check even_length_mut.
(**  
even_length_mut
     : forall (A : Type) (P : forall l : list A, even_length l -> Prop) (P0 : forall l : list A, odd_length l -> Prop),
       P nil e_nil ->
       (forall (e : A) (l : list A) (o : odd_length l), P0 l o -> P (e :: l) (e_cons e o)) ->
       (forall (e : A) (l : list A) (e0 : even_length l), P l e0 -> P0 (e :: l) (o_cons e e0)) -> forall (l : list A) (e : even_length l), P l e
*)

通过上面的这种类型以及我看到的示例,我设法像下面这样完成了证明:

1
2
3
4
5
6
7
8
9
Lemma map_even : forall A B (f : A -> B) (l : list A),
    even_length l -> even_length (map f l).
Proof.
  intros.
  apply (even_length_mut (fun l (h : even_length l) => even_length (map f l) )
                         (fun l (h : odd_length l) => odd_length (map f l) )
        );
    try econstructor; auto.
Qed.

但是,这种归纳并没有超过l,这就是所谓的"证据之上的归纳"。

我的问题是even_length_mut中的谓词应该是什么,所以
感应超过l

编辑:另外,有可能得到odd_length l -> odd_length (map f l)假设吗?


为了通过归纳证明这一点,我们需要概括引理以得到更强的归纳假设,或者使用定制的归纳方案,该方案将两个元素同时添加到列表中,而不只是一个元素(这也需要这样的概括)。

由于默认归纳方案(induction l)一次仅添加一个元素,因此我们需要一个中间谓词来记录列表中具有偶数长度的状态之间的"状态",即,我们还需要记住这种情况 其中l是奇数长度。

1
2
3
4
5
Lemma map_odd_even {A B} (f : A -> B) : forall l : list A,
  (even_length l -> even_length (map f l)) /\\
  (odd_length l -> odd_length (map f l)).
Proof.
  induction l.

您可以应用相同的想法为偶数长度的列表证明更通用的归纳方案,您的map_even定理可以通过apply even_list_ind很容易地遵循。 (编辑:另一个候选,induction l using even_list_ind失败,我不知道为什么。)

1
2
3
4
Theorem even_list_ind {A} (P : list A -> Prop) :
  P [] ->
  (forall x y l, even_length l -> P l -> P (x :: y :: l)) ->
  forall l, even_length l -> P l.