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

inffast.c.step1.lean

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

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

1import ZlibF.Proof.«inffast.c.env»
2
3namespace Zlib.Inffast.Proofs
4open C Zlib.Inffast Zlib.Inffast.Spec
5
6variable (e : Env)
7
8/-- The locals are consistent with the situation: `in` is at offset `i` of the input block, `out` at offset `o` of the
9output block, both within their windows; the bit buffer holds `bits ≤ 30` bits; and the bits read so far account for
10the bytes consumed (`bits ≤ bits_at_entry + 8 * (i - i0)`). -/
11structure LS (l : L) (i o : Nat) : Prop where
12  hin : l.in_ = .ref (BRef.blk e.ib) i
13  hout : l.out = .ref (BRef.blk e.ob) o
14  hi0 : e.i0 ≤ i
15  hi1 : i ≤ e.i0 + e.sm0.avail_in.toNat
16  ho0 : e.o0 ≤ o
17  hb : l.bits.toNat ≤ 30
18  hH : l.hold.toNat < 2 ^ l.bits.toNat
19  hacc : l.bits.toNat + 8 * e.i0 ≤ e.s0.bits.toNat + 8 * i
20
21/-- `l` after `hold += (unsigned long)(*in++) << bits; bits += 8;` with the byte `x` and the new pointer `p`. -/
22def pullL (l : L) (x : UInt8) (p : BPtr) : L :=
23  { l with in_ := p, hold := l.hold + (x.toUInt64 <<< l.bits.toUInt64), bits := l.bits + 8 }
24
25theorem pullL_bits (l : L) (x p) (hb : l.bits.toNat ≤ 30) : (pullL l x p).bits.toNat = l.bits.toNat + 8 := by
26  unfold pullL; exact u32_toNat_add (by simp [UInt32.toNat_ofNat]; omega)
27
28theorem pullL_hold (l : L) (x p) (hb : l.bits.toNat ≤ 30) (hH : l.hold.toNat < 2 ^ l.bits.toNat) :
29    (pullL l x p).hold.toNat = l.hold.toNat + x.toNat * 2 ^ l.bits.toNat := by
30  unfold pullL
31  have h1 := u64_shl x hb
32  have h2 : l.hold.toNat + x.toNat * 2 ^ l.bits.toNat < 2 ^ 64 := by
33    have hx := UInt8.toNat_lt x
34    have : x.toNat * 2 ^ l.bits.toNat ≤ 255 * 2 ^ 30 := by
35      calc x.toNat * 2 ^ l.bits.toNat ≤ 255 * 2 ^ l.bits.toNat := Nat.mul_le_mul_right _ (by omega)
36        _ ≤ 255 * 2 ^ 30 := Nat.mul_le_mul_left _ (Nat.pow_le_pow_right (by omega) hb)
37    have : l.hold.toNat < 2 ^ 30 := Nat.lt_of_lt_of_le hH (Nat.pow_le_pow_right (by omega) hb)
38    omega
39  rw [u64_toNat_add (by rw [h1]; exact h2), h1]
40
41theorem pull_run (h : Heap) (l : L) (i o : Nat) (hl : LS e l i o) (hb : l.bits.toNat ≤ 22)
42    (hi : i < e.i0 + e.sm0.avail_in.toNat) (hIN : h.bytes e.ib = some e.IN) :
43    OkOn h (pull l) (pullL l (e.IN.getD i 0) (.ref (BRef.blk e.ib) (i + 1))) := by
44  have hlt : i < e.IN.size := by have := e.hINsz; omega
45  have hg : Space.get h (BRef.blk e.ib) = some e.IN := hIN
46  unfold pull
47  rw [hl.hin]
48  refine OkOn.bind (x := e.IN[i]) (Ptr.load_ok hg hlt) ?_
49  have hadd := Ptr.add_nat_ok (h := h) (r := BRef.blk e.ib) (a := e.IN) (off := i) (n := 1) hg (by omega)
50  refine OkOn.bind (x := Ptr.ref (BRef.blk e.ib) (i + 1)) (by simpa using hadd) ?_
51  have hsh : shl64 e.IN[i].toUInt64 l.bits.toUInt64 = pure (e.IN[i].toUInt64 <<< l.bits.toUInt64) :=
52    shl64_eq (by rw [UInt32.toNat_toUInt64]; omega)
53  rw [hsh]
54  have : e.IN.getD i 0 = e.IN[i] := by simp [Array.getD_eq_getD_getElem?, hlt]
55  rw [this]
56  exact rfl
57
58theorem LS.pull {l : L} {i o : Nat} (hl : LS e l i o) (hb : l.bits.toNat ≤ 22) (hi : i < e.i0 + e.sm0.avail_in.toNat)
59    (x : UInt8) : LS e (pullL l x (.ref (BRef.blk e.ib) (i + 1))) (i + 1) o := by
60  have hb' := pullL_bits l x (.ref (BRef.blk e.ib) (i + 1)) hl.hb
61  have hh' := pullL_hold l x (.ref (BRef.blk e.ib) (i + 1)) hl.hb hl.hH
62  have hx := UInt8.toNat_lt x
63  refine ⟨rfl, hl.hout, by have := hl.hi0; omega, by omega, hl.ho0, by omega, ?_, by have := hl.hacc; omega⟩
64  rw [hh', hb']
65  have h8 : 2 ^ (l.bits.toNat + 8) = 2 ^ l.bits.toNat * 256 := by rw [Nat.pow_add]
66  rw [h8]
67  have := hl.hH
68  have h3 : (x.toNat + 1) * 2 ^ l.bits.toNat ≤ 256 * 2 ^ l.bits.toNat := Nat.mul_le_mul_right _ (by omega)
69  have : (x.toNat + 1) * 2 ^ l.bits.toNat = x.toNat * 2 ^ l.bits.toNat + 2 ^ l.bits.toNat := by simp [Nat.add_mul]
70  omega
71
72end Zlib.Inffast.Proofs
ZLIB × LEAN

全局目录

当前位置inffast.c.step1.lean