Require Coq.funind.Recdef.
Ltac inv_int i :=
let ofs := fresh "ofs" in
let H := fresh "H" in
let H0 := fresh "H" in
let H1 := fresh "H" in
match type of i with
| int =>
pose proof Int.repr_unsigned i as H;
pose proof Int.unsigned_range i as H0;
remember (Int.unsigned i) as ofs eqn:H1;
rewrite <- H in *;
clear H H1; try clear i
| ptrofs =>
pose proof Ptrofs.repr_unsigned i as H;
pose proof Ptrofs.unsigned_range i as H0;
remember (Ptrofs.unsigned i) as ofs eqn:H1;
rewrite <- H in *;
clear H H1; try clear i
end.
(**************************************************  Solve_mod_modulus  **************************************************)
Definition int_modm x := x mod Int.modulus.
Definition int_reprm := Int.repr.
Ltac int_simpl_mod A H :=
let H0 := fresh "H" in
let H1 := fresh "H" in
match A with
| (?B + ?C)%Z =>
int_simpl_mod B H0; int_simpl_mod C H1;
pose proof Zbits.eqmod_add Int.modulus _ _ _ _ H0 H1 as H;
clear H1 H0
| (?B - ?C)%Z =>
int_simpl_mod B H0; int_simpl_mod C H1;
pose proof Zbits.eqmod_sub Int.modulus _ _ _ _ H0 H1 as H;
clear H1 H0
| (?B * ?C)%Z =>
int_simpl_mod B H0; int_simpl_mod C H1;
pose proof Zbits.eqmod_mult Int.modulus _ _ _ _ H0 H1 as H;
clear H1 H0
| (- ?B)%Z =>
int_simpl_mod B H0;
pose proof Zbits.eqmod_neg Int.modulus _ _ H0 as H;
clear H0
| ?B mod Int.modulus =>
int_simpl_mod B H0;
pose proof int_modm_mod_elim B _ H0 as H;
clear H0
| int_modm ?B =>
int_simpl_mod B H0;
pose proof int_modm_mod_elim B _ H0 as H;
clear H0
| _ =>
pose proof Zbits.eqmod_refl Int.modulus A as H
end.
Definition ptrofs_modm x := x mod Ptrofs.modulus.

Lemma ptrofs_modm_mod_elim: forall x y, Zbits.eqmod Ptrofs.modulus x y -> Zbits.eqmod Ptrofs.modulus (x mod Ptrofs.modulus) y.