intro H2. elim (Zle_or_lt 0 (x / m)); intro H3. elim (Zle_lt_or_eq 0 (x / m)). intro H4.
cut (m * 1 <= m * (x / m)). intro H5. absurd (m * (x / m) < m). omega. assumption.
apply Zmult_le_compat_l. omega. omega. omega. assumption. absurd (x / m < 0). apply Zle_not_lt.
apply Zge_le. apply Z_div_ge0; omega. assumption. cut (0 <= x mod m). omega. elim (Z_mod_lt x m). omega.
omega. rewrite <- Z_div_mod_eq. assumption. omega. Qed.

(* Specifications: *)
Lemma Zle_0_div : forall a m : Z, 0 <= a -> 0 < m -> 0 <= a / m.
intros a m H H0. apply Zge_le. apply Z_div_ge0. omega. omega. Qed.
Lemma Zdiv_le : forall a b m : Z, 0 < m -> a <= b -> a / m <= b / m.
intros. apply Zge_le. apply Z_div_ge. omega. omega. Qed.
Lemma Zmod_plus_m : forall x m : Z, 0 < m -> (x + m) mod m = x mod m.
intros x m H. replace (x + m) with (x + 1 * m). apply Z_mod_plus. omega. ring. Qed.
Lemma Zmod_minus_m : forall x m : Z, 0 < m -> (x - m) mod m = x mod m.
intros x m H. replace (x - m) with (x + -1 * m). apply Z_mod_plus. omega. ring. Qed.
Lemma Zmod_km_plus : forall x k m : Z, 0 < m -> (k * m + x) mod m = x mod m.
intros. rewrite Zplus_comm. apply Z_mod_plus. omega. Qed.
Lemma Zmod_minus_km : forall x k m : Z, 0 < m -> (x - k * m) mod m = x mod m.
intros. unfold Zminus. rewrite <- Zopp_mult_distr_l_reverse. apply Z_mod_plus. omega. Qed.
Lemma Zdivmod_split : forall x m : Z, 0 < m -> x / m * m + x mod m = x.
intros. rewrite Zmult_comm. rewrite <- Z_div_mod_eq. trivial. omega. Qed.
Lemma Zmod_plus_distr_l : forall a b m : Z, 0 < m -> (a + b) mod m = (a mod m + b) mod m.
intros a b m H. replace (a + b) with (a / m * m + a mod m + b). rewrite Zplus_comm.