Skip to content
REFERENCE / ZLIB × LEAN

DeflateBounds.lean

Source snapshot · 1b9abb8b027a61a5 · 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.Proof.Api.Deflate
2
3namespace ZlibF.Spec.Api.Proofs
4open ZlibF.Spec
5
6private def BoundInvariant (s : DeflState) : Prop :=
7  s.done = true → s.started = true ∧ (s.clean = true → s.produced.length ≤ s.bound s.input.length)
8
9private theorem bound_run {st st' : DeflState} {c : DeflCall} {o : DeflOut}
10    (hr : DeflRun st c o st') (hp : BoundInvariant st) : BoundInvariant st' := by
11  rcases hr with ⟨hf, hparams, _, hstart, _, _, _, _, _, hend, _, _, _, _, hdone, _, _, hstable,
12    _, hclean, _, _, hstarted, _⟩
13  rcases hf with ⟨_, _, hi, ho, _, _, hd, hh⟩
14  intro hdone'
15  by_cases hd0 : st.done = true
16  · refine ⟨hstarted (hp hd0).1, fun hc => ?_⟩
17    have hb := (hp hd0).2 (hclean hc)
18    have he := hstable hd0
19    have hbound : st'.bound st'.input.length = st.bound st.input.length := by
20      simp only [DeflState.bound, DeflState.header, DeflState.dictEff, hparams, hd, hh, hi,
21        he.1, List.take_zero, List.append_nil]
22      rfl
23    simpa only [ho, he.2, List.append_nil, hbound] using hb
24  · have hrc := (hdone.mp hdone').resolve_left hd0
25    refine ⟨(hstart (Or.inr hrc)).1, fun hc => ?_⟩
26    have hb := (hend hrc).2.2.2.2.2.2.2.2 (hclean hc)
27    have hbound : st'.bound st'.input.length = st.bound (st.input ++ c.inp.take o.consumed).length := by
28      simp only [DeflState.bound, DeflState.header, DeflState.dictEff, hparams, hd, hh, hi]
29      rfl
30    simpa only [ho, hbound] using hb
31
32private theorem bound_step {st st' : DeflState} {c : DeflCall} {o : DeflOut}
33    (hr : DeflStep st c o st') (hp : BoundInvariant st) : BoundInvariant st' := by
34  by_cases ht : c.flush = .trees
35  · have he := (hr.1 ht).2.2.2
36    subst st'; exact hp
37  by_cases hb : c.badBuf = true ∨ (st.finishing = true ∧ c.flush ≠ .finish)
38  · have he := (hr.2.1 ht hb).2.2.2
39    subst st'; exact hp
40  have hbuf : c.badBuf = false := by cases h : c.badBuf <;> simp_all
41  have hnfin : ¬ (st.finishing = true ∧ c.flush ≠ .finish) := fun h => hb (Or.inr h)
42  by_cases hz : c.availOut = 0
43  · have he := (hr.2.2.1 ht hbuf hnfin hz).2.2.2
44    subst st'; exact hp
45  exact bound_run (hr.2.2.2 ht hbuf hnfin hz) hp
46
47private theorem bound_dict {st st' : DeflState} {d : List UInt8} {rc : Int}
48    (hr : DeflSetDict st d rc st') (hp : BoundInvariant st) : BoundInvariant st' := by
49  cases hw : st.params.wrap with
50  | gzip =>
51    simp only [DeflSetDict, hw] at hr
52    rcases hr with ⟨_, rfl⟩
53    exact hp
54  | zlib =>
55    simp only [DeflSetDict, hw] at hr
56    split at hr
57    · rcases hr with ⟨_, rfl⟩
58      exact hp
59    · rename_i hn
60      rcases hr with ⟨_, rfl⟩
61      intro hd
62      exact (hn (hp hd).1).elim
63  | raw =>
64    simp only [DeflSetDict, hw] at hr
65    split at hr
66    · rcases hr with ⟨_, rfl⟩
67      intro hd
68      refine ⟨(hp hd).1, fun hc => ?_⟩
69      have hb := (hp hd).2 hc
70      simpa only [DeflState.bound, DeflState.header, DeflState.dictEff, hw] using hb
71    · rcases hr with ⟨_, rfl⟩ | ⟨_, rfl⟩
72      · exact hp
73      · intro hd
74        refine ⟨(hp hd).1, fun hc => ?_⟩
75        cases hc
76
77private theorem bound_header {st st' : DeflState} {h : GzHead} {rc : Int}
78    (hr : DeflSetHeader st h rc st') (hp : BoundInvariant st) : BoundInvariant st' := by
79  unfold DeflSetHeader at hr
80  split at hr
81  · rcases hr with ⟨_, rfl⟩
82    exact hp
83  · rcases hr with ⟨_, hbad, hgood⟩
84    by_cases hb : st.started = true ∨ ¬ h.Valid
85    · obtain rfl := hbad hb
86      intro hd
87      refine ⟨(hp hd).1, fun hc => ?_⟩
88      cases hc
89    · obtain rfl := hgood hb
90      intro hd
91      exact (hb (Or.inl (hp hd).1)).elim
92
93private theorem trace_bound {X : List UInt8} {st st' : DeflState} (ht : DeflTrace X st st')
94    (hp : BoundInvariant st) : BoundInvariant st' := by
95  induction ht with
96  | nil => exact hp
97  | step _ hm _ ih => exact ih (bound_step hm.1 hp)
98  | dict hm _ ih => exact ih (bound_dict hm hp)
99  | header hm _ ih => exact ih (bound_header hm hp)
100
101/-- The abstract trace model bounds a clean completed stream. This does not establish the
102corresponding refinement for translated C. -/
103theorem deflate_bound_adequate : Goal.deflate_bound_adequate := by
104  intro p x st _ ht hd hc
105  exact (trace_bound ht (by simp [BoundInvariant, DeflState.fresh]) hd).2 hc
106
107private theorem step_input_prefix {x : List UInt8} {st st' : DeflState} {c : DeflCall} {o : DeflOut}
108    (hs : DeflStep st c o st') (hin : st.input <+: x) (hc : c.inp <+: x.drop st.input.length) :
109    st'.input <+: x := by
110  have hframe : st'.input = st.input ++ c.inp.take o.consumed := by
111    by_cases ht : c.flush = .trees
112    · rcases hs.1 ht with ⟨_, hz, _, rfl⟩
113      simp [hz]
114    by_cases hb : c.badBuf = true ∨ (st.finishing = true ∧ c.flush ≠ .finish)
115    · rcases hs.2.1 ht hb with ⟨_, hz, _, rfl⟩
116      simp [hz]
117    have hbuf : c.badBuf = false := by cases h : c.badBuf <;> simp_all
118    have hnfin : ¬ (st.finishing = true ∧ c.flush ≠ .finish) := fun h => hb (Or.inr h)
119    by_cases hz : c.availOut = 0
120    · rcases hs.2.2.1 ht hbuf hnfin hz with ⟨_, hn, _, rfl⟩
121      simp [hn]
122    exact (hs.2.2.2 ht hbuf hnfin hz).1.2.2.1
123  rw [hframe]
124  have htake : c.inp.take o.consumed <+: x.drop st.input.length :=
125    (List.take_prefix _ _).trans hc
126  obtain ⟨tail, htail⟩ := hin
127  rw [← htail, List.drop_left] at htake
128  obtain ⟨tail', htail'⟩ := htake
129  refine ⟨tail', ?_⟩
130  simp only [htail, htail', List.append_assoc]
131
132private theorem dict_input {s s' : DeflState} {d : List UInt8} {r : Int}
133    (hm : DeflSetDict s d r s') : s'.input = s.input := by
134  cases hw : s.params.wrap with
135  | gzip => simp only [DeflSetDict, hw] at hm; rcases hm with ⟨_, rfl⟩; rfl
136  | zlib =>
137    simp only [DeflSetDict, hw] at hm
138    split at hm <;> rcases hm with ⟨_, rfl⟩ <;> rfl
139  | raw =>
140    simp only [DeflSetDict, hw] at hm
141    split at hm
142    · rcases hm with ⟨_, rfl⟩; rfl
143    · rcases hm with ⟨_, rfl⟩ | ⟨_, rfl⟩ <;> rfl
144
145private theorem header_input {s s' : DeflState} {h : GzHead} {r : Int}
146    (hm : DeflSetHeader s h r s') : s'.input = s.input := by
147  unfold DeflSetHeader at hm
148  split at hm
149  · rcases hm with ⟨_, rfl⟩; rfl
150  · rcases hm with ⟨_, hb, hg⟩
151    by_cases he : s.started = true ∨ ¬ h.Valid
152    · rw [hb he]
153    · rw [hg he]
154
155private theorem trace_input_prefix {x : List UInt8} {st st' : DeflState} (ht : DeflTrace x st st')
156    (hin : st.input <+: x) : st'.input <+: x := by
157  induction ht with
158  | nil => exact hin
159  | step hp hm _ ih => exact ih (step_input_prefix hm.1 hin hp)
160  | dict hm _ ih => exact ih (by rw [dict_input hm]; exact hin)
161  | header hm _ ih => exact ih (by rw [header_input hm]; exact hin)
162
163/-- A finish call in the abstract model completes when the stated bound fits. -/
164theorem deflate_completes : Goal.deflate_completes := by
165  intro p x s c r s' _ ht hc hp hfin hd hbuf hflush hin hroom hbound hm
166  have hprefix : s.input <+: x := trace_input_prefix ht (by simp [DeflState.fresh])
167  have hcat : s.input ++ c.inp = x := by
168    rw [hin]
169    obtain ⟨tail, htail⟩ := hprefix
170    rw [← htail, List.drop_left]
171  have hrun : DeflRun s c r.out s' := by
172    apply hm.1.2.2.2
173    · rw [hflush]; decide
174    · exact hbuf
175    · rw [hfin]; simp
176    · omega
177  rcases hrun with ⟨hframe, _, _, _, _, _, _, _, _, hend, _, _, _, _, _, _, _, _, _, _, _, _, _, hlive⟩
178  have hr : r.out.rc = Z.streamEnd := by
179    apply hlive hflush hc hp hfin hd
180    have hlen : s.input.length + c.inp.length = x.length := by
181      have he := congrArg List.length hcat
182      simpa only [List.length_append] using he
183    simpa [hlen] using hbound
184  have hend' := hend hr
185  refine ⟨?_, hend'.2.2.1, ?_⟩
186  · exact hm.2.trans hr
187  · rw [hframe.2.2.1, hend'.2.1, List.take_length, hcat]
188
189#print axioms deflate_bound_adequate
190#print axioms deflate_completes
191end ZlibF.Spec.Api.Proofs
ZLIB × LEAN

Global contents

READING NOWDeflateBounds.lean