Library Coq.Reals.Cauchy.QExtra
Require Import QArith.
Require Import Qpower.
Require Import Qabs.
Require Import Qround.
Require Import Lia.
Require Import Lqa. Require Import PosExtra.
Require Import Qpower.
Require Import Qabs.
Require Import Qround.
Require Import Lia.
Require Import Lqa. Require Import PosExtra.
Lemma Q_factorDenom : forall (a:Z) (b d:positive), (a # (d * b)) == (1#d) * (a#b).
Lemma Q_factorNum_l : forall (a b : Z) (c : positive),
(a*b # c == (a # 1) * (b # c))%Q.
Lemma Q_factorNum : forall (a : Z) (b : positive),
(a # b == (a # 1) * (1 # b))%Q.
Lemma Q_reduce_fl : forall (a b : positive),
(Z.pos a # a * b == (1 # b))%Q.
Lemma Qle_neq: forall p q : Q, p < q <-> p <= q /\ ~ (p == q).
Lemma Qplus_lt_compat : forall x y z t : Q,
(x < y)%Q -> (z < t)%Q -> (x + z < y + t)%Q.
Lemma Qgt_lt: forall p q : Q, p > q -> q < p.
Lemma Qlt_gt: forall p q : Q, p < q -> q > p.
Notation "x <= y < z" := (x<=y/\y<z) : Q_scope.
Notation "x < y <= z" := (x<y/\y<=z) : Q_scope.
Notation "x < y < z" := (x<y/\y<z) : Q_scope.
Lemma Qmult_lt_0_compat : forall a b : Q,
0 < a
-> 0 < b
-> 0 < a * b.
Lemma Qmult_lt_1_compat:
forall a b : Q, (1 < a)%Q -> (1 < b)%Q -> (1 < a * b)%Q.
Lemma Qmult_le_1_compat:
forall a b : Q, (1 <= a)%Q -> (1 <= b)%Q -> (1 <= a * b)%Q.
Lemma Qmult_lt_compat_nonneg: forall x y z t : Q,
(0 <= x < y)%Q -> (0 <= z < t)%Q -> (x * z < y * t)%Q.
Lemma Qmult_lt_le_compat_nonneg: forall x y z t : Q,
(0 < x <= y)%Q -> (0 < z < t)%Q -> (x * z < y * t)%Q.
Lemma Qmult_le_compat_nonneg: forall x y z t : Q,
(0 <= x <= y)%Q -> (0 <= z <= t)%Q -> (x * z <= y * t)%Q.
Lemma Qinv_swap_pos: forall (a b : positive),
Z.pos a # b == / (Z.pos b # a).
Lemma Qinv_swap_neg: forall (a b : positive),
Z.neg a # b == / (Z.neg b # a).
Lemma Qabs_Qlt_condition: forall x y : Q,
Qabs x < y <-> -y < x < y.
Lemma Qabs_gt: forall r s : Q,
(r < s)%Q -> (r < Qabs s)%Q.
Lemma Qpower_0_r: forall q:Q,
q^0 == 1.
Lemma Qpower_1_r: forall q:Q,
q^1 == q.
Lemma Qpower_not_0: forall (a : Q) (z : Z),
~ a == 0 -> ~ Qpower a z == 0.
Lemma Qpower_pos_lt: forall (a : Q) (z : Z),
a > 0 -> Qpower a z > 0.
Lemma Qpower_minus: forall (a : Q) (n m : Z),
~ a == 0 -> a ^ (n - m) == a ^ n / a ^ m.
Lemma Qpower_minus_pos: forall (a b : positive) (n m : Z),
(Z.pos a#b) ^ (n - m) == (Z.pos a#b) ^ n * (Z.pos b#a) ^ m.
Lemma Qpower_minus_neg: forall (a b : positive) (n m : Z),
(Z.neg a#b) ^ (n - m) == (Z.neg a#b) ^ n * (Z.neg b#a) ^ m.
Lemma Qpower_lt_1_increasing:
forall (q : Q) (n : positive), (1<q)%Q -> (1 < q ^ (Z.pos n))%Q.
Lemma Qpower_lt_1_increasing':
forall (q : Q) (n : Z), (1<q)%Q -> (0<n)%Z -> (1 < q ^ n)%Q.
Lemma Qzero_eq: forall (d : positive),
(0#d == 0)%Q.
Lemma Qpower_le_1_increasing:
forall (q : Q) (n : positive), (1<=q)%Q -> (1 <= q ^ (Z.pos n))%Q.
Lemma Qpower_le_1_increasing':
forall (q : Q) (n : Z), (1<=q)%Q -> (0<=n)%Z -> (1 <= q ^ n)%Q.
Lemma Qpower_lt_compat:
forall (q : Q) (n m : Z), (n < m)%Z -> (1<q)%Q -> (q ^ n < q ^ m)%Q.
Lemma Qpower_le_compat:
forall (q : Q) (n m : Z), (n <= m)%Z -> (1<=q)%Q -> (q ^ n <= q ^ m)%Q.
Lemma Qpower_lt_compat_inv:
forall (q : Q) (n m : Z), (q ^ n < q ^ m)%Q -> (1<q)%Q -> (n < m)%Z.
Lemma Qpower_le_compat_inv:
forall (q : Q) (n m : Z), (q ^ n <= q ^ m)%Q -> (1<q)%Q -> (n <= m)%Z.
Lemma Qpower_decomp': forall (p : positive) (a : Z) (b : positive),
(a # b) ^ (Z.pos p) == a ^ (Z.pos p) # (b ^ p)%positive.
Lemma QarchimedeanExp2_Pos : forall q : Q,
{p : positive | (q < Z.pos (2^p) # 1)%Q}.
Fixpoint Pos_log2floor_plus1 (p : positive) : positive :=
match p with
| (p'~1)%positive => Pos.succ (Pos_log2floor_plus1 p')
| (p'~0)%positive => Pos.succ (Pos_log2floor_plus1 p')
| 1%positive => 1
end.
Lemma Pos_log2floor_plus1_spec : forall (p : positive),
(Pos.pow 2 (Pos_log2floor_plus1 p) <= 2 * p < 2 * Pos.pow 2 (Pos_log2floor_plus1 p))%positive.
Fixpoint Pos_log2ceil_plus1 (p : positive) : positive :=
match p with
| (p'~1)%positive => Pos.succ (Pos.succ (Pos_log2floor_plus1 p'))
| (p'~0)%positive => Pos.succ (Pos_log2ceil_plus1 p')
| 1%positive => 1
end.
Lemma Pos_log2ceil_plus1_spec : forall (p : positive),
(Pos.pow 2 (Pos_log2ceil_plus1 p) < 4 * p <= 2 * Pos.pow 2 (Pos_log2ceil_plus1 p))%positive.
Fixpoint Pos_is_pow2 (p : positive) : bool :=
match p with
| (p'~1)%positive => false
| (p'~0)%positive => Pos_is_pow2 p'
| 1%positive => true
end.
Definition Qbound_le_ZExp2 (q : Q) : Z :=
match Qnum q with
| Z0 => -1000
| Zneg p => 0
| Zpos p => (Z.pos (Pos_log2ceil_plus1 p) - Z.pos (Pos_log2floor_plus1 (Qden q)))%Z
end.
Lemma Qbound_le_ZExp2_spec : forall (q : Q),
(q <= 2^(Qbound_le_ZExp2 q))%Q.
Definition Qbound_leabs_ZExp2 (q : Q) : Z := Qbound_le_ZExp2 (Qabs q).
Lemma Qbound_leabs_ZExp2_spec : forall (q : Q),
(Qabs q <= 2^(Qbound_leabs_ZExp2 q))%Q.
Power of two open upper bound q < 2^z and Qabs q < 2^z
Definition Qbound_lt_ZExp2 (q : Q) : Z :=
match Qnum q with
| Z0 => -1000
| Zneg p => 0
| Zpos p => Z.pos_sub (Pos.succ (Pos_log2floor_plus1 p)) (Pos_log2floor_plus1 (Qden q))
end.
Remark Qbound_lt_ZExp2_test_1 : Qbound_lt_ZExp2 (4#4) = 1%Z.
Remark Qbound_lt_ZExp2_test_2 : Qbound_lt_ZExp2 (5#4) = 1%Z.
Remark Qbound_lt_ZExp2_test_3 : Qbound_lt_ZExp2 (4#5) = 1%Z.
Remark Qbound_lt_ZExp2_test_4 : Qbound_lt_ZExp2 (7#5) = 1%Z.
Lemma Qbound_lt_ZExp2_spec : forall (q : Q),
(q < 2^(Qbound_lt_ZExp2 q))%Q.
Definition Qbound_ltabs_ZExp2 (q : Q) : Z := Qbound_lt_ZExp2 (Qabs q).
Lemma Qbound_ltabs_ZExp2_spec : forall (q : Q),
(Qabs q < 2^(Qbound_ltabs_ZExp2 q))%Q.
Power of 2 open lower bounds for 2^z < q and 2^z < Qabs q
Definition Qlowbound_ltabs_ZExp2 (q : Q) : Z := -2 + Qbound_ltabs_ZExp2 q.
Lemma Qlowbound_ltabs_ZExp2_inv: forall q : Q,
q > 0
-> Qlowbound_ltabs_ZExp2 q = (- Qbound_ltabs_ZExp2 (/q))%Z.
Lemma Qlowbound_ltabs_ZExp2_opp: forall q : Q,
(Qlowbound_ltabs_ZExp2 q = Qlowbound_ltabs_ZExp2 (-q))%Z.
Lemma Qlowbound_lt_ZExp2_spec : forall (q : Q) (Hqgt0 : q > 0),
(2^(Qlowbound_ltabs_ZExp2 q) < q)%Q.
Lemma Qlowbound_ltabs_ZExp2_spec : forall (q : Q) (Hqgt0 : ~ q == 0),
(2^(Qlowbound_ltabs_ZExp2 q) < Qabs q)%Q.
Lemma Qlowbound_ltabs_ZExp2_inv: forall q : Q,
q > 0
-> Qlowbound_ltabs_ZExp2 q = (- Qbound_ltabs_ZExp2 (/q))%Z.
Lemma Qlowbound_ltabs_ZExp2_opp: forall q : Q,
(Qlowbound_ltabs_ZExp2 q = Qlowbound_ltabs_ZExp2 (-q))%Z.
Lemma Qlowbound_lt_ZExp2_spec : forall (q : Q) (Hqgt0 : q > 0),
(2^(Qlowbound_ltabs_ZExp2 q) < q)%Q.
Lemma Qlowbound_ltabs_ZExp2_spec : forall (q : Q) (Hqgt0 : ~ q == 0),
(2^(Qlowbound_ltabs_ZExp2 q) < Qabs q)%Q.
Definition QarchimedeanExp2_Z (q : Q)
: {z : Z | (q < 2^z)%Q}
:= exist _ (Qbound_lt_ZExp2 q) (Qbound_lt_ZExp2_spec q).
Definition QarchimedeanAbsExp2_Z (q : Q)
: {z : Z | (Qabs q < 2^z)%Q}
:= exist _ (Qbound_ltabs_ZExp2 q) (Qbound_ltabs_ZExp2_spec q).
Definition QarchimedeanLowExp2_Z (q : Q) (Hqgt0 : q > 0)
: {z : Z | (2^z < q)%Q}
:= exist _ (Qlowbound_ltabs_ZExp2 q) (Qlowbound_lt_ZExp2_spec q Hqgt0).
Definition QarchimedeanLowAbsExp2_Z (q : Q) (Hqgt0 : ~ q == 0)
: {z : Z | (2^z < Qabs q)%Q}
:= exist _ (Qlowbound_ltabs_ZExp2 q) (Qlowbound_ltabs_ZExp2_spec q Hqgt0).