creusot_contracts/logic/mapping.rs
1use crate::{logic::ops::IndexLogic, prelude::*};
2use std::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_contracts::{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")]
20pub struct Mapping<A: ?Sized, B>(PhantomData<A>, PhantomData<B>);
21
22impl<A: ?Sized, B> Mapping<A, B> {
23 /// Get the value associated with `a` in the map.
24 #[logic]
25 #[builtin("map.Map.get")]
26 #[allow(unused_variables)]
27 pub fn get(self, a: A) -> B {
28 dead
29 }
30
31 /// Returns a new mapping, where `a` is now mapped to `b`.
32 #[logic]
33 #[builtin("map.Map.set")]
34 #[allow(unused_variables)]
35 pub fn set(self, a: A, b: B) -> Self {
36 dead
37 }
38
39 /// Create a mapping, where every value of type `a` is mapped to `b`.
40 #[logic]
41 #[builtin("map.Const.const")]
42 #[allow(unused_variables)]
43 pub fn cst(b: B) -> Self {
44 dead
45 }
46
47 /// Extensional equality.
48 ///
49 /// Returns `true` if `self` and `other` contain exactly the same key-value pairs.
50 ///
51 /// This is in fact equivalent with normal equality.
52 #[logic]
53 #[builtin("map.MapExt.(==)")]
54 #[allow(unused_variables)]
55 pub fn ext_eq(self, x: Self) -> bool {
56 dead
57 }
58}
59
60impl<A: ?Sized, B> IndexLogic<A> for Mapping<A, B> {
61 type Item = B;
62
63 #[logic(open, inline)]
64 fn index_logic(self, a: A) -> B {
65 self.get(a)
66 }
67}