1use crate::{
2 logic::ra::{
3 RA, UnitRA,
4 update::{LocalUpdate, Update},
5 },
6 prelude::*,
7};
8
9macro_rules! ra_tuples {
10 ($(($t:ident, $n:tt, $v:ident, $r:ident))*) => {
11
12impl<$($t : RA),*> RA for ($($t),*) {
13 #[logic(open)]
14 fn op(self, other: Self) -> Option<Self> {
15 match ($(self.$n.op(other.$n)),*) {
16 ($(Some($v)),*) => Some(($($v),*)),
17 _ => None,
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.$n.factor(factor.$n)),*) {
28 ($(Some($v)),*) => Some(($($v),*)),
29 _ => None,
30 }
31 }
32
33 #[logic(open, inline)]
34 #[ensures(#[trigger(self == other)] result == (self == other))]
35 fn eq(self, other: Self) -> bool {
36 $(self.$n.eq(other.$n))&&*
37 }
38
39 #[logic(law)]
40 #[ensures(a.op(b) == b.op(a))]
41 fn commutative(a: Self, b: Self) {}
42
43 #[logic]
44 #[ensures(a.op(b).and_then_logic(|ab: Self| ab.op(c)) == b.op(c).and_then_logic(|bc| a.op(bc)))]
45 fn associative(a: Self, b: Self, c: Self) {}
46
47 #[logic(open)]
48 fn core(self) -> Option<Self> {
49 match ($(self.$n.core()),*) {
50 ($(Some($v)),*) => Some(($($v),*)),
51 _ => None,
52 }
53 }
54
55 #[logic]
56 #[requires(self.core() != None)]
57 #[ensures({
58 let c = self.core().unwrap_logic();
59 c.op(c) == Some(c)
60 })]
61 #[ensures(self.core().unwrap_logic().op(self) == Some(self))]
62 fn core_idemp(self) {
63 $(
64 self.$n.core_idemp();
65 )*
66 }
67
68 #[logic]
69 #[requires(i.op(i) == Some(i))]
70 #[requires(i.op(self) == Some(self))]
71 #[ensures(match self.core() {
72 Some(c) => i.incl(c),
73 None => false,
74 })]
75 fn core_is_maximal_idemp(self, i: Self) {
76 $(
77 self.$n.core_is_maximal_idemp(i.$n);
78 )*
79 }
80
81 ra_tuples! { @cancelation $(($n, $v))* }
82}
83
84impl<$($t : UnitRA),*> UnitRA for ($($t),*) {
85 #[logic]
86 #[ensures(forall<x: Self> #[trigger(x.op(result))] x.op(result) == Some(x))]
87 fn unit() -> Self {
88 ($($t::unit()),*)
89 }
90
91 #[logic(open)]
92 #[ensures(self.core() == Some(result))]
93 fn core_total(self) -> Self {
94 ($(self.$n.core_total()),*)
95 }
96
97 #[logic]
98 #[ensures(self.core_total().op(self.core_total()) == Some(self.core_total()))]
99 #[ensures(self.core_total().op(self) == Some(self))]
100 fn core_total_idemp(self) {
101 $(
102 self.$n.core_total_idemp();
103 )*
104 }
105}
106
107impl<$($r : RA),* , $($t : Update<$r>),*> Update<($($r),*)> for ($($t),*) {
108 type Choice = ($($t::Choice),*);
109
110 #[logic(open, inline)]
111 fn premise(self, from: ($($r),*)) -> bool {
112 $(
113 self.$n.premise(from.$n)
114 )&&*
115 }
116
117 #[logic(open, inline)]
118 #[requires(self.premise(from))]
119 fn update(self, from: ($($r),*), ch: Self::Choice) -> ($($r),*) {
120 ($(self.$n.update(from.$n, ch.$n)),*)
121 }
122
123 #[logic]
124 #[requires(self.premise(from))]
125 #[requires(from.op(frame) != None)]
126 #[ensures(self.update(from, result).op(frame) != None)]
127 fn frame_preserving(self, from: ($($r),*), frame: ($($r),*)) -> Self::Choice {
128 ( $(
129 self.$n.frame_preserving(from.$n, frame.$n)
130 ),* )
131 }
132}
133
134impl<$($r : RA),* , $($t : LocalUpdate<$r>),*> LocalUpdate<($($r),*)> for ($($t),*) {
135 #[logic(open, inline)]
136 fn premise(self, from_auth: ($($r),*), from_frag: ($($r),*)) -> bool {
137 $(
138 self.$n.premise(from_auth.$n, from_frag.$n)
139 )&&*
140 }
141
142 #[logic(open, inline)]
143 fn update(self, from_auth: ($($r),*), from_frag: ($($r),*)) -> (($($r),*), ($($r),*)) {
144 $(
145 let $v = self.$n.update(from_auth.$n, from_frag.$n);
146 )*
147 (($($v.0),*), ($($v.1),*))
148 }
149
150 ra_tuples! { @local_upd_frame_preserve
151 type_r: $($r)* ;
152 list: $(($n, $v))* ;
153 with_type_r: ;
154 }
155
156}
157
158 };
159
160 (@local_upd_frame_preserve
162 type_r: $($r:ident)* ;
163 list: ($n1:tt, $v1:ident) $(($n_t:tt, $v_t:tt))* ;
164 with_type_r: $(($n:tt, $v:ident, $t:ty))* ;
165 ) => {
166 ra_tuples! { @local_upd_frame_preserve
167 type_r: $($r)* ;
168 list: $(($n_t, $v_t))* ;
169 with_type_r: $(($n, $v, $t))* ($n1, $v1, ($($r),*)) ;
170 }
171 };
172
173 (@local_upd_frame_preserve
174 type_r: $($r:ident)* ;
175 list: ;
176 with_type_r: $(($n:tt, $v:ident, $t:ty))* ;
177 ) => {
178 #[logic]
179 #[requires(self.premise(from_auth, from_frag))]
180 #[requires(Some(from_frag).op(frame) == Some(Some(from_auth)))]
181 #[ensures({
182 let (to_auth, to_frag) = self.update(from_auth, from_frag);
183 Some(to_frag).op(frame) == Some(Some(to_auth))
184 })]
185 fn frame_preserving(self, from_auth: ($($r),*), from_frag: ($($r),*), frame: Option<($($r),*)>) {
186 $(
187 self.$n.frame_preserving(from_auth.$n, from_frag.$n, frame.map_logic(|f: $t| f.$n));
188 )*
189 }
190 };
191
192
193 (@cancelation ($n1:tt, $v1:ident) $(($n:tt, $v:ident))*) => {
195 #[logic(open)]
196 #[ensures(result == (forall<x, y> self.op(x) != None ==>
197 self.op(x) == self.op(y) ==> x == y))]
198 fn cancelable(self) -> bool {
199 proof_assert!(
200 forall<$v1, $($v),*> self.0.op($v1) != None ==> $(self.$n.op($v) != None ==>)*
202 (forall<x, y> self.op(x) != None ==> self.op(y) != None ==> self.op(x) == self.op(y) ==> x == y) ==>
204 forall<x, y> self.0.op(x) != None ==> self.0.op(y) != None ==>
206 self.op((x, $($v),*)) == self.op((y, $($v),*)) ==> x == y
207 );
208 pearlite! {
209 (forall<$v1> self.0.op($v1) == None) ||
210 $(
211 (forall<$v> self.$n.op($v) == None) ||
212 )*
213 ( self.$n1.cancelable() && $(self.$n.cancelable())&&* )
214 }
215 }
216 };
217}
218
219ra_tuples! { (T1, 0, v1, R1) (T2, 1, v2, R2) }
220ra_tuples! { (T1, 0, v1, R1) (T2, 1, v2, R2) (T3, 2, v3, R3) }
221ra_tuples! { (T1, 0, v1, R1) (T2, 1, v2, R2) (T3, 2, v3, R3) (T4, 3, v4, R4) }
222