我想证明下面的引理。我试图使用战术'破坏',但我 无法证明这一点。请任何身体指导我如何证明这样的引理。我可以为EmptyString证明它,但不能为变量s1和s2证明。感谢
Inductive nat : Set :=
| O : nat
| S : nat -> nat.
Inductive string : Set :=
| EmptyString : string
| String : ascii -> string -> string.
Fixpoint CompStrings (sa : string) (sb : string) {struct sb}: bool :=
match sa with
| EmptyString => match sb with
| EmptyString => true
| String b sb'=> false
end
| String a sa' => match sb with
| EmptyString => false
| String b sb'=> CompStrings sa' sb'
end
end.
Lemma Eq_lenght : forall (s1 s2 : string),
(CompStrings s1 s2) = true -> (Eq_nat (length s1) (length s2)) = true.
答案 0 :(得分:3)
首先,让我争论风格。您可以将CompStrings函数编写为:
Fixpoint CompStrings' (sa : string) (sb : string) {struct sb}: bool :=
match sa, sb with
| EmptyString, EmptyString => true
| EmptyString, _
| _, EmptyString => false
| String a sa', String b sb'=> CompStrings sa' sb'
end.
我觉得它更容易阅读。这是一个证据,它与你的相同,以防你怀疑:
Theorem CompStrings'ok: forall sa sb, CompStrings sa sb = CompStrings' sa sb.
Proof.
intros. destruct sa, sb; simpl; reflexivity.
Qed.
现在,这将是一个双重答案。首先,我只是暗示你向证明方向发展。然后,我会给你一个完整的证明,我鼓励你在自己尝试之前不要阅读。
首先,我假设了length
的这个定义,因为你没有提供它:
Fixpoint length (s: string): nat :=
match s with
| EmptyString => O
| String _ rest => S (length rest)
end.
由于我也没有Eq_nat,我开始证明长度在命题上相等。适应Eq_nat应该是相当微不足道的。
Lemma Eq_length' : forall (s1 s2 : string),
CompStrings s1 s2 = true ->
length s1 = length s2.
Proof.
induction s1.
(* TODO *)
Admitted.
所以这是开始!您想要证明有关归纳数据类型字符串的属性。问题是,您需要通过案例分析来进行,但如果您只是使用destruct
s进行,它将永远不会结束。这就是为什么我们继续induction
。也就是说,您需要证明if s1 is the EmptyString, then the property holds
和if the property holds for a substring, then it holds for the string with one character added
。这两种情况相当简单,在每种情况下,您都可以通过s2上的案例分析(即使用destruct
)继续。
请注意,在intros s1 s2 C.
之前我没有induction s1.
。这一点非常重要,原因如下:如果你这样做(试试!),你的归纳假设就会受到限制,因为它会谈论一个特定的s2
,而不是由它量化。当您开始通过归纳进行校样时,这可能会非常棘手。所以,一定要尝试继续这个证明:
Lemma Eq_length'_will_fail : forall (s1 s2 : string),
CompStrings s1 s2 = true ->
length s1 = length s2.
Proof.
intros s1 s2 C. induction s1.
(* TODO *)
Admitted.
最终,您会发现您的归纳假设无法应用于您的目标,因为它是关于特定s2
的。
我希望你们尝试过这两个练习。
现在,如果你遇到困难,这是证明第一个目标的一种方法。
不要作弊! :)
Lemma Eq_length' : forall (s1 s2 : string),
CompStrings s1 s2 = true ->
length s1 = length s2.
Proof.
induction s1.
intros s2 C. destruct s2. reflexivity. inversion C.
intros s2 C. destruct s2. inversion C. simpl in *. f_equal.
exact (IHs1 _ C).
Qed.
将其置于可理解的术语中:
让我们通过s1:
的归纳来证明属性forall s2, CompStrings s1 s2 = true -> length s1 = s2
在s1是EmptyString
的情况下,让我们看一下s2的形状:
s2是EmptyString
,那么两个长度都等于0,所以reflexivity.
;
s2是String _ _
,所以假设中存在矛盾,由inversion C.
显示;
在s1是String char1 rest1
的情况下,让我们看一下s2的形状,假设该属性为休息时为真:
s2是EmptyString
,所以假设中存在矛盾,由inversion C.
显示;
s2是String char2 rest2
,然后是length s1 = S (length rest1)
和length s2 = S (length rest2)
,因此我们需要证明S (length rest1) = S (length rest2)
。此外,假设C简化为C: CompStrings rest1 rest2 = true
。这是使用归纳假设来证明length rest1 = length rest2
,然后以某种方式使用该结果来证明目标的完美场合。
请注意,对于最后一步,有许多方法可以继续证明S (length rest1) = S (length rest2)
。其中一个是使用f_equal.
,它要求您证明构造函数的参数之间成对相等。您也可以使用rewrite (IHs1 _ C).
然后在该目标上使用反身性。
希望这不仅可以帮助您解决这一特定目标,还可以通过归纳获得对证据的初步了解!
关闭此页面,这里有两个有趣的链接。
This presents the basics of induction (see paragraph "Induction on lists").
This explains, better than me, why and how to generalize your induction hypotheses.您将使用策略intros s1 s2 C.
了解如何通过在开始归纳之前将s2
放回目标中来解决我generalize (dependent)
所做的目标{{1}}
一般情况下,我建议您阅读whole book。它节奏缓慢且很有说服力。