1#[cfg(creusot)]
2use crate::resolve::structural_resolve;
3use crate::{
4 ghost::Plain,
5 logic::{Mapping, ops::IndexLogic},
6 prelude::*,
7 std::ops::RangeInclusiveExt as _,
8};
9use core::{
10 marker::PhantomData,
11 ops::{Range, RangeFrom, RangeFull, RangeInclusive, RangeTo, RangeToInclusive},
12};
13
14#[builtin("seq.Seq.seq")]
45pub struct Seq<T>(PhantomData<T>);
46
47impl<T> Seq<T> {
49 #[logic]
51 #[builtin("seq.Seq.empty", ascription)]
52 pub fn empty() -> Self {
53 dead
54 }
55
56 #[logic]
69 #[builtin("seq.Seq.create")]
70 pub fn create(n: Int, mapping: Mapping<Int, T>) -> Self {
71 let _ = n;
72 let _ = mapping;
73 dead
74 }
75
76 #[logic(open)]
80 pub fn get(self, ix: Int) -> Option<T> {
81 if 0 <= ix && ix < self.len() { Some(self.index_logic(ix)) } else { None }
82 }
83
84 #[logic]
99 #[builtin("seq.Seq.get")]
100 pub fn index_logic_unsized<'a>(self, ix: Int) -> &'a T {
101 let _ = ix;
102 dead
103 }
104
105 #[logic]
121 #[builtin("seq.Seq.([..])")]
122 pub fn subsequence(self, start: Int, end: Int) -> Self {
123 let _ = start;
124 let _ = end;
125 dead
126 }
127
128 #[logic]
139 #[builtin("seq.Seq.singleton")]
140 pub fn singleton(value: T) -> Self {
141 let _ = value;
142 dead
143 }
144
145 #[logic(open)]
159 pub fn tail(self) -> Self {
160 self.subsequence(1, self.len())
161 }
162
163 #[logic(open)]
165 pub fn pop_front(self) -> Self {
166 self.tail()
167 }
168
169 #[logic(open)]
183 pub fn pop_back(self) -> Self {
184 self.subsequence(0, self.len() - 1)
185 }
186
187 #[logic]
197 #[builtin("seq.Seq.length")]
198 pub fn len(self) -> Int {
199 dead
200 }
201
202 #[logic]
216 #[builtin("seq.Seq.set")]
217 pub fn set(self, ix: Int, x: T) -> Self {
218 let _ = ix;
219 let _ = x;
220 dead
221 }
222
223 #[logic]
230 #[builtin("seq.Seq.(==)")]
231 pub fn ext_eq(self, other: Self) -> bool {
232 let _ = other;
233 dead
234 }
235
236 #[doc(hidden)]
238 #[logic]
239 #[builtin("seq.Seq.cons")]
240 pub fn cons(_: T, _: Self) -> Self {
241 dead
242 }
243
244 #[logic(open, inline)]
255 pub fn push_front(self, x: T) -> Self {
256 Self::cons(x, self)
257 }
258
259 #[logic]
270 #[builtin("seq.Seq.snoc")]
271 pub fn push_back(self, x: T) -> Self {
272 let _ = x;
273 dead
274 }
275
276 #[logic]
292 #[builtin("seq.Seq.(++)")]
293 pub fn concat(self, other: Self) -> Self {
294 let _ = other;
295 dead
296 }
297
298 #[logic]
299 #[ensures(result.len() == self.len())]
300 #[ensures(forall<i> 0 <= i && i < self.len() ==> result[i] == m[self[i]])]
301 #[variant(self.len())]
302 pub fn map<U>(self, m: Mapping<T, U>) -> Seq<U> {
303 if self.len() == 0 {
304 Seq::empty()
305 } else {
306 self.tail().map(m).push_front(m.get(*self.index_logic_unsized(0)))
307 }
308 }
309
310 #[logic(open)]
311 #[variant(self.len())]
312 pub fn flat_map<U>(self, other: Mapping<T, Seq<U>>) -> Seq<U> {
313 if self.len() == 0 {
314 Seq::empty()
315 } else {
316 other.get(*self.index_logic_unsized(0)).concat(self.tail().flat_map(other))
317 }
318 }
319
320 #[logic]
333 #[builtin("seq.Reverse.reverse")]
334 pub fn reverse(self) -> Self {
335 dead
336 }
337
338 #[logic]
339 #[ensures(Self::empty().reverse() == Self::empty())]
340 pub fn reverse_empty() {}
341
342 #[logic]
343 #[requires(0 <= position && position <= self.len())]
344 #[ensures(result.len() == self.len() + 1)]
345 #[ensures(forall<i> 0 <= i && i <= self.len() ==>
346 if i < position {
347 result[i] == self[i]
348 } else if i == position {
349 result[i] == value
350 } else {
351 result[i] == self[i - 1]
352 }
353 )]
354 #[variant(position)]
355 pub fn insert(self, position: Int, value: T) -> Self {
356 if position == 0 {
357 self.push_front(value)
358 } else {
359 self.pop_front().insert(position - 1, value).push_front(self[0])
360 }
361 }
362
363 #[logic(open)]
375 pub fn removed(self, index: Int) -> Self {
376 pearlite! { self[..index].concat(self[index+1..]) }
377 }
378
379 #[logic(open)]
381 pub fn permutation_of(self, other: Self) -> bool {
382 self.permut(other, 0, self.len())
383 }
384
385 #[logic]
390 #[builtin("seq.Permut.permut")]
391 pub fn permut(self, other: Self, start: Int, end: Int) -> bool {
392 let _ = other;
393 let _ = start;
394 let _ = end;
395 dead
396 }
397
398 #[logic]
403 #[builtin("seq.Permut.exchange")]
404 pub fn exchange(self, other: Self, i: Int, j: Int) -> bool {
405 let _ = other;
406 let _ = i;
407 let _ = j;
408 dead
409 }
410
411 #[logic(open)]
413 pub fn contains(self, x: T) -> bool {
414 pearlite! { exists<i> 0 <= i && i < self.len() && self[i] == x }
415 }
416
417 #[logic(open)]
419 pub fn sorted_range(self, start: Int, end: Int) -> bool
420 where
421 T: OrdLogic,
422 {
423 pearlite! {
424 forall<i, j> start <= i && i <= j && j < end ==> self[i] <= self[j]
425 }
426 }
427
428 #[logic(open)]
430 pub fn sorted(self) -> bool
431 where
432 T: OrdLogic,
433 {
434 self.sorted_range(0, self.len())
435 }
436
437 #[logic(open)]
438 #[ensures(forall<a: Seq<T>, b: Seq<T>, x>
439 a.concat(b).contains(x) == a.contains(x) || b.contains(x))]
440 pub fn concat_contains() {}
441
442 #[logic]
443 #[ensures(self.concat(other1).concat(other2) == self.concat(other1.concat(other2)))]
444 pub fn concat_assoc(self, other1: Self, other2: Self) {}
445
446 #[logic]
447 #[ensures(self.concat(Seq::empty()) == self)]
448 #[ensures(Seq::empty().concat(self) == self)]
449 pub fn concat_empty(self) {}
450
451 #[logic]
452 #[ensures(self.concat(other).reverse() == other.reverse().concat(self.reverse()))]
453 pub fn reverse_concat(self, other: Self) {}
454}
455
456impl<T> Seq<Seq<T>> {
457 #[logic(open)]
458 #[variant(self.len())]
459 pub fn flatten(self) -> Seq<T> {
460 if self.len() == 0 {
461 Seq::empty()
462 } else {
463 self.index_logic_unsized(0).concat(self.tail().flatten())
464 }
465 }
466}
467
468impl<T> Seq<&T> {
469 #[logic]
473 #[builtin("identity")]
474 pub fn to_owned_seq(self) -> Seq<T> {
475 dead
476 }
477}
478
479impl<T> IndexLogic<Int> for Seq<T> {
480 type Item = T;
481
482 #[logic]
483 #[builtin("seq.Seq.get")]
484 fn index_logic(self, _: Int) -> Self::Item {
485 dead
486 }
487}
488
489impl<T> IndexLogic<Range<Int>> for Seq<T> {
490 type Item = Seq<T>;
491
492 #[logic(open, inline)]
493 fn index_logic(self, range: Range<Int>) -> Self::Item {
494 self.subsequence(range.start, range.end)
495 }
496}
497
498impl<T> IndexLogic<RangeInclusive<Int>> for Seq<T> {
499 type Item = Seq<T>;
500
501 #[logic(open, inline)]
502 fn index_logic(self, range: RangeInclusive<Int>) -> Self::Item {
503 self.subsequence(range.start_log(), range.end_log() + 1)
504 }
505}
506
507impl<T> IndexLogic<RangeFull> for Seq<T> {
508 type Item = Seq<T>;
509
510 #[logic(open, inline)]
511 fn index_logic(self, _: RangeFull) -> Self::Item {
512 self
513 }
514}
515
516impl<T> IndexLogic<RangeFrom<Int>> for Seq<T> {
517 type Item = Seq<T>;
518
519 #[logic(open, inline)]
520 fn index_logic(self, range: RangeFrom<Int>) -> Self::Item {
521 self.subsequence(range.start, self.len())
522 }
523}
524
525impl<T> IndexLogic<RangeTo<Int>> for Seq<T> {
526 type Item = Seq<T>;
527
528 #[logic(open, inline)]
529 fn index_logic(self, range: RangeTo<Int>) -> Self::Item {
530 self.subsequence(0, range.end)
531 }
532}
533
534impl<T> IndexLogic<RangeToInclusive<Int>> for Seq<T> {
535 type Item = Seq<T>;
536
537 #[logic(open, inline)]
538 fn index_logic(self, range: RangeToInclusive<Int>) -> Self::Item {
539 self.subsequence(0, range.end + 1)
540 }
541}
542
543impl<T> Seq<T> {
545 #[trusted]
557 #[check(ghost)]
558 #[ensures(*result == Self::empty())]
559 #[allow(unreachable_code)]
560 pub fn new() -> Ghost<Self> {
561 Ghost::conjure()
562 }
563
564 #[trusted]
582 #[check(ghost)]
583 #[ensures(result == self.len())]
584 pub fn len_ghost(&self) -> Int {
585 panic!()
586 }
587
588 #[trusted]
606 #[check(ghost)]
607 #[ensures(result == (self.len() == 0))]
608 pub fn is_empty_ghost(&self) -> bool {
609 panic!()
610 }
611
612 #[trusted]
627 #[check(ghost)]
628 #[ensures(^self == self.push_front(x))]
629 pub fn push_front_ghost(&mut self, x: T) {
630 let _ = x;
631 panic!()
632 }
633
634 #[trusted]
649 #[check(ghost)]
650 #[ensures(^self == self.push_back(x))]
651 pub fn push_back_ghost(&mut self, x: T) {
652 let _ = x;
653 panic!()
654 }
655
656 #[check(ghost)]
674 #[ensures(match self.get(index) {
675 None => result == None,
676 Some(v) => result == Some(&v),
677 })]
678 pub fn get_ghost(&self, index: Int) -> Option<&T> {
679 if index - index <= index && index < self.len_ghost() {
681 Some(self.as_refs().extract(index))
682 } else {
683 None
684 }
685 }
686
687 #[check(ghost)]
706 #[ensures(match result {
707 None => self.get(index) == None && *self == ^self,
708 Some(r) => self.get(index) == Some(*r) && ^r == (^self)[index],
709 })]
710 #[ensures(forall<i> i != index ==> (*self).get(i) == (^self).get(i))]
711 #[ensures((*self).len() == (^self).len())]
712 pub fn get_mut_ghost(&mut self, index: Int) -> Option<&mut T> {
713 if index - index <= index && index < self.len_ghost() {
715 Some(self.as_muts().extract(index))
716 } else {
717 None
718 }
719 }
720
721 #[check(ghost)]
746 #[requires(0 <= position && position <= self.len())]
747 #[ensures((^self) == self.insert(position, x))]
748 #[variant(position)]
749 pub fn insert_ghost(&mut self, position: Int, x: T) {
750 let after = self.split_off_ghost(position);
751 self.push_back_ghost(x);
752 self.extend(after);
753 }
754
755 #[check(ghost)]
759 #[requires(0 <= index && index < self.len())]
760 #[ensures(result == self[index])]
761 #[ensures(forall<i> 0 <= i && i < self.len() && i != index ==> resolve(self[i]))]
762 pub fn extract(mut self, index: Int) -> T {
763 proof_assert! { forall<i> index < i && i < self.len() ==> self[i] == self[index + 1..][i - index - 1] }
764 self.split_off_ghost(index).pop_front_ghost().unwrap()
765 }
766
767 #[check(ghost)]
771 #[requires(0 <= index && index < self.len())]
772 #[ensures(result == self[index])]
773 #[ensures(^self == (*self).removed(index))]
774 pub fn remove(&mut self, index: Int) -> T {
775 let mut right = self.split_off_ghost(index);
776 let result = right.pop_front_ghost().unwrap();
777 self.extend(right);
778 result
779 }
780
781 #[check(ghost)]
792 #[ensures(^self == (*self).concat(rhs))]
793 pub fn extend(&mut self, mut rhs: Self) {
794 let _final = snapshot! { self.concat(rhs) };
795 #[variant(rhs.len())]
796 #[invariant(self.concat(rhs) == *_final)]
797 while let Some(x) = rhs.pop_front_ghost() {
798 self.push_back_ghost(x)
799 }
800 }
801
802 #[trusted]
819 #[check(ghost)]
820 #[ensures(match result {
821 None => *self == Seq::empty() && *self == ^self,
822 Some(r) => *self == (^self).push_back(r)
823 })]
824 pub fn pop_back_ghost(&mut self) -> Option<T> {
825 panic!()
826 }
827
828 #[trusted]
845 #[check(ghost)]
846 #[ensures(match result {
847 None => *self == Seq::empty() && *self == ^self,
848 Some(r) => (*self).len() > 0 && r == (*self)[0] && ^self == (*self).tail()
849 })]
850 pub fn pop_front_ghost(&mut self) -> Option<T> {
851 panic!()
852 }
853
854 #[trusted]
870 #[check(ghost)]
871 #[ensures(^self == Self::empty())]
872 pub fn clear_ghost(&mut self) {}
873
874 #[trusted]
876 #[check(ghost)]
877 #[requires(0 <= mid && mid <= self.len())]
878 #[ensures(^self == self[..mid])]
879 #[ensures(result == self[mid..])]
880 pub fn split_off_ghost(&mut self, mid: Int) -> Self {
881 let _ = mid;
882 panic!("ghost code")
883 }
884
885 #[trusted]
887 #[check(ghost)]
888 #[ensures(*self == result.to_owned_seq())]
889 pub fn as_refs(&self) -> Seq<&T> {
890 panic!("ghost code")
891 }
892
893 #[trusted]
895 #[check(ghost)]
896 #[ensures(result.len() == self.len())]
897 #[ensures((^self).len() == self.len())]
898 #[ensures(forall<i> 0 <= i && i < self.len() ==> *result[i] == (*self)[i])]
899 #[ensures(forall<i> 0 <= i && i < self.len() ==> ^result[i] == (^self)[i])]
900 pub fn as_muts(&mut self) -> Seq<&mut T> {
901 panic!("ghost code")
902 }
903}
904
905impl<T> core::ops::Index<Int> for Seq<T> {
906 type Output = T;
907
908 #[check(ghost)]
909 #[requires(0 <= index && index < self.len())]
910 #[ensures(*result == self[index])]
911 fn index(&self, index: Int) -> &Self::Output {
912 self.get_ghost(index).unwrap()
913 }
914}
915impl<T> core::ops::IndexMut<Int> for Seq<T> {
916 #[check(ghost)]
917 #[requires(0 <= index && index < self.len())]
918 #[ensures((*self).len() == (^self).len())]
919 #[ensures(*result == (*self)[index] && ^result == (^self)[index])]
920 #[ensures(forall<i> i != index ==> (*self).get(i) == (^self).get(i))]
921 fn index_mut(&mut self, index: Int) -> &mut Self::Output {
922 self.get_mut_ghost(index).unwrap()
923 }
924}
925
926impl<T> core::ops::Index<(Int, Int)> for Seq<T> {
927 type Output = (T, T);
928
929 #[trusted]
930 #[check(ghost)]
931 #[requires(0 <= index.0 && index.0 < self.len() && 0 <= index.1 && index.1 < self.len())]
932 #[ensures(result.0 == self[index.0] && result.1 == self[index.1])]
933 #[allow(unused_variables)]
934 fn index(&self, index: (Int, Int)) -> &Self::Output {
935 panic!()
936 }
937}
938
939impl<T> core::ops::IndexMut<(Int, Int)> for Seq<T> {
940 #[trusted]
941 #[check(ghost)]
942 #[requires(0 <= index.0 && index.0 < self.len() && 0 <= index.1 && index.1 < self.len())]
943 #[requires(index.0 != index.1)]
944 #[ensures((*result).0 == (*self)[index.0] && (*result).1 == (*self)[index.1]
945 && (^result).0 == (^self)[index.0] && (^result).1 == (^self)[index.1])]
946 #[ensures(forall<i> i != index.0 && i != index.1 ==> (*self).get(i) == (^self).get(i))]
947 #[ensures((*self).len() == (^self).len())]
948 #[allow(unused_variables)]
949 fn index_mut(&mut self, index: (Int, Int)) -> &mut Self::Output {
950 panic!()
951 }
952}
953
954impl<T: Clone + Copy> Clone for Seq<T> {
956 #[trusted]
957 #[check(ghost)]
958 #[ensures(result == *self)]
959 fn clone(&self) -> Self {
960 *self
961 }
962}
963
964impl<T: Copy> Copy for Seq<T> {}
965impl<T: Plain> Plain for Seq<T> {
966 #[ensures(*result == *snap)]
967 #[check(ghost)]
968 #[allow(unused_variables)]
969 fn into_ghost(snap: Snapshot<Self>) -> Ghost<Self> {
970 ghost! {
971 let mut res = Seq::new().into_inner();
972 let len: Snapshot<Int> = snapshot!(snap.len());
973 let len = len.into_ghost().into_inner();
974 let mut i = 0int;
975 #[variant(len - i)]
976 #[invariant(i <= len)]
977 #[invariant(res.len() == i)]
978 #[invariant(forall<j> 0 <= j && j < i ==> res[j] == snap[j])]
979 while i < len {
980 let elem: Snapshot<T> = snapshot!(snap[i]);
981 res.push_back_ghost(elem.into_ghost().into_inner());
982 i = i + 1int;
983 }
984 res
985 }
986 }
987}
988
989impl<T> Invariant for Seq<T> {
990 #[logic(open, prophetic, inline)]
991 #[creusot::trusted_trivial_if_param_trivial]
992 fn invariant(self) -> bool {
993 pearlite! { forall<i> 0 <= i && i < self.len() ==> inv(self.index_logic_unsized(i)) }
994 }
995}
996
997impl<T: PartialOrdLogic> PartialOrdLogic for Seq<T> {
998 #[logic(open)]
999 fn lt_log(self, other: Self) -> bool {
1000 pearlite! {
1001 (exists<i: Int> 0 <= i && i < self.len() && i < other.len() &&
1002 (forall<j: Int> 0 <= j && j < i ==> self[j] == other[j]) &&
1003 self[i] < other[i])
1004 ||
1005 self.len() < other.len() &&
1006 (forall<i: Int> 0 <= i && i < self.len() ==> self[i] == other[i])
1007 }
1008 }
1009
1010 #[logic(law)]
1011 #[ensures(!(self < self))]
1012 fn irreflexive(self) {}
1013
1014 #[logic(law)]
1015 #[requires(x < y)]
1016 #[requires(y < z)]
1017 #[ensures(x < z)]
1018 fn transitive(x: Self, y: Self, z: Self) {}
1019
1020 #[logic(law)]
1021 #[ensures((self <= other) == (self < other || self == other))]
1022 fn le_lt_log(self, other: Self) {}
1023}
1024
1025impl<T: OrdLogic> Seq<T> {
1026 #[logic]
1027 #[requires(self.len() > 0 && other.len() > 0)]
1028 #[requires(self[0] == other[0])]
1029 #[ensures((self < other) == (self[1..] < other[1..]))]
1030 fn lt_log_tail(self, other: Self) {}
1031}
1032
1033impl<T: OrdLogic> OrdLogic for Seq<T> {
1034 #[logic(law)]
1035 #[ensures(self < other || self == other || other < self)]
1036 #[variant(self.len())]
1037 fn lt_log_total(self, other: Self) {
1038 if self.len() > 0 && other.len() > 0 {
1039 if self[0] == other[0] {
1040 self[1..].lt_log_total(other[1..]);
1041 self.lt_log_tail(other);
1042 other.lt_log_tail(self);
1043 proof_assert!(forall<i> 0 < i && i < self.len() ==> self[i] == self[1..][i-1]);
1044 proof_assert!(forall<i> 0 < i && i < other.len() ==> other[i] == other[1..][i-1]);
1045 } else {
1046 self[0].lt_log_total(other[0]);
1047 }
1048 }
1049 }
1050}
1051
1052pub struct Iter<T>(Seq<T>);
1081
1082impl<T> View for Iter<T> {
1083 type ViewTy = Seq<T>;
1084 #[logic]
1085 fn view(self) -> Self::ViewTy {
1086 self.0
1087 }
1088}
1089
1090impl<T> Iterator for Iter<T> {
1091 type Item = T;
1092
1093 #[check(ghost)]
1094 #[ensures(match result {
1095 None => self.completed(),
1096 Some(v) => (*self).produces(Seq::singleton(v), ^self)
1097 })]
1098 fn next(&mut self) -> Option<T> {
1099 self.0.pop_front_ghost()
1100 }
1101}
1102
1103impl<T> IteratorSpec for Iter<T> {
1104 #[logic(prophetic, open)]
1105 fn produces(self, visited: Seq<T>, o: Self) -> bool {
1106 pearlite! { self@ == visited.concat(o@) }
1107 }
1108
1109 #[logic(prophetic, open)]
1110 fn completed(&mut self) -> bool {
1111 pearlite! { self@ == Seq::empty() }
1112 }
1113
1114 #[logic(law)]
1115 #[ensures(self.produces(Seq::empty(), self))]
1116 fn produces_refl(self) {}
1117
1118 #[logic(law)]
1119 #[requires(a.produces(ab, b))]
1120 #[requires(b.produces(bc, c))]
1121 #[ensures(a.produces(ab.concat(bc), c))]
1122 fn produces_trans(a: Self, ab: Seq<Self::Item>, b: Self, bc: Seq<Self::Item>, c: Self) {}
1123}
1124
1125impl<T> IntoIterator for Seq<T> {
1126 type Item = T;
1127 type IntoIter = Iter<T>;
1128
1129 #[check(ghost)]
1130 #[ensures(self == result@)]
1131 fn into_iter(self) -> Self::IntoIter {
1132 Iter(self)
1133 }
1134}
1135
1136impl<'a, T> IntoIterator for &'a Seq<T> {
1137 type Item = &'a T;
1138 type IntoIter = Iter<&'a T>;
1139
1140 #[check(ghost)]
1141 #[ensures(*self == result@.to_owned_seq())]
1142 fn into_iter(self) -> Self::IntoIter {
1143 Iter(self.as_refs())
1144 }
1145}
1146
1147impl<'a, T> IntoIterator for &'a mut Seq<T> {
1148 type Item = &'a mut T;
1149 type IntoIter = Iter<&'a mut T>;
1150
1151 #[check(ghost)]
1152 #[ensures(result@.len() == self.len())]
1153 #[ensures((^self).len() == self.len())]
1154 #[ensures(forall<i> 0 <= i && i < self.len() ==> *result@[i] == (*self)[i])]
1155 #[ensures(forall<i> 0 <= i && i < self.len() ==> ^result@[i] == (^self)[i])]
1156 fn into_iter(self) -> Self::IntoIter {
1157 Iter(self.as_muts())
1158 }
1159}
1160
1161impl<T> Resolve for Seq<T> {
1162 #[logic(open, prophetic)]
1163 #[creusot::trusted_trivial_if_param_trivial]
1164 fn resolve(self) -> bool {
1165 pearlite! { forall<i : Int> 0 <= i && i < self.len() ==> resolve(self[i]) }
1166 }
1167
1168 #[trusted]
1169 #[logic(prophetic)]
1170 #[requires(structural_resolve(self))]
1171 #[ensures(self.resolve())]
1172 fn resolve_coherence(self) {}
1173}
1174
1175impl<T> Resolve for Iter<T> {
1176 #[logic(open, prophetic, inline)]
1177 #[creusot::trusted_trivial_if_param_trivial]
1178 fn resolve(self) -> bool {
1179 pearlite! { resolve(self@) }
1180 }
1181
1182 #[logic(prophetic)]
1183 #[requires(structural_resolve(self))]
1184 #[ensures(self.resolve())]
1185 fn resolve_coherence(self) {}
1186}
1187
1188impl<T> Seq<T> {
1190 #[logic(open)]
1191 #[ensures(Seq::singleton(x).flat_map(f) == f.get(x))]
1192 pub fn flat_map_singleton<U>(x: T, f: Mapping<T, Seq<U>>) {}
1193
1194 #[logic(open)]
1195 #[ensures(self.push_back(x).flat_map(f) == self.flat_map(f).concat(f.get(x)))]
1196 #[variant(self.len())]
1197 pub fn flat_map_push_back<U>(self, x: T, f: Mapping<T, Seq<U>>) {
1198 if self.len() > 0 {
1199 Self::flat_map_push_back::<U>(self.tail(), x, f);
1200 proof_assert! { self.tail().push_back(x) == self.push_back(x).tail() }
1201 }
1202 }
1203}