From e69bcb0757e2c237cbb8f016a17cd5cdf6c36c3a Mon Sep 17 00:00:00 2001 From: Kim Morrison Date: Tue, 10 Dec 2024 12:33:09 +1100 Subject: [PATCH] chore: improve BitVec ext lemmas (#6349) This PR modifies `BitVec` extensionality lemmas to prefer bounded Nats over `Fin`, and avoids unnecessary use of `bif` in BitVec theorems. --- src/Init/Data/BitVec/Bitblast.lean | 10 +- src/Init/Data/BitVec/Lemmas.lean | 182 +++++++++--------- .../Bitblast/BVExpr/Circuit/Lemmas/Expr.lean | 8 +- .../BVExpr/Circuit/Lemmas/Operations/Eq.lean | 4 +- src/Std/Tactic/BVDecide/Normalize/BitVec.lean | 8 +- tests/lean/run/bv_uninterpreted.lean | 4 +- 6 files changed, 101 insertions(+), 115 deletions(-) diff --git a/src/Init/Data/BitVec/Bitblast.lean b/src/Init/Data/BitVec/Bitblast.lean index 3ef86361b6..1f086933f7 100644 --- a/src/Init/Data/BitVec/Bitblast.lean +++ b/src/Init/Data/BitVec/Bitblast.lean @@ -462,7 +462,7 @@ theorem msb_neg {w : Nat} {x : BitVec w} : case true => apply hmin apply eq_of_getMsbD_eq - rintro ⟨i, hi⟩ + intro i hi simp only [getMsbD_intMin, w_pos, decide_true, Bool.true_and] cases i case zero => exact hmsb @@ -470,7 +470,7 @@ theorem msb_neg {w : Nat} {x : BitVec w} : case false => apply hzero apply eq_of_getMsbD_eq - rintro ⟨i, hi⟩ + intro i hi simp only [getMsbD_zero] cases i case zero => exact hmsb @@ -573,11 +573,11 @@ theorem setWidth_setWidth_succ_eq_setWidth_setWidth_add_twoPow (x : BitVec w) (i setWidth w (x.setWidth (i + 1)) = setWidth w (x.setWidth i) + (x &&& twoPow w i) := by rw [add_eq_or_of_and_eq_zero] - · ext k - simp only [getLsbD_setWidth, Fin.is_lt, decide_true, Bool.true_and, getLsbD_or, getLsbD_and] + · 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 + simp [h] · simp only [getLsbD_twoPow, hik, decide_false, Bool.and_false, Bool.or_false] by_cases hik' : k < (i + 1) · have hik'' : k < i := by omega diff --git a/src/Init/Data/BitVec/Lemmas.lean b/src/Init/Data/BitVec/Lemmas.lean index ad4d7343b8..00b12166b8 100644 --- a/src/Init/Data/BitVec/Lemmas.lean +++ b/src/Init/Data/BitVec/Lemmas.lean @@ -173,21 +173,21 @@ theorem getMsbD_eq_getMsb?_getD (x : BitVec w) (i : Nat) : -- 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} - (pred : ∀(i : Fin w), x.getLsbD i.val = y.getLsbD i.val) : x = y := by + (pred : ∀ i, i < w → x.getLsbD i = y.getLsbD i) : x = y := by apply eq_of_toNat_eq apply Nat.eq_of_testBit_eq intro i if i_lt : i < w then - exact pred ⟨i, i_lt⟩ + exact pred i i_lt else have p : i ≥ w := Nat.le_of_not_gt i_lt simp [testBit_toNat, getLsbD_ge _ _ p] theorem eq_of_getMsbD_eq {x y : BitVec w} - (pred : ∀(i : Fin w), x.getMsbD i.val = y.getMsbD i.val) : x = y := by + (pred : ∀ i, i < w → x.getMsbD i = y.getMsbD i) : x = y := by simp only [getMsbD] at pred apply eq_of_getLsbD_eq - intro ⟨i, i_lt⟩ + intro i i_lt if w_zero : w = 0 then simp [w_zero] else @@ -199,7 +199,7 @@ theorem eq_of_getMsbD_eq {x y : BitVec w} simp only [Nat.sub_sub] apply Nat.sub_lt w_pos simp [Nat.succ_add] - have q := pred ⟨w - 1 - i, q_lt⟩ + have q := pred (w - 1 - i) q_lt simpa [q_lt, Nat.sub_sub_self, r] using q -- This cannot be a `@[simp]` lemma, as it would be tried at every term. @@ -710,14 +710,15 @@ theorem msb_setWidth'' (x : BitVec w) : (x.setWidth (k + 1)).msb = x.getLsbD k : /-- zero extending a bitvector to width 1 equals the boolean of the lsb. -/ theorem setWidth_one_eq_ofBool_getLsb_zero (x : BitVec w) : x.setWidth 1 = BitVec.ofBool (x.getLsbD 0) := by - ext i - simp [getLsbD_setWidth, Fin.fin_one_eq_zero i] + ext i h + simp at h + simp [getLsbD_setWidth, h] /-- Zero extending `1#v` to `1#w` equals `1#w` when `v > 0`. -/ 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, hilt⟩ - simp only [getLsbD_setWidth, hilt, decide_true, getLsbD_ofNat, Bool.true_and, + ext i h + simp only [getLsbD_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₁ @@ -744,8 +745,7 @@ protected theorem extractLsb_ofFin {n} (x : Fin (2^n)) (hi lo : Nat) : @[simp] protected theorem extractLsb_ofNat (x n : Nat) (hi lo : Nat) : extractLsb hi lo (BitVec.ofNat n x) = .ofNat (hi - lo + 1) ((x % 2^n) >>> lo) := by - apply eq_of_getLsbD_eq - intro ⟨i, _lt⟩ + ext i simp [BitVec.ofNat] @[simp] theorem extractLsb'_toNat (s m : Nat) (x : BitVec n) : @@ -832,8 +832,8 @@ theorem extractLsb'_eq_extractLsb {w : Nat} (x : BitVec w) (start len : Nat) (h @[simp] theorem setWidth_or {x y : BitVec w} : (x ||| y).setWidth k = x.setWidth k ||| y.setWidth k := by - ext - simp + ext i h + simp [h] theorem or_assoc (x y z : BitVec w) : x ||| y ||| z = x ||| (y ||| z) := by @@ -866,12 +866,12 @@ instance : Std.LawfulCommIdentity (α := BitVec n) (· ||| · ) (0#n) where simp @[simp] theorem or_allOnes {x : BitVec w} : x ||| allOnes w = allOnes w := by - ext i - simp + ext i h + simp [h] @[simp] theorem allOnes_or {x : BitVec w} : allOnes w ||| x = allOnes w := by - ext i - simp + ext i h + simp [h] /-! ### and -/ @@ -905,8 +905,8 @@ instance : Std.LawfulCommIdentity (α := BitVec n) (· ||| · ) (0#n) where @[simp] theorem setWidth_and {x y : BitVec w} : (x &&& y).setWidth k = x.setWidth k &&& y.setWidth k := by - ext - simp + ext i h + simp [h] theorem and_assoc (x y z : BitVec w) : x &&& y &&& z = x &&& (y &&& z) := by @@ -936,15 +936,15 @@ instance : Std.IdempotentOp (α := BitVec n) (· &&& · ) where simp @[simp] theorem and_allOnes {x : BitVec w} : x &&& allOnes w = x := by - ext i - simp + ext i h + simp [h] instance : Std.LawfulCommIdentity (α := BitVec n) (· &&& · ) (allOnes n) where right_id _ := BitVec.and_allOnes @[simp] theorem allOnes_and {x : BitVec w} : allOnes w &&& x = x := by - ext i - simp + ext i h + simp [h] /-! ### xor -/ @@ -981,8 +981,8 @@ instance : Std.LawfulCommIdentity (α := BitVec n) (· &&& · ) (allOnes n) wher @[simp] theorem setWidth_xor {x y : BitVec w} : (x ^^^ y).setWidth k = x.setWidth k ^^^ y.setWidth k := by - ext - simp + ext i h + simp [h] theorem xor_assoc (x y z : BitVec w) : x ^^^ y ^^^ z = x ^^^ (y ^^^ z) := by @@ -1075,9 +1075,9 @@ theorem not_def {x : BitVec v} : ~~~x = allOnes v ^^^ x := rfl rw [Nat.testBit_two_pow_sub_succ x.isLt] simp [h] -@[simp] theorem setWidth_not {x : BitVec w} (h : k ≤ w) : +@[simp] theorem setWidth_not {x : BitVec w} (_ : k ≤ w) : (~~~x).setWidth k = ~~~(x.setWidth k) := by - ext + ext i h simp [h] omega @@ -1090,17 +1090,17 @@ theorem not_def {x : BitVec v} : ~~~x = allOnes v ^^^ x := rfl simp @[simp] theorem xor_allOnes {x : BitVec w} : x ^^^ allOnes w = ~~~ x := by - ext i - simp + ext i h + simp [h] @[simp] theorem allOnes_xor {x : BitVec w} : allOnes w ^^^ x = ~~~ x := by - ext i - simp + ext i h + simp [h] @[simp] theorem not_not {b : BitVec w} : ~~~(~~~b) = b := by - ext i - simp + ext i h + simp [h] theorem not_eq_comm {x y : BitVec w} : ~~~ x = y ↔ x = ~~~ y := by constructor @@ -1175,24 +1175,21 @@ 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 - simp only [getLsbD_shiftLeft, Fin.is_lt, decide_true, Bool.true_and, getLsbD_xor] - by_cases h : i < n - <;> simp [h] + ext i h + simp only [getLsbD_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 - simp only [getLsbD_shiftLeft, Fin.is_lt, decide_true, Bool.true_and, getLsbD_and] - by_cases h : i < n - <;> simp [h] + ext i h + simp only [getLsbD_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 - simp only [getLsbD_shiftLeft, Fin.is_lt, decide_true, Bool.true_and, getLsbD_or] - by_cases h : i < n - <;> simp [h] + ext i h + simp only [getLsbD_shiftLeft, h, decide_true, Bool.true_and, getLsbD_or] + by_cases h' : i < n <;> simp [h'] @[simp] theorem getMsbD_shiftLeft (x : BitVec w) (i) : (x <<< i).getMsbD k = x.getMsbD (k + i) := by @@ -1531,12 +1528,12 @@ theorem msb_sshiftRight {n : Nat} {x : BitVec w} : simp [show n = 0 by omega] @[simp] theorem sshiftRight_zero {x : BitVec w} : x.sshiftRight 0 = x := by - ext i - simp [getLsbD_sshiftRight] + ext i h + simp [getLsbD_sshiftRight, h] @[simp] theorem zero_sshiftRight {n : Nat} : (0#w).sshiftRight n = 0#w := by - ext i - simp [getLsbD_sshiftRight] + ext i h + simp [getLsbD_sshiftRight, h] theorem sshiftRight_add {x : BitVec w} {m n : Nat} : x.sshiftRight (m + n) = (x.sshiftRight m).sshiftRight n := by @@ -1701,8 +1698,8 @@ theorem msb_signExtend {x : BitVec w} : /-- Sign extending to a width smaller than the starting width is a truncation. -/ theorem signExtend_eq_setWidth_of_lt (x : BitVec w) {v : Nat} (hv : v ≤ w): x.signExtend v = x.setWidth v := by - ext i - simp only [getLsbD_signExtend, Fin.is_lt, decide_true, Bool.true_and, getLsbD_setWidth, + ext i h + simp only [getLsbD_signExtend, h, decide_true, Bool.true_and, getLsbD_setWidth, ite_eq_left_iff, Nat.not_lt] omega @@ -1796,35 +1793,34 @@ theorem append_def (x : BitVec v) (y : BitVec w) : rfl theorem getLsbD_append {x : BitVec n} {y : BitVec m} : - getLsbD (x ++ y) i = bif i < m then getLsbD y i else getLsbD x (i - m) := by + getLsbD (x ++ y) i = if i < m then getLsbD y i else getLsbD x (i - m) := by simp only [append_def, getLsbD_or, getLsbD_shiftLeftZeroExtend, getLsbD_setWidth'] by_cases h : i < m · simp [h] · simp_all [h] theorem getElem_append {x : BitVec n} {y : BitVec m} (h : i < n + m) : - (x ++ y)[i] = bif i < m then getLsbD y i else getLsbD x (i - m) := by + (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'] by_cases h' : i < m · simp [h'] · simp_all [h'] @[simp] theorem getMsbD_append {x : BitVec n} {y : BitVec m} : - getMsbD (x ++ y) i = bif n ≤ i then getMsbD y (i - n) else getMsbD x i := by + getMsbD (x ++ y) i = if n ≤ i then getMsbD y (i - n) else getMsbD x i := by simp only [append_def] by_cases h : n ≤ i · simp [h] · simp [h] theorem msb_append {x : BitVec w} {y : BitVec v} : - (x ++ y).msb = bif (w == 0) then (y.msb) else (x.msb) := by + (x ++ y).msb = if w = 0 then y.msb else x.msb := by rw [← append_eq, append] simp only [msb_or, msb_shiftLeftZeroExtend, msb_setWidth'] by_cases h : w = 0 · subst h simp [BitVec.msb, getMsbD] - · rw [cond_eq_if] - have q : 0 < w + v := by omega + · have q : 0 < w + v := by omega have t : y.getLsbD (w + v - 1) = false := getLsbD_ge _ _ (by omega) simp [h, q, t, BitVec.msb, getMsbD] @@ -1840,7 +1836,7 @@ theorem msb_append {x : BitVec w} {y : BitVec v} : @[simp] theorem zero_append_zero : 0#v ++ 0#w = 0#(v + w) := by ext - simp only [getLsbD_append, getLsbD_zero, Bool.cond_self] + simp only [getLsbD_append, getLsbD_zero, ite_self] @[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 @@ -1860,21 +1856,19 @@ theorem msb_append {x : BitVec w} {y : BitVec v} : 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 - apply eq_of_getLsbD_eq - intro i - simp only [getLsbD_setWidth, Fin.is_lt, decide_true, getLsbD_append, Bool.true_and] - split - · have t : i < v := by omega - simp [t] - · by_cases t : i < v - · simp [t, getLsbD_append] - · have t' : i - v < k - v := by omega - simp [t, t', getLsbD_append] + ext i h + simp only [getLsbD_setWidth, h, getLsbD_append] + split <;> rename_i h₁ <;> split <;> rename_i h₂ + · simp [h] + · simp [getLsbD_append, h₁] + · omega + · simp [getLsbD_append, h₁] + omega @[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 - simp only [getLsbD_setWidth, Fin.is_lt, decide_true, getLsbD_append, cond_eq_if, + ext i h + simp only [getLsbD_setWidth, h, decide_true, getLsbD_append, cond_eq_if, decide_eq_true_eq, Bool.true_and, setWidth_eq] split · simp_all @@ -1924,12 +1918,12 @@ theorem shiftLeft_ushiftRight {x : BitVec w} {n : Nat}: case succ n ih => rw [BitVec.shiftLeft_add, Nat.add_comm, BitVec.shiftRight_add, ih, Nat.add_comm, BitVec.shiftLeft_add, BitVec.shiftLeft_and_distrib] - ext i + ext i h by_cases hw : w = 0 · simp [hw] - · by_cases hi₂ : i.val = 0 + · by_cases hi₂ : i = 0 · simp [hi₂] - · simp [Nat.lt_one_iff, hi₂, show 1 + (i.val - 1) = i by omega] + · simp [Nat.lt_one_iff, hi₂, h, show 1 + (i - 1) = i by omega] @[simp] theorem msb_shiftLeft {x : BitVec w} {n : Nat} : @@ -2014,13 +2008,12 @@ 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 - apply eq_of_getLsbD_eq - intro j - simp only [getLsbD_setWidth, getLsbD_cons, j.isLt, decide_true, Bool.true_and] - if j_eq : j.val = i then + ext j h + simp only [getLsbD_setWidth, getLsbD_cons, h, decide_true, Bool.true_and] + if j_eq : j = i then simp [j_eq] else - have j_lt : j.val < i := Nat.lt_of_le_of_ne (Nat.le_of_succ_le_succ j.isLt) j_eq + have j_lt : j < i := Nat.lt_of_le_of_ne (Nat.le_of_succ_le_succ h) j_eq simp [j_eq, j_lt] @[simp] theorem cons_msb_setWidth (x : BitVec (w+1)) : (cons x.msb (x.setWidth w)) = x := by @@ -2134,19 +2127,19 @@ theorem msb_concat {w : Nat} {b : Bool} {x : BitVec w} : simp [← Fin.val_inj] @[simp] theorem not_concat (x : BitVec w) (b : Bool) : ~~~(concat x b) = concat (~~~x) !b := by - ext i; cases i using Fin.succRecOn <;> simp [*, Nat.succ_lt_succ] + ext (_ | i) h <;> simp [getLsbD_concat] @[simp] theorem concat_or_concat (x y : BitVec w) (a b : Bool) : (concat x a) ||| (concat y b) = concat (x ||| y) (a || b) := by - ext i; cases i using Fin.succRecOn <;> simp + ext (_ | i) h <;> simp [getLsbD_concat] @[simp] theorem concat_and_concat (x y : BitVec w) (a b : Bool) : (concat x a) &&& (concat y b) = concat (x &&& y) (a && b) := by - ext i; cases i using Fin.succRecOn <;> simp + ext (_ | i) h <;> simp [getLsbD_concat] @[simp] theorem concat_xor_concat (x y : BitVec w) (a b : Bool) : (concat x a) ^^^ (concat y b) = concat (x ^^^ y) (a ^^ b) := by - ext i; cases i using Fin.succRecOn <;> simp + ext (_ | i) h <;> simp [getLsbD_concat] @[simp] theorem zero_concat_false : concat 0#w false = 0#(w + 1) := by ext @@ -2167,8 +2160,8 @@ 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 - simp only [getLsbD_ushiftRight, getLsbD_shiftConcat, Fin.is_lt, decide_true, Bool.true_and] + ext i h + simp only [getLsbD_ushiftRight, getLsbD_shiftConcat, h, decide_true, Bool.true_and] split · simp [*] · congr 1; omega @@ -3179,8 +3172,8 @@ theorem setWidth_setWidth_succ_eq_setWidth_setWidth_of_getLsbD_false {x : BitVec w} {i : Nat} (hx : x.getLsbD i = false) : setWidth w (x.setWidth (i + 1)) = setWidth w (x.setWidth i) := by - ext k - simp only [getLsbD_setWidth, Fin.is_lt, decide_true, Bool.true_and, getLsbD_or, getLsbD_and] + 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] @@ -3195,20 +3188,17 @@ theorem setWidth_setWidth_succ_eq_setWidth_setWidth_or_twoPow_of_getLsbD_true {x : BitVec w} {i : Nat} (hx : x.getLsbD i = true) : setWidth w (x.setWidth (i + 1)) = setWidth w (x.setWidth i) ||| (twoPow w i) := by - ext k - simp only [getLsbD_setWidth, Fin.is_lt, decide_true, Bool.true_and, getLsbD_or, getLsbD_and] + 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] + simp [hx, h] · by_cases hik' : k < i + 1 <;> simp [hik, hik'] <;> 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 - simp only [getLsbD_and, getLsbD_one, getLsbD_setWidth, Fin.is_lt, decide_true, getLsbD_ofBool, - Bool.true_and] - by_cases h : ((i : Nat) = 0) <;> simp [h] <;> omega + ext (_ | i) h <;> simp [Bool.and_comm] @[simp] theorem replicate_zero_eq {x : BitVec w} : x.replicate 0 = 0#0 := by @@ -3232,7 +3222,7 @@ theorem getLsbD_replicate {n w : Nat} (x : BitVec w) : · simp only [hi, decide_true, Bool.true_and] by_cases hi' : i < w * n · simp [hi', ih] - · simp only [hi', decide_false, cond_false] + · simp [hi', decide_false] rw [Nat.sub_mul_eq_mod_of_lt_of_le] <;> omega · rw [Nat.mul_succ] at hi ⊢ simp only [show ¬i < w * n by omega, decide_false, cond_false, hi, Bool.false_and] @@ -3538,7 +3528,7 @@ theorem forall_zero_iff {P : BitVec 0 → Prop} : · intro h apply h · intro h v - obtain (rfl : v = 0#0) := (by ext ⟨i, h⟩; simp at h) + obtain (rfl : v = 0#0) := (by ext i ⟨⟩) apply h theorem forall_cons_iff {P : BitVec (n + 1) → Prop} : @@ -3554,7 +3544,7 @@ theorem forall_cons_iff {P : BitVec (n + 1) → Prop} : instance instDecidableForallBitVecZero (P : BitVec 0 → Prop) : ∀ [Decidable (P 0#0)], Decidable (∀ v, P v) | .isTrue h => .isTrue fun v => by - obtain (rfl : v = 0#0) := (by ext ⟨i, h⟩; cases h) + obtain (rfl : v = 0#0) := (by ext i ⟨⟩) exact h | .isFalse h => .isFalse (fun w => h (w _)) diff --git a/src/Std/Tactic/BVDecide/Bitblast/BVExpr/Circuit/Lemmas/Expr.lean b/src/Std/Tactic/BVDecide/Bitblast/BVExpr/Circuit/Lemmas/Expr.lean index de3c7eba71..ac3deef26c 100644 --- a/src/Std/Tactic/BVDecide/Bitblast/BVExpr/Circuit/Lemmas/Expr.lean +++ b/src/Std/Tactic/BVDecide/Bitblast/BVExpr/Circuit/Lemmas/Expr.lean @@ -77,12 +77,8 @@ theorem go_denote_eq (aig : AIG BVBit) (expr : BVExpr w) (assign : Assignment) : simp only [go, denote_blastAppend, RefVec.get_cast, Ref.cast_eq, eval_append, BitVec.getLsbD_append] split - · next hsplit => - simp only [hsplit, decide_true, cond_true] - rw [rih] - · next hsplit => - simp only [hsplit, decide_false, cond_false] - rw [go_denote_mem_prefix, lih] + · next hsplit => rw [rih] + · next hsplit => rw [go_denote_mem_prefix, lih] | replicate n expr ih => simp [go, ih, hidx] | signExtend v inner ih => rename_i originalWidth diff --git a/src/Std/Tactic/BVDecide/Bitblast/BVExpr/Circuit/Lemmas/Operations/Eq.lean b/src/Std/Tactic/BVDecide/Bitblast/BVExpr/Circuit/Lemmas/Operations/Eq.lean index d8ef872677..5a552aec57 100644 --- a/src/Std/Tactic/BVDecide/Bitblast/BVExpr/Circuit/Lemmas/Operations/Eq.lean +++ b/src/Std/Tactic/BVDecide/Bitblast/BVExpr/Circuit/Lemmas/Operations/Eq.lean @@ -30,9 +30,9 @@ theorem mkEq_denote_eq (aig : AIG α) (pair : AIG.BinaryRefVec aig w) (assign : simp only [RefVec.denote_fold_and, RefVec.denote_zip, denote_mkBEqCached, beq_iff_eq] constructor · intro h - ext + ext i h' rw [← hleft, ← hright] - · simp [h] + · simp [h, h'] · omega · omega · intro h idx hidx diff --git a/src/Std/Tactic/BVDecide/Normalize/BitVec.lean b/src/Std/Tactic/BVDecide/Normalize/BitVec.lean index b7187f59de..13c6e8611e 100644 --- a/src/Std/Tactic/BVDecide/Normalize/BitVec.lean +++ b/src/Std/Tactic/BVDecide/Normalize/BitVec.lean @@ -168,13 +168,13 @@ attribute [bv_normalize] BitVec.and_self @[bv_normalize] theorem BitVec.and_contra (a : BitVec w) : a &&& ~~~a = 0#w := by - ext - simp + ext i h + simp [h] @[bv_normalize] theorem BitVec.and_contra' (a : BitVec w) : ~~~a &&& a = 0#w := by - ext - simp + ext i h + simp [h] @[bv_normalize] theorem BitVec.add_not (a : BitVec w) : a + ~~~a = (-1#w) := by diff --git a/tests/lean/run/bv_uninterpreted.lean b/tests/lean/run/bv_uninterpreted.lean index b341a57db8..32b6b542bf 100644 --- a/tests/lean/run/bv_uninterpreted.lean +++ b/tests/lean/run/bv_uninterpreted.lean @@ -5,8 +5,8 @@ example {x y z : BitVec w} : (x &&& y) ||| (x &&& z) ||| (y &&& z) ||| x ||| y ||| z = ~~~ ((~~~ x) &&& (~~~ y) &&& (~~~ z)) := by - ext - simp + ext i h + simp [h] bv_decide @[irreducible]