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 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 domain(&self) -> Option<DomainPtr> {
281 match &self.kind() as &DeclarationKind {
282 DeclarationKind::Find(var) => Some(var.domain_of()),
283 DeclarationKind::ValueLetting(e, _) | DeclarationKind::TemporaryValueLetting(e) => {
284 e.domain_of()
285 }
286 DeclarationKind::DomainLetting(domain) => Some(domain.clone()),
287 DeclarationKind::Given(domain) => Some(domain.clone()),
288 DeclarationKind::Quantified(inner) => Some(inner.domain.clone()),
289 DeclarationKind::QuantifiedExpr(expr) => expr.domain_of(),
290 }
291 }
292
293 pub fn resolved_domain(&self) -> Option<Moo<GroundDomain>> {
295 self.domain()?.resolve().ok()
296 }
297
298 pub fn kind(&self) -> MappedRwLockReadGuard<'_, DeclarationKind> {
310 self.map(|x| &x.kind)
311 }
312
313 pub fn name(&self) -> MappedRwLockReadGuard<'_, Name> {
326 self.map(|x| &x.name)
327 }
328
329 pub fn as_find(&self) -> Option<MappedRwLockReadGuard<'_, DecisionVariable>> {
331 RwLockReadGuard::try_map(self.read(), |x| {
332 if let DeclarationKind::Find(var) = &x.kind {
333 Some(var)
334 } else {
335 None
336 }
337 })
338 .ok()
339 }
340
341 pub fn as_find_mut(&mut self) -> Option<MappedRwLockWriteGuard<'_, DecisionVariable>> {
343 RwLockWriteGuard::try_map(self.write(), |x| {
344 if let DeclarationKind::Find(var) = &mut x.kind {
345 Some(var)
346 } else {
347 None
348 }
349 })
350 .ok()
351 }
352
353 pub fn as_domain_letting(&self) -> Option<MappedRwLockReadGuard<'_, DomainPtr>> {
355 RwLockReadGuard::try_map(self.read(), |x| {
356 if let DeclarationKind::DomainLetting(domain) = &x.kind {
357 Some(domain)
358 } else {
359 None
360 }
361 })
362 .ok()
363 }
364
365 pub fn as_domain_letting_mut(&mut self) -> Option<MappedRwLockWriteGuard<'_, DomainPtr>> {
367 RwLockWriteGuard::try_map(self.write(), |x| {
368 if let DeclarationKind::DomainLetting(domain) = &mut x.kind {
369 Some(domain)
370 } else {
371 None
372 }
373 })
374 .ok()
375 }
376
377 pub fn as_value_letting(&self) -> Option<MappedRwLockReadGuard<'_, Expression>> {
379 RwLockReadGuard::try_map(self.read(), |x| {
380 if let DeclarationKind::ValueLetting(expression, _)
381 | DeclarationKind::TemporaryValueLetting(expression) = &x.kind
382 {
383 Some(expression)
384 } else {
385 None
386 }
387 })
388 .ok()
389 }
390
391 pub fn as_value_letting_mut(&mut self) -> Option<MappedRwLockWriteGuard<'_, Expression>> {
393 RwLockWriteGuard::try_map(self.write(), |x| {
394 if let DeclarationKind::ValueLetting(expression, _)
395 | DeclarationKind::TemporaryValueLetting(expression) = &mut x.kind
396 {
397 Some(expression)
398 } else {
399 None
400 }
401 })
402 .ok()
403 }
404
405 pub fn as_given(&self) -> Option<MappedRwLockReadGuard<'_, DomainPtr>> {
407 RwLockReadGuard::try_map(self.read(), |x| {
408 if let DeclarationKind::Given(domain) = &x.kind {
409 Some(domain)
410 } else {
411 None
412 }
413 })
414 .ok()
415 }
416
417 pub fn as_given_mut(&mut self) -> Option<MappedRwLockWriteGuard<'_, DomainPtr>> {
419 RwLockWriteGuard::try_map(self.write(), |x| {
420 if let DeclarationKind::Given(domain) = &mut x.kind {
421 Some(domain)
422 } else {
423 None
424 }
425 })
426 .ok()
427 }
428
429 pub fn as_quantified_expr(&self) -> Option<MappedRwLockReadGuard<'_, Expression>> {
431 RwLockReadGuard::try_map(self.read(), |x| {
432 if let DeclarationKind::QuantifiedExpr(expr) = &x.kind {
433 Some(expr)
434 } else {
435 None
436 }
437 })
438 .ok()
439 }
440
441 pub fn as_quantified_expr_mut(&mut self) -> Option<MappedRwLockWriteGuard<'_, Expression>> {
443 RwLockWriteGuard::try_map(self.write(), |x| {
444 if let DeclarationKind::QuantifiedExpr(expr) = &mut x.kind {
445 Some(expr)
446 } else {
447 None
448 }
449 })
450 .ok()
451 }
452
453 pub fn replace_name(&mut self, name: Name) -> Name {
468 let mut decl = self.write();
469 std::mem::replace(&mut decl.name, name)
470 }
471
472 pub fn replace_kind(&mut self, kind: DeclarationKind) -> DeclarationKind {
475 let mut decl = self.write();
476 std::mem::replace(&mut decl.kind, kind)
477 }
478
479 fn read(&self) -> RwLockReadGuard<'_, Declaration> {
493 self.inner.value.read()
494 }
495
496 fn write(&mut self) -> RwLockWriteGuard<'_, Declaration> {
501 self.inner.value.write()
502 }
503
504 pub fn detach(self) -> DeclarationPtr {
534 let value = self.inner.value.read().clone();
537 DeclarationPtr {
538 inner: DeclarationPtrInner::new(RwLock::new(value)),
539 }
540 }
541
542 fn map<U>(&self, f: impl FnOnce(&Declaration) -> &U) -> MappedRwLockReadGuard<'_, U> {
544 RwLockReadGuard::map(self.read(), f)
545 }
546
547 fn map_mut<U>(
549 &mut self,
550 f: impl FnOnce(&mut Declaration) -> &mut U,
551 ) -> MappedRwLockWriteGuard<'_, U> {
552 RwLockWriteGuard::map(self.write(), f)
553 }
554
555 pub fn replace(&mut self, declaration: Declaration) -> Declaration {
558 let mut guard = self.write();
559 let ans = mem::replace(&mut *guard, declaration);
560 drop(guard);
561 ans
562 }
563}
564
565impl CategoryOf for DeclarationPtr {
566 fn category_of(&self) -> Category {
567 match &self.kind() as &DeclarationKind {
568 DeclarationKind::Find(decision_variable) => decision_variable.category_of(),
569 DeclarationKind::ValueLetting(expression, _)
570 | DeclarationKind::TemporaryValueLetting(expression) => expression.category_of(),
571 DeclarationKind::DomainLetting(_) => Category::Constant,
572 DeclarationKind::Given(_) => Category::Parameter,
573 DeclarationKind::Quantified(..) => Category::Quantified,
574 DeclarationKind::QuantifiedExpr(..) => Category::Quantified,
575 }
576 }
577}
578impl HasId for DeclarationPtr {
579 const TYPE_NAME: &'static str = "DeclarationPtrInner";
580 fn id(&self) -> ObjId {
581 self.inner.id.clone()
582 }
583}
584
585impl DefaultWithId for DeclarationPtr {
586 fn default_with_id(id: ObjId) -> Self {
587 DeclarationPtr {
588 inner: DeclarationPtrInner::new_with_id_unchecked(
589 RwLock::new(Declaration {
590 name: Name::User("_UNKNOWN".into()),
591 kind: DeclarationKind::ValueLetting(false.into(), None),
592 }),
593 id,
594 ),
595 }
596 }
597}
598
599impl Typeable for DeclarationPtr {
600 fn return_type(&self) -> ReturnType {
601 match &self.kind() as &DeclarationKind {
602 DeclarationKind::Find(var) => var.return_type(),
603 DeclarationKind::ValueLetting(expression, _)
604 | DeclarationKind::TemporaryValueLetting(expression) => expression.return_type(),
605 DeclarationKind::DomainLetting(domain) => domain.return_type(),
606 DeclarationKind::Given(domain) => domain.return_type(),
607 DeclarationKind::Quantified(inner) => inner.domain.return_type(),
608 DeclarationKind::QuantifiedExpr(expr) => expr.return_type(),
609 }
610 }
611}
612
613impl Uniplate for DeclarationPtr {
614 fn uniplate(&self) -> (Tree<Self>, Box<dyn Fn(Tree<Self>) -> Self>) {
615 let decl = self.read();
616 let (tree, recons) = Biplate::<DeclarationPtr>::biplate(&decl as &Declaration);
617
618 let self2 = self.clone();
619 (
620 tree,
621 Box::new(move |x| {
622 let mut self3 = self2.clone();
623 let inner = recons(x);
624 *(&mut self3.write() as &mut Declaration) = inner;
625 self3
626 }),
627 )
628 }
629}
630
631impl<To> Biplate<To> for DeclarationPtr
632where
633 Declaration: Biplate<To>,
634 To: Uniplate,
635{
636 fn biplate(&self) -> (Tree<To>, Box<dyn Fn(Tree<To>) -> Self>) {
637 if TypeId::of::<To>() == TypeId::of::<Self>() {
638 unsafe {
639 let self_as_to = std::mem::transmute::<&Self, &To>(self).clone();
640 (
641 Tree::One(self_as_to),
642 Box::new(move |x| {
643 let Tree::One(x) = x else { panic!() };
644
645 let x_as_self = std::mem::transmute::<&To, &Self>(&x);
646 x_as_self.clone()
647 }),
648 )
649 }
650 } else {
651 let decl = self.read();
653 let (tree, recons) = Biplate::<To>::biplate(&decl as &Declaration);
654
655 let self2 = self.clone();
656 (
657 tree,
658 Box::new(move |x| {
659 let mut self3 = self2.clone();
660 let inner = recons(x);
661 *(&mut self3.write() as &mut Declaration) = inner;
662 self3
663 }),
664 )
665 }
666 }
667}
668
669type ReferenceTree = Tree<Reference>;
670type ReferenceReconstructor<T> = Box<dyn Fn(ReferenceTree) -> T>;
671
672impl Biplate<Reference> for DeclarationPtr {
673 fn biplate(&self) -> (ReferenceTree, ReferenceReconstructor<Self>) {
674 let (tree, recons_kind) = biplate_declaration_kind_references(self.kind().clone());
675
676 let self2 = self.clone();
677 (
678 tree,
679 Box::new(move |x| {
680 let mut self3 = self2.clone();
681 let _ = self3.replace_kind(recons_kind(x));
682 self3
683 }),
684 )
685 }
686}
687
688fn biplate_domain_ptr_references(
689 domain: DomainPtr,
690) -> (ReferenceTree, ReferenceReconstructor<DomainPtr>) {
691 let domain_inner = domain.as_ref().clone();
692 let (tree, recons_domain) = Biplate::<Reference>::biplate(&domain_inner);
693 (tree, Box::new(move |x| Moo::new(recons_domain(x))))
694}
695
696fn biplate_declaration_kind_references(
697 kind: DeclarationKind,
698) -> (ReferenceTree, ReferenceReconstructor<DeclarationKind>) {
699 match kind {
700 DeclarationKind::Find(var) => {
701 let (tree, recons_domain) = biplate_domain_ptr_references(var.domain.clone());
702 (
703 tree,
704 Box::new(move |x| {
705 let mut var2 = var.clone();
706 var2.domain = recons_domain(x);
707 DeclarationKind::Find(var2)
708 }),
709 )
710 }
711 DeclarationKind::Given(domain) => {
712 let (tree, recons_domain) = biplate_domain_ptr_references(domain);
713 (
714 tree,
715 Box::new(move |x| DeclarationKind::Given(recons_domain(x))),
716 )
717 }
718 DeclarationKind::DomainLetting(domain) => {
719 let (tree, recons_domain) = biplate_domain_ptr_references(domain);
720 (
721 tree,
722 Box::new(move |x| DeclarationKind::DomainLetting(recons_domain(x))),
723 )
724 }
725 DeclarationKind::ValueLetting(expression, domain) => {
726 let (tree, recons_expr) = Biplate::<Reference>::biplate(&expression);
727 (
728 tree,
729 Box::new(move |x| DeclarationKind::ValueLetting(recons_expr(x), domain.clone())),
730 )
731 }
732 DeclarationKind::TemporaryValueLetting(expression) => {
733 let (tree, recons_expr) = Biplate::<Reference>::biplate(&expression);
734 (
735 tree,
736 Box::new(move |x| DeclarationKind::TemporaryValueLetting(recons_expr(x))),
737 )
738 }
739 DeclarationKind::Quantified(quantified) => {
740 let (domain_tree, recons_domain) =
741 biplate_domain_ptr_references(quantified.domain.clone());
742
743 let (generator_tree, recons_generator) = if let Some(generator) = quantified.generator()
744 {
745 let generator = generator.clone();
746 let (tree, recons_declaration) = Biplate::<Reference>::biplate(&generator);
747 (
748 tree,
749 Box::new(move |x| Some(recons_declaration(x)))
750 as ReferenceReconstructor<Option<DeclarationPtr>>,
751 )
752 } else {
753 (
754 Tree::Zero,
755 Box::new(|_| None) as ReferenceReconstructor<Option<DeclarationPtr>>,
756 )
757 };
758
759 (
760 Tree::Many(VecDeque::from([domain_tree, generator_tree])),
761 Box::new(move |x| {
762 let Tree::Many(mut children) = x else {
763 panic!("unexpected biplate tree shape for quantified declaration")
764 };
765
766 let domain = children.pop_front().unwrap_or(Tree::Zero);
767 let generator = children.pop_front().unwrap_or(Tree::Zero);
768
769 let mut quantified2 = quantified.clone();
770 quantified2.domain = recons_domain(domain);
771 quantified2.generator = recons_generator(generator);
772 DeclarationKind::Quantified(quantified2)
773 }),
774 )
775 }
776 DeclarationKind::QuantifiedExpr(expr) => {
777 let (tree, recons_expr) = Biplate::<Reference>::biplate(&expr);
778 (
779 tree,
780 Box::new(move |x| DeclarationKind::QuantifiedExpr(recons_expr(x))),
781 )
782 }
783 }
784}
785
786impl IdPtr for DeclarationPtr {
787 type Data = Declaration;
788
789 fn get_data(&self) -> Self::Data {
790 self.read().clone()
791 }
792
793 fn with_id_and_data(id: ObjId, data: Self::Data) -> Self {
794 Self {
795 inner: DeclarationPtrInner::new_with_id_unchecked(RwLock::new(data), id),
796 }
797 }
798}
799
800impl Ord for DeclarationPtr {
801 fn cmp(&self, other: &Self) -> std::cmp::Ordering {
802 self.inner.id.cmp(&other.inner.id)
803 }
804}
805
806impl PartialOrd for DeclarationPtr {
807 fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
808 Some(self.cmp(other))
809 }
810}
811
812impl PartialEq for DeclarationPtr {
813 fn eq(&self, other: &Self) -> bool {
814 self.inner.id == other.inner.id
815 }
816}
817
818impl Eq for DeclarationPtr {}
819
820impl std::hash::Hash for DeclarationPtr {
821 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
822 self.inner.id.hash(state);
824 }
825}
826
827impl Display for DeclarationPtr {
828 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
829 let value: &Declaration = &self.read();
830 value.fmt(f)
831 }
832}
833
834#[derive(Clone, PartialEq, Debug, Serialize, Deserialize, Eq, Uniplate)]
835#[biplate(to=Expression)]
836#[biplate(to=DeclarationPtr)]
837#[biplate(to=Name)]
838pub struct Declaration {
840 name: Name,
842
843 kind: DeclarationKind,
845}
846
847impl Declaration {
848 pub fn new(name: Name, kind: DeclarationKind) -> Declaration {
850 Declaration { name, kind }
851 }
852}
853
854#[non_exhaustive]
856#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, Uniplate)]
857#[biplate(to=Expression)]
858#[biplate(to=DeclarationPtr)]
859#[biplate(to=Declaration)]
860pub enum DeclarationKind {
861 Find(DecisionVariable),
862 Given(DomainPtr),
863 Quantified(Quantified),
864 QuantifiedExpr(Expression),
865
866 ValueLetting(Expression, Option<DomainPtr>),
868 DomainLetting(DomainPtr),
869
870 TemporaryValueLetting(Expression),
874}
875
876#[serde_as]
877#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, Uniplate)]
878pub struct Quantified {
879 domain: DomainPtr,
880
881 #[serde_as(as = "Option<PtrAsInner>")]
882 generator: Option<DeclarationPtr>,
883}
884
885impl Quantified {
886 pub fn domain(&self) -> &DomainPtr {
887 &self.domain
888 }
889
890 pub fn generator(&self) -> Option<&DeclarationPtr> {
891 self.generator.as_ref()
892 }
893}