creusot_contracts/ghost/resource/
fmap_view.rs1use super::Resource;
11#[cfg(creusot)]
12use crate::logic::Id;
13use crate::{
14 logic::{
15 FMap,
16 ra::{
17 agree::Ag,
18 auth::{Auth, AuthUpdate},
19 fmap::FMapInsertLocalUpdate,
20 },
21 },
22 prelude::*,
23};
24
25type FMapAuth<K, V> = Resource<Auth<FMap<K, Ag<V>>>>;
27
28pub struct Authority<K, V>(FMapAuth<K, V>);
32
33pub struct Fragment<K, V>(FMapAuth<K, V>, Snapshot<K>, Snapshot<V>);
37
38impl<K, V> Invariant for Authority<K, V> {
39 #[logic]
40 fn invariant(self) -> bool {
41 self.0.view().auth() != None
42 }
43}
44impl<K, V> Invariant for Fragment<K, V> {
45 #[logic]
46 fn invariant(self) -> bool {
47 pearlite! { self.0@.frag().get(*self.1) == Some(Ag(*self.2)) }
48 }
49}
50
51impl<K, V> View for Authority<K, V> {
52 type ViewTy = FMap<K, V>;
53
54 #[logic]
56 fn view(self) -> FMap<K, V> {
57 self.0.view().auth().unwrap_logic().map(|(_, x): (K, Ag<V>)| x.0)
58 }
59}
60impl<K, V> View for Fragment<K, V> {
61 type ViewTy = (K, V);
62
63 #[logic]
65 fn view(self) -> (K, V) {
66 (*self.1, *self.2)
67 }
68}
69
70impl<K, V> Authority<K, V> {
71 #[logic]
73 pub fn id(self) -> Id {
74 self.0.id()
75 }
76
77 #[check(ghost)]
79 #[ensures(result@ == FMap::empty())]
80 pub fn new() -> Ghost<Self> {
81 let r =
82 ghost!(Self(Resource::alloc(snapshot!(Auth::new_auth(FMap::empty()))).into_inner()));
83 proof_assert!(r@.ext_eq(FMap::empty()));
84 r
85 }
86
87 #[requires(!self@.contains(*k))]
90 #[ensures((^self)@ == self@.insert(*k, *v))]
91 #[ensures((^self).id() == self.id())]
92 #[ensures(result@ == (*k, *v))]
93 #[ensures(result.id() == self.id())]
94 #[check(ghost)]
95 #[allow(unused_variables)]
96 pub fn insert(&mut self, k: Snapshot<K>, v: Snapshot<V>) -> Fragment<K, V> {
97 let s = snapshot!(*self);
98 self.0.update(AuthUpdate(FMapInsertLocalUpdate(k, snapshot!(Ag(*v)))));
99 proof_assert!(self@.ext_eq(s@.insert(*k, *v)));
100 Fragment(self.0.core(), k, v)
101 }
102
103 #[requires(self.id() == frag.id())]
105 #[ensures(self@.get(frag@.0) == Some(frag@.1))]
106 #[check(ghost)]
107 #[allow(unused_variables)]
108 pub fn contains(&self, frag: &Fragment<K, V>) {
109 let new_resource = self.0.join_shared(&frag.0);
110 proof_assert!(new_resource@.frag().get(frag@.0) == Some(Ag(frag@.1)));
111 }
112}
113impl<K, V> Fragment<K, V> {
114 #[logic]
116 pub fn id(self) -> Id {
117 self.0.id()
118 }
119}
120
121impl<K, V> Clone for Fragment<K, V> {
122 #[check(ghost)]
123 #[ensures(result@ == self@)]
124 #[ensures(result.id() == self.id())]
125 fn clone(&self) -> Self {
126 Self(self.0.core(), self.1, self.2)
127 }
128}