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 open spec fn is_prefix_of(self, other: Self) -> bool {
68 self.len() <= other.len() && self =~= other.subrange(0, self.len() as int)
69 }
70
71 pub open spec fn is_suffix_of(self, other: Self) -> bool {
83 self.len() <= other.len() && self =~= other.subrange(
84 (other.len() - self.len()) as int,
85 other.len() as int,
86 )
87 }
88
89 pub closed spec fn sort_by(self, leq: spec_fn(A, A) -> bool) -> Seq<A>
97 recommends
98 total_ordering(leq),
99 decreases self.len(),
100 {
101 if self.len() <= 1 {
102 self
103 } else {
104 let split_index = self.len() / 2;
105 let left = self.subrange(0, split_index as int);
106 let right = self.subrange(split_index as int, self.len() as int);
107 let left_sorted = left.sort_by(leq);
108 let right_sorted = right.sort_by(leq);
109 merge_sorted_with(left_sorted, right_sorted, leq)
110 }
111 }
112
113 pub open spec fn all(self, pred: spec_fn(A) -> bool) -> bool {
124 forall|i: int| 0 <= i < self.len() ==> #[trigger] pred(self[i])
125 }
126
127 pub open spec fn any(self, pred: spec_fn(A) -> bool) -> bool {
138 exists|i: int| 0 <= i < self.len() && #[trigger] pred(self[i])
139 }
140
141 pub open spec fn exactly_one(self, pred: spec_fn(A) -> bool) -> bool {
151 self.filter(pred).len() == 1
152 }
153
154 pub proof fn lemma_sort_by_ensures(self, leq: spec_fn(A, A) -> bool)
155 requires
156 total_ordering(leq),
157 ensures
158 self.to_multiset() =~= self.sort_by(leq).to_multiset(),
159 sorted_by(self.sort_by(leq), leq),
160 forall|x: A| !self.contains(x) ==> !(#[trigger] self.sort_by(leq).contains(x)),
161 decreases self.len(),
162 {
163 if self.len() <= 1 {
164 } else {
165 let split_index = self.len() / 2;
166 let left = self.subrange(0, split_index as int);
167 let right = self.subrange(split_index as int, self.len() as int);
168 assert(self =~= left + right);
169 let left_sorted = left.sort_by(leq);
170 left.lemma_sort_by_ensures(leq);
171 let right_sorted = right.sort_by(leq);
172 right.lemma_sort_by_ensures(leq);
173 lemma_merge_sorted_with_ensures(left_sorted, right_sorted, leq);
174 lemma_multiset_commutative(left, right);
175 lemma_multiset_commutative(left_sorted, right_sorted);
176 assert forall|x: A| !self.contains(x) implies !(#[trigger] self.sort_by(leq).contains(
177 x,
178 )) by {
179 broadcast use group_to_multiset_ensures;
180
181 assert(!self.contains(x) ==> self.to_multiset().count(x) == 0);
182 }
183 }
184 }
185
186 #[verifier::opaque]
200 pub open spec fn filter(self, pred: spec_fn(A) -> bool) -> Self
201 decreases self.len(),
202 {
203 if self.len() == 0 {
204 self
205 } else {
206 let subseq = self.drop_last().filter(pred);
207 if pred(self.last()) {
208 subseq.push(self.last())
209 } else {
210 subseq
211 }
212 }
213 }
214
215 pub broadcast proof fn lemma_filter_len(self, pred: spec_fn(A) -> bool)
216 ensures
217 #[trigger] self.filter(pred).len() <= self.len(),
220 decreases self.len(),
221 {
222 reveal(Seq::filter);
223 let out = self.filter(pred);
224 if 0 < self.len() {
225 self.drop_last().lemma_filter_len(pred);
226 }
227 }
228
229 pub broadcast proof fn lemma_filter_pred(self, pred: spec_fn(A) -> bool, i: int)
230 requires
231 0 <= i < self.filter(pred).len(),
232 ensures
233 pred(#[trigger] self.filter(pred)[i]),
234 {
235 #[allow(deprecated)]
237 self.filter_lemma(pred);
238 }
239
240 pub broadcast proof fn lemma_filter_contains(self, pred: spec_fn(A) -> bool, i: int)
241 requires
242 0 <= i < self.len() && pred(self[i]),
243 ensures
244 #[trigger] self.filter(pred).contains(self[i]),
245 {
246 #[allow(deprecated)]
248 self.filter_lemma(pred);
249 }
250
251 #[cfg_attr(not(verus_verify_core), deprecated = "Use `broadcast use group_filter_ensures` instead" )]
253 pub proof fn filter_lemma(self, pred: spec_fn(A) -> bool)
254 ensures
255 forall|i: int|
261 0 <= i < self.filter(pred).len() ==> pred(#[trigger] self.filter(pred)[i]),
262 forall|i: int|
264 0 <= i < self.len() && pred(self[i]) ==> #[trigger] self.filter(pred).contains(
265 self[i],
266 ),
267 #[trigger] self.filter(pred).len() <= self.len(),
269 decreases self.len(),
270 {
271 reveal(Seq::filter);
272 let out = self.filter(pred);
273 if 0 < self.len() {
274 self.drop_last().filter_lemma(pred);
275 assert forall|i: int| 0 <= i < out.len() implies pred(out[i]) by {
276 if i < out.len() - 1 {
277 assert(self.drop_last().filter(pred)[i] == out.drop_last()[i]); assert(pred(out[i])); }
280 }
281 assert forall|i: int|
282 0 <= i < self.len() && pred(self[i]) implies #[trigger] out.contains(self[i]) by {
283 if i == self.len() - 1 {
284 assert(self[i] == out[out.len() - 1]); } else {
286 let subseq = self.drop_last().filter(pred);
287 assert(subseq.contains(self.drop_last()[i])); let j = choose|j| 0 <= j < subseq.len() && subseq[j] == self[i];
289 assert(out[j] == self[i]); }
291 }
292 }
293 }
294
295 pub broadcast proof fn filter_distributes_over_add(a: Self, b: Self, pred: spec_fn(A) -> bool)
296 ensures
297 #[trigger] (a + b).filter(pred) == a.filter(pred) + b.filter(pred),
298 decreases b.len(),
299 {
300 reveal(Seq::filter);
301 if 0 < b.len() {
302 Self::drop_last_distributes_over_add(a, b);
303 Self::filter_distributes_over_add(a, b.drop_last(), pred);
304 if pred(b.last()) {
305 Self::push_distributes_over_add(
306 a.filter(pred),
307 b.drop_last().filter(pred),
308 b.last(),
309 );
310 }
311 } else {
312 Self::add_empty_right(a, b);
313 Self::add_empty_right(a.filter(pred), b.filter(pred));
314 }
315 }
316
317 #[verifier::opaque]
341 pub open spec fn filter_index(self, pred: spec_fn(int) -> bool) -> Self
342 decreases self.len(),
343 {
344 if self.len() == 0 {
345 self
346 } else {
347 let subseq = self.drop_last().filter_index(pred);
348 if pred(self.len() - 1) {
349 subseq.push(self.last())
350 } else {
351 subseq
352 }
353 }
354 }
355
356 broadcast proof fn lemma_filter_index_len(self, pred: spec_fn(int) -> bool)
358 ensures
359 #[trigger] (self.filter_index(pred).len()) <= self.len(),
360 decreases self.len(),
361 {
362 reveal(Seq::filter_index);
363 if self.len() != 0 {
364 self.drop_last().lemma_filter_index_len(pred);
365 }
366 }
367
368 proof fn lemma_filter_index_source(self, pred: spec_fn(int) -> bool)
370 ensures
371 self.filter_index_range(pred),
372 decreases self.len(),
373 {
374 reveal(Seq::filter_index);
375 if self.len() != 0 {
376 let s_rest = self.drop_last();
377 assert(s_rest.len() == self.len() - 1);
378 s_rest.lemma_filter_index_source(pred);
379 let rest = s_rest.filter_index(pred);
380 let result = self.filter_index(pred);
381 let last_idx = (self.len() - 1) as int;
382 assert(forall|k: int| 0 <= k < s_rest.len() ==> #[trigger] s_rest[k] == self[k]);
383
384 if pred(last_idx) {
385 assert(result =~= rest.push(self.last()));
386 } else {
387 assert(result =~= rest);
388 }
389
390 assert forall|i: int| 0 <= i < result.len() implies (exists|j: int|
391 0 <= j < self.len() && #[trigger] result[i] == #[trigger] self[j] && pred(j)) by {
392 if pred(last_idx) && i == rest.len() {
393 assert(result[i] == self[last_idx]);
394 } else {
395 assert(result[i] == rest[i]);
396 let j_rest = choose|j: int|
397 0 <= j < s_rest.len() && rest[i] == s_rest[j] && pred(j);
398 assert(self[j_rest] == s_rest[j_rest]);
399 }
400 }
401 }
402 }
403
404 proof fn lemma_filter_index_witness(self, pred: spec_fn(int) -> bool)
406 ensures
407 self.filter_index_domain(pred),
408 decreases self.len(),
409 {
410 reveal(Seq::filter_index);
411 if self.len() != 0 {
412 let s_rest = self.drop_last();
413 assert(s_rest.len() == self.len() - 1);
414 s_rest.lemma_filter_index_witness(pred);
415 s_rest.lemma_filter_index_len(pred);
416 let rest = s_rest.filter_index(pred);
417 let result = self.filter_index(pred);
418 let last_idx = (self.len() - 1) as int;
419 assert(forall|k: int| 0 <= k < s_rest.len() ==> #[trigger] s_rest[k] == self[k]);
420
421 if pred(last_idx) {
422 assert(result =~= rest.push(self.last()));
423 } else {
424 assert(result =~= rest);
425 }
426
427 s_rest.lemma_filter_index_source(pred);
428 assert forall|i: int| 0 <= i < result.len() implies (exists|j: int|
429 0 <= j < self.len() && #[trigger] result[i] == #[trigger] self[j] && pred(j)) by {
430 if pred(last_idx) && i == rest.len() {
431 assert(result[i] == self[last_idx]);
432 } else {
433 assert(result[i] == rest[i]);
434 let j_rest = choose|j: int|
435 0 <= j < s_rest.len() && rest[i] == s_rest[j] && pred(j);
436 assert(self[j_rest] == s_rest[j_rest]);
437 }
438 }
439
440 assert forall|j: int| 0 <= j < self.len() && pred(j) implies (exists|i: int|
441 0 <= i < self.filter_index(pred).len() && #[trigger] self[j] == self.filter_index(
442 pred,
443 )[i]) by {
444 if j == last_idx {
445 assert(result =~= rest.push(self.last()));
446 assert(self.filter_index(pred)[rest.len() as int] == self[j]);
447 } else {
448 assert(rest.contains(s_rest[j]));
449 let w = choose|i: int| 0 <= i < rest.len() && rest[i] == s_rest[j];
450 assert(self.filter_index(pred)[w] == self[j]);
451 }
452 }
453 }
454 }
455
456 pub open spec fn filter_index_range(self, pred: spec_fn(int) -> bool) -> bool {
458 forall|i|
459 0 <= i < self.filter_index(pred).len() ==> (exists|j|
460 0 <= j < self.len() && #[trigger] self.filter_index(pred)[i] == #[trigger] self[j]
461 && pred(j))
462 }
463
464 pub open spec fn filter_index_domain(self, pred: spec_fn(int) -> bool) -> bool {
466 forall|j|
467 0 <= j < self.len() && pred(j) ==> #[trigger] self.filter_index(pred).contains(self[j])
468 }
469
470 pub broadcast proof fn lemma_filter_index(self, pred: spec_fn(int) -> bool)
472 ensures
473 (#[trigger] self.filter_index(pred)).len() <= self.len(),
476 self.filter_index_range(pred),
478 self.filter_index_domain(pred),
480 decreases self.len(),
481 {
482 self.lemma_filter_index_len(pred);
483 self.lemma_filter_index_source(pred);
484 self.lemma_filter_index_witness(pred);
485 }
486
487 pub proof fn filter_index_ext(self, p: spec_fn(int) -> bool, q: spec_fn(int) -> bool)
490 requires
491 forall|i| 0 <= i < self.len() ==> #[trigger] p(i) == q(i),
492 ensures
493 self.filter_index(p) == self.filter_index(q),
494 decreases self.len(),
495 {
496 reveal(Seq::filter_index);
497 if self.len() != 0 {
498 self.drop_last().filter_index_ext(p, q);
499 }
500 }
501
502 pub proof fn lemma_filter_index_head(self, pred: spec_fn(int) -> bool)
504 requires
505 self.len() > 0,
506 ensures
507 pred(0) ==> self.filter_index(pred) == seq![self[0]] + self.drop_first().filter_index(
508 |i: int| pred(i + 1),
509 ),
510 !pred(0) ==> self.filter_index(pred) == self.drop_first().filter_index(
511 |i: int| pred(i + 1),
512 ),
513 decreases self.len(),
514 {
515 reveal(Seq::filter_index);
516 let p2 = |i: int| pred(i + 1);
517 let t = self.drop_first();
518 if self.len() == 1 {
519 reveal_with_fuel(Seq::filter_index, 2);
520 assert(t.len() == 0);
521 assert(self.drop_last().len() == 0);
522 if pred(0) {
523 assert(self.filter_index(pred) =~= seq![self[0]] + t.filter_index(p2));
524 } else {
525 assert(self.filter_index(pred) =~= t.filter_index(p2));
526 }
527 } else {
528 let sdl = self.drop_last();
529 sdl.lemma_filter_index_head(pred);
530 assert(t.drop_last() =~= sdl.drop_first());
531 let p2b = |i: int| pred(i + 1);
532 sdl.drop_first().filter_index_ext(p2, p2b);
533 if pred(0) {
534 assert(self.filter_index(pred) =~= seq![self[0]] + t.filter_index(p2));
535 } else {
536 assert(self.filter_index(pred) =~= t.filter_index(p2));
537 }
538 }
539 }
540
541 pub broadcast proof fn add_empty_left(a: Self, b: Self)
542 requires
543 a.len() == 0,
544 ensures
545 #[trigger] (a + b) == b,
546 {
547 assert(a + b =~= b);
548 }
549
550 pub broadcast proof fn add_empty_right(a: Self, b: Self)
551 requires
552 b.len() == 0,
553 ensures
554 #[trigger] (a + b) == a,
555 {
556 assert(a + b =~= a);
557 }
558
559 pub broadcast proof fn push_distributes_over_add(a: Self, b: Self, elt: A)
560 ensures
561 #[trigger] (a + b).push(elt) == a + b.push(elt),
562 {
563 assert((a + b).push(elt) =~= a + b.push(elt));
564 }
565
566 pub open spec fn max_via(self, leq: spec_fn(A, A) -> bool) -> A
568 recommends
569 self.len() > 0,
570 decreases self.len(),
571 {
572 if self.len() > 1 {
573 if leq(self[0], self.subrange(1, self.len() as int).max_via(leq)) {
574 self.subrange(1, self.len() as int).max_via(leq)
575 } else {
576 self[0]
577 }
578 } else {
579 self[0]
580 }
581 }
582
583 pub open spec fn min_via(self, leq: spec_fn(A, A) -> bool) -> A
585 recommends
586 self.len() > 0,
587 decreases self.len(),
588 {
589 if self.len() > 1 {
590 let subseq = self.subrange(1, self.len() as int);
591 let elt = subseq.min_via(leq);
592 if leq(elt, self[0]) {
593 elt
594 } else {
595 self[0]
596 }
597 } else {
598 self[0]
599 }
600 }
601
602 pub open spec fn contains(self, needle: A) -> bool {
604 exists|i: int| 0 <= i < self.len() && self[i] == needle
605 }
606
607 pub open spec fn index_of(self, needle: A) -> int {
610 choose|i: int| 0 <= i < self.len() && self[i] == needle
611 }
612
613 pub closed spec fn index_of_first(self, needle: A) -> (result: Option<int>) {
616 if self.contains(needle) {
617 Some(self.first_index_helper(needle))
618 } else {
619 None
620 }
621 }
622
623 spec fn first_index_helper(self, needle: A) -> int
625 recommends
626 self.contains(needle),
627 decreases self.len(),
628 {
629 if self.len() <= 0 {
630 -1 } else if self[0] == needle {
633 0
634 } else {
635 1 + self.subrange(1, self.len() as int).first_index_helper(needle)
636 }
637 }
638
639 pub proof fn index_of_first_ensures(self, needle: A)
640 ensures
641 match self.index_of_first(needle) {
642 Some(index) => {
643 &&& self.contains(needle)
644 &&& 0 <= index < self.len()
645 &&& self[index] == needle
646 &&& forall|j: int| 0 <= j < index < self.len() ==> self[j] != needle
647 },
648 None => { !self.contains(needle) },
649 },
650 decreases self.len(),
651 {
652 if self.contains(needle) {
653 let index = self.index_of_first(needle).unwrap();
654 if self.len() <= 0 {
655 } else if self[0] == needle {
656 } else {
657 assert(Seq::empty().push(self.first()).add(self.drop_first()) =~= self);
658 self.drop_first().index_of_first_ensures(needle);
659 }
660 }
661 }
662
663 pub closed spec fn index_of_last(self, needle: A) -> Option<int> {
666 if self.contains(needle) {
667 Some(self.last_index_helper(needle))
668 } else {
669 None
670 }
671 }
672
673 spec fn last_index_helper(self, needle: A) -> int
675 recommends
676 self.contains(needle),
677 decreases self.len(),
678 {
679 if self.len() <= 0 {
680 -1 } else if self.last() == needle {
683 self.len() - 1
684 } else {
685 self.drop_last().last_index_helper(needle)
686 }
687 }
688
689 pub proof fn index_of_last_ensures(self, needle: A)
690 ensures
691 match self.index_of_last(needle) {
692 Some(index) => {
693 &&& self.contains(needle)
694 &&& 0 <= index < self.len()
695 &&& self[index] == needle
696 &&& forall|j: int| 0 <= index < j < self.len() ==> self[j] != needle
697 },
698 None => { !self.contains(needle) },
699 },
700 decreases self.len(),
701 {
702 if self.contains(needle) {
703 let index = self.index_of_last(needle).unwrap();
704 if self.len() <= 0 {
705 } else if self.last() == needle {
706 } else {
707 assert(self.drop_last().push(self.last()) =~= self);
708 self.drop_last().index_of_last_ensures(needle);
709 }
710 }
711 }
712
713 pub open spec fn drop_last(self) -> Seq<A>
718 recommends
719 self.len() >= 1,
720 {
721 self.subrange(0, self.len() as int - 1)
722 }
723
724 pub proof fn drop_last_distributes_over_add(a: Self, b: Self)
727 requires
728 0 < b.len(),
729 ensures
730 (a + b).drop_last() == a + b.drop_last(),
731 {
732 assert_seqs_equal!((a+b).drop_last(), a+b.drop_last());
733 }
734
735 pub open spec fn drop_first(self) -> Seq<A>
736 recommends
737 self.len() >= 1,
738 {
739 self.subrange(1, self.len() as int)
740 }
741
742 pub open spec fn no_duplicates(self) -> bool {
744 forall|i, j| (0 <= i < self.len() && 0 <= j < self.len() && i != j) ==> self[i] != self[j]
745 }
746
747 pub open spec fn disjoint(self, other: Self) -> bool {
749 forall|i: int, j: int| 0 <= i < self.len() && 0 <= j < other.len() ==> self[i] != other[j]
750 }
751
752 pub closed spec fn to_set(self) -> Set<A> {
754 Set::range(0, self.len() as int).map(|i| self.index(i))
755 }
756
757 pub broadcast proof fn to_set_ensures(self)
758 ensures
759 #![trigger(self.to_set())]
760 forall|i|
762 0 <= i < self.len() ==> #[trigger] self.to_set().contains(self[i]),
763 forall|a| #[trigger] self.to_set().contains(a) <==> self.contains(a),
765 {
766 broadcast use super::set::group_set_lemmas;
767 broadcast use super::set_lib::range_set_properties;
768
769 assert forall|i| 0 <= i < self.len() implies #[trigger] self.to_set().contains(self[i]) by {
770 Set::range(0, self.len() as int).lemma_map_contains(|i: int| self.index(i), self[i]);
771 assert(Set::range(0, self.len() as int).contains(i));
772 assert(self.to_set().contains(self[i]));
773 }
774 assert forall|a| #[trigger] self.to_set().contains(a) <==> self.contains(a) by {
775 Set::range(0, self.len() as int).lemma_map_contains(|i: int| self.index(i), a);
776 if self.to_set().contains(a) {
777 let i = choose|i: int| #[trigger]
778 Set::range(0, self.len() as int).contains(i) && self.index(i) == a;
779 assert(0 <= i < self.len());
780 assert(self.contains(a));
781 }
782 if self.contains(a) {
783 let i = choose|i: int| 0 <= i < self.len() && self[i] == a;
784 assert(self.to_set().contains(self[i]));
785 assert(a == self[i]);
786 }
787 }
788 }
789
790 pub open spec fn to_iset(self) -> ISet<A> {
791 self.to_set().to_iset()
792 }
793
794 pub closed spec fn to_multiset(self) -> Multiset<A>
796 decreases self.len(),
797 {
798 if self.len() == 0 {
799 Multiset::<A>::empty()
800 } else {
801 Multiset::<A>::empty().insert(self.first()).add(self.drop_first().to_multiset())
802 }
803 }
804
805 pub broadcast proof fn to_multiset_ensures(self)
809 ensures
810 forall|a: A| #[trigger] (self.push(a).to_multiset()) =~= self.to_multiset().insert(a), forall|i: int|
812 0 <= i < self.len() ==> #[trigger] (self.remove(i).to_multiset())
813 =~= self.to_multiset().remove(self[i]), self.len() == #[trigger] self.to_multiset().len(), forall|a: A|
816 self.contains(a) <==> #[trigger] self.to_multiset().count(a)
817 > 0, {
819 broadcast use group_seq_properties;
820
821 }
822
823 pub open spec fn insert(self, i: int, a: A) -> Seq<A>
825 recommends
826 0 <= i <= self.len(),
827 {
828 self.subrange(0, i).push(a) + self.subrange(i, self.len() as int)
829 }
830
831 pub proof fn insert_ensures(self, pos: int, elt: A)
833 requires
834 0 <= pos <= self.len(),
835 ensures
836 self.insert(pos, elt).len() == self.len() + 1,
837 forall|i: int| 0 <= i < pos ==> #[trigger] self.insert(pos, elt)[i] == self[i],
838 forall|i: int| pos <= i < self.len() ==> self.insert(pos, elt)[i + 1] == self[i],
839 self.insert(pos, elt)[pos] == elt,
840 {
841 }
842
843 pub open spec fn remove(self, i: int) -> Seq<A>
845 recommends
846 0 <= i < self.len(),
847 {
848 self.subrange(0, i) + self.subrange(i + 1, self.len() as int)
849 }
850
851 pub proof fn remove_ensures(self, i: int)
853 requires
854 0 <= i < self.len(),
855 ensures
856 self.remove(i).len() == self.len() - 1,
857 forall|index: int| 0 <= index < i ==> #[trigger] self.remove(i)[index] == self[index],
858 forall|index: int|
859 i <= index < self.len() - 1 ==> #[trigger] self.remove(i)[index] == self[index + 1],
860 {
861 }
862
863 pub open spec fn remove_value(self, val: A) -> Seq<A> {
866 let index = self.index_of_first(val);
867 match index {
868 Some(i) => self.remove(i),
869 None => self,
870 }
871 }
872
873 pub open spec fn reverse(self) -> Seq<A>
875 decreases self.len(),
876 {
877 if self.len() == 0 {
878 Seq::empty()
879 } else {
880 Seq::new(self.len(), |i: int| self[self.len() - 1 - i])
881 }
882 }
883
884 pub open spec fn zip_with<B>(self, other: Seq<B>) -> Seq<(A, B)>
887 recommends
888 self.len() == other.len(),
889 decreases self.len(),
890 {
891 if self.len() != other.len() {
892 Seq::empty()
893 } else if self.len() == 0 {
894 Seq::empty()
895 } else {
896 Seq::new(self.len(), |i: int| (self[i], other[i]))
897 }
898 }
899
900 pub open spec fn fold_left<B>(self, b: B, f: spec_fn(B, A) -> B) -> (res: B)
907 decreases self.len(),
908 {
909 if self.len() == 0 {
910 b
911 } else {
912 f(self.drop_last().fold_left(b, f), self.last())
913 }
914 }
915
916 pub open spec fn fold_left_alt<B>(self, b: B, f: spec_fn(B, A) -> B) -> (res: B)
920 decreases self.len(),
921 {
922 if self.len() == 0 {
923 b
924 } else {
925 self.subrange(1, self.len() as int).fold_left_alt(f(b, self[0]), f)
926 }
927 }
928
929 pub broadcast proof fn lemma_fold_left_split<B>(self, b: B, f: spec_fn(B, A) -> B, k: int)
931 requires
932 0 <= k <= self.len(),
933 ensures
934 self.subrange(k, self.len() as int).fold_left(
935 (#[trigger] self.subrange(0, k).fold_left(b, f)),
936 f,
937 ) == self.fold_left(b, f),
938 decreases self.len(),
939 {
940 reveal_with_fuel(Seq::fold_left, 2);
941 if k == self.len() {
942 assert(self.subrange(0, self.len() as int) == self);
943 } else {
944 self.drop_last().lemma_fold_left_split(b, f, k);
945 assert_seqs_equal!(
946 self.drop_last().subrange(k, self.drop_last().len() as int) ==
947 self.subrange(k, self.len()-1)
948 );
949 assert_seqs_equal!(
950 self.drop_last().subrange(0, k) ==
951 self.subrange(0, k)
952 );
953 assert_seqs_equal!(
954 self.subrange(k, self.len() as int).drop_last() ==
955 self.subrange(k, self.len() - 1)
956 );
957 }
958 }
959
960 proof fn aux_lemma_fold_left_alt<B>(self, b: B, f: spec_fn(B, A) -> B, k: int)
962 requires
963 0 < k <= self.len(),
964 ensures
965 self.subrange(k, self.len() as int).fold_left_alt(
966 self.subrange(0, k).fold_left_alt(b, f),
967 f,
968 ) == self.fold_left_alt(b, f),
969 decreases k,
970 {
971 reveal_with_fuel(Seq::fold_left_alt, 2);
972 if k == 1 {
973 } else {
975 self.subrange(1, self.len() as int).aux_lemma_fold_left_alt(f(b, self[0]), f, k - 1);
976 assert_seqs_equal!(
977 self.subrange(1, self.len() as int)
978 .subrange(k - 1, self.subrange(1, self.len() as int).len() as int) ==
979 self.subrange(k, self.len() as int)
980 );
981 assert_seqs_equal!(
982 self.subrange(1, self.len() as int).subrange(0, k - 1) ==
983 self.subrange(1, k)
984 );
985 assert_seqs_equal!(
986 self.subrange(0, k).subrange(1, self.subrange(0, k).len() as int) ==
987 self.subrange(1, k)
988 );
989 }
990 }
991
992 pub proof fn lemma_fold_left_alt<B>(self, b: B, f: spec_fn(B, A) -> B)
994 ensures
995 self.fold_left(b, f) == self.fold_left_alt(b, f),
996 decreases self.len(),
997 {
998 reveal_with_fuel(Seq::fold_left, 2);
999 reveal_with_fuel(Seq::fold_left_alt, 2);
1000 if self.len() <= 1 {
1001 } else {
1003 self.aux_lemma_fold_left_alt(b, f, self.len() - 1);
1004 self.subrange(self.len() - 1, self.len() as int).lemma_fold_left_alt(
1005 self.drop_last().fold_left_alt(b, f),
1006 f,
1007 );
1008 self.subrange(0, self.len() - 1).lemma_fold_left_alt(b, f);
1009 }
1010 }
1011
1012 pub proof fn lemma_reverse_fold_left<B>(self, v: B, f: spec_fn(B, A) -> B)
1015 ensures
1016 self.reverse().fold_left(v, f) == self.fold_right(|a: A, b: B| f(b, a), v),
1017 {
1018 assert(self.reverse().reverse() =~= self);
1019 let g = |a: A, b: B| f(b, a);
1020 assert(f =~= |b: B, a: A| g(a, b));
1021 self.reverse().lemma_reverse_fold_right(v, |a: A, b: B| f(b, a))
1022 }
1023
1024 pub open spec fn fold_right<B>(self, f: spec_fn(A, B) -> B, b: B) -> (res: B)
1031 decreases self.len(),
1032 {
1033 if self.len() == 0 {
1034 b
1035 } else {
1036 self.drop_last().fold_right(f, f(self.last(), b))
1037 }
1038 }
1039
1040 pub open spec fn fold_right_alt<B>(self, f: spec_fn(A, B) -> B, b: B) -> (res: B)
1044 decreases self.len(),
1045 {
1046 if self.len() == 0 {
1047 b
1048 } else {
1049 f(self[0], self.subrange(1, self.len() as int).fold_right_alt(f, b))
1050 }
1051 }
1052
1053 pub broadcast proof fn lemma_fold_right_split<B>(self, f: spec_fn(A, B) -> B, b: B, k: int)
1055 requires
1056 0 <= k <= self.len(),
1057 ensures
1058 self.subrange(0, k).fold_right(
1059 f,
1060 (#[trigger] self.subrange(k, self.len() as int).fold_right(f, b)),
1061 ) == self.fold_right(f, b),
1062 decreases self.len(),
1063 {
1064 reveal_with_fuel(Seq::fold_right, 2);
1065 if k == self.len() {
1066 assert(self.subrange(0, k) == self);
1067 } else if k == self.len() - 1 {
1068 } else {
1070 self.subrange(0, self.len() - 1).lemma_fold_right_split(f, f(self.last(), b), k);
1071 assert_seqs_equal!(
1072 self.subrange(0, self.len() - 1).subrange(0, k) ==
1073 self.subrange(0, k)
1074 );
1075 assert_seqs_equal!(
1076 self.subrange(0, self.len() - 1).subrange(k, self.subrange(0, self.len() - 1).len() as int) ==
1077 self.subrange(k, self.len() - 1)
1078 );
1079 assert_seqs_equal!(
1080 self.subrange(k, self.len() as int).drop_last() ==
1081 self.subrange(k, self.len() - 1)
1082 );
1083 }
1084 }
1085
1086 pub proof fn lemma_fold_right_commute_one<B>(self, a: A, f: spec_fn(A, B) -> B, v: B)
1088 requires
1089 commutative_foldr(f),
1090 ensures
1091 self.fold_right(f, f(a, v)) == f(a, self.fold_right(f, v)),
1092 decreases self.len(),
1093 {
1094 if self.len() > 0 {
1095 self.drop_last().lemma_fold_right_commute_one(a, f, f(self.last(), v));
1096 }
1097 }
1098
1099 pub proof fn lemma_fold_right_alt<B>(self, f: spec_fn(A, B) -> B, b: B)
1101 ensures
1102 self.fold_right(f, b) == self.fold_right_alt(f, b),
1103 decreases self.len(),
1104 {
1105 reveal_with_fuel(Seq::fold_right, 2);
1106 reveal_with_fuel(Seq::fold_right_alt, 2);
1107 if self.len() <= 1 {
1108 } else {
1110 self.subrange(1, self.len() as int).lemma_fold_right_alt(f, b);
1111 self.lemma_fold_right_split(f, b, 1);
1112 }
1113 }
1114
1115 pub proof fn lemma_reverse_fold_right<B>(self, v: B, f: spec_fn(A, B) -> B)
1118 ensures
1119 self.reverse().fold_right(f, v) == self.fold_left(v, |b: B, a: A| f(a, b)),
1120 decreases self.len(),
1121 {
1122 let g = |b: B, a: A| f(a, b);
1123 if self.len() > 0 {
1124 let last = self.last();
1125 let s0 = self.drop_last();
1126 assert(self.reverse() =~= seq![last] + s0.reverse());
1127 let res1 = self.reverse().fold_right(f, v);
1128 let res2 = self.fold_left(v, g);
1129 assert(res1 == self.reverse().fold_right_alt(f, v)) by {
1130 self.reverse().lemma_fold_right_alt(f, v)
1131 }
1132 assert(res2 == g(s0.fold_left(v, g), last));
1133 assert(self.reverse().first() == last);
1134 assert(self.reverse().subrange(1, self.reverse().len() as int) =~= s0.reverse());
1135 assert(res1 == f(last, s0.reverse().fold_right_alt(f, v)));
1136 assert(res1 == f(last, s0.reverse().fold_right(f, v))) by {
1137 s0.reverse().lemma_fold_right_alt(f, v)
1138 }
1139 assert(res2 == g(s0.fold_left(v, g), last));
1140 s0.lemma_reverse_fold_right(v, f);
1141 }
1142 }
1143
1144 pub proof fn lemma_multiset_has_no_duplicates(self)
1148 requires
1149 self.no_duplicates(),
1150 ensures
1151 forall|x: A| self.to_multiset().contains(x) ==> self.to_multiset().count(x) == 1,
1152 decreases self.len(),
1153 {
1154 broadcast use super::multiset::group_multiset_axioms;
1155
1156 if self.len() == 0 {
1157 assert(forall|x: A|
1158 self.to_multiset().contains(x) ==> self.to_multiset().count(x) == 1);
1159 } else {
1160 broadcast use group_seq_properties;
1161
1162 assert(self.drop_last().push(self.last()) =~= self);
1163 self.drop_last().lemma_multiset_has_no_duplicates();
1164 }
1165 }
1166
1167 pub proof fn lemma_multiset_has_no_duplicates_conv(self)
1170 requires
1171 forall|x: A| self.to_multiset().contains(x) ==> self.to_multiset().count(x) == 1,
1172 ensures
1173 self.no_duplicates(),
1174 {
1175 broadcast use super::multiset::group_multiset_axioms;
1176
1177 assert forall|i, j| (0 <= i < self.len() && 0 <= j < self.len() && i != j) implies self[i]
1178 != self[j] by {
1179 let mut a = if (i < j) {
1180 i
1181 } else {
1182 j
1183 };
1184 let mut b = if (i < j) {
1185 j
1186 } else {
1187 i
1188 };
1189
1190 if (self[a] == self[b]) {
1191 let s0 = self.subrange(0, b);
1192 let s1 = self.subrange(b, self.len() as int);
1193 assert(self == s0 + s1);
1194
1195 broadcast use group_to_multiset_ensures;
1196
1197 lemma_multiset_commutative(s0, s1);
1198 assert(self.to_multiset().count(self[a]) >= 2);
1199 }
1200 }
1201 }
1202
1203 pub proof fn lemma_reverse_to_multiset(self)
1205 ensures
1206 self.reverse().to_multiset() =~= self.to_multiset(),
1207 decreases self.len(),
1208 {
1209 broadcast use group_seq_properties;
1210 broadcast use super::multiset::group_multiset_axioms;
1211
1212 if self.len() > 0 {
1213 let s2 = self.drop_first();
1214 let e = self.first();
1215 assert(self =~= seq![e] + s2);
1216 assert(self.to_multiset() =~= seq![e].to_multiset().add(s2.to_multiset())) by {
1217 lemma_multiset_commutative(seq![e], s2)
1218 }
1219 assert(self.reverse() =~= s2.reverse().push(e));
1220 assert(self.reverse().to_multiset() =~= s2.reverse().to_multiset().insert(e));
1221 s2.lemma_reverse_to_multiset();
1222 }
1223 }
1224
1225 pub proof fn lemma_add_last_back(self)
1229 requires
1230 0 < self.len(),
1231 ensures
1232 #[trigger] self.drop_last().push(self.last()) =~= self,
1233 {
1234 }
1235
1236 pub proof fn lemma_indexing_implies_membership(self, f: spec_fn(A) -> bool)
1241 requires
1242 forall|i: int| 0 <= i < self.len() ==> #[trigger] f(#[trigger] self[i]),
1243 ensures
1244 forall|x: A| #[trigger] self.contains(x) ==> #[trigger] f(x),
1245 {
1246 assert(forall|i: int| 0 <= i < self.len() ==> #[trigger] self.contains(self[i]));
1247 }
1248
1249 pub proof fn lemma_membership_implies_indexing(self, f: spec_fn(A) -> bool)
1254 requires
1255 forall|x: A| #[trigger] self.contains(x) ==> #[trigger] f(x),
1256 ensures
1257 forall|i: int| 0 <= i < self.len() ==> #[trigger] f(self[i]),
1258 {
1259 assert forall|i: int| 0 <= i < self.len() implies #[trigger] f(self[i]) by {
1260 assert(self.contains(self[i]));
1261 }
1262 }
1263
1264 pub proof fn lemma_split_at(self, pos: int)
1268 requires
1269 0 <= pos <= self.len(),
1270 ensures
1271 self.subrange(0, pos) + self.subrange(pos, self.len() as int) =~= self,
1272 {
1273 }
1274
1275 pub proof fn lemma_element_from_slice(self, new: Seq<A>, a: int, b: int, pos: int)
1277 requires
1278 0 <= a <= b <= self.len(),
1279 new == self.subrange(a, b),
1280 a <= pos < b,
1281 ensures
1282 pos - a < new.len(),
1283 new[pos - a] == self[pos],
1284 {
1285 }
1286
1287 pub proof fn lemma_slice_of_slice(self, s1: int, e1: int, s2: int, e2: int)
1290 requires
1291 0 <= s1 <= e1 <= self.len(),
1292 0 <= s2 <= e2 <= e1 - s1,
1293 ensures
1294 self.subrange(s1, e1).subrange(s2, e2) =~= self.subrange(s1 + s2, s1 + e2),
1295 {
1296 }
1297
1298 pub proof fn unique_seq_to_set(self)
1300 requires
1301 self.no_duplicates(),
1302 ensures
1303 self.len() == self.to_set().len(),
1304 decreases self.len(),
1305 {
1306 broadcast use super::set::group_set_lemmas;
1307
1308 seq_to_set_equal_rec::<A>(self);
1309 if self.len() == 0 {
1310 } else {
1311 let rest = self.drop_last();
1312 rest.unique_seq_to_set();
1313 seq_to_set_equal_rec::<A>(rest);
1314 assert(!rest.contains(self.last()));
1315 assert(!seq_to_set_rec(rest).contains(self.last())) by {
1316 seq_to_set_rec_contains::<A>(rest);
1317 }
1318 assert(seq_to_set_rec(rest).insert(self.last()).len() == seq_to_set_rec(rest).len()
1319 + 1);
1320 }
1321 }
1322
1323 pub proof fn lemma_cardinality_of_set(self)
1326 ensures
1327 self.to_set().len() <= self.len(),
1328 {
1329 broadcast use super::set_lib::range_set_properties;
1330
1331 super::set_lib::lemma_map_size_bound::<int, A>(
1332 Set::range(0, self.len() as int),
1333 self.to_set(),
1334 |i: int| self.index(i),
1335 );
1336 }
1337
1338 pub proof fn lemma_cardinality_of_empty_set_is_0(self)
1341 ensures
1342 self.to_set().len() == 0 <==> self.len() == 0,
1343 {
1344 broadcast use super::set::group_set_lemmas;
1345
1346 self.to_set_ensures();
1347
1348 assert(self.len() == 0 ==> self.to_set().len() == 0) by { self.lemma_cardinality_of_set() }
1349 assert(!(self.len() == 0) ==> !(self.to_set().len() == 0)) by {
1350 if self.len() > 0 {
1351 assert(self.to_set().contains(self[0]));
1352 assert(self.to_set().remove(self[0]).len() <= self.to_set().len());
1353 }
1354 }
1355 }
1356
1357 pub proof fn lemma_no_dup_set_cardinality(self)
1360 requires
1361 self.to_set().len() == self.len(),
1362 ensures
1363 self.no_duplicates(),
1364 decreases self.len(),
1365 {
1366 broadcast use super::set::group_set_lemmas;
1367
1368 self.to_set_ensures();
1369 self.drop_first().to_set_ensures();
1370
1371 if self.len() == 0 {
1372 } else {
1373 assert(self =~= Seq::empty().push(self.first()).add(self.drop_first()));
1374 if self.drop_first().contains(self.first()) {
1375 assert(self.to_set() =~= self.drop_first().to_set());
1377 assert(self.to_set().len() <= self.drop_first().len()) by {
1378 self.drop_first().lemma_cardinality_of_set()
1379 }
1380 } else {
1381 assert(self.to_set().len() == 1 + self.drop_first().to_set().len()) by {
1382 assert(self.drop_first().to_set().insert(self.first()) =~= self.to_set());
1383 }
1384 self.drop_first().lemma_no_dup_set_cardinality();
1385 }
1386 }
1387 }
1388
1389 pub broadcast proof fn lemma_to_set_map_commutes<B>(self, f: spec_fn(A) -> B)
1392 ensures
1393 #[trigger] self.to_set().map(f) =~= self.map_values(f).to_set(),
1394 {
1395 broadcast use crate::vstd::group_vstd_default;
1396
1397 assert forall|elem: B|
1398 self.to_set().map(f).contains(elem) <==> self.map_values(f).to_set().contains(elem) by {
1399 if self.to_set().map(f).contains(elem) {
1400 let x = choose|x: A| self.to_set().contains(x) && f(x) == elem;
1401 let i = choose|i: int| 0 <= i < self.len() && self[i] == x;
1402 assert(self.map_values(f)[i] == elem);
1403 }
1404 if self.map_values(f).to_set().contains(elem) {
1405 let i = choose|i: int|
1406 0 <= i < self.map_values(f).len() && self.map_values(f)[i] == elem;
1407 let x = self[i];
1408 assert(self.to_set().contains(x));
1409 }
1410 };
1411 }
1412
1413 pub broadcast proof fn lemma_to_iset_map_commutes<B>(self, f: spec_fn(A) -> B)
1416 ensures
1417 #[trigger] self.to_iset().map(f) =~= self.map_values(f).to_iset(),
1418 {
1419 broadcast use crate::vstd::group_vstd_default;
1420
1421 assert forall|elem: B|
1422 self.to_iset().map(f).contains(elem) <==> self.map_values(f).to_iset().contains(
1423 elem,
1424 ) by {
1425 if self.to_iset().map(f).contains(elem) {
1426 let x = choose|x: A| self.to_iset().contains(x) && f(x) == elem;
1427 let i = choose|i: int| 0 <= i < self.len() && self[i] == x;
1428 assert(self.map_values(f)[i] == elem);
1429 }
1430 if self.map_values(f).to_iset().contains(elem) {
1431 let i = choose|i: int|
1432 0 <= i < self.map_values(f).len() && self.map_values(f)[i] == elem;
1433 let x = self[i];
1434 assert(self.to_iset().contains(x));
1435 }
1436 };
1437 }
1438
1439 pub broadcast proof fn lemma_to_set_insert_commutes(sq: Seq<A>, elt: A)
1442 ensures
1443 #[trigger] (sq + seq![elt]).to_set() =~= sq.to_set().insert(elt),
1444 {
1445 broadcast use crate::vstd::group_vstd_default;
1446 broadcast use lemma_seq_concat_contains_all_elements;
1447 broadcast use lemma_seq_empty_contains_nothing;
1448 broadcast use lemma_seq_contains_after_push;
1449 broadcast use super::seq::group_seq_lemmas;
1450 broadcast use super::set_lib::group_set_properties;
1451
1452 }
1453
1454 pub broadcast proof fn lemma_to_iset_insert_commutes(sq: Seq<A>, elt: A)
1457 ensures
1458 #[trigger] (sq + seq![elt]).to_iset() =~= sq.to_iset().insert(elt),
1459 {
1460 broadcast use crate::vstd::group_vstd_default;
1461 broadcast use lemma_seq_concat_contains_all_elements;
1462 broadcast use lemma_seq_empty_contains_nothing;
1463 broadcast use lemma_seq_contains_after_push;
1464 broadcast use super::seq::group_seq_lemmas;
1465 broadcast use super::set_lib::group_set_properties;
1466
1467 }
1468
1469 pub open spec fn update_subrange_with(self, off: int, vs: Self) -> Self
1473 recommends
1474 0 <= off,
1475 off + vs.len() <= self.len(),
1476 {
1477 Seq::new(
1478 self.len(),
1479 |i: int|
1480 if off <= i < off + vs.len() {
1481 vs[i - off]
1482 } else {
1483 self[i]
1484 },
1485 )
1486 }
1487
1488 pub broadcast proof fn lemma_seq_skip_skip(self, i: int)
1500 ensures
1501 0 <= i < self.len() ==> (self.skip(i)).skip(1) =~= #[trigger] self.skip(i + 1),
1502 {
1503 broadcast use group_seq_properties;
1504
1505 }
1506
1507 pub proof fn lemma_contains_to_index(self, elem: A) -> (idx: int)
1520 requires
1521 self.contains(elem),
1522 ensures
1523 0 <= idx < self.len() && self[idx] == elem,
1524 decreases self.len(),
1525 {
1526 broadcast use group_seq_properties;
1527
1528 if self[0] == elem {
1529 0
1530 } else {
1531 let i = self.skip(1).lemma_contains_to_index(elem);
1532 i + 1
1533 }
1534 }
1535
1536 pub proof fn lemma_all_from_head_tail(self, pred: spec_fn(A) -> bool)
1552 requires
1553 self.len() > 0,
1554 pred(self[0]) && self.skip(1).all(|x| pred(x)),
1555 ensures
1556 self.all(|x| pred(x)),
1557 {
1558 broadcast use group_seq_properties;
1559
1560 assert(seq![self[0]] + self.skip(1) == self);
1561 }
1562
1563 pub proof fn lemma_any_tail(self, pred: spec_fn(A) -> bool)
1579 requires
1580 self.any(|x| pred(x)),
1581 ensures
1582 !pred(self[0]) ==> self.skip(1).any(|x| pred(x)),
1583 {
1584 broadcast use group_seq_properties;
1585
1586 }
1587
1588 pub open spec fn remove_duplicates(self, seen: Seq<A>) -> Seq<A>
1606 decreases self.len(),
1607 {
1608 if self.len() == 0 {
1609 seen
1610 } else if seen.contains(self[0]) {
1611 self.skip(1).remove_duplicates(seen)
1612 } else {
1613 self.skip(1).remove_duplicates(seen + seq![self[0]])
1614 }
1615 }
1616
1617 pub broadcast proof fn lemma_remove_duplicates_properties(self, seen: Seq<A>)
1635 ensures
1636 forall|x|
1637 (self + seen).contains(x) <==> #[trigger] self.remove_duplicates(seen).contains(x),
1638 #[trigger] self.remove_duplicates(seen).len() <= self.len() + seen.len(),
1639 decreases self.len(),
1640 {
1641 broadcast use group_seq_properties;
1642
1643 if self.len() == 0 {
1644 } else if seen.contains(self[0]) {
1645 let rest = self.skip(1);
1646 rest.lemma_remove_duplicates_properties(seen);
1647 } else {
1648 let rest = self.skip(1);
1649 rest.lemma_remove_duplicates_properties(seen + seq![self[0]]);
1650 }
1651 }
1652
1653 pub proof fn lemma_remove_duplicates_append_index(self, i: int, seen: Seq<A>)
1669 requires
1670 0 <= i < self.len(),
1671 ensures
1672 self.remove_duplicates(seen) == self.skip(i).remove_duplicates(
1673 self.take(i).remove_duplicates(seen),
1674 ),
1675 decreases self.len(),
1676 {
1677 broadcast use {
1678 group_seq_properties,
1679 lemma_seq_skip_of_skip,
1680 Seq::lemma_remove_duplicates_properties,
1681 };
1682
1683 if i == 0 {
1684 } else if i == self.len() {
1685 assert(self.take(i) == self);
1686 } else {
1687 assert(self.skip(1).take(i - 1) == self.subrange(1, i));
1688 assert(self.take(i).skip(1) == self.subrange(1, i));
1689 assert(self.skip(1).take(i - 1) == self.take(i).skip(1));
1690 if seen.contains(self[0]) {
1691 self.skip(1).lemma_remove_duplicates_append_index(i - 1, seen);
1692 } else {
1693 self.skip(1).lemma_remove_duplicates_append_index(i - 1, seen + seq![self[0]]);
1694 }
1695 }
1696 }
1697
1698 proof fn lemma_skip1_concat(xs: Seq<A>, ys: Seq<A>)
1713 requires
1714 xs.len() > 0,
1715 ensures
1716 (xs + ys).skip(1) == xs.skip(1) + ys,
1717 {
1718 broadcast use group_seq_properties;
1719
1720 assert((xs + ys).skip(1) == xs.skip(1) + ys);
1721 }
1722
1723 pub proof fn lemma_remove_duplicates_append(self, x: A, seen: Seq<A>)
1739 ensures
1740 (self + seen).contains(x) ==> (self + seq![x]).remove_duplicates(seen)
1741 == self.remove_duplicates(seen),
1742 !(self + seen).contains(x) ==> (self + seq![x]).remove_duplicates(seen)
1743 == self.remove_duplicates(seen) + seq![x],
1744 decreases self.len(),
1745 {
1746 broadcast use group_seq_properties;
1747
1748 reveal_with_fuel(Seq::remove_duplicates, 2);
1749
1750 if self.len() != 0 {
1751 let head = self[0];
1752 let tail = self.skip(1);
1753
1754 let seen2 = if seen.contains(head) {
1755 seen
1756 } else {
1757 seen + seq![head]
1758 };
1759 tail.lemma_remove_duplicates_append(x, seen2);
1760 assert((self + seq![x]).skip(1) == tail + seq![x]) by {
1761 Seq::lemma_skip1_concat(self, seq![x]);
1762 };
1763 }
1764 }
1765
1766 pub proof fn lemma_all_neg_filter_empty(self, pred: spec_fn(A) -> bool)
1779 requires
1780 self.all(|x: A| !pred(x)),
1781 ensures
1782 self.filter(pred).len() == 0,
1783 decreases self.len(),
1784 {
1785 broadcast use group_seq_properties;
1786
1787 reveal(Seq::filter);
1788 if self.len() != 0 {
1789 let rest = self.drop_last();
1790 rest.lemma_all_neg_filter_empty(pred);
1791 rest.lemma_filter_len_push(pred, self.last());
1792 let neg_pred = |x| !pred(x);
1793 assert(neg_pred(self.last()));
1794 }
1795 }
1796
1797 pub open spec fn filter_map<B>(self, f: spec_fn(A) -> Option<B>) -> Seq<B>
1806 decreases self.len(),
1807 {
1808 if self.len() == 0 {
1812 Seq::empty()
1813 } else {
1814 let rest = self.drop_last();
1815 match f(self.last()) {
1816 Option::Some(s) => rest.filter_map(f) + seq![s],
1817 Option::None => rest.filter_map(f),
1818 }
1819 }
1820 }
1821
1822 pub broadcast proof fn lemma_filter_contains_rev(self, p: spec_fn(A) -> bool, elem: A)
1826 requires
1827 #[trigger] self.filter(p).contains(elem),
1828 ensures
1829 self.contains(elem),
1830 decreases self.len(),
1831 {
1832 broadcast use group_seq_properties;
1833
1834 reveal(Seq::filter);
1835 if self.len() == 0 {
1836 } else {
1837 let rest = self.drop_last();
1838 let last = self.last();
1839 if !p(last) || last != elem {
1840 rest.lemma_filter_contains_rev(p, elem);
1841 }
1842 }
1843 }
1844
1845 pub broadcast proof fn lemma_filter_map_contains<B>(self, f: spec_fn(A) -> Option<B>, elt: B)
1849 requires
1850 #[trigger] self.filter_map(f).contains(elt),
1851 ensures
1852 exists|t: A| #[trigger] self.contains(t) && f(t) == Some(elt),
1853 decreases self.len(),
1854 {
1855 broadcast use group_seq_properties;
1856
1857 if self.len() == 0 {
1858 } else {
1859 let last = self.last();
1860 let rest = self.drop_last();
1861 if f(last) == Some(elt) {
1862 assert(self.contains(last));
1863 } else {
1864 rest.lemma_filter_map_contains(f, elt);
1865 let t = choose|t: A| #[trigger] rest.contains(t) && f(t) == Some(elt);
1866 assert(self.contains(t));
1867 }
1868 }
1869 }
1870
1871 pub proof fn lemma_take_succ(xs: Seq<A>, k: int)
1880 requires
1881 0 <= k < xs.len(),
1882 ensures
1883 xs.take(k + 1) =~= xs.take(k) + seq![xs[k]],
1884 {
1885 broadcast use group_seq_properties;
1886
1887 }
1888
1889 pub proof fn lemma_filter_map_singleton<B>(a: A, f: spec_fn(A) -> Option<B>)
1893 ensures
1894 seq![a].filter_map(f) =~= match f(a) {
1895 Option::Some(b) => seq![b],
1896 Option::None => Seq::empty(),
1897 },
1898 {
1899 reveal_with_fuel(Seq::filter_map, 2);
1900 }
1901
1902 pub broadcast proof fn lemma_filter_map_take_succ<B>(self, f: spec_fn(A) -> Option<B>, i: int)
1914 requires
1915 0 <= i < self.len(),
1916 ensures
1917 #[trigger] self.take(i + 1).filter_map(f) =~= self.take(i).filter_map(f) + (match f(
1918 self[i],
1919 ) {
1920 Option::Some(s) => seq![s],
1921 Option::None => Seq::empty(),
1922 }),
1923 decreases self.len(),
1924 {
1925 broadcast use group_seq_properties;
1926
1927 if i != 0 {
1928 self.drop_last().lemma_filter_map_take_succ(f, i - 1);
1929 assert(self.take(i + 1).drop_last() == self.take(i));
1930 }
1931 }
1932
1933 pub open spec fn filter_alt(self, p: spec_fn(A) -> bool) -> Seq<A> {
1936 if self.len() == 0 {
1937 Seq::empty()
1938 } else {
1939 let rest = self.drop_first().filter(p);
1940 let first = self.first();
1941 if p(first) {
1942 seq![first] + rest
1943 } else {
1944 rest
1945 }
1946 }
1947 }
1948
1949 pub broadcast proof fn lemma_filter_prepend(self, x: A, p: spec_fn(A) -> bool)
1964 ensures
1965 #[trigger] (seq![x] + self).filter(p) == (if p(x) {
1966 seq![x]
1967 } else {
1968 Seq::empty()
1969 }) + self.filter(p),
1970 decreases self.len(),
1971 {
1972 broadcast use group_seq_properties;
1973
1974 reveal(Seq::filter);
1975 let lhs = (seq![x] + self).filter(p);
1976 let rhs = (if p(x) {
1977 seq![x]
1978 } else {
1979 Seq::empty()
1980 }) + self.filter(p);
1981
1982 if self.len() == 0 {
1983 assert(lhs =~= rhs);
1984 } else {
1985 let tail_seq = if p(self.last()) {
1986 seq![self.last()]
1987 } else {
1988 Seq::empty()
1989 };
1990
1991 assert(((seq![x] + self).drop_last()) =~= seq![x] + self.drop_last());
1992 let sub = (seq![x] + self.drop_last()).filter(p);
1993 assert(lhs =~= sub + tail_seq);
1994 assert(rhs =~= (if p(x) {
1995 seq![x]
1996 } else {
1997 Seq::empty()
1998 }) + self.drop_last().filter(p) + tail_seq);
1999 self.drop_last().lemma_filter_prepend(x, p);
2000 }
2001 }
2002
2003 pub proof fn lemma_filter_eq_filter_alt(self, p: spec_fn(A) -> bool)
2005 ensures
2006 self.filter(p) =~= self.filter_alt(p),
2007 decreases self.len(),
2008 {
2009 broadcast use group_seq_properties;
2010 broadcast use Seq::lemma_filter_prepend;
2011
2012 reveal(Seq::filter);
2013 if self.len() == 0 {
2014 } else {
2015 let first = self.first();
2016 let but_first = self.drop_first();
2017 assert(self =~= seq![first] + but_first);
2018 self.drop_first().lemma_filter_eq_filter_alt(p);
2019 }
2020 }
2021
2022 pub proof fn lemma_filter_monotone(self, ys: Seq<A>, p: spec_fn(A) -> bool)
2037 requires
2038 self.is_prefix_of(ys),
2039 ensures
2040 self.filter(p).is_prefix_of(ys.filter(p)),
2041 decreases self.len(),
2042 {
2043 broadcast use group_seq_properties;
2044
2045 self.lemma_filter_eq_filter_alt(p);
2046 ys.lemma_filter_eq_filter_alt(p);
2047 if self.len() == 0 {
2048 } else {
2049 self.drop_first().lemma_filter_monotone(ys.drop_first(), p);
2050 }
2051 }
2052
2053 pub proof fn lemma_filter_take_len(self, p: spec_fn(A) -> bool, i: int)
2068 requires
2069 0 <= i <= self.len(),
2070 ensures
2071 self.filter(p).len() >= self.take(i).filter(p).len(),
2072 decreases i,
2073 {
2074 broadcast use group_seq_properties;
2075 broadcast use Seq::lemma_filter_len_push;
2076 broadcast use Seq::lemma_filter_push;
2077
2078 self.take(i).lemma_filter_monotone(self, p);
2079 }
2080
2081 pub broadcast proof fn lemma_filter_len_push(self, p: spec_fn(A) -> bool, elem: A)
2093 ensures
2094 #[trigger] self.push(elem).filter(p).len() == self.filter(p).len() + (if p(elem) {
2095 1int
2096 } else {
2097 0int
2098 }),
2099 {
2100 broadcast use group_seq_properties;
2101 broadcast use Seq::lemma_filter_push;
2102
2103 }
2104
2105 pub broadcast proof fn lemma_index_contains(self, i: int)
2108 requires
2109 0 <= i < self.len(),
2110 ensures
2111 self.contains(#[trigger] self[i]),
2112 {
2113 }
2114
2115 pub broadcast proof fn lemma_take_succ_push(self, i: int)
2118 requires
2119 0 <= i < self.len(),
2120 ensures
2121 #[trigger] self.take(i + 1) =~= self.take(i).push(self[i]),
2122 {
2123 broadcast use group_seq_properties;
2124
2125 }
2126
2127 pub broadcast proof fn lemma_take_len(self)
2129 ensures
2130 #[trigger] self.take(self.len() as int) == self,
2131 {
2132 broadcast use group_seq_properties;
2133
2134 }
2135
2136 pub broadcast proof fn lemma_take_any_succ(self, p: spec_fn(A) -> bool, i: int)
2149 requires
2150 0 <= i < self.len(),
2151 ensures
2152 #[trigger] self.take(i + 1).any(p) <==> self.take(i).any(p) || p(self[i]),
2153 {
2154 broadcast use group_seq_properties;
2155
2156 self.lemma_take_succ_push(i);
2157 if self.take(i + 1).any(p) {
2158 let x = choose|x: A| self.take(i + 1).contains(x) && #[trigger] p(x);
2159 assert(self.take(i).contains(x) || x == self[i]);
2160 }
2161 if self.take(i).any(p) {
2162 let x = choose|x: A| self.take(i).contains(x) && #[trigger] p(x);
2163 assert(self.take(i + 1).contains(x));
2164 }
2165 if p(self[i]) {
2166 assert(self.take(i + 1).contains(self[i]));
2167 }
2168 }
2169
2170 pub proof fn lemma_no_duplicates_injective<B>(self, f: spec_fn(A) -> B)
2182 requires
2183 injective(f),
2184 ensures
2185 self.no_duplicates() <==> self.map_values(f).no_duplicates(),
2186 {
2187 broadcast use group_seq_properties;
2188 broadcast use super::set_lib::group_set_properties;
2189
2190 let mapped = self.map_values(f);
2191 assert(mapped.len() == self.len());
2192 if mapped.no_duplicates() {
2193 assert forall|i: int, j: int| 0 <= i < j < mapped.len() implies self[i] != self[j] by {
2194 assert(mapped[i] == f(self[i]));
2195 assert(mapped[j] == f(self[j]));
2196 }
2197 }
2198 }
2199
2200 pub broadcast proof fn lemma_push_map_commute<B>(self, f: spec_fn(A) -> B, x: A)
2212 ensures
2213 self.map_values(f).push(f(x)) =~= #[trigger] self.push(x).map_values(f),
2214 decreases self.len(),
2215 {
2216 broadcast use group_seq_properties;
2217
2218 }
2219
2220 pub broadcast proof fn lemma_push_to_set_commute(self, elem: A)
2231 ensures
2232 #[trigger] self.push(elem).to_set() =~= self.to_set().insert(elem),
2233 {
2234 broadcast use {group_seq_properties, super::set::group_set_lemmas, Seq::to_set_ensures};
2235
2236 let lhs = self.push(elem).to_set();
2237 let rhs = self.to_set().insert(elem);
2238 assert forall|x: A| rhs.contains(x) implies lhs.contains(x) by {
2239 lemma_seq_contains_after_push(self, elem, x);
2240 }
2241 }
2242
2243 pub broadcast proof fn lemma_filter_push(self, elem: A, pred: spec_fn(A) -> bool)
2257 ensures
2258 #[trigger] self.push(elem).filter(pred) == if pred(elem) {
2259 self.filter(pred).push(elem)
2260 } else {
2261 self.filter(pred)
2262 },
2263 {
2264 broadcast use group_seq_properties;
2265
2266 reveal(Seq::filter);
2267 assert(self.push(elem).drop_last() =~= self);
2268 }
2269
2270 pub proof fn lemma_zip_with_contains_index<B>(self, b: Seq<B>, i: int)
2283 requires
2284 0 <= i < self.len(),
2285 self.len() == b.len(),
2286 ensures
2287 self.zip_with(b).contains((self[i], b[i])),
2288 {
2289 assert(self.zip_with(b)[i] == (self[i], b[i]));
2290 }
2291
2292 pub proof fn lemma_zip_with_uncurry_all<B>(self, b: Seq<B>, f: spec_fn(A, B) -> bool)
2309 requires
2310 self.len() == b.len(),
2311 ensures
2312 self.zip_with(b).all(|p: (A, B)| f(p.0, p.1)) <==> forall|i: int|
2313 0 <= i < self.len() ==> f(self[i], b[i]),
2314 {
2315 broadcast use group_seq_properties;
2316
2317 let zipped = self.zip_with(b);
2318 let f_uncurr = |p: (A, B)| f(p.0, p.1);
2319 let lhs = zipped.all(f_uncurr);
2320 let rhs = (forall|i: int| 0 <= i < self.len() ==> f(self[i], b[i]));
2321 if lhs {
2322 assert forall|i: int| 0 <= i < self.len() implies f(self[i], b[i]) by {
2323 self.lemma_zip_with_contains_index(b, i);
2324 assert(forall|j| 0 <= j < zipped.len() ==> f_uncurr(zipped[j]));
2325 }
2326 }
2327 }
2328
2329 pub proof fn lemma_flat_map_push<B>(self, f: spec_fn(A) -> Seq<B>, elem: A)
2343 ensures
2344 self.push(elem).flat_map(f) =~= self.flat_map(f) + f(elem),
2345 decreases self.len(),
2346 {
2347 broadcast use group_seq_properties;
2348 broadcast use Seq::lemma_flatten_push;
2349 broadcast use Seq::lemma_push_map_commute;
2350
2351 }
2352
2353 pub broadcast proof fn lemma_flat_map_take_append<B>(self, f: spec_fn(A) -> Seq<B>, i: int)
2368 requires
2369 0 <= i < self.len(),
2370 ensures
2371 #[trigger] self.take(i + 1).flat_map(f) =~= self.take(i).flat_map(f) + f(self[i]),
2372 decreases i,
2373 {
2374 broadcast use group_seq_properties;
2375
2376 self.lemma_take_succ_push(i);
2377 self.take(i).lemma_flat_map_push(f, self[i]);
2378 }
2379
2380 pub broadcast proof fn lemma_flat_map_singleton<B>(self, f: spec_fn(A) -> Seq<B>)
2383 requires
2384 #[trigger] self.len() == 1,
2385 ensures
2386 #[trigger] self.flat_map(f) == f(self[0]),
2387 {
2388 broadcast use Seq::lemma_flatten_singleton;
2389
2390 }
2391
2392 pub broadcast proof fn lemma_map_take_succ<B>(self, f: spec_fn(A) -> B, i: int)
2407 requires
2408 0 <= i < self.len(),
2409 ensures
2410 #[trigger] self.take(i + 1).map_values(f) =~= self.take(i).map_values(f).push(
2411 f(self[i]),
2412 ),
2413 {
2414 broadcast use group_seq_properties;
2415
2416 self.lemma_take_succ_push(i);
2417 }
2418
2419 pub broadcast proof fn lemma_prefix_index_eq(self, prefix: Seq<A>)
2432 requires
2433 #[trigger] prefix.is_prefix_of(self),
2434 ensures
2435 forall|i: int| 0 <= i < prefix.len() ==> prefix[i] == self[i],
2436 {
2437 }
2438
2439 pub broadcast proof fn lemma_prefix_concat(self, prefix1: Seq<A>, prefix2: Seq<A>)
2453 requires
2454 #[trigger] (prefix1 + prefix2).is_prefix_of(self),
2455 ensures
2456 prefix1.is_prefix_of(self),
2457 {
2458 broadcast use Seq::lemma_prefix_index_eq;
2459
2460 }
2461
2462 pub broadcast proof fn lemma_prefix_chain_contains(self, prefix1: Seq<A>, prefix2: Seq<A>, t: A)
2483 requires
2484 #[trigger] (prefix1 + seq![t]).is_prefix_of(self),
2485 #[trigger] prefix1.is_prefix_of(prefix2),
2486 prefix2.is_prefix_of(self),
2487 prefix1 != prefix2,
2488 !prefix1.contains(t),
2489 ensures
2490 prefix2.contains(t),
2491 {
2492 broadcast use Seq::lemma_prefix_concat;
2493 broadcast use Seq::lemma_prefix_index_eq;
2494
2495 assert(prefix2[prefix1.len() as int] == t);
2496 }
2497
2498 pub broadcast proof fn lemma_prefix_append_unique(self, prefix1: Seq<A>, prefix2: Seq<A>, t: A)
2502 requires
2503 #[trigger] (prefix1 + seq![t]).is_prefix_of(self),
2504 #[trigger] (prefix2 + seq![t]).is_prefix_of(self),
2505 !prefix1.contains(t),
2506 !prefix2.contains(t),
2507 ensures
2508 prefix1 == prefix2,
2509 {
2510 broadcast use Seq::lemma_prefix_concat;
2511 broadcast use Seq::lemma_prefix_index_eq;
2512 broadcast use Seq::lemma_prefix_chain_contains;
2513
2514 if prefix1 != prefix2 {
2515 assert(prefix1.is_prefix_of(prefix2) || prefix2.is_prefix_of(prefix1));
2516 }
2517 }
2518
2519 pub broadcast proof fn lemma_all_push(self, p: spec_fn(A) -> bool, elem: A)
2534 requires
2535 self.all(p),
2536 p(elem),
2537 ensures
2538 #[trigger] self.push(elem).all(p),
2539 {
2540 broadcast use group_seq_properties;
2541
2542 assert forall|x: A| self.push(elem).contains(x) implies p(x) by {
2543 lemma_seq_contains_after_push(self, elem, x);
2544 }
2545 }
2546
2547 pub proof fn lemma_concat_injective(self, s1: Seq<A>, s2: Seq<A>)
2550 ensures
2551 (self + s1 == self + s2) <==> (s1 == s2),
2552 {
2553 broadcast use group_seq_properties;
2554
2555 assert((self + s1).skip(self.len() as int) == s1);
2556 }
2557
2558 pub broadcast group group_seq_extra {
2559 Seq::<_>::lemma_seq_skip_skip,
2560 Seq::<_>::lemma_remove_duplicates_properties,
2561 Seq::<_>::lemma_filter_contains_rev,
2562 Seq::<_>::lemma_filter_map_take_succ,
2563 Seq::<_>::lemma_filter_prepend,
2564 Seq::<_>::lemma_filter_len_push,
2565 Seq::<_>::lemma_take_len,
2566 Seq::<_>::lemma_take_any_succ,
2567 Seq::<_>::lemma_push_map_commute,
2568 Seq::<_>::lemma_push_to_set_commute,
2569 Seq::<_>::lemma_filter_push,
2570 Seq::<_>::lemma_flat_map_take_append,
2571 Seq::<_>::lemma_flat_map_singleton,
2572 Seq::<_>::lemma_map_take_succ,
2573 Seq::<_>::lemma_prefix_index_eq,
2574 Seq::<_>::lemma_prefix_concat,
2575 Seq::<_>::lemma_prefix_chain_contains,
2576 Seq::<_>::lemma_prefix_append_unique,
2577 Seq::<_>::lemma_all_push,
2578 }
2579}
2580
2581impl<A> Seq<&A> {
2582 pub open spec fn unref(self) -> Seq<A> {
2584 Seq::new(self.len(), |i: int| *self[i])
2585 }
2586}
2587
2588impl<A, B> Seq<(&A, &B)> {
2589 pub open spec fn unref(self) -> Seq<(A, B)> {
2591 Seq::new(self.len(), |i: int| (*self[i].0, *self[i].1))
2592 }
2593}
2594
2595pub proof fn lemma_filter_view_commute<S: View>(
2612 s: Seq<S>,
2613 p: spec_fn(S) -> bool,
2614 sp: spec_fn(S::V) -> bool,
2615)
2616 requires
2617 forall|s: S| p(s) <==> sp(s.view()),
2618 ensures
2619 s.filter(p).map_values(|x: S| x.view()) == s.map_values(|x: S| x.view()).filter(sp),
2620 decreases s.len(),
2621{
2622 broadcast use group_seq_properties;
2623 broadcast use Seq::lemma_push_map_commute;
2624 broadcast use Seq::lemma_filter_push;
2625
2626 reveal(Seq::filter);
2627 let view = |x: S| x.view();
2628 if s.len() > 0 {
2629 let rest = s.drop_last();
2630 let last = s.last();
2631 assert(s =~= rest.push(last));
2632 assert(s.map_values(view).last() == view(last));
2633 lemma_filter_view_commute(rest, p, sp);
2634 }
2635}
2636
2637pub proof fn lemma_exactly_one_view<S: View>(
2652 s: Seq<S>,
2653 p: spec_fn(S) -> bool,
2654 sp: spec_fn(S::V) -> bool,
2655)
2656 requires
2657 forall|s: S| p(s) <==> sp(s.view()),
2658 injective(|x: S| x.view()),
2659 ensures
2660 s.exactly_one(p) <==> s.map_values(|x: S| x.view()).exactly_one(sp),
2661{
2662 lemma_filter_view_commute(s, p, sp);
2663}
2664
2665impl<A, B> Seq<(A, B)> {
2666 pub closed spec fn unzip(self) -> (Seq<A>, Seq<B>) {
2668 (Seq::new(self.len(), |i: int| self[i].0), Seq::new(self.len(), |i: int| self[i].1))
2669 }
2670
2671 pub proof fn unzip_ensures(self)
2673 ensures
2674 self.unzip().0.len() == self.unzip().1.len(),
2675 self.unzip().0.len() == self.len(),
2676 self.unzip().1.len() == self.len(),
2677 forall|i: int|
2678 0 <= i < self.len() ==> (#[trigger] self.unzip().0[i], #[trigger] self.unzip().1[i])
2679 == self[i],
2680 decreases self.len(),
2681 {
2682 if self.len() > 0 {
2683 self.drop_last().unzip_ensures();
2684 }
2685 }
2686
2687 pub proof fn lemma_zip_of_unzip(self)
2690 ensures
2691 self.unzip().0.zip_with(self.unzip().1) =~= self,
2692 {
2693 }
2694}
2695
2696impl<A> Seq<Seq<A>> {
2697 pub open spec fn flatten(self) -> Seq<A>
2711 decreases self.len(),
2712 {
2713 if self.len() == 0 {
2714 Seq::empty()
2715 } else {
2716 self.first().add(self.drop_first().flatten())
2717 }
2718 }
2719
2720 pub open spec fn flatten_alt(self) -> Seq<A>
2725 decreases self.len(),
2726 {
2727 if self.len() == 0 {
2728 Seq::empty()
2729 } else {
2730 self.drop_last().flatten_alt().add(self.last())
2731 }
2732 }
2733
2734 pub proof fn lemma_flatten_one_element(self)
2737 ensures
2738 self.len() == 1 ==> self.flatten() == self.first(),
2739 {
2740 broadcast use Seq::add_empty_right;
2741
2742 if self.len() == 1 {
2743 assert(self.flatten() =~= self.first().add(self.drop_first().flatten()));
2744 }
2745 }
2746
2747 pub proof fn lemma_flatten_length_ge_single_element_length(self, i: int)
2750 requires
2751 0 <= i < self.len(),
2752 ensures
2753 self.flatten_alt().len() >= self[i].len(),
2754 decreases self.len(),
2755 {
2756 if self.len() == 1 {
2757 self.lemma_flatten_one_element();
2758 self.lemma_flatten_and_flatten_alt_are_equivalent();
2759 } else if i < self.len() - 1 {
2760 self.drop_last().lemma_flatten_length_ge_single_element_length(i);
2761 } else {
2762 assert(self.flatten_alt() == self.drop_last().flatten_alt().add(self.last()));
2763 }
2764 }
2765
2766 pub proof fn lemma_flatten_length_le_mul(self, j: int)
2770 requires
2771 forall|i: int| 0 <= i < self.len() ==> (#[trigger] self[i]).len() <= j,
2772 ensures
2773 self.flatten_alt().len() <= self.len() * j,
2774 decreases self.len(),
2775 {
2776 broadcast use group_seq_properties;
2777
2778 if self.len() == 0 {
2779 } else {
2780 self.drop_last().lemma_flatten_length_le_mul(j);
2781 assert((self.len() - 1) * j == (self.len() * j) - (1 * j)) by (nonlinear_arith); }
2783 }
2784
2785 pub proof fn lemma_flatten_and_flatten_alt_are_equivalent(self)
2788 ensures
2789 self.flatten() =~= self.flatten_alt(),
2790 decreases self.len(),
2791 {
2792 broadcast use {Seq::add_empty_right, Seq::push_distributes_over_add};
2793
2794 if self.len() != 0 {
2795 self.drop_last().lemma_flatten_and_flatten_alt_are_equivalent();
2796 seq![self.last()].lemma_flatten_one_element();
2800 assert(seq![self.last()].flatten() == self.last());
2801 lemma_flatten_concat(self.drop_last(), seq![self.last()]);
2802 assert((self.drop_last() + seq![self.last()]).flatten() == self.drop_last().flatten()
2803 + self.last());
2804 assert(self.drop_last() + seq![self.last()] =~= self);
2805 assert(self.flatten_alt() == self.drop_last().flatten_alt() + self.last());
2806 }
2807 }
2808
2809 pub broadcast proof fn lemma_flatten_push(self, elem: Seq<A>)
2812 ensures
2813 #[trigger] self.push(elem).flatten() =~= self.flatten() + elem,
2814 decreases self.len(),
2815 {
2816 broadcast use group_seq_properties;
2817
2818 assert(self.push(elem).last() == elem);
2819 assert(self.push(elem).drop_last() =~= self);
2820 calc! {
2821 (==)
2822 self.push(elem).flatten(); {
2823 self.push(elem).lemma_flatten_and_flatten_alt_are_equivalent();
2824 }
2825 self.push(elem).flatten_alt(); {}
2826 self.flatten_alt() + elem; {
2827 self.lemma_flatten_and_flatten_alt_are_equivalent();
2828 }
2829 self.flatten() + elem;
2830 }
2831 }
2832
2833 pub broadcast proof fn lemma_flatten_singleton(self)
2835 requires
2836 #[trigger] self.len() == 1,
2837 ensures
2838 #[trigger] self.flatten() == self[0],
2839 {
2840 assert(self.flatten() == self[0] + self.drop_first().flatten());
2841 assert(self.flatten() == self[0]);
2842 }
2843
2844 pub broadcast group group_seq_flatten {
2845 Seq::<_>::lemma_flatten_push,
2846 Seq::<_>::lemma_flatten_singleton,
2847 }
2848}
2849
2850impl Seq<int> {
2853 pub open spec fn max(self) -> int
2855 recommends
2856 0 < self.len(),
2857 decreases self.len(),
2858 {
2859 if self.len() == 1 {
2860 self[0]
2861 } else if self.len() == 0 {
2862 0
2863 } else {
2864 let later_max = self.drop_first().max();
2865 if self[0] >= later_max {
2866 self[0]
2867 } else {
2868 later_max
2869 }
2870 }
2871 }
2872
2873 pub proof fn max_ensures(self)
2875 ensures
2876 forall|x: int| self.contains(x) ==> x <= self.max(),
2877 forall|i: int| 0 <= i < self.len() ==> self[i] <= self.max(),
2878 self.len() == 0 || self.contains(self.max()),
2879 decreases self.len(),
2880 {
2881 if self.len() <= 1 {
2882 } else {
2883 let elt = self.drop_first().max();
2884 assert(self.drop_first().contains(elt)) by { self.drop_first().max_ensures() }
2885 assert forall|i: int| 0 <= i < self.len() implies self[i] <= self.max() by {
2886 assert(i == 0 || self[i] == self.drop_first()[i - 1]);
2887 assert(forall|j: int|
2888 0 <= j < self.drop_first().len() ==> self.drop_first()[j]
2889 <= self.drop_first().max()) by { self.drop_first().max_ensures() }
2890 }
2891 }
2892 }
2893
2894 pub open spec fn min(self) -> int
2896 recommends
2897 0 < self.len(),
2898 decreases self.len(),
2899 {
2900 if self.len() == 1 {
2901 self[0]
2902 } else if self.len() == 0 {
2903 0
2904 } else {
2905 let later_min = self.drop_first().min();
2906 if self[0] <= later_min {
2907 self[0]
2908 } else {
2909 later_min
2910 }
2911 }
2912 }
2913
2914 pub proof fn min_ensures(self)
2916 ensures
2917 forall|x: int| self.contains(x) ==> self.min() <= x,
2918 forall|i: int| 0 <= i < self.len() ==> self.min() <= self[i],
2919 self.len() == 0 || self.contains(self.min()),
2920 decreases self.len(),
2921 {
2922 if self.len() <= 1 {
2923 } else {
2924 let elt = self.drop_first().min();
2925 assert(self.subrange(1, self.len() as int).contains(elt)) by {
2926 self.drop_first().min_ensures()
2927 }
2928 assert forall|i: int| 0 <= i < self.len() implies self.min() <= self[i] by {
2929 assert(i == 0 || self[i] == self.drop_first()[i - 1]);
2930 assert(forall|j: int|
2931 0 <= j < self.drop_first().len() ==> self.drop_first().min()
2932 <= self.drop_first()[j]) by { self.drop_first().min_ensures() }
2933 }
2934 }
2935 }
2936
2937 pub closed spec fn sort(self) -> Self {
2938 self.sort_by(|x: int, y: int| x <= y)
2939 }
2940
2941 pub proof fn lemma_sort_ensures(self)
2942 ensures
2943 self.to_multiset() =~= self.sort().to_multiset(),
2944 sorted_by(self.sort(), |x: int, y: int| x <= y),
2945 {
2946 self.lemma_sort_by_ensures(|x: int, y: int| x <= y);
2947 }
2948
2949 pub proof fn lemma_subrange_max(self, from: int, to: int)
2952 requires
2953 0 <= from < to <= self.len(),
2954 ensures
2955 self.subrange(from, to).max() <= self.max(),
2956 {
2957 self.max_ensures();
2958 self.subrange(from, to).max_ensures();
2959 }
2960
2961 pub proof fn lemma_subrange_min(self, from: int, to: int)
2964 requires
2965 0 <= from < to <= self.len(),
2966 ensures
2967 self.subrange(from, to).min() >= self.min(),
2968 {
2969 self.min_ensures();
2970 self.subrange(from, to).min_ensures();
2971 }
2972}
2973
2974spec fn merge_sorted_with<A>(left: Seq<A>, right: Seq<A>, leq: spec_fn(A, A) -> bool) -> Seq<A>
2976 recommends
2977 sorted_by(left, leq),
2978 sorted_by(right, leq),
2979 total_ordering(leq),
2980 decreases left.len(), right.len(),
2981{
2982 if left.len() == 0 {
2983 right
2984 } else if right.len() == 0 {
2985 left
2986 } else if leq(left.first(), right.first()) {
2987 Seq::<A>::empty().push(left.first()) + merge_sorted_with(left.drop_first(), right, leq)
2988 } else {
2989 Seq::<A>::empty().push(right.first()) + merge_sorted_with(left, right.drop_first(), leq)
2990 }
2991}
2992
2993proof fn lemma_merge_sorted_with_ensures<A>(left: Seq<A>, right: Seq<A>, leq: spec_fn(A, A) -> bool)
2994 requires
2995 sorted_by(left, leq),
2996 sorted_by(right, leq),
2997 total_ordering(leq),
2998 ensures
2999 (left + right).to_multiset() =~= merge_sorted_with(left, right, leq).to_multiset(),
3000 sorted_by(merge_sorted_with(left, right, leq), leq),
3001 decreases left.len(), right.len(),
3002{
3003 broadcast use group_seq_properties;
3005
3006 if left.len() == 0 {
3007 assert(left + right =~= right);
3008 } else if right.len() == 0 {
3009 assert(left + right =~= left);
3010 } else if leq(left.first(), right.first()) {
3011 let result = Seq::<A>::empty().push(left.first()) + merge_sorted_with(
3012 left.drop_first(),
3013 right,
3014 leq,
3015 );
3016 lemma_merge_sorted_with_ensures(left.drop_first(), right, leq);
3017 let rest = merge_sorted_with(left.drop_first(), right, leq);
3018 assert(rest.len() == 0 || rest.first() == left.drop_first().first() || rest.first()
3019 == right.first()) by {
3020 if left.drop_first().len() == 0 {
3021 } else if leq(left.drop_first().first(), right.first()) {
3022 assert(rest =~= Seq::<A>::empty().push(left.drop_first().first())
3023 + merge_sorted_with(left.drop_first().drop_first(), right, leq));
3024 } else {
3025 assert(rest =~= Seq::<A>::empty().push(right.first()) + merge_sorted_with(
3026 left.drop_first(),
3027 right.drop_first(),
3028 leq,
3029 ));
3030 }
3031 }
3032 lemma_new_first_element_still_sorted_by(left.first(), rest, leq);
3033 assert((left.drop_first() + right) =~= (left + right).drop_first());
3034 } else {
3035 let result = Seq::<A>::empty().push(right.first()) + merge_sorted_with(
3036 left,
3037 right.drop_first(),
3038 leq,
3039 );
3040 lemma_merge_sorted_with_ensures(left, right.drop_first(), leq);
3041 let rest = merge_sorted_with(left, right.drop_first(), leq);
3042 assert(rest.len() == 0 || rest.first() == left.first() || rest.first()
3043 == right.drop_first().first()) by {
3044 assert(left.len() > 0);
3045 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(
3048 left.drop_first(),
3049 right.drop_first(),
3050 leq,
3051 ));
3052 } else {
3053 assert(rest =~= Seq::<A>::empty().push(right.drop_first().first())
3054 + merge_sorted_with(left, right.drop_first().drop_first(), leq));
3055 }
3056 }
3057 lemma_new_first_element_still_sorted_by(
3058 right.first(),
3059 merge_sorted_with(left, right.drop_first(), leq),
3060 leq,
3061 );
3062 lemma_seq_union_to_multiset_commutative(left, right);
3063 assert((right.drop_first() + left) =~= (right + left).drop_first());
3064 lemma_seq_union_to_multiset_commutative(right.drop_first(), left);
3065 }
3066}
3067
3068pub proof fn lemma_max_of_concat(x: Seq<int>, y: Seq<int>)
3071 requires
3072 0 < x.len() && 0 < y.len(),
3073 ensures
3074 x.max() <= (x + y).max(),
3075 y.max() <= (x + y).max(),
3076 forall|elt: int| (x + y).contains(elt) ==> elt <= (x + y).max(),
3077 decreases x.len(),
3078{
3079 broadcast use group_seq_properties;
3080
3081 x.max_ensures();
3082 y.max_ensures();
3083 (x + y).max_ensures();
3084 assert(x.drop_first().len() == x.len() - 1);
3085 if x.len() == 1 {
3086 assert(y.max() <= (x + y).max()) by {
3087 assert((x + y).contains(y.max()));
3088 }
3089 } else {
3090 assert(x.max() <= (x + y).max()) by {
3091 assert(x.contains(x.max()));
3092 assert((x + y).contains(x.max()));
3093 }
3094 assert(x.drop_first() + y =~= (x + y).drop_first());
3095 lemma_max_of_concat(x.drop_first(), y);
3096 }
3097}
3098
3099pub proof fn lemma_min_of_concat(x: Seq<int>, y: Seq<int>)
3102 requires
3103 0 < x.len() && 0 < y.len(),
3104 ensures
3105 (x + y).min() <= x.min(),
3106 (x + y).min() <= y.min(),
3107 forall|elt: int| (x + y).contains(elt) ==> (x + y).min() <= elt,
3108 decreases x.len(),
3109{
3110 x.min_ensures();
3111 y.min_ensures();
3112 (x + y).min_ensures();
3113 broadcast use group_seq_properties;
3114
3115 if x.len() == 1 {
3116 assert((x + y).min() <= y.min()) by {
3117 assert((x + y).contains(y.min()));
3118 }
3119 } else {
3120 assert((x + y).min() <= x.min()) by {
3121 assert((x + y).contains(x.min()));
3122 }
3123 assert((x + y).min() <= y.min()) by {
3124 assert((x + y).contains(y.min()));
3125 }
3126 assert(x.drop_first() + y =~= (x + y).drop_first());
3127 lemma_max_of_concat(x.drop_first(), y)
3128 }
3129}
3130
3131pub broadcast proof fn to_multiset_build<A>(s: Seq<A>, a: A)
3135 ensures
3136 #![trigger s.push(a).to_multiset()]
3137 s.push(a).to_multiset() =~= s.to_multiset().insert(a),
3138 decreases s.len(),
3139{
3140 broadcast use super::multiset::group_multiset_axioms;
3141
3142 if s.len() == 0 {
3143 assert(s.to_multiset() =~= Multiset::<A>::empty());
3144 assert(s.push(a).drop_first() =~= Seq::<A>::empty());
3145 assert(s.push(a).to_multiset() =~= Multiset::<A>::empty().insert(a).add(
3146 Seq::<A>::empty().to_multiset(),
3147 ));
3148 } else {
3149 to_multiset_build(s.drop_first(), a);
3150 assert(s.drop_first().push(a).to_multiset() =~= s.drop_first().to_multiset().insert(a));
3151 assert(s.push(a).drop_first() =~= s.drop_first().push(a));
3152 }
3153}
3154
3155pub broadcast proof fn to_multiset_remove<A>(s: Seq<A>, i: int)
3156 requires
3157 0 <= i < s.len(),
3158 ensures
3159 #![trigger s.remove(i).to_multiset()]
3160 s.remove(i).to_multiset() == s.to_multiset().remove(s[i]),
3161{
3162 broadcast use super::multiset::group_multiset_axioms;
3163
3164 let s0 = s.subrange(0, i);
3165 let s1 = s.subrange(i, s.len() as int);
3166 let s2 = s.subrange(i + 1, s.len() as int);
3167 lemma_seq_union_to_multiset_commutative(s0, s2);
3168 lemma_seq_union_to_multiset_commutative(s0, s1);
3169 assert(s == s0 + s1);
3170 assert(s2 + s0 == (s1 + s0).drop_first());
3171 assert(s.remove(i).to_multiset() =~= s.to_multiset().remove(s[i]));
3172}
3173
3174pub broadcast proof fn to_multiset_insert<A>(s: Seq<A>, i: int, a: A)
3175 requires
3176 0 <= i <= s.len(),
3177 ensures
3178 #![trigger s.insert(i, a).to_multiset()]
3179 s.insert(i, a).to_multiset() == s.to_multiset().insert(a),
3180 decreases s.len(),
3181{
3182 broadcast use super::multiset::group_multiset_axioms;
3183
3184 let s0 = s.subrange(0, i);
3185 let s1 = s.subrange(i, s.len() as int);
3186
3187 assert(s =~= s0 + s1);
3188 assert(s.insert(i, a) =~= s0 + seq![a] + s1);
3189 assert(((s0 + seq![a]) + s1).to_multiset() =~= ((seq![a] + s0) + s1).to_multiset()) by {
3190 broadcast use lemma_multiset_commutative;
3191
3192 };
3193 assert((seq![a] + s0 + s1).drop_first() == s0 + s1);
3194 assert(s.insert(i, a).to_multiset() =~= s.to_multiset().insert(a));
3195}
3196
3197pub broadcast proof fn to_multiset_len<A>(s: Seq<A>)
3199 ensures
3200 s.len() == #[trigger] s.to_multiset().len(),
3201 decreases s.len(),
3202{
3203 broadcast use super::multiset::group_multiset_axioms;
3204
3205 if s.len() == 0 {
3206 assert(s.to_multiset() =~= Multiset::<A>::empty());
3207 assert(s.len() == 0);
3208 } else {
3209 to_multiset_len(s.drop_first());
3210 assert(s.len() == s.drop_first().len() + 1);
3211 assert(s.to_multiset().len() == s.drop_first().to_multiset().len() + 1);
3212 }
3213}
3214
3215pub broadcast proof fn to_multiset_contains<A>(s: Seq<A>, a: A)
3217 ensures
3218 #![trigger s.to_multiset().count(a)]
3219 s.contains(a) <==> s.to_multiset().count(a) > 0,
3220 decreases s.len(),
3221{
3222 broadcast use super::multiset::group_multiset_axioms;
3223
3224 if s.len() != 0 {
3225 if s.contains(a) {
3227 if s.first() == a {
3228 to_multiset_build(s, a);
3229 assert(s.to_multiset() =~= Multiset::<A>::empty().insert(s.first()).add(
3230 s.drop_first().to_multiset(),
3231 ));
3232 assert(Multiset::<A>::empty().insert(s.first()).contains(s.first()));
3233 } else {
3234 to_multiset_contains(s.drop_first(), a);
3235 assert(s.skip(1) =~= s.drop_first());
3236 lemma_seq_skip_contains(s, 1, a);
3237 assert(s.to_multiset().count(a) == s.drop_first().to_multiset().count(a));
3238 assert(s.contains(a) <==> s.to_multiset().count(a) > 0);
3239 }
3240 }
3241 if s.to_multiset().count(a) > 0 {
3244 to_multiset_contains(s.drop_first(), a);
3245 assert(s.contains(a) <==> s.to_multiset().count(a) > 0);
3246 } else {
3247 assert(s.contains(a) <==> s.to_multiset().count(a) > 0);
3248 }
3249 }
3250}
3251
3252pub broadcast proof fn to_multiset_update<A>(s: Seq<A>, i: int, a: A)
3253 requires
3254 0 <= i < s.len(),
3255 ensures
3256 #[trigger] s.update(i, a).to_multiset() == s.to_multiset().insert(a).remove(s[i]),
3257 decreases s.len(),
3258{
3259 broadcast use {
3260 super::seq_lib::lemma_seq_take_len,
3261 super::multiset::group_multiset_properties,
3262 super::multiset::group_multiset_axioms,
3263 to_multiset_insert,
3264 to_multiset_remove,
3265 to_multiset_contains,
3266 lemma_update_is_remove_insert,
3267 };
3268
3269 assert(s.update(i, a).to_multiset() =~= s.to_multiset().insert(a).remove(s[i]));
3270
3271}
3272
3273pub broadcast proof fn lemma_update_is_remove_insert<A>(s: Seq<A>, i: int, a: A)
3275 requires
3276 0 <= i < s.len(),
3277 ensures
3278 #[trigger] s.update(i, a) =~= s.remove(i).insert(i, a),
3279 decreases s.len(),
3280{
3281}
3282
3283pub proof fn lemma_append_last<A>(s1: Seq<A>, s2: Seq<A>)
3286 requires
3287 0 < s2.len(),
3288 ensures
3289 (s1 + s2).last() == s2.last(),
3290{
3291}
3292
3293pub proof fn lemma_concat_associative<A>(s1: Seq<A>, s2: Seq<A>, s3: Seq<A>)
3295 ensures
3296 s1.add(s2.add(s3)) =~= s1.add(s2).add(s3),
3297{
3298}
3299
3300spec fn seq_to_set_rec<A>(seq: Seq<A>) -> Set<A>
3302 decreases seq.len(),
3303{
3304 if seq.len() == 0 {
3305 Set::empty()
3306 } else {
3307 seq_to_set_rec(seq.drop_last()).insert(seq.last())
3308 }
3309}
3310
3311proof fn seq_to_set_rec_contains<A>(seq: Seq<A>)
3313 ensures
3314 forall|a| #[trigger] seq.contains(a) <==> seq_to_set_rec(seq).contains(a),
3315 decreases seq.len(),
3316{
3317 broadcast use super::set::group_set_lemmas;
3318
3319 if seq.len() > 0 {
3320 assert(forall|a| #[trigger]
3321 seq.drop_last().contains(a) <==> seq_to_set_rec(seq.drop_last()).contains(a)) by {
3322 seq_to_set_rec_contains(seq.drop_last());
3323 }
3324 assert(seq =~= seq.drop_last().push(seq.last()));
3325 assert forall|a| #[trigger] seq.contains(a) <==> seq_to_set_rec(seq).contains(a) by {
3326 if !seq.drop_last().contains(a) {
3327 if a == seq.last() {
3328 assert(seq.contains(a));
3329 assert(seq_to_set_rec(seq).contains(a));
3330 } else {
3331 assert(!seq_to_set_rec(seq).contains(a));
3332 }
3333 }
3334 }
3335 }
3336}
3337
3338proof fn seq_to_set_equal_rec<A>(seq: Seq<A>)
3340 ensures
3341 seq.to_set() == seq_to_set_rec(seq),
3342 decreases seq.len(),
3343{
3344 broadcast use super::set::group_set_lemmas;
3345
3346 seq.to_set_ensures();
3347 assert(forall|n| seq.contains(n) <==> #[trigger] seq_to_set_rec(seq).contains(n)) by {
3348 seq_to_set_rec_contains(seq);
3349 }
3350 assert(seq.to_set() =~= seq_to_set_rec(seq));
3351}
3352
3353pub proof fn seq_to_set_distributes_over_add<T>(s1: Seq<T>, s2: Seq<T>)
3354 ensures
3355 s1.to_set() + s2.to_set() =~= (s1 + s2).to_set(),
3356{
3357 broadcast use super::group_vstd_default;
3358 broadcast use super::set_lib::group_set_properties;
3359 broadcast use group_seq_properties;
3360
3361}
3362
3363pub proof fn lemma_no_dup_in_concat<A>(a: Seq<A>, b: Seq<A>)
3367 requires
3368 a.no_duplicates(),
3369 b.no_duplicates(),
3370 forall|i: int, j: int| 0 <= i < a.len() && 0 <= j < b.len() ==> a[i] != b[j],
3371 ensures
3372 #[trigger] (a + b).no_duplicates(),
3373{
3374}
3375
3376pub proof fn lemma_flatten_concat<A>(x: Seq<Seq<A>>, y: Seq<Seq<A>>)
3380 ensures
3381 (x + y).flatten() =~= x.flatten() + y.flatten(),
3382 decreases x.len(),
3383{
3384 if x.len() == 0 {
3385 assert(x + y =~= y);
3386 } else {
3387 assert((x + y).drop_first() =~= x.drop_first() + y);
3388 assert(x.first() + (x.drop_first() + y).flatten() =~= x.first() + x.drop_first().flatten()
3389 + y.flatten()) by {
3390 lemma_flatten_concat(x.drop_first(), y);
3391 }
3392 }
3393}
3394
3395pub proof fn lemma_flatten_alt_concat<A>(x: Seq<Seq<A>>, y: Seq<Seq<A>>)
3400 ensures
3401 (x + y).flatten_alt() =~= x.flatten_alt() + y.flatten_alt(),
3402 decreases y.len(),
3403{
3404 if y.len() == 0 {
3405 assert(x + y =~= x);
3406 } else {
3407 assert((x + y).drop_last() =~= x + y.drop_last());
3408 assert((x + y.drop_last()).flatten_alt() + y.last() =~= x.flatten_alt()
3409 + y.drop_last().flatten_alt() + y.last()) by {
3410 lemma_flatten_alt_concat(x, y.drop_last());
3411 }
3412 }
3413}
3414
3415pub broadcast proof fn lemma_seq_union_to_multiset_commutative<A>(a: Seq<A>, b: Seq<A>)
3418 ensures
3419 #[trigger] (a + b).to_multiset() =~= (b + a).to_multiset(),
3420{
3421 broadcast use super::multiset::group_multiset_axioms;
3422
3423 lemma_multiset_commutative(a, b);
3424 lemma_multiset_commutative(b, a);
3425}
3426
3427pub broadcast proof fn lemma_multiset_commutative<A>(a: Seq<A>, b: Seq<A>)
3430 ensures
3431 #[trigger] (a + b).to_multiset() =~= a.to_multiset().add(b.to_multiset()),
3432 decreases a.len(),
3433{
3434 broadcast use super::multiset::group_multiset_axioms;
3435
3436 if a.len() == 0 {
3437 assert(a + b =~= b);
3438 } else {
3439 lemma_multiset_commutative(a.drop_first(), b);
3440 assert(a.drop_first() + b =~= (a + b).drop_first());
3441 }
3442}
3443
3444pub proof fn lemma_sorted_unique<A>(x: Seq<A>, y: Seq<A>, leq: spec_fn(A, A) -> bool)
3446 requires
3447 sorted_by(x, leq),
3448 sorted_by(y, leq),
3449 total_ordering(leq),
3450 x.to_multiset() == y.to_multiset(),
3451 ensures
3452 x =~= y,
3453 decreases x.len(), y.len(),
3454{
3455 broadcast use super::multiset::group_multiset_axioms;
3456 broadcast use group_to_multiset_ensures;
3457
3458 if x.len() == 0 || y.len() == 0 {
3459 } else {
3460 assert(x.to_multiset().contains(x[0]));
3461 assert(x.to_multiset().contains(y[0]));
3462 let i = choose|i: int| #![trigger x.spec_index(i) ] 0 <= i < x.len() && x[i] == y[0];
3463 assert(leq(x[i], x[0]));
3464 assert(leq(x[0], x[i]));
3465 assert(x.drop_first().to_multiset() =~= x.to_multiset().remove(x[0]));
3466 assert(y.drop_first().to_multiset() =~= y.to_multiset().remove(y[0]));
3467 lemma_sorted_unique(x.drop_first(), y.drop_first(), leq);
3468 assert(x.drop_first() =~= y.drop_first());
3469 assert(x.first() == y.first());
3470 assert(x =~= Seq::<A>::empty().push(x.first()).add(x.drop_first()));
3471 assert(x =~= y);
3472 }
3473}
3474
3475pub broadcast proof fn lemma_seq_contains<A>(s: Seq<A>, x: A)
3477 ensures
3478 #[trigger] s.contains(x) <==> exists|i: int| 0 <= i < s.len() && #[trigger] s[i] == x,
3479{
3480}
3481
3482pub broadcast proof fn lemma_seq_empty_contains_nothing<A>(x: A)
3485 ensures
3486 !(#[trigger] Seq::<A>::empty().contains(x)),
3487{
3488}
3489
3490pub broadcast proof fn lemma_seq_empty_equality<A>(s: Seq<A>)
3494 ensures
3495 #[trigger] s.len() == 0 ==> s =~= Seq::<A>::empty(),
3496{
3497}
3498
3499pub broadcast proof fn lemma_seq_concat_contains_all_elements<A>(x: Seq<A>, y: Seq<A>, elt: A)
3503 ensures
3504 #[trigger] (x + y).contains(elt) <==> x.contains(elt) || y.contains(elt),
3505 decreases x.len(),
3506{
3507 if x.len() == 0 && y.len() > 0 {
3508 assert((x + y) =~= y);
3509 } else {
3510 assert forall|elt: A| #[trigger] x.contains(elt) implies #[trigger] (x + y).contains(
3511 elt,
3512 ) by {
3513 let index = choose|i: int| 0 <= i < x.len() && x[i] == elt;
3514 assert((x + y)[index] == elt);
3515 }
3516 assert forall|elt: A| #[trigger] y.contains(elt) implies #[trigger] (x + y).contains(
3517 elt,
3518 ) by {
3519 let index = choose|i: int| 0 <= i < y.len() && y[i] == elt;
3520 assert((x + y)[index + x.len()] == elt);
3521 }
3522 }
3523}
3524
3525pub broadcast proof fn lemma_seq_contains_after_push<A>(s: Seq<A>, v: A, x: A)
3528 ensures
3529 #[trigger] s.push(v).contains(x) <==> v == x || s.contains(x),
3530{
3531 assert forall|elt: A| #[trigger] s.contains(elt) implies #[trigger] s.push(v).contains(elt) by {
3532 let index = choose|i: int| 0 <= i < s.len() && s[i] == elt;
3533 assert(s.push(v)[index] == elt);
3534 }
3535 assert(s.push(v)[s.len() as int] == v);
3536}
3537
3538pub broadcast proof fn lemma_seq_subrange_elements<A>(s: Seq<A>, start: int, stop: int, x: A)
3542 requires
3543 0 <= start <= stop <= s.len(),
3544 ensures
3545 #[trigger] s.subrange(start, stop).contains(x) <==> (exists|i: int|
3546 0 <= start <= i < stop <= s.len() && #[trigger] s[i] == x),
3547{
3548 assert((exists|i: int| 0 <= start <= i < stop <= s.len() && s[i] == x) ==> s.subrange(
3549 start,
3550 stop,
3551 ).contains(x)) by {
3552 if exists|i: int| 0 <= start <= i < stop <= s.len() && s[i] == x {
3553 let index = choose|i: int| 0 <= start <= i < stop <= s.len() && s[i] == x;
3554 assert(s.subrange(start, stop)[index - start] == s[index]);
3555 }
3556 }
3557}
3558
3559pub open spec fn commutative_foldr<A, B>(f: spec_fn(A, B) -> B) -> bool {
3561 forall|x: A, y: A, v: B| #[trigger] f(x, f(y, v)) == f(y, f(x, v))
3562}
3563
3564pub open spec fn commutative_foldl<A, B>(f: spec_fn(B, A) -> B) -> bool {
3566 forall|x: A, y: A, v: B| #[trigger] f(f(v, x), y) == f(f(v, y), x)
3567}
3568
3569pub proof fn lemma_fold_right_permutation<A, B>(l1: Seq<A>, l2: Seq<A>, f: spec_fn(A, B) -> B, v: B)
3572 requires
3573 commutative_foldr(f),
3574 l1.to_multiset() == l2.to_multiset(),
3575 ensures
3576 l1.fold_right(f, v) == l2.fold_right(f, v),
3577 decreases l1.len(),
3578{
3579 broadcast use group_to_multiset_ensures;
3580
3581 if l1.len() > 0 {
3582 let a = l1.last();
3583 let i = l2.index_of(a);
3584 let l2r = l2.subrange(i + 1, l2.len() as int).fold_right(f, v);
3585
3586 assert(l1.to_multiset().count(a) > 0);
3587 l1.drop_last().lemma_fold_right_commute_one(a, f, v);
3588 l2.subrange(0, i).lemma_fold_right_commute_one(a, f, l2r);
3589
3590 l2.lemma_fold_right_split(f, v, i + 1);
3591 l2.remove(i).lemma_fold_right_split(f, v, i);
3592
3593 assert(l2.subrange(0, i + 1).drop_last() == l2.subrange(0, i));
3594 assert(l1.drop_last() == l1.remove(l1.len() - 1));
3595
3596 assert(l2.remove(i).subrange(0, i) == l2.subrange(0, i));
3597 assert(l2.remove(i).subrange(i, l2.remove(i).len() as int) == l2.subrange(
3598 i + 1,
3599 l2.len() as int,
3600 ));
3601
3602 lemma_fold_right_permutation(l1.drop_last(), l2.remove(i), f, v);
3603 } else {
3604 assert(l2.to_multiset().len() == 0);
3605 }
3606}
3607
3608pub proof fn lemma_fold_left_permutation<A, B>(l1: Seq<A>, l2: Seq<A>, f: spec_fn(B, A) -> B, v: B)
3611 requires
3612 commutative_foldl(f),
3613 l1.to_multiset() == l2.to_multiset(),
3614 ensures
3615 l1.fold_left(v, f) == l2.fold_left(v, f),
3616{
3617 let g = |a: A, b: B| f(b, a);
3618 assert(f =~= |b: B, a: A| g(a, b));
3619 assert(l1.fold_left(v, f) == l1.reverse().fold_right(g, v)) by {
3620 l1.lemma_reverse_fold_right(v, g)
3621 };
3622 assert(l2.fold_left(v, f) == l2.reverse().fold_right(g, v)) by {
3623 l2.lemma_reverse_fold_right(v, g)
3624 };
3625 assert(l1.reverse().to_multiset() =~= l2.reverse().to_multiset()) by {
3626 l1.lemma_reverse_to_multiset();
3627 l2.lemma_reverse_to_multiset();
3628 }
3629 assert(forall|x: A| #[trigger] l1.reverse().contains(x) ==> l1.contains(x));
3630 assert(forall|x: A| #[trigger] l2.reverse().contains(x) ==> l2.contains(x));
3631 lemma_fold_right_permutation(l1.reverse(), l2.reverse(), g, v);
3632}
3633
3634pub broadcast proof fn lemma_seq_take_len<A>(s: Seq<A>, n: int)
3640 ensures
3641 0 <= n <= s.len() ==> #[trigger] s.take(n).len() == n,
3642{
3643}
3644
3645pub broadcast proof fn lemma_seq_take_contains<A>(s: Seq<A>, n: int, x: A)
3649 requires
3650 0 <= n <= s.len(),
3651 ensures
3652 #[trigger] s.take(n).contains(x) <==> (exists|i: int|
3653 0 <= i < n <= s.len() && #[trigger] s[i] == x),
3654{
3655 assert((exists|i: int| 0 <= i < n <= s.len() && #[trigger] s[i] == x) ==> s.take(n).contains(x))
3656 by {
3657 if exists|i: int| 0 <= i < n <= s.len() && #[trigger] s[i] == x {
3658 let index = choose|i: int| 0 <= i < n <= s.len() && #[trigger] s[i] == x;
3659 assert(s.take(n)[index] == s[index]);
3660 }
3661 }
3662}
3663
3664pub broadcast proof fn lemma_seq_take_index<A>(s: Seq<A>, n: int, j: int)
3668 ensures
3669 0 <= j < n <= s.len() ==> #[trigger] s.take(n)[j] == s[j],
3670{
3671}
3672
3673pub proof fn subrange_of_matching_take<T>(a: Seq<T>, b: Seq<T>, s: int, e: int, l: int)
3674 requires
3675 a.take(l) == b.take(l),
3676 l <= a.len(),
3677 l <= b.len(),
3678 0 <= s <= e <= l,
3679 ensures
3680 a.subrange(s, e) == b.subrange(s, e),
3681{
3682 assert forall|i| 0 <= i < e - s implies a.subrange(s, e)[i] == b.subrange(s, e)[i] by {
3683 assert(a.subrange(s, e)[i] == a.take(l)[i + s]);
3684 }
3686 assert(a.subrange(s, e) == b.subrange(s, e));
3689}
3690
3691pub broadcast proof fn lemma_seq_skip_len<A>(s: Seq<A>, n: int)
3695 ensures
3696 0 <= n <= s.len() ==> #[trigger] s.skip(n).len() == s.len() - n,
3697{
3698}
3699
3700pub broadcast proof fn lemma_seq_skip_contains<A>(s: Seq<A>, n: int, x: A)
3704 requires
3705 0 <= n <= s.len(),
3706 ensures
3707 #[trigger] s.skip(n).contains(x) <==> (exists|i: int|
3708 0 <= n <= i < s.len() && #[trigger] s[i] == x),
3709{
3710 assert((exists|i: int| 0 <= n <= i < s.len() && #[trigger] s[i] == x) ==> s.skip(n).contains(x))
3711 by {
3712 let index = choose|i: int| 0 <= n <= i < s.len() && #[trigger] s[i] == x;
3713 lemma_seq_skip_index(s, n, index - n);
3714 }
3715}
3716
3717pub broadcast proof fn lemma_seq_skip_index<A>(s: Seq<A>, n: int, j: int)
3721 ensures
3722 0 <= n && 0 <= j < (s.len() - n) ==> #[trigger] s.skip(n)[j] == s[j + n],
3723{
3724}
3725
3726pub broadcast proof fn lemma_seq_skip_index2<A>(s: Seq<A>, n: int, k: int)
3731 ensures
3732 0 <= n <= k < s.len() ==> (#[trigger] s.skip(n))[k - n] == #[trigger] s[k],
3733{
3734}
3735
3736pub broadcast proof fn lemma_seq_append_take_skip<A>(a: Seq<A>, b: Seq<A>, n: int)
3741 ensures
3742 #![trigger (a + b).take(n)]
3743 #![trigger (a + b).skip(n)]
3744 n == a.len() ==> ((a + b).take(n) =~= a && (a + b).skip(n) =~= b),
3745{
3746}
3747
3748pub broadcast proof fn lemma_seq_take_update_commut1<A>(s: Seq<A>, i: int, v: A, n: int)
3755 ensures
3756 #![trigger s.update(i, v).take(n)]
3757 0 <= i < n <= s.len() ==> #[trigger] s.update(i, v).take(n) =~= s.take(n).update(i, v),
3758{
3759}
3760
3761pub broadcast proof fn lemma_seq_take_update_commut2<A>(s: Seq<A>, i: int, v: A, n: int)
3766 ensures
3767 0 <= n <= i < s.len() ==> #[trigger] s.update(i, v).take(n) =~= s.take(n),
3768{
3769}
3770
3771pub broadcast proof fn lemma_seq_skip_update_commut1<A>(s: Seq<A>, i: int, v: A, n: int)
3776 ensures
3777 0 <= n <= i < s.len() ==> #[trigger] s.update(i, v).skip(n) =~= s.skip(n).update(i - n, v),
3778{
3779}
3780
3781pub broadcast proof fn lemma_seq_skip_update_commut2<A>(s: Seq<A>, i: int, v: A, n: int)
3786 ensures
3787 0 <= i < n <= s.len() ==> #[trigger] s.update(i, v).skip(n) =~= s.skip(n),
3788{
3789}
3790
3791pub broadcast proof fn lemma_seq_skip_build_commut<A>(s: Seq<A>, v: A, n: int)
3795 ensures
3796 #![trigger s.push(v).skip(n)]
3797 0 <= n <= s.len() ==> s.push(v).skip(n) =~= s.skip(n).push(v),
3798{
3799}
3800
3801pub broadcast proof fn lemma_seq_skip_nothing<A>(s: Seq<A>, n: int)
3804 ensures
3805 n == 0 ==> #[trigger] s.skip(n) =~= s,
3806{
3807}
3808
3809pub broadcast proof fn lemma_seq_take_nothing<A>(s: Seq<A>, n: int)
3812 ensures
3813 n == 0 ==> #[trigger] s.take(n) =~= Seq::<A>::empty(),
3814{
3815}
3816
3817pub broadcast proof fn lemma_seq_skip_of_skip<A>(s: Seq<A>, m: int, n: int)
3822 ensures
3823 (0 <= m && 0 <= n && m + n <= s.len()) ==> #[trigger] s.skip(m).skip(n) =~= s.skip(m + n),
3824{
3825}
3826
3827#[doc(hidden)]
3828#[verifier::inline]
3829pub open spec fn check_argument_is_seq<A>(s: Seq<A>) -> Seq<A> {
3830 s
3831}
3832
3833#[macro_export]
3878macro_rules! assert_seqs_equal {
3879 [$($tail:tt)*] => {
3880 $crate::vstd::prelude::verus_proof_macro_exprs!($crate::vstd::seq_lib::assert_seqs_equal_internal!($($tail)*))
3881 };
3882}
3883
3884#[macro_export]
3885#[doc(hidden)]
3886macro_rules! assert_seqs_equal_internal {
3887 (::vstd::spec_eq($s1:expr, $s2:expr)) => {
3888 $crate::vstd::seq_lib::assert_seqs_equal_internal!($s1, $s2)
3889 };
3890 (::vstd::prelude::spec_eq($s1:expr, $s2:expr)) => {
3891 $crate::vstd::seq_lib::assert_seqs_equal_internal!($s1, $s2)
3892 };
3893 (::vstd::prelude::spec_eq($s1:expr, $s2:expr), $idx:ident => $bblock:block) => {
3894 $crate::vstd::seq_lib::assert_seqs_equal_internal!($s1, $s2, $idx => $bblock)
3895 };
3896 (crate::prelude::spec_eq($s1:expr, $s2:expr)) => {
3897 $crate::vstd::seq_lib::assert_seqs_equal_internal!($s1, $s2)
3898 };
3899 (crate::prelude::spec_eq($s1:expr, $s2:expr), $idx:ident => $bblock:block) => {
3900 $crate::vstd::seq_lib::assert_seqs_equal_internal!($s1, $s2, $idx => $bblock)
3901 };
3902 (crate::verus_builtin::spec_eq($s1:expr, $s2:expr)) => {
3903 $crate::vstd::seq_lib::assert_seqs_equal_internal!($s1, $s2)
3904 };
3905 (crate::verus_builtin::spec_eq($s1:expr, $s2:expr), $idx:ident => $bblock:block) => {
3906 $crate::vstd::seq_lib::assert_seqs_equal_internal!($s1, $s2, $idx => $bblock)
3907 };
3908 ($s1:expr, $s2:expr $(,)?) => {
3909 $crate::vstd::seq_lib::assert_seqs_equal_internal!($s1, $s2, idx => { })
3910 };
3911 ($s1:expr, $s2:expr, $idx:ident => $bblock:block) => {
3912 #[verifier::spec] let s1 = $crate::vstd::seq_lib::check_argument_is_seq($s1);
3913 #[verifier::spec] let s2 = $crate::vstd::seq_lib::check_argument_is_seq($s2);
3914 $crate::vstd::prelude::assert_by($crate::vstd::prelude::equal(s1, s2), {
3915 $crate::vstd::prelude::assert_(s1.len() == s2.len());
3916 $crate::vstd::prelude::assert_forall_by(|$idx : $crate::vstd::prelude::int| {
3917 $crate::vstd::prelude::requires($crate::vstd::prelude::verus_proof_expr!(0 <= $idx && $idx < s1.len()));
3918 $crate::vstd::prelude::ensures($crate::vstd::prelude::equal(s1.index($idx), s2.index($idx)));
3919 { $bblock }
3920 });
3921 $crate::vstd::prelude::assert_($crate::vstd::prelude::ext_equal(s1, s2));
3922 });
3923 }
3924}
3925
3926pub broadcast group group_filter_ensures {
3927 Seq::lemma_filter_len,
3928 Seq::lemma_filter_pred,
3929 Seq::lemma_filter_contains,
3930}
3931
3932pub broadcast group group_seq_lib_default {
3933 Seq::to_set_ensures,
3934 group_filter_ensures,
3935 Seq::lemma_filter_index,
3936 Seq::add_empty_left,
3937 Seq::add_empty_right,
3938 Seq::push_distributes_over_add,
3939 Seq::filter_distributes_over_add,
3940 Seq::lemma_fold_right_split,
3941 Seq::lemma_fold_left_split,
3942}
3943
3944pub broadcast group group_to_multiset_ensures {
3945 to_multiset_build,
3946 to_multiset_remove,
3947 to_multiset_len,
3948 to_multiset_contains,
3949 to_multiset_insert,
3950 to_multiset_update,
3951}
3952
3953pub broadcast group group_seq_properties {
3955 lemma_seq_contains,
3956 lemma_seq_empty_contains_nothing,
3957 lemma_seq_empty_equality,
3958 lemma_seq_concat_contains_all_elements,
3959 lemma_seq_contains_after_push,
3960 lemma_seq_subrange_elements,
3961 lemma_seq_take_len,
3962 lemma_seq_take_contains,
3963 lemma_seq_take_index,
3964 lemma_seq_skip_len,
3965 lemma_seq_skip_contains,
3966 lemma_seq_skip_index,
3967 lemma_seq_skip_index2,
3968 lemma_seq_append_take_skip,
3969 lemma_seq_take_update_commut1,
3970 lemma_seq_take_update_commut2,
3971 lemma_seq_skip_update_commut1,
3972 lemma_seq_skip_update_commut2,
3973 lemma_seq_skip_build_commut,
3974 lemma_seq_skip_nothing,
3975 lemma_seq_take_nothing,
3976 group_to_multiset_ensures,
3980}
3981
3982#[doc(hidden)]
3983pub use assert_seqs_equal_internal;
3984pub use assert_seqs_equal;
3985
3986}