improvements and fixes

This commit is contained in:
elvis
2025-10-27 14:39:11 +01:00
parent 462d0e9d53
commit fbc767a21b
6 changed files with 252 additions and 54 deletions

View File

@ -20,6 +20,7 @@ impl PrintableWithTranslator for IdType {
} }
} }
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
#[derive( #[derive(
@ -108,3 +109,15 @@ impl From<(&IdType, &IdState)> for PositiveType {
} }
} }
} }
impl From<PositiveType> for IdType {
fn from(value: PositiveType) -> Self {
value.id
}
}
impl From<&PositiveType> for IdType {
fn from(value: &PositiveType) -> Self {
value.id
}
}

View File

@ -430,7 +430,7 @@ impl<'a> IntoIterator for &'a Environment {
impl<const N: usize> From<[(IdType, Process); N]> for Environment { impl<const N: usize> From<[(IdType, Process); N]> for Environment {
fn from(arr: [(IdType, Process); N]) -> Self { fn from(arr: [(IdType, Process); N]) -> Self {
Environment { Self {
definitions: BTreeMap::from(arr), definitions: BTreeMap::from(arr),
} }
} }
@ -438,7 +438,7 @@ impl<const N: usize> From<[(IdType, Process); N]> for Environment {
impl From<&[(IdType, Process)]> for Environment { impl From<&[(IdType, Process)]> for Environment {
fn from(arr: &[(IdType, Process)]) -> Self { fn from(arr: &[(IdType, Process)]) -> Self {
Environment { Self {
definitions: BTreeMap::from_iter(arr.to_vec()), definitions: BTreeMap::from_iter(arr.to_vec()),
} }
} }
@ -446,7 +446,7 @@ impl From<&[(IdType, Process)]> for Environment {
impl From<Vec<(IdType, Process)>> for Environment { impl From<Vec<(IdType, Process)>> for Environment {
fn from(arr: Vec<(IdType, Process)>) -> Self { fn from(arr: Vec<(IdType, Process)>) -> Self {
Environment { Self {
definitions: BTreeMap::from_iter(arr), definitions: BTreeMap::from_iter(arr),
} }
} }
@ -812,3 +812,28 @@ impl From<Environment> for PositiveEnvironment {
(&value).into() (&value).into()
} }
} }
impl<const N: usize> 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<Vec<(IdType, PositiveProcess)>> for PositiveEnvironment {
fn from(arr: Vec<(IdType, PositiveProcess)>) -> Self {
Self {
definitions: BTreeMap::from_iter(arr),
}
}
}

View File

@ -16,11 +16,28 @@ where
+ Ord + Ord
+ Hash + Hash
+ PrintableWithTranslator, + PrintableWithTranslator,
for<'a> Self: Deserialize<'a>,
{ {
type Set: BasicSet; type Set: BasicSet;
fn get_context(&self) -> (&Self::Set, &Self::Set, &Self::Set); 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) { fn get_context(&self) -> (&Set, &Set, &Set) {
(&self.available_entities, &self.context, &self.t) (&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 { impl Label {
@ -171,6 +239,57 @@ impl BasicLabel for PositiveLabel {
fn get_context(&self) -> (&PositiveSet, &PositiveSet, &PositiveSet) { fn get_context(&self) -> (&PositiveSet, &PositiveSet, &PositiveSet) {
(&self.available_entities, &self.context, &self.t) (&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 { impl PartialEq for PositiveLabel {

View File

@ -226,9 +226,7 @@ impl Reaction {
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
#[derive( #[derive(Clone, Debug, Default, Serialize, Deserialize, PartialEq, Eq, Hash)]
Clone, Debug, Default, Serialize, Deserialize, PartialEq, Eq, Hash,
)]
pub struct PositiveReaction { pub struct PositiveReaction {
pub reactants: PositiveSet, pub reactants: PositiveSet,
pub products: PositiveSet, pub products: PositiveSet,
@ -308,3 +306,61 @@ impl PositiveReaction {
Some(self.reactants.intersection(&other.reactants)) 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<PositiveReaction> {
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::<Vec<_>>(),
&p.iter().map(|p| p.inhibitors.clone()).collect::<Vec<_>>(),
)
.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<Self> {
Reaction::into_positive_reactions(reactions)
}
}

View File

@ -33,6 +33,7 @@ where
fn len(&self) -> usize; fn len(&self) -> usize;
fn is_empty(&self) -> bool; fn is_empty(&self) -> bool;
fn contains(&self, el: &Self::Element) -> bool; fn contains(&self, el: &Self::Element) -> bool;
fn add(&mut self, el: Self::Element);
} }
pub trait ExtensionsSet { pub trait ExtensionsSet {
@ -140,6 +141,10 @@ impl BasicSet for Set {
fn contains(&self, el: &Self::Element) -> bool { fn contains(&self, el: &Self::Element) -> bool {
self.identifiers.contains(el) self.identifiers.contains(el)
} }
fn add(&mut self, el: Self::Element) {
self.identifiers.insert(el);
}
} }
impl PartialEq for Set { impl PartialEq for Set {
@ -488,6 +493,10 @@ impl BasicSet for PositiveSet {
false false
} }
} }
fn add(&mut self, el: Self::Element) {
self.identifiers.insert(el.id, el.state);
}
} }
impl PrintableWithTranslator for PositiveSet { impl PrintableWithTranslator for PositiveSet {

View File

@ -703,6 +703,17 @@ impl System {
products_elements: Rc::new(RefCell::new(None)), 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<System> for PositiveSystem {
let new_available_entities = let new_available_entities =
positive_entities.union(&negative_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_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::<Vec<_>>(),
&p.iter().map(|p| p.inhibitors.clone()).collect::<Vec<_>>(),
)
.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) Self::from(new_env, new_available_entities, new_context, new_reactions)
} }
@ -1105,4 +1070,15 @@ impl PositiveSystem {
.map(|el| (*el.0, IdState::Negative)) .map(|el| (*el.0, IdState::Negative))
.collect::<PositiveSet>() .collect::<PositiveSet>()
} }
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)));
}
} }