1use super::multiset::*;
2use super::prelude::*;
3use core::marker::PhantomData;
4
5use verus as verus_;
6verus_! {
7
8#[verusfmt::skip]
14broadcast use {
15 super::set_lib::group_set_lib_default,
16 super::set::group_set_axioms,
17 super::map::group_map_axioms };
18
19pub type InstanceId = super::resource::Loc;
23
24pub trait ValueToken<Value> : Sized {
38 spec fn instance_id(&self) -> InstanceId;
39 spec fn value(&self) -> Value;
40
41 proof fn agree(tracked &self, tracked other: &Self)
43 requires self.instance_id() == other.instance_id(),
44 ensures self.value() == other.value();
45
46 proof fn arbitrary() -> (tracked s: Self);
49}
50
51pub trait UniqueValueToken<Value> : ValueToken<Value> {
55 proof fn unique(tracked &mut self, tracked other: &Self)
60 ensures
61 self.instance_id() != other.instance_id(),
62 *self == *old(self);
63}
64
65pub trait KeyValueToken<Key, Value> : Sized {
81 spec fn instance_id(&self) -> InstanceId;
82 spec fn key(&self) -> Key;
83 spec fn value(&self) -> Value;
84
85 proof fn agree(tracked &self, tracked other: &Self)
87 requires self.instance_id() == other.instance_id(),
88 self.key() == other.key(),
89 ensures self.value() == other.value();
90
91 proof fn arbitrary() -> (tracked s: Self);
94}
95
96pub trait UniqueKeyValueToken<Key, Value> : KeyValueToken<Key, Value> {
100 proof fn unique(tracked &mut self, tracked other: &Self)
105 ensures
106 self.instance_id() != other.instance_id() || self.key() != other.key(),
107 *self == *old(self);
108}
109
110pub trait CountToken : Sized {
121 spec fn instance_id(&self) -> InstanceId;
122 spec fn count(&self) -> nat;
123
124 proof fn join(tracked &mut self, tracked other: Self)
125 requires
126 old(self).instance_id() == other.instance_id(),
127 ensures
128 self.instance_id() == old(self).instance_id(),
129 self.count() == old(self).count() + other.count();
130
131 proof fn split(tracked &mut self, count: nat) -> (tracked token: Self)
132 requires
133 count <= old(self).count()
134 ensures
135 self.instance_id() == old(self).instance_id(),
136 self.count() == old(self).count() - count,
137 token.instance_id() == old(self).instance_id(),
138 token.count() == count;
139
140 proof fn weaken_shared(tracked &self, count: nat) -> (tracked s: &Self)
141 requires count <= self.count(),
142 ensures s.instance_id() == self.instance_id(),
143 s.count() == count;
144
145 proof fn arbitrary() -> (tracked s: Self);
148}
149
150pub trait MonotonicCountToken : Sized {
159 spec fn instance_id(&self) -> InstanceId;
160 spec fn count(&self) -> nat;
161
162 proof fn weaken(tracked &self, count: nat) -> (tracked s: Self)
163 requires count <= self.count(),
164 ensures s.instance_id() == self.instance_id(),
165 s.count() == count;
166
167 proof fn arbitrary() -> (tracked s: Self);
170}
171
172pub trait ElementToken<Element> : Sized {
191 spec fn instance_id(&self) -> InstanceId;
192 spec fn element(&self) -> Element;
193
194 proof fn arbitrary() -> (tracked s: Self);
197}
198
199pub trait UniqueElementToken<Element> : ElementToken<Element> {
203 proof fn unique(tracked &mut self, tracked other: &Self)
208 ensures
209 self.instance_id() == other.instance_id() ==> self.element() != other.element(),
210 *self == *old(self);
211}
212
213pub trait SimpleToken : Sized {
224 spec fn instance_id(&self) -> InstanceId;
225
226 proof fn arbitrary() -> (tracked s: Self);
229}
230
231pub trait UniqueSimpleToken : SimpleToken {
235 proof fn unique(tracked &mut self, tracked other: &Self)
240 ensures
241 self.instance_id() != other.instance_id(),
242 *self == *old(self);
243}
244
245#[verifier::reject_recursive_types(Key)]
246pub tracked struct MapToken<Key, Value, Token>
247 where Token: KeyValueToken<Key, Value>
248{
249 ghost _v: PhantomData<Value>,
250 ghost inst: InstanceId,
251 tracked m: Map<Key, Token>,
252}
253
254impl<Key, Value, Token> MapToken<Key, Value, Token>
255 where Token: KeyValueToken<Key, Value>
256{
257 #[verifier::type_invariant]
258 spec fn wf(self) -> bool {
259 forall |k| #[trigger] self.m.dom().contains(k) ==> self.m[k].key() == k
260 && self.m[k].instance_id() == self.inst
261 }
262
263 pub closed spec fn instance_id(self) -> InstanceId {
264 self.inst
265 }
266
267 pub closed spec fn map(self) -> Map<Key, Value> {
268 Map::new(
269 |k: Key| self.m.dom().contains(k),
270 |k: Key| self.m[k].value(),
271 )
272 }
273
274 #[verifier::inline]
275 pub open spec fn dom(self) -> Set<Key> {
276 self.map().dom()
277 }
278
279 #[verifier::inline]
280 pub open spec fn spec_index(self, k: Key) -> Value {
281 self.map()[k]
282 }
283
284 #[verifier::inline]
285 pub open spec fn index(self, k: Key) -> Value {
286 self.map()[k]
287 }
288
289 pub proof fn empty(instance_id: InstanceId) -> (tracked s: Self)
290 ensures
291 s.instance_id() == instance_id,
292 s.map() === Map::empty(),
293 {
294 let tracked s = Self { inst: instance_id, m: Map::tracked_empty(), _v: PhantomData };
295 assert(s.map() =~= Map::empty());
296 return s;
297 }
298
299 pub proof fn insert(tracked &mut self, tracked token: Token)
300 requires
301 old(self).instance_id() == token.instance_id(),
302 ensures
303 self.instance_id() == old(self).instance_id(),
304 self.map() == old(self).map().insert(token.key(), token.value()),
305 {
306 use_type_invariant(&*self);
307 self.m.tracked_insert(token.key(), token);
308 assert(self.map() =~= old(self).map().insert(token.key(), token.value()));
309 }
310
311 pub proof fn remove(tracked &mut self, key: Key) -> (tracked token: Token)
312 requires
313 old(self).map().dom().contains(key)
314 ensures
315 self.instance_id() == old(self).instance_id(),
316 self.map() == old(self).map().remove(key),
317 token.instance_id() == self.instance_id(),
318 token.key() == key,
319 token.value() == old(self).map()[key]
320 {
321 use_type_invariant(&*self);
322 let tracked t = self.m.tracked_remove(key);
323 assert(self.map() =~= old(self).map().remove(key));
324 t
325 }
326
327 pub proof fn into_map(tracked self) -> (tracked map: Map<Key, Token>)
328 ensures
329 map.dom() == self.map().dom(),
330 forall |key|
331 #![trigger(map.dom().contains(key))]
332 #![trigger(map.index(key))]
333 map.dom().contains(key)
334 ==> map[key].instance_id() == self.instance_id()
335 && map[key].key() == key
336 && map[key].value() == self.map()[key]
337 {
338 use_type_invariant(&self);
339 let tracked MapToken { inst, m, _v } = self;
340 assert(m.dom() =~= self.map().dom());
341 return m;
342 }
343
344 pub proof fn from_map(instance_id: InstanceId, tracked map: Map<Key, Token>) -> (tracked s: Self)
345 requires
346 forall |key| #[trigger] map.dom().contains(key) ==> map[key].instance_id() == instance_id,
347 forall |key| #[trigger] map.dom().contains(key) ==> map[key].key() == key,
348 ensures
349 s.instance_id() == instance_id,
350 s.map().dom() == map.dom(),
351 forall |key| #[trigger] map.dom().contains(key)
352 ==> s.map()[key] == map[key].value()
353 {
354 let tracked s = MapToken { inst: instance_id, m: map, _v: PhantomData };
355 assert(map.dom() == s.map().dom());
356 s
357 }
358}
359
360#[verifier::reject_recursive_types(Element)]
361pub tracked struct SetToken<Element, Token>
362 where Token: ElementToken<Element>
363{
364 ghost inst: InstanceId,
365 tracked m: Map<Element, Token>,
366}
367
368impl<Element, Token> SetToken<Element, Token>
369 where Token: ElementToken<Element>
370{
371 #[verifier::type_invariant]
372 spec fn wf(self) -> bool {
373 forall |k| #[trigger] self.m.dom().contains(k) ==> self.m[k].element() == k
374 && self.m[k].instance_id() == self.inst
375 }
376
377 pub closed spec fn instance_id(self) -> InstanceId {
378 self.inst
379 }
380
381 pub closed spec fn set(self) -> Set<Element> {
382 Set::new(
383 |e: Element| self.m.dom().contains(e),
384 )
385 }
386
387 #[verifier::inline]
388 pub open spec fn contains(self, element: Element) -> bool {
389 self.set().contains(element)
390 }
391
392 pub proof fn empty(instance_id: InstanceId) -> (tracked s: Self)
393 ensures
394 s.instance_id() == instance_id,
395 s.set() === Set::empty(),
396 {
397 let tracked s = Self { inst: instance_id, m: Map::tracked_empty() };
398 assert(s.set() =~= Set::empty());
399 return s;
400 }
401
402 pub proof fn insert(tracked &mut self, tracked token: Token)
403 requires
404 old(self).instance_id() == token.instance_id(),
405 ensures
406 self.instance_id() == old(self).instance_id(),
407 self.set() == old(self).set().insert(token.element()),
408 {
409 use_type_invariant(&*self);
410 self.m.tracked_insert(token.element(), token);
411 assert(self.set() =~= old(self).set().insert(token.element()));
412 }
413
414 pub proof fn remove(tracked &mut self, element: Element) -> (tracked token: Token)
415 requires
416 old(self).set().contains(element)
417 ensures
418 self.instance_id() == old(self).instance_id(),
419 self.set() == old(self).set().remove(element),
420 token.instance_id() == self.instance_id(),
421 token.element() == element,
422 {
423 use_type_invariant(&*self);
424 let tracked t = self.m.tracked_remove(element);
425 assert(self.set() =~= old(self).set().remove(element));
426 t
427 }
428
429 pub proof fn into_map(tracked self) -> (tracked map: Map<Element, Token>)
430 ensures
431 map.dom() == self.set(),
432 forall |key|
433 #![trigger(map.dom().contains(key))]
434 #![trigger(map.index(key))]
435 map.dom().contains(key)
436 ==> map[key].instance_id() == self.instance_id()
437 && map[key].element() == key
438 {
439 use_type_invariant(&self);
440 let tracked SetToken { inst, m } = self;
441 assert(m.dom() =~= self.set());
442 return m;
443 }
444
445 pub proof fn from_map(instance_id: InstanceId, tracked map: Map<Element, Token>) -> (tracked s: Self)
446 requires
447 forall |key| #[trigger] map.dom().contains(key) ==> map[key].instance_id() == instance_id,
448 forall |key| #[trigger] map.dom().contains(key) ==> map[key].element() == key,
449 ensures
450 s.instance_id() == instance_id,
451 s.set() == map.dom(),
452 {
453 let tracked s = SetToken { inst: instance_id, m: map };
454 assert(s.set() =~= map.dom());
455 s
456 }
457}
458
459pub tracked struct MultisetToken<Element, Token>
460 where Token: ElementToken<Element>
461{
462 ghost _v: PhantomData<Element>,
463 ghost inst: InstanceId,
464 tracked m: Map<int, Token>,
465}
466
467spec fn map_values<K, V>(m: Map<K, V>) -> Multiset<V> {
468 m.dom().fold(Multiset::empty(), |multiset: Multiset<V>, k: K| multiset.insert(m[k]))
469}
470
471proof fn map_values_insert_not_in<K, V>(m: Map<K, V>, k: K, v: V)
472 requires
473 !m.dom().contains(k)
474 ensures
475 map_values(m.insert(k, v)) == map_values(m).insert(v)
476{
477 assume(false);
478}
479
480proof fn map_values_remove<K, V>(m: Map<K, V>, k: K)
481 requires
482 m.dom().contains(k)
483 ensures
484 map_values(m.remove(k)) == map_values(m).remove(m[k])
485{
486 assume(false);
487}
488
489spec fn fresh(m: Set<int>) -> int {
493 m.find_unique_maximal(|a: int, b: int| a <= b) + 1
494}
495
496proof fn fresh_is_fresh(s: Set<int>)
497 requires s.finite(),
498 ensures !s.contains(fresh(s))
499{
500 assume(false);
501}
502
503proof fn get_key_for_value<K, V>(m: Map<K, V>, value: V) -> (k: K)
504 requires map_values(m).contains(value), m.dom().finite(),
505 ensures m.dom().contains(k), m[k] == value,
506{
507 assume(false);
508 arbitrary()
509}
510
511impl<Element, Token> MultisetToken<Element, Token>
512 where Token: ElementToken<Element>
513{
514 #[verifier::type_invariant]
515 spec fn wf(self) -> bool {
516 self.m.dom().finite() &&
517 forall |k| #[trigger] self.m.dom().contains(k)
518 ==> self.m[k].instance_id() == self.inst
519 }
520
521 pub closed spec fn instance_id(self) -> InstanceId {
522 self.inst
523 }
524
525 spec fn map_elems(m: Map<int, Token>) -> Map<int, Element> {
526 m.map_values(|t: Token| t.element())
527 }
528
529 pub closed spec fn multiset(self) -> Multiset<Element> {
530 map_values(Self::map_elems(self.m))
531 }
532
533 pub proof fn empty(instance_id: InstanceId) -> (tracked s: Self)
534 ensures
535 s.instance_id() == instance_id,
536 s.multiset() === Multiset::empty(),
537 {
538 let tracked s = Self { inst: instance_id, m: Map::tracked_empty(), _v: PhantomData, };
539 broadcast use super::set::fold::lemma_fold_empty;
540 assert(Self::map_elems(Map::empty()) =~= Map::empty());
541 return s;
542 }
543
544 pub proof fn insert(tracked &mut self, tracked token: Token)
545 requires
546 old(self).instance_id() == token.instance_id(),
547 ensures
548 self.instance_id() == old(self).instance_id(),
549 self.multiset() == old(self).multiset().insert(token.element()),
550 {
551 use_type_invariant(&*self);
552 let f = fresh(self.m.dom());
553 fresh_is_fresh(self.m.dom());
554 map_values_insert_not_in(
555 Self::map_elems(self.m),
556 f,
557 token.element());
558 self.m.tracked_insert(f, token);
559 assert(Self::map_elems(self.m) =~= Self::map_elems(old(self).m).insert(
560 f, token.element()));
561 assert(self.multiset() =~= old(self).multiset().insert(token.element()));
562 }
563
564 pub proof fn remove(tracked &mut self, element: Element) -> (tracked token: Token)
565 requires
566 old(self).multiset().contains(element)
567 ensures
568 self.instance_id() == old(self).instance_id(),
569 self.multiset() == old(self).multiset().remove(element),
570 token.instance_id() == self.instance_id(),
571 token.element() == element,
572 {
573 use_type_invariant(&*self);
574 assert(Self::map_elems(self.m).dom() =~= self.m.dom());
575 let k = get_key_for_value(Self::map_elems(self.m), element);
576 map_values_remove(Self::map_elems(self.m), k);
577 let tracked t = self.m.tracked_remove(k);
578 assert(Self::map_elems(self.m) =~= Self::map_elems(old(self).m).remove(k));
579 assert(self.multiset() =~= old(self).multiset().remove(element));
580 t
581 }
582}
583
584pub open spec fn option_value_eq_option_token<Value, Token: ValueToken<Value>>(
585 opt_value: Option<Value>,
586 opt_token: Option<Token>,
587 instance_id: InstanceId,
588) -> bool {
589 match opt_value {
590 Some(val) => opt_token.is_some()
591 && opt_token.unwrap().value() == val
592 && opt_token.unwrap().instance_id() == instance_id,
593 None => opt_token.is_none(),
594 }
595}
596
597pub open spec fn option_value_le_option_token<Value, Token: ValueToken<Value>>(
598 opt_value: Option<Value>,
599 opt_token: Option<Token>,
600 instance_id: InstanceId,
601) -> bool {
602 match opt_value {
603 Some(val) => opt_token.is_some()
604 && opt_token.unwrap().value() == val
605 && opt_token.unwrap().instance_id() == instance_id,
606 None => true,
607 }
608}
609
610pub open spec fn bool_value_eq_option_token<Token: SimpleToken>(
611 b: bool,
612 opt_token: Option<Token>,
613 instance_id: InstanceId,
614) -> bool {
615 if b {
616 opt_token.is_some() && opt_token.unwrap().instance_id() == instance_id
617 } else {
618 opt_token.is_none()
619 }
620}
621
622pub open spec fn bool_value_le_option_token<Token: SimpleToken>(
623 b: bool,
624 opt_token: Option<Token>,
625 instance_id: InstanceId,
626) -> bool {
627 b ==>
628 opt_token.is_some() && opt_token.unwrap().instance_id() == instance_id
629}
630
631}