From 5af8cd98c28e22d113d53ef47c4bc71dc1acedac Mon Sep 17 00:00:00 2001 From: elvis Date: Tue, 1 Jul 2025 04:04:13 +0200 Subject: [PATCH] Starting to convert main_do, statistics, frequency not working frequency not working, also need to look into perpetual better --- src/examples.rs | 123 +++++++++++++++++++++ src/main.rs | 198 ++-------------------------------- src/rsprocess/grammar.lalrpop | 76 ++++++++++--- src/rsprocess/mod.rs | 1 + src/rsprocess/statistics.rs | 134 +++++++++++++++++++++++ src/rsprocess/structure.rs | 88 ++++++++++++++- src/rsprocess/translator.rs | 8 +- testing/first.stats | 25 +++++ testing/first.system | 4 + 9 files changed, 450 insertions(+), 207 deletions(-) create mode 100644 src/examples.rs create mode 100644 src/rsprocess/statistics.rs create mode 100644 testing/first.stats create mode 100644 testing/first.system diff --git a/src/examples.rs b/src/examples.rs new file mode 100644 index 0000000..a3f854b --- /dev/null +++ b/src/examples.rs @@ -0,0 +1,123 @@ +use crate::rsprocess::statistics; +use crate::rsprocess::structure::RSsystem; +use crate::rsprocess::transitions; +use crate::rsprocess::translator::Translator; +use crate::rsprocess::translator::WithTranslator; +use crate::rsprocess::perpetual; + +use std::fs; +use std::io; +use std::io::prelude::*; +use std::env; + +// grammar is defined in main.rs, calling lalrpop_mod! twice, generates twice +// the code +use super::grammar; + + +fn read_system( + translator: &mut Translator, + path: std::path::PathBuf +) -> std::io::Result { + // we read the file with a buffer + let f = fs::File::open(path.clone())?; + let mut buf_reader = io::BufReader::new(f); + let mut contents = String::new(); + buf_reader.read_to_string(&mut contents)?; + + // parse + let result = grammar::SystemParser::new().parse(translator, &contents).unwrap(); + + Ok(result) +} + +// equivalent main_do(stat) or main_do(stat, MissingE) +pub fn stats() -> std::io::Result<()> { + let mut translator = Translator::new(); + + let mut path = env::current_dir()?; + // file to read is inside testing/ + path = path.join("testing/first.system"); + let system = read_system(&mut translator, path)?; + + + // print statistics to screan + println!("{}", statistics::of_RSsystem(&translator, &system)); + + // to write to file: + //// path = path.with_extension("stats"); + //// let mut f = std::fs::File::create(path)?; + //// writeln!(f, "{}", statistics::of_RSsystem(translator, &result))?; + + Ok(()) +} + +// equivalent to main_do(target, E) +pub fn target() -> std::io::Result<()> { + let mut translator = Translator::new(); + + let mut path = env::current_dir()?; + // file to read is inside testing/ + path = path.join("testing/first.system"); + let system = read_system(&mut translator, path)?; + + // the system needs to terminate to return + let res = match transitions::target(&system) { + Ok(o) => o, + Err(e) => {println!("Error computing target: {e}"); return Ok(());} + }; + + println!("After {} steps we arrive at state:\n{}", + res.0, + WithTranslator::from_RSset(&translator, &res.1)); + + Ok(()) +} + +// equivalent to main_do(run,Es) +pub fn run() -> std::io::Result<()> { + let mut translator = Translator::new(); + + let mut path = env::current_dir()?; + // file to read is inside testing/ + path = path.join("testing/first.system"); + let system = read_system(&mut translator, path)?; + + // the system needs to terminate to return + let res = match transitions::run_separated(&system) { + Ok(o) => o, + Err(e) => {println!("Error computing target: {e}"); return Ok(());} + }; + + println!("The trace is composed of the entities:"); + + for (e, _c, _t) in res { + println!("{}", WithTranslator::from_RSset(&translator, &e)); + } + + Ok(()) +} + +// equivalent to main_do(loop,Es) +pub fn hoop() -> std::io::Result<()> { + let mut translator = Translator::new(); + + let mut path = env::current_dir()?; + // file to read is inside testing/ + path = path.join("testing/first.system"); + let system = read_system(&mut translator, path)?; + + // we retrieve the id for "x" and use it to find the corresponding loop + let res = match perpetual::lollipops_only_loop_named(system, translator.encode("x")) { + Some(o) => o, + None => {println!("No loop found."); return Ok(());} + }; + + println!("The loop is composed by the sets:"); + + for e in res { + println!("{}", WithTranslator::from_RSset(&translator, &e)); + } + + Ok(()) +} diff --git a/src/main.rs b/src/main.rs index a9b4efa..b985a7d 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,201 +1,25 @@ #![allow(unused_imports)] mod rsprocess; -use lalrpop_util::lalrpop_mod; +mod examples; + use std::{hash::Hash, rc::Rc}; use rsprocess::translator::WithTranslator; -// use std::io; -fn main() -> Result<(), Box> { - lalrpop_mod!(grammar, "/rsprocess/grammar.rs"); +lalrpop_util::lalrpop_mod!(#[allow(clippy::uninlined_format_args)] pub grammar, "/rsprocess/grammar.rs"); - let mut translator = rsprocess::translator::Translator::new(); +fn main() -> std::io::Result<()> { - // let mut buffer = String::new(); - // let i = io::stdin(); - // i.read_line(&mut buffer).expect("Can't read stdin"); + // let now = std::time::Instant::now(); + // std::thread::sleep(std::time::Duration::new(2, 0)); + // println!("{}", now.elapsed().as_micros()); - // let result = grammar::SetParser::new().parse(&mut translator, &buffer).unwrap(); + examples::stats()?; + examples::hoop()?; - // ------------------------------------------------------------------------- - // let reactants = grammar::SetParser::new().parse(&mut translator, "{a}").unwrap(); - // let inihibitors = grammar::SetParser::new().parse(&mut translator, "{c}").unwrap(); - // let products = grammar::SetParser::new().parse(&mut translator, "{a,c}").unwrap(); + examples::target()?; - // let process1 = rsprocess::structure::RSreaction::from(reactants, inihibitors, products); + examples::run()?; - // let reactants = grammar::SetParser::new().parse(&mut translator, "{b}").unwrap(); - // let inihibitors = grammar::SetParser::new().parse(&mut translator, "{c}").unwrap(); - // let products = grammar::SetParser::new().parse(&mut translator, "{b,c}").unwrap(); - - // let process2 = rsprocess::structure::RSreaction::from(reactants, inihibitors, products); - - // let current_state = grammar::SetParser::new().parse(&mut translator, "{b}").unwrap(); - - // println!("{:?}", rsprocess::classical::compute_all(¤t_state, vec![&process1, &process2])); - - - // ------------------------------------------------------------------------- - // let env = grammar::EnvironmentParser::new().parse(&mut translator, "[x = {a}.{b}.x , y = ({a,c}.y + {b,c}.y)]").unwrap(); - // let process = grammar::ContextParser::new().parse(&mut translator, "[({a}.nil + x + y)]").unwrap(); - - // println!("{:?}", rsprocess::transitions::unfold(&env, &process)); - - // println!("--------------------"); - - // println!("{:?}", env); - - - // ------------------------------------------------------------------------- - // allTransitions(sys([],[a,b],[],[react([a],[c],[a]),react([b],[d],[b])]) , Moves). - - // let env = grammar::EnvironmentParser::new().parse(&mut translator, "[]").unwrap(); - // let process = grammar::ContextParser::new().parse(&mut translator, "[]").unwrap(); - - // let sys = rsprocess::structure::RSsystem::from(Rc::new(*env), - // rsprocess::structure::RSset::from(vec![translator.encode("a"), - // translator.encode("b")]), - // *process, - // Rc::new(vec![ - // rsprocess::structure::RSreaction::from( - // rsprocess::structure::RSset::from(vec![translator.encode("a")]), - // rsprocess::structure::RSset::from(vec![translator.encode("c")]), - // rsprocess::structure::RSset::from(vec![translator.encode("a")]) - // ), - // rsprocess::structure::RSreaction::from( - // rsprocess::structure::RSset::from(vec![translator.encode("b")]), - // rsprocess::structure::RSset::from(vec![translator.encode("d")]), - // rsprocess::structure::RSset::from(vec![translator.encode("b")]) - // ) - // ])); - - - // println!("all_transitions: {:?}", rsprocess::transitions::all_transitions(&sys)); - // ------------------------------------------------------------------------- - // parse_ctx("[({a}.nil + {b}.nil)]",Ks) , allTransitions(sys([],[],Ks,[react([a],[c],[a]),react([b],[d],[b])]),Moves). - // let env = grammar::EnvironmentParser::new().parse(&mut translator, "[]").unwrap(); - // let process = grammar::ContextParser::new().parse(&mut translator, "[({a}.nil + {b}.nil)]").unwrap(); - - // let sys = rsprocess::structure::RSsystem::from(Rc::new(*env), - // rsprocess::structure::RSset::from(vec![]), - // *process, - // Rc::new(vec![ - // rsprocess::structure::RSreaction::from( - // rsprocess::structure::RSset::from(vec![translator.encode("a")]), - // rsprocess::structure::RSset::from(vec![translator.encode("c")]), - // rsprocess::structure::RSset::from(vec![translator.encode("a")]) - // ), - // rsprocess::structure::RSreaction::from( - // rsprocess::structure::RSset::from(vec![translator.encode("b")]), - // rsprocess::structure::RSset::from(vec![translator.encode("d")]), - // rsprocess::structure::RSset::from(vec![translator.encode("b")]) - // ) - // ])); - - - // println!("all_transitions: {:?}", rsprocess::transitions::all_transitions(&sys)); - - // ------------------------------------------------------------------------- - // parse_ctx("[({a}.nil + {b}.nil),({c}.nil + {d}.nil)]",Ks) , allTransitions(sys([],[],Ks,[react([a],[c],[a]),react([b],[d],[b])]),Moves). - // let env = grammar::EnvironmentParser::new().parse(&mut translator, "[]").unwrap(); - // let process = grammar::ContextParser::new().parse(&mut translator, "[({a}.nil + {b}.nil),({c}.nil + {d}.nil)]").unwrap(); - - // let sys = rsprocess::structure::RSsystem::from(Rc::new(*env), - // rsprocess::structure::RSset::from(vec![]), - // *process, - // Rc::new(vec![ - // rsprocess::structure::RSreaction::from( - // rsprocess::structure::RSset::from(vec![translator.encode("a")]), - // rsprocess::structure::RSset::from(vec![translator.encode("c")]), - // rsprocess::structure::RSset::from(vec![translator.encode("a")]) - // ), - // rsprocess::structure::RSreaction::from( - // rsprocess::structure::RSset::from(vec![translator.encode("b")]), - // rsprocess::structure::RSset::from(vec![translator.encode("d")]), - // rsprocess::structure::RSset::from(vec![translator.encode("b")]) - // ) - // ])); - - // let it = rsprocess::transitions::iterator_transitions(&sys)?; - - // for (n, i) in it.into_iter().enumerate() { - // println!("next i - {n}: {:?}", i); - // println!("--------------------"); - // } - - // ------------------------------------------------------------------------- - // let env = grammar::EnvironmentParser::new().parse(&mut translator, "[]").unwrap(); - // let process = grammar::ContextParser::new().parse(&mut translator, "[({a}.nil + {b}.nil),({c}.nil + {d}.nil)]").unwrap(); - - // let sys = rsprocess::structure::RSsystem::from(Rc::new(*env), - // rsprocess::structure::RSset::from(vec![]), - // *process, - // Rc::new(vec![ - // rsprocess::structure::RSreaction::from( - // rsprocess::structure::RSset::from(vec![translator.encode("a")]), - // rsprocess::structure::RSset::from(vec![translator.encode("c")]), - // rsprocess::structure::RSset::from(vec![translator.encode("a")]) - // ), - // rsprocess::structure::RSreaction::from( - // rsprocess::structure::RSset::from(vec![translator.encode("b")]), - // rsprocess::structure::RSset::from(vec![translator.encode("d")]), - // rsprocess::structure::RSset::from(vec![translator.encode("b")]) - // ) - // ])); - // println!("{:?}", rsprocess::transitions::run_separated(&sys)); - - // ------------------------------------------------------------------------- - // list_to_assoc([x-pre([a, b], rec(x)), y-pre([d, e], rec(y))], Ass), - // lollipop(sys(Ass, [a, b, c, d], [], [react([a], [c], [a]), react([d], [f], [d])]), Prefix, Loop). - - let env = grammar::EnvironmentParser::new().parse(&mut translator, "[x = {a,b}.x]").unwrap(); - let process = grammar::ContextParser::new().parse(&mut translator, "[]").unwrap(); - - let sys = rsprocess::structure::RSsystem::from(Rc::new(*env), - rsprocess::structure::RSset::from(vec![translator.encode("a"), - translator.encode("b"), - translator.encode("c"), - translator.encode("d")]), - *process, - Rc::new(vec![ - rsprocess::structure::RSreaction::from( - rsprocess::structure::RSset::from(vec![translator.encode("a")]), - rsprocess::structure::RSset::from(vec![translator.encode("c")]), - rsprocess::structure::RSset::from(vec![translator.encode("a")]) - ), - rsprocess::structure::RSreaction::from( - rsprocess::structure::RSset::from(vec![translator.encode("d")]), - rsprocess::structure::RSset::from(vec![translator.encode("f")]), - rsprocess::structure::RSset::from(vec![translator.encode("d")]) - ) - ])); - - let res = rsprocess::perpetual::lollipops(sys.clone()); - - println!("res:"); - for (prefix, hoop) in res { - print!("prefix: "); - for p in prefix { - print!("{}, ", WithTranslator::from_RSset(&translator, &p)); - } - print!("\nhoop: "); - for l in hoop { - print!("{}, ", WithTranslator::from_RSset(&translator, &l)); - } - println!(); - } - - let res = rsprocess::perpetual::lollipops_only_loop(sys); - - println!("res:"); - for hoop in res { - print!("hoop: "); - for l in hoop { - print!("{}, ", WithTranslator::from_RSset(&translator, &l)); - } - println!(); - } - - // ------------------------------------------------------------------------- Ok(()) } diff --git a/src/rsprocess/grammar.lalrpop b/src/rsprocess/grammar.lalrpop index 1c12e24..809d59f 100644 --- a/src/rsprocess/grammar.lalrpop +++ b/src/rsprocess/grammar.lalrpop @@ -1,11 +1,22 @@ use std::rc::Rc; use std::str::FromStr; use lalrpop_util::ParseError; -use crate::rsprocess::structure::{RSset, RSprocess, RSenvironment, RSassert, RSassertOp, RSBHML}; +use crate::rsprocess::structure::{RSset, + RSprocess, + RSenvironment, + RSassert, + RSassertOp, + RSBHML, + RSsystem, + RSreaction}; use crate::rsprocess::translator::{Translator, IdType}; grammar(translator: &mut Translator); +// ----------------------------------------------------------------------------- +// Helpers +// ----------------------------------------------------------------------------- + // matches words (letter followed by numbers, letters or _) Literal = { r"[[:alpha:]][[:word:]]*" }; @@ -26,7 +37,9 @@ Separeted: Vec = { } }; -// ----- SetParser ----- +// ----------------------------------------------------------------------------- +// SetParser +// ----------------------------------------------------------------------------- pub Set: RSset = { => s }; @@ -38,18 +51,31 @@ Set_of_entities: RSset = { RSset::from(t.into_iter().map(|t| translator.encode(t)).collect::>()) }; -// ----- ContextParser ----- -pub Context: Box = { - // "[" "]" => Box::new(RSprocess::Nill), - // "[" "]" => Box::new(t), - // "[" > "]" => - // Box::new(RSprocess::NondeterministicChoice{ children: t }) - "[" "]" => Box::new(RSprocess::NondeterministicChoice{ children: vec![] }), +// ----------------------------------------------------------------------------- +// ReactionParser +// ----------------------------------------------------------------------------- + +pub Reactions: Vec = { + "(" ")" => vec![], + "(" ")" => vec![r], + "(" > ")" => s +} + +Reaction: RSreaction = { + "[" "," "," "]" => RSreaction::from(r, i, p), + "[" "r:" "," "i:" "," "p:" "]" => RSreaction::from(r, i, p), +} + +// ----------------------------------------------------------------------------- +// ContextParser +// ----------------------------------------------------------------------------- +pub Context: RSprocess = { + "[" "]" => RSprocess::NondeterministicChoice{ children: vec![] }, "[" "]" => - Box::new(RSprocess::NondeterministicChoice{children: vec![Rc::new(t)]}), + RSprocess::NondeterministicChoice{children: vec![Rc::new(t)]}, "[" > "]" => - Box::new(RSprocess::NondeterministicChoice{ children: t }) + RSprocess::NondeterministicChoice{ children: t } }; Boxed_CTX_process: Rc = { @@ -71,7 +97,9 @@ CTX_process: RSprocess = { RSprocess::RecursiveIdentifier{ identifier: translator.encode(identifier) } }; -// ----- EnvironmentParser ----- +// ----------------------------------------------------------------------------- +// EnvironmentParser +// ----------------------------------------------------------------------------- pub Environment: Box = { "[" "]" => Box::new(RSenvironment::new()), "[" "]" => Box::new(RSenvironment::from(vec![t])), @@ -83,7 +111,9 @@ Env_term: (IdType, RSprocess) = { (translator.encode(identifier), k) }; -// ----- AssertParser ----- +// ----------------------------------------------------------------------------- +// AssertParser +// ----------------------------------------------------------------------------- pub Assert: Box = { => Box::new(f) }; @@ -104,7 +134,9 @@ Formula_Assert: RSassert = { "?" "inP" => RSassert::NonEmpty(RSassertOp::InP), }; -// ----- BHMLParser ----- +// ----------------------------------------------------------------------------- +// BHMLParser +// ----------------------------------------------------------------------------- pub BHML: Box = { => Box::new(g) }; @@ -119,3 +151,19 @@ Formula_BHML: RSBHML = { "[" "]" => RSBHML::Box(Box::new(f), Box::new(g)), }; + + +// ----------------------------------------------------------------------------- +// File Parsing +// ----------------------------------------------------------------------------- +// system +// a system is an environment, a set of entities as initial state, a context and +// a set of reaction rules. + +pub System: RSsystem = { + "Environment:" + "Initial Entities:" + "Context:" + "Reactions:" + => RSsystem::from(delta.into(), available_entities, context_process, Rc::new(reaction_rules)) +} diff --git a/src/rsprocess/mod.rs b/src/rsprocess/mod.rs index 0525a43..874cb0b 100644 --- a/src/rsprocess/mod.rs +++ b/src/rsprocess/mod.rs @@ -6,3 +6,4 @@ pub mod transitions; pub mod perpetual; pub mod confluence; pub mod frequency; +pub mod statistics; diff --git a/src/rsprocess/statistics.rs b/src/rsprocess/statistics.rs new file mode 100644 index 0000000..a602619 --- /dev/null +++ b/src/rsprocess/statistics.rs @@ -0,0 +1,134 @@ +#![allow(dead_code)] + +use super::structure::RSset; +use super::structure::RSsystem; +use super::translator::{Translator, WithTranslator}; + +#[allow(non_snake_case)] +pub fn of_RSsystem<'a>(translator: &'a Translator, system: &'a RSsystem) -> String { + let mut result: String = "Statistics:\n".into(); + result.push_str( + "=============================================================\n" + ); + result.push_str( + &format!("the initial state has {} entities:\n", + system.get_available_entities().len()) + ); + result.push_str( + &format!("{}\n", + WithTranslator::from_RSset(translator, + system.get_available_entities())) + ); + + let reactants = + system + .get_reaction_rules() + .iter() + .fold(RSset::new(), |acc, new| acc.union(new.reactants())); + result.push_str( + &format!("The reactants are {}:\n{}\n", + reactants.len(), + WithTranslator::from_RSset(translator, &reactants)) + ); + + let inhibitors = + system + .get_reaction_rules() + .iter() + .fold(RSset::new(), |acc, new| acc.union(new.inihibitors())); + result.push_str( + &format!("The inhibitors are {}:\n{}\n", + inhibitors.len(), + WithTranslator::from_RSset(translator, &inhibitors)) + ); + + let products = + system + .get_reaction_rules() + .iter() + .fold(RSset::new(), |acc, new| acc.union(new.products())); + result.push_str( + &format!("The products are {}:\n{}\n", + products.len(), + WithTranslator::from_RSset(translator, &products)) + ); + + + let total = reactants.union(&inhibitors.union(&products)); + result.push_str( + &format!("The reactions involve {} entities:\n{}\n", + total.len(), + WithTranslator::from_RSset(translator, &total)) + ); + + let entities_env = system.get_delta().all_elements(); + result.push_str( + &format!("The environment involves {} entities:\n{}\n", + entities_env.len(), + WithTranslator::from_RSset(translator, &entities_env)) + ); + + let entities_context = system.get_context_process().all_elements(); + result.push_str( + &format!("The context involves {} entities:\n{}\n", + entities_context.len(), + WithTranslator::from_RSset(translator, &entities_context)) + ); + + let entities_all = total.union(&entities_env) + .union(&entities_context) + .union(system.get_available_entities()); + + result.push_str( + &format!("The whole RS involves {} entities:\n{}\n", + entities_all.len(), + WithTranslator::from_RSset(translator, &entities_all)) + ); + + let possible_e = products.union(system.get_available_entities()) + .union(&entities_context); + let missing_e = reactants.subtraction(&possible_e); + result.push_str( + &format!("There are {} reactants that will never be available:\n{}\n", + missing_e.len(), + WithTranslator::from_RSset(translator, &missing_e)) + ); + + let entities_not_needed = entities_context.subtraction(&total); + result.push_str( + &format!("The context can provide {} entities that will never be used:\n{}\n", + entities_not_needed.len(), + WithTranslator::from_RSset(translator, &entities_not_needed)) + ); + + result.push_str( + &format!("There are {} reactions in total.\n", + system.get_reaction_rules().len()) + ); + + let mut admissible_reactions = vec![]; + let mut nonadmissible_reactions = vec![]; + + for reaction in system.get_reaction_rules().iter() { + if reaction.reactants().is_disjoint(&missing_e) { + admissible_reactions.push(reaction); + } else { + nonadmissible_reactions.push(reaction); + } + } + + result.push_str( + &format!("- the applicable reactions are {}.\n", + admissible_reactions.len()) + ); + + result.push_str( + &format!("- there are {} reactions that will never be enabled.\n", + nonadmissible_reactions.len()) + ); + result.push_str( + "=============================================================" + ); + + result +} diff --git a/src/rsprocess/structure.rs b/src/rsprocess/structure.rs index 5452024..811601a 100644 --- a/src/rsprocess/structure.rs +++ b/src/rsprocess/structure.rs @@ -1,6 +1,6 @@ #![allow(dead_code)] -use std::collections::{BTreeSet, HashMap, HashSet}; +use std::collections::{BTreeSet, HashMap, HashSet, VecDeque}; use std::hash::{Hash, Hasher}; use std::rc::Rc; use super::translator::{IdType}; @@ -75,13 +75,31 @@ impl RSset { RSset { identifiers: res } } - pub fn hashset(&self) -> &BTreeSet { + pub fn set(&self) -> &BTreeSet { &self.identifiers } pub fn iter(&self) -> std::collections::btree_set::Iter<'_, IdType> { self.identifiers.iter() } + + pub fn len(&self) -> usize { + self.identifiers.len() + } + + pub fn insert(&mut self, el: IdType) -> bool { + self.identifiers.insert(el) + } + + pub fn push(&mut self, b: &RSset) { + self.identifiers.extend(b.iter()) + } +} + +impl Default for RSset { + fn default() -> Self { + RSset::new() + } } impl IntoIterator for RSset { @@ -140,6 +158,12 @@ impl RSreaction { } } +impl Default for RSreaction { + fn default() -> Self { + RSreaction::new() + } +} + // ----------------------------------------------------------------------------- @@ -183,8 +207,42 @@ impl RSprocess { } } } + + pub fn all_elements(&self) -> RSset { + let mut queue = VecDeque::from([self]); + let mut elements = RSset::new(); + + while let Some(el) = queue.pop_front() { + match el { + Self::Nill => {} + Self::RecursiveIdentifier { identifier: _ } => {} + Self::EntitySet { entities, next_process } => { + elements.push(entities); + queue.push_back(next_process); + } + Self::WaitEntity { repeat: _, repeated_process, next_process } => { + queue.push_back(repeated_process); + queue.push_back(next_process); + } + Self::Summation { children } => { + for c in children { + queue.push_back(c); + } + } + Self::NondeterministicChoice { children } => { + for c in children { + queue.push_back(c); + } + } + } + } + elements + } } +// ----------------------------------------------------------------------------- +// RSchoices +// ----------------------------------------------------------------------------- #[derive(Clone, Debug)] pub struct RSchoices { context_moves: Vec<(Rc, Rc)> @@ -284,6 +342,20 @@ impl RSenvironment { pub fn iter(&self) -> std::collections::hash_map::Iter<'_, u32, RSprocess> { self.definitions.iter() } + + pub fn all_elements(&self) -> RSset { + let mut acc = RSset::new(); + for (_, process) in self.definitions.iter() { + acc.push(&process.all_elements()); + } + acc + } +} + +impl Default for RSenvironment { + fn default() -> Self { + RSenvironment::new() + } } impl From<[(IdType, RSprocess); N]> for RSenvironment { @@ -352,6 +424,12 @@ impl RSsystem { } } +impl Default for RSsystem { + fn default() -> Self { + RSsystem::new() + } +} + // ----------------------------------------------------------------------------- // RSsystem // ----------------------------------------------------------------------------- @@ -361,9 +439,9 @@ pub struct RSlabel { pub context: RSset, pub t: RSset, /// union of available_entities and context pub reactants: RSset, - pub reactantsi: RSset, + pub reactantsi: RSset, // reactants absent pub inihibitors: RSset, - pub ireactants: RSset, + pub ireactants: RSset, // inhibitors present pub products: RSset, } @@ -399,7 +477,7 @@ impl RSlabel { } pub fn get_context(&self) -> (RSset, RSset, RSset) { - // FIXME clone? + // TODO remove clone? (self.available_entities.clone(), self.context.clone(), self.t.clone()) } } diff --git a/src/rsprocess/translator.rs b/src/rsprocess/translator.rs index 009a0ad..04ac2be 100644 --- a/src/rsprocess/translator.rs +++ b/src/rsprocess/translator.rs @@ -20,6 +20,12 @@ impl Translator { } } +impl Default for Translator { + fn default() -> Self { + Translator::new() + } +} + impl Translator { pub fn encode(&mut self, s: impl Into) -> IdType { let s = s.into(); @@ -144,7 +150,7 @@ fn print_set( set: &RSset ) -> fmt::Result { write!(f, "{{")?; - let mut it = set.hashset().iter().peekable(); + let mut it = set.iter().peekable(); while let Some(el) = it.next() { if it.peek().is_none() { write!(f, "{}", translator.decode(*el))?; diff --git a/testing/first.stats b/testing/first.stats new file mode 100644 index 0000000..a12aeeb --- /dev/null +++ b/testing/first.stats @@ -0,0 +1,25 @@ +Statistics: +============================================================= +the initial state has 2 entities: +{a, b} +The reactants are 2: +{a, b} +The inhibitors are 1: +{c} +The products are 1: +{b} +The reactions involve 3 entities: +{a, b, c} +The environment involves 2 entities: +{a, b} +The context involves 3 entities: +{a, b, c} +The whole RS involves 3 entities: +{a, b, c} +There are 0 reactants that will never be available: +{} +The context can provide 0 entities that will never be used: +{} +There are 1 reactions in total. +- the applicable reactions are 1. +- there are 0 reactions that will never be enabled. diff --git a/testing/first.system b/testing/first.system new file mode 100644 index 0000000..37d49d8 --- /dev/null +++ b/testing/first.system @@ -0,0 +1,4 @@ +Environment: [x = {a}.y, y =({a}.x + {b}.y)] +Initial Entities: {a, b} +Context: [({a,b}.{a}.{a,c}.x + {a,b}.{a}.{a}.nil)] +Reactions: ([r: {a,b}, i: {c}, p: {b}])