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

trees.c.heap.gbmath.lean

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

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

1
2/-!
3# Pure facts behind `gen_bitlen`
4
5* `rs F n = Σ_{i<n} F i` and its algebra (congruence, additivity, single
6  point, swap, image/reindexing, counting).
7* The clamped-depth identity of a Huffman tree laid out as `build_tree` lays
8  it out (`kraft_clamped`): with `ovf` the number of nodes whose depth exceeds
9  `L`, the clamped Kraft sum of the leaves is `2^L + ovf/2`, `ovf` is even, and
10  `bl_count[L] ≥ ovf/2 + 1` when `ovf > 0`.
11* One round of the overflow fix-up lowers the Kraft sum by exactly one.
12
13Everything here is about natural numbers; no heap.
14-/
15
16namespace Zlib.Trees.Proofs.GB
17
18/-! ## Finite sums -/
19
20/-- `rs F n = F 0 + … + F (n-1)`. -/
21def rs (F : Nat → Nat) : Nat → Nat
22  | 0 => 0
23  | n + 1 => rs F n + F n
24
25@[simp] theorem rs_zero (F : Nat → Nat) : rs F 0 = 0 := rfl
26theorem rs_succ (F : Nat → Nat) (n : Nat) : rs F (n + 1) = rs F n + F n := rfl
27
28theorem rs_congr {F G : Nat → Nat} {n : Nat} (h : ∀ i < n, F i = G i) : rs F n = rs G n := by
29  induction n with
30  | zero => rfl
31  | succ n ih => rw [rs_succ, rs_succ, ih (fun i hi => h i (by omega)), h n (by omega)]
32
33theorem rs_add (F G : Nat → Nat) (n : Nat) : rs (fun i => F i + G i) n = rs F n + rs G n := by
34  induction n with
35  | zero => rfl
36  | succ n ih => rw [rs_succ, rs_succ, rs_succ, ih]; omega
37
38theorem rs_mul (c : Nat) (F : Nat → Nat) (n : Nat) : rs (fun i => c * F i) n = c * rs F n := by
39  induction n with
40  | zero => simp
41  | succ n ih => rw [rs_succ, rs_succ, ih, Nat.mul_add]
42
43theorem rs_le {F G : Nat → Nat} {n : Nat} (h : ∀ i < n, F i ≤ G i) : rs F n ≤ rs G n := by
44  induction n with
45  | zero => simp
46  | succ n ih =>
47    rw [rs_succ, rs_succ]
48    have := ih (fun i hi => h i (by omega)); have := h n (by omega); omega
49
50theorem rs_eq_zero {F : Nat → Nat} {n : Nat} (h : ∀ i < n, F i = 0) : rs F n = 0 := by
51  induction n with
52  | zero => rfl
53  | succ n ih => rw [rs_succ, ih (fun i hi => h i (by omega)), h n (by omega)]
54
55theorem rs_zero_of {F : Nat → Nat} {n : Nat} (h : rs F n = 0) : ∀ i < n, F i = 0 := by
56  induction n with
57  | zero => intro i hi; omega
58  | succ n ih =>
59    rw [rs_succ] at h
60    intro i hi
61    by_cases e : i = n
62    · subst e; omega
63    · exact ih (by omega) i (by omega)
64
65theorem le_rs {F : Nat → Nat} {n i : Nat} (hi : i < n) : F i ≤ rs F n := by
66  induction n with
67  | zero => omega
68  | succ n ih =>
69    rw [rs_succ]
70    by_cases e : i = n
71    · subst e; omega
72    · have := ih (by omega); omega
73
74theorem rs_const (c n : Nat) : rs (fun _ => c) n = c * n := by
75  induction n with
76  | zero => simp
77  | succ n ih => rw [rs_succ, ih, Nat.mul_succ]
78
79/-- Splitting a range. -/
80theorem rs_split (F : Nat → Nat) (a b : Nat) : rs F (a + b) = rs F a + rs (fun i => F (a + i)) b := by
81  induction b with
82  | zero => rfl
83  | succ b ih => rw [← Nat.add_assoc, rs_succ, rs_succ, ih, Nat.add_assoc]
84
85/-- Sum of a function supported at one point. -/
86theorem rs_single (G : Nat → Nat) (k n : Nat) :
87    rs (fun i => if i = k then G i else 0) n = if k < n then G k else 0 := by
88  induction n with
89  | zero => simp
90  | succ n ih =>
91    rw [rs_succ, ih]
92    by_cases e : n = k
93    · subst e; simp
94    · rw [ite_eq_right e]
95      by_cases h1 : k < n
96      · rw [ite_eq_left h1, ite_eq_left (by omega)]; rfl
97      · rw [ite_eq_right h1, ite_eq_right (by omega)]
98
99theorem rs_single' (G : Nat → Nat) (k n : Nat) (hk : k < n) :
100    rs (fun i => if k = i then G i else 0) n = G k := by
101  rw [rs_congr (G := fun i => if i = k then G i else 0) (fun i _ => by
102    by_cases e : i = k
103    · subst e; simp
104    · rw [ite_eq_right (Ne.symm e), ite_eq_right e])]
105  rw [rs_single, ite_eq_left hk]
106
107theorem rs_swap (F : Nat → Nat → Nat) (m n : Nat) :
108    rs (fun b => rs (fun p => F b p) m) n = rs (fun p => rs (fun b => F b p) n) m := by
109  induction n with
110  | zero => simp only [rs_zero]; exact (rs_eq_zero (fun _ _ => rfl)).symm
111  | succ n ih =>
112    rw [rs_succ, ih]
113    rw [show (fun p => rs (fun b => F b p) (n + 1)) = (fun p => rs (fun b => F b p) n + F n p) from rfl]
114    rw [rs_add]
115
116/-- Changing one term. -/
117theorem rs_upd {F G : Nat → Nat} {n k : Nat} (hk : k < n) (h : ∀ i < n, i ≠ k → F i = G i) :
118    rs F n + G k = rs G n + F k := by
119  induction n with
120  | zero => omega
121  | succ n ih =>
122    rw [rs_succ, rs_succ]
123    by_cases e : k = n
124    · subst e
125      rw [rs_congr (fun i hi => h i (by omega) (by omega))]; omega
126    · have := ih (by omega) (fun i hi hne => h i (by omega) hne)
127      rw [h n (by omega) (Ne.symm e)]; omega
128
129/-- All terms `≤ 1` and the sum is `n`: every term is `1`. -/
130theorem rs_all_one {F : Nat → Nat} {n : Nat} (hle : ∀ i < n, F i ≤ 1) (hs : rs F n = n) :
131    ∀ i < n, F i = 1 := by
132  induction n with
133  | zero => intro i hi; omega
134  | succ n ih =>
135    rw [rs_succ] at hs
136    have h1 := hle n (by omega)
137    have h2 : rs F n ≤ n := by
138      have := rs_le (n := n) (G := fun _ => 1) (fun i hi => hle i (by omega)); rw [rs_const] at this; omega
139    intro i hi
140    by_cases e : i = n
141    · subst e; omega
142    · exact ih (fun j hj => hle j (by omega)) (by omega) i (by omega)
143
144/-- Indicator. -/
145def ind (p : Prop) [Decidable p] : Nat := if p then 1 else 0
146
147theorem ind_le (p : Prop) [Decidable p] : ind p ≤ 1 := by unfold ind; split <;> omega
148
149/-! ## Counting and reindexing -/
150
151/-- Number of `i < m` with `P i = v`. -/
152def cnt (P : Nat → Nat) (m v : Nat) : Nat := rs (fun i => if P i = v then 1 else 0) m
153
154/-- **Image lemma.** Summing `F ∘ P` over `i < m` is summing `F v` weighted by
155the multiplicity of `v` among `P 0, …, P (m-1)`. -/
156theorem rs_image (P F : Nat → Nat) (m N : Nat) (hP : ∀ i < m, P i < N) :
157    rs (fun i => F (P i)) m = rs (fun v => cnt P m v * F v) N := by
158  induction m with
159  | zero =>
160    simp only [rs_zero]
161    exact (rs_eq_zero (fun v _ => by simp [cnt])).symm
162  | succ m ih =>
163    rw [rs_succ, ih (fun i hi => hP i (by omega))]
164    have e : (fun v => cnt P (m + 1) v * F v) =
165        (fun v => cnt P m v * F v + (if v = P m then F v else 0)) := by
166      funext v; simp only [cnt, rs_succ]
167      by_cases e : P m = v
168      · subst e; simp [Nat.add_mul]
169      · rw [ite_eq_right e, ite_eq_right (Ne.symm e)]; simp
170    rw [e, rs_add, rs_single, ite_eq_left (hP m (by omega))]
171
172theorem cnt_le_one (P : Nat → Nat) (m v : Nat)
173    (hinj : ∀ i j, i < m → j < m → P i = P j → i = j) : cnt P m v ≤ 1 := by
174  induction m with
175  | zero => simp [cnt]
176  | succ m ih =>
177    simp only [cnt, rs_succ] at *
178    have ih' := ih (fun i j hi hj e => hinj i j (by omega) (by omega) e)
179    by_cases e : P m = v
180    · rw [ite_eq_left e]
181      have : rs (fun i => if P i = v then 1 else 0) m = 0 := rs_eq_zero (fun i hi => by
182        rw [ite_eq_right]; intro e'; have := hinj i m (by omega) (by omega) (e'.trans e.symm); omega)
183      omega
184    · rw [ite_eq_right e]; omega
185
186theorem cnt_pos {P : Nat → Nat} {m v i : Nat} (hi : i < m) (e : P i = v) : 1 ≤ cnt P m v := by
187  have := le_rs (F := fun i => if P i = v then 1 else 0) hi
188  simp only [e, ite_true] at this; exact this
189
190theorem cnt_zero {P : Nat → Nat} {m v : Nat} (h : ∀ i < m, P i ≠ v) : cnt P m v = 0 :=
191  rs_eq_zero (fun i hi => by rw [ite_eq_right (h i hi)])
192
193theorem cnt_exists {P : Nat → Nat} {m v : Nat} (h : 1 ≤ cnt P m v) : ∃ i < m, P i = v := by
194  by_cases hx : ∃ i < m, P i = v
195  · exact hx
196  · have := cnt_zero (P := P) (m := m) (v := v) (fun i hi e => hx ⟨i, hi, e⟩); omega
197
198/-- Pigeonhole: an injective map from `m` points into `N` values has `m ≤ N`. -/
199theorem inj_le (P : Nat → Nat) (m N : Nat) (hP : ∀ i < m, P i < N)
200    (hinj : ∀ i j, i < m → j < m → P i = P j → i = j) : m ≤ N := by
201  have := rs_image P (fun _ => 1) m N hP
202  rw [rs_const] at this
203  have h2 : rs (fun v => cnt P m v * 1) N ≤ rs (fun _ => 1) N :=
204    rs_le (fun v _ => by have := cnt_le_one P m v hinj; omega)
205  rw [rs_const] at h2; omega
206
207/-- An injective self-map of `[0, n)` hits every point. -/
208theorem inj_surj (P : Nat → Nat) (n : Nat) (hP : ∀ i < n, P i < n)
209    (hinj : ∀ i j, i < n → j < n → P i = P j → i = j) : ∀ v < n, ∃ i < n, P i = v := by
210  have h1 := rs_image P (fun _ => 1) n n hP
211  rw [rs_const] at h1
212  have := rs_all_one (F := fun v => cnt P n v) (n := n) (fun v _ => cnt_le_one P n v hinj)
213    (by rw [← rs_congr (F := fun v => cnt P n v * 1) (fun v _ => by simp)]; omega)
214  intro v hv
215  exact cnt_exists (by rw [this v hv]; exact Nat.le_refl 1)
216
217/-- Reindexing by a bijection of `[0, n)`. -/
218theorem rs_perm (σ F : Nat → Nat) (n : Nat) (hσ : ∀ i < n, σ i < n)
219    (hinj : ∀ i j, i < n → j < n → σ i = σ j → i = j) : rs (fun i => F (σ i)) n = rs F n := by
220  rw [rs_image σ F n n hσ]
221  apply rs_congr
222  intro v hv
223  obtain ⟨i, hi, e⟩ := inj_surj σ n hσ hinj v hv
224  have h1 := cnt_pos (P := σ) hi e
225  have h2 := cnt_le_one σ n v hinj
226  rw [show cnt σ n v = 1 by omega, Nat.one_mul]
227
228/-- Regrouping a sum by the value of a key `f i < B`. -/
229theorem rs_regroup (Q : Nat → Prop) [DecidablePred Q] (f W : Nat → Nat) (m B : Nat)
230    (hf : ∀ i < m, Q i → f i < B) :
231    rs (fun i => if Q i then W (f i) else 0) m =
232      rs (fun b => rs (fun i => if Q i ∧ f i = b then 1 else 0) m * W b) B := by
233  have e1 : (fun b => rs (fun i => if Q i ∧ f i = b then 1 else 0) m * W b) =
234      (fun b => rs (fun i => if Q i ∧ f i = b then W b else 0) m) := by
235    funext b
236    rw [Nat.mul_comm, ← rs_mul]
237    apply rs_congr; intro i _; split <;> simp
238  rw [e1, rs_swap]
239  apply rs_congr
240  intro i hi
241  by_cases hq : Q i
242  · rw [ite_eq_left hq]
243    rw [rs_congr (G := fun b => if f i = b then W b else 0) (fun b _ => by
244      by_cases e : f i = b
245      · rw [ite_eq_left ⟨hq, e⟩, ite_eq_left e]
246      · rw [ite_eq_right (fun h => e h.2), ite_eq_right e])]
247    rw [rs_single' W (f i) B (hf i hi hq)]
248  · rw [ite_eq_right hq]
249    exact (rs_eq_zero (fun b _ => by rw [ite_eq_right (fun h => hq h.1)])).symm
250
251/-- Pairing: `F (t/2)` summed over `t < 2J`... in the `gen_bitlen` order,
252position offset `i` belongs to pair `(2J-1-i)/2`. -/
253theorem rs_pair (F : Nat → Nat) (J : Nat) :
254    rs (fun i => F ((2 * J - 1 - i) / 2)) (2 * J) = 2 * rs F J := by
255  induction J with
256  | zero => simp
257  | succ J ih =>
258    rw [show 2 * (J + 1) = 2 + 2 * J by omega, rs_split]
259    rw [rs_congr (F := fun i => F ((2 + 2 * J - 1 - (2 + i)) / 2)) (G := fun i => F ((2 * J - 1 - i) / 2))
260      (fun i hi => by congr 1; omega)]
261    rw [ih, rs_succ]
262    simp only [rs_succ, rs_zero]
263    rw [show (2 + 2 * J - 1 - 0) / 2 = J by omega, show (2 + 2 * J - 1 - 1) / 2 = J by omega]
264    omega
265
266theorem rs_ind_add (p q : Nat → Prop) [DecidablePred p] [DecidablePred q] (n : Nat)
267    (h : ∀ i < n, ¬ (p i ∧ q i)) :
268    rs (fun i => if p i ∨ q i then 1 else 0) n =
269      rs (fun i => if p i then 1 else 0) n + rs (fun i => if q i then 1 else 0) n := by
270  rw [← rs_add]; apply rs_congr; intro i hi
271  have := h i hi
272  by_cases a : p i <;> by_cases b : q i <;> simp_all
273
274end Zlib.Trees.Proofs.GB
ZLIB × LEAN

全局目录

当前位置trees.c.heap.gbmath.lean