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

trees.c.build.scan.lean

此页源文件快照 · 4d95b785d5e3ade3 · 对应提交的原文 ↗

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

1import ZlibF.Math.DeflateTreeScan
2import ZlibF.Proof.«trees.c.monad»
3import ZlibF.Proof.«trees.c.heap.gbdef»
4
5/-! # trees.c: the first `build_tree` scan -/
6
7namespace Zlib.Trees.Proofs
8open C Zlib.Trees
9
10/-- The first scan's body, in the actual source order. -/
11def btScanBody (s : DeflateStatePtr) (tree : CtDataPtr) : Int32 × Int32 → M (Int32 × Int32) :=
12  fun (n, mc) => do
13    if (← getFc tree n.toInt) != 0 then
14      let hl ← iadd (← rd s).heap_len 1
15      md s fun d => { d with heap_len := hl }
16      heapSet s hl n
17      setAt (← pDepth s) n.toInt 0
18      pure (n, n)
19    else
20      setDl tree n.toInt 0
21      pure (n, mc)
22
23/-- The first scan, including the separate increment. -/
24def btScan (s : DeflateStatePtr) (tree : CtDataPtr) (elems : Int32) : M (Int32 × Int32) :=
25  cfor (σ := Int32 × Int32)
26    (fun (n, _) => pure (decide (n.toInt < elems.toInt)))
27    (fun (n, mc) => do pure (← iadd n 1, mc))
28    (btScanBody s tree) (0, -1)
29
30/-- Exact state frame of the scan. -/
31def btScanState (tk : TK) (d : DeflateState) (T : Array CtData) (H : Array Int32)
32    (D : Array UInt8) (hl : Int32) : DeflateState :=
33  { tk.setArr d T with heap := H, depth := D, heap_len := hl }
34
35@[simp] theorem btScanState_tree (tk : TK) (d T H D hl) :
36    tk.arr (btScanState tk d T H D hl) = T := by cases tk <;> rfl
37
38@[simp] theorem btScanState_heap (tk : TK) (d T H D hl) :
39    (btScanState tk d T H D hl).heap = H := rfl
40
41@[simp] theorem btScanState_depth (tk : TK) (d T H D hl) :
42    (btScanState tk d T H D hl).depth = D := rfl
43
44@[simp] theorem btScanState_len (tk : TK) (d T H D hl) :
45    (btScanState tk d T H D hl).heap_len = hl := rfl
46
47/-- One actual positive-frequency iteration writes the next heap slot and
48zeroes the leaf depth. It keeps the code-tree entry unchanged. -/
49theorem btScanBody_used {h0 : Heap} {id : Nat} (tk : TK) (d : DeflateState) (n mc : Int32)
50    (hn0 : 0 ≤ n.toInt) (hnT : n.toInt < (tk.arr d).size)
51    (hnD : n.toInt < d.depth.size) (hl0 : 0 ≤ d.heap_len.toInt)
52    (hlH : d.heap_len.toInt + 1 < d.heap.size) (hbig : d.heap.size ≤ 573)
53    (hf : ((tk.arr d)[n.toInt.toNat]!).fc ≠ 0) :
54    WS h0 id (btScanBody (Sp id) (.ref (tk.ref id) 0) (n, mc)) d
55      (fun r e => ∃ hl : Int32, hl.toInt = d.heap_len.toInt + 1 ∧ r = (n, n) ∧
56        e = { d with
57          heap_len := hl, heap := d.heap.set! hl.toInt.toNat n, depth := d.depth.set! n.toInt.toNat 0 }) := by
58  unfold btScanBody
59  refine WS.bind' (ws_getFc tk n.toInt hn0 hnT) fun v e1 ⟨hv, he1⟩ => ?_
60  subst e1; subst v
61  have hb : (((tk.arr d)[n.toInt.toNat]!).fc != 0) = true := by simpa using hf
62  simp only [hb, Bool.true_eq, ite_true]
63  refine WS.bind' ws_rd fun dz e1 ⟨hdz, he1⟩ => ?_
64  subst e1; subst dz
65  have hi1 : (1 : Int32).toInt = 1 := rfl
66  refine WS.bind' (ws_iadd d.heap_len 1 (by omega) (by omega)) fun hl e1 ⟨hhl, he1⟩ => ?_
67  subst e1
68  refine WS.bind' (ws_md (fun e => { e with heap_len := hl })) fun _ e1 he1 => ?_
69  subst e1
70  unfold heapSet
71  simp only [M_bind_assoc]
72  refine WS.bind' ws_pHeap fun p e1 ⟨hp, he1⟩ => ?_
73  subst e1; subst p
74  refine WS.bind' (ws_setAt_heap hl.toInt n (by omega) (by dsimp; omega)) fun _ e1 he1 => ?_
75  subst e1
76  refine WS.bind' ws_pDepth fun p e1 ⟨hp, he1⟩ => ?_
77  subst e1; subst p
78  refine WS.bind' (ws_setAt_depth n.toInt 0 hn0 (by dsimp; exact hnD)) fun _ e1 he1 => ?_
79  subst e1
80  exact WS.pure' ⟨hl, by omega, rfl, rfl⟩
81
82/-- One actual zero-frequency iteration only clears that leaf's length. -/
83theorem btScanBody_unused {h0 : Heap} {id : Nat} (tk : TK) (d : DeflateState) (n mc : Int32)
84    (hn0 : 0 ≤ n.toInt) (hnT : n.toInt < (tk.arr d).size)
85    (hf : ((tk.arr d)[n.toInt.toNat]!).fc = 0) :
86    WS h0 id (btScanBody (Sp id) (.ref (tk.ref id) 0) (n, mc)) d
87      (fun r e => r = (n, mc) ∧
88        e = tk.setArr d ((tk.arr d).set! n.toInt.toNat { (tk.arr d)[n.toInt.toNat]! with dl := 0 })) := by
89  unfold btScanBody
90  refine WS.bind' (ws_getFc tk n.toInt hn0 hnT) fun v e1 ⟨hv, he1⟩ => ?_
91  subst e1; subst v
92  simp only [hf, bne_self_eq_false, Bool.false_eq_true, ite_false]
93  refine WS.bind' (ws_setDl tk n.toInt 0 hn0 hnT) fun _ e1 he1 => ?_
94  subst e1
95  exact WS.pure' ⟨rfl, by simp only [hf]⟩
96
97/-- Frequencies before the scan; the scan preserves these code cells. -/
98def btFreq (tk : TK) (d : DeflateState) (v : Nat) : UInt16 := ((tk.arr d)[v]!).fc
99
100/-- The first scan's derived state: exact writes, one occurrence of every
101used symbol, no other heap entries, and the exact largest used symbol. -/
102def BTScanInv (tk : TK) (d : DeflateState) (k : Nat) (mc : Int32) (e : DeflateState) : Prop :=
103  let fr := btFreq tk d
104  ∃ (T : Array CtData) (H : Array Int32) (D : Array UInt8) (hl : Int32),
105    e = btScanState tk d T H D hl ∧ T.size = (tk.arr d).size ∧ H.size = d.heap.size ∧
106    D.size = d.depth.size ∧ hl.toInt = Math.scanCount fr k ∧ mc.toInt = Math.scanMax fr k ∧
107    (∀ j < T.size, T[j]! = if j < k ∧ fr j = 0 then { (tk.arr d)[j]! with dl := 0 } else (tk.arr d)[j]!) ∧
108    (∀ j < D.size, D[j]! = if j < k ∧ fr j ≠ 0 then 0 else d.depth[j]!) ∧
109    (∀ q, ¬ (1 ≤ q ∧ q ≤ Math.scanCount fr k) → H[q]! = d.heap[q]!) ∧
110    (∀ q, 1 ≤ q → q ≤ Math.scanCount fr k →
111      0 ≤ H[q]!.toInt ∧ H[q]!.toInt < k ∧ fr H[q]!.toInt.toNat ≠ 0) ∧
112    (∀ q q', 1 ≤ q → q ≤ Math.scanCount fr k → 1 ≤ q' → q' ≤ Math.scanCount fr k →
113      H[q]! = H[q']! → q = q') ∧
114    ∀ v < k, fr v ≠ 0 → ∃ q, 1 ≤ q ∧ q ≤ Math.scanCount fr k ∧ H[q]!.toInt = v
115
116/-- The scan invariant is established by an empty heap, independently of
117the old lengths and depths. -/
118theorem btScan_init (tk : TK) (d : DeflateState) (hl : d.heap_len.toInt = 0) :
119    BTScanInv tk d 0 (-1) d := by
120  refine ⟨tk.arr d, d.heap, d.depth, d.heap_len, ?_, rfl, rfl, rfl, hl, rfl,
121    ?_, ?_, ?_, ?_, ?_, ?_⟩
122  · cases tk <;> rfl
123  · intro j hj; simp
124  · intro j hj; simp
125  · intro q hq; rfl
126  · intro q hq1 hq2; simp only [Math.scanCount] at hq2; omega
127  · intro q q' hq1 hq2; simp only [Math.scanCount] at hq2; omega
128  · intro v hv; omega
129
130/-- One complete scan iteration, including the separate checked increment. -/
131theorem btScan_step {h0 : Heap} {id : Nat} (tk : TK) (d e : DeflateState) (k N : Nat)
132    (n mc : Int32) (hn : n.toInt = k) (hk : k < N) (hN : N ≤ 286)
133    (hT : N ≤ (tk.arr d).size) (hD : N ≤ d.depth.size)
134    (hH : N < d.heap.size) (hbig : d.heap.size ≤ 573)
135    (hi : BTScanInv tk d k mc e) :
136    WS h0 id (do
137      let (n, mc) ← btScanBody (Sp id) (.ref (tk.ref id) 0) (n, mc)
138      pure (← iadd n 1, mc)) e (fun r e' => r.1.toInt = k + 1 ∧ BTScanInv tk d (k + 1) r.2 e') := by
139  obtain ⟨T, H, D, hl, he, hsT, hsH, hsD, hhl, hmc, ht, hd, hh, hv, hj, hc⟩ := hi
140  subst e
141  have hcount := Math.scanCount_le (btFreq tk d) k
142  have hnN : n.toInt.toNat = k := by omega
143  have hkT : k < T.size := by omega
144  have hkD : k < D.size := by omega
145  have hcur : (T[k]!).fc = (btFreq tk d) k := by rw [ht k hkT]; split <;> rfl
146  have hfcur : ((tk.arr (btScanState tk d T H D hl))[n.toInt.toNat]!).fc = (btFreq tk d) k := by
147    simpa only [btScanState_tree, hnN] using hcur
148  have hi1 : (1 : Int32).toInt = 1 := rfl
149  by_cases hf : (btFreq tk d) k ≠ 0
150  · refine WS.bind' (btScanBody_used tk (btScanState tk d T H D hl) n mc
151      (by omega) (by simp only [btScanState_tree]; omega)
152      (by simp only [btScanState_depth]; omega) (by simp only [btScanState_len]; omega)
153      (by simp only [btScanState_len, btScanState_heap]; omega)
154      (by simp only [btScanState_heap]; omega) (by rw [hfcur]; exact hf))
155      fun r e1 ⟨hl', hhl', hr, he1⟩ => ?_
156    subst r; subst e1
157    dsimp only
158    refine WS.bind' (ws_iadd n 1 (by omega) (by omega)) fun n' e1 ⟨hn', he1⟩ => ?_
159    subst e1
160    have hhl' : hl'.toInt = Math.scanCount (btFreq tk d) k + 1 := by simpa only [btScanState_len, hhl] using hhl'
161    have hhlN : hl'.toInt.toNat = Math.scanCount (btFreq tk d) k + 1 := by omega
162    have hnewH : Math.scanCount (btFreq tk d) k + 1 < H.size := by omega
163    have hnext : Math.scanCount (btFreq tk d) (k + 1) = Math.scanCount (btFreq tk d) k + 1 := by simp only [Math.scanCount, ite_eq_left hf]
164    have hnextmc : Math.scanMax (btFreq tk d) (k + 1) = k := by simp only [Math.scanMax, ite_eq_left hf]
165    refine WS.pure' ⟨by dsimp; omega,
166      T, H.set! (Math.scanCount (btFreq tk d) k + 1) n, D.set! k 0, hl', ?_, hsT,
167      by simpa only [size_set!] using hsH, by simpa only [size_set!] using hsD,
168      by rw [hnext]; omega, by dsimp; rw [hnextmc]; exact hn, ?_, ?_, ?_, ?_, ?_, ?_⟩
169    · simp only [btScanState_heap, btScanState_depth, hnN, hhlN]
170      rfl
171    · intro j hjT
172      rw [ht j hjT]
173      by_cases hjk : j = k
174      · subst j; simp [hf]
175      · have hcut : (j < k) ↔ (j < k + 1) := by omega
176        simp only [hcut]
177    · intro j hjD
178      have hjD' : j < D.size := by simpa only [size_set!] using hjD
179      rw [getD_set D k j 0 hkD]
180      by_cases hjk : j = k
181      · subst j; simp [hf]
182      · rw [ite_eq_right hjk, hd j hjD']
183        have hcut : (j < k) ↔ (j < k + 1) := by omega
184        simp only [hcut]
185    · intro q hq
186      rw [hnext] at hq
187      rw [getD_set H (Math.scanCount (btFreq tk d) k + 1) q n hnewH, ite_eq_right (by omega)]
188      exact hh q (by omega)
189    · intro q hq1 hq2
190      rw [hnext] at hq2
191      rw [getD_set H (Math.scanCount (btFreq tk d) k + 1) q n hnewH]
192      by_cases hq : q = Math.scanCount (btFreq tk d) k + 1
193      · rw [ite_eq_left hq]
194        exact ⟨by omega, by omega, by simpa only [hnN] using hf⟩
195      · rw [ite_eq_right hq]
196        obtain ⟨h0, hlt, hfq⟩ := hv q hq1 (by omega)
197        exact ⟨h0, by omega, hfq⟩
198    · intro q q' hq1 hq2 hq'1 hq'2 heq
199      rw [hnext] at hq2 hq'2
200      rw [getD_set H (Math.scanCount (btFreq tk d) k + 1) q n hnewH,
201        getD_set H (Math.scanCount (btFreq tk d) k + 1) q' n hnewH] at heq
202      by_cases hq : q = Math.scanCount (btFreq tk d) k + 1
203      · rw [ite_eq_left hq] at heq
204        by_cases hq' : q' = Math.scanCount (btFreq tk d) k + 1
205        · omega
206        · rw [ite_eq_right hq'] at heq
207          have hlt := (hv q' hq'1 (by omega)).2.1
208          rw [← heq] at hlt
209          omega
210      · rw [ite_eq_right hq] at heq
211        by_cases hq' : q' = Math.scanCount (btFreq tk d) k + 1
212        · rw [ite_eq_left hq'] at heq
213          have hlt := (hv q hq1 (by omega)).2.1
214          rw [heq] at hlt
215          omega
216        · rw [ite_eq_right hq'] at heq
217          exact hj q q' hq1 (by omega) hq'1 (by omega) heq
218    · intro v hvk hfv
219      rw [hnext]
220      by_cases hvk' : v = k
221      · subst v
222        refine ⟨Math.scanCount (btFreq tk d) k + 1, by omega, by omega, ?_⟩
223        rw [getD_set H (Math.scanCount (btFreq tk d) k + 1) _ n hnewH, ite_eq_left rfl]
224        exact hn
225      · obtain ⟨q, hq1, hq2, hqv⟩ := hc v (by omega) hfv
226        refine ⟨q, hq1, by omega, ?_⟩
227        rw [getD_set H (Math.scanCount (btFreq tk d) k + 1) q n hnewH, ite_eq_right (by omega)]
228        exact hqv
229  · have hf0 : (btFreq tk d) k = 0 := by simpa using hf
230    refine WS.bind' (btScanBody_unused tk (btScanState tk d T H D hl) n mc
231      (by omega) (by simp only [btScanState_tree]; omega) (by rw [hfcur]; exact hf0))
232      fun r e1 ⟨hr, he1⟩ => ?_
233    subst r; subst e1
234    dsimp only
235    refine WS.bind' (ws_iadd n 1 (by omega) (by omega)) fun n' e1 ⟨hn', he1⟩ => ?_
236    subst e1
237    have hnext : Math.scanCount (btFreq tk d) (k + 1) = Math.scanCount (btFreq tk d) k := by simp only [Math.scanCount, hf0, ne_eq, not_true_eq_false, ite_false, Nat.add_zero]
238    have hnextmc : Math.scanMax (btFreq tk d) (k + 1) = Math.scanMax (btFreq tk d) k := by simp only [Math.scanMax, hf0, ne_eq, not_true_eq_false, ite_false]
239    refine WS.pure' ⟨by dsimp; omega,
240      T.set! k { T[k]! with dl := 0 }, H, D, hl, ?_,
241      by simpa only [size_set!] using hsT, hsH, hsD,
242      by simpa only [hnext] using hhl, by simpa only [hnextmc] using hmc, ?_, ?_,
243      by simpa only [hnext] using hh, ?_, by simpa only [hnext] using hj, ?_⟩
244    · simp only [btScanState_tree, hnN]
245      cases tk <;> rfl
246    · intro j hjT
247      have hjT' : j < T.size := by simpa only [size_set!] using hjT
248      rw [getD_set T k j _ hkT]
249      by_cases hjk : j = k
250      · subst j
251        rw [ite_eq_left rfl, ht k hkT]
252        simp [hf0]
253      · rw [ite_eq_right hjk, ht j hjT']
254        have hcut : (j < k) ↔ (j < k + 1) := by omega
255        simp only [hcut]
256    · intro j hjD
257      rw [hd j hjD]
258      by_cases hjk : j = k
259      · subst j; simp [hf0]
260      · have hcut : (j < k) ↔ (j < k + 1) := by omega
261        simp only [hcut]
262    · intro q hq1 hq2
263      rw [hnext] at hq2
264      obtain ⟨h0, hlt, hfq⟩ := hv q hq1 hq2
265      exact ⟨h0, by omega, hfq⟩
266    · intro v hvk hfv
267      rw [hnext]
268      have hvk' : v < k := by
269        by_cases heq : v = k
270        · subst v; exact False.elim (hfv hf0)
271        · omega
272      exact hc v hvk' hfv
273
274/-- The complete first scan terminates, keeps each used symbol exactly once
275in the heap, computes the exact largest used symbol, clears unused lengths,
276and preserves all cells outside its explicit write set. The caller must supply
277the empty heap written immediately before the loop. -/
278theorem ws_btScan {h0 : Heap} {id : Nat} (tk : TK) (d : DeflateState) (elems : Int32)
279    (he0 : 0 ≤ elems.toInt) (he286 : elems.toInt ≤ 286)
280    (hT : elems.toInt ≤ (tk.arr d).size) (hD : elems.toInt ≤ d.depth.size)
281    (hH : elems.toInt < d.heap.size) (hbig : d.heap.size ≤ 573)
282    (hlen : d.heap_len.toInt = 0) :
283    WS h0 id (btScan (Sp id) (.ref (tk.ref id) 0) elems) d
284      (fun r e => r.1.toInt = elems.toInt ∧ BTScanInv tk d elems.toInt.toNat r.2 e) := by
285  let N := elems.toInt.toNat
286  have heN : elems.toInt = N := by dsimp [N]; omega
287  let Inv : Int32 × Int32 → DeflateState → Prop := fun r e =>
288    ∃ k : Nat, k ≤ N ∧ r.1.toInt = k ∧ BTScanInv tk d k r.2 e
289  unfold btScan
290  refine WS.cfor2 Inv (fun r _ => N - r.1.toInt.toNat) _ ?_
291    ⟨0, by omega, rfl, btScan_init tk d hlen⟩ (by simp only [fuel]; omega)
292  rintro ⟨n, mc⟩ e ⟨k, hk, hn, hi⟩
293  change n.toInt = (k : Int) at hn
294  refine WS.pure' ?_
295  by_cases hlt : k < N
296  · refine Or.inr ⟨by simp only [decide_eq_true_eq]; omega, ?_⟩
297    dsimp only
298    refine WS.mono (btScan_step tk d e k N n mc hn hlt (by omega) (by omega)
299      (by omega) (by omega) hbig hi) ?_
300    intro r e' ⟨hr, hi'⟩
301    exact ⟨⟨k + 1, by omega, hr, hi'⟩, by omega⟩
302  · refine Or.inl ⟨by simp only [decide_eq_false_iff_not]; omega, ?_⟩
303    have hkN : k = N := by omega
304    exact ⟨by dsimp; omega, by simpa only [hkN] using hi⟩
305
306/-- Any scanned symbol absent from the resulting heap has length zero.
307This derives the inactive-symbol condition needed after tree construction. -/
308theorem BTScanInv.absent_zero {tk : TK} {d e : DeflateState} {k : Nat} {mc : Int32}
309    (hi : BTScanInv tk d k mc e) (hT : k ≤ (tk.arr d).size) (v : Nat) (hv : v < k)
310    (habsent : ∀ q : Nat, 1 ≤ q → (q : Int) ≤ e.heap_len.toInt → (e.heap[q]!).toInt ≠ v) :
311    ((tk.arr e)[v]!).dl = 0 := by
312  obtain ⟨T, H, D, hl, rfl, hsT, hsH, hsD, hhl, hmc, ht, hd, hh, hvalid, hinj, hcomplete⟩ := hi
313  have hfreq : btFreq tk d v = 0 := by
314    apply Classical.byContradiction
315    intro hf
316    obtain ⟨q, hq1, hq2, hqv⟩ := hcomplete v hv hf
317    exact habsent q hq1 (by simp only [btScanState_len]; omega) hqv
318  simp only [btScanState_tree]
319  rw [ht v (by omega), ite_eq_left ⟨hv, hfreq⟩]
320
321end Zlib.Trees.Proofs
ZLIB × LEAN

全局目录

当前位置trees.c.build.scan.lean