vest_lib/regular/
variant.rs

1use super::disjoint::DisjointFrom;
2use crate::properties::*;
3use vstd::prelude::*;
4
5verus! {
6
7#[allow(missing_docs)]
8#[derive(Debug)]
9pub enum Either<A, B> {
10    Left(A),
11    Right(B),
12}
13
14impl<A: View, B: View> View for Either<A, B> {
15    type V = Either<A::V, B::V>;
16
17    open spec fn view(&self) -> Either<A::V, B::V> {
18        match self {
19            Either::Left(v) => Either::Left(v@),
20            Either::Right(v) => Either::Right(v@),
21        }
22    }
23}
24
25/// Combinator that tries the `Fst` combinator and if it fails, tries the `Snd` combinator.
26pub struct Choice<Fst, Snd>(pub Fst, pub Snd);
27
28impl<Fst, Snd> Choice<Fst, Snd> where
29    Fst: View,
30    Snd: View,
31    Fst::V: SpecCombinator,
32    Snd::V: SpecCombinator,
33    Snd::V: DisjointFrom<Fst::V>,
34 {
35    pub fn new(fst: Fst, snd: Snd) -> (o: Self)
36        requires
37            snd@.disjoint_from(&fst@),
38        ensures
39            o == Choice(fst, snd),
40    {
41        Choice(fst, snd)
42    }
43}
44
45impl<Fst: View, Snd: View> View for Choice<Fst, Snd> where  {
46    type V = Choice<Fst::V, Snd::V>;
47
48    open spec fn view(&self) -> Self::V {
49        Choice(self.0@, self.1@)
50    }
51}
52
53impl<Fst, Snd> SpecCombinator for Choice<Fst, Snd> where
54    Fst: SpecCombinator,
55    Snd: SpecCombinator + DisjointFrom<Fst>,
56 {
57    type Type = Either<Fst::Type, Snd::Type>;
58
59    open spec fn requires(&self) -> bool {
60        self.0.requires() && self.1.requires() && self.1.disjoint_from(&self.0)
61    }
62
63    open spec fn wf(&self, v: Self::Type) -> bool {
64        match v {
65            Either::Left(v) => self.0.wf(v),
66            Either::Right(v) => self.1.wf(v),
67        }
68    }
69
70    open spec fn spec_parse(&self, s: Seq<u8>) -> Option<(int, Self::Type)> {
71        if let Some((n, v)) = self.0.spec_parse(s) {
72            Some((n, Either::Left(v)))
73        } else {
74            if let Some((n, v)) = self.1.spec_parse(s) {
75                Some((n, Either::Right(v)))
76            } else {
77                None
78            }
79        }
80    }
81
82    open spec fn spec_serialize(&self, v: Self::Type) -> Seq<u8> {
83        match v {
84            Either::Left(v) => self.0.spec_serialize(v),
85            Either::Right(v) => self.1.spec_serialize(v),
86        }
87    }
88}
89
90impl<Fst, Snd> SecureSpecCombinator for Choice<Fst, Snd> where
91    Fst: SecureSpecCombinator,
92    Snd: SecureSpecCombinator + DisjointFrom<Fst>,
93 {
94    open spec fn is_prefix_secure() -> bool {
95        Fst::is_prefix_secure() && Snd::is_prefix_secure()
96    }
97
98    open spec fn is_productive(&self) -> bool {
99        self.0.is_productive() && self.1.is_productive()
100    }
101
102    proof fn lemma_prefix_secure(&self, s1: Seq<u8>, s2: Seq<u8>) {
103        if self.1.disjoint_from(&self.0) {
104            // must also explicitly state that parser1 will fail on anything that parser2 will succeed on
105            self.1.parse_disjoint_on(&self.0, s1.add(s2));
106            if Self::is_prefix_secure() {
107                self.0.lemma_prefix_secure(s1, s2);
108                self.1.lemma_prefix_secure(s1, s2);
109            }
110        }
111    }
112
113    proof fn theorem_serialize_parse_roundtrip(&self, v: Self::Type) {
114        match v {
115            Either::Left(v) => {
116                self.0.theorem_serialize_parse_roundtrip(v);
117            },
118            Either::Right(v) => {
119                self.1.theorem_serialize_parse_roundtrip(v);
120                let buf = self.1.spec_serialize(v);
121                if self.1.disjoint_from(&self.0) {
122                    self.1.parse_disjoint_on(&self.0, buf);
123                }
124            },
125        }
126    }
127
128    proof fn theorem_parse_serialize_roundtrip(&self, buf: Seq<u8>) {
129        if let Some((n, v)) = self.0.spec_parse(buf) {
130            self.0.theorem_parse_serialize_roundtrip(buf);
131        } else {
132            if let Some((n, v)) = self.1.spec_parse(buf) {
133                self.1.theorem_parse_serialize_roundtrip(buf);
134            }
135        }
136    }
137
138    proof fn lemma_parse_length(&self, s: Seq<u8>) {
139        if let Some((n, v)) = self.0.spec_parse(s) {
140            self.0.lemma_parse_length(s);
141        } else {
142            if let Some((n, v)) = self.1.spec_parse(s) {
143                self.1.lemma_parse_length(s);
144            }
145        }
146    }
147
148    proof fn lemma_parse_productive(&self, s: Seq<u8>) {
149        if let Some((n, v)) = self.0.spec_parse(s) {
150            self.0.lemma_parse_productive(s);
151        } else {
152            if let Some((n, v)) = self.1.spec_parse(s) {
153                self.1.lemma_parse_productive(s);
154            }
155        }
156    }
157}
158
159impl<'x, I, O, Fst, Snd> Combinator<'x, I, O> for Choice<Fst, Snd> where
160    I: VestInput,
161    O: VestOutput<I>,
162    Fst: Combinator<'x, I, O>,
163    Snd: Combinator<'x, I, O>,
164    Fst::V: SecureSpecCombinator<Type = <Fst::Type as View>::V>,
165    Snd::V: SecureSpecCombinator<Type = <Snd::Type as View>::V>,
166    Snd::V: DisjointFrom<Fst::V>,
167 {
168    type Type = Either<Fst::Type, Snd::Type>;
169
170    type SType = Either<Fst::SType, Snd::SType>;
171
172    fn length(&self, v: Self::SType) -> usize {
173        match v {
174            Either::Left(v) => self.0.length(v),
175            Either::Right(v) => self.1.length(v),
176        }
177    }
178
179    open spec fn ex_requires(&self) -> bool {
180        self.0.ex_requires() && self.1.ex_requires()
181    }
182
183    fn parse(&self, s: I) -> (res: Result<(usize, Self::Type), ParseError>) {
184        if let Ok((n, v)) = self.0.parse(s.clone()) {
185            Ok((n, Either::Left(v)))
186        } else {
187            if let Ok((n, v)) = self.1.parse(s) {
188                Ok((n, Either::Right(v)))
189            } else {
190                Err(ParseError::OrdChoiceNoMatch)
191            }
192        }
193    }
194
195    fn serialize(&self, v: Self::SType, data: &mut O, pos: usize) -> (res: Result<
196        usize,
197        SerializeError,
198    >) {
199        match v {
200            Either::Left(v) => {
201                let n = self.0.serialize(v, data, pos)?;
202                Ok(n)
203            },
204            Either::Right(v) => {
205                let n = self.1.serialize(v, data, pos)?;
206                Ok(n)
207            },
208        }
209    }
210}
211
212/// The optional combinator that never fails.
213/// If the inner combinator fails, the result is `None`.
214///
215/// ## Note
216///
217/// One might think that the `Opt<T>` combinator can be encoded as `OrdChoice<T, Success>`.
218/// However, this is not the case because one cannot prove that `Success` is disjoint from `T`.
219/// In fact, there is a fundamental difference between `Opt<T>` and `OrdChoice<Fst, Snd>`:
220/// the `Disjoint` conditions can be aggregated for `OrdChoice`, making it "nestable", while
221/// the "productivity" condition cannot be aggregated for `Opt` (i.e., `Opt<Opt<T>>` can never be
222/// constructed).
223pub struct Opt<T>(pub T);
224
225impl<T: View> View for Opt<T> where  {
226    type V = Opt<T::V>;
227
228    open spec fn view(&self) -> Self::V {
229        Opt(self.0@)
230    }
231}
232
233impl<C: View> Opt<C> where C::V: SecureSpecCombinator {
234    /// Constructs a new `Opt` combinator, only if the inner combinator is productive.
235    pub fn new(c: C) -> (o: Self)
236        requires
237            c@.is_productive(),
238        ensures
239            o == Opt(c),
240    {
241        Opt(c)
242    }
243}
244
245/// Wrapper for the `core::option::Option` type.
246/// Needed because currently Verus does not implement the `View` trait for `Option`.
247#[derive(Debug, PartialEq, Eq)]
248pub struct Optional<T>(pub Option<T>);
249
250impl<T: Clone> Clone for Optional<T> {
251    fn clone(&self) -> Self {
252        Optional(self.0.clone())
253    }
254}
255
256impl<T: View> View for Optional<T> where  {
257    type V = Option<T::V>;
258
259    open spec fn view(&self) -> Self::V {
260        match &self.0 {
261            Some(v) => Some(v@),
262            None => None,
263        }
264    }
265}
266
267impl<T: SecureSpecCombinator> SpecCombinator for Opt<T> where  {
268    type Type = Option<T::Type>;
269
270    open spec fn requires(&self) -> bool {
271        self.0.requires() && self.0.is_productive()
272    }
273
274    open spec fn wf(&self, v: Self::Type) -> bool {
275        match v {
276            Some(vv) => self.0.wf(vv),
277            None => true,
278        }
279    }
280
281    open spec fn spec_parse(&self, s: Seq<u8>) -> Option<(int, Self::Type)> {
282        if let Some((n, v)) = self.0.spec_parse(s) {
283            Some((n, Some(v)))
284        } else {
285            Some((0, None))
286        }
287    }
288
289    open spec fn spec_serialize(&self, v: Self::Type) -> Seq<u8> {
290        match v {
291            Some(v) => self.0.spec_serialize(v),
292            None => Seq::empty(),
293        }
294    }
295}
296
297impl<T: SecureSpecCombinator> SecureSpecCombinator for Opt<T> where  {
298    open spec fn is_prefix_secure() -> bool {
299        false
300    }
301
302    open spec fn is_productive(&self) -> bool {
303        false
304    }
305
306    proof fn lemma_prefix_secure(&self, s1: Seq<u8>, s2: Seq<u8>) {
307    }
308
309    proof fn theorem_serialize_parse_roundtrip(&self, v: Self::Type) {
310        if self.wf(v) {
311            match v {
312                Some(vv) => {
313                    assert(self.0.wf(vv));
314                    self.0.lemma_serialize_productive(vv);
315                    self.0.theorem_serialize_parse_roundtrip(vv);
316                },
317                None => {
318                    // the following two lines establish a contradiction (n > 0 and n <= 0)
319                    self.0.lemma_parse_productive(Seq::empty());
320                    self.0.lemma_parse_length(Seq::empty());
321                },
322            }
323        }
324    }
325
326    proof fn theorem_parse_serialize_roundtrip(&self, buf: Seq<u8>) {
327        if let Some((n, v)) = self.0.spec_parse(buf) {
328            self.0.lemma_parse_productive(buf);
329            if n != 0 {
330                self.0.theorem_parse_serialize_roundtrip(buf);
331            }
332        } else {
333            assert(Seq::<u8>::empty() == buf.take(0));
334        }
335    }
336
337    proof fn lemma_parse_length(&self, s: Seq<u8>) {
338        if let Some((n, v)) = self.0.spec_parse(s) {
339            self.0.lemma_parse_length(s);
340        }
341    }
342
343    proof fn lemma_parse_productive(&self, s: Seq<u8>) {
344    }
345}
346
347impl<'x, I, O, T> Combinator<'x, I, O> for Opt<T> where
348    I: VestInput,
349    O: VestOutput<I>,
350    T: Combinator<'x, I, O, SType = &'x <T as Combinator<'x, I, O>>::Type>,
351    T::V: SecureSpecCombinator<Type = <T::Type as View>::V>,
352    T::Type: 'x,
353 {
354    type Type = Optional<T::Type>;
355
356    type SType = &'x Self::Type;
357
358    fn length(&self, v: Self::SType) -> usize {
359        assert(self@.wf(v@)); // TODO: why is this needed?
360        match &v.0 {
361            Some(v) => self.0.length(v),
362            None => 0,
363        }
364    }
365
366    open spec fn ex_requires(&self) -> bool {
367        self.0.ex_requires()
368    }
369
370    fn parse(&self, s: I) -> (res: Result<(usize, Self::Type), ParseError>) {
371        if let Ok((n, v)) = self.0.parse(s) {
372            Ok((n, Optional(Some(v))))
373        } else {
374            Ok((0, Optional(None)))
375        }
376    }
377
378    fn serialize(&self, v: Self::SType, data: &mut O, pos: usize) -> (res: Result<
379        usize,
380        SerializeError,
381    >) {
382        match &v.0 {
383            Some(v) => self.0.serialize(v, data, pos),
384            None => {
385                if pos <= data.len() {
386                    assert(seq_splice(old(data)@, pos, Seq::<u8>::empty()) == data@);
387                    Ok(0)
388                } else {
389                    Err(SerializeError::InsufficientBuffer)
390                }
391            },
392        }
393    }
394}
395
396pub struct OptThen<Fst, Snd>(pub (Opt<Fst>, Snd));
397
398impl<Fst: View, Snd: View> View for OptThen<Fst, Snd> {
399    type V = OptThen<Fst::V, Snd::V>;
400
401    open spec fn view(&self) -> Self::V {
402        OptThen((self.0.0@, self.0.1@))
403    }
404}
405
406impl<Fst, Snd> OptThen<Fst, Snd> where
407 {
408    pub open spec fn spec_new(fst: Fst, snd: Snd) -> Self {
409        OptThen((Opt(fst), snd))
410    }
411
412    pub fn new(fst: Fst, snd: Snd) -> (o: Self)
413        ensures
414            o == OptThen((Opt(fst), snd)),
415    {
416        OptThen((Opt(fst), snd))
417    }
418}
419
420impl<C, Fst, Snd> DisjointFrom<C> for OptThen<Fst, Snd> where
421    C: SpecCombinator,
422    Fst: SecureSpecCombinator + DisjointFrom<C>,
423    Snd: SpecCombinator + DisjointFrom<Fst> + DisjointFrom<C>,
424 {
425    open spec fn disjoint_from(&self, other: &C) -> bool {
426        &&& self.0.0.0.disjoint_from(other) 
427        &&& self.0.1.disjoint_from(other)
428    }
429
430    proof fn parse_disjoint_on(&self, other: &C, buf: Seq<u8>) {
431        match self.spec_parse(buf) {
432            Some((_, (Some(_), _))) => {
433                self.0.0.0.parse_disjoint_on(other, buf);
434                self.0.1.parse_disjoint_on(other, buf);
435            },
436            Some((_, (None, _))) => {
437                assert(buf.skip(0) == buf);
438                self.0.1.parse_disjoint_on(other, buf);
439            },
440            _ => {}
441        }
442    }
443}
444
445
446impl<Fst, Snd> SpecCombinator for OptThen<Fst, Snd> where
447    Fst: SecureSpecCombinator,
448    Snd: SpecCombinator + DisjointFrom<Fst>,
449 {
450    type Type = (<Opt<Fst> as SpecCombinator>::Type, Snd::Type);
451
452    open spec fn requires(&self) -> bool {
453        // instead of just requiring `Fst` to be
454        // prefix-secure, we require `Snd`
455        // to be disjoint from `Fst`
456        // Note that `Opt<T>` is always not prefix-secure
457        Fst::is_prefix_secure()
458        && self.0.0.requires() && self.0.1.requires() 
459        && self.0.1.disjoint_from(&self.0.0.0)
460    }
461
462    open spec fn wf(&self, v: Self::Type) -> bool {
463        self.0.wf(v)
464    }
465
466    open spec fn spec_parse(&self, s: Seq<u8>) -> Option<(int, Self::Type)> {
467        self.0.spec_parse(s)
468    }
469
470    open spec fn spec_serialize(&self, v: Self::Type) -> Seq<u8> {
471        self.0.spec_serialize(v)
472    }
473}
474
475impl<Fst, Snd> SecureSpecCombinator for OptThen<Fst, Snd> where
476    Fst: SecureSpecCombinator,
477    Snd: SecureSpecCombinator + DisjointFrom<Fst>,
478 {
479    proof fn theorem_serialize_parse_roundtrip(&self, v: Self::Type) {
480        let buf = self.spec_serialize(v);
481        let buf0 = self.0.0.spec_serialize(v.0);
482        let buf1 = self.0.1.spec_serialize(v.1);
483        self.0.0.theorem_serialize_parse_roundtrip(v.0);
484        self.0.1.theorem_serialize_parse_roundtrip(v.1);
485        assert((buf0 + buf1).skip(buf0.len() as int) == buf1);
486        self.0.0.0.lemma_prefix_secure(buf0, buf1);
487        self.0.1.parse_disjoint_on(&self.0.0.0, buf1); // <-- this is the key
488    }
489
490    proof fn theorem_parse_serialize_roundtrip(&self, buf: Seq<u8>) {
491        if let Some((nm, (v0, v1))) = self.spec_parse(buf) {
492            let (n, v0_) = self.0.0.spec_parse(buf).unwrap();
493            self.0.0.lemma_parse_length(buf);
494            let buf0 = buf.take(n);
495            let buf1 = buf.skip(n);
496            assert(buf == buf0 + buf1);
497            self.0.0.theorem_parse_serialize_roundtrip(buf);
498            let (m, v1_) = self.0.1.spec_parse(buf1).unwrap();
499            self.0.1.theorem_parse_serialize_roundtrip(buf1);
500            self.0.1.lemma_parse_length(buf1);
501            let buf2 = self.spec_serialize((v0, v1));
502            assert(buf2 == buf.take(nm));
503        }
504    }
505
506    open spec fn is_prefix_secure() -> bool {
507        Fst::is_prefix_secure() && Snd::is_prefix_secure()
508    }
509
510    proof fn lemma_prefix_secure(&self, s1: Seq<u8>, s2: Seq<u8>) {
511        if Fst::is_prefix_secure() && Snd::is_prefix_secure() {
512            self.0.0.0.lemma_prefix_secure(s1, s2);
513            self.0.0.lemma_parse_length(s1);
514            if let Some((n1, v1)) = self.0.0.spec_parse(s1) {
515                match v1 {
516                    Some(v1) => {
517                        assert(s1.skip(n1) + s2 == (s1 + s2).skip(n1));
518                        self.0.1.lemma_prefix_secure(s1.skip(n1), s2);
519                    },
520                    None => {
521                        assert(s1.skip(n1) == s1);
522                        assert(self.0.0.0.spec_parse(s1) is None);
523                        self.0.1.lemma_prefix_secure(s1, s2);
524                        if let Some((n2, v2)) = self.0.1.spec_parse(s1) {
525                            self.0.1.parse_disjoint_on(&self.0.0.0, s1 + s2);
526                            assert(self.0.0.0.spec_parse(s1 + s2) is None);
527                        }
528                    },
529                }
530            }
531        }
532    }
533
534    proof fn lemma_parse_length(&self, s: Seq<u8>) {
535        if let Some((n, _)) = self.0.0.spec_parse(s) {
536            if let Some(_) = self.0.1.spec_parse(s.skip(n)) {
537                self.0.0.lemma_parse_length(s);
538                self.0.1.lemma_parse_length(s.skip(n));
539            }
540        }
541    }
542
543    open spec fn is_productive(&self) -> bool {
544        self.0.1.is_productive()
545    }
546
547    proof fn lemma_parse_productive(&self, s: Seq<u8>) {
548        if let Some((n, _)) = self.0.0.spec_parse(s) {
549            if let Some(_) = self.0.1.spec_parse(s.skip(n)) {
550                self.0.0.0.lemma_parse_length(s);
551                self.0.1.lemma_parse_productive(s.skip(n));
552                self.0.1.lemma_parse_length(s.skip(n));
553            }
554        }
555    }
556}
557
558impl<'x, I, O, Fst, Snd> Combinator<'x, I, O> for OptThen<Fst, Snd> where
559    I: VestInput,
560    O: VestOutput<I>,
561    Fst: Combinator<'x, I, O, SType = &'x <Fst as Combinator<'x, I, O>>::Type>,
562    Snd: Combinator<'x, I, O>,
563    Fst::V: SecureSpecCombinator<Type = <Fst::Type as View>::V>,
564    Snd::V: SecureSpecCombinator<Type = <Snd::Type as View>::V>,
565    Snd::V: DisjointFrom<Fst::V>,
566    Fst::Type: 'x,
567 {
568    type Type = (<Opt<Fst> as Combinator<'x, I, O>>::Type, Snd::Type);
569
570    type SType = (<Opt<Fst> as Combinator<'x, I, O>>::SType, Snd::SType);
571
572    fn length(&self, v: Self::SType) -> usize {
573        self.0.0.length(&v.0) + self.0.1.length(v.1)
574    }
575
576    open spec fn ex_requires(&self) -> bool {
577        self.0.ex_requires()
578    }
579
580    fn parse(&self, s: I) -> (res: Result<(usize, Self::Type), ParseError>) {
581        let (n, v1) = self.0.0.parse(s.clone())?;
582        proof {
583            self@.0.0.lemma_parse_length(s@);
584        }
585        let s_ = s.subrange(n, s.len());
586        let (m, v2) = self.0.1.parse(s_)?;
587        proof {
588            self.0.1@.lemma_parse_length(s@.skip(n as int));
589        }
590        Ok((n + m, (v1, v2)))
591    }
592
593    fn serialize(&self, v: Self::SType, data: &mut O, pos: usize) -> (res: Result<
594        usize,
595        SerializeError,
596    >) {
597        let n = self.0.0.serialize(&v.0, data, pos)?;
598        let m = self.0.1.serialize(v.1, data, pos + n)?;
599        Ok(n + m)
600    }
601}
602
603/// This macro constructs a nested OrdChoice combinator
604/// in the form of OrdChoice(..., OrdChoice(..., OrdChoice(..., ...)))
605#[allow(unused_macros)]
606#[macro_export]
607macro_rules! ord_choice {
608    ($c:expr $(,)?) => {
609        $c
610    };
611
612    ($c:expr, $($rest:expr),* $(,)?) => {
613        Choice($c, ord_choice!($($rest),*))
614    };
615}
616
617pub use ord_choice;
618
619/// Build a type for the `ord_choice!` macro
620#[allow(unused_macros)]
621#[macro_export]
622macro_rules! ord_choice_type {
623    ($c:ty $(,)?) => {
624        $c
625    };
626
627    ($c:ty, $($rest:ty),* $(,)?) => {
628        OrdChoice<$c, ord_choice_type!($($rest),*)>
629    };
630}
631
632pub use ord_choice_type;
633
634/// Build a type for the result of `ord_choice!`
635#[allow(unused_macros)]
636#[macro_export]
637macro_rules! ord_choice_result {
638    ($c:ty $(,)?) => {
639        $c
640    };
641
642    ($c:ty, $($rest:ty),* $(,)?) => {
643        Either<$c, ord_choice_result!($($rest),*)>
644    };
645}
646
647pub use ord_choice_result;
648
649/// Maps x:Ti to ord_choice_result!(T1, ..., Tn)
650#[allow(unused_macros)]
651#[macro_export]
652macro_rules! inj_ord_choice_result {
653    (*, $($rest:tt),* $(,)?) => {
654        Either::Right(inj_ord_choice_result!($($rest),*))
655    };
656
657    ($x:expr $(,)?) => {
658        $x
659    };
660
661    ($x:expr, $(*),* $(,)?) => {
662        Either::Left($x)
663    };
664}
665
666pub use inj_ord_choice_result;
667
668/// Same as above but for patterns
669#[allow(unused_macros)]
670#[macro_export]
671macro_rules! inj_ord_choice_pat {
672    (*, $($rest:tt),* $(,)?) => {
673        Either::Right(inj_ord_choice_pat!($($rest),*))
674    };
675
676    ($x:pat $(,)?) => {
677        $x
678    };
679
680    ($x:pat, $(*),* $(,)?) => {
681        Either::Left($x)
682    };
683}
684
685pub use inj_ord_choice_pat;
686
687// what would it look like if we manually implemented the match combinator?
688//
689// use super::uints::*;
690// use super::tail::*;
691//
692// pub struct MatchU8With123 {
693//     pub val: u8,
694//     pub arm1: U8,
695//     pub arm2: U16,
696//     pub arm3: U32,
697//     pub default: Tail,
698// }
699//
700// impl View for MatchU8With123 {
701//     type V = Self;
702//
703//     open spec fn view(&self) -> Self::V {
704//         MatchU8With123 {
705//             val: self.val,
706//             arm1: self.arm1@,
707//             arm2: self.arm2@,
708//             arm3: self.arm3@,
709//             default: self.default@,
710//         }
711//     }
712// }
713//
714// pub enum SpecMsgMatchU8With123 {
715//     Arm1(u8),
716//     Arm2(u16),
717//     Arm3(u32),
718//     Default(Seq<u8>),
719// }
720//
721// pub enum MsgMatchU8With123<'a> {
722//     Arm1(u8),
723//     Arm2(u16),
724//     Arm3(u32),
725//     Default(&'a [u8]),
726// }
727//
728// pub enum MsgMatchU8With123 {
729//     Arm1(u8),
730//     Arm2(u16),
731//     Arm3(u32),
732//     Default(Vec<u8>),
733// }
734//
735// impl View for MsgMatchU8With123<'_> {
736//     type V = SpecMsgMatchU8With123;
737//
738//     open spec fn view(&self) -> Self::V {
739//         match self {
740//             MsgMatchU8With123::Arm1(v) => SpecMsgMatchU8With123::Arm1(v@),
741//             MsgMatchU8With123::Arm2(v) => SpecMsgMatchU8With123::Arm2(v@),
742//             MsgMatchU8With123::Arm3(v) => SpecMsgMatchU8With123::Arm3(v@),
743//             MsgMatchU8With123::Default(v) => SpecMsgMatchU8With123::Default(v@),
744//         }
745//     }
746// }
747//
748// impl View for MsgMatchU8With123 {
749//     type V = SpecMsgMatchU8With123;
750//
751//     open spec fn view(&self) -> Self::V {
752//         match self {
753//             MsgMatchU8With123::Arm1(v) => SpecMsgMatchU8With123::Arm1(v@),
754//             MsgMatchU8With123::Arm2(v) => SpecMsgMatchU8With123::Arm2(v@),
755//             MsgMatchU8With123::Arm3(v) => SpecMsgMatchU8With123::Arm3(v@),
756//             MsgMatchU8With123::Default(v) => SpecMsgMatchU8With123::Default(v@),
757//         }
758//     }
759// }
760//
761// impl SpecCombinator for MatchU8With123 {
762//     type SpecResult = SpecMsgMatchU8With123;
763//
764//     open spec fn spec_parse(&self, s: Seq<u8>) -> Result<(usize, Self::SpecResult), ()> {
765//         match self.val {
766//             1u8 => {
767//                 if let Ok((n, v)) = self.arm1.spec_parse(s) {
768//                     Ok((n, SpecMsgMatchU8With123::Arm1(v)))
769//                 } else {
770//                     Err(())
771//                 }
772//             },
773//             2u8 => {
774//                 if let Ok((n, v)) = self.arm2.spec_parse(s) {
775//                     Ok((n, SpecMsgMatchU8With123::Arm2(v)))
776//                 } else {
777//                     Err(())
778//                 }
779//             },
780//             3u8 => {
781//                 if let Ok((n, v)) = self.arm3.spec_parse(s) {
782//                     Ok((n, SpecMsgMatchU8With123::Arm3(v)))
783//                 } else {
784//                     Err(())
785//                 }
786//             },
787//             _ => {
788//                 if let Ok((n, v)) = self.default.spec_parse(s) {
789//                     Ok((n, SpecMsgMatchU8With123::Default(v)))
790//                 } else {
791//                     Err(())
792//                 }
793//             },
794//         }
795//     }
796//
797//     proof fn spec_parse_wf(&self, s: Seq<u8>) {
798//         match self.val {
799//             1u8 => {
800//                 if let Ok((n, v)) = self.arm1.spec_parse(s) {
801//                     self.arm1.spec_parse_wf(s);
802//                 }
803//             },
804//             2u8 => {
805//                 if let Ok((n, v)) = self.arm2.spec_parse(s) {
806//                     self.arm2.spec_parse_wf(s);
807//                 }
808//             },
809//             3u8 => {
810//                 if let Ok((n, v)) = self.arm3.spec_parse(s) {
811//                     self.arm3.spec_parse_wf(s);
812//                 }
813//             },
814//             _ => {
815//                 if let Ok((n, v)) = self.default.spec_parse(s) {
816//                     self.default.spec_parse_wf(s);
817//                 }
818//             },
819//         }
820//     }
821//
822//     open spec fn spec_serialize(&self, v: Self::SpecResult) -> Result<Seq<u8>, ()> {
823//         match self.val {
824//             1u8 => {
825//                 if let SpecMsgMatchU8With123::Arm1(v) = v {
826//                     self.arm1.spec_serialize(v)
827//                 } else {
828//                     Err(())
829//                 }
830//             },
831//             2u8 => {
832//                 if let SpecMsgMatchU8With123::Arm2(v) = v {
833//                     self.arm2.spec_serialize(v)
834//                 } else {
835//                     Err(())
836//                 }
837//             },
838//             3u8 => {
839//                 if let SpecMsgMatchU8With123::Arm3(v) = v {
840//                     self.arm3.spec_serialize(v)
841//                 } else {
842//                     Err(())
843//                 }
844//             },
845//             _ => {
846//                 if let SpecMsgMatchU8With123::Default(v) = v {
847//                     self.default.spec_serialize(v)
848//                 } else {
849//                     Err(())
850//                 }
851//             },
852//         }
853//     }
854// }
855//
856// impl SecureSpecCombinator for MatchU8With123 {
857//     open spec fn spec_is_prefix_secure() -> bool {
858//         U8::spec_is_prefix_secure() && U16::spec_is_prefix_secure() && U32::spec_is_prefix_secure()
859//             && Tail::spec_is_prefix_secure()
860//     }
861//
862//     proof fn lemma_prefix_secure(&self, s1: Seq<u8>, s2: Seq<u8>) {
863//         match self.val {
864//             1u8 => {
865//                 self.arm1.lemma_prefix_secure(s1, s2);
866//             },
867//             2u8 => {
868//                 self.arm2.lemma_prefix_secure(s1, s2);
869//             },
870//             3u8 => {
871//                 self.arm3.lemma_prefix_secure(s1, s2);
872//             },
873//             _ => {
874//                 self.default.lemma_prefix_secure(s1, s2);
875//             },
876//         }
877//     }
878//
879//     proof fn theorem_serialize_parse_roundtrip(&self, v: Self::SpecResult) {
880//         match self.val {
881//             1u8 => {
882//                 if let SpecMsgMatchU8With123::Arm1(v) = v {
883//                     self.arm1.theorem_serialize_parse_roundtrip(v);
884//                 }
885//             },
886//             2u8 => {
887//                 if let SpecMsgMatchU8With123::Arm2(v) = v {
888//                     self.arm2.theorem_serialize_parse_roundtrip(v);
889//                 }
890//             },
891//             3u8 => {
892//                 if let SpecMsgMatchU8With123::Arm3(v) = v {
893//                     self.arm3.theorem_serialize_parse_roundtrip(v);
894//                 }
895//             },
896//             _ => {
897//                 if let SpecMsgMatchU8With123::Default(v) = v {
898//                     self.default.theorem_serialize_parse_roundtrip(v);
899//                 }
900//             },
901//         }
902//     }
903//
904//     proof fn theorem_parse_serialize_roundtrip(&self, buf: Seq<u8>) {
905//         match self.val {
906//             1u8 => {
907//                 self.arm1.theorem_parse_serialize_roundtrip(buf);
908//             },
909//             2u8 => {
910//                 self.arm2.theorem_parse_serialize_roundtrip(buf);
911//             },
912//             3u8 => {
913//                 self.arm3.theorem_parse_serialize_roundtrip(buf);
914//             },
915//             _ => {
916//                 self.default.theorem_parse_serialize_roundtrip(buf);
917//             },
918//         }
919//     }
920// }
921//
922// impl Combinator for MatchU8With123 {
923//     type Result<'a> = MsgMatchU8With123<'a>;
924//
925//     type  = MsgMatchU8With123;
926//
927//     open spec fn spec_length(&self) -> Option<usize> {
928//         None
929//     }
930//
931//     fn length(&self) -> Option<usize> {
932//         None
933//     }
934//
935//     fn exec_is_prefix_secure() -> bool {
936//         U8::exec_is_prefix_secure() && U16::exec_is_prefix_secure() && U32::exec_is_prefix_secure()
937//             && Tail::exec_is_prefix_secure()
938//     }
939//
940//     open spec fn parse_requires(&self) -> bool {
941//         self.arm1.parse_requires() && self.arm2.parse_requires() && self.arm3.parse_requires()
942//             && self.default.parse_requires()
943//     }
944//
945//     fn parse<'a>(&self, s: &'a [u8]) -> (res: Result<(usize, Self::Result<'a>), ()>) {
946//         match self.val {
947//             1u8 => {
948//                 if let Ok((n, v)) = self.arm1.parse(s) {
949//                     Ok((n, MsgMatchU8With123::Arm1(v)))
950//                 } else {
951//                     Err(())
952//                 }
953//             },
954//             2u8 => {
955//                 if let Ok((n, v)) = self.arm2.parse(s) {
956//                     Ok((n, MsgMatchU8With123::Arm2(v)))
957//                 } else {
958//                     Err(())
959//                 }
960//             },
961//             3u8 => {
962//                 if let Ok((n, v)) = self.arm3.parse(s) {
963//                     Ok((n, MsgMatchU8With123::Arm3(v)))
964//                 } else {
965//                     Err(())
966//                 }
967//             },
968//             _ => {
969//                 if let Ok((n, v)) = self.default.parse(s) {
970//                     Ok((n, MsgMatchU8With123::Default(v)))
971//                 } else {
972//                     Err(())
973//                 }
974//             },
975//         }
976//     }
977//
978//     open spec fn serialize_requires(&self) -> bool {
979//         self.arm1.serialize_requires() && self.arm2.serialize_requires()
980//             && self.arm3.serialize_requires() && self.default.serialize_requires()
981//     }
982//
983//     fn serialize(&self, v: Self::Result<'_>, data: &mut Vec<u8>, pos: usize) -> (res: Result<
984//         usize,
985//         (),
986//     >) {
987//         match self.val {
988//             1u8 => {
989//                 if let MsgMatchU8With123::Arm1(v) = v {
990//                     self.arm1.serialize(v, data, pos)
991//                 } else {
992//                     Err(())
993//                 }
994//             },
995//             2u8 => {
996//                 if let MsgMatchU8With123::Arm2(v) = v {
997//                     self.arm2.serialize(v, data, pos)
998//                 } else {
999//                     Err(())
1000//                 }
1001//             },
1002//             3u8 => {
1003//                 if let MsgMatchU8With123::Arm3(v) = v {
1004//                     self.arm3.serialize(v, data, pos)
1005//                 } else {
1006//                     Err(())
1007//                 }
1008//             },
1009//             _ => {
1010//                 if let MsgMatchU8With123::Default(v) = v {
1011//                     self.default.serialize(v, data, pos)
1012//                 } else {
1013//                     Err(())
1014//                 }
1015//             },
1016//         }
1017//     }
1018// }
1019} // verus!