Definition Zlog_sup (M : Z) :=
  match M with
  | Zpos p => log_sup p
  | _ => 0
  end.

(* Specifications: *)
Lemma Zlog_sup_pow : forall i : Z, 0 <= i -> Zlog_sup (2 ^ i) = i.
Lemma two_p_pow : forall z : Z, 0 <= z -> two_p z = 2 ^ z.
Lemma Zlog_sup_correct1 : forall z : Z, 0 < z -> 0 <= Zlog_sup z.
Lemma Zlog_sup_correct2 : forall z : Z, 0 < z -> 2 ^ (Zlog_sup z - 1) < z <= 2 ^ Zlog_sup z.
Lemma Zlog_sup_unique : forall z : Z, 0 < z -> forall i j : Z, 0 <= i -> 0 <= j -> 2 ^ (i - 1) < z -> z <= 2 ^ i -> 2 ^ (j - 1) < z -> z <= 2 ^ j -> i = j.
Lemma Zlog_sup_from_interval : forall z : Z, 0 < z -> forall i : Z, 0 <= i -> 2 ^ (i - 1) < z -> z <= 2 ^ i -> Zlog_sup z = i.
Lemma Zlog_sup_seq : forall p q : Z, p <= q -> Zlog_sup p <= Zlog_sup q.
Lemma Z_pow_plus : forall x : Z, 0 <= x -> 2 ^ x + 2 ^ x = 2 ^ (x + 1).
Lemma Zdivdivdiv : forall x y z : Z, 0 < y -> 0 < z -> x / y / z = x / (y * z).
Lemma Zdiv_simpl : forall x y z : Z, 0 < y -> 0 < z -> (x * z) / (y * z) = x / y.
Lemma Zdiv_den_le : forall x y z : Z, 0 <= x -> 0 < z -> z <= y -> x / y <= x / z.
Lemma approx_cz : forall c y z : Z, 0 < c -> 0 < y -> 0 <= z -> z <= c -> z / y - c / y * z / c <= 1.
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.
Lemma approx_m1_one : forall a b y x : Z, 0 < a -> 0 < b -> 0 < y -> 0 <= x -> x < a * b + a -> x / a * a / y - 1 <= x / a * (a * b / y) / b.
Lemma approx_cz0 : forall c y z : Z, 0 < c -> 0 < y -> 0 <= z -> c / y * z / c <= z / y.
Lemma approx_ab_le : forall a b y x : Z, 0 < a -> 0 < b -> 0 < y -> 0 <= x -> x / a * (a * b / y) / b <= x / a * a / y.
Lemma approx_m1_two : forall y a b x : Z, 0 < y -> 0 < a -> a <= y -> 0 < b -> 0 <= x -> x / y - 1 <= x / a * a / y.
Lemma approx_m2 : forall y a b x : Z, 0 < y -> 0 < a -> a <= y -> 0 < b -> 0 <= x -> x < a * b + a -> x / y - 2 <= x / a * (a * b / y) / b.
Lemma approx_0_one : forall y a b x : Z, 0 < y -> 0 < a -> 0 < b -> 0 <= x -> x / a * (a * b / y) / b <= x / a * a / y.
Lemma approx_0_two : forall y a b x : Z, 0 < y -> 0 < a -> 0 < b -> 0 <= x -> x / a * a / y <= x / y.
Lemma approx_0 : forall y a b x : Z, 0 < y -> 0 < a -> 0 < b -> 0 <= x -> x / a * (a * b / y) / b <= x / y.
Lemma mod_over_div : forall a b c m : Z, 0 < b -> 0 < m -> (a * b + c) / b * b mod m = (a mod m * b + c) / b * b mod m.
Lemma sum_r'_i : forall a b m : Z, 0 < m -> (a mod m + b mod m) / m = 0 \/ (a mod m + b mod m) / m = 1.
Lemma mod_plus : forall a b m : Z, 0 < m -> a mod m + b mod m = (a + b) mod m \/ a mod m + b mod m = (a + b) mod m + m.
Lemma div_m_1 : forall m : Z, 0 < m -> 2 ^ Zlog_sup m / m = 1.
Lemma div_r'_i : forall a m : Z, 0 < m -> a mod 2 ^ Zlog_sup m / m = 0 \/ a mod 2 ^ Zlog_sup m / m = 1.
Theorem approx_0_m2 : forall (y b : Zpls) (a : Z_ y) (x : Z_ (a * b + a)), x / y - 2 <= x / a * (a * b / y) / b <= x / y.
Theorem div_approx1 : forall (y : Zpls) (a : Zpls) (b : Zpls) (x : Z_ (a * b + a)), x / a * a / y - 1 <= x / a * (a * b / y) / b <= x / a * a / y.