如何使用加交换律和结合律重新排列 Coq 中的术语?
how to rearrange terms in Coq using plus communtativity and associativity?
我有一个关于如何在 Coq 中重新排列术语的一般性问题。例如,如果我们有一个术语 m + p + n + p
,人类可以快速将这些术语重新排列为 m + n + p + p
(隐式使用 plus_comm 和 plus_assoc)。我们如何在 Coq 中有效地做到这一点?
举个(愚蠢的)例子,
Require Import Coq.Arith.Plus.
Require Import Coq.Setoids.Setoid.
Theorem plus_comm_test: forall n m p: nat,
m + p + (n + p) = m + n + 2 * p.
Proof. intros. rewrite plus_assoc. simpl. rewrite <- plus_n_O.
现在,我们有
1 subgoals
...
______________________________________(1/1)
m + p + n + p = m + n + (p + p)
我的问题是:
如何有效地将 LHS 重写为 m + n + p + p
?
我尝试使用 rewrite plus_comm at 2
,但出现错误 Nothing to rewrite.
只需使用 rewrite plus_comm
即可将 LHS 更改为 p + m + n + p
。
也欢迎任何关于有效重写的建议。
谢谢。
在这种特殊情况下(整数的线性算术),您可以只使用 omega
策略:
Require Import Omega.
Theorem plus_comm_test: forall n m p: nat,
m + p + (n + p) = m + n + 2 * p.
Proof. intros; omega. Qed.
但是,有些情况下 omega
是不够的。在那些情况下,标准的 rewrite
策略不是很方便。 Ssreflect 库带有它自己版本的 rewrite
策略,它更适合重写目标子项等任务。例如:
Require Import Ssreflect.ssreflect Ssreflect.ssrfun Ssreflect.ssrbool.
Require Import Ssreflect.ssrnat.
Theorem plus_comm_test: forall n m p: nat,
m + p + (n + p) = m + n + 2 * p.
Proof.
move=> n m p.
by rewrite -addnA [p + _]addnC -[_ + p]addnA addnn -mul2n addnA.
Qed.
方括号中的注释,例如 [p + _]
,提供了帮助 rewrite
策略找出行动位置的模式。 addn*
引理和朋友是 Ssreflect 自己版本的自然数标准算术结果。
正如 Arthur 所说,有时 omega
是不够的,但我有时会用它来完成像这样的简单步骤。
Require Import Omega.
Theorem test: forall a b c:nat, a + b + 2 * c = c + b + a + c.
intros.
replace (c + b + a) with (a + b + c) by omega.
replace (a + b + c + c) with (a + b + (c + c)) by omega.
replace (c + c) with (2 * c) by omega.
reflexivity.
Qed.
这是一个愚蠢的例子,因为 omega
可以一次性解决所有问题,但有时您想重写 omega
在没有一点帮助的情况下无法触及的函数内部的东西...
ring
策略能够证明这些重排的相等性。
使用你的例子:
Require Import ZArith.
Open Scope Z_scope.
(* Both "ring" and "omega" can prove this. *)
Theorem plus_comm_test : forall n m p : Z,
m + p + (n + p) = m + n + 2 * p.
Proof.
intros.
ring.
Qed.
ring
适用于整数,但我认为它不适用于自然数。
但是,ring
可以证明一些omega
不能证明的身份。 (docs 说,"Multiplication is handled by omega but only goals where at least one of the two multiplicands of products is a constant are solvable. This is the restriction meant by "Presburger 算术。”)
例如:
(* "ring" can prove this but "omega" cannot. *)
Theorem rearrange_test : forall a b c : Z,
a * (b + c) = c*a + b*a.
Proof.
intros.
ring.
Qed.
我有一个关于如何在 Coq 中重新排列术语的一般性问题。例如,如果我们有一个术语 m + p + n + p
,人类可以快速将这些术语重新排列为 m + n + p + p
(隐式使用 plus_comm 和 plus_assoc)。我们如何在 Coq 中有效地做到这一点?
举个(愚蠢的)例子,
Require Import Coq.Arith.Plus.
Require Import Coq.Setoids.Setoid.
Theorem plus_comm_test: forall n m p: nat,
m + p + (n + p) = m + n + 2 * p.
Proof. intros. rewrite plus_assoc. simpl. rewrite <- plus_n_O.
现在,我们有
1 subgoals
...
______________________________________(1/1)
m + p + n + p = m + n + (p + p)
我的问题是:
如何有效地将 LHS 重写为 m + n + p + p
?
我尝试使用 rewrite plus_comm at 2
,但出现错误 Nothing to rewrite.
只需使用 rewrite plus_comm
即可将 LHS 更改为 p + m + n + p
。
也欢迎任何关于有效重写的建议。
谢谢。
在这种特殊情况下(整数的线性算术),您可以只使用 omega
策略:
Require Import Omega.
Theorem plus_comm_test: forall n m p: nat,
m + p + (n + p) = m + n + 2 * p.
Proof. intros; omega. Qed.
但是,有些情况下 omega
是不够的。在那些情况下,标准的 rewrite
策略不是很方便。 Ssreflect 库带有它自己版本的 rewrite
策略,它更适合重写目标子项等任务。例如:
Require Import Ssreflect.ssreflect Ssreflect.ssrfun Ssreflect.ssrbool.
Require Import Ssreflect.ssrnat.
Theorem plus_comm_test: forall n m p: nat,
m + p + (n + p) = m + n + 2 * p.
Proof.
move=> n m p.
by rewrite -addnA [p + _]addnC -[_ + p]addnA addnn -mul2n addnA.
Qed.
方括号中的注释,例如 [p + _]
,提供了帮助 rewrite
策略找出行动位置的模式。 addn*
引理和朋友是 Ssreflect 自己版本的自然数标准算术结果。
正如 Arthur 所说,有时 omega
是不够的,但我有时会用它来完成像这样的简单步骤。
Require Import Omega.
Theorem test: forall a b c:nat, a + b + 2 * c = c + b + a + c.
intros.
replace (c + b + a) with (a + b + c) by omega.
replace (a + b + c + c) with (a + b + (c + c)) by omega.
replace (c + c) with (2 * c) by omega.
reflexivity.
Qed.
这是一个愚蠢的例子,因为 omega
可以一次性解决所有问题,但有时您想重写 omega
在没有一点帮助的情况下无法触及的函数内部的东西...
ring
策略能够证明这些重排的相等性。
使用你的例子:
Require Import ZArith.
Open Scope Z_scope.
(* Both "ring" and "omega" can prove this. *)
Theorem plus_comm_test : forall n m p : Z,
m + p + (n + p) = m + n + 2 * p.
Proof.
intros.
ring.
Qed.
ring
适用于整数,但我认为它不适用于自然数。
但是,ring
可以证明一些omega
不能证明的身份。 (docs 说,"Multiplication is handled by omega but only goals where at least one of the two multiplicands of products is a constant are solvable. This is the restriction meant by "Presburger 算术。”)
例如:
(* "ring" can prove this but "omega" cannot. *)
Theorem rearrange_test : forall a b c : Z,
a * (b + c) = c*a + b*a.
Proof.
intros.
ring.
Qed.