1use crate::combinators::choice::Alt;
3use crate::combinators::tuple::Pair;
4use crate::combinators::Mapped;
5use crate::core::{proof::*, spec::*};
6use vstd::prelude::*;
7
8verus! {
9
10impl<P1: SafeParser, P2: SafeParser> SafeParser for super::Permute2<P1, P2> {
14 open spec fn safe_inv(&self) -> bool {
15 &&& self.0.safe_inv()
16 &&& self.1.safe_inv()
17 }
18
19 proof fn lemma_parse_safe(&self, ibuf: Seq<u8>) {
20 Alt::<_, _, false>(
21 Pair(self.0, self.1),
22 Mapped { inner: Pair(self.1, self.0), mapper: |i| super::swap2(i) },
23 ).lemma_parse_safe(ibuf);
24 }
25}
26
27impl<P1: Productive, P2: Productive> Productive for super::Permute2<P1, P2> {
28 open spec fn productive_inv(&self) -> bool {
29 &&& self.0.productive_inv()
30 &&& self.1.productive_inv()
31 }
32
33 proof fn lemma_productive(&self, ibuf: Seq<u8>) {
34 Alt::<_, _, false>(
35 Pair(self.0, self.1),
36 Mapped { inner: Pair(self.1, self.0), mapper: |i| super::swap2(i) },
37 ).lemma_productive(ibuf);
38 }
39}
40
41impl<P1: SoundParser, P2: SoundParser> SoundParser for super::Permute2<P1, P2> {
44 open spec fn sound_inv(&self) -> bool {
45 &&& self.0.sound_inv()
46 &&& self.1.sound_inv()
47 }
48
49 proof fn lemma_parse_sound_consumption(&self, ibuf: Seq<u8>) {
50 let canonical = Pair(self.0, self.1);
51 let swapped = Pair(self.1, self.0);
52 canonical.lemma_parse_sound_consumption(ibuf);
53 swapped.lemma_parse_sound_consumption(ibuf);
54 if canonical.spec_parse(ibuf) is None {
57 if let Some((_n, iv)) = swapped.spec_parse(ibuf) {
58 assert(self.byte_len(super::swap2(iv)) == swapped.byte_len(iv));
59 }
60 }
61 }
62
63 proof fn lemma_parse_sound_value(&self, ibuf: Seq<u8>) {
64 let canonical = Pair(self.0, self.1);
65 let swapped = Pair(self.1, self.0);
66 canonical.lemma_parse_sound_value(ibuf);
67 swapped.lemma_parse_sound_value(ibuf);
68 if canonical.spec_parse(ibuf) is None {
70 if let Some((_n, iv)) = swapped.spec_parse(ibuf) {
71 assert(self.consistent(super::swap2(iv)));
72 }
73 }
74 }
75}
76
77impl<P1, P2> SPRoundTripDps for super::Permute2<P1, P2> where
78 P1: SPRoundTripDps + NonTailFmt,
79 P2: SPRoundTripDps,
80 {
81 open spec fn unambiguous(&self) -> bool {
82 &&& self.0.unambiguous()
83 &&& self.1.unambiguous()
84 &&& self.0.serialize_dps_inv()
85 }
86
87 proof fn theorem_serialize_dps_parse_roundtrip(&self, v: Self::T, obuf: Seq<u8>) {
88 let canonical = Pair(self.0, self.1);
89 canonical.theorem_serialize_dps_parse_roundtrip(v, obuf);
90 }
91}
92
93impl<P1, P2> EquivSerializersGeneral for super::Permute2<P1, P2> where
94 P1: EquivSerializersGeneral,
95 P2: EquivSerializersGeneral,
96 {
97 open spec fn equiv_general_inv(&self) -> bool {
98 &&& self.0.equiv_general_inv()
99 &&& self.1.equiv_general_inv()
100 }
101
102 proof fn lemma_serialize_equiv(&self, v: Self::SVal, obuf: Seq<u8>) {
103 Pair(self.0, self.1).lemma_serialize_equiv(v, obuf);
104 }
105}
106
107impl<P1, P2> EquivSerializers for super::Permute2<P1, P2> where
108 P1: EquivSerializersGeneral,
109 P2: EquivSerializers,
110 {
111 open spec fn equiv_inv(&self) -> bool {
112 &&& self.0.equiv_general_inv()
113 &&& self.1.equiv_inv()
114 }
115
116 proof fn lemma_serialize_equiv_on_empty(&self, v: Self::SVal) {
117 Pair(self.0, self.1).lemma_serialize_equiv_on_empty(v);
118 }
119}
120
121impl<A: SafeParser, B: SafeParser, C: SafeParser> SafeParser for super::Permute3<A, B, C> {
125 open spec fn safe_inv(&self) -> bool {
126 &&& self.0.safe_inv()
127 &&& self.1.safe_inv()
128 &&& self.2.safe_inv()
129 }
130
131 proof fn lemma_parse_safe(&self, ibuf: Seq<u8>) {
132 reveal(<super::Permute3<_, _, _> as SpecParser>::spec_parse);
133 Alt::<_, _, false>(
134 Pair(self.0, super::Permute2(self.1, self.2)),
135 Alt::<_, _, false>(
136 Mapped {
137 inner: Pair(self.1, super::Permute2(self.0, self.2)),
138 mapper: |i| super::swap3_1(i),
139 },
140 Mapped {
141 inner: Pair(self.2, super::Permute2(self.0, self.1)),
142 mapper: |i| super::swap3_2(i),
143 },
144 ),
145 ).lemma_parse_safe(ibuf);
146 }
147}
148
149impl<A: Productive, B: Productive, C: Productive> Productive for super::Permute3<A, B, C> {
150 open spec fn productive_inv(&self) -> bool {
151 &&& self.0.productive_inv()
152 &&& self.1.productive_inv()
153 &&& self.2.productive_inv()
154 }
155
156 proof fn lemma_productive(&self, ibuf: Seq<u8>) {
157 reveal(<super::Permute3<_, _, _> as SpecParser>::spec_parse);
158 Alt::<_, _, false>(
159 Pair(self.0, super::Permute2(self.1, self.2)),
160 Alt::<_, _, false>(
161 Mapped {
162 inner: Pair(self.1, super::Permute2(self.0, self.2)),
163 mapper: |i| super::swap3_1(i),
164 },
165 Mapped {
166 inner: Pair(self.2, super::Permute2(self.0, self.1)),
167 mapper: |i| super::swap3_2(i),
168 },
169 ),
170 ).lemma_productive(ibuf);
171 }
172}
173
174impl<A: SoundParser, B: SoundParser, C: SoundParser> SoundParser for super::Permute3<A, B, C> {
175 open spec fn sound_inv(&self) -> bool {
176 &&& self.0.sound_inv()
177 &&& self.1.sound_inv()
178 &&& self.2.sound_inv()
179 }
180
181 proof fn lemma_parse_sound_consumption(&self, ibuf: Seq<u8>) {
182 reveal(<super::Permute3<_, _, _> as SpecParser>::spec_parse);
183 let b0 = Pair(self.0, super::Permute2(self.1, self.2));
184 let b1 = Pair(self.1, super::Permute2(self.0, self.2));
185 let b2 = Pair(self.2, super::Permute2(self.0, self.1));
186 b0.lemma_parse_sound_consumption(ibuf);
187 b1.lemma_parse_sound_consumption(ibuf);
188 b2.lemma_parse_sound_consumption(ibuf);
189 if b0.spec_parse(ibuf) is None {
190 if let Some((_n, iv)) = b1.spec_parse(ibuf) {
191 assert(self.byte_len(super::swap3_1(iv)) == b1.byte_len(iv));
192 }
193 if b1.spec_parse(ibuf) is None {
194 if let Some((_n, iv)) = b2.spec_parse(ibuf) {
195 assert(self.byte_len(super::swap3_2(iv)) == b2.byte_len(iv));
196 }
197 }
198 }
199 }
200
201 proof fn lemma_parse_sound_value(&self, ibuf: Seq<u8>) {
202 reveal(<super::Permute3<_, _, _> as SpecParser>::spec_parse);
203 let b0 = Pair(self.0, super::Permute2(self.1, self.2));
204 let b1 = Pair(self.1, super::Permute2(self.0, self.2));
205 let b2 = Pair(self.2, super::Permute2(self.0, self.1));
206 b0.lemma_parse_sound_value(ibuf);
207 b1.lemma_parse_sound_value(ibuf);
208 b2.lemma_parse_sound_value(ibuf);
209 if b0.spec_parse(ibuf) is None {
210 if let Some((_n, iv)) = b1.spec_parse(ibuf) {
211 assert(self.consistent(super::swap3_1(iv)));
212 }
213 if b1.spec_parse(ibuf) is None {
214 if let Some((_n, iv)) = b2.spec_parse(ibuf) {
215 assert(self.consistent(super::swap3_2(iv)));
216 }
217 }
218 }
219 }
220}
221
222impl<A, B, C> SPRoundTripDps for super::Permute3<A, B, C> where
223 A: SPRoundTripDps + NonTailFmt,
224 B: SPRoundTripDps + NonTailFmt,
225 C: SPRoundTripDps,
226 {
227 open spec fn unambiguous(&self) -> bool {
228 &&& self.0.unambiguous()
229 &&& self.1.unambiguous()
230 &&& self.2.unambiguous()
231 &&& self.0.serialize_dps_inv()
232 &&& self.1.serialize_dps_inv()
233 }
234
235 proof fn theorem_serialize_dps_parse_roundtrip(&self, v: Self::T, obuf: Seq<u8>) {
236 reveal(<super::Permute3<_, _, _> as SpecParser>::spec_parse);
237 Pair(self.0, super::Permute2(self.1, self.2)).theorem_serialize_dps_parse_roundtrip(
238 v,
239 obuf,
240 );
241 }
242}
243
244impl<A, B, C> EquivSerializersGeneral for super::Permute3<A, B, C> where
245 A: EquivSerializersGeneral,
246 B: EquivSerializersGeneral,
247 C: EquivSerializersGeneral,
248 {
249 open spec fn equiv_general_inv(&self) -> bool {
250 &&& self.0.equiv_general_inv()
251 &&& self.1.equiv_general_inv()
252 &&& self.2.equiv_general_inv()
253 }
254
255 proof fn lemma_serialize_equiv(&self, v: Self::SVal, obuf: Seq<u8>) {
256 reveal(<super::Permute3<_, _, _> as SpecParser>::spec_parse);
257 Pair(self.0, super::Permute2(self.1, self.2)).lemma_serialize_equiv(v, obuf);
258 }
259}
260
261impl<A, B, C> EquivSerializers for super::Permute3<A, B, C> where
262 A: EquivSerializersGeneral,
263 B: EquivSerializersGeneral,
264 C: EquivSerializers,
265 {
266 open spec fn equiv_inv(&self) -> bool {
267 &&& self.0.equiv_general_inv()
268 &&& self.1.equiv_general_inv()
269 &&& self.2.equiv_inv()
270 }
271
272 proof fn lemma_serialize_equiv_on_empty(&self, v: Self::SVal) {
273 reveal(<super::Permute3<_, _, _> as SpecParser>::spec_parse);
274 Pair(self.0, super::Permute2(self.1, self.2)).lemma_serialize_equiv_on_empty(v);
275 }
276}
277
278impl<A: SafeParser, B: SafeParser, C: SafeParser, D: SafeParser> SafeParser for super::Permute4<
282 A,
283 B,
284 C,
285 D,
286> {
287 open spec fn safe_inv(&self) -> bool {
288 &&& self.0.safe_inv()
289 &&& self.1.safe_inv()
290 &&& self.2.safe_inv()
291 &&& self.3.safe_inv()
292 }
293
294 proof fn lemma_parse_safe(&self, ibuf: Seq<u8>) {
295 reveal(<super::Permute4<_, _, _, _> as SpecParser>::spec_parse);
296 Alt::<_, _, false>(
297 Pair(self.0, super::Permute3(self.1, self.2, self.3)),
298 Alt::<_, _, false>(
299 Mapped {
300 inner: Pair(self.1, super::Permute3(self.0, self.2, self.3)),
301 mapper: |i| super::swap4_1(i),
302 },
303 Alt::<_, _, false>(
304 Mapped {
305 inner: Pair(self.2, super::Permute3(self.0, self.1, self.3)),
306 mapper: |i| super::swap4_2(i),
307 },
308 Mapped {
309 inner: Pair(self.3, super::Permute3(self.0, self.1, self.2)),
310 mapper: |i| super::swap4_3(i),
311 },
312 ),
313 ),
314 ).lemma_parse_safe(ibuf);
315 }
316}
317
318impl<A: Productive, B: Productive, C: Productive, D: Productive> Productive for super::Permute4<
319 A,
320 B,
321 C,
322 D,
323> {
324 open spec fn productive_inv(&self) -> bool {
325 &&& self.0.productive_inv()
326 &&& self.1.productive_inv()
327 &&& self.2.productive_inv()
328 &&& self.3.productive_inv()
329 }
330
331 proof fn lemma_productive(&self, ibuf: Seq<u8>) {
332 reveal(<super::Permute4<_, _, _, _> as SpecParser>::spec_parse);
333 Alt::<_, _, false>(
334 Pair(self.0, super::Permute3(self.1, self.2, self.3)),
335 Alt::<_, _, false>(
336 Mapped {
337 inner: Pair(self.1, super::Permute3(self.0, self.2, self.3)),
338 mapper: |i| super::swap4_1(i),
339 },
340 Alt::<_, _, false>(
341 Mapped {
342 inner: Pair(self.2, super::Permute3(self.0, self.1, self.3)),
343 mapper: |i| super::swap4_2(i),
344 },
345 Mapped {
346 inner: Pair(self.3, super::Permute3(self.0, self.1, self.2)),
347 mapper: |i| super::swap4_3(i),
348 },
349 ),
350 ),
351 ).lemma_productive(ibuf);
352 }
353}
354
355impl<
356 A: SoundParser,
357 B: SoundParser,
358 C: SoundParser,
359 D: SoundParser,
360> SoundParser for super::Permute4<A, B, C, D> {
361 open spec fn sound_inv(&self) -> bool {
362 &&& self.0.sound_inv()
363 &&& self.1.sound_inv()
364 &&& self.2.sound_inv()
365 &&& self.3.sound_inv()
366 }
367
368 proof fn lemma_parse_sound_consumption(&self, ibuf: Seq<u8>) {
369 reveal(<super::Permute4<_, _, _, _> as SpecParser>::spec_parse);
370 let b0 = Pair(self.0, super::Permute3(self.1, self.2, self.3));
371 let b1 = Pair(self.1, super::Permute3(self.0, self.2, self.3));
372 let b2 = Pair(self.2, super::Permute3(self.0, self.1, self.3));
373 let b3 = Pair(self.3, super::Permute3(self.0, self.1, self.2));
374 b0.lemma_parse_sound_consumption(ibuf);
375 b1.lemma_parse_sound_consumption(ibuf);
376 b2.lemma_parse_sound_consumption(ibuf);
377 b3.lemma_parse_sound_consumption(ibuf);
378 if b0.spec_parse(ibuf) is None {
379 if let Some((_n, iv)) = b1.spec_parse(ibuf) {
380 assert(self.byte_len(super::swap4_1(iv)) == b1.byte_len(iv));
381 }
382 if b1.spec_parse(ibuf) is None {
383 if let Some((_n, iv)) = b2.spec_parse(ibuf) {
384 assert(self.byte_len(super::swap4_2(iv)) == b2.byte_len(iv));
385 }
386 if b2.spec_parse(ibuf) is None {
387 if let Some((_n, iv)) = b3.spec_parse(ibuf) {
388 assert(self.byte_len(super::swap4_3(iv)) == b3.byte_len(iv));
389 }
390 }
391 }
392 }
393 }
394
395 proof fn lemma_parse_sound_value(&self, ibuf: Seq<u8>) {
396 reveal(<super::Permute4<_, _, _, _> as SpecParser>::spec_parse);
397 let b0 = Pair(self.0, super::Permute3(self.1, self.2, self.3));
398 let b1 = Pair(self.1, super::Permute3(self.0, self.2, self.3));
399 let b2 = Pair(self.2, super::Permute3(self.0, self.1, self.3));
400 let b3 = Pair(self.3, super::Permute3(self.0, self.1, self.2));
401 b0.lemma_parse_sound_value(ibuf);
402 b1.lemma_parse_sound_value(ibuf);
403 b2.lemma_parse_sound_value(ibuf);
404 b3.lemma_parse_sound_value(ibuf);
405 if b0.spec_parse(ibuf) is None {
406 if let Some((_n, iv)) = b1.spec_parse(ibuf) {
407 assert(self.consistent(super::swap4_1(iv)));
408 }
409 if b1.spec_parse(ibuf) is None {
410 if let Some((_n, iv)) = b2.spec_parse(ibuf) {
411 assert(self.consistent(super::swap4_2(iv)));
412 }
413 if b2.spec_parse(ibuf) is None {
414 if let Some((_n, iv)) = b3.spec_parse(ibuf) {
415 assert(self.consistent(super::swap4_3(iv)));
416 }
417 }
418 }
419 }
420 }
421}
422
423impl<A, B, C, D> SPRoundTripDps for super::Permute4<A, B, C, D> where
424 A: SPRoundTripDps + NonTailFmt,
425 B: SPRoundTripDps + NonTailFmt,
426 C: SPRoundTripDps + NonTailFmt,
427 D: SPRoundTripDps,
428 {
429 open spec fn unambiguous(&self) -> bool {
430 &&& self.0.unambiguous()
431 &&& self.1.unambiguous()
432 &&& self.2.unambiguous()
433 &&& self.3.unambiguous()
434 &&& self.0.serialize_dps_inv()
435 &&& self.1.serialize_dps_inv()
436 &&& self.2.serialize_dps_inv()
437 }
438
439 proof fn theorem_serialize_dps_parse_roundtrip(&self, v: Self::T, obuf: Seq<u8>) {
440 reveal(<super::Permute4<_, _, _, _> as SpecParser>::spec_parse);
441 Pair(self.0, super::Permute3(self.1, self.2, self.3)).theorem_serialize_dps_parse_roundtrip(
442 v,
443 obuf,
444 );
445 }
446}
447
448impl<A, B, C, D> EquivSerializersGeneral for super::Permute4<A, B, C, D> where
449 A: EquivSerializersGeneral,
450 B: EquivSerializersGeneral,
451 C: EquivSerializersGeneral,
452 D: EquivSerializersGeneral,
453 {
454 open spec fn equiv_general_inv(&self) -> bool {
455 &&& self.0.equiv_general_inv()
456 &&& self.1.equiv_general_inv()
457 &&& self.2.equiv_general_inv()
458 &&& self.3.equiv_general_inv()
459 }
460
461 proof fn lemma_serialize_equiv(&self, v: Self::SVal, obuf: Seq<u8>) {
462 reveal(<super::Permute4<_, _, _, _> as SpecParser>::spec_parse);
463 Pair(self.0, super::Permute3(self.1, self.2, self.3)).lemma_serialize_equiv(v, obuf);
464 }
465}
466
467impl<A, B, C, D> EquivSerializers for super::Permute4<A, B, C, D> where
468 A: EquivSerializersGeneral,
469 B: EquivSerializersGeneral,
470 C: EquivSerializersGeneral,
471 D: EquivSerializers,
472 {
473 open spec fn equiv_inv(&self) -> bool {
474 &&& self.0.equiv_general_inv()
475 &&& self.1.equiv_general_inv()
476 &&& self.2.equiv_general_inv()
477 &&& self.3.equiv_inv()
478 }
479
480 proof fn lemma_serialize_equiv_on_empty(&self, v: Self::SVal) {
481 reveal(<super::Permute4<_, _, _, _> as SpecParser>::spec_parse);
482 Pair(self.0, super::Permute3(self.1, self.2, self.3)).lemma_serialize_equiv_on_empty(v);
483 }
484}
485
486impl<A: SafeParser, B: SafeParser, C: SafeParser, D: SafeParser, E: SafeParser> SafeParser for super::Permute5<
490 A,
491 B,
492 C,
493 D,
494 E,
495> {
496 open spec fn safe_inv(&self) -> bool {
497 &&& self.0.safe_inv()
498 &&& self.1.safe_inv()
499 &&& self.2.safe_inv()
500 &&& self.3.safe_inv()
501 &&& self.4.safe_inv()
502 }
503
504 proof fn lemma_parse_safe(&self, ibuf: Seq<u8>) {
505 Alt::<_, _, false>(
506 Pair(self.0, super::Permute4(self.1, self.2, self.3, self.4)),
507 Alt::<_, _, false>(
508 Mapped {
509 inner: Pair(self.1, super::Permute4(self.0, self.2, self.3, self.4)),
510 mapper: |i| super::swap5_1(i),
511 },
512 Alt::<_, _, false>(
513 Mapped {
514 inner: Pair(self.2, super::Permute4(self.0, self.1, self.3, self.4)),
515 mapper: |i| super::swap5_2(i),
516 },
517 Alt::<_, _, false>(
518 Mapped {
519 inner: Pair(self.3, super::Permute4(self.0, self.1, self.2, self.4)),
520 mapper: |i| super::swap5_3(i),
521 },
522 Mapped {
523 inner: Pair(self.4, super::Permute4(self.0, self.1, self.2, self.3)),
524 mapper: |i| super::swap5_4(i),
525 },
526 ),
527 ),
528 ),
529 ).lemma_parse_safe(ibuf);
530 }
531}
532
533impl<A: Productive, B: Productive, C: Productive, D: Productive, E: Productive> Productive for super::Permute5<
534 A,
535 B,
536 C,
537 D,
538 E,
539> {
540 open spec fn productive_inv(&self) -> bool {
541 &&& self.0.productive_inv()
542 &&& self.1.productive_inv()
543 &&& self.2.productive_inv()
544 &&& self.3.productive_inv()
545 &&& self.4.productive_inv()
546 }
547
548 proof fn lemma_productive(&self, ibuf: Seq<u8>) {
549 Alt::<_, _, false>(
550 Pair(self.0, super::Permute4(self.1, self.2, self.3, self.4)),
551 Alt::<_, _, false>(
552 Mapped {
553 inner: Pair(self.1, super::Permute4(self.0, self.2, self.3, self.4)),
554 mapper: |i| super::swap5_1(i),
555 },
556 Alt::<_, _, false>(
557 Mapped {
558 inner: Pair(self.2, super::Permute4(self.0, self.1, self.3, self.4)),
559 mapper: |i| super::swap5_2(i),
560 },
561 Alt::<_, _, false>(
562 Mapped {
563 inner: Pair(self.3, super::Permute4(self.0, self.1, self.2, self.4)),
564 mapper: |i| super::swap5_3(i),
565 },
566 Mapped {
567 inner: Pair(self.4, super::Permute4(self.0, self.1, self.2, self.3)),
568 mapper: |i| super::swap5_4(i),
569 },
570 ),
571 ),
572 ),
573 ).lemma_productive(ibuf);
574 }
575}
576
577impl<
578 A: SoundParser,
579 B: SoundParser,
580 C: SoundParser,
581 D: SoundParser,
582 E: SoundParser,
583> SoundParser for super::Permute5<A, B, C, D, E> {
584 open spec fn sound_inv(&self) -> bool {
585 &&& self.0.sound_inv()
586 &&& self.1.sound_inv()
587 &&& self.2.sound_inv()
588 &&& self.3.sound_inv()
589 &&& self.4.sound_inv()
590 }
591
592 proof fn lemma_parse_sound_consumption(&self, ibuf: Seq<u8>) {
593 let b0 = Pair(self.0, super::Permute4(self.1, self.2, self.3, self.4));
594 let b1 = Pair(self.1, super::Permute4(self.0, self.2, self.3, self.4));
595 let b2 = Pair(self.2, super::Permute4(self.0, self.1, self.3, self.4));
596 let b3 = Pair(self.3, super::Permute4(self.0, self.1, self.2, self.4));
597 let b4 = Pair(self.4, super::Permute4(self.0, self.1, self.2, self.3));
598 b0.lemma_parse_sound_consumption(ibuf);
599 b1.lemma_parse_sound_consumption(ibuf);
600 b2.lemma_parse_sound_consumption(ibuf);
601 b3.lemma_parse_sound_consumption(ibuf);
602 b4.lemma_parse_sound_consumption(ibuf);
603 if b0.spec_parse(ibuf) is None {
604 if let Some((_n, iv)) = b1.spec_parse(ibuf) {
605 assert(self.byte_len(super::swap5_1(iv)) == b1.byte_len(iv));
606 }
607 if b1.spec_parse(ibuf) is None {
608 if let Some((_n, iv)) = b2.spec_parse(ibuf) {
609 assert(self.byte_len(super::swap5_2(iv)) == b2.byte_len(iv));
610 }
611 if b2.spec_parse(ibuf) is None {
612 if let Some((_n, iv)) = b3.spec_parse(ibuf) {
613 assert(self.byte_len(super::swap5_3(iv)) == b3.byte_len(iv));
614 }
615 if b3.spec_parse(ibuf) is None {
616 if let Some((_n, iv)) = b4.spec_parse(ibuf) {
617 assert(self.byte_len(super::swap5_4(iv)) == b4.byte_len(iv));
618 }
619 }
620 }
621 }
622 }
623 }
624
625 proof fn lemma_parse_sound_value(&self, ibuf: Seq<u8>) {
626 let b0 = Pair(self.0, super::Permute4(self.1, self.2, self.3, self.4));
627 let b1 = Pair(self.1, super::Permute4(self.0, self.2, self.3, self.4));
628 let b2 = Pair(self.2, super::Permute4(self.0, self.1, self.3, self.4));
629 let b3 = Pair(self.3, super::Permute4(self.0, self.1, self.2, self.4));
630 let b4 = Pair(self.4, super::Permute4(self.0, self.1, self.2, self.3));
631 b0.lemma_parse_sound_value(ibuf);
632 b1.lemma_parse_sound_value(ibuf);
633 b2.lemma_parse_sound_value(ibuf);
634 b3.lemma_parse_sound_value(ibuf);
635 b4.lemma_parse_sound_value(ibuf);
636 if b0.spec_parse(ibuf) is None {
637 if let Some((_n, iv)) = b1.spec_parse(ibuf) {
638 assert(self.consistent(super::swap5_1(iv)));
639 }
640 if b1.spec_parse(ibuf) is None {
641 if let Some((_n, iv)) = b2.spec_parse(ibuf) {
642 assert(self.consistent(super::swap5_2(iv)));
643 }
644 if b2.spec_parse(ibuf) is None {
645 if let Some((_n, iv)) = b3.spec_parse(ibuf) {
646 assert(self.consistent(super::swap5_3(iv)));
647 }
648 if b3.spec_parse(ibuf) is None {
649 if let Some((_n, iv)) = b4.spec_parse(ibuf) {
650 assert(self.consistent(super::swap5_4(iv)));
651 }
652 }
653 }
654 }
655 }
656 }
657}
658
659impl<A, B, C, D, E> SPRoundTripDps for super::Permute5<A, B, C, D, E> where
660 A: SPRoundTripDps + NonTailFmt,
661 B: SPRoundTripDps + NonTailFmt,
662 C: SPRoundTripDps + NonTailFmt,
663 D: SPRoundTripDps + NonTailFmt,
664 E: SPRoundTripDps,
665{
666 open spec fn unambiguous(&self) -> bool {
667 &&& self.0.unambiguous()
668 &&& self.1.unambiguous()
669 &&& self.2.unambiguous()
670 &&& self.3.unambiguous()
671 &&& self.4.unambiguous()
672 &&& self.0.serialize_dps_inv()
673 &&& self.1.serialize_dps_inv()
674 &&& self.2.serialize_dps_inv()
675 &&& self.3.serialize_dps_inv()
676 }
677
678 proof fn theorem_serialize_dps_parse_roundtrip(&self, v: Self::T, obuf: Seq<u8>) {
679 Pair(self.0, super::Permute4(self.1, self.2, self.3, self.4)).theorem_serialize_dps_parse_roundtrip(
680 v,
681 obuf,
682 );
683 }
684}
685
686impl<A, B, C, D, E> EquivSerializersGeneral for super::Permute5<A, B, C, D, E> where
687 A: EquivSerializersGeneral,
688 B: EquivSerializersGeneral,
689 C: EquivSerializersGeneral,
690 D: EquivSerializersGeneral,
691 E: EquivSerializersGeneral,
692{
693 open spec fn equiv_general_inv(&self) -> bool {
694 &&& self.0.equiv_general_inv()
695 &&& self.1.equiv_general_inv()
696 &&& self.2.equiv_general_inv()
697 &&& self.3.equiv_general_inv()
698 &&& self.4.equiv_general_inv()
699 }
700
701 proof fn lemma_serialize_equiv(&self, v: Self::SVal, obuf: Seq<u8>) {
702 Pair(self.0, super::Permute4(self.1, self.2, self.3, self.4)).lemma_serialize_equiv(v, obuf);
703 }
704}
705
706impl<A, B, C, D, E> EquivSerializers for super::Permute5<A, B, C, D, E> where
707 A: EquivSerializersGeneral,
708 B: EquivSerializersGeneral,
709 C: EquivSerializersGeneral,
710 D: EquivSerializersGeneral,
711 E: EquivSerializers,
712{
713 open spec fn equiv_inv(&self) -> bool {
714 &&& self.0.equiv_general_inv()
715 &&& self.1.equiv_general_inv()
716 &&& self.2.equiv_general_inv()
717 &&& self.3.equiv_general_inv()
718 &&& self.4.equiv_inv()
719 }
720
721 proof fn lemma_serialize_equiv_on_empty(&self, v: Self::SVal) {
722 Pair(self.0, super::Permute4(self.1, self.2, self.3, self.4)).lemma_serialize_equiv_on_empty(v);
723 }
724}
725
726}