1use crate::{
2 logic::ra::{
3 RA, UnitRA,
4 update::{LocalUpdate, Update},
5 },
6 prelude::*,
7};
8
9impl<T: RA, U: RA> RA for (T, U) {
12 #[logic(open)]
13 fn op(self, other: Self) -> Option<Self> {
14 match (self.0.op(other.0), self.1.op(other.1)) {
15 (Some(r1), Some(r2)) => Some((r1, r2)),
16 _ => None,
17 }
18 }
19
20 #[logic(open)]
21 #[ensures(match result {
22 Some(c) => factor.op(c) == Some(self),
23 None => forall<c: Self> factor.op(c) != Some(self),
24 })]
25 fn factor(self, factor: Self) -> Option<Self> {
26 match (self.0.factor(factor.0), self.1.factor(factor.1)) {
27 (Some(x), Some(y)) => Some((x, y)),
28 _ => None,
29 }
30 }
31
32 #[logic(open, inline)]
33 #[ensures(result == (self == other))]
34 fn eq(self, other: Self) -> bool {
35 self.0.eq(other.0) && self.1.eq(other.1)
36 }
37
38 #[logic(law)]
39 #[ensures(a.op(b) == b.op(a))]
40 fn commutative(a: Self, b: Self) {}
41
42 #[logic]
43 #[ensures(a.op(b).and_then_logic(|ab: Self| ab.op(c)) == b.op(c).and_then_logic(|bc| a.op(bc)))]
44 fn associative(a: Self, b: Self, c: Self) {}
45
46 #[logic(open)]
47 fn core(self) -> Option<Self> {
48 match (self.0.core(), self.1.core()) {
49 (Some(x), Some(y)) => Some((x, y)),
50 _ => None,
51 }
52 }
53
54 #[logic]
55 #[requires(self.core() != None)]
56 #[ensures({
57 let c = self.core().unwrap_logic();
58 c.op(c) == Some(c)
59 })]
60 #[ensures(self.core().unwrap_logic().op(self) == Some(self))]
61 fn core_idemp(self) {
62 self.0.core_idemp();
63 self.1.core_idemp();
64 }
65
66 #[logic]
67 #[requires(i.op(i) == Some(i))]
68 #[requires(i.op(self) == Some(self))]
69 #[ensures(match self.core() {
70 Some(c) => i.incl(c),
71 None => false,
72 })]
73 fn core_is_maximal_idemp(self, i: Self) {
74 self.0.core_is_maximal_idemp(i.0);
75 self.1.core_is_maximal_idemp(i.1);
76 }
77}
78
79impl<T: UnitRA, U: UnitRA> UnitRA for (T, U) {
80 #[logic]
81 #[ensures(forall<x: Self> #[trigger(x.op(result))] x.op(result) == Some(x))]
82 fn unit() -> Self {
83 (T::unit(), U::unit())
84 }
85
86 #[logic(open)]
87 #[ensures(self.core() == Some(result))]
88 fn core_total(self) -> Self {
89 (self.0.core_total(), self.1.core_total())
90 }
91
92 #[logic]
93 #[ensures(self.core_total().op(self.core_total()) == Some(self.core_total()))]
94 #[ensures(self.core_total().op(self) == Some(self))]
95 fn core_total_idemp(self) {
96 self.0.core_total_idemp();
97 self.1.core_total_idemp();
98 }
99}
100
101impl<R1: RA, R2: RA, U1: Update<R1>, U2: Update<R2>> Update<(R1, R2)> for (U1, U2) {
102 type Choice = (U1::Choice, U2::Choice);
103
104 #[logic(open, inline)]
105 fn premise(self, from: (R1, R2)) -> bool {
106 self.0.premise(from.0) && self.1.premise(from.1)
107 }
108
109 #[logic(open, inline)]
110 #[requires(self.premise(from))]
111 fn update(self, from: (R1, R2), ch: (U1::Choice, U2::Choice)) -> (R1, R2) {
112 (self.0.update(from.0, ch.0), self.1.update(from.1, ch.1))
113 }
114
115 #[logic]
116 #[requires(self.premise(from))]
117 #[requires(from.op(frame) != None)]
118 #[ensures(self.update(from, result).op(frame) != None)]
119 fn frame_preserving(self, from: (R1, R2), frame: (R1, R2)) -> Self::Choice {
120 (self.0.frame_preserving(from.0, frame.0), self.1.frame_preserving(from.1, frame.1))
121 }
122}
123
124impl<R1: RA, R2: RA, U1: LocalUpdate<R1>, U2: LocalUpdate<R2>> LocalUpdate<(R1, R2)> for (U1, U2) {
125 #[logic(open, inline)]
126 fn premise(self, from_auth: (R1, R2), from_frag: (R1, R2)) -> bool {
127 self.0.premise(from_auth.0, from_frag.0) && self.1.premise(from_auth.1, from_frag.1)
128 }
129
130 #[logic(open, inline)]
131 fn update(self, from_auth: (R1, R2), from_frag: (R1, R2)) -> ((R1, R2), (R1, R2)) {
132 let (to_auth0, to_frag0) = self.0.update(from_auth.0, from_frag.0);
133 let (to_auth1, to_frag1) = self.1.update(from_auth.1, from_frag.1);
134 ((to_auth0, to_auth1), (to_frag0, to_frag1))
135 }
136
137 #[logic]
138 #[requires(self.premise(from_auth, from_frag))]
139 #[requires(Some(from_frag).op(frame) == Some(Some(from_auth)))]
140 #[ensures({
141 let (to_auth, to_frag) = self.update(from_auth, from_frag);
142 Some(to_frag).op(frame) == Some(Some(to_auth))
143 })]
144 fn frame_preserving(self, from_auth: (R1, R2), from_frag: (R1, R2), frame: Option<(R1, R2)>) {
145 self.0.frame_preserving(from_auth.0, from_frag.0, frame.map_logic(|f: (R1, R2)| f.0));
146 self.1.frame_preserving(from_auth.1, from_frag.1, frame.map_logic(|f: (R1, R2)| f.1));
147 }
148}