Require Import Coq.ZArith.BinInt.
Require Import Coq.micromega.Lia.
Require Import Coq.ZArith.ZArith.
Local Open Scope Z_scope.
Module ZLib.
forall n : Z, n mod 2 = 0 \/ n mod 2 = 1
forall n : Z, n mod 2 = 0 \/ n mod 2 = 1
n mod 2 = 0 \/ n mod 2 = 1
n:Z
H:0 < 2 -> 0 <= n mod 2 < 2
n mod 2 = 0 \/ n mod 2 = 1
lia.
Qed.
forall a b : Z, b <> 0 -> a mod b = 0 -> a / b * b = a
forall a b : Z, b <> 0 -> a mod b = 0 -> a / b * b = a
a, b:Z
H:b <> 0
H0:a mod b = 0
a / b * b = a
a, b:Z
H:b <> 0
H0:a mod b = 0
A:forall a b c : Z,
b <> 0 -> c <> 0 -> c * a / (c * b) = a / b
a / b * b = a
a, b:Z
H:b <> 0
H0:a mod b = 0
A:1 <> 0 -> b <> 0 -> b * a / (b * 1) = a / 1
a / b * b = a
a, b:Z
H:b <> 0
H0:a mod b = 0
A:1 <> 0 -> b <> 0 -> b * a / b = a / 1
a / b * b = a
a, b:Z
H:b <> 0
H0:a mod b = 0
A:1 <> 0 -> b <> 0 -> b * a / b = a
a / b * b = a
a, b:Z
H:b <> 0
H0:a mod b = 0
A:1 <> 0 -> b <> 0 -> b * a / b = a
b * (a / b) = a
a, b:Z
H:b <> 0
H0:a mod b = 0
A:1 <> 0 -> b <> 0 -> b * a / b = a
b * a / b = a
a, b:Z
H:b <> 0
H0:a mod b = 0
A:1 <> 0 -> b <> 0 -> b * a / b = a
b * a / b = a
apply A; congruence.
a, b:Z
H:b <> 0
H0:a mod b = 0
A:1 <> 0 -> b <> 0 -> b * a / b = a
(b | a)
apply Z.mod_divide; assumption.
Qed.
forall m : Z, m mod 0 = 0
forall m : Z, m mod 0 = 0
destruct m; reflexivity.
Qed.
forall a b m : Z,
a mod m = 0 -> b mod m = 0 -> (a - b) mod m = 0
forall a b m : Z,
a mod m = 0 -> b mod m = 0 -> (a - b) mod m = 0
a mod m = 0 -> b mod m = 0 -> (a - b) mod m = 0
a, b, m:Z
E1:a mod m = 0
E2:b mod m = 0
(a - b) mod m = 0
a, b, m:Z
E1:a mod m = 0
E2:b mod m = 0
(a mod m - b mod m) mod m = 0
a, b, m:Z
E1:a mod m = 0
E2:b mod m = 0
(0 - b mod m) mod m = 0
a, b, m:Z
E1:a mod m = 0
E2:b mod m = 0
(0 - 0) mod m = 0
reflexivity.
Qed.
forall a b m : Z,
a mod m = 0 -> b mod m = 0 -> (a + b) mod m = 0
forall a b m : Z,
a mod m = 0 -> b mod m = 0 -> (a + b) mod m = 0
a mod m = 0 -> b mod m = 0 -> (a + b) mod m = 0
a, b, m:Z
E1:a mod m = 0
E2:b mod m = 0
(a + b) mod m = 0
a, b, m:Z
E1:a mod m = 0
E2:b mod m = 0
(a mod m + b mod m) mod m = 0
a, b, m:Z
E1:a mod m = 0
E2:b mod m = 0
(0 + b mod m) mod m = 0
a, b, m:Z
E1:a mod m = 0
E2:b mod m = 0
(0 + 0) mod m = 0
reflexivity.
Qed.
forall a b : Z, (a * b) mod a = 0
forall a b : Z, (a * b) mod a = 0
apply Z_mod_mult.
Qed.
forall a b : Z, b <> 0 -> (a + b) mod b = a mod b
forall a b : Z, b <> 0 -> (a + b) mod b = a mod b
(a + b mod b) mod b = a mod b
reflexivity.
Qed.
forall a n : Z,
a mod 2 ^ n = a ->
2 ^ n = 0 /\ a = 0 \/ 0 <= a < 2 ^ n
forall a n : Z,
a mod 2 ^ n = a ->
2 ^ n = 0 /\ a = 0 \/ 0 <= a < 2 ^ n
2 ^ n = 0 /\ a = 0 \/ 0 <= a < 2 ^ n
a, n:Z
H:a mod 2 ^ n = a
C:n < 0 \/ 0 <= n
2 ^ n = 0 /\ a = 0 \/ 0 <= a < 2 ^ n
a, n:Z
H:a mod 2 ^ n = a
C:n < 0
2 ^ n = 0 /\ a = 0 \/ 0 <= a < 2 ^ n
a, n:Z
H:a mod 2 ^ n = a
C:n < 0
2 ^ n = 0 /\ a = 0 \/ 0 <= a < 2 ^ n
a, n:Z
H:a mod 2 ^ n = a
C:n < 0
2 ^ n = 0 /\ a = 0
a, n:Z
H:a mod 0 = a
C:n < 0
0 = 0 /\ a = 0
auto.
a, n:Z
H:a mod 2 ^ n = a
C:0 <= n
2 ^ n = 0 /\ a = 0 \/ 0 <= a < 2 ^ n
a, n:Z
H:a mod 2 ^ n = a
C:0 <= n
0 <= a < 2 ^ n
a, n:Z
H:a mod 2 ^ n = a
C:0 <= n
0 <= a mod 2 ^ n < 2 ^ n
a, n:Z
H:a mod 2 ^ n = a
C:0 <= n
0 < 2 ^ n
apply Z.pow_pos_nonneg; lia.
Qed.
forall a n : Z,
a mod 2 ^ n = a -> 0 <= n -> 0 <= a < 2 ^ n
forall a n : Z,
a mod 2 ^ n = a -> 0 <= n -> 0 <= a < 2 ^ n
a, n:Z
H:a mod 2 ^ n = a
H0:0 <= n
0 <= a < 2 ^ n
a, n:Z
H:a mod 2 ^ n = a
H0:0 <= n
0 <= a mod 2 ^ n < 2 ^ n
a, n:Z
H:a mod 2 ^ n = a
H0:0 <= n
0 < 2 ^ n
apply Z.pow_pos_nonneg; lia.
Qed.
lia.
Qed.
forall n : Z, 0 <= n -> 0 < 2 ^ n
forall n : Z, 0 <= n -> 0 < 2 ^ n
apply Z.pow_pos_nonneg; lia.
Qed.
forall i : Z, 0 < i -> 2 ^ i = 2 * 2 ^ (i - 1)
forall i : Z, 0 < i -> 2 ^ i = 2 * 2 ^ (i - 1)
2 ^ i = 2 ^ Z.succ (i - 1)
lia.
Qed.
forall i : Z, 0 <= i -> 2 ^ (i - 1) = 2 ^ i / 2
forall i : Z, 0 <= i -> 2 ^ (i - 1) = 2 ^ i / 2
i:Z
H:0 <= i
C:i = 0 \/ 0 < i
2 ^ (i - 1) = 2 ^ i / 2
reflexivity.
2 ^ i / 2 ^ 1 = 2 ^ i / 2
reflexivity.
Qed.
forall a b : Z, 0 <= a -> 0 < b -> a / b * b <= a
forall a b : Z, 0 <= a -> 0 < b -> a / b * b <= a
a, b:Z
H:0 <= a
H0:0 < b
P:b <> 0 -> a mod b = a - a / b * b
a / b * b <= a
a, b:Z
H:0 <= a
H0:0 < b
P:b <> 0 -> a mod b = a - a / b * b
Q:0 <= a -> 0 < b -> 0 <= a mod b < b
a / b * b <= a
lia.
Qed.
forall a i : Z,
0 <= a -> 0 <= i -> Z.testbit a i = true -> 2 ^ i <= a
forall a i : Z,
0 <= a -> 0 <= i -> Z.testbit a i = true -> 2 ^ i <= a
a, i:Z
H:0 <= a
H0:0 <= i
H1:Z.testbit a i = true
2 ^ i <= a
a, i:Z
H:0 <= a
H0:0 <= i
H1:(a / 2 ^ i) mod 2 = 1
2 ^ i <= a
a, i:Z
H:0 <= a
H0:0 <= i
H1:(a / 2 ^ i) mod 2 = 1
H2:0 < 2 ^ i
2 ^ i <= a
a, i:Z
H:0 <= a
H0:0 <= i
H1:(a / 2 ^ i) mod 2 = 1
H2:0 < 2 ^ i
2 ^ i <= a / 2 ^ i * 2 ^ i
a, i:Z
H:0 <= a
H0:0 <= i
H1:(a / 2 ^ i) mod 2 = 1
H2:0 < 2 ^ i
1 * 2 ^ i <= a / 2 ^ i * 2 ^ i
a, i:Z
H:0 <= a
H0:0 <= i
H1:(a / 2 ^ i) mod 2 = 1
H2:0 < 2 ^ i
1 <= a / 2 ^ i
a, i:Z
H:0 <= a
H0:0 <= i
H1:(a / 2 ^ i) mod 2 = 1
H2:0 < 2 ^ i
H3:0 <= a -> 0 < 2 ^ i -> 0 <= a / 2 ^ i
1 <= a / 2 ^ i
a, i:Z
H:0 <= a
H0:0 <= i
H1:(a / 2 ^ i) mod 2 = 1
H2:0 < 2 ^ i
H3:0 <= a -> 0 < 2 ^ i -> 0 <= a / 2 ^ i
a / 2 ^ i <> 0
a, i:Z
H:0 <= a
H0:0 <= i
H1:(a / 2 ^ i) mod 2 = 1
H2:0 < 2 ^ i
H3:0 <= a -> 0 < 2 ^ i -> 0 <= a / 2 ^ i
E:a / 2 ^ i = 0
False
a, i:Z
H:0 <= a
H0:0 <= i
H1:0 mod 2 = 1
H2:0 < 2 ^ i
H3:0 <= a -> 0 < 2 ^ i -> 0 <= a / 2 ^ i
E:a / 2 ^ i = 0
False
a, i:Z
H:0 <= a
H0:0 <= i
H1:0 = 1
H2:0 < 2 ^ i
H3:0 <= a -> 0 < 2 ^ i -> 0 <= a / 2 ^ i
E:a / 2 ^ i = 0
False
discriminate H1.
Qed.
forall a b c d : Z,
0 < d -> a <= b <= c -> a / d <= b / d <= c / d
forall a b c d : Z,
0 < d -> a <= b <= c -> a / d <= b / d <= c / d
a, b, c, d:Z
H:0 < d
H1:a <= b
H2:b <= c
a / d <= b / d
a, b, c, d:Z
H:0 < d
H1:a <= b
H2:b <= c
a / d <= b / d
apply (Z.div_le_mono _ _ _ H H1).
a, b, c, d:Z
H:0 < d
H1:a <= b
H2:b <= c
b / d <= c / d
apply (Z.div_le_mono _ _ _ H H2).
Qed.
forall a i : Z,
0 <= i ->
2 ^ i <= a < 2 ^ (i + 1) -> Z.testbit a i = true
forall a i : Z,
0 <= i ->
2 ^ i <= a < 2 ^ (i + 1) -> Z.testbit a i = true
a, i:Z
H:0 <= i
H0:2 ^ i <= a < 2 ^ (i + 1)
Z.testbit a i = true
a, i:Z
H:0 <= i
H0:2 ^ i <= a < 2 ^ (i + 1)
(a / 2 ^ i) mod 2 = 1
a, i:Z
H:0 <= i
A:2 ^ i <= a
B:a < 2 ^ (i + 1)
(a / 2 ^ i) mod 2 = 1
a, i:Z
H:0 <= i
A:2 ^ i <= a
B:a < 2 ^ (i + 1)
Q:0 < 2 ^ i
(a / 2 ^ i) mod 2 = 1
a, i:Z
H:0 <= i
A:2 ^ i / 2 ^ i <= a / 2 ^ i
B:a < 2 ^ (i + 1)
Q:0 < 2 ^ i
(a / 2 ^ i) mod 2 = 1
a, i:Z
H:0 <= i
A:1 <= a / 2 ^ i
B:a < 2 ^ (i + 1)
Q:0 < 2 ^ i
(a / 2 ^ i) mod 2 = 1
a, i:Z
H:0 <= i
A:1 <= a / 2 ^ i
B:a < 2 ^ (i + 1)
Q:0 < 2 ^ i
P:a < 2 ^ i * 2 -> a / 2 ^ i < 2
(a / 2 ^ i) mod 2 = 1
a, i:Z
H:0 <= i
A:1 <= a / 2 ^ i
B:a < 2 ^ (i + 1)
Q:0 < 2 ^ i
P:a < 2 * 2 ^ i -> a / 2 ^ i < 2
(a / 2 ^ i) mod 2 = 1
a, i:Z
H:0 <= i
A:1 <= a / 2 ^ i
B:a < 2 ^ (i + 1)
Q:0 < 2 ^ i
P:a < 2 * 2 ^ (i + 1 - 1) -> a / 2 ^ (i + 1 - 1) < 2
(a / 2 ^ i) mod 2 = 1
a, i:Z
H:0 <= i
A:1 <= a / 2 ^ i
B:a < 2 ^ (i + 1)
Q:0 < 2 ^ i
P:a < 2 ^ (i + 1) -> a / 2 ^ (i + 1 - 1) < 2
(a / 2 ^ i) mod 2 = 1
a, i:Z
H:0 <= i
A:1 <= a / 2 ^ i
B:a < 2 ^ (i + 1)
Q:0 < 2 ^ i
P:a / 2 ^ (i + 1 - 1) < 2
(a / 2 ^ i) mod 2 = 1
a, i:Z
H:0 <= i
A:1 <= a / 2 ^ i
B:a < 2 ^ (i + 1)
Q:0 < 2 ^ i
P:a / 2 ^ i < 2
(a / 2 ^ i) mod 2 = 1
a, i:Z
H:0 <= i
A:1 <= a / 2 ^ i
B:a < 2 ^ (i + 1)
Q:0 < 2 ^ i
P:a / 2 ^ i < 2
1 mod 2 = 1
reflexivity.
Qed.
forall a i : Z,
0 <= a < 2 ^ i ->
0 < i ->
Z.testbit a (i - 1) = false -> a < 2 ^ (i - 1)
forall a i : Z,
0 <= a < 2 ^ i ->
0 < i ->
Z.testbit a (i - 1) = false -> a < 2 ^ (i - 1)
a, i:Z
H:0 <= a < 2 ^ i
H0:0 < i
H1:Z.testbit a (i - 1) = false
a < 2 ^ (i - 1)
a, i:Z
H:0 <= a < 2 ^ i
H0:0 < i
H1:Z.testbit a (i - 1) = false
C:2 ^ (i - 1) <= a < 2 ^ i \/ a < 2 ^ (i - 1)
a < 2 ^ (i - 1)
a, i:Z
H:0 <= a < 2 ^ i
H0:0 < i
H1:Z.testbit a (i - 1) = false
C:2 ^ (i - 1) <= a < 2 ^ i
False
a, i:Z
H:0 <= a < 2 ^ i
H0:0 < i
H1:Z.testbit a (i - 1) = false
C:2 ^ (i - 1) <= a < 2 ^ i
Z.testbit a (i - 1) = true
a, i:Z
H:0 <= a < 2 ^ i
H0:0 < i
H1:Z.testbit a (i - 1) = false
C:2 ^ (i - 1) <= a < 2 ^ (i - 1 + 1)
Z.testbit a (i - 1) = true
apply testbit_true_nonneg'; lia.
Qed.
forall sz n : Z,
- 2 ^ (sz - 1) <= n < 2 ^ (sz - 1) -> 0 < sz
forall sz n : Z,
- 2 ^ (sz - 1) <= n < 2 ^ (sz - 1) -> 0 < sz
sz, n:Z
H:- 2 ^ (sz - 1) <= n < 2 ^ (sz - 1)
0 < sz
sz, n:Z
H:- 2 ^ (sz - 1) <= n < 2 ^ (sz - 1)
C:0 < sz \/ sz - 1 < 0
0 < sz
sz, n:Z
H:- 2 ^ (sz - 1) <= n < 2 ^ (sz - 1)
C:sz - 1 < 0
False
sz, n:Z
H:- 0 <= n < 0
C:sz - 1 < 0
False
lia.
Qed.
forall base a b c d : Z,
0 <= b < base ->
0 <= d < base -> base * a + b = base * c + d -> b = d
forall base a b c d : Z,
0 <= b < base ->
0 <= d < base -> base * a + b = base * c + d -> b = d
base, a, b, c, d:Z
H:0 <= b < base
H0:0 <= d < base
H1:base * a + b = base * c + d
b = d
base, a, b, c, d:Z
H:0 <= b < base
H0:0 <= d < base
H1:base * a + b = base * c + d
P:forall a b q r : Z,
0 <= r < b \/ b < r <= 0 ->
a = b * q + r -> r = a mod b
b = d
base, a, b, c, d:Z
H:0 <= b < base
H0:0 <= d < base
H1:base * a + b = base * c + d
P:forall a : Z,
0 <= d < base \/ base < d <= 0 ->
a = base * c + d -> d = a mod base
b = d
base, a, b, c, d:Z
H:0 <= b < base
H0:0 <= d < base
H1:base * a + b = base * c + d
P:0 <= d < base \/ base < d <= 0 ->
d = (base * a + b) mod base
b = d
base, a, b, c, d:Z
H:0 <= b < base
H0:0 <= d < base
H1:base * a + b = base * c + d
P:0 <= d < base \/ base < d <= 0 ->
d = (base * a + b) mod base
b = (base * a + b) mod base
base, a, b, c, d:Z
H:0 <= b < base
H0:0 <= d < base
H1:base * a + b = base * c + d
P:0 <= d < base \/ base < d <= 0 ->
d = (base * a + b) mod base
b = ((base * a) mod base + b) mod base
base, a, b, c, d:Z
H:0 <= b < base
H0:0 <= d < base
H1:base * a + b = base * c + d
P:0 <= d < base \/ base < d <= 0 ->
d = (base * a + b) mod base
b = ((a * base) mod base + b) mod base
base, a, b, c, d:Z
H:0 <= b < base
H0:0 <= d < base
H1:base * a + b = base * c + d
P:0 <= d < base \/ base < d <= 0 ->
d = (base * a + b) mod base
b = (0 + b) mod base
base, a, b, c, d:Z
H:0 <= b < base
H0:0 <= d < base
H1:base * a + b = base * c + d
P:0 <= d < base \/ base < d <= 0 ->
d = (base * a + b) mod base
b = b mod base
base, a, b, c, d:Z
H:0 <= b < base
H0:0 <= d < base
H1:base * a + b = base * c + d
P:0 <= d < base \/ base < d <= 0 ->
d = (base * a + b) mod base
b = b
reflexivity.
Qed.
forall base a b c d : Z,
0 <= b < base ->
0 <= d < base -> base * a + b = base * c + d -> a = c
forall base a b c d : Z,
0 <= b < base ->
0 <= d < base -> base * a + b = base * c + d -> a = c
base, a, b, c, d:Z
H:0 <= b < base
H0:0 <= d < base
H1:base * a + b = base * c + d
a = c
nia.
Qed.
forall n : Z, n < 0 -> Z.to_nat n = 0%nat
forall n : Z, n < 0 -> Z.to_nat n = 0%nat
destruct n; (lia||reflexivity).
Qed.
End ZLib.
Module ZExtra.
forall x y m : Z,
0 < m ->
x mod m = 0 ->
y mod m = 0 -> x <> y -> x + m > y -> y + m <= x
forall x y m : Z,
0 < m ->
x mod m = 0 ->
y mod m = 0 -> x <> y -> x + m > y -> y + m <= x
0 < m ->
x mod m = 0 ->
y mod m = 0 -> x <> y -> x + m > y -> y + m <= x
x, y, m:Z
POS:0 < m
XMOD:x mod m = 0
YMOD:y mod m = 0
NEQ:x <> y
H:x + m > y
y + m <= x
x, y, m:Z
POS:0 < m
XMOD:x mod m = 0
YMOD:y mod m = 0
NEQ:x <> y
H:x + m > y
g:y + m > x
y + m <= x
x, y, m:Z
POS:0 < m
XMOD:x mod m = 0
YMOD:(m | y)
NEQ:x <> y
H:x + m > y
g:y + m > x
y + m <= x
x, y, m:Z
POS:0 < m
XMOD:(m | x)
YMOD:(m | y)
NEQ:x <> y
H:x + m > y
g:y + m > x
y + m <= x
y, m:Z
POS:0 < m
x':Z
YMOD:(m | y)
g:y + m > x' * m
H:x' * m + m > y
NEQ:x' * m <> y
y + m <= x' * m
m:Z
POS:0 < m
x', y':Z
NEQ:x' * m <> y' * m
H:x' * m + m > y' * m
g:y' * m + m > x' * m
y' * m + m <= x' * m
m:Z
POS:0 < m
x', y':Z
H:x' * m + m > y' * m
g:y' * m + m > x' * m
NEQ':x' <> y'
y' * m + m <= x' * m
m:Z
POS:0 < m
x', y':Z
H:Z.succ x' * m > y' * m
g:y' * m + m > x' * m
NEQ':x' <> y'
y' * m + m <= x' * m
m:Z
POS:0 < m
x', y':Z
H:Z.succ x' * m > y' * m
g:Z.succ y' * m > x' * m
NEQ':x' <> y'
y' * m + m <= x' * m
apply Zmult_gt_reg_r in H;
apply Zmult_gt_reg_r in g; lia.
Qed.
forall x y : positive, (x < y)%positive -> x <> y
forall x y : positive, (x < y)%positive -> x <> y
lia. Qed.
forall x y : positive, (y < x)%positive -> x <> y
forall x y : positive, (y < x)%positive -> x <> y
lia. Qed.
forall x y n : positive,
(x <= y)%positive -> (x < y + n)%positive
forall x y n : positive,
(x <= y)%positive -> (x < y + n)%positive
lia. Qed.
End ZExtra.