1use core::marker;
2
3#[allow(unused_imports)]
4use super::pervasive::*;
5#[allow(unused_imports)]
6use super::prelude::*;
7
8verus! {
9
10#[verifier::external_body]
29#[verifier::ext_equal]
30#[verifier::accept_recursive_types(A)]
31pub struct Seq<A> {
32 dummy: marker::PhantomData<A>,
33}
34
35impl<A> Seq<A> {
36 #[rustc_diagnostic_item = "verus::vstd::seq::Seq::empty"]
38 pub uninterp spec fn empty() -> Seq<A>;
39
40 #[rustc_diagnostic_item = "verus::vstd::seq::Seq::new"]
42 pub uninterp spec fn new(len: nat, f: impl Fn(int) -> A) -> Seq<A>;
43
44 #[rustc_diagnostic_item = "verus::vstd::seq::Seq::len"]
46 pub uninterp spec fn len(self) -> nat;
47
48 #[rustc_diagnostic_item = "verus::vstd::seq::Seq::index"]
53 pub uninterp spec fn index(self, i: int) -> A
54 recommends
55 0 <= i < self.len(),
56 ;
57
58 #[verifier::inline]
60 pub open spec fn spec_index(self, i: int) -> A
61 recommends
62 0 <= i < self.len(),
63 {
64 self.index(i)
65 }
66
67 #[rustc_diagnostic_item = "verus::vstd::seq::Seq::push"]
80 pub uninterp spec fn push(self, a: A) -> Seq<A>;
81
82 #[rustc_diagnostic_item = "verus::vstd::seq::Seq::update"]
95 pub uninterp spec fn update(self, i: int, a: A) -> Seq<A>
96 recommends
97 0 <= i < self.len(),
98 ;
99
100 #[rustc_diagnostic_item = "verus::vstd::seq::Seq::subrange"]
114 pub uninterp spec fn subrange(self, start_inclusive: int, end_exclusive: int) -> Seq<A>
115 recommends
116 0 <= start_inclusive <= end_exclusive <= self.len(),
117 ;
118
119 #[verifier::inline]
121 pub open spec fn take(self, n: int) -> Seq<A> {
122 self.subrange(0, n)
123 }
124
125 #[verifier::inline]
127 pub open spec fn skip(self, n: int) -> Seq<A> {
128 self.subrange(n, self.len() as int)
129 }
130
131 #[rustc_diagnostic_item = "verus::vstd::seq::Seq::add"]
142 pub uninterp spec fn add(self, rhs: Seq<A>) -> Seq<A>;
143
144 #[verifier::inline]
146 pub open spec fn spec_add(self, rhs: Seq<A>) -> Seq<A> {
147 self.add(rhs)
148 }
149
150 #[rustc_diagnostic_item = "verus::vstd::seq::Seq::last"]
152 pub open spec fn last(self) -> A
153 recommends
154 0 < self.len(),
155 {
156 self[self.len() as int - 1]
157 }
158
159 #[rustc_diagnostic_item = "vstd::seq::Seq::first"]
161 pub open spec fn first(self) -> A
162 recommends
163 0 < self.len(),
164 {
165 self[0]
166 }
167
168 #[verifier(external_body)]
169 pub proof fn tracked_empty() -> (tracked ret: Self)
170 ensures
171 ret === Seq::empty(),
172 {
173 unimplemented!()
174 }
175
176 #[verifier(external_body)]
177 pub proof fn tracked_remove(tracked &mut self, i: int) -> (tracked ret: A)
178 requires
179 0 <= i < old(self).len(),
180 ensures
181 ret === old(self)[i],
182 self.len() == old(self).len() - 1,
183 self == old(self).remove(i),
184 {
185 unimplemented!()
186 }
187
188 #[verifier(external_body)]
189 pub proof fn tracked_insert(tracked &mut self, i: int, tracked v: A)
190 requires
191 0 <= i <= old(self).len(),
192 ensures
193 self.len() == old(self).len() + 1,
194 self == old(self).insert(i, v),
195 {
196 unimplemented!()
197 }
198
199 #[verifier(external_body)]
200 pub proof fn tracked_borrow(tracked &self, i: int) -> (tracked ret: &A)
201 requires
202 0 <= i < self.len(),
203 ensures
204 *ret === self[i],
205 {
206 unimplemented!()
207 }
208
209 pub proof fn tracked_push(tracked &mut self, tracked v: A)
210 ensures
211 *self == old(self).push(v),
212 self.len() == old(self).len() + 1,
213 {
214 broadcast use group_seq_axioms;
215
216 assert(self.insert(self.len() as int, v) =~= self.push(v));
217 self.tracked_insert(self.len() as int, v);
218 }
219
220 pub proof fn tracked_pop(tracked &mut self) -> (tracked ret: A)
221 requires
222 old(self).len() > 0,
223 ensures
224 ret === old(self).last(),
225 self.len() == old(self).len() - 1,
226 *self == old(self).take(old(self).len() - 1),
227 {
228 broadcast use group_seq_axioms;
229
230 assert(self.remove(self.len() - 1) =~= self.take(self.len() - 1));
231 self.tracked_remove(self.len() - 1)
232 }
233
234 pub proof fn tracked_pop_front(tracked &mut self) -> (tracked ret: A)
235 requires
236 old(self).len() > 0,
237 ensures
238 ret === old(self).first(),
239 self.len() == old(self).len() - 1,
240 *self == old(self).drop_first(),
241 {
242 broadcast use group_seq_axioms;
243
244 assert(self.remove(0) =~= self.drop_first());
245 self.tracked_remove(0)
246 }
247}
248
249pub broadcast axiom fn axiom_seq_index_decreases<A>(s: Seq<A>, i: int)
251 requires
252 0 <= i < s.len(),
253 ensures
254 #[trigger] (decreases_to!(s => s[i])),
255;
256
257pub axiom fn axiom_seq_len_decreases<A>(s1: Seq<A>, s2: Seq<A>)
258 requires
259 s2.len() < s1.len(),
260 forall|i2: int|
261 0 <= i2 < s2.len() && #[trigger] trigger(s2[i2]) ==> exists|i1: int|
262 0 <= i1 < s1.len() && s1[i1] == s2[i2],
263 ensures
264 decreases_to!(s1 => s2),
265;
266
267pub broadcast proof fn axiom_seq_subrange_decreases<A>(s: Seq<A>, i: int, j: int)
268 requires
269 0 <= i <= j <= s.len(),
270 s.subrange(i, j).len() < s.len(),
271 ensures
272 #[trigger] (decreases_to!(s => s.subrange(i, j))),
273{
274 broadcast use {axiom_seq_subrange_len, axiom_seq_subrange_index};
275
276 let s2 = s.subrange(i, j);
277 assert forall|i2: int| 0 <= i2 < s2.len() && #[trigger] trigger(s2[i2]) implies exists|i1: int|
278 0 <= i1 < s.len() && s[i1] == s2[i2] by {
279 assert(s[i + i2] == s2[i2]);
280 }
281 axiom_seq_len_decreases(s, s2);
282}
283
284pub broadcast axiom fn axiom_seq_empty<A>()
285 ensures
286 #[trigger] Seq::<A>::empty().len() == 0,
287;
288
289pub broadcast axiom fn axiom_seq_new_len<A>(len: nat, f: spec_fn(int) -> A)
290 ensures
291 #[trigger] Seq::new(len, f).len() == len,
292;
293
294pub broadcast axiom fn axiom_seq_new_index<A>(len: nat, f: spec_fn(int) -> A, i: int)
295 requires
296 0 <= i < len,
297 ensures
298 #[trigger] Seq::new(len, f)[i] == f(i),
299;
300
301pub broadcast axiom fn axiom_seq_push_len<A>(s: Seq<A>, a: A)
302 ensures
303 #[trigger] s.push(a).len() == s.len() + 1,
304;
305
306pub broadcast axiom fn axiom_seq_push_index_same<A>(s: Seq<A>, a: A, i: int)
307 requires
308 i == s.len(),
309 ensures
310 #[trigger] s.push(a)[i] == a,
311;
312
313pub broadcast axiom fn axiom_seq_push_index_different<A>(s: Seq<A>, a: A, i: int)
314 requires
315 0 <= i < s.len(),
316 ensures
317 #[trigger] s.push(a)[i] == s[i],
318;
319
320pub broadcast axiom fn axiom_seq_update_len<A>(s: Seq<A>, i: int, a: A)
321 requires
322 0 <= i < s.len(),
323 ensures
324 #[trigger] s.update(i, a).len() == s.len(),
325;
326
327pub broadcast axiom fn axiom_seq_update_same<A>(s: Seq<A>, i: int, a: A)
328 requires
329 0 <= i < s.len(),
330 ensures
331 #[trigger] s.update(i, a)[i] == a,
332;
333
334pub broadcast axiom fn axiom_seq_update_different<A>(s: Seq<A>, i1: int, i2: int, a: A)
335 requires
336 0 <= i1 < s.len(),
337 0 <= i2 < s.len(),
338 i1 != i2,
339 ensures
340 #[trigger] s.update(i2, a)[i1] == s[i1],
341;
342
343pub broadcast axiom fn axiom_seq_ext_equal<A>(s1: Seq<A>, s2: Seq<A>)
344 ensures
345 #[trigger] (s1 =~= s2) <==> {
346 &&& s1.len() == s2.len()
347 &&& forall|i: int| 0 <= i < s1.len() ==> s1[i] == s2[i]
348 },
349;
350
351pub broadcast axiom fn axiom_seq_ext_equal_deep<A>(s1: Seq<A>, s2: Seq<A>)
352 ensures
353 #[trigger] (s1 =~~= s2) <==> {
354 &&& s1.len() == s2.len()
355 &&& forall|i: int| 0 <= i < s1.len() ==> s1[i] =~~= s2[i]
356 },
357;
358
359pub broadcast axiom fn axiom_seq_subrange_len<A>(s: Seq<A>, j: int, k: int)
360 requires
361 0 <= j <= k <= s.len(),
362 ensures
363 #[trigger] s.subrange(j, k).len() == k - j,
364;
365
366pub broadcast axiom fn axiom_seq_subrange_index<A>(s: Seq<A>, j: int, k: int, i: int)
367 requires
368 0 <= j <= k <= s.len(),
369 0 <= i < k - j,
370 ensures
371 #[trigger] s.subrange(j, k)[i] == s[i + j],
372;
373
374pub broadcast axiom fn axiom_seq_add_len<A>(s1: Seq<A>, s2: Seq<A>)
375 ensures
376 #[trigger] s1.add(s2).len() == s1.len() + s2.len(),
377;
378
379pub broadcast axiom fn axiom_seq_add_index1<A>(s1: Seq<A>, s2: Seq<A>, i: int)
380 requires
381 0 <= i < s1.len(),
382 ensures
383 #[trigger] s1.add(s2)[i] == s1[i],
384;
385
386pub broadcast axiom fn axiom_seq_add_index2<A>(s1: Seq<A>, s2: Seq<A>, i: int)
387 requires
388 s1.len() <= i < s1.len() + s2.len(),
389 ensures
390 #[trigger] s1.add(s2)[i] == s2[i - s1.len()],
391;
392
393pub broadcast group group_seq_axioms {
394 axiom_seq_index_decreases,
395 axiom_seq_subrange_decreases,
396 axiom_seq_empty,
397 axiom_seq_new_len,
398 axiom_seq_new_index,
399 axiom_seq_push_len,
400 axiom_seq_push_index_same,
401 axiom_seq_push_index_different,
402 axiom_seq_update_len,
403 axiom_seq_update_same,
404 axiom_seq_update_different,
405 axiom_seq_ext_equal,
406 axiom_seq_ext_equal_deep,
407 axiom_seq_subrange_len,
408 axiom_seq_subrange_index,
409 axiom_seq_add_len,
410 axiom_seq_add_index1,
411 axiom_seq_add_index2,
412}
413
414#[doc(hidden)]
416#[macro_export]
417macro_rules! seq_internal {
418 [] => {
419 $crate::vstd::seq::Seq::empty()
420 };
421 [$elem:expr] => {
422 $crate::vstd::seq::Seq::empty()
423 .push($elem)
424 };
425 [$($elem:expr),* $(,)?] => {
426 <_ as $crate::vstd::view::View>::view(&[$($elem),*])
427 };
428 [$elem:expr; $n:expr] => {
429 $crate::vstd::seq::Seq::new(
430 $n,
431 $crate::vstd::prelude::closure_to_fn_spec(
432 |_x: _| $elem
433 ),
434 )
435 };
436}
437
438#[macro_export]
451macro_rules! seq {
452 [$($tail:tt)*] => {
453 ::builtin_macros::verus_proof_macro_exprs!($crate::vstd::seq::seq_internal!($($tail)*))
454 };
455}
456
457#[doc(hidden)]
458pub use seq_internal;
459pub use seq;
460
461}