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),
|
||||
}
|
||||
}
|
||||
|
||||
/// 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)
|
||||
) {
|
||||
let intersection = set1.opposite_intersection(set2);
|
||||
if intersection.len() != 1 {
|
||||
continue
|
||||
}
|
||||
set1.remove_elements(intersection);
|
||||
|
||||
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.
|
||||
fn from(value: System) -> Self {
|
||||
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
|
||||
.context_process
|
||||
@ -666,27 +667,46 @@ impl From<System> for PositiveSystem {
|
||||
)
|
||||
.subtraction(&value.available_entities)
|
||||
.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_reactions = {
|
||||
let mut res = vec![];
|
||||
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);
|
||||
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(
|
||||
&p.iter().map(|p| p.reactants.clone()).collect::<Vec<_>>(),
|
||||
&p.iter().map(|p| p.inhibitors.clone()).collect::<Vec<_>>(),
|
||||
)
|
||||
.unwrap();
|
||||
).unwrap(); // since we have in input a valid system
|
||||
for s in prohib_set {
|
||||
res.push(PositiveReaction {
|
||||
reactants: s,
|
||||
@ -694,6 +714,8 @@ impl From<System> for PositiveSystem {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Rc::new(res)
|
||||
};
|
||||
|
||||
|
||||
@ -1,3 +1,5 @@
|
||||
use crate::rsprocess::{set::PositiveSet, system::BasicSystem};
|
||||
|
||||
#[test]
|
||||
fn one_transition() {
|
||||
use super::environment::Environment;
|
||||
@ -14,11 +16,13 @@ fn one_transition() {
|
||||
entities: Set::from([]),
|
||||
next_process: Rc::new(Process::Nill),
|
||||
},
|
||||
Rc::new(vec![Reaction {
|
||||
reactants: Set::from([1]),
|
||||
inhibitors: Set::from([3]),
|
||||
products: Set::from([3]),
|
||||
}]),
|
||||
Rc::new(vec![
|
||||
Reaction::from(
|
||||
Set::from([1]),
|
||||
Set::from([3]),
|
||||
Set::from([3]),
|
||||
),
|
||||
]),
|
||||
);
|
||||
|
||||
match system.one_transition() {
|
||||
@ -59,7 +63,8 @@ fn one_transition_2() {
|
||||
},
|
||||
Rc::new(vec![
|
||||
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)]),
|
||||
},
|
||||
PositiveReaction {
|
||||
@ -122,11 +127,13 @@ fn convertion() {
|
||||
entities: Set::from([]),
|
||||
next_process: Rc::new(Process::Nill),
|
||||
},
|
||||
Rc::new(vec![Reaction {
|
||||
reactants: Set::from([1]),
|
||||
inhibitors: Set::from([3]),
|
||||
products: Set::from([3]),
|
||||
}]),
|
||||
Rc::new(vec![
|
||||
Reaction::from(
|
||||
Set::from([1]),
|
||||
Set::from([3]),
|
||||
Set::from([3]),
|
||||
),
|
||||
]),
|
||||
);
|
||||
|
||||
let system: PositiveSystem = system.into();
|
||||
@ -202,21 +209,21 @@ fn traces_1() {
|
||||
available_entities: Set::from([1, 2]),
|
||||
context_process: Process::RecursiveIdentifier { identifier: 101 },
|
||||
reaction_rules: Rc::new(vec![
|
||||
Reaction {
|
||||
reactants: Set::from([1]),
|
||||
inhibitors: Set::from([3]),
|
||||
products: Set::from([3]),
|
||||
},
|
||||
Reaction {
|
||||
reactants: Set::from([3]),
|
||||
inhibitors: Set::from([1]),
|
||||
products: Set::from([1]),
|
||||
},
|
||||
Reaction {
|
||||
reactants: Set::from([2]),
|
||||
inhibitors: Set::default(),
|
||||
products: Set::from([4]),
|
||||
},
|
||||
Reaction::from(
|
||||
Set::from([1]),
|
||||
Set::from([3]),
|
||||
Set::from([3]),
|
||||
),
|
||||
Reaction::from(
|
||||
Set::from([3]),
|
||||
Set::from([1]),
|
||||
Set::from([1]),
|
||||
),
|
||||
Reaction::from(
|
||||
Set::from([2]),
|
||||
Set::default(),
|
||||
Set::from([4]),
|
||||
),
|
||||
]),
|
||||
};
|
||||
|
||||
@ -261,21 +268,21 @@ fn traces_empty_env() {
|
||||
next_process: Rc::new(Process::Nill),
|
||||
},
|
||||
reaction_rules: Rc::new(vec![
|
||||
Reaction {
|
||||
reactants: Set::from([1]),
|
||||
inhibitors: Set::from([3]),
|
||||
products: Set::from([3]),
|
||||
},
|
||||
Reaction {
|
||||
reactants: Set::from([3]),
|
||||
inhibitors: Set::from([1]),
|
||||
products: Set::from([1]),
|
||||
},
|
||||
Reaction {
|
||||
reactants: Set::from([2]),
|
||||
inhibitors: Set::default(),
|
||||
products: Set::from([4]),
|
||||
},
|
||||
Reaction::from(
|
||||
Set::from([1]),
|
||||
Set::from([3]),
|
||||
Set::from([3]),
|
||||
),
|
||||
Reaction::from(
|
||||
Set::from([3]),
|
||||
Set::from([1]),
|
||||
Set::from([1]),
|
||||
),
|
||||
Reaction::from(
|
||||
Set::from([2]),
|
||||
Set::default(),
|
||||
Set::from([4]),
|
||||
),
|
||||
]),
|
||||
};
|
||||
|
||||
@ -283,3 +290,92 @@ fn traces_empty_env() {
|
||||
assert_eq!(res.len(), 1);
|
||||
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