Skip to content
REFERENCE / ZLIB × LEAN

Dictionary.lean

Source snapshot · a20daad1bab61981 · 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.Math.LZ77History
2import ZlibF.Spec.Api.Basic
3
4namespace ZlibF.Spec.Proofs
5open ZlibF.Spec ZlibF.Math.LZ77History
6
7/-- A match whose distance fits a retained suffix copies the same bytes if older dictionary
8bytes are available. -/
9private theorem copy_suffix {small large history : List UInt8} {dist n : Nat}
10    (hs : small <:+ large) (hp : 0 < dist) (hd : dist ≤ (small ++ history).length) :
11    copyBack large dist n history = copyBack small dist n history := by
12  have he := retained_history_agrees large [] history small dist n (by simpa using hs) hp
13    (by simpa [List.length_append] using hd)
14  simpa using he
15
16/-- Decoding symbols is stable when extra older dictionary bytes are prepended. -/
17theorem symbols_dictionary_suffix {L D : List Nat} {small large history output : List UInt8}
18    {input rest : List Bool} (hs : small <:+ large)
19    (h : Symbols L D small history input rest output) : Symbols L D large history input rest output := by
20  induction h with
21  | eob hd => exact .eob hd
22  | lit hd hlt _ ih => exact .lit hd hlt ih
23  | @copy hist inp r1 r2 r3 r4 rest sym ds xl xd output hd h1 h2 hr1 hd2 h3 hr2 hb hcopy ih =>
24    have hbase : 0 < distBases.getD ds 0 :=
25      (by decide : ∀ i, i < 30 → 0 < distBases.getD i 0) ds (by omega)
26    have hpos : 0 < distBases.getD ds 0 + xd := by omega
27    have hfit : distBases.getD ds 0 + xd ≤ (small ++ hist).length := by omega
28    have hsame := copy_suffix hs hpos hfit (n := lengthBases.getD (sym - 257) 0 + xl)
29    have hlarge : xd + distBases.getD ds 0 ≤ (large ++ hist).length := by
30      obtain ⟨older, he⟩ := hs
31      rw [← he]
32      simp only [List.length_append] at *
33      omega
34    apply Symbols.copy hd h1 h2 hr1 hd2 h3 hr2 hlarge
35    rw [hsame]
36    exact ih
37
38/-- A block keeps its decoding when the dictionary grows by an older prefix. -/
39theorem body_dictionary_suffix {small large history output : List UInt8} {bt : Nat}
40    {input rest : List Bool} (hs : small <:+ large)
41    (h : Body small bt history input rest output) : Body large bt history input rest output := by
42  cases h with
43  | stored h1 h2 h3 h4 => exact .stored h1 h2 h3 h4
44  | fixed h => exact .fixed (symbols_dictionary_suffix hs h)
45  | dynamic h1 h2 h3 hc h4 ha hl heob hL hD h =>
46    exact .dynamic h1 h2 h3 hc h4 ha hl heob hL hD (symbols_dictionary_suffix hs h)
47
48/-- A complete sequence of blocks has the same output with a larger dictionary. -/
49theorem blocks_dictionary_suffix {small large history output : List UInt8} {input rest : List Bool}
50    (hs : small <:+ large) (h : Blocks small history input rest output) :
51    Blocks large history input rest output := by
52  induction h with
53  | last h1 h2 hb => exact .last h1 h2 (body_dictionary_suffix hs hb)
54  | more h1 h2 hb _ ih => exact .more h1 h2 (body_dictionary_suffix hs hb) ih
55
56/-- A complete raw deflate stream remains valid after prepending older dictionary bytes. -/
57theorem deflate_dictionary_suffix {small large stream output : List UInt8}
58    (hs : small <:+ large) (h : Deflate.Decodes small stream output) :
59    Deflate.Decodes large stream output := by
60  obtain ⟨rest, hb, hr⟩ := h
61  exact ⟨rest, blocks_dictionary_suffix hs hb, hr⟩
62
63/-- A stream valid for a smaller raw window is valid for the 32 KiB raw window. -/
64theorem raw_full_window {dict stream output : List UInt8} {bits : Nat} (hb : bits ≤ 15)
65    (h : Deflate.Decodes (dict.drop (dict.length - 2 ^ bits)) stream output) :
66    ZlibF.Spec.Api.Layer.Decodes .raw 15 dict stream output := by
67  have hpow : 2 ^ bits ≤ 2 ^ 15 := Nat.pow_le_pow_right (by decide) hb
68  have hi : dict.length - 2 ^ 15 ≤ dict.length - 2 ^ bits := by omega
69  have hs := List.drop_suffix ((dict.length - 2 ^ bits) - (dict.length - 2 ^ 15))
70    (dict.drop (dict.length - 2 ^ 15))
71  have hs' : dict.drop (dict.length - 2 ^ bits) <:+ dict.drop (dict.length - 2 ^ 15) := by
72    simpa only [List.drop_drop, Nat.add_sub_of_le hi] using hs
73  exact deflate_dictionary_suffix hs' h
74
75#print axioms deflate_dictionary_suffix
76#print axioms raw_full_window
77end ZlibF.Spec.Proofs
ZLIB × LEAN

Global contents

READING NOWDictionary.lean