Documentation

CompPoly.Fields.Binary.Tower.Concrete.Arithmetic

Concrete binary tower arithmetic #

A nominal carrier with low-first bitvector coordinates, explicit word encoding, and executable recursive multiplication, inversion, and powers. Elementary laws and the additive group are available without the recursive field certificates. CompPoly.Fields.Binary.Tower.Concrete.Core re-exports this interface and supplies law records and instance assembly; CompPoly.Fields.Binary.Tower.Concrete.Field constructs the field.

At positive level k, the arithmetic adjoins a generator z satisfying z² = Z (k - 1) * z + 1 over the previous level, with Z 0 = 1. An element lo + hi * z stores lo in the low half and hi in the high half of its word; split returns (hi, lo). This is the quadratic tower of [DP23], §2.3, where the paper's X (k - 1) corresponds to Z k.

References #

A binary tower element with low-first bit coordinates at level k.

  • toBitVec : BitVec (2 ^ k)

    The 2 ^ k binary coordinates.

Instances For
    @[inline]

    Interpret 2 ^ k bits as the coordinates of a level-k tower element.

    Instances For
      @[simp]

      Reading the coordinates of a constructed element recovers the input word.

      @[simp]

      Reconstructing an element from its stored coordinates recovers the element.

      The explicit equivalence between tower elements and their stored words.

      Instances For

        Stored word coordinates uniquely determine a tower element.

        Distinct stored words construct distinct tower elements.

        Tower elements with equal stored word coordinates are equal.

        @[inline]

        Read the stored word as an unsigned natural number. This is not a field cast.

        Instances For
          @[simp]

          Reading a constructed word as a natural number preserves its unsigned value.

          @[simp]

          Reading encoded bits as a natural number agrees with the tower word readback.

          A level-k stored word lies below 2 ^ (2 ^ k).

          Unsigned word readback uniquely determines a tower element.

          theorem ConcreteBinaryTower.BitVec.dcast_id {n : } (bv : BitVec n) :
          dcast bv = bv
          theorem ConcreteBinaryTower.BitVec.dcast_bitvec_eq {l r val : } (h_width_eq : l = r) :
          dcast h_width_eq (BitVec.ofNat l val) = BitVec.ofNat r val
          @[simp]
          theorem ConcreteBinaryTower.BitVec.cast_zero {n m : } (h : n = m) :
          @[simp]
          theorem ConcreteBinaryTower.BitVec.cast_one {n m : } (h : n = m) :
          @[simp]
          theorem ConcreteBinaryTower.BitVec.dcast_zero {n m : } (h : n = m) :
          dcast h 0#n = 0#m
          @[simp]
          theorem ConcreteBinaryTower.BitVec.dcast_one {n m : } (h : n = m) :
          dcast h 1#n = 1#m
          theorem ConcreteBinaryTower.BitVec.dcast_bitvec_toNat_eq {w w2 : } (x : BitVec w) (h_width_eq : w = w2) :
          x.toNat = (dcast h_width_eq x).toNat
          theorem ConcreteBinaryTower.BitVec.dcast_bitvec_eq_zero {l r : } (h_width_eq : l = r) :
          dcast h_width_eq 0#l = 0#r
          theorem ConcreteBinaryTower.BitVec.dcast_bitvec_extractLsb_eq {w hi1 lo1 hi2 lo2 : } (x : BitVec w) (h_lo_eq : lo1 = lo2) (h_width_eq : hi1 - lo1 + 1 = hi2 - lo2 + 1) :
          dcast h_width_eq (BitVec.extractLsb hi1 lo1 x) = BitVec.extractLsb hi2 lo2 x
          theorem ConcreteBinaryTower.BitVec.dcast_dcast_bitvec_extractLsb_eq {w hi lo : } (x : BitVec w) (h_width_eq : w = hi - lo + 1) :
          dcast h_width_eq (dcast (BitVec.extractLsb hi lo x)) = BitVec.extractLsb hi lo x
          theorem ConcreteBinaryTower.BitVec.eq_mp_eq_dcast {w w2 : } (x : BitVec w) (h_width_eq : w = w2) (h_bitvec_eq : BitVec w = BitVec w2 := by rw [h_width_eq]) :
          h_bitvec_eq.mp x = dcast h_width_eq x
          theorem ConcreteBinaryTower.BitVec.extractLsb_concat_hi {hi_size lo_size : } (hi : BitVec hi_size) (lo : BitVec lo_size) (h_hi : hi_size > 0) :
          BitVec.extractLsb (hi_size + lo_size - 1) lo_size (hi.append lo) = dcast hi
          theorem ConcreteBinaryTower.BitVec.extractLsb_concat_lo {hi_size lo_size : } (hi : BitVec hi_size) (lo : BitVec lo_size) (h_lo : lo_size > 0) :
          BitVec.extractLsb (lo_size - 1) 0 (hi.append lo) = dcast lo
          theorem ConcreteBinaryTower.Nat.shiftRight_eq_sub_mod_then_div_two_pow {n lo_len : } :
          n >>> lo_len = (n - n % 2 ^ lo_len) / 2 ^ lo_len
          theorem ConcreteBinaryTower.Nat.shiftRight_lo_mod_2_pow_hi_shiftLeft_lo (n hi_len lo_len : ) (h_n : n < 2 ^ (hi_len + lo_len)) :
          (n >>> lo_len % 2 ^ hi_len) <<< lo_len = n - n % 2 ^ lo_len
          theorem ConcreteBinaryTower.Nat.reconstruct_from_hi_and_lo_parts (n hi_len lo_len : ) (h_n : n < 2 ^ (hi_len + lo_len)) :
          n = (n >>> lo_len % 2 ^ hi_len) <<< lo_len + n % 2 ^ lo_len
          theorem ConcreteBinaryTower.Nat.reconstruct_from_hi_and_lo_parts_or_ver (n hi_len lo_len : ) (h_n : n < 2 ^ (hi_len + lo_len)) :
          n = (n >>> lo_len % 2 ^ hi_len) <<< lo_len ||| n % 2 ^ lo_len
          theorem ConcreteBinaryTower.BitVec.eq_append_iff_extract {lo_size hi_size : } (lo : BitVec lo_size) (hi : BitVec hi_size) (h_hi_gt_0 : hi_size > 0) (h_lo_gt_0 : lo_size > 0) (x : BitVec (hi_size + lo_size)) :
          x = dcast (hi.append lo) hi = dcast (BitVec.extractLsb (hi_size + lo_size - 1) lo_size x) lo = dcast (BitVec.extractLsb (lo_size - 1) 0 x)
          Instances For
            Instances For
              @[simp]

              The explicit natural-word constructor stores the low 2 ^ k bits.

              @[simp]

              Reading an explicit natural-word construction reduces modulo its word size.

              @[simp]

              Reconstructing a tower element from its unsigned stored word recovers it.

              theorem ConcreteBinaryTower.one_le_sub_middle_of_pow2 {k : } (h_k : 1 k) :
              1 2 ^ k - 2 ^ (k - 1)
              theorem ConcreteBinaryTower.sub_middle_of_pow2_with_one_canceled {k : } (h_k : 1 k) :
              2 ^ k - 1 - 2 ^ (k - 1) + 1 = 2 ^ (k - 1)
              theorem ConcreteBinaryTower.h_sub_middle {k : } (h_pos : k > 0) :
              2 ^ k - 1 - 2 ^ (k - 1) + 1 = 2 ^ (k - 1)
              theorem ConcreteBinaryTower.h_middle_sub {k : } :
              2 ^ (k - 1) - 1 - 0 + 1 = 2 ^ (k - 1)
              theorem ConcreteBinaryTower.h_sum_two_same_pow2 {k : } (h_pos : k > 0) :
              2 ^ (k - 1) + 2 ^ (k - 1) = 2 ^ k
              @[reducible, inline, deprecated "Use addition inherited from Add." (since := "2026-09-16")]

              Compatibility name for addition inherited from the homogeneous operation.

              Instances For
                theorem ConcreteBinaryTower.add_assoc {k : } (a b c : ConcreteBTField k) :
                a + b + c = a + (b + c)
                theorem ConcreteBinaryTower.add_comm {k : } (a b : ConcreteBTField k) :
                a + b = b + a
                theorem ConcreteBinaryTower.if_self_rfl {α : Type u_1} [DecidableEq α] (a b : α) :
                (if a = b then b else a) = a
                theorem ConcreteBinaryTower.nsmul_succ {k : } (n : ) (x : ConcreteBTField k) :
                (if n.succ % 2 = 0 then zero else x) = (if n % 2 = 0 then zero else x) + x
                theorem ConcreteBinaryTower.zsmul_succ {k : } (n : ) (x : ConcreteBTField k) :
                (if n.succ % 2 = 0 then zero else x) = (if n % 2 = 0 then zero else x) + x
                Instances For
                  def ConcreteBinaryTower.join {k : } (h_pos : k > 0) (hi lo : ConcreteBTField (k - 1)) :
                  Instances For
                    theorem ConcreteBinaryTower.cast_join {k n : } (h_pos : k > 0) (hi lo : ConcreteBTField (k - 1)) (heq : k = n) :
                    join h_pos hi lo = cast (join (cast hi) (cast lo))
                    theorem ConcreteBinaryTower.setWidth_eq_ofNat_mod {n num_bits : } (x : BitVec n) :
                    BitVec.setWidth num_bits x = BitVec.ofNat num_bits (x.toNat % 2 ^ num_bits)
                    theorem ConcreteBinaryTower.BitVec.extractLsb_eq_and_pow_2_minus_1_ofNat {n num_bits : } (h_num_bits : num_bits > 0) (x : BitVec n) :
                    BitVec.extractLsb (num_bits - 1) 0 x = BitVec.ofNat (num_bits - 1 - 0 + 1) (x.toNat &&& 2 ^ num_bits - 1)
                    theorem ConcreteBinaryTower.split_bitvec_eq_iff_fromNat {k : } (h_pos : k > 0) (x : ConcreteBTField k) (hi_btf lo_btf : ConcreteBTField (k - 1)) :
                    split h_pos x = (hi_btf, lo_btf) hi_btf = fromNat (x.toNat >>> 2 ^ (k - 1)) lo_btf = fromNat (x.toNat &&& 2 ^ 2 ^ (k - 1) - 1)
                    theorem ConcreteBinaryTower.BitVec.extractLsb_dcast_eq {w w2 hi lo : } (x : BitVec w) (h : w = w2) :
                    theorem ConcreteBinaryTower.join_eq_dcast_append {k : } (h_pos : k > 0) (hi lo : ConcreteBTField (k - 1)) :
                    (join h_pos hi lo).toBitVec = dcast (hi.toBitVec ++ lo.toBitVec)
                    theorem ConcreteBinaryTower.eq_join_iff_dcast_eq_append {k : } (h_pos : k > 0) (x : ConcreteBTField k) (hi lo : ConcreteBTField (k - 1)) :
                    x = join h_pos hi lo dcast x.toBitVec = hi.toBitVec ++ lo.toBitVec
                    theorem ConcreteBinaryTower.join_eq_iff_dcast_extractLsb {k : } (h_pos : k > 0) (x : ConcreteBTField k) (hi_btf lo_btf : ConcreteBTField (k - 1)) :
                    x = join h_pos hi_btf lo_btf hi_btf.toBitVec = dcast (BitVec.extractLsb (2 ^ k - 1) (2 ^ (k - 1)) x.toBitVec) lo_btf.toBitVec = dcast (BitVec.extractLsb (2 ^ (k - 1) - 1) 0 x.toBitVec)
                    theorem ConcreteBinaryTower.join_eq_join_iff {k : } (h_pos : k > 0) (hi₀ lo₀ hi₁ lo₁ : ConcreteBTField (k - 1)) :
                    join h_pos hi₀ lo₀ = join h_pos hi₁ lo₁ hi₀ = hi₁ lo₀ = lo₁
                    theorem ConcreteBinaryTower.join_eq_bitvec_iff_fromNat {k : } (h_pos : k > 0) (x : ConcreteBTField k) (hi_btf lo_btf : ConcreteBTField (k - 1)) :
                    x = join h_pos hi_btf lo_btf hi_btf = fromNat (x.toNat >>> 2 ^ (k - 1)) lo_btf = fromNat (x.toNat &&& 2 ^ 2 ^ (k - 1) - 1)
                    theorem ConcreteBinaryTower.join_of_split {k : } (h_pos : k > 0) (x : ConcreteBTField k) (hi_btf lo_btf : ConcreteBTField (k - 1)) (h_split_eq : split h_pos x = (hi_btf, lo_btf)) :
                    x = join h_pos hi_btf lo_btf
                    theorem ConcreteBinaryTower.split_of_join {k : } (h_pos : k > 0) (x : ConcreteBTField k) (hi_btf lo_btf : ConcreteBTField (k - 1)) (h_join : x = join h_pos hi_btf lo_btf) :
                    (hi_btf, lo_btf) = split h_pos x
                    theorem ConcreteBinaryTower.split_join_eq_split {k : } (h_pos : k > 0) (hi_btf lo_btf : ConcreteBTField (k - 1)) :
                    split h_pos (join h_pos hi_btf lo_btf) = (hi_btf, lo_btf)
                    theorem ConcreteBinaryTower.join_split_eq_join {k : } (h_pos : k > 0) (x : ConcreteBTField k) :
                    join h_pos (split h_pos x).1 (split h_pos x).2 = x
                    theorem ConcreteBinaryTower.eq_iff_split_eq {k : } (h_pos : k > 0) (x₀ x₁ : ConcreteBTField k) :
                    x₀ = x₁ split h_pos x₀ = split h_pos x₁
                    theorem ConcreteBinaryTower.split_sum_eq_sum_split {k : } (h_pos : k > 0) (x₀ x₁ : ConcreteBTField k) (hi₀ lo₀ hi₁ lo₁ : ConcreteBTField (k - 1)) (h_split_x₀ : split h_pos x₀ = (hi₀, lo₀)) (h_split_x₁ : split h_pos x₁ = (hi₁, lo₁)) :
                    split h_pos (x₀ + x₁) = (hi₀ + hi₁, lo₀ + lo₁)
                    theorem ConcreteBinaryTower.join_add_join {k : } (h_pos : k > 0) (hi₀ lo₀ hi₁ lo₁ : ConcreteBTField (k - 1)) :
                    join h_pos hi₀ lo₀ + join h_pos hi₁ lo₁ = join h_pos (hi₀ + hi₁) (lo₀ + lo₁)
                    theorem ConcreteBinaryTower.split_zero {k : } (h_pos : k > 0) :
                    theorem ConcreteBinaryTower.split_Z {k : } (h_pos : k > 0) :
                    split h_pos (Z k) = (one, zero)
                    theorem ConcreteBinaryTower.one_bitvec_toNat {width : } (h_width : width > 0) :
                    (1#width).toNat = 1
                    theorem ConcreteBinaryTower.toNat_Z_succ (k : ) :
                    (Z (k + 1)).toNat = 2 ^ 2 ^ k

                    The generator at level k + 1 is the word with its only set bit at position 2 ^ k.

                    theorem ConcreteBinaryTower.one_bitvec_shiftRight {d : } (h_d : d > 0) :
                    1 >>> d = 0
                    Instances For
                      theorem ConcreteBinaryTower.mul_trans_inequality {k : } (x : ) (h_k : k 2) (h_x : x 2 ^ 2 ^ k - 1) :
                      x < 16
                      @[irreducible]
                      Instances For
                        @[reducible, inline, deprecated "Use multiplication inherited from Mul." (since := "2026-09-16")]

                        Compatibility name for multiplication inherited from the homogeneous operation.

                        Instances For
                          @[irreducible]
                          Instances For
                            @[irreducible]
                            Instances For
                              theorem ConcreteBinaryTower.cast_mul (m n : ) {x y : ConcreteBTField m} (h_eq : m = n) :
                              cast (x * y) = cast x * cast y
                              @[instance_reducible]

                              Strict unsigned order on stored words, independent of field arithmetic.

                              @[instance_reducible]

                              Unsigned order on stored words, independent of field arithmetic.

                              @[instance_reducible]

                              The preorder inherited from unsigned word readback.

                              theorem ConcreteBinaryTower.add_eq_one_iff (a b : ConcreteBTField 0) :
                              a + b = 1 a = 0 b = 1 a = 1 b = 0
                              @[instance_reducible]
                              @[simp]
                              theorem ConcreteBinaryTower.natCast_eq {k : } (n : ) :
                              n = natCast n
                              @[simp]
                              theorem ConcreteBinaryTower.my_neg_mod_two (m : ) :
                              -m % 2 = if m % 2 = 0 then 0 else 1
                              @[simp]
                              @[instance_reducible]
                              @[reducible, inline, deprecated "Use division inherited from Div." (since := "2026-09-16")]

                              Compatibility name for division inherited from the homogeneous operation.

                              Instances For
                                @[reducible, inline, deprecated "Use integer powers from the Field instance." (since := "2026-09-16")]

                                Legacy integer-power dictionary using the raw binary-power routine.

                                Instances For