1use super::super::map::*;
77use super::super::map_lib::*;
78use super::super::modes::*;
79use super::super::pcm::*;
80use super::super::prelude::*;
81use super::super::set_lib::*;
82
83verus! {
84
85broadcast use super::super::group_vstd_default;
86
87#[verifier::reject_recursive_types(K)]
88#[verifier::ext_equal]
89enum AuthCarrier<K, V> {
90 Auth(Map<K, V>),
91 Frac,
92 Invalid,
93}
94
95#[verifier::reject_recursive_types(K)]
96#[verifier::ext_equal]
97enum FracCarrier<K, V> {
98 Frac { owning: Map<K, V>, dup: Map<K, V> },
99 Invalid,
100}
101
102impl<K, V> AuthCarrier<K, V> {
103 spec fn valid(self) -> bool {
104 !(self is Invalid)
105 }
106
107 spec fn map(self) -> Map<K, V>
108 recommends
109 self.valid(),
110 {
111 match self {
112 AuthCarrier::Auth(m) => m,
113 AuthCarrier::Frac => Map::empty(),
114 AuthCarrier::Invalid => Map::empty(),
115 }
116 }
117}
118
119impl<K, V> FracCarrier<K, V> {
120 spec fn valid(self) -> bool {
121 match self {
122 FracCarrier::Invalid => false,
123 FracCarrier::Frac { owning, dup } => owning.dom().disjoint(dup.dom()),
124 }
125 }
126
127 spec fn owning_map(self) -> Map<K, V> {
128 match self {
129 FracCarrier::Frac { owning, .. } => owning,
130 FracCarrier::Invalid => Map::empty(),
131 }
132 }
133
134 spec fn dup_map(self) -> Map<K, V> {
135 match self {
136 FracCarrier::Frac { dup, .. } => dup,
137 FracCarrier::Invalid => Map::empty(),
138 }
139 }
140}
141
142#[verifier::reject_recursive_types(K)]
143#[verifier::ext_equal]
144struct MapCarrier<K, V> {
146 auth: AuthCarrier<K, V>,
147 frac: FracCarrier<K, V>,
148}
149
150impl<K, V> PCM for MapCarrier<K, V> {
151 closed spec fn valid(self) -> bool {
152 match (self.auth, self.frac) {
153 (AuthCarrier::Invalid, _) => false,
154 (_, FracCarrier::Invalid) => false,
155 (AuthCarrier::Auth(auth), FracCarrier::Frac { owning, dup }) => {
156 &&& owning <= auth
157 &&& dup <= auth
158 &&& owning.dom().disjoint(dup.dom())
159 },
160 (AuthCarrier::Frac, FracCarrier::Frac { owning, dup }) => owning.dom().disjoint(
161 dup.dom(),
162 ),
163 }
164 }
165
166 closed spec fn op(self, other: Self) -> Self {
167 let auth = match (self.auth, other.auth) {
168 (AuthCarrier::Invalid, _) => AuthCarrier::Invalid,
170 (_, AuthCarrier::Invalid) => AuthCarrier::Invalid,
171 (AuthCarrier::Auth(_), AuthCarrier::Auth(_)) => AuthCarrier::Invalid,
173 (AuthCarrier::Frac, AuthCarrier::Frac) => AuthCarrier::Frac,
175 (AuthCarrier::Auth(_), _) => self.auth,
177 (_, AuthCarrier::Auth(_)) => other.auth,
178 };
179
180 let frac = match (self.frac, other.frac) {
181 (FracCarrier::Invalid, _) => FracCarrier::Invalid,
183 (_, FracCarrier::Invalid) => FracCarrier::Invalid,
184 (
190 FracCarrier::Frac { owning: self_owning, dup: self_dup },
191 FracCarrier::Frac { owning: other_owning, dup: other_dup },
192 ) => {
193 let non_overlapping = {
194 &&& self_owning.dom().disjoint(other_dup.dom())
195 &&& other_owning.dom().disjoint(self_dup.dom())
196 &&& self_owning.dom().disjoint(other_owning.dom())
197 };
198 let aggreement = self_dup.agrees(other_dup);
199 if non_overlapping && aggreement {
200 FracCarrier::Frac {
201 owning: self_owning.union_prefer_right(other_owning),
202 dup: self_dup.union_prefer_right(other_dup),
203 }
204 } else {
205 FracCarrier::Invalid
206 }
207 },
208 };
209
210 MapCarrier { auth, frac }
211 }
212
213 closed spec fn unit() -> Self {
214 MapCarrier {
215 auth: AuthCarrier::Frac,
216 frac: FracCarrier::Frac { owning: Map::empty(), dup: Map::empty() },
217 }
218 }
219
220 proof fn closed_under_incl(a: Self, b: Self) {
221 broadcast use lemma_submap_of_trans;
222
223 let ab = MapCarrier::op(a, b);
224 lemma_submap_of_op_frac(a, b);
225 if !a.frac.owning_map().dom().disjoint(a.frac.dup_map().dom()) {
227 lemma_disjoint_iff_empty_intersection(
229 a.frac.owning_map().dom(),
230 a.frac.dup_map().dom(),
231 );
232 let a_k = choose|k: K|
233 a.frac.owning_map().dom().intersect(a.frac.dup_map().dom()).contains(k);
234 assert(ab.frac.owning_map().dom().intersect(ab.frac.dup_map().dom()).contains(a_k)); };
236 }
237
238 proof fn commutative(a: Self, b: Self) {
239 let ab = Self::op(a, b);
240 let ba = Self::op(b, a);
241 assert(ab == ba);
242 }
243
244 proof fn associative(a: Self, b: Self, c: Self) {
245 let bc = Self::op(b, c);
246 let ab = Self::op(a, b);
247 let a_bc = Self::op(a, bc);
248 let ab_c = Self::op(ab, c);
249 assert(a_bc == ab_c);
250 }
251
252 proof fn op_unit(a: Self) {
253 let x = Self::op(a, Self::unit());
254 assert(a == x);
255 }
256
257 proof fn unit_valid() {
258 }
259}
260
261proof fn lemma_submap_of_op_frac<K, V>(a: MapCarrier<K, V>, b: MapCarrier<K, V>)
262 requires
263 MapCarrier::op(a, b).valid(),
264 ensures
265 a.frac.owning_map() <= MapCarrier::op(a, b).frac.owning_map(),
266 a.frac.dup_map() <= MapCarrier::op(a, b).frac.dup_map(),
267 b.frac.owning_map() <= MapCarrier::op(a, b).frac.owning_map(),
268 b.frac.dup_map() <= MapCarrier::op(a, b).frac.dup_map(),
269{
270 let ab = MapCarrier::op(a, b);
271 assert(ab.frac.owning_map() == a.frac.owning_map().union_prefer_right(b.frac.owning_map()));
272 assert(ab.frac.dup_map() == a.frac.dup_map().union_prefer_right(b.frac.dup_map()));
273 assert(a.frac.owning_map().dom().disjoint(b.frac.owning_map().dom()));
274}
275
276broadcast proof fn lemma_submap_of_op<K, V>(a: MapCarrier<K, V>, b: MapCarrier<K, V>)
277 requires
278 #[trigger] MapCarrier::op(a, b).valid(),
279 ensures
280 a.frac.owning_map() <= MapCarrier::op(a, b).frac.owning_map(),
281 a.frac.dup_map() <= MapCarrier::op(a, b).frac.dup_map(),
282 a.auth.map() <= MapCarrier::op(a, b).auth.map(),
283 b.frac.owning_map() <= MapCarrier::op(a, b).frac.owning_map(),
284 b.frac.dup_map() <= MapCarrier::op(a, b).frac.dup_map(),
285 b.auth.map() <= MapCarrier::op(a, b).auth.map(),
286 a.valid(),
287 b.valid(),
288{
289 lemma_submap_of_op_frac(a, b);
290 MapCarrier::closed_under_incl(a, b);
291 MapCarrier::commutative(a, b);
292 MapCarrier::closed_under_incl(b, a);
293 let ab = MapCarrier::op(a, b);
294 assert(ab.auth.map() == a.auth.map().union_prefer_right(b.auth.map()));
295}
296
297#[verifier::reject_recursive_types(K)]
299pub struct GhostMapAuth<K, V> {
300 r: Resource<MapCarrier<K, V>>,
301}
302
303#[verifier::reject_recursive_types(K)]
310pub struct GhostSubmap<K, V> {
311 r: Resource<MapCarrier<K, V>>,
312}
313
314#[verifier::reject_recursive_types(K)]
320pub struct GhostPersistentSubmap<K, V> {
321 r: Resource<MapCarrier<K, V>>,
322}
323
324#[verifier::reject_recursive_types(K)]
331pub struct GhostPointsTo<K, V> {
332 submap: GhostSubmap<K, V>,
333}
334
335#[verifier::reject_recursive_types(K)]
341pub struct GhostPersistentPointsTo<K, V> {
342 submap: GhostPersistentSubmap<K, V>,
343}
344
345impl<K, V> GhostMapAuth<K, V> {
346 #[verifier::type_invariant]
347 spec fn inv(self) -> bool {
348 &&& self.r.value().auth is Auth
349 &&& self.r.value().frac == FracCarrier::Frac {
350 owning: Map::<K, V>::empty(),
351 dup: Map::<K, V>::empty(),
352 }
353 }
354
355 pub closed spec fn id(self) -> Loc {
357 self.r.loc()
358 }
359
360 pub closed spec fn view(self) -> Map<K, V> {
362 self.r.value().auth.map()
363 }
364
365 pub open spec fn dom(self) -> Set<K> {
367 self@.dom()
368 }
369
370 pub open spec fn spec_index(self, key: K) -> V
372 recommends
373 self.dom().contains(key),
374 {
375 self@[key]
376 }
377
378 pub proof fn dummy() -> (tracked result: GhostMapAuth<K, V>) {
380 let tracked (auth, submap) = GhostMapAuth::<K, V>::new(Map::empty());
381 auth
382 }
383
384 pub proof fn take(tracked &mut self) -> (tracked result: GhostMapAuth<K, V>)
386 ensures
387 result == *old(self),
388 {
389 use_type_invariant(&*self);
390 let tracked mut r = Self::dummy();
391 tracked_swap(self, &mut r);
392 r
393 }
394
395 pub proof fn empty(tracked &self) -> (tracked result: GhostSubmap<K, V>)
397 ensures
398 result.id() == self.id(),
399 result@ == Map::<K, V>::empty(),
400 {
401 use_type_invariant(self);
402 GhostSubmap::<K, V>::empty(self.id())
403 }
404
405 pub proof fn insert_map(tracked &mut self, m: Map<K, V>) -> (tracked result: GhostSubmap<K, V>)
420 requires
421 old(self)@.dom().disjoint(m.dom()),
422 ensures
423 self.id() == old(self).id(),
424 self@ == old(self)@.union_prefer_right(m),
425 result.id() == self.id(),
426 result@ == m,
427 {
428 broadcast use lemma_submap_of_trans;
429 broadcast use lemma_submap_of_op;
430
431 let tracked mut mself = Self::dummy();
432 tracked_swap(self, &mut mself);
433
434 use_type_invariant(&mself);
435 assert(mself.inv());
436 let tracked mut self_r = mself.r;
437
438 let full_carrier = MapCarrier {
439 auth: AuthCarrier::Auth(self_r.value().auth.map().union_prefer_right(m)),
440 frac: FracCarrier::Frac { owning: m, dup: Map::empty() },
441 };
442
443 assert(full_carrier.valid());
444 let tracked updated_r = self_r.update(full_carrier);
445
446 let auth_carrier = MapCarrier {
447 auth: updated_r.value().auth,
448 frac: FracCarrier::Frac { owning: Map::empty(), dup: Map::empty() },
449 };
450 let frac_carrier = MapCarrier { auth: AuthCarrier::Frac, frac: updated_r.value().frac };
451
452 assert(updated_r.value() == MapCarrier::op(auth_carrier, frac_carrier));
453 let tracked (auth_r, frac_r) = updated_r.split(auth_carrier, frac_carrier);
454 self.r = auth_r;
455 GhostSubmap { r: frac_r }
456 }
457
458 pub proof fn insert(tracked &mut self, k: K, v: V) -> (tracked result: GhostPointsTo<K, V>)
471 requires
472 !old(self)@.contains_key(k),
473 ensures
474 self.id() == old(self).id(),
475 self@ == old(self)@.insert(k, v),
476 result.id() == self.id(),
477 result@ == (k, v),
478 {
479 let tracked submap = self.insert_map(map![k => v]);
480 GhostPointsTo { submap }
481 }
482
483 pub proof fn delete(tracked &mut self, tracked submap: GhostSubmap<K, V>)
498 requires
499 submap.id() == old(self).id(),
500 ensures
501 self.id() == old(self).id(),
502 self@ == old(self)@.remove_keys(submap@.dom()),
503 {
504 broadcast use lemma_submap_of_trans;
505 broadcast use lemma_submap_of_op;
506
507 use_type_invariant(&*self);
508 use_type_invariant(&submap);
509
510 let tracked mut mself = Self::dummy();
511 tracked_swap(self, &mut mself);
512 let tracked mut self_r = mself.r;
513
514 self_r = self_r.join(submap.r);
516
517 let auth_map = self_r.value().auth.map();
519 let new_auth_map = auth_map.remove_keys(submap@.dom());
520
521 let new_r = MapCarrier {
522 auth: AuthCarrier::Auth(new_auth_map),
523 frac: FracCarrier::Frac { owning: Map::empty(), dup: Map::empty() },
524 };
525
526 self.r = self_r.update(new_r);
528 }
529
530 pub proof fn delete_points_to(tracked &mut self, tracked p: GhostPointsTo<K, V>)
544 requires
545 p.id() == old(self).id(),
546 ensures
547 self.id() == old(self).id(),
548 self@ == old(self)@.remove(p.key()),
549 {
550 use_type_invariant(&p);
551 p.lemma_map_view();
552 self.delete(p.submap);
553 }
554
555 pub proof fn new(m: Map<K, V>) -> (tracked result: (GhostMapAuth<K, V>, GhostSubmap<K, V>))
567 ensures
568 result.0.id() == result.1.id(),
569 result.0@ == m,
570 result.1@ == m,
571 {
572 let tracked full_r = Resource::alloc(
573 MapCarrier {
574 auth: AuthCarrier::Auth(m),
575 frac: FracCarrier::Frac { owning: m, dup: Map::empty() },
576 },
577 );
578
579 let auth_carrier = MapCarrier {
580 auth: AuthCarrier::Auth(m),
581 frac: FracCarrier::Frac { owning: Map::empty(), dup: Map::empty() },
582 };
583
584 let frac_carrier = MapCarrier {
585 auth: AuthCarrier::Frac,
586 frac: FracCarrier::Frac { owning: m, dup: Map::empty() },
587 };
588
589 assert(full_r.value() == MapCarrier::op(auth_carrier, frac_carrier));
590 let tracked (auth_r, frac_r) = full_r.split(auth_carrier, frac_carrier);
591 (GhostMapAuth { r: auth_r }, GhostSubmap { r: frac_r })
592 }
593}
594
595impl<K, V> GhostSubmap<K, V> {
596 #[verifier::type_invariant]
597 spec fn inv(self) -> bool {
598 &&& self.r.value().auth is Frac
599 &&& self.r.value().frac is Frac
600 &&& self.r.value().frac.dup_map().is_empty()
601 }
602
603 pub open spec fn is_points_to(self) -> bool {
606 &&& self@.len() == 1
607 &&& self.dom().finite()
608 &&& !self@.is_empty()
609 }
610
611 pub closed spec fn id(self) -> Loc {
613 self.r.loc()
614 }
615
616 pub closed spec fn view(self) -> Map<K, V> {
618 self.r.value().frac.owning_map()
619 }
620
621 pub open spec fn dom(self) -> Set<K> {
623 self@.dom()
624 }
625
626 pub open spec fn spec_index(self, key: K) -> V
628 recommends
629 self.dom().contains(key),
630 {
631 self@[key]
632 }
633
634 pub proof fn dummy() -> (tracked result: GhostSubmap<K, V>) {
636 let tracked (auth, submap) = GhostMapAuth::<K, V>::new(Map::empty());
637 submap
638 }
639
640 pub proof fn empty(id: int) -> (tracked result: GhostSubmap<K, V>)
642 ensures
643 result.id() == id,
644 result@ == Map::<K, V>::empty(),
645 {
646 let tracked r = Resource::create_unit(id);
647 GhostSubmap { r }
648 }
649
650 pub proof fn take(tracked &mut self) -> (tracked result: GhostSubmap<K, V>)
652 ensures
653 old(self).id() == self.id(),
654 self@.is_empty(),
655 result == *old(self),
656 result.id() == self.id(),
657 {
658 use_type_invariant(&*self);
659
660 let tracked mut r = Self::empty(self.id());
661 tracked_swap(self, &mut r);
662 r
663 }
664
665 pub proof fn agree(tracked self: &GhostSubmap<K, V>, tracked auth: &GhostMapAuth<K, V>)
685 requires
686 self.id() == auth.id(),
687 ensures
688 self@ <= auth@,
689 {
690 broadcast use lemma_submap_of_trans;
691
692 use_type_invariant(self);
693 use_type_invariant(auth);
694
695 let tracked joined = self.r.join_shared(&auth.r);
696 joined.validate();
697 assert(self.r.value().frac.owning_map() <= joined.value().frac.owning_map());
698 }
699
700 pub proof fn combine(tracked &mut self, tracked other: GhostSubmap<K, V>)
704 requires
705 old(self).id() == other.id(),
706 ensures
707 self.id() == old(self).id(),
708 self@ == old(self)@.union_prefer_right(other@),
709 old(self)@.dom().disjoint(other@.dom()),
710 {
711 use_type_invariant(&*self);
712 use_type_invariant(&other);
713
714 let tracked mut r = Resource::alloc(MapCarrier::unit());
715 tracked_swap(&mut self.r, &mut r);
716 r.validate_2(&other.r);
717 self.r = r.join(other.r);
718 }
719
720 pub proof fn combine_points_to(tracked &mut self, tracked other: GhostPointsTo<K, V>)
723 requires
724 old(self).id() == other.id(),
725 ensures
726 self.id() == old(self).id(),
727 self@ == old(self)@.insert(other.key(), other.value()),
728 !old(self)@.contains_key(other.key()),
729 {
730 use_type_invariant(&*self);
731 use_type_invariant(&other);
732
733 other.lemma_map_view();
734 self.combine(other.submap);
735 }
736
737 pub proof fn disjoint(tracked &mut self, tracked other: &GhostSubmap<K, V>)
739 requires
740 old(self).id() == other.id(),
741 ensures
742 self.id() == old(self).id(),
743 self@ == old(self)@,
744 self@.dom().disjoint(other@.dom()),
745 {
746 use_type_invariant(&*self);
747 use_type_invariant(other);
748 self.r.validate_2(&other.r);
749 }
750
751 pub proof fn disjoint_persistent(tracked &mut self, tracked other: &GhostPersistentSubmap<K, V>)
754 requires
755 old(self).id() == other.id(),
756 ensures
757 self.id() == old(self).id(),
758 self@ == old(self)@,
759 self@.dom().disjoint(other@.dom()),
760 {
761 use_type_invariant(&*self);
762 use_type_invariant(other);
763 self.r.validate_2(&other.r);
764 }
765
766 pub proof fn disjoint_points_to(tracked &mut self, tracked other: &GhostPointsTo<K, V>)
769 requires
770 old(self).id() == other.id(),
771 ensures
772 self.id() == old(self).id(),
773 self@ == old(self)@,
774 !self@.contains_key(other.key()),
775 {
776 use_type_invariant(&*self);
777 use_type_invariant(other);
778 self.disjoint(&other.submap);
779 }
780
781 pub proof fn disjoint_persistent_points_to(
784 tracked &mut self,
785 tracked other: &GhostPersistentPointsTo<K, V>,
786 )
787 requires
788 old(self).id() == other.id(),
789 ensures
790 self.id() == old(self).id(),
791 self@ == old(self)@,
792 !self@.contains_key(other.key()),
793 {
794 use_type_invariant(&*self);
795 use_type_invariant(other);
796 self.disjoint_persistent(&other.submap);
797 }
798
799 pub proof fn split(tracked &mut self, s: Set<K>) -> (tracked result: GhostSubmap<K, V>)
801 requires
802 s <= old(self)@.dom(),
803 ensures
804 self.id() == old(self).id(),
805 result.id() == self.id(),
806 old(self)@ == self@.union_prefer_right(result@),
807 result@.dom() =~= s,
808 self@.dom() =~= old(self)@.dom() - s,
809 {
810 use_type_invariant(&*self);
811
812 let tracked mut r = Resource::alloc(MapCarrier::<K, V>::unit());
813 tracked_swap(&mut self.r, &mut r);
814
815 let self_carrier = MapCarrier {
816 auth: AuthCarrier::Frac,
817 frac: FracCarrier::Frac {
818 owning: r.value().frac.owning_map().remove_keys(s),
819 dup: r.value().frac.dup_map(),
820 },
821 };
822
823 let res_carrier = MapCarrier {
824 auth: AuthCarrier::Frac,
825 frac: FracCarrier::Frac {
826 owning: r.value().frac.owning_map().restrict(s),
827 dup: r.value().frac.dup_map(),
828 },
829 };
830
831 assert(r.value().frac == MapCarrier::op(self_carrier, res_carrier).frac);
832 let tracked (self_r, res_r) = r.split(self_carrier, res_carrier);
833 self.r = self_r;
834 GhostSubmap { r: res_r }
835 }
836
837 pub proof fn split_points_to(tracked &mut self, k: K) -> (tracked result: GhostPointsTo<K, V>)
839 requires
840 old(self)@.contains_key(k),
841 ensures
842 self.id() == old(self).id(),
843 result.id() == self.id(),
844 old(self)@ == self@.insert(result.key(), result.value()),
845 result.key() == k,
846 self@.dom() =~= old(self)@.dom().remove(k),
847 {
848 use_type_invariant(&*self);
849
850 let tracked submap = self.split(set![k]);
851 GhostPointsTo { submap }
852 }
853
854 pub proof fn update(tracked &mut self, tracked auth: &mut GhostMapAuth<K, V>, m: Map<K, V>)
873 requires
874 m.dom() <= old(self)@.dom(),
875 old(self).id() == old(auth).id(),
876 ensures
877 self.id() == old(self).id(),
878 auth.id() == old(auth).id(),
879 self@ == old(self)@.union_prefer_right(m),
880 auth@ == old(auth)@.union_prefer_right(m),
881 {
882 broadcast use lemma_submap_of_trans;
883 broadcast use lemma_submap_of_op;
884
885 use_type_invariant(&*self);
886 use_type_invariant(&*auth);
887
888 let tracked mut mself = Self::dummy();
889 tracked_swap(self, &mut mself);
890 let tracked mut frac_r = mself.r;
891
892 let tracked mut mauth = GhostMapAuth::<K, V>::dummy();
893 tracked_swap(auth, &mut mauth);
894 let tracked mut auth_r = mauth.r;
895
896 frac_r.validate_2(&auth_r);
897 let tracked mut full_r = frac_r.join(auth_r);
898
899 assert(full_r.value().frac.owning_map() == frac_r.value().frac.owning_map());
900
901 let auth_carrier = AuthCarrier::Auth(full_r.value().auth.map().union_prefer_right(m));
902 let frac_carrier = FracCarrier::Frac {
903 owning: full_r.value().frac.owning_map().union_prefer_right(m),
904 dup: Map::empty(),
905 };
906 let new_full_carrier = MapCarrier { auth: auth_carrier, frac: frac_carrier };
907
908 assert(new_full_carrier.valid());
909 let tracked r_upd = full_r.update(new_full_carrier);
910
911 let new_auth_carrier = MapCarrier {
912 auth: r_upd.value().auth,
913 frac: FracCarrier::Frac { owning: Map::empty(), dup: Map::empty() },
914 };
915 let new_frac_carrier = MapCarrier { auth: AuthCarrier::Frac, frac: r_upd.value().frac };
916 assert(r_upd.value().frac == MapCarrier::op(new_auth_carrier, new_frac_carrier).frac);
917 assert(r_upd.value() == MapCarrier::op(new_auth_carrier, new_frac_carrier));
918
919 let tracked (new_auth_r, new_frac_r) = r_upd.split(new_auth_carrier, new_frac_carrier);
920 auth.r = new_auth_r;
921 self.r = new_frac_r;
922 }
923
924 pub proof fn points_to(tracked self) -> (tracked r: GhostPointsTo<K, V>)
926 requires
927 self.is_points_to(),
928 ensures
929 self@ == map![r.key() => r.value()],
930 self.id() == r.id(),
931 {
932 let tracked r = GhostPointsTo { submap: self };
933 r.lemma_map_view();
934 r
935 }
936
937 pub proof fn persist(tracked self) -> (tracked r: GhostPersistentSubmap<K, V>)
939 ensures
940 self@ == r@,
941 self.id() == r.id(),
942 {
943 broadcast use lemma_submap_of_trans;
944 broadcast use lemma_submap_of_op;
945
946 use_type_invariant(&self);
947
948 let tracked mut r = self.r;
949
950 let self_carrier = MapCarrier {
951 auth: AuthCarrier::Frac,
952 frac: FracCarrier::Frac {
953 owning: self.r.value().frac.owning_map(),
954 dup: self.r.value().frac.dup_map(),
955 },
956 };
957
958 let res_carrier = MapCarrier {
959 auth: AuthCarrier::Frac,
960 frac: FracCarrier::Frac {
961 owning: self.r.value().frac.dup_map(),
962 dup: self.r.value().frac.owning_map(),
963 },
964 };
965
966 let tracked r = r.update(res_carrier);
967 GhostPersistentSubmap { r }
968 }
969}
970
971impl<K, V> GhostPersistentSubmap<K, V> {
972 #[verifier::type_invariant]
973 spec fn inv(self) -> bool {
974 &&& self.r.value().auth is Frac
975 &&& self.r.value().frac is Frac
976 &&& self.r.value().frac.owning_map().is_empty()
977 }
978
979 pub open spec fn is_points_to(self) -> bool {
982 &&& self@.len() == 1
983 &&& self.dom().finite()
984 &&& !self@.is_empty()
985 }
986
987 pub closed spec fn id(self) -> Loc {
989 self.r.loc()
990 }
991
992 pub closed spec fn view(self) -> Map<K, V> {
994 self.r.value().frac.dup_map()
995 }
996
997 pub open spec fn dom(self) -> Set<K> {
999 self@.dom()
1000 }
1001
1002 pub open spec fn spec_index(self, key: K) -> V
1004 recommends
1005 self.dom().contains(key),
1006 {
1007 self@[key]
1008 }
1009
1010 pub proof fn dummy() -> (tracked result: GhostPersistentSubmap<K, V>) {
1012 let tracked owned = GhostSubmap::<K, V>::dummy();
1013 owned.persist()
1014 }
1015
1016 pub proof fn empty(id: int) -> (tracked result: GhostPersistentSubmap<K, V>)
1018 ensures
1019 result.id() == id,
1020 result@ == Map::<K, V>::empty(),
1021 {
1022 let tracked r = Resource::create_unit(id);
1023 GhostPersistentSubmap { r }
1024 }
1025
1026 pub proof fn duplicate(tracked &mut self) -> (tracked result: GhostPersistentSubmap<K, V>)
1028 ensures
1029 self.id() == result.id(),
1030 old(self).id() == self.id(),
1031 old(self)@ == self@,
1032 result@ == self@,
1033 {
1034 use_type_invariant(&*self);
1035
1036 let tracked mut owned = Self::empty(self.id());
1037 let carrier = self.r.value();
1038 assert(carrier == MapCarrier::op(carrier, carrier));
1039
1040 tracked_swap(self, &mut owned);
1041 let tracked (mut orig, new) = owned.r.split(carrier, carrier);
1042 tracked_swap(&mut self.r, &mut orig);
1043 GhostPersistentSubmap { r: new }
1044 }
1045
1046 pub proof fn agree(
1066 tracked self: &GhostPersistentSubmap<K, V>,
1067 tracked auth: &GhostMapAuth<K, V>,
1068 )
1069 requires
1070 self.id() == auth.id(),
1071 ensures
1072 self@ <= auth@,
1073 {
1074 broadcast use lemma_submap_of_trans;
1075
1076 use_type_invariant(self);
1077 use_type_invariant(auth);
1078
1079 let tracked joined = self.r.join_shared(&auth.r);
1080 joined.validate();
1081 assert(self.r.value().frac.dup_map() <= joined.value().frac.dup_map());
1082 }
1083
1084 pub proof fn combine(tracked &mut self, tracked other: GhostPersistentSubmap<K, V>)
1088 requires
1089 old(self).id() == other.id(),
1090 ensures
1091 self.id() == old(self).id(),
1092 self@ == old(self)@.union_prefer_right(other@),
1093 old(self)@.agrees(other@),
1094 {
1095 use_type_invariant(&*self);
1096 use_type_invariant(&other);
1097
1098 let tracked mut r = Resource::alloc(MapCarrier::unit());
1099 tracked_swap(&mut self.r, &mut r);
1100 r.validate_2(&other.r);
1101 self.r = r.join(other.r);
1102 }
1103
1104 pub proof fn combine_points_to(tracked &mut self, tracked other: GhostPersistentPointsTo<K, V>)
1107 requires
1108 old(self).id() == other.id(),
1109 ensures
1110 self.id() == old(self).id(),
1111 self@ == old(self)@.insert(other.key(), other.value()),
1112 old(self)@.contains_key(other.key()) ==> old(self)@[other.key()] == other.value(),
1113 {
1114 use_type_invariant(&*self);
1115 use_type_invariant(&other);
1116
1117 other.lemma_map_view();
1118 self.combine(other.submap);
1119 }
1120
1121 pub proof fn disjoint(tracked &mut self, tracked other: &GhostSubmap<K, V>)
1123 requires
1124 old(self).id() == other.id(),
1125 ensures
1126 self.id() == old(self).id(),
1127 self@ == old(self)@,
1128 self@.dom().disjoint(other@.dom()),
1129 {
1130 use_type_invariant(&*self);
1131 use_type_invariant(other);
1132 self.r.validate_2(&other.r);
1133 }
1134
1135 pub proof fn intersection_agrees(tracked &mut self, tracked other: &GhostPersistentSubmap<K, V>)
1137 requires
1138 old(self).id() == other.id(),
1139 ensures
1140 self.id() == old(self).id(),
1141 self@ == old(self)@,
1142 self@.agrees(other@),
1143 {
1144 use_type_invariant(&*self);
1145 use_type_invariant(other);
1146 self.r.validate_2(&other.r);
1147 }
1148
1149 pub proof fn disjoint_points_to(tracked &mut self, tracked other: &GhostPointsTo<K, V>)
1152 requires
1153 old(self).id() == other.id(),
1154 ensures
1155 self.id() == old(self).id(),
1156 self@ == old(self)@,
1157 !self@.contains_key(other.key()),
1158 {
1159 use_type_invariant(&*self);
1160 use_type_invariant(other);
1161 self.disjoint(&other.submap);
1162 }
1163
1164 pub proof fn intersection_agrees_points_to(
1168 tracked &mut self,
1169 tracked other: &GhostPersistentPointsTo<K, V>,
1170 )
1171 requires
1172 old(self).id() == other.id(),
1173 ensures
1174 self.id() == old(self).id(),
1175 self@ == old(self)@,
1176 self@.contains_key(other.key()) ==> self@[other.key()] == other.value(),
1177 {
1178 use_type_invariant(&*self);
1179 use_type_invariant(other);
1180 self.intersection_agrees(&other.submap);
1181 }
1182
1183 pub proof fn split(tracked &mut self, s: Set<K>) -> (tracked result: GhostPersistentSubmap<
1185 K,
1186 V,
1187 >)
1188 requires
1189 s <= old(self)@.dom(),
1190 ensures
1191 self.id() == old(self).id(),
1192 result.id() == self.id(),
1193 old(self)@ == self@.union_prefer_right(result@),
1194 result@.dom() =~= s,
1195 self@.dom() =~= old(self)@.dom() - s,
1196 {
1197 use_type_invariant(&*self);
1198
1199 let tracked mut r = Resource::alloc(MapCarrier::<K, V>::unit());
1200 tracked_swap(&mut self.r, &mut r);
1201
1202 let self_carrier = MapCarrier {
1203 auth: AuthCarrier::Frac,
1204 frac: FracCarrier::Frac {
1205 owning: r.value().frac.owning_map(),
1206 dup: r.value().frac.dup_map().remove_keys(s),
1207 },
1208 };
1209
1210 let res_carrier = MapCarrier {
1211 auth: AuthCarrier::Frac,
1212 frac: FracCarrier::Frac {
1213 owning: r.value().frac.owning_map(),
1214 dup: r.value().frac.dup_map().restrict(s),
1215 },
1216 };
1217
1218 assert(r.value().frac == MapCarrier::op(self_carrier, res_carrier).frac);
1219 let tracked (self_r, res_r) = r.split(self_carrier, res_carrier);
1220 self.r = self_r;
1221 GhostPersistentSubmap { r: res_r }
1222 }
1223
1224 pub proof fn split_points_to(tracked &mut self, k: K) -> (tracked result:
1226 GhostPersistentPointsTo<K, V>)
1227 requires
1228 old(self)@.contains_key(k),
1229 ensures
1230 self.id() == old(self).id(),
1231 result.id() == self.id(),
1232 old(self)@ == self@.insert(result.key(), result.value()),
1233 result.key() == k,
1234 self@.dom() =~= old(self)@.dom().remove(k),
1235 {
1236 use_type_invariant(&*self);
1237
1238 let tracked submap = self.split(set![k]);
1239 GhostPersistentPointsTo { submap }
1240 }
1241
1242 pub proof fn points_to(tracked self) -> (tracked r: GhostPersistentPointsTo<K, V>)
1244 requires
1245 self.is_points_to(),
1246 ensures
1247 self@ == map![r.key() => r.value()],
1248 self.id() == r.id(),
1249 {
1250 let tracked r = GhostPersistentPointsTo { submap: self };
1251 r.lemma_map_view();
1252 r
1253 }
1254}
1255
1256impl<K, V> GhostPointsTo<K, V> {
1257 #[verifier::type_invariant]
1258 spec fn inv(self) -> bool {
1259 self.submap.is_points_to()
1260 }
1261
1262 pub closed spec fn id(self) -> Loc {
1264 self.submap.id()
1265 }
1266
1267 pub open spec fn view(self) -> (K, V) {
1269 (self.key(), self.value())
1270 }
1271
1272 pub closed spec fn key(self) -> K {
1274 self.submap.dom().choose()
1275 }
1276
1277 pub closed spec fn value(self) -> V {
1279 self.submap[self.key()]
1280 }
1281
1282 pub proof fn agree(tracked self: &GhostPointsTo<K, V>, tracked auth: &GhostMapAuth<K, V>)
1300 requires
1301 self.id() == auth.id(),
1302 ensures
1303 auth@.contains_pair(self.key(), self.value()),
1304 {
1305 use_type_invariant(self);
1306 use_type_invariant(auth);
1307
1308 self.lemma_map_view();
1309 self.submap.agree(auth);
1310 assert(self.submap@ <= auth@);
1311 assert(self.submap@.contains_key(self.key()));
1312 assert(self.submap@.contains_pair(self.key(), self.value()));
1313 }
1314
1315 pub proof fn combine(tracked self, tracked other: GhostPointsTo<K, V>) -> (tracked r:
1318 GhostSubmap<K, V>)
1319 requires
1320 self.id() == other.id(),
1321 ensures
1322 r.id() == self.id(),
1323 r@ == map![self.key() => self.value(), other.key() => other.value()],
1324 self.key() != other.key(),
1325 {
1326 use_type_invariant(&self);
1327 use_type_invariant(&other);
1328
1329 let tracked mut submap = self.submap();
1330 submap.combine_points_to(other);
1331
1332 submap
1333 }
1334
1335 pub proof fn disjoint(tracked &mut self, tracked other: &GhostPointsTo<K, V>)
1337 requires
1338 old(self).id() == other.id(),
1339 ensures
1340 self.id() == old(self).id(),
1341 self@ == old(self)@,
1342 self.key() != other.key(),
1343 {
1344 use_type_invariant(&*self);
1345 use_type_invariant(other);
1346 self.submap.disjoint(&other.submap);
1347 }
1348
1349 pub proof fn disjoint_submap(tracked &mut self, tracked other: &GhostSubmap<K, V>)
1351 requires
1352 old(self).id() == other.id(),
1353 ensures
1354 self.id() == old(self).id(),
1355 self@ == old(self)@,
1356 !other.dom().contains(self.key()),
1357 {
1358 use_type_invariant(&*self);
1359 use_type_invariant(other);
1360 self.submap.disjoint(other);
1361 }
1362
1363 pub proof fn disjoint_persistent_submap(
1365 tracked &mut self,
1366 tracked other: &GhostPersistentSubmap<K, V>,
1367 )
1368 requires
1369 old(self).id() == other.id(),
1370 ensures
1371 self.id() == old(self).id(),
1372 self@ == old(self)@,
1373 !other.dom().contains(self.key()),
1374 {
1375 use_type_invariant(&*self);
1376 use_type_invariant(other);
1377 self.submap.disjoint_persistent(other);
1378 }
1379
1380 pub proof fn disjoint_persistent(
1382 tracked &mut self,
1383 tracked other: &GhostPersistentPointsTo<K, V>,
1384 )
1385 requires
1386 old(self).id() == other.id(),
1387 ensures
1388 self.id() == old(self).id(),
1389 self@ == old(self)@,
1390 self.key() != other.key(),
1391 {
1392 use_type_invariant(&*self);
1393 use_type_invariant(other);
1394 self.submap.disjoint_persistent_points_to(other);
1395 }
1396
1397 pub proof fn update(tracked &mut self, tracked auth: &mut GhostMapAuth<K, V>, v: V)
1399 requires
1400 old(self).id() == old(auth).id(),
1401 ensures
1402 self.id() == old(self).id(),
1403 auth.id() == old(auth).id(),
1404 self.key() == old(self).key(),
1405 self@ == (self.key(), v),
1406 auth@ == old(auth)@.union_prefer_right(map![self.key() => v]),
1407 {
1408 broadcast use lemma_submap_of_trans;
1409 broadcast use lemma_submap_of_op;
1410
1411 use_type_invariant(&*self);
1412 use_type_invariant(&*auth);
1413
1414 let ghost old_dom = self.submap.dom();
1415 self.lemma_map_view();
1416 let m = map![self.key() => v];
1417 assert(self.submap@.union_prefer_right(m) == m);
1418 self.submap.update(auth, m);
1419 }
1420
1421 pub proof fn submap(tracked self) -> (tracked r: GhostSubmap<K, V>)
1423 ensures
1424 r.id() == self.id(),
1425 r@ == map![self.key() => self.value()],
1426 {
1427 self.lemma_map_view();
1428 self.submap
1429 }
1430
1431 proof fn lemma_map_view(tracked &self)
1432 ensures
1433 self.submap@ == map![self.key() => self.value()],
1434 {
1435 use_type_invariant(self);
1436 let key = self.key();
1437 let target_dom = set![key];
1438
1439 assert(self.submap@.dom().len() == 1);
1440 assert(target_dom.len() == 1);
1441
1442 assert(self.submap@.dom().finite());
1443 assert(target_dom.finite());
1444
1445 assert(self.submap@.dom().contains(key));
1446 assert(target_dom.contains(key));
1447
1448 assert(self.submap@.dom().remove(key).len() == 0);
1449 assert(target_dom.remove(key).len() == 0);
1450
1451 assert(self.submap@.dom() =~= target_dom);
1452 assert(self.submap@ == map![self.key() => self.value()]);
1453 }
1454
1455 pub proof fn lemma_view(self)
1457 ensures
1458 self@ == (self.key(), self.value()),
1459 {
1460 }
1461
1462 pub proof fn persist(tracked self) -> (tracked r: GhostPersistentPointsTo<K, V>)
1464 ensures
1465 self@ == r@,
1466 self.id() == r.id(),
1467 {
1468 use_type_invariant(&self);
1469 self.submap.persist().points_to()
1470 }
1471}
1472
1473impl<K, V> GhostPersistentPointsTo<K, V> {
1474 #[verifier::type_invariant]
1475 spec fn inv(self) -> bool {
1476 self.submap.is_points_to()
1477 }
1478
1479 pub closed spec fn id(self) -> Loc {
1481 self.submap.id()
1482 }
1483
1484 pub open spec fn view(self) -> (K, V) {
1486 (self.key(), self.value())
1487 }
1488
1489 pub closed spec fn key(self) -> K {
1491 self.submap.dom().choose()
1492 }
1493
1494 pub closed spec fn value(self) -> V {
1496 self.submap[self.key()]
1497 }
1498
1499 pub proof fn duplicate(tracked &mut self) -> (tracked result: GhostPersistentPointsTo<K, V>)
1501 ensures
1502 self.id() == result.id(),
1503 old(self).id() == self.id(),
1504 old(self)@ == self@,
1505 result@ == self@,
1506 {
1507 use_type_invariant(&*self);
1508 let tracked submap = self.submap.duplicate();
1509 GhostPersistentPointsTo { submap }
1510 }
1511
1512 pub proof fn agree(
1530 tracked self: &GhostPersistentPointsTo<K, V>,
1531 tracked auth: &GhostMapAuth<K, V>,
1532 )
1533 requires
1534 self.id() == auth.id(),
1535 ensures
1536 auth@.contains_pair(self.key(), self.value()),
1537 {
1538 use_type_invariant(self);
1539 use_type_invariant(auth);
1540
1541 self.lemma_map_view();
1542 self.submap.agree(auth);
1543 assert(self.submap@ <= auth@);
1544 assert(self.submap@.contains_key(self.key()));
1545 }
1546
1547 pub proof fn combine(
1549 tracked self,
1550 tracked other: GhostPersistentPointsTo<K, V>,
1551 ) -> (tracked submap: GhostPersistentSubmap<K, V>)
1552 requires
1553 self.id() == other.id(),
1554 ensures
1555 submap.id() == self.id(),
1556 submap@ == map![self.key() => self.value(), other.key() => other.value()],
1557 self.key() != other.key() ==> submap@.len() == 2,
1558 self.key() == other.key() ==> submap@.len() == 1,
1559 {
1560 use_type_invariant(&self);
1561 use_type_invariant(&other);
1562
1563 let tracked mut submap = self.submap();
1564 submap.combine_points_to(other);
1565
1566 submap
1567 }
1568
1569 pub proof fn disjoint(tracked &mut self, tracked other: &GhostPointsTo<K, V>)
1572 requires
1573 old(self).id() == other.id(),
1574 ensures
1575 self.id() == old(self).id(),
1576 self@ == old(self)@,
1577 self.key() != other.key(),
1578 {
1579 use_type_invariant(&*self);
1580 use_type_invariant(other);
1581 self.disjoint_submap(&other.submap);
1582 }
1583
1584 pub proof fn disjoint_submap(tracked &mut self, tracked other: &GhostSubmap<K, V>)
1587 requires
1588 old(self).id() == other.id(),
1589 ensures
1590 self.id() == old(self).id(),
1591 self@ == old(self)@,
1592 !other@.contains_key(self.key()),
1593 {
1594 use_type_invariant(&*self);
1595 use_type_invariant(other);
1596 self.submap.disjoint(&other);
1597 }
1598
1599 pub proof fn intersection_agrees(
1602 tracked &mut self,
1603 tracked other: &GhostPersistentPointsTo<K, V>,
1604 )
1605 requires
1606 old(self).id() == other.id(),
1607 ensures
1608 self.id() == old(self).id(),
1609 self@ == old(self)@,
1610 self.key() == other.key() ==> self.value() == other.value(),
1611 {
1612 use_type_invariant(&*self);
1613 use_type_invariant(other);
1614 self.submap.intersection_agrees_points_to(&other);
1615 }
1616
1617 pub proof fn intersection_agrees_submap(
1619 tracked &mut self,
1620 tracked other: &GhostPersistentSubmap<K, V>,
1621 )
1622 requires
1623 old(self).id() == other.id(),
1624 ensures
1625 self.id() == old(self).id(),
1626 self@ == old(self)@,
1627 other@.contains_key(self.key()) ==> other@[self.key()] == self.value(),
1628 {
1629 use_type_invariant(&*self);
1630 use_type_invariant(other);
1631 self.submap.intersection_agrees(other);
1632 }
1633
1634 pub proof fn submap(tracked self) -> (tracked r: GhostPersistentSubmap<K, V>)
1636 ensures
1637 r.id() == self.id(),
1638 r@ == map![self.key() => self.value()],
1639 {
1640 self.lemma_map_view();
1641 self.submap
1642 }
1643
1644 proof fn lemma_map_view(tracked &self)
1645 ensures
1646 self.submap@ == map![self.key() => self.value()],
1647 {
1648 use_type_invariant(self);
1649 let key = self.key();
1650 let target_dom = set![key];
1651
1652 assert(self.submap@.dom().len() == 1);
1653 assert(target_dom.len() == 1);
1654
1655 assert(self.submap@.dom().finite());
1656 assert(target_dom.finite());
1657
1658 assert(self.submap@.dom().contains(key));
1659 assert(target_dom.contains(key));
1660
1661 assert(self.submap@.dom().remove(key).len() == 0);
1662 assert(target_dom.remove(key).len() == 0);
1663
1664 assert(self.submap@.dom() =~= target_dom);
1665 assert(self.submap@ == map![self.key() => self.value()]);
1666 }
1667
1668 pub proof fn lemma_view(self)
1670 ensures
1671 self@ == (self.key(), self.value()),
1672 {
1673 }
1674}
1675
1676}