sdml_core/model/constraints/formal/
functions.rs

1use crate::{
2    load::ModuleLoader,
3    model::{
4        check::Validate,
5        constraints::{
6            BooleanSentence, ConstraintSentence, FunctionComposition, FunctionalTerm,
7            PredicateValue, QuantifiedSentence, SequenceBuilder, SimpleSentence, Term,
8        },
9        identifiers::{Identifier, IdentifierReference},
10        members::{CardinalityRange, MappingType, Ordering, Uniqueness},
11        modules::Module,
12        HasBody, HasName, HasSourceSpan, Span,
13    },
14    store::ModuleStore,
15    syntax::KW_WILDCARD,
16};
17use std::fmt::Display;
18
19#[cfg(feature = "serde")]
20use serde::{Deserialize, Serialize};
21
22// ------------------------------------------------------------------------------------------------
23// Public Types ❱ Constraints ❱ Functions
24// ------------------------------------------------------------------------------------------------
25
26#[derive(Clone, Debug)]
27#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
28pub struct FunctionDef {
29    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
30    span: Option<Span>,
31    signature: FunctionSignature,
32    body: FunctionBody,
33}
34
35#[derive(Clone, Debug)]
36#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
37pub struct FunctionSignature {
38    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
39    span: Option<Span>,
40    name: Identifier,
41    parameters: Vec<FunctionParameter>,
42    target_type: FunctionType,
43}
44
45#[derive(Clone, Debug)]
46#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
47pub struct FunctionParameter {
48    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
49    span: Option<Span>,
50    name: Identifier,
51    target_type: FunctionType,
52}
53
54#[derive(Clone, Debug)]
55#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
56pub struct FunctionType {
57    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
58    span: Option<Span>,
59    target_cardinality: FunctionCardinality,
60    target_type: FunctionTypeReference,
61}
62
63/// Corresponds to the grammar rule `cardinality`.
64#[derive(Clone, Debug, Default, PartialEq, Eq)]
65#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
66pub struct FunctionCardinality {
67    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
68    span: Option<Span>,
69    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
70    ordering: Option<Ordering>,
71    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
72    uniqueness: Option<Uniqueness>,
73    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
74    range: Option<CardinalityRange>,
75}
76
77#[derive(Clone, Debug)]
78#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
79pub enum FunctionTypeReference {
80    Wildcard,
81    Reference(IdentifierReference),
82    // builtin_simple_type is converted into a reference
83    MappingType(MappingType),
84}
85
86#[derive(Clone, Debug)]
87#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
88pub enum FunctionBody {
89    Sentence(ConstraintSentence),
90    Term(Term),
91}
92
93// ------------------------------------------------------------------------------------------------
94// Implementations ❱ Constraints ❱ FunctionDef
95// ------------------------------------------------------------------------------------------------
96
97impl HasBody for FunctionDef {
98    type Body = FunctionBody;
99
100    fn body(&self) -> &Self::Body {
101        &self.body
102    }
103
104    fn body_mut(&mut self) -> &mut Self::Body {
105        &mut self.body
106    }
107
108    fn set_body(&mut self, body: Self::Body) {
109        self.body = body;
110    }
111}
112
113impl HasSourceSpan for FunctionDef {
114    fn with_source_span(self, span: Span) -> Self {
115        let mut self_mut = self;
116        self_mut.span = Some(span);
117        self_mut
118    }
119
120    fn source_span(&self) -> Option<&Span> {
121        self.span.as_ref()
122    }
123
124    fn set_source_span(&mut self, span: Span) {
125        self.span = Some(span);
126    }
127
128    fn unset_source_span(&mut self) {
129        self.span = None;
130    }
131}
132
133impl FunctionDef {
134    // --------------------------------------------------------------------------------------------
135    // Constructors
136    // --------------------------------------------------------------------------------------------
137
138    pub fn new<T>(signature: FunctionSignature, body: T) -> Self
139    where
140        T: Into<FunctionBody>,
141    {
142        Self {
143            span: None,
144            signature,
145            body: body.into(),
146        }
147    }
148
149    // --------------------------------------------------------------------------------------------
150    // Fields
151    // --------------------------------------------------------------------------------------------
152
153    pub fn name(&self) -> &Identifier {
154        self.signature.name()
155    }
156
157    pub const fn signature(&self) -> &FunctionSignature {
158        &self.signature
159    }
160
161    pub fn set_signature(&mut self, signature: FunctionSignature) {
162        self.signature = signature;
163    }
164}
165
166// ------------------------------------------------------------------------------------------------
167// Implementations ❱ Constraints ❱ FunctionSignature
168// ------------------------------------------------------------------------------------------------
169
170impl HasName for FunctionSignature {
171    fn name(&self) -> &Identifier {
172        &self.name
173    }
174
175    fn set_name(&mut self, name: Identifier) {
176        self.name = name;
177    }
178}
179
180impl HasSourceSpan for FunctionSignature {
181    fn with_source_span(self, span: Span) -> Self {
182        let mut self_mut = self;
183        self_mut.span = Some(span);
184        self_mut
185    }
186
187    fn source_span(&self) -> Option<&Span> {
188        self.span.as_ref()
189    }
190
191    fn set_source_span(&mut self, span: Span) {
192        self.span = Some(span);
193    }
194
195    fn unset_source_span(&mut self) {
196        self.span = None;
197    }
198}
199
200impl FunctionSignature {
201    // --------------------------------------------------------------------------------------------
202    // Constructors
203    // --------------------------------------------------------------------------------------------
204
205    pub fn new(
206        name: Identifier,
207        parameters: Vec<FunctionParameter>,
208        target_type: FunctionType,
209    ) -> Self {
210        Self::named(name, target_type).with_parameters(parameters)
211    }
212
213    pub fn named(name: Identifier, target_type: FunctionType) -> Self {
214        Self {
215            span: Default::default(),
216            name,
217            parameters: Default::default(),
218            target_type,
219        }
220    }
221
222    pub fn with_parameters<I>(self, parameters: I) -> Self
223    where
224        I: IntoIterator<Item = FunctionParameter>,
225    {
226        let mut self_mut = self;
227        self_mut.extend_parameters(parameters);
228        self_mut
229    }
230
231    // --------------------------------------------------------------------------------------------
232    // Fields
233    // --------------------------------------------------------------------------------------------
234
235    pub fn has_parameters(&self) -> bool {
236        !self.parameters.is_empty()
237    }
238
239    pub fn parameters_len(&self) -> usize {
240        self.parameters.len()
241    }
242
243    pub fn parameters(&self) -> impl Iterator<Item = &FunctionParameter> {
244        self.parameters.iter()
245    }
246
247    pub fn parameters_mut(&mut self) -> impl Iterator<Item = &mut FunctionParameter> {
248        self.parameters.iter_mut()
249    }
250
251    pub fn add_to_parameters<I>(&mut self, value: I)
252    where
253        I: Into<FunctionParameter>,
254    {
255        self.parameters.push(value.into())
256    }
257
258    pub fn extend_parameters<I>(&mut self, extension: I)
259    where
260        I: IntoIterator<Item = FunctionParameter>,
261    {
262        self.parameters.extend(extension)
263    }
264
265    // --------------------------------------------------------------------------------------------
266
267    pub const fn target_type(&self) -> &FunctionType {
268        &self.target_type
269    }
270
271    pub fn set_target_type(&mut self, target_type: FunctionType) {
272        self.target_type = target_type;
273    }
274}
275
276// ------------------------------------------------------------------------------------------------
277// Implementations ❱ Constraints ❱ FunctionParameter
278// ------------------------------------------------------------------------------------------------
279
280impl HasName for FunctionParameter {
281    fn name(&self) -> &Identifier {
282        &self.name
283    }
284
285    fn set_name(&mut self, name: Identifier) {
286        self.name = name;
287    }
288}
289
290impl HasSourceSpan for FunctionParameter {
291    fn with_source_span(self, span: Span) -> Self {
292        let mut self_mut = self;
293        self_mut.span = Some(span);
294        self_mut
295    }
296
297    fn source_span(&self) -> Option<&Span> {
298        self.span.as_ref()
299    }
300
301    fn set_source_span(&mut self, span: Span) {
302        self.span = Some(span);
303    }
304
305    fn unset_source_span(&mut self) {
306        self.span = None;
307    }
308}
309
310impl FunctionParameter {
311    // --------------------------------------------------------------------------------------------
312    // Constructors
313    // --------------------------------------------------------------------------------------------
314
315    pub const fn new(name: Identifier, target_type: FunctionType) -> Self {
316        Self {
317            span: None,
318            name,
319            target_type,
320        }
321    }
322
323    // --------------------------------------------------------------------------------------------
324    // Fields
325    // --------------------------------------------------------------------------------------------
326
327    pub const fn target_type(&self) -> &FunctionType {
328        &self.target_type
329    }
330
331    pub fn set_target_type(&mut self, target_type: FunctionType) {
332        self.target_type = target_type;
333    }
334}
335
336// ------------------------------------------------------------------------------------------------
337// Implementations ❱ Constraints ❱ FunctionType
338// ------------------------------------------------------------------------------------------------
339
340impl HasSourceSpan for FunctionType {
341    fn with_source_span(self, span: Span) -> Self {
342        let mut self_mut = self;
343        self_mut.span = Some(span);
344        self_mut
345    }
346
347    fn source_span(&self) -> Option<&Span> {
348        self.span.as_ref()
349    }
350
351    fn set_source_span(&mut self, span: Span) {
352        self.span = Some(span);
353    }
354
355    fn unset_source_span(&mut self) {
356        self.span = None;
357    }
358}
359
360impl FunctionType {
361    // --------------------------------------------------------------------------------------------
362    // Constructors
363    // --------------------------------------------------------------------------------------------
364
365    pub fn new(
366        target_cardinality: FunctionCardinality,
367        target_type: FunctionTypeReference,
368    ) -> Self {
369        Self {
370            span: Default::default(),
371            target_cardinality,
372            target_type,
373        }
374    }
375
376    pub fn with_wildcard_cardinality(self) -> Self {
377        let mut self_mut = self;
378        self_mut.target_cardinality = FunctionCardinality::new_wildcard();
379        self_mut
380    }
381
382    pub fn with_target_cardinality(self, target_cardinality: FunctionCardinality) -> Self {
383        let mut self_mut = self;
384        self_mut.target_cardinality = target_cardinality;
385        self_mut
386    }
387
388    pub fn with_target_type(self, target_type: FunctionTypeReference) -> Self {
389        let mut self_mut = self;
390        self_mut.target_type = target_type;
391        self_mut
392    }
393
394    // --------------------------------------------------------------------------------------------
395    // Fields
396    // --------------------------------------------------------------------------------------------
397
398    pub const fn target_cardinality(&self) -> &FunctionCardinality {
399        &self.target_cardinality
400    }
401
402    pub fn set_target_cardinality(&mut self, target_cardinality: FunctionCardinality) {
403        self.target_cardinality = target_cardinality;
404    }
405
406    // --------------------------------------------------------------------------------------------
407
408    pub const fn target_type(&self) -> &FunctionTypeReference {
409        &self.target_type
410    }
411
412    pub fn set_target_type(&mut self, target_type: FunctionTypeReference) {
413        self.target_type = target_type;
414    }
415}
416
417// ------------------------------------------------------------------------------------------------
418// Implementations ❱ Constraints ❱ FunctionCardinality
419// ------------------------------------------------------------------------------------------------
420
421impl Display for FunctionCardinality {
422    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
423        write!(
424            f,
425            "{{{}{}{}}}",
426            self.ordering.map(|c| format!("{} ", c)).unwrap_or_default(),
427            self.uniqueness
428                .map(|c| format!("{} ", c))
429                .unwrap_or_default(),
430            if let Some(range) = &self.range {
431                range.to_string()
432            } else {
433                KW_WILDCARD.to_string()
434            }
435        )
436    }
437}
438
439impl HasSourceSpan for FunctionCardinality {
440    fn with_source_span(self, span: Span) -> Self {
441        let mut self_mut = self;
442        self_mut.span = Some(span);
443        self_mut
444    }
445
446    fn source_span(&self) -> Option<&Span> {
447        self.span.as_ref()
448    }
449
450    fn set_source_span(&mut self, span: Span) {
451        self.span = Some(span);
452    }
453
454    fn unset_source_span(&mut self) {
455        self.span = None;
456    }
457}
458
459impl Validate for FunctionCardinality {
460    fn validate(
461        &self,
462        _top: &Module,
463        _cache: &impl ModuleStore,
464        _loader: &impl ModuleLoader,
465        _check_constraints: bool,
466    ) {
467        todo!()
468    }
469}
470
471impl FunctionCardinality {
472    // --------------------------------------------------------------------------------------------
473    // Constructors
474    // --------------------------------------------------------------------------------------------
475
476    pub const fn new(
477        ordering: Option<Ordering>,
478        uniqueness: Option<Uniqueness>,
479        range: Option<CardinalityRange>,
480    ) -> Self {
481        Self {
482            span: None,
483            ordering,
484            uniqueness,
485            range,
486        }
487    }
488
489    pub const fn new_range(min: u32, max: u32) -> Self {
490        Self {
491            span: None,
492            ordering: None,
493            uniqueness: None,
494            range: Some(CardinalityRange::new_range(min, max)),
495        }
496    }
497
498    pub const fn new_unbounded(min: u32) -> Self {
499        Self {
500            span: None,
501            ordering: None,
502            uniqueness: None,
503            range: Some(CardinalityRange::new_unbounded(min)),
504        }
505    }
506
507    pub const fn new_single(min_and_max: u32) -> Self {
508        Self {
509            span: None,
510            ordering: None,
511            uniqueness: None,
512            range: Some(CardinalityRange::new_single(min_and_max)),
513        }
514    }
515
516    pub const fn new_wildcard() -> Self {
517        Self {
518            span: None,
519            ordering: None,
520            uniqueness: None,
521            range: None,
522        }
523    }
524
525    #[inline(always)]
526    pub const fn one() -> Self {
527        Self::new_single(1)
528    }
529
530    #[inline(always)]
531    pub const fn zero_or_one() -> Self {
532        Self::new_range(0, 1)
533    }
534
535    #[inline(always)]
536    pub const fn one_or_more() -> Self {
537        Self::new_unbounded(1)
538    }
539
540    #[inline(always)]
541    pub const fn zero_or_more() -> Self {
542        Self::new_unbounded(0)
543    }
544
545    pub const fn with_uniqueness(self, uniqueness: Uniqueness) -> Self {
546        let mut self_mut = self;
547        self_mut.uniqueness = Some(uniqueness);
548        self_mut
549    }
550
551    pub const fn with_ordering(self, ordering: Ordering) -> Self {
552        let mut self_mut = self;
553        self_mut.ordering = Some(ordering);
554        self_mut
555    }
556
557    // --------------------------------------------------------------------------------------------
558    // Fields
559    // --------------------------------------------------------------------------------------------
560
561    pub const fn has_ordering(&self) -> bool {
562        self.ordering.is_some()
563    }
564
565    pub const fn ordering(&self) -> Option<Ordering> {
566        self.ordering
567    }
568
569    pub fn set_ordering(&mut self, ordering: Ordering) {
570        self.ordering = Some(ordering);
571    }
572
573    pub fn unset_ordering(&mut self) {
574        self.ordering = None;
575    }
576
577    #[inline(always)]
578    pub fn is_ordered(&self) -> Option<bool> {
579        self.ordering().map(|o| o == Ordering::Ordered)
580    }
581
582    // --------------------------------------------------------------------------------------------
583
584    pub const fn has_uniqueness(&self) -> bool {
585        self.uniqueness.is_some()
586    }
587
588    pub const fn uniqueness(&self) -> Option<Uniqueness> {
589        self.uniqueness
590    }
591
592    pub fn set_uniqueness(&mut self, uniqueness: Uniqueness) {
593        self.uniqueness = Some(uniqueness);
594    }
595
596    pub fn unset_uniqueness(&mut self) {
597        self.uniqueness = None;
598    }
599
600    #[inline(always)]
601    pub fn is_unique(&self) -> Option<bool> {
602        self.uniqueness().map(|u| u == Uniqueness::Unique)
603    }
604
605    // --------------------------------------------------------------------------------------------
606
607    pub const fn has_range(&self) -> bool {
608        self.range.is_some()
609    }
610
611    pub const fn range(&self) -> Option<&CardinalityRange> {
612        self.range.as_ref()
613    }
614
615    pub fn set_range(&mut self, range: CardinalityRange) {
616        self.range = Some(range);
617    }
618
619    pub fn unset_range(&mut self) {
620        self.range = None;
621    }
622
623    // --------------------------------------------------------------------------------------------
624
625    #[inline(always)]
626    pub fn is_default(&self) -> bool {
627        self.ordering.is_none() && self.uniqueness.is_none() && self.range.is_none()
628    }
629
630    pub fn is_wildcard(&self) -> bool {
631        self.range.is_none()
632    }
633}
634
635// ------------------------------------------------------------------------------------------------
636// Implementations ❱ Constraints ❱ FunctionTypeReference
637// ------------------------------------------------------------------------------------------------
638
639impl From<&IdentifierReference> for FunctionTypeReference {
640    fn from(value: &IdentifierReference) -> Self {
641        Self::Reference(value.clone())
642    }
643}
644
645impl From<IdentifierReference> for FunctionTypeReference {
646    fn from(value: IdentifierReference) -> Self {
647        Self::Reference(value)
648    }
649}
650
651impl From<&MappingType> for FunctionTypeReference {
652    fn from(value: &MappingType) -> Self {
653        Self::MappingType(value.clone())
654    }
655}
656
657impl From<MappingType> for FunctionTypeReference {
658    fn from(value: MappingType) -> Self {
659        Self::MappingType(value)
660    }
661}
662
663impl FunctionTypeReference {
664    // --------------------------------------------------------------------------------------------
665    // Variants
666    // --------------------------------------------------------------------------------------------
667
668    pub const fn is_reference(&self) -> bool {
669        matches!(self, Self::Reference(_))
670    }
671
672    pub const fn as_reference(&self) -> Option<&IdentifierReference> {
673        match self {
674            Self::Reference(v) => Some(v),
675            _ => None,
676        }
677    }
678
679    // --------------------------------------------------------------------------------------------
680
681    pub const fn is_mapping_type(&self) -> bool {
682        matches!(self, Self::MappingType(_))
683    }
684
685    pub const fn as_mapping_type(&self) -> Option<&MappingType> {
686        match self {
687            Self::MappingType(v) => Some(v),
688            _ => None,
689        }
690    }
691
692    // --------------------------------------------------------------------------------------------
693
694    pub const fn is_wildcard(&self) -> bool {
695        matches!(self, Self::Wildcard)
696    }
697}
698
699// ------------------------------------------------------------------------------------------------
700// Implementations ❱ Constraints ❱ FunctionBody
701// ------------------------------------------------------------------------------------------------
702
703impl From<ConstraintSentence> for FunctionBody {
704    fn from(value: ConstraintSentence) -> FunctionBody {
705        FunctionBody::Sentence(value)
706    }
707}
708
709impl From<SimpleSentence> for FunctionBody {
710    fn from(value: SimpleSentence) -> FunctionBody {
711        FunctionBody::Sentence(value.into())
712    }
713}
714
715impl From<BooleanSentence> for FunctionBody {
716    fn from(value: BooleanSentence) -> FunctionBody {
717        FunctionBody::Sentence(value.into())
718    }
719}
720
721impl From<QuantifiedSentence> for FunctionBody {
722    fn from(value: QuantifiedSentence) -> FunctionBody {
723        FunctionBody::Sentence(value.into())
724    }
725}
726
727impl From<Term> for FunctionBody {
728    fn from(value: Term) -> FunctionBody {
729        FunctionBody::Term(value)
730    }
731}
732
733impl From<SequenceBuilder> for FunctionBody {
734    fn from(value: SequenceBuilder) -> FunctionBody {
735        FunctionBody::Term(Box::new(value).into())
736    }
737}
738
739impl From<FunctionalTerm> for FunctionBody {
740    fn from(value: FunctionalTerm) -> FunctionBody {
741        FunctionBody::Term(Box::new(value).into())
742    }
743}
744
745impl From<FunctionComposition> for FunctionBody {
746    fn from(value: FunctionComposition) -> FunctionBody {
747        FunctionBody::Term(value.into())
748    }
749}
750
751impl From<IdentifierReference> for FunctionBody {
752    fn from(value: IdentifierReference) -> FunctionBody {
753        FunctionBody::Term(value.into())
754    }
755}
756
757impl From<PredicateValue> for FunctionBody {
758    fn from(value: PredicateValue) -> FunctionBody {
759        FunctionBody::Term(value.into())
760    }
761}
762
763impl FunctionBody {
764    pub fn is_sentence(&self) -> bool {
765        matches!(self, Self::Sentence(_))
766    }
767
768    pub fn as_sentence(&self) -> Option<&ConstraintSentence> {
769        match &self {
770            Self::Sentence(value) => Some(value),
771            _ => None,
772        }
773    }
774
775    pub fn is_term(&self) -> bool {
776        matches!(self, Self::Term(_))
777    }
778
779    pub fn as_term(&self) -> Option<&Term> {
780        match &self {
781            Self::Term(value) => Some(value),
782            _ => None,
783        }
784    }
785}