sdml_core/model/constraints/
mod.rs1use crate::{
6 load::ModuleLoader,
7 model::{
8 check::Validate, modules::Module, HasBody, HasName, HasSourceSpan, Identifier,
9 IdentifierReference, References, Span,
10 },
11 store::ModuleStore,
12};
13use std::collections::BTreeSet;
14
15#[cfg(feature = "serde")]
16use serde::{Deserialize, Serialize};
17
18#[derive(Clone, Debug)]
24#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
25pub struct Constraint {
26 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
27 span: Option<Span>,
28 name: Identifier,
29 body: ConstraintBody,
30}
31
32#[derive(Clone, Debug)]
41#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
42pub enum ConstraintBody {
43 Informal(ControlledLanguageString),
45 Formal(FormalConstraint),
47}
48
49impl HasName for Constraint {
54 fn name(&self) -> &Identifier {
55 &self.name
56 }
57
58 fn set_name(&mut self, name: Identifier) {
59 self.name = name;
60 }
61}
62
63impl HasBody for Constraint {
64 type Body = ConstraintBody;
65
66 fn body(&self) -> &Self::Body {
67 &self.body
68 }
69
70 fn body_mut(&mut self) -> &mut Self::Body {
71 &mut self.body
72 }
73
74 fn set_body(&mut self, body: Self::Body) {
75 self.body = body;
76 }
77}
78
79impl HasSourceSpan for Constraint {
80 fn with_source_span(self, span: Span) -> Self {
81 let mut self_mut = self;
82 self_mut.span = Some(span);
83 self_mut
84 }
85
86 fn source_span(&self) -> Option<&Span> {
87 self.span.as_ref()
88 }
89
90 fn set_source_span(&mut self, span: Span) {
91 self.span = Some(span);
92 }
93
94 fn unset_source_span(&mut self) {
95 self.span = None;
96 }
97}
98
99impl References for Constraint {
100 fn referenced_annotations<'a>(&'a self, names: &mut BTreeSet<&'a IdentifierReference>) {
101 self.body.referenced_annotations(names);
102 }
103
104 fn referenced_types<'a>(&'a self, names: &mut BTreeSet<&'a IdentifierReference>) {
105 self.body.referenced_types(names);
106 }
107}
108
109impl Validate for Constraint {
110 fn validate(
111 &self,
112 top: &Module,
113 cache: &impl ModuleStore,
114 loader: &impl ModuleLoader,
115 check_constraints: bool,
116 ) {
117 self.body.validate(top, cache, loader, check_constraints)
118 }
119}
120
121impl Constraint {
122 pub fn new<B>(name: Identifier, body: B) -> Self
127 where
128 B: Into<ConstraintBody>,
129 {
130 Self {
131 span: None,
132 name,
133 body: body.into(),
134 }
135 }
136}
137
138impl From<&ControlledLanguageString> for ConstraintBody {
143 fn from(v: &ControlledLanguageString) -> Self {
144 Self::Informal(v.clone())
145 }
146}
147
148impl From<ControlledLanguageString> for ConstraintBody {
149 fn from(v: ControlledLanguageString) -> Self {
150 Self::Informal(v)
151 }
152}
153
154impl From<&FormalConstraint> for ConstraintBody {
155 fn from(v: &FormalConstraint) -> Self {
156 Self::Formal(v.clone())
157 }
158}
159
160impl From<FormalConstraint> for ConstraintBody {
161 fn from(v: FormalConstraint) -> Self {
162 Self::Formal(v)
163 }
164}
165
166impl References for ConstraintBody {
167 fn referenced_annotations<'a>(&'a self, names: &mut BTreeSet<&'a IdentifierReference>) {
168 match self {
169 Self::Informal(v) => v.referenced_annotations(names),
170 Self::Formal(v) => v.referenced_annotations(names),
171 }
172 }
173
174 fn referenced_types<'a>(&'a self, names: &mut BTreeSet<&'a IdentifierReference>) {
175 match self {
176 Self::Informal(v) => v.referenced_types(names),
177 Self::Formal(v) => v.referenced_types(names),
178 }
179 }
180}
181
182impl Validate for ConstraintBody {
183 fn validate(
184 &self,
185 top: &Module,
186 cache: &impl ModuleStore,
187 loader: &impl ModuleLoader,
188 check_constraints: bool,
189 ) {
190 match self {
191 Self::Informal(v) => v.validate(top, cache, loader, check_constraints),
192 Self::Formal(v) => v.validate(top, cache, loader, check_constraints),
193 }
194 }
195}
196
197impl ConstraintBody {
198 pub const fn is_informal(&self) -> bool {
203 matches!(self, Self::Informal(_))
204 }
205
206 pub const fn as_informal(&self) -> Option<&ControlledLanguageString> {
207 match self {
208 Self::Informal(v) => Some(v),
209 _ => None,
210 }
211 }
212
213 pub const fn is_formal(&self) -> bool {
214 matches!(self, Self::Formal(_))
215 }
216
217 pub const fn as_formal(&self) -> Option<&FormalConstraint> {
218 match self {
219 Self::Formal(v) => Some(v),
220 _ => None,
221 }
222 }
223}
224
225mod formal;
230pub use formal::{
231 AtomicSentence, BinaryBooleanSentence, BooleanSentence, ConnectiveOperator, ConstraintSentence,
232 Equation, FormalConstraint, FunctionBody, FunctionCardinality, FunctionComposition,
233 FunctionDef, FunctionParameter, FunctionSignature, FunctionType, FunctionTypeReference,
234 FunctionalTerm, InequalityRelation, Inequation, PredicateSequenceMember, PredicateValue,
235 QuantifiedSentence, QuantifiedVariable, QuantifiedVariableBinding, Quantifier, SequenceBuilder,
236 SequenceOfPredicateValues, SimpleSentence, Subject, Term, UnaryBooleanSentence, Variable,
237};
238
239mod informal;
240pub use informal::{ControlledLanguageString, ControlledLanguageTag};