-- Mathlib/.lake/packages/lean4/src/lean/Init/Data/BitVec/Lemmas.lean
theorem signExtend_eq_not_setWidth_not_of_msb_true {x : BitVec w} {v : Nat} (hmsb : x.msb = true) :
    x.signExtend v = ~~~((~~~x).setWidth v)

Proof state:
case a.a
w : Nat
x : BitVec w
v : Nat
hmsb : x.msb = true
⊢ (2 ^ w - 1 - x.toNat) % 2 ^ v + 1 ≤ ?a.m✝

Tactic:
apply Nat.succ_le_of_lt

Result:
case a.a.h
w : Nat
x : BitVec w
v : Nat
hmsb : x.msb = true
⊢ (2 ^ w - 1 - x.toNat) % 2 ^ v < ?a.m✝

Proof state:
case a
w : Nat
x : BitVec w
v : Nat
hmsb : x.msb = true
⊢ ((↑x.toNat - ↑(2 ^ w)) % ↑(2 ^ v)).toNat = 2 ^ v - 1 - (2 ^ w - 1 - x.toNat) % 2 ^ v

Tactic:
rw [Int.ofNat_sub_ofNat_of_lt, Int.negSucc_emod]

Result:
case a
w : Nat
x : BitVec w
v : Nat
hmsb : x.msb = true
⊢ (Int.subNatNat (↑(2 ^ v)).natAbs ((2 ^ w - 1 - x.toNat) % (↑(2 ^ v)).natAbs + 1)).toNat =
    2 ^ v - 1 - (2 ^ w - 1 - x.toNat) % 2 ^ v

case a
w : Nat
x : BitVec w
v : Nat
hmsb : x.msb = true
⊢ x.toNat < 2 ^ w

Proof state:
case a
w : Nat
x : BitVec w
v : Nat
hmsb : x.msb = true
⊢ (Int.subNatNat (↑(2 ^ v)).natAbs ((2 ^ w - 1 - x.toNat) % (↑(2 ^ v)).natAbs + 1)).toNat =
    2 ^ v - 1 - (2 ^ w - 1 - x.toNat) % 2 ^ v

case a
w : Nat
x : BitVec w
v : Nat
hmsb : x.msb = true
⊢ x.toNat < 2 ^ w

Tactic:
simp only [Int.natAbs_ofNat, Nat.succ_eq_add_one]

Result:
case a
w : Nat
x : BitVec w
v : Nat
hmsb : x.msb = true
⊢ (Int.subNatNat (2 ^ v) ((2 ^ w - 1 - x.toNat) % 2 ^ v + 1)).toNat = 2 ^ v - 1 - (2 ^ w - 1 - x.toNat) % 2 ^ v

case a
w : Nat
x : BitVec w
v : Nat
hmsb : x.msb = true
⊢ x.toNat < 2 ^ w

Proof state:
case a
w : Nat
x : BitVec w
v : Nat
hmsb : x.msb = true
⊢ (↑(2 ^ v - ((2 ^ w - 1 - x.toNat) % 2 ^ v + 1))).toNat = 2 ^ v - 1 - (2 ^ w - 1 - x.toNat) % 2 ^ v

Tactic:
rw [Int.toNat_ofNat, Nat.add_comm, Nat.sub_add_eq]

Result:
no goals

Proof state:
case a.a.h
w : Nat
x : BitVec w
v : Nat
hmsb : x.msb = true
⊢ (2 ^ w - 1 - x.toNat) % 2 ^ v < ?a.m✝

Tactic:
apply Nat.mod_lt

Result:
case a.a.h.a
w : Nat
x : BitVec w
v : Nat
hmsb : x.msb = true
⊢ 2 ^ v > 0

Proof state:
case a.a.h.a
w : Nat
x : BitVec w
v : Nat
hmsb : x.msb = true
⊢ 2 ^ v > 0

Tactic:
apply Nat.two_pow_pos

Result:
no goals

Proof state:
case a
w : Nat
x : BitVec w
v : Nat
hmsb : x.msb = true
⊢ (2 ^ w - 1 - x.toNat) % 2 ^ v + 1 ≤ 2 ^ v

Tactic:
apply Nat.le_trans

Result:
case a.a
w : Nat
x : BitVec w
v : Nat
hmsb : x.msb = true
⊢ (2 ^ w - 1 - x.toNat) % 2 ^ v + 1 ≤ ?a.m✝

case a.a
w : Nat
x : BitVec w
v : Nat
hmsb : x.msb = true
⊢ ?a.m✝ ≤ 2 ^ v

case a.m
w : Nat
x : BitVec w
v : Nat
hmsb : x.msb = true
⊢ Nat

Proof state:
w : Nat
x : BitVec w
v : Nat
hmsb : x.msb = true
⊢ signExtend v x = ~~~setWidth v (~~~x)

Tactic:
apply BitVec.eq_of_toNat_eq

Result:
case a
w : Nat
x : BitVec w
v : Nat
hmsb : x.msb = true
⊢ (signExtend v x).toNat = (~~~setWidth v (~~~x)).toNat

Proof state:
case a.a
w : Nat
x : BitVec w
v : Nat
hmsb : x.msb = true
⊢ 2 ^ v ≤ 2 ^ v

Tactic:
apply Nat.le_refl

Result:
no goals

Proof state:
case a
w : Nat
x : BitVec w
v : Nat
hmsb : x.msb = true
⊢ (signExtend v x).toNat = (~~~setWidth v (~~~x)).toNat

Tactic:
simp only [signExtend, BitVec.toInt_eq_msb_cond, toNat_ofInt, toNat_not,
  toNat_setWidth, hmsb, ↓reduceIte]

Result:
case a
w : Nat
x : BitVec w
v : Nat
hmsb : x.msb = true
⊢ ((↑x.toNat - ↑(2 ^ w)) % ↑(2 ^ v)).toNat = 2 ^ v - 1 - (2 ^ w - 1 - x.toNat) % 2 ^ v

Proof state:
case a
w : Nat
x : BitVec w
v : Nat
hmsb : x.msb = true
⊢ x.toNat < 2 ^ w

Tactic:
omega

Result:
no goals

Proof state:
case a
w : Nat
x : BitVec w
v : Nat
hmsb : x.msb = true
⊢ (Int.subNatNat (2 ^ v) ((2 ^ w - 1 - x.toNat) % 2 ^ v + 1)).toNat = 2 ^ v - 1 - (2 ^ w - 1 - x.toNat) % 2 ^ v

case a
w : Nat
x : BitVec w
v : Nat
hmsb : x.msb = true
⊢ x.toNat < 2 ^ w

Tactic:
rw [Int.subNatNat_of_le]

Result:
case a
w : Nat
x : BitVec w
v : Nat
hmsb : x.msb = true
⊢ (↑(2 ^ v - ((2 ^ w - 1 - x.toNat) % 2 ^ v + 1))).toNat = 2 ^ v - 1 - (2 ^ w - 1 - x.toNat) % 2 ^ v

case a
w : Nat
x : BitVec w
v : Nat
hmsb : x.msb = true
⊢ (2 ^ w - 1 - x.toNat) % 2 ^ v + 1 ≤ 2 ^ v

case a
w : Nat
x : BitVec w
v : Nat
hmsb : x.msb = true
⊢ x.toNat < 2 ^ w