1#[cfg(creusot)]
2use crate::resolve::structural_resolve;
3use crate::{invariant::*, logic::ops::IndexLogic, prelude::*};
4use core::array::*;
5
6impl<T, const N: usize> Invariant for [T; N] {
7 #[logic(open, prophetic)]
8 fn invariant(self) -> bool {
9 pearlite! { inv(self@) && self@.len() == N@ }
10 }
11}
12
13impl<T, const N: usize> View for [T; N] {
14 type ViewTy = Seq<T>;
15
16 #[logic]
17 #[cfg_attr(target_pointer_width = "16", builtin("creusot.slice.Slice16.view"))]
18 #[cfg_attr(target_pointer_width = "32", builtin("creusot.slice.Slice32.view"))]
19 #[cfg_attr(target_pointer_width = "64", builtin("creusot.slice.Slice64.view"))]
20 fn view(self) -> Self::ViewTy {
21 dead
22 }
23}
24
25impl<T: DeepModel, const N: usize> DeepModel for [T; N] {
26 type DeepModelTy = Seq<T::DeepModelTy>;
27
28 #[trusted]
29 #[logic(opaque)]
30 #[ensures(self.view().len() == result.len())]
31 #[ensures(forall<i> 0 <= i && i < result.len() ==> result[i] == self[i].deep_model())]
32 fn deep_model(self) -> Self::DeepModelTy {
33 dead
34 }
35}
36
37impl<T, const N: usize> Resolve for [T; N] {
38 #[logic(open, prophetic, inline)]
39 #[creusot::trusted_trivial_if_param_trivial]
40 fn resolve(self) -> bool {
41 pearlite! { forall<i: Int> 0 <= i && i < N@ ==> resolve(self@[i]) }
42 }
43
44 #[trusted]
45 #[logic(prophetic)]
46 #[requires(structural_resolve(self))]
47 #[ensures(self.resolve())]
48 fn resolve_coherence(self) {}
49}
50
51impl<T, const N: usize> IndexLogic<Int> for [T; N] {
52 type Item = T;
53
54 #[logic(open, inline)]
55 fn index_logic(self, ix: Int) -> Self::Item {
56 pearlite! { self@[ix] }
57 }
58}
59
60impl<T, const N: usize> IndexLogic<usize> for [T; N] {
61 type Item = T;
62
63 #[logic(open, inline)]
64 fn index_logic(self, ix: usize) -> Self::Item {
65 pearlite! { self@[ix@] }
66 }
67}
68
69impl<T, const N: usize> View for IntoIter<T, N> {
70 type ViewTy = Seq<T>;
71
72 #[logic(opaque)]
73 fn view(self) -> Self::ViewTy {
74 dead
75 }
76}
77
78impl<T, const N: usize> IteratorSpec for IntoIter<T, N> {
79 #[logic(open, prophetic)]
80 fn produces(self, visited: Seq<T>, o: Self) -> bool {
81 pearlite! { self@ == visited.concat(o@) }
82 }
83
84 #[logic(open, prophetic)]
85 fn completed(&mut self) -> bool {
86 pearlite! { resolve(self) && self@ == Seq::empty() }
87 }
88
89 #[logic(law)]
90 #[ensures(self.produces(Seq::empty(), self))]
91 fn produces_refl(self) {
92 let _ = Seq::<T>::concat_empty;
93 }
94
95 #[logic(law)]
96 #[requires(a.produces(ab, b))]
97 #[requires(b.produces(bc, c))]
98 #[ensures(a.produces(ab.concat(bc), c))]
99 fn produces_trans(a: Self, ab: Seq<T>, b: Self, bc: Seq<T>, c: Self) {
100 let _ = ab.reverse_concat(bc);
101 let _ = Seq::<T>::concat_assoc;
102 }
103}
104
105impl<T, const N: usize> DoubleEndedIteratorSpec for IntoIter<T, N> {
106 #[logic(open)]
107 fn produces_back(self, visited: Seq<T>, o: Self) -> bool {
108 pearlite! {
109 self@ == o@.concat(visited.reverse())
110 }
111 }
112
113 #[logic(law)]
114 #[ensures(self.produces_back(Seq::empty(), self))]
115 fn produces_back_refl(self) {
116 let _ = Seq::<T>::reverse_empty();
117 let _ = Seq::<T>::concat_empty;
118 }
119
120 #[logic(law)]
121 #[requires(a.produces_back(ab, b))]
122 #[requires(b.produces_back(bc, c))]
123 #[ensures(a.produces_back(ab.concat(bc), c))]
124 fn produces_back_trans(a: Self, ab: Seq<T>, b: Self, bc: Seq<T>, c: Self) {
125 let _ = ab.reverse_concat(bc);
126 let _ = Seq::<T>::concat_assoc;
127 }
128}
129
130extern_spec! {
131 impl<T, const N: usize> IntoIterator for [T; N] {
132 #[check(ghost)]
133 #[ensures(self@ == result@)]
134 fn into_iter(self) -> core::array::IntoIter<T, N>;
135 }
136
137 impl<T: Clone, const N: usize> Clone for [T; N] {
138 #[ensures(forall<i> 0 <= i && i < self@.len() ==>
139 T::clone.postcondition((&self@[i],), result@[i]))]
140 fn clone(&self) -> [T; N];
141 }
142
143 impl<T, const N: usize> [T; N] {
144 #[check(ghost)]
145 #[ensures(result@ == self@)]
146 fn as_slice(&self) -> &[T] {
147 self
148 }
149
150 #[check(ghost)]
151 #[ensures(result@ == self@)]
152 #[ensures((^self)@.len() == (*self)@.len())]
153 #[ensures((^result)@ == (^self)@)]
154 fn as_mut_slice(&mut self) -> &mut [T] {
155 self
156 }
157 }
158}