1#[cfg(creusot)]
2use crate::resolve::structural_resolve;
3use crate::{
4 ghost::Plain,
5 logic::{Mapping, ops::IndexLogic},
6 ord_laws_impl,
7 prelude::*,
8 std::ops::RangeInclusiveExt as _,
9};
10use core::{
11 cmp,
12 marker::PhantomData,
13 ops::{Range, RangeFrom, RangeFull, RangeInclusive, RangeTo, RangeToInclusive},
14};
15
16#[builtin("seq.Seq.seq")]
47pub struct Seq<T>(PhantomData<T>);
48
49impl<T> Seq<T> {
51 #[logic]
53 #[builtin("seq.Seq.empty", ascription)]
54 pub fn empty() -> Self {
55 dead
56 }
57
58 #[logic]
71 #[builtin("seq.Seq.create")]
72 pub fn create(n: Int, mapping: Mapping<Int, T>) -> Self {
73 let _ = n;
74 let _ = mapping;
75 dead
76 }
77
78 #[logic(open)]
82 pub fn get(self, ix: Int) -> Option<T> {
83 if 0 <= ix && ix < self.len() { Some(self.index_logic(ix)) } else { None }
84 }
85
86 #[logic]
101 #[builtin("seq.Seq.get")]
102 pub fn index_logic_unsized<'a>(self, ix: Int) -> &'a T {
103 let _ = ix;
104 dead
105 }
106
107 #[logic]
123 #[builtin("seq.Seq.([..])")]
124 pub fn subsequence(self, start: Int, end: Int) -> Self {
125 let _ = start;
126 let _ = end;
127 dead
128 }
129
130 #[logic]
141 #[builtin("seq.Seq.singleton")]
142 pub fn singleton(value: T) -> Self {
143 let _ = value;
144 dead
145 }
146
147 #[logic(open)]
161 pub fn tail(self) -> Self {
162 self.subsequence(1, self.len())
163 }
164
165 #[logic(open)]
167 pub fn pop_front(self) -> Self {
168 self.tail()
169 }
170
171 #[logic(open)]
185 pub fn pop_back(self) -> Self {
186 self.subsequence(0, self.len() - 1)
187 }
188
189 #[logic]
199 #[builtin("seq.Seq.length")]
200 pub fn len(self) -> Int {
201 dead
202 }
203
204 #[logic]
218 #[builtin("seq.Seq.set")]
219 pub fn set(self, ix: Int, x: T) -> Self {
220 let _ = ix;
221 let _ = x;
222 dead
223 }
224
225 #[logic]
232 #[builtin("seq.Seq.(==)")]
233 pub fn ext_eq(self, other: Self) -> bool {
234 let _ = other;
235 dead
236 }
237
238 #[doc(hidden)]
240 #[logic]
241 #[builtin("seq.Seq.cons")]
242 pub fn cons(_: T, _: Self) -> Self {
243 dead
244 }
245
246 #[logic(open, inline)]
257 pub fn push_front(self, x: T) -> Self {
258 Self::cons(x, self)
259 }
260
261 #[logic]
272 #[builtin("seq.Seq.snoc")]
273 pub fn push_back(self, x: T) -> Self {
274 let _ = x;
275 dead
276 }
277
278 #[logic]
294 #[builtin("seq.Seq.(++)")]
295 pub fn concat(self, other: Self) -> Self {
296 let _ = other;
297 dead
298 }
299
300 #[logic]
301 #[ensures(result.len() == self.len())]
302 #[ensures(forall<i> 0 <= i && i < self.len() ==> result[i] == m[self[i]])]
303 #[variant(self.len())]
304 pub fn map<U>(self, m: Mapping<T, U>) -> Seq<U> {
305 if self.len() == 0 {
306 Seq::empty()
307 } else {
308 self.tail().map(m).push_front(m.get(*self.index_logic_unsized(0)))
309 }
310 }
311
312 #[logic(open)]
313 #[variant(self.len())]
314 pub fn flat_map<U>(self, other: Mapping<T, Seq<U>>) -> Seq<U> {
315 if self.len() == 0 {
316 Seq::empty()
317 } else {
318 other.get(*self.index_logic_unsized(0)).concat(self.tail().flat_map(other))
319 }
320 }
321
322 #[logic]
335 #[builtin("seq.Reverse.reverse")]
336 pub fn reverse(self) -> Self {
337 dead
338 }
339
340 #[logic]
341 #[ensures(Self::empty().reverse() == Self::empty())]
342 pub fn reverse_empty() {}
343
344 #[logic(open)]
356 pub fn removed(self, index: Int) -> Self {
357 pearlite! { self[..index].concat(self[index+1..]) }
358 }
359
360 #[logic(open)]
362 pub fn permutation_of(self, other: Self) -> bool {
363 self.permut(other, 0, self.len())
364 }
365
366 #[logic]
371 #[builtin("seq.Permut.permut")]
372 pub fn permut(self, other: Self, start: Int, end: Int) -> bool {
373 let _ = other;
374 let _ = start;
375 let _ = end;
376 dead
377 }
378
379 #[logic]
384 #[builtin("seq.Permut.exchange")]
385 pub fn exchange(self, other: Self, i: Int, j: Int) -> bool {
386 let _ = other;
387 let _ = i;
388 let _ = j;
389 dead
390 }
391
392 #[logic(open)]
394 pub fn contains(self, x: T) -> bool {
395 pearlite! { exists<i> 0 <= i && i < self.len() && self[i] == x }
396 }
397
398 #[logic(open)]
400 pub fn sorted_range(self, start: Int, end: Int) -> bool
401 where
402 T: OrdLogic,
403 {
404 pearlite! {
405 forall<i, j> start <= i && i <= j && j < end ==> self[i] <= self[j]
406 }
407 }
408
409 #[logic(open)]
411 pub fn sorted(self) -> bool
412 where
413 T: OrdLogic,
414 {
415 self.sorted_range(0, self.len())
416 }
417
418 #[logic(open)]
419 #[ensures(forall<a: Seq<T>, b: Seq<T>, x>
420 a.concat(b).contains(x) == a.contains(x) || b.contains(x))]
421 pub fn concat_contains() {}
422
423 #[logic]
424 #[ensures(self.concat(other1).concat(other2) == self.concat(other1.concat(other2)))]
425 pub fn concat_assoc(self, other1: Self, other2: Self) {}
426
427 #[logic]
428 #[ensures(self.concat(Seq::empty()) == self)]
429 #[ensures(Seq::empty().concat(self) == self)]
430 pub fn concat_empty(self) {}
431
432 #[logic]
433 #[ensures(self.concat(other).reverse() == other.reverse().concat(self.reverse()))]
434 pub fn reverse_concat(self, other: Self) {}
435}
436
437impl<T> Seq<Seq<T>> {
438 #[logic(open)]
439 #[variant(self.len())]
440 pub fn flatten(self) -> Seq<T> {
441 if self.len() == 0 {
442 Seq::empty()
443 } else {
444 self.index_logic_unsized(0).concat(self.tail().flatten())
445 }
446 }
447}
448
449impl<T> Seq<&T> {
450 #[logic]
454 #[builtin("identity")]
455 pub fn to_owned_seq(self) -> Seq<T> {
456 dead
457 }
458}
459
460impl<T> IndexLogic<Int> for Seq<T> {
461 type Item = T;
462
463 #[logic]
464 #[builtin("seq.Seq.get")]
465 fn index_logic(self, _: Int) -> Self::Item {
466 dead
467 }
468}
469
470impl<T> IndexLogic<Range<Int>> for Seq<T> {
471 type Item = Seq<T>;
472
473 #[logic(open, inline)]
474 fn index_logic(self, range: Range<Int>) -> Self::Item {
475 self.subsequence(range.start, range.end)
476 }
477}
478
479impl<T> IndexLogic<RangeInclusive<Int>> for Seq<T> {
480 type Item = Seq<T>;
481
482 #[logic(open, inline)]
483 fn index_logic(self, range: RangeInclusive<Int>) -> Self::Item {
484 self.subsequence(range.start_log(), range.end_log() + 1)
485 }
486}
487
488impl<T> IndexLogic<RangeFull> for Seq<T> {
489 type Item = Seq<T>;
490
491 #[logic(open, inline)]
492 fn index_logic(self, _: RangeFull) -> Self::Item {
493 self
494 }
495}
496
497impl<T> IndexLogic<RangeFrom<Int>> for Seq<T> {
498 type Item = Seq<T>;
499
500 #[logic(open, inline)]
501 fn index_logic(self, range: RangeFrom<Int>) -> Self::Item {
502 self.subsequence(range.start, self.len())
503 }
504}
505
506impl<T> IndexLogic<RangeTo<Int>> for Seq<T> {
507 type Item = Seq<T>;
508
509 #[logic(open, inline)]
510 fn index_logic(self, range: RangeTo<Int>) -> Self::Item {
511 self.subsequence(0, range.end)
512 }
513}
514
515impl<T> IndexLogic<RangeToInclusive<Int>> for Seq<T> {
516 type Item = Seq<T>;
517
518 #[logic(open, inline)]
519 fn index_logic(self, range: RangeToInclusive<Int>) -> Self::Item {
520 self.subsequence(0, range.end + 1)
521 }
522}
523
524impl<T> Seq<T> {
526 #[trusted]
538 #[check(ghost)]
539 #[ensures(*result == Self::empty())]
540 #[allow(unreachable_code)]
541 pub fn new() -> Ghost<Self> {
542 Ghost::conjure()
543 }
544
545 #[trusted]
563 #[check(ghost)]
564 #[ensures(result == self.len())]
565 pub fn len_ghost(&self) -> Int {
566 panic!()
567 }
568
569 #[trusted]
587 #[check(ghost)]
588 #[ensures(result == (self.len() == 0))]
589 pub fn is_empty_ghost(&self) -> bool {
590 panic!()
591 }
592
593 #[trusted]
608 #[check(ghost)]
609 #[ensures(^self == self.push_front(x))]
610 pub fn push_front_ghost(&mut self, x: T) {
611 let _ = x;
612 panic!()
613 }
614
615 #[trusted]
630 #[check(ghost)]
631 #[ensures(^self == self.push_back(x))]
632 pub fn push_back_ghost(&mut self, x: T) {
633 let _ = x;
634 panic!()
635 }
636
637 #[check(ghost)]
655 #[ensures(match self.get(index) {
656 None => result == None,
657 Some(v) => result == Some(&v),
658 })]
659 pub fn get_ghost(&self, index: Int) -> Option<&T> {
660 if index - index <= index && index < self.len_ghost() {
662 Some(self.as_refs().extract(index))
663 } else {
664 None
665 }
666 }
667
668 #[check(ghost)]
687 #[ensures(match result {
688 None => self.get(index) == None && *self == ^self,
689 Some(r) => self.get(index) == Some(*r) && ^r == (^self)[index],
690 })]
691 #[ensures(forall<i> i != index ==> (*self).get(i) == (^self).get(i))]
692 #[ensures((*self).len() == (^self).len())]
693 pub fn get_mut_ghost(&mut self, index: Int) -> Option<&mut T> {
694 if index - index <= index && index < self.len_ghost() {
696 Some(self.as_muts().extract(index))
697 } else {
698 None
699 }
700 }
701
702 #[check(ghost)]
706 #[requires(0 <= index && index < self.len())]
707 #[ensures(result == self[index])]
708 #[ensures(forall<i> 0 <= i && i < self.len() && i != index ==> resolve(self[i]))]
709 pub fn extract(mut self, index: Int) -> T {
710 proof_assert! { forall<i> index < i && i < self.len() ==> self[i] == self[index + 1..][i - index - 1] }
711 self.split_off_ghost(index).pop_front_ghost().unwrap()
712 }
713
714 #[check(ghost)]
718 #[requires(0 <= index && index < self.len())]
719 #[ensures(result == self[index])]
720 #[ensures(^self == (*self).removed(index))]
721 pub fn remove(&mut self, index: Int) -> T {
722 let mut right = self.split_off_ghost(index);
723 let result = right.pop_front_ghost().unwrap();
724 self.extend(right);
725 result
726 }
727
728 #[check(ghost)]
739 #[ensures(^self == (*self).concat(rhs))]
740 pub fn extend(&mut self, mut rhs: Self) {
741 let _final = snapshot! { self.concat(rhs) };
742 #[variant(rhs.len())]
743 #[invariant(self.concat(rhs) == *_final)]
744 while let Some(x) = rhs.pop_front_ghost() {
745 self.push_back_ghost(x)
746 }
747 }
748
749 #[trusted]
766 #[check(ghost)]
767 #[ensures(match result {
768 None => *self == Seq::empty() && *self == ^self,
769 Some(r) => *self == (^self).push_back(r)
770 })]
771 pub fn pop_back_ghost(&mut self) -> Option<T> {
772 panic!()
773 }
774
775 #[trusted]
792 #[check(ghost)]
793 #[ensures(match result {
794 None => *self == Seq::empty() && *self == ^self,
795 Some(r) => (*self).len() > 0 && r == (*self)[0] && ^self == (*self).tail()
796 })]
797 pub fn pop_front_ghost(&mut self) -> Option<T> {
798 panic!()
799 }
800
801 #[trusted]
817 #[check(ghost)]
818 #[ensures(^self == Self::empty())]
819 pub fn clear_ghost(&mut self) {}
820
821 #[trusted]
823 #[check(ghost)]
824 #[requires(0 <= mid && mid <= self.len())]
825 #[ensures(^self == self[..mid])]
826 #[ensures(result == self[mid..])]
827 pub fn split_off_ghost(&mut self, mid: Int) -> Self {
828 let _ = mid;
829 panic!("ghost code")
830 }
831
832 #[trusted]
834 #[check(ghost)]
835 #[ensures(*self == result.to_owned_seq())]
836 pub fn as_refs(&self) -> Seq<&T> {
837 panic!("ghost code")
838 }
839
840 #[trusted]
842 #[check(ghost)]
843 #[ensures(result.len() == self.len())]
844 #[ensures((^self).len() == self.len())]
845 #[ensures(forall<i> 0 <= i && i < self.len() ==> *result[i] == (*self)[i])]
846 #[ensures(forall<i> 0 <= i && i < self.len() ==> ^result[i] == (^self)[i])]
847 pub fn as_muts(&mut self) -> Seq<&mut T> {
848 panic!("ghost code")
849 }
850}
851
852impl<T> core::ops::Index<Int> for Seq<T> {
853 type Output = T;
854
855 #[check(ghost)]
856 #[requires(0 <= index && index < self.len())]
857 #[ensures(*result == self[index])]
858 fn index(&self, index: Int) -> &Self::Output {
859 self.get_ghost(index).unwrap()
860 }
861}
862impl<T> core::ops::IndexMut<Int> for Seq<T> {
863 #[check(ghost)]
864 #[requires(0 <= index && index < self.len())]
865 #[ensures((*self).len() == (^self).len())]
866 #[ensures(*result == (*self)[index] && ^result == (^self)[index])]
867 #[ensures(forall<i> i != index ==> (*self).get(i) == (^self).get(i))]
868 fn index_mut(&mut self, index: Int) -> &mut Self::Output {
869 self.get_mut_ghost(index).unwrap()
870 }
871}
872
873impl<T> core::ops::Index<(Int, Int)> for Seq<T> {
874 type Output = (T, T);
875
876 #[trusted]
877 #[check(ghost)]
878 #[requires(0 <= index.0 && index.0 < self.len() && 0 <= index.1 && index.1 < self.len())]
879 #[ensures(result.0 == self[index.0] && result.1 == self[index.1])]
880 #[allow(unused_variables)]
881 fn index(&self, index: (Int, Int)) -> &Self::Output {
882 panic!()
883 }
884}
885
886impl<T> core::ops::IndexMut<(Int, Int)> for Seq<T> {
887 #[trusted]
888 #[check(ghost)]
889 #[requires(0 <= index.0 && index.0 < self.len() && 0 <= index.1 && index.1 < self.len())]
890 #[requires(index.0 != index.1)]
891 #[ensures((*result).0 == (*self)[index.0] && (*result).1 == (*self)[index.1]
892 && (^result).0 == (^self)[index.0] && (^result).1 == (^self)[index.1])]
893 #[ensures(forall<i> i != index.0 && i != index.1 ==> (*self).get(i) == (^self).get(i))]
894 #[ensures((*self).len() == (^self).len())]
895 #[allow(unused_variables)]
896 fn index_mut(&mut self, index: (Int, Int)) -> &mut Self::Output {
897 panic!()
898 }
899}
900
901impl<T: Clone + Copy> Clone for Seq<T> {
903 #[trusted]
904 #[check(ghost)]
905 #[ensures(result == *self)]
906 fn clone(&self) -> Self {
907 *self
908 }
909}
910
911impl<T: Copy> Copy for Seq<T> {}
912impl<T: Plain> Plain for Seq<T> {
913 #[ensures(*result == *snap)]
914 #[check(ghost)]
915 #[allow(unused_variables)]
916 fn into_ghost(snap: Snapshot<Self>) -> Ghost<Self> {
917 ghost! {
918 let mut res = Seq::new().into_inner();
919 let len: Snapshot<Int> = snapshot!(snap.len());
920 let len = len.into_ghost().into_inner();
921 let mut i = 0int;
922 #[variant(len - i)]
923 #[invariant(i <= len)]
924 #[invariant(res.len() == i)]
925 #[invariant(forall<j> 0 <= j && j < i ==> res[j] == snap[j])]
926 while i < len {
927 let elem: Snapshot<T> = snapshot!(snap[i]);
928 res.push_back_ghost(elem.into_ghost().into_inner());
929 i = i + 1int;
930 }
931 res
932 }
933 }
934}
935
936impl<T> Invariant for Seq<T> {
937 #[logic(open, prophetic, inline)]
938 #[creusot::trusted_trivial_if_param_trivial]
939 fn invariant(self) -> bool {
940 pearlite! { forall<i> 0 <= i && i < self.len() ==> inv(self.index_logic_unsized(i)) }
941 }
942}
943
944impl<T: OrdLogic> Seq<T> {
945 #[logic]
946 fn lexico_lt_log(self, other: Self) -> bool {
947 pearlite! {
948 (exists<i: Int> 0 <= i && i < self.len() && i < other.len() &&
949 (forall<j: Int> 0 <= j && j < i ==> self[j] == other[j]) &&
950 self[i] < other[i])
951 ||
952 self.len() < other.len() &&
953 (forall<i: Int> 0 <= i && i < self.len() ==> self[i] == other[i])
954 }
955 }
956
957 #[logic]
958 #[requires(x.lexico_lt_log(y) && y.lexico_lt_log(z))]
959 #[ensures(x.lexico_lt_log(z))]
960 fn lexico_lt_log_trans(x: Self, y: Self, z: Self) {}
961
962 #[logic]
963 #[ensures(!self.lexico_lt_log(self))]
964 fn lexico_lt_log_irreflexive(self) {}
965
966 #[logic]
967 #[requires(self.len() > 0 && other.len() > 0)]
968 #[requires(self[0] == other[0])]
969 #[ensures(self.lexico_lt_log(other) == self[1..].lexico_lt_log(other[1..]))]
970 fn lexico_lt_log_tail(self, other: Self) {}
971
972 #[logic]
973 #[ensures(self.lexico_lt_log(other) || self == other || other.lexico_lt_log(self))]
974 #[variant(self.len())]
975 fn lexico_lt_log_total(self, other: Self) {
976 if self.len() > 0 && other.len() > 0 && self[0] == other[0] {
977 self[1..].lexico_lt_log_total(other[1..]);
978 self.lexico_lt_log_tail(other);
979 other.lexico_lt_log_tail(self);
980 proof_assert!(forall<i> 0 < i && i < self.len() ==> self[i] == self[1..][i-1]);
981 proof_assert!(forall<i> 0 < i && i < other.len() ==> other[i] == other[1..][i-1]);
982 }
983 }
984}
985
986impl<T: OrdLogic> OrdLogic for Seq<T> {
987 #[logic]
988 #[ensures(match result {
989 cmp::Ordering::Equal => self == other,
990 _ => {
991 (exists<i: Int> 0 <= i && i < self.len() && i < other.len() &&
992 (forall<j: Int> 0 <= j && j < i ==> self[j] == other[j]) &&
993 result == self[i].cmp_log(other[i]))
994 ||
995 result == self.len().cmp_log(other.len()) &&
996 (forall<i: Int> 0 <= i && i < self.len() && i < other.len() ==> self[i] == other[i])
997 }})]
998 fn cmp_log(self, other: Self) -> cmp::Ordering {
999 if self.lexico_lt_log(other) {
1000 cmp::Ordering::Less
1001 } else if other.lexico_lt_log(self) {
1002 cmp::Ordering::Greater
1003 } else {
1004 proof_assert!(self.lexico_lt_log_total(other); true);
1005 cmp::Ordering::Equal
1006 }
1007 }
1008
1009 ord_laws_impl! {
1010 let _ = Self::lexico_lt_log_trans;
1011 let _ = Self::lexico_lt_log_irreflexive;
1012 }
1013}
1014
1015pub struct Iter<T>(Seq<T>);
1044
1045impl<T> View for Iter<T> {
1046 type ViewTy = Seq<T>;
1047 #[logic]
1048 fn view(self) -> Self::ViewTy {
1049 self.0
1050 }
1051}
1052
1053impl<T> Iterator for Iter<T> {
1054 type Item = T;
1055
1056 #[check(ghost)]
1057 #[ensures(match result {
1058 None => self.completed(),
1059 Some(v) => (*self).produces(Seq::singleton(v), ^self)
1060 })]
1061 fn next(&mut self) -> Option<T> {
1062 self.0.pop_front_ghost()
1063 }
1064}
1065
1066impl<T> IteratorSpec for Iter<T> {
1067 #[logic(prophetic, open)]
1068 fn produces(self, visited: Seq<T>, o: Self) -> bool {
1069 pearlite! { self@ == visited.concat(o@) }
1070 }
1071
1072 #[logic(prophetic, open)]
1073 fn completed(&mut self) -> bool {
1074 pearlite! { self@ == Seq::empty() }
1075 }
1076
1077 #[logic(law)]
1078 #[ensures(self.produces(Seq::empty(), self))]
1079 fn produces_refl(self) {}
1080
1081 #[logic(law)]
1082 #[requires(a.produces(ab, b))]
1083 #[requires(b.produces(bc, c))]
1084 #[ensures(a.produces(ab.concat(bc), c))]
1085 fn produces_trans(a: Self, ab: Seq<Self::Item>, b: Self, bc: Seq<Self::Item>, c: Self) {}
1086}
1087
1088impl<T> IntoIterator for Seq<T> {
1089 type Item = T;
1090 type IntoIter = Iter<T>;
1091
1092 #[check(ghost)]
1093 #[ensures(self == result@)]
1094 fn into_iter(self) -> Self::IntoIter {
1095 Iter(self)
1096 }
1097}
1098
1099impl<'a, T> IntoIterator for &'a Seq<T> {
1100 type Item = &'a T;
1101 type IntoIter = Iter<&'a T>;
1102
1103 #[check(ghost)]
1104 #[ensures(*self == result@.to_owned_seq())]
1105 fn into_iter(self) -> Self::IntoIter {
1106 Iter(self.as_refs())
1107 }
1108}
1109
1110impl<'a, T> IntoIterator for &'a mut Seq<T> {
1111 type Item = &'a mut T;
1112 type IntoIter = Iter<&'a mut T>;
1113
1114 #[check(ghost)]
1115 #[ensures(result@.len() == self.len())]
1116 #[ensures((^self).len() == self.len())]
1117 #[ensures(forall<i> 0 <= i && i < self.len() ==> *result@[i] == (*self)[i])]
1118 #[ensures(forall<i> 0 <= i && i < self.len() ==> ^result@[i] == (^self)[i])]
1119 fn into_iter(self) -> Self::IntoIter {
1120 Iter(self.as_muts())
1121 }
1122}
1123
1124impl<T> Resolve for Seq<T> {
1125 #[logic(open, prophetic)]
1126 #[creusot::trusted_trivial_if_param_trivial]
1127 fn resolve(self) -> bool {
1128 pearlite! { forall<i : Int> resolve(self.get(i)) }
1129 }
1130
1131 #[trusted]
1132 #[logic(prophetic)]
1133 #[requires(structural_resolve(self))]
1134 #[ensures(self.resolve())]
1135 fn resolve_coherence(self) {}
1136}
1137
1138impl<T> Resolve for Iter<T> {
1139 #[logic(open, prophetic, inline)]
1140 #[creusot::trusted_trivial_if_param_trivial]
1141 fn resolve(self) -> bool {
1142 pearlite! { resolve(self@) }
1143 }
1144
1145 #[logic(prophetic)]
1146 #[requires(structural_resolve(self))]
1147 #[ensures(self.resolve())]
1148 fn resolve_coherence(self) {}
1149}
1150
1151impl<T> Seq<T> {
1153 #[logic(open)]
1154 #[ensures(Seq::singleton(x).flat_map(f) == f.get(x))]
1155 pub fn flat_map_singleton<U>(x: T, f: Mapping<T, Seq<U>>) {}
1156
1157 #[logic(open)]
1158 #[ensures(self.push_back(x).flat_map(f) == self.flat_map(f).concat(f.get(x)))]
1159 #[variant(self.len())]
1160 pub fn flat_map_push_back<U>(self, x: T, f: Mapping<T, Seq<U>>) {
1161 if self.len() > 0 {
1162 Self::flat_map_push_back::<U>(self.tail(), x, f);
1163 proof_assert! { self.tail().push_back(x) == self.push_back(x).tail() }
1164 }
1165 }
1166}