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

trees.c.build.forest.lean

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

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

1import ZlibF.Proof.«trees.c.build.merge»
2import ZlibF.Proof.«trees.c.heap.gbre»
3import ZlibF.Math.DeflateForest
4
5/-! # trees.c: retaining the forest represented by the heap queue and tail -/
6
7namespace Zlib.Trees.Proofs
8open C Zlib.Trees
9
10/-- The actual two-node selection and child stores preserve every previously
11stored tail cell. The queue/tail gap is numeric data, not a callee contract. -/
12theorem ws_btMergeOpen_tail {h0 : Heap} {id : Nat} (tk : TK) (d : DeflateState) (len : Nat)
13    (hlen : d.heap_len.toInt = len) (h2 : 2 ≤ len) (hsz : len < d.heap.size)
14    (hbig : d.heap.size ≤ 573) (hmH : d.heap_max.toInt ≤ d.heap.size)
15    (hgap : (len : Int) < d.heap_max.toInt - 1)
16    (hval : ∀ i, 1 ≤ i → i ≤ len → NV (tk.arr d) d.depth d.heap[i]!)
17    (hinj : ∀ i j, 1 ≤ i → i ≤ len → 1 ≤ j → j ≤ len → d.heap[i]! = d.heap[j]! → i = j)
18    (ho : HeapOK (sm (tk.arr d) d.depth) (fun i => d.heap[i]!) len 0) :
19    WS h0 id (btMergeOpen (Sp id) (.ref (tk.ref id) 0)) d (fun _ e =>
20      ∀ q : Nat, d.heap_max.toInt ≤ (q : Int) → e.heap[q]! = d.heap[q]!) := by
21  unfold btMergeOpen
22  refine WS.bind' (ws_btPick2 tk d len hlen h2 hsz hbig hval hinj ho)
23    fun pair e1 ⟨hl, H, hn, hm, hhl, he1, hsH, hframe, hp, horder, hnv, hmv, hnm,
24      hminn, hminm, horigin, hcomplete, hno, hHinj, hcount⟩ => ?_
25  subst e1
26  rcases pair with ⟨n, m⟩
27  refine WS.bind' (ws_btKeepChildren { d with heap := H, heap_len := hl } n m
28    (by dsimp only; omega) (by dsimp only; omega) (by dsimp only; omega))
29    fun _ e2 ⟨hm1, hm2, hh1, hh2, he2, hsH', hnKeep, hmKeep, hKeepFrame⟩ => ?_
30  subst e2
31  refine WS.pure' ?_
32  intro q hq
33  have hqH := hKeepFrame q (by dsimp only at hh1; omega) (by dsimp only at hh2; omega)
34  change ((H.set! hm1.toInt.toNat n).set! hm2.toInt.toNat m)[q]! = d.heap[q]!
35  rw [hqH]
36  exact hframe q (by omega)
37
38/-- Parent creation sees the same tree and depth through heap-control-only
39updates. This is a record identity, not an assumed functional contract. -/
40theorem btParentState_heap_view (tk : TK) (d : DeflateState) (H : Array Int32) (hl hm n m node : Int32) :
41    tk.arr (btParentState tk { d with heap := H, heap_len := hl, heap_max := hm } n m node) =
42      tk.arr (btParentState tk d n m node) ∧
43    (btParentState tk { d with heap := H, heap_len := hl, heap_max := hm } n m node).depth =
44      (btParentState tk d n m node).depth := by
45  cases tk <;> exact ⟨rfl, rfl⟩
46
47/-- A singleton permutation of a root-replaced queue contains that root. -/
48theorem PermOn.singleton_root {A H : Nat → Int32} {node : Int32}
49    (hp : PermOn A (fun i => if i = 1 then node else H i) 1) : A 1 = node := by
50  obtain ⟨q, hq1, hq2, hq⟩ := hp.preimage 1 (by omega) (by omega)
51  have hq' : q = 1 := by omega
52  simpa only [hq', ite_true] using hq
53
54/-- A whole actual merge retains the old tail, gives exact parent-array
55effects, and retains exact queue counts. Both selected nodes came from the
56old queue. When this is the last merge, its new singleton root is the fresh
57parent. All called-function behavior is supplied by checked execution
58proofs. -/
59theorem ws_btMergeBody_forest {h0 : Heap} {id : Nat} (tk : TK) (d : DeflateState) (len : Nat) (node : Int32)
60    (hlen : d.heap_len.toInt = len) (h2 : 2 ≤ len) (hsz : len < d.heap.size)
61    (hbig : d.heap.size ≤ 573) (hmH : d.heap_max.toInt ≤ d.heap.size)
62    (hgap : (len : Int) < d.heap_max.toInt - 1)
63    (hp : NV (tk.arr d) d.depth node) (hinc : node.toInt < 2147483647)
64    (hbefore : ∀ i, 1 ≤ i → i ≤ len → 0 ≤ d.heap[i]!.toInt ∧ d.heap[i]!.toInt < node.toInt)
65    (hinj : ∀ i j, 1 ≤ i → i ≤ len → 1 ≤ j → j ≤ len → d.heap[i]! = d.heap[j]! → i = j)
66    (ho : HeapOK (sm (tk.arr d) d.depth) (fun i => d.heap[i]!) len 0) :
67    WS h0 id (btMergeBody (Sp id) (.ref (tk.ref id) 0) node) d (fun next e =>
68      next.toInt = node.toInt + 1 ∧ ∃ n m : Int32, n ≠ m ∧
69        (∃ q : Nat, 1 ≤ q ∧ q ≤ len ∧ n = d.heap[q]!) ∧
70        (∃ q : Nat, 1 ≤ q ∧ q ≤ len ∧ m = d.heap[q]!) ∧
71        e.heap_len.toInt = (len : Int) - 1 ∧ e.heap_max.toInt = d.heap_max.toInt - 2 ∧
72        e.heap[(d.heap_max.toInt - 1).toNat]! = n ∧ e.heap[(d.heap_max.toInt - 2).toNat]! = m ∧
73        (∀ q : Nat, d.heap_max.toInt ≤ (q : Int) → e.heap[q]! = d.heap[q]!) ∧
74        tk.arr e = tk.arr (btParentState tk d n m node) ∧ e.depth = (btParentState tk d n m node).depth ∧
75        (len = 2 → e.heap[1]! = node) ∧
76        ∀ F : Int32 → Nat, GB.rs (fun i => F e.heap[i + 1]!) (len - 1) + F n + F m =
77          GB.rs (fun i => F d.heap[i + 1]!) len + F node) := by
78  have hv : ∀ i, 1 ≤ i → i ≤ len → NV (tk.arr d) d.depth d.heap[i]! := by
79    intro i hi1 hi2
80    have hb := hbefore i hi1 hi2
81    exact ⟨hb.1, by have := hp.2.1; omega, by have := hp.2.2; omega⟩
82  unfold btMergeBody
83  refine WS.bind' (merge_ws_and
84    (ws_btMergeOpen tk d len hlen h2 hsz hbig hmH hgap hv hinj ho)
85    (ws_btMergeOpen_tail tk d len hlen h2 hsz hbig hmH hgap hv hinj ho))
86    fun pair e1 ⟨⟨hl, hm1, hm2, H, hn, hm, hnm, hhl, hh1, hh2, he1, hsH, hkeepn, hkeepm,
87      hnv, hmv, horder, hminn, hminm, horigin, hcomplete, hno, hHi, hcount⟩, htail⟩ => ?_
88  rcases pair with ⟨n, m⟩
89  dsimp only at hn hm hnm hnv hmv hkeepn hkeepm hno hcount ⊢
90  subst e1
91  let d1 := { d with heap := H, heap_len := hl, heap_max := hm2 }
92  have hT1 : tk.arr d1 = tk.arr d := by cases tk <;> rfl
93  have hD1 : d1.depth = d.depth := rfl
94  have hp1 : NV (tk.arr d1) d1.depth node := by rw [hT1, hD1]; exact hp
95  have hn1 : NV (tk.arr d1) d1.depth n := by rw [hT1, hD1]; exact hnv
96  have hm1v : NV (tk.arr d1) d1.depth m := by rw [hT1, hD1]; exact hmv
97  have hB : ∀ i, 1 ≤ i → i ≤ len - 1 → 0 ≤ H[i]!.toInt ∧ H[i]!.toInt < node.toInt := by
98    intro i hi1 hi2
99    obtain ⟨j, hj1, hj2, heq⟩ := horigin i hi1 hi2
100    rw [heq]
101    exact hbefore j (by omega) hj2
102  refine WS.bind' (ws_btMakeParent tk d1 n m node hn1 hm1v hp1) fun _ e2 he2 => ?_
103  subst e2
104  let d2 := btParentState tk d1 n m node
105  have hp2 : NV (tk.arr d2) d2.depth node := by
106    simpa only [d2, NV, btParentState_tree_size, btParentState_depth_size] using hp1
107  have hv2 : ∀ i, 1 ≤ i → i ≤ len - 1 → NV (tk.arr d2) d2.depth d2.heap[i]! := by
108    intro i hi1 hi2
109    have hb := hB i hi1 hi2
110    simp only [d2, btParentState_heap, d1, NV, btParentState_tree_size, btParentState_depth_size, hT1]
111    exact ⟨hb.1, by have := hp.2.1; omega, by have := hp.2.2; omega⟩
112  have ho2 : HeapOK (sm (tk.arr d2) d2.depth) (fun i => d2.heap[i]!) (len - 1) 1 := by
113    intro c hc2 hcl hcp
114    have hb := hB c (by omega) hcl
115    have hb' := hB (c / 2) (by omega) (by omega)
116    dsimp only [d2]
117    rw [btParentState_heap]
118    change sm (tk.arr (btParentState tk d1 n m node)) (btParentState tk d1 n m node).depth H[c / 2]! H[c]! = true
119    rw [btParentState_sm tk d1 n m node _ _ hn1 hm1v hp1 hb'.1 hb'.2 hb.1 hb.2, hT1, hD1]
120    exact horder c hc2 hcl (by omega)
121  refine WS.mono (ws_btMergeClose tk d2 (len - 1) node
122    (by simpa only [d2, btParentState_len] using hhl.trans (by omega)) (by omega)
123    (by simpa only [d2, btParentState_heap] using (show len - 1 < H.size by omega))
124    (by simpa only [d2, btParentState_heap] using (show H.size ≤ 573 by omega)) hp2 hinc hv2 ho2) ?_
125  intro next e3 ⟨hnext, H', he3, hsH', hframe, hperm, horder', hmin', hcount'⟩
126  subst e3
127  have hHeap2 : d2.heap = H := by simp only [d2, btParentState_heap]; rfl
128  have hroot : d2.heap[1]! = m := by rw [hHeap2]; exact hm.symm
129  have hmorigin : ∃ q : Nat, 1 ≤ q ∧ q ≤ len ∧ m = d.heap[q]! := by
130    obtain ⟨q, hq1, hq2, hq⟩ := horigin 1 (by omega) (by omega)
131    exact ⟨q, by omega, hq2, hm.trans hq⟩
132  have hview := btParentState_heap_view tk d H hl hm2 n m node
133  refine ⟨hnext, n, m, hnm, ⟨1, by omega, by omega, hn⟩, hmorigin,
134    by simpa only [d2, btParentState_len] using hhl, by simpa only [d2, btParentState_max] using hh2,
135    ?_, ?_, ?_, ?_, hview.2, ?_, ?_⟩
136  · change H'[(d.heap_max.toInt - 1).toNat]! = n
137    rw [← hh1, hframe _ (by omega), hHeap2]
138    exact hkeepn
139  · change H'[(d.heap_max.toInt - 2).toNat]! = m
140    rw [← hh2, hframe _ (by omega), hHeap2]
141    exact hkeepm
142  · intro q hq
143    change H'[q]! = d.heap[q]!
144    rw [hframe q (by omega), hHeap2]
145    exact htail q hq
146  · rw [tk_arr_heap]
147    exact hview.1
148  · intro hlen2
149    have hp' : PermOn (fun i => H'[i]!) (fun i => if i = 1 then node else d2.heap[i]!) 1 := by
150      simpa only [hlen2] using hperm
151    exact hp'.singleton_root
152  · intro F
153    have hc := hcount F
154    have hc' := hcount' F
155    rw [hroot, hHeap2] at hc'
156    change GB.rs (fun i => F H'[i + 1]!) (len - 1) + F n + F m = _
157    omega
158
159
160/-- A forest consists of the active queue and the descending retained tail.
161Its observations are exactly the original leaves plus every parent created
162so far. Parent links and placement describe the actual source layout. -/
163structure BTForest (tk : TK) (N K j : Nat) (mc : Int32) (d0 : DeflateState)
164    (node : Int32) (d : DeflateState) : Prop where
165  initial : BTLeafInv tk N mc d0
166  initial_len : d0.heap_len.toInt = K
167  queue : BTMergeQueue tk N K j node d
168  observations : ∀ F : Nat → Nat,
169    GB.poolSum (Hn d) (K - j) (2 * j) F =
170      GB.rs (fun i => F (Hn d0 (i + 1))) K + GB.rs (fun i => F (N + i)) j
171  tail_valid : ∀ q : Nat, 573 - 2 * j ≤ q → q < 573 →
172    0 ≤ d.heap[q]!.toInt ∧ d.heap[q]!.toInt < node.toInt
173  parent : ∀ q : Nat, 573 - 2 * j ≤ q → q < 573 →
174    (tk.arr d)[Hn d q]!.dl = UInt16.ofNat (GB.dadP N q)
175  placement : ∀ q : Nat, 573 - 2 * j ≤ q → q < 573 → N ≤ Hn d q →
176    q < 571 - 2 * (Hn d q - N)
177  leaf_freq : ∀ v < N, (tk.arr d)[v]!.fc = (tk.arr d0)[v]!.fc
178  unused : ∀ v < N, btFreq tk d0 v = 0 → (tk.arr d)[v]!.dl = 0
179  leaf_depth : ∀ v < N, btFreq tk d0 v ≠ 0 → d.depth[v]! = 0
180  last_root : j + 1 = K → d.heap[1]!.toInt = (N + j - 1 : Nat)
181
182/-- The actual prepared leaves establish the complete initial forest.
183The tail is empty at this stage, so its link and placement facts are derived
184without assumptions about old heap contents. -/
185theorem BTForest.of_leaf {tk : TK} {d : DeflateState} {N : Nat} {mc node : Int32}
186    (hi : BTLeafInv tk N mc d) (h2 : 2 ≤ d.heap_len.toInt) (hm : d.heap_max = HEAP_SIZE)
187    (hn : node.toInt = N)
188    (hT : N + d.heap_len.toInt.toNat - 1 ≤ (tk.arr d).size)
189    (hD : N + d.heap_len.toInt.toNat - 1 ≤ d.depth.size)
190    (ho : HeapOK (sm (tk.arr d) d.depth) (fun i => d.heap[i]!) d.heap_len.toInt.toNat 0) :
191    BTForest tk N d.heap_len.toInt.toNat 0 mc d node d := by
192  refine ⟨hi, by omega, BTMergeQueue.of_leaf hi h2 hm hn hT hD ho, ?_, ?_, ?_, ?_,
193    by intros; rfl, hi.unusedLength, hi.usedDepth, ?_⟩
194  · intro F
195    simp only [Nat.sub_zero, Nat.mul_zero, GB.poolSum, GB.rs_zero, Nat.add_zero]
196  · intro q hq hq'; omega
197  · intro q hq hq'; omega
198  · intro q hq hq'; omega
199  · intro heq; omega
200
201/-- Initial queue indices are distinct natural-valued leaf nodes below N. -/
202theorem BTForest.initial_nodes {tk : TK} {d0 d : DeflateState} {N K j : Nat} {mc node : Int32}
203    (hi : BTForest tk N K j mc d0 node d) :
204    (∀ i < K, Hn d0 (i + 1) < N) ∧
205    (∀ i i', i < K → i' < K → Hn d0 (i + 1) = Hn d0 (i' + 1) → i = i') := by
206  have hlen := hi.initial_len
207  constructor
208  · intro i hiK
209    have hv := hi.initial.valid (i + 1) (by omega) (by omega)
210    unfold Hn
211    omega
212  · intro i i' hiK hiK' heq
213    have hv := hi.initial.valid (i + 1) (by omega) (by omega)
214    have hv' := hi.initial.valid (i' + 1) (by omega) (by omega)
215    have he : d0.heap[i + 1]! = d0.heap[i' + 1]! := Int32.toInt_inj.mp (by unfold Hn at heq; omega)
216    have := hi.initial.injective (i + 1) (i' + 1) (by omega) (by omega) (by omega) (by omega) he
217    omega
218
219/-- Exact observations establish uniqueness across the queue and tail,
220including between those two regions. -/
221theorem BTForest.injective {tk : TK} {d0 d : DeflateState} {N K j : Nat} {mc node : Int32}
222    (hi : BTForest tk N K j mc d0 node d) :
223    ∀ q q', ((1 ≤ q ∧ q ≤ K - j) ∨ (573 - 2 * j ≤ q ∧ q < 573)) →
224      ((1 ≤ q' ∧ q' ≤ K - j) ∨ (573 - 2 * j ≤ q' ∧ q' < 573)) → Hn d q = Hn d q' → q = q' := by
225  have hinit := hi.initial_nodes
226  have hseq := GB.pool_unique (Hn d) (Hn d0) (K - j) (2 * j) K N j hinit.1 hinit.2 hi.observations
227  have hbound : K - j + 2 * j = K + j := by have := hi.queue.stage; omega
228  rw [hbound] at hseq
229  exact GB.pool_heap_injective (Hn d) K j (by have := hi.queue.kN; have := hi.queue.n286; omega)
230    hi.queue.stage hseq
231
232/-- Every active leaf came from the prepared nonzero-frequency leaf set. -/
233theorem BTForest.leaf_used {tk : TK} {d0 d : DeflateState} {N K j : Nat} {mc node : Int32}
234    (hi : BTForest tk N K j mc d0 node d) (q : Nat)
235    (hq : (1 ≤ q ∧ q ≤ K - j) ∨ (573 - 2 * j ≤ q ∧ q < 573)) (hN : Hn d q < N) :
236    btFreq tk d0 (Hn d q) ≠ 0 := by
237  have hK : K ≤ 286 := by have := hi.queue.kN; have := hi.queue.n286; omega
238  obtain ⟨i, hiB, hei⟩ := GB.poolAt_preimage (Hn d) K j q hK hi.queue.stage hq
239  have hiB' : i < K - j + 2 * j := by have := hi.queue.stage; omega
240  rcases GB.pool_origin (Hn d) (Hn d0) (K - j) (2 * j) K N j hi.observations i hiB' with
241    ⟨a, ha, he⟩ | he
242  · have hv := hi.initial.valid (a + 1) (by omega) (by have := hi.initial_len; omega)
243    rw [hei] at he
244    change (d0.heap[a + 1]!).toInt.toNat = Hn d q at he
245    rw [he] at hv
246    exact hv.2.2
247  · rw [hei] at he
248    omega
249
250/-- All retained old tail nodes are distinct from a selected old queue node. -/
251theorem BTForest.queue_not_tail {tk : TK} {d0 d : DeflateState} {N K j : Nat} {mc node : Int32}
252    (hi : BTForest tk N K j mc d0 node d) (p q : Nat)
253    (hp1 : 1 ≤ p) (hp2 : p ≤ K - j) (hq1 : 573 - 2 * j ≤ q) (hq2 : q < 573) :
254    Hn d q ≠ Hn d p := by
255  intro heq
256  have he := hi.injective q p (Or.inr ⟨hq1, hq2⟩) (Or.inl ⟨hp1, hp2⟩) heq
257  have := hi.queue.stage
258  have := hi.queue.kN
259  have := hi.queue.n286
260  omega
261
262
263/-- The actual merge preserves the full queue/tail forest. Old parent links
264and heap-tail entries are framed; the two new children point to the numeric
265fresh parent. Leaf frequencies, unused lengths and initialized leaf depths
266are preserved. The initial leaf representation is carried from the actual
267prefix, not supplied as a called-function contract. -/
268theorem ws_btMergeBody_forest_inv {h0 : Heap} {id : Nat} {tk : TK} {d0 d : DeflateState}
269    {N K j : Nat} {mc node : Int32} (hi : BTForest tk N K j mc d0 node d) (hmore : j + 1 < K) :
270    WS h0 id (btMergeBody (Sp id) (.ref (tk.ref id) 0) node) d
271      (fun next e => BTForest tk N K (j + 1) mc d0 next e) := by
272  have hK : K ≤ 286 := by have := hi.queue.kN; have := hi.queue.n286; omega
273  have hj := hi.queue.stage
274  have hcounter := hi.queue.counter
275  have hlen := hi.queue.len
276  have hmax := hi.queue.max
277  have hsize := hi.queue.heap
278  have hTsize := hi.queue.tree
279  have hDsize := hi.queue.depth
280  have hN3 := hi.queue.n3
281  have hNb := hi.queue.n286
282  have hKN := hi.queue.kN
283  have hnode : NV (tk.arr d) d.depth node := ⟨by omega, by omega, by omega⟩
284  refine WS.mono (merge_ws_and (ws_btMergeBody_queue hi.queue hmore)
285    (ws_btMergeBody_forest tk d (K - j) node hlen (by omega) (by omega) (by omega)
286      (by omega) (by omega) hnode (by omega)
287      (fun i hi1 hi2 => hi.queue.valid i hi1 (by omega))
288      (fun i i' hi1 hi2 hi'1 hi'2 => hi.queue.injective i i' hi1 (by omega) hi'1 (by omega)) hi.queue.order)) ?_
289  intro next e ⟨hq, hnext, n, m, hnm, ⟨pn, hpn1, hpn2, hpn⟩, ⟨pm, hpm1, hpm2, hpm⟩,
290    hlen', hmax', hkeepn, hkeepm, htail, htree, hdepth, hroot, hcount⟩
291  have hnv := hi.queue.valid pn hpn1 (by omega)
292  have hmv := hi.queue.valid pm hpm1 (by omega)
293  rw [← hpn] at hnv
294  rw [← hpm] at hmv
295  have hnV : NV (tk.arr d) d.depth n := ⟨hnv.1, by omega, by omega⟩
296  have hmV : NV (tk.arr d) d.depth m := ⟨hmv.1, by omega, by omega⟩
297  have hnodeN : node.toInt.toNat = N + j := by omega
298  have hpnN : Hn d pn = n.toInt.toNat := congrArg (fun x : Int32 => x.toInt.toNat) hpn.symm
299  have hpmN : Hn d pm = m.toInt.toNat := congrArg (fun x : Int32 => x.toInt.toNat) hpm.symm
300  have hboundary : d.heap_max.toInt = (573 - 2 * j : Nat) := by omega
301  have hnidx : (d.heap_max.toInt - 1).toNat = 572 - 2 * j := by omega
302  have hmidx : (d.heap_max.toInt - 2).toNat = 571 - 2 * j := by omega
303  rw [hnidx] at hkeepn
304  rw [hmidx] at hkeepm
305  have hkeepnN : Hn e (572 - 2 * j) = n.toInt.toNat := congrArg (fun x : Int32 => x.toInt.toNat) hkeepn
306  have hkeepmN : Hn e (571 - 2 * j) = m.toInt.toNat := congrArg (fun x : Int32 => x.toInt.toNat) hkeepm
307  have htailN : ∀ q : Nat, 573 - 2 * j ≤ q → Hn e q = Hn d q := by
308    intro q hq
309    exact congrArg (fun x : Int32 => x.toInt.toNat) (htail q (by omega))
310  have hnotn : ∀ q : Nat, 573 - 2 * j ≤ q → q < 573 → Hn d q ≠ n.toInt.toNat := by
311    intro q hq1 hq2
312    rw [← hpnN]
313    exact hi.queue_not_tail pn q hpn1 hpn2 hq1 hq2
314  have hnotm : ∀ q : Nat, 573 - 2 * j ≤ q → q < 573 → Hn d q ≠ m.toInt.toNat := by
315    intro q hq1 hq2
316    rw [← hpmN]
317    exact hi.queue_not_tail pm q hpm1 hpm2 hq1 hq2
318  have hcast : i2us node = UInt16.ofNat (N + j) := by
319    rw [i2us_eq node (by omega) (by omega), hnodeN]
320  have hsplit : ∀ q : Nat, 573 - 2 * (j + 1) ≤ q → q < 573 →
321      q = 572 - 2 * j ∨ q = 571 - 2 * j ∨ 573 - 2 * j ≤ q := by intros; omega
322  refine ⟨hi.initial, hi.initial_len, hq, ?_, ?_, ?_, ?_, ?_, ?_, ?_, ?_⟩
323  · intro F
324    have hs := GB.poolSum_step (Hn d) (Hn e) K j n.toInt.toNat m.toInt.toNat (N + j) hK hmore
325      hkeepnN hkeepmN (fun i hi => htailN (572 - i) (by omega)) (fun G => ?_) F
326    · rw [hs, hi.observations, GB.rs_succ]
327      omega
328    · have hc := hcount (fun x => G x.toInt.toNat)
329      simpa only [Hn, hnodeN] using hc
330  · intro q hq1 hq2
331    rcases hsplit q hq1 hq2 with he | he | hqold
332    · subst q; rw [hkeepn]; exact ⟨hnv.1, by omega⟩
333    · subst q; rw [hkeepm]; exact ⟨hmv.1, by omega⟩
334    · rw [htail q (by omega)]
335      have hv := hi.tail_valid q hqold hq2
336      exact ⟨hv.1, by omega⟩
337  · intro q hq1 hq2
338    rw [htree, btParentState_dad tk d n m node hnV hmV hnode]
339    rcases hsplit q hq1 hq2 with he | he | hqold
340    · subst q; rw [hkeepnN, ite_eq_left (Or.inl rfl), hcast]
341      congr 1
342      unfold GB.dadP
343      omega
344    · subst q; rw [hkeepmN, ite_eq_left (Or.inr rfl), hcast]
345      congr 1
346      unfold GB.dadP
347      omega
348    · rw [htailN q hqold, ite_eq_right (by intro he; rcases he with he | he; exact hnotn q hqold hq2 he; exact hnotm q hqold hq2 he)]
349      exact hi.parent q hqold hq2
350  · intro q hq1 hq2 hqN
351    rcases hsplit q hq1 hq2 with he | he | hqold
352    · subst q; rw [hkeepnN] at hqN ⊢; omega
353    · subst q; rw [hkeepmN] at hqN ⊢; omega
354    · rw [htailN q hqold] at hqN ⊢
355      exact hi.placement q hqold hq2 hqN
356  · intro v hv
357    rw [htree, btParentState_fc tk d n m node hnV hmV hnode, ite_eq_right (by omega)]
358    exact hi.leaf_freq v hv
359  · intro v hv hz
360    have hvn : v ≠ n.toInt.toNat := by
361      intro he
362      have hu := hi.leaf_used pn (Or.inl ⟨hpn1, hpn2⟩) (by rw [hpnN, ← he]; exact hv)
363      rw [hpnN, ← he] at hu
364      exact hu hz
365    have hvm : v ≠ m.toInt.toNat := by
366      intro he
367      have hu := hi.leaf_used pm (Or.inl ⟨hpm1, hpm2⟩) (by rw [hpmN, ← he]; exact hv)
368      rw [hpmN, ← he] at hu
369      exact hu hz
370    rw [htree, btParentState_dad tk d n m node hnV hmV hnode,
371      ite_eq_right (by intro he; rcases he with he | he; exact hvn he; exact hvm he)]
372    exact hi.unused v hv hz
373  · intro v hv hz
374    rw [hdepth, btParentState_depth tk d n m node hnode, ite_eq_right (by omega)]
375    exact hi.leaf_depth v hv hz
376  · intro hlast
377    have hlen2 : K - j = 2 := by omega
378    have hr := hroot hlen2
379    have hrI := congrArg Int32.toInt hr
380    omega
381
382
383/-- Exact footprint of merging: only the selected tree, heap, depth and
384the two heap controls can change. Every array retains its size. -/
385def BTForestFrame (tk : TK) (d0 d : DeflateState) : Prop :=
386  ∃ (T : Array CtData) (H : Array Int32) (D : Array UInt8) (hl hm : Int32),
387    d = { btScanState tk d0 T H D hl with heap_max := hm } ∧
388    T.size = (tk.arr d0).size ∧ H.size = d0.heap.size ∧ D.size = d0.depth.size
389
390theorem BTForestFrame.refl (tk : TK) (d : DeflateState) : BTForestFrame tk d d := by
391  refine ⟨tk.arr d, d.heap, d.depth, d.heap_len, d.heap_max, ?_, rfl, rfl, rfl⟩
392  cases tk <;> rfl
393
394theorem BTForestFrame.trans {tk : TK} {a b c : DeflateState}
395    (hab : BTForestFrame tk a b) (hbc : BTForestFrame tk b c) : BTForestFrame tk a c := by
396  obtain ⟨T, H, D, hl, hm, rfl, hT, hH, hD⟩ := hab
397  obtain ⟨T', H', D', hl', hm', rfl, hT', hH', hD'⟩ := hbc
398  refine ⟨T', H', D', hl', hm', ?_, ?_, hH'.trans hH, hD'.trans hD⟩
399  · cases tk <;> rfl
400  · cases tk <;> exact hT'.trans hT
401
402/-- Descriptor and bit-count metadata survive the exact merge footprint. -/
403theorem BTForestFrame.metadata {tk : TK} {a b : DeflateState} (hi : BTForestFrame tk a b) (dk : TK) :
404    dk.getDesc b = dk.getDesc a ∧ b.bl_count = a.bl_count := by
405  obtain ⟨T, H, D, hl, hm, rfl, rest⟩ := hi
406  cases tk <;> cases dk <;> exact ⟨rfl, rfl⟩
407
408/-- The actual full iteration has precisely the merging footprint. -/
409theorem ws_btMergeBody_frame {h0 : Heap} {id : Nat} {tk : TK} {d : DeflateState}
410    {N K j : Nat} {node : Int32} (hi : BTMergeQueue tk N K j node d) (hmore : j + 1 < K) :
411    WS h0 id (btMergeBody (Sp id) (.ref (tk.ref id) 0) node) d
412      (fun _ e => BTForestFrame tk d e) := by
413  have hN3 := hi.n3
414  have hNb := hi.n286
415  have hK2 := hi.k2
416  have hKN := hi.kN
417  have hj := hi.stage
418  have hn := hi.counter
419  have hl := hi.len
420  have hm := hi.max
421  have hH := hi.heap
422  have hT := hi.tree
423  have hD := hi.depth
424  have hp : NV (tk.arr d) d.depth node := ⟨by omega, by omega, by omega⟩
425  refine WS.mono (ws_btMergeBody tk d (K - j) node hl (by omega) (by omega)
426    (by omega) (by omega) (by omega) hp (by omega)
427    (fun i hi1 hi2 => hi.valid i hi1 (by omega))
428    (fun i i' hi1 hi2 hi'1 hi'2 => hi.injective i i' hi1 (by omega) hi'1 (by omega)) hi.order) ?_
429  intro next e ⟨hnext, n, m, hlen, hm1, hm2, H, H', hn', hm', hnm, hlen', hm1', hm2', he,
430    hsize, htailn, htailm, horder, hvalid, hinj, hcount⟩
431  subst e
432  let mid := btParentState tk { d with heap := H, heap_len := hlen, heap_max := hm2 } n m node
433  refine ⟨tk.arr mid, H', mid.depth, hlen, hm2, ?_, ?_, hsize, ?_⟩
434  · cases tk <;> rfl
435  · dsimp only [mid]
436    rw [btParentState_tree_size]
437    cases tk <;> rfl
438  · dsimp only [mid]
439    rw [btParentState_depth_size]
440
441/-- The full actual merge loop preserves the forest layout and exact frame.
442The singleton last root and every earlier child link follow from the
443iteration proof; none is supplied as a callee contract premise. -/
444theorem ws_btMergeLoop_forest {h0 : Heap} {id : Nat} {tk : TK} {d : DeflateState}
445    {N K : Nat} {mc node : Int32} (hi : BTForest tk N K 0 mc d node d) :
446    WS h0 id (btMergeLoop (Sp id) (.ref (tk.ref id) 0) node) d (fun next e =>
447      BTForest tk N K (K - 1) mc d next e ∧ BTForestFrame tk d e ∧ e.heap_len.toInt = 1) := by
448  let Inv : Int32 → DeflateState → Prop := fun node e =>
449    ∃ j : Nat, BTForest tk N K j mc d node e ∧ BTForestFrame tk d e ∧ j + 1 < K
450  let Q : Int32 → DeflateState → Prop := fun node e =>
451    BTForest tk N K (K - 1) mc d node e ∧ BTForestFrame tk d e ∧ e.heap_len.toInt = 1
452  unfold btMergeLoop
453  refine WS.cdoWhile2 Inv (fun _ e => e.heap_len.toInt.toNat) Q ?_
454    ⟨0, hi, BTForestFrame.refl tk d, by have := hi.queue.k2; omega⟩
455    (by have := hi.queue.len; have := hi.queue.kN; have := hi.queue.n286; dsimp only [fuel]; omega)
456  intro current e ⟨j, hj, hfr, hmore⟩
457  refine WS.mono (merge_ws_and (ws_btMergeBody_forest_inv hj hmore) (ws_btMergeBody_frame hj.queue hmore)) ?_
458  intro next e' ⟨hj', hfr'⟩
459  have hframe := hfr.trans hfr'
460  refine WS.bind' ws_rd fun got e'' ⟨hgot, he''⟩ => ?_
461  subst e''; subst got
462  have hlen := hj'.queue.len
463  have hstage := hj'.queue.stage
464  have hK := hj'.queue.k2
465  by_cases hcontinue : e'.heap_len.toInt ≥ 2
466  · have hjnext : j + 1 + 1 < K := by omega
467    refine WS.pure' (Or.inr ⟨by simp only [hcontinue, decide_true], ⟨j + 1, hj', hframe, hjnext⟩, ?_⟩)
468    have hlen0 := hj.queue.len
469    omega
470  · have hjend : j + 1 = K - 1 := by omega
471    refine WS.pure' (Or.inl ⟨by simp only [hcontinue, decide_false], ?_⟩)
472    change Q next e'
473    rw [hjend] at hj'
474    exact ⟨hj', hframe, by omega⟩
475
476
477/-- The exact prepared maximum bounds every original leaf, and is a valid
478nonnegative symbol. Nonemptiness comes from the actual two-leaf repair. -/
479theorem BTForest.max_leaf {tk : TK} {d0 d : DeflateState} {N K j : Nat} {mc node : Int32}
480    (hi : BTForest tk N K j mc d0 node d) :
481    0 ≤ mc.toInt ∧ mc.toInt < N ∧ ∀ q : Nat, 1 ≤ q → q ≤ K → Hn d0 q ≤ mc.toInt.toNat := by
482  have hlen := hi.initial_len
483  have hK2 := hi.queue.k2
484  have hmc := hi.initial.maxCode
485  have hv := hi.initial.valid 1 (by omega) (by omega)
486  have hvN : (d0.heap[1]!).toInt.toNat < N := by omega
487  rcases Math.scanMax_spec (btFreq tk d0) N with ⟨hmax, hz⟩ | ⟨v, hmax, hvN', hfreq, hz⟩
488  · exact False.elim (hv.2.2 (hz _ hvN))
489  · have hmc' : mc.toInt = v := hmc.trans hmax
490    refine ⟨by omega, by omega, ?_⟩
491    intro q hq1 hq2
492    have hvq := hi.initial.valid q hq1 (by omega)
493    have hvqN : Hn d0 q < N := by unfold Hn; omega
494    have hvbound : Hn d0 q ≤ v := by
495      by_cases he : Hn d0 q ≤ v
496      · exact he
497      · have hzq := hz (Hn d0 q) (by omega) hvqN
498        exact False.elim (hvq.2.2 hzq)
499    omega
500
501/-- Pool membership has the leaf/internal-node split required by the tree
502layout specification. It is derived from exact observations. -/
503theorem BTForest.kind {tk : TK} {d0 d : DeflateState} {N K j : Nat} {mc node : Int32}
504    (hi : BTForest tk N K j mc d0 node d) (q : Nat)
505    (hq : (1 ≤ q ∧ q ≤ K - j) ∨ (573 - 2 * j ≤ q ∧ q < 573)) :
506    Hn d q ≤ mc.toInt.toNat ∨ (N ≤ Hn d q ∧ Hn d q < N + j) := by
507  have hK : K ≤ 286 := by have := hi.queue.kN; have := hi.queue.n286; omega
508  obtain ⟨i, hiB, hei⟩ := GB.poolAt_preimage (Hn d) K j q hK hi.queue.stage hq
509  have hiB' : i < K - j + 2 * j := by have := hi.queue.stage; omega
510  rcases GB.pool_origin (Hn d) (Hn d0) (K - j) (2 * j) K N j hi.observations i hiB' with
511    ⟨a, ha, he⟩ | he
512  · have hv := hi.max_leaf.2.2 (a + 1) (by omega) (by omega)
513    rw [hei] at he
514    exact Or.inl (he ▸ hv)
515  · rw [hei] at he
516    exact Or.inr he
517
518/-- Every created internal node has a represented position below its own
519children. Queue positions satisfy this bound by the queue/tail geometry;
520retained positions satisfy the preserved placement property. -/
521theorem BTForest.internal_position {tk : TK} {d0 d : DeflateState} {N K j : Nat} {mc node : Int32}
522    (hi : BTForest tk N K j mc d0 node d) (a : Nat) (ha : a < j) :
523    ∃ q : Nat, ((1 ≤ q ∧ q ≤ K - j) ∨ (573 - 2 * j ≤ q ∧ q < 573)) ∧
524      q < 571 - 2 * a ∧ Hn d q = N + a := by
525  have hK : K ≤ 286 := by have := hi.queue.kN; have := hi.queue.n286; omega
526  have hj := hi.queue.stage
527  obtain ⟨i, hiB, hei⟩ := GB.pool_internal (Hn d) (Hn d0) (K - j) (2 * j) K N j hi.observations a ha
528  have hiB' : i < K + j := by omega
529  obtain ⟨q, hq, hval⟩ := GB.poolAt_position (Hn d) K j i hK hj hiB'
530  have hqval : Hn d q = N + a := hval.symm.trans hei
531  refine ⟨q, hq, ?_, hqval⟩
532  rcases hq with hq | hq
533  · omega
534  · have hp := hi.placement q hq.1 hq.2 (by omega)
535    rw [hqval] at hp
536    simpa only [Nat.add_sub_cancel_left] using hp
537
538/-- Every initially used leaf has a represented queue or retained-tail
539position after merging. -/
540theorem BTForest.used_position {tk : TK} {d0 d : DeflateState} {N K j : Nat} {mc node : Int32}
541    (hi : BTForest tk N K j mc d0 node d) (v : Nat) (hv : v < N) (hf : btFreq tk d0 v ≠ 0) :
542    ∃ q : Nat, ((1 ≤ q ∧ q ≤ K - j) ∨ (573 - 2 * j ≤ q ∧ q < 573)) ∧ Hn d q = v := by
543  have hK : K ≤ 286 := by have := hi.queue.kN; have := hi.queue.n286; omega
544  have hj := hi.queue.stage
545  obtain ⟨q0, hq01, hq02, hval0⟩ := hi.initial.complete v hv hf
546  have hq0K : q0 ≤ K := by have := hi.initial_len; omega
547  have hval0N : Hn d0 q0 = v := by unfold Hn; omega
548  obtain ⟨i, hiB, hei⟩ := GB.pool_leaf (Hn d) (Hn d0) (K - j) (2 * j) K N j hi.observations (q0 - 1) (by omega)
549  rw [show q0 - 1 + 1 = q0 by omega, hval0N] at hei
550  have hiB' : i < K + j := by omega
551  obtain ⟨q, hq, hval⟩ := GB.poolAt_position (Hn d) K j i hK hj hiB'
552  exact ⟨q, hq, hval.symm.trans hei⟩
553
554
555/-- The tree layout established by the actual completed heap prefix. The
556root and all children occur exactly once in the retained interval. These
557are data results used to build the bit-length generator's context. -/
558structure BTBuilt (tk : TK) (N K : Nat) (mc : Int32) (d0 d : DeflateState) : Prop where
559  k2 : 2 ≤ K
560  kN : K ≤ N
561  n286 : N ≤ 286
562  max_nonneg : 0 ≤ mc.toInt
563  heap : d.heap.size = 573
564  heap_max : d.heap_max.toInt = (574 - 2 * K : Nat)
565  heap_len : d.heap_len.toInt = 1
566  shape : GB.PShape (Hn d) (574 - 2 * K) (K - 1) N mc.toInt.toNat
567  nonneg : ∀ q : Nat, 574 - 2 * K ≤ q → q < 573 → 0 ≤ d.heap[q]!.toInt
568  capacity : N + K - 1 ≤ (tk.arr d).size
569  parent : ∀ q : Nat, 574 - 2 * K < q → q < 573 →
570    (tk.arr d)[Hn d q]!.dl = UInt16.ofNat (GB.dadP N q)
571  unused : ∀ v ≤ mc.toInt.toNat, (∀ q, 574 - 2 * K ≤ q → q < 573 → Hn d q ≠ v) → (tk.arr d)[v]!.dl = 0
572  leaf_freq : ∀ v < N, (tk.arr d)[v]!.fc = (tk.arr d0)[v]!.fc
573  frame : BTForestFrame tk d0 d
574
575/-- The actual root store converts the complete forest into the precise
576retained tree layout. Its shape, parent links and inactive-symbol lengths
577are derived from merging, not assumed as a bit-length callee contract. -/
578theorem ws_btSaveRoot_forest {h0 : Heap} {id : Nat} {tk : TK} {d0 d : DeflateState}
579    {N K : Nat} {mc node : Int32} (hi : BTForest tk N K (K - 1) mc d0 node d)
580    (hfr : BTForestFrame tk d0 d) :
581    WS h0 id (btSaveRoot (Sp id)) d (fun _ e => BTBuilt tk N K mc d0 e) := by
582  have hK2 := hi.queue.k2
583  have hKN := hi.queue.kN
584  have hNb := hi.queue.n286
585  have hN3 := hi.queue.n3
586  have hj := hi.queue.stage
587  have hsize := hi.queue.heap
588  have hlen := hi.queue.len
589  have hmax := hi.queue.max
590  have hmBounds := hi.queue.tail_bounds
591  have hmc := hi.max_leaf
592  let b := 574 - 2 * K
593  have hb2 : 2 ≤ b := by dsimp only [b]; omega
594  have hb573 : b < 573 := by dsimp only [b]; omega
595  have hbmax : d.heap_max.toInt = (b + 1 : Nat) := by dsimp only [b]; omega
596  have hbtail : 573 - 2 * (K - 1) = b + 1 := by dsimp only [b]; omega
597  have hlast := hi.last_root (by omega)
598  refine WS.mono (ws_btSaveRoot d (by omega) (by omega) (by omega) (by omega)) ?_
599  intro _ e ⟨hm, hhm, he, hsz, hroot, hframe⟩
600  have hhmB : hm.toInt = b := by omega
601  have hhmBN : hm.toInt.toNat = b := by omega
602  have hHeap : ∀ q : Nat, e.heap[q]! = if q = b then d.heap[1]! else d.heap[q]! := by
603    intro q
604    rw [he]
605    change (d.heap.set! hm.toInt.toNat d.heap[1]!)[q]! = _
606    rw [hhmBN, getD_set _ _ _ _ (by omega)]
607  have hHN : ∀ q : Nat, Hn e q = if q = b then Hn d 1 else Hn d q := by
608    intro q
609    unfold Hn
610    rw [hHeap q]
611    split <;> rfl
612  have hTree : tk.arr e = tk.arr d := by rw [he]; cases tk <;> rfl
613  have hLen : e.heap_len.toInt = 1 := by rw [he]; dsimp only; omega
614  have hMax : e.heap_max.toInt = b := by rw [he]; exact hhmB
615  have hFrame : BTForestFrame tk d e := by
616    refine ⟨tk.arr d, e.heap, d.depth, d.heap_len, hm, ?_, rfl, hsz, rfl⟩
617    rw [he]
618    cases tk <;> rfl
619  let P : Nat → Nat := fun q => if q = b then 1 else q
620  have hP : ∀ q : Nat, b ≤ q → q < 573 →
621      (1 ≤ P q ∧ P q ≤ K - (K - 1)) ∨ (573 - 2 * (K - 1) ≤ P q ∧ P q < 573) := by
622    intro q hq1 hq2
623    dsimp only [P]
624    split
625    · exact Or.inl ⟨by omega, by omega⟩
626    · exact Or.inr ⟨by omega, hq2⟩
627  have hVal : ∀ q : Nat, Hn e q = Hn d (P q) := by
628    intro q
629    rw [hHN]
630    dsimp only [P]
631    split <;> rfl
632  have hPi : ∀ q q' : Nat, b ≤ q → q < 573 → b ≤ q' → q' < 573 → P q = P q' → q = q' := by
633    intro q q' hq1 hq2 hq'1 hq'2 heq
634    dsimp only [P] at heq
635    split at heq <;> split at heq <;> omega
636  have hLift : ∀ q : Nat,
637      ((1 ≤ q ∧ q ≤ K - (K - 1)) ∨ (573 - 2 * (K - 1) ≤ q ∧ q < 573)) →
638      ∃ q' : Nat, b ≤ q' ∧ q' < 573 ∧ Hn e q' = Hn d q ∧ (q ≠ 1 → q' = q) := by
639    intro q hq
640    by_cases hq1 : q = 1
641    · refine ⟨b, by omega, hb573, ?_, ?_⟩
642      · rw [hHN, ite_eq_left rfl, hq1]
643      · intro hh; exact False.elim (hh hq1)
644    · have hqtail : b + 1 ≤ q ∧ q < 573 := by rcases hq with hq | hq <;> omega
645      refine ⟨q, by omega, hqtail.2, ?_, fun _ => rfl⟩
646      rw [hHN, ite_eq_right (by omega)]
647  have hshape : GB.PShape (Hn e) b (K - 1) N mc.toInt.toNat := by
648    refine ⟨by dsimp only [b]; omega, by omega, by omega, ?_, ?_, ?_, ?_⟩
649    · intro q q' hq1 hq2 hq'1 hq'2 heq
650      rw [hVal, hVal] at heq
651      exact hPi q q' hq1 hq2 hq'1 hq'2 (hi.injective _ _ (hP q hq1 hq2) (hP q' hq'1 hq'2) heq)
652    · intro q hq1 hq2
653      rw [hVal]
654      exact hi.kind _ (hP q hq1 hq2)
655    · rw [hHN, ite_eq_left rfl]
656      unfold Hn
657      omega
658    · intro a ha
659      obtain ⟨q, hq, hpos, hqval⟩ := hi.internal_position a ha
660      obtain ⟨q', hq'1, hq'2, hval, hsame⟩ := hLift q hq
661      refine ⟨q', hq'1, ?_, hval.trans hqval⟩
662      by_cases hq1 : q = 1
663      · have heq : q' = b := by
664          rcases hq with hq | hq
665          · have hpe := hP q' hq'1 hq'2
666            have hinj := hi.injective (P q') 1 hpe (Or.inl ⟨by omega, by omega⟩)
667              (by rw [← hVal, hval, hq1])
668            dsimp only [P] at hinj
669            split at hinj <;> omega
670          · omega
671        rw [heq]
672        dsimp only [b]
673        omega
674      · rw [hsame hq1]
675        exact hpos
676  refine ⟨hK2, hKN, hNb, hmc.1, hsz.trans hsize, hMax, hLen, hshape, ?_, ?_, ?_, ?_, ?_, hfr.trans hFrame⟩
677  · intro q hq1 hq2
678    rw [hHeap]
679    split
680    · exact (hi.queue.valid 1 (by omega) (by omega)).1
681    · exact (hi.tail_valid q (by omega) hq2).1
682  · rw [hTree]
683    exact hi.queue.tree
684  · intro q hq1 hq2
685    rw [hTree, hHN, ite_eq_right (by omega)]
686    exact hi.parent q (by omega) hq2
687  · intro v hv hnone
688    have hvN : v < N := by omega
689    have hz : btFreq tk d0 v = 0 := by
690      by_cases hz : btFreq tk d0 v = 0
691      · exact hz
692      · obtain ⟨q, hq, hqval⟩ := hi.used_position v hvN hz
693        obtain ⟨q', hq'1, hq'2, hval, hsame⟩ := hLift q hq
694        exact False.elim (hnone q' hq'1 hq'2 (hval.trans hqval))
695    rw [hTree]
696    exact hi.unused v hvN hz
697  · intro v hv
698    rw [hTree]
699    exact hi.leaf_freq v hv
700
701end Zlib.Trees.Proofs
ZLIB × LEAN

全局目录

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