Skip to main content

creusot_std/logic/
mapping.rs

1use crate::{logic::ops::IndexLogic, prelude::*};
2use core::marker::PhantomData;
3
4/// A mapping: map every value of type `A` to a value of type `B`.
5///
6/// # Pearlite syntax
7///
8/// Mappings have special support in pearlite code: you may write a closure to create a
9/// mapping.
10///
11/// ## Example
12///
13/// ```
14/// # use creusot_std::{logic::Mapping, prelude::*};
15/// let value = snapshot!(4);
16/// let map: Snapshot<Mapping<Int, Int>> = snapshot!(|n| if n % 2 == 0 { 0 } else { *value });
17/// proof_assert!(map.get(1) == 4);
18/// ```
19#[builtin("map.Map.map")]
20#[trusted(positive(B))]
21pub struct Mapping<A: ?Sized, B>(PhantomData<fn(&A) -> B>);
22
23impl<A: ?Sized, B> Mapping<A, B> {
24    /// Get the value associated with `a` in the map.
25    #[logic]
26    #[builtin("map.Map.get")]
27    #[allow(unused_variables)]
28    pub fn get(self, a: A) -> B {
29        dead
30    }
31
32    /// Returns a new mapping, where `a` is now mapped to `b`.
33    #[logic]
34    #[builtin("map.Map.set")]
35    #[allow(unused_variables)]
36    pub fn set(self, a: A, b: B) -> Self {
37        dead
38    }
39
40    /// Create a mapping, where every value of type `a` is mapped to `b`.
41    #[logic]
42    #[builtin("map.Const.const")]
43    #[allow(unused_variables)]
44    pub fn cst(b: B) -> Self {
45        dead
46    }
47
48    /// Extensional equality.
49    ///
50    /// Returns `true` if `self` and `other` contain exactly the same key-value pairs.
51    ///
52    /// This is in fact equivalent with normal equality.
53    #[logic]
54    #[builtin("map.MapExt.(==)")]
55    #[allow(unused_variables)]
56    pub fn ext_eq(self, x: Self) -> bool {
57        dead
58    }
59}
60
61impl<A: ?Sized, B> IndexLogic<A> for Mapping<A, B> {
62    type Item = B;
63
64    #[logic(open, inline)]
65    fn index_logic(self, a: A) -> B {
66        self.get(a)
67    }
68}