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 *) |
请注意,我希望通过对列表
如此处所述,默认情况下,Coq仅生成非互归原理,并且要获取互归原理,必须使用
这就是我所做的:
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. |
但是,这种归纳并没有超过
我的问题是
感应超过
编辑:另外,有可能得到
为了通过归纳证明这一点,我们需要概括引理以得到更强的归纳假设,或者使用定制的归纳方案,该方案将两个元素同时添加到列表中,而不只是一个元素(这也需要这样的概括)。
由于默认归纳方案(
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. |
您可以应用相同的想法为偶数长度的列表证明更通用的归纳方案,您的
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. |