1use crate::combinators::bits::Bits;
3use crate::combinators::bytes::{AndThen, ExactLen, Fixed, Varied};
4use crate::combinators::mapped::spec::{BiMap, BiMapper, FnSpecMapper, SpecMap};
5use crate::combinators::named::Named;
6use crate::combinators::reference::Ref;
7use crate::combinators::tail::{Eof, RepeatTillEnd, Tail};
8use crate::combinators::AsLen;
9use crate::combinators::Optional;
10use crate::combinators::OptionalEnd;
11use crate::combinators::{
12 Alt, Array, Bind, Choice, Cond, Const, Mapped, Opt, Pair, Preceded, PrefixTagged, Refined,
13 Repeat, RepeatN, Star, SuffixTagged, Sum, Terminated,
14};
15use crate::core::exec::fns::FnParser;
16use crate::core::exec::parser::PResult;
17use crate::core::spec::{
18 BytesCombinator, Consistency, SafeParser, SpecByteLen, SpecParser, SpecPred, SpecSerializer,
19 SpecSerializerDps,
20};
21use vstd::prelude::*;
22
23verus! {
24
25#[verifier::opaque]
28pub open spec fn parser_congruent<A, B>(a: A, b: B) -> bool where
29 A: SpecParser,
30 B: SpecParser<PVal = A::PVal>,
31 {
32 forall|input: Seq<u8>| a.spec_parse(input) == b.spec_parse(input)
33}
34
35#[verifier::opaque]
37pub open spec fn prepare_congruent<A, B>(a: A, b: B) -> bool where
38 A: Consistency + SpecByteLen<T = A::Val>,
39 B: Consistency<Val = A::Val> + SpecByteLen<T = A::Val>,
40 {
41 &&& forall|v: A::Val| a.consistent(v) <==> b.consistent(v)
42 &&& forall|v: A::Val| a.byte_len(v) == b.byte_len(v)
43}
44
45#[verifier::opaque]
47pub open spec fn serializer_congruent<A, B>(a: A, b: B) -> bool where
48 A: Consistency + SpecByteLen<T = A::Val> + SpecSerializer<SVal = A::Val>,
49 B: Consistency<Val = A::Val> + SpecByteLen<T = A::Val> + SpecSerializer<SVal = A::Val>,
50 {
51 &&& prepare_congruent(a, b)
52 &&& forall|v: A::Val| a.spec_serialize(v) == b.spec_serialize(v)
53}
54
55pub broadcast proof fn lemma_parser_congruent_apply<A, B>(a: A, b: B, input: Seq<u8>) where
56 A: SpecParser,
57 B: SpecParser<PVal = A::PVal>,
58
59 requires
60 parser_congruent(a, b),
61 ensures
62 #[trigger] a.spec_parse(input) == #[trigger] b.spec_parse(input),
63{
64 reveal(parser_congruent);
65}
66
67pub broadcast proof fn lemma_parser_congruent_intro<A, B>(a: A, b: B) where
68 A: SpecParser,
69 B: SpecParser<PVal = A::PVal>,
70
71 requires
72 forall|input: Seq<u8>| #[trigger] a.spec_parse(input) == b.spec_parse(input),
73 ensures
74 #[trigger] parser_congruent(a, b),
75{
76 reveal(parser_congruent);
77}
78
79pub broadcast proof fn lemma_ref_fn_parser_congruence<I, O, Spec, Exec>(
82 parser: &FnParser<I, O, Spec, Exec>,
83) where I: View<V = Seq<u8>>, O: DeepView, Spec: SpecParser<PVal = O::V>, Exec: Fn(&I) -> PResult<O>
84 ensures
85 #[trigger] parser_congruent(parser, parser.spec_fn@),
86{
87 reveal(parser_congruent);
88 assert forall|input: Seq<u8>| #[trigger]
89 (&parser).spec_parse(input) == parser.spec_fn@.spec_parse(input) by {
90 crate::core::exec::fns::lemma_ref_fn_parser_spec_parse(parser, input);
91 }
92}
93
94pub broadcast proof fn lemma_prepare_congruent_intro<A, B>(a: A, b: B) where
95 A: Consistency + SpecByteLen<T = A::Val>,
96 B: Consistency<Val = A::Val> + SpecByteLen<T = A::Val>,
97
98 requires
99 forall|v: A::Val| #[trigger] a.consistent(v) <==> b.consistent(v),
100 forall|v: A::Val| #[trigger] a.byte_len(v) == b.byte_len(v),
101 ensures
102 #[trigger] prepare_congruent(a, b),
103{
104 reveal(prepare_congruent);
105}
106
107pub broadcast proof fn lemma_serializer_congruent_intro<A, B>(a: A, b: B) where
108 A: Consistency + SpecByteLen<T = A::Val> + SpecSerializer<SVal = A::Val>,
109 B: Consistency<Val = A::Val> + SpecByteLen<T = A::Val> + SpecSerializer<SVal = A::Val>,
110
111 requires
112 prepare_congruent(a, b),
113 forall|v: A::Val| #[trigger] a.spec_serialize(v) == b.spec_serialize(v),
114 ensures
115 #[trigger] serializer_congruent(a, b),
116{
117 reveal(serializer_congruent);
118}
119
120pub broadcast proof fn lemma_prepare_congruent_consistent<A, B>(a: A, b: B, v: A::Val) where
121 A: Consistency + SpecByteLen<T = A::Val>,
122 B: Consistency<Val = A::Val> + SpecByteLen<T = A::Val>,
123
124 requires
125 prepare_congruent(a, b),
126 ensures
127 #[trigger] a.consistent(v) <==> #[trigger] b.consistent(v),
128{
129 reveal(prepare_congruent);
130}
131
132pub broadcast proof fn lemma_prepare_congruent_byte_len<A, B>(a: A, b: B, v: A::Val) where
133 A: Consistency + SpecByteLen<T = A::Val>,
134 B: Consistency<Val = A::Val> + SpecByteLen<T = A::Val>,
135
136 requires
137 prepare_congruent(a, b),
138 ensures
139 #[trigger] a.byte_len(v) == #[trigger] b.byte_len(v),
140{
141 reveal(prepare_congruent);
142}
143
144pub broadcast proof fn lemma_serializer_congruent_prepare<A, B>(a: A, b: B) where
145 A: Consistency + SpecByteLen<T = A::Val> + SpecSerializer<SVal = A::Val>,
146 B: Consistency<Val = A::Val> + SpecByteLen<T = A::Val> + SpecSerializer<SVal = A::Val>,
147
148 requires
149 serializer_congruent(a, b),
150 ensures
151 #[trigger] prepare_congruent(a, b),
152{
153 reveal(serializer_congruent);
154}
155
156pub broadcast proof fn lemma_serializer_congruent_serialize<A, B>(a: A, b: B, v: A::Val) where
157 A: Consistency + SpecByteLen<T = A::Val> + SpecSerializer<SVal = A::Val>,
158 B: Consistency<Val = A::Val> + SpecByteLen<T = A::Val> + SpecSerializer<SVal = A::Val>,
159
160 requires
161 serializer_congruent(a, b),
162 ensures
163 #[trigger] a.spec_serialize(v) == #[trigger] b.spec_serialize(v),
164{
165 reveal(serializer_congruent);
166}
167
168pub broadcast proof fn lemma_parser_congruent_reflexive<A: SpecParser>(a: A)
169 ensures
170 #[trigger] parser_congruent(a, a),
171{
172 reveal(parser_congruent);
173}
174
175pub proof fn lemma_parser_congruent_symmetric<A, B>(a: A, b: B) where
178 A: SpecParser,
179 B: SpecParser<PVal = A::PVal>,
180
181 requires
182 parser_congruent(a, b),
183 ensures
184 parser_congruent(b, a),
185{
186 reveal(parser_congruent);
187}
188
189pub proof fn lemma_parser_congruent_transitive<A, B, C>(a: A, b: B, c: C) where
190 A: SpecParser,
191 B: SpecParser<PVal = A::PVal>,
192 C: SpecParser<PVal = A::PVal>,
193
194 requires
195 parser_congruent(a, b),
196 parser_congruent(b, c),
197 ensures
198 parser_congruent(a, c),
199{
200 reveal(parser_congruent);
201}
202
203pub broadcast proof fn lemma_prepare_congruent_reflexive<A>(a: A) where
204 A: Consistency + SpecByteLen<T = A::Val>,
205
206 ensures
207 #[trigger] prepare_congruent(a, a),
208{
209 reveal(prepare_congruent);
210}
211
212pub proof fn lemma_prepare_congruent_symmetric<A, B>(a: A, b: B) where
213 A: Consistency + SpecByteLen<T = A::Val>,
214 B: Consistency<Val = A::Val> + SpecByteLen<T = A::Val>,
215
216 requires
217 prepare_congruent(a, b),
218 ensures
219 prepare_congruent(b, a),
220{
221 reveal(prepare_congruent);
222}
223
224pub proof fn lemma_prepare_congruent_transitive<A, B, C>(a: A, b: B, c: C) where
225 A: Consistency + SpecByteLen<T = A::Val>,
226 B: Consistency<Val = A::Val> + SpecByteLen<T = A::Val>,
227 C: Consistency<Val = A::Val> + SpecByteLen<T = A::Val>,
228
229 requires
230 prepare_congruent(a, b),
231 prepare_congruent(b, c),
232 ensures
233 prepare_congruent(a, c),
234{
235 reveal(prepare_congruent);
236}
237
238pub broadcast proof fn lemma_serializer_congruent_reflexive<A>(a: A) where
239 A: Consistency + SpecByteLen<T = A::Val> + SpecSerializer<SVal = A::Val>,
240
241 ensures
242 #[trigger] serializer_congruent(a, a),
243{
244 reveal(serializer_congruent);
245 lemma_prepare_congruent_reflexive(a);
246}
247
248pub proof fn lemma_serializer_congruent_symmetric<A, B>(a: A, b: B) where
249 A: Consistency + SpecByteLen<T = A::Val> + SpecSerializer<SVal = A::Val>,
250 B: Consistency<Val = A::Val> + SpecByteLen<T = A::Val> + SpecSerializer<SVal = A::Val>,
251
252 requires
253 serializer_congruent(a, b),
254 ensures
255 serializer_congruent(b, a),
256{
257 reveal(serializer_congruent);
258 lemma_prepare_congruent_symmetric(a, b);
259}
260
261pub proof fn lemma_serializer_congruent_transitive<A, B, C>(a: A, b: B, c: C) where
262 A: Consistency + SpecByteLen<T = A::Val> + SpecSerializer<SVal = A::Val>,
263 B: Consistency<Val = A::Val> + SpecByteLen<T = A::Val> + SpecSerializer<SVal = A::Val>,
264 C: Consistency<Val = A::Val> + SpecByteLen<T = A::Val> + SpecSerializer<SVal = A::Val>,
265
266 requires
267 serializer_congruent(a, b),
268 serializer_congruent(b, c),
269 ensures
270 serializer_congruent(a, c),
271{
272 reveal(serializer_congruent);
273 lemma_prepare_congruent_transitive(a, b, c);
274}
275
276pub proof fn lemma_exact_len_spec_parse_congruence<
280 Inner: SpecParser,
281 Inner2: SpecParser<PVal = Inner::PVal>,
282 Len: AsLen,
283>(len: Len, inner: Inner, inner2: Inner2)
284 requires
285 forall|x: Seq<u8>| #[trigger] inner.spec_parse(x) == inner2.spec_parse(x),
286 ensures
287 forall|x: Seq<u8>| #[trigger]
288 ExactLen(len, inner).spec_parse(x) == ExactLen(len, inner2).spec_parse(x),
289{
290}
291
292pub proof fn lemma_and_then_spec_parse_congruence<
296 Tail1: SpecParser<PVal = Seq<u8>>,
297 Tail2: SpecParser<PVal = Seq<u8>>,
298 Then1: SpecParser,
299 Then2: SpecParser<PVal = Then1::PVal>,
300>(tail1: Tail1, tail2: Tail2, then1: Then1, then2: Then2)
301 requires
302 forall|x: Seq<u8>| #[trigger] tail1.spec_parse(x) == tail2.spec_parse(x),
303 forall|x: Seq<u8>| #[trigger] then1.spec_parse(x) == then2.spec_parse(x),
304 ensures
305 forall|x: Seq<u8>| #[trigger]
306 AndThen(tail1, then1).spec_parse(x) == AndThen(tail2, then2).spec_parse(x),
307{
308}
309
310pub proof fn lemma_mapped_spec_parse_congruence<
314 Inner1: SpecParser,
315 Inner2: SpecParser<PVal = Inner1::PVal>,
316 M1: crate::combinators::mapped::spec::SpecMapper<In = Inner1::PVal>,
317 M2: crate::combinators::mapped::spec::SpecMapper<In = Inner2::PVal, Out = M1::Out>,
318>(inner1: Inner1, inner2: Inner2, mapper1: M1, mapper2: M2)
319 requires
320 forall|x: Seq<u8>| #[trigger] inner1.spec_parse(x) == inner2.spec_parse(x),
321 forall|v: Inner1::PVal| #[trigger] mapper1.spec_map(v) == mapper2.spec_map(v),
322 ensures
323 forall|x: Seq<u8>| #[trigger]
324 (Mapped { inner: inner1, mapper: mapper1 }).spec_parse(x) == (Mapped {
325 inner: inner2,
326 mapper: mapper2,
327 }).spec_parse(x),
328{
329}
330
331pub proof fn lemma_refined_spec_parse_congruence<
335 Inner1: SpecParser,
336 Inner2: SpecParser<PVal = Inner1::PVal>,
337 Pred: SpecPred<Inner1::PVal>,
338>(inner1: Inner1, inner2: Inner2, pred: Pred)
339 requires
340 forall|x: Seq<u8>| #[trigger] inner1.spec_parse(x) == inner2.spec_parse(x),
341 ensures
342 forall|x: Seq<u8>| #[trigger]
343 Refined(inner1, pred).spec_parse(x) == Refined(inner2, pred).spec_parse(x),
344{
345}
346
347pub proof fn lemma_const_spec_parse_congruence<
351 Inner1: SpecParser<PVal = T>,
352 Inner2: SpecParser<PVal = T>,
353 T,
354>(inner1: Inner1, inner2: Inner2, val: T)
355 requires
356 forall|x: Seq<u8>| #[trigger] inner1.spec_parse(x) == inner2.spec_parse(x),
357 ensures
358 forall|x: Seq<u8>| #[trigger]
359 Const(inner1, val).spec_parse(x) == Const(inner2, val).spec_parse(x),
360{
361}
362
363pub proof fn lemma_cond_spec_parse_congruence<
367 Inner1: SpecParser,
368 Inner2: SpecParser<PVal = Inner1::PVal>,
369>(cond: bool, inner1: Inner1, inner2: Inner2)
370 requires
371 forall|x: Seq<u8>| #[trigger] inner1.spec_parse(x) == inner2.spec_parse(x),
372 ensures
373 forall|x: Seq<u8>| #[trigger]
374 Cond(cond, inner1).spec_parse(x) == Cond(cond, inner2).spec_parse(x),
375{
376}
377
378pub proof fn lemma_choice_spec_parse_congruence<
382 A1: SpecParser,
383 A2: SpecParser<PVal = A1::PVal>,
384 B1: SpecParser,
385 B2: SpecParser<PVal = B1::PVal>,
386>(a1: A1, a2: A2, b1: B1, b2: B2)
387 requires
388 forall|x: Seq<u8>| #[trigger] a1.spec_parse(x) == a2.spec_parse(x),
389 forall|x: Seq<u8>| #[trigger] b1.spec_parse(x) == b2.spec_parse(x),
390 ensures
391 forall|x: Seq<u8>| #[trigger] Choice(a1, b1).spec_parse(x) == Choice(a2, b2).spec_parse(x),
392{
393}
394
395pub proof fn lemma_alt_spec_parse_congruence<
399 const NONDETERMINISTIC: bool,
400 A1: SpecParser,
401 A2: SpecParser<PVal = A1::PVal>,
402 B1: SpecParser<PVal = A1::PVal>,
403 B2: SpecParser<PVal = A1::PVal>,
404>(a1: A1, a2: A2, b1: B1, b2: B2)
405 requires
406 forall|x: Seq<u8>| #[trigger] a1.spec_parse(x) == a2.spec_parse(x),
407 forall|x: Seq<u8>| #[trigger] b1.spec_parse(x) == b2.spec_parse(x),
408 ensures
409 forall|x: Seq<u8>| #[trigger]
410 Alt::<A1, B1, NONDETERMINISTIC>(a1, b1).spec_parse(x) == Alt::<
411 A2,
412 B2,
413 NONDETERMINISTIC,
414 >(a2, b2).spec_parse(x),
415{
416}
417
418pub proof fn lemma_sum_spec_parse_congruence<
422 A1: SpecParser,
423 A2: SpecParser<PVal = A1::PVal>,
424 B1: SpecParser,
425 B2: SpecParser<PVal = B1::PVal>,
426>(a1: A1, a2: A2, b1: B1, b2: B2)
427 requires
428 forall|x: Seq<u8>| #[trigger] a1.spec_parse(x) == a2.spec_parse(x),
429 forall|x: Seq<u8>| #[trigger] b1.spec_parse(x) == b2.spec_parse(x),
430 ensures
431 forall|x: Seq<u8>| #[trigger]
432 Sum::<A1, B1>::Inl(a1).spec_parse(x) == Sum::<A2, B2>::Inl(a2).spec_parse(x),
433 forall|x: Seq<u8>| #[trigger]
434 Sum::<A1, B1>::Inr(b1).spec_parse(x) == Sum::<A2, B2>::Inr(b2).spec_parse(x),
435{
436}
437
438pub proof fn lemma_opt_spec_parse_congruence<A: SpecParser, B: SpecParser<PVal = A::PVal>>(
442 a: A,
443 b: B,
444)
445 requires
446 forall|x: Seq<u8>| #[trigger] a.spec_parse(x) == b.spec_parse(x),
447 ensures
448 forall|x: Seq<u8>| #[trigger] Opt(a).spec_parse(x) == Opt(b).spec_parse(x),
449{
450}
451
452pub proof fn lemma_optional_spec_parse_congruence<
456 A1: SpecParser,
457 A2: SpecParser<PVal = A1::PVal>,
458 B1: SpecParser,
459 B2: SpecParser<PVal = B1::PVal>,
460>(a1: A1, a2: A2, b1: B1, b2: B2)
461 requires
462 forall|x: Seq<u8>| #[trigger] a1.spec_parse(x) == a2.spec_parse(x),
463 forall|x: Seq<u8>| #[trigger] b1.spec_parse(x) == b2.spec_parse(x),
464 ensures
465 forall|x: Seq<u8>| #[trigger]
466 Optional(a1, b1).spec_parse(x) == Optional(a2, b2).spec_parse(x),
467{
468 lemma_opt_spec_parse_congruence(a1, a2);
469 lemma_pair_spec_parse_congruence(Opt(a1), Opt(a2), b1, b2);
470}
471
472pub proof fn lemma_optional_end_spec_parse_congruence<
476 Inner1: SpecParser,
477 Inner2: SpecParser<PVal = Inner1::PVal>,
478>(inner1: Inner1, inner2: Inner2)
479 requires
480 forall|x: Seq<u8>| #[trigger] inner1.spec_parse(x) == inner2.spec_parse(x),
481 ensures
482 forall|x: Seq<u8>| #[trigger]
483 OptionalEnd(inner1).spec_parse(x) == OptionalEnd(inner2).spec_parse(x),
484{
485 lemma_optional_spec_parse_congruence(inner1, inner2, Eof, Eof);
486}
487
488pub proof fn lemma_preceded_spec_parse_congruence<
492 const CHECK: bool,
493 A1: SpecParser<PVal = AVal>,
494 A2: SpecParser<PVal = AVal>,
495 B1: SpecParser,
496 B2: SpecParser<PVal = B1::PVal>,
497 AVal,
498>(a1: A1, a2: A2, b1: B1, b2: B2, a_val: AVal)
499 requires
500 forall|x: Seq<u8>| #[trigger] a1.spec_parse(x) == a2.spec_parse(x),
501 forall|x: Seq<u8>| #[trigger] b1.spec_parse(x) == b2.spec_parse(x),
502 ensures
503 forall|x: Seq<u8>| #[trigger]
504 (Preceded::<A1, AVal, B1, CHECK> { a: a1, b: b1, a_val }).spec_parse(x) == (Preceded::<
505 A2,
506 AVal,
507 B2,
508 CHECK,
509 > { a: a2, b: b2, a_val }).spec_parse(x),
510{
511 lemma_pair_spec_parse_congruence(a1, a2, b1, b2);
512}
513
514pub proof fn lemma_terminated_spec_parse_congruence<
518 const CHECK: bool,
519 A1: SpecParser,
520 A2: SpecParser<PVal = A1::PVal>,
521 B1: SpecParser<PVal = BVal>,
522 B2: SpecParser<PVal = BVal>,
523 BVal,
524>(a1: A1, a2: A2, b1: B1, b2: B2, b_val: BVal)
525 requires
526 forall|x: Seq<u8>| #[trigger] a1.spec_parse(x) == a2.spec_parse(x),
527 forall|x: Seq<u8>| #[trigger] b1.spec_parse(x) == b2.spec_parse(x),
528 ensures
529 forall|x: Seq<u8>| #[trigger]
530 (Terminated::<A1, B1, BVal, CHECK> { a: a1, b: b1, b_val }).spec_parse(x) == (
531 Terminated::<A2, B2, BVal, CHECK> { a: a2, b: b2, b_val }).spec_parse(x),
532{
533 lemma_pair_spec_parse_congruence(a1, a2, b1, b2);
534}
535
536pub proof fn lemma_pair_spec_parse_congruence<
540 A1: SpecParser,
541 A2: SpecParser<PVal = A1::PVal>,
542 B1: SpecParser,
543 B2: SpecParser<PVal = B1::PVal>,
544>(a1: A1, a2: A2, b1: B1, b2: B2)
545 requires
546 forall|x: Seq<u8>| #[trigger] a1.spec_parse(x) == a2.spec_parse(x),
547 forall|x: Seq<u8>| #[trigger] b1.spec_parse(x) == b2.spec_parse(x),
548 ensures
549 forall|x: Seq<u8>| #[trigger] Pair(a1, b1).spec_parse(x) == Pair(a2, b2).spec_parse(x),
550{
551}
552
553pub proof fn lemma_bind_spec_parse_congruence<
557 A1: SpecParser,
558 A2: SpecParser<PVal = A1::PVal>,
559 B1: SpecMap<Input = A1::PVal>,
560 B2: SpecMap<Input = A2::PVal>,
561 OutVal,
562>(a1: A1, a2: A2, b1: B1, b2: B2) where
563 B1::Output: SpecParser<PVal = OutVal>,
564 B2::Output: SpecParser<PVal = OutVal>,
565
566 requires
567 forall|x: Seq<u8>| #[trigger] a1.spec_parse(x) == a2.spec_parse(x),
568 forall|key: A1::PVal, x: Seq<u8>| #[trigger]
569 b1.spec_map(key).spec_parse(x) == b2.spec_map(key).spec_parse(x),
570 ensures
571 forall|x: Seq<u8>| #[trigger] Bind(a1, b1).spec_parse(x) == Bind(a2, b2).spec_parse(x),
572{
573}
574
575pub proof fn lemma_ref_spec_parse_congruence<
579 Inner1: SpecParser,
580 Inner2: SpecParser<PVal = Inner1::PVal>,
581>(inner1: Inner1, inner2: Inner2)
582 requires
583 forall|x: Seq<u8>| #[trigger] inner1.spec_parse(x) == inner2.spec_parse(x),
584 ensures
585 forall|x: Seq<u8>| #[trigger] Ref(inner1).spec_parse(x) == Ref(inner2).spec_parse(x),
586{
587}
588
589pub proof fn lemma_named_spec_parse_congruence<
593 Inner1: SpecParser,
594 Inner2: SpecParser<PVal = Inner1::PVal>,
595>(name: &'static str, inner1: Inner1, inner2: Inner2)
596 requires
597 forall|x: Seq<u8>| #[trigger] inner1.spec_parse(x) == inner2.spec_parse(x),
598 ensures
599 forall|x: Seq<u8>| #[trigger]
600 Named(name, inner1).spec_parse(x) == Named(name, inner2).spec_parse(x),
601{
602}
603
604pub proof fn lemma_star_parse_rec_congruence<A: SpecParser, B: SpecParser<PVal = A::PVal>>(
608 a: A,
609 b: B,
610 ibuf: Seq<u8>,
611)
612 requires
613 forall|x: Seq<u8>| #[trigger] a.spec_parse(x) == b.spec_parse(x),
614 ensures
615 Star(a).parse_rec(ibuf) == Star(b).parse_rec(ibuf),
616 decreases ibuf.len(),
617{
618 if let Some((n, _v)) = a.spec_parse(ibuf) {
619 if 0 < n <= ibuf.len() {
620 lemma_star_parse_rec_congruence(a, b, ibuf.skip(n));
621 }
622 }
623}
624
625pub proof fn lemma_star_spec_parse_congruence<A: SpecParser, B: SpecParser<PVal = A::PVal>>(
626 a: A,
627 b: B,
628)
629 requires
630 forall|x: Seq<u8>| #[trigger] a.spec_parse(x) == b.spec_parse(x),
631 ensures
632 forall|x: Seq<u8>| #[trigger] Star(a).spec_parse(x) == Star(b).spec_parse(x),
633{
634 reveal(<Star::<_> as SpecParser>::spec_parse);
635 assert forall|x: Seq<u8>| #[trigger] Star(a).spec_parse(x) == Star(b).spec_parse(x) by {
636 lemma_star_parse_rec_congruence(a, b, x);
637 }
638}
639
640pub proof fn lemma_repeat_spec_parse_congruence<
641 A: SpecParser,
642 B: SpecParser<PVal = A::PVal>,
643 T: SpecParser,
644>(a: A, b: B, t: T)
645 requires
646 forall|x: Seq<u8>| #[trigger] a.spec_parse(x) == b.spec_parse(x),
647 ensures
648 forall|x: Seq<u8>| #[trigger] Repeat(a, t).spec_parse(x) == Repeat(b, t).spec_parse(x),
649{
650 lemma_star_spec_parse_congruence(a, b);
651 lemma_pair_spec_parse_congruence(Star(a), Star(b), t, t);
652}
653
654pub proof fn lemma_repeat_till_end_spec_parse_congruence<
655 A: SpecParser,
656 B: SpecParser<PVal = A::PVal>,
657>(a: A, b: B)
658 requires
659 forall|x: Seq<u8>| #[trigger] a.spec_parse(x) == b.spec_parse(x),
660 ensures
661 forall|x: Seq<u8>| #[trigger]
662 RepeatTillEnd(a).spec_parse(x) == RepeatTillEnd(b).spec_parse(x),
663{
664 lemma_repeat_spec_parse_congruence(a, b, Eof);
665}
666
667pub proof fn lemma_repeat_n_parse_n_rec_congruence<
671 A: SpecParser,
672 B: SpecParser<PVal = A::PVal>,
673 N: AsLen,
674>(a: &RepeatN<A, N>, b: &RepeatN<B, N>, count: nat, ibuf: Seq<u8>)
675 requires
676 forall|x: Seq<u8>| #[trigger] a.1.spec_parse(x) == b.1.spec_parse(x),
677 ensures
678 a.parse_n_rec(count, ibuf) == b.parse_n_rec(count, ibuf),
679 decreases count,
680{
681 if count == 0 {
682 } else {
683 assert(a.1.spec_parse(ibuf) == b.1.spec_parse(ibuf));
684 if let Some((n0, _)) = a.1.spec_parse(ibuf) {
685 lemma_repeat_n_parse_n_rec_congruence(a, b, (count - 1) as nat, ibuf.skip(n0));
686 }
687 }
688}
689
690pub proof fn lemma_repeat_n_spec_parse_congruence<
691 A: SpecParser,
692 B: SpecParser<PVal = A::PVal>,
693 N: AsLen,
694>(a: RepeatN<A, N>, b: RepeatN<B, N>)
695 requires
696 forall|x: Seq<u8>| #[trigger] a.1.spec_parse(x) == b.1.spec_parse(x),
697 a.0.as_nat() == b.0.as_nat(),
698 ensures
699 forall|x: Seq<u8>| #[trigger] a.spec_parse(x) == b.spec_parse(x),
700{
701 assert forall|x: Seq<u8>| #[trigger] a.spec_parse(x) == b.spec_parse(x) by {
702 lemma_repeat_n_parse_n_rec_congruence(&a, &b, a.0.as_nat(), x);
703 }
704}
705
706pub broadcast proof fn lemma_exact_len_parser_congruence<
710 Inner1: SpecParser,
711 Inner2: SpecParser<PVal = Inner1::PVal>,
712 Len: AsLen,
713>(len: Len, inner1: Inner1, inner2: Inner2)
714 requires
715 parser_congruent(inner1, inner2),
716 ensures
717 #[trigger] parser_congruent(ExactLen(len, inner1), ExactLen(len, inner2)),
718{
719 reveal(parser_congruent);
720 lemma_exact_len_spec_parse_congruence(len, inner1, inner2);
721}
722
723pub broadcast proof fn lemma_pair_parser_congruence<
724 A1: SpecParser,
725 A2: SpecParser<PVal = A1::PVal>,
726 B1: SpecParser,
727 B2: SpecParser<PVal = B1::PVal>,
728>(a1: A1, a2: A2, b1: B1, b2: B2)
729 requires
730 parser_congruent(a1, a2),
731 parser_congruent(b1, b2),
732 ensures
733 #[trigger] parser_congruent(Pair(a1, b1), Pair(a2, b2)),
734{
735 reveal(parser_congruent);
736 lemma_pair_spec_parse_congruence(a1, a2, b1, b2);
737}
738
739pub broadcast proof fn lemma_ref_parser_congruence<
740 Inner1: SpecParser,
741 Inner2: SpecParser<PVal = Inner1::PVal>,
742>(inner1: Inner1, inner2: Inner2)
743 requires
744 parser_congruent(inner1, inner2),
745 ensures
746 #[trigger] parser_congruent(Ref(inner1), Ref(inner2)),
747{
748 reveal(parser_congruent);
749 lemma_ref_spec_parse_congruence(inner1, inner2);
750}
751
752pub broadcast proof fn lemma_named_parser_congruence<
753 Inner1: SpecParser,
754 Inner2: SpecParser<PVal = Inner1::PVal>,
755>(name1: &'static str, name2: &'static str, inner1: Inner1, inner2: Inner2)
756 requires
757 parser_congruent(inner1, inner2),
758 ensures
759 #[trigger] parser_congruent(Named(name1, inner1), Named(name2, inner2)),
760{
761 reveal(parser_congruent);
762}
763
764pub broadcast proof fn lemma_star_parser_congruence<A: SpecParser, B: SpecParser<PVal = A::PVal>>(
765 a: A,
766 b: B,
767)
768 requires
769 parser_congruent(a, b),
770 ensures
771 #[trigger] parser_congruent(Star(a), Star(b)),
772{
773 reveal(parser_congruent);
774 lemma_star_spec_parse_congruence(a, b);
775}
776
777pub broadcast proof fn lemma_repeat_parser_congruence<
778 A: SpecParser,
779 B: SpecParser<PVal = A::PVal>,
780 T1: SpecParser,
781 T2: SpecParser<PVal = T1::PVal>,
782>(a: A, b: B, t1: T1, t2: T2)
783 requires
784 parser_congruent(a, b),
785 parser_congruent(t1, t2),
786 ensures
787 #[trigger] parser_congruent(Repeat(a, t1), Repeat(b, t2)),
788{
789 reveal(parser_congruent);
790 lemma_star_spec_parse_congruence(a, b);
791 lemma_pair_spec_parse_congruence(Star(a), Star(b), t1, t2);
792}
793
794pub broadcast proof fn lemma_repeat_till_end_parser_congruence<
795 A: SpecParser,
796 B: SpecParser<PVal = A::PVal>,
797>(a: A, b: B)
798 requires
799 parser_congruent(a, b),
800 ensures
801 #[trigger] parser_congruent(RepeatTillEnd(a), RepeatTillEnd(b)),
802{
803 reveal(parser_congruent);
804 lemma_repeat_till_end_spec_parse_congruence(a, b);
805}
806
807pub broadcast proof fn lemma_repeat_n_parser_congruence<
808 A: SpecParser,
809 B: SpecParser<PVal = A::PVal>,
810 N: AsLen,
811>(a: RepeatN<A, N>, b: RepeatN<B, N>)
812 requires
813 parser_congruent(a.1, b.1),
814 a.0.as_nat() == b.0.as_nat(),
815 ensures
816 #[trigger] parser_congruent(a, b),
817{
818 reveal(parser_congruent);
819 lemma_repeat_n_spec_parse_congruence(a, b);
820}
821
822pub broadcast proof fn lemma_array_parser_congruence<
823 A: SpecParser,
824 B: SpecParser<PVal = A::PVal>,
825 const N: usize,
826>(a: A, b: B)
827 requires
828 parser_congruent(a, b),
829 ensures
830 #[trigger] parser_congruent(Array::<N, A>(a), Array::<N, B>(b)),
831{
832 reveal(parser_congruent);
833 lemma_repeat_n_spec_parse_congruence(RepeatN(N, a), RepeatN(N, b));
834}
835
836pub broadcast proof fn lemma_and_then_parser_congruence<
837 Tail1: SpecParser<PVal = Seq<u8>>,
838 Tail2: SpecParser<PVal = Seq<u8>>,
839 Then1: SpecParser,
840 Then2: SpecParser<PVal = Then1::PVal>,
841>(tail1: Tail1, tail2: Tail2, then1: Then1, then2: Then2)
842 requires
843 parser_congruent(tail1, tail2),
844 parser_congruent(then1, then2),
845 ensures
846 #[trigger] parser_congruent(AndThen(tail1, then1), AndThen(tail2, then2)),
847{
848 reveal(parser_congruent);
849 lemma_and_then_spec_parse_congruence(tail1, tail2, then1, then2);
850}
851
852pub broadcast proof fn lemma_mapped_parser_congruence<
853 Inner1: SpecParser,
854 Inner2: SpecParser<PVal = Inner1::PVal>,
855 M1: crate::combinators::mapped::spec::SpecMapper<In = Inner1::PVal>,
856 M2: crate::combinators::mapped::spec::SpecMapper<In = Inner2::PVal, Out = M1::Out>,
857>(inner1: Inner1, inner2: Inner2, mapper1: M1, mapper2: M2)
858 requires
859 parser_congruent(inner1, inner2),
860 forall|v: Inner1::PVal| #[trigger] mapper1.spec_map(v) == mapper2.spec_map(v),
861 ensures
862 #[trigger] parser_congruent(
863 Mapped { inner: inner1, mapper: mapper1 },
864 Mapped { inner: inner2, mapper: mapper2 },
865 ),
866{
867 reveal(parser_congruent);
868 lemma_mapped_spec_parse_congruence(inner1, inner2, mapper1, mapper2);
869}
870
871pub broadcast proof fn lemma_refined_parser_congruence<
872 Inner1: SpecParser,
873 Inner2: SpecParser<PVal = Inner1::PVal>,
874 P1: SpecPred<Inner1::PVal>,
875 P2: SpecPred<Inner1::PVal>,
876>(a: Refined<Inner1, P1>, b: Refined<Inner2, P2>)
877 requires
878 parser_congruent(a.0, b.0),
879 forall|v: Inner1::PVal| #[trigger] a.1.apply(v) <==> b.1.apply(v),
880 ensures
881 #[trigger] parser_congruent(a, b),
882{
883 reveal(parser_congruent);
884}
885
886pub broadcast proof fn lemma_const_parser_congruence<
887 Inner1: SpecParser<PVal = T>,
888 Inner2: SpecParser<PVal = T>,
889 T,
890>(a: Const<Inner1, T>, b: Const<Inner2, T>)
891 requires
892 parser_congruent(a.0, b.0),
893 a.1 == b.1,
894 ensures
895 #[trigger] parser_congruent(a, b),
896{
897 reveal(parser_congruent);
898}
899
900pub broadcast proof fn lemma_cond_parser_congruence<
901 Inner1: SpecParser,
902 Inner2: SpecParser<PVal = Inner1::PVal>,
903>(a: Cond<Inner1>, b: Cond<Inner2>)
904 requires
905 a.0 == b.0,
906 parser_congruent(a.1, b.1),
907 ensures
908 #[trigger] parser_congruent(a, b),
909{
910 reveal(parser_congruent);
911}
912
913pub broadcast proof fn lemma_choice_parser_congruence<
914 A1: SpecParser,
915 A2: SpecParser<PVal = A1::PVal>,
916 B1: SpecParser,
917 B2: SpecParser<PVal = B1::PVal>,
918>(a1: A1, a2: A2, b1: B1, b2: B2)
919 requires
920 parser_congruent(a1, a2),
921 parser_congruent(b1, b2),
922 ensures
923 #[trigger] parser_congruent(Choice(a1, b1), Choice(a2, b2)),
924{
925 reveal(parser_congruent);
926 lemma_choice_spec_parse_congruence(a1, a2, b1, b2);
927}
928
929pub broadcast proof fn lemma_alt_parser_congruence<
930 const NONDETERMINISTIC: bool,
931 A1: SpecParser,
932 A2: SpecParser<PVal = A1::PVal>,
933 B1: SpecParser<PVal = A1::PVal>,
934 B2: SpecParser<PVal = A1::PVal>,
935>(a1: A1, a2: A2, b1: B1, b2: B2)
936 requires
937 parser_congruent(a1, a2),
938 parser_congruent(b1, b2),
939 ensures
940 #[trigger] parser_congruent(
941 Alt::<A1, B1, NONDETERMINISTIC>(a1, b1),
942 Alt::<A2, B2, NONDETERMINISTIC>(a2, b2),
943 ),
944{
945 reveal(parser_congruent);
946 lemma_alt_spec_parse_congruence::<NONDETERMINISTIC, _, _, _, _>(a1, a2, b1, b2);
947}
948
949pub broadcast proof fn lemma_opt_parser_congruence<A: SpecParser, B: SpecParser<PVal = A::PVal>>(
950 a: A,
951 b: B,
952)
953 requires
954 parser_congruent(a, b),
955 ensures
956 #[trigger] parser_congruent(Opt(a), Opt(b)),
957{
958 reveal(parser_congruent);
959 lemma_opt_spec_parse_congruence(a, b);
960}
961
962pub broadcast proof fn lemma_optional_parser_congruence<
963 A1: SpecParser,
964 A2: SpecParser<PVal = A1::PVal>,
965 B1: SpecParser,
966 B2: SpecParser<PVal = B1::PVal>,
967>(a1: A1, a2: A2, b1: B1, b2: B2)
968 requires
969 parser_congruent(a1, a2),
970 parser_congruent(b1, b2),
971 ensures
972 #[trigger] parser_congruent(Optional(a1, b1), Optional(a2, b2)),
973{
974 reveal(parser_congruent);
975 lemma_optional_spec_parse_congruence(a1, a2, b1, b2);
976}
977
978pub broadcast proof fn lemma_optional_end_parser_congruence<
979 A: SpecParser,
980 B: SpecParser<PVal = A::PVal>,
981>(a: A, b: B)
982 requires
983 parser_congruent(a, b),
984 ensures
985 #[trigger] parser_congruent(OptionalEnd(a), OptionalEnd(b)),
986{
987 reveal(parser_congruent);
988 lemma_optional_end_spec_parse_congruence(a, b);
989}
990
991pub broadcast proof fn lemma_preceded_parser_congruence<
992 const CHECK: bool,
993 A1: SpecParser<PVal = AVal>,
994 A2: SpecParser<PVal = AVal>,
995 B1: SpecParser,
996 B2: SpecParser<PVal = B1::PVal>,
997 AVal,
998>(a: Preceded<A1, AVal, B1, CHECK>, b: Preceded<A2, AVal, B2, CHECK>)
999 requires
1000 parser_congruent(a.a, b.a),
1001 parser_congruent(a.b, b.b),
1002 a.a_val == b.a_val,
1003 ensures
1004 #[trigger] parser_congruent(a, b),
1005{
1006 reveal(parser_congruent);
1007 lemma_preceded_spec_parse_congruence::<CHECK, _, _, _, _, _>(a.a, b.a, a.b, b.b, a.a_val);
1008}
1009
1010pub broadcast proof fn lemma_terminated_parser_congruence<
1011 const CHECK: bool,
1012 A1: SpecParser,
1013 A2: SpecParser<PVal = A1::PVal>,
1014 B1: SpecParser<PVal = BVal>,
1015 B2: SpecParser<PVal = BVal>,
1016 BVal,
1017>(a: Terminated<A1, B1, BVal, CHECK>, b: Terminated<A2, B2, BVal, CHECK>)
1018 requires
1019 parser_congruent(a.a, b.a),
1020 parser_congruent(a.b, b.b),
1021 a.b_val == b.b_val,
1022 ensures
1023 #[trigger] parser_congruent(a, b),
1024{
1025 reveal(parser_congruent);
1026 lemma_terminated_spec_parse_congruence::<CHECK, _, _, _, _, _>(a.a, b.a, a.b, b.b, a.b_val);
1027}
1028
1029pub broadcast proof fn lemma_bind_parser_congruence<
1030 A1: SpecParser,
1031 A2: SpecParser<PVal = A1::PVal>,
1032 B1: SpecMap<Input = A1::PVal>,
1033 B2: SpecMap<Input = A2::PVal>,
1034>(a: Bind<A1, B1>, b: Bind<A2, B2>) where
1035 B1::Output: SpecParser,
1036 B2::Output: SpecParser<PVal = <B1::Output as SpecParser>::PVal>,
1037
1038 requires
1039 parser_congruent(a.0, b.0),
1040 forall|key: A1::PVal| #[trigger] parser_congruent(a.1.spec_map(key), b.1.spec_map(key)),
1041 ensures
1042 #[trigger] parser_congruent(a, b),
1043{
1044 reveal(parser_congruent);
1045 broadcast use lemma_parser_congruent_apply;
1046
1047 lemma_bind_spec_parse_congruence(a.0, b.0, a.1, b.1);
1048}
1049
1050pub broadcast proof fn lemma_sum_parser_congruence<
1051 A1: SpecParser,
1052 A2: SpecParser<PVal = A1::PVal>,
1053 B1: SpecParser,
1054 B2: SpecParser<PVal = B1::PVal>,
1055>(a: Sum<A1, B1>, b: Sum<A2, B2>)
1056 requires
1057 match (a, b) {
1058 (Sum::Inl(a), Sum::Inl(b)) => parser_congruent(a, b),
1059 (Sum::Inr(a), Sum::Inr(b)) => parser_congruent(a, b),
1060 _ => false,
1061 },
1062 ensures
1063 #[trigger] parser_congruent(a, b),
1064{
1065 reveal(parser_congruent);
1066 match (a, b) {
1067 (Sum::Inl(a), Sum::Inl(b)) => lemma_sum_spec_parse_congruence(a, b, a, b),
1068 (Sum::Inr(a), Sum::Inr(b)) => lemma_sum_spec_parse_congruence(a, b, a, b),
1069 _ => {},
1070 }
1071}
1072
1073pub broadcast proof fn lemma_exact_len_prepare_congruence<A, B, L1, L2>(
1077 a: ExactLen<A, L1>,
1078 b: ExactLen<B, L2>,
1079) where
1080 A: Consistency + SpecByteLen<T = A::Val>,
1081 B: Consistency<Val = A::Val> + SpecByteLen<T = A::Val>,
1082 L1: AsLen,
1083 L2: AsLen,
1084
1085 requires
1086 prepare_congruent(a.1, b.1),
1087 a.0.as_nat() == b.0.as_nat(),
1088 ensures
1089 #[trigger] prepare_congruent(a, b),
1090{
1091 reveal(prepare_congruent);
1092}
1093
1094pub broadcast proof fn lemma_exact_len_serializer_congruence<A, B, L1, L2>(
1095 a: ExactLen<A, L1>,
1096 b: ExactLen<B, L2>,
1097) where
1098 A: Consistency + SpecByteLen<T = A::Val> + SpecSerializer<SVal = A::Val>,
1099 B: Consistency<Val = A::Val> + SpecByteLen<T = A::Val> + SpecSerializer<SVal = A::Val>,
1100 L1: AsLen,
1101 L2: AsLen,
1102
1103 requires
1104 serializer_congruent(a.1, b.1),
1105 a.0.as_nat() == b.0.as_nat(),
1106 ensures
1107 #[trigger] serializer_congruent(a, b),
1108{
1109 reveal(serializer_congruent);
1110 lemma_exact_len_prepare_congruence(a, b);
1111}
1112
1113pub broadcast proof fn lemma_refined_prepare_congruence<A, B, P1, P2>(
1114 a: Refined<A, P1>,
1115 b: Refined<B, P2>,
1116) where
1117 A: Consistency + SpecByteLen<T = A::Val>,
1118 B: Consistency<Val = A::Val> + SpecByteLen<T = A::Val>,
1119 P1: SpecPred<A::Val>,
1120 P2: SpecPred<A::Val>,
1121
1122 requires
1123 prepare_congruent(a.0, b.0),
1124 forall|v: A::Val| #[trigger] a.1.apply(v) <==> b.1.apply(v),
1125 ensures
1126 #[trigger] prepare_congruent(a, b),
1127{
1128 reveal(prepare_congruent);
1129}
1130
1131pub broadcast proof fn lemma_refined_serializer_congruence<A, B, P1, P2>(
1132 a: Refined<A, P1>,
1133 b: Refined<B, P2>,
1134) where
1135 A: Consistency + SpecByteLen<T = A::Val> + SpecSerializer<SVal = A::Val>,
1136 B: Consistency<Val = A::Val> + SpecByteLen<T = A::Val> + SpecSerializer<SVal = A::Val>,
1137 P1: SpecPred<A::Val>,
1138 P2: SpecPred<A::Val>,
1139
1140 requires
1141 serializer_congruent(a.0, b.0),
1142 forall|v: A::Val| #[trigger] a.1.apply(v) <==> b.1.apply(v),
1143 ensures
1144 #[trigger] serializer_congruent(a, b),
1145{
1146 reveal(serializer_congruent);
1147 lemma_refined_prepare_congruence(a, b);
1148}
1149
1150pub broadcast proof fn lemma_cond_prepare_congruence<A, B>(a: Cond<A>, b: Cond<B>) where
1151 A: Consistency + SpecByteLen<T = A::Val>,
1152 B: Consistency<Val = A::Val> + SpecByteLen<T = A::Val>,
1153
1154 requires
1155 a.0 == b.0,
1156 prepare_congruent(a.1, b.1),
1157 ensures
1158 #[trigger] prepare_congruent(a, b),
1159{
1160 reveal(prepare_congruent);
1161}
1162
1163pub broadcast proof fn lemma_cond_serializer_congruence<A, B>(a: Cond<A>, b: Cond<B>) where
1164 A: Consistency + SpecByteLen<T = A::Val> + SpecSerializer<SVal = A::Val>,
1165 B: Consistency<Val = A::Val> + SpecByteLen<T = A::Val> + SpecSerializer<SVal = A::Val>,
1166
1167 requires
1168 a.0 == b.0,
1169 serializer_congruent(a.1, b.1),
1170 ensures
1171 #[trigger] serializer_congruent(a, b),
1172{
1173 reveal(serializer_congruent);
1174 lemma_cond_prepare_congruence(a, b);
1175}
1176
1177pub broadcast proof fn lemma_const_prepare_congruence<A, B>(
1178 a: Const<A, A::Val>,
1179 b: Const<B, A::Val>,
1180) where
1181 A: Consistency + SpecByteLen<T = A::Val>,
1182 B: Consistency<Val = A::Val> + SpecByteLen<T = A::Val>,
1183
1184 requires
1185 a.1 == b.1,
1186 prepare_congruent(a.0, b.0),
1187 ensures
1188 #[trigger] prepare_congruent(a, b),
1189{
1190 reveal(prepare_congruent);
1191}
1192
1193pub broadcast proof fn lemma_const_serializer_congruence<A, B>(
1194 a: Const<A, A::Val>,
1195 b: Const<B, A::Val>,
1196) where
1197 A: Consistency + SpecByteLen<T = A::Val> + SpecSerializer<SVal = A::Val>,
1198 B: Consistency<Val = A::Val> + SpecByteLen<T = A::Val> + SpecSerializer<SVal = A::Val>,
1199
1200 requires
1201 a.1 == b.1,
1202 serializer_congruent(a.0, b.0),
1203 ensures
1204 #[trigger] serializer_congruent(a, b),
1205{
1206 reveal(serializer_congruent);
1207 lemma_const_prepare_congruence(a, b);
1208}
1209
1210pub broadcast proof fn lemma_opt_prepare_congruence<A, B>(a: Opt<A>, b: Opt<B>) where
1211 A: Consistency + SpecByteLen<T = A::Val>,
1212 B: Consistency<Val = A::Val> + SpecByteLen<T = A::Val>,
1213
1214 requires
1215 prepare_congruent(a.0, b.0),
1216 ensures
1217 #[trigger] prepare_congruent(a, b),
1218{
1219 reveal(prepare_congruent);
1220}
1221
1222pub broadcast proof fn lemma_opt_serializer_congruence<A, B>(a: Opt<A>, b: Opt<B>) where
1223 A: Consistency + SpecByteLen<T = A::Val> + SpecSerializer<SVal = A::Val>,
1224 B: Consistency<Val = A::Val> + SpecByteLen<T = A::Val> + SpecSerializer<SVal = A::Val>,
1225
1226 requires
1227 serializer_congruent(a.0, b.0),
1228 ensures
1229 #[trigger] serializer_congruent(a, b),
1230{
1231 reveal(serializer_congruent);
1232 lemma_opt_prepare_congruence(a, b);
1233}
1234
1235pub broadcast proof fn lemma_ref_prepare_congruence<A, B>(a: Ref<A>, b: Ref<B>) where
1236 A: Consistency + SpecByteLen<T = A::Val>,
1237 B: Consistency<Val = A::Val> + SpecByteLen<T = A::Val>,
1238
1239 requires
1240 prepare_congruent(a.0, b.0),
1241 ensures
1242 #[trigger] prepare_congruent(a, b),
1243{
1244 reveal(prepare_congruent);
1245}
1246
1247pub broadcast proof fn lemma_ref_serializer_congruence<A, B>(a: Ref<A>, b: Ref<B>) where
1248 A: Consistency + SpecByteLen<T = A::Val> + SpecSerializer<SVal = A::Val>,
1249 B: Consistency<Val = A::Val> + SpecByteLen<T = A::Val> + SpecSerializer<SVal = A::Val>,
1250
1251 requires
1252 serializer_congruent(a.0, b.0),
1253 ensures
1254 #[trigger] serializer_congruent(a, b),
1255{
1256 reveal(serializer_congruent);
1257 lemma_ref_prepare_congruence(a, b);
1258}
1259
1260pub broadcast proof fn lemma_named_prepare_congruence<A, B>(a: Named<A>, b: Named<B>) where
1261 A: Consistency + SpecByteLen<T = A::Val>,
1262 B: Consistency<Val = A::Val> + SpecByteLen<T = A::Val>,
1263
1264 requires
1265 prepare_congruent(a.1, b.1),
1266 ensures
1267 #[trigger] prepare_congruent(a, b),
1268{
1269 reveal(prepare_congruent);
1270}
1271
1272pub broadcast proof fn lemma_named_serializer_congruence<A, B>(a: Named<A>, b: Named<B>) where
1273 A: Consistency + SpecByteLen<T = A::Val> + SpecSerializer<SVal = A::Val>,
1274 B: Consistency<Val = A::Val> + SpecByteLen<T = A::Val> + SpecSerializer<SVal = A::Val>,
1275
1276 requires
1277 serializer_congruent(a.1, b.1),
1278 ensures
1279 #[trigger] serializer_congruent(a, b),
1280{
1281 reveal(serializer_congruent);
1282 lemma_named_prepare_congruence(a, b);
1283}
1284
1285proof fn lemma_star_byte_len_congruence_rec<A, B>(a: A, b: B, vs: Seq<A::Val>) where
1289 A: Consistency + SpecByteLen<T = A::Val>,
1290 B: Consistency<Val = A::Val> + SpecByteLen<T = A::Val>,
1291
1292 requires
1293 prepare_congruent(a, b),
1294 ensures
1295 Star(a).byte_len(vs) == Star(b).byte_len(vs),
1296 decreases vs.len(),
1297{
1298 reveal(prepare_congruent);
1299 reveal(<Star::<_> as SpecByteLen>::byte_len);
1300 if vs.len() > 0 {
1301 lemma_star_byte_len_congruence_rec(a, b, vs.drop_last());
1302 }
1303}
1304
1305proof fn lemma_star_serialize_congruence_rec<A, B>(a: A, b: B, vs: Seq<A::Val>) where
1306 A: Consistency + SpecByteLen<T = A::Val> + SpecSerializer<SVal = A::Val>,
1307 B: Consistency<Val = A::Val> + SpecByteLen<T = A::Val> + SpecSerializer<SVal = A::Val>,
1308
1309 requires
1310 serializer_congruent(a, b),
1311 ensures
1312 Star(a).spec_serialize(vs) == Star(b).spec_serialize(vs),
1313 decreases vs.len(),
1314{
1315 reveal(serializer_congruent);
1316 reveal(<Star::<_> as SpecSerializer>::spec_serialize);
1317 if vs.len() > 0 {
1318 lemma_star_serialize_congruence_rec(a, b, vs.drop_last());
1319 }
1320}
1321
1322pub broadcast proof fn lemma_star_prepare_congruence<A, B>(a: Star<A>, b: Star<B>) where
1323 A: Consistency + SpecByteLen<T = A::Val>,
1324 B: Consistency<Val = A::Val> + SpecByteLen<T = A::Val>,
1325
1326 requires
1327 prepare_congruent(a.0, b.0),
1328 ensures
1329 #[trigger] prepare_congruent(a, b),
1330{
1331 reveal(prepare_congruent);
1332 reveal(<Star::<_> as Consistency>::consistent);
1333 assert forall|vs: Seq<A::Val>| #[trigger] a.byte_len(vs) == b.byte_len(vs) by {
1334 lemma_star_byte_len_congruence_rec(a.0, b.0, vs);
1335 }
1336}
1337
1338pub broadcast proof fn lemma_star_serializer_congruence<A, B>(a: Star<A>, b: Star<B>) where
1339 A: Consistency + SpecByteLen<T = A::Val> + SpecSerializer<SVal = A::Val>,
1340 B: Consistency<Val = A::Val> + SpecByteLen<T = A::Val> + SpecSerializer<SVal = A::Val>,
1341
1342 requires
1343 serializer_congruent(a.0, b.0),
1344 ensures
1345 #[trigger] serializer_congruent(a, b),
1346{
1347 reveal(serializer_congruent);
1348 lemma_star_prepare_congruence(a, b);
1349 assert forall|vs: Seq<A::Val>| #[trigger] a.spec_serialize(vs) == b.spec_serialize(vs) by {
1350 lemma_star_serialize_congruence_rec(a.0, b.0, vs);
1351 }
1352}
1353
1354pub broadcast proof fn lemma_pair_prepare_congruence<A1, A2, B1, B2>(
1355 a: Pair<A1, B1>,
1356 b: Pair<A2, B2>,
1357) where
1358 A1: Consistency + SpecByteLen<T = A1::Val>,
1359 A2: Consistency<Val = A1::Val> + SpecByteLen<T = A1::Val>,
1360 B1: Consistency + SpecByteLen<T = B1::Val>,
1361 B2: Consistency<Val = B1::Val> + SpecByteLen<T = B1::Val>,
1362
1363 requires
1364 prepare_congruent(a.0, b.0),
1365 prepare_congruent(a.1, b.1),
1366 ensures
1367 #[trigger] prepare_congruent(a, b),
1368{
1369 reveal(prepare_congruent);
1370}
1371
1372pub broadcast proof fn lemma_pair_serializer_congruence<A1, A2, B1, B2>(
1373 a: Pair<A1, B1>,
1374 b: Pair<A2, B2>,
1375) where
1376 A1: Consistency + SpecByteLen<T = A1::Val> + SpecSerializer<SVal = A1::Val>,
1377 A2: Consistency<Val = A1::Val> + SpecByteLen<T = A1::Val> + SpecSerializer<SVal = A1::Val>,
1378 B1: Consistency + SpecByteLen<T = B1::Val> + SpecSerializer<SVal = B1::Val>,
1379 B2: Consistency<Val = B1::Val> + SpecByteLen<T = B1::Val> + SpecSerializer<SVal = B1::Val>,
1380
1381 requires
1382 serializer_congruent(a.0, b.0),
1383 serializer_congruent(a.1, b.1),
1384 ensures
1385 #[trigger] serializer_congruent(a, b),
1386{
1387 reveal(serializer_congruent);
1388 lemma_pair_prepare_congruence(a, b);
1389}
1390
1391pub broadcast proof fn lemma_choice_prepare_congruence<A1, A2, B1, B2>(
1392 a: Choice<A1, B1>,
1393 b: Choice<A2, B2>,
1394) where
1395 A1: Consistency + SpecByteLen<T = A1::Val>,
1396 A2: Consistency<Val = A1::Val> + SpecByteLen<T = A1::Val>,
1397 B1: Consistency + SpecByteLen<T = B1::Val>,
1398 B2: Consistency<Val = B1::Val> + SpecByteLen<T = B1::Val>,
1399
1400 requires
1401 prepare_congruent(a.0, b.0),
1402 prepare_congruent(a.1, b.1),
1403 ensures
1404 #[trigger] prepare_congruent(a, b),
1405{
1406 reveal(prepare_congruent);
1407}
1408
1409pub broadcast proof fn lemma_choice_serializer_congruence<A1, A2, B1, B2>(
1410 a: Choice<A1, B1>,
1411 b: Choice<A2, B2>,
1412) where
1413 A1: Consistency + SpecByteLen<T = A1::Val> + SpecSerializer<SVal = A1::Val>,
1414 A2: Consistency<Val = A1::Val> + SpecByteLen<T = A1::Val> + SpecSerializer<SVal = A1::Val>,
1415 B1: Consistency + SpecByteLen<T = B1::Val> + SpecSerializer<SVal = B1::Val>,
1416 B2: Consistency<Val = B1::Val> + SpecByteLen<T = B1::Val> + SpecSerializer<SVal = B1::Val>,
1417
1418 requires
1419 serializer_congruent(a.0, b.0),
1420 serializer_congruent(a.1, b.1),
1421 ensures
1422 #[trigger] serializer_congruent(a, b),
1423{
1424 reveal(serializer_congruent);
1425 lemma_choice_prepare_congruence(a, b);
1426}
1427
1428pub broadcast proof fn lemma_optional_prepare_congruence<A1, A2, B1, B2>(
1429 a: Optional<A1, B1>,
1430 b: Optional<A2, B2>,
1431) where
1432 A1: Consistency + SpecByteLen<T = A1::Val>,
1433 A2: Consistency<Val = A1::Val> + SpecByteLen<T = A1::Val>,
1434 B1: Consistency + SpecByteLen<T = B1::Val>,
1435 B2: Consistency<Val = B1::Val> + SpecByteLen<T = B1::Val>,
1436
1437 requires
1438 prepare_congruent(a.0, b.0),
1439 prepare_congruent(a.1, b.1),
1440 ensures
1441 #[trigger] prepare_congruent(a, b),
1442{
1443 reveal(prepare_congruent);
1444 lemma_opt_prepare_congruence(Opt(a.0), Opt(b.0));
1445 lemma_pair_prepare_congruence(Pair(Opt(a.0), a.1), Pair(Opt(b.0), b.1));
1446}
1447
1448pub broadcast proof fn lemma_optional_serializer_congruence<A1, A2, B1, B2>(
1449 a: Optional<A1, B1>,
1450 b: Optional<A2, B2>,
1451) where
1452 A1: Consistency + SpecByteLen<T = A1::Val> + SpecSerializer<SVal = A1::Val>,
1453 A2: Consistency<Val = A1::Val> + SpecByteLen<T = A1::Val> + SpecSerializer<SVal = A1::Val>,
1454 B1: Consistency + SpecByteLen<T = B1::Val> + SpecSerializer<SVal = B1::Val>,
1455 B2: Consistency<Val = B1::Val> + SpecByteLen<T = B1::Val> + SpecSerializer<SVal = B1::Val>,
1456
1457 requires
1458 serializer_congruent(a.0, b.0),
1459 serializer_congruent(a.1, b.1),
1460 ensures
1461 #[trigger] serializer_congruent(a, b),
1462{
1463 reveal(serializer_congruent);
1464 lemma_optional_prepare_congruence(a, b);
1465}
1466
1467pub broadcast proof fn lemma_repeat_prepare_congruence<A1, A2, B1, B2>(
1468 a: Repeat<A1, B1>,
1469 b: Repeat<A2, B2>,
1470) where
1471 A1: Consistency + SpecByteLen<T = A1::Val>,
1472 A2: Consistency<Val = A1::Val> + SpecByteLen<T = A1::Val>,
1473 B1: Consistency + SpecByteLen<T = B1::Val>,
1474 B2: Consistency<Val = B1::Val> + SpecByteLen<T = B1::Val>,
1475
1476 requires
1477 prepare_congruent(a.0, b.0),
1478 prepare_congruent(a.1, b.1),
1479 ensures
1480 #[trigger] prepare_congruent(a, b),
1481{
1482 reveal(prepare_congruent);
1483 lemma_star_prepare_congruence(Star(a.0), Star(b.0));
1484 lemma_pair_prepare_congruence(Pair(Star(a.0), a.1), Pair(Star(b.0), b.1));
1485}
1486
1487pub broadcast proof fn lemma_repeat_serializer_congruence<A1, A2, B1, B2>(
1488 a: Repeat<A1, B1>,
1489 b: Repeat<A2, B2>,
1490) where
1491 A1: Consistency + SpecByteLen<T = A1::Val> + SpecSerializer<SVal = A1::Val>,
1492 A2: Consistency<Val = A1::Val> + SpecByteLen<T = A1::Val> + SpecSerializer<SVal = A1::Val>,
1493 B1: Consistency + SpecByteLen<T = B1::Val> + SpecSerializer<SVal = B1::Val>,
1494 B2: Consistency<Val = B1::Val> + SpecByteLen<T = B1::Val> + SpecSerializer<SVal = B1::Val>,
1495
1496 requires
1497 serializer_congruent(a.0, b.0),
1498 serializer_congruent(a.1, b.1),
1499 ensures
1500 #[trigger] serializer_congruent(a, b),
1501{
1502 reveal(serializer_congruent);
1503 lemma_repeat_prepare_congruence(a, b);
1504 lemma_star_serializer_congruence(Star(a.0), Star(b.0));
1505}
1506
1507pub broadcast proof fn lemma_repeat_n_prepare_congruence<A, B, N1, N2>(
1508 a: RepeatN<A, N1>,
1509 b: RepeatN<B, N2>,
1510) where
1511 A: Consistency + SpecByteLen<T = A::Val>,
1512 B: Consistency<Val = A::Val> + SpecByteLen<T = A::Val>,
1513 N1: AsLen,
1514 N2: AsLen,
1515
1516 requires
1517 prepare_congruent(a.1, b.1),
1518 a.0.as_nat() == b.0.as_nat(),
1519 ensures
1520 #[trigger] prepare_congruent(a, b),
1521{
1522 reveal(prepare_congruent);
1523 lemma_star_prepare_congruence(Star(a.1), Star(b.1));
1524}
1525
1526pub broadcast proof fn lemma_repeat_n_serializer_congruence<A, B, N1, N2>(
1527 a: RepeatN<A, N1>,
1528 b: RepeatN<B, N2>,
1529) where
1530 A: Consistency + SpecByteLen<T = A::Val> + SpecSerializer<SVal = A::Val>,
1531 B: Consistency<Val = A::Val> + SpecByteLen<T = A::Val> + SpecSerializer<SVal = A::Val>,
1532 N1: AsLen,
1533 N2: AsLen,
1534
1535 requires
1536 serializer_congruent(a.1, b.1),
1537 a.0.as_nat() == b.0.as_nat(),
1538 ensures
1539 #[trigger] serializer_congruent(a, b),
1540{
1541 reveal(serializer_congruent);
1542 reveal(<Star::<_> as SpecSerializer>::spec_serialize);
1543 broadcast use lemma_serializer_congruent_serialize;
1544
1545 lemma_repeat_n_prepare_congruence(a, b);
1546 lemma_star_serializer_congruence(Star(a.1), Star(b.1));
1547 assert forall|vs: Seq<A::Val>| #[trigger] a.spec_serialize(vs) == b.spec_serialize(vs) by {
1548 lemma_star_serialize_congruence_rec(a.1, b.1, vs);
1549 }
1550}
1551
1552pub broadcast proof fn lemma_array_prepare_congruence<A, B, const N: usize>(
1553 a: Array<N, A>,
1554 b: Array<N, B>,
1555) where
1556 A: Consistency + SpecByteLen<T = A::Val>,
1557 B: Consistency<Val = A::Val> + SpecByteLen<T = A::Val>,
1558
1559 requires
1560 prepare_congruent(a.0, b.0),
1561 ensures
1562 #[trigger] prepare_congruent(a, b),
1563{
1564 reveal(prepare_congruent);
1565 lemma_repeat_n_prepare_congruence(RepeatN(N, a.0), RepeatN(N, b.0));
1566}
1567
1568pub broadcast proof fn lemma_array_serializer_congruence<A, B, const N: usize>(
1569 a: Array<N, A>,
1570 b: Array<N, B>,
1571) where
1572 A: Consistency + SpecByteLen<T = A::Val> + SpecSerializer<SVal = A::Val>,
1573 B: Consistency<Val = A::Val> + SpecByteLen<T = A::Val> + SpecSerializer<SVal = A::Val>,
1574
1575 requires
1576 serializer_congruent(a.0, b.0),
1577 ensures
1578 #[trigger] serializer_congruent(a, b),
1579{
1580 reveal(serializer_congruent);
1581 lemma_array_prepare_congruence(a, b);
1582 lemma_repeat_n_serializer_congruence(RepeatN(N, a.0), RepeatN(N, b.0));
1583}
1584
1585pub broadcast proof fn lemma_optional_end_prepare_congruence<A, B>(
1586 a: OptionalEnd<A>,
1587 b: OptionalEnd<B>,
1588) where
1589 A: Consistency + SpecByteLen<T = A::Val>,
1590 B: Consistency<Val = A::Val> + SpecByteLen<T = A::Val>,
1591
1592 requires
1593 prepare_congruent(a.0, b.0),
1594 ensures
1595 #[trigger] prepare_congruent(a, b),
1596{
1597 reveal(prepare_congruent);
1598 lemma_prepare_congruent_reflexive(Eof);
1599 lemma_optional_prepare_congruence(Optional(a.0, Eof), Optional(b.0, Eof));
1600}
1601
1602pub broadcast proof fn lemma_optional_end_serializer_congruence<A, B>(
1603 a: OptionalEnd<A>,
1604 b: OptionalEnd<B>,
1605) where
1606 A: Consistency + SpecByteLen<T = A::Val> + SpecSerializer<SVal = A::Val>,
1607 B: Consistency<Val = A::Val> + SpecByteLen<T = A::Val> + SpecSerializer<SVal = A::Val>,
1608
1609 requires
1610 serializer_congruent(a.0, b.0),
1611 ensures
1612 #[trigger] serializer_congruent(a, b),
1613{
1614 reveal(serializer_congruent);
1615 lemma_optional_end_prepare_congruence(a, b);
1616 lemma_serializer_congruent_reflexive(Eof);
1617 lemma_optional_serializer_congruence(Optional(a.0, Eof), Optional(b.0, Eof));
1618}
1619
1620pub broadcast proof fn lemma_repeat_till_end_prepare_congruence<A, B>(
1621 a: RepeatTillEnd<A>,
1622 b: RepeatTillEnd<B>,
1623) where
1624 A: Consistency + SpecByteLen<T = A::Val>,
1625 B: Consistency<Val = A::Val> + SpecByteLen<T = A::Val>,
1626
1627 requires
1628 prepare_congruent(a.0, b.0),
1629 ensures
1630 #[trigger] prepare_congruent(a, b),
1631{
1632 reveal(prepare_congruent);
1633 lemma_prepare_congruent_reflexive(Eof);
1634 lemma_repeat_prepare_congruence(Repeat(a.0, Eof), Repeat(b.0, Eof));
1635}
1636
1637pub broadcast proof fn lemma_repeat_till_end_serializer_congruence<A, B>(
1638 a: RepeatTillEnd<A>,
1639 b: RepeatTillEnd<B>,
1640) where
1641 A: Consistency + SpecByteLen<T = A::Val> + SpecSerializer<SVal = A::Val>,
1642 B: Consistency<Val = A::Val> + SpecByteLen<T = A::Val> + SpecSerializer<SVal = A::Val>,
1643
1644 requires
1645 serializer_congruent(a.0, b.0),
1646 ensures
1647 #[trigger] serializer_congruent(a, b),
1648{
1649 reveal(serializer_congruent);
1650 lemma_repeat_till_end_prepare_congruence(a, b);
1651 lemma_serializer_congruent_reflexive(Eof);
1652 lemma_repeat_serializer_congruence(Repeat(a.0, Eof), Repeat(b.0, Eof));
1653}
1654
1655pub broadcast proof fn lemma_preceded_prepare_congruence<A1, A2, B1, B2, const CHECK: bool>(
1656 a: Preceded<A1, A1::Val, B1, CHECK>,
1657 b: Preceded<A2, A1::Val, B2, CHECK>,
1658) where
1659 A1: Consistency + SpecByteLen<T = A1::Val>,
1660 A2: Consistency<Val = A1::Val> + SpecByteLen<T = A1::Val>,
1661 B1: Consistency + SpecByteLen<T = B1::Val>,
1662 B2: Consistency<Val = B1::Val> + SpecByteLen<T = B1::Val>,
1663
1664 requires
1665 prepare_congruent(a.a, b.a),
1666 prepare_congruent(a.b, b.b),
1667 a.a_val == b.a_val,
1668 ensures
1669 #[trigger] prepare_congruent(a, b),
1670{
1671 reveal(prepare_congruent);
1672}
1673
1674pub broadcast proof fn lemma_preceded_serializer_congruence<A1, A2, B1, B2, const CHECK: bool>(
1675 a: Preceded<A1, A1::Val, B1, CHECK>,
1676 b: Preceded<A2, A1::Val, B2, CHECK>,
1677) where
1678 A1: Consistency + SpecByteLen<T = A1::Val> + SpecSerializer<SVal = A1::Val>,
1679 A2: Consistency<Val = A1::Val> + SpecByteLen<T = A1::Val> + SpecSerializer<SVal = A1::Val>,
1680 B1: Consistency + SpecByteLen<T = B1::Val> + SpecSerializer<SVal = B1::Val>,
1681 B2: Consistency<Val = B1::Val> + SpecByteLen<T = B1::Val> + SpecSerializer<SVal = B1::Val>,
1682
1683 requires
1684 serializer_congruent(a.a, b.a),
1685 serializer_congruent(a.b, b.b),
1686 a.a_val == b.a_val,
1687 ensures
1688 #[trigger] serializer_congruent(a, b),
1689{
1690 reveal(serializer_congruent);
1691 lemma_preceded_prepare_congruence(a, b);
1692}
1693
1694pub broadcast proof fn lemma_terminated_prepare_congruence<A1, A2, B1, B2, const CHECK: bool>(
1695 a: Terminated<A1, B1, B1::Val, CHECK>,
1696 b: Terminated<A2, B2, B1::Val, CHECK>,
1697) where
1698 A1: Consistency + SpecByteLen<T = A1::Val>,
1699 A2: Consistency<Val = A1::Val> + SpecByteLen<T = A1::Val>,
1700 B1: Consistency + SpecByteLen<T = B1::Val>,
1701 B2: Consistency<Val = B1::Val> + SpecByteLen<T = B1::Val>,
1702
1703 requires
1704 prepare_congruent(a.a, b.a),
1705 prepare_congruent(a.b, b.b),
1706 a.b_val == b.b_val,
1707 ensures
1708 #[trigger] prepare_congruent(a, b),
1709{
1710 reveal(prepare_congruent);
1711}
1712
1713pub broadcast proof fn lemma_terminated_serializer_congruence<A1, A2, B1, B2, const CHECK: bool>(
1714 a: Terminated<A1, B1, B1::Val, CHECK>,
1715 b: Terminated<A2, B2, B1::Val, CHECK>,
1716) where
1717 A1: Consistency + SpecByteLen<T = A1::Val> + SpecSerializer<SVal = A1::Val>,
1718 A2: Consistency<Val = A1::Val> + SpecByteLen<T = A1::Val> + SpecSerializer<SVal = A1::Val>,
1719 B1: Consistency + SpecByteLen<T = B1::Val> + SpecSerializer<SVal = B1::Val>,
1720 B2: Consistency<Val = B1::Val> + SpecByteLen<T = B1::Val> + SpecSerializer<SVal = B1::Val>,
1721
1722 requires
1723 serializer_congruent(a.a, b.a),
1724 serializer_congruent(a.b, b.b),
1725 a.b_val == b.b_val,
1726 ensures
1727 #[trigger] serializer_congruent(a, b),
1728{
1729 reveal(serializer_congruent);
1730 lemma_terminated_prepare_congruence(a, b);
1731}
1732
1733pub broadcast proof fn lemma_and_then_prepare_congruence<A1, A2, B1, B2>(
1734 a: AndThen<A1, B1>,
1735 b: AndThen<A2, B2>,
1736) where
1737 A1: BytesCombinator + Consistency<Val = Seq<u8>>,
1738 A2: BytesCombinator + Consistency<Val = Seq<u8>>,
1739 B1: Consistency + SpecByteLen<T = B1::Val>,
1740 B2: Consistency<Val = B1::Val> + SpecByteLen<T = B1::Val>,
1741
1742 requires
1743 prepare_congruent(a.0, b.0),
1744 prepare_congruent(a.1, b.1),
1745 ensures
1746 #[trigger] prepare_congruent(a, b),
1747{
1748 reveal(prepare_congruent);
1749}
1750
1751pub broadcast proof fn lemma_and_then_serializer_congruence<A1, A2, B1, B2>(
1752 a: AndThen<A1, B1>,
1753 b: AndThen<A2, B2>,
1754) where
1755 A1: BytesCombinator + Consistency<Val = Seq<u8>> + SpecSerializer<SVal = Seq<u8>>,
1756 A2: BytesCombinator + Consistency<Val = Seq<u8>> + SpecSerializer<SVal = Seq<u8>>,
1757 B1: Consistency + SpecByteLen<T = B1::Val> + SpecSerializer<SVal = B1::Val>,
1758 B2: Consistency<Val = B1::Val> + SpecByteLen<T = B1::Val> + SpecSerializer<SVal = B1::Val>,
1759
1760 requires
1761 serializer_congruent(a.0, b.0),
1762 serializer_congruent(a.1, b.1),
1763 ensures
1764 #[trigger] serializer_congruent(a, b),
1765{
1766 reveal(serializer_congruent);
1767 lemma_and_then_prepare_congruence(a, b);
1768}
1769
1770pub broadcast proof fn lemma_alt_prepare_congruence<A1, A2, B1, B2, const NONDETERMINISTIC: bool>(
1771 a: Alt<A1, B1, NONDETERMINISTIC>,
1772 b: Alt<A2, B2, NONDETERMINISTIC>,
1773) where
1774 A1: Consistency + SpecByteLen<T = A1::Val>,
1775 A2: Consistency<Val = A1::Val> + SpecByteLen<T = A1::Val>,
1776 B1: Consistency<Val = A1::Val> + SpecByteLen<T = A1::Val>,
1777 B2: Consistency<Val = A1::Val> + SpecByteLen<T = A1::Val>,
1778
1779 requires
1780 prepare_congruent(a.0, b.0),
1781 prepare_congruent(a.1, b.1),
1782 ensures
1783 #[trigger] prepare_congruent(a, b),
1784{
1785 reveal(prepare_congruent);
1786}
1787
1788pub broadcast proof fn lemma_alt_serializer_congruence<
1789 A1,
1790 A2,
1791 B1,
1792 B2,
1793 const NONDETERMINISTIC: bool,
1794>(a: Alt<A1, B1, NONDETERMINISTIC>, b: Alt<A2, B2, NONDETERMINISTIC>) where
1795 A1: Consistency + SpecByteLen<T = A1::Val> + SpecSerializer<SVal = A1::Val>,
1796 A2: Consistency<Val = A1::Val> + SpecByteLen<T = A1::Val> + SpecSerializer<SVal = A1::Val>,
1797 B1: Consistency<Val = A1::Val> + SpecByteLen<T = A1::Val> + SpecSerializer<SVal = A1::Val>,
1798 B2: Consistency<Val = A1::Val> + SpecByteLen<T = A1::Val> + SpecSerializer<SVal = A1::Val>,
1799
1800 requires
1801 serializer_congruent(a.0, b.0),
1802 serializer_congruent(a.1, b.1),
1803 ensures
1804 #[trigger] serializer_congruent(a, b),
1805{
1806 reveal(serializer_congruent);
1807 broadcast use lemma_serializer_congruent_prepare;
1808 broadcast use lemma_prepare_congruent_consistent;
1809 broadcast use lemma_serializer_congruent_serialize;
1810
1811 lemma_alt_prepare_congruence(a, b);
1812}
1813
1814pub broadcast proof fn lemma_mapped_prepare_congruence<A, B, M1, M2>(
1815 a: Mapped<A, M1>,
1816 b: Mapped<B, M2>,
1817) where
1818 A: Consistency + SpecByteLen<T = A::Val>,
1819 B: Consistency<Val = A::Val> + SpecByteLen<T = A::Val>,
1820 M1: crate::combinators::mapped::spec::SpecMapper<In = A::Val>,
1821 M2: crate::combinators::mapped::spec::SpecMapper<In = A::Val, Out = M1::Out>,
1822
1823 requires
1824 prepare_congruent(a.inner, b.inner),
1825 forall|v: M1::Out| #[trigger] a.mapper.spec_map_rev(v) == b.mapper.spec_map_rev(v),
1826 forall|v: M1::Out| #[trigger] a.mapper.wf_out(v) <==> b.mapper.wf_out(v),
1827 ensures
1828 #[trigger] prepare_congruent(a, b),
1829{
1830 reveal(prepare_congruent);
1831}
1832
1833pub broadcast proof fn lemma_mapped_serializer_congruence<A, B, M1, M2>(
1834 a: Mapped<A, M1>,
1835 b: Mapped<B, M2>,
1836) where
1837 A: Consistency + SpecByteLen<T = A::Val> + SpecSerializer<SVal = A::Val>,
1838 B: Consistency<Val = A::Val> + SpecByteLen<T = A::Val> + SpecSerializer<SVal = A::Val>,
1839 M1: crate::combinators::mapped::spec::SpecMapper<In = A::Val>,
1840 M2: crate::combinators::mapped::spec::SpecMapper<In = A::Val, Out = M1::Out>,
1841
1842 requires
1843 serializer_congruent(a.inner, b.inner),
1844 forall|v: M1::Out| #[trigger] a.mapper.spec_map_rev(v) == b.mapper.spec_map_rev(v),
1845 forall|v: M1::Out| #[trigger] a.mapper.wf_out(v) <==> b.mapper.wf_out(v),
1846 ensures
1847 #[trigger] serializer_congruent(a, b),
1848{
1849 reveal(serializer_congruent);
1850 lemma_mapped_prepare_congruence(a, b);
1851}
1852
1853pub broadcast proof fn lemma_bind_prepare_congruence<A1, A2, B1, B2>(
1857 a: Bind<A1, B1>,
1858 b: Bind<A2, B2>,
1859) where
1860 A1: Consistency + SpecByteLen<T = A1::Val>,
1861 A2: Consistency<Val = A1::Val> + SpecByteLen<T = A1::Val>,
1862 B1: SpecMap<Input = A1::Val>,
1863 B2: SpecMap<Input = A1::Val>,
1864 B1::Output: Consistency + SpecByteLen<T = <B1::Output as Consistency>::Val>,
1865 B2::Output: Consistency<Val = <B1::Output as Consistency>::Val> + SpecByteLen<
1866 T = <B1::Output as Consistency>::Val,
1867 >,
1868
1869 requires
1870 prepare_congruent(a.0, b.0),
1871 forall|key: A1::Val| #[trigger] prepare_congruent(a.1.spec_map(key), b.1.spec_map(key)),
1872 ensures
1873 #[trigger] prepare_congruent(a, b),
1874{
1875 reveal(prepare_congruent);
1876 broadcast use lemma_prepare_congruent_consistent;
1877 broadcast use lemma_prepare_congruent_byte_len;
1878
1879}
1880
1881pub broadcast proof fn lemma_bind_serializer_congruence<A1, A2, B1, B2>(
1882 a: Bind<A1, B1>,
1883 b: Bind<A2, B2>,
1884) where
1885 A1: Consistency + SpecByteLen<T = A1::Val> + SpecSerializer<SVal = A1::Val>,
1886 A2: Consistency<Val = A1::Val> + SpecByteLen<T = A1::Val> + SpecSerializer<SVal = A1::Val>,
1887 B1: SpecMap<Input = A1::Val>,
1888 B2: SpecMap<Input = A1::Val>,
1889 B1::Output: Consistency + SpecByteLen<T = <B1::Output as Consistency>::Val> + SpecSerializer<
1890 SVal = <B1::Output as Consistency>::Val,
1891 >,
1892 B2::Output: Consistency<Val = <B1::Output as Consistency>::Val> + SpecByteLen<
1893 T = <B1::Output as Consistency>::Val,
1894 > + SpecSerializer<SVal = <B1::Output as Consistency>::Val>,
1895
1896 requires
1897 serializer_congruent(a.0, b.0),
1898 forall|key: A1::Val| #[trigger] serializer_congruent(a.1.spec_map(key), b.1.spec_map(key)),
1899 ensures
1900 #[trigger] serializer_congruent(a, b),
1901{
1902 reveal(serializer_congruent);
1903 broadcast use lemma_serializer_congruent_prepare;
1904 broadcast use lemma_serializer_congruent_serialize;
1905
1906 lemma_bind_prepare_congruence(a, b);
1907}
1908
1909pub broadcast proof fn lemma_sum_prepare_congruence<A1, A2, B1, B2>(
1910 a: Sum<A1, B1>,
1911 b: Sum<A2, B2>,
1912) where
1913 A1: Consistency + SpecByteLen<T = A1::Val>,
1914 A2: Consistency<Val = A1::Val> + SpecByteLen<T = A1::Val>,
1915 B1: Consistency + SpecByteLen<T = B1::Val>,
1916 B2: Consistency<Val = B1::Val> + SpecByteLen<T = B1::Val>,
1917
1918 requires
1919 match (a, b) {
1920 (Sum::Inl(a), Sum::Inl(b)) => prepare_congruent(a, b),
1921 (Sum::Inr(a), Sum::Inr(b)) => prepare_congruent(a, b),
1922 _ => false,
1923 },
1924 ensures
1925 #[trigger] prepare_congruent(a, b),
1926{
1927 reveal(prepare_congruent);
1928 broadcast use lemma_prepare_congruent_consistent;
1929 broadcast use lemma_prepare_congruent_byte_len;
1930
1931}
1932
1933pub broadcast proof fn lemma_sum_serializer_congruence<A1, A2, B1, B2>(
1934 a: Sum<A1, B1>,
1935 b: Sum<A2, B2>,
1936) where
1937 A1: Consistency + SpecByteLen<T = A1::Val> + SpecSerializer<SVal = A1::Val>,
1938 A2: Consistency<Val = A1::Val> + SpecByteLen<T = A1::Val> + SpecSerializer<SVal = A1::Val>,
1939 B1: Consistency + SpecByteLen<T = B1::Val> + SpecSerializer<SVal = B1::Val>,
1940 B2: Consistency<Val = B1::Val> + SpecByteLen<T = B1::Val> + SpecSerializer<SVal = B1::Val>,
1941
1942 requires
1943 match (a, b) {
1944 (Sum::Inl(a), Sum::Inl(b)) => serializer_congruent(a, b),
1945 (Sum::Inr(a), Sum::Inr(b)) => serializer_congruent(a, b),
1946 _ => false,
1947 },
1948 ensures
1949 #[trigger] serializer_congruent(a, b),
1950{
1951 reveal(serializer_congruent);
1952 broadcast use lemma_serializer_congruent_prepare;
1953 broadcast use lemma_serializer_congruent_serialize;
1954
1955 lemma_sum_prepare_congruence(a, b);
1956}
1957
1958pub broadcast proof fn lemma_prefix_tagged_parser_congruence<Tg1, Tg2, Of1, Of2>(
1962 a: PrefixTagged<Tg1, Tg1::T, Of1>,
1963 b: PrefixTagged<Tg2, Tg1::T, Of2>,
1964) where
1965 Tg1: SpecByteLen + SpecParser<PVal = Tg1::T>,
1966 Tg2: SpecByteLen<T = Tg1::T> + SpecParser<PVal = Tg1::T>,
1967 Of1: SpecParser,
1968 Of2: SpecParser<PVal = Of1::PVal>,
1969
1970 requires
1971 parser_congruent(a.0, b.0),
1972 parser_congruent(a.2, b.2),
1973 a.1 == b.1,
1974 ensures
1975 #[trigger] parser_congruent(a, b),
1976{
1977 reveal(parser_congruent);
1978 lemma_const_parser_congruence(Const(a.0, a.1), Const(b.0, b.1));
1979 lemma_preceded_parser_congruence(
1980 Preceded::<_, _, _, false> { a: Const(a.0, a.1), b: a.2, a_val: a.1 },
1981 Preceded::<_, _, _, false> { a: Const(b.0, b.1), b: b.2, a_val: b.1 },
1982 );
1983}
1984
1985pub broadcast proof fn lemma_suffix_tagged_parser_congruence<Tg1, Tg2, Of1, Of2>(
1986 a: SuffixTagged<Of1, Tg1, Tg1::T>,
1987 b: SuffixTagged<Of2, Tg2, Tg1::T>,
1988) where
1989 Tg1: SpecByteLen + SpecParser<PVal = Tg1::T>,
1990 Tg2: SpecByteLen<T = Tg1::T> + SpecParser<PVal = Tg1::T>,
1991 Of1: SpecParser,
1992 Of2: SpecParser<PVal = Of1::PVal>,
1993
1994 requires
1995 parser_congruent(a.0, b.0),
1996 parser_congruent(a.1, b.1),
1997 a.2 == b.2,
1998 ensures
1999 #[trigger] parser_congruent(a, b),
2000{
2001 reveal(parser_congruent);
2002 lemma_const_parser_congruence(Const(a.1, a.2), Const(b.1, b.2));
2003 lemma_terminated_parser_congruence(
2004 Terminated::<_, _, _, false> { a: a.0, b: Const(a.1, a.2), b_val: a.2 },
2005 Terminated::<_, _, _, false> { a: b.0, b: Const(b.1, b.2), b_val: b.2 },
2006 );
2007}
2008
2009pub broadcast proof fn lemma_prefix_tagged_prepare_congruence<Tg1, Tg2, Of1, Of2>(
2010 a: PrefixTagged<Tg1, Tg1::Val, Of1>,
2011 b: PrefixTagged<Tg2, Tg1::Val, Of2>,
2012) where
2013 Tg1: Consistency + SpecByteLen<T = Tg1::Val>,
2014 Tg2: Consistency<Val = Tg1::Val> + SpecByteLen<T = Tg1::Val>,
2015 Of1: Consistency + SpecByteLen<T = Of1::Val>,
2016 Of2: Consistency<Val = Of1::Val> + SpecByteLen<T = Of1::Val>,
2017
2018 requires
2019 prepare_congruent(a.0, b.0),
2020 prepare_congruent(a.2, b.2),
2021 a.1 == b.1,
2022 ensures
2023 #[trigger] prepare_congruent(a, b),
2024{
2025 reveal(prepare_congruent);
2026 lemma_const_prepare_congruence(Const(a.0, a.1), Const(b.0, b.1));
2027 lemma_preceded_prepare_congruence(
2028 Preceded::<_, _, _, false> { a: Const(a.0, a.1), b: a.2, a_val: a.1 },
2029 Preceded::<_, _, _, false> { a: Const(b.0, b.1), b: b.2, a_val: b.1 },
2030 );
2031}
2032
2033pub broadcast proof fn lemma_prefix_tagged_serializer_congruence<Tg1, Tg2, Of1, Of2>(
2034 a: PrefixTagged<Tg1, Tg1::Val, Of1>,
2035 b: PrefixTagged<Tg2, Tg1::Val, Of2>,
2036) where
2037 Tg1: Consistency + SpecByteLen<T = Tg1::Val> + SpecSerializer<SVal = Tg1::Val>,
2038 Tg2: Consistency<Val = Tg1::Val> + SpecByteLen<T = Tg1::Val> + SpecSerializer<SVal = Tg1::Val>,
2039 Of1: Consistency + SpecByteLen<T = Of1::Val> + SpecSerializer<SVal = Of1::Val>,
2040 Of2: Consistency<Val = Of1::Val> + SpecByteLen<T = Of1::Val> + SpecSerializer<SVal = Of1::Val>,
2041
2042 requires
2043 serializer_congruent(a.0, b.0),
2044 serializer_congruent(a.2, b.2),
2045 a.1 == b.1,
2046 ensures
2047 #[trigger] serializer_congruent(a, b),
2048{
2049 reveal(serializer_congruent);
2050 lemma_const_serializer_congruence(Const(a.0, a.1), Const(b.0, b.1));
2051 lemma_preceded_serializer_congruence(
2052 Preceded::<_, _, _, false> { a: Const(a.0, a.1), b: a.2, a_val: a.1 },
2053 Preceded::<_, _, _, false> { a: Const(b.0, b.1), b: b.2, a_val: b.1 },
2054 );
2055 lemma_prefix_tagged_prepare_congruence(a, b);
2056}
2057
2058pub broadcast proof fn lemma_suffix_tagged_prepare_congruence<Tg1, Tg2, Of1, Of2>(
2059 a: SuffixTagged<Of1, Tg1, Tg1::Val>,
2060 b: SuffixTagged<Of2, Tg2, Tg1::Val>,
2061) where
2062 Tg1: Consistency + SpecByteLen<T = Tg1::Val>,
2063 Tg2: Consistency<Val = Tg1::Val> + SpecByteLen<T = Tg1::Val>,
2064 Of1: Consistency + SpecByteLen<T = Of1::Val>,
2065 Of2: Consistency<Val = Of1::Val> + SpecByteLen<T = Of1::Val>,
2066
2067 requires
2068 prepare_congruent(a.0, b.0),
2069 prepare_congruent(a.1, b.1),
2070 a.2 == b.2,
2071 ensures
2072 #[trigger] prepare_congruent(a, b),
2073{
2074 reveal(prepare_congruent);
2075 lemma_const_prepare_congruence(Const(a.1, a.2), Const(b.1, b.2));
2076 lemma_terminated_prepare_congruence(
2077 Terminated::<_, _, _, false> { a: a.0, b: Const(a.1, a.2), b_val: a.2 },
2078 Terminated::<_, _, _, false> { a: b.0, b: Const(b.1, b.2), b_val: b.2 },
2079 );
2080}
2081
2082pub broadcast proof fn lemma_suffix_tagged_serializer_congruence<Tg1, Tg2, Of1, Of2>(
2083 a: SuffixTagged<Of1, Tg1, Tg1::Val>,
2084 b: SuffixTagged<Of2, Tg2, Tg1::Val>,
2085) where
2086 Tg1: Consistency + SpecByteLen<T = Tg1::Val> + SpecSerializer<SVal = Tg1::Val>,
2087 Tg2: Consistency<Val = Tg1::Val> + SpecByteLen<T = Tg1::Val> + SpecSerializer<SVal = Tg1::Val>,
2088 Of1: Consistency + SpecByteLen<T = Of1::Val> + SpecSerializer<SVal = Of1::Val>,
2089 Of2: Consistency<Val = Of1::Val> + SpecByteLen<T = Of1::Val> + SpecSerializer<SVal = Of1::Val>,
2090
2091 requires
2092 serializer_congruent(a.0, b.0),
2093 serializer_congruent(a.1, b.1),
2094 a.2 == b.2,
2095 ensures
2096 #[trigger] serializer_congruent(a, b),
2097{
2098 reveal(serializer_congruent);
2099 lemma_const_serializer_congruence(Const(a.1, a.2), Const(b.1, b.2));
2100 lemma_terminated_serializer_congruence(
2101 Terminated::<_, _, _, false> { a: a.0, b: Const(a.1, a.2), b_val: a.2 },
2102 Terminated::<_, _, _, false> { a: b.0, b: Const(b.1, b.2), b_val: b.2 },
2103 );
2104 lemma_suffix_tagged_prepare_congruence(a, b);
2105}
2106
2107pub broadcast proof fn lemma_bits_parser_congruence<R1, R2, Tuple, Nominal>(
2111 a: Bits<R1, Tuple, Nominal>,
2112 b: Bits<R2, Tuple, Nominal>,
2113) where
2114 R1: SpecByteLen + SpecParser<PVal = R1::T>,
2115 R2: SpecByteLen<T = R1::T> + SpecParser<PVal = R1::T>,
2116
2117 requires
2118 parser_congruent(a.repr, b.repr),
2119 a.unpack == b.unpack,
2120 a.pack == b.pack,
2121 a.refinement == b.refinement,
2122 a.ctor == b.ctor,
2123 a.dtor == b.dtor,
2124 a.consistent == b.consistent,
2125 ensures
2126 #[trigger] parser_congruent(a, b),
2127{
2128 reveal(parser_congruent);
2129 broadcast use lemma_parser_congruent_apply;
2130
2131}
2132
2133pub broadcast proof fn lemma_bits_prepare_congruence<R1, R2, Tuple, Nominal>(
2134 a: Bits<R1, Tuple, Nominal>,
2135 b: Bits<R2, Tuple, Nominal>,
2136) where
2137 R1: SpecByteLen + Consistency<Val = R1::T>,
2138 R2: SpecByteLen<T = R1::T> + Consistency<Val = R1::T>,
2139
2140 requires
2141 prepare_congruent(a.repr, b.repr),
2142 a.unpack == b.unpack,
2143 a.pack == b.pack,
2144 a.refinement == b.refinement,
2145 a.ctor == b.ctor,
2146 a.dtor == b.dtor,
2147 a.consistent == b.consistent,
2148 ensures
2149 #[trigger] prepare_congruent(a, b),
2150{
2151 reveal(prepare_congruent);
2152 broadcast use lemma_prepare_congruent_consistent;
2153 broadcast use lemma_prepare_congruent_byte_len;
2154
2155}
2156
2157pub broadcast proof fn lemma_bits_serializer_congruence<R1, R2, Tuple, Nominal>(
2158 a: Bits<R1, Tuple, Nominal>,
2159 b: Bits<R2, Tuple, Nominal>,
2160) where
2161 R1: SpecByteLen + Consistency<Val = R1::T> + SpecSerializer<SVal = R1::T>,
2162 R2: SpecByteLen<T = R1::T> + Consistency<Val = R1::T> + SpecSerializer<SVal = R1::T>,
2163
2164 requires
2165 serializer_congruent(a.repr, b.repr),
2166 a.unpack == b.unpack,
2167 a.pack == b.pack,
2168 a.refinement == b.refinement,
2169 a.ctor == b.ctor,
2170 a.dtor == b.dtor,
2171 a.consistent == b.consistent,
2172 ensures
2173 #[trigger] serializer_congruent(a, b),
2174{
2175 reveal(serializer_congruent);
2176 broadcast use lemma_serializer_congruent_prepare;
2177 broadcast use lemma_serializer_congruent_serialize;
2178
2179 lemma_bits_prepare_congruence(a, b);
2180}
2181
2182pub broadcast group parser_congruence_lemmas {
2186 lemma_parser_congruent_intro,
2187 lemma_ref_fn_parser_congruence,
2188 lemma_parser_congruent_reflexive,
2189 lemma_parser_congruent_apply,
2190 lemma_exact_len_parser_congruence,
2191 lemma_pair_parser_congruence,
2192 lemma_ref_parser_congruence,
2193 lemma_named_parser_congruence,
2194 lemma_star_parser_congruence,
2195 lemma_repeat_parser_congruence,
2196 lemma_repeat_till_end_parser_congruence,
2197 lemma_repeat_n_parser_congruence,
2198 lemma_array_parser_congruence,
2199 lemma_and_then_parser_congruence,
2200 lemma_mapped_parser_congruence,
2201 lemma_refined_parser_congruence,
2202 lemma_const_parser_congruence,
2203 lemma_cond_parser_congruence,
2204 lemma_choice_parser_congruence,
2205 lemma_alt_parser_congruence,
2206 lemma_sum_parser_congruence,
2207 lemma_opt_parser_congruence,
2208 lemma_optional_parser_congruence,
2209 lemma_optional_end_parser_congruence,
2210 lemma_preceded_parser_congruence,
2211 lemma_terminated_parser_congruence,
2212 lemma_bind_parser_congruence,
2213 lemma_prefix_tagged_parser_congruence,
2214 lemma_suffix_tagged_parser_congruence,
2215 lemma_bits_parser_congruence,
2216}
2217
2218pub broadcast group prepare_congruence_lemmas {
2219 lemma_prepare_congruent_intro,
2220 lemma_prepare_congruent_reflexive,
2221 lemma_prepare_congruent_consistent,
2222 lemma_prepare_congruent_byte_len,
2223 lemma_exact_len_prepare_congruence,
2224 lemma_refined_prepare_congruence,
2225 lemma_cond_prepare_congruence,
2226 lemma_const_prepare_congruence,
2227 lemma_opt_prepare_congruence,
2228 lemma_ref_prepare_congruence,
2229 lemma_named_prepare_congruence,
2230 lemma_star_prepare_congruence,
2231 lemma_pair_prepare_congruence,
2232 lemma_choice_prepare_congruence,
2233 lemma_optional_prepare_congruence,
2234 lemma_repeat_prepare_congruence,
2235 lemma_repeat_n_prepare_congruence,
2236 lemma_array_prepare_congruence,
2237 lemma_optional_end_prepare_congruence,
2238 lemma_repeat_till_end_prepare_congruence,
2239 lemma_preceded_prepare_congruence,
2240 lemma_terminated_prepare_congruence,
2241 lemma_and_then_prepare_congruence,
2242 lemma_alt_prepare_congruence,
2243 lemma_mapped_prepare_congruence,
2244 lemma_bind_prepare_congruence,
2245 lemma_sum_prepare_congruence,
2246 lemma_prefix_tagged_prepare_congruence,
2247 lemma_suffix_tagged_prepare_congruence,
2248 lemma_bits_prepare_congruence,
2249}
2250
2251pub broadcast group serializer_congruence_lemmas {
2252 lemma_serializer_congruent_intro,
2253 lemma_serializer_congruent_reflexive,
2254 lemma_serializer_congruent_prepare,
2255 lemma_serializer_congruent_serialize,
2256 lemma_exact_len_serializer_congruence,
2257 lemma_refined_serializer_congruence,
2258 lemma_cond_serializer_congruence,
2259 lemma_const_serializer_congruence,
2260 lemma_opt_serializer_congruence,
2261 lemma_ref_serializer_congruence,
2262 lemma_named_serializer_congruence,
2263 lemma_star_serializer_congruence,
2264 lemma_pair_serializer_congruence,
2265 lemma_choice_serializer_congruence,
2266 lemma_optional_serializer_congruence,
2267 lemma_repeat_serializer_congruence,
2268 lemma_repeat_n_serializer_congruence,
2269 lemma_array_serializer_congruence,
2270 lemma_optional_end_serializer_congruence,
2271 lemma_repeat_till_end_serializer_congruence,
2272 lemma_preceded_serializer_congruence,
2273 lemma_terminated_serializer_congruence,
2274 lemma_and_then_serializer_congruence,
2275 lemma_alt_serializer_congruence,
2276 lemma_mapped_serializer_congruence,
2277 lemma_bind_serializer_congruence,
2278 lemma_sum_serializer_congruence,
2279 lemma_prefix_tagged_serializer_congruence,
2280 lemma_suffix_tagged_serializer_congruence,
2281 lemma_bits_serializer_congruence,
2282}
2283
2284}