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

inffast.c.lp.lean

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

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

1import ZlibF.Proof.«inffast.c.pass»
2
3namespace Zlib.Inffast.Proofs
4open C Zlib.Inffast Zlib.Inffast.Spec ZlibF.Spec
5
6theorem fuel_split2 : ∃ n, fuel = n + 1 + 1 := ⟨fuel - 2, by unfold fuel; omega⟩
7
8theorem cdoWhile_one {σ : Type} {body : σ → M σ} {cond : σ → M (Bool × σ)} {s s1 s1' : σ} {h h1 : Heap}
9    (e1 : body s h = .ok (s1, h1)) (c1 : cond s1 h1 = .ok ((false, s1'), h1)) :
10    cdoWhile body cond s h = .ok (s1', h1) := by
11  obtain ⟨n, hn⟩ := fuel_split2
12  unfold cdoWhile
13  rw [hn]
14  simp [cdoWhile.go, e1, c1]
15
16theorem cdoWhile_two {σ : Type} {body : σ → M σ} {cond : σ → M (Bool × σ)} {s s1 s1' s2 s2' : σ} {h h1 h2 : Heap}
17    (e1 : body s h = .ok (s1, h1)) (c1 : cond s1 h1 = .ok ((true, s1'), h1))
18    (e2 : body s1' h1 = .ok (s2, h2)) (c2 : cond s2 h2 = .ok ((false, s2'), h2)) :
19    cdoWhile body cond s h = .ok (s2', h2) := by
20  obtain ⟨n, hn⟩ := fuel_split2
21  unfold cdoWhile
22  rw [hn]
23  simp [cdoWhile.go, e1, c1, e2, c2]
24
25
26variable {e : Env} {c : Ctx}
27
28theorem DistLeaf_class (d : Nat) (E : Code) (h : DistLeaf d E) : (E.op &&& 16 ≠ 0 ∧ (E.op &&& 15).toNat ≤ 13 ∧ 1 ≤ E.val.toNat) ∨
29    (E.op &&& 16 = 0 ∧ E.op &&& 64 ≠ 0) := h.2
30
31/-- A root entry of the distance table is either a leaf or a link whose second level is in range. -/
32theorem distRoot (hts : DistTableSafe e.DCA e.od e.s0.distbits.toNat) (kidx : Nat) (hk : kidx < 2 ^ e.s0.distbits.toNat) :
33    e.od + kidx < e.DCA.size ∧
34    ((DistLink (e.DCA.getD (e.od + kidx) default) → LinkOK DistLeaf e.DCA e.od (e.DCA.getD (e.od + kidx) default)) ∧
35     (¬ DistLink (e.DCA.getD (e.od + kidx) default) → DistLeaf 0 (e.DCA.getD (e.od + kidx) default))) := by
36  obtain ⟨_, hsz, hall⟩ := hts
37  refine ⟨by omega, ?_⟩
38  have := hall kidx hk
39  by_cases hl : DistLink (e.DCA.getD (e.od + kidx) default)
40  · rw [ite_eq_left hl] at this
41    exact ⟨fun _ => this, fun h => absurd hl h⟩
42  · rw [ite_eq_right hl] at this
43    exact ⟨fun h => absurd h hl, fun _ => this⟩
44
45theorem distClass_of (E : Code) (hl : DistLink E → LinkOK DistLeaf e.DCA e.od E) (hn : ¬ DistLink E → DistLeaf 0 E) :
46    DistClass e E := by
47  by_cases h : DistLink E
48  · have := hl h
49    exact Or.inr (Or.inl ⟨h.1, h.2, this.2.1, this.2.2.1, this.2.2.2.1⟩)
50  · have := (hn h).2
51    rcases this with h1 | h1
52    · exact Or.inl h1
53    · exact Or.inr (Or.inr h1)
54
55
56/-- The entry on which a distance lookup ends and the number of bits it consumes, for the hold value `H` and the root
57index `kidx`: a root leaf, or a root link and a leaf of its second level. -/
58def DistLook (e : Env) (H kidx : Nat) (E : Code) (cb : Nat) : Prop :=
59  (e.DCA.getD (e.od + kidx) default = E ∧ cb = E.bits.toNat ∧ ¬ DistLink E) ∨
60  (∃ E0 j, e.DCA.getD (e.od + kidx) default = E0 ∧ DistLink E0 ∧ j < 2 ^ E0.op.toNat ∧
61     j = (H / 2 ^ E0.bits.toNat) % 2 ^ E0.op.toNat ∧ e.DCA.getD (e.od + E0.val.toNat + j) default = E ∧
62     cb = E0.bits.toNat + E.bits.toNat ∧ E0.bits.toNat + E.bits.toNat ≤ 15 ∧ ¬ DistLink E)
63
64theorem dodistLoop_wp (hc : CtxOK e c) (A : Array UInt8) (msg : BPtr) (m : UInt32) (l : L) (i o kidx : Nat)
65    (hts : DistTableSafe e.DCA e.od e.s0.distbits.toNat) (hk : kidx < 2 ^ e.s0.distbits.toNat)
66    (hls : LS e l i o) (hA : e.o0 + e.sm0.avail_out.toNat ≤ A.size) (ho : o + 258 ≤ e.o0 + e.sm0.avail_out.toNat)
67    (hAb : A.size < 2 ^ 63) (hbroke : l.broke = false) (hlen : 3 ≤ l.len.toNat ∧ l.len.toNat ≤ 258)
68    (hhere : l.here = .ref e.rd (e.od + kidx)) (hb15 : 15 ≤ l.bits.toNat)
69    (hpull : i + 2 ≤ e.i0 + e.sm0.avail_in.toNat ∨ (i + 1 ≤ e.i0 + e.sm0.avail_in.toNat ∧ 20 ≤ l.bits.toNat)) :
70    Wp (cdoWhile (dodist c) (fun l => pure (l.againD, l)) l) (e.heap A msg m) (fun l' h' =>
71      ∃ E cb, cb ≤ 15 ∧ DistLook e l.hold.toNat kidx E cb ∧
72        DistEnd e A msg m ((Sg e l.hold.toNat l.bits.toNat i).drop cb) i o l.len.toNat E l' h') := by
73  obtain ⟨hksz, hlk, hnl⟩ := distRoot hts kidx hk
74  have hcl0 := distClass_of (e := e) _ hlk hnl
75  have hEd0 : (e.DCA.getD (e.od + kidx) default).bits.toNat + 0 ≤ 15 := by
76    by_cases hl : DistLink (e.DCA.getD (e.od + kidx) default)
77    · have := (hlk hl).1; omega
78    · have := (hnl hl).1; omega
79  obtain ⟨l1, h1, e1, hq1⟩ := dodist_pass hc A msg m l i o 0 (e.od + kidx) hls hA ho hAb hbroke hlen hhere hksz
80    (by omega) hEd0 hcl0 (by simpa using hpull)
81  obtain ⟨E0, hE0⟩ : ∃ E0, e.DCA.getD (e.od + kidx) default = E0 := ⟨_, rfl⟩
82  rw [hE0] at hq1 hlk hnl hcl0 hEd0
83  rcases hq1 with ⟨hag, hbr, hh, ⟨hl16, hl64⟩, j, hjlt, hjd, hhere1, hls1, hsg1, hb1, hlen1, hout1, hdist1, hagL1⟩ | ⟨hNL, hag, hend⟩
84  · -- a link: the second pass ends the block
85    subst hh
86    have hlink : DistLink E0 := ⟨hl16, hl64⟩
87    have hlk' := hlk hlink
88    have hleaf := hlk'.2.2.2.2 j hjlt
89    have hk2 : e.od + E0.val.toNat + j < e.DCA.size := by
90      have := hlk'.2.2.2.1; omega
91    have hcl1 : DistClass e (e.DCA.getD (e.od + E0.val.toNat + j) default) := by
92      rcases hleaf.2 with h | h
93      · exact Or.inl h
94      · exact Or.inr (Or.inr h)
95    have hb15' : E0.bits.toNat ≤ 15 := hlk'.1
96    obtain ⟨l2, h2, e2, hq2⟩ := dodist_pass hc A msg m l1 i o E0.bits.toNat (e.od + E0.val.toNat + j) hls1 hA ho hAb hbr
97      (by rw [hlen1]; exact hlen) hhere1 hk2 (by have := hleaf.1; omega) (by omega) hcl1 (by
98        rcases hpull with h | h
99        · exact Or.inl h
100        · exact Or.inr ⟨h.1, by omega⟩)
101    rcases hq2 with ⟨hag2, -, -, ⟨hl16', hl64'⟩, -⟩ | hend2
102    · rcases hleaf.2 with h | h
103      · exact absurd hl16' h.1
104      · exact absurd hl64' h.2
105    · have c1 : (fun l : L => (pure (l.againD, l) : M (Bool × L))) l1 (e.heap A msg m) = .ok ((true, l1), e.heap A msg m) := by simp [hag]
106      have c2 : (fun l : L => (pure (l.againD, l) : M (Bool × L))) l2 h2 = .ok ((false, l2), h2) := by simp [hend2.2.1]
107      have e1' : dodist c l (e.heap A msg m) = .ok (l1, e.heap A msg m) := e1
108      refine Wp.of_eq (cdoWhile_two e1' c1 e2 c2) ?_
109      refine ⟨e.DCA.getD (e.od + E0.val.toNat + j) default, E0.bits.toNat + (e.DCA.getD (e.od + E0.val.toNat + j) default).bits.toNat, by have := hleaf.1; omega, ?_, ?_⟩
110      · refine Or.inr ⟨E0, j, hE0, hlink, hjlt, ?_, rfl, rfl, by have := hleaf.1; omega, ?_⟩
111        · rw [hjd]
112        · intro hl; rcases hleaf.2 with h | h
113          · exact absurd hl.1 h.1
114          · exact absurd hl.2 h.2
115      · have := hend2
116        rw [hlen1] at this
117        have hd : (Sg e l.hold.toNat l.bits.toNat i).drop (E0.bits.toNat + (e.DCA.getD (e.od + E0.val.toNat + j) default).bits.toNat) =
118            ((Sg e l.hold.toNat l.bits.toNat i).drop E0.bits.toNat).drop (e.DCA.getD (e.od + E0.val.toNat + j) default).bits.toNat := by
119          rw [List.drop_drop]
120        rw [hd, ← hsg1]
121        exact this
122  · -- the first pass ended the block
123    have c1 : (fun l : L => (pure (l.againD, l) : M (Bool × L))) l1 h1 = .ok ((false, l1), h1) := by simp [hag]
124    refine Wp.of_eq (cdoWhile_one e1 c1) ?_
125    refine ⟨E0, E0.bits.toNat, by omega, Or.inl ⟨hE0, rfl, hNL⟩, ⟨hNL, hag, hend⟩⟩
126
127end Zlib.Inffast.Proofs
ZLIB × LEAN

全局目录

当前位置inffast.c.lp.lean