sdml_core/model/constraints/formal/
sentences.rs

1use crate::error::Error;
2use crate::model::constraints::Term;
3use crate::model::identifiers::Identifier;
4use crate::model::{HasBody, HasName, HasSourceSpan, Span};
5use crate::syntax::{
6    KW_OPERATION_BICONDITIONAL, KW_OPERATION_BICONDITIONAL_SYMBOL, KW_OPERATION_CONJUNCTION,
7    KW_OPERATION_CONJUNCTION_SYMBOL, KW_OPERATION_DISJUNCTION, KW_OPERATION_DISJUNCTION_SYMBOL,
8    KW_OPERATION_EXCLUSIVE_DISJUNCTION, KW_OPERATION_EXCLUSIVE_DISJUNCTION_SYMBOL,
9    KW_OPERATION_IMPLICATION, KW_OPERATION_IMPLICATION_SYMBOL, KW_OPERATION_NEGATION,
10    KW_OPERATION_NEGATION_SYMBOL, KW_QUANTIFIER_EXISTS, KW_QUANTIFIER_EXISTS_SYMBOL,
11    KW_QUANTIFIER_FORALL, KW_QUANTIFIER_FORALL_SYMBOL, KW_RELATION_GREATER_THAN,
12    KW_RELATION_GREATER_THAN_OR_EQUAL, KW_RELATION_GREATER_THAN_OR_EQUAL_SYMBOL,
13    KW_RELATION_LESS_THAN, KW_RELATION_LESS_THAN_OR_EQUAL, KW_RELATION_LESS_THAN_OR_EQUAL_SYMBOL,
14    KW_RELATION_NOT_EQUAL, KW_RELATION_NOT_EQUAL_SYMBOL,
15};
16use std::fmt::Display;
17use std::str::FromStr;
18
19#[cfg(feature = "serde")]
20use serde::{Deserialize, Serialize};
21
22// ------------------------------------------------------------------------------------------------
23// Public Types ❱ Constraints ❱  Sentences
24// ------------------------------------------------------------------------------------------------
25
26///
27/// Corresponds to the grammar rule `constraint_sentence`.
28///
29/// A `ConstraintSentence` is either a [`SimpleSentence`], a [`BooleanSentence`], or
30/// a [`QuantifiedSentence`].
31///
32#[derive(Clone, Debug)]
33#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
34pub enum ConstraintSentence {
35    Simple(SimpleSentence),
36    Boolean(BooleanSentence),
37    Quantified(QuantifiedSentence),
38}
39
40///
41/// Corresponds to the grammar rule `simple_sentence`.
42///
43/// A `SimpleSentence` is either an [`AtomicSentence`] or an [`Equation`].
44///
45#[derive(Clone, Debug)]
46#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
47pub enum SimpleSentence {
48    /// Corresponds to the choice `atomic_sentence`.
49    Atomic(AtomicSentence),
50    /// Corresponds to the choice `equation`.
51    Equation(Equation),
52    /// Corresponds to the choice `inequation`.
53    Inequation(Inequation),
54}
55
56///
57/// Corresponds to the grammar rule `atomic_sentence`.
58///
59/// An `AtomicSentence` has a *predicate* term and an ordered list of terms corresponding
60/// to the predicate *arguments*.
61///
62#[derive(Clone, Debug)]
63#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
64pub struct AtomicSentence {
65    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
66    span: Option<Span>,
67    predicate: Term,
68    arguments: Vec<Term>,
69}
70
71#[derive(Clone, Debug)]
72#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
73pub struct Equation {
74    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
75    span: Option<Span>,
76    left_operand: Term,
77    right_operand: Term,
78}
79
80#[derive(Clone, Debug)]
81#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
82pub struct Inequation {
83    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
84    span: Option<Span>,
85    left_operand: Term,
86    relation: InequalityRelation,
87    right_operand: Term,
88}
89
90#[derive(Clone, Copy, Debug, PartialEq, Eq)]
91#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
92pub enum InequalityRelation {
93    NotEqual,
94    LessThan,
95    LessThanOrEqual,
96    GreaterThan,
97    GreaterThanOrEqual,
98}
99
100///
101/// Corresponds to the grammar rule `boolean_sentence`.
102///
103/// Boolean sentences are those that are constructed with the boolean operations negation (not),
104/// conjunction (and), disjunction (or), exclusive disjunction (xor), implication, or
105/// biconditional.
106///
107#[derive(Clone, Debug)]
108#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
109pub enum BooleanSentence {
110    Unary(UnaryBooleanSentence),
111    Binary(BinaryBooleanSentence),
112}
113
114///
115/// Holds the *left* and *right* operands in the rules `conjunction`, `disjunction`,
116/// `exclusive_disjunction`, `implication`, and `biconditional`.
117///
118#[derive(Clone, Debug)]
119#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
120pub struct UnaryBooleanSentence {
121    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
122    span: Option<Span>,
123    operand: Box<ConstraintSentence>,
124}
125
126///
127/// Holds the *left* and *right* operands in the rules `conjunction`, `disjunction`,
128/// `exclusive_disjunction`, `implication`, and `biconditional`.
129///
130#[derive(Clone, Debug)]
131#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
132pub struct BinaryBooleanSentence {
133    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
134    span: Option<Span>,
135    left_operand: Box<ConstraintSentence>,
136    operator: ConnectiveOperator,
137    right_operand: Box<ConstraintSentence>,
138}
139
140#[derive(Clone, Copy, Debug, PartialEq, Eq)]
141#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
142pub enum ConnectiveOperator {
143    /// Corresponds to the grammar rule `negation`. Uses the prefix keyword **`not`**
144    /// or the operator $\lnot$.
145    Negation,
146    /// Corresponds to the grammar rule `conjunction`. Uses the infix keyword **`and`**
147    /// or the operator $\land$.
148    Conjunction,
149    /// Corresponds to the grammar rule `disjunction`. Uses the infix keyword **`or`**
150    /// or the operator $\lor$.
151    Disjunction,
152    /// Corresponds to the grammar rule `exclusive_disjunction`. Uses the infix keyword **`xor`**
153    /// or the operator $\veebar$. Note that this operation is not a part of ISO Common Logic but
154    /// $a \veebar b$ can be rewritten as $\lnot (a \iff b)$
155    ExclusiveDisjunction,
156    /// Corresponds to the grammar rule `implication`. Uses the infix keyword **`implies`**
157    /// or the operator $\implies$.
158    Implication,
159    /// Corresponds to the grammar rule `biconditional`. Uses the infix keyword **`iff`**
160    /// or the operator $\iff$.
161    Biconditional,
162}
163
164///
165/// Corresponds to the grammar rule `quantified_sentence`.
166///
167/// Such a sentence may be either *universally* or *existentially* quantified.
168///
169#[derive(Clone, Debug)]
170#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
171pub struct QuantifiedSentence {
172    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
173    span: Option<Span>,
174    binding: QuantifiedVariableBinding,
175    body: Box<ConstraintSentence>,
176}
177
178#[derive(Clone, Debug)]
179#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
180pub struct QuantifiedVariableBinding {
181    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
182    span: Option<Span>,
183    quantifier: Quantifier,
184    // None = `self`
185    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
186    binding: Option<QuantifiedVariable>,
187}
188
189#[derive(Clone, Copy, Debug, PartialEq, Eq)]
190#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
191pub enum Quantifier {
192    /// Corresponds to the grammar rule `universal`. Introduced with the keyword **`forall`**
193    /// or the operator $\forall$.
194    Universal,
195    /// Corresponds to the grammar rule `existential`. Introduced with the keyword **`exists`**
196    /// or the operator $\exists$.
197    Existential,
198}
199
200///
201/// Corresponds to the grammar rule `quantified_variable`.
202///
203/// A `QuantifiedVariable` is a *name* and *source* pair.
204///
205#[derive(Clone, Debug)]
206#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
207pub struct QuantifiedVariable {
208    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
209    span: Option<Span>,
210    name: Identifier,
211    source: Term,
212}
213
214// ------------------------------------------------------------------------------------------------
215// Implementations ❱ Constraints ❱ ConstraintSentence
216// ------------------------------------------------------------------------------------------------
217
218impl From<&SimpleSentence> for ConstraintSentence {
219    fn from(v: &SimpleSentence) -> Self {
220        Self::Simple(v.clone())
221    }
222}
223
224impl From<SimpleSentence> for ConstraintSentence {
225    fn from(v: SimpleSentence) -> Self {
226        Self::Simple(v)
227    }
228}
229
230impl From<&BooleanSentence> for ConstraintSentence {
231    fn from(v: &BooleanSentence) -> Self {
232        Self::Boolean(v.clone())
233    }
234}
235
236impl From<BooleanSentence> for ConstraintSentence {
237    fn from(v: BooleanSentence) -> Self {
238        Self::Boolean(v)
239    }
240}
241
242impl From<&QuantifiedSentence> for ConstraintSentence {
243    fn from(v: &QuantifiedSentence) -> Self {
244        Self::Quantified(v.clone())
245    }
246}
247
248impl From<QuantifiedSentence> for ConstraintSentence {
249    fn from(v: QuantifiedSentence) -> Self {
250        Self::Quantified(v)
251    }
252}
253
254impl ConstraintSentence {
255    // --------------------------------------------------------------------------------------------
256    // Variants
257    // --------------------------------------------------------------------------------------------
258
259    pub const fn is_simple(&self) -> bool {
260        matches!(self, Self::Simple(_))
261    }
262
263    pub const fn as_simple(&self) -> Option<&SimpleSentence> {
264        match self {
265            Self::Simple(v) => Some(v),
266            _ => None,
267        }
268    }
269
270    pub const fn is_boolean(&self) -> bool {
271        matches!(self, Self::Boolean(_))
272    }
273
274    pub const fn as_boolean(&self) -> Option<&BooleanSentence> {
275        match self {
276            Self::Boolean(v) => Some(v),
277            _ => None,
278        }
279    }
280
281    pub const fn is_quantified(&self) -> bool {
282        matches!(self, Self::Quantified(_))
283    }
284
285    pub const fn as_quantified(&self) -> Option<&QuantifiedSentence> {
286        match self {
287            Self::Quantified(v) => Some(v),
288            _ => None,
289        }
290    }
291}
292
293// ------------------------------------------------------------------------------------------------
294// Implementations ❱ Constraints ❱ SimpleSentence
295// ------------------------------------------------------------------------------------------------
296
297impl From<&AtomicSentence> for SimpleSentence {
298    fn from(v: &AtomicSentence) -> Self {
299        Self::Atomic(v.clone())
300    }
301}
302
303impl From<AtomicSentence> for SimpleSentence {
304    fn from(v: AtomicSentence) -> Self {
305        Self::Atomic(v)
306    }
307}
308
309impl From<&Equation> for SimpleSentence {
310    fn from(v: &Equation) -> Self {
311        Self::Equation(v.clone())
312    }
313}
314
315impl From<Equation> for SimpleSentence {
316    fn from(v: Equation) -> Self {
317        Self::Equation(v)
318    }
319}
320
321impl From<&Inequation> for SimpleSentence {
322    fn from(v: &Inequation) -> Self {
323        Self::Inequation(v.clone())
324    }
325}
326
327impl From<Inequation> for SimpleSentence {
328    fn from(v: Inequation) -> Self {
329        Self::Inequation(v)
330    }
331}
332
333impl SimpleSentence {
334    // --------------------------------------------------------------------------------------------
335    // Variants
336    // --------------------------------------------------------------------------------------------
337
338    pub const fn is_atomic(&self) -> bool {
339        matches!(self, Self::Atomic(_))
340    }
341
342    pub const fn as_atomic(&self) -> Option<&AtomicSentence> {
343        match self {
344            Self::Atomic(v) => Some(v),
345            _ => None,
346        }
347    }
348
349    pub const fn is_equation(&self) -> bool {
350        matches!(self, Self::Equation(_))
351    }
352
353    pub const fn as_equation(&self) -> Option<&Equation> {
354        match self {
355            Self::Equation(v) => Some(v),
356            _ => None,
357        }
358    }
359
360    pub const fn is_inequation(&self) -> bool {
361        matches!(self, Self::Inequation(_))
362    }
363
364    pub const fn as_inequation(&self) -> Option<&Inequation> {
365        match self {
366            Self::Inequation(v) => Some(v),
367            _ => None,
368        }
369    }
370}
371
372// ------------------------------------------------------------------------------------------------
373// Implementations ❱ Constraints ❱ AtomicSentence
374// ------------------------------------------------------------------------------------------------
375
376impl HasSourceSpan for AtomicSentence {
377    fn with_source_span(self, span: Span) -> Self {
378        let mut self_mut = self;
379        self_mut.span = Some(span);
380        self_mut
381    }
382
383    fn source_span(&self) -> Option<&Span> {
384        self.span.as_ref()
385    }
386
387    fn set_source_span(&mut self, span: Span) {
388        self.span = Some(span);
389    }
390
391    fn unset_source_span(&mut self) {
392        self.span = None;
393    }
394}
395
396impl AtomicSentence {
397    // --------------------------------------------------------------------------------------------
398    // Constructors
399    // --------------------------------------------------------------------------------------------
400
401    pub fn new<T>(predicate: T) -> Self
402    where
403        T: Into<Term>,
404    {
405        Self {
406            span: Default::default(),
407            predicate: predicate.into(),
408            arguments: Default::default(),
409        }
410    }
411
412    pub fn new_with_arguments<T, I>(predicate: T, arguments: I) -> Self
413    where
414        T: Into<Term>,
415        I: IntoIterator<Item = Term>,
416    {
417        Self {
418            span: Default::default(),
419            predicate: predicate.into(),
420            arguments: Vec::from_iter(arguments),
421        }
422    }
423
424    // --------------------------------------------------------------------------------------------
425    // Fields
426    // --------------------------------------------------------------------------------------------
427
428    pub const fn predicate(&self) -> &Term {
429        &self.predicate
430    }
431
432    pub fn set_predicate(&mut self, predicate: Term) {
433        self.predicate = predicate;
434    }
435
436    // --------------------------------------------------------------------------------------------
437
438    pub fn has_arguments(&self) -> bool {
439        !self.arguments.is_empty()
440    }
441
442    pub fn arguments_len(&self) -> usize {
443        self.arguments.len()
444    }
445
446    pub fn arguments(&self) -> impl Iterator<Item = &Term> {
447        self.arguments.iter()
448    }
449
450    pub fn arguments_mut(&mut self) -> impl Iterator<Item = &mut Term> {
451        self.arguments.iter_mut()
452    }
453
454    pub fn add_to_arguments<I>(&mut self, value: I)
455    where
456        I: Into<Term>,
457    {
458        self.arguments.push(value.into())
459    }
460
461    pub fn extend_arguments<I>(&mut self, extension: I)
462    where
463        I: IntoIterator<Item = Term>,
464    {
465        self.arguments.extend(extension)
466    }
467}
468
469// ------------------------------------------------------------------------------------------------
470// Implementations ❱ Constraints ❱ Equation
471// ------------------------------------------------------------------------------------------------
472
473impl HasSourceSpan for Equation {
474    fn with_source_span(self, span: Span) -> Self {
475        let mut self_mut = self;
476        self_mut.span = Some(span);
477        self_mut
478    }
479
480    fn source_span(&self) -> Option<&Span> {
481        self.span.as_ref()
482    }
483
484    fn set_source_span(&mut self, span: Span) {
485        self.span = Some(span);
486    }
487
488    fn unset_source_span(&mut self) {
489        self.span = None;
490    }
491}
492
493impl Equation {
494    // --------------------------------------------------------------------------------------------
495    // Constructors
496    // --------------------------------------------------------------------------------------------
497
498    pub fn new<L, R>(left_operand: L, right_operand: R) -> Self
499    where
500        L: Into<Term>,
501        R: Into<Term>,
502    {
503        Self {
504            span: Default::default(),
505            left_operand: left_operand.into(),
506            right_operand: right_operand.into(),
507        }
508    }
509
510    // --------------------------------------------------------------------------------------------
511    // Fields
512    // --------------------------------------------------------------------------------------------
513
514    pub const fn left_operand(&self) -> &Term {
515        &self.left_operand
516    }
517
518    pub fn set_left_operand(&mut self, left_operand: Term) {
519        self.left_operand = left_operand;
520    }
521
522    // --------------------------------------------------------------------------------------------
523
524    pub const fn right_operand(&self) -> &Term {
525        &self.right_operand
526    }
527
528    pub fn set_right_operand(&mut self, right_operand: Term) {
529        self.right_operand = right_operand;
530    }
531}
532
533// ------------------------------------------------------------------------------------------------
534// Implementations ❱ Constraints ❱ Inequation
535// ------------------------------------------------------------------------------------------------
536
537impl HasSourceSpan for Inequation {
538    fn with_source_span(self, span: Span) -> Self {
539        let mut self_mut = self;
540        self_mut.span = Some(span);
541        self_mut
542    }
543
544    fn source_span(&self) -> Option<&Span> {
545        self.span.as_ref()
546    }
547
548    fn set_source_span(&mut self, span: Span) {
549        self.span = Some(span);
550    }
551
552    fn unset_source_span(&mut self) {
553        self.span = None;
554    }
555}
556
557impl Inequation {
558    // --------------------------------------------------------------------------------------------
559    // Constructors
560    // --------------------------------------------------------------------------------------------
561
562    pub fn new<L, R>(left_operand: L, relation: InequalityRelation, right_operand: R) -> Self
563    where
564        L: Into<Term>,
565        R: Into<Term>,
566    {
567        Self {
568            span: Default::default(),
569            left_operand: left_operand.into(),
570            relation,
571            right_operand: right_operand.into(),
572        }
573    }
574
575    #[inline(always)]
576    pub fn not_equal<L, R>(left_operand: L, right_operand: R) -> Self
577    where
578        L: Into<Term>,
579        R: Into<Term>,
580    {
581        Self::new(left_operand, InequalityRelation::NotEqual, right_operand)
582    }
583
584    #[inline(always)]
585    pub fn less_than<L, R>(left_operand: L, right_operand: R) -> Self
586    where
587        L: Into<Term>,
588        R: Into<Term>,
589    {
590        Self::new(left_operand, InequalityRelation::LessThan, right_operand)
591    }
592
593    #[inline(always)]
594    pub fn less_than_or_greater<L, R>(left_operand: L, right_operand: R) -> Self
595    where
596        L: Into<Term>,
597        R: Into<Term>,
598    {
599        Self::new(
600            left_operand,
601            InequalityRelation::LessThanOrEqual,
602            right_operand,
603        )
604    }
605
606    #[inline(always)]
607    pub fn greater_than<L, R>(left_operand: L, right_operand: R) -> Self
608    where
609        L: Into<Term>,
610        R: Into<Term>,
611    {
612        Self::new(left_operand, InequalityRelation::GreaterThan, right_operand)
613    }
614
615    #[inline(always)]
616    pub fn greater_than_or_equal<L, R>(left_operand: L, right_operand: R) -> Self
617    where
618        L: Into<Term>,
619        R: Into<Term>,
620    {
621        Self::new(
622            left_operand,
623            InequalityRelation::GreaterThanOrEqual,
624            right_operand,
625        )
626    }
627
628    // --------------------------------------------------------------------------------------------
629    // Fields
630    // --------------------------------------------------------------------------------------------
631
632    pub const fn left_operand(&self) -> &Term {
633        &self.left_operand
634    }
635
636    pub fn set_left_operand(&mut self, left_operand: Term) {
637        self.left_operand = left_operand;
638    }
639
640    // --------------------------------------------------------------------------------------------
641
642    pub const fn relation(&self) -> &InequalityRelation {
643        &self.relation
644    }
645
646    pub fn set_relation(&mut self, relation: InequalityRelation) {
647        self.relation = relation;
648    }
649
650    #[inline(always)]
651    pub fn is_not_equal(&self) -> bool {
652        self.relation == InequalityRelation::NotEqual
653    }
654
655    #[inline(always)]
656    pub fn is_less_than(&self) -> bool {
657        self.relation == InequalityRelation::LessThan
658    }
659
660    #[inline(always)]
661    pub fn is_greater_than(&self) -> bool {
662        self.relation == InequalityRelation::GreaterThan
663    }
664
665    #[inline(always)]
666    pub fn is_less_than_or_equal(&self) -> bool {
667        self.relation == InequalityRelation::LessThanOrEqual
668    }
669
670    #[inline(always)]
671    pub fn is_greater_than_or_equal(&self) -> bool {
672        self.relation == InequalityRelation::GreaterThanOrEqual
673    }
674
675    // --------------------------------------------------------------------------------------------
676
677    pub const fn right_operand(&self) -> &Term {
678        &self.right_operand
679    }
680
681    pub fn set_right_operand(&mut self, right_operand: Term) {
682        self.right_operand = right_operand;
683    }
684}
685
686// ------------------------------------------------------------------------------------------------
687// Implementations ❱ Constraints ❱ InequalityRelation
688// ------------------------------------------------------------------------------------------------
689
690impl FromStr for InequalityRelation {
691    type Err = Error;
692
693    fn from_str(s: &str) -> Result<Self, Self::Err> {
694        match s {
695            KW_RELATION_NOT_EQUAL | KW_RELATION_NOT_EQUAL_SYMBOL => Ok(Self::NotEqual),
696            KW_RELATION_LESS_THAN => Ok(Self::LessThan),
697            KW_RELATION_LESS_THAN_OR_EQUAL | KW_RELATION_LESS_THAN_OR_EQUAL_SYMBOL => {
698                Ok(Self::LessThanOrEqual)
699            }
700            KW_RELATION_GREATER_THAN => Ok(Self::GreaterThan),
701            KW_RELATION_GREATER_THAN_OR_EQUAL | KW_RELATION_GREATER_THAN_OR_EQUAL_SYMBOL => {
702                Ok(Self::GreaterThanOrEqual)
703            }
704            // TODO: a real error.
705            _ => panic!(),
706        }
707    }
708}
709
710impl Display for InequalityRelation {
711    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
712        write!(
713            f,
714            "{}",
715            match (self, f.alternate()) {
716                (Self::NotEqual, true) => KW_RELATION_NOT_EQUAL_SYMBOL,
717                (Self::NotEqual, false) => KW_RELATION_NOT_EQUAL,
718                (Self::LessThan, _) => KW_RELATION_LESS_THAN,
719                (Self::LessThanOrEqual, true) => KW_RELATION_LESS_THAN_OR_EQUAL_SYMBOL,
720                (Self::LessThanOrEqual, false) => KW_RELATION_LESS_THAN_OR_EQUAL,
721                (Self::GreaterThan, _) => KW_RELATION_GREATER_THAN,
722                (Self::GreaterThanOrEqual, true) => KW_RELATION_GREATER_THAN_OR_EQUAL,
723                (Self::GreaterThanOrEqual, false) => KW_RELATION_GREATER_THAN_OR_EQUAL_SYMBOL,
724            }
725        )
726    }
727}
728
729// ------------------------------------------------------------------------------------------------
730// Implementations ❱ Constraints ❱ BooleanSentence
731// ------------------------------------------------------------------------------------------------
732
733impl From<&UnaryBooleanSentence> for BooleanSentence {
734    fn from(v: &UnaryBooleanSentence) -> Self {
735        Self::Unary(v.clone())
736    }
737}
738
739impl From<UnaryBooleanSentence> for BooleanSentence {
740    fn from(v: UnaryBooleanSentence) -> Self {
741        Self::Unary(v)
742    }
743}
744
745impl From<&BinaryBooleanSentence> for BooleanSentence {
746    fn from(v: &BinaryBooleanSentence) -> Self {
747        Self::Binary(v.clone())
748    }
749}
750
751impl From<BinaryBooleanSentence> for BooleanSentence {
752    fn from(v: BinaryBooleanSentence) -> Self {
753        Self::Binary(v)
754    }
755}
756
757impl BooleanSentence {
758    // --------------------------------------------------------------------------------------------
759    // Variants
760    // --------------------------------------------------------------------------------------------
761
762    pub const fn is_unary(&self) -> bool {
763        matches!(self, Self::Unary(_))
764    }
765
766    pub const fn as_unary(&self) -> Option<&UnaryBooleanSentence> {
767        match self {
768            Self::Unary(v) => Some(v),
769            _ => None,
770        }
771    }
772
773    pub const fn is_binary(&self) -> bool {
774        matches!(self, Self::Binary(_))
775    }
776
777    pub const fn as_binary(&self) -> Option<&BinaryBooleanSentence> {
778        match self {
779            Self::Binary(v) => Some(v),
780            _ => None,
781        }
782    }
783}
784
785// ------------------------------------------------------------------------------------------------
786// Implementations ❱ Constraints ❱ UnaryBooleanSentence
787// ------------------------------------------------------------------------------------------------
788
789impl HasSourceSpan for UnaryBooleanSentence {
790    fn with_source_span(self, span: Span) -> Self {
791        let mut self_mut = self;
792        self_mut.span = Some(span);
793        self_mut
794    }
795
796    fn source_span(&self) -> Option<&Span> {
797        self.span.as_ref()
798    }
799
800    fn set_source_span(&mut self, span: Span) {
801        self.span = Some(span);
802    }
803
804    fn unset_source_span(&mut self) {
805        self.span = None;
806    }
807}
808
809impl UnaryBooleanSentence {
810    // --------------------------------------------------------------------------------------------
811    // Constructors
812    // --------------------------------------------------------------------------------------------
813
814    pub fn new<R>(operand: R) -> Self
815    where
816        R: Into<ConstraintSentence>,
817    {
818        Self {
819            span: Default::default(),
820            operand: Box::new(operand.into()),
821        }
822    }
823
824    #[inline(always)]
825    pub fn negate<R>(operand: R) -> Self
826    where
827        R: Into<ConstraintSentence>,
828    {
829        Self::new(operand)
830    }
831
832    // --------------------------------------------------------------------------------------------
833    // Fields
834    // --------------------------------------------------------------------------------------------
835
836    pub const fn operator(&self) -> ConnectiveOperator {
837        ConnectiveOperator::Negation
838    }
839
840    // --------------------------------------------------------------------------------------------
841
842    pub const fn operand(&self) -> &ConstraintSentence {
843        &self.operand
844    }
845
846    pub fn set_operand(&mut self, operand: ConstraintSentence) {
847        self.operand = Box::new(operand);
848    }
849}
850
851// ------------------------------------------------------------------------------------------------
852// Implementations ❱ Constraints ❱ BinaryBooleanSentence
853// ------------------------------------------------------------------------------------------------
854
855impl HasSourceSpan for BinaryBooleanSentence {
856    fn with_source_span(self, span: Span) -> Self {
857        let mut self_mut = self;
858        self_mut.span = Some(span);
859        self_mut
860    }
861
862    fn source_span(&self) -> Option<&Span> {
863        self.span.as_ref()
864    }
865
866    fn set_source_span(&mut self, span: Span) {
867        self.span = Some(span);
868    }
869
870    fn unset_source_span(&mut self) {
871        self.span = None;
872    }
873}
874
875impl BinaryBooleanSentence {
876    // --------------------------------------------------------------------------------------------
877    // Constructors
878    // --------------------------------------------------------------------------------------------
879
880    pub fn new<L, R>(left_operand: L, operator: ConnectiveOperator, right_operand: R) -> Self
881    where
882        L: Into<ConstraintSentence>,
883        R: Into<ConstraintSentence>,
884    {
885        assert!(operator != ConnectiveOperator::Negation);
886        Self {
887            span: Default::default(),
888            left_operand: Box::new(left_operand.into()),
889            operator,
890            right_operand: Box::new(right_operand.into()),
891        }
892    }
893
894    #[inline(always)]
895    pub fn and<L, R>(left_operand: L, right_operand: R) -> Self
896    where
897        L: Into<ConstraintSentence>,
898        R: Into<ConstraintSentence>,
899    {
900        Self::new(left_operand, ConnectiveOperator::Conjunction, right_operand)
901    }
902
903    #[inline(always)]
904    pub fn or<L, R>(left_operand: L, right_operand: R) -> Self
905    where
906        L: Into<ConstraintSentence>,
907        R: Into<ConstraintSentence>,
908    {
909        Self::new(left_operand, ConnectiveOperator::Disjunction, right_operand)
910    }
911
912    #[inline(always)]
913    pub fn xor<L, R>(left_operand: L, right_operand: R) -> Self
914    where
915        L: Into<ConstraintSentence>,
916        R: Into<ConstraintSentence>,
917    {
918        Self::new(
919            left_operand,
920            ConnectiveOperator::ExclusiveDisjunction,
921            right_operand,
922        )
923    }
924
925    #[inline(always)]
926    pub fn implies<L, R>(left_operand: L, right_operand: R) -> Self
927    where
928        L: Into<ConstraintSentence>,
929        R: Into<ConstraintSentence>,
930    {
931        Self::new(left_operand, ConnectiveOperator::Implication, right_operand)
932    }
933
934    #[inline(always)]
935    pub fn iff<L, R>(left_operand: L, right_operand: R) -> Self
936    where
937        L: Into<ConstraintSentence>,
938        R: Into<ConstraintSentence>,
939    {
940        Self::new(
941            left_operand,
942            ConnectiveOperator::Biconditional,
943            right_operand,
944        )
945    }
946
947    // --------------------------------------------------------------------------------------------
948    // Fields
949    // --------------------------------------------------------------------------------------------
950
951    pub const fn left_operand(&self) -> &ConstraintSentence {
952        &self.left_operand
953    }
954
955    pub fn set_left_operand(&mut self, left_operand: ConstraintSentence) {
956        self.left_operand = Box::new(left_operand);
957    }
958
959    // --------------------------------------------------------------------------------------------
960
961    pub const fn operator(&self) -> &ConnectiveOperator {
962        &self.operator
963    }
964
965    pub fn set_operator(&mut self, operator: ConnectiveOperator) {
966        self.operator = operator;
967    }
968
969    // --------------------------------------------------------------------------------------------
970
971    pub const fn right_operand(&self) -> &ConstraintSentence {
972        &self.right_operand
973    }
974
975    pub fn set_right_operand(&mut self, right_operand: ConstraintSentence) {
976        self.right_operand = Box::new(right_operand);
977    }
978}
979
980// ------------------------------------------------------------------------------------------------
981// Implementations ❱ Constraints ❱ ConnectiveOperator
982// ------------------------------------------------------------------------------------------------
983
984impl Display for ConnectiveOperator {
985    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
986        write!(
987            f,
988            "{}",
989            match (self, f.alternate()) {
990                (ConnectiveOperator::Negation, true) => KW_OPERATION_NEGATION,
991                (ConnectiveOperator::Negation, false) => KW_OPERATION_NEGATION_SYMBOL,
992                (ConnectiveOperator::Conjunction, true) => KW_OPERATION_CONJUNCTION,
993                (ConnectiveOperator::Conjunction, false) => KW_OPERATION_CONJUNCTION_SYMBOL,
994                (ConnectiveOperator::Disjunction, true) => KW_OPERATION_DISJUNCTION,
995                (ConnectiveOperator::Disjunction, false) => KW_OPERATION_DISJUNCTION_SYMBOL,
996                (ConnectiveOperator::ExclusiveDisjunction, true) =>
997                    KW_OPERATION_EXCLUSIVE_DISJUNCTION,
998                (ConnectiveOperator::ExclusiveDisjunction, false) =>
999                    KW_OPERATION_EXCLUSIVE_DISJUNCTION_SYMBOL,
1000                (ConnectiveOperator::Implication, true) => KW_OPERATION_IMPLICATION,
1001                (ConnectiveOperator::Implication, false) => KW_OPERATION_IMPLICATION_SYMBOL,
1002                (ConnectiveOperator::Biconditional, true) => KW_OPERATION_BICONDITIONAL,
1003                (ConnectiveOperator::Biconditional, false) => KW_OPERATION_BICONDITIONAL_SYMBOL,
1004            }
1005        )
1006    }
1007}
1008
1009// ------------------------------------------------------------------------------------------------
1010// Implementations ❱ Constraints ❱ QuantifiedSentence
1011// ------------------------------------------------------------------------------------------------
1012
1013impl HasBody for QuantifiedSentence {
1014    type Body = ConstraintSentence;
1015
1016    fn body(&self) -> &Self::Body {
1017        &self.body
1018    }
1019
1020    fn body_mut(&mut self) -> &mut Self::Body {
1021        &mut self.body
1022    }
1023
1024    fn set_body(&mut self, body: Self::Body) {
1025        self.body = Box::new(body);
1026    }
1027}
1028
1029impl HasSourceSpan for QuantifiedSentence {
1030    fn with_source_span(self, span: Span) -> Self {
1031        let mut self_mut = self;
1032        self_mut.span = Some(span);
1033        self_mut
1034    }
1035
1036    fn source_span(&self) -> Option<&Span> {
1037        self.span.as_ref()
1038    }
1039
1040    fn set_source_span(&mut self, span: Span) {
1041        self.span = Some(span);
1042    }
1043
1044    fn unset_source_span(&mut self) {
1045        self.span = None;
1046    }
1047}
1048
1049impl QuantifiedSentence {
1050    // --------------------------------------------------------------------------------------------
1051    // Constructors
1052    // --------------------------------------------------------------------------------------------
1053
1054    pub fn new<S>(binding: QuantifiedVariableBinding, body: S) -> Self
1055    where
1056        S: Into<ConstraintSentence>,
1057    {
1058        Self {
1059            span: Default::default(),
1060            binding,
1061            body: Box::new(body.into()),
1062        }
1063    }
1064
1065    // --------------------------------------------------------------------------------------------
1066    // Fields
1067    // --------------------------------------------------------------------------------------------
1068
1069    pub const fn binding(&self) -> &QuantifiedVariableBinding {
1070        &self.binding
1071    }
1072
1073    pub fn set_binding(&mut self, binding: QuantifiedVariableBinding) {
1074        self.binding = binding;
1075    }
1076}
1077
1078// ------------------------------------------------------------------------------------------------
1079// Implementations ❱ Constraints ❱ Quantifier
1080// ------------------------------------------------------------------------------------------------
1081
1082impl Default for Quantifier {
1083    fn default() -> Self {
1084        Self::Universal
1085    }
1086}
1087
1088impl Display for Quantifier {
1089    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1090        write!(
1091            f,
1092            "{}",
1093            match (self, f.alternate()) {
1094                (Self::Existential, true) => KW_QUANTIFIER_EXISTS_SYMBOL,
1095                (Self::Existential, false) => KW_QUANTIFIER_EXISTS,
1096                (Self::Universal, true) => KW_QUANTIFIER_FORALL,
1097                (Self::Universal, false) => KW_QUANTIFIER_FORALL_SYMBOL,
1098            }
1099        )
1100    }
1101}
1102
1103impl FromStr for Quantifier {
1104    type Err = Error;
1105
1106    fn from_str(s: &str) -> Result<Self, Self::Err> {
1107        match s {
1108            KW_QUANTIFIER_EXISTS => Ok(Self::Existential),
1109            KW_QUANTIFIER_EXISTS_SYMBOL => Ok(Self::Existential),
1110            KW_QUANTIFIER_FORALL => Ok(Self::Universal),
1111            KW_QUANTIFIER_FORALL_SYMBOL => Ok(Self::Universal),
1112            // TODO: need an error here.
1113            _ => panic!("Invalid Quantifier value {:?}", s),
1114        }
1115    }
1116}
1117
1118// ------------------------------------------------------------------------------------------------
1119// Implementations ❱ Constraints ❱ QuantifiedVariableBinding
1120// ------------------------------------------------------------------------------------------------
1121
1122impl HasSourceSpan for QuantifiedVariableBinding {
1123    fn with_source_span(self, span: Span) -> Self {
1124        let mut self_mut = self;
1125        self_mut.span = Some(span);
1126        self_mut
1127    }
1128
1129    fn source_span(&self) -> Option<&Span> {
1130        self.span.as_ref()
1131    }
1132
1133    fn set_source_span(&mut self, span: Span) {
1134        self.span = Some(span);
1135    }
1136
1137    fn unset_source_span(&mut self) {
1138        self.span = None;
1139    }
1140}
1141
1142impl QuantifiedVariableBinding {
1143    // --------------------------------------------------------------------------------------------
1144    // Constructors
1145    // --------------------------------------------------------------------------------------------
1146
1147    pub fn new(quantifier: Quantifier, binding: QuantifiedVariable) -> Self {
1148        Self {
1149            span: Default::default(),
1150            quantifier,
1151            binding: Some(binding),
1152        }
1153    }
1154
1155    pub fn new_self(quantifier: Quantifier) -> Self {
1156        Self {
1157            span: Default::default(),
1158            quantifier,
1159            binding: None,
1160        }
1161    }
1162
1163    pub fn new_existential(binding: QuantifiedVariable) -> Self {
1164        Self::new(Quantifier::Existential, binding)
1165    }
1166
1167    pub fn new_universal(binding: QuantifiedVariable) -> Self {
1168        Self::new(Quantifier::Universal, binding)
1169    }
1170
1171    // --------------------------------------------------------------------------------------------
1172    // Fields
1173    // --------------------------------------------------------------------------------------------
1174
1175    pub const fn quantifier(&self) -> &Quantifier {
1176        &self.quantifier
1177    }
1178
1179    pub fn set_quantifier(&mut self, quantifier: Quantifier) {
1180        self.quantifier = quantifier;
1181    }
1182
1183    #[inline(always)]
1184    pub fn is_existential(&self) -> bool {
1185        self.quantifier == Quantifier::Existential
1186    }
1187
1188    #[inline(always)]
1189    pub fn is_universal(&self) -> bool {
1190        self.quantifier == Quantifier::Universal
1191    }
1192
1193    // --------------------------------------------------------------------------------------------
1194
1195    pub fn binding(&self) -> Option<&QuantifiedVariable> {
1196        self.binding.as_ref()
1197    }
1198
1199    pub fn is_bound_to_variable(&self) -> bool {
1200        self.binding.is_some()
1201    }
1202
1203    pub fn set_binding_to_variable(&mut self, binding: QuantifiedVariable) {
1204        self.binding = Some(binding);
1205    }
1206
1207    pub fn is_bound_to_self(&self) -> bool {
1208        self.binding.is_none()
1209    }
1210
1211    pub fn set_binding_to_self(&mut self) {
1212        self.binding = None;
1213    }
1214}
1215
1216// ------------------------------------------------------------------------------------------------
1217// Implementations ❱ Constraints ❱ QuantifiedVariable
1218// ------------------------------------------------------------------------------------------------
1219
1220impl HasName for QuantifiedVariable {
1221    fn name(&self) -> &Identifier {
1222        &self.name
1223    }
1224
1225    fn set_name(&mut self, name: Identifier) {
1226        self.name = name;
1227    }
1228}
1229
1230impl HasSourceSpan for QuantifiedVariable {
1231    fn with_source_span(self, span: Span) -> Self {
1232        let mut self_mut = self;
1233        self_mut.span = Some(span);
1234        self_mut
1235    }
1236
1237    fn source_span(&self) -> Option<&Span> {
1238        self.span.as_ref()
1239    }
1240
1241    fn set_source_span(&mut self, span: Span) {
1242        self.span = Some(span);
1243    }
1244
1245    fn unset_source_span(&mut self) {
1246        self.span = None;
1247    }
1248}
1249
1250impl QuantifiedVariable {
1251    // --------------------------------------------------------------------------------------------
1252    // Constructors
1253    // --------------------------------------------------------------------------------------------
1254
1255    pub fn new<T>(name: Identifier, source: T) -> Self
1256    where
1257        T: Into<Term>,
1258    {
1259        Self {
1260            span: Default::default(),
1261            name,
1262            source: source.into(),
1263        }
1264    }
1265
1266    // --------------------------------------------------------------------------------------------
1267    // Fields
1268    // --------------------------------------------------------------------------------------------
1269
1270    pub const fn source(&self) -> &Term {
1271        &self.source
1272    }
1273
1274    pub fn set_source<T>(&mut self, source: T)
1275    where
1276        T: Into<Term>,
1277    {
1278        self.source = source.into();
1279    }
1280}