dafny_runtime/
lib.rs

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