1#[cfg(creusot)]
2use crate::logic::any;
3use crate::{
4 logic::{
5 FMap,
6 ra::{RA, UnitRA, update::LocalUpdate},
7 },
8 prelude::*,
9};
10
11impl<K, V: RA> RA for FMap<K, V> {
12 #[logic(open)]
13 fn op(self, other: Self) -> Option<Self> {
14 pearlite! {
15 if (forall<k: K> self.get(k).op(other.get(k)) != None) {
16 Some(self.total_op(other))
17 } else {
18 None
19 }
20 }
21 }
22
23 #[logic(open)]
24 #[ensures(result == (exists<factor> self.op(factor) == Some(other)))]
25 fn incl(self, other: Self) -> bool {
26 pearlite! {
27 let r = forall<k: K> self.get(k).incl(other.get(k));
28
29 proof_assert!(r ==> {
30 let factor = other.filter_map(|(k, vo): (K, V)|
31 if self.get(k).incl(Some(vo)) {
32 Some(vo).factor(self.get(k))
33 } else { None }
34 );
35
36 match self.op(factor) {
37 None => false,
38 Some(o) => o.ext_eq(other)
39 }
40 });
41
42 r
43 }
44 }
45
46 #[logic(open, inline)]
47 #[ensures(#[trigger(self == other)] result == (self == other))]
48 fn eq(self, other: Self) -> bool {
49 pearlite! {
50 let _ = Self::ext_eq;
51 forall<k: K> self.get(k).eq(other.get(k))
52 }
53 }
54
55 #[logic(law)]
56 #[ensures(a.op(b) == b.op(a))]
57 fn commutative(a: Self, b: Self) {
58 proof_assert!(match (a.op(b), b.op(a)) {
59 (Some(ab), Some(ba)) => ab.ext_eq(ba),
60 (None, None) => true,
61 _ => false,
62 })
63 }
64
65 #[logic]
66 #[ensures(a.op(b).and_then_logic(|ab: Self| ab.op(c)) == b.op(c).and_then_logic(|bc| a.op(bc)))]
67 fn associative(a: Self, b: Self, c: Self) {
68 match (a.op(b), b.op(c)) {
69 (Some(ab), Some(bc)) => match (ab.op(c), a.op(bc)) {
70 (Some(x), Some(y)) => proof_assert!(x.ext_eq(y)),
71 _ => (),
72 },
73 _ => (),
74 }
75 }
76
77 #[logic(open)]
78 fn core(self) -> Option<Self> {
79 Some(self.filter_map(|(_, v): (K, V)| v.core()))
80 }
81
82 #[logic]
83 #[requires(self.core() != None)]
84 #[ensures({
85 let c = self.core().unwrap_logic();
86 c.op(c) == Some(c)
87 })]
88 #[ensures(self.core().unwrap_logic().op(self) == Some(self))]
89 fn core_idemp(self) {
90 self.core_total_idemp()
91 }
92
93 #[logic]
94 #[requires(i.op(i) == Some(i))]
95 #[requires(i.op(self) == Some(self))]
96 #[ensures(match self.core() {
97 Some(c) => i.incl(c),
98 None => false,
99 })]
100 fn core_is_maximal_idemp(self, i: Self) {
101 let _ = V::core_is_maximal_idemp;
102 }
103
104 #[logic(open)]
105 #[ensures(result == (forall<x, y> self.op(x) != None ==>
106 self.op(x) == self.op(y) ==> x == y))]
107 fn cancelable(self) -> bool {
108 proof_assert!(
109 (forall<x, y> self.op(x) != None ==> self.op(x) == self.op(y) ==> x == y) ==>
110 forall<k> match self.get(k) {
111 None => true,
112 Some(v) => forall<x, y> Some(v).op(x) != None ==> Some(v).op(x) == Some(v).op(y) ==> {
113 let fx = match x {
114 None => FMap::empty(),
115 Some(x) => FMap::singleton(k, x),
116 };
117 let fy = match y {
118 None => FMap::empty(),
119 Some(y) => FMap::singleton(k, y),
120 };
121 let opx = self.op(fx).unwrap_logic();
122 let opy = self.op(fy).unwrap_logic();
123 opx.ext_eq(opy) && (opx == opy ==> fx == fy)
124 }
125 }
126 );
127 proof_assert!((forall<k> self.get(k).cancelable()) ==>
128 forall<x, y> self.op(x) != None ==> self.op(x) == self.op(y) ==>
129 x.ext_eq(y)
130 );
131 pearlite! { forall<k> self.get(k).cancelable() }
132 }
133}
134
135impl<K, V: RA> UnitRA for FMap<K, V> {
136 #[logic(open)]
137 #[ensures(forall<x: Self> #[trigger(x.op(result))] x.op(result) == Some(x))]
138 fn unit() -> Self {
139 proof_assert!(forall<x: Self> x.op(Self::empty()).unwrap_logic().ext_eq(x));
140 Self::empty()
141 }
142
143 #[logic(open)]
144 #[ensures(self.core() == Some(result))]
145 fn core_total(self) -> Self {
146 self.filter_map(|(_, v): (K, V)| v.core())
147 }
148
149 #[logic]
150 #[ensures(self.core_total().op(self.core_total()) == Some(self.core_total()))]
151 #[ensures(self.core_total().op(self) == Some(self))]
152 fn core_total_idemp(self) {
153 let _ = V::core_idemp;
154 let c = self.core_total();
155 proof_assert!(c.op(c).unwrap_logic().ext_eq(c));
156 proof_assert!(c.op(self).unwrap_logic().ext_eq(self));
157 }
158}
159
160impl<K, V: RA> FMap<K, V> {
161 #[logic]
162 #[requires(forall<k: K> self.get(k).op(other.get(k)) != None)]
163 #[ensures(forall<k: K> Some(result.get(k)) == self.get(k).op(other.get(k)))]
164 pub fn total_op(self, other: Self) -> Self {
165 self.merge(other, |(x, y): (V, V)| match x.op(y) {
166 Some(r) => r,
167 _ => any(),
168 })
169 }
170}
171
172pub struct FMapInsertLocalUpdate<K, V>(pub Snapshot<K>, pub Snapshot<V>);
176
177impl<K, V: RA> LocalUpdate<FMap<K, V>> for FMapInsertLocalUpdate<K, V> {
178 #[logic(open, inline)]
179 fn premise(self, from_auth: FMap<K, V>, _: FMap<K, V>) -> bool {
180 from_auth.get(*self.0) == None
181 }
182
183 #[logic(open, inline)]
184 fn update(self, from_auth: FMap<K, V>, from_frag: FMap<K, V>) -> (FMap<K, V>, FMap<K, V>) {
185 (from_auth.insert(*self.0, *self.1), from_frag.insert(*self.0, *self.1))
186 }
187
188 #[logic]
189 #[allow(unused)]
190 #[requires(self.premise(from_auth, from_frag))]
191 #[requires(Some(from_frag).op(frame) == Some(Some(from_auth)))]
192 #[ensures({
193 let (to_auth, to_frag) = self.update(from_auth, from_frag);
194 Some(to_frag).op(frame) == Some(Some(to_auth))
195 })]
196 fn frame_preserving(
197 self,
198 from_auth: FMap<K, V>,
199 from_frag: FMap<K, V>,
200 frame: Option<FMap<K, V>>,
201 ) {
202 let (to_auth, to_frag) = self.update(from_auth, from_frag);
203 proof_assert!(match Some(to_frag).op(frame) {
204 Some(Some(x)) => to_auth.ext_eq(x),
205 _ => false,
206 });
207 }
208}
209
210pub struct FMapKeyLocalUpdate<K, U>(pub Snapshot<K>, pub U);
214
215impl<K, V: RA, U: LocalUpdate<V>> LocalUpdate<FMap<K, V>> for FMapKeyLocalUpdate<K, U> {
216 #[logic(open, inline)]
217 fn premise(self, from_auth: FMap<K, V>, from_frag: FMap<K, V>) -> bool {
218 pearlite! {
219 match (from_auth.get(*self.0), from_frag.get(*self.0)) {
220 (Some(auth_v), Some(frag_v)) => self.1.premise(auth_v, frag_v),
221 (_, None) => false,
222 _ => true,
223 }
224 }
225 }
226
227 #[logic(open, inline)]
228 fn update(self, from_auth: FMap<K, V>, from_frag: FMap<K, V>) -> (FMap<K, V>, FMap<K, V>) {
229 let (auth, frag) = self.1.update(from_auth[*self.0], from_frag[*self.0]);
230 (from_auth.insert(*self.0, auth), from_frag.insert(*self.0, frag))
231 }
232
233 #[logic]
234 #[allow(unused)]
235 #[requires(self.premise(from_auth, from_frag))]
236 #[requires(Some(from_frag).op(frame) == Some(Some(from_auth)))]
237 #[ensures({
238 let (to_auth, to_frag) = self.update(from_auth, from_frag);
239 Some(to_frag).op(frame) == Some(Some(to_auth))
240 })]
241 fn frame_preserving(
242 self,
243 from_auth: FMap<K, V>,
244 from_frag: FMap<K, V>,
245 frame: Option<FMap<K, V>>,
246 ) {
247 match (from_auth.get(*self.0), from_frag.get(*self.0)) {
248 (Some(auth_v), Some(frag_v)) => {
249 let frame_k = match frame {
250 Some(frame) => frame.get(*self.0),
251 None => None,
252 };
253 self.1.frame_preserving(auth_v, frag_v, frame_k);
254
255 let (to_auth, to_frag) = self.update(from_auth, from_frag);
256 proof_assert!(match Some(to_frag).op(frame) {
257 Some(Some(x)) => to_auth.ext_eq(x),
258 _ => false,
259 });
260 }
261 _ => (),
262 }
263 }
264}