creusot_std/ghost/resource/
auth.rs1use super::Resource;
2use crate::{
3 logic::{
4 Id,
5 ra::{
6 UnitRA,
7 auth::{Auth, AuthUpdate, OpLocalUpdate},
8 update::LocalUpdate,
9 },
10 },
11 prelude::*,
12};
13
14pub struct Authority<R: UnitRA>(Resource<Auth<R>>);
22
23pub struct Fragment<R: UnitRA>(pub Resource<Auth<R>>);
27
28impl<R: UnitRA> Invariant for Authority<R> {
29 #[logic]
30 fn invariant(self) -> bool {
31 pearlite! { self.0@.auth() != None }
32 }
33}
34
35impl<R: UnitRA> View for Authority<R> {
36 type ViewTy = R;
37
38 #[logic]
40 fn view(self) -> R {
41 self.0.view().auth().unwrap_logic()
42 }
43}
44
45impl<R: UnitRA> View for Fragment<R> {
46 type ViewTy = R;
47
48 #[logic(open)]
50 fn view(self) -> R {
51 pearlite! { self.0@.frag() }
52 }
53}
54
55impl<R: UnitRA> From<Resource<Auth<R>>> for Fragment<R> {
56 #[check(ghost)]
57 #[ensures(result@ == value@.frag())]
58 fn from(value: Resource<Auth<R>>) -> Self {
59 Fragment(value)
60 }
61}
62
63impl<R: UnitRA> Authority<R> {
64 #[logic]
66 pub fn id(self) -> Id {
67 self.0.id()
68 }
69
70 #[trusted]
74 #[check(ghost)]
75 #[ensures(result == self.id())]
76 pub fn id_ghost(&self) -> Id {
77 self.0.id_ghost()
78 }
79
80 #[check(ghost)]
82 #[ensures(result@ == R::unit())]
83 #[allow(unused_variables)]
84 pub fn alloc() -> Ghost<Self> {
85 ghost!(Self(Resource::alloc(snapshot!(Auth::new_auth(R::unit()))).into_inner()))
86 }
87
88 #[check(ghost)]
90 #[requires(r@.auth() != None)]
91 #[ensures(result.0.id() == r.id() && result.1.id() == r.id())]
92 #[ensures(result.0@ == r@.auth().unwrap_logic())]
93 #[ensures(result.1@ == r@.frag())]
94 pub fn from_resource(mut r: Resource<Auth<R>>) -> (Self, Fragment<R>) {
95 let fragment = snapshot!(Auth::new_frag(r@.frag()));
96 let authority = snapshot!(Auth::new_auth(r@.auth().unwrap_logic()));
97 let frag = r.split_off(fragment, authority);
98 (Self(r), Fragment(frag))
99 }
100
101 #[check(ghost)]
103 #[requires(self.id() == frag.id())]
104 #[requires(upd.premise(self@, frag@))]
105 #[ensures(self.id() == (^self).id())]
106 #[ensures(frag.id() == (^frag).id())]
107 #[ensures(frag@.incl(self@))]
108 #[ensures(((^self)@, (^frag)@) == upd.update(self@, frag@))]
109 #[allow(unused_variables)]
110 pub fn update<U: LocalUpdate<R>>(&mut self, frag: &mut Fragment<R>, upd: U) {
111 let from = snapshot!(Auth::new(Some(self@), frag@));
112 self.0.join_in(frag.0.take());
113 self.0.weaken(from);
115 self.0.update(AuthUpdate(upd));
116 let rs = snapshot!((Auth::new_frag(self.0@.frag()), Auth::new(self.0@.auth(), R::unit())));
117 frag.0 = self.0.split_off(snapshot!(rs.0), snapshot!(rs.1));
118 }
119
120 #[check(ghost)]
124 #[requires(self@.op(*frag) != None)]
125 #[ensures((^self)@ == self@.op(*frag).unwrap_logic())]
126 #[ensures(result@ == *frag)]
127 #[ensures(result.id() == self.id() && (^self).id() == self.id())]
128 #[allow(unused_variables)]
129 pub fn add_fragment(&mut self, frag: Snapshot<R>) -> Fragment<R> {
130 let mut unit: Fragment<R> = Fragment::new_unit(self.id_ghost());
131 self.update(&mut unit, OpLocalUpdate(frag));
132 unit
133 }
134
135 #[check(ghost)]
137 #[requires(self.id() == frag.id())]
138 #[ensures(frag@.incl(self@))]
139 pub fn frag_lemma(&self, frag: &Fragment<R>) {
140 self.0.join_shared(&frag.0);
141 }
142}
143
144impl<R: UnitRA> Fragment<R> {
145 #[logic]
147 pub fn id(self) -> Id {
148 self.0.id()
149 }
150
151 #[trusted]
155 #[check(ghost)]
156 #[ensures(result == self.id())]
157 pub fn id_ghost(&self) -> Id {
158 self.0.id_ghost()
159 }
160
161 #[check(ghost)]
163 #[ensures(result@ == R::unit() && result.id() == id)]
164 pub fn new_unit(id: Id) -> Fragment<R> {
165 Fragment(Resource::new_unit(id))
166 }
167
168 #[check(ghost)]
170 #[ensures(result.id() == self.id())]
171 #[ensures(result@ == self@.core_total())]
172 pub fn core(&self) -> Self {
173 Fragment(self.0.core())
174 }
175
176 #[check(ghost)]
180 #[requires(R::incl_eq_op(*a, *b, self@))]
181 #[ensures(result.0.id() == self.id() && result.1.id() == self.id())]
182 #[ensures(result.0@ == *a)]
183 #[ensures(result.1@ == *b)]
184 #[allow(unused_variables)]
185 pub fn split(self, a: Snapshot<R>, b: Snapshot<R>) -> (Self, Self) {
186 let (r1, r2) = self.0.split(snapshot!(Auth::new_frag(*a)), snapshot!(Auth::new_frag(*b)));
187 (Fragment(r1), Fragment(r2))
188 }
189
190 #[check(ghost)]
192 #[requires(R::incl_eq_op(*r, *s, self@))]
193 #[ensures((^self).id() == self.id() && result.id() == self.id())]
194 #[ensures((^self)@ == *s)]
195 #[ensures(result@ == *r)]
196 #[allow(unused_variables)]
197 pub fn split_off(&mut self, r: Snapshot<R>, s: Snapshot<R>) -> Self {
198 Fragment(self.0.split_off(snapshot!(Auth::new_frag(*r)), snapshot!(Auth::new_frag(*s))))
199 }
200
201 #[check(ghost)]
205 #[requires(self.id() == other.id())]
206 #[ensures(result.id() == self.id())]
207 #[ensures(Some(result@) == self@.op(other@))]
208 pub fn join(self, other: Self) -> Self {
209 Fragment(self.0.join(other.0))
210 }
211
212 #[check(ghost)]
214 #[requires(self.id() == other.id())]
215 #[ensures((^self).id() == self.id())]
216 #[ensures(Some((^self)@) == self@.op(other@))]
217 pub fn join_in(&mut self, other: Self) {
218 self.0.join_in(other.0)
219 }
220
221 #[check(ghost)]
223 #[requires(target.incl(self@))]
224 #[ensures((^self).id() == self.id())]
225 #[ensures((^self)@ == *target)]
226 #[allow(unused_variables)]
227 pub fn weaken(&mut self, target: Snapshot<R>) {
228 self.0.weaken(snapshot! { Auth::new_frag(*target) });
229 }
230
231 #[check(ghost)]
233 #[requires(self.id() == other.id())]
234 #[ensures(^self == *self)]
235 #[ensures(self@.op(other@) != None)]
236 pub fn valid_op_lemma(&mut self, other: &Self) {
237 self.0.valid_op_lemma(&other.0);
238 }
239}