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

trees.c.emit.lean

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

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

1import ZlibF.Proof.«trees.c.block»
2
3/-!
4# trees.c: the bit writers as an algebra of emissions
5
6`Emit id b m h d buf w k`: the statement `m` runs without fault on `h` and appends the bits `w` to the output stream
7(`outBits`), writes at most `k` bytes of `pending_buf` (at `pending_buf[pending ..]`), keeps the invariant `TreesInvAt`
8for the same byte block `b`, and changes only `pending`, `bi_buf`, `bi_valid`, `bi_used` of the record and the bytes
9of `pending_buf` it writes. `Emit.bind` composes two statements. The functions that only call `send_bits`,
10`send_code` and `bi_flush` (`_tr_align`, `send_tree`, `send_all_trees`, `_tr_stored_block`) are proved by it.
11-/
12
13namespace Zlib.Trees.Proofs.Out
14open C Zlib.Trees
15
16/-- `d'` differs from `d` only in the bit-output fields. -/
17def BitsDiff (d d' : DeflateState) : Prop :=
18  ∃ p a v u, d' = { d with pending := p, bi_buf := a, bi_valid := v, bi_used := u }
19
20theorem BitsDiff.refl (d : DeflateState) : BitsDiff d d := ⟨d.pending, d.bi_buf, d.bi_valid, d.bi_used, rfl⟩
21
22theorem BitsDiff.trans {d d1 d2 : DeflateState} (h1 : BitsDiff d d1) (h2 : BitsDiff d1 d2) : BitsDiff d d2 := by
23  obtain ⟨p, a, v, u, rfl⟩ := h1
24  obtain ⟨p2, a2, v2, u2, rfl⟩ := h2
25  exact ⟨p2, a2, v2, u2, rfl⟩
26
27/-- See the module comment. -/
28def Emit (id b : Nat) (m : M Unit) (h : Heap) (d : DeflateState) (buf : Array UInt8) (w : List Bool) (k : Nat) : Prop :=
29  ∃ buf' d', m h = .ok ((), setD (setB h b buf') id d') ∧ TreesInvAt (setD (setB h b buf') id d') id d' b buf' ∧
30    outBits buf' d' = outBits buf d ++ w ∧ buf'.size = buf.size ∧
31    (∀ i, (i < d.pending.toNat ∨ d'.pending.toNat ≤ i) → buf'.getD i 0 = buf.getD i 0) ∧
32    d.pending.toNat ≤ d'.pending.toNat ∧ d'.pending.toNat ≤ d.pending.toNat + k ∧ BitsDiff d d'
33
34theorem setB_setD (h : Heap) (id b : Nat) (a : Array UInt8) (d : DeflateState) :
35    setB (setD h id d) b a = setD (setB h b a) id d := rfl
36
37theorem outBits_length (buf : Array UInt8) (d : DeflateState) :
38    (outBits buf d).length = 8 * d.pending.toNat + d.bi_valid.toInt.toNat := by
39  unfold outBits; simp
40
41theorem Emit.bind {id b : Nat} {m1 m2 : M Unit} {h : Heap} {d : DeflateState} {buf : Array UInt8}
42    {w1 w2 : List Bool} {k1 k2 : Nat} (e1 : Emit id b m1 h d buf w1 k1)
43    (f : ∀ buf1 d1, TreesInvAt (setD (setB h b buf1) id d1) id d1 b buf1 → outBits buf1 d1 = outBits buf d ++ w1 →
44      buf1.size = buf.size → Emit id b m2 (setD (setB h b buf1) id d1) d1 buf1 w2 k2) :
45    Emit id b (m1 >>= fun _ => m2) h d buf (w1 ++ w2) (k1 + k2) := by
46  obtain ⟨buf1, d1, r1, i1, o1, s1, f1, l1, u1, b1⟩ := e1
47  obtain ⟨buf2, d2, r2, i2, o2, s2, f2, l2, u2, b2⟩ := f buf1 d1 i1 o1 s1
48  refine ⟨buf2, d2, ?_, ?_, ?_, by rw [s2, s1], ?_, by omega, by omega, b1.trans b2⟩
49  · rw [bind_app, r1]; simp only []; rw [r2]; simp only [setB_setD, setB_setB, setD_setD]
50  · simpa only [setB_setD, setB_setB, setD_setD] using i2
51  · rw [o2, o1, List.append_assoc]
52  · intro i hi
53    rw [f2 i (by omega), f1 i (by omega)]
54
55theorem Emit.pure {id b : Nat} {h : Heap} {d : DeflateState} {buf : Array UInt8}
56    (hI : TreesInvAt h id d b buf) : Emit id b (pure ()) h d buf [] 0 := by
57  refine ⟨buf, d, ?_, ?_, by simp, rfl, fun _ _ => rfl, Nat.le_refl _, by omega, BitsDiff.refl d⟩
58  · rw [setB_self hI.base.bytes, setD_self hI.base.dstate]; rfl
59  · rw [setB_self hI.base.bytes, setD_self hI.base.dstate]; exact hI
60
61theorem Emit.mono {id b : Nat} {m : M Unit} {h : Heap} {d : DeflateState} {buf : Array UInt8} {w : List Bool}
62    {k k' : Nat} (e : Emit id b m h d buf w k) (hk : k ≤ k') : Emit id b m h d buf w k' := by
63  obtain ⟨buf1, d1, r1, i1, o1, s1, f1, l1, u1, b1⟩ := e
64  exact ⟨buf1, d1, r1, i1, o1, s1, f1, l1, by omega, b1⟩
65
66/-- **`send_bits` as an emission.** -/
67theorem send_bits_emit {h : Heap} {id : Nat} {d : DeflateState} {b : Nat} {buf : Array UInt8}
68    (hI : TreesInvAt h id d b buf) (value len : Int32)
69    (hl0 : 0 ≤ len.toInt) (hl1 : len.toInt ≤ 15) (hv : v16 value < 2 ^ len.toInt.toNat)
70    (hroom : 8 * d.pending.toNat + d.bi_valid.toInt.toNat + len.toInt.toNat ≤ 8 * buf.size) :
71    Emit id b (send_bits (some (.tab id)) value len) h d buf (natBits (v16 value) len.toInt.toNat) 2 := by
72  obtain ⟨buf', d', e, hi, ho, hs, hf, hl, hu, p, a, v, hd⟩ := send_bits_spec hI value len hl0 hl1 hv hroom
73  exact ⟨buf', d', e, hi, ho, hs, hf, hl, hu, ⟨p, a, v, d.bi_used, by rw [hd]⟩⟩
74
75/-- **`bi_flush` as an emission.** -/
76theorem bi_flush_emit {h : Heap} {id : Nat} {d : DeflateState} {b : Nat} {buf : Array UInt8}
77    (hI : TreesInvAt h id d b buf) (hroom : 8 * d.pending.toNat + d.bi_valid.toInt.toNat ≤ 8 * buf.size) :
78    Emit id b (bi_flush (some (.tab id))) h d buf [] 2 := by
79  obtain ⟨buf', d', e, hi, ho, -, hs, hf, hl, hu, p, a, v, hd⟩ := bi_flush_spec hI hroom
80  exact ⟨buf', d', e, hi, by simpa using ho, hs, hf, hl, hu, ⟨p, a, v, d.bi_used, by rw [hd]⟩⟩
81
82
83/-- **`bi_windup` as an emission.** -/
84theorem bi_windup_emit {h : Heap} {id : Nat} {d : DeflateState} {b : Nat} {buf : Array UInt8}
85    (hI : TreesInvAt h id d b buf) (hroom : 8 * d.pending.toNat + d.bi_valid.toInt.toNat ≤ 8 * buf.size) :
86    Emit id b (bi_windup (some (.tab id))) h d buf (List.replicate ((8 - d.bi_valid.toInt.toNat % 8) % 8) false) 2 := by
87  obtain ⟨buf', d', e, hi, ho, -, -, -, hs, hf, hl, hu, p, u, hd⟩ := bi_windup_spec hI hroom
88  exact ⟨buf', d', e, hi, ho, hs, hf, hl, hu, ⟨p, 0, 0, u, by rw [hd]⟩⟩
89
90theorem u16i_toInt (x : UInt16) : (u16i x).toInt = x.toNat := by
91  unfold u16i
92  have := x.toNat_lt
93  exact i32_ofInt_toInt (by omega) (by omega)
94
95theorem v16_u16i (x : UInt16) : v16 (u16i x) = x.toNat := by
96  unfold v16 i2us
97  have := u16i_toInt x
98  have h2 := x.toNat_lt
99  rw [this, u16_toNat_ofNat_mod]
100  have : ((x.toNat : Int) % 65536).toNat = x.toNat := by omega
101  rw [this]; exact Nat.mod_eq_of_lt h2
102
103/-- **`send_code` as an emission.** `send_code(s, c, tree)` sends `tree[c].Len` bits of `tree[c].Code`. Preconditions:
104the entry is readable without a fault (`hdl`, `hfc`: the two loads succeed and leave the heap unchanged), the length
105is at most 15 and the code has no bit above its length (both true of the codes `gen_codes` makes and of the static
106tables), and the bits fit in `pending_buf`. -/
107theorem send_code_emit {h : Heap} {id : Nat} {d : DeflateState} {b : Nat} {buf : Array UInt8}
108    (hI : TreesInvAt h id d b buf) (c : Int) (tree : CtDataPtr) (dl fc : UInt16)
109    (hdl : getDl tree c h = .ok (dl, h)) (hfc : getFc tree c h = .ok (fc, h))
110    (hl : dl.toNat ≤ 15) (hv : fc.toNat < 2 ^ dl.toNat)
111    (hroom : 8 * d.pending.toNat + d.bi_valid.toInt.toNat + dl.toNat ≤ 8 * buf.size) :
112    Emit id b (send_code (some (.tab id)) c tree) h d buf (natBits fc.toNat dl.toNat) 2 := by
113  have e := send_bits_emit hI (u16i fc) (u16i dl) (by rw [u16i_toInt]; omega) (by rw [u16i_toInt]; omega)
114    (by rw [v16_u16i, u16i_toInt]; exact hv) (by rw [u16i_toInt]; exact hroom)
115  rw [v16_u16i, u16i_toInt] at e
116  obtain ⟨buf', d', r, hi, ho, hs, hf, hl', hu, hb⟩ := e
117  refine ⟨buf', d', ?_, hi, ho, hs, hf, hl', hu, hb⟩
118  unfold send_code
119  rw [bind_app, hdl]
120  simp only []
121  rw [bind_app, hfc]
122  simp only []
123  exact r
124
125end Zlib.Trees.Proofs.Out
ZLIB × LEAN

全局目录

当前位置trees.c.emit.lean