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

deflate.c.init.storage.lean

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

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

1import ZlibF.Proof.«deflate.c.init.default»
2import ZlibF.Proof.«deflate.c.init.cleanup»
3
4/-! # deflate.c: exact default allocation storage and failure alternatives -/
5
6namespace Zlib.Deflate.Proofs.DefaultInit
7open C Zlib.Deflate Zlib.Deflate.Spec
8set_option autoImplicit false
9
10structure StableFields (h g : Heap) : Prop where
11  streams : g.streams = h.streams
12  gzheaders : g.gzheaders = h.gzheaders
13  dstates : g.dstates = h.dstates
14  istates : g.istates = h.istates
15  gzstates : g.gzstates = h.gzstates
16  static : g.static = h.static
17  allocOk : g.allocOk = h.allocOk
18  garbage : g.garbage = h.garbage
19
20theorem StableFields.trans {h g j : Heap} (a : StableFields h g) (b : StableFields g j) :
21    StableFields h j :=
22  ⟨b.streams.trans a.streams, b.gzheaders.trans a.gzheaders, b.dstates.trans a.dstates,
23    b.istates.trans a.istates, b.gzstates.trans a.gzstates, b.static.trans a.static,
24    b.allocOk.trans a.allocOk, b.garbage.trans a.garbage⟩
25
26theorem byteResult_stable (h : Heap) (n : Nat) : StableFields h (byteResult h n) := by
27  unfold byteResult
28  split <;> exact ⟨rfl, rfl, rfl, rfl, rfl, rfl, rfl, rfl⟩
29
30theorem wordResult_stable (h : Heap) (n : Nat) : StableFields h (wordResult h n) := by
31  unfold wordResult
32  split <;> exact ⟨rfl, rfl, rfl, rfl, rfl, rfl, rfl, rfl⟩
33
34theorem buffers_stable (h : Heap) : StableFields h (buffersHeap h) :=
35  (((byteResult_stable h 65536).trans (wordResult_stable (windowHeap h) 32768)).trans
36    (wordResult_stable (prevHeap h) 32768)).trans (byteResult_stable (headHeap h) 65536)
37
38theorem freeBytes_stable (h : Heap) (p : BPtr) : StableFields h (freeBytes h p) := by
39  unfold freeBytes
40  split <;> exact ⟨rfl, rfl, rfl, rfl, rfl, rfl, rfl, rfl⟩
41
42theorem freeWords_stable (h : Heap) (p : WPtr) : StableFields h (freeWords h p) := by
43  unfold freeWords
44  split <;> exact ⟨rfl, rfl, rfl, rfl, rfl, rfl, rfl, rfl⟩
45
46@[simp] theorem freeBytes_nalloc (h : Heap) (p : BPtr) : (freeBytes h p).nalloc = h.nalloc := by
47  unfold freeBytes
48  split <;> rfl
49
50@[simp] theorem freeWords_nalloc (h : Heap) (p : WPtr) : (freeWords h p).nalloc = h.nalloc := by
51  unfold freeWords
52  split <;> rfl
53
54theorem buffers_fresh {h : Heap} (hf : Fresh h) : Fresh (buffersHeap h) :=
55  fresh_byteResult (fresh_wordResult (fresh_wordResult (fresh_byteResult hf 65536) 32768) 32768) 65536
56
57theorem buffers_uniq {h : Heap} (hu : Uniq h) (hf : Fresh h) : Uniq (buffersHeap h) :=
58  uniq_byteResult
59    (uniq_wordResult
60      (uniq_wordResult (uniq_byteResult hu hf 65536) (fresh_byteResult hf 65536) 32768)
61      (fresh_wordResult (fresh_byteResult hf 65536) 32768) 32768)
62    (fresh_wordResult (fresh_wordResult (fresh_byteResult hf 65536) 32768) 32768) 65536
63
64theorem buffers_next (h : Heap) : h.nextBlk ≤ (buffersHeap h).nextBlk := by
65  have a := byteResult_next h 65536
66  have b := wordResult_next (windowHeap h) 32768
67  have c := wordResult_next (prevHeap h) 32768
68  have d := byteResult_next (headHeap h) 65536
69  dsimp only [buffersHeap, headHeap, prevHeap, windowHeap] at *
70  omega
71
72theorem buffers_old (h : Heap) (x : Nat) (hx : x < h.nextBlk) : SlotSame h (buffersHeap h) x := by
73  have a := byteResult_next h 65536
74  have b := wordResult_next (windowHeap h) 32768
75  have c := wordResult_next (prevHeap h) 32768
76  exact ((byteResult_old h 65536 x hx).trans
77    (wordResult_old (windowHeap h) 32768 x (by dsimp only [windowHeap] at *; omega))).trans
78    ((wordResult_old (prevHeap h) 32768 x (by dsimp only [prevHeap, windowHeap] at *; omega)).trans
79      (byteResult_old (headHeap h) 65536 x (by dsimp only [headHeap, prevHeap, windowHeap] at *; omega)))
80
81@[simp] theorem buffers_nalloc (h : Heap) : (buffersHeap h).nalloc = h.nalloc + 4 := by
82  simp [buffersHeap, headHeap, prevHeap, windowHeap, Nat.add_assoc]
83
84@[simp] theorem buffers_dstates (h : Heap) : (buffersHeap h).dstates = h.dstates := by
85  simp [buffersHeap, headHeap, prevHeap, windowHeap]
86
87@[simp] theorem get_buffersHeap (h : Heap) (r : ZStreamRef) : r.get (buffersHeap h) = r.get h := by
88  simp [buffersHeap, headHeap, prevHeap, windowHeap]
89
90theorem buffers_live (h : Heap) (x : Nat) :
91    (buffersHeap h).live x ↔ h.live x ∨ (bufferPointers h).1 = .ref (.blk x) 0 ∨
92      (bufferPointers h).2.1 = .ref (.blk x) 0 ∨
93      (bufferPointers h).2.2.1 = .ref (.blk x) 0 ∨
94      (bufferPointers h).2.2.2 = .ref (.blk x) 0 := by
95  simp only [buffersHeap, byteResult_live, headHeap, wordResult_live, prevHeap,
96    windowHeap, bufferPointers, or_assoc]
97
98def byteGarbage (h : Heap) (j : Nat) : Array UInt8 :=
99  Array.ofFn (n := 65536) fun i => Junk.of (h.garbage (h.nalloc + j) i.val)
100def wordGarbage (h : Heap) (j : Nat) : Array UInt16 :=
101  Array.ofFn (n := 32768) fun i => Junk.of (h.garbage (h.nalloc + j) i.val)
102
103def successfulBuffers (h : Heap) : Heap :=
104  { h with
105    bytes := upd (upd h.bytes h.nextBlk (some (byteGarbage h 0))) (h.nextBlk + 3) (some (byteGarbage h 3)),
106    words := upd (upd h.words (h.nextBlk + 1) (some (wordGarbage h 1)))
107      (h.nextBlk + 2) (some (wordGarbage h 2)),
108    ro := upd (upd h.ro h.nextBlk false) (h.nextBlk + 3) false,
109    nextBlk := h.nextBlk + 4, nalloc := h.nalloc + 4 }
110
111/-- Exact storage when all four requests succeed; all arrays keep the
112allocator's arbitrary integer contents. -/
113theorem buffers_success (h : Heap) (ha : ∀ j, j < 4 → h.allocOk (h.nalloc + j) = true) :
114    buffersHeap h = successfulBuffers h ∧
115    bufferPointers h = (.ref (.blk h.nextBlk) 0, .ref (.blk (h.nextBlk + 1)) 0,
116      .ref (.blk (h.nextBlk + 2)) 0, .ref (.blk (h.nextBlk + 3)) 0) := by
117  have hw := ha 0 (by decide)
118  have hp := ha 1 (by decide)
119  have hq := ha 2 (by decide)
120  have hb := ha 3 (by decide)
121  simp only [Nat.add_zero] at hw
122  constructor
123  · simp [buffersHeap, headHeap, prevHeap, windowHeap, successfulBuffers,
124      byteResult, wordResult, byteHeap, wordHeap, Zlib.Zutil.Proofs.allocHeap,
125      byteGarbage, wordGarbage, hw, hp, hq, hb, Nat.add_assoc]
126  · simp [bufferPointers, headHeap, prevHeap, windowHeap,
127      byteResult, wordResult, bytePtr, wordPtr, byteHeap, wordHeap,
128      Zlib.Zutil.Proofs.allocHeap, hw, hp, hq, hb, Nat.add_assoc]
129
130/-- Every returned buffer is NULL or the live allocation of its request.
131The two byte buffers and two word buffers cannot alias when non-NULL. -/
132theorem buffers_freeable (h : Heap) :
133    FreeableB (buffersHeap h) (bufferPointers h).1 ∧
134    FreeableW (buffersHeap h) (bufferPointers h).2.1 ∧
135    FreeableW (buffersHeap h) (bufferPointers h).2.2.1 ∧
136    FreeableB (buffersHeap h) (bufferPointers h).2.2.2 ∧
137    ((bufferPointers h).2.2.2 = .null ∨ (bufferPointers h).1 = .null ∨
138      (bufferPointers h).2.2.2 ≠ (bufferPointers h).1) ∧
139    ((bufferPointers h).2.2.1 = .null ∨ (bufferPointers h).2.1 = .null ∨
140      (bufferPointers h).2.2.1 ≠ (bufferPointers h).2.1) := by
141  by_cases hw : h.allocOk h.nalloc = true <;>
142    by_cases hp : h.allocOk (h.nalloc + 1) = true <;>
143    by_cases hq : h.allocOk (h.nalloc + 2) = true <;>
144    by_cases hb : h.allocOk (h.nalloc + 3) = true
145  all_goals simp [FreeableB, FreeableW, bufferPointers, buffersHeap, headHeap, prevHeap, windowHeap,
146    byteResult, wordResult, bytePtr, wordPtr, byteHeap, wordHeap, failedHeap,
147    Zlib.Zutil.Proofs.allocHeap, hw, hp, hq, hb, Nat.add_assoc]
148
149/-- The failure test sees the exact four allocator outcomes. -/
150theorem buffers_failed_iff (h : Heap) :
151    ((bufferPointers h).1 == .null || (bufferPointers h).2.1 == .null ||
152      (bufferPointers h).2.2.1 == .null || (bufferPointers h).2.2.2 == .null) = false ↔
153      h.allocOk h.nalloc = true ∧ h.allocOk (h.nalloc + 1) = true ∧
154        h.allocOk (h.nalloc + 2) = true ∧ h.allocOk (h.nalloc + 3) = true := by
155  by_cases hw : h.allocOk h.nalloc = true <;>
156    by_cases hp : h.allocOk (h.nalloc + 1) = true <;>
157    by_cases hq : h.allocOk (h.nalloc + 2) = true <;>
158    by_cases hb : h.allocOk (h.nalloc + 3) = true
159  all_goals simp [bufferPointers, buffersHeap, headHeap, prevHeap, windowHeap,
160    byteResult, wordResult, bytePtr, wordPtr, byteHeap, wordHeap, failedHeap,
161    Zlib.Zutil.Proofs.allocHeap, hw, hp, hq, hb, Nat.add_assoc]
162
163theorem freeBytes_congr (h g : Heap) (p : BPtr) (he : h.bytes = g.bytes) :
164    (freeBytes h p).bytes = (freeBytes g p).bytes := by
165  unfold freeBytes
166  split <;> simp_all
167
168theorem freeWords_congr (h g : Heap) (p : WPtr) (he : h.words = g.words) :
169    (freeWords h p).words = (freeWords g p).words := by
170  unfold freeWords
171  split <;> simp_all
172
173theorem freeBytes_congr_at (h g : Heap) (p : BPtr) (x : Nat) (he : h.bytes x = g.bytes x) :
174    (freeBytes h p).bytes x = (freeBytes g p).bytes x := by
175  unfold freeBytes
176  split <;> simp_all [upd_apply]
177
178theorem freeWords_congr_at (h g : Heap) (p : WPtr) (x : Nat) (he : h.words x = g.words x) :
179    (freeWords h p).words x = (freeWords g p).words x := by
180  unfold freeWords
181  split <;> simp_all [upd_apply]
182
183/-- Cleanup restores each byte-object lookup. It does not shrink a grown
184table or rewind the allocation counters and permission metadata. -/
185theorem byte_pop_at {h : Heap} (hf : Fresh h) (n x : Nat) :
186    (freeBytes (byteResult h n) (bytePtr h)).bytes x = h.bytes x := by
187  obtain ⟨hb, _, _, _, _, _, _⟩ := Heap.not_live.mp (hf _ (Nat.le_refl _))
188  by_cases ho : h.allocOk h.nalloc = true <;> by_cases hx : x = h.nextBlk
189  all_goals simp [byteResult, bytePtr, byteHeap, Zlib.Zutil.Proofs.allocHeap,
190    failedHeap, ho, freeBytes, upd_apply, hx, hb]
191
192theorem word_pop_at {h : Heap} (hf : Fresh h) (n x : Nat) :
193    (freeWords (wordResult h n) (wordPtr h)).words x = h.words x := by
194  obtain ⟨_, hw, _, _, _, _, _⟩ := Heap.not_live.mp (hf _ (Nat.le_refl _))
195  by_cases ho : h.allocOk h.nalloc = true <;> by_cases hx : x = h.nextBlk
196  all_goals simp [wordResult, wordPtr, wordHeap, failedHeap, ho, freeWords, upd_apply, hx, hw]
197
198def rollbackBuffers (h g : Heap) : Heap :=
199  freeBytes (freeWords (freeWords (freeBytes g (bufferPointers h).2.2.2)
200    (bufferPointers h).2.2.1) (bufferPointers h).2.1) (bufferPointers h).1
201
202theorem rollback_stable (h g : Heap) : StableFields g (rollbackBuffers h g) := by
203  unfold rollbackBuffers
204  exact (((freeBytes_stable g _).trans (freeWords_stable _ _)).trans
205    (freeWords_stable _ _)).trans (freeBytes_stable _ _)
206
207@[simp] theorem rollback_nalloc (h g : Heap) : (rollbackBuffers h g).nalloc = g.nalloc := by
208  simp [rollbackBuffers]
209
210@[simp] theorem rollback_next (h g : Heap) : (rollbackBuffers h g).nextBlk = g.nextBlk := by
211  simp [rollbackBuffers]
212
213@[simp] theorem get_rollback (h g : Heap) (r : ZStreamRef) : r.get (rollbackBuffers h g) = r.get g := by
214  simp [rollbackBuffers]
215
216theorem slot_freeBytePtr_old (h g : Heap) (x : Nat) (hx : x < h.nextBlk) :
217    SlotSame g (freeBytes g (bytePtr h)) x := by
218  unfold bytePtr
219  split
220  · simp [SlotSame, freeBytes, upd_ne _ _ _ _ (show x ≠ h.nextBlk by omega)]
221  · exact ⟨rfl, rfl, rfl, rfl, rfl, rfl, rfl, rfl⟩
222
223theorem slot_freeWordPtr_old (h g : Heap) (x : Nat) (hx : x < h.nextBlk) :
224    SlotSame g (freeWords g (wordPtr h)) x := by
225  unfold wordPtr
226  split
227  · simp [SlotSame, freeWords, upd_ne _ _ _ _ (show x ≠ h.nextBlk by omega)]
228  · exact ⟨rfl, rfl, rfl, rfl, rfl, rfl, rfl, rfl⟩
229
230theorem rollback_old (h g : Heap) (x : Nat) (hx : x < h.nextBlk) : SlotSame g (rollbackBuffers h g) x := by
231  have a := byteResult_next h 65536
232  have b := wordResult_next (windowHeap h) 32768
233  have c := wordResult_next (prevHeap h) 32768
234  have i1 := slot_freeBytePtr_old (headHeap h) g x (by
235    dsimp only [headHeap, prevHeap, windowHeap] at *; omega)
236  have i2 := slot_freeWordPtr_old (prevHeap h) (freeBytes g (bytePtr (headHeap h))) x (by
237    dsimp only [headHeap, prevHeap, windowHeap] at *; omega)
238  have i3 := slot_freeWordPtr_old (windowHeap h)
239    (freeWords (freeBytes g (bytePtr (headHeap h))) (wordPtr (prevHeap h))) x (by
240      dsimp only [windowHeap] at *; omega)
241  exact ((i1.trans i2).trans i3).trans (slot_freeBytePtr_old h _ x hx)
242
243/-- Reverse-order cleanup restores every byte/word object lookup for all
244sixteen buffer-success patterns. Table capacities may remain enlarged. -/
245theorem rollback_arrays_at {h g : Heap} (hf : Fresh h) (x : Nat)
246    (hb : g.bytes x = (buffersHeap h).bytes x) (hw : g.words x = (buffersHeap h).words x) :
247    (rollbackBuffers h g).bytes x = h.bytes x ∧ (rollbackBuffers h g).words x = h.words x := by
248  have fW := fresh_byteResult hf 65536
249  have fP := fresh_wordResult fW 32768
250  have fH := fresh_wordResult fP 32768
251  have popB := byte_pop_at fH 65536 x
252  have popH := word_pop_at fP 32768 x
253  have popP := word_pop_at fW 32768 x
254  have popW := byte_pop_at hf 65536 x
255  have b1 : (freeBytes g (bytePtr (headHeap h))).bytes x = (headHeap h).bytes x := by
256    rw [freeBytes_congr_at g (buffersHeap h) _ x hb]
257    exact popB
258  have w1 : (freeBytes g (bytePtr (headHeap h))).words x = (headHeap h).words x := by
259    simpa [buffersHeap] using hw
260  have w2 : (freeWords (freeBytes g (bytePtr (headHeap h))) (wordPtr (prevHeap h))).words x =
261      (prevHeap h).words x := by
262    rw [freeWords_congr_at _ (headHeap h) _ x w1]
263    exact popH
264  have w3 : (freeWords (freeWords (freeBytes g (bytePtr (headHeap h))) (wordPtr (prevHeap h)))
265      (wordPtr (windowHeap h))).words x = (windowHeap h).words x := by
266    rw [freeWords_congr_at _ (prevHeap h) _ x w2]
267    exact popP
268  constructor
269  · unfold rollbackBuffers bufferPointers
270    simp only [freeWords_bytes] at b1 ⊢
271    have eq : (freeWords (freeWords (freeBytes g (bytePtr (headHeap h))) (wordPtr (prevHeap h)))
272        (wordPtr (windowHeap h))).bytes x = (windowHeap h).bytes x := by
273      simpa [headHeap, prevHeap] using b1
274    rw [freeBytes_congr_at _ (windowHeap h) _ x eq]
275    exact popW
276  · unfold rollbackBuffers bufferPointers
277    simpa [windowHeap] using w3
278
279end Zlib.Deflate.Proofs.DefaultInit
ZLIB × LEAN

全局目录

当前位置deflate.c.init.storage.lean