IMP.简单命令式程序.Coq自动化

Coq Automation

最后一个证明中重复的次数有点烦人。如果算术表达式的语言或被证明合理的优化明显更复杂,那么它将开始成为一个真正的问题。

到目前为止,我们所做的所有证明都只使用了Coq的一小部分策略,而完全忽略了它自动构造部分证明的强大功能。本节将介绍其中的一些设施,我们将在接下来的几章中看到更多内容。习惯它们需要一些精力——Coq的自动化是一个强有力的工具——但它将允许我们扩大我们的工作范围,以获得更复杂的定义和更有趣的属性,而不会被无聊、重复、低级的细节所淹没。

Tacticals

战术是Coq对以其他战术为论据的战术的术语——“高阶战术”,如果你愿意的话。

The try Tactical

如果T是一种策略,那么try T是一种与T类似的策略,只是如果T失败,try T成功地什么都不做(而不是失败)。

Theorem silly1 : forall ae, aeval ae = aeval ae.
Proof. try reflexivity. //这就是反射性。
Qed.
Theorem silly2 : forall (P : Prop), P -> P.
Proof.
  intros P HP.
  try reflexivity. //仅仅是自反性就会失败。
  apply HP.//我们仍然可以用其他方式完成证明。
Qed.

并没有真正的理由在像这样的完全手工校对中使用try,但它对于结合自动化校对是非常有用的;战术,我们接下来展示。

The ; Tactical (Simple Form)

最常见的形式是;战术以两种战术作为论据。复合战术T;T'首先执行T,然后对T生成的每个子目标执行T'。

例如,考虑下面的微不足道引理:

Lemma foo : forall n, 0 <=? n = true.
Proof.
  intros.
  destruct n.
    (* Leaves two subgoals, which are discharged identically...  *)
    - (* n=0 *) simpl. reflexivity.
    - (* n=Sn' *) simpl. reflexivity.
Qed.

我们可以使用;策略简化此证明:

Lemma foo' : forall n, 0 <=? n = true.
Proof.
  intros.
  (* [destruct] the current goal *)
  destruct n;
  (* then [simpl] each resulting subgoal *)
  simpl;
  (* and do [reflexivity] on each resulting subgoal *)
  reflexivity.
Qed.

同时使用try和;,我们可以消除刚才困扰我们的证明中的重复。

Theorem optimize_0plus_sound': forall a,
  aeval (optimize_0plus a) = aeval a.
Proof.
  intros a.
  induction a;
    (* Most cases follow directly by the IH... *)
    try (simpl; rewrite IHa1; rewrite IHa2; reflexivity).
    (* ... but the remaining cases -- ANum and APlus --
       are different: *)
  - (* ANum *) reflexivity.
  - (* APlus *)
    destruct a1 eqn:Ea1;
      (* Again, most cases follow directly by the IH: *)
      try (simpl; simpl in IHa1; rewrite IHa1;
           rewrite IHa2; reflexivity).
    (* The interesting case, on which the [try...]
       does nothing, is when [e1 = ANum n]. In this
       case, we have to destruct [n] (to see whether
       the optimization applies) and rewrite with the
       induction hypothesis. *)
    + (* a1 = ANum n *) destruct n eqn:En;
      simpl; rewrite IHa2; reflexivity.   Qed.

Coq专家经常使用这个“……;try……”成语经过一个像归纳法这样的策略,一次处理了许多类似的情况。当然,这种做法在非正式的证明中也有相似之处。例如,下面是优化定理的非正式证明,它与正式定理的结构相匹配:

_Theorem_: For all arithmetic expressions [a],

       aeval (optimize_0plus a) = aeval a.

    _Proof_: By induction on [a].  Most cases follow directly from the
    IH.  The remaining cases are as follows:

      - Suppose [a = ANum n] for some [n].  We must show

          aeval (optimize_0plus (ANum n)) = aeval (ANum n).

        This is immediate from the definition of [optimize_0plus].

      - Suppose [a = APlus a1 a2] for some [a1] and [a2].  We must
        show

          aeval (optimize_0plus (APlus a1 a2)) = aeval (APlus a1 a2).

        Consider the possible forms of [a1].  For most of them,
        [optimize_0plus] simply calls itself recursively for the
        subexpressions and rebuilds a new expression of the same form
        as [a1]; in these cases, the result follows directly from the
        IH.

        The interesting case is when [a1 = ANum n] for some [n].  If
        [n = 0], then

          optimize_0plus (APlus a1 a2) = optimize_0plus a2

        and the IH for [a2] is exactly what we need.  On the other
        hand, if [n = S n'] for some [n'], then again [optimize_0plus]
        simply calls itself recursively, and the result follows from
        the IH. 

然而,这一证明仍然可以改进:第一个案例(对于a=ANum n)非常琐碎——甚至比我们所说的简单地遵循IH的案例更琐碎——但我们选择将其全部写出来。最好是把它放下,在最上面说,“大多数案件要么是直接的,要么是来自IH的。唯一有趣的案件是APlus的案件……”我们也可以在形式证明上做同样的改进。下面是它的外观:

Theorem optimize_0plus_sound'': forall a,
  aeval (optimize_0plus a) = aeval a.
Proof.
  intros a.
  induction a;
    (* Most cases follow directly by the IH *)
    try (simpl; rewrite IHa1; rewrite IHa2; reflexivity);
    (* ... or are immediate by definition *)
    try reflexivity.
  (* The interesting case is when a = APlus a1 a2. *)
  - (* APlus *)
    destruct a1; try (simpl; simpl in IHa1; rewrite IHa1;
                      rewrite IHa2; reflexivity).
    + (* a1 = ANum n *) destruct n;
      simpl; rewrite IHa2; reflexivity. Qed.

The ; Tactical (General Form)

这个战术也有比简单T更一般的形式;我们已经在上面看到了。如果T,T1。。。,Tn是战术,然后是T;[T1 | T2 |…| Tn]是一种策略,首先执行T,然后对T生成的第一个子目标执行T1,对第二个子目标执行T2,等等。

所以T;T’只是所有Ti都是相同策略时的特殊符号;i、 e,T;T’是:T的简写;[T'| T'|…| T']

The repeat Tactical

重复战术采用另一种战术,并持续应用该战术,直到无法取得进展。下面是一个示例,使用repeat显示10在一个长列表中。

Theorem In10

Theorem In10 : In 10 [1;2;3;4;5;6;7;8;9;10].
Proof.
  repeat (try (left; reflexivity); right).
Qed.

战术重复T从不失败:如果战术T不适用于原始目标,那么重复仍然成功,而不改变原始目标(即重复零次)。

Theorem In10' : In 10 [1;2;3;4;5;6;7;8;9;10].
Proof.
  repeat simpl.
  repeat (left; reflexivity).
  repeat (right; try (left; reflexivity)).
Qed.

战术重复T也没有应用T次数的上限。如果T是一个总是成功(并取得进展)的战术,那么重复T将永远循环。

Theorem repeat_loop

Theorem repeat_loop : forall (m n : nat),
  m + n = n + m.
Proof.
  intros m n.
  (* Uncomment the next line to see the infinite loop occur.
     In Proof General, [C-c C-c] will break out of the loop. *)
  (* repeat rewrite Nat.add_comm. *)
Admitted.

虽然Coq术语语言Gallina的评估保证终止,但战术评估不终止!然而,这并不影响Coq的逻辑一致性,因为重复和其他策略的工作是指导Coq构造证明;如果构建过程出现分歧(即,它没有终止),这仅仅意味着我们没有构建证据,而不是我们构建了错误的证据。

Exercise: 3 stars, standard (optimize_0plus_b_sound)

由于optimize_0plus转换不会更改aexps的值,因此我们应该能够将其应用于bexp中出现的所有aexps,而无需更改bexp的值。编写一个在bexps上执行此转换的函数,并证明它是正确的。使用我们刚刚看到的战术,使证据尽可能优雅。

Fixpoint optimize_0plus_b (b : bexp) : bexp
  (* REPLACE THIS LINE WITH ":= _your_definition_ ." *). Admitted.

Theorem optimize_0plus_b_sound : forall b,
  beval (optimize_0plus_b b) = beval b.
Proof.
  (* FILL IN HERE *) Admitted.

Fixpoint optimize_0plus_b (b : bexp) : bexp

Fixpoint optimize_0plus_b (b : bexp) : bexp :=
  match b with
  | BEq l r => BEq (optimize_0plus l) (optimize_0plus r)
  | BLe l r => BLe (optimize_0plus l) (optimize_0plus r)
  | BNot b' => BNot (optimize_0plus_b b')
  | BAnd l r => BAnd (optimize_0plus_b l) (optimize_0plus_b r)
  | _ => b
  end.

Theorem optimize_0plus_b_sound

Theorem optimize_0plus_b_sound : forall b,
  beval (optimize_0plus_b b) = beval b.
Proof.
  intros.
  induction b;
    try (simpl; reflexivity);
    try (simpl; repeat rewrite optimize_0plus_sound; reflexivity).
  - simpl. rewrite IHb. reflexivity.
  - simpl. rewrite IHb1. rewrite IHb2. reflexivity.
Qed.
【学习】函数语言程序设计 文章被收录于专栏

函数语言程序设计 Coq章节 Ch1 Basics【COQ中的函数编程】 Ch2 Induction【归纳法证明】 Ch3 Lists【使用结构化数据】 Ch4 Poly【多态性与高阶函数】 Ch5 Tactics【更基本的战术】 Ch6 Logic【COQ中的逻辑】 Ch7 IndProp【归纳定义命题】 Ch8 Maps【全图和局部图】 Ch9 Rel【关系的性质】

全部评论

相关推荐

Noel_:中石油是这样的 哥们侥幸混进免笔试名单 一看给我吓尿了
点赞 评论 收藏
分享
点赞 收藏 评论
分享
牛客网
牛客企业服务