Documentation

Init.Data.BitVec.Lemmas

theorem BitVec.ofFin_eq_ofNat {w : Nat} {x : Nat} {lt : x < 2 ^ w} :
{ toFin := { val := x, isLt := lt } } = x#w

This normalized a bitvec using ofFin to ofNat.

theorem BitVec.eq_of_toNat_eq {n : Nat} {i : BitVec n} {j : BitVec n} :

Prove equality of bitvectors in terms of nat operations.

@[simp]
theorem BitVec.val_toFin {w : Nat} (x : BitVec w) :
x.toFin = BitVec.toNat x
theorem BitVec.toNat_eq {n : Nat} (x : BitVec n) (y : BitVec n) :
theorem BitVec.toNat_ne {n : Nat} (x : BitVec n) (y : BitVec n) :
theorem BitVec.toNat_lt {n : Nat} (x : BitVec n) :
@[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.getLsb_ge {w : Nat} (x : BitVec w) (i : Nat) (ge : i w) :
theorem BitVec.lt_of_getLsb {w : Nat} (x : BitVec w) (i : Nat) :
BitVec.getLsb x i = truei < w
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]
theorem BitVec.of_length_zero {x : BitVec 0} :
x = 0#0
theorem BitVec.eq_of_toFin_eq {w : Nat} {x : BitVec w} {y : BitVec w} :
x.toFin = y.toFinx = y
theorem BitVec.ofNat_one (n : Nat) :
n#1 = BitVec.ofBool (decide (n % 2 = 1))
@[simp]
theorem BitVec.toNat_ofFin {n : Nat} (x : Fin (2 ^ n)) :
BitVec.toNat { toFin := x } = x
@[simp]
theorem BitVec.toNat_ofNatLt {w : Nat} (x : Nat) (p : x < 2 ^ w) :
@[simp]
theorem BitVec.getLsb_ofNatLt {n : Nat} (x : Nat) (lt : x < 2 ^ n) (i : Nat) :
@[simp]
theorem BitVec.toNat_ofNat (x : Nat) (w : Nat) :
BitVec.toNat x#w = x % 2 ^ w
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]
theorem BitVec.toNat_zero (n : Nat) :
@[simp]
theorem BitVec.getLsb_zero {w : Nat} {i : Nat} :
@[simp]

msb #

@[simp]
theorem BitVec.msb_zero {w : Nat} :
theorem BitVec.getLsb_last {w : Nat} (x : BitVec w) :
BitVec.getLsb x (w - 1) = decide (2 ^ (w - 1) BitVec.toNat x)
theorem BitVec.msb_eq_decide {w : Nat} (x : BitVec w) :
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) :
@[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) :
@[simp]
theorem BitVec.getMsb_cast {w : Nat} {v : Nat} {i : Nat} (h : w = v) (x : BitVec w) :
@[simp]
theorem BitVec.msb_cast {w : Nat} {v : Nat} (h : w = v) (x : BitVec w) :

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.eq_of_toInt_eq {n : Nat} {i : BitVec n} {j : BitVec n} :

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))
theorem BitVec.toInt_ofNat {n : Nat} (x : Nat) :
BitVec.toInt x#n = Int.bmod (x) (2 ^ n)
@[simp]
theorem BitVec.toInt_ofInt {n : Nat} (i : Int) :

zeroExtend and truncate #

@[simp]
theorem BitVec.toNat_zeroExtend' {m : Nat} {n : Nat} (p : m n) (x : BitVec m) :
@[simp]
theorem BitVec.toNat_truncate {n : Nat} {i : Nat} (x : BitVec n) :
@[simp]
theorem BitVec.zeroExtend_eq {n : Nat} (x : BitVec n) :
@[simp]
theorem BitVec.zeroExtend_zero (m : Nat) (n : Nat) :
@[simp]
theorem BitVec.truncate_eq {n : Nat} (x : BitVec n) :
@[simp]
theorem BitVec.ofNat_toNat {n : Nat} (m : Nat) (x : BitVec n) :
theorem BitVec.toNat_eq_nat {w : Nat} (x : BitVec w) (y : Nat) :
BitVec.toNat x = y y < 2 ^ w x = y#w

Moves one-sided left toNat equality to BitVec equality.

theorem BitVec.nat_eq_toNat {w : Nat} (x : BitVec w) (y : Nat) :
y = BitVec.toNat x y < 2 ^ w x = y#w

Moves one-sided right toNat equality to BitVec equality.

@[simp]
theorem BitVec.getLsb_zeroExtend' {m : Nat} {n : Nat} (ge : m n) (x : BitVec n) (i : Nat) :
@[simp]
theorem BitVec.getLsb_zeroExtend {n : Nat} (m : Nat) (x : BitVec n) (i : Nat) :
@[simp]
theorem BitVec.getLsb_truncate {n : Nat} (m : Nat) (x : BitVec n) (i : Nat) :
@[simp]
@[simp]
theorem BitVec.truncate_truncate_of_le {w : Nat} {k : Nat} {l : Nat} (x : BitVec w) (h : k l) :
theorem BitVec.msb_zeroExtend {w : Nat} {v : Nat} (x : BitVec w) :

extractLsb #

@[simp]
theorem BitVec.extractLsb_ofFin {n : Nat} (x : Fin (2 ^ n)) (hi : Nat) (lo : Nat) :
BitVec.extractLsb hi lo { toFin := x } = (x >>> lo)#(hi - lo + 1)
@[simp]
theorem BitVec.extractLsb_ofNat (x : Nat) (n : Nat) (hi : Nat) (lo : Nat) :
BitVec.extractLsb hi lo x#n = ((x % 2 ^ n) >>> lo)#(hi - lo + 1)
@[simp]
theorem BitVec.extractLsb'_toNat {n : Nat} (s : Nat) (m : Nat) (x : BitVec n) :
@[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]
@[simp]

or #

@[simp]
theorem BitVec.toNat_or {v : Nat} (x : BitVec v) (y : BitVec v) :
@[simp]
theorem BitVec.toFin_or {v : Nat} (x : BitVec v) (y : BitVec v) :
(x ||| y).toFin = x.toFin ||| y.toFin
@[simp]
theorem BitVec.getLsb_or {v : Nat} {i : Nat} {x : BitVec v} {y : BitVec v} :

and #

@[simp]
theorem BitVec.toNat_and {v : Nat} (x : BitVec v) (y : BitVec v) :
@[simp]
theorem BitVec.toFin_and {v : Nat} (x : BitVec v) (y : BitVec v) :
(x &&& y).toFin = x.toFin &&& y.toFin
@[simp]
theorem BitVec.getLsb_and {v : Nat} {i : Nat} {x : BitVec v} {y : BitVec v} :

xor #

@[simp]
theorem BitVec.toNat_xor {v : Nat} (x : BitVec v) (y : BitVec v) :
@[simp]
theorem BitVec.toFin_xor {v : Nat} (x : BitVec v) (y : BitVec v) :
(x ^^^ y).toFin = x.toFin ^^^ y.toFin
@[simp]
theorem BitVec.getLsb_xor {v : Nat} {i : Nat} {x : BitVec v} {y : BitVec v} :

not #

theorem BitVec.not_def {v : Nat} {x : BitVec v} :
@[simp]
theorem BitVec.toNat_not {v : Nat} {x : BitVec v} :
@[simp]
theorem BitVec.toFin_not {w : Nat} (x : BitVec w) :
(~~~x).toFin = Fin.rev x.toFin
@[simp]
theorem BitVec.getLsb_not {v : Nat} {i : Nat} {x : BitVec v} :

shiftLeft #

@[simp]
theorem BitVec.toNat_shiftLeft {v : Nat} {n : Nat} {x : BitVec v} :
@[simp]
theorem BitVec.toFin_shiftLeft {w : Nat} {n : Nat} (x : BitVec w) :
(x <<< n).toFin = Fin.ofNat' (BitVec.toNat x <<< n)
@[simp]
theorem BitVec.getLsb_shiftLeft {m : Nat} {i : Nat} (x : BitVec m) (n : Nat) :
BitVec.getLsb (x <<< n) i = (decide (i < m) && !decide (i < n) && BitVec.getLsb x (i - n))
@[simp]

ushiftRight #

@[simp]
theorem BitVec.toNat_ushiftRight {n : Nat} (x : BitVec n) (i : Nat) :
@[simp]
theorem BitVec.getLsb_ushiftRight {n : Nat} (x : BitVec n) (i : Nat) (j : Nat) :

append #

@[simp]
theorem BitVec.toNat_append {m : Nat} {n : Nat} (x : BitVec m) (y : BitVec n) :
@[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) :
theorem BitVec.getMsb_rev {w : Nat} (x : BitVec w) (i : Fin w) :

cons #

@[simp]
@[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

concat #

@[simp]
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) :
@[simp]
theorem BitVec.toNat_add {w : Nat} (x : BitVec w) (y : BitVec w) :

Definition of bitvector addition as a nat.

@[simp]
theorem BitVec.toFin_add {w : Nat} (x : BitVec w) (y : BitVec w) :
(x + y).toFin = x.toFin + y.toFin
@[simp]
theorem BitVec.ofFin_add {n : Nat} (x : Fin (2 ^ n)) (y : BitVec n) :
{ toFin := x } + y = { toFin := x + y.toFin }
@[simp]
theorem BitVec.add_ofFin {n : Nat} (x : BitVec n) (y : Fin (2 ^ n)) :
x + { toFin := y } = { toFin := x.toFin + y }
@[simp]
theorem BitVec.ofNat_add_ofNat {n : Nat} (x : Nat) (y : Nat) :
x#n + y#n = (x + y)#n
theorem BitVec.add_assoc {n : Nat} (x : BitVec n) (y : BitVec n) (z : BitVec n) :
x + y + z = x + (y + z)
theorem BitVec.add_comm {n : Nat} (x : BitVec n) (y : BitVec n) :
x + y = y + x
@[simp]
theorem BitVec.add_zero {n : Nat} (x : BitVec n) :
x + 0#n = x
@[simp]
theorem BitVec.zero_add {n : Nat} (x : BitVec n) :
0#n + x = x

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.toFin_sub {n : Nat} (x : BitVec n) (y : BitVec n) :
(x - y).toFin = x.toFin - y.toFin
@[simp]
theorem BitVec.ofFin_sub {n : Nat} (x : Fin (2 ^ n)) (y : BitVec n) :
{ toFin := x } - y = { toFin := x - y.toFin }
@[simp]
theorem BitVec.sub_ofFin {n : Nat} (x : BitVec n) (y : Fin (2 ^ n)) :
x - { toFin := y } = { toFin := x.toFin - y }
theorem BitVec.ofNat_sub_ofNat {n : Nat} (x : Nat) (y : Nat) :
x#n - y#n = (x + (2 ^ n - y % 2 ^ n))#n
@[simp]
theorem BitVec.sub_zero {n : Nat} (x : BitVec n) :
x - 0#n = x
@[simp]
theorem BitVec.sub_self {n : Nat} (x : BitVec n) :
x - x = 0#n
@[simp]
theorem BitVec.toNat_neg {n : Nat} (x : BitVec n) :
BitVec.toNat (-x) = (2 ^ n - BitVec.toNat x) % 2 ^ n
theorem BitVec.sub_toAdd {n : Nat} (x : BitVec n) (y : BitVec n) :
x - y = x + -y
@[simp]
theorem BitVec.neg_zero (n : Nat) :
-0#n = 0#n
theorem BitVec.add_sub_cancel {w : Nat} (x : BitVec w) (y : BitVec w) :
x + y - y = x

mul #

theorem BitVec.mul_def {n : Nat} {x : BitVec n} {y : BitVec n} :
x * y = { toFin := x.toFin * y.toFin }
@[simp]
theorem BitVec.toNat_mul {n : Nat} (x : BitVec n) (y : BitVec n) :
@[simp]
theorem BitVec.toFin_mul {n : Nat} (x : BitVec n) (y : BitVec n) :
(x * y).toFin = x.toFin * y.toFin
theorem BitVec.mul_comm {w : Nat} (x : BitVec w) (y : BitVec w) :
x * y = y * x
Equations
  • =
theorem BitVec.mul_assoc {w : Nat} (x : BitVec w) (y : BitVec w) (z : BitVec w) :
x * y * z = x * (y * z)
Equations
  • =
@[simp]
theorem BitVec.mul_one {w : Nat} (x : BitVec w) :
x * 1#w = x
@[simp]
theorem BitVec.one_mul {w : Nat} (x : BitVec w) :
1#w * x = x

le and lt #

theorem BitVec.le_def {n : Nat} (x : BitVec n) (y : BitVec n) :
@[simp]
theorem BitVec.le_ofFin {n : Nat} (x : BitVec n) (y : Fin (2 ^ n)) :
x { toFin := y } x.toFin y
@[simp]
theorem BitVec.ofFin_le {n : Nat} (x : Fin (2 ^ n)) (y : BitVec n) :
{ toFin := x } y x y.toFin
@[simp]
theorem BitVec.ofNat_le_ofNat {n : Nat} (x : Nat) (y : Nat) :
x#n y#n x % 2 ^ n y % 2 ^ n
theorem BitVec.lt_def {n : Nat} (x : BitVec n) (y : BitVec n) :
@[simp]
theorem BitVec.lt_ofFin {n : Nat} (x : BitVec n) (y : Fin (2 ^ n)) :
x < { toFin := y } x.toFin < y
@[simp]
theorem BitVec.ofFin_lt {n : Nat} (x : Fin (2 ^ n)) (y : BitVec n) :
{ toFin := x } < y x < y.toFin
@[simp]
theorem BitVec.ofNat_lt_ofNat {n : Nat} (x : Nat) (y : Nat) :
x#n < y#n x % 2 ^ n < y % 2 ^ n
theorem BitVec.lt_of_le_ne {n : Nat} (x : BitVec n) (y : BitVec n) (h1 : x y) (h2 : ¬x = y) :
x < y
def BitVec.intMax (w : Nat) :

The bitvector of width w that has the largest value when interpreted as an integer.

Equations
Instances For