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]
290 #[builtin("seq.Seq.(++)")]
291 pub fn concat(self, other: Self) -> Self {
292 let _ = other;
293 dead
294 }
295
296 #[logic]
297 #[ensures(result.len() == self.len())]
298 #[ensures(forall<i> 0 <= i && i < self.len() ==> result[i] == m[self[i]])]
299 #[variant(self.len())]
300 pub fn map<U>(self, m: Mapping<T, U>) -> Seq<U> {
301 if self.len() == 0 {
302 Seq::empty()
303 } else {
304 self.tail().map(m).push_front(m.get(*self.index_logic_unsized(0)))
305 }
306 }
307
308 #[logic(open)]
309 #[variant(self.len())]
310 pub fn flat_map<U>(self, other: Mapping<T, Seq<U>>) -> Seq<U> {
311 if self.len() == 0 {
312 Seq::empty()
313 } else {
314 other.get(*self.index_logic_unsized(0)).concat(self.tail().flat_map(other))
315 }
316 }
317
318 #[logic]
331 #[builtin("seq.Reverse.reverse")]
332 pub fn reverse(self) -> Self {
333 dead
334 }
335
336 #[logic(open)]
338 pub fn permutation_of(self, other: Self) -> bool {
339 self.permut(other, 0, self.len())
340 }
341
342 #[logic]
347 #[builtin("seq.Permut.permut")]
348 pub fn permut(self, other: Self, start: Int, end: Int) -> bool {
349 let _ = other;
350 let _ = start;
351 let _ = end;
352 dead
353 }
354
355 #[logic]
360 #[builtin("seq.Permut.exchange")]
361 pub fn exchange(self, other: Self, i: Int, j: Int) -> bool {
362 let _ = other;
363 let _ = i;
364 let _ = j;
365 dead
366 }
367
368 #[logic(open)]
370 pub fn contains(self, x: T) -> bool {
371 pearlite! { exists<i> 0 <= i && i < self.len() && self[i] == x }
372 }
373
374 #[logic(open)]
376 pub fn sorted_range(self, start: Int, end: Int) -> bool
377 where
378 T: OrdLogic,
379 {
380 pearlite! {
381 forall<i, j> start <= i && i <= j && j < end ==> self[i] <= self[j]
382 }
383 }
384
385 #[logic(open)]
387 pub fn sorted(self) -> bool
388 where
389 T: OrdLogic,
390 {
391 self.sorted_range(0, self.len())
392 }
393
394 #[logic(open)]
395 #[ensures(forall<a: Seq<T>, b: Seq<T>, x>
396 a.concat(b).contains(x) == a.contains(x) || b.contains(x))]
397 pub fn concat_contains() {}
398}
399
400impl<T> Seq<Seq<T>> {
401 #[logic(open)]
402 #[variant(self.len())]
403 pub fn flatten(self) -> Seq<T> {
404 if self.len() == 0 {
405 Seq::empty()
406 } else {
407 self.index_logic_unsized(0).concat(self.tail().flatten())
408 }
409 }
410}
411
412impl<T> Seq<&T> {
413 #[logic]
417 #[builtin("identity")]
418 pub fn to_owned_seq(self) -> Seq<T> {
419 dead
420 }
421}
422
423impl<T> IndexLogic<Int> for Seq<T> {
424 type Item = T;
425
426 #[logic]
427 #[builtin("seq.Seq.get")]
428 fn index_logic(self, _: Int) -> Self::Item {
429 dead
430 }
431}
432
433impl<T> IndexLogic<Range<Int>> for Seq<T> {
434 type Item = Seq<T>;
435
436 #[logic(open, inline)]
437 fn index_logic(self, range: Range<Int>) -> Self::Item {
438 self.subsequence(range.start, range.end)
439 }
440}
441
442impl<T> IndexLogic<RangeInclusive<Int>> for Seq<T> {
443 type Item = Seq<T>;
444
445 #[logic(open, inline)]
446 fn index_logic(self, range: RangeInclusive<Int>) -> Self::Item {
447 self.subsequence(range.start_log(), range.end_log() + 1)
448 }
449}
450
451impl<T> IndexLogic<RangeFull> for Seq<T> {
452 type Item = Seq<T>;
453
454 #[logic(open, inline)]
455 fn index_logic(self, _: RangeFull) -> Self::Item {
456 self
457 }
458}
459
460impl<T> IndexLogic<RangeFrom<Int>> for Seq<T> {
461 type Item = Seq<T>;
462
463 #[logic(open, inline)]
464 fn index_logic(self, range: RangeFrom<Int>) -> Self::Item {
465 self.subsequence(range.start, self.len())
466 }
467}
468
469impl<T> IndexLogic<RangeTo<Int>> for Seq<T> {
470 type Item = Seq<T>;
471
472 #[logic(open, inline)]
473 fn index_logic(self, range: RangeTo<Int>) -> Self::Item {
474 self.subsequence(0, range.end)
475 }
476}
477
478impl<T> IndexLogic<RangeToInclusive<Int>> for Seq<T> {
479 type Item = Seq<T>;
480
481 #[logic(open, inline)]
482 fn index_logic(self, range: RangeToInclusive<Int>) -> Self::Item {
483 self.subsequence(0, range.end + 1)
484 }
485}
486
487impl<T> Seq<T> {
489 #[trusted]
501 #[check(ghost)]
502 #[ensures(*result == Self::empty())]
503 #[allow(unreachable_code)]
504 pub fn new() -> Ghost<Self> {
505 Ghost::conjure()
506 }
507
508 #[trusted]
526 #[check(ghost)]
527 #[ensures(result == self.len())]
528 pub fn len_ghost(&self) -> Int {
529 panic!()
530 }
531
532 #[trusted]
550 #[check(ghost)]
551 #[ensures(result == (self.len() == 0))]
552 pub fn is_empty_ghost(&self) -> bool {
553 panic!()
554 }
555
556 #[trusted]
571 #[check(ghost)]
572 #[ensures(^self == self.push_front(x))]
573 pub fn push_front_ghost(&mut self, x: T) {
574 let _ = x;
575 panic!()
576 }
577
578 #[trusted]
593 #[check(ghost)]
594 #[ensures(^self == self.push_back(x))]
595 pub fn push_back_ghost(&mut self, x: T) {
596 let _ = x;
597 panic!()
598 }
599
600 #[trusted]
618 #[check(ghost)]
619 #[ensures(match self.get(index) {
620 None => result == None,
621 Some(v) => result == Some(&v),
622 })]
623 pub fn get_ghost(&self, index: Int) -> Option<&T> {
624 let _ = index;
625 panic!()
626 }
627
628 #[trusted]
647 #[check(ghost)]
648 #[ensures(match result {
649 None => self.get(index) == None && *self == ^self,
650 Some(r) => self.get(index) == Some(*r) && ^r == (^self)[index],
651 })]
652 #[ensures(forall<i> i != index ==> (*self).get(i) == (^self).get(i))]
653 #[ensures((*self).len() == (^self).len())]
654 pub fn get_mut_ghost(&mut self, index: Int) -> Option<&mut T> {
655 let _ = index;
656 panic!()
657 }
658
659 #[trusted]
676 #[check(ghost)]
677 #[ensures(match result {
678 None => *self == Seq::empty() && *self == ^self,
679 Some(r) => *self == (^self).push_back(r)
680 })]
681 pub fn pop_back_ghost(&mut self) -> Option<T> {
682 panic!()
683 }
684
685 #[trusted]
702 #[check(ghost)]
703 #[ensures(match result {
704 None => *self == Seq::empty() && *self == ^self,
705 Some(r) => (*self).len() > 0 && r == (*self)[0] && ^self == (*self).tail()
706 })]
707 pub fn pop_front_ghost(&mut self) -> Option<T> {
708 panic!()
709 }
710
711 #[trusted]
727 #[check(ghost)]
728 #[ensures(^self == Self::empty())]
729 pub fn clear_ghost(&mut self) {}
730
731 #[trusted]
733 #[check(ghost)]
734 #[requires(0 <= mid && mid <= self.len())]
735 #[ensures((^self).len() == mid)]
736 #[ensures((^self).concat(result) == *self)]
737 pub fn split_off_ghost(&mut self, mid: Int) -> Self {
738 let _ = mid;
739 panic!("ghost code")
740 }
741}
742
743impl<T> core::ops::Index<Int> for Seq<T> {
744 type Output = T;
745
746 #[check(ghost)]
747 #[requires(0 <= index && index < self.len())]
748 #[ensures(*result == self[index])]
749 fn index(&self, index: Int) -> &Self::Output {
750 self.get_ghost(index).unwrap()
751 }
752}
753impl<T> core::ops::IndexMut<Int> for Seq<T> {
754 #[check(ghost)]
755 #[requires(0 <= index && index < self.len())]
756 #[ensures((*self).len() == (^self).len())]
757 #[ensures(*result == (*self)[index] && ^result == (^self)[index])]
758 #[ensures(forall<i> i != index ==> (*self).get(i) == (^self).get(i))]
759 fn index_mut(&mut self, index: Int) -> &mut Self::Output {
760 self.get_mut_ghost(index).unwrap()
761 }
762}
763
764impl<T> core::ops::Index<(Int, Int)> for Seq<T> {
765 type Output = (T, T);
766
767 #[trusted]
768 #[check(ghost)]
769 #[requires(0 <= index.0 && index.0 < self.len() && 0 <= index.1 && index.1 < self.len())]
770 #[ensures(result.0 == self[index.0] && result.1 == self[index.1])]
771 #[allow(unused_variables)]
772 fn index(&self, index: (Int, Int)) -> &Self::Output {
773 panic!()
774 }
775}
776
777impl<T> core::ops::IndexMut<(Int, Int)> for Seq<T> {
778 #[trusted]
779 #[check(ghost)]
780 #[requires(0 <= index.0 && index.0 < self.len() && 0 <= index.1 && index.1 < self.len())]
781 #[requires(index.0 != index.1)]
782 #[ensures((*result).0 == (*self)[index.0] && (*result).1 == (*self)[index.1]
783 && (^result).0 == (^self)[index.0] && (^result).1 == (^self)[index.1])]
784 #[ensures(forall<i> i != index.0 && i != index.1 ==> (*self).get(i) == (^self).get(i))]
785 #[ensures((*self).len() == (^self).len())]
786 #[allow(unused_variables)]
787 fn index_mut(&mut self, index: (Int, Int)) -> &mut Self::Output {
788 panic!()
789 }
790}
791
792impl<T: Clone + Copy> Clone for Seq<T> {
794 #[trusted]
795 #[check(ghost)]
796 #[ensures(result == *self)]
797 fn clone(&self) -> Self {
798 *self
799 }
800}
801
802impl<T: Copy> Copy for Seq<T> {}
803#[trusted]
804impl<T: Plain> Plain for Seq<T> {}
805
806impl<T> Invariant for Seq<T> {
807 #[logic(open, prophetic, inline)]
808 #[creusot::trusted_trivial_if_param_trivial]
809 fn invariant(self) -> bool {
810 pearlite! { forall<i> 0 <= i && i < self.len() ==> inv(self.index_logic_unsized(i)) }
811 }
812}
813
814impl<T> IntoIterator for Seq<T> {
819 type Item = T;
820 type IntoIter = SeqIter<T>;
821
822 #[check(ghost)]
823 #[ensures(result@ == self)]
824 fn into_iter(self) -> SeqIter<T> {
825 SeqIter { inner: self }
826 }
827}
828
829pub struct SeqIter<T> {
848 inner: Seq<T>,
849}
850
851impl<T> View for SeqIter<T> {
852 type ViewTy = Seq<T>;
853 #[logic]
854 fn view(self) -> Seq<T> {
855 self.inner
856 }
857}
858
859impl<T> Iterator for SeqIter<T> {
860 type Item = T;
861
862 #[check(ghost)]
863 #[ensures(match result {
864 None => self.completed(),
865 Some(v) => (*self).produces(Seq::singleton(v), ^self)
866 })]
867 fn next(&mut self) -> Option<T> {
868 self.inner.pop_front_ghost()
869 }
870}
871
872impl<T> IteratorSpec for SeqIter<T> {
873 #[logic(prophetic, open)]
874 fn produces(self, visited: Seq<T>, o: Self) -> bool {
875 pearlite! { self@ == visited.concat(o@) }
876 }
877
878 #[logic(prophetic, open)]
879 fn completed(&mut self) -> bool {
880 pearlite! { self@ == Seq::empty() }
881 }
882
883 #[logic(law)]
884 #[ensures(self.produces(Seq::empty(), self))]
885 fn produces_refl(self) {}
886
887 #[logic(law)]
888 #[requires(a.produces(ab, b))]
889 #[requires(b.produces(bc, c))]
890 #[ensures(a.produces(ab.concat(bc), c))]
891 fn produces_trans(a: Self, ab: Seq<Self::Item>, b: Self, bc: Seq<Self::Item>, c: Self) {}
892}
893
894impl<'a, T> IntoIterator for &'a Seq<T> {
895 type Item = &'a T;
896 type IntoIter = SeqIterRef<'a, T>;
897
898 #[check(ghost)]
899 #[ensures(result@ == *self)]
900 fn into_iter(self) -> Self::IntoIter {
901 SeqIterRef { inner: self, index: self.len_ghost() - self.len_ghost() }
902 }
903}
904
905pub struct SeqIterRef<'a, T> {
907 inner: &'a Seq<T>,
908 index: Int,
909}
910impl<T> Invariant for SeqIterRef<'_, T> {
911 #[logic]
912 fn invariant(self) -> bool {
913 0 <= self.index && self.index <= self.inner.len()
914 }
915}
916
917impl<T> View for SeqIterRef<'_, T> {
918 type ViewTy = Seq<T>;
919 #[logic]
920 fn view(self) -> Seq<T> {
921 self.inner.subsequence(self.index, self.inner.len())
922 }
923}
924
925impl<'a, T> Iterator for SeqIterRef<'a, T> {
926 type Item = &'a T;
927
928 #[check(ghost)]
929 #[ensures(match result {
930 None => self.completed(),
931 Some(v) => (*self).produces(Seq::singleton(v), ^self)
932 })]
933 fn next(&mut self) -> Option<&'a T> {
934 let _before = snapshot!((*self)@);
935 if let Some(res) = self.inner.get_ghost(self.index) {
936 self.index.incr_ghost();
937 proof_assert!((*self)@ == _before.tail());
938 Some(res)
939 } else {
940 proof_assert!(self.index == self.inner.len());
941 proof_assert!(self@ == Seq::empty());
942 None
943 }
944 }
945}
946impl<'a, T> IteratorSpec for SeqIterRef<'a, T> {
947 #[logic(prophetic, open)]
948 fn produces(self, visited: Seq<&'a T>, o: Self) -> bool {
949 let visited: Seq<T> = visited.to_owned_seq();
950 pearlite! { self@ == visited.concat(o@) }
951 }
952
953 #[logic(prophetic, open)]
954 fn completed(&mut self) -> bool {
955 pearlite! { self@ == Seq::empty() }
956 }
957
958 #[logic(law)]
959 #[ensures(self.produces(Seq::empty(), self))]
960 fn produces_refl(self) {}
961
962 #[logic(law)]
963 #[requires(a.produces(ab, b))]
964 #[requires(b.produces(bc, c))]
965 #[ensures(a.produces(ab.concat(bc), c))]
966 fn produces_trans(a: Self, ab: Seq<Self::Item>, b: Self, bc: Seq<Self::Item>, c: Self) {}
967}
968
969impl<T> Resolve for Seq<T> {
970 #[logic(open, prophetic)]
971 #[creusot::trusted_trivial_if_param_trivial]
972 fn resolve(self) -> bool {
973 pearlite! { forall<i : Int> resolve(self.get(i)) }
974 }
975
976 #[trusted]
977 #[logic(open(self), prophetic)]
978 #[requires(structural_resolve(self))]
979 #[ensures(self.resolve())]
980 fn resolve_coherence(self) {}
981}
982
983impl<T> Resolve for SeqIter<T> {
984 #[logic(open, prophetic, inline)]
985 #[creusot::trusted_trivial_if_param_trivial]
986 fn resolve(self) -> bool {
987 pearlite! { resolve(self@) }
988 }
989
990 #[logic(open, prophetic)]
991 #[requires(structural_resolve(self))]
992 #[ensures(self.resolve())]
993 fn resolve_coherence(self) {}
994}
995
996#[logic(open)]
1000#[ensures(forall<x: A, f: Mapping<A, Seq<B>>> Seq::singleton(x).flat_map(f) == f.get(x))]
1001pub fn flat_map_singleton<A, B>() {}
1002
1003#[logic(open)]
1004#[ensures(forall<x: A, f: Mapping<A, Seq<B>>> xs.push_back(x).flat_map(f) == xs.flat_map(f).concat(f.get(x)))]
1005#[variant(xs.len())]
1006pub fn flat_map_push_back<A, B>(xs: Seq<A>) {
1007 if xs.len() > 0 {
1008 flat_map_push_back::<A, B>(xs.tail());
1009 proof_assert! { forall<x: A> xs.tail().push_back(x) == xs.push_back(x).tail() }
1010 }
1011}