Finished refactoring

This commit is contained in:
elvis
2025-08-24 03:35:32 +02:00
parent 3a4c4d43c2
commit 9a80044a89
11 changed files with 511 additions and 301 deletions

View File

@ -7,12 +7,12 @@ use super::super::{translator, graph, set, process, system, label};
/// AssertExpression /// AssertExpression
type IntegerType = i64; type IntegerType = i64;
#[derive(Debug, Clone)] #[derive(Clone)]
pub struct RSassert<S> { pub struct Assert<S> {
pub tree: Tree<S> pub tree: Tree<S>
} }
#[derive(Debug, Clone)] #[derive(Clone)]
pub enum Tree<S> { pub enum Tree<S> {
Concat(Box<Tree<S>>, Box<Tree<S>>), Concat(Box<Tree<S>>, Box<Tree<S>>),
If(Box<Expression<S>>, Box<Tree<S>>), If(Box<Expression<S>>, Box<Tree<S>>),
@ -22,15 +22,15 @@ pub enum Tree<S> {
For(Variable<S>, Range<S>, Box<Tree<S>>), For(Variable<S>, Range<S>, Box<Tree<S>>),
} }
#[derive(Debug, Clone, PartialEq, Eq, Hash)] #[derive(Clone, PartialEq, Eq, Hash)]
pub enum Variable<S> { pub enum Variable<S> {
Id(String), Id(String),
Special(S) Special(S)
} }
/// Trait needed for special variables. /// Trait needed for special variables.
pub(super) trait SpecialVariables<G>: std::fmt::Display + std::fmt::Debug pub(super) trait SpecialVariables<G>: translator::PrintableWithTranslator
+ Sized + Eq + Copy + std::hash::Hash + std::fmt::Debug + Sized + Eq + Copy + std::hash::Hash
{ {
/// Returns the type of the specific special variable. /// Returns the type of the specific special variable.
fn type_of(&self) -> AssertionTypes; fn type_of(&self) -> AssertionTypes;
@ -46,7 +46,7 @@ pub(super) trait SpecialVariables<G>: std::fmt::Display + std::fmt::Debug
fn correct_type(&self, other: &AssertReturnValue) -> bool; fn correct_type(&self, other: &AssertReturnValue) -> bool;
} }
#[derive(Debug, Clone)] #[derive(Clone)]
pub enum Expression<S> { pub enum Expression<S> {
True, True,
False, False,
@ -61,13 +61,13 @@ pub enum Expression<S> {
Binary(Binary, Box<Expression<S>>, Box<Expression<S>>), Binary(Binary, Box<Expression<S>>, Box<Expression<S>>),
} }
#[derive(Debug, Clone)] #[derive(Clone)]
pub enum Range<S> { pub enum Range<S> {
IterateOverSet(Box<Expression<S>>), IterateOverSet(Box<Expression<S>>),
IterateInRange(Box<Expression<S>>, Box<Expression<S>>), IterateInRange(Box<Expression<S>>, Box<Expression<S>>),
} }
#[derive(Debug, Clone, Copy)] #[derive(Clone, Copy)]
pub enum Unary { pub enum Unary {
Not, Not,
Rand, Rand,
@ -79,7 +79,7 @@ pub enum Unary {
Qualifier(Qualifier), Qualifier(Qualifier),
} }
#[derive(Debug, Clone, Copy)] #[derive(Clone, Copy)]
pub enum QualifierRestricted { pub enum QualifierRestricted {
Entities, Entities,
Context, Context,
@ -90,32 +90,32 @@ pub enum QualifierRestricted {
Products, Products,
} }
#[derive(Debug, Clone, Copy)] #[derive(Clone, Copy)]
pub enum QualifierLabel { pub enum QualifierLabel {
AvailableEntities, AvailableEntities,
AllReactants, AllReactants,
AllInhibitors, AllInhibitors,
} }
#[derive(Debug, Clone, Copy)] #[derive(Clone, Copy)]
pub enum QualifierSystem { pub enum QualifierSystem {
Entities, Entities,
Context, Context,
} }
#[derive(Debug, Clone, Copy)] #[derive(Clone, Copy)]
pub enum QualifierEdge { pub enum QualifierEdge {
Source, Source,
Target, Target,
} }
#[derive(Debug, Clone, Copy)] #[derive(Clone, Copy)]
pub enum QualifierNode { pub enum QualifierNode {
Neighbours, Neighbours,
System, System,
} }
#[derive(Debug, Clone, Copy)] #[derive(Clone, Copy)]
pub enum Qualifier { pub enum Qualifier {
System(QualifierSystem), System(QualifierSystem),
Label(QualifierLabel), Label(QualifierLabel),
@ -124,7 +124,7 @@ pub enum Qualifier {
Node(QualifierNode), Node(QualifierNode),
} }
#[derive(Debug, Clone, Copy)] #[derive(Clone, Copy)]
pub enum Binary { pub enum Binary {
And, And,
Or, Or,
@ -149,7 +149,7 @@ pub enum Binary {
CommonSubStr, CommonSubStr,
} }
#[derive(Debug, Copy, Clone, PartialEq, Eq)] #[derive(Copy, Clone, PartialEq, Eq)]
pub(super) enum AssertionTypes { pub(super) enum AssertionTypes {
Boolean, Boolean,
Integer, Integer,
@ -168,7 +168,7 @@ pub(super) enum AssertionTypes {
Edge, Edge,
} }
#[derive(Debug, Clone, Hash, PartialEq, Eq)] #[derive(Clone, Hash, PartialEq, Eq)]
pub enum AssertReturnValue { pub enum AssertReturnValue {
Boolean(bool), Boolean(bool),
Integer(IntegerType), Integer(IntegerType),
@ -335,7 +335,7 @@ impl Unary {
}, },
(op, type_exp) => { (op, type_exp) => {
Err(format!("Expression has incompatible type with operation: \ Err(format!("Expression has incompatible type with operation: \
{type_exp} with operation {op}.")) {type_exp:?} with operation {op:?}."))
} }
} }
} }
@ -473,8 +473,8 @@ impl Binary {
Ok(AssertionTypes::String) Ok(AssertionTypes::String)
}, },
_ => { _ => {
Err(format!("Expressions have incompatible types: {t1} and \ Err(format!("Expressions have incompatible types: {t1:?} and \
{t2} with operation {self}.")) {t2:?} with operation {self:?}."))
} }
} }
} }
@ -492,7 +492,8 @@ impl AssertReturnValue {
Ok(()) Ok(())
}, },
(s, q, val) => { (s, q, val) => {
Err(format!("Cannot assign {val} to {s} with qualifier {q}")) Err(format!("Cannot assign {val:?} to {s:?} with qualifier \
{q:?}"))
} }
} }
} }
@ -530,8 +531,8 @@ impl TypeContext {
if ty_return == ty { if ty_return == ty {
Ok(()) Ok(())
} else { } else {
Err(format!("Return statements don't agree: {ty_return} and \ Err(format!("Return statements don't agree: {ty_return:?} and \
{ty} found.")) {ty:?} found."))
} }
} else { } else {
self.return_ty = Some(ty); self.return_ty = Some(ty);
@ -556,8 +557,8 @@ impl TypeContext {
(Variable::Id(v), Some(q)) => { (Variable::Id(v), Some(q)) => {
match self.data.entry(v.clone()) { match self.data.entry(v.clone()) {
std::collections::hash_map::Entry::Vacant(_ve) => { std::collections::hash_map::Entry::Vacant(_ve) => {
Err(format!("Variable {v} as no assignment while \ Err(format!("Variable {v:?} as no assignment while \
trying to assign to qualification {q}, \ trying to assign to qualification {q:?}, \
assign first a value.")) assign first a value."))
}, },
std::collections::hash_map::Entry::Occupied(oe) => { std::collections::hash_map::Entry::Occupied(oe) => {
@ -568,9 +569,9 @@ impl TypeContext {
Ok(()) Ok(())
}, },
(t, q, ty) => { (t, q, ty) => {
Err(format!("Variable {v} has type {t}, but \ Err(format!("Variable {v:?} has type {t:?}, \
was assigned with qualifier {q} \ but was assigned with qualifier \
value with type {ty}")) {q:?} value with type {ty:?}."))
} }
} }
} }
@ -580,17 +581,18 @@ impl TypeContext {
if s.type_of() == ty { if s.type_of() == ty {
Ok(()) Ok(())
} else { } else {
Err(format!("Variable {s} has type {} but was \ Err(format!("Variable {s:?} has type {:?} but was \
assigned a value of type {ty}.", s.type_of())) assigned a value of type {ty:?}.",
s.type_of()))
} }
}, },
(Variable::Special(s), Some(q)) => { (Variable::Special(s), Some(q)) => {
if s.type_qualified(q)? == ty { if s.type_qualified(q)? == ty {
Ok(()) Ok(())
} else { } else {
Err(format!("Variable {s} has type {} but was \ Err(format!("Variable {s:?} has type {:?} but was \
assigned a value of type {ty} with qualifier \ assigned a value of type {ty:?} with \
{q}.", s.type_of())) qualifier {q:?}.", s.type_of()))
} }
} }
} }
@ -604,7 +606,7 @@ impl TypeContext {
where S: SpecialVariables<G> { where S: SpecialVariables<G> {
let v = match v { let v = match v {
Variable::Special(s) => Variable::Special(s) =>
return Err(format!("Protected word {s} used in for \ return Err(format!("Protected word {s:?} used in for \
assignment.")), assignment.")),
Variable::Id(v) => v Variable::Id(v) => v
}; };
@ -622,7 +624,7 @@ impl TypeContext {
Ok(()) Ok(())
}, },
_ => { _ => {
Err(format!("Range has incorrect type {ty}.")) Err(format!("Range has incorrect type {ty:?}."))
}, },
} }
} }
@ -640,7 +642,7 @@ impl TypeContext {
if let Some(ty) = self.data.get(v) { if let Some(ty) = self.data.get(v) {
Ok(*ty) Ok(*ty)
} else { } else {
Err(format!("Could not find variable {v}.")) Err(format!("Could not find variable {v:?}."))
} }
}, },
} }
@ -671,8 +673,8 @@ impl<S> Context<S> {
(Variable::Id(v), Some(q)) => { (Variable::Id(v), Some(q)) => {
match self.data.entry(v.clone()) { match self.data.entry(v.clone()) {
std::collections::hash_map::Entry::Vacant(_ve) => { std::collections::hash_map::Entry::Vacant(_ve) => {
Err(format!("Variable {v} as no assignment while \ Err(format!("Variable {v:?} as no assignment while \
trying to assign to qualification {q}, \ trying to assign to qualification {q:?}, \
assign first a value.")) assign first a value."))
}, },
std::collections::hash_map::Entry::Occupied(mut oe) => { std::collections::hash_map::Entry::Occupied(mut oe) => {
@ -684,9 +686,9 @@ impl<S> Context<S> {
Ok(()) Ok(())
}, },
(val, q, newval) => { (val, q, newval) => {
Err(format!("Variable {v} has value {val}, but \ Err(format!("Variable {v:?} has value {val:?}, \
was assigned with qualifier {q} \ but was assigned with qualifier \
new value {newval}.")) {q:?} new value {newval:?}."))
} }
} }
} }
@ -701,16 +703,16 @@ impl<S> Context<S> {
} }
Ok(()) Ok(())
} else { } else {
Err(format!("Trying to assign {val} to variable {s}.")) Err(format!("Trying to assign {val:?} to variable {s:?}."))
} }
}, },
(Variable::Special(s), Some(q)) => { (Variable::Special(s), Some(q)) => {
if let Some(s) = self.special.get_mut(s) { if let Some(s) = self.special.get_mut(s) {
s.assign_qualified(*q, val) s.assign_qualified(*q, val)
} else { } else {
Err(format!("Trying to assign {val} to variable {s} with \ Err(format!("Trying to assign {val:?} to variable {s:?} \
qualifier {q} but no value for {val} was found\ with qualifier {q:?} but no value for {val:?} \
.")) was found."))
} }
} }
} }
@ -725,12 +727,14 @@ impl<S> Context<S> {
Variable::Id(var) => { Variable::Id(var) => {
self.data.get(var) self.data.get(var)
.cloned() .cloned()
.ok_or(format!("Variable {v} used, but no value assigned.")) .ok_or(format!("Variable {v:?} used, but no value \
assigned."))
}, },
Variable::Special(s) => { Variable::Special(s) => {
self.special.get(s) self.special.get(s)
.cloned() .cloned()
.ok_or(format!("Variable {v} used but no value assigned.")) .ok_or(format!("Variable {v:?} used but no value \
assigned."))
}, },
} }
} }
@ -771,7 +775,7 @@ impl AssertReturnValue {
(AssertReturnValue::Element(el), Unary::ToStr) => { (AssertReturnValue::Element(el), Unary::ToStr) => {
Ok(AssertReturnValue::String( Ok(AssertReturnValue::String(
translator.decode(el).ok_or( translator.decode(el).ok_or(
format!("Could not find element {el}.") format!("Could not find element {el:?}.")
)? )?
)) ))
}, },
@ -811,7 +815,8 @@ impl AssertReturnValue {
Ok(q.get(&sys)) Ok(q.get(&sys))
} }
(val, u) => { (val, u) => {
Err(format!("Incompatible unary operation {u} on value {val}.")) Err(format!("Incompatible unary operation {u:?} on value \
{val:?}."))
} }
} }
} }
@ -897,8 +902,8 @@ impl AssertReturnValue {
String(s) String(s)
}, },
(b, val1, val2) => (b, val1, val2) =>
return Err(format!("Operation {b} on values {val1} and {val2} \ return Err(format!("Operation {b:?} on values {val1:?} and \
could not be executed.")) {val2:?} could not be executed."))
}) })
} }
} }
@ -1008,7 +1013,7 @@ where S: SpecialVariables<G> {
Ok(AssertionTypes::RangeInteger) Ok(AssertionTypes::RangeInteger)
} else { } else {
Err(format!("Expressions in range are not integers, but are: \ Err(format!("Expressions in range are not integers, but are: \
{type_exp1} and {type_exp2}.")) {type_exp1:?} and {type_exp2:?}."))
} }
}, },
Range::IterateOverSet(exp) => { Range::IterateOverSet(exp) => {
@ -1019,7 +1024,7 @@ where S: SpecialVariables<G> {
AssertionTypes::RangeNeighbours => AssertionTypes::RangeNeighbours =>
Ok(AssertionTypes::RangeNeighbours), Ok(AssertionTypes::RangeNeighbours),
_ => Err(format!("Expressions in range is not a set or \ _ => Err(format!("Expressions in range is not a set or \
neighbours of a node, but is: {type_exp}.")) neighbours of a node, but is: {type_exp:?}."))
} }
} }
} }
@ -1106,7 +1111,7 @@ where S: SpecialVariables<G> {
.collect::<Vec<_>>() .collect::<Vec<_>>()
.into_iter()) .into_iter())
} }
_ => Err(format!("{val} is not a set in for cycle.")) _ => Err(format!("{val:?} is not a set in for cycle."))
} }
}, },
Range::IterateInRange(exp1, exp2) => { Range::IterateInRange(exp1, exp2) => {
@ -1118,8 +1123,8 @@ where S: SpecialVariables<G> {
Ok((i1..i2).map(AssertReturnValue::Integer) Ok((i1..i2).map(AssertReturnValue::Integer)
.collect::<Vec<_>>().into_iter()), .collect::<Vec<_>>().into_iter()),
(val1, val2) => (val1, val2) =>
Err(format!("{val1}..{val2} is not a valid integer range \ Err(format!("{val1:?}..{val2:?} is not a valid integer \
in for cycle.")) range in for cycle."))
} }
} }
} }

View File

@ -3,44 +3,47 @@
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
use std::fmt; use std::fmt;
use super::dsl::*; use super::dsl::*;
use super::super::translator::{Formatter, PrintableWithTranslator, Translator};
impl<S> fmt::Display for RSassert<S> where S: fmt::Display { impl<S> fmt::Debug for Assert<S> where S: fmt::Debug {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "label {{\n{}\n}}", self.tree) write!(f, "label {{\n{:?}\n}}", self.tree)
} }
} }
impl<S> fmt::Display for Tree<S> where S: fmt::Display { impl<S> fmt::Debug for Tree<S> where S: fmt::Debug {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self { match self {
Self::Concat(t1, t2) => {write!(f, "{t1};\n{t2}")}, Self::Concat(t1, t2) => {write!(f, "{t1:?};\n{t2:?}")},
Self::If(exp, t) => {write!(f, "if {exp} {{\n{t}\n}}")}, Self::If(exp, t) => {write!(f, "if {exp:?} {{\n{t:?}\n}}")},
Self::IfElse(exp, t1, t2) => { Self::IfElse(exp, t1, t2) => {
write!(f, "if {exp} {{\n{t1}\n}} else {{\n{t2}\n}}") write!(f, "if {exp:?} {{\n{t1:?}\n}} else {{\n{t2:?}\n}}")
}, },
Self::Assignment(v, q, exp) => { Self::Assignment(v, q, exp) => {
if let Some(q) = q { if let Some(q) = q {
write!(f, "{v}.{q} = {exp}") write!(f, "{v:?}.{q:?} = {exp:?}")
} else { } else {
write!(f, "{v} = {exp}") write!(f, "{v:?} = {exp:?}")
} }
}, },
Self::Return(exp) => {write!(f, "return {exp}")}, Self::Return(exp) => {write!(f, "return {exp:?}")},
Self::For(v, r, t) => {write!(f, "for {v} in {r} {{\n{t}\n}}")}, Self::For(v, r, t) => {
write!(f, "for {v:?} in {r:?} {{\n{t:?}\n}}")
},
} }
} }
} }
impl<S> fmt::Display for Variable<S> where S: fmt::Display { impl<S> fmt::Debug for Variable<S> where S: fmt::Debug {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self { match self {
Self::Special(s) => {write!(f, "{s}")}, Self::Special(s) => {write!(f, "{s:?}")},
Self::Id(s) => {write!(f, "{s}")} Self::Id(s) => {write!(f, "{s:?}")}
} }
} }
} }
impl<S> fmt::Display for Expression<S> where S: fmt::Display { impl<S> fmt::Debug for Expression<S> where S: fmt::Debug {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self { match self {
Self::True => {write!(f, "True")}, Self::True => {write!(f, "True")},
@ -49,24 +52,24 @@ impl<S> fmt::Display for Expression<S> where S: fmt::Display {
Self::Label(rslabel) => {write!(f, "{{debug: {rslabel:?}}}")}, Self::Label(rslabel) => {write!(f, "{{debug: {rslabel:?}}}")},
Self::Set(set) => {write!(f, "{{debug: {set:?}}}")}, Self::Set(set) => {write!(f, "{{debug: {set:?}}}")},
Self::Element(el) => {write!(f, "'{{debug: {el:?}}}'")}, Self::Element(el) => {write!(f, "'{{debug: {el:?}}}'")},
Self::String(s) => {write!(f, r#""{s}""#)}, Self::String(s) => {write!(f, r#""{s:?}""#)},
Self::Var(v) => {write!(f, "{v}")}, Self::Var(v) => {write!(f, "{v:?}")},
Self::Unary(u, exp) => { Self::Unary(u, exp) => {
if u.is_prefix() { if u.is_prefix() {
write!(f, "{u}({exp})") write!(f, "{u:?}({exp:?})")
} else if u.is_suffix() { } else if u.is_suffix() {
write!(f, "{exp}{u}") write!(f, "{exp:?}{u:?}")
} else { } else {
unreachable!() unreachable!()
} }
}, },
Self::Binary(b, exp1, exp2) => { Self::Binary(b, exp1, exp2) => {
if b.is_prefix() { if b.is_prefix() {
write!(f, "{b}({exp1}, {exp2})") write!(f, "{b:?}({exp1:?}, {exp2:?})")
} else if b.is_suffix() { } else if b.is_suffix() {
write!(f, "({exp1}, {exp2}){b}") write!(f, "({exp1:?}, {exp2:?}){b:?}")
} else if b.is_infix() { } else if b.is_infix() {
write!(f, "({exp1} {b} {exp2})") write!(f, "({exp1:?} {b:?} {exp2:?})")
} else { } else {
unreachable!() unreachable!()
} }
@ -75,16 +78,16 @@ impl<S> fmt::Display for Expression<S> where S: fmt::Display {
} }
} }
impl<S> fmt::Display for Range<S> where S: fmt::Display { impl<S> fmt::Debug for Range<S> where S: fmt::Debug {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self { match self {
Self::IterateOverSet(exp) => {write!(f, "{{{exp}}}")}, Self::IterateOverSet(exp) => write!(f, "{{{exp:?}}}"),
Self::IterateInRange(exp1, exp2) => {write!(f, "{exp1}..{exp2}")} Self::IterateInRange(exp1, exp2) => write!(f, "{exp1:?}..{exp2:?}")
} }
} }
} }
impl fmt::Display for Unary { impl fmt::Debug for Unary {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self { match self {
Self::Not => write!(f, "not"), Self::Not => write!(f, "not"),
@ -93,12 +96,12 @@ impl fmt::Display for Unary {
Self::Length => write!(f, ".length"), Self::Length => write!(f, ".length"),
Self::ToStr => write!(f, ".tostr"), Self::ToStr => write!(f, ".tostr"),
Self::ToEl => write!(f, ".toel"), Self::ToEl => write!(f, ".toel"),
Self::Qualifier(q) => write!(f, ".{q}"), Self::Qualifier(q) => write!(f, ".{q:?}"),
} }
} }
} }
impl fmt::Display for QualifierRestricted { impl fmt::Debug for QualifierRestricted {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self { match self {
Self::Entities => write!(f, "Entities"), Self::Entities => write!(f, "Entities"),
@ -112,7 +115,7 @@ impl fmt::Display for QualifierRestricted {
} }
} }
impl fmt::Display for QualifierLabel { impl fmt::Debug for QualifierLabel {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self { match self {
Self::AvailableEntities => write!(f, "AvailableEntities"), Self::AvailableEntities => write!(f, "AvailableEntities"),
@ -122,7 +125,7 @@ impl fmt::Display for QualifierLabel {
} }
} }
impl fmt::Display for QualifierSystem { impl fmt::Debug for QualifierSystem {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self { match self {
Self::Context => write!(f, "context"), Self::Context => write!(f, "context"),
@ -131,7 +134,7 @@ impl fmt::Display for QualifierSystem {
} }
} }
impl fmt::Display for QualifierEdge { impl fmt::Debug for QualifierEdge {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self { match self {
Self::Source => write!(f, "source"), Self::Source => write!(f, "source"),
@ -140,7 +143,7 @@ impl fmt::Display for QualifierEdge {
} }
} }
impl fmt::Display for QualifierNode { impl fmt::Debug for QualifierNode {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self { match self {
Self::Neighbours => write!(f, "neighbours"), Self::Neighbours => write!(f, "neighbours"),
@ -149,19 +152,19 @@ impl fmt::Display for QualifierNode {
} }
} }
impl fmt::Display for Qualifier { impl fmt::Debug for Qualifier {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self { match self {
Self::Label(q) => write!(f, "{q}"), Self::Label(q) => write!(f, "{q:?}"),
Self::Restricted(q) => write!(f, "{q}"), Self::Restricted(q) => write!(f, "{q:?}"),
Self::System(q) => write!(f, "{q}"), Self::System(q) => write!(f, "{q:?}"),
Self::Edge(q) => write!(f, "{q}"), Self::Edge(q) => write!(f, "{q:?}"),
Self::Node(q) => write!(f, "{q}"), Self::Node(q) => write!(f, "{q:?}"),
} }
} }
} }
impl fmt::Display for Binary { impl fmt::Debug for Binary {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self { match self {
Self::And => write!(f, "&&"), Self::And => write!(f, "&&"),
@ -188,12 +191,12 @@ impl fmt::Display for Binary {
} }
} }
impl fmt::Display for AssertReturnValue { impl fmt::Debug for AssertReturnValue {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self { match self {
Self::Boolean(b) => write!(f, "{b}"), Self::Boolean(b) => write!(f, "{b:?}"),
Self::Integer(i) => write!(f, "{i}"), Self::Integer(i) => write!(f, "{i:?}"),
Self::String(s) => write!(f, r#""{s}""#), Self::String(s) => write!(f, r#""{s:?}""#),
Self::Label(l) => write!(f, "{{debug: {l:?}}}"), Self::Label(l) => write!(f, "{{debug: {l:?}}}"),
Self::Set(set) => write!(f, "{{debug: {set:?}}}"), Self::Set(set) => write!(f, "{{debug: {set:?}}}"),
Self::Element(el) => write!(f, "{{debug: {el:?}}}"), Self::Element(el) => write!(f, "{{debug: {el:?}}}"),
@ -207,7 +210,7 @@ impl fmt::Display for AssertReturnValue {
} }
} }
impl fmt::Display for AssertionTypes { impl fmt::Debug for AssertionTypes {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self { match self {
Self::Boolean => write!(f, "boolean"), Self::Boolean => write!(f, "boolean"),
@ -227,3 +230,245 @@ impl fmt::Display for AssertionTypes {
} }
} }
} }
// -----------------------------------------------------------------------------
impl<S> PrintableWithTranslator for Assert<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 Tree<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 Variable<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 Expression<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::Element(el) =>
write!(f, "'{}'",
translator.decode(*el).unwrap_or("Missing".into())),
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 Range<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 Unary {
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 Qualifier {
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 Binary {
fn print(&self, f: &mut fmt::Formatter, _translator: &Translator)
-> fmt::Result {
write!(f, "{self:?}")
}
}
impl PrintableWithTranslator for AssertReturnValue {
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::Element(el) =>
write!(f, "{}",
translator.decode(*el).unwrap_or("Missing".into())),
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 AssertionTypes {
fn print(&self, f: &mut fmt::Formatter, _translator: &Translator)
-> fmt::Result {
write!(f, "{self:?}")
}
}

View File

@ -1,6 +1,10 @@
pub mod dsl; pub mod dsl;
pub mod rsassert; pub mod rsassert;
pub mod types {
pub use super::rsassert::useful_types_edge_relabeler::*;
}
mod fmt; mod fmt;
#[cfg(test)] #[cfg(test)]

View File

@ -1,3 +1,5 @@
use crate::rsprocess::translator::PrintableWithTranslator;
use super::dsl::*; use super::dsl::*;
use super::super::{translator, graph, set, system, label}; use super::super::{translator, graph, set, system, label};
use std::collections::HashMap; use std::collections::HashMap;
@ -23,7 +25,7 @@ pub mod useful_types_edge_relabeler {
}; };
} }
export_types!(RSassert, Tree, Variable, Expression, Range); export_types!(Assert, Tree, Variable, Expression, Range);
export_types_no_parameter!(Unary, QualifierRestricted, QualifierLabel, export_types_no_parameter!(Unary, QualifierRestricted, QualifierLabel,
QualifierSystem, QualifierEdge, QualifierNode, QualifierSystem, QualifierEdge, QualifierNode,
@ -35,13 +37,13 @@ pub mod useful_types_edge_relabeler {
// Implementation for graph labeling in bisimulation. // Implementation for graph labeling in bisimulation.
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] #[derive(Copy, Clone, PartialEq, Eq, Hash)]
pub enum EdgeRelablerInput { pub enum EdgeRelablerInput {
Label, Label,
Edge, Edge,
} }
#[derive(Debug, Clone)] #[derive(Clone)]
enum EdgeRelablerInputValues { enum EdgeRelablerInputValues {
Label(label::Label), Label(label::Label),
Edge(petgraph::graph::EdgeIndex), Edge(petgraph::graph::EdgeIndex),
@ -61,7 +63,7 @@ impl SpecialVariables<EdgeRelablerInputValues> for EdgeRelablerInput {
(Self::Label, Qualifier::Restricted(_)) => (Self::Label, Qualifier::Restricted(_)) =>
Ok(AssertionTypes::Set), Ok(AssertionTypes::Set),
(s, q) => (s, q) =>
Err(format!("Wrong use of qualifier {q} on variable {s}.")) Err(format!("Wrong use of qualifier {q:?} on variable {s:?}."))
} }
} }
@ -86,7 +88,7 @@ impl SpecialVariables<EdgeRelablerInputValues> for EdgeRelablerInput {
} }
} }
impl std::fmt::Display for EdgeRelablerInput { impl std::fmt::Debug for EdgeRelablerInput {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self { match self {
Self::Label => write!(f, "label"), Self::Label => write!(f, "label"),
@ -95,7 +97,16 @@ impl std::fmt::Display for EdgeRelablerInput {
} }
} }
impl RSassert<EdgeRelablerInput> { impl PrintableWithTranslator for EdgeRelablerInput {
fn print(&self,
f: &mut std::fmt::Formatter,
_translator: &translator::Translator)
-> std::fmt::Result {
write!(f, "{self:?}")
}
}
impl Assert<EdgeRelablerInput> {
pub fn typecheck(&self) -> Result<(), String> { pub fn typecheck(&self) -> Result<(), String> {
let mut context = TypeContext::new(); let mut context = TypeContext::new();
let ty = typecheck(&self.tree, &mut context)?; let ty = typecheck(&self.tree, &mut context)?;
@ -113,11 +124,12 @@ impl RSassert<EdgeRelablerInput> {
Ok(()), Ok(()),
AssertionTypes::NoType => AssertionTypes::NoType =>
Err("No return type, at least one return statement \ Err("No return type, at least one return statement \
required.".into()), required.".into()),
AssertionTypes::RangeInteger | AssertionTypes::RangeInteger |
AssertionTypes::RangeSet | AssertionTypes::RangeSet |
AssertionTypes::RangeNeighbours => AssertionTypes::RangeNeighbours =>
Err(format!("Returned type {ty} is not a valid return type.")), Err(format!("Returned type {ty:?} is not a valid return \
type.")),
} }
} }
@ -149,13 +161,13 @@ impl RSassert<EdgeRelablerInput> {
// Implementation for node grouping. // Implementation for node grouping.
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] #[derive(Copy, Clone, PartialEq, Eq, Hash)]
pub enum NodeRelablerInput { pub enum NodeRelablerInput {
Entities, Entities,
Node, Node,
} }
#[derive(Debug, Clone)] #[derive(Clone)]
enum NodeRelablerInputValues { enum NodeRelablerInputValues {
Entities(set::Set), Entities(set::Set),
Node(petgraph::graph::NodeIndex), Node(petgraph::graph::NodeIndex),
@ -176,7 +188,7 @@ impl SpecialVariables<NodeRelablerInputValues> for NodeRelablerInput {
(Self::Node, Qualifier::Node(QualifierNode::Neighbours)) => (Self::Node, Qualifier::Node(QualifierNode::Neighbours)) =>
Ok(AssertionTypes::RangeNeighbours), Ok(AssertionTypes::RangeNeighbours),
(s, q) => (s, q) =>
Err(format!("Wrong use of qualifier {q} on variable {s}.")) Err(format!("Wrong use of qualifier {q:?} on variable {s:?}."))
} }
} }
@ -201,7 +213,7 @@ impl SpecialVariables<NodeRelablerInputValues> for NodeRelablerInput {
} }
} }
impl std::fmt::Display for NodeRelablerInput { impl std::fmt::Debug for NodeRelablerInput {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self { match self {
Self::Entities => write!(f, "entities"), Self::Entities => write!(f, "entities"),
@ -210,8 +222,17 @@ impl std::fmt::Display for NodeRelablerInput {
} }
} }
impl PrintableWithTranslator for NodeRelablerInput {
fn print(&self,
f: &mut std::fmt::Formatter,
_translator: &translator::Translator)
-> std::fmt::Result {
write!(f, "{self:?}")
}
}
impl RSassert<NodeRelablerInput> {
impl Assert<NodeRelablerInput> {
pub fn typecheck(&self) -> Result<(), String> { pub fn typecheck(&self) -> Result<(), String> {
let mut context = TypeContext::new(); let mut context = TypeContext::new();
let ty = typecheck(&self.tree, &mut context)?; let ty = typecheck(&self.tree, &mut context)?;
@ -233,7 +254,8 @@ impl RSassert<NodeRelablerInput> {
AssertionTypes::RangeInteger | AssertionTypes::RangeInteger |
AssertionTypes::RangeSet | AssertionTypes::RangeSet |
AssertionTypes::RangeNeighbours => AssertionTypes::RangeNeighbours =>
Err(format!("Returned type {ty} is not a valid return type.")), Err(format!("Returned type {ty:?} is not a valid return \
type.")),
} }
} }

View File

@ -7,7 +7,7 @@ use super::super::{ environment,
label }; label };
use super::rsassert::*; use super::rsassert::*;
type LocalAssert = RSassert<EdgeRelablerInput>; type LocalAssert = Assert<EdgeRelablerInput>;
#[test] #[test]
fn return_true() { fn return_true() {

View File

@ -2,9 +2,8 @@ use std::rc::Rc;
use std::str::FromStr; use std::str::FromStr;
use lalrpop_util::ParseError; use lalrpop_util::ParseError;
use crate::rsprocess::{set, reaction, process, environment, system, label}; use crate::rsprocess::{set, reaction, process, environment, system, label};
use crate::rsprocess::structure::rsassert; use crate::rsprocess::assert::types;
use crate::rsprocess::translator::{ Translator, IdType }; use crate::rsprocess::translator::{ Translator, IdType };
use crate::rsprocess::presets::Instructions;
use crate::rsprocess::presets; use crate::rsprocess::presets;
use crate::rsprocess::graph; use crate::rsprocess::graph;
@ -270,181 +269,181 @@ Env_term: (IdType, process::Process) = {
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// AssertParser // AssertParser
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
pub Assert: Box<rsassert::RSassert> = { pub Assert: Box<types::Assert> = {
"label" "{" <f: AssertTree> "}" => "label" "{" <f: AssertTree> "}" =>
Box::new(rsassert::RSassert{tree: f}), Box::new(types::Assert{tree: f}),
}; };
AssertTree: rsassert::Tree = { AssertTree: types::Tree = {
<t1: AssertTree2> ";" <t2: AssertTree> => <t1: AssertTree2> ";" <t2: AssertTree> =>
rsassert::Tree::Concat(Box::new(t1), Box::new(t2)), types::Tree::Concat(Box::new(t1), Box::new(t2)),
<t: AssertTree2> => t, <t: AssertTree2> => t,
} }
AssertTree2: rsassert::Tree = { AssertTree2: types::Tree = {
#[precedence(level="1")] #[precedence(level="1")]
"if" <e: AssertExpression> "if" <e: AssertExpression>
"then" "{" <t: AssertTree> "}" => "then" "{" <t: AssertTree> "}" =>
rsassert::Tree::If(Box::new(e), Box::new(t)), types::Tree::If(Box::new(e), Box::new(t)),
#[precedence(level="0")] #[precedence(level="0")]
"if" <e: AssertExpression> "if" <e: AssertExpression>
"then" "{" <t1: AssertTree> "}" "then" "{" <t1: AssertTree> "}"
"else" "{" <t2: AssertTree> "}" => "else" "{" <t2: AssertTree> "}" =>
rsassert::Tree::IfElse(Box::new(e), Box::new(t1), Box::new(t2)), types::Tree::IfElse(Box::new(e), Box::new(t1), Box::new(t2)),
#[precedence(level="2")] #[precedence(level="2")]
"let" <v: AssertVariable> <q: AssertQualifier?> "=" <e: AssertExpression> => "let" <v: AssertVariable> <q: AssertQualifier?> "=" <e: AssertExpression> =>
rsassert::Tree::Assignment(v, q, Box::new(e)), types::Tree::Assignment(v, q, Box::new(e)),
#[precedence(level="3")] #[precedence(level="3")]
"return" <e: AssertExpression> => "return" <e: AssertExpression> =>
rsassert::Tree::Return(Box::new(e)), types::Tree::Return(Box::new(e)),
#[precedence(level="4")] #[precedence(level="4")]
"for" <v: AssertVariable> "in" <r: AssertRange> "{" <t: AssertTree> "}" => "for" <v: AssertVariable> "in" <r: AssertRange> "{" <t: AssertTree> "}" =>
rsassert::Tree::For(v, r, Box::new(t)), types::Tree::For(v, r, Box::new(t)),
} }
AssertVariable: rsassert::Variable = { AssertVariable: types::Variable = {
#[precedence(level="0")] #[precedence(level="0")]
"label" => rsassert::Variable::Special(rsassert::Special::Label), "label" => types::Variable::Special(types::Special::Label),
#[precedence(level="1")] #[precedence(level="1")]
"edge" => rsassert::Variable::Special(rsassert::Special::Edge), "edge" => types::Variable::Special(types::Special::Edge),
#[precedence(level="2")] #[precedence(level="2")]
<v: Literal> => rsassert::Variable::Id(v), <v: Literal> => types::Variable::Id(v),
} }
AssertExpression: rsassert::Expression = { AssertExpression: types::Expression = {
// Unary // Unary
#[precedence(level="0")] #[precedence(level="0")]
<unp: AssertUnaryPrefix> <e: AssertExpression> => <unp: AssertUnaryPrefix> <e: AssertExpression> =>
rsassert::Expression::Unary(unp, Box::new(e)), types::Expression::Unary(unp, Box::new(e)),
#[precedence(level="2")] #[precedence(level="2")]
<e: AssertExpression> <uns: AssertUnarySuffix> => <e: AssertExpression> <uns: AssertUnarySuffix> =>
rsassert::Expression::Unary(uns, Box::new(e)), types::Expression::Unary(uns, Box::new(e)),
// binary // binary
#[precedence(level="3")] #[assoc(side="left")] #[precedence(level="3")] #[assoc(side="left")]
<e1: AssertExpression> <b: AssertBinary> <e2: AssertExpression> => <e1: AssertExpression> <b: AssertBinary> <e2: AssertExpression> =>
rsassert::Expression::Binary(b, Box::new(e1), Box::new(e2)), types::Expression::Binary(b, Box::new(e1), Box::new(e2)),
#[precedence(level="1")] #[precedence(level="1")]
<b: AssertBinaryPrefix> <b: AssertBinaryPrefix>
"(" <e1: AssertExpression> "," <e2: AssertExpression> ")" => "(" <e1: AssertExpression> "," <e2: AssertExpression> ")" =>
rsassert::Expression::Binary(b, Box::new(e1), Box::new(e2)), types::Expression::Binary(b, Box::new(e1), Box::new(e2)),
#[precedence(level="4")] #[precedence(level="4")]
"(" <e: AssertExpression> ")" => e, "(" <e: AssertExpression> ")" => e,
"true" => rsassert::Expression::True, "true" => types::Expression::True,
"false" => rsassert::Expression::False, "false" => types::Expression::False,
#[precedence(level="5")] #[precedence(level="5")]
<v: AssertVariable> => rsassert::Expression::Var(v), <v: AssertVariable> => types::Expression::Var(v),
// If changing IntegerType in assert.rs, also change from Num to another // If changing IntegerType in assert.rs, also change from Num to another
// similar parser with different return type // similar parser with different return type
#[precedence(level="6")] #[precedence(level="6")]
<i: Num> => rsassert::Expression::Integer(i), <i: Num> => types::Expression::Integer(i),
#[precedence(level="7")] #[precedence(level="7")]
<lab: AssertLabel> => rsassert::Expression::Label(Box::new(lab)), <lab: AssertLabel> => types::Expression::Label(Box::new(lab)),
<set: Set_of_entities> => rsassert::Expression::Set(set), <set: Set_of_entities> => types::Expression::Set(set),
"'" <el: Literal> "'" => rsassert::Expression::Element(translator.encode(el)), "'" <el: Literal> "'" => types::Expression::Element(translator.encode(el)),
// strings // strings
#[precedence(level="8")] #[precedence(level="8")]
PATH => rsassert::Expression::String(<>.trim_end_matches("\"") PATH => types::Expression::String(<>.trim_end_matches("\"")
.trim_start_matches("\"") .trim_start_matches("\"")
.to_string()), .to_string()),
} }
AssertRange: rsassert::Range = { AssertRange: types::Range = {
"{" <e: AssertExpression> "}" => rsassert::Range::IterateOverSet(Box::new(e)), "{" <e: AssertExpression> "}" => types::Range::IterateOverSet(Box::new(e)),
"{" <e1: AssertExpression> ".." <e2: AssertExpression> "}" => "{" <e1: AssertExpression> ".." <e2: AssertExpression> "}" =>
rsassert::Range::IterateInRange(Box::new(e1), Box::new(e2)), types::Range::IterateInRange(Box::new(e1), Box::new(e2)),
} }
AssertUnaryPrefix: rsassert::Unary = { AssertUnaryPrefix: types::Unary = {
"not" => rsassert::Unary::Not, "not" => types::Unary::Not,
"rand" => rsassert::Unary::Rand, "rand" => types::Unary::Rand,
} }
AssertUnarySuffix: rsassert::Unary = { AssertUnarySuffix: types::Unary = {
#[precedence(level="0")] #[precedence(level="0")]
"." "empty" => rsassert::Unary::Empty, "." "empty" => types::Unary::Empty,
"." "length" => rsassert::Unary::Length, "." "length" => types::Unary::Length,
"." "tostr" => rsassert::Unary::ToStr, "." "tostr" => types::Unary::ToStr,
"." "toel" => rsassert::Unary::ToEl, "." "toel" => types::Unary::ToEl,
#[precedence(level="1")] #[precedence(level="1")]
"." <q: AssertQualifier> => rsassert::Unary::Qualifier(q), "." <q: AssertQualifier> => types::Unary::Qualifier(q),
} }
AssertQualifierRestricted: rsassert::QualifierRestricted = { AssertQualifierRestricted: types::QualifierRestricted = {
"Entities" => rsassert::QualifierRestricted::Entities, "Entities" => types::QualifierRestricted::Entities,
"Context" => rsassert::QualifierRestricted::Context, "Context" => types::QualifierRestricted::Context,
"Reactants" => rsassert::QualifierRestricted::Reactants, "Reactants" => types::QualifierRestricted::Reactants,
"ReactantsAbsent" => rsassert::QualifierRestricted::ReactantsAbsent, "ReactantsAbsent" => types::QualifierRestricted::ReactantsAbsent,
"Inhibitors" => rsassert::QualifierRestricted::Inhibitors, "Inhibitors" => types::QualifierRestricted::Inhibitors,
"InhibitorsPresent" => rsassert::QualifierRestricted::InhibitorsPresent, "InhibitorsPresent" => types::QualifierRestricted::InhibitorsPresent,
"Products" => rsassert::QualifierRestricted::Products, "Products" => types::QualifierRestricted::Products,
} }
AssertQualifierLabel: rsassert::QualifierLabel = { AssertQualifierLabel: types::QualifierLabel = {
"AvailableEntities" => rsassert::QualifierLabel::AvailableEntities, "AvailableEntities" => types::QualifierLabel::AvailableEntities,
"AllReactants" => rsassert::QualifierLabel::AllReactants, "AllReactants" => types::QualifierLabel::AllReactants,
"AllInhibitors" => rsassert::QualifierLabel::AllInhibitors, "AllInhibitors" => types::QualifierLabel::AllInhibitors,
} }
AssertQualifierSystem: rsassert::QualifierSystem = { AssertQualifierSystem: types::QualifierSystem = {
"SystemEntities" => rsassert::QualifierSystem::Entities, "SystemEntities" => types::QualifierSystem::Entities,
"SystemContext" => rsassert::QualifierSystem::Context, "SystemContext" => types::QualifierSystem::Context,
} }
AssertQualifierEdge: rsassert::QualifierEdge = { AssertQualifierEdge: types::QualifierEdge = {
"source" => rsassert::QualifierEdge::Source, "source" => types::QualifierEdge::Source,
"target" => rsassert::QualifierEdge::Target, "target" => types::QualifierEdge::Target,
} }
AssertQualifierNode: rsassert::QualifierNode = { AssertQualifierNode: types::QualifierNode = {
"neighbours" => rsassert::QualifierNode::Neighbours, "neighbours" => types::QualifierNode::Neighbours,
"system" => rsassert::QualifierNode::System, "system" => types::QualifierNode::System,
} }
AssertQualifier: rsassert::Qualifier = { AssertQualifier: types::Qualifier = {
<q: AssertQualifierSystem> => rsassert::Qualifier::System(q), <q: AssertQualifierSystem> => types::Qualifier::System(q),
<q: AssertQualifierLabel> => rsassert::Qualifier::Label(q), <q: AssertQualifierLabel> => types::Qualifier::Label(q),
<q: AssertQualifierRestricted> => rsassert::Qualifier::Restricted(q), <q: AssertQualifierRestricted> => types::Qualifier::Restricted(q),
<q: AssertQualifierEdge> => rsassert::Qualifier::Edge(q), <q: AssertQualifierEdge> => types::Qualifier::Edge(q),
<q: AssertQualifierNode> => rsassert::Qualifier::Node(q), <q: AssertQualifierNode> => types::Qualifier::Node(q),
} }
AssertBinary: rsassert::Binary = { AssertBinary: types::Binary = {
"&&" => rsassert::Binary::And, "&&" => types::Binary::And,
"||" => rsassert::Binary::Or, "||" => types::Binary::Or,
"^^" => rsassert::Binary::Xor, "^^" => types::Binary::Xor,
"<" => rsassert::Binary::Less, "<" => types::Binary::Less,
"<=" => rsassert::Binary::LessEq, "<=" => types::Binary::LessEq,
">" => rsassert::Binary::More, ">" => types::Binary::More,
">=" => rsassert::Binary::MoreEq, ">=" => types::Binary::MoreEq,
"==" => rsassert::Binary::Eq, "==" => types::Binary::Eq,
"!=" => rsassert::Binary::NotEq, "!=" => types::Binary::NotEq,
"+" => rsassert::Binary::Plus, "+" => types::Binary::Plus,
"-" => rsassert::Binary::Minus, "-" => types::Binary::Minus,
"*" => rsassert::Binary::Times, "*" => types::Binary::Times,
"^" => rsassert::Binary::Exponential, "^" => types::Binary::Exponential,
"/" => rsassert::Binary::Quotient, "/" => types::Binary::Quotient,
"%" => rsassert::Binary::Reminder, "%" => types::Binary::Reminder,
"::" => rsassert::Binary::Concat, "::" => types::Binary::Concat,
} }
AssertBinaryPrefix: rsassert::Binary = { AssertBinaryPrefix: types::Binary = {
"substr" => rsassert::Binary::SubStr, "substr" => types::Binary::SubStr,
"min" => rsassert::Binary::Min, "min" => types::Binary::Min,
"max" => rsassert::Binary::Max, "max" => types::Binary::Max,
"commonsubstr" => rsassert::Binary::CommonSubStr, "commonsubstr" => types::Binary::CommonSubStr,
} }
@ -858,17 +857,17 @@ Instruction: presets::Instruction = {
pub Run: presets::Instructions = { pub Run: presets::Instructions = {
#[precedence(level="0")] #[precedence(level="0")]
<sys: System> <instr: Separated_Or<Instruction, ",">> => <sys: System> <instr: Separated_Or<Instruction, ",">> =>
Instructions { system: presets::System::System { sys }, presets::Instructions { system: presets::System::System { sys },
instructions: instr }, instructions: instr },
#[precedence(level="1")] #[precedence(level="1")]
<sys: System> => <sys: System> =>
Instructions { system: presets::System::System { sys }, presets::Instructions { system: presets::System::System { sys },
instructions: vec![] }, instructions: vec![] },
#[precedence(level="2")] #[precedence(level="2")]
"Deserialize" "(" <path: Path> ")" "Deserialize" "(" <path: Path> ")"
<instr: Separated_Or<Instruction, ",">> => <instr: Separated_Or<Instruction, ",">> =>
Instructions { system: presets::System::Deserialize { path }, presets::Instructions { system: presets::System::Deserialize { path },
instructions: instr }, instructions: instr },
} }

View File

@ -99,11 +99,11 @@ where
{ {
fn map_edges( fn map_edges(
&self, &self,
edge_map: &super::structure::RSassert, edge_map: &super::assert::types::Assert,
translator: &mut super::translator::Translator translator: &mut super::translator::Translator
) -> Result< ) -> Result<
Graph<System, Graph<System,
super::structure::assert::AssertReturnValue, Ty, Ix> super::assert::types::AssertReturnValue, Ty, Ix>
, String>; , String>;
} }
@ -112,9 +112,11 @@ impl<'a> MapEdges<'a, System, Label, Directed, u32>
{ {
fn map_edges( fn map_edges(
&self, &self,
edge_map: &super::structure::RSassert, edge_map: &super::assert::types::Assert,
translator: &mut super::translator::Translator translator: &mut super::translator::Translator
)-> Result<Graph<System, super::structure::assert::AssertReturnValue, Directed, u32>, String> { )-> Result<Graph<System, super::assert::types::AssertReturnValue,
Directed, u32>
, String> {
use petgraph::graph::EdgeIndex; use petgraph::graph::EdgeIndex;
let mut g = Graph::with_capacity(self.node_count(), self.edge_count()); let mut g = Graph::with_capacity(self.node_count(), self.edge_count());

View File

@ -1,27 +1,24 @@
//! Crate root //! Crate root
pub mod structure;
pub mod translator; pub mod translator;
mod format_helpers;
pub mod choices;
pub mod environment;
pub mod label;
pub mod process;
pub mod reaction;
pub mod set;
pub mod system;
pub mod graph;
pub mod transitions;
pub mod rsdot;
pub mod serialize;
pub mod presets;
pub mod assert; pub mod assert;
pub mod bisimilarity; pub mod bisimilarity;
pub mod frequency; pub mod frequency;
pub mod graph;
mod format_helpers; pub mod presets;
pub mod rsdot;
pub mod set; pub mod serialize;
pub mod reaction; pub mod transitions;
pub mod process;
pub mod choices;
pub mod environment;
pub mod system;
pub mod label;
#[cfg(test)] #[cfg(test)]
mod system_test; mod system_test;

View File

@ -87,7 +87,7 @@ pub enum Instruction {
FastFrequency { experiment: String, so: SaveOptions }, FastFrequency { experiment: String, so: SaveOptions },
Digraph { gso: Vec<GraphSaveOptions> }, Digraph { gso: Vec<GraphSaveOptions> },
Bisimilarity { system_b: String, Bisimilarity { system_b: String,
edge_relabeler: Box<super::structure::RSassert>, edge_relabeler: Box<super::assert::types::Assert>,
so: SaveOptions } so: SaveOptions }
} }
@ -547,11 +547,11 @@ pub fn digraph(system: &mut EvaluatedSystem) -> Result<(), String> {
/// Computes bisimularity of two provided systems /// Computes bisimularity of two provided systems
pub fn bisimilar( pub fn bisimilar(
system_a: &mut EvaluatedSystem, system_a: &mut EvaluatedSystem,
edge_relabeler: &super::structure::RSassert, edge_relabeler: &super::assert::types::Assert,
system_b: String system_b: String
) -> Result<String, String> ) -> Result<String, String>
{ {
use super::structure::assert::AssertReturnValue; use super::assert::types::AssertReturnValue;
let system_b = read_file(system_a.get_translator(), let system_b = read_file(system_a.get_translator(),
system_b.to_string(), system_b.to_string(),

View File

@ -1,17 +0,0 @@
//! Module for all basic structures.
// -----------------------------------------------------------------------------
// RSassert
// -----------------------------------------------------------------------------
pub type RSassert =
crate::rsprocess::assert::rsassert::useful_types_edge_relabeler::RSassert;
pub mod assert {
pub use crate::rsprocess::assert::dsl::*;
}
/// Export of useful values from submodule of submodule
pub mod rsassert {
pub use crate::rsprocess::assert::rsassert::useful_types_edge_relabeler::*;
}

View File

@ -1,7 +1,8 @@
//! Module for translation and keeping track of strings. //! Module for translation and keeping track of strings.
use std::collections::HashMap;
use serde::{Serialize, Deserialize}; use serde::{Serialize, Deserialize};
use std::collections::HashMap;
use std::fmt;
/// precision for printing frequencies /// precision for printing frequencies
pub static PRECISION: &usize = &2; pub static PRECISION: &usize = &2;
@ -102,51 +103,3 @@ impl<'a, T> Formatter<'a, T> {
} }
use super::{
structure::{
RSassert
},
};
use std::fmt;
macro_rules! translator_structure {
($name:ident, $type:ty, $dataname:ident, $print_func:ident) => {
#[derive(Clone, Debug)]
#[allow(dead_code)]
pub struct $name<'a> {
translator: &'a Translator,
$dataname: &'a $type,
}
#[allow(dead_code)]
impl <'a>$name<'a> {
pub fn from(translator: &'a Translator, $dataname: &'a $type) -> Self {
$name { translator, $dataname }
}
}
impl<'a> fmt::Display for $name<'a> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
$print_func(f, self.translator, self.$dataname)
}
}
};
}
// RSassert
#[allow(unused_variables)]
fn print_assert(
f: &mut fmt::Formatter,
translator: &Translator,
assert: &RSassert
) -> fmt::Result {
todo!()
}
translator_structure!(RSassertDisplay, RSassert, assert, print_assert);