feat: add ByteArray indexing and set! lemmas (#13457)
This PR adds the missing `ByteArray` push and `set!` lemmas that are still carried locally in `ZipForStd.ByteArray` downstream. These lemmas provide one coherent API layer for reasoning about `ByteArray` pushes and `set!` updates on top of the existing upstream append, extract, and size lemmas. Previous downstream code had to keep local compatibility lemmas for these common proof steps. --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
c993d3f237
commit
1b8f1f140c
1 changed files with 77 additions and 0 deletions
|
|
@ -328,4 +328,81 @@ theorem extract_eq_extract_iff_getElem {as bs : ByteArray} {i j len : Nat}
|
|||
· exact h k hk'
|
||||
· exact (by omega : k = len) ▸ h'
|
||||
|
||||
theorem getElem!_push_lt (data : ByteArray) (b : UInt8) (i : Nat) (hi : i < data.size) :
|
||||
(data.push b)[i]! = data[i]! := by
|
||||
have hi' : i < (data.push b).size := by
|
||||
simp only [ByteArray.size_push]
|
||||
omega
|
||||
rw [getElem!_pos (data.push b) i hi', getElem!_pos data i hi]
|
||||
exact Array.getElem_push_lt hi
|
||||
|
||||
@[simp] theorem getElem!_push_eq (data : ByteArray) (b : UInt8) :
|
||||
(data.push b)[data.size]! = b := by
|
||||
have h : data.size < (data.push b).size := by
|
||||
simp only [ByteArray.size_push]
|
||||
omega
|
||||
rw [getElem!_pos (data.push b) data.size h]
|
||||
exact Array.getElem_push_eq
|
||||
|
||||
@[grind =] theorem getElem!_push (data : ByteArray) (b : UInt8) (i : Nat) :
|
||||
(data.push b)[i]! = if i = data.size then b else data[i]! := by
|
||||
split
|
||||
· subst i
|
||||
exact getElem!_push_eq data b
|
||||
· by_cases hi : i < data.size
|
||||
· exact getElem!_push_lt data b i hi
|
||||
· rw [getElem!_neg data i hi,
|
||||
getElem!_neg (data.push b) i (by simp only [ByteArray.size_push]; omega)]
|
||||
|
||||
private theorem getElem!_eq_data_getElem! (data : ByteArray) (i : Nat) :
|
||||
data[i]! = data.data[i]! := by
|
||||
by_cases h : i < data.size
|
||||
· rw [getElem!_pos data i h, getElem!_pos data.data i h]
|
||||
rfl
|
||||
· rw [getElem!_neg data i h, getElem!_neg data.data i h]
|
||||
|
||||
@[simp, grind =] theorem size_set! (data : ByteArray) (i : Nat) (v : UInt8) :
|
||||
(data.set! i v).size = data.size := by
|
||||
show (data.data.setIfInBounds i v).size = data.data.size
|
||||
exact Array.size_setIfInBounds ..
|
||||
|
||||
@[simp] theorem getElem!_set!_self (data : ByteArray) (i : Nat) (v : UInt8) (h : i < data.size) :
|
||||
(data.set! i v)[i]! = v := by
|
||||
rw [getElem!_eq_data_getElem!]
|
||||
show (data.data.set! i v)[i]! = v
|
||||
simp only [Array.set!_eq_setIfInBounds, Array.getElem!_eq_getD, Array.getD_eq_getD_getElem?,
|
||||
Array.getElem?_setIfInBounds_self_of_lt h, Option.getD_some]
|
||||
|
||||
@[simp] theorem getElem!_set!_ne (data : ByteArray) (i j : Nat) (v : UInt8) (hij : i ≠ j) :
|
||||
(data.set! i v)[j]! = data[j]! := by
|
||||
rw [getElem!_eq_data_getElem!, getElem!_eq_data_getElem!]
|
||||
show (data.data.set! i v)[j]! = data.data[j]!
|
||||
simp only [Array.set!_eq_setIfInBounds, Array.getElem!_eq_getD, Array.getD_eq_getD_getElem?,
|
||||
Array.getElem?_setIfInBounds_ne hij]
|
||||
|
||||
@[grind =] theorem getElem!_set! (data : ByteArray) (i : Nat) (v : UInt8) (j : Nat) (h : i < data.size) :
|
||||
(data.set! i v)[j]! = if i = j then v else data[j]! := by
|
||||
split
|
||||
· next hij => subst hij; exact getElem!_set!_self data i v h
|
||||
· next hij => exact getElem!_set!_ne data i j v hij
|
||||
|
||||
@[simp] theorem getElem_set!_ne (data : ByteArray) (i j : Nat) (v : UInt8) (hij : i ≠ j)
|
||||
(hj : j < data.size) :
|
||||
(data.set! i v)[j]'(by rw [size_set!]; exact hj) = data[j] := by
|
||||
rw [← getElem!_pos (data.set! i v) j (by rw [size_set!]; exact hj),
|
||||
← getElem!_pos data j hj,
|
||||
getElem!_set!_ne _ _ _ _ hij]
|
||||
|
||||
@[simp] theorem getElem_set!_self (data : ByteArray) (i : Nat) (v : UInt8) (h : i < data.size) :
|
||||
(data.set! i v)[i]'(by rw [size_set!]; exact h) = v := by
|
||||
rw [← getElem!_pos (data.set! i v) i (by rw [size_set!]; exact h),
|
||||
getElem!_set!_self _ _ _ h]
|
||||
|
||||
@[grind =] theorem getElem_set! (data : ByteArray) (i j : Nat) (v : UInt8) (h : i < data.size)
|
||||
(hj : j < data.size) :
|
||||
(data.set! i v)[j]'(by rw [size_set!]; exact hj) = if i = j then v else data[j] := by
|
||||
split
|
||||
· next hij => subst hij; exact getElem_set!_self data i v h
|
||||
· next hij => exact getElem_set!_ne data i j v hij hj
|
||||
|
||||
end ByteArray
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue