1#[cfg(creusot)]
2use crate::logic::such_that;
3use crate::{
4 logic::ra::{
5 RA, UnitRA,
6 update::{LocalUpdate, Update},
7 },
8 prelude::*,
9};
10
11impl<T: RA> RA for Option<T> {
12 #[logic(open)]
13 fn op(self, other: Self) -> Option<Self> {
14 match (self, other) {
15 (None, _) => Some(other),
16 (_, None) => Some(self),
17 (Some(x), Some(y)) => x.op(y).map_logic(|z| Some(z)),
18 }
19 }
20
21 #[logic(open)]
22 #[ensures(match result {
23 Some(c) => factor.op(c) == Some(self),
24 None => forall<c: Self> factor.op(c) != Some(self),
25 })]
26 fn factor(self, factor: Self) -> Option<Self> {
27 match (self, factor) {
28 (x, None) => Some(x),
29 (None, _) => None,
30 (Some(x), Some(y)) => match x.factor(y) {
31 Some(z) => Some(Some(z)),
32 None => {
33 if x == y {
34 Some(None)
35 } else {
36 None
37 }
38 }
39 },
40 }
41 }
42
43 #[logic(open, inline)]
44 #[ensures(result == (self == other))]
45 fn eq(self, other: Self) -> bool {
46 match (self, other) {
47 (Some(s), Some(o)) => s.eq(o),
48 (None, None) => true,
49 _ => false,
50 }
51 }
52
53 #[logic(law)]
54 #[ensures(a.op(b) == b.op(a))]
55 fn commutative(a: Self, b: Self) {
56 let _ = <T as RA>::commutative;
57 }
58
59 #[logic]
60 #[ensures(a.op(b).and_then_logic(|ab: Self| ab.op(c)) == b.op(c).and_then_logic(|bc| a.op(bc)))]
61 fn associative(a: Self, b: Self, c: Self) {}
62
63 #[logic(open)]
64 fn core(self) -> Option<Self> {
65 match self {
66 None => Some(None),
67 Some(x) => Some(x.core()),
68 }
69 }
70
71 #[logic]
72 #[requires(self.core() != None)]
73 #[ensures({
74 let c = self.core().unwrap_logic();
75 c.op(c) == Some(c)
76 })]
77 #[ensures(self.core().unwrap_logic().op(self) == Some(self))]
78 fn core_idemp(self) {
79 self.core_total_idemp()
80 }
81
82 #[logic]
83 #[requires(i.op(i) == Some(i))]
84 #[requires(i.op(self) == Some(self))]
85 #[ensures(match self.core() {
86 Some(c) => i.incl(c),
87 None => false,
88 })]
89 fn core_is_maximal_idemp(self, i: Self) {
90 match (self, i) {
91 (Some(x), Some(i)) => x.core_is_maximal_idemp(i),
92 _ => (),
93 }
94 }
95
96 #[logic(open)]
97 #[ensures(result == (forall<x, y> self.op(x) != None ==>
98 self.op(x) == self.op(y) ==> x == y))]
99 fn cancelable(self) -> bool {
100 match self {
101 None => true,
102 Some(this) => {
103 proof_assert! {
104 let _ = T::core_is_maximal_idemp;
105 let _ = T::core_idemp;
106 ((forall<x, y> self.op(x) != None ==> self.op(x) == self.op(y) ==> x == y) ==>
107 self.op(this.core()) == self.op(None)) &&
108 this.cancelable() ==> this.core() == None ==>
109 forall<x, y> self.op(x) != None ==> self.op(x) == self.op(y) ==>
110 match (x, y) {
111 (Some(x), Some(y)) => this.op(x) != None && this.op(x) == this.op(y),
112 (Some(_), None) => false,
113 (None, Some(y)) => y.op(this) == Some(this),
114 (None, None) => true,
115 }
116 };
117 this.cancelable() && this.core() == None
118 }
119 }
120 }
121}
122
123impl<T: RA> UnitRA for Option<T> {
124 #[logic(open)]
125 #[ensures(forall<x: Self> #[trigger(x.op(result))] x.op(result) == Some(x))]
126 fn unit() -> Self {
127 None
128 }
129
130 #[logic(open)]
131 #[ensures(self.core() == Some(result))]
132 fn core_total(self) -> Self {
133 match self {
134 None => None,
135 Some(x) => x.core(),
136 }
137 }
138
139 #[logic]
140 #[ensures(self.core_total().op(self.core_total()) == Some(self.core_total()))]
141 #[ensures(self.core_total().op(self) == Some(self))]
142 fn core_total_idemp(self) {
143 let _ = T::core_idemp;
144 }
145}
146
147pub struct OptionUpdate<U>(pub U);
168
169impl<R: RA, U: Update<R>> Update<Option<R>> for OptionUpdate<U> {
170 type Choice = U::Choice;
171
172 #[logic(open, inline)]
173 fn premise(self, from: Option<R>) -> bool {
174 match from {
175 Some(from) => self.0.premise(from),
176 None => false,
177 }
178 }
179
180 #[logic(open, inline)]
181 #[requires(self.premise(from))]
182 fn update(self, from: Option<R>, ch: U::Choice) -> Option<R> {
183 match from {
184 Some(from) => Some(self.0.update(from, ch)),
185 None => None, }
187 }
188
189 #[logic]
190 #[requires(self.premise(from))]
191 #[requires(from.op(frame) != None)]
192 #[ensures(self.update(from, result).op(frame) != None)]
193 fn frame_preserving(self, from: Option<R>, frame: Option<R>) -> U::Choice {
194 match frame {
195 Some(frame) => self.0.frame_preserving(from.unwrap_logic(), frame),
196 None => such_that(|_| true),
197 }
198 }
199}
200
201pub struct OptionLocalUpdate<U>(pub U);
206
207impl<R: RA, U: LocalUpdate<R>> LocalUpdate<Option<R>> for OptionLocalUpdate<U> {
208 #[logic(open, inline)]
209 fn premise(self, from_auth: Option<R>, from_frag: Option<R>) -> bool {
210 match (from_auth, from_frag) {
211 (Some(from_auth), Some(from_frag)) => self.0.premise(from_auth, from_frag),
212 _ => false,
213 }
214 }
215
216 #[logic(open, inline)]
217 fn update(self, from_auth: Option<R>, from_frag: Option<R>) -> (Option<R>, Option<R>) {
218 match (from_auth, from_frag) {
219 (Some(from_auth), Some(from_frag)) => {
220 let (to_auth, to_frag) = self.0.update(from_auth, from_frag);
221 (Some(to_auth), Some(to_frag))
222 }
223 _ => (None, None), }
225 }
226
227 #[logic]
228 #[requires(self.premise(from_auth, from_frag))]
229 #[requires(Some(from_frag).op(frame) == Some(Some(from_auth)))]
230 #[ensures({
231 let (to_auth, to_frag) = self.update(from_auth, from_frag);
232 Some(to_frag).op(frame) == Some(Some(to_auth))
233 })]
234 fn frame_preserving(
235 self,
236 from_auth: Option<R>,
237 from_frag: Option<R>,
238 frame: Option<Option<R>>,
239 ) {
240 let frame = match frame {
241 None => None,
242 Some(f) => f,
243 };
244 self.0.frame_preserving(from_auth.unwrap_logic(), from_frag.unwrap_logic(), frame)
245 }
246}