Coq:出现在箭头左侧时,目标变量未通过归纳转换
我试图用l上的归纳法证明下面的定理。这在纸上是一个简单的定理,但是当我试图用Coq证明它时,我并没有达到我期望的归纳目标Coq:出现在箭头左侧时,目标变量未通过归纳转换,coq,induction,Coq,Induction,我试图用l上的归纳法证明下面的定理。这在纸上是一个简单的定理,但是当我试图用Coq证明它时,我并没有达到我期望的归纳目标 Theorem nodup_app__disjoint: forall {X: Type} (l: list X), (forall l1 l2 : list X, l = l1 ++ l2 -> Disjoint l1 l2) -> NoDup l. Proof. intros X l. induction l. - intros F. apply
Theorem nodup_app__disjoint: forall {X: Type} (l: list X),
(forall l1 l2 : list X, l = l1 ++ l2 -> Disjoint l1 l2) -> NoDup l.
Proof.
intros X l. induction l.
- intros F. apply nodup_nil.
- (* ??? *)
此时的国家:
1 subgoal
X : Type
x : X
l : list X
IHl : (forall l1 l2 : list X, l = l1 ++ l2 -> Disjoint l1 l2) -> NoDup l
______________________________________(1/1)
(forall l1 l2 : list X, x :: l = l1 ++ l2 -> Disjoint l1 l2) ->
NoDup (x :: l)
但这根本不是我所期望的目标!难道不应该用l=l1++l2
代替x::l=l1++l2
以下是我正在处理的命题,以防您想重现问题并亲自查看:
Inductive Disjoint {X : Type}: list X -> list X -> Prop :=
| disjoint_nil: Disjoint [] []
| disjoint_left: forall x l1 l2, Disjoint l1 l2 -> ~(In x l2) -> Disjoint (x :: l1) l2
| disjoint_right: forall x l1 l2, Disjoint l1 l2 -> ~(In x l1) -> Disjoint l1 (x :: l2).
Inductive NoDup {X: Type}: list X -> Prop :=
| nodup_nil: NoDup []
| nodup_cons: forall hd tl, NoDup tl -> ~(In hd tl) -> NoDup (hd :: tl).
但这根本不是我所期望的目标!难道不应该用l=l1++l2
代替x::l=l1++l2
简短回答:不应该
列表的归纳原则
让我们回顾一下列表的归纳原则:
Check list_ind.
(*
list_ind
: forall (A : Type) (P : list A -> Prop),
P [] ->
(forall (a : A) (l : list A), P l -> P (a :: l)) ->
forall l : list A, P l
*)
这意味着为了证明谓词p
适用于所有列表(forall l:list a,pl
),需要证明
保留空列表--P
李>P[]
适用于所有非空列表,因为它适用于它们的尾部--P
(对于所有(a:a)(l:list a),pl->P(a::l))
(forall l1 l2, l = l1 ++ l2 -> Disjoint l1 l2) -> NoDup l.
为了了解当我们试图通过归纳法证明l
的陈述时应该达到什么目标,让我们机械地将上面的l
替换为[]
,另一种替换为h::tl
[]
案例:
(forall l1 l2, [] = l1 ++ l2 -> Disjoint l1 l2) -> NoDup [].
(forall l1 l2, h :: tl = l1 ++ l2 -> Disjoint l1 l2) -> NoDup (h :: tl).
h::tl
案例:
(forall l1 l2, [] = l1 ++ l2 -> Disjoint l1 l2) -> NoDup [].
(forall l1 l2, h :: tl = l1 ++ l2 -> Disjoint l1 l2) -> NoDup (h :: tl).
这是您在上面得到的(以重命名为模)。对于第二种情况,你也得到了归纳假设,我们从原始语句中用tl
代替l
:
(forall l1 l2, tl = l1 ++ l2 -> Disjoint l1 l2) -> NoDup tl.
顺便说一句,该定理是可证明的,您可能会发现以下辅助引理很有用:
Lemma disjoint_cons_l {X} (h : X) l1 l2 :
Disjoint (h :: l1) l2 -> Disjoint l1 l2.
Admitted.
Lemma disjoint_singleton {X} h (l : list X) :
Disjoint [h] l -> ~ In h l.
Admitted.
我不确定我是否理解你的定理。
中的l
对于所有l1-l2,l=l1++l2->不相交的l1-l2
似乎没有用。在我看来,归纳方案似乎还可以:由l
绑定的每个实例都将被nil
或x::l
替换。你能说出你想证明的引理吗?也许你用Coq翻译的不正确?另外,你的引理中可能缺少NoDup l1
和NoDup l2
?只是胡乱猜测;)@Vinz前提是,对于列表l
的任何“切块”,“部分”(l1
和l2
)是不相交的。这意味着l
没有重复项。如果在l
中有重复项,它的形式将是l'+[x]++l'+[x]++l'
,这将使我们产生矛盾,因为l1
=l'+[x]
和l2
=l'+[x]++l'
是不相交的。。好吧,我弄错了。谢谢我想你设法把问题的困难归结为这两个引理,因为我对这两个引理都完全不了解!我需要什么特别的技巧吗?对各种参数的归纳使我一无所获。注意,我重用了标准的NoDup
谓词。您可能需要使用记住策略。