Introducing traits for sets and reactions
This commit is contained in:
@ -1,6 +1,7 @@
|
|||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
use super::super::{translator, graph, set, process, system, label};
|
use super::super::{translator, graph, set, process, system, label};
|
||||||
|
use super::super::set::BasicSet;
|
||||||
|
|
||||||
/// If changing IntegerType in assert.rs, also change from Num to another
|
/// If changing IntegerType in assert.rs, also change from Num to another
|
||||||
/// similar parser with different return type in grammar.lalrpop in
|
/// similar parser with different return type in grammar.lalrpop in
|
||||||
|
|||||||
@ -890,12 +890,12 @@ fn for_1() {
|
|||||||
Box::new(Tree::Assignment(
|
Box::new(Tree::Assignment(
|
||||||
Variable::Id("a".into()),
|
Variable::Id("a".into()),
|
||||||
None,
|
None,
|
||||||
Box::new(Expression::Set(Set::new()))
|
Box::new(Expression::Set(Set::default()))
|
||||||
)),
|
)),
|
||||||
Box::new(Tree::Assignment(
|
Box::new(Tree::Assignment(
|
||||||
Variable::Id("b".into()),
|
Variable::Id("b".into()),
|
||||||
None,
|
None,
|
||||||
Box::new(Expression::Set(Set::new()))
|
Box::new(Expression::Set(Set::default()))
|
||||||
)),
|
)),
|
||||||
)),
|
)),
|
||||||
Box::new(Tree::For(
|
Box::new(Tree::For(
|
||||||
@ -945,7 +945,7 @@ fn for_2() {
|
|||||||
Box::new(Tree::Assignment(
|
Box::new(Tree::Assignment(
|
||||||
Variable::Id("b".into()),
|
Variable::Id("b".into()),
|
||||||
None,
|
None,
|
||||||
Box::new(Expression::Set(Set::new()))
|
Box::new(Expression::Set(Set::default()))
|
||||||
)),
|
)),
|
||||||
)),
|
)),
|
||||||
Box::new(Tree::For(
|
Box::new(Tree::For(
|
||||||
@ -996,19 +996,19 @@ fn for_3() {
|
|||||||
None,
|
None,
|
||||||
Box::new(Expression::Label(
|
Box::new(Expression::Label(
|
||||||
Box::new(Label::from(Set::from([1, 2]),
|
Box::new(Label::from(Set::from([1, 2]),
|
||||||
Set::new(),
|
Set::default(),
|
||||||
Set::from([1, 2]),
|
Set::from([1, 2]),
|
||||||
Set::new(),
|
Set::default(),
|
||||||
Set::new(),
|
Set::default(),
|
||||||
Set::new(),
|
Set::default(),
|
||||||
Set::new(),
|
Set::default(),
|
||||||
Set::new()))
|
Set::default()))
|
||||||
))
|
))
|
||||||
)),
|
)),
|
||||||
Box::new(Tree::Assignment(
|
Box::new(Tree::Assignment(
|
||||||
Variable::Id("b".into()),
|
Variable::Id("b".into()),
|
||||||
None,
|
None,
|
||||||
Box::new(Expression::Set(Set::new()))
|
Box::new(Expression::Set(Set::default()))
|
||||||
)),
|
)),
|
||||||
)),
|
)),
|
||||||
Box::new(Tree::For(
|
Box::new(Tree::For(
|
||||||
@ -1066,17 +1066,17 @@ fn for_4() {
|
|||||||
Box::new(Label::from(Set::from([1, 2]),
|
Box::new(Label::from(Set::from([1, 2]),
|
||||||
Set::from([3]),
|
Set::from([3]),
|
||||||
Set::from([1, 2, 3]),
|
Set::from([1, 2, 3]),
|
||||||
Set::new(),
|
Set::default(),
|
||||||
Set::new(),
|
Set::default(),
|
||||||
Set::new(),
|
Set::default(),
|
||||||
Set::new(),
|
Set::default(),
|
||||||
Set::new()))
|
Set::default()))
|
||||||
))
|
))
|
||||||
)),
|
)),
|
||||||
Box::new(Tree::Assignment(
|
Box::new(Tree::Assignment(
|
||||||
Variable::Id("b".into()),
|
Variable::Id("b".into()),
|
||||||
None,
|
None,
|
||||||
Box::new(Expression::Set(Set::new()))
|
Box::new(Expression::Set(Set::default()))
|
||||||
)),
|
)),
|
||||||
)),
|
)),
|
||||||
Box::new(Tree::For(
|
Box::new(Tree::For(
|
||||||
@ -1133,13 +1133,13 @@ fn for_5() {
|
|||||||
None,
|
None,
|
||||||
Box::new(Expression::Label(
|
Box::new(Expression::Label(
|
||||||
Box::new(Label::from(Set::from([1, 2]),
|
Box::new(Label::from(Set::from([1, 2]),
|
||||||
Set::from([3]),
|
Set::from([3]),
|
||||||
Set::from([1, 2, 3]),
|
Set::from([1, 2, 3]),
|
||||||
Set::new(),
|
Set::default(),
|
||||||
Set::new(),
|
Set::default(),
|
||||||
Set::new(),
|
Set::default(),
|
||||||
Set::new(),
|
Set::default(),
|
||||||
Set::new()))
|
Set::default()))
|
||||||
))
|
))
|
||||||
)),
|
)),
|
||||||
Box::new(Tree::Assignment(
|
Box::new(Tree::Assignment(
|
||||||
@ -1217,11 +1217,11 @@ fn for_6() {
|
|||||||
Box::new(Label::from(Set::from([1, 2]),
|
Box::new(Label::from(Set::from([1, 2]),
|
||||||
Set::from([3]),
|
Set::from([3]),
|
||||||
Set::from([1, 2, 3]),
|
Set::from([1, 2, 3]),
|
||||||
Set::new(),
|
Set::default(),
|
||||||
Set::new(),
|
Set::default(),
|
||||||
Set::new(),
|
Set::default(),
|
||||||
Set::new(),
|
Set::default(),
|
||||||
Set::new()))
|
Set::default()))
|
||||||
))
|
))
|
||||||
)),
|
)),
|
||||||
Box::new(Tree::Concat(
|
Box::new(Tree::Concat(
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|
||||||
use super::process::Process;
|
use super::process::Process;
|
||||||
use super::set::Set;
|
use super::set::{BasicSet, Set};
|
||||||
use super::translator::{Translator, PrintableWithTranslator, Formatter};
|
use super::translator::{Translator, PrintableWithTranslator, Formatter};
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
@ -18,7 +18,7 @@ impl Choices {
|
|||||||
|
|
||||||
pub fn new_not_empty() -> Self {
|
pub fn new_not_empty() -> Self {
|
||||||
Choices {
|
Choices {
|
||||||
context_moves: vec![(Rc::new(Set::new()),
|
context_moves: vec![(Rc::new(Set::default()),
|
||||||
Rc::new(Process::Nill))],
|
Rc::new(Process::Nill))],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -5,8 +5,8 @@ use std::rc::Rc;
|
|||||||
|
|
||||||
use super::choices::Choices;
|
use super::choices::Choices;
|
||||||
use super::process::Process;
|
use super::process::Process;
|
||||||
use super::reaction::Reaction;
|
use super::reaction::{Reaction, BasicReaction, ExtensionReaction};
|
||||||
use super::set::Set;
|
use super::set::{BasicSet, Set};
|
||||||
use super::translator::{IdType, Translator, PrintableWithTranslator, Formatter};
|
use super::translator::{IdType, Translator, PrintableWithTranslator, Formatter};
|
||||||
|
|
||||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||||
@ -30,7 +30,7 @@ impl Environment {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn all_elements(&self) -> Set {
|
pub fn all_elements(&self) -> Set {
|
||||||
let mut acc = Set::new();
|
let mut acc = Set::default();
|
||||||
for (_, process) in self.definitions.iter() {
|
for (_, process) in self.definitions.iter() {
|
||||||
acc.push(&process.all_elements());
|
acc.push(&process.all_elements());
|
||||||
}
|
}
|
||||||
@ -110,7 +110,7 @@ impl Environment {
|
|||||||
// short-circuits with try_fold.
|
// short-circuits with try_fold.
|
||||||
if children.is_empty() {
|
if children.is_empty() {
|
||||||
Ok(Choices::from(vec![(
|
Ok(Choices::from(vec![(
|
||||||
Rc::new(Set::new()),
|
Rc::new(Set::default()),
|
||||||
Rc::new(Process::Nill),
|
Rc::new(Process::Nill),
|
||||||
)]))
|
)]))
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
pub mod graph_map_nodes_ty_from {
|
pub mod graph_map_nodes_ty_from {
|
||||||
use super::super::set::Set;
|
use super::super::set::{BasicSet, Set};
|
||||||
use super::super::system::System;
|
use super::super::system::System;
|
||||||
use super::super::translator;
|
use super::super::translator;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
@ -74,7 +74,7 @@ pub mod graph_map_nodes_ty_from {
|
|||||||
|
|
||||||
|
|
||||||
pub mod graph_map_edges_ty_from {
|
pub mod graph_map_edges_ty_from {
|
||||||
use super::super::set::Set;
|
use super::super::set::{BasicSet, Set};
|
||||||
use super::super::label::Label;
|
use super::super::label::Label;
|
||||||
use super::super::translator;
|
use super::super::translator;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|||||||
@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
use super::reaction::Reaction;
|
use super::reaction::{Reaction, ExtensionReaction};
|
||||||
use super::set::Set;
|
use super::set::{Set, ExtensionsSet};
|
||||||
use super::system::System;
|
use super::system::System;
|
||||||
use super::translator::{IdType, Translator, PrintableWithTranslator, PRECISION};
|
use super::translator::{IdType, Translator, PrintableWithTranslator, PRECISION};
|
||||||
|
|
||||||
|
|||||||
@ -5,7 +5,7 @@ use petgraph::{Graph, Directed};
|
|||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|
||||||
use super::label::Label;
|
use super::label::Label;
|
||||||
use super::set::Set;
|
use super::set::{BasicSet, Set};
|
||||||
use super::system::System;
|
use super::system::System;
|
||||||
use super::translator::{self, IdType};
|
use super::translator::{self, IdType};
|
||||||
|
|
||||||
@ -19,7 +19,7 @@ fn common_system_entities(graph: &SystemGraph) -> Set {
|
|||||||
None => Some(node.1.available_entities.clone()),
|
None => Some(node.1.available_entities.clone()),
|
||||||
Some(acc) => Some(node.1.available_entities.intersection(&acc))
|
Some(acc) => Some(node.1.available_entities.intersection(&acc))
|
||||||
}
|
}
|
||||||
).unwrap_or(Set::new())
|
).unwrap_or(Set::default())
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! common_label {
|
macro_rules! common_label {
|
||||||
@ -39,7 +39,7 @@ macro_rules! common_label {
|
|||||||
Some($acc_name) => Some($some_expr)
|
Some($acc_name) => Some($some_expr)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
).unwrap_or(Set::new())
|
).unwrap_or(Set::default())
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -218,7 +218,7 @@ impl NodeDisplay {
|
|||||||
if self.contains_uncommon() {
|
if self.contains_uncommon() {
|
||||||
Rc::new(common_system_entities(current_graph))
|
Rc::new(common_system_entities(current_graph))
|
||||||
} else {
|
} else {
|
||||||
Rc::new(Set::new())
|
Rc::new(Set::default())
|
||||||
};
|
};
|
||||||
|
|
||||||
Box::new(
|
Box::new(
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::hash::Hash;
|
use std::hash::Hash;
|
||||||
|
|
||||||
use super::set::Set;
|
use super::set::{BasicSet, Set};
|
||||||
use super::translator::{Translator, PrintableWithTranslator, Formatter};
|
use super::translator::{Translator, PrintableWithTranslator, Formatter};
|
||||||
|
|
||||||
#[derive(Clone, Debug, Serialize, Deserialize, Eq, PartialOrd)]
|
#[derive(Clone, Debug, Serialize, Deserialize, Eq, PartialOrd)]
|
||||||
@ -19,14 +19,14 @@ pub struct Label {
|
|||||||
impl Label {
|
impl Label {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Label {
|
Label {
|
||||||
available_entities: Set::new(),
|
available_entities: Set::default(),
|
||||||
context: Set::new(),
|
context: Set::default(),
|
||||||
t: Set::new(),
|
t: Set::default(),
|
||||||
reactants: Set::new(),
|
reactants: Set::default(),
|
||||||
reactants_absent: Set::new(),
|
reactants_absent: Set::default(),
|
||||||
inhibitors: Set::new(),
|
inhibitors: Set::default(),
|
||||||
inhibitors_present: Set::new(),
|
inhibitors_present: Set::default(),
|
||||||
products: Set::new(),
|
products: Set::default(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -4,7 +4,7 @@ use std::hash::Hash;
|
|||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|
||||||
use super::reaction::Reaction;
|
use super::reaction::Reaction;
|
||||||
use super::set::Set;
|
use super::set::{Set, BasicSet};
|
||||||
use super::translator::{IdType, Translator, PrintableWithTranslator, Formatter};
|
use super::translator::{IdType, Translator, PrintableWithTranslator, Formatter};
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||||
@ -61,7 +61,7 @@ impl Process {
|
|||||||
/// returns all elements used
|
/// returns all elements used
|
||||||
pub fn all_elements(&self) -> Set {
|
pub fn all_elements(&self) -> Set {
|
||||||
let mut queue = VecDeque::from([self]);
|
let mut queue = VecDeque::from([self]);
|
||||||
let mut elements = Set::new();
|
let mut elements = Set::default();
|
||||||
|
|
||||||
while let Some(el) = queue.pop_front() {
|
while let Some(el) = queue.pop_front() {
|
||||||
match el {
|
match el {
|
||||||
|
|||||||
@ -6,161 +6,190 @@
|
|||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::hash::Hash;
|
use std::hash::Hash;
|
||||||
|
|
||||||
use super::set::Set;
|
use super::set::{BasicSet, ExtensionsSet, Set};
|
||||||
use super::translator::{Translator, PrintableWithTranslator, Formatter};
|
use super::translator::{Translator, PrintableWithTranslator, Formatter};
|
||||||
|
|
||||||
|
pub trait BasicReaction<S: BasicSet>:
|
||||||
|
Clone + Default + Eq + Hash + Serialize + PrintableWithTranslator
|
||||||
|
where for<'de> Self: Deserialize<'de>,
|
||||||
|
{
|
||||||
|
fn enabled(&self, state: &S) -> bool;
|
||||||
|
fn compute_step(&self, state: &S) -> Option<&S>;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait ExtensionReaction<S: BasicSet> {
|
||||||
|
fn compute_all(reactions: &[Self], state: &S) -> S
|
||||||
|
where Self: Sized;
|
||||||
|
|
||||||
|
fn find_loop(reactions: &[Self], entities: S, q: &S) -> (Vec<S>, Vec<S>)
|
||||||
|
where Self: Sized;
|
||||||
|
|
||||||
|
fn find_only_loop(reactions: &[Self], entities: S, q: &S) -> Vec<S>
|
||||||
|
where Self: Sized;
|
||||||
|
|
||||||
|
fn find_prefix_len_loop(
|
||||||
|
reactions: &[Self],
|
||||||
|
entities: S,
|
||||||
|
q: &S
|
||||||
|
) -> (usize, Vec<S>)
|
||||||
|
where Self: Sized;
|
||||||
|
|
||||||
|
fn lollipops_only_loop_decomposed_q(
|
||||||
|
reactions: &[Self],
|
||||||
|
entities: &S,
|
||||||
|
q: &S
|
||||||
|
) -> Vec<S>
|
||||||
|
where Self: Sized;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
impl<T: BasicReaction<S>, S: BasicSet> ExtensionReaction<S> for T {
|
||||||
|
/// Computes the result of a series of reactions. Returns the union of all
|
||||||
|
/// products.
|
||||||
|
/// see result
|
||||||
|
fn compute_all(
|
||||||
|
reactions: &[Self],
|
||||||
|
state: &S
|
||||||
|
) -> S
|
||||||
|
where Self: Sized {
|
||||||
|
reactions.iter().fold(S::default(), |mut acc: S, r| {
|
||||||
|
acc.extend(r.compute_step(state));
|
||||||
|
acc
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Finds the loops by simulating the system.
|
||||||
|
fn find_loop(
|
||||||
|
reactions: &[Self],
|
||||||
|
entities: S,
|
||||||
|
q: &S
|
||||||
|
) -> (Vec<S>, Vec<S>) {
|
||||||
|
let mut entities = entities;
|
||||||
|
let mut trace = vec![];
|
||||||
|
loop {
|
||||||
|
if let Some((prefix, hoop)) = entities.split(&trace) {
|
||||||
|
return (prefix.to_vec(), hoop.to_vec());
|
||||||
|
} else {
|
||||||
|
let t = entities.union(q);
|
||||||
|
let products = Self::compute_all(reactions, &t);
|
||||||
|
trace.push(entities.clone());
|
||||||
|
entities = products;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// Finds the loops by simulating the system.
|
||||||
|
fn find_only_loop(
|
||||||
|
reactions: &[Self],
|
||||||
|
entities: S,
|
||||||
|
q: &S
|
||||||
|
) -> Vec<S> {
|
||||||
|
let mut entities = entities;
|
||||||
|
let mut trace = vec![];
|
||||||
|
loop {
|
||||||
|
if let Some((_prefix, hoop)) = entities.split(&trace) {
|
||||||
|
return hoop.to_vec();
|
||||||
|
} else {
|
||||||
|
let t = entities.union(q);
|
||||||
|
let products = Self::compute_all(reactions, &t);
|
||||||
|
trace.push(entities.clone());
|
||||||
|
entities = products;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// Finds the loops and the length of the prefix by simulating the system.
|
||||||
|
fn find_prefix_len_loop(
|
||||||
|
reactions: &[Self],
|
||||||
|
entities: S,
|
||||||
|
q: &S
|
||||||
|
) -> (usize, Vec<S>) {
|
||||||
|
let mut entities = entities;
|
||||||
|
let mut trace = vec![];
|
||||||
|
loop {
|
||||||
|
if let Some((prefix, hoop)) = entities.split(&trace) {
|
||||||
|
return (prefix.len(), hoop.to_vec());
|
||||||
|
} else {
|
||||||
|
let t = entities.union(q);
|
||||||
|
let products = Self::compute_all(reactions, &t);
|
||||||
|
trace.push(entities.clone());
|
||||||
|
entities = products;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// see loop/5
|
||||||
|
fn lollipops_only_loop_decomposed_q(
|
||||||
|
reactions: &[Self],
|
||||||
|
entities: &S,
|
||||||
|
q: &S,
|
||||||
|
) -> Vec<S> {
|
||||||
|
let find_loop_fn =
|
||||||
|
|q| Self::find_only_loop(reactions,
|
||||||
|
entities.clone(),
|
||||||
|
q);
|
||||||
|
find_loop_fn(q)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
/// Basic structure for a reaction.
|
/// Basic structure for a reaction.
|
||||||
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq, Hash)]
|
#[derive(Clone, Debug, Default, Serialize, Deserialize, PartialEq, Eq, Hash)]
|
||||||
pub struct Reaction {
|
pub struct Reaction {
|
||||||
pub reactants: Set,
|
pub reactants: Set,
|
||||||
pub inhibitors: Set,
|
pub inhibitors: Set,
|
||||||
pub products: Set,
|
pub products: Set,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl BasicReaction<Set> for Reaction {
|
||||||
|
/// returns true if ```current_state``` enables the reaction
|
||||||
|
/// see enable
|
||||||
|
fn enabled(&self, current_state: &Set) -> bool {
|
||||||
|
self.reactants.is_subset(current_state)
|
||||||
|
&& self.inhibitors.is_disjoint(current_state)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Computes the result of a single reaction (if enabled returns the
|
||||||
|
/// products) otherwise returns None.
|
||||||
|
/// see result
|
||||||
|
fn compute_step(
|
||||||
|
&self,
|
||||||
|
state: &Set,
|
||||||
|
) -> Option<&Set> {
|
||||||
|
if self.enabled(state) {
|
||||||
|
Some(&self.products)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Reaction {
|
impl Reaction {
|
||||||
pub fn new() -> Self {
|
pub fn from(reactants: Set, inhibitors: Set, products: Set) -> Self {
|
||||||
Reaction {
|
Reaction {
|
||||||
reactants: Set::new(),
|
reactants,
|
||||||
inhibitors: Set::new(),
|
inhibitors,
|
||||||
products: Set::new(),
|
products,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
pub fn from(reactants: Set, inhibitors: Set, products: Set) -> Self {
|
|
||||||
Reaction {
|
|
||||||
reactants,
|
|
||||||
inhibitors,
|
|
||||||
products,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// returns true if ```current_state``` enables the reaction
|
|
||||||
/// see enable
|
|
||||||
pub fn enabled(&self, current_state: &Set) -> bool {
|
|
||||||
self.reactants.is_subset(current_state)
|
|
||||||
&& self.inhibitors.is_disjoint(current_state)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Computes the result of a single reaction (if enabled returns the products)
|
|
||||||
/// otherwise returns None.
|
|
||||||
/// see result
|
|
||||||
pub fn compute_step<'a>(
|
|
||||||
&'a self,
|
|
||||||
current_state: &'a Set,
|
|
||||||
) -> Option<&'a Set> {
|
|
||||||
if self.enabled(current_state) {
|
|
||||||
Some(&self.products)
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Computes the result of a series of reactions. Returns the union of all
|
|
||||||
/// products.
|
|
||||||
/// see result
|
|
||||||
pub fn compute_all<'a>(
|
|
||||||
current_state: &'a Set,
|
|
||||||
reactions: &'a [Self]
|
|
||||||
) -> Set {
|
|
||||||
reactions.iter().fold(Set::new(), |mut acc, r| {
|
|
||||||
acc.union_option(r.compute_step(current_state));
|
|
||||||
acc
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/// Finds the loops by simulating the system.
|
|
||||||
pub fn find_loop(
|
|
||||||
rs: &[Self],
|
|
||||||
entities: Set,
|
|
||||||
q: &Set
|
|
||||||
) -> (Vec<Set>, Vec<Set>) {
|
|
||||||
let mut entities = entities;
|
|
||||||
let mut trace = vec![];
|
|
||||||
loop {
|
|
||||||
if let Some((prefix, hoop)) = entities.split(&trace) {
|
|
||||||
return (prefix.to_vec(), hoop.to_vec());
|
|
||||||
} else {
|
|
||||||
let t = entities.union(q);
|
|
||||||
let products = Self::compute_all(&t, rs);
|
|
||||||
trace.push(entities.clone());
|
|
||||||
entities = products;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/// Finds the loops by simulating the system.
|
|
||||||
pub fn find_only_loop(
|
|
||||||
rs: &[Self],
|
|
||||||
entities: Set,
|
|
||||||
q: &Set
|
|
||||||
) -> Vec<Set> {
|
|
||||||
let mut entities = entities;
|
|
||||||
let mut trace = vec![];
|
|
||||||
loop {
|
|
||||||
if let Some((_prefix, hoop)) = entities.split(&trace) {
|
|
||||||
return hoop.to_vec();
|
|
||||||
} else {
|
|
||||||
let t = entities.union(q);
|
|
||||||
let products = Self::compute_all(&t, rs);
|
|
||||||
trace.push(entities.clone());
|
|
||||||
entities = products;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/// Finds the loops and the length of the prefix by simulating the system.
|
|
||||||
pub fn find_prefix_len_loop(
|
|
||||||
rs: &[Self],
|
|
||||||
entities: Set,
|
|
||||||
q: &Set
|
|
||||||
) -> (usize, Vec<Set>) {
|
|
||||||
let mut entities = entities;
|
|
||||||
let mut trace = vec![];
|
|
||||||
loop {
|
|
||||||
if let Some((prefix, hoop)) = entities.split(&trace) {
|
|
||||||
return (prefix.len(), hoop.to_vec());
|
|
||||||
} else {
|
|
||||||
let t = entities.union(q);
|
|
||||||
let products = Self::compute_all(&t, rs);
|
|
||||||
trace.push(entities.clone());
|
|
||||||
entities = products;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/// see loop/5
|
|
||||||
pub fn lollipops_only_loop_decomposed_q(
|
|
||||||
reaction_rules: &[Self],
|
|
||||||
q: &Set,
|
|
||||||
available_entities: &Set,
|
|
||||||
) -> Vec<Set> {
|
|
||||||
let find_loop_fn =
|
|
||||||
|q| Reaction::find_only_loop(reaction_rules,
|
|
||||||
available_entities.clone(),
|
|
||||||
q);
|
|
||||||
find_loop_fn(q)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Default for Reaction {
|
|
||||||
fn default() -> Self {
|
|
||||||
Reaction::new()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PrintableWithTranslator for Reaction {
|
impl PrintableWithTranslator for Reaction {
|
||||||
fn print(&self, f: &mut std::fmt::Formatter, translator: &Translator)
|
fn print(&self, f: &mut std::fmt::Formatter, translator: &Translator)
|
||||||
-> std::fmt::Result {
|
-> std::fmt::Result {
|
||||||
write!(
|
write!(
|
||||||
f,
|
f,
|
||||||
"(r: {}, i: {}, p: {})",
|
"(r: {}, i: {}, p: {})",
|
||||||
Formatter::from(translator, &self.reactants),
|
Formatter::from(translator, &self.reactants),
|
||||||
Formatter::from(translator, &self.inhibitors),
|
Formatter::from(translator, &self.inhibitors),
|
||||||
Formatter::from(translator, &self.products)
|
Formatter::from(translator, &self.products)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -5,108 +5,48 @@ use std::fmt;
|
|||||||
|
|
||||||
use super::translator::{IdType, Translator, PrintableWithTranslator};
|
use super::translator::{IdType, Translator, PrintableWithTranslator};
|
||||||
|
|
||||||
/// Basic set of entities.
|
|
||||||
#[derive(Clone, Debug, PartialOrd, Eq, Ord, Serialize, Deserialize)]
|
/// Basic trait for all Set implementations.
|
||||||
pub struct Set {
|
/// Implement IntoIterator for &Self to have .iter() (not required directly by
|
||||||
pub identifiers: BTreeSet<IdType>,
|
/// the trait).
|
||||||
|
pub trait BasicSet
|
||||||
|
where Self: Clone + Eq + Ord + Default + Serialize + IntoIterator
|
||||||
|
+ PrintableWithTranslator,
|
||||||
|
for<'de> Self: Deserialize<'de>
|
||||||
|
{
|
||||||
|
fn is_subset(&self, other: &Self) -> bool;
|
||||||
|
fn is_disjoint(&self, other: &Self) -> bool;
|
||||||
|
fn union(&self, other: &Self) -> Self;
|
||||||
|
fn push(&mut self, other: &Self);
|
||||||
|
fn extend(&mut self, other: Option<&Self>);
|
||||||
|
fn intersection(&self, other: &Self) -> Self;
|
||||||
|
fn subtraction(&self, other: &Self) -> Self;
|
||||||
|
fn len(&self) -> usize;
|
||||||
|
fn is_empty(&self) -> bool;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<const N: usize> From<[IdType; N]> for Set {
|
pub trait ExtensionsSet {
|
||||||
fn from(arr: [IdType; N]) -> Self {
|
fn iter(
|
||||||
Set {
|
&self
|
||||||
identifiers: BTreeSet::from(arr),
|
) -> <&Self as IntoIterator>::IntoIter
|
||||||
}
|
where for<'b> &'b Self: IntoIterator;
|
||||||
}
|
|
||||||
|
fn split<'a>(
|
||||||
|
&'a self,
|
||||||
|
trace: &'a [Self]
|
||||||
|
) -> Option<(&'a [Self], &'a [Self])>
|
||||||
|
where Self: Sized;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<&[IdType]> for Set {
|
/// Implementations for all sets.
|
||||||
fn from(arr: &[IdType]) -> Self {
|
impl<T: BasicSet> ExtensionsSet for T {
|
||||||
Set {
|
fn iter(&self) -> <&T as IntoIterator>::IntoIter
|
||||||
identifiers: BTreeSet::from_iter(arr.to_vec()),
|
where for<'b> &'b T: IntoIterator {
|
||||||
}
|
self.into_iter()
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<Vec<IdType>> for Set {
|
|
||||||
fn from(arr: Vec<IdType>) -> Self {
|
|
||||||
Set {
|
|
||||||
identifiers: BTreeSet::from_iter(arr),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Set {
|
|
||||||
pub const fn new() -> Self {
|
|
||||||
Set {
|
|
||||||
identifiers: BTreeSet::new(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn is_subset(&self, b: &Set) -> bool {
|
|
||||||
self.identifiers.is_subset(&b.identifiers)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn is_disjoint(&self, b: &Set) -> bool {
|
|
||||||
self.identifiers.is_disjoint(&b.identifiers)
|
|
||||||
}
|
|
||||||
|
|
||||||
// returns the new set a \cup b
|
|
||||||
pub fn union(&self, b: &Set) -> Set {
|
|
||||||
let mut ret: Set = b.clone();
|
|
||||||
ret.identifiers.extend(self.identifiers.iter());
|
|
||||||
ret
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn union_option(&mut self, b: Option<&Set>) {
|
|
||||||
if let Some(b) = b {
|
|
||||||
self.identifiers.extend(b.iter());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// returns the new set a \cap b
|
|
||||||
pub fn intersection(&self, b: &Set) -> Set {
|
|
||||||
// TODO maybe find more efficient way without copy/clone
|
|
||||||
let res: BTreeSet<_> = b
|
|
||||||
.identifiers
|
|
||||||
.intersection(&self.identifiers)
|
|
||||||
.copied()
|
|
||||||
.collect();
|
|
||||||
Set { identifiers: res }
|
|
||||||
}
|
|
||||||
|
|
||||||
/// returns the new set a ∖ b
|
|
||||||
pub fn subtraction(&self, b: &Set) -> Set {
|
|
||||||
// TODO maybe find more efficient way without copy/clone
|
|
||||||
let res: BTreeSet<_> = self
|
|
||||||
.identifiers
|
|
||||||
.difference(&b.identifiers)
|
|
||||||
.copied()
|
|
||||||
.collect();
|
|
||||||
Set { identifiers: res }
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn iter(&self) -> std::collections::btree_set::Iter<'_, IdType> {
|
|
||||||
self.identifiers.iter()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn len(&self) -> usize {
|
|
||||||
self.identifiers.len()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn insert(&mut self, el: IdType) -> bool {
|
|
||||||
self.identifiers.insert(el)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn push(&mut self, b: &Set) {
|
|
||||||
self.identifiers.extend(b.iter())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn is_empty(&self) -> bool {
|
|
||||||
self.identifiers.is_empty()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the prefix and the loop from a trace.
|
/// Returns the prefix and the loop from a trace.
|
||||||
pub fn split<'a>(
|
fn split<'a>(
|
||||||
&'a self,
|
&'a self,
|
||||||
trace: &'a [Self]
|
trace: &'a [Self]
|
||||||
) -> Option<(&'a [Self], &'a [Self])> {
|
) -> Option<(&'a [Self], &'a [Self])> {
|
||||||
@ -115,9 +55,69 @@ impl Set {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for Set {
|
|
||||||
fn default() -> Self {
|
// -----------------------------------------------------------------------------
|
||||||
Set::new()
|
|
||||||
|
/// Basic set of entities.
|
||||||
|
#[derive(Clone, Debug, Default, PartialOrd, Eq, Ord, Serialize, Deserialize)]
|
||||||
|
pub struct Set {
|
||||||
|
pub identifiers: BTreeSet<IdType>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl BasicSet for Set {
|
||||||
|
fn is_subset(&self, other: &Self) -> bool {
|
||||||
|
self.identifiers.is_subset(&other.identifiers)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn is_disjoint(&self, other: &Self) -> bool {
|
||||||
|
self.identifiers.is_disjoint(&other.identifiers)
|
||||||
|
}
|
||||||
|
|
||||||
|
// returns the new set a \cup b
|
||||||
|
fn union(&self, other: &Self) -> Self {
|
||||||
|
let mut ret: Set = other.clone();
|
||||||
|
ret.identifiers.extend(self.identifiers.iter());
|
||||||
|
ret
|
||||||
|
}
|
||||||
|
|
||||||
|
fn push(&mut self, b: &Self) {
|
||||||
|
self.identifiers.extend(b.iter())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn extend(&mut self, other: Option<&Self>) {
|
||||||
|
if let Some(other) = other {
|
||||||
|
self.identifiers.extend(other);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// returns the new set a \cap b
|
||||||
|
fn intersection(&self, other: &Self) -> Self {
|
||||||
|
// TODO maybe find more efficient way without copy/clone
|
||||||
|
let res: BTreeSet<_> = other
|
||||||
|
.identifiers
|
||||||
|
.intersection(&self.identifiers)
|
||||||
|
.copied()
|
||||||
|
.collect();
|
||||||
|
Set { identifiers: res }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// returns the new set a ∖ b
|
||||||
|
fn subtraction(&self, other: &Self) -> Self {
|
||||||
|
// TODO maybe find more efficient way without copy/clone
|
||||||
|
let res: BTreeSet<_> = self
|
||||||
|
.identifiers
|
||||||
|
.difference(&other.identifiers)
|
||||||
|
.copied()
|
||||||
|
.collect();
|
||||||
|
Set { identifiers: res }
|
||||||
|
}
|
||||||
|
|
||||||
|
fn len(&self) -> usize {
|
||||||
|
self.identifiers.len()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn is_empty(&self) -> bool {
|
||||||
|
self.identifiers.is_empty()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -142,6 +142,15 @@ impl IntoIterator for Set {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'a> IntoIterator for &'a Set {
|
||||||
|
type Item = &'a IdType;
|
||||||
|
type IntoIter = std::collections::btree_set::Iter<'a, IdType>;
|
||||||
|
|
||||||
|
fn into_iter(self) -> Self::IntoIter {
|
||||||
|
self.identifiers.iter()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl PrintableWithTranslator for Set {
|
impl PrintableWithTranslator for Set {
|
||||||
fn print(
|
fn print(
|
||||||
&self,
|
&self,
|
||||||
@ -164,3 +173,28 @@ impl PrintableWithTranslator for Set {
|
|||||||
write!(f, "}}")
|
write!(f, "}}")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
impl<const N: usize> From<[IdType; N]> for Set {
|
||||||
|
fn from(arr: [IdType; N]) -> Self {
|
||||||
|
Set {
|
||||||
|
identifiers: BTreeSet::from(arr),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<&[IdType]> for Set {
|
||||||
|
fn from(arr: &[IdType]) -> Self {
|
||||||
|
Set {
|
||||||
|
identifiers: BTreeSet::from_iter(arr.to_vec()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<Vec<IdType>> for Set {
|
||||||
|
fn from(arr: Vec<IdType>) -> Self {
|
||||||
|
Set {
|
||||||
|
identifiers: BTreeSet::from_iter(arr),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@ -7,8 +7,8 @@ use super::environment::Environment;
|
|||||||
use super::graph::SystemGraph;
|
use super::graph::SystemGraph;
|
||||||
use super::label::Label;
|
use super::label::Label;
|
||||||
use super::process::Process;
|
use super::process::Process;
|
||||||
use super::reaction::Reaction;
|
use super::reaction::{Reaction, ExtensionReaction};
|
||||||
use super::set::Set;
|
use super::set::{BasicSet, Set};
|
||||||
use super::transitions::TransitionsIterator;
|
use super::transitions::TransitionsIterator;
|
||||||
use super::translator::{IdType, Translator, PrintableWithTranslator, Formatter};
|
use super::translator::{IdType, Translator, PrintableWithTranslator, Formatter};
|
||||||
|
|
||||||
@ -27,7 +27,7 @@ impl System {
|
|||||||
pub fn new() -> System {
|
pub fn new() -> System {
|
||||||
System {
|
System {
|
||||||
delta: Rc::new(Environment::new()),
|
delta: Rc::new(Environment::new()),
|
||||||
available_entities: Set::new(),
|
available_entities: Set::default(),
|
||||||
context_process: Process::Nill,
|
context_process: Process::Nill,
|
||||||
reaction_rules: Rc::new(vec![]),
|
reaction_rules: Rc::new(vec![]),
|
||||||
}
|
}
|
||||||
@ -405,7 +405,7 @@ impl System {
|
|||||||
let reactants = self
|
let reactants = self
|
||||||
.reaction_rules
|
.reaction_rules
|
||||||
.iter()
|
.iter()
|
||||||
.fold(Set::new(), |acc, new| acc.union(&new.reactants));
|
.fold(Set::default(), |acc, new| acc.union(&new.reactants));
|
||||||
result.push_str(&format!(
|
result.push_str(&format!(
|
||||||
"The reactants are {}:\n{}\n",
|
"The reactants are {}:\n{}\n",
|
||||||
reactants.len(),
|
reactants.len(),
|
||||||
@ -415,7 +415,7 @@ impl System {
|
|||||||
let inhibitors = self
|
let inhibitors = self
|
||||||
.reaction_rules
|
.reaction_rules
|
||||||
.iter()
|
.iter()
|
||||||
.fold(Set::new(), |acc, new| acc.union(&new.inhibitors));
|
.fold(Set::default(), |acc, new| acc.union(&new.inhibitors));
|
||||||
result.push_str(&format!(
|
result.push_str(&format!(
|
||||||
"The inhibitors are {}:\n{}\n",
|
"The inhibitors are {}:\n{}\n",
|
||||||
inhibitors.len(),
|
inhibitors.len(),
|
||||||
@ -425,7 +425,7 @@ impl System {
|
|||||||
let products = self
|
let products = self
|
||||||
.reaction_rules
|
.reaction_rules
|
||||||
.iter()
|
.iter()
|
||||||
.fold(Set::new(), |acc, new| acc.union(&new.products));
|
.fold(Set::default(), |acc, new| acc.union(&new.products));
|
||||||
result.push_str(&format!(
|
result.push_str(&format!(
|
||||||
"The products are {}:\n{}\n",
|
"The products are {}:\n{}\n",
|
||||||
products.len(),
|
products.len(),
|
||||||
|
|||||||
@ -53,7 +53,7 @@ fn traces_1() {
|
|||||||
inhibitors: Set::from([1]),
|
inhibitors: Set::from([1]),
|
||||||
products: Set::from([1]), },
|
products: Set::from([1]), },
|
||||||
Reaction { reactants: Set::from([2]),
|
Reaction { reactants: Set::from([2]),
|
||||||
inhibitors: Set::new(),
|
inhibitors: Set::default(),
|
||||||
products: Set::from([4]), },
|
products: Set::from([4]), },
|
||||||
])
|
])
|
||||||
};
|
};
|
||||||
@ -113,7 +113,7 @@ fn traces_empty_env() {
|
|||||||
inhibitors: Set::from([1]),
|
inhibitors: Set::from([1]),
|
||||||
products: Set::from([1]), },
|
products: Set::from([1]), },
|
||||||
Reaction { reactants: Set::from([2]),
|
Reaction { reactants: Set::from([2]),
|
||||||
inhibitors: Set::new(),
|
inhibitors: Set::default(),
|
||||||
products: Set::from([4]), },
|
products: Set::from([4]), },
|
||||||
])
|
])
|
||||||
};
|
};
|
||||||
|
|||||||
@ -4,8 +4,9 @@ use std::rc::Rc;
|
|||||||
|
|
||||||
use super::label::Label;
|
use super::label::Label;
|
||||||
use super::process::Process;
|
use super::process::Process;
|
||||||
use super::set::Set;
|
use super::set::{BasicSet, Set};
|
||||||
use super::system::System;
|
use super::system::System;
|
||||||
|
use super::reaction::BasicReaction;
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct TransitionsIterator<'a> {
|
pub struct TransitionsIterator<'a> {
|
||||||
@ -44,11 +45,11 @@ impl<'a> Iterator for TransitionsIterator<'a> {
|
|||||||
) =
|
) =
|
||||||
self.system.reaction_rules.iter().fold(
|
self.system.reaction_rules.iter().fold(
|
||||||
(
|
(
|
||||||
Set::new(), // reactants
|
Set::default(), // reactants
|
||||||
Set::new(), // reactants_absent
|
Set::default(), // reactants_absent
|
||||||
Set::new(), // inhibitors
|
Set::default(), // inhibitors
|
||||||
Set::new(), // inhibitors_present
|
Set::default(), // inhibitors_present
|
||||||
Set::new(), // products
|
Set::default(), // products
|
||||||
),
|
),
|
||||||
|acc, reaction| {
|
|acc, reaction| {
|
||||||
if reaction.enabled(&t) {
|
if reaction.enabled(&t) {
|
||||||
|
|||||||
Reference in New Issue
Block a user