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

inflate.c.input-cursor.lean

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

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

1import ZlibF.Proof.«inflate.c.main.macros»
2import ZlibF.Spec.Public.Memory
3
4namespace Zlib.Inflate.Proofs
5open C Zlib.Inflate
6set_option autoImplicit false
7
8/-- The cursor value after consuming bytes, without changing its byte view. -/
9def inputAdvance : BPtr → Nat → BPtr
10  | .null, _ => .null
11  | .ref ref off, used => .ref ref (off + used)
12
13theorem inputAdvance_zero (pointer : BPtr) : inputAdvance pointer 0 = pointer := by
14  cases pointer <;> rfl
15
16theorem inputAdvance_add (pointer : BPtr) (first second : Nat) :
17    inputAdvance (inputAdvance pointer first) second = inputAdvance pointer (first + second) := by
18  cases pointer <;> simp [inputAdvance, Nat.add_assoc]
19
20/-- Advancing within caller input preserves its public separation from the
21output range. Different allocations are not required. -/
22theorem inputAdvance_separate (input output : BPtr) (size room used : Nat)
23    (bound : used ≤ size) (separate : ZlibF.Spec.Public.Separate input size output room) :
24    ZlibF.Spec.Public.Separate (inputAdvance input used) (size - used) output room := by
25  rcases separate with empty | empty | separate
26  · exact Or.inl (by omega)
27  · exact Or.inr (Or.inl empty)
28  · right
29    right
30    cases input with
31    | null => trivial
32    | ref ref off =>
33      cases output with
34      | null => trivial
35      | ref dest outOffset =>
36        rcases separate with different | before | after
37        · exact Or.inl different
38        · exact Or.inr (Or.inl (by omega))
39        · exact Or.inr (Or.inr (by omega))
40
41/-- A retained cursor origin and the actual input count transport the
42public separation premise across any checked refill boundary. -/
43theorem BitInv.cursor_separate {h after : Heap} {l regs : IL} {bs : List UInt8} {used : Nat}
44    (before : BitInv h l bs) (current : BitInv after regs (bs.drop used)) (bound : used ≤ bs.length)
45    (cursor : regs.next = inputAdvance l.next used)
46    (separate : ZlibF.Spec.Public.Separate l.next l.have_.toNat l.put l.left.toNat) :
47    ZlibF.Spec.Public.Separate regs.next regs.have_.toNat l.put l.left.toNat := by
48  rw [before.have_eq] at separate
49  rw [current.have_eq, List.length_drop, cursor]
50  exact inputAdvance_separate l.next l.put bs.length l.left.toNat used bound separate
51
52/-- The actual input macro retains its byte-view identity and exact cursor
53offset, in addition to the earlier bit-stream facts. -/
54theorem PULLBYTE_succ_cursor {h : Heap} {l : IL} {b : UInt8} {bs : List UInt8}
55    (B : BitInv h l (b :: bs)) (hb : l.bits.toNat ≤ 56) :
56    ∃ nx, runX PULLBYTE l h = .ok ((.ok (), pulled l b nx), h) ∧
57      BitInv h (pulled l b nx) bs ∧ stream (pulled l b nx) bs = stream l (b :: bs) ∧
58      (pulled l b nx).bits.toNat = l.bits.toNat + 8 ∧ nx = inputAdvance l.next 1 := by
59  obtain ⟨nx, run, inv, bits, count⟩ := PULLBYTE_succ B hb
60  obtain ⟨ref, array, off, ptr, get, bound, _⟩ := B.next.resolve_left (by simp)
61  have fit : off < array.size := by simp only [List.length_cons] at bound; omega
62  have empty : (l.have_ == 0) = false := by
63    simp only [beq_eq_false_iff_ne]
64    intro zero
65    have length := B.have_eq
66    rw [zero] at length
67    simp at length
68  have load : load8 l.next h = .ok (array[off], h) := by rw [ptr]; exact Ptr.load_ok get fit
69  have add : l.next.add 1 h = .ok (.ref ref (off + 1), h) := by
70    rw [ptr]
71    exact Ptr.add_nat_ok (n := 1) get (by omega)
72  have shift : shl64 array[off].toUInt64 l.bits h = .ok (array[off].toUInt64 <<< l.bits.toUInt64, h) := by
73    rw [shl64_run _ _ (by omega : l.bits.toNat < 64)]
74    rfl
75  have actual : runX PULLBYTE l h = .ok ((.ok (), pulled l array[off] (.ref ref (off + 1))), h) := by
76    unfold PULLBYTE
77    rw [runX_bind, runX_get]
78    simp only [empty, Bool.false_eq_true, ↓reduceIte]
79    simp only [runX_bind, runX_set, runX_lift_ok load, runX_lift_ok add, runX_lift_ok shift]
80    rfl
81  have registers := congrArg (fun result => result.map (fun entry => entry.1.2.next)) (run.symm.trans actual)
82  have cursor : nx = inputAdvance l.next 1 := by
83    simp only [Except.map, pulled] at registers
84    rw [ptr]
85    exact Except.ok.inj registers
86  exact ⟨nx, run, inv, bits, count, cursor⟩
87
88end Zlib.Inflate.Proofs
ZLIB × LEAN

全局目录

当前位置inflate.c.input-cursor.lean