intros c y z Hc Hy Hz Hzc. rewrite <- Z_div_mult with (a := z / y - c / y * z / c) (b := c * y).
rewrite Zmult_minus_distr_r. rewrite Zmult_comm with (n := c). rewrite Zmult_assoc.
rewrite Zdiv_a_b_b_Zmod. rewrite Zmult_comm with (n := y). rewrite Zmult_assoc. rewrite Zdiv_a_b_b_Zmod.
do 2 rewrite Zmult_minus_distr_r. rewrite <- Zmult_assoc. rewrite Zmult_comm with (m := y).
rewrite Zmult_assoc. rewrite Zdiv_a_b_b_Zmod. rewrite Zmult_minus_distr_r.
replace (z * c - z mod y * c - (c * z - c mod y * z - (c / y * z) mod c * y))
with (c mod y * z + (c / y * z) mod c * y - z mod y * c).
apply Zle_trans with ((c mod y * z + c * y) / (c * y)). apply Zdiv_le. apply Zmult_lt_0_compat;
assumption. apply Zle_trans with (c mod y * z + (c / y * z) mod c * y). cut (0 <= z mod y * c). omega.
apply Zmult_le_0_compat. apply Zmod_le_0_z. assumption. omega. apply Zplus_le_compat. omega.
apply Zmult_le_compat_r. apply Zlt_le_weak. apply Zmod_lt_z_m. assumption. omega.
replace (c mod y * z + c * y) with (1 * (c * y) + c mod y * z).
rewrite Zdiv_times_plus. cut (c mod y * z / (c * y) <= 0). omega.
apply Zle_trans with ((y - 1) * z / (c * y)). apply Zdiv_le. apply Zmult_lt_0_compat; assumption.
apply Zmult_le_compat_r. cut (c mod y < y). omega. apply Zmod_lt_z_m.
assumption. omega. rewrite Zdiv_small_0. omega. apply Zmult_le_0_compat; omega.
rewrite Zmult_comm with (n := c). elim (Zle_lt_or_eq 0 z). intro H. apply Zlt_le_trans with (y * z).
apply Zmult_lt_compat_r. assumption. omega. apply Zmult_le_compat_l; omega. intro H. rewrite <- H.
replace ((y - 1) * 0) with 0. apply Zmult_lt_0_compat; assumption. ring. assumption.
apply Zmult_lt_0_compat; assumption. ring. ring. assumption. assumption. assumption.
apply Zmult_gt_0_compat; omega. Qed.

(* Specifications: *)
Lemma approx_le1 : forall a b y x : Z, 0 < a -> 0 < b -> 0 < y -> 0 <= x -> x < a * b + a ->
x / a * a / y - x / a * (a * b / y) / b <= 1.