1use super::super::map::*;
77use super::super::map_lib::*;
78use super::super::modes::*;
79use super::super::prelude::*;
80use super::super::set_lib::*;
81use super::Loc;
82use super::algebra::ResourceAlgebra;
83#[cfg(verus_keep_ghost)]
84use super::incorporate;
85use super::pcm::PCM;
86use super::pcm::Resource;
87#[cfg(verus_keep_ghost)]
88use super::split_mut;
89
90verus! {
91
92broadcast use super::super::group_vstd_default;
93
94#[verifier::reject_recursive_types(K)]
95#[verifier::ext_equal]
96enum AuthCarrier<K, V> {
97 Auth(Map<K, V>),
98 Frac,
99 Invalid,
100}
101
102#[verifier::reject_recursive_types(K)]
103#[verifier::ext_equal]
104enum FracCarrier<K, V> {
105 Frac { owning: Map<K, V>, dup: Map<K, V> },
106 Invalid,
107}
108
109impl<K, V> AuthCarrier<K, V> {
110 spec fn valid(self) -> bool {
111 !(self is Invalid)
112 }
113
114 spec fn map(self) -> Map<K, V>
115 recommends
116 self.valid(),
117 {
118 match self {
119 AuthCarrier::Auth(m) => m,
120 AuthCarrier::Frac => Map::empty(),
121 AuthCarrier::Invalid => Map::empty(),
122 }
123 }
124}
125
126impl<K, V> FracCarrier<K, V> {
127 spec fn valid(self) -> bool {
128 match self {
129 FracCarrier::Invalid => false,
130 FracCarrier::Frac { owning, dup } => owning.dom().disjoint(dup.dom()),
131 }
132 }
133
134 spec fn owning_map(self) -> Map<K, V> {
135 match self {
136 FracCarrier::Frac { owning, .. } => owning,
137 FracCarrier::Invalid => Map::empty(),
138 }
139 }
140
141 spec fn dup_map(self) -> Map<K, V> {
142 match self {
143 FracCarrier::Frac { dup, .. } => dup,
144 FracCarrier::Invalid => Map::empty(),
145 }
146 }
147}
148
149#[verifier::reject_recursive_types(K)]
150#[verifier::ext_equal]
151tracked struct MapCarrier<K, V> {
153 auth: AuthCarrier<K, V>,
154 frac: FracCarrier<K, V>,
155}
156
157impl<K, V> ResourceAlgebra for MapCarrier<K, V> {
158 closed spec fn valid(self) -> bool {
159 match (self.auth, self.frac) {
160 (AuthCarrier::Invalid, _) => false,
161 (_, FracCarrier::Invalid) => false,
162 (AuthCarrier::Auth(auth), FracCarrier::Frac { owning, dup }) => {
163 &&& owning <= auth
164 &&& dup <= auth
165 &&& owning.dom().disjoint(dup.dom())
166 },
167 (AuthCarrier::Frac, FracCarrier::Frac { owning, dup }) => owning.dom().disjoint(
168 dup.dom(),
169 ),
170 }
171 }
172
173 closed spec fn op(a: Self, b: Self) -> Self {
174 let auth = match (a.auth, b.auth) {
175 (AuthCarrier::Invalid, _) => AuthCarrier::Invalid,
177 (_, AuthCarrier::Invalid) => AuthCarrier::Invalid,
178 (AuthCarrier::Auth(_), AuthCarrier::Auth(_)) => AuthCarrier::Invalid,
180 (AuthCarrier::Frac, AuthCarrier::Frac) => AuthCarrier::Frac,
182 (AuthCarrier::Auth(_), _) => a.auth,
184 (_, AuthCarrier::Auth(_)) => b.auth,
185 };
186
187 let frac = match (a.frac, b.frac) {
188 (FracCarrier::Invalid, _) => FracCarrier::Invalid,
190 (_, FracCarrier::Invalid) => FracCarrier::Invalid,
191 (
197 FracCarrier::Frac { owning: a_owning, dup: a_dup },
198 FracCarrier::Frac { owning: b_owning, dup: b_dup },
199 ) => {
200 let non_overlapping = {
201 &&& a_owning.dom().disjoint(b_dup.dom())
202 &&& b_owning.dom().disjoint(a_dup.dom())
203 &&& a_owning.dom().disjoint(b_owning.dom())
204 };
205 let aggreement = a_dup.agrees(b_dup);
206 if non_overlapping && aggreement {
207 FracCarrier::Frac {
208 owning: a_owning.union_prefer_right(b_owning),
209 dup: a_dup.union_prefer_right(b_dup),
210 }
211 } else {
212 FracCarrier::Invalid
213 }
214 },
215 };
216
217 MapCarrier { auth, frac }
218 }
219
220 proof fn valid_op(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
253impl<K, V> PCM for MapCarrier<K, V> {
254 closed spec fn unit() -> Self {
255 MapCarrier {
256 auth: AuthCarrier::Frac,
257 frac: FracCarrier::Frac { owning: Map::empty(), dup: Map::empty() },
258 }
259 }
260
261 proof fn op_unit(self) {
262 let x = Self::op(self, Self::unit());
263 assert(self == x);
264 }
265
266 proof fn unit_valid() {
267 }
268}
269
270proof fn lemma_submap_of_op_frac<K, V>(a: MapCarrier<K, V>, b: MapCarrier<K, V>)
271 requires
272 MapCarrier::op(a, b).valid(),
273 ensures
274 a.frac.owning_map() <= MapCarrier::op(a, b).frac.owning_map(),
275 a.frac.dup_map() <= MapCarrier::op(a, b).frac.dup_map(),
276 b.frac.owning_map() <= MapCarrier::op(a, b).frac.owning_map(),
277 b.frac.dup_map() <= MapCarrier::op(a, b).frac.dup_map(),
278{
279 let ab = MapCarrier::op(a, b);
280 assert(ab.frac.owning_map() == a.frac.owning_map().union_prefer_right(b.frac.owning_map()));
281 assert(ab.frac.dup_map() == a.frac.dup_map().union_prefer_right(b.frac.dup_map()));
282 assert(a.frac.owning_map().dom().disjoint(b.frac.owning_map().dom()));
283}
284
285broadcast proof fn lemma_submap_of_op<K, V>(a: MapCarrier<K, V>, b: MapCarrier<K, V>)
286 requires
287 #[trigger] MapCarrier::op(a, b).valid(),
288 ensures
289 a.frac.owning_map() <= MapCarrier::op(a, b).frac.owning_map(),
290 a.frac.dup_map() <= MapCarrier::op(a, b).frac.dup_map(),
291 a.auth.map() <= MapCarrier::op(a, b).auth.map(),
292 b.frac.owning_map() <= MapCarrier::op(a, b).frac.owning_map(),
293 b.frac.dup_map() <= MapCarrier::op(a, b).frac.dup_map(),
294 b.auth.map() <= MapCarrier::op(a, b).auth.map(),
295 a.valid(),
296 b.valid(),
297{
298 lemma_submap_of_op_frac(a, b);
299 MapCarrier::valid_op(a, b);
300 MapCarrier::commutative(a, b);
301 MapCarrier::valid_op(b, a);
302 let ab = MapCarrier::op(a, b);
303 assert(ab.auth.map() == a.auth.map().union_prefer_right(b.auth.map()));
304}
305
306#[verifier::reject_recursive_types(K)]
308pub tracked struct GhostMapAuth<K, V> {
309 r: Resource<MapCarrier<K, V>>,
310}
311
312#[verifier::reject_recursive_types(K)]
319pub tracked struct GhostSubmap<K, V> {
320 r: Resource<MapCarrier<K, V>>,
321}
322
323#[verifier::reject_recursive_types(K)]
329pub tracked struct GhostPersistentSubmap<K, V> {
330 r: Resource<MapCarrier<K, V>>,
331}
332
333#[verifier::reject_recursive_types(K)]
340pub tracked struct GhostPointsTo<K, V> {
341 submap: GhostSubmap<K, V>,
342}
343
344#[verifier::reject_recursive_types(K)]
350pub tracked struct GhostPersistentPointsTo<K, V> {
351 submap: GhostPersistentSubmap<K, V>,
352}
353
354impl<K, V> GhostMapAuth<K, V> {
355 #[verifier::type_invariant]
356 spec fn inv(self) -> bool {
357 &&& self.r.value().auth is Auth
358 &&& self.r.value().frac == FracCarrier::Frac {
359 owning: Map::<K, V>::empty(),
360 dup: Map::<K, V>::empty(),
361 }
362 }
363
364 pub closed spec fn id(self) -> Loc {
366 self.r.loc()
367 }
368
369 pub closed spec fn view(self) -> Map<K, V> {
371 self.r.value().auth.map()
372 }
373
374 pub open spec fn dom(self) -> Set<K> {
376 self@.dom()
377 }
378
379 pub open spec fn spec_index(self, key: K) -> V
381 recommends
382 self.dom().contains(key),
383 {
384 self@[key]
385 }
386
387 pub proof fn dummy() -> (tracked result: GhostMapAuth<K, V>) {
389 let tracked (auth, submap) = GhostMapAuth::<K, V>::new(Map::empty());
390 auth
391 }
392
393 pub proof fn take(tracked &mut self) -> (tracked result: GhostMapAuth<K, V>)
395 ensures
396 result == *old(self),
397 {
398 use_type_invariant(&*self);
399 let tracked mut r = Self::dummy();
400 tracked_swap(self, &mut r);
401 r
402 }
403
404 pub proof fn empty(tracked &self) -> (tracked result: GhostSubmap<K, V>)
406 ensures
407 result.id() == self.id(),
408 result@ == Map::<K, V>::empty(),
409 {
410 use_type_invariant(self);
411 let tracked r = Resource::<MapCarrier<_, _>>::create_unit(self.r.loc());
412 GhostSubmap { r }
413 }
414
415 pub proof fn insert_map(tracked &mut self, m: Map<K, V>) -> (tracked result: GhostSubmap<K, V>)
430 requires
431 old(self)@.dom().disjoint(m.dom()),
432 ensures
433 self.id() == old(self).id(),
434 self@ == old(self)@.union_prefer_right(m),
435 result.id() == self.id(),
436 result@ == m,
437 {
438 broadcast use lemma_submap_of_trans;
439 broadcast use lemma_submap_of_op;
440
441 let tracked mut mself = Self::dummy();
442 tracked_swap(self, &mut mself);
443
444 use_type_invariant(&mself);
445 assert(mself.inv());
446 let tracked mut self_r = mself.r;
447
448 let full_carrier = MapCarrier {
449 auth: AuthCarrier::Auth(self_r.value().auth.map().union_prefer_right(m)),
450 frac: FracCarrier::Frac { owning: m, dup: Map::empty() },
451 };
452
453 assert(full_carrier.valid());
454 let tracked updated_r = self_r.update(full_carrier);
455
456 let auth_carrier = MapCarrier {
457 auth: updated_r.value().auth,
458 frac: FracCarrier::Frac { owning: Map::empty(), dup: Map::empty() },
459 };
460 let frac_carrier = MapCarrier { auth: AuthCarrier::Frac, frac: updated_r.value().frac };
461
462 assert(updated_r.value() == MapCarrier::op(auth_carrier, frac_carrier));
463 let tracked (auth_r, frac_r) = updated_r.split(auth_carrier, frac_carrier);
464 self.r = auth_r;
465 GhostSubmap { r: frac_r }
466 }
467
468 pub proof fn insert(tracked &mut self, k: K, v: V) -> (tracked result: GhostPointsTo<K, V>)
481 requires
482 !old(self)@.contains_key(k),
483 ensures
484 self.id() == old(self).id(),
485 self@ == old(self)@.insert(k, v),
486 result.id() == self.id(),
487 result@ == (k, v),
488 {
489 let tracked submap = self.insert_map(map![k => v]);
490 GhostPointsTo { submap }
491 }
492
493 pub proof fn delete(tracked &mut self, tracked submap: GhostSubmap<K, V>)
508 requires
509 submap.id() == old(self).id(),
510 ensures
511 self.id() == old(self).id(),
512 self@ == old(self)@.remove_keys(submap@.dom()),
513 {
514 broadcast use lemma_submap_of_trans;
515 broadcast use lemma_submap_of_op;
516
517 use_type_invariant(&*self);
518 use_type_invariant(&submap);
519
520 let tracked mut mself = Self::dummy();
521 tracked_swap(self, &mut mself);
522 let tracked mut self_r = mself.r;
523
524 self_r = self_r.join(submap.r);
526
527 let auth_map = self_r.value().auth.map();
529 let new_auth_map = auth_map.remove_keys(submap@.dom());
530
531 let new_r = MapCarrier {
532 auth: AuthCarrier::Auth(new_auth_map),
533 frac: FracCarrier::Frac { owning: Map::empty(), dup: Map::empty() },
534 };
535
536 self.r = self_r.update(new_r);
538 }
539
540 pub proof fn delete_points_to(tracked &mut self, tracked p: GhostPointsTo<K, V>)
554 requires
555 p.id() == old(self).id(),
556 ensures
557 self.id() == old(self).id(),
558 self@ == old(self)@.remove(p.key()),
559 {
560 use_type_invariant(&p);
561 p.lemma_map_view();
562 self.delete(p.submap);
563 }
564
565 pub proof fn new(m: Map<K, V>) -> (tracked result: (GhostMapAuth<K, V>, GhostSubmap<K, V>))
577 ensures
578 result.0.id() == result.1.id(),
579 result.0@ == m,
580 result.1@ == m,
581 {
582 let tracked full_r = Resource::alloc(
583 MapCarrier {
584 auth: AuthCarrier::Auth(m),
585 frac: FracCarrier::Frac { owning: m, dup: Map::empty() },
586 },
587 );
588
589 let auth_carrier = MapCarrier {
590 auth: AuthCarrier::Auth(m),
591 frac: FracCarrier::Frac { owning: Map::empty(), dup: Map::empty() },
592 };
593
594 let frac_carrier = MapCarrier {
595 auth: AuthCarrier::Frac,
596 frac: FracCarrier::Frac { owning: m, dup: Map::empty() },
597 };
598
599 assert(full_r.value() == MapCarrier::op(auth_carrier, frac_carrier));
600 let tracked (auth_r, frac_r) = full_r.split(auth_carrier, frac_carrier);
601 (GhostMapAuth { r: auth_r }, GhostSubmap { r: frac_r })
602 }
603}
604
605impl<K, V> GhostSubmap<K, V> {
606 #[verifier::type_invariant]
607 spec fn inv(self) -> bool {
608 &&& self.r.value().auth is Frac
609 &&& self.r.value().frac is Frac
610 &&& self.r.value().frac.dup_map().is_empty()
611 }
612
613 pub open spec fn is_points_to(self) -> bool {
616 &&& self@.len() == 1
617 &&& self.dom().finite()
618 &&& !self@.is_empty()
619 }
620
621 pub closed spec fn id(self) -> Loc {
623 self.r.loc()
624 }
625
626 pub closed spec fn view(self) -> Map<K, V> {
628 self.r.value().frac.owning_map()
629 }
630
631 pub open spec fn dom(self) -> Set<K> {
633 self@.dom()
634 }
635
636 pub open spec fn spec_index(self, key: K) -> V
638 recommends
639 self.dom().contains(key),
640 {
641 self@[key]
642 }
643
644 pub proof fn dummy() -> (tracked result: GhostSubmap<K, V>) {
646 let tracked (auth, submap) = GhostMapAuth::<K, V>::new(Map::empty());
647 submap
648 }
649
650 pub proof fn empty(tracked &self) -> (tracked result: GhostSubmap<K, V>)
652 ensures
653 result.id() == self.id(),
654 result@ == Map::<K, V>::empty(),
655 {
656 use_type_invariant(self);
657 let tracked r = Resource::<MapCarrier<_, _>>::create_unit(self.r.loc());
658 GhostSubmap { r }
659 }
660
661 pub proof fn take(tracked &mut self) -> (tracked result: GhostSubmap<K, V>)
663 ensures
664 old(self).id() == self.id(),
665 self@.is_empty(),
666 result == *old(self),
667 result.id() == self.id(),
668 {
669 use_type_invariant(&*self);
670
671 let tracked mut r = self.empty();
672 tracked_swap(self, &mut r);
673 r
674 }
675
676 pub proof fn agree(tracked self: &GhostSubmap<K, V>, tracked auth: &GhostMapAuth<K, V>)
696 requires
697 self.id() == auth.id(),
698 ensures
699 self@ <= auth@,
700 {
701 broadcast use lemma_submap_of_trans;
702
703 use_type_invariant(self);
704 use_type_invariant(auth);
705
706 let tracked joined = self.r.join_shared(&auth.r);
707 joined.validate();
708 assert(self.r.value().frac.owning_map() <= joined.value().frac.owning_map());
709 }
710
711 pub proof fn combine(tracked &mut self, tracked other: GhostSubmap<K, V>)
715 requires
716 old(self).id() == other.id(),
717 ensures
718 self.id() == old(self).id(),
719 self@ == old(self)@.union_prefer_right(other@),
720 old(self)@.dom().disjoint(other@.dom()),
721 {
722 use_type_invariant(&*self);
723 use_type_invariant(&other);
724
725 self.r.validate_2(&other.r);
726 incorporate(&mut self.r, other.r);
727 }
728
729 pub proof fn combine_points_to(tracked &mut self, tracked other: GhostPointsTo<K, V>)
732 requires
733 old(self).id() == other.id(),
734 ensures
735 self.id() == old(self).id(),
736 self@ == old(self)@.insert(other.key(), other.value()),
737 !old(self)@.contains_key(other.key()),
738 {
739 use_type_invariant(&*self);
740 use_type_invariant(&other);
741
742 other.lemma_map_view();
743 self.combine(other.submap);
744 }
745
746 pub proof fn disjoint(tracked &mut self, tracked other: &GhostSubmap<K, V>)
748 requires
749 old(self).id() == other.id(),
750 ensures
751 self.id() == old(self).id(),
752 self@ == old(self)@,
753 self@.dom().disjoint(other@.dom()),
754 {
755 use_type_invariant(&*self);
756 use_type_invariant(other);
757 self.r.validate_2(&other.r);
758 }
759
760 pub proof fn disjoint_persistent(tracked &mut self, tracked other: &GhostPersistentSubmap<K, V>)
763 requires
764 old(self).id() == other.id(),
765 ensures
766 self.id() == old(self).id(),
767 self@ == old(self)@,
768 self@.dom().disjoint(other@.dom()),
769 {
770 use_type_invariant(&*self);
771 use_type_invariant(other);
772 self.r.validate_2(&other.r);
773 }
774
775 pub proof fn disjoint_points_to(tracked &mut self, tracked other: &GhostPointsTo<K, V>)
778 requires
779 old(self).id() == other.id(),
780 ensures
781 self.id() == old(self).id(),
782 self@ == old(self)@,
783 !self@.contains_key(other.key()),
784 {
785 use_type_invariant(&*self);
786 use_type_invariant(other);
787 self.disjoint(&other.submap);
788 }
789
790 pub proof fn disjoint_persistent_points_to(
793 tracked &mut self,
794 tracked other: &GhostPersistentPointsTo<K, V>,
795 )
796 requires
797 old(self).id() == other.id(),
798 ensures
799 self.id() == old(self).id(),
800 self@ == old(self)@,
801 !self@.contains_key(other.key()),
802 {
803 use_type_invariant(&*self);
804 use_type_invariant(other);
805 self.disjoint_persistent(&other.submap);
806 }
807
808 pub proof fn split(tracked &mut self, s: Set<K>) -> (tracked result: GhostSubmap<K, V>)
810 requires
811 s <= old(self)@.dom(),
812 ensures
813 self.id() == old(self).id(),
814 result.id() == self.id(),
815 old(self)@ == self@.union_prefer_right(result@),
816 result@.dom() =~= s,
817 self@.dom() =~= old(self)@.dom() - s,
818 {
819 use_type_invariant(&*self);
820
821 let self_carrier = MapCarrier {
822 auth: AuthCarrier::Frac,
823 frac: FracCarrier::Frac {
824 owning: self.r.value().frac.owning_map().remove_keys(s),
825 dup: self.r.value().frac.dup_map(),
826 },
827 };
828
829 let res_carrier = MapCarrier {
830 auth: AuthCarrier::Frac,
831 frac: FracCarrier::Frac {
832 owning: self.r.value().frac.owning_map().restrict(s),
833 dup: self.r.value().frac.dup_map(),
834 },
835 };
836
837 assert(self.r.value().frac == MapCarrier::op(self_carrier, res_carrier).frac);
838 let tracked r = split_mut(&mut self.r, self_carrier, res_carrier);
839 GhostSubmap { r }
840 }
841
842 pub proof fn split_points_to(tracked &mut self, k: K) -> (tracked result: GhostPointsTo<K, V>)
844 requires
845 old(self)@.contains_key(k),
846 ensures
847 self.id() == old(self).id(),
848 result.id() == self.id(),
849 old(self)@ == self@.insert(result.key(), result.value()),
850 result.key() == k,
851 self@ == old(self)@.remove(k),
852 {
853 use_type_invariant(&*self);
854
855 let tracked submap = self.split(set![k]);
856 GhostPointsTo { submap }
857 }
858
859 pub proof fn update(tracked &mut self, tracked auth: &mut GhostMapAuth<K, V>, m: Map<K, V>)
878 requires
879 m.dom() <= old(self)@.dom(),
880 old(self).id() == old(auth).id(),
881 ensures
882 self.id() == old(self).id(),
883 auth.id() == old(auth).id(),
884 self@ == old(self)@.union_prefer_right(m),
885 auth@ == old(auth)@.union_prefer_right(m),
886 {
887 broadcast use lemma_submap_of_trans;
888 broadcast use lemma_submap_of_op;
889
890 use_type_invariant(&*self);
891 use_type_invariant(&*auth);
892
893 let tracked mut mself = Self::dummy();
894 tracked_swap(self, &mut mself);
895 let tracked mut frac_r = mself.r;
896
897 let tracked mut mauth = GhostMapAuth::<K, V>::dummy();
898 tracked_swap(auth, &mut mauth);
899 let tracked mut auth_r = mauth.r;
900
901 frac_r.validate_2(&auth_r);
902 let tracked mut full_r = frac_r.join(auth_r);
903
904 assert(full_r.value().frac.owning_map() == frac_r.value().frac.owning_map());
905
906 let auth_carrier = AuthCarrier::Auth(full_r.value().auth.map().union_prefer_right(m));
907 let frac_carrier = FracCarrier::Frac {
908 owning: full_r.value().frac.owning_map().union_prefer_right(m),
909 dup: Map::empty(),
910 };
911 let new_full_carrier = MapCarrier { auth: auth_carrier, frac: frac_carrier };
912
913 assert(new_full_carrier.valid());
914 let tracked r_upd = full_r.update(new_full_carrier);
915
916 let new_auth_carrier = MapCarrier {
917 auth: r_upd.value().auth,
918 frac: FracCarrier::Frac { owning: Map::empty(), dup: Map::empty() },
919 };
920 let new_frac_carrier = MapCarrier { auth: AuthCarrier::Frac, frac: r_upd.value().frac };
921 assert(r_upd.value().frac == MapCarrier::op(new_auth_carrier, new_frac_carrier).frac);
922 assert(r_upd.value() == MapCarrier::op(new_auth_carrier, new_frac_carrier));
923
924 let tracked (new_auth_r, new_frac_r) = r_upd.split(new_auth_carrier, new_frac_carrier);
925 auth.r = new_auth_r;
926 self.r = new_frac_r;
927 }
928
929 pub proof fn points_to(tracked self) -> (tracked r: GhostPointsTo<K, V>)
931 requires
932 self.is_points_to(),
933 ensures
934 self@ == map![r.key() => r.value()],
935 self.id() == r.id(),
936 {
937 let tracked r = GhostPointsTo { submap: self };
938 r.lemma_map_view();
939 r
940 }
941
942 pub proof fn persist(tracked self) -> (tracked r: GhostPersistentSubmap<K, V>)
944 ensures
945 self@ == r@,
946 self.id() == r.id(),
947 {
948 broadcast use lemma_submap_of_trans;
949 broadcast use lemma_submap_of_op;
950
951 use_type_invariant(&self);
952
953 let tracked mut r = self.r;
954
955 let self_carrier = MapCarrier {
956 auth: AuthCarrier::Frac,
957 frac: FracCarrier::Frac {
958 owning: self.r.value().frac.owning_map(),
959 dup: self.r.value().frac.dup_map(),
960 },
961 };
962
963 let res_carrier = MapCarrier {
964 auth: AuthCarrier::Frac,
965 frac: FracCarrier::Frac {
966 owning: self.r.value().frac.dup_map(),
967 dup: self.r.value().frac.owning_map(),
968 },
969 };
970
971 let tracked r = r.update(res_carrier);
972 GhostPersistentSubmap { r }
973 }
974}
975
976impl<K, V> GhostPersistentSubmap<K, V> {
977 #[verifier::type_invariant]
978 spec fn inv(self) -> bool {
979 &&& self.r.value().auth is Frac
980 &&& self.r.value().frac is Frac
981 &&& self.r.value().frac.owning_map().is_empty()
982 }
983
984 pub open spec fn is_points_to(self) -> bool {
987 &&& self@.len() == 1
988 &&& self.dom().finite()
989 &&& !self@.is_empty()
990 }
991
992 pub closed spec fn id(self) -> Loc {
994 self.r.loc()
995 }
996
997 pub closed spec fn view(self) -> Map<K, V> {
999 self.r.value().frac.dup_map()
1000 }
1001
1002 pub open spec fn dom(self) -> Set<K> {
1004 self@.dom()
1005 }
1006
1007 pub open spec fn spec_index(self, key: K) -> V
1009 recommends
1010 self.dom().contains(key),
1011 {
1012 self@[key]
1013 }
1014
1015 pub proof fn dummy() -> (tracked result: GhostPersistentSubmap<K, V>) {
1017 let tracked owned = GhostSubmap::<K, V>::dummy();
1018 owned.persist()
1019 }
1020
1021 pub proof fn empty(tracked &self) -> (tracked result: GhostPersistentSubmap<K, V>)
1023 ensures
1024 result.id() == self.id(),
1025 result@ == Map::<K, V>::empty(),
1026 {
1027 use_type_invariant(self);
1028 let tracked r = Resource::<MapCarrier<_, _>>::create_unit(self.r.loc());
1029 GhostSubmap { r }.persist()
1030 }
1031
1032 pub proof fn duplicate(tracked &mut self) -> (tracked result: GhostPersistentSubmap<K, V>)
1034 ensures
1035 self.id() == result.id(),
1036 old(self).id() == self.id(),
1037 old(self)@ == self@,
1038 result@ == self@,
1039 {
1040 use_type_invariant(&*self);
1041
1042 let tracked mut owned = self.empty();
1043 let carrier = self.r.value();
1044 assert(carrier == MapCarrier::op(carrier, carrier));
1045
1046 tracked_swap(self, &mut owned);
1047 let tracked (mut orig, new) = owned.r.split(carrier, carrier);
1048 tracked_swap(&mut self.r, &mut orig);
1049 GhostPersistentSubmap { r: new }
1050 }
1051
1052 pub proof fn agree(
1072 tracked self: &GhostPersistentSubmap<K, V>,
1073 tracked auth: &GhostMapAuth<K, V>,
1074 )
1075 requires
1076 self.id() == auth.id(),
1077 ensures
1078 self@ <= auth@,
1079 {
1080 broadcast use lemma_submap_of_trans;
1081
1082 use_type_invariant(self);
1083 use_type_invariant(auth);
1084
1085 let tracked joined = self.r.join_shared(&auth.r);
1086 joined.validate();
1087 assert(self.r.value().frac.dup_map() <= joined.value().frac.dup_map());
1088 }
1089
1090 pub proof fn combine(tracked &mut self, tracked other: GhostPersistentSubmap<K, V>)
1094 requires
1095 old(self).id() == other.id(),
1096 ensures
1097 self.id() == old(self).id(),
1098 self@ == old(self)@.union_prefer_right(other@),
1099 old(self)@.agrees(other@),
1100 {
1101 use_type_invariant(&*self);
1102 use_type_invariant(&other);
1103
1104 self.r.validate_2(&other.r);
1105 incorporate(&mut self.r, other.r);
1106 }
1107
1108 pub proof fn combine_points_to(tracked &mut self, tracked other: GhostPersistentPointsTo<K, V>)
1111 requires
1112 old(self).id() == other.id(),
1113 ensures
1114 self.id() == old(self).id(),
1115 self@ == old(self)@.insert(other.key(), other.value()),
1116 old(self)@.contains_key(other.key()) ==> old(self)@[other.key()] == other.value(),
1117 {
1118 use_type_invariant(&*self);
1119 use_type_invariant(&other);
1120
1121 other.lemma_map_view();
1122 self.combine(other.submap);
1123 }
1124
1125 pub proof fn disjoint(tracked &mut self, tracked other: &GhostSubmap<K, V>)
1127 requires
1128 old(self).id() == other.id(),
1129 ensures
1130 self.id() == old(self).id(),
1131 self@ == old(self)@,
1132 self@.dom().disjoint(other@.dom()),
1133 {
1134 use_type_invariant(&*self);
1135 use_type_invariant(other);
1136 self.r.validate_2(&other.r);
1137 }
1138
1139 pub proof fn intersection_agrees(tracked &mut self, tracked other: &GhostPersistentSubmap<K, V>)
1141 requires
1142 old(self).id() == other.id(),
1143 ensures
1144 self.id() == old(self).id(),
1145 self@ == old(self)@,
1146 self@.agrees(other@),
1147 {
1148 use_type_invariant(&*self);
1149 use_type_invariant(other);
1150 self.r.validate_2(&other.r);
1151 }
1152
1153 pub proof fn disjoint_points_to(tracked &mut self, tracked other: &GhostPointsTo<K, V>)
1156 requires
1157 old(self).id() == other.id(),
1158 ensures
1159 self.id() == old(self).id(),
1160 self@ == old(self)@,
1161 !self@.contains_key(other.key()),
1162 {
1163 use_type_invariant(&*self);
1164 use_type_invariant(other);
1165 self.disjoint(&other.submap);
1166 }
1167
1168 pub proof fn intersection_agrees_points_to(
1172 tracked &mut self,
1173 tracked other: &GhostPersistentPointsTo<K, V>,
1174 )
1175 requires
1176 old(self).id() == other.id(),
1177 ensures
1178 self.id() == old(self).id(),
1179 self@ == old(self)@,
1180 self@.contains_key(other.key()) ==> self@[other.key()] == other.value(),
1181 {
1182 use_type_invariant(&*self);
1183 use_type_invariant(other);
1184 self.intersection_agrees(&other.submap);
1185 }
1186
1187 pub proof fn split(tracked &mut self, s: Set<K>) -> (tracked result: GhostPersistentSubmap<
1189 K,
1190 V,
1191 >)
1192 requires
1193 s <= old(self)@.dom(),
1194 ensures
1195 self.id() == old(self).id(),
1196 result.id() == self.id(),
1197 old(self)@ == self@.union_prefer_right(result@),
1198 result@.dom() =~= s,
1199 self@.dom() =~= old(self)@.dom() - s,
1200 {
1201 use_type_invariant(&*self);
1202
1203 let tracked mut r = Resource::alloc(MapCarrier::<K, V>::unit());
1204 tracked_swap(&mut self.r, &mut r);
1205
1206 let self_carrier = MapCarrier {
1207 auth: AuthCarrier::Frac,
1208 frac: FracCarrier::Frac {
1209 owning: r.value().frac.owning_map(),
1210 dup: r.value().frac.dup_map().remove_keys(s),
1211 },
1212 };
1213
1214 let res_carrier = MapCarrier {
1215 auth: AuthCarrier::Frac,
1216 frac: FracCarrier::Frac {
1217 owning: r.value().frac.owning_map(),
1218 dup: r.value().frac.dup_map().restrict(s),
1219 },
1220 };
1221
1222 assert(r.value().frac == MapCarrier::op(self_carrier, res_carrier).frac);
1223 let tracked (self_r, res_r) = r.split(self_carrier, res_carrier);
1224 self.r = self_r;
1225 GhostPersistentSubmap { r: res_r }
1226 }
1227
1228 pub proof fn split_points_to(tracked &mut self, k: K) -> (tracked result:
1230 GhostPersistentPointsTo<K, V>)
1231 requires
1232 old(self)@.contains_key(k),
1233 ensures
1234 self.id() == old(self).id(),
1235 result.id() == self.id(),
1236 old(self)@ == self@.insert(result.key(), result.value()),
1237 result.key() == k,
1238 self@ == old(self)@.remove(k),
1239 {
1240 use_type_invariant(&*self);
1241
1242 let tracked submap = self.split(set![k]);
1243 GhostPersistentPointsTo { submap }
1244 }
1245
1246 pub proof fn points_to(tracked self) -> (tracked r: GhostPersistentPointsTo<K, V>)
1248 requires
1249 self.is_points_to(),
1250 ensures
1251 self@ == map![r.key() => r.value()],
1252 self.id() == r.id(),
1253 {
1254 let tracked r = GhostPersistentPointsTo { submap: self };
1255 r.lemma_map_view();
1256 r
1257 }
1258}
1259
1260impl<K, V> GhostPointsTo<K, V> {
1261 #[verifier::type_invariant]
1262 spec fn inv(self) -> bool {
1263 self.submap.is_points_to()
1264 }
1265
1266 pub closed spec fn id(self) -> Loc {
1268 self.submap.id()
1269 }
1270
1271 pub open spec fn view(self) -> (K, V) {
1273 (self.key(), self.value())
1274 }
1275
1276 pub closed spec fn key(self) -> K {
1278 self.submap.dom().choose()
1279 }
1280
1281 pub closed spec fn value(self) -> V {
1283 self.submap[self.key()]
1284 }
1285
1286 pub proof fn agree(tracked self: &GhostPointsTo<K, V>, tracked auth: &GhostMapAuth<K, V>)
1304 requires
1305 self.id() == auth.id(),
1306 ensures
1307 auth@.contains_pair(self.key(), self.value()),
1308 {
1309 use_type_invariant(self);
1310 use_type_invariant(auth);
1311
1312 self.lemma_map_view();
1313 self.submap.agree(auth);
1314 assert(self.submap@ <= auth@);
1315 assert(self.submap@.contains_key(self.key()));
1316 assert(self.submap@.contains_pair(self.key(), self.value()));
1317 }
1318
1319 pub proof fn combine(tracked self, tracked other: GhostPointsTo<K, V>) -> (tracked r:
1322 GhostSubmap<K, V>)
1323 requires
1324 self.id() == other.id(),
1325 ensures
1326 r.id() == self.id(),
1327 r@ == map![self.key() => self.value(), other.key() => other.value()],
1328 self.key() != other.key(),
1329 {
1330 use_type_invariant(&self);
1331 use_type_invariant(&other);
1332
1333 let tracked mut submap = self.submap();
1334 submap.combine_points_to(other);
1335
1336 submap
1337 }
1338
1339 pub proof fn disjoint(tracked &mut self, tracked other: &GhostPointsTo<K, V>)
1341 requires
1342 old(self).id() == other.id(),
1343 ensures
1344 self.id() == old(self).id(),
1345 self@ == old(self)@,
1346 self.key() != other.key(),
1347 {
1348 use_type_invariant(&*self);
1349 use_type_invariant(other);
1350 self.submap.disjoint(&other.submap);
1351 }
1352
1353 pub proof fn disjoint_submap(tracked &mut self, tracked other: &GhostSubmap<K, V>)
1355 requires
1356 old(self).id() == other.id(),
1357 ensures
1358 self.id() == old(self).id(),
1359 self@ == old(self)@,
1360 !other.dom().contains(self.key()),
1361 {
1362 use_type_invariant(&*self);
1363 use_type_invariant(other);
1364 self.submap.disjoint(other);
1365 }
1366
1367 pub proof fn disjoint_persistent_submap(
1369 tracked &mut self,
1370 tracked other: &GhostPersistentSubmap<K, V>,
1371 )
1372 requires
1373 old(self).id() == other.id(),
1374 ensures
1375 self.id() == old(self).id(),
1376 self@ == old(self)@,
1377 !other.dom().contains(self.key()),
1378 {
1379 use_type_invariant(&*self);
1380 use_type_invariant(other);
1381 self.submap.disjoint_persistent(other);
1382 }
1383
1384 pub proof fn disjoint_persistent(
1386 tracked &mut self,
1387 tracked other: &GhostPersistentPointsTo<K, V>,
1388 )
1389 requires
1390 old(self).id() == other.id(),
1391 ensures
1392 self.id() == old(self).id(),
1393 self@ == old(self)@,
1394 self.key() != other.key(),
1395 {
1396 use_type_invariant(&*self);
1397 use_type_invariant(other);
1398 self.submap.disjoint_persistent_points_to(other);
1399 }
1400
1401 pub proof fn update(tracked &mut self, tracked auth: &mut GhostMapAuth<K, V>, v: V)
1403 requires
1404 old(self).id() == old(auth).id(),
1405 ensures
1406 self.id() == old(self).id(),
1407 auth.id() == old(auth).id(),
1408 self.key() == old(self).key(),
1409 self@ == (self.key(), v),
1410 auth@ == old(auth)@.union_prefer_right(map![self.key() => v]),
1411 {
1412 broadcast use lemma_submap_of_trans;
1413 broadcast use lemma_submap_of_op;
1414
1415 use_type_invariant(&*self);
1416 use_type_invariant(&*auth);
1417
1418 let ghost old_dom = self.submap.dom();
1419 self.lemma_map_view();
1420 let m = map![self.key() => v];
1421 assert(self.submap@.union_prefer_right(m) == m);
1422 self.submap.update(auth, m);
1423 }
1424
1425 pub proof fn submap(tracked self) -> (tracked r: GhostSubmap<K, V>)
1427 ensures
1428 r.id() == self.id(),
1429 r@ == map![self.key() => self.value()],
1430 {
1431 self.lemma_map_view();
1432 self.submap
1433 }
1434
1435 proof fn lemma_map_view(tracked &self)
1436 ensures
1437 self.submap@ == map![self.key() => self.value()],
1438 {
1439 use_type_invariant(self);
1440 let key = self.key();
1441 let target_dom = set![key];
1442
1443 assert(self.submap@.dom().len() == 1);
1444 assert(target_dom.len() == 1);
1445
1446 assert(self.submap@.dom().finite());
1447 assert(target_dom.finite());
1448
1449 assert(self.submap@.dom().contains(key));
1450 assert(target_dom.contains(key));
1451
1452 assert(self.submap@.dom().remove(key).len() == 0);
1453 assert(target_dom.remove(key).len() == 0);
1454
1455 assert(self.submap@.dom() =~= target_dom);
1456 assert(self.submap@ == map![self.key() => self.value()]);
1457 }
1458
1459 pub proof fn lemma_view(self)
1461 ensures
1462 self@ == (self.key(), self.value()),
1463 {
1464 }
1465
1466 pub proof fn persist(tracked self) -> (tracked r: GhostPersistentPointsTo<K, V>)
1468 ensures
1469 self@ == r@,
1470 self.id() == r.id(),
1471 {
1472 use_type_invariant(&self);
1473 self.submap.persist().points_to()
1474 }
1475}
1476
1477impl<K, V> GhostPersistentPointsTo<K, V> {
1478 #[verifier::type_invariant]
1479 spec fn inv(self) -> bool {
1480 self.submap.is_points_to()
1481 }
1482
1483 pub closed spec fn id(self) -> Loc {
1485 self.submap.id()
1486 }
1487
1488 pub open spec fn view(self) -> (K, V) {
1490 (self.key(), self.value())
1491 }
1492
1493 pub closed spec fn key(self) -> K {
1495 self.submap.dom().choose()
1496 }
1497
1498 pub closed spec fn value(self) -> V {
1500 self.submap[self.key()]
1501 }
1502
1503 pub proof fn duplicate(tracked &mut self) -> (tracked result: GhostPersistentPointsTo<K, V>)
1505 ensures
1506 self.id() == result.id(),
1507 old(self).id() == self.id(),
1508 old(self)@ == self@,
1509 result@ == self@,
1510 {
1511 use_type_invariant(&*self);
1512 let tracked submap = self.submap.duplicate();
1513 GhostPersistentPointsTo { submap }
1514 }
1515
1516 pub proof fn agree(
1534 tracked self: &GhostPersistentPointsTo<K, V>,
1535 tracked auth: &GhostMapAuth<K, V>,
1536 )
1537 requires
1538 self.id() == auth.id(),
1539 ensures
1540 auth@.contains_pair(self.key(), self.value()),
1541 {
1542 use_type_invariant(self);
1543 use_type_invariant(auth);
1544
1545 self.lemma_map_view();
1546 self.submap.agree(auth);
1547 assert(self.submap@ <= auth@);
1548 assert(self.submap@.contains_key(self.key()));
1549 }
1550
1551 pub proof fn combine(
1553 tracked self,
1554 tracked other: GhostPersistentPointsTo<K, V>,
1555 ) -> (tracked submap: GhostPersistentSubmap<K, V>)
1556 requires
1557 self.id() == other.id(),
1558 ensures
1559 submap.id() == self.id(),
1560 submap@ == map![self.key() => self.value(), other.key() => other.value()],
1561 self.key() != other.key() ==> submap@.len() == 2,
1562 self.key() == other.key() ==> submap@.len() == 1,
1563 {
1564 use_type_invariant(&self);
1565 use_type_invariant(&other);
1566
1567 let tracked mut submap = self.submap();
1568 submap.combine_points_to(other);
1569
1570 submap
1571 }
1572
1573 pub proof fn disjoint(tracked &mut self, tracked other: &GhostPointsTo<K, V>)
1576 requires
1577 old(self).id() == other.id(),
1578 ensures
1579 self.id() == old(self).id(),
1580 self@ == old(self)@,
1581 self.key() != other.key(),
1582 {
1583 use_type_invariant(&*self);
1584 use_type_invariant(other);
1585 self.disjoint_submap(&other.submap);
1586 }
1587
1588 pub proof fn disjoint_submap(tracked &mut self, tracked other: &GhostSubmap<K, V>)
1591 requires
1592 old(self).id() == other.id(),
1593 ensures
1594 self.id() == old(self).id(),
1595 self@ == old(self)@,
1596 !other@.contains_key(self.key()),
1597 {
1598 use_type_invariant(&*self);
1599 use_type_invariant(other);
1600 self.submap.disjoint(&other);
1601 }
1602
1603 pub proof fn intersection_agrees(
1606 tracked &mut self,
1607 tracked other: &GhostPersistentPointsTo<K, V>,
1608 )
1609 requires
1610 old(self).id() == other.id(),
1611 ensures
1612 self.id() == old(self).id(),
1613 self@ == old(self)@,
1614 self.key() == other.key() ==> self.value() == other.value(),
1615 {
1616 use_type_invariant(&*self);
1617 use_type_invariant(other);
1618 self.submap.intersection_agrees_points_to(&other);
1619 }
1620
1621 pub proof fn intersection_agrees_submap(
1623 tracked &mut self,
1624 tracked other: &GhostPersistentSubmap<K, V>,
1625 )
1626 requires
1627 old(self).id() == other.id(),
1628 ensures
1629 self.id() == old(self).id(),
1630 self@ == old(self)@,
1631 other@.contains_key(self.key()) ==> other@[self.key()] == self.value(),
1632 {
1633 use_type_invariant(&*self);
1634 use_type_invariant(other);
1635 self.submap.intersection_agrees(other);
1636 }
1637
1638 pub proof fn submap(tracked self) -> (tracked r: GhostPersistentSubmap<K, V>)
1640 ensures
1641 r.id() == self.id(),
1642 r@ == map![self.key() => self.value()],
1643 {
1644 self.lemma_map_view();
1645 self.submap
1646 }
1647
1648 proof fn lemma_map_view(tracked &self)
1649 ensures
1650 self.submap@ == map![self.key() => self.value()],
1651 {
1652 use_type_invariant(self);
1653 let key = self.key();
1654 let target_dom = set![key];
1655
1656 assert(self.submap@.dom().len() == 1);
1657 assert(target_dom.len() == 1);
1658
1659 assert(self.submap@.dom().finite());
1660 assert(target_dom.finite());
1661
1662 assert(self.submap@.dom().contains(key));
1663 assert(target_dom.contains(key));
1664
1665 assert(self.submap@.dom().remove(key).len() == 0);
1666 assert(target_dom.remove(key).len() == 0);
1667
1668 assert(self.submap@.dom() =~= target_dom);
1669 assert(self.submap@ == map![self.key() => self.value()]);
1670 }
1671
1672 pub proof fn lemma_view(self)
1674 ensures
1675 self@ == (self.key(), self.value()),
1676 {
1677 }
1678}
1679
1680}