1#[cfg(creusot)]
2use crate::logic::such_that;
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(match result {
25 Some(c) => factor.op(c) == Some(self),
26 None => forall<c: Self> factor.op(c) != Some(self),
27 })]
28 fn factor(self, factor: Self) -> Option<Self> {
29 pearlite! {
30 if (forall<k: K> factor.get(k).incl(self.get(k))) {
31 let res = self.filter_map(|(k, vo): (K, V)|
32 match Some(vo).factor(factor.get(k)) {
33 Some(r) => r,
34 None => None,
35 });
36 proof_assert!(
37 match factor.op(res) {
38 None => false,
39 Some(o) => o.ext_eq(self)
40 }
41 );
42 Some(res)
43 } else {
44 None
45 }
46 }
47 }
48
49 #[logic(open, inline)]
50 #[ensures(result == (self == other))]
51 fn eq(self, other: Self) -> bool {
52 pearlite! {
53 let _ = Self::ext_eq;
54 forall<k: K> self.get(k).eq(other.get(k))
55 }
56 }
57
58 #[logic(law)]
59 #[ensures(a.op(b) == b.op(a))]
60 fn commutative(a: Self, b: Self) {
61 proof_assert!(match (a.op(b), b.op(a)) {
62 (Some(ab), Some(ba)) => ab.ext_eq(ba),
63 (None, None) => true,
64 _ => false,
65 })
66 }
67
68 #[logic]
69 #[ensures(a.op(b).and_then_logic(|ab: Self| ab.op(c)) == b.op(c).and_then_logic(|bc| a.op(bc)))]
70 fn associative(a: Self, b: Self, c: Self) {
71 match (a.op(b), b.op(c)) {
72 (Some(ab), Some(bc)) => match (ab.op(c), a.op(bc)) {
73 (Some(x), Some(y)) => proof_assert!(x.ext_eq(y)),
74 _ => (),
75 },
76 _ => (),
77 }
78 }
79
80 #[logic(open)]
81 fn core(self) -> Option<Self> {
82 Some(self.filter_map(|(_, v): (K, V)| v.core()))
83 }
84
85 #[logic]
86 #[requires(self.core() != None)]
87 #[ensures({
88 let c = self.core().unwrap_logic();
89 c.op(c) == Some(c)
90 })]
91 #[ensures(self.core().unwrap_logic().op(self) == Some(self))]
92 fn core_idemp(self) {
93 self.core_total_idemp()
94 }
95
96 #[logic]
97 #[requires(i.op(i) == Some(i))]
98 #[requires(i.op(self) == Some(self))]
99 #[ensures(match self.core() {
100 Some(c) => i.incl(c),
101 None => false,
102 })]
103 fn core_is_maximal_idemp(self, i: Self) {
104 let _ = V::core_is_maximal_idemp;
105 }
106
107 #[logic(open)]
108 #[ensures(result == (forall<x, y> self.op(x) != None ==>
109 self.op(x) == self.op(y) ==> x == y))]
110 fn cancelable(self) -> bool {
111 proof_assert!(
112 (forall<x, y> self.op(x) != None ==> self.op(x) == self.op(y) ==> x == y) ==>
113 forall<k> match self.get(k) {
114 None => true,
115 Some(v) => forall<x, y> Some(v).op(x) != None ==> Some(v).op(x) == Some(v).op(y) ==> {
116 let fx = match x {
117 None => FMap::empty(),
118 Some(x) => FMap::singleton(k, x),
119 };
120 let fy = match y {
121 None => FMap::empty(),
122 Some(y) => FMap::singleton(k, y),
123 };
124 let opx = self.op(fx).unwrap_logic();
125 let opy = self.op(fy).unwrap_logic();
126 opx.ext_eq(opy) && (opx == opy ==> fx == fy)
127 }
128 }
129 );
130 proof_assert!((forall<k> self.get(k).cancelable()) ==>
131 forall<x, y> self.op(x) != None ==> self.op(x) == self.op(y) ==>
132 x.ext_eq(y)
133 );
134 pearlite! { forall<k> self.get(k).cancelable() }
135 }
136}
137
138impl<K, V: RA> UnitRA for FMap<K, V> {
139 #[logic(open)]
140 #[ensures(forall<x: Self> #[trigger(x.op(result))] x.op(result) == Some(x))]
141 fn unit() -> Self {
142 proof_assert!(forall<x: Self> x.op(Self::empty()).unwrap_logic().ext_eq(x));
143 Self::empty()
144 }
145
146 #[logic(open)]
147 #[ensures(self.core() == Some(result))]
148 fn core_total(self) -> Self {
149 self.filter_map(|(_, v): (K, V)| v.core())
150 }
151
152 #[logic]
153 #[ensures(self.core_total().op(self.core_total()) == Some(self.core_total()))]
154 #[ensures(self.core_total().op(self) == Some(self))]
155 fn core_total_idemp(self) {
156 let _ = V::core_idemp;
157 let c = self.core_total();
158 proof_assert!(c.op(c).unwrap_logic().ext_eq(c));
159 proof_assert!(c.op(self).unwrap_logic().ext_eq(self));
160 }
161}
162
163impl<K, V: RA> FMap<K, V> {
164 #[logic]
165 #[requires(forall<k: K> self.get(k).op(other.get(k)) != None)]
166 #[ensures(forall<k: K> Some(result.get(k)) == self.get(k).op(other.get(k)))]
167 pub fn total_op(self, other: Self) -> Self {
168 self.merge(other, |(x, y): (V, V)| match x.op(y) {
169 Some(r) => r,
170 _ => such_that(|_| true),
171 })
172 }
173}
174
175pub struct FMapInsertLocalUpdate<K, V>(pub Snapshot<K>, pub Snapshot<V>);
179
180impl<K, V: RA> LocalUpdate<FMap<K, V>> for FMapInsertLocalUpdate<K, V> {
181 #[logic(open, inline)]
182 fn premise(self, from_auth: FMap<K, V>, _: FMap<K, V>) -> bool {
183 from_auth.get(*self.0) == None
184 }
185
186 #[logic(open, inline)]
187 fn update(self, from_auth: FMap<K, V>, from_frag: FMap<K, V>) -> (FMap<K, V>, FMap<K, V>) {
188 (from_auth.insert(*self.0, *self.1), from_frag.insert(*self.0, *self.1))
189 }
190
191 #[logic]
192 #[allow(unused)]
193 #[requires(self.premise(from_auth, from_frag))]
194 #[requires(Some(from_frag).op(frame) == Some(Some(from_auth)))]
195 #[ensures({
196 let (to_auth, to_frag) = self.update(from_auth, from_frag);
197 Some(to_frag).op(frame) == Some(Some(to_auth))
198 })]
199 fn frame_preserving(
200 self,
201 from_auth: FMap<K, V>,
202 from_frag: FMap<K, V>,
203 frame: Option<FMap<K, V>>,
204 ) {
205 let (to_auth, to_frag) = self.update(from_auth, from_frag);
206 proof_assert!(match Some(to_frag).op(frame) {
207 Some(Some(x)) => to_auth.ext_eq(x),
208 _ => false,
209 });
210 }
211}