1use crate::combinators::length::AsLen;
3use crate::core::{proof::*, spec::*};
4use vstd::prelude::*;
5
6use super::Varied;
7use crate::combinators::Tail;
8
9verus! {
10
11pub uninterp spec fn array_from_seq<const N: usize, T>(s: Seq<T>) -> [T; N]
12 recommends
13 s.len() == N,
14;
15
16pub broadcast axiom fn axiom_array_from_seq<const N: usize, T>(s: Seq<T>)
17 requires
18 s.len() == N,
19 ensures
20 (#[trigger] array_from_seq::<N, T>(s))@ == s,
21;
22
23pub broadcast proof fn lemma_array_from_seq_roundtrip<const N: usize, T>(a: [T; N])
24 ensures
25 #[trigger] array_from_seq::<N, T>(a@) == a,
26{
27 broadcast use axiom_array_from_seq;
28
29}
30
31impl<const N: usize> SpecParser for super::Fixed<N> {
32 type PVal = Seq<u8>;
33
34 open spec fn spec_parse(&self, ibuf: Seq<u8>) -> Option<(int, Self::PVal)> {
35 if ibuf.len() < N as int {
36 None
37 } else {
38 Some((N as int, ibuf[0..N]))
39 }
40 }
41}
42
43impl<const N: usize> Consistency for super::Fixed<N> {
44 type Val = Seq<u8>;
45
46 open spec fn consistent(&self, v: Self::Val) -> bool {
47 v.len() == N
48 }
49}
50
51impl<const N: usize> SafeParser for super::Fixed<N> {
52 proof fn lemma_parse_safe(&self, ibuf: Seq<u8>) {
53 }
54}
55
56impl<const N: usize> SoundParser for super::Fixed<N> {
57 proof fn lemma_parse_sound_consumption(&self, ibuf: Seq<u8>) {
58 }
59
60 proof fn lemma_parse_sound_value(&self, ibuf: Seq<u8>) {
61 }
62}
63
64impl<const N: usize> SpecSerializerDps for super::Fixed<N> {
65 type SValue = Seq<u8>;
66
67 open spec fn spec_serialize_dps(&self, v: Self::SValue, obuf: Seq<u8>) -> Seq<u8> {
68 v + obuf
69 }
70}
71
72impl<const N: usize> SpecSerializer for super::Fixed<N> {
73 type SVal = Seq<u8>;
74
75 open spec fn spec_serialize(&self, v: Self::SVal) -> Seq<u8> {
76 v
77 }
78}
79
80impl<const N: usize> NonTailFmt for super::Fixed<N> {
81 proof fn lemma_serialize_dps_prepend(&self, v: Seq<u8>, obuf: Seq<u8>) {
82 assert(self.spec_serialize_dps(v, obuf) == v + obuf);
83 }
84
85 proof fn lemma_serialize_dps_len(&self, v: Seq<u8>, obuf: Seq<u8>) {
86 assert(self.spec_serialize_dps(v, obuf).len() - obuf.len() == v.len());
87 }
88}
89
90impl<const N: usize> GoodSerializer for super::Fixed<N> {
91 proof fn lemma_serialize_len(&self, v: Self::SVal) {
92 assert(self.spec_serialize(v).len() == v.len());
93 }
94}
95
96impl<const N: usize> SpecByteLen for super::Fixed<N> {
97 type T = Seq<u8>;
98
99 open spec fn byte_len(&self, v: Self::T) -> nat {
100 v.len()
101 }
102}
103
104impl<const N: usize> MinMaxByteLen for super::Fixed<N> {
105 open spec fn min(&self) -> nat {
106 N as nat
107 }
108
109 open spec fn max(&self) -> nat {
110 N as nat
111 }
112
113 proof fn lemma_min_max_byte_len(&self, v: Self::T) {
114 }
115}
116
117impl<const N: usize> StaticByteLen for super::Fixed<N> {
118 open spec fn static_byte_len() -> nat {
119 N as nat
120 }
121
122 proof fn lemma_static_len_matches_byte_len(&self, v: Self::T) {
123 }
124}
125
126impl<const N: usize> ValueByteLen for super::Fixed<N> {
127 open spec fn value_byte_len(_v: Self::T) -> nat {
128 N as nat
129 }
130
131 proof fn lemma_value_len_matches_byte_len(&self, v: Self::T) {
132 }
133}
134
135impl<const N: usize> BytesCombinator for super::Fixed<N> {
136 proof fn lemma_byte_len_is_buf_len(&self, buf: Seq<u8>) {
137 }
138}
139
140impl<Len: AsLen> SpecParser for super::Varied<Len> {
141 type PVal = Seq<u8>;
142
143 open spec fn spec_parse(&self, ibuf: Seq<u8>) -> Option<(int, Self::PVal)> {
144 if ibuf.len() < self.0.as_nat() {
145 None
146 } else {
147 Some((self.0.as_nat() as int, ibuf[0..self.0.as_nat()]))
148 }
149 }
150}
151
152impl<Len: AsLen> Consistency for super::Varied<Len> {
153 type Val = Seq<u8>;
154
155 open spec fn consistent(&self, v: Self::Val) -> bool {
156 v.len() == self.0.as_nat()
157 }
158}
159
160impl<Len: AsLen> SafeParser for super::Varied<Len> {
161 proof fn lemma_parse_safe(&self, ibuf: Seq<u8>) {
162 }
163}
164
165impl<Len: AsLen> SoundParser for super::Varied<Len> {
166 proof fn lemma_parse_sound_consumption(&self, ibuf: Seq<u8>) {
167 }
168
169 proof fn lemma_parse_sound_value(&self, ibuf: Seq<u8>) {
170 }
171}
172
173impl<Len: AsLen> SpecSerializerDps for super::Varied<Len> {
174 type SValue = Seq<u8>;
175
176 open spec fn spec_serialize_dps(&self, v: Self::SValue, obuf: Seq<u8>) -> Seq<u8> {
177 v + obuf
178 }
179}
180
181impl<Len: AsLen> SpecSerializer for super::Varied<Len> {
182 type SVal = Seq<u8>;
183
184 open spec fn spec_serialize(&self, v: Self::SVal) -> Seq<u8> {
185 v
186 }
187}
188
189impl<Len: AsLen> NonTailFmt for super::Varied<Len> {
190 proof fn lemma_serialize_dps_prepend(&self, v: Seq<u8>, obuf: Seq<u8>) {
191 assert(self.spec_serialize_dps(v, obuf) == v + obuf);
192 }
193
194 proof fn lemma_serialize_dps_len(&self, v: Seq<u8>, obuf: Seq<u8>) {
195 assert(self.spec_serialize_dps(v, obuf).len() - obuf.len() == v.len());
196 }
197}
198
199impl<Len: AsLen> GoodSerializer for super::Varied<Len> {
200 proof fn lemma_serialize_len(&self, v: Self::SVal) {
201 assert(self.spec_serialize(v).len() == v.len());
202 }
203}
204
205impl<Len: AsLen> SpecByteLen for super::Varied<Len> {
206 type T = Seq<u8>;
207
208 open spec fn byte_len(&self, v: Self::T) -> nat {
209 v.len()
210 }
211}
212
213impl<Len: AsLen> MinMaxByteLen for super::Varied<Len> {
214 open spec fn min(&self) -> nat {
215 self.0.as_nat()
216 }
217
218 open spec fn max(&self) -> nat {
219 self.0.as_nat()
220 }
221
222 proof fn lemma_min_max_byte_len(&self, v: Self::T) {
223 }
224}
225
226impl<Len: AsLen> super::Varied<Len> {
227 pub open spec fn byte_len(v: <Self as SpecByteLen>::T) -> nat {
228 v.len()
229 }
230}
231
232impl<Len: AsLen> BytesCombinator for super::Varied<Len> {
233 proof fn lemma_byte_len_is_buf_len(&self, s: Seq<u8>) {
234 }
235}
236
237impl<Len: AsLen> ValueByteLen for super::Varied<Len> {
238 open spec fn value_byte_len(v: Self::T) -> nat {
239 v.len()
240 }
241
242 proof fn lemma_value_len_matches_byte_len(&self, v: Self::T) {
243 }
244}
245
246impl<Inner: SpecParser, Len: AsLen> SpecParser for super::ExactLen<Inner, Len> {
247 type PVal = Inner::PVal;
248
249 open spec fn spec_parse(&self, ibuf: Seq<u8>) -> Option<(int, Self::PVal)> {
250 super::AndThen(super::Varied(self.0), self.1).spec_parse(ibuf)
251 }
252}
253
254impl<Inner: Consistency + SpecByteLen<T = Inner::Val>, Len: AsLen> Consistency for super::ExactLen<
255 Inner,
256 Len,
257> {
258 type Val = Inner::Val;
259
260 open spec fn consistent(&self, v: Self::Val) -> bool {
261 &&& self.1.consistent(v)
262 &&& self.0.as_nat() == self.1.byte_len(v)
263 }
264}
265
266impl<Inner: SafeParser, Len: AsLen> SafeParser for super::ExactLen<Inner, Len> {
267 open spec fn safe_inv(&self) -> bool {
268 super::AndThen(super::Varied(self.0), self.1).safe_inv()
269 }
270
271 proof fn lemma_parse_safe(&self, ibuf: Seq<u8>) {
272 super::AndThen(super::Varied(self.0), self.1).lemma_parse_safe(ibuf);
273 }
274}
275
276impl<Inner: SoundParser, Len: AsLen> SoundParser for super::ExactLen<Inner, Len> {
277 open spec fn sound_inv(&self) -> bool {
278 super::AndThen(super::Varied(self.0), self.1).sound_inv()
279 }
280
281 proof fn lemma_parse_sound_consumption(&self, ibuf: Seq<u8>) {
282 super::AndThen(super::Varied(self.0), self.1).lemma_parse_sound_consumption(ibuf);
283 }
284
285 proof fn lemma_parse_sound_value(&self, ibuf: Seq<u8>) {
286 super::AndThen(super::Varied(self.0), self.1).lemma_parse_sound_value(ibuf);
287 }
288}
289
290impl<Inner: SpecSerializerDps, Len: AsLen> SpecSerializerDps for super::ExactLen<Inner, Len> {
291 type SValue = Inner::SValue;
292
293 open spec fn spec_serialize_dps(&self, v: Self::SValue, obuf: Seq<u8>) -> Seq<u8> {
294 super::AndThen(super::Varied(self.0), self.1).spec_serialize_dps(v, obuf)
295 }
296}
297
298impl<Inner: SpecSerializer, Len: AsLen> SpecSerializer for super::ExactLen<Inner, Len> {
299 type SVal = Inner::SVal;
300
301 open spec fn spec_serialize(&self, v: Self::SVal) -> Seq<u8> {
302 super::AndThen(super::Varied(self.0), self.1).spec_serialize(v)
303 }
304}
305
306impl<Inner, Len> NonTailFmt for super::ExactLen<Inner, Len> where
307 Inner: GoodSerializer + EquivSerializers,
308 Len: AsLen,
309 {
310 open spec fn serialize_dps_inv(&self) -> bool {
311 super::AndThen(super::Varied(self.0), self.1).serialize_dps_inv()
312 }
313
314 proof fn lemma_serialize_dps_prepend(&self, v: Self::SValue, obuf: Seq<u8>) {
315 super::AndThen(super::Varied(self.0), self.1).lemma_serialize_dps_prepend(v, obuf);
316 }
317
318 proof fn lemma_serialize_dps_len(&self, v: Self::SValue, obuf: Seq<u8>) {
319 super::AndThen(super::Varied(self.0), self.1).lemma_serialize_dps_len(v, obuf);
320 }
321}
322
323impl<Inner: GoodSerializer, Len: AsLen> GoodSerializer for super::ExactLen<Inner, Len> {
324 open spec fn serialize_inv(&self) -> bool {
325 super::AndThen(super::Varied(self.0), self.1).serialize_inv()
326 }
327
328 proof fn lemma_serialize_len(&self, v: Self::SVal) {
329 super::AndThen(super::Varied(self.0), self.1).lemma_serialize_len(v);
330 }
331}
332
333impl<Inner: SpecByteLen, Len: AsLen> SpecByteLen for super::ExactLen<Inner, Len> {
334 type T = Inner::T;
335
336 open spec fn byte_len(&self, v: Self::T) -> nat {
337 super::AndThen(super::Varied(self.0), self.1).byte_len(v)
338 }
339}
340
341impl<Inner, Len> MinMaxByteLen for super::ExactLen<Inner, Len> where
342 Inner: SpecByteLen + Consistency<Val = Inner::T>,
343 Len: AsLen,
344 {
345 open spec fn min(&self) -> nat {
346 self.0.as_nat()
347 }
348
349 open spec fn max(&self) -> nat {
350 self.0.as_nat()
351 }
352
353 proof fn lemma_min_max_byte_len(&self, v: Self::T) {
354 assert(self.0.as_nat() == self.1.byte_len(v));
355 }
356}
357
358impl<Inner: SpecByteLen, Len: AsLen> super::ExactLen<Inner, Len> {
359 pub open spec fn byte_len(inner: Inner, v: <Self as SpecByteLen>::T) -> nat {
360 inner.byte_len(v)
361 }
362}
363
364impl<Inner: ValueByteLen, Len: AsLen> ValueByteLen for super::ExactLen<Inner, Len> {
365 open spec fn value_byte_len(v: Self::T) -> nat {
366 Inner::value_byte_len(v)
367 }
368
369 proof fn lemma_value_len_matches_byte_len(&self, v: Self::T) {
370 self.1.lemma_value_len_matches_byte_len(v);
371 }
372}
373
374impl<Inner: StaticByteLen, Len: AsLen> StaticByteLen for super::ExactLen<Inner, Len> {
375 open spec fn static_byte_len() -> nat {
376 Inner::static_byte_len()
377 }
378
379 proof fn lemma_static_len_matches_byte_len(&self, v: Self::T) {
380 self.1.lemma_static_len_matches_byte_len(v);
381 }
382}
383
384impl<A, Then> SpecParser for super::AndThen<A, Then> where
385 A: SpecParser<PVal = Seq<u8>>,
386 Then: SpecParser,
387 {
388 type PVal = Then::PVal;
389
390 open spec fn spec_parse(&self, ibuf: Seq<u8>) -> Option<(int, Self::PVal)> {
391 match self.0.spec_parse(ibuf) {
392 None => None,
393 Some((len_a, chunk)) => match self.1.spec_parse(chunk) {
394 Some((len_b, v)) if len_a == len_b => Some((len_a, v)),
395 _ => None,
396 },
397 }
398 }
399}
400
401impl<A, Then> Consistency for super::AndThen<A, Then> where
402 A: BytesCombinator + Consistency<Val = Seq<u8>>,
403 Then: Consistency + SpecByteLen<T = Then::Val>,
404 {
405 type Val = Then::Val;
406
407 open spec fn consistent(&self, v: Self::Val) -> bool {
408 &&& self.1.consistent(v)
409 &&& exists|chunk: Seq<u8>|
410 self.0.consistent(chunk) && self.0.byte_len(chunk) == self.1.byte_len(v)
411 }
412}
413
414pub broadcast proof fn lemma_tail_and_then_consistent<Then>(then: Then, v: Then::Val) where
415 Then: Consistency + SpecByteLen<T = Then::Val>,
416
417 ensures
418 #[trigger] super::AndThen(Tail, then).consistent(v) == then.consistent(v),
419{
420 if then.consistent(v) {
421 let chunk = Seq::new(then.byte_len(v), |_i| 0u8);
422 assert(Tail.consistent(chunk));
423 assert(Tail.byte_len(chunk) == then.byte_len(v));
424 assert(super::AndThen(Tail, then).0.consistent(chunk));
425 } else {
426 }
427}
428
429pub broadcast group tail_and_then_lemmas {
430 lemma_tail_and_then_consistent,
431}
432
433impl<A, Then> SafeParser for super::AndThen<A, Then> where
434 A: BytesCombinator + SafeParser<PVal = Seq<u8>>,
435 Then: SafeParser,
436 {
437 open spec fn safe_inv(&self) -> bool {
438 self.0.safe_inv()
439 }
440
441 proof fn lemma_parse_safe(&self, ibuf: Seq<u8>) {
442 self.0.lemma_parse_safe(ibuf);
443 }
444}
445
446impl<A, Then> SoundParser for super::AndThen<A, Then> where
447 A: BytesCombinator + SoundParser,
448 Then: SoundParser,
449 {
450 open spec fn sound_inv(&self) -> bool {
451 self.0.sound_inv() && self.1.sound_inv()
452 }
453
454 proof fn lemma_parse_sound_consumption(&self, ibuf: Seq<u8>) {
455 match self.0.spec_parse(ibuf) {
456 None => {},
457 Some((len_a, chunk)) => match self.1.spec_parse(chunk) {
458 Some((len_b, v)) if len_a == len_b => {
459 self.1.lemma_parse_sound_consumption(chunk);
460 assert(self.byte_len(v) == self.1.byte_len(v));
461 },
462 _ => {},
463 },
464 }
465 }
466
467 proof fn lemma_parse_sound_value(&self, ibuf: Seq<u8>) {
468 match self.0.spec_parse(ibuf) {
469 None => {},
470 Some((len_a, chunk)) => match self.1.spec_parse(chunk) {
471 Some((len_b, v)) if len_a == len_b => {
472 self.0.lemma_parse_sound_value(ibuf);
473 self.0.lemma_parse_sound_consumption(ibuf);
474 self.1.lemma_parse_sound_consumption(chunk);
475 self.1.lemma_parse_sound_value(chunk);
476 assert(self.0.consistent(chunk));
477 },
478 _ => {},
479 },
480 }
481 }
482}
483
484impl<A, Then> SpecSerializerDps for super::AndThen<A, Then> where
485 A: SpecSerializerDps<SValue = Seq<u8>>,
486 Then: SpecSerializerDps,
487 {
488 type SValue = Then::SValue;
489
490 open spec fn spec_serialize_dps(&self, v: Self::SValue, obuf: Seq<u8>) -> Seq<u8> {
491 self.0.spec_serialize_dps(self.1.spec_serialize_dps(v, seq![]), obuf)
492 }
493}
494
495impl<A, Then> SpecSerializer for super::AndThen<A, Then> where
496 A: SpecSerializer<SVal = Seq<u8>>,
497 Then: SpecSerializer,
498 {
499 type SVal = Then::SVal;
500
501 open spec fn spec_serialize(&self, v: Self::SVal) -> Seq<u8> {
502 let inner_bytes = self.1.spec_serialize(v);
503 self.0.spec_serialize(inner_bytes)
504 }
505}
506
507impl<A, Then> NonTailFmt for super::AndThen<A, Then> where
508 A: BytesCombinator + NonTailFmt,
509 Then: GoodSerializer + EquivSerializers,
510 {
511 open spec fn serialize_dps_inv(&self) -> bool {
512 &&& self.0.serialize_dps_inv()
513 &&& self.1.serialize_inv()
514 &&& self.1.equiv_inv()
515 }
516
517 proof fn lemma_serialize_dps_prepend(&self, v: Self::SValue, obuf: Seq<u8>) {
518 self.0.lemma_serialize_dps_prepend(self.1.spec_serialize_dps(v, seq![]), obuf);
519 }
520
521 proof fn lemma_serialize_dps_len(&self, v: Self::SValue, obuf: Seq<u8>) {
522 self.1.lemma_serialize_equiv_on_empty(v);
523 self.1.lemma_serialize_len(v);
524 let inner_bytes = self.1.spec_serialize_dps(v, seq![]);
525 self.0.lemma_serialize_dps_len(inner_bytes, obuf);
526 self.0.lemma_byte_len_is_buf_len(inner_bytes);
527 }
528}
529
530impl<A, Then> GoodSerializer for super::AndThen<A, Then> where
531 A: BytesCombinator + GoodSerializer,
532 Then: GoodSerializer,
533 {
534 open spec fn serialize_inv(&self) -> bool {
535 &&& self.0.serialize_inv()
536 &&& self.1.serialize_inv()
537 }
538
539 proof fn lemma_serialize_len(&self, v: Self::SVal) {
540 let inner_bytes = self.1.spec_serialize(v);
541 self.1.lemma_serialize_len(v);
542 self.0.lemma_serialize_len(inner_bytes);
543 self.0.lemma_byte_len_is_buf_len(inner_bytes);
544 }
545}
546
547impl<A, Then: SpecByteLen> SpecByteLen for super::AndThen<A, Then> {
548 type T = Then::T;
549
550 open spec fn byte_len(&self, v: Self::T) -> nat {
551 self.1.byte_len(v)
552 }
553}
554
555impl<A, Then> MinMaxByteLen for super::AndThen<A, Then> where
556 A: BytesCombinator + Consistency<Val = Seq<u8>>,
557 Then: MinMaxByteLen,
558 {
559 open spec fn min(&self) -> nat {
560 self.1.min()
561 }
562
563 open spec fn max(&self) -> nat {
564 self.1.max()
565 }
566
567 proof fn lemma_min_max_byte_len(&self, v: Self::T) {
568 self.1.lemma_min_max_byte_len(v);
569 }
570}
571
572impl<A, Then> ValueByteLen for super::AndThen<A, Then> where
573 A: BytesCombinator + Consistency<Val = Seq<u8>>,
574 Then: ValueByteLen,
575 {
576 open spec fn value_byte_len(v: Self::T) -> nat {
577 Then::value_byte_len(v)
578 }
579
580 proof fn lemma_value_len_matches_byte_len(&self, v: Self::T) {
581 self.1.lemma_value_len_matches_byte_len(v);
582 }
583}
584
585impl<A, Then> StaticByteLen for super::AndThen<A, Then> where
586 A: BytesCombinator + StaticByteLen,
587 Then: Consistency + SpecByteLen<T = Then::Val>,
588 {
589 open spec fn static_byte_len() -> nat {
590 A::static_byte_len()
591 }
592
593 proof fn lemma_static_len_matches_byte_len(&self, v: Self::T) {
594 let chunk = choose|chunk: Seq<u8>|
595 self.0.consistent(chunk) && self.0.byte_len(chunk) == self.1.byte_len(v);
596 self.0.lemma_static_len_matches_byte_len(chunk);
597 }
598}
599
600}