参考文档 / ZLIB × LEAN
trees.c.heap.gbtop.lean
此页源文件快照 ·
00cf5a0de180d172 · 对应提交的原文 ↗本页保留 Lean 源码及行号。点击行号可定位语句,点击 import 中的模块名可查看依赖。
1import ZlibF.Proof.«trees.c.heap.gbre»
2import ZlibF.Proof.«trees.c.heap.gbsym»
3
4/-!
5# trees.c: `gen_bitlen` (safe and correct)
6
7The proof chains the loops: `bl_count` zeroing, the root `Len := 0`, the first pass (`ws_gbPass1`), and, when the
8clamped depths overflowed, the repair (`ws_gbFixLoop`) and the reassignment (`ws_gbOuter`).
9-/
10
11namespace Zlib.Trees.Proofs
12open C Zlib.Trees Zlib.Trees.Proofs.GB
13
14theorem mk_eq (tk : TK) (d : DeflateState) (B0 : Array UInt16) (A : Array CtData) :
15 tk.setArr { d with bl_count := B0 } A = mkP1 tk d A B0 d.opt_len d.static_len := by cases tk <;> rfl
16
17/-- The state after the zeroing of `bl_count` and the root `Len := 0` is the start of the first pass. -/
18theorem p1_init {h0 : Heap} {id : Nat} {tk : TK} {d : DeflateState} {stree : CtDataPtr} {extra : IPtr}
19 {mc base ml : Int32} {hm J elems maxc L baseN : Nat} {xb : Nat → Nat} {slOpt : Option (Nat → Nat)}
20 (ctx : P1Ctx h0 id tk d stree extra mc base ml hm J elems maxc L baseN xb slOpt) (B0 : Array UInt16)
21 (hB0s : B0.size = 16) (hB0z : ∀ i, i < 16 → B0[i]! = 0) :
22 P1State tk d hm J elems maxc L xb slOpt 0
23 (mkP1 tk d (setLen (tk.arr d) (Hn d hm) 0) B0 d.opt_len d.static_len) := by
24 have PS := ctx.shape
25 have hm_eq := PS.hm_eq
26 have hC : Clamped (Hn d) hm J elems L (clK (Hn d) hm elems L (2 * J)) := clK_clamped PS
27 have hnT : Hn d hm < (tk.arr d).size := by
28 rcases PS.kind hm (Nat.le_refl _) (by omega) with h1 | h1
29 · have := PS.maxc_lt; have := ctx.nc; omega
30 · have := ctx.nc; omega
31 have hget : ∀ v, (setLen (tk.arr d) (Hn d hm) 0)[v]! =
32 if v = Hn d hm then { (tk.arr d)[Hn d hm]! with dl := UInt16.ofNat 0 } else (tk.arr d)[v]! := fun v => by
33 unfold setLen; exact getD_set _ _ v _ hnT
34 refine ⟨setLen (tk.arr d) (Hn d hm) 0, B0, d.opt_len, d.static_len, rfl, ?_, ?_, ?_, hB0s, ?_, ?_, ?_, ?_, ?_⟩
35 · show d.opt_len = d.opt_len + UInt64.ofNat 0
36 rw [show UInt64.ofNat 0 = 0 from rfl, UInt64.add_zero]
37 · cases slOpt with
38 | none => rfl
39 | some sl => show d.static_len = d.static_len + UInt64.ofNat 0; rw [show UInt64.ofNat 0 = 0 from rfl, UInt64.add_zero]
40 · unfold setLen; rw [size_set!]
41 · intro q h1 h2
42 have : q = hm := by omega
43 subst this
44 rw [hget, ite_eq_left rfl, hC.root]
45 · intro i _ hi
46 rw [hget, ite_eq_right]
47 · exact ctx.dad i hi
48 · intro e; have := PS.inj (hm + 1 + i) hm (by omega) (by omega) (Nat.le_refl _) (by omega) e; omega
49 · intro v; rw [hget]; split
50 · rename_i e; subst e; rfl
51 · rfl
52 · intro v hv; rw [hget, ite_eq_right]
53 intro e; exact hv hm (Nat.le_refl _) (by omega) e.symm
54 · intro b hb; rw [hB0z b hb]; show (0 : UInt16) = UInt16.ofNat 0; rfl
55
56
57/-- What `gen_bitlen` establishes: the tree array `Tf` holds the lengths, `Bf` the counts. -/
58def GBDone (tk : TK) (d : DeflateState) (hm J maxc L : Nat) (xb : Nat → Nat) (slOpt : Option (Nat → Nat))
59 (e : DeflateState) : Prop :=
60 ∃ (Tf : Array CtData) (Bf : Array UInt16) (O S : UInt64), e = mkP1 tk d Tf Bf O S ∧ Tf.size = (tk.arr d).size ∧
61 Bf.size = 16 ∧ (∀ v : Nat, (Tf[v]!).fc = ((tk.arr d)[v]!).fc) ∧
62 (∀ v : Nat, (∀ q, hm ≤ q → q < 573 → Hn d q ≠ v) → (Tf[v]!).dl = ((tk.arr d)[v]!).dl) ∧
63 (∀ i, i < 2 * J → Hn d (hm + 1 + i) ≤ maxc →
64 1 ≤ curL Tf (Hn d (hm + 1 + i)) ∧ curL Tf (Hn d (hm + 1 + i)) ≤ L) ∧
65 rs (fun i => if Hn d (hm + 1 + i) ≤ maxc then 2 ^ (L - curL Tf (Hn d (hm + 1 + i))) else 0) (2 * J) = 2 ^ L ∧
66 (∀ b, b < 16 → Bf[b]! = UInt16.ofNat (if b = 0 then 0 else blP (Hn d) hm maxc (curL Tf) (2 * J) b)) ∧
67 O = d.opt_len + UInt64.ofNat (costP (Hn d) hm maxc (frn (tk.arr d)) (curL Tf) xb (2 * J)) ∧
68 S = addOpt d.static_len (slOpt.map fun sl => costP (Hn d) hm maxc (frn (tk.arr d)) sl xb (2 * J))
69
70/-- No overflow: the clamped depths are the lengths. -/
71theorem done_noovf {tk : TK} {d : DeflateState} {hm J elems maxc L : Nat} {xb : Nat → Nat}
72 {slOpt : Option (Nat → Nat)} {e : DeflateState} (PS : PShape (Hn d) hm J elems maxc) (hL1 : 1 ≤ L) (hL15 : L ≤ 15)
73 (hov : ovP (Hn d) hm elems L (clK (Hn d) hm elems L (2 * J)) (2 * J) = 0)
74 (hP : P1State tk d hm J elems maxc L xb slOpt (2 * J) e) : GBDone tk d hm J maxc L xb slOpt e := by
75 have hm_eq := PS.hm_eq
76 have hC : Clamped (Hn d) hm J elems L (clK (Hn d) hm elems L (2 * J)) := clK_clamped PS
77 obtain ⟨Tk, Bk, O, S, he, hO, hS, hTs, hBs, hcl, hdad, hfc, hout, hbl⟩ := hP
78 have hcur : ∀ i, i < 2 * J → curL Tk (Hn d (hm + 1 + i)) = clK (Hn d) hm elems L (2 * J) (Hn d (hm + 1 + i)) := by
79 intro i hi
80 unfold curL
81 rw [hcl (hm + 1 + i) (by omega) (by omega), UInt16.toNat_ofNat']
82 have := hC.le_all PS (hm + 1 + i) (by omega) (by omega)
83 omega
84 have hcl1 : ∀ i, i < 2 * J → 1 ≤ clK (Hn d) hm elems L (2 * J) (Hn d (hm + 1 + i)) := by
85 intro i hi
86 rw [hC.step i hi]
87 have := hC.dad_le PS i hi
88 omega
89 have hkr := kraft_clamped PS hC hL1
90 have hovC : ovfC (Hn d) hm J elems L (clK (Hn d) hm elems L (2 * J)) = 0 := hov
91 refine ⟨Tk, Bk, O, S, he, hTs, hBs, hfc, hout, fun i hi _ => ?_, ?_, fun b hb => ?_, ?_, hS⟩
92 · rw [hcur i hi]; exact ⟨hcl1 i hi, (hC.le_all PS (hm + 1 + i) (by omega) (by omega))⟩
93 · unfold kraftC at hkr
94 rw [hovC, Nat.pow_succ] at hkr
95 rw [← show (2 : Nat) ^ L = 2 ^ L from rfl]
96 have : rs (fun i => if Hn d (hm + 1 + i) ≤ maxc then 2 ^ (L - curL Tk (Hn d (hm + 1 + i))) else 0) (2 * J) =
97 rs (fun i => if Hn d (hm + 1 + i) ≤ maxc then 2 ^ (L - clK (Hn d) hm elems L (2 * J) (Hn d (hm + 1 + i))) else 0) (2 * J) :=
98 rs_congr (fun i hi => by rw [hcur i hi])
99 rw [this]; omega
100 · rw [hbl b hb]
101 by_cases e0 : b = 0
102 · subst e0; rw [ite_eq_left rfl]
103 have := blC_zero PS hC hL1
104 unfold blC at this
105 rw [show blP (Hn d) hm maxc (clK (Hn d) hm elems L (2 * J)) (2 * J) 0 = 0 from this]
106 · rw [ite_eq_right e0]
107 have e1 : blP (Hn d) hm maxc (clK (Hn d) hm elems L (2 * J)) (2 * J) b = blP (Hn d) hm maxc (curL Tk) (2 * J) b := by
108 unfold blP; apply rs_congr; intro i hi; rw [hcur i hi]
109 rw [e1]
110 · rw [hO]
111 have e1 : costP (Hn d) hm maxc (frn (tk.arr d)) (clK (Hn d) hm elems L (2 * J)) xb (2 * J) =
112 costP (Hn d) hm maxc (frn (tk.arr d)) (curL Tk) xb (2 * J) := by
113 unfold costP; apply rs_congr; intro i hi; rw [hcur i hi]
114 rw [e1]
115
116
117theorem mkP2_mkP1 (tk : TK) (d Tk Bk O S Tc O') : mkP2 tk (mkP1 tk d Tk Bk O S) Tc O' = mkP1 tk d Tc Bk O' S := by
118 cases tk <;> rfl
119
120@[simp] theorem Hn_mkP1 (tk : TK) (d Tk Bk O S) : Hn (mkP1 tk d Tk Bk O S) = Hn d := by
121 funext q; unfold Hn; rw [mkP1_heap]
122
123/-- The facts about the state `ef` after the repair that the reassignment needs. -/
124theorem rctx_of {tk : TK} {d e2 ef : DeflateState} {hm J elems maxc L : Nat} {c' : Nat → Nat} {ov : Int32} {Tk Bk O S}
125 (he2 : e2 = mkP1 tk d Tk Bk O S) (hTs : Tk.size = (tk.arr d).size)
126 (PS : PShape (Hn d) hm J elems maxc) (hsz : d.heap.size = 573) (hnn : ∀ q, hm ≤ q → q < 573 → 0 ≤ (d.heap[q]!).toInt)
127 (hnc : elems + J ≤ (tk.arr d).size) (htsz : (tk.arr d).size ≤ 600) (hL1 : 1 ≤ L) (hL15 : L ≤ 15)
128 (hfix : FixInvX L (nLeaves (Hn d) hm J maxc) 0 ov c' e2 ef) :
129 RCtx tk ef hm J elems maxc L c' := by
130 obtain ⟨-, -, hc0, -, -, -, htot, Bc, hef⟩ := hfix
131 have hef' : ef = mkP1 tk d Tk Bc O S := by rw [hef, he2, bl_mkP1]
132 have hh : ef.heap = d.heap := by rw [hef', mkP1_heap]
133 have hHn : Hn ef = Hn d := by rw [hef', Hn_mkP1]
134 refine ⟨by rw [hh]; exact hsz, fun q h1 h2 => by rw [hh]; exact hnn q h1 h2, by rw [hHn]; exact PS, ?_, ?_, hL1, hL15, hc0, by rw [hHn]; exact htot⟩
135 · rw [hef', tk_arr_mkP1, hTs]; exact hnc
136 · rw [hef', tk_arr_mkP1, hTs]; exact htsz
137
138
139theorem curL_clK {tk : TK} {d : DeflateState} {hm J elems maxc L : Nat} (PS : PShape (Hn d) hm J elems maxc)
140 {Tk : Array CtData} (hL15 : L ≤ 15)
141 (hcl : ∀ q, hm ≤ q → q ≤ hm + 2 * J → (Tk[Hn d q]!).dl = UInt16.ofNat (clK (Hn d) hm elems L (2 * J) (Hn d q))) :
142 ∀ i, i < 2 * J → curL Tk (Hn d (hm + 1 + i)) = clK (Hn d) hm elems L (2 * J) (Hn d (hm + 1 + i)) := by
143 have hm_eq := PS.hm_eq
144 have hC : Clamped (Hn d) hm J elems L (clK (Hn d) hm elems L (2 * J)) := clK_clamped PS
145 intro i hi
146 unfold curL
147 rw [hcl (hm + 1 + i) (by omega) (by omega), UInt16.toNat_ofNat']
148 have := hC.le_all PS (hm + 1 + i) (by omega) (by omega)
149 omega
150
151
152theorem reinit {tk : TK} {d e2 ef : DeflateState} {hm J elems maxc L : Nat} {xb : Nat → Nat}
153 {slOpt : Option (Nat → Nat)} {c' : Nat → Nat} {ov : Int32}
154 (PS : PShape (Hn d) hm J elems maxc) (hL15 : L ≤ 15) (hsz : d.heap.size = 573)
155 (hP : P1State tk d hm J elems maxc L xb slOpt (2 * J) e2)
156 (hfix : FixInvX L (nLeaves (Hn d) hm J maxc) 0 ov c' e2 ef) :
157 ReSt tk ef hm J maxc L xb c' d.opt_len 573 L (c' L) ef := by
158 have hm_eq := PS.hm_eq
159 obtain ⟨Tk, Bk, O, S, he2, hO, hS, hTs, hBs, hcl, hdad, hfc, hout, hbl⟩ := hP
160 obtain ⟨-, -, hc0, -, -, -, htot, Bc, hef⟩ := hfix
161 have hef' : ef = mkP1 tk d Tk Bc O S := by rw [hef, he2, bl_mkP1]
162 have hcur := curL_clK (tk := tk) (elems := elems) (L := L) PS hL15 (fun q h1 h2 => hcl q h1 (by omega))
163 have hfr : frn Tk = frn (tk.arr d) := by funext v; unfold frn; rw [hfc v]
164 refine ⟨tk.arr ef, ef.opt_len, by cases tk <;> rfl, rfl, by omega, Nat.le_refl _, Nat.le_refl _, ?_, fun v => rfl,
165 fun v hv => rfl, fun x => ?_, ?_⟩
166 · rw [hef', tk_arr_mkP1, Hn_mkP1]
167 show O = _
168 rw [hO, hfr]
169 congr 2
170 unfold costP; apply rs_congr; intro i hi; rw [hcur i hi]
171 · have h0 : scnt (Hn ef) hm maxc J 573 (curL (tk.arr ef)) x = 0 := by
172 unfold scnt; exact rs_eq_zero (fun i hi => by rw [ite_eq_right (fun h => by omega)])
173 rw [h0]
174 by_cases e1 : L < x ∧ x ≤ L
175 · omega
176 · rw [ite_eq_right e1]; by_cases e2 : x = L
177 · rw [ite_eq_left e2, Nat.sub_self]
178 · rw [ite_eq_right e2]
179 · have h0 : stot (Hn ef) hm maxc J 573 = 0 := by
180 unfold stot; exact rs_eq_zero (fun i hi => by rw [ite_eq_right (fun h => by omega)])
181 rw [h0, Nat.sub_self]
182 unfold Aab
183 rw [rs_eq_zero (fun x hx => by rw [ite_eq_right (by omega)])]
184
185
186/-- Overflow: the lengths after the reassignment. -/
187theorem done_ovf {tk : TK} {d e2 ef efin : DeflateState} {hm J elems maxc L : Nat} {xb : Nat → Nat}
188 {slOpt : Option (Nat → Nat)} {c' : Nat → Nat} {ov : Int32} {hc : Nat}
189 (PS : PShape (Hn d) hm J elems maxc) (hL1 : 1 ≤ L) (hL15 : L ≤ 15)
190 (hP : P1State tk d hm J elems maxc L xb slOpt (2 * J) e2)
191 (hfix : FixInvX L (nLeaves (Hn d) hm J maxc) 0 ov c' e2 ef)
192 (hre : ReSt tk ef hm J maxc L xb c' d.opt_len hc 0 0 efin) : GBDone tk d hm J maxc L xb slOpt efin := by
193 have hm_eq := PS.hm_eq
194 obtain ⟨Tk, Bk, O, S, he2, hO, hS, hTs, hBs, hcl, hdad, hfc, hout, hbl⟩ := hP
195 obtain ⟨hfv, hBcI, hc0, hchi, hkc, -, htot, Bc, hef⟩ := hfix
196 have hef' : ef = mkP1 tk d Tk Bc O S := by rw [hef, he2, bl_mkP1]
197 obtain ⟨Tc, O2, hefin, hTcs, hc1, hc2, -, hO2, hfcc, houtc, hsc, hst⟩ := hre
198 have hefin' : efin = mkP1 tk d Tc Bc O2 S := by rw [hefin, hef', mkP2_mkP1]
199 have hHn : Hn ef = Hn d := by rw [hef', Hn_mkP1]
200 have hTarr : tk.arr ef = Tk := by rw [hef', tk_arr_mkP1]
201 have hfr : frn Tk = frn (tk.arr d) := by funext v; unfold frn; rw [hfc v]
202 rw [hHn] at hsc hst hO2
203 rw [hTarr, hfr] at hO2
204 rw [hTarr] at hTcs
205 have hmL : ∀ i, i < 2 * J → Hn d (hm + 1 + i) ≤ maxc → hc ≤ hm + 1 + i := by
206 intro i hi hl
207 by_cases h : hc ≤ hm + 1 + i
208 · exact h
209 · exfalso
210 have h1 := stot_utot (Hn d) hm maxc J hc
211 rw [hst] at h1
212 simp only [Nat.sub_zero] at h1
213 have h2 : Aab c' L 0 = rs c' (L + 1) := Aab_zero c' L hc0
214 have h3 : 1 ≤ utot (Hn d) hm maxc J hc := by
215 have := le_rs (F := fun j => if hm + 1 + j < hc ∧ Hn d (hm + 1 + j) ≤ maxc then 1 else 0) (n := 2 * J) (i := i) hi
216 unfold utot
217 rw [ite_eq_left ⟨by omega, hl⟩] at this
218 exact this
219 omega
220 have hcnt : ∀ x, blP (Hn d) hm maxc (curL Tc) (2 * J) x = if 0 < x ∧ x ≤ L then c' x else 0 := by
221 intro x
222 have h := hsc x
223 have e1 : scnt (Hn d) hm maxc J hc (curL Tc) x = blP (Hn d) hm maxc (curL Tc) (2 * J) x := by
224 unfold scnt blP; apply rs_congr; intro i hi
225 by_cases hl : Hn d (hm + 1 + i) ≤ maxc
226 · by_cases hx : curL Tc (Hn d (hm + 1 + i)) = x
227 · simp [hl, hx, hmL i hi hl]
228 · simp [hx]
229 · rw [ite_eq_right (fun h => hl h.2.1), ite_eq_right (fun h => hl h.1)]
230 rw [← e1, h]
231 by_cases e : 0 < x ∧ x ≤ L
232 · simp [e]
233 · by_cases e0 : x = 0
234 · subst e0; simp [hc0]
235 · have e' : ¬ (0 < x ∧ x ≤ L) := e
236 simp [e', e0]
237 have hrange : ∀ i, i < 2 * J → Hn d (hm + 1 + i) ≤ maxc →
238 1 ≤ curL Tc (Hn d (hm + 1 + i)) ∧ curL Tc (Hn d (hm + 1 + i)) ≤ L := by
239 intro i hi hl
240 have h1 := hcnt (curL Tc (Hn d (hm + 1 + i)))
241 have h2 : 1 ≤ blP (Hn d) hm maxc (curL Tc) (2 * J) (curL Tc (Hn d (hm + 1 + i))) := by
242 have := le_rs (F := fun j => if Hn d (hm + 1 + j) ≤ maxc ∧ curL Tc (Hn d (hm + 1 + j)) = curL Tc (Hn d (hm + 1 + i)) then 1 else 0)
243 (n := 2 * J) (i := i) hi
244 unfold blP
245 rw [ite_eq_left ⟨hl, rfl⟩] at this
246 exact this
247 by_cases e : 0 < curL Tc (Hn d (hm + 1 + i)) ∧ curL Tc (Hn d (hm + 1 + i)) ≤ L
248 · exact ⟨e.1, e.2⟩
249 · rw [ite_eq_right e] at h1; omega
250 have hBcs : Bc.size = 16 := by have := hBcI.1; rw [hef', mkP1_bl_count] at this; exact this
251 have hBcv : ∀ b, b < 16 → Bc[b]! = UInt16.ofNat (c' b) := by
252 intro b hb; have := hBcI.2 b hb; rw [hef', mkP1_bl_count] at this; exact this
253 refine ⟨Tc, Bc, O2, S, hefin', by rw [hTcs, hTs], hBcs, ?_, ?_, hrange, ?_, fun b hb => ?_, ?_, hS⟩
254 · intro v; rw [hfcc v, hTarr]; exact hfc v
255 · intro v hv; rw [houtc v (fun q h1 h2 => by rw [hHn]; exact hv q h1 h2), hTarr]; exact hout v hv
256 · exact kraft_of_counts (Hn d) hm J maxc L (curL Tc) c' hc0 (by rw [hkc]; rfl) (fun i hi hl => (hrange i hi hl).2) hcnt
257 · rw [hBcv b hb]
258 by_cases e0 : b = 0
259 · subst e0; rw [ite_eq_left rfl, hc0]
260 · rw [ite_eq_right e0, hcnt b]
261 by_cases e : 0 < b ∧ b ≤ L
262 · rw [ite_eq_left e]
263 · rw [ite_eq_right e, hchi b (by omega)]
264 · rw [hO2]
265
266
267@[simp] theorem mkP1_heap_max (tk : TK) (d Tk Bk O S) : (mkP1 tk d Tk Bk O S).heap_max = d.heap_max := by cases tk <;> rfl
268
269theorem ws_ldTreeDesc {h0 : Heap} {id : Nat} {d : DeflateState} (r : TreeDescRef) (dd : TreeDesc)
270 (h : r.get (setD h0 id d) = some dd) : WS h0 id (ldTreeDesc (some r)) d (fun v d' => v = dd ∧ d' = d) :=
271 WS.of_eq (ldTreeDesc_ok h) ⟨rfl, rfl⟩
272
273theorem ws_ldStaticTreeDesc {h0 : Heap} {id : Nat} {d : DeflateState} (sref : StaticTreeDescRef) (sd : StaticTreeDesc)
274 (h : StaticTreeDescRef.get h0 sref = some sd) :
275 WS h0 id (ldStaticTreeDesc (some sref)) d (fun v d' => v = sd ∧ d' = d) :=
276 WS.of_eq (ldStaticTreeDesc_ok (by cases sref <;> simpa [StaticTreeDescRef.get, setD] using h)) ⟨rfl, rfl⟩
277
278/-- **`gen_bitlen`.** -/
279theorem ws_gen_bitlen {h0 : Heap} {id : Nat} {tk : TK} {d : DeflateState} {r : TreeDescRef} {sref : StaticTreeDescRef}
280 {dd : TreeDesc} {sd : StaticTreeDesc} {hm J elems maxc L baseN : Nat} {xb : Nat → Nat}
281 {slOpt : Option (Nat → Nat)}
282 (hdd : r.get (setD h0 id d) = some dd) (hsd : StaticTreeDescRef.get h0 sref = some sd)
283 (hstat : dd.stat_desc = some sref) (htree : dd.dyn_tree = Ptr.ref (tk.ref id) 0)
284 (ctx : P1Ctx h0 id tk d sd.static_tree sd.extra_bits dd.max_code sd.extra_base sd.max_length hm J elems maxc L baseN
285 xb slOpt)
286 (hHM : d.heap_max.toInt = hm) (hel : elems ≤ 2 ^ L) :
287 WS h0 id (gen_bitlen (Sp id) (some r)) d (fun _ d' => GBDone tk d hm J maxc L xb slOpt d') := by
288 have PS := ctx.shape
289 have hm_eq := PS.hm_eq
290 rw [gen_bitlen_eq]
291 unfold gbTop
292 simp only []
293 refine WS.bind' (ws_ldTreeDesc r dd hdd) fun dd' e1 ⟨hdd', he1⟩ => ?_
294 subst e1; subst dd'
295 rw [hstat]
296 refine WS.bind' (ws_ldStaticTreeDesc sref sd hsd) fun sd' e1 ⟨hsd', he1⟩ => ?_
297 subst e1; subst sd'
298 rw [htree]
299 refine WS.bind' (ws_gbZero d ctx.bsz) fun _ e1 ⟨B0, he1, hB0s, hB0z⟩ => ?_
300 subst e1
301 have hhsz := ctx.hsz
302 have hnn0 := ctx.hnn hm (Nat.le_refl _) (by omega)
303 have hnT : Hn d hm < (tk.arr d).size := by
304 rcases PS.kind hm (Nat.le_refl _) (by omega) with h1 | h1
305 · have := PS.maxc_lt; have := ctx.nc; omega
306 · have := ctx.nc; omega
307 have h1i : (1 : Int32).toInt = 1 := rfl
308 refine WS.bind' ws_rd fun dz e1 ⟨hz, he1⟩ => ?_
309 subst e1; subst hz
310 refine WS.bind' (ws_heapAt d.heap_max (by omega) (by show _ < (d.heap.size : Int); omega)) fun r0 e1 ⟨hr0, he1⟩ => ?_
311 subst e1
312 have hr0n : r0.toInt = (Hn d hm : Int) := by
313 rw [hr0]; show (d.heap[d.heap_max.toInt.toNat]!).toInt = _
314 have : d.heap_max.toInt.toNat = hm := by omega
315 rw [this]; unfold Hn; omega
316 refine WS.bind' (ws_setDl tk r0.toInt 0 (by omega) (by rw [tk_arr_bl_count]; omega)) fun _ e1 he1 => ?_
317 have hr0nat : r0.toInt.toNat = Hn d hm := by omega
318 rw [tk_arr_bl_count, hr0nat] at he1
319 change e1 = tk.setArr { d with bl_count := B0 } (setLen (tk.arr d) (Hn d hm) 0) at he1
320 rw [mk_eq] at he1
321 subst e1
322 refine WS.bind' ws_rd fun dz e1 ⟨hz, he1⟩ => ?_
323 subst e1; subst hz
324 refine WS.bind' (ws_iadd _ 1 (by simp only [mkP1_heap_max]; omega) (by simp only [mkP1_heap_max]; omega))
325 fun h0v e1 ⟨hh0, he1⟩ => ?_
326 subst e1
327 simp only [mkP1_heap_max] at hh0
328 have hp1 := ws_gbPass1 ctx h0v (by omega) _ (p1_init ctx B0 hB0s hB0z)
329 refine WS.bind' hp1 fun x e2 ⟨hx1, hx2, hP⟩ => ?_
330 have hC : Clamped (Hn d) hm J elems L (clK (Hn d) hm elems L (2 * J)) := clK_clamped PS
331 have hL1 := ctx.L1
332 have hL15 := ctx.L15
333 have hmlv := ctx.mlv
334 by_cases hov : ovP (Hn d) hm elems L (clK (Hn d) hm elems L (2 * J)) (2 * J) = 0
335 · refine WS.ite' (fun _ => ?_) (fun hh => absurd (by
336 have : x.snd.toInt = 0 := by rw [hx2, hov]; rfl
337 have : x.snd = 0 := Int32.toInt_inj.mp (by rw [this]; rfl)
338 simp [this]) hh)
339 exact WS.pure' (done_noovf PS hL1 hL15 hov hP)
340 · refine WS.ite' (fun hh => absurd ?_ hov) (fun _ => ?_)
341 · have : x.snd = 0 := by simpa using hh
342 have h1 : x.snd.toInt = 0 := by rw [this]; rfl
343 rw [hx2] at h1; omega
344 · -- overflow: repair, then reassign
345 have hovpos : 0 < ovP (Hn d) hm elems L (clK (Hn d) hm elems L (2 * J)) (2 * J) := Nat.pos_of_ne_zero hov
346 have hovE := blC_top PS hC hL1
347 have hkr := kraft_clamped PS hC hL1
348 have hex := exactC_pos PS hC hL1 hovpos
349 obtain ⟨R, hR⟩ : ∃ R, ovfC (Hn d) hm J elems L (clK (Hn d) hm elems L (2 * J)) = 2 * (R + 1) :=
350 ⟨ovfC (Hn d) hm J elems L (clK (Hn d) hm elems L (2 * J)) / 2 - 1, by
351 have := hovE.1; have : 0 < ovfC (Hn d) hm J elems L (clK (Hn d) hm elems L (2 * J)) := hovpos
352 omega⟩
353 have hNL := nLeaves_le PS
354 have hmc := PS.maxc_lt
355 have hnc := ctx.nc
356 have htsz := ctx.tsz
357 obtain ⟨Tk, Bk, O, S, he2, hO, hS, hTs, hBs, hcl, hdad, hfc, hout, hbl⟩ := hP
358 have hP' : P1State tk d hm J elems maxc L xb slOpt (2 * J) e2 :=
359 ⟨Tk, Bk, O, S, he2, hO, hS, hTs, hBs, hcl, hdad, hfc, hout, hbl⟩
360 let c0 : Nat → Nat := fun b => blC (Hn d) hm J maxc (clK (Hn d) hm elems L (2 * J)) b
361 have hI : FixInvX L (nLeaves (Hn d) hm J maxc) (R + 1) x.snd c0 e2 e2 := by
362 refine ⟨by rw [hx2]; show ((ovfC (Hn d) hm J elems L (clK (Hn d) hm elems L (2 * J)) : Nat) : Int) = _; rw [hR]; omega, ?_, blC_zero PS hC hL1, fun b hb => blC_high PS hC b hb, ?_, ?_, blC_total PS hC, e2.bl_count, rfl⟩
363 · rw [he2]; simp only [BcIs, mkP1_bl_count]
364 exact ⟨hBs, fun b hb => (hbl b hb).trans rfl⟩
365 · show kc c0 L = _
366 unfold kc
367 have := kraftC_eq PS hC
368 rw [← this]
369 unfold kraftC at hkr ⊢
370 have hp : ovfC (Hn d) hm J elems L (clK (Hn d) hm elems L (2 * J)) = 2 * (R + 1) := hR
371 rw [Nat.pow_succ] at hkr
372 omega
373 · have := hovE.2
374 show R + 1 + 1 ≤ blC (Hn d) hm J maxc (clK (Hn d) hm elems L (2 * J)) L
375 omega
376 have hNLa : nLeaves (Hn d) hm J maxc ≤ 2 ^ L := by omega
377 have hNLb : nLeaves (Hn d) hm J maxc ≤ 1000 := by omega
378 refine WS.bind' (ws_gbFixLoop (h0 := h0) (id := id) e2 sd.max_length L (nLeaves (Hn d) hm J maxc) R hmlv hL1 hL15
379 hNLa hNLb x.snd c0 e2 hI) fun ov' ef hfix => ?_
380 have rctx := rctx_of he2 hTs PS ctx.hsz ctx.hnn ctx.nc ctx.tsz hL1 hL15 hfix
381 have hR0 := reinit PS hL15 ctx.hsz hP' hfix
382 refine WS.bind' (ws_gbOuter rctx hfix.2.1 dd.max_code sd.max_length ctx.mcv hmlv x.fst hx1 ef hR0)
383 fun r efin ⟨hc, hre⟩ => ?_
384 exact WS.pure' (done_ovf PS hL1 hL15 hP' hfix hre)
385
386
387/-- **`gen_bitlen`: correct.** On the heap `h` with the deflate state `id` (the record `d`), called on the tree
388descriptor `r` (one of `l_desc`, `d_desc`, `bl_desc` of the same state) whose `dyn_tree` is the tree array `tk` of
389that state, `max_code = maxc`, and whose static descriptor `sd` has `elems`, `max_length = L`, `extra_base = baseN`:
390
391* the tree is laid out as `build_tree` leaves it (`P1Ctx.shape`: `J ≥ 1` internal nodes `elems .. elems+J-1`, the root
392 at `heap[heap_max]`, `heap_max = hm`, the node `elems + j` stored below its children at `572 - 2j`, `571 - 2j`, the other
393 entries symbols `≤ maxc < elems`, all distinct) and the `Dad` of each non-root node is `dadP elems position`;
394* `1 ≤ L ≤ 15` (`bl_count` has 16 entries), `elems ≤ 2^L` (so a node can always be found below the limit: F8), the tree
395 array has `elems + J ≤ size ≤ 600` entries, the heap array has 573, `bl_count` 16;
396* the extra bits (`xb`) and the static lengths (`slOpt`, none when `static_tree` is null) are read from static arrays
397 that are large enough for the symbols `≤ maxc`.
398
399The call runs to the end without a fault, only the tree array, `bl_count`, `opt_len` and `static_len` change, and
400(`GBDone`) the leaves get lengths in `[1, L]` forming a complete prefix code (`Σ 2^(L - len) = 2^L`), `bl_count[b]` is the number
401of leaves of length `b` (`bl_count[0] = 0`), and `opt_len`, `static_len` grow by `Σ freq * (len + extra bits)`, resp. the same with
402the static lengths (modulo `2^64`). -/
403theorem gen_bitlen_correct {h : Heap} {id : Nat} {d : DeflateState} (hd : h.dstates id = some d) {tk : TK}
404 {r : TreeDescRef} {sref : StaticTreeDescRef} {dd : TreeDesc} {sd : StaticTreeDesc}
405 {hm J elems maxc L baseN : Nat} {xb : Nat → Nat} {slOpt : Option (Nat → Nat)}
406 (hdd : r.get h = some dd) (hsd : StaticTreeDescRef.get h sref = some sd)
407 (hstat : dd.stat_desc = some sref) (htree : dd.dyn_tree = Ptr.ref (tk.ref id) 0)
408 (ctx : P1Ctx h id tk d sd.static_tree sd.extra_bits dd.max_code sd.extra_base sd.max_length hm J elems maxc L baseN
409 xb slOpt)
410 (hHM : d.heap_max.toInt = hm) (hel : elems ≤ 2 ^ L) :
411 ∃ d', gen_bitlen (Sp id) (some r) h = .ok ((), setD h id d') ∧ GBDone tk d hm J maxc L xb slOpt d' := by
412 have hdd' : r.get (setD h id d) = some dd := by rw [setD_self hd]; exact hdd
413 obtain ⟨_, d', e, hq⟩ := ws_gen_bitlen (h0 := h) hdd' hsd hstat htree ctx hHM hel
414 rw [setD_self hd] at e
415 exact ⟨d', e, hq⟩
416
417/-- **`gen_bitlen` does not fault.** Same preconditions as `gen_bitlen_correct` (they are what `build_tree` establishes
418before the call): the call returns normally, every index into `heap`, `bl_count` and the tree is inside its array
419(including the search `while (bl_count[bits] == 0) bits--`, which stays at `bits ≥ 1`, and the scan `heap[--h]`, which
420stays above the root). -/
421theorem gen_bitlen_safe {h : Heap} {id : Nat} {d : DeflateState} (hd : h.dstates id = some d) {tk : TK}
422 {r : TreeDescRef} {sref : StaticTreeDescRef} {dd : TreeDesc} {sd : StaticTreeDesc}
423 {hm J elems maxc L baseN : Nat} {xb : Nat → Nat} {slOpt : Option (Nat → Nat)}
424 (hdd : r.get h = some dd) (hsd : StaticTreeDescRef.get h sref = some sd)
425 (hstat : dd.stat_desc = some sref) (htree : dd.dyn_tree = Ptr.ref (tk.ref id) 0)
426 (ctx : P1Ctx h id tk d sd.static_tree sd.extra_bits dd.max_code sd.extra_base sd.max_length hm J elems maxc L baseN
427 xb slOpt)
428 (hHM : d.heap_max.toInt = hm) (hel : elems ≤ 2 ^ L) :
429 ∃ h', gen_bitlen (Sp id) (some r) h = .ok ((), h') := by
430 obtain ⟨d', e, -⟩ := gen_bitlen_correct hd hdd hsd hstat htree ctx hHM hel
431 exact ⟨_, e⟩
432
433end Zlib.Trees.Proofs