From fbc767a21bba325b0511e88b6df07c2412628e87 Mon Sep 17 00:00:00 2001 From: elvis Date: Mon, 27 Oct 2025 14:39:11 +0100 Subject: [PATCH] improvements and fixes --- rsprocess/src/element.rs | 13 ++++ rsprocess/src/environment.rs | 31 ++++++++- rsprocess/src/label.rs | 121 ++++++++++++++++++++++++++++++++++- rsprocess/src/reaction.rs | 62 +++++++++++++++++- rsprocess/src/set.rs | 9 +++ rsprocess/src/system.rs | 70 +++++++------------- 6 files changed, 252 insertions(+), 54 deletions(-) diff --git a/rsprocess/src/element.rs b/rsprocess/src/element.rs index f15c107..2cfa0f2 100644 --- a/rsprocess/src/element.rs +++ b/rsprocess/src/element.rs @@ -20,6 +20,7 @@ impl PrintableWithTranslator for IdType { } } + // ----------------------------------------------------------------------------- #[derive( @@ -108,3 +109,15 @@ impl From<(&IdType, &IdState)> for PositiveType { } } } + +impl From for IdType { + fn from(value: PositiveType) -> Self { + value.id + } +} + +impl From<&PositiveType> for IdType { + fn from(value: &PositiveType) -> Self { + value.id + } +} diff --git a/rsprocess/src/environment.rs b/rsprocess/src/environment.rs index 96b7b19..71f2881 100644 --- a/rsprocess/src/environment.rs +++ b/rsprocess/src/environment.rs @@ -430,7 +430,7 @@ impl<'a> IntoIterator for &'a Environment { impl From<[(IdType, Process); N]> for Environment { fn from(arr: [(IdType, Process); N]) -> Self { - Environment { + Self { definitions: BTreeMap::from(arr), } } @@ -438,7 +438,7 @@ impl From<[(IdType, Process); N]> for Environment { impl From<&[(IdType, Process)]> for Environment { fn from(arr: &[(IdType, Process)]) -> Self { - Environment { + Self { definitions: BTreeMap::from_iter(arr.to_vec()), } } @@ -446,7 +446,7 @@ impl From<&[(IdType, Process)]> for Environment { impl From> for Environment { fn from(arr: Vec<(IdType, Process)>) -> Self { - Environment { + Self { definitions: BTreeMap::from_iter(arr), } } @@ -812,3 +812,28 @@ impl From for PositiveEnvironment { (&value).into() } } + + +impl From<[(IdType, PositiveProcess); N]> for PositiveEnvironment { + fn from(arr: [(IdType, PositiveProcess); N]) -> Self { + Self { + definitions: BTreeMap::from(arr), + } + } +} + +impl From<&[(IdType, PositiveProcess)]> for PositiveEnvironment { + fn from(arr: &[(IdType, PositiveProcess)]) -> Self { + Self { + definitions: BTreeMap::from_iter(arr.to_vec()), + } + } +} + +impl From> for PositiveEnvironment { + fn from(arr: Vec<(IdType, PositiveProcess)>) -> Self { + Self { + definitions: BTreeMap::from_iter(arr), + } + } +} diff --git a/rsprocess/src/label.rs b/rsprocess/src/label.rs index 5624730..80af5c3 100644 --- a/rsprocess/src/label.rs +++ b/rsprocess/src/label.rs @@ -16,11 +16,28 @@ where + Ord + Hash + PrintableWithTranslator, - for<'a> Self: Deserialize<'a>, { type Set: BasicSet; fn get_context(&self) -> (&Self::Set, &Self::Set, &Self::Set); + + fn available_entities(&self) -> &Self::Set; + fn context(&self) -> &Self::Set; + fn t(&self) -> &Self::Set; + fn reactants(&self) -> &Self::Set; + fn reactants_absent(&self) -> &Self::Set; + fn inhibitors(&self) -> &Self::Set; + fn inhibitors_present(&self) -> &Self::Set; + fn products(&self) -> &Self::Set; + + fn set_available_entities(&mut self, set: Self::Set); + fn set_context(&mut self, set: Self::Set); + fn set_t(&mut self, set: Self::Set); + fn set_reactants(&mut self, set: Self::Set); + fn set_reactants_absent(&mut self, set: Self::Set); + fn set_inhibitors(&mut self, set: Self::Set); + fn set_inhibitors_present(&mut self, set: Self::Set); + fn set_products(&mut self, set: Self::Set); } // ----------------------------------------------------------------------------- @@ -45,6 +62,57 @@ impl BasicLabel for Label { fn get_context(&self) -> (&Set, &Set, &Set) { (&self.available_entities, &self.context, &self.t) } + + fn available_entities(&self) -> &Self::Set { + &self.available_entities + } + fn context(&self) -> &Self::Set { + &self.context + } + fn t(&self) -> &Self::Set { + &self.t + } + fn reactants(&self) -> &Self::Set { + &self.reactants + } + fn reactants_absent(&self) -> &Self::Set { + &self.reactants_absent + } + fn inhibitors(&self) -> &Self::Set { + &self.inhibitors + } + fn inhibitors_present(&self) -> &Self::Set { + &self.inhibitors_present + } + fn products(&self) -> &Self::Set { + &self.products + } + + + fn set_available_entities(&mut self, set: Self::Set) { + self.available_entities = set; + } + fn set_context(&mut self, set: Self::Set) { + self.context = set; + } + fn set_t(&mut self, set: Self::Set) { + self.t = set; + } + fn set_reactants(&mut self, set: Self::Set) { + self.reactants = set; + } + fn set_reactants_absent(&mut self, set: Self::Set) { + self.reactants_absent = set; + } + fn set_inhibitors(&mut self, set: Self::Set) { + self.inhibitors = set; + } + fn set_inhibitors_present(&mut self, set: Self::Set) { + self.inhibitors_present = set; + } + fn set_products(&mut self, set: Self::Set) { + self.products = set; + } } impl Label { @@ -171,6 +239,57 @@ impl BasicLabel for PositiveLabel { fn get_context(&self) -> (&PositiveSet, &PositiveSet, &PositiveSet) { (&self.available_entities, &self.context, &self.t) } + + fn available_entities(&self) -> &Self::Set { + &self.available_entities + } + fn context(&self) -> &Self::Set { + &self.context + } + fn t(&self) -> &Self::Set { + &self.t + } + fn reactants(&self) -> &Self::Set { + &self.reactants + } + fn reactants_absent(&self) -> &Self::Set { + &self.reactants_absent + } + fn inhibitors(&self) -> &Self::Set { + &self.inhibitors + } + fn inhibitors_present(&self) -> &Self::Set { + &self.inhibitors_present + } + fn products(&self) -> &Self::Set { + &self.products + } + + + fn set_available_entities(&mut self, set: Self::Set) { + self.available_entities = set; + } + fn set_context(&mut self, set: Self::Set) { + self.context = set; + } + fn set_t(&mut self, set: Self::Set) { + self.t = set; + } + fn set_reactants(&mut self, set: Self::Set) { + self.reactants = set; + } + fn set_reactants_absent(&mut self, set: Self::Set) { + self.reactants_absent = set; + } + fn set_inhibitors(&mut self, set: Self::Set) { + self.inhibitors = set; + } + fn set_inhibitors_present(&mut self, set: Self::Set) { + self.inhibitors_present = set; + } + fn set_products(&mut self, set: Self::Set) { + self.products = set; + } } impl PartialEq for PositiveLabel { diff --git a/rsprocess/src/reaction.rs b/rsprocess/src/reaction.rs index ce4738a..c9c3fa2 100644 --- a/rsprocess/src/reaction.rs +++ b/rsprocess/src/reaction.rs @@ -226,9 +226,7 @@ impl Reaction { // ----------------------------------------------------------------------------- -#[derive( - Clone, Debug, Default, Serialize, Deserialize, PartialEq, Eq, Hash, -)] +#[derive(Clone, Debug, Default, Serialize, Deserialize, PartialEq, Eq, Hash)] pub struct PositiveReaction { pub reactants: PositiveSet, pub products: PositiveSet, @@ -308,3 +306,61 @@ impl PositiveReaction { Some(self.reactants.intersection(&other.reactants)) } } + +// ----------------------------------------------------------------------------- +// Convert from list of reactions to list of positive reactions + +impl Reaction { + pub fn into_positive_reactions(reactions: &[Self]) -> Vec { + let mut res = vec![]; + let old_reactions = &reactions; + + let all_products = Reaction::all_products(old_reactions); + for el in all_products { + let p = + Reaction::all_reactions_with_product(old_reactions, &el); + let mut tmp = vec![]; + for r in p.iter() { + tmp.push(PositiveReaction::create( + r.reactants.clone(), + r.inhibitors.clone(), + Set::from([el]), + )) + } + tmp.sort_by(|r1, r2| r1.reactants.cmp(&r2.reactants)); + + // remove reactions with only one element of opposite state + // as intersection (same product ```el```) + let mut pos = tmp.len() - 1; + while pos > 0 { + if let Some(intersection) = + tmp[pos].differ_only_one_element(&tmp[pos - 1]) + { + tmp[pos - 1].reactants = intersection; + tmp.remove(pos); + } + pos -= 1; + } + + res.extend(tmp); + let prohib_set = Set::prohibiting_set( + &p.iter().map(|p| p.reactants.clone()).collect::>(), + &p.iter().map(|p| p.inhibitors.clone()).collect::>(), + ) + .unwrap(); // since we have in input a valid system + for s in prohib_set { + res.push(PositiveReaction { + reactants: s, + products: PositiveSet::from([(el, IdState::Negative)]), + }) + } + } + res + } +} + +impl PositiveReaction { + pub fn from_reactions(reactions: &[Reaction]) -> Vec { + Reaction::into_positive_reactions(reactions) + } +} diff --git a/rsprocess/src/set.rs b/rsprocess/src/set.rs index 466e7d6..abbd72f 100644 --- a/rsprocess/src/set.rs +++ b/rsprocess/src/set.rs @@ -33,6 +33,7 @@ where fn len(&self) -> usize; fn is_empty(&self) -> bool; fn contains(&self, el: &Self::Element) -> bool; + fn add(&mut self, el: Self::Element); } pub trait ExtensionsSet { @@ -140,6 +141,10 @@ impl BasicSet for Set { fn contains(&self, el: &Self::Element) -> bool { self.identifiers.contains(el) } + + fn add(&mut self, el: Self::Element) { + self.identifiers.insert(el); + } } impl PartialEq for Set { @@ -488,6 +493,10 @@ impl BasicSet for PositiveSet { false } } + + fn add(&mut self, el: Self::Element) { + self.identifiers.insert(el.id, el.state); + } } impl PrintableWithTranslator for PositiveSet { diff --git a/rsprocess/src/system.rs b/rsprocess/src/system.rs index 898be1a..9ed0129 100644 --- a/rsprocess/src/system.rs +++ b/rsprocess/src/system.rs @@ -703,6 +703,17 @@ impl System { products_elements: Rc::new(RefCell::new(None)), } } + + pub fn overwrite_context_elements(&mut self, new_context_elements: Set) { + self.context_elements = Rc::new(RefCell::new(Some(new_context_elements))); + } + + pub fn overwrite_product_elements(&mut self, new_product_elements: Set) { + // since context_elements depend on product elements we make sure that + // its computed to ensure consistent behaviour + self.context_elements(); + self.products_elements = Rc::new(RefCell::new(Some(new_product_elements))); + } } // ----------------------------------------------------------------------------- @@ -1028,54 +1039,8 @@ impl From for PositiveSystem { let new_available_entities = positive_entities.union(&negative_entities); + let new_reactions = Rc::new(PositiveReaction::from_reactions(value.reactions())); let new_context = value.context_process.into(); - let new_reactions = { - let mut res = vec![]; - let old_reactions = &value.reaction_rules; - - let all_products = Reaction::all_products(old_reactions); - for el in all_products { - let p = - Reaction::all_reactions_with_product(old_reactions, &el); - let mut tmp = vec![]; - for r in p.iter() { - tmp.push(PositiveReaction::create( - r.reactants.clone(), - r.inhibitors.clone(), - Set::from([el]), - )) - } - tmp.sort_by(|r1, r2| r1.reactants.cmp(&r2.reactants)); - - // remove reactions with only one element of opposite state - // as intersection (same product ```el```) - let mut pos = tmp.len() - 1; - while pos > 0 { - if let Some(intersection) = - tmp[pos].differ_only_one_element(&tmp[pos - 1]) - { - tmp[pos - 1].reactants = intersection; - tmp.remove(pos); - } - pos -= 1; - } - - res.extend(tmp); - let prohib_set = Set::prohibiting_set( - &p.iter().map(|p| p.reactants.clone()).collect::>(), - &p.iter().map(|p| p.inhibitors.clone()).collect::>(), - ) - .unwrap(); // since we have in input a valid system - for s in prohib_set { - res.push(PositiveReaction { - reactants: s, - products: PositiveSet::from([(el, IdState::Negative)]), - }) - } - } - - Rc::new(res) - }; Self::from(new_env, new_available_entities, new_context, new_reactions) } @@ -1105,4 +1070,15 @@ impl PositiveSystem { .map(|el| (*el.0, IdState::Negative)) .collect::() } + + pub fn overwrite_context_elements(&mut self, new_context_elements: PositiveSet) { + self.context_elements = Rc::new(RefCell::new(Some(new_context_elements))); + } + + pub fn overwrite_product_elements(&mut self, new_product_elements: PositiveSet) { + // since context_elements depend on product elements we make sure that + // its computed to ensure consistent behaviour + self.context_elements(); + self.products_elements = Rc::new(RefCell::new(Some(new_product_elements))); + } }