|
|
|
|
@ -22,6 +22,9 @@ namespace BitVec
|
|
|
|
|
@[simp] theorem getLsbD_ofFin (x : Fin (2^n)) (i : Nat) :
|
|
|
|
|
getLsbD (BitVec.ofFin x) i = x.val.testBit i := rfl
|
|
|
|
|
|
|
|
|
|
@[simp] theorem getElem_ofFin (x : Fin (2^n)) (i : Nat) (h : i < n) :
|
|
|
|
|
(BitVec.ofFin x)[i] = x.val.testBit i := rfl
|
|
|
|
|
|
|
|
|
|
@[simp] theorem getLsbD_ge (x : BitVec w) (i : Nat) (ge : w ≤ i) : getLsbD x i = false := by
|
|
|
|
|
let ⟨x, x_lt⟩ := x
|
|
|
|
|
simp only [getLsbD_ofFin]
|
|
|
|
|
@ -90,6 +93,11 @@ theorem getLsbD_eq_getElem?_getD {x : BitVec w} {i : Nat} :
|
|
|
|
|
· rfl
|
|
|
|
|
· simp_all
|
|
|
|
|
|
|
|
|
|
@[simp]
|
|
|
|
|
theorem getElem_of_getLsbD_eq_true {x : BitVec w} {i : Nat} (h : x.getLsbD i = true) :
|
|
|
|
|
(x[i]'(lt_of_getLsbD h) = true) = True := by
|
|
|
|
|
simp [← BitVec.getLsbD_eq_getElem, h]
|
|
|
|
|
|
|
|
|
|
/--
|
|
|
|
|
This normalized a bitvec using `ofFin` to `ofNat`.
|
|
|
|
|
-/
|
|
|
|
|
@ -178,9 +186,7 @@ theorem getMsbD_eq_getMsb?_getD (x : BitVec w) (i : Nat) :
|
|
|
|
|
intros
|
|
|
|
|
omega
|
|
|
|
|
|
|
|
|
|
-- We choose `eq_of_getLsbD_eq` as the `@[ext]` theorem for `BitVec`
|
|
|
|
|
-- somewhat arbitrarily over `eq_of_getMsbD_eq`.
|
|
|
|
|
@[ext] theorem eq_of_getLsbD_eq {x y : BitVec w}
|
|
|
|
|
theorem eq_of_getLsbD_eq {x y : BitVec w}
|
|
|
|
|
(pred : ∀ i, i < w → x.getLsbD i = y.getLsbD i) : x = y := by
|
|
|
|
|
apply eq_of_toNat_eq
|
|
|
|
|
apply Nat.eq_of_testBit_eq
|
|
|
|
|
@ -191,6 +197,21 @@ theorem getMsbD_eq_getMsb?_getD (x : BitVec w) (i : Nat) :
|
|
|
|
|
have p : i ≥ w := Nat.le_of_not_gt i_lt
|
|
|
|
|
simp [testBit_toNat, getLsbD_ge _ _ p]
|
|
|
|
|
|
|
|
|
|
@[ext] theorem eq_of_getElem_eq {x y : BitVec n} :
|
|
|
|
|
(∀ i (hi : i < n), x[i] = y[i]) → x = y :=
|
|
|
|
|
fun h => BitVec.eq_of_getLsbD_eq (h ↑·)
|
|
|
|
|
|
|
|
|
|
theorem eq_of_getLsbD_eq_iff {w : Nat} {x y : BitVec w} :
|
|
|
|
|
x = y ↔ ∀ (i : Nat), i < w → x.getLsbD i = y.getLsbD i := by
|
|
|
|
|
have iff := @BitVec.eq_of_getElem_eq_iff w x y
|
|
|
|
|
constructor
|
|
|
|
|
· intros heq i lt
|
|
|
|
|
have hext := iff.mp heq i lt
|
|
|
|
|
simp only [← getLsbD_eq_getElem] at hext
|
|
|
|
|
exact hext
|
|
|
|
|
· intros heq
|
|
|
|
|
exact iff.mpr heq
|
|
|
|
|
|
|
|
|
|
theorem eq_of_getMsbD_eq {x y : BitVec w}
|
|
|
|
|
(pred : ∀ i, i < w → x.getMsbD i = y.getMsbD i) : x = y := by
|
|
|
|
|
simp only [getMsbD] at pred
|
|
|
|
|
@ -211,7 +232,7 @@ theorem eq_of_getMsbD_eq {x y : BitVec w}
|
|
|
|
|
simpa [q_lt, Nat.sub_sub_self, r] using q
|
|
|
|
|
|
|
|
|
|
-- This cannot be a `@[simp]` lemma, as it would be tried at every term.
|
|
|
|
|
theorem of_length_zero {x : BitVec 0} : x = 0#0 := by ext; simp
|
|
|
|
|
theorem of_length_zero {x : BitVec 0} : x = 0#0 := by ext; simp [← getLsbD_eq_getElem]
|
|
|
|
|
|
|
|
|
|
theorem toNat_zero_length (x : BitVec 0) : x.toNat = 0 := by simp [of_length_zero]
|
|
|
|
|
theorem getLsbD_zero_length (x : BitVec 0) : x.getLsbD i = false := by simp
|
|
|
|
|
@ -385,7 +406,12 @@ theorem getLsbD_ofBool (b : Bool) (i : Nat) : (ofBool b).getLsbD i = ((i = 0) &&
|
|
|
|
|
· simp only [ofBool, ofNat_eq_ofNat, cond_true, getLsbD_ofNat, Bool.and_true]
|
|
|
|
|
by_cases hi : i = 0 <;> simp [hi] <;> omega
|
|
|
|
|
|
|
|
|
|
theorem getElem_ofBool {b : Bool} : (ofBool b)[0] = b := by simp
|
|
|
|
|
@[simp] theorem getElem_ofBool_zero {b : Bool} : (ofBool b)[0] = b := by simp
|
|
|
|
|
|
|
|
|
|
@[simp]
|
|
|
|
|
theorem getElem_ofBool {b : Bool} {h : i < 1}: (ofBool b)[i] = b := by
|
|
|
|
|
simp [← getLsbD_eq_getElem]
|
|
|
|
|
omega
|
|
|
|
|
|
|
|
|
|
@[simp] theorem getMsbD_ofBool (b : Bool) : (ofBool b).getMsbD i = (decide (i = 0) && b) := by
|
|
|
|
|
cases b <;> simp [getMsbD]
|
|
|
|
|
@ -546,7 +572,7 @@ theorem toInt_ofNat {n : Nat} (x : Nat) :
|
|
|
|
|
BitVec.ofInt w (no_index (OfNat.ofNat n)) = BitVec.ofNat w (OfNat.ofNat n) := rfl
|
|
|
|
|
|
|
|
|
|
@[simp] theorem ofInt_toInt {x : BitVec w} : BitVec.ofInt w x.toInt = x := by
|
|
|
|
|
by_cases h : 2 * x.toNat < 2^w <;> ext <;> simp [getLsbD, h, BitVec.toInt]
|
|
|
|
|
by_cases h : 2 * x.toNat < 2^w <;> ext <;> simp [←getLsbD_eq_getElem, getLsbD, h, BitVec.toInt]
|
|
|
|
|
|
|
|
|
|
theorem toInt_neg_iff {w : Nat} {x : BitVec w} :
|
|
|
|
|
BitVec.toInt x < 0 ↔ 2 ^ w ≤ 2 * x.toNat := by
|
|
|
|
|
@ -761,10 +787,8 @@ theorem setWidth'_eq {x : BitVec w} (h : w ≤ v) : x.setWidth' h = x.setWidth v
|
|
|
|
|
@[simp] theorem setWidth_setWidth_of_le (x : BitVec w) (h : k ≤ l) :
|
|
|
|
|
(x.setWidth l).setWidth k = x.setWidth k := by
|
|
|
|
|
ext i
|
|
|
|
|
simp only [getLsbD_setWidth, Fin.is_lt, decide_true, Bool.true_and]
|
|
|
|
|
have p := lt_of_getLsbD (x := x) (i := i)
|
|
|
|
|
revert p
|
|
|
|
|
cases getLsbD x i <;> simp; omega
|
|
|
|
|
simp [getElem_setWidth, Fin.is_lt, decide_true, Bool.true_and]
|
|
|
|
|
omega
|
|
|
|
|
|
|
|
|
|
@[simp] theorem setWidth_cast {x : BitVec w} {h : w = v} : (x.cast h).setWidth k = x.setWidth k := by
|
|
|
|
|
apply eq_of_getLsbD_eq
|
|
|
|
|
@ -792,11 +816,10 @@ theorem setWidth_one_eq_ofBool_getLsb_zero (x : BitVec w) :
|
|
|
|
|
theorem setWidth_ofNat_one_eq_ofNat_one_of_lt {v w : Nat} (hv : 0 < v) :
|
|
|
|
|
(BitVec.ofNat v 1).setWidth w = BitVec.ofNat w 1 := by
|
|
|
|
|
ext i h
|
|
|
|
|
simp only [getLsbD_setWidth, h, decide_true, getLsbD_ofNat, Bool.true_and,
|
|
|
|
|
simp only [getElem_setWidth, h, decide_true, getLsbD_ofNat, Bool.true_and,
|
|
|
|
|
Bool.and_iff_right_iff_imp, decide_eq_true_eq]
|
|
|
|
|
intros hi₁
|
|
|
|
|
have hv := Nat.testBit_one_eq_true_iff_self_eq_zero.mp hi₁
|
|
|
|
|
omega
|
|
|
|
|
have hv := (@Nat.testBit_one_eq_true_iff_self_eq_zero i)
|
|
|
|
|
by_cases h : Nat.testBit 1 i = true <;> simp_all
|
|
|
|
|
|
|
|
|
|
/-- Truncating to width 1 produces a bitvector equal to the least significant bit. -/
|
|
|
|
|
theorem setWidth_one {x : BitVec w} :
|
|
|
|
|
@ -819,12 +842,9 @@ and the second `setWidth` is a non-trivial extension.
|
|
|
|
|
-- `simp` can discharge the side condition itself.
|
|
|
|
|
@[simp] theorem setWidth_setWidth {x : BitVec u} {w v : Nat} (h : ¬ (v < u ∧ v < w)) :
|
|
|
|
|
setWidth w (setWidth v x) = setWidth w x := by
|
|
|
|
|
ext
|
|
|
|
|
simp_all only [getLsbD_setWidth, decide_true, Bool.true_and, Bool.and_iff_right_iff_imp,
|
|
|
|
|
decide_eq_true_eq]
|
|
|
|
|
intro h
|
|
|
|
|
replace h := lt_of_getLsbD h
|
|
|
|
|
omega
|
|
|
|
|
ext i ih
|
|
|
|
|
have := @lt_of_getLsbD u x i
|
|
|
|
|
by_cases h' : x.getLsbD i = true <;> simp [h'] at * <;> omega
|
|
|
|
|
|
|
|
|
|
/-! ## extractLsb -/
|
|
|
|
|
|
|
|
|
|
@ -896,12 +916,13 @@ theorem extractLsb'_eq_extractLsb {w : Nat} (x : BitVec w) (start len : Nat) (h
|
|
|
|
|
|
|
|
|
|
@[simp] theorem ofFin_add_rev (x : Fin (2^n)) : ofFin (x + x.rev) = allOnes n := by
|
|
|
|
|
ext
|
|
|
|
|
simp only [Fin.rev, getLsbD_ofFin, getLsbD_allOnes, Fin.is_lt, decide_true]
|
|
|
|
|
simp only [Fin.rev, getElem_ofFin, getElem_allOnes, Fin.is_lt, decide_true]
|
|
|
|
|
rw [Fin.add_def]
|
|
|
|
|
simp only [Nat.testBit_mod_two_pow, Fin.is_lt, decide_true, Bool.true_and]
|
|
|
|
|
have h : (x : Nat) + (2 ^ n - (x + 1)) = 2 ^ n - 1 := by omega
|
|
|
|
|
rw [h, Nat.testBit_two_pow_sub_one]
|
|
|
|
|
simp
|
|
|
|
|
omega
|
|
|
|
|
|
|
|
|
|
/-! ### or -/
|
|
|
|
|
|
|
|
|
|
@ -983,8 +1004,8 @@ theorem or_eq_zero_iff {x y : BitVec w} : (x ||| y) = 0#w ↔ x = 0#w ∧ y = 0#
|
|
|
|
|
constructor
|
|
|
|
|
all_goals
|
|
|
|
|
· ext i ih
|
|
|
|
|
have := BitVec.eq_of_getLsbD_eq_iff.mp h i ih
|
|
|
|
|
simp only [getLsbD_or, getLsbD_zero, Bool.or_eq_false_iff] at this
|
|
|
|
|
have := BitVec.eq_of_getElem_eq_iff.mp h i ih
|
|
|
|
|
simp only [getElem_or, getElem_zero, Bool.or_eq_false_iff] at this
|
|
|
|
|
simp [this]
|
|
|
|
|
· intro h
|
|
|
|
|
simp [h]
|
|
|
|
|
@ -1080,8 +1101,8 @@ theorem and_eq_allOnes_iff {x y : BitVec w} :
|
|
|
|
|
constructor
|
|
|
|
|
all_goals
|
|
|
|
|
· ext i ih
|
|
|
|
|
have := BitVec.eq_of_getLsbD_eq_iff.mp h i ih
|
|
|
|
|
simp only [getLsbD_and, getLsbD_allOnes, ih, decide_true, Bool.and_eq_true] at this
|
|
|
|
|
have := BitVec.eq_of_getElem_eq_iff.mp h i ih
|
|
|
|
|
simp only [getElem_and, getElem_allOnes, Bool.and_eq_true] at this
|
|
|
|
|
simp [this, ih]
|
|
|
|
|
· intro h
|
|
|
|
|
simp [h]
|
|
|
|
|
@ -1166,8 +1187,8 @@ theorem xor_left_inj {x y : BitVec w} (z : BitVec w) : (x ^^^ z = y ^^^ z) ↔ x
|
|
|
|
|
constructor
|
|
|
|
|
· intro h
|
|
|
|
|
ext i ih
|
|
|
|
|
have := BitVec.eq_of_getLsbD_eq_iff.mp h i
|
|
|
|
|
simp only [getLsbD_xor, Bool.xor_left_inj] at this
|
|
|
|
|
have := BitVec.eq_of_getElem_eq_iff.mp h i
|
|
|
|
|
simp only [getElem_xor, Bool.xor_left_inj] at this
|
|
|
|
|
exact this ih
|
|
|
|
|
· intro h
|
|
|
|
|
rw [h]
|
|
|
|
|
@ -1395,19 +1416,19 @@ theorem zero_shiftLeft (n : Nat) : 0#w <<< n = 0#w := by
|
|
|
|
|
theorem shiftLeft_xor_distrib (x y : BitVec w) (n : Nat) :
|
|
|
|
|
(x ^^^ y) <<< n = (x <<< n) ^^^ (y <<< n) := by
|
|
|
|
|
ext i h
|
|
|
|
|
simp only [getLsbD_shiftLeft, h, decide_true, Bool.true_and, getLsbD_xor]
|
|
|
|
|
simp only [getElem_shiftLeft, h, decide_true, Bool.true_and, getLsbD_xor]
|
|
|
|
|
by_cases h' : i < n <;> simp [h']
|
|
|
|
|
|
|
|
|
|
theorem shiftLeft_and_distrib (x y : BitVec w) (n : Nat) :
|
|
|
|
|
(x &&& y) <<< n = (x <<< n) &&& (y <<< n) := by
|
|
|
|
|
ext i h
|
|
|
|
|
simp only [getLsbD_shiftLeft, h, decide_true, Bool.true_and, getLsbD_and]
|
|
|
|
|
simp only [getElem_shiftLeft, h, decide_true, Bool.true_and, getLsbD_and]
|
|
|
|
|
by_cases h' : i < n <;> simp [h']
|
|
|
|
|
|
|
|
|
|
theorem shiftLeft_or_distrib (x y : BitVec w) (n : Nat) :
|
|
|
|
|
(x ||| y) <<< n = (x <<< n) ||| (y <<< n) := by
|
|
|
|
|
ext i h
|
|
|
|
|
simp only [getLsbD_shiftLeft, h, decide_true, Bool.true_and, getLsbD_or]
|
|
|
|
|
simp only [getElem_shiftLeft, h, decide_true, Bool.true_and, getLsbD_or]
|
|
|
|
|
by_cases h' : i < n <;> simp [h']
|
|
|
|
|
|
|
|
|
|
@[simp] theorem getMsbD_shiftLeft (x : BitVec w) (i) :
|
|
|
|
|
@ -1466,7 +1487,7 @@ theorem shiftLeftZeroExtend_eq {x : BitVec w} :
|
|
|
|
|
theorem shiftLeft_add {w : Nat} (x : BitVec w) (n m : Nat) :
|
|
|
|
|
x <<< (n + m) = (x <<< n) <<< m := by
|
|
|
|
|
ext i
|
|
|
|
|
simp only [getLsbD_shiftLeft, Fin.is_lt, decide_true, Bool.true_and]
|
|
|
|
|
simp only [getElem_shiftLeft, Fin.is_lt, decide_true, Bool.true_and]
|
|
|
|
|
rw [show i - (n + m) = (i - m - n) by omega]
|
|
|
|
|
cases h₂ : decide (i < m) <;>
|
|
|
|
|
cases h₃ : decide (i - m < w) <;>
|
|
|
|
|
@ -1723,7 +1744,7 @@ theorem getElem_sshiftRight {x : BitVec w} {s i : Nat} (h : i < w) :
|
|
|
|
|
theorem sshiftRight_xor_distrib (x y : BitVec w) (n : Nat) :
|
|
|
|
|
(x ^^^ y).sshiftRight n = (x.sshiftRight n) ^^^ (y.sshiftRight n) := by
|
|
|
|
|
ext i
|
|
|
|
|
simp only [getLsbD_sshiftRight, getLsbD_xor, msb_xor]
|
|
|
|
|
simp only [getElem_sshiftRight, getElem_xor, msb_xor]
|
|
|
|
|
split
|
|
|
|
|
<;> by_cases w ≤ i
|
|
|
|
|
<;> simp [*]
|
|
|
|
|
@ -1731,7 +1752,7 @@ theorem sshiftRight_xor_distrib (x y : BitVec w) (n : Nat) :
|
|
|
|
|
theorem sshiftRight_and_distrib (x y : BitVec w) (n : Nat) :
|
|
|
|
|
(x &&& y).sshiftRight n = (x.sshiftRight n) &&& (y.sshiftRight n) := by
|
|
|
|
|
ext i
|
|
|
|
|
simp only [getLsbD_sshiftRight, getLsbD_and, msb_and]
|
|
|
|
|
simp only [getElem_sshiftRight, getElem_and, msb_and]
|
|
|
|
|
split
|
|
|
|
|
<;> by_cases w ≤ i
|
|
|
|
|
<;> simp [*]
|
|
|
|
|
@ -1739,7 +1760,7 @@ theorem sshiftRight_and_distrib (x y : BitVec w) (n : Nat) :
|
|
|
|
|
theorem sshiftRight_or_distrib (x y : BitVec w) (n : Nat) :
|
|
|
|
|
(x ||| y).sshiftRight n = (x.sshiftRight n) ||| (y.sshiftRight n) := by
|
|
|
|
|
ext i
|
|
|
|
|
simp only [getLsbD_sshiftRight, getLsbD_or, msb_or]
|
|
|
|
|
simp only [getElem_sshiftRight, getElem_or, msb_or]
|
|
|
|
|
split
|
|
|
|
|
<;> by_cases w ≤ i
|
|
|
|
|
<;> simp [*]
|
|
|
|
|
@ -1761,31 +1782,28 @@ theorem msb_sshiftRight {n : Nat} {x : BitVec w} :
|
|
|
|
|
|
|
|
|
|
@[simp] theorem sshiftRight_zero {x : BitVec w} : x.sshiftRight 0 = x := by
|
|
|
|
|
ext i h
|
|
|
|
|
simp [getLsbD_sshiftRight, h]
|
|
|
|
|
simp [getElem_sshiftRight, h]
|
|
|
|
|
|
|
|
|
|
@[simp] theorem zero_sshiftRight {n : Nat} : (0#w).sshiftRight n = 0#w := by
|
|
|
|
|
ext i h
|
|
|
|
|
simp [getLsbD_sshiftRight, h]
|
|
|
|
|
simp [getElem_sshiftRight, h]
|
|
|
|
|
|
|
|
|
|
theorem sshiftRight_add {x : BitVec w} {m n : Nat} :
|
|
|
|
|
x.sshiftRight (m + n) = (x.sshiftRight m).sshiftRight n := by
|
|
|
|
|
ext i
|
|
|
|
|
simp only [getLsbD_sshiftRight, Nat.add_assoc]
|
|
|
|
|
by_cases h₁ : w ≤ (i : Nat)
|
|
|
|
|
· simp [h₁]
|
|
|
|
|
· simp only [h₁, decide_false, Bool.not_false, Bool.true_and]
|
|
|
|
|
by_cases h₂ : n + ↑i < w
|
|
|
|
|
· simp [h₂]
|
|
|
|
|
· simp only [h₂, ↓reduceIte]
|
|
|
|
|
by_cases h₃ : m + (n + ↑i) < w
|
|
|
|
|
· simp [h₃]
|
|
|
|
|
omega
|
|
|
|
|
· simp [h₃, msb_sshiftRight]
|
|
|
|
|
simp [getElem_sshiftRight, getLsbD_sshiftRight, Nat.add_assoc]
|
|
|
|
|
by_cases h₂ : n + i < w
|
|
|
|
|
· simp [h₂]
|
|
|
|
|
· simp only [h₂, ↓reduceIte]
|
|
|
|
|
by_cases h₃ : m + (n + ↑i) < w
|
|
|
|
|
· simp [h₃]
|
|
|
|
|
omega
|
|
|
|
|
· simp [h₃, msb_sshiftRight]
|
|
|
|
|
|
|
|
|
|
theorem not_sshiftRight {b : BitVec w} :
|
|
|
|
|
~~~b.sshiftRight n = (~~~b).sshiftRight n := by
|
|
|
|
|
ext i
|
|
|
|
|
simp only [getLsbD_not, Fin.is_lt, decide_true, getLsbD_sshiftRight, Bool.not_and, Bool.not_not,
|
|
|
|
|
simp only [getElem_not, Fin.is_lt, decide_true, getElem_sshiftRight, Bool.not_and, Bool.not_not,
|
|
|
|
|
Bool.true_and, msb_not]
|
|
|
|
|
by_cases h : w ≤ i
|
|
|
|
|
<;> by_cases h' : n + i < w
|
|
|
|
|
@ -1856,12 +1874,10 @@ theorem signExtend_eq_setWidth_of_msb_false {x : BitVec w} {v : Nat} (hmsb : x.m
|
|
|
|
|
x.signExtend v = x.setWidth v := by
|
|
|
|
|
ext i
|
|
|
|
|
by_cases hv : i < v
|
|
|
|
|
· simp only [signExtend, getLsbD, getLsbD_setWidth, hv, decide_true, Bool.true_and, toNat_ofInt,
|
|
|
|
|
· simp only [signExtend, getLsbD, getElem_setWidth, hv, decide_true, Bool.true_and, toNat_ofInt,
|
|
|
|
|
BitVec.toInt_eq_msb_cond, hmsb, ↓reduceIte, reduceCtorEq]
|
|
|
|
|
rw [Int.ofNat_mod_ofNat, Int.toNat_ofNat, Nat.testBit_mod_two_pow]
|
|
|
|
|
simp [BitVec.testBit_toNat]
|
|
|
|
|
· simp only [getLsbD_setWidth, hv, decide_false, Bool.false_and]
|
|
|
|
|
apply getLsbD_ge
|
|
|
|
|
· simp only [getElem_setWidth, hv, decide_false, Bool.false_and]
|
|
|
|
|
omega
|
|
|
|
|
|
|
|
|
|
/--
|
|
|
|
|
@ -1917,7 +1933,7 @@ theorem msb_signExtend {x : BitVec w} :
|
|
|
|
|
theorem signExtend_eq_setWidth_of_lt (x : BitVec w) {v : Nat} (hv : v ≤ w):
|
|
|
|
|
x.signExtend v = x.setWidth v := by
|
|
|
|
|
ext i h
|
|
|
|
|
simp only [getLsbD_signExtend, h, decide_true, Bool.true_and, getLsbD_setWidth,
|
|
|
|
|
simp only [getElem_signExtend, h, decide_true, Bool.true_and, getElem_setWidth,
|
|
|
|
|
ite_eq_left_iff, Nat.not_lt]
|
|
|
|
|
omega
|
|
|
|
|
|
|
|
|
|
@ -2018,11 +2034,11 @@ theorem getLsbD_append {x : BitVec n} {y : BitVec m} :
|
|
|
|
|
· simp_all [h]
|
|
|
|
|
|
|
|
|
|
theorem getElem_append {x : BitVec n} {y : BitVec m} (h : i < n + m) :
|
|
|
|
|
(x ++ y)[i] = if i < m then getLsbD y i else getLsbD x (i - m) := by
|
|
|
|
|
simp only [append_def, getElem_or, getElem_shiftLeftZeroExtend, getElem_setWidth']
|
|
|
|
|
(x ++ y)[i] = if h : i < m then y[i] else x[i - m] := by
|
|
|
|
|
simp only [append_def]
|
|
|
|
|
by_cases h' : i < m
|
|
|
|
|
· simp [h']
|
|
|
|
|
· simp_all [h']
|
|
|
|
|
· simp [h', show m ≤ i by omega, show i - m < n by omega]
|
|
|
|
|
|
|
|
|
|
@[simp] theorem getMsbD_append {x : BitVec n} {y : BitVec m} :
|
|
|
|
|
getMsbD (x ++ y) i = if n ≤ i then getMsbD y (i - n) else getMsbD x i := by
|
|
|
|
|
@ -2044,23 +2060,22 @@ theorem msb_append {x : BitVec w} {y : BitVec v} :
|
|
|
|
|
simp [h, q, t, BitVec.msb, getMsbD]
|
|
|
|
|
|
|
|
|
|
@[simp] theorem append_zero_width (x : BitVec w) (y : BitVec 0) : x ++ y = x := by
|
|
|
|
|
ext
|
|
|
|
|
rw [getLsbD_append] -- Why does this not work with `simp [getLsbD_append]`?
|
|
|
|
|
simp
|
|
|
|
|
ext i ih
|
|
|
|
|
rw [getElem_append] -- Why does this not work with `simp [getElem_append]`?
|
|
|
|
|
simp [show i < w by omega]
|
|
|
|
|
|
|
|
|
|
@[simp] theorem zero_width_append (x : BitVec 0) (y : BitVec v) : x ++ y = y.cast (by omega) := by
|
|
|
|
|
ext
|
|
|
|
|
rw [getLsbD_append]
|
|
|
|
|
simpa using lt_of_getLsbD
|
|
|
|
|
ext i ih
|
|
|
|
|
simp [getElem_append, show i < v by omega]
|
|
|
|
|
|
|
|
|
|
@[simp] theorem zero_append_zero : 0#v ++ 0#w = 0#(v + w) := by
|
|
|
|
|
ext
|
|
|
|
|
simp only [getLsbD_append, getLsbD_zero, ite_self]
|
|
|
|
|
simp [getElem_append]
|
|
|
|
|
|
|
|
|
|
@[simp] theorem cast_append_right (h : w + v = w + v') (x : BitVec w) (y : BitVec v) :
|
|
|
|
|
(x ++ y).cast h = x ++ y.cast (by omega) := by
|
|
|
|
|
ext
|
|
|
|
|
simp only [getLsbD_cast, getLsbD_append, cond_eq_if, decide_eq_true_eq]
|
|
|
|
|
simp only [getElem_cast, getElem_append]
|
|
|
|
|
split <;> split
|
|
|
|
|
· rfl
|
|
|
|
|
· omega
|
|
|
|
|
@ -2071,57 +2086,54 @@ theorem msb_append {x : BitVec w} {y : BitVec v} :
|
|
|
|
|
@[simp] theorem cast_append_left (h : w + v = w' + v) (x : BitVec w) (y : BitVec v) :
|
|
|
|
|
(x ++ y).cast h = x.cast (by omega) ++ y := by
|
|
|
|
|
ext
|
|
|
|
|
simp [getLsbD_append]
|
|
|
|
|
simp [getElem_append]
|
|
|
|
|
|
|
|
|
|
theorem setWidth_append {x : BitVec w} {y : BitVec v} :
|
|
|
|
|
(x ++ y).setWidth k = if h : k ≤ v then y.setWidth k else (x.setWidth (k - v) ++ y).cast (by omega) := by
|
|
|
|
|
ext i h
|
|
|
|
|
simp only [getLsbD_setWidth, h, getLsbD_append]
|
|
|
|
|
simp only [getElem_setWidth, h, getLsbD_append, getElem_append]
|
|
|
|
|
split <;> rename_i h₁ <;> split <;> rename_i h₂
|
|
|
|
|
· simp [h]
|
|
|
|
|
· simp [getLsbD_append, h₁]
|
|
|
|
|
· simp [getElem_append, h₁]
|
|
|
|
|
· omega
|
|
|
|
|
· simp [getLsbD_append, h₁]
|
|
|
|
|
omega
|
|
|
|
|
· simp [getElem_append, h₁]
|
|
|
|
|
|
|
|
|
|
@[simp] theorem setWidth_append_of_eq {x : BitVec v} {y : BitVec w} (h : w' = w) : setWidth (v' + w') (x ++ y) = setWidth v' x ++ setWidth w' y := by
|
|
|
|
|
@[simp] theorem setWidth_append_of_eq {x : BitVec v} {y : BitVec w} (h : w' = w) :
|
|
|
|
|
setWidth (v' + w') (x ++ y) = setWidth v' x ++ setWidth w' y := by
|
|
|
|
|
subst h
|
|
|
|
|
ext i h
|
|
|
|
|
simp only [getLsbD_setWidth, h, decide_true, getLsbD_append, cond_eq_if,
|
|
|
|
|
decide_eq_true_eq, Bool.true_and, setWidth_eq]
|
|
|
|
|
ext i h'
|
|
|
|
|
simp only [getElem_setWidth, getLsbD_append, getElem_append]
|
|
|
|
|
split
|
|
|
|
|
· simp_all
|
|
|
|
|
· simp_all only [Bool.iff_and_self, decide_eq_true_eq]
|
|
|
|
|
intro h
|
|
|
|
|
omega
|
|
|
|
|
· simp
|
|
|
|
|
· simp
|
|
|
|
|
|
|
|
|
|
@[simp] theorem setWidth_cons {x : BitVec w} : (cons a x).setWidth w = x := by
|
|
|
|
|
simp [cons, setWidth_append]
|
|
|
|
|
|
|
|
|
|
@[simp] theorem not_append {x : BitVec w} {y : BitVec v} : ~~~ (x ++ y) = (~~~ x) ++ (~~~ y) := by
|
|
|
|
|
ext i
|
|
|
|
|
simp only [getLsbD_not, getLsbD_append, cond_eq_if]
|
|
|
|
|
simp only [getElem_not, getElem_append, cond_eq_if]
|
|
|
|
|
split
|
|
|
|
|
· simp_all
|
|
|
|
|
· simp_all; omega
|
|
|
|
|
· simp_all
|
|
|
|
|
|
|
|
|
|
@[simp] theorem and_append {x₁ x₂ : BitVec w} {y₁ y₂ : BitVec v} :
|
|
|
|
|
(x₁ ++ y₁) &&& (x₂ ++ y₂) = (x₁ &&& x₂) ++ (y₁ &&& y₂) := by
|
|
|
|
|
ext i
|
|
|
|
|
simp only [getLsbD_append, cond_eq_if]
|
|
|
|
|
split <;> simp [getLsbD_append, *]
|
|
|
|
|
simp only [getElem_and, getElem_append]
|
|
|
|
|
split <;> simp
|
|
|
|
|
|
|
|
|
|
@[simp] theorem or_append {x₁ x₂ : BitVec w} {y₁ y₂ : BitVec v} :
|
|
|
|
|
(x₁ ++ y₁) ||| (x₂ ++ y₂) = (x₁ ||| x₂) ++ (y₁ ||| y₂) := by
|
|
|
|
|
ext i
|
|
|
|
|
simp only [getLsbD_append, cond_eq_if]
|
|
|
|
|
split <;> simp [getLsbD_append, *]
|
|
|
|
|
simp only [getElem_or, getElem_append]
|
|
|
|
|
split <;> simp
|
|
|
|
|
|
|
|
|
|
@[simp] theorem xor_append {x₁ x₂ : BitVec w} {y₁ y₂ : BitVec v} :
|
|
|
|
|
(x₁ ++ y₁) ^^^ (x₂ ++ y₂) = (x₁ ^^^ x₂) ++ (y₁ ^^^ y₂) := by
|
|
|
|
|
ext i
|
|
|
|
|
simp only [getLsbD_append, cond_eq_if]
|
|
|
|
|
split <;> simp [getLsbD_append, *]
|
|
|
|
|
simp only [getElem_xor, getElem_append]
|
|
|
|
|
split <;> simp
|
|
|
|
|
|
|
|
|
|
theorem shiftRight_add {w : Nat} (x : BitVec w) (n m : Nat) :
|
|
|
|
|
x >>> (n + m) = (x >>> n) >>> m:= by
|
|
|
|
|
@ -2151,21 +2163,19 @@ theorem msb_shiftLeft {x : BitVec w} {n : Nat} :
|
|
|
|
|
theorem ushiftRight_eq_extractLsb'_of_lt {x : BitVec w} {n : Nat} (hn : n < w) :
|
|
|
|
|
x >>> n = ((0#n) ++ (x.extractLsb' n (w - n))).cast (by omega) := by
|
|
|
|
|
ext i hi
|
|
|
|
|
simp only [getLsbD_ushiftRight, getLsbD_cast, getLsbD_append, getLsbD_extractLsb', getLsbD_zero,
|
|
|
|
|
Bool.if_false_right, Bool.and_self_left, Bool.iff_and_self, decide_eq_true_eq]
|
|
|
|
|
intros h
|
|
|
|
|
have := lt_of_getLsbD h
|
|
|
|
|
omega
|
|
|
|
|
simp only [getElem_cast, getElem_append, getElem_zero, getElem_ushiftRight, getElem_extractLsb']
|
|
|
|
|
split
|
|
|
|
|
· simp
|
|
|
|
|
· exact getLsbD_ge x (n+i) (by omega)
|
|
|
|
|
|
|
|
|
|
theorem shiftLeft_eq_concat_of_lt {x : BitVec w} {n : Nat} (hn : n < w) :
|
|
|
|
|
x <<< n = (x.extractLsb' 0 (w - n) ++ 0#n).cast (by omega) := by
|
|
|
|
|
ext i hi
|
|
|
|
|
simp only [getLsbD_shiftLeft, hi, decide_true, Bool.true_and, getLsbD_cast, getLsbD_append,
|
|
|
|
|
getLsbD_zero, getLsbD_extractLsb', Nat.zero_add, Bool.if_false_left]
|
|
|
|
|
simp only [getElem_shiftLeft, getElem_cast, getElem_append, getLsbD_zero, getLsbD_extractLsb',
|
|
|
|
|
Nat.zero_add, Bool.if_false_left]
|
|
|
|
|
by_cases hi' : i < n
|
|
|
|
|
· simp [hi']
|
|
|
|
|
· simp [hi']
|
|
|
|
|
omega
|
|
|
|
|
|
|
|
|
|
/-! ### rev -/
|
|
|
|
|
|
|
|
|
|
@ -2241,7 +2251,7 @@ theorem getElem_cons {b : Bool} {n} {x : BitVec n} {i : Nat} (h : i < n + 1) :
|
|
|
|
|
theorem setWidth_succ (x : BitVec w) :
|
|
|
|
|
setWidth (i+1) x = cons (getLsbD x i) (setWidth i x) := by
|
|
|
|
|
ext j h
|
|
|
|
|
simp only [getLsbD_setWidth, getLsbD_cons, h, decide_true, Bool.true_and]
|
|
|
|
|
simp only [getElem_setWidth, getElem_cons]
|
|
|
|
|
if j_eq : j = i then
|
|
|
|
|
simp [j_eq]
|
|
|
|
|
else
|
|
|
|
|
@ -2250,7 +2260,7 @@ theorem setWidth_succ (x : BitVec w) :
|
|
|
|
|
|
|
|
|
|
@[simp] theorem cons_msb_setWidth (x : BitVec (w+1)) : (cons x.msb (x.setWidth w)) = x := by
|
|
|
|
|
ext i
|
|
|
|
|
simp only [getLsbD_cons]
|
|
|
|
|
simp only [getElem_cons]
|
|
|
|
|
split <;> rename_i h
|
|
|
|
|
· simp [BitVec.msb, getMsbD, h]
|
|
|
|
|
· by_cases h' : i < w
|
|
|
|
|
@ -2289,7 +2299,7 @@ theorem cons_append (x : BitVec w₁) (y : BitVec w₂) (a : Bool) :
|
|
|
|
|
theorem cons_append_append (x : BitVec w₁) (y : BitVec w₂) (z : BitVec w₃) (a : Bool) :
|
|
|
|
|
(cons a x) ++ y ++ z = (cons a (x ++ y ++ z)).cast (by omega) := by
|
|
|
|
|
ext i h
|
|
|
|
|
simp only [cons, getLsbD_append, getLsbD_cast, getLsbD_ofBool, cast_cast]
|
|
|
|
|
simp only [cons, getElem_append, getElem_cast, getElem_ofBool, cast_cast, getLsbD_append, getLsbD_cast, getLsbD_ofBool]
|
|
|
|
|
by_cases h₀ : i < w₁ + w₂ + w₃
|
|
|
|
|
· simp only [h₀, ↓reduceIte]
|
|
|
|
|
by_cases h₁ : i < w₃
|
|
|
|
|
@ -2297,8 +2307,7 @@ theorem cons_append_append (x : BitVec w₁) (y : BitVec w₂) (z : BitVec w₃)
|
|
|
|
|
· simp only [h₁, ↓reduceIte]
|
|
|
|
|
by_cases h₂ : i - w₃ < w₂
|
|
|
|
|
· simp [h₂]
|
|
|
|
|
· simp [h₂]
|
|
|
|
|
omega
|
|
|
|
|
· simp [h₂, show i - w₃ - w₂ < w₁ by omega]
|
|
|
|
|
· simp only [show ¬i - w₃ - w₂ < w₁ by omega, ↓reduceIte, show i - w₃ - w₂ - w₁ = 0 by omega,
|
|
|
|
|
decide_true, Bool.true_and, h₀, show i - (w₁ + w₂ + w₃) = 0 by omega]
|
|
|
|
|
by_cases h₂ : i < w₃
|
|
|
|
|
@ -2332,7 +2341,7 @@ theorem getElem_concat (x : BitVec w) (b : Bool) (i : Nat) (h : i < w + 1) :
|
|
|
|
|
· simp [Nat.div_eq_of_lt b.toNat_lt, Nat.testBit_add_one]
|
|
|
|
|
|
|
|
|
|
@[simp] theorem getLsbD_concat_zero : (concat x b).getLsbD 0 = b := by
|
|
|
|
|
simp [getLsbD_concat]
|
|
|
|
|
simp [getElem_concat]
|
|
|
|
|
|
|
|
|
|
@[simp] theorem getElem_concat_zero : (concat x b)[0] = b := by
|
|
|
|
|
simp [getElem_concat]
|
|
|
|
|
@ -2402,7 +2411,7 @@ theorem msb_concat {w : Nat} {b : Bool} {x : BitVec w} :
|
|
|
|
|
|
|
|
|
|
@[simp] theorem zero_concat_false : concat 0#w false = 0#(w + 1) := by
|
|
|
|
|
ext
|
|
|
|
|
simp [getLsbD_concat]
|
|
|
|
|
simp [getElem_concat]
|
|
|
|
|
|
|
|
|
|
/-! ### shiftConcat -/
|
|
|
|
|
|
|
|
|
|
@ -2411,6 +2420,20 @@ theorem getLsbD_shiftConcat (x : BitVec w) (b : Bool) (i : Nat) :
|
|
|
|
|
= (decide (i < w) && (if (i = 0) then b else x.getLsbD (i - 1))) := by
|
|
|
|
|
simp only [shiftConcat, getLsbD_setWidth, getLsbD_concat]
|
|
|
|
|
|
|
|
|
|
theorem getElem_shiftConcat {x : BitVec w} {b : Bool} (h : i < w) :
|
|
|
|
|
(x.shiftConcat b)[i] = if i = 0 then b else x[i-1] := by
|
|
|
|
|
rw [← getLsbD_eq_getElem, getLsbD_shiftConcat, getLsbD_eq_getElem, decide_eq_true h, Bool.true_and]
|
|
|
|
|
|
|
|
|
|
@[simp]
|
|
|
|
|
theorem getElem_shiftConcat_zero {x : BitVec w} (b : Bool) (h : 0 < w) :
|
|
|
|
|
(x.shiftConcat b)[0] = b := by
|
|
|
|
|
simp [getElem_shiftConcat]
|
|
|
|
|
|
|
|
|
|
@[simp]
|
|
|
|
|
theorem getElem_shiftConcat_succ {x : BitVec w} {b : Bool} (h : i + 1 < w) :
|
|
|
|
|
(x.shiftConcat b)[i+1] = x[i] := by
|
|
|
|
|
simp [getElem_shiftConcat]
|
|
|
|
|
|
|
|
|
|
theorem getLsbD_shiftConcat_eq_decide (x : BitVec w) (b : Bool) (i : Nat) :
|
|
|
|
|
(shiftConcat x b).getLsbD i
|
|
|
|
|
= (decide (i < w) && ((decide (i = 0) && b) || (decide (0 < i) && x.getLsbD (i - 1)))) := by
|
|
|
|
|
@ -2420,7 +2443,7 @@ theorem getLsbD_shiftConcat_eq_decide (x : BitVec w) (b : Bool) (i : Nat) :
|
|
|
|
|
theorem shiftRight_sub_one_eq_shiftConcat (n : BitVec w) (hwn : 0 < wn) :
|
|
|
|
|
n >>> (wn - 1) = (n >>> wn).shiftConcat (n.getLsbD (wn - 1)) := by
|
|
|
|
|
ext i h
|
|
|
|
|
simp only [getLsbD_ushiftRight, getLsbD_shiftConcat, h, decide_true, Bool.true_and]
|
|
|
|
|
simp only [getElem_ushiftRight, getElem_shiftConcat, h, decide_true, Bool.true_and]
|
|
|
|
|
split
|
|
|
|
|
· simp [*]
|
|
|
|
|
· congr 1; omega
|
|
|
|
|
@ -2448,20 +2471,6 @@ theorem toNat_shiftConcat_lt_of_lt {x : BitVec w} {b : Bool} {k : Nat}
|
|
|
|
|
have := Bool.toNat_lt b
|
|
|
|
|
omega
|
|
|
|
|
|
|
|
|
|
theorem getElem_shiftConcat {x : BitVec w} {b : Bool} (h : i < w) :
|
|
|
|
|
(x.shiftConcat b)[i] = if i = 0 then b else x[i-1] := by
|
|
|
|
|
rw [← getLsbD_eq_getElem, getLsbD_shiftConcat, getLsbD_eq_getElem, decide_eq_true h, Bool.true_and]
|
|
|
|
|
|
|
|
|
|
@[simp]
|
|
|
|
|
theorem getElem_shiftConcat_zero {x : BitVec w} (b : Bool) (h : 0 < w) :
|
|
|
|
|
(x.shiftConcat b)[0] = b := by
|
|
|
|
|
simp [getElem_shiftConcat]
|
|
|
|
|
|
|
|
|
|
@[simp]
|
|
|
|
|
theorem getElem_shiftConcat_succ {x : BitVec w} {b : Bool} (h : i + 1 < w) :
|
|
|
|
|
(x.shiftConcat b)[i+1] = x[i] := by
|
|
|
|
|
simp [getElem_shiftConcat]
|
|
|
|
|
|
|
|
|
|
/-! ### add -/
|
|
|
|
|
|
|
|
|
|
theorem add_def {n} (x y : BitVec n) : x + y = .ofNat n (x.toNat + y.toNat) := rfl
|
|
|
|
|
@ -3532,8 +3541,7 @@ theorem getLsbD_rotateRight {x : BitVec w} {r i : Nat} :
|
|
|
|
|
@[simp]
|
|
|
|
|
theorem getElem_rotateRight {x : BitVec w} {r i : Nat} (h : i < w) :
|
|
|
|
|
(x.rotateRight r)[i] = if h' : i < w - (r % w) then x[(r % w) + i] else x[(i - (w - (r % w)))] := by
|
|
|
|
|
simp only [← BitVec.getLsbD_eq_getElem]
|
|
|
|
|
simp [getLsbD_rotateRight, h]
|
|
|
|
|
simp [← BitVec.getLsbD_eq_getElem, getLsbD_rotateRight, h]
|
|
|
|
|
|
|
|
|
|
theorem getMsbD_rotateRightAux_of_lt {x : BitVec w} {r : Nat} {i : Nat} (hi : i < r) :
|
|
|
|
|
(x.rotateRightAux r).getMsbD i = x.getMsbD (i + (w - r)) := by
|
|
|
|
|
@ -3644,9 +3652,9 @@ theorem msb_twoPow {i w: Nat} :
|
|
|
|
|
|
|
|
|
|
theorem and_twoPow (x : BitVec w) (i : Nat) :
|
|
|
|
|
x &&& (twoPow w i) = if x.getLsbD i then twoPow w i else 0#w := by
|
|
|
|
|
ext j
|
|
|
|
|
simp only [getLsbD_and, getLsbD_twoPow]
|
|
|
|
|
by_cases hj : i = j <;> by_cases hx : x.getLsbD i <;> simp_all
|
|
|
|
|
ext j h
|
|
|
|
|
simp only [getElem_and, getLsbD_twoPow]
|
|
|
|
|
by_cases hj : i = j <;> by_cases hx : x.getLsbD i <;> simp_all <;> omega
|
|
|
|
|
|
|
|
|
|
theorem twoPow_and (x : BitVec w) (i : Nat) :
|
|
|
|
|
(twoPow w i) &&& x = if x.getLsbD i then twoPow w i else 0#w := by
|
|
|
|
|
@ -3697,16 +3705,15 @@ theorem udiv_twoPow_eq_of_lt {w : Nat} {x : BitVec w} {k : Nat} (hk : k < w) : x
|
|
|
|
|
|
|
|
|
|
@[simp] theorem true_cons_zero : cons true 0#w = twoPow (w + 1) w := by
|
|
|
|
|
ext
|
|
|
|
|
simp [getLsbD_cons]
|
|
|
|
|
omega
|
|
|
|
|
simp [getElem_cons]
|
|
|
|
|
|
|
|
|
|
@[simp] theorem false_cons_zero : cons false 0#w = 0#(w + 1) := by
|
|
|
|
|
ext
|
|
|
|
|
simp [getLsbD_cons]
|
|
|
|
|
simp [getElem_cons]
|
|
|
|
|
|
|
|
|
|
@[simp] theorem zero_concat_true : concat 0#w true = 1#(w + 1) := by
|
|
|
|
|
ext
|
|
|
|
|
simp [getLsbD_concat]
|
|
|
|
|
simp [getElem_concat]
|
|
|
|
|
|
|
|
|
|
/- ### setWidth, setWidth, and bitwise operations -/
|
|
|
|
|
|
|
|
|
|
@ -3719,7 +3726,6 @@ theorem setWidth_setWidth_succ_eq_setWidth_setWidth_of_getLsbD_false
|
|
|
|
|
setWidth w (x.setWidth (i + 1)) =
|
|
|
|
|
setWidth w (x.setWidth i) := by
|
|
|
|
|
ext k h
|
|
|
|
|
simp only [getLsbD_setWidth, h, decide_true, Bool.true_and, getLsbD_or, getLsbD_and]
|
|
|
|
|
by_cases hik : i = k
|
|
|
|
|
· subst hik
|
|
|
|
|
simp [hx]
|
|
|
|
|
@ -3735,16 +3741,18 @@ theorem setWidth_setWidth_succ_eq_setWidth_setWidth_or_twoPow_of_getLsbD_true
|
|
|
|
|
setWidth w (x.setWidth (i + 1)) =
|
|
|
|
|
setWidth w (x.setWidth i) ||| (twoPow w i) := by
|
|
|
|
|
ext k h
|
|
|
|
|
simp only [getLsbD_setWidth, h, decide_true, Bool.true_and, getLsbD_or, getLsbD_and]
|
|
|
|
|
simp only [getElem_setWidth, h, getElem_or, getElem_twoPow]
|
|
|
|
|
by_cases hik : i = k
|
|
|
|
|
· subst hik
|
|
|
|
|
simp [hx, h]
|
|
|
|
|
· by_cases hik' : k < i + 1 <;> simp [hik, hik'] <;> omega
|
|
|
|
|
simp [hx]
|
|
|
|
|
· by_cases hik' : k < i + 1
|
|
|
|
|
<;> simp [hik, hik', show ¬ (k = i) by omega]
|
|
|
|
|
<;> omega
|
|
|
|
|
|
|
|
|
|
/-- Bitwise and of `(x : BitVec w)` with `1#w` equals zero extending `x.lsb` to `w`. -/
|
|
|
|
|
theorem and_one_eq_setWidth_ofBool_getLsbD {x : BitVec w} :
|
|
|
|
|
(x &&& 1#w) = setWidth w (ofBool (x.getLsbD 0)) := by
|
|
|
|
|
ext (_ | i) h <;> simp [Bool.and_comm]
|
|
|
|
|
ext (_ | i) h <;> simp [Bool.and_comm, h]
|
|
|
|
|
|
|
|
|
|
@[simp]
|
|
|
|
|
theorem replicate_zero {x : BitVec w} : x.replicate 0 = 0#0 := by
|
|
|
|
|
@ -3772,7 +3780,8 @@ theorem getLsbD_replicate {n w : Nat} {x : BitVec w} :
|
|
|
|
|
by_cases hi : i < w * (n + 1)
|
|
|
|
|
· simp only [hi, decide_true, Bool.true_and]
|
|
|
|
|
by_cases hi' : i < w * n
|
|
|
|
|
· simp [hi', ih]
|
|
|
|
|
· rw [ih]
|
|
|
|
|
simp_all
|
|
|
|
|
· simp only [hi', ↓reduceIte]
|
|
|
|
|
rw [Nat.sub_mul_eq_mod_of_lt_of_le (by omega) (by omega)]
|
|
|
|
|
· rw [Nat.mul_succ] at hi ⊢
|
|
|
|
|
@ -3793,7 +3802,7 @@ theorem append_assoc {x₁ : BitVec w₁} {x₂ : BitVec w₂} {x₃ : BitVec w
|
|
|
|
|
specialize @ih (setWidth n x₁)
|
|
|
|
|
rw [← cons_msb_setWidth x₁, cons_append_append, ih, cons_append]
|
|
|
|
|
ext j h
|
|
|
|
|
simp [getLsbD_cons, show n + w₂ + w₃ = n + (w₂ + w₃) by omega]
|
|
|
|
|
simp [getElem_cons, show n + w₂ + w₃ = n + (w₂ + w₃) by omega]
|
|
|
|
|
|
|
|
|
|
theorem replicate_append_self {x : BitVec w} :
|
|
|
|
|
x ++ x.replicate n = (x.replicate n ++ x).cast (by omega) := by
|
|
|
|
|
@ -4112,6 +4121,10 @@ theorem getLsbD_reverse {i : Nat} {x : BitVec w} :
|
|
|
|
|
simp only [show n - (n + 1) = 0 by omega, Nat.zero_le, decide_true, Bool.true_and]
|
|
|
|
|
congr; omega
|
|
|
|
|
|
|
|
|
|
theorem getElem_reverse (x : BitVec w) (h : i < w) :
|
|
|
|
|
x.reverse[i] = x.getMsbD i := by
|
|
|
|
|
rw [← getLsbD_eq_getElem, getLsbD_reverse]
|
|
|
|
|
|
|
|
|
|
theorem getMsbD_reverse {i : Nat} {x : BitVec w} :
|
|
|
|
|
(x.reverse).getMsbD i = x.getLsbD i := by
|
|
|
|
|
simp only [getMsbD_eq_getLsbD, getLsbD_reverse]
|
|
|
|
|
@ -4127,14 +4140,14 @@ theorem msb_reverse {x : BitVec w} :
|
|
|
|
|
theorem reverse_append {x : BitVec w} {y : BitVec v} :
|
|
|
|
|
(x ++ y).reverse = (y.reverse ++ x.reverse).cast (by omega) := by
|
|
|
|
|
ext i h
|
|
|
|
|
simp only [getLsbD_append, getLsbD_reverse]
|
|
|
|
|
simp only [getElem_reverse, getElem_cast, getElem_append]
|
|
|
|
|
by_cases hi : i < v
|
|
|
|
|
· by_cases hw : w ≤ i
|
|
|
|
|
· simp [getMsbD_append, getLsbD_cast, getLsbD_append, getLsbD_reverse, hw]
|
|
|
|
|
· simp [getMsbD_append, getLsbD_cast, getLsbD_append, getLsbD_reverse, hw, show i < w by omega]
|
|
|
|
|
· simp [getLsbD_reverse, hw]
|
|
|
|
|
· simp [getElem_reverse, hw, show i < w by omega]
|
|
|
|
|
· by_cases hw : w ≤ i
|
|
|
|
|
· simp [getMsbD_append, getLsbD_cast, getLsbD_append, hw, show ¬ i < w by omega, getLsbD_reverse]
|
|
|
|
|
· simp [getMsbD_append, getLsbD_cast, getLsbD_append, hw, show i < w by omega, getLsbD_reverse]
|
|
|
|
|
· simp [hw, show ¬ i < w by omega, getLsbD_reverse]
|
|
|
|
|
· simp [hw, show i < w by omega, getElem_reverse]
|
|
|
|
|
|
|
|
|
|
@[simp]
|
|
|
|
|
theorem reverse_cast {w v : Nat} (h : w = v) (x : BitVec w) :
|
|
|
|
|
|