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, RecordEntry, Reference,
6 ReturnType, Typeable,
7};
8use parking_lot::{
9 MappedRwLockReadGuard, MappedRwLockWriteGuard, RwLock, RwLockReadGuard, RwLockWriteGuard,
10};
11use serde::{Deserialize, Serialize};
12use serde_with::serde_as;
13use std::any::TypeId;
14use std::collections::VecDeque;
15use std::fmt::{Debug, Display};
16use std::mem;
17use std::sync::Arc;
18use std::sync::atomic::{AtomicU32, Ordering};
19use uniplate::{Biplate, Tree, Uniplate};
20
21static DECLARATION_PTR_ID_COUNTER: AtomicU32 = const { AtomicU32::new(0) };
26
27#[doc(hidden)]
28pub fn reset_declaration_id_unchecked() {
32 let _ = DECLARATION_PTR_ID_COUNTER.swap(0, Ordering::Relaxed);
33}
34
35#[derive(Clone, Debug)]
61pub struct DeclarationPtr
62where
63 Self: Send + Sync,
64{
65 inner: Arc<DeclarationPtrInner>,
67}
68
69#[derive(Debug)]
71struct DeclarationPtrInner {
72 id: ObjId,
77
78 value: RwLock<Declaration>,
80}
81
82impl DeclarationPtrInner {
83 fn new(value: RwLock<Declaration>) -> Arc<DeclarationPtrInner> {
84 Arc::new(DeclarationPtrInner {
85 id: ObjId {
86 type_name: ustr::ustr(DeclarationPtr::TYPE_NAME),
87 object_id: DECLARATION_PTR_ID_COUNTER.fetch_add(1, Ordering::Relaxed),
88 },
89 value,
90 })
91 }
92
93 fn new_with_id_unchecked(value: RwLock<Declaration>, id: ObjId) -> Arc<DeclarationPtrInner> {
96 Arc::new(DeclarationPtrInner { id, value })
97 }
98}
99
100#[allow(dead_code)]
101impl DeclarationPtr {
102 fn from_declaration(declaration: Declaration) -> DeclarationPtr {
108 DeclarationPtr {
109 inner: DeclarationPtrInner::new(RwLock::new(declaration)),
110 }
111 }
112
113 pub fn new(name: Name, kind: DeclarationKind) -> DeclarationPtr {
127 DeclarationPtr::from_declaration(Declaration::new(name, kind))
128 }
129
130 pub fn new_find(name: Name, domain: DomainPtr) -> DeclarationPtr {
144 let kind = DeclarationKind::Find(DecisionVariable::new(domain));
145 DeclarationPtr::new(name, kind)
146 }
147
148 pub fn new_given(name: Name, domain: DomainPtr) -> DeclarationPtr {
162 let kind = DeclarationKind::Given(domain);
163 DeclarationPtr::new(name, kind)
164 }
165
166 pub fn new_quantified(name: Name, domain: DomainPtr) -> DeclarationPtr {
170 DeclarationPtr::new(
171 name,
172 DeclarationKind::Quantified(Quantified {
173 domain,
174 generator: None,
175 }),
176 )
177 }
178
179 pub fn new_quantified_from_generator(decl: &DeclarationPtr) -> Option<DeclarationPtr> {
183 let kind = DeclarationKind::Quantified(Quantified {
184 domain: decl.domain()?,
185 generator: Some(decl.clone()),
186 });
187 Some(DeclarationPtr::new(decl.name().clone(), kind))
188 }
189
190 pub fn new_quantified_expr(name: Name, expr: Expression) -> DeclarationPtr {
191 let kind = DeclarationKind::QuantifiedExpr(expr);
192 DeclarationPtr::new(name, kind)
193 }
194
195 pub fn new_value_letting(name: Name, expression: Expression) -> DeclarationPtr {
213 let kind = DeclarationKind::ValueLetting(expression, None);
214 DeclarationPtr::new(name, kind)
215 }
216
217 pub fn new_value_letting_with_domain(
237 name: Name,
238 expression: Expression,
239 domain: DomainPtr,
240 ) -> DeclarationPtr {
241 let kind = DeclarationKind::ValueLetting(expression, Some(domain));
242 DeclarationPtr::new(name, kind)
243 }
244
245 pub fn new_domain_letting(name: Name, domain: DomainPtr) -> DeclarationPtr {
259 let kind = DeclarationKind::DomainLetting(domain);
260 DeclarationPtr::new(name, kind)
261 }
262
263 pub fn new_record_field(entry: RecordEntry) -> DeclarationPtr {
280 let kind = DeclarationKind::RecordField(entry.domain);
281 DeclarationPtr::new(entry.name, kind)
282 }
283
284 pub fn domain(&self) -> Option<DomainPtr> {
302 match &self.kind() as &DeclarationKind {
303 DeclarationKind::Find(var) => Some(var.domain_of()),
304 DeclarationKind::ValueLetting(e, _) | DeclarationKind::TemporaryValueLetting(e) => {
305 e.domain_of()
306 }
307 DeclarationKind::DomainLetting(domain) => Some(domain.clone()),
308 DeclarationKind::Given(domain) => Some(domain.clone()),
309 DeclarationKind::Quantified(inner) => Some(inner.domain.clone()),
310 DeclarationKind::QuantifiedExpr(expr) => expr.domain_of(),
311 DeclarationKind::RecordField(domain) => Some(domain.clone()),
312 }
313 }
314
315 pub fn resolved_domain(&self) -> Option<Moo<GroundDomain>> {
317 self.domain()?.resolve()
318 }
319
320 pub fn kind(&self) -> MappedRwLockReadGuard<'_, DeclarationKind> {
332 self.map(|x| &x.kind)
333 }
334
335 pub fn name(&self) -> MappedRwLockReadGuard<'_, Name> {
348 self.map(|x| &x.name)
349 }
350
351 pub fn as_find(&self) -> Option<MappedRwLockReadGuard<'_, DecisionVariable>> {
353 RwLockReadGuard::try_map(self.read(), |x| {
354 if let DeclarationKind::Find(var) = &x.kind {
355 Some(var)
356 } else {
357 None
358 }
359 })
360 .ok()
361 }
362
363 pub fn as_find_mut(&mut self) -> Option<MappedRwLockWriteGuard<'_, DecisionVariable>> {
365 RwLockWriteGuard::try_map(self.write(), |x| {
366 if let DeclarationKind::Find(var) = &mut x.kind {
367 Some(var)
368 } else {
369 None
370 }
371 })
372 .ok()
373 }
374
375 pub fn as_domain_letting(&self) -> Option<MappedRwLockReadGuard<'_, DomainPtr>> {
377 RwLockReadGuard::try_map(self.read(), |x| {
378 if let DeclarationKind::DomainLetting(domain) = &x.kind {
379 Some(domain)
380 } else {
381 None
382 }
383 })
384 .ok()
385 }
386
387 pub fn as_domain_letting_mut(&mut self) -> Option<MappedRwLockWriteGuard<'_, DomainPtr>> {
389 RwLockWriteGuard::try_map(self.write(), |x| {
390 if let DeclarationKind::DomainLetting(domain) = &mut x.kind {
391 Some(domain)
392 } else {
393 None
394 }
395 })
396 .ok()
397 }
398
399 pub fn as_value_letting(&self) -> Option<MappedRwLockReadGuard<'_, Expression>> {
401 RwLockReadGuard::try_map(self.read(), |x| {
402 if let DeclarationKind::ValueLetting(expression, _)
403 | DeclarationKind::TemporaryValueLetting(expression) = &x.kind
404 {
405 Some(expression)
406 } else {
407 None
408 }
409 })
410 .ok()
411 }
412
413 pub fn as_value_letting_mut(&mut self) -> Option<MappedRwLockWriteGuard<'_, Expression>> {
415 RwLockWriteGuard::try_map(self.write(), |x| {
416 if let DeclarationKind::ValueLetting(expression, _)
417 | DeclarationKind::TemporaryValueLetting(expression) = &mut x.kind
418 {
419 Some(expression)
420 } else {
421 None
422 }
423 })
424 .ok()
425 }
426
427 pub fn as_given(&self) -> Option<MappedRwLockReadGuard<'_, DomainPtr>> {
429 RwLockReadGuard::try_map(self.read(), |x| {
430 if let DeclarationKind::Given(domain) = &x.kind {
431 Some(domain)
432 } else {
433 None
434 }
435 })
436 .ok()
437 }
438
439 pub fn as_given_mut(&mut self) -> Option<MappedRwLockWriteGuard<'_, DomainPtr>> {
441 RwLockWriteGuard::try_map(self.write(), |x| {
442 if let DeclarationKind::Given(domain) = &mut x.kind {
443 Some(domain)
444 } else {
445 None
446 }
447 })
448 .ok()
449 }
450
451 pub fn as_quantified_expr(&self) -> Option<MappedRwLockReadGuard<'_, Expression>> {
453 RwLockReadGuard::try_map(self.read(), |x| {
454 if let DeclarationKind::QuantifiedExpr(expr) = &x.kind {
455 Some(expr)
456 } else {
457 None
458 }
459 })
460 .ok()
461 }
462
463 pub fn as_quantified_expr_mut(&mut self) -> Option<MappedRwLockWriteGuard<'_, Expression>> {
465 RwLockWriteGuard::try_map(self.write(), |x| {
466 if let DeclarationKind::QuantifiedExpr(expr) = &mut x.kind {
467 Some(expr)
468 } else {
469 None
470 }
471 })
472 .ok()
473 }
474
475 pub fn replace_name(&mut self, name: Name) -> Name {
490 let mut decl = self.write();
491 std::mem::replace(&mut decl.name, name)
492 }
493
494 pub fn replace_kind(&mut self, kind: DeclarationKind) -> DeclarationKind {
497 let mut decl = self.write();
498 std::mem::replace(&mut decl.kind, kind)
499 }
500
501 fn read(&self) -> RwLockReadGuard<'_, Declaration> {
515 self.inner.value.read()
516 }
517
518 fn write(&mut self) -> RwLockWriteGuard<'_, Declaration> {
523 self.inner.value.write()
524 }
525
526 pub fn detach(self) -> DeclarationPtr {
556 let value = self.inner.value.read().clone();
559 DeclarationPtr {
560 inner: DeclarationPtrInner::new(RwLock::new(value)),
561 }
562 }
563
564 fn map<U>(&self, f: impl FnOnce(&Declaration) -> &U) -> MappedRwLockReadGuard<'_, U> {
566 RwLockReadGuard::map(self.read(), f)
567 }
568
569 fn map_mut<U>(
571 &mut self,
572 f: impl FnOnce(&mut Declaration) -> &mut U,
573 ) -> MappedRwLockWriteGuard<'_, U> {
574 RwLockWriteGuard::map(self.write(), f)
575 }
576
577 pub fn replace(&mut self, declaration: Declaration) -> Declaration {
580 let mut guard = self.write();
581 let ans = mem::replace(&mut *guard, declaration);
582 drop(guard);
583 ans
584 }
585}
586
587impl CategoryOf for DeclarationPtr {
588 fn category_of(&self) -> Category {
589 match &self.kind() as &DeclarationKind {
590 DeclarationKind::Find(decision_variable) => decision_variable.category_of(),
591 DeclarationKind::ValueLetting(expression, _)
592 | DeclarationKind::TemporaryValueLetting(expression) => expression.category_of(),
593 DeclarationKind::DomainLetting(_) => Category::Constant,
594 DeclarationKind::Given(_) => Category::Parameter,
595 DeclarationKind::Quantified(..) => Category::Quantified,
596 DeclarationKind::QuantifiedExpr(..) => Category::Quantified,
597 DeclarationKind::RecordField(_) => Category::Bottom,
598 }
599 }
600}
601impl HasId for DeclarationPtr {
602 const TYPE_NAME: &'static str = "DeclarationPtrInner";
603 fn id(&self) -> ObjId {
604 self.inner.id.clone()
605 }
606}
607
608impl DefaultWithId for DeclarationPtr {
609 fn default_with_id(id: ObjId) -> Self {
610 DeclarationPtr {
611 inner: DeclarationPtrInner::new_with_id_unchecked(
612 RwLock::new(Declaration {
613 name: Name::User("_UNKNOWN".into()),
614 kind: DeclarationKind::ValueLetting(false.into(), None),
615 }),
616 id,
617 ),
618 }
619 }
620}
621
622impl Typeable for DeclarationPtr {
623 fn return_type(&self) -> ReturnType {
624 match &self.kind() as &DeclarationKind {
625 DeclarationKind::Find(var) => var.return_type(),
626 DeclarationKind::ValueLetting(expression, _)
627 | DeclarationKind::TemporaryValueLetting(expression) => expression.return_type(),
628 DeclarationKind::DomainLetting(domain) => domain.return_type(),
629 DeclarationKind::Given(domain) => domain.return_type(),
630 DeclarationKind::Quantified(inner) => inner.domain.return_type(),
631 DeclarationKind::QuantifiedExpr(expr) => expr.return_type(),
632 DeclarationKind::RecordField(domain) => domain.return_type(),
633 }
634 }
635}
636
637impl Uniplate for DeclarationPtr {
638 fn uniplate(&self) -> (Tree<Self>, Box<dyn Fn(Tree<Self>) -> Self>) {
639 let decl = self.read();
640 let (tree, recons) = Biplate::<DeclarationPtr>::biplate(&decl as &Declaration);
641
642 let self2 = self.clone();
643 (
644 tree,
645 Box::new(move |x| {
646 let mut self3 = self2.clone();
647 let inner = recons(x);
648 *(&mut self3.write() as &mut Declaration) = inner;
649 self3
650 }),
651 )
652 }
653}
654
655impl<To> Biplate<To> for DeclarationPtr
656where
657 Declaration: Biplate<To>,
658 To: Uniplate,
659{
660 fn biplate(&self) -> (Tree<To>, Box<dyn Fn(Tree<To>) -> Self>) {
661 if TypeId::of::<To>() == TypeId::of::<Self>() {
662 unsafe {
663 let self_as_to = std::mem::transmute::<&Self, &To>(self).clone();
664 (
665 Tree::One(self_as_to),
666 Box::new(move |x| {
667 let Tree::One(x) = x else { panic!() };
668
669 let x_as_self = std::mem::transmute::<&To, &Self>(&x);
670 x_as_self.clone()
671 }),
672 )
673 }
674 } else {
675 let decl = self.read();
677 let (tree, recons) = Biplate::<To>::biplate(&decl as &Declaration);
678
679 let self2 = self.clone();
680 (
681 tree,
682 Box::new(move |x| {
683 let mut self3 = self2.clone();
684 let inner = recons(x);
685 *(&mut self3.write() as &mut Declaration) = inner;
686 self3
687 }),
688 )
689 }
690 }
691}
692
693type ReferenceTree = Tree<Reference>;
694type ReferenceReconstructor<T> = Box<dyn Fn(ReferenceTree) -> T>;
695
696impl Biplate<Reference> for DeclarationPtr {
697 fn biplate(&self) -> (ReferenceTree, ReferenceReconstructor<Self>) {
698 let (tree, recons_kind) = biplate_declaration_kind_references(self.kind().clone());
699
700 let self2 = self.clone();
701 (
702 tree,
703 Box::new(move |x| {
704 let mut self3 = self2.clone();
705 let _ = self3.replace_kind(recons_kind(x));
706 self3
707 }),
708 )
709 }
710}
711
712fn biplate_domain_ptr_references(
713 domain: DomainPtr,
714) -> (ReferenceTree, ReferenceReconstructor<DomainPtr>) {
715 let domain_inner = domain.as_ref().clone();
716 let (tree, recons_domain) = Biplate::<Reference>::biplate(&domain_inner);
717 (tree, Box::new(move |x| Moo::new(recons_domain(x))))
718}
719
720fn biplate_declaration_kind_references(
721 kind: DeclarationKind,
722) -> (ReferenceTree, ReferenceReconstructor<DeclarationKind>) {
723 match kind {
724 DeclarationKind::Find(var) => {
725 let (tree, recons_domain) = biplate_domain_ptr_references(var.domain.clone());
726 (
727 tree,
728 Box::new(move |x| {
729 let mut var2 = var.clone();
730 var2.domain = recons_domain(x);
731 DeclarationKind::Find(var2)
732 }),
733 )
734 }
735 DeclarationKind::Given(domain) => {
736 let (tree, recons_domain) = biplate_domain_ptr_references(domain);
737 (
738 tree,
739 Box::new(move |x| DeclarationKind::Given(recons_domain(x))),
740 )
741 }
742 DeclarationKind::DomainLetting(domain) => {
743 let (tree, recons_domain) = biplate_domain_ptr_references(domain);
744 (
745 tree,
746 Box::new(move |x| DeclarationKind::DomainLetting(recons_domain(x))),
747 )
748 }
749 DeclarationKind::RecordField(domain) => {
750 let (tree, recons_domain) = biplate_domain_ptr_references(domain);
751 (
752 tree,
753 Box::new(move |x| DeclarationKind::RecordField(recons_domain(x))),
754 )
755 }
756 DeclarationKind::ValueLetting(expression, domain) => {
757 let (tree, recons_expr) = Biplate::<Reference>::biplate(&expression);
758 (
759 tree,
760 Box::new(move |x| DeclarationKind::ValueLetting(recons_expr(x), domain.clone())),
761 )
762 }
763 DeclarationKind::TemporaryValueLetting(expression) => {
764 let (tree, recons_expr) = Biplate::<Reference>::biplate(&expression);
765 (
766 tree,
767 Box::new(move |x| DeclarationKind::TemporaryValueLetting(recons_expr(x))),
768 )
769 }
770 DeclarationKind::Quantified(quantified) => {
771 let (domain_tree, recons_domain) =
772 biplate_domain_ptr_references(quantified.domain.clone());
773
774 let (generator_tree, recons_generator) = if let Some(generator) = quantified.generator()
775 {
776 let generator = generator.clone();
777 let (tree, recons_declaration) = Biplate::<Reference>::biplate(&generator);
778 (
779 tree,
780 Box::new(move |x| Some(recons_declaration(x)))
781 as ReferenceReconstructor<Option<DeclarationPtr>>,
782 )
783 } else {
784 (
785 Tree::Zero,
786 Box::new(|_| None) as ReferenceReconstructor<Option<DeclarationPtr>>,
787 )
788 };
789
790 (
791 Tree::Many(VecDeque::from([domain_tree, generator_tree])),
792 Box::new(move |x| {
793 let Tree::Many(mut children) = x else {
794 panic!("unexpected biplate tree shape for quantified declaration")
795 };
796
797 let domain = children.pop_front().unwrap_or(Tree::Zero);
798 let generator = children.pop_front().unwrap_or(Tree::Zero);
799
800 let mut quantified2 = quantified.clone();
801 quantified2.domain = recons_domain(domain);
802 quantified2.generator = recons_generator(generator);
803 DeclarationKind::Quantified(quantified2)
804 }),
805 )
806 }
807 DeclarationKind::QuantifiedExpr(expr) => {
808 let (tree, recons_expr) = Biplate::<Reference>::biplate(&expr);
809 (
810 tree,
811 Box::new(move |x| DeclarationKind::QuantifiedExpr(recons_expr(x))),
812 )
813 }
814 }
815}
816
817impl IdPtr for DeclarationPtr {
818 type Data = Declaration;
819
820 fn get_data(&self) -> Self::Data {
821 self.read().clone()
822 }
823
824 fn with_id_and_data(id: ObjId, data: Self::Data) -> Self {
825 Self {
826 inner: DeclarationPtrInner::new_with_id_unchecked(RwLock::new(data), id),
827 }
828 }
829}
830
831impl Ord for DeclarationPtr {
832 fn cmp(&self, other: &Self) -> std::cmp::Ordering {
833 self.inner.id.cmp(&other.inner.id)
834 }
835}
836
837impl PartialOrd for DeclarationPtr {
838 fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
839 Some(self.cmp(other))
840 }
841}
842
843impl PartialEq for DeclarationPtr {
844 fn eq(&self, other: &Self) -> bool {
845 self.inner.id == other.inner.id
846 }
847}
848
849impl Eq for DeclarationPtr {}
850
851impl std::hash::Hash for DeclarationPtr {
852 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
853 self.inner.id.hash(state);
855 }
856}
857
858impl Display for DeclarationPtr {
859 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
860 let value: &Declaration = &self.read();
861 value.fmt(f)
862 }
863}
864
865#[derive(Clone, PartialEq, Debug, Serialize, Deserialize, Eq, Uniplate)]
866#[biplate(to=Expression)]
867#[biplate(to=DeclarationPtr)]
868#[biplate(to=Name)]
869pub struct Declaration {
871 name: Name,
873
874 kind: DeclarationKind,
876}
877
878impl Declaration {
879 pub fn new(name: Name, kind: DeclarationKind) -> Declaration {
881 Declaration { name, kind }
882 }
883}
884
885#[non_exhaustive]
887#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, Uniplate)]
888#[biplate(to=Expression)]
889#[biplate(to=DeclarationPtr)]
890#[biplate(to=Declaration)]
891pub enum DeclarationKind {
892 Find(DecisionVariable),
893 Given(DomainPtr),
894 Quantified(Quantified),
895 QuantifiedExpr(Expression),
896
897 ValueLetting(Expression, Option<DomainPtr>),
899 DomainLetting(DomainPtr),
900
901 TemporaryValueLetting(Expression),
905
906 RecordField(DomainPtr),
909}
910
911#[serde_as]
912#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, Uniplate)]
913pub struct Quantified {
914 domain: DomainPtr,
915
916 #[serde_as(as = "Option<PtrAsInner>")]
917 generator: Option<DeclarationPtr>,
918}
919
920impl Quantified {
921 pub fn domain(&self) -> &DomainPtr {
922 &self.domain
923 }
924
925 pub fn generator(&self) -> Option<&DeclarationPtr> {
926 self.generator.as_ref()
927 }
928}