Ltac ptrofs_simpl_mod A H :=
  let H0 := fresh "H" in
  let H1 := fresh "H" in
  match A with
  | (?B + ?C)%Z =>
    ptrofs_simpl_mod B H0; ptrofs_simpl_mod C H1;
    pose proof Ptrofs.eqmod_add Ptrofs.modulus _ _ _ _ H0 H1 as H;
    clear H1 H0
  | (?B - ?C)%Z =>
    ptrofs_simpl_mod B H0; ptrofs_simpl_mod C H1;
    pose proof Ptrofs.eqmod_sub Ptrofs.modulus _ _ _ _ H0 H1 as H;
    clear H1 H0
  | (?B * ?C)%Z =>
    ptrofs_simpl_mod B H0; ptrofs_simpl_mod C H1;
    pose proof Ptrofs.eqmod_mult Ptrofs.modulus _ _ _ _ H0 H1 as H;
    clear H1 H0
  | (- ?B)%Z =>
    ptrofs_simpl_mod B H0;
    pose proof Ptrofs.eqmod_neg Ptrofs.modulus _ _ H0 as H;
    clear H0
  | ?B mod Ptrofs.modulus =>
    ptrofs_simpl_mod B H0;
    pose proof ptrofs_modm_mod_elim B _ H0 as H;
    clear H0
  | ptrofs_modm ?B =>
    ptrofs_simpl_mod B H0;
    pose proof ptrofs_modm_mod_elim B _ H0 as H;
    clear H0
  | _ =>
    pose proof Ptrofs.eqmod_refl Ptrofs.modulus A as H
  end.Ltac solve_mod_modulus :=
  unfold Int.add; rewrite ?Int.unsigned_repr_eq;
  unfold Ptrofs.add; rewrite ?Ptrofs.unsigned_repr_eq;
  repeat
  match goal with
  | |- context [?A mod Int.modulus] =>
         let H := fresh "H" in int_simpl_mod A H;
         rewrite (int_modm_mod_eq A _ H);
         clear H
  | |- context [Int.repr ?A] =>
         let H := fresh "H" in int_simpl_mod A H;
         rewrite (int_modm_repr_eq A _ H);
         clear H
  | |- context [?A mod Ptrofs.modulus] =>
         let H := fresh "H" in int_simpl_mod A H;
         rewrite (int_modm_mod_eq A _ H);
         clear H
  | |- context [Int.repr ?A] =>
         let H := fresh "H" in int_simpl_mod A H;
         rewrite (int_modm_repr_eq A _ H);
         clear H
  | |- context [?A mod Ptrofs.modulus] =>
         let H := fresh "H" in ptrofs_simpl_mod A H;
         rewrite (ptrofs_modm_mod_eq A _ H);
         clear H
  | |- context [Ptrofs.repr ?A] =>
         let H := fresh "H" in ptrofs_simpl_mod A H;
         rewrite (ptrofs_modm_repr_eq A _ H);
         clear H
  | |- context [?A mod Ptrofs.modulus] =>
         let H := fresh "H" in ptrofs_simpl_mod A H;
         rewrite (ptrofs_modm_mod_eq A _ H);
         clear H
  | |- context [Ptrofs.repr ?A] =>
         let H := fresh "H" in ptrofs_simpl_mod A H;
         rewrite (ptrofs_modm_repr_eq A _ H);
         clear H
  end;
  unfold int_modm, int_reprm, ptrofs_modm, ptrofs_reprm in *.

(* Specifications: *)
Lemma add_repr: forall i j, Int.add (Int.repr i) (Int.repr j) = Int.repr (i+j).
Lemma mul_repr: forall x y, Int.mul (Int.repr x) (Int.repr y) = Int.repr (x * y).
Lemma sub_repr: forall i j, Int.sub (Int.repr i) (Int.repr j) = Int.repr (i-j).
Lemma ptrofs_add_repr: forall i j, Ptrofs.add (Ptrofs.repr i) (Ptrofs.repr j) = Ptrofs.repr (i+j).
Lemma ptrofs_mul_repr: forall x y, Ptrofs.mul (Ptrofs.repr x) (Ptrofs.repr y) = Ptrofs.repr (x * y).
Lemma ptrofs_sub_repr: forall i j, Ptrofs.sub (Ptrofs.repr i) (Ptrofs.repr j) = Ptrofs.repr (i-j).
Lemma Zland_two_p: forall i n, (0 <= n)%Z -> Z.land i (Z.ones n) = i mod (2 ^ n).
Lemma and_repr : forall i j : Z, Int.and (Int.repr i) (Int.repr j) = Int.repr (Z.land i j).
Lemma or_repr : forall i j : Z, Int.or (Int.repr i) (Int.repr j) = Int.repr (Z.lor i j).
Lemma add64_repr: forall i j, Int64.add (Int64.repr i) (Int64.repr j) = Int64.repr (i+j).
Lemma mul64_repr: forall x y, Int64.mul (Int64.repr x) (Int64.repr y) = Int64.repr (x * y).
Lemma sub64_repr: forall i j, Int64.sub (Int64.repr i) (Int64.repr j) = Int64.repr (i-j).
Lemma and64_repr : forall i j : Z, Int64.and (Int64.repr i) (Int64.repr j) = Int64.repr (Z.land i j).
Lemma or64_repr : forall i j : Z, Int64.or (Int64.repr i) (Int64.repr j) = Int64.repr (Z.lor i j).
Lemma neg_repr: forall i, Int.neg (Int.repr i) = Int.repr (-i).
Lemma neg64_repr: forall i, Int64.neg (Int64.repr i) = Int64.repr (-i).
Lemma align_0: forall z, z > 0 -> align 0 z = 0.
Lemma align_1: forall n, align n 1 = n.
Lemma fold_right_andb: forall bl b, fold_right andb b bl = true -> forall b0, In b0 bl -> b0 = true.
Lemma Z2Nat_inj_0: forall z, z >= 0 -> Z.to_nat z = 0%nat -> z = 0.
Lemma Z2Nat_id': forall n, Z.of_nat (Z.to_nat n) = Z.max 0 n.
Lemma nil_or_non_nil: forall {A} (a: list A), {a = nil} + {a <> nil}.
Lemma Permutation_concat: forall {A} (P Q: list (list A)), Permutation P Q -> Permutation (concat P) (concat Q).
Lemma proj_sumbool_is_false: forall (P: Prop) (a: {P}+{~P}), ~P -> proj_sumbool a = false.
Lemma ptrofs_to_int_repr: forall x, (Ptrofs.to_int (Ptrofs.repr x)) = Int.repr x.