From bf2403cdcf7e16edc951607f18cfafbbb28c7e48 Mon Sep 17 00:00:00 2001 From: elvis Date: Tue, 26 Aug 2025 16:56:08 +0200 Subject: [PATCH] Introducing traits for sets and reactions --- src/rsprocess/assert/dsl.rs | 1 + src/rsprocess/assert/tests.rs | 56 +++--- src/rsprocess/choices.rs | 4 +- src/rsprocess/environment.rs | 8 +- src/rsprocess/format_helpers.rs | 4 +- src/rsprocess/frequency.rs | 4 +- src/rsprocess/graph.rs | 8 +- src/rsprocess/label.rs | 18 +- src/rsprocess/process.rs | 4 +- src/rsprocess/reaction.rs | 321 +++++++++++++++++--------------- src/rsprocess/set.rs | 230 +++++++++++++---------- src/rsprocess/system.rs | 12 +- src/rsprocess/system_test.rs | 4 +- src/rsprocess/transitions.rs | 13 +- 14 files changed, 376 insertions(+), 311 deletions(-) diff --git a/src/rsprocess/assert/dsl.rs b/src/rsprocess/assert/dsl.rs index 4f5becf..f36dadc 100644 --- a/src/rsprocess/assert/dsl.rs +++ b/src/rsprocess/assert/dsl.rs @@ -1,6 +1,7 @@ use std::collections::HashMap; use super::super::{translator, graph, set, process, system, label}; +use super::super::set::BasicSet; /// If changing IntegerType in assert.rs, also change from Num to another /// similar parser with different return type in grammar.lalrpop in diff --git a/src/rsprocess/assert/tests.rs b/src/rsprocess/assert/tests.rs index 2f70cae..d809749 100644 --- a/src/rsprocess/assert/tests.rs +++ b/src/rsprocess/assert/tests.rs @@ -890,12 +890,12 @@ fn for_1() { Box::new(Tree::Assignment( Variable::Id("a".into()), None, - Box::new(Expression::Set(Set::new())) + Box::new(Expression::Set(Set::default())) )), Box::new(Tree::Assignment( Variable::Id("b".into()), None, - Box::new(Expression::Set(Set::new())) + Box::new(Expression::Set(Set::default())) )), )), Box::new(Tree::For( @@ -945,7 +945,7 @@ fn for_2() { Box::new(Tree::Assignment( Variable::Id("b".into()), None, - Box::new(Expression::Set(Set::new())) + Box::new(Expression::Set(Set::default())) )), )), Box::new(Tree::For( @@ -996,19 +996,19 @@ fn for_3() { None, Box::new(Expression::Label( Box::new(Label::from(Set::from([1, 2]), - Set::new(), + Set::default(), Set::from([1, 2]), - Set::new(), - Set::new(), - Set::new(), - Set::new(), - Set::new())) + Set::default(), + Set::default(), + Set::default(), + Set::default(), + Set::default())) )) )), Box::new(Tree::Assignment( Variable::Id("b".into()), None, - Box::new(Expression::Set(Set::new())) + Box::new(Expression::Set(Set::default())) )), )), Box::new(Tree::For( @@ -1066,17 +1066,17 @@ fn for_4() { Box::new(Label::from(Set::from([1, 2]), Set::from([3]), Set::from([1, 2, 3]), - Set::new(), - Set::new(), - Set::new(), - Set::new(), - Set::new())) + Set::default(), + Set::default(), + Set::default(), + Set::default(), + Set::default())) )) )), Box::new(Tree::Assignment( Variable::Id("b".into()), None, - Box::new(Expression::Set(Set::new())) + Box::new(Expression::Set(Set::default())) )), )), Box::new(Tree::For( @@ -1133,13 +1133,13 @@ fn for_5() { None, Box::new(Expression::Label( Box::new(Label::from(Set::from([1, 2]), - Set::from([3]), - Set::from([1, 2, 3]), - Set::new(), - Set::new(), - Set::new(), - Set::new(), - Set::new())) + Set::from([3]), + Set::from([1, 2, 3]), + Set::default(), + Set::default(), + Set::default(), + Set::default(), + Set::default())) )) )), Box::new(Tree::Assignment( @@ -1217,11 +1217,11 @@ fn for_6() { Box::new(Label::from(Set::from([1, 2]), Set::from([3]), Set::from([1, 2, 3]), - Set::new(), - Set::new(), - Set::new(), - Set::new(), - Set::new())) + Set::default(), + Set::default(), + Set::default(), + Set::default(), + Set::default())) )) )), Box::new(Tree::Concat( diff --git a/src/rsprocess/choices.rs b/src/rsprocess/choices.rs index a1f2c37..f35f8ad 100644 --- a/src/rsprocess/choices.rs +++ b/src/rsprocess/choices.rs @@ -1,7 +1,7 @@ use std::rc::Rc; use super::process::Process; -use super::set::Set; +use super::set::{BasicSet, Set}; use super::translator::{Translator, PrintableWithTranslator, Formatter}; #[derive(Clone, Debug)] @@ -18,7 +18,7 @@ impl Choices { pub fn new_not_empty() -> Self { Choices { - context_moves: vec![(Rc::new(Set::new()), + context_moves: vec![(Rc::new(Set::default()), Rc::new(Process::Nill))], } } diff --git a/src/rsprocess/environment.rs b/src/rsprocess/environment.rs index 1b91ede..c146c60 100644 --- a/src/rsprocess/environment.rs +++ b/src/rsprocess/environment.rs @@ -5,8 +5,8 @@ use std::rc::Rc; use super::choices::Choices; use super::process::Process; -use super::reaction::Reaction; -use super::set::Set; +use super::reaction::{Reaction, BasicReaction, ExtensionReaction}; +use super::set::{BasicSet, Set}; use super::translator::{IdType, Translator, PrintableWithTranslator, Formatter}; #[derive(Clone, Debug, Serialize, Deserialize)] @@ -30,7 +30,7 @@ impl Environment { } pub fn all_elements(&self) -> Set { - let mut acc = Set::new(); + let mut acc = Set::default(); for (_, process) in self.definitions.iter() { acc.push(&process.all_elements()); } @@ -110,7 +110,7 @@ impl Environment { // short-circuits with try_fold. if children.is_empty() { Ok(Choices::from(vec![( - Rc::new(Set::new()), + Rc::new(Set::default()), Rc::new(Process::Nill), )])) } else { diff --git a/src/rsprocess/format_helpers.rs b/src/rsprocess/format_helpers.rs index b90872e..7b977c6 100644 --- a/src/rsprocess/format_helpers.rs +++ b/src/rsprocess/format_helpers.rs @@ -1,5 +1,5 @@ pub mod graph_map_nodes_ty_from { - use super::super::set::Set; + use super::super::set::{BasicSet, Set}; use super::super::system::System; use super::super::translator; use std::rc::Rc; @@ -74,7 +74,7 @@ pub mod graph_map_nodes_ty_from { pub mod graph_map_edges_ty_from { - use super::super::set::Set; + use super::super::set::{BasicSet, Set}; use super::super::label::Label; use super::super::translator; use std::rc::Rc; diff --git a/src/rsprocess/frequency.rs b/src/rsprocess/frequency.rs index 88da04b..1939c92 100644 --- a/src/rsprocess/frequency.rs +++ b/src/rsprocess/frequency.rs @@ -2,8 +2,8 @@ use std::collections::HashMap; -use super::reaction::Reaction; -use super::set::Set; +use super::reaction::{Reaction, ExtensionReaction}; +use super::set::{Set, ExtensionsSet}; use super::system::System; use super::translator::{IdType, Translator, PrintableWithTranslator, PRECISION}; diff --git a/src/rsprocess/graph.rs b/src/rsprocess/graph.rs index a30fa1e..4400edf 100644 --- a/src/rsprocess/graph.rs +++ b/src/rsprocess/graph.rs @@ -5,7 +5,7 @@ use petgraph::{Graph, Directed}; use std::rc::Rc; use super::label::Label; -use super::set::Set; +use super::set::{BasicSet, Set}; use super::system::System; use super::translator::{self, IdType}; @@ -19,7 +19,7 @@ fn common_system_entities(graph: &SystemGraph) -> Set { None => Some(node.1.available_entities.clone()), Some(acc) => Some(node.1.available_entities.intersection(&acc)) } - ).unwrap_or(Set::new()) + ).unwrap_or(Set::default()) } macro_rules! common_label { @@ -39,7 +39,7 @@ macro_rules! common_label { Some($acc_name) => Some($some_expr) } } - ).unwrap_or(Set::new()) + ).unwrap_or(Set::default()) } }; } @@ -218,7 +218,7 @@ impl NodeDisplay { if self.contains_uncommon() { Rc::new(common_system_entities(current_graph)) } else { - Rc::new(Set::new()) + Rc::new(Set::default()) }; Box::new( diff --git a/src/rsprocess/label.rs b/src/rsprocess/label.rs index 88b59e6..57b5cdc 100644 --- a/src/rsprocess/label.rs +++ b/src/rsprocess/label.rs @@ -1,7 +1,7 @@ use serde::{Deserialize, Serialize}; use std::hash::Hash; -use super::set::Set; +use super::set::{BasicSet, Set}; use super::translator::{Translator, PrintableWithTranslator, Formatter}; #[derive(Clone, Debug, Serialize, Deserialize, Eq, PartialOrd)] @@ -19,14 +19,14 @@ pub struct Label { impl Label { pub fn new() -> Self { Label { - available_entities: Set::new(), - context: Set::new(), - t: Set::new(), - reactants: Set::new(), - reactants_absent: Set::new(), - inhibitors: Set::new(), - inhibitors_present: Set::new(), - products: Set::new(), + available_entities: Set::default(), + context: Set::default(), + t: Set::default(), + reactants: Set::default(), + reactants_absent: Set::default(), + inhibitors: Set::default(), + inhibitors_present: Set::default(), + products: Set::default(), } } diff --git a/src/rsprocess/process.rs b/src/rsprocess/process.rs index 65d0fba..10c932e 100644 --- a/src/rsprocess/process.rs +++ b/src/rsprocess/process.rs @@ -4,7 +4,7 @@ use std::hash::Hash; use std::rc::Rc; use super::reaction::Reaction; -use super::set::Set; +use super::set::{Set, BasicSet}; use super::translator::{IdType, Translator, PrintableWithTranslator, Formatter}; #[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] @@ -61,7 +61,7 @@ impl Process { /// returns all elements used pub fn all_elements(&self) -> Set { let mut queue = VecDeque::from([self]); - let mut elements = Set::new(); + let mut elements = Set::default(); while let Some(el) = queue.pop_front() { match el { diff --git a/src/rsprocess/reaction.rs b/src/rsprocess/reaction.rs index 582319c..431f8e2 100644 --- a/src/rsprocess/reaction.rs +++ b/src/rsprocess/reaction.rs @@ -6,161 +6,190 @@ use serde::{Deserialize, Serialize}; use std::hash::Hash; -use super::set::Set; +use super::set::{BasicSet, ExtensionsSet, Set}; use super::translator::{Translator, PrintableWithTranslator, Formatter}; +pub trait BasicReaction: +Clone + Default + Eq + Hash + Serialize + PrintableWithTranslator +where for<'de> Self: Deserialize<'de>, +{ + fn enabled(&self, state: &S) -> bool; + fn compute_step(&self, state: &S) -> Option<&S>; +} + +pub trait ExtensionReaction { + fn compute_all(reactions: &[Self], state: &S) -> S + where Self: Sized; + + fn find_loop(reactions: &[Self], entities: S, q: &S) -> (Vec, Vec) + where Self: Sized; + + fn find_only_loop(reactions: &[Self], entities: S, q: &S) -> Vec + where Self: Sized; + + fn find_prefix_len_loop( + reactions: &[Self], + entities: S, + q: &S + ) -> (usize, Vec) + where Self: Sized; + + fn lollipops_only_loop_decomposed_q( + reactions: &[Self], + entities: &S, + q: &S + ) -> Vec + where Self: Sized; +} + + +impl, S: BasicSet> ExtensionReaction for T { + /// Computes the result of a series of reactions. Returns the union of all + /// products. + /// see result + fn compute_all( + reactions: &[Self], + state: &S + ) -> S + where Self: Sized { + reactions.iter().fold(S::default(), |mut acc: S, r| { + acc.extend(r.compute_step(state)); + acc + }) + } + + /// Finds the loops by simulating the system. + fn find_loop( + reactions: &[Self], + entities: S, + q: &S + ) -> (Vec, Vec) { + let mut entities = entities; + let mut trace = vec![]; + loop { + if let Some((prefix, hoop)) = entities.split(&trace) { + return (prefix.to_vec(), hoop.to_vec()); + } else { + let t = entities.union(q); + let products = Self::compute_all(reactions, &t); + trace.push(entities.clone()); + entities = products; + } + } + } + + + /// Finds the loops by simulating the system. + fn find_only_loop( + reactions: &[Self], + entities: S, + q: &S + ) -> Vec { + let mut entities = entities; + let mut trace = vec![]; + loop { + if let Some((_prefix, hoop)) = entities.split(&trace) { + return hoop.to_vec(); + } else { + let t = entities.union(q); + let products = Self::compute_all(reactions, &t); + trace.push(entities.clone()); + entities = products; + } + } + } + + + /// Finds the loops and the length of the prefix by simulating the system. + fn find_prefix_len_loop( + reactions: &[Self], + entities: S, + q: &S + ) -> (usize, Vec) { + let mut entities = entities; + let mut trace = vec![]; + loop { + if let Some((prefix, hoop)) = entities.split(&trace) { + return (prefix.len(), hoop.to_vec()); + } else { + let t = entities.union(q); + let products = Self::compute_all(reactions, &t); + trace.push(entities.clone()); + entities = products; + } + } + } + + + /// see loop/5 + fn lollipops_only_loop_decomposed_q( + reactions: &[Self], + entities: &S, + q: &S, + ) -> Vec { + let find_loop_fn = + |q| Self::find_only_loop(reactions, + entities.clone(), + q); + find_loop_fn(q) + } +} + + + + +// ----------------------------------------------------------------------------- + /// Basic structure for a reaction. -#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq, Hash)] +#[derive(Clone, Debug, Default, Serialize, Deserialize, PartialEq, Eq, Hash)] pub struct Reaction { - pub reactants: Set, - pub inhibitors: Set, - pub products: Set, + pub reactants: Set, + pub inhibitors: Set, + pub products: Set, +} + +impl BasicReaction for Reaction { + /// returns true if ```current_state``` enables the reaction + /// see enable + fn enabled(&self, current_state: &Set) -> bool { + self.reactants.is_subset(current_state) + && self.inhibitors.is_disjoint(current_state) + } + + /// Computes the result of a single reaction (if enabled returns the + /// products) otherwise returns None. + /// see result + fn compute_step( + &self, + state: &Set, + ) -> Option<&Set> { + if self.enabled(state) { + Some(&self.products) + } else { + None + } + } } impl Reaction { - pub fn new() -> Self { - Reaction { - reactants: Set::new(), - inhibitors: Set::new(), - products: Set::new(), + pub fn from(reactants: Set, inhibitors: Set, products: Set) -> Self { + Reaction { + reactants, + inhibitors, + products, + } } - } - - pub fn from(reactants: Set, inhibitors: Set, products: Set) -> Self { - Reaction { - reactants, - inhibitors, - products, - } - } - - /// returns true if ```current_state``` enables the reaction - /// see enable - pub fn enabled(&self, current_state: &Set) -> bool { - self.reactants.is_subset(current_state) - && self.inhibitors.is_disjoint(current_state) - } - - /// Computes the result of a single reaction (if enabled returns the products) - /// otherwise returns None. - /// see result - pub fn compute_step<'a>( - &'a self, - current_state: &'a Set, - ) -> Option<&'a Set> { - if self.enabled(current_state) { - Some(&self.products) - } else { - None - } - } - - /// Computes the result of a series of reactions. Returns the union of all - /// products. - /// see result - pub fn compute_all<'a>( - current_state: &'a Set, - reactions: &'a [Self] - ) -> Set { - reactions.iter().fold(Set::new(), |mut acc, r| { - acc.union_option(r.compute_step(current_state)); - acc - }) - } - - - /// Finds the loops by simulating the system. - pub fn find_loop( - rs: &[Self], - entities: Set, - q: &Set - ) -> (Vec, Vec) { - let mut entities = entities; - let mut trace = vec![]; - loop { - if let Some((prefix, hoop)) = entities.split(&trace) { - return (prefix.to_vec(), hoop.to_vec()); - } else { - let t = entities.union(q); - let products = Self::compute_all(&t, rs); - trace.push(entities.clone()); - entities = products; - } - } - } - - - /// Finds the loops by simulating the system. - pub fn find_only_loop( - rs: &[Self], - entities: Set, - q: &Set - ) -> Vec { - let mut entities = entities; - let mut trace = vec![]; - loop { - if let Some((_prefix, hoop)) = entities.split(&trace) { - return hoop.to_vec(); - } else { - let t = entities.union(q); - let products = Self::compute_all(&t, rs); - trace.push(entities.clone()); - entities = products; - } - } - } - - - /// Finds the loops and the length of the prefix by simulating the system. - pub fn find_prefix_len_loop( - rs: &[Self], - entities: Set, - q: &Set - ) -> (usize, Vec) { - let mut entities = entities; - let mut trace = vec![]; - loop { - if let Some((prefix, hoop)) = entities.split(&trace) { - return (prefix.len(), hoop.to_vec()); - } else { - let t = entities.union(q); - let products = Self::compute_all(&t, rs); - trace.push(entities.clone()); - entities = products; - } - } - } - - - /// see loop/5 - pub fn lollipops_only_loop_decomposed_q( - reaction_rules: &[Self], - q: &Set, - available_entities: &Set, - ) -> Vec { - let find_loop_fn = - |q| Reaction::find_only_loop(reaction_rules, - available_entities.clone(), - q); - find_loop_fn(q) - } -} - -impl Default for Reaction { - fn default() -> Self { - Reaction::new() - } } impl PrintableWithTranslator for Reaction { - fn print(&self, f: &mut std::fmt::Formatter, translator: &Translator) - -> std::fmt::Result { - write!( - f, - "(r: {}, i: {}, p: {})", - Formatter::from(translator, &self.reactants), - Formatter::from(translator, &self.inhibitors), - Formatter::from(translator, &self.products) - ) - } + fn print(&self, f: &mut std::fmt::Formatter, translator: &Translator) + -> std::fmt::Result { + write!( + f, + "(r: {}, i: {}, p: {})", + Formatter::from(translator, &self.reactants), + Formatter::from(translator, &self.inhibitors), + Formatter::from(translator, &self.products) + ) + } } diff --git a/src/rsprocess/set.rs b/src/rsprocess/set.rs index 40a4d95..b7758b1 100644 --- a/src/rsprocess/set.rs +++ b/src/rsprocess/set.rs @@ -5,108 +5,48 @@ use std::fmt; use super::translator::{IdType, Translator, PrintableWithTranslator}; -/// Basic set of entities. -#[derive(Clone, Debug, PartialOrd, Eq, Ord, Serialize, Deserialize)] -pub struct Set { - pub identifiers: BTreeSet, + +/// Basic trait for all Set implementations. +/// Implement IntoIterator for &Self to have .iter() (not required directly by +/// the trait). +pub trait BasicSet +where Self: Clone + Eq + Ord + Default + Serialize + IntoIterator + + PrintableWithTranslator, +for<'de> Self: Deserialize<'de> +{ + fn is_subset(&self, other: &Self) -> bool; + fn is_disjoint(&self, other: &Self) -> bool; + fn union(&self, other: &Self) -> Self; + fn push(&mut self, other: &Self); + fn extend(&mut self, other: Option<&Self>); + fn intersection(&self, other: &Self) -> Self; + fn subtraction(&self, other: &Self) -> Self; + fn len(&self) -> usize; + fn is_empty(&self) -> bool; } -impl From<[IdType; N]> for Set { - fn from(arr: [IdType; N]) -> Self { - Set { - identifiers: BTreeSet::from(arr), - } - } +pub trait ExtensionsSet { + fn iter( + &self + ) -> <&Self as IntoIterator>::IntoIter + where for<'b> &'b Self: IntoIterator; + + fn split<'a>( + &'a self, + trace: &'a [Self] + ) -> Option<(&'a [Self], &'a [Self])> + where Self: Sized; } -impl From<&[IdType]> for Set { - fn from(arr: &[IdType]) -> Self { - Set { - identifiers: BTreeSet::from_iter(arr.to_vec()), - } - } -} - -impl From> for Set { - fn from(arr: Vec) -> Self { - Set { - identifiers: BTreeSet::from_iter(arr), - } - } -} - -impl Set { - pub const fn new() -> Self { - Set { - identifiers: BTreeSet::new(), - } - } - - pub fn is_subset(&self, b: &Set) -> bool { - self.identifiers.is_subset(&b.identifiers) - } - - pub fn is_disjoint(&self, b: &Set) -> bool { - self.identifiers.is_disjoint(&b.identifiers) - } - - // returns the new set a \cup b - pub fn union(&self, b: &Set) -> Set { - let mut ret: Set = b.clone(); - ret.identifiers.extend(self.identifiers.iter()); - ret - } - - pub fn union_option(&mut self, b: Option<&Set>) { - if let Some(b) = b { - self.identifiers.extend(b.iter()); - } - } - - /// returns the new set a \cap b - pub fn intersection(&self, b: &Set) -> Set { - // TODO maybe find more efficient way without copy/clone - let res: BTreeSet<_> = b - .identifiers - .intersection(&self.identifiers) - .copied() - .collect(); - Set { identifiers: res } - } - - /// returns the new set a ∖ b - pub fn subtraction(&self, b: &Set) -> Set { - // TODO maybe find more efficient way without copy/clone - let res: BTreeSet<_> = self - .identifiers - .difference(&b.identifiers) - .copied() - .collect(); - Set { identifiers: res } - } - - 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: &Set) { - self.identifiers.extend(b.iter()) - } - - pub fn is_empty(&self) -> bool { - self.identifiers.is_empty() +/// Implementations for all sets. +impl ExtensionsSet for T { + fn iter(&self) -> <&T as IntoIterator>::IntoIter + where for<'b> &'b T: IntoIterator { + self.into_iter() } /// Returns the prefix and the loop from a trace. - pub fn split<'a>( + fn split<'a>( &'a self, trace: &'a [Self] ) -> Option<(&'a [Self], &'a [Self])> { @@ -115,9 +55,69 @@ impl Set { } } -impl Default for Set { - fn default() -> Self { - Set::new() + +// ----------------------------------------------------------------------------- + +/// Basic set of entities. +#[derive(Clone, Debug, Default, PartialOrd, Eq, Ord, Serialize, Deserialize)] +pub struct Set { + pub identifiers: BTreeSet, +} + +impl BasicSet for Set { + fn is_subset(&self, other: &Self) -> bool { + self.identifiers.is_subset(&other.identifiers) + } + + fn is_disjoint(&self, other: &Self) -> bool { + self.identifiers.is_disjoint(&other.identifiers) + } + + // returns the new set a \cup b + fn union(&self, other: &Self) -> Self { + let mut ret: Set = other.clone(); + ret.identifiers.extend(self.identifiers.iter()); + ret + } + + fn push(&mut self, b: &Self) { + self.identifiers.extend(b.iter()) + } + + fn extend(&mut self, other: Option<&Self>) { + if let Some(other) = other { + self.identifiers.extend(other); + } + } + + /// returns the new set a \cap b + fn intersection(&self, other: &Self) -> Self { + // TODO maybe find more efficient way without copy/clone + let res: BTreeSet<_> = other + .identifiers + .intersection(&self.identifiers) + .copied() + .collect(); + Set { identifiers: res } + } + + /// returns the new set a ∖ b + fn subtraction(&self, other: &Self) -> Self { + // TODO maybe find more efficient way without copy/clone + let res: BTreeSet<_> = self + .identifiers + .difference(&other.identifiers) + .copied() + .collect(); + Set { identifiers: res } + } + + fn len(&self) -> usize { + self.identifiers.len() + } + + fn is_empty(&self) -> bool { + self.identifiers.is_empty() } } @@ -142,6 +142,15 @@ impl IntoIterator for Set { } } +impl<'a> IntoIterator for &'a Set { + type Item = &'a IdType; + type IntoIter = std::collections::btree_set::Iter<'a, IdType>; + + fn into_iter(self) -> Self::IntoIter { + self.identifiers.iter() + } +} + impl PrintableWithTranslator for Set { fn print( &self, @@ -164,3 +173,28 @@ impl PrintableWithTranslator for Set { write!(f, "}}") } } + + +impl From<[IdType; N]> for Set { + fn from(arr: [IdType; N]) -> Self { + Set { + identifiers: BTreeSet::from(arr), + } + } +} + +impl From<&[IdType]> for Set { + fn from(arr: &[IdType]) -> Self { + Set { + identifiers: BTreeSet::from_iter(arr.to_vec()), + } + } +} + +impl From> for Set { + fn from(arr: Vec) -> Self { + Set { + identifiers: BTreeSet::from_iter(arr), + } + } +} diff --git a/src/rsprocess/system.rs b/src/rsprocess/system.rs index 064e4a3..e172dd1 100644 --- a/src/rsprocess/system.rs +++ b/src/rsprocess/system.rs @@ -7,8 +7,8 @@ use super::environment::Environment; use super::graph::SystemGraph; use super::label::Label; use super::process::Process; -use super::reaction::Reaction; -use super::set::Set; +use super::reaction::{Reaction, ExtensionReaction}; +use super::set::{BasicSet, Set}; use super::transitions::TransitionsIterator; use super::translator::{IdType, Translator, PrintableWithTranslator, Formatter}; @@ -27,7 +27,7 @@ impl System { pub fn new() -> System { System { delta: Rc::new(Environment::new()), - available_entities: Set::new(), + available_entities: Set::default(), context_process: Process::Nill, reaction_rules: Rc::new(vec![]), } @@ -405,7 +405,7 @@ impl System { let reactants = self .reaction_rules .iter() - .fold(Set::new(), |acc, new| acc.union(&new.reactants)); + .fold(Set::default(), |acc, new| acc.union(&new.reactants)); result.push_str(&format!( "The reactants are {}:\n{}\n", reactants.len(), @@ -415,7 +415,7 @@ impl System { let inhibitors = self .reaction_rules .iter() - .fold(Set::new(), |acc, new| acc.union(&new.inhibitors)); + .fold(Set::default(), |acc, new| acc.union(&new.inhibitors)); result.push_str(&format!( "The inhibitors are {}:\n{}\n", inhibitors.len(), @@ -425,7 +425,7 @@ impl System { let products = self .reaction_rules .iter() - .fold(Set::new(), |acc, new| acc.union(&new.products)); + .fold(Set::default(), |acc, new| acc.union(&new.products)); result.push_str(&format!( "The products are {}:\n{}\n", products.len(), diff --git a/src/rsprocess/system_test.rs b/src/rsprocess/system_test.rs index 10996b4..e51439e 100644 --- a/src/rsprocess/system_test.rs +++ b/src/rsprocess/system_test.rs @@ -53,7 +53,7 @@ fn traces_1() { inhibitors: Set::from([1]), products: Set::from([1]), }, Reaction { reactants: Set::from([2]), - inhibitors: Set::new(), + inhibitors: Set::default(), products: Set::from([4]), }, ]) }; @@ -113,7 +113,7 @@ fn traces_empty_env() { inhibitors: Set::from([1]), products: Set::from([1]), }, Reaction { reactants: Set::from([2]), - inhibitors: Set::new(), + inhibitors: Set::default(), products: Set::from([4]), }, ]) }; diff --git a/src/rsprocess/transitions.rs b/src/rsprocess/transitions.rs index 2f79d3e..15e664d 100644 --- a/src/rsprocess/transitions.rs +++ b/src/rsprocess/transitions.rs @@ -4,8 +4,9 @@ use std::rc::Rc; use super::label::Label; use super::process::Process; -use super::set::Set; +use super::set::{BasicSet, Set}; use super::system::System; +use super::reaction::BasicReaction; #[derive(Clone, Debug)] pub struct TransitionsIterator<'a> { @@ -44,11 +45,11 @@ impl<'a> Iterator for TransitionsIterator<'a> { ) = self.system.reaction_rules.iter().fold( ( - Set::new(), // reactants - Set::new(), // reactants_absent - Set::new(), // inhibitors - Set::new(), // inhibitors_present - Set::new(), // products + Set::default(), // reactants + Set::default(), // reactants_absent + Set::default(), // inhibitors + Set::default(), // inhibitors_present + Set::default(), // products ), |acc, reaction| { if reaction.enabled(&t) {