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