1

Here's a minimal example of my problem

Lemma arith: forall T (G: seq T), (size G + 1 + 1).+1 = (size G + 3).

I would like to be able to reduce this to forall T (G: seq T), (size G + 2).+1 = (size G + 3).

by the simplest possible means. Trying simpl or auto immediately does nothing.

If I rewrite with associativity first, that is,

intros. rewrite - addnA. simpl. auto.,

simpl and auto still do nothing. I am left with a goal of

(size G + (1 + 1)).+1 = size G + 3

I guess the .+1 is "in the way" of simpl and auto working on the (1+1) somehow. It seems like I must first remove the .+1 before I can simplify the 1+1.

However, in my actual proof, there is a lot more stuff than the .+1 "in the way" and I would really like to simplify my copious amount of +1s first. As a hack, I'm using 'replace' on individual occurrences but this feels very clumsy (and there are a lot of different arithmetic expressions to replace). Is there any better way to do this?

I am using the ssrnat library.

Thanks.

push33n
  • 398
  • 4
  • 12

2 Answers2

2

There are many lemmas in ssrnat to reason about addition. One possible solution to your problem is the following:

From mathcomp Require Import all_ssreflect.

Lemma arith: forall T (G: seq T), (size G + 1 + 1).+1 = (size G + 3).
Proof. by move=> T G; rewrite !addn1 addn3. Qed.

where

addn1 : forall n, n + 1 = n.+1
addn3 : forall n, n + 3 = n.+3 (* := n.+1.+1.+1 *)

You can use the Search command to look for lemmas related to certain term patterns. For instance, Search (_ + 1) returns, among other things, addn1.

Arthur Azevedo De Amorim
  • 23,012
  • 3
  • 33
  • 39
  • hello! thank you! unfortunately, the .+1 thing was just a simple example to show a case where simpl doesn't do the trick. in my actual use case i have a bunch of other things cluttering up my goal, and i'd like to simplify the 1+1+1... before I attend to them. is there any way to do this? – push33n May 25 '21 at 00:21
  • 1
    @push33n Can't you do `rewrite !addn1`, or use the `ring` tactic as suggested by the other answer? The rewrite should in principle collapse all the ones. – Arthur Azevedo De Amorim May 26 '21 at 01:36
2

Coq has a ring and ring_simplify tactic for this kind of work. Sorry for my ssreflect ignorant intros, but this works:

From mathcomp Require Import all_ssreflect.

Lemma arith: forall T (G: seq T), (size G + 1 + 1).+1 = (size G + 3).
Proof.
  intros.
  ring.
Qed.

There is also a field and field_simplify. For inequalities there are lia and lra, but I am not sure if these work in mathcomp - for lia you might need this (https://github.com/math-comp/mczify) but it might be integrated meanwhile.

M Soegtrop
  • 1,268
  • 2
  • 8
  • Thank you! This did fix my simple example but didn't fix my convoluted use-case lol (I get a ``Arguments of ring_simplify do not have all the same type`` error). I'll mess around with ring more and see what I can get it to do :). – push33n May 27 '21 at 02:06
  • 1
    This error means you give ring_simplify e.g. one argument of type `nat` and another one of type `Z`. You should do separate calls to ring_simplify for separate types, but for several expressions of the same type, one call is preferable, because otherwise the same order is not guaranteed. – M Soegtrop May 30 '21 at 07:11