Require Import Coqlib.
Require Import Integers.
Require Import Psatz.
Require Import Align Tactics.
Require Import Permutation.
Opaque two_power_nat.
Opaque minus Z.mul.
Local Opaque Pos.of_nat.
Hint Resolve two_power_nat_pos.
Lemma two_power :
forall n, (1 <=
NPeano.pow 2
n)%
nat.
Proof.
Lemma two_power_nat_monotone:
forall m n,
(
m <=
n)%
nat ->
two_power_nat m <=
two_power_nat n.
Proof.
Lemma two_power_nat_monotone_strict:
forall m n,
(
m <
n)%
nat ->
two_power_nat m <
two_power_nat n.
Proof.
Lemma eq_le:
forall (
n m:
nat),
n =
m -> (
n <=
m)%
nat.
Proof.
intros; lia. Qed.
Lemma N2Z_add_lt_lt_Z2N:
forall n e m,
Z.of_nat (
n +
e) <
m ->
(
n <
Z.to_nat m)%
nat.
Proof.
intros.
zify.
rewrite Z2Nat.id by lia.
lia.
Qed.
Lemma mult_lt_le_mono:
forall (
a b c d:
nat),
(
a <
c)%
nat -> (
O <
b <=
d)%
nat ->
(
a *
b <
c *
d)%
nat.
Proof.
intros. nia.
Qed.
Lemma div_mul_add:
forall x k y,
x = 8 *
k ->
(
x +
y) / 8 =
x / 8 +
y / 8.
Proof.
Lemma div_spec:
forall a b,
b > 0 ->
exists q r,
a =
q *
b +
r /\ 0 <=
r <
b.
Proof.
Lemma div_large_div_small:
forall x b,
(
exists k,
x =
b *
k) ->
forall b',
(
b' |
b) ->
exists k,
x =
b' *
k.
Proof.
intros x b (k & EQ) b' (k' & EQ').
subst. exists (k' * k); lia.
Qed.
Lemma div_large_div_small_two_p:
forall x b,
(
exists k,
x =
two_power_nat b *
k) ->
forall b',
(
b' <=
b)%
nat ->
exists k,
x =
two_power_nat b' *
k.
Proof.
Lemma two_p_split:
forall x y,
0 <=
y <=
x ->
two_p x =
two_p y *
two_p (
x -
y).
Proof.
intros;
rewrite <-
two_p_is_exp;
try lia.
f_equal.
lia.
Qed.
Lemma two_power_nat_split:
forall x y,
(
y <=
x)%
nat ->
two_power_nat x =
two_power_nat y *
two_power_nat (
x -
y).
Proof.
Lemma two_p_div:
forall X Y Y'
k,
X =
two_power_nat Y *
k ->
(
Y' <=
Y)%
nat ->
X =
two_power_nat Y' * (
two_power_nat (
Y -
Y') *
k).
Proof.
Lemma two_p_div_rew:
forall n m (
LE: (
m <=
n)%
nat)
x y,
(
two_power_nat n *
x +
y) /
two_power_nat m =
(
two_power_nat n *
x) /
two_power_nat m +
y /
two_power_nat m.
Proof.
Lemma two_p_div_rew':
forall n m (
LE: (
m <=
n)%
nat)
x,
(
two_power_nat n *
x) /
two_power_nat m =
(
two_power_nat (
n -
m) *
x).
Proof.
Opaque two_power_nat.
Opaque minus Z.mul.
Lemma int_and_two_p_m1_mul':
forall i n,
Z.of_nat n <=
Int.max_unsigned ->
Int.and i (
Int.not (
Int.repr (
two_power_nat n - 1))) =
i ->
exists k,
i =
Int.mul (
Int.repr (
two_power_nat n))
k.
Proof.
Lemma int_and_two_p_m1_mul_Z':
forall i n,
Z.of_nat n < 32 ->
Int.and i (
Int.not (
Int.repr (
two_power_nat n - 1))) =
i ->
exists k,
Int.unsigned i = (
two_power_nat n) *
k.
Proof.