1#[cfg(creusot)]
2use crate::logic::such_that;
3use crate::{
4 logic::{Mapping, ord::ord_laws_impl},
5 prelude::*,
6};
7#[cfg(creusot)]
8use std::marker::Destruct;
9use std::{cmp::Ordering, option::*};
10
11impl<T: DeepModel> DeepModel for Option<T> {
12 type DeepModelTy = Option<T::DeepModelTy>;
13
14 #[logic(open, inline)]
15 fn deep_model(self) -> Self::DeepModelTy {
16 match self {
17 Some(t) => Some(t.deep_model()),
18 None => None,
19 }
20 }
21}
22
23extern_spec! {
24 impl<T: PartialEq + DeepModel> PartialEq for Option<T> {
25 #[allow(unstable_name_collisions)]
26 #[ensures(result == (self.deep_model() == rhs.deep_model()))]
27 fn eq(&self, rhs: &Self) -> bool {
28 match (self, rhs) {
29 (None, None) => true,
30 (Some(x), Some(y)) => x == y,
31 _ => false,
32 }
33 }
34 }
35
36 impl<T: Clone> Clone for Option<T> {
37 #[ensures(match (*self, result) {
38 (None, None) => true,
39 (Some(s), Some(r)) => T::clone.postcondition((&s,), r),
40 _ => false
41 })]
42 fn clone(&self) -> Option<T> {
43 match self {
44 None => None,
45 Some(x) => Some(x.clone())
46 }
47 }
48 }
49
50 mod std {
51 mod option {
52 impl<T> Option<T> {
53 #[check(ghost)]
54 #[erasure]
55 #[ensures(result == (*self != None))]
56 fn is_some(&self) -> bool {
57 match *self {
58 Some(_) => true,
59 None => false,
60 }
61 }
62
63 #[erasure]
64 #[requires(match self {
65 None => true,
66 Some(t) => f.precondition((t,)),
67 })]
68 #[ensures(match self {
69 None => result == false,
70 Some(t) => f.postcondition_once((t,), result),
71 })]
72 fn is_some_and(self, f: impl FnOnce(T) -> bool + Destruct) -> bool {
73 match self {
74 None => false,
75 Some(t) => f(t),
76 }
77 }
78
79 #[check(ghost)]
80 #[erasure]
81 #[ensures(result == (*self == None))]
82 fn is_none(&self) -> bool {
83 !self.is_some()
84 }
85
86 #[check(ghost)]
87 #[erasure]
88 #[ensures(*self == None ==> result == None)]
89 #[ensures(
90 *self == None || exists<r: &T> result == Some(r) && *self == Some(*r)
91 )]
92 fn as_ref(&self) -> Option<&T> {
93 match *self {
94 Some(ref t) => Some(t),
95 None => None,
96 }
97 }
98
99 #[check(ghost)]
100 #[erasure]
101 #[ensures(*self == None ==> result == None && ^self == None)]
102 #[ensures(
103 *self == None
104 || exists<r: &mut T> result == Some(r) && *self == Some(*r) && ^self == Some(^r)
105 )]
106 fn as_mut(&mut self) -> Option<&mut T> {
107 match *self {
108 Some(ref mut t) => Some(t),
109 None => None,
110 }
111 }
112
113 #[check(ghost)]
114 #[ensures(match *self {
115 None => result@.len() == 0,
116 Some(t) => result@.len() == 1 && result@[0] == t
117 })]
118 fn as_slice(&self) -> &[T] {
119 match self {
120 None => &[],
121 Some(t) => std::slice::from_ref(t),
122 }
123 }
124
125 #[check(ghost)]
126 #[ensures(match *self {
127 None => result@.len() == 0,
128 Some(_) => exists<b:&mut T>
129 *self == Some(*b) && ^self == Some(^b) &&
130 (*result)@[0] == *b && (^result)@[0] == ^b &&
131 (*result)@.len() == 1 && (^result)@.len() == 1,
132 })]
133 fn as_mut_slice(&mut self) -> &mut [T] {
134 match self {
135 None => &mut [],
136 Some(t) => std::slice::from_mut(t),
137 }
138 }
139
140 #[check(ghost)]
141 #[requires(self != None)]
142 #[ensures(Some(result) == self)]
143 fn expect(self, msg: &str) -> T {
144 match self {
145 None => panic!(),
146 Some(t) => t,
147 }
148 }
149
150 #[check(ghost)]
151 #[requires(self != None)]
152 #[ensures(Some(result) == self)]
153 fn unwrap(self) -> T {
154 match self {
155 None => panic!(),
156 Some(t) => t,
157 }
158 }
159
160 #[check(ghost)]
161 #[erasure]
162 #[ensures(self == None ==> result == default)]
163 #[ensures(self == None || (self == Some(result) && resolve(default)))]
164 fn unwrap_or(self, default: T) -> T {
165 match self {
166 Some(t) => t,
167 None => default,
168 }
169 }
170
171 #[erasure]
172 #[requires(self == None ==> f.precondition(()))]
173 #[ensures(match self {
174 None => f.postcondition_once((), result),
175 Some(t) => result == t
176 })]
177 fn unwrap_or_else<F>(self, f: F) -> T
178 where
179 F: FnOnce() -> T {
180 match self {
181 Some(t) => t,
182 None => f(),
183 }
184 }
185
186 #[erasure]
187 #[ensures(self == None ==> T::default.postcondition((), result))]
188 #[ensures(self == None || self == Some(result))]
189 fn unwrap_or_default(self) -> T
190 where
191 T: Default {
192 match self {
193 Some(t) => t,
194 None => T::default(),
195 }
196 }
197
198 #[check(ghost)]
199 #[requires(self != None)]
200 #[ensures(Some(result) == self)]
201 unsafe fn unwrap_unchecked(self) -> T {
202 match self {
203 None => panic!(),
204 Some(t) => t,
205 }
206 }
207
208 #[erasure]
209 #[requires(match self {
210 None => true,
211 Some(t) => f.precondition((t,)),
212 })]
213 #[ensures(match self {
214 None => result == None,
215 Some(t) => exists<r> result == Some(r) && f.postcondition_once((t,), r),
216 })]
217 fn map<U, F: FnOnce(T) -> U>(self, f: F) -> Option<U> {
218 match self {
219 Some(t) => Some(f(t)),
220 None => None,
221 }
222 }
223
224 #[requires(match self {
225 None => true,
226 Some(t) => f.precondition((&t,)),
227 })]
228 #[ensures(result == self)]
229 #[ensures(match self {
230 None => true,
231 Some(t) => f.postcondition_once((&t,), ()),
232 })]
233 fn inspect<F: FnOnce(&T)>(self, f: F) -> Option<T> {
234 match self {
235 None => None,
236 Some(t) => { f(&t); Some(t) }
237 }
238 }
239
240 #[requires(match self {
241 None => true,
242 Some(t) => f.precondition((t,)),
243 })]
244 #[ensures(match self {
245 None => result == default,
246 Some(t) => f.postcondition_once((t,), result)
247 })]
248 fn map_or<U, F: FnOnce(T) -> U>(self, default: U, f: F) -> U {
249 match self {
250 None => default,
251 Some(t) => f(t),
252 }
253 }
254
255 #[requires(match self {
256 None => default.precondition(()),
257 Some(t) => f.precondition((t,)),
258 })]
259 #[ensures(match self {
260 None => default.postcondition_once((), result),
261 Some(t) => f.postcondition_once((t,), result),
262 })]
263 fn map_or_else<U, D: FnOnce() -> U, F: FnOnce(T) -> U>(self, default: D, f: F) -> U {
264 match self {
265 None => default(),
266 Some(t) => f(t),
267 }
268 }
269
270 #[check(ghost)]
271 #[ensures(match self {
272 None => result == Err(err),
273 Some(t) => result == Ok(t) && resolve(err),
274 })]
275 fn ok_or<E>(self, err: E) -> Result<T, E> {
276 match self {
277 None => Err(err),
278 Some(t) => Ok(t),
279 }
280 }
281
282 #[requires(self == None ==> err.precondition(()))]
283 #[ensures(match self {
284 None => exists<r> result == Err(r) && err.postcondition_once((), r),
285 Some(t) => result == Ok(t),
286 })]
287 fn ok_or_else<E, F: FnOnce() -> E>(self, err: F) -> Result<T, E> {
288 match self {
289 None => Err(err()),
290 Some(t) => Ok(t),
291 }
292 }
293
294 #[check(ghost)]
295 #[ensures(self == None ==> result == None && resolve(optb))]
296 #[ensures(self == None || (result == optb && resolve(self)))]
297 fn and<U>(self, optb: Option<U>) -> Option<U> {
298 match self {
299 None => None,
300 Some(_) => optb,
301 }
302 }
303
304 #[requires(match self {
305 None => true,
306 Some(t) => f.precondition((t,)),
307 })]
308 #[ensures(match self {
309 None => result == None,
310 Some(t) => f.postcondition_once((t,), result),
311 })]
312 fn and_then<U, F: FnOnce(T) -> Option<U>>(self, f: F) -> Option<U> {
313 match self {
314 None => None,
315 Some(t) => f(t),
316 }
317 }
318
319 #[requires(match self {
320 None => true,
321 Some(t) => predicate.precondition((&t,))
322 })]
323 #[ensures(match self {
324 None => result == None,
325 Some(t) => match result {
326 None => predicate.postcondition_once((&t,), false) && resolve(t),
327 Some(r) => predicate.postcondition_once((&t,), true) && r == t,
328 },
329 })]
330 fn filter<P: FnOnce(&T) -> bool>(self, predicate: P) -> Option<T> {
331 match self {
332 None => None,
333 Some(t) => if predicate(&t) { Some(t) } else { None }
334 }
335 }
336
337 #[check(ghost)]
338 #[ensures(self == None ==> result == optb)]
339 #[ensures(self == None || (result == self && resolve(optb)))]
340 fn or(self, optb: Option<T>) -> Option<T> {
341 match self {
342 None => optb,
343 Some(t) => Some(t),
344 }
345 }
346
347 #[requires(self == None ==> f.precondition(()))]
348 #[ensures(match self {
349 None => f.postcondition_once((), result),
350 Some(t) => result == Some(t),
351 })]
352 fn or_else<F: FnOnce() -> Option<T>>(self, f: F) -> Option<T> {
353 match self {
354 None => f(),
355 Some(t) => Some(t),
356 }
357 }
358
359 #[check(ghost)]
360 #[ensures(match (self, optb) {
361 (None, None) => result == None,
362 (Some(t1), Some(t2)) => result == None && resolve(t1) && resolve(t2),
363 (Some(t), None) => result == Some(t),
364 (None, Some(t)) => result == Some(t),
365 })]
366 fn xor(self, optb: Option<T>) -> Option<T> {
367 match (self, optb) {
368 (Some(t), None) | (None, Some(t)) => Some(t),
369 _ => None,
370 }
371 }
372
373 #[check(ghost)]
374 #[ensures(match *self {
375 Some(t) => resolve(t),
376 None => true,
377 })]
378 #[ensures(*result == value && ^self == Some(^result))]
379 fn insert(&mut self, value: T) -> &mut T {
380 *self = Some(value);
381 match self {
382 None => unreachable!(),
383 Some(v) => v,
384 }
385 }
386
387 #[check(ghost)]
388 #[ensures(match *self {
389 None => *result == value && ^self == Some(^result),
390 Some(_) => *self == Some(*result) && ^self == Some(^result) && resolve(value),
391 })]
392 fn get_or_insert(&mut self, value: T) -> &mut T {
393 match self {
394 None => *self = Some(value),
395 Some(_) => {}
396 }
397 match self {
398 None => unreachable!(),
399 Some(v) => v,
400 }
401 }
402
403 #[requires(*self == None ==> f.precondition(()))]
404 #[ensures(match *self {
405 None => f.postcondition_once((), *result) && ^self == Some(^result),
406 Some(_) => *self == Some(*result) && ^self == Some(^result),
407 })]
408 fn get_or_insert_with<F: FnOnce() -> T>(&mut self, f: F) -> &mut T {
409 match self {
410 None => { *self = Some(f()); self.as_mut().unwrap() }
411 Some(t) => t,
412 }
413 }
414
415 #[check(ghost)]
416 #[ensures(result == *self && ^self == None)]
417 fn take(&mut self) -> Option<T> {
418 std::mem::replace(self, None)
419 }
420
421 #[requires(match *self {
422 None => true,
423 Some(t) => forall<b:&mut T> inv(b) && *b == t ==> predicate.precondition((b,)),
424 })]
425 #[ensures(match *self {
426 None => result == None && ^self == None,
427 Some(cur) =>
428 exists<b: &mut T, res: bool> inv(b) && cur == *b && predicate.postcondition_once((b,), res) &&
429 if res {
430 ^self == None && result == Some(^b)
431 } else {
432 ^self == Some(^b) && result == None
433 }
434 })]
435 fn take_if<P: FnOnce(&mut T) -> bool>(&mut self, predicate: P) -> Option<T> {
436 match self {
437 None => None,
438 Some(t) => if predicate(t) { self.take() } else { None },
439 }
440 }
441
442 #[check(ghost)]
443 #[ensures(result == *self && ^self == Some(value))]
444 fn replace(&mut self, value: T) -> Option<T> {
445 std::mem::replace(self, Some(value))
446 }
447
448 #[check(ghost)]
449 #[ensures(match (self, other) {
450 (None, _) => result == None && resolve(other),
451 (_, None) => result == None && resolve(self),
452 (Some(t), Some(u)) => result == Some((t, u)),
453 })]
454 fn zip<U>(self, other: Option<U>) -> Option<(T, U)> {
455 match (self, other) {
456 (Some(t), Some(u)) => Some((t, u)),
457 _ => None,
458 }
459 }
460 }
461
462 impl<T, U> Option<(T, U)> {
463 #[check(ghost)]
464 #[ensures(match self {
465 None => result == (None, None),
466 Some((t, u)) => result == (Some(t), Some(u)),
467 })]
468 fn unzip(self) -> (Option<T>, Option<U>) {
469 match self {
470 Some((t, u)) => (Some(t), Some(u)),
471 None => (None, None),
472 }
473 }
474 }
475
476 impl<T> Option<&T> {
477 #[check(ghost)]
478 #[ensures(match self {
479 None => result == None,
480 Some(s) => result == Some(*s)
481 })]
482 fn copied(self) -> Option<T>
483 where
484 T: Copy
485 {
486 match self {
487 None => None,
488 Some(t) => Some(*t),
489 }
490 }
491
492 #[ensures(match (self, result) {
493 (None, None) => true,
494 (Some(s), Some(r)) =>T::clone.postcondition((s,), r),
495 _ => false
496 })]
497 fn cloned(self) -> Option<T>
498 where
499 T: Clone
500 {
501 match self {
502 None => None,
503 Some(t) => Some(t.clone()),
504 }
505 }
506 }
507
508 impl<T> Option<&mut T> {
509 #[check(ghost)]
510 #[ensures(match self {
511 None => result == None,
512 Some(s) => result == Some(*s) && ^s == *s
513 })]
514 fn copied(self) -> Option<T>
515 where
516 T: Copy
517 {
518 match self {
519 None => None,
520 Some(t) => Some(*t),
521 }
522 }
523
524 #[ensures(match (self, result) {
525 (None, None) => true,
526 (Some(s), Some(r)) => T::clone.postcondition((s,), r) && ^s == *s,
527 _ => false
528 })]
529 fn cloned(self) -> Option<T>
530 where
531 T: Clone
532 {
533 match self {
534 None => None,
535 Some(t) => Some(t.clone()),
536 }
537 }
538 }
539
540 impl<T, E> Option<Result<T, E>> {
541 #[check(ghost)]
542 #[ensures(match self {
543 None => result == Ok(None),
544 Some(Ok(ok)) => result == Ok(Some(ok)),
545 Some(Err(err)) => result == Err(err),
546 })]
547 fn transpose(self) -> Result<Option<T>, E> {
548 match self {
549 None => Ok(None),
550 Some(Ok(ok)) => Ok(Some(ok)),
551 Some(Err(err)) => Err(err),
552 }
553 }
554 }
555
556 impl<T> Option<Option<T>> {
557 #[check(ghost)]
558 #[ensures(self == None ==> result == None)]
559 #[ensures(self == None || self == Some(result))]
560 fn flatten(self) -> Option<T> {
561 match self {
562 None => None,
563 Some(opt) => opt,
564 }
565 }
566 }
567 }
568 }
569
570 impl<T> IntoIterator for Option<T>{
571 #[check(ghost)]
572 #[ensures(self == result@)]
573 fn into_iter(self) -> IntoIter<T>;
574 }
575
576 impl<'a, T> IntoIterator for &'a Option<T>{
577 #[check(ghost)]
578 #[ensures(*self == match result@ { None => None, Some(r) => Some(*r) })]
579 fn into_iter(self) -> Iter<'a, T>;
580 }
581
582 impl<'a, T> IntoIterator for &'a mut Option<T>{
583 #[check(ghost)]
584 #[ensures(*self == match result@ { None => None, Some(r) => Some(*r) })]
585 #[ensures(^self == match result@ { None => None, Some(r) => Some(^r) })]
586 fn into_iter(self) -> IterMut<'a, T>;
587 }
588
589 impl<T> Default for Option<T> {
590 #[check(ghost)]
591 #[ensures(result == None)]
592 fn default() -> Option<T>;
593 }
594}
595
596impl<T: OrdLogic> OrdLogic for Option<T> {
597 #[logic(open)]
598 fn cmp_log(self, o: Self) -> Ordering {
599 match (self, o) {
600 (None, None) => Ordering::Equal,
601 (None, Some(_)) => Ordering::Less,
602 (Some(_), None) => Ordering::Greater,
603 (Some(x), Some(y)) => x.cmp_log(y),
604 }
605 }
606
607 ord_laws_impl! {}
608}
609
610impl<T> View for IntoIter<T> {
611 type ViewTy = Option<T>;
612
613 #[logic(opaque)]
614 fn view(self) -> Option<T> {
615 dead
616 }
617}
618
619impl<T> IteratorSpec for IntoIter<T> {
620 #[logic(open, prophetic)]
621 fn completed(&mut self) -> bool {
622 pearlite! { (*self)@ == None && resolve(self) }
623 }
624
625 #[logic(open)]
626 fn produces(self, visited: Seq<Self::Item>, o: Self) -> bool {
627 pearlite! {
628 visited == Seq::empty() && self == o ||
629 exists<e: Self::Item> self@ == Some(e) && visited == Seq::singleton(e) && o@ == None
630 }
631 }
632
633 #[logic(law)]
634 #[ensures(self.produces(Seq::empty(), self))]
635 fn produces_refl(self) {}
636
637 #[logic(law)]
638 #[requires(a.produces(ab, b))]
639 #[requires(b.produces(bc, c))]
640 #[ensures(a.produces(ab.concat(bc), c))]
641 fn produces_trans(a: Self, ab: Seq<Self::Item>, b: Self, bc: Seq<Self::Item>, c: Self) {}
642}
643
644impl<'a, T> View for Iter<'a, T> {
645 type ViewTy = Option<&'a T>;
646
647 #[logic(opaque)]
648 fn view(self) -> Option<&'a T> {
649 dead
650 }
651}
652
653impl<T> IteratorSpec for Iter<'_, T> {
654 #[logic(open, prophetic)]
655 fn completed(&mut self) -> bool {
656 pearlite! { (*self)@ == None && resolve(self) }
657 }
658
659 #[logic(open)]
660 fn produces(self, visited: Seq<Self::Item>, o: Self) -> bool {
661 pearlite! {
662 visited == Seq::empty() && self == o ||
663 exists<e: Self::Item> self@ == Some(e) && visited == Seq::singleton(e) && o@ == None
664 }
665 }
666
667 #[logic(law)]
668 #[ensures(self.produces(Seq::empty(), self))]
669 fn produces_refl(self) {}
670
671 #[logic(law)]
672 #[requires(a.produces(ab, b))]
673 #[requires(b.produces(bc, c))]
674 #[ensures(a.produces(ab.concat(bc), c))]
675 fn produces_trans(a: Self, ab: Seq<Self::Item>, b: Self, bc: Seq<Self::Item>, c: Self) {}
676}
677
678impl<'a, T> View for IterMut<'a, T> {
679 type ViewTy = Option<&'a mut T>;
680
681 #[logic(opaque)]
682 fn view(self) -> Option<&'a mut T> {
683 dead
684 }
685}
686
687impl<T> IteratorSpec for IterMut<'_, T> {
688 #[logic(open, prophetic)]
689 fn completed(&mut self) -> bool {
690 pearlite! { (*self)@ == None && resolve(self) }
691 }
692
693 #[logic(open)]
694 fn produces(self, visited: Seq<Self::Item>, o: Self) -> bool {
695 pearlite! {
696 visited == Seq::empty() && self == o ||
697 exists<e: Self::Item> self@ == Some(e) && visited == Seq::singleton(e) && o@ == None
698 }
699 }
700
701 #[logic(law)]
702 #[ensures(self.produces(Seq::empty(), self))]
703 fn produces_refl(self) {}
704
705 #[logic(law)]
706 #[requires(a.produces(ab, b))]
707 #[requires(b.produces(bc, c))]
708 #[ensures(a.produces(ab.concat(bc), c))]
709 fn produces_trans(a: Self, ab: Seq<Self::Item>, b: Self, bc: Seq<Self::Item>, c: Self) {}
710}
711
712pub trait OptionExt<T> {
713 #[logic]
715 #[requires(false)]
716 fn unwrap_logic(self) -> T;
717
718 #[logic]
720 fn and_then_logic<U>(self, f: Mapping<T, Option<U>>) -> Option<U>;
721
722 #[logic]
724 fn map_logic<U>(self, f: Mapping<T, U>) -> Option<U>;
725}
726
727impl<T> OptionExt<T> for Option<T> {
728 #[logic(open)]
729 #[requires(self != None)]
730 fn unwrap_logic(self) -> T {
731 match self {
732 Some(x) => x,
733 None => such_that(|_| true),
734 }
735 }
736
737 #[logic(open)]
738 fn and_then_logic<U>(self, f: Mapping<T, Option<U>>) -> Option<U> {
739 match self {
740 None => None,
741 Some(x) => f.get(x),
742 }
743 }
744
745 #[logic(open)]
746 fn map_logic<U>(self, f: Mapping<T, U>) -> Option<U> {
747 match self {
748 None => None,
749 Some(x) => Some(f.get(x)),
750 }
751 }
752}