如何在特定的子表达式中应用重写?

时间:2014-03-24 11:45:12

标签: coq

我正在使用在线图书"软件基础"了解Coq。

在第二章中,要求证明" plus_assoc"定理:

Theorem plus_assoc : forall n m p : nat, n + (m + p) = (n + m) + p.

我使用了两个先前证明的定理:

Theorem plus_comm : forall n m : nat, n + m = m + n.
Theorem plus_n_Sm : forall n m : nat, S (n + m) = n + (S m).

我在n:

上使用归纳证明了plus_assoc定理
Proof.
  intros n m p.
  induction n as [ | n' ].
    reflexivity.

    rewrite plus_comm.
    rewrite <- plus_n_Sm.
    rewrite plus_comm.
    rewrite IHn'.
    symmetry.
    rewrite plus_comm.

此时,上下文(*)为:

1 subgoals
case := "n = S n'" : String.string
n' : nat
m : nat
p : nat
IHn' : n' + (m + p) = n' + m + p
______________________________________(1/1)
p + (S n' + m) = S (n' + m + p)

我想使用plus_comm来获取

p + (m + S n') = S (n' + m + p)

然后是plus_n_sm

p + S (m + n') = S (n' + m + p)

然后再加上plus_n_sm

S (p + (m + n')) = S (n' + m + p)

并使用plus_comm两次完成证明然后反身性

S (p + (n' + m)) = S (n' + m + p)
S (n' + m + p) = S (n' + m + p)

小问题是我不知道如何将plus_comm应用于(S n&#39; + m)。

最大的问题是:为什么发布

apply plus_comm.

立即完成证明(在给定的上下文中(*))?

提前感谢您的任何澄清!

Fabian Pijcke

1 个答案:

答案 0 :(得分:4)

您可以通过用(S n&#39;)和m实例化它来将plus_comm应用于(S n&#39; + m)。

    Check plus_comm.
    Check plus_comm (S n').
    Check plus_comm (S n') m.
    rewrite (plus_comm (S n') m).
    rewrite <- plus_n_Sm.
    rewrite <- plus_n_Sm.
    rewrite (plus_comm m n').
    rewrite plus_comm.
    reflexivity.
Qed.

我认为使用Require Import Coq.Setoids.Setoid.然后使用rewrite plus_comm at 2.是 应该具有相同的效果,但它不起作用。

apply plus_comm完成目标的原因是因为apply执行统一 模数转换。也就是说,p + (S n' + m) = S (n' + m + p)可转换为 p + (S n' + m) = S n' + m + pp + (S n' + m) = S n' + m + p是统一的 ?1 + ?2 = ?2 + ?1

事实上,如果使用simpl策略进行缩减,则证明会缩短。

Theorem plus_assoc : forall n m p : nat, n + (m + p) = (n + m) + p.
Proof.
induction n.
  reflexivity.

  intros.
  simpl.
  apply f_equal.
  apply IHn.
Qed.