Correct hanlding of reactions
while converting from System to PositiveSystem
This commit is contained in:
@ -67,3 +67,15 @@ impl PrintableWithTranslator for PositiveType {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl From<(IdType, IdState)> for PositiveType {
|
||||||
|
fn from(value: (IdType, IdState)) -> Self {
|
||||||
|
Self { id: value.0, state: value.1 }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<(&IdType, &IdState)> for PositiveType {
|
||||||
|
fn from(value: (&IdType, &IdState)) -> Self {
|
||||||
|
Self { id: *value.0, state: *value.1 }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@ -236,4 +236,27 @@ impl PositiveReaction {
|
|||||||
products: products.to_positive_set(IdState::Positive),
|
products: products.to_positive_set(IdState::Positive),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// returns the reactants that are equal
|
||||||
|
pub fn differ_only_one_element(&self, other: &Self) -> Option<PositiveSet> {
|
||||||
|
if self.products != other.products {
|
||||||
|
return None
|
||||||
|
}
|
||||||
|
let mut found = false;
|
||||||
|
for el in self.reactants.iter() {
|
||||||
|
match other.reactants.identifiers.get(el.0) {
|
||||||
|
None => return None,
|
||||||
|
Some(s) => {
|
||||||
|
if s != el.1 {
|
||||||
|
if found {
|
||||||
|
return None
|
||||||
|
} else {
|
||||||
|
found = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Some(self.reactants.intersection(&other.reactants))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -349,6 +349,9 @@ impl Set {
|
|||||||
set1.equal_except_negated_elements(set2)
|
set1.equal_except_negated_elements(set2)
|
||||||
) {
|
) {
|
||||||
let intersection = set1.opposite_intersection(set2);
|
let intersection = set1.opposite_intersection(set2);
|
||||||
|
if intersection.len() != 1 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
set1.remove_elements(intersection);
|
set1.remove_elements(intersection);
|
||||||
|
|
||||||
t[pos_set1 - removed] = set1.clone();
|
t[pos_set1 - removed] = set1.clone();
|
||||||
|
|||||||
@ -107,3 +107,26 @@ fn prohibiting_set_4() {
|
|||||||
]
|
]
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn prohibiting_set_5() {
|
||||||
|
use super::element::IdState::*;
|
||||||
|
use super::set::{PositiveSet, Set};
|
||||||
|
|
||||||
|
let r1r = Set::from(vec![1]);
|
||||||
|
let r1i = Set::from(vec![2]);
|
||||||
|
|
||||||
|
let r2r = Set::from(vec![1, 2]);
|
||||||
|
let r2i = Set::from(vec![]);
|
||||||
|
|
||||||
|
let mut prohibiting_set =
|
||||||
|
Set::prohibiting_set(&[r1r, r2r], &[r1i, r2i]).unwrap();
|
||||||
|
prohibiting_set.sort();
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
prohibiting_set,
|
||||||
|
vec![
|
||||||
|
PositiveSet::from([(1, Negative)]),
|
||||||
|
]
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|||||||
@ -648,7 +648,8 @@ impl From<System> for PositiveSystem {
|
|||||||
/// Should never fail.
|
/// Should never fail.
|
||||||
fn from(value: System) -> Self {
|
fn from(value: System) -> Self {
|
||||||
let new_env = Rc::new((&*value.delta).into());
|
let new_env = Rc::new((&*value.delta).into());
|
||||||
let positive_entities = value.available_entities.to_positive_set(IdState::Positive);
|
let positive_entities =
|
||||||
|
value.available_entities.to_positive_set(IdState::Positive);
|
||||||
|
|
||||||
let negative_entities = value
|
let negative_entities = value
|
||||||
.context_process
|
.context_process
|
||||||
@ -666,27 +667,46 @@ impl From<System> for PositiveSystem {
|
|||||||
)
|
)
|
||||||
.subtraction(&value.available_entities)
|
.subtraction(&value.available_entities)
|
||||||
.to_positive_set(IdState::Negative);
|
.to_positive_set(IdState::Negative);
|
||||||
let new_available_entities = positive_entities.union(&negative_entities);
|
let new_available_entities =
|
||||||
|
positive_entities.union(&negative_entities);
|
||||||
|
|
||||||
let new_context = value.context_process.into();
|
let new_context = value.context_process.into();
|
||||||
let new_reactions = {
|
let new_reactions = {
|
||||||
let mut res = vec![];
|
let mut res = vec![];
|
||||||
let old_reactions = &value.reaction_rules;
|
let old_reactions = &value.reaction_rules;
|
||||||
old_reactions.iter().for_each(|r| {
|
|
||||||
res.push(PositiveReaction::create(
|
|
||||||
r.reactants.clone(),
|
|
||||||
r.inhibitors.clone(),
|
|
||||||
r.products.clone(),
|
|
||||||
))
|
|
||||||
});
|
|
||||||
let all_products = Reaction::all_products(old_reactions);
|
let all_products = Reaction::all_products(old_reactions);
|
||||||
for el in all_products {
|
for el in all_products {
|
||||||
let p = Reaction::all_reactions_with_product(old_reactions, &el);
|
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(
|
let prohib_set = Set::prohibiting_set(
|
||||||
&p.iter().map(|p| p.reactants.clone()).collect::<Vec<_>>(),
|
&p.iter().map(|p| p.reactants.clone()).collect::<Vec<_>>(),
|
||||||
&p.iter().map(|p| p.inhibitors.clone()).collect::<Vec<_>>(),
|
&p.iter().map(|p| p.inhibitors.clone()).collect::<Vec<_>>(),
|
||||||
)
|
).unwrap(); // since we have in input a valid system
|
||||||
.unwrap();
|
|
||||||
for s in prohib_set {
|
for s in prohib_set {
|
||||||
res.push(PositiveReaction {
|
res.push(PositiveReaction {
|
||||||
reactants: s,
|
reactants: s,
|
||||||
@ -694,6 +714,8 @@ impl From<System> for PositiveSystem {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Rc::new(res)
|
Rc::new(res)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -1,3 +1,5 @@
|
|||||||
|
use crate::rsprocess::{set::PositiveSet, system::BasicSystem};
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn one_transition() {
|
fn one_transition() {
|
||||||
use super::environment::Environment;
|
use super::environment::Environment;
|
||||||
@ -14,11 +16,13 @@ fn one_transition() {
|
|||||||
entities: Set::from([]),
|
entities: Set::from([]),
|
||||||
next_process: Rc::new(Process::Nill),
|
next_process: Rc::new(Process::Nill),
|
||||||
},
|
},
|
||||||
Rc::new(vec![Reaction {
|
Rc::new(vec![
|
||||||
reactants: Set::from([1]),
|
Reaction::from(
|
||||||
inhibitors: Set::from([3]),
|
Set::from([1]),
|
||||||
products: Set::from([3]),
|
Set::from([3]),
|
||||||
}]),
|
Set::from([3]),
|
||||||
|
),
|
||||||
|
]),
|
||||||
);
|
);
|
||||||
|
|
||||||
match system.one_transition() {
|
match system.one_transition() {
|
||||||
@ -59,7 +63,8 @@ fn one_transition_2() {
|
|||||||
},
|
},
|
||||||
Rc::new(vec![
|
Rc::new(vec![
|
||||||
PositiveReaction {
|
PositiveReaction {
|
||||||
reactants: PositiveSet::from([(1, IdState::Positive), (3, IdState::Negative)]),
|
reactants: PositiveSet::from([(1, IdState::Positive),
|
||||||
|
(3, IdState::Negative)]),
|
||||||
products: PositiveSet::from([(3, IdState::Positive)]),
|
products: PositiveSet::from([(3, IdState::Positive)]),
|
||||||
},
|
},
|
||||||
PositiveReaction {
|
PositiveReaction {
|
||||||
@ -122,11 +127,13 @@ fn convertion() {
|
|||||||
entities: Set::from([]),
|
entities: Set::from([]),
|
||||||
next_process: Rc::new(Process::Nill),
|
next_process: Rc::new(Process::Nill),
|
||||||
},
|
},
|
||||||
Rc::new(vec![Reaction {
|
Rc::new(vec![
|
||||||
reactants: Set::from([1]),
|
Reaction::from(
|
||||||
inhibitors: Set::from([3]),
|
Set::from([1]),
|
||||||
products: Set::from([3]),
|
Set::from([3]),
|
||||||
}]),
|
Set::from([3]),
|
||||||
|
),
|
||||||
|
]),
|
||||||
);
|
);
|
||||||
|
|
||||||
let system: PositiveSystem = system.into();
|
let system: PositiveSystem = system.into();
|
||||||
@ -202,21 +209,21 @@ fn traces_1() {
|
|||||||
available_entities: Set::from([1, 2]),
|
available_entities: Set::from([1, 2]),
|
||||||
context_process: Process::RecursiveIdentifier { identifier: 101 },
|
context_process: Process::RecursiveIdentifier { identifier: 101 },
|
||||||
reaction_rules: Rc::new(vec![
|
reaction_rules: Rc::new(vec![
|
||||||
Reaction {
|
Reaction::from(
|
||||||
reactants: Set::from([1]),
|
Set::from([1]),
|
||||||
inhibitors: Set::from([3]),
|
Set::from([3]),
|
||||||
products: Set::from([3]),
|
Set::from([3]),
|
||||||
},
|
),
|
||||||
Reaction {
|
Reaction::from(
|
||||||
reactants: Set::from([3]),
|
Set::from([3]),
|
||||||
inhibitors: Set::from([1]),
|
Set::from([1]),
|
||||||
products: Set::from([1]),
|
Set::from([1]),
|
||||||
},
|
),
|
||||||
Reaction {
|
Reaction::from(
|
||||||
reactants: Set::from([2]),
|
Set::from([2]),
|
||||||
inhibitors: Set::default(),
|
Set::default(),
|
||||||
products: Set::from([4]),
|
Set::from([4]),
|
||||||
},
|
),
|
||||||
]),
|
]),
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -261,21 +268,21 @@ fn traces_empty_env() {
|
|||||||
next_process: Rc::new(Process::Nill),
|
next_process: Rc::new(Process::Nill),
|
||||||
},
|
},
|
||||||
reaction_rules: Rc::new(vec![
|
reaction_rules: Rc::new(vec![
|
||||||
Reaction {
|
Reaction::from(
|
||||||
reactants: Set::from([1]),
|
Set::from([1]),
|
||||||
inhibitors: Set::from([3]),
|
Set::from([3]),
|
||||||
products: Set::from([3]),
|
Set::from([3]),
|
||||||
},
|
),
|
||||||
Reaction {
|
Reaction::from(
|
||||||
reactants: Set::from([3]),
|
Set::from([3]),
|
||||||
inhibitors: Set::from([1]),
|
Set::from([1]),
|
||||||
products: Set::from([1]),
|
Set::from([1]),
|
||||||
},
|
),
|
||||||
Reaction {
|
Reaction::from(
|
||||||
reactants: Set::from([2]),
|
Set::from([2]),
|
||||||
inhibitors: Set::default(),
|
Set::default(),
|
||||||
products: Set::from([4]),
|
Set::from([4]),
|
||||||
},
|
),
|
||||||
]),
|
]),
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -283,3 +290,92 @@ fn traces_empty_env() {
|
|||||||
assert_eq!(res.len(), 1);
|
assert_eq!(res.len(), 1);
|
||||||
assert_eq!(res[0].len(), 10);
|
assert_eq!(res[0].len(), 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn conversion_reactions() {
|
||||||
|
use std::rc::Rc;
|
||||||
|
|
||||||
|
use super::system::{System, PositiveSystem};
|
||||||
|
use super::environment::Environment;
|
||||||
|
use super::set::Set;
|
||||||
|
use super::process::Process;
|
||||||
|
use super::reaction::{Reaction, PositiveReaction};
|
||||||
|
use super::element::IdState::*;
|
||||||
|
|
||||||
|
let system = System {
|
||||||
|
delta: Rc::new(Environment::from([])),
|
||||||
|
available_entities: Set::from([1, 2]),
|
||||||
|
context_process: Process::Nill,
|
||||||
|
reaction_rules: Rc::new(vec![
|
||||||
|
Reaction::from(
|
||||||
|
Set::from([2]),
|
||||||
|
Set::from([1, 3]),
|
||||||
|
Set::from([5]),
|
||||||
|
),
|
||||||
|
Reaction::from(
|
||||||
|
Set::from([1, 2]),
|
||||||
|
Set::from([3]),
|
||||||
|
Set::from([5]),
|
||||||
|
),
|
||||||
|
]),
|
||||||
|
};
|
||||||
|
let converted_system: PositiveSystem = system.into();
|
||||||
|
let mut reactions = converted_system.reactions().clone();
|
||||||
|
reactions.sort_by(|a, b| a.products.cmp(&b.products)
|
||||||
|
.then(a.reactants.cmp(&b.reactants)));
|
||||||
|
|
||||||
|
assert_eq!(reactions,
|
||||||
|
vec![
|
||||||
|
PositiveReaction::from(
|
||||||
|
PositiveSet::from([(2, Positive), (3, Negative)]),
|
||||||
|
PositiveSet::from([(5, Positive)]),
|
||||||
|
),
|
||||||
|
PositiveReaction::from(
|
||||||
|
PositiveSet::from([(2, Negative)]),
|
||||||
|
PositiveSet::from([(5, Negative)]),
|
||||||
|
),
|
||||||
|
PositiveReaction::from(
|
||||||
|
PositiveSet::from([(3, Positive)]),
|
||||||
|
PositiveSet::from([(5, Negative)]),
|
||||||
|
),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn conversion_entities() {
|
||||||
|
use std::rc::Rc;
|
||||||
|
|
||||||
|
use super::system::{System, PositiveSystem};
|
||||||
|
use super::environment::Environment;
|
||||||
|
use super::set::Set;
|
||||||
|
use super::process::Process;
|
||||||
|
use super::reaction::Reaction;
|
||||||
|
use super::element::IdState::*;
|
||||||
|
|
||||||
|
let system = System {
|
||||||
|
delta: Rc::new(Environment::from([])),
|
||||||
|
available_entities: Set::from([1, 2]),
|
||||||
|
context_process: Process::Nill,
|
||||||
|
reaction_rules: Rc::new(vec![
|
||||||
|
Reaction::from(
|
||||||
|
Set::from([2]),
|
||||||
|
Set::from([1, 3]),
|
||||||
|
Set::from([5]),
|
||||||
|
),
|
||||||
|
Reaction::from(
|
||||||
|
Set::from([1, 2]),
|
||||||
|
Set::from([3]),
|
||||||
|
Set::from([5]),
|
||||||
|
),
|
||||||
|
]),
|
||||||
|
};
|
||||||
|
let converted_system: PositiveSystem = system.into();
|
||||||
|
let entities = converted_system.available_entities().clone();
|
||||||
|
|
||||||
|
assert_eq!(entities,
|
||||||
|
PositiveSet::from([(1, Positive),
|
||||||
|
(2, Positive),
|
||||||
|
(3, Negative),
|
||||||
|
(5, Negative)
|
||||||
|
]));
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user