creusot_contracts/ghost/
resource.rs1pub mod fmap_view;
6
7mod m {
10 #[cfg(creusot)]
11 use crate::logic::such_that;
12
13 #[opaque]
39 pub struct Resource<R>(PhantomData<R>);
40
41 use crate::{
42 logic::{
43 Id, Set,
44 ra::{RA, update::Update},
45 },
46 prelude::*,
47 };
48 use std::marker::PhantomData;
49
50 impl<R: RA> View for Resource<R> {
51 type ViewTy = R;
52 #[logic(open, inline)]
53 fn view(self) -> R {
54 self.val()
55 }
56 }
57
58 #[allow(unused_variables)]
59 impl<R: RA> Resource<R> {
60 #[logic(opaque)]
64 pub fn id(self) -> Id {
65 dead
66 }
67
68 #[check(ghost)]
72 #[trusted]
73 #[ensures(result == self.id())]
74 pub fn id_ghost(&self) -> Id {
75 panic!("ghost code only")
76 }
77
78 #[logic(opaque)]
80 pub fn val(self) -> R {
81 dead
82 }
83
84 #[trusted]
90 #[check(ghost)]
91 #[ensures(result@ == *r)]
92 pub fn alloc(r: Snapshot<R>) -> Ghost<Self> {
93 Ghost::conjure()
94 }
95
96 #[trusted]
104 #[check(ghost)]
105 fn dummy() -> Self {
106 panic!("ghost code only")
107 }
108
109 #[trusted]
111 #[requires(self@.core() != None)]
112 #[ensures(result.id() == self.id())]
113 #[ensures(Some(result@) == self@.core())]
114 #[check(ghost)]
115 pub fn core(&self) -> Self {
116 panic!("ghost code only")
117 }
118
119 #[trusted]
127 #[check(ghost)]
128 #[requires(R::incl_eq_op(*a, *b, self@))]
129 #[ensures(result.0.id() == self.id() && result.1.id() == self.id())]
130 #[ensures(result.0@ == *a)]
131 #[ensures(result.1@ == *b)]
132 pub fn split(self, a: Snapshot<R>, b: Snapshot<R>) -> (Self, Self) {
133 panic!("ghost code only")
134 }
135
136 #[trusted]
138 #[check(ghost)]
139 #[requires(R::incl_eq_op(*a, *b, self@))]
140 #[ensures(result.0.id() == self.id() && result.1.id() == self.id())]
141 #[ensures(result.0@ == *a && result.1@ == *b)]
142 #[ensures((^result.0).id() == self.id() && (^result.1).id() == self.id() ==>
143 (^self).id() == self.id() &&
144 Some((^self)@) == (^result.0)@.op((^result.1)@))]
145 pub fn split_mut(&mut self, a: Snapshot<R>, b: Snapshot<R>) -> (&mut Self, &mut Self) {
146 panic!("ghost code only")
147 }
148
149 #[check(ghost)]
151 #[requires(R::incl_eq_op(*r, *s, self@))]
152 #[ensures((^self).id() == self.id() && result.id() == self.id())]
153 #[ensures((^self)@ == *s)]
154 #[ensures(result@ == *r)]
155 pub fn split_off(&mut self, r: Snapshot<R>, s: Snapshot<R>) -> Self {
156 let this = std::mem::replace(self, Self::dummy());
157 let (r, this) = this.split(r, s);
158 let _ = std::mem::replace(self, this);
159 r
160 }
161
162 #[trusted]
170 #[check(ghost)]
171 #[requires(self.id() == other.id())]
172 #[ensures(result.id() == self.id())]
173 #[ensures(Some(result@) == self@.op(other@))]
174 pub fn join(self, other: Self) -> Self {
175 panic!("ghost code only")
176 }
177
178 #[check(ghost)]
180 #[requires(self.id() == other.id())]
181 #[ensures((^self).id() == self.id())]
182 #[ensures(Some((^self)@) == self@.op(other@))]
183 pub fn join_in(&mut self, other: Self) {
184 let this = std::mem::replace(self, Self::dummy());
185 let this = this.join(other);
186 let _ = std::mem::replace(self, this);
187 }
188
189 #[trusted]
195 #[check(ghost)]
196 #[requires(self.id() == other.id())]
197 #[ensures(result.id() == self.id())]
198 #[ensures(self@.incl_eq(result@) && other@.incl_eq(result@))]
199 pub fn join_shared<'a>(&'a self, other: &'a Self) -> &'a Self {
200 panic!("ghost code only")
201 }
202
203 #[check(ghost)]
205 #[requires(target.incl(self@))]
206 #[ensures((^self).id() == self.id())]
207 #[ensures((^self)@ == *target)]
208 pub fn weaken(&mut self, target: Snapshot<R>) {
209 let f = snapshot! {self@.factor(*target).unwrap_logic()};
210 self.split_off(f, target);
211 }
212
213 #[trusted]
215 #[check(ghost)]
216 #[requires(self.id() == other.id())]
217 #[ensures(^self == *self)]
218 #[ensures(self@.op(other@) != None)]
219 pub fn valid_shared(&mut self, other: &Self) {}
220
221 #[trusted]
223 #[check(ghost)]
224 #[requires(forall<f: Option<R>> Some(self@).op(f) != None ==>
225 exists<x: R> target_s.contains(x) && Some(x).op(f) != None)]
226 #[ensures((^self).id() == self.id())]
227 #[ensures(target_s.contains(*result))]
228 #[ensures((^self)@ == *result)]
229 fn update_raw(&mut self, target_s: Snapshot<Set<R>>) -> Snapshot<R> {
230 panic!("ghost code only")
231 }
232
233 #[check(ghost)]
239 #[requires(upd.premise(self@))]
240 #[ensures((^self).id() == self.id())]
241 #[ensures((^self)@ == upd.update(self@, *result))]
242 pub fn update<U: Update<R>>(&mut self, upd: U) -> Snapshot<U::Choice> {
243 let v = snapshot!(self@);
244 let target_s = snapshot!(Set::from_predicate(|r| exists<ch> upd.update(*v, ch) == r));
245 proof_assert!(target_s.contains(upd.update(*v, such_that(|_| true))));
246 proof_assert!(
247 forall<f: R> v.op(f) != None ==>
248 exists<ch: U::Choice> upd.update(*v, ch).op(f) != None
249 );
250 let _ = snapshot!(U::frame_preserving);
251 let r = self.update_raw(target_s);
252 snapshot!(such_that(|ch| upd.update(*v, ch) == *r))
253 }
254 }
255}
256
257pub use m::*;