Positive version of assert and group functions w/ parsers
Grouping function in execution::data
This commit is contained in:
@ -1,5 +1,10 @@
|
||||
pub mod dsl;
|
||||
pub mod rsassert;
|
||||
mod fmt;
|
||||
|
||||
pub mod positivedsl;
|
||||
mod positivefmt;
|
||||
|
||||
mod rsassert;
|
||||
|
||||
pub mod relabel {
|
||||
pub use super::rsassert::useful_types_edge_relabeler::*;
|
||||
@ -9,7 +14,13 @@ pub mod grouping {
|
||||
pub use super::rsassert::useful_types_node_relabeler::*;
|
||||
}
|
||||
|
||||
mod fmt;
|
||||
pub mod positive_relabel {
|
||||
pub use super::rsassert::useful_types_positive_edge_relabeler::*;
|
||||
}
|
||||
|
||||
pub mod positive_grouping {
|
||||
pub use super::rsassert::useful_types_positive_node_relabeler::*;
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests;
|
||||
|
||||
1222
assert/src/positivedsl.rs
Normal file
1222
assert/src/positivedsl.rs
Normal file
File diff suppressed because it is too large
Load Diff
615
assert/src/positivefmt.rs
Normal file
615
assert/src/positivefmt.rs
Normal file
@ -0,0 +1,615 @@
|
||||
// -----------------------------------------------------------------------------
|
||||
// Display Implementation for all types
|
||||
// -----------------------------------------------------------------------------
|
||||
use std::fmt;
|
||||
|
||||
use rsprocess::translator::{Formatter, PrintableWithTranslator, Translator};
|
||||
|
||||
use super::positivedsl::*;
|
||||
|
||||
impl<S> fmt::Debug for PositiveAssert<S>
|
||||
where
|
||||
S: fmt::Debug,
|
||||
{
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "label {{\n{:?}\n}}", self.tree)
|
||||
}
|
||||
}
|
||||
|
||||
impl<S> fmt::Debug for PositiveTree<S>
|
||||
where
|
||||
S: fmt::Debug,
|
||||
{
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
| Self::Concat(t1, t2) => {
|
||||
write!(f, "{t1:?};\n{t2:?}")
|
||||
},
|
||||
| Self::If(exp, t) => {
|
||||
write!(f, "if {exp:?} {{\n{t:?}\n}}")
|
||||
},
|
||||
| Self::IfElse(exp, t1, t2) => {
|
||||
write!(f, "if {exp:?} {{\n{t1:?}\n}} else {{\n{t2:?}\n}}")
|
||||
},
|
||||
| Self::Assignment(v, q, exp) =>
|
||||
if let Some(q) = q {
|
||||
write!(f, "{v:?}.{q:?} = {exp:?}")
|
||||
} else {
|
||||
write!(f, "{v:?} = {exp:?}")
|
||||
},
|
||||
| Self::Return(exp) => {
|
||||
write!(f, "return {exp:?}")
|
||||
},
|
||||
| Self::For(v, r, t) => {
|
||||
write!(f, "for {v:?} in {r:?} {{\n{t:?}\n}}")
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<S> fmt::Debug for PositiveVariable<S>
|
||||
where
|
||||
S: fmt::Debug,
|
||||
{
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
| Self::Special(s) => {
|
||||
write!(f, "{s:?}")
|
||||
},
|
||||
| Self::Id(s) => {
|
||||
write!(f, "{s:?}")
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<S> fmt::Debug for PositiveExpression<S>
|
||||
where
|
||||
S: fmt::Debug,
|
||||
{
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
| Self::True => {
|
||||
write!(f, "True")
|
||||
},
|
||||
| Self::False => {
|
||||
write!(f, "False")
|
||||
},
|
||||
| Self::Integer(i) => {
|
||||
write!(f, "{i}")
|
||||
},
|
||||
| Self::Label(rslabel) => {
|
||||
write!(f, "{{debug: {rslabel:?}}}")
|
||||
},
|
||||
| Self::Set(set) => {
|
||||
write!(f, "{{debug: {set:?}}}")
|
||||
},
|
||||
| Self::PositiveElement(el) => {
|
||||
write!(f, "'{{debug: {el:?}}}'")
|
||||
},
|
||||
| Self::String(s) => {
|
||||
write!(f, r#""{s:?}""#)
|
||||
},
|
||||
| Self::Var(v) => {
|
||||
write!(f, "{v:?}")
|
||||
},
|
||||
| Self::Unary(u, exp) =>
|
||||
if u.is_prefix() {
|
||||
write!(f, "{u:?}({exp:?})")
|
||||
} else if u.is_suffix() {
|
||||
write!(f, "{exp:?}{u:?}")
|
||||
} else {
|
||||
unreachable!()
|
||||
},
|
||||
| Self::Binary(b, exp1, exp2) =>
|
||||
if b.is_prefix() {
|
||||
write!(f, "{b:?}({exp1:?}, {exp2:?})")
|
||||
} else if b.is_suffix() {
|
||||
write!(f, "({exp1:?}, {exp2:?}){b:?}")
|
||||
} else if b.is_infix() {
|
||||
write!(f, "({exp1:?} {b:?} {exp2:?})")
|
||||
} else {
|
||||
unreachable!()
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<S> fmt::Debug for PositiveRange<S>
|
||||
where
|
||||
S: fmt::Debug,
|
||||
{
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
| Self::IterateOverSet(exp) => write!(f, "{{{exp:?}}}"),
|
||||
| Self::IterateInRange(exp1, exp2) => {
|
||||
write!(f, "{exp1:?}..{exp2:?}")
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Debug for PositiveUnary {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
| Self::Not => write!(f, "not"),
|
||||
| Self::Rand => write!(f, "rand"),
|
||||
| Self::Empty => write!(f, ".empty"),
|
||||
| Self::Length => write!(f, ".length"),
|
||||
| Self::ToStr => write!(f, ".tostr"),
|
||||
| Self::ToEl => write!(f, ".toel"),
|
||||
| Self::Qualifier(q) => write!(f, ".{q:?}"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Debug for QualifierRestricted {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
| Self::Entities => write!(f, "Entities"),
|
||||
| Self::Context => write!(f, "Context"),
|
||||
| Self::Reactants => write!(f, "Reactants"),
|
||||
| Self::ReactantsAbsent => write!(f, "ReactantsAbsent"),
|
||||
| Self::Inhibitors => write!(f, "Inhibitors"),
|
||||
| Self::InhibitorsPresent => write!(f, "InhibitorsPresent"),
|
||||
| Self::Products => write!(f, "Products"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Debug for QualifierLabel {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
| Self::AvailableEntities => write!(f, "AvailableEntities"),
|
||||
| Self::AllReactants => write!(f, "AllReactants"),
|
||||
| Self::AllInhibitors => write!(f, "AllInhibitors"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Debug for QualifierSystem {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match self {
|
||||
| Self::Context => write!(f, "context"),
|
||||
| Self::Entities => write!(f, "entities"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Debug for QualifierEdge {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match self {
|
||||
| Self::Source => write!(f, "source"),
|
||||
| Self::Target => write!(f, "target"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Debug for QualifierNode {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match self {
|
||||
| Self::Neighbours => write!(f, "neighbours"),
|
||||
| Self::System => write!(f, "system"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Debug for PositiveQualifier {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match self {
|
||||
| Self::Label(q) => write!(f, "{q:?}"),
|
||||
| Self::Restricted(q) => write!(f, "{q:?}"),
|
||||
| Self::System(q) => write!(f, "{q:?}"),
|
||||
| Self::Edge(q) => write!(f, "{q:?}"),
|
||||
| Self::Node(q) => write!(f, "{q:?}"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Debug for PositiveBinary {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
| Self::And => write!(f, "&&"),
|
||||
| Self::Or => write!(f, "||"),
|
||||
| Self::Xor => write!(f, "^^"),
|
||||
| Self::Less => write!(f, "<"),
|
||||
| Self::LessEq => write!(f, "<="),
|
||||
| Self::More => write!(f, ">"),
|
||||
| Self::MoreEq => write!(f, ">="),
|
||||
| Self::Eq => write!(f, "=="),
|
||||
| Self::NotEq => write!(f, "!="),
|
||||
| Self::Plus => write!(f, "+"),
|
||||
| Self::Minus => write!(f, "-"),
|
||||
| Self::Times => write!(f, "*"),
|
||||
| Self::Exponential => write!(f, "^"),
|
||||
| Self::Quotient => write!(f, "/"),
|
||||
| Self::Reminder => write!(f, "%"),
|
||||
| Self::Concat => write!(f, "::"),
|
||||
| Self::SubStr => write!(f, "substr"),
|
||||
| Self::Min => write!(f, "min"),
|
||||
| Self::Max => write!(f, "max"),
|
||||
| Self::CommonSubStr => write!(f, "commonsubstr"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Debug for PositiveAssertReturnValue {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
| Self::Boolean(b) => write!(f, "{b:?}"),
|
||||
| Self::Integer(i) => write!(f, "{i:?}"),
|
||||
| Self::String(s) => write!(f, r#""{s:?}""#),
|
||||
| Self::Label(l) => write!(f, "{{debug: {l:?}}}"),
|
||||
| Self::Set(set) => write!(f, "{{debug: {set:?}}}"),
|
||||
| Self::PositiveElement(el) => write!(f, "{{debug: {el:?}}}"),
|
||||
| Self::Edge(edge) => write!(f, "{{debug: {edge:?}}}"),
|
||||
| Self::Node(node) => write!(f, "{{debug: {node:?}}}"),
|
||||
| Self::Neighbours(node) => {
|
||||
write!(f, "{{debug: {node:?}}}.neighbours")
|
||||
},
|
||||
| Self::System(sys) => write!(f, "{{debug: {sys:?}}}"),
|
||||
| Self::Context(ctx) => write!(f, "{{debug: {ctx:?}}}"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Debug for PositiveAssertionTypes {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
| Self::Boolean => write!(f, "boolean"),
|
||||
| Self::Integer => write!(f, "integer"),
|
||||
| Self::String => write!(f, "string"),
|
||||
| Self::Label => write!(f, "label"),
|
||||
| Self::Set => write!(f, "set"),
|
||||
| Self::PositiveElement => write!(f, "element"),
|
||||
| Self::System => write!(f, "system"),
|
||||
| Self::Context => write!(f, "context"),
|
||||
| Self::NoType => write!(f, "no type"),
|
||||
| Self::RangeInteger => write!(f, "range of integers"),
|
||||
| Self::RangeSet => write!(f, "range of set"),
|
||||
| Self::RangeNeighbours => write!(f, "range of edges"),
|
||||
| Self::Edge => write!(f, "edge"),
|
||||
| Self::Node => write!(f, "node"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
impl<S> PrintableWithTranslator for PositiveAssert<S>
|
||||
where
|
||||
S: PrintableWithTranslator,
|
||||
{
|
||||
fn print(
|
||||
&self,
|
||||
f: &mut fmt::Formatter,
|
||||
translator: &Translator,
|
||||
) -> fmt::Result {
|
||||
write!(
|
||||
f,
|
||||
"label {{\n{}\n}}",
|
||||
Formatter::from(translator, &self.tree)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl<S> PrintableWithTranslator for PositiveTree<S>
|
||||
where
|
||||
S: PrintableWithTranslator,
|
||||
{
|
||||
fn print(
|
||||
&self,
|
||||
f: &mut fmt::Formatter,
|
||||
translator: &Translator,
|
||||
) -> fmt::Result {
|
||||
match self {
|
||||
| Self::Concat(t1, t2) => write!(
|
||||
f,
|
||||
"{};\n{}",
|
||||
Formatter::from(translator, &**t1),
|
||||
Formatter::from(translator, &**t2)
|
||||
),
|
||||
| Self::If(exp, t) => write!(
|
||||
f,
|
||||
"if {} {{\n{}\n}}",
|
||||
Formatter::from(translator, &**exp),
|
||||
Formatter::from(translator, &**t)
|
||||
),
|
||||
| Self::IfElse(exp, t1, t2) => {
|
||||
write!(
|
||||
f,
|
||||
"if {} {{\n{}\n}} else {{\n{}\n}}",
|
||||
Formatter::from(translator, &**exp),
|
||||
Formatter::from(translator, &**t1),
|
||||
Formatter::from(translator, &**t2)
|
||||
)
|
||||
},
|
||||
| Self::Assignment(v, q, exp) =>
|
||||
if let Some(q) = q {
|
||||
write!(
|
||||
f,
|
||||
"{}.{} = {}",
|
||||
Formatter::from(translator, v),
|
||||
Formatter::from(translator, q),
|
||||
Formatter::from(translator, &**exp)
|
||||
)
|
||||
} else {
|
||||
write!(
|
||||
f,
|
||||
"{} = {}",
|
||||
Formatter::from(translator, v),
|
||||
Formatter::from(translator, &**exp)
|
||||
)
|
||||
},
|
||||
| Self::Return(exp) => {
|
||||
write!(f, "return {}", Formatter::from(translator, &**exp))
|
||||
},
|
||||
| Self::For(v, r, t) => {
|
||||
write!(
|
||||
f,
|
||||
"for {} in {} {{\n{}\n}}",
|
||||
Formatter::from(translator, v),
|
||||
Formatter::from(translator, r),
|
||||
Formatter::from(translator, &**t)
|
||||
)
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<S> PrintableWithTranslator for PositiveVariable<S>
|
||||
where
|
||||
S: PrintableWithTranslator,
|
||||
{
|
||||
fn print(
|
||||
&self,
|
||||
f: &mut fmt::Formatter,
|
||||
translator: &Translator,
|
||||
) -> fmt::Result {
|
||||
match self {
|
||||
| Self::Special(s) => {
|
||||
write!(f, "{}", Formatter::from(translator, s))
|
||||
},
|
||||
| Self::Id(s) => write!(f, "{s}"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<S> PrintableWithTranslator for PositiveExpression<S>
|
||||
where
|
||||
S: PrintableWithTranslator,
|
||||
{
|
||||
fn print(
|
||||
&self,
|
||||
f: &mut fmt::Formatter,
|
||||
translator: &Translator,
|
||||
) -> fmt::Result {
|
||||
match self {
|
||||
| Self::True => write!(f, "True"),
|
||||
| Self::False => write!(f, "False"),
|
||||
| Self::Integer(i) => write!(f, "{i}"),
|
||||
| Self::Label(l) => {
|
||||
write!(f, "{}", Formatter::from(translator, &**l))
|
||||
},
|
||||
| Self::Set(set) => {
|
||||
write!(f, "{}", Formatter::from(translator, set))
|
||||
},
|
||||
| Self::PositiveElement(el) => {
|
||||
write!(f, "'{}'", Formatter::from(translator, el))
|
||||
},
|
||||
| Self::String(s) => write!(f, r#""{s}""#),
|
||||
| Self::Var(v) => write!(f, "{}", Formatter::from(translator, v)),
|
||||
| Self::Unary(u, exp) =>
|
||||
if u.is_prefix() {
|
||||
write!(
|
||||
f,
|
||||
"{}({})",
|
||||
Formatter::from(translator, u),
|
||||
Formatter::from(translator, &**exp)
|
||||
)
|
||||
} else if u.is_suffix() {
|
||||
write!(
|
||||
f,
|
||||
"{}{}",
|
||||
Formatter::from(translator, &**exp),
|
||||
Formatter::from(translator, u)
|
||||
)
|
||||
} else {
|
||||
unreachable!()
|
||||
},
|
||||
| Self::Binary(b, exp1, exp2) =>
|
||||
if b.is_prefix() {
|
||||
write!(
|
||||
f,
|
||||
"{}({}, {})",
|
||||
Formatter::from(translator, b),
|
||||
Formatter::from(translator, &**exp1),
|
||||
Formatter::from(translator, &**exp2)
|
||||
)
|
||||
} else if b.is_suffix() {
|
||||
write!(
|
||||
f,
|
||||
"({}, {}){}",
|
||||
Formatter::from(translator, &**exp1),
|
||||
Formatter::from(translator, &**exp2),
|
||||
Formatter::from(translator, b)
|
||||
)
|
||||
} else if b.is_infix() {
|
||||
write!(
|
||||
f,
|
||||
"({} {} {})",
|
||||
Formatter::from(translator, &**exp1),
|
||||
Formatter::from(translator, b),
|
||||
Formatter::from(translator, &**exp2)
|
||||
)
|
||||
} else {
|
||||
unreachable!()
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<S> PrintableWithTranslator for PositiveRange<S>
|
||||
where
|
||||
S: PrintableWithTranslator,
|
||||
{
|
||||
fn print(
|
||||
&self,
|
||||
f: &mut fmt::Formatter,
|
||||
translator: &Translator,
|
||||
) -> fmt::Result {
|
||||
match self {
|
||||
| Self::IterateOverSet(exp) => {
|
||||
write!(f, "{}", Formatter::from(translator, &**exp))
|
||||
},
|
||||
| Self::IterateInRange(exp1, exp2) => write!(
|
||||
f,
|
||||
"{}..{}",
|
||||
Formatter::from(translator, &**exp1),
|
||||
Formatter::from(translator, &**exp2)
|
||||
),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl PrintableWithTranslator for PositiveUnary {
|
||||
fn print(
|
||||
&self,
|
||||
f: &mut fmt::Formatter,
|
||||
translator: &Translator,
|
||||
) -> fmt::Result {
|
||||
match self {
|
||||
| Self::Not => write!(f, "not"),
|
||||
| Self::Rand => write!(f, "rand"),
|
||||
| Self::Empty => write!(f, ".empty"),
|
||||
| Self::Length => write!(f, ".length"),
|
||||
| Self::ToStr => write!(f, ".tostr"),
|
||||
| Self::ToEl => write!(f, ".toel"),
|
||||
| Self::Qualifier(q) => {
|
||||
write!(f, ".{}", Formatter::from(translator, q))
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl PrintableWithTranslator for QualifierRestricted {
|
||||
fn print(
|
||||
&self,
|
||||
f: &mut fmt::Formatter,
|
||||
_translator: &Translator,
|
||||
) -> fmt::Result {
|
||||
write!(f, "{self:?}")
|
||||
}
|
||||
}
|
||||
|
||||
impl PrintableWithTranslator for QualifierLabel {
|
||||
fn print(
|
||||
&self,
|
||||
f: &mut fmt::Formatter,
|
||||
_translator: &Translator,
|
||||
) -> fmt::Result {
|
||||
write!(f, "{self:?}")
|
||||
}
|
||||
}
|
||||
|
||||
impl PrintableWithTranslator for QualifierSystem {
|
||||
fn print(
|
||||
&self,
|
||||
f: &mut fmt::Formatter,
|
||||
_translator: &Translator,
|
||||
) -> fmt::Result {
|
||||
write!(f, "{self:?}")
|
||||
}
|
||||
}
|
||||
|
||||
impl PrintableWithTranslator for QualifierEdge {
|
||||
fn print(
|
||||
&self,
|
||||
f: &mut fmt::Formatter,
|
||||
_translator: &Translator,
|
||||
) -> fmt::Result {
|
||||
write!(f, "{self:?}")
|
||||
}
|
||||
}
|
||||
|
||||
impl PrintableWithTranslator for QualifierNode {
|
||||
fn print(
|
||||
&self,
|
||||
f: &mut fmt::Formatter,
|
||||
_translator: &Translator,
|
||||
) -> fmt::Result {
|
||||
write!(f, "{self:?}")
|
||||
}
|
||||
}
|
||||
|
||||
impl PrintableWithTranslator for PositiveQualifier {
|
||||
fn print(
|
||||
&self,
|
||||
f: &mut fmt::Formatter,
|
||||
translator: &Translator,
|
||||
) -> fmt::Result {
|
||||
match self {
|
||||
| Self::Label(q) => write!(f, "{}", Formatter::from(translator, q)),
|
||||
| Self::Restricted(q) => {
|
||||
write!(f, "{}", Formatter::from(translator, q))
|
||||
},
|
||||
| Self::System(q) => {
|
||||
write!(f, "{}", Formatter::from(translator, q))
|
||||
},
|
||||
| Self::Edge(q) => write!(f, "{}", Formatter::from(translator, q)),
|
||||
| Self::Node(q) => write!(f, "{}", Formatter::from(translator, q)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl PrintableWithTranslator for PositiveBinary {
|
||||
fn print(
|
||||
&self,
|
||||
f: &mut fmt::Formatter,
|
||||
_translator: &Translator,
|
||||
) -> fmt::Result {
|
||||
write!(f, "{self:?}")
|
||||
}
|
||||
}
|
||||
|
||||
impl PrintableWithTranslator for PositiveAssertReturnValue {
|
||||
fn print(
|
||||
&self,
|
||||
f: &mut fmt::Formatter,
|
||||
translator: &Translator,
|
||||
) -> fmt::Result {
|
||||
match self {
|
||||
| Self::Boolean(b) => write!(f, "{b}"),
|
||||
| Self::Integer(i) => write!(f, "{i}"),
|
||||
| Self::String(s) => write!(f, r#""{s}""#),
|
||||
| Self::Label(l) => write!(f, "{}", Formatter::from(translator, l)),
|
||||
| Self::Set(set) => {
|
||||
write!(f, "{}", Formatter::from(translator, set))
|
||||
},
|
||||
| Self::PositiveElement(el) => {
|
||||
write!(f, "{}", Formatter::from(translator, el))
|
||||
},
|
||||
| Self::Edge(edge) => write!(f, "{{edge: {edge:?}}}"),
|
||||
| Self::Node(node) => write!(f, "{{node: {node:?}}}"),
|
||||
| Self::Neighbours(node) => {
|
||||
write!(f, "{{node: {node:?}}}.neighbours")
|
||||
},
|
||||
| Self::System(sys) => {
|
||||
write!(f, "{}", Formatter::from(translator, sys))
|
||||
},
|
||||
| Self::Context(ctx) => {
|
||||
write!(f, "{}", Formatter::from(translator, ctx))
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl PrintableWithTranslator for PositiveAssertionTypes {
|
||||
fn print(
|
||||
&self,
|
||||
f: &mut fmt::Formatter,
|
||||
_translator: &Translator,
|
||||
) -> fmt::Result {
|
||||
write!(f, "{self:?}")
|
||||
}
|
||||
}
|
||||
@ -4,11 +4,15 @@ use rsprocess::translator::PrintableWithTranslator;
|
||||
use rsprocess::{graph, label, set, system, translator};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use super::dsl::*;
|
||||
use super::{dsl, positivedsl};
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// -----------------------------------------------------------------------------
|
||||
// Specific Assert Implementation
|
||||
// ----------------------------------------------------------------------------
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// System
|
||||
|
||||
/// Module that has all types and structures for bisimilarity relabeler.
|
||||
pub mod useful_types_edge_relabeler {
|
||||
@ -59,19 +63,19 @@ enum EdgeRelablerInputValues {
|
||||
Edge(petgraph::graph::EdgeIndex),
|
||||
}
|
||||
|
||||
impl SpecialVariables<EdgeRelablerInputValues> for EdgeRelablerInput {
|
||||
fn type_of(&self) -> AssertionTypes {
|
||||
impl dsl::SpecialVariables<EdgeRelablerInputValues> for EdgeRelablerInput {
|
||||
fn type_of(&self) -> dsl::AssertionTypes {
|
||||
match self {
|
||||
| Self::Edge => AssertionTypes::Edge,
|
||||
| Self::Label => AssertionTypes::Label,
|
||||
| Self::Edge => dsl::AssertionTypes::Edge,
|
||||
| Self::Label => dsl::AssertionTypes::Label,
|
||||
}
|
||||
}
|
||||
|
||||
fn type_qualified(&self, q: &Qualifier) -> Result<AssertionTypes, String> {
|
||||
fn type_qualified(&self, q: &dsl::Qualifier) -> Result<dsl::AssertionTypes, String> {
|
||||
match (self, q) {
|
||||
| (Self::Label, Qualifier::Label(_))
|
||||
| (Self::Label, Qualifier::Restricted(_)) =>
|
||||
Ok(AssertionTypes::Set),
|
||||
| (Self::Label, dsl::Qualifier::Label(_))
|
||||
| (Self::Label, dsl::Qualifier::Restricted(_)) =>
|
||||
Ok(dsl::AssertionTypes::Set),
|
||||
| (s, q) =>
|
||||
Err(format!("Wrong use of qualifier {q:?} on variable {s:?}.")),
|
||||
}
|
||||
@ -79,22 +83,22 @@ impl SpecialVariables<EdgeRelablerInputValues> for EdgeRelablerInput {
|
||||
|
||||
fn new_context(
|
||||
input: HashMap<Self, EdgeRelablerInputValues>,
|
||||
) -> HashMap<Self, AssertReturnValue> {
|
||||
) -> HashMap<Self, dsl::AssertReturnValue> {
|
||||
input
|
||||
.iter()
|
||||
.map(|(key, value)| match value {
|
||||
| EdgeRelablerInputValues::Edge(e) =>
|
||||
(*key, AssertReturnValue::Edge(*e)),
|
||||
(*key, dsl::AssertReturnValue::Edge(*e)),
|
||||
| EdgeRelablerInputValues::Label(l) =>
|
||||
(*key, AssertReturnValue::Label(l.clone())),
|
||||
(*key, dsl::AssertReturnValue::Label(l.clone())),
|
||||
})
|
||||
.collect::<HashMap<Self, AssertReturnValue>>()
|
||||
.collect::<HashMap<Self, dsl::AssertReturnValue>>()
|
||||
}
|
||||
|
||||
fn correct_type(&self, other: &AssertReturnValue) -> bool {
|
||||
fn correct_type(&self, other: &dsl::AssertReturnValue) -> bool {
|
||||
match (self, other) {
|
||||
| (Self::Edge, AssertReturnValue::Edge(_))
|
||||
| (Self::Label, AssertReturnValue::Label(_)) => true,
|
||||
| (Self::Edge, dsl::AssertReturnValue::Edge(_))
|
||||
| (Self::Label, dsl::AssertReturnValue::Label(_)) => true,
|
||||
| (_, _) => false,
|
||||
}
|
||||
}
|
||||
@ -119,27 +123,27 @@ impl PrintableWithTranslator for EdgeRelablerInput {
|
||||
}
|
||||
}
|
||||
|
||||
impl Assert<EdgeRelablerInput> {
|
||||
impl dsl::Assert<EdgeRelablerInput> {
|
||||
pub fn typecheck(&self) -> Result<(), String> {
|
||||
let mut context = TypeContext::new();
|
||||
let ty = typecheck(&self.tree, &mut context)?;
|
||||
let mut context = dsl::TypeContext::new();
|
||||
let ty = dsl::typecheck(&self.tree, &mut context)?;
|
||||
match ty {
|
||||
| AssertionTypes::Boolean
|
||||
| AssertionTypes::Integer
|
||||
| AssertionTypes::String
|
||||
| AssertionTypes::Label
|
||||
| AssertionTypes::Set
|
||||
| AssertionTypes::Element
|
||||
| AssertionTypes::Edge
|
||||
| AssertionTypes::Node
|
||||
| AssertionTypes::System
|
||||
| AssertionTypes::Context => Ok(()),
|
||||
| AssertionTypes::NoType =>
|
||||
| dsl::AssertionTypes::Boolean
|
||||
| dsl::AssertionTypes::Integer
|
||||
| dsl::AssertionTypes::String
|
||||
| dsl::AssertionTypes::Label
|
||||
| dsl::AssertionTypes::Set
|
||||
| dsl::AssertionTypes::Element
|
||||
| dsl::AssertionTypes::Edge
|
||||
| dsl::AssertionTypes::Node
|
||||
| dsl::AssertionTypes::System
|
||||
| dsl::AssertionTypes::Context => Ok(()),
|
||||
| dsl::AssertionTypes::NoType =>
|
||||
Err("No return type, at least one return statement required."
|
||||
.into()),
|
||||
| AssertionTypes::RangeInteger
|
||||
| AssertionTypes::RangeSet
|
||||
| AssertionTypes::RangeNeighbours =>
|
||||
| dsl::AssertionTypes::RangeInteger
|
||||
| dsl::AssertionTypes::RangeSet
|
||||
| dsl::AssertionTypes::RangeNeighbours =>
|
||||
Err(format!("Returned type {ty:?} is not a valid return type.")),
|
||||
}
|
||||
}
|
||||
@ -149,7 +153,7 @@ impl Assert<EdgeRelablerInput> {
|
||||
graph: &graph::SystemGraph,
|
||||
edge: &<graph::SystemGraph as petgraph::visit::GraphBase>::EdgeId,
|
||||
translator: &mut translator::Translator,
|
||||
) -> Result<AssertReturnValue, String> {
|
||||
) -> Result<dsl::AssertReturnValue, String> {
|
||||
let label = graph
|
||||
.edge_weight(*edge)
|
||||
.ok_or("Missing edge {{debug: {edge:?}}}")?;
|
||||
@ -164,8 +168,8 @@ impl Assert<EdgeRelablerInput> {
|
||||
EdgeRelablerInputValues::Label(label.clone()),
|
||||
);
|
||||
|
||||
let mut context = Context::new(input_vals);
|
||||
if let Some(v) = execute(&self.tree, &mut context, translator, graph)? {
|
||||
let mut context = dsl::Context::new(input_vals);
|
||||
if let Some(v) = dsl::execute(&self.tree, &mut context, translator, graph)? {
|
||||
Ok(v)
|
||||
} else {
|
||||
Err("No value returned.".into())
|
||||
@ -224,20 +228,20 @@ enum NodeRelablerInputValues {
|
||||
Node(petgraph::graph::NodeIndex),
|
||||
}
|
||||
|
||||
impl SpecialVariables<NodeRelablerInputValues> for NodeRelablerInput {
|
||||
fn type_of(&self) -> AssertionTypes {
|
||||
impl dsl::SpecialVariables<NodeRelablerInputValues> for NodeRelablerInput {
|
||||
fn type_of(&self) -> dsl::AssertionTypes {
|
||||
match self {
|
||||
| Self::Entities => AssertionTypes::Set,
|
||||
| Self::Node => AssertionTypes::Node,
|
||||
| Self::Entities => dsl::AssertionTypes::Set,
|
||||
| Self::Node => dsl::AssertionTypes::Node,
|
||||
}
|
||||
}
|
||||
|
||||
fn type_qualified(&self, q: &Qualifier) -> Result<AssertionTypes, String> {
|
||||
fn type_qualified(&self, q: &dsl::Qualifier) -> Result<dsl::AssertionTypes, String> {
|
||||
match (self, q) {
|
||||
| (Self::Node, Qualifier::Node(QualifierNode::System)) =>
|
||||
Ok(AssertionTypes::System),
|
||||
| (Self::Node, Qualifier::Node(QualifierNode::Neighbours)) =>
|
||||
Ok(AssertionTypes::RangeNeighbours),
|
||||
| (Self::Node, dsl::Qualifier::Node(dsl::QualifierNode::System)) =>
|
||||
Ok(dsl::AssertionTypes::System),
|
||||
| (Self::Node, dsl::Qualifier::Node(dsl::QualifierNode::Neighbours)) =>
|
||||
Ok(dsl::AssertionTypes::RangeNeighbours),
|
||||
| (s, q) =>
|
||||
Err(format!("Wrong use of qualifier {q:?} on variable {s:?}.")),
|
||||
}
|
||||
@ -245,22 +249,22 @@ impl SpecialVariables<NodeRelablerInputValues> for NodeRelablerInput {
|
||||
|
||||
fn new_context(
|
||||
input: HashMap<Self, NodeRelablerInputValues>,
|
||||
) -> HashMap<Self, AssertReturnValue> {
|
||||
) -> HashMap<Self, dsl::AssertReturnValue> {
|
||||
input
|
||||
.iter()
|
||||
.map(|(key, value)| match value {
|
||||
| NodeRelablerInputValues::Entities(e) =>
|
||||
(*key, AssertReturnValue::Set(e.clone())),
|
||||
(*key, dsl::AssertReturnValue::Set(e.clone())),
|
||||
| NodeRelablerInputValues::Node(n) =>
|
||||
(*key, AssertReturnValue::Node(*n)),
|
||||
(*key, dsl::AssertReturnValue::Node(*n)),
|
||||
})
|
||||
.collect::<HashMap<Self, AssertReturnValue>>()
|
||||
.collect::<HashMap<Self, dsl::AssertReturnValue>>()
|
||||
}
|
||||
|
||||
fn correct_type(&self, other: &AssertReturnValue) -> bool {
|
||||
fn correct_type(&self, other: &dsl::AssertReturnValue) -> bool {
|
||||
match (self, other) {
|
||||
| (Self::Entities, AssertReturnValue::Set(_))
|
||||
| (Self::Node, AssertReturnValue::Node(_)) => true,
|
||||
| (Self::Entities, dsl::AssertReturnValue::Set(_))
|
||||
| (Self::Node, dsl::AssertReturnValue::Node(_)) => true,
|
||||
| (_, _) => false,
|
||||
}
|
||||
}
|
||||
@ -285,27 +289,27 @@ impl PrintableWithTranslator for NodeRelablerInput {
|
||||
}
|
||||
}
|
||||
|
||||
impl Assert<NodeRelablerInput> {
|
||||
impl dsl::Assert<NodeRelablerInput> {
|
||||
pub fn typecheck(&self) -> Result<(), String> {
|
||||
let mut context = TypeContext::new();
|
||||
let ty = typecheck(&self.tree, &mut context)?;
|
||||
let mut context = dsl::TypeContext::new();
|
||||
let ty = dsl::typecheck(&self.tree, &mut context)?;
|
||||
match ty {
|
||||
| AssertionTypes::Boolean
|
||||
| AssertionTypes::Integer
|
||||
| AssertionTypes::String
|
||||
| AssertionTypes::Label
|
||||
| AssertionTypes::Set
|
||||
| AssertionTypes::Element
|
||||
| AssertionTypes::Edge
|
||||
| AssertionTypes::Node
|
||||
| AssertionTypes::System
|
||||
| AssertionTypes::Context => Ok(()),
|
||||
| AssertionTypes::NoType =>
|
||||
| dsl::AssertionTypes::Boolean
|
||||
| dsl::AssertionTypes::Integer
|
||||
| dsl::AssertionTypes::String
|
||||
| dsl::AssertionTypes::Label
|
||||
| dsl::AssertionTypes::Set
|
||||
| dsl::AssertionTypes::Element
|
||||
| dsl::AssertionTypes::Edge
|
||||
| dsl::AssertionTypes::Node
|
||||
| dsl::AssertionTypes::System
|
||||
| dsl::AssertionTypes::Context => Ok(()),
|
||||
| dsl::AssertionTypes::NoType =>
|
||||
Err("No return type, at least one return statement required."
|
||||
.into()),
|
||||
| AssertionTypes::RangeInteger
|
||||
| AssertionTypes::RangeSet
|
||||
| AssertionTypes::RangeNeighbours =>
|
||||
| dsl::AssertionTypes::RangeInteger
|
||||
| dsl::AssertionTypes::RangeSet
|
||||
| dsl::AssertionTypes::RangeNeighbours =>
|
||||
Err(format!("Returned type {ty:?} is not a valid return type.")),
|
||||
}
|
||||
}
|
||||
@ -315,7 +319,7 @@ impl Assert<NodeRelablerInput> {
|
||||
graph: &graph::SystemGraph,
|
||||
node: &<graph::SystemGraph as petgraph::visit::GraphBase>::NodeId,
|
||||
translator: &mut translator::Translator,
|
||||
) -> Result<AssertReturnValue, String> {
|
||||
) -> Result<dsl::AssertReturnValue, String> {
|
||||
let system::System {
|
||||
available_entities: entities,
|
||||
..
|
||||
@ -333,8 +337,359 @@ impl Assert<NodeRelablerInput> {
|
||||
NodeRelablerInputValues::Node(*node),
|
||||
);
|
||||
|
||||
let mut context = Context::new(input_vals);
|
||||
if let Some(v) = execute(&self.tree, &mut context, translator, graph)? {
|
||||
let mut context = dsl::Context::new(input_vals);
|
||||
if let Some(v) = dsl::execute(&self.tree, &mut context, translator, graph)? {
|
||||
Ok(v)
|
||||
} else {
|
||||
Err("No value returned.".into())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Positive System
|
||||
|
||||
|
||||
/// Module that has all types and structures for bisimilarity relabeler.
|
||||
pub mod useful_types_positive_edge_relabeler {
|
||||
macro_rules! export_types {
|
||||
( $( $x:ident ),* ) => {
|
||||
$(
|
||||
pub type $x = super::super::positivedsl::$x<super::PositiveEdgeRelablerInput>;
|
||||
)*
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! export_types_no_parameter {
|
||||
( $( $x:ident ),* ) => {
|
||||
$(
|
||||
pub type $x = super::super::positivedsl::$x;
|
||||
)*
|
||||
};
|
||||
}
|
||||
|
||||
export_types!(
|
||||
PositiveAssert,
|
||||
PositiveTree,
|
||||
PositiveVariable,
|
||||
PositiveExpression,
|
||||
PositiveRange
|
||||
);
|
||||
|
||||
export_types_no_parameter!(
|
||||
PositiveUnary,
|
||||
QualifierRestricted,
|
||||
QualifierLabel,
|
||||
QualifierSystem,
|
||||
QualifierEdge,
|
||||
QualifierNode,
|
||||
PositiveQualifier,
|
||||
PositiveBinary,
|
||||
PositiveAssertReturnValue
|
||||
);
|
||||
|
||||
pub type Special = super::PositiveEdgeRelablerInput;
|
||||
}
|
||||
|
||||
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||
pub enum PositiveEdgeRelablerInput {
|
||||
Label,
|
||||
Edge,
|
||||
}
|
||||
|
||||
#[derive(Clone, Serialize, Deserialize)]
|
||||
enum PositiveEdgeRelablerInputValues {
|
||||
Label(label::PositiveLabel),
|
||||
Edge(petgraph::graph::EdgeIndex),
|
||||
}
|
||||
|
||||
impl positivedsl::SpecialVariables<PositiveEdgeRelablerInputValues> for PositiveEdgeRelablerInput {
|
||||
fn type_of(&self) -> positivedsl::PositiveAssertionTypes {
|
||||
match self {
|
||||
| Self::Edge => positivedsl::PositiveAssertionTypes::Edge,
|
||||
| Self::Label => positivedsl::PositiveAssertionTypes::Label,
|
||||
}
|
||||
}
|
||||
|
||||
fn type_qualified(&self, q: &positivedsl::PositiveQualifier) -> Result<positivedsl::PositiveAssertionTypes, String> {
|
||||
match (self, q) {
|
||||
| (Self::Label, positivedsl::PositiveQualifier::Label(_))
|
||||
| (Self::Label, positivedsl::PositiveQualifier::Restricted(_)) =>
|
||||
Ok(positivedsl::PositiveAssertionTypes::Set),
|
||||
| (s, q) =>
|
||||
Err(format!("Wrong use of qualifier {q:?} on variable {s:?}.")),
|
||||
}
|
||||
}
|
||||
|
||||
fn new_context(
|
||||
input: HashMap<Self, PositiveEdgeRelablerInputValues>,
|
||||
) -> HashMap<Self, positivedsl::PositiveAssertReturnValue> {
|
||||
input
|
||||
.iter()
|
||||
.map(|(key, value)| match value {
|
||||
| PositiveEdgeRelablerInputValues::Edge(e) =>
|
||||
(*key, positivedsl::PositiveAssertReturnValue::Edge(*e)),
|
||||
| PositiveEdgeRelablerInputValues::Label(l) =>
|
||||
(*key, positivedsl::PositiveAssertReturnValue::Label(l.clone())),
|
||||
})
|
||||
.collect::<HashMap<Self, positivedsl::PositiveAssertReturnValue>>()
|
||||
}
|
||||
|
||||
fn correct_type(&self, other: &positivedsl::PositiveAssertReturnValue) -> bool {
|
||||
match (self, other) {
|
||||
| (Self::Edge, positivedsl::PositiveAssertReturnValue::Edge(_))
|
||||
| (Self::Label, positivedsl::PositiveAssertReturnValue::Label(_)) => true,
|
||||
| (_, _) => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl std::fmt::Debug for PositiveEdgeRelablerInput {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
| Self::Label => write!(f, "label"),
|
||||
| Self::Edge => write!(f, "edge"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl PrintableWithTranslator for PositiveEdgeRelablerInput {
|
||||
fn print(
|
||||
&self,
|
||||
f: &mut std::fmt::Formatter,
|
||||
_translator: &translator::Translator,
|
||||
) -> std::fmt::Result {
|
||||
write!(f, "{self:?}")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
impl positivedsl::PositiveAssert<PositiveEdgeRelablerInput> {
|
||||
pub fn typecheck(&self) -> Result<(), String> {
|
||||
let mut context = positivedsl::TypeContext::new();
|
||||
let ty = positivedsl::typecheck(&self.tree, &mut context)?;
|
||||
match ty {
|
||||
| positivedsl::PositiveAssertionTypes::Boolean
|
||||
| positivedsl::PositiveAssertionTypes::Integer
|
||||
| positivedsl::PositiveAssertionTypes::String
|
||||
| positivedsl::PositiveAssertionTypes::Label
|
||||
| positivedsl::PositiveAssertionTypes::Set
|
||||
| positivedsl::PositiveAssertionTypes::PositiveElement
|
||||
| positivedsl::PositiveAssertionTypes::Edge
|
||||
| positivedsl::PositiveAssertionTypes::Node
|
||||
| positivedsl::PositiveAssertionTypes::System
|
||||
| positivedsl::PositiveAssertionTypes::Context => Ok(()),
|
||||
| positivedsl::PositiveAssertionTypes::NoType =>
|
||||
Err("No return type, at least one return statement required."
|
||||
.into()),
|
||||
| positivedsl::PositiveAssertionTypes::RangeInteger
|
||||
| positivedsl::PositiveAssertionTypes::RangeSet
|
||||
| positivedsl::PositiveAssertionTypes::RangeNeighbours =>
|
||||
Err(format!("Returned type {ty:?} is not a valid return type.")),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn execute(
|
||||
&self,
|
||||
graph: &graph::PositiveSystemGraph,
|
||||
edge: &<graph::PositiveSystemGraph as petgraph::visit::GraphBase>::EdgeId,
|
||||
translator: &mut translator::Translator,
|
||||
) -> Result<positivedsl::PositiveAssertReturnValue, String> {
|
||||
let label = graph
|
||||
.edge_weight(*edge)
|
||||
.ok_or("Missing edge {{debug: {edge:?}}}")?;
|
||||
|
||||
let mut input_vals = HashMap::new();
|
||||
input_vals.insert(
|
||||
PositiveEdgeRelablerInput::Edge,
|
||||
PositiveEdgeRelablerInputValues::Edge(*edge),
|
||||
);
|
||||
input_vals.insert(
|
||||
PositiveEdgeRelablerInput::Label,
|
||||
PositiveEdgeRelablerInputValues::Label(label.clone()),
|
||||
);
|
||||
|
||||
let mut context = positivedsl::Context::new(input_vals);
|
||||
if let Some(v) = positivedsl::execute(&self.tree, &mut context, translator, graph)? {
|
||||
Ok(v)
|
||||
} else {
|
||||
Err("No value returned.".into())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Positive node grouping
|
||||
|
||||
pub mod useful_types_positive_node_relabeler {
|
||||
macro_rules! export_types {
|
||||
( $( $x:ident ),* ) => {
|
||||
$(
|
||||
pub type $x = super::super::positivedsl::$x<super::PositiveNodeRelablerInput>;
|
||||
)*
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! export_types_no_parameter {
|
||||
( $( $x:ident ),* ) => {
|
||||
$(
|
||||
pub type $x = super::super::positivedsl::$x;
|
||||
)*
|
||||
};
|
||||
}
|
||||
|
||||
export_types!(
|
||||
PositiveAssert,
|
||||
PositiveTree,
|
||||
PositiveVariable,
|
||||
PositiveExpression,
|
||||
PositiveRange
|
||||
);
|
||||
|
||||
export_types_no_parameter!(
|
||||
PositiveUnary,
|
||||
QualifierRestricted,
|
||||
QualifierLabel,
|
||||
QualifierSystem,
|
||||
QualifierEdge,
|
||||
QualifierNode,
|
||||
PositiveQualifier,
|
||||
PositiveBinary,
|
||||
PositiveAssertReturnValue
|
||||
);
|
||||
|
||||
pub type Special = super::PositiveNodeRelablerInput;
|
||||
}
|
||||
|
||||
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||
pub enum PositiveNodeRelablerInput {
|
||||
Entities,
|
||||
Node,
|
||||
}
|
||||
|
||||
#[derive(Clone, Serialize, Deserialize)]
|
||||
enum PositiveNodeRelablerInputValues {
|
||||
Entities(set::PositiveSet),
|
||||
Node(petgraph::graph::NodeIndex),
|
||||
}
|
||||
|
||||
|
||||
impl positivedsl::SpecialVariables<PositiveNodeRelablerInputValues> for PositiveNodeRelablerInput {
|
||||
fn type_of(&self) -> positivedsl::PositiveAssertionTypes {
|
||||
match self {
|
||||
| Self::Entities => positivedsl::PositiveAssertionTypes::Set,
|
||||
| Self::Node => positivedsl::PositiveAssertionTypes::Node,
|
||||
}
|
||||
}
|
||||
|
||||
fn type_qualified(&self, q: &positivedsl::PositiveQualifier) -> Result<positivedsl::PositiveAssertionTypes, String> {
|
||||
match (self, q) {
|
||||
| (Self::Node, positivedsl::PositiveQualifier::Node(positivedsl::QualifierNode::System)) =>
|
||||
Ok(positivedsl::PositiveAssertionTypes::System),
|
||||
| (Self::Node, positivedsl::PositiveQualifier::Node(positivedsl::QualifierNode::Neighbours)) =>
|
||||
Ok(positivedsl::PositiveAssertionTypes::RangeNeighbours),
|
||||
| (s, q) =>
|
||||
Err(format!("Wrong use of qualifier {q:?} on variable {s:?}.")),
|
||||
}
|
||||
}
|
||||
|
||||
fn new_context(
|
||||
input: HashMap<Self, PositiveNodeRelablerInputValues>,
|
||||
) -> HashMap<Self, positivedsl::PositiveAssertReturnValue> {
|
||||
input
|
||||
.iter()
|
||||
.map(|(key, value)| match value {
|
||||
| PositiveNodeRelablerInputValues::Entities(e) =>
|
||||
(*key, positivedsl::PositiveAssertReturnValue::Set(e.clone())),
|
||||
| PositiveNodeRelablerInputValues::Node(n) =>
|
||||
(*key, positivedsl::PositiveAssertReturnValue::Node(*n)),
|
||||
})
|
||||
.collect::<HashMap<Self, positivedsl::PositiveAssertReturnValue>>()
|
||||
}
|
||||
|
||||
fn correct_type(&self, other: &positivedsl::PositiveAssertReturnValue) -> bool {
|
||||
match (self, other) {
|
||||
| (Self::Entities, positivedsl::PositiveAssertReturnValue::Set(_))
|
||||
| (Self::Node, positivedsl::PositiveAssertReturnValue::Node(_)) => true,
|
||||
| (_, _) => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
impl std::fmt::Debug for PositiveNodeRelablerInput {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
| Self::Entities => write!(f, "entities"),
|
||||
| Self::Node => write!(f, "node"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl PrintableWithTranslator for PositiveNodeRelablerInput {
|
||||
fn print(
|
||||
&self,
|
||||
f: &mut std::fmt::Formatter,
|
||||
_translator: &translator::Translator,
|
||||
) -> std::fmt::Result {
|
||||
write!(f, "{self:?}")
|
||||
}
|
||||
}
|
||||
|
||||
impl positivedsl::PositiveAssert<PositiveNodeRelablerInput> {
|
||||
pub fn typecheck(&self) -> Result<(), String> {
|
||||
let mut context = positivedsl::TypeContext::new();
|
||||
let ty = positivedsl::typecheck(&self.tree, &mut context)?;
|
||||
match ty {
|
||||
| positivedsl::PositiveAssertionTypes::Boolean
|
||||
| positivedsl::PositiveAssertionTypes::Integer
|
||||
| positivedsl::PositiveAssertionTypes::String
|
||||
| positivedsl::PositiveAssertionTypes::Label
|
||||
| positivedsl::PositiveAssertionTypes::Set
|
||||
| positivedsl::PositiveAssertionTypes::PositiveElement
|
||||
| positivedsl::PositiveAssertionTypes::Edge
|
||||
| positivedsl::PositiveAssertionTypes::Node
|
||||
| positivedsl::PositiveAssertionTypes::System
|
||||
| positivedsl::PositiveAssertionTypes::Context => Ok(()),
|
||||
| positivedsl::PositiveAssertionTypes::NoType =>
|
||||
Err("No return type, at least one return statement required."
|
||||
.into()),
|
||||
| positivedsl::PositiveAssertionTypes::RangeInteger
|
||||
| positivedsl::PositiveAssertionTypes::RangeSet
|
||||
| positivedsl::PositiveAssertionTypes::RangeNeighbours =>
|
||||
Err(format!("Returned type {ty:?} is not a valid return type.")),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn execute(
|
||||
&self,
|
||||
graph: &graph::PositiveSystemGraph,
|
||||
node: &<graph::PositiveSystemGraph as petgraph::visit::GraphBase>::NodeId,
|
||||
translator: &mut translator::Translator,
|
||||
) -> Result<positivedsl::PositiveAssertReturnValue, String> {
|
||||
let system::PositiveSystem {
|
||||
available_entities: entities,
|
||||
..
|
||||
} = graph
|
||||
.node_weight(*node)
|
||||
.ok_or("Missing node {{debug: {node:?}}}")?;
|
||||
|
||||
let mut input_vals = HashMap::new();
|
||||
input_vals.insert(
|
||||
PositiveNodeRelablerInput::Entities,
|
||||
PositiveNodeRelablerInputValues::Entities(entities.clone()),
|
||||
);
|
||||
input_vals.insert(
|
||||
PositiveNodeRelablerInput::Node,
|
||||
PositiveNodeRelablerInputValues::Node(*node),
|
||||
);
|
||||
|
||||
let mut context = positivedsl::Context::new(input_vals);
|
||||
if let Some(v) = positivedsl::execute(&self.tree, &mut context, translator, graph)? {
|
||||
Ok(v)
|
||||
} else {
|
||||
Err("No value returned.".into())
|
||||
|
||||
Reference in New Issue
Block a user