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 final(self).id() == old(self).id(),
434 final(self)@ == old(self)@.union_prefer_right(m),
435 result.id() == final(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 final(self).id() == old(self).id(),
485 final(self)@ == old(self)@.insert(k, v),
486 result.id() == final(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 final(self).id() == old(self).id(),
512 final(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 final(self).id() == old(self).id(),
558 final(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() == final(self).id(),
665 final(self)@.is_empty(),
666 result == *old(self),
667 result.id() == final(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 final(self).id() == old(self).id(),
719 final(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 final(self).id() == old(self).id(),
736 final(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 final(self).id() == old(self).id(),
752 final(self)@ == old(self)@,
753 final(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 final(self).id() == old(self).id(),
767 final(self)@ == old(self)@,
768 final(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 final(self).id() == old(self).id(),
782 final(self)@ == old(self)@,
783 !final(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 final(self).id() == old(self).id(),
800 final(self)@ == old(self)@,
801 !final(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 final(self).id() == old(self).id(),
814 result.id() == final(self).id(),
815 old(self)@ == final(self)@.union_prefer_right(result@),
816 result@.dom() =~= s,
817 final(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 final(self).id() == old(self).id(),
848 result.id() == final(self).id(),
849 old(self)@ == final(self)@.insert(result.key(), result.value()),
850 result.key() == k,
851 final(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 final(self).id() == old(self).id(),
883 final(auth).id() == old(auth).id(),
884 final(self)@ == old(self)@.union_prefer_right(m),
885 final(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 &self) -> (tracked result: GhostPersistentSubmap<K, V>)
1034 ensures
1035 result.id() == self.id(),
1036 result@ == self@,
1037 {
1038 use_type_invariant(&*self);
1039
1040 assert(MapCarrier::op(self.r.value(), self.r.value()) == self.r.value());
1041 let tracked r = super::lib::duplicate(&self.r);
1042
1043 GhostPersistentSubmap { r }
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 final(self).id() == old(self).id(),
1092 final(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 self.r.validate_2(&other.r);
1099 incorporate(&mut self.r, other.r);
1100 }
1101
1102 pub proof fn combine_points_to(tracked &mut self, tracked other: GhostPersistentPointsTo<K, V>)
1105 requires
1106 old(self).id() == other.id(),
1107 ensures
1108 final(self).id() == old(self).id(),
1109 final(self)@ == old(self)@.insert(other.key(), other.value()),
1110 old(self)@.contains_key(other.key()) ==> old(self)@[other.key()] == other.value(),
1111 {
1112 use_type_invariant(&*self);
1113 use_type_invariant(&other);
1114
1115 other.lemma_map_view();
1116 self.combine(other.submap);
1117 }
1118
1119 pub proof fn disjoint(tracked &mut self, tracked other: &GhostSubmap<K, V>)
1121 requires
1122 old(self).id() == other.id(),
1123 ensures
1124 final(self).id() == old(self).id(),
1125 final(self)@ == old(self)@,
1126 final(self)@.dom().disjoint(other@.dom()),
1127 {
1128 use_type_invariant(&*self);
1129 use_type_invariant(other);
1130 self.r.validate_2(&other.r);
1131 }
1132
1133 pub proof fn intersection_agrees(tracked &mut self, tracked other: &GhostPersistentSubmap<K, V>)
1135 requires
1136 old(self).id() == other.id(),
1137 ensures
1138 final(self).id() == old(self).id(),
1139 final(self)@ == old(self)@,
1140 final(self)@.agrees(other@),
1141 {
1142 use_type_invariant(&*self);
1143 use_type_invariant(other);
1144 self.r.validate_2(&other.r);
1145 }
1146
1147 pub proof fn disjoint_points_to(tracked &mut self, tracked other: &GhostPointsTo<K, V>)
1150 requires
1151 old(self).id() == other.id(),
1152 ensures
1153 final(self).id() == old(self).id(),
1154 final(self)@ == old(self)@,
1155 !final(self)@.contains_key(other.key()),
1156 {
1157 use_type_invariant(&*self);
1158 use_type_invariant(other);
1159 self.disjoint(&other.submap);
1160 }
1161
1162 pub proof fn intersection_agrees_points_to(
1166 tracked &mut self,
1167 tracked other: &GhostPersistentPointsTo<K, V>,
1168 )
1169 requires
1170 old(self).id() == other.id(),
1171 ensures
1172 final(self).id() == old(self).id(),
1173 final(self)@ == old(self)@,
1174 final(self)@.contains_key(other.key()) ==> final(self)@[other.key()] == other.value(),
1175 {
1176 use_type_invariant(&*self);
1177 use_type_invariant(other);
1178 self.intersection_agrees(&other.submap);
1179 }
1180
1181 pub proof fn split(tracked &mut self, s: Set<K>) -> (tracked result: GhostPersistentSubmap<
1183 K,
1184 V,
1185 >)
1186 requires
1187 s <= old(self)@.dom(),
1188 ensures
1189 final(self).id() == old(self).id(),
1190 result.id() == final(self).id(),
1191 old(self)@ == final(self)@.union_prefer_right(result@),
1192 result@.dom() =~= s,
1193 final(self)@.dom() =~= old(self)@.dom() - s,
1194 {
1195 use_type_invariant(&*self);
1196
1197 let tracked mut r = Resource::alloc(MapCarrier::<K, V>::unit());
1198 tracked_swap(&mut self.r, &mut r);
1199
1200 let self_carrier = MapCarrier {
1201 auth: AuthCarrier::Frac,
1202 frac: FracCarrier::Frac {
1203 owning: r.value().frac.owning_map(),
1204 dup: r.value().frac.dup_map().remove_keys(s),
1205 },
1206 };
1207
1208 let res_carrier = MapCarrier {
1209 auth: AuthCarrier::Frac,
1210 frac: FracCarrier::Frac {
1211 owning: r.value().frac.owning_map(),
1212 dup: r.value().frac.dup_map().restrict(s),
1213 },
1214 };
1215
1216 assert(r.value().frac == MapCarrier::op(self_carrier, res_carrier).frac);
1217 let tracked (self_r, res_r) = r.split(self_carrier, res_carrier);
1218 self.r = self_r;
1219 GhostPersistentSubmap { r: res_r }
1220 }
1221
1222 pub proof fn split_points_to(tracked &mut self, k: K) -> (tracked result:
1224 GhostPersistentPointsTo<K, V>)
1225 requires
1226 old(self)@.contains_key(k),
1227 ensures
1228 final(self).id() == old(self).id(),
1229 result.id() == final(self).id(),
1230 old(self)@ == final(self)@.insert(result.key(), result.value()),
1231 result.key() == k,
1232 final(self)@ == old(self)@.remove(k),
1233 {
1234 use_type_invariant(&*self);
1235
1236 let tracked submap = self.split(set![k]);
1237 GhostPersistentPointsTo { submap }
1238 }
1239
1240 pub proof fn points_to(tracked self) -> (tracked r: GhostPersistentPointsTo<K, V>)
1242 requires
1243 self.is_points_to(),
1244 ensures
1245 self@ == map![r.key() => r.value()],
1246 self.id() == r.id(),
1247 {
1248 let tracked r = GhostPersistentPointsTo { submap: self };
1249 r.lemma_map_view();
1250 r
1251 }
1252}
1253
1254impl<K, V> GhostPointsTo<K, V> {
1255 #[verifier::type_invariant]
1256 spec fn inv(self) -> bool {
1257 self.submap.is_points_to()
1258 }
1259
1260 pub closed spec fn id(self) -> Loc {
1262 self.submap.id()
1263 }
1264
1265 pub open spec fn view(self) -> (K, V) {
1267 (self.key(), self.value())
1268 }
1269
1270 pub closed spec fn key(self) -> K {
1272 self.submap.dom().choose()
1273 }
1274
1275 pub closed spec fn value(self) -> V {
1277 self.submap[self.key()]
1278 }
1279
1280 pub proof fn agree(tracked self: &GhostPointsTo<K, V>, tracked auth: &GhostMapAuth<K, V>)
1298 requires
1299 self.id() == auth.id(),
1300 ensures
1301 auth@.contains_pair(self.key(), self.value()),
1302 {
1303 use_type_invariant(self);
1304 use_type_invariant(auth);
1305
1306 self.lemma_map_view();
1307 self.submap.agree(auth);
1308 assert(self.submap@ <= auth@);
1309 assert(self.submap@.dom().contains(self.key()));
1310 assert(auth@.dom().contains(self.key()));
1311 assert(self.submap@[self.key()] == self.value());
1312 assert(auth@[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 final(self).id() == old(self).id(),
1341 final(self)@ == old(self)@,
1342 final(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 final(self).id() == old(self).id(),
1355 final(self)@ == old(self)@,
1356 !other.dom().contains(final(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 final(self).id() == old(self).id(),
1372 final(self)@ == old(self)@,
1373 !other.dom().contains(final(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 final(self).id() == old(self).id(),
1389 final(self)@ == old(self)@,
1390 final(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 final(self).id() == old(self).id(),
1403 final(auth).id() == old(auth).id(),
1404 final(self).key() == old(self).key(),
1405 final(self)@ == (final(self).key(), v),
1406 final(auth)@ == old(auth)@.union_prefer_right(map![final(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 &self) -> (tracked result: GhostPersistentPointsTo<K, V>)
1501 ensures
1502 result.id() == self.id(),
1503 result@ == self@,
1504 {
1505 use_type_invariant(&*self);
1506 let tracked submap = self.submap.duplicate();
1507 GhostPersistentPointsTo { submap }
1508 }
1509
1510 pub proof fn agree(
1528 tracked self: &GhostPersistentPointsTo<K, V>,
1529 tracked auth: &GhostMapAuth<K, V>,
1530 )
1531 requires
1532 self.id() == auth.id(),
1533 ensures
1534 auth@.contains_pair(self.key(), self.value()),
1535 {
1536 use_type_invariant(self);
1537 use_type_invariant(auth);
1538
1539 self.lemma_map_view();
1540 self.submap.agree(auth);
1541 assert(self.submap@ <= auth@);
1542 assert(self.submap@.contains_key(self.key()));
1543 }
1544
1545 pub proof fn combine(
1547 tracked self,
1548 tracked other: GhostPersistentPointsTo<K, V>,
1549 ) -> (tracked submap: GhostPersistentSubmap<K, V>)
1550 requires
1551 self.id() == other.id(),
1552 ensures
1553 submap.id() == self.id(),
1554 submap@ == map![self.key() => self.value(), other.key() => other.value()],
1555 self.key() != other.key() ==> submap@.len() == 2,
1556 self.key() == other.key() ==> submap@.len() == 1,
1557 {
1558 use_type_invariant(&self);
1559 use_type_invariant(&other);
1560
1561 let tracked mut submap = self.submap();
1562 submap.combine_points_to(other);
1563
1564 submap
1565 }
1566
1567 pub proof fn disjoint(tracked &mut self, tracked other: &GhostPointsTo<K, V>)
1570 requires
1571 old(self).id() == other.id(),
1572 ensures
1573 final(self).id() == old(self).id(),
1574 final(self)@ == old(self)@,
1575 final(self).key() != other.key(),
1576 {
1577 use_type_invariant(&*self);
1578 use_type_invariant(other);
1579 self.disjoint_submap(&other.submap);
1580 }
1581
1582 pub proof fn disjoint_submap(tracked &mut self, tracked other: &GhostSubmap<K, V>)
1585 requires
1586 old(self).id() == other.id(),
1587 ensures
1588 final(self).id() == old(self).id(),
1589 final(self)@ == old(self)@,
1590 !other@.contains_key(final(self).key()),
1591 {
1592 use_type_invariant(&*self);
1593 use_type_invariant(other);
1594 self.submap.disjoint(&other);
1595 }
1596
1597 pub proof fn intersection_agrees(
1600 tracked &mut self,
1601 tracked other: &GhostPersistentPointsTo<K, V>,
1602 )
1603 requires
1604 old(self).id() == other.id(),
1605 ensures
1606 final(self).id() == old(self).id(),
1607 final(self)@ == old(self)@,
1608 final(self).key() == other.key() ==> final(self).value() == other.value(),
1609 {
1610 use_type_invariant(&*self);
1611 use_type_invariant(other);
1612 self.submap.intersection_agrees_points_to(&other);
1613 }
1614
1615 pub proof fn intersection_agrees_submap(
1617 tracked &mut self,
1618 tracked other: &GhostPersistentSubmap<K, V>,
1619 )
1620 requires
1621 old(self).id() == other.id(),
1622 ensures
1623 final(self).id() == old(self).id(),
1624 final(self)@ == old(self)@,
1625 other@.contains_key(final(self).key()) ==> other@[final(self).key()]
1626 == final(self).value(),
1627 {
1628 use_type_invariant(&*self);
1629 use_type_invariant(other);
1630 self.submap.intersection_agrees(other);
1631 }
1632
1633 pub proof fn submap(tracked self) -> (tracked r: GhostPersistentSubmap<K, V>)
1635 ensures
1636 r.id() == self.id(),
1637 r@ == map![self.key() => self.value()],
1638 {
1639 self.lemma_map_view();
1640 self.submap
1641 }
1642
1643 proof fn lemma_map_view(tracked &self)
1644 ensures
1645 self.submap@ == map![self.key() => self.value()],
1646 {
1647 use_type_invariant(self);
1648 let key = self.key();
1649 let target_dom = set![key];
1650
1651 assert(self.submap@.dom().len() == 1);
1652 assert(target_dom.len() == 1);
1653
1654 assert(self.submap@.dom().finite());
1655 assert(target_dom.finite());
1656
1657 assert(self.submap@.dom().contains(key));
1658 assert(target_dom.contains(key));
1659
1660 assert(self.submap@.dom().remove(key).len() == 0);
1661 assert(target_dom.remove(key).len() == 0);
1662
1663 assert(self.submap@.dom() =~= target_dom);
1664 assert(self.submap@ == map![self.key() => self.value()]);
1665 }
1666
1667 pub proof fn lemma_view(self)
1669 ensures
1670 self@ == (self.key(), self.value()),
1671 {
1672 }
1673}
1674
1675}