1use super::multiset::*;
2use super::prelude::*;
3use core::marker::PhantomData;
4
5use verus as verus_;
6verus_! {
7
8#[verusfmt::skip]
14broadcast use {
15 super::iset::group_iset_lemmas,
16 super::iset_lib::group_iset_lib_default,
17 super::imap::group_imap_lemmas,
18 super::map::group_map_lemmas,
19 super::set::group_set_lemmas,
20 super::set_lib::group_set_lib_default,
21};
22
23pub type InstanceId = super::resource::Loc;
27
28pub trait ValueToken<Value> : Sized {
42 spec fn instance_id(&self) -> InstanceId;
43 spec fn value(&self) -> Value;
44
45 proof fn agree(tracked &self, tracked other: &Self)
47 requires self.instance_id() == other.instance_id(),
48 ensures self.value() == other.value();
49
50 proof fn arbitrary() -> (tracked s: Self);
53}
54
55pub trait UniqueValueToken<Value> : ValueToken<Value> {
59 proof fn unique(tracked &mut self, tracked other: &Self)
64 ensures
65 final(self).instance_id() != other.instance_id(),
66 *final(self) == *old(self);
67}
68
69pub trait KeyValueToken<Key, Value> : Sized {
87 spec fn instance_id(&self) -> InstanceId;
88 spec fn key(&self) -> Key;
89 spec fn value(&self) -> Value;
90
91 proof fn agree(tracked &self, tracked other: &Self)
93 requires self.instance_id() == other.instance_id(),
94 self.key() == other.key(),
95 ensures self.value() == other.value();
96
97 proof fn arbitrary() -> (tracked s: Self);
100}
101
102pub trait UniqueKeyValueToken<Key, Value> : KeyValueToken<Key, Value> {
106 proof fn unique(tracked &mut self, tracked other: &Self)
111 ensures
112 final(self).instance_id() != other.instance_id() || final(self).key() != other.key(),
113 *final(self) == *old(self);
114}
115
116pub trait CountToken : Sized {
127 spec fn instance_id(&self) -> InstanceId;
128 spec fn count(&self) -> nat;
129
130 proof fn join(tracked &mut self, tracked other: Self)
131 requires
132 old(self).instance_id() == other.instance_id(),
133 ensures
134 final(self).instance_id() == old(self).instance_id(),
135 final(self).count() == old(self).count() + other.count();
136
137 proof fn split(tracked &mut self, count: nat) -> (tracked token: Self)
138 requires
139 count <= old(self).count()
140 ensures
141 final(self).instance_id() == old(self).instance_id(),
142 final(self).count() == old(self).count() - count,
143 token.instance_id() == old(self).instance_id(),
144 token.count() == count;
145
146 proof fn weaken_shared(tracked &self, count: nat) -> (tracked s: &Self)
147 requires count <= self.count(),
148 ensures s.instance_id() == self.instance_id(),
149 s.count() == count;
150
151 proof fn arbitrary() -> (tracked s: Self);
154}
155
156pub trait MonotonicCountToken : Sized {
165 spec fn instance_id(&self) -> InstanceId;
166 spec fn count(&self) -> nat;
167
168 proof fn weaken(tracked &self, count: nat) -> (tracked s: Self)
169 requires count <= self.count(),
170 ensures s.instance_id() == self.instance_id(),
171 s.count() == count;
172
173 proof fn arbitrary() -> (tracked s: Self);
176}
177
178pub trait ElementToken<Element> : Sized {
199 spec fn instance_id(&self) -> InstanceId;
200 spec fn element(&self) -> Element;
201
202 proof fn arbitrary() -> (tracked s: Self);
205}
206
207pub trait UniqueElementToken<Element> : ElementToken<Element> {
211 proof fn unique(tracked &mut self, tracked other: &Self)
216 ensures
217 final(self).instance_id() == other.instance_id() ==> final(self).element() != other.element(),
218 *final(self) == *old(self);
219}
220
221pub trait SimpleToken : Sized {
232 spec fn instance_id(&self) -> InstanceId;
233
234 proof fn arbitrary() -> (tracked s: Self);
237}
238
239pub trait UniqueSimpleToken : SimpleToken {
243 proof fn unique(tracked &mut self, tracked other: &Self)
248 ensures
249 final(self).instance_id() != other.instance_id(),
250 *final(self) == *old(self);
251}
252
253#[verifier::reject_recursive_types(Key)]
254pub tracked struct IMapToken<Key, Value, Token>
255 where Token: KeyValueToken<Key, Value>
256{
257 ghost _v: PhantomData<Value>,
258 ghost inst: InstanceId,
259 tracked m: IMap<Key, Token>,
260}
261
262impl<Key, Value, Token> IMapToken<Key, Value, Token>
263 where Token: KeyValueToken<Key, Value>
264{
265 #[verifier::type_invariant]
266 spec fn wf(self) -> bool {
267 forall |k| #[trigger] self.m.dom().contains(k) ==> self.m[k].key() == k
268 && self.m[k].instance_id() == self.inst
269 }
270
271 pub closed spec fn instance_id(self) -> InstanceId {
272 self.inst
273 }
274
275 pub closed spec fn map(self) -> IMap<Key, Value> {
276 IMap::new(
277 |k: Key| self.m.dom().contains(k),
278 |k: Key| self.m[k].value(),
279 )
280 }
281
282 #[verifier::inline]
283 pub open spec fn dom(self) -> ISet<Key> {
284 self.map().dom()
285 }
286
287 #[verifier::inline]
288 pub open spec fn spec_index(self, k: Key) -> Value {
289 self.map()[k]
290 }
291
292 #[verifier::inline]
293 pub open spec fn index(self, k: Key) -> Value {
294 self.map()[k]
295 }
296
297 pub proof fn empty(instance_id: InstanceId) -> (tracked s: Self)
298 ensures
299 s.instance_id() == instance_id,
300 s.map() == IMap::empty(),
301 {
302 let tracked s = Self { inst: instance_id, m: IMap::tracked_empty(), _v: PhantomData };
303 assert(s.map() =~= IMap::empty());
304 return s;
305 }
306
307 pub proof fn insert(tracked &mut self, tracked token: Token)
308 requires
309 old(self).instance_id() == token.instance_id(),
310 ensures
311 final(self).instance_id() == old(self).instance_id(),
312 final(self).map() == old(self).map().insert(token.key(), token.value()),
313 {
314 use_type_invariant(&*self);
315 self.m.tracked_insert(token.key(), token);
316 assert(self.map() =~= old(self).map().insert(token.key(), token.value()));
317 }
318
319 pub proof fn remove(tracked &mut self, key: Key) -> (tracked token: Token)
320 requires
321 old(self).map().dom().contains(key)
322 ensures
323 final(self).instance_id() == old(self).instance_id(),
324 final(self).map() == old(self).map().remove(key),
325 token.instance_id() == final(self).instance_id(),
326 token.key() == key,
327 token.value() == old(self).map()[key]
328 {
329 use_type_invariant(&*self);
330 let tracked t = self.m.tracked_remove(key);
331 assert(self.map() =~= old(self).map().remove(key));
332 t
333 }
334
335 pub proof fn into_map(tracked self) -> (tracked map: IMap<Key, Token>)
336 ensures
337 map.dom() == self.map().dom(),
338 forall |key|
339 #![trigger(map.dom().contains(key))]
340 #![trigger(map.index(key))]
341 map.dom().contains(key)
342 ==> map[key].instance_id() == self.instance_id()
343 && map[key].key() == key
344 && map[key].value() == self.map()[key]
345 {
346 use_type_invariant(&self);
347 let tracked IMapToken { inst, m, _v } = self;
348 assert(m.dom() =~= self.map().dom());
349 return m;
350 }
351
352 pub proof fn from_map(instance_id: InstanceId, tracked map: IMap<Key, Token>) -> (tracked s: Self)
353 requires
354 forall |key| #[trigger] map.dom().contains(key) ==> map[key].instance_id() == instance_id,
355 forall |key| #[trigger] map.dom().contains(key) ==> map[key].key() == key,
356 ensures
357 s.instance_id() == instance_id,
358 s.map().dom() == map.dom(),
359 forall |key| #[trigger] map.dom().contains(key)
360 ==> s.map()[key] == map[key].value()
361 {
362 let tracked s = IMapToken { inst: instance_id, m: map, _v: PhantomData };
363 assert(map.dom() == s.map().dom());
364 s
365 }
366}
367
368#[verifier::reject_recursive_types(Key)]
369pub tracked struct MapToken<Key, Value, Token>
370 where Token: KeyValueToken<Key, Value>
371{
372 ghost _v: PhantomData<Value>,
373 ghost inst: InstanceId,
374 tracked m: Map<Key, Token>,
375}
376
377impl<Key, Value, Token> MapToken<Key, Value, Token>
378 where Token: KeyValueToken<Key, Value>
379{
380 #[verifier::type_invariant]
381 spec fn wf(self) -> bool {
382 forall |k| #[trigger] self.m.dom().contains(k) ==> self.m[k].key() == k
383 && self.m[k].instance_id() == self.inst
384 }
385
386 pub closed spec fn instance_id(self) -> InstanceId {
387 self.inst
388 }
389
390 pub closed spec fn map(self) -> Map<Key, Value> {
391 Map::new(
392 self.m.dom(),
393 |k: Key| self.m[k].value(),
394 )
395 }
396
397 #[verifier::inline]
398 pub open spec fn dom(self) -> Set<Key> {
399 self.map().dom()
400 }
401
402 #[verifier::inline]
403 pub open spec fn spec_index(self, k: Key) -> Value {
404 self.map()[k]
405 }
406
407 #[verifier::inline]
408 pub open spec fn index(self, k: Key) -> Value {
409 self.map()[k]
410 }
411
412 pub proof fn empty(instance_id: InstanceId) -> (tracked s: Self)
413 ensures
414 s.instance_id() == instance_id,
415 s.map() == Map::empty(),
416 {
417 let tracked s = Self { inst: instance_id, m: Map::tracked_empty(), _v: PhantomData };
418 assert(s.map() =~= Map::empty());
419 return s;
420 }
421
422 pub proof fn insert(tracked &mut self, tracked token: Token)
423 requires
424 old(self).instance_id() == token.instance_id(),
425 ensures
426 final(self).instance_id() == old(self).instance_id(),
427 final(self).map() == old(self).map().insert(token.key(), token.value()),
428 {
429 use_type_invariant(&*self);
430 self.m.tracked_insert(token.key(), token);
431 assert(self.map() =~= old(self).map().insert(token.key(), token.value()));
432 }
433
434 pub proof fn remove(tracked &mut self, key: Key) -> (tracked token: Token)
435 requires
436 old(self).map().dom().contains(key)
437 ensures
438 final(self).instance_id() == old(self).instance_id(),
439 final(self).map() == old(self).map().remove(key),
440 token.instance_id() == final(self).instance_id(),
441 token.key() == key,
442 token.value() == old(self).map()[key]
443 {
444 use_type_invariant(&*self);
445 let tracked t = self.m.tracked_remove(key);
446 assert(self.map() =~= old(self).map().remove(key));
447 t
448 }
449
450 pub proof fn into_map(tracked self) -> (tracked map: Map<Key, Token>)
451 ensures
452 map.dom() == self.map().dom(),
453 forall |key|
454 #![trigger(map.dom().contains(key))]
455 #![trigger(map.index(key))]
456 map.dom().contains(key)
457 ==> map[key].instance_id() == self.instance_id()
458 && map[key].key() == key
459 && map[key].value() == self.map()[key]
460 {
461 use_type_invariant(&self);
462 let tracked MapToken { inst, m, _v } = self;
463 assert(m.dom() =~= self.map().dom());
464 return m;
465 }
466
467 pub proof fn from_map(instance_id: InstanceId, tracked map: Map<Key, Token>) -> (tracked s: Self)
468 requires
469 forall |key| #[trigger] map.dom().contains(key) ==> map[key].instance_id() == instance_id,
470 forall |key| #[trigger] map.dom().contains(key) ==> map[key].key() == key,
471 ensures
472 s.instance_id() == instance_id,
473 s.map().dom() == map.dom(),
474 forall |key| #[trigger] map.dom().contains(key)
475 ==> s.map()[key] == map[key].value()
476 {
477 let tracked s = MapToken { inst: instance_id, m: map, _v: PhantomData };
478 assert(map.dom() == s.map().dom());
479 s
480 }
481}
482
483#[verifier::reject_recursive_types(Element)]
484pub tracked struct ISetToken<Element, Token>
485 where Token: ElementToken<Element>
486{
487 ghost inst: InstanceId,
488 tracked m: IMap<Element, Token>,
489}
490
491impl<Element, Token> ISetToken<Element, Token>
492 where Token: ElementToken<Element>
493{
494 #[verifier::type_invariant]
495 spec fn wf(self) -> bool {
496 forall |k| #[trigger] self.m.dom().contains(k) ==> self.m[k].element() == k
497 && self.m[k].instance_id() == self.inst
498 }
499
500 pub closed spec fn instance_id(self) -> InstanceId {
501 self.inst
502 }
503
504 pub closed spec fn set(self) -> ISet<Element> {
505 ISet::new(
506 |e: Element| self.m.dom().contains(e),
507 )
508 }
509
510 #[verifier::inline]
511 pub open spec fn contains(self, element: Element) -> bool {
512 self.set().contains(element)
513 }
514
515 pub proof fn empty(instance_id: InstanceId) -> (tracked s: Self)
516 ensures
517 s.instance_id() == instance_id,
518 s.set() == ISet::empty(),
519 {
520 let tracked s = Self { inst: instance_id, m: IMap::tracked_empty() };
521 assert(s.set() =~= ISet::empty());
522 return s;
523 }
524
525 pub proof fn insert(tracked &mut self, tracked token: Token)
526 requires
527 old(self).instance_id() == token.instance_id(),
528 ensures
529 final(self).instance_id() == old(self).instance_id(),
530 final(self).set() == old(self).set().insert(token.element()),
531 {
532 use_type_invariant(&*self);
533 self.m.tracked_insert(token.element(), token);
534 assert(self.set() =~= old(self).set().insert(token.element()));
535 }
536
537 pub proof fn remove(tracked &mut self, element: Element) -> (tracked token: Token)
538 requires
539 old(self).set().contains(element)
540 ensures
541 final(self).instance_id() == old(self).instance_id(),
542 final(self).set() == old(self).set().remove(element),
543 token.instance_id() == final(self).instance_id(),
544 token.element() == element,
545 {
546 use_type_invariant(&*self);
547 let tracked t = self.m.tracked_remove(element);
548 assert(self.set() =~= old(self).set().remove(element));
549 t
550 }
551
552 pub proof fn into_map(tracked self) -> (tracked map: IMap<Element, Token>)
553 ensures
554 map.dom() == self.set(),
555 forall |key|
556 #![trigger(map.dom().contains(key))]
557 #![trigger(map.index(key))]
558 map.dom().contains(key)
559 ==> map[key].instance_id() == self.instance_id()
560 && map[key].element() == key
561 {
562 use_type_invariant(&self);
563 let tracked ISetToken { inst, m } = self;
564 assert(m.dom() =~= self.set());
565 return m;
566 }
567
568 pub proof fn from_map(instance_id: InstanceId, tracked map: IMap<Element, Token>) -> (tracked s: Self)
569 requires
570 forall |key| #[trigger] map.dom().contains(key) ==> map[key].instance_id() == instance_id,
571 forall |key| #[trigger] map.dom().contains(key) ==> map[key].element() == key,
572 ensures
573 s.instance_id() == instance_id,
574 s.set() == map.dom(),
575 {
576 let tracked s = ISetToken { inst: instance_id, m: map };
577 assert(s.set() =~= map.dom());
578 s
579 }
580}
581
582#[verifier::reject_recursive_types(Element)]
583pub tracked struct SetToken<Element, Token>
584 where Token: ElementToken<Element>
585{
586 ghost inst: InstanceId,
587 tracked m: Map<Element, Token>,
588}
589
590impl<Element, Token> SetToken<Element, Token>
591 where Token: ElementToken<Element>
592{
593 #[verifier::type_invariant]
594 spec fn wf(self) -> bool {
595 forall |k| #[trigger] self.m.dom().contains(k) ==> self.m[k].element() == k
596 && self.m[k].instance_id() == self.inst
597 }
598
599 pub closed spec fn instance_id(self) -> InstanceId {
600 self.inst
601 }
602
603 pub closed spec fn set(self) -> Set<Element> {
604 self.m.dom()
605 }
606
607 #[verifier::inline]
608 pub open spec fn contains(self, element: Element) -> bool {
609 self.set().contains(element)
610 }
611
612 pub proof fn empty(instance_id: InstanceId) -> (tracked s: Self)
613 ensures
614 s.instance_id() == instance_id,
615 s.set() == Set::empty(),
616 {
617 let tracked s = Self { inst: instance_id, m: Map::tracked_empty() };
618 assert(s.set() =~= Set::empty());
619 return s;
620 }
621
622 pub proof fn insert(tracked &mut self, tracked token: Token)
623 requires
624 old(self).instance_id() == token.instance_id(),
625 ensures
626 final(self).instance_id() == old(self).instance_id(),
627 final(self).set() == old(self).set().insert(token.element()),
628 {
629 use_type_invariant(&*self);
630 self.m.tracked_insert(token.element(), token);
631 assert(self.set() =~= old(self).set().insert(token.element()));
632 }
633
634 pub proof fn remove(tracked &mut self, element: Element) -> (tracked token: Token)
635 requires
636 old(self).set().contains(element)
637 ensures
638 final(self).instance_id() == old(self).instance_id(),
639 final(self).set() == old(self).set().remove(element),
640 token.instance_id() == final(self).instance_id(),
641 token.element() == element,
642 {
643 use_type_invariant(&*self);
644 let tracked t = self.m.tracked_remove(element);
645 assert(self.set() =~= old(self).set().remove(element));
646 t
647 }
648
649 pub proof fn into_map(tracked self) -> (tracked map: Map<Element, Token>)
650 ensures
651 map.dom() == self.set(),
652 forall |key|
653 #![trigger(map.dom().contains(key))]
654 #![trigger(map.index(key))]
655 map.dom().contains(key)
656 ==> map[key].instance_id() == self.instance_id()
657 && map[key].element() == key
658 {
659 use_type_invariant(&self);
660 let tracked SetToken { inst, m } = self;
661 assert(m.dom() =~= self.set());
662 return m;
663 }
664
665 pub proof fn from_map(instance_id: InstanceId, tracked map: Map<Element, Token>) -> (tracked s: Self)
666 requires
667 forall |key| #[trigger] map.dom().contains(key) ==> map[key].instance_id() == instance_id,
668 forall |key| #[trigger] map.dom().contains(key) ==> map[key].element() == key,
669 ensures
670 s.instance_id() == instance_id,
671 s.set() == map.dom(),
672 {
673 let tracked s = SetToken { inst: instance_id, m: map };
674 assert(s.set() =~= map.dom());
675 s
676 }
677}
678
679pub tracked struct MultisetToken<Element, Token>
680 where Token: ElementToken<Element>
681{
682 ghost _v: PhantomData<Element>,
683 ghost inst: InstanceId,
684 tracked m: IMap<int, Token>,
685}
686
687spec fn map_values<K, V>(m: IMap<K, V>) -> Multiset<V> {
688 m.dom().fold(Multiset::empty(), |multiset: Multiset<V>, k: K| multiset.insert(m[k]))
689}
690
691proof fn map_values_insert_not_in<K, V>(m: IMap<K, V>, k: K, v: V)
692 requires
693 !m.dom().contains(k)
694 ensures
695 map_values(m.insert(k, v)) == map_values(m).insert(v)
696{
697 assume(false);
698}
699
700proof fn map_values_remove<K, V>(m: IMap<K, V>, k: K)
701 requires
702 m.dom().contains(k)
703 ensures
704 map_values(m.remove(k)) == map_values(m).remove(m[k])
705{
706 assume(false);
707}
708
709spec fn fresh(m: ISet<int>) -> int {
713 m.find_unique_maximal(|a: int, b: int| a <= b) + 1
714}
715
716proof fn fresh_is_fresh(s: ISet<int>)
717 requires s.finite(),
718 ensures !s.contains(fresh(s))
719{
720 assume(false);
721}
722
723proof fn get_key_for_value<K, V>(m: IMap<K, V>, value: V) -> (k: K)
724 requires map_values(m).contains(value),
725 ensures m.dom().contains(k), m[k] == value,
726{
727 assume(false);
728 arbitrary()
729}
730
731impl<Element, Token> MultisetToken<Element, Token>
732 where Token: ElementToken<Element>
733{
734 #[verifier::type_invariant]
735 spec fn wf(self) -> bool {
736 self.m.dom().finite() &&
737 forall |k| #[trigger] self.m.dom().contains(k)
738 ==> self.m[k].instance_id() == self.inst
739 }
740
741 pub closed spec fn instance_id(self) -> InstanceId {
742 self.inst
743 }
744
745 spec fn map_elems(m: IMap<int, Token>) -> IMap<int, Element> {
746 m.map_values(|t: Token| t.element())
747 }
748
749 pub closed spec fn multiset(self) -> Multiset<Element> {
750 map_values(Self::map_elems(self.m))
751 }
752
753 pub proof fn empty(instance_id: InstanceId) -> (tracked s: Self)
754 ensures
755 s.instance_id() == instance_id,
756 s.multiset() == Multiset::empty(),
757 {
758 let tracked s = Self { inst: instance_id, m: IMap::tracked_empty(), _v: PhantomData, };
759 broadcast use super::iset::fold::lemma_fold_empty;
760 assert(Self::map_elems(IMap::empty()) =~= IMap::empty());
761 return s;
762 }
763
764 pub proof fn insert(tracked &mut self, tracked token: Token)
765 requires
766 old(self).instance_id() == token.instance_id(),
767 ensures
768 final(self).instance_id() == old(self).instance_id(),
769 final(self).multiset() == old(self).multiset().insert(token.element()),
770 {
771 use_type_invariant(&*self);
772 let f = fresh(self.m.dom());
773 fresh_is_fresh(self.m.dom());
774 map_values_insert_not_in(
775 Self::map_elems(self.m),
776 f,
777 token.element());
778 self.m.tracked_insert(f, token);
779 assert(Self::map_elems(self.m) =~= Self::map_elems(old(self).m).insert(
780 f, token.element()));
781 assert(self.multiset() =~= old(self).multiset().insert(token.element()));
782 }
783
784 pub proof fn remove(tracked &mut self, element: Element) -> (tracked token: Token)
785 requires
786 old(self).multiset().contains(element)
787 ensures
788 final(self).instance_id() == old(self).instance_id(),
789 final(self).multiset() == old(self).multiset().remove(element),
790 token.instance_id() == final(self).instance_id(),
791 token.element() == element,
792 {
793 use_type_invariant(&*self);
794 assert(Self::map_elems(self.m).dom() =~= self.m.dom());
795 let k = get_key_for_value(Self::map_elems(self.m), element);
796 map_values_remove(Self::map_elems(self.m), k);
797 let tracked t = self.m.tracked_remove(k);
798 assert(Self::map_elems(self.m) =~= Self::map_elems(old(self).m).remove(k));
799 assert(self.multiset() =~= old(self).multiset().remove(element));
800 t
801 }
802}
803
804pub open spec fn option_value_eq_option_token<Value, Token: ValueToken<Value>>(
805 opt_value: Option<Value>,
806 opt_token: Option<Token>,
807 instance_id: InstanceId,
808) -> bool {
809 match opt_value {
810 Some(val) => opt_token.is_some()
811 && opt_token.unwrap().value() == val
812 && opt_token.unwrap().instance_id() == instance_id,
813 None => opt_token.is_none(),
814 }
815}
816
817pub open spec fn option_value_le_option_token<Value, Token: ValueToken<Value>>(
818 opt_value: Option<Value>,
819 opt_token: Option<Token>,
820 instance_id: InstanceId,
821) -> bool {
822 match opt_value {
823 Some(val) => opt_token.is_some()
824 && opt_token.unwrap().value() == val
825 && opt_token.unwrap().instance_id() == instance_id,
826 None => true,
827 }
828}
829
830pub open spec fn bool_value_eq_option_token<Token: SimpleToken>(
831 b: bool,
832 opt_token: Option<Token>,
833 instance_id: InstanceId,
834) -> bool {
835 if b {
836 opt_token.is_some() && opt_token.unwrap().instance_id() == instance_id
837 } else {
838 opt_token.is_none()
839 }
840}
841
842pub open spec fn bool_value_le_option_token<Token: SimpleToken>(
843 b: bool,
844 opt_token: Option<Token>,
845 instance_id: InstanceId,
846) -> bool {
847 b ==>
848 opt_token.is_some() && opt_token.unwrap().instance_id() == instance_id
849}
850
851}