@@ -619,6 +619,8 @@ theorem le_toInt {w : Nat} {x : BitVec w} : -2 ^ w ≤ 2 * x.toInt := by
619619 · rw [← Nat.two_pow_pred_add_two_pow_pred (by omega), ← Nat.two_mul, Nat.add_sub_cancel]
620620 simp only [Nat.zero_lt_succ, Nat.mul_lt_mul_left, Int.natCast_mul, Int.Nat.cast_ofNat_Int]
621621 norm_cast; omega
622+ @[simp] theorem toInt_cast (h : w = v) (x : BitVec w) : (cast h x).toInt = x.toInt := by
623+ simp [toInt_eq_toNat_bmod, h]
622624
623625/-! ### slt -/
624626
@@ -673,6 +675,12 @@ theorem zeroExtend_eq_setWidth {v : Nat} {x : BitVec w} :
673675 (x.setWidth v).toFin = Fin.ofNat' (2 ^v) x.toNat := by
674676 ext; simp
675677
678+ theorem setWidth'_eq {x : BitVec w} (h : w ≤ v) : x.setWidth' h = x.setWidth v := by
679+ apply eq_of_toNat_eq
680+ rw [toNat_setWidth, toNat_setWidth']
681+ rw [Nat.mod_eq_of_lt]
682+ exact Nat.lt_of_lt_of_le x.isLt (Nat.pow_le_pow_right (Nat.zero_lt_two) h)
683+
676684@[simp] theorem setWidth_eq (x : BitVec n) : setWidth n x = x := by
677685 apply eq_of_toNat_eq
678686 let ⟨x, lt_n⟩ := x
@@ -2026,6 +2034,23 @@ theorem append_def (x : BitVec v) (y : BitVec w) :
20262034 (x ++ y).toNat = x.toNat <<< n ||| y.toNat :=
20272035 rfl
20282036
2037+ /-- Helper theorem to show that the expression in `(x ++ y).toFin` is inbounds. -/
2038+ theorem toNat_append_lt {m n : Nat} (x : BitVec m) (y : BitVec n) :
2039+ x.toNat <<< n ||| y.toNat < 2 ^ (m + n) := by
2040+ have hnLe : 2 ^n ≤ 2 ^(m + n) := by
2041+ rw [Nat.pow_add]
2042+ exact Nat.le_mul_of_pos_left (2 ^ n) (Nat.two_pow_pos m)
2043+ apply Nat.or_lt_two_pow
2044+ · have := Nat.two_pow_pos n
2045+ rw [Nat.shiftLeft_eq, Nat.pow_add, Nat.mul_lt_mul_right]
2046+ <;> omega
2047+ · omega
2048+
2049+ @[simp] theorem toFin_append {x : BitVec m} {y : BitVec n} :
2050+ (x ++ y).toFin = @Fin.mk (2 ^(m+n)) (x.toNat <<< n ||| y.toNat) (toNat_append_lt x y) := by
2051+ ext
2052+ simp
2053+
20292054theorem getLsbD_append {x : BitVec n} {y : BitVec m} :
20302055 getLsbD (x ++ y) i = if i < m then getLsbD y i else getLsbD x (i - m) := by
20312056 simp only [append_def, getLsbD_or, getLsbD_shiftLeftZeroExtend, getLsbD_setWidth']
@@ -2072,6 +2097,173 @@ theorem msb_append {x : BitVec w} {y : BitVec v} :
20722097 ext
20732098 simp [getElem_append]
20742099
2100+ theorem append_zero {n m : Nat} {x : BitVec n} :
2101+ x ++ 0 #m = x.signExtend (n + m) <<< m := by
2102+ induction m
2103+ case zero =>
2104+ simp [signExtend]
2105+ case succ i ih =>
2106+ simp [bv_toNat]
2107+ sorry
2108+
2109+ def lhs (x : BitVec n) (y : BitVec m) : Int := (x++y).toInt
2110+ def rhs (x : BitVec n) (y : BitVec m) : Int := if n == 0 then y.toInt else (x.toInt * (2 ^m)) + y.toNat
2111+
2112+ def eq (x: BitVec n) (y: BitVec m) : Bool := (lhs x y) = (rhs x y)
2113+
2114+
2115+ #eval (-5 #10 ++ 3 #2 ).toInt
2116+
2117+ def test : Bool := Id.run do
2118+ for i in [0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 ] do
2119+ for j in [0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 ] do
2120+ for n in [0 , 1 , 2 , 3 , 4 ] do
2121+ for m in [0 , 1 , 2 , 3 , 4 ] do
2122+ let x := BitVec.ofNat n i
2123+ let y := BitVec.ofNat m j
2124+ if (!eq x y) then
2125+ return false
2126+ return true
2127+
2128+ private theorem Nat.lt_mul_of_le_of_lt_of_lt {a b c : Nat} (hab : a ≤ b) (ha : 0 < a) (hc : 1 < c) :
2129+ a < b * c := by
2130+ have : a * 1 < b * c := Nat.mul_lt_mul_of_le_of_lt' (by omega) (by simp [hc]) (by omega)
2131+ simp at this
2132+ simp [this]
2133+
2134+ private theorem Nat.two_pow_lt_two_pow_add {n m : Nat} (h : m ≠ 0 ) :
2135+ 2 ^ n < 2 ^ (n + m) := by
2136+ apply Nat.pow_lt_pow_of_lt (by omega) (by omega)
2137+
2138+ @[simp] theorem signExtend_shiftLeft_msb {n m : Nat} {x : BitVec n} :
2139+ (signExtend (n + m) x <<< m).msb = x.msb := by
2140+ induction m
2141+ case zero =>
2142+ simp [signExtend]
2143+ case succ i ih =>
2144+ rw [← ih]
2145+ rw [msb_setWidth]
2146+
2147+ unfold BitVec.msb getMsbD
2148+ simp
2149+ by_cases h : (0 < n + i)
2150+ ·
2151+ rw [← Nat.add_assoc]
2152+ simp [h]
2153+ have h' : (0 < n + i + 1 ) := by omega
2154+ have hh : (n + i - (i + 1 )) = (n + i - i - 1 ) := by
2155+ omega
2156+ rw [hh]
2157+ simp
2158+ have hhh : (n + i - 1 - i) = (n + i - i - 1 ) := by omega
2159+ rw [hhh]
2160+ simp
2161+ rw [getLsbD_signExtend]
2162+
2163+
2164+
2165+
2166+
2167+
2168+ simp [BitVec.msb, getMsbD]
2169+
2170+ by_cases h : 0 < n + (i + 1 )
2171+ · simp [h]
2172+
2173+ sorry
2174+ · simp [h]
2175+ sorry
2176+
2177+ @[simp] theorem signExtend_toNat_shift_mod :
2178+ ((signExtend (n + m) x).toNat <<< m) % ↑(2 ^ (n + m)) = (signExtend (n + m) x).toNat <<< m :=
2179+ sorry
2180+
2181+ @[simp] theorem toInt_append_zero {n m : Nat} {x : BitVec n} :
2182+ (x ++ 0 #m).toInt = x.toInt * (2 ^ m) := by
2183+ by_cases m0 : m = 0
2184+ · subst m0
2185+ simp
2186+ · simp only [ofNat_eq_ofNat, append_zero, toInt_eq_msb_cond]
2187+ by_cases h1 : (signExtend (n + m) x <<< m).msb
2188+ · by_cases h2: x.msb
2189+ · norm_cast
2190+ simp [h1, h2]
2191+ norm_cast
2192+ rw [Int.sub_mul, Nat.pow_add]
2193+ norm_cast
2194+ simp
2195+ rw [Nat.shiftLeft_eq]
2196+ norm_cast
2197+ have aa := @Nat.pow_pos 2 m (by omega)
2198+ norm_cast
2199+ have bb := @Nat.mul_right_cancel_iff (2 ^m) ((signExtend (n + m) x).toNat)
2200+ apply bb
2201+ rfl
2202+ rw [Nat.mul_right_cancel (m := 2 ^ m)]
2203+ simp [aa]
2204+ rw [Nat.mod_eq_of_lt (a := x.toNat) (by omega)]
2205+ norm_cast
2206+ simp [h3]
2207+ simp_all
2208+ rw [Nat.shiftLeft_eq]
2209+ · simp only [signExtend_shiftLeft_of_lt] at h1
2210+ contradiction
2211+ · by_cases h2: x.msb
2212+ · simp [signExtend_shiftLeft_of_lt, h2] at h1
2213+ · sorry
2214+
2215+ @[simp] theorem toInt_append {x : BitVec n} {y : BitVec m} :
2216+ (x ++ y).toInt = if n == 0 then y.toInt else x.toInt * (2 ^ m) + y.toNat := by
2217+ by_cases n0 : n = 0
2218+ · subst n0
2219+ simp [BitVec.eq_nil x]
2220+ · by_cases m0 : m = 0
2221+ · subst m0
2222+ simp [BitVec.eq_nil y, n0]
2223+ · simp [m0]
2224+ by_cases y0 : y = 0
2225+ · simp [toInt_append_zero, y0, n0]
2226+ rw [toInt_eq_toNat_cond]
2227+ rw [toInt_eq_toNat_cond]
2228+ split
2229+ ·
2230+ split
2231+ <;> norm_cast
2232+ <;> simp
2233+ <;> rw [Nat.mod_eq_of_lt (a := x.toNat) (by omega)]
2234+ <;> norm_cast
2235+ <;> simp [h3]
2236+ <;> simp_all
2237+ · rw [Nat.shiftLeft_eq]
2238+ · rename_i aa bb
2239+ rw [Nat.shiftLeft_eq] at aa
2240+ rw [Nat.pow_add] at aa
2241+ rw [← Nat.mul_assoc] at aa
2242+
2243+ sorry
2244+ ·
2245+ split
2246+ <;> norm_cast
2247+ <;> simp
2248+ <;> rw [Nat.mod_eq_of_lt (a := x.toNat) (by omega)]
2249+ <;> norm_cast
2250+ <;> simp [h3]
2251+ <;> simp_all
2252+ · rename_i aa bb
2253+ rw [Nat.shiftLeft_eq] at aa
2254+ rw [Nat.pow_add] at aa
2255+ rw [← Nat.mul_assoc] at aa
2256+
2257+
2258+
2259+
2260+ simp_all
2261+
2262+
2263+ sorry
2264+ · simp [Nat.shiftLeft_eq, Int.sub_mul, Nat.pow_add]
2265+ · sorry
2266+
20752267@[simp] theorem cast_append_right (h : w + v = w + v') (x : BitVec w) (y : BitVec v) :
20762268 (x ++ y).cast h = x ++ y.cast (by omega) := by
20772269 ext
0 commit comments