1use crate::properties::*;
2use vstd::prelude::*;
3
4verus! {
5
6pub type GhostFn<I, O> = spec_fn(I) -> O;
8
9pub type SpecPair<Fst, Snd> = Pair<Fst, Snd, GhostFn<<Fst as SpecCombinator>::Type, Snd>>;
11
12impl<Fst, Snd> SpecCombinator for SpecPair<Fst, Snd> where
13 Fst: SecureSpecCombinator,
14 Snd: SpecCombinator,
15 {
16 type Type = (Fst::Type, Snd::Type);
17
18 open spec fn requires(&self) -> bool {
19 &&& Fst::is_prefix_secure()
20 &&& self.fst.requires()
21 &&& forall|i: Fst::Type| #[trigger] (self.snd)(i).requires()
22 }
23
24 open spec fn wf(&self, v: Self::Type) -> bool {
25 &&& self.fst.wf(v.0)
26 &&& (self.snd)(v.0).wf(v.1)
27 }
28
29 open spec fn spec_parse(&self, s: Seq<u8>) -> Option<(int, Self::Type)> {
30 if let Some((n, v1)) = self.fst.spec_parse(s) {
31 let snd = (self.snd)(v1);
32 if let Some((m, v2)) = snd.spec_parse(s.skip(n as int)) {
33 Some((n + m, (v1, v2)))
34 } else {
35 None
36 }
37 } else {
38 None
39 }
40 }
41
42 open spec fn spec_serialize(&self, v: Self::Type) -> Seq<u8> {
43 let snd = (self.snd)(v.0);
44 let buf1 = self.fst.spec_serialize(v.0);
45 let buf2 = snd.spec_serialize(v.1);
46 buf1 + buf2
47 }
48}
49
50impl<Fst, Snd> SecureSpecCombinator for SpecPair<Fst, Snd> where
51 Fst: SecureSpecCombinator,
52 Snd: SecureSpecCombinator,
53 {
54 proof fn theorem_serialize_parse_roundtrip(&self, v: Self::Type) {
55 let buf = self.spec_serialize(v);
56 let buf0 = self.fst.spec_serialize(v.0);
57 let buf1 = (self.snd)(v.0).spec_serialize(v.1);
58 self.fst.theorem_serialize_parse_roundtrip(v.0);
59 self.fst.lemma_prefix_secure(buf0, buf1);
60 (self.snd)(v.0).theorem_serialize_parse_roundtrip(v.1);
61 assert((buf0 + buf1).subrange(buf0.len() as int, buf.len() as int) == buf1);
62 }
63
64 proof fn theorem_parse_serialize_roundtrip(&self, buf: Seq<u8>) {
65 if let Some((nm, (v0, v1))) = self.spec_parse(buf) {
66 let (n, v0_) = self.fst.spec_parse(buf).unwrap();
67 self.fst.lemma_parse_length(buf);
68 let buf0 = buf.take(n);
69 let buf1 = buf.skip(n);
70 assert(buf == buf0 + buf1);
71 self.fst.theorem_parse_serialize_roundtrip(buf);
72 let (m, v1_) = (self.snd)(v0).spec_parse(buf1).unwrap();
73 (self.snd)(v0).theorem_parse_serialize_roundtrip(buf1);
74 (self.snd)(v0).lemma_parse_length(buf1);
75 let buf2 = self.spec_serialize((v0, v1));
76 assert(buf2 == buf.take(nm as int));
77 } else {
78 }
79 }
80
81 open spec fn is_prefix_secure() -> bool {
82 Fst::is_prefix_secure() && Snd::is_prefix_secure()
83 }
84
85 proof fn lemma_prefix_secure(&self, buf: Seq<u8>, s2: Seq<u8>) {
86 if Fst::is_prefix_secure() && Snd::is_prefix_secure() {
87 if let Some((nm, (v0, v1))) = self.spec_parse(buf) {
88 let (n, _) = self.fst.spec_parse(buf).unwrap();
89 self.fst.lemma_parse_length(buf);
90 let buf0 = buf.subrange(0, n as int);
91 let buf1 = buf.subrange(n as int, buf.len() as int);
92 self.fst.lemma_prefix_secure(buf0, buf1);
93 self.fst.lemma_prefix_secure(buf0, buf1.add(s2));
94 self.fst.lemma_prefix_secure(buf, s2);
95 let snd = (self.snd)(v0);
96 let (m, v1_) = snd.spec_parse(buf1).unwrap();
97 assert(buf.add(s2).subrange(0, n as int) == buf0);
98 assert(buf.add(s2).subrange(n as int, buf.add(s2).len() as int) == buf1.add(s2));
99 snd.lemma_prefix_secure(buf1, s2);
100 } else {
101 }
102 } else {
103 }
104 }
105
106 proof fn lemma_parse_length(&self, s: Seq<u8>) {
107 if let Some((n, v1)) = self.fst.spec_parse(s) {
108 let snd = (self.snd)(v1);
109 if let Some((m, v2)) = snd.spec_parse(s.subrange(n as int, s.len() as int)) {
110 self.fst.lemma_parse_length(s);
111 snd.lemma_parse_length(s.subrange(n as int, s.len() as int));
112 }
113 }
114 }
115
116 open spec fn is_productive(&self) -> bool {
117 ||| self.fst.is_productive()
118 ||| forall|v1| #[trigger] ((self.snd)(v1)).is_productive()
119 }
120
121 proof fn lemma_parse_productive(&self, s: Seq<u8>) {
122 if let Some((n, v1)) = self.fst.spec_parse(s) {
123 let snd = (self.snd)(v1);
124 if let Some((m, v2)) = snd.spec_parse(s.skip(n as int)) {
125 self.fst.lemma_parse_productive(s);
126 snd.lemma_parse_productive(s.skip(n as int));
127 self.fst.lemma_parse_length(s);
128 snd.lemma_parse_length(s.skip(n as int));
129 }
130 }
131 }
132}
133
134pub trait Continuation<Input> {
137 type Output;
139
140 fn apply(&self, i: Input) -> (o: Self::Output)
142 requires
143 self.requires(i),
144 ensures
145 self.ensures(i, o),
146 ;
147
148 spec fn requires(&self, i: Input) -> bool;
150
151 spec fn ensures(&self, i: Input, o: Self::Output) -> bool;
153}
154
155pub struct Pair<Fst, Snd, Cont> {
158 pub fst: Fst,
160 pub _snd: core::marker::PhantomData<Snd>,
166 pub snd: Cont,
168}
169
170impl<Fst, Snd, Cont> Pair<Fst, Snd, Cont> where
171 Fst: View,
172 Snd: View,
173 Cont: View<V = GhostFn<<Fst::V as SpecCombinator>::Type, Snd::V>>,
174 Fst::V: SecureSpecCombinator,
175 Snd::V: SpecCombinator,
176 {
177 pub fn new(fst: Fst, snd: Cont) -> (o: Self)
179 ensures
180 o.fst == fst,
181 o.snd == snd,
182 o@ == Pair::spec_new(fst@, snd@),
183 {
184 Pair { fst, _snd: core::marker::PhantomData, snd }
185 }
186}
187
188impl<Fst, Snd> Pair<Fst, Snd, GhostFn<Fst::Type, Snd>> where
189 Fst: SecureSpecCombinator,
190 Snd: SpecCombinator,
191 {
192 pub open spec fn spec_new(fst: Fst, snd: GhostFn<Fst::Type, Snd>) -> Self {
194 Pair { fst, _snd: core::marker::PhantomData, snd }
195 }
196}
197
198impl<Fst, Snd, Cont> View for Pair<Fst, Snd, Cont> where
199 Fst: View,
200 Snd: View,
201 Cont: View<V = GhostFn<<Fst::V as SpecCombinator>::Type, Snd::V>>,
202 Fst::V: SecureSpecCombinator,
203 Snd::V: SpecCombinator,
204 {
205 type V = Pair<Fst::V, Snd::V, GhostFn<<Fst::V as SpecCombinator>::Type, Snd::V>>;
206
207 open spec fn view(&self) -> Self::V {
208 Pair::spec_new(self.fst@, self.snd@)
209 }
210}
211
212#[allow(missing_docs)]
215pub enum POrSType<PType, SType> {
216 P(PType),
218 S(SType),
220}
221
222impl<PType: View, SType: View<V = <PType as View>::V>> View for POrSType<PType, SType> {
223 type V = PType::V;
224
225 open spec fn view(&self) -> Self::V {
226 match self {
227 POrSType::P(p) => p@,
228 POrSType::S(s) => s@,
229 }
230 }
231}
232
233impl<'x, I, O, Fst, Snd, Cont> Combinator<'x, I, O> for Pair<Fst, Snd, Cont> where
234 I: VestInput,
235 O: VestOutput<I>,
236 Fst: Combinator<'x, I, O>,
237 Snd: Combinator<'x, I, O>,
238 Fst::V: SecureSpecCombinator<Type = <Fst::Type as View>::V>,
239 Snd::V: SecureSpecCombinator<Type = <Snd::Type as View>::V>,
240 Fst::SType: Copy,
241 Cont: for <'a>Continuation<POrSType<&'a Fst::Type, Fst::SType>, Output = Snd>,
242 Cont: View<V = GhostFn<<Fst::Type as View>::V, Snd::V>>,
243 <Fst as Combinator<'x, I, O>>::Type: 'x,
244 {
245 type Type = (Fst::Type, Snd::Type);
246
247 type SType = (Fst::SType, Snd::SType);
248
249 fn length(&self, v: Self::SType) -> usize {
250 let snd = self.snd.apply(POrSType::S(v.0));
251 self.fst.length(v.0) + snd.length(v.1)
252 }
253
254 open spec fn ex_requires(&self) -> bool {
255 let spec_snd_dep = self.snd@;
256 &&& self.fst.ex_requires()
257 &&& forall|i| #[trigger] self.snd.requires(i)
258 &&& forall|i, snd| #[trigger]
259 self.snd.ensures(i, snd) ==> snd.ex_requires() && snd@ == spec_snd_dep(i@)
260 }
261
262 fn parse(&self, s: I) -> (res: Result<(usize, Self::Type), ParseError>) {
263 let (n, v1) = self.fst.parse(s.clone())?;
264 proof {
265 self@.fst.lemma_parse_length(s@);
266 }
267 let s_ = s.subrange(n, s.len());
268 let snd = self.snd.apply(POrSType::P(&v1));
269 let (m, v2) = snd.parse(s_)?;
270 proof {
271 snd@.lemma_parse_length(s@.skip(n as int));
272 }
273 Ok((n + m, (v1, v2)))
274 }
275
276 fn serialize(&self, v: Self::SType, data: &mut O, pos: usize) -> (res: Result<
277 usize,
278 SerializeError,
279 >) {
280 let snd = self.snd.apply(POrSType::S(v.0));
281 let n = self.fst.serialize(v.0, data, pos)?;
282 let m = snd.serialize(v.1, data, pos + n)?;
283 assert(data@ == seq_splice(old(data)@, pos, self@.spec_serialize(v@)));
284 Ok(n + m)
285 }
286}
287
288impl<Fst: SecureSpecCombinator, Snd: SpecCombinator> SpecCombinator for (Fst, Snd) {
289 type Type = (Fst::Type, Snd::Type);
290
291 open spec fn requires(&self) -> bool {
292 Pair::spec_new(self.0, |r: Fst::Type| self.1).requires()
293 }
294
295 open spec fn wf(&self, v: Self::Type) -> bool {
296 Pair::spec_new(self.0, |r: Fst::Type| self.1).wf(v)
297 }
298
299 open spec fn spec_parse(&self, s: Seq<u8>) -> Option<(int, Self::Type)> {
300 Pair::spec_new(self.0, |r: Fst::Type| self.1).spec_parse(s)
301 }
302
303 open spec fn spec_serialize(&self, v: Self::Type) -> Seq<u8> {
304 Pair::spec_new(self.0, |r: Fst::Type| self.1).spec_serialize(v)
305 }
306}
307
308impl<Fst: SecureSpecCombinator, Snd: SecureSpecCombinator> SecureSpecCombinator for (Fst, Snd) {
309 proof fn theorem_serialize_parse_roundtrip(&self, v: Self::Type) {
310 Pair::spec_new(self.0, |r: Fst::Type| self.1).theorem_serialize_parse_roundtrip(v)
311 }
312
313 proof fn theorem_parse_serialize_roundtrip(&self, buf: Seq<u8>) {
314 Pair::spec_new(self.0, |r: Fst::Type| self.1).theorem_parse_serialize_roundtrip(buf)
315 }
316
317 open spec fn is_prefix_secure() -> bool {
318 Fst::is_prefix_secure() && Snd::is_prefix_secure()
319 }
320
321 proof fn lemma_prefix_secure(&self, buf: Seq<u8>, s2: Seq<u8>) {
322 Pair::spec_new(self.0, |r: Fst::Type| self.1).lemma_prefix_secure(buf, s2)
323 }
324
325 proof fn lemma_parse_length(&self, s: Seq<u8>) {
326 Pair::spec_new(self.0, |r: Fst::Type| self.1).lemma_parse_length(s)
327 }
328
329 open spec fn is_productive(&self) -> bool {
330 Pair::spec_new(self.0, |r: Fst::Type| self.1).is_productive()
331 }
332
333 proof fn lemma_parse_productive(&self, s: Seq<u8>) {
334 Pair::spec_new(self.0, |r: Fst::Type| self.1).lemma_parse_productive(s)
335 }
336}
337
338impl<'x, Fst, Snd, I, O> Combinator<'x, I, O> for (Fst, Snd) where
339 I: VestInput,
340 O: VestOutput<I>,
341 Fst: Combinator<'x, I, O>,
342 Snd: Combinator<'x, I, O>,
343 Fst::V: SecureSpecCombinator<Type = <Fst::Type as View>::V>,
344 Snd::V: SecureSpecCombinator<Type = <Snd::Type as View>::V>,
345 {
346 type Type = (Fst::Type, Snd::Type);
347
348 type SType = (Fst::SType, Snd::SType);
349
350 fn length(&self, v: Self::SType) -> usize {
351 self.0.length(v.0) + self.1.length(v.1)
352 }
353
354 open spec fn ex_requires(&self) -> bool {
355 self.0.ex_requires() && self.1.ex_requires()
356 }
357
358 fn parse(&self, s: I) -> (res: Result<(usize, Self::Type), ParseError>) {
359 let (n, v1) = self.0.parse(s.clone())?;
360 proof {
361 self@.0.lemma_parse_length(s@);
362 }
363 let s_ = s.subrange(n, s.len());
364 let (m, v2) = self.1.parse(s_)?;
365 proof {
366 self.1@.lemma_parse_length(s@.skip(n as int));
367 }
368 Ok((n + m, (v1, v2)))
369 }
370
371 fn serialize(&self, v: Self::SType, data: &mut O, pos: usize) -> (res: Result<
372 usize,
373 SerializeError,
374 >) {
375 let n = self.0.serialize(v.0, data, pos)?;
376 let m = self.1.serialize(v.1, data, pos + n)?;
377 assert(data@ == seq_splice(old(data)@, pos, self@.spec_serialize(v@)));
378 Ok(n + m)
379 }
380}
381
382pub struct Preceded<Fst, Snd>(pub Fst, pub Snd);
384
385impl<Fst: View, Snd: View> View for Preceded<Fst, Snd> {
386 type V = Preceded<Fst::V, Snd::V>;
387
388 open spec fn view(&self) -> Self::V {
389 Preceded(self.0@, self.1@)
390 }
391}
392
393impl<Fst: SecureSpecCombinator<Type = ()>, Snd: SpecCombinator> SpecCombinator for Preceded<
394 Fst,
395 Snd,
396> {
397 type Type = Snd::Type;
398
399 open spec fn requires(&self) -> bool {
400 (self.0, self.1).requires()
401 }
402
403 open spec fn wf(&self, v: Self::Type) -> bool {
404 (self.0, self.1).wf(((), v))
405 }
406
407 open spec fn spec_parse(&self, s: Seq<u8>) -> Option<(int, Self::Type)> {
408 if let Some((n, ((), v))) = (self.0, self.1).spec_parse(s) {
409 Some((n, v))
410 } else {
411 None
412 }
413 }
414
415 open spec fn spec_serialize(&self, v: Self::Type) -> Seq<u8> {
416 (self.0, self.1).spec_serialize(((), v))
417 }
418}
419
420impl<
421 Fst: SecureSpecCombinator<Type = ()>,
422 Snd: SecureSpecCombinator,
423> SecureSpecCombinator for Preceded<Fst, Snd> {
424 proof fn theorem_serialize_parse_roundtrip(&self, v: Self::Type) {
425 (self.0, self.1).theorem_serialize_parse_roundtrip(((), v));
426 }
427
428 proof fn theorem_parse_serialize_roundtrip(&self, buf: Seq<u8>) {
429 if let Some((n, ((), v))) = (self.0, self.1).spec_parse(buf) {
430 (self.0, self.1).theorem_parse_serialize_roundtrip(buf);
431 }
432 }
433
434 open spec fn is_prefix_secure() -> bool {
435 Fst::is_prefix_secure() && Snd::is_prefix_secure()
436 }
437
438 proof fn lemma_prefix_secure(&self, s1: Seq<u8>, s2: Seq<u8>) {
439 if Fst::is_prefix_secure() && Snd::is_prefix_secure() {
440 (self.0, self.1).lemma_prefix_secure(s1, s2);
441 }
442 }
443
444 proof fn lemma_parse_length(&self, s: Seq<u8>) {
445 if let Some((n, ((), v))) = (self.0, self.1).spec_parse(s) {
446 (self.0, self.1).lemma_parse_length(s);
447 }
448 }
449
450 open spec fn is_productive(&self) -> bool {
451 (self.0, self.1).is_productive()
452 }
453
454 proof fn lemma_parse_productive(&self, s: Seq<u8>) {
455 if let Some((n, ((), v))) = (self.0, self.1).spec_parse(s) {
456 (self.0, self.1).lemma_parse_productive(s);
457 }
458 }
459}
460
461impl<'x, I, O, Fst, Snd> Combinator<'x, I, O> for Preceded<Fst, Snd> where
462 I: VestInput,
463 O: VestOutput<I>,
464 Fst: Combinator<'x, I, O, Type = (), SType = ()>,
465 Snd: Combinator<'x, I, O>,
466 Fst::V: SecureSpecCombinator<Type = ()>,
467 Snd::V: SecureSpecCombinator<Type = <Snd::Type as View>::V>,
468 {
469 type Type = Snd::Type;
470
471 type SType = Snd::SType;
472
473 fn length(&self, v: Self::SType) -> usize {
474 (&self.0, &self.1).length(((), v))
475 }
476
477 open spec fn ex_requires(&self) -> bool {
478 (&self.0, &self.1).ex_requires()
479 }
480
481 fn parse(&self, s: I) -> Result<(usize, Self::Type), ParseError> {
482 let (n, ((), v)) = (&self.0, &self.1).parse(s.clone())?;
483 Ok((n, v))
484 }
485
486 fn serialize<'b>(&self, v: Self::SType, data: &'b mut O, pos: usize) -> Result<
487 usize,
488 SerializeError,
489 > {
490 (&self.0, &self.1).serialize(((), v), data, pos)
491 }
492}
493
494pub struct Terminated<Fst, Snd>(pub Fst, pub Snd);
496
497impl<Fst: View, Snd: View> View for Terminated<Fst, Snd> {
498 type V = Terminated<Fst::V, Snd::V>;
499
500 open spec fn view(&self) -> Self::V {
501 Terminated(self.0@, self.1@)
502 }
503}
504
505impl<Fst: SecureSpecCombinator, Snd: SpecCombinator<Type = ()>> SpecCombinator for Terminated<
506 Fst,
507 Snd,
508> {
509 type Type = Fst::Type;
510
511 open spec fn requires(&self) -> bool {
512 (self.0, self.1).requires()
513 }
514
515 open spec fn wf(&self, v: Self::Type) -> bool {
516 (self.0, self.1).wf((v, ()))
517 }
518
519 open spec fn spec_parse(&self, s: Seq<u8>) -> Option<(int, Self::Type)> {
520 if let Some((n, (v, ()))) = (self.0, self.1).spec_parse(s) {
521 Some((n, v))
522 } else {
523 None
524 }
525 }
526
527 open spec fn spec_serialize(&self, v: Self::Type) -> Seq<u8> {
528 (self.0, self.1).spec_serialize((v, ()))
529 }
530}
531
532impl<
533 Fst: SecureSpecCombinator,
534 Snd: SecureSpecCombinator<Type = ()>,
535> SecureSpecCombinator for Terminated<Fst, Snd> {
536 proof fn theorem_serialize_parse_roundtrip(&self, v: Self::Type) {
537 (self.0, self.1).theorem_serialize_parse_roundtrip((v, ()));
538 }
539
540 proof fn theorem_parse_serialize_roundtrip(&self, buf: Seq<u8>) {
541 if let Some((n, (v, ()))) = (self.0, self.1).spec_parse(buf) {
542 (self.0, self.1).theorem_parse_serialize_roundtrip(buf);
543 }
544 }
545
546 open spec fn is_prefix_secure() -> bool {
547 Fst::is_prefix_secure() && Snd::is_prefix_secure()
548 }
549
550 proof fn lemma_prefix_secure(&self, s1: Seq<u8>, s2: Seq<u8>) {
551 if Fst::is_prefix_secure() && Snd::is_prefix_secure() {
552 (self.0, self.1).lemma_prefix_secure(s1, s2);
553 }
554 }
555
556 proof fn lemma_parse_length(&self, s: Seq<u8>) {
557 if let Some((n, (v, ()))) = (self.0, self.1).spec_parse(s) {
558 (self.0, self.1).lemma_parse_length(s);
559 }
560 }
561
562 open spec fn is_productive(&self) -> bool {
563 (self.0, self.1).is_productive()
564 }
565
566 proof fn lemma_parse_productive(&self, s: Seq<u8>) {
567 if let Some((n, (v, ()))) = (self.0, self.1).spec_parse(s) {
568 (self.0, self.1).lemma_parse_productive(s);
569 }
570 }
571}
572
573impl<'x, I, O, Fst, Snd> Combinator<'x, I, O> for Terminated<Fst, Snd> where
574 I: VestInput,
575 O: VestOutput<I>,
576 Fst: Combinator<'x, I, O>,
577 Snd: Combinator<'x, I, O, Type = (), SType = ()>,
578 Fst::V: SecureSpecCombinator<Type = <Fst::Type as View>::V>,
579 Snd::V: SecureSpecCombinator<Type = ()>,
580 {
581 type Type = Fst::Type;
582
583 type SType = Fst::SType;
584
585 fn length(&self, v: Self::SType) -> usize {
586 (&self.0, &self.1).length((v, ()))
587 }
588
589 open spec fn ex_requires(&self) -> bool {
590 (&self.0, &self.1).ex_requires()
591 }
592
593 fn parse(&self, s: I) -> Result<(usize, Self::Type), ParseError> {
594 let (n, (v, ())) = (&self.0, &self.1).parse(s.clone())?;
595 Ok((n, v))
596 }
597
598 fn serialize<'b>(&self, v: Self::SType, data: &'b mut O, pos: usize) -> Result<
599 usize,
600 SerializeError,
601 > {
602 (&self.0, &self.1).serialize((v, ()), data, pos)
603 }
604}
605
606}