creusot_std/logic/ra/
auth.rs1use core::marker::PhantomData;
2
3#[cfg(creusot)]
4use crate::logic::any;
5use crate::{
6 logic::ra::{
7 RA, UnitRA,
8 update::{LocalUpdate, Update},
9 view::{View, ViewRel},
10 },
11 prelude::*,
12};
13
14pub type Auth<T> = View<AuthViewRel<T>>;
24
25pub struct AuthViewRel<T>(PhantomData<T>);
27
28impl<T: UnitRA> ViewRel for AuthViewRel<T> {
29 type Auth = T;
30 type Frag = T;
31
32 #[logic(open)]
33 fn rel(a: Option<T>, f: T) -> bool {
34 match a {
35 Some(a) => f.incl(a),
36 None => true,
37 }
38 }
39
40 #[logic(law)]
41 #[requires(Self::rel(a, f1))]
42 #[requires(f2.incl(f1))]
43 #[ensures(Self::rel(a, f2))]
44 fn rel_mono(a: Option<T>, f1: T, f2: T) {}
45
46 #[logic(law)]
47 #[ensures(Self::rel(None, f))]
48 fn rel_none(a: Option<T>, f: T) {}
49
50 #[logic(law)]
51 #[ensures(Self::rel(a, T::unit()))]
52 fn rel_unit(a: Option<T>) {}
53}
54
55pub struct AuthUpdate<U>(pub U);
58
59impl<R: UnitRA, U: LocalUpdate<R>> Update<Auth<R>> for AuthUpdate<U> {
60 type Choice = ();
61
62 #[logic(open, inline)]
63 fn premise(self, from: Auth<R>) -> bool {
64 match from.auth() {
65 Some(auth) => self.0.premise(auth, from.frag()),
66 None => false,
67 }
68 }
69
70 #[logic]
71 #[requires(self.premise(from))]
72 #[ensures(result.auth() == Some(self.0.update(from.auth().unwrap_logic(), from.frag()).0))]
73 #[ensures(result.frag() == self.0.update(from.auth().unwrap_logic(), from.frag()).1)]
74 fn update(self, from: Auth<R>, _: ()) -> Auth<R> {
75 let from_auth = from.auth().unwrap_logic();
76 let (auth, frag) = self.0.update(from_auth, from.frag());
77 self.0.frame_preserving(from_auth, from.frag(), Some(from_auth.factor(from.frag())));
78 Auth::new(Some(auth), frag)
79 }
80
81 #[logic]
82 #[requires(self.premise(from))]
83 #[requires(from.op(frame) != None)]
84 #[ensures(self.update(from, result).op(frame) != None)]
85 fn frame_preserving(self, from: Auth<R>, frame: Auth<R>) {
86 let auth = from.auth().unwrap_logic();
87 let x = from.op(frame).unwrap_logic().frag();
88 let y = auth.factor(x);
89 let f = frame.frag().op(y).unwrap_logic();
90 self.0.frame_preserving(auth, from.frag(), Some(f));
91 }
92}
93
94pub struct OpLocalUpdate<R>(pub Snapshot<R>);
98
99impl<R: UnitRA> LocalUpdate<R> for OpLocalUpdate<R> {
100 #[logic(open)]
101 fn premise(self, from_auth: R, _: R) -> bool {
102 from_auth.op(*self.0) != None
103 }
104
105 #[logic(open)]
106 fn update(self, from_auth: R, from_frag: R) -> (R, R) {
107 (from_auth.op(*self.0).unwrap_logic(), from_frag.op(*self.0).unwrap_logic())
108 }
109
110 #[logic]
111 #[requires(self.premise(from_auth, from_frag))]
112 #[requires(Some(from_frag).op(frame) == Some(Some(from_auth)))]
113 #[ensures({
114 let (to_auth, to_frag) = self.update(from_auth, from_frag);
115 Some(to_frag).op(frame) == Some(Some(to_auth))
116 })]
117 fn frame_preserving(self, from_auth: R, from_frag: R, frame: Option<R>) {}
118}
119
120pub struct CancelLocalUpdateUnit;
124
125impl<R: UnitRA> LocalUpdate<R> for CancelLocalUpdateUnit {
126 #[logic(open)]
127 fn premise(self, _: R, from_frag: R) -> bool {
128 from_frag.cancelable()
129 }
130
131 #[logic]
132 #[ensures(result.1 == R::unit())]
133 #[ensures(from_frag.incl(from_auth) ==> result.0.op(from_frag) == Some(from_auth))]
134 fn update(self, from_auth: R, from_frag: R) -> (R, R) {
135 let f = if from_frag.incl(from_auth) { from_auth.factor(from_frag) } else { any() };
136 (f, R::unit())
137 }
138
139 #[logic]
140 #[requires(self.premise(from_auth, from_frag))]
141 #[requires(Some(from_frag).op(frame) == Some(Some(from_auth)))]
142 #[ensures({
143 let (to_auth, to_frag) = self.update(from_auth, from_frag);
144 Some(to_frag).op(frame) == Some(Some(to_auth))
145 })]
146 fn frame_preserving(self, from_auth: R, from_frag: R, frame: Option<R>) {}
147}