Section projection.
Variable A : Set.
Variable P : A -> Prop.
Definition projP1 (H : sig P) := let (x, h) := H in x.
Definition projP2 (H : sig P) :=
let (x, h) as H return (P (projP1 H)) := H in h.
End projection.
(*###########################################################################*)
(* Declaring some relations on natural numbers for stepl and stepr tactics.  *)
(*###########################################################################*)
Declare Left Step le_stepl.
Declare Right Step le_stepr.
Declare Left Step lt_stepl.
Declare Right Step lt_stepr.
Declare Left Step neq_stepl.
Declare Right Step neq_stepr.
(*###########################################################################*)
(** Some random facts about natural numbers, positive numbers and integers   *)
(*###########################################################################*)
(*###########################################################################*)
(* Declaring some relations on integers for stepl and stepr tactics.         *)
(*###########################################################################*)
Declare Left Step Zle_stepl.
Declare Right Step Zle_stepr.
Declare Left Step Zlt_stepl.
Declare Right Step Zlt_stepr.
Declare Left Step Zneq_stepl.
Declare Right Step Zneq_stepr.
(*###########################################################################*)
(** Informative case analysis                                                *)
(*###########################################################################*)
(*###########################################################################*)
(** General auxiliary lemmata                                                *)
(*###########################################################################*)
intros.
apply Zgt_trans with (m := (n + p)%Z).
rewrite Zplus_comm.
rewrite Zplus_comm with (n := n).
apply Zplus_gt_compat_l.
assumption.
apply Zplus_gt_compat_l.
assumption.
Qed.
Hint Resolve Zmult_pos_pos Zmult_neg_neg Zmult_neg_pos Zmult_pos_neg: zarith.
Hint Resolve square_pos: zarith.
(*###########################################################################*)
(** Properties of positive numbers, mapping between Z and nat                *)
(*###########################################################################*)
Definition Z2positive (z : Z) :=
match z with
| Zpos p => p
| Zneg p => p
| Z0 => 1%positive
end.
Definition pred_nat : forall (x : Z) (Hx : (0 < x)%Z), nat.
intros [| px| px] Hx; try abstract (discriminate Hx).
exact (pred (nat_of_P px)).
Defined.
Let pred_nat_unfolded_subproof px :
Pos.to_nat px <> 0.
(*###########################################################################*)
(** Properties of Zsgn                                                       *)
(*###########################################################################*)
Hint Resolve Zsgn_1 Zsgn_2 Zsgn_3 Zsgn_4 Zsgn_5 Zsgn_6 Zsgn_7 Zsgn_7' Zsgn_8
Zsgn_9 Zsgn_10 Zsgn_11 Zsgn_12 Zsgn_13 Zsgn_14 Zsgn_15 Zsgn_16 Zsgn_17
Zsgn_18 Zsgn_19 Zsgn_20 Zsgn_21 Zsgn_22 Zsgn_23 Zsgn_24 Zsgn_25 Zsgn_26
Zsgn_27: zarith.
(*###########################################################################*)
(** Properties of Zabs                                                       *)
(*###########################################################################*)
Hint Resolve Zabs_1 Zabs_2 Zabs_3 Zabs_4 Zabs_5 Zabs_6 Zabs_7 Zabs_8 Zabs_9
Zabs_10 Zabs_11 Zabs_12 Zabs_min Zabs_neg Zabs_mult Zabs_plus Zle_Zabs: zarith.
(*###########################################################################*)
(** Induction on Z                                                           *)
(*###########################################################################*)
(*###########################################################################*)
(** Properties of Zmax                                                       *)
(*###########################################################################*)
Definition Zmax (n m : Z) := (n + m - Z.min n m)%Z.
Hint Resolve ZmaxSS Zle_max_r Zle_max_l Zmax_n_n: zarith.
(*###########################################################################*)
(** Properties of Arity                                                      *)
(*###########################################################################*)
(* This lemma used to be useful since it was mentioned with an unnecessary premise `x>=0` as Z_modulo_2 in ZArith, but the ZArith version has been fixed. *)
Definition Z_modulo_2_always :
forall x : Z, {y : Z | x = (2 * y)%Z} + {y : Z | x = (2 * y + 1)%Z} :=
Zeven.Z_modulo_2.
(*###########################################################################*)
(** Properties of Zdiv                                                       *)
(*###########################################################################*)

Lemma Z_div_mod_eq_2 :
forall a b : Z, (0 < b)%Z -> (b * (a / b))%Z = (a - a mod b)%Z.