Skip to content
REFERENCE / ZLIB × LEAN

trees.c.build.emit.lean

Source snapshot · 4f99d35e49b09ca9 · 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.build.support»
2import ZlibF.Proof.«trees.c.emit»
3import ZlibF.Spec.Format.Bits
4
5/-! # trees.c: transmitting the canonical values established by tree building -/
6
7namespace Zlib.Trees.Proofs
8open C Zlib.Trees
9
10/-- Stored reversed canonical words are sent in the format's most-significant
11bit order. This statement concerns exact bit order; prefix freedom requires
12the separate length/count consistency bridge. -/
13theorem canonical_code_wire (tk : TK) (d : DeflateState) (v : Nat)
14    (hc : (tk.arr d)[v]!.fc.toNat = Math.storedCode
15      (fun b => d.bl_count[b]!.toNat) (fun n => (tk.arr d)[n]!.dl.toNat) v) :
16    Out.natBits (tk.arr d)[v]!.fc.toNat (tk.arr d)[v]!.dl.toNat =
17      ZlibF.Spec.natToBitsMSB (tk.arr d)[v]!.dl.toNat
18        (Math.canonicalCode (fun b => d.bl_count[b]!.toNat) (fun n => (tk.arr d)[n]!.dl.toNat) v) := by
19  rw [hc]
20  unfold Out.natBits ZlibF.Spec.natToBitsMSB Math.storedCode
21  exact Math.reverseLowBits_wire _ _
22
23/-- The actual send_code reads the represented dynamic-tree entry and
24emits its exact canonical bits. Length and code-value facts are the data
25results of build_tree; its two reads are proved here. Output capacity and
26the current live output invariant remain explicit caller obligations. -/
27theorem send_canonical_code_emit {h : Heap} {id b : Nat} {d : DeflateState} {buf : Array UInt8}
28    (hI : Out.TreesInvAt h id d b buf) (tk : TK) (v : Nat) (hv : v < (tk.arr d).size)
29    (hl : (tk.arr d)[v]!.dl.toNat ≤ 15)
30    (hc : (tk.arr d)[v]!.fc.toNat = Math.storedCode
31      (fun b => d.bl_count[b]!.toNat) (fun n => (tk.arr d)[n]!.dl.toNat) v)
32    (hroom : 8 * d.pending.toNat + d.bi_valid.toInt.toNat + (tk.arr d)[v]!.dl.toNat ≤ 8 * buf.size) :
33    Out.Emit id b (send_code (Sp id) (v : Int) (.ref (tk.ref id) 0)) h d buf
34      (ZlibF.Spec.natToBitsMSB (tk.arr d)[v]!.dl.toNat
35        (Math.canonicalCode (fun b => d.bl_count[b]!.toNat) (fun n => (tk.arr d)[n]!.dl.toNat) v)) 2 := by
36  have hg := tk_get (h0 := h) (id := id) (d := d) tk
37  rw [setD_self hI.base.dstate] at hg
38  have hdl : getDl (.ref (tk.ref id) 0) (v : Int) h = .ok ((tk.arr d)[v]!.dl, h) := by
39    simpa only [getElem!_pos, hv] using Out.getDl_gen hg hv
40  have hfc : getFc (.ref (tk.ref id) 0) (v : Int) h = .ok ((tk.arr d)[v]!.fc, h) := by
41    simpa only [getElem!_pos, hv] using Out.getFc_gen hg hv
42  have hfit : (tk.arr d)[v]!.fc.toNat < 2 ^ (tk.arr d)[v]!.dl.toNat := by
43    rw [hc]
44    exact Math.storedCode_lt _ _ _
45  have hemit := Out.send_code_emit hI (v : Int) (.ref (tk.ref id) 0) _ _ hdl hfc hl hfit hroom
46  rw [canonical_code_wire tk d v hc] at hemit
47  exact hemit
48
49end Zlib.Trees.Proofs
ZLIB × LEAN

Global contents

READING NOWtrees.c.build.emit.lean