Skip to content
REFERENCE / ZLIB × LEAN

trees.c.heap.gbp1.lean

Source snapshot · b0f8dab79f9ac82a · 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.gbdef»
2import ZlibF.Proof.«trees.c.heap.gbclk»
3
4/-!
5# trees.c: `gen_bitlen`, the first pass
6
7The loop `for (h = heap_max + 1; h < HEAP_SIZE; h++)` stores in `tree[n].Len` the depth of each node clamped to
8`max_length`, counts the leaves into `bl_count`, counts the clamped nodes in `overflow`, and adds each leaf's
9cost to `opt_len` and `static_len`. The invariant and the clamped depths `clK` are those of the earlier attempt
10(`GenBitlenPass1.lean`, `GenBitlenBase.lean`).
11-/
12
13namespace Zlib.Trees.Proofs
14open C Zlib.Trees
15
16theorem i2u_u64 (t : Int32) (h : 0 ≤ t.toInt) : (i2u t).toUInt64 = UInt64.ofNat t.toInt.toNat := by
17  have h2 : t.toInt < 2147483648 := by
18    have := t.toInt_le
19    have e : Int32.maxValue.toInt = 2147483647 := by decide
20    omega
21  apply UInt64.toNat_inj.mp
22  unfold i2u
23  rw [UInt32.toNat_toUInt64, UInt32.toNat_ofNat', UInt64.toNat_ofNat']
24  omega
25
26theorem u16_u64 (f : UInt16) : f.toUInt64 = UInt64.ofNat f.toNat := by
27  apply UInt64.toNat_inj.mp
28  rw [UInt16.toNat_toUInt64, UInt64.toNat_ofNat']
29  have := f.toNat_lt
30  omega
31
32theorem u16i_toInt (x : UInt16) : (u16i x).toInt = x.toNat := by
33  unfold u16i
34  have := x.toNat_lt
35  rw [Int32.toInt_ofInt]
36  have : Int32.size = 4294967296 := rfl
37  rw [this, Int.bmod_eq_of_le] <;> omega
38
39/-- `s0` with `c` added, when there is a static tree. -/
40def addOpt (s0 : UInt64) : Option Nat → UInt64
41  | none => s0
42  | some c => s0 + UInt64.ofNat c
43
44/-- The record after the cost of a leaf with `fv` occurrences is added. -/
45def costAdd (e : DeflateState) (fv bits xbv : Nat) (slv : Option Nat) : DeflateState :=
46  { e with opt_len := e.opt_len + UInt64.ofNat (fv * (bits + xbv)),
47           static_len := addOpt e.static_len (slv.map fun l => fv * (l + xbv)) }
48
49
50theorem opt_add (o : UInt64) (f : UInt16) (t : Int32) (ht : 0 ≤ t.toInt) (b x : Nat) (hb : t.toInt.toNat = b + x) :
51    o + f.toUInt64 * (i2u t).toUInt64 = o + UInt64.ofNat (f.toNat * (b + x)) := by
52  rw [u16_u64, i2u_u64 t ht, hb, UInt64.ofNat_mul]
53
54theorem ws_gbTail2_null {h0 : Heap} {id : Nat} (tk : TK) (e : DeflateState) (h n bits ov xbits : Int32)
55    (hn : 0 ≤ n.toInt ∧ n.toInt < (tk.arr e).size) (hb : 0 ≤ bits.toInt ∧ bits.toInt ≤ 15)
56    (hx : 0 ≤ xbits.toInt ∧ xbits.toInt ≤ 1000) :
57    WS h0 id (gbTail2 (Sp id) (Ptr.ref (tk.ref id) 0) Ptr.null h n bits ov xbits) e (fun r e' =>
58      r = (h, ov) ∧ e' = costAdd e ((tk.arr e)[n.toInt.toNat]!).fc.toNat bits.toInt.toNat xbits.toInt.toNat none) := by
59  unfold gbTail2
60  refine WS.bind' (ws_getFc tk n.toInt hn.1 hn.2) fun f e1 ⟨hf, he1⟩ => ?_
61  subst e1; subst hf
62  refine WS.bind' (ws_iadd bits xbits (by omega) (by omega)) fun t e1 ⟨ht, he1⟩ => ?_
63  subst e1
64  refine WS.bind' (ws_md _) fun _ e1 he1 => ?_
65  subst he1
66  simp only [bne_self_eq_false, Bool.false_eq_true, ite_false]
67  refine WS.pure' ⟨rfl, ?_⟩
68  unfold costAdd
69  rw [opt_add _ _ t (by omega) bits.toInt.toNat xbits.toInt.toNat (by omega)]
70  rfl
71
72theorem ws_gbTail2_ref {h0 : Heap} {id : Nat} (tk : TK) (e : DeflateState) (r : CtDataRef) (st : Array CtData)
73    (h n bits ov xbits : Int32)
74    (hn : 0 ≤ n.toInt ∧ n.toInt < (tk.arr e).size) (hb : 0 ≤ bits.toInt ∧ bits.toInt ≤ 15)
75    (hx : 0 ≤ xbits.toInt ∧ xbits.toInt ≤ 1000) (hr : ∀ e', Space.get (setD h0 id e') r = some st)
76    (hs : n.toInt < st.size) (hl : (st[n.toInt.toNat]!).dl.toNat ≤ 15) :
77    WS h0 id (gbTail2 (Sp id) (Ptr.ref (tk.ref id) 0) (Ptr.ref r 0) h n bits ov xbits) e (fun res e' =>
78      res = (h, ov) ∧ e' = costAdd e ((tk.arr e)[n.toInt.toNat]!).fc.toNat bits.toInt.toNat xbits.toInt.toNat
79        (some ((st[n.toInt.toNat]!).dl.toNat))) := by
80  unfold gbTail2
81  refine WS.bind' (ws_getFc tk n.toInt hn.1 hn.2) fun f e1 ⟨hf, he1⟩ => ?_
82  subst e1; subst hf
83  refine WS.bind' (ws_iadd bits xbits (by omega) (by omega)) fun t e1 ⟨ht, he1⟩ => ?_
84  subst e1
85  refine WS.bind' (ws_md _) fun _ e1 he1 => ?_
86  subst he1
87  have hne : (Ptr.ref r 0 != (Ptr.null : CtDataPtr)) = true := by simp
88  simp only [hne, ite_true]
89  have hdl : WS h0 id (getDl (Ptr.ref r 0) n.toInt) { e with opt_len := e.opt_len + ((tk.arr e)[n.toInt.toNat]!).fc.toUInt64 * (i2u t).toUInt64 }
90      (fun v e' => v = (st[n.toInt.toNat]!).dl ∧ e' = { e with opt_len := e.opt_len + ((tk.arr e)[n.toInt.toNat]!).fc.toUInt64 * (i2u t).toUInt64 }) := by
91    unfold getDl
92    have := index0_ok (h := setD h0 id { e with opt_len := e.opt_len + ((tk.arr e)[n.toInt.toNat]!).fc.toUInt64 * (i2u t).toUInt64 })
93      (hr _) (i := n.toInt) hn.1 hs
94    exact WS.of_eq (by simp only [bind_app, this]; rfl) ⟨rfl, rfl⟩
95  refine WS.bind' hdl fun dl e1 ⟨hdl1, he1⟩ => ?_
96  subst e1; subst hdl1
97  refine WS.bind' (ws_iadd (u16i _) xbits (by rw [u16i_toInt]; omega) (by rw [u16i_toInt]; omega)) fun t2 e1 ⟨ht2, he1⟩ => ?_
98  subst e1
99  refine WS.bind' (ws_md _) fun _ e1 he1 => ?_
100  subst he1
101  refine WS.pure' ⟨rfl, ?_⟩
102  unfold costAdd
103  rw [u16i_toInt] at ht2
104  simp only [addOpt, Option.map, opt_add _ _ t (by omega) bits.toInt.toNat xbits.toInt.toNat (by omega),
105    opt_add _ _ t2 (by omega) (st[n.toInt.toNat]!).dl.toNat xbits.toInt.toNat (by omega)]
106
107/-- `Ptr.index` through a static array (found by `setD h0 id e` for every `e`). -/
108theorem ws_index_static {R T : Type} [Space Heap R T] [Inhabited T] {h0 : Heap} {id : Nat} (e : DeflateState)
109    (r : R) (a : Array T) (hr : ∀ e', Space.get (setD h0 id e') r = some a) (i : Int) (h1 : 0 ≤ i)
110    (h2 : i < a.size) :
111    WS h0 id (Ptr.index (Ptr.ref r 0) i) e (fun v e' => v = a[i.toNat]! ∧ e' = e) :=
112  WS.of_eq (index0_ok (hr e) h1 h2) ⟨rfl, rfl⟩
113
114@[simp] theorem tk_arr_bl_count (tk : TK) (d : DeflateState) (a : Array UInt16) :
115    tk.arr { d with bl_count := a } = tk.arr d := by cases tk <;> rfl
116
117/-- The result of the tail of the first-pass body for a leaf. -/
118def leafEff (tk : TK) (e : DeflateState) (n bits : Nat) (xbv : Nat) (slv : Option Nat) : DeflateState :=
119  costAdd { e with bl_count := e.bl_count.set! bits (e.bl_count[bits]! + 1) } ((tk.arr e)[n]!).fc.toNat bits xbv slv
120
121theorem ws_gbTail1 {h0 : Heap} {id : Nat} (tk : TK) (e : DeflateState) (stree : CtDataPtr) (extra : IPtr)
122    (mc base h n bits ov : Int32) (xbv : Nat) (slv : Option Nat) (hbase : 0 ≤ base.toInt)
123    (hn : 0 ≤ n.toInt ∧ n.toInt < (tk.arr e).size) (hb : 0 ≤ bits.toInt ∧ bits.toInt ≤ 15)
124    (hbc : e.bl_count.size = 16)
125    (hxb : (base.toInt ≤ n.toInt → n.toInt ≤ mc.toInt → ∃ (r : IRef) (ex : Array Int32), extra = Ptr.ref r 0 ∧
126        (∀ e', Space.get (setD h0 id e') r = some ex) ∧ 0 ≤ n.toInt - base.toInt ∧ n.toInt - base.toInt < ex.size ∧
127        0 ≤ (ex[(n.toInt - base.toInt).toNat]!).toInt ∧ (ex[(n.toInt - base.toInt).toNat]!).toInt ≤ 1000 ∧
128        xbv = (ex[(n.toInt - base.toInt).toNat]!).toInt.toNat) ∧
129      (n.toInt < base.toInt → xbv = 0))
130    (hst : n.toInt ≤ mc.toInt → (stree = Ptr.null ∧ slv = none) ∨ (∃ (r : CtDataRef) (st : Array CtData),
131      stree = Ptr.ref r 0 ∧
132      (∀ e', Space.get (setD h0 id e') r = some st) ∧ n.toInt < st.size ∧ (st[n.toInt.toNat]!).dl.toNat ≤ 15 ∧
133      slv = some ((st[n.toInt.toNat]!).dl.toNat)))
134    (hxsz : xbv ≤ 1000) :
135    WS h0 id (gbTail1 (Sp id) (Ptr.ref (tk.ref id) 0) stree extra mc base h n bits ov) e (fun r e' =>
136      r = (h, ov) ∧ (n.toInt ≤ mc.toInt → e' = leafEff tk e n.toInt.toNat bits.toInt.toNat xbv slv) ∧
137        (¬ n.toInt ≤ mc.toInt → e' = e)) := by
138  unfold gbTail1
139  have hnb : n.toInt ≤ 2147483647 := by
140    have := n.toInt_le
141    have e : Int32.maxValue.toInt = 2147483647 := by decide
142    omega
143  by_cases hmc : n.toInt > mc.toInt
144  · refine WS.ite' (fun _ => ?_) (fun hh => absurd hmc hh)
145    exact WS.pure' ⟨rfl, fun h' => by omega, fun _ => rfl⟩
146  · refine WS.ite' (fun hh => absurd hh hmc) (fun _ => ?_)
147    refine WS.bind' ws_pBlCount fun bc e1 ⟨hbc1, he1⟩ => ?_
148    subst e1; subst hbc1
149    refine WS.bind' (ws_index_blc bits.toInt hb.1 (by omega)) fun v e1 ⟨hv, he1⟩ => ?_
150    subst e1; subst hv
151    refine WS.bind' (ws_setAt_blc bits.toInt _ hb.1 (by omega)) fun _ e1 he1 => ?_
152    subst he1
153    have hmc' : n.toInt ≤ mc.toInt := by omega
154    have hn' : 0 ≤ n.toInt ∧ n.toInt < (tk.arr { e with bl_count := e.bl_count.set! bits.toInt.toNat (e.bl_count[bits.toInt.toNat]! + 1) }).size := by
155      rw [tk_arr_bl_count]; exact hn
156    -- the tail2 call, for a given extra-bits value
157    have fin : ∀ (x : Int32), 0 ≤ x.toInt → x.toInt ≤ 1000 → x.toInt.toNat = xbv →
158        WS h0 id (gbTail2 (Sp id) (Ptr.ref (tk.ref id) 0) stree h n bits ov x)
159          { e with bl_count := e.bl_count.set! bits.toInt.toNat (e.bl_count[bits.toInt.toNat]! + 1) }
160          (fun r e' => r = (h, ov) ∧ (n.toInt ≤ mc.toInt → e' = leafEff tk e n.toInt.toNat bits.toInt.toNat xbv slv) ∧
161            (¬ n.toInt ≤ mc.toInt → e' = e)) := by
162      intro x hx1 hx2 hx3
163      rcases hst hmc' with ⟨hs, hsl⟩ | ⟨r, st, hs, hrr, hs1, hs2, hsl⟩
164      · subst hs; subst hsl
165        refine WS.mono (ws_gbTail2_null (h0 := h0) (id := id) tk _ h n bits ov x hn' hb ⟨hx1, hx2⟩) ?_
166        intro res e' ⟨h1, h2⟩
167        refine ⟨h1, fun _ => ?_, fun hh => absurd hmc' hh⟩
168        rw [h2, tk_arr_bl_count, hx3]; rfl
169      · subst hs; subst hsl
170        refine WS.mono (ws_gbTail2_ref (h0 := h0) (id := id) tk _ r st h n bits ov x hn' hb ⟨hx1, hx2⟩ hrr hs1 hs2) ?_
171        intro res e' ⟨h1, h2⟩
172        refine ⟨h1, fun _ => ?_, fun hh => absurd hmc' hh⟩
173        rw [h2, tk_arr_bl_count, hx3]; rfl
174    by_cases hge : n.toInt ≥ base.toInt
175    · refine WS.ite' (fun _ => ?_) (fun hh => absurd hge hh)
176      obtain ⟨r, ex, hex, hrr, h0', h1', h2', h3', hxv⟩ := hxb.1 hge hmc'
177      refine WS.bind' (ws_isub n base (by omega) (by omega)) fun d' e1 ⟨hd', he1⟩ => ?_
178      subst e1
179      have hidx : d'.toInt = n.toInt - base.toInt := hd'
180      rw [hex]
181      refine WS.bind' (ws_index_static _ r ex hrr d'.toInt (by omega) (by omega)) fun x e1 ⟨hx, he1⟩ => ?_
182      subst e1; subst hx
183      refine fin _ (by rw [hidx]; exact h2') (by rw [hidx]; exact h3') (by rw [hidx]; exact hxv.symm)
184    · refine WS.ite' (fun hh => absurd hh hge) (fun _ => ?_)
185      have := hxb.2 (by omega)
186      exact fin 0 (by decide) (by decide) (by rw [this]; rfl)
187/-! ### The state of the first pass -/
188
189open Zlib.Trees.Proofs.GB
190
191/-- The record `d` with the tree array replaced and `bl_count`, `opt_len`, `static_len` set. -/
192def mkP1 (tk : TK) (d : DeflateState) (Tk : Array CtData) (Bk : Array UInt16) (O S : UInt64) : DeflateState :=
193  { tk.setArr d Tk with bl_count := Bk, opt_len := O, static_len := S }
194
195@[simp] theorem tk_arr_mkP1 (tk : TK) (d Tk Bk O S) : tk.arr (mkP1 tk d Tk Bk O S) = Tk := by
196  cases tk <;> rfl
197theorem setArr_mkP1 (tk : TK) (d Tk Bk O S A) : tk.setArr (mkP1 tk d Tk Bk O S) A = mkP1 tk d A Bk O S := by
198  cases tk <;> rfl
199theorem costAdd_mkP1 (tk : TK) (d Tk Bk O S fv bits xbv slv) :
200    costAdd (mkP1 tk d Tk Bk O S) fv bits xbv slv = mkP1 tk d Tk Bk (O + UInt64.ofNat (fv * (bits + xbv)))
201      (addOpt S (slv.map fun l => fv * (l + xbv))) := by
202  cases slv <;> rfl
203theorem bl_mkP1 (tk : TK) (d Tk Bk O S B) : ({ mkP1 tk d Tk Bk O S with bl_count := B } : DeflateState) =
204    mkP1 tk d Tk B O S := by
205  cases tk <;> rfl
206
207/-- `Tk` with the `Len` of node `v` set to `c`. -/
208def setLen (Tk : Array CtData) (v c : Nat) : Array CtData := Tk.set! v { Tk[v]! with dl := UInt16.ofNat c }
209
210/-- The nodes of the heap array, as numbers. -/
211def Hn (d : DeflateState) (q : Nat) : Nat := (d.heap[q]!).toInt.toNat
212/-- The frequency of a symbol. -/
213def frn (T : Array CtData) (v : Nat) : Nat := (T[v]!).fc.toNat
214
215/-- The state after `k` non-root positions of the first pass. -/
216def P1State (tk : TK) (d : DeflateState) (hm J elems maxc L : Nat) (xb : Nat → Nat) (slOpt : Option (Nat → Nat))
217    (k : Nat) (e : DeflateState) : Prop :=
218  ∃ (Tk : Array CtData) (Bk : Array UInt16) (O S : UInt64), e = mkP1 tk d Tk Bk O S ∧
219    O = d.opt_len + UInt64.ofNat (costP (Hn d) hm maxc (frn (tk.arr d)) (clK (Hn d) hm elems L (2 * J)) xb k) ∧
220    S = addOpt d.static_len (slOpt.map fun sl => costP (Hn d) hm maxc (frn (tk.arr d)) sl xb k) ∧
221    Tk.size = (tk.arr d).size ∧ Bk.size = 16 ∧
222    (∀ q, hm ≤ q → q ≤ hm + k → (Tk[Hn d q]!).dl = UInt16.ofNat (clK (Hn d) hm elems L (2 * J) (Hn d q))) ∧
223    (∀ i, k ≤ i → i < 2 * J → (Tk[Hn d (hm + 1 + i)]!).dl = UInt16.ofNat (dadP elems (hm + 1 + i))) ∧
224    (∀ v : Nat, (Tk[v]!).fc = ((tk.arr d)[v]!).fc) ∧
225    (∀ v : Nat, (∀ q, hm ≤ q → q < 573 → Hn d q ≠ v) → (Tk[v]!).dl = ((tk.arr d)[v]!).dl) ∧
226    (∀ b, b < 16 → Bk[b]! = UInt16.ofNat (blP (Hn d) hm maxc (clK (Hn d) hm elems L (2 * J)) k b))
227
228@[simp] theorem mkP1_bl_count (tk : TK) (d Tk Bk O S) : (mkP1 tk d Tk Bk O S).bl_count = Bk := by cases tk <;> rfl
229
230theorem mkP1_heap (tk : TK) (d Tk Bk O S) : (mkP1 tk d Tk Bk O S).heap = d.heap := by cases tk <;> rfl
231
232/-- All the preconditions of the first pass. -/
233structure P1Ctx (h0 : Heap) (id : Nat) (tk : TK) (d : DeflateState) (stree : CtDataPtr) (extra : IPtr)
234    (mc base ml : Int32) (hm J elems maxc L baseN : Nat) (xb : Nat → Nat) (slOpt : Option (Nat → Nat)) : Prop where
235  hsz : d.heap.size = 573
236  bsz : d.bl_count.size = 16
237  hnn : ∀ q, hm ≤ q → q < 573 → 0 ≤ (d.heap[q]!).toInt
238  shape : PShape (Hn d) hm J elems maxc
239  nc : elems + J ≤ (tk.arr d).size
240  tsz : (tk.arr d).size ≤ 600
241  mcv : mc.toInt = maxc
242  basev : base.toInt = baseN
243  mlv : ml.toInt = L
244  L1 : 1 ≤ L
245  L15 : L ≤ 15
246  dad : ∀ i, i < 2 * J → ((tk.arr d)[Hn d (hm + 1 + i)]!).dl = UInt16.ofNat (dadP elems (hm + 1 + i))
247  xbOK : ∀ n, n ≤ maxc → (baseN ≤ n → ∃ (r : IRef) (ex : Array Int32), extra = Ptr.ref r 0 ∧
248      (∀ e, Space.get (setD h0 id e) r = some ex) ∧ n - baseN < ex.size ∧ 0 ≤ (ex[n - baseN]!).toInt ∧
249      (ex[n - baseN]!).toInt ≤ 1000 ∧ xb n = (ex[n - baseN]!).toInt.toNat) ∧ (n < baseN → xb n = 0)
250  stOK : (stree = Ptr.null ∧ slOpt = none) ∨ ∃ (r : CtDataRef) (st : Array CtData) (sl : Nat → Nat),
251    stree = Ptr.ref r 0 ∧ slOpt = some sl ∧ (∀ e, Space.get (setD h0 id e) r = some st) ∧
252    ∀ n, n ≤ maxc → n < st.size ∧ (st[n]!).dl.toNat ≤ 15 ∧ sl n = (st[n]!).dl.toNat
253
254theorem ws_gbBody1 {h0 : Heap} {id : Nat} {tk : TK} {d : DeflateState} {stree : CtDataPtr} {extra : IPtr}
255    {mc base ml : Int32} {hm J elems maxc L baseN : Nat} {xb : Nat → Nat} {slOpt : Option (Nat → Nat)}
256    (ctx : P1Ctx h0 id tk d stree extra mc base ml hm J elems maxc L baseN xb slOpt) (k : Nat) (hk : k < 2 * J)
257    (h o : Int32) (hh : h.toInt = (hm + 1 + k : Nat)) (ho : o.toInt = ovP (Hn d) hm elems L (clK (Hn d) hm elems L (2 * J)) k)
258    (e : DeflateState) (hst : P1State tk d hm J elems maxc L xb slOpt k e) :
259    WS h0 id (gbBody1 (Sp id) (Ptr.ref (tk.ref id) 0) stree extra mc base ml (h, o)) e (fun r e' =>
260      r.1.toInt = (hm + 1 + k : Nat) ∧ r.2.toInt = ovP (Hn d) hm elems L (clK (Hn d) hm elems L (2 * J)) (k + 1) ∧
261      P1State tk d hm J elems maxc L xb slOpt (k + 1) e') := by
262  have PS := ctx.shape
263  have hm_eq := PS.hm_eq
264  have hC : Clamped (Hn d) hm J elems L (clK (Hn d) hm elems L (2 * J)) := clK_clamped PS
265  obtain ⟨Tk, Bk, O, S, rfl, hO, hS, hTs, hBs, hcl, hdad, hfc, hout, hbl⟩ := hst
266  have hq1 : hm + 1 + k < 573 := by omega
267  have hnn := ctx.hnn (hm + 1 + k) (by omega) hq1
268  have hnode : Hn d (hm + 1 + k) < elems + J := by
269    rcases PS.kind (hm + 1 + k) (by omega) hq1 with h1 | h1
270    · have := PS.maxc_lt; omega
271    · omega
272  have hdv : dadP elems (hm + 1 + k) < elems + J := by unfold dadP; omega
273  obtain ⟨q', hq'1, hq'2, hq'e⟩ := dad_pos PS k hk
274  have hCd := hC.dad_le PS k hk
275  have hsz573 := ctx.hsz
276  have hTn := ctx.nc
277  have htsz := ctx.tsz
278  have hL1 := ctx.L1
279  have hL15 := ctx.L15
280  have hmlv := ctx.mlv
281  have hbasev := ctx.basev
282  have hmcv := ctx.mcv
283  have hTk : (tk.arr (mkP1 tk d Tk Bk O S)).size = (tk.arr d).size := by rw [tk_arr_mkP1]; exact hTs
284  unfold gbBody1
285  refine WS.bind' (ws_heapAt h (by omega) (by rw [mkP1_heap]; omega)) fun n e1 ⟨hn, he1⟩ => ?_
286  subst e1
287  have hnv : n.toInt = (Hn d (hm + 1 + k) : Int) := by
288    rw [mkP1_heap] at hn
289    have : h.toInt.toNat = hm + 1 + k := by omega
290    rw [this] at hn
291    rw [hn]; unfold Hn; omega
292  have hdn := hdad k (Nat.le_refl _) hk
293  refine WS.bind' (ws_getDl tk n.toInt (by omega) (by rw [hTk]; omega)) fun a1 e1 ⟨ha1, he1⟩ => ?_
294  subst e1
295  have ha1' : a1 = UInt16.ofNat (dadP elems (hm + 1 + k)) := by
296    rw [ha1, tk_arr_mkP1]
297    have : n.toInt.toNat = Hn d (hm + 1 + k) := by omega
298    rw [this]; exact hdn
299  have hdvlt : dadP elems (hm + 1 + k) < 65536 := by omega
300  have hu1 : (u16i a1).toInt = (dadP elems (hm + 1 + k) : Int) := by
301    rw [u16i_toInt, ha1', UInt16.toNat_ofNat']; omega
302  refine WS.bind' (ws_getDl tk (u16i a1).toInt (by omega) (by rw [hTk]; omega)) fun a2 e1 ⟨ha2, he1⟩ => ?_
303  subst e1
304  have ha2' : a2 = UInt16.ofNat (clK (Hn d) hm elems L (2 * J) (dadP elems (hm + 1 + k))) := by
305    rw [ha2, tk_arr_mkP1]
306    have : (u16i a1).toInt.toNat = Hn d q' := by omega
307    rw [this]
308    have := hcl q' hq'1 (by omega)
309    rw [this, hq'e]
310  have hCdv : (u16i a2).toInt = (clK (Hn d) hm elems L (2 * J) (dadP elems (hm + 1 + k)) : Int) := by
311    rw [u16i_toInt, ha2', UInt16.toNat_ofNat']; omega
312  refine WS.bind' (ws_iadd (u16i a2) 1 (by have : (1 : Int32).toInt = 1 := rfl; omega)
313    (by have : (1 : Int32).toInt = 1 := rfl; omega)) fun bits e1 ⟨hbits, he1⟩ => ?_
314  subst e1
315  have h1i : (1 : Int32).toInt = 1 := rfl
316  have hCn : clK (Hn d) hm elems L (2 * J) (Hn d (hm + 1 + k)) =
317      min (clK (Hn d) hm elems L (2 * J) (dadP elems (hm + 1 + k)) + 1) L := hC.step k hk
318  have hCnL : 1 ≤ clK (Hn d) hm elems L (2 * J) (Hn d (hm + 1 + k)) ∧
319      clK (Hn d) hm elems L (2 * J) (Hn d (hm + 1 + k)) ≤ L := by omega
320  have hnT : Hn d (hm + 1 + k) < (tk.arr d).size := by omega
321  have hnvn : n.toInt.toNat = Hn d (hm + 1 + k) := by omega
322  have hleaf : n.toInt ≤ mc.toInt ↔ Hn d (hm + 1 + k) ≤ maxc := by rw [hnv, ctx.mcv]; omega
323  -- everything after `Len` is stored
324  have fin : ∀ (bitsv ov' : Int32), bitsv.toInt = (clK (Hn d) hm elems L (2 * J) (Hn d (hm + 1 + k)) : Int) →
325      ov'.toInt = (ovP (Hn d) hm elems L (clK (Hn d) hm elems L (2 * J)) (k + 1) : Int) →
326      WS h0 id (do setDl (Ptr.ref (tk.ref id) 0) n.toInt (i2us bitsv)
327                   gbTail1 (Sp id) (Ptr.ref (tk.ref id) 0) stree extra mc base h n bitsv ov')
328        (mkP1 tk d Tk Bk O S) (fun r e' => r.1.toInt = (hm + 1 + k : Nat) ∧
329          r.2.toInt = (ovP (Hn d) hm elems L (clK (Hn d) hm elems L (2 * J)) (k + 1) : Int) ∧
330          P1State tk d hm J elems maxc L xb slOpt (k + 1) e') := by
331    intro bitsv ov' hbv hov
332    have hbvn : 0 ≤ bitsv.toInt ∧ bitsv.toInt ≤ 15 := by omega
333    have hi2us : i2us bitsv = UInt16.ofNat (clK (Hn d) hm elems L (2 * J) (Hn d (hm + 1 + k))) := by
334      unfold i2us; rw [hbv]; congr 1; omega
335    refine WS.bind' (ws_setDl tk n.toInt (i2us bitsv) (by omega) (by rw [hTk]; omega)) fun _ e2 he2 => ?_
336    rw [setArr_mkP1, tk_arr_mkP1, hnvn, hi2us] at he2
337    change e2 = mkP1 tk d (setLen Tk (Hn d (hm + 1 + k)) (clK (Hn d) hm elems L (2 * J) (Hn d (hm + 1 + k)))) Bk O S at he2
338    subst he2
339    have hTk's : (setLen Tk (Hn d (hm + 1 + k)) (clK (Hn d) hm elems L (2 * J) (Hn d (hm + 1 + k)))).size = Tk.size :=
340      size_set! _ _ _
341    have hnTk : Hn d (hm + 1 + k) < Tk.size := by omega
342    obtain ⟨xbv, hxbv⟩ : ∃ x : Nat, x = (if Hn d (hm + 1 + k) ≤ maxc then xb (Hn d (hm + 1 + k)) else 0) := ⟨_, rfl⟩
343    obtain ⟨slv, hslv⟩ : ∃ x : Option Nat, x = slOpt.map (fun sl => if Hn d (hm + 1 + k) ≤ maxc then sl (Hn d (hm + 1 + k)) else 0) := ⟨_, rfl⟩
344    obtain ⟨Tn, hTn'⟩ : ∃ T2, T2 = setLen Tk (Hn d (hm + 1 + k)) (clK (Hn d) hm elems L (2 * J) (Hn d (hm + 1 + k))) := ⟨_, rfl⟩
345    rw [← hTn'] at hTk's ⊢
346    have hTns : Tn.size = (tk.arr d).size := by rw [hTk's]; exact hTs
347    -- facts about the new tree array
348    have getTn : ∀ v, Tn[v]! = if v = Hn d (hm + 1 + k) then
349        { Tk[Hn d (hm + 1 + k)]! with dl := UInt16.ofNat (clK (Hn d) hm elems L (2 * J) (Hn d (hm + 1 + k))) } else Tk[v]! := by
350      intro v; rw [hTn']; exact getD_set Tk _ v _ hnTk
351    have hinj : ∀ q2, hm ≤ q2 → q2 < 573 → Hn d q2 = Hn d (hm + 1 + k) → q2 = hm + 1 + k :=
352      fun q2 h1 h2 h3 => PS.inj q2 (hm + 1 + k) h1 h2 (by omega) hq1 h3
353    have Tn_cl : ∀ q2, hm ≤ q2 → q2 ≤ hm + (k + 1) → (Tn[Hn d q2]!).dl =
354        UInt16.ofNat (clK (Hn d) hm elems L (2 * J) (Hn d q2)) := by
355      intro q2 h1 h2
356      rw [getTn]
357      by_cases e : Hn d q2 = Hn d (hm + 1 + k)
358      · rw [ite_eq_left e, e]
359      · rw [ite_eq_right e]
360        have hne : q2 ≠ hm + 1 + k := fun h' => e (by rw [h'])
361        exact hcl q2 h1 (by omega)
362    have Tn_dad : ∀ i, k + 1 ≤ i → i < 2 * J → (Tn[Hn d (hm + 1 + i)]!).dl = UInt16.ofNat (dadP elems (hm + 1 + i)) := by
363      intro i h1 h2
364      rw [getTn, ite_eq_right]
365      · exact hdad i (by omega) h2
366      · intro e; have := hinj (hm + 1 + i) (by omega) (by omega) e; omega
367    have Tn_fc : ∀ v : Nat, (Tn[v]!).fc = ((tk.arr d)[v]!).fc := by
368      intro v; rw [getTn]; split
369      · rename_i e; subst e; exact hfc _
370      · exact hfc v
371    have Tn_out : ∀ v : Nat, (∀ q, hm ≤ q → q < 573 → Hn d q ≠ v) → (Tn[v]!).dl = ((tk.arr d)[v]!).dl := by
372      intro v hv; rw [getTn, ite_eq_right]
373      · exact hout v hv
374      · intro e; exact hv (hm + 1 + k) (by omega) hq1 e.symm
375    have hCn' : clK (Hn d) hm elems L (2 * J) (Hn d (hm + 1 + k)) ≤ 15 := by omega
376    have hnTn : 0 ≤ n.toInt ∧ n.toInt < (tk.arr (mkP1 tk d Tn Bk O S)).size := by
377      rw [tk_arr_mkP1, hTns]; omega
378    have hxb1000 : xbv ≤ 1000 := by
379      rw [hxbv]; split
380      · rename_i hl
381        by_cases hb : baseN ≤ Hn d (hm + 1 + k)
382        · obtain ⟨r, ex, -, -, -, -, h1, h2⟩ := (ctx.xbOK _ hl).1 hb
383          omega
384        · rw [(ctx.xbOK _ hl).2 (by omega)]; omega
385      · omega
386    have hbase0 : 0 ≤ base.toInt := by have := ctx.basev; omega
387    have tail := ws_gbTail1 (h0 := h0) (id := id) tk (mkP1 tk d Tn Bk O S) stree extra mc base h n bitsv ov' xbv slv
388      hbase0 hnTn hbvn (by rw [mkP1_bl_count]; exact hBs)
389      (by
390        constructor
391        · intro hb hl
392          have hl' : Hn d (hm + 1 + k) ≤ maxc := hleaf.mp hl
393          obtain ⟨r, ex, h1, h2, h3, h4, h5, h7⟩ := (ctx.xbOK _ hl').1 (by omega)
394          refine ⟨r, ex, h1, h2, by omega, ?_, ?_, ?_, ?_⟩
395          · have : n.toInt - base.toInt = ((Hn d (hm + 1 + k) - baseN : Nat) : Int) := by omega
396            rw [this]; omega
397          · have : (n.toInt - base.toInt).toNat = Hn d (hm + 1 + k) - baseN := by omega
398            rw [this]; exact h4
399          · have : (n.toInt - base.toInt).toNat = Hn d (hm + 1 + k) - baseN := by omega
400            rw [this]; exact h5
401          · have : (n.toInt - base.toInt).toNat = Hn d (hm + 1 + k) - baseN := by omega
402            rw [this, hxbv, ite_eq_left hl']; exact h7
403        · intro hb
404          rw [hxbv]; split
405          · rename_i hl'; exact (ctx.xbOK _ hl').2 (by omega)
406          · rfl)
407      (by
408        intro hl
409        have hl' : Hn d (hm + 1 + k) ≤ maxc := hleaf.mp hl
410        rcases ctx.stOK with ⟨h1, h2⟩ | ⟨r, st, sl, h1, h2, h3, h4⟩
411        · left; refine ⟨h1, ?_⟩; rw [hslv, h2]; rfl
412        · right
413          obtain ⟨g1, g2, g3⟩ := h4 _ hl'
414          refine ⟨r, st, h1, h3, by omega, by rw [hnvn]; exact g2, ?_⟩
415          rw [hslv, h2, hnvn]; simp [hl', g3])
416      hxb1000
417    refine WS.mono tail ?_
418    rintro r e' ⟨hr, hl1, hl2⟩
419    subst hr
420    refine ⟨by omega, hov, ?_⟩
421    have hbn : bitsv.toInt.toNat = clK (Hn d) hm elems L (2 * J) (Hn d (hm + 1 + k)) := by omega
422    have hcs := costP_succ (Hn d) hm maxc (frn (tk.arr d)) (clK (Hn d) hm elems L (2 * J)) xb k
423    have hcs2 : ∀ sl, costP (Hn d) hm maxc (frn (tk.arr d)) sl xb (k + 1) = costP (Hn d) hm maxc (frn (tk.arr d)) sl xb k +
424        (if Hn d (hm + 1 + k) ≤ maxc then frn (tk.arr d) (Hn d (hm + 1 + k)) * (sl (Hn d (hm + 1 + k)) + xb (Hn d (hm + 1 + k))) else 0) :=
425      fun sl => costP_succ (Hn d) hm maxc (frn (tk.arr d)) sl xb k
426    have hfv : ((tk.arr (mkP1 tk d Tn Bk O S))[n.toInt.toNat]!).fc.toNat = frn (tk.arr d) (Hn d (hm + 1 + k)) := by
427      rw [tk_arr_mkP1, hnvn]; unfold frn; rw [Tn_fc]
428    by_cases hl : Hn d (hm + 1 + k) ≤ maxc
429    · have he' := hl1 (hleaf.mpr hl)
430      unfold leafEff at he'
431      rw [bl_mkP1, costAdd_mkP1, hfv, hbn] at he'
432      simp only [mkP1_bl_count] at he'
433      refine ⟨Tn, Bk.set! (clK (Hn d) hm elems L (2 * J) (Hn d (hm + 1 + k))) (Bk[clK (Hn d) hm elems L (2 * J) (Hn d (hm + 1 + k))]! + 1),
434        O + UInt64.ofNat (frn (tk.arr d) (Hn d (hm + 1 + k)) * (clK (Hn d) hm elems L (2 * J) (Hn d (hm + 1 + k)) + xbv)),
435        (addOpt S (slv.map fun l => frn (tk.arr d) (Hn d (hm + 1 + k)) * (l + xbv))),
436        he', ?_, ?_, hTns, ?_, Tn_cl, Tn_dad, Tn_fc, Tn_out, ?_⟩
437      · rw [hO, hcs, ite_eq_left hl, hxbv, ite_eq_left hl, UInt64.ofNat_add]; ac_rfl
438      · rw [hS, hslv]
439        cases slOpt with
440        | none => rfl
441        | some sl =>
442          simp only [Option.map, addOpt, hcs2, ite_eq_left hl, hxbv, UInt64.ofNat_add, UInt64.add_assoc]
443      · rw [size_set!]; exact hBs
444      · intro b hb
445        rw [getD_set Bk _ b _ (by omega), blP_succ]
446        by_cases e : b = clK (Hn d) hm elems L (2 * J) (Hn d (hm + 1 + k))
447        · subst e; rw [ite_eq_left rfl, hbl _ hb, ite_eq_left ⟨hl, rfl⟩, UInt16.ofNat_add]; rfl
448        · rw [ite_eq_right e, hbl b hb, ite_eq_right (fun hh => e hh.2.symm)]; simp
449    · have he' := hl2 (fun hh => hl (hleaf.mp hh))
450      refine ⟨Tn, Bk, O, S, he', ?_, ?_, hTns, hBs, Tn_cl, Tn_dad, Tn_fc, Tn_out, ?_⟩
451      · rw [hO, hcs, ite_eq_right hl]; simp
452      · rw [hS]; cases slOpt with
453        | none => rfl
454        | some sl => simp only [Option.map, addOpt, hcs2, ite_eq_right hl, Nat.add_zero]
455      · intro b hb
456        rw [hbl b hb, blP_succ, ite_eq_right (fun hh => hl hh.1)]; simp
457  have hovs : ovP (Hn d) hm elems L (clK (Hn d) hm elems L (2 * J)) (k + 1) =
458      ovP (Hn d) hm elems L (clK (Hn d) hm elems L (2 * J)) k +
459        (if clK (Hn d) hm elems L (2 * J) (dadP elems (hm + 1 + k)) = L then 1 else 0) := rfl
460  have hovle := ovP_le (Hn d) hm elems L (clK (Hn d) hm elems L (2 * J)) k
461  refine WS.ite' (fun hgt => ?_) (fun hle => ?_)
462  · refine WS.bind' (ws_iadd o 1 (by omega) (by omega)) fun ov e1 ⟨hov, he1⟩ => ?_
463    subst e1
464    have hcd : clK (Hn d) hm elems L (2 * J) (dadP elems (hm + 1 + k)) = L := by omega
465    refine fin ml ov (by omega) (by rw [hovs, ite_eq_left hcd]; omega)
466  · have hcd : ¬ clK (Hn d) hm elems L (2 * J) (dadP elems (hm + 1 + k)) = L := by omega
467    refine fin bits o (by omega) (by rw [hovs, ite_eq_right hcd]; omega)
468
469/-- **The first pass.** From the state after `Len` of the root is zero, the pass ends with `h = HEAP_SIZE`, `overflow` the
470number of clamped nodes, and the state of `k = 2J` positions processed. -/
471theorem ws_gbPass1 {h0 : Heap} {id : Nat} {tk : TK} {d : DeflateState} {stree : CtDataPtr} {extra : IPtr}
472    {mc base ml : Int32} {hm J elems maxc L baseN : Nat} {xb : Nat → Nat} {slOpt : Option (Nat → Nat)}
473    (ctx : P1Ctx h0 id tk d stree extra mc base ml hm J elems maxc L baseN xb slOpt)
474    (h0v : Int32) (hh0 : h0v.toInt = (hm + 1 : Nat)) (e : DeflateState)
475    (hst : P1State tk d hm J elems maxc L xb slOpt 0 e) :
476    WS h0 id (gbPass1 (Sp id) (Ptr.ref (tk.ref id) 0) stree extra mc base ml h0v) e (fun r e' =>
477      r.1.toInt = 573 ∧ r.2.toInt = (ovP (Hn d) hm elems L (clK (Hn d) hm elems L (2 * J)) (2 * J) : Int) ∧
478      P1State tk d hm J elems maxc L xb slOpt (2 * J) e') := by
479  have PS := ctx.shape
480  have hm_eq := PS.hm_eq
481  unfold gbPass1
482  refine WS.cfor2 (id := id)
483    (fun (st : Int32 × Int32) e => ∃ k, k ≤ 2 * J ∧ st.1.toInt = (hm + 1 + k : Nat) ∧
484      st.2.toInt = (ovP (Hn d) hm elems L (clK (Hn d) hm elems L (2 * J)) k : Int) ∧
485      P1State tk d hm J elems maxc L xb slOpt k e)
486    (fun (st : Int32 × Int32) _ => (573 : Nat) - st.1.toInt.toNat)
487    (fun (r : Int32 × Int32) e' => r.1.toInt = 573 ∧ r.2.toInt = (ovP (Hn d) hm elems L (clK (Hn d) hm elems L (2 * J)) (2 * J) : Int) ∧
488      P1State tk d hm J elems maxc L xb slOpt (2 * J) e') ?_
489    ⟨0, by omega, by show h0v.toInt = _; omega, ?_, hst⟩ (by simp only [fuel]; omega)
490  · rintro ⟨h, o⟩ e ⟨k, hk, hh, ho, hs⟩
491    simp only at hh ho
492    refine WS.pure' ?_
493    have hH : HEAP_SIZE.toInt = 573 := rfl
494    by_cases hlt : k < 2 * J
495    · refine Or.inr ⟨?_, ?_⟩
496      · simp only [gbCond1, decide_eq_true_eq]; omega
497      · refine WS.bind' (ws_gbBody1 ctx k hlt h o hh ho e hs) fun r e1 ⟨h1, h2, h3⟩ => ?_
498        have h1i : (1 : Int32).toInt = 1 := rfl
499        refine WS.bind' (ws_iadd r.1 1 (by omega) (by omega)) fun h' e2 ⟨hh', he2⟩ => ?_
500        subst e2
501        refine WS.pure' ⟨⟨k + 1, by omega, ?_, ?_, h3⟩, ?_⟩
502        · show h'.toInt = _; omega
503        · exact h2
504        · show 573 - h'.toInt.toNat < 573 - h.toInt.toNat; omega
505    · refine Or.inl ⟨?_, ?_⟩
506      · simp only [gbCond1, decide_eq_false_iff_not]; show ¬ h.toInt < 573; omega
507      · have hk2 : k = 2 * J := by omega
508        subst hk2
509        exact ⟨by show h.toInt = 573; omega, ho, hs⟩
510  · show (0 : Int32).toInt = _
511    simp [ovP]
512
513end Zlib.Trees.Proofs
ZLIB × LEAN

Global contents

READING NOWtrees.c.heap.gbp1.lean