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

inffast.c.length-semantics.lean

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

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

1import ZlibF.Spec.InflateFastLengthSemantics
2import ZlibF.Proof.«inftrees.c.decode.stability-rejection»
3
4/-!
5# Fast length lookup and independent decoding
6
7The existing fast lookup relation is tied to the same finite two-level
8query as the slow decoder. Constructor-derived flags reconcile acceptance
9before the invariant supplies independent symbol meaning or rejection.
10-/
11
12set_option autoImplicit false
13
14namespace Zlib.Inffast.Proofs
15open C Zlib.Inffast Zlib.Inffast.Spec ZlibF.Spec
16open Zlib.Inftrees.Spec Zlib.Inftrees.Spec.DecodeSemantics
17open Zlib.Inftrees.Spec.DecodeSoundness
18open Zlib.Inffast.Spec.LengthSemantics
19
20/-- Every selected fast length leaf has the independent meaning of its
21actual table query, including all future-stable rejected prefixes. -/
22theorem length_lookup_matches_format : Goal.length_lookup_matches_format := by
23  intro e hold bits input tableUsed lens entry consumed inv stable flags hhold hbits look
24  let root := e.s0.lenbits.toNat
25  let idx := hold % 2 ^ root
26  let stream := Sg e hold bits input
27  have rootLe : root ≤ 15 := inv.rootTable.2.1
28  have idxLt : idx < 2 ^ root := Nat.mod_lt _ (Nat.two_pow_pos root)
29  have rootRead : readBits root stream =
30      some (idx, Sg e (hold / 2 ^ root) (bits-root) input) := by
31    exact readBits_bitsOfNat root bits hold (inBits e input) (by omega)
32  obtain ⟨first, firstCell, firstPos, firstBits⟩ := inv.rootTable.2.2.2 idx idxLt
33  have firstGet : e.LCA.getD (e.ol + idx) default = first := by
34    simp only [Array.getD_eq_getD_getElem?, firstCell, Option.getD_some]
35  have maskBits (op : UInt8) (hm : op &&& 0xf0 = 0) : op &&& 16 = 0 ∧ op &&& 64 = 0 := by
36    have h16 := congrArg (fun x : UInt8 => x &&& 16) hm
37    have h64 := congrArg (fun x : UInt8 => x &&& 64) hm
38    rw [UInt8.and_assoc] at h16 h64
39    exact ⟨h16, h64⟩
40  have smallMask : ∀ op : UInt8, op.toNat ≤ 15 → op &&& 0xf0 = 0 := by
41    apply u8_forall
42    decide +kernel
43  have selected : tableRead LENS e.LCA e.ol root stream = some (entry, consumed) ∧
44      1 ≤ consumed ∧ consumed ≤ 15 ∧ LenLeaf 0 entry := by
45    rcases look with ⟨hget, hconsumed, noLink⟩ |
46      ⟨E0, j, hget, link, jLt, jEq, hleafGet, hconsumed, codeLe, noLink⟩
47    · change e.LCA.getD (e.ol + idx) default = entry at hget
48      have he : first = entry := firstGet.symm.trans hget
49      rw [he] at firstCell firstPos firstBits
50      have slowNoLink : (entry.op != 0 && (entry.op &&& 0xf0) == 0) = false := by
51        by_cases opNonzero : entry.op ≠ 0
52        · have invalidMask : entry.op &&& 0xf0 ≠ 0 := by
53            intro hm
54            exact noLink ⟨opNonzero, maskBits entry.op hm⟩
55          simp [invalidMask]
56        · simp_all
57      have leaf := e.hlt.2.2 idx idxLt
58      rw [hget, ite_eq_right noLink] at leaf
59      refine ⟨?_, ?_, ?_, leaf⟩
60      · simp only [tableRead, rootRead, bind, Option.bind, firstCell]
61        simp only [ite_true]
62        simp [slowNoLink, hconsumed]
63      · omega
64      · omega
65    · change e.LCA.getD (e.ol + idx) default = E0 at hget
66      have he : first = E0 := firstGet.symm.trans hget
67      rw [he] at firstCell firstPos firstBits
68      have linkOK := e.hlt.2.2 idx idxLt
69      rw [hget, ite_eq_left link] at linkOK
70      have opMask : E0.op &&& 0xf0 = 0 := smallMask E0.op linkOK.2.2.1
71      have slowLink : Subtable.IsLink LENS E0 = true := by
72        simp [Subtable.IsLink, link.1, opMask]
73      obtain ⟨bitsRoot, subSafe⟩ := inv.subtables idx E0 idxLt firstCell slowLink
74      have rootFits : E0.bits.toNat ≤ bits := by omega
75      have opFits : E0.op.toNat ≤ bits - E0.bits.toNat := by have := subSafe.2.2.1; omega
76      have secondRead : readBits E0.op.toNat (stream.drop E0.bits.toNat) =
77          some (j, Sg e ((hold / 2 ^ E0.bits.toNat) / 2 ^ E0.op.toNat)
78            ((bits-E0.bits.toNat)-E0.op.toNat) input) := by
79        rw [show stream.drop E0.bits.toNat = Sg e (hold / 2 ^ E0.bits.toNat) (bits-E0.bits.toNat) input
80          from (Sg_drop hold bits input E0.bits.toNat rootFits).symm]
81        rw [jEq]
82        exact readBits_bitsOfNat E0.op.toNat (bits-E0.bits.toNat) (hold / 2 ^ E0.bits.toNat)
83          (inBits e input) opFits
84      obtain ⟨second, secondCell, secondPos, secondBits⟩ := subSafe.2.2.2.2 j jLt
85      have secondGet : e.LCA.getD (e.ol+E0.val.toNat+j) default = second := by
86        simp only [Array.getD_eq_getD_getElem?, secondCell, Option.getD_some]
87      have he : second = entry := secondGet.symm.trans hleafGet
88      rw [he] at secondCell secondPos secondBits
89      have leafD := linkOK.2.2.2.2 j jLt
90      rw [hleafGet] at leafD
91      have leaf : LenLeaf 0 entry := ⟨by have := leafD.1; omega, leafD.2⟩
92      refine ⟨?_, ?_, by omega, leaf⟩
93      · simp only [tableRead, rootRead, bind, Option.bind, firstCell]
94        simp only [ite_true, opMask, BEq.rfl]
95        simp only [secondRead, Option.bind_some, secondCell]
96        simp [hconsumed, link.1]
97      · omega
98  obtain ⟨query, positive, codeLe, leaf⟩ := selected
99  have streamLong : 15 ≤ stream.length := by
100    simp only [stream, Sg, List.length_append, bitsOfNat_length]
101    omega
102  have paddedStream : DecodeShort.padded stream = stream := by
103    simp [DecodeShort.padded, Nat.sub_eq_zero_of_le streamLong]
104  have queryPadded : tableRead LENS e.LCA e.ol root (DecodeShort.padded stream) = some (entry,consumed) := by
105    rw [paddedStream]
106    exact query
107  have fit : consumed ≤ stream.length := by omega
108  have compatible := flags stream entry consumed streamLong query
109  refine ⟨query, positive, codeLe, leaf, ?_⟩
110  have agrees : FastTableFlags.FastLeafAccepted LENS entry ↔ LeafAccepted LENS entry := by
111    rcases leaf.2 with literal | base | invalid
112    · simp [FastTableFlags.FastLeafAccepted, LeafAccepted, literal]
113    · have validFlag := compatible base.1
114      simp [FastTableFlags.FastLeafAccepted, LeafAccepted, base.1, validFlag]
115    · have nonzero : entry.op ≠ 0 := by
116        intro zero
117        simp [zero] at invalid
118      simp [FastTableFlags.FastLeafAccepted, LeafAccepted, nonzero, invalid.1, invalid.2]
119  by_cases accepted : FastTableFlags.FastLeafAccepted LENS entry
120  · right
121    obtain ⟨symbol, valid, meaning, hused, decoded, extended⟩ :=
122      inv.short stream entry consumed queryPadded fit (agrees.mp accepted)
123    exact ⟨accepted, symbol, valid, meaning, hused, decoded, extended⟩
124  · left
125    have rejected : ¬ LeafAccepted LENS entry := fun h => accepted (agrees.mpr h)
126    have noValid := Zlib.Inftrees.Proofs.short_rejected_leaf_stays_invalid LENS e.LCA e.ol root tableUsed lens
127      inv stable stream entry consumed queryPadded fit rejected
128    exact ⟨accepted, noValid⟩
129
130end Zlib.Inffast.Proofs
ZLIB × LEAN

全局目录

当前位置inffast.c.length-semantics.lean