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
16use verus as verus_skip_verusfmt; verus_skip_verusfmt! {
18
19broadcast use group_seq_lemmas;
20
21impl<A> Seq<A> {
22 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> {
32 Seq::new(self.len(), |i: int| f(self[i]))
33 }
34
35 pub open spec fn flat_map<B>(self, f: spec_fn(A) -> Seq<B>) -> Seq<B> {
49 self.map_values(f).flatten()
50 }
51
52 pub open spec fn as_ref(&self) -> Seq<&A> {
54 Seq::new(self.len(), |i: int| &self[i])
55 }
56
57 pub open spec fn is_prefix_of(self, other: Self) -> bool {
69 self.len() <= other.len() && self =~= other[..self.len()]
70 }
71
72 pub open spec fn is_suffix_of(self, other: Self) -> bool {
84 &&& self.len() <= other.len()
85 &&& self =~= other[other.len() - self.len()..other.len()]
86 }
87
88 pub closed spec fn sort_by(self, leq: spec_fn(A, A) -> bool) -> Seq<A>
96 recommends
97 total_ordering(leq),
98 decreases self.len(),
99 {
100 if self.len() <= 1 {
101 self
102 } else {
103 let split_index = self.len() / 2;
104 let left = self[..split_index];
105 let right = self[split_index..];
106 let left_sorted = left.sort_by(leq);
107 let right_sorted = right.sort_by(leq);
108 merge_sorted_with(left_sorted, right_sorted, leq)
109 }
110 }
111
112 pub open spec fn all(self, pred: spec_fn(A) -> bool) -> bool {
123 forall|i: int| 0 <= i < self.len() ==> #[trigger] pred(self[i])
124 }
125
126 pub open spec fn any(self, pred: spec_fn(A) -> bool) -> bool {
137 exists|i: int| 0 <= i < self.len() && #[trigger] pred(self[i])
138 }
139
140 pub open spec fn exactly_one(self, pred: spec_fn(A) -> bool) -> bool {
150 self.filter(pred).len() == 1
151 }
152
153 pub proof fn lemma_sort_by_ensures(self, leq: spec_fn(A, A) -> bool)
154 requires
155 total_ordering(leq),
156 ensures
157 self.to_multiset() =~= self.sort_by(leq).to_multiset(),
158 sorted_by(self.sort_by(leq), leq),
159 forall|x: A| !self.contains(x) ==> !(#[trigger] self.sort_by(leq).contains(x)),
160 decreases self.len(),
161 {
162 if self.len() <= 1 {
163 } else {
164 let split_index = self.len() / 2;
165 let left = self[..split_index];
166 let right = self[split_index..];
167 assert(self =~= left + right);
168 let left_sorted = left.sort_by(leq);
169 left.lemma_sort_by_ensures(leq);
170 let right_sorted = right.sort_by(leq);
171 right.lemma_sort_by_ensures(leq);
172 lemma_merge_sorted_with_ensures(left_sorted, right_sorted, leq);
173 lemma_multiset_commutative(left, right);
174 lemma_multiset_commutative(left_sorted, right_sorted);
175 assert forall|x: A| !self.contains(x) implies !(#[trigger] self.sort_by(leq).contains(
176 x,
177 )) by {
178 broadcast use group_to_multiset_ensures;
179
180 assert(!self.contains(x) ==> self.to_multiset().count(x) == 0);
181 }
182 }
183 }
184
185 #[verifier::opaque]
199 pub open spec fn filter(self, pred: spec_fn(A) -> bool) -> Self
200 decreases self.len(),
201 {
202 if self.len() == 0 {
203 self
204 } else {
205 let subseq = self.drop_last().filter(pred);
206 if pred(self.last()) {
207 subseq.push(self.last())
208 } else {
209 subseq
210 }
211 }
212 }
213
214 pub broadcast proof fn lemma_filter_len(self, pred: spec_fn(A) -> bool)
215 ensures
216 #[trigger] self.filter(pred).len() <= self.len(),
219 decreases self.len(),
220 {
221 reveal(Seq::filter);
222 let out = self.filter(pred);
223 if 0 < self.len() {
224 self.drop_last().lemma_filter_len(pred);
225 }
226 }
227
228 pub broadcast proof fn lemma_filter_pred(self, pred: spec_fn(A) -> bool, i: int)
229 requires
230 0 <= i < self.filter(pred).len(),
231 ensures
232 pred(#[trigger] self.filter(pred)[i]),
233 {
234 #[allow(deprecated)]
236 self.filter_lemma(pred);
237 }
238
239 pub broadcast proof fn lemma_filter_contains(self, pred: spec_fn(A) -> bool, i: int)
240 requires
241 0 <= i < self.len() && pred(self[i]),
242 ensures
243 #[trigger] self.filter(pred).contains(self[i]),
244 {
245 #[allow(deprecated)]
247 self.filter_lemma(pred);
248 }
249
250 #[cfg_attr(not(verus_verify_core), deprecated = "Use `broadcast use group_filter_ensures` instead" )]
252 pub proof fn filter_lemma(self, pred: spec_fn(A) -> bool)
253 ensures
254 forall|i: int|
260 0 <= i < self.filter(pred).len() ==> pred(#[trigger] self.filter(pred)[i]),
261 forall|i: int|
263 0 <= i < self.len() && pred(self[i]) ==> #[trigger] self.filter(pred).contains(
264 self[i],
265 ),
266 #[trigger] self.filter(pred).len() <= self.len(),
268 decreases self.len(),
269 {
270 reveal(Seq::filter);
271 let out = self.filter(pred);
272 if 0 < self.len() {
273 self.drop_last().filter_lemma(pred);
274 assert forall|i: int| 0 <= i < out.len() implies pred(out[i]) by {
275 if i < out.len() - 1 {
276 assert(self.drop_last().filter(pred)[i] == out.drop_last()[i]); assert(pred(out[i])); }
279 }
280 assert forall|i: int|
281 0 <= i < self.len() && pred(self[i]) implies #[trigger] out.contains(self[i]) by {
282 if i == self.len() - 1 {
283 assert(self[i] == out[out.len() - 1]); } else {
285 let subseq = self.drop_last().filter(pred);
286 assert(subseq.contains(self.drop_last()[i])); let j = choose|j| 0 <= j < subseq.len() && subseq[j] == self[i];
288 assert(out[j] == self[i]); }
290 }
291 }
292 }
293
294 pub broadcast proof fn filter_distributes_over_add(a: Self, b: Self, pred: spec_fn(A) -> bool)
295 ensures
296 #[trigger] (a + b).filter(pred) == a.filter(pred) + b.filter(pred),
297 decreases b.len(),
298 {
299 reveal(Seq::filter);
300 if 0 < b.len() {
301 Self::drop_last_distributes_over_add(a, b);
302 Self::filter_distributes_over_add(a, b.drop_last(), pred);
303 if pred(b.last()) {
304 Self::push_distributes_over_add(
305 a.filter(pred),
306 b.drop_last().filter(pred),
307 b.last(),
308 );
309 }
310 } else {
311 Self::add_empty_right(a, b);
312 Self::add_empty_right(a.filter(pred), b.filter(pred));
313 }
314 }
315
316 #[verifier::opaque]
340 pub open spec fn filter_index(self, pred: spec_fn(int) -> bool) -> Self
341 decreases self.len(),
342 {
343 if self.len() == 0 {
344 self
345 } else {
346 let subseq = self.drop_last().filter_index(pred);
347 if pred(self.len() - 1) {
348 subseq.push(self.last())
349 } else {
350 subseq
351 }
352 }
353 }
354
355 broadcast proof fn lemma_filter_index_len(self, pred: spec_fn(int) -> bool)
357 ensures
358 #[trigger] (self.filter_index(pred).len()) <= self.len(),
359 decreases self.len(),
360 {
361 reveal(Seq::filter_index);
362 if self.len() != 0 {
363 self.drop_last().lemma_filter_index_len(pred);
364 }
365 }
366
367 proof fn lemma_filter_index_source(self, pred: spec_fn(int) -> bool)
369 ensures
370 self.filter_index_range(pred),
371 decreases self.len(),
372 {
373 reveal(Seq::filter_index);
374 if self.len() != 0 {
375 let s_rest = self.drop_last();
376 assert(s_rest.len() == self.len() - 1);
377 s_rest.lemma_filter_index_source(pred);
378 let rest = s_rest.filter_index(pred);
379 let result = self.filter_index(pred);
380 let last_idx = (self.len() - 1) as int;
381 assert(forall|k: int| 0 <= k < s_rest.len() ==> #[trigger] s_rest[k] == self[k]);
382
383 if pred(last_idx) {
384 assert(result =~= rest.push(self.last()));
385 } else {
386 assert(result =~= rest);
387 }
388
389 assert forall|i: int| 0 <= i < result.len() implies (exists|j: int|
390 0 <= j < self.len() && #[trigger] result[i] == #[trigger] self[j] && pred(j)) by {
391 if pred(last_idx) && i == rest.len() {
392 assert(result[i] == self[last_idx]);
393 } else {
394 assert(result[i] == rest[i]);
395 let j_rest = choose|j: int|
396 0 <= j < s_rest.len() && rest[i] == s_rest[j] && pred(j);
397 assert(self[j_rest] == s_rest[j_rest]);
398 }
399 }
400 }
401 }
402
403 proof fn lemma_filter_index_witness(self, pred: spec_fn(int) -> bool)
405 ensures
406 self.filter_index_domain(pred),
407 decreases self.len(),
408 {
409 reveal(Seq::filter_index);
410 if self.len() != 0 {
411 let s_rest = self.drop_last();
412 assert(s_rest.len() == self.len() - 1);
413 s_rest.lemma_filter_index_witness(pred);
414 s_rest.lemma_filter_index_len(pred);
415 let rest = s_rest.filter_index(pred);
416 let result = self.filter_index(pred);
417 let last_idx = (self.len() - 1) as int;
418 assert(forall|k: int| 0 <= k < s_rest.len() ==> #[trigger] s_rest[k] == self[k]);
419
420 if pred(last_idx) {
421 assert(result =~= rest.push(self.last()));
422 } else {
423 assert(result =~= rest);
424 }
425
426 s_rest.lemma_filter_index_source(pred);
427 assert forall|i: int| 0 <= i < result.len() implies (exists|j: int|
428 0 <= j < self.len() && #[trigger] result[i] == #[trigger] self[j] && pred(j)) by {
429 if pred(last_idx) && i == rest.len() {
430 assert(result[i] == self[last_idx]);
431 } else {
432 assert(result[i] == rest[i]);
433 let j_rest = choose|j: int|
434 0 <= j < s_rest.len() && rest[i] == s_rest[j] && pred(j);
435 assert(self[j_rest] == s_rest[j_rest]);
436 }
437 }
438
439 assert forall|j: int| 0 <= j < self.len() && pred(j) implies (exists|i: int|
440 0 <= i < self.filter_index(pred).len() && #[trigger] self[j] == self.filter_index(
441 pred,
442 )[i]) by {
443 if j == last_idx {
444 assert(result =~= rest.push(self.last()));
445 assert(self.filter_index(pred)[rest.len() as int] == self[j]);
446 } else {
447 assert(rest.contains(s_rest[j]));
448 let w = choose|i: int| 0 <= i < rest.len() && rest[i] == s_rest[j];
449 assert(self.filter_index(pred)[w] == self[j]);
450 }
451 }
452 }
453 }
454
455 pub open spec fn filter_index_range(self, pred: spec_fn(int) -> bool) -> bool {
457 forall|i|
458 0 <= i < self.filter_index(pred).len() ==> (exists|j|
459 0 <= j < self.len() && #[trigger] self.filter_index(pred)[i] == #[trigger] self[j]
460 && pred(j))
461 }
462
463 pub open spec fn filter_index_domain(self, pred: spec_fn(int) -> bool) -> bool {
465 forall|j|
466 0 <= j < self.len() && pred(j) ==> #[trigger] self.filter_index(pred).contains(self[j])
467 }
468
469 pub broadcast proof fn lemma_filter_index(self, pred: spec_fn(int) -> bool)
471 ensures
472 (#[trigger] self.filter_index(pred)).len() <= self.len(),
475 self.filter_index_range(pred),
477 self.filter_index_domain(pred),
479 decreases self.len(),
480 {
481 self.lemma_filter_index_len(pred);
482 self.lemma_filter_index_source(pred);
483 self.lemma_filter_index_witness(pred);
484 }
485
486 pub proof fn filter_index_ext(self, p: spec_fn(int) -> bool, q: spec_fn(int) -> bool)
489 requires
490 forall|i| 0 <= i < self.len() ==> #[trigger] p(i) == q(i),
491 ensures
492 self.filter_index(p) == self.filter_index(q),
493 decreases self.len(),
494 {
495 reveal(Seq::filter_index);
496 if self.len() != 0 {
497 self.drop_last().filter_index_ext(p, q);
498 }
499 }
500
501 pub proof fn lemma_filter_index_head(self, pred: spec_fn(int) -> bool)
503 requires
504 self.len() > 0,
505 ensures
506 pred(0) ==> self.filter_index(pred) == seq![self[0]] + self.drop_first().filter_index(
507 |i: int| pred(i + 1),
508 ),
509 !pred(0) ==> self.filter_index(pred) == self.drop_first().filter_index(
510 |i: int| pred(i + 1),
511 ),
512 decreases self.len(),
513 {
514 reveal(Seq::filter_index);
515 let p2 = |i: int| pred(i + 1);
516 let t = self.drop_first();
517 if self.len() == 1 {
518 reveal_with_fuel(Seq::filter_index, 2);
519 assert(t.len() == 0);
520 assert(self.drop_last().len() == 0);
521 if pred(0) {
522 assert(self.filter_index(pred) =~= seq![self[0]] + t.filter_index(p2));
523 } else {
524 assert(self.filter_index(pred) =~= t.filter_index(p2));
525 }
526 } else {
527 let sdl = self.drop_last();
528 sdl.lemma_filter_index_head(pred);
529 assert(t.drop_last() =~= sdl.drop_first());
530 let p2b = |i: int| pred(i + 1);
531 sdl.drop_first().filter_index_ext(p2, p2b);
532 if pred(0) {
533 assert(self.filter_index(pred) =~= seq![self[0]] + t.filter_index(p2));
534 } else {
535 assert(self.filter_index(pred) =~= t.filter_index(p2));
536 }
537 }
538 }
539
540 pub broadcast proof fn add_empty_left(a: Self, b: Self)
541 requires
542 a.len() == 0,
543 ensures
544 #[trigger] (a + b) == b,
545 {
546 assert(a + b =~= b);
547 }
548
549 pub broadcast proof fn add_empty_right(a: Self, b: Self)
550 requires
551 b.len() == 0,
552 ensures
553 #[trigger] (a + b) == a,
554 {
555 assert(a + b =~= a);
556 }
557
558 pub broadcast proof fn push_distributes_over_add(a: Self, b: Self, elt: A)
559 ensures
560 #[trigger] (a + b).push(elt) == a + b.push(elt),
561 {
562 assert((a + b).push(elt) =~= a + b.push(elt));
563 }
564
565 pub open spec fn max_via(self, leq: spec_fn(A, A) -> bool) -> A
567 recommends
568 self.len() > 0,
569 decreases self.len(),
570 {
571 if self.len() > 1 {
572 if leq(self[0], self[1..].max_via(leq)) {
573 self[1..].max_via(leq)
574 } else {
575 self[0]
576 }
577 } else {
578 self[0]
579 }
580 }
581
582 pub open spec fn min_via(self, leq: spec_fn(A, A) -> bool) -> A
584 recommends
585 self.len() > 0,
586 decreases self.len(),
587 {
588 if self.len() > 1 {
589 let subseq = self[1..];
590 let elt = subseq.min_via(leq);
591 if leq(elt, self[0]) {
592 elt
593 } else {
594 self[0]
595 }
596 } else {
597 self[0]
598 }
599 }
600
601 pub open spec fn contains(self, needle: A) -> bool {
603 exists|i: int| 0 <= i < self.len() && self[i] == needle
604 }
605
606 pub open spec fn index_of(self, needle: A) -> int {
609 choose|i: int| 0 <= i < self.len() && self[i] == needle
610 }
611
612 pub closed spec fn index_of_first(self, needle: A) -> (result: Option<int>) {
615 if self.contains(needle) {
616 Some(self.first_index_helper(needle))
617 } else {
618 None
619 }
620 }
621
622 spec fn first_index_helper(self, needle: A) -> int
624 recommends
625 self.contains(needle),
626 decreases self.len(),
627 {
628 if self.len() <= 0 {
629 -1 } else if self[0] == needle {
631 0
632 } else {
633 1 + self[1..].first_index_helper(needle)
634 }
635 }
636
637 pub proof fn index_of_first_ensures(self, needle: A)
638 ensures
639 match self.index_of_first(needle) {
640 Some(index) => {
641 &&& self.contains(needle)
642 &&& 0 <= index < self.len()
643 &&& self[index] == needle
644 &&& forall|j: int| 0 <= j < index < self.len() ==> self[j] != needle
645 },
646 None => { !self.contains(needle) },
647 },
648 decreases self.len(),
649 {
650 if self.contains(needle) {
651 let index = self.index_of_first(needle).unwrap();
652 if self.len() <= 0 {
653 } else if self[0] == needle {
654 } else {
655 assert(Seq::empty().push(self.first()).add(self.drop_first()) =~= self);
656 self.drop_first().index_of_first_ensures(needle);
657 }
658 }
659 }
660
661 pub closed spec fn index_of_last(self, needle: A) -> Option<int> {
664 if self.contains(needle) {
665 Some(self.last_index_helper(needle))
666 } else {
667 None
668 }
669 }
670
671 spec fn last_index_helper(self, needle: A) -> int
673 recommends
674 self.contains(needle),
675 decreases self.len(),
676 {
677 if self.len() <= 0 {
678 -1 } else if self.last() == needle {
681 self.len() - 1
682 } else {
683 self.drop_last().last_index_helper(needle)
684 }
685 }
686
687 pub proof fn index_of_last_ensures(self, needle: A)
688 ensures
689 match self.index_of_last(needle) {
690 Some(index) => {
691 &&& self.contains(needle)
692 &&& 0 <= index < self.len()
693 &&& self[index] == needle
694 &&& forall|j: int| 0 <= index < j < self.len() ==> self[j] != needle
695 },
696 None => { !self.contains(needle) },
697 },
698 decreases self.len(),
699 {
700 if self.contains(needle) {
701 let index = self.index_of_last(needle).unwrap();
702 if self.len() <= 0 {
703 } else if self.last() == needle {
704 } else {
705 assert(self.drop_last().push(self.last()) =~= self);
706 self.drop_last().index_of_last_ensures(needle);
707 }
708 }
709 }
710
711 pub open spec fn drop_last(self) -> Seq<A>
716 recommends
717 self.len() >= 1,
718 {
719 self.subrange(0, self.len() as int - 1)
720 }
721
722 pub proof fn drop_last_distributes_over_add(a: Self, b: Self)
725 requires
726 0 < b.len(),
727 ensures
728 (a + b).drop_last() == a + b.drop_last(),
729 {
730 }
731
732 pub open spec fn drop_first(self) -> Seq<A>
733 recommends
734 self.len() >= 1,
735 {
736 self.subrange(1, self.len() as int)
737 }
738
739 pub open spec fn no_duplicates(self) -> bool {
741 forall|i, j| (0 <= i < self.len() && 0 <= j < self.len() && i != j) ==> self[i] != self[j]
742 }
743
744 pub open spec fn disjoint(self, other: Self) -> bool {
746 forall|i: int, j: int| 0 <= i < self.len() && 0 <= j < other.len() ==> self[i] != other[j]
747 }
748
749 pub closed spec fn to_set(self) -> Set<A> {
751 Set::range(0, self.len() as int).map(|i| self.index(i))
752 }
753
754 pub broadcast proof fn to_set_ensures(self)
755 ensures
756 #![trigger(self.to_set())]
757 forall|i|
759 0 <= i < self.len() ==> #[trigger] self.to_set().contains(self[i]),
760 forall|a| #[trigger] self.to_set().contains(a) <==> self.contains(a),
762 {
763 broadcast use super::set::group_set_lemmas;
764 broadcast use super::set_lib::range_set_properties;
765
766 assert forall|i| 0 <= i < self.len() implies #[trigger] self.to_set().contains(self[i]) by {
767 Set::range(0, self.len() as int).lemma_map_contains(|i: int| self.index(i), self[i]);
768 assert(Set::range(0, self.len() as int).contains(i));
769 assert(self.to_set().contains(self[i]));
770 }
771 assert forall|a| #[trigger] self.to_set().contains(a) <==> self.contains(a) by {
772 Set::range(0, self.len() as int).lemma_map_contains(|i: int| self.index(i), a);
773 if self.to_set().contains(a) {
774 let i = choose|i: int| #[trigger]
775 Set::range(0, self.len() as int).contains(i) && self.index(i) == a;
776 assert(0 <= i < self.len());
777 assert(self.contains(a));
778 }
779 if self.contains(a) {
780 let i = choose|i: int| 0 <= i < self.len() && self[i] == a;
781 assert(self.to_set().contains(self[i]));
782 assert(a == self[i]);
783 }
784 }
785 }
786
787 pub open spec fn to_iset(self) -> ISet<A> {
788 self.to_set().to_iset()
789 }
790
791 pub closed spec fn to_multiset(self) -> Multiset<A>
793 decreases self.len(),
794 {
795 if self.len() == 0 {
796 Multiset::<A>::empty()
797 } else {
798 Multiset::<A>::empty().insert(self.first()).add(self.drop_first().to_multiset())
799 }
800 }
801
802 pub broadcast proof fn to_multiset_ensures(self)
806 ensures
807 forall|a: A| #[trigger] (self.push(a).to_multiset()) =~= self.to_multiset().insert(a), forall|i: int|
809 0 <= i < self.len() ==> #[trigger] (self.remove(i).to_multiset())
810 =~= self.to_multiset().remove(self[i]), self.len() == #[trigger] self.to_multiset().len(), forall|a: A|
813 self.contains(a) <==> #[trigger] self.to_multiset().count(a)
814 > 0, {
816 broadcast use group_seq_properties;
817
818 }
819
820 pub open spec fn insert(self, i: int, a: A) -> Seq<A>
822 recommends
823 0 <= i <= self.len(),
824 {
825 self.subrange(0, i).push(a) + self.subrange(i, self.len() as int)
826 }
827
828 pub proof fn insert_ensures(self, pos: int, elt: A)
830 requires
831 0 <= pos <= self.len(),
832 ensures
833 self.insert(pos, elt).len() == self.len() + 1,
834 forall|i: int| 0 <= i < pos ==> #[trigger] self.insert(pos, elt)[i] == self[i],
835 forall|i: int| pos <= i < self.len() ==> self.insert(pos, elt)[i + 1] == self[i],
836 self.insert(pos, elt)[pos] == elt,
837 {
838 }
839
840 pub open spec fn remove(self, i: int) -> Seq<A>
842 recommends
843 0 <= i < self.len(),
844 {
845 self.subrange(0, i) + self.subrange(i + 1, self.len() as int)
846 }
847
848 pub proof fn remove_ensures(self, i: int)
850 requires
851 0 <= i < self.len(),
852 ensures
853 self.remove(i).len() == self.len() - 1,
854 forall|index: int| 0 <= index < i ==> #[trigger] self.remove(i)[index] == self[index],
855 forall|index: int|
856 i <= index < self.len() - 1 ==> #[trigger] self.remove(i)[index] == self[index + 1],
857 {
858 }
859
860 pub open spec fn remove_value(self, val: A) -> Seq<A> {
863 let index = self.index_of_first(val);
864 match index {
865 Some(i) => self.remove(i),
866 None => self,
867 }
868 }
869
870 pub open spec fn reverse(self) -> Seq<A>
872 decreases self.len(),
873 {
874 if self.len() == 0 {
875 Seq::empty()
876 } else {
877 Seq::new(self.len(), |i: int| self[self.len() - 1 - i])
878 }
879 }
880
881 pub open spec fn zip_with<B>(self, other: Seq<B>) -> Seq<(A, B)>
884 recommends
885 self.len() == other.len(),
886 decreases self.len(),
887 {
888 if self.len() != other.len() {
889 Seq::empty()
890 } else if self.len() == 0 {
891 Seq::empty()
892 } else {
893 Seq::new(self.len(), |i: int| (self[i], other[i]))
894 }
895 }
896
897 pub open spec fn zip_truncate<B>(self, other: Seq<B>) -> Seq<(A, B)> {
899 if self.len() == other.len() {
900 self.zip_with(other)
902 } else if self.len() < other.len() {
903 self.zip_with(other[..self.len()])
904 } else {
905 self[..other.len()].zip_with(other)
906 }
907 }
908
909 pub open spec fn fold_left<B>(self, b: B, f: spec_fn(B, A) -> B) -> (res: B)
916 decreases self.len(),
917 {
918 if self.len() == 0 {
919 b
920 } else {
921 f(self.drop_last().fold_left(b, f), self.last())
922 }
923 }
924
925 pub open spec fn fold_left_alt<B>(self, b: B, f: spec_fn(B, A) -> B) -> (res: B)
929 decreases self.len(),
930 {
931 if self.len() == 0 {
932 b
933 } else {
934 self[1..].fold_left_alt(f(b, self[0]), f)
935 }
936 }
937
938 pub broadcast proof fn lemma_fold_left_split<B>(self, b: B, f: spec_fn(B, A) -> B, k: int)
940 requires
941 0 <= k <= self.len(),
942 ensures
943 self[k..].fold_left(
944 (#[trigger] self[..k].fold_left(b, f)),
945 f,
946 ) == self.fold_left(b, f),
947 decreases self.len(),
948 {
949 reveal_with_fuel(Seq::fold_left, 2);
950 if k == self.len() {
951 assert(self[0..] == self);
952 } else {
953 self.drop_last().lemma_fold_left_split(b, f, k);
954 assert(
955 self.drop_last()[k..self.drop_last().len()] =~=
956 self[k..self.len() - 1]
957 );
958 assert(self.drop_last()[..k] =~= self[..k]);
959 assert(self[k..].drop_last() =~= self[k..self.len() - 1]);
960 }
961 }
962
963 proof fn aux_lemma_fold_left_alt<B>(self, b: B, f: spec_fn(B, A) -> B, k: int)
965 requires
966 0 < k <= self.len(),
967 ensures
968 self[k..].fold_left_alt(
969 self[..k].fold_left_alt(b, f),
970 f,
971 ) == 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(
998 self.drop_last().fold_left_alt(b, f),
999 f,
1000 );
1001 self[..self.len() - 1].lemma_fold_left_alt(b, f);
1002 }
1003 }
1004
1005 pub proof fn lemma_reverse_fold_left<B>(self, v: B, f: spec_fn(B, A) -> B)
1008 ensures
1009 self.reverse().fold_left(v, f) == self.fold_right(|a: A, b: B| f(b, a), v),
1010 {
1011 assert(self.reverse().reverse() =~= self);
1012 let g = |a: A, b: B| f(b, a);
1013 assert(f =~= |b: B, a: A| g(a, b));
1014 self.reverse().lemma_reverse_fold_right(v, |a: A, b: B| f(b, a))
1015 }
1016
1017 pub open spec fn fold_right<B>(self, f: spec_fn(A, B) -> B, b: B) -> (res: B)
1024 decreases self.len(),
1025 {
1026 if self.len() == 0 {
1027 b
1028 } else {
1029 self.drop_last().fold_right(f, f(self.last(), b))
1030 }
1031 }
1032
1033 pub open spec fn fold_right_alt<B>(self, f: spec_fn(A, B) -> B, b: B) -> (res: B)
1037 decreases self.len(),
1038 {
1039 if self.len() == 0 {
1040 b
1041 } else {
1042 f(self[0], self[1..].fold_right_alt(f, b))
1043 }
1044 }
1045
1046 pub broadcast proof fn lemma_fold_right_split<B>(self, f: spec_fn(A, B) -> B, b: B, k: int)
1048 requires
1049 0 <= k <= self.len(),
1050 ensures
1051 self[..k].fold_right(
1052 f,
1053 (#[trigger] self[k..].fold_right(f, b)),
1054 ) == self.fold_right(f, b),
1055 decreases self.len(),
1056 {
1057 reveal_with_fuel(Seq::fold_right, 2);
1058 if k == self.len() {
1059 assert(self[..k] == self);
1060 } else if k == self.len() - 1 {
1061 } else {
1063 self[..self.len() - 1].lemma_fold_right_split(f, f(self.last(), b), k);
1064 assert(self[..self.len() - 1][..k] =~= self[..k]);
1065 assert(
1066 self[..self.len() - 1][k..self[..self.len() - 1].len()] =~=
1067 self[k..self.len() - 1]
1068 );
1069 assert(self[k..].drop_last() =~= self[k..self.len() - 1]);
1070 }
1071 }
1072
1073 pub proof fn lemma_fold_right_commute_one<B>(self, a: A, f: spec_fn(A, B) -> B, v: B)
1075 requires
1076 commutative_foldr(f),
1077 ensures
1078 self.fold_right(f, f(a, v)) == f(a, self.fold_right(f, v)),
1079 decreases self.len(),
1080 {
1081 if self.len() > 0 {
1082 self.drop_last().lemma_fold_right_commute_one(a, f, f(self.last(), v));
1083 }
1084 }
1085
1086 pub proof fn lemma_fold_right_alt<B>(self, f: spec_fn(A, B) -> B, b: B)
1088 ensures
1089 self.fold_right(f, b) == self.fold_right_alt(f, b),
1090 decreases self.len(),
1091 {
1092 reveal_with_fuel(Seq::fold_right, 2);
1093 reveal_with_fuel(Seq::fold_right_alt, 2);
1094 if self.len() <= 1 {
1095 } else {
1097 self[1..].lemma_fold_right_alt(f, b);
1098 self.lemma_fold_right_split(f, b, 1);
1099 }
1100 }
1101
1102 pub proof fn lemma_reverse_fold_right<B>(self, v: B, f: spec_fn(A, B) -> B)
1105 ensures
1106 self.reverse().fold_right(f, v) == self.fold_left(v, |b: B, a: A| f(a, b)),
1107 decreases self.len(),
1108 {
1109 let g = |b: B, a: A| f(a, b);
1110 if self.len() > 0 {
1111 let last = self.last();
1112 let s0 = self.drop_last();
1113 assert(self.reverse() =~= seq![last] + s0.reverse());
1114 let res1 = self.reverse().fold_right(f, v);
1115 let res2 = self.fold_left(v, g);
1116 assert(res1 == self.reverse().fold_right_alt(f, v)) by {
1117 self.reverse().lemma_fold_right_alt(f, v)
1118 }
1119 assert(res2 == g(s0.fold_left(v, g), last));
1120 assert(self.reverse().first() == last);
1121 assert(self.reverse()[1..self.reverse().len()] =~= s0.reverse());
1122 assert(res1 == f(last, s0.reverse().fold_right_alt(f, v)));
1123 assert(res1 == f(last, s0.reverse().fold_right(f, v))) by {
1124 s0.reverse().lemma_fold_right_alt(f, v)
1125 }
1126 assert(res2 == g(s0.fold_left(v, g), last));
1127 s0.lemma_reverse_fold_right(v, f);
1128 }
1129 }
1130
1131 pub proof fn lemma_multiset_has_no_duplicates(self)
1135 requires
1136 self.no_duplicates(),
1137 ensures
1138 forall|x: A| self.to_multiset().contains(x) ==> self.to_multiset().count(x) == 1,
1139 decreases self.len(),
1140 {
1141 broadcast use super::multiset::group_multiset_axioms;
1142
1143 if self.len() == 0 {
1144 assert(forall|x: A|
1145 self.to_multiset().contains(x) ==> self.to_multiset().count(x) == 1);
1146 } else {
1147 broadcast use group_seq_properties;
1148
1149 assert(self.drop_last().push(self.last()) =~= self);
1150 self.drop_last().lemma_multiset_has_no_duplicates();
1151 }
1152 }
1153
1154 pub proof fn lemma_multiset_has_no_duplicates_conv(self)
1157 requires
1158 forall|x: A| self.to_multiset().contains(x) ==> self.to_multiset().count(x) == 1,
1159 ensures
1160 self.no_duplicates(),
1161 {
1162 broadcast use super::multiset::group_multiset_axioms;
1163
1164 assert forall|i, j| (0 <= i < self.len() && 0 <= j < self.len() && i != j) implies self[i]
1165 != self[j] by {
1166 let mut a = if (i < j) {
1167 i
1168 } else {
1169 j
1170 };
1171 let mut b = if (i < j) {
1172 j
1173 } else {
1174 i
1175 };
1176
1177 if (self[a] == self[b]) {
1178 let s0 = self[..b];
1179 let s1 = self[b..];
1180 assert(self == s0 + s1);
1181
1182 broadcast use group_to_multiset_ensures;
1183
1184 lemma_multiset_commutative(s0, s1);
1185 assert(self.to_multiset().count(self[a]) >= 2);
1186 }
1187 }
1188 }
1189
1190 pub proof fn lemma_reverse_to_multiset(self)
1192 ensures
1193 self.reverse().to_multiset() =~= self.to_multiset(),
1194 decreases self.len(),
1195 {
1196 broadcast use group_seq_properties;
1197 broadcast use super::multiset::group_multiset_axioms;
1198
1199 if self.len() > 0 {
1200 let s2 = self.drop_first();
1201 let e = self.first();
1202 assert(self =~= seq![e] + s2);
1203 assert(self.to_multiset() =~= seq![e].to_multiset().add(s2.to_multiset())) by {
1204 lemma_multiset_commutative(seq![e], s2)
1205 }
1206 assert(self.reverse() =~= s2.reverse().push(e));
1207 assert(self.reverse().to_multiset() =~= s2.reverse().to_multiset().insert(e));
1208 s2.lemma_reverse_to_multiset();
1209 }
1210 }
1211
1212 pub proof fn lemma_add_last_back(self)
1216 requires
1217 0 < self.len(),
1218 ensures
1219 #[trigger] self.drop_last().push(self.last()) =~= self,
1220 {
1221 }
1222
1223 pub proof fn lemma_indexing_implies_membership(self, f: spec_fn(A) -> bool)
1228 requires
1229 forall|i: int| 0 <= i < self.len() ==> #[trigger] f(#[trigger] self[i]),
1230 ensures
1231 forall|x: A| #[trigger] self.contains(x) ==> #[trigger] f(x),
1232 {
1233 assert(forall|i: int| 0 <= i < self.len() ==> #[trigger] self.contains(self[i]));
1234 }
1235
1236 pub proof fn lemma_membership_implies_indexing(self, f: spec_fn(A) -> bool)
1241 requires
1242 forall|x: A| #[trigger] self.contains(x) ==> #[trigger] f(x),
1243 ensures
1244 forall|i: int| 0 <= i < self.len() ==> #[trigger] f(self[i]),
1245 {
1246 assert forall|i: int| 0 <= i < self.len() implies #[trigger] f(self[i]) by {
1247 assert(self.contains(self[i]));
1248 }
1249 }
1250
1251 pub proof fn lemma_split_at(self, pos: int)
1255 requires
1256 0 <= pos <= self.len(),
1257 ensures
1258 self[..pos] + self[pos..] =~= self,
1259 {
1260 }
1261
1262 pub proof fn lemma_element_from_slice(self, new: Seq<A>, a: int, b: int, pos: int)
1264 requires
1265 0 <= a <= b <= self.len(),
1266 new == self[a..b],
1267 a <= pos < b,
1268 ensures
1269 pos - a < new.len(),
1270 new[pos - a] == self[pos],
1271 {
1272 }
1273
1274 pub proof fn lemma_slice_of_slice(self, s1: int, e1: int, s2: int, e2: int)
1277 requires
1278 0 <= s1 <= e1 <= self.len(),
1279 0 <= s2 <= e2 <= e1 - s1,
1280 ensures
1281 self[s1..e1][s2..e2] =~= self[s1 + s2..s1 + e2],
1282 {
1283 }
1284
1285 pub proof fn unique_seq_to_set(self)
1287 requires
1288 self.no_duplicates(),
1289 ensures
1290 self.len() == self.to_set().len(),
1291 decreases self.len(),
1292 {
1293 broadcast use super::set::group_set_lemmas;
1294
1295 seq_to_set_equal_rec::<A>(self);
1296 if self.len() == 0 {
1297 } else {
1298 let rest = self.drop_last();
1299 rest.unique_seq_to_set();
1300 seq_to_set_equal_rec::<A>(rest);
1301 assert(!rest.contains(self.last()));
1302 assert(!seq_to_set_rec(rest).contains(self.last())) by {
1303 seq_to_set_rec_contains::<A>(rest);
1304 }
1305 assert(seq_to_set_rec(rest).insert(self.last()).len() == seq_to_set_rec(rest).len()
1306 + 1);
1307 }
1308 }
1309
1310 pub proof fn lemma_cardinality_of_set(self)
1313 ensures
1314 self.to_set().len() <= self.len(),
1315 {
1316 broadcast use super::set_lib::range_set_properties;
1317
1318 super::set_lib::lemma_map_size_bound::<int, A>(
1319 Set::range(0, self.len() as int),
1320 self.to_set(),
1321 |i: int| self.index(i),
1322 );
1323 }
1324
1325 pub proof fn lemma_cardinality_of_empty_set_is_0(self)
1328 ensures
1329 self.to_set().len() == 0 <==> self.len() == 0,
1330 {
1331 broadcast use super::set::group_set_lemmas;
1332
1333 self.to_set_ensures();
1334
1335 assert(self.len() == 0 ==> self.to_set().len() == 0) by { self.lemma_cardinality_of_set() }
1336 assert(!(self.len() == 0) ==> !(self.to_set().len() == 0)) by {
1337 if self.len() > 0 {
1338 assert(self.to_set().contains(self[0]));
1339 assert(self.to_set().remove(self[0]).len() <= self.to_set().len());
1340 }
1341 }
1342 }
1343
1344 pub proof fn lemma_no_dup_set_cardinality(self)
1347 requires
1348 self.to_set().len() == self.len(),
1349 ensures
1350 self.no_duplicates(),
1351 decreases self.len(),
1352 {
1353 broadcast use super::set::group_set_lemmas;
1354
1355 self.to_set_ensures();
1356 self.drop_first().to_set_ensures();
1357
1358 if self.len() == 0 {
1359 } else {
1360 assert(self =~= Seq::empty().push(self.first()).add(self.drop_first()));
1361 if self.drop_first().contains(self.first()) {
1362 assert(self.to_set() =~= self.drop_first().to_set());
1364 assert(self.to_set().len() <= self.drop_first().len()) by {
1365 self.drop_first().lemma_cardinality_of_set()
1366 }
1367 } else {
1368 assert(self.to_set().len() == 1 + self.drop_first().to_set().len()) by {
1369 assert(self.drop_first().to_set().insert(self.first()) =~= self.to_set());
1370 }
1371 self.drop_first().lemma_no_dup_set_cardinality();
1372 }
1373 }
1374 }
1375
1376 pub broadcast proof fn lemma_to_set_map_commutes<B>(self, f: spec_fn(A) -> B)
1379 ensures
1380 #[trigger] self.to_set().map(f) =~= self.map_values(f).to_set(),
1381 {
1382 broadcast use crate::vstd::group_vstd_default;
1383
1384 assert forall|elem: B|
1385 self.to_set().map(f).contains(elem) <==> self.map_values(f).to_set().contains(elem) by {
1386 if self.to_set().map(f).contains(elem) {
1387 let x = choose|x: A| self.to_set().contains(x) && f(x) == elem;
1388 let i = choose|i: int| 0 <= i < self.len() && self[i] == x;
1389 assert(self.map_values(f)[i] == elem);
1390 }
1391 if self.map_values(f).to_set().contains(elem) {
1392 let i = choose|i: int|
1393 0 <= i < self.map_values(f).len() && self.map_values(f)[i] == elem;
1394 let x = self[i];
1395 assert(self.to_set().contains(x));
1396 }
1397 };
1398 }
1399
1400 pub broadcast proof fn lemma_to_iset_map_commutes<B>(self, f: spec_fn(A) -> B)
1403 ensures
1404 #[trigger] self.to_iset().map(f) =~= self.map_values(f).to_iset(),
1405 {
1406 broadcast use crate::vstd::group_vstd_default;
1407
1408 assert forall|elem: B|
1409 self.to_iset().map(f).contains(elem) <==> self.map_values(f).to_iset().contains(
1410 elem,
1411 ) by {
1412 if self.to_iset().map(f).contains(elem) {
1413 let x = choose|x: A| self.to_iset().contains(x) && f(x) == elem;
1414 let i = choose|i: int| 0 <= i < self.len() && self[i] == x;
1415 assert(self.map_values(f)[i] == elem);
1416 }
1417 if self.map_values(f).to_iset().contains(elem) {
1418 let i = choose|i: int|
1419 0 <= i < self.map_values(f).len() && self.map_values(f)[i] == elem;
1420 let x = self[i];
1421 assert(self.to_iset().contains(x));
1422 }
1423 };
1424 }
1425
1426 pub broadcast proof fn lemma_to_set_insert_commutes(sq: Seq<A>, elt: A)
1429 ensures
1430 #[trigger] (sq + seq![elt]).to_set() =~= sq.to_set().insert(elt),
1431 {
1432 broadcast use crate::vstd::group_vstd_default;
1433 broadcast use lemma_seq_concat_contains_all_elements;
1434 broadcast use lemma_seq_empty_contains_nothing;
1435 broadcast use lemma_seq_contains_after_push;
1436 broadcast use super::seq::group_seq_lemmas;
1437 broadcast use super::set_lib::group_set_properties;
1438
1439 }
1440
1441 pub broadcast proof fn lemma_to_iset_insert_commutes(sq: Seq<A>, elt: A)
1444 ensures
1445 #[trigger] (sq + seq![elt]).to_iset() =~= sq.to_iset().insert(elt),
1446 {
1447 broadcast use crate::vstd::group_vstd_default;
1448 broadcast use lemma_seq_concat_contains_all_elements;
1449 broadcast use lemma_seq_empty_contains_nothing;
1450 broadcast use lemma_seq_contains_after_push;
1451 broadcast use super::seq::group_seq_lemmas;
1452 broadcast use super::set_lib::group_set_properties;
1453
1454 }
1455
1456 pub open spec fn update_subrange_with(self, off: int, vs: Self) -> Self
1460 recommends
1461 0 <= off,
1462 off + vs.len() <= self.len(),
1463 {
1464 Seq::new(
1465 self.len(),
1466 |i: int|
1467 if off <= i < off + vs.len() {
1468 vs[i - off]
1469 } else {
1470 self[i]
1471 },
1472 )
1473 }
1474
1475 pub broadcast proof fn lemma_seq_skip_skip(self, i: int)
1487 ensures
1488 0 <= i < self.len() ==> self[i..][1..] =~= #[trigger] self[i + 1..],
1489 {
1490 broadcast use group_seq_properties;
1491
1492 }
1493
1494 pub proof fn lemma_contains_to_index(self, elem: A) -> (idx: int)
1507 requires
1508 self.contains(elem),
1509 ensures
1510 0 <= idx < self.len() && self[idx] == elem,
1511 decreases self.len(),
1512 {
1513 broadcast use group_seq_properties;
1514
1515 if self[0] == elem {
1516 0
1517 } else {
1518 let i = self[1..].lemma_contains_to_index(elem);
1519 i + 1
1520 }
1521 }
1522
1523 pub proof fn lemma_all_from_head_tail(self, pred: spec_fn(A) -> bool)
1539 requires
1540 self.len() > 0,
1541 pred(self[0]) && self[1..].all(|x| pred(x)),
1542 ensures
1543 self.all(|x| pred(x)),
1544 {
1545 broadcast use group_seq_properties;
1546
1547 assert(seq![self[0]] + self[1..] == self);
1548 }
1549
1550 pub proof fn lemma_any_tail(self, pred: spec_fn(A) -> bool)
1566 requires
1567 self.any(|x| pred(x)),
1568 ensures
1569 !pred(self[0]) ==> self[1..].any(|x| pred(x)),
1570 {
1571 broadcast use group_seq_properties;
1572
1573 }
1574
1575 pub open spec fn remove_duplicates(self, seen: Seq<A>) -> Seq<A>
1593 decreases self.len(),
1594 {
1595 if self.len() == 0 {
1596 seen
1597 } else if seen.contains(self[0]) {
1598 self[1..].remove_duplicates(seen)
1599 } else {
1600 self[1..].remove_duplicates(seen + seq![self[0]])
1601 }
1602 }
1603
1604 pub broadcast proof fn lemma_remove_duplicates_properties(self, seen: Seq<A>)
1622 ensures
1623 forall|x|
1624 (self + seen).contains(x) <==> #[trigger] self.remove_duplicates(seen).contains(x),
1625 #[trigger] self.remove_duplicates(seen).len() <= self.len() + seen.len(),
1626 decreases self.len(),
1627 {
1628 broadcast use group_seq_properties;
1629
1630 if self.len() == 0 {
1631 } else if seen.contains(self[0]) {
1632 let rest = self[1..];
1633 rest.lemma_remove_duplicates_properties(seen);
1634 } else {
1635 let rest = self[1..];
1636 rest.lemma_remove_duplicates_properties(seen + seq![self[0]]);
1637 }
1638 }
1639
1640 pub proof fn lemma_remove_duplicates_append_index(self, i: int, seen: Seq<A>)
1656 requires
1657 0 <= i < self.len(),
1658 ensures
1659 self.remove_duplicates(seen) == self[i..].remove_duplicates(
1660 self[..i].remove_duplicates(seen),
1661 ),
1662 decreases self.len(),
1663 {
1664 broadcast use {
1665 group_seq_properties,
1666 lemma_seq_skip_of_skip,
1667 Seq::lemma_remove_duplicates_properties,
1668 };
1669
1670 if i == 0 {
1671 } else if i == self.len() {
1672 assert(self[..i] == self);
1673 } else {
1674 assert(self[1..][..i - 1] == self[1..i]);
1675 assert(self[..i][1..] == self[1..i]);
1676 assert(self[1..][..i - 1] == self[..i][1..]);
1677 if seen.contains(self[0]) {
1678 self[1..].lemma_remove_duplicates_append_index(i - 1, seen);
1679 } else {
1680 self[1..].lemma_remove_duplicates_append_index(i - 1, seen + seq![self[0]]);
1681 }
1682 }
1683 }
1684
1685 proof fn lemma_skip1_concat(xs: Seq<A>, ys: Seq<A>)
1700 requires
1701 xs.len() > 0,
1702 ensures
1703 (xs + ys)[1..] == xs[1..] + ys,
1704 {
1705 broadcast use group_seq_properties;
1706
1707 assert((xs + ys)[1..] == xs[1..] + ys);
1708 }
1709
1710 pub proof fn lemma_remove_duplicates_append(self, x: A, seen: Seq<A>)
1726 ensures
1727 (self + seen).contains(x) ==> (self + seq![x]).remove_duplicates(seen)
1728 == self.remove_duplicates(seen),
1729 !(self + seen).contains(x) ==> (self + seq![x]).remove_duplicates(seen)
1730 == self.remove_duplicates(seen) + seq![x],
1731 decreases self.len(),
1732 {
1733 broadcast use group_seq_properties;
1734
1735 reveal_with_fuel(Seq::remove_duplicates, 2);
1736
1737 if self.len() != 0 {
1738 let head = self[0];
1739 let tail = self[1..];
1740
1741 let seen2 = if seen.contains(head) {
1742 seen
1743 } else {
1744 seen + seq![head]
1745 };
1746 tail.lemma_remove_duplicates_append(x, seen2);
1747 assert((self + seq![x])[1..] == tail + seq![x]) by {
1748 Seq::lemma_skip1_concat(self, seq![x]);
1749 };
1750 }
1751 }
1752
1753 pub proof fn lemma_all_neg_filter_empty(self, pred: spec_fn(A) -> bool)
1766 requires
1767 self.all(|x: A| !pred(x)),
1768 ensures
1769 self.filter(pred).len() == 0,
1770 decreases self.len(),
1771 {
1772 broadcast use group_seq_properties;
1773
1774 reveal(Seq::filter);
1775 if self.len() != 0 {
1776 let rest = self.drop_last();
1777 rest.lemma_all_neg_filter_empty(pred);
1778 rest.lemma_filter_len_push(pred, self.last());
1779 let neg_pred = |x| !pred(x);
1780 assert(neg_pred(self.last()));
1781 }
1782 }
1783
1784 pub open spec fn filter_map<B>(self, f: spec_fn(A) -> Option<B>) -> Seq<B>
1793 decreases self.len(),
1794 {
1795 if self.len() == 0 {
1799 Seq::empty()
1800 } else {
1801 let rest = self.drop_last();
1802 match f(self.last()) {
1803 Option::Some(s) => rest.filter_map(f) + seq![s],
1804 Option::None => rest.filter_map(f),
1805 }
1806 }
1807 }
1808
1809 pub broadcast proof fn lemma_filter_contains_rev(self, p: spec_fn(A) -> bool, elem: A)
1813 requires
1814 #[trigger] self.filter(p).contains(elem),
1815 ensures
1816 self.contains(elem),
1817 decreases self.len(),
1818 {
1819 broadcast use group_seq_properties;
1820
1821 reveal(Seq::filter);
1822 if self.len() == 0 {
1823 } else {
1824 let rest = self.drop_last();
1825 let last = self.last();
1826 if !p(last) || last != elem {
1827 rest.lemma_filter_contains_rev(p, elem);
1828 }
1829 }
1830 }
1831
1832 pub broadcast proof fn lemma_filter_map_contains<B>(self, f: spec_fn(A) -> Option<B>, elt: B)
1836 requires
1837 #[trigger] self.filter_map(f).contains(elt),
1838 ensures
1839 exists|t: A| #[trigger] self.contains(t) && f(t) == Some(elt),
1840 decreases self.len(),
1841 {
1842 broadcast use group_seq_properties;
1843
1844 if self.len() == 0 {
1845 } else {
1846 let last = self.last();
1847 let rest = self.drop_last();
1848 if f(last) == Some(elt) {
1849 assert(self.contains(last));
1850 } else {
1851 rest.lemma_filter_map_contains(f, elt);
1852 let t = choose|t: A| #[trigger] rest.contains(t) && f(t) == Some(elt);
1853 assert(self.contains(t));
1854 }
1855 }
1856 }
1857
1858 pub proof fn lemma_take_succ(xs: Seq<A>, k: int)
1867 requires
1868 0 <= k < xs.len(),
1869 ensures
1870 xs[..k + 1] =~= xs[..k] + seq![xs[k]],
1871 {
1872 broadcast use group_seq_properties;
1873
1874 }
1875
1876 pub proof fn lemma_filter_map_singleton<B>(a: A, f: spec_fn(A) -> Option<B>)
1880 ensures
1881 seq![a].filter_map(f) =~= match f(a) {
1882 Option::Some(b) => seq![b],
1883 Option::None => Seq::empty(),
1884 },
1885 {
1886 reveal_with_fuel(Seq::filter_map, 2);
1887 }
1888
1889 pub broadcast proof fn lemma_filter_map_take_succ<B>(self, f: spec_fn(A) -> Option<B>, i: int)
1901 requires
1902 0 <= i < self.len(),
1903 ensures
1904 #[trigger] self[..i + 1].filter_map(f) =~= self[..i].filter_map(f) + (match f(
1905 self[i],
1906 ) {
1907 Option::Some(s) => seq![s],
1908 Option::None => Seq::empty(),
1909 }),
1910 decreases self.len(),
1911 {
1912 broadcast use group_seq_properties;
1913
1914 if i != 0 {
1915 self.drop_last().lemma_filter_map_take_succ(f, i - 1);
1916 assert(self[..i + 1].drop_last() == self[..i]);
1917 }
1918 }
1919
1920 pub open spec fn filter_alt(self, p: spec_fn(A) -> bool) -> Seq<A> {
1923 if self.len() == 0 {
1924 Seq::empty()
1925 } else {
1926 let rest = self.drop_first().filter(p);
1927 let first = self.first();
1928 if p(first) {
1929 seq![first] + rest
1930 } else {
1931 rest
1932 }
1933 }
1934 }
1935
1936 pub broadcast proof fn lemma_filter_prepend(self, x: A, p: spec_fn(A) -> bool)
1951 ensures
1952 #[trigger] (seq![x] + self).filter(p) == (if p(x) {
1953 seq![x]
1954 } else {
1955 Seq::empty()
1956 }) + self.filter(p),
1957 decreases self.len(),
1958 {
1959 broadcast use group_seq_properties;
1960
1961 reveal(Seq::filter);
1962 let lhs = (seq![x] + self).filter(p);
1963 let rhs = (if p(x) {
1964 seq![x]
1965 } else {
1966 Seq::empty()
1967 }) + self.filter(p);
1968
1969 if self.len() == 0 {
1970 assert(lhs =~= rhs);
1971 } else {
1972 let tail_seq = if p(self.last()) {
1973 seq![self.last()]
1974 } else {
1975 Seq::empty()
1976 };
1977
1978 assert(((seq![x] + self).drop_last()) =~= seq![x] + self.drop_last());
1979 let sub = (seq![x] + self.drop_last()).filter(p);
1980 assert(lhs =~= sub + tail_seq);
1981 assert(rhs =~= (if p(x) {
1982 seq![x]
1983 } else {
1984 Seq::empty()
1985 }) + self.drop_last().filter(p) + tail_seq);
1986 self.drop_last().lemma_filter_prepend(x, p);
1987 }
1988 }
1989
1990 pub proof fn lemma_filter_eq_filter_alt(self, p: spec_fn(A) -> bool)
1992 ensures
1993 self.filter(p) =~= self.filter_alt(p),
1994 decreases self.len(),
1995 {
1996 broadcast use group_seq_properties;
1997 broadcast use Seq::lemma_filter_prepend;
1998
1999 reveal(Seq::filter);
2000 if self.len() == 0 {
2001 } else {
2002 let first = self.first();
2003 let but_first = self.drop_first();
2004 assert(self =~= seq![first] + but_first);
2005 self.drop_first().lemma_filter_eq_filter_alt(p);
2006 }
2007 }
2008
2009 pub proof fn lemma_filter_monotone(self, ys: Seq<A>, p: spec_fn(A) -> bool)
2024 requires
2025 self.is_prefix_of(ys),
2026 ensures
2027 self.filter(p).is_prefix_of(ys.filter(p)),
2028 decreases self.len(),
2029 {
2030 broadcast use group_seq_properties;
2031
2032 self.lemma_filter_eq_filter_alt(p);
2033 ys.lemma_filter_eq_filter_alt(p);
2034 if self.len() == 0 {
2035 } else {
2036 self.drop_first().lemma_filter_monotone(ys.drop_first(), p);
2037 }
2038 }
2039
2040 pub proof fn lemma_filter_take_len(self, p: spec_fn(A) -> bool, i: int)
2055 requires
2056 0 <= i <= self.len(),
2057 ensures
2058 self.filter(p).len() >= self[..i].filter(p).len(),
2059 decreases i,
2060 {
2061 broadcast use group_seq_properties;
2062 broadcast use Seq::lemma_filter_len_push;
2063 broadcast use Seq::lemma_filter_push;
2064
2065 self[..i].lemma_filter_monotone(self, p);
2066 }
2067
2068 pub broadcast proof fn lemma_filter_len_push(self, p: spec_fn(A) -> bool, elem: A)
2080 ensures
2081 #[trigger] self.push(elem).filter(p).len() == self.filter(p).len() + (if p(elem) {
2082 1int
2083 } else {
2084 0int
2085 }),
2086 {
2087 broadcast use group_seq_properties;
2088 broadcast use Seq::lemma_filter_push;
2089
2090 }
2091
2092 pub broadcast proof fn lemma_index_contains(self, i: int)
2095 requires
2096 0 <= i < self.len(),
2097 ensures
2098 self.contains(#[trigger] self[i]),
2099 {
2100 }
2101
2102 pub broadcast proof fn lemma_take_succ_push(self, i: int)
2105 requires
2106 0 <= i < self.len(),
2107 ensures
2108 #[trigger] self[..i + 1] =~= self[..i].push(self[i]),
2109 {
2110 broadcast use group_seq_properties;
2111
2112 }
2113
2114 pub broadcast proof fn lemma_take_len(self)
2116 ensures
2117 #[trigger] self[..self.len()] == self,
2118 {
2119 broadcast use group_seq_properties;
2120
2121 }
2122
2123 pub broadcast proof fn lemma_take_any_succ(self, p: spec_fn(A) -> bool, i: int)
2136 requires
2137 0 <= i < self.len(),
2138 ensures
2139 #[trigger] self[..i + 1].any(p) <==> self[..i].any(p) || p(self[i]),
2140 {
2141 broadcast use group_seq_properties;
2142
2143 self.lemma_take_succ_push(i);
2144 if self[..i + 1].any(p) {
2145 let x = choose|x: A| self[..i + 1].contains(x) && #[trigger] p(x);
2146 assert(self[..i].contains(x) || x == self[i]);
2147 }
2148 if self[..i].any(p) {
2149 let x = choose|x: A| self[..i].contains(x) && #[trigger] p(x);
2150 assert(self[..i + 1].contains(x));
2151 }
2152 if p(self[i]) {
2153 assert(self[..i + 1].contains(self[i]));
2154 }
2155 }
2156
2157 pub proof fn lemma_no_duplicates_injective<B>(self, f: spec_fn(A) -> B)
2169 requires
2170 injective(f),
2171 ensures
2172 self.no_duplicates() <==> self.map_values(f).no_duplicates(),
2173 {
2174 broadcast use group_seq_properties;
2175 broadcast use super::set_lib::group_set_properties;
2176
2177 let mapped = self.map_values(f);
2178 assert(mapped.len() == self.len());
2179 if mapped.no_duplicates() {
2180 assert forall|i: int, j: int| 0 <= i < j < mapped.len() implies self[i] != self[j] by {
2181 assert(mapped[i] == f(self[i]));
2182 assert(mapped[j] == f(self[j]));
2183 }
2184 }
2185 }
2186
2187 pub broadcast proof fn lemma_push_map_commute<B>(self, f: spec_fn(A) -> B, x: A)
2199 ensures
2200 self.map_values(f).push(f(x)) =~= #[trigger] self.push(x).map_values(f),
2201 decreases self.len(),
2202 {
2203 broadcast use group_seq_properties;
2204
2205 }
2206
2207 pub broadcast proof fn lemma_push_to_set_commute(self, elem: A)
2218 ensures
2219 #[trigger] self.push(elem).to_set() =~= self.to_set().insert(elem),
2220 {
2221 broadcast use {group_seq_properties, super::set::group_set_lemmas, Seq::to_set_ensures};
2222
2223 let lhs = self.push(elem).to_set();
2224 let rhs = self.to_set().insert(elem);
2225 assert forall|x: A| rhs.contains(x) implies lhs.contains(x) by {
2226 lemma_seq_contains_after_push(self, elem, x);
2227 }
2228 }
2229
2230 pub broadcast proof fn lemma_filter_push(self, elem: A, pred: spec_fn(A) -> bool)
2244 ensures
2245 #[trigger] self.push(elem).filter(pred) == if pred(elem) {
2246 self.filter(pred).push(elem)
2247 } else {
2248 self.filter(pred)
2249 },
2250 {
2251 broadcast use group_seq_properties;
2252
2253 reveal(Seq::filter);
2254 assert(self.push(elem).drop_last() =~= self);
2255 }
2256
2257 pub proof fn lemma_zip_with_contains_index<B>(self, b: Seq<B>, i: int)
2270 requires
2271 0 <= i < self.len(),
2272 self.len() == b.len(),
2273 ensures
2274 self.zip_with(b).contains((self[i], b[i])),
2275 {
2276 assert(self.zip_with(b)[i] == (self[i], b[i]));
2277 }
2278
2279 pub proof fn lemma_zip_with_uncurry_all<B>(self, b: Seq<B>, f: spec_fn(A, B) -> bool)
2296 requires
2297 self.len() == b.len(),
2298 ensures
2299 self.zip_with(b).all(|p: (A, B)| f(p.0, p.1)) <==> forall|i: int|
2300 0 <= i < self.len() ==> f(self[i], b[i]),
2301 {
2302 broadcast use group_seq_properties;
2303
2304 let zipped = self.zip_with(b);
2305 let f_uncurr = |p: (A, B)| f(p.0, p.1);
2306 let lhs = zipped.all(f_uncurr);
2307 let rhs = (forall|i: int| 0 <= i < self.len() ==> f(self[i], b[i]));
2308 if lhs {
2309 assert forall|i: int| 0 <= i < self.len() implies f(self[i], b[i]) by {
2310 self.lemma_zip_with_contains_index(b, i);
2311 assert(forall|j| 0 <= j < zipped.len() ==> f_uncurr(zipped[j]));
2312 }
2313 }
2314 }
2315
2316 pub proof fn lemma_flat_map_push<B>(self, f: spec_fn(A) -> Seq<B>, elem: A)
2330 ensures
2331 self.push(elem).flat_map(f) =~= self.flat_map(f) + f(elem),
2332 decreases self.len(),
2333 {
2334 broadcast use group_seq_properties;
2335 broadcast use Seq::lemma_flatten_push;
2336 broadcast use Seq::lemma_push_map_commute;
2337
2338 }
2339
2340 pub broadcast proof fn lemma_flat_map_take_append<B>(self, f: spec_fn(A) -> Seq<B>, i: int)
2355 requires
2356 0 <= i < self.len(),
2357 ensures
2358 #[trigger] self[..i + 1].flat_map(f) =~= self[..i].flat_map(f) + f(self[i]),
2359 decreases i,
2360 {
2361 broadcast use group_seq_properties;
2362
2363 self.lemma_take_succ_push(i);
2364 self[..i].lemma_flat_map_push(f, self[i]);
2365 }
2366
2367 pub broadcast proof fn lemma_flat_map_singleton<B>(self, f: spec_fn(A) -> Seq<B>)
2370 requires
2371 #[trigger] self.len() == 1,
2372 ensures
2373 #[trigger] self.flat_map(f) == f(self[0]),
2374 {
2375 broadcast use Seq::lemma_flatten_singleton;
2376
2377 }
2378
2379 pub broadcast proof fn lemma_map_take_succ<B>(self, f: spec_fn(A) -> B, i: int)
2394 requires
2395 0 <= i < self.len(),
2396 ensures
2397 #[trigger] self[..i + 1].map_values(f) =~= self[..i].map_values(f).push(
2398 f(self[i]),
2399 ),
2400 {
2401 broadcast use group_seq_properties;
2402
2403 self.lemma_take_succ_push(i);
2404 }
2405
2406 pub broadcast proof fn lemma_prefix_index_eq(self, prefix: Seq<A>)
2419 requires
2420 #[trigger] prefix.is_prefix_of(self),
2421 ensures
2422 forall|i: int| 0 <= i < prefix.len() ==> prefix[i] == self[i],
2423 {
2424 }
2425
2426 pub broadcast proof fn lemma_prefix_concat(self, prefix1: Seq<A>, prefix2: Seq<A>)
2440 requires
2441 #[trigger] (prefix1 + prefix2).is_prefix_of(self),
2442 ensures
2443 prefix1.is_prefix_of(self),
2444 {
2445 broadcast use Seq::lemma_prefix_index_eq;
2446
2447 }
2448
2449 pub broadcast proof fn lemma_prefix_chain_contains(self, prefix1: Seq<A>, prefix2: Seq<A>, t: A)
2470 requires
2471 #[trigger] (prefix1 + seq![t]).is_prefix_of(self),
2472 #[trigger] prefix1.is_prefix_of(prefix2),
2473 prefix2.is_prefix_of(self),
2474 prefix1 != prefix2,
2475 !prefix1.contains(t),
2476 ensures
2477 prefix2.contains(t),
2478 {
2479 broadcast use Seq::lemma_prefix_concat;
2480 broadcast use Seq::lemma_prefix_index_eq;
2481
2482 assert(prefix2[prefix1.len() as int] == t);
2483 }
2484
2485 pub broadcast proof fn lemma_prefix_append_unique(self, prefix1: Seq<A>, prefix2: Seq<A>, t: A)
2489 requires
2490 #[trigger] (prefix1 + seq![t]).is_prefix_of(self),
2491 #[trigger] (prefix2 + seq![t]).is_prefix_of(self),
2492 !prefix1.contains(t),
2493 !prefix2.contains(t),
2494 ensures
2495 prefix1 == prefix2,
2496 {
2497 broadcast use Seq::lemma_prefix_concat;
2498 broadcast use Seq::lemma_prefix_index_eq;
2499 broadcast use Seq::lemma_prefix_chain_contains;
2500
2501 if prefix1 != prefix2 {
2502 assert(prefix1.is_prefix_of(prefix2) || prefix2.is_prefix_of(prefix1));
2503 }
2504 }
2505
2506 pub broadcast proof fn lemma_all_push(self, p: spec_fn(A) -> bool, elem: A)
2521 requires
2522 self.all(p),
2523 p(elem),
2524 ensures
2525 #[trigger] self.push(elem).all(p),
2526 {
2527 broadcast use group_seq_properties;
2528
2529 assert forall|x: A| self.push(elem).contains(x) implies p(x) by {
2530 lemma_seq_contains_after_push(self, elem, x);
2531 }
2532 }
2533
2534 pub proof fn lemma_concat_injective(self, s1: Seq<A>, s2: Seq<A>)
2537 ensures
2538 (self + s1 == self + s2) <==> (s1 == s2),
2539 {
2540 broadcast use group_seq_properties;
2541
2542 assert((self + s1)[self.len()..] == s1);
2543 }
2544
2545 pub broadcast group group_seq_extra {
2546 Seq::<_>::lemma_seq_skip_skip,
2547 Seq::<_>::lemma_remove_duplicates_properties,
2548 Seq::<_>::lemma_filter_contains_rev,
2549 Seq::<_>::lemma_filter_map_take_succ,
2550 Seq::<_>::lemma_filter_prepend,
2551 Seq::<_>::lemma_filter_len_push,
2552 Seq::<_>::lemma_take_len,
2553 Seq::<_>::lemma_take_any_succ,
2554 Seq::<_>::lemma_push_map_commute,
2555 Seq::<_>::lemma_push_to_set_commute,
2556 Seq::<_>::lemma_filter_push,
2557 Seq::<_>::lemma_flat_map_take_append,
2558 Seq::<_>::lemma_flat_map_singleton,
2559 Seq::<_>::lemma_map_take_succ,
2560 Seq::<_>::lemma_prefix_index_eq,
2561 Seq::<_>::lemma_prefix_concat,
2562 Seq::<_>::lemma_prefix_chain_contains,
2563 Seq::<_>::lemma_prefix_append_unique,
2564 Seq::<_>::lemma_all_push,
2565 }
2566}
2567
2568impl<A> Seq<&A> {
2569 pub open spec fn unref(self) -> Seq<A> {
2571 Seq::new(self.len(), |i: int| *self[i])
2572 }
2573}
2574
2575impl<A, B> Seq<(&A, &B)> {
2576 pub open spec fn unref(self) -> Seq<(A, B)> {
2578 Seq::new(self.len(), |i: int| (*self[i].0, *self[i].1))
2579 }
2580}
2581
2582pub proof fn lemma_filter_view_commute<S: View>(
2599 s: Seq<S>,
2600 p: spec_fn(S) -> bool,
2601 sp: spec_fn(S::V) -> bool,
2602)
2603 requires
2604 forall|s: S| p(s) <==> sp(s.view()),
2605 ensures
2606 s.filter(p).map_values(|x: S| x.view()) == s.map_values(|x: S| x.view()).filter(sp),
2607 decreases s.len(),
2608{
2609 broadcast use group_seq_properties;
2610 broadcast use Seq::lemma_push_map_commute;
2611 broadcast use Seq::lemma_filter_push;
2612
2613 reveal(Seq::filter);
2614 let view = |x: S| x.view();
2615 if s.len() > 0 {
2616 let rest = s.drop_last();
2617 let last = s.last();
2618 assert(s =~= rest.push(last));
2619 assert(s.map_values(view).last() == view(last));
2620 lemma_filter_view_commute(rest, p, sp);
2621 }
2622}
2623
2624pub proof fn lemma_exactly_one_view<S: View>(
2639 s: Seq<S>,
2640 p: spec_fn(S) -> bool,
2641 sp: spec_fn(S::V) -> bool,
2642)
2643 requires
2644 forall|s: S| p(s) <==> sp(s.view()),
2645 injective(|x: S| x.view()),
2646 ensures
2647 s.exactly_one(p) <==> s.map_values(|x: S| x.view()).exactly_one(sp),
2648{
2649 lemma_filter_view_commute(s, p, sp);
2650}
2651
2652impl<A, B> Seq<(A, B)> {
2653 pub closed spec fn unzip(self) -> (Seq<A>, Seq<B>) {
2655 (Seq::new(self.len(), |i: int| self[i].0), Seq::new(self.len(), |i: int| self[i].1))
2656 }
2657
2658 pub proof fn unzip_ensures(self)
2660 ensures
2661 self.unzip().0.len() == self.unzip().1.len(),
2662 self.unzip().0.len() == self.len(),
2663 self.unzip().1.len() == self.len(),
2664 forall|i: int|
2665 0 <= i < self.len() ==> (#[trigger] self.unzip().0[i], #[trigger] self.unzip().1[i])
2666 == self[i],
2667 decreases self.len(),
2668 {
2669 if self.len() > 0 {
2670 self.drop_last().unzip_ensures();
2671 }
2672 }
2673
2674 pub proof fn lemma_zip_of_unzip(self)
2677 ensures
2678 self.unzip().0.zip_with(self.unzip().1) =~= self,
2679 {
2680 }
2681}
2682
2683impl<A> Seq<Seq<A>> {
2684 pub open spec fn flatten(self) -> Seq<A>
2698 decreases self.len(),
2699 {
2700 if self.len() == 0 {
2701 Seq::empty()
2702 } else {
2703 self.first().add(self.drop_first().flatten())
2704 }
2705 }
2706
2707 pub open spec fn flatten_alt(self) -> Seq<A>
2712 decreases self.len(),
2713 {
2714 if self.len() == 0 {
2715 Seq::empty()
2716 } else {
2717 self.drop_last().flatten_alt().add(self.last())
2718 }
2719 }
2720
2721 pub proof fn lemma_flatten_one_element(self)
2724 ensures
2725 self.len() == 1 ==> self.flatten() == self.first(),
2726 {
2727 broadcast use Seq::add_empty_right;
2728
2729 if self.len() == 1 {
2730 assert(self.flatten() =~= self.first().add(self.drop_first().flatten()));
2731 }
2732 }
2733
2734 pub proof fn lemma_flatten_length_ge_single_element_length(self, i: int)
2737 requires
2738 0 <= i < self.len(),
2739 ensures
2740 self.flatten_alt().len() >= self[i].len(),
2741 decreases self.len(),
2742 {
2743 if self.len() == 1 {
2744 self.lemma_flatten_one_element();
2745 self.lemma_flatten_and_flatten_alt_are_equivalent();
2746 } else if i < self.len() - 1 {
2747 self.drop_last().lemma_flatten_length_ge_single_element_length(i);
2748 } else {
2749 assert(self.flatten_alt() == self.drop_last().flatten_alt().add(self.last()));
2750 }
2751 }
2752
2753 pub proof fn lemma_flatten_length_le_mul(self, j: int)
2757 requires
2758 forall|i: int| 0 <= i < self.len() ==> (#[trigger] self[i]).len() <= j,
2759 ensures
2760 self.flatten_alt().len() <= self.len() * j,
2761 decreases self.len(),
2762 {
2763 broadcast use group_seq_properties;
2764
2765 if self.len() == 0 {
2766 } else {
2767 self.drop_last().lemma_flatten_length_le_mul(j);
2768 assert((self.len() - 1) * j == (self.len() * j) - (1 * j)) by (nonlinear_arith); }
2770 }
2771
2772 pub proof fn lemma_flatten_and_flatten_alt_are_equivalent(self)
2775 ensures
2776 self.flatten() =~= self.flatten_alt(),
2777 decreases self.len(),
2778 {
2779 broadcast use {Seq::add_empty_right, Seq::push_distributes_over_add};
2780
2781 if self.len() != 0 {
2782 self.drop_last().lemma_flatten_and_flatten_alt_are_equivalent();
2783 seq![self.last()].lemma_flatten_one_element();
2787 assert(seq![self.last()].flatten() == self.last());
2788 lemma_flatten_concat(self.drop_last(), seq![self.last()]);
2789 assert((self.drop_last() + seq![self.last()]).flatten() == self.drop_last().flatten()
2790 + self.last());
2791 assert(self.drop_last() + seq![self.last()] =~= self);
2792 assert(self.flatten_alt() == self.drop_last().flatten_alt() + self.last());
2793 }
2794 }
2795
2796 pub broadcast proof fn lemma_flatten_push(self, elem: Seq<A>)
2799 ensures
2800 #[trigger] self.push(elem).flatten() =~= self.flatten() + elem,
2801 decreases self.len(),
2802 {
2803 broadcast use group_seq_properties;
2804
2805 assert(self.push(elem).last() == elem);
2806 assert(self.push(elem).drop_last() =~= self);
2807 calc! {
2808 (==)
2809 self.push(elem).flatten(); {
2810 self.push(elem).lemma_flatten_and_flatten_alt_are_equivalent();
2811 }
2812 self.push(elem).flatten_alt(); {}
2813 self.flatten_alt() + elem; {
2814 self.lemma_flatten_and_flatten_alt_are_equivalent();
2815 }
2816 self.flatten() + elem;
2817 }
2818 }
2819
2820 pub broadcast proof fn lemma_flatten_singleton(self)
2822 requires
2823 #[trigger] self.len() == 1,
2824 ensures
2825 #[trigger] self.flatten() == self[0],
2826 {
2827 assert(self.flatten() == self[0] + self.drop_first().flatten());
2828 assert(self.flatten() == self[0]);
2829 }
2830
2831 pub broadcast group group_seq_flatten {
2832 Seq::<_>::lemma_flatten_push,
2833 Seq::<_>::lemma_flatten_singleton,
2834 }
2835}
2836
2837impl Seq<int> {
2840 pub open spec fn max(self) -> int
2842 recommends
2843 0 < self.len(),
2844 decreases self.len(),
2845 {
2846 if self.len() == 1 {
2847 self[0]
2848 } else if self.len() == 0 {
2849 0
2850 } else {
2851 let later_max = self.drop_first().max();
2852 if self[0] >= later_max {
2853 self[0]
2854 } else {
2855 later_max
2856 }
2857 }
2858 }
2859
2860 pub proof fn max_ensures(self)
2862 ensures
2863 forall|x: int| self.contains(x) ==> x <= self.max(),
2864 forall|i: int| 0 <= i < self.len() ==> self[i] <= self.max(),
2865 self.len() == 0 || self.contains(self.max()),
2866 decreases self.len(),
2867 {
2868 if self.len() <= 1 {
2869 } else {
2870 let elt = self.drop_first().max();
2871 assert(self.drop_first().contains(elt)) by { self.drop_first().max_ensures() }
2872 assert forall|i: int| 0 <= i < self.len() implies self[i] <= self.max() by {
2873 assert(i == 0 || self[i] == self.drop_first()[i - 1]);
2874 assert(forall|j: int|
2875 0 <= j < self.drop_first().len() ==> self.drop_first()[j]
2876 <= self.drop_first().max()) by { self.drop_first().max_ensures() }
2877 }
2878 }
2879 }
2880
2881 pub open spec fn min(self) -> int
2883 recommends
2884 0 < self.len(),
2885 decreases self.len(),
2886 {
2887 if self.len() == 1 {
2888 self[0]
2889 } else if self.len() == 0 {
2890 0
2891 } else {
2892 let later_min = self.drop_first().min();
2893 if self[0] <= later_min {
2894 self[0]
2895 } else {
2896 later_min
2897 }
2898 }
2899 }
2900
2901 pub proof fn min_ensures(self)
2903 ensures
2904 forall|x: int| self.contains(x) ==> self.min() <= x,
2905 forall|i: int| 0 <= i < self.len() ==> self.min() <= self[i],
2906 self.len() == 0 || self.contains(self.min()),
2907 decreases self.len(),
2908 {
2909 if self.len() <= 1 {
2910 } else {
2911 let elt = self.drop_first().min();
2912 assert(self[1..].contains(elt)) by {
2913 self.drop_first().min_ensures()
2914 }
2915 assert forall|i: int| 0 <= i < self.len() implies self.min() <= self[i] by {
2916 assert(i == 0 || self[i] == self.drop_first()[i - 1]);
2917 assert(forall|j: int|
2918 0 <= j < self.drop_first().len() ==> self.drop_first().min()
2919 <= self.drop_first()[j]) by { self.drop_first().min_ensures() }
2920 }
2921 }
2922 }
2923
2924 pub closed spec fn sort(self) -> Self {
2925 self.sort_by(|x: int, y: int| x <= y)
2926 }
2927
2928 pub proof fn lemma_sort_ensures(self)
2929 ensures
2930 self.to_multiset() =~= self.sort().to_multiset(),
2931 sorted_by(self.sort(), |x: int, y: int| x <= y),
2932 {
2933 self.lemma_sort_by_ensures(|x: int, y: int| x <= y);
2934 }
2935
2936 pub proof fn lemma_subrange_max(self, from: int, to: int)
2939 requires
2940 0 <= from < to <= self.len(),
2941 ensures
2942 self[from..to].max() <= self.max(),
2943 {
2944 self.max_ensures();
2945 self[from..to].max_ensures();
2946 }
2947
2948 pub proof fn lemma_subrange_min(self, from: int, to: int)
2951 requires
2952 0 <= from < to <= self.len(),
2953 ensures
2954 self[from..to].min() >= self.min(),
2955 {
2956 self.min_ensures();
2957 self[from..to].min_ensures();
2958 }
2959}
2960
2961spec fn merge_sorted_with<A>(left: Seq<A>, right: Seq<A>, leq: spec_fn(A, A) -> bool) -> Seq<A>
2963 recommends
2964 sorted_by(left, leq),
2965 sorted_by(right, leq),
2966 total_ordering(leq),
2967 decreases left.len(), right.len(),
2968{
2969 if left.len() == 0 {
2970 right
2971 } else if right.len() == 0 {
2972 left
2973 } else if leq(left.first(), right.first()) {
2974 Seq::<A>::empty().push(left.first()) + merge_sorted_with(left.drop_first(), right, leq)
2975 } else {
2976 Seq::<A>::empty().push(right.first()) + merge_sorted_with(left, right.drop_first(), leq)
2977 }
2978}
2979
2980proof fn lemma_merge_sorted_with_ensures<A>(left: Seq<A>, right: Seq<A>, leq: spec_fn(A, A) -> bool)
2981 requires
2982 sorted_by(left, leq),
2983 sorted_by(right, leq),
2984 total_ordering(leq),
2985 ensures
2986 (left + right).to_multiset() =~= merge_sorted_with(left, right, leq).to_multiset(),
2987 sorted_by(merge_sorted_with(left, right, leq), leq),
2988 decreases left.len(), right.len(),
2989{
2990 broadcast use group_seq_properties;
2992
2993 if left.len() == 0 {
2994 assert(left + right =~= right);
2995 } else if right.len() == 0 {
2996 assert(left + right =~= left);
2997 } else if leq(left.first(), right.first()) {
2998 let result = Seq::<A>::empty().push(left.first()) + merge_sorted_with(
2999 left.drop_first(),
3000 right,
3001 leq,
3002 );
3003 lemma_merge_sorted_with_ensures(left.drop_first(), right, leq);
3004 let rest = merge_sorted_with(left.drop_first(), right, leq);
3005 assert(rest.len() == 0 || rest.first() == left.drop_first().first() || rest.first()
3006 == right.first()) by {
3007 if left.drop_first().len() == 0 {
3008 } else if leq(left.drop_first().first(), right.first()) {
3009 assert(rest =~= Seq::<A>::empty().push(left.drop_first().first())
3010 + merge_sorted_with(left.drop_first().drop_first(), right, leq));
3011 } else {
3012 assert(rest =~= Seq::<A>::empty().push(right.first()) + merge_sorted_with(
3013 left.drop_first(),
3014 right.drop_first(),
3015 leq,
3016 ));
3017 }
3018 }
3019 lemma_new_first_element_still_sorted_by(left.first(), rest, leq);
3020 assert((left.drop_first() + right) =~= (left + right).drop_first());
3021 } else {
3022 let result = Seq::<A>::empty().push(right.first()) + merge_sorted_with(
3023 left,
3024 right.drop_first(),
3025 leq,
3026 );
3027 lemma_merge_sorted_with_ensures(left, right.drop_first(), leq);
3028 let rest = merge_sorted_with(left, right.drop_first(), leq);
3029 assert(rest.len() == 0 || rest.first() == left.first() || rest.first()
3030 == right.drop_first().first()) by {
3031 assert(left.len() > 0);
3032 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(
3035 left.drop_first(),
3036 right.drop_first(),
3037 leq,
3038 ));
3039 } else {
3040 assert(rest =~= Seq::<A>::empty().push(right.drop_first().first())
3041 + merge_sorted_with(left, right.drop_first().drop_first(), leq));
3042 }
3043 }
3044 lemma_new_first_element_still_sorted_by(
3045 right.first(),
3046 merge_sorted_with(left, right.drop_first(), leq),
3047 leq,
3048 );
3049 lemma_seq_union_to_multiset_commutative(left, right);
3050 assert((right.drop_first() + left) =~= (right + left).drop_first());
3051 lemma_seq_union_to_multiset_commutative(right.drop_first(), left);
3052 }
3053}
3054
3055pub proof fn lemma_max_of_concat(x: Seq<int>, y: Seq<int>)
3058 requires
3059 0 < x.len() && 0 < y.len(),
3060 ensures
3061 x.max() <= (x + y).max(),
3062 y.max() <= (x + y).max(),
3063 forall|elt: int| (x + y).contains(elt) ==> elt <= (x + y).max(),
3064 decreases x.len(),
3065{
3066 broadcast use group_seq_properties;
3067
3068 x.max_ensures();
3069 y.max_ensures();
3070 (x + y).max_ensures();
3071 assert(x.drop_first().len() == x.len() - 1);
3072 if x.len() == 1 {
3073 assert(y.max() <= (x + y).max()) by {
3074 assert((x + y).contains(y.max()));
3075 }
3076 } else {
3077 assert(x.max() <= (x + y).max()) by {
3078 assert(x.contains(x.max()));
3079 assert((x + y).contains(x.max()));
3080 }
3081 assert(x.drop_first() + y =~= (x + y).drop_first());
3082 lemma_max_of_concat(x.drop_first(), y);
3083 }
3084}
3085
3086pub proof fn lemma_min_of_concat(x: Seq<int>, y: Seq<int>)
3089 requires
3090 0 < x.len() && 0 < y.len(),
3091 ensures
3092 (x + y).min() <= x.min(),
3093 (x + y).min() <= y.min(),
3094 forall|elt: int| (x + y).contains(elt) ==> (x + y).min() <= elt,
3095 decreases x.len(),
3096{
3097 x.min_ensures();
3098 y.min_ensures();
3099 (x + y).min_ensures();
3100 broadcast use group_seq_properties;
3101
3102 if x.len() == 1 {
3103 assert((x + y).min() <= y.min()) by {
3104 assert((x + y).contains(y.min()));
3105 }
3106 } else {
3107 assert((x + y).min() <= x.min()) by {
3108 assert((x + y).contains(x.min()));
3109 }
3110 assert((x + y).min() <= y.min()) by {
3111 assert((x + y).contains(y.min()));
3112 }
3113 assert(x.drop_first() + y =~= (x + y).drop_first());
3114 lemma_max_of_concat(x.drop_first(), y)
3115 }
3116}
3117
3118pub broadcast proof fn to_multiset_build<A>(s: Seq<A>, a: A)
3122 ensures
3123 #![trigger s.push(a).to_multiset()]
3124 s.push(a).to_multiset() =~= s.to_multiset().insert(a),
3125 decreases s.len(),
3126{
3127 broadcast use super::multiset::group_multiset_axioms;
3128
3129 if s.len() == 0 {
3130 assert(s.to_multiset() =~= Multiset::<A>::empty());
3131 assert(s.push(a).drop_first() =~= Seq::<A>::empty());
3132 assert(s.push(a).to_multiset() =~= Multiset::<A>::empty().insert(a).add(
3133 Seq::<A>::empty().to_multiset(),
3134 ));
3135 } else {
3136 to_multiset_build(s.drop_first(), a);
3137 assert(s.drop_first().push(a).to_multiset() =~= s.drop_first().to_multiset().insert(a));
3138 assert(s.push(a).drop_first() =~= s.drop_first().push(a));
3139 }
3140}
3141
3142pub broadcast proof fn to_multiset_remove<A>(s: Seq<A>, i: int)
3143 requires
3144 0 <= i < s.len(),
3145 ensures
3146 #![trigger s.remove(i).to_multiset()]
3147 s.remove(i).to_multiset() == s.to_multiset().remove(s[i]),
3148{
3149 broadcast use super::multiset::group_multiset_axioms;
3150
3151 let s0 = s[..i];
3152 let s1 = s[i..];
3153 let s2 = s[i + 1..];
3154 lemma_seq_union_to_multiset_commutative(s0, s2);
3155 lemma_seq_union_to_multiset_commutative(s0, s1);
3156 assert(s == s0 + s1);
3157 assert(s2 + s0 == (s1 + s0).drop_first());
3158 assert(s.remove(i).to_multiset() =~= s.to_multiset().remove(s[i]));
3159}
3160
3161pub broadcast proof fn to_multiset_insert<A>(s: Seq<A>, i: int, a: A)
3162 requires
3163 0 <= i <= s.len(),
3164 ensures
3165 #![trigger s.insert(i, a).to_multiset()]
3166 s.insert(i, a).to_multiset() == s.to_multiset().insert(a),
3167 decreases s.len(),
3168{
3169 broadcast use super::multiset::group_multiset_axioms;
3170
3171 let s0 = s[..i];
3172 let s1 = s[i..];
3173
3174 assert(s =~= s0 + s1);
3175 assert(s.insert(i, a) =~= s0 + seq![a] + s1);
3176 assert(((s0 + seq![a]) + s1).to_multiset() =~= ((seq![a] + s0) + s1).to_multiset()) by {
3177 broadcast use lemma_multiset_commutative;
3178
3179 };
3180 assert((seq![a] + s0 + s1).drop_first() == s0 + s1);
3181 assert(s.insert(i, a).to_multiset() =~= s.to_multiset().insert(a));
3182}
3183
3184pub broadcast proof fn to_multiset_len<A>(s: Seq<A>)
3186 ensures
3187 s.len() == #[trigger] s.to_multiset().len(),
3188 decreases s.len(),
3189{
3190 broadcast use super::multiset::group_multiset_axioms;
3191
3192 if s.len() == 0 {
3193 assert(s.to_multiset() =~= Multiset::<A>::empty());
3194 assert(s.len() == 0);
3195 } else {
3196 to_multiset_len(s.drop_first());
3197 assert(s.len() == s.drop_first().len() + 1);
3198 assert(s.to_multiset().len() == s.drop_first().to_multiset().len() + 1);
3199 }
3200}
3201
3202pub broadcast proof fn to_multiset_contains<A>(s: Seq<A>, a: A)
3204 ensures
3205 #![trigger s.to_multiset().count(a)]
3206 s.contains(a) <==> s.to_multiset().count(a) > 0,
3207 decreases s.len(),
3208{
3209 broadcast use super::multiset::group_multiset_axioms;
3210
3211 if s.len() != 0 {
3212 if s.contains(a) {
3214 if s.first() == a {
3215 to_multiset_build(s, a);
3216 assert(s.to_multiset() =~= Multiset::<A>::empty().insert(s.first()).add(
3217 s.drop_first().to_multiset(),
3218 ));
3219 assert(Multiset::<A>::empty().insert(s.first()).contains(s.first()));
3220 } else {
3221 to_multiset_contains(s.drop_first(), a);
3222 assert(s[1..] =~= s.drop_first());
3223 lemma_seq_skip_contains(s, 1, a);
3224 assert(s.to_multiset().count(a) == s.drop_first().to_multiset().count(a));
3225 assert(s.contains(a) <==> s.to_multiset().count(a) > 0);
3226 }
3227 }
3228 if s.to_multiset().count(a) > 0 {
3231 to_multiset_contains(s.drop_first(), a);
3232 assert(s.contains(a) <==> s.to_multiset().count(a) > 0);
3233 } else {
3234 assert(s.contains(a) <==> s.to_multiset().count(a) > 0);
3235 }
3236 }
3237}
3238
3239pub broadcast proof fn to_multiset_update<A>(s: Seq<A>, i: int, a: A)
3240 requires
3241 0 <= i < s.len(),
3242 ensures
3243 #[trigger] s.update(i, a).to_multiset() == s.to_multiset().insert(a).remove(s[i]),
3244 decreases s.len(),
3245{
3246 broadcast use {
3247 super::seq_lib::lemma_seq_take_len,
3248 super::multiset::group_multiset_properties,
3249 super::multiset::group_multiset_axioms,
3250 to_multiset_insert,
3251 to_multiset_remove,
3252 to_multiset_contains,
3253 lemma_update_is_remove_insert,
3254 };
3255
3256 assert(s.update(i, a).to_multiset() =~= s.to_multiset().insert(a).remove(s[i]));
3257
3258}
3259
3260pub broadcast proof fn lemma_update_is_remove_insert<A>(s: Seq<A>, i: int, a: A)
3262 requires
3263 0 <= i < s.len(),
3264 ensures
3265 #[trigger] s.update(i, a) =~= s.remove(i).insert(i, a),
3266 decreases s.len(),
3267{
3268}
3269
3270pub proof fn lemma_append_last<A>(s1: Seq<A>, s2: Seq<A>)
3273 requires
3274 0 < s2.len(),
3275 ensures
3276 (s1 + s2).last() == s2.last(),
3277{
3278}
3279
3280pub proof fn lemma_concat_associative<A>(s1: Seq<A>, s2: Seq<A>, s3: Seq<A>)
3282 ensures
3283 s1.add(s2.add(s3)) =~= s1.add(s2).add(s3),
3284{
3285}
3286
3287spec fn seq_to_set_rec<A>(seq: Seq<A>) -> Set<A>
3289 decreases seq.len(),
3290{
3291 if seq.len() == 0 {
3292 Set::empty()
3293 } else {
3294 seq_to_set_rec(seq.drop_last()).insert(seq.last())
3295 }
3296}
3297
3298proof fn seq_to_set_rec_contains<A>(seq: Seq<A>)
3300 ensures
3301 forall|a| #[trigger] seq.contains(a) <==> seq_to_set_rec(seq).contains(a),
3302 decreases seq.len(),
3303{
3304 broadcast use super::set::group_set_lemmas;
3305
3306 if seq.len() > 0 {
3307 assert(forall|a| #[trigger]
3308 seq.drop_last().contains(a) <==> seq_to_set_rec(seq.drop_last()).contains(a)) by {
3309 seq_to_set_rec_contains(seq.drop_last());
3310 }
3311 assert(seq =~= seq.drop_last().push(seq.last()));
3312 assert forall|a| #[trigger] seq.contains(a) <==> seq_to_set_rec(seq).contains(a) by {
3313 if !seq.drop_last().contains(a) {
3314 if a == seq.last() {
3315 assert(seq.contains(a));
3316 assert(seq_to_set_rec(seq).contains(a));
3317 } else {
3318 assert(!seq_to_set_rec(seq).contains(a));
3319 }
3320 }
3321 }
3322 }
3323}
3324
3325proof fn seq_to_set_equal_rec<A>(seq: Seq<A>)
3327 ensures
3328 seq.to_set() == seq_to_set_rec(seq),
3329 decreases seq.len(),
3330{
3331 broadcast use super::set::group_set_lemmas;
3332
3333 seq.to_set_ensures();
3334 assert(forall|n| seq.contains(n) <==> #[trigger] seq_to_set_rec(seq).contains(n)) by {
3335 seq_to_set_rec_contains(seq);
3336 }
3337 assert(seq.to_set() =~= seq_to_set_rec(seq));
3338}
3339
3340pub proof fn seq_to_set_distributes_over_add<T>(s1: Seq<T>, s2: Seq<T>)
3341 ensures
3342 s1.to_set() + s2.to_set() =~= (s1 + s2).to_set(),
3343{
3344 broadcast use super::group_vstd_default;
3345 broadcast use super::set_lib::group_set_properties;
3346 broadcast use group_seq_properties;
3347
3348}
3349
3350pub proof fn lemma_no_dup_in_concat<A>(a: Seq<A>, b: Seq<A>)
3354 requires
3355 a.no_duplicates(),
3356 b.no_duplicates(),
3357 forall|i: int, j: int| 0 <= i < a.len() && 0 <= j < b.len() ==> a[i] != b[j],
3358 ensures
3359 #[trigger] (a + b).no_duplicates(),
3360{
3361}
3362
3363pub proof fn lemma_flatten_concat<A>(x: Seq<Seq<A>>, y: Seq<Seq<A>>)
3367 ensures
3368 (x + y).flatten() =~= x.flatten() + y.flatten(),
3369 decreases x.len(),
3370{
3371 if x.len() == 0 {
3372 assert(x + y =~= y);
3373 } else {
3374 assert((x + y).drop_first() =~= x.drop_first() + y);
3375 assert(x.first() + (x.drop_first() + y).flatten() =~= x.first() + x.drop_first().flatten()
3376 + y.flatten()) by {
3377 lemma_flatten_concat(x.drop_first(), y);
3378 }
3379 }
3380}
3381
3382pub proof fn lemma_flatten_alt_concat<A>(x: Seq<Seq<A>>, y: Seq<Seq<A>>)
3387 ensures
3388 (x + y).flatten_alt() =~= x.flatten_alt() + y.flatten_alt(),
3389 decreases y.len(),
3390{
3391 if y.len() == 0 {
3392 assert(x + y =~= x);
3393 } else {
3394 assert((x + y).drop_last() =~= x + y.drop_last());
3395 assert((x + y.drop_last()).flatten_alt() + y.last() =~= x.flatten_alt()
3396 + y.drop_last().flatten_alt() + y.last()) by {
3397 lemma_flatten_alt_concat(x, y.drop_last());
3398 }
3399 }
3400}
3401
3402pub broadcast proof fn lemma_seq_union_to_multiset_commutative<A>(a: Seq<A>, b: Seq<A>)
3405 ensures
3406 #[trigger] (a + b).to_multiset() =~= (b + a).to_multiset(),
3407{
3408 broadcast use super::multiset::group_multiset_axioms;
3409
3410 lemma_multiset_commutative(a, b);
3411 lemma_multiset_commutative(b, a);
3412}
3413
3414pub broadcast proof fn lemma_multiset_commutative<A>(a: Seq<A>, b: Seq<A>)
3417 ensures
3418 #[trigger] (a + b).to_multiset() =~= a.to_multiset().add(b.to_multiset()),
3419 decreases a.len(),
3420{
3421 broadcast use super::multiset::group_multiset_axioms;
3422
3423 if a.len() == 0 {
3424 assert(a + b =~= b);
3425 } else {
3426 lemma_multiset_commutative(a.drop_first(), b);
3427 assert(a.drop_first() + b =~= (a + b).drop_first());
3428 }
3429}
3430
3431pub proof fn lemma_sorted_unique<A>(x: Seq<A>, y: Seq<A>, leq: spec_fn(A, A) -> bool)
3433 requires
3434 sorted_by(x, leq),
3435 sorted_by(y, leq),
3436 total_ordering(leq),
3437 x.to_multiset() == y.to_multiset(),
3438 ensures
3439 x =~= y,
3440 decreases x.len(), y.len(),
3441{
3442 broadcast use super::multiset::group_multiset_axioms;
3443 broadcast use group_to_multiset_ensures;
3444
3445 if x.len() == 0 || y.len() == 0 {
3446 } else {
3447 assert(x.to_multiset().contains(x[0]));
3448 assert(x.to_multiset().contains(y[0]));
3449 let i = choose|i: int| #![trigger x.spec_index(i) ] 0 <= i < x.len() && x[i] == y[0];
3450 assert(leq(x[i], x[0]));
3451 assert(leq(x[0], x[i]));
3452 assert(x.drop_first().to_multiset() =~= x.to_multiset().remove(x[0]));
3453 assert(y.drop_first().to_multiset() =~= y.to_multiset().remove(y[0]));
3454 lemma_sorted_unique(x.drop_first(), y.drop_first(), leq);
3455 assert(x.drop_first() =~= y.drop_first());
3456 assert(x.first() == y.first());
3457 assert(x =~= Seq::<A>::empty().push(x.first()).add(x.drop_first()));
3458 assert(x =~= y);
3459 }
3460}
3461
3462pub broadcast proof fn lemma_seq_contains<A>(s: Seq<A>, x: A)
3464 ensures
3465 #[trigger] s.contains(x) <==> exists|i: int| 0 <= i < s.len() && #[trigger] s[i] == x,
3466{
3467}
3468
3469pub broadcast proof fn lemma_seq_empty_contains_nothing<A>(x: A)
3472 ensures
3473 !(#[trigger] Seq::<A>::empty().contains(x)),
3474{
3475}
3476
3477pub broadcast proof fn lemma_seq_empty_equality<A>(s: Seq<A>)
3481 ensures
3482 #[trigger] s.len() == 0 ==> s =~= Seq::<A>::empty(),
3483{
3484}
3485
3486pub broadcast proof fn lemma_seq_concat_contains_all_elements<A>(x: Seq<A>, y: Seq<A>, elt: A)
3490 ensures
3491 #[trigger] (x + y).contains(elt) <==> x.contains(elt) || y.contains(elt),
3492 decreases x.len(),
3493{
3494 if x.len() == 0 && y.len() > 0 {
3495 assert((x + y) =~= y);
3496 } else {
3497 assert forall|elt: A| #[trigger] x.contains(elt) implies #[trigger] (x + y).contains(
3498 elt,
3499 ) by {
3500 let index = choose|i: int| 0 <= i < x.len() && x[i] == elt;
3501 assert((x + y)[index] == elt);
3502 }
3503 assert forall|elt: A| #[trigger] y.contains(elt) implies #[trigger] (x + y).contains(
3504 elt,
3505 ) by {
3506 let index = choose|i: int| 0 <= i < y.len() && y[i] == elt;
3507 assert((x + y)[index + x.len()] == elt);
3508 }
3509 }
3510}
3511
3512pub broadcast proof fn lemma_seq_contains_after_push<A>(s: Seq<A>, v: A, x: A)
3515 ensures
3516 #[trigger] s.push(v).contains(x) <==> v == x || s.contains(x),
3517{
3518 assert forall|elt: A| #[trigger] s.contains(elt) implies #[trigger] s.push(v).contains(elt) by {
3519 let index = choose|i: int| 0 <= i < s.len() && s[i] == elt;
3520 assert(s.push(v)[index] == elt);
3521 }
3522 assert(s.push(v)[s.len() as int] == v);
3523}
3524
3525pub broadcast proof fn lemma_seq_subrange_elements<A>(s: Seq<A>, start: int, stop: int, x: A)
3529 requires
3530 0 <= start <= stop <= s.len(),
3531 ensures
3532 #[trigger] s[start..stop].contains(x) <==> (exists|i: int|
3533 0 <= start <= i < stop <= s.len() && #[trigger] s[i] == x),
3534{
3535 assert((exists|i: int| 0 <= start <= i < stop <= s.len() && s[i] == x) ==> s[start..stop].contains(x)) by {
3536 if exists|i: int| 0 <= start <= i < stop <= s.len() && s[i] == x {
3537 let index = choose|i: int| 0 <= start <= i < stop <= s.len() && s[i] == x;
3538 assert(s[start..stop][index - start] == s[index]);
3539 }
3540 }
3541}
3542
3543pub open spec fn commutative_foldr<A, B>(f: spec_fn(A, B) -> B) -> bool {
3545 forall|x: A, y: A, v: B| #[trigger] f(x, f(y, v)) == f(y, f(x, v))
3546}
3547
3548pub open spec fn commutative_foldl<A, B>(f: spec_fn(B, A) -> B) -> bool {
3550 forall|x: A, y: A, v: B| #[trigger] f(f(v, x), y) == f(f(v, y), x)
3551}
3552
3553pub proof fn lemma_fold_right_permutation<A, B>(l1: Seq<A>, l2: Seq<A>, f: spec_fn(A, B) -> B, v: B)
3556 requires
3557 commutative_foldr(f),
3558 l1.to_multiset() == l2.to_multiset(),
3559 ensures
3560 l1.fold_right(f, v) == l2.fold_right(f, v),
3561 decreases l1.len(),
3562{
3563 broadcast use group_to_multiset_ensures;
3564
3565 if l1.len() > 0 {
3566 let a = l1.last();
3567 let i = l2.index_of(a);
3568 let l2r = l2[i + 1..].fold_right(f, v);
3569
3570 assert(l1.to_multiset().count(a) > 0);
3571 l1.drop_last().lemma_fold_right_commute_one(a, f, v);
3572 l2[..i].lemma_fold_right_commute_one(a, f, l2r);
3573
3574 l2.lemma_fold_right_split(f, v, i + 1);
3575 l2.remove(i).lemma_fold_right_split(f, v, i);
3576
3577 assert(l2[..i + 1].drop_last() == l2[..i]);
3578 assert(l1.drop_last() == l1.remove(l1.len() - 1));
3579
3580 assert(l2.remove(i)[..i] == l2[..i]);
3581 assert(l2.remove(i)[i..l2.remove(i).len()] == l2[i + 1..l2.len()]);
3582
3583 lemma_fold_right_permutation(l1.drop_last(), l2.remove(i), f, v);
3584 } else {
3585 assert(l2.to_multiset().len() == 0);
3586 }
3587}
3588
3589pub proof fn lemma_fold_left_permutation<A, B>(l1: Seq<A>, l2: Seq<A>, f: spec_fn(B, A) -> B, v: B)
3592 requires
3593 commutative_foldl(f),
3594 l1.to_multiset() == l2.to_multiset(),
3595 ensures
3596 l1.fold_left(v, f) == l2.fold_left(v, f),
3597{
3598 let g = |a: A, b: B| f(b, a);
3599 assert(f =~= |b: B, a: A| g(a, b));
3600 assert(l1.fold_left(v, f) == l1.reverse().fold_right(g, v)) by {
3601 l1.lemma_reverse_fold_right(v, g)
3602 };
3603 assert(l2.fold_left(v, f) == l2.reverse().fold_right(g, v)) by {
3604 l2.lemma_reverse_fold_right(v, g)
3605 };
3606 assert(l1.reverse().to_multiset() =~= l2.reverse().to_multiset()) by {
3607 l1.lemma_reverse_to_multiset();
3608 l2.lemma_reverse_to_multiset();
3609 }
3610 assert(forall|x: A| #[trigger] l1.reverse().contains(x) ==> l1.contains(x));
3611 assert(forall|x: A| #[trigger] l2.reverse().contains(x) ==> l2.contains(x));
3612 lemma_fold_right_permutation(l1.reverse(), l2.reverse(), g, v);
3613}
3614
3615pub broadcast proof fn lemma_seq_take_len<A>(s: Seq<A>, n: int)
3621 ensures
3622 0 <= n <= s.len() ==> #[trigger] s[..n].len() == n,
3623{
3624}
3625
3626pub broadcast proof fn lemma_seq_take_contains<A>(s: Seq<A>, n: int, x: A)
3630 requires
3631 0 <= n <= s.len(),
3632 ensures
3633 #[trigger] s[..n].contains(x) <==> (exists|i: int|
3634 0 <= i < n <= s.len() && #[trigger] s[i] == x),
3635{
3636 assert((exists|i: int| 0 <= i < n <= s.len() && #[trigger] s[i] == x) ==> s[..n].contains(x))
3637 by {
3638 if exists|i: int| 0 <= i < n <= s.len() && #[trigger] s[i] == x {
3639 let index = choose|i: int| 0 <= i < n <= s.len() && #[trigger] s[i] == x;
3640 assert(s[..n][index] == s[index]);
3641 }
3642 }
3643}
3644
3645pub broadcast proof fn lemma_seq_take_index<A>(s: Seq<A>, n: int, j: int)
3649 ensures
3650 0 <= j < n <= s.len() ==> #[trigger] s[..n][j] == s[j],
3651{
3652}
3653
3654pub proof fn subrange_of_matching_take<T>(a: Seq<T>, b: Seq<T>, s: int, e: int, l: int)
3655 requires
3656 a[..l] == b[..l],
3657 l <= a.len(),
3658 l <= b.len(),
3659 0 <= s <= e <= l,
3660 ensures
3661 a[s..e] == b[s..e],
3662{
3663 assert forall|i| 0 <= i < e - s implies #[trigger] a[s..e][i] == b[s..e][i] by {
3664 assert(a[s..e][i] == a[..l][i + s]);
3665 }
3667 assert(a[s..e] == b[s..e]);
3670}
3671
3672pub broadcast proof fn lemma_seq_skip_len<A>(s: Seq<A>, n: int)
3676 ensures
3677 0 <= n <= s.len() ==> #[trigger] s[n..].len() == s.len() - n,
3678{
3679}
3680
3681pub broadcast proof fn lemma_seq_skip_contains<A>(s: Seq<A>, n: int, x: A)
3685 requires
3686 0 <= n <= s.len(),
3687 ensures
3688 #[trigger] s[n..].contains(x) <==> (exists|i: int|
3689 0 <= n <= i < s.len() && #[trigger] s[i] == x),
3690{
3691 assert((exists|i: int| 0 <= n <= i < s.len() && #[trigger] s[i] == x) ==> s[n..].contains(x))
3692 by {
3693 let index = choose|i: int| 0 <= n <= i < s.len() && #[trigger] s[i] == x;
3694 lemma_seq_skip_index(s, n, index - n);
3695 }
3696}
3697
3698pub broadcast proof fn lemma_seq_skip_index<A>(s: Seq<A>, n: int, j: int)
3702 ensures
3703 0 <= n && 0 <= j < (s.len() - n) ==> #[trigger] s[n..][j] == s[j + n],
3704{
3705}
3706
3707pub broadcast proof fn lemma_seq_skip_index2<A>(s: Seq<A>, n: int, k: int)
3712 ensures
3713 0 <= n <= k < s.len() ==> (#[trigger] s[n..])[k - n] == #[trigger] s[k],
3714{
3715}
3716
3717pub broadcast proof fn lemma_seq_append_take_skip<A>(a: Seq<A>, b: Seq<A>, n: int)
3722 ensures
3723 #![trigger (a + b)[..n]]
3724 #![trigger (a + b)[n..]]
3725n == a.len() ==> ((a + b)[..n] =~= a && (a + b)[n..] =~= b),
3728{
3729}
3730
3731pub broadcast proof fn lemma_seq_take_update_commut1<A>(s: Seq<A>, i: int, v: A, n: int)
3738 ensures
3739 #![trigger s.update(i, v)[..n]]
3740 0 <= i < n <= s.len() ==> #[trigger] s.update(i, v)[..n] =~= s[..n].update(i, v),
3741{
3742}
3743
3744pub broadcast proof fn lemma_seq_take_update_commut2<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],
3751{
3752}
3753
3754pub broadcast proof fn lemma_seq_skip_update_commut1<A>(s: Seq<A>, i: int, v: A, n: int)
3759 ensures
3760 0 <= n <= i < s.len() ==> #[trigger] s.update(i, v)[n..] =~= s[n..].update(i - n, v),
3761{
3762}
3763
3764pub broadcast proof fn lemma_seq_skip_update_commut2<A>(s: Seq<A>, i: int, v: A, n: int)
3769 ensures
3770 0 <= i < n <= s.len() ==> #[trigger] s.update(i, v)[n..] =~= s[n..],
3771{
3772}
3773
3774pub broadcast proof fn lemma_seq_skip_build_commut<A>(s: Seq<A>, v: A, n: int)
3778 ensures
3779 #![trigger s.push(v)[n..]]
3780 0 <= n <= s.len() ==> s.push(v)[n..] =~= s[n..].push(v),
3781{
3782}
3783
3784pub broadcast proof fn lemma_seq_skip_nothing<A>(s: Seq<A>, n: int)
3787 ensures
3788 n == 0 ==> #[trigger] s[n..] =~= s,
3789{
3790}
3791
3792pub broadcast proof fn lemma_seq_take_nothing<A>(s: Seq<A>, n: int)
3795 ensures
3796 n == 0 ==> #[trigger] s[..n] =~= Seq::<A>::empty(),
3797{
3798}
3799
3800pub broadcast proof fn lemma_seq_skip_of_skip<A>(s: Seq<A>, m: int, n: int)
3805 ensures
3806 (0 <= m && 0 <= n && m + n <= s.len()) ==> #[trigger] s[m..][n..] =~= s[m + n..],
3807{
3808}
3809
3810#[doc(hidden)]
3811#[verifier::inline]
3812pub open spec fn check_argument_is_seq<A>(s: Seq<A>) -> Seq<A> {
3813 s
3814}
3815
3816#[macro_export]
3861macro_rules! assert_seqs_equal {
3862 [$($tail:tt)*] => {
3863 $crate::vstd::prelude::verus_proof_macro_exprs!($crate::vstd::seq_lib::assert_seqs_equal_internal!($($tail)*))
3864 };
3865}
3866
3867#[macro_export]
3868#[doc(hidden)]
3869macro_rules! assert_seqs_equal_internal {
3870 (::vstd::spec_eq($s1:expr, $s2:expr)) => {
3871 $crate::vstd::seq_lib::assert_seqs_equal_internal!($s1, $s2)
3872 };
3873 (::vstd::prelude::spec_eq($s1:expr, $s2:expr)) => {
3874 $crate::vstd::seq_lib::assert_seqs_equal_internal!($s1, $s2)
3875 };
3876 (::vstd::prelude::spec_eq($s1:expr, $s2:expr), $idx:ident => $bblock:block) => {
3877 $crate::vstd::seq_lib::assert_seqs_equal_internal!($s1, $s2, $idx => $bblock)
3878 };
3879 (crate::prelude::spec_eq($s1:expr, $s2:expr)) => {
3880 $crate::vstd::seq_lib::assert_seqs_equal_internal!($s1, $s2)
3881 };
3882 (crate::prelude::spec_eq($s1:expr, $s2:expr), $idx:ident => $bblock:block) => {
3883 $crate::vstd::seq_lib::assert_seqs_equal_internal!($s1, $s2, $idx => $bblock)
3884 };
3885 (crate::verus_builtin::spec_eq($s1:expr, $s2:expr)) => {
3886 $crate::vstd::seq_lib::assert_seqs_equal_internal!($s1, $s2)
3887 };
3888 (crate::verus_builtin::spec_eq($s1:expr, $s2:expr), $idx:ident => $bblock:block) => {
3889 $crate::vstd::seq_lib::assert_seqs_equal_internal!($s1, $s2, $idx => $bblock)
3890 };
3891 ($s1:expr, $s2:expr $(,)?) => {
3892 $crate::vstd::seq_lib::assert_seqs_equal_internal!($s1, $s2, idx => { })
3893 };
3894 ($s1:expr, $s2:expr, $idx:ident => $bblock:block) => {
3895 #[verifier::spec] let s1 = $crate::vstd::seq_lib::check_argument_is_seq($s1);
3896 #[verifier::spec] let s2 = $crate::vstd::seq_lib::check_argument_is_seq($s2);
3897 $crate::vstd::prelude::assert_by($crate::vstd::prelude::equal(s1, s2), {
3898 $crate::vstd::prelude::assert_(s1.len() == s2.len());
3899 $crate::vstd::prelude::assert_forall_by(|$idx : $crate::vstd::prelude::int| {
3900 $crate::vstd::prelude::requires($crate::vstd::prelude::verus_proof_expr!(0 <= $idx && $idx < s1.len()));
3901 $crate::vstd::prelude::ensures($crate::vstd::prelude::equal(s1.index($idx), s2.index($idx)));
3902 { $bblock }
3903 });
3904 $crate::vstd::prelude::assert_($crate::vstd::prelude::ext_equal(s1, s2));
3905 });
3906 }
3907}
3908
3909pub broadcast group group_filter_ensures {
3910 Seq::lemma_filter_len,
3911 Seq::lemma_filter_pred,
3912 Seq::lemma_filter_contains,
3913}
3914
3915pub broadcast group group_seq_lib_default {
3916 Seq::to_set_ensures,
3917 group_filter_ensures,
3918 Seq::lemma_filter_index,
3919 Seq::add_empty_left,
3920 Seq::add_empty_right,
3921 Seq::push_distributes_over_add,
3922 Seq::filter_distributes_over_add,
3923 Seq::lemma_fold_right_split,
3924 Seq::lemma_fold_left_split,
3925}
3926
3927pub broadcast group group_to_multiset_ensures {
3928 to_multiset_build,
3929 to_multiset_remove,
3930 to_multiset_len,
3931 to_multiset_contains,
3932 to_multiset_insert,
3933 to_multiset_update,
3934}
3935
3936pub broadcast group group_seq_properties {
3938 lemma_seq_contains,
3939 lemma_seq_empty_contains_nothing,
3940 lemma_seq_empty_equality,
3941 lemma_seq_concat_contains_all_elements,
3942 lemma_seq_contains_after_push,
3943 lemma_seq_subrange_elements,
3944 lemma_seq_take_len,
3945 lemma_seq_take_contains,
3946 lemma_seq_take_index,
3947 lemma_seq_skip_len,
3948 lemma_seq_skip_contains,
3949 lemma_seq_skip_index,
3950 lemma_seq_skip_index2,
3951 lemma_seq_append_take_skip,
3952 lemma_seq_take_update_commut1,
3953 lemma_seq_take_update_commut2,
3954 lemma_seq_skip_update_commut1,
3955 lemma_seq_skip_update_commut2,
3956 lemma_seq_skip_build_commut,
3957 lemma_seq_skip_nothing,
3958 lemma_seq_take_nothing,
3959 group_to_multiset_ensures,
3963}
3964
3965#[doc(hidden)]
3966pub use assert_seqs_equal_internal;
3967pub use assert_seqs_equal;
3968
3969}