use super::{
BiOperator, OperatorF, OperatorG, OperatorR, OperatorU, Property, TemporalOperator, UniOperator,
};
impl Property {
#[must_use]
pub fn enf(&self) -> Self {
match self {
Property::Const(_) => self.clone(),
Property::Atomic(_) => self.clone(),
Property::Negation(inner) => Property::Negation(inner.enf()),
Property::Or(v) => Property::Or(v.enf()),
Property::And(v) => Property::And(v.enf()),
Property::E(temporal) => Property::E(match temporal {
TemporalOperator::X(inner) => TemporalOperator::X(inner.enf()),
TemporalOperator::F(inner) => {
TemporalOperator::U(inner.expanded().enf())
}
TemporalOperator::G(inner) => TemporalOperator::G(inner.enf()),
TemporalOperator::U(inner) => TemporalOperator::U(inner.enf()),
TemporalOperator::R(inner) => {
let au = make_negated(Property::A(TemporalOperator::U(inner.negated())));
return au.enf();
}
}),
Property::A(temporal) => make_negated(Property::E(match temporal {
TemporalOperator::X(inner) => {
TemporalOperator::X(UniOperator::new(make_negated_box(inner.enf().0)))
}
TemporalOperator::F(inner) => {
TemporalOperator::G(inner.negated().enf())
}
TemporalOperator::G(inner) => {
TemporalOperator::U(inner.negated().expanded().enf())
}
TemporalOperator::U(inner) => {
let hold_enf = inner.hold.enf();
let until_enf = inner.until.enf();
let eu_part = Property::E(TemporalOperator::U(OperatorU {
hold: Box::new(Property::Negation(UniOperator::new(until_enf.clone()))),
until: Box::new(Property::Negation(UniOperator::new(Property::Or(
BiOperator {
a: Box::new(hold_enf),
b: Box::new(until_enf.clone()),
},
)))),
}));
let eg_part = Property::E(TemporalOperator::G(OperatorG(Box::new(
make_negated(until_enf),
))));
return Property::Negation(UniOperator::new(Property::Or(BiOperator {
a: Box::new(eu_part),
b: Box::new(eg_part),
})));
}
TemporalOperator::R(inner) => {
TemporalOperator::U(inner.negated().enf())
}
})),
}
}
}
impl UniOperator {
#[must_use]
pub fn enf(&self) -> Self {
UniOperator(Box::new(self.0.enf()))
}
}
impl OperatorF {
#[must_use]
pub fn negated(&self) -> OperatorG {
OperatorG(Box::new(make_negated((*self.0).clone())))
}
#[must_use]
pub fn expanded(&self) -> OperatorU {
OperatorU {
hold: Box::new(Property::Const(true)),
until: Box::clone(&self.0),
}
}
}
impl OperatorG {
#[must_use]
pub fn enf(&self) -> Self {
OperatorG(Box::new(self.0.enf()))
}
#[must_use]
pub fn negated(&self) -> OperatorF {
OperatorF(Box::new(make_negated((*self.0).clone())))
}
}
impl BiOperator {
#[must_use]
pub fn enf(&self) -> Self {
BiOperator {
a: Box::new(self.a.enf()),
b: Box::new(self.b.enf()),
}
}
}
impl OperatorU {
#[must_use]
pub fn enf(&self) -> Self {
OperatorU {
hold: Box::new(self.hold.enf()),
until: Box::new(self.until.enf()),
}
}
}
impl OperatorR {
#[must_use]
pub fn negated(&self) -> OperatorU {
OperatorU {
hold: Box::new(make_negated((*self.releaser).clone())),
until: Box::new(make_negated((*self.releasee).clone())),
}
}
}
fn make_negated_box(prop: Box<Property>) -> Property {
Property::Negation(UniOperator(prop))
}
fn make_negated(prop: Property) -> Property {
Property::Negation(UniOperator::new(prop))
}