1use super::super::prelude::*;
2use super::algebra::ResourceAlgebra;
3use super::pcm::PCM;
4use super::relations::*;
5
6verus! {
7
8impl<RA: ResourceAlgebra> ResourceAlgebra for Option<RA> {
9 open spec fn valid(self) -> bool {
11 match self {
12 Some(v) => v.valid(),
13 None => true,
14 }
15 }
16
17 open spec fn op(a: Self, b: Self) -> Self {
19 match (a, b) {
20 (Some(a), Some(b)) => Some(RA::op(a, b)),
21 (None, _) => b,
22 (_, None) => a,
23 }
24 }
25
26 proof fn associative(a: Self, b: Self, c: Self) {
28 match (a, b, c) {
29 (Some(a), Some(b), Some(c)) => RA::associative(a, b, c),
30 (_, _, _) => {},
31 }
32 }
33
34 proof fn commutative(a: Self, b: Self) {
36 match (a, b) {
37 (Some(a), Some(b)) => RA::commutative(a, b),
38 (_, _) => {},
39 }
40 }
41
42 proof fn valid_op(a: Self, b: Self) {
45 match (a, b) {
46 (Some(a), Some(b)) => RA::valid_op(a, b),
47 (_, _) => {},
48 }
49 }
50}
51
52impl<RA: ResourceAlgebra> PCM for Option<RA> {
53 open spec fn unit() -> Self {
54 None
55 }
56
57 proof fn op_unit(self) {
60 }
61
62 proof fn unit_valid() {
64 }
65}
66
67pub proof fn lemma_incl_opt<RA: ResourceAlgebra>(a: RA, b: RA)
68 requires
69 incl::<RA>(a, b),
70 ensures
71 incl::<Option<RA>>(Some(a), Some(b)),
72{
73 let c = choose|x| RA::op(a, x) == b;
74 assert(Option::<RA>::op(Some(a), Some(c)) == Some(b));
75}
76
77pub proof fn lemma_incl_opt_rev<RA: ResourceAlgebra>(a: RA, b: RA)
78 requires
79 incl::<Option<RA>>(Some(a), Some(b)),
80 ensures
81 incl::<RA>(a, b) || a == b,
82{
83 let c = choose|x| Option::<RA>::op(Some(a), x) == Some(b);
84 if c is None {
85 Some(a).op_unit();
86 }
87}
88
89pub proof fn lemma_set_op_opt<RA: ResourceAlgebra>(s: Set<RA>, t: RA)
90 ensures
91 set_op(s, t).map(|b| Some(b)) == set_op(s.map(|x| Some(x)), Some(t)),
92{
93 broadcast use super::super::set::group_set_axioms;
94
95 let s_mapped = s.map(|x| Some(x));
96 let original = set_op(s, t);
97 let map_after = original.map(|b| Some(b));
98 let map_before = set_op(s_mapped, Some(t));
99
100 assert forall|v| map_after.contains(v) implies map_before.contains(v) by {
101 let q = choose|q| #[trigger] s.contains(q) && v->Some_0 == RA::op(q, t);
102 assert(s_mapped.contains(Some(q)));
103 }
104
105 assert forall|v| map_before.contains(v) implies map_after.contains(v) by {
106 let q = choose|q| #[trigger] s_mapped.contains(q) && v == Option::<RA>::op(q, Some(t));
107 assert(original.contains(v->Some_0));
108 }
109}
110
111}