1#[allow(unused_imports)]
2use super::calc_macro::*;
3#[allow(unused_imports)]
4use super::multiset::Multiset;
5#[allow(unused_imports)]
6use super::pervasive::*;
7#[allow(unused_imports)]
8use super::prelude::*;
9#[allow(unused_imports)]
10use super::relations::*;
11#[allow(unused_imports)]
12use super::seq::*;
13#[allow(unused_imports)]
14use super::set::*;
15
16verus! {
17
18broadcast use group_seq_axioms;
19
20impl<A> Seq<A> {
21 pub open spec fn map<B>(self, f: spec_fn(int, A) -> B) -> Seq<B> {
25 Seq::new(self.len(), |i: int| f(i, self[i]))
26 }
27
28 pub open spec fn map_values<B>(self, f: spec_fn(A) -> B) -> Seq<B> {
31 Seq::new(self.len(), |i: int| f(self[i]))
32 }
33
34 pub open spec fn flat_map<B>(self, f: spec_fn(A) -> Seq<B>) -> Seq<B> {
48 self.map_values(f).flatten()
49 }
50
51 pub open spec fn as_ref(&self) -> Seq<&A> {
53 Seq::new(self.len(), |i: int| &self[i])
54 }
55
56 pub open spec fn is_prefix_of(self, other: Self) -> bool {
68 self.len() <= other.len() && self =~= other.subrange(0, self.len() as int)
69 }
70
71 pub open spec fn is_suffix_of(self, other: Self) -> bool {
83 self.len() <= other.len() && self =~= other.subrange(
84 (other.len() - self.len()) as int,
85 other.len() as int,
86 )
87 }
88
89 pub closed spec fn sort_by(self, leq: spec_fn(A, A) -> bool) -> Seq<A>
97 recommends
98 total_ordering(leq),
99 decreases self.len(),
100 {
101 if self.len() <= 1 {
102 self
103 } else {
104 let split_index = self.len() / 2;
105 let left = self.subrange(0, split_index as int);
106 let right = self.subrange(split_index as int, self.len() as int);
107 let left_sorted = left.sort_by(leq);
108 let right_sorted = right.sort_by(leq);
109 merge_sorted_with(left_sorted, right_sorted, leq)
110 }
111 }
112
113 pub open spec fn all(self, pred: spec_fn(A) -> bool) -> bool {
124 forall|i: int| 0 <= i < self.len() ==> #[trigger] pred(self[i])
125 }
126
127 pub open spec fn any(self, pred: spec_fn(A) -> bool) -> bool {
138 exists|i: int| 0 <= i < self.len() && #[trigger] pred(self[i])
139 }
140
141 pub open spec fn exactly_one(self, pred: spec_fn(A) -> bool) -> bool {
151 self.filter(pred).len() == 1
152 }
153
154 pub proof fn lemma_sort_by_ensures(self, leq: spec_fn(A, A) -> bool)
155 requires
156 total_ordering(leq),
157 ensures
158 self.to_multiset() =~= self.sort_by(leq).to_multiset(),
159 sorted_by(self.sort_by(leq), leq),
160 forall|x: A| !self.contains(x) ==> !(#[trigger] self.sort_by(leq).contains(x)),
161 decreases self.len(),
162 {
163 if self.len() <= 1 {
164 } else {
165 let split_index = self.len() / 2;
166 let left = self.subrange(0, split_index as int);
167 let right = self.subrange(split_index as int, self.len() as int);
168 assert(self =~= left + right);
169 let left_sorted = left.sort_by(leq);
170 left.lemma_sort_by_ensures(leq);
171 let right_sorted = right.sort_by(leq);
172 right.lemma_sort_by_ensures(leq);
173 lemma_merge_sorted_with_ensures(left_sorted, right_sorted, leq);
174 lemma_multiset_commutative(left, right);
175 lemma_multiset_commutative(left_sorted, right_sorted);
176 assert forall|x: A| !self.contains(x) implies !(#[trigger] self.sort_by(leq).contains(
177 x,
178 )) by {
179 broadcast use group_to_multiset_ensures;
180
181 assert(!self.contains(x) ==> self.to_multiset().count(x) == 0);
182 }
183 }
184 }
185
186 #[verifier::opaque]
200 pub open spec fn filter(self, pred: spec_fn(A) -> bool) -> Self
201 decreases self.len(),
202 {
203 if self.len() == 0 {
204 self
205 } else {
206 let subseq = self.drop_last().filter(pred);
207 if pred(self.last()) {
208 subseq.push(self.last())
209 } else {
210 subseq
211 }
212 }
213 }
214
215 pub broadcast proof fn lemma_filter_len(self, pred: spec_fn(A) -> bool)
216 ensures
217 #[trigger] self.filter(pred).len() <= self.len(),
220 decreases self.len(),
221 {
222 reveal(Seq::filter);
223 let out = self.filter(pred);
224 if 0 < self.len() {
225 self.drop_last().lemma_filter_len(pred);
226 }
227 }
228
229 pub broadcast proof fn lemma_filter_pred(self, pred: spec_fn(A) -> bool, i: int)
230 requires
231 0 <= i < self.filter(pred).len(),
232 ensures
233 pred(#[trigger] self.filter(pred)[i]),
234 {
235 #[allow(deprecated)]
237 self.filter_lemma(pred);
238 }
239
240 pub broadcast proof fn lemma_filter_contains(self, pred: spec_fn(A) -> bool, i: int)
241 requires
242 0 <= i < self.len() && pred(self[i]),
243 ensures
244 #[trigger] self.filter(pred).contains(self[i]),
245 {
246 #[allow(deprecated)]
248 self.filter_lemma(pred);
249 }
250
251 #[cfg_attr(not(verus_verify_core), deprecated = "Use `broadcast use group_filter_ensures` instead" )]
253 pub proof fn filter_lemma(self, pred: spec_fn(A) -> bool)
254 ensures
255 forall|i: int|
261 0 <= i < self.filter(pred).len() ==> pred(#[trigger] self.filter(pred)[i]),
262 forall|i: int|
264 0 <= i < self.len() && pred(self[i]) ==> #[trigger] self.filter(pred).contains(
265 self[i],
266 ),
267 #[trigger] self.filter(pred).len() <= self.len(),
269 decreases self.len(),
270 {
271 reveal(Seq::filter);
272 let out = self.filter(pred);
273 if 0 < self.len() {
274 self.drop_last().filter_lemma(pred);
275 assert forall|i: int| 0 <= i < out.len() implies pred(out[i]) by {
276 if i < out.len() - 1 {
277 assert(self.drop_last().filter(pred)[i] == out.drop_last()[i]); assert(pred(out[i])); }
280 }
281 assert forall|i: int|
282 0 <= i < self.len() && pred(self[i]) implies #[trigger] out.contains(self[i]) by {
283 if i == self.len() - 1 {
284 assert(self[i] == out[out.len() - 1]); } else {
286 let subseq = self.drop_last().filter(pred);
287 assert(subseq.contains(self.drop_last()[i])); let j = choose|j| 0 <= j < subseq.len() && subseq[j] == self[i];
289 assert(out[j] == self[i]); }
291 }
292 }
293 }
294
295 pub broadcast proof fn filter_distributes_over_add(a: Self, b: Self, pred: spec_fn(A) -> bool)
296 ensures
297 #[trigger] (a + b).filter(pred) == a.filter(pred) + b.filter(pred),
298 decreases b.len(),
299 {
300 reveal(Seq::filter);
301 if 0 < b.len() {
302 Self::drop_last_distributes_over_add(a, b);
303 Self::filter_distributes_over_add(a, b.drop_last(), pred);
304 if pred(b.last()) {
305 Self::push_distributes_over_add(
306 a.filter(pred),
307 b.drop_last().filter(pred),
308 b.last(),
309 );
310 }
311 } else {
312 Self::add_empty_right(a, b);
313 Self::add_empty_right(a.filter(pred), b.filter(pred));
314 }
315 }
316
317 pub broadcast proof fn add_empty_left(a: Self, b: Self)
318 requires
319 a.len() == 0,
320 ensures
321 #[trigger] (a + b) == b,
322 {
323 assert(a + b =~= b);
324 }
325
326 pub broadcast proof fn add_empty_right(a: Self, b: Self)
327 requires
328 b.len() == 0,
329 ensures
330 #[trigger] (a + b) == a,
331 {
332 assert(a + b =~= a);
333 }
334
335 pub broadcast proof fn push_distributes_over_add(a: Self, b: Self, elt: A)
336 ensures
337 #[trigger] (a + b).push(elt) == a + b.push(elt),
338 {
339 assert((a + b).push(elt) =~= a + b.push(elt));
340 }
341
342 pub open spec fn max_via(self, leq: spec_fn(A, A) -> bool) -> A
344 recommends
345 self.len() > 0,
346 decreases self.len(),
347 {
348 if self.len() > 1 {
349 if leq(self[0], self.subrange(1, self.len() as int).max_via(leq)) {
350 self.subrange(1, self.len() as int).max_via(leq)
351 } else {
352 self[0]
353 }
354 } else {
355 self[0]
356 }
357 }
358
359 pub open spec fn min_via(self, leq: spec_fn(A, A) -> bool) -> A
361 recommends
362 self.len() > 0,
363 decreases self.len(),
364 {
365 if self.len() > 1 {
366 let subseq = self.subrange(1, self.len() as int);
367 let elt = subseq.min_via(leq);
368 if leq(elt, self[0]) {
369 elt
370 } else {
371 self[0]
372 }
373 } else {
374 self[0]
375 }
376 }
377
378 pub open spec fn contains(self, needle: A) -> bool {
380 exists|i: int| 0 <= i < self.len() && self[i] == needle
381 }
382
383 pub open spec fn index_of(self, needle: A) -> int {
386 choose|i: int| 0 <= i < self.len() && self[i] == needle
387 }
388
389 pub closed spec fn index_of_first(self, needle: A) -> (result: Option<int>) {
392 if self.contains(needle) {
393 Some(self.first_index_helper(needle))
394 } else {
395 None
396 }
397 }
398
399 spec fn first_index_helper(self, needle: A) -> int
401 recommends
402 self.contains(needle),
403 decreases self.len(),
404 {
405 if self.len() <= 0 {
406 -1 } else if self[0] == needle {
409 0
410 } else {
411 1 + self.subrange(1, self.len() as int).first_index_helper(needle)
412 }
413 }
414
415 pub proof fn index_of_first_ensures(self, needle: A)
416 ensures
417 match self.index_of_first(needle) {
418 Some(index) => {
419 &&& self.contains(needle)
420 &&& 0 <= index < self.len()
421 &&& self[index] == needle
422 &&& forall|j: int| 0 <= j < index < self.len() ==> self[j] != needle
423 },
424 None => { !self.contains(needle) },
425 },
426 decreases self.len(),
427 {
428 if self.contains(needle) {
429 let index = self.index_of_first(needle).unwrap();
430 if self.len() <= 0 {
431 } else if self[0] == needle {
432 } else {
433 assert(Seq::empty().push(self.first()).add(self.drop_first()) =~= self);
434 self.drop_first().index_of_first_ensures(needle);
435 }
436 }
437 }
438
439 pub closed spec fn index_of_last(self, needle: A) -> Option<int> {
442 if self.contains(needle) {
443 Some(self.last_index_helper(needle))
444 } else {
445 None
446 }
447 }
448
449 spec fn last_index_helper(self, needle: A) -> int
451 recommends
452 self.contains(needle),
453 decreases self.len(),
454 {
455 if self.len() <= 0 {
456 -1 } else if self.last() == needle {
459 self.len() - 1
460 } else {
461 self.drop_last().last_index_helper(needle)
462 }
463 }
464
465 pub proof fn index_of_last_ensures(self, needle: A)
466 ensures
467 match self.index_of_last(needle) {
468 Some(index) => {
469 &&& self.contains(needle)
470 &&& 0 <= index < self.len()
471 &&& self[index] == needle
472 &&& forall|j: int| 0 <= index < j < self.len() ==> self[j] != needle
473 },
474 None => { !self.contains(needle) },
475 },
476 decreases self.len(),
477 {
478 if self.contains(needle) {
479 let index = self.index_of_last(needle).unwrap();
480 if self.len() <= 0 {
481 } else if self.last() == needle {
482 } else {
483 assert(self.drop_last().push(self.last()) =~= self);
484 self.drop_last().index_of_last_ensures(needle);
485 }
486 }
487 }
488
489 pub open spec fn drop_last(self) -> Seq<A>
494 recommends
495 self.len() >= 1,
496 {
497 self.subrange(0, self.len() as int - 1)
498 }
499
500 pub proof fn drop_last_distributes_over_add(a: Self, b: Self)
503 requires
504 0 < b.len(),
505 ensures
506 (a + b).drop_last() == a + b.drop_last(),
507 {
508 assert_seqs_equal!((a+b).drop_last(), a+b.drop_last());
509 }
510
511 pub open spec fn drop_first(self) -> Seq<A>
512 recommends
513 self.len() >= 1,
514 {
515 self.subrange(1, self.len() as int)
516 }
517
518 pub open spec fn no_duplicates(self) -> bool {
520 forall|i, j| (0 <= i < self.len() && 0 <= j < self.len() && i != j) ==> self[i] != self[j]
521 }
522
523 pub open spec fn disjoint(self, other: Self) -> bool {
525 forall|i: int, j: int| 0 <= i < self.len() && 0 <= j < other.len() ==> self[i] != other[j]
526 }
527
528 pub closed spec fn to_set(self) -> Set<A> {
530 Set::range(0, self.len() as int).map(|i| self.index(i))
531 }
532
533 pub broadcast proof fn to_set_ensures(self)
534 ensures
535 #![trigger(self.to_set())]
536 forall|i|
538 0 <= i < self.len() ==> #[trigger] self.to_set().contains(self[i]),
539 forall|a| #[trigger] self.to_set().contains(a) <==> self.contains(a),
541 {
542 broadcast use super::set::group_set_lemmas;
543 broadcast use super::set_lib::range_set_properties;
544
545 assert forall|i| 0 <= i < self.len() implies #[trigger] self.to_set().contains(self[i]) by {
546 Set::range(0, self.len() as int).lemma_map_contains(|i: int| self.index(i), self[i]);
547 assert(Set::range(0, self.len() as int).contains(i));
548 assert(self.to_set().contains(self[i]));
549 }
550 assert forall|a| #[trigger] self.to_set().contains(a) <==> self.contains(a) by {
551 Set::range(0, self.len() as int).lemma_map_contains(|i: int| self.index(i), a);
552 if self.to_set().contains(a) {
553 let i = choose|i: int| #[trigger]
554 Set::range(0, self.len() as int).contains(i) && self.index(i) == a;
555 assert(0 <= i < self.len());
556 assert(self.contains(a));
557 }
558 if self.contains(a) {
559 let i = choose|i: int| 0 <= i < self.len() && self[i] == a;
560 assert(self.to_set().contains(self[i]));
561 assert(a == self[i]);
562 }
563 }
564 }
565
566 pub open spec fn to_iset(self) -> ISet<A> {
567 self.to_set().to_iset()
568 }
569
570 pub closed spec fn to_multiset(self) -> Multiset<A>
572 decreases self.len(),
573 {
574 if self.len() == 0 {
575 Multiset::<A>::empty()
576 } else {
577 Multiset::<A>::empty().insert(self.first()).add(self.drop_first().to_multiset())
578 }
579 }
580
581 pub broadcast proof fn to_multiset_ensures(self)
585 ensures
586 forall|a: A| #[trigger] (self.push(a).to_multiset()) =~= self.to_multiset().insert(a), forall|i: int|
588 0 <= i < self.len() ==> #[trigger] (self.remove(i).to_multiset())
589 =~= self.to_multiset().remove(self[i]), self.len() == #[trigger] self.to_multiset().len(), forall|a: A|
592 self.contains(a) <==> #[trigger] self.to_multiset().count(a)
593 > 0, {
595 broadcast use group_seq_properties;
596
597 }
598
599 pub open spec fn insert(self, i: int, a: A) -> Seq<A>
601 recommends
602 0 <= i <= self.len(),
603 {
604 self.subrange(0, i).push(a) + self.subrange(i, self.len() as int)
605 }
606
607 pub proof fn insert_ensures(self, pos: int, elt: A)
609 requires
610 0 <= pos <= self.len(),
611 ensures
612 self.insert(pos, elt).len() == self.len() + 1,
613 forall|i: int| 0 <= i < pos ==> #[trigger] self.insert(pos, elt)[i] == self[i],
614 forall|i: int| pos <= i < self.len() ==> self.insert(pos, elt)[i + 1] == self[i],
615 self.insert(pos, elt)[pos] == elt,
616 {
617 }
618
619 pub open spec fn remove(self, i: int) -> Seq<A>
621 recommends
622 0 <= i < self.len(),
623 {
624 self.subrange(0, i) + self.subrange(i + 1, self.len() as int)
625 }
626
627 pub proof fn remove_ensures(self, i: int)
629 requires
630 0 <= i < self.len(),
631 ensures
632 self.remove(i).len() == self.len() - 1,
633 forall|index: int| 0 <= index < i ==> #[trigger] self.remove(i)[index] == self[index],
634 forall|index: int|
635 i <= index < self.len() - 1 ==> #[trigger] self.remove(i)[index] == self[index + 1],
636 {
637 }
638
639 pub open spec fn remove_value(self, val: A) -> Seq<A> {
642 let index = self.index_of_first(val);
643 match index {
644 Some(i) => self.remove(i),
645 None => self,
646 }
647 }
648
649 pub open spec fn reverse(self) -> Seq<A>
651 decreases self.len(),
652 {
653 if self.len() == 0 {
654 Seq::empty()
655 } else {
656 Seq::new(self.len(), |i: int| self[self.len() - 1 - i])
657 }
658 }
659
660 pub open spec fn zip_with<B>(self, other: Seq<B>) -> Seq<(A, B)>
663 recommends
664 self.len() == other.len(),
665 decreases self.len(),
666 {
667 if self.len() != other.len() {
668 Seq::empty()
669 } else if self.len() == 0 {
670 Seq::empty()
671 } else {
672 Seq::new(self.len(), |i: int| (self[i], other[i]))
673 }
674 }
675
676 pub open spec fn fold_left<B>(self, b: B, f: spec_fn(B, A) -> B) -> (res: B)
683 decreases self.len(),
684 {
685 if self.len() == 0 {
686 b
687 } else {
688 f(self.drop_last().fold_left(b, f), self.last())
689 }
690 }
691
692 pub open spec fn fold_left_alt<B>(self, b: B, f: spec_fn(B, A) -> B) -> (res: B)
696 decreases self.len(),
697 {
698 if self.len() == 0 {
699 b
700 } else {
701 self.subrange(1, self.len() as int).fold_left_alt(f(b, self[0]), f)
702 }
703 }
704
705 pub broadcast proof fn lemma_fold_left_split<B>(self, b: B, f: spec_fn(B, A) -> B, k: int)
707 requires
708 0 <= k <= self.len(),
709 ensures
710 self.subrange(k, self.len() as int).fold_left(
711 (#[trigger] self.subrange(0, k).fold_left(b, f)),
712 f,
713 ) == self.fold_left(b, f),
714 decreases self.len(),
715 {
716 reveal_with_fuel(Seq::fold_left, 2);
717 if k == self.len() {
718 assert(self.subrange(0, self.len() as int) == self);
719 } else {
720 self.drop_last().lemma_fold_left_split(b, f, k);
721 assert_seqs_equal!(
722 self.drop_last().subrange(k, self.drop_last().len() as int) ==
723 self.subrange(k, self.len()-1)
724 );
725 assert_seqs_equal!(
726 self.drop_last().subrange(0, k) ==
727 self.subrange(0, k)
728 );
729 assert_seqs_equal!(
730 self.subrange(k, self.len() as int).drop_last() ==
731 self.subrange(k, self.len() - 1)
732 );
733 }
734 }
735
736 proof fn aux_lemma_fold_left_alt<B>(self, b: B, f: spec_fn(B, A) -> B, k: int)
738 requires
739 0 < k <= self.len(),
740 ensures
741 self.subrange(k, self.len() as int).fold_left_alt(
742 self.subrange(0, k).fold_left_alt(b, f),
743 f,
744 ) == self.fold_left_alt(b, f),
745 decreases k,
746 {
747 reveal_with_fuel(Seq::fold_left_alt, 2);
748 if k == 1 {
749 } else {
751 self.subrange(1, self.len() as int).aux_lemma_fold_left_alt(f(b, self[0]), f, k - 1);
752 assert_seqs_equal!(
753 self.subrange(1, self.len() as int)
754 .subrange(k - 1, self.subrange(1, self.len() as int).len() as int) ==
755 self.subrange(k, self.len() as int)
756 );
757 assert_seqs_equal!(
758 self.subrange(1, self.len() as int).subrange(0, k - 1) ==
759 self.subrange(1, k)
760 );
761 assert_seqs_equal!(
762 self.subrange(0, k).subrange(1, self.subrange(0, k).len() as int) ==
763 self.subrange(1, k)
764 );
765 }
766 }
767
768 pub proof fn lemma_fold_left_alt<B>(self, b: B, f: spec_fn(B, A) -> B)
770 ensures
771 self.fold_left(b, f) == self.fold_left_alt(b, f),
772 decreases self.len(),
773 {
774 reveal_with_fuel(Seq::fold_left, 2);
775 reveal_with_fuel(Seq::fold_left_alt, 2);
776 if self.len() <= 1 {
777 } else {
779 self.aux_lemma_fold_left_alt(b, f, self.len() - 1);
780 self.subrange(self.len() - 1, self.len() as int).lemma_fold_left_alt(
781 self.drop_last().fold_left_alt(b, f),
782 f,
783 );
784 self.subrange(0, self.len() - 1).lemma_fold_left_alt(b, f);
785 }
786 }
787
788 pub proof fn lemma_reverse_fold_left<B>(self, v: B, f: spec_fn(B, A) -> B)
791 ensures
792 self.reverse().fold_left(v, f) == self.fold_right(|a: A, b: B| f(b, a), v),
793 {
794 assert(self.reverse().reverse() =~= self);
795 let g = |a: A, b: B| f(b, a);
796 assert(f =~= |b: B, a: A| g(a, b));
797 self.reverse().lemma_reverse_fold_right(v, |a: A, b: B| f(b, a))
798 }
799
800 pub open spec fn fold_right<B>(self, f: spec_fn(A, B) -> B, b: B) -> (res: B)
807 decreases self.len(),
808 {
809 if self.len() == 0 {
810 b
811 } else {
812 self.drop_last().fold_right(f, f(self.last(), b))
813 }
814 }
815
816 pub open spec fn fold_right_alt<B>(self, f: spec_fn(A, B) -> B, b: B) -> (res: B)
820 decreases self.len(),
821 {
822 if self.len() == 0 {
823 b
824 } else {
825 f(self[0], self.subrange(1, self.len() as int).fold_right_alt(f, b))
826 }
827 }
828
829 pub broadcast proof fn lemma_fold_right_split<B>(self, f: spec_fn(A, B) -> B, b: B, k: int)
831 requires
832 0 <= k <= self.len(),
833 ensures
834 self.subrange(0, k).fold_right(
835 f,
836 (#[trigger] self.subrange(k, self.len() as int).fold_right(f, b)),
837 ) == self.fold_right(f, b),
838 decreases self.len(),
839 {
840 reveal_with_fuel(Seq::fold_right, 2);
841 if k == self.len() {
842 assert(self.subrange(0, k) == self);
843 } else if k == self.len() - 1 {
844 } else {
846 self.subrange(0, self.len() - 1).lemma_fold_right_split(f, f(self.last(), b), k);
847 assert_seqs_equal!(
848 self.subrange(0, self.len() - 1).subrange(0, k) ==
849 self.subrange(0, k)
850 );
851 assert_seqs_equal!(
852 self.subrange(0, self.len() - 1).subrange(k, self.subrange(0, self.len() - 1).len() as int) ==
853 self.subrange(k, self.len() - 1)
854 );
855 assert_seqs_equal!(
856 self.subrange(k, self.len() as int).drop_last() ==
857 self.subrange(k, self.len() - 1)
858 );
859 }
860 }
861
862 pub proof fn lemma_fold_right_commute_one<B>(self, a: A, f: spec_fn(A, B) -> B, v: B)
864 requires
865 commutative_foldr(f),
866 ensures
867 self.fold_right(f, f(a, v)) == f(a, self.fold_right(f, v)),
868 decreases self.len(),
869 {
870 if self.len() > 0 {
871 self.drop_last().lemma_fold_right_commute_one(a, f, f(self.last(), v));
872 }
873 }
874
875 pub proof fn lemma_fold_right_alt<B>(self, f: spec_fn(A, B) -> B, b: B)
877 ensures
878 self.fold_right(f, b) == self.fold_right_alt(f, b),
879 decreases self.len(),
880 {
881 reveal_with_fuel(Seq::fold_right, 2);
882 reveal_with_fuel(Seq::fold_right_alt, 2);
883 if self.len() <= 1 {
884 } else {
886 self.subrange(1, self.len() as int).lemma_fold_right_alt(f, b);
887 self.lemma_fold_right_split(f, b, 1);
888 }
889 }
890
891 pub proof fn lemma_reverse_fold_right<B>(self, v: B, f: spec_fn(A, B) -> B)
894 ensures
895 self.reverse().fold_right(f, v) == self.fold_left(v, |b: B, a: A| f(a, b)),
896 decreases self.len(),
897 {
898 let g = |b: B, a: A| f(a, b);
899 if self.len() > 0 {
900 let last = self.last();
901 let s0 = self.drop_last();
902 assert(self.reverse() =~= seq![last] + s0.reverse());
903 let res1 = self.reverse().fold_right(f, v);
904 let res2 = self.fold_left(v, g);
905 assert(res1 == self.reverse().fold_right_alt(f, v)) by {
906 self.reverse().lemma_fold_right_alt(f, v)
907 }
908 assert(res2 == g(s0.fold_left(v, g), last));
909 assert(self.reverse().first() == last);
910 assert(self.reverse().subrange(1, self.reverse().len() as int) =~= s0.reverse());
911 assert(res1 == f(last, s0.reverse().fold_right_alt(f, v)));
912 assert(res1 == f(last, s0.reverse().fold_right(f, v))) by {
913 s0.reverse().lemma_fold_right_alt(f, v)
914 }
915 assert(res2 == g(s0.fold_left(v, g), last));
916 s0.lemma_reverse_fold_right(v, f);
917 }
918 }
919
920 pub proof fn lemma_multiset_has_no_duplicates(self)
924 requires
925 self.no_duplicates(),
926 ensures
927 forall|x: A| self.to_multiset().contains(x) ==> self.to_multiset().count(x) == 1,
928 decreases self.len(),
929 {
930 broadcast use super::multiset::group_multiset_axioms;
931
932 if self.len() == 0 {
933 assert(forall|x: A|
934 self.to_multiset().contains(x) ==> self.to_multiset().count(x) == 1);
935 } else {
936 broadcast use group_seq_properties;
937
938 assert(self.drop_last().push(self.last()) =~= self);
939 self.drop_last().lemma_multiset_has_no_duplicates();
940 }
941 }
942
943 pub proof fn lemma_multiset_has_no_duplicates_conv(self)
946 requires
947 forall|x: A| self.to_multiset().contains(x) ==> self.to_multiset().count(x) == 1,
948 ensures
949 self.no_duplicates(),
950 {
951 broadcast use super::multiset::group_multiset_axioms;
952
953 assert forall|i, j| (0 <= i < self.len() && 0 <= j < self.len() && i != j) implies self[i]
954 != self[j] by {
955 let mut a = if (i < j) {
956 i
957 } else {
958 j
959 };
960 let mut b = if (i < j) {
961 j
962 } else {
963 i
964 };
965
966 if (self[a] == self[b]) {
967 let s0 = self.subrange(0, b);
968 let s1 = self.subrange(b, self.len() as int);
969 assert(self == s0 + s1);
970
971 broadcast use group_to_multiset_ensures;
972
973 lemma_multiset_commutative(s0, s1);
974 assert(self.to_multiset().count(self[a]) >= 2);
975 }
976 }
977 }
978
979 pub proof fn lemma_reverse_to_multiset(self)
981 ensures
982 self.reverse().to_multiset() =~= self.to_multiset(),
983 decreases self.len(),
984 {
985 broadcast use group_seq_properties;
986 broadcast use super::multiset::group_multiset_axioms;
987
988 if self.len() > 0 {
989 let s2 = self.drop_first();
990 let e = self.first();
991 assert(self =~= seq![e] + s2);
992 assert(self.to_multiset() =~= seq![e].to_multiset().add(s2.to_multiset())) by {
993 lemma_multiset_commutative(seq![e], s2)
994 }
995 assert(self.reverse() =~= s2.reverse().push(e));
996 assert(self.reverse().to_multiset() =~= s2.reverse().to_multiset().insert(e));
997 s2.lemma_reverse_to_multiset();
998 }
999 }
1000
1001 pub proof fn lemma_add_last_back(self)
1005 requires
1006 0 < self.len(),
1007 ensures
1008 #[trigger] self.drop_last().push(self.last()) =~= self,
1009 {
1010 }
1011
1012 pub proof fn lemma_indexing_implies_membership(self, f: spec_fn(A) -> bool)
1017 requires
1018 forall|i: int| 0 <= i < self.len() ==> #[trigger] f(#[trigger] self[i]),
1019 ensures
1020 forall|x: A| #[trigger] self.contains(x) ==> #[trigger] f(x),
1021 {
1022 assert(forall|i: int| 0 <= i < self.len() ==> #[trigger] self.contains(self[i]));
1023 }
1024
1025 pub proof fn lemma_membership_implies_indexing(self, f: spec_fn(A) -> bool)
1030 requires
1031 forall|x: A| #[trigger] self.contains(x) ==> #[trigger] f(x),
1032 ensures
1033 forall|i: int| 0 <= i < self.len() ==> #[trigger] f(self[i]),
1034 {
1035 assert forall|i: int| 0 <= i < self.len() implies #[trigger] f(self[i]) by {
1036 assert(self.contains(self[i]));
1037 }
1038 }
1039
1040 pub proof fn lemma_split_at(self, pos: int)
1044 requires
1045 0 <= pos <= self.len(),
1046 ensures
1047 self.subrange(0, pos) + self.subrange(pos, self.len() as int) =~= self,
1048 {
1049 }
1050
1051 pub proof fn lemma_element_from_slice(self, new: Seq<A>, a: int, b: int, pos: int)
1053 requires
1054 0 <= a <= b <= self.len(),
1055 new == self.subrange(a, b),
1056 a <= pos < b,
1057 ensures
1058 pos - a < new.len(),
1059 new[pos - a] == self[pos],
1060 {
1061 }
1062
1063 pub proof fn lemma_slice_of_slice(self, s1: int, e1: int, s2: int, e2: int)
1066 requires
1067 0 <= s1 <= e1 <= self.len(),
1068 0 <= s2 <= e2 <= e1 - s1,
1069 ensures
1070 self.subrange(s1, e1).subrange(s2, e2) =~= self.subrange(s1 + s2, s1 + e2),
1071 {
1072 }
1073
1074 pub proof fn unique_seq_to_set(self)
1076 requires
1077 self.no_duplicates(),
1078 ensures
1079 self.len() == self.to_set().len(),
1080 decreases self.len(),
1081 {
1082 broadcast use super::set::group_set_lemmas;
1083
1084 seq_to_set_equal_rec::<A>(self);
1085 if self.len() == 0 {
1086 } else {
1087 let rest = self.drop_last();
1088 rest.unique_seq_to_set();
1089 seq_to_set_equal_rec::<A>(rest);
1090 assert(!rest.contains(self.last()));
1091 assert(!seq_to_set_rec(rest).contains(self.last())) by {
1092 seq_to_set_rec_contains::<A>(rest);
1093 }
1094 assert(seq_to_set_rec(rest).insert(self.last()).len() == seq_to_set_rec(rest).len()
1095 + 1);
1096 }
1097 }
1098
1099 pub proof fn lemma_cardinality_of_set(self)
1102 ensures
1103 self.to_set().len() <= self.len(),
1104 {
1105 broadcast use super::set_lib::range_set_properties;
1106
1107 super::set_lib::lemma_map_size_bound::<int, A>(
1108 Set::range(0, self.len() as int),
1109 self.to_set(),
1110 |i: int| self.index(i),
1111 );
1112 }
1113
1114 pub proof fn lemma_cardinality_of_empty_set_is_0(self)
1117 ensures
1118 self.to_set().len() == 0 <==> self.len() == 0,
1119 {
1120 broadcast use super::set::group_set_lemmas;
1121
1122 self.to_set_ensures();
1123
1124 assert(self.len() == 0 ==> self.to_set().len() == 0) by { self.lemma_cardinality_of_set() }
1125 assert(!(self.len() == 0) ==> !(self.to_set().len() == 0)) by {
1126 if self.len() > 0 {
1127 assert(self.to_set().contains(self[0]));
1128 assert(self.to_set().remove(self[0]).len() <= self.to_set().len());
1129 }
1130 }
1131 }
1132
1133 pub proof fn lemma_no_dup_set_cardinality(self)
1136 requires
1137 self.to_set().len() == self.len(),
1138 ensures
1139 self.no_duplicates(),
1140 decreases self.len(),
1141 {
1142 broadcast use super::set::group_set_lemmas;
1143
1144 self.to_set_ensures();
1145 self.drop_first().to_set_ensures();
1146
1147 if self.len() == 0 {
1148 } else {
1149 assert(self =~= Seq::empty().push(self.first()).add(self.drop_first()));
1150 if self.drop_first().contains(self.first()) {
1151 assert(self.to_set() =~= self.drop_first().to_set());
1153 assert(self.to_set().len() <= self.drop_first().len()) by {
1154 self.drop_first().lemma_cardinality_of_set()
1155 }
1156 } else {
1157 assert(self.to_set().len() == 1 + self.drop_first().to_set().len()) by {
1158 assert(self.drop_first().to_set().insert(self.first()) =~= self.to_set());
1159 }
1160 self.drop_first().lemma_no_dup_set_cardinality();
1161 }
1162 }
1163 }
1164
1165 pub broadcast proof fn lemma_to_set_map_commutes<B>(self, f: spec_fn(A) -> B)
1168 ensures
1169 #[trigger] self.to_set().map(f) =~= self.map_values(f).to_set(),
1170 {
1171 broadcast use crate::vstd::group_vstd_default;
1172
1173 assert forall|elem: B|
1174 self.to_set().map(f).contains(elem) <==> self.map_values(f).to_set().contains(elem) by {
1175 if self.to_set().map(f).contains(elem) {
1176 let x = choose|x: A| self.to_set().contains(x) && f(x) == elem;
1177 let i = choose|i: int| 0 <= i < self.len() && self[i] == x;
1178 assert(self.map_values(f)[i] == elem);
1179 }
1180 if self.map_values(f).to_set().contains(elem) {
1181 let i = choose|i: int|
1182 0 <= i < self.map_values(f).len() && self.map_values(f)[i] == elem;
1183 let x = self[i];
1184 assert(self.to_set().contains(x));
1185 }
1186 };
1187 }
1188
1189 pub broadcast proof fn lemma_to_iset_map_commutes<B>(self, f: spec_fn(A) -> B)
1192 ensures
1193 #[trigger] self.to_iset().map(f) =~= self.map_values(f).to_iset(),
1194 {
1195 broadcast use crate::vstd::group_vstd_default;
1196
1197 assert forall|elem: B|
1198 self.to_iset().map(f).contains(elem) <==> self.map_values(f).to_iset().contains(
1199 elem,
1200 ) by {
1201 if self.to_iset().map(f).contains(elem) {
1202 let x = choose|x: A| self.to_iset().contains(x) && f(x) == elem;
1203 let i = choose|i: int| 0 <= i < self.len() && self[i] == x;
1204 assert(self.map_values(f)[i] == elem);
1205 }
1206 if self.map_values(f).to_iset().contains(elem) {
1207 let i = choose|i: int|
1208 0 <= i < self.map_values(f).len() && self.map_values(f)[i] == elem;
1209 let x = self[i];
1210 assert(self.to_iset().contains(x));
1211 }
1212 };
1213 }
1214
1215 pub broadcast proof fn lemma_to_set_insert_commutes(sq: Seq<A>, elt: A)
1218 ensures
1219 #[trigger] (sq + seq![elt]).to_set() =~= sq.to_set().insert(elt),
1220 {
1221 broadcast use crate::vstd::group_vstd_default;
1222 broadcast use lemma_seq_concat_contains_all_elements;
1223 broadcast use lemma_seq_empty_contains_nothing;
1224 broadcast use lemma_seq_contains_after_push;
1225 broadcast use super::seq::group_seq_axioms;
1226 broadcast use super::set_lib::group_set_properties;
1227
1228 }
1229
1230 pub broadcast proof fn lemma_to_iset_insert_commutes(sq: Seq<A>, elt: A)
1233 ensures
1234 #[trigger] (sq + seq![elt]).to_iset() =~= sq.to_iset().insert(elt),
1235 {
1236 broadcast use crate::vstd::group_vstd_default;
1237 broadcast use lemma_seq_concat_contains_all_elements;
1238 broadcast use lemma_seq_empty_contains_nothing;
1239 broadcast use lemma_seq_contains_after_push;
1240 broadcast use super::seq::group_seq_axioms;
1241 broadcast use super::set_lib::group_set_properties;
1242
1243 }
1244
1245 pub open spec fn update_subrange_with(self, off: int, vs: Self) -> Self
1249 recommends
1250 0 <= off,
1251 off + vs.len() <= self.len(),
1252 {
1253 Seq::new(
1254 self.len(),
1255 |i: int|
1256 if off <= i < off + vs.len() {
1257 vs[i - off]
1258 } else {
1259 self[i]
1260 },
1261 )
1262 }
1263
1264 pub broadcast proof fn lemma_seq_skip_skip(self, i: int)
1276 ensures
1277 0 <= i < self.len() ==> (self.skip(i)).skip(1) =~= #[trigger] self.skip(i + 1),
1278 {
1279 broadcast use group_seq_properties;
1280
1281 }
1282
1283 pub proof fn lemma_contains_to_index(self, elem: A) -> (idx: int)
1296 requires
1297 self.contains(elem),
1298 ensures
1299 0 <= idx < self.len() && self[idx] == elem,
1300 decreases self.len(),
1301 {
1302 broadcast use group_seq_properties;
1303
1304 if self[0] == elem {
1305 0
1306 } else {
1307 let i = self.skip(1).lemma_contains_to_index(elem);
1308 i + 1
1309 }
1310 }
1311
1312 pub proof fn lemma_all_from_head_tail(self, pred: spec_fn(A) -> bool)
1328 requires
1329 self.len() > 0,
1330 pred(self[0]) && self.skip(1).all(|x| pred(x)),
1331 ensures
1332 self.all(|x| pred(x)),
1333 {
1334 broadcast use group_seq_properties;
1335
1336 assert(seq![self[0]] + self.skip(1) == self);
1337 }
1338
1339 pub proof fn lemma_any_tail(self, pred: spec_fn(A) -> bool)
1355 requires
1356 self.any(|x| pred(x)),
1357 ensures
1358 !pred(self[0]) ==> self.skip(1).any(|x| pred(x)),
1359 {
1360 broadcast use group_seq_properties;
1361
1362 }
1363
1364 pub open spec fn remove_duplicates(self, seen: Seq<A>) -> Seq<A>
1382 decreases self.len(),
1383 {
1384 if self.len() == 0 {
1385 seen
1386 } else if seen.contains(self[0]) {
1387 self.skip(1).remove_duplicates(seen)
1388 } else {
1389 self.skip(1).remove_duplicates(seen + seq![self[0]])
1390 }
1391 }
1392
1393 pub broadcast proof fn lemma_remove_duplicates_properties(self, seen: Seq<A>)
1411 ensures
1412 forall|x|
1413 (self + seen).contains(x) <==> #[trigger] self.remove_duplicates(seen).contains(x),
1414 #[trigger] self.remove_duplicates(seen).len() <= self.len() + seen.len(),
1415 decreases self.len(),
1416 {
1417 broadcast use group_seq_properties;
1418
1419 if self.len() == 0 {
1420 } else if seen.contains(self[0]) {
1421 let rest = self.skip(1);
1422 rest.lemma_remove_duplicates_properties(seen);
1423 } else {
1424 let rest = self.skip(1);
1425 rest.lemma_remove_duplicates_properties(seen + seq![self[0]]);
1426 }
1427 }
1428
1429 pub proof fn lemma_remove_duplicates_append_index(self, i: int, seen: Seq<A>)
1445 requires
1446 0 <= i < self.len(),
1447 ensures
1448 self.remove_duplicates(seen) == self.skip(i).remove_duplicates(
1449 self.take(i).remove_duplicates(seen),
1450 ),
1451 decreases self.len(),
1452 {
1453 broadcast use {
1454 group_seq_properties,
1455 lemma_seq_skip_of_skip,
1456 Seq::lemma_remove_duplicates_properties,
1457 };
1458
1459 if i == 0 {
1460 } else if i == self.len() {
1461 assert(self.take(i) == self);
1462 } else {
1463 assert(self.skip(1).take(i - 1) == self.subrange(1, i));
1464 assert(self.take(i).skip(1) == self.subrange(1, i));
1465 assert(self.skip(1).take(i - 1) == self.take(i).skip(1));
1466 if seen.contains(self[0]) {
1467 self.skip(1).lemma_remove_duplicates_append_index(i - 1, seen);
1468 } else {
1469 self.skip(1).lemma_remove_duplicates_append_index(i - 1, seen + seq![self[0]]);
1470 }
1471 }
1472 }
1473
1474 proof fn lemma_skip1_concat(xs: Seq<A>, ys: Seq<A>)
1489 requires
1490 xs.len() > 0,
1491 ensures
1492 (xs + ys).skip(1) == xs.skip(1) + ys,
1493 {
1494 broadcast use group_seq_properties;
1495
1496 assert((xs + ys).skip(1) == xs.skip(1) + ys);
1497 }
1498
1499 pub proof fn lemma_remove_duplicates_append(self, x: A, seen: Seq<A>)
1515 ensures
1516 (self + seen).contains(x) ==> (self + seq![x]).remove_duplicates(seen)
1517 == self.remove_duplicates(seen),
1518 !(self + seen).contains(x) ==> (self + seq![x]).remove_duplicates(seen)
1519 == self.remove_duplicates(seen) + seq![x],
1520 decreases self.len(),
1521 {
1522 broadcast use group_seq_properties;
1523
1524 reveal_with_fuel(Seq::remove_duplicates, 2);
1525
1526 if self.len() != 0 {
1527 let head = self[0];
1528 let tail = self.skip(1);
1529
1530 let seen2 = if seen.contains(head) {
1531 seen
1532 } else {
1533 seen + seq![head]
1534 };
1535 tail.lemma_remove_duplicates_append(x, seen2);
1536 assert((self + seq![x]).skip(1) == tail + seq![x]) by {
1537 Seq::lemma_skip1_concat(self, seq![x]);
1538 };
1539 }
1540 }
1541
1542 pub proof fn lemma_all_neg_filter_empty(self, pred: spec_fn(A) -> bool)
1555 requires
1556 self.all(|x: A| !pred(x)),
1557 ensures
1558 self.filter(pred).len() == 0,
1559 decreases self.len(),
1560 {
1561 broadcast use group_seq_properties;
1562
1563 reveal(Seq::filter);
1564 if self.len() != 0 {
1565 let rest = self.drop_last();
1566 rest.lemma_all_neg_filter_empty(pred);
1567 rest.lemma_filter_len_push(pred, self.last());
1568 let neg_pred = |x| !pred(x);
1569 assert(neg_pred(self.last()));
1570 }
1571 }
1572
1573 pub open spec fn filter_map<B>(self, f: spec_fn(A) -> Option<B>) -> Seq<B>
1582 decreases self.len(),
1583 {
1584 if self.len() == 0 {
1588 Seq::empty()
1589 } else {
1590 let rest = self.drop_last();
1591 match f(self.last()) {
1592 Option::Some(s) => rest.filter_map(f) + seq![s],
1593 Option::None => rest.filter_map(f),
1594 }
1595 }
1596 }
1597
1598 pub broadcast proof fn lemma_filter_contains_rev(self, p: spec_fn(A) -> bool, elem: A)
1602 requires
1603 #[trigger] self.filter(p).contains(elem),
1604 ensures
1605 self.contains(elem),
1606 decreases self.len(),
1607 {
1608 broadcast use group_seq_properties;
1609
1610 reveal(Seq::filter);
1611 if self.len() == 0 {
1612 } else {
1613 let rest = self.drop_last();
1614 let last = self.last();
1615 if !p(last) || last != elem {
1616 rest.lemma_filter_contains_rev(p, elem);
1617 }
1618 }
1619 }
1620
1621 pub broadcast proof fn lemma_filter_map_contains<B>(self, f: spec_fn(A) -> Option<B>, elt: B)
1625 requires
1626 #[trigger] self.filter_map(f).contains(elt),
1627 ensures
1628 exists|t: A| #[trigger] self.contains(t) && f(t) == Some(elt),
1629 decreases self.len(),
1630 {
1631 broadcast use group_seq_properties;
1632
1633 if self.len() == 0 {
1634 } else {
1635 let last = self.last();
1636 let rest = self.drop_last();
1637 if f(last) == Some(elt) {
1638 assert(self.contains(last));
1639 } else {
1640 rest.lemma_filter_map_contains(f, elt);
1641 let t = choose|t: A| #[trigger] rest.contains(t) && f(t) == Some(elt);
1642 assert(self.contains(t));
1643 }
1644 }
1645 }
1646
1647 pub proof fn lemma_take_succ(xs: Seq<A>, k: int)
1656 requires
1657 0 <= k < xs.len(),
1658 ensures
1659 xs.take(k + 1) =~= xs.take(k) + seq![xs[k]],
1660 {
1661 broadcast use group_seq_properties;
1662
1663 }
1664
1665 pub proof fn lemma_filter_map_singleton<B>(a: A, f: spec_fn(A) -> Option<B>)
1669 ensures
1670 seq![a].filter_map(f) =~= match f(a) {
1671 Option::Some(b) => seq![b],
1672 Option::None => Seq::empty(),
1673 },
1674 {
1675 reveal_with_fuel(Seq::filter_map, 2);
1676 }
1677
1678 pub broadcast proof fn lemma_filter_map_take_succ<B>(self, f: spec_fn(A) -> Option<B>, i: int)
1690 requires
1691 0 <= i < self.len(),
1692 ensures
1693 #[trigger] self.take(i + 1).filter_map(f) =~= self.take(i).filter_map(f) + (match f(
1694 self[i],
1695 ) {
1696 Option::Some(s) => seq![s],
1697 Option::None => Seq::empty(),
1698 }),
1699 decreases self.len(),
1700 {
1701 broadcast use group_seq_properties;
1702
1703 if i != 0 {
1704 self.drop_last().lemma_filter_map_take_succ(f, i - 1);
1705 assert(self.take(i + 1).drop_last() == self.take(i));
1706 }
1707 }
1708
1709 pub open spec fn filter_alt(self, p: spec_fn(A) -> bool) -> Seq<A> {
1712 if self.len() == 0 {
1713 Seq::empty()
1714 } else {
1715 let rest = self.drop_first().filter(p);
1716 let first = self.first();
1717 if p(first) {
1718 seq![first] + rest
1719 } else {
1720 rest
1721 }
1722 }
1723 }
1724
1725 pub broadcast proof fn lemma_filter_prepend(self, x: A, p: spec_fn(A) -> bool)
1740 ensures
1741 #[trigger] (seq![x] + self).filter(p) == (if p(x) {
1742 seq![x]
1743 } else {
1744 Seq::empty()
1745 }) + self.filter(p),
1746 decreases self.len(),
1747 {
1748 broadcast use group_seq_properties;
1749
1750 reveal(Seq::filter);
1751 let lhs = (seq![x] + self).filter(p);
1752 let rhs = (if p(x) {
1753 seq![x]
1754 } else {
1755 Seq::empty()
1756 }) + self.filter(p);
1757
1758 if self.len() == 0 {
1759 assert(lhs =~= rhs);
1760 } else {
1761 let tail_seq = if p(self.last()) {
1762 seq![self.last()]
1763 } else {
1764 Seq::empty()
1765 };
1766
1767 assert(((seq![x] + self).drop_last()) =~= seq![x] + self.drop_last());
1768 let sub = (seq![x] + self.drop_last()).filter(p);
1769 assert(lhs =~= sub + tail_seq);
1770 assert(rhs =~= (if p(x) {
1771 seq![x]
1772 } else {
1773 Seq::empty()
1774 }) + self.drop_last().filter(p) + tail_seq);
1775 self.drop_last().lemma_filter_prepend(x, p);
1776 }
1777 }
1778
1779 pub proof fn lemma_filter_eq_filter_alt(self, p: spec_fn(A) -> bool)
1781 ensures
1782 self.filter(p) =~= self.filter_alt(p),
1783 decreases self.len(),
1784 {
1785 broadcast use group_seq_properties;
1786 broadcast use Seq::lemma_filter_prepend;
1787
1788 reveal(Seq::filter);
1789 if self.len() == 0 {
1790 } else {
1791 let first = self.first();
1792 let but_first = self.drop_first();
1793 assert(self =~= seq![first] + but_first);
1794 self.drop_first().lemma_filter_eq_filter_alt(p);
1795 }
1796 }
1797
1798 pub proof fn lemma_filter_monotone(self, ys: Seq<A>, p: spec_fn(A) -> bool)
1813 requires
1814 self.is_prefix_of(ys),
1815 ensures
1816 self.filter(p).is_prefix_of(ys.filter(p)),
1817 decreases self.len(),
1818 {
1819 broadcast use group_seq_properties;
1820
1821 self.lemma_filter_eq_filter_alt(p);
1822 ys.lemma_filter_eq_filter_alt(p);
1823 if self.len() == 0 {
1824 } else {
1825 self.drop_first().lemma_filter_monotone(ys.drop_first(), p);
1826 }
1827 }
1828
1829 pub proof fn lemma_filter_take_len(self, p: spec_fn(A) -> bool, i: int)
1844 requires
1845 0 <= i <= self.len(),
1846 ensures
1847 self.filter(p).len() >= self.take(i).filter(p).len(),
1848 decreases i,
1849 {
1850 broadcast use group_seq_properties;
1851 broadcast use Seq::lemma_filter_len_push;
1852 broadcast use Seq::lemma_filter_push;
1853
1854 self.take(i).lemma_filter_monotone(self, p);
1855 }
1856
1857 pub broadcast proof fn lemma_filter_len_push(self, p: spec_fn(A) -> bool, elem: A)
1869 ensures
1870 #[trigger] self.push(elem).filter(p).len() == self.filter(p).len() + (if p(elem) {
1871 1int
1872 } else {
1873 0int
1874 }),
1875 {
1876 broadcast use group_seq_properties;
1877 broadcast use Seq::lemma_filter_push;
1878
1879 }
1880
1881 pub broadcast proof fn lemma_index_contains(self, i: int)
1884 requires
1885 0 <= i < self.len(),
1886 ensures
1887 self.contains(#[trigger] self[i]),
1888 {
1889 }
1890
1891 pub broadcast proof fn lemma_take_succ_push(self, i: int)
1894 requires
1895 0 <= i < self.len(),
1896 ensures
1897 #[trigger] self.take(i + 1) =~= self.take(i).push(self[i]),
1898 {
1899 broadcast use group_seq_properties;
1900
1901 }
1902
1903 pub broadcast proof fn lemma_take_len(self)
1905 ensures
1906 #[trigger] self.take(self.len() as int) == self,
1907 {
1908 broadcast use group_seq_properties;
1909
1910 }
1911
1912 pub broadcast proof fn lemma_take_any_succ(self, p: spec_fn(A) -> bool, i: int)
1925 requires
1926 0 <= i < self.len(),
1927 ensures
1928 #[trigger] self.take(i + 1).any(p) <==> self.take(i).any(p) || p(self[i]),
1929 {
1930 broadcast use group_seq_properties;
1931
1932 self.lemma_take_succ_push(i);
1933 if self.take(i + 1).any(p) {
1934 let x = choose|x: A| self.take(i + 1).contains(x) && #[trigger] p(x);
1935 assert(self.take(i).contains(x) || x == self[i]);
1936 }
1937 if self.take(i).any(p) {
1938 let x = choose|x: A| self.take(i).contains(x) && #[trigger] p(x);
1939 assert(self.take(i + 1).contains(x));
1940 }
1941 if p(self[i]) {
1942 assert(self.take(i + 1).contains(self[i]));
1943 }
1944 }
1945
1946 pub proof fn lemma_no_duplicates_injective<B>(self, f: spec_fn(A) -> B)
1958 requires
1959 injective(f),
1960 ensures
1961 self.no_duplicates() <==> self.map_values(f).no_duplicates(),
1962 {
1963 broadcast use group_seq_properties;
1964 broadcast use super::set_lib::group_set_properties;
1965
1966 let mapped = self.map_values(f);
1967 assert(mapped.len() == self.len());
1968 if mapped.no_duplicates() {
1969 assert forall|i: int, j: int| 0 <= i < j < mapped.len() implies self[i] != self[j] by {
1970 assert(mapped[i] == f(self[i]));
1971 assert(mapped[j] == f(self[j]));
1972 }
1973 }
1974 }
1975
1976 pub broadcast proof fn lemma_push_map_commute<B>(self, f: spec_fn(A) -> B, x: A)
1988 ensures
1989 self.map_values(f).push(f(x)) =~= #[trigger] self.push(x).map_values(f),
1990 decreases self.len(),
1991 {
1992 broadcast use group_seq_properties;
1993
1994 }
1995
1996 pub broadcast proof fn lemma_push_to_set_commute(self, elem: A)
2007 ensures
2008 #[trigger] self.push(elem).to_set() =~= self.to_set().insert(elem),
2009 {
2010 broadcast use {group_seq_properties, super::set::group_set_lemmas, Seq::to_set_ensures};
2011
2012 let lhs = self.push(elem).to_set();
2013 let rhs = self.to_set().insert(elem);
2014 assert forall|x: A| rhs.contains(x) implies lhs.contains(x) by {
2015 lemma_seq_contains_after_push(self, elem, x);
2016 }
2017 }
2018
2019 pub broadcast proof fn lemma_filter_push(self, elem: A, pred: spec_fn(A) -> bool)
2033 ensures
2034 #[trigger] self.push(elem).filter(pred) == if pred(elem) {
2035 self.filter(pred).push(elem)
2036 } else {
2037 self.filter(pred)
2038 },
2039 {
2040 broadcast use group_seq_properties;
2041
2042 reveal(Seq::filter);
2043 assert(self.push(elem).drop_last() =~= self);
2044 }
2045
2046 pub proof fn lemma_zip_with_contains_index<B>(self, b: Seq<B>, i: int)
2059 requires
2060 0 <= i < self.len(),
2061 self.len() == b.len(),
2062 ensures
2063 self.zip_with(b).contains((self[i], b[i])),
2064 {
2065 assert(self.zip_with(b)[i] == (self[i], b[i]));
2066 }
2067
2068 pub proof fn lemma_zip_with_uncurry_all<B>(self, b: Seq<B>, f: spec_fn(A, B) -> bool)
2085 requires
2086 self.len() == b.len(),
2087 ensures
2088 self.zip_with(b).all(|p: (A, B)| f(p.0, p.1)) <==> forall|i: int|
2089 0 <= i < self.len() ==> f(self[i], b[i]),
2090 {
2091 broadcast use group_seq_properties;
2092
2093 let zipped = self.zip_with(b);
2094 let f_uncurr = |p: (A, B)| f(p.0, p.1);
2095 let lhs = zipped.all(f_uncurr);
2096 let rhs = (forall|i: int| 0 <= i < self.len() ==> f(self[i], b[i]));
2097 if lhs {
2098 assert forall|i: int| 0 <= i < self.len() implies f(self[i], b[i]) by {
2099 self.lemma_zip_with_contains_index(b, i);
2100 assert(forall|j| 0 <= j < zipped.len() ==> f_uncurr(zipped[j]));
2101 }
2102 }
2103 }
2104
2105 pub proof fn lemma_flat_map_push<B>(self, f: spec_fn(A) -> Seq<B>, elem: A)
2119 ensures
2120 self.push(elem).flat_map(f) =~= self.flat_map(f) + f(elem),
2121 decreases self.len(),
2122 {
2123 broadcast use group_seq_properties;
2124 broadcast use Seq::lemma_flatten_push;
2125 broadcast use Seq::lemma_push_map_commute;
2126
2127 }
2128
2129 pub broadcast proof fn lemma_flat_map_take_append<B>(self, f: spec_fn(A) -> Seq<B>, i: int)
2144 requires
2145 0 <= i < self.len(),
2146 ensures
2147 #[trigger] self.take(i + 1).flat_map(f) =~= self.take(i).flat_map(f) + f(self[i]),
2148 decreases i,
2149 {
2150 broadcast use group_seq_properties;
2151
2152 self.lemma_take_succ_push(i);
2153 self.take(i).lemma_flat_map_push(f, self[i]);
2154 }
2155
2156 pub broadcast proof fn lemma_flat_map_singleton<B>(self, f: spec_fn(A) -> Seq<B>)
2159 requires
2160 #[trigger] self.len() == 1,
2161 ensures
2162 #[trigger] self.flat_map(f) == f(self[0]),
2163 {
2164 broadcast use Seq::lemma_flatten_singleton;
2165
2166 }
2167
2168 pub broadcast proof fn lemma_map_take_succ<B>(self, f: spec_fn(A) -> B, i: int)
2183 requires
2184 0 <= i < self.len(),
2185 ensures
2186 #[trigger] self.take(i + 1).map_values(f) =~= self.take(i).map_values(f).push(
2187 f(self[i]),
2188 ),
2189 {
2190 broadcast use group_seq_properties;
2191
2192 self.lemma_take_succ_push(i);
2193 }
2194
2195 pub broadcast proof fn lemma_prefix_index_eq(self, prefix: Seq<A>)
2208 requires
2209 #[trigger] prefix.is_prefix_of(self),
2210 ensures
2211 forall|i: int| 0 <= i < prefix.len() ==> prefix[i] == self[i],
2212 {
2213 }
2214
2215 pub broadcast proof fn lemma_prefix_concat(self, prefix1: Seq<A>, prefix2: Seq<A>)
2229 requires
2230 #[trigger] (prefix1 + prefix2).is_prefix_of(self),
2231 ensures
2232 prefix1.is_prefix_of(self),
2233 {
2234 broadcast use Seq::lemma_prefix_index_eq;
2235
2236 }
2237
2238 pub broadcast proof fn lemma_prefix_chain_contains(self, prefix1: Seq<A>, prefix2: Seq<A>, t: A)
2259 requires
2260 #[trigger] (prefix1 + seq![t]).is_prefix_of(self),
2261 #[trigger] prefix1.is_prefix_of(prefix2),
2262 prefix2.is_prefix_of(self),
2263 prefix1 != prefix2,
2264 !prefix1.contains(t),
2265 ensures
2266 prefix2.contains(t),
2267 {
2268 broadcast use Seq::lemma_prefix_concat;
2269 broadcast use Seq::lemma_prefix_index_eq;
2270
2271 assert(prefix2[prefix1.len() as int] == t);
2272 }
2273
2274 pub broadcast proof fn lemma_prefix_append_unique(self, prefix1: Seq<A>, prefix2: Seq<A>, t: A)
2278 requires
2279 #[trigger] (prefix1 + seq![t]).is_prefix_of(self),
2280 #[trigger] (prefix2 + seq![t]).is_prefix_of(self),
2281 !prefix1.contains(t),
2282 !prefix2.contains(t),
2283 ensures
2284 prefix1 == prefix2,
2285 {
2286 broadcast use Seq::lemma_prefix_concat;
2287 broadcast use Seq::lemma_prefix_index_eq;
2288 broadcast use Seq::lemma_prefix_chain_contains;
2289
2290 if prefix1 != prefix2 {
2291 assert(prefix1.is_prefix_of(prefix2) || prefix2.is_prefix_of(prefix1));
2292 }
2293 }
2294
2295 pub broadcast proof fn lemma_all_push(self, p: spec_fn(A) -> bool, elem: A)
2310 requires
2311 self.all(p),
2312 p(elem),
2313 ensures
2314 #[trigger] self.push(elem).all(p),
2315 {
2316 broadcast use group_seq_properties;
2317
2318 assert forall|x: A| self.push(elem).contains(x) implies p(x) by {
2319 lemma_seq_contains_after_push(self, elem, x);
2320 }
2321 }
2322
2323 pub proof fn lemma_concat_injective(self, s1: Seq<A>, s2: Seq<A>)
2326 ensures
2327 (self + s1 == self + s2) <==> (s1 == s2),
2328 {
2329 broadcast use group_seq_properties;
2330
2331 assert((self + s1).skip(self.len() as int) == s1);
2332 }
2333
2334 pub broadcast group group_seq_extra {
2335 Seq::<_>::lemma_seq_skip_skip,
2336 Seq::<_>::lemma_remove_duplicates_properties,
2337 Seq::<_>::lemma_filter_contains_rev,
2338 Seq::<_>::lemma_filter_map_take_succ,
2339 Seq::<_>::lemma_filter_prepend,
2340 Seq::<_>::lemma_filter_len_push,
2341 Seq::<_>::lemma_take_len,
2342 Seq::<_>::lemma_take_any_succ,
2343 Seq::<_>::lemma_push_map_commute,
2344 Seq::<_>::lemma_push_to_set_commute,
2345 Seq::<_>::lemma_filter_push,
2346 Seq::<_>::lemma_flat_map_take_append,
2347 Seq::<_>::lemma_flat_map_singleton,
2348 Seq::<_>::lemma_map_take_succ,
2349 Seq::<_>::lemma_prefix_index_eq,
2350 Seq::<_>::lemma_prefix_concat,
2351 Seq::<_>::lemma_prefix_chain_contains,
2352 Seq::<_>::lemma_prefix_append_unique,
2353 Seq::<_>::lemma_all_push,
2354 }
2355}
2356
2357impl<A> Seq<&A> {
2358 pub open spec fn unref(self) -> Seq<A> {
2360 Seq::new(self.len(), |i: int| *self[i])
2361 }
2362}
2363
2364impl<A, B> Seq<(&A, &B)> {
2365 pub open spec fn unref(self) -> Seq<(A, B)> {
2367 Seq::new(self.len(), |i: int| (*self[i].0, *self[i].1))
2368 }
2369}
2370
2371pub proof fn lemma_filter_view_commute<S: View>(
2388 s: Seq<S>,
2389 p: spec_fn(S) -> bool,
2390 sp: spec_fn(S::V) -> bool,
2391)
2392 requires
2393 forall|s: S| p(s) <==> sp(s.view()),
2394 ensures
2395 s.filter(p).map_values(|x: S| x.view()) == s.map_values(|x: S| x.view()).filter(sp),
2396 decreases s.len(),
2397{
2398 broadcast use group_seq_properties;
2399 broadcast use Seq::lemma_push_map_commute;
2400 broadcast use Seq::lemma_filter_push;
2401
2402 reveal(Seq::filter);
2403 let view = |x: S| x.view();
2404 if s.len() > 0 {
2405 let rest = s.drop_last();
2406 let last = s.last();
2407 assert(s =~= rest.push(last));
2408 assert(s.map_values(view).last() == view(last));
2409 lemma_filter_view_commute(rest, p, sp);
2410 }
2411}
2412
2413pub proof fn lemma_exactly_one_view<S: View>(
2428 s: Seq<S>,
2429 p: spec_fn(S) -> bool,
2430 sp: spec_fn(S::V) -> bool,
2431)
2432 requires
2433 forall|s: S| p(s) <==> sp(s.view()),
2434 injective(|x: S| x.view()),
2435 ensures
2436 s.exactly_one(p) <==> s.map_values(|x: S| x.view()).exactly_one(sp),
2437{
2438 lemma_filter_view_commute(s, p, sp);
2439}
2440
2441impl<A, B> Seq<(A, B)> {
2442 pub closed spec fn unzip(self) -> (Seq<A>, Seq<B>) {
2444 (Seq::new(self.len(), |i: int| self[i].0), Seq::new(self.len(), |i: int| self[i].1))
2445 }
2446
2447 pub proof fn unzip_ensures(self)
2449 ensures
2450 self.unzip().0.len() == self.unzip().1.len(),
2451 self.unzip().0.len() == self.len(),
2452 self.unzip().1.len() == self.len(),
2453 forall|i: int|
2454 0 <= i < self.len() ==> (#[trigger] self.unzip().0[i], #[trigger] self.unzip().1[i])
2455 == self[i],
2456 decreases self.len(),
2457 {
2458 if self.len() > 0 {
2459 self.drop_last().unzip_ensures();
2460 }
2461 }
2462
2463 pub proof fn lemma_zip_of_unzip(self)
2466 ensures
2467 self.unzip().0.zip_with(self.unzip().1) =~= self,
2468 {
2469 }
2470}
2471
2472impl<A> Seq<Seq<A>> {
2473 pub open spec fn flatten(self) -> Seq<A>
2487 decreases self.len(),
2488 {
2489 if self.len() == 0 {
2490 Seq::empty()
2491 } else {
2492 self.first().add(self.drop_first().flatten())
2493 }
2494 }
2495
2496 pub open spec fn flatten_alt(self) -> Seq<A>
2501 decreases self.len(),
2502 {
2503 if self.len() == 0 {
2504 Seq::empty()
2505 } else {
2506 self.drop_last().flatten_alt().add(self.last())
2507 }
2508 }
2509
2510 pub proof fn lemma_flatten_one_element(self)
2513 ensures
2514 self.len() == 1 ==> self.flatten() == self.first(),
2515 {
2516 broadcast use Seq::add_empty_right;
2517
2518 if self.len() == 1 {
2519 assert(self.flatten() =~= self.first().add(self.drop_first().flatten()));
2520 }
2521 }
2522
2523 pub proof fn lemma_flatten_length_ge_single_element_length(self, i: int)
2526 requires
2527 0 <= i < self.len(),
2528 ensures
2529 self.flatten_alt().len() >= self[i].len(),
2530 decreases self.len(),
2531 {
2532 if self.len() == 1 {
2533 self.lemma_flatten_one_element();
2534 self.lemma_flatten_and_flatten_alt_are_equivalent();
2535 } else if i < self.len() - 1 {
2536 self.drop_last().lemma_flatten_length_ge_single_element_length(i);
2537 } else {
2538 assert(self.flatten_alt() == self.drop_last().flatten_alt().add(self.last()));
2539 }
2540 }
2541
2542 pub proof fn lemma_flatten_length_le_mul(self, j: int)
2546 requires
2547 forall|i: int| 0 <= i < self.len() ==> (#[trigger] self[i]).len() <= j,
2548 ensures
2549 self.flatten_alt().len() <= self.len() * j,
2550 decreases self.len(),
2551 {
2552 broadcast use group_seq_properties;
2553
2554 if self.len() == 0 {
2555 } else {
2556 self.drop_last().lemma_flatten_length_le_mul(j);
2557 assert((self.len() - 1) * j == (self.len() * j) - (1 * j)) by (nonlinear_arith); }
2559 }
2560
2561 pub proof fn lemma_flatten_and_flatten_alt_are_equivalent(self)
2564 ensures
2565 self.flatten() =~= self.flatten_alt(),
2566 decreases self.len(),
2567 {
2568 broadcast use {Seq::add_empty_right, Seq::push_distributes_over_add};
2569
2570 if self.len() != 0 {
2571 self.drop_last().lemma_flatten_and_flatten_alt_are_equivalent();
2572 seq![self.last()].lemma_flatten_one_element();
2576 assert(seq![self.last()].flatten() == self.last());
2577 lemma_flatten_concat(self.drop_last(), seq![self.last()]);
2578 assert((self.drop_last() + seq![self.last()]).flatten() == self.drop_last().flatten()
2579 + self.last());
2580 assert(self.drop_last() + seq![self.last()] =~= self);
2581 assert(self.flatten_alt() == self.drop_last().flatten_alt() + self.last());
2582 }
2583 }
2584
2585 pub broadcast proof fn lemma_flatten_push(self, elem: Seq<A>)
2588 ensures
2589 #[trigger] self.push(elem).flatten() =~= self.flatten() + elem,
2590 decreases self.len(),
2591 {
2592 broadcast use group_seq_properties;
2593
2594 assert(self.push(elem).last() == elem);
2595 assert(self.push(elem).drop_last() =~= self);
2596 calc! {
2597 (==)
2598 self.push(elem).flatten(); {
2599 self.push(elem).lemma_flatten_and_flatten_alt_are_equivalent();
2600 }
2601 self.push(elem).flatten_alt(); {}
2602 self.flatten_alt() + elem; {
2603 self.lemma_flatten_and_flatten_alt_are_equivalent();
2604 }
2605 self.flatten() + elem;
2606 }
2607 }
2608
2609 pub broadcast proof fn lemma_flatten_singleton(self)
2611 requires
2612 #[trigger] self.len() == 1,
2613 ensures
2614 #[trigger] self.flatten() == self[0],
2615 {
2616 assert(self.flatten() == self[0] + self.drop_first().flatten());
2617 assert(self.flatten() == self[0]);
2618 }
2619
2620 pub broadcast group group_seq_flatten {
2621 Seq::<_>::lemma_flatten_push,
2622 Seq::<_>::lemma_flatten_singleton,
2623 }
2624}
2625
2626impl Seq<int> {
2629 pub open spec fn max(self) -> int
2631 recommends
2632 0 < self.len(),
2633 decreases self.len(),
2634 {
2635 if self.len() == 1 {
2636 self[0]
2637 } else if self.len() == 0 {
2638 0
2639 } else {
2640 let later_max = self.drop_first().max();
2641 if self[0] >= later_max {
2642 self[0]
2643 } else {
2644 later_max
2645 }
2646 }
2647 }
2648
2649 pub proof fn max_ensures(self)
2651 ensures
2652 forall|x: int| self.contains(x) ==> x <= self.max(),
2653 forall|i: int| 0 <= i < self.len() ==> self[i] <= self.max(),
2654 self.len() == 0 || self.contains(self.max()),
2655 decreases self.len(),
2656 {
2657 if self.len() <= 1 {
2658 } else {
2659 let elt = self.drop_first().max();
2660 assert(self.drop_first().contains(elt)) by { self.drop_first().max_ensures() }
2661 assert forall|i: int| 0 <= i < self.len() implies self[i] <= self.max() by {
2662 assert(i == 0 || self[i] == self.drop_first()[i - 1]);
2663 assert(forall|j: int|
2664 0 <= j < self.drop_first().len() ==> self.drop_first()[j]
2665 <= self.drop_first().max()) by { self.drop_first().max_ensures() }
2666 }
2667 }
2668 }
2669
2670 pub open spec fn min(self) -> int
2672 recommends
2673 0 < self.len(),
2674 decreases self.len(),
2675 {
2676 if self.len() == 1 {
2677 self[0]
2678 } else if self.len() == 0 {
2679 0
2680 } else {
2681 let later_min = self.drop_first().min();
2682 if self[0] <= later_min {
2683 self[0]
2684 } else {
2685 later_min
2686 }
2687 }
2688 }
2689
2690 pub proof fn min_ensures(self)
2692 ensures
2693 forall|x: int| self.contains(x) ==> self.min() <= x,
2694 forall|i: int| 0 <= i < self.len() ==> self.min() <= self[i],
2695 self.len() == 0 || self.contains(self.min()),
2696 decreases self.len(),
2697 {
2698 if self.len() <= 1 {
2699 } else {
2700 let elt = self.drop_first().min();
2701 assert(self.subrange(1, self.len() as int).contains(elt)) by {
2702 self.drop_first().min_ensures()
2703 }
2704 assert forall|i: int| 0 <= i < self.len() implies self.min() <= self[i] by {
2705 assert(i == 0 || self[i] == self.drop_first()[i - 1]);
2706 assert(forall|j: int|
2707 0 <= j < self.drop_first().len() ==> self.drop_first().min()
2708 <= self.drop_first()[j]) by { self.drop_first().min_ensures() }
2709 }
2710 }
2711 }
2712
2713 pub closed spec fn sort(self) -> Self {
2714 self.sort_by(|x: int, y: int| x <= y)
2715 }
2716
2717 pub proof fn lemma_sort_ensures(self)
2718 ensures
2719 self.to_multiset() =~= self.sort().to_multiset(),
2720 sorted_by(self.sort(), |x: int, y: int| x <= y),
2721 {
2722 self.lemma_sort_by_ensures(|x: int, y: int| x <= y);
2723 }
2724
2725 pub proof fn lemma_subrange_max(self, from: int, to: int)
2728 requires
2729 0 <= from < to <= self.len(),
2730 ensures
2731 self.subrange(from, to).max() <= self.max(),
2732 {
2733 self.max_ensures();
2734 self.subrange(from, to).max_ensures();
2735 }
2736
2737 pub proof fn lemma_subrange_min(self, from: int, to: int)
2740 requires
2741 0 <= from < to <= self.len(),
2742 ensures
2743 self.subrange(from, to).min() >= self.min(),
2744 {
2745 self.min_ensures();
2746 self.subrange(from, to).min_ensures();
2747 }
2748}
2749
2750spec fn merge_sorted_with<A>(left: Seq<A>, right: Seq<A>, leq: spec_fn(A, A) -> bool) -> Seq<A>
2752 recommends
2753 sorted_by(left, leq),
2754 sorted_by(right, leq),
2755 total_ordering(leq),
2756 decreases left.len(), right.len(),
2757{
2758 if left.len() == 0 {
2759 right
2760 } else if right.len() == 0 {
2761 left
2762 } else if leq(left.first(), right.first()) {
2763 Seq::<A>::empty().push(left.first()) + merge_sorted_with(left.drop_first(), right, leq)
2764 } else {
2765 Seq::<A>::empty().push(right.first()) + merge_sorted_with(left, right.drop_first(), leq)
2766 }
2767}
2768
2769proof fn lemma_merge_sorted_with_ensures<A>(left: Seq<A>, right: Seq<A>, leq: spec_fn(A, A) -> bool)
2770 requires
2771 sorted_by(left, leq),
2772 sorted_by(right, leq),
2773 total_ordering(leq),
2774 ensures
2775 (left + right).to_multiset() =~= merge_sorted_with(left, right, leq).to_multiset(),
2776 sorted_by(merge_sorted_with(left, right, leq), leq),
2777 decreases left.len(), right.len(),
2778{
2779 broadcast use group_seq_properties;
2781
2782 if left.len() == 0 {
2783 assert(left + right =~= right);
2784 } else if right.len() == 0 {
2785 assert(left + right =~= left);
2786 } else if leq(left.first(), right.first()) {
2787 let result = Seq::<A>::empty().push(left.first()) + merge_sorted_with(
2788 left.drop_first(),
2789 right,
2790 leq,
2791 );
2792 lemma_merge_sorted_with_ensures(left.drop_first(), right, leq);
2793 let rest = merge_sorted_with(left.drop_first(), right, leq);
2794 assert(rest.len() == 0 || rest.first() == left.drop_first().first() || rest.first()
2795 == right.first()) by {
2796 if left.drop_first().len() == 0 {
2797 } else if leq(left.drop_first().first(), right.first()) {
2798 assert(rest =~= Seq::<A>::empty().push(left.drop_first().first())
2799 + merge_sorted_with(left.drop_first().drop_first(), right, leq));
2800 } else {
2801 assert(rest =~= Seq::<A>::empty().push(right.first()) + merge_sorted_with(
2802 left.drop_first(),
2803 right.drop_first(),
2804 leq,
2805 ));
2806 }
2807 }
2808 lemma_new_first_element_still_sorted_by(left.first(), rest, leq);
2809 assert((left.drop_first() + right) =~= (left + right).drop_first());
2810 } else {
2811 let result = Seq::<A>::empty().push(right.first()) + merge_sorted_with(
2812 left,
2813 right.drop_first(),
2814 leq,
2815 );
2816 lemma_merge_sorted_with_ensures(left, right.drop_first(), leq);
2817 let rest = merge_sorted_with(left, right.drop_first(), leq);
2818 assert(rest.len() == 0 || rest.first() == left.first() || rest.first()
2819 == right.drop_first().first()) by {
2820 assert(left.len() > 0);
2821 if right.drop_first().len() == 0 { } else if leq(left.first(), right.drop_first().first()) { assert(rest =~= Seq::<A>::empty().push(left.first()) + merge_sorted_with(
2824 left.drop_first(),
2825 right.drop_first(),
2826 leq,
2827 ));
2828 } else {
2829 assert(rest =~= Seq::<A>::empty().push(right.drop_first().first())
2830 + merge_sorted_with(left, right.drop_first().drop_first(), leq));
2831 }
2832 }
2833 lemma_new_first_element_still_sorted_by(
2834 right.first(),
2835 merge_sorted_with(left, right.drop_first(), leq),
2836 leq,
2837 );
2838 lemma_seq_union_to_multiset_commutative(left, right);
2839 assert((right.drop_first() + left) =~= (right + left).drop_first());
2840 lemma_seq_union_to_multiset_commutative(right.drop_first(), left);
2841 }
2842}
2843
2844pub proof fn lemma_max_of_concat(x: Seq<int>, y: Seq<int>)
2847 requires
2848 0 < x.len() && 0 < y.len(),
2849 ensures
2850 x.max() <= (x + y).max(),
2851 y.max() <= (x + y).max(),
2852 forall|elt: int| (x + y).contains(elt) ==> elt <= (x + y).max(),
2853 decreases x.len(),
2854{
2855 broadcast use group_seq_properties;
2856
2857 x.max_ensures();
2858 y.max_ensures();
2859 (x + y).max_ensures();
2860 assert(x.drop_first().len() == x.len() - 1);
2861 if x.len() == 1 {
2862 assert(y.max() <= (x + y).max()) by {
2863 assert((x + y).contains(y.max()));
2864 }
2865 } else {
2866 assert(x.max() <= (x + y).max()) by {
2867 assert(x.contains(x.max()));
2868 assert((x + y).contains(x.max()));
2869 }
2870 assert(x.drop_first() + y =~= (x + y).drop_first());
2871 lemma_max_of_concat(x.drop_first(), y);
2872 }
2873}
2874
2875pub proof fn lemma_min_of_concat(x: Seq<int>, y: Seq<int>)
2878 requires
2879 0 < x.len() && 0 < y.len(),
2880 ensures
2881 (x + y).min() <= x.min(),
2882 (x + y).min() <= y.min(),
2883 forall|elt: int| (x + y).contains(elt) ==> (x + y).min() <= elt,
2884 decreases x.len(),
2885{
2886 x.min_ensures();
2887 y.min_ensures();
2888 (x + y).min_ensures();
2889 broadcast use group_seq_properties;
2890
2891 if x.len() == 1 {
2892 assert((x + y).min() <= y.min()) by {
2893 assert((x + y).contains(y.min()));
2894 }
2895 } else {
2896 assert((x + y).min() <= x.min()) by {
2897 assert((x + y).contains(x.min()));
2898 }
2899 assert((x + y).min() <= y.min()) by {
2900 assert((x + y).contains(y.min()));
2901 }
2902 assert(x.drop_first() + y =~= (x + y).drop_first());
2903 lemma_max_of_concat(x.drop_first(), y)
2904 }
2905}
2906
2907pub broadcast proof fn to_multiset_build<A>(s: Seq<A>, a: A)
2911 ensures
2912 #![trigger s.push(a).to_multiset()]
2913 s.push(a).to_multiset() =~= s.to_multiset().insert(a),
2914 decreases s.len(),
2915{
2916 broadcast use super::multiset::group_multiset_axioms;
2917
2918 if s.len() == 0 {
2919 assert(s.to_multiset() =~= Multiset::<A>::empty());
2920 assert(s.push(a).drop_first() =~= Seq::<A>::empty());
2921 assert(s.push(a).to_multiset() =~= Multiset::<A>::empty().insert(a).add(
2922 Seq::<A>::empty().to_multiset(),
2923 ));
2924 } else {
2925 to_multiset_build(s.drop_first(), a);
2926 assert(s.drop_first().push(a).to_multiset() =~= s.drop_first().to_multiset().insert(a));
2927 assert(s.push(a).drop_first() =~= s.drop_first().push(a));
2928 }
2929}
2930
2931pub broadcast proof fn to_multiset_remove<A>(s: Seq<A>, i: int)
2932 requires
2933 0 <= i < s.len(),
2934 ensures
2935 #![trigger s.remove(i).to_multiset()]
2936 s.remove(i).to_multiset() == s.to_multiset().remove(s[i]),
2937{
2938 broadcast use super::multiset::group_multiset_axioms;
2939
2940 let s0 = s.subrange(0, i);
2941 let s1 = s.subrange(i, s.len() as int);
2942 let s2 = s.subrange(i + 1, s.len() as int);
2943 lemma_seq_union_to_multiset_commutative(s0, s2);
2944 lemma_seq_union_to_multiset_commutative(s0, s1);
2945 assert(s == s0 + s1);
2946 assert(s2 + s0 == (s1 + s0).drop_first());
2947 assert(s.remove(i).to_multiset() =~= s.to_multiset().remove(s[i]));
2948}
2949
2950pub broadcast proof fn to_multiset_insert<A>(s: Seq<A>, i: int, a: A)
2951 requires
2952 0 <= i <= s.len(),
2953 ensures
2954 #![trigger s.insert(i, a).to_multiset()]
2955 s.insert(i, a).to_multiset() == s.to_multiset().insert(a),
2956 decreases s.len(),
2957{
2958 broadcast use super::multiset::group_multiset_axioms;
2959
2960 let s0 = s.subrange(0, i);
2961 let s1 = s.subrange(i, s.len() as int);
2962
2963 assert(s =~= s0 + s1);
2964 assert(s.insert(i, a) =~= s0 + seq![a] + s1);
2965 assert(((s0 + seq![a]) + s1).to_multiset() =~= ((seq![a] + s0) + s1).to_multiset()) by {
2966 broadcast use lemma_multiset_commutative;
2967
2968 };
2969 assert((seq![a] + s0 + s1).drop_first() == s0 + s1);
2970 assert(s.insert(i, a).to_multiset() =~= s.to_multiset().insert(a));
2971}
2972
2973pub broadcast proof fn to_multiset_len<A>(s: Seq<A>)
2975 ensures
2976 s.len() == #[trigger] s.to_multiset().len(),
2977 decreases s.len(),
2978{
2979 broadcast use super::multiset::group_multiset_axioms;
2980
2981 if s.len() == 0 {
2982 assert(s.to_multiset() =~= Multiset::<A>::empty());
2983 assert(s.len() == 0);
2984 } else {
2985 to_multiset_len(s.drop_first());
2986 assert(s.len() == s.drop_first().len() + 1);
2987 assert(s.to_multiset().len() == s.drop_first().to_multiset().len() + 1);
2988 }
2989}
2990
2991pub broadcast proof fn to_multiset_contains<A>(s: Seq<A>, a: A)
2993 ensures
2994 #![trigger s.to_multiset().count(a)]
2995 s.contains(a) <==> s.to_multiset().count(a) > 0,
2996 decreases s.len(),
2997{
2998 broadcast use super::multiset::group_multiset_axioms;
2999
3000 if s.len() != 0 {
3001 if s.contains(a) {
3003 if s.first() == a {
3004 to_multiset_build(s, a);
3005 assert(s.to_multiset() =~= Multiset::<A>::empty().insert(s.first()).add(
3006 s.drop_first().to_multiset(),
3007 ));
3008 assert(Multiset::<A>::empty().insert(s.first()).contains(s.first()));
3009 } else {
3010 to_multiset_contains(s.drop_first(), a);
3011 assert(s.skip(1) =~= s.drop_first());
3012 lemma_seq_skip_contains(s, 1, a);
3013 assert(s.to_multiset().count(a) == s.drop_first().to_multiset().count(a));
3014 assert(s.contains(a) <==> s.to_multiset().count(a) > 0);
3015 }
3016 }
3017 if s.to_multiset().count(a) > 0 {
3020 to_multiset_contains(s.drop_first(), a);
3021 assert(s.contains(a) <==> s.to_multiset().count(a) > 0);
3022 } else {
3023 assert(s.contains(a) <==> s.to_multiset().count(a) > 0);
3024 }
3025 }
3026}
3027
3028pub broadcast proof fn to_multiset_update<A>(s: Seq<A>, i: int, a: A)
3029 requires
3030 0 <= i < s.len(),
3031 ensures
3032 #[trigger] s.update(i, a).to_multiset() == s.to_multiset().insert(a).remove(s[i]),
3033 decreases s.len(),
3034{
3035 broadcast use {
3036 super::seq_lib::lemma_seq_take_len,
3037 super::multiset::group_multiset_properties,
3038 super::multiset::group_multiset_axioms,
3039 to_multiset_insert,
3040 to_multiset_remove,
3041 to_multiset_contains,
3042 lemma_update_is_remove_insert,
3043 };
3044
3045 assert(s.update(i, a).to_multiset() =~= s.to_multiset().insert(a).remove(s[i]));
3046
3047}
3048
3049pub broadcast proof fn lemma_update_is_remove_insert<A>(s: Seq<A>, i: int, a: A)
3051 requires
3052 0 <= i < s.len(),
3053 ensures
3054 #[trigger] s.update(i, a) =~= s.remove(i).insert(i, a),
3055 decreases s.len(),
3056{
3057}
3058
3059pub proof fn lemma_append_last<A>(s1: Seq<A>, s2: Seq<A>)
3062 requires
3063 0 < s2.len(),
3064 ensures
3065 (s1 + s2).last() == s2.last(),
3066{
3067}
3068
3069pub proof fn lemma_concat_associative<A>(s1: Seq<A>, s2: Seq<A>, s3: Seq<A>)
3071 ensures
3072 s1.add(s2.add(s3)) =~= s1.add(s2).add(s3),
3073{
3074}
3075
3076spec fn seq_to_set_rec<A>(seq: Seq<A>) -> Set<A>
3078 decreases seq.len(),
3079{
3080 if seq.len() == 0 {
3081 Set::empty()
3082 } else {
3083 seq_to_set_rec(seq.drop_last()).insert(seq.last())
3084 }
3085}
3086
3087proof fn seq_to_set_rec_contains<A>(seq: Seq<A>)
3089 ensures
3090 forall|a| #[trigger] seq.contains(a) <==> seq_to_set_rec(seq).contains(a),
3091 decreases seq.len(),
3092{
3093 broadcast use super::set::group_set_lemmas;
3094
3095 if seq.len() > 0 {
3096 assert(forall|a| #[trigger]
3097 seq.drop_last().contains(a) <==> seq_to_set_rec(seq.drop_last()).contains(a)) by {
3098 seq_to_set_rec_contains(seq.drop_last());
3099 }
3100 assert(seq =~= seq.drop_last().push(seq.last()));
3101 assert forall|a| #[trigger] seq.contains(a) <==> seq_to_set_rec(seq).contains(a) by {
3102 if !seq.drop_last().contains(a) {
3103 if a == seq.last() {
3104 assert(seq.contains(a));
3105 assert(seq_to_set_rec(seq).contains(a));
3106 } else {
3107 assert(!seq_to_set_rec(seq).contains(a));
3108 }
3109 }
3110 }
3111 }
3112}
3113
3114proof fn seq_to_set_equal_rec<A>(seq: Seq<A>)
3116 ensures
3117 seq.to_set() == seq_to_set_rec(seq),
3118 decreases seq.len(),
3119{
3120 broadcast use super::set::group_set_lemmas;
3121
3122 seq.to_set_ensures();
3123 assert(forall|n| seq.contains(n) <==> #[trigger] seq_to_set_rec(seq).contains(n)) by {
3124 seq_to_set_rec_contains(seq);
3125 }
3126 assert(seq.to_set() =~= seq_to_set_rec(seq));
3127}
3128
3129pub proof fn seq_to_set_distributes_over_add<T>(s1: Seq<T>, s2: Seq<T>)
3130 ensures
3131 s1.to_set() + s2.to_set() =~= (s1 + s2).to_set(),
3132{
3133 broadcast use super::group_vstd_default;
3134 broadcast use super::set_lib::group_set_properties;
3135 broadcast use group_seq_properties;
3136
3137}
3138
3139pub proof fn lemma_no_dup_in_concat<A>(a: Seq<A>, b: Seq<A>)
3143 requires
3144 a.no_duplicates(),
3145 b.no_duplicates(),
3146 forall|i: int, j: int| 0 <= i < a.len() && 0 <= j < b.len() ==> a[i] != b[j],
3147 ensures
3148 #[trigger] (a + b).no_duplicates(),
3149{
3150}
3151
3152pub proof fn lemma_flatten_concat<A>(x: Seq<Seq<A>>, y: Seq<Seq<A>>)
3156 ensures
3157 (x + y).flatten() =~= x.flatten() + y.flatten(),
3158 decreases x.len(),
3159{
3160 if x.len() == 0 {
3161 assert(x + y =~= y);
3162 } else {
3163 assert((x + y).drop_first() =~= x.drop_first() + y);
3164 assert(x.first() + (x.drop_first() + y).flatten() =~= x.first() + x.drop_first().flatten()
3165 + y.flatten()) by {
3166 lemma_flatten_concat(x.drop_first(), y);
3167 }
3168 }
3169}
3170
3171pub proof fn lemma_flatten_alt_concat<A>(x: Seq<Seq<A>>, y: Seq<Seq<A>>)
3176 ensures
3177 (x + y).flatten_alt() =~= x.flatten_alt() + y.flatten_alt(),
3178 decreases y.len(),
3179{
3180 if y.len() == 0 {
3181 assert(x + y =~= x);
3182 } else {
3183 assert((x + y).drop_last() =~= x + y.drop_last());
3184 assert((x + y.drop_last()).flatten_alt() + y.last() =~= x.flatten_alt()
3185 + y.drop_last().flatten_alt() + y.last()) by {
3186 lemma_flatten_alt_concat(x, y.drop_last());
3187 }
3188 }
3189}
3190
3191pub broadcast proof fn lemma_seq_union_to_multiset_commutative<A>(a: Seq<A>, b: Seq<A>)
3194 ensures
3195 #[trigger] (a + b).to_multiset() =~= (b + a).to_multiset(),
3196{
3197 broadcast use super::multiset::group_multiset_axioms;
3198
3199 lemma_multiset_commutative(a, b);
3200 lemma_multiset_commutative(b, a);
3201}
3202
3203pub broadcast proof fn lemma_multiset_commutative<A>(a: Seq<A>, b: Seq<A>)
3206 ensures
3207 #[trigger] (a + b).to_multiset() =~= a.to_multiset().add(b.to_multiset()),
3208 decreases a.len(),
3209{
3210 broadcast use super::multiset::group_multiset_axioms;
3211
3212 if a.len() == 0 {
3213 assert(a + b =~= b);
3214 } else {
3215 lemma_multiset_commutative(a.drop_first(), b);
3216 assert(a.drop_first() + b =~= (a + b).drop_first());
3217 }
3218}
3219
3220pub proof fn lemma_sorted_unique<A>(x: Seq<A>, y: Seq<A>, leq: spec_fn(A, A) -> bool)
3222 requires
3223 sorted_by(x, leq),
3224 sorted_by(y, leq),
3225 total_ordering(leq),
3226 x.to_multiset() == y.to_multiset(),
3227 ensures
3228 x =~= y,
3229 decreases x.len(), y.len(),
3230{
3231 broadcast use super::multiset::group_multiset_axioms;
3232 broadcast use group_to_multiset_ensures;
3233
3234 if x.len() == 0 || y.len() == 0 {
3235 } else {
3236 assert(x.to_multiset().contains(x[0]));
3237 assert(x.to_multiset().contains(y[0]));
3238 let i = choose|i: int| #![trigger x.spec_index(i) ] 0 <= i < x.len() && x[i] == y[0];
3239 assert(leq(x[i], x[0]));
3240 assert(leq(x[0], x[i]));
3241 assert(x.drop_first().to_multiset() =~= x.to_multiset().remove(x[0]));
3242 assert(y.drop_first().to_multiset() =~= y.to_multiset().remove(y[0]));
3243 lemma_sorted_unique(x.drop_first(), y.drop_first(), leq);
3244 assert(x.drop_first() =~= y.drop_first());
3245 assert(x.first() == y.first());
3246 assert(x =~= Seq::<A>::empty().push(x.first()).add(x.drop_first()));
3247 assert(x =~= y);
3248 }
3249}
3250
3251pub broadcast proof fn lemma_seq_contains<A>(s: Seq<A>, x: A)
3253 ensures
3254 #[trigger] s.contains(x) <==> exists|i: int| 0 <= i < s.len() && #[trigger] s[i] == x,
3255{
3256}
3257
3258pub broadcast proof fn lemma_seq_empty_contains_nothing<A>(x: A)
3261 ensures
3262 !(#[trigger] Seq::<A>::empty().contains(x)),
3263{
3264}
3265
3266pub broadcast proof fn lemma_seq_empty_equality<A>(s: Seq<A>)
3270 ensures
3271 #[trigger] s.len() == 0 ==> s =~= Seq::<A>::empty(),
3272{
3273}
3274
3275pub broadcast proof fn lemma_seq_concat_contains_all_elements<A>(x: Seq<A>, y: Seq<A>, elt: A)
3279 ensures
3280 #[trigger] (x + y).contains(elt) <==> x.contains(elt) || y.contains(elt),
3281 decreases x.len(),
3282{
3283 if x.len() == 0 && y.len() > 0 {
3284 assert((x + y) =~= y);
3285 } else {
3286 assert forall|elt: A| #[trigger] x.contains(elt) implies #[trigger] (x + y).contains(
3287 elt,
3288 ) by {
3289 let index = choose|i: int| 0 <= i < x.len() && x[i] == elt;
3290 assert((x + y)[index] == elt);
3291 }
3292 assert forall|elt: A| #[trigger] y.contains(elt) implies #[trigger] (x + y).contains(
3293 elt,
3294 ) by {
3295 let index = choose|i: int| 0 <= i < y.len() && y[i] == elt;
3296 assert((x + y)[index + x.len()] == elt);
3297 }
3298 }
3299}
3300
3301pub broadcast proof fn lemma_seq_contains_after_push<A>(s: Seq<A>, v: A, x: A)
3304 ensures
3305 #[trigger] s.push(v).contains(x) <==> v == x || s.contains(x),
3306{
3307 assert forall|elt: A| #[trigger] s.contains(elt) implies #[trigger] s.push(v).contains(elt) by {
3308 let index = choose|i: int| 0 <= i < s.len() && s[i] == elt;
3309 assert(s.push(v)[index] == elt);
3310 }
3311 assert(s.push(v)[s.len() as int] == v);
3312}
3313
3314pub broadcast proof fn lemma_seq_subrange_elements<A>(s: Seq<A>, start: int, stop: int, x: A)
3318 requires
3319 0 <= start <= stop <= s.len(),
3320 ensures
3321 #[trigger] s.subrange(start, stop).contains(x) <==> (exists|i: int|
3322 0 <= start <= i < stop <= s.len() && #[trigger] s[i] == x),
3323{
3324 assert((exists|i: int| 0 <= start <= i < stop <= s.len() && s[i] == x) ==> s.subrange(
3325 start,
3326 stop,
3327 ).contains(x)) by {
3328 if exists|i: int| 0 <= start <= i < stop <= s.len() && s[i] == x {
3329 let index = choose|i: int| 0 <= start <= i < stop <= s.len() && s[i] == x;
3330 assert(s.subrange(start, stop)[index - start] == s[index]);
3331 }
3332 }
3333}
3334
3335pub open spec fn commutative_foldr<A, B>(f: spec_fn(A, B) -> B) -> bool {
3337 forall|x: A, y: A, v: B| #[trigger] f(x, f(y, v)) == f(y, f(x, v))
3338}
3339
3340pub open spec fn commutative_foldl<A, B>(f: spec_fn(B, A) -> B) -> bool {
3342 forall|x: A, y: A, v: B| #[trigger] f(f(v, x), y) == f(f(v, y), x)
3343}
3344
3345pub proof fn lemma_fold_right_permutation<A, B>(l1: Seq<A>, l2: Seq<A>, f: spec_fn(A, B) -> B, v: B)
3348 requires
3349 commutative_foldr(f),
3350 l1.to_multiset() == l2.to_multiset(),
3351 ensures
3352 l1.fold_right(f, v) == l2.fold_right(f, v),
3353 decreases l1.len(),
3354{
3355 broadcast use group_to_multiset_ensures;
3356
3357 if l1.len() > 0 {
3358 let a = l1.last();
3359 let i = l2.index_of(a);
3360 let l2r = l2.subrange(i + 1, l2.len() as int).fold_right(f, v);
3361
3362 assert(l1.to_multiset().count(a) > 0);
3363 l1.drop_last().lemma_fold_right_commute_one(a, f, v);
3364 l2.subrange(0, i).lemma_fold_right_commute_one(a, f, l2r);
3365
3366 l2.lemma_fold_right_split(f, v, i + 1);
3367 l2.remove(i).lemma_fold_right_split(f, v, i);
3368
3369 assert(l2.subrange(0, i + 1).drop_last() == l2.subrange(0, i));
3370 assert(l1.drop_last() == l1.remove(l1.len() - 1));
3371
3372 assert(l2.remove(i).subrange(0, i) == l2.subrange(0, i));
3373 assert(l2.remove(i).subrange(i, l2.remove(i).len() as int) == l2.subrange(
3374 i + 1,
3375 l2.len() as int,
3376 ));
3377
3378 lemma_fold_right_permutation(l1.drop_last(), l2.remove(i), f, v);
3379 } else {
3380 assert(l2.to_multiset().len() == 0);
3381 }
3382}
3383
3384pub proof fn lemma_fold_left_permutation<A, B>(l1: Seq<A>, l2: Seq<A>, f: spec_fn(B, A) -> B, v: B)
3387 requires
3388 commutative_foldl(f),
3389 l1.to_multiset() == l2.to_multiset(),
3390 ensures
3391 l1.fold_left(v, f) == l2.fold_left(v, f),
3392{
3393 let g = |a: A, b: B| f(b, a);
3394 assert(f =~= |b: B, a: A| g(a, b));
3395 assert(l1.fold_left(v, f) == l1.reverse().fold_right(g, v)) by {
3396 l1.lemma_reverse_fold_right(v, g)
3397 };
3398 assert(l2.fold_left(v, f) == l2.reverse().fold_right(g, v)) by {
3399 l2.lemma_reverse_fold_right(v, g)
3400 };
3401 assert(l1.reverse().to_multiset() =~= l2.reverse().to_multiset()) by {
3402 l1.lemma_reverse_to_multiset();
3403 l2.lemma_reverse_to_multiset();
3404 }
3405 assert(forall|x: A| #[trigger] l1.reverse().contains(x) ==> l1.contains(x));
3406 assert(forall|x: A| #[trigger] l2.reverse().contains(x) ==> l2.contains(x));
3407 lemma_fold_right_permutation(l1.reverse(), l2.reverse(), g, v);
3408}
3409
3410pub broadcast proof fn lemma_seq_take_len<A>(s: Seq<A>, n: int)
3416 ensures
3417 0 <= n <= s.len() ==> #[trigger] s.take(n).len() == n,
3418{
3419}
3420
3421pub broadcast proof fn lemma_seq_take_contains<A>(s: Seq<A>, n: int, x: A)
3425 requires
3426 0 <= n <= s.len(),
3427 ensures
3428 #[trigger] s.take(n).contains(x) <==> (exists|i: int|
3429 0 <= i < n <= s.len() && #[trigger] s[i] == x),
3430{
3431 assert((exists|i: int| 0 <= i < n <= s.len() && #[trigger] s[i] == x) ==> s.take(n).contains(x))
3432 by {
3433 if exists|i: int| 0 <= i < n <= s.len() && #[trigger] s[i] == x {
3434 let index = choose|i: int| 0 <= i < n <= s.len() && #[trigger] s[i] == x;
3435 assert(s.take(n)[index] == s[index]);
3436 }
3437 }
3438}
3439
3440pub broadcast proof fn lemma_seq_take_index<A>(s: Seq<A>, n: int, j: int)
3444 ensures
3445 0 <= j < n <= s.len() ==> #[trigger] s.take(n)[j] == s[j],
3446{
3447}
3448
3449pub proof fn subrange_of_matching_take<T>(a: Seq<T>, b: Seq<T>, s: int, e: int, l: int)
3450 requires
3451 a.take(l) == b.take(l),
3452 l <= a.len(),
3453 l <= b.len(),
3454 0 <= s <= e <= l,
3455 ensures
3456 a.subrange(s, e) == b.subrange(s, e),
3457{
3458 assert forall|i| 0 <= i < e - s implies a.subrange(s, e)[i] == b.subrange(s, e)[i] by {
3459 assert(a.subrange(s, e)[i] == a.take(l)[i + s]);
3460 }
3462 assert(a.subrange(s, e) == b.subrange(s, e));
3465}
3466
3467pub broadcast proof fn lemma_seq_skip_len<A>(s: Seq<A>, n: int)
3471 ensures
3472 0 <= n <= s.len() ==> #[trigger] s.skip(n).len() == s.len() - n,
3473{
3474}
3475
3476pub broadcast proof fn lemma_seq_skip_contains<A>(s: Seq<A>, n: int, x: A)
3480 requires
3481 0 <= n <= s.len(),
3482 ensures
3483 #[trigger] s.skip(n).contains(x) <==> (exists|i: int|
3484 0 <= n <= i < s.len() && #[trigger] s[i] == x),
3485{
3486 assert((exists|i: int| 0 <= n <= i < s.len() && #[trigger] s[i] == x) ==> s.skip(n).contains(x))
3487 by {
3488 let index = choose|i: int| 0 <= n <= i < s.len() && #[trigger] s[i] == x;
3489 lemma_seq_skip_index(s, n, index - n);
3490 }
3491}
3492
3493pub broadcast proof fn lemma_seq_skip_index<A>(s: Seq<A>, n: int, j: int)
3497 ensures
3498 0 <= n && 0 <= j < (s.len() - n) ==> #[trigger] s.skip(n)[j] == s[j + n],
3499{
3500}
3501
3502pub broadcast proof fn lemma_seq_skip_index2<A>(s: Seq<A>, n: int, k: int)
3507 ensures
3508 0 <= n <= k < s.len() ==> (#[trigger] s.skip(n))[k - n] == #[trigger] s[k],
3509{
3510}
3511
3512pub broadcast proof fn lemma_seq_append_take_skip<A>(a: Seq<A>, b: Seq<A>, n: int)
3517 ensures
3518 #![trigger (a + b).take(n)]
3519 #![trigger (a + b).skip(n)]
3520 n == a.len() ==> ((a + b).take(n) =~= a && (a + b).skip(n) =~= b),
3521{
3522}
3523
3524pub broadcast proof fn lemma_seq_take_update_commut1<A>(s: Seq<A>, i: int, v: A, n: int)
3531 ensures
3532 #![trigger s.update(i, v).take(n)]
3533 0 <= i < n <= s.len() ==> #[trigger] s.update(i, v).take(n) =~= s.take(n).update(i, v),
3534{
3535}
3536
3537pub broadcast proof fn lemma_seq_take_update_commut2<A>(s: Seq<A>, i: int, v: A, n: int)
3542 ensures
3543 0 <= n <= i < s.len() ==> #[trigger] s.update(i, v).take(n) =~= s.take(n),
3544{
3545}
3546
3547pub broadcast proof fn lemma_seq_skip_update_commut1<A>(s: Seq<A>, i: int, v: A, n: int)
3552 ensures
3553 0 <= n <= i < s.len() ==> #[trigger] s.update(i, v).skip(n) =~= s.skip(n).update(i - n, v),
3554{
3555}
3556
3557pub broadcast proof fn lemma_seq_skip_update_commut2<A>(s: Seq<A>, i: int, v: A, n: int)
3562 ensures
3563 0 <= i < n <= s.len() ==> #[trigger] s.update(i, v).skip(n) =~= s.skip(n),
3564{
3565}
3566
3567pub broadcast proof fn lemma_seq_skip_build_commut<A>(s: Seq<A>, v: A, n: int)
3571 ensures
3572 #![trigger s.push(v).skip(n)]
3573 0 <= n <= s.len() ==> s.push(v).skip(n) =~= s.skip(n).push(v),
3574{
3575}
3576
3577pub broadcast proof fn lemma_seq_skip_nothing<A>(s: Seq<A>, n: int)
3580 ensures
3581 n == 0 ==> #[trigger] s.skip(n) =~= s,
3582{
3583}
3584
3585pub broadcast proof fn lemma_seq_take_nothing<A>(s: Seq<A>, n: int)
3588 ensures
3589 n == 0 ==> #[trigger] s.take(n) =~= Seq::<A>::empty(),
3590{
3591}
3592
3593pub broadcast proof fn lemma_seq_skip_of_skip<A>(s: Seq<A>, m: int, n: int)
3598 ensures
3599 (0 <= m && 0 <= n && m + n <= s.len()) ==> #[trigger] s.skip(m).skip(n) =~= s.skip(m + n),
3600{
3601}
3602
3603#[doc(hidden)]
3604#[verifier::inline]
3605pub open spec fn check_argument_is_seq<A>(s: Seq<A>) -> Seq<A> {
3606 s
3607}
3608
3609#[macro_export]
3654macro_rules! assert_seqs_equal {
3655 [$($tail:tt)*] => {
3656 $crate::vstd::prelude::verus_proof_macro_exprs!($crate::vstd::seq_lib::assert_seqs_equal_internal!($($tail)*))
3657 };
3658}
3659
3660#[macro_export]
3661#[doc(hidden)]
3662macro_rules! assert_seqs_equal_internal {
3663 (::vstd::spec_eq($s1:expr, $s2:expr)) => {
3664 $crate::vstd::seq_lib::assert_seqs_equal_internal!($s1, $s2)
3665 };
3666 (::vstd::prelude::spec_eq($s1:expr, $s2:expr)) => {
3667 $crate::vstd::seq_lib::assert_seqs_equal_internal!($s1, $s2)
3668 };
3669 (::vstd::prelude::spec_eq($s1:expr, $s2:expr), $idx:ident => $bblock:block) => {
3670 $crate::vstd::seq_lib::assert_seqs_equal_internal!($s1, $s2, $idx => $bblock)
3671 };
3672 (crate::prelude::spec_eq($s1:expr, $s2:expr)) => {
3673 $crate::vstd::seq_lib::assert_seqs_equal_internal!($s1, $s2)
3674 };
3675 (crate::prelude::spec_eq($s1:expr, $s2:expr), $idx:ident => $bblock:block) => {
3676 $crate::vstd::seq_lib::assert_seqs_equal_internal!($s1, $s2, $idx => $bblock)
3677 };
3678 (crate::verus_builtin::spec_eq($s1:expr, $s2:expr)) => {
3679 $crate::vstd::seq_lib::assert_seqs_equal_internal!($s1, $s2)
3680 };
3681 (crate::verus_builtin::spec_eq($s1:expr, $s2:expr), $idx:ident => $bblock:block) => {
3682 $crate::vstd::seq_lib::assert_seqs_equal_internal!($s1, $s2, $idx => $bblock)
3683 };
3684 ($s1:expr, $s2:expr $(,)?) => {
3685 $crate::vstd::seq_lib::assert_seqs_equal_internal!($s1, $s2, idx => { })
3686 };
3687 ($s1:expr, $s2:expr, $idx:ident => $bblock:block) => {
3688 #[verifier::spec] let s1 = $crate::vstd::seq_lib::check_argument_is_seq($s1);
3689 #[verifier::spec] let s2 = $crate::vstd::seq_lib::check_argument_is_seq($s2);
3690 $crate::vstd::prelude::assert_by($crate::vstd::prelude::equal(s1, s2), {
3691 $crate::vstd::prelude::assert_(s1.len() == s2.len());
3692 $crate::vstd::prelude::assert_forall_by(|$idx : $crate::vstd::prelude::int| {
3693 $crate::vstd::prelude::requires($crate::vstd::prelude::verus_proof_expr!(0 <= $idx && $idx < s1.len()));
3694 $crate::vstd::prelude::ensures($crate::vstd::prelude::equal(s1.index($idx), s2.index($idx)));
3695 { $bblock }
3696 });
3697 $crate::vstd::prelude::assert_($crate::vstd::prelude::ext_equal(s1, s2));
3698 });
3699 }
3700}
3701
3702pub broadcast group group_filter_ensures {
3703 Seq::lemma_filter_len,
3704 Seq::lemma_filter_pred,
3705 Seq::lemma_filter_contains,
3706}
3707
3708pub broadcast group group_seq_lib_default {
3709 Seq::to_set_ensures,
3710 group_filter_ensures,
3711 Seq::add_empty_left,
3712 Seq::add_empty_right,
3713 Seq::push_distributes_over_add,
3714 Seq::filter_distributes_over_add,
3715 Seq::lemma_fold_right_split,
3716 Seq::lemma_fold_left_split,
3717}
3718
3719pub broadcast group group_to_multiset_ensures {
3720 to_multiset_build,
3721 to_multiset_remove,
3722 to_multiset_len,
3723 to_multiset_contains,
3724 to_multiset_insert,
3725 to_multiset_update,
3726}
3727
3728pub broadcast group group_seq_properties {
3730 lemma_seq_contains,
3731 lemma_seq_empty_contains_nothing,
3732 lemma_seq_empty_equality,
3733 lemma_seq_concat_contains_all_elements,
3734 lemma_seq_contains_after_push,
3735 lemma_seq_subrange_elements,
3736 lemma_seq_take_len,
3737 lemma_seq_take_contains,
3738 lemma_seq_take_index,
3739 lemma_seq_skip_len,
3740 lemma_seq_skip_contains,
3741 lemma_seq_skip_index,
3742 lemma_seq_skip_index2,
3743 lemma_seq_append_take_skip,
3744 lemma_seq_take_update_commut1,
3745 lemma_seq_take_update_commut2,
3746 lemma_seq_skip_update_commut1,
3747 lemma_seq_skip_update_commut2,
3748 lemma_seq_skip_build_commut,
3749 lemma_seq_skip_nothing,
3750 lemma_seq_take_nothing,
3751 group_to_multiset_ensures,
3755}
3756
3757#[doc(hidden)]
3758pub use assert_seqs_equal_internal;
3759pub use assert_seqs_equal;
3760
3761}