Converting to library and commenting code
refactoring and removing useless functions
This commit is contained in:
@ -11,7 +11,7 @@ use std::io;
|
||||
use std::io::prelude::*;
|
||||
use std::rc::Rc;
|
||||
|
||||
// grammar is defined in main.rs, calling lalrpop_mod! twice, generates twice
|
||||
// grammar is defined in lib.rs, calling lalrpop_mod! twice, generates twice
|
||||
// the code
|
||||
use super::grammar;
|
||||
|
||||
|
||||
7
src/lib.rs
Normal file
7
src/lib.rs
Normal file
@ -0,0 +1,7 @@
|
||||
pub mod rsprocess;
|
||||
pub mod examples;
|
||||
|
||||
lalrpop_util::lalrpop_mod!(
|
||||
#[allow(clippy::uninlined_format_args)] pub grammar, // name of module
|
||||
"/rsprocess/grammar.rs" // location of parser
|
||||
);
|
||||
27
src/main.rs
27
src/main.rs
@ -1,33 +1,10 @@
|
||||
mod examples;
|
||||
mod rsprocess;
|
||||
|
||||
lalrpop_util::lalrpop_mod!(
|
||||
#[allow(clippy::uninlined_format_args)] pub grammar, // name of module
|
||||
"/rsprocess/grammar.rs" // location of parser
|
||||
);
|
||||
|
||||
fn main() -> std::io::Result<()> {
|
||||
// let now = std::time::Instant::now();
|
||||
// std::thread::sleep(std::time::Duration::new(2, 0));
|
||||
// println!("{}", now.elapsed().as_micros());
|
||||
|
||||
// examples::stats()?;
|
||||
reactionsystems::examples::digraph()?;
|
||||
|
||||
// examples::freq()?;
|
||||
|
||||
// examples::hoop()?;
|
||||
|
||||
// examples::target()?;
|
||||
|
||||
// examples::run()?;
|
||||
|
||||
// examples::limit_freq()?;
|
||||
|
||||
// examples::fast_freq()?;
|
||||
|
||||
examples::digraph()?;
|
||||
|
||||
examples::adversarial()?;
|
||||
reactionsystems::examples::adversarial()?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@ -4,13 +4,11 @@
|
||||
//! Reaction System (RS) Framework.
|
||||
//! The data is held in RSset or RSreaction, in the latter the reagents,
|
||||
//! inhibitors and products are held.
|
||||
#![allow(dead_code)]
|
||||
|
||||
use super::structure::{RSreaction, RSset};
|
||||
|
||||
/// Computes the result of a single reaction (if enabled returns the products)
|
||||
/// otherwise returns None.
|
||||
// see result
|
||||
/// see result
|
||||
pub fn compute_step<'a>(
|
||||
current_state: &'a RSset,
|
||||
reaction: &'a RSreaction
|
||||
@ -24,21 +22,13 @@ pub fn compute_step<'a>(
|
||||
|
||||
/// Computes the result of a series of reactions. Returns the union of all
|
||||
/// products.
|
||||
// see result
|
||||
/// see result
|
||||
pub fn compute_all<'a>(
|
||||
current_state: &'a RSset,
|
||||
reactions: Vec<&'a RSreaction>
|
||||
) -> RSset {
|
||||
reactions.iter().fold(RSset::new(), |acc, r| {
|
||||
acc.union_option(compute_step(current_state, r))
|
||||
})
|
||||
}
|
||||
|
||||
pub fn compute_all_owned<'a>(
|
||||
current_state: &'a RSset,
|
||||
reactions: &'a [RSreaction]
|
||||
) -> RSset {
|
||||
reactions.iter().fold(RSset::new(), |acc, r| {
|
||||
acc.union_option(compute_step(current_state, r))
|
||||
reactions.iter().fold(RSset::new(), |mut acc, r| {
|
||||
acc.union_option(compute_step(current_state, r));
|
||||
acc
|
||||
})
|
||||
}
|
||||
|
||||
@ -1,5 +1,3 @@
|
||||
#![allow(dead_code)]
|
||||
|
||||
use super::perpetual::{
|
||||
lollipops_decomposed_named, lollipops_prefix_len_loop_decomposed,
|
||||
lollipops_prefix_len_loop_decomposed_named,
|
||||
@ -9,7 +7,13 @@ use super::translator::IdType;
|
||||
use std::cmp;
|
||||
use std::collections::HashSet;
|
||||
|
||||
// see confluent, confluents
|
||||
|
||||
/// Two set of entities E1 and E2 are confluent w.r.t. the perpetual context
|
||||
/// delta iff they reach the same loop.
|
||||
/// confluent checks if all the sets of entities in ```entities``` are confluent
|
||||
/// and if so returns the maximal length of prefixes traversed to reached the
|
||||
/// loop, its dimension (length) and the loop.
|
||||
/// see confluent, confluents
|
||||
pub fn confluent(
|
||||
delta: &RSenvironment,
|
||||
reaction_rules: &[RSreaction],
|
||||
@ -27,7 +31,6 @@ pub fn confluent(
|
||||
lollipops_prefix_len_loop_decomposed(delta,
|
||||
reaction_rules,
|
||||
available_entities);
|
||||
// FIXME we take just the first? do we compare all?
|
||||
let (prefix_len, new_hoop) = all_loops.first()?;
|
||||
|
||||
if new_hoop.len() != dimension || !hoop.contains(new_hoop.first()?) {
|
||||
@ -38,7 +41,12 @@ pub fn confluent(
|
||||
Some((max_distance, dimension, hoop))
|
||||
}
|
||||
|
||||
// see confluent, confluents
|
||||
/// Two set of entities E1 and E2 are confluent w.r.t. the perpetual context Q
|
||||
/// iff they reach the same loop.
|
||||
/// The predicate confluent(Rs,Q,Es,Loop,Distance,Dimension) checks if all the
|
||||
/// sets of entities in Es are confluent and if so returns the Loop, the maximal
|
||||
/// length of prefixes traversed to reached the loop and its dimension (length).
|
||||
/// see confluent, confluents
|
||||
pub fn confluent_named(
|
||||
delta: &RSenvironment,
|
||||
reaction_rules: &[RSreaction],
|
||||
@ -72,7 +80,9 @@ pub fn confluent_named(
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
// see invariant
|
||||
/// invariant_named checks if all the sets of entities in ```entities``` are
|
||||
/// confluent and if so returns the set of all traversed states, together with the loop.
|
||||
/// see invariant
|
||||
pub fn invariant_named(
|
||||
delta: &RSenvironment,
|
||||
reaction_rules: &[RSreaction],
|
||||
@ -113,7 +123,18 @@ pub fn invariant_named(
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
// see loop_confluent
|
||||
/// Suppose the context has the form
|
||||
/// Q1. ... Q1.Q2. ... Q2. ... Qn. ... Qn. ...
|
||||
/// and that each context Q1, Q2, ... , Q(n-1) is provided for a large number
|
||||
/// of times, enough to stabilize the system in a loop (while Qn is provided
|
||||
/// infinitely many times). Then it can be the case that when the context
|
||||
/// switches from Qi to Q(i+1), no matter what is the current state of the loop
|
||||
/// for Qi at the moment of the switching, the system will stabilize in the same
|
||||
/// loop for Q(i+1): if this is the case the system is called "loop confluent".
|
||||
/// loop_confluent_named checks this property over the list of contexts
|
||||
/// [Q1,Q2,...,Qn] and returns the lists of Loops, Distances and Dimensions for
|
||||
/// all Qi's.
|
||||
/// see loop_confluent
|
||||
pub fn loop_confluent_named(
|
||||
deltas: &[RSenvironment],
|
||||
reaction_rules: &[RSreaction],
|
||||
@ -126,7 +147,12 @@ pub fn loop_confluent_named(
|
||||
.collect::<Option<Vec<_>>>()
|
||||
}
|
||||
|
||||
// see strong_confluent
|
||||
/// "strong confluence" requires loop confluence and additionally check
|
||||
/// that even if the context is switched BEFORE REACHING THE LOOP for Qi
|
||||
/// the traversed states are still confluent for Q(i+1)
|
||||
/// IMPORTANT: this notion of confluence assumes each context can be executed 0
|
||||
/// or more times
|
||||
/// see strong_confluent
|
||||
#[allow(clippy::type_complexity)]
|
||||
pub fn strong_confluent_named(
|
||||
deltas: &[RSenvironment],
|
||||
@ -146,3 +172,5 @@ pub fn strong_confluent_named(
|
||||
})
|
||||
.collect::<Option<Vec<_>>>()
|
||||
}
|
||||
|
||||
// TODO: weak confluence
|
||||
|
||||
@ -1,5 +1,3 @@
|
||||
#![allow(dead_code)]
|
||||
|
||||
use crate::rsprocess::perpetual::lollipops_only_loop_decomposed_q;
|
||||
use std::collections::HashMap;
|
||||
|
||||
@ -8,6 +6,8 @@ use super::structure::{RSreaction, RSset, RSsystem};
|
||||
use super::transitions::run_separated;
|
||||
use super::translator::IdType;
|
||||
|
||||
/// structure that holds the frequency of elements of a run or multiple runs,
|
||||
/// weighted
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Frequency {
|
||||
pub frequency_map: HashMap<IdType, Vec<u32>>,
|
||||
@ -56,8 +56,9 @@ impl Default for Frequency {
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
// see naiveFreq, assume the system is finite, calculate the frequency of
|
||||
// each symbol in all traversed states
|
||||
/// assume the system is finite, calculate the frequency of each symbol in all
|
||||
/// traversed states
|
||||
/// see naiveFreq
|
||||
pub fn naive_frequency(system: &RSsystem) -> Result<Frequency, String> {
|
||||
let ect = run_separated(system)?;
|
||||
let es = ect.iter().map(|(e, _, _)| e).collect::<Vec<_>>();
|
||||
@ -70,8 +71,9 @@ pub fn naive_frequency(system: &RSsystem) -> Result<Frequency, String> {
|
||||
Ok(freq)
|
||||
}
|
||||
|
||||
// see loopFreq, assume the system stabilizes in a loop, calculate the frequency
|
||||
// of each symbol in all states of the loop
|
||||
/// assume the system stabilizes in a loop, calculate the frequency of each
|
||||
/// symbol in all states of the loop
|
||||
/// see loopFreq
|
||||
pub fn loop_frequency(system: &RSsystem, symb: IdType) -> Frequency {
|
||||
let mut freq = Frequency::new();
|
||||
freq.append_weight(1);
|
||||
@ -82,8 +84,9 @@ pub fn loop_frequency(system: &RSsystem, symb: IdType) -> Frequency {
|
||||
freq
|
||||
}
|
||||
|
||||
// see limitFreq, q[i] is given enough times such that the stabilizes in a loop,
|
||||
// calculate the frequency of the symbols in any state in the last loop
|
||||
/// ```q[i]``` is given enough times such that the stabilizes in a loop, calculate the
|
||||
/// frequency of the symbols in any state in the last loop
|
||||
/// see limitFreq
|
||||
pub fn limit_frequency(
|
||||
q: &[RSset],
|
||||
reaction_rules: &[RSreaction],
|
||||
@ -109,8 +112,9 @@ pub fn limit_frequency(
|
||||
Some(freq)
|
||||
}
|
||||
|
||||
// see fastFreq, q[i] is given enough times such that the stabilizes in a loop,
|
||||
// calculate the frequency of the symbols in any state in any loop, weighted.
|
||||
/// ```q[i]``` is given enough times such that the stabilizes in a loop, calculate the
|
||||
/// frequency of the symbols in any state in any loop, weighted.
|
||||
/// see fastFreq
|
||||
pub fn fast_frequency(
|
||||
q: &[RSset],
|
||||
reaction_rules: &[RSreaction],
|
||||
|
||||
@ -1,5 +1,3 @@
|
||||
#![allow(dead_code)]
|
||||
|
||||
use petgraph::{Graph, Directed};
|
||||
use std::collections::HashMap;
|
||||
use super::structure::{RSlabel, RSsystem, RSset, RSprocess};
|
||||
@ -9,6 +7,7 @@ use std::rc::Rc;
|
||||
|
||||
type RSgraph = Graph<RSsystem, RSlabel, Directed, u32>;
|
||||
|
||||
/// creates a graph starting from a system as root node
|
||||
pub fn digraph(
|
||||
system: RSsystem
|
||||
) -> Result<RSgraph, String> {
|
||||
@ -27,10 +26,7 @@ pub fn digraph(
|
||||
current = stack.pop().unwrap();
|
||||
let current_node = *association.get(¤t).unwrap();
|
||||
|
||||
// cycle through all next nodes
|
||||
let tr = TransitionsIterator::from(¤t)?;
|
||||
|
||||
for (label, next) in tr {
|
||||
for (label, next) in TransitionsIterator::from(¤t)? {
|
||||
// if not already visited
|
||||
let next_node = association.entry(next.clone()).or_insert_with(|| {
|
||||
stack.push(next.clone());
|
||||
@ -49,6 +45,7 @@ pub fn digraph(
|
||||
|
||||
// Nodes -----------------------------------------------------------------------
|
||||
|
||||
/// Helper structure that specifies what information to display for nodes.
|
||||
pub enum GraphMapNodes {
|
||||
Hide,
|
||||
Entities,
|
||||
@ -57,6 +54,8 @@ pub enum GraphMapNodes {
|
||||
}
|
||||
|
||||
type GraphMapNodesFnTy = dyn Fn(petgraph::prelude::NodeIndex, &RSsystem) -> String;
|
||||
/// Helper structure that holds a formatting function from node as RSsystem to
|
||||
/// string
|
||||
pub struct GraphMapNodesTy {
|
||||
function: Box<GraphMapNodesFnTy>
|
||||
}
|
||||
@ -131,6 +130,7 @@ impl From<GraphMapNodesTy> for Box<GraphMapNodesFnTy> {
|
||||
|
||||
// Edges -----------------------------------------------------------------------
|
||||
|
||||
/// Helper structure that specifies what information to display for edges
|
||||
pub enum GraphMapEdges {
|
||||
Hide,
|
||||
Products,
|
||||
@ -150,6 +150,8 @@ pub enum GraphMapEdges {
|
||||
}
|
||||
|
||||
type GraphMapEdgesFnTy = dyn Fn(petgraph::prelude::EdgeIndex, &RSlabel) -> String;
|
||||
/// Helper structure that holds a formatting function from node as RSsystem to
|
||||
/// string
|
||||
pub struct GraphMapEdgesTy {
|
||||
function: Box<GraphMapEdgesFnTy>
|
||||
}
|
||||
|
||||
@ -1,10 +1,8 @@
|
||||
#![allow(dead_code)]
|
||||
|
||||
use super::classical::compute_all_owned;
|
||||
use super::classical::compute_all;
|
||||
use super::structure::{RSenvironment, RSprocess, RSreaction, RSset, RSsystem};
|
||||
use super::translator::IdType;
|
||||
|
||||
// returns the prefix and the loop from a trace
|
||||
/// returns the prefix and the loop from a trace
|
||||
fn split<'a>(
|
||||
set: &'a RSset,
|
||||
trace: &'a [RSset]
|
||||
@ -13,7 +11,7 @@ fn split<'a>(
|
||||
position.map(|pos| trace.split_at(pos))
|
||||
}
|
||||
|
||||
// finds the loops by simulating the system
|
||||
/// finds the loops by simulating the system
|
||||
fn find_loop(
|
||||
rs: &[RSreaction],
|
||||
entities: RSset,
|
||||
@ -26,14 +24,14 @@ fn find_loop(
|
||||
return (prefix.to_vec(), hoop.to_vec());
|
||||
} else {
|
||||
let t = entities.union(q);
|
||||
let products = compute_all_owned(&t, rs);
|
||||
let products = compute_all(&t, rs);
|
||||
trace.push(entities.clone());
|
||||
entities = products;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// finds the loops by simulating the system
|
||||
/// finds the loops by simulating the system
|
||||
fn find_only_loop(
|
||||
rs: &[RSreaction],
|
||||
entities: RSset,
|
||||
@ -46,14 +44,14 @@ fn find_only_loop(
|
||||
return hoop.to_vec();
|
||||
} else {
|
||||
let t = entities.union(q);
|
||||
let products = compute_all_owned(&t, rs);
|
||||
let products = compute_all(&t, rs);
|
||||
trace.push(entities.clone());
|
||||
entities = products;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// finds the loops and the length of the prefix by simulating the system
|
||||
/// finds the loops and the length of the prefix by simulating the system
|
||||
fn find_prefix_len_loop(
|
||||
rs: &[RSreaction],
|
||||
entities: RSset,
|
||||
@ -66,7 +64,7 @@ fn find_prefix_len_loop(
|
||||
return (prefix.len(), hoop.to_vec());
|
||||
} else {
|
||||
let t = entities.union(q);
|
||||
let products = compute_all_owned(&t, rs);
|
||||
let products = compute_all(&t, rs);
|
||||
trace.push(entities.clone());
|
||||
entities = products;
|
||||
}
|
||||
@ -75,8 +73,8 @@ fn find_prefix_len_loop(
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
// finds only the rules X = pre(Q, rec(X)), but not only x = pre(Q, rec(x))
|
||||
// to use in filter_map
|
||||
/// finds only the rules X = pre(Q, rec(X)), but not only x = pre(Q, rec(x))
|
||||
/// to use in filter_map
|
||||
fn filter_delta<'a>(x: (&IdType, &'a RSprocess)) -> Option<&'a RSset> {
|
||||
use super::structure::RSprocess::*;
|
||||
let (id, rest) = x;
|
||||
@ -95,7 +93,14 @@ fn filter_delta<'a>(x: (&IdType, &'a RSprocess)) -> Option<&'a RSset> {
|
||||
None
|
||||
}
|
||||
|
||||
// see lollipop
|
||||
/// A special case of systems is when the context recursively provides always
|
||||
/// the same set of entities. The corresponding computation is infinite. It
|
||||
/// consists of a finite sequence of states followed by a looping sequence.
|
||||
/// IMPORTANT: We return all loops for all X = Q.X, by varing X. The set of
|
||||
/// reactions Rs and the context x are constant. Each state of the computation
|
||||
/// is distinguished by the current entities E. Under these assumptions, the
|
||||
/// predicate lollipop finds the Prefixes and the Loops sequences of entities.
|
||||
/// see lollipop
|
||||
pub fn lollipops_decomposed(
|
||||
delta: &RSenvironment,
|
||||
reaction_rules: &[RSreaction],
|
||||
@ -112,7 +117,14 @@ pub fn lollipops_decomposed(
|
||||
filtered.map(find_loop_fn).collect::<Vec<_>>()
|
||||
}
|
||||
|
||||
// see lollipop
|
||||
/// A special case of systems is when the context recursively provides always
|
||||
/// the same set of entities. The corresponding computation is infinite. It
|
||||
/// consists of a finite sequence of states followed by a looping sequence.
|
||||
/// IMPORTANT: We return all loops for all X = Q.X, by varing X. The set of
|
||||
/// reactions Rs and the context x are constant. Each state of the computation
|
||||
/// is distinguished by the current entities E. Under these assumptions, the
|
||||
/// predicate lollipop finds the Prefixes and the Loops sequences of entities.
|
||||
/// see lollipop
|
||||
pub fn lollipops(system: RSsystem) -> Vec<(Vec<RSset>, Vec<RSset>)> {
|
||||
lollipops_decomposed(
|
||||
&system.delta,
|
||||
@ -121,10 +133,9 @@ pub fn lollipops(system: RSsystem) -> Vec<(Vec<RSset>, Vec<RSset>)> {
|
||||
)
|
||||
}
|
||||
|
||||
// see loop
|
||||
/// Only returns the loop part of the lollipop, returns for all X, where X = Q.X
|
||||
/// see loop
|
||||
pub fn lollipops_only_loop(system: RSsystem) -> Vec<Vec<RSset>> {
|
||||
// FIXME: i think we are only interested in "x", not all symbols that
|
||||
// satisfy X = pre(Q, rec(X))
|
||||
let filtered = system.delta.iter().filter_map(filter_delta);
|
||||
|
||||
let find_loop_fn = |q| {
|
||||
@ -143,8 +154,6 @@ pub fn lollipops_prefix_len_loop_decomposed(
|
||||
reaction_rules: &[RSreaction],
|
||||
available_entities: &RSset,
|
||||
) -> Vec<(usize, Vec<RSset>)> {
|
||||
// FIXME: i think we are only interested in "x", not all symbols that
|
||||
// satisfy X = pre(Q, rec(X))
|
||||
let filtered = delta.iter().filter_map(filter_delta);
|
||||
|
||||
let find_loop_fn = |q| find_prefix_len_loop(reaction_rules,
|
||||
@ -154,14 +163,12 @@ pub fn lollipops_prefix_len_loop_decomposed(
|
||||
filtered.map(find_loop_fn).collect::<Vec<_>>()
|
||||
}
|
||||
|
||||
// see loop
|
||||
/// see loop
|
||||
pub fn lollipops_only_loop_decomposed(
|
||||
delta: &RSenvironment,
|
||||
reaction_rules: &[RSreaction],
|
||||
available_entities: &RSset,
|
||||
) -> Vec<Vec<RSset>> {
|
||||
// FIXME: i think we are only interested in "x", not all symbols that
|
||||
// satisfy X = pre(Q, rec(X))
|
||||
let filtered = delta.iter().filter_map(filter_delta);
|
||||
|
||||
let find_loop_fn = |q| find_only_loop(reaction_rules,
|
||||
@ -175,8 +182,8 @@ pub fn lollipops_only_loop_decomposed(
|
||||
// Named versions
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
// finds only the rules symb = pre(Q, rec(symb)), get symb from a translator
|
||||
// to use in filter_map
|
||||
/// finds only the rules symb = pre(Q, rec(symb)), get symb from a translator
|
||||
/// to use in filter_map
|
||||
fn filter_delta_named<'a>(
|
||||
x: (&IdType, &'a RSprocess),
|
||||
symb: &IdType
|
||||
@ -201,7 +208,14 @@ fn filter_delta_named<'a>(
|
||||
None
|
||||
}
|
||||
|
||||
// see lollipop
|
||||
/// A special case of systems is when the context recursively provides always
|
||||
/// the same set of entities. The corresponding computation is infinite. It
|
||||
/// consists of a finite sequence of states followed by a looping sequence.
|
||||
/// IMPORTANT: We return all loops for all X = Q.X, by varing X. The set of
|
||||
/// reactions Rs and the context x are constant. Each state of the computation
|
||||
/// is distinguished by the current entities E. Under these assumptions, the
|
||||
/// predicate lollipop finds the Prefixes and the Loops sequences of entities.
|
||||
/// see lollipop
|
||||
pub fn lollipops_decomposed_named(
|
||||
delta: &RSenvironment,
|
||||
reaction_rules: &[RSreaction],
|
||||
@ -220,7 +234,14 @@ pub fn lollipops_decomposed_named(
|
||||
filtered.map(find_loop_fn)
|
||||
}
|
||||
|
||||
// see lollipop
|
||||
/// A special case of systems is when the context recursively provides always
|
||||
/// the same set of entities. The corresponding computation is infinite. It
|
||||
/// consists of a finite sequence of states followed by a looping sequence.
|
||||
/// IMPORTANT: We return all loops for all X = Q.X, by varing X. The set of
|
||||
/// reactions Rs and the context x are constant. Each state of the computation
|
||||
/// is distinguished by the current entities E. Under these assumptions, the
|
||||
/// predicate lollipop finds the Prefixes and the Loops sequences of entities.
|
||||
/// see lollipop
|
||||
pub fn lollipops_named(
|
||||
system: RSsystem,
|
||||
symb: IdType
|
||||
@ -233,7 +254,8 @@ pub fn lollipops_named(
|
||||
)
|
||||
}
|
||||
|
||||
// see loop
|
||||
/// Only returns the loop part of the lollipop, returns for all X, where X = Q.X
|
||||
/// see loop
|
||||
pub fn lollipops_only_loop_named(
|
||||
system: RSsystem,
|
||||
symb: IdType
|
||||
@ -273,7 +295,7 @@ pub fn lollipops_prefix_len_loop_decomposed_named(
|
||||
filtered.map(find_loop_fn)
|
||||
}
|
||||
|
||||
// see loop
|
||||
/// see loop
|
||||
pub fn lollipops_only_loop_decomposed_named(
|
||||
delta: &RSenvironment,
|
||||
reaction_rules: &[RSreaction],
|
||||
@ -292,7 +314,7 @@ pub fn lollipops_only_loop_decomposed_named(
|
||||
filtered.map(find_loop_fn)
|
||||
}
|
||||
|
||||
// see loop/5
|
||||
/// see loop/5
|
||||
pub fn lollipops_only_loop_decomposed_q(
|
||||
q: &RSset,
|
||||
reaction_rules: &[RSreaction],
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
//! Slightly modified Simple graphviz dot file format output.
|
||||
//! See petgraph::dot::mod.
|
||||
#![allow(dead_code)]
|
||||
|
||||
// use alloc::string::String;
|
||||
use core::fmt::{self, Display, Write};
|
||||
|
||||
@ -1,10 +1,10 @@
|
||||
#![allow(dead_code)]
|
||||
|
||||
use super::structure::RSset;
|
||||
use super::structure::RSsystem;
|
||||
use super::translator;
|
||||
use super::translator::Translator;
|
||||
|
||||
/// Returns statistics about the system
|
||||
/// see main_do(stat,MissingE)
|
||||
#[allow(non_snake_case)]
|
||||
pub fn of_RSsystem<'a>(translator: &'a Translator, system: &'a RSsystem) -> String {
|
||||
let mut result: String = "Statistics:\n".into();
|
||||
|
||||
@ -1,5 +1,3 @@
|
||||
#![allow(dead_code)]
|
||||
|
||||
use super::translator::IdType;
|
||||
use std::collections::{BTreeSet, HashMap, VecDeque};
|
||||
use std::hash::Hash;
|
||||
@ -8,6 +6,7 @@ use std::rc::Rc;
|
||||
// -----------------------------------------------------------------------------
|
||||
// RSset
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||
pub struct RSset {
|
||||
pub identifiers: BTreeSet<IdType>,
|
||||
@ -52,18 +51,16 @@ impl RSset {
|
||||
self.identifiers.is_disjoint(&b.identifiers)
|
||||
}
|
||||
|
||||
// returns the new set a \cup b
|
||||
pub fn union(&self, b: &RSset) -> RSset {
|
||||
// TODO maybe find more efficient way without copy/clone
|
||||
let mut ret: RSset = b.clone();
|
||||
ret.identifiers.extend(self.identifiers.iter());
|
||||
ret
|
||||
}
|
||||
|
||||
pub fn union_option(&self, b: Option<&RSset>) -> RSset {
|
||||
pub fn union_option(&mut self, b: Option<&RSset>) {
|
||||
if let Some(b) = b {
|
||||
self.union(b)
|
||||
} else {
|
||||
self.clone()
|
||||
self.identifiers.extend(b.iter());
|
||||
}
|
||||
}
|
||||
|
||||
@ -78,7 +75,7 @@ impl RSset {
|
||||
RSset { identifiers: res }
|
||||
}
|
||||
|
||||
/// returns the new set a - b
|
||||
/// returns the new set a \ b
|
||||
pub fn subtraction(&self, b: &RSset) -> RSset {
|
||||
// TODO maybe find more efficient way without copy/clone
|
||||
let res: BTreeSet<_> = self
|
||||
@ -152,7 +149,8 @@ impl RSreaction {
|
||||
}
|
||||
}
|
||||
|
||||
// see enable
|
||||
/// returns true if ```current_state``` enables the reaction
|
||||
/// see enable
|
||||
pub fn enabled(&self, current_state: &RSset) -> bool {
|
||||
self.reactants.is_subset(current_state)
|
||||
&& self.inihibitors.is_disjoint(current_state)
|
||||
@ -215,6 +213,7 @@ impl RSprocess {
|
||||
}
|
||||
}
|
||||
|
||||
/// returns all elements used
|
||||
pub fn all_elements(&self) -> RSset {
|
||||
let mut queue = VecDeque::from([self]);
|
||||
let mut elements = RSset::new();
|
||||
@ -316,6 +315,12 @@ impl RSchoices {
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for RSchoices {
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
}
|
||||
}
|
||||
|
||||
impl IntoIterator for RSchoices {
|
||||
type Item = (Rc<RSset>, Rc<RSprocess>);
|
||||
type IntoIter = std::vec::IntoIter<Self::Item>;
|
||||
@ -536,6 +541,12 @@ impl RSlabel {
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for RSlabel {
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
}
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// RSassertOp
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
@ -1,4 +1,3 @@
|
||||
#![allow(dead_code)]
|
||||
use super::structure::{RSlabel, RSprocess, RSset, RSsystem};
|
||||
use super::transitions::unfold;
|
||||
use std::rc::Rc;
|
||||
@ -29,13 +28,19 @@ impl<'a> Iterator for TransitionsIterator<'a> {
|
||||
fn next(&mut self) -> Option<(RSlabel, RSsystem)> {
|
||||
let (c, k) = self.choices_iterator.next()?;
|
||||
let t = self.system.available_entities.union(c.as_ref());
|
||||
let (reactants, reactantsi, inihibitors, ireactants, products) =
|
||||
let (
|
||||
reactants,
|
||||
reactants_absent,
|
||||
inihibitors,
|
||||
inihibitors_present,
|
||||
products
|
||||
) =
|
||||
self.system.reaction_rules.iter().fold(
|
||||
(
|
||||
RSset::new(), // reactants
|
||||
RSset::new(), // reactantsi
|
||||
RSset::new(), // reactants_absent
|
||||
RSset::new(), // inihibitors
|
||||
RSset::new(), // ireactants
|
||||
RSset::new(), // inihibitors_present
|
||||
RSset::new(), // products
|
||||
),
|
||||
|acc, reaction| {
|
||||
@ -64,9 +69,9 @@ impl<'a> Iterator for TransitionsIterator<'a> {
|
||||
(*c).clone(),
|
||||
t,
|
||||
reactants,
|
||||
reactantsi,
|
||||
reactants_absent,
|
||||
inihibitors,
|
||||
ireactants,
|
||||
inihibitors_present,
|
||||
products.clone(),
|
||||
);
|
||||
let new_system = RSsystem::from(
|
||||
|
||||
@ -1,5 +1,3 @@
|
||||
#![allow(dead_code)]
|
||||
|
||||
use super::structure::{RSchoices,
|
||||
RSenvironment,
|
||||
RSlabel,
|
||||
@ -9,7 +7,10 @@ use super::structure::{RSchoices,
|
||||
use super::support_structures::TransitionsIterator;
|
||||
use std::rc::Rc;
|
||||
|
||||
// see unfold
|
||||
/// unfold returns the list of choices for the context given the process
|
||||
/// definitions environment. RSchoices is a list of context moves mapping a set
|
||||
/// of entities and the continuation
|
||||
/// see unfold
|
||||
pub fn unfold(
|
||||
environment: &RSenvironment,
|
||||
context_process: &RSprocess,
|
||||
@ -93,7 +94,7 @@ pub fn iterator_transitions<'a>(
|
||||
TransitionsIterator::from(system)
|
||||
}
|
||||
|
||||
// see oneTransition, transition, smartTransition, smartOneTransition
|
||||
/// see oneTransition, transition, smartTransition, smartOneTransition
|
||||
pub fn one_transition(
|
||||
system: &RSsystem
|
||||
) -> Result<Option<(RSlabel, RSsystem)>, String> {
|
||||
@ -101,7 +102,7 @@ pub fn one_transition(
|
||||
Ok(tr.next())
|
||||
}
|
||||
|
||||
// see allTransitions, smartAllTransitions
|
||||
/// see allTransitions, smartAllTransitions
|
||||
pub fn all_transitions(
|
||||
system: &RSsystem
|
||||
) -> Result<Vec<(RSlabel, RSsystem)>, String> {
|
||||
@ -109,7 +110,7 @@ pub fn all_transitions(
|
||||
Ok(tr.collect::<Vec<_>>())
|
||||
}
|
||||
|
||||
// see oneTarget, smartOneTarget, target, smartTarget
|
||||
/// see oneTarget, smartOneTarget, target, smartTarget
|
||||
pub fn target(
|
||||
system: &RSsystem
|
||||
) -> Result<(i64, RSset), String> {
|
||||
@ -126,7 +127,7 @@ pub fn target(
|
||||
Ok((n, current.available_entities.clone()))
|
||||
}
|
||||
|
||||
// see oneRun, run, smartOneRunEK, smartRunEK
|
||||
/// see oneRun, run, smartOneRunEK, smartRunEK
|
||||
pub fn run(system: RSsystem) -> Result<Vec<Rc<RSsystem>>, String> {
|
||||
let mut res = vec![Rc::new(system)];
|
||||
while let Some((_, next_sys)) = one_transition(res.last().unwrap())? {
|
||||
@ -135,7 +136,7 @@ pub fn run(system: RSsystem) -> Result<Vec<Rc<RSsystem>>, String> {
|
||||
Ok(res)
|
||||
}
|
||||
|
||||
// see smartOneRunECT, smartRunECT
|
||||
/// see smartOneRunECT, smartRunECT
|
||||
pub fn run_separated(
|
||||
system: &RSsystem
|
||||
) -> Result<Vec<(RSset, RSset, RSset)>, String> {
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
// translate and keeps track of strings
|
||||
//! Module for translation and keeping track of strings.
|
||||
use std::{cmp::max, collections::HashMap};
|
||||
|
||||
/// precision for printing frequencies
|
||||
static PRECISION: &usize = &2;
|
||||
|
||||
pub type IdType = u32;
|
||||
@ -29,6 +30,7 @@ impl Default for Translator {
|
||||
}
|
||||
|
||||
impl Translator {
|
||||
/// converts a string into an id
|
||||
pub fn encode(&mut self, s: impl Into<String>) -> IdType {
|
||||
let s = s.into();
|
||||
let id = *(self.strings.entry(s.clone()).or_insert({
|
||||
@ -39,6 +41,7 @@ impl Translator {
|
||||
id
|
||||
}
|
||||
|
||||
/// converts an id into the corresponding string
|
||||
pub fn decode(&self, el: IdType) -> Option<String> {
|
||||
self.reverse
|
||||
.get(&el)
|
||||
|
||||
Reference in New Issue
Block a user