Introducing traits for sets and reactions
This commit is contained in:
@ -1,6 +1,7 @@
|
||||
use std::collections::HashMap;
|
||||
|
||||
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
|
||||
/// similar parser with different return type in grammar.lalrpop in
|
||||
|
||||
@ -890,12 +890,12 @@ fn for_1() {
|
||||
Box::new(Tree::Assignment(
|
||||
Variable::Id("a".into()),
|
||||
None,
|
||||
Box::new(Expression::Set(Set::new()))
|
||||
Box::new(Expression::Set(Set::default()))
|
||||
)),
|
||||
Box::new(Tree::Assignment(
|
||||
Variable::Id("b".into()),
|
||||
None,
|
||||
Box::new(Expression::Set(Set::new()))
|
||||
Box::new(Expression::Set(Set::default()))
|
||||
)),
|
||||
)),
|
||||
Box::new(Tree::For(
|
||||
@ -945,7 +945,7 @@ fn for_2() {
|
||||
Box::new(Tree::Assignment(
|
||||
Variable::Id("b".into()),
|
||||
None,
|
||||
Box::new(Expression::Set(Set::new()))
|
||||
Box::new(Expression::Set(Set::default()))
|
||||
)),
|
||||
)),
|
||||
Box::new(Tree::For(
|
||||
@ -996,19 +996,19 @@ fn for_3() {
|
||||
None,
|
||||
Box::new(Expression::Label(
|
||||
Box::new(Label::from(Set::from([1, 2]),
|
||||
Set::new(),
|
||||
Set::default(),
|
||||
Set::from([1, 2]),
|
||||
Set::new(),
|
||||
Set::new(),
|
||||
Set::new(),
|
||||
Set::new(),
|
||||
Set::new()))
|
||||
Set::default(),
|
||||
Set::default(),
|
||||
Set::default(),
|
||||
Set::default(),
|
||||
Set::default()))
|
||||
))
|
||||
)),
|
||||
Box::new(Tree::Assignment(
|
||||
Variable::Id("b".into()),
|
||||
None,
|
||||
Box::new(Expression::Set(Set::new()))
|
||||
Box::new(Expression::Set(Set::default()))
|
||||
)),
|
||||
)),
|
||||
Box::new(Tree::For(
|
||||
@ -1066,17 +1066,17 @@ fn for_4() {
|
||||
Box::new(Label::from(Set::from([1, 2]),
|
||||
Set::from([3]),
|
||||
Set::from([1, 2, 3]),
|
||||
Set::new(),
|
||||
Set::new(),
|
||||
Set::new(),
|
||||
Set::new(),
|
||||
Set::new()))
|
||||
Set::default(),
|
||||
Set::default(),
|
||||
Set::default(),
|
||||
Set::default(),
|
||||
Set::default()))
|
||||
))
|
||||
)),
|
||||
Box::new(Tree::Assignment(
|
||||
Variable::Id("b".into()),
|
||||
None,
|
||||
Box::new(Expression::Set(Set::new()))
|
||||
Box::new(Expression::Set(Set::default()))
|
||||
)),
|
||||
)),
|
||||
Box::new(Tree::For(
|
||||
@ -1135,11 +1135,11 @@ fn for_5() {
|
||||
Box::new(Label::from(Set::from([1, 2]),
|
||||
Set::from([3]),
|
||||
Set::from([1, 2, 3]),
|
||||
Set::new(),
|
||||
Set::new(),
|
||||
Set::new(),
|
||||
Set::new(),
|
||||
Set::new()))
|
||||
Set::default(),
|
||||
Set::default(),
|
||||
Set::default(),
|
||||
Set::default(),
|
||||
Set::default()))
|
||||
))
|
||||
)),
|
||||
Box::new(Tree::Assignment(
|
||||
@ -1217,11 +1217,11 @@ fn for_6() {
|
||||
Box::new(Label::from(Set::from([1, 2]),
|
||||
Set::from([3]),
|
||||
Set::from([1, 2, 3]),
|
||||
Set::new(),
|
||||
Set::new(),
|
||||
Set::new(),
|
||||
Set::new(),
|
||||
Set::new()))
|
||||
Set::default(),
|
||||
Set::default(),
|
||||
Set::default(),
|
||||
Set::default(),
|
||||
Set::default()))
|
||||
))
|
||||
)),
|
||||
Box::new(Tree::Concat(
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
use std::rc::Rc;
|
||||
|
||||
use super::process::Process;
|
||||
use super::set::Set;
|
||||
use super::set::{BasicSet, Set};
|
||||
use super::translator::{Translator, PrintableWithTranslator, Formatter};
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
@ -18,7 +18,7 @@ impl Choices {
|
||||
|
||||
pub fn new_not_empty() -> Self {
|
||||
Choices {
|
||||
context_moves: vec![(Rc::new(Set::new()),
|
||||
context_moves: vec![(Rc::new(Set::default()),
|
||||
Rc::new(Process::Nill))],
|
||||
}
|
||||
}
|
||||
|
||||
@ -5,8 +5,8 @@ use std::rc::Rc;
|
||||
|
||||
use super::choices::Choices;
|
||||
use super::process::Process;
|
||||
use super::reaction::Reaction;
|
||||
use super::set::Set;
|
||||
use super::reaction::{Reaction, BasicReaction, ExtensionReaction};
|
||||
use super::set::{BasicSet, Set};
|
||||
use super::translator::{IdType, Translator, PrintableWithTranslator, Formatter};
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||
@ -30,7 +30,7 @@ impl Environment {
|
||||
}
|
||||
|
||||
pub fn all_elements(&self) -> Set {
|
||||
let mut acc = Set::new();
|
||||
let mut acc = Set::default();
|
||||
for (_, process) in self.definitions.iter() {
|
||||
acc.push(&process.all_elements());
|
||||
}
|
||||
@ -110,7 +110,7 @@ impl Environment {
|
||||
// short-circuits with try_fold.
|
||||
if children.is_empty() {
|
||||
Ok(Choices::from(vec![(
|
||||
Rc::new(Set::new()),
|
||||
Rc::new(Set::default()),
|
||||
Rc::new(Process::Nill),
|
||||
)]))
|
||||
} else {
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
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::translator;
|
||||
use std::rc::Rc;
|
||||
@ -74,7 +74,7 @@ pub mod graph_map_nodes_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::translator;
|
||||
use std::rc::Rc;
|
||||
|
||||
@ -2,8 +2,8 @@
|
||||
|
||||
use std::collections::HashMap;
|
||||
|
||||
use super::reaction::Reaction;
|
||||
use super::set::Set;
|
||||
use super::reaction::{Reaction, ExtensionReaction};
|
||||
use super::set::{Set, ExtensionsSet};
|
||||
use super::system::System;
|
||||
use super::translator::{IdType, Translator, PrintableWithTranslator, PRECISION};
|
||||
|
||||
|
||||
@ -5,7 +5,7 @@ use petgraph::{Graph, Directed};
|
||||
use std::rc::Rc;
|
||||
|
||||
use super::label::Label;
|
||||
use super::set::Set;
|
||||
use super::set::{BasicSet, Set};
|
||||
use super::system::System;
|
||||
use super::translator::{self, IdType};
|
||||
|
||||
@ -19,7 +19,7 @@ fn common_system_entities(graph: &SystemGraph) -> Set {
|
||||
None => Some(node.1.available_entities.clone()),
|
||||
Some(acc) => Some(node.1.available_entities.intersection(&acc))
|
||||
}
|
||||
).unwrap_or(Set::new())
|
||||
).unwrap_or(Set::default())
|
||||
}
|
||||
|
||||
macro_rules! common_label {
|
||||
@ -39,7 +39,7 @@ macro_rules! common_label {
|
||||
Some($acc_name) => Some($some_expr)
|
||||
}
|
||||
}
|
||||
).unwrap_or(Set::new())
|
||||
).unwrap_or(Set::default())
|
||||
}
|
||||
};
|
||||
}
|
||||
@ -218,7 +218,7 @@ impl NodeDisplay {
|
||||
if self.contains_uncommon() {
|
||||
Rc::new(common_system_entities(current_graph))
|
||||
} else {
|
||||
Rc::new(Set::new())
|
||||
Rc::new(Set::default())
|
||||
};
|
||||
|
||||
Box::new(
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::hash::Hash;
|
||||
|
||||
use super::set::Set;
|
||||
use super::set::{BasicSet, Set};
|
||||
use super::translator::{Translator, PrintableWithTranslator, Formatter};
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, Eq, PartialOrd)]
|
||||
@ -19,14 +19,14 @@ pub struct Label {
|
||||
impl Label {
|
||||
pub fn new() -> Self {
|
||||
Label {
|
||||
available_entities: Set::new(),
|
||||
context: Set::new(),
|
||||
t: Set::new(),
|
||||
reactants: Set::new(),
|
||||
reactants_absent: Set::new(),
|
||||
inhibitors: Set::new(),
|
||||
inhibitors_present: Set::new(),
|
||||
products: Set::new(),
|
||||
available_entities: Set::default(),
|
||||
context: Set::default(),
|
||||
t: Set::default(),
|
||||
reactants: Set::default(),
|
||||
reactants_absent: Set::default(),
|
||||
inhibitors: Set::default(),
|
||||
inhibitors_present: Set::default(),
|
||||
products: Set::default(),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -4,7 +4,7 @@ use std::hash::Hash;
|
||||
use std::rc::Rc;
|
||||
|
||||
use super::reaction::Reaction;
|
||||
use super::set::Set;
|
||||
use super::set::{Set, BasicSet};
|
||||
use super::translator::{IdType, Translator, PrintableWithTranslator, Formatter};
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||
@ -61,7 +61,7 @@ impl Process {
|
||||
/// returns all elements used
|
||||
pub fn all_elements(&self) -> Set {
|
||||
let mut queue = VecDeque::from([self]);
|
||||
let mut elements = Set::new();
|
||||
let mut elements = Set::default();
|
||||
|
||||
while let Some(el) = queue.pop_front() {
|
||||
match el {
|
||||
|
||||
@ -6,75 +6,64 @@
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::hash::Hash;
|
||||
|
||||
use super::set::Set;
|
||||
use super::set::{BasicSet, ExtensionsSet, Set};
|
||||
use super::translator::{Translator, PrintableWithTranslator, Formatter};
|
||||
|
||||
/// Basic structure for a reaction.
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq, Hash)]
|
||||
pub struct Reaction {
|
||||
pub reactants: Set,
|
||||
pub inhibitors: Set,
|
||||
pub products: Set,
|
||||
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>;
|
||||
}
|
||||
|
||||
impl Reaction {
|
||||
pub fn new() -> Self {
|
||||
Reaction {
|
||||
reactants: Set::new(),
|
||||
inhibitors: Set::new(),
|
||||
products: Set::new(),
|
||||
}
|
||||
}
|
||||
pub trait ExtensionReaction<S: BasicSet> {
|
||||
fn compute_all(reactions: &[Self], state: &S) -> S
|
||||
where Self: Sized;
|
||||
|
||||
pub fn from(reactants: Set, inhibitors: Set, products: Set) -> Self {
|
||||
Reaction {
|
||||
reactants,
|
||||
inhibitors,
|
||||
products,
|
||||
}
|
||||
}
|
||||
fn find_loop(reactions: &[Self], entities: S, q: &S) -> (Vec<S>, Vec<S>)
|
||||
where Self: Sized;
|
||||
|
||||
/// 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)
|
||||
}
|
||||
fn find_only_loop(reactions: &[Self], entities: S, q: &S) -> Vec<S>
|
||||
where Self: Sized;
|
||||
|
||||
/// 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
|
||||
}
|
||||
}
|
||||
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
|
||||
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));
|
||||
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.
|
||||
pub fn find_loop(
|
||||
rs: &[Self],
|
||||
entities: Set,
|
||||
q: &Set
|
||||
) -> (Vec<Set>, Vec<Set>) {
|
||||
fn find_loop(
|
||||
reactions: &[Self],
|
||||
entities: S,
|
||||
q: &S
|
||||
) -> (Vec<S>, Vec<S>) {
|
||||
let mut entities = entities;
|
||||
let mut trace = vec![];
|
||||
loop {
|
||||
@ -82,7 +71,7 @@ impl Reaction {
|
||||
return (prefix.to_vec(), hoop.to_vec());
|
||||
} else {
|
||||
let t = entities.union(q);
|
||||
let products = Self::compute_all(&t, rs);
|
||||
let products = Self::compute_all(reactions, &t);
|
||||
trace.push(entities.clone());
|
||||
entities = products;
|
||||
}
|
||||
@ -91,11 +80,11 @@ impl Reaction {
|
||||
|
||||
|
||||
/// Finds the loops by simulating the system.
|
||||
pub fn find_only_loop(
|
||||
rs: &[Self],
|
||||
entities: Set,
|
||||
q: &Set
|
||||
) -> Vec<Set> {
|
||||
fn find_only_loop(
|
||||
reactions: &[Self],
|
||||
entities: S,
|
||||
q: &S
|
||||
) -> Vec<S> {
|
||||
let mut entities = entities;
|
||||
let mut trace = vec![];
|
||||
loop {
|
||||
@ -103,7 +92,7 @@ impl Reaction {
|
||||
return hoop.to_vec();
|
||||
} else {
|
||||
let t = entities.union(q);
|
||||
let products = Self::compute_all(&t, rs);
|
||||
let products = Self::compute_all(reactions, &t);
|
||||
trace.push(entities.clone());
|
||||
entities = products;
|
||||
}
|
||||
@ -112,11 +101,11 @@ impl Reaction {
|
||||
|
||||
|
||||
/// 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>) {
|
||||
fn find_prefix_len_loop(
|
||||
reactions: &[Self],
|
||||
entities: S,
|
||||
q: &S
|
||||
) -> (usize, Vec<S>) {
|
||||
let mut entities = entities;
|
||||
let mut trace = vec![];
|
||||
loop {
|
||||
@ -124,7 +113,7 @@ impl Reaction {
|
||||
return (prefix.len(), hoop.to_vec());
|
||||
} else {
|
||||
let t = entities.union(q);
|
||||
let products = Self::compute_all(&t, rs);
|
||||
let products = Self::compute_all(reactions, &t);
|
||||
trace.push(entities.clone());
|
||||
entities = products;
|
||||
}
|
||||
@ -133,22 +122,62 @@ impl Reaction {
|
||||
|
||||
|
||||
/// see loop/5
|
||||
pub fn lollipops_only_loop_decomposed_q(
|
||||
reaction_rules: &[Self],
|
||||
q: &Set,
|
||||
available_entities: &Set,
|
||||
) -> Vec<Set> {
|
||||
fn lollipops_only_loop_decomposed_q(
|
||||
reactions: &[Self],
|
||||
entities: &S,
|
||||
q: &S,
|
||||
) -> Vec<S> {
|
||||
let find_loop_fn =
|
||||
|q| Reaction::find_only_loop(reaction_rules,
|
||||
available_entities.clone(),
|
||||
|q| Self::find_only_loop(reactions,
|
||||
entities.clone(),
|
||||
q);
|
||||
find_loop_fn(q)
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for Reaction {
|
||||
fn default() -> Self {
|
||||
Reaction::new()
|
||||
|
||||
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
/// Basic structure for a reaction.
|
||||
#[derive(Clone, Debug, Default, Serialize, Deserialize, PartialEq, Eq, Hash)]
|
||||
pub struct Reaction {
|
||||
pub reactants: Set,
|
||||
pub inhibitors: 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 {
|
||||
pub fn from(reactants: Set, inhibitors: Set, products: Set) -> Self {
|
||||
Reaction {
|
||||
reactants,
|
||||
inhibitors,
|
||||
products,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -5,108 +5,48 @@ use std::fmt;
|
||||
|
||||
use super::translator::{IdType, Translator, PrintableWithTranslator};
|
||||
|
||||
/// Basic set of entities.
|
||||
#[derive(Clone, Debug, PartialOrd, Eq, Ord, Serialize, Deserialize)]
|
||||
pub struct Set {
|
||||
pub identifiers: BTreeSet<IdType>,
|
||||
|
||||
/// Basic trait for all Set implementations.
|
||||
/// Implement IntoIterator for &Self to have .iter() (not required directly by
|
||||
/// 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 {
|
||||
fn from(arr: [IdType; N]) -> Self {
|
||||
Set {
|
||||
identifiers: BTreeSet::from(arr),
|
||||
}
|
||||
}
|
||||
pub trait ExtensionsSet {
|
||||
fn iter(
|
||||
&self
|
||||
) -> <&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 {
|
||||
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),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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()
|
||||
/// Implementations for all sets.
|
||||
impl<T: BasicSet> ExtensionsSet for T {
|
||||
fn iter(&self) -> <&T as IntoIterator>::IntoIter
|
||||
where for<'b> &'b T: IntoIterator {
|
||||
self.into_iter()
|
||||
}
|
||||
|
||||
/// Returns the prefix and the loop from a trace.
|
||||
pub fn split<'a>(
|
||||
fn split<'a>(
|
||||
&'a self,
|
||||
trace: &'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 {
|
||||
fn print(
|
||||
&self,
|
||||
@ -164,3 +173,28 @@ impl PrintableWithTranslator for Set {
|
||||
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::label::Label;
|
||||
use super::process::Process;
|
||||
use super::reaction::Reaction;
|
||||
use super::set::Set;
|
||||
use super::reaction::{Reaction, ExtensionReaction};
|
||||
use super::set::{BasicSet, Set};
|
||||
use super::transitions::TransitionsIterator;
|
||||
use super::translator::{IdType, Translator, PrintableWithTranslator, Formatter};
|
||||
|
||||
@ -27,7 +27,7 @@ impl System {
|
||||
pub fn new() -> System {
|
||||
System {
|
||||
delta: Rc::new(Environment::new()),
|
||||
available_entities: Set::new(),
|
||||
available_entities: Set::default(),
|
||||
context_process: Process::Nill,
|
||||
reaction_rules: Rc::new(vec![]),
|
||||
}
|
||||
@ -405,7 +405,7 @@ impl System {
|
||||
let reactants = self
|
||||
.reaction_rules
|
||||
.iter()
|
||||
.fold(Set::new(), |acc, new| acc.union(&new.reactants));
|
||||
.fold(Set::default(), |acc, new| acc.union(&new.reactants));
|
||||
result.push_str(&format!(
|
||||
"The reactants are {}:\n{}\n",
|
||||
reactants.len(),
|
||||
@ -415,7 +415,7 @@ impl System {
|
||||
let inhibitors = self
|
||||
.reaction_rules
|
||||
.iter()
|
||||
.fold(Set::new(), |acc, new| acc.union(&new.inhibitors));
|
||||
.fold(Set::default(), |acc, new| acc.union(&new.inhibitors));
|
||||
result.push_str(&format!(
|
||||
"The inhibitors are {}:\n{}\n",
|
||||
inhibitors.len(),
|
||||
@ -425,7 +425,7 @@ impl System {
|
||||
let products = self
|
||||
.reaction_rules
|
||||
.iter()
|
||||
.fold(Set::new(), |acc, new| acc.union(&new.products));
|
||||
.fold(Set::default(), |acc, new| acc.union(&new.products));
|
||||
result.push_str(&format!(
|
||||
"The products are {}:\n{}\n",
|
||||
products.len(),
|
||||
|
||||
@ -53,7 +53,7 @@ fn traces_1() {
|
||||
inhibitors: Set::from([1]),
|
||||
products: Set::from([1]), },
|
||||
Reaction { reactants: Set::from([2]),
|
||||
inhibitors: Set::new(),
|
||||
inhibitors: Set::default(),
|
||||
products: Set::from([4]), },
|
||||
])
|
||||
};
|
||||
@ -113,7 +113,7 @@ fn traces_empty_env() {
|
||||
inhibitors: Set::from([1]),
|
||||
products: Set::from([1]), },
|
||||
Reaction { reactants: Set::from([2]),
|
||||
inhibitors: Set::new(),
|
||||
inhibitors: Set::default(),
|
||||
products: Set::from([4]), },
|
||||
])
|
||||
};
|
||||
|
||||
@ -4,8 +4,9 @@ use std::rc::Rc;
|
||||
|
||||
use super::label::Label;
|
||||
use super::process::Process;
|
||||
use super::set::Set;
|
||||
use super::set::{BasicSet, Set};
|
||||
use super::system::System;
|
||||
use super::reaction::BasicReaction;
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct TransitionsIterator<'a> {
|
||||
@ -44,11 +45,11 @@ impl<'a> Iterator for TransitionsIterator<'a> {
|
||||
) =
|
||||
self.system.reaction_rules.iter().fold(
|
||||
(
|
||||
Set::new(), // reactants
|
||||
Set::new(), // reactants_absent
|
||||
Set::new(), // inhibitors
|
||||
Set::new(), // inhibitors_present
|
||||
Set::new(), // products
|
||||
Set::default(), // reactants
|
||||
Set::default(), // reactants_absent
|
||||
Set::default(), // inhibitors
|
||||
Set::default(), // inhibitors_present
|
||||
Set::default(), // products
|
||||
),
|
||||
|acc, reaction| {
|
||||
if reaction.enabled(&t) {
|
||||
|
||||
Reference in New Issue
Block a user