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 realtions 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 realtions 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 Z.sgn                                                       *)
(*###########################################################################*)
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 Z.abs                                                       *)
(*###########################################################################*)
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                                                           *)
(*###########################################################################*)

Lemma Zind_wf_double :
forall (P : Z -> Z -> Prop) (p0 q0 : Z),
(forall n m : Z,
(forall p q : Z, (q0 <= q)%Z -> (p0 <= p < n)%Z -> P p q) ->
(forall p : Z, (q0 <= p < m)%Z -> P n p) -> P n m) ->
forall p q : Z, (q0 <= q)%Z -> (p0 <= p)%Z -> P p q.