1use super::spec::*;
3use crate::core::{proof::*, spec::*};
4use vstd::prelude::*;
5
6verus! {
7
8impl<Inner, M> SPRoundTripDps for super::Mapped<Inner, M> where
9 Inner: SPRoundTripDps,
10 M: LossyMapper<In = Inner::T>,
11 {
12 open spec fn unambiguous(&self) -> bool {
13 self.inner.unambiguous()
14 }
15
16 proof fn theorem_serialize_dps_parse_roundtrip(&self, v: Self::T, obuf: Seq<u8>) {
17 let inner_v = self.mapper.spec_map_rev(v);
18 assert(self.unambiguous());
19 self.inner.theorem_serialize_dps_parse_roundtrip(inner_v, obuf);
20 assert(self.mapper.wf_out(v));
21 self.mapper.lemma_sound_mapper(v);
22 }
23}
24
25impl<Inner, M> NonMalleable for super::Mapped<Inner, M> where
26 Inner: SoundParser + NonMalleable,
27 M: LosslessMapper<In = Inner::PVal>,
28 {
29 open spec fn nonmal_inv(&self) -> bool {
30 &&& self.inner.nonmal_inv()
31 &&& self.inner.sound_inv()
32 &&& forall|v: Inner::T| #![auto] self.inner.consistent(v) ==> self.mapper.wf_in(v)
33 }
34
35 proof fn lemma_parse_non_malleable(&self, buf1: Seq<u8>, buf2: Seq<u8>) {
36 assert(self.nonmal_inv());
37 if let Some((n1, v1)) = self.spec_parse(buf1) {
38 if let Some((n2, v2)) = self.spec_parse(buf2) {
39 if v1 == v2 {
40 let (i_n1, i_v1) = self.inner.spec_parse(buf1)->0;
41 let (i_n2, i_v2) = self.inner.spec_parse(buf2)->0;
42 self.inner.lemma_parse_sound_value(buf1);
43 self.inner.lemma_parse_sound_value(buf2);
44 assert(self.mapper.wf_in(i_v1));
45 assert(self.mapper.wf_in(i_v2));
46 self.mapper.lemma_lossless_mapper(i_v1);
47 self.mapper.lemma_lossless_mapper(i_v2);
48 self.inner.lemma_parse_non_malleable(buf1, buf2);
49 }
50 }
51 }
52 }
53}
54
55impl<Inner, M> NoLookAhead for super::Mapped<Inner, M> where
56 Inner: NoLookAhead,
57 M: SpecMapper<In = Inner::PVal>,
58 {
59 open spec fn no_lookahead_inv(&self) -> bool {
60 self.inner.no_lookahead_inv()
61 }
62
63 proof fn lemma_no_lookahead(&self, i1: Seq<u8>, i2: Seq<u8>) {
64 if let Some((n, v)) = self.spec_parse(i1) {
65 if 0 <= n <= i2.len() {
66 if i2[0..n] == i1[0..n] {
67 assert(self.safe_inv());
68 assert(self.no_lookahead_inv());
69 self.inner.lemma_no_lookahead(i1, i2);
70 }
71 }
72 }
73 }
74}
75
76impl<Inner, M> Productive for super::Mapped<Inner, M> where
77 Inner: Productive,
78 M: SpecMapper<In = Inner::PVal>,
79 {
80 open spec fn productive_inv(&self) -> bool {
81 self.inner.productive_inv()
82 }
83
84 proof fn lemma_productive(&self, s: Seq<u8>) {
85 self.inner.lemma_productive(s);
86 }
87}
88
89impl<Inner, M> EquivSerializersGeneral for super::Mapped<Inner, M> where
90 Inner: EquivSerializersGeneral,
91 M: SpecMapper<In = Inner::SVal>,
92 {
93 open spec fn equiv_general_inv(&self) -> bool {
94 self.inner.equiv_general_inv()
95 }
96
97 proof fn lemma_serialize_equiv(&self, v: Self::SVal, obuf: Seq<u8>) {
98 let inner_v = self.mapper.spec_map_rev(v);
99 self.inner.lemma_serialize_equiv(inner_v, obuf);
100 }
101}
102
103impl<Inner, M> EquivSerializers for super::Mapped<Inner, M> where
104 Inner: EquivSerializers,
105 M: SpecMapper<In = Inner::SVal>,
106 {
107 open spec fn equiv_inv(&self) -> bool {
108 self.inner.equiv_inv()
109 }
110
111 proof fn lemma_serialize_equiv_on_empty(&self, v: Self::SVal) {
112 let inner_v = self.mapper.spec_map_rev(v);
113 self.inner.lemma_serialize_equiv_on_empty(inner_v);
114 }
115}
116
117impl<Inner: SPRoundTripDps, Out> SPRoundTripDps for super::Mapped<
122 Inner,
123 FnSpecMapper<Inner::T, Out>,
124> {
125 open spec fn unambiguous(&self) -> bool {
126 &&& self.inner.unambiguous()
127 &&& forall|o: Out| #[trigger]
128 self.consistent(o) ==> (self.mapper.0)((self.mapper.1)(o)) == o
129 }
130
131 proof fn theorem_serialize_dps_parse_roundtrip(&self, v: Self::T, obuf: Seq<u8>) {
132 let inner_v = self.mapper.1(v);
133 self.inner.theorem_serialize_dps_parse_roundtrip(inner_v, obuf);
134 }
135}
136
137impl<Inner, Out> NonMalleable for super::Mapped<Inner, FnSpecMapper<Inner::PVal, Out>> where
138 Inner: SoundParser + NonMalleable,
139 {
140 open spec fn nonmal_inv(&self) -> bool {
141 &&& self.inner.nonmal_inv()
142 &&& self.inner.sound_inv()
143 &&& forall|v: Inner::PVal| #[trigger]
144 self.inner.consistent(v) ==> (self.mapper.1)((self.mapper.0)(v)) == v
145 }
146
147 proof fn lemma_parse_non_malleable(&self, buf1: Seq<u8>, buf2: Seq<u8>) {
148 if let Some((n1, v1)) = self.spec_parse(buf1) {
149 if let Some((n2, v2)) = self.spec_parse(buf2) {
150 if v1 == v2 {
151 let (i_n1, i_v1) = self.inner.spec_parse(buf1)->0;
152 let (i_n2, i_v2) = self.inner.spec_parse(buf2)->0;
153 self.inner.lemma_parse_sound_value(buf1);
154 self.inner.lemma_parse_sound_value(buf2);
155 self.inner.lemma_parse_non_malleable(buf1, buf2);
156 }
157 }
158 }
159 }
160}
161
162impl<Inner, M, MRev> SPRoundTripDps for super::Mapped<Inner, BiMap<M, MRev>> where
167 Inner: SPRoundTripDps,
168 M: SpecMap<Input = Inner::T>,
169 MRev: SpecMap<Input = M::Output, Output = M::Input>,
170 {
171 open spec fn unambiguous(&self) -> bool {
172 &&& self.inner.unambiguous()
173 &&& forall|o: M::Output| #![auto] self.consistent(o) ==> self.mapper.sound(o)
174 }
175
176 proof fn theorem_serialize_dps_parse_roundtrip(&self, v: Self::T, obuf: Seq<u8>) {
177 assert(self.unambiguous());
178 assert(self.mapper.sound(v));
179 let inner_v = self.mapper.1.spec_map(v);
180 self.inner.theorem_serialize_dps_parse_roundtrip(inner_v, obuf);
181 }
182}
183
184impl<Inner, M, MRev> NonMalleable for super::Mapped<Inner, BiMap<M, MRev>> where
185 Inner: SoundParser + NonMalleable,
186 M: SpecMap<Input = Inner::PVal>,
187 MRev: SpecMap<Input = M::Output, Output = M::Input>,
188 {
189 open spec fn nonmal_inv(&self) -> bool {
190 &&& self.inner.nonmal_inv()
191 &&& self.inner.sound_inv()
192 &&& forall|i: Inner::T| #![auto] self.inner.consistent(i) ==> self.mapper.lossless(i)
193 }
194
195 proof fn lemma_parse_non_malleable(&self, buf1: Seq<u8>, buf2: Seq<u8>) {
196 if let Some((n1, v1)) = self.spec_parse(buf1) {
197 if let Some((n2, v2)) = self.spec_parse(buf2) {
198 if v1 == v2 {
199 let (i_n1, i_v1) = self.inner.spec_parse(buf1)->0;
200 let (i_n2, i_v2) = self.inner.spec_parse(buf2)->0;
201 self.inner.lemma_parse_sound_value(buf1);
202 self.inner.lemma_parse_sound_value(buf2);
203 self.inner.lemma_parse_non_malleable(buf1, buf2);
204 }
205 }
206 }
207 }
208}
209
210impl<Inner, M, MRev> NoLookAhead for super::Mapped<Inner, BiMap<M, MRev>> where
211 Inner: NoLookAhead,
212 M: SpecMap<Input = Inner::PVal>,
213 MRev: SpecMap<Input = M::Output, Output = M::Input>,
214 {
215 open spec fn no_lookahead_inv(&self) -> bool {
216 self.inner.no_lookahead_inv()
217 }
218
219 proof fn lemma_no_lookahead(&self, i1: Seq<u8>, i2: Seq<u8>) {
220 if let Some((n, v)) = self.spec_parse(i1) {
221 if 0 <= n <= i2.len() {
222 if i2[0..n] == i1[0..n] {
223 assert(self.safe_inv());
224 assert(self.no_lookahead_inv());
225 self.inner.lemma_no_lookahead(i1, i2);
226 }
227 }
228 }
229 }
230}
231
232impl<Inner, M, MRev> Productive for super::Mapped<Inner, BiMap<M, MRev>> where
233 Inner: Productive,
234 M: SpecMap<Input = Inner::PVal>,
235 MRev: SpecMap<Input = M::Output, Output = M::Input>,
236 {
237 open spec fn productive_inv(&self) -> bool {
238 self.inner.productive_inv()
239 }
240
241 proof fn lemma_productive(&self, s: Seq<u8>) {
242 self.inner.lemma_productive(s);
243 }
244}
245
246impl<Inner, M, MRev> EquivSerializersGeneral for super::Mapped<Inner, BiMap<M, MRev>> where
247 Inner: EquivSerializersGeneral,
248 M: SpecMap<Input = Inner::SVal>,
249 MRev: SpecMap<Input = M::Output, Output = M::Input>,
250 {
251 open spec fn equiv_general_inv(&self) -> bool {
252 self.inner.equiv_general_inv()
253 }
254
255 proof fn lemma_serialize_equiv(&self, v: Self::SVal, obuf: Seq<u8>) {
256 let inner_v = self.mapper.1.spec_map(v);
257 self.inner.lemma_serialize_equiv(inner_v, obuf);
258 }
259}
260
261impl<Inner, M, MRev> EquivSerializers for super::Mapped<Inner, BiMap<M, MRev>> where
262 Inner: EquivSerializers,
263 M: SpecMap<Input = Inner::SVal>,
264 MRev: SpecMap<Input = M::Output, Output = M::Input>,
265 {
266 open spec fn equiv_inv(&self) -> bool {
267 self.inner.equiv_inv()
268 }
269
270 proof fn lemma_serialize_equiv_on_empty(&self, v: Self::SVal) {
271 let inner_v = self.mapper.1.spec_map(v);
272 self.inner.lemma_serialize_equiv_on_empty(inner_v);
273 }
274}
275
276impl<Inner, M> SPRoundTripDps for super::TryMap<Inner, M> where
277 Inner: SPRoundTripDps,
278 M: LossyMapper<In = Inner::T>,
279 {
280 open spec fn unambiguous(&self) -> bool {
281 self.inner().unambiguous()
282 }
283
284 proof fn theorem_serialize_dps_parse_roundtrip(&self, v: Self::T, obuf: Seq<u8>) {
285 self.inner().theorem_serialize_dps_parse_roundtrip(v, obuf);
286 }
287}
288
289impl<Inner, M> NonMalleable for super::TryMap<Inner, M> where
290 Inner: SoundParser + NonMalleable,
291 M: LosslessMapper<In = Inner::PVal>,
292 {
293 open spec fn nonmal_inv(&self) -> bool {
294 self.inner().nonmal_inv()
295 }
296
297 proof fn lemma_parse_non_malleable(&self, buf1: Seq<u8>, buf2: Seq<u8>) {
298 self.inner().lemma_parse_non_malleable(buf1, buf2);
299 }
300}
301
302impl<Inner, M> NoLookAhead for super::TryMap<Inner, M> where
303 Inner: NoLookAhead,
304 M: LossyMapper<In = Inner::PVal>,
305 {
306 open spec fn no_lookahead_inv(&self) -> bool {
307 self.inner().no_lookahead_inv()
308 }
309
310 proof fn lemma_no_lookahead(&self, i1: Seq<u8>, i2: Seq<u8>) {
311 assert(self.no_lookahead_inv());
312 self.inner().lemma_no_lookahead(i1, i2);
313 }
314}
315
316impl<Inner, M> Productive for super::TryMap<Inner, M> where
317 Inner: Productive,
318 M: SpecMapper<In = Inner::PVal>,
319 {
320 open spec fn productive_inv(&self) -> bool {
321 self.inner().productive_inv()
322 }
323
324 proof fn lemma_productive(&self, s: Seq<u8>) {
325 self.inner().lemma_productive(s);
326 }
327}
328
329impl<Inner, M> EquivSerializersGeneral for super::TryMap<Inner, M> where
330 Inner: EquivSerializersGeneral,
331 M: SpecMapper<In = Inner::SVal>,
332 {
333 open spec fn equiv_general_inv(&self) -> bool {
334 self.inner().equiv_general_inv()
335 }
336
337 proof fn lemma_serialize_equiv(&self, v: Self::SVal, obuf: Seq<u8>) {
338 self.inner().lemma_serialize_equiv(v, obuf);
339 }
340}
341
342impl<Inner, M> EquivSerializers for super::TryMap<Inner, M> where
343 Inner: EquivSerializers,
344 M: SpecMapper<In = Inner::SVal>,
345 {
346 open spec fn equiv_inv(&self) -> bool {
347 self.inner().equiv_inv()
348 }
349
350 proof fn lemma_serialize_equiv_on_empty(&self, v: Self::SVal) {
351 self.inner().lemma_serialize_equiv_on_empty(v);
352 }
353}
354
355}