REFERENCE / ZLIB × LEAN
trees.c.heap.gbtree.lean
Source snapshot ·
577193144110d94e · 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.«trees.c.heap.gbmath»
2
3/-!
4# The tree layout of `build_tree` and its clamped depths (pure)
5
6`PShape H hm J elems maxc` is the layout `build_tree` leaves in
7`heap[hm .. HEAP_SIZE)`; `Clamped … cl` says `cl` is the clamped depth that the
8first pass of `gen_bitlen` computes. Proved: the clamped Kraft identity
9(`kraft_clamped`), `bl_count[L] = exact + overflow/2` (`blC_top`), some node has
10exact depth `L` when `overflow > 0` (`exactC_pos`), and the fix-up round facts.
11-/
12
13namespace Zlib.Trees.Proofs.GB
14
15/-- The `Dad` of the node at heap position `p`: positions `572-2j` and `571-2j`
16hold the two children of node `elems + j`. -/
17def dadP (elems p : Nat) : Nat := elems + (572 - p) / 2
18
19/-- Pure shape of the tree that `build_tree` leaves in `heap[hm .. 573)`: `J ≥ 1`
20internal nodes `elems .. elems+J-1`, root `elems+J-1` at `hm = 572 - 2J`, node
21`elems+j` placed below its children `572-2j`, `571-2j`, all other entries symbols
22`≤ maxc < elems`, all entries distinct. -/
23structure PShape (H : Nat → Nat) (hm J elems maxc : Nat) : Prop where
24 hm_eq : hm + 2 * J + 1 = 573
25 J1 : 1 ≤ J
26 maxc_lt : maxc < elems
27 inj : ∀ q q', hm ≤ q → q < 573 → hm ≤ q' → q' < 573 → H q = H q' → q = q'
28 kind : ∀ q, hm ≤ q → q < 573 → H q ≤ maxc ∨ (elems ≤ H q ∧ H q < elems + J)
29 root : H hm = elems + J - 1
30 appears : ∀ j < J, ∃ q, hm ≤ q ∧ q < 571 - 2 * j ∧ H q = elems + j
31
32/-- `cl` is the clamped depth: `0` at the root, `min (cl dad + 1) L` elsewhere. -/
33structure Clamped (H : Nat → Nat) (hm J elems L : Nat) (cl : Nat → Nat) : Prop where
34 root : cl (H hm) = 0
35 step : ∀ i < 2 * J, cl (H (hm + 1 + i)) = min (cl (dadP elems (hm + 1 + i)) + 1) L
36
37section tree
38variable {H : Nat → Nat} {hm J elems maxc L : Nat} {cl : Nat → Nat}
39
40theorem PShape.dadP_eq (S : PShape H hm J elems maxc) (i : Nat) (hi : i < 2 * J) :
41 dadP elems (hm + 1 + i) = elems + (2 * J - 1 - i) / 2 := by
42 have := S.hm_eq; unfold dadP; congr 2; omega
43
44theorem Clamped.le_all (S : PShape H hm J elems maxc) (C : Clamped H hm J elems L cl) (q : Nat)
45 (h1 : hm ≤ q) (h2 : q < 573) : cl (H q) ≤ L := by
46 by_cases e : q = hm
47 · subst e; rw [C.root]; omega
48 · have := C.step (q - hm - 1) (by have := S.hm_eq; omega)
49 rw [show hm + 1 + (q - hm - 1) = q by omega] at this
50 rw [this]; exact Nat.min_le_right _ _
51
52theorem Clamped.dad_le (S : PShape H hm J elems maxc) (C : Clamped H hm J elems L cl) (i : Nat)
53 (hi : i < 2 * J) : cl (dadP elems (hm + 1 + i)) ≤ L := by
54 rw [S.dadP_eq i hi]
55 obtain ⟨q, h1, h2, e⟩ := S.appears ((2 * J - 1 - i) / 2) (by omega)
56 rw [← e]; exact C.le_all S q h1 (by omega)
57
58/-- The internal nodes, counted through the heap positions, are `elems .. elems+J-1`. -/
59theorem PShape.internal_sum (S : PShape H hm J elems maxc) (F : Nat → Nat) :
60 rs (fun i => if elems ≤ H (hm + i) then F (H (hm + i)) else 0) (2 * J + 1) =
61 rs (fun j => F (elems + j)) J := by
62 have hm_eq := S.hm_eq
63 have hP : ∀ i < 2 * J + 1, H (hm + i) < elems + J := by
64 intro i hi
65 rcases S.kind (hm + i) (by omega) (by omega) with h | h
66 · have := S.maxc_lt; omega
67 · exact h.2
68 have := rs_image (fun i => H (hm + i)) (fun v => if elems ≤ v then F v else 0) (2 * J + 1) (elems + J) hP
69 rw [this, rs_split]
70 rw [rs_eq_zero (fun v hv => by rw [ite_eq_right (by omega), Nat.mul_zero])]
71 rw [Nat.zero_add]
72 apply rs_congr
73 intro j hj
74 rw [ite_eq_left (by omega)]
75 obtain ⟨q, h1, h2, e⟩ := S.appears j hj
76 have c1 := cnt_pos (P := fun i => H (hm + i)) (m := 2 * J + 1) (i := q - hm) (by omega)
77 (by show H (hm + (q - hm)) = _; rw [show hm + (q - hm) = q by omega, e])
78 have c2 := cnt_le_one (fun i => H (hm + i)) (2 * J + 1) (elems + j)
79 (fun a b ha hb e => by have := S.inj (hm + a) (hm + b) (by omega) (by omega) (by omega) (by omega) e; omega)
80 rw [show cnt (fun i => H (hm + i)) (2 * J + 1) (elems + j) = 1 by omega, Nat.one_mul]
81
82/-- Weight of one open child slot below a node of clamped depth `x` (scaled by `2^(L+1)`). -/
83def slot (L x : Nat) : Nat := if x < L then 2 ^ (L - x) else 1
84
85theorem local_leaf (L d : Nat) (hL : 1 ≤ L) (hd : d ≤ L) :
86 2 * 2 ^ (L - min (d + 1) L) = slot L d + ind (d = L) := by
87 by_cases e : d = L
88 · rw [show min (d + 1) L = L by omega]
89 unfold slot ind
90 rw [ite_eq_right (show ¬ d < L by omega), ite_eq_left e, Nat.sub_self]
91 · rw [show min (d + 1) L = d + 1 by omega]
92 unfold slot ind
93 rw [ite_eq_left (show d < L by omega), ite_eq_right e]
94 rw [show L - d = (L - (d + 1)) + 1 by omega, Nat.pow_succ]; omega
95
96theorem local_int (L d : Nat) (hL : 1 ≤ L) (hd : d ≤ L) :
97 2 * slot L (min (d + 1) L) = slot L d + ind (d = L) := by
98 by_cases e : d = L
99 · rw [show min (d + 1) L = L by omega]
100 unfold slot ind
101 rw [ite_eq_right (Nat.lt_irrefl _), ite_eq_right (show ¬ d < L by omega), ite_eq_left e]
102 · by_cases e2 : d + 1 = L
103 · rw [show min (d + 1) L = L by omega]
104 unfold slot ind
105 rw [ite_eq_right (Nat.lt_irrefl _), ite_eq_left (show d < L by omega), ite_eq_right e, show L - d = 1 by omega]
106 · rw [show min (d + 1) L = d + 1 by omega]
107 unfold slot ind
108 rw [ite_eq_left (show d + 1 < L by omega), ite_eq_left (show d < L by omega), ite_eq_right e]
109 rw [show L - d = (L - (d + 1)) + 1 by omega, Nat.pow_succ]; omega
110
111/-- Clamped Kraft sum of the leaves, scaled by `2^L`. -/
112def kraftC (H : Nat → Nat) (hm J maxc L : Nat) (cl : Nat → Nat) : Nat :=
113 rs (fun i => if H (hm + 1 + i) ≤ maxc then 2 ^ (L - cl (H (hm + 1 + i))) else 0) (2 * J)
114
115/-- Number of nodes whose (clamped) parent depth is already `L`: `gen_bitlen`'s `overflow`. -/
116def ovfC (H : Nat → Nat) (hm J elems L : Nat) (cl : Nat → Nat) : Nat :=
117 rs (fun i => if cl (dadP elems (hm + 1 + i)) = L then 1 else 0) (2 * J)
118
119theorem PShape.internal_tail (S : PShape H hm J elems maxc) (C : Clamped H hm J elems L cl) (F : Nat → Nat) :
120 F 0 + rs (fun i => if elems ≤ H (hm + 1 + i) then F (cl (H (hm + 1 + i))) else 0) (2 * J) =
121 rs (fun j => F (cl (elems + j))) J := by
122 have hint := S.internal_sum (fun v => F (cl v))
123 rw [show 2 * J + 1 = 1 + 2 * J by omega, rs_split] at hint
124 simp only [rs_succ, rs_zero, Nat.add_zero, Nat.zero_add] at hint
125 rw [S.root, ite_eq_left (by have := S.J1; omega)] at hint
126 rw [show elems + J - 1 = H hm by rw [S.root], C.root] at hint
127 rw [← hint]
128 congr 1
129 apply rs_congr; intro i _; rw [Nat.add_assoc]
130
131/-- **Clamped Kraft identity.** `2 · Σ_leaves 2^(L - cl) = 2^(L+1) + overflow`. -/
132theorem kraft_clamped (S : PShape H hm J elems maxc) (C : Clamped H hm J elems L cl) (hL : 1 ≤ L) :
133 2 * kraftC H hm J maxc L cl = 2 ^ (L + 1) + ovfC H hm J elems L cl := by
134 have hm_eq := S.hm_eq
135 have hloc : ∀ i < 2 * J,
136 (if H (hm + 1 + i) ≤ maxc then 2 * 2 ^ (L - cl (H (hm + 1 + i))) else 0) +
137 2 * (if elems ≤ H (hm + 1 + i) then slot L (cl (H (hm + 1 + i))) else 0) =
138 slot L (cl (dadP elems (hm + 1 + i))) + (if cl (dadP elems (hm + 1 + i)) = L then 1 else 0) := by
139 intro i hi
140 have hd := C.dad_le S i hi
141 rw [C.step i hi]
142 have hk := S.kind (hm + 1 + i) (by omega) (by omega)
143 have := S.maxc_lt
144 by_cases hl : H (hm + 1 + i) ≤ maxc
145 · rw [ite_eq_left hl, ite_eq_right (by omega)]
146 have := local_leaf L _ hL hd; unfold ind at this; omega
147 · rw [ite_eq_right hl, ite_eq_left (by omega)]
148 have := local_int L _ hL hd; unfold ind at this; omega
149 have hsum := rs_congr hloc
150 rw [rs_add, rs_add, rs_mul] at hsum
151 have hpair : rs (fun i => slot L (cl (dadP elems (hm + 1 + i)))) (2 * J) =
152 2 * rs (fun j => slot L (cl (elems + j))) J := by
153 rw [rs_congr (G := fun i => (fun j => slot L (cl (elems + j))) ((2 * J - 1 - i) / 2))
154 (fun i hi => by simp only; rw [S.dadP_eq i hi])]
155 exact rs_pair (fun j => slot L (cl (elems + j))) J
156 have hint := S.internal_tail C (slot L)
157 have hs0 : slot L 0 = 2 ^ L := by unfold slot; rw [ite_eq_left (show 0 < L by omega), Nat.sub_zero]
158 rw [hs0] at hint
159 have hleaf : rs (fun i => if H (hm + 1 + i) ≤ maxc then 2 * 2 ^ (L - cl (H (hm + 1 + i))) else 0) (2 * J) =
160 2 * kraftC H hm J maxc L cl := by
161 unfold kraftC; rw [← rs_mul]; apply rs_congr; intro i _; split <;> simp
162 unfold ovfC
163 rw [Nat.pow_succ]
164 omega
165
166/-- Nodes at exact depth `L`: their parent has clamped depth `L - 1`. -/
167def exactC (H : Nat → Nat) (hm J elems L : Nat) (cl : Nat → Nat) : Nat :=
168 rs (fun i => if cl (dadP elems (hm + 1 + i)) + 1 = L then 1 else 0) (2 * J)
169
170/-- Leaves of clamped depth `b` (`bl_count[b]` after the first pass). -/
171def blC (H : Nat → Nat) (hm J maxc : Nat) (cl : Nat → Nat) (b : Nat) : Nat :=
172 rs (fun i => if H (hm + 1 + i) ≤ maxc ∧ cl (H (hm + 1 + i)) = b then 1 else 0) (2 * J)
173
174/-- `bl_count[L] = #(nodes of exact depth L) + overflow / 2`, and `overflow` is even. -/
175theorem blC_top (S : PShape H hm J elems maxc) (C : Clamped H hm J elems L cl) (hL : 1 ≤ L) :
176 ovfC H hm J elems L cl % 2 = 0 ∧
177 blC H hm J maxc cl L = exactC H hm J elems L cl + ovfC H hm J elems L cl / 2 := by
178 have hm_eq := S.hm_eq
179 have hloc : ∀ i < 2 * J,
180 (if H (hm + 1 + i) ≤ maxc ∧ cl (H (hm + 1 + i)) = L then 1 else 0) +
181 (if elems ≤ H (hm + 1 + i) then (if cl (H (hm + 1 + i)) = L then 1 else 0) else 0) =
182 (if cl (dadP elems (hm + 1 + i)) + 1 = L then 1 else 0) +
183 (if cl (dadP elems (hm + 1 + i)) = L then 1 else 0) := by
184 intro i hi
185 have hd := C.dad_le S i hi
186 have hk := S.kind (hm + 1 + i) (by omega) (by omega)
187 have := S.maxc_lt
188 rw [C.step i hi]
189 by_cases hl : H (hm + 1 + i) ≤ maxc
190 · rw [ite_eq_right (show ¬ elems ≤ H (hm + 1 + i) by omega)]
191 by_cases a : cl (dadP elems (hm + 1 + i)) + 1 = L
192 · rw [ite_eq_left ⟨hl, by omega⟩, ite_eq_left a, ite_eq_right (by omega)]
193 · by_cases b : cl (dadP elems (hm + 1 + i)) = L
194 · rw [ite_eq_left ⟨hl, by omega⟩, ite_eq_right a, ite_eq_left b]
195 · rw [ite_eq_right (fun h => by omega), ite_eq_right a, ite_eq_right b]
196 · rw [ite_eq_right (fun h => hl h.1), ite_eq_left (by omega)]
197 by_cases a : cl (dadP elems (hm + 1 + i)) + 1 = L
198 · rw [ite_eq_left (by omega), ite_eq_left a, ite_eq_right (by omega)]
199 · by_cases b : cl (dadP elems (hm + 1 + i)) = L
200 · rw [ite_eq_left (by omega), ite_eq_right a, ite_eq_left b]
201 · rw [ite_eq_right (by omega), ite_eq_right a, ite_eq_right b]
202 have hsum := rs_congr hloc
203 rw [rs_add, rs_add] at hsum
204 have hpair : rs (fun i => if cl (dadP elems (hm + 1 + i)) = L then 1 else 0) (2 * J) =
205 2 * rs (fun j => if cl (elems + j) = L then 1 else 0) J := by
206 rw [rs_congr (G := fun i => (fun j => if cl (elems + j) = L then 1 else 0) ((2 * J - 1 - i) / 2))
207 (fun i hi => by simp only; rw [S.dadP_eq i hi])]
208 exact rs_pair (fun j => if cl (elems + j) = L then 1 else 0) J
209 have hint := S.internal_tail C (fun x => if x = L then 1 else 0)
210 rw [ite_eq_right (by omega), Nat.zero_add] at hint
211 unfold blC exactC ovfC
212 constructor <;> omega
213
214/-- If some node overflows, some node has exact depth `L`. -/
215theorem exactC_pos (S : PShape H hm J elems maxc) (C : Clamped H hm J elems L cl) (hL : 1 ≤ L)
216 (hov : 0 < ovfC H hm J elems L cl) : 0 < exactC H hm J elems L cl := by
217 have hm_eq := S.hm_eq
218 have key0 : ∀ n i, i < n → i < 2 * J → cl (dadP elems (hm + 1 + i)) = L →
219 ∃ i' < 2 * J, cl (dadP elems (hm + 1 + i')) + 1 = L := by
220 intro n
221 induction n with
222 | zero => intro i hi; omega
223 | succ n ihn =>
224 intro i hin hi hcl
225 have ih : ∀ i', i' < i → i' < 2 * J → cl (dadP elems (hm + 1 + i')) = L →
226 ∃ i' < 2 * J, cl (dadP elems (hm + 1 + i')) + 1 = L :=
227 fun i' h1 => ihn i' (by omega)
228 rw [S.dadP_eq i hi] at hcl
229 obtain ⟨q, h1, h2, e⟩ := S.appears ((2 * J - 1 - i) / 2) (by omega)
230 rw [← e] at hcl
231 have hq : q ≠ hm := by intro e'; subst e'; rw [C.root] at hcl; omega
232 obtain ⟨i', rfl⟩ : ∃ i', q = hm + 1 + i' := ⟨q - hm - 1, by omega⟩
233 have hq' : i' < i := by omega
234 have := C.step i' (by omega)
235 rw [hcl] at this
236 have hd := C.dad_le S i' (by omega)
237 by_cases a : cl (dadP elems (hm + 1 + i')) + 1 = L
238 · exact ⟨i', by omega, a⟩
239 · exact ih i' hq' (by omega) (by omega)
240 obtain ⟨i, hi, hcl⟩ : ∃ i < 2 * J, cl (dadP elems (hm + 1 + i)) = L := by
241 by_cases hx : ∃ i < 2 * J, cl (dadP elems (hm + 1 + i)) = L
242 · exact hx
243 · have := rs_eq_zero (F := fun i => if cl (dadP elems (hm + 1 + i)) = L then 1 else 0) (n := 2 * J)
244 (fun i hi => by rw [ite_eq_right (fun e => hx ⟨i, hi, e⟩)])
245 unfold ovfC at hov; omega
246 obtain ⟨i', hi', e'⟩ := key0 (i + 1) i (by omega) hi hcl
247 have := le_rs (F := fun i => if cl (dadP elems (hm + 1 + i)) + 1 = L then 1 else 0) hi'
248 simp only [e', ite_true] at this
249 unfold exactC; omega
250
251/-- No leaf has clamped depth `0`. -/
252theorem blC_zero (S : PShape H hm J elems maxc) (C : Clamped H hm J elems L cl) (hL : 1 ≤ L) :
253 blC H hm J maxc cl 0 = 0 := by
254 unfold blC
255 apply rs_eq_zero; intro i hi
256 rw [ite_eq_right]; rintro ⟨-, e⟩; rw [C.step i hi] at e; omega
257
258theorem blC_high (S : PShape H hm J elems maxc) (C : Clamped H hm J elems L cl) (b : Nat) (hb : L < b) :
259 blC H hm J maxc cl b = 0 := by
260 have hm_eq := S.hm_eq
261 unfold blC
262 apply rs_eq_zero; intro i hi
263 rw [ite_eq_right]; rintro ⟨-, e⟩; have := C.le_all S (hm + 1 + i) (by omega) (by omega); omega
264
265/-- The clamped Kraft sum regrouped by length. -/
266theorem kraftC_eq (S : PShape H hm J elems maxc) (C : Clamped H hm J elems L cl) :
267 kraftC H hm J maxc L cl = rs (fun b => blC H hm J maxc cl b * 2 ^ (L - b)) (L + 1) := by
268 have hm_eq := S.hm_eq
269 unfold kraftC blC
270 exact rs_regroup (fun i => H (hm + 1 + i) ≤ maxc) (fun i => cl (H (hm + 1 + i))) (fun b => 2 ^ (L - b))
271 (2 * J) (L + 1) (fun i hi _ => by have := C.le_all S (hm + 1 + i) (by omega) (by omega); omega)
272
273/-- Number of leaves. -/
274def nLeaves (H : Nat → Nat) (hm J maxc : Nat) : Nat :=
275 rs (fun i => if H (hm + 1 + i) ≤ maxc then 1 else 0) (2 * J)
276
277theorem blC_total (S : PShape H hm J elems maxc) (C : Clamped H hm J elems L cl) :
278 rs (fun b => blC H hm J maxc cl b) (L + 1) = nLeaves H hm J maxc := by
279 have hm_eq := S.hm_eq
280 have := rs_regroup (fun i => H (hm + 1 + i) ≤ maxc) (fun i => cl (H (hm + 1 + i))) (fun _ => 1)
281 (2 * J) (L + 1) (fun i hi _ => by have := C.le_all S (hm + 1 + i) (by omega) (by omega); omega)
282 unfold nLeaves blC
283 rw [this]; apply rs_congr; intro b _; simp
284
285/-- Summing over the leaves (by position) is summing over the symbols in the tree. -/
286theorem PShape.leaf_sum (S : PShape H hm J elems maxc) (T : Nat → Prop) [DecidablePred T]
287 (hT : ∀ v ≤ maxc, T v ↔ ∃ q, hm < q ∧ q < 573 ∧ H q = v) (F : Nat → Nat) :
288 rs (fun i => if H (hm + 1 + i) ≤ maxc then F (H (hm + 1 + i)) else 0) (2 * J) =
289 rs (fun v => if T v then F v else 0) (maxc + 1) := by
290 have hm_eq := S.hm_eq
291 have hlt := S.maxc_lt
292 have hP : ∀ i < 2 * J, H (hm + 1 + i) < elems + J := by
293 intro i hi
294 rcases S.kind (hm + 1 + i) (by omega) (by omega) with h | h
295 · omega
296 · exact h.2
297 have := rs_image (fun i => H (hm + 1 + i)) (fun v => if v ≤ maxc then F v else 0) (2 * J) (elems + J) hP
298 rw [this, show elems + J = (maxc + 1) + (elems + J - (maxc + 1)) by omega, rs_split]
299 rw [rs_eq_zero (F := fun i => cnt (fun i => H (hm + 1 + i)) (2 * J) (maxc + 1 + i) *
300 (if maxc + 1 + i ≤ maxc then F (maxc + 1 + i) else 0)) (fun v _ => by rw [ite_eq_right (by omega), Nat.mul_zero]),
301 Nat.add_zero]
302 apply rs_congr
303 intro v hv
304 rw [ite_eq_left (by omega)]
305 have hinj : ∀ a b, a < 2 * J → b < 2 * J → H (hm + 1 + a) = H (hm + 1 + b) → a = b :=
306 fun a b ha hb e => by
307 have := S.inj (hm + 1 + a) (hm + 1 + b) (by omega) (by omega) (by omega) (by omega) e; omega
308 have c2 := cnt_le_one (fun i => H (hm + 1 + i)) (2 * J) v hinj
309 by_cases ht : T v
310 · rw [ite_eq_left ht]
311 obtain ⟨q, h1, h2, e⟩ := (hT v (by omega)).mp ht
312 have c1 := cnt_pos (P := fun i => H (hm + 1 + i)) (m := 2 * J) (i := q - hm - 1) (by omega)
313 (by show H (hm + 1 + (q - hm - 1)) = _; rw [show hm + 1 + (q - hm - 1) = q by omega, e])
314 rw [show cnt (fun i => H (hm + 1 + i)) (2 * J) v = 1 by omega, Nat.one_mul]
315 · rw [ite_eq_right ht]
316 have : cnt (fun i => H (hm + 1 + i)) (2 * J) v = 0 := cnt_zero (fun i hi e =>
317 ht ((hT v (by omega)).mpr ⟨hm + 1 + i, by omega, by omega, e⟩))
318 rw [this, Nat.zero_mul]
319
320theorem nLeaves_le (S : PShape H hm J elems maxc) : nLeaves H hm J maxc ≤ maxc + 1 := by
321 classical
322 have hl := S.leaf_sum (fun v => ∃ q, hm < q ∧ q < 573 ∧ H q = v) (fun _ _ => Iff.rfl) (fun _ => 1)
323 unfold nLeaves
324 rw [hl]
325 have := rs_le (n := maxc + 1) (F := fun v => if (∃ q, hm < q ∧ q < 573 ∧ H q = v) then 1 else 0)
326 (G := fun _ => 1) (fun v _ => by split <;> omega)
327 rw [rs_const] at this; omega
328
329end tree
330
331/-! ## One round of the overflow fix-up -/
332
333/-- Kraft sum of the counts `c b` (`b = 0 .. L`), scaled by `2^L`. -/
334def kc (c : Nat → Nat) (L : Nat) : Nat := rs (fun b => c b * 2 ^ (L - b)) (L + 1)
335
336theorem ind_mul (p : Prop) [Decidable p] (x : Nat) : ind p * x = if p then x else 0 := by
337 unfold ind; split <;> simp
338
339theorem rs_ind_eq (k n : Nat) (hk : k < n) : rs (fun x => ind (x = k)) n = 1 := by
340 rw [rs_congr (F := fun x => ind (x = k)) (G := fun x => if x = k then 1 else 0) (fun x _ => rfl),
341 rs_single, ite_eq_left hk]
342
343/-- One round: `c[b]--`, `c[b+1] += 2`, `c[L]--` lowers the Kraft sum by one
344and keeps the total. -/
345theorem round_kraft (c c' : Nat → Nat) (L b : Nat) (hb : b + 1 ≤ L)
346 (h : ∀ x ≤ L, c' x + ind (x = b) + ind (x = L) = c x + 2 * ind (x = b + 1)) :
347 kc c' L + 1 = kc c L ∧ rs c' (L + 1) = rs c (L + 1) := by
348 have e1 := rs_congr (n := L + 1) (F := fun x => (c' x + ind (x = b) + ind (x = L)) * 2 ^ (L - x))
349 (G := fun x => (c x + 2 * ind (x = b + 1)) * 2 ^ (L - x)) (fun x hx => by rw [h x (by omega)])
350 simp only [Nat.add_mul, Nat.mul_assoc] at e1
351 rw [rs_add, rs_add, rs_add] at e1
352 simp only [ind_mul] at e1
353 rw [rs_single _ _ _, rs_single _ _ _, ite_eq_left (by omega), ite_eq_left (by omega)] at e1
354 have e3 : rs (fun i => 2 * (if i = b + 1 then 2 ^ (L - i) else 0)) (L + 1) = 2 * 2 ^ (L - (b + 1)) := by
355 rw [rs_mul, rs_single, ite_eq_left (by omega)]
356 rw [e3] at e1
357 have e4 : 2 ^ (L - b) = 2 * 2 ^ (L - (b + 1)) := by
358 rw [show L - b = (L - (b + 1)) + 1 by omega, Nat.pow_succ]; omega
359 rw [e4, Nat.sub_self, Nat.pow_zero] at e1
360 refine ⟨by unfold kc; omega, ?_⟩
361 have e2 := rs_congr (n := L + 1) (F := fun x => c' x + ind (x = b) + ind (x = L))
362 (G := fun x => c x + 2 * ind (x = b + 1)) (fun x hx => h x (by omega))
363 rw [rs_add, rs_add, rs_add, rs_mul] at e2
364 rw [rs_ind_eq b _ (by omega), rs_ind_eq L _ (by omega), rs_ind_eq (b + 1) _ (by omega)] at e2
365 omega
366
367/-- While the Kraft sum exceeds `2^L` and there are at most `2^L` leaves, some
368length `1 ≤ b < L` is in use. -/
369theorem exists_short (c : Nat → Nat) (L R : Nat) (hR : 1 ≤ R) (hk : kc c L = 2 ^ L + R)
370 (htot : rs c (L + 1) ≤ 2 ^ L) (h0 : c 0 = 0) : ∃ b, 1 ≤ b ∧ b < L ∧ c b ≠ 0 := by
371 by_cases hx : ∃ b, 1 ≤ b ∧ b < L ∧ c b ≠ 0
372 · exact hx
373 · exfalso
374 have z : rs (fun b => c b * 2 ^ (L - b)) L = 0 := rs_eq_zero (fun b hb => by
375 by_cases e : b = 0
376 · subst e; rw [h0, Nat.zero_mul]
377 · have : c b = 0 := by
378 by_cases e' : c b = 0
379 · exact e'
380 · exact absurd ⟨b, by omega, hb, e'⟩ hx
381 rw [this, Nat.zero_mul])
382 unfold kc at hk
383 rw [rs_succ, z, Nat.sub_self, Nat.pow_zero, Nat.mul_one, Nat.zero_add] at hk
384 have := le_rs (F := c) (n := L + 1) (i := L) (by omega)
385 omega
386
387end Zlib.Trees.Proofs.GB