creusot_contracts/logic/
seq.rs

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 std::{
10    marker::PhantomData,
11    ops::{Range, RangeFrom, RangeFull, RangeInclusive, RangeTo, RangeToInclusive},
12};
13
14/// A type of sequence usable in pearlite and `ghost!` blocks.
15///
16/// # Logic
17///
18/// This type is (in particular) the logical representation of a [`Vec`]. This can be
19/// accessed via its [view][crate::model::View] (The `@` operator).
20///
21/// ```rust,creusot
22/// # use creusot_contracts::prelude::*;
23/// #[logic]
24/// fn get_model<T>(v: Vec<T>) -> Seq<T> {
25///     pearlite!(v@)
26/// }
27/// ```
28///
29/// # Ghost
30///
31/// Since [`Vec`] have finite capacity, this could cause some issues in ghost code:
32/// ```rust,creusot,compile_fail
33/// ghost! {
34///     let mut v = Vec::new();
35///     for _ in 0..=usize::MAX as u128 + 1 {
36///         v.push(0); // cannot fail, since we are in a ghost block
37///     }
38///     proof_assert!(v@.len() <= usize::MAX@); // by definition
39///     proof_assert!(v@.len() > usize::MAX@); // uh-oh
40/// }
41/// ```
42///
43/// This type is designed for this use-case, with no restriction on the capacity.
44#[builtin("seq.Seq.seq")]
45pub struct Seq<T>(PhantomData<T>);
46
47/// Logical definitions
48impl<T> Seq<T> {
49    /// Returns the empty sequence.
50    #[logic]
51    #[builtin("seq.Seq.empty", ascription)]
52    pub fn empty() -> Self {
53        dead
54    }
55
56    /// Create a new sequence in pearlite.
57    ///
58    /// The new sequence will be of length `n`, and will contain `mapping[i]` at index `i`.
59    ///
60    /// # Example
61    ///
62    /// ```
63    /// # use creusot_contracts::prelude::*;
64    /// let s = snapshot!(Seq::create(5, |i| i + 1));
65    /// proof_assert!(s.len() == 5);
66    /// proof_assert!(forall<i> 0 <= i && i < 5 ==> s[i] == i + 1);
67    /// ```
68    #[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    /// Returns the value at index `ix`.
77    ///
78    /// If `ix` is out of bounds, return `None`.
79    #[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    /// Returns the value at index `ix`.
85    ///
86    /// If `ix` is out of bounds, the returned value is meaningless.
87    ///
88    /// You should prefer using the indexing operator `s[ix]`.
89    ///
90    /// # Example
91    ///
92    /// ```
93    /// # use creusot_contracts::prelude::*;
94    /// let s = snapshot!(Seq::singleton(2));
95    /// proof_assert!(s.index_logic_unsized(0) == 2);
96    /// proof_assert!(s[0] == 2); // prefer this
97    /// ```
98    #[logic]
99    #[builtin("seq.Seq.get")]
100    pub fn index_logic_unsized(self, ix: Int) -> Box<T> {
101        let _ = ix;
102        dead
103    }
104
105    /// Returns the subsequence between indices `start` and `end`.
106    ///
107    /// If either `start` or `end` are out of bounds, the result is meaningless.
108    ///
109    /// # Example
110    ///
111    /// ```
112    /// # use creusot_contracts::prelude::*;
113    /// let subs = snapshot! {
114    ///     let s: Seq<Int> = Seq::create(10, |i| i);
115    ///     s.subsequence(2, 5)
116    /// };
117    /// proof_assert!(subs.len() == 3);
118    /// proof_assert!(subs[0] == 2 && subs[1] == 3 && subs[2] == 4);
119    /// ```
120    #[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    /// Create a sequence containing one element.
129    ///
130    /// # Example
131    ///
132    /// ```
133    /// # use creusot_contracts::prelude::*;
134    /// let s = snapshot!(Seq::singleton(42));
135    /// proof_assert!(s.len() == 1);
136    /// proof_assert!(s[0] == 42);
137    /// ```
138    #[logic]
139    #[builtin("seq.Seq.singleton")]
140    pub fn singleton(value: T) -> Self {
141        let _ = value;
142        dead
143    }
144
145    /// Returns the sequence without its first element.
146    ///
147    /// If the sequence is empty, the result is meaningless.
148    ///
149    /// # Example
150    ///
151    /// ```
152    /// # use creusot_contracts::prelude::*;
153    /// let s = snapshot!(seq![5, 10, 15]);
154    /// proof_assert!(s.tail() == seq![10, 15]);
155    /// proof_assert!(s.tail().tail() == Seq::singleton(15));
156    /// proof_assert!(s.tail().tail().tail() == Seq::empty());
157    /// ```
158    #[logic(open)]
159    pub fn tail(self) -> Self {
160        self.subsequence(1, self.len())
161    }
162
163    /// Alias for [`Self::tail`].
164    #[logic(open)]
165    pub fn pop_front(self) -> Self {
166        self.tail()
167    }
168
169    /// Returns the sequence without its last element.
170    ///
171    /// If the sequence is empty, the result is meaningless.
172    ///
173    /// # Example
174    ///
175    /// ```
176    /// # use creusot_contracts::prelude::*;
177    /// let s = snapshot!(seq![5, 10, 15]);
178    /// proof_assert!(s.pop_back() == seq![5, 10]);
179    /// proof_assert!(s.pop_back().pop_back() == Seq::singleton(5));
180    /// proof_assert!(s.pop_back().pop_back().pop_back() == Seq::empty());
181    /// ```
182    #[logic(open)]
183    pub fn pop_back(self) -> Self {
184        self.subsequence(0, self.len() - 1)
185    }
186
187    /// Returns the number of elements in the sequence, also referred to as its 'length'.
188    ///
189    /// # Example
190    ///
191    /// ```
192    /// # use creusot_contracts::prelude::*;
193    /// #[requires(v@.len() > 0)]
194    /// fn f<T>(v: Vec<T>) { /* ... */ }
195    /// ```
196    #[logic]
197    #[builtin("seq.Seq.length")]
198    pub fn len(self) -> Int {
199        dead
200    }
201
202    /// Returns a new sequence, where the element at index `ix` has been replaced by `x`.
203    ///
204    /// If `ix` is out of bounds, the result is meaningless.
205    ///
206    /// # Example
207    ///
208    /// ```
209    /// # use creusot_contracts::prelude::*;
210    /// let s = snapshot!(Seq::create(2, |_| 0));
211    /// let s2 = snapshot!(s.set(1, 3));
212    /// proof_assert!(s2[0] == 0);
213    /// proof_assert!(s2[1] == 3);
214    /// ```
215    #[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    /// Extensional equality
224    ///
225    /// Returns `true` if `self` and `other` have the same length, and contain the same
226    /// elements at the same indices.
227    ///
228    /// This is in fact equivalent with normal equality.
229    #[logic]
230    #[builtin("seq.Seq.(==)")]
231    pub fn ext_eq(self, other: Self) -> bool {
232        let _ = other;
233        dead
234    }
235
236    // internal wrapper to match the order of arguments of Seq.cons
237    #[doc(hidden)]
238    #[logic]
239    #[builtin("seq.Seq.cons")]
240    pub fn cons(_: T, _: Self) -> Self {
241        dead
242    }
243
244    /// Returns a new sequence, where `x` has been prepended to `self`.
245    ///
246    /// # Example
247    ///
248    /// ```
249    /// let s = snapshot!(Seq::singleton(1));
250    /// let s2 = snapshot!(s.push_front(2));
251    /// proof_assert!(s2[0] == 2);
252    /// proof_assert!(s2[1] == 1);
253    /// ```
254    #[logic(open, inline)]
255    pub fn push_front(self, x: T) -> Self {
256        Self::cons(x, self)
257    }
258
259    /// Returns a new sequence, where `x` has been appended to `self`.
260    ///
261    /// # Example
262    ///
263    /// ```
264    /// let s = snapshot!(Seq::singleton(1));
265    /// let s2 = snapshot!(s.push_back(2));
266    /// proof_assert!(s2[0] == 1);
267    /// proof_assert!(s2[1] == 2);
268    /// ```
269    #[logic]
270    #[builtin("seq.Seq.snoc")]
271    pub fn push_back(self, x: T) -> Self {
272        let _ = x;
273        dead
274    }
275
276    /// Returns a new sequence, made of the concatenation of `self` and `other`.
277    ///
278    /// # Example
279    ///
280    /// ```
281    /// # use creusot_contracts::prelude::*;
282    /// let s1 = snapshot!(Seq::singleton(1));
283    /// let s2 = snapshot!(Seq::create(2, |i| i));
284    /// let s = snapshot!(s1.concat(s2));
285    /// proof_assert!(s[0] == 1);
286    /// proof_assert!(s[1] == 0);
287    /// proof_assert!(s[2] == 1);
288    /// ```
289    #[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    /// Returns a new sequence, which is `self` in reverse order.
319    ///
320    /// # Example
321    ///
322    /// ```
323    /// # use creusot_contracts::prelude::*;
324    /// let s = snapshot!(Seq::create(3, |i| i));
325    /// let s2 = snapshot!(s.reverse());
326    /// proof_assert!(s2[0] == 2);
327    /// proof_assert!(s2[1] == 1);
328    /// proof_assert!(s2[2] == 0);
329    /// ```
330    #[logic]
331    #[builtin("seq.Reverse.reverse")]
332    pub fn reverse(self) -> Self {
333        dead
334    }
335
336    /// Returns `true` if `other` is a permutation of `self`.
337    #[logic(open)]
338    pub fn permutation_of(self, other: Self) -> bool {
339        self.permut(other, 0, self.len())
340    }
341
342    /// Returns `true` if:
343    /// - `self` and `other` have the same length
344    /// - `start` and `end` are in bounds (between `0` and `self.len()` included)
345    /// - Every element of `self` between `start` (included) and `end` (excluded) can
346    ///   also be found in `other` between `start` and `end`, and vice-versa
347    #[logic]
348    #[builtin("seq.Permut.permut")]
349    pub fn permut(self, other: Self, start: Int, end: Int) -> bool {
350        let _ = other;
351        let _ = start;
352        let _ = end;
353        dead
354    }
355
356    /// Returns `true` if:
357    /// - `self` and `other` have the same length
358    /// - `i` and `j` are in bounds (between `0` and `self.len()` excluded)
359    /// - `other` is equal to `self` where the elements at `i` and `j` are swapped
360    #[logic]
361    #[builtin("seq.Permut.exchange")]
362    pub fn exchange(self, other: Self, i: Int, j: Int) -> bool {
363        let _ = other;
364        let _ = i;
365        let _ = j;
366        dead
367    }
368
369    /// Returns `true` if there is an index `i` such that `self[i] == x`.
370    #[logic(open)]
371    pub fn contains(self, x: T) -> bool {
372        pearlite! { exists<i> 0 <= i &&  i < self.len() && self[i] == x }
373    }
374
375    /// Returns `true` if `self` is sorted between `start` and `end`.
376    #[logic(open)]
377    pub fn sorted_range(self, start: Int, end: Int) -> bool
378    where
379        T: OrdLogic,
380    {
381        pearlite! {
382            forall<i, j> start <= i && i <= j && j < end ==> self[i] <= self[j]
383        }
384    }
385
386    /// Returns `true` if `self` is sorted.
387    #[logic(open)]
388    pub fn sorted(self) -> bool
389    where
390        T: OrdLogic,
391    {
392        self.sorted_range(0, self.len())
393    }
394
395    #[logic(open)]
396    #[ensures(forall<a: Seq<T>, b: Seq<T>, x>
397        a.concat(b).contains(x) == a.contains(x) || b.contains(x))]
398    pub fn concat_contains() {}
399}
400
401impl<T> Seq<Seq<T>> {
402    #[logic(open)]
403    #[variant(self.len())]
404    pub fn flatten(self) -> Seq<T> {
405        if self.len() == 0 {
406            Seq::empty()
407        } else {
408            self.index_logic_unsized(0).concat(self.tail().flatten())
409        }
410    }
411}
412
413impl<T> Seq<&T> {
414    /// Convert `Seq<&T>` to `Seq<T>`.
415    ///
416    /// This is simply a utility method, because `&T` is equivalent to `T` in pearlite.
417    #[logic]
418    #[builtin("identity")]
419    pub fn to_owned_seq(self) -> Seq<T> {
420        dead
421    }
422}
423
424impl<T> IndexLogic<Int> for Seq<T> {
425    type Item = T;
426
427    #[logic]
428    #[builtin("seq.Seq.get")]
429    fn index_logic(self, _: Int) -> Self::Item {
430        dead
431    }
432}
433
434impl<T> IndexLogic<Range<Int>> for Seq<T> {
435    type Item = Seq<T>;
436
437    #[logic(open, inline)]
438    fn index_logic(self, range: Range<Int>) -> Self::Item {
439        self.subsequence(range.start, range.end)
440    }
441}
442
443impl<T> IndexLogic<RangeInclusive<Int>> for Seq<T> {
444    type Item = Seq<T>;
445
446    #[logic(open, inline)]
447    fn index_logic(self, range: RangeInclusive<Int>) -> Self::Item {
448        self.subsequence(range.start_log(), range.end_log() + 1)
449    }
450}
451
452impl<T> IndexLogic<RangeFull> for Seq<T> {
453    type Item = Seq<T>;
454
455    #[logic(open, inline)]
456    fn index_logic(self, _: RangeFull) -> Self::Item {
457        self
458    }
459}
460
461impl<T> IndexLogic<RangeFrom<Int>> for Seq<T> {
462    type Item = Seq<T>;
463
464    #[logic(open, inline)]
465    fn index_logic(self, range: RangeFrom<Int>) -> Self::Item {
466        self.subsequence(range.start, self.len())
467    }
468}
469
470impl<T> IndexLogic<RangeTo<Int>> for Seq<T> {
471    type Item = Seq<T>;
472
473    #[logic(open, inline)]
474    fn index_logic(self, range: RangeTo<Int>) -> Self::Item {
475        self.subsequence(0, range.end)
476    }
477}
478
479impl<T> IndexLogic<RangeToInclusive<Int>> for Seq<T> {
480    type Item = Seq<T>;
481
482    #[logic(open, inline)]
483    fn index_logic(self, range: RangeToInclusive<Int>) -> Self::Item {
484        self.subsequence(0, range.end + 1)
485    }
486}
487
488/// Ghost definitions
489impl<T> Seq<T> {
490    /// Constructs a new, empty `Seq<T>`.
491    ///
492    /// This can only be manipulated in the ghost world, and as such is wrapped in [`Ghost`].
493    ///
494    /// # Example
495    ///
496    /// ```rust,creusot
497    /// use creusot_contracts::prelude::*;
498    /// let ghost_seq = Seq::<i32>::new();
499    /// proof_assert!(seq == Seq::create());
500    /// ```
501    #[trusted]
502    #[check(ghost)]
503    #[ensures(*result == Self::empty())]
504    #[allow(unreachable_code)]
505    pub fn new() -> Ghost<Self> {
506        Ghost::conjure()
507    }
508
509    /// Returns the number of elements in the sequence, also referred to as its 'length'.
510    ///
511    /// If you need to get the length in pearlite, consider using [`len`](Self::len).
512    ///
513    /// # Example
514    /// ```rust,creusot
515    /// use creusot_contracts::prelude::*;
516    ///
517    /// let mut s = Seq::new();
518    /// ghost! {
519    ///     s.push_back_ghost(1);
520    ///     s.push_back_ghost(2);
521    ///     s.push_back_ghost(3);
522    ///     let len = s.len_ghost();
523    ///     proof_assert!(len == 3);
524    /// };
525    /// ```
526    #[trusted]
527    #[check(ghost)]
528    #[ensures(result == self.len())]
529    pub fn len_ghost(&self) -> Int {
530        panic!()
531    }
532
533    /// Returns `true` if the sequence is empty.
534    ///
535    /// # Example
536    ///
537    /// ```rust,creusot
538    /// use creusot_contracts::prelude::*;
539    /// #[check(ghost)]
540    /// #[requires(s.len() == 0)]
541    /// pub fn foo(mut s: Seq<i32>) {
542    ///     assert!(s.is_empty_ghost());
543    ///     s.push_back_ghost(1i32);
544    ///     assert!(!s.is_empty_ghost());
545    /// }
546    /// ghost! {
547    ///     foo(Seq::new().into_inner())
548    /// };
549    /// ```
550    #[trusted]
551    #[check(ghost)]
552    #[ensures(result == (self.len() == 0))]
553    pub fn is_empty_ghost(&self) -> bool {
554        panic!()
555    }
556
557    /// Appends an element to the front of a collection.
558    ///
559    /// # Example
560    /// ```rust,creusot
561    /// use creusot_contracts::prelude::*;
562    ///
563    /// let mut s = Seq::new();
564    /// ghost! {
565    ///     s.push_front_ghost(1);
566    ///     s.push_front_ghost(2);
567    ///     s.push_front_ghost(3);
568    ///     proof_assert!(s[0] == 3i32 && s[1] == 2i32 && s[2] == 1i32);
569    /// };
570    /// ```
571    #[trusted]
572    #[check(ghost)]
573    #[ensures(^self == self.push_front(x))]
574    pub fn push_front_ghost(&mut self, x: T) {
575        let _ = x;
576        panic!()
577    }
578
579    /// Appends an element to the back of a collection.
580    ///
581    /// # Example
582    /// ```rust,creusot
583    /// use creusot_contracts::prelude::*;
584    ///
585    /// let mut s = Seq::new();
586    /// ghost! {
587    ///     s.push_back_ghost(1);
588    ///     s.push_back_ghost(2);
589    ///     s.push_back_ghost(3);
590    ///     proof_assert!(s[0] == 1i32 && s[1] == 2i32 && s[2] == 3i32);
591    /// };
592    /// ```
593    #[trusted]
594    #[check(ghost)]
595    #[ensures(^self == self.push_back(x))]
596    pub fn push_back_ghost(&mut self, x: T) {
597        let _ = x;
598        panic!()
599    }
600
601    /// Returns a reference to an element at `index` or `None` if `index` is out of bounds.
602    ///
603    /// # Example
604    /// ```rust,creusot
605    /// use creusot_contracts::prelude::*;
606    ///
607    /// let mut s = Seq::new();
608    /// ghost! {
609    ///     s.push_back_ghost(10);
610    ///     s.push_back_ghost(40);
611    ///     s.push_back_ghost(30);
612    ///     let get1 = s.get_ghost(1int);
613    ///     let get2 = s.get_ghost(3int);
614    ///     proof_assert!(get1 == Some(&40i32));
615    ///     proof_assert!(get2 == None);
616    /// };
617    /// ```
618    #[trusted]
619    #[check(ghost)]
620    #[ensures(match self.get(index) {
621        None => result == None,
622        Some(v) => result == Some(&v),
623    })]
624    pub fn get_ghost(&self, index: Int) -> Option<&T> {
625        let _ = index;
626        panic!()
627    }
628
629    /// Returns a mutable reference to an element at `index` or `None` if `index` is out of bounds.
630    ///
631    /// # Example
632    /// ```rust,creusot
633    /// use creusot_contracts::prelude::*;
634    ///
635    /// let mut s = Seq::new();
636    ///
637    /// ghost! {
638    ///     s.push_back_ghost(0);
639    ///     s.push_back_ghost(1);
640    ///     s.push_back_ghost(2);
641    ///     if let Some(elem) = s.get_mut_ghost(1int) {
642    ///         *elem = 42;
643    ///     }
644    ///     proof_assert!(s[0] == 0i32 && s[1] == 42i32 && s[2] == 2i32);
645    /// };
646    /// ```
647    #[trusted]
648    #[check(ghost)]
649    #[ensures(match result {
650        None => self.get(index) == None && *self == ^self,
651        Some(r) => self.get(index) == Some(*r) && ^r == (^self)[index],
652    })]
653    #[ensures(forall<i> i != index ==> (*self).get(i) == (^self).get(i))]
654    #[ensures((*self).len() == (^self).len())]
655    pub fn get_mut_ghost(&mut self, index: Int) -> Option<&mut T> {
656        let _ = index;
657        panic!()
658    }
659
660    /// Removes the last element from a vector and returns it, or `None` if it is empty.
661    ///
662    /// # Example
663    /// ```rust,creusot
664    /// use creusot_contracts::prelude::*;
665    ///
666    /// let mut s = Seq::new();
667    /// ghost! {
668    ///     s.push_back_ghost(1);
669    ///     s.push_back_ghost(2);
670    ///     s.push_back_ghost(3);
671    ///     let popped = s.pop_back_ghost();
672    ///     proof_assert!(popped == Some(3i32));
673    ///     proof_assert!(s[0] == 1i32 && s[1] == 2i32);
674    /// };
675    /// ```
676    #[trusted]
677    #[check(ghost)]
678    #[ensures(match result {
679        None => *self == Seq::empty() && *self == ^self,
680        Some(r) => *self == (^self).push_back(r)
681    })]
682    pub fn pop_back_ghost(&mut self) -> Option<T> {
683        panic!()
684    }
685
686    /// Removes the first element from a vector and returns it, or `None` if it is empty.
687    ///
688    /// # Example
689    /// ```rust,creusot
690    /// use creusot_contracts::prelude::*;
691    ///
692    /// let mut s = Seq::new();
693    /// ghost! {
694    ///     s.push_back_ghost(1);
695    ///     s.push_back_ghost(2);
696    ///     s.push_back_ghost(3);
697    ///     let popped = s.pop_front_ghost();
698    ///     proof_assert!(popped == Some(1i32));
699    ///     proof_assert!(s[0] == 2i32 && s[1] == 3i32);
700    /// };
701    /// ```
702    #[trusted]
703    #[check(ghost)]
704    #[ensures(match result {
705        None => *self == Seq::empty() && *self == ^self,
706        Some(r) => (*self).len() > 0 && r == (*self)[0] && ^self == (*self).tail()
707    })]
708    pub fn pop_front_ghost(&mut self) -> Option<T> {
709        panic!()
710    }
711
712    /// Clears the sequence, removing all values.
713    ///
714    /// # Example
715    /// ```rust,creusot
716    /// use creusot_contracts::prelude::*;
717    ///
718    /// let mut s = Seq::new();
719    /// ghost! {
720    ///     s.push_back_ghost(1);
721    ///     s.push_back_ghost(2);
722    ///     s.push_back_ghost(3);
723    ///     s.clear_ghost();
724    ///     proof_assert!(s == Seq::empty());
725    /// };
726    /// ```
727    #[trusted]
728    #[check(ghost)]
729    #[ensures(^self == Self::empty())]
730    pub fn clear_ghost(&mut self) {}
731
732    /// Split a sequence in two at the given index.
733    #[trusted]
734    #[check(ghost)]
735    #[requires(0 <= mid && mid <= self.len())]
736    #[ensures((^self).len() == mid)]
737    #[ensures((^self).concat(result) == *self)]
738    pub fn split_off_ghost(&mut self, mid: Int) -> Self {
739        let _ = mid;
740        panic!("ghost code")
741    }
742}
743
744impl<T> std::ops::Index<Int> for Seq<T> {
745    type Output = T;
746
747    #[check(ghost)]
748    #[requires(0 <= index && index < self.len())]
749    #[ensures(*result == self[index])]
750    fn index(&self, index: Int) -> &Self::Output {
751        self.get_ghost(index).unwrap()
752    }
753}
754impl<T> std::ops::IndexMut<Int> for Seq<T> {
755    #[check(ghost)]
756    #[requires(0 <= index && index < self.len())]
757    #[ensures((*self).len() == (^self).len())]
758    #[ensures(*result == (*self)[index] && ^result == (^self)[index])]
759    #[ensures(forall<i> i != index ==> (*self).get(i) == (^self).get(i))]
760    fn index_mut(&mut self, index: Int) -> &mut Self::Output {
761        self.get_mut_ghost(index).unwrap()
762    }
763}
764
765impl<T> std::ops::Index<(Int, Int)> for Seq<T> {
766    type Output = (T, T);
767
768    #[trusted]
769    #[check(ghost)]
770    #[requires(0 <= index.0 && index.0 < self.len() && 0 <= index.1 && index.1 < self.len())]
771    #[ensures(result.0 == self[index.0] && result.1 == self[index.1])]
772    #[allow(unused_variables)]
773    fn index(&self, index: (Int, Int)) -> &Self::Output {
774        panic!()
775    }
776}
777
778impl<T> std::ops::IndexMut<(Int, Int)> for Seq<T> {
779    #[trusted]
780    #[check(ghost)]
781    #[requires(0 <= index.0 && index.0 < self.len() && 0 <= index.1 && index.1 < self.len())]
782    #[requires(index.0 != index.1)]
783    #[ensures((*result).0 == (*self)[index.0] && (*result).1 == (*self)[index.1]
784           && (^result).0 == (^self)[index.0] && (^result).1 == (^self)[index.1])]
785    #[ensures(forall<i> i != index.0 && i != index.1 ==> (*self).get(i) == (^self).get(i))]
786    #[ensures((*self).len() == (^self).len())]
787    #[allow(unused_variables)]
788    fn index_mut(&mut self, index: (Int, Int)) -> &mut Self::Output {
789        panic!()
790    }
791}
792
793// Having `Copy` guarantees that the operation is pure, even if we decide to change the definition of `Clone`.
794impl<T: Clone + Copy> Clone for Seq<T> {
795    #[trusted]
796    #[check(ghost)]
797    #[ensures(result == *self)]
798    fn clone(&self) -> Self {
799        *self
800    }
801}
802
803impl<T: Copy> Copy for Seq<T> {}
804#[trusted]
805impl<T: Plain> Plain for Seq<T> {}
806
807impl<T> Invariant for Seq<T> {
808    #[logic(open, prophetic, inline)]
809    #[creusot::trusted_trivial_if_param_trivial]
810    fn invariant(self) -> bool {
811        pearlite! { forall<i> 0 <= i && i < self.len() ==> inv(self.index_logic_unsized(i)) }
812    }
813}
814
815// =========
816// Iterators
817// =========
818
819impl<T> IntoIterator for Seq<T> {
820    type Item = T;
821    type IntoIter = SeqIter<T>;
822
823    #[check(ghost)]
824    #[ensures(result@ == self)]
825    fn into_iter(self) -> SeqIter<T> {
826        SeqIter { inner: self }
827    }
828}
829
830/// An owning iterator for [`Seq`].
831///
832/// # Ghost code and variants
833///
834/// This iterator is only obtainable in ghost code.
835///
836/// To use it in a `for` loop, a variant must be declared:
837/// ```rust,creusot
838/// # use creusot_contracts::prelude::*;
839/// # #[requires(true)]
840/// fn iter_on_seq<T>(s: Seq<T>) {
841///     let len = snapshot!(s.len());
842///     #[variant(len - produced.len())]
843///     for i in s {
844///         // ...
845///     }
846/// }
847/// ```
848pub struct SeqIter<T> {
849    inner: Seq<T>,
850}
851
852impl<T> View for SeqIter<T> {
853    type ViewTy = Seq<T>;
854    #[logic]
855    fn view(self) -> Seq<T> {
856        self.inner
857    }
858}
859
860impl<T> Iterator for SeqIter<T> {
861    type Item = T;
862
863    #[check(ghost)]
864    #[ensures(match result {
865        None => self.completed(),
866        Some(v) => (*self).produces(Seq::singleton(v), ^self)
867    })]
868    fn next(&mut self) -> Option<T> {
869        self.inner.pop_front_ghost()
870    }
871}
872
873impl<T> IteratorSpec for SeqIter<T> {
874    #[logic(prophetic, open)]
875    fn produces(self, visited: Seq<T>, o: Self) -> bool {
876        pearlite! { self@ == visited.concat(o@) }
877    }
878
879    #[logic(prophetic, open)]
880    fn completed(&mut self) -> bool {
881        pearlite! { self@ == Seq::empty() }
882    }
883
884    #[logic(law)]
885    #[ensures(self.produces(Seq::empty(), self))]
886    fn produces_refl(self) {}
887
888    #[logic(law)]
889    #[requires(a.produces(ab, b))]
890    #[requires(b.produces(bc, c))]
891    #[ensures(a.produces(ab.concat(bc), c))]
892    fn produces_trans(a: Self, ab: Seq<Self::Item>, b: Self, bc: Seq<Self::Item>, c: Self) {}
893}
894
895impl<'a, T> IntoIterator for &'a Seq<T> {
896    type Item = &'a T;
897    type IntoIter = SeqIterRef<'a, T>;
898
899    #[check(ghost)]
900    #[ensures(result@ == *self)]
901    fn into_iter(self) -> Self::IntoIter {
902        SeqIterRef { inner: self, index: self.len_ghost() - self.len_ghost() }
903    }
904}
905
906/// An iterator over references in a [`Seq`].
907pub struct SeqIterRef<'a, T> {
908    inner: &'a Seq<T>,
909    index: Int,
910}
911impl<T> Invariant for SeqIterRef<'_, T> {
912    #[logic]
913    fn invariant(self) -> bool {
914        0 <= self.index && self.index <= self.inner.len()
915    }
916}
917
918impl<T> View for SeqIterRef<'_, T> {
919    type ViewTy = Seq<T>;
920    #[logic]
921    fn view(self) -> Seq<T> {
922        self.inner.subsequence(self.index, self.inner.len())
923    }
924}
925
926impl<'a, T> Iterator for SeqIterRef<'a, T> {
927    type Item = &'a T;
928
929    #[check(ghost)]
930    #[ensures(match result {
931        None => self.completed(),
932        Some(v) => (*self).produces(Seq::singleton(v), ^self)
933    })]
934    fn next(&mut self) -> Option<&'a T> {
935        let _before = snapshot!((*self)@);
936        if let Some(res) = self.inner.get_ghost(self.index) {
937            self.index.incr_ghost();
938            proof_assert!((*self)@ == _before.tail());
939            Some(res)
940        } else {
941            proof_assert!(self.index == self.inner.len());
942            proof_assert!(self@ == Seq::empty());
943            None
944        }
945    }
946}
947impl<'a, T> IteratorSpec for SeqIterRef<'a, T> {
948    #[logic(prophetic, open)]
949    fn produces(self, visited: Seq<&'a T>, o: Self) -> bool {
950        let visited: Seq<T> = visited.to_owned_seq();
951        pearlite! { self@ == visited.concat(o@) }
952    }
953
954    #[logic(prophetic, open)]
955    fn completed(&mut self) -> bool {
956        pearlite! { self@ == Seq::empty() }
957    }
958
959    #[logic(law)]
960    #[ensures(self.produces(Seq::empty(), self))]
961    fn produces_refl(self) {}
962
963    #[logic(law)]
964    #[requires(a.produces(ab, b))]
965    #[requires(b.produces(bc, c))]
966    #[ensures(a.produces(ab.concat(bc), c))]
967    fn produces_trans(a: Self, ab: Seq<Self::Item>, b: Self, bc: Seq<Self::Item>, c: Self) {}
968}
969
970impl<T> Resolve for Seq<T> {
971    #[logic(open, prophetic)]
972    #[creusot::trusted_trivial_if_param_trivial]
973    fn resolve(self) -> bool {
974        pearlite! { forall<i : Int> resolve(self.get(i)) }
975    }
976
977    #[trusted]
978    #[logic(open(self), prophetic)]
979    #[requires(structural_resolve(self))]
980    #[ensures(self.resolve())]
981    fn resolve_coherence(self) {}
982}
983
984impl<T> Resolve for SeqIter<T> {
985    #[logic(open, prophetic, inline)]
986    #[creusot::trusted_trivial_if_param_trivial]
987    fn resolve(self) -> bool {
988        pearlite! { resolve(self@) }
989    }
990
991    #[logic(open, prophetic)]
992    #[requires(structural_resolve(self))]
993    #[ensures(self.resolve())]
994    fn resolve_coherence(self) {}
995}
996
997// Some properties
998// TODO : use parameters instead of quantification, and mode to impl block
999
1000#[logic(open)]
1001#[ensures(forall<x: A, f: Mapping<A, Seq<B>>> Seq::singleton(x).flat_map(f) == f.get(x))]
1002pub fn flat_map_singleton<A, B>() {}
1003
1004#[logic(open)]
1005#[ensures(forall<x: A, f: Mapping<A, Seq<B>>> xs.push_back(x).flat_map(f) == xs.flat_map(f).concat(f.get(x)))]
1006#[variant(xs.len())]
1007pub fn flat_map_push_back<A, B>(xs: Seq<A>) {
1008    if xs.len() > 0 {
1009        flat_map_push_back::<A, B>(xs.tail());
1010        proof_assert! { forall<x: A> xs.tail().push_back(x) == xs.push_back(x).tail() }
1011    }
1012}