This commit is contained in:
elvis
2025-12-02 05:01:16 +01:00
parent a85c372462
commit ca6f6e7b39
6 changed files with 178 additions and 76 deletions

View File

@ -211,6 +211,7 @@ impl Reaction {
.fold(Set::default(), |acc, r| acc.union(&r.products))
}
/// Returns all reactions that have a certain product
pub fn all_reactions_with_product<'a>(
reactions: &'a [Self],
el: &IdType,
@ -238,7 +239,8 @@ impl BasicReaction for PositiveReaction {
type Set = PositiveSet;
fn enabled(&self, state: &Self::Set) -> bool {
self.reactants.is_subset(state)
self.reactants.has_positives(state)
// self.reactants.is_subset(state)
}
fn compute_step(&self, state: &Self::Set) -> Option<&Self::Set> {
@ -281,6 +283,8 @@ impl PositiveReaction {
}
}
/// Creates a Positive Reaction from the positive reactants and negative
/// inhibitors that produces positive products.
pub fn create(reactants: Set, inhibitors: Set, products: Set) -> Self {
Self {
reactants: reactants
@ -290,7 +294,7 @@ impl PositiveReaction {
}
}
/// returns the reactants that are equal
/// Returns the reactants that are equal
pub fn differ_only_one_element(&self, other: &Self) -> Option<PositiveSet> {
if self.products != other.products {
return None;
@ -334,9 +338,10 @@ impl Reaction {
r.reactants.clone(),
r.inhibitors.clone(),
Set::from([el]),
))
));
}
tmp.sort_by(|r1, r2| r1.reactants.cmp(&r2.reactants));
tmp.dedup();
// remove reactions with only one element of opposite state
// as intersection (same product ```el```)
@ -344,6 +349,7 @@ impl Reaction {
while pos > 0 {
if let Some(intersection) =
tmp[pos].differ_only_one_element(&tmp[pos - 1])
// && !intersection.is_empty()
{
tmp[pos - 1].reactants = intersection;
tmp.remove(pos);
@ -364,6 +370,7 @@ impl Reaction {
})
}
}
res
}
}

View File

@ -352,9 +352,13 @@ impl Set {
},
}
}
t
};
t.sort();
t.dedup();
// minimization
// remove sets that contain other sets
{
@ -682,6 +686,20 @@ impl PositiveSet {
)
}
pub fn inverted_mask(&self, other: &Self) -> Self {
Self::from_iter(
self.iter()
.filter(|el| {
!other.contains(&PositiveType::from((
*el.0,
IdState::Positive
))
)
})
.map(|el| (*el.0, *el.1))
)
}
fn remove_elements(&mut self, other: Vec<IdType>) {
for element in other {
self.identifiers.remove(&element);
@ -703,7 +721,7 @@ impl PositiveSet {
self_copy.is_empty()
}
// Returns only the positive entities.
/// Returns only the positive entities.
pub fn positives(&self) -> Self {
self.iter()
.filter(|el| *el.1 == IdState::Positive)
@ -711,7 +729,7 @@ impl PositiveSet {
.collect::<PositiveSet>()
}
// Returns only the negative entities.
/// Returns only the negative entities.
pub fn negatives(&self) -> Self {
self.iter()
.filter(|el| *el.1 == IdState::Negative)
@ -719,6 +737,7 @@ impl PositiveSet {
.collect::<PositiveSet>()
}
/// Adds only the elements not in self that are in other.
pub fn add_unique(&self, other: &Self) -> Self {
other
.iter()
@ -731,4 +750,27 @@ impl PositiveSet {
pub fn elements(&self) -> Set {
self.iter().map(|el| *el.0).collect::<Vec<_>>().into()
}
pub fn has_positives(&self, state: &Self) -> bool {
self.iter()
.all(|a| {
if *a.1 == IdState::Positive {
state.contains(&PositiveType::from(a))
} else {
!state.contains(&PositiveType::from((*a.0, IdState::Positive)))
}
})
}
fn has_element(&self, el: &PositiveType) -> bool {
self.identifiers.contains_key(&el.id)
}
pub fn push_unique(&self, other: &Self) -> Self {
self.union(
&other.iter().filter(|el| {
!self.has_element(&PositiveType::from(*el))
}).map(|el| (*el.0, *el.1)).collect::<Vec<_>>().into()
)
}
}

View File

@ -715,6 +715,26 @@ impl System {
self.products_elements =
Arc::new(Mutex::new(Some(new_product_elements)));
}
pub fn precomputed_context_elements(&mut self, new_context_elements: Option<Set>) {
if let Some(nce) = new_context_elements {
self.overwrite_context_elements(nce);
}
}
pub fn precomputed_product_elements(&mut self, new_product_elements: Option<Set>) {
if let Some(npe) = new_product_elements {
self.overwrite_product_elements(npe);
}
}
pub fn direct_get_product_elements(&self) -> Option<Set> {
self.products_elements.lock().unwrap().clone()
}
pub fn direct_get_context_elements(&self) -> Option<Set> {
self.context_elements.lock().unwrap().clone()
}
}
// -----------------------------------------------------------------------------
@ -1005,7 +1025,7 @@ impl PrintableWithTranslator for PositiveSystem {
if it.peek().is_none() {
write!(f, "{}", Formatter::from(translator, el))?;
} else {
write!(f, "{}, ", Formatter::from(translator, el))?;
writeln!(f, "{},", Formatter::from(translator, el))?;
}
}
write!(f, "]\n]")
@ -1023,22 +1043,25 @@ impl From<System> for PositiveSystem {
let positive_entities =
value.available_entities.to_positive_set(IdState::Positive);
let negative_entities = value
.context_process
.all_elements()
.union(&value.environment().all_elements())
.union(&value.reactions().iter().fold(
Set::default(),
|acc: Set, el| {
acc.union(&el.inhibitors)
.union(&el.products)
.union(&el.reactants)
},
))
.subtraction(&value.available_entities)
// let negative_entities = value
// .context_process
// .all_elements()
// .union(&value.environment().all_elements())
// .union(&value.reactions().iter().fold(
// Set::default(),
// |acc: Set, el| {
// acc.union(&el.inhibitors)
// .union(&el.products)
// .union(&el.reactants)
// },
// ))
// .subtraction(&value.available_entities)
// .to_positive_set(IdState::Negative);
let negative_entities =
value.products_elements()
.to_positive_set(IdState::Negative);
let new_available_entities =
positive_entities.union(&negative_entities);
positive_entities.add_unique(&negative_entities);
let new_reactions =
Arc::new(PositiveReaction::from_reactions(value.reactions()));
@ -1091,4 +1114,24 @@ impl PositiveSystem {
self.products_elements =
Arc::new(Mutex::new(Some(new_product_elements)));
}
pub fn precomputed_context_elements(&mut self, new_context_elements: Option<PositiveSet>) {
if let Some(nce) = new_context_elements {
self.overwrite_context_elements(nce);
}
}
pub fn precomputed_product_elements(&mut self, new_product_elements: Option<PositiveSet>) {
if let Some(npe) = new_product_elements {
self.overwrite_product_elements(npe);
}
}
pub fn direct_get_product_elements(&self) -> Option<PositiveSet> {
self.products_elements.lock().unwrap().clone()
}
pub fn direct_get_context_elements(&self) -> Option<PositiveSet> {
self.context_elements.lock().unwrap().clone()
}
}

View File

@ -328,7 +328,6 @@ fn conversion_entities() {
PositiveSet::from([
(1, Positive),
(2, Positive),
(3, Negative),
(5, Negative)
])
);

View File

@ -323,7 +323,7 @@ impl SlicingTrace<PositiveSet, PositiveReaction, PositiveSystem> {
reversed_elements[reverse_i].context.push(
&self.reactions[*r]
.reactants()
.mask(&self.context_elements),
.inverted_mask(&self.products_elements),
);
reversed_elements[reverse_i].reaction_products.push(
&self.reactions[*r]
@ -361,45 +361,6 @@ impl<
f: &mut std::fmt::Formatter,
translator: &crate::translator::Translator,
) -> std::fmt::Result {
// let mut systems = self.systems.iter().peekable();
// writeln!(f, "Systems:")?;
// while let Some(system) = systems.next() {
// if systems.peek().is_some() {
// write!(f, "{} --> ", Formatter::from(translator,
// &**system))?; } else {
// writeln!(f, "{}", Formatter::from(translator, &**system))?;
// }
// }
let mut reactions = self.reactions.iter().enumerate().peekable();
writeln!(f, "Reactions:")?;
while let Some((pos, reaction)) = reactions.next() {
if reactions.peek().is_some() {
writeln!(
f,
"\t({pos}) {},",
Formatter::from(translator, reaction)
)?;
} else {
writeln!(
f,
"\t({pos}) {}.",
Formatter::from(translator, reaction)
)?;
}
}
writeln!(
f,
"Context Elements: {}",
Formatter::from(translator, &*self.context_elements)
)?;
writeln!(
f,
"Product Elements: {}",
Formatter::from(translator, &*self.products_elements)
)?;
writeln!(f, "Trace:")?;
let mut elements = self.elements.iter().peekable();
@ -440,6 +401,45 @@ impl<
}
}
// let mut systems = self.systems.iter().peekable();
// writeln!(f, "Systems:")?;
// while let Some(system) = systems.next() {
// if systems.peek().is_some() {
// write!(f, "{} --> ", Formatter::from(translator,
// &**system))?; } else {
// writeln!(f, "{}", Formatter::from(translator, &**system))?;
// }
// }
let mut reactions = self.reactions.iter().enumerate().peekable();
writeln!(f, "Reactions:")?;
while let Some((pos, reaction)) = reactions.next() {
if reactions.peek().is_some() {
writeln!(
f,
"\t({pos}) {},",
Formatter::from(translator, reaction)
)?;
} else {
writeln!(
f,
"\t({pos}) {}.",
Formatter::from(translator, reaction)
)?;
}
}
writeln!(
f,
"Context Elements: {}",
Formatter::from(translator, &*self.context_elements)
)?;
writeln!(
f,
"Product Elements: {}",
Formatter::from(translator, &*self.products_elements)
)?;
Ok(())
}
}

View File

@ -84,22 +84,25 @@ impl<'a> Iterator for TransitionsIterator<'a, Set, System, Process> {
},
);
let label = Label::from(
let label = Label::create(
self.system.available_entities.clone(),
(*c).clone(),
t,
reactants,
reactants_absent,
inhibitors,
inhibitors_present,
products.clone(),
);
let new_system = System::from(
let mut new_system = System::from(
Arc::clone(&self.system.delta),
products,
(*k).clone(),
Arc::clone(&self.system.reaction_rules),
);
new_system.precomputed_context_elements(self.system.direct_get_context_elements());
new_system.precomputed_product_elements(self.system.direct_get_product_elements());
Some((label, new_system))
}
}
@ -136,6 +139,7 @@ impl<'a> Iterator
fn next(&mut self) -> Option<Self::Item> {
let (c, k) = self.choices_iterator.next()?;
let t = self.system.available_entities.union(c.as_ref());
let (
reactants,
reactants_absent,
@ -175,23 +179,26 @@ impl<'a> Iterator
},
);
let label = PositiveLabel::from(
let label = PositiveLabel::create(
self.system.available_entities.clone(),
(*c).clone(),
t,
reactants,
reactants_absent,
inhibitors,
inhibitors_present,
products.clone(),
);
let new_system = PositiveSystem::from(
let mut new_system = PositiveSystem::from(
Arc::clone(&self.system.delta),
// products.add_unique(&self.system.negated_products_elements()),
products,
products.push_unique(&self.system.negated_products_elements()),
// products,
(*k).clone(),
Arc::clone(&self.system.reaction_rules),
);
new_system.precomputed_context_elements(self.system.direct_get_context_elements());
new_system.precomputed_product_elements(self.system.direct_get_product_elements());
Some((label, new_system))
}
}
@ -260,7 +267,7 @@ impl<'a> Iterator for TraceIterator<'a, Set, System, Process> {
},
);
let new_system = System::from(
let mut new_system = System::from(
Arc::clone(&self.system.delta),
// all_products.add_unique(&self.system.
// negated_products_elements()),
@ -269,6 +276,9 @@ impl<'a> Iterator for TraceIterator<'a, Set, System, Process> {
Arc::clone(&self.system.reaction_rules),
);
new_system.precomputed_context_elements(self.system.direct_get_context_elements());
new_system.precomputed_product_elements(self.system.direct_get_product_elements());
Some((
context.as_ref().clone(),
all_products,
@ -285,8 +295,7 @@ impl<'a> Iterator
fn next(&mut self) -> Option<Self::Item> {
let (context, k) = self.choices_iterator.next()?;
let total_entities =
self.system.available_entities().union(context.as_ref());
let total_entities = self.system.available_entities().union(context.as_ref());
let (enabled_reaction_positions, all_products) =
self.system.reactions().iter().enumerate().fold(
@ -301,15 +310,17 @@ impl<'a> Iterator
},
);
let new_system = PositiveSystem::from(
let mut new_system = PositiveSystem::from(
Arc::clone(&self.system.delta),
// all_products.add_unique(&self.system.
// negated_products_elements()),
all_products.clone(),
all_products.push_unique(&self.system.negated_products_elements()),
// all_products.clone(),
(*k).clone(),
Arc::clone(&self.system.reaction_rules),
);
new_system.precomputed_context_elements(self.system.direct_get_context_elements());
new_system.precomputed_product_elements(self.system.direct_get_product_elements());
Some((
context.as_ref().clone(),
all_products.mask(&self.system.products_elements()),