1use crate::ast::enumerated::EnumeratedType;
2
3use super::categories::{Category, CategoryOf};
4use super::name::Name;
5use super::serde::{DefaultWithId, HasId, IdPtr, ObjId, PtrAsInner};
6use super::{
7 DecisionVariable, DomainPtr, Expression, GroundDomain, HasDomain, Moo, Reference, ReturnType,
8 Typeable,
9};
10use crate::representation::{ReprRule, ReprStore};
11use parking_lot::{
12 MappedRwLockReadGuard, MappedRwLockWriteGuard, RwLock, RwLockReadGuard, RwLockWriteGuard,
13};
14use serde::{Deserialize, Serialize};
15use serde_with::serde_as;
16use std::any::TypeId;
17use std::collections::BTreeSet;
18use std::collections::VecDeque;
19use std::fmt::{Debug, Display};
20use std::hash::{DefaultHasher, Hash, Hasher};
21use std::mem;
22use std::ops::{Deref, DerefMut};
23use std::sync::Arc;
24use std::sync::atomic::{AtomicU32, AtomicU64, Ordering};
25use uniplate::{Biplate, Tree, Uniplate};
26
27static DECLARATION_PTR_ID_COUNTER: AtomicU32 = const { AtomicU32::new(0) };
32
33static DECLARATION_CONTENT_GENERATION: AtomicU64 = const { AtomicU64::new(1) };
39
40pub(crate) fn declaration_content_generation() -> u64 {
42 DECLARATION_CONTENT_GENERATION.load(Ordering::Acquire)
43}
44
45fn mark_declaration_content_changed() {
47 DECLARATION_CONTENT_GENERATION.fetch_add(1, Ordering::AcqRel);
48}
49
50pub struct DeclarationMutGuard<'a, T: ?Sized> {
52 inner: Option<MappedRwLockWriteGuard<'a, T>>,
53}
54
55impl<'a, T: ?Sized> DeclarationMutGuard<'a, T> {
56 fn new(inner: MappedRwLockWriteGuard<'a, T>) -> Self {
58 Self { inner: Some(inner) }
59 }
60}
61
62impl<T: ?Sized> Deref for DeclarationMutGuard<'_, T> {
63 type Target = T;
64
65 fn deref(&self) -> &Self::Target {
66 self.inner.as_deref().expect("declaration guard is live")
67 }
68}
69
70impl<T: ?Sized> DerefMut for DeclarationMutGuard<'_, T> {
71 fn deref_mut(&mut self) -> &mut Self::Target {
72 self.inner
73 .as_deref_mut()
74 .expect("declaration guard is live")
75 }
76}
77
78impl<T: ?Sized> Drop for DeclarationMutGuard<'_, T> {
79 fn drop(&mut self) {
80 drop(self.inner.take());
81 mark_declaration_content_changed();
82 }
83}
84
85#[doc(hidden)]
86pub fn reset_declaration_id_unchecked() {
90 let _ = DECLARATION_PTR_ID_COUNTER.swap(0, Ordering::Relaxed);
91}
92
93#[derive(Clone, Debug)]
119pub struct DeclarationPtr
120where
121 Self: Send + Sync,
122{
123 inner: Arc<DeclarationPtrInner>,
125}
126
127#[derive(Debug)]
129struct DeclarationPtrInner {
130 id: ObjId,
137
138 value: RwLock<Declaration>,
140
141 representations: RwLock<ReprStore>,
143
144 source: RwLock<Option<DeclarationPtr>>,
146}
147
148impl DeclarationPtrInner {
149 fn new(value: RwLock<Declaration>) -> Arc<DeclarationPtrInner> {
150 Arc::new(DeclarationPtrInner {
151 id: ObjId {
152 type_name: ustr::ustr(DeclarationPtr::TYPE_NAME),
153 object_id: DECLARATION_PTR_ID_COUNTER.fetch_add(1, Ordering::Relaxed),
154 },
155 value,
156 representations: RwLock::new(ReprStore::new()),
157 source: RwLock::new(None),
158 })
159 }
160
161 fn new_with_id_unchecked(value: RwLock<Declaration>, id: ObjId) -> Arc<DeclarationPtrInner> {
164 Arc::new(DeclarationPtrInner {
165 id,
166 value,
167 representations: RwLock::new(ReprStore::new()),
168 source: RwLock::new(None),
169 })
170 }
171}
172
173#[allow(dead_code)]
174impl DeclarationPtr {
175 fn from_declaration(declaration: Declaration) -> DeclarationPtr {
181 DeclarationPtr {
182 inner: DeclarationPtrInner::new(RwLock::new(declaration)),
183 }
184 }
185
186 pub fn source(&self) -> RwLockReadGuard<'_, Option<DeclarationPtr>> {
188 self.inner.source.read()
189 }
190
191 pub fn source_mut(&mut self) -> RwLockWriteGuard<'_, Option<DeclarationPtr>> {
193 self.inner.source.write()
194 }
195
196 pub fn reprs(&self) -> RwLockReadGuard<'_, ReprStore> {
198 self.inner.representations.read()
199 }
200
201 pub fn reprs_mut(&mut self) -> RwLockWriteGuard<'_, ReprStore> {
203 self.inner.representations.write()
204 }
205
206 pub fn get_repr<T: ReprRule + ?Sized>(
208 &self,
209 ) -> Option<MappedRwLockReadGuard<'_, T::DeclLevel>> {
210 RwLockReadGuard::try_map(self.inner.representations.read(), |reprs| reprs.get::<T>()).ok()
211 }
212
213 pub fn new(name: Name, kind: DeclarationKind) -> DeclarationPtr {
227 DeclarationPtr::from_declaration(Declaration::new(name, kind))
228 }
229
230 pub fn new_find(name: Name, domain: DomainPtr) -> DeclarationPtr {
244 let kind = DeclarationKind::Find(DecisionVariable::new(domain));
245 DeclarationPtr::new(name, kind)
246 }
247
248 pub fn new_find_auxiliary(name: Name, domain: DomainPtr) -> DeclarationPtr {
255 let kind = DeclarationKind::FindAuxiliary(DecisionVariable::new(domain));
256 DeclarationPtr::new(name, kind)
257 }
258
259 pub fn new_given(name: Name, domain: DomainPtr) -> DeclarationPtr {
273 let kind = DeclarationKind::Given(domain);
274 DeclarationPtr::new(name, kind)
275 }
276
277 pub fn new_quantified(name: Name, domain: DomainPtr) -> DeclarationPtr {
281 DeclarationPtr::new(
282 name,
283 DeclarationKind::Quantified(Quantified {
284 domain,
285 generator: None,
286 }),
287 )
288 }
289
290 pub fn new_quantified_from_generator(decl: &DeclarationPtr) -> Option<DeclarationPtr> {
294 let kind = DeclarationKind::Quantified(Quantified {
295 domain: decl.domain()?,
296 generator: Some(decl.clone()),
297 });
298 Some(DeclarationPtr::new(decl.name().clone(), kind))
299 }
300
301 pub fn new_quantified_expr(name: Name, expr: Expression) -> DeclarationPtr {
302 let kind = DeclarationKind::QuantifiedExpr(expr);
303 DeclarationPtr::new(name, kind)
304 }
305
306 pub fn new_value_letting(name: Name, expression: Expression) -> DeclarationPtr {
324 let kind = DeclarationKind::ValueLetting(expression, None);
325 DeclarationPtr::new(name, kind)
326 }
327
328 pub fn new_value_letting_with_domain(
348 name: Name,
349 expression: Expression,
350 domain: DomainPtr,
351 ) -> DeclarationPtr {
352 let kind = DeclarationKind::ValueLetting(expression, Some(domain));
353 DeclarationPtr::new(name, kind)
354 }
355
356 pub fn new_domain_letting(name: Name, domain: DomainPtr) -> DeclarationPtr {
370 let kind = DeclarationKind::DomainLetting(domain);
371 DeclarationPtr::new(name, kind)
372 }
373
374 pub fn new_enumerated(name: Name, ty: Moo<EnumeratedType>) -> DeclarationPtr {
377 let kind = DeclarationKind::EnumeratedType(ty);
378 DeclarationPtr::new(name, kind)
379 }
380
381 pub fn new_unnamed(name: Name, size: u32) -> DeclarationPtr {
384 let kind = DeclarationKind::UnnamedType(size);
385 DeclarationPtr::new(name, kind)
386 }
387
388 pub fn domain(&self) -> Option<DomainPtr> {
406 let declaration = self.read();
407 match &declaration.kind {
412 DeclarationKind::Find(var) | DeclarationKind::FindAuxiliary(var) => {
413 Some(var.domain_of())
414 }
415 DeclarationKind::ValueLetting(e, domain) => {
416 domain.clone().or_else(|| e.domain_of_uncached())
417 }
418 DeclarationKind::TemporaryValueLetting(e) => e.domain_of_uncached(),
419 DeclarationKind::DomainLetting(domain) => Some(domain.clone()),
420 DeclarationKind::Given(domain) => Some(domain.clone()),
421 DeclarationKind::Quantified(inner) => Some(inner.domain.clone()),
422 DeclarationKind::QuantifiedExpr(expr) => expr.domain_of_uncached()?.element_domain(),
423 DeclarationKind::EnumeratedType(et) => Some(et.to_domain()),
424 DeclarationKind::UnnamedType(size) => Some(
425 Moo::new(crate::ast::GroundDomain::UnnamedType(Moo::new(
426 crate::ast::unnamed::UnnamedType {
427 name: declaration.name.clone(),
428 size: *size,
429 },
430 )))
431 .into(),
432 ),
433 }
434 }
435
436 pub fn is_find_auxiliary(&self) -> bool {
441 matches!(
442 &self.kind() as &DeclarationKind,
443 DeclarationKind::FindAuxiliary(_)
444 )
445 }
446
447 pub fn resolved_domain(&self) -> Option<Moo<GroundDomain>> {
449 self.domain()?.resolve().ok()
450 }
451
452 pub fn kind(&self) -> MappedRwLockReadGuard<'_, DeclarationKind> {
464 self.map(|x| &x.kind)
465 }
466
467 pub fn name(&self) -> MappedRwLockReadGuard<'_, Name> {
480 self.map(|x| &x.name)
481 }
482
483 pub fn as_find(&self) -> Option<MappedRwLockReadGuard<'_, DecisionVariable>> {
488 RwLockReadGuard::try_map(self.read(), |x| match &x.kind {
489 DeclarationKind::Find(var) | DeclarationKind::FindAuxiliary(var) => Some(var),
490 _ => None,
491 })
492 .ok()
493 }
494
495 pub fn as_find_mut(&mut self) -> Option<DeclarationMutGuard<'_, DecisionVariable>> {
500 RwLockWriteGuard::try_map(self.write(), |x| match &mut x.kind {
501 DeclarationKind::Find(var) | DeclarationKind::FindAuxiliary(var) => Some(var),
502 _ => None,
503 })
504 .ok()
505 .map(DeclarationMutGuard::new)
506 }
507
508 pub fn as_domain_letting(&self) -> Option<MappedRwLockReadGuard<'_, DomainPtr>> {
510 RwLockReadGuard::try_map(self.read(), |x| {
511 if let DeclarationKind::DomainLetting(domain) = &x.kind {
512 Some(domain)
513 } else {
514 None
515 }
516 })
517 .ok()
518 }
519
520 pub fn as_domain_letting_mut(&mut self) -> Option<DeclarationMutGuard<'_, DomainPtr>> {
522 RwLockWriteGuard::try_map(self.write(), |x| {
523 if let DeclarationKind::DomainLetting(domain) = &mut x.kind {
524 Some(domain)
525 } else {
526 None
527 }
528 })
529 .ok()
530 .map(DeclarationMutGuard::new)
531 }
532
533 pub fn as_value_letting(&self) -> Option<MappedRwLockReadGuard<'_, Expression>> {
535 RwLockReadGuard::try_map(self.read(), |x| {
536 if let DeclarationKind::ValueLetting(expression, _)
537 | DeclarationKind::TemporaryValueLetting(expression) = &x.kind
538 {
539 Some(expression)
540 } else {
541 None
542 }
543 })
544 .ok()
545 }
546
547 pub fn as_value_letting_mut(&mut self) -> Option<DeclarationMutGuard<'_, Expression>> {
549 RwLockWriteGuard::try_map(self.write(), |x| {
550 if let DeclarationKind::ValueLetting(expression, _)
551 | DeclarationKind::TemporaryValueLetting(expression) = &mut x.kind
552 {
553 Some(expression)
554 } else {
555 None
556 }
557 })
558 .ok()
559 .map(DeclarationMutGuard::new)
560 }
561
562 pub fn as_given(&self) -> Option<MappedRwLockReadGuard<'_, DomainPtr>> {
564 RwLockReadGuard::try_map(self.read(), |x| {
565 if let DeclarationKind::Given(domain) = &x.kind {
566 Some(domain)
567 } else {
568 None
569 }
570 })
571 .ok()
572 }
573
574 pub fn as_given_mut(&mut self) -> Option<DeclarationMutGuard<'_, DomainPtr>> {
576 RwLockWriteGuard::try_map(self.write(), |x| {
577 if let DeclarationKind::Given(domain) = &mut x.kind {
578 Some(domain)
579 } else {
580 None
581 }
582 })
583 .ok()
584 .map(DeclarationMutGuard::new)
585 }
586
587 pub fn as_quantified_expr(&self) -> Option<MappedRwLockReadGuard<'_, Expression>> {
589 RwLockReadGuard::try_map(self.read(), |x| {
590 if let DeclarationKind::QuantifiedExpr(expr) = &x.kind {
591 Some(expr)
592 } else {
593 None
594 }
595 })
596 .ok()
597 }
598
599 pub fn as_quantified_expr_mut(&mut self) -> Option<DeclarationMutGuard<'_, Expression>> {
601 RwLockWriteGuard::try_map(self.write(), |x| {
602 if let DeclarationKind::QuantifiedExpr(expr) = &mut x.kind {
603 Some(expr)
604 } else {
605 None
606 }
607 })
608 .ok()
609 .map(DeclarationMutGuard::new)
610 }
611
612 pub fn as_enumerated_type(&self) -> Option<MappedRwLockReadGuard<'_, Moo<EnumeratedType>>> {
614 RwLockReadGuard::try_map(self.read(), |x| {
615 if let DeclarationKind::EnumeratedType(e) = &x.kind {
616 Some(e)
617 } else {
618 None
619 }
620 })
621 .ok()
622 }
623
624 pub fn as_enumerated_type_mut(
626 &mut self,
627 ) -> Option<DeclarationMutGuard<'_, Moo<EnumeratedType>>> {
628 RwLockWriteGuard::try_map(self.write(), |x| {
629 if let DeclarationKind::EnumeratedType(e) = &mut x.kind {
630 Some(e)
631 } else {
632 None
633 }
634 })
635 .ok()
636 .map(DeclarationMutGuard::new)
637 }
638
639 pub fn as_unnamed_type(&self) -> Option<MappedRwLockReadGuard<'_, u32>> {
641 RwLockReadGuard::try_map(self.read(), |x| {
642 if let DeclarationKind::UnnamedType(e) = &x.kind {
643 Some(e)
644 } else {
645 None
646 }
647 })
648 .ok()
649 }
650
651 pub fn as_unnamed_type_mut(&mut self) -> Option<DeclarationMutGuard<'_, u32>> {
653 RwLockWriteGuard::try_map(self.write(), |x| {
654 if let DeclarationKind::UnnamedType(e) = &mut x.kind {
655 Some(e)
656 } else {
657 None
658 }
659 })
660 .ok()
661 .map(DeclarationMutGuard::new)
662 }
663
664 pub fn replace_name(&mut self, name: Name) -> Name {
679 let mut current_name = self.map_mut(|decl| &mut decl.name);
680 std::mem::replace(&mut *current_name, name)
681 }
682
683 pub fn replace_kind(&mut self, kind: DeclarationKind) -> DeclarationKind {
686 let mut current_kind = self.map_mut(|decl| &mut decl.kind);
687 std::mem::replace(&mut *current_kind, kind)
688 }
689
690 fn read(&self) -> RwLockReadGuard<'_, Declaration> {
704 self.inner.value.read()
705 }
706
707 fn write(&mut self) -> RwLockWriteGuard<'_, Declaration> {
712 self.inner.value.write()
713 }
714
715 pub fn detach(self) -> DeclarationPtr {
745 let value = self.inner.value.read().clone();
748 let representations = self.inner.representations.read().clone();
749 let source = self.inner.source.read().clone();
750 let detached = DeclarationPtr {
751 inner: DeclarationPtrInner::new(RwLock::new(value)),
752 };
753 *detached.inner.representations.write() = representations;
754 *detached.inner.source.write() = source;
755 detached
756 }
757
758 fn map<U>(&self, f: impl FnOnce(&Declaration) -> &U) -> MappedRwLockReadGuard<'_, U> {
760 RwLockReadGuard::map(self.read(), f)
761 }
762
763 fn map_mut<U>(
765 &mut self,
766 f: impl FnOnce(&mut Declaration) -> &mut U,
767 ) -> DeclarationMutGuard<'_, U> {
768 DeclarationMutGuard::new(RwLockWriteGuard::map(self.write(), f))
769 }
770
771 pub fn replace(&mut self, declaration: Declaration) -> Declaration {
774 let mut guard = self.write();
775 let ans = mem::replace(&mut *guard, declaration);
776 drop(guard);
777 mark_declaration_content_changed();
778 ans
779 }
780
781 pub(crate) fn content_hash(&self) -> u64 {
787 let mut hasher = DefaultHasher::new();
788 let mut seen = BTreeSet::new();
789 self.hash_content(&mut hasher, &mut seen);
790 hasher.finish()
791 }
792
793 pub(crate) fn content_eq(&self, other: &Self) -> bool {
795 if self.id() == other.id() {
796 return true;
797 }
798 let this = self.read().clone();
799 let other = other.read().clone();
800 this == other
801 }
802
803 fn hash_content<H: Hasher>(&self, state: &mut H, seen: &mut BTreeSet<ObjId>) {
805 let id = self.id();
806 if !seen.insert(id.clone()) {
807 "recursive-declaration".hash(state);
808 return;
809 }
810
811 let declaration = self.read();
812 declaration.name.hash(state);
813 declaration.kind.hash_content(state, seen);
814 seen.remove(&id);
815 }
816}
817
818impl CategoryOf for DeclarationPtr {
819 fn category_of(&self) -> Category {
820 match &self.kind() as &DeclarationKind {
821 DeclarationKind::Find(decision_variable)
822 | DeclarationKind::FindAuxiliary(decision_variable) => decision_variable.category_of(),
823 DeclarationKind::ValueLetting(expression, _)
824 | DeclarationKind::TemporaryValueLetting(expression) => expression.category_of(),
825 DeclarationKind::DomainLetting(_) => Category::Constant,
826 DeclarationKind::Given(_) => Category::Parameter,
827 DeclarationKind::Quantified(..) => Category::Quantified,
828 DeclarationKind::QuantifiedExpr(..) => Category::Quantified,
829 DeclarationKind::EnumeratedType(_) | DeclarationKind::UnnamedType(_) => {
830 Category::Constant
831 }
832 }
833 }
834}
835impl HasId for DeclarationPtr {
836 const TYPE_NAME: &'static str = "DeclarationPtrInner";
837 fn id(&self) -> ObjId {
838 self.inner.id.clone()
839 }
840}
841
842impl DefaultWithId for DeclarationPtr {
843 fn default_with_id(id: ObjId) -> Self {
844 DeclarationPtr {
845 inner: DeclarationPtrInner::new_with_id_unchecked(
846 RwLock::new(Declaration {
847 name: Name::User("_UNKNOWN".into()),
848 kind: DeclarationKind::ValueLetting(false.into(), None),
849 }),
850 id,
851 ),
852 }
853 }
854}
855
856impl Typeable for DeclarationPtr {
857 fn return_type(&self) -> ReturnType {
858 let declaration = self.read();
859 match &declaration.kind {
860 DeclarationKind::Find(var) | DeclarationKind::FindAuxiliary(var) => var.return_type(),
861 DeclarationKind::ValueLetting(expression, _)
862 | DeclarationKind::TemporaryValueLetting(expression) => expression.return_type(),
863 DeclarationKind::DomainLetting(domain) => domain.return_type(),
864 DeclarationKind::Given(domain) => domain.return_type(),
865 DeclarationKind::Quantified(inner) => inner.domain.return_type(),
866 DeclarationKind::QuantifiedExpr(expr) => expr.return_type(),
867 DeclarationKind::EnumeratedType(ty) => ReturnType::EnumeratedType(ty.clone()),
868 DeclarationKind::UnnamedType(size) => {
869 ReturnType::UnnamedType(Moo::new(crate::ast::unnamed::UnnamedType {
870 name: declaration.name.clone(),
871 size: *size,
872 }))
873 }
874 }
875 }
876}
877
878impl Uniplate for DeclarationPtr {
879 fn uniplate(&self) -> (Tree<Self>, Box<dyn Fn(Tree<Self>) -> Self>) {
880 let decl = self.read();
881 let (tree, recons) = Biplate::<DeclarationPtr>::biplate(&decl as &Declaration);
882
883 let self2 = self.clone();
884 (
885 tree,
886 Box::new(move |x| {
887 let mut self3 = self2.clone();
888 let inner = recons(x);
889 let _ = self3.replace(inner);
890 self3
891 }),
892 )
893 }
894}
895
896impl<To> Biplate<To> for DeclarationPtr
897where
898 Declaration: Biplate<To>,
899 To: Uniplate,
900{
901 fn biplate(&self) -> (Tree<To>, Box<dyn Fn(Tree<To>) -> Self>) {
902 if TypeId::of::<To>() == TypeId::of::<Self>() {
903 unsafe {
904 let self_as_to = std::mem::transmute::<&Self, &To>(self).clone();
905 (
906 Tree::One(self_as_to),
907 Box::new(move |x| {
908 let Tree::One(x) = x else { panic!() };
909
910 let x_as_self = std::mem::transmute::<&To, &Self>(&x);
911 x_as_self.clone()
912 }),
913 )
914 }
915 } else {
916 let decl = self.read();
918 let (tree, recons) = Biplate::<To>::biplate(&decl as &Declaration);
919
920 let self2 = self.clone();
921 (
922 tree,
923 Box::new(move |x| {
924 let mut self3 = self2.clone();
925 let inner = recons(x);
926 let _ = self3.replace(inner);
927 self3
928 }),
929 )
930 }
931 }
932}
933
934type ReferenceTree = Tree<Reference>;
935type ReferenceReconstructor<T> = Box<dyn Fn(ReferenceTree) -> T>;
936
937impl Biplate<Reference> for DeclarationPtr {
938 fn biplate(&self) -> (ReferenceTree, ReferenceReconstructor<Self>) {
939 let (tree, recons_kind) = biplate_declaration_kind_references(self.kind().clone());
940
941 let self2 = self.clone();
942 (
943 tree,
944 Box::new(move |x| {
945 let mut self3 = self2.clone();
946 let _ = self3.replace_kind(recons_kind(x));
947 self3
948 }),
949 )
950 }
951}
952
953fn biplate_domain_ptr_references(
954 domain: DomainPtr,
955) -> (ReferenceTree, ReferenceReconstructor<DomainPtr>) {
956 let domain_inner = domain.as_ref().clone();
957 let (tree, recons_domain) = Biplate::<Reference>::biplate(&domain_inner);
958 (tree, Box::new(move |x| Moo::new(recons_domain(x))))
959}
960
961fn biplate_declaration_kind_references(
962 kind: DeclarationKind,
963) -> (ReferenceTree, ReferenceReconstructor<DeclarationKind>) {
964 match kind {
965 DeclarationKind::Find(var) => {
966 let (tree, recons_domain) = biplate_domain_ptr_references(var.domain.clone());
967 (
968 tree,
969 Box::new(move |x| {
970 let mut var2 = var.clone();
971 var2.domain = recons_domain(x);
972 DeclarationKind::Find(var2)
973 }),
974 )
975 }
976 DeclarationKind::FindAuxiliary(var) => {
977 let (tree, recons_domain) = biplate_domain_ptr_references(var.domain.clone());
978 (
979 tree,
980 Box::new(move |x| {
981 let mut var2 = var.clone();
982 var2.domain = recons_domain(x);
983 DeclarationKind::FindAuxiliary(var2)
984 }),
985 )
986 }
987 DeclarationKind::Given(domain) => {
988 let (tree, recons_domain) = biplate_domain_ptr_references(domain);
989 (
990 tree,
991 Box::new(move |x| DeclarationKind::Given(recons_domain(x))),
992 )
993 }
994 DeclarationKind::DomainLetting(domain) => {
995 let (tree, recons_domain) = biplate_domain_ptr_references(domain);
996 (
997 tree,
998 Box::new(move |x| DeclarationKind::DomainLetting(recons_domain(x))),
999 )
1000 }
1001 DeclarationKind::ValueLetting(expression, domain) => {
1002 let (tree, recons_expr) = Biplate::<Reference>::biplate(&expression);
1003 (
1004 tree,
1005 Box::new(move |x| DeclarationKind::ValueLetting(recons_expr(x), domain.clone())),
1006 )
1007 }
1008 DeclarationKind::TemporaryValueLetting(expression) => {
1009 let (tree, recons_expr) = Biplate::<Reference>::biplate(&expression);
1010 (
1011 tree,
1012 Box::new(move |x| DeclarationKind::TemporaryValueLetting(recons_expr(x))),
1013 )
1014 }
1015 DeclarationKind::Quantified(quantified) => {
1016 let (domain_tree, recons_domain) =
1017 biplate_domain_ptr_references(quantified.domain.clone());
1018
1019 let (generator_tree, recons_generator) = if let Some(generator) = quantified.generator()
1020 {
1021 let generator = generator.clone();
1022 let (tree, recons_declaration) = Biplate::<Reference>::biplate(&generator);
1023 (
1024 tree,
1025 Box::new(move |x| Some(recons_declaration(x)))
1026 as ReferenceReconstructor<Option<DeclarationPtr>>,
1027 )
1028 } else {
1029 (
1030 Tree::Zero,
1031 Box::new(|_| None) as ReferenceReconstructor<Option<DeclarationPtr>>,
1032 )
1033 };
1034
1035 (
1036 Tree::Many(VecDeque::from([domain_tree, generator_tree])),
1037 Box::new(move |x| {
1038 let Tree::Many(mut children) = x else {
1039 panic!("unexpected biplate tree shape for quantified declaration")
1040 };
1041
1042 let domain = children.pop_front().unwrap_or(Tree::Zero);
1043 let generator = children.pop_front().unwrap_or(Tree::Zero);
1044
1045 let mut quantified2 = quantified.clone();
1046 quantified2.domain = recons_domain(domain);
1047 quantified2.generator = recons_generator(generator);
1048 DeclarationKind::Quantified(quantified2)
1049 }),
1050 )
1051 }
1052 DeclarationKind::QuantifiedExpr(expr) => {
1053 let (tree, recons_expr) = Biplate::<Reference>::biplate(&expr);
1054 (
1055 tree,
1056 Box::new(move |x| DeclarationKind::QuantifiedExpr(recons_expr(x))),
1057 )
1058 }
1059 kind @ (DeclarationKind::EnumeratedType(_) | DeclarationKind::UnnamedType(_)) => {
1060 (Tree::Zero, Box::new(move |_| kind.clone()))
1061 }
1062 }
1063}
1064
1065impl IdPtr for DeclarationPtr {
1066 type Data = Declaration;
1067
1068 fn get_data(&self) -> Self::Data {
1069 self.read().clone()
1070 }
1071
1072 fn with_id_and_data(id: ObjId, data: Self::Data) -> Self {
1073 Self {
1074 inner: DeclarationPtrInner::new_with_id_unchecked(RwLock::new(data), id),
1075 }
1076 }
1077}
1078
1079impl Ord for DeclarationPtr {
1080 fn cmp(&self, other: &Self) -> std::cmp::Ordering {
1081 self.inner.id.cmp(&other.inner.id)
1082 }
1083}
1084
1085impl PartialOrd for DeclarationPtr {
1086 fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
1087 Some(self.cmp(other))
1088 }
1089}
1090
1091impl PartialEq for DeclarationPtr {
1092 fn eq(&self, other: &Self) -> bool {
1093 self.inner.id == other.inner.id
1094 }
1095}
1096
1097impl Eq for DeclarationPtr {}
1098
1099impl std::hash::Hash for DeclarationPtr {
1100 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
1101 self.inner.id.hash(state);
1103 }
1104}
1105
1106impl Display for DeclarationPtr {
1107 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1108 let value: &Declaration = &self.read();
1109 value.fmt(f)
1110 }
1111}
1112
1113#[derive(Clone, PartialEq, Debug, Serialize, Deserialize, Eq, Uniplate)]
1114#[biplate(to=Expression)]
1115#[biplate(to=DeclarationPtr)]
1116#[biplate(to=Name)]
1117pub struct Declaration {
1119 name: Name,
1121
1122 kind: DeclarationKind,
1124}
1125
1126impl Declaration {
1127 pub fn new(name: Name, kind: DeclarationKind) -> Declaration {
1129 Declaration { name, kind }
1130 }
1131}
1132
1133#[non_exhaustive]
1135#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, Uniplate)]
1136#[biplate(to=Expression)]
1137#[biplate(to=DeclarationPtr)]
1138#[biplate(to=Declaration)]
1139pub enum DeclarationKind {
1140 Find(DecisionVariable),
1141
1142 FindAuxiliary(DecisionVariable),
1147
1148 Given(DomainPtr),
1149 Quantified(Quantified),
1150 QuantifiedExpr(Expression),
1151
1152 ValueLetting(Expression, Option<DomainPtr>),
1154 DomainLetting(DomainPtr),
1155
1156 TemporaryValueLetting(Expression),
1160
1161 EnumeratedType(Moo<EnumeratedType>),
1163 UnnamedType(u32),
1165}
1166
1167impl DeclarationKind {
1168 fn hash_content<H: Hasher>(&self, state: &mut H, seen: &mut BTreeSet<ObjId>) {
1170 mem::discriminant(self).hash(state);
1171 match self {
1172 DeclarationKind::Find(var) | DeclarationKind::FindAuxiliary(var) => {
1173 var.domain.hash(state);
1174 for representation in &var.representations {
1175 for repr in representation {
1176 repr.repr_name().hash(state);
1177 if let Ok(declarations) = repr.declaration_down() {
1178 for declaration in declarations {
1179 declaration.hash_content(state, seen);
1180 }
1181 } else {
1182 "unavailable-representation-declarations".hash(state);
1183 }
1184 }
1185 }
1186 }
1187 DeclarationKind::Given(domain) | DeclarationKind::DomainLetting(domain) => {
1188 domain.hash(state);
1189 }
1190 DeclarationKind::Quantified(quantified) => {
1191 quantified.domain.hash(state);
1192 if let Some(generator) = quantified.generator() {
1193 generator.hash_content(state, seen);
1194 }
1195 }
1196 DeclarationKind::QuantifiedExpr(expr)
1197 | DeclarationKind::TemporaryValueLetting(expr) => {
1198 expr.cached_content_hash().hash(state);
1199 expr.to_string().hash(state);
1200 }
1201 DeclarationKind::EnumeratedType(ty) => ty.hash(state),
1202 DeclarationKind::UnnamedType(size) => size.hash(state),
1203 DeclarationKind::ValueLetting(expr, domain) => {
1204 expr.cached_content_hash().hash(state);
1205 expr.to_string().hash(state);
1206 domain.hash(state);
1207 }
1208 }
1209 }
1210}
1211
1212#[serde_as]
1213#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, Uniplate)]
1214pub struct Quantified {
1215 domain: DomainPtr,
1216
1217 #[serde_as(as = "Option<PtrAsInner>")]
1218 generator: Option<DeclarationPtr>,
1219}
1220
1221impl Quantified {
1222 pub fn domain(&self) -> &DomainPtr {
1223 &self.domain
1224 }
1225
1226 pub fn generator(&self) -> Option<&DeclarationPtr> {
1227 self.generator.as_ref()
1228 }
1229}