bedrock.prelude.bitsN
(*
* Copyright (c) 2021-2022 BedRock Systems, Inc.
* This software is distributed under the terms of the BedRock Open-Source License.
* See the LICENSE-BedRock file in the repository root for details.
*)
Require Import bedrock.prelude.base.
Require Import bedrock.prelude.bool.
Require Import bedrock.prelude.finite.
Require Import bedrock.prelude.fin.
Require Import bedrock.prelude.list_numbers.
#[local] Set Printing Coercions.
* Copyright (c) 2021-2022 BedRock Systems, Inc.
* This software is distributed under the terms of the BedRock Open-Source License.
* See the LICENSE-BedRock file in the repository root for details.
*)
Require Import bedrock.prelude.base.
Require Import bedrock.prelude.bool.
Require Import bedrock.prelude.finite.
Require Import bedrock.prelude.fin.
Require Import bedrock.prelude.list_numbers.
#[local] Set Printing Coercions.
get_range_bitsN
Extract from val the count lowest bits starting from from.
Follows get_range_bits but on N.
TODO: this one generalizes bedrock.lang.cpp.arith.builtins.get_byte. Consider
unifying them.
Definition get_range_bitsN (val from count : N) : N :=
N.land (val ≫ from) (N.ones count).
Section get_range_bitsN.
#[local] Open Scope N_scope.
Lemma get_range_bitsN_eq val from count :
get_range_bitsN val from count = (val ≫ from) `mod` 2 ^ count.
Proof. by rewrite /get_range_bitsN N.land_ones. Qed.
Lemma get_range_bitsN_1_eq val from :
get_range_bitsN val from 1 = N.b2n (N.testbit val from).
Proof.
rewrite get_range_bitsN_eq N.testbit_eqb -N.shiftr_div_pow2.
case: N.eqb_spec =>//.
move: (N.shiftr _ _) => {val from} x.
have /= := N.mod_upper_bound x 2.
move: (N.modulo _ _).
lia.
Qed.
Lemma get_range_bitsN_1_bool_decide_eq val from :
bool_decide (get_range_bitsN val from 1 = 1) = N.testbit val from.
Proof.
rewrite get_range_bitsN_1_eq.
by rewrite (bool_decide_ext _ _ (N_b2n_1 _)) bool_decide_Is_true.
Qed.
Lemma get_range_bitsN_bounded {n i cnt : N} :
get_range_bitsN n i cnt < 2^cnt.
Proof.
rewrite get_range_bitsN_eq. apply N.mod_bound_pos. { apply N.le_0_l. }
by apply N.le_succ_l, (N.pow_le_mono_r 2 0), N.le_0_l.
Qed.
Definition get_range_bits_fin (val from count : N) : fin.t (2 ^ count) :=
fin.mk (get_range_bitsN val from count) get_range_bitsN_bounded.
Section get_range_bitsN_bounded_elim.
Context {X} (of_N : N -> option X) (count : N) {n from : N}.
Lemma get_range_bitsN_bounded_elim
(Hdef : ∀ n, n < 2 ^ count → of_N n ≠ None) :
is_Some (of_N (get_range_bitsN n from count)).
Proof. apply not_eq_None_Some, Hdef, get_range_bitsN_bounded. Qed.
Lemma get_range_bitsN_bounded_elim'
(Hdef : List.Forall (λ i , of_N i ≠ None) (seqN 0 (2 ^ count))) :
is_Some (of_N (get_range_bitsN n from count)).
Proof. apply get_range_bitsN_bounded_elim, N_fin_iter_lt, Hdef. Qed.
End get_range_bitsN_bounded_elim.
End get_range_bitsN.
N.land (val ≫ from) (N.ones count).
Section get_range_bitsN.
#[local] Open Scope N_scope.
Lemma get_range_bitsN_eq val from count :
get_range_bitsN val from count = (val ≫ from) `mod` 2 ^ count.
Proof. by rewrite /get_range_bitsN N.land_ones. Qed.
Lemma get_range_bitsN_1_eq val from :
get_range_bitsN val from 1 = N.b2n (N.testbit val from).
Proof.
rewrite get_range_bitsN_eq N.testbit_eqb -N.shiftr_div_pow2.
case: N.eqb_spec =>//.
move: (N.shiftr _ _) => {val from} x.
have /= := N.mod_upper_bound x 2.
move: (N.modulo _ _).
lia.
Qed.
Lemma get_range_bitsN_1_bool_decide_eq val from :
bool_decide (get_range_bitsN val from 1 = 1) = N.testbit val from.
Proof.
rewrite get_range_bitsN_1_eq.
by rewrite (bool_decide_ext _ _ (N_b2n_1 _)) bool_decide_Is_true.
Qed.
Lemma get_range_bitsN_bounded {n i cnt : N} :
get_range_bitsN n i cnt < 2^cnt.
Proof.
rewrite get_range_bitsN_eq. apply N.mod_bound_pos. { apply N.le_0_l. }
by apply N.le_succ_l, (N.pow_le_mono_r 2 0), N.le_0_l.
Qed.
Definition get_range_bits_fin (val from count : N) : fin.t (2 ^ count) :=
fin.mk (get_range_bitsN val from count) get_range_bitsN_bounded.
Section get_range_bitsN_bounded_elim.
Context {X} (of_N : N -> option X) (count : N) {n from : N}.
Lemma get_range_bitsN_bounded_elim
(Hdef : ∀ n, n < 2 ^ count → of_N n ≠ None) :
is_Some (of_N (get_range_bitsN n from count)).
Proof. apply not_eq_None_Some, Hdef, get_range_bitsN_bounded. Qed.
Lemma get_range_bitsN_bounded_elim'
(Hdef : List.Forall (λ i , of_N i ≠ None) (seqN 0 (2 ^ count))) :
is_Some (of_N (get_range_bitsN n from count)).
Proof. apply get_range_bitsN_bounded_elim, N_fin_iter_lt, Hdef. Qed.
End get_range_bitsN_bounded_elim.
End get_range_bitsN.