1use super::categories::{Category, CategoryOf};
2use super::name::Name;
3use super::serde::{DefaultWithId, HasId, IdPtr, ObjId, PtrAsInner};
4use super::{
5 DecisionVariable, DomainPtr, Expression, GroundDomain, HasDomain, Moo, Reference, ReturnType,
6 Typeable,
7};
8use crate::representation::{ReprRule, ReprStore};
9use parking_lot::{
10 MappedRwLockReadGuard, MappedRwLockWriteGuard, RwLock, RwLockReadGuard, RwLockWriteGuard,
11};
12use serde::{Deserialize, Serialize};
13use serde_with::serde_as;
14use std::any::TypeId;
15use std::collections::BTreeSet;
16use std::collections::VecDeque;
17use std::fmt::{Debug, Display};
18use std::hash::{DefaultHasher, Hash, Hasher};
19use std::mem;
20use std::ops::{Deref, DerefMut};
21use std::sync::Arc;
22use std::sync::atomic::{AtomicU32, AtomicU64, Ordering};
23use uniplate::{Biplate, Tree, Uniplate};
24
25static DECLARATION_PTR_ID_COUNTER: AtomicU32 = const { AtomicU32::new(0) };
30
31static DECLARATION_CONTENT_GENERATION: AtomicU64 = const { AtomicU64::new(1) };
37
38pub(crate) fn declaration_content_generation() -> u64 {
40 DECLARATION_CONTENT_GENERATION.load(Ordering::Acquire)
41}
42
43fn mark_declaration_content_changed() {
45 DECLARATION_CONTENT_GENERATION.fetch_add(1, Ordering::AcqRel);
46}
47
48pub struct DeclarationMutGuard<'a, T: ?Sized> {
50 inner: Option<MappedRwLockWriteGuard<'a, T>>,
51}
52
53impl<'a, T: ?Sized> DeclarationMutGuard<'a, T> {
54 fn new(inner: MappedRwLockWriteGuard<'a, T>) -> Self {
56 Self { inner: Some(inner) }
57 }
58}
59
60impl<T: ?Sized> Deref for DeclarationMutGuard<'_, T> {
61 type Target = T;
62
63 fn deref(&self) -> &Self::Target {
64 self.inner.as_deref().expect("declaration guard is live")
65 }
66}
67
68impl<T: ?Sized> DerefMut for DeclarationMutGuard<'_, T> {
69 fn deref_mut(&mut self) -> &mut Self::Target {
70 self.inner
71 .as_deref_mut()
72 .expect("declaration guard is live")
73 }
74}
75
76impl<T: ?Sized> Drop for DeclarationMutGuard<'_, T> {
77 fn drop(&mut self) {
78 drop(self.inner.take());
79 mark_declaration_content_changed();
80 }
81}
82
83#[doc(hidden)]
84pub fn reset_declaration_id_unchecked() {
88 let _ = DECLARATION_PTR_ID_COUNTER.swap(0, Ordering::Relaxed);
89}
90
91#[derive(Clone, Debug)]
117pub struct DeclarationPtr
118where
119 Self: Send + Sync,
120{
121 inner: Arc<DeclarationPtrInner>,
123}
124
125#[derive(Debug)]
127struct DeclarationPtrInner {
128 id: ObjId,
135
136 value: RwLock<Declaration>,
138
139 representations: RwLock<ReprStore>,
141
142 source: RwLock<Option<DeclarationPtr>>,
144}
145
146impl DeclarationPtrInner {
147 fn new(value: RwLock<Declaration>) -> Arc<DeclarationPtrInner> {
148 Arc::new(DeclarationPtrInner {
149 id: ObjId {
150 type_name: ustr::ustr(DeclarationPtr::TYPE_NAME),
151 object_id: DECLARATION_PTR_ID_COUNTER.fetch_add(1, Ordering::Relaxed),
152 },
153 value,
154 representations: RwLock::new(ReprStore::new()),
155 source: RwLock::new(None),
156 })
157 }
158
159 fn new_with_id_unchecked(value: RwLock<Declaration>, id: ObjId) -> Arc<DeclarationPtrInner> {
162 Arc::new(DeclarationPtrInner {
163 id,
164 value,
165 representations: RwLock::new(ReprStore::new()),
166 source: RwLock::new(None),
167 })
168 }
169}
170
171#[allow(dead_code)]
172impl DeclarationPtr {
173 fn from_declaration(declaration: Declaration) -> DeclarationPtr {
179 DeclarationPtr {
180 inner: DeclarationPtrInner::new(RwLock::new(declaration)),
181 }
182 }
183
184 pub fn source(&self) -> RwLockReadGuard<'_, Option<DeclarationPtr>> {
186 self.inner.source.read()
187 }
188
189 pub fn source_mut(&mut self) -> RwLockWriteGuard<'_, Option<DeclarationPtr>> {
191 self.inner.source.write()
192 }
193
194 pub fn reprs(&self) -> RwLockReadGuard<'_, ReprStore> {
196 self.inner.representations.read()
197 }
198
199 pub fn reprs_mut(&mut self) -> RwLockWriteGuard<'_, ReprStore> {
201 self.inner.representations.write()
202 }
203
204 pub fn get_repr<T: ReprRule + ?Sized>(
206 &self,
207 ) -> Option<MappedRwLockReadGuard<'_, T::DeclLevel>> {
208 RwLockReadGuard::try_map(self.inner.representations.read(), |reprs| reprs.get::<T>()).ok()
209 }
210
211 pub fn new(name: Name, kind: DeclarationKind) -> DeclarationPtr {
225 DeclarationPtr::from_declaration(Declaration::new(name, kind))
226 }
227
228 pub fn new_find(name: Name, domain: DomainPtr) -> DeclarationPtr {
242 let kind = DeclarationKind::Find(DecisionVariable::new(domain));
243 DeclarationPtr::new(name, kind)
244 }
245
246 pub fn new_find_auxiliary(name: Name, domain: DomainPtr) -> DeclarationPtr {
253 let kind = DeclarationKind::FindAuxiliary(DecisionVariable::new(domain));
254 DeclarationPtr::new(name, kind)
255 }
256
257 pub fn new_given(name: Name, domain: DomainPtr) -> DeclarationPtr {
271 let kind = DeclarationKind::Given(domain);
272 DeclarationPtr::new(name, kind)
273 }
274
275 pub fn new_quantified(name: Name, domain: DomainPtr) -> DeclarationPtr {
279 DeclarationPtr::new(
280 name,
281 DeclarationKind::Quantified(Quantified {
282 domain,
283 generator: None,
284 }),
285 )
286 }
287
288 pub fn new_quantified_from_generator(decl: &DeclarationPtr) -> Option<DeclarationPtr> {
292 let kind = DeclarationKind::Quantified(Quantified {
293 domain: decl.domain()?,
294 generator: Some(decl.clone()),
295 });
296 Some(DeclarationPtr::new(decl.name().clone(), kind))
297 }
298
299 pub fn new_quantified_expr(name: Name, expr: Expression) -> DeclarationPtr {
300 let kind = DeclarationKind::QuantifiedExpr(expr);
301 DeclarationPtr::new(name, kind)
302 }
303
304 pub fn new_value_letting(name: Name, expression: Expression) -> DeclarationPtr {
322 let kind = DeclarationKind::ValueLetting(expression, None);
323 DeclarationPtr::new(name, kind)
324 }
325
326 pub fn new_value_letting_with_domain(
346 name: Name,
347 expression: Expression,
348 domain: DomainPtr,
349 ) -> DeclarationPtr {
350 let kind = DeclarationKind::ValueLetting(expression, Some(domain));
351 DeclarationPtr::new(name, kind)
352 }
353
354 pub fn new_domain_letting(name: Name, domain: DomainPtr) -> DeclarationPtr {
368 let kind = DeclarationKind::DomainLetting(domain);
369 DeclarationPtr::new(name, kind)
370 }
371
372 pub fn domain(&self) -> Option<DomainPtr> {
390 match &self.kind() as &DeclarationKind {
395 DeclarationKind::Find(var) | DeclarationKind::FindAuxiliary(var) => {
396 Some(var.domain_of())
397 }
398 DeclarationKind::ValueLetting(e, domain) => {
399 domain.clone().or_else(|| e.domain_of_uncached())
400 }
401 DeclarationKind::TemporaryValueLetting(e) => e.domain_of_uncached(),
402 DeclarationKind::DomainLetting(domain) => Some(domain.clone()),
403 DeclarationKind::Given(domain) => Some(domain.clone()),
404 DeclarationKind::Quantified(inner) => Some(inner.domain.clone()),
405 DeclarationKind::QuantifiedExpr(expr) => expr.domain_of_uncached()?.element_domain(),
406 }
407 }
408
409 pub fn is_find_auxiliary(&self) -> bool {
414 matches!(
415 &self.kind() as &DeclarationKind,
416 DeclarationKind::FindAuxiliary(_)
417 )
418 }
419
420 pub fn resolved_domain(&self) -> Option<Moo<GroundDomain>> {
422 self.domain()?.resolve().ok()
423 }
424
425 pub fn kind(&self) -> MappedRwLockReadGuard<'_, DeclarationKind> {
437 self.map(|x| &x.kind)
438 }
439
440 pub fn name(&self) -> MappedRwLockReadGuard<'_, Name> {
453 self.map(|x| &x.name)
454 }
455
456 pub fn as_find(&self) -> Option<MappedRwLockReadGuard<'_, DecisionVariable>> {
461 RwLockReadGuard::try_map(self.read(), |x| match &x.kind {
462 DeclarationKind::Find(var) | DeclarationKind::FindAuxiliary(var) => Some(var),
463 _ => None,
464 })
465 .ok()
466 }
467
468 pub fn as_find_mut(&mut self) -> Option<DeclarationMutGuard<'_, DecisionVariable>> {
473 RwLockWriteGuard::try_map(self.write(), |x| match &mut x.kind {
474 DeclarationKind::Find(var) | DeclarationKind::FindAuxiliary(var) => Some(var),
475 _ => None,
476 })
477 .ok()
478 .map(DeclarationMutGuard::new)
479 }
480
481 pub fn as_domain_letting(&self) -> Option<MappedRwLockReadGuard<'_, DomainPtr>> {
483 RwLockReadGuard::try_map(self.read(), |x| {
484 if let DeclarationKind::DomainLetting(domain) = &x.kind {
485 Some(domain)
486 } else {
487 None
488 }
489 })
490 .ok()
491 }
492
493 pub fn as_domain_letting_mut(&mut self) -> Option<DeclarationMutGuard<'_, DomainPtr>> {
495 RwLockWriteGuard::try_map(self.write(), |x| {
496 if let DeclarationKind::DomainLetting(domain) = &mut x.kind {
497 Some(domain)
498 } else {
499 None
500 }
501 })
502 .ok()
503 .map(DeclarationMutGuard::new)
504 }
505
506 pub fn as_value_letting(&self) -> Option<MappedRwLockReadGuard<'_, Expression>> {
508 RwLockReadGuard::try_map(self.read(), |x| {
509 if let DeclarationKind::ValueLetting(expression, _)
510 | DeclarationKind::TemporaryValueLetting(expression) = &x.kind
511 {
512 Some(expression)
513 } else {
514 None
515 }
516 })
517 .ok()
518 }
519
520 pub fn as_value_letting_mut(&mut self) -> Option<DeclarationMutGuard<'_, Expression>> {
522 RwLockWriteGuard::try_map(self.write(), |x| {
523 if let DeclarationKind::ValueLetting(expression, _)
524 | DeclarationKind::TemporaryValueLetting(expression) = &mut x.kind
525 {
526 Some(expression)
527 } else {
528 None
529 }
530 })
531 .ok()
532 .map(DeclarationMutGuard::new)
533 }
534
535 pub fn as_given(&self) -> Option<MappedRwLockReadGuard<'_, DomainPtr>> {
537 RwLockReadGuard::try_map(self.read(), |x| {
538 if let DeclarationKind::Given(domain) = &x.kind {
539 Some(domain)
540 } else {
541 None
542 }
543 })
544 .ok()
545 }
546
547 pub fn as_given_mut(&mut self) -> Option<DeclarationMutGuard<'_, DomainPtr>> {
549 RwLockWriteGuard::try_map(self.write(), |x| {
550 if let DeclarationKind::Given(domain) = &mut x.kind {
551 Some(domain)
552 } else {
553 None
554 }
555 })
556 .ok()
557 .map(DeclarationMutGuard::new)
558 }
559
560 pub fn as_quantified_expr(&self) -> Option<MappedRwLockReadGuard<'_, Expression>> {
562 RwLockReadGuard::try_map(self.read(), |x| {
563 if let DeclarationKind::QuantifiedExpr(expr) = &x.kind {
564 Some(expr)
565 } else {
566 None
567 }
568 })
569 .ok()
570 }
571
572 pub fn as_quantified_expr_mut(&mut self) -> Option<DeclarationMutGuard<'_, Expression>> {
574 RwLockWriteGuard::try_map(self.write(), |x| {
575 if let DeclarationKind::QuantifiedExpr(expr) = &mut x.kind {
576 Some(expr)
577 } else {
578 None
579 }
580 })
581 .ok()
582 .map(DeclarationMutGuard::new)
583 }
584
585 pub fn replace_name(&mut self, name: Name) -> Name {
600 let mut current_name = self.map_mut(|decl| &mut decl.name);
601 std::mem::replace(&mut *current_name, name)
602 }
603
604 pub fn replace_kind(&mut self, kind: DeclarationKind) -> DeclarationKind {
607 let mut current_kind = self.map_mut(|decl| &mut decl.kind);
608 std::mem::replace(&mut *current_kind, kind)
609 }
610
611 fn read(&self) -> RwLockReadGuard<'_, Declaration> {
625 self.inner.value.read()
626 }
627
628 fn write(&mut self) -> RwLockWriteGuard<'_, Declaration> {
633 self.inner.value.write()
634 }
635
636 pub fn detach(self) -> DeclarationPtr {
666 let value = self.inner.value.read().clone();
669 let representations = self.inner.representations.read().clone();
670 let source = self.inner.source.read().clone();
671 let detached = DeclarationPtr {
672 inner: DeclarationPtrInner::new(RwLock::new(value)),
673 };
674 *detached.inner.representations.write() = representations;
675 *detached.inner.source.write() = source;
676 detached
677 }
678
679 fn map<U>(&self, f: impl FnOnce(&Declaration) -> &U) -> MappedRwLockReadGuard<'_, U> {
681 RwLockReadGuard::map(self.read(), f)
682 }
683
684 fn map_mut<U>(
686 &mut self,
687 f: impl FnOnce(&mut Declaration) -> &mut U,
688 ) -> DeclarationMutGuard<'_, U> {
689 DeclarationMutGuard::new(RwLockWriteGuard::map(self.write(), f))
690 }
691
692 pub fn replace(&mut self, declaration: Declaration) -> Declaration {
695 let mut guard = self.write();
696 let ans = mem::replace(&mut *guard, declaration);
697 drop(guard);
698 mark_declaration_content_changed();
699 ans
700 }
701
702 pub(crate) fn content_hash(&self) -> u64 {
708 let mut hasher = DefaultHasher::new();
709 let mut seen = BTreeSet::new();
710 self.hash_content(&mut hasher, &mut seen);
711 hasher.finish()
712 }
713
714 pub(crate) fn content_eq(&self, other: &Self) -> bool {
716 if self.id() == other.id() {
717 return true;
718 }
719 let this = self.read().clone();
720 let other = other.read().clone();
721 this == other
722 }
723
724 fn hash_content<H: Hasher>(&self, state: &mut H, seen: &mut BTreeSet<ObjId>) {
726 let id = self.id();
727 if !seen.insert(id.clone()) {
728 "recursive-declaration".hash(state);
729 return;
730 }
731
732 let declaration = self.read();
733 declaration.name.hash(state);
734 declaration.kind.hash_content(state, seen);
735 seen.remove(&id);
736 }
737}
738
739impl CategoryOf for DeclarationPtr {
740 fn category_of(&self) -> Category {
741 match &self.kind() as &DeclarationKind {
742 DeclarationKind::Find(decision_variable)
743 | DeclarationKind::FindAuxiliary(decision_variable) => decision_variable.category_of(),
744 DeclarationKind::ValueLetting(expression, _)
745 | DeclarationKind::TemporaryValueLetting(expression) => expression.category_of(),
746 DeclarationKind::DomainLetting(_) => Category::Constant,
747 DeclarationKind::Given(_) => Category::Parameter,
748 DeclarationKind::Quantified(..) => Category::Quantified,
749 DeclarationKind::QuantifiedExpr(..) => Category::Quantified,
750 }
751 }
752}
753impl HasId for DeclarationPtr {
754 const TYPE_NAME: &'static str = "DeclarationPtrInner";
755 fn id(&self) -> ObjId {
756 self.inner.id.clone()
757 }
758}
759
760impl DefaultWithId for DeclarationPtr {
761 fn default_with_id(id: ObjId) -> Self {
762 DeclarationPtr {
763 inner: DeclarationPtrInner::new_with_id_unchecked(
764 RwLock::new(Declaration {
765 name: Name::User("_UNKNOWN".into()),
766 kind: DeclarationKind::ValueLetting(false.into(), None),
767 }),
768 id,
769 ),
770 }
771 }
772}
773
774impl Typeable for DeclarationPtr {
775 fn return_type(&self) -> ReturnType {
776 match &self.kind() as &DeclarationKind {
777 DeclarationKind::Find(var) | DeclarationKind::FindAuxiliary(var) => var.return_type(),
778 DeclarationKind::ValueLetting(expression, _)
779 | DeclarationKind::TemporaryValueLetting(expression) => expression.return_type(),
780 DeclarationKind::DomainLetting(domain) => domain.return_type(),
781 DeclarationKind::Given(domain) => domain.return_type(),
782 DeclarationKind::Quantified(inner) => inner.domain.return_type(),
783 DeclarationKind::QuantifiedExpr(expr) => expr.return_type(),
784 }
785 }
786}
787
788impl Uniplate for DeclarationPtr {
789 fn uniplate(&self) -> (Tree<Self>, Box<dyn Fn(Tree<Self>) -> Self>) {
790 let decl = self.read();
791 let (tree, recons) = Biplate::<DeclarationPtr>::biplate(&decl as &Declaration);
792
793 let self2 = self.clone();
794 (
795 tree,
796 Box::new(move |x| {
797 let mut self3 = self2.clone();
798 let inner = recons(x);
799 let _ = self3.replace(inner);
800 self3
801 }),
802 )
803 }
804}
805
806impl<To> Biplate<To> for DeclarationPtr
807where
808 Declaration: Biplate<To>,
809 To: Uniplate,
810{
811 fn biplate(&self) -> (Tree<To>, Box<dyn Fn(Tree<To>) -> Self>) {
812 if TypeId::of::<To>() == TypeId::of::<Self>() {
813 unsafe {
814 let self_as_to = std::mem::transmute::<&Self, &To>(self).clone();
815 (
816 Tree::One(self_as_to),
817 Box::new(move |x| {
818 let Tree::One(x) = x else { panic!() };
819
820 let x_as_self = std::mem::transmute::<&To, &Self>(&x);
821 x_as_self.clone()
822 }),
823 )
824 }
825 } else {
826 let decl = self.read();
828 let (tree, recons) = Biplate::<To>::biplate(&decl as &Declaration);
829
830 let self2 = self.clone();
831 (
832 tree,
833 Box::new(move |x| {
834 let mut self3 = self2.clone();
835 let inner = recons(x);
836 let _ = self3.replace(inner);
837 self3
838 }),
839 )
840 }
841 }
842}
843
844type ReferenceTree = Tree<Reference>;
845type ReferenceReconstructor<T> = Box<dyn Fn(ReferenceTree) -> T>;
846
847impl Biplate<Reference> for DeclarationPtr {
848 fn biplate(&self) -> (ReferenceTree, ReferenceReconstructor<Self>) {
849 let (tree, recons_kind) = biplate_declaration_kind_references(self.kind().clone());
850
851 let self2 = self.clone();
852 (
853 tree,
854 Box::new(move |x| {
855 let mut self3 = self2.clone();
856 let _ = self3.replace_kind(recons_kind(x));
857 self3
858 }),
859 )
860 }
861}
862
863fn biplate_domain_ptr_references(
864 domain: DomainPtr,
865) -> (ReferenceTree, ReferenceReconstructor<DomainPtr>) {
866 let domain_inner = domain.as_ref().clone();
867 let (tree, recons_domain) = Biplate::<Reference>::biplate(&domain_inner);
868 (tree, Box::new(move |x| Moo::new(recons_domain(x))))
869}
870
871fn biplate_declaration_kind_references(
872 kind: DeclarationKind,
873) -> (ReferenceTree, ReferenceReconstructor<DeclarationKind>) {
874 match kind {
875 DeclarationKind::Find(var) => {
876 let (tree, recons_domain) = biplate_domain_ptr_references(var.domain.clone());
877 (
878 tree,
879 Box::new(move |x| {
880 let mut var2 = var.clone();
881 var2.domain = recons_domain(x);
882 DeclarationKind::Find(var2)
883 }),
884 )
885 }
886 DeclarationKind::FindAuxiliary(var) => {
887 let (tree, recons_domain) = biplate_domain_ptr_references(var.domain.clone());
888 (
889 tree,
890 Box::new(move |x| {
891 let mut var2 = var.clone();
892 var2.domain = recons_domain(x);
893 DeclarationKind::FindAuxiliary(var2)
894 }),
895 )
896 }
897 DeclarationKind::Given(domain) => {
898 let (tree, recons_domain) = biplate_domain_ptr_references(domain);
899 (
900 tree,
901 Box::new(move |x| DeclarationKind::Given(recons_domain(x))),
902 )
903 }
904 DeclarationKind::DomainLetting(domain) => {
905 let (tree, recons_domain) = biplate_domain_ptr_references(domain);
906 (
907 tree,
908 Box::new(move |x| DeclarationKind::DomainLetting(recons_domain(x))),
909 )
910 }
911 DeclarationKind::ValueLetting(expression, domain) => {
912 let (tree, recons_expr) = Biplate::<Reference>::biplate(&expression);
913 (
914 tree,
915 Box::new(move |x| DeclarationKind::ValueLetting(recons_expr(x), domain.clone())),
916 )
917 }
918 DeclarationKind::TemporaryValueLetting(expression) => {
919 let (tree, recons_expr) = Biplate::<Reference>::biplate(&expression);
920 (
921 tree,
922 Box::new(move |x| DeclarationKind::TemporaryValueLetting(recons_expr(x))),
923 )
924 }
925 DeclarationKind::Quantified(quantified) => {
926 let (domain_tree, recons_domain) =
927 biplate_domain_ptr_references(quantified.domain.clone());
928
929 let (generator_tree, recons_generator) = if let Some(generator) = quantified.generator()
930 {
931 let generator = generator.clone();
932 let (tree, recons_declaration) = Biplate::<Reference>::biplate(&generator);
933 (
934 tree,
935 Box::new(move |x| Some(recons_declaration(x)))
936 as ReferenceReconstructor<Option<DeclarationPtr>>,
937 )
938 } else {
939 (
940 Tree::Zero,
941 Box::new(|_| None) as ReferenceReconstructor<Option<DeclarationPtr>>,
942 )
943 };
944
945 (
946 Tree::Many(VecDeque::from([domain_tree, generator_tree])),
947 Box::new(move |x| {
948 let Tree::Many(mut children) = x else {
949 panic!("unexpected biplate tree shape for quantified declaration")
950 };
951
952 let domain = children.pop_front().unwrap_or(Tree::Zero);
953 let generator = children.pop_front().unwrap_or(Tree::Zero);
954
955 let mut quantified2 = quantified.clone();
956 quantified2.domain = recons_domain(domain);
957 quantified2.generator = recons_generator(generator);
958 DeclarationKind::Quantified(quantified2)
959 }),
960 )
961 }
962 DeclarationKind::QuantifiedExpr(expr) => {
963 let (tree, recons_expr) = Biplate::<Reference>::biplate(&expr);
964 (
965 tree,
966 Box::new(move |x| DeclarationKind::QuantifiedExpr(recons_expr(x))),
967 )
968 }
969 }
970}
971
972impl IdPtr for DeclarationPtr {
973 type Data = Declaration;
974
975 fn get_data(&self) -> Self::Data {
976 self.read().clone()
977 }
978
979 fn with_id_and_data(id: ObjId, data: Self::Data) -> Self {
980 Self {
981 inner: DeclarationPtrInner::new_with_id_unchecked(RwLock::new(data), id),
982 }
983 }
984}
985
986impl Ord for DeclarationPtr {
987 fn cmp(&self, other: &Self) -> std::cmp::Ordering {
988 self.inner.id.cmp(&other.inner.id)
989 }
990}
991
992impl PartialOrd for DeclarationPtr {
993 fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
994 Some(self.cmp(other))
995 }
996}
997
998impl PartialEq for DeclarationPtr {
999 fn eq(&self, other: &Self) -> bool {
1000 self.inner.id == other.inner.id
1001 }
1002}
1003
1004impl Eq for DeclarationPtr {}
1005
1006impl std::hash::Hash for DeclarationPtr {
1007 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
1008 self.inner.id.hash(state);
1010 }
1011}
1012
1013impl Display for DeclarationPtr {
1014 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1015 let value: &Declaration = &self.read();
1016 value.fmt(f)
1017 }
1018}
1019
1020#[derive(Clone, PartialEq, Debug, Serialize, Deserialize, Eq, Uniplate)]
1021#[biplate(to=Expression)]
1022#[biplate(to=DeclarationPtr)]
1023#[biplate(to=Name)]
1024pub struct Declaration {
1026 name: Name,
1028
1029 kind: DeclarationKind,
1031}
1032
1033impl Declaration {
1034 pub fn new(name: Name, kind: DeclarationKind) -> Declaration {
1036 Declaration { name, kind }
1037 }
1038}
1039
1040#[non_exhaustive]
1042#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, Uniplate)]
1043#[biplate(to=Expression)]
1044#[biplate(to=DeclarationPtr)]
1045#[biplate(to=Declaration)]
1046pub enum DeclarationKind {
1047 Find(DecisionVariable),
1048
1049 FindAuxiliary(DecisionVariable),
1054
1055 Given(DomainPtr),
1056 Quantified(Quantified),
1057 QuantifiedExpr(Expression),
1058
1059 ValueLetting(Expression, Option<DomainPtr>),
1061 DomainLetting(DomainPtr),
1062
1063 TemporaryValueLetting(Expression),
1067}
1068
1069impl DeclarationKind {
1070 fn hash_content<H: Hasher>(&self, state: &mut H, seen: &mut BTreeSet<ObjId>) {
1072 mem::discriminant(self).hash(state);
1073 match self {
1074 DeclarationKind::Find(var) | DeclarationKind::FindAuxiliary(var) => {
1075 var.domain.hash(state);
1076 for representation in &var.representations {
1077 for repr in representation {
1078 repr.repr_name().hash(state);
1079 if let Ok(declarations) = repr.declaration_down() {
1080 for declaration in declarations {
1081 declaration.hash_content(state, seen);
1082 }
1083 } else {
1084 "unavailable-representation-declarations".hash(state);
1085 }
1086 }
1087 }
1088 }
1089 DeclarationKind::Given(domain) | DeclarationKind::DomainLetting(domain) => {
1090 domain.hash(state);
1091 }
1092 DeclarationKind::Quantified(quantified) => {
1093 quantified.domain.hash(state);
1094 if let Some(generator) = quantified.generator() {
1095 generator.hash_content(state, seen);
1096 }
1097 }
1098 DeclarationKind::QuantifiedExpr(expr)
1099 | DeclarationKind::TemporaryValueLetting(expr) => {
1100 expr.cached_content_hash().hash(state);
1101 expr.to_string().hash(state);
1102 }
1103 DeclarationKind::ValueLetting(expr, domain) => {
1104 expr.cached_content_hash().hash(state);
1105 expr.to_string().hash(state);
1106 domain.hash(state);
1107 }
1108 }
1109 }
1110}
1111
1112#[serde_as]
1113#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, Uniplate)]
1114pub struct Quantified {
1115 domain: DomainPtr,
1116
1117 #[serde_as(as = "Option<PtrAsInner>")]
1118 generator: Option<DeclarationPtr>,
1119}
1120
1121impl Quantified {
1122 pub fn domain(&self) -> &DomainPtr {
1123 &self.domain
1124 }
1125
1126 pub fn generator(&self) -> Option<&DeclarationPtr> {
1127 self.generator.as_ref()
1128 }
1129}