Skip to content
REFERENCE / ZLIB × LEAN

public-adler-update.lean

Source snapshot · e0be7bd1cbf668e8 · Source at the matching commit ↗

Lean source with line numbers. Follow a line number to locate a statement, or an import to read its dependency.

1import ZlibF.Spec.Public.Checksums
2import ZlibF.Proof.«adler32.c.public-any»
3
4open C Zlib.Adler32 Zlib.Adler32.Spec Zlib.Adler32.Proofs ZlibF.Spec.Public
5
6namespace ZlibF.Spec.Public.AdlerUpdateProof
7
8theorem adler_z_any_public {h : Heap} {ref : BRef} {data : Array UInt8}
9    (hg : Space.get h ref = some data) (seed : UInt64) (off : Nat) (len : UInt64)
10    (hf : off + len.toNat ≤ data.size) :
11    C.run (adler32_z seed (.ref ref off) len) h =
12      .ok (adlerValue seed ((data.toList.drop off).take len.toNat), h) := by
13  have he : UInt64.ofNat len.toNat = len := UInt64.ofNat_toNat
14  by_cases h1 : len.toNat = 1
15  · have hlen : len = 1 := by apply UInt64.toNat_inj.mp; simpa using h1
16    subst len
17    have hr := adler32_z_one_public (h := h) (r := ref) (off := off) (bytes := data) hg (by simpa using hf) seed
18    have hs := seg_eq_slice data off 1 (by simpa using hf)
19    rw [seg_one] at hs
20    have hout : (data.toList.drop off).take 1 = [data[off]!] := hs.symm
21    simpa [adlerValue, hout] using hr
22  · have hr := adler32_z_any_format hg seed off len.toNat hf len.toNat_lt h1
23    rw [seg_eq_slice data off len.toNat hf] at hr
24    have hl : ((data.toList.drop off).take len.toNat).length = len.toNat := by
25      simp only [List.length_take, List.length_drop, Array.length_toList]
26      apply Nat.min_eq_left
27      omega
28    have hn : ((data.toList.drop off).take len.toNat).length ≠ 1 := by omega
29    unfold adlerValue
30    rw [ite_eq_right hn]
31    change C.run (adler32_z seed (.ref ref off) len) h =
32      .ok ((ZlibF.Spec.adler32Update (canonicalStart seed) ((data.toList.drop off).take len.toNat)).toUInt64, h)
33    simpa only [he] using hr
34
35/-- `uLong adler32_z(uLong adler, const Bytef *buf, z_size_t len)` updates the checksum. -/
36theorem adler_z_public : Goal.adler32_z := by
37  intro h seed pointer len bytes hb
38  obtain ⟨hbuf, hnull⟩ := hb
39  rcases hbuf with ⟨rfl, rfl⟩ | ⟨ref, off, data, rfl, hg, hf, rfl⟩
40  · have hlen : len = 0 := UInt64.toNat_inj.mp (by simpa using hnull rfl)
41    subst len
42    rfl
43  · simpa using adler_z_any_public hg seed off len hf
44
45/-- `uLong adler32(uLong adler, const Bytef *buf, uInt len)` has the same update contract. -/
46theorem adler_public : Goal.adler32 := by
47  intro h seed pointer len bytes hb
48  have hr := adler_z_public h seed pointer len.toUInt64 bytes (by simpa [AdlerBufferBytes] using hb)
49  simpa [Zlib.Adler32.adler32] using hr
50
51#print axioms adler_z_public
52#print axioms adler_public
53end ZlibF.Spec.Public.AdlerUpdateProof
ZLIB × LEAN

Global contents

READING NOWpublic-adler-update.lean