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

inffast.c.body-token.lean

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

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

1import ZlibF.Spec.InflateFastBodyToken
2import ZlibF.Proof.«inffast.c.length-trace»
3import ZlibF.Proof.«inffast.c.length-semantics»
4import ZlibF.Proof.«inffast.c.distance-result»
5
6set_option autoImplicit false
7
8namespace Zlib.Inffast.Proofs.BodyTokenProof
9open C Zlib.Inffast Zlib.Inffast.Spec Zlib.Inffast.Proofs ZlibF.Spec
10open Zlib.Inftrees Zlib.Inftrees.Spec ZlibF.Math.LZ77Copy
11open Zlib.Inffast.Spec.BodyToken
12open Zlib.Inffast.Spec.LengthTrace
13variable {e : Env} {c : Ctx}
14
15private theorem written_length (bytes : Array UInt8) (offset count : Nat)
16    (hc : count ≤ offset) (hb : offset ≤ bytes.size) :
17    (writtenBytes bytes offset count).length = count := by
18  simp only [writtenBytes, List.length_take, List.length_drop, Array.length_toList]
19  omega
20
21private theorem written_get (bytes : Array UInt8) (offset count i : Nat) :
22    (writtenBytes bytes offset count)[i]? =
23      if i < count then bytes[offset - count + i]? else none := by
24  simp only [writtenBytes, List.getElem?_take, List.getElem?_drop, Array.getElem?_toList]
25
26private theorem written_set_append (bytes : Array UInt8) (offset count : Nat)
27    (value : UInt8) (hc : count ≤ offset) (hb : offset < bytes.size) :
28    writtenBytes (bytes.set! offset value) (offset + 1) (count + 1) =
29      writtenBytes bytes offset count ++ [value] := by
30  apply List.ext_getElem?
31  intro i
32  rw [written_get, List.getElem?_append, written_length bytes offset count hc (by omega)]
33  have hstart : offset + 1 - (count + 1) = offset - count := by omega
34  rw [hstart]
35  by_cases hi : i < count
36  · have hne : offset ≠ offset - count + i := by omega
37    simp [hi, show i < count + 1 by omega, written_get, Array.set!_eq_setIfInBounds,
38      Array.getElem?_setIfInBounds, hne]
39  · by_cases he : i = count
40    · subst i
41      have hs : offset - count + count = offset := by omega
42      simp [show ¬ count < count by omega, show count < count + 1 by omega, hs,
43        Array.set!_eq_setIfInBounds, Array.getElem?_setIfInBounds, hb]
44    · have hn : ¬ i < count + 1 := by omega
45      have hz : i - count ≠ 0 := by omega
46      simp [hi, hn, List.getElem?_singleton, hz]
47
48
49private theorem length_base_fields (symbol : Nat) (entry : Code)
50    (lo : 257 ≤ symbol) (hi : symbol ≤ 285)
51    (meaning : DecodeSemantics.SymbolEntry LENS symbol entry) :
52    entry.op &&& 16 ≠ 0 ∧
53    (entry.op &&& 15).toNat = lengthExtras.getD (symbol - 257) 0 ∧
54    entry.val.toNat = lengthBases.getD (symbol - 257) 0 := by
55  have extrasBound : ∀ n : Fin 29, lengthExtras.getD n.val 0 ≤ 5 := by decide +kernel
56  have bound : lengthExtras.getD (symbol - 257) 0 ≤ 5 := extrasBound ⟨symbol - 257, by omega⟩
57  have fields : entry.op.toNat = 16 + lengthExtras.getD (symbol - 257) 0 ∧
58      entry.val.toNat = lengthBases.getD (symbol - 257) 0 := by
59    simpa only [DecodeSemantics.SymbolEntry, ite_true,
60      ite_eq_right (show ¬ symbol < 256 by omega), ite_eq_right (show symbol ≠ 256 by omega), ite_eq_left hi] using meaning
61  have mask : ∀ op : UInt8, 16 ≤ op.toNat → op.toNat ≤ 21 →
62      op &&& 16 ≠ 0 ∧ (op &&& 15).toNat = op.toNat - 16 := by
63    apply u8_forall
64    decide +kernel
65  have shape := mask entry.op (by omega) (by omega)
66  exact ⟨shape.1, by rw [shape.2, fields.1]; omega, fields.2⟩
67
68private theorem literal_symbol (symbol : Nat) (entry : Code) (hi : symbol ≤ 285)
69    (meaning : DecodeSemantics.SymbolEntry LENS symbol entry) (literal : entry.op = 0) :
70    symbol < 256 ∧ entry.val.toNat = symbol := by
71  by_cases small : symbol < 256
72  · have fields : entry.op = 0 ∧ entry.val.toNat = symbol := by
73      simpa only [DecodeSemantics.SymbolEntry, ite_true, ite_eq_left small] using meaning
74    exact ⟨small, fields.2⟩
75  · by_cases eob : symbol = 256
76    · subst symbol
77      have fields : entry.op = 96 ∧ entry.val = 0 := by
78        simpa [DecodeSemantics.SymbolEntry] using meaning
79      simp [literal] at fields
80    · have fields := length_base_fields symbol entry (by omega) hi meaning
81      simp [literal] at fields
82
83private theorem base_symbol (symbol : Nat) (entry : Code) (hi : symbol ≤ 285)
84    (meaning : DecodeSemantics.SymbolEntry LENS symbol entry) (base : entry.op &&& 16 ≠ 0) :
85    257 ≤ symbol := by
86  by_cases small : symbol < 256
87  · have fields : entry.op = 0 ∧ entry.val.toNat = symbol := by
88      simpa only [DecodeSemantics.SymbolEntry, ite_true, ite_eq_left small] using meaning
89    simp [fields.1] at base
90  · by_cases eob : symbol = 256
91    · subst symbol
92      have fields : entry.op = 96 ∧ entry.val = 0 := by
93        simpa [DecodeSemantics.SymbolEntry] using meaning
94      exact False.elim (base (by rw [fields.1]; decide +kernel))
95    · omega
96
97private theorem eob_symbol (symbol : Nat) (entry : Code) (hi : symbol ≤ 285)
98    (meaning : DecodeSemantics.SymbolEntry LENS symbol entry)
99    (nonzero : entry.op ≠ 0) (noBase : entry.op &&& 16 = 0) : symbol = 256 := by
100  by_cases small : symbol < 256
101  · have fields : entry.op = 0 ∧ entry.val.toNat = symbol := by
102      simpa only [DecodeSemantics.SymbolEntry, ite_true, ite_eq_left small] using meaning
103    exact False.elim (nonzero fields.1)
104  · by_cases eob : symbol = 256
105    · exact eob
106    · have fields := length_base_fields symbol entry (by omega) hi meaning
107      exact False.elim (fields.1 noBase)
108
109private theorem refill_entry_wp (hc : CtxOK e c) (A : Array UInt8) (msg : BPtr) (m : UInt32) (l : L) (i o s : Nat)
110    (hts : DistTableSafe e.DCA e.od e.s0.distbits.toNat)
111    (hls : LS e l i o) (hA : e.o0 + e.sm0.avail_out.toNat ≤ A.size) (ho : o + 258 ≤ e.o0 + e.sm0.avail_out.toNat)
112    (hAb : A.size < 2 ^ 63) (hbroke : l.broke = false) (hlen : 3 ≤ l.len.toNat ∧ l.len.toNat ≤ 258)
113    (hs6 : s + 6 ≤ e.i0 + e.sm0.avail_in.toNat) (hT : i ≤ s + 3) (hT3 : i = s + 3 → 4 ≤ l.bits.toNat) :
114    Wp (dolenRefill c l) (e.heap A msg m) (fun l' h' =>
115      DistanceEntry e c A msg m (Sg e l.hold.toNat l.bits.toNat i) i o l.len.toNat l' h') := by
116  unfold dolenRefill
117  by_cases h1 : l.bits < 15
118  · simp only [h1, ite_true]
119    have h1' : l.bits.toNat < 15 := by simpa using UInt32.lt_iff_toNat_lt.mp h1
120    have hiin : i < e.i0 + e.sm0.avail_in.toNat := by omega
121    refine Wp.bindO (pull_run e _ l i o hls (by omega) hiin (e.heap_bytes_in A msg m)) ?_
122    have hl3 := hls.pullL (by omega) hiin
123    have hs3 := Sg_pullL hls (by omega) hiin
124    have hb3 := pullL_bits l (e.IN.getD i 0) (.ref (BRef.blk e.ib) (i + 1)) hls.hb
125    have hi2 : i + 1 < e.i0 + e.sm0.avail_in.toNat := by omega
126    have hb3' : (pullL l (e.IN.getD i 0) (.ref (BRef.blk e.ib) (i + 1))).bits.toNat ≤ 22 := by
127      simp only [pullL] at hb3 ⊢; omega
128    refine Wp.bindO (pull_run e _ _ (i + 1) o hl3 hb3' hi2 (e.heap_bytes_in A msg m)) ?_
129    have hl4 := hl3.pullL hb3' hi2
130    have hs4 := Sg_pullL hl3 hb3' hi2
131    have hb4 := pullL_bits (pullL l (e.IN.getD i 0) (.ref (BRef.blk e.ib) (i + 1))) (e.IN.getD (i + 1) 0)
132      (.ref (BRef.blk e.ib) (i + 1 + 1)) hl3.hb
133    simp only [pullL] at hb3 hb4
134    have pullRoom : i + 1 + 1 + 2 ≤ e.i0 + e.sm0.avail_in.toNat ∨
135        (i + 1 + 1 + 1 ≤ e.i0 + e.sm0.avail_in.toNat ∧
136          20 ≤ (pullL (pullL l (e.IN.getD i 0) (.ref (.blk e.ib) (i + 1)))
137            (e.IN.getD (i + 1) 0) (.ref (.blk e.ib) (i + 1 + 1))).bits.toNat) := by
138      by_cases hc3 : i = s + 3
139      · right; have := hT3 hc3; simp only [pullL]; omega
140      · left; omega
141    obtain ⟨l', after, run, _⟩ := dolenDist_wp hc A msg m _ (i + 1 + 1) o hts hl4 hA ho hAb hbroke hlen
142      (by simp only [pullL]; omega) pullRoom
143    exact Wp.of_eq run ⟨_, i + 1 + 1, by omega, by omega, hl4, hbroke, rfl,
144      by simp only [pullL]; omega, pullRoom, hs4.trans hs3, run⟩
145  · simp only [h1, ite_false]
146    have h1' : 15 ≤ l.bits.toNat := by
147      have : ¬ (l.bits.toNat < 15) := fun h => h1 (UInt32.lt_iff_toNat_lt.mpr (by simpa using h))
148      omega
149    obtain ⟨l', after, run, _⟩ := dolenDist_wp hc A msg m l i o hts hls hA ho hAb hbroke hlen h1' (Or.inl (by omega))
150    exact Wp.of_eq run ⟨l, i, by omega, by omega, hls, hbroke, rfl, h1', Or.inl (by omega), rfl, run⟩
151
152private theorem ext_entry_wp (hc : CtxOK e c) (A : Array UInt8) (msg : BPtr) (m : UInt32) (l : L) (i o s : Nat)
153    (hts : DistTableSafe e.DCA e.od e.s0.distbits.toNat)
154    (hls : LS e l i o) (hA : e.o0 + e.sm0.avail_out.toNat ≤ A.size) (ho : o + 258 ≤ e.o0 + e.sm0.avail_out.toNat)
155    (hAb : A.size < 2 ^ 63) (hbroke : l.broke = false) (hx : l.op.toNat ≤ 5) (hxb : l.op.toNat ≤ l.bits.toNat)
156    (hlen : 3 ≤ l.len.toNat ∧ l.len.toNat + 2 ^ l.op.toNat ≤ 259)
157    (hs6 : s + 6 ≤ e.i0 + e.sm0.avail_in.toNat) (hT : i ≤ s + 3)
158    (hT3 : i = s + 3 → 4 + l.op.toNat ≤ l.bits.toNat) :
159    Wp (dolenExt c l) (e.heap A msg m) (fun l' h' =>
160      ∃ lx S1, readBits l.op.toNat (Sg e l.hold.toNat l.bits.toNat i) = some (lx, S1) ∧
161        DistanceEntry e c A msg m S1 i o (l.len.toNat + lx) l' h') := by
162  unfold dolenExt
163  have hxs : l.op.toNat < 32 := by omega
164  refine Wp.bindO (shl32_ok hxs) ?_
165  dsimp only
166  have hlow := hold_low32 (x := l.hold) (k := l.op) hxs
167  have hlowlt : l.hold.toNat % 2 ^ l.op.toNat < 2 ^ l.op.toNat := Nat.mod_lt _ (Nat.pow_pos (by omega))
168  have hpow : 0 < 2 ^ l.op.toNat := Nat.pow_pos (by omega)
169  have hlen' : (l.len + (l.hold.toUInt32 &&& (1 <<< l.op) - 1)).toNat = l.len.toNat + l.hold.toNat % 2 ^ l.op.toNat := by
170    rw [u32_toNat_add (by rw [hlow]; omega), hlow]
171  refine Wp.bindO (shr64_ok (x := l.hold) (n := l.op.toUInt64) (by rw [UInt32.toNat_toUInt64]; omega)) ?_
172  have hls1 : LS e (dropL l l.op) i o := hls.dropL l.op hxb (by omega)
173  have hbn := dropL_bits l l.op hxb
174  have hrb := readBits_bitsOfNat l.op.toNat l.bits.toNat l.hold.toNat (inBits e i) hxb
175  have hsg := Sg_dropL (e := e) l l.op i hxb (by omega)
176  refine Wp.mono (refill_entry_wp hc A msg m
177    { in_ := l.in_, out := l.out, hold := l.hold >>> l.op.toUInt64, bits := l.bits - l.op, here := l.here, op := l.op,
178      len := l.len + (l.hold.toUInt32 &&& (1 <<< l.op) - 1), dist := l.dist, from_ := l.from_, broke := l.broke,
179      againL := l.againL, againD := l.againD } i o s hts (LS.congr hls1 rfl rfl rfl rfl) hA ho hAb hbroke
180    (by rw [hlen']; omega) hs6 hT (by intro h3; have := hT3 h3; show 4 ≤ (l.bits - l.op).toNat; simp only [dropL] at hbn; omega)) ?_
181  intro l' h' hq
182  refine ⟨l.hold.toNat % 2 ^ l.op.toNat, Sg e (dropL l l.op).hold.toNat (dropL l l.op).bits.toNat i, ?_, ?_⟩
183  · unfold Sg; rw [hrb, dropL_hold l l.op (by omega), dropL_bits l l.op hxb]
184  · simp only [hlen'] at hq
185    exact hq
186
187
188private theorem len_entry_wp (hc : CtxOK e c) (A : Array UInt8) (msg : BPtr) (m : UInt32) (l : L) (i o s : Nat)
189    (hts : DistTableSafe e.DCA e.od e.s0.distbits.toNat)
190    (hls : LS e l i o) (hA : e.o0 + e.sm0.avail_out.toNat ≤ A.size) (ho : o + 258 ≤ e.o0 + e.sm0.avail_out.toNat)
191    (hAb : A.size < 2 ^ 63) (hbroke : l.broke = false) (hx : l.op.toNat ≤ 5)
192    (hlen : 3 ≤ l.len.toNat ∧ l.len.toNat + 2 ^ l.op.toNat ≤ 259)
193    (hs6 : s + 6 ≤ e.i0 + e.sm0.avail_in.toNat) (hT : i ≤ s + 2) (hb2 : i = s + 2 → 1 ≤ l.bits.toNat) :
194    Wp (dolenLen c l) (e.heap A msg m) (fun l' h' =>
195      ∃ i2 lx S1, i ≤ i2 ∧ i2 ≤ i + 1 ∧ readBits l.op.toNat (Sg e l.hold.toNat l.bits.toNat i) = some (lx, S1) ∧
196        DistanceEntry e c A msg m S1 i2 o (l.len.toNat + lx) l' h') := by
197  unfold dolenLen
198  by_cases h0 : l.op != 0
199  · simp only [h0, ite_true]
200    have h0' : l.op.toNat ≠ 0 := by
201      intro h; apply (by simpa using h0 : l.op ≠ 0); exact UInt32.toNat_inj.mp (by simpa using h)
202    by_cases h1 : l.bits < l.op
203    · simp only [h1, ite_true]
204      have h1' : l.bits.toNat < l.op.toNat := UInt32.lt_iff_toNat_lt.mp h1
205      have hiin : i < e.i0 + e.sm0.avail_in.toNat := by omega
206      refine Wp.bindO (pull_run e _ l i o hls (by omega) hiin (e.heap_bytes_in A msg m)) ?_
207      have hl3 := hls.pullL (by omega) hiin
208      have hs3 := Sg_pullL hls (by omega) hiin
209      have hb3 := pullL_bits l (e.IN.getD i 0) (.ref (BRef.blk e.ib) (i + 1)) hls.hb
210      refine Wp.mono (ext_entry_wp hc A msg m _ (i + 1) o s hts hl3 hA ho hAb hbroke (by simp only [pullL]; omega)
211        (by simp only [pullL] at hb3 ⊢; omega) (by simp only [pullL]; omega) hs6 (by omega)
212        (by intro h3; simp only [pullL] at hb3 ⊢; have := hb2 (by omega); omega)) ?_
213      intro l' h' hq
214      obtain ⟨lx, S1, hr, hrp⟩ := hq
215      refine ⟨i + 1, lx, S1, by omega, by omega, ?_, ?_⟩
216      · simp only [pullL] at hr hs3 ⊢; rw [hs3] at hr; exact hr
217      · simp only [pullL] at hrp ⊢; exact hrp
218    · simp only [h1, ite_false]
219      have h1' : l.op.toNat ≤ l.bits.toNat := by
220        have : ¬ (l.bits.toNat < l.op.toNat) := fun h => h1 (UInt32.lt_iff_toNat_lt.mpr h)
221        omega
222      refine Wp.mono (ext_entry_wp hc A msg m l i o s hts hls hA ho hAb hbroke hx h1' hlen hs6 (by omega)
223        (by intro h3; omega)) ?_
224      intro l' h' hq
225      obtain ⟨lx, S1, hr, hrp⟩ := hq
226      exact ⟨i, lx, S1, by omega, by omega, hr, hrp⟩
227  · simp only [h0, ite_false]
228    have h0' : l.op.toNat = 0 := by
229      have : l.op = 0 := by simpa using h0
230      rw [this]; rfl
231    refine Wp.mono (refill_entry_wp hc A msg m l i o s hts hls hA ho hAb hbroke ⟨hlen.1, by
232      have : 0 < 2 ^ l.op.toNat := Nat.pow_pos (by omega)
233      omega⟩ hs6 (by omega) (by intro h3; omega)) ?_
234    intro l' h' hq
235    refine ⟨i, 0, Sg e l.hold.toNat l.bits.toNat i, by omega, by omega, ?_, ?_⟩
236    · rw [h0']; rfl
237    · simpa using hq
238
239set_option maxHeartbeats 1000000 in
240private theorem pass_entry_wp (hc : CtxOK e c) (A : Array UInt8) (msg : BPtr) (m : UInt32)
241    (l : L) (i o s d k : Nat) (hls : LS e l i o) (hAsz : A.size = e.A0.size)
242    (ho : o + 258 ≤ e.o0 + e.sm0.avail_out.toNat) (hbroke : l.broke = false)
243    (hs6 : s + 6 ≤ e.i0 + e.sm0.avail_in.toNat) (hsi : s ≤ i) (hT : i ≤ s + 2)
244    (hb15 : 15 ≤ l.bits.toNat + d) (hbi2 : i = s + 2 → 16 ≤ l.bits.toNat + d)
245    (hhere : l.here = .ref e.rl k) (hk : k < e.LCA.size)
246    (hEb : (e.LCA.getD k default).bits.toNat ≤ l.bits.toNat)
247    (hEd : (e.LCA.getD k default).bits.toNat + d ≤ 15)
248    (hcl : (LenLink (e.LCA.getD k default) ∧ LinkOK LenLeaf e.LCA e.ol (e.LCA.getD k default)) ∨
249      LenLeaf d (e.LCA.getD k default)) :
250    Wp (dolen c l) (e.heap A msg m) (fun l' h' =>
251      (l'.againL = true ∧ l'.broke = false ∧ h' = e.heap A msg m ∧
252        LenLink (e.LCA.getD k default) ∧
253        ∃ j, j < 2 ^ (e.LCA.getD k default).op.toNat ∧
254          l'.here = .ref e.rl (e.ol + (e.LCA.getD k default).val.toNat + j) ∧
255          j = (l.hold.toNat / 2 ^ (e.LCA.getD k default).bits.toNat) % 2 ^ (e.LCA.getD k default).op.toNat ∧
256          LS e l' i o ∧ l'.bits.toNat = l.bits.toNat - (e.LCA.getD k default).bits.toNat ∧
257          Sg e l'.hold.toNat l'.bits.toNat i = (Sg e l.hold.toNat l.bits.toNat i).drop (e.LCA.getD k default).bits.toNat) ∨
258      EndWithDistanceEntry e c A msg m ((Sg e l.hold.toNat l.bits.toNat i).drop (e.LCA.getD k default).bits.toNat)
259        i o (e.LCA.getD k default) l' h') := by
260  have hA : e.o0 + e.sm0.avail_out.toNat ≤ A.size := by rw [hAsz]; exact e.hAsz
261  have hAb : A.size < 2 ^ 63 := by rw [hAsz]; exact e.hAbig
262  have hkE : e.LCA[k]'hk = e.LCA.getD k default := by simp [Array.getD_eq_getD_getElem?, hk]
263  have hld : OkOn (e.heap A msg m) (Ptr.load l.here) (e.LCA.getD k default) := by
264    rw [hhere, ← hkE]; exact Ptr.load_ok (e.heap_cget_LCA A msg m) hk
265  have hEbn : (e.LCA.getD k default).bits.toUInt32.toNat = (e.LCA.getD k default).bits.toNat := toNat32 _
266  have hEb64 : (e.LCA.getD k default).bits.toUInt32.toUInt64.toNat = (e.LCA.getD k default).bits.toNat := by simp [toNat32]
267  have hls1 := hls.dropL (e.LCA.getD k default).bits.toUInt32 (by omega) (by omega)
268  have hsg1 := Sg_dropL (e := e) l (e.LCA.getD k default).bits.toUInt32 i (by omega) (by omega)
269  rw [dolen_eq_len]
270  dsimp only
271  refine Wp.bindO hld ?_
272  refine Wp.bindO (shr64_ok (x := l.hold) (by omega)) ?_
273  refine Wp.bindO hld ?_
274  generalize e.LCA.getD k default = E at *
275  have hsg1' : Sg e (l.hold >>> E.bits.toUInt32.toUInt64).toNat (l.bits - E.bits.toUInt32).toNat i =
276      (Sg e l.hold.toNat l.bits.toNat i).drop E.bits.toNat := by
277    simpa only [dropL, hEbn] using hsg1
278  by_cases hz : (E.op.toUInt32 == 0) = true
279  · simp only [hz, ite_true]
280    refine Wp.bindO hld ?_
281    have hst : store8 l.out E.val.toUInt8 (e.heap A msg m) =
282        .ok ((), e.heap (A.set! o E.val.toUInt8) msg m) := by
283      rw [hls.hout, ← e.heap_put A (A.set! o E.val.toUInt8) msg m]
284      exact Ptr.store_ok (e.heap_bytes_ob A msg m) (e.heap_ro_ob A msg m) (by omega)
285    refine Wp.bindE hst ?_
286    refine Wp.bindO (x := Ptr.ref (BRef.blk e.ob) (o + 1)) ?_ ?_
287    · rw [hls.hout]
288      exact Ptr.add_nat_ok (e.heap_bytes_ob _ msg m) (by simp; omega)
289    · have hop : E.op = 0 := by rw [mask0] at hz; simpa using hz
290      refine Wp.pure' (Or.inr ?_)
291      refine ⟨?_, ?_⟩
292      · refine ⟨?_, rfl, Or.inl ⟨hop, hbroke, ?_, hsg1', rfl⟩⟩
293        · intro link; exact link.1 hop
294        · exact ⟨hls.hin, rfl, hls.hi0, hls.hi1, by have := hls.ho0; omega, hls1.hb, hls1.hH, hls1.hacc⟩
295      · intro bad; exact False.elim (bad.1 hop)
296  · have hz' : E.op ≠ 0 := by rw [mask0] at hz; simpa using hz
297    by_cases hb16 : (E.op.toUInt32 &&& 16 != 0) = true
298    · simp only [hz, hb16, ite_true, ite_false, Bool.false_eq_true]
299      have hb16' : E.op &&& 16 ≠ 0 := by rw [mask16] at hb16; simpa using hb16
300      have hbase : (E.op &&& 15).toNat ≤ 5 ∧ 3 ≤ E.val.toNat ∧
301          E.val.toNat + 2 ^ (E.op &&& 15).toNat ≤ 259 := by
302        rcases hcl with h | h
303        · exact False.elim (hb16' h.1.2.1)
304        · rcases h.2 with h0 | h | h
305          · exact False.elim (hz' h0)
306          · exact h.2
307          · exact False.elim (hb16' h.1)
308      refine Wp.bindO hld ?_
309      let stage : L :=
310        { in_ := l.in_, out := l.out, hold := l.hold >>> E.bits.toUInt32.toUInt64, bits := l.bits - E.bits.toUInt32,
311          here := l.here, op := E.op.toUInt32 &&& 15, len := E.val.toUInt32, dist := l.dist, from_ := l.from_,
312          broke := l.broke, againL := false, againD := l.againD }
313      obtain ⟨l', h', run, tail⟩ := len_entry_wp hc A msg m stage i o s e.hdt
314        (LS.congr hls1 rfl rfl rfl rfl) hA ho hAb hbroke
315        (by dsimp [stage]; rw [mask15]; exact hbase.1)
316        (by simpa [stage, mask15] using hbase.2) hs6 hT
317        (by intro hi; have := hbi2 hi; show 1 ≤ (l.bits - E.bits.toUInt32).toNat
318            rw [u32_toNat_sub (by omega), hEbn]; omega)
319      have oldRun := dolenLen_wp hc A msg m stage i o s e.hdt
320        (LS.congr hls1 rfl rfl rfl rfl) hA ho hAb hbroke
321        (by dsimp [stage]; rw [mask15]; exact hbase.1)
322        (by simpa [stage, mask15] using hbase.2) hs6 hT
323        (by intro hi; have := hbi2 hi; show 1 ≤ (l.bits - E.bits.toUInt32).toNat
324            rw [u32_toNat_sub (by omega), hEbn]; omega)
325      have result := Wp.at_run oldRun run
326      have hag : l'.againL = false := by simpa [stage] using dolenLen_againL run
327      refine Wp.of_eq run (Or.inr ?_)
328      refine ⟨?_, ?_⟩
329      · refine ⟨?_, hag, Or.inr (Or.inl ⟨hz', hb16', ?_⟩)⟩
330        · intro link; exact hb16' link.2.1
331        · obtain ⟨i', extra, rest, hi, hi1, read, refill⟩ := result
332          refine ⟨i', extra, rest, hi, hi1, ?_, ?_⟩
333          · simpa only [stage, mask15, hsg1'] using read
334          · simpa only [stage, UInt16.toNat_toUInt32] using refill
335      · intro _
336        obtain ⟨i', extra, rest, hi, hi1, read, distance⟩ := tail
337        refine ⟨i', extra, rest, hi, hi1, ?_, ?_⟩
338        · simpa only [stage, mask15, hsg1'] using read
339        · simpa only [stage, UInt16.toNat_toUInt32] using distance
340    · have hb16' : E.op &&& 16 = 0 := by rw [mask16] at hb16; simpa using hb16
341      by_cases hb64 : (E.op.toUInt32 &&& 64 == 0) = true
342      · simp only [hz, hb16, hb64, ite_true, ite_false, Bool.false_eq_true]
343        have hb64' : E.op &&& 64 = 0 := by rw [mask64] at hb64; simpa using hb64
344        have hl : LenLink E := ⟨hz', hb16', hb64'⟩
345        have hlk : LinkOK LenLeaf e.LCA e.ol E := by
346          rcases hcl with h | h
347          · exact h.2
348          · rcases h.2 with h0 | h | h
349            · exact False.elim (hz' h0)
350            · exact False.elim (h.1 hb16')
351            · exact False.elim (h.2 hb64')
352        refine Wp.bindO hld ?_
353        have hlc : c.lcode = .ref e.rl e.ol := by rw [hc.lcode]; exact e.hlc
354        have hop32 : E.op.toUInt32.toNat < 32 := by rw [toNat32]; have := hlk.2.2.1; omega
355        refine Wp.bindO (x := Ptr.ref e.rl (e.ol + E.val.toNat)) ?_ ?_
356        · rw [hlc]
357          exact Ptr.add_nat_ok (h := e.heap A msg m) (r := e.rl) (a := e.LCA) (off := e.ol)
358            (n := E.val.toNat) (e.heap_cget_LCA A msg m)
359            (Nat.le_trans (Nat.le_add_right _ _) hlk.2.2.2.1)
360        refine Wp.bindO (shl32_ok hop32) ?_
361        have hlow := hold_low64 (x := l.hold >>> E.bits.toUInt32.toUInt64) (k := E.op.toUInt32) hop32
362        have hjlt : (l.hold >>> E.bits.toUInt32.toUInt64).toNat % 2 ^ E.op.toUInt32.toNat < 2 ^ E.op.toNat := by
363          rw [toNat32]; exact Nat.mod_lt _ (Nat.pow_pos (by omega))
364        generalize hjd : (l.hold >>> E.bits.toUInt32.toUInt64).toNat % 2 ^ E.op.toUInt32.toNat = j at hlow hjlt
365        refine Wp.bindO (x := Ptr.ref e.rl (e.ol + E.val.toNat + j)) ?_ ?_
366        · rw [hlow]
367          exact Ptr.add_nat_ok (h := e.heap A msg m) (r := e.rl) (a := e.LCA) (off := e.ol + E.val.toNat)
368            (n := j) (e.heap_cget_LCA A msg m) (by have := hlk.2.2.2.1; omega)
369        refine Wp.pure' (Or.inl ⟨rfl, hbroke, rfl, hl, j, hjlt, rfl, ?_,
370          LS.congr hls1 rfl rfl rfl rfl, ?_, hsg1'⟩)
371        · have hshift : (l.hold >>> E.bits.toUInt32.toUInt64).toNat = l.hold.toNat / 2 ^ E.bits.toNat := by
372            rw [u64_shr (by omega), hEbn]
373          simpa only [hshift, toNat32] using hjd.symm
374        · rw [u32_toNat_sub (by omega), hEbn]
375      · simp only [hz, hb16, hb64, ite_false, Bool.false_eq_true]
376        by_cases hb32 : (E.op.toUInt32 &&& 32 != 0) = true
377        · simp only [hb32, ite_true]
378          refine Wp.bindE (e.heap_ldstate hc A msg m) ?_
379          refine Wp.bindE (e.heap_stmode hc A msg m TYPE _ rfl) ?_
380          have hb64' : E.op &&& 64 ≠ 0 := by rw [mask64] at hb64; simpa using hb64
381          have hb32' : E.op &&& 32 ≠ 0 := by rw [mask32] at hb32; simpa using hb32
382          refine Wp.pure' (Or.inr ?_)
383          refine ⟨?_, ?_⟩
384          · refine ⟨?_, rfl, Or.inr (Or.inr (Or.inl ⟨hz', hb16', hb64', hb32', rfl,
385              LS.congr hls1 rfl rfl rfl rfl, hsg1', rfl⟩))⟩
386            intro link; exact hb64' link.2.2
387          · intro bad; exact False.elim (bad.2 hb16')
388        · simp only [hb32, ite_false, Bool.false_eq_true]
389          obtain ⟨ip, hip⟩ := badData_run hc A msg m "invalid literal/length code" (by decide +kernel)
390          refine Wp.bindE hip ?_
391          have hb64' : E.op &&& 64 ≠ 0 := by rw [mask64] at hb64; simpa using hb64
392          have hb32' : E.op &&& 32 = 0 := by rw [mask32] at hb32; simpa using hb32
393          refine Wp.pure' (Or.inr ?_)
394          refine ⟨?_, ?_⟩
395          · refine ⟨?_, rfl, Or.inr (Or.inr (Or.inr ⟨hz', hb16', hb64', hb32', rfl,
396              LS.congr hls1 rfl rfl rfl rfl, hsg1', .ref (.str ip) 0, rfl⟩))⟩
397            intro link; exact hb64' link.2.2
398          · intro bad; exact False.elim (bad.2 hb16')
399
400private theorem loop_entry_wp (hc : CtxOK e c) (A : Array UInt8) (msg : BPtr) (m : UInt32)
401    (l : L) (i o s kidx : Nat) (hls : LS e l i o) (hAsz : A.size = e.A0.size)
402    (ho : o + 258 ≤ e.o0 + e.sm0.avail_out.toNat) (hbroke : l.broke = false)
403    (hs6 : s + 6 ≤ e.i0 + e.sm0.avail_in.toNat) (hsi : s ≤ i) (hT : i ≤ s + 2)
404    (hb15 : 15 ≤ l.bits.toNat) (hbi2 : i = s + 2 → 16 ≤ l.bits.toNat)
405    (hk : kidx < 2 ^ e.s0.lenbits.toNat) (hhere : l.here = .ref e.rl (e.ol + kidx)) :
406    Wp (cdoWhile (dolen c) (fun l => pure (l.againL, l)) l) (e.heap A msg m)
407      (fun l' h' => ∃ entry consumed, consumed ≤ 15 ∧
408        LengthSemantics.Look e l.hold.toNat kidx entry consumed ∧
409        EndWithDistanceEntry e c A msg m ((Sg e l.hold.toNat l.bits.toNat i).drop consumed) i o entry l' h') := by
410  obtain ⟨hR, hsz, hall⟩ := e.hlt
411  have hksz : e.ol + kidx < e.LCA.size := by omega
412  have hclass : (LenLink (e.LCA.getD (e.ol + kidx) default) ∧
413      LinkOK LenLeaf e.LCA e.ol (e.LCA.getD (e.ol + kidx) default)) ∨
414      LenLeaf 0 (e.LCA.getD (e.ol + kidx) default) := by
415    have hh := hall kidx hk
416    by_cases hl : LenLink (e.LCA.getD (e.ol + kidx) default)
417    · rw [ite_eq_left hl] at hh; exact Or.inl ⟨hl, hh⟩
418    · rw [ite_eq_right hl] at hh; exact Or.inr hh
419  have hEd0 : (e.LCA.getD (e.ol + kidx) default).bits.toNat + 0 ≤ 15 := by
420    rcases hclass with h | h
421    · exact h.2.1
422    · exact h.1
423  obtain ⟨l1, h1, run1, result1⟩ := pass_entry_wp hc A msg m l i o s 0 (e.ol + kidx) hls hAsz ho hbroke
424    hs6 hsi hT (by omega) (by intro hi; have := hbi2 hi; omega) hhere hksz (by omega) hEd0 hclass
425  generalize firstCell : e.LCA.getD (e.ol + kidx) default = first at result1 hclass hEd0
426  rcases result1 with ⟨again1, broke1, heap1, link1, j, jLt, here1, jEq, locals1, bits1, stream1⟩ | end1
427  · subst heap1
428    have links : LinkOK LenLeaf e.LCA e.ol first := by
429      rcases hclass with h | h
430      · exact h.2
431      · rcases h.2 with h0 | h | h
432        · exact False.elim (link1.1 h0)
433        · exact False.elim (h.1 link1.2.1)
434        · exact False.elim (h.2 link1.2.2)
435    have leaf := links.2.2.2.2 j jLt
436    have secondIn : e.ol + first.val.toNat + j < e.LCA.size := by have := links.2.2.2.1; omega
437    obtain ⟨l2, h2, run2, result2⟩ := pass_entry_wp hc A msg m l1 i o s first.bits.toNat
438      (e.ol + first.val.toNat + j) locals1 hAsz ho broke1 hs6 hsi hT
439      (by omega) (by intro hi; have := hbi2 hi; omega) here1 secondIn
440      (by have := leaf.1; omega) leaf.1 (Or.inr leaf)
441    rcases result2 with ⟨_, _, _, link2, _⟩ | end2
442    · rcases leaf.2 with h0 | h | h
443      · exact False.elim (link2.1 h0)
444      · exact False.elim (h.1 link2.2.1)
445      · exact False.elim (h.2 link2.2.2)
446    · have cond1 : (fun q : L => (pure (q.againL, q) : M (Bool × L))) l1 (e.heap A msg m) =
447          .ok ((true, l1), e.heap A msg m) := by simp [again1]
448      have cond2 : (fun q : L => (pure (q.againL, q) : M (Bool × L))) l2 h2 =
449          .ok ((false, l2), h2) := by simp [end2.1.2.1]
450      refine Wp.of_eq (cdoWhile_two run1 cond1 run2 cond2)
451        ⟨e.LCA.getD (e.ol + first.val.toNat + j) default,
452          first.bits.toNat + (e.LCA.getD (e.ol + first.val.toNat + j) default).bits.toNat,
453          by have := leaf.1; omega, ?_, ?_⟩
454      · exact Or.inr ⟨first, j, firstCell, link1, jLt, jEq, rfl, rfl, by have := leaf.1; omega, end2.1.1⟩
455      · simpa only [stream1, List.drop_drop] using end2
456  · have cond1 : (fun q : L => (pure (q.againL, q) : M (Bool × L))) l1 h1 =
457        .ok ((false, l1), h1) := by simp [end1.1.2.1]
458    exact Wp.of_eq (cdoWhile_one run1 cond1)
459      ⟨first, first.bits.toNat, by omega, Or.inl ⟨firstCell, rfl, end1.1.1⟩, end1⟩
460
461private theorem root_entry_wp (hc : CtxOK e c) (A : Array UInt8) (msg : BPtr) (m : UInt32)
462    (l : L) (i o s : Nat) (hls : LS e l i o) (hAsz : A.size = e.A0.size)
463    (ho : o + 258 ≤ e.o0 + e.sm0.avail_out.toNat) (hbroke : l.broke = false)
464    (hs6 : s + 6 ≤ e.i0 + e.sm0.avail_in.toNat) (hsi : s ≤ i) (hT : i ≤ s + 2)
465    (hb15 : 15 ≤ l.bits.toNat) (hbi2 : i = s + 2 → 16 ≤ l.bits.toNat) :
466    Wp (do
467      let here ← c.lcode.add (l.hold &&& c.lmask.toUInt64).toNat
468      cdoWhile (dolen c) (fun l => pure (l.againL, l)) {l with here}) (e.heap A msg m)
469      (fun l' h' => ∃ entry consumed, consumed ≤ 15 ∧
470        LengthSemantics.Look e l.hold.toNat (l.hold.toNat % 2 ^ e.s0.lenbits.toNat) entry consumed ∧
471        EndWithDistanceEntry e c A msg m ((Sg e l.hold.toNat l.bits.toNat i).drop consumed) i o entry l' h') := by
472  have hlc : c.lcode = .ref e.rl e.ol := by rw [hc.lcode]; exact e.hlc
473  have hR : e.s0.lenbits.toNat < 32 := by have := e.hlt.1; omega
474  have hmask : c.lmask.toUInt64.toNat = 2 ^ e.s0.lenbits.toNat - 1 := by
475    rw [hc.lmask, UInt32.toNat_toUInt64]; exact u32_shl1_sub1 hR
476  have hidx := u64_and_mask (x := l.hold) hmask
477  have hmod : l.hold.toNat % 2 ^ e.s0.lenbits.toNat < 2 ^ e.s0.lenbits.toNat :=
478    Nat.mod_lt _ (Nat.pow_pos (by omega))
479  refine Wp.bindO (x := Ptr.ref e.rl (e.ol + l.hold.toNat % 2 ^ e.s0.lenbits.toNat)) ?_ ?_
480  · rw [hlc, hidx]
481    exact Ptr.add_nat_ok (e.heap_cget_LCA A msg m) (by have := e.hlt.2.1; omega)
482  · exact loop_entry_wp hc A msg m _ i o s _ (LS.congr hls rfl rfl rfl rfl)
483      hAsz ho hbroke hs6 hsi hT hb15 hbi2 hmod rfl
484
485private theorem body_entry_wp (e : Env) (c : Ctx) (A : Array UInt8) (msg : BPtr) (m : UInt32)
486    (l : L) (i o : Nat) (hp : StepPre e c A l i o) :
487    Wp (inflate_fast_body c l) (e.heap A msg m) (fun l' h' =>
488      Sg e (ready e l i).1.hold.toNat (ready e l i).1.bits.toNat (ready e l i).2 =
489        Sg e l.hold.toNat l.bits.toNat i ∧
490      ∃ entry consumed, consumed ≤ 15 ∧
491        LengthSemantics.Look e (ready e l i).1.hold.toNat
492          ((ready e l i).1.hold.toNat % 2 ^ e.s0.lenbits.toNat) entry consumed ∧
493        EndWithDistanceEntry e c A msg m ((Sg e (ready e l i).1.hold.toNat (ready e l i).1.bits.toNat
494          (ready e l i).2).drop consumed) (ready e l i).2 o entry l' h') := by
495  have hc := hp.context
496  have hls := hp.locals
497  have hAsz := hp.outputSize
498  have hi6 := hp.inputRoom
499  have ho258 := hp.outputRoom
500  have hbroke := hp.notStopped
501  have trace : Wp (inflate_fast_body c l) (e.heap A msg m) (fun l' h' =>
502      Sg e (ready e l i).1.hold.toNat (ready e l i).1.bits.toNat (ready e l i).2 =
503        Sg e l.hold.toNat l.bits.toNat i ∧
504      ∃ entry consumed, consumed ≤ 15 ∧
505        LengthSemantics.Look e (ready e l i).1.hold.toNat
506          ((ready e l i).1.hold.toNat % 2 ^ e.s0.lenbits.toNat) entry consumed ∧
507        EndWithDistanceEntry e c A msg m ((Sg e (ready e l i).1.hold.toNat (ready e l i).1.bits.toNat
508          (ready e l i).2).drop consumed) (ready e l i).2 o entry l' h') := by
509    unfold inflate_fast_body
510    by_cases h1 : l.bits < 15
511    · simp only [ready, h1, ite_true]
512      have hb : l.bits.toNat < 15 := by simpa using UInt32.lt_iff_toNat_lt.mp h1
513      have hiin : i < e.i0 + e.sm0.avail_in.toNat := by omega
514      refine Wp.bindO (pull_run e _ l i o hls (by omega) hiin (e.heap_bytes_in A msg m)) ?_
515      have hl1 := hls.pullL (by omega) hiin
516      have stream1 := Sg_pullL hls (by omega) hiin
517      have hb1 := pullL_bits l (e.IN.getD i 0) (.ref (.blk e.ib) (i + 1)) hls.hb
518      have hi2 : i + 1 < e.i0 + e.sm0.avail_in.toNat := by omega
519      have hb1' : (pullL l (e.IN.getD i 0) (.ref (.blk e.ib) (i + 1))).bits.toNat ≤ 22 := by
520        simp only [pullL] at hb1 ⊢; omega
521      refine Wp.bindO (pull_run e _ _ (i + 1) o hl1 hb1' hi2 (e.heap_bytes_in A msg m)) ?_
522      have hl2 := hl1.pullL hb1' hi2
523      have stream2 := Sg_pullL hl1 hb1' hi2
524      have hb2 := pullL_bits (pullL l (e.IN.getD i 0) (.ref (.blk e.ib) (i + 1)))
525        (e.IN.getD (i + 1) 0) (.ref (.blk e.ib) (i + 1 + 1)) hl1.hb
526      refine Wp.mono (root_entry_wp hc A msg m _ (i + 1 + 1) o i hl2 hAsz ho258 hbroke hi6 (by omega) (by omega)
527        (by simp only [pullL] at hb1 hb2 ⊢; omega)
528        (by intro _; simp only [pullL] at hb1 hb2 ⊢; omega)) ?_
529      intro l' h' result
530      exact ⟨stream2.trans stream1, result⟩
531    · simp only [ready, h1, ite_false]
532      have hb : 15 ≤ l.bits.toNat := by
533        have : ¬ l.bits.toNat < 15 := fun h => h1 (UInt32.lt_iff_toNat_lt.mpr (by simpa using h))
534        omega
535      exact Wp.mono (root_entry_wp hc A msg m l i o i hls hAsz ho258 hbroke hi6 (by omega) (by omega) hb (by omega))
536        (fun _ _ result => ⟨by trivial, result⟩)
537  exact trace
538
539private theorem ready_locals (e : Env) (c : Ctx) (A : Array UInt8)
540    (l : L) (i o : Nat) (pre : StepPre e c A l i o) :
541    LS e (ready e l i).1 (ready e l i).2 o ∧ 15 ≤ (ready e l i).1.bits.toNat := by
542  by_cases short : l.bits < 15
543  · have bitsLt : l.bits.toNat < 15 := by simpa using UInt32.lt_iff_toNat_lt.mp short
544    have in1 : i < e.i0 + e.sm0.avail_in.toNat := by have := pre.inputRoom; omega
545    have first := pre.locals.pullL (by omega) in1
546    have bits1 := pullL_bits l (e.IN.getD i 0) (.ref (.blk e.ib) (i + 1)) pre.locals.hb
547    have bound1 : (pullL l (e.IN.getD i 0) (.ref (.blk e.ib) (i + 1))).bits.toNat ≤ 22 := by
548      simp only [pullL] at bits1 ⊢; omega
549    have in2 : i + 1 < e.i0 + e.sm0.avail_in.toNat := by have := pre.inputRoom; omega
550    have second := first.pullL bound1 in2
551    have bits2 := pullL_bits (pullL l (e.IN.getD i 0) (.ref (.blk e.ib) (i + 1)))
552      (e.IN.getD (i + 1) 0) (.ref (.blk e.ib) (i + 1 + 1)) first.hb
553    simp only [ready, short, ite_true]
554    constructor
555    · simpa only [Nat.add_assoc] using second
556    · simp only [pullL] at bits1 bits2 ⊢; omega
557  · simp only [ready, short, ite_false]
558    refine ⟨pre.locals, ?_⟩
559    have large : ¬ l.bits.toNat < 15 := fun h => short (UInt32.lt_iff_toNat_lt.mpr (by simpa using h))
560    omega
561
562
563
564theorem actual_body_refines_token : BodyToken.Goal.actual_body_refines_token := by
565  intro e c bytes msg mode l input output L D pre tables
566  obtain ⟨l', after, run, sameStream, entry, consumed, limit, look, oldEnd, tail⟩ :=
567    body_entry_wp e c bytes msg mode l input output pre
568  have safe := Wp.at_run (inflate_fast_body_step_safe e c bytes msg mode l input output pre) run
569  obtain ⟨readyLS, enough⟩ := ready_locals e c bytes l input output pre
570  obtain ⟨usedL, invL⟩ := tables.lengthTable
571  obtain ⟨query, positive, codeBound, leaf, semantic⟩ := length_lookup_matches_format e
572    (ready e l input).1.hold.toNat (ready e l input).1.bits.toNat (ready e l input).2
573    usedL L entry consumed invL tables.lengthStable tables.lengthFlags readyLS.hH enough look
574  rw [sameStream] at semantic oldEnd tail
575  have acceptedMeaning (accepts : FastTableFlags.FastLeafAccepted LENS entry) :
576      ∃ symbol, symbol ≤ 285 ∧ DecodeSemantics.SymbolEntry LENS symbol entry ∧
577        consumed = L.getD symbol 0 ∧
578        decodeSym L (Sg e l.hold.toNat l.bits.toNat input) =
579          some (symbol, (Sg e l.hold.toNat l.bits.toNat input).drop consumed) := by
580    rcases semantic with ⟨rejects, _⟩ | ⟨_, symbol, valid, meaning, length, decoded, _⟩
581    · exact False.elim (rejects accepts)
582    · exact ⟨symbol, valid, meaning, length, decoded⟩
583  have bgLe : e.bg ≤ output := Nat.le_trans e.bg_le pre.locals.ho0
584  have outSize : output < bytes.size := by
585    have := pre.outputRoom
586    have endSize := e.hAsz
587    rw [← pre.outputSize] at endSize
588    omega
589  rcases oldEnd.2.2 with literal | length | eob | invalid
590  · obtain ⟨hop, stopped, locals, rest, heap⟩ := literal
591    have accepts : FastTableFlags.FastLeafAccepted LENS entry := by
592      simp [FastTableFlags.FastLeafAccepted, hop]
593    obtain ⟨symbol, valid, meaning, _, decoded⟩ := acceptedMeaning accepts
594    obtain ⟨small, value⟩ := literal_symbol symbol entry valid meaning hop
595    refine ⟨l', after, (ready e l input).2, output + 1, bytes.set! output entry.val.toUInt8,
596      msg, mode, run, safe, locals, by simp, heap, Or.inl ⟨stopped, ?_⟩⟩
597    have written := written_set_append bytes output (output - e.bg) entry.val.toUInt8 (by omega) outSize
598    have count : output + 1 - e.bg = output - e.bg + 1 := by omega
599    rw [count, written, rest]
600    have byte : entry.val.toUInt8 = symbol.toUInt8 := by
601      apply UInt8.toNat_inj.mp
602      simp only [UInt16.toNat_toUInt8, UInt8.toNat_ofNat']
603      rw [value]
604    rw [byte]
605    exact Token.Step.literal decoded small
606  · obtain ⟨nonzero, hasBase, _⟩ := length
607    have accepts : FastTableFlags.FastLeafAccepted LENS entry := by
608      simp [FastTableFlags.FastLeafAccepted, hasBase]
609    obtain ⟨symbol, valid, meaning, _, decoded⟩ := acceptedMeaning accepts
610    have lower := base_symbol symbol entry valid meaning hasBase
611    obtain ⟨_, extraBits, baseValue⟩ := length_base_fields symbol entry lower valid meaning
612    obtain ⟨input2, xl, r2, _, _, readLength, distEntry⟩ := tail ⟨nonzero, hasBase⟩
613    obtain ⟨dl, di, _, _, dlLocals, dlRunning, dlLength, dlBits, dlRoom, dlSource, dlRun⟩ := distEntry
614    have lenBase : 3 ≤ entry.val.toNat ∧
615        entry.val.toNat + 2 ^ (entry.op &&& 15).toNat ≤ 259 := by
616      rcases leaf.2 with literal | base | invalid
617      · exact False.elim (nonzero literal)
618      · exact base.2.2
619      · exact False.elim (hasBase invalid.1)
620    have xlBound := readBits_value_lt readLength
621    have dlLen : 3 ≤ dl.len.toNat ∧ dl.len.toNat ≤ 258 := by omega
622    obtain ⟨usedD, invD⟩ := tables.distanceTable
623    obtain ⟨dl', dh, distanceEntry, dc, distanceRun, _, _, _, outcome⟩ := actual_distance_refines_lz77
624      e c bytes msg mode dl di output usedD D pre.context dlLocals
625      (by rw [pre.outputSize]; exact e.hAsz) pre.outputRoom
626      (by rw [pre.outputSize]; exact e.hAbig) dlRunning dlLen dlBits dlRoom
627      invD tables.distanceStable tables.distanceFlags
628    have sameRun := distanceRun.symm.trans dlRun
629    cases sameRun
630    unfold DistanceResult.Outcome at outcome
631    dsimp only at outcome
632    rw [dlSource] at outcome
633    rw [extraBits] at readLength
634    rcases outcome with ⟨noBase, rejected, di', errorMsg, stopped, locals, rest, heap⟩ |
635      ⟨base, distanceSymbol, xd, codeRest, finalRest, distanceValid, distanceMeaning, _,
636        distanceDecoded, readDistance, copy⟩
637    · refine ⟨l', after, di', output, bytes, errorMsg, BAD, run, safe, locals, rfl, heap,
638        Or.inr (Or.inr ⟨stopped, rfl, rfl, ?_⟩)⟩
639      exact Token.Rejected.distance decoded lower valid readLength rejected
640    · by_cases tooFar : (MatchHistory.saved e.W e.s0.wsize.toNat e.s0.wnext.toNat
641          e.s0.whave.toNat e.woff).length + (writtenBytes bytes output (output - e.bg)).length <
642          distBases.getD distanceSymbol 0 + xd
643      · rw [ite_eq_left tooFar] at copy
644        obtain ⟨di', errorMsg, stopped, locals, rest, heap⟩ := copy
645        refine ⟨l', after, di', output, bytes, errorMsg, BAD, run, safe, locals, rfl, heap,
646          Or.inr (Or.inr ⟨stopped, rfl, rfl, ?_⟩)⟩
647        exact Token.Rejected.tooFar decoded lower valid readLength distanceDecoded distanceValid
648          readDistance (by simpa only [List.length_append] using tooFar)
649      · rw [ite_eq_right tooFar] at copy
650        obtain ⟨di', stopped, locals, rest, heap, written⟩ := copy
651        refine ⟨l', after, di', output + dl.len.toNat, _, msg, mode, run, safe, locals,
652          matchArr_size _ _ _ _ _ _ _ _ _, heap, Or.inl ⟨stopped, ?_⟩⟩
653        have count : output + dl.len.toNat - e.bg = output - e.bg + dl.len.toNat := by omega
654        rw [count, written, rest, dlLength, baseValue]
655        exact Token.Step.copy decoded lower valid readLength distanceDecoded distanceValid readDistance
656          (by simp only [List.length_append]; omega)
657  · obtain ⟨nonzero, noBase, invalidFlag, endFlag, stopped, locals, rest, heap⟩ := eob
658    have accepts : FastTableFlags.FastLeafAccepted LENS entry := by
659      simp [FastTableFlags.FastLeafAccepted, invalidFlag, endFlag]
660    obtain ⟨symbol, valid, meaning, _, decoded⟩ := acceptedMeaning accepts
661    have symbolIsEnd := eob_symbol symbol entry valid meaning nonzero noBase
662    subst symbol
663    refine ⟨l', after, (ready e l input).2, output, bytes, msg, TYPE,
664      run, safe, locals, rfl, heap, Or.inr (Or.inl ⟨stopped, rfl, ?_⟩)⟩
665    rw [rest]
666    exact Token.Step.eob decoded
667  · obtain ⟨nonzero, noBase, invalidFlag, noEnd, stopped, locals, rest, errorMsg, heap⟩ := invalid
668    have rejects : ¬ FastTableFlags.FastLeafAccepted LENS entry := by
669      simp [FastTableFlags.FastLeafAccepted, nonzero, noBase, noEnd]
670    have future : ∀ more : List Bool,
671        ¬ ∃ symbol remaining, decodeSym L (Sg e l.hold.toNat l.bits.toNat input ++ more) =
672          some (symbol, remaining) ∧ symbol ≤ 285 := by
673      rcases semantic with ⟨_, allFuture⟩ | ⟨accepts, _⟩
674      · exact allFuture
675      · exact False.elim (rejects accepts)
676    refine ⟨l', after, (ready e l input).2, output, bytes, errorMsg, BAD,
677      run, safe, locals, rfl, heap, Or.inr (Or.inr ⟨stopped, rfl, rfl, ?_⟩)⟩
678    exact Token.Rejected.length future
679
680end Zlib.Inffast.Proofs.BodyTokenProof
681
682namespace Zlib.Inffast.Proofs
683/-- The actual fast body emits one independent token, ends the block,
684or rejects the current token without emitting output. -/
685theorem actual_body_refines_token : Spec.BodyToken.Goal.actual_body_refines_token :=
686  BodyTokenProof.actual_body_refines_token
687end Zlib.Inffast.Proofs
ZLIB × LEAN

全局目录

当前位置inffast.c.body-token.lean