1use core::marker;
2
3#[allow(unused_imports)]
4use super::pervasive::*;
5#[allow(unused_imports)]
6use super::prelude::*;
7
8use verus as verus_skip_verusfmt; verus_skip_verusfmt! {
10
11#[verifier::ext_equal]
12#[verifier::accept_recursive_types(A)]
13tracked enum SeqInner<A> {
14 Nil,
15 Cons { head: Tracked<A>, tail: Tracked<SeqInner<A>> },
16}
17
18impl<A> SeqInner<A> {
23 spec fn len(self) -> nat
24 decreases self,
25 {
26 match self {
27 SeqInner::Nil => 0,
28 SeqInner::Cons { tail, .. } => { 1 + tail.len() },
29 }
30 }
31
32 spec fn index(self, i: int) -> A
33 recommends
34 0 <= i < self.len(),
35 decreases self.len(),
36 {
37 match self {
38 SeqInner::Nil => arbitrary(),
39 SeqInner::Cons { head, tail } => if i == 0 {
40 head@
41 } else {
42 tail.index(i - 1)
43 },
44 }
45 }
46
47 #[verifier::inline]
48 spec fn spec_index(self, i: int) -> A
49 recommends
50 0 <= i < self.len(),
51 {
52 self.index(i)
53 }
54
55 #[verifier::inline]
56 spec fn spec_index_range<I: Integer, J: Integer>(self, i: I, j: J) -> Self
57 recommends
58 0 <= i as int <= j as int <= self.len(),
59 {
60 self.subrange(i as int, j as int)
61 }
62
63 spec fn first(self) -> A
64 recommends
65 0 < self.len(),
66 {
67 self[0]
68 }
69
70 spec fn last(self) -> A
71 recommends
72 0 < self.len(),
73 {
74 self[self.len() as int - 1]
75 }
76
77 spec fn push(self, a: A) -> SeqInner<A>
78 decreases self.len(),
79 {
80 match self {
81 SeqInner::Nil => SeqInner::Cons { head: Tracked(a), tail: Tracked(SeqInner::Nil) },
82 SeqInner::Cons { head, tail } => {
83 let new_tail = tail.push(a);
84 SeqInner::Cons { head, tail: Tracked(new_tail) }
85 },
86 }
87 }
88
89 spec fn update(self, i: int, a: A) -> SeqInner<A>
90 recommends
91 0 <= i < self.len(),
92 decreases self.len(),
93 {
94 if !(0 <= i < self.len()) { self
96 } else {
97 match self {
98 SeqInner::Nil => arbitrary(),
99 SeqInner::Cons { head, tail } => if i == 0 {
100 SeqInner::Cons { head: Tracked(a), tail }
101 } else {
102 let new_tail = tail.update(i - 1, a);
103 SeqInner::Cons { head, tail: Tracked(new_tail) }
104 },
105 }
106 }
107 }
108
109 spec fn subrange(self, start_inclusive: int, end_exclusive: int) -> SeqInner<A>
110 recommends
111 0 <= start_inclusive <= end_exclusive <= self.len(),
112 decreases start_inclusive, end_exclusive - start_inclusive,
113 {
114 match self {
115 SeqInner::Nil => SeqInner::Nil,
116 SeqInner::Cons {
117 head,
118 tail,
119 } =>
120 if start_inclusive > 0 {
122 tail.subrange(start_inclusive - 1, end_exclusive - 1)
123 } else {
124 if end_exclusive <= 0 {
125 SeqInner::Nil
126 } else {
127 let new_tail = tail.subrange(start_inclusive, end_exclusive - 1);
128 SeqInner::Cons { head, tail: Tracked(new_tail) }
129 }
130 },
131 }
132 }
133
134 spec fn add(self, rhs: SeqInner<A>) -> SeqInner<A>
135 decreases self.len(),
136 {
137 match self {
138 SeqInner::Nil => rhs,
139 SeqInner::Cons { head, tail } => {
140 let new_tail = tail.add(rhs);
141 SeqInner::Cons { head, tail: Tracked(new_tail) }
142 },
143 }
144 }
145
146 spec fn insert(self, i: int, a: A) -> SeqInner<A>
147 recommends
148 0 <= i <= self.len(),
149 {
150 self.subrange(0, i).push(a).add(self.subrange(i, self.len() as int))
151 }
152
153 spec fn remove(self, i: int) -> SeqInner<A>
154 recommends
155 0 <= i < self.len(),
156 {
157 self.subrange(0, i).add(self.subrange(i + 1, self.len() as int))
158 }
159
160 proof fn tracked_split_at(tracked &mut self, i: int) -> (tracked ret: Self)
162 requires
163 0 <= i <= old(self).len(),
164 ensures
165 *final(self) == old(self)[0..i],
166 ret == old(self)[i..old(self).len()],
167 final(self).len() == i,
168 ret.len() == old(self).len() - i,
169 decreases self.len(),
170 {
171 let tracked mut s = SeqInner::Nil;
172 super::modes::tracked_swap(&mut s, self);
173 let tracked ret = if i == 0 {
174 seq_inner::lemma_subrange_len(*old(self), 0, i);
175 seq_inner::lemma_empty(old(self)[0..i]);
176 seq_inner::lemma_full_subrange_idempotent(*old(self));
177
178 s
179 } else {
180 let ghost old_self = s;
181 match s {
182 SeqInner::Nil => {
183 assert(false);
184 proof_from_false()
185 },
186 SeqInner::Cons { head, tail } => {
187 let tracked Tracked(mut tail) = tail;
188 let ghost old_tail = tail;
189 let tracked suff = tail.tracked_split_at(i - 1);
190
191 let tracked mut new = SeqInner::Cons { head, tail: Tracked(tail) };
192
193 super::modes::tracked_swap(&mut new, self);
194
195 suff
196 },
197 }
198 };
199
200 assert(*final(self) == old(self)[0..i]);
201 assert(ret == old(self)[i..old(self).len()]);
202 seq_inner::lemma_subrange_len(*old(self), 0, i);
203 seq_inner::lemma_subrange_len(*old(self), i, old(self).len() as int);
204
205 ret
206 }
207
208 proof fn tracked_add(tracked &mut self, tracked mut b: Self)
209 ensures
210 *final(self) == old(self).add(b),
211 final(self).len() == old(self).len() + b.len(),
212 decreases self.len(),
213 {
214 let tracked mut s = SeqInner::Nil;
215 super::modes::tracked_swap(&mut s, self);
216 match s {
217 SeqInner::Nil => {
218 seq_inner::lemma_empty(*old(self));
219 super::modes::tracked_swap(&mut b, self);
220 },
221 SeqInner::Cons { head, tail } => {
222 let tracked Tracked(mut tail) = tail;
223 tail.tracked_add(b);
224 let tracked mut new = SeqInner::Cons { head, tail: Tracked(tail) };
225 super::modes::tracked_swap(&mut new, self);
226 seq_inner::lemma_add_len(s, b);
227 },
228 }
229 }
230
231 proof fn tracked_insert(tracked &mut self, i: int, tracked v: A)
232 requires
233 0 <= i <= old(self).len(),
234 ensures
235 final(self).len() == old(self).len() + 1,
236 *final(self) == old(self).insert(i, v),
237 decreases self.len(),
238 {
239 if i == self.len() {
240 seq_inner::lemma_subrange_len(*old(self), i, self.len() as int);
241 seq_inner::lemma_empty(old(self)[i..self.len()]);
242 seq_inner::lemma_full_subrange_idempotent(*old(self));
243 seq_inner::lemma_add_empty(self.push(v));
244 self.tracked_push(v);
245 } else {
246 let tracked suff = self.tracked_split_at(i);
247 self.tracked_push(v);
248 self.tracked_add(suff);
249 }
250 }
251
252 proof fn tracked_remove(tracked &mut self, i: int) -> (tracked ret: A)
253 requires
254 0 <= i < old(self).len(),
255 ensures
256 ret == old(self)[i],
257 final(self).len() == old(self).len() - 1,
258 *final(self) == old(self).remove(i),
259 decreases self.len(),
260 {
261 if i == 0 {
262 self.tracked_pop_front()
263 } else {
264 let tracked suff = self.tracked_split_at(i + 1);
265 assert(suff == old(self)[i + 1..old(self).len()]);
266
267 let tracked ret = self.tracked_pop();
268 seq_inner::lemma_subrange_index(*old(self), 0, i + 1, i);
269 assert(ret == old(self)[i]);
270 assert(*self == old(self)[0..i + 1][0..i]);
271 seq_inner::lemma_subrange_composition(*old(self), 0, i + 1, 0, i);
272
273 self.tracked_add(suff);
274 ret
275 }
276 }
277
278 proof fn tracked_borrow(tracked &self, i: int) -> (tracked ret: &A)
279 requires
280 0 <= i < self.len(),
281 ensures
282 *ret == self[i],
283 decreases self.len(),
284 {
285 if i == 0 {
286 match self {
287 SeqInner::Nil => {
288 assert(false);
289 proof_from_false()
290 },
291 SeqInner::Cons { head, .. } => { head.borrow() },
292 }
293 } else {
294 match self {
295 SeqInner::Nil => {
296 assert(false);
297 proof_from_false()
298 },
299 SeqInner::Cons { tail, .. } => { tail.tracked_borrow(i - 1) },
300 }
301 }
302 }
303
304 proof fn tracked_borrow_mut(tracked &mut self, i: int) -> (tracked ret: &mut A)
305 requires
306 0 <= i < old(self).len(),
307 ensures
308 *ret == old(self)[i],
309 *final(self) == old(self).update(i, *final(ret)),
310 decreases self.len(),
311 {
312 if i == 0 {
313 match self {
314 SeqInner::Nil => {
315 assert(false);
316 proof_from_false()
317 },
318 SeqInner::Cons { head, .. } => { head.borrow_mut() },
319 }
320 } else {
321 match self {
322 SeqInner::Nil => {
323 assert(false);
324 proof_from_false()
325 },
326 SeqInner::Cons { tail, .. } => { tail.tracked_borrow_mut(i - 1) },
327 }
328 }
329 }
330
331 proof fn tracked_push(tracked &mut self, tracked v: A)
332 ensures
333 *final(self) == old(self).push(v),
334 final(self).len() == old(self).len() + 1,
335 decreases self.len(),
336 {
337 let tracked mut s = SeqInner::Nil;
338 super::modes::tracked_swap(&mut s, self);
339 match s {
340 SeqInner::Nil => {
341 let tracked mut new = SeqInner::Cons {
342 head: Tracked(v),
343 tail: Tracked(SeqInner::Nil),
344 };
345 super::modes::tracked_swap(&mut new, self);
346 },
347 SeqInner::Cons { head, tail } => {
348 let tracked Tracked(mut tail) = tail;
349 tail.tracked_push(v);
350 let tracked mut new = SeqInner::Cons { head, tail: Tracked(tail) };
351 super::modes::tracked_swap(&mut new, self);
352 },
353 }
354 assert(*final(self) == old(self).push(v));
355 seq_inner::lemma_push_len(*old(self), v);
356 }
357
358 proof fn tracked_push_front(tracked &mut self, tracked v: A)
359 ensures
360 *final(self) == old(self).insert(0, v),
361 final(self).len() == old(self).len() + 1,
362 decreases self.len(),
363 {
364 self.tracked_insert(0, v);
365 }
366
367 proof fn tracked_pop(tracked &mut self) -> (tracked ret: A)
368 requires
369 old(self).len() > 0,
370 ensures
371 ret == old(self).last(),
372 final(self).len() == old(self).len() - 1,
373 *final(self) == old(self)[0..old(self).len() - 1],
374 decreases self.len(),
375 {
376 let tracked mut s = SeqInner::Nil;
377 super::modes::tracked_swap(&mut s, self);
378
379 let tracked ret = match s {
380 SeqInner::Nil => {
381 assert(false);
382 proof_from_false()
383 },
384 SeqInner::Cons { head, tail } => {
385 let tracked Tracked(mut tail) = tail;
386 let tracked Tracked(head) = head;
387
388 let tracked v = match tail {
389 SeqInner::Nil => {
390 let tracked mut new = SeqInner::Nil;
391 super::modes::tracked_swap(&mut new, self);
392
393 seq_inner::lemma_empty(tail);
394 seq_inner::lemma_subrange_len(*old(self), 0, old(self).len() - 1);
395 seq_inner::lemma_empty(old(self)[0..old(self).len() - 1]);
396
397 head
398 },
399 SeqInner::Cons { head: thead, tail: ttail } => {
400 let tracked mut tail = SeqInner::Cons { head: thead, tail: ttail };
401 let tracked v = tail.tracked_pop();
402
403 let tracked mut new = SeqInner::Cons {
404 head: Tracked(head),
405 tail: Tracked(tail),
406 };
407 super::modes::tracked_swap(&mut new, self);
408
409 v
410 },
411 };
412
413 v
414 },
415 };
416
417 assert(*final(self) == old(self)[0..old(self).len() - 1]);
418 seq_inner::lemma_subrange_len(*old(self), 0, old(self).len() - 1);
419
420 ret
421 }
422
423 proof fn tracked_pop_front(tracked &mut self) -> (tracked ret: A)
424 requires
425 old(self).len() > 0,
426 ensures
427 ret == old(self).first(),
428 final(self).len() == old(self).len() - 1,
429 *final(self) == old(self)[1..old(self).len()],
430 {
431 let tracked mut s = SeqInner::Nil;
432 super::modes::tracked_swap(&mut s, self);
433 let tracked ret = match s {
434 SeqInner::Nil => {
435 assert(false);
436 proof_from_false()
437 },
438 SeqInner::Cons { head, tail } => {
439 let tracked Tracked(mut tail) = tail;
440 let tracked Tracked(head) = head;
441 seq_inner::lemma_tail_subrange(head, tail);
442 assert(tail == old(self)[1..old(self).len()]);
443 super::modes::tracked_swap(&mut tail, self);
444 head
445 },
446 };
447
448 assert(*final(self) == old(self)[1..old(self).len()]);
449 seq_inner::lemma_subrange_len(*old(self), 1, old(self).len() as int);
450
451 ret
452 }
453}
454
455mod seq_inner {
456 use super::*;
457
458 pub(super) proof fn lemma_empty<A>(s: SeqInner<A>)
460 ensures
461 s.len() == 0 <==> s == SeqInner::Nil,
462 {
463 if s.len() == 0 {
464 assert(s == SeqInner::Nil)
465 }
466 if s == SeqInner::Nil {
467 assert(s.len() == 0);
468 }
469 }
470
471 pub(super) proof fn lemma_push_len<A>(s: SeqInner<A>, a: A)
473 ensures
474 s.push(a).len() == s.len() + 1,
475 decreases s.len(),
476 {
477 match s {
478 SeqInner::Nil => {},
479 SeqInner::Cons { tail, .. } => {
480 lemma_push_len(tail@, a);
481 },
482 }
483 }
484
485 pub(super) proof fn lemma_push_index_different<A>(s: SeqInner<A>, a: A, i: int)
486 requires
487 i < s.len(),
488 ensures
489 #[trigger] s.push(a)[i] == s[i],
490 decreases s,
491 {
492 match s {
493 SeqInner::Nil => {
494 lemma_index_out_of_bounds(s.push(a), i);
495 },
496 SeqInner::Cons { tail, .. } => {
497 if i == 0 {
498 } else {
499 lemma_push_index_different(tail@, a, i - 1);
500 }
501 },
502 }
503 }
504
505 pub(super) proof fn lemma_push_index_same<A>(s: SeqInner<A>, a: A, i: int)
506 requires
507 i == s.len(),
508 ensures
509 #[trigger] s.push(a)[i] == a,
510 decreases s,
511 {
512 match s {
513 SeqInner::Nil => {
514 assert(s.push(a) == SeqInner::Cons {
515 head: Tracked(a),
516 tail: Tracked(SeqInner::Nil),
517 });
518 assert(s.push(a)[0] == a);
519 },
520 SeqInner::Cons { tail, .. } => {
521 lemma_push_index_same(tail@, a, i - 1);
522 },
523 }
524 }
525
526 pub(super) proof fn lemma_update_len<A>(s: SeqInner<A>, i: int, a: A)
528 ensures
529 s.update(i, a).len() == s.len(),
530 decreases i,
531 {
532 if !(0 <= i < s.len()) {
533 assert(s.update(i, a) == s);
534 } else {
535 let s_upd = s.update(i, a);
536 match s {
537 SeqInner::Nil => {},
538 SeqInner::Cons { head, tail } => {
539 match s_upd {
540 SeqInner::Nil => {},
541 SeqInner::Cons { head: head_upd, tail: tail_upd } => {
542 if i == 0 {
543 assert(head_upd == a);
544 } else {
545 lemma_update_len(tail@, (i - 1), a);
546 }
547 },
548 }
549 },
550 }
551 }
552 }
553
554 pub(super) proof fn lemma_update_index_same<A>(s: SeqInner<A>, i: int, a: A)
555 requires
556 0 <= i < s.len(),
557 ensures
558 #[trigger] s.update(i, a)[i] == a,
559 decreases s,
560 {
561 match s {
562 SeqInner::Nil => {},
563 SeqInner::Cons { tail, .. } => {
564 if i == 0 {
565 assert(s.update(i, a)[i] == a)
566 } else {
567 lemma_update_index_same(tail@, i - 1, a);
568 }
569 },
570 }
571 }
572
573 pub(super) proof fn lemma_update_index_different<A>(s: SeqInner<A>, i1: int, i2: int, a: A)
574 requires
575 i1 != i2,
576 ensures
577 #[trigger] s.update(i2, a)[i1] == s[i1],
578 decreases s,
579 {
580 if !(0 <= i2 < s.len()) {
581 assert(s.update(i2, a) == s);
582 } else {
583 match s {
584 SeqInner::Nil => {},
585 SeqInner::Cons { tail, .. } => {
586 if i2 == 0 {
587 assert(s.update(i2, a)[i1] == s[i1]);
588 } else if i1 == 0 {
589 assert(s.update(i2, a)[i1] == s[i1]);
590 } else {
591 lemma_update_index_different(tail@, i1 - 1, i2 - 1, a);
592 }
593 },
594 }
595 }
596 }
597
598 pub(super) proof fn lemma_subrange_len<A>(s: SeqInner<A>, j: int, k: int)
600 requires
601 0 <= j <= k <= s.len(),
602 ensures
603 s[j..k].len() == k - j,
604 decreases j, k,
605 {
606 match s {
607 SeqInner::Nil => {},
608 SeqInner::Cons { head, tail } => {
609 if j > 0 {
610 assert(s[j..k] == tail[j - 1..k - 1]);
611 lemma_subrange_len(tail@, j - 1, k - 1);
612 } else if k > 0 {
613 let new_tail = tail@[j..k - 1];
614 lemma_subrange_len(tail@, j, k - 1);
615 assert(new_tail.len() == k - j - 1);
616 let sub = SeqInner::Cons { head, tail: Tracked(new_tail) };
617 assert(sub.len() == 1 + new_tail.len());
618 } else {
619 assert(j == k == 0);
620 assert(s[j..k].len() == 0);
621 }
622 },
623 }
624 }
625
626 pub(super) proof fn lemma_subrange_composition_aux2<A>(s: SeqInner<A>, j1: int, j2: int)
627 requires
628 0 <= j2 <= j1 <= s.len(),
629 ensures
630 s[0..j1][0..j2] == s[0..j2],
631 decreases s.len(),
632 {
633 if j1 == j2 {
634 lemma_subrange_len(s, 0, j1);
635 lemma_full_subrange_idempotent(s[0..j1]);
636 } else if j1 == 0 {
637 assert(false);
638 } else if j2 == 0 {
639 lemma_subrange_len(s[0..j1], 0, j2);
640 lemma_empty(s[0..j1][0..j2]);
641 } else {
642 match s {
643 SeqInner::Nil => {},
644 SeqInner::Cons { head, tail } => {
645 lemma_subrange_composition_aux2(tail@, j1 - 1, j2 - 1);
646 },
647 }
648 }
649 }
650
651 pub(super) proof fn lemma_subrange_index_aux<A>(s: SeqInner<A>, k: int, i: int)
652 requires
653 0 <= k <= s.len(),
654 0 <= i < k,
655 ensures
656 s[0..k][i] == s[i],
657 decreases s,
658 {
659 lemma_subrange_len(s, 0, k);
660 match s {
663 SeqInner::Nil => {
664 },
666 SeqInner::Cons { head, tail } => {
667 if i == 0 {
668 assert(s[0..k][0] == head);
670 } else {
671 lemma_subrange_index_aux(tail@, k - 1, i - 1);
672 }
673 },
674 }
675 }
676
677 pub(super) proof fn lemma_subrange_index<A>(s: SeqInner<A>, j: int, k: int, i: int)
678 requires
679 0 <= j <= k <= s.len(),
680 0 <= i < k - j,
681 ensures
682 s[j..k][i] == s[i + j],
683 decreases s,
684 {
685 lemma_subrange_len(s, j, k);
686 if j == 0 {
687 lemma_subrange_index_aux(s, k, i);
688 } else {
689 match s {
690 SeqInner::Nil => {
691 assert(false);
692 },
693 SeqInner::Cons { head, tail } => {
694 lemma_subrange_index(tail@, j - 1, k - 1, i);
695 },
696 }
697 }
698 }
699
700 pub(super) proof fn lemma_subrange_composition_aux1<A>(
701 s: SeqInner<A>,
702 j1: int,
703 i2: int,
704 j2: int,
705 )
706 requires
707 0 <= j1 <= s.len(),
708 0 <= i2 <= j2 <= j1,
709 ensures
710 s[0..j1][i2..j2] == s[i2..j2],
711 decreases s.len(),
712 {
713 if i2 == 0 {
714 lemma_subrange_composition_aux2(s, j1, j2);
715 } else {
716 match s {
717 SeqInner::Nil => {},
718 SeqInner::Cons { head, tail } => {
719 lemma_subrange_composition_aux1(tail@, j1 - 1, i2 - 1, j2 - 1);
720 },
721 }
722 }
723 }
724
725 pub(super) proof fn lemma_subrange_composition<A>(
726 s: SeqInner<A>,
727 i1: int,
728 j1: int,
729 i2: int,
730 j2: int,
731 )
732 requires
733 0 <= i1 <= j1 <= s.len(),
734 0 <= i2 <= j2 <= j1 - i1,
735 ensures
736 s[i1..j1][i2..j2] == s[i1 + i2..i1 + j2],
737 decreases s.len(),
738 {
739 if i1 == 0 {
740 lemma_subrange_composition_aux1(s, j1, i2, j2);
741 } else {
742 match s {
743 SeqInner::Nil => {},
744 SeqInner::Cons { head, tail } => {
745 lemma_subrange_composition(tail@, i1 - 1, j1 - 1, i2, j2);
746 },
747 }
748 }
749 }
750
751 pub(super) open spec fn cons_list<A>(head: A, tail: SeqInner<A>) -> SeqInner<A> {
752 SeqInner::Cons { head: Tracked(head), tail: Tracked(tail) }
753 }
754
755 pub(super) proof fn lemma_tail_subrange<A>(head: A, tail: SeqInner<A>)
756 ensures
757 cons_list(head, tail)[1..cons_list(head, tail).len()] == tail,
758 {
759 let s = SeqInner::Cons { head: Tracked(head), tail: Tracked(tail) };
760 match s {
761 SeqInner::Nil => {
762 assert(false);
763 },
764 SeqInner::Cons { head: h, tail: t } => { lemma_full_subrange_idempotent(tail) },
765 }
766 }
767
768 pub(super) proof fn lemma_full_subrange_idempotent<A>(s: SeqInner<A>)
769 ensures
770 s[0..s.len()] == s,
771 decreases s.len(),
772 {
773 match s {
774 SeqInner::Nil => {
775 assert(s[0..s.len()] == s);
776 },
777 SeqInner::Cons { head, tail } => {
778 lemma_subrange_index(s, 0, s.len() as int, 0);
779 lemma_full_subrange_idempotent(tail@);
780 },
781 }
782 }
783
784 pub(super) proof fn lemma_index_decreases<A>(s: SeqInner<A>, i: int)
786 requires
787 0 <= i < s.len(),
788 ensures
789 (decreases_to!(s => s[i])),
790 decreases i,
791 {
792 match s {
793 SeqInner::Nil => {
794 assert(s.len() == 0);
795 assert(false);
796 },
797 SeqInner::Cons { head, tail } => {
798 if i == 0 {
799 assert(decreases_to!(s => s[i]));
800 } else {
801 assert(tail[i - 1] == s[i]);
802 lemma_index_decreases(tail@, i - 1);
803 assert(decreases_to!(s => tail@));
804 assert(decreases_to!(tail@ => tail[i-1]));
805 }
806 },
807 }
808 }
809
810 pub(super) proof fn lemma_add_empty<A>(s: SeqInner<A>)
812 ensures
813 s.add(SeqInner::Nil) == s,
814 SeqInner::Nil.add(s) == s,
815 decreases s.len(),
816 {
817 assert(SeqInner::Nil.add(s) == s);
818
819 let sum = s.add(SeqInner::Nil);
820 match s {
821 SeqInner::Nil => {
822 assert(sum == SeqInner::Nil);
823 assert(s == SeqInner::Nil);
824 },
825 SeqInner::Cons { head, tail } => {
826 assert(sum == SeqInner::Cons { head, tail: Tracked(tail@.add(SeqInner::Nil)) });
827 lemma_add_empty(tail@);
828 },
829 }
830 }
831
832 pub(super) proof fn lemma_add_len<A>(s1: SeqInner<A>, s2: SeqInner<A>)
833 ensures
834 s1.add(s2).len() == s1.len() + s2.len(),
835 decreases s1.add(s2).len(),
836 {
837 let sum = s1.add(s2);
838 match s1 {
839 SeqInner::Nil => {
840 assert(sum == s2);
841 },
842 SeqInner::Cons { head, tail } => {
843 let new_tail = tail@.add(s2);
844 lemma_add_len(tail@, s2);
845 assert(new_tail.len() == (s1.len() - 1) + s2.len());
846 assert(sum.len() == 1 + new_tail.len());
847 },
848 }
849 }
850
851 pub(super) proof fn lemma_add_index1<A>(s1: SeqInner<A>, s2: SeqInner<A>, i: int)
852 requires
853 i < s1.len(),
854 ensures
855 s1.add(s2)[i] == s1[i],
856 decreases s1,
857 {
858 if i < 0 {
859 lemma_index_out_of_bounds(s1, i);
860 lemma_index_out_of_bounds(s1.add(s2), i);
861 } else {
862 match s1 {
863 SeqInner::Nil => {},
864 SeqInner::Cons { head, tail } => {
865 if i == 0 {
866 assert(s1[i] == s1.add(s2)[i]);
867 } else {
868 lemma_add_index1(tail@, s2, i - 1);
869 }
870 },
871 }
872 }
873 }
874
875 pub(super) proof fn lemma_add_index2<A>(s1: SeqInner<A>, s2: SeqInner<A>, i: int)
876 requires
877 s1.len() <= i < s1.len() + s2.len(),
878 ensures
879 s1.add(s2)[i] == s2[i - s1.len()],
880 decreases s1,
881 {
882 match s1 {
883 SeqInner::Nil => {
884 assert(s1.add(s2) == s2);
885 assert(s1.add(s2)[i] == s2[i - s1.len()]);
886 },
887 SeqInner::Cons { head, tail } => {
888 if i == 0 {
889 assert(s1.add(s2)[i] == s2[i - s1.len()]);
890 } else {
891 lemma_add_index2(tail@, s2, i - 1);
892 assert(s1.add(s2)[i] == s2[i - s1.len()]);
893 }
894 },
895 }
896 }
897
898 pub(super) proof fn lemma_index_out_of_bounds<A>(s: SeqInner<A>, i: int)
900 requires
901 !(0 <= i < s.len()),
902 ensures
903 s[i] == arbitrary::<A>(),
904 decreases s,
905 {
906 match s {
907 SeqInner::Nil => {},
908 SeqInner::Cons { tail, .. } => {
909 lemma_index_out_of_bounds(tail@, i - 1);
910 },
911 }
912 }
913
914}
915
916#[verifier::ext_equal]
935#[verifier::accept_recursive_types(A)]
936pub tracked struct Seq<A> {
937 inner: SeqInner<A>,
938}
939
940impl<A> Seq<A> {
941 #[rustc_diagnostic_item = "verus::vstd::seq::Seq::empty"]
943 pub closed spec fn empty() -> Seq<A> {
944 Seq { inner: SeqInner::Nil }
945 }
946
947 #[rustc_diagnostic_item = "verus::vstd::seq::Seq::new"]
949 pub closed spec fn new(len: nat, f: spec_fn(int) -> A) -> Seq<A>
950 decreases len,
951 {
952 if len == 0 {
953 Seq { inner: SeqInner::Nil }
954 } else {
955 Self::new((len - 1) as nat, f).push(f(len - 1))
956 }
957 }
958
959 #[rustc_diagnostic_item = "verus::vstd::seq::Seq::len"]
961 pub closed spec fn len(self) -> nat {
962 self.inner.len()
963 }
964
965 #[rustc_diagnostic_item = "verus::vstd::seq::Seq::index"]
970 pub closed spec fn index(self, i: int) -> A
971 recommends
972 0 <= i < self.len(),
973 {
974 self.inner.index(i)
975 }
976
977 #[verifier::inline]
979 pub open spec fn spec_index(self, i: int) -> A
980 recommends
981 0 <= i < self.len(),
982 {
983 self.index(i)
984 }
985
986 #[verifier::inline]
988 pub open spec fn spec_index_range_full(self) -> Seq<A> {
989 self
990 }
991
992 #[verifier::inline]
994 pub open spec fn spec_index_range_from<I: Integer>(self, i: I) -> Seq<A>
995 recommends
996 0 <= i as int <= self.len(),
997 {
998 self.skip(i as int)
999 }
1000
1001 #[verifier::inline]
1003 pub open spec fn spec_index_range_to<J: Integer>(self, j: J) -> Seq<A>
1004 recommends
1005 0 <= j as int <= self.len(),
1006 {
1007 self.take(j as int)
1008 }
1009
1010 #[verifier::inline]
1012 pub open spec fn spec_index_range_to_inclusive<J: Integer>(self, j: J) -> Seq<A>
1013 recommends
1014 0 <= (j as int) < self.len(),
1015 {
1016 self.take(j as int + 1)
1017 }
1018
1019 #[verifier::inline]
1021 pub open spec fn spec_index_range<I: Integer, J: Integer>(self, i: I, j: J) -> Seq<A>
1022 recommends
1023 0 <= i as int <= j as int <= self.len(),
1024 {
1025 self.subrange(i as int, j as int)
1026 }
1027
1028 #[verifier::inline]
1030 pub open spec fn spec_index_range_inclusive<I: Integer, J: Integer>(self, i: I, j: J) -> Seq<A>
1031 recommends
1032 0 <= i as int <= (j as int) < self.len(),
1033 {
1034 self.subrange(i as int, j as int + 1)
1035 }
1036
1037 #[rustc_diagnostic_item = "verus::vstd::seq::Seq::push"]
1050 pub closed spec fn push(self, a: A) -> Seq<A> {
1051 Seq { inner: self.inner.push(a) }
1052 }
1053
1054 #[rustc_diagnostic_item = "verus::vstd::seq::Seq::update"]
1067 pub closed spec fn update(self, i: int, a: A) -> Seq<A>
1068 recommends
1069 0 <= i < self.len(),
1070 {
1071 Seq { inner: self.inner.update(i, a) }
1072 }
1073
1074 #[rustc_diagnostic_item = "verus::vstd::seq::Seq::subrange"]
1088 pub closed spec fn subrange(self, start_inclusive: int, end_exclusive: int) -> Seq<A>
1089 recommends
1090 0 <= start_inclusive <= end_exclusive <= self.len(),
1091 {
1092 Seq { inner: self.inner.subrange(start_inclusive, end_exclusive) }
1093 }
1094
1095 #[verifier::inline]
1097 pub open spec fn take(self, n: int) -> Seq<A> {
1098 self.subrange(0, n)
1099 }
1100
1101 #[verifier::inline]
1103 pub open spec fn skip(self, n: int) -> Seq<A> {
1104 self.subrange(n, self.len() as int)
1105 }
1106
1107 #[rustc_diagnostic_item = "verus::vstd::seq::Seq::add"]
1118 pub closed spec fn add(self, rhs: Seq<A>) -> Seq<A> {
1119 Seq { inner: self.inner.add(rhs.inner) }
1120 }
1121
1122 #[verifier::inline]
1124 pub open spec fn spec_add(self, rhs: Seq<A>) -> Seq<A> {
1125 self.add(rhs)
1126 }
1127
1128 #[rustc_diagnostic_item = "verus::vstd::seq::Seq::last"]
1130 pub open spec fn last(self) -> A
1131 recommends
1132 0 < self.len(),
1133 {
1134 self[self.len() as int - 1]
1135 }
1136
1137 #[rustc_diagnostic_item = "vstd::seq::Seq::first"]
1139 pub open spec fn first(self) -> A
1140 recommends
1141 0 < self.len(),
1142 {
1143 self[0]
1144 }
1145
1146 pub proof fn tracked_empty() -> (tracked ret: Self)
1148 ensures
1149 ret == Seq::empty(),
1150 {
1151 Seq { inner: SeqInner::Nil }
1152 }
1153
1154 pub proof fn tracked_insert(tracked &mut self, i: int, tracked v: A)
1169 requires
1170 0 <= i <= old(self).len(),
1171 ensures
1172 final(self).len() == old(self).len() + 1,
1173 *final(self) == old(self).insert(i, v),
1174 {
1175 self.inner.tracked_insert(i, v)
1176 }
1177
1178 pub proof fn tracked_remove(tracked &mut self, i: int) -> (tracked ret: A)
1180 requires
1181 0 <= i < old(self).len(),
1182 ensures
1183 ret == old(self)[i],
1184 final(self).len() == old(self).len() - 1,
1185 *final(self) == old(self).remove(i),
1186 {
1187 self.inner.tracked_remove(i)
1188 }
1189
1190 pub proof fn tracked_borrow(tracked &self, i: int) -> (tracked ret: &A)
1192 requires
1193 0 <= i < self.len(),
1194 ensures
1195 *ret == self[i],
1196 {
1197 self.inner.tracked_borrow(i)
1198 }
1199
1200 pub proof fn tracked_borrow_mut(tracked &mut self, i: int) -> (tracked ret: &mut A)
1202 requires
1203 0 <= i < old(self).len(),
1204 ensures
1205 *ret == old(self)[i],
1206 *final(self) == old(self).update(i, *final(ret)),
1207 {
1208 self.inner.tracked_borrow_mut(i)
1209 }
1210
1211 pub proof fn tracked_push(tracked &mut self, tracked v: A)
1213 ensures
1214 *final(self) == old(self).push(v),
1215 final(self).len() == old(self).len() + 1,
1216 {
1217 self.inner.tracked_push(v)
1218 }
1219
1220 pub proof fn tracked_push_front(tracked &mut self, tracked v: A)
1222 ensures
1223 *final(self) == old(self).insert(0, v),
1224 final(self).len() == old(self).len() + 1,
1225 {
1226 self.inner.tracked_push_front(v)
1227 }
1228
1229 pub proof fn tracked_pop(tracked &mut self) -> (tracked ret: A)
1231 requires
1232 old(self).len() > 0,
1233 ensures
1234 ret == old(self).last(),
1235 final(self).len() == old(self).len() - 1,
1236 *final(self) == old(self)[..old(self).len() - 1],
1237 {
1238 self.inner.tracked_pop()
1239 }
1240
1241 pub proof fn tracked_pop_front(tracked &mut self) -> (tracked ret: A)
1243 requires
1244 old(self).len() > 0,
1245 ensures
1246 ret == old(self).first(),
1247 final(self).len() == old(self).len() - 1,
1248 *final(self) == old(self).drop_first(),
1249 {
1250 self.inner.tracked_pop_front()
1251 }
1252
1253 pub proof fn tracked_split_at(tracked &mut self, i: int) -> (tracked ret: Self)
1255 requires
1256 0 <= i <= old(self).len(),
1257 ensures
1258 *final(self) == old(self)[0..i],
1259 ret == old(self)[i..old(self).len()],
1260 final(self).len() == i,
1261 ret.len() == old(self).len() - i,
1262 {
1263 Seq { inner: self.inner.tracked_split_at(i) }
1264 }
1265
1266 proof fn tracked_add(tracked &mut self, tracked b: Self)
1267 ensures
1268 *final(self) == old(self).add(b),
1269 final(self).len() == old(self).len() + b.len(),
1270 {
1271 self.inner.tracked_add(b.inner)
1272 }
1273}
1274
1275#[deprecated(note = "Seq axioms have been verified, and are now lemmas")]
1276pub broadcast proof fn axiom_seq_index_decreases<A>(s: Seq<A>, i: int)
1277 requires
1278 0 <= i < s.len(),
1279 ensures
1280 #[trigger] (decreases_to!(s => s[i])),
1281{
1282 lemma_seq_index_decreases(s, i)
1283}
1284
1285pub broadcast proof fn lemma_seq_index_decreases<A>(s: Seq<A>, i: int)
1286 requires
1287 0 <= i < s.len(),
1288 ensures
1289 #[trigger] (decreases_to!(s => s[i])),
1290{
1291 seq_inner::lemma_index_decreases(s.inner, i)
1292}
1293
1294pub axiom fn axiom_seq_len_decreases<A>(s1: Seq<A>, s2: Seq<A>)
1296 requires
1297 s2.len() < s1.len(),
1298 forall|i2: int|
1299 0 <= i2 < s2.len() && #[trigger] trigger(s2[i2]) ==> exists|i1: int|
1300 0 <= i1 < s1.len() && s1[i1] == s2[i2],
1301 ensures
1302 decreases_to!(s1 => s2),
1303;
1304
1305#[deprecated(note = "Seq axioms have been verified, and are now lemmas")]
1306pub broadcast proof fn axiom_seq_subrange_decreases<A>(s: Seq<A>, i: int, j: int)
1307 requires
1308 0 <= i <= j <= s.len(),
1309 s[i..j].len() < s.len(),
1310 ensures
1311 #[trigger] (decreases_to!(s => s[i..j])),
1312{
1313 lemma_seq_subrange_decreases(s, i, j)
1314}
1315
1316pub broadcast proof fn lemma_seq_subrange_decreases<A>(s: Seq<A>, i: int, j: int)
1317 requires
1318 0 <= i <= j <= s.len(),
1319 s[i..j].len() < s.len(),
1320 ensures
1321 #[trigger] (decreases_to!(s => s[i..j])),
1322{
1323 broadcast use {lemma_seq_subrange_len, lemma_seq_subrange_index};
1324
1325 let s2 = s[i..j];
1326 assert forall|i2: int| 0 <= i2 < s2.len() && #[trigger] trigger(s2[i2]) implies exists|i1: int|
1327 0 <= i1 < s.len() && s[i1] == s2[i2] by {
1328 assert(s[i + i2] == s2[i2]);
1329 }
1330 axiom_seq_len_decreases(s, s2);
1331}
1332
1333#[deprecated(note = "Seq axioms have been verified, and are now lemmas")]
1334pub broadcast proof fn axiom_seq_empty<A>()
1335 ensures
1336 #[trigger] Seq::<A>::empty().len() == 0,
1337{
1338 broadcast use lemma_seq_empty;
1339
1340}
1341
1342pub broadcast proof fn lemma_seq_empty<A>()
1343 ensures
1344 #[trigger] Seq::<A>::empty().len() == 0,
1345{
1346 let s = Seq::<A>::empty();
1347 match s.inner {
1348 SeqInner::Nil => {
1349 assert(s == Seq { inner: SeqInner::Nil });
1350 },
1351 SeqInner::Cons { tail, .. } => {
1352 let seq_tail = Seq { inner: tail@ };
1353 assert(s.len() == 1 + seq_tail.len());
1354 assert(s.len() > 0);
1355 },
1356 }
1357}
1358
1359#[deprecated(note = "Seq axioms have been verified, and are now lemmas")]
1360pub broadcast proof fn axiom_seq_new_len<A>(len: nat, f: spec_fn(int) -> A)
1361 ensures
1362 #[trigger] Seq::new(len, f).len() == len,
1363{
1364 lemma_seq_new_len(len, f)
1365}
1366
1367pub broadcast proof fn lemma_seq_new_len<A>(len: nat, f: spec_fn(int) -> A)
1368 ensures
1369 #[trigger] Seq::new(len, f).len() == len,
1370 decreases len,
1371{
1372 let s = Seq::new(len, f);
1373 if len == 0 {
1374 assert(s.len() == 0);
1375 } else {
1376 broadcast use lemma_seq_push_len;
1377
1378 let pref = Seq::new((len - 1) as nat, f);
1379 lemma_seq_new_len((len - 1) as nat, f);
1380 assert(pref.len() == (len - 1) as nat);
1381
1382 let s2 = pref.push(f(len - 1));
1383 assert(s2.len() == pref.len() + 1);
1384
1385 assert(s == s2);
1386 assert(s.len() == len);
1387 }
1388}
1389
1390#[deprecated(note = "Seq axioms have been verified, and are now lemmas")]
1391pub broadcast proof fn axiom_seq_new_index<A>(len: nat, f: spec_fn(int) -> A, i: int)
1392 requires
1393 0 <= i < len,
1394 ensures
1395 #[trigger] Seq::new(len, f)[i] == f(i),
1396{
1397 lemma_seq_new_index(len, f, i)
1398}
1399
1400pub broadcast proof fn lemma_seq_new_index<A>(len: nat, f: spec_fn(int) -> A, i: int)
1401 requires
1402 0 <= i < len,
1403 ensures
1404 #[trigger] Seq::new(len, f)[i] == f(i),
1405 decreases len,
1406{
1407 broadcast use lemma_seq_new_len;
1408
1409 let s = Seq::new(len, f);
1410 assert(s.len() == len);
1411
1412 let pref = Seq::new((len - 1) as nat, f);
1413 assert(pref.len() == len - 1);
1414
1415 let a = f(len - 1);
1416 assert(s == pref.push(a));
1417
1418 if i == len - 1 {
1419 lemma_seq_push_index_same(pref, a, i);
1420 assert(s[i] == a);
1421 } else {
1422 assert(0 <= i < (len - 1));
1423 lemma_seq_new_index((len - 1) as nat, f, i);
1424 lemma_seq_push_index_different(pref, a, i);
1425 }
1426}
1427
1428#[deprecated(note = "Seq axioms have been verified, and are now lemmas")]
1429pub broadcast proof fn axiom_seq_push_len<A>(s: Seq<A>, a: A)
1430 ensures
1431 #[trigger] s.push(a).len() == s.len() + 1,
1432{
1433 lemma_seq_push_len(s, a)
1434}
1435
1436pub broadcast proof fn lemma_seq_push_len<A>(s: Seq<A>, a: A)
1437 ensures
1438 #[trigger] s.push(a).len() == s.len() + 1,
1439{
1440 seq_inner::lemma_push_len(s.inner, a)
1441}
1442
1443#[deprecated(note = "Seq axioms have been verified, and are now lemmas")]
1444pub broadcast proof fn axiom_seq_push_index_same<A>(s: Seq<A>, a: A, i: int)
1445 requires
1446 i == s.len(),
1447 ensures
1448 #[trigger] s.push(a)[i] == a,
1449{
1450 lemma_seq_push_index_same(s, a, i)
1451}
1452
1453pub broadcast proof fn lemma_seq_push_index_same<A>(s: Seq<A>, a: A, i: int)
1454 requires
1455 i == s.len(),
1456 ensures
1457 #[trigger] s.push(a)[i] == a,
1458{
1459 seq_inner::lemma_push_index_same(s.inner, a, i);
1460}
1461
1462#[deprecated(note = "Seq axioms have been verified, and are now lemmas")]
1463pub broadcast proof fn axiom_seq_push_index_different<A>(s: Seq<A>, a: A, i: int)
1464 requires
1465 i < s.len(),
1466 ensures
1467 #[trigger] s.push(a)[i] == s[i],
1468{
1469 lemma_seq_push_index_different(s, a, i)
1470}
1471
1472pub broadcast proof fn lemma_seq_push_index_different<A>(s: Seq<A>, a: A, i: int)
1473 requires
1474 i < s.len(),
1475 ensures
1476 #[trigger] s.push(a)[i] == s[i],
1477{
1478 seq_inner::lemma_push_index_different(s.inner, a, i);
1479}
1480
1481pub broadcast proof fn lemma_seq_push_index_different_alt<A>(s: Seq<A>, a: A, i: int)
1483 requires
1484 i < s.len(),
1485 ensures
1486 (#[trigger] s.push(a))[i] == #[trigger] s[i],
1487{
1488 broadcast use lemma_seq_push_index_different;
1489
1490}
1491
1492#[deprecated(note = "Seq axioms have been verified, and are now lemmas")]
1493pub broadcast proof fn axiom_seq_update_len<A>(s: Seq<A>, i: int, a: A)
1494 ensures
1495 #[trigger] s.update(i, a).len() == s.len(),
1496{
1497 lemma_seq_update_len(s, i, a)
1498}
1499
1500pub broadcast proof fn lemma_seq_update_len<A>(s: Seq<A>, i: int, a: A)
1501 ensures
1502 #[trigger] s.update(i, a).len() == s.len(),
1503 decreases i,
1504{
1505 seq_inner::lemma_update_len(s.inner, i, a)
1506}
1507
1508#[deprecated(note = "Seq axioms have been verified, and are now lemmas")]
1509pub broadcast proof fn axiom_seq_update_same<A>(s: Seq<A>, i: int, a: A)
1510 requires
1511 0 <= i < s.len(),
1512 ensures
1513 #[trigger] s.update(i, a)[i] == a,
1514{
1515 lemma_seq_update_same(s, i, a)
1516}
1517
1518pub broadcast proof fn lemma_seq_update_same<A>(s: Seq<A>, i: int, a: A)
1519 requires
1520 0 <= i < s.len(),
1521 ensures
1522 #[trigger] s.update(i, a)[i] == a,
1523{
1524 seq_inner::lemma_update_index_same(s.inner, i, a);
1525}
1526
1527pub broadcast proof fn lemma_seq_update_same_alt<A>(s: Seq<A>, i: int, a: A)
1529 requires
1530 0 <= i < s.len(),
1531 ensures
1532 #![trigger s.update(i, a), s[i]]
1533 s.update(i, a)[i] == a,
1534{
1535 broadcast use lemma_seq_update_same;
1536
1537}
1538
1539#[deprecated(note = "Seq axioms have been verified, and are now lemmas")]
1540pub broadcast proof fn axiom_seq_update_different<A>(s: Seq<A>, i1: int, i2: int, a: A)
1541 requires
1542 i1 != i2,
1543 ensures
1544 #[trigger] s.update(i2, a)[i1] == s[i1],
1545{
1546 lemma_seq_update_different(s, i1, i2, a)
1547}
1548
1549pub broadcast proof fn lemma_seq_update_different<A>(s: Seq<A>, i1: int, i2: int, a: A)
1550 requires
1551 i1 != i2,
1552 ensures
1553 #[trigger] s.update(i2, a)[i1] == s[i1],
1554{
1555 seq_inner::lemma_update_index_different(s.inner, i1, i2, a);
1556}
1557
1558pub broadcast proof fn lemma_seq_update_different_alt<A>(s: Seq<A>, i1: int, i2: int, a: A)
1560 requires
1561 i1 != i2,
1562 ensures
1563 (#[trigger] s.update(i2, a))[i1] == #[trigger] s[i1],
1564{
1565 broadcast use lemma_seq_update_different;
1566
1567}
1568
1569#[deprecated(note = "Seq axioms have been verified, and are now lemmas")]
1570pub broadcast proof fn axiom_seq_ext_equal<A>(s1: Seq<A>, s2: Seq<A>)
1571 ensures
1572 #[trigger] (s1 =~= s2) <==> {
1573 &&& s1.len() == s2.len()
1574 &&& forall|i: int| 0 <= i < s1.len() ==> s1[i] == s2[i]
1575 },
1576{
1577 lemma_seq_ext_equal(s1, s2)
1578}
1579
1580pub broadcast proof fn lemma_seq_ext_equal<A>(s1: Seq<A>, s2: Seq<A>)
1581 ensures
1582 #[trigger] (s1 =~= s2) <==> {
1583 &&& s1.len() == s2.len()
1584 &&& forall|i: int| 0 <= i < s1.len() ==> s1[i] == s2[i]
1585 },
1586 decreases s1.len(),
1587{
1588 match s1.inner {
1589 SeqInner::Nil => {
1590 assert(s1.len() == s2.len() <==> s1 =~= s2);
1591 },
1592 SeqInner::Cons { head: head1, tail: tail1 } => {
1593 let seq_tail1 = Seq { inner: tail1@ };
1594
1595 match s2.inner {
1596 SeqInner::Nil => {
1597 assert(s1.len() != s2.len());
1598 },
1599 SeqInner::Cons { head: head2, tail: tail2 } => {
1600 if head1 != head2 {
1601 assert(s1[0] != s2[0]);
1602 } else {
1603 let seq_tail2 = Seq { inner: tail2@ };
1604 lemma_seq_ext_equal(seq_tail1, seq_tail2);
1605 if seq_tail1 =~= seq_tail2 {
1606 assert(s1.len() == seq_tail1.len() + 1 == seq_tail2.len() + 1
1607 == s2.len());
1608 assert forall|i: int| 0 <= i < s1.len() implies s1[i] == s2[i] by {
1609 if i == 0 {
1610 assert(s1[0] == s2[0]);
1611 } else {
1612 assert(s1[i] == s2[i]);
1613 }
1614 }
1615 } else if seq_tail1.len() == seq_tail2.len() {
1616 assert(exists|i: int|
1617 0 <= i < seq_tail1.len() && seq_tail1[i] != seq_tail2[i]);
1618 let i = choose|i: int|
1619 0 <= i < seq_tail1.len() && seq_tail1[i] != seq_tail2[i];
1620 assert(s1[i + 1] != s2[i + 1]);
1621 } else {
1622 assert(s1.len() != s2.len());
1623 }
1624 }
1625 },
1626 }
1627 },
1628 }
1629}
1630
1631#[deprecated(note = "Seq axioms have been verified, and are now lemmas")]
1632pub broadcast proof fn axiom_seq_ext_equal_deep<A>(s1: Seq<A>, s2: Seq<A>)
1633 ensures
1634 #[trigger] (s1 =~~= s2) <==> {
1635 &&& s1.len() == s2.len()
1636 &&& forall|i: int| 0 <= i < s1.len() ==> s1[i] =~~= s2[i]
1637 },
1638{
1639 lemma_seq_ext_equal_deep(s1, s2)
1640}
1641
1642pub broadcast proof fn lemma_seq_ext_equal_deep<A>(s1: Seq<A>, s2: Seq<A>)
1643 ensures
1644 #[trigger] (s1 =~~= s2) <==> {
1645 &&& s1.len() == s2.len()
1646 &&& forall|i: int| 0 <= i < s1.len() ==> s1[i] =~~= s2[i]
1647 },
1648{
1649 match s1.inner {
1650 SeqInner::Nil => {
1651 assert(s1.len() == s2.len() <==> s1 =~~= s2);
1652 },
1653 SeqInner::Cons { head: head1, tail: tail1 } => {
1654 let seq_tail1 = Seq { inner: tail1@ };
1655
1656 match s2.inner {
1657 SeqInner::Nil => {
1658 assert(s1.len() != s2.len());
1659 },
1660 SeqInner::Cons { head: head2, tail: tail2 } => {
1661 if head1 != head2 {
1662 assert(s1[0] != s2[0]);
1663 } else {
1664 let seq_tail2 = Seq { inner: tail2@ };
1665 lemma_seq_ext_equal(seq_tail1, seq_tail2);
1666 if seq_tail1 =~~= seq_tail2 {
1667 assert(s1.len() == seq_tail1.len() + 1 == seq_tail2.len() + 1
1668 == s2.len());
1669 assert forall|i: int| 0 <= i < s1.len() implies s1[i] == s2[i] by {
1670 if i == 0 {
1671 assert(s1[0] == s2[0]);
1672 } else {
1673 assert(s1[i] == s2[i]);
1674 }
1675 }
1676 } else if seq_tail1.len() == seq_tail2.len() {
1677 assert(exists|i: int|
1678 0 <= i < seq_tail1.len() && seq_tail1[i] != seq_tail2[i]);
1679 let i = choose|i: int|
1680 0 <= i < seq_tail1.len() && seq_tail1[i] != seq_tail2[i];
1681 assert(s1[i + 1] != s2[i + 1]);
1682 } else {
1683 assert(s1.len() != s2.len());
1684 }
1685 }
1686 },
1687 }
1688 },
1689 }
1690}
1691
1692#[deprecated(note = "Seq axioms have been verified, and are now lemmas")]
1693pub broadcast proof fn axiom_seq_subrange_len<A>(s: Seq<A>, j: int, k: int)
1694 requires
1695 0 <= j <= k <= s.len(),
1696 ensures
1697 #[trigger] s[j..k].len() == k - j,
1698{
1699 lemma_seq_subrange_len(s, j, k)
1700}
1701
1702pub broadcast proof fn lemma_seq_subrange_len<A>(s: Seq<A>, j: int, k: int)
1703 requires
1704 0 <= j <= k <= s.len(),
1705 ensures
1706 #[trigger] s[j..k].len() == k - j,
1707{
1708 seq_inner::lemma_subrange_len(s.inner, j, k)
1709}
1710
1711pub broadcast proof fn lemma_seq_subrange_composition<A>(
1712 s: Seq<A>,
1713 i1: int,
1714 j1: int,
1715 i2: int,
1716 j2: int,
1717)
1718 requires
1719 0 <= i1 <= j1 <= s.len(),
1720 0 <= i2 <= j2 <= j1 - i1,
1721 ensures
1722 #[trigger] s[i1..j1][i2..j2] == s[i1 + i2..i1 + j2],
1723{
1724 seq_inner::lemma_subrange_composition(s.inner, i1, j1, i2, j2)
1725}
1726
1727#[deprecated(note = "Seq axioms have been verified, and are now lemmas")]
1728pub broadcast proof fn axiom_seq_subrange_index<A>(s: Seq<A>, j: int, k: int, i: int)
1729 requires
1730 0 <= j <= k <= s.len(),
1731 0 <= i < k - j,
1732 ensures
1733 #[trigger] s[j..k][i] == s[i + j],
1734{
1735 lemma_seq_subrange_index(s, j, k, i)
1736}
1737
1738pub broadcast proof fn lemma_seq_subrange_index<A>(s: Seq<A>, j: int, k: int, i: int)
1739 requires
1740 0 <= j <= k <= s.len(),
1741 0 <= i < k - j,
1742 ensures
1743 #[trigger] s[j..k][i] == s[i + j],
1744{
1745 seq_inner::lemma_subrange_index(s.inner, j, k, i);
1746}
1747
1748pub broadcast proof fn lemma_seq_subrange_index_alt<A>(s: Seq<A>, j: int, k: int, i: int)
1750 requires
1751 0 <= j <= k <= s.len(),
1752 0 <= i - j < k - j,
1753 ensures
1754 (#[trigger] s[j..k])[i - j] == #[trigger] s[i],
1755{
1756 broadcast use lemma_seq_subrange_index;
1757
1758}
1759
1760pub broadcast proof fn lemma_seq_two_subranges_index<A>(s: Seq<A>, j: int, k1: int, k2: int, i: int)
1762 requires
1763 0 <= j <= k1 <= s.len(),
1764 0 <= j <= k2 <= s.len(),
1765 0 <= i < k1 - j,
1766 0 <= i < k2 - j,
1767 ensures
1768 #[trigger] s[j..k1][i] == (#[trigger] s[j..k2])[i],
1769{
1770 broadcast use lemma_seq_subrange_index;
1771
1772}
1773
1774#[deprecated(note = "Seq axioms have been verified, and are now lemmas")]
1775pub broadcast proof fn axiom_seq_add_len<A>(s1: Seq<A>, s2: Seq<A>)
1776 ensures
1777 #[trigger] s1.add(s2).len() == s1.len() + s2.len(),
1778{
1779 lemma_seq_add_len(s1, s2)
1780}
1781
1782pub broadcast proof fn lemma_seq_add_len<A>(s1: Seq<A>, s2: Seq<A>)
1783 ensures
1784 #[trigger] s1.add(s2).len() == s1.len() + s2.len(),
1785{
1786 seq_inner::lemma_add_len(s1.inner, s2.inner);
1787}
1788
1789#[deprecated(note = "Seq axioms have been verified, and are now lemmas")]
1790pub broadcast proof fn axiom_seq_add_index1<A>(s1: Seq<A>, s2: Seq<A>, i: int)
1791 requires
1792 i < s1.len(),
1793 ensures
1794 #[trigger] s1.add(s2)[i] == s1[i],
1795{
1796 lemma_seq_add_index1(s1, s2, i)
1797}
1798
1799pub broadcast proof fn lemma_seq_add_index1<A>(s1: Seq<A>, s2: Seq<A>, i: int)
1800 requires
1801 i < s1.len(),
1802 ensures
1803 #[trigger] s1.add(s2)[i] == s1[i],
1804{
1805 seq_inner::lemma_add_index1(s1.inner, s2.inner, i)
1806}
1807
1808#[deprecated(note = "Seq axioms have been verified, and are now lemmas")]
1809pub broadcast proof fn axiom_seq_add_index2<A>(s1: Seq<A>, s2: Seq<A>, i: int)
1810 requires
1811 s1.len() <= i < s1.len() + s2.len(),
1812 ensures
1813 #[trigger] s1.add(s2)[i] == s2[i - s1.len()],
1814{
1815 lemma_seq_add_index2(s1, s2, i)
1816}
1817
1818pub broadcast proof fn lemma_seq_add_index2<A>(s1: Seq<A>, s2: Seq<A>, i: int)
1819 requires
1820 s1.len() <= i < s1.len() + s2.len(),
1821 ensures
1822 #[trigger] s1.add(s2)[i] == s2[i - s1.len()],
1823{
1824 seq_inner::lemma_add_index2(s1.inner, s2.inner, i);
1825}
1826
1827pub broadcast proof fn lemma_seq_add_index1_alt<A>(s1: Seq<A>, s2: Seq<A>, i: int)
1829 requires
1830 0 <= i < s1.len(),
1831 ensures
1832 (#[trigger] s1.add(s2))[i] == #[trigger] s1[i],
1833{
1834 broadcast use lemma_seq_add_index1;
1835
1836}
1837
1838pub broadcast proof fn lemma_seq_add_index2_alt<A>(s1: Seq<A>, s2: Seq<A>, i: int)
1840 requires
1841 0 <= i < s2.len(),
1842 ensures
1843 (#[trigger] s1.add(s2))[i + s1.len()] == #[trigger] s2[i],
1844{
1845 broadcast use lemma_seq_add_index2;
1846
1847}
1848
1849#[deprecated(note = "Use `group_seq_lemmas` instead")]
1850pub broadcast group group_seq_axioms {
1851 lemma_seq_index_decreases,
1852 lemma_seq_subrange_decreases,
1853 lemma_seq_empty,
1854 lemma_seq_new_len,
1855 lemma_seq_new_index,
1856 lemma_seq_push_len,
1857 lemma_seq_push_index_same,
1858 lemma_seq_push_index_different,
1859 lemma_seq_update_len,
1860 lemma_seq_update_same,
1861 lemma_seq_update_different,
1862 lemma_seq_ext_equal,
1863 lemma_seq_ext_equal_deep,
1864 lemma_seq_subrange_len,
1865 lemma_seq_subrange_index,
1866 lemma_seq_two_subranges_index,
1867 lemma_seq_add_len,
1868 lemma_seq_add_index1,
1869 lemma_seq_add_index2,
1870}
1871
1872pub broadcast group group_seq_lemmas {
1873 lemma_seq_index_decreases,
1874 lemma_seq_subrange_decreases,
1875 lemma_seq_empty,
1876 lemma_seq_new_len,
1877 lemma_seq_new_index,
1878 lemma_seq_push_len,
1879 lemma_seq_push_index_same,
1880 lemma_seq_push_index_different,
1881 lemma_seq_update_len,
1882 lemma_seq_update_same,
1883 lemma_seq_update_different,
1884 lemma_seq_ext_equal,
1885 lemma_seq_ext_equal_deep,
1886 lemma_seq_subrange_len,
1887 lemma_seq_subrange_index,
1888 lemma_seq_two_subranges_index,
1889 lemma_seq_add_len,
1890 lemma_seq_add_index1,
1891 lemma_seq_add_index2,
1892}
1893
1894pub broadcast group group_seq_lemmas_expensive {
1896 lemma_seq_push_index_different_alt,
1897 lemma_seq_update_same_alt,
1898 lemma_seq_update_different_alt,
1899 lemma_seq_subrange_index_alt,
1900 lemma_seq_add_index1_alt,
1901 lemma_seq_add_index2_alt,
1902}
1903
1904#[doc(hidden)]
1906#[macro_export]
1907macro_rules! seq_internal {
1908 [] => {
1909 $crate::vstd::seq::Seq::empty()
1910 };
1911 [$elem:expr] => {
1912 $crate::vstd::seq::Seq::empty()
1913 .push($elem)
1914 };
1915 [$elem:expr,] => {
1916 $crate::vstd::seq::Seq::empty()
1917 .push($elem)
1918 };
1919 [$($elem:expr),* $(,)?] => {
1920 <_ as $crate::vstd::view::View>::view(&[$($elem),*])
1921 };
1922 [$elem:expr; $n:expr] => {
1923 $crate::vstd::seq::Seq::new(
1924 $n,
1925 $crate::vstd::prelude::closure_to_fn_spec(
1926 |_x: _| $elem
1927 ),
1928 )
1929 };
1930}
1931
1932#[macro_export]
1945macro_rules! seq {
1946 [$($tail:tt)*] => {
1947 $crate::vstd::prelude::verus_proof_macro_exprs!($crate::vstd::seq::seq_internal!($($tail)*))
1948 };
1949}
1950
1951#[doc(hidden)]
1952pub use seq_internal;
1953pub use seq;
1954
1955}