1#![allow(clippy::collapsible_else_if)]
2#![allow(clippy::multiple_bound_locations)]
3#![allow(clippy::missing_safety_doc)]
4#![allow(clippy::too_many_arguments)]
5#![allow(clippy::clone_on_copy)]
6#![warn(
7 absolute_paths_not_starting_with_crate,
8 explicit_outlives_requirements,
9 deprecated_in_future,
10 keyword_idents,
11 let_underscore_drop,
12 macro_use_extern_crate,
13 non_ascii_idents,
15 noop_method_call,
16 rust_2021_incompatible_closure_captures,
17 rust_2021_incompatible_or_patterns,
18 rust_2021_prefixes_incompatible_syntax,
19 rust_2021_prelude_collisions,
20 rust_2018_idioms,
21 single_use_lifetimes,
22 trivial_numeric_casts,
23 unit_bindings,
24 unreachable_pub,
25 unsafe_op_in_unsafe_fn,
26 unused_extern_crates,
27 unused_lifetimes,
28 unused_qualifications,
29)]
30
31#[cfg(test)]
32mod tests;
33
34mod system;
35pub use mem::MaybeUninit;
36use num::{One, Signed};
37pub use once_cell::unsync::Lazy;
38use std::{
39 borrow::Borrow,
40 boxed::Box,
41 clone::Clone,
42 cmp::Ordering,
43 collections::{HashMap, HashSet},
44 convert::From,
45 fmt::{Debug, Display, Formatter},
46 hash::{Hash, Hasher},
47 mem,
48 ops::{Add, Deref, Fn, Sub},
49 ptr::NonNull,
50 vec::Vec,
51};
52
53#[cfg(not(feature = "small-int"))]
54mod big_int;
55#[cfg(not(feature = "small-int"))]
56pub use big_int::*;
57
58#[cfg(feature = "small-int")]
59mod small_int;
60#[cfg(feature = "small-int")]
61pub use small_int::*;
62
63#[cfg(not(feature = "sync"))]
64pub use ::std::{
65 cell::RefCell,
66 rc::{Rc, Weak},
67};
68
69#[cfg(feature = "sync")]
70pub use ::std::sync::{Arc as Rc, Mutex as RefCell, Weak};
71
72pub use system::*;
73
74pub use itertools;
75pub use num::FromPrimitive;
76pub use num::NumCast;
77pub use num::ToPrimitive;
78pub use num::Zero;
79pub use std::convert::Into;
80
81pub use ::std::any::Any;
82pub use ::std::marker::Send;
83pub use ::std::marker::Sync;
84
85#[cfg(not(feature = "sync"))]
86pub type DynAny = dyn Any;
87#[cfg(feature = "sync")]
88pub type DynAny = dyn Any + Send + Sync;
89
90#[cfg(not(feature = "sync"))]
91pub use ::std::cell::UnsafeCell;
92
93#[cfg(feature = "sync")]
94pub struct UnsafeCell<T: ?Sized> {
95 data: ::std::cell::UnsafeCell<T>, }
97#[cfg(feature = "sync")]
101unsafe impl<T: ?Sized> Sync for UnsafeCell<T> where T: Send {}
102#[cfg(feature = "sync")]
103impl<T: Sized> UnsafeCell<T> {
104 pub fn new(data: T) -> Self {
105 UnsafeCell {
106 data: ::std::cell::UnsafeCell::new(data),
107 }
108 }
109}
110#[cfg(feature = "sync")]
111impl<T: ?Sized> UnsafeCell<T> {
112 pub fn get(&self) -> *mut T {
113 ::std::cell::UnsafeCell::get(&self.data)
114 }
115 pub fn raw_get(this: *const UnsafeCell<T>) -> *mut T {
116 unsafe { ::std::cell::UnsafeCell::raw_get(&(*this).data) }
117 }
118}
119
120pub type SizeT = usize;
122
123#[cfg(not(feature = "sync"))]
124pub trait DafnyType: Clone + DafnyPrint + 'static {}
125#[cfg(feature = "sync")]
126pub trait DafnyType: Clone + DafnyPrint + Send + Sync + 'static {}
127
128#[cfg(not(feature = "sync"))]
129impl<T> DafnyType for T where T: Clone + DafnyPrint + 'static {}
130#[cfg(feature = "sync")]
131impl<T> DafnyType for T where T: Clone + DafnyPrint + Send + Sync + 'static {}
132
133pub trait DafnyTypeEq: DafnyType + Hash + Eq {}
134
135impl<T> DafnyTypeEq for T where T: DafnyType + Hash + Eq {}
136
137pub trait NontrivialDefault {
139 fn nontrivial_default() -> Self;
140}
141
142pub mod dafny_runtime_conversions {
143 use crate::DafnyType;
144 use crate::DafnyTypeEq;
145 pub type DafnyInt = crate::DafnyInt;
146 pub type DafnySequence<T> = crate::Sequence<T>;
147 pub type DafnyMap<K, V> = crate::Map<K, V>;
148 pub type DafnySet<T> = crate::Set<T>;
149 pub type DafnyMultiset<T> = crate::Multiset<T>;
150 pub type DafnyBool = bool;
151 pub type DafnyChar = crate::DafnyChar;
152 pub type DafnyCharUTF16 = crate::DafnyCharUTF16;
153
154 use ::std::collections::HashMap;
155 use ::std::collections::HashSet;
156 use ::std::hash::Hash;
157
158 pub use super::Rc;
159
160 pub mod object {
161 pub use super::Rc;
162 pub type DafnyClass<T> = crate::Object<T>;
163 pub type DafnyArray<T> = crate::Object<[T]>;
164 pub type DafnyArray2<T> = crate::Object<crate::Array2<T>>;
165 pub type DafnyArray3<T> = crate::Object<crate::Array3<T>>;
166 pub fn dafny_class_to_struct<T: Clone>(ptr: DafnyClass<T>) -> T {
168 let t: &T = crate::rd!(ptr);
169 t.clone()
170 }
171 pub fn dafny_class_to_boxed_struct<T: Clone>(ptr: DafnyClass<T>) -> Box<T> {
172 Box::new(dafny_class_to_struct(ptr))
173 }
174 pub unsafe fn dafny_class_to_rc_struct<T: Clone>(ptr: DafnyClass<T>) -> Rc<T> {
175 unsafe { crate::rcmut::to_rc(ptr.0.unwrap()) }
176 }
177 pub fn struct_to_dafny_class<T>(t: T) -> DafnyClass<T> {
178 crate::Object::new(t)
179 }
180 pub fn boxed_struct_to_dafny_class<T>(t: Box<T>) -> DafnyClass<T> {
181 struct_to_dafny_class(*t)
182 }
183 pub unsafe fn rc_struct_to_dafny_class<T: ?Sized>(t: Rc<T>) -> DafnyClass<T> {
184 unsafe { crate::Object::from_rc(t) }
185 }
186 pub unsafe fn dafny_array_to_vec<T: Clone>(ptr: DafnyArray<T>) -> Vec<T> {
188 ptr.as_ref().to_vec()
189 }
190 pub fn vec_to_dafny_array<T: Clone>(array: Vec<T>) -> DafnyArray<T> {
191 unsafe { crate::Object::from_rc(Rc::from(array.into_boxed_slice())) }
193 }
194 pub unsafe fn dafny_array2_to_vec<T: Clone>(ptr: DafnyArray2<T>) -> Vec<Vec<T>> {
195 crate::rd!(ptr).to_vec()
196 }
197 }
198
199 pub mod ptr {
200 pub use super::Rc;
201 pub type DafnyClass<T> = crate::Ptr<T>;
202 pub type DafnyArray<T> = crate::Ptr<[T]>;
203 pub type DafnyArray2<T> = crate::Ptr<crate::Array2<T>>;
204 pub type DafnyArray3<T> = crate::Ptr<crate::Array3<T>>;
205 pub unsafe fn dafny_class_to_struct<T: Clone>(ptr: DafnyClass<T>) -> T {
207 unsafe { *dafny_class_to_boxed_struct(ptr) }
208 }
209 pub unsafe fn dafny_class_to_boxed_struct<T: Clone>(ptr: DafnyClass<T>) -> Box<T> {
210 unsafe { Box::from_raw(crate::Ptr::into_raw(ptr)) }
211 }
212 pub fn struct_to_dafny_class<T>(t: T) -> DafnyClass<T> {
213 boxed_struct_to_dafny_class(Box::new(t))
214 }
215 pub fn boxed_struct_to_dafny_class<T>(t: Box<T>) -> DafnyClass<T> {
216 crate::Ptr::from_raw_nonnull(Box::into_raw(t))
217 }
218 pub unsafe fn dafny_array_to_vec<T: Clone>(ptr: DafnyArray<T>) -> Vec<T> {
220 ptr.as_ref().to_vec()
221 }
222 pub fn vec_to_dafny_array<T: Clone>(array: Vec<T>) -> DafnyArray<T> {
223 crate::Ptr::from_box(array.into_boxed_slice())
224 }
225 pub unsafe fn dafny_array2_to_vec<T: Clone>(ptr: DafnyArray2<T>) -> Vec<Vec<T>> {
226 unsafe { Box::from_raw(crate::Ptr::into_raw(ptr)).to_vec() }
227 }
228 }
229
230 pub fn dafny_sequence_to_vec<T, X>(s: &DafnySequence<T>, elem_converter: fn(&T) -> X) -> Vec<X>
231 where
232 T: DafnyType,
233 {
234 let mut array: Vec<T> = Vec::with_capacity(s.cardinality_usize());
235 DafnySequence::<T>::append_recursive(&mut array, s);
236 array.iter().map(elem_converter).collect()
237 }
238
239 pub fn vec_to_dafny_sequence<T, X>(
241 array: &Vec<X>,
242 elem_converter: fn(&X) -> T,
243 ) -> DafnySequence<T>
244 where
245 T: DafnyType,
246 {
247 let mut result: Vec<T> = Vec::with_capacity(array.len());
248 for elem in array.iter() {
249 result.push(elem_converter(elem));
250 }
251 DafnySequence::<T>::from_array_owned(result)
252 }
253
254 pub fn dafny_map_to_hashmap<K, V, K2, V2>(
255 m: &DafnyMap<K, V>,
256 converter_k: fn(&K) -> K2,
257 converter_v: fn(&V) -> V2,
258 ) -> HashMap<K2, V2>
259 where
260 K: DafnyTypeEq,
261 V: DafnyTypeEq,
262 K2: Eq + Hash,
263 V2: Clone,
264 {
265 m.to_hashmap_owned(converter_k, converter_v)
266 }
267
268 pub fn hashmap_to_dafny_map<K2, V2, K, V>(
269 map: &HashMap<K2, V2>,
270 converter_k: fn(&K2) -> K,
271 converter_v: fn(&V2) -> V,
272 ) -> DafnyMap<K, V>
273 where
274 K: DafnyTypeEq,
275 V: DafnyTypeEq,
276 K2: Eq + Hash,
277 V2: Clone,
278 {
279 DafnyMap::<K, V>::from_hashmap(map, converter_k, converter_v)
280 }
281
282 pub mod unicode_chars_true {
284 use crate::Sequence;
285
286 type DafnyChar = crate::DafnyChar;
287 type DafnyString = Sequence<DafnyChar>;
288
289 pub fn string_to_dafny_string(s: &str) -> DafnyString {
290 Sequence::from_array_owned(s.chars().map(crate::DafnyChar).collect())
291 }
292 pub fn dafny_string_to_string(s: &DafnyString) -> String {
293 let characters = s.to_array();
294 characters.iter().map(|v| v.0).collect::<String>()
295 }
296 }
297
298 pub mod unicode_chars_false {
300 use crate::Sequence;
301
302 type DafnyCharUTF16 = crate::DafnyCharUTF16;
303 type DafnyString = Sequence<DafnyCharUTF16>;
304
305 pub fn string_to_dafny_string(s: &str) -> DafnyString {
306 Sequence::from_array_owned(s.encode_utf16().map(crate::DafnyCharUTF16).collect())
307 }
308 pub fn dafny_string_to_string(s: &DafnyString) -> String {
309 let characters = s
310 .to_array()
311 .as_ref()
312 .iter()
313 .map(|v| v.0)
314 .collect::<Vec<_>>();
315 String::from_utf16_lossy(&characters)
316 }
317 }
318
319 pub fn set_to_dafny_set<U, T: DafnyTypeEq>(
320 set: &HashSet<U>,
321 converter: fn(&U) -> T,
322 ) -> DafnySet<T> {
323 DafnySet::from_iterator(set.iter().map(converter))
324 }
325 pub fn dafny_set_to_set<T, U>(set: &DafnySet<T>, converter: fn(&T) -> U) -> HashSet<U>
326 where
327 T: DafnyTypeEq,
328 U: Clone + Eq + Hash,
329 {
330 let mut result: HashSet<U> = HashSet::new();
331 for s in set.data.iter() {
332 result.insert(converter(s));
333 }
334 result
335 }
336
337 pub fn dafny_multiset_to_owned_vec<T, U>(
338 ms: &DafnyMultiset<T>,
339 converter: fn(&T) -> U,
340 ) -> Vec<U>
341 where
342 T: DafnyTypeEq,
343 U: Clone + Eq,
344 {
345 let mut result: Vec<U> = Vec::new();
346 for s in ms.data.iter() {
347 for _ in 0..s.1.as_usize() {
349 result.push(converter(s.0));
350 }
351 }
352 result
353 }
354
355 pub fn vec_to_dafny_multiset<T, U>(vec: &Vec<U>, converter: fn(&U) -> T) -> DafnyMultiset<T>
356 where
357 T: DafnyTypeEq,
358 U: Clone + Eq + Hash,
359 {
360 DafnyMultiset::from_iterator(vec.iter().map(|u: &U| converter(u)))
361 }
362}
363
364pub trait DafnyUsize {
365 fn into_usize(self) -> usize;
366}
367
368impl DafnyInt {
373 pub fn as_usize(&self) -> usize {
374 self.to_usize().unwrap()
375 }
376}
377
378impl DafnyUsize for DafnyInt {
379 fn into_usize(self) -> usize {
380 self.as_usize()
381 }
382}
383
384#[macro_export]
387macro_rules! truncate {
388 ($x:expr, $t:ty) => {
389 <$crate::DafnyInt as ::std::convert::Into<$t>>::into($x)
390 };
391}
392
393impl NontrivialDefault for DafnyInt {
394 fn nontrivial_default() -> Self {
395 Self::default()
396 }
397}
398
399impl From<&[u8]> for DafnyInt {
400 fn from(number: &[u8]) -> Self {
401 DafnyInt::parse_bytes(number, 10)
402 }
403}
404
405impl<const N: usize> From<&[u8; N]> for DafnyInt {
407 fn from(number: &[u8; N]) -> Self {
408 DafnyInt::parse_bytes(number, 10)
409 }
410}
411
412impl From<char> for DafnyInt {
413 fn from(c: char) -> Self {
414 let cu32: u32 = c.into();
415 int!(cu32)
416 }
417}
418
419impl From<DafnyChar> for DafnyInt {
420 fn from(c: DafnyChar) -> Self {
421 int!(c.0)
422 }
423}
424
425impl From<DafnyCharUTF16> for DafnyInt {
426 fn from(c: DafnyCharUTF16) -> Self {
427 int!(c.0)
428 }
429}
430
431impl<T: DafnyTypeEq> Eq for Sequence<T> {}
436
437impl<T: DafnyType> Add<&Sequence<T>> for &Sequence<T> {
438 type Output = Sequence<T>;
439
440 fn add(self, rhs: &Sequence<T>) -> Self::Output {
441 Sequence::new_concat_sequence(self, rhs)
442 }
443}
444
445impl<T: DafnyType + Hash> Hash for Sequence<T> {
446 fn hash<H: Hasher>(&self, state: &mut H) {
447 self.cardinality_usize().hash(state);
448 let array = self.to_array();
449 for elt in array.iter() {
451 elt.hash(state);
452 }
453 }
454}
455
456#[derive(Clone)]
458pub enum Sequence<T>
459where
460 T: DafnyType,
461{
462 ArraySequence {
463 values: Rc<Vec<T>>,
466 },
467 ConcatSequence {
468 left: Rc<RefCell<Sequence<T>>>,
469 right: Rc<RefCell<Sequence<T>>>,
470 length: SizeT,
471 cache: Rc<RefCell<Option<Rc<Vec<T>>>>>,
472 },
473}
474
475impl<T> Sequence<T>
476where
477 T: DafnyType,
478{
479 pub fn from_array(values: Ptr<[T]>) -> Sequence<T> {
480 let mut v = vec![];
481 v.extend_from_slice(read!(values));
482 Sequence::ArraySequence { values: Rc::new(v) }
483 }
484 pub fn from_array_object(values: &Object<[T]>) -> Sequence<T> {
485 let mut v = vec![];
486 v.extend_from_slice(rd!(values));
487 Sequence::ArraySequence { values: Rc::new(v) }
488 }
489 pub fn from_array_slice(values: Ptr<[T]>, start: &DafnyInt, end: &DafnyInt) -> Sequence<T> {
490 let mut v = vec![];
491 v.extend_from_slice(&read!(values)[start.to_usize().unwrap()..end.to_usize().unwrap()]);
492 Sequence::ArraySequence { values: Rc::new(v) }
493 }
494 pub fn from_array_slice_object(
495 values: &Object<[T]>,
496 start: &DafnyInt,
497 end: &DafnyInt,
498 ) -> Sequence<T> {
499 let mut v = vec![];
500 v.extend_from_slice(&rd!(values)[start.to_usize().unwrap()..end.to_usize().unwrap()]);
501 Sequence::ArraySequence { values: Rc::new(v) }
502 }
503 pub fn from_array_take(values: Ptr<[T]>, n: &DafnyInt) -> Sequence<T> {
504 let mut v = vec![];
505 v.extend_from_slice(&read!(values)[..n.to_usize().unwrap()]);
506 Sequence::ArraySequence { values: Rc::new(v) }
507 }
508 pub fn from_array_take_object(values: &Object<[T]>, n: &DafnyInt) -> Sequence<T> {
509 let mut v = vec![];
510 v.extend_from_slice(&rd!(values)[..n.to_usize().unwrap()]);
511 Sequence::ArraySequence { values: Rc::new(v) }
512 }
513 pub fn from_array_drop(values: Ptr<[T]>, n: &DafnyInt) -> Sequence<T> {
514 let mut v = vec![];
515 v.extend_from_slice(&read!(values)[n.to_usize().unwrap()..]);
516 Sequence::ArraySequence { values: Rc::new(v) }
517 }
518 pub fn from_array_drop_object(values: &Object<[T]>, n: &DafnyInt) -> Sequence<T> {
519 let mut v = vec![];
520 v.extend_from_slice(&rd!(values)[n.to_usize().unwrap()..]);
521 Sequence::ArraySequence { values: Rc::new(v) }
522 }
523 pub fn from_array_owned(values: Vec<T>) -> Sequence<T> {
524 Sequence::ArraySequence {
525 values: Rc::new(values),
526 }
527 }
528 pub(crate) fn new_concat_sequence(left: &Sequence<T>, right: &Sequence<T>) -> Sequence<T> {
529 Sequence::ConcatSequence {
530 left: Rc::new(RefCell::new(left.clone())),
531 right: Rc::new(RefCell::new(right.clone())),
532 length: left.cardinality_usize() + right.cardinality_usize(),
533 cache: Rc::new(RefCell::new(None)),
534 }
535 }
536 pub fn to_array(&self) -> Rc<Vec<T>> {
537 match self {
539 Sequence::ArraySequence { values, .. } =>
540 {
542 Rc::clone(values)
543 }
544 Sequence::ConcatSequence {
545 length,
546 cache,
547 left,
548 right,
549 } => {
550 #[cfg(feature = "sync")]
551 {
552 let guard = cache.as_ref().lock().unwrap();
553 let cache_borrow: Option<&Rc<Vec<T>>> = guard.as_ref();
554 if let Some(cache) = cache_borrow {
555 return Rc::clone(cache);
556 }
557 }
558
559 #[cfg(not(feature = "sync"))]
560 {
561 let cache_opened = cache.as_ref().clone();
562 let cache_opened_borrowed = cache_opened.borrow();
563 let cache_borrow: Option<&Rc<Vec<T>>> = cache_opened_borrowed.as_ref();
564 if let Some(cache) = cache_borrow {
565 return Rc::clone(cache);
566 }
567 }
568 let mut array: Vec<T> = Vec::with_capacity(*length);
571 Sequence::<T>::append_recursive(&mut array, self);
572 let result = Rc::new(array);
573 #[cfg(not(feature = "sync"))]
574 {
575 *left.borrow_mut() = seq!();
576 *right.borrow_mut() = seq!();
577 }
578 #[cfg(feature = "sync")]
579 {
580 let mut left_guard = left.as_ref().lock().unwrap();
581 let mut right_guard = right.as_ref().lock().unwrap();
582 *left_guard = seq!();
583 *right_guard = seq!();
584 }
585 #[cfg(not(feature = "sync"))]
586 let mut guard = cache.borrow_mut();
587 #[cfg(feature = "sync")]
588 let mut guard = cache.as_ref().lock().unwrap();
589 *guard = Some(result.clone());
590 result
591 }
592 }
593 }
594
595 pub fn append_simple(array: &mut Vec<T>, this: &Sequence<T>) -> bool {
596 match this {
597 Sequence::ArraySequence { values, .. } => {
598 for value in values.iter() {
599 array.push(value.clone());
600 }
601 true
602 }
603 _ => false,
604 }
605 }
606
607 pub fn append_recursive(array: &mut Vec<T>, this: &Sequence<T>) {
608 let mut this_ptr: *const Sequence<T> = this;
609 loop {
610 match unsafe { &*this_ptr } {
612 Sequence::ArraySequence { values, .. } => {
613 for value in values.iter() {
614 array.push(value.clone());
615 }
616 return;
617 }
618 Sequence::ConcatSequence {
619 cache: boxed,
620 left,
621 right,
622 ..
623 } =>
624 {
626 #[cfg(feature = "sync")]
627 let into_boxed = boxed.as_ref();
628 #[cfg(feature = "sync")]
629 let into_boxed_borrowed = into_boxed;
630 #[cfg(feature = "sync")]
631 let guard = into_boxed_borrowed.lock().unwrap();
632 #[cfg(feature = "sync")]
633 let borrowed: Option<&Rc<Vec<T>>> = guard.as_ref();
634
635 #[cfg(not(feature = "sync"))]
636 let into_boxed = boxed.as_ref().clone();
637 #[cfg(not(feature = "sync"))]
638 let into_boxed_borrowed = into_boxed.borrow();
639 #[cfg(not(feature = "sync"))]
640 let borrowed: Option<&Rc<Vec<T>>> = into_boxed_borrowed.as_ref();
641 if let Some(values) = borrowed.as_ref() {
642 for value in values.iter() {
643 array.push(value.clone());
644 }
645 return;
646 }
647 #[cfg(not(feature = "sync"))]
648 {
649 let left_empty = left.as_ref().borrow().cardinality_usize() == 0;
650 let right_empty = right.as_ref().borrow().cardinality_usize() == 0;
651 if left_empty && right_empty {
652 return;
653 } else if left_empty {
654 this_ptr = right.as_ref().as_ptr();
655 } else if right_empty {
656 this_ptr = left.as_ref().as_ptr();
657 } else {
658 if !Sequence::<T>::append_simple(array, &left.as_ref().borrow()) {
659 Sequence::<T>::append_recursive(array, &left.as_ref().borrow());
660 }
661 this_ptr = right.as_ref().as_ptr();
662 }
663 }
664 #[cfg(feature = "sync")]
665 {
666 let left_guard = left.as_ref().lock().unwrap();
667 let right_guard = right.as_ref().lock().unwrap();
668 let left_empty: bool = left_guard.cardinality_usize() == 0;
669 let right_empty: bool = right_guard.cardinality_usize() == 0;
670 if left_empty && right_empty {
671 return;
672 } else if left_empty {
673 this_ptr = right_guard.deref();
674 } else if right_empty {
675 this_ptr = left_guard.deref();
676 } else {
677 if !Sequence::<T>::append_simple(array, &left_guard) {
678 Sequence::<T>::append_recursive(array, &left_guard);
679 }
680 this_ptr = right_guard.deref();
681 }
682 }
683 }
684 }
685 }
686 }
687 pub fn cardinality_usize(&self) -> SizeT {
689 match self {
690 Sequence::ArraySequence { values, .. } =>
691 {
693 values.len()
694 }
695 Sequence::ConcatSequence { length, .. } => *length,
696 }
697 }
698 pub fn cardinality(&self) -> DafnyInt {
699 DafnyInt::from_usize(self.cardinality_usize())
700 }
701 pub fn get_usize(&self, index: SizeT) -> T {
702 let array = self.to_array();
703 array[index].clone()
704 }
705
706 pub fn slice(&self, start: &DafnyInt, end: &DafnyInt) -> Sequence<T> {
707 let start_index = start.as_usize();
708 let end_index = end.as_usize();
709 Sequence::from_array_owned(self.to_array()[start_index..end_index].to_vec())
710 }
711 pub fn take(&self, end: &DafnyInt) -> Sequence<T> {
712 let end_index = end.as_usize();
713 Sequence::from_array_owned(self.to_array()[..end_index].to_vec())
714 }
715 pub fn drop(&self, start: &DafnyInt) -> Sequence<T> {
716 let start_index = start.as_usize();
717 Sequence::from_array_owned(self.to_array()[start_index..].to_vec())
718 }
719
720 pub fn update_index(&self, index: &DafnyInt, value: &T) -> Self {
721 let mut result = self.to_array().as_ref().clone();
722 result[index.as_usize()] = value.clone();
723 Sequence::from_array_owned(result)
724 }
725
726 pub fn concat(&self, other: &Sequence<T>) -> Sequence<T> {
727 Sequence::new_concat_sequence(self, other)
728 }
729
730 pub fn get(&self, index: &DafnyInt) -> T {
731 self.get_usize(index.as_usize())
732 }
733 pub fn iter(&self) -> SequenceIter<T> {
734 SequenceIter {
735 array: self.to_array(),
736 index: 0,
737 }
738 }
739}
740
741pub struct SequenceIter<T: Clone> {
742 array: Rc<Vec<T>>,
743 index: SizeT,
744}
745impl<T: Clone> Iterator for SequenceIter<T> {
746 type Item = T;
747 fn next(&mut self) -> Option<Self::Item> {
748 if self.index < self.array.len() {
749 let result = self.array[self.index].clone();
750 self.index += 1;
751 Some(result)
752 } else {
753 None
754 }
755 }
756}
757
758impl<T: DafnyType> Default for Sequence<T> {
759 fn default() -> Self {
760 Sequence::from_array_owned(vec![])
761 }
762}
763impl<T: DafnyType> NontrivialDefault for Sequence<T> {
764 fn nontrivial_default() -> Self {
765 Self::default()
766 }
767}
768
769impl<T: DafnyTypeEq> Sequence<T> {
770 pub fn as_dafny_multiset(&self) -> Multiset<T> {
771 Multiset::from_array(&self.to_array())
772 }
773}
774
775impl<T: DafnyType> FromIterator<T> for Sequence<T> {
777 fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
778 Sequence::from_array_owned(iter.into_iter().collect())
779 }
780}
781
782impl<T: DafnyTypeEq> Sequence<T> {
783 pub fn contains(&self, value: &T) -> bool {
784 self.to_array().contains(value)
785 }
786}
787impl<T> PartialEq<Sequence<T>> for Sequence<T>
788where
789 T: DafnyType + PartialEq<T>,
790{
791 fn eq(&self, other: &Sequence<T>) -> bool {
792 let values: Rc<Vec<T>> = self.to_array();
794 if other.cardinality_usize() != values.len() {
795 return false;
796 }
797 for (i, value) in values.iter().enumerate() {
798 if value != &other.get_usize(i) {
799 return false;
800 }
801 }
802 true
803 }
804}
805
806impl<T: DafnyTypeEq> PartialOrd for Sequence<T> {
807 fn partial_cmp(&self, other: &Sequence<T>) -> Option<Ordering> {
808 match self.cardinality_usize().cmp(&other.cardinality_usize()) {
810 Ordering::Equal => {
811 if self == other {
812 Some(Ordering::Equal)
813 } else {
814 None
815 }
816 }
817 Ordering::Less => {
818 for i in 0..self.cardinality_usize() {
819 if self.get_usize(i) != other.get_usize(i) {
820 return None;
821 }
822 }
823 Some(Ordering::Less)
824 }
825 Ordering::Greater => {
826 for i in 0..other.cardinality_usize() {
827 if self.get_usize(i) != other.get_usize(i) {
828 return None;
829 }
830 }
831 Some(Ordering::Greater)
832 }
833 }
834 }
835}
836
837impl<V: DafnyType> DafnyPrint for Sequence<V> {
838 fn fmt_print(&self, f: &mut Formatter<'_>, _in_seq: bool) -> std::fmt::Result {
839 if !V::is_char() {
840 write!(f, "[")?;
841 }
842 let mut first = true;
843 for value in self.to_array().iter() {
844 if !first && !V::is_char() {
845 write!(f, ", ")?;
846 }
847 first = false;
848 value.fmt_print(f, true)?;
849 }
850 if !V::is_char() {
851 write!(f, "]")
852 } else {
853 write!(f, "")
854 }
855 }
856}
857
858impl<V: DafnyType> Debug for Sequence<V> {
859 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
860 self.fmt_print(f, false)
861 }
862}
863
864#[derive(Clone)]
869pub struct Map<K, V>
870where
871 K: DafnyTypeEq,
872 V: DafnyType,
873{
874 data: Rc<HashMap<K, V>>,
875}
876
877impl<K: DafnyTypeEq, V: DafnyType> Default for Map<K, V> {
878 fn default() -> Self {
879 Map {
880 data: Rc::new(HashMap::new()),
881 }
882 }
883}
884
885impl<K: DafnyTypeEq, V: DafnyType> NontrivialDefault for Map<K, V> {
886 fn nontrivial_default() -> Self {
887 Self::default()
888 }
889}
890
891impl<K: DafnyTypeEq, V: DafnyType> Hash for Map<K, V> {
892 fn hash<H: Hasher>(&self, state: &mut H) {
893 self.data.len().hash(state); }
895}
896
897impl<K, V> PartialEq<Map<K, V>> for Map<K, V>
898where
899 K: DafnyTypeEq,
900 V: DafnyTypeEq,
901{
902 fn eq(&self, other: &Map<K, V>) -> bool {
903 if self.data.len() != other.data.len() {
904 return false;
905 }
906 for (k, v) in self.data.iter() {
907 if other.data.get(k) != Some(v) {
908 return false;
909 }
910 }
911 true
912 }
913}
914
915impl<K: DafnyTypeEq, V: DafnyTypeEq> Eq for Map<K, V> {}
916
917impl<K: DafnyTypeEq, V: DafnyType> Map<K, V> {
918 pub fn new_empty() -> Map<K, V> {
919 Map {
920 data: Rc::new(HashMap::new()),
921 }
922 }
923 pub fn from_array(values: &Vec<(K, V)>) -> Map<K, V> {
924 Self::from_iterator(values.iter().map(|(k, v)| (k.clone(), v.clone())))
925 }
926 pub fn from_iterator<I>(data: I) -> Map<K, V>
927 where
928 I: Iterator<Item = (K, V)>,
929 {
930 let mut result: HashMap<K, V> = HashMap::new();
931 for (k, v) in data {
932 result.insert(k, v);
933 }
934 Self::from_hashmap_owned(result)
935 }
936 pub fn from_hashmap_owned(values: HashMap<K, V>) -> Map<K, V> {
937 Map {
938 data: Rc::new(values),
939 }
940 }
941 pub fn to_hashmap_owned<K2, V2>(
942 &self,
943 converter_k: fn(&K) -> K2,
944 converter_v: fn(&V) -> V2,
945 ) -> HashMap<K2, V2>
946 where
947 K2: Eq + Hash,
948 V2: Clone,
949 {
950 let mut result: HashMap<K2, V2> = HashMap::new();
951 for (k, v) in self.data.iter() {
952 result.insert(converter_k(k), converter_v(v));
953 }
954 result
955 }
956 pub fn cardinality_usize(&self) -> usize {
957 self.data.len()
958 }
959 pub fn cardinality(&self) -> DafnyInt {
960 DafnyInt::from_usize(self.cardinality_usize())
961 }
962 pub fn contains(&self, key: &K) -> bool {
963 self.data.contains_key(key)
964 }
965 pub fn get_or_none(&self, key: &K) -> Option<V> {
966 self.data.get(key).cloned()
967 }
968 pub fn get(&self, key: &K) -> V {
970 self.data[key].clone()
971 }
972 pub fn merge(&self, other: &Map<K, V>) -> Map<K, V> {
973 if other.cardinality_usize() == 0 {
974 return self.clone();
975 }
976 if self.cardinality_usize() == 0 {
977 return other.clone();
978 }
979 let mut new_data = (*other.data).clone();
980 for (k, v) in self.data.iter() {
982 if !other.contains(k) {
983 new_data.insert(k.clone(), v.clone());
984 }
985 }
986 Self::from_hashmap_owned(new_data)
987 }
988 pub fn subtract(&self, keys: &Set<K>) -> Self {
989 if keys.cardinality_usize() == 0 {
990 return self.clone();
991 }
992 let mut result: HashMap<K, V> = HashMap::new();
993 for (k, v) in self.data.iter() {
994 if !keys.contains(k) {
995 result.insert(k.clone(), v.clone());
996 }
997 }
998 Self::from_hashmap_owned(result)
999 }
1000
1001 pub fn from_hashmap<K2, V2>(
1002 map: &HashMap<K2, V2>,
1003 converter_k: fn(&K2) -> K,
1004 converter_v: fn(&V2) -> V,
1005 ) -> Map<K, V>
1006 where
1007 K: DafnyTypeEq,
1008 V: DafnyTypeEq,
1009 K2: Eq + Hash,
1010 V2: Clone,
1011 {
1012 let mut result: HashMap<K, V> = HashMap::new();
1013 for (k, v) in map.iter() {
1014 result.insert(converter_k(k), converter_v(v));
1015 }
1016 Map {
1017 data: Rc::new(result),
1018 }
1019 }
1020 pub fn keys(&self) -> Set<K> {
1021 let mut result: HashSet<K> = HashSet::new();
1022 for (k, _) in self.data.iter() {
1023 result.insert(k.clone());
1024 }
1025 Set::from_hashset_owned(result)
1026 }
1027
1028 pub fn update_index(&self, index: &K, value: &V) -> Self {
1029 let mut result = self.data.as_ref().clone();
1030 result.insert(index.clone(), value.clone());
1031 Map::from_hashmap_owned(result)
1032 }
1033
1034 pub fn update_index_owned(&self, index: K, value: V) -> Self {
1035 let mut result = self.data.as_ref().clone();
1036 result.insert(index, value);
1037 Map::from_hashmap_owned(result)
1038 }
1039
1040 pub fn iter_raw(&self) -> std::collections::hash_map::Iter<'_, K, V> {
1041 self.data.iter()
1042 }
1043
1044 pub fn iter(&self) -> impl Iterator<Item = K> + '_ {
1045 self.data.iter().map(|(k, _v)| k).cloned()
1046 }
1047}
1048
1049impl<K: DafnyTypeEq, V: DafnyTypeEq> Map<K, V> {
1050 pub fn values(&self) -> Set<V> {
1051 let mut result: Vec<V> = Vec::new();
1052 for (_, v) in self.data.iter() {
1053 result.push(v.clone());
1054 }
1055 Set::from_array(&result)
1056 }
1057 pub fn items(&self) -> Set<(K, V)> {
1058 let mut result: Vec<(K, V)> = Vec::new();
1059 for (k, v) in self.data.iter() {
1060 result.push((k.clone(), v.clone()));
1061 }
1062 Set::from_array(&result)
1063 }
1064}
1065
1066impl<K: DafnyTypeEq> Map<K, DafnyInt> {
1067 pub fn as_dafny_multiset(&self) -> Multiset<K> {
1068 Multiset::from_hashmap(&self.data)
1069 }
1070}
1071
1072pub struct MapBuilder<K, V>
1073where
1074 K: Clone + Eq + Hash,
1075 V: Clone,
1076{
1077 data: HashMap<K, V>,
1078}
1079
1080impl<K, V> Default for MapBuilder<K, V>
1081where
1082 K: DafnyTypeEq,
1083 V: DafnyType,
1084{
1085 fn default() -> Self {
1086 Self::new()
1087 }
1088}
1089
1090impl<K, V> MapBuilder<K, V>
1091where
1092 K: DafnyTypeEq,
1093 V: DafnyType,
1094{
1095 pub fn new() -> MapBuilder<K, V> {
1096 MapBuilder {
1097 data: HashMap::new(),
1098 }
1099 }
1100 pub fn add(&mut self, key: &K, value: &V) {
1101 self.data.insert(key.clone(), value.clone());
1103 }
1104 pub fn build(self) -> Map<K, V> {
1105 Map::from_hashmap_owned(self.data)
1106 }
1107}
1108
1109impl<K, V> DafnyPrint for Map<K, V>
1110where
1111 K: DafnyTypeEq,
1112 V: DafnyType,
1113{
1114 fn fmt_print(&self, f: &mut Formatter<'_>, in_seq: bool) -> std::fmt::Result {
1115 f.write_str("map[")?;
1116 let mut first = true;
1117 for (k, v) in self.data.iter() {
1118 if !first {
1119 f.write_str(", ")?;
1120 }
1121 first = false;
1122 k.fmt_print(f, in_seq)?;
1123 f.write_str(" := ")?;
1124 v.fmt_print(f, in_seq)?;
1125 }
1126 f.write_str("]")
1127 }
1128}
1129
1130impl<K, V> Debug for Map<K, V>
1131where
1132 K: DafnyTypeEq,
1133 V: DafnyTypeEq,
1134{
1135 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
1136 self.fmt_print(f, false)
1137 }
1138}
1139
1140#[derive(Clone)]
1145pub struct Set<V: DafnyTypeEq> {
1146 data: Rc<HashSet<V>>,
1147}
1148
1149impl<T: DafnyTypeEq> ::std::hash::Hash for Set<T> {
1151 fn hash<_H: ::std::hash::Hasher>(&self, _state: &mut _H) {
1152 self.cardinality_usize().hash(_state)
1153 }
1154}
1155
1156impl<T: DafnyTypeEq> Eq for Set<T> {}
1157
1158impl<T> Default for Set<T>
1159where
1160 T: DafnyTypeEq,
1161{
1162 fn default() -> Self {
1163 Self::new_empty()
1164 }
1165}
1166impl<T: DafnyTypeEq> NontrivialDefault for Set<T> {
1167 fn nontrivial_default() -> Self {
1168 Self::default()
1169 }
1170}
1171
1172impl<V> PartialEq<Set<V>> for Set<V>
1173where
1174 V: DafnyTypeEq,
1175{
1176 fn eq(&self, other: &Set<V>) -> bool {
1177 if self.cardinality_usize() != other.cardinality_usize() {
1180 false
1181 } else {
1182 for value in self.data.iter() {
1183 if !other.contains(value) {
1184 return false;
1185 }
1186 }
1187 for value in other.data.iter() {
1188 if !self.contains(value) {
1189 return false;
1190 }
1191 }
1192 true
1193 }
1194 }
1195}
1196
1197impl<T: DafnyTypeEq> PartialOrd for Set<T> {
1198 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
1199 if self.cardinality_usize() <= other.cardinality_usize() {
1201 for value in self.data.iter() {
1202 if !other.contains(value) {
1203 return None;
1204 }
1205 }
1206 if self.cardinality_usize() == other.cardinality_usize() {
1207 Some(Ordering::Equal)
1208 } else {
1209 Some(Ordering::Less)
1210 }
1211 } else {
1212 for value in other.data.iter() {
1213 if !self.contains(value) {
1214 return None;
1215 }
1216 }
1217 Some(Ordering::Greater)
1218 }
1219 }
1220}
1221
1222impl<V: DafnyTypeEq> Set<V> {
1223 pub fn new_empty() -> Set<V> {
1224 Self::from_hashset_owned(HashSet::new())
1225 }
1226 pub fn from_array(array: &Vec<V>) -> Set<V> {
1227 Self::from_iterator(array.iter().cloned())
1228 }
1229 pub fn from_iterator<I>(data: I) -> Set<V>
1230 where
1231 I: Iterator<Item = V>,
1232 {
1233 let mut set: HashSet<V> = HashSet::new();
1234 for value in data {
1235 set.insert(value);
1236 }
1237 Self::from_hashset_owned(set)
1238 }
1239 pub fn from_sequence(data: &Rc<Sequence<V>>) -> Set<V> {
1240 Self::from_array(data.to_array().borrow())
1241 }
1242 pub fn from_hashset_owned(hashset: HashSet<V>) -> Set<V> {
1243 Set {
1244 data: Rc::new(hashset),
1245 }
1246 }
1247 pub fn cardinality_usize(&self) -> usize {
1248 self.data.len()
1249 }
1250 pub fn cardinality(&self) -> DafnyInt {
1251 DafnyInt::from_usize(self.data.len())
1252 }
1253 pub fn contains(&self, value: &V) -> bool {
1254 self.data.contains(value)
1255 }
1256 pub fn merge(&self, other: &Set<V>) -> Set<V> {
1257 if self.cardinality_usize() == 0 {
1258 return other.clone();
1259 }
1260 if other.cardinality_usize() == 0 {
1261 return self.clone();
1262 }
1263 let mut result = self.data.as_ref().clone();
1264 for value in other.data.iter() {
1266 if !result.contains(value) {
1267 result.insert(value.clone());
1268 }
1269 }
1270 Set::from_hashset_owned(result)
1271 }
1272
1273 pub fn intersect(&self, other: &Set<V>) -> Set<V> {
1274 if self.cardinality_usize() == 0 {
1275 return self.clone();
1276 }
1277 if other.cardinality_usize() == 0 {
1278 return other.clone();
1279 }
1280 let mut result = HashSet::new();
1282
1283 for value in self.data.iter() {
1285 if other.data.contains(value) {
1286 result.insert(value.clone());
1287 }
1288 }
1289 Set::from_hashset_owned(result)
1290 }
1291
1292 pub fn subtract(&self, other: &Set<V>) -> Set<V> {
1293 if self.cardinality_usize() == 0 {
1294 return self.clone();
1295 }
1296 if other.cardinality_usize() == 0 {
1297 return self.clone();
1298 }
1299 let mut result = HashSet::new();
1301
1302 for value in self.data.iter() {
1304 if !other.contains(value) {
1305 result.insert(value.clone());
1306 }
1307 }
1308 Set::from_hashset_owned(result)
1309 }
1310
1311 pub fn disjoint(&self, other: &Set<V>) -> bool {
1312 if self.cardinality_usize() == 0 {
1313 return true;
1314 }
1315 if other.cardinality_usize() == 0 {
1316 return true;
1317 }
1318 if other.data.len() < self.data.len() {
1319 for value in other.data.iter() {
1321 if self.contains(value) {
1322 return false;
1323 }
1324 }
1325 } else {
1326 for value in self.data.iter() {
1328 if other.contains(value) {
1329 return false;
1330 }
1331 }
1332 }
1333 true
1334 }
1335
1336 pub fn equals(&self, other: &Set<V>) -> bool {
1337 if self.cardinality_usize() != other.cardinality_usize() {
1338 return false;
1339 }
1340 for value in other.data.iter() {
1342 if !self.contains(value) {
1343 return false;
1344 }
1345 }
1346 true
1347 }
1348
1349 pub fn elements(&self) -> Set<V> {
1350 self.clone()
1351 }
1352
1353 pub fn as_dafny_multiset(&self) -> Multiset<V> {
1354 Multiset::from_set(self)
1355 }
1356
1357 pub fn iter(&self) -> std::collections::hash_set::Iter<'_, V> {
1358 self.data.iter()
1359 }
1360
1361 pub fn peek(&self) -> V {
1362 self.data.iter().next().unwrap().clone()
1363 }
1364}
1365
1366pub struct SetBuilder<T>
1367where
1368 T: Clone + Eq + Hash,
1369{
1370 data: HashMap<T, bool>,
1371}
1372
1373impl<T: DafnyTypeEq> Default for SetBuilder<T> {
1374 fn default() -> Self {
1375 Self::new()
1376 }
1377}
1378
1379impl<T: DafnyTypeEq> SetBuilder<T> {
1380 pub fn new() -> SetBuilder<T> {
1381 SetBuilder {
1382 data: HashMap::new(),
1383 }
1384 }
1385 pub fn add(&mut self, value: &T) {
1386 self.data.insert(value.clone(), true);
1388 }
1389 pub fn build(self) -> Set<T> {
1390 let mut result: Vec<T> = Vec::new();
1392 for (k, _v) in self.data.iter() {
1393 result.push(k.clone());
1394 }
1395
1396 Set::from_array(&result)
1397 }
1398}
1399
1400impl<V: DafnyTypeEq> DafnyPrint for Set<V> {
1401 fn fmt_print(&self, f: &mut Formatter<'_>, in_seq: bool) -> std::fmt::Result {
1402 f.write_str("{")?;
1403 let mut first = true;
1404 for value in self.data.iter() {
1405 if !first {
1406 f.write_str(", ")?;
1407 }
1408 first = false;
1409 value.fmt_print(f, in_seq)?;
1410 }
1411 f.write_str("}")
1412 }
1413}
1414
1415impl<V> Debug for Set<V>
1416where
1417 V: DafnyTypeEq,
1418{
1419 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
1420 self.fmt_print(f, false)
1421 }
1422}
1423
1424#[derive(Clone)]
1429pub struct Multiset<V: DafnyTypeEq> {
1430 pub data: HashMap<V, DafnyInt>,
1431 pub size: DafnyInt,
1432}
1433
1434impl<V: DafnyTypeEq> Multiset<V> {
1435 pub fn new_empty() -> Multiset<V> {
1436 Self::from_array(&vec![])
1437 }
1438 pub fn get_total(map: &HashMap<V, DafnyInt>) -> DafnyInt {
1439 let mut total = DafnyInt::zero();
1440 for (_, v) in map.iter() {
1441 total = total + v.clone();
1442 }
1443 total
1444 }
1445 pub fn from_hashmap_owned(map: HashMap<V, DafnyInt>) -> Multiset<V> {
1446 Multiset {
1447 size: Self::get_total(&map),
1448 data: map,
1449 }
1450 }
1451 pub fn from_hashmap(map: &HashMap<V, DafnyInt>) -> Multiset<V> {
1452 Self::from_hashmap_owned(map.clone())
1453 }
1454 pub fn from_array(data: &Vec<V>) -> Multiset<V> {
1455 Self::from_iterator(data.iter().cloned())
1456 }
1457 pub fn from_iterator<I>(data: I) -> Multiset<V>
1458 where
1459 I: Iterator<Item = V>,
1460 {
1461 let mut hashmap: HashMap<V, DafnyInt> = HashMap::new();
1462 let mut total: DafnyInt = DafnyInt::zero();
1463 for value in data {
1464 let count = hashmap.entry(value.clone()).or_insert(DafnyInt::zero());
1465 *count = count.clone() + DafnyInt::one();
1466 total = total + DafnyInt::one();
1467 }
1468 Multiset {
1469 data: hashmap,
1470 size: total,
1471 }
1472 }
1473 pub fn from_set(set: &Set<V>) -> Multiset<V> {
1474 Self::from_iterator(set.data.iter().cloned())
1475 }
1476
1477 pub fn cardinality_usize(&self) -> SizeT {
1478 self.size.as_usize()
1479 }
1480 pub fn cardinality(&self) -> DafnyInt {
1481 self.size.clone()
1482 }
1483 pub fn contains(&self, value: &V) -> bool {
1484 self.data.contains_key(value) && self.data.get(value).unwrap() > &DafnyInt::zero()
1485 }
1486 pub fn get(&self, value: &V) -> DafnyInt {
1487 if self.data.contains_key(value) {
1488 self.data.get(value).unwrap().clone()
1489 } else {
1490 DafnyInt::zero()
1491 }
1492 }
1493 pub fn update_count(&self, value: &V, new_count: &DafnyInt) -> Multiset<V> {
1494 let mut result = self.clone();
1495 let old_count = self.get(value);
1496 if new_count == &DafnyInt::zero() {
1497 result.data.remove(value);
1498 } else {
1499 result.data.insert(value.clone(), new_count.clone());
1500 }
1501 result.size = self.size.clone() + new_count.clone() - old_count;
1502 result
1503 }
1504 pub fn merge(&self, other: &Multiset<V>) -> Multiset<V> {
1505 if other.size.is_zero() {
1506 return self.clone();
1507 }
1508 if self.size.is_zero() {
1509 return other.clone();
1510 }
1511 let mut result = self.data.clone();
1512 for (k, v) in other.data.iter() {
1513 let old_count = self.get(k);
1514 let new_count = old_count.clone() + v.clone();
1515 result.insert(k.clone(), new_count);
1516 }
1517 Multiset {
1518 data: result,
1519 size: self.size.clone() + other.size.clone(),
1520 }
1521 }
1522 pub fn intersect(&self, other: &Multiset<V>) -> Multiset<V> {
1523 if other.size.is_zero() {
1524 return other.clone();
1525 }
1526 if self.size.is_zero() {
1527 return self.clone();
1528 }
1529 let mut result = HashMap::<V, DafnyInt>::new();
1530 let mut total = DafnyInt::zero();
1531 for (k, other_count) in other.data.iter() {
1532 let self_count = self.get(k);
1533 let resulting_count = if self_count < *other_count {
1534 self_count
1535 } else {
1536 other_count.clone()
1537 };
1538 if resulting_count.is_positive() {
1539 result.insert(k.clone(), resulting_count.clone());
1540 total = total + resulting_count;
1541 }
1542 }
1543 Multiset {
1544 data: result,
1545 size: total,
1546 }
1547 }
1548 pub fn subtract(&self, other: &Multiset<V>) -> Multiset<V> {
1549 if other.size.is_zero() {
1550 return self.clone();
1551 }
1552 if self.size.is_zero() {
1553 return self.clone();
1554 }
1555 let mut result = self.data.clone();
1556 let mut total = self.size.clone();
1557 for (k, v) in other.data.iter() {
1558 let old_count = self.get(k);
1559 let new_count = old_count.clone() - v.clone();
1560 if !new_count.is_positive() {
1561 total = total - old_count.clone();
1562 result.remove(k);
1563 } else {
1564 total = total - v.clone();
1565 result.insert(k.clone(), new_count);
1566 }
1567 }
1568 Multiset {
1569 data: result,
1570 size: total,
1571 }
1572 }
1573 pub fn disjoint(&self, other: &Multiset<V>) -> bool {
1574 for value in other.data.keys() {
1575 if self.contains(value) {
1576 return false;
1577 }
1578 }
1579 true
1580 }
1581
1582 pub fn as_dafny_multiset(&self) -> Multiset<V> {
1583 self.clone()
1584 }
1585
1586 pub fn peek(&self) -> V {
1587 self.data.iter().next().unwrap().0.clone()
1588 }
1589
1590 pub fn iter_raw(&self) -> std::collections::hash_map::Iter<'_, V, DafnyInt> {
1591 self.data.iter()
1592 }
1593
1594 pub fn iter(&self) -> impl Iterator<Item = V> + '_ {
1595 self.data
1596 .iter()
1597 .flat_map(|(k, v)| ::std::iter::repeat(k).take(v.clone().as_usize()))
1598 .cloned()
1599 }
1600}
1601
1602impl<T> Default for Multiset<T>
1603where
1604 T: DafnyTypeEq,
1605{
1606 fn default() -> Self {
1607 Self::new_empty()
1608 }
1609}
1610impl<T: DafnyTypeEq> NontrivialDefault for Multiset<T> {
1611 fn nontrivial_default() -> Self {
1612 Self::default()
1613 }
1614}
1615
1616impl<V: DafnyTypeEq> PartialOrd<Multiset<V>> for Multiset<V> {
1617 fn partial_cmp(&self, other: &Multiset<V>) -> Option<Ordering> {
1618 match self.cardinality().cmp(&other.cardinality()) {
1619 Ordering::Less => {
1620 for value in self.data.keys() {
1621 if !other.contains(value) || self.get(value) > other.get(value) {
1622 return None;
1623 }
1624 }
1625 Some(Ordering::Less)
1626 }
1627 Ordering::Equal => {
1628 for value in self.data.keys() {
1629 if self.get(value) != other.get(value) {
1630 return None;
1631 }
1632 }
1633 Some(Ordering::Equal)
1634 }
1635 Ordering::Greater => {
1636 for value in other.data.keys() {
1637 if !self.contains(value) || self.get(value) < other.get(value) {
1638 return None;
1639 }
1640 }
1641 Some(Ordering::Greater)
1642 }
1643 }
1644 }
1645}
1646
1647impl<V: DafnyTypeEq> DafnyPrint for Multiset<V> {
1648 fn fmt_print(&self, f: &mut Formatter<'_>, in_seq: bool) -> std::fmt::Result {
1649 f.write_str("multiset{")?;
1650 let mut first = true;
1651 for value in self.data.iter() {
1652 for _count in 0..value.1.as_usize() {
1653 if !first {
1654 f.write_str(", ")?;
1655 }
1656 first = false;
1657 value.0.fmt_print(f, in_seq)?;
1658 }
1659 }
1660 f.write_str("}")
1661 }
1662}
1663
1664impl<V> Debug for Multiset<V>
1665where
1666 V: DafnyTypeEq,
1667{
1668 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
1669 self.fmt_print(f, false)
1670 }
1671}
1672
1673impl<V: DafnyTypeEq> PartialEq<Multiset<V>> for Multiset<V> {
1674 fn eq(&self, other: &Multiset<V>) -> bool {
1675 if self.cardinality() != other.cardinality() {
1676 return false;
1677 }
1678 for value in other.data.iter() {
1680 if !self.contains(value.0) || self.get(value.0) != *value.1 {
1681 return false;
1682 }
1683 }
1684 true
1685 }
1686}
1687impl<V: DafnyTypeEq> Eq for Multiset<V> {}
1688impl<V: DafnyTypeEq> Hash for Multiset<V> {
1689 fn hash<H: Hasher>(&self, state: &mut H) {
1690 self.cardinality().hash(state);
1691 }
1692}
1693
1694pub fn euclidian_division<A: Signed + Zero + One + Clone + PartialEq>(a: A, b: A) -> A {
1695 if !a.is_negative() {
1696 if !b.is_negative() {
1697 a / b
1698 } else {
1699 -(a / -b)
1700 }
1701 } else {
1702 if !b.is_negative() {
1703 -((-(a + One::one())) / b) - One::one()
1704 } else {
1705 (-(a + One::one())) / (-b) + One::one()
1706 }
1707 }
1708}
1709
1710pub fn euclidian_modulo<A: Signed + Zero + One + Clone + PartialEq>(a: A, b: A) -> A {
1711 if !a.is_negative() {
1712 if !b.is_negative() {
1713 a % b
1714 } else {
1715 a % -b
1716 }
1717 } else {
1718 let bp = b.abs();
1719 let c = (-a) % bp.clone();
1720 if c == Zero::zero() {
1721 Zero::zero()
1722 } else {
1723 bp - c
1724 }
1725 }
1726}
1727
1728pub struct IntegerRange<A: Add<Output = A> + One + Ord + Clone> {
1729 hi: A,
1730 current: A,
1731}
1732
1733impl<A: Add<Output = A> + One + Ord + Clone> Iterator for IntegerRange<A> {
1734 type Item = A;
1735
1736 fn next(&mut self) -> Option<Self::Item> {
1737 if self.current < self.hi {
1738 let result = self.current.clone();
1739 self.current = self.current.clone() + One::one();
1740 Some(result)
1741 } else {
1742 None
1743 }
1744 }
1745}
1746
1747pub fn integer_range<A: Add<Output = A> + One + Ord + Clone>(
1748 low: A,
1749 hi: A,
1750) -> impl Iterator<Item = A> {
1751 IntegerRange { hi, current: low }
1752}
1753
1754pub struct IntegerRangeDown<A: Sub<Output = A> + One + Ord + Clone> {
1755 current: A,
1756 low: A,
1757}
1758
1759impl<A: Sub<Output = A> + One + Ord + Clone> Iterator for IntegerRangeDown<A> {
1760 type Item = A;
1761
1762 fn next(&mut self) -> Option<Self::Item> {
1763 if self.current > self.low {
1764 self.current = self.current.clone() - One::one();
1765 Some(self.current.clone())
1766 } else {
1767 None
1768 }
1769 }
1770}
1771
1772pub fn integer_range_down<A: Sub<Output = A> + One + Ord + Clone>(
1773 hi: A,
1774 low: A,
1775) -> impl Iterator<Item = A> {
1776 IntegerRangeDown { current: hi, low }
1777}
1778
1779pub struct IntegerRangeUnbounded<A: Add<Output = A> + One + Clone> {
1782 current: A,
1783}
1784impl<A: Add<Output = A> + One + Clone> Iterator for IntegerRangeUnbounded<A> {
1785 type Item = A;
1786
1787 fn next(&mut self) -> Option<Self::Item> {
1788 let result = self.current.clone();
1789 self.current = self.current.clone() + One::one();
1790 Some(result)
1791 }
1792}
1793pub fn integer_range_unbounded<A: Add<Output = A> + One + Clone>(
1794 low: A,
1795) -> impl Iterator<Item = A> {
1796 IntegerRangeUnbounded { current: low }
1797}
1798
1799pub struct IntegerRangeDownUnbounded<A: Sub<Output = A> + One + Clone> {
1800 current: A,
1801}
1802
1803impl<A: Sub<Output = A> + One + Clone> Iterator for IntegerRangeDownUnbounded<A> {
1804 type Item = A;
1805
1806 fn next(&mut self) -> Option<Self::Item> {
1807 self.current = self.current.clone() - One::one();
1808 Some(self.current.clone())
1809 }
1810}
1811
1812pub fn integer_range_down_unbounded<A: Sub<Output = A> + One + Clone>(
1813 hi: A,
1814) -> impl Iterator<Item = A> {
1815 IntegerRangeDownUnbounded { current: hi }
1816}
1817
1818pub struct LazyFieldWrapper<A>(pub Lazy<A, Box<dyn 'static + FnOnce() -> A>>);
1819
1820impl<A: PartialEq> PartialEq for LazyFieldWrapper<A> {
1821 fn eq(&self, other: &Self) -> bool {
1822 self.0.deref() == other.0.deref()
1823 }
1824}
1825
1826impl<A: Default + 'static> Default for LazyFieldWrapper<A> {
1827 fn default() -> Self {
1828 Self(Lazy::new(Box::new(A::default)))
1829 }
1830}
1831
1832impl<A: DafnyPrint> DafnyPrint for LazyFieldWrapper<A> {
1833 fn fmt_print(&self, f: &mut Formatter<'_>, in_seq: bool) -> std::fmt::Result {
1834 self.0.deref().fmt_print(f, in_seq)
1835 }
1836}
1837
1838#[cfg(feature = "sync")]
1839macro_rules! dafny_print_function {
1841 ($($n:tt)*) => {
1842 impl <B, $($n),*> $crate::DafnyPrint for $crate::Rc<dyn ::std::ops::Fn($(&$n),*) -> B + Send + Sync> {
1843 fn fmt_print(&self, f: &mut ::std::fmt::Formatter<'_>, _in_seq: bool) -> ::std::fmt::Result {
1844 write!(f, "<function>")
1845 }
1846 }
1847 }
1848}
1849#[cfg(not(feature = "sync"))]
1850macro_rules! dafny_print_function {
1852 ($($n:tt)*) => {
1853 impl <B, $($n),*> $crate::DafnyPrint for $crate::Rc<dyn ::std::ops::Fn($(&$n),*) -> B> {
1854 fn fmt_print(&self, f: &mut ::std::fmt::Formatter<'_>, _in_seq: bool) -> ::std::fmt::Result {
1855 write!(f, "<function>")
1856 }
1857 }
1858 }
1859}
1860
1861macro_rules! dafny_print_function_loop {
1863 ($first:ident $($rest:ident)*) => {
1864 dafny_print_function_loop! { $($rest)* }
1865 dafny_print_function! { $first $($rest)* }
1866 };
1867 () => {
1868 }
1869}
1870dafny_print_function_loop! { A1 A2 A3 A4 A5 A6 A7 A8 A9 A10 A11 A12 A13 A14 A15 A16
1872A17 A18 A19 A20 A21 A22 A23 A24 A25 A26 A27 A28 A29 A30 A31 A32 }
1873
1874pub struct FunctionWrapper<A: ?Sized>(pub A);
1875impl<A> DafnyPrint for FunctionWrapper<A> {
1876 fn fmt_print(&self, f: &mut Formatter<'_>, _in_seq: bool) -> std::fmt::Result {
1877 write!(f, "<function>")
1878 }
1879}
1880
1881impl<A: Clone> Clone for FunctionWrapper<A> {
1882 fn clone(&self) -> Self {
1883 Self(self.0.clone())
1884 }
1885}
1886
1887impl<A: ?Sized> PartialEq for FunctionWrapper<Rc<A>> {
1888 fn eq(&self, other: &Self) -> bool {
1889 Rc::ptr_eq(&self.0, &other.0)
1890 }
1891}
1892
1893pub struct DafnyPrintWrapper<T>(pub T);
1894impl<T: DafnyPrint> Display for DafnyPrintWrapper<&T> {
1895 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
1896 self.0.fmt_print(f, false)
1897 }
1898}
1899
1900pub trait DafnyPrint {
1901 fn fmt_print(&self, f: &mut Formatter<'_>, in_seq: bool) -> std::fmt::Result;
1902
1903 #[inline]
1905 fn is_char() -> bool {
1906 false
1907 }
1908}
1909
1910impl<T> DafnyPrint for *const T {
1911 fn fmt_print(&self, f: &mut Formatter<'_>, _in_seq: bool) -> std::fmt::Result {
1912 write!(f, "<{} object>", std::any::type_name::<T>())
1913 }
1914}
1915
1916macro_rules! impl_print_display {
1917 ($name:ty) => {
1918 impl $crate::DafnyPrint for $name {
1919 fn fmt_print(
1920 &self,
1921 f: &mut ::std::fmt::Formatter<'_>,
1922 _in_seq: bool,
1923 ) -> ::std::fmt::Result {
1924 ::std::fmt::Display::fmt(&self, f)
1925 }
1926 }
1927 };
1928}
1929
1930impl_print_display! { String }
1931impl_print_display! { bool }
1932impl_print_display! { u8 }
1933impl_print_display! { u16 }
1934impl_print_display! { u32 }
1935impl_print_display! { u64 }
1936impl_print_display! { u128 }
1937impl_print_display! { i8 }
1938impl_print_display! { i16 }
1939impl_print_display! { i32 }
1940impl_print_display! { i64 }
1941impl_print_display! { i128 }
1942impl_print_display! { usize }
1943
1944impl DafnyPrint for f32 {
1945 fn fmt_print(&self, f: &mut Formatter<'_>, _in_seq: bool) -> std::fmt::Result {
1946 write!(f, "{:.1}", self)
1947 }
1948}
1949
1950impl DafnyPrint for f64 {
1951 fn fmt_print(&self, f: &mut Formatter<'_>, _in_seq: bool) -> std::fmt::Result {
1952 write!(f, "{:.1}", self)
1953 }
1954}
1955
1956impl DafnyPrint for () {
1957 fn fmt_print(&self, f: &mut Formatter<'_>, _in_seq: bool) -> std::fmt::Result {
1958 write!(f, "()")
1959 }
1960}
1961
1962#[derive(Clone, Copy)]
1963pub struct DafnyCharUTF16(pub u16);
1964pub type DafnyStringUTF16 = Sequence<DafnyCharUTF16>;
1965
1966impl Default for DafnyCharUTF16 {
1967 fn default() -> Self {
1968 Self('a' as u16)
1969 }
1970}
1971
1972impl DafnyPrint for DafnyCharUTF16 {
1973 #[inline]
1974 fn fmt_print(&self, f: &mut Formatter<'_>, in_seq: bool) -> std::fmt::Result {
1975 let real_char = char::decode_utf16([*self].iter().map(|v| v.0))
1976 .map(|r| r.map_err(|e| e.unpaired_surrogate()))
1977 .collect::<Vec<_>>()[0];
1978 let rendered_char = match real_char {
1979 Ok(c) => c,
1980 Err(e) => {
1981 return write!(f, "Invalid UTF-16 code point: {}", e);
1982 }
1983 };
1984
1985 if in_seq {
1986 write!(f, "{}", rendered_char)
1987 } else {
1988 write!(f, "'{}'", rendered_char)
1989 }
1990 }
1991
1992 #[inline]
1993 fn is_char() -> bool {
1994 true
1995 }
1996}
1997
1998impl Debug for DafnyCharUTF16 {
1999 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
2000 self.fmt_print(f, false)
2001 }
2002}
2003
2004impl PartialEq<DafnyCharUTF16> for DafnyCharUTF16 {
2005 fn eq(&self, other: &DafnyCharUTF16) -> bool {
2006 self.0 == other.0
2007 }
2008}
2009impl Eq for DafnyCharUTF16 {}
2010impl Hash for DafnyCharUTF16 {
2011 fn hash<H: Hasher>(&self, state: &mut H) {
2012 self.0.hash(state)
2013 }
2014}
2015
2016impl PartialOrd<DafnyCharUTF16> for DafnyCharUTF16 {
2017 fn partial_cmp(&self, other: &DafnyCharUTF16) -> Option<Ordering> {
2018 (self.0).partial_cmp(&other.0)
2019 }
2020}
2021
2022impl Add<DafnyCharUTF16> for DafnyCharUTF16 {
2023 type Output = DafnyCharUTF16;
2024
2025 fn add(self, rhs: DafnyCharUTF16) -> Self::Output {
2026 DafnyCharUTF16(self.0 + rhs.0)
2027 }
2028}
2029
2030impl Sub<DafnyCharUTF16> for DafnyCharUTF16 {
2031 type Output = DafnyCharUTF16;
2032
2033 fn sub(self, rhs: DafnyCharUTF16) -> Self::Output {
2034 DafnyCharUTF16(self.0 - rhs.0)
2035 }
2036}
2037
2038#[derive(Clone, Copy)]
2039pub struct DafnyChar(pub char);
2040pub type DafnyString = Sequence<DafnyChar>;
2041
2042impl Default for DafnyChar {
2043 fn default() -> Self {
2044 Self('a')
2045 }
2046}
2047
2048impl DafnyPrint for DafnyChar {
2049 #[inline]
2050 fn fmt_print(&self, f: &mut Formatter<'_>, in_seq: bool) -> std::fmt::Result {
2051 if in_seq {
2052 write!(f, "{}", self.0)
2053 } else {
2054 write!(f, "'{}'", self.0)
2055 }
2056 }
2057
2058 #[inline]
2059 fn is_char() -> bool {
2060 true
2061 }
2062}
2063
2064impl Debug for DafnyChar {
2065 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
2066 self.fmt_print(f, false)
2067 }
2068}
2069
2070impl PartialEq<DafnyChar> for DafnyChar {
2071 fn eq(&self, other: &DafnyChar) -> bool {
2072 self.0 == other.0
2073 }
2074}
2075
2076impl PartialOrd<DafnyChar> for DafnyChar {
2077 fn partial_cmp(&self, other: &DafnyChar) -> Option<Ordering> {
2078 (self.0 as u32).partial_cmp(&(other.0 as u32))
2079 }
2080}
2081impl Eq for DafnyChar {}
2082impl Hash for DafnyChar {
2083 fn hash<H: Hasher>(&self, state: &mut H) {
2084 self.0.hash(state)
2085 }
2086}
2087
2088impl Add<DafnyChar> for DafnyChar {
2089 type Output = DafnyChar;
2090
2091 fn add(self, rhs: DafnyChar) -> Self::Output {
2092 DafnyChar(unsafe { char::from_u32_unchecked(self.0 as u32 + rhs.0 as u32) })
2093 }
2094}
2095
2096impl Sub<DafnyChar> for DafnyChar {
2097 type Output = DafnyChar;
2098
2099 fn sub(self, rhs: DafnyChar) -> Self::Output {
2100 DafnyChar(unsafe { char::from_u32_unchecked(self.0 as u32 - rhs.0 as u32) })
2101 }
2102}
2103
2104impl<T: DafnyPrint> DafnyPrint for Option<T> {
2105 fn fmt_print(&self, f: &mut Formatter<'_>, _in_seq: bool) -> std::fmt::Result {
2106 match self {
2107 Some(x) => x.fmt_print(f, false),
2108 None => write!(f, "null"),
2109 }
2110 }
2111}
2112
2113impl<T: ?Sized + DafnyPrint> DafnyPrint for Rc<T> {
2114 fn fmt_print(&self, f: &mut Formatter<'_>, in_seq: bool) -> std::fmt::Result {
2115 self.as_ref().fmt_print(f, in_seq)
2116 }
2117}
2118
2119impl<T: ?Sized + DafnyPrint> DafnyPrint for &Rc<T> {
2120 fn fmt_print(&self, f: &mut Formatter<'_>, in_seq: bool) -> std::fmt::Result {
2121 self.as_ref().fmt_print(f, in_seq)
2122 }
2123}
2124
2125impl<T: DafnyPrint> DafnyPrint for Vec<T> {
2126 fn fmt_print(&self, f: &mut Formatter<'_>, _in_seq: bool) -> std::fmt::Result {
2127 if !T::is_char() {
2128 write!(f, "[")?;
2129 }
2130
2131 for (i, item) in self.iter().enumerate() {
2132 if !T::is_char() {
2133 if i > 0 {
2134 write!(f, ", ")?;
2135 }
2136
2137 item.fmt_print(f, false)?;
2138 } else {
2139 item.fmt_print(f, true)?;
2140 }
2141 }
2142
2143 if !T::is_char() {
2144 write!(f, "]")
2145 } else {
2146 Ok(())
2147 }
2148 }
2149}
2150
2151#[cfg(not(feature = "sync"))]
2152impl<T: DafnyPrint> DafnyPrint for RefCell<T> {
2153 fn fmt_print(&self, f: &mut Formatter<'_>, _in_seq: bool) -> std::fmt::Result {
2154 self.borrow().fmt_print(f, _in_seq)
2155 }
2156}
2157
2158#[cfg(feature = "sync")]
2159impl<T: DafnyPrint> DafnyPrint for RefCell<T> {
2160 fn fmt_print(&self, f: &mut Formatter<'_>, _in_seq: bool) -> std::fmt::Result {
2161 self.lock().unwrap().fmt_print(f, _in_seq)
2162 }
2163}
2164
2165impl<T: DafnyPrint> DafnyPrint for HashSet<T> {
2166 fn fmt_print(&self, f: &mut Formatter<'_>, _in_seq: bool) -> std::fmt::Result {
2167 write!(f, "{{")?;
2168
2169 for (i, item) in self.iter().enumerate() {
2170 if i > 0 {
2171 write!(f, ", ")?;
2172 }
2173 item.fmt_print(f, false)?;
2174 }
2175
2176 write!(f, "}}")
2177 }
2178}
2179
2180pub fn char_lt(left: char, right: char) -> bool {
2181 let left_code = left as u32;
2182 let right_code = right as u32;
2183
2184 left_code < right_code
2185}
2186
2187pub fn string_of(s: &str) -> DafnyString {
2188 s.chars().map(DafnyChar).collect::<Sequence<DafnyChar>>()
2189}
2190
2191pub fn string_utf16_of(s: &str) -> DafnyStringUTF16 {
2192 Sequence::from_array_owned(s.encode_utf16().map(DafnyCharUTF16).collect())
2193}
2194
2195macro_rules! impl_tuple_print {
2196 ($($items:ident)*) => {
2197 impl <$($items,)*> $crate::DafnyPrint for ($($items,)*)
2198 where
2199 $($items: $crate::DafnyPrint,)*
2200 {
2201 #[allow(unused_assignments)]
2202 fn fmt_print(&self, f: &mut ::std::fmt::Formatter<'_>, _in_seq: bool) -> ::std::fmt::Result {
2203 #[allow(non_snake_case)]
2204 let ($($items,)*) = self;
2205
2206 write!(f, "(")?;
2207
2208 let mut i = 0;
2209
2210 $(
2211 if (i > 0) {
2212 write!(f, ", ")?;
2213 }
2214
2215 $items.fmt_print(f, false)?;
2216
2217 i += 1;
2218 )*
2219
2220 write!(f, ")")
2221 }
2222 }
2223 };
2224}
2225
2226macro_rules! impl_tuple_print_loop {
2227 () => {};
2228 ($first:ident $($rest:ident)*) => {
2229 impl_tuple_print_loop! { $($rest)* }
2230 impl_tuple_print! { $first $($rest)* }
2231 };
2232}
2233
2234impl_tuple_print_loop! {
2236 A0 A1 A2 A3 A4 A5 A6 A7 A8 A9 A10
2237 A11 A12 A13 A14 A15 A16 A17 A18 A19 A20
2238 A21 A22 A23 A24 A25 A26 A27 A28 A29 A30
2239 A31
2240}
2241
2242#[macro_export]
2244macro_rules! seq {
2245 ($($x:expr),*) => {
2246 $crate::Sequence::from_array_owned(vec![$($x), *])
2247 }
2248}
2249
2250#[macro_export]
2251macro_rules! set {
2252 ($($x:expr), *) => {
2253 {
2254 #[allow(unused_mut)]
2256 let mut temp_hash = ::std::collections::HashSet::new();
2257 $(
2258 temp_hash.insert($x);
2259 )*
2260 $crate::Set::from_hashset_owned(temp_hash)
2261 }
2262 }
2263}
2264
2265#[macro_export]
2266macro_rules! multiset {
2267 ($($x:expr), *) => {
2268 {
2269 #[allow(unused_mut)]
2270 let mut temp_hash = ::std::collections::HashMap::new();
2271 #[allow(unused_mut)]
2272 let mut total_size: usize = 0;
2273 $( {
2274 #[allow(unused_mut)]
2275 let mut entry = temp_hash.entry($x).or_insert($crate::DafnyInt::from(0));
2276 *entry = (*entry).clone() + $crate::DafnyInt::from(1);
2277 total_size += 1;
2278 }
2279 )*
2280 $crate::Multiset {
2281 data: temp_hash,
2282 size: $crate::DafnyInt::from(total_size),
2283 }
2284 }
2285 }
2286}
2287
2288#[macro_export]
2290macro_rules! map {
2291 ($($k:expr => $v:expr), *) => {
2292 {
2293 #[allow(unused_mut)]
2294 let mut temp_hash = ::std::collections::HashMap::new();
2295 $(
2296 temp_hash.insert($k.clone(), $v.clone());
2297 )*
2298 $crate::Map::from_hashmap_owned(temp_hash)
2299 }
2300 }
2301}
2302
2303#[macro_export]
2304macro_rules! int {
2305 ($x:expr) => {
2306 $crate::DafnyInt::from($x)
2307 };
2308}
2309
2310macro_rules! ARRAY_GETTER_LENGTH0 {
2315 () => {
2316 #[inline]
2317 pub fn length0(&self) -> $crate::DafnyInt {
2318 $crate::DafnyInt::from(self.length0_usize())
2319 }
2320 #[inline]
2321 pub fn length0_usize(&self) -> usize {
2322 self.data.len()
2323 }
2324 };
2325}
2326macro_rules! ARRAY_GETTER_LENGTH {
2327 ($field: ident, $field_usize: ident) => {
2328 #[inline]
2329 pub fn $field(&self) -> $crate::DafnyInt {
2330 $crate::DafnyInt::from(self.$field_usize())
2331 }
2332 #[inline]
2333 pub fn $field_usize(&self) -> usize {
2334 self.$field
2335 }
2336 };
2337}
2338
2339#[macro_export]
2341macro_rules! array {
2342 ($($x:expr), *) => {
2343 $crate::array::from_native(::std::boxed::Box::new([$($x), *]))
2344 }
2345}
2346
2347macro_rules! ARRAY_INIT {
2348 {$length: ident, $inner: expr} => {
2349 $crate::array::initialize_box_usize($length, {
2350 $crate::Rc::new(move |_| { $inner })
2351 })
2352 }
2353}
2354
2355macro_rules! ARRAY_INIT_INNER {
2356 ($length: ident) => {
2357 $crate::array::placebos_box_usize::<T>($length)
2358 };
2359}
2360
2361macro_rules! ARRAY_DATA_TYPE {
2364 ($length:ident) => {
2365 ::std::boxed::Box<[T]>
2366 };
2367 ($length:ident, $($rest_length:ident),+) => {
2368 ::std::boxed::Box<[ARRAY_DATA_TYPE!($($rest_length),+)]>
2369 };
2370}
2371
2372#[macro_export]
2375macro_rules! INIT_ARRAY_DATA {
2376 ($ArrayType:ident, $last_length:ident) => {
2378 ARRAY_INIT_INNER!($last_length)
2379 };
2380 ($ArrayType:ident, $first_length:ident, $($rest_length:ident),+) => {
2382 ARRAY_INIT!($first_length, INIT_ARRAY_DATA!($ArrayType, $($rest_length),+))
2383 };
2384}
2385
2386macro_rules! ARRAY_METHODS {
2387 ($ArrayType:ident, $length0: ident, $($length:ident),+) => {
2389 pub fn placebos_box_usize(
2390 $length0: usize,
2391 $($length: usize),+
2392 ) -> ::std::boxed::Box<$ArrayType<$crate::MaybeUninit<T>>> {
2393 ::std::boxed::Box::new($ArrayType {
2394 $($length: $length),+,
2395 data: INIT_ARRAY_DATA!($ArrayType, $length0, $($length),+),
2396 })
2397 }
2398
2399 pub fn placebos_usize(
2400 $length0: usize,
2401 $($length: usize),+
2402 ) -> $crate::Ptr<$ArrayType<$crate::MaybeUninit<T>>> {
2403 $crate::Ptr::from_box(Self::placebos_box_usize(
2404 $length0,
2405 $($length),+
2406 ))
2407 }
2408
2409 pub fn placebos_usize_object(
2410 $length0: usize,
2411 $($length: usize),+
2412 ) -> $crate::Object<$ArrayType<$crate::MaybeUninit<T>>> {
2413 $crate::Object::new($ArrayType {
2415 $($length: $length),+,
2416 data: INIT_ARRAY_DATA!($ArrayType, $length0, $($length),+),
2417 })
2418 }
2419
2420 pub fn placebos(
2421 $length0: &$crate::DafnyInt,
2422 $($length: &$crate::DafnyInt),+
2423 ) -> $crate::Ptr<$ArrayType<$crate::MaybeUninit<T>>> {
2424 Self::placebos_usize(
2425 $length0.as_usize(),
2426 $($length.as_usize()),+
2427 )
2428 }
2429
2430 pub fn construct(p: $crate::Ptr<$ArrayType<$crate::MaybeUninit<T>>>) -> $crate::Ptr<$ArrayType<T>> {
2432 unsafe { std::mem::transmute(p) }
2433 }
2434 pub fn construct_object(p: $crate::Object<$ArrayType<$crate::MaybeUninit<T>>>) -> $crate::Object<$ArrayType<T>> {
2436 unsafe { std::mem::transmute(p) }
2437 }
2438 };
2439}
2440
2441macro_rules! ARRAY_STRUCT {
2442 ($ArrayType:ident, $length0: ident, $($length:ident),+) => {
2443 pub struct $ArrayType<T> {
2444 $($length: usize),+,
2445 pub data: ARRAY_DATA_TYPE!($length0, $($length),+),
2446 }
2447 }
2448}
2449
2450macro_rules! ARRAY_TO_VEC_LOOP {
2451 (@inner $self: ident, $tmp: ident, $data: expr) => {
2452 $tmp.push($data.clone());
2453 };
2454 (@for $self: ident, $tmp: ident, $data: expr, $length_usize: ident $(, $rest_length_usize: ident)*) => {
2455 for i in 0..$self.$length_usize() {
2456 ARRAY_TO_VEC_LOOP!(@inner $self, $tmp, $data[i] $(, $rest_length_usize)*);
2457 }
2458 };
2459 (@inner $self: ident, $outerTmp: ident, $data: expr $(, $rest_length_usize: ident)*) => {
2460 {
2461 let mut tmp = ::std::vec::Vec::new();
2462 ARRAY_TO_VEC_LOOP!(@for $self, tmp, $data $(, $rest_length_usize)*);
2463 $outerTmp.push(tmp);
2464 }
2465 };
2466
2467 ($self: ident, $data: expr $(, $rest_length_usize: ident)*) => {
2468 {
2469 let mut tmp = ::std::vec::Vec::new();
2470 ARRAY_TO_VEC_LOOP!(@for $self, tmp, $data $(, $rest_length_usize)*);
2471 tmp
2472 }
2473 };
2474}
2475
2476macro_rules! ARRAY_TO_VEC_TYPE {
2477 ($length0: ident) => {
2478 ::std::vec::Vec<T>
2479 };
2480 ($length0: ident $(, $res_length: ident)*) => {
2481 ::std::vec::Vec<ARRAY_TO_VEC_TYPE!($($res_length), *)>
2482 }
2483}
2484
2485macro_rules! ARRAY_TO_VEC {
2486 ($length0_usize: ident $(, $res_length_usize: ident)*) => {
2487 pub fn to_vec(&self) -> ARRAY_TO_VEC_TYPE!($length0_usize, $($res_length_usize),*) {
2488 ARRAY_TO_VEC_LOOP!(self, self.data, $length0_usize, $($res_length_usize),*)
2489 }
2490 }
2491}
2492
2493macro_rules! ARRAY_LENGTHS {
2494 () => {
2495
2496 };
2497 (($length0: ident, $length0_usize: ident) $(, $rest: tt)*) => {
2498 ARRAY_GETTER_LENGTH0!();
2499 ARRAY_LENGTHS!($(, $rest)*);
2500 };
2501 (, ($length: ident, $length_usize: ident) $(, $rest: tt)*) => {
2502 ARRAY_GETTER_LENGTH!($length, $length_usize);
2503 ARRAY_LENGTHS!($(, $rest)*);
2504 }
2505}
2506
2507macro_rules! ARRAY_METHODS_WRAPPER {
2508 ($ArrayType:ident, $(($length:ident, $length_usize: ident)), +) => {
2509 ARRAY_METHODS!($ArrayType, $($length), +);
2510 }
2511}
2512
2513macro_rules! ARRAY_TO_VEC_WRAPPER {
2514 ($(($length:ident, $length_usize: ident)), +) => {
2515 ARRAY_TO_VEC!($($length_usize), +);
2516 }
2517}
2518
2519macro_rules! ARRAY_STRUCT_WRAPPER {
2520 ($ArrayType:ident, $(($length:ident, $length_usize: ident)), +) => {
2521 ARRAY_STRUCT!($ArrayType, $($length), +);
2522 }
2523}
2524
2525macro_rules! ARRAY_DEF {
2526 ($ArrayType:ident, $(($length:ident, $length_usize: ident)), +) => {
2527 ARRAY_STRUCT_WRAPPER!($ArrayType, $(($length, $length_usize)), +);
2528 impl<T> $ArrayType<T> {
2529 ARRAY_LENGTHS!{
2530 $(($length, $length_usize)), +
2531 }
2532 ARRAY_METHODS_WRAPPER!{$ArrayType,
2533 $(($length, $length_usize)), +
2534 }
2535 }
2536 impl<T: ::std::clone::Clone> $ArrayType<T> {
2537 ARRAY_TO_VEC_WRAPPER!{
2538 $(($length, $length_usize)), +
2539 }
2540 }
2541 }
2542}
2543
2544ARRAY_DEF! {Array2,
2547 (length0, length0_usize),
2548 (length1, length1_usize)
2549}
2550
2551ARRAY_DEF! {Array3,
2552 (length0, length0_usize),
2553 (length1, length1_usize),
2554 (length2, length2_usize)
2555}
2556
2557ARRAY_DEF! {Array4,
2558 (length0, length0_usize),
2559 (length1, length1_usize),
2560 (length2, length2_usize),
2561 (length3, length3_usize)
2562}
2563
2564ARRAY_DEF! {Array5,
2565 (length0, length0_usize),
2566 (length1, length1_usize),
2567 (length2, length2_usize),
2568 (length3, length3_usize),
2569 (length4, length4_usize)
2570}
2571
2572ARRAY_DEF! {Array6,
2573 (length0, length0_usize),
2574 (length1, length1_usize),
2575 (length2, length2_usize),
2576 (length3, length3_usize),
2577 (length4, length4_usize),
2578 (length5, length5_usize)
2579}
2580
2581ARRAY_DEF! {Array7,
2582 (length0, length0_usize),
2583 (length1, length1_usize),
2584 (length2, length2_usize),
2585 (length3, length3_usize),
2586 (length4, length4_usize),
2587 (length5, length5_usize),
2588 (length6, length6_usize)
2589}
2590
2591ARRAY_DEF! {Array8,
2592 (length0, length0_usize),
2593 (length1, length1_usize),
2594 (length2, length2_usize),
2595 (length3, length3_usize),
2596 (length4, length4_usize),
2597 (length5, length5_usize),
2598 (length6, length6_usize),
2599 (length7, length7_usize)
2600}
2601
2602ARRAY_DEF! {Array9,
2603 (length0, length0_usize),
2604 (length1, length1_usize),
2605 (length2, length2_usize),
2606 (length3, length3_usize),
2607 (length4, length4_usize),
2608 (length5, length5_usize),
2609 (length6, length6_usize),
2610 (length7, length7_usize),
2611 (length8, length8_usize)
2612}
2613
2614ARRAY_DEF! {Array10,
2615 (length0, length0_usize),
2616 (length1, length1_usize),
2617 (length2, length2_usize),
2618 (length3, length3_usize),
2619 (length4, length4_usize),
2620 (length5, length5_usize),
2621 (length6, length6_usize),
2622 (length7, length7_usize),
2623 (length8, length8_usize),
2624 (length9, length9_usize)
2625}
2626
2627ARRAY_DEF! {Array11,
2628 (length0, length0_usize),
2629 (length1, length1_usize),
2630 (length2, length2_usize),
2631 (length3, length3_usize),
2632 (length4, length4_usize),
2633 (length5, length5_usize),
2634 (length6, length6_usize),
2635 (length7, length7_usize),
2636 (length8, length8_usize),
2637 (length9, length9_usize),
2638 (length10, length10_usize)
2639}
2640
2641ARRAY_DEF! {Array12,
2642 (length0, length0_usize),
2643 (length1, length1_usize),
2644 (length2, length2_usize),
2645 (length3, length3_usize),
2646 (length4, length4_usize),
2647 (length5, length5_usize),
2648 (length6, length6_usize),
2649 (length7, length7_usize),
2650 (length8, length8_usize),
2651 (length9, length9_usize),
2652 (length10, length10_usize),
2653 (length11, length11_usize)
2654}
2655
2656ARRAY_DEF! {Array13,
2657 (length0, length0_usize),
2658 (length1, length1_usize),
2659 (length2, length2_usize),
2660 (length3, length3_usize),
2661 (length4, length4_usize),
2662 (length5, length5_usize),
2663 (length6, length6_usize),
2664 (length7, length7_usize),
2665 (length8, length8_usize),
2666 (length9, length9_usize),
2667 (length10, length10_usize),
2668 (length11, length11_usize),
2669 (length12, length12_usize)
2670}
2671
2672ARRAY_DEF! {Array14,
2673 (length0, length0_usize),
2674 (length1, length1_usize),
2675 (length2, length2_usize),
2676 (length3, length3_usize),
2677 (length4, length4_usize),
2678 (length5, length5_usize),
2679 (length6, length6_usize),
2680 (length7, length7_usize),
2681 (length8, length8_usize),
2682 (length9, length9_usize),
2683 (length10, length10_usize),
2684 (length11, length11_usize),
2685 (length12, length12_usize),
2686 (length13, length13_usize)
2687}
2688
2689ARRAY_DEF! {Array15,
2690 (length0, length0_usize),
2691 (length1, length1_usize),
2692 (length2, length2_usize),
2693 (length3, length3_usize),
2694 (length4, length4_usize),
2695 (length5, length5_usize),
2696 (length6, length6_usize),
2697 (length7, length7_usize),
2698 (length8, length8_usize),
2699 (length9, length9_usize),
2700 (length10, length10_usize),
2701 (length11, length11_usize),
2702 (length12, length12_usize),
2703 (length13, length13_usize),
2704 (length14, length14_usize)
2705}
2706
2707ARRAY_DEF! {Array16,
2708 (length0, length0_usize),
2709 (length1, length1_usize),
2710 (length2, length2_usize),
2711 (length3, length3_usize),
2712 (length4, length4_usize),
2713 (length5, length5_usize),
2714 (length6, length6_usize),
2715 (length7, length7_usize),
2716 (length8, length8_usize),
2717 (length9, length9_usize),
2718 (length10, length10_usize),
2719 (length11, length11_usize),
2720 (length12, length12_usize),
2721 (length13, length13_usize),
2722 (length14, length14_usize),
2723 (length15, length15_usize)
2724}
2725
2726pub mod array {
2727 use super::DafnyInt;
2728 use super::Ptr;
2729 use super::Rc;
2730 use ::std::boxed::Box;
2731 use ::std::mem::MaybeUninit;
2732 use ::std::vec::Vec;
2733 use num::ToPrimitive;
2734
2735 #[inline]
2736 pub fn from_native<T>(v: Box<[T]>) -> Ptr<[T]> {
2737 Ptr::from_box(v)
2738 }
2739 #[inline]
2740 pub fn from_vec<T>(v: Vec<T>) -> Ptr<[T]> {
2741 from_native(v.into_boxed_slice())
2742 }
2743 pub fn to_vec<T>(v: Ptr<[T]>) -> Vec<T> {
2744 unsafe { Box::<[T]>::from_raw(v.into_raw()) }.into_vec()
2745 }
2746 pub fn initialize_usize<T>(n: usize, initializer: Rc<dyn Fn(usize) -> T>) -> Ptr<[T]> {
2747 let mut v = Vec::with_capacity(n);
2748 for i in 0..n {
2749 v.push(initializer(i));
2750 }
2751 from_vec(v)
2752 }
2753
2754 pub fn placebos<T>(n: &DafnyInt) -> Ptr<[MaybeUninit<T>]> {
2755 placebos_usize(n.as_usize())
2756 }
2757 pub fn placebos_usize<T>(n: usize) -> Ptr<[MaybeUninit<T>]> {
2758 Ptr::from_box(placebos_box_usize(n))
2759 }
2760 pub fn placebos_usize_object<T>(n: usize) -> super::Object<[MaybeUninit<T>]> {
2761 super::rcmut::array_object_from_box(placebos_box_usize(n))
2762 }
2763 pub fn construct<T>(p: Ptr<[MaybeUninit<T>]>) -> Ptr<[T]> {
2765 unsafe { std::mem::transmute(p) }
2766 }
2767 pub fn construct_object<T>(p: super::Object<[MaybeUninit<T>]>) -> super::Object<[T]> {
2768 unsafe { std::mem::transmute(p) }
2769 }
2770
2771 pub fn placebos_box<T>(n: &DafnyInt) -> Box<[MaybeUninit<T>]> {
2772 placebos_box_usize(n.to_usize().unwrap())
2773 }
2774 pub fn placebos_box_usize<T>(n_usize: usize) -> Box<[MaybeUninit<T>]> {
2775 std::iter::repeat_with(MaybeUninit::uninit)
2778 .take(n_usize)
2779 .collect()
2780 }
2781
2782 pub fn initialize<T>(n: &DafnyInt, initializer: Rc<dyn Fn(&DafnyInt) -> T>) -> Ptr<[T]> {
2783 Ptr::from_box(initialize_box(n, initializer))
2784 }
2785
2786 pub fn initialize_box<T>(n: &DafnyInt, initializer: Rc<dyn Fn(&DafnyInt) -> T>) -> Box<[T]> {
2787 initialize_box_usize(n.to_usize().unwrap(), initializer)
2788 }
2789 pub fn initialize_box_usize<T>(
2790 n_usize: usize,
2791 initializer: Rc<dyn Fn(&DafnyInt) -> T>,
2792 ) -> Box<[T]> {
2793 let mut v = Vec::with_capacity(n_usize);
2794 for i in 0..n_usize {
2795 v.push(initializer(&int!(i)));
2796 }
2797 v.into_boxed_slice()
2798 }
2799
2800 #[inline]
2801 pub fn length_usize<T>(this: Ptr<[T]>) -> usize {
2802 super::read!(this).len()
2804 }
2805 #[inline]
2806 pub fn length<T>(this: Ptr<[T]>) -> DafnyInt {
2807 int!(length_usize(this))
2808 }
2809 #[inline]
2810 pub fn get_usize<T: Clone>(this: Ptr<[T]>, i: usize) -> T {
2811 this.as_ref()[i].clone()
2813 }
2814 #[inline]
2815 pub fn get<T: Clone>(this: Ptr<[T]>, i: &DafnyInt) -> T {
2816 get_usize(this, i.to_usize().unwrap())
2817 }
2818 #[inline]
2819 pub fn update_usize<T>(this: Ptr<[T]>, i: usize, val: T) {
2820 crate::modify!(this)[i] = val;
2822 }
2823 #[inline]
2824 pub fn update<T>(this: Ptr<[T]>, i: &DafnyInt, val: T) {
2825 update_usize(this, i.to_usize().unwrap(), val);
2826 }
2827}
2828
2829pub fn allocate<T>() -> Ptr<T> {
2833 let this_ptr = Box::into_raw(Box::new(MaybeUninit::uninit())) as *mut MaybeUninit<T> as *mut T;
2834 Ptr::from_raw_nonnull(this_ptr)
2835}
2836#[inline]
2838pub fn deallocate<T: ?Sized>(pointer: Ptr<T>) {
2839 unsafe {
2841 drop(Box::from_raw(pointer.into_raw()));
2844 }
2845}
2846
2847pub struct ExactPool<T: Clone> {
2848 current: T,
2849 yielded: bool,
2850}
2851
2852impl<T: Clone> Iterator for ExactPool<T> {
2854 type Item = T;
2855 fn next(&mut self) -> Option<Self::Item> {
2856 if self.yielded {
2857 None
2858 } else {
2859 self.yielded = true;
2860 Some(self.current.clone())
2861 }
2862 }
2863}
2864pub fn exact_range<T: Clone>(value: T) -> ExactPool<T> {
2865 ExactPool {
2866 current: value,
2867 yielded: false,
2868 }
2869}
2870
2871#[macro_export]
2876macro_rules! is {
2877 ($raw:expr, $id:ty) => {
2878 $crate::modify!($crate::cast_any!($raw))
2879 .downcast_mut::<$id>()
2880 .is_some()
2881 };
2882}
2883
2884#[macro_export]
2885macro_rules! is_object {
2886 ($raw:expr, $id:ty) => {
2887 $crate::md!($crate::cast_any_object!($raw))
2888 .downcast_mut::<$id>()
2889 .is_some()
2890 };
2891}
2892
2893#[macro_export]
2896macro_rules! cast_any {
2897 ($raw:expr) => {
2898 $crate::Upcast::<$crate::DynAny>::upcast($crate::read!($raw))
2899 };
2900}
2901#[macro_export]
2904macro_rules! cast_any_object {
2905 ($obj:expr) => {
2906 $crate::UpcastObject::<$crate::DynAny>::upcast($crate::md!($obj))
2907 };
2908}
2909
2910#[macro_export]
2915macro_rules! update_field_nodrop {
2916 ($ptr:expr, $field:ident, $value:expr) => {
2917 $crate::update_nodrop!($crate::modify!($ptr).$field, $value)
2918 };
2919}
2920
2921#[macro_export]
2923macro_rules! update_field_mut_nodrop {
2924 ($ptr:expr, $field:ident, $value:expr) => {
2925 let lhs = $ptr;
2926 let value = $value;
2927 unsafe { $crate::read!(lhs).$field.get().write(value) }
2928 };
2929}
2930
2931#[macro_export]
2934macro_rules! update_nodrop {
2935 ($ptr:expr, $value:expr) => {
2936 unsafe { ::std::ptr::addr_of_mut!($ptr).write($value) }
2939 }
2940}
2941
2942#[macro_export]
2944macro_rules! modify {
2945 ($ptr:expr) => {{
2946 #[allow(unused_unsafe)]
2947 let tmp =
2948 unsafe { &mut *($crate::UnsafeCell::raw_get($ptr.0.unwrap_unchecked().as_ptr())) };
2949 tmp
2950 }};
2951}
2952
2953#[macro_export]
2955macro_rules! read {
2956 ($ptr:expr) => {{
2957 #[allow(unused_unsafe)]
2958 let tmp = unsafe { &*($crate::UnsafeCell::raw_get($ptr.0.unwrap_unchecked().as_ptr())) };
2959 tmp
2960 }};
2961}
2962
2963#[macro_export]
2965macro_rules! update_field_uninit {
2966 ($t:expr, $field:ident, $field_assigned:expr, $value:expr) => {{
2967 let computed_value = $value;
2968 #[allow(unused_assignments)]
2969 if $field_assigned {
2970 $crate::modify!($t).$field = computed_value;
2971 } else {
2972 $crate::update_field_nodrop!($t, $field, computed_value);
2973 $field_assigned = true;
2974 }
2975 }};
2976}
2977
2978#[macro_export]
2980macro_rules! update_field_mut_uninit {
2981 ($t:expr, $field:ident, $field_assigned:expr, $value:expr) => {{
2982 let computed_value = $value;
2983 #[allow(unused_assignments)]
2984 if $field_assigned {
2985 $crate::modify_field!($crate::read!($t).$field, computed_value);
2986 } else {
2987 $crate::update_field_mut_nodrop!($t, $field, computed_value);
2988 $field_assigned = true;
2989 }
2990 }};
2991}
2992
2993#[macro_export]
2995macro_rules! update_field_if_uninit {
2996 ($t:expr, $field:ident, $field_assigned:expr, $value:expr) => {{
2997 let computed_value = $value;
2998 if !$field_assigned {
2999 $crate::update_field_nodrop!($t, $field, computed_value);
3000 $field_assigned = true;
3001 }
3002 }};
3003}
3004
3005#[macro_export]
3007macro_rules! update_field_mut_if_uninit {
3008 ($t:expr, $field:ident, $field_assigned:expr, $value:expr) => {{
3009 let computed_value = $value;
3010 if !$field_assigned {
3011 $crate::update_field_mut_nodrop!($t, $field, computed_value);
3012 $field_assigned = true;
3013 }
3014 }};
3015}
3016
3017pub struct Ptr<T: ?Sized>(pub Option<NonNull<UnsafeCell<T>>>);
3023
3024#[cfg(feature = "sync")]
3025unsafe impl<T: ?Sized> Send for Ptr<T> {}
3026
3027#[cfg(feature = "sync")]
3028unsafe impl<T: ?Sized> Sync for Ptr<T> {}
3029
3030impl<T: ?Sized> Ptr<T> {
3031 pub fn null() -> Self {
3032 Ptr(None)
3033 }
3034 pub fn is_null(&self) -> bool {
3035 self.0.is_none()
3036 }
3037 #[inline]
3038 pub fn from_raw_nonnull(t: *mut T) -> Ptr<T> {
3039 unsafe {
3040 Ptr(Some(::std::mem::transmute::<
3041 NonNull<T>,
3042 NonNull<UnsafeCell<T>>,
3043 >(NonNull::new_unchecked(t))))
3044 }
3045 }
3046 pub fn from_box(t: Box<T>) -> Ptr<T> {
3047 Self::from_raw_nonnull(Box::into_raw(t))
3048 }
3049 pub fn into_raw(self) -> *mut T {
3050 if self.is_null() {
3051 panic!("Cannot turn a null pointer into a raw pointer");
3052 }
3053 let nonnull = unsafe { self.0.unwrap_unchecked() };
3054 unsafe { ::std::mem::transmute::<_, *mut T>(nonnull.as_ptr()) }
3055 }
3056}
3057
3058impl<T: ?Sized + 'static + Upcast<DynAny>> Ptr<T> {
3059 pub fn is_instance_of<U: 'static>(self) -> bool {
3060 if self.is_null() {
3061 false
3062 } else {
3063 read!(Upcast::<DynAny>::upcast(read!(self)))
3064 .downcast_ref::<U>()
3065 .is_some()
3066 }
3067 }
3068}
3069
3070impl<T> NontrivialDefault for Ptr<T> {
3071 fn nontrivial_default() -> Self {
3072 Self::null()
3074 }
3075}
3076
3077impl<T> Ptr<T> {
3078 pub fn new(val: T) -> Ptr<T> {
3079 Self::from_box(Box::new(val))
3080 }
3081}
3082
3083impl<T: ?Sized> Eq for Ptr<T> {}
3084
3085impl<T: ?Sized> Clone for Ptr<T> {
3086 fn clone(&self) -> Self {
3087 *self
3088 }
3089}
3090
3091impl<T: ?Sized> Copy for Ptr<T> {}
3092
3093impl<T: ?Sized> Default for Ptr<T> {
3094 fn default() -> Self {
3095 Ptr::null()
3096 }
3097}
3098
3099impl<T: ?Sized> Debug for Ptr<T> {
3100 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
3101 self.fmt_print(f, false)
3102 }
3103}
3104impl<T: ?Sized> DafnyPrint for Ptr<T> {
3105 fn fmt_print(&self, f: &mut Formatter<'_>, _in_seq: bool) -> std::fmt::Result {
3106 write!(f, "<object>")
3107 }
3108}
3109
3110impl<T: ?Sized, U: ?Sized> PartialEq<Ptr<U>> for Ptr<T> {
3111 fn eq(&self, other: &Ptr<U>) -> bool {
3112 if !self.is_null() {
3113 if !other.is_null() {
3114 ::std::ptr::eq(
3117 self.clone().into_raw() as *const (),
3118 other.clone().into_raw() as *const (),
3119 )
3120 } else {
3121 false
3122 }
3123 } else if !other.is_null() {
3124 false
3125 } else {
3126 true
3127 }
3128 }
3129}
3130
3131impl<T: ?Sized> Hash for Ptr<T> {
3132 fn hash<H: Hasher>(&self, state: &mut H) {
3133 if !self.is_null() {
3134 (read!(self.clone()) as *const T as *const ()).hash(state);
3135 } else {
3136 0.hash(state);
3137 }
3138 }
3139}
3140
3141impl<T: ?Sized> AsMut<T> for Ptr<T> {
3142 fn as_mut(&mut self) -> &mut T {
3143 modify!(self.clone())
3144 }
3145}
3146impl<T: ?Sized> AsRef<T> for Ptr<T> {
3147 fn as_ref(&self) -> &T {
3148 read!(self.clone())
3149 }
3150}
3151
3152impl<T: ?Sized> Ptr<T> {
3153 pub fn from_ref(r: &T) -> Ptr<T> {
3155 Ptr(unsafe { ::std::mem::transmute::<_, Option<NonNull<UnsafeCell<T>>>>(r as *const T) })
3156 }
3157}
3158#[macro_export]
3160macro_rules! cast {
3161 ($raw:expr, $id:ty) => {{
3162 #[allow(unused_unsafe)]
3163 let tmp = unsafe {
3164 let expr = $raw;
3165 let res: $crate::Ptr<$id> = if expr.is_null() {
3166 $crate::Ptr::null()
3167 } else {
3168 $crate::Ptr::from_raw_nonnull(expr.into_raw() as *mut $id)
3169 };
3170 res
3171 };
3172 tmp
3173 }};
3174}
3175
3176pub struct Object<T: ?Sized>(pub Option<rcmut::RcMut<T>>);
3181
3182impl<T: ?Sized> Object<T> {
3183 pub unsafe fn from_rc(rc: Rc<T>) -> Object<T> {
3185 unsafe { Object(Some(rcmut::from_rc(rc))) }
3186 }
3187 pub fn null() -> Object<T> {
3188 Object(None)
3189 }
3190 pub fn is_null(&self) -> bool {
3191 self.0.is_none()
3192 }
3193}
3194impl<T: ?Sized + 'static + UpcastObject<DynAny>> Object<T> {
3195 pub fn is_instance_of<U: 'static>(self) -> bool {
3196 rd!(UpcastObject::<DynAny>::upcast(rd!(self)))
3198 .downcast_ref::<U>()
3199 .is_some()
3200 }
3201}
3202impl<T> Object<T> {
3203 pub fn new(val: T) -> Object<T> {
3204 Object(Some(rcmut::new(val)))
3205 }
3206}
3207impl<T: ?Sized> Eq for Object<T> {}
3208
3209impl<T: ?Sized> Clone for Object<T> {
3210 fn clone(&self) -> Self {
3211 Object(self.0.clone())
3212 }
3213}
3214
3215impl<T: ?Sized> Default for Object<T> {
3216 fn default() -> Self {
3217 Object(None)
3218 }
3219}
3220
3221impl<T: ?Sized + UpcastObject<DynAny>> Debug for Object<T> {
3222 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
3223 self.fmt_print(f, false)
3224 }
3225}
3226impl<T: ?Sized + UpcastObject<DynAny>> DafnyPrint for Object<T> {
3227 fn fmt_print(&self, f: &mut Formatter<'_>, _in_seq: bool) -> std::fmt::Result {
3228 let obj_any = UpcastObject::<DynAny>::upcast(self.as_ref());
3229 let option_string = obj_any.as_ref().downcast_ref::<String>();
3230 match option_string {
3231 Some(s) => write!(f, "{}", s),
3232 None => write!(f, "<object>"),
3233 }
3234 }
3235}
3236
3237impl<T: DafnyType> DafnyPrint for Object<[T]> {
3238 fn fmt_print(&self, f: &mut Formatter<'_>, _in_seq: bool) -> std::fmt::Result {
3239 write!(f, "<object>")
3240 }
3241}
3242impl UpcastObject<DynAny> for String {
3243 fn upcast(&self) -> Object<DynAny> {
3244 unsafe { Object::from_rc(Rc::new(self.clone()) as Rc<DynAny>) }
3246 }
3247}
3248
3249impl<T: ?Sized, U: ?Sized> PartialEq<Object<U>> for Object<T> {
3250 fn eq(&self, other: &Object<U>) -> bool {
3251 if let Some(p) = &self.0 {
3252 if let Some(q) = &other.0 {
3253 ::std::ptr::eq(p.as_ref().get() as *const (), q.as_ref().get() as *const ())
3256 } else {
3257 false
3258 }
3259 } else if let Some(_q) = &other.0 {
3260 false
3261 } else {
3262 true
3263 }
3264 }
3265}
3266
3267impl<T: ?Sized> Hash for Object<T> {
3268 fn hash<H: Hasher>(&self, state: &mut H) {
3269 if let Some(p) = &self.0 {
3270 (p.as_ref().get() as *const ()).hash(state);
3271 } else {
3272 0.hash(state);
3273 }
3274 }
3275}
3276
3277impl<T: ?Sized> AsMut<T> for Object<T> {
3278 fn as_mut(&mut self) -> &mut T {
3279 unsafe { &mut *(self.0).as_ref().unwrap_unchecked().as_ref().get() }
3280 }
3281}
3282impl<T: ?Sized> AsRef<T> for Object<T> {
3283 fn as_ref(&self) -> &T {
3284 unsafe { &*(self.0).as_ref().unwrap_unchecked().as_ref().get() }
3285 }
3286}
3287
3288#[inline(never)]
3290fn increment_strong_count<T: ?Sized>(data: *const T) {
3291 unsafe {
3293 ::std::hint::black_box(Rc::increment_strong_count(data));
3295 }
3296}
3297
3298impl<T: ?Sized> Object<T> {
3299 #[inline(never)]
3302 pub fn from_ref(r: &T) -> Object<T> {
3303 let pt = r as *const T as *const UnsafeCell<T>;
3304 let rebuilt = ::std::hint::black_box(unsafe { Rc::from_raw(pt) });
3307 let _previous_strong_count = ::std::hint::black_box(Rc::strong_count(&rebuilt));
3308 ::std::hint::black_box(increment_strong_count(pt));
3309 let _new_strong_count = ::std::hint::black_box(Rc::strong_count(&rebuilt));
3310 #[cfg(not(feature = "sync"))]
3311 assert_eq!(_new_strong_count, _previous_strong_count + 1); Object(Some(rebuilt))
3313 }
3314}
3315
3316#[macro_export]
3317macro_rules! cast_object {
3318 ($raw:expr, $id:ty) => {
3319 unsafe {
3320 let res: $crate::Object<$id> = $crate::Object(Some($crate::Rc::from_raw(
3321 $crate::Rc::into_raw($raw.0.unwrap()) as _,
3322 )));
3323 res
3324 }
3325 };
3326}
3327
3328pub fn allocate_object<T>() -> Object<T> {
3330 unsafe { mem::transmute(object::new::<MaybeUninit<T>>(MaybeUninit::uninit())) }
3331}
3332
3333pub struct AllocationTracker {
3334 allocations: Vec<Weak<DynAny>>,
3335}
3336
3337#[cfg(feature = "sync")]
3338pub fn allocate_object_track<T: 'static + Sync + Send>(
3339 allocation_tracker: &mut AllocationTracker,
3340) -> Object<T> {
3341 let res = allocate_object::<T>();
3342 allocation_tracker
3343 .allocations
3344 .push(Rc::<UnsafeCell<T>>::downgrade(&res.0.clone().unwrap()));
3345 res
3346}
3347#[cfg(not(feature = "sync"))]
3348pub fn allocate_object_track<T: 'static>(allocation_tracker: &mut AllocationTracker) -> Object<T> {
3349 let res = allocate_object::<T>();
3350 allocation_tracker
3351 .allocations
3352 .push(Rc::<UnsafeCell<T>>::downgrade(&res.0.clone().unwrap()));
3353 res
3354}
3355
3356#[macro_export]
3358macro_rules! update_field_nodrop_object {
3359 ($ptr:expr, $field: ident, $value:expr) => {
3360 $crate::update_nodrop_object!(
3361 ($crate::rcmut::borrow_mut(&mut $ptr.0.clone().unwrap())).$field,
3362 $value
3363 )
3364 };
3365}
3366
3367#[macro_export]
3369macro_rules! update_field_mut_nodrop_object {
3370 ($ptr:expr, $field: ident, $value:expr) => {
3371 unsafe {
3372 ($crate::rcmut::borrow_mut(&mut $ptr.0.clone().unwrap()))
3373 .$field
3374 .get()
3375 .write($value)
3376 }
3377 };
3378}
3379
3380#[macro_export]
3382macro_rules! update_nodrop_object {
3383 ($ptr:expr, $value:expr) => {
3384 unsafe { ::std::ptr::addr_of_mut!($ptr).write($value) }
3385 };
3386}
3387
3388#[macro_export]
3390macro_rules! update_field_if_uninit_object {
3391 ($t:expr, $field:ident, $field_assigned:expr, $value:expr) => {{
3392 #[allow(unused_assignments)]
3393 if !$field_assigned {
3394 let computed_value = $value;
3395 $crate::update_field_nodrop_object!($t, $field, computed_value);
3396 $field_assigned = true;
3397 }
3398 }};
3399}
3400
3401#[macro_export]
3403macro_rules! update_field_mut_if_uninit_object {
3404 ($t:expr, $field:ident, $field_assigned:expr, $value:expr) => {{
3405 #[allow(unused_assignments)]
3406 if !$field_assigned {
3407 let computed_value = $value;
3408 $crate::update_field_mut_nodrop_object!($t, $field, computed_value);
3409 $field_assigned = true;
3410 }
3411 }};
3412}
3413
3414#[macro_export]
3416macro_rules! update_field_uninit_object {
3417 ($t:expr, $field:ident, $field_assigned:expr, $value:expr) => {{
3418 let computed_value = $value;
3419 #[allow(unused_assignments)]
3420 if $field_assigned {
3421 $crate::md!($t).$field = computed_value;
3422 } else {
3423 $crate::update_field_nodrop_object!($t, $field, computed_value);
3424 $field_assigned = true;
3425 }
3426 }};
3427}
3428
3429#[macro_export]
3431macro_rules! update_field_mut_uninit_object {
3432 ($t:expr, $field:ident, $field_assigned:expr, $value:expr) => {{
3433 let computed_value = $value;
3434 #[allow(unused_assignments)]
3435 if $field_assigned {
3436 $crate::modify_field!($crate::rd!($t).$field, computed_value);
3437 } else {
3438 $crate::update_field_mut_nodrop_object!($t, $field, computed_value);
3439 $field_assigned = true;
3440 }
3441 }};
3442}
3443
3444#[macro_export]
3446macro_rules! md {
3447 ($x:expr) => {
3448 $x.clone().as_mut()
3449 };
3450}
3451
3452#[macro_export]
3454macro_rules! rd {
3455 ($x:expr) => {
3456 $x.as_ref()
3457 };
3458}
3459
3460#[macro_export]
3462macro_rules! modify_field {
3463 ($pointer:expr, $rhs:expr) => {{
3464 let lhs = $pointer.get();
3465 let rhs = $rhs;
3466 unsafe { *lhs = rhs }
3467 }};
3468}
3469
3470#[macro_export]
3472macro_rules! read_field {
3473 ($pointer:expr) => {{
3474 let lhs = $pointer.get();
3475 unsafe { (*lhs).clone() }
3476 }};
3477}
3478
3479pub type Field<T> = UnsafeCell<T>;
3480pub fn new_field<T>(t: T) -> Field<T> {
3481 UnsafeCell::new(t)
3482}
3483
3484#[macro_export]
3486macro_rules! refcount {
3487 ($x:expr) => {
3488 $crate::Rc::strong_count(unsafe { $crate::rcmut::as_rc($x.0.as_ref().unwrap()) })
3489 };
3490}
3491
3492pub mod object {
3493 use crate::{Any, DynAny};
3494
3495 pub fn downcast<T: 'static>(_self: crate::Object<DynAny>) -> crate::Object<T> {
3496 super::cast_object!(_self, T)
3497 }
3498
3499 pub fn new<T>(val: T) -> crate::Object<T> {
3500 crate::Object(Some(crate::rcmut::new(val)))
3501 }
3502 #[inline]
3503 pub fn is<T: 'static + Any>(_self: crate::Object<DynAny>) -> bool {
3504 is_object!(_self, T)
3505 }
3506}
3507
3508pub mod rcmut {
3510 use crate::Rc;
3511 use crate::UnsafeCell;
3512 use ::std::mem::{self, MaybeUninit};
3513
3514 pub fn array_object_from_rc<T>(data: Rc<[T]>) -> crate::Object<[T]> {
3515 crate::Object(Some(unsafe { from_rc(data) }))
3516 }
3517 pub fn array_object_from_box<T>(data: Box<[T]>) -> crate::Object<[T]> {
3518 let data: Rc<[T]> = data.into();
3519 crate::Object(Some(unsafe { from_rc(data) }))
3520 }
3521 pub struct Array<T> {
3522 pub data: Box<[T]>,
3523 }
3524 impl<T> Array<T> {
3525 pub fn new(data: Box<[T]>) -> crate::Object<Array<T>> {
3526 crate::Object(Some(new(Array { data })))
3527 }
3528
3529 pub fn placebos_usize_object(length: usize) -> crate::Object<Array<MaybeUninit<T>>> {
3530 let x = crate::array::placebos_box_usize::<T>(length);
3531 Array::<MaybeUninit<T>>::new(x)
3532 }
3533 }
3534 pub type RcMut<T> = Rc<UnsafeCell<T>>;
3536
3537 pub fn new<T>(val: T) -> RcMut<T> {
3539 Rc::new(UnsafeCell::new(val))
3540 }
3541 pub unsafe fn from<T>(value: Box<T>) -> RcMut<T> {
3543 unsafe { mem::transmute(Rc::new(*value)) }
3544 }
3545
3546 pub unsafe fn from_rc<T: ?Sized>(value: Rc<T>) -> RcMut<T> {
3547 unsafe { mem::transmute(value) }
3548 }
3549
3550 pub unsafe fn as_rc<T: ?Sized>(this: &RcMut<T>) -> &Rc<T> {
3551 unsafe { mem::transmute(this) }
3552 }
3553 pub unsafe fn to_rc<T: ?Sized>(this: RcMut<T>) -> Rc<T> {
3554 unsafe { mem::transmute(this) }
3555 }
3556
3557 pub unsafe fn as_rc_mut<T: ?Sized>(this: &mut RcMut<T>) -> &mut Rc<T> {
3559 unsafe { mem::transmute(this) }
3560 }
3561
3562 #[inline]
3564 pub unsafe fn borrow<T: ?Sized>(this: &RcMut<T>) -> &T {
3565 unsafe { &*this.get() }
3566 }
3567
3568 #[inline]
3570 pub unsafe fn borrow_mut<T: ?Sized>(this: &mut RcMut<T>) -> &mut T {
3571 unsafe { &mut *this.get() }
3572 }
3573
3574 #[cfg(feature = "sync")]
3575 pub unsafe fn downcast<T: 'static + Send + Sync>(
3576 this: RcMut<crate::DynAny>,
3577 ) -> Option<RcMut<T>> {
3578 let t: Rc<crate::DynAny> = unsafe { to_rc(this) };
3579 let t: Rc<T> = Rc::downcast::<T>(t).ok()?;
3580 unsafe { mem::transmute(t) }
3581 }
3582
3583 #[cfg(not(feature = "sync"))]
3584 pub unsafe fn downcast<T: 'static>(this: RcMut<crate::DynAny>) -> Option<RcMut<T>> {
3585 let t: Rc<crate::DynAny> = unsafe { to_rc(this) };
3586 let t: Rc<T> = Rc::downcast::<T>(t).ok()?;
3587 unsafe { mem::transmute(t) }
3588 }
3589}
3590
3591#[derive(Clone)]
3600pub struct MaybePlacebo<T>(Option<T>);
3601impl<T: Clone> MaybePlacebo<T> {
3602 #[inline]
3603 pub fn read(&self) -> T {
3604 unsafe { self.0.clone().unwrap_unchecked() }
3606 }
3607}
3608
3609impl<T> MaybePlacebo<T> {
3610 #[inline]
3611 pub fn new() -> Self {
3612 MaybePlacebo(None)
3613 }
3614 #[inline]
3615 pub fn from(v: T) -> Self {
3616 MaybePlacebo(Some(v))
3617 }
3618}
3619
3620#[macro_export]
3621macro_rules! tuple_extract_index {
3622 ($x:expr, $i:expr) => {
3623 $x.$i
3624 };
3625}
3626
3627#[macro_export]
3632macro_rules! maybe_placebos_from {
3633 ($x:expr, $($i:tt), *) => {
3634 {
3635 let x = $x;
3636 (
3637 $( $crate::MaybePlacebo::from(x.$i), )*
3638 )
3639 }
3640 }
3641}
3642
3643pub fn upcast_object<A: ?Sized, B: ?Sized>() -> Rc<impl Fn(Object<A>) -> Object<B>>
3648where
3649 A: UpcastObject<B>,
3650{
3651 Rc::new(|x: Object<A>| x.as_ref().upcast())
3652}
3653
3654pub fn upcast<A: ?Sized, B: ?Sized>() -> Rc<impl Fn(Ptr<A>) -> Ptr<B>>
3655where
3656 A: Upcast<B>,
3657{
3658 Rc::new(|x: Ptr<A>| read!(x).upcast())
3659}
3660
3661pub fn upcast_box<A, B: ?Sized>() -> Rc<impl Fn(A) -> Box<B>>
3662where
3663 A: UpcastBox<B>,
3664{
3665 Rc::new(|x: A| UpcastBox::upcast(&x))
3666}
3667pub fn upcast_box_box<A: ?Sized, B: ?Sized>() -> Rc<impl Fn(Box<A>) -> Box<B>>
3668where
3669 A: UpcastBox<B>,
3670{
3671 Rc::new(|x: Box<A>| UpcastBox::upcast(x.as_ref()))
3672}
3673
3674pub fn upcast_id<A>() -> Rc<impl Fn(A) -> A> {
3675 Rc::new(|x: A| x)
3676}
3677
3678pub fn rc_coerce<T: Clone, U: Clone>(f: Rc<impl Fn(T) -> U>) -> Rc<impl Fn(Rc<T>) -> Rc<U>> {
3679 Rc::new(move |x: Rc<T>| Rc::new(f.as_ref()(x.as_ref().clone())))
3680}
3681pub fn box_coerce<T: Clone, U: Clone>(f: Box<impl Fn(T) -> U>) -> Box<impl Fn(Box<T>) -> Box<U>> {
3682 Box::new(move |x: Box<T>| Box::new(f.as_ref()(x.as_ref().clone())))
3683}
3684
3685pub fn fn1_coerce<T: Clone + 'static, A: Clone + 'static, R: Clone + 'static>(
3686 a_to_r: Rc<impl Fn(A) -> R + 'static>,
3687) -> Rc<impl Fn(Rc<dyn Fn(&T) -> A>) -> Rc<dyn Fn(&T) -> R> + 'static> {
3688 Rc::new(move |t_to_a: Rc<dyn Fn(&T) -> A>| {
3689 let a_to_r = a_to_r.clone();
3690 let t_to_a = t_to_a.clone();
3691 let r: Rc<dyn Fn(&T) -> R + 'static> = Rc::new(move |t: &T| a_to_r(t_to_a(t)));
3692 r
3693 })
3694}
3695
3696pub trait Upcast<T: ?Sized> {
3698 fn upcast(&self) -> Ptr<T>;
3699}
3700pub trait UpcastObject<T: ?Sized> {
3701 fn upcast(&self) -> Object<T>;
3702}
3703impl<T: ?Sized> Upcast<T> for T {
3704 fn upcast(&self) -> Ptr<T> {
3705 Ptr::from_raw_nonnull(self as *const T as *mut T)
3706 }
3707}
3708impl<T: ?Sized> UpcastObject<T> for T {
3709 fn upcast(&self) -> Object<T> {
3710 Object::from_ref(self)
3711 }
3712}
3713
3714pub trait UpcastBox<T: ?Sized> {
3716 fn upcast(&self) -> Box<T>;
3717}
3718
3719impl<T: ?Sized, U> UpcastBox<T> for Rc<U>
3720where
3721 U: UpcastBox<T>,
3722{
3723 fn upcast(&self) -> Box<T> {
3724 UpcastBox::upcast(AsRef::as_ref(self))
3725 }
3726}
3727
3728pub trait AnyRef {
3729 fn as_any_ref(&self) -> &dyn Any;
3730}
3731
3732impl<T: 'static> AnyRef for T {
3733 fn as_any_ref(&self) -> &dyn Any {
3734 self
3735 }
3736}
3737
3738#[macro_export]
3739macro_rules! Extends {
3740 ($traitType: tt) => {
3741 $traitType + ::dafny_runtime::Upcast<dyn $traitType>
3742 }
3743}
3744
3745#[macro_export]
3746macro_rules! UpcastFn {
3747 ($B:ty) => {
3748 fn upcast(&self) -> $crate::Ptr<$B> {
3749 $crate::Ptr::from_raw_nonnull(self as *const Self as *mut Self as *mut $B)
3750 }
3751 };
3752}
3753
3754#[macro_export]
3755macro_rules! UpcastObjectFn {
3756 ($B:ty) => {
3757 fn upcast(&self) -> $crate::Object<$B> {
3758 $crate::Object::from_ref(self as &$B)
3759 }
3760 };
3761}
3762
3763#[macro_export]
3765macro_rules! UpcastDef {
3766 ($A:ty, $B:ty) => {
3767 impl $crate::Upcast<$B> for $A {
3768 $crate::UpcastFn!($B);
3769 }
3770 };
3771
3772 ($A:ty, $B:ty, $($C: ty),*) => {
3773 $crate::UpcastDef!($A, $B);
3774 $crate::UpcastDef!($A, $($C),*);
3775 }
3776}
3777
3778#[macro_export]
3779macro_rules! UpcastDefObject {
3780 ($A:ty, $B:ty) => {
3781 impl $crate::UpcastObject<$B> for $A {
3782 $crate::UpcastObjectFn!($B);
3783 }
3784 };
3785
3786 ($A:ty, $B:ty, $($C: ty),*) => {
3787 $crate::UpcastDefObject!($A, $B);
3788 $crate::UpcastDefObject!($A, $($C),*);
3789 }
3790}
3791
3792impl<U: DafnyTypeEq> Set<U> {
3794 pub fn coerce<V: DafnyTypeEq>(f: Rc<impl Fn(U) -> V>) -> Rc<impl Fn(Set<U>) -> Set<V>> {
3795 Rc::new(move |x: Set<U>| {
3796 let f2 = f.clone();
3798 let mut new_set: HashSet<V> = HashSet::<V>::default();
3799 for value in x.data.iter() {
3800 new_set.insert(f2(value.clone()));
3801 }
3802 Set::from_hashset_owned(new_set)
3803 })
3804 }
3805}
3806
3807impl<U: DafnyType> Sequence<U> {
3809 pub fn coerce<V: DafnyType>(f: Rc<impl Fn(U) -> V>) -> Rc<impl Fn(Sequence<U>) -> Sequence<V>> {
3810 Rc::new(move |x: Sequence<U>| {
3812 let mut new_seq: Vec<V> = Vec::<V>::default();
3813 let f2 = f.clone();
3814 for value in x.to_array().iter() {
3815 new_seq.push(f2(value.clone()));
3816 }
3817 Sequence::from_array_owned(new_seq)
3818 })
3819 }
3820}
3821
3822impl<U: DafnyTypeEq> Multiset<U> {
3824 pub fn coerce<V: DafnyTypeEq>(
3825 f: Rc<impl Fn(U) -> V>,
3826 ) -> Rc<impl Fn(Multiset<U>) -> Multiset<V>> {
3827 Rc::new(move |x: Multiset<U>| {
3829 let f2 = f.clone();
3830 let mut new_multiset: HashMap<V, DafnyInt> = HashMap::<V, DafnyInt>::default();
3832 for (value, count) in x.data.into_iter() {
3833 new_multiset.insert(f2(value), count.clone());
3834 }
3835 Multiset::from_hashmap_owned(new_multiset)
3836 })
3837 }
3838}
3839
3840impl<K: DafnyTypeEq, U: DafnyTypeEq> Map<K, U> {
3842 pub fn coerce<V: DafnyTypeEq>(f: Rc<impl Fn(U) -> V>) -> Rc<impl Fn(Map<K, U>) -> Map<K, V>> {
3843 Rc::new(move |x: Map<K, U>| {
3845 let f2 = f.clone();
3846 let mut new_map: HashMap<K, V> = HashMap::<K, V>::default();
3847 for (key, value) in x.data.iter() {
3848 new_map.insert(key.clone(), f2(value.clone()));
3849 }
3850 Map::from_hashmap_owned(new_map)
3851 })
3852 }
3853}