use crate::{
load::ModuleLoader,
model::{
check::Validate, modules::Module, HasBody, HasName, HasSourceSpan, Identifier,
IdentifierReference, References, Span,
},
store::ModuleStore,
};
use std::collections::BTreeSet;
#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};
#[derive(Clone, Debug)]
#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
pub struct Constraint {
#[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
span: Option<Span>,
name: Identifier,
body: ConstraintBody,
}
#[derive(Clone, Debug)]
#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
pub enum ConstraintBody {
Informal(ControlledLanguageString),
Formal(FormalConstraint),
}
impl HasName for Constraint {
fn name(&self) -> &Identifier {
&self.name
}
fn set_name(&mut self, name: Identifier) {
self.name = name;
}
}
impl HasBody for Constraint {
type Body = ConstraintBody;
fn body(&self) -> &Self::Body {
&self.body
}
fn body_mut(&mut self) -> &mut Self::Body {
&mut self.body
}
fn set_body(&mut self, body: Self::Body) {
self.body = body;
}
}
impl HasSourceSpan for Constraint {
fn with_source_span(self, span: Span) -> Self {
let mut self_mut = self;
self_mut.span = Some(span);
self_mut
}
fn source_span(&self) -> Option<&Span> {
self.span.as_ref()
}
fn set_source_span(&mut self, span: Span) {
self.span = Some(span);
}
fn unset_source_span(&mut self) {
self.span = None;
}
}
impl References for Constraint {
fn referenced_annotations<'a>(&'a self, names: &mut BTreeSet<&'a IdentifierReference>) {
self.body.referenced_annotations(names);
}
fn referenced_types<'a>(&'a self, names: &mut BTreeSet<&'a IdentifierReference>) {
self.body.referenced_types(names);
}
}
impl Validate for Constraint {
fn validate(
&self,
top: &Module,
cache: &impl ModuleStore,
loader: &impl ModuleLoader,
check_constraints: bool,
) {
self.body.validate(top, cache, loader, check_constraints)
}
}
impl Constraint {
pub fn new<B>(name: Identifier, body: B) -> Self
where
B: Into<ConstraintBody>,
{
Self {
span: None,
name,
body: body.into(),
}
}
}
impl From<&ControlledLanguageString> for ConstraintBody {
fn from(v: &ControlledLanguageString) -> Self {
Self::Informal(v.clone())
}
}
impl From<ControlledLanguageString> for ConstraintBody {
fn from(v: ControlledLanguageString) -> Self {
Self::Informal(v)
}
}
impl From<&FormalConstraint> for ConstraintBody {
fn from(v: &FormalConstraint) -> Self {
Self::Formal(v.clone())
}
}
impl From<FormalConstraint> for ConstraintBody {
fn from(v: FormalConstraint) -> Self {
Self::Formal(v)
}
}
impl References for ConstraintBody {
fn referenced_annotations<'a>(&'a self, names: &mut BTreeSet<&'a IdentifierReference>) {
match self {
Self::Informal(v) => v.referenced_annotations(names),
Self::Formal(v) => v.referenced_annotations(names),
}
}
fn referenced_types<'a>(&'a self, names: &mut BTreeSet<&'a IdentifierReference>) {
match self {
Self::Informal(v) => v.referenced_types(names),
Self::Formal(v) => v.referenced_types(names),
}
}
}
impl Validate for ConstraintBody {
fn validate(
&self,
top: &Module,
cache: &impl ModuleStore,
loader: &impl ModuleLoader,
check_constraints: bool,
) {
match self {
Self::Informal(v) => v.validate(top, cache, loader, check_constraints),
Self::Formal(v) => v.validate(top, cache, loader, check_constraints),
}
}
}
impl ConstraintBody {
pub const fn is_informal(&self) -> bool {
matches!(self, Self::Informal(_))
}
pub const fn as_informal(&self) -> Option<&ControlledLanguageString> {
match self {
Self::Informal(v) => Some(v),
_ => None,
}
}
pub const fn is_formal(&self) -> bool {
matches!(self, Self::Formal(_))
}
pub const fn as_formal(&self) -> Option<&FormalConstraint> {
match self {
Self::Formal(v) => Some(v),
_ => None,
}
}
}
mod formal;
pub use formal::{
AtomicSentence, BinaryBooleanSentence, BooleanSentence, ConnectiveOperator, ConstraintSentence,
Equation, FormalConstraint, FunctionBody, FunctionCardinality, FunctionComposition,
FunctionDef, FunctionParameter, FunctionSignature, FunctionType, FunctionTypeReference,
FunctionalTerm, InequalityRelation, Inequation, PredicateSequenceMember, PredicateValue,
QuantifiedSentence, QuantifiedVariable, QuantifiedVariableBinding, Quantifier, SequenceBuilder,
SequenceOfPredicateValues, SimpleSentence, Subject, Term, UnaryBooleanSentence, Variable,
};
mod informal;
pub use informal::{ControlledLanguageString, ControlledLanguageTag};