I have a general question about how to rearrange terms in Coq. For example, if we have a term m + p + n + p
, humans can quickly re-arrange the terms to something like m + n + p + p
(implicitly using plus_comm and plus_assoc). How do we do this efficiently in Coq?
For a (silly) example,
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.
Now, we have
1 subgoals
...
______________________________________(1/1)
m + p + n + p = m + n + (p + p)
My question is:
How do I rewrite the LHS to m + n + p + p
effectively?
I tried to use rewrite plus_comm at 2
, but it gives an error Nothing to rewrite.
Simply using rewrite plus_comm
changes the LHS to p + m + n + p
.
Any suggestions on effective rewrites are also welcome.
Thanks.
In this particular case (linear arithmetic over the integers), you can just use the
omega
tactic:However, there are situations where
omega
is not enough. In those cases, the standardrewrite
tactic is not very convenient. The Ssreflect library comes with its own version of therewrite
tactic, that works much better for tasks such as rewriting on sub-terms of your goal. For instance:The annotations in square brackets, such as
[p + _]
, provide patterns that help therewrite
tactic figure out where to act. Theaddn*
lemmas and friends are Ssreflect's own version of the standard arithmetic results over the natural numbers.As Arthur says sometimes
omega
is not enough, but I sometimes use it for simple steps like this.This is a silly example, because
omega
would have solved it all in one go, but sometimes you want to rewrite things inside functions thatomega
can't reach into without a little help...The
ring
tactic is able to prove equality of these rearrangements.Using your example:
ring
works on the integers, but I don't think it works on the natural numbers.However,
ring
is able to prove some identities thatomega
cannot prove. (The docs say, "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 arithmetic".")For example: