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 #[check(ghost)]
74 #[ensures(result == self.id())]
75 pub fn id_ghost(&self) -> Id {
76 self.0.id_ghost()
77 }
78
79 #[check(ghost)]
81 #[ensures(result@ == R::unit())]
82 #[allow(unused_variables)]
83 pub fn alloc() -> Ghost<Self> {
84 ghost!(Self(Resource::alloc(snapshot!(Auth::new_auth(R::unit()))).into_inner()))
85 }
86
87 #[check(ghost)]
89 #[requires(r@.auth() != None)]
90 #[ensures(result.0.id() == r.id() && result.1.id() == r.id())]
91 #[ensures(result.0@ == r@.auth().unwrap_logic())]
92 #[ensures(result.1@ == r@.frag())]
93 pub fn from_resource(mut r: Resource<Auth<R>>) -> (Self, Fragment<R>) {
94 let fragment = snapshot!(Auth::new_frag(r@.frag()));
95 let authority = snapshot!(Auth::new_auth(r@.auth().unwrap_logic()));
96 let frag = r.split_off(fragment, authority);
97 (Self(r), Fragment(frag))
98 }
99
100 #[check(ghost)]
117 #[requires(self.id() == frag.id())]
118 #[requires(upd.premise(self@, frag@))]
119 #[ensures(self.id() == (^self).id())]
120 #[ensures(frag.id() == (^frag).id())]
121 #[ensures(frag@.incl(self@))]
122 #[ensures(((^self)@, (^frag)@) == upd.update(self@, frag@))]
123 #[allow(unused_variables)]
124 pub fn update<U: LocalUpdate<R>>(&mut self, frag: &mut Fragment<R>, upd: U) {
125 let from = snapshot!(Auth::new(Some(self@), frag@));
126 self.0.join_in(frag.0.take());
127 self.0.weaken(from);
129 self.0.update(AuthUpdate(upd));
130 let rs = snapshot!((Auth::new_frag(self.0@.frag()), Auth::new(self.0@.auth(), R::unit())));
131 frag.0 = self.0.split_off(snapshot!(rs.0), snapshot!(rs.1));
132 }
133
134 #[check(ghost)]
138 #[requires(self@.op(*frag) != None)]
139 #[ensures((^self)@ == self@.op(*frag).unwrap_logic())]
140 #[ensures(result@ == *frag)]
141 #[ensures(result.id() == self.id() && (^self).id() == self.id())]
142 #[allow(unused_variables)]
143 pub fn add_fragment(&mut self, frag: Snapshot<R>) -> Fragment<R> {
144 let mut unit: Fragment<R> = Fragment::new_unit(self.id_ghost());
145 self.update(&mut unit, OpLocalUpdate(frag));
146 unit
147 }
148
149 #[check(ghost)]
151 #[requires(self.id() == frag.id())]
152 #[ensures(frag@.incl(self@))]
153 pub fn frag_lemma(&self, frag: &Fragment<R>) {
154 self.0.join_shared(&frag.0);
155 }
156}
157
158impl<R: UnitRA> Fragment<R> {
159 #[logic(open)]
161 pub fn id(self) -> Id {
162 self.0.id()
163 }
164
165 #[check(ghost)]
169 #[ensures(result == self.id())]
170 pub fn id_ghost(&self) -> Id {
171 self.0.id_ghost()
172 }
173
174 #[check(ghost)]
176 #[ensures(result@ == R::unit() && result.id() == id)]
177 pub fn new_unit(id: Id) -> Fragment<R> {
178 Fragment(Resource::new_unit(id))
179 }
180
181 #[check(ghost)]
183 #[ensures(result.id() == self.id())]
184 #[ensures(result@ == self@.core_total())]
185 pub fn core(&self) -> Self {
186 Fragment(self.0.core())
187 }
188
189 #[check(ghost)]
193 #[requires(R::incl_eq_op(*a, *b, self@))]
194 #[ensures(result.0.id() == self.id() && result.1.id() == self.id())]
195 #[ensures(result.0@ == *a)]
196 #[ensures(result.1@ == *b)]
197 #[allow(unused_variables)]
198 pub fn split(self, a: Snapshot<R>, b: Snapshot<R>) -> (Self, Self) {
199 let (r1, r2) = self.0.split(snapshot!(Auth::new_frag(*a)), snapshot!(Auth::new_frag(*b)));
200 (Fragment(r1), Fragment(r2))
201 }
202
203 #[check(ghost)]
205 #[requires(R::incl_eq_op(*r, *s, self@))]
206 #[ensures((^self).id() == self.id() && result.id() == self.id())]
207 #[ensures((^self)@ == *s)]
208 #[ensures(result@ == *r)]
209 #[allow(unused_variables)]
210 pub fn split_off(&mut self, r: Snapshot<R>, s: Snapshot<R>) -> Self {
211 Fragment(self.0.split_off(snapshot!(Auth::new_frag(*r)), snapshot!(Auth::new_frag(*s))))
212 }
213
214 #[check(ghost)]
218 #[requires(self.id() == other.id())]
219 #[ensures(result.id() == self.id())]
220 #[ensures(Some(result@) == self@.op(other@))]
221 pub fn join(self, other: Self) -> Self {
222 Fragment(self.0.join(other.0))
223 }
224
225 #[check(ghost)]
227 #[requires(self.id() == other.id())]
228 #[ensures((^self).id() == self.id())]
229 #[ensures(Some((^self)@) == self@.op(other@))]
230 pub fn join_in(&mut self, other: Self) {
231 self.0.join_in(other.0)
232 }
233
234 #[check(ghost)]
236 #[requires(target.incl(self@))]
237 #[ensures((^self).id() == self.id())]
238 #[ensures((^self)@ == *target)]
239 #[allow(unused_variables)]
240 pub fn weaken(&mut self, target: Snapshot<R>) {
241 self.0.weaken(snapshot! { Auth::new_frag(*target) });
242 }
243
244 #[check(ghost)]
246 #[requires(self.id() == other.id())]
247 #[ensures(^self == *self)]
248 #[ensures(self@.op(other@) != None)]
249 pub fn valid_op_lemma(&mut self, other: &Self) {
250 self.0.valid_op_lemma(&other.0);
251 }
252}