dafny_runtime/
lib.rs

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    // missing_debug_implementations,
14    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>, // UnsafeCell for interior mutability
96}
97// SAFETY: UnsafeCell is not possibly sync normally.
98// However, we use it only for raw pointers, and fields and access to read and write
99// to fields will be subject to mutexes in any cases.
100#[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
120// An atomic box is just a RefCell in Rust
121pub 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
137// Dafny's type (0) compiles to NontrivialDefault to prevent subset types from being considered as Default if their witness is nonzero
138pub 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        // Conversion to and from Dafny reference-counted classes. All these methods take ownership of the class.
167        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        // Conversions to and from Dafny arrays. They all take ownership
187        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            // SAFETY: We own the array
192            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        // Conversion to and from Dafny reference-counted classes. All these methods take ownership of the class.
206        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        // Conversions to and from Dafny arrays. They all take ownership
219        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    // Used for external conversions
240    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    // --unicode-char:true
283    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    // --unicode-char:false
299    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            // Push T as many times as its size
348            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
368// **************
369// Dafny integers
370// **************
371
372impl 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// truncate_u(x, u64)
385// = <DafnyInt as ToPrimitive>::to_u128(&x).unwrap() as u64;
386#[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
405// Now the same but for &[u8, N] for any kind of such references
406impl<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
431// **************
432// Immutable sequences
433// **************
434
435impl<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        // Iterate over the elements
450        for elt in array.iter() {
451            elt.hash(state);
452        }
453    }
454}
455
456// Clone can be derived automatically
457#[derive(Clone)]
458pub enum Sequence<T>
459where
460    T: DafnyType,
461{
462    ArraySequence {
463        // Values could be a native array because we will know statically that all
464        // accesses are in bounds when using this data structure
465        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        // Let's convert the if then else below to a proper match statement
538        match self {
539            Sequence::ArraySequence { values, .. } =>
540            // The length of the elements
541            {
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's create an array of size length and fill it up recursively
569                // We don't materialize nested arrays because most of the time they are forgotten
570                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            // SAFETY: The invariant is that this_ptr is always a pointer to a sub-sequence of the original `this`parameter when following the field name 'right', which are allocated in this scope
611            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                // Let's create an array of size length and fill it up recursively
625                {
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    /// Returns the cardinality or length of this [`Sequence<T>`].
688    pub fn cardinality_usize(&self) -> SizeT {
689        match self {
690            Sequence::ArraySequence { values, .. } =>
691            // The length of the elements
692            {
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
775// Makes it possible to write iterator.collect::<Sequence<T>> and obtain a sequence
776impl<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        // Iterate through both elements and verify that they are equal
793        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        // Comparison is only prefix-based
809        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// **************
865// Immutable maps
866// **************
867
868#[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); // Worst performance for things that are not hashable like maps
894    }
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    // Dafny will normally guarantee that the key exists.
969    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        // Overriding self's keys with other's keys if there are some.
981        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        // Dafny will prove that overriding has the same value anyway
1102        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// **************
1141// Immutable sets
1142// **************
1143
1144#[derive(Clone)]
1145pub struct Set<V: DafnyTypeEq> {
1146    data: Rc<HashSet<V>>,
1147}
1148
1149// Since there is no canonical way to iterate over a set to compute the hash.
1150impl<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        // 1. Same cardinality
1178        // 2. All the elements of self are in the other
1179        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        // Partial ordering is inclusion
1200        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        // iterate over the other, add only not contained elements
1265        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        // Start with an empty vec with capacity the smallest of both sets
1281        let mut result = HashSet::new();
1282
1283        // iterate over the other, take only elements in common
1284        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        // Start with a vec the size of the first one
1300        let mut result = HashSet::new();
1301
1302        // iterate over the other, take only elements not in second
1303        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            // iterate over the other, take only elements not in self
1320            for value in other.data.iter() {
1321                if self.contains(value) {
1322                    return false;
1323                }
1324            }
1325        } else {
1326            // iterate over the self, take only elements not in other
1327            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        // iterate over the other, take only elements not in second
1341        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        // Dafny will prove that overriding has the same value anyway
1387        self.data.insert(value.clone(), true);
1388    }
1389    pub fn build(self) -> Set<T> {
1390        // Iterate over all the key values of the hashmap and add them to an array
1391        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// *******************
1425// Immutable multisets
1426// *******************
1427
1428#[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        // iterate over the other, take only elements not in second
1679        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
1779// Unbounded versions
1780
1781pub 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")]
1839// Convert the DafnyPrint above into a macro so that we can create it for functions of any input arity
1840macro_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"))]
1850// Convert the DafnyPrint above into a macro so that we can create it for functions of any input arity
1851macro_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
1861// Now create a loop like impl_tuple_print_loop so that we can create functions up to size 32
1862macro_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}
1870// Emit functions till 32 parameters
1871dafny_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    // Vec<char> gets special treatment so we carry that information here
1904    #[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
2234// 32 elements ought to be enough for everyone
2235impl_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// seq!(1, 2, 3) is rewritten to Sequence::from_array_owned(vec!(1, 2, 3))
2243#[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            // No warning about this variable not needing to be mut in the case of an empty set
2255            #[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// we enable the syntax map![k1 => v1, k2 => v2]
2289#[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
2310//////////
2311// Arrays
2312//////////
2313
2314macro_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// An 1-dimensional Dafny array is a zero-cost abstraction over a pointer on a native array
2340#[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
2361// ARRAY_DATA_TYPE(length0, length1, length2) will return
2362// Box<[Box<[Box<[T]>]>]>
2363macro_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 to generate generalizations of the function placebos_usize to higher-dimensions arrays
2373
2374#[macro_export]
2375macro_rules! INIT_ARRAY_DATA {
2376    // Handle the innermost array initialization
2377    ($ArrayType:ident, $last_length:ident) => {
2378        ARRAY_INIT_INNER!($last_length)
2379    };
2380    // Handle recursive array initialization for multiple dimensions
2381    ($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    // Accepts any number of length identifiers
2388    ($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            // SAFETY: We know the object is owned and never referred to by anything else
2414            $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        // Once all the elements have been initialized, transform the signature of the pointer
2431        pub fn construct(p: $crate::Ptr<$ArrayType<$crate::MaybeUninit<T>>>) -> $crate::Ptr<$ArrayType<T>> {
2432            unsafe { std::mem::transmute(p) }
2433        }
2434        // Once all the elements have been initialized, transform the signature of the pointer
2435        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
2544// Array2 to Array16
2545
2546ARRAY_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    // Once all the elements have been initialized, transform the signature of the pointer
2764    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        // This code is optimized to take a constant time. See:
2776        // https://users.rust-lang.org/t/allocate-a-boxed-array-of-maybeuninit/110169/7
2777        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        // safety: Dafny won't call this function unless it can guarantee the array is still allocated
2803        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        // safety: Dafny won't call this function unless it can guarantee the array is still allocated
2812        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        // safety: Dafny won't call this function unless it can guarantee the array is still allocated
2821        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
2829///////////////////
2830// Class helpers //
2831///////////////////
2832pub 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// Generic function to safely deallocate a raw pointer
2837#[inline]
2838pub fn deallocate<T: ?Sized>(pointer: Ptr<T>) {
2839    // safety: Dafny won't call this function unless it can guarantee the object is still allocated
2840    unsafe {
2841        // Takes ownership of the reference,
2842        // so that it's deallocated at the end of the method
2843        drop(Box::from_raw(pointer.into_raw()));
2844    }
2845}
2846
2847pub struct ExactPool<T: Clone> {
2848    current: T,
2849    yielded: bool,
2850}
2851
2852// Implement iterator for an exact pool, yielding
2853impl<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// Any Dafny trait must require classes extending it to have a method "as_any_mut"
2872// that can convert the reference from that trait to a reference of Any
2873
2874// 'is' is meant to be used on references only, to check if a trait reference is a class reference
2875#[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// cast_any is meant to be used on references only, to convert any references (classes or traits)*
2894// to an Any reference trait
2895#[macro_export]
2896macro_rules! cast_any {
2897    ($raw:expr) => {
2898        $crate::Upcast::<$crate::DynAny>::upcast($crate::read!($raw))
2899    };
2900}
2901// cast_any_object is meant to be used on references only, to convert any references (classes or traits)*
2902// to an Any reference trait
2903#[macro_export]
2904macro_rules! cast_any_object {
2905    ($obj:expr) => {
2906        $crate::UpcastObject::<$crate::DynAny>::upcast($crate::md!($obj))
2907    };
2908}
2909
2910// When initializing an uninitialized field for the first time,
2911// we ensure we don't drop the previous content
2912// This is problematic if the same field is overwritten multiple times
2913/// In that case, prefer to use update_uninit
2914#[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// Same as update_field_nodrop but for mutable fields
2922#[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// When initializing an uninitialized field for the first time,
2932// we ensure we don't drop the previous content
2933#[macro_export]
2934macro_rules! update_nodrop {
2935    ($ptr:expr, $value:expr) => {
2936        // safety: Dafny won't call this function unless it can guarantee the value at the address was not
2937        // yet initialized, so that not dropping it won't create a memory leak
2938        unsafe { ::std::ptr::addr_of_mut!($ptr).write($value) }
2939    }
2940}
2941
2942// Given a class or array pointer, transforms it to a mutable reference
2943#[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// Given a class or array pointer, transforms it to a read-only reference
2954#[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// If the field is guaranteed to be assigned only once, update_field_nodrop is sufficient
2964#[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// Same as update_field_uninit but for mutable fields
2979#[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 to call at the end of the first new; constructor when not every field is guaranteed to be assigned.
2994#[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// Same as update_field_if_uninit but for mutable fields
3006#[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
3017/////////////////
3018// Raw pointers (require wrapping because of equality)
3019/////////////////
3020
3021// This Ptr has the same run-time space as *mut
3022pub 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        // Create a null pointer
3073        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                // To compare addresses, we need to ensure we only compare thin pointers
3115                // https://users.rust-lang.org/t/comparing-addresses-between-fat-and-thin-pointers/89008
3116                ::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    // Never use on local values, only on &self types previously called on Ptr types.
3154    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// cast is meant to be used on references only, to downcast a trait reference to a class reference
3159#[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
3176/////////////////
3177// Reference-counted classes mode
3178/////////////////
3179
3180pub struct Object<T: ?Sized>(pub Option<rcmut::RcMut<T>>);
3181
3182impl<T: ?Sized> Object<T> {
3183    // For safety, it requires the Rc to have been created with Rc::new()
3184    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        // safety: Dafny won't call this function unless it can guarantee the object is still allocated
3197        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        // SAFETY: RC was just created
3245        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                // To compare addresses, we need to ensure we only compare thin pointers
3254                // https://users.rust-lang.org/t/comparing-addresses-between-fat-and-thin-pointers/89008
3255                ::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// Never inline because, when compiling with cargo --release, sometimes it gets rid of this statement
3289#[inline(never)]
3290fn increment_strong_count<T: ?Sized>(data: *const T) {
3291    // SAFETY: This method is called only on values that were constructed from an Rc
3292    unsafe {
3293        // Black box avoids the compiler wrongly inferring that increment strong count does nothing since the data it was applied to can be traced to be borrowed
3294        ::std::hint::black_box(Rc::increment_strong_count(data));
3295    }
3296}
3297
3298impl<T: ?Sized> Object<T> {
3299    // SAFETY: This function needs to be called from a reference obtained by calling read!(o) on an object
3300    // We never inline this function, otherwise the compiler might figure out a way to remove the increment_strong_count
3301    #[inline(never)]
3302    pub fn from_ref(r: &T) -> Object<T> {
3303        let pt = r as *const T as *const UnsafeCell<T>;
3304        // SAFETY: Not guaranteed unfortunately. But looking at the sources of from_raw as of today 10/24/2024
3305        // it will will correctly rebuilt the Rc
3306        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); // Will panic if not. Asserted only in sequential mode
3312        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
3328// Returns an object whose fields are yet initialized. Only use update_field_uninit_object  and update_field_if_uninit_object to initialize fields.
3329pub 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// Equivalent of update_field_nodrop but for rcmut
3357#[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// Same but for mutable fields
3368#[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// Equivalent of update_nodrop but for rcmut
3381#[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// Equivalent of update_field_if_uninit but for rcmut
3389#[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// Same for mutable fields
3402#[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// Equivalent of update_field_uninit but for rcmut
3415#[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// Same but for mutable fields
3430#[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// Equivalent of modify but for rcmut
3445#[macro_export]
3446macro_rules! md {
3447    ($x:expr) => {
3448        $x.clone().as_mut()
3449    };
3450}
3451
3452// Equivalent of read but for rcmut
3453#[macro_export]
3454macro_rules! rd {
3455    ($x:expr) => {
3456        $x.as_ref()
3457    };
3458}
3459
3460// To use when modifying a mutable field that is wrapped with UnsafeCell
3461#[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// To use when reading a mutable field that is wrapped with UnsafeCell
3471#[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// Count the number of references to the given object
3485#[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
3508// Inspired from https://crates.io/crates/rcmut
3509pub 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    /// A reference counted smart pointer with unrestricted mutability.
3535    pub type RcMut<T> = Rc<UnsafeCell<T>>;
3536
3537    /// Create a new RcMut for a value.
3538    pub fn new<T>(val: T) -> RcMut<T> {
3539        Rc::new(UnsafeCell::new(val))
3540    }
3541    /// Retrieve the inner Rc as a reference.
3542    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    /// Retrieve the inner Rc as a mutable reference.
3558    pub unsafe fn as_rc_mut<T: ?Sized>(this: &mut RcMut<T>) -> &mut Rc<T> {
3559        unsafe { mem::transmute(this) }
3560    }
3561
3562    /// Get a reference to the value.
3563    #[inline]
3564    pub unsafe fn borrow<T: ?Sized>(this: &RcMut<T>) -> &T {
3565        unsafe { &*this.get() }
3566    }
3567
3568    /// Get a mutable reference to the value.
3569    #[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/////////////////
3592// Method helpers
3593/////////////////
3594
3595// A MaybePlacebo is a value that is either a placebo or a real value.
3596// It is a wrapper around a MaybeUninit<T> value, but knowing whether the value is a placebo or not.
3597// That way, when it is dropped, the underlying value is only dropped if it is not a placebo.
3598
3599#[derive(Clone)]
3600pub struct MaybePlacebo<T>(Option<T>);
3601impl<T: Clone> MaybePlacebo<T> {
3602    #[inline]
3603    pub fn read(&self) -> T {
3604        // safety: Dafny will guarantee we will never read a placebo value
3605        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// A macro that maps tuple (a, b, c...) to produce (MaybePlacebo::from(a), MaybePlacebo::from(b), MaybePlacebo::from(c))
3628// maybe_placebos_from!(expr, 0, 1, 2, 3)
3629// = let x = expr;
3630//   (MaybePlacebo::from(x.0), MaybePlacebo::from(x.1), MaybePlacebo::from(x.2), MaybePlacebo::from(x.3))
3631#[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
3643////////////////
3644// Coercion
3645////////////////
3646
3647pub 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
3696// For pointers
3697pub 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
3714// For general traits
3715pub 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// It works only when there is no type parameters for $A...
3764#[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
3792// Coercions for sets
3793impl<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            // We need to upcast individual elements
3797            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
3807// Coercions for sequences
3808impl<U: DafnyType> Sequence<U> {
3809    pub fn coerce<V: DafnyType>(f: Rc<impl Fn(U) -> V>) -> Rc<impl Fn(Sequence<U>) -> Sequence<V>> {
3810        // We need to upcast individual elements
3811        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
3822// Coercions for multisets
3823impl<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        // We need to upcast individual elements
3828        Rc::new(move |x: Multiset<U>| {
3829            let f2 = f.clone();
3830            // We need to upcast individual elements
3831            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
3840// Coercions for Maps
3841impl<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        // We need to upcast individual elements
3844        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}