Coq 一个相互归纳命题的证明

Coq 一个相互归纳命题的证明,coq,induction,Coq,Induction,考虑以下代码: 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 :=

考虑以下代码:

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 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 
*)
根据上述类型和我看到的示例,我成功地完成了以下证明:

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


编辑:也可以得到
odd_length l->odd_length(map f l)
假设吗

要通过归纳证明这一点,我们需要对引理进行推广,以获得更强的归纳假设,或者使用自定义归纳方案,将两个元素同时添加到列表中,而不是仅添加一个元素(这也需要这样的推广)

由于默认的归纳方案(
inclusion l
)一次只添加一个元素,因此我们需要一个中间谓词来记录列表在两个状态之间的“状态”,即长度为偶数,也就是说,我们还需要记住
l
长度为奇数的情况

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.
您可以应用相同的思想证明偶数长度列表的更一般归纳方案,通过
应用偶数列表ind
,您的
映射偶数
定理将非常容易遵循。(编辑:另一个候选人,
使用偶数列表ind的入职培训失败,我不知道为什么。)


我设法证明了
map\u奇偶
,但到目前为止还没有
偶数
。有什么建议吗?此外,当我尝试使用偶数列表进行归纳时,Coq抱怨“归纳参数的数量不正确(预期为2个参数)”。@RafaelCastro更直接的解决方案是使用
偶数长度mut
(或与答案中的第一个引理类似的风格)和
p0l
(由
奇数长度l
隐含的属性)简单地说明
l
的尾部满足
P
。我发现一个更优雅的解决方案是将定理及其证明写成
不动点,它允许您使用两个嵌套的
匹配
,从而完全跳过“奇数”case.@Li yao Xia关于“归纳参数数量不正确(应为2个参数)”的修复的任何信息?这个错误是什么意思?我不知道这意味着什么,也不知道如何修复归纳法的这种用法,但另一种方法是使用
apply
。我可以用
intros A B f;apply偶_list_ind.
进行证明。对于归纳谓词,通常最好使用
最小值
而不是
归纳法
偶数长度mut
奇数长度mut
的定义。请参见示例。
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.