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

InflateFastMatchHistory.lean

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

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

1import ZlibF.Spec.InflateFastMatchHistory
2import ZlibF.Math.LZ77Copy
3import ZlibF.Math.LZ77History
4
5/-!
6# The fast copier's physical pieces form one independent match
7
8Every window segment is related to its chronological ring position. The
9pieces are then joined with the bytewise copyBack composition theorem.
10-/
11
12set_option autoImplicit false
13
14namespace Zlib.Inffast.Proofs
15open C Zlib.Inffast.Spec Zlib.Inffast.Spec.MatchHistory
16open ZlibF.Spec ZlibF.Math.LZ77Copy ZlibF.Math.LZ77History
17open Zlib.Inflate.Spec (ringSlot)
18
19private theorem saved_length (W : Array UInt8) (ws wn wh woff : Nat) :
20    (saved W ws wn wh woff).length = wh := by simp [saved]
21
22private theorem saved_get (W : Array UInt8) (ws wn wh woff j : Nat) (hj : j < wh) :
23    (saved W ws wn wh woff).getD j 0 = W.getD (woff + ringSlot ws wn wh j) 0 := by
24  have hlen : j < (saved W ws wn wh woff).length := by simpa [saved] using hj
25  rw [← List.getElem_eq_getD (h := hlen) 0]
26  simp only [saved, List.getElem_map, List.getElem_range]
27
28private theorem before_wrap (ws wn wh back i : Nat)
29    (hwh : wh ≤ ws) (hb : back ≤ wh) (hw : wn < back) (hi : i < back - wn) :
30    ringSlot ws wn wh (wh - back + i) = ws + wn - back + i := by
31  have hfull : ¬ wh ≤ wn := by omega
32  have hindex : wh - back + i < wh - wn := by omega
33  simp only [ringSlot, hfull, hindex, ite_false, ite_true]
34  omega
35
36private theorem after_wrap (ws wn wh back i : Nat)
37    (hb : back ≤ wh) (hw : wn < back) (hi : i < wn) :
38    ringSlot ws wn wh (wh - wn + i) = i := by
39  have hfull : ¬ wh ≤ wn := by omega
40  have hindex : ¬ wh - wn + i < wh - wn := by omega
41  simp only [ringSlot, hfull, hindex, ite_false]
42  omega
43
44private theorem no_wrap (ws wn wh back i : Nat)
45    (hb : back ≤ wh) (hw : back ≤ wn) (hi : i < back) :
46    ringSlot ws wn wh (wh - back + i) = wn - back + i := by
47  by_cases hfull : wh ≤ wn
48  · simp only [ringSlot, hfull, ite_true]
49    omega
50  · have hindex : ¬ wh - back + i < wh - wn := by omega
51    simp only [ringSlot, hfull, hindex, ite_false]
52    omega
53
54/-- Both window segments, followed by overlapping output if necessary,
55implement one independent copyBack on the actual chronological history. -/
56theorem fast_match_array_refines_lz77 : MatchHistory.Goal.match_array_refines_lz77 := by
57  intro W A ws wn wh woff bg o dist len hwh hwn hW hbg hroom hd havail
58  let count := o - bg
59  let history := saved W ws wn wh woff
60  let current := writtenBytes A o count
61  have hcount : count ≤ o := by dsimp [count]; omega
62  have hhistory : history.length = wh := saved_length W ws wn wh woff
63  by_cases route : o - bg < dist
64  · let back := dist - count
65    have hroute : count < dist := route
66    have hback : 0 < back ∧ back ≤ wh := by dsimp [back]; dsimp [count] at *; omega
67    have hstorage : woff + ws ≤ W.size := hW (by omega)
68    have first : ∀ (n sourceOffset : Nat), n ≤ back → o + n ≤ A.size →
69        sourceOffset + n ≤ W.size →
70        (∀ i, i < n → W.getD (sourceOffset + i) 0 =
71          history.getD (history.length + count - dist + i) 0) →
72        writtenBytes (blitN W n sourceOffset o A) (o + n) (count + n) =
73          copyBack history dist n current := by
74      intro n sourceOffset hn hr hs hp
75      exact window_copy_refines_lz77 history A W o count sourceOffset dist n
76        hcount hroute (by rw [hhistory]; exact havail) (by dsimp [back] at hn; exact hn) hr hs hp
77    have finish : ∀ (B : Array UInt8) (k : Nat),
78        B.size = A.size → k ≤ len → dist ≤ count + k →
79        writtenBytes B (o + k) (count + k) = copyBack history dist k current →
80        writtenBytes (cpyN (len - k) (o + k - dist) (o + k) B)
81          (o + len) (count + len) = copyBack history dist len current := by
82      intro B k hsz hk hdist hp
83      have H := output_copy_refines_lz77 history B (o + k) (count + k) dist (len - k)
84        (by omega) hd hdist (by omega)
85      have hoff : o + k + (len - k) = o + len := by omega
86      have hc : count + k + (len - k) = count + len := by omega
87      rw [hoff, hc, hp, ← copy_back_compose] at H
88      simpa only [show k + (len - k) = len by omega] using H
89    by_cases hzero : wn = 0
90    · have segment : ∀ n, n ≤ back → n ≤ len →
91          writtenBytes (blitN W n (woff + ws - back) o A) (o + n) (count + n) =
92            copyBack history dist n current := by
93        intro n hn hlen
94        apply first n (woff + ws - back) hn (by omega) (by omega)
95        intro i hi
96        have hj : history.length + count - dist + i < wh := by rw [hhistory]; dsimp [back] at hn; omega
97        have hidx : history.length + count - dist + i = wh - back + i := by rw [hhistory]; dsimp [back]; omega
98        rw [hidx, saved_get W ws wn wh woff _ (by omega)]
99        rw [before_wrap ws wn wh back i hwh hback.2 (by omega) (by omega)]
100        congr 1
101        omega
102      by_cases hlen : back < len
103      · have hprefix := segment back (by omega) (by omega)
104        have H := finish (blitN W back (woff + ws - back) o A) back
105          (blitN_size ..) (by omega) (by dsimp [back]; omega) hprefix
106        simpa [matchArr, route, hzero, hlen, back, count, history, current] using H
107      · have H := segment len (by omega) (by omega)
108        simpa [matchArr, route, hzero, hlen, back, count, history, current] using H
109    · by_cases hwrap : wn < back
110      · let k := back - wn
111        have hkpos : 0 < k := by dsimp [k]; omega
112        have segment : ∀ n, n ≤ k → n ≤ len →
113            writtenBytes (blitN W n (woff + ws + wn - back) o A) (o + n) (count + n) =
114              copyBack history dist n current := by
115          intro n hn hlen
116          apply first n (woff + ws + wn - back) (by dsimp [k] at hn; omega) (by omega) (by dsimp [k] at hn; omega)
117          intro i hi
118          have hidx : history.length + count - dist + i = wh - back + i := by rw [hhistory]; dsimp [back]; omega
119          rw [hidx, saved_get W ws wn wh woff _ (by dsimp [k] at hn; omega)]
120          rw [before_wrap ws wn wh back i hwh hback.2 hwrap (by dsimp [k] at hn; omega)]
121          congr 1
122          omega
123        by_cases hlen1 : k < len
124        · let B := blitN W k (woff + ws + wn - back) o A
125          have hB : B.size = A.size := blitN_size ..
126          have hfirst := segment k (by omega) (by omega)
127          have second : ∀ n, n ≤ wn → n ≤ len - k →
128              writtenBytes (blitN W n woff (o + k) B) (o + k + n) (count + k + n) =
129                copyBack history dist (k + n) current := by
130            intro n hn hlen
131            have H := window_copy_refines_lz77 history B W (o + k) (count + k) woff dist n
132              (by omega) (by dsimp [k, back]; omega) (by rw [hhistory]; omega)
133              (by dsimp [k, back]; omega) (by omega) (by omega) ?_
134            · rw [show writtenBytes B (o + k) (count + k) = copyBack history dist k current from hfirst,
135                ← copy_back_compose] at H
136              exact H
137            · intro i hi
138              have hidx : history.length + (count + k) - dist + i = wh - wn + i := by
139                rw [hhistory]; dsimp [k, back]; omega
140              rw [hidx, saved_get W ws wn wh woff _ (by omega)]
141              rw [after_wrap ws wn wh back i hback.2 hwrap (by omega)]
142          by_cases hlen2 : wn < len - k
143          · have hsecond := second wn (by omega) (by omega)
144            have heq : k + wn = back := by dsimp [k]; omega
145            have hprefix : writtenBytes (blitN W wn woff (o + k) B) (o + back) (count + back) =
146                copyBack history dist back current := by simpa only [Nat.add_assoc, heq] using hsecond
147            have H := finish (blitN W wn woff (o + k) B) back
148              (by simp only [blitN_size]; exact hB) (by dsimp [k] at hlen2; omega)
149              (by dsimp [back]; omega) hprefix
150            have hlenrem : len - k - wn = len - back := by dsimp [k]; omega
151            simpa [matchArr, route, hzero, hwrap, hlen1, hlen2, hlenrem, B, k, back, count,
152              history, current, Nat.add_assoc, heq] using H
153          · have H := second (len - k) (by omega) (by omega)
154            have hlenfull : k + (len - k) = len := by omega
155            simpa [matchArr, route, hzero, hwrap, hlen1, hlen2, B, k, back, count,
156              history, current, Nat.add_assoc, hlenfull] using H
157        · have H := segment len (by omega) (by omega)
158          simpa [matchArr, route, hzero, hwrap, hlen1, k, back, count, history, current] using H
159      · have segment : ∀ n, n ≤ back → n ≤ len →
160            writtenBytes (blitN W n (woff + wn - back) o A) (o + n) (count + n) =
161              copyBack history dist n current := by
162          intro n hn hlen
163          apply first n (woff + wn - back) hn (by omega) (by omega)
164          intro i hi
165          have hidx : history.length + count - dist + i = wh - back + i := by rw [hhistory]; dsimp [back]; omega
166          rw [hidx, saved_get W ws wn wh woff _ (by omega)]
167          rw [no_wrap ws wn wh back i hback.2 (by omega) (by omega)]
168          congr 1
169          omega
170        by_cases hlen : back < len
171        · have H := finish (blitN W back (woff + wn - back) o A) back
172            (blitN_size ..) (by omega) (by dsimp [back]; omega) (segment back (by omega) (by omega))
173          simpa [matchArr, route, hzero, hwrap, hlen, back, count, history, current] using H
174        · have H := segment len (by omega) (by omega)
175          simpa [matchArr, route, hzero, hwrap, hlen, back, count, history, current] using H
176  · have H := output_copy_refines_lz77 (saved W ws wn wh woff) A o (o - bg) dist len
177      (by omega) hd (by omega) hroom
178    simpa only [matchArr, route, ite_false] using H
179
180end Zlib.Inffast.Proofs
ZLIB × LEAN

全局目录

当前位置InflateFastMatchHistory.lean