theorem
BitVec.eq_of_toNat_eq
{n : Nat}
{i : BitVec n}
{j : BitVec n}
:
BitVec.toNat i = BitVec.toNat j → i = j
Prove equality of bitvectors in terms of nat operations.
theorem
BitVec.toNat_eq
{n : Nat}
(x : BitVec n)
(y : BitVec n)
:
x = y ↔ BitVec.toNat x = BitVec.toNat y
theorem
BitVec.toNat_ne
{n : Nat}
(x : BitVec n)
(y : BitVec n)
:
x ≠ y ↔ BitVec.toNat x ≠ BitVec.toNat y
theorem
BitVec.testBit_toNat
{w : Nat}
{i : Nat}
(x : BitVec w)
:
Nat.testBit (BitVec.toNat x) i = BitVec.getLsb x i
@[simp]
theorem
BitVec.getLsb_ofFin
{n : Nat}
(x : Fin (2 ^ n))
(i : Nat)
:
BitVec.getLsb { toFin := x } i = Nat.testBit (↑x) i
@[simp]
theorem
BitVec.eq_of_getLsb_eq
{w : Nat}
{x : BitVec w}
{y : BitVec w}
(pred : ∀ (i : Fin w), BitVec.getLsb x ↑i = BitVec.getLsb y ↑i)
:
x = y
theorem
BitVec.eq_of_getMsb_eq
{w : Nat}
{x : BitVec w}
{y : BitVec w}
(pred : ∀ (i : Fin w), BitVec.getMsb x ↑i = BitVec.getMsb y ↑i)
:
x = y
@[simp]
@[simp]
@[simp]
theorem
BitVec.getLsb_ofNatLt
{n : Nat}
(x : Nat)
(lt : x < 2 ^ n)
(i : Nat)
:
BitVec.getLsb (x#'lt) i = Nat.testBit x i
theorem
BitVec.getLsb_ofNat
(n : Nat)
(x : Nat)
(i : Nat)
:
BitVec.getLsb (x#n) i = (decide (i < n) && Nat.testBit x i)
@[simp, deprecated BitVec.toNat_ofNat]
@[simp]
msb #
theorem
BitVec.getLsb_last
{w : Nat}
(x : BitVec w)
:
BitVec.getLsb x (w - 1) = decide (2 ^ (w - 1) ≤ BitVec.toNat x)
theorem
BitVec.getLsb_succ_last
{w : Nat}
(x : BitVec (w + 1))
:
BitVec.getLsb x w = decide (2 ^ w ≤ BitVec.toNat x)
theorem
BitVec.msb_eq_decide
{w : Nat}
(x : BitVec w)
:
BitVec.msb x = decide (2 ^ (w - 1) ≤ BitVec.toNat x)
theorem
BitVec.toNat_ge_of_msb_true
{n : Nat}
{x : BitVec n}
(p : BitVec.msb x = true)
:
BitVec.toNat x ≥ 2 ^ (n - 1)
cast #
@[simp]
theorem
BitVec.toNat_cast
{w : Nat}
{v : Nat}
(h : w = v)
(x : BitVec w)
:
BitVec.toNat (BitVec.cast h x) = BitVec.toNat x
@[simp]
theorem
BitVec.toFin_cast
{w : Nat}
{v : Nat}
(h : w = v)
(x : BitVec w)
:
(BitVec.cast h x).toFin = Fin.cast ⋯ x.toFin
@[simp]
theorem
BitVec.getLsb_cast
{w : Nat}
{v : Nat}
{i : Nat}
(h : w = v)
(x : BitVec w)
:
BitVec.getLsb (BitVec.cast h x) i = BitVec.getLsb x i
@[simp]
theorem
BitVec.getMsb_cast
{w : Nat}
{v : Nat}
{i : Nat}
(h : w = v)
(x : BitVec w)
:
BitVec.getMsb (BitVec.cast h x) i = BitVec.getMsb x i
@[simp]
theorem
BitVec.msb_cast
{w : Nat}
{v : Nat}
(h : w = v)
(x : BitVec w)
:
BitVec.msb (BitVec.cast h x) = BitVec.msb x
toInt/ofInt #
theorem
BitVec.toInt_eq_toNat_cond
{n : Nat}
(i : BitVec n)
:
BitVec.toInt i = if 2 * BitVec.toNat i < 2 ^ n then ↑(BitVec.toNat i) else ↑(BitVec.toNat i) - ↑(2 ^ n)
Prove equality of bitvectors in terms of nat operations.
theorem
BitVec.toInt_eq_toNat_bmod
{n : Nat}
(x : BitVec n)
:
BitVec.toInt x = Int.bmod (↑(BitVec.toNat x)) (2 ^ n)
theorem
BitVec.eq_of_toInt_eq
{n : Nat}
{i : BitVec n}
{j : BitVec n}
:
BitVec.toInt i = BitVec.toInt j → i = j
Prove equality of bitvectors in terms of nat operations.
@[simp]
theorem
BitVec.toNat_ofInt
{n : Nat}
(i : Int)
:
BitVec.toNat (BitVec.ofInt n i) = Int.toNat (i % ↑(2 ^ n))
@[simp]
theorem
BitVec.toInt_ofInt
{n : Nat}
(i : Int)
:
BitVec.toInt (BitVec.ofInt n i) = Int.bmod i (2 ^ n)
zeroExtend and truncate #
@[simp]
theorem
BitVec.toNat_zeroExtend'
{m : Nat}
{n : Nat}
(p : m ≤ n)
(x : BitVec m)
:
BitVec.toNat (BitVec.zeroExtend' p x) = BitVec.toNat x
theorem
BitVec.toNat_zeroExtend
{n : Nat}
(i : Nat)
(x : BitVec n)
:
BitVec.toNat (BitVec.zeroExtend i x) = BitVec.toNat x % 2 ^ i
@[simp]
theorem
BitVec.toNat_truncate
{n : Nat}
{i : Nat}
(x : BitVec n)
:
BitVec.toNat (BitVec.truncate i x) = BitVec.toNat x % 2 ^ i
@[simp]
theorem
BitVec.ofNat_toNat
{n : Nat}
(m : Nat)
(x : BitVec n)
:
(BitVec.toNat x)#m = BitVec.truncate m x
@[simp]
theorem
BitVec.getLsb_zeroExtend'
{m : Nat}
{n : Nat}
(ge : m ≥ n)
(x : BitVec n)
(i : Nat)
:
BitVec.getLsb (BitVec.zeroExtend' ge x) i = BitVec.getLsb x i
@[simp]
theorem
BitVec.getLsb_zeroExtend
{n : Nat}
(m : Nat)
(x : BitVec n)
(i : Nat)
:
BitVec.getLsb (BitVec.zeroExtend m x) i = (decide (i < m) && BitVec.getLsb x i)
@[simp]
theorem
BitVec.getLsb_truncate
{n : Nat}
(m : Nat)
(x : BitVec n)
(i : Nat)
:
BitVec.getLsb (BitVec.truncate m x) i = (decide (i < m) && BitVec.getLsb x i)
@[simp]
theorem
BitVec.zeroExtend_zeroExtend_of_le
{w : Nat}
{k : Nat}
{l : Nat}
(x : BitVec w)
(h : k ≤ l)
:
BitVec.zeroExtend k (BitVec.zeroExtend l x) = BitVec.zeroExtend k x
@[simp]
theorem
BitVec.truncate_truncate_of_le
{w : Nat}
{k : Nat}
{l : Nat}
(x : BitVec w)
(h : k ≤ l)
:
BitVec.truncate k (BitVec.truncate l x) = BitVec.truncate k x
theorem
BitVec.msb_zeroExtend
{w : Nat}
{v : Nat}
(x : BitVec w)
:
BitVec.msb (BitVec.zeroExtend v x) = (decide (0 < v) && BitVec.getLsb x (v - 1))
extractLsb #
@[simp]
theorem
BitVec.extractLsb'_toNat
{n : Nat}
(s : Nat)
(m : Nat)
(x : BitVec n)
:
BitVec.toNat (BitVec.extractLsb' s m x) = BitVec.toNat x >>> s % 2 ^ m
@[simp]
theorem
BitVec.extractLsb_toNat
{n : Nat}
(hi : Nat)
(lo : Nat)
(x : BitVec n)
:
BitVec.toNat (BitVec.extractLsb hi lo x) = BitVec.toNat x >>> lo % 2 ^ (hi - lo + 1)
@[simp]
theorem
BitVec.getLsb_extract
{n : Nat}
(hi : Nat)
(lo : Nat)
(x : BitVec n)
(i : Nat)
:
BitVec.getLsb (BitVec.extractLsb hi lo x) i = (decide (i ≤ hi - lo) && BitVec.getLsb x (lo + i))
allOnes #
@[simp]
theorem
BitVec.getLsb_allOnes
{v : Nat}
{i : Nat}
:
BitVec.getLsb (BitVec.allOnes v) i = decide (i < v)
or #
@[simp]
theorem
BitVec.toNat_or
{v : Nat}
(x : BitVec v)
(y : BitVec v)
:
BitVec.toNat (x ||| y) = BitVec.toNat x ||| BitVec.toNat y
@[simp]
theorem
BitVec.getLsb_or
{v : Nat}
{i : Nat}
{x : BitVec v}
{y : BitVec v}
:
BitVec.getLsb (x ||| y) i = (BitVec.getLsb x i || BitVec.getLsb y i)
and #
@[simp]
theorem
BitVec.toNat_and
{v : Nat}
(x : BitVec v)
(y : BitVec v)
:
BitVec.toNat (x &&& y) = BitVec.toNat x &&& BitVec.toNat y
@[simp]
theorem
BitVec.getLsb_and
{v : Nat}
{i : Nat}
{x : BitVec v}
{y : BitVec v}
:
BitVec.getLsb (x &&& y) i = (BitVec.getLsb x i && BitVec.getLsb y i)
xor #
@[simp]
theorem
BitVec.toNat_xor
{v : Nat}
(x : BitVec v)
(y : BitVec v)
:
BitVec.toNat (x ^^^ y) = BitVec.toNat x ^^^ BitVec.toNat y
@[simp]
theorem
BitVec.getLsb_xor
{v : Nat}
{i : Nat}
{x : BitVec v}
{y : BitVec v}
:
BitVec.getLsb (x ^^^ y) i = xor (BitVec.getLsb x i) (BitVec.getLsb y i)
not #
@[simp]
@[simp]
theorem
BitVec.getLsb_not
{v : Nat}
{i : Nat}
{x : BitVec v}
:
BitVec.getLsb (~~~x) i = (decide (i < v) && !BitVec.getLsb x i)
shiftLeft #
@[simp]
theorem
BitVec.toNat_shiftLeft
{v : Nat}
{n : Nat}
{x : BitVec v}
:
BitVec.toNat (x <<< n) = BitVec.toNat x <<< n % 2 ^ v
@[simp]
theorem
BitVec.toFin_shiftLeft
{w : Nat}
{n : Nat}
(x : BitVec w)
:
(x <<< n).toFin = Fin.ofNat' (BitVec.toNat x <<< n) ⋯
theorem
BitVec.shiftLeftZeroExtend_eq
{w : Nat}
{n : Nat}
{x : BitVec w}
:
BitVec.shiftLeftZeroExtend x n = BitVec.zeroExtend (w + n) x <<< n
@[simp]
theorem
BitVec.getLsb_shiftLeftZeroExtend
{m : Nat}
{i : Nat}
(x : BitVec m)
(n : Nat)
:
BitVec.getLsb (BitVec.shiftLeftZeroExtend x n) i = (!decide (i < n) && BitVec.getLsb x (i - n))
ushiftRight #
@[simp]
theorem
BitVec.toNat_ushiftRight
{n : Nat}
(x : BitVec n)
(i : Nat)
:
BitVec.toNat (x >>> i) = BitVec.toNat x >>> i
@[simp]
theorem
BitVec.getLsb_ushiftRight
{n : Nat}
(x : BitVec n)
(i : Nat)
(j : Nat)
:
BitVec.getLsb (x >>> i) j = BitVec.getLsb x (i + j)
append #
theorem
BitVec.append_def
{v : Nat}
{w : Nat}
(x : BitVec v)
(y : BitVec w)
:
x ++ y = BitVec.shiftLeftZeroExtend x w ||| BitVec.zeroExtend' ⋯ y
@[simp]
theorem
BitVec.toNat_append
{m : Nat}
{n : Nat}
(x : BitVec m)
(y : BitVec n)
:
BitVec.toNat (x ++ y) = BitVec.toNat x <<< n ||| BitVec.toNat y
@[simp]
theorem
BitVec.getLsb_append
{n : Nat}
{m : Nat}
{i : Nat}
{v : BitVec n}
{w : BitVec m}
:
BitVec.getLsb (v ++ w) i = bif decide (i < m) then BitVec.getLsb w i else BitVec.getLsb v (i - m)
rev #
theorem
BitVec.getLsb_rev
{w : Nat}
(x : BitVec w)
(i : Fin w)
:
BitVec.getLsb x ↑(Fin.rev i) = BitVec.getMsb x ↑i
theorem
BitVec.getMsb_rev
{w : Nat}
(x : BitVec w)
(i : Fin w)
:
BitVec.getMsb x ↑(Fin.rev i) = BitVec.getLsb x ↑i
cons #
@[simp]
theorem
BitVec.toNat_cons
{w : Nat}
(b : Bool)
(x : BitVec w)
:
BitVec.toNat (BitVec.cons b x) = Bool.toNat b <<< w ||| BitVec.toNat x
@[simp]
theorem
BitVec.getLsb_cons
(b : Bool)
{n : Nat}
(x : BitVec n)
(i : Nat)
:
BitVec.getLsb (BitVec.cons b x) i = if i = n then b else BitVec.getLsb x i
theorem
BitVec.truncate_succ
{w : Nat}
{i : Nat}
(x : BitVec w)
:
BitVec.truncate (i + 1) x = BitVec.cons (BitVec.getLsb x i) (BitVec.truncate i x)
concat #
@[simp]
theorem
BitVec.toNat_concat
{w : Nat}
(x : BitVec w)
(b : Bool)
:
BitVec.toNat (BitVec.concat x b) = BitVec.toNat x * 2 + Bool.toNat b
theorem
BitVec.getLsb_concat
{w : Nat}
(x : BitVec w)
(b : Bool)
(i : Nat)
:
BitVec.getLsb (BitVec.concat x b) i = if i = 0 then b else BitVec.getLsb x (i - 1)
@[simp]
theorem
BitVec.getLsb_concat_zero :
∀ {w : Nat} {x : BitVec w} {b : Bool}, BitVec.getLsb (BitVec.concat x b) 0 = b
@[simp]
theorem
BitVec.getLsb_concat_succ :
∀ {w : Nat} {x : BitVec w} {b : Bool} {i : Nat}, BitVec.getLsb (BitVec.concat x b) (i + 1) = BitVec.getLsb x i
add #
theorem
BitVec.add_def
{n : Nat}
(x : BitVec n)
(y : BitVec n)
:
x + y = (BitVec.toNat x + BitVec.toNat y)#n
@[simp]
theorem
BitVec.toNat_add
{w : Nat}
(x : BitVec w)
(y : BitVec w)
:
BitVec.toNat (x + y) = (BitVec.toNat x + BitVec.toNat y) % 2 ^ w
Definition of bitvector addition as a nat.
sub/neg #
theorem
BitVec.sub_def
{n : Nat}
(x : BitVec n)
(y : BitVec n)
:
x - y = (BitVec.toNat x + (2 ^ n - BitVec.toNat y))#n
@[simp]
theorem
BitVec.toNat_sub
{n : Nat}
(x : BitVec n)
(y : BitVec n)
:
BitVec.toNat (x - y) = (BitVec.toNat x + (2 ^ n - BitVec.toNat y)) % 2 ^ n
@[simp]
theorem
BitVec.toNat_neg
{n : Nat}
(x : BitVec n)
:
BitVec.toNat (-x) = (2 ^ n - BitVec.toNat x) % 2 ^ n
mul #
@[simp]
theorem
BitVec.toNat_mul
{n : Nat}
(x : BitVec n)
(y : BitVec n)
:
BitVec.toNat (x * y) = BitVec.toNat x * BitVec.toNat y % 2 ^ n
instance
BitVec.instCommutativeBitVecHMulInstHMulInstMulBitVec
{w : Nat}
:
Std.Commutative fun (x y : BitVec w) => x * y
Equations
- ⋯ = ⋯
instance
BitVec.instAssociativeBitVecHMulInstHMulInstMulBitVec
{w : Nat}
:
Std.Associative fun (x y : BitVec w) => x * y
Equations
- ⋯ = ⋯
instance
BitVec.instLawfulCommIdentityBitVecHMulInstHMulInstMulBitVecOfNatOfNatNatInstOfNatNatInstCommutativeBitVecHMulInstHMulInstMulBitVec
{w : Nat}
:
Std.LawfulCommIdentity (fun (x y : BitVec w) => x * y) 1#w
Equations
- ⋯ = ⋯
le and lt #
theorem
BitVec.le_def
{n : Nat}
(x : BitVec n)
(y : BitVec n)
:
x ≤ y ↔ BitVec.toNat x ≤ BitVec.toNat y
theorem
BitVec.lt_def
{n : Nat}
(x : BitVec n)
(y : BitVec n)
:
x < y ↔ BitVec.toNat x < BitVec.toNat y
The bitvector of width w
that has the largest value when interpreted as an integer.
Equations
- BitVec.intMax w = (2 ^ w - 1)#w
Instances For
theorem
BitVec.getLsb_intMax_eq
{i : Nat}
(w : Nat)
:
BitVec.getLsb (BitVec.intMax w) i = decide (i < w)