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_lemmas;
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 broadcast proof fn lemma_as_ref_index(self, i: int)
57 requires
58 0 <= i < self.len(),
59 ensures
60 #![trigger self.as_ref(), self[i]]
61 *self.as_ref()[i] == self[i],
62 {
63 }
64
65 pub open spec fn is_prefix_of(self, other: Self) -> bool {
77 self.len() <= other.len() && self =~= other[..self.len()]
78 }
79
80 pub open spec fn is_suffix_of(self, other: Self) -> bool {
92 &&& self.len() <= other.len()
93 &&& self =~= other[other.len() - self.len()..other.len()]
94 }
95
96 pub closed spec fn sort_by(self, leq: spec_fn(A, A) -> bool) -> Seq<A>
104 recommends
105 total_ordering(leq),
106 decreases self.len(),
107 {
108 if self.len() <= 1 {
109 self
110 } else {
111 let split_index = self.len() / 2;
112 let left = self[..split_index];
113 let right = self[split_index..];
114 let left_sorted = left.sort_by(leq);
115 let right_sorted = right.sort_by(leq);
116 merge_sorted_with(left_sorted, right_sorted, leq)
117 }
118 }
119
120 pub open spec fn all(self, pred: spec_fn(A) -> bool) -> bool {
131 forall|i: int| 0 <= i < self.len() ==> #[trigger] pred(self[i])
132 }
133
134 pub open spec fn any(self, pred: spec_fn(A) -> bool) -> bool {
145 exists|i: int| 0 <= i < self.len() && #[trigger] pred(self[i])
146 }
147
148 pub open spec fn exactly_one(self, pred: spec_fn(A) -> bool) -> bool {
158 self.filter(pred).len() == 1
159 }
160
161 pub proof fn lemma_sort_by_ensures(self, leq: spec_fn(A, A) -> bool)
162 requires
163 total_ordering(leq),
164 ensures
165 self.to_multiset() =~= self.sort_by(leq).to_multiset(),
166 sorted_by(self.sort_by(leq), leq),
167 forall|x: A| !self.contains(x) ==> !(#[trigger] self.sort_by(leq).contains(x)),
168 decreases self.len(),
169 {
170 if self.len() <= 1 {
171 } else {
172 let split_index = self.len() / 2;
173 let left = self[..split_index];
174 let right = self[split_index..];
175 assert(self =~= left + right);
176 let left_sorted = left.sort_by(leq);
177 left.lemma_sort_by_ensures(leq);
178 let right_sorted = right.sort_by(leq);
179 right.lemma_sort_by_ensures(leq);
180 lemma_merge_sorted_with_ensures(left_sorted, right_sorted, leq);
181 lemma_multiset_commutative(left, right);
182 lemma_multiset_commutative(left_sorted, right_sorted);
183 assert forall|x: A| !self.contains(x) implies !(#[trigger] self.sort_by(leq).contains(
184 x,
185 )) by {
186 broadcast use group_to_multiset_ensures;
187
188 assert(!self.contains(x) ==> self.to_multiset().count(x) == 0);
189 }
190 }
191 }
192
193 #[verifier::opaque]
207 pub open spec fn filter(self, pred: spec_fn(A) -> bool) -> Self
208 decreases self.len(),
209 {
210 if self.len() == 0 {
211 self
212 } else {
213 let subseq = self.drop_last().filter(pred);
214 if pred(self.last()) {
215 subseq.push(self.last())
216 } else {
217 subseq
218 }
219 }
220 }
221
222 pub broadcast proof fn lemma_filter_len(self, pred: spec_fn(A) -> bool)
223 ensures
224 #[trigger] self.filter(pred).len() <= self.len(),
227 decreases self.len(),
228 {
229 reveal(Seq::filter);
230 let out = self.filter(pred);
231 if 0 < self.len() {
232 self.drop_last().lemma_filter_len(pred);
233 }
234 }
235
236 pub broadcast proof fn lemma_filter_pred(self, pred: spec_fn(A) -> bool, i: int)
237 requires
238 0 <= i < self.filter(pred).len(),
239 ensures
240 pred(#[trigger] self.filter(pred)[i]),
241 {
242 #[allow(deprecated)]
244 self.filter_lemma(pred);
245 }
246
247 pub broadcast proof fn lemma_filter_contains(self, pred: spec_fn(A) -> bool, i: int)
248 requires
249 0 <= i < self.len() && pred(self[i]),
250 ensures
251 #[trigger] self.filter(pred).contains(self[i]),
252 {
253 #[allow(deprecated)]
255 self.filter_lemma(pred);
256 }
257
258 #[cfg_attr(not(verus_verify_core), deprecated = "Use `broadcast use group_filter_ensures` instead" )]
260 pub proof fn filter_lemma(self, pred: spec_fn(A) -> bool)
261 ensures
262 forall|i: int|
268 0 <= i < self.filter(pred).len() ==> pred(#[trigger] self.filter(pred)[i]),
269 forall|i: int|
271 0 <= i < self.len() && pred(self[i]) ==> #[trigger] self.filter(pred).contains(
272 self[i],
273 ),
274 #[trigger] self.filter(pred).len() <= self.len(),
276 decreases self.len(),
277 {
278 reveal(Seq::filter);
279 let out = self.filter(pred);
280 if 0 < self.len() {
281 self.drop_last().filter_lemma(pred);
282 assert forall|i: int| 0 <= i < out.len() implies pred(out[i]) by {
283 if i < out.len() - 1 {
284 assert(self.drop_last().filter(pred)[i] == out.drop_last()[i]); assert(pred(out[i])); }
287 }
288 assert forall|i: int|
289 0 <= i < self.len() && pred(self[i]) implies #[trigger] out.contains(self[i]) by {
290 if i == self.len() - 1 {
291 assert(self[i] == out[out.len() - 1]); } else {
293 let subseq = self.drop_last().filter(pred);
294 assert(subseq.contains(self.drop_last()[i])); let j = choose|j| 0 <= j < subseq.len() && subseq[j] == self[i];
296 assert(out[j] == self[i]); }
298 }
299 }
300 }
301
302 pub broadcast proof fn filter_distributes_over_add(a: Self, b: Self, pred: spec_fn(A) -> bool)
303 ensures
304 #[trigger] (a + b).filter(pred) == a.filter(pred) + b.filter(pred),
305 decreases b.len(),
306 {
307 reveal(Seq::filter);
308 if 0 < b.len() {
309 Self::drop_last_distributes_over_add(a, b);
310 Self::filter_distributes_over_add(a, b.drop_last(), pred);
311 if pred(b.last()) {
312 Self::push_distributes_over_add(
313 a.filter(pred),
314 b.drop_last().filter(pred),
315 b.last(),
316 );
317 }
318 } else {
319 Self::add_empty_right(a, b);
320 Self::add_empty_right(a.filter(pred), b.filter(pred));
321 }
322 }
323
324 #[verifier::opaque]
348 pub open spec fn filter_index(self, pred: spec_fn(int) -> bool) -> Self
349 decreases self.len(),
350 {
351 if self.len() == 0 {
352 self
353 } else {
354 let subseq = self.drop_last().filter_index(pred);
355 if pred(self.len() - 1) {
356 subseq.push(self.last())
357 } else {
358 subseq
359 }
360 }
361 }
362
363 broadcast proof fn lemma_filter_index_len(self, pred: spec_fn(int) -> bool)
365 ensures
366 #[trigger] (self.filter_index(pred).len()) <= self.len(),
367 decreases self.len(),
368 {
369 reveal(Seq::filter_index);
370 if self.len() != 0 {
371 self.drop_last().lemma_filter_index_len(pred);
372 }
373 }
374
375 proof fn lemma_filter_index_source(self, pred: spec_fn(int) -> bool)
377 ensures
378 self.filter_index_range(pred),
379 decreases self.len(),
380 {
381 reveal(Seq::filter_index);
382 if self.len() != 0 {
383 let s_rest = self.drop_last();
384 assert(s_rest.len() == self.len() - 1);
385 s_rest.lemma_filter_index_source(pred);
386 let rest = s_rest.filter_index(pred);
387 let result = self.filter_index(pred);
388 let last_idx = (self.len() - 1) as int;
389 assert(forall|k: int| 0 <= k < s_rest.len() ==> #[trigger] s_rest[k] == self[k]);
390
391 if pred(last_idx) {
392 assert(result =~= rest.push(self.last()));
393 } else {
394 assert(result =~= rest);
395 }
396
397 assert forall|i: int| 0 <= i < result.len() implies (exists|j: int|
398 0 <= j < self.len() && #[trigger] result[i] == #[trigger] self[j] && pred(j)) by {
399 if pred(last_idx) && i == rest.len() {
400 assert(result[i] == self[last_idx]);
401 } else {
402 assert(result[i] == rest[i]);
403 let j_rest = choose|j: int|
404 0 <= j < s_rest.len() && rest[i] == s_rest[j] && pred(j);
405 assert(self[j_rest] == s_rest[j_rest]);
406 }
407 }
408 }
409 }
410
411 proof fn lemma_filter_index_witness(self, pred: spec_fn(int) -> bool)
413 ensures
414 self.filter_index_domain(pred),
415 decreases self.len(),
416 {
417 reveal(Seq::filter_index);
418 if self.len() != 0 {
419 let s_rest = self.drop_last();
420 assert(s_rest.len() == self.len() - 1);
421 s_rest.lemma_filter_index_witness(pred);
422 s_rest.lemma_filter_index_len(pred);
423 let rest = s_rest.filter_index(pred);
424 let result = self.filter_index(pred);
425 let last_idx = (self.len() - 1) as int;
426 assert(forall|k: int| 0 <= k < s_rest.len() ==> #[trigger] s_rest[k] == self[k]);
427
428 if pred(last_idx) {
429 assert(result =~= rest.push(self.last()));
430 } else {
431 assert(result =~= rest);
432 }
433
434 s_rest.lemma_filter_index_source(pred);
435 assert forall|i: int| 0 <= i < result.len() implies (exists|j: int|
436 0 <= j < self.len() && #[trigger] result[i] == #[trigger] self[j] && pred(j)) by {
437 if pred(last_idx) && i == rest.len() {
438 assert(result[i] == self[last_idx]);
439 } else {
440 assert(result[i] == rest[i]);
441 let j_rest = choose|j: int|
442 0 <= j < s_rest.len() && rest[i] == s_rest[j] && pred(j);
443 assert(self[j_rest] == s_rest[j_rest]);
444 }
445 }
446
447 assert forall|j: int| 0 <= j < self.len() && pred(j) implies (exists|i: int|
448 0 <= i < self.filter_index(pred).len() && #[trigger] self[j] == self.filter_index(
449 pred,
450 )[i]) by {
451 if j == last_idx {
452 assert(result =~= rest.push(self.last()));
453 assert(self.filter_index(pred)[rest.len() as int] == self[j]);
454 } else {
455 assert(rest.contains(s_rest[j]));
456 let w = choose|i: int| 0 <= i < rest.len() && rest[i] == s_rest[j];
457 assert(self.filter_index(pred)[w] == self[j]);
458 }
459 }
460 }
461 }
462
463 pub open spec fn filter_index_range(self, pred: spec_fn(int) -> bool) -> bool {
465 forall|i|
466 0 <= i < self.filter_index(pred).len() ==> (exists|j|
467 0 <= j < self.len() && #[trigger] self.filter_index(pred)[i] == #[trigger] self[j]
468 && pred(j))
469 }
470
471 pub open spec fn filter_index_domain(self, pred: spec_fn(int) -> bool) -> bool {
473 forall|j|
474 0 <= j < self.len() && pred(j) ==> #[trigger] self.filter_index(pred).contains(self[j])
475 }
476
477 pub broadcast proof fn lemma_filter_index(self, pred: spec_fn(int) -> bool)
479 ensures
480 (#[trigger] self.filter_index(pred)).len() <= self.len(),
483 self.filter_index_range(pred),
485 self.filter_index_domain(pred),
487 decreases self.len(),
488 {
489 self.lemma_filter_index_len(pred);
490 self.lemma_filter_index_source(pred);
491 self.lemma_filter_index_witness(pred);
492 }
493
494 pub proof fn filter_index_ext(self, p: spec_fn(int) -> bool, q: spec_fn(int) -> bool)
497 requires
498 forall|i| 0 <= i < self.len() ==> #[trigger] p(i) == q(i),
499 ensures
500 self.filter_index(p) == self.filter_index(q),
501 decreases self.len(),
502 {
503 reveal(Seq::filter_index);
504 if self.len() != 0 {
505 self.drop_last().filter_index_ext(p, q);
506 }
507 }
508
509 pub proof fn lemma_filter_index_head(self, pred: spec_fn(int) -> bool)
511 requires
512 self.len() > 0,
513 ensures
514 pred(0) ==> self.filter_index(pred) == seq![self[0]] + self.drop_first().filter_index(
515 |i: int| pred(i + 1),
516 ),
517 !pred(0) ==> self.filter_index(pred) == self.drop_first().filter_index(
518 |i: int| pred(i + 1),
519 ),
520 decreases self.len(),
521 {
522 reveal(Seq::filter_index);
523 let p2 = |i: int| pred(i + 1);
524 let t = self.drop_first();
525 if self.len() == 1 {
526 reveal_with_fuel(Seq::filter_index, 2);
527 assert(t.len() == 0);
528 assert(self.drop_last().len() == 0);
529 if pred(0) {
530 assert(self.filter_index(pred) =~= seq![self[0]] + t.filter_index(p2));
531 } else {
532 assert(self.filter_index(pred) =~= t.filter_index(p2));
533 }
534 } else {
535 let sdl = self.drop_last();
536 sdl.lemma_filter_index_head(pred);
537 assert(t.drop_last() =~= sdl.drop_first());
538 let p2b = |i: int| pred(i + 1);
539 sdl.drop_first().filter_index_ext(p2, p2b);
540 if pred(0) {
541 assert(self.filter_index(pred) =~= seq![self[0]] + t.filter_index(p2));
542 } else {
543 assert(self.filter_index(pred) =~= t.filter_index(p2));
544 }
545 }
546 }
547
548 pub broadcast proof fn add_empty_left(a: Self, b: Self)
549 requires
550 a.len() == 0,
551 ensures
552 #[trigger] (a + b) == b,
553 {
554 assert(a + b =~= b);
555 }
556
557 pub broadcast proof fn add_empty_right(a: Self, b: Self)
558 requires
559 b.len() == 0,
560 ensures
561 #[trigger] (a + b) == a,
562 {
563 assert(a + b =~= a);
564 }
565
566 pub broadcast proof fn push_distributes_over_add(a: Self, b: Self, elt: A)
567 ensures
568 #[trigger] (a + b).push(elt) == a + b.push(elt),
569 {
570 assert((a + b).push(elt) =~= a + b.push(elt));
571 }
572
573 pub open spec fn max_via(self, leq: spec_fn(A, A) -> bool) -> A
575 recommends
576 self.len() > 0,
577 decreases self.len(),
578 {
579 if self.len() > 1 {
580 if leq(self[0], self[1..].max_via(leq)) {
581 self[1..].max_via(leq)
582 } else {
583 self[0]
584 }
585 } else {
586 self[0]
587 }
588 }
589
590 pub open spec fn min_via(self, leq: spec_fn(A, A) -> bool) -> A
592 recommends
593 self.len() > 0,
594 decreases self.len(),
595 {
596 if self.len() > 1 {
597 let subseq = self[1..];
598 let elt = subseq.min_via(leq);
599 if leq(elt, self[0]) {
600 elt
601 } else {
602 self[0]
603 }
604 } else {
605 self[0]
606 }
607 }
608
609 pub open spec fn contains(self, needle: A) -> bool {
611 exists|i: int| 0 <= i < self.len() && self[i] == needle
612 }
613
614 pub open spec fn index_of(self, needle: A) -> int {
617 choose|i: int| 0 <= i < self.len() && self[i] == needle
618 }
619
620 pub closed spec fn index_of_first(self, needle: A) -> (result: Option<int>) {
623 if self.contains(needle) {
624 Some(self.first_index_helper(needle))
625 } else {
626 None
627 }
628 }
629
630 spec fn first_index_helper(self, needle: A) -> int
632 recommends
633 self.contains(needle),
634 decreases self.len(),
635 {
636 if self.len() <= 0 {
637 -1 } else if self[0] == needle {
640 0
641 } else {
642 1 + self[1..].first_index_helper(needle)
643 }
644 }
645
646 pub proof fn index_of_first_ensures(self, needle: A)
647 ensures
648 match self.index_of_first(needle) {
649 Some(index) => {
650 &&& self.contains(needle)
651 &&& 0 <= index < self.len()
652 &&& self[index] == needle
653 &&& forall|j: int| 0 <= j < index < self.len() ==> self[j] != needle
654 },
655 None => { !self.contains(needle) },
656 },
657 decreases self.len(),
658 {
659 if self.contains(needle) {
660 let index = self.index_of_first(needle).unwrap();
661 if self.len() <= 0 {
662 } else if self[0] == needle {
663 } else {
664 assert(Seq::empty().push(self.first()).add(self.drop_first()) =~= self);
665 self.drop_first().index_of_first_ensures(needle);
666 }
667 }
668 }
669
670 pub closed spec fn index_of_last(self, needle: A) -> Option<int> {
673 if self.contains(needle) {
674 Some(self.last_index_helper(needle))
675 } else {
676 None
677 }
678 }
679
680 spec fn last_index_helper(self, needle: A) -> int
682 recommends
683 self.contains(needle),
684 decreases self.len(),
685 {
686 if self.len() <= 0 {
687 -1 } else if self.last() == needle {
690 self.len() - 1
691 } else {
692 self.drop_last().last_index_helper(needle)
693 }
694 }
695
696 pub proof fn index_of_last_ensures(self, needle: A)
697 ensures
698 match self.index_of_last(needle) {
699 Some(index) => {
700 &&& self.contains(needle)
701 &&& 0 <= index < self.len()
702 &&& self[index] == needle
703 &&& forall|j: int| 0 <= index < j < self.len() ==> self[j] != needle
704 },
705 None => { !self.contains(needle) },
706 },
707 decreases self.len(),
708 {
709 if self.contains(needle) {
710 let index = self.index_of_last(needle).unwrap();
711 if self.len() <= 0 {
712 } else if self.last() == needle {
713 } else {
714 assert(self.drop_last().push(self.last()) =~= self);
715 self.drop_last().index_of_last_ensures(needle);
716 }
717 }
718 }
719
720 pub open spec fn drop_last(self) -> Seq<A>
725 recommends
726 self.len() >= 1,
727 {
728 self.subrange(0, self.len() as int - 1)
729 }
730
731 pub proof fn drop_last_distributes_over_add(a: Self, b: Self)
734 requires
735 0 < b.len(),
736 ensures
737 (a + b).drop_last() == a + b.drop_last(),
738 {
739 }
740
741 pub open spec fn drop_first(self) -> Seq<A>
742 recommends
743 self.len() >= 1,
744 {
745 self.subrange(1, self.len() as int)
746 }
747
748 pub open spec fn no_duplicates(self) -> bool {
750 forall|i, j| (0 <= i < self.len() && 0 <= j < self.len() && i != j) ==> self[i] != self[j]
751 }
752
753 pub open spec fn disjoint(self, other: Self) -> bool {
755 forall|i: int, j: int| 0 <= i < self.len() && 0 <= j < other.len() ==> self[i] != other[j]
756 }
757
758 pub closed spec fn to_set(self) -> Set<A> {
760 Set::range(0, self.len() as int).map(|i| self.index(i))
761 }
762
763 pub broadcast proof fn to_set_ensures(self)
764 ensures
765 #![trigger(self.to_set())]
766 forall|i|
768 0 <= i < self.len() ==> #[trigger] self.to_set().contains(self[i]),
769 forall|a| #[trigger] self.to_set().contains(a) <==> self.contains(a),
771 {
772 broadcast use super::set::group_set_lemmas;
773 broadcast use super::set_lib::range_set_properties;
774
775 assert forall|i| 0 <= i < self.len() implies #[trigger] self.to_set().contains(self[i]) by {
776 Set::range(0, self.len() as int).lemma_map_contains(|i: int| self.index(i), self[i]);
777 assert(Set::range(0, self.len() as int).contains(i));
778 assert(self.to_set().contains(self[i]));
779 }
780 assert forall|a| #[trigger] self.to_set().contains(a) <==> self.contains(a) by {
781 Set::range(0, self.len() as int).lemma_map_contains(|i: int| self.index(i), a);
782 if self.to_set().contains(a) {
783 let i = choose|i: int| #[trigger]
784 Set::range(0, self.len() as int).contains(i) && self.index(i) == a;
785 assert(0 <= i < self.len());
786 assert(self.contains(a));
787 }
788 if self.contains(a) {
789 let i = choose|i: int| 0 <= i < self.len() && self[i] == a;
790 assert(self.to_set().contains(self[i]));
791 assert(a == self[i]);
792 }
793 }
794 }
795
796 pub open spec fn to_iset(self) -> ISet<A> {
797 self.to_set().to_iset()
798 }
799
800 pub closed spec fn to_multiset(self) -> Multiset<A>
802 decreases self.len(),
803 {
804 if self.len() == 0 {
805 Multiset::<A>::empty()
806 } else {
807 Multiset::<A>::empty().insert(self.first()).add(self.drop_first().to_multiset())
808 }
809 }
810
811 pub broadcast proof fn to_multiset_ensures(self)
815 ensures
816 forall|a: A| #[trigger] (self.push(a).to_multiset()) =~= self.to_multiset().insert(a), forall|i: int|
818 0 <= i < self.len() ==> #[trigger] (self.remove(i).to_multiset())
819 =~= self.to_multiset().remove(self[i]), self.len() == #[trigger] self.to_multiset().len(), forall|a: A|
822 self.contains(a) <==> #[trigger] self.to_multiset().count(a)
823 > 0, {
825 broadcast use group_seq_properties;
826
827 }
828
829 pub open spec fn insert(self, i: int, a: A) -> Seq<A>
831 recommends
832 0 <= i <= self.len(),
833 {
834 self.subrange(0, i).push(a) + self.subrange(i, self.len() as int)
835 }
836
837 pub proof fn insert_ensures(self, pos: int, elt: A)
839 requires
840 0 <= pos <= self.len(),
841 ensures
842 self.insert(pos, elt).len() == self.len() + 1,
843 forall|i: int| 0 <= i < pos ==> #[trigger] self.insert(pos, elt)[i] == self[i],
844 forall|i: int| pos <= i < self.len() ==> self.insert(pos, elt)[i + 1] == self[i],
845 self.insert(pos, elt)[pos] == elt,
846 {
847 }
848
849 pub open spec fn remove(self, i: int) -> Seq<A>
851 recommends
852 0 <= i < self.len(),
853 {
854 self.subrange(0, i) + self.subrange(i + 1, self.len() as int)
855 }
856
857 pub proof fn remove_ensures(self, i: int)
859 requires
860 0 <= i < self.len(),
861 ensures
862 self.remove(i).len() == self.len() - 1,
863 forall|index: int| 0 <= index < i ==> #[trigger] self.remove(i)[index] == self[index],
864 forall|index: int|
865 i <= index < self.len() - 1 ==> #[trigger] self.remove(i)[index] == self[index + 1],
866 {
867 }
868
869 pub open spec fn remove_value(self, val: A) -> Seq<A> {
872 let index = self.index_of_first(val);
873 match index {
874 Some(i) => self.remove(i),
875 None => self,
876 }
877 }
878
879 pub open spec fn reverse(self) -> Seq<A>
881 decreases self.len(),
882 {
883 if self.len() == 0 {
884 Seq::empty()
885 } else {
886 Seq::new(self.len(), |i: int| self[self.len() - 1 - i])
887 }
888 }
889
890 pub open spec fn zip_with<B>(self, other: Seq<B>) -> Seq<(A, B)>
893 recommends
894 self.len() == other.len(),
895 decreases self.len(),
896 {
897 if self.len() != other.len() {
898 Seq::empty()
899 } else if self.len() == 0 {
900 Seq::empty()
901 } else {
902 Seq::new(self.len(), |i: int| (self[i], other[i]))
903 }
904 }
905
906 pub open spec fn zip_truncate<B>(self, other: Seq<B>) -> Seq<(A, B)> {
908 if self.len() == other.len() {
909 self.zip_with(other)
911 } else if self.len() < other.len() {
912 self.zip_with(other[..self.len()])
913 } else {
914 self[..other.len()].zip_with(other)
915 }
916 }
917
918 pub open spec fn fold_left<B>(self, b: B, f: spec_fn(B, A) -> B) -> (res: B)
925 decreases self.len(),
926 {
927 if self.len() == 0 {
928 b
929 } else {
930 f(self.drop_last().fold_left(b, f), self.last())
931 }
932 }
933
934 pub open spec fn fold_left_alt<B>(self, b: B, f: spec_fn(B, A) -> B) -> (res: B)
938 decreases self.len(),
939 {
940 if self.len() == 0 {
941 b
942 } else {
943 self[1..].fold_left_alt(f(b, self[0]), f)
944 }
945 }
946
947 pub broadcast proof fn lemma_fold_left_split<B>(self, b: B, f: spec_fn(B, A) -> B, k: int)
949 requires
950 0 <= k <= self.len(),
951 ensures
952 self[k..].fold_left((#[trigger] self[..k].fold_left(b, f)), f) == self.fold_left(b, f),
953 decreases self.len(),
954 {
955 reveal_with_fuel(Seq::fold_left, 2);
956 if k == self.len() {
957 assert(self[0..] == self);
958 } else {
959 self.drop_last().lemma_fold_left_split(b, f, k);
960 assert(self.drop_last()[k..self.drop_last().len()] =~= self[k..self.len() - 1]);
961 assert(self.drop_last()[..k] =~= self[..k]);
962 assert(self[k..].drop_last() =~= self[k..self.len() - 1]);
963 }
964 }
965
966 proof fn aux_lemma_fold_left_alt<B>(self, b: B, f: spec_fn(B, A) -> B, k: int)
968 requires
969 0 < k <= self.len(),
970 ensures
971 self[k..].fold_left_alt(self[..k].fold_left_alt(b, f), f) == self.fold_left_alt(b, f),
972 decreases k,
973 {
974 reveal_with_fuel(Seq::fold_left_alt, 2);
975 if k == 1 {
976 } else {
978 self[1..].aux_lemma_fold_left_alt(f(b, self[0]), f, k - 1);
979 assert(self[1..][k - 1..self[1..].len()] =~= self[k..]);
980 assert(self[1..][..k - 1] =~= self[1..k]);
981 assert(self[..k][1..self[..k].len()] =~= self[1..k]);
982 }
983 }
984
985 pub proof fn lemma_fold_left_alt<B>(self, b: B, f: spec_fn(B, A) -> B)
987 ensures
988 self.fold_left(b, f) == self.fold_left_alt(b, f),
989 decreases self.len(),
990 {
991 reveal_with_fuel(Seq::fold_left, 2);
992 reveal_with_fuel(Seq::fold_left_alt, 2);
993 if self.len() <= 1 {
994 } else {
996 self.aux_lemma_fold_left_alt(b, f, self.len() - 1);
997 self[self.len() - 1..].lemma_fold_left_alt(self.drop_last().fold_left_alt(b, f), f);
998 self[..self.len() - 1].lemma_fold_left_alt(b, f);
999 }
1000 }
1001
1002 pub proof fn lemma_reverse_fold_left<B>(self, v: B, f: spec_fn(B, A) -> B)
1005 ensures
1006 self.reverse().fold_left(v, f) == self.fold_right(|a: A, b: B| f(b, a), v),
1007 {
1008 assert(self.reverse().reverse() =~= self);
1009 let g = |a: A, b: B| f(b, a);
1010 assert(f =~= |b: B, a: A| g(a, b));
1011 self.reverse().lemma_reverse_fold_right(v, |a: A, b: B| f(b, a))
1012 }
1013
1014 pub open spec fn fold_right<B>(self, f: spec_fn(A, B) -> B, b: B) -> (res: B)
1021 decreases self.len(),
1022 {
1023 if self.len() == 0 {
1024 b
1025 } else {
1026 self.drop_last().fold_right(f, f(self.last(), b))
1027 }
1028 }
1029
1030 pub open spec fn fold_right_alt<B>(self, f: spec_fn(A, B) -> B, b: B) -> (res: B)
1034 decreases self.len(),
1035 {
1036 if self.len() == 0 {
1037 b
1038 } else {
1039 f(self[0], self[1..].fold_right_alt(f, b))
1040 }
1041 }
1042
1043 pub broadcast proof fn lemma_fold_right_split<B>(self, f: spec_fn(A, B) -> B, b: B, k: int)
1045 requires
1046 0 <= k <= self.len(),
1047 ensures
1048 self[..k].fold_right(f, (#[trigger] self[k..].fold_right(f, b))) == self.fold_right(
1049 f,
1050 b,
1051 ),
1052 decreases self.len(),
1053 {
1054 reveal_with_fuel(Seq::fold_right, 2);
1055 if k == self.len() {
1056 assert(self[..k] == self);
1057 } else if k == self.len() - 1 {
1058 } else {
1060 self[..self.len() - 1].lemma_fold_right_split(f, f(self.last(), b), k);
1061 assert(self[..self.len() - 1][..k] =~= self[..k]);
1062 assert(self[..self.len() - 1][k..self[..self.len() - 1].len()] =~= self[k..self.len()
1063 - 1]);
1064 assert(self[k..].drop_last() =~= self[k..self.len() - 1]);
1065 }
1066 }
1067
1068 pub proof fn lemma_fold_right_commute_one<B>(self, a: A, f: spec_fn(A, B) -> B, v: B)
1070 requires
1071 commutative_foldr(f),
1072 ensures
1073 self.fold_right(f, f(a, v)) == f(a, self.fold_right(f, v)),
1074 decreases self.len(),
1075 {
1076 if self.len() > 0 {
1077 self.drop_last().lemma_fold_right_commute_one(a, f, f(self.last(), v));
1078 }
1079 }
1080
1081 pub proof fn lemma_fold_right_alt<B>(self, f: spec_fn(A, B) -> B, b: B)
1083 ensures
1084 self.fold_right(f, b) == self.fold_right_alt(f, b),
1085 decreases self.len(),
1086 {
1087 reveal_with_fuel(Seq::fold_right, 2);
1088 reveal_with_fuel(Seq::fold_right_alt, 2);
1089 if self.len() <= 1 {
1090 } else {
1092 self[1..].lemma_fold_right_alt(f, b);
1093 self.lemma_fold_right_split(f, b, 1);
1094 }
1095 }
1096
1097 pub proof fn lemma_reverse_fold_right<B>(self, v: B, f: spec_fn(A, B) -> B)
1100 ensures
1101 self.reverse().fold_right(f, v) == self.fold_left(v, |b: B, a: A| f(a, b)),
1102 decreases self.len(),
1103 {
1104 let g = |b: B, a: A| f(a, b);
1105 if self.len() > 0 {
1106 let last = self.last();
1107 let s0 = self.drop_last();
1108 assert(self.reverse() =~= seq![last] + s0.reverse());
1109 let res1 = self.reverse().fold_right(f, v);
1110 let res2 = self.fold_left(v, g);
1111 assert(res1 == self.reverse().fold_right_alt(f, v)) by {
1112 self.reverse().lemma_fold_right_alt(f, v)
1113 }
1114 assert(res2 == g(s0.fold_left(v, g), last));
1115 assert(self.reverse().first() == last);
1116 assert(self.reverse()[1..self.reverse().len()] =~= s0.reverse());
1117 assert(res1 == f(last, s0.reverse().fold_right_alt(f, v)));
1118 assert(res1 == f(last, s0.reverse().fold_right(f, v))) by {
1119 s0.reverse().lemma_fold_right_alt(f, v)
1120 }
1121 assert(res2 == g(s0.fold_left(v, g), last));
1122 s0.lemma_reverse_fold_right(v, f);
1123 }
1124 }
1125
1126 pub proof fn lemma_multiset_has_no_duplicates(self)
1130 requires
1131 self.no_duplicates(),
1132 ensures
1133 forall|x: A| self.to_multiset().contains(x) ==> self.to_multiset().count(x) == 1,
1134 decreases self.len(),
1135 {
1136 broadcast use super::multiset::group_multiset_axioms;
1137
1138 if self.len() == 0 {
1139 assert(forall|x: A|
1140 self.to_multiset().contains(x) ==> self.to_multiset().count(x) == 1);
1141 } else {
1142 broadcast use group_seq_properties;
1143
1144 assert(self.drop_last().push(self.last()) =~= self);
1145 self.drop_last().lemma_multiset_has_no_duplicates();
1146 }
1147 }
1148
1149 pub proof fn lemma_multiset_has_no_duplicates_conv(self)
1152 requires
1153 forall|x: A| self.to_multiset().contains(x) ==> self.to_multiset().count(x) == 1,
1154 ensures
1155 self.no_duplicates(),
1156 {
1157 broadcast use super::multiset::group_multiset_axioms;
1158
1159 assert forall|i, j| (0 <= i < self.len() && 0 <= j < self.len() && i != j) implies self[i]
1160 != self[j] by {
1161 let mut a = if (i < j) {
1162 i
1163 } else {
1164 j
1165 };
1166 let mut b = if (i < j) {
1167 j
1168 } else {
1169 i
1170 };
1171
1172 if (self[a] == self[b]) {
1173 let s0 = self[..b];
1174 let s1 = self[b..];
1175 assert(self == s0 + s1);
1176
1177 broadcast use group_to_multiset_ensures;
1178
1179 lemma_multiset_commutative(s0, s1);
1180 assert(self.to_multiset().count(self[a]) >= 2);
1181 }
1182 }
1183 }
1184
1185 pub proof fn lemma_reverse_to_multiset(self)
1187 ensures
1188 self.reverse().to_multiset() =~= self.to_multiset(),
1189 decreases self.len(),
1190 {
1191 broadcast use group_seq_properties;
1192 broadcast use super::multiset::group_multiset_axioms;
1193
1194 if self.len() > 0 {
1195 let s2 = self.drop_first();
1196 let e = self.first();
1197 assert(self =~= seq![e] + s2);
1198 assert(self.to_multiset() =~= seq![e].to_multiset().add(s2.to_multiset())) by {
1199 lemma_multiset_commutative(seq![e], s2)
1200 }
1201 assert(self.reverse() =~= s2.reverse().push(e));
1202 assert(self.reverse().to_multiset() =~= s2.reverse().to_multiset().insert(e));
1203 s2.lemma_reverse_to_multiset();
1204 }
1205 }
1206
1207 pub proof fn lemma_add_last_back(self)
1211 requires
1212 0 < self.len(),
1213 ensures
1214 #[trigger] self.drop_last().push(self.last()) =~= self,
1215 {
1216 }
1217
1218 pub proof fn lemma_indexing_implies_membership(self, f: spec_fn(A) -> bool)
1223 requires
1224 forall|i: int| 0 <= i < self.len() ==> #[trigger] f(#[trigger] self[i]),
1225 ensures
1226 forall|x: A| #[trigger] self.contains(x) ==> #[trigger] f(x),
1227 {
1228 assert(forall|i: int| 0 <= i < self.len() ==> #[trigger] self.contains(self[i]));
1229 }
1230
1231 pub proof fn lemma_membership_implies_indexing(self, f: spec_fn(A) -> bool)
1236 requires
1237 forall|x: A| #[trigger] self.contains(x) ==> #[trigger] f(x),
1238 ensures
1239 forall|i: int| 0 <= i < self.len() ==> #[trigger] f(self[i]),
1240 {
1241 assert forall|i: int| 0 <= i < self.len() implies #[trigger] f(self[i]) by {
1242 assert(self.contains(self[i]));
1243 }
1244 }
1245
1246 pub proof fn lemma_split_at(self, pos: int)
1250 requires
1251 0 <= pos <= self.len(),
1252 ensures
1253 self[..pos] + self[pos..] =~= self,
1254 {
1255 }
1256
1257 pub proof fn lemma_element_from_slice(self, new: Seq<A>, a: int, b: int, pos: int)
1259 requires
1260 0 <= a <= b <= self.len(),
1261 new == self[a..b],
1262 a <= pos < b,
1263 ensures
1264 pos - a < new.len(),
1265 new[pos - a] == self[pos],
1266 {
1267 }
1268
1269 pub proof fn lemma_slice_of_slice(self, s1: int, e1: int, s2: int, e2: int)
1272 requires
1273 0 <= s1 <= e1 <= self.len(),
1274 0 <= s2 <= e2 <= e1 - s1,
1275 ensures
1276 self[s1..e1][s2..e2] =~= self[s1 + s2..s1 + e2],
1277 {
1278 }
1279
1280 pub proof fn unique_seq_to_set(self)
1282 requires
1283 self.no_duplicates(),
1284 ensures
1285 self.len() == self.to_set().len(),
1286 decreases self.len(),
1287 {
1288 broadcast use super::set::group_set_lemmas;
1289
1290 seq_to_set_equal_rec::<A>(self);
1291 if self.len() == 0 {
1292 } else {
1293 let rest = self.drop_last();
1294 rest.unique_seq_to_set();
1295 seq_to_set_equal_rec::<A>(rest);
1296 assert(!rest.contains(self.last()));
1297 assert(!seq_to_set_rec(rest).contains(self.last())) by {
1298 seq_to_set_rec_contains::<A>(rest);
1299 }
1300 assert(seq_to_set_rec(rest).insert(self.last()).len() == seq_to_set_rec(rest).len()
1301 + 1);
1302 }
1303 }
1304
1305 pub proof fn lemma_cardinality_of_set(self)
1308 ensures
1309 self.to_set().len() <= self.len(),
1310 {
1311 broadcast use super::set_lib::range_set_properties;
1312
1313 super::set_lib::lemma_map_size_bound::<int, A>(
1314 Set::range(0, self.len() as int),
1315 self.to_set(),
1316 |i: int| self.index(i),
1317 );
1318 }
1319
1320 pub proof fn lemma_cardinality_of_empty_set_is_0(self)
1323 ensures
1324 self.to_set().len() == 0 <==> self.len() == 0,
1325 {
1326 broadcast use super::set::group_set_lemmas;
1327
1328 self.to_set_ensures();
1329
1330 assert(self.len() == 0 ==> self.to_set().len() == 0) by { self.lemma_cardinality_of_set() }
1331 assert(!(self.len() == 0) ==> !(self.to_set().len() == 0)) by {
1332 if self.len() > 0 {
1333 assert(self.to_set().contains(self[0]));
1334 assert(self.to_set().remove(self[0]).len() <= self.to_set().len());
1335 }
1336 }
1337 }
1338
1339 pub proof fn lemma_no_dup_set_cardinality(self)
1342 requires
1343 self.to_set().len() == self.len(),
1344 ensures
1345 self.no_duplicates(),
1346 decreases self.len(),
1347 {
1348 broadcast use super::set::group_set_lemmas;
1349
1350 self.to_set_ensures();
1351 self.drop_first().to_set_ensures();
1352
1353 if self.len() == 0 {
1354 } else {
1355 assert(self =~= Seq::empty().push(self.first()).add(self.drop_first()));
1356 if self.drop_first().contains(self.first()) {
1357 assert(self.to_set() =~= self.drop_first().to_set());
1359 assert(self.to_set().len() <= self.drop_first().len()) by {
1360 self.drop_first().lemma_cardinality_of_set()
1361 }
1362 } else {
1363 assert(self.to_set().len() == 1 + self.drop_first().to_set().len()) by {
1364 assert(self.drop_first().to_set().insert(self.first()) =~= self.to_set());
1365 }
1366 self.drop_first().lemma_no_dup_set_cardinality();
1367 }
1368 }
1369 }
1370
1371 pub broadcast proof fn lemma_to_set_map_commutes<B>(self, f: spec_fn(A) -> B)
1374 ensures
1375 #[trigger] self.to_set().map(f) =~= self.map_values(f).to_set(),
1376 {
1377 broadcast use crate::vstd::group_vstd_default;
1378
1379 assert forall|elem: B|
1380 self.to_set().map(f).contains(elem) <==> self.map_values(f).to_set().contains(elem) by {
1381 if self.to_set().map(f).contains(elem) {
1382 let x = choose|x: A| self.to_set().contains(x) && f(x) == elem;
1383 let i = choose|i: int| 0 <= i < self.len() && self[i] == x;
1384 assert(self.map_values(f)[i] == elem);
1385 }
1386 if self.map_values(f).to_set().contains(elem) {
1387 let i = choose|i: int|
1388 0 <= i < self.map_values(f).len() && self.map_values(f)[i] == elem;
1389 let x = self[i];
1390 assert(self.to_set().contains(x));
1391 }
1392 };
1393 }
1394
1395 pub broadcast proof fn lemma_to_iset_map_commutes<B>(self, f: spec_fn(A) -> B)
1398 ensures
1399 #[trigger] self.to_iset().map(f) =~= self.map_values(f).to_iset(),
1400 {
1401 broadcast use crate::vstd::group_vstd_default;
1402
1403 assert forall|elem: B|
1404 self.to_iset().map(f).contains(elem) <==> self.map_values(f).to_iset().contains(
1405 elem,
1406 ) by {
1407 if self.to_iset().map(f).contains(elem) {
1408 let x = choose|x: A| self.to_iset().contains(x) && f(x) == elem;
1409 let i = choose|i: int| 0 <= i < self.len() && self[i] == x;
1410 assert(self.map_values(f)[i] == elem);
1411 }
1412 if self.map_values(f).to_iset().contains(elem) {
1413 let i = choose|i: int|
1414 0 <= i < self.map_values(f).len() && self.map_values(f)[i] == elem;
1415 let x = self[i];
1416 assert(self.to_iset().contains(x));
1417 }
1418 };
1419 }
1420
1421 pub broadcast proof fn lemma_to_set_insert_commutes(sq: Seq<A>, elt: A)
1424 ensures
1425 #[trigger] (sq + seq![elt]).to_set() =~= sq.to_set().insert(elt),
1426 {
1427 broadcast use crate::vstd::group_vstd_default;
1428 broadcast use lemma_seq_concat_contains_all_elements;
1429 broadcast use lemma_seq_empty_contains_nothing;
1430 broadcast use lemma_seq_contains_after_push;
1431 broadcast use super::seq::group_seq_lemmas;
1432 broadcast use super::set_lib::group_set_properties;
1433
1434 }
1435
1436 pub broadcast proof fn lemma_to_iset_insert_commutes(sq: Seq<A>, elt: A)
1439 ensures
1440 #[trigger] (sq + seq![elt]).to_iset() =~= sq.to_iset().insert(elt),
1441 {
1442 broadcast use crate::vstd::group_vstd_default;
1443 broadcast use lemma_seq_concat_contains_all_elements;
1444 broadcast use lemma_seq_empty_contains_nothing;
1445 broadcast use lemma_seq_contains_after_push;
1446 broadcast use super::seq::group_seq_lemmas;
1447 broadcast use super::set_lib::group_set_properties;
1448
1449 }
1450
1451 pub open spec fn update_subrange_with(self, off: int, vs: Self) -> Self
1455 recommends
1456 0 <= off,
1457 off + vs.len() <= self.len(),
1458 {
1459 Seq::new(
1460 self.len(),
1461 |i: int|
1462 if off <= i < off + vs.len() {
1463 vs[i - off]
1464 } else {
1465 self[i]
1466 },
1467 )
1468 }
1469
1470 pub broadcast proof fn lemma_seq_skip_skip(self, i: int)
1482 ensures
1483 0 <= i < self.len() ==> self[i..][1..] =~= #[trigger] self[i + 1..],
1484 {
1485 broadcast use group_seq_properties;
1486
1487 }
1488
1489 pub proof fn lemma_contains_to_index(self, elem: A) -> (idx: int)
1502 requires
1503 self.contains(elem),
1504 ensures
1505 0 <= idx < self.len() && self[idx] == elem,
1506 decreases self.len(),
1507 {
1508 broadcast use group_seq_properties;
1509
1510 if self[0] == elem {
1511 0
1512 } else {
1513 let i = self[1..].lemma_contains_to_index(elem);
1514 i + 1
1515 }
1516 }
1517
1518 pub proof fn lemma_all_from_head_tail(self, pred: spec_fn(A) -> bool)
1534 requires
1535 self.len() > 0,
1536 pred(self[0]) && self[1..].all(|x| pred(x)),
1537 ensures
1538 self.all(|x| pred(x)),
1539 {
1540 broadcast use group_seq_properties;
1541
1542 assert(seq![self[0]] + self[1..] == self);
1543 }
1544
1545 pub proof fn lemma_any_tail(self, pred: spec_fn(A) -> bool)
1561 requires
1562 self.any(|x| pred(x)),
1563 ensures
1564 !pred(self[0]) ==> self[1..].any(|x| pred(x)),
1565 {
1566 broadcast use group_seq_properties;
1567
1568 }
1569
1570 pub open spec fn remove_duplicates(self, seen: Seq<A>) -> Seq<A>
1588 decreases self.len(),
1589 {
1590 if self.len() == 0 {
1591 seen
1592 } else if seen.contains(self[0]) {
1593 self[1..].remove_duplicates(seen)
1594 } else {
1595 self[1..].remove_duplicates(seen + seq![self[0]])
1596 }
1597 }
1598
1599 pub broadcast proof fn lemma_remove_duplicates_properties(self, seen: Seq<A>)
1617 ensures
1618 forall|x|
1619 (self + seen).contains(x) <==> #[trigger] self.remove_duplicates(seen).contains(x),
1620 #[trigger] self.remove_duplicates(seen).len() <= self.len() + seen.len(),
1621 decreases self.len(),
1622 {
1623 broadcast use group_seq_properties;
1624
1625 if self.len() == 0 {
1626 } else if seen.contains(self[0]) {
1627 let rest = self[1..];
1628 rest.lemma_remove_duplicates_properties(seen);
1629 } else {
1630 let rest = self[1..];
1631 rest.lemma_remove_duplicates_properties(seen + seq![self[0]]);
1632 }
1633 }
1634
1635 pub proof fn lemma_remove_duplicates_append_index(self, i: int, seen: Seq<A>)
1651 requires
1652 0 <= i < self.len(),
1653 ensures
1654 self.remove_duplicates(seen) == self[i..].remove_duplicates(
1655 self[..i].remove_duplicates(seen),
1656 ),
1657 decreases self.len(),
1658 {
1659 broadcast use {
1660 group_seq_properties,
1661 lemma_seq_skip_of_skip,
1662 Seq::lemma_remove_duplicates_properties,
1663 };
1664
1665 if i == 0 {
1666 } else if i == self.len() {
1667 assert(self[..i] == self);
1668 } else {
1669 assert(self[1..][..i - 1] == self[1..i]);
1670 assert(self[..i][1..] == self[1..i]);
1671 assert(self[1..][..i - 1] == self[..i][1..]);
1672 if seen.contains(self[0]) {
1673 self[1..].lemma_remove_duplicates_append_index(i - 1, seen);
1674 } else {
1675 self[1..].lemma_remove_duplicates_append_index(i - 1, seen + seq![self[0]]);
1676 }
1677 }
1678 }
1679
1680 proof fn lemma_skip1_concat(xs: Seq<A>, ys: Seq<A>)
1695 requires
1696 xs.len() > 0,
1697 ensures
1698 (xs + ys)[1..] == xs[1..] + ys,
1699 {
1700 broadcast use group_seq_properties;
1701
1702 assert((xs + ys)[1..] == xs[1..] + ys);
1703 }
1704
1705 pub proof fn lemma_remove_duplicates_append(self, x: A, seen: Seq<A>)
1721 ensures
1722 (self + seen).contains(x) ==> (self + seq![x]).remove_duplicates(seen)
1723 == self.remove_duplicates(seen),
1724 !(self + seen).contains(x) ==> (self + seq![x]).remove_duplicates(seen)
1725 == self.remove_duplicates(seen) + seq![x],
1726 decreases self.len(),
1727 {
1728 broadcast use group_seq_properties;
1729
1730 reveal_with_fuel(Seq::remove_duplicates, 2);
1731
1732 if self.len() != 0 {
1733 let head = self[0];
1734 let tail = self[1..];
1735
1736 let seen2 = if seen.contains(head) {
1737 seen
1738 } else {
1739 seen + seq![head]
1740 };
1741 tail.lemma_remove_duplicates_append(x, seen2);
1742 assert((self + seq![x])[1..] == tail + seq![x]) by {
1743 Seq::lemma_skip1_concat(self, seq![x]);
1744 };
1745 }
1746 }
1747
1748 pub proof fn lemma_all_neg_filter_empty(self, pred: spec_fn(A) -> bool)
1761 requires
1762 self.all(|x: A| !pred(x)),
1763 ensures
1764 self.filter(pred).len() == 0,
1765 decreases self.len(),
1766 {
1767 broadcast use group_seq_properties;
1768
1769 reveal(Seq::filter);
1770 if self.len() != 0 {
1771 let rest = self.drop_last();
1772 rest.lemma_all_neg_filter_empty(pred);
1773 rest.lemma_filter_len_push(pred, self.last());
1774 let neg_pred = |x| !pred(x);
1775 assert(neg_pred(self.last()));
1776 }
1777 }
1778
1779 pub open spec fn filter_map<B>(self, f: spec_fn(A) -> Option<B>) -> Seq<B>
1788 decreases self.len(),
1789 {
1790 if self.len() == 0 {
1794 Seq::empty()
1795 } else {
1796 let rest = self.drop_last();
1797 match f(self.last()) {
1798 Option::Some(s) => rest.filter_map(f) + seq![s],
1799 Option::None => rest.filter_map(f),
1800 }
1801 }
1802 }
1803
1804 pub broadcast proof fn lemma_filter_contains_rev(self, p: spec_fn(A) -> bool, elem: A)
1808 requires
1809 #[trigger] self.filter(p).contains(elem),
1810 ensures
1811 self.contains(elem),
1812 decreases self.len(),
1813 {
1814 broadcast use group_seq_properties;
1815
1816 reveal(Seq::filter);
1817 if self.len() == 0 {
1818 } else {
1819 let rest = self.drop_last();
1820 let last = self.last();
1821 if !p(last) || last != elem {
1822 rest.lemma_filter_contains_rev(p, elem);
1823 }
1824 }
1825 }
1826
1827 pub broadcast proof fn lemma_filter_map_contains<B>(self, f: spec_fn(A) -> Option<B>, elt: B)
1831 requires
1832 #[trigger] self.filter_map(f).contains(elt),
1833 ensures
1834 exists|t: A| #[trigger] self.contains(t) && f(t) == Some(elt),
1835 decreases self.len(),
1836 {
1837 broadcast use group_seq_properties;
1838
1839 if self.len() == 0 {
1840 } else {
1841 let last = self.last();
1842 let rest = self.drop_last();
1843 if f(last) == Some(elt) {
1844 assert(self.contains(last));
1845 } else {
1846 rest.lemma_filter_map_contains(f, elt);
1847 let t = choose|t: A| #[trigger] rest.contains(t) && f(t) == Some(elt);
1848 assert(self.contains(t));
1849 }
1850 }
1851 }
1852
1853 pub proof fn lemma_take_succ(xs: Seq<A>, k: int)
1862 requires
1863 0 <= k < xs.len(),
1864 ensures
1865 xs[..k + 1] =~= xs[..k] + seq![xs[k]],
1866 {
1867 broadcast use group_seq_properties;
1868
1869 }
1870
1871 pub proof fn lemma_filter_map_singleton<B>(a: A, f: spec_fn(A) -> Option<B>)
1875 ensures
1876 seq![a].filter_map(f) =~= match f(a) {
1877 Option::Some(b) => seq![b],
1878 Option::None => Seq::empty(),
1879 },
1880 {
1881 reveal_with_fuel(Seq::filter_map, 2);
1882 }
1883
1884 pub broadcast proof fn lemma_filter_map_take_succ<B>(self, f: spec_fn(A) -> Option<B>, i: int)
1896 requires
1897 0 <= i < self.len(),
1898 ensures
1899 #[trigger] self[..i + 1].filter_map(f) =~= self[..i].filter_map(f) + (match f(self[i]) {
1900 Option::Some(s) => seq![s],
1901 Option::None => Seq::empty(),
1902 }),
1903 decreases self.len(),
1904 {
1905 broadcast use group_seq_properties;
1906
1907 if i != 0 {
1908 self.drop_last().lemma_filter_map_take_succ(f, i - 1);
1909 assert(self[..i + 1].drop_last() == self[..i]);
1910 }
1911 }
1912
1913 pub open spec fn filter_alt(self, p: spec_fn(A) -> bool) -> Seq<A> {
1916 if self.len() == 0 {
1917 Seq::empty()
1918 } else {
1919 let rest = self.drop_first().filter(p);
1920 let first = self.first();
1921 if p(first) {
1922 seq![first] + rest
1923 } else {
1924 rest
1925 }
1926 }
1927 }
1928
1929 pub broadcast proof fn lemma_filter_prepend(self, x: A, p: spec_fn(A) -> bool)
1944 ensures
1945 #[trigger] (seq![x] + self).filter(p) == (if p(x) {
1946 seq![x]
1947 } else {
1948 Seq::empty()
1949 }) + self.filter(p),
1950 decreases self.len(),
1951 {
1952 broadcast use group_seq_properties;
1953
1954 reveal(Seq::filter);
1955 let lhs = (seq![x] + self).filter(p);
1956 let rhs = (if p(x) {
1957 seq![x]
1958 } else {
1959 Seq::empty()
1960 }) + self.filter(p);
1961
1962 if self.len() == 0 {
1963 assert(lhs =~= rhs);
1964 } else {
1965 let tail_seq = if p(self.last()) {
1966 seq![self.last()]
1967 } else {
1968 Seq::empty()
1969 };
1970
1971 assert(((seq![x] + self).drop_last()) =~= seq![x] + self.drop_last());
1972 let sub = (seq![x] + self.drop_last()).filter(p);
1973 assert(lhs =~= sub + tail_seq);
1974 assert(rhs =~= (if p(x) {
1975 seq![x]
1976 } else {
1977 Seq::empty()
1978 }) + self.drop_last().filter(p) + tail_seq);
1979 self.drop_last().lemma_filter_prepend(x, p);
1980 }
1981 }
1982
1983 pub proof fn lemma_filter_eq_filter_alt(self, p: spec_fn(A) -> bool)
1985 ensures
1986 self.filter(p) =~= self.filter_alt(p),
1987 decreases self.len(),
1988 {
1989 broadcast use group_seq_properties;
1990 broadcast use Seq::lemma_filter_prepend;
1991
1992 reveal(Seq::filter);
1993 if self.len() == 0 {
1994 } else {
1995 let first = self.first();
1996 let but_first = self.drop_first();
1997 assert(self =~= seq![first] + but_first);
1998 self.drop_first().lemma_filter_eq_filter_alt(p);
1999 }
2000 }
2001
2002 pub proof fn lemma_filter_monotone(self, ys: Seq<A>, p: spec_fn(A) -> bool)
2017 requires
2018 self.is_prefix_of(ys),
2019 ensures
2020 self.filter(p).is_prefix_of(ys.filter(p)),
2021 decreases self.len(),
2022 {
2023 broadcast use group_seq_properties;
2024
2025 self.lemma_filter_eq_filter_alt(p);
2026 ys.lemma_filter_eq_filter_alt(p);
2027 if self.len() == 0 {
2028 } else {
2029 self.drop_first().lemma_filter_monotone(ys.drop_first(), p);
2030 }
2031 }
2032
2033 pub proof fn lemma_filter_take_len(self, p: spec_fn(A) -> bool, i: int)
2048 requires
2049 0 <= i <= self.len(),
2050 ensures
2051 self.filter(p).len() >= self[..i].filter(p).len(),
2052 decreases i,
2053 {
2054 broadcast use group_seq_properties;
2055 broadcast use Seq::lemma_filter_len_push;
2056 broadcast use Seq::lemma_filter_push;
2057
2058 self[..i].lemma_filter_monotone(self, p);
2059 }
2060
2061 pub broadcast proof fn lemma_filter_len_push(self, p: spec_fn(A) -> bool, elem: A)
2073 ensures
2074 #[trigger] self.push(elem).filter(p).len() == self.filter(p).len() + (if p(elem) {
2075 1int
2076 } else {
2077 0int
2078 }),
2079 {
2080 broadcast use group_seq_properties;
2081 broadcast use Seq::lemma_filter_push;
2082
2083 }
2084
2085 pub broadcast proof fn lemma_index_contains(self, i: int)
2088 requires
2089 0 <= i < self.len(),
2090 ensures
2091 self.contains(#[trigger] self[i]),
2092 {
2093 }
2094
2095 pub broadcast proof fn lemma_take_succ_push(self, i: int)
2098 requires
2099 0 <= i < self.len(),
2100 ensures
2101 #[trigger] self[..i + 1] =~= self[..i].push(self[i]),
2102 {
2103 broadcast use group_seq_properties;
2104
2105 }
2106
2107 pub broadcast proof fn lemma_take_len(self)
2109 ensures
2110 #[trigger] self[..self.len()] == self,
2111 {
2112 broadcast use group_seq_properties;
2113
2114 }
2115
2116 pub broadcast proof fn lemma_take_any_succ(self, p: spec_fn(A) -> bool, i: int)
2129 requires
2130 0 <= i < self.len(),
2131 ensures
2132 #[trigger] self[..i + 1].any(p) <==> self[..i].any(p) || p(self[i]),
2133 {
2134 broadcast use group_seq_properties;
2135
2136 self.lemma_take_succ_push(i);
2137 if self[..i + 1].any(p) {
2138 let x = choose|x: A| self[..i + 1].contains(x) && #[trigger] p(x);
2139 assert(self[..i].contains(x) || x == self[i]);
2140 }
2141 if self[..i].any(p) {
2142 let x = choose|x: A| self[..i].contains(x) && #[trigger] p(x);
2143 assert(self[..i + 1].contains(x));
2144 }
2145 if p(self[i]) {
2146 assert(self[..i + 1].contains(self[i]));
2147 }
2148 }
2149
2150 pub proof fn lemma_no_duplicates_injective<B>(self, f: spec_fn(A) -> B)
2162 requires
2163 injective(f),
2164 ensures
2165 self.no_duplicates() <==> self.map_values(f).no_duplicates(),
2166 {
2167 broadcast use group_seq_properties;
2168 broadcast use super::set_lib::group_set_properties;
2169
2170 let mapped = self.map_values(f);
2171 assert(mapped.len() == self.len());
2172 if mapped.no_duplicates() {
2173 assert forall|i: int, j: int| 0 <= i < j < mapped.len() implies self[i] != self[j] by {
2174 assert(mapped[i] == f(self[i]));
2175 assert(mapped[j] == f(self[j]));
2176 }
2177 }
2178 }
2179
2180 pub broadcast proof fn lemma_push_map_commute<B>(self, f: spec_fn(A) -> B, x: A)
2192 ensures
2193 self.map_values(f).push(f(x)) =~= #[trigger] self.push(x).map_values(f),
2194 decreases self.len(),
2195 {
2196 broadcast use group_seq_properties;
2197
2198 }
2199
2200 pub broadcast proof fn lemma_push_to_set_commute(self, elem: A)
2211 ensures
2212 #[trigger] self.push(elem).to_set() =~= self.to_set().insert(elem),
2213 {
2214 broadcast use {group_seq_properties, super::set::group_set_lemmas, Seq::to_set_ensures};
2215
2216 let lhs = self.push(elem).to_set();
2217 let rhs = self.to_set().insert(elem);
2218 assert forall|x: A| rhs.contains(x) implies lhs.contains(x) by {
2219 lemma_seq_contains_after_push(self, elem, x);
2220 }
2221 }
2222
2223 pub broadcast proof fn lemma_filter_push(self, elem: A, pred: spec_fn(A) -> bool)
2237 ensures
2238 #[trigger] self.push(elem).filter(pred) == if pred(elem) {
2239 self.filter(pred).push(elem)
2240 } else {
2241 self.filter(pred)
2242 },
2243 {
2244 broadcast use group_seq_properties;
2245
2246 reveal(Seq::filter);
2247 assert(self.push(elem).drop_last() =~= self);
2248 }
2249
2250 pub proof fn lemma_zip_with_contains_index<B>(self, b: Seq<B>, i: int)
2263 requires
2264 0 <= i < self.len(),
2265 self.len() == b.len(),
2266 ensures
2267 self.zip_with(b).contains((self[i], b[i])),
2268 {
2269 assert(self.zip_with(b)[i] == (self[i], b[i]));
2270 }
2271
2272 pub proof fn lemma_zip_with_uncurry_all<B>(self, b: Seq<B>, f: spec_fn(A, B) -> bool)
2289 requires
2290 self.len() == b.len(),
2291 ensures
2292 self.zip_with(b).all(|p: (A, B)| f(p.0, p.1)) <==> forall|i: int|
2293 0 <= i < self.len() ==> f(self[i], b[i]),
2294 {
2295 broadcast use group_seq_properties;
2296
2297 let zipped = self.zip_with(b);
2298 let f_uncurr = |p: (A, B)| f(p.0, p.1);
2299 let lhs = zipped.all(f_uncurr);
2300 let rhs = (forall|i: int| 0 <= i < self.len() ==> f(self[i], b[i]));
2301 if lhs {
2302 assert forall|i: int| 0 <= i < self.len() implies f(self[i], b[i]) by {
2303 self.lemma_zip_with_contains_index(b, i);
2304 assert(forall|j| 0 <= j < zipped.len() ==> f_uncurr(zipped[j]));
2305 }
2306 }
2307 }
2308
2309 pub proof fn lemma_flat_map_push<B>(self, f: spec_fn(A) -> Seq<B>, elem: A)
2323 ensures
2324 self.push(elem).flat_map(f) =~= self.flat_map(f) + f(elem),
2325 decreases self.len(),
2326 {
2327 broadcast use group_seq_properties;
2328 broadcast use Seq::lemma_flatten_push;
2329 broadcast use Seq::lemma_push_map_commute;
2330
2331 }
2332
2333 pub broadcast proof fn lemma_flat_map_take_append<B>(self, f: spec_fn(A) -> Seq<B>, i: int)
2348 requires
2349 0 <= i < self.len(),
2350 ensures
2351 #[trigger] self[..i + 1].flat_map(f) =~= self[..i].flat_map(f) + f(self[i]),
2352 decreases i,
2353 {
2354 broadcast use group_seq_properties;
2355
2356 self.lemma_take_succ_push(i);
2357 self[..i].lemma_flat_map_push(f, self[i]);
2358 }
2359
2360 pub broadcast proof fn lemma_flat_map_singleton<B>(self, f: spec_fn(A) -> Seq<B>)
2363 requires
2364 #[trigger] self.len() == 1,
2365 ensures
2366 #[trigger] self.flat_map(f) == f(self[0]),
2367 {
2368 broadcast use Seq::lemma_flatten_singleton;
2369
2370 }
2371
2372 pub broadcast proof fn lemma_map_take_succ<B>(self, f: spec_fn(A) -> B, i: int)
2387 requires
2388 0 <= i < self.len(),
2389 ensures
2390 #[trigger] self[..i + 1].map_values(f) =~= self[..i].map_values(f).push(f(self[i])),
2391 {
2392 broadcast use group_seq_properties;
2393
2394 self.lemma_take_succ_push(i);
2395 }
2396
2397 pub broadcast proof fn lemma_prefix_index_eq(self, prefix: Seq<A>)
2410 requires
2411 #[trigger] prefix.is_prefix_of(self),
2412 ensures
2413 forall|i: int| 0 <= i < prefix.len() ==> prefix[i] == self[i],
2414 {
2415 }
2416
2417 pub broadcast proof fn lemma_prefix_concat(self, prefix1: Seq<A>, prefix2: Seq<A>)
2431 requires
2432 #[trigger] (prefix1 + prefix2).is_prefix_of(self),
2433 ensures
2434 prefix1.is_prefix_of(self),
2435 {
2436 broadcast use Seq::lemma_prefix_index_eq;
2437
2438 }
2439
2440 pub broadcast proof fn lemma_prefix_chain_contains(self, prefix1: Seq<A>, prefix2: Seq<A>, t: A)
2461 requires
2462 #[trigger] (prefix1 + seq![t]).is_prefix_of(self),
2463 #[trigger] prefix1.is_prefix_of(prefix2),
2464 prefix2.is_prefix_of(self),
2465 prefix1 != prefix2,
2466 !prefix1.contains(t),
2467 ensures
2468 prefix2.contains(t),
2469 {
2470 broadcast use Seq::lemma_prefix_concat;
2471 broadcast use Seq::lemma_prefix_index_eq;
2472
2473 assert(prefix2[prefix1.len() as int] == t);
2474 }
2475
2476 pub broadcast proof fn lemma_prefix_append_unique(self, prefix1: Seq<A>, prefix2: Seq<A>, t: A)
2480 requires
2481 #[trigger] (prefix1 + seq![t]).is_prefix_of(self),
2482 #[trigger] (prefix2 + seq![t]).is_prefix_of(self),
2483 !prefix1.contains(t),
2484 !prefix2.contains(t),
2485 ensures
2486 prefix1 == prefix2,
2487 {
2488 broadcast use Seq::lemma_prefix_concat;
2489 broadcast use Seq::lemma_prefix_index_eq;
2490 broadcast use Seq::lemma_prefix_chain_contains;
2491
2492 if prefix1 != prefix2 {
2493 assert(prefix1.is_prefix_of(prefix2) || prefix2.is_prefix_of(prefix1));
2494 }
2495 }
2496
2497 pub broadcast proof fn lemma_all_push(self, p: spec_fn(A) -> bool, elem: A)
2512 requires
2513 self.all(p),
2514 p(elem),
2515 ensures
2516 #[trigger] self.push(elem).all(p),
2517 {
2518 broadcast use group_seq_properties;
2519
2520 assert forall|x: A| self.push(elem).contains(x) implies p(x) by {
2521 lemma_seq_contains_after_push(self, elem, x);
2522 }
2523 }
2524
2525 pub proof fn lemma_concat_injective(self, s1: Seq<A>, s2: Seq<A>)
2528 ensures
2529 (self + s1 == self + s2) <==> (s1 == s2),
2530 {
2531 broadcast use group_seq_properties;
2532
2533 assert((self + s1)[self.len()..] == s1);
2534 }
2535
2536 pub broadcast group group_seq_extra {
2537 Seq::<_>::lemma_seq_skip_skip,
2538 Seq::<_>::lemma_remove_duplicates_properties,
2539 Seq::<_>::lemma_filter_contains_rev,
2540 Seq::<_>::lemma_filter_map_take_succ,
2541 Seq::<_>::lemma_filter_prepend,
2542 Seq::<_>::lemma_filter_len_push,
2543 Seq::<_>::lemma_take_len,
2544 Seq::<_>::lemma_take_any_succ,
2545 Seq::<_>::lemma_push_map_commute,
2546 Seq::<_>::lemma_push_to_set_commute,
2547 Seq::<_>::lemma_filter_push,
2548 Seq::<_>::lemma_flat_map_take_append,
2549 Seq::<_>::lemma_flat_map_singleton,
2550 Seq::<_>::lemma_map_take_succ,
2551 Seq::<_>::lemma_prefix_index_eq,
2552 Seq::<_>::lemma_prefix_concat,
2553 Seq::<_>::lemma_prefix_chain_contains,
2554 Seq::<_>::lemma_prefix_append_unique,
2555 Seq::<_>::lemma_all_push,
2556 }
2557}
2558
2559impl<A> Seq<&A> {
2560 pub open spec fn unref(self) -> Seq<A> {
2562 Seq::new(self.len(), |i: int| *self[i])
2563 }
2564}
2565
2566impl<A, B> Seq<(&A, &B)> {
2567 pub open spec fn unref(self) -> Seq<(A, B)> {
2569 Seq::new(self.len(), |i: int| (*self[i].0, *self[i].1))
2570 }
2571}
2572
2573pub proof fn lemma_filter_view_commute<S: View>(
2590 s: Seq<S>,
2591 p: spec_fn(S) -> bool,
2592 sp: spec_fn(S::V) -> bool,
2593)
2594 requires
2595 forall|s: S| p(s) <==> sp(s.view()),
2596 ensures
2597 s.filter(p).map_values(|x: S| x.view()) == s.map_values(|x: S| x.view()).filter(sp),
2598 decreases s.len(),
2599{
2600 broadcast use group_seq_properties;
2601 broadcast use Seq::lemma_push_map_commute;
2602 broadcast use Seq::lemma_filter_push;
2603
2604 reveal(Seq::filter);
2605 let view = |x: S| x.view();
2606 if s.len() > 0 {
2607 let rest = s.drop_last();
2608 let last = s.last();
2609 assert(s =~= rest.push(last));
2610 assert(s.map_values(view).last() == view(last));
2611 lemma_filter_view_commute(rest, p, sp);
2612 }
2613}
2614
2615pub proof fn lemma_exactly_one_view<S: View>(
2630 s: Seq<S>,
2631 p: spec_fn(S) -> bool,
2632 sp: spec_fn(S::V) -> bool,
2633)
2634 requires
2635 forall|s: S| p(s) <==> sp(s.view()),
2636 injective(|x: S| x.view()),
2637 ensures
2638 s.exactly_one(p) <==> s.map_values(|x: S| x.view()).exactly_one(sp),
2639{
2640 lemma_filter_view_commute(s, p, sp);
2641}
2642
2643impl<A, B> Seq<(A, B)> {
2644 pub closed spec fn unzip(self) -> (Seq<A>, Seq<B>) {
2646 (Seq::new(self.len(), |i: int| self[i].0), Seq::new(self.len(), |i: int| self[i].1))
2647 }
2648
2649 pub proof fn unzip_ensures(self)
2651 ensures
2652 self.unzip().0.len() == self.unzip().1.len(),
2653 self.unzip().0.len() == self.len(),
2654 self.unzip().1.len() == self.len(),
2655 forall|i: int|
2656 0 <= i < self.len() ==> (#[trigger] self.unzip().0[i], #[trigger] self.unzip().1[i])
2657 == self[i],
2658 decreases self.len(),
2659 {
2660 if self.len() > 0 {
2661 self.drop_last().unzip_ensures();
2662 }
2663 }
2664
2665 pub proof fn lemma_zip_of_unzip(self)
2668 ensures
2669 self.unzip().0.zip_with(self.unzip().1) =~= self,
2670 {
2671 }
2672}
2673
2674impl<A> Seq<Seq<A>> {
2675 pub open spec fn flatten(self) -> Seq<A>
2689 decreases self.len(),
2690 {
2691 if self.len() == 0 {
2692 Seq::empty()
2693 } else {
2694 self.first().add(self.drop_first().flatten())
2695 }
2696 }
2697
2698 pub open spec fn flatten_alt(self) -> Seq<A>
2703 decreases self.len(),
2704 {
2705 if self.len() == 0 {
2706 Seq::empty()
2707 } else {
2708 self.drop_last().flatten_alt().add(self.last())
2709 }
2710 }
2711
2712 pub proof fn lemma_flatten_one_element(self)
2715 ensures
2716 self.len() == 1 ==> self.flatten() == self.first(),
2717 {
2718 broadcast use Seq::add_empty_right;
2719
2720 if self.len() == 1 {
2721 assert(self.flatten() =~= self.first().add(self.drop_first().flatten()));
2722 }
2723 }
2724
2725 pub proof fn lemma_flatten_length_ge_single_element_length(self, i: int)
2728 requires
2729 0 <= i < self.len(),
2730 ensures
2731 self.flatten_alt().len() >= self[i].len(),
2732 decreases self.len(),
2733 {
2734 if self.len() == 1 {
2735 self.lemma_flatten_one_element();
2736 self.lemma_flatten_and_flatten_alt_are_equivalent();
2737 } else if i < self.len() - 1 {
2738 self.drop_last().lemma_flatten_length_ge_single_element_length(i);
2739 } else {
2740 assert(self.flatten_alt() == self.drop_last().flatten_alt().add(self.last()));
2741 }
2742 }
2743
2744 pub proof fn lemma_flatten_length_le_mul(self, j: int)
2748 requires
2749 forall|i: int| 0 <= i < self.len() ==> (#[trigger] self[i]).len() <= j,
2750 ensures
2751 self.flatten_alt().len() <= self.len() * j,
2752 decreases self.len(),
2753 {
2754 broadcast use group_seq_properties;
2755
2756 if self.len() == 0 {
2757 } else {
2758 self.drop_last().lemma_flatten_length_le_mul(j);
2759 assert((self.len() - 1) * j == (self.len() * j) - (1 * j)) by (nonlinear_arith); }
2761 }
2762
2763 pub proof fn lemma_flatten_and_flatten_alt_are_equivalent(self)
2766 ensures
2767 self.flatten() =~= self.flatten_alt(),
2768 decreases self.len(),
2769 {
2770 broadcast use {Seq::add_empty_right, Seq::push_distributes_over_add};
2771
2772 if self.len() != 0 {
2773 self.drop_last().lemma_flatten_and_flatten_alt_are_equivalent();
2774 seq![self.last()].lemma_flatten_one_element();
2778 assert(seq![self.last()].flatten() == self.last());
2779 lemma_flatten_concat(self.drop_last(), seq![self.last()]);
2780 assert((self.drop_last() + seq![self.last()]).flatten() == self.drop_last().flatten()
2781 + self.last());
2782 assert(self.drop_last() + seq![self.last()] =~= self);
2783 assert(self.flatten_alt() == self.drop_last().flatten_alt() + self.last());
2784 }
2785 }
2786
2787 pub broadcast proof fn lemma_flatten_push(self, elem: Seq<A>)
2790 ensures
2791 #[trigger] self.push(elem).flatten() =~= self.flatten() + elem,
2792 decreases self.len(),
2793 {
2794 broadcast use group_seq_properties;
2795
2796 assert(self.push(elem).last() == elem);
2797 assert(self.push(elem).drop_last() =~= self);
2798 calc! {
2799 (==)
2800 self.push(elem).flatten(); {
2801 self.push(elem).lemma_flatten_and_flatten_alt_are_equivalent();
2802 }
2803 self.push(elem).flatten_alt(); {}
2804 self.flatten_alt() + elem; {
2805 self.lemma_flatten_and_flatten_alt_are_equivalent();
2806 }
2807 self.flatten() + elem;
2808 }
2809 }
2810
2811 pub broadcast proof fn lemma_flatten_singleton(self)
2813 requires
2814 #[trigger] self.len() == 1,
2815 ensures
2816 #[trigger] self.flatten() == self[0],
2817 {
2818 assert(self.flatten() == self[0] + self.drop_first().flatten());
2819 assert(self.flatten() == self[0]);
2820 }
2821
2822 pub broadcast group group_seq_flatten {
2823 Seq::<_>::lemma_flatten_push,
2824 Seq::<_>::lemma_flatten_singleton,
2825 }
2826}
2827
2828impl Seq<int> {
2831 pub open spec fn max(self) -> int
2833 recommends
2834 0 < self.len(),
2835 decreases self.len(),
2836 {
2837 if self.len() == 1 {
2838 self[0]
2839 } else if self.len() == 0 {
2840 0
2841 } else {
2842 let later_max = self.drop_first().max();
2843 if self[0] >= later_max {
2844 self[0]
2845 } else {
2846 later_max
2847 }
2848 }
2849 }
2850
2851 pub proof fn max_ensures(self)
2853 ensures
2854 forall|x: int| self.contains(x) ==> x <= self.max(),
2855 forall|i: int| 0 <= i < self.len() ==> self[i] <= self.max(),
2856 self.len() == 0 || self.contains(self.max()),
2857 decreases self.len(),
2858 {
2859 if self.len() <= 1 {
2860 } else {
2861 let elt = self.drop_first().max();
2862 assert(self.drop_first().contains(elt)) by { self.drop_first().max_ensures() }
2863 assert forall|i: int| 0 <= i < self.len() implies self[i] <= self.max() by {
2864 assert(i == 0 || self[i] == self.drop_first()[i - 1]);
2865 assert(forall|j: int|
2866 0 <= j < self.drop_first().len() ==> self.drop_first()[j]
2867 <= self.drop_first().max()) by { self.drop_first().max_ensures() }
2868 }
2869 }
2870 }
2871
2872 pub open spec fn min(self) -> int
2874 recommends
2875 0 < self.len(),
2876 decreases self.len(),
2877 {
2878 if self.len() == 1 {
2879 self[0]
2880 } else if self.len() == 0 {
2881 0
2882 } else {
2883 let later_min = self.drop_first().min();
2884 if self[0] <= later_min {
2885 self[0]
2886 } else {
2887 later_min
2888 }
2889 }
2890 }
2891
2892 pub proof fn min_ensures(self)
2894 ensures
2895 forall|x: int| self.contains(x) ==> self.min() <= x,
2896 forall|i: int| 0 <= i < self.len() ==> self.min() <= self[i],
2897 self.len() == 0 || self.contains(self.min()),
2898 decreases self.len(),
2899 {
2900 if self.len() <= 1 {
2901 } else {
2902 let elt = self.drop_first().min();
2903 assert(self[1..].contains(elt)) by { self.drop_first().min_ensures() }
2904 assert forall|i: int| 0 <= i < self.len() implies self.min() <= self[i] by {
2905 assert(i == 0 || self[i] == self.drop_first()[i - 1]);
2906 assert(forall|j: int|
2907 0 <= j < self.drop_first().len() ==> self.drop_first().min()
2908 <= self.drop_first()[j]) by { self.drop_first().min_ensures() }
2909 }
2910 }
2911 }
2912
2913 pub closed spec fn sort(self) -> Self {
2914 self.sort_by(|x: int, y: int| x <= y)
2915 }
2916
2917 pub proof fn lemma_sort_ensures(self)
2918 ensures
2919 self.to_multiset() =~= self.sort().to_multiset(),
2920 sorted_by(self.sort(), |x: int, y: int| x <= y),
2921 {
2922 self.lemma_sort_by_ensures(|x: int, y: int| x <= y);
2923 }
2924
2925 pub proof fn lemma_subrange_max(self, from: int, to: int)
2928 requires
2929 0 <= from < to <= self.len(),
2930 ensures
2931 self[from..to].max() <= self.max(),
2932 {
2933 self.max_ensures();
2934 self[from..to].max_ensures();
2935 }
2936
2937 pub proof fn lemma_subrange_min(self, from: int, to: int)
2940 requires
2941 0 <= from < to <= self.len(),
2942 ensures
2943 self[from..to].min() >= self.min(),
2944 {
2945 self.min_ensures();
2946 self[from..to].min_ensures();
2947 }
2948}
2949
2950spec fn merge_sorted_with<A>(left: Seq<A>, right: Seq<A>, leq: spec_fn(A, A) -> bool) -> Seq<A>
2952 recommends
2953 sorted_by(left, leq),
2954 sorted_by(right, leq),
2955 total_ordering(leq),
2956 decreases left.len(), right.len(),
2957{
2958 if left.len() == 0 {
2959 right
2960 } else if right.len() == 0 {
2961 left
2962 } else if leq(left.first(), right.first()) {
2963 Seq::<A>::empty().push(left.first()) + merge_sorted_with(left.drop_first(), right, leq)
2964 } else {
2965 Seq::<A>::empty().push(right.first()) + merge_sorted_with(left, right.drop_first(), leq)
2966 }
2967}
2968
2969proof fn lemma_merge_sorted_with_ensures<A>(left: Seq<A>, right: Seq<A>, leq: spec_fn(A, A) -> bool)
2970 requires
2971 sorted_by(left, leq),
2972 sorted_by(right, leq),
2973 total_ordering(leq),
2974 ensures
2975 (left + right).to_multiset() =~= merge_sorted_with(left, right, leq).to_multiset(),
2976 sorted_by(merge_sorted_with(left, right, leq), leq),
2977 decreases left.len(), right.len(),
2978{
2979 broadcast use group_seq_properties;
2981
2982 if left.len() == 0 {
2983 assert(left + right =~= right);
2984 } else if right.len() == 0 {
2985 assert(left + right =~= left);
2986 } else if leq(left.first(), right.first()) {
2987 let result = Seq::<A>::empty().push(left.first()) + merge_sorted_with(
2988 left.drop_first(),
2989 right,
2990 leq,
2991 );
2992 lemma_merge_sorted_with_ensures(left.drop_first(), right, leq);
2993 let rest = merge_sorted_with(left.drop_first(), right, leq);
2994 assert(rest.len() == 0 || rest.first() == left.drop_first().first() || rest.first()
2995 == right.first()) by {
2996 if left.drop_first().len() == 0 {
2997 } else if leq(left.drop_first().first(), right.first()) {
2998 assert(rest =~= Seq::<A>::empty().push(left.drop_first().first())
2999 + merge_sorted_with(left.drop_first().drop_first(), right, leq));
3000 } else {
3001 assert(rest =~= Seq::<A>::empty().push(right.first()) + merge_sorted_with(
3002 left.drop_first(),
3003 right.drop_first(),
3004 leq,
3005 ));
3006 }
3007 }
3008 lemma_new_first_element_still_sorted_by(left.first(), rest, leq);
3009 assert((left.drop_first() + right) =~= (left + right).drop_first());
3010 } else {
3011 let result = Seq::<A>::empty().push(right.first()) + merge_sorted_with(
3012 left,
3013 right.drop_first(),
3014 leq,
3015 );
3016 lemma_merge_sorted_with_ensures(left, right.drop_first(), leq);
3017 let rest = merge_sorted_with(left, right.drop_first(), leq);
3018 assert(rest.len() == 0 || rest.first() == left.first() || rest.first()
3019 == right.drop_first().first()) by {
3020 assert(left.len() > 0);
3021 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(
3024 left.drop_first(),
3025 right.drop_first(),
3026 leq,
3027 ));
3028 } else {
3029 assert(rest =~= Seq::<A>::empty().push(right.drop_first().first())
3030 + merge_sorted_with(left, right.drop_first().drop_first(), leq));
3031 }
3032 }
3033 lemma_new_first_element_still_sorted_by(
3034 right.first(),
3035 merge_sorted_with(left, right.drop_first(), leq),
3036 leq,
3037 );
3038 lemma_seq_union_to_multiset_commutative(left, right);
3039 assert((right.drop_first() + left) =~= (right + left).drop_first());
3040 lemma_seq_union_to_multiset_commutative(right.drop_first(), left);
3041 }
3042}
3043
3044pub proof fn lemma_max_of_concat(x: Seq<int>, y: Seq<int>)
3047 requires
3048 0 < x.len() && 0 < y.len(),
3049 ensures
3050 x.max() <= (x + y).max(),
3051 y.max() <= (x + y).max(),
3052 forall|elt: int| (x + y).contains(elt) ==> elt <= (x + y).max(),
3053 decreases x.len(),
3054{
3055 broadcast use group_seq_properties;
3056
3057 x.max_ensures();
3058 y.max_ensures();
3059 (x + y).max_ensures();
3060 assert(x.drop_first().len() == x.len() - 1);
3061 if x.len() == 1 {
3062 assert(y.max() <= (x + y).max()) by {
3063 assert((x + y).contains(y.max()));
3064 }
3065 } else {
3066 assert(x.max() <= (x + y).max()) by {
3067 assert(x.contains(x.max()));
3068 assert((x + y).contains(x.max()));
3069 }
3070 assert(x.drop_first() + y =~= (x + y).drop_first());
3071 lemma_max_of_concat(x.drop_first(), y);
3072 }
3073}
3074
3075pub proof fn lemma_min_of_concat(x: Seq<int>, y: Seq<int>)
3078 requires
3079 0 < x.len() && 0 < y.len(),
3080 ensures
3081 (x + y).min() <= x.min(),
3082 (x + y).min() <= y.min(),
3083 forall|elt: int| (x + y).contains(elt) ==> (x + y).min() <= elt,
3084 decreases x.len(),
3085{
3086 x.min_ensures();
3087 y.min_ensures();
3088 (x + y).min_ensures();
3089 broadcast use group_seq_properties;
3090
3091 if x.len() == 1 {
3092 assert((x + y).min() <= y.min()) by {
3093 assert((x + y).contains(y.min()));
3094 }
3095 } else {
3096 assert((x + y).min() <= x.min()) by {
3097 assert((x + y).contains(x.min()));
3098 }
3099 assert((x + y).min() <= y.min()) by {
3100 assert((x + y).contains(y.min()));
3101 }
3102 assert(x.drop_first() + y =~= (x + y).drop_first());
3103 lemma_max_of_concat(x.drop_first(), y)
3104 }
3105}
3106
3107pub broadcast proof fn to_multiset_build<A>(s: Seq<A>, a: A)
3111 ensures
3112 #![trigger s.push(a).to_multiset()]
3113 s.push(a).to_multiset() =~= s.to_multiset().insert(a),
3114 decreases s.len(),
3115{
3116 broadcast use super::multiset::group_multiset_axioms;
3117
3118 if s.len() == 0 {
3119 assert(s.to_multiset() =~= Multiset::<A>::empty());
3120 assert(s.push(a).drop_first() =~= Seq::<A>::empty());
3121 assert(s.push(a).to_multiset() =~= Multiset::<A>::empty().insert(a).add(
3122 Seq::<A>::empty().to_multiset(),
3123 ));
3124 } else {
3125 to_multiset_build(s.drop_first(), a);
3126 assert(s.drop_first().push(a).to_multiset() =~= s.drop_first().to_multiset().insert(a));
3127 assert(s.push(a).drop_first() =~= s.drop_first().push(a));
3128 }
3129}
3130
3131pub broadcast proof fn to_multiset_remove<A>(s: Seq<A>, i: int)
3132 requires
3133 0 <= i < s.len(),
3134 ensures
3135 #![trigger s.remove(i).to_multiset()]
3136 s.remove(i).to_multiset() == s.to_multiset().remove(s[i]),
3137{
3138 broadcast use super::multiset::group_multiset_axioms;
3139
3140 let s0 = s[..i];
3141 let s1 = s[i..];
3142 let s2 = s[i + 1..];
3143 lemma_seq_union_to_multiset_commutative(s0, s2);
3144 lemma_seq_union_to_multiset_commutative(s0, s1);
3145 assert(s == s0 + s1);
3146 assert(s2 + s0 == (s1 + s0).drop_first());
3147 assert(s.remove(i).to_multiset() =~= s.to_multiset().remove(s[i]));
3148}
3149
3150pub broadcast proof fn to_multiset_insert<A>(s: Seq<A>, i: int, a: A)
3151 requires
3152 0 <= i <= s.len(),
3153 ensures
3154 #![trigger s.insert(i, a).to_multiset()]
3155 s.insert(i, a).to_multiset() == s.to_multiset().insert(a),
3156 decreases s.len(),
3157{
3158 broadcast use super::multiset::group_multiset_axioms;
3159
3160 let s0 = s[..i];
3161 let s1 = s[i..];
3162
3163 assert(s =~= s0 + s1);
3164 assert(s.insert(i, a) =~= s0 + seq![a] + s1);
3165 assert(((s0 + seq![a]) + s1).to_multiset() =~= ((seq![a] + s0) + s1).to_multiset()) by {
3166 broadcast use lemma_multiset_commutative;
3167
3168 };
3169 assert((seq![a] + s0 + s1).drop_first() == s0 + s1);
3170 assert(s.insert(i, a).to_multiset() =~= s.to_multiset().insert(a));
3171}
3172
3173pub broadcast proof fn to_multiset_len<A>(s: Seq<A>)
3175 ensures
3176 s.len() == #[trigger] s.to_multiset().len(),
3177 decreases s.len(),
3178{
3179 broadcast use super::multiset::group_multiset_axioms;
3180
3181 if s.len() == 0 {
3182 assert(s.to_multiset() =~= Multiset::<A>::empty());
3183 assert(s.len() == 0);
3184 } else {
3185 to_multiset_len(s.drop_first());
3186 assert(s.len() == s.drop_first().len() + 1);
3187 assert(s.to_multiset().len() == s.drop_first().to_multiset().len() + 1);
3188 }
3189}
3190
3191pub broadcast proof fn to_multiset_contains<A>(s: Seq<A>, a: A)
3193 ensures
3194 #![trigger s.to_multiset().count(a)]
3195 s.contains(a) <==> s.to_multiset().count(a) > 0,
3196 decreases s.len(),
3197{
3198 broadcast use super::multiset::group_multiset_axioms;
3199
3200 if s.len() != 0 {
3201 if s.contains(a) {
3203 if s.first() == a {
3204 to_multiset_build(s, a);
3205 assert(s.to_multiset() =~= Multiset::<A>::empty().insert(s.first()).add(
3206 s.drop_first().to_multiset(),
3207 ));
3208 assert(Multiset::<A>::empty().insert(s.first()).contains(s.first()));
3209 } else {
3210 to_multiset_contains(s.drop_first(), a);
3211 assert(s[1..] =~= s.drop_first());
3212 lemma_seq_skip_contains(s, 1, a);
3213 assert(s.to_multiset().count(a) == s.drop_first().to_multiset().count(a));
3214 assert(s.contains(a) <==> s.to_multiset().count(a) > 0);
3215 }
3216 }
3217 if s.to_multiset().count(a) > 0 {
3220 to_multiset_contains(s.drop_first(), a);
3221 assert(s.contains(a) <==> s.to_multiset().count(a) > 0);
3222 } else {
3223 assert(s.contains(a) <==> s.to_multiset().count(a) > 0);
3224 }
3225 }
3226}
3227
3228pub broadcast proof fn to_multiset_update<A>(s: Seq<A>, i: int, a: A)
3229 requires
3230 0 <= i < s.len(),
3231 ensures
3232 #[trigger] s.update(i, a).to_multiset() == s.to_multiset().insert(a).remove(s[i]),
3233 decreases s.len(),
3234{
3235 broadcast use {
3236 super::seq_lib::lemma_seq_take_len,
3237 super::multiset::group_multiset_properties,
3238 super::multiset::group_multiset_axioms,
3239 to_multiset_insert,
3240 to_multiset_remove,
3241 to_multiset_contains,
3242 lemma_update_is_remove_insert,
3243 };
3244
3245 assert(s.update(i, a).to_multiset() =~= s.to_multiset().insert(a).remove(s[i]));
3246
3247}
3248
3249pub broadcast proof fn lemma_update_is_remove_insert<A>(s: Seq<A>, i: int, a: A)
3251 requires
3252 0 <= i < s.len(),
3253 ensures
3254 #[trigger] s.update(i, a) =~= s.remove(i).insert(i, a),
3255 decreases s.len(),
3256{
3257}
3258
3259pub proof fn lemma_append_last<A>(s1: Seq<A>, s2: Seq<A>)
3262 requires
3263 0 < s2.len(),
3264 ensures
3265 (s1 + s2).last() == s2.last(),
3266{
3267}
3268
3269pub proof fn lemma_concat_associative<A>(s1: Seq<A>, s2: Seq<A>, s3: Seq<A>)
3271 ensures
3272 s1.add(s2.add(s3)) =~= s1.add(s2).add(s3),
3273{
3274}
3275
3276spec fn seq_to_set_rec<A>(seq: Seq<A>) -> Set<A>
3278 decreases seq.len(),
3279{
3280 if seq.len() == 0 {
3281 Set::empty()
3282 } else {
3283 seq_to_set_rec(seq.drop_last()).insert(seq.last())
3284 }
3285}
3286
3287proof fn seq_to_set_rec_contains<A>(seq: Seq<A>)
3289 ensures
3290 forall|a| #[trigger] seq.contains(a) <==> seq_to_set_rec(seq).contains(a),
3291 decreases seq.len(),
3292{
3293 broadcast use super::set::group_set_lemmas;
3294
3295 if seq.len() > 0 {
3296 assert(forall|a| #[trigger]
3297 seq.drop_last().contains(a) <==> seq_to_set_rec(seq.drop_last()).contains(a)) by {
3298 seq_to_set_rec_contains(seq.drop_last());
3299 }
3300 assert(seq =~= seq.drop_last().push(seq.last()));
3301 assert forall|a| #[trigger] seq.contains(a) <==> seq_to_set_rec(seq).contains(a) by {
3302 if !seq.drop_last().contains(a) {
3303 if a == seq.last() {
3304 assert(seq.contains(a));
3305 assert(seq_to_set_rec(seq).contains(a));
3306 } else {
3307 assert(!seq_to_set_rec(seq).contains(a));
3308 }
3309 }
3310 }
3311 }
3312}
3313
3314proof fn seq_to_set_equal_rec<A>(seq: Seq<A>)
3316 ensures
3317 seq.to_set() == seq_to_set_rec(seq),
3318 decreases seq.len(),
3319{
3320 broadcast use super::set::group_set_lemmas;
3321
3322 seq.to_set_ensures();
3323 assert(forall|n| seq.contains(n) <==> #[trigger] seq_to_set_rec(seq).contains(n)) by {
3324 seq_to_set_rec_contains(seq);
3325 }
3326 assert(seq.to_set() =~= seq_to_set_rec(seq));
3327}
3328
3329pub proof fn seq_to_set_distributes_over_add<T>(s1: Seq<T>, s2: Seq<T>)
3330 ensures
3331 s1.to_set() + s2.to_set() =~= (s1 + s2).to_set(),
3332{
3333 broadcast use super::group_vstd_default;
3334 broadcast use super::set_lib::group_set_properties;
3335 broadcast use group_seq_properties;
3336
3337}
3338
3339pub proof fn lemma_no_dup_in_concat<A>(a: Seq<A>, b: Seq<A>)
3343 requires
3344 a.no_duplicates(),
3345 b.no_duplicates(),
3346 forall|i: int, j: int| 0 <= i < a.len() && 0 <= j < b.len() ==> a[i] != b[j],
3347 ensures
3348 #[trigger] (a + b).no_duplicates(),
3349{
3350}
3351
3352pub proof fn lemma_flatten_concat<A>(x: Seq<Seq<A>>, y: Seq<Seq<A>>)
3356 ensures
3357 (x + y).flatten() =~= x.flatten() + y.flatten(),
3358 decreases x.len(),
3359{
3360 if x.len() == 0 {
3361 assert(x + y =~= y);
3362 } else {
3363 assert((x + y).drop_first() =~= x.drop_first() + y);
3364 assert(x.first() + (x.drop_first() + y).flatten() =~= x.first() + x.drop_first().flatten()
3365 + y.flatten()) by {
3366 lemma_flatten_concat(x.drop_first(), y);
3367 }
3368 }
3369}
3370
3371pub proof fn lemma_flatten_alt_concat<A>(x: Seq<Seq<A>>, y: Seq<Seq<A>>)
3376 ensures
3377 (x + y).flatten_alt() =~= x.flatten_alt() + y.flatten_alt(),
3378 decreases y.len(),
3379{
3380 if y.len() == 0 {
3381 assert(x + y =~= x);
3382 } else {
3383 assert((x + y).drop_last() =~= x + y.drop_last());
3384 assert((x + y.drop_last()).flatten_alt() + y.last() =~= x.flatten_alt()
3385 + y.drop_last().flatten_alt() + y.last()) by {
3386 lemma_flatten_alt_concat(x, y.drop_last());
3387 }
3388 }
3389}
3390
3391pub broadcast proof fn lemma_seq_union_to_multiset_commutative<A>(a: Seq<A>, b: Seq<A>)
3394 ensures
3395 #[trigger] (a + b).to_multiset() =~= (b + a).to_multiset(),
3396{
3397 broadcast use super::multiset::group_multiset_axioms;
3398
3399 lemma_multiset_commutative(a, b);
3400 lemma_multiset_commutative(b, a);
3401}
3402
3403pub broadcast proof fn lemma_multiset_commutative<A>(a: Seq<A>, b: Seq<A>)
3406 ensures
3407 #[trigger] (a + b).to_multiset() =~= a.to_multiset().add(b.to_multiset()),
3408 decreases a.len(),
3409{
3410 broadcast use super::multiset::group_multiset_axioms;
3411
3412 if a.len() == 0 {
3413 assert(a + b =~= b);
3414 } else {
3415 lemma_multiset_commutative(a.drop_first(), b);
3416 assert(a.drop_first() + b =~= (a + b).drop_first());
3417 }
3418}
3419
3420pub proof fn lemma_sorted_unique<A>(x: Seq<A>, y: Seq<A>, leq: spec_fn(A, A) -> bool)
3422 requires
3423 sorted_by(x, leq),
3424 sorted_by(y, leq),
3425 total_ordering(leq),
3426 x.to_multiset() == y.to_multiset(),
3427 ensures
3428 x =~= y,
3429 decreases x.len(), y.len(),
3430{
3431 broadcast use super::multiset::group_multiset_axioms;
3432 broadcast use group_to_multiset_ensures;
3433
3434 if x.len() == 0 || y.len() == 0 {
3435 } else {
3436 assert(x.to_multiset().contains(x[0]));
3437 assert(x.to_multiset().contains(y[0]));
3438 let i = choose|i: int| #![trigger x.spec_index(i) ] 0 <= i < x.len() && x[i] == y[0];
3439 assert(leq(x[i], x[0]));
3440 assert(leq(x[0], x[i]));
3441 assert(x.drop_first().to_multiset() =~= x.to_multiset().remove(x[0]));
3442 assert(y.drop_first().to_multiset() =~= y.to_multiset().remove(y[0]));
3443 lemma_sorted_unique(x.drop_first(), y.drop_first(), leq);
3444 assert(x.drop_first() =~= y.drop_first());
3445 assert(x.first() == y.first());
3446 assert(x =~= Seq::<A>::empty().push(x.first()).add(x.drop_first()));
3447 assert(x =~= y);
3448 }
3449}
3450
3451pub broadcast proof fn lemma_seq_contains<A>(s: Seq<A>, x: A)
3453 ensures
3454 #[trigger] s.contains(x) <==> exists|i: int| 0 <= i < s.len() && #[trigger] s[i] == x,
3455{
3456}
3457
3458pub broadcast proof fn lemma_seq_empty_contains_nothing<A>(x: A)
3461 ensures
3462 !(#[trigger] Seq::<A>::empty().contains(x)),
3463{
3464}
3465
3466pub broadcast proof fn lemma_seq_empty_equality<A>(s: Seq<A>)
3470 ensures
3471 #[trigger] s.len() == 0 ==> s =~= Seq::<A>::empty(),
3472{
3473}
3474
3475pub broadcast proof fn lemma_seq_concat_contains_all_elements<A>(x: Seq<A>, y: Seq<A>, elt: A)
3479 ensures
3480 #[trigger] (x + y).contains(elt) <==> x.contains(elt) || y.contains(elt),
3481 decreases x.len(),
3482{
3483 if x.len() == 0 && y.len() > 0 {
3484 assert((x + y) =~= y);
3485 } else {
3486 assert forall|elt: A| #[trigger] x.contains(elt) implies #[trigger] (x + y).contains(
3487 elt,
3488 ) by {
3489 let index = choose|i: int| 0 <= i < x.len() && x[i] == elt;
3490 assert((x + y)[index] == elt);
3491 }
3492 assert forall|elt: A| #[trigger] y.contains(elt) implies #[trigger] (x + y).contains(
3493 elt,
3494 ) by {
3495 let index = choose|i: int| 0 <= i < y.len() && y[i] == elt;
3496 assert((x + y)[index + x.len()] == elt);
3497 }
3498 }
3499}
3500
3501pub broadcast proof fn lemma_seq_contains_after_push<A>(s: Seq<A>, v: A, x: A)
3504 ensures
3505 #[trigger] s.push(v).contains(x) <==> v == x || s.contains(x),
3506{
3507 assert forall|elt: A| #[trigger] s.contains(elt) implies #[trigger] s.push(v).contains(elt) by {
3508 let index = choose|i: int| 0 <= i < s.len() && s[i] == elt;
3509 assert(s.push(v)[index] == elt);
3510 }
3511 assert(s.push(v)[s.len() as int] == v);
3512}
3513
3514pub broadcast proof fn lemma_seq_subrange_elements<A>(s: Seq<A>, start: int, stop: int, x: A)
3518 requires
3519 0 <= start <= stop <= s.len(),
3520 ensures
3521 #[trigger] s[start..stop].contains(x) <==> (exists|i: int|
3522 0 <= start <= i < stop <= s.len() && #[trigger] s[i] == x),
3523{
3524 assert((exists|i: int| 0 <= start <= i < stop <= s.len() && s[i] == x)
3525 ==> s[start..stop].contains(x)) by {
3526 if exists|i: int| 0 <= start <= i < stop <= s.len() && s[i] == x {
3527 let index = choose|i: int| 0 <= start <= i < stop <= s.len() && s[i] == x;
3528 assert(s[start..stop][index - start] == s[index]);
3529 }
3530 }
3531}
3532
3533pub open spec fn commutative_foldr<A, B>(f: spec_fn(A, B) -> B) -> bool {
3535 forall|x: A, y: A, v: B| #[trigger] f(x, f(y, v)) == f(y, f(x, v))
3536}
3537
3538pub open spec fn commutative_foldl<A, B>(f: spec_fn(B, A) -> B) -> bool {
3540 forall|x: A, y: A, v: B| #[trigger] f(f(v, x), y) == f(f(v, y), x)
3541}
3542
3543pub proof fn lemma_fold_right_permutation<A, B>(l1: Seq<A>, l2: Seq<A>, f: spec_fn(A, B) -> B, v: B)
3546 requires
3547 commutative_foldr(f),
3548 l1.to_multiset() == l2.to_multiset(),
3549 ensures
3550 l1.fold_right(f, v) == l2.fold_right(f, v),
3551 decreases l1.len(),
3552{
3553 broadcast use group_to_multiset_ensures;
3554
3555 if l1.len() > 0 {
3556 let a = l1.last();
3557 let i = l2.index_of(a);
3558 let l2r = l2[i + 1..].fold_right(f, v);
3559
3560 assert(l1.to_multiset().count(a) > 0);
3561 l1.drop_last().lemma_fold_right_commute_one(a, f, v);
3562 l2[..i].lemma_fold_right_commute_one(a, f, l2r);
3563
3564 l2.lemma_fold_right_split(f, v, i + 1);
3565 l2.remove(i).lemma_fold_right_split(f, v, i);
3566
3567 assert(l2[..i + 1].drop_last() == l2[..i]);
3568 assert(l1.drop_last() == l1.remove(l1.len() - 1));
3569
3570 assert(l2.remove(i)[..i] == l2[..i]);
3571 assert(l2.remove(i)[i..l2.remove(i).len()] == l2[i + 1..l2.len()]);
3572
3573 lemma_fold_right_permutation(l1.drop_last(), l2.remove(i), f, v);
3574 } else {
3575 assert(l2.to_multiset().len() == 0);
3576 }
3577}
3578
3579pub proof fn lemma_fold_left_permutation<A, B>(l1: Seq<A>, l2: Seq<A>, f: spec_fn(B, A) -> B, v: B)
3582 requires
3583 commutative_foldl(f),
3584 l1.to_multiset() == l2.to_multiset(),
3585 ensures
3586 l1.fold_left(v, f) == l2.fold_left(v, f),
3587{
3588 let g = |a: A, b: B| f(b, a);
3589 assert(f =~= |b: B, a: A| g(a, b));
3590 assert(l1.fold_left(v, f) == l1.reverse().fold_right(g, v)) by {
3591 l1.lemma_reverse_fold_right(v, g)
3592 };
3593 assert(l2.fold_left(v, f) == l2.reverse().fold_right(g, v)) by {
3594 l2.lemma_reverse_fold_right(v, g)
3595 };
3596 assert(l1.reverse().to_multiset() =~= l2.reverse().to_multiset()) by {
3597 l1.lemma_reverse_to_multiset();
3598 l2.lemma_reverse_to_multiset();
3599 }
3600 assert(forall|x: A| #[trigger] l1.reverse().contains(x) ==> l1.contains(x));
3601 assert(forall|x: A| #[trigger] l2.reverse().contains(x) ==> l2.contains(x));
3602 lemma_fold_right_permutation(l1.reverse(), l2.reverse(), g, v);
3603}
3604
3605pub broadcast proof fn lemma_seq_take_len<A>(s: Seq<A>, n: int)
3611 ensures
3612 0 <= n <= s.len() ==> #[trigger] s[..n].len() == n,
3613{
3614}
3615
3616pub broadcast proof fn lemma_seq_take_contains<A>(s: Seq<A>, n: int, x: A)
3620 requires
3621 0 <= n <= s.len(),
3622 ensures
3623 #[trigger] s[..n].contains(x) <==> (exists|i: int|
3624 0 <= i < n <= s.len() && #[trigger] s[i] == x),
3625{
3626 assert((exists|i: int| 0 <= i < n <= s.len() && #[trigger] s[i] == x) ==> s[..n].contains(x))
3627 by {
3628 if exists|i: int| 0 <= i < n <= s.len() && #[trigger] s[i] == x {
3629 let index = choose|i: int| 0 <= i < n <= s.len() && #[trigger] s[i] == x;
3630 assert(s[..n][index] == s[index]);
3631 }
3632 }
3633}
3634
3635pub broadcast proof fn lemma_seq_take_index<A>(s: Seq<A>, n: int, j: int)
3639 ensures
3640 0 <= j < n <= s.len() ==> #[trigger] s[..n][j] == s[j],
3641{
3642}
3643
3644pub proof fn subrange_of_matching_take<T>(a: Seq<T>, b: Seq<T>, s: int, e: int, l: int)
3645 requires
3646 a[..l] == b[..l],
3647 l <= a.len(),
3648 l <= b.len(),
3649 0 <= s <= e <= l,
3650 ensures
3651 a[s..e] == b[s..e],
3652{
3653 assert forall|i| 0 <= i < e - s implies #[trigger] a[s..e][i] == b[s..e][i] by {
3654 assert(a[s..e][i] == a[..l][i + s]);
3655 }
3657 assert(a[s..e] == b[s..e]);
3660}
3661
3662pub broadcast proof fn lemma_seq_skip_len<A>(s: Seq<A>, n: int)
3666 ensures
3667 0 <= n <= s.len() ==> #[trigger] s[n..].len() == s.len() - n,
3668{
3669}
3670
3671pub broadcast proof fn lemma_seq_skip_contains<A>(s: Seq<A>, n: int, x: A)
3675 requires
3676 0 <= n <= s.len(),
3677 ensures
3678 #[trigger] s[n..].contains(x) <==> (exists|i: int|
3679 0 <= n <= i < s.len() && #[trigger] s[i] == x),
3680{
3681 assert((exists|i: int| 0 <= n <= i < s.len() && #[trigger] s[i] == x) ==> s[n..].contains(x))
3682 by {
3683 let index = choose|i: int| 0 <= n <= i < s.len() && #[trigger] s[i] == x;
3684 lemma_seq_skip_index(s, n, index - n);
3685 }
3686}
3687
3688pub broadcast proof fn lemma_seq_skip_index<A>(s: Seq<A>, n: int, j: int)
3692 ensures
3693 0 <= n && 0 <= j < (s.len() - n) ==> #[trigger] s[n..][j] == s[j + n],
3694{
3695}
3696
3697pub broadcast proof fn lemma_seq_skip_index2<A>(s: Seq<A>, n: int, k: int)
3702 ensures
3703 0 <= n <= k < s.len() ==> (#[trigger] s[n..])[k - n] == #[trigger] s[k],
3704{
3705}
3706
3707pub broadcast proof fn lemma_seq_append_take_skip<A>(a: Seq<A>, b: Seq<A>, n: int)
3712 ensures
3713 #![trigger (a + b)[..n]]
3714 #![trigger (a + b)[n..]]
3715 n == a.len() ==> ((a + b)[..n] =~= a && (a + b)[n..] =~= b),
3718{
3719}
3720
3721pub broadcast proof fn lemma_seq_take_update_commut1<A>(s: Seq<A>, i: int, v: A, n: int)
3728 ensures
3729 #![trigger s.update(i, v)[..n]]
3730 0 <= i < n <= s.len() ==> #[trigger] s.update(i, v)[..n] =~= s[..n].update(i, v),
3731{
3732}
3733
3734pub broadcast proof fn lemma_seq_take_update_commut2<A>(s: Seq<A>, i: int, v: A, n: int)
3739 ensures
3740 0 <= n <= i < s.len() ==> #[trigger] s.update(i, v)[..n] =~= s[..n],
3741{
3742}
3743
3744pub broadcast proof fn lemma_seq_skip_update_commut1<A>(s: Seq<A>, i: int, v: A, n: int)
3749 ensures
3750 0 <= n <= i < s.len() ==> #[trigger] s.update(i, v)[n..] =~= s[n..].update(i - n, v),
3751{
3752}
3753
3754pub broadcast proof fn lemma_seq_skip_update_commut2<A>(s: Seq<A>, i: int, v: A, n: int)
3759 ensures
3760 0 <= i < n <= s.len() ==> #[trigger] s.update(i, v)[n..] =~= s[n..],
3761{
3762}
3763
3764pub broadcast proof fn lemma_seq_skip_build_commut<A>(s: Seq<A>, v: A, n: int)
3768 ensures
3769 #![trigger s.push(v)[n..]]
3770 0 <= n <= s.len() ==> s.push(v)[n..] =~= s[n..].push(v),
3771{
3772}
3773
3774pub broadcast proof fn lemma_seq_skip_nothing<A>(s: Seq<A>, n: int)
3777 ensures
3778 n == 0 ==> #[trigger] s[n..] =~= s,
3779{
3780}
3781
3782pub broadcast proof fn lemma_seq_take_nothing<A>(s: Seq<A>, n: int)
3785 ensures
3786 n == 0 ==> #[trigger] s[..n] =~= Seq::<A>::empty(),
3787{
3788}
3789
3790pub broadcast proof fn lemma_seq_skip_of_skip<A>(s: Seq<A>, m: int, n: int)
3795 ensures
3796 (0 <= m && 0 <= n && m + n <= s.len()) ==> #[trigger] s[m..][n..] =~= s[m + n..],
3797{
3798}
3799
3800#[doc(hidden)]
3801#[verifier::inline]
3802pub open spec fn check_argument_is_seq<A>(s: Seq<A>) -> Seq<A> {
3803 s
3804}
3805
3806#[macro_export]
3851macro_rules! assert_seqs_equal {
3852 [$($tail:tt)*] => {
3853 $crate::vstd::prelude::verus_proof_macro_exprs!($crate::vstd::seq_lib::assert_seqs_equal_internal!($($tail)*))
3854 };
3855}
3856
3857#[macro_export]
3858#[doc(hidden)]
3859macro_rules! assert_seqs_equal_internal {
3860 (::vstd::spec_eq($s1:expr, $s2:expr)) => {
3861 $crate::vstd::seq_lib::assert_seqs_equal_internal!($s1, $s2)
3862 };
3863 (::vstd::prelude::spec_eq($s1:expr, $s2:expr)) => {
3864 $crate::vstd::seq_lib::assert_seqs_equal_internal!($s1, $s2)
3865 };
3866 (::vstd::prelude::spec_eq($s1:expr, $s2:expr), $idx:ident => $bblock:block) => {
3867 $crate::vstd::seq_lib::assert_seqs_equal_internal!($s1, $s2, $idx => $bblock)
3868 };
3869 (crate::prelude::spec_eq($s1:expr, $s2:expr)) => {
3870 $crate::vstd::seq_lib::assert_seqs_equal_internal!($s1, $s2)
3871 };
3872 (crate::prelude::spec_eq($s1:expr, $s2:expr), $idx:ident => $bblock:block) => {
3873 $crate::vstd::seq_lib::assert_seqs_equal_internal!($s1, $s2, $idx => $bblock)
3874 };
3875 (crate::verus_builtin::spec_eq($s1:expr, $s2:expr)) => {
3876 $crate::vstd::seq_lib::assert_seqs_equal_internal!($s1, $s2)
3877 };
3878 (crate::verus_builtin::spec_eq($s1:expr, $s2:expr), $idx:ident => $bblock:block) => {
3879 $crate::vstd::seq_lib::assert_seqs_equal_internal!($s1, $s2, $idx => $bblock)
3880 };
3881 ($s1:expr, $s2:expr $(,)?) => {
3882 $crate::vstd::seq_lib::assert_seqs_equal_internal!($s1, $s2, idx => { })
3883 };
3884 ($s1:expr, $s2:expr, $idx:ident => $bblock:block) => {
3885 #[verifier::spec] let s1 = $crate::vstd::seq_lib::check_argument_is_seq($s1);
3886 #[verifier::spec] let s2 = $crate::vstd::seq_lib::check_argument_is_seq($s2);
3887 $crate::vstd::prelude::assert_by($crate::vstd::prelude::equal(s1, s2), {
3888 $crate::vstd::prelude::assert_(s1.len() == s2.len());
3889 $crate::vstd::prelude::assert_forall_by(|$idx : $crate::vstd::prelude::int| {
3890 $crate::vstd::prelude::requires($crate::vstd::prelude::verus_proof_expr!(0 <= $idx && $idx < s1.len()));
3891 $crate::vstd::prelude::ensures($crate::vstd::prelude::equal(s1.index($idx), s2.index($idx)));
3892 { $bblock }
3893 });
3894 $crate::vstd::prelude::assert_($crate::vstd::prelude::ext_equal(s1, s2));
3895 });
3896 }
3897}
3898
3899pub broadcast group group_filter_ensures {
3900 Seq::lemma_filter_len,
3901 Seq::lemma_filter_pred,
3902 Seq::lemma_filter_contains,
3903}
3904
3905pub broadcast group group_seq_lib_default {
3906 Seq::to_set_ensures,
3907 group_filter_ensures,
3908 Seq::lemma_filter_index,
3909 Seq::add_empty_left,
3910 Seq::add_empty_right,
3911 Seq::push_distributes_over_add,
3912 Seq::filter_distributes_over_add,
3913 Seq::lemma_fold_right_split,
3914 Seq::lemma_fold_left_split,
3915 Seq::lemma_as_ref_index,
3916}
3917
3918pub broadcast group group_to_multiset_ensures {
3919 to_multiset_build,
3920 to_multiset_remove,
3921 to_multiset_len,
3922 to_multiset_contains,
3923 to_multiset_insert,
3924 to_multiset_update,
3925}
3926
3927pub broadcast group group_seq_properties {
3929 lemma_seq_contains,
3930 lemma_seq_empty_contains_nothing,
3931 lemma_seq_empty_equality,
3932 lemma_seq_concat_contains_all_elements,
3933 lemma_seq_contains_after_push,
3934 lemma_seq_subrange_elements,
3935 lemma_seq_take_len,
3936 lemma_seq_take_contains,
3937 lemma_seq_take_index,
3938 lemma_seq_skip_len,
3939 lemma_seq_skip_contains,
3940 lemma_seq_skip_index,
3941 lemma_seq_skip_index2,
3942 lemma_seq_append_take_skip,
3943 lemma_seq_take_update_commut1,
3944 lemma_seq_take_update_commut2,
3945 lemma_seq_skip_update_commut1,
3946 lemma_seq_skip_update_commut2,
3947 lemma_seq_skip_build_commut,
3948 lemma_seq_skip_nothing,
3949 lemma_seq_take_nothing,
3950 group_to_multiset_ensures,
3954}
3955
3956#[doc(hidden)]
3957pub use assert_seqs_equal_internal;
3958pub use assert_seqs_equal;
3959
3960}