基于函数证明引理含义

时间:2012-06-12 13:13:42

标签: proof coq

我想证明下面的引理。我试图使用战术'破坏',但我         无法证明这一点。请任何身体指导我如何证明这样的引理。我可以为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.

1 个答案:

答案 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 holdsif 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的形状:

      1. s2是EmptyString,那么两个长度都等于0,所以reflexivity.;

      2. s2是String _ _,所以假设中存在矛盾,由inversion C.显示;

    • 在s1是String char1 rest1的情况下,让我们看一下s2的形状,假设该属性为休息时为真:

      1. s2是EmptyString,所以假设中存在矛盾,由inversion C.显示;

      2. 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。它节奏缓慢且很有说服力。