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::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> {
26 Seq::new(self.len(), |i: int| f(i, self[i]))
27 }
28
29 pub open spec fn map_values<B>(self, f: spec_fn(A) -> B) -> Seq<B> {
33 Seq::new(self.len(), |i: int| f(self[i]))
34 }
35
36 pub open spec fn flat_map<B>(self, f: spec_fn(A) -> Seq<B>) -> Seq<B> {
50 self.map_values(f).flatten()
51 }
52
53 pub open spec fn as_ref(&self) -> Seq<&A> {
55 Seq::new(self.len(), |i: int| &self[i])
56 }
57
58 pub open spec fn is_prefix_of(self, other: Self) -> bool {
70 self.len() <= other.len() && self =~= other.subrange(0, self.len() as int)
71 }
72
73 pub open spec fn is_suffix_of(self, other: Self) -> bool {
85 self.len() <= other.len() && self =~= other.subrange(
86 (other.len() - self.len()) as int,
87 other.len() as int,
88 )
89 }
90
91 pub closed spec fn sort_by(self, leq: spec_fn(A, A) -> bool) -> Seq<A>
99 recommends
100 total_ordering(leq),
101 decreases self.len(),
102 {
103 if self.len() <= 1 {
104 self
105 } else {
106 let split_index = self.len() / 2;
107 let left = self.subrange(0, split_index as int);
108 let right = self.subrange(split_index as int, self.len() as int);
109 let left_sorted = left.sort_by(leq);
110 let right_sorted = right.sort_by(leq);
111 merge_sorted_with(left_sorted, right_sorted, leq)
112 }
113 }
114
115 pub open spec fn all(self, pred: spec_fn(A) -> bool) -> bool {
126 forall|i: int| 0 <= i < self.len() ==> #[trigger] pred(self[i])
127 }
128
129 pub open spec fn any(self, pred: spec_fn(A) -> bool) -> bool {
140 exists|i: int| 0 <= i < self.len() && #[trigger] pred(self[i])
141 }
142
143 pub open spec fn exactly_one(self, pred: spec_fn(A) -> bool) -> bool {
153 self.filter(pred).len() == 1
154 }
155
156 pub proof fn lemma_sort_by_ensures(self, leq: spec_fn(A, A) -> bool)
157 requires
158 total_ordering(leq),
159 ensures
160 self.to_multiset() =~= self.sort_by(leq).to_multiset(),
161 sorted_by(self.sort_by(leq), leq),
162 forall|x: A| !self.contains(x) ==> !(#[trigger] self.sort_by(leq).contains(x)),
163 decreases self.len(),
164 {
165 if self.len() <= 1 {
166 } else {
167 let split_index = self.len() / 2;
168 let left = self.subrange(0, split_index as int);
169 let right = self.subrange(split_index as int, self.len() as int);
170 assert(self =~= left + right);
171 let left_sorted = left.sort_by(leq);
172 left.lemma_sort_by_ensures(leq);
173 let right_sorted = right.sort_by(leq);
174 right.lemma_sort_by_ensures(leq);
175 lemma_merge_sorted_with_ensures(left_sorted, right_sorted, leq);
176 lemma_multiset_commutative(left, right);
177 lemma_multiset_commutative(left_sorted, right_sorted);
178 assert forall|x: A| !self.contains(x) implies !(#[trigger] self.sort_by(leq).contains(
179 x,
180 )) by {
181 broadcast use group_to_multiset_ensures;
182
183 assert(!self.contains(x) ==> self.to_multiset().count(x) == 0);
184 }
185 }
186 }
187
188 #[verifier::opaque]
202 pub open spec fn filter(self, pred: spec_fn(A) -> bool) -> Self
203 decreases self.len(),
204 {
205 if self.len() == 0 {
206 self
207 } else {
208 let subseq = self.drop_last().filter(pred);
209 if pred(self.last()) {
210 subseq.push(self.last())
211 } else {
212 subseq
213 }
214 }
215 }
216
217 pub broadcast proof fn lemma_filter_len(self, pred: spec_fn(A) -> bool)
218 ensures
219 #[trigger] self.filter(pred).len() <= self.len(),
222 decreases self.len(),
223 {
224 reveal(Seq::filter);
225 let out = self.filter(pred);
226 if 0 < self.len() {
227 self.drop_last().lemma_filter_len(pred);
228 }
229 }
230
231 pub broadcast proof fn lemma_filter_pred(self, pred: spec_fn(A) -> bool, i: int)
232 requires
233 0 <= i < self.filter(pred).len(),
234 ensures
235 pred(#[trigger] self.filter(pred)[i]),
236 {
237 #[allow(deprecated)]
239 self.filter_lemma(pred);
240 }
241
242 pub broadcast proof fn lemma_filter_contains(self, pred: spec_fn(A) -> bool, i: int)
243 requires
244 0 <= i < self.len() && pred(self[i]),
245 ensures
246 #[trigger] self.filter(pred).contains(self[i]),
247 {
248 #[allow(deprecated)]
250 self.filter_lemma(pred);
251 }
252
253 #[cfg_attr(not(verus_verify_core), deprecated = "Use `broadcast use group_filter_ensures` instead" )]
255 pub proof fn filter_lemma(self, pred: spec_fn(A) -> bool)
256 ensures
257 forall|i: int|
263 0 <= i < self.filter(pred).len() ==> pred(#[trigger] self.filter(pred)[i]),
264 forall|i: int|
266 0 <= i < self.len() && pred(self[i]) ==> #[trigger] self.filter(pred).contains(
267 self[i],
268 ),
269 #[trigger] self.filter(pred).len() <= self.len(),
271 decreases self.len(),
272 {
273 reveal(Seq::filter);
274 let out = self.filter(pred);
275 if 0 < self.len() {
276 self.drop_last().filter_lemma(pred);
277 assert forall|i: int| 0 <= i < out.len() implies pred(out[i]) by {
278 if i < out.len() - 1 {
279 assert(self.drop_last().filter(pred)[i] == out.drop_last()[i]); assert(pred(out[i])); }
282 }
283 assert forall|i: int|
284 0 <= i < self.len() && pred(self[i]) implies #[trigger] out.contains(self[i]) by {
285 if i == self.len() - 1 {
286 assert(self[i] == out[out.len() - 1]); } else {
288 let subseq = self.drop_last().filter(pred);
289 assert(subseq.contains(self.drop_last()[i])); let j = choose|j| 0 <= j < subseq.len() && subseq[j] == self[i];
291 assert(out[j] == self[i]); }
293 }
294 }
295 }
296
297 pub broadcast proof fn filter_distributes_over_add(a: Self, b: Self, pred: spec_fn(A) -> bool)
298 ensures
299 #[trigger] (a + b).filter(pred) == a.filter(pred) + b.filter(pred),
300 decreases b.len(),
301 {
302 reveal(Seq::filter);
303 if 0 < b.len() {
304 Self::drop_last_distributes_over_add(a, b);
305 Self::filter_distributes_over_add(a, b.drop_last(), pred);
306 if pred(b.last()) {
307 Self::push_distributes_over_add(
308 a.filter(pred),
309 b.drop_last().filter(pred),
310 b.last(),
311 );
312 }
313 } else {
314 Self::add_empty_right(a, b);
315 Self::add_empty_right(a.filter(pred), b.filter(pred));
316 }
317 }
318
319 pub broadcast proof fn add_empty_left(a: Self, b: Self)
320 requires
321 a.len() == 0,
322 ensures
323 #[trigger] (a + b) == b,
324 {
325 assert(a + b =~= b);
326 }
327
328 pub broadcast proof fn add_empty_right(a: Self, b: Self)
329 requires
330 b.len() == 0,
331 ensures
332 #[trigger] (a + b) == a,
333 {
334 assert(a + b =~= a);
335 }
336
337 pub broadcast proof fn push_distributes_over_add(a: Self, b: Self, elt: A)
338 ensures
339 #[trigger] (a + b).push(elt) == a + b.push(elt),
340 {
341 assert((a + b).push(elt) =~= a + b.push(elt));
342 }
343
344 pub open spec fn max_via(self, leq: spec_fn(A, A) -> bool) -> A
346 recommends
347 self.len() > 0,
348 decreases self.len(),
349 {
350 if self.len() > 1 {
351 if leq(self[0], self.subrange(1, self.len() as int).max_via(leq)) {
352 self.subrange(1, self.len() as int).max_via(leq)
353 } else {
354 self[0]
355 }
356 } else {
357 self[0]
358 }
359 }
360
361 pub open spec fn min_via(self, leq: spec_fn(A, A) -> bool) -> A
363 recommends
364 self.len() > 0,
365 decreases self.len(),
366 {
367 if self.len() > 1 {
368 let subseq = self.subrange(1, self.len() as int);
369 let elt = subseq.min_via(leq);
370 if leq(elt, self[0]) {
371 elt
372 } else {
373 self[0]
374 }
375 } else {
376 self[0]
377 }
378 }
379
380 pub open spec fn contains(self, needle: A) -> bool {
382 exists|i: int| 0 <= i < self.len() && self[i] == needle
383 }
384
385 pub open spec fn index_of(self, needle: A) -> int {
388 choose|i: int| 0 <= i < self.len() && self[i] == needle
389 }
390
391 pub closed spec fn index_of_first(self, needle: A) -> (result: Option<int>) {
394 if self.contains(needle) {
395 Some(self.first_index_helper(needle))
396 } else {
397 None
398 }
399 }
400
401 spec fn first_index_helper(self, needle: A) -> int
403 recommends
404 self.contains(needle),
405 decreases self.len(),
406 {
407 if self.len() <= 0 {
408 -1 } else if self[0] == needle {
411 0
412 } else {
413 1 + self.subrange(1, self.len() as int).first_index_helper(needle)
414 }
415 }
416
417 pub proof fn index_of_first_ensures(self, needle: A)
418 ensures
419 match self.index_of_first(needle) {
420 Some(index) => {
421 &&& self.contains(needle)
422 &&& 0 <= index < self.len()
423 &&& self[index] == needle
424 &&& forall|j: int| 0 <= j < index < self.len() ==> self[j] != needle
425 },
426 None => { !self.contains(needle) },
427 },
428 decreases self.len(),
429 {
430 if self.contains(needle) {
431 let index = self.index_of_first(needle).unwrap();
432 if self.len() <= 0 {
433 } else if self[0] == needle {
434 } else {
435 assert(Seq::empty().push(self.first()).add(self.drop_first()) =~= self);
436 self.drop_first().index_of_first_ensures(needle);
437 }
438 }
439 }
440
441 pub closed spec fn index_of_last(self, needle: A) -> Option<int> {
444 if self.contains(needle) {
445 Some(self.last_index_helper(needle))
446 } else {
447 None
448 }
449 }
450
451 spec fn last_index_helper(self, needle: A) -> int
453 recommends
454 self.contains(needle),
455 decreases self.len(),
456 {
457 if self.len() <= 0 {
458 -1 } else if self.last() == needle {
461 self.len() - 1
462 } else {
463 self.drop_last().last_index_helper(needle)
464 }
465 }
466
467 pub proof fn index_of_last_ensures(self, needle: A)
468 ensures
469 match self.index_of_last(needle) {
470 Some(index) => {
471 &&& self.contains(needle)
472 &&& 0 <= index < self.len()
473 &&& self[index] == needle
474 &&& forall|j: int| 0 <= index < j < self.len() ==> self[j] != needle
475 },
476 None => { !self.contains(needle) },
477 },
478 decreases self.len(),
479 {
480 if self.contains(needle) {
481 let index = self.index_of_last(needle).unwrap();
482 if self.len() <= 0 {
483 } else if self.last() == needle {
484 } else {
485 assert(self.drop_last().push(self.last()) =~= self);
486 self.drop_last().index_of_last_ensures(needle);
487 }
488 }
489 }
490
491 pub open spec fn drop_last(self) -> Seq<A>
496 recommends
497 self.len() >= 1,
498 {
499 self.subrange(0, self.len() as int - 1)
500 }
501
502 pub proof fn drop_last_distributes_over_add(a: Self, b: Self)
505 requires
506 0 < b.len(),
507 ensures
508 (a + b).drop_last() == a + b.drop_last(),
509 {
510 assert_seqs_equal!((a+b).drop_last(), a+b.drop_last());
511 }
512
513 pub open spec fn drop_first(self) -> Seq<A>
514 recommends
515 self.len() >= 1,
516 {
517 self.subrange(1, self.len() as int)
518 }
519
520 pub open spec fn no_duplicates(self) -> bool {
522 forall|i, j| (0 <= i < self.len() && 0 <= j < self.len() && i != j) ==> self[i] != self[j]
523 }
524
525 pub open spec fn disjoint(self, other: Self) -> bool {
527 forall|i: int, j: int| 0 <= i < self.len() && 0 <= j < other.len() ==> self[i] != other[j]
528 }
529
530 pub open spec fn to_set(self) -> Set<A> {
532 Set::new(|a: A| self.contains(a))
533 }
534
535 pub closed spec fn to_multiset(self) -> Multiset<A>
537 decreases self.len(),
538 {
539 if self.len() == 0 {
540 Multiset::<A>::empty()
541 } else {
542 Multiset::<A>::empty().insert(self.first()).add(self.drop_first().to_multiset())
543 }
544 }
545
546 pub broadcast proof fn to_multiset_ensures(self)
550 ensures
551 forall|a: A| #[trigger] (self.push(a).to_multiset()) =~= self.to_multiset().insert(a), forall|i: int|
553 0 <= i < self.len() ==> #[trigger] (self.remove(i).to_multiset())
554 =~= self.to_multiset().remove(self[i]), self.len() == #[trigger] self.to_multiset().len(), forall|a: A|
557 self.contains(a) <==> #[trigger] self.to_multiset().count(a)
558 > 0, {
560 broadcast use group_seq_properties;
561
562 }
563
564 pub open spec fn insert(self, i: int, a: A) -> Seq<A>
566 recommends
567 0 <= i <= self.len(),
568 {
569 self.subrange(0, i).push(a) + self.subrange(i, self.len() as int)
570 }
571
572 pub proof fn insert_ensures(self, pos: int, elt: A)
574 requires
575 0 <= pos <= self.len(),
576 ensures
577 self.insert(pos, elt).len() == self.len() + 1,
578 forall|i: int| 0 <= i < pos ==> #[trigger] self.insert(pos, elt)[i] == self[i],
579 forall|i: int| pos <= i < self.len() ==> self.insert(pos, elt)[i + 1] == self[i],
580 self.insert(pos, elt)[pos] == elt,
581 {
582 }
583
584 pub open spec fn remove(self, i: int) -> Seq<A>
586 recommends
587 0 <= i < self.len(),
588 {
589 self.subrange(0, i) + self.subrange(i + 1, self.len() as int)
590 }
591
592 pub proof fn remove_ensures(self, i: int)
594 requires
595 0 <= i < self.len(),
596 ensures
597 self.remove(i).len() == self.len() - 1,
598 forall|index: int| 0 <= index < i ==> #[trigger] self.remove(i)[index] == self[index],
599 forall|index: int|
600 i <= index < self.len() - 1 ==> #[trigger] self.remove(i)[index] == self[index + 1],
601 {
602 }
603
604 pub open spec fn remove_value(self, val: A) -> Seq<A> {
607 let index = self.index_of_first(val);
608 match index {
609 Some(i) => self.remove(i),
610 None => self,
611 }
612 }
613
614 pub open spec fn reverse(self) -> Seq<A>
616 decreases self.len(),
617 {
618 if self.len() == 0 {
619 Seq::empty()
620 } else {
621 Seq::new(self.len(), |i: int| self[self.len() - 1 - i])
622 }
623 }
624
625 pub open spec fn zip_with<B>(self, other: Seq<B>) -> Seq<(A, B)>
628 recommends
629 self.len() == other.len(),
630 decreases self.len(),
631 {
632 if self.len() != other.len() {
633 Seq::empty()
634 } else if self.len() == 0 {
635 Seq::empty()
636 } else {
637 Seq::new(self.len(), |i: int| (self[i], other[i]))
638 }
639 }
640
641 pub open spec fn fold_left<B>(self, b: B, f: spec_fn(B, A) -> B) -> (res: B)
648 decreases self.len(),
649 {
650 if self.len() == 0 {
651 b
652 } else {
653 f(self.drop_last().fold_left(b, f), self.last())
654 }
655 }
656
657 pub open spec fn fold_left_alt<B>(self, b: B, f: spec_fn(B, A) -> B) -> (res: B)
661 decreases self.len(),
662 {
663 if self.len() == 0 {
664 b
665 } else {
666 self.subrange(1, self.len() as int).fold_left_alt(f(b, self[0]), f)
667 }
668 }
669
670 pub broadcast proof fn lemma_fold_left_split<B>(self, b: B, f: spec_fn(B, A) -> B, k: int)
672 requires
673 0 <= k <= self.len(),
674 ensures
675 self.subrange(k, self.len() as int).fold_left(
676 (#[trigger] self.subrange(0, k).fold_left(b, f)),
677 f,
678 ) == self.fold_left(b, f),
679 decreases self.len(),
680 {
681 reveal_with_fuel(Seq::fold_left, 2);
682 if k == self.len() {
683 assert(self.subrange(0, self.len() as int) == self);
684 } else {
685 self.drop_last().lemma_fold_left_split(b, f, k);
686 assert_seqs_equal!(
687 self.drop_last().subrange(k, self.drop_last().len() as int) ==
688 self.subrange(k, self.len()-1)
689 );
690 assert_seqs_equal!(
691 self.drop_last().subrange(0, k) ==
692 self.subrange(0, k)
693 );
694 assert_seqs_equal!(
695 self.subrange(k, self.len() as int).drop_last() ==
696 self.subrange(k, self.len() - 1)
697 );
698 }
699 }
700
701 proof fn aux_lemma_fold_left_alt<B>(self, b: B, f: spec_fn(B, A) -> B, k: int)
703 requires
704 0 < k <= self.len(),
705 ensures
706 self.subrange(k, self.len() as int).fold_left_alt(
707 self.subrange(0, k).fold_left_alt(b, f),
708 f,
709 ) == self.fold_left_alt(b, f),
710 decreases k,
711 {
712 reveal_with_fuel(Seq::fold_left_alt, 2);
713 if k == 1 {
714 } else {
716 self.subrange(1, self.len() as int).aux_lemma_fold_left_alt(f(b, self[0]), f, k - 1);
717 assert_seqs_equal!(
718 self.subrange(1, self.len() as int)
719 .subrange(k - 1, self.subrange(1, self.len() as int).len() as int) ==
720 self.subrange(k, self.len() as int)
721 );
722 assert_seqs_equal!(
723 self.subrange(1, self.len() as int).subrange(0, k - 1) ==
724 self.subrange(1, k)
725 );
726 assert_seqs_equal!(
727 self.subrange(0, k).subrange(1, self.subrange(0, k).len() as int) ==
728 self.subrange(1, k)
729 );
730 }
731 }
732
733 pub proof fn lemma_fold_left_alt<B>(self, b: B, f: spec_fn(B, A) -> B)
735 ensures
736 self.fold_left(b, f) == self.fold_left_alt(b, f),
737 decreases self.len(),
738 {
739 reveal_with_fuel(Seq::fold_left, 2);
740 reveal_with_fuel(Seq::fold_left_alt, 2);
741 if self.len() <= 1 {
742 } else {
744 self.aux_lemma_fold_left_alt(b, f, self.len() - 1);
745 self.subrange(self.len() - 1, self.len() as int).lemma_fold_left_alt(
746 self.drop_last().fold_left_alt(b, f),
747 f,
748 );
749 self.subrange(0, self.len() - 1).lemma_fold_left_alt(b, f);
750 }
751 }
752
753 pub proof fn lemma_reverse_fold_left<B>(self, v: B, f: spec_fn(B, A) -> B)
756 ensures
757 self.reverse().fold_left(v, f) == self.fold_right(|a: A, b: B| f(b, a), v),
758 {
759 assert(self.reverse().reverse() =~= self);
760 let g = |a: A, b: B| f(b, a);
761 assert(f =~= |b: B, a: A| g(a, b));
762 self.reverse().lemma_reverse_fold_right(v, |a: A, b: B| f(b, a))
763 }
764
765 pub open spec fn fold_right<B>(self, f: spec_fn(A, B) -> B, b: B) -> (res: B)
772 decreases self.len(),
773 {
774 if self.len() == 0 {
775 b
776 } else {
777 self.drop_last().fold_right(f, f(self.last(), b))
778 }
779 }
780
781 pub open spec fn fold_right_alt<B>(self, f: spec_fn(A, B) -> B, b: B) -> (res: B)
785 decreases self.len(),
786 {
787 if self.len() == 0 {
788 b
789 } else {
790 f(self[0], self.subrange(1, self.len() as int).fold_right_alt(f, b))
791 }
792 }
793
794 pub broadcast proof fn lemma_fold_right_split<B>(self, f: spec_fn(A, B) -> B, b: B, k: int)
796 requires
797 0 <= k <= self.len(),
798 ensures
799 self.subrange(0, k).fold_right(
800 f,
801 (#[trigger] self.subrange(k, self.len() as int).fold_right(f, b)),
802 ) == self.fold_right(f, b),
803 decreases self.len(),
804 {
805 reveal_with_fuel(Seq::fold_right, 2);
806 if k == self.len() {
807 assert(self.subrange(0, k) == self);
808 } else if k == self.len() - 1 {
809 } else {
811 self.subrange(0, self.len() - 1).lemma_fold_right_split(f, f(self.last(), b), k);
812 assert_seqs_equal!(
813 self.subrange(0, self.len() - 1).subrange(0, k) ==
814 self.subrange(0, k)
815 );
816 assert_seqs_equal!(
817 self.subrange(0, self.len() - 1).subrange(k, self.subrange(0, self.len() - 1).len() as int) ==
818 self.subrange(k, self.len() - 1)
819 );
820 assert_seqs_equal!(
821 self.subrange(k, self.len() as int).drop_last() ==
822 self.subrange(k, self.len() - 1)
823 );
824 }
825 }
826
827 pub proof fn lemma_fold_right_commute_one<B>(self, a: A, f: spec_fn(A, B) -> B, v: B)
829 requires
830 commutative_foldr(f),
831 ensures
832 self.fold_right(f, f(a, v)) == f(a, self.fold_right(f, v)),
833 decreases self.len(),
834 {
835 if self.len() > 0 {
836 self.drop_last().lemma_fold_right_commute_one(a, f, f(self.last(), v));
837 }
838 }
839
840 pub proof fn lemma_fold_right_alt<B>(self, f: spec_fn(A, B) -> B, b: B)
842 ensures
843 self.fold_right(f, b) == self.fold_right_alt(f, b),
844 decreases self.len(),
845 {
846 reveal_with_fuel(Seq::fold_right, 2);
847 reveal_with_fuel(Seq::fold_right_alt, 2);
848 if self.len() <= 1 {
849 } else {
851 self.subrange(1, self.len() as int).lemma_fold_right_alt(f, b);
852 self.lemma_fold_right_split(f, b, 1);
853 }
854 }
855
856 pub proof fn lemma_reverse_fold_right<B>(self, v: B, f: spec_fn(A, B) -> B)
859 ensures
860 self.reverse().fold_right(f, v) == self.fold_left(v, |b: B, a: A| f(a, b)),
861 decreases self.len(),
862 {
863 let g = |b: B, a: A| f(a, b);
864 if self.len() > 0 {
865 let last = self.last();
866 let s0 = self.drop_last();
867 assert(self.reverse() =~= seq![last] + s0.reverse());
868 let res1 = self.reverse().fold_right(f, v);
869 let res2 = self.fold_left(v, g);
870 assert(res1 == self.reverse().fold_right_alt(f, v)) by {
871 self.reverse().lemma_fold_right_alt(f, v)
872 }
873 assert(res2 == g(s0.fold_left(v, g), last));
874 assert(self.reverse().first() == last);
875 assert(self.reverse().subrange(1, self.reverse().len() as int) =~= s0.reverse());
876 assert(res1 == f(last, s0.reverse().fold_right_alt(f, v)));
877 assert(res1 == f(last, s0.reverse().fold_right(f, v))) by {
878 s0.reverse().lemma_fold_right_alt(f, v)
879 }
880 assert(res2 == g(s0.fold_left(v, g), last));
881 s0.lemma_reverse_fold_right(v, f);
882 }
883 }
884
885 pub proof fn lemma_multiset_has_no_duplicates(self)
889 requires
890 self.no_duplicates(),
891 ensures
892 forall|x: A| self.to_multiset().contains(x) ==> self.to_multiset().count(x) == 1,
893 decreases self.len(),
894 {
895 broadcast use super::multiset::group_multiset_axioms;
896
897 if self.len() == 0 {
898 assert(forall|x: A|
899 self.to_multiset().contains(x) ==> self.to_multiset().count(x) == 1);
900 } else {
901 broadcast use group_seq_properties;
902
903 assert(self.drop_last().push(self.last()) =~= self);
904 self.drop_last().lemma_multiset_has_no_duplicates();
905 }
906 }
907
908 pub proof fn lemma_multiset_has_no_duplicates_conv(self)
911 requires
912 forall|x: A| self.to_multiset().contains(x) ==> self.to_multiset().count(x) == 1,
913 ensures
914 self.no_duplicates(),
915 {
916 broadcast use super::multiset::group_multiset_axioms;
917
918 assert forall|i, j| (0 <= i < self.len() && 0 <= j < self.len() && i != j) implies self[i]
919 != self[j] by {
920 let mut a = if (i < j) {
921 i
922 } else {
923 j
924 };
925 let mut b = if (i < j) {
926 j
927 } else {
928 i
929 };
930
931 if (self[a] == self[b]) {
932 let s0 = self.subrange(0, b);
933 let s1 = self.subrange(b, self.len() as int);
934 assert(self == s0 + s1);
935
936 broadcast use group_to_multiset_ensures;
937
938 lemma_multiset_commutative(s0, s1);
939 assert(self.to_multiset().count(self[a]) >= 2);
940 }
941 }
942 }
943
944 pub proof fn lemma_reverse_to_multiset(self)
946 ensures
947 self.reverse().to_multiset() =~= self.to_multiset(),
948 decreases self.len(),
949 {
950 broadcast use group_seq_properties;
951 broadcast use super::multiset::group_multiset_axioms;
952
953 if self.len() > 0 {
954 let s2 = self.drop_first();
955 let e = self.first();
956 assert(self =~= seq![e] + s2);
957 assert(self.to_multiset() =~= seq![e].to_multiset().add(s2.to_multiset())) by {
958 lemma_multiset_commutative(seq![e], s2)
959 }
960 assert(self.reverse() =~= s2.reverse().push(e));
961 assert(self.reverse().to_multiset() =~= s2.reverse().to_multiset().insert(e));
962 s2.lemma_reverse_to_multiset();
963 }
964 }
965
966 pub proof fn lemma_add_last_back(self)
970 requires
971 0 < self.len(),
972 ensures
973 #[trigger] self.drop_last().push(self.last()) =~= self,
974 {
975 }
976
977 pub proof fn lemma_indexing_implies_membership(self, f: spec_fn(A) -> bool)
982 requires
983 forall|i: int| 0 <= i < self.len() ==> #[trigger] f(#[trigger] self[i]),
984 ensures
985 forall|x: A| #[trigger] self.contains(x) ==> #[trigger] f(x),
986 {
987 assert(forall|i: int| 0 <= i < self.len() ==> #[trigger] self.contains(self[i]));
988 }
989
990 pub proof fn lemma_membership_implies_indexing(self, f: spec_fn(A) -> bool)
995 requires
996 forall|x: A| #[trigger] self.contains(x) ==> #[trigger] f(x),
997 ensures
998 forall|i: int| 0 <= i < self.len() ==> #[trigger] f(self[i]),
999 {
1000 assert forall|i: int| 0 <= i < self.len() implies #[trigger] f(self[i]) by {
1001 assert(self.contains(self[i]));
1002 }
1003 }
1004
1005 pub proof fn lemma_split_at(self, pos: int)
1009 requires
1010 0 <= pos <= self.len(),
1011 ensures
1012 self.subrange(0, pos) + self.subrange(pos, self.len() as int) =~= self,
1013 {
1014 }
1015
1016 pub proof fn lemma_element_from_slice(self, new: Seq<A>, a: int, b: int, pos: int)
1018 requires
1019 0 <= a <= b <= self.len(),
1020 new == self.subrange(a, b),
1021 a <= pos < b,
1022 ensures
1023 pos - a < new.len(),
1024 new[pos - a] == self[pos],
1025 {
1026 }
1027
1028 pub proof fn lemma_slice_of_slice(self, s1: int, e1: int, s2: int, e2: int)
1031 requires
1032 0 <= s1 <= e1 <= self.len(),
1033 0 <= s2 <= e2 <= e1 - s1,
1034 ensures
1035 self.subrange(s1, e1).subrange(s2, e2) =~= self.subrange(s1 + s2, s1 + e2),
1036 {
1037 }
1038
1039 pub proof fn unique_seq_to_set(self)
1041 requires
1042 self.no_duplicates(),
1043 ensures
1044 self.len() == self.to_set().len(),
1045 decreases self.len(),
1046 {
1047 broadcast use super::set::group_set_axioms;
1048
1049 seq_to_set_equal_rec::<A>(self);
1050 if self.len() == 0 {
1051 } else {
1052 let rest = self.drop_last();
1053 rest.unique_seq_to_set();
1054 seq_to_set_equal_rec::<A>(rest);
1055 seq_to_set_rec_is_finite::<A>(rest);
1056 assert(!seq_to_set_rec(rest).contains(self.last()));
1057 assert(seq_to_set_rec(rest).insert(self.last()).len() == seq_to_set_rec(rest).len()
1058 + 1);
1059 }
1060 }
1061
1062 pub proof fn lemma_cardinality_of_set(self)
1065 ensures
1066 self.to_set().len() <= self.len(),
1067 decreases self.len(),
1068 {
1069 broadcast use {super::set::group_set_axioms, seq_to_set_is_finite};
1070 broadcast use group_seq_properties;
1071 broadcast use super::set_lib::group_set_properties;
1072
1073 if self.len() == 0 {
1074 } else {
1075 assert(self.drop_last().to_set().insert(self.last()) =~= self.to_set());
1076 self.drop_last().lemma_cardinality_of_set();
1077 }
1078 }
1079
1080 pub proof fn lemma_cardinality_of_empty_set_is_0(self)
1083 ensures
1084 self.to_set().len() == 0 <==> self.len() == 0,
1085 {
1086 broadcast use {super::set::group_set_axioms, seq_to_set_is_finite};
1087
1088 assert(self.len() == 0 ==> self.to_set().len() == 0) by { self.lemma_cardinality_of_set() }
1089 assert(!(self.len() == 0) ==> !(self.to_set().len() == 0)) by {
1090 if self.len() > 0 {
1091 assert(self.to_set().contains(self[0]));
1092 assert(self.to_set().remove(self[0]).len() <= self.to_set().len());
1093 }
1094 }
1095 }
1096
1097 pub proof fn lemma_no_dup_set_cardinality(self)
1100 requires
1101 self.to_set().len() == self.len(),
1102 ensures
1103 self.no_duplicates(),
1104 decreases self.len(),
1105 {
1106 broadcast use {super::set::group_set_axioms, seq_to_set_is_finite};
1107
1108 if self.len() == 0 {
1109 } else {
1110 assert(self =~= Seq::empty().push(self.first()).add(self.drop_first()));
1111 if self.drop_first().contains(self.first()) {
1112 assert(self.to_set() =~= self.drop_first().to_set());
1114 assert(self.to_set().len() <= self.drop_first().len()) by {
1115 self.drop_first().lemma_cardinality_of_set()
1116 }
1117 } else {
1118 assert(self.to_set().len() == 1 + self.drop_first().to_set().len()) by {
1119 assert(self.drop_first().to_set().insert(self.first()) =~= self.to_set());
1120 }
1121 self.drop_first().lemma_no_dup_set_cardinality();
1122 }
1123 }
1124 }
1125
1126 pub broadcast proof fn lemma_to_set_map_commutes<B>(self, f: spec_fn(A) -> B)
1129 ensures
1130 #[trigger] self.to_set().map(f) =~= self.map_values(f).to_set(),
1131 {
1132 broadcast use crate::vstd::group_vstd_default;
1133
1134 assert forall|elem: B|
1135 self.to_set().map(f).contains(elem) <==> self.map_values(f).to_set().contains(elem) by {
1136 if self.to_set().map(f).contains(elem) {
1137 let x = choose|x: A| self.to_set().contains(x) && f(x) == elem;
1138 let i = choose|i: int| 0 <= i < self.len() && self[i] == x;
1139 assert(self.map_values(f)[i] == elem);
1140 }
1141 if self.map_values(f).to_set().contains(elem) {
1142 let i = choose|i: int|
1143 0 <= i < self.map_values(f).len() && self.map_values(f)[i] == elem;
1144 let x = self[i];
1145 assert(self.to_set().contains(x));
1146 }
1147 };
1148 }
1149
1150 pub broadcast proof fn lemma_to_set_insert_commutes(sq: Seq<A>, elt: A)
1153 requires
1154 ensures
1155 #[trigger] (sq + seq![elt]).to_set() =~= sq.to_set().insert(elt),
1156 {
1157 broadcast use crate::vstd::group_vstd_default;
1158 broadcast use lemma_seq_concat_contains_all_elements;
1159 broadcast use lemma_seq_empty_contains_nothing;
1160 broadcast use lemma_seq_contains_after_push;
1161 broadcast use super::seq::group_seq_axioms;
1162 broadcast use super::set_lib::group_set_properties;
1163
1164 }
1165
1166 pub open spec fn update_subrange_with(self, off: int, vs: Self) -> Self
1170 recommends
1171 0 <= off,
1172 off + vs.len() <= self.len(),
1173 {
1174 Seq::new(
1175 self.len(),
1176 |i: int|
1177 if off <= i < off + vs.len() {
1178 vs[i - off]
1179 } else {
1180 self[i]
1181 },
1182 )
1183 }
1184
1185 pub broadcast proof fn lemma_seq_skip_skip(self, i: int)
1197 ensures
1198 0 <= i < self.len() ==> (self.skip(i)).skip(1) =~= #[trigger] self.skip(i + 1),
1199 {
1200 broadcast use group_seq_properties;
1201
1202 }
1203
1204 pub proof fn lemma_contains_to_index(self, elem: A) -> (idx: int)
1217 requires
1218 self.contains(elem),
1219 ensures
1220 0 <= idx < self.len() && self[idx] == elem,
1221 decreases self.len(),
1222 {
1223 broadcast use group_seq_properties;
1224
1225 if self[0] == elem {
1226 0
1227 } else {
1228 let i = self.skip(1).lemma_contains_to_index(elem);
1229 i + 1
1230 }
1231 }
1232
1233 pub proof fn lemma_all_from_head_tail(self, pred: spec_fn(A) -> bool)
1249 requires
1250 self.len() > 0,
1251 pred(self[0]) && self.skip(1).all(|x| pred(x)),
1252 ensures
1253 self.all(|x| pred(x)),
1254 {
1255 broadcast use group_seq_properties;
1256
1257 assert(seq![self[0]] + self.skip(1) == self);
1258 }
1259
1260 pub proof fn lemma_any_tail(self, pred: spec_fn(A) -> bool)
1276 requires
1277 self.any(|x| pred(x)),
1278 ensures
1279 !pred(self[0]) ==> self.skip(1).any(|x| pred(x)),
1280 {
1281 broadcast use group_seq_properties;
1282
1283 }
1284
1285 pub open spec fn remove_duplicates(self, seen: Seq<A>) -> Seq<A>
1303 decreases self.len(),
1304 {
1305 if self.len() == 0 {
1306 seen
1307 } else if seen.contains(self[0]) {
1308 self.skip(1).remove_duplicates(seen)
1309 } else {
1310 self.skip(1).remove_duplicates(seen + seq![self[0]])
1311 }
1312 }
1313
1314 pub broadcast proof fn lemma_remove_duplicates_properties(self, seen: Seq<A>)
1332 ensures
1333 forall|x|
1334 (self + seen).contains(x) <==> #[trigger] self.remove_duplicates(seen).contains(x),
1335 #[trigger] self.remove_duplicates(seen).len() <= self.len() + seen.len(),
1336 decreases self.len(),
1337 {
1338 broadcast use group_seq_properties;
1339
1340 if self.len() == 0 {
1341 } else if seen.contains(self[0]) {
1342 let rest = self.skip(1);
1343 rest.lemma_remove_duplicates_properties(seen);
1344 } else {
1345 let rest = self.skip(1);
1346 rest.lemma_remove_duplicates_properties(seen + seq![self[0]]);
1347 }
1348 }
1349
1350 pub proof fn lemma_remove_duplicates_append_index(self, i: int, seen: Seq<A>)
1366 requires
1367 0 <= i < self.len(),
1368 ensures
1369 self.remove_duplicates(seen) == self.skip(i).remove_duplicates(
1370 self.take(i).remove_duplicates(seen),
1371 ),
1372 decreases self.len(),
1373 {
1374 broadcast use {
1375 group_seq_properties,
1376 lemma_seq_skip_of_skip,
1377 Seq::lemma_remove_duplicates_properties,
1378 };
1379
1380 if i == 0 {
1381 } else if i == self.len() {
1382 assert(self.take(i) == self);
1383 } else {
1384 assert(self.skip(1).take(i - 1) == self.subrange(1, i));
1385 assert(self.take(i).skip(1) == self.subrange(1, i));
1386 assert(self.skip(1).take(i - 1) == self.take(i).skip(1));
1387 if seen.contains(self[0]) {
1388 self.skip(1).lemma_remove_duplicates_append_index(i - 1, seen);
1389 } else {
1390 self.skip(1).lemma_remove_duplicates_append_index(i - 1, seen + seq![self[0]]);
1391 }
1392 }
1393 }
1394
1395 proof fn lemma_skip1_concat(xs: Seq<A>, ys: Seq<A>)
1410 requires
1411 xs.len() > 0,
1412 ensures
1413 (xs + ys).skip(1) == xs.skip(1) + ys,
1414 {
1415 broadcast use group_seq_properties;
1416
1417 assert((xs + ys).skip(1) == xs.skip(1) + ys);
1418 }
1419
1420 pub proof fn lemma_remove_duplicates_append(self, x: A, seen: Seq<A>)
1436 ensures
1437 (self + seen).contains(x) ==> (self + seq![x]).remove_duplicates(seen)
1438 == self.remove_duplicates(seen),
1439 !(self + seen).contains(x) ==> (self + seq![x]).remove_duplicates(seen)
1440 == self.remove_duplicates(seen) + seq![x],
1441 decreases self.len(),
1442 {
1443 broadcast use group_seq_properties;
1444
1445 reveal_with_fuel(Seq::remove_duplicates, 2);
1446
1447 if self.len() != 0 {
1448 let head = self[0];
1449 let tail = self.skip(1);
1450
1451 let seen2 = if seen.contains(head) {
1452 seen
1453 } else {
1454 seen + seq![head]
1455 };
1456 tail.lemma_remove_duplicates_append(x, seen2);
1457 assert((self + seq![x]).skip(1) == tail + seq![x]) by {
1458 Seq::lemma_skip1_concat(self, seq![x]);
1459 };
1460 }
1461 }
1462
1463 pub proof fn lemma_all_neg_filter_empty(self, pred: spec_fn(A) -> bool)
1476 requires
1477 self.all(|x: A| !pred(x)),
1478 ensures
1479 self.filter(pred).len() == 0,
1480 decreases self.len(),
1481 {
1482 broadcast use group_seq_properties;
1483
1484 reveal(Seq::filter);
1485 if self.len() != 0 {
1486 let rest = self.drop_last();
1487 rest.lemma_all_neg_filter_empty(pred);
1488 rest.lemma_filter_len_push(pred, self.last());
1489 let neg_pred = |x| !pred(x);
1490 assert(neg_pred(self.last()));
1491 }
1492 }
1493
1494 pub open spec fn filter_map<B>(self, f: spec_fn(A) -> Option<B>) -> Seq<B>
1503 decreases self.len(),
1504 {
1505 if self.len() == 0 {
1509 Seq::empty()
1510 } else {
1511 let rest = self.drop_last();
1512 match f(self.last()) {
1513 Option::Some(s) => rest.filter_map(f) + seq![s],
1514 Option::None => rest.filter_map(f),
1515 }
1516 }
1517 }
1518
1519 pub broadcast proof fn lemma_filter_contains_rev(self, p: spec_fn(A) -> bool, elem: A)
1523 requires
1524 #[trigger] self.filter(p).contains(elem),
1525 ensures
1526 self.contains(elem),
1527 decreases self.len(),
1528 {
1529 broadcast use group_seq_properties;
1530
1531 reveal(Seq::filter);
1532 if self.len() == 0 {
1533 } else {
1534 let rest = self.drop_last();
1535 let last = self.last();
1536 if !p(last) || last != elem {
1537 rest.lemma_filter_contains_rev(p, elem);
1538 }
1539 }
1540 }
1541
1542 pub broadcast proof fn lemma_filter_map_contains<B>(self, f: spec_fn(A) -> Option<B>, elt: B)
1546 requires
1547 #[trigger] self.filter_map(f).contains(elt),
1548 ensures
1549 exists|t: A| #[trigger] self.contains(t) && f(t) == Some(elt),
1550 decreases self.len(),
1551 {
1552 broadcast use group_seq_properties;
1553
1554 if self.len() == 0 {
1555 } else {
1556 let last = self.last();
1557 let rest = self.drop_last();
1558 if f(last) == Some(elt) {
1559 assert(self.contains(last));
1560 } else {
1561 rest.lemma_filter_map_contains(f, elt);
1562 let t = choose|t: A| #[trigger] rest.contains(t) && f(t) == Some(elt);
1563 assert(self.contains(t));
1564 }
1565 }
1566 }
1567
1568 pub proof fn lemma_take_succ(xs: Seq<A>, k: int)
1577 requires
1578 0 <= k < xs.len(),
1579 ensures
1580 xs.take(k + 1) =~= xs.take(k) + seq![xs[k]],
1581 {
1582 broadcast use group_seq_properties;
1583
1584 }
1585
1586 pub proof fn lemma_filter_map_singleton<B>(a: A, f: spec_fn(A) -> Option<B>)
1590 ensures
1591 seq![a].filter_map(f) =~= match f(a) {
1592 Option::Some(b) => seq![b],
1593 Option::None => Seq::empty(),
1594 },
1595 {
1596 reveal_with_fuel(Seq::filter_map, 2);
1597 }
1598
1599 pub broadcast proof fn lemma_filter_map_take_succ<B>(self, f: spec_fn(A) -> Option<B>, i: int)
1611 requires
1612 0 <= i < self.len(),
1613 ensures
1614 #[trigger] self.take(i + 1).filter_map(f) =~= self.take(i).filter_map(f) + (match f(
1615 self[i],
1616 ) {
1617 Option::Some(s) => seq![s],
1618 Option::None => Seq::empty(),
1619 }),
1620 decreases self.len(),
1621 {
1622 broadcast use group_seq_properties;
1623
1624 if i != 0 {
1625 self.drop_last().lemma_filter_map_take_succ(f, i - 1);
1626 assert(self.take(i + 1).drop_last() == self.take(i));
1627 }
1628 }
1629
1630 pub open spec fn filter_alt(self, p: spec_fn(A) -> bool) -> Seq<A> {
1633 if self.len() == 0 {
1634 Seq::empty()
1635 } else {
1636 let rest = self.drop_first().filter(p);
1637 let first = self.first();
1638 if p(first) {
1639 seq![first] + rest
1640 } else {
1641 rest
1642 }
1643 }
1644 }
1645
1646 pub broadcast proof fn lemma_filter_prepend(self, x: A, p: spec_fn(A) -> bool)
1661 ensures
1662 #[trigger] (seq![x] + self).filter(p) == (if p(x) {
1663 seq![x]
1664 } else {
1665 Seq::empty()
1666 }) + self.filter(p),
1667 decreases self.len(),
1668 {
1669 broadcast use group_seq_properties;
1670
1671 reveal(Seq::filter);
1672 let lhs = (seq![x] + self).filter(p);
1673 let rhs = (if p(x) {
1674 seq![x]
1675 } else {
1676 Seq::empty()
1677 }) + self.filter(p);
1678
1679 if self.len() == 0 {
1680 assert(lhs =~= rhs);
1681 } else {
1682 let tail_seq = if p(self.last()) {
1683 seq![self.last()]
1684 } else {
1685 Seq::empty()
1686 };
1687
1688 assert(((seq![x] + self).drop_last()) =~= seq![x] + self.drop_last());
1689 let sub = (seq![x] + self.drop_last()).filter(p);
1690 assert(lhs =~= sub + tail_seq);
1691 assert(rhs =~= (if p(x) {
1692 seq![x]
1693 } else {
1694 Seq::empty()
1695 }) + self.drop_last().filter(p) + tail_seq);
1696 self.drop_last().lemma_filter_prepend(x, p);
1697 }
1698 }
1699
1700 pub proof fn lemma_filter_eq_filter_alt(self, p: spec_fn(A) -> bool)
1702 ensures
1703 self.filter(p) =~= self.filter_alt(p),
1704 decreases self.len(),
1705 {
1706 broadcast use group_seq_properties;
1707 broadcast use Seq::lemma_filter_prepend;
1708
1709 reveal(Seq::filter);
1710 if self.len() == 0 {
1711 } else {
1712 let first = self.first();
1713 let but_first = self.drop_first();
1714 assert(self =~= seq![first] + but_first);
1715 self.drop_first().lemma_filter_eq_filter_alt(p);
1716 }
1717 }
1718
1719 pub proof fn lemma_filter_monotone(self, ys: Seq<A>, p: spec_fn(A) -> bool)
1734 requires
1735 self.is_prefix_of(ys),
1736 ensures
1737 self.filter(p).is_prefix_of(ys.filter(p)),
1738 decreases self.len(),
1739 {
1740 broadcast use group_seq_properties;
1741
1742 self.lemma_filter_eq_filter_alt(p);
1743 ys.lemma_filter_eq_filter_alt(p);
1744 if self.len() == 0 {
1745 } else {
1746 self.drop_first().lemma_filter_monotone(ys.drop_first(), p);
1747 }
1748 }
1749
1750 pub proof fn lemma_filter_take_len(self, p: spec_fn(A) -> bool, i: int)
1765 requires
1766 0 <= i <= self.len(),
1767 ensures
1768 self.filter(p).len() >= self.take(i).filter(p).len(),
1769 decreases i,
1770 {
1771 broadcast use group_seq_properties;
1772 broadcast use Seq::lemma_filter_len_push;
1773 broadcast use Seq::lemma_filter_push;
1774
1775 self.take(i).lemma_filter_monotone(self, p);
1776 }
1777
1778 pub broadcast proof fn lemma_filter_len_push(self, p: spec_fn(A) -> bool, elem: A)
1790 ensures
1791 #[trigger] self.push(elem).filter(p).len() == self.filter(p).len() + (if p(elem) {
1792 1int
1793 } else {
1794 0int
1795 }),
1796 {
1797 broadcast use group_seq_properties;
1798 broadcast use Seq::lemma_filter_push;
1799
1800 }
1801
1802 pub broadcast proof fn lemma_index_contains(self, i: int)
1805 requires
1806 0 <= i < self.len(),
1807 ensures
1808 self.contains(#[trigger] self[i]),
1809 {
1810 }
1811
1812 pub broadcast proof fn lemma_take_succ_push(self, i: int)
1815 requires
1816 0 <= i < self.len(),
1817 ensures
1818 #[trigger] self.take(i + 1) =~= self.take(i).push(self[i]),
1819 {
1820 broadcast use group_seq_properties;
1821
1822 }
1823
1824 pub broadcast proof fn lemma_take_len(self)
1826 ensures
1827 #[trigger] self.take(self.len() as int) == self,
1828 {
1829 broadcast use group_seq_properties;
1830
1831 }
1832
1833 pub broadcast proof fn lemma_take_any_succ(self, p: spec_fn(A) -> bool, i: int)
1846 requires
1847 0 <= i < self.len(),
1848 ensures
1849 #[trigger] self.take(i + 1).any(p) <==> self.take(i).any(p) || p(self[i]),
1850 {
1851 broadcast use group_seq_properties;
1852
1853 self.lemma_take_succ_push(i);
1854 if self.take(i + 1).any(p) {
1855 let x = choose|x: A| self.take(i + 1).contains(x) && #[trigger] p(x);
1856 assert(self.take(i).contains(x) || x == self[i]);
1857 }
1858 if self.take(i).any(p) {
1859 let x = choose|x: A| self.take(i).contains(x) && #[trigger] p(x);
1860 assert(self.take(i + 1).contains(x));
1861 }
1862 if p(self[i]) {
1863 assert(self.take(i + 1).contains(self[i]));
1864 }
1865 }
1866
1867 pub proof fn lemma_no_duplicates_injective<B>(self, f: spec_fn(A) -> B)
1879 requires
1880 injective(f),
1881 ensures
1882 self.no_duplicates() <==> self.map_values(f).no_duplicates(),
1883 {
1884 broadcast use group_seq_properties;
1885 broadcast use super::set_lib::group_set_properties;
1886
1887 let mapped = self.map_values(f);
1888 assert(mapped.len() == self.len());
1889 if mapped.no_duplicates() {
1890 assert forall|i: int, j: int| 0 <= i < j < mapped.len() implies self[i] != self[j] by {
1891 assert(mapped[i] == f(self[i]));
1892 assert(mapped[j] == f(self[j]));
1893 }
1894 }
1895 }
1896
1897 pub broadcast proof fn lemma_push_map_commute<B>(self, f: spec_fn(A) -> B, x: A)
1909 ensures
1910 self.map_values(f).push(f(x)) =~= #[trigger] self.push(x).map_values(f),
1911 decreases self.len(),
1912 {
1913 broadcast use group_seq_properties;
1914
1915 }
1916
1917 pub broadcast proof fn lemma_push_to_set_commute(self, elem: A)
1928 ensures
1929 #[trigger] self.push(elem).to_set() =~= self.to_set().insert(elem),
1930 {
1931 broadcast use group_seq_properties;
1932 broadcast use super::set::group_set_axioms;
1933
1934 let lhs = self.push(elem).to_set();
1935 let rhs = self.to_set().insert(elem);
1936
1937 assert(lhs.subset_of(rhs));
1938 assert forall|x: A| rhs.contains(x) implies lhs.contains(x) by {
1939 lemma_seq_contains_after_push(self, elem, x);
1940 if x == elem {
1941 } else {
1942 lemma_seq_contains_after_push(self, elem, x);
1943 }
1944 }
1945 }
1946
1947 pub broadcast proof fn lemma_filter_push(self, elem: A, pred: spec_fn(A) -> bool)
1961 ensures
1962 #[trigger] self.push(elem).filter(pred) == if pred(elem) {
1963 self.filter(pred).push(elem)
1964 } else {
1965 self.filter(pred)
1966 },
1967 {
1968 broadcast use group_seq_properties;
1969
1970 reveal(Seq::filter);
1971 assert(self.push(elem).drop_last() =~= self);
1972 }
1973
1974 pub proof fn lemma_zip_with_contains_index<B>(self, b: Seq<B>, i: int)
1987 requires
1988 0 <= i < self.len(),
1989 self.len() == b.len(),
1990 ensures
1991 self.zip_with(b).contains((self[i], b[i])),
1992 {
1993 assert(self.zip_with(b)[i] == (self[i], b[i]));
1994 }
1995
1996 pub proof fn lemma_zip_with_uncurry_all<B>(self, b: Seq<B>, f: spec_fn(A, B) -> bool)
2013 requires
2014 self.len() == b.len(),
2015 ensures
2016 self.zip_with(b).all(|p: (A, B)| f(p.0, p.1)) <==> forall|i: int|
2017 0 <= i < self.len() ==> f(self[i], b[i]),
2018 {
2019 broadcast use group_seq_properties;
2020
2021 let zipped = self.zip_with(b);
2022 let f_uncurr = |p: (A, B)| f(p.0, p.1);
2023 let lhs = zipped.all(f_uncurr);
2024 let rhs = (forall|i: int| 0 <= i < self.len() ==> f(self[i], b[i]));
2025 if lhs {
2026 assert forall|i: int| 0 <= i < self.len() implies f(self[i], b[i]) by {
2027 self.lemma_zip_with_contains_index(b, i);
2028 assert(forall|j| 0 <= j < zipped.len() ==> f_uncurr(zipped[j]));
2029 }
2030 }
2031 }
2032
2033 pub proof fn lemma_flat_map_push<B>(self, f: spec_fn(A) -> Seq<B>, elem: A)
2047 ensures
2048 self.push(elem).flat_map(f) =~= self.flat_map(f) + f(elem),
2049 decreases self.len(),
2050 {
2051 broadcast use group_seq_properties;
2052 broadcast use Seq::lemma_flatten_push;
2053 broadcast use Seq::lemma_push_map_commute;
2054
2055 }
2056
2057 pub broadcast proof fn lemma_flat_map_take_append<B>(self, f: spec_fn(A) -> Seq<B>, i: int)
2072 requires
2073 0 <= i < self.len(),
2074 ensures
2075 #[trigger] self.take(i + 1).flat_map(f) =~= self.take(i).flat_map(f) + f(self[i]),
2076 decreases i,
2077 {
2078 broadcast use group_seq_properties;
2079
2080 self.lemma_take_succ_push(i);
2081 self.take(i).lemma_flat_map_push(f, self[i]);
2082 }
2083
2084 pub broadcast proof fn lemma_flat_map_singleton<B>(self, f: spec_fn(A) -> Seq<B>)
2087 requires
2088 #[trigger] self.len() == 1,
2089 ensures
2090 #[trigger] self.flat_map(f) == f(self[0]),
2091 {
2092 broadcast use Seq::lemma_flatten_singleton;
2093
2094 }
2095
2096 pub broadcast proof fn lemma_map_take_succ<B>(self, f: spec_fn(A) -> B, i: int)
2111 requires
2112 0 <= i < self.len(),
2113 ensures
2114 #[trigger] self.take(i + 1).map_values(f) =~= self.take(i).map_values(f).push(
2115 f(self[i]),
2116 ),
2117 {
2118 broadcast use group_seq_properties;
2119
2120 self.lemma_take_succ_push(i);
2121 }
2122
2123 pub broadcast proof fn lemma_prefix_index_eq(self, prefix: Seq<A>)
2136 requires
2137 #[trigger] prefix.is_prefix_of(self),
2138 ensures
2139 forall|i: int| 0 <= i < prefix.len() ==> prefix[i] == self[i],
2140 {
2141 }
2142
2143 pub broadcast proof fn lemma_prefix_concat(self, prefix1: Seq<A>, prefix2: Seq<A>)
2157 requires
2158 #[trigger] (prefix1 + prefix2).is_prefix_of(self),
2159 ensures
2160 prefix1.is_prefix_of(self),
2161 {
2162 broadcast use Seq::lemma_prefix_index_eq;
2163
2164 }
2165
2166 pub broadcast proof fn lemma_prefix_chain_contains(self, prefix1: Seq<A>, prefix2: Seq<A>, t: A)
2187 requires
2188 #[trigger] (prefix1 + seq![t]).is_prefix_of(self),
2189 #[trigger] prefix1.is_prefix_of(prefix2),
2190 prefix2.is_prefix_of(self),
2191 prefix1 != prefix2,
2192 !prefix1.contains(t),
2193 ensures
2194 prefix2.contains(t),
2195 {
2196 broadcast use Seq::lemma_prefix_concat;
2197 broadcast use Seq::lemma_prefix_index_eq;
2198
2199 assert(prefix2[prefix1.len() as int] == t);
2200 }
2201
2202 pub broadcast proof fn lemma_prefix_append_unique(self, prefix1: Seq<A>, prefix2: Seq<A>, t: A)
2206 requires
2207 #[trigger] (prefix1 + seq![t]).is_prefix_of(self),
2208 #[trigger] (prefix2 + seq![t]).is_prefix_of(self),
2209 !prefix1.contains(t),
2210 !prefix2.contains(t),
2211 ensures
2212 prefix1 == prefix2,
2213 {
2214 broadcast use Seq::lemma_prefix_concat;
2215 broadcast use Seq::lemma_prefix_index_eq;
2216 broadcast use Seq::lemma_prefix_chain_contains;
2217
2218 if prefix1 != prefix2 {
2219 assert(prefix1.is_prefix_of(prefix2) || prefix2.is_prefix_of(prefix1));
2220 }
2221 }
2222
2223 pub broadcast proof fn lemma_all_push(self, p: spec_fn(A) -> bool, elem: A)
2238 requires
2239 self.all(p),
2240 p(elem),
2241 ensures
2242 #[trigger] self.push(elem).all(p),
2243 {
2244 broadcast use group_seq_properties;
2245
2246 assert forall|x: A| self.push(elem).contains(x) implies p(x) by {
2247 lemma_seq_contains_after_push(self, elem, x);
2248 }
2249 }
2250
2251 pub proof fn lemma_concat_injective(self, s1: Seq<A>, s2: Seq<A>)
2254 ensures
2255 (self + s1 == self + s2) <==> (s1 == s2),
2256 {
2257 broadcast use group_seq_properties;
2258
2259 assert((self + s1).skip(self.len() as int) == s1);
2260 }
2261
2262 pub broadcast group group_seq_extra {
2263 Seq::<_>::lemma_seq_skip_skip,
2264 Seq::<_>::lemma_remove_duplicates_properties,
2265 Seq::<_>::lemma_filter_contains_rev,
2266 Seq::<_>::lemma_filter_map_take_succ,
2267 Seq::<_>::lemma_filter_prepend,
2268 Seq::<_>::lemma_filter_len_push,
2269 Seq::<_>::lemma_take_len,
2270 Seq::<_>::lemma_take_any_succ,
2271 Seq::<_>::lemma_push_map_commute,
2272 Seq::<_>::lemma_push_to_set_commute,
2273 Seq::<_>::lemma_filter_push,
2274 Seq::<_>::lemma_flat_map_take_append,
2275 Seq::<_>::lemma_flat_map_singleton,
2276 Seq::<_>::lemma_map_take_succ,
2277 Seq::<_>::lemma_prefix_index_eq,
2278 Seq::<_>::lemma_prefix_concat,
2279 Seq::<_>::lemma_prefix_chain_contains,
2280 Seq::<_>::lemma_prefix_append_unique,
2281 Seq::<_>::lemma_all_push,
2282 }
2283}
2284
2285impl<A> Seq<&A> {
2286 pub open spec fn unref(self) -> Seq<A> {
2288 Seq::new(self.len(), |i: int| *self[i])
2289 }
2290}
2291
2292impl<A, B> Seq<(&A, &B)> {
2293 pub open spec fn unref(self) -> Seq<(A, B)> {
2295 Seq::new(self.len(), |i: int| (*self[i].0, *self[i].1))
2296 }
2297}
2298
2299pub proof fn lemma_filter_view_commute<S: View>(
2316 s: Seq<S>,
2317 p: spec_fn(S) -> bool,
2318 sp: spec_fn(S::V) -> bool,
2319)
2320 requires
2321 forall|s: S| p(s) <==> sp(s.view()),
2322 ensures
2323 s.filter(p).map_values(|x: S| x.view()) == s.map_values(|x: S| x.view()).filter(sp),
2324 decreases s.len(),
2325{
2326 broadcast use group_seq_properties;
2327 broadcast use Seq::lemma_push_map_commute;
2328 broadcast use Seq::lemma_filter_push;
2329
2330 reveal(Seq::filter);
2331 let view = |x: S| x.view();
2332 if s.len() > 0 {
2333 let rest = s.drop_last();
2334 let last = s.last();
2335 assert(s =~= rest.push(last));
2336 assert(s.map_values(view).last() == view(last));
2337 lemma_filter_view_commute(rest, p, sp);
2338 }
2339}
2340
2341pub proof fn lemma_exactly_one_view<S: View>(
2356 s: Seq<S>,
2357 p: spec_fn(S) -> bool,
2358 sp: spec_fn(S::V) -> bool,
2359)
2360 requires
2361 forall|s: S| p(s) <==> sp(s.view()),
2362 injective(|x: S| x.view()),
2363 ensures
2364 s.exactly_one(p) <==> s.map_values(|x: S| x.view()).exactly_one(sp),
2365{
2366 lemma_filter_view_commute(s, p, sp);
2367}
2368
2369impl<A, B> Seq<(A, B)> {
2370 pub closed spec fn unzip(self) -> (Seq<A>, Seq<B>) {
2372 (Seq::new(self.len(), |i: int| self[i].0), Seq::new(self.len(), |i: int| self[i].1))
2373 }
2374
2375 pub proof fn unzip_ensures(self)
2377 ensures
2378 self.unzip().0.len() == self.unzip().1.len(),
2379 self.unzip().0.len() == self.len(),
2380 self.unzip().1.len() == self.len(),
2381 forall|i: int|
2382 0 <= i < self.len() ==> (#[trigger] self.unzip().0[i], #[trigger] self.unzip().1[i])
2383 == self[i],
2384 decreases self.len(),
2385 {
2386 if self.len() > 0 {
2387 self.drop_last().unzip_ensures();
2388 }
2389 }
2390
2391 pub proof fn lemma_zip_of_unzip(self)
2394 ensures
2395 self.unzip().0.zip_with(self.unzip().1) =~= self,
2396 {
2397 }
2398}
2399
2400impl<A> Seq<Seq<A>> {
2401 pub open spec fn flatten(self) -> Seq<A>
2415 decreases self.len(),
2416 {
2417 if self.len() == 0 {
2418 Seq::empty()
2419 } else {
2420 self.first().add(self.drop_first().flatten())
2421 }
2422 }
2423
2424 pub open spec fn flatten_alt(self) -> Seq<A>
2429 decreases self.len(),
2430 {
2431 if self.len() == 0 {
2432 Seq::empty()
2433 } else {
2434 self.drop_last().flatten_alt().add(self.last())
2435 }
2436 }
2437
2438 pub proof fn lemma_flatten_one_element(self)
2441 ensures
2442 self.len() == 1 ==> self.flatten() == self.first(),
2443 {
2444 broadcast use Seq::add_empty_right;
2445
2446 if self.len() == 1 {
2447 assert(self.flatten() =~= self.first().add(self.drop_first().flatten()));
2448 }
2449 }
2450
2451 pub proof fn lemma_flatten_length_ge_single_element_length(self, i: int)
2454 requires
2455 0 <= i < self.len(),
2456 ensures
2457 self.flatten_alt().len() >= self[i].len(),
2458 decreases self.len(),
2459 {
2460 if self.len() == 1 {
2461 self.lemma_flatten_one_element();
2462 self.lemma_flatten_and_flatten_alt_are_equivalent();
2463 } else if i < self.len() - 1 {
2464 self.drop_last().lemma_flatten_length_ge_single_element_length(i);
2465 } else {
2466 assert(self.flatten_alt() == self.drop_last().flatten_alt().add(self.last()));
2467 }
2468 }
2469
2470 pub proof fn lemma_flatten_length_le_mul(self, j: int)
2474 requires
2475 forall|i: int| 0 <= i < self.len() ==> (#[trigger] self[i]).len() <= j,
2476 ensures
2477 self.flatten_alt().len() <= self.len() * j,
2478 decreases self.len(),
2479 {
2480 broadcast use group_seq_properties;
2481
2482 if self.len() == 0 {
2483 } else {
2484 self.drop_last().lemma_flatten_length_le_mul(j);
2485 assert((self.len() - 1) * j == (self.len() * j) - (1 * j)) by (nonlinear_arith); }
2487 }
2488
2489 pub proof fn lemma_flatten_and_flatten_alt_are_equivalent(self)
2492 ensures
2493 self.flatten() =~= self.flatten_alt(),
2494 decreases self.len(),
2495 {
2496 broadcast use {Seq::add_empty_right, Seq::push_distributes_over_add};
2497
2498 if self.len() != 0 {
2499 self.drop_last().lemma_flatten_and_flatten_alt_are_equivalent();
2500 seq![self.last()].lemma_flatten_one_element();
2504 assert(seq![self.last()].flatten() == self.last());
2505 lemma_flatten_concat(self.drop_last(), seq![self.last()]);
2506 assert((self.drop_last() + seq![self.last()]).flatten() == self.drop_last().flatten()
2507 + self.last());
2508 assert(self.drop_last() + seq![self.last()] =~= self);
2509 assert(self.flatten_alt() == self.drop_last().flatten_alt() + self.last());
2510 }
2511 }
2512
2513 pub broadcast proof fn lemma_flatten_push(self, elem: Seq<A>)
2516 ensures
2517 #[trigger] self.push(elem).flatten() =~= self.flatten() + elem,
2518 decreases self.len(),
2519 {
2520 broadcast use group_seq_properties;
2521
2522 assert(self.push(elem).last() == elem);
2523 assert(self.push(elem).drop_last() =~= self);
2524 calc! {
2525 (==)
2526 self.push(elem).flatten(); {
2527 self.push(elem).lemma_flatten_and_flatten_alt_are_equivalent();
2528 }
2529 self.push(elem).flatten_alt(); {}
2530 self.flatten_alt() + elem; {
2531 self.lemma_flatten_and_flatten_alt_are_equivalent();
2532 }
2533 self.flatten() + elem;
2534 }
2535 }
2536
2537 pub broadcast proof fn lemma_flatten_singleton(self)
2539 requires
2540 #[trigger] self.len() == 1,
2541 ensures
2542 #[trigger] self.flatten() == self[0],
2543 {
2544 assert(self.flatten() == self[0] + self.drop_first().flatten());
2545 assert(self.flatten() == self[0]);
2546 }
2547
2548 pub broadcast group group_seq_flatten {
2549 Seq::<_>::lemma_flatten_push,
2550 Seq::<_>::lemma_flatten_singleton,
2551 }
2552}
2553
2554impl Seq<int> {
2557 pub open spec fn max(self) -> int
2559 recommends
2560 0 < self.len(),
2561 decreases self.len(),
2562 {
2563 if self.len() == 1 {
2564 self[0]
2565 } else if self.len() == 0 {
2566 0
2567 } else {
2568 let later_max = self.drop_first().max();
2569 if self[0] >= later_max {
2570 self[0]
2571 } else {
2572 later_max
2573 }
2574 }
2575 }
2576
2577 pub proof fn max_ensures(self)
2579 ensures
2580 forall|x: int| self.contains(x) ==> x <= self.max(),
2581 forall|i: int| 0 <= i < self.len() ==> self[i] <= self.max(),
2582 self.len() == 0 || self.contains(self.max()),
2583 decreases self.len(),
2584 {
2585 if self.len() <= 1 {
2586 } else {
2587 let elt = self.drop_first().max();
2588 assert(self.drop_first().contains(elt)) by { self.drop_first().max_ensures() }
2589 assert forall|i: int| 0 <= i < self.len() implies self[i] <= self.max() by {
2590 assert(i == 0 || self[i] == self.drop_first()[i - 1]);
2591 assert(forall|j: int|
2592 0 <= j < self.drop_first().len() ==> self.drop_first()[j]
2593 <= self.drop_first().max()) by { self.drop_first().max_ensures() }
2594 }
2595 }
2596 }
2597
2598 pub open spec fn min(self) -> int
2600 recommends
2601 0 < self.len(),
2602 decreases self.len(),
2603 {
2604 if self.len() == 1 {
2605 self[0]
2606 } else if self.len() == 0 {
2607 0
2608 } else {
2609 let later_min = self.drop_first().min();
2610 if self[0] <= later_min {
2611 self[0]
2612 } else {
2613 later_min
2614 }
2615 }
2616 }
2617
2618 pub proof fn min_ensures(self)
2620 ensures
2621 forall|x: int| self.contains(x) ==> self.min() <= x,
2622 forall|i: int| 0 <= i < self.len() ==> self.min() <= self[i],
2623 self.len() == 0 || self.contains(self.min()),
2624 decreases self.len(),
2625 {
2626 if self.len() <= 1 {
2627 } else {
2628 let elt = self.drop_first().min();
2629 assert(self.subrange(1, self.len() as int).contains(elt)) by {
2630 self.drop_first().min_ensures()
2631 }
2632 assert forall|i: int| 0 <= i < self.len() implies self.min() <= self[i] by {
2633 assert(i == 0 || self[i] == self.drop_first()[i - 1]);
2634 assert(forall|j: int|
2635 0 <= j < self.drop_first().len() ==> self.drop_first().min()
2636 <= self.drop_first()[j]) by { self.drop_first().min_ensures() }
2637 }
2638 }
2639 }
2640
2641 pub closed spec fn sort(self) -> Self {
2642 self.sort_by(|x: int, y: int| x <= y)
2643 }
2644
2645 pub proof fn lemma_sort_ensures(self)
2646 ensures
2647 self.to_multiset() =~= self.sort().to_multiset(),
2648 sorted_by(self.sort(), |x: int, y: int| x <= y),
2649 {
2650 self.lemma_sort_by_ensures(|x: int, y: int| x <= y);
2651 }
2652
2653 pub proof fn lemma_subrange_max(self, from: int, to: int)
2656 requires
2657 0 <= from < to <= self.len(),
2658 ensures
2659 self.subrange(from, to).max() <= self.max(),
2660 {
2661 self.max_ensures();
2662 self.subrange(from, to).max_ensures();
2663 }
2664
2665 pub proof fn lemma_subrange_min(self, from: int, to: int)
2668 requires
2669 0 <= from < to <= self.len(),
2670 ensures
2671 self.subrange(from, to).min() >= self.min(),
2672 {
2673 self.min_ensures();
2674 self.subrange(from, to).min_ensures();
2675 }
2676}
2677
2678spec fn merge_sorted_with<A>(left: Seq<A>, right: Seq<A>, leq: spec_fn(A, A) -> bool) -> Seq<A>
2680 recommends
2681 sorted_by(left, leq),
2682 sorted_by(right, leq),
2683 total_ordering(leq),
2684 decreases left.len(), right.len(),
2685{
2686 if left.len() == 0 {
2687 right
2688 } else if right.len() == 0 {
2689 left
2690 } else if leq(left.first(), right.first()) {
2691 Seq::<A>::empty().push(left.first()) + merge_sorted_with(left.drop_first(), right, leq)
2692 } else {
2693 Seq::<A>::empty().push(right.first()) + merge_sorted_with(left, right.drop_first(), leq)
2694 }
2695}
2696
2697proof fn lemma_merge_sorted_with_ensures<A>(left: Seq<A>, right: Seq<A>, leq: spec_fn(A, A) -> bool)
2698 requires
2699 sorted_by(left, leq),
2700 sorted_by(right, leq),
2701 total_ordering(leq),
2702 ensures
2703 (left + right).to_multiset() =~= merge_sorted_with(left, right, leq).to_multiset(),
2704 sorted_by(merge_sorted_with(left, right, leq), leq),
2705 decreases left.len(), right.len(),
2706{
2707 broadcast use group_seq_properties;
2709
2710 if left.len() == 0 {
2711 assert(left + right =~= right);
2712 } else if right.len() == 0 {
2713 assert(left + right =~= left);
2714 } else if leq(left.first(), right.first()) {
2715 let result = Seq::<A>::empty().push(left.first()) + merge_sorted_with(
2716 left.drop_first(),
2717 right,
2718 leq,
2719 );
2720 lemma_merge_sorted_with_ensures(left.drop_first(), right, leq);
2721 let rest = merge_sorted_with(left.drop_first(), right, leq);
2722 assert(rest.len() == 0 || rest.first() == left.drop_first().first() || rest.first()
2723 == right.first()) by {
2724 if left.drop_first().len() == 0 {
2725 } else if leq(left.drop_first().first(), right.first()) {
2726 assert(rest =~= Seq::<A>::empty().push(left.drop_first().first())
2727 + merge_sorted_with(left.drop_first().drop_first(), right, leq));
2728 } else {
2729 assert(rest =~= Seq::<A>::empty().push(right.first()) + merge_sorted_with(
2730 left.drop_first(),
2731 right.drop_first(),
2732 leq,
2733 ));
2734 }
2735 }
2736 lemma_new_first_element_still_sorted_by(left.first(), rest, leq);
2737 assert((left.drop_first() + right) =~= (left + right).drop_first());
2738 } else {
2739 let result = Seq::<A>::empty().push(right.first()) + merge_sorted_with(
2740 left,
2741 right.drop_first(),
2742 leq,
2743 );
2744 lemma_merge_sorted_with_ensures(left, right.drop_first(), leq);
2745 let rest = merge_sorted_with(left, right.drop_first(), leq);
2746 assert(rest.len() == 0 || rest.first() == left.first() || rest.first()
2747 == right.drop_first().first()) by {
2748 assert(left.len() > 0);
2749 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(
2752 left.drop_first(),
2753 right.drop_first(),
2754 leq,
2755 ));
2756 } else {
2757 assert(rest =~= Seq::<A>::empty().push(right.drop_first().first())
2758 + merge_sorted_with(left, right.drop_first().drop_first(), leq));
2759 }
2760 }
2761 lemma_new_first_element_still_sorted_by(
2762 right.first(),
2763 merge_sorted_with(left, right.drop_first(), leq),
2764 leq,
2765 );
2766 lemma_seq_union_to_multiset_commutative(left, right);
2767 assert((right.drop_first() + left) =~= (right + left).drop_first());
2768 lemma_seq_union_to_multiset_commutative(right.drop_first(), left);
2769 }
2770}
2771
2772pub proof fn lemma_max_of_concat(x: Seq<int>, y: Seq<int>)
2775 requires
2776 0 < x.len() && 0 < y.len(),
2777 ensures
2778 x.max() <= (x + y).max(),
2779 y.max() <= (x + y).max(),
2780 forall|elt: int| (x + y).contains(elt) ==> elt <= (x + y).max(),
2781 decreases x.len(),
2782{
2783 broadcast use group_seq_properties;
2784
2785 x.max_ensures();
2786 y.max_ensures();
2787 (x + y).max_ensures();
2788 assert(x.drop_first().len() == x.len() - 1);
2789 if x.len() == 1 {
2790 assert(y.max() <= (x + y).max()) by {
2791 assert((x + y).contains(y.max()));
2792 }
2793 } else {
2794 assert(x.max() <= (x + y).max()) by {
2795 assert(x.contains(x.max()));
2796 assert((x + y).contains(x.max()));
2797 }
2798 assert(x.drop_first() + y =~= (x + y).drop_first());
2799 lemma_max_of_concat(x.drop_first(), y);
2800 }
2801}
2802
2803pub proof fn lemma_min_of_concat(x: Seq<int>, y: Seq<int>)
2806 requires
2807 0 < x.len() && 0 < y.len(),
2808 ensures
2809 (x + y).min() <= x.min(),
2810 (x + y).min() <= y.min(),
2811 forall|elt: int| (x + y).contains(elt) ==> (x + y).min() <= elt,
2812 decreases x.len(),
2813{
2814 x.min_ensures();
2815 y.min_ensures();
2816 (x + y).min_ensures();
2817 broadcast use group_seq_properties;
2818
2819 if x.len() == 1 {
2820 assert((x + y).min() <= y.min()) by {
2821 assert((x + y).contains(y.min()));
2822 }
2823 } else {
2824 assert((x + y).min() <= x.min()) by {
2825 assert((x + y).contains(x.min()));
2826 }
2827 assert((x + y).min() <= y.min()) by {
2828 assert((x + y).contains(y.min()));
2829 }
2830 assert(x.drop_first() + y =~= (x + y).drop_first());
2831 lemma_max_of_concat(x.drop_first(), y)
2832 }
2833}
2834
2835pub broadcast proof fn to_multiset_build<A>(s: Seq<A>, a: A)
2839 ensures
2840 #![trigger s.push(a).to_multiset()]
2841 s.push(a).to_multiset() =~= s.to_multiset().insert(a),
2842 decreases s.len(),
2843{
2844 broadcast use super::multiset::group_multiset_axioms;
2845
2846 if s.len() == 0 {
2847 assert(s.to_multiset() =~= Multiset::<A>::empty());
2848 assert(s.push(a).drop_first() =~= Seq::<A>::empty());
2849 assert(s.push(a).to_multiset() =~= Multiset::<A>::empty().insert(a).add(
2850 Seq::<A>::empty().to_multiset(),
2851 ));
2852 } else {
2853 to_multiset_build(s.drop_first(), a);
2854 assert(s.drop_first().push(a).to_multiset() =~= s.drop_first().to_multiset().insert(a));
2855 assert(s.push(a).drop_first() =~= s.drop_first().push(a));
2856 }
2857}
2858
2859pub broadcast proof fn to_multiset_remove<A>(s: Seq<A>, i: int)
2860 requires
2861 0 <= i < s.len(),
2862 ensures
2863 #![trigger s.remove(i).to_multiset()]
2864 s.remove(i).to_multiset() == s.to_multiset().remove(s[i]),
2865{
2866 broadcast use super::multiset::group_multiset_axioms;
2867
2868 let s0 = s.subrange(0, i);
2869 let s1 = s.subrange(i, s.len() as int);
2870 let s2 = s.subrange(i + 1, s.len() as int);
2871 lemma_seq_union_to_multiset_commutative(s0, s2);
2872 lemma_seq_union_to_multiset_commutative(s0, s1);
2873 assert(s == s0 + s1);
2874 assert(s2 + s0 == (s1 + s0).drop_first());
2875 assert(s.remove(i).to_multiset() =~= s.to_multiset().remove(s[i]));
2876}
2877
2878pub broadcast proof fn to_multiset_insert<A>(s: Seq<A>, i: int, a: A)
2879 requires
2880 0 <= i <= s.len(),
2881 ensures
2882 #![trigger s.insert(i, a).to_multiset()]
2883 s.insert(i, a).to_multiset() == s.to_multiset().insert(a),
2884 decreases s.len(),
2885{
2886 broadcast use super::multiset::group_multiset_axioms;
2887
2888 let s0 = s.subrange(0, i);
2889 let s1 = s.subrange(i, s.len() as int);
2890
2891 assert(s =~= s0 + s1);
2892 assert(s.insert(i, a) =~= s0 + seq![a] + s1);
2893 assert(((s0 + seq![a]) + s1).to_multiset() =~= ((seq![a] + s0) + s1).to_multiset()) by {
2894 broadcast use lemma_multiset_commutative;
2895
2896 };
2897 assert((seq![a] + s0 + s1).drop_first() == s0 + s1);
2898 assert(s.insert(i, a).to_multiset() =~= s.to_multiset().insert(a));
2899}
2900
2901pub broadcast proof fn to_multiset_len<A>(s: Seq<A>)
2903 ensures
2904 s.len() == #[trigger] s.to_multiset().len(),
2905 decreases s.len(),
2906{
2907 broadcast use super::multiset::group_multiset_axioms;
2908
2909 if s.len() == 0 {
2910 assert(s.to_multiset() =~= Multiset::<A>::empty());
2911 assert(s.len() == 0);
2912 } else {
2913 to_multiset_len(s.drop_first());
2914 assert(s.len() == s.drop_first().len() + 1);
2915 assert(s.to_multiset().len() == s.drop_first().to_multiset().len() + 1);
2916 }
2917}
2918
2919pub broadcast proof fn to_multiset_contains<A>(s: Seq<A>, a: A)
2921 ensures
2922 #![trigger s.to_multiset().count(a)]
2923 s.contains(a) <==> s.to_multiset().count(a) > 0,
2924 decreases s.len(),
2925{
2926 broadcast use super::multiset::group_multiset_axioms;
2927
2928 if s.len() != 0 {
2929 if s.contains(a) {
2931 if s.first() == a {
2932 to_multiset_build(s, a);
2933 assert(s.to_multiset() =~= Multiset::<A>::empty().insert(s.first()).add(
2934 s.drop_first().to_multiset(),
2935 ));
2936 assert(Multiset::<A>::empty().insert(s.first()).contains(s.first()));
2937 } else {
2938 to_multiset_contains(s.drop_first(), a);
2939 assert(s.skip(1) =~= s.drop_first());
2940 lemma_seq_skip_contains(s, 1, a);
2941 assert(s.to_multiset().count(a) == s.drop_first().to_multiset().count(a));
2942 assert(s.contains(a) <==> s.to_multiset().count(a) > 0);
2943 }
2944 }
2945 if s.to_multiset().count(a) > 0 {
2948 to_multiset_contains(s.drop_first(), a);
2949 assert(s.contains(a) <==> s.to_multiset().count(a) > 0);
2950 } else {
2951 assert(s.contains(a) <==> s.to_multiset().count(a) > 0);
2952 }
2953 }
2954}
2955
2956pub broadcast proof fn to_multiset_update<A>(s: Seq<A>, i: int, a: A)
2957 requires
2958 0 <= i < s.len(),
2959 ensures
2960 #[trigger] s.update(i, a).to_multiset() == s.to_multiset().insert(a).remove(s[i]),
2961 decreases s.len(),
2962{
2963 broadcast use {
2964 super::seq_lib::lemma_seq_take_len,
2965 super::multiset::group_multiset_properties,
2966 super::multiset::group_multiset_axioms,
2967 to_multiset_insert,
2968 to_multiset_remove,
2969 to_multiset_contains,
2970 lemma_update_is_remove_insert,
2971 };
2972
2973 assert(s.update(i, a).to_multiset() =~= s.to_multiset().insert(a).remove(s[i]));
2974
2975}
2976
2977pub broadcast proof fn lemma_update_is_remove_insert<A>(s: Seq<A>, i: int, a: A)
2979 requires
2980 0 <= i < s.len(),
2981 ensures
2982 #[trigger] s.update(i, a) =~= s.remove(i).insert(i, a),
2983 decreases s.len(),
2984{
2985}
2986
2987pub proof fn lemma_append_last<A>(s1: Seq<A>, s2: Seq<A>)
2990 requires
2991 0 < s2.len(),
2992 ensures
2993 (s1 + s2).last() == s2.last(),
2994{
2995}
2996
2997pub proof fn lemma_concat_associative<A>(s1: Seq<A>, s2: Seq<A>, s3: Seq<A>)
2999 ensures
3000 s1.add(s2.add(s3)) =~= s1.add(s2).add(s3),
3001{
3002}
3003
3004spec fn seq_to_set_rec<A>(seq: Seq<A>) -> Set<A>
3006 decreases seq.len(),
3007{
3008 if seq.len() == 0 {
3009 Set::empty()
3010 } else {
3011 seq_to_set_rec(seq.drop_last()).insert(seq.last())
3012 }
3013}
3014
3015proof fn seq_to_set_rec_is_finite<A>(seq: Seq<A>)
3017 ensures
3018 seq_to_set_rec(seq).finite(),
3019 decreases seq.len(),
3020{
3021 broadcast use super::set::group_set_axioms;
3022
3023 if seq.len() > 0 {
3024 let sub_seq = seq.drop_last();
3025 assert(seq_to_set_rec(sub_seq).finite()) by {
3026 seq_to_set_rec_is_finite(sub_seq);
3027 }
3028 }
3029}
3030
3031proof fn seq_to_set_rec_contains<A>(seq: Seq<A>)
3033 ensures
3034 forall|a| #[trigger] seq.contains(a) <==> seq_to_set_rec(seq).contains(a),
3035 decreases seq.len(),
3036{
3037 broadcast use super::set::group_set_axioms;
3038
3039 if seq.len() > 0 {
3040 assert(forall|a| #[trigger]
3041 seq.drop_last().contains(a) <==> seq_to_set_rec(seq.drop_last()).contains(a)) by {
3042 seq_to_set_rec_contains(seq.drop_last());
3043 }
3044 assert(seq =~= seq.drop_last().push(seq.last()));
3045 assert forall|a| #[trigger] seq.contains(a) <==> seq_to_set_rec(seq).contains(a) by {
3046 if !seq.drop_last().contains(a) {
3047 if a == seq.last() {
3048 assert(seq.contains(a));
3049 assert(seq_to_set_rec(seq).contains(a));
3050 } else {
3051 assert(!seq_to_set_rec(seq).contains(a));
3052 }
3053 }
3054 }
3055 }
3056}
3057
3058proof fn seq_to_set_equal_rec<A>(seq: Seq<A>)
3060 ensures
3061 seq.to_set() == seq_to_set_rec(seq),
3062{
3063 broadcast use super::set::group_set_axioms;
3064
3065 assert(forall|n| #[trigger] seq.contains(n) <==> seq_to_set_rec(seq).contains(n)) by {
3066 seq_to_set_rec_contains(seq);
3067 }
3068 assert(forall|n| #[trigger] seq.contains(n) <==> seq.to_set().contains(n));
3069 assert(seq.to_set() =~= seq_to_set_rec(seq));
3070}
3071
3072pub broadcast proof fn seq_to_set_is_finite<A>(seq: Seq<A>)
3074 ensures
3075 #[trigger] seq.to_set().finite(),
3076{
3077 broadcast use super::set::group_set_axioms;
3078
3079 assert(seq.to_set().finite()) by {
3080 seq_to_set_equal_rec(seq);
3081 seq_to_set_rec_is_finite(seq);
3082 }
3083}
3084
3085pub proof fn seq_to_set_distributes_over_add<T>(s1: Seq<T>, s2: Seq<T>)
3086 ensures
3087 s1.to_set() + s2.to_set() =~= (s1 + s2).to_set(),
3088{
3089 broadcast use super::group_vstd_default;
3090 broadcast use super::set_lib::group_set_properties;
3091 broadcast use group_seq_properties;
3092
3093}
3094
3095pub proof fn lemma_no_dup_in_concat<A>(a: Seq<A>, b: Seq<A>)
3099 requires
3100 a.no_duplicates(),
3101 b.no_duplicates(),
3102 forall|i: int, j: int| 0 <= i < a.len() && 0 <= j < b.len() ==> a[i] != b[j],
3103 ensures
3104 #[trigger] (a + b).no_duplicates(),
3105{
3106}
3107
3108pub proof fn lemma_flatten_concat<A>(x: Seq<Seq<A>>, y: Seq<Seq<A>>)
3112 ensures
3113 (x + y).flatten() =~= x.flatten() + y.flatten(),
3114 decreases x.len(),
3115{
3116 if x.len() == 0 {
3117 assert(x + y =~= y);
3118 } else {
3119 assert((x + y).drop_first() =~= x.drop_first() + y);
3120 assert(x.first() + (x.drop_first() + y).flatten() =~= x.first() + x.drop_first().flatten()
3121 + y.flatten()) by {
3122 lemma_flatten_concat(x.drop_first(), y);
3123 }
3124 }
3125}
3126
3127pub proof fn lemma_flatten_alt_concat<A>(x: Seq<Seq<A>>, y: Seq<Seq<A>>)
3132 ensures
3133 (x + y).flatten_alt() =~= x.flatten_alt() + y.flatten_alt(),
3134 decreases y.len(),
3135{
3136 if y.len() == 0 {
3137 assert(x + y =~= x);
3138 } else {
3139 assert((x + y).drop_last() =~= x + y.drop_last());
3140 assert((x + y.drop_last()).flatten_alt() + y.last() =~= x.flatten_alt()
3141 + y.drop_last().flatten_alt() + y.last()) by {
3142 lemma_flatten_alt_concat(x, y.drop_last());
3143 }
3144 }
3145}
3146
3147pub broadcast proof fn lemma_seq_union_to_multiset_commutative<A>(a: Seq<A>, b: Seq<A>)
3150 ensures
3151 #[trigger] (a + b).to_multiset() =~= (b + a).to_multiset(),
3152{
3153 broadcast use super::multiset::group_multiset_axioms;
3154
3155 lemma_multiset_commutative(a, b);
3156 lemma_multiset_commutative(b, a);
3157}
3158
3159pub broadcast proof fn lemma_multiset_commutative<A>(a: Seq<A>, b: Seq<A>)
3162 ensures
3163 #[trigger] (a + b).to_multiset() =~= a.to_multiset().add(b.to_multiset()),
3164 decreases a.len(),
3165{
3166 broadcast use super::multiset::group_multiset_axioms;
3167
3168 if a.len() == 0 {
3169 assert(a + b =~= b);
3170 } else {
3171 lemma_multiset_commutative(a.drop_first(), b);
3172 assert(a.drop_first() + b =~= (a + b).drop_first());
3173 }
3174}
3175
3176pub proof fn lemma_sorted_unique<A>(x: Seq<A>, y: Seq<A>, leq: spec_fn(A, A) -> bool)
3178 requires
3179 sorted_by(x, leq),
3180 sorted_by(y, leq),
3181 total_ordering(leq),
3182 x.to_multiset() == y.to_multiset(),
3183 ensures
3184 x =~= y,
3185 decreases x.len(), y.len(),
3186{
3187 broadcast use super::multiset::group_multiset_axioms;
3188 broadcast use group_to_multiset_ensures;
3189
3190 if x.len() == 0 || y.len() == 0 {
3191 } else {
3192 assert(x.to_multiset().contains(x[0]));
3193 assert(x.to_multiset().contains(y[0]));
3194 let i = choose|i: int| #![trigger x.spec_index(i) ] 0 <= i < x.len() && x[i] == y[0];
3195 assert(leq(x[i], x[0]));
3196 assert(leq(x[0], x[i]));
3197 assert(x.drop_first().to_multiset() =~= x.to_multiset().remove(x[0]));
3198 assert(y.drop_first().to_multiset() =~= y.to_multiset().remove(y[0]));
3199 lemma_sorted_unique(x.drop_first(), y.drop_first(), leq);
3200 assert(x.drop_first() =~= y.drop_first());
3201 assert(x.first() == y.first());
3202 assert(x =~= Seq::<A>::empty().push(x.first()).add(x.drop_first()));
3203 assert(x =~= y);
3204 }
3205}
3206
3207pub broadcast proof fn lemma_seq_contains<A>(s: Seq<A>, x: A)
3209 ensures
3210 #[trigger] s.contains(x) <==> exists|i: int| 0 <= i < s.len() && #[trigger] s[i] == x,
3211{
3212}
3213
3214pub broadcast proof fn lemma_seq_empty_contains_nothing<A>(x: A)
3217 ensures
3218 !(#[trigger] Seq::<A>::empty().contains(x)),
3219{
3220}
3221
3222pub broadcast proof fn lemma_seq_empty_equality<A>(s: Seq<A>)
3226 ensures
3227 #[trigger] s.len() == 0 ==> s =~= Seq::<A>::empty(),
3228{
3229}
3230
3231pub broadcast proof fn lemma_seq_concat_contains_all_elements<A>(x: Seq<A>, y: Seq<A>, elt: A)
3235 ensures
3236 #[trigger] (x + y).contains(elt) <==> x.contains(elt) || y.contains(elt),
3237 decreases x.len(),
3238{
3239 if x.len() == 0 && y.len() > 0 {
3240 assert((x + y) =~= y);
3241 } else {
3242 assert forall|elt: A| #[trigger] x.contains(elt) implies #[trigger] (x + y).contains(
3243 elt,
3244 ) by {
3245 let index = choose|i: int| 0 <= i < x.len() && x[i] == elt;
3246 assert((x + y)[index] == elt);
3247 }
3248 assert forall|elt: A| #[trigger] y.contains(elt) implies #[trigger] (x + y).contains(
3249 elt,
3250 ) by {
3251 let index = choose|i: int| 0 <= i < y.len() && y[i] == elt;
3252 assert((x + y)[index + x.len()] == elt);
3253 }
3254 }
3255}
3256
3257pub broadcast proof fn lemma_seq_contains_after_push<A>(s: Seq<A>, v: A, x: A)
3260 ensures
3261 #[trigger] s.push(v).contains(x) <==> v == x || s.contains(x),
3262{
3263 assert forall|elt: A| #[trigger] s.contains(elt) implies #[trigger] s.push(v).contains(elt) by {
3264 let index = choose|i: int| 0 <= i < s.len() && s[i] == elt;
3265 assert(s.push(v)[index] == elt);
3266 }
3267 assert(s.push(v)[s.len() as int] == v);
3268}
3269
3270pub broadcast proof fn lemma_seq_subrange_elements<A>(s: Seq<A>, start: int, stop: int, x: A)
3274 requires
3275 0 <= start <= stop <= s.len(),
3276 ensures
3277 #[trigger] s.subrange(start, stop).contains(x) <==> (exists|i: int|
3278 0 <= start <= i < stop <= s.len() && #[trigger] s[i] == x),
3279{
3280 assert((exists|i: int| 0 <= start <= i < stop <= s.len() && s[i] == x) ==> s.subrange(
3281 start,
3282 stop,
3283 ).contains(x)) by {
3284 if exists|i: int| 0 <= start <= i < stop <= s.len() && s[i] == x {
3285 let index = choose|i: int| 0 <= start <= i < stop <= s.len() && s[i] == x;
3286 assert(s.subrange(start, stop)[index - start] == s[index]);
3287 }
3288 }
3289}
3290
3291pub open spec fn commutative_foldr<A, B>(f: spec_fn(A, B) -> B) -> bool {
3293 forall|x: A, y: A, v: B| #[trigger] f(x, f(y, v)) == f(y, f(x, v))
3294}
3295
3296pub open spec fn commutative_foldl<A, B>(f: spec_fn(B, A) -> B) -> bool {
3298 forall|x: A, y: A, v: B| #[trigger] f(f(v, x), y) == f(f(v, y), x)
3299}
3300
3301pub proof fn lemma_fold_right_permutation<A, B>(l1: Seq<A>, l2: Seq<A>, f: spec_fn(A, B) -> B, v: B)
3304 requires
3305 commutative_foldr(f),
3306 l1.to_multiset() == l2.to_multiset(),
3307 ensures
3308 l1.fold_right(f, v) == l2.fold_right(f, v),
3309 decreases l1.len(),
3310{
3311 broadcast use group_to_multiset_ensures;
3312
3313 if l1.len() > 0 {
3314 let a = l1.last();
3315 let i = l2.index_of(a);
3316 let l2r = l2.subrange(i + 1, l2.len() as int).fold_right(f, v);
3317
3318 assert(l1.to_multiset().count(a) > 0);
3319 l1.drop_last().lemma_fold_right_commute_one(a, f, v);
3320 l2.subrange(0, i).lemma_fold_right_commute_one(a, f, l2r);
3321
3322 l2.lemma_fold_right_split(f, v, i + 1);
3323 l2.remove(i).lemma_fold_right_split(f, v, i);
3324
3325 assert(l2.subrange(0, i + 1).drop_last() == l2.subrange(0, i));
3326 assert(l1.drop_last() == l1.remove(l1.len() - 1));
3327
3328 assert(l2.remove(i).subrange(0, i) == l2.subrange(0, i));
3329 assert(l2.remove(i).subrange(i, l2.remove(i).len() as int) == l2.subrange(
3330 i + 1,
3331 l2.len() as int,
3332 ));
3333
3334 lemma_fold_right_permutation(l1.drop_last(), l2.remove(i), f, v);
3335 } else {
3336 assert(l2.to_multiset().len() == 0);
3337 }
3338}
3339
3340pub proof fn lemma_fold_left_permutation<A, B>(l1: Seq<A>, l2: Seq<A>, f: spec_fn(B, A) -> B, v: B)
3343 requires
3344 commutative_foldl(f),
3345 l1.to_multiset() == l2.to_multiset(),
3346 ensures
3347 l1.fold_left(v, f) == l2.fold_left(v, f),
3348{
3349 let g = |a: A, b: B| f(b, a);
3350 assert(f =~= |b: B, a: A| g(a, b));
3351 assert(l1.fold_left(v, f) == l1.reverse().fold_right(g, v)) by {
3352 l1.lemma_reverse_fold_right(v, g)
3353 };
3354 assert(l2.fold_left(v, f) == l2.reverse().fold_right(g, v)) by {
3355 l2.lemma_reverse_fold_right(v, g)
3356 };
3357 assert(l1.reverse().to_multiset() =~= l2.reverse().to_multiset()) by {
3358 l1.lemma_reverse_to_multiset();
3359 l2.lemma_reverse_to_multiset();
3360 }
3361 assert(forall|x: A| #[trigger] l1.reverse().contains(x) ==> l1.contains(x));
3362 assert(forall|x: A| #[trigger] l2.reverse().contains(x) ==> l2.contains(x));
3363 lemma_fold_right_permutation(l1.reverse(), l2.reverse(), g, v);
3364}
3365
3366pub broadcast proof fn lemma_seq_take_len<A>(s: Seq<A>, n: int)
3372 ensures
3373 0 <= n <= s.len() ==> #[trigger] s.take(n).len() == n,
3374{
3375}
3376
3377pub broadcast proof fn lemma_seq_take_contains<A>(s: Seq<A>, n: int, x: A)
3381 requires
3382 0 <= n <= s.len(),
3383 ensures
3384 #[trigger] s.take(n).contains(x) <==> (exists|i: int|
3385 0 <= i < n <= s.len() && #[trigger] s[i] == x),
3386{
3387 assert((exists|i: int| 0 <= i < n <= s.len() && #[trigger] s[i] == x) ==> s.take(n).contains(x))
3388 by {
3389 if exists|i: int| 0 <= i < n <= s.len() && #[trigger] s[i] == x {
3390 let index = choose|i: int| 0 <= i < n <= s.len() && #[trigger] s[i] == x;
3391 assert(s.take(n)[index] == s[index]);
3392 }
3393 }
3394}
3395
3396pub broadcast proof fn lemma_seq_take_index<A>(s: Seq<A>, n: int, j: int)
3400 ensures
3401 0 <= j < n <= s.len() ==> #[trigger] s.take(n)[j] == s[j],
3402{
3403}
3404
3405pub proof fn subrange_of_matching_take<T>(a: Seq<T>, b: Seq<T>, s: int, e: int, l: int)
3406 requires
3407 a.take(l) == b.take(l),
3408 l <= a.len(),
3409 l <= b.len(),
3410 0 <= s <= e <= l,
3411 ensures
3412 a.subrange(s, e) == b.subrange(s, e),
3413{
3414 assert forall|i| 0 <= i < e - s implies a.subrange(s, e)[i] == b.subrange(s, e)[i] by {
3415 assert(a.subrange(s, e)[i] == a.take(l)[i + s]);
3416 }
3418 assert(a.subrange(s, e) == b.subrange(s, e));
3421}
3422
3423pub broadcast proof fn lemma_seq_skip_len<A>(s: Seq<A>, n: int)
3427 ensures
3428 0 <= n <= s.len() ==> #[trigger] s.skip(n).len() == s.len() - n,
3429{
3430}
3431
3432pub broadcast proof fn lemma_seq_skip_contains<A>(s: Seq<A>, n: int, x: A)
3436 requires
3437 0 <= n <= s.len(),
3438 ensures
3439 #[trigger] s.skip(n).contains(x) <==> (exists|i: int|
3440 0 <= n <= i < s.len() && #[trigger] s[i] == x),
3441{
3442 assert((exists|i: int| 0 <= n <= i < s.len() && #[trigger] s[i] == x) ==> s.skip(n).contains(x))
3443 by {
3444 let index = choose|i: int| 0 <= n <= i < s.len() && #[trigger] s[i] == x;
3445 lemma_seq_skip_index(s, n, index - n);
3446 }
3447}
3448
3449pub broadcast proof fn lemma_seq_skip_index<A>(s: Seq<A>, n: int, j: int)
3453 ensures
3454 0 <= n && 0 <= j < (s.len() - n) ==> #[trigger] s.skip(n)[j] == s[j + n],
3455{
3456}
3457
3458pub broadcast proof fn lemma_seq_skip_index2<A>(s: Seq<A>, n: int, k: int)
3463 ensures
3464 0 <= n <= k < s.len() ==> (#[trigger] s.skip(n))[k - n] == #[trigger] s[k],
3465{
3466}
3467
3468pub broadcast proof fn lemma_seq_append_take_skip<A>(a: Seq<A>, b: Seq<A>, n: int)
3473 ensures
3474 #![trigger (a + b).take(n)]
3475 #![trigger (a + b).skip(n)]
3476 n == a.len() ==> ((a + b).take(n) =~= a && (a + b).skip(n) =~= b),
3477{
3478}
3479
3480pub broadcast proof fn lemma_seq_take_update_commut1<A>(s: Seq<A>, i: int, v: A, n: int)
3487 ensures
3488 #![trigger s.update(i, v).take(n)]
3489 0 <= i < n <= s.len() ==> #[trigger] s.update(i, v).take(n) =~= s.take(n).update(i, v),
3490{
3491}
3492
3493pub broadcast proof fn lemma_seq_take_update_commut2<A>(s: Seq<A>, i: int, v: A, n: int)
3498 ensures
3499 0 <= n <= i < s.len() ==> #[trigger] s.update(i, v).take(n) =~= s.take(n),
3500{
3501}
3502
3503pub broadcast proof fn lemma_seq_skip_update_commut1<A>(s: Seq<A>, i: int, v: A, n: int)
3508 ensures
3509 0 <= n <= i < s.len() ==> #[trigger] s.update(i, v).skip(n) =~= s.skip(n).update(i - n, v),
3510{
3511}
3512
3513pub broadcast proof fn lemma_seq_skip_update_commut2<A>(s: Seq<A>, i: int, v: A, n: int)
3518 ensures
3519 0 <= i < n <= s.len() ==> #[trigger] s.update(i, v).skip(n) =~= s.skip(n),
3520{
3521}
3522
3523pub broadcast proof fn lemma_seq_skip_build_commut<A>(s: Seq<A>, v: A, n: int)
3527 ensures
3528 #![trigger s.push(v).skip(n)]
3529 0 <= n <= s.len() ==> s.push(v).skip(n) =~= s.skip(n).push(v),
3530{
3531}
3532
3533pub broadcast proof fn lemma_seq_skip_nothing<A>(s: Seq<A>, n: int)
3536 ensures
3537 n == 0 ==> #[trigger] s.skip(n) =~= s,
3538{
3539}
3540
3541pub broadcast proof fn lemma_seq_take_nothing<A>(s: Seq<A>, n: int)
3544 ensures
3545 n == 0 ==> #[trigger] s.take(n) =~= Seq::<A>::empty(),
3546{
3547}
3548
3549pub broadcast proof fn lemma_seq_skip_of_skip<A>(s: Seq<A>, m: int, n: int)
3554 ensures
3555 (0 <= m && 0 <= n && m + n <= s.len()) ==> #[trigger] s.skip(m).skip(n) =~= s.skip(m + n),
3556{
3557}
3558
3559#[doc(hidden)]
3560#[verifier::inline]
3561pub open spec fn check_argument_is_seq<A>(s: Seq<A>) -> Seq<A> {
3562 s
3563}
3564
3565#[macro_export]
3610macro_rules! assert_seqs_equal {
3611 [$($tail:tt)*] => {
3612 $crate::vstd::prelude::verus_proof_macro_exprs!($crate::vstd::seq_lib::assert_seqs_equal_internal!($($tail)*))
3613 };
3614}
3615
3616#[macro_export]
3617#[doc(hidden)]
3618macro_rules! assert_seqs_equal_internal {
3619 (::vstd::spec_eq($s1:expr, $s2:expr)) => {
3620 $crate::vstd::seq_lib::assert_seqs_equal_internal!($s1, $s2)
3621 };
3622 (::vstd::prelude::spec_eq($s1:expr, $s2:expr)) => {
3623 $crate::vstd::seq_lib::assert_seqs_equal_internal!($s1, $s2)
3624 };
3625 (::vstd::prelude::spec_eq($s1:expr, $s2:expr), $idx:ident => $bblock:block) => {
3626 $crate::vstd::seq_lib::assert_seqs_equal_internal!($s1, $s2, $idx => $bblock)
3627 };
3628 (crate::prelude::spec_eq($s1:expr, $s2:expr)) => {
3629 $crate::vstd::seq_lib::assert_seqs_equal_internal!($s1, $s2)
3630 };
3631 (crate::prelude::spec_eq($s1:expr, $s2:expr), $idx:ident => $bblock:block) => {
3632 $crate::vstd::seq_lib::assert_seqs_equal_internal!($s1, $s2, $idx => $bblock)
3633 };
3634 (crate::verus_builtin::spec_eq($s1:expr, $s2:expr)) => {
3635 $crate::vstd::seq_lib::assert_seqs_equal_internal!($s1, $s2)
3636 };
3637 (crate::verus_builtin::spec_eq($s1:expr, $s2:expr), $idx:ident => $bblock:block) => {
3638 $crate::vstd::seq_lib::assert_seqs_equal_internal!($s1, $s2, $idx => $bblock)
3639 };
3640 ($s1:expr, $s2:expr $(,)?) => {
3641 $crate::vstd::seq_lib::assert_seqs_equal_internal!($s1, $s2, idx => { })
3642 };
3643 ($s1:expr, $s2:expr, $idx:ident => $bblock:block) => {
3644 #[verifier::spec] let s1 = $crate::vstd::seq_lib::check_argument_is_seq($s1);
3645 #[verifier::spec] let s2 = $crate::vstd::seq_lib::check_argument_is_seq($s2);
3646 $crate::vstd::prelude::assert_by($crate::vstd::prelude::equal(s1, s2), {
3647 $crate::vstd::prelude::assert_(s1.len() == s2.len());
3648 $crate::vstd::prelude::assert_forall_by(|$idx : $crate::vstd::prelude::int| {
3649 $crate::vstd::prelude::requires($crate::vstd::prelude::verus_proof_expr!(0 <= $idx && $idx < s1.len()));
3650 $crate::vstd::prelude::ensures($crate::vstd::prelude::equal(s1.index($idx), s2.index($idx)));
3651 { $bblock }
3652 });
3653 $crate::vstd::prelude::assert_($crate::vstd::prelude::ext_equal(s1, s2));
3654 });
3655 }
3656}
3657
3658pub broadcast group group_filter_ensures {
3659 Seq::lemma_filter_len,
3660 Seq::lemma_filter_pred,
3661 Seq::lemma_filter_contains,
3662}
3663
3664pub broadcast group group_seq_lib_default {
3665 group_filter_ensures,
3666 Seq::add_empty_left,
3667 Seq::add_empty_right,
3668 Seq::push_distributes_over_add,
3669 Seq::filter_distributes_over_add,
3670 seq_to_set_is_finite,
3671 Seq::lemma_fold_right_split,
3672 Seq::lemma_fold_left_split,
3673}
3674
3675pub broadcast group group_to_multiset_ensures {
3676 to_multiset_build,
3677 to_multiset_remove,
3678 to_multiset_len,
3679 to_multiset_contains,
3680 to_multiset_insert,
3681 to_multiset_update,
3682}
3683
3684pub broadcast group group_seq_properties {
3686 lemma_seq_contains,
3687 lemma_seq_empty_contains_nothing,
3688 lemma_seq_empty_equality,
3689 lemma_seq_concat_contains_all_elements,
3690 lemma_seq_contains_after_push,
3691 lemma_seq_subrange_elements,
3692 lemma_seq_take_len,
3693 lemma_seq_take_contains,
3694 lemma_seq_take_index,
3695 lemma_seq_skip_len,
3696 lemma_seq_skip_contains,
3697 lemma_seq_skip_index,
3698 lemma_seq_skip_index2,
3699 lemma_seq_append_take_skip,
3700 lemma_seq_take_update_commut1,
3701 lemma_seq_take_update_commut2,
3702 lemma_seq_skip_update_commut1,
3703 lemma_seq_skip_update_commut2,
3704 lemma_seq_skip_build_commut,
3705 lemma_seq_skip_nothing,
3706 lemma_seq_take_nothing,
3707 group_to_multiset_ensures,
3711}
3712
3713#[doc(hidden)]
3714pub use assert_seqs_equal_internal;
3715pub use assert_seqs_equal;
3716
3717}