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.