跳到正文
参考文档 / ZLIB × LEAN

inflate.c.main.table2.lean

此页源文件快照 · 82f1bcc904e191a0 · 对应提交的原文 ↗

本页保留 Lean 源码及行号。点击行号可定位语句,点击 import 中的模块名可查看依赖。

1import ZlibF.Proof.«inflate.c.main.table»
2
3/-!
4# inflate.c: `case LENLENS:` -- the code-length code lengths
5
6Pure part: the order of the 19 code-length code lengths, the 3-bit groups of the stream, and the array `lens` after the
7two loops (`lensRead`, `lensZero`). Mode part: the loop body, the two loops, the `inflate_table(CODES, ...)` call.
8-/
9
10namespace Zlib.Inflate.Proofs
11open C Zlib.Inflate Zlib.Inflate.Spec
12
13/-! ## The order of the code-length code lengths -/
14
15/-- `order[i]` as a number. -/
16def orderNat (i : Nat) : Nat := (order[i]!).toNat
17
18theorem order_size : order.size = 19 := rfl
19
20theorem order_lt : ∀ i, i < 19 → orderNat i < 19 := by
21  unfold orderNat order; decide +kernel
22
23theorem order_surj : ∀ k, k < 19 → ∃ i, i < 19 ∧ orderNat i = k := by
24  unfold orderNat order; decide +kernel
25
26theorem orderAt_run (h : Heap) (i : UInt32) (hi : i.toNat < 19) :
27    orderAt i h = .ok (order[i.toNat]!, h) := by
28  have hi' : i.toNat < order.size := by rw [order_size]; exact hi
29  unfold orderAt
30  rw [Array.getElem?_eq_getElem hi']
31  simp [pure_app]
32  exact (getElem!_pos order i.toNat hi').symm
33
34/-! ## The 3-bit groups of a bit stream -/
35
36/-- The number given by the first three bits of `L` (least significant first; missing bits are 0). -/
37def grp0 (L : List Bool) : Nat :=
38  (L.getD 0 false).toNat + 2 * (L.getD 1 false).toNat + 4 * (L.getD 2 false).toNat
39
40/-- The `t`-th 3-bit group of the stream `S`. -/
41def grp (S : List Bool) (t : Nat) : Nat := grp0 (S.drop (3 * t))
42
43theorem grp0_le (L : List Bool) : grp0 L ≤ 7 := by
44  unfold grp0
45  cases L.getD 0 false <;> cases L.getD 1 false <;> cases L.getD 2 false <;> decide
46
47theorem grp_le (S : List Bool) (t : Nat) : grp S t ≤ 7 := grp0_le _
48
49theorem grp0_natBits (k n : Nat) (rest : List Bool) : grp0 (natBits (3 + k) n ++ rest) = n % 8 := by
50  rw [natBits_add]
51  simp only [natBits]
52  simp [grp0]
53  have h0 := Nat.mod_two_eq_zero_or_one n
54  have h1 := Nat.mod_two_eq_zero_or_one (n / 2)
55  have h2 := Nat.mod_two_eq_zero_or_one (n / 2 / 2)
56  rcases h0 with h0 | h0 <;> rcases h1 with h1 | h1 <;> rcases h2 with h2 | h2 <;> simp [h0, h1, h2] <;> omega
57
58/-- Reading from the registers: the group is `hold % 8` once three bits are held. -/
59theorem grp_head (bits hold : Nat) (rest : List Bool) (h3 : 3 ≤ bits) : grp0 (natBits bits hold ++ rest) = hold % 8 := by
60  obtain ⟨k, rfl⟩ : ∃ k, bits = 3 + k := ⟨bits - 3, by omega⟩
61  exact grp0_natBits k hold rest
62
63theorem grp_succ (S : List Bool) (t : Nat) : grp S t = grp (S.drop (3 * t)) 0 := by
64  simp [grp]
65
66/-! ## The array `lens` after the two loops -/
67
68/-- `lens[order[i0 + u]] = grp S u` for `u < t`. -/
69def lensRead (a : Array UInt16) (i0 : Nat) (S : List Bool) : Nat → Array UInt16
70  | 0 => a
71  | t + 1 => (lensRead a i0 S t).set! (orderNat (i0 + t)) (grp S t).toUInt16
72
73/-- `lens[order[i0 + u]] = 0` for `u < t`. -/
74def lensZero (a : Array UInt16) (i0 : Nat) : Nat → Array UInt16
75  | 0 => a
76  | t + 1 => (lensZero a i0 t).set! (orderNat (i0 + t)) 0
77
78theorem lensRead_size (a : Array UInt16) (i0 : Nat) (S : List Bool) : ∀ t, (lensRead a i0 S t).size = a.size
79  | 0 => rfl
80  | t + 1 => by simp [lensRead, lensRead_size a i0 S t]
81
82theorem lensZero_size (a : Array UInt16) (i0 : Nat) : ∀ t, (lensZero a i0 t).size = a.size
83  | 0 => rfl
84  | t + 1 => by simp [lensZero, lensZero_size a i0 t]
85
86/-- The entries `lens[order[i]]`, `i < u`, are 3-bit values. -/
87def Good3 (a : Array UInt16) (u : Nat) : Prop := ∀ i, i < u → (a.getD (orderNat i) 0).toNat ≤ 7
88
89theorem Good3.set {a : Array UInt16} {u : Nat} (H : Good3 a u) (v : UInt16) (hv : v.toNat ≤ 7) (hu : u < 19) :
90    Good3 (a.set! (orderNat u) v) (u + 1) := by
91  intro i hi
92  by_cases he : orderNat i = orderNat u
93  · rw [he]
94    have hlt := order_lt u hu
95    by_cases hsz : orderNat u < a.size
96    · simp [Array.getD_eq_getD_getElem?, Array.set!_eq_setIfInBounds, Array.getElem?_setIfInBounds, hsz]; exact hv
97    · simp [Array.getD_eq_getD_getElem?, Array.set!_eq_setIfInBounds, Array.getElem?_setIfInBounds, hsz]
98  · have hne : i < u := by
99      rcases Nat.lt_succ_iff_lt_or_eq.mp hi with h | h
100      · exact h
101      · exact absurd (by rw [h]) he
102    have := H i hne
103    have he' : orderNat u ≠ orderNat i := fun e => he e.symm
104    simpa [Array.getD_eq_getD_getElem?, Array.set!_eq_setIfInBounds, Array.getElem?_setIfInBounds, he'] using this
105
106theorem lensRead_good {a : Array UInt16} {i0 : Nat} (S : List Bool) (H : Good3 a i0) :
107    ∀ t, i0 + t ≤ 19 → Good3 (lensRead a i0 S t) (i0 + t)
108  | 0, _ => H
109  | t + 1, ht => by
110    have := (lensRead_good S H t (by omega)).set (grp S t).toUInt16 (by
111      have := grp_le S t
112      simp only [Nat.toUInt16_eq, UInt16.toNat_ofNat']; omega) (by omega)
113    rwa [show i0 + (t + 1) = i0 + t + 1 by omega]
114
115theorem lensZero_good {a : Array UInt16} {i0 : Nat} (H : Good3 a i0) :
116    ∀ t, i0 + t ≤ 19 → Good3 (lensZero a i0 t) (i0 + t)
117  | 0, _ => H
118  | t + 1, ht => by
119    have := (lensZero_good H t (by omega)).set 0 (by decide) (by omega)
120    rwa [show i0 + (t + 1) = i0 + t + 1 by omega]
121
122theorem Good3.all {a : Array UInt16} (H : Good3 a 19) : ∀ k, k < 19 → (a.getD k 0).toNat ≤ 7 := by
123  intro k hk
124  obtain ⟨i, hi, he⟩ := order_surj k hk
125  rw [← he]; exact H i hi
126
127/-! ## A mode that never executes `return v` -/
128
129/-- Running `x` never ends in `return v` (`Ex.ret`); the other exits (`goto inf_leave`, a value) are allowed. -/
130def NoRet {α : Type} (x : X α) : Prop :=
131  ∀ l h r l' h', runX x l h = .ok ((r, l'), h') → ∀ v, r ≠ .error (Ex.ret v)
132
133theorem noRet_pure {α : Type} (a : α) : NoRet (pure a : X α) := by
134  intro l h r l' h' e v
135  rw [runX_pure] at e
136  cases e
137  simp
138
139theorem noRet_leave {α : Type} : NoRet (throw Ex.leave : X α) := by
140  intro l h r l' h' e v
141  rw [runX_throw] at e
142  cases e
143  simp
144
145theorem noRet_get : NoRet (get : X IL) := by
146  intro l h r l' h' e v
147  rw [runX_get] at e
148  cases e
149  simp
150
151theorem noRet_set (l0 : IL) : NoRet (set l0 : X PUnit) := by
152  intro l h r l' h' e v
153  rw [runX_set] at e
154  cases e
155  simp
156
157theorem noRet_modify (f : IL → IL) : NoRet (modify f : X PUnit) := by
158  intro l h r l' h' e v
159  rw [runX_modify] at e
160  cases e
161  simp
162
163theorem noRet_lift {α : Type} (m : M α) : NoRet (monadLift m : X α) := by
164  intro l h r l' h' e v
165  rw [runX_lift] at e
166  cases hm : m h with
167  | error f => rw [hm] at e; cases e
168  | ok p =>
169    obtain ⟨a, h1⟩ := p
170    rw [hm] at e
171    cases e
172    simp
173
174theorem noRet_bind {α β : Type} {x : X α} {f : α → X β} (hx : NoRet x) (hf : ∀ a, NoRet (f a)) : NoRet (x >>= f) := by
175  intro l h r l' h' e v
176  rw [runX_bind] at e
177  cases hr : runX x l h with
178  | error f' => rw [hr] at e; cases e
179  | ok p =>
180    obtain ⟨⟨r1, l1⟩, h1⟩ := p
181    rw [hr] at e
182    cases r1 with
183    | ok a => exact hf a l1 h1 r l' h' e v
184    | error ex =>
185      simp only at e
186      cases e
187      intro hh
188      have hex : ex = Ex.ret v := by cases hh; rfl
189      subst hex
190      exact hx l h _ l' h' hr v rfl
191
192theorem noRet_ite {α : Type} {b : Prop} [Decidable b] {x y : X α} (hx : NoRet x) (hy : NoRet y) :
193    NoRet (if b then x else y) := by
194  by_cases hb : b
195  · simpa [hb] using hx
196  · simpa [hb] using hy
197
198theorem go_inv {σ : Type} (P : σ → Prop) (F : σ → M (Bool × σ)) (B : σ → M σ)
199    (hF : ∀ s h c s' h', P s → F s h = .ok ((c, s'), h') → P s')
200    (hB : ∀ s h s' h', P s → B s h = .ok (s', h') → P s') :
201    ∀ n s h s' h', P s → cwhile.go F B n s h = .ok (s', h') → P s' := by
202  intro n
203  induction n with
204  | zero => intro s h s' h' _ e; simp [cwhile.go] at e
205  | succ n ih =>
206    intro s h s' h' hs e
207    simp only [cwhile.go, bind_app] at e
208    cases hf : F s h with
209    | error f => rw [hf] at e; cases e
210    | ok p =>
211      obtain ⟨⟨c, s1⟩, h1⟩ := p
212      rw [hf] at e
213      have hs1 := hF s h c s1 h1 hs hf
214      cases c
215      · simp only [Bool.false_eq_true, ↓reduceIte, pure_app, Except.ok.injEq, Prod.mk.injEq] at e
216        obtain ⟨rfl, _⟩ := e
217        exact hs1
218      · simp only [ite_true, bind_app] at e
219        cases hbb : B s1 h1 with
220        | error f => rw [hbb] at e; cases e
221        | ok q =>
222          obtain ⟨s2, h2⟩ := q
223          rw [hbb] at e
224          exact ih s2 h2 s' h' (hB s1 h1 s2 h2 hs1 hbb) e
225
226/-- `xwhileBrk` over a condition and a body that never `return`: the loop never `return`s. -/
227theorem noRet_xwhileBrk {cond body : X Bool} (hc : NoRet cond) (hb : NoRet body) : NoRet (xwhileBrk cond body) := by
228  intro l0 h0 r l' h' e v
229  unfold runX xwhileBrk at e
230  simp only [ExceptT.run, StateT.run, ExceptT.mk, cwhile, bind_app] at e
231  generalize hg : cwhile.go _ _ fuel (l0, Stop.go) h0 = G at e
232  cases G with
233  | error f => simp at e
234  | ok p =>
235    obtain ⟨⟨l2, s2⟩, h2⟩ := p
236    have hk : (l2, s2).2 ≠ Stop.ex (Ex.ret v) := go_inv (fun s => s.2 ≠ Stop.ex (Ex.ret v)) _ _
237      (by
238        intro s h c s' h' hs hF
239        obtain ⟨l1, st⟩ := s
240        cases st with
241        | go =>
242          simp only [bind_app] at hF
243          cases hcr : cond l1 h with
244          | error f => rw [hcr] at hF; cases hF
245          | ok p =>
246            obtain ⟨⟨rc, lc⟩, hh⟩ := p
247            have hrc := hc l1 h rc lc hh hcr v
248            rw [hcr] at hF
249            cases rc with
250            | error ex =>
251              simp only [pure_app, Except.ok.injEq, Prod.mk.injEq] at hF
252              obtain ⟨⟨_, rfl⟩, _⟩ := hF
253              intro hh2
254              simp only [Stop.ex.injEq] at hh2
255              subst hh2
256              exact hrc rfl
257            | ok b =>
258              simp only [pure_app, Except.ok.injEq, Prod.mk.injEq] at hF
259              obtain ⟨⟨_, rfl⟩, _⟩ := hF
260              simp
261        | brk =>
262          simp only [pure_app, Except.ok.injEq, Prod.mk.injEq] at hF
263          obtain ⟨⟨_, rfl⟩, _⟩ := hF
264          exact hs
265        | ex ex2 =>
266          simp only [pure_app, Except.ok.injEq, Prod.mk.injEq] at hF
267          obtain ⟨⟨_, rfl⟩, _⟩ := hF
268          exact hs)
269      (by
270        intro s h s' h' hs hB
271        obtain ⟨l1, st⟩ := s
272        simp only [bind_app] at hB
273        cases hbr : body l1 h with
274        | error f => rw [hbr] at hB; cases hB
275        | ok p =>
276          obtain ⟨⟨rb, lb⟩, hh⟩ := p
277          have hrb := hb l1 h rb lb hh hbr v
278          rw [hbr] at hB
279          cases rb with
280          | error ex =>
281            simp only [pure_app, Except.ok.injEq, Prod.mk.injEq] at hB
282            obtain ⟨rfl, _⟩ := hB
283            intro hh2
284            simp only [Stop.ex.injEq] at hh2
285            subst hh2
286            exact hrb rfl
287          | ok b =>
288            simp only [pure_app, Except.ok.injEq, Prod.mk.injEq] at hB
289            obtain ⟨rfl, _⟩ := hB
290            cases b <;> simp)
291      fuel (l0, Stop.go) h0 (l2, s2) h2 (by simp) hg
292    simp only at hk
293    cases s2 with
294    | go => simp at e; obtain ⟨⟨rfl, _⟩, _⟩ := e; simp
295    | brk => simp at e; obtain ⟨⟨rfl, _⟩, _⟩ := e; simp
296    | ex ex2 =>
297      simp at e
298      obtain ⟨⟨rfl, _⟩, _⟩ := e
299      intro hh2
300      simp only [Except.error.injEq] at hh2
301      subst hh2
302      exact hk rfl
303
304theorem noRet_xwhile {cond : X Bool} {body : X Unit} (hc : NoRet cond) (hb : NoRet body) : NoRet (xwhile cond body) :=
305  noRet_xwhileBrk hc (noRet_bind hb fun _ => noRet_pure _)
306
307theorem noRet_PULLBYTE : NoRet PULLBYTE := by
308  unfold PULLBYTE
309  refine noRet_bind noRet_get fun l => ?_
310  by_cases h0 : l.have_ == 0
311  · simp only [h0, ite_true]
312    exact noRet_leave
313  · simp only [h0, ite_false]
314    refine noRet_bind (noRet_set _) fun _ => ?_
315    refine noRet_bind (noRet_lift _) fun _ => ?_
316    refine noRet_bind (noRet_lift _) fun _ => ?_
317    refine noRet_bind (noRet_lift _) fun _ => ?_
318    exact noRet_set _
319
320/-- `NEEDBITS(n)` never executes `return v`: it ends with a value or with `goto inf_leave`. -/
321theorem noRet_NEEDBITS (n : UInt32) : NoRet (NEEDBITS n) := by
322  unfold NEEDBITS
323  refine noRet_xwhile (noRet_bind noRet_get fun _ => noRet_pure _) noRet_PULLBYTE
324
325end Zlib.Inflate.Proofs
ZLIB × LEAN

全局目录

当前位置inflate.c.main.table2.lean