Coq:为什么重写定理中的引理会创建两个子目标?
Coq: Why rewrite of lemma in theorem create two subgoal?
我正在尝试证明我的非零函数分布在列表的连接上。
我是这样写的带过滤器的nonzeros':
Definition nonzeros' (l : list nat) : list nat := filter (fun x => match x with | O => false | _ => true end) l.
我已经证明了这 2 个引理:
Lemma nonzeros'_remove_0 :
forall (a b: list nat),
nonzeros' (0 :: b) = nonzeros' b.
Proof.
intros a b.
unfold nonzeros'.
simpl.
reflexivity.
Qed.
Lemma nonzeros'_not_remove_Sn :
forall (a b: list nat) (n : nat),
nonzeros' (S n :: b) = S n :: nonzeros' b.
Proof.
intros a b n.
unfold nonzeros'.
simpl.
reflexivity.
Qed.
现在我必须通过 concat 证明分布:
Lemma nonzero'_distribution_over_concat :
forall (a b : list nat),
nonzeros' (concat a b) = concat (nonzeros' a) (nonzeros' b).
为了证明这一点,我做了以下事情:
Proof.
intros a b.
induction a as [| h t IHa].
-
simpl.
reflexivity.
-
simpl.
destruct h.
+ rewrite nonzeros'_remove_0. rewrite nonzeros'_remove_0. rewrite IHa. reflexivity.
问题是后招
rewrite nonzeros'_remove_0.
Coq 创建 2 个子目标:
______________________________________(1/2)
nonzeros' (concat t b) = concat (nonzeros' (0 :: t)) (nonzeros' b)
______________________________________(2/2)
list nat
第二个子目标是意外的。为什么会出现?
引理有一个未使用的参数a : list nat
:
Lemma nonzeros'_remove_0 :
forall (a b: list nat),
nonzeros' (0 :: b) = nonzeros' b.
因此,要应用该引理,您需要提供这样一个列表,并且除了通过额外目标询问您之外,没有办法告诉您它应该是哪个列表。还可以开发自动化以在此处做出任意选择,但更好的解决方法是首先从引理中删除未使用的参数。
Lemma nonzeros'_remove_0 :
forall (b: list nat),
nonzeros' (0 :: b) = nonzeros' b.
我正在尝试证明我的非零函数分布在列表的连接上。
我是这样写的带过滤器的nonzeros':
Definition nonzeros' (l : list nat) : list nat := filter (fun x => match x with | O => false | _ => true end) l.
我已经证明了这 2 个引理:
Lemma nonzeros'_remove_0 :
forall (a b: list nat),
nonzeros' (0 :: b) = nonzeros' b.
Proof.
intros a b.
unfold nonzeros'.
simpl.
reflexivity.
Qed.
Lemma nonzeros'_not_remove_Sn :
forall (a b: list nat) (n : nat),
nonzeros' (S n :: b) = S n :: nonzeros' b.
Proof.
intros a b n.
unfold nonzeros'.
simpl.
reflexivity.
Qed.
现在我必须通过 concat 证明分布:
Lemma nonzero'_distribution_over_concat :
forall (a b : list nat),
nonzeros' (concat a b) = concat (nonzeros' a) (nonzeros' b).
为了证明这一点,我做了以下事情:
Proof.
intros a b.
induction a as [| h t IHa].
-
simpl.
reflexivity.
-
simpl.
destruct h.
+ rewrite nonzeros'_remove_0. rewrite nonzeros'_remove_0. rewrite IHa. reflexivity.
问题是后招
rewrite nonzeros'_remove_0.
Coq 创建 2 个子目标:
______________________________________(1/2)
nonzeros' (concat t b) = concat (nonzeros' (0 :: t)) (nonzeros' b)
______________________________________(2/2)
list nat
第二个子目标是意外的。为什么会出现?
引理有一个未使用的参数a : list nat
:
Lemma nonzeros'_remove_0 :
forall (a b: list nat),
nonzeros' (0 :: b) = nonzeros' b.
因此,要应用该引理,您需要提供这样一个列表,并且除了通过额外目标询问您之外,没有办法告诉您它应该是哪个列表。还可以开发自动化以在此处做出任意选择,但更好的解决方法是首先从引理中删除未使用的参数。
Lemma nonzeros'_remove_0 :
forall (b: list nat),
nonzeros' (0 :: b) = nonzeros' b.