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>, }
59#[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
82pub 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
99pub 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 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 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 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 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 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 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 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 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 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#[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#[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 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
620impl 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
683impl<'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
709impl<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 for elt in array.iter() {
729 elt.hash(state);
730 }
731 }
732}
733
734#[derive(Clone)]
736pub enum Sequence<T>
737where
738 T: DafnyType,
739{
740 ArraySequence {
741 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 match self {
817 Sequence::ArraySequence { values, .. } =>
818 {
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 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 {
904 for value in values.iter() {
905 array.push(value.clone());
906 }
907 }
908 Sequence::ConcatSequence {
909 cache: boxed, left, right, ..
910 } =>
911 {
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 pub fn cardinality_usize(&self) -> SizeT {
934 match self {
935 Sequence::ArraySequence { values, .. } =>
936 {
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
1023impl<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 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 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#[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); }
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 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 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 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#[derive(Clone)]
1385pub struct Set<V: DafnyTypeEq> {
1386 data: Rc<HashSet<V>>,
1387}
1388
1389impl<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 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 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 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 let mut result = HashSet::new();
1522
1523 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 let mut result = HashSet::new();
1541
1542 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 for value in other.data.iter() {
1561 if self.contains(value) {
1562 return false;
1563 }
1564 }
1565 } else {
1566 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 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 self.data.insert(value.clone(), true);
1622 }
1623 pub fn build(self) -> Set<T> {
1624 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#[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 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
2017pub 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")]
2077macro_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"))]
2088macro_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
2099macro_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}
2108dafny_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 #[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
2558impl_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#[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 #[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#[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
2634macro_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#[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
2685macro_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_export]
2699macro_rules! INIT_ARRAY_DATA {
2700 ($ArrayType:ident, $last_length:ident) => {
2702 ARRAY_INIT_INNER!($last_length)
2703 };
2704 ($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 ($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 $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 pub fn construct(p: $crate::Ptr<$ArrayType<$crate::MaybeUninit<T>>>) -> $crate::Ptr<$ArrayType<T>> {
2756 unsafe { std::mem::transmute(p) }
2757 }
2758 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
2868ARRAY_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 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 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 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 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 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
3153pub 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#[inline]
3162pub fn deallocate<T: ?Sized>(pointer: Ptr<T>) {
3163 unsafe {
3165 let _ = Box::from_raw(pointer.into_raw());
3168 }
3169}
3170
3171pub struct ExactPool<T: Clone> {
3172 current: T,
3173 yielded: bool,
3174}
3175
3176impl<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#[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#[macro_export]
3220macro_rules! cast_any {
3221 ($raw:expr) => {
3222 $crate::Upcast::<$crate::DynAny>::upcast($crate::read!($raw))
3223 };
3224}
3225#[macro_export]
3228macro_rules! cast_any_object {
3229 ($obj:expr) => {
3230 $crate::UpcastObject::<$crate::DynAny>::upcast($crate::md!($obj))
3231 };
3232}
3233
3234#[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#[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#[macro_export]
3258macro_rules! update_nodrop {
3259 ($ptr:expr, $value:expr) => {
3260 unsafe { ::std::ptr::addr_of_mut!($ptr).write($value) }
3263 }
3264}
3265
3266#[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#[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#[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#[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_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#[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
3341pub 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 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 ::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 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#[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
3500pub struct Object<T: ?Sized>(pub Option<rcmut::RcMut<T>>);
3505
3506impl<T: ?Sized> Object<T> {
3507 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 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 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 ::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#[inline(never)]
3614fn increment_strong_count<T: ?Sized>(data: *const T) {
3615 unsafe {
3617 ::std::hint::black_box(Rc::increment_strong_count(data));
3619 }
3620}
3621
3622impl<T: ?Sized> Object<T> {
3623 #[inline(never)]
3626 pub fn from_ref(r: &T) -> Object<T> {
3627 let pt = r as *const T as *const UnsafeCell<T>;
3628 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); 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
3651pub 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#[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#[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#[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#[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#[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#[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#[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#[macro_export]
3769macro_rules! md {
3770 ($x:expr) => {
3771 $x.clone().as_mut()
3772 };
3773}
3774
3775#[macro_export]
3777macro_rules! rd {
3778 ($x:expr) => {
3779 $x.as_ref()
3780 };
3781}
3782
3783#[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#[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#[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
3831pub 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 pub type RcMut<T> = Rc<UnsafeCell<T>>;
3859
3860 pub fn new<T>(val: T) -> RcMut<T> {
3862 Rc::new(UnsafeCell::new(val))
3863 }
3864 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 pub unsafe fn as_rc_mut<T: ?Sized>(this: &mut RcMut<T>) -> &mut Rc<T> {
3882 mem::transmute(this)
3883 }
3884
3885 #[inline]
3887 pub unsafe fn borrow<T: ?Sized>(this: &RcMut<T>) -> &T {
3888 mem::transmute(this.get())
3889 }
3890
3891 #[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#[derive(Clone)]
3923pub struct MaybePlacebo<T>(Option<T>);
3924impl<T: Clone> MaybePlacebo<T> {
3925 #[inline]
3926 pub fn read(&self) -> T {
3927 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#[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
3966pub 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
4019pub 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
4037pub 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#[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
4096impl<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 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
4111impl<U: DafnyType> Sequence<U> {
4113 pub fn coerce<V: DafnyType>(f: Rc<impl Fn(U) -> V>) -> Rc<impl Fn(Sequence<U>) -> Sequence<V>> {
4114 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
4126impl<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 Rc::new(move |x: Multiset<U>| {
4133 let f2 = f.clone();
4134 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
4144impl<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 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}