From eba5d1266d6e58c4acbb886f78dc50739b427fa8 Mon Sep 17 00:00:00 2001 From: elvis Date: Tue, 1 Jul 2025 19:22:50 +0200 Subject: [PATCH] formatting with rustfmt --- src/examples.rs | 64 ++-- src/main.rs | 10 +- src/rsprocess/classical.rs | 20 +- src/rsprocess/confluence.rs | 90 +++--- src/rsprocess/frequency.rs | 47 +-- src/rsprocess/grammar.lalrpop | 18 +- src/rsprocess/mod.rs | 10 +- src/rsprocess/perpetual.rs | 176 ++++++----- src/rsprocess/statistics.rs | 181 ++++++----- src/rsprocess/structure.rs | 463 ++++++++++++++++------------ src/rsprocess/support_structures.rs | 8 +- src/rsprocess/transitions.rs | 171 +++++----- src/rsprocess/translator.rs | 175 +++++++---- testing/first.system | 2 +- 14 files changed, 796 insertions(+), 639 deletions(-) diff --git a/src/examples.rs b/src/examples.rs index 6b0bb90..4ffaec9 100644 --- a/src/examples.rs +++ b/src/examples.rs @@ -1,23 +1,19 @@ -use crate::rsprocess::{frequency, - statistics, - transitions, - perpetual}; +#![allow(dead_code)] + use crate::rsprocess::structure::RSsystem; use crate::rsprocess::translator::{Translator, WithTranslator}; +use crate::rsprocess::{frequency, perpetual, statistics, transitions}; use std::env; use std::fs; -use std::io::prelude::*; use std::io; +use std::io::prelude::*; // 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 { +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); @@ -25,7 +21,9 @@ fn read_system( buf_reader.read_to_string(&mut contents)?; // parse - let result = grammar::SystemParser::new().parse(translator, &contents).unwrap(); + let result = grammar::SystemParser::new() + .parse(translator, &contents) + .unwrap(); Ok(result) } @@ -39,7 +37,6 @@ pub fn stats() -> std::io::Result<()> { path = path.join("testing/first.system"); let system = read_system(&mut translator, path)?; - // print statistics to screan println!("{}", statistics::of_RSsystem(&translator, &system)); @@ -62,13 +59,18 @@ pub fn target() -> std::io::Result<()> { // 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(());} + 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)); + println!( + "After {} steps we arrive at state:\n{}", + res.0, + WithTranslator::from_RSset(&translator, &res.1) + ); Ok(()) } @@ -84,14 +86,17 @@ pub fn run() -> std::io::Result<()> { // 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(());} + 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)); + println!("{}", WithTranslator::from_RSset(&translator, &e)); } Ok(()) @@ -108,14 +113,17 @@ pub fn hoop() -> std::io::Result<()> { // 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(());} + 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)); + println!("{}", WithTranslator::from_RSset(&translator, &e)); } Ok(()) @@ -130,11 +138,17 @@ pub fn freq() -> std::io::Result<()> { let system = read_system(&mut translator, path)?; let res = match frequency::naive_frequency(&system) { - Ok(f) => f, - Err(e) => {println!("Error computing target: {e}"); return Ok(());} + Ok(f) => f, + Err(e) => { + println!("Error computing target: {e}"); + return Ok(()); + } }; - println!("Frequency of encountered symbols:\n{}", WithTranslator::from_Frequency(&translator, &res)); + println!( + "Frequency of encountered symbols:\n{}", + WithTranslator::from_Frequency(&translator, &res) + ); Ok(()) } diff --git a/src/main.rs b/src/main.rs index 0ecfb0e..24e6373 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,5 +1,5 @@ -mod rsprocess; mod examples; +mod rsprocess; lalrpop_util::lalrpop_mod!( #[allow(clippy::uninlined_format_args)] pub grammar, // name of module @@ -11,15 +11,15 @@ fn main() -> std::io::Result<()> { // std::thread::sleep(std::time::Duration::new(2, 0)); // println!("{}", now.elapsed().as_micros()); - examples::stats()?; + // examples::stats()?; examples::freq()?; - examples::hoop()?; + // examples::hoop()?; - examples::target()?; + // examples::target()?; - examples::run()?; + // examples::run()?; Ok(()) } diff --git a/src/rsprocess/classical.rs b/src/rsprocess/classical.rs index e7c3148..f8ac38d 100644 --- a/src/rsprocess/classical.rs +++ b/src/rsprocess/classical.rs @@ -6,7 +6,7 @@ //! inhibitors and products are held. #![allow(dead_code)] -use super::structure::{RSset, RSreaction}; +use super::structure::{RSreaction, RSset}; /// Computes the result of a single reaction (if enabled returns the products) /// otherwise returns None. @@ -16,9 +16,9 @@ pub fn compute_step<'a>( reaction: &'a RSreaction ) -> Option<&'a RSset> { if reaction.enabled(current_state) { - Some(reaction.products()) + Some(reaction.products()) } else { - None + None } } @@ -29,18 +29,16 @@ pub fn compute_all<'a>( current_state: &'a RSset, reactions: Vec<&'a RSreaction> ) -> RSset { - reactions.iter().fold( - RSset::new(), - |acc, r| acc.union_option(compute_step(current_state, r)) - ) + reactions.iter().fold(RSset::new(), |acc, r| { + acc.union_option(compute_step(current_state, r)) + }) } pub fn compute_all_owned<'a>( current_state: &'a RSset, reactions: &'a [RSreaction] ) -> RSset { - reactions.iter().fold( - RSset::new(), - |acc, r| acc.union_option(compute_step(current_state, r)) - ) + reactions.iter().fold(RSset::new(), |acc, r| { + acc.union_option(compute_step(current_state, r)) + }) } diff --git a/src/rsprocess/confluence.rs b/src/rsprocess/confluence.rs index f5ef28b..dd21888 100644 --- a/src/rsprocess/confluence.rs +++ b/src/rsprocess/confluence.rs @@ -1,23 +1,20 @@ #![allow(dead_code)] use super::perpetual::{ - lollipops_decomposed_named, - lollipops_prefix_len_loop_decomposed, - lollipops_prefix_len_loop_decomposed_named + lollipops_decomposed_named, lollipops_prefix_len_loop_decomposed, + lollipops_prefix_len_loop_decomposed_named, }; use super::structure::{RSenvironment, RSreaction, RSset}; use super::translator::IdType; use std::cmp; use std::collections::HashSet; - // see confluent, confluents pub fn confluent( delta: &RSenvironment, reaction_rules: &[RSreaction], entities: &[RSset], ) -> Option<(usize, usize, Vec)> { - let all_loops = lollipops_prefix_len_loop_decomposed(delta, reaction_rules, entities.first()?); @@ -26,9 +23,10 @@ pub fn confluent( let mut max_distance = prefix_len; for available_entities in entities.iter().skip(1) { - let all_loops = lollipops_prefix_len_loop_decomposed(delta, - reaction_rules, - available_entities); + let all_loops = + lollipops_prefix_len_loop_decomposed(delta, + reaction_rules, + available_entities); // FIXME we take just the first? do we compare all? let (prefix_len, new_hoop) = all_loops.first()?; @@ -40,16 +38,15 @@ pub fn confluent( Some((max_distance, dimension, hoop)) } - // see confluent, confluents pub fn confluent_named( delta: &RSenvironment, reaction_rules: &[RSreaction], entities: &[RSset], - symb: IdType + symb: IdType, ) -> Option<(usize, usize, Vec)> { let (prefix_len, first_hoop) = - lollipops_prefix_len_loop_decomposed_named(delta, + lollipops_prefix_len_loop_decomposed_named(delta, reaction_rules, entities.first()?, symb)?; @@ -58,11 +55,12 @@ pub fn confluent_named( let hoop = first_hoop; for available_entities in entities.iter().skip(1) { - let (prefix_len, new_hoop) = - lollipops_prefix_len_loop_decomposed_named(delta, - reaction_rules, - available_entities, - symb)?; + let (prefix_len, new_hoop) = lollipops_prefix_len_loop_decomposed_named( + delta, + reaction_rules, + available_entities, + symb, + )?; if new_hoop.len() != dimension || !hoop.contains(new_hoop.first()?) { return None; @@ -79,37 +77,37 @@ pub fn invariant_named( delta: &RSenvironment, reaction_rules: &[RSreaction], entities: &[RSset], - symb: IdType + symb: IdType, ) -> Option<(Vec, Vec)> { - let (prefix, hoop) = lollipops_decomposed_named(delta, - reaction_rules, - entities.first()?, - symb)?; + let (prefix, hoop) = + lollipops_decomposed_named(delta, + reaction_rules, + entities.first()?, + symb)?; let mut invariant = vec![]; invariant.append(&mut prefix.clone()); invariant.append(&mut hoop.clone()); let dimension = hoop.len(); for available_entities in entities { - let (new_prefix, new_hoop) = - lollipops_decomposed_named(delta, + let (new_prefix, new_hoop) = + lollipops_decomposed_named(delta, reaction_rules, available_entities, symb)?; - if new_hoop.len() != dimension || !hoop.contains(new_hoop.first()?) { - return None - } - invariant.append(&mut new_prefix.clone()); + if new_hoop.len() != dimension || !hoop.contains(new_hoop.first()?) { + return None; + } + invariant.append(&mut new_prefix.clone()); } // remove duplicates, maybe better with sorting? - invariant = - invariant - .iter() - .cloned() - .collect::>() - .iter() - .cloned() - .collect::>(); + invariant = invariant + .iter() + .cloned() + .collect::>() + .iter() + .cloned() + .collect::>(); Some((invariant, hoop)) } @@ -120,11 +118,12 @@ pub fn loop_confluent_named( deltas: &[RSenvironment], reaction_rules: &[RSreaction], entities: &[RSset], - symb: IdType + symb: IdType, ) -> Option)>> { - deltas.iter() - .map(|q| confluent_named(q, reaction_rules, entities, symb)) - .collect::>>() + deltas + .iter() + .map(|q| confluent_named(q, reaction_rules, entities, symb)) + .collect::>>() } // see strong_confluent @@ -133,16 +132,17 @@ pub fn strong_confluent_named( deltas: &[RSenvironment], reaction_rules: &[RSreaction], entities: &[RSset], - symb: IdType + symb: IdType, ) -> Option, usize, Vec)>> { - deltas.iter() + deltas + .iter() .map(|q| { - let (invariant, hoop) = invariant_named(q, + let (invariant, hoop) = invariant_named(q, reaction_rules, entities, symb)?; - let length = invariant.len(); - Some((invariant, length, hoop)) } - ) + let length = invariant.len(); + Some((invariant, length, hoop)) + }) .collect::>>() } diff --git a/src/rsprocess/frequency.rs b/src/rsprocess/frequency.rs index d387cff..8d4f98a 100644 --- a/src/rsprocess/frequency.rs +++ b/src/rsprocess/frequency.rs @@ -1,7 +1,7 @@ #![allow(dead_code)] -use std::collections::HashMap; use crate::rsprocess::perpetual::lollipops_only_loop_decomposed_q; +use std::collections::HashMap; use super::perpetual::lollipops_only_loop_named; use super::structure::{RSreaction, RSset, RSsystem}; @@ -12,37 +12,40 @@ use super::translator::IdType; pub struct Frequency { pub frequency_map: HashMap>, pub totals: Vec, - pub weights: Vec + pub weights: Vec, } impl Frequency { pub fn new() -> Self { - Frequency { frequency_map: HashMap::new(), totals: vec![], weights: vec![] } + Frequency { + frequency_map: HashMap::new(), + totals: vec![], + weights: vec![], + } } pub fn add(&mut self, e: &RSset, run: usize) { - for &el in e.iter() { - self.frequency_map.entry(el).or_insert(vec![0; run+1])[run] += 1 - } - self.totals[run] += 1 + for &el in e.iter() { + self.frequency_map.entry(el).or_insert(vec![0; run + 1])[run] += 1 + } + self.totals[run] += 1 } pub fn append_weight(&mut self, new_weight: u32) { - self.weights.push(new_weight) + self.weights.push(new_weight) } pub fn total_weights(&self) -> u32 { - self.weights.iter().sum() + self.weights.iter().sum() } } impl Default for Frequency { fn default() -> Self { - Frequency::new() + Frequency::new() } } - // ----------------------------------------------------------------------------- // see naiveFreq, assume the system is finite, calculate the frequency of @@ -66,7 +69,7 @@ pub fn loop_frequency(system: &RSsystem, symb: IdType) -> Frequency { freq.append_weight(1); if let Some(hoop) = lollipops_only_loop_named(system.clone(), symb) { - hoop.iter().for_each(|e| freq.add(e, 0)); + hoop.iter().for_each(|e| freq.add(e, 0)); } freq } @@ -76,15 +79,15 @@ pub fn loop_frequency(system: &RSsystem, symb: IdType) -> Frequency { pub fn limit_frequency( q: &[RSset], reaction_rules: &[RSreaction], - available_entities: &RSset + available_entities: &RSset, ) -> Option { let mut available_entities = available_entities.clone(); for q in q.iter().rev().skip(1).rev() { - let res = lollipops_only_loop_decomposed_q(q, + let res = lollipops_only_loop_decomposed_q(q, reaction_rules, &available_entities); - available_entities = res.into_iter().next()?; + available_entities = res.into_iter().next()?; } let mut freq = Frequency::new(); @@ -93,18 +96,18 @@ pub fn limit_frequency( lollipops_only_loop_decomposed_q(q.last().unwrap(), reaction_rules, &available_entities) - .iter().for_each(|e| freq.add(e, 0)); + .iter() + .for_each(|e| freq.add(e, 0)); Some(freq) } - // see fastFreq, q[i] is given enough times such that the stabilizes in a loop, // calculate the frequency of the symbols in any state in any loop, weighted. pub fn fast_frequency( q: &[RSset], reaction_rules: &[RSreaction], available_entities: &RSset, - weights: &[u32] + weights: &[u32], ) -> Option { // FIXME: we return the empty frequency or do we not return anything? let mut available_entities = available_entities.clone(); @@ -112,12 +115,12 @@ pub fn fast_frequency( let mut freq = Frequency::new(); for (pos, (q, &w)) in q.iter().zip(weights).enumerate() { - freq.append_weight(w); - let hoop = lollipops_only_loop_decomposed_q(q, + freq.append_weight(w); + let hoop = lollipops_only_loop_decomposed_q(q, reaction_rules, &available_entities); - hoop.iter().for_each(|e| freq.add(e, pos)); - available_entities = hoop.into_iter().next()?; + hoop.iter().for_each(|e| freq.add(e, pos)); + available_entities = hoop.into_iter().next()?; } Some(freq) } diff --git a/src/rsprocess/grammar.lalrpop b/src/rsprocess/grammar.lalrpop index 809d59f..2901a1c 100644 --- a/src/rsprocess/grammar.lalrpop +++ b/src/rsprocess/grammar.lalrpop @@ -64,7 +64,8 @@ pub Reactions: Vec = { Reaction: RSreaction = { "[" "," "," "]" => RSreaction::from(r, i, p), - "[" "r:" "," "i:" "," "p:" "]" => RSreaction::from(r, i, p), + "[" "r:" "," "i:" "," "p:" "]" => + RSreaction::from(r, i, p), } // ----------------------------------------------------------------------------- @@ -87,14 +88,18 @@ CTX_process: RSprocess = { RSprocess::EntitySet{ entities: c, next_process: Rc::new(k) }, "(" ")" => k, "(" > ")" => - RSprocess::Summation{ children: k.into_iter().map(Rc::new).collect::>() }, + RSprocess::Summation{ + children: k.into_iter().map(Rc::new).collect::>() + }, "<" ">" "." => RSprocess::WaitEntity{ repeat: n, repeated_process: Rc::new(k1), - next_process: Rc::new(k)}, + next_process: Rc::new(k) }, "nil" => RSprocess::Nill, => - RSprocess::RecursiveIdentifier{ identifier: translator.encode(identifier) } + RSprocess::RecursiveIdentifier{ + identifier: translator.encode(identifier) + } }; // ----------------------------------------------------------------------------- @@ -165,5 +170,8 @@ pub System: RSsystem = { "Initial Entities:" "Context:" "Reactions:" - => RSsystem::from(delta.into(), available_entities, context_process, Rc::new(reaction_rules)) + => 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 874cb0b..0d88a94 100644 --- a/src/rsprocess/mod.rs +++ b/src/rsprocess/mod.rs @@ -1,9 +1,9 @@ -pub mod translator; -pub mod structure; -pub mod support_structures; pub mod classical; -pub mod transitions; -pub mod perpetual; pub mod confluence; pub mod frequency; +pub mod perpetual; pub mod statistics; +pub mod structure; +pub mod support_structures; +pub mod transitions; +pub mod translator; diff --git a/src/rsprocess/perpetual.rs b/src/rsprocess/perpetual.rs index 018c698..f09d3d9 100644 --- a/src/rsprocess/perpetual.rs +++ b/src/rsprocess/perpetual.rs @@ -1,15 +1,14 @@ #![allow(dead_code)] use super::classical::compute_all_owned; -use super::translator::IdType; use super::structure::{RSenvironment, RSprocess, RSreaction, RSset, RSsystem}; - +use super::translator::IdType; // returns the prefix and the loop from a trace fn split<'a>( set: &'a RSset, trace: &'a [RSset] -) -> Option<(&'a[RSset], &'a[RSset])> { +) -> Option<(&'a [RSset], &'a [RSset])> { let position = trace.iter().rposition(|x| x == set); position.map(|pos| trace.split_at(pos)) } @@ -23,35 +22,37 @@ fn find_loop( let mut entities = entities; let mut trace = vec![]; loop { - if let Some((prefix, hoop)) = split(&entities, &trace) { - return (prefix.to_vec(), hoop.to_vec()); - } else { - let t = entities.union(q); - let products = compute_all_owned(&t, rs); - trace.push(entities.clone()); - entities = products; - } + if let Some((prefix, hoop)) = split(&entities, &trace) { + return (prefix.to_vec(), hoop.to_vec()); + } else { + let t = entities.union(q); + let products = compute_all_owned(&t, rs); + trace.push(entities.clone()); + entities = products; + } } } - // finds the loops by simulating the system -fn find_only_loop(rs: &[RSreaction], entities: RSset, q: &RSset) -> Vec { +fn find_only_loop( + rs: &[RSreaction], + entities: RSset, + q: &RSset +) -> Vec { let mut entities = entities; let mut trace = vec![]; loop { - if let Some((_prefix, hoop)) = split(&entities, &trace) { - return hoop.to_vec(); - } else { - let t = entities.union(q); - let products = compute_all_owned(&t, rs); - trace.push(entities.clone()); - entities = products; - } + if let Some((_prefix, hoop)) = split(&entities, &trace) { + return hoop.to_vec(); + } else { + let t = entities.union(q); + let products = compute_all_owned(&t, rs); + trace.push(entities.clone()); + entities = products; + } } } - // finds the loops and the length of the prefix by simulating the system fn find_prefix_len_loop( rs: &[RSreaction], @@ -61,14 +62,14 @@ fn find_prefix_len_loop( let mut entities = entities; let mut trace = vec![]; loop { - if let Some((prefix, hoop)) = split(&entities, &trace) { - return (prefix.len(), hoop.to_vec()); - } else { - let t = entities.union(q); - let products = compute_all_owned(&t, rs); - trace.push(entities.clone()); - entities = products; - } + if let Some((prefix, hoop)) = split(&entities, &trace) { + return (prefix.len(), hoop.to_vec()); + } else { + let t = entities.union(q); + let products = compute_all_owned(&t, rs); + trace.push(entities.clone()); + entities = products; + } } } @@ -80,22 +81,25 @@ fn filter_delta<'a>(x: (&IdType, &'a RSprocess)) -> Option<&'a RSset> { use super::structure::RSprocess::*; let (id, rest) = x; - if let EntitySet{ entities, next_process} = rest { - if let RecursiveIdentifier{ identifier } = &**next_process { - if identifier == id { - return Some(entities); - } - } + if let EntitySet { + entities, + next_process, + } = rest + { + if let RecursiveIdentifier { identifier } = &**next_process { + if identifier == id { + return Some(entities); + } + } } None } - // see lollipop pub fn lollipops_decomposed( delta: &RSenvironment, reaction_rules: &[RSreaction], - available_entities: &RSset + available_entities: &RSset, ) -> Vec<(Vec, Vec)> { // FIXME: i think we are only interested in "x", not all symbols that // satisfy X = pre(Q, rec(X)) @@ -110,9 +114,11 @@ pub fn lollipops_decomposed( // see lollipop pub fn lollipops(system: RSsystem) -> Vec<(Vec, Vec)> { - lollipops_decomposed(system.get_delta(), - system.get_reaction_rules(), - system.get_available_entities()) + lollipops_decomposed( + system.get_delta(), + system.get_reaction_rules(), + system.get_available_entities(), + ) } // see loop @@ -121,18 +127,21 @@ pub fn lollipops_only_loop(system: RSsystem) -> Vec> { // satisfy X = pre(Q, rec(X)) let filtered = system.get_delta().iter().filter_map(filter_delta); - let find_loop_fn = |q| find_only_loop(system.get_reaction_rules(), - system.get_available_entities().clone(), - q); + let find_loop_fn = |q| { + find_only_loop( + system.get_reaction_rules(), + system.get_available_entities().clone(), + q, + ) + }; filtered.map(find_loop_fn).collect::>() } - pub fn lollipops_prefix_len_loop_decomposed( delta: &RSenvironment, reaction_rules: &[RSreaction], - available_entities: &RSset + available_entities: &RSset, ) -> Vec<(usize, Vec)> { // FIXME: i think we are only interested in "x", not all symbols that // satisfy X = pre(Q, rec(X)) @@ -149,15 +158,15 @@ pub fn lollipops_prefix_len_loop_decomposed( pub fn lollipops_only_loop_decomposed( delta: &RSenvironment, reaction_rules: &[RSreaction], - available_entities: &RSset + available_entities: &RSset, ) -> Vec> { // FIXME: i think we are only interested in "x", not all symbols that // satisfy X = pre(Q, rec(X)) let filtered = delta.iter().filter_map(filter_delta); let find_loop_fn = |q| find_only_loop(reaction_rules, - available_entities.clone(), - q); + available_entities.clone(), + q); filtered.map(find_loop_fn).collect::>() } @@ -175,15 +184,19 @@ fn filter_delta_named<'a>( use super::structure::RSprocess::*; let (id, rest) = x; if id != symb { - return None; + return None; } - if let EntitySet{ entities, next_process} = rest { - if let RecursiveIdentifier{ identifier } = &**next_process { - if identifier == id { - return Some(entities); - } - } + if let EntitySet { + entities, + next_process, + } = rest + { + if let RecursiveIdentifier { identifier } = &**next_process { + if identifier == id { + return Some(entities); + } + } } None } @@ -193,9 +206,12 @@ pub fn lollipops_decomposed_named( delta: &RSenvironment, reaction_rules: &[RSreaction], available_entities: &RSset, - symb: IdType + symb: IdType, ) -> Option<(Vec, Vec)> { - let filtered = delta.iter().filter_map(|x| filter_delta_named(x, &symb)).next(); + let filtered = delta + .iter() + .filter_map(|x| filter_delta_named(x, &symb)) + .next(); let find_loop_fn = |q| find_loop(reaction_rules, available_entities.clone(), @@ -209,10 +225,12 @@ pub fn lollipops_named( system: RSsystem, symb: IdType ) -> Option<(Vec, Vec)> { - lollipops_decomposed_named(system.get_delta(), - system.get_reaction_rules(), - system.get_available_entities(), - symb) + lollipops_decomposed_named( + system.get_delta(), + system.get_reaction_rules(), + system.get_available_entities(), + symb, + ) } // see loop @@ -220,13 +238,19 @@ pub fn lollipops_only_loop_named( system: RSsystem, symb: IdType ) -> Option> { - let filtered = system.get_delta().iter() - .filter_map(|x| filter_delta_named(x, &symb)).next(); + let filtered = system + .get_delta() + .iter() + .filter_map(|x| filter_delta_named(x, &symb)) + .next(); - let find_loop_fn = - |q| find_only_loop(system.get_reaction_rules(), - system.get_available_entities().clone(), - q); + let find_loop_fn = |q| { + find_only_loop( + system.get_reaction_rules(), + system.get_available_entities().clone(), + q, + ) + }; filtered.map(find_loop_fn) } @@ -235,10 +259,12 @@ pub fn lollipops_prefix_len_loop_decomposed_named( delta: &RSenvironment, reaction_rules: &[RSreaction], available_entities: &RSset, - symb: IdType + symb: IdType, ) -> Option<(usize, Vec)> { - let filtered = delta.iter() - .filter_map(|x| filter_delta_named(x, &symb)).next(); + let filtered = delta + .iter() + .filter_map(|x| filter_delta_named(x, &symb)) + .next(); let find_loop_fn = |q| find_prefix_len_loop(reaction_rules, available_entities.clone(), @@ -252,10 +278,12 @@ pub fn lollipops_only_loop_decomposed_named( delta: &RSenvironment, reaction_rules: &[RSreaction], available_entities: &RSset, - symb: IdType + symb: IdType, ) -> Option> { - let filtered = delta.iter() - .filter_map(|x| filter_delta_named(x, &symb)).next(); + let filtered = delta + .iter() + .filter_map(|x| filter_delta_named(x, &symb)) + .next(); let find_loop_fn = |q| find_only_loop(reaction_rules, available_entities.clone(), diff --git a/src/rsprocess/statistics.rs b/src/rsprocess/statistics.rs index a602619..79e2f11 100644 --- a/src/rsprocess/statistics.rs +++ b/src/rsprocess/statistics.rs @@ -10,122 +10,119 @@ pub fn of_RSsystem<'a>(translator: &'a Translator, system: &'a RSsystem) -> Stri 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())) - ); + 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 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 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)) - ); + 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)) - ); + 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)) - ); + 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()); + 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)) - ); + 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 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)) - ); + 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!( + "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()) - ); + 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); - } + 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!( + "- 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(&format!( + "- there are {} reactions that will never be enabled.\n", + nonadmissible_reactions.len() + )); result.push_str( "=============================================================" ); diff --git a/src/rsprocess/structure.rs b/src/rsprocess/structure.rs index cdd083b..3f1b69c 100644 --- a/src/rsprocess/structure.rs +++ b/src/rsprocess/structure.rs @@ -1,104 +1,116 @@ #![allow(dead_code)] +use super::translator::IdType; use std::collections::{BTreeSet, HashMap, VecDeque}; use std::hash::Hash; use std::rc::Rc; -use super::translator::{IdType}; // ----------------------------------------------------------------------------- // RSset // ----------------------------------------------------------------------------- #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] pub struct RSset { - identifiers: BTreeSet + identifiers: BTreeSet, } impl From<[IdType; N]> for RSset { fn from(arr: [IdType; N]) -> Self { - RSset{identifiers: BTreeSet::from(arr)} + RSset { + identifiers: BTreeSet::from(arr), + } } } impl From<&[IdType]> for RSset { fn from(arr: &[IdType]) -> Self { - RSset{identifiers: BTreeSet::from_iter(arr.to_vec())} + RSset { + identifiers: BTreeSet::from_iter(arr.to_vec()), + } } } impl From> for RSset { fn from(arr: Vec) -> Self { - RSset{identifiers: BTreeSet::from_iter(arr)} + RSset { + identifiers: BTreeSet::from_iter(arr), + } } } impl RSset { pub fn new() -> Self { - RSset{identifiers: BTreeSet::new()} + RSset { + identifiers: BTreeSet::new(), + } } pub fn is_subset(&self, b: &RSset) -> bool { - self.identifiers.is_subset(&b.identifiers) + self.identifiers.is_subset(&b.identifiers) } pub fn is_disjoint(&self, b: &RSset) -> bool { - self.identifiers.is_disjoint(&b.identifiers) + self.identifiers.is_disjoint(&b.identifiers) } pub fn union(&self, b: &RSset) -> RSset { - // TODO maybe find more efficient way without copy/clone - let mut ret: RSset = b.clone(); - ret.identifiers.extend(self.identifiers.iter()); - ret + // TODO maybe find more efficient way without copy/clone + let mut ret: RSset = b.clone(); + ret.identifiers.extend(self.identifiers.iter()); + ret } pub fn union_option(&self, b: Option<&RSset>) -> RSset { - if let Some(b) = b { - self.union(b) - } else { - self.clone() - } + if let Some(b) = b { + self.union(b) + } else { + self.clone() + } } pub fn intersection(&self, b: &RSset) -> RSset { - // TODO maybe find more efficient way without copy/clone - let res: BTreeSet<_> = b.identifiers.intersection(&self.identifiers) - .copied() - .collect(); - RSset { identifiers: res } + // TODO maybe find more efficient way without copy/clone + let res: BTreeSet<_> = b + .identifiers + .intersection(&self.identifiers) + .copied() + .collect(); + RSset { identifiers: res } } pub fn subtraction(&self, b: &RSset) -> RSset { - // TODO maybe find more efficient way without copy/clone - let res: BTreeSet<_> = self.identifiers.difference(&b.identifiers) - .copied() - .collect(); - RSset { identifiers: res } + // TODO maybe find more efficient way without copy/clone + let res: BTreeSet<_> = self + .identifiers + .difference(&b.identifiers) + .copied() + .collect(); + RSset { identifiers: res } } pub fn set(&self) -> &BTreeSet { - &self.identifiers + &self.identifiers } pub fn iter(&self) -> std::collections::btree_set::Iter<'_, IdType> { - self.identifiers.iter() + self.identifiers.iter() } pub fn len(&self) -> usize { - self.identifiers.len() + self.identifiers.len() } pub fn insert(&mut self, el: IdType) -> bool { - self.identifiers.insert(el) + self.identifiers.insert(el) } pub fn push(&mut self, b: &RSset) { - self.identifiers.extend(b.iter()) + self.identifiers.extend(b.iter()) } } impl Default for RSset { fn default() -> Self { - RSset::new() + RSset::new() } } @@ -107,11 +119,10 @@ impl IntoIterator for RSset { type IntoIter = std::collections::btree_set::IntoIter; fn into_iter(self) -> Self::IntoIter { - self.identifiers.into_iter() + self.identifiers.into_iter() } } - // ----------------------------------------------------------------------------- // RSreaction // ----------------------------------------------------------------------------- @@ -119,124 +130,141 @@ impl IntoIterator for RSset { pub struct RSreaction { reactants: RSset, inihibitors: RSset, - products: RSset + products: RSset, } impl RSreaction { pub fn new() -> Self { - RSreaction{ reactants: RSset::new(), - inihibitors: RSset::new(), - products: RSset::new(), } + RSreaction { + reactants: RSset::new(), + inihibitors: RSset::new(), + products: RSset::new(), + } } pub fn from(reactants: RSset, inihibitors: RSset, products: RSset) -> Self { - RSreaction{ reactants, - inihibitors, - products } + RSreaction { + reactants, + inihibitors, + products, + } } // see enable pub fn enabled(&self, current_state: &RSset) -> bool { - self.reactants.is_subset(current_state) + self.reactants.is_subset(current_state) && self.inihibitors.is_disjoint(current_state) } pub fn products_clone(&self) -> RSset { - self.products.clone() + self.products.clone() } pub fn reactants(&self) -> &RSset { - &self.reactants + &self.reactants } pub fn inihibitors(&self) -> &RSset { - &self.inihibitors + &self.inihibitors } pub fn products(&self) -> &RSset { - &self.products + &self.products } } impl Default for RSreaction { fn default() -> Self { - RSreaction::new() + RSreaction::new() } } - - // ----------------------------------------------------------------------------- // RSprocess // ----------------------------------------------------------------------------- #[derive(Clone, Debug)] pub enum RSprocess { Nill, - RecursiveIdentifier{ identifier: IdType }, - EntitySet{ entities: RSset, - next_process: Rc }, - WaitEntity{ repeat: i64, - repeated_process: Rc, - next_process: Rc }, - Summation{ children: Vec> }, - NondeterministicChoice{ children: Vec> } + RecursiveIdentifier { + identifier: IdType, + }, + EntitySet { + entities: RSset, + next_process: Rc, + }, + WaitEntity { + repeat: i64, + repeated_process: Rc, + next_process: Rc, + }, + Summation { + children: Vec>, + }, + NondeterministicChoice { + children: Vec>, + }, } impl RSprocess { // TODO: remove all the clone() - pub fn concat(&self, new: &RSprocess) -> RSprocess{ - match (self, new) { - (RSprocess::NondeterministicChoice{children: c1}, - RSprocess::NondeterministicChoice{children: c2}) => { - RSprocess::NondeterministicChoice { - children: [c1.clone(), - c2.clone()].concat() - } - }, - (RSprocess::NondeterministicChoice{children}, new) | - (new, RSprocess::NondeterministicChoice{children}) => { - let mut new_children = children.clone(); - new_children.push(Rc::new(new.clone())); - RSprocess::NondeterministicChoice{ children: new_children } - }, - (_, _) => { - RSprocess::NondeterministicChoice { - children: vec![Rc::new(self.clone()), - Rc::new(new.clone())] - } - } - } + pub fn concat(&self, new: &RSprocess) -> RSprocess { + match (self, new) { + ( + RSprocess::NondeterministicChoice { children: c1 }, + RSprocess::NondeterministicChoice { children: c2 }, + ) => RSprocess::NondeterministicChoice { + children: [c1.clone(), c2.clone()].concat(), + }, + (RSprocess::NondeterministicChoice { children }, new) + | (new, RSprocess::NondeterministicChoice { children }) => { + let mut new_children = children.clone(); + new_children.push(Rc::new(new.clone())); + RSprocess::NondeterministicChoice { + children: new_children, + } + } + (_, _) => RSprocess::NondeterministicChoice { + children: vec![Rc::new(self.clone()), Rc::new(new.clone())], + }, + } } pub fn all_elements(&self) -> RSset { - let mut queue = VecDeque::from([self]); - let mut elements = RSset::new(); + 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 + 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 } } @@ -245,52 +273,60 @@ impl RSprocess { // ----------------------------------------------------------------------------- #[derive(Clone, Debug)] pub struct RSchoices { - context_moves: Vec<(Rc, Rc)> + context_moves: Vec<(Rc, Rc)>, } impl RSchoices { pub fn new() -> Self { - RSchoices{ context_moves: vec![] } + RSchoices { + context_moves: vec![], + } } pub fn new_not_empty() -> Self { - RSchoices{ context_moves: vec![(Rc::new(RSset::new()), - Rc::new(RSprocess::Nill))] } + RSchoices { + context_moves: vec![(Rc::new(RSset::new()), + Rc::new(RSprocess::Nill))], + } } pub fn append(&mut self, a: &mut RSchoices) { - self.context_moves.append(&mut a.context_moves); + self.context_moves.append(&mut a.context_moves); } pub fn replace(&mut self, a: Rc) { - self.context_moves = - self.context_moves - .iter_mut() - .map(|(c1, _)| (Rc::clone(c1), Rc::clone(&a))).collect::>(); + self.context_moves = self + .context_moves + .iter_mut() + .map(|(c1, _)| (Rc::clone(c1), Rc::clone(&a))) + .collect::>(); } pub fn shuffle(&mut self, choices: RSchoices) { - match (self.context_moves.is_empty(), choices.context_moves.is_empty()){ - (true, true) => {} - (true, false) => { self.context_moves = choices.context_moves } - (false, true) => {} - (false, false) => { - let mut new_self = vec![]; - for item_self in &self.context_moves { - for item_choices in &choices.context_moves { - new_self.push( - (Rc::new(item_self.0.union(&item_choices.0)), - Rc::new(item_self.1.concat(&item_choices.1))) - ); - } - } - self.context_moves = new_self; - } - } + match ( + self.context_moves.is_empty(), + choices.context_moves.is_empty(), + ) { + (true, true) => {} + (true, false) => self.context_moves = choices.context_moves, + (false, true) => {} + (false, false) => { + let mut new_self = vec![]; + for item_self in &self.context_moves { + for item_choices in &choices.context_moves { + new_self.push(( + Rc::new(item_self.0.union(&item_choices.0)), + Rc::new(item_self.1.concat(&item_choices.1)), + )); + } + } + self.context_moves = new_self; + } + } } pub fn iter(&self) -> std::slice::Iter<'_, (Rc, Rc)> { - self.context_moves.iter() + self.context_moves.iter() } } @@ -299,26 +335,29 @@ impl IntoIterator for RSchoices { type IntoIter = std::vec::IntoIter; fn into_iter(self) -> Self::IntoIter { - self.context_moves.into_iter() + self.context_moves.into_iter() } } - impl From<[(Rc, Rc); N]> for RSchoices { fn from(arr: [(Rc, Rc); N]) -> Self { - RSchoices{context_moves: arr.to_vec()} + RSchoices { + context_moves: arr.to_vec(), + } } } impl From<&[(Rc, Rc)]> for RSchoices { fn from(arr: &[(Rc, Rc)]) -> Self { - RSchoices{context_moves: arr.to_vec()} + RSchoices { + context_moves: arr.to_vec(), + } } } impl From, Rc)>> for RSchoices { fn from(arr: Vec<(Rc, Rc)>) -> Self { - RSchoices{context_moves: arr} + RSchoices { context_moves: arr } } } @@ -332,47 +371,55 @@ pub struct RSenvironment { impl RSenvironment { pub fn new() -> RSenvironment { - RSenvironment{definitions: HashMap::new()} + RSenvironment { + definitions: HashMap::new(), + } } pub fn get(&self, k: IdType) -> Option<&RSprocess> { - self.definitions.get(&k) + self.definitions.get(&k) } pub fn iter(&self) -> std::collections::hash_map::Iter<'_, u32, RSprocess> { - self.definitions.iter() + 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 + 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() + RSenvironment::new() } } impl From<[(IdType, RSprocess); N]> for RSenvironment { fn from(arr: [(IdType, RSprocess); N]) -> Self { - RSenvironment{definitions: HashMap::from(arr)} + RSenvironment { + definitions: HashMap::from(arr), + } } } impl From<&[(IdType, RSprocess)]> for RSenvironment { fn from(arr: &[(IdType, RSprocess)]) -> Self { - RSenvironment{definitions: HashMap::from_iter(arr.to_vec())} + RSenvironment { + definitions: HashMap::from_iter(arr.to_vec()), + } } } impl From> for RSenvironment { fn from(arr: Vec<(IdType, RSprocess)>) -> Self { - RSenvironment{definitions: HashMap::from_iter(arr)} + RSenvironment { + definitions: HashMap::from_iter(arr), + } } } @@ -389,44 +436,48 @@ pub struct RSsystem { impl RSsystem { pub fn new() -> RSsystem { - RSsystem { - delta: Rc::new(RSenvironment::new()), - available_entities: RSset::new(), - context_process: RSprocess::Nill, - reaction_rules: Rc::new(vec![]), - } + RSsystem { + delta: Rc::new(RSenvironment::new()), + available_entities: RSset::new(), + context_process: RSprocess::Nill, + reaction_rules: Rc::new(vec![]), + } } - pub fn from(delta: Rc, - available_entities: RSset, - context_process: RSprocess, - reaction_rules: Rc>) -> RSsystem { - RSsystem { delta: Rc::clone(&delta), - available_entities, - context_process, - reaction_rules: Rc::clone(&reaction_rules) } + pub fn from( + delta: Rc, + available_entities: RSset, + context_process: RSprocess, + reaction_rules: Rc>, + ) -> RSsystem { + RSsystem { + delta: Rc::clone(&delta), + available_entities, + context_process, + reaction_rules: Rc::clone(&reaction_rules), + } } pub fn get_delta(&self) -> &Rc { - &self.delta + &self.delta } pub fn get_available_entities(&self) -> &RSset { - &self.available_entities + &self.available_entities } pub fn get_context_process(&self) -> &RSprocess { - &self.context_process + &self.context_process } pub fn get_reaction_rules(&self) -> &Rc> { - &self.reaction_rules + &self.reaction_rules } } impl Default for RSsystem { fn default() -> Self { - RSsystem::new() + RSsystem::new() } } @@ -437,7 +488,8 @@ impl Default for RSsystem { pub struct RSlabel { pub available_entities: RSset, pub context: RSset, - pub t: RSset, /// union of available_entities and context + pub t: RSset, + /// union of available_entities and context pub reactants: RSset, pub reactantsi: RSset, // reactants absent pub inihibitors: RSset, @@ -447,42 +499,51 @@ pub struct RSlabel { impl RSlabel { pub fn new() -> Self { - RSlabel { available_entities: RSset::new(), - context: RSset::new(), - t: RSset::new(), - reactants: RSset::new(), - reactantsi: RSset::new(), - inihibitors: RSset::new(), - ireactants: RSset::new(), - products: RSset::new() } + RSlabel { + available_entities: RSset::new(), + context: RSset::new(), + t: RSset::new(), + reactants: RSset::new(), + reactantsi: RSset::new(), + inihibitors: RSset::new(), + ireactants: RSset::new(), + products: RSset::new(), + } } #[allow(clippy::too_many_arguments)] - pub fn from(available_entities: RSset, - context: RSset, - t: RSset, - reactants: RSset, - reactantsi: RSset, - inihibitors: RSset, - ireactants: RSset, - products: RSset,) -> Self { - RSlabel { available_entities, - context, - t, - reactants, - reactantsi, - inihibitors, - ireactants, - products } + pub fn from( + available_entities: RSset, + context: RSset, + t: RSset, + reactants: RSset, + reactantsi: RSset, + inihibitors: RSset, + ireactants: RSset, + products: RSset, + ) -> Self { + RSlabel { + available_entities, + context, + t, + reactants, + reactantsi, + inihibitors, + ireactants, + products, + } } pub fn get_context(&self) -> (RSset, RSset, RSset) { - // TODO remove clone? - (self.available_entities.clone(), self.context.clone(), self.t.clone()) + // TODO remove clone? + ( + self.available_entities.clone(), + self.context.clone(), + self.t.clone(), + ) } } - // ----------------------------------------------------------------------------- // RSassertOp // ----------------------------------------------------------------------------- @@ -491,7 +552,7 @@ pub enum RSassertOp { InW, InR, InI, - InP + InP, } // ----------------------------------------------------------------------------- @@ -504,7 +565,7 @@ pub enum RSassert { Or(Vec), And(Vec), Sub(RSset, RSassertOp), - NonEmpty(RSassertOp) + NonEmpty(RSassertOp), } // ----------------------------------------------------------------------------- @@ -518,5 +579,5 @@ pub enum RSBHML { Or(Vec), And(Vec), Diamond(Box, Box), - Box(Box, Box) + Box(Box, Box), } diff --git a/src/rsprocess/support_structures.rs b/src/rsprocess/support_structures.rs index e8ab343..ed0dd75 100644 --- a/src/rsprocess/support_structures.rs +++ b/src/rsprocess/support_structures.rs @@ -10,7 +10,9 @@ pub struct TransitionsIterator<'a> { } impl<'a> TransitionsIterator<'a> { - pub fn from(system: &'a RSsystem) -> Result, String> { + pub fn from( + system: &'a RSsystem + ) -> Result, String> { match unfold(system.get_delta(), system.get_context_process()) { Ok(o) => Ok(TransitionsIterator { choices_iterator: o.into_iter(), @@ -38,13 +40,13 @@ impl<'a> Iterator for TransitionsIterator<'a> { ), |acc, reaction| { if reaction.enabled(&t) { - ( + ( acc.0.union(reaction.reactants()), acc.1, acc.2.union(reaction.inihibitors()), acc.3, acc.4.union(reaction.products()), - ) + ) } else { ( acc.0, diff --git a/src/rsprocess/transitions.rs b/src/rsprocess/transitions.rs index 553854a..6bc7378 100644 --- a/src/rsprocess/transitions.rs +++ b/src/rsprocess/transitions.rs @@ -1,8 +1,11 @@ #![allow(dead_code)] -use super::structure::{ - RSchoices, RSenvironment, RSlabel, RSprocess, RSset, RSsystem -}; +use super::structure::{RSchoices, + RSenvironment, + RSlabel, + RSprocess, + RSset, + RSsystem}; use super::support_structures::TransitionsIterator; use std::rc::Rc; @@ -12,87 +15,87 @@ pub fn unfold( context_process: &RSprocess, ) -> Result { match context_process { - RSprocess::Nill => Ok(RSchoices::new()), - RSprocess::RecursiveIdentifier { identifier } => { - let newprocess = environment.get(*identifier); - if let Some(newprocess) = newprocess { - unfold(environment, newprocess) - } else { - Err(format!("Recursive call to missing symbol: {identifier}")) - } - } - RSprocess::EntitySet { - entities, - next_process, - } => Ok(RSchoices::from(vec![( - Rc::new(entities.clone()), - Rc::clone(next_process), - )])), - RSprocess::WaitEntity { - repeat, - repeated_process: _, - next_process, - } if *repeat <= 0 => unfold(environment, next_process), - RSprocess::WaitEntity { - repeat, - repeated_process, - next_process, - } if *repeat == 1 => { - let mut choices1 = unfold(environment, repeated_process)?; - choices1.replace(Rc::clone(next_process)); - Ok(choices1) - } - RSprocess::WaitEntity { - repeat, - repeated_process, - next_process, - } => { - let mut choices1 = unfold(environment, repeated_process)?; - choices1.replace(Rc::new(RSprocess::WaitEntity { - repeat: (*repeat - 1), - repeated_process: Rc::clone(repeated_process), - next_process: Rc::clone(next_process), - })); - Ok(choices1) - } - RSprocess::Summation { children } => { - // short-circuits with try_fold. - children.iter().try_fold(RSchoices::new(), |mut acc, x| { - match unfold(environment, x) { - Ok(mut choices) => { - acc.append(&mut choices); - Ok(acc) - } - Err(e) => Err(e), - } - }) - } - RSprocess::NondeterministicChoice { children } => { - // short-circuits with try_fold. - if children.is_empty() { - Ok(RSchoices::from(vec![( - Rc::new(RSset::new()), - Rc::new(RSprocess::Nill), - )])) - } else { - children.iter().try_fold(RSchoices::new(), |mut acc, x| { - acc.shuffle(unfold(environment, x)?); - Ok(acc) - }) - } - } + RSprocess::Nill => Ok(RSchoices::new()), + RSprocess::RecursiveIdentifier { identifier } => { + let newprocess = environment.get(*identifier); + if let Some(newprocess) = newprocess { + unfold(environment, newprocess) + } else { + Err(format!("Recursive call to missing symbol: {identifier}")) + } + } + RSprocess::EntitySet { + entities, + next_process, + } => Ok(RSchoices::from(vec![( + Rc::new(entities.clone()), + Rc::clone(next_process), + )])), + RSprocess::WaitEntity { + repeat, + repeated_process: _, + next_process, + } if *repeat <= 0 => unfold(environment, next_process), + RSprocess::WaitEntity { + repeat, + repeated_process, + next_process, + } if *repeat == 1 => { + let mut choices1 = unfold(environment, repeated_process)?; + choices1.replace(Rc::clone(next_process)); + Ok(choices1) + } + RSprocess::WaitEntity { + repeat, + repeated_process, + next_process, + } => { + let mut choices1 = unfold(environment, repeated_process)?; + choices1.replace(Rc::new(RSprocess::WaitEntity { + repeat: (*repeat - 1), + repeated_process: Rc::clone(repeated_process), + next_process: Rc::clone(next_process), + })); + Ok(choices1) + } + RSprocess::Summation { children } => { + // short-circuits with try_fold. + children.iter().try_fold(RSchoices::new(), |mut acc, x| { + match unfold(environment, x) { + Ok(mut choices) => { + acc.append(&mut choices); + Ok(acc) + } + Err(e) => Err(e), + } + }) + } + RSprocess::NondeterministicChoice { children } => { + // short-circuits with try_fold. + if children.is_empty() { + Ok(RSchoices::from(vec![( + Rc::new(RSset::new()), + Rc::new(RSprocess::Nill), + )])) + } else { + children.iter().try_fold(RSchoices::new(), |mut acc, x| { + acc.shuffle(unfold(environment, x)?); + Ok(acc) + }) + } + } } } pub fn iterator_transitions<'a>( - system: &'a RSsystem, + system: &'a RSsystem ) -> Result, String> { TransitionsIterator::from(system) } // see oneTransition, transition, smartTransition, smartOneTransition pub fn one_transition( - system: &RSsystem, + system: &RSsystem ) -> Result, String> { let mut tr = TransitionsIterator::from(system)?; Ok(tr.next()) @@ -100,23 +103,25 @@ pub fn one_transition( // see allTransitions, smartAllTransitions pub fn all_transitions( - system: &RSsystem, + system: &RSsystem ) -> Result, String> { let tr = TransitionsIterator::from(system)?; Ok(tr.collect::>()) } // see oneTarget, smartOneTarget, target, smartTarget -pub fn target(system: &RSsystem) -> Result<(i64, RSset), String> { +pub fn target( + system: &RSsystem +) -> Result<(i64, RSset), String> { let current = one_transition(system)?; if current.is_none() { - return Ok((0, system.get_available_entities().clone())); + return Ok((0, system.get_available_entities().clone())); } let mut n = 1; let mut current = current.unwrap().1; while let Some((_, next)) = one_transition(¤t)? { - current = next; - n += 1; + current = next; + n += 1; } Ok((n, current.get_available_entities().clone())) } @@ -125,7 +130,7 @@ pub fn target(system: &RSsystem) -> Result<(i64, RSset), String> { pub fn run(system: RSsystem) -> Result>, String> { let mut res = vec![Rc::new(system)]; while let Some((_, next_sys)) = one_transition(res.last().unwrap())? { - res.push(Rc::new(next_sys)); + res.push(Rc::new(next_sys)); } Ok(res) } @@ -137,14 +142,14 @@ pub fn run_separated( let mut res = vec![]; let current = one_transition(system)?; if current.is_none() { - return Ok(res); + return Ok(res); } let current = current.unwrap(); res.push(current.0.get_context()); let mut current = current.1; while let Some((label, next)) = one_transition(¤t)? { - current = next; - res.push(label.get_context()); + current = next; + res.push(label.get_context()); } Ok(res) } diff --git a/src/rsprocess/translator.rs b/src/rsprocess/translator.rs index 42517e8..82520b6 100644 --- a/src/rsprocess/translator.rs +++ b/src/rsprocess/translator.rs @@ -22,7 +22,7 @@ impl Translator { impl Default for Translator { fn default() -> Self { - Translator::new() + Translator::new() } } @@ -47,10 +47,13 @@ impl Translator { } // ----------------------------------------------------------------------------- -use super::{frequency::Frequency, structure::{ - RSassert, RSassertOp, RSchoices, RSenvironment, RSlabel, RSprocess, - RSreaction, RSset, RSsystem, RSBHML, -}}; +use super::{ + frequency::Frequency, + structure::{ + RSBHML, RSassert, RSassertOp, RSchoices, RSenvironment, RSlabel, + RSprocess, RSreaction, RSset, RSsystem, + }, +}; use std::fmt; #[allow(clippy::large_enum_variant)] @@ -98,9 +101,9 @@ pub enum WithTranslator<'a> { bhml: &'a RSBHML, }, Frequency { - translator: &'a Translator, - frequency: &'a Frequency, - } + translator: &'a Translator, + frequency: &'a Frequency, + }, } macro_rules! from_RS { @@ -125,7 +128,12 @@ impl<'a> WithTranslator<'a> { from_RS!(from_RSchoices, RSchoices, choices, RSchoices); - from_RS!(from_RSenvironment, RSenvironment, environment, RSenvironment); + from_RS!( + from_RSenvironment, + RSenvironment, + environment, + RSenvironment + ); from_RS!(from_RSsystem, RSsystem, system, RSsystem); @@ -216,8 +224,11 @@ fn print_process( let mut it = children.iter().peekable(); while let Some(child) = it.next() { if it.peek().is_none() { - write!(f, "{}", - WithTranslator::from_RSprocess(translator, child))?; + write!( + f, + "{}", + WithTranslator::from_RSprocess(translator, child) + )?; } else { write!( f, @@ -233,11 +244,17 @@ fn print_process( let mut it = children.iter().peekable(); while let Some(child) = it.next() { if it.peek().is_none() { - write!(f, "{}", - WithTranslator::from_RSprocess(translator, child))?; + write!( + f, + "{}", + WithTranslator::from_RSprocess(translator, child) + )?; } else { - write!(f, "{}, ", - WithTranslator::from_RSprocess(translator, child))?; + write!( + f, + "{}, ", + WithTranslator::from_RSprocess(translator, child) + )?; } } write!(f, "]") @@ -327,15 +344,17 @@ fn print_label( translator: &Translator, label: &RSlabel ) -> fmt::Result { - write!(f, "{{available_entities: {}, context: {}, t: {}, reactants: {}, reactantsi: {}, inihibitors: {}, ireactants: {}, products: {}}}", - WithTranslator::from_RSset(translator, &label.available_entities), - WithTranslator::from_RSset(translator, &label.context), - WithTranslator::from_RSset(translator, &label.t), - WithTranslator::from_RSset(translator, &label.reactants), - WithTranslator::from_RSset(translator, &label.reactantsi), - WithTranslator::from_RSset(translator, &label.inihibitors), - WithTranslator::from_RSset(translator, &label.ireactants), - WithTranslator::from_RSset(translator, &label.products), + write!( + f, + "{{available_entities: {}, context: {}, t: {}, reactants: {}, reactantsi: {}, inihibitors: {}, ireactants: {}, products: {}}}", + WithTranslator::from_RSset(translator, &label.available_entities), + WithTranslator::from_RSset(translator, &label.context), + WithTranslator::from_RSset(translator, &label.t), + WithTranslator::from_RSset(translator, &label.reactants), + WithTranslator::from_RSset(translator, &label.reactantsi), + WithTranslator::from_RSset(translator, &label.inihibitors), + WithTranslator::from_RSset(translator, &label.ireactants), + WithTranslator::from_RSset(translator, &label.products), ) } @@ -388,33 +407,33 @@ fn print_frequency( let mut freq_it = frequency.frequency_map.iter().peekable(); while let Some((e, freq)) = freq_it.next() { - write!(f, "{} -> ", translator.decode(*e))?; + write!(f, "{} -> ", translator.decode(*e))?; - let mut iter = freq.iter() - .zip(frequency.totals.iter() - .zip(frequency.weights.iter())) - .peekable(); + let mut iter = freq + .iter() + .zip(frequency.totals.iter().zip(frequency.weights.iter())) + .peekable(); - let mut total_freq = 0.; + let mut total_freq = 0.; - while let Some((freq_e, (total, weight))) = iter.next() { - let weighted_freq = (*freq_e as f32 * *weight as f32 * 100.)/(*total as f32); - - if iter.peek().is_none() { - write!(f, "{weighted_freq:.2}")?; - } else { - write!(f, "{weighted_freq:.2}, ")?; - } - total_freq += weighted_freq; - } + while let Some((freq_e, (total, weight))) = iter.next() { + let weighted_freq = (*freq_e as f32 * *weight as f32 * 100.) / (*total as f32); - total_freq /= frequency.total_weights() as f32; + if iter.peek().is_none() { + write!(f, "{weighted_freq:.2}")?; + } else { + write!(f, "{weighted_freq:.2}, ")?; + } + total_freq += weighted_freq; + } - write!(f, "(total: {total_freq:.2})")?; + total_freq /= frequency.total_weights() as f32; - if freq_it.peek().is_some() { - writeln!(f, ",")?; - } + write!(f, "(total: {total_freq:.2})")?; + + if freq_it.peek().is_some() { + writeln!(f, ",")?; + } } write!(f, "]") } @@ -422,28 +441,50 @@ fn print_frequency( impl<'a> fmt::Display for WithTranslator<'a> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self { - WithTranslator::RSset { translator, set, } => - print_set(f, translator, set), - WithTranslator::RSreaction { translator, reaction, } => - print_reaction(f, translator, reaction), - WithTranslator::RSprocess { translator, process, } => - print_process(f, translator, process), - WithTranslator::RSchoices { translator, choices, } => - print_choices(f, translator, choices), - WithTranslator::RSenvironment { translator, environment, } => - print_environment(f, translator, environment), - WithTranslator::RSsystem { translator, system, } => - print_system(f, translator, system), - WithTranslator::RSlabel { translator, label, } => - print_label(f, translator, label), - WithTranslator::RSassertOp { translator, assert_op, } => - print_assert_op(f, translator, assert_op), - WithTranslator::RSassert { translator, assert, } => - print_assert(f, translator, assert), - WithTranslator::RSBHML { translator, bhml, } => - print_bhml(f, translator, bhml), - WithTranslator::Frequency { translator, frequency } => - print_frequency(f, translator, frequency), + WithTranslator::RSset { + translator, + set + } => print_set(f, translator, set), + WithTranslator::RSreaction { + translator, + reaction, + } => print_reaction(f, translator, reaction), + WithTranslator::RSprocess { + translator, + process, + } => print_process(f, translator, process), + WithTranslator::RSchoices { + translator, + choices, + } => print_choices(f, translator, choices), + WithTranslator::RSenvironment { + translator, + environment, + } => print_environment(f, translator, environment), + WithTranslator::RSsystem { + translator, + system + } => print_system(f, translator, system), + WithTranslator::RSlabel { + translator, + label + } => print_label(f, translator, label), + WithTranslator::RSassertOp { + translator, + assert_op, + } => print_assert_op(f, translator, assert_op), + WithTranslator::RSassert { + translator, + assert + } => print_assert(f, translator, assert), + WithTranslator::RSBHML { + translator, + bhml + } => print_bhml(f, translator, bhml), + WithTranslator::Frequency { + translator, + frequency, + } => print_frequency(f, translator, frequency), } } } diff --git a/testing/first.system b/testing/first.system index 37d49d8..765bddb 100644 --- a/testing/first.system +++ b/testing/first.system @@ -1,4 +1,4 @@ -Environment: [x = {a}.y, y =({a}.x + {b}.y)] +Environment: [x = {a}.y, y =({a}.nill + {b}.nill)] Initial Entities: {a, b} Context: [({a,b}.{a}.{a,c}.x + {a,b}.{a}.{a}.nil)] Reactions: ([r: {a,b}, i: {c}, p: {b}])