formatting with rustfmt

This commit is contained in:
elvis
2025-07-01 19:22:50 +02:00
parent dcb4cbecb0
commit eba5d1266d
14 changed files with 796 additions and 639 deletions

View File

@ -1,23 +1,19 @@
use crate::rsprocess::{frequency, #![allow(dead_code)]
statistics,
transitions,
perpetual};
use crate::rsprocess::structure::RSsystem; use crate::rsprocess::structure::RSsystem;
use crate::rsprocess::translator::{Translator, WithTranslator}; use crate::rsprocess::translator::{Translator, WithTranslator};
use crate::rsprocess::{frequency, perpetual, statistics, transitions};
use std::env; use std::env;
use std::fs; use std::fs;
use std::io::prelude::*;
use std::io; use std::io;
use std::io::prelude::*;
// grammar is defined in main.rs, calling lalrpop_mod! twice, generates twice // grammar is defined in main.rs, calling lalrpop_mod! twice, generates twice
// the code // the code
use super::grammar; use super::grammar;
fn read_system( fn read_system(translator: &mut Translator, path: std::path::PathBuf) -> std::io::Result<RSsystem> {
translator: &mut Translator,
path: std::path::PathBuf
) -> std::io::Result<RSsystem> {
// we read the file with a buffer // we read the file with a buffer
let f = fs::File::open(path.clone())?; let f = fs::File::open(path.clone())?;
let mut buf_reader = io::BufReader::new(f); let mut buf_reader = io::BufReader::new(f);
@ -25,7 +21,9 @@ fn read_system(
buf_reader.read_to_string(&mut contents)?; buf_reader.read_to_string(&mut contents)?;
// parse // parse
let result = grammar::SystemParser::new().parse(translator, &contents).unwrap(); let result = grammar::SystemParser::new()
.parse(translator, &contents)
.unwrap();
Ok(result) Ok(result)
} }
@ -39,7 +37,6 @@ pub fn stats() -> std::io::Result<()> {
path = path.join("testing/first.system"); path = path.join("testing/first.system");
let system = read_system(&mut translator, path)?; let system = read_system(&mut translator, path)?;
// print statistics to screan // print statistics to screan
println!("{}", statistics::of_RSsystem(&translator, &system)); println!("{}", statistics::of_RSsystem(&translator, &system));
@ -62,13 +59,18 @@ pub fn target() -> std::io::Result<()> {
// the system needs to terminate to return // the system needs to terminate to return
let res = match transitions::target(&system) { let res = match transitions::target(&system) {
Ok(o) => o, Ok(o) => o,
Err(e) => {println!("Error computing target: {e}"); return Ok(());} Err(e) => {
println!("Error computing target: {e}");
return Ok(());
}
}; };
println!("After {} steps we arrive at state:\n{}", println!(
res.0, "After {} steps we arrive at state:\n{}",
WithTranslator::from_RSset(&translator, &res.1)); res.0,
WithTranslator::from_RSset(&translator, &res.1)
);
Ok(()) Ok(())
} }
@ -84,14 +86,17 @@ pub fn run() -> std::io::Result<()> {
// the system needs to terminate to return // the system needs to terminate to return
let res = match transitions::run_separated(&system) { let res = match transitions::run_separated(&system) {
Ok(o) => o, Ok(o) => o,
Err(e) => {println!("Error computing target: {e}"); return Ok(());} Err(e) => {
println!("Error computing target: {e}");
return Ok(());
}
}; };
println!("The trace is composed of the entities:"); println!("The trace is composed of the entities:");
for (e, _c, _t) in res { for (e, _c, _t) in res {
println!("{}", WithTranslator::from_RSset(&translator, &e)); println!("{}", WithTranslator::from_RSset(&translator, &e));
} }
Ok(()) Ok(())
@ -108,14 +113,17 @@ pub fn hoop() -> std::io::Result<()> {
// we retrieve the id for "x" and use it to find the corresponding loop // we retrieve the id for "x" and use it to find the corresponding loop
let res = match perpetual::lollipops_only_loop_named(system, translator.encode("x")) { let res = match perpetual::lollipops_only_loop_named(system, translator.encode("x")) {
Some(o) => o, Some(o) => o,
None => {println!("No loop found."); return Ok(());} None => {
println!("No loop found.");
return Ok(());
}
}; };
println!("The loop is composed by the sets:"); println!("The loop is composed by the sets:");
for e in res { for e in res {
println!("{}", WithTranslator::from_RSset(&translator, &e)); println!("{}", WithTranslator::from_RSset(&translator, &e));
} }
Ok(()) Ok(())
@ -130,11 +138,17 @@ pub fn freq() -> std::io::Result<()> {
let system = read_system(&mut translator, path)?; let system = read_system(&mut translator, path)?;
let res = match frequency::naive_frequency(&system) { let res = match frequency::naive_frequency(&system) {
Ok(f) => f, Ok(f) => f,
Err(e) => {println!("Error computing target: {e}"); return Ok(());} Err(e) => {
println!("Error computing target: {e}");
return Ok(());
}
}; };
println!("Frequency of encountered symbols:\n{}", WithTranslator::from_Frequency(&translator, &res)); println!(
"Frequency of encountered symbols:\n{}",
WithTranslator::from_Frequency(&translator, &res)
);
Ok(()) Ok(())
} }

View File

@ -1,5 +1,5 @@
mod rsprocess;
mod examples; mod examples;
mod rsprocess;
lalrpop_util::lalrpop_mod!( lalrpop_util::lalrpop_mod!(
#[allow(clippy::uninlined_format_args)] pub grammar, // name of module #[allow(clippy::uninlined_format_args)] pub grammar, // name of module
@ -11,15 +11,15 @@ fn main() -> std::io::Result<()> {
// std::thread::sleep(std::time::Duration::new(2, 0)); // std::thread::sleep(std::time::Duration::new(2, 0));
// println!("{}", now.elapsed().as_micros()); // println!("{}", now.elapsed().as_micros());
examples::stats()?; // examples::stats()?;
examples::freq()?; examples::freq()?;
examples::hoop()?; // examples::hoop()?;
examples::target()?; // examples::target()?;
examples::run()?; // examples::run()?;
Ok(()) Ok(())
} }

View File

@ -6,7 +6,7 @@
//! inhibitors and products are held. //! inhibitors and products are held.
#![allow(dead_code)] #![allow(dead_code)]
use super::structure::{RSset, RSreaction}; use super::structure::{RSreaction, RSset};
/// Computes the result of a single reaction (if enabled returns the products) /// Computes the result of a single reaction (if enabled returns the products)
/// otherwise returns None. /// otherwise returns None.
@ -16,9 +16,9 @@ pub fn compute_step<'a>(
reaction: &'a RSreaction reaction: &'a RSreaction
) -> Option<&'a RSset> { ) -> Option<&'a RSset> {
if reaction.enabled(current_state) { if reaction.enabled(current_state) {
Some(reaction.products()) Some(reaction.products())
} else { } else {
None None
} }
} }
@ -29,18 +29,16 @@ pub fn compute_all<'a>(
current_state: &'a RSset, current_state: &'a RSset,
reactions: Vec<&'a RSreaction> reactions: Vec<&'a RSreaction>
) -> RSset { ) -> RSset {
reactions.iter().fold( reactions.iter().fold(RSset::new(), |acc, r| {
RSset::new(), acc.union_option(compute_step(current_state, r))
|acc, r| acc.union_option(compute_step(current_state, r)) })
)
} }
pub fn compute_all_owned<'a>( pub fn compute_all_owned<'a>(
current_state: &'a RSset, current_state: &'a RSset,
reactions: &'a [RSreaction] reactions: &'a [RSreaction]
) -> RSset { ) -> RSset {
reactions.iter().fold( reactions.iter().fold(RSset::new(), |acc, r| {
RSset::new(), acc.union_option(compute_step(current_state, r))
|acc, r| acc.union_option(compute_step(current_state, r)) })
)
} }

View File

@ -1,23 +1,20 @@
#![allow(dead_code)] #![allow(dead_code)]
use super::perpetual::{ use super::perpetual::{
lollipops_decomposed_named, lollipops_decomposed_named, lollipops_prefix_len_loop_decomposed,
lollipops_prefix_len_loop_decomposed, lollipops_prefix_len_loop_decomposed_named,
lollipops_prefix_len_loop_decomposed_named
}; };
use super::structure::{RSenvironment, RSreaction, RSset}; use super::structure::{RSenvironment, RSreaction, RSset};
use super::translator::IdType; use super::translator::IdType;
use std::cmp; use std::cmp;
use std::collections::HashSet; use std::collections::HashSet;
// see confluent, confluents // see confluent, confluents
pub fn confluent( pub fn confluent(
delta: &RSenvironment, delta: &RSenvironment,
reaction_rules: &[RSreaction], reaction_rules: &[RSreaction],
entities: &[RSset], entities: &[RSset],
) -> Option<(usize, usize, Vec<RSset>)> { ) -> Option<(usize, usize, Vec<RSset>)> {
let all_loops = lollipops_prefix_len_loop_decomposed(delta, let all_loops = lollipops_prefix_len_loop_decomposed(delta,
reaction_rules, reaction_rules,
entities.first()?); entities.first()?);
@ -26,9 +23,10 @@ pub fn confluent(
let mut max_distance = prefix_len; let mut max_distance = prefix_len;
for available_entities in entities.iter().skip(1) { for available_entities in entities.iter().skip(1) {
let all_loops = lollipops_prefix_len_loop_decomposed(delta, let all_loops =
reaction_rules, lollipops_prefix_len_loop_decomposed(delta,
available_entities); reaction_rules,
available_entities);
// FIXME we take just the first? do we compare all? // FIXME we take just the first? do we compare all?
let (prefix_len, new_hoop) = all_loops.first()?; let (prefix_len, new_hoop) = all_loops.first()?;
@ -40,16 +38,15 @@ pub fn confluent(
Some((max_distance, dimension, hoop)) Some((max_distance, dimension, hoop))
} }
// see confluent, confluents // see confluent, confluents
pub fn confluent_named( pub fn confluent_named(
delta: &RSenvironment, delta: &RSenvironment,
reaction_rules: &[RSreaction], reaction_rules: &[RSreaction],
entities: &[RSset], entities: &[RSset],
symb: IdType symb: IdType,
) -> Option<(usize, usize, Vec<RSset>)> { ) -> Option<(usize, usize, Vec<RSset>)> {
let (prefix_len, first_hoop) = let (prefix_len, first_hoop) =
lollipops_prefix_len_loop_decomposed_named(delta, lollipops_prefix_len_loop_decomposed_named(delta,
reaction_rules, reaction_rules,
entities.first()?, entities.first()?,
symb)?; symb)?;
@ -58,11 +55,12 @@ pub fn confluent_named(
let hoop = first_hoop; let hoop = first_hoop;
for available_entities in entities.iter().skip(1) { for available_entities in entities.iter().skip(1) {
let (prefix_len, new_hoop) = let (prefix_len, new_hoop) = lollipops_prefix_len_loop_decomposed_named(
lollipops_prefix_len_loop_decomposed_named(delta, delta,
reaction_rules, reaction_rules,
available_entities, available_entities,
symb)?; symb,
)?;
if new_hoop.len() != dimension || !hoop.contains(new_hoop.first()?) { if new_hoop.len() != dimension || !hoop.contains(new_hoop.first()?) {
return None; return None;
@ -79,37 +77,37 @@ pub fn invariant_named(
delta: &RSenvironment, delta: &RSenvironment,
reaction_rules: &[RSreaction], reaction_rules: &[RSreaction],
entities: &[RSset], entities: &[RSset],
symb: IdType symb: IdType,
) -> Option<(Vec<RSset>, Vec<RSset>)> { ) -> Option<(Vec<RSset>, Vec<RSset>)> {
let (prefix, hoop) = lollipops_decomposed_named(delta, let (prefix, hoop) =
reaction_rules, lollipops_decomposed_named(delta,
entities.first()?, reaction_rules,
symb)?; entities.first()?,
symb)?;
let mut invariant = vec![]; let mut invariant = vec![];
invariant.append(&mut prefix.clone()); invariant.append(&mut prefix.clone());
invariant.append(&mut hoop.clone()); invariant.append(&mut hoop.clone());
let dimension = hoop.len(); let dimension = hoop.len();
for available_entities in entities { for available_entities in entities {
let (new_prefix, new_hoop) = let (new_prefix, new_hoop) =
lollipops_decomposed_named(delta, lollipops_decomposed_named(delta,
reaction_rules, reaction_rules,
available_entities, available_entities,
symb)?; symb)?;
if new_hoop.len() != dimension || !hoop.contains(new_hoop.first()?) { if new_hoop.len() != dimension || !hoop.contains(new_hoop.first()?) {
return None return None;
} }
invariant.append(&mut new_prefix.clone()); invariant.append(&mut new_prefix.clone());
} }
// remove duplicates, maybe better with sorting? // remove duplicates, maybe better with sorting?
invariant = invariant = invariant
invariant .iter()
.iter() .cloned()
.cloned() .collect::<HashSet<_>>()
.collect::<HashSet<_>>() .iter()
.iter() .cloned()
.cloned() .collect::<Vec<_>>();
.collect::<Vec<_>>();
Some((invariant, hoop)) Some((invariant, hoop))
} }
@ -120,11 +118,12 @@ pub fn loop_confluent_named(
deltas: &[RSenvironment], deltas: &[RSenvironment],
reaction_rules: &[RSreaction], reaction_rules: &[RSreaction],
entities: &[RSset], entities: &[RSset],
symb: IdType symb: IdType,
) -> Option<Vec<(usize, usize, Vec<RSset>)>> { ) -> Option<Vec<(usize, usize, Vec<RSset>)>> {
deltas.iter() deltas
.map(|q| confluent_named(q, reaction_rules, entities, symb)) .iter()
.collect::<Option<Vec<_>>>() .map(|q| confluent_named(q, reaction_rules, entities, symb))
.collect::<Option<Vec<_>>>()
} }
// see strong_confluent // see strong_confluent
@ -133,16 +132,17 @@ pub fn strong_confluent_named(
deltas: &[RSenvironment], deltas: &[RSenvironment],
reaction_rules: &[RSreaction], reaction_rules: &[RSreaction],
entities: &[RSset], entities: &[RSset],
symb: IdType symb: IdType,
) -> Option<Vec<(Vec<RSset>, usize, Vec<RSset>)>> { ) -> Option<Vec<(Vec<RSset>, usize, Vec<RSset>)>> {
deltas.iter() deltas
.iter()
.map(|q| { .map(|q| {
let (invariant, hoop) = invariant_named(q, let (invariant, hoop) = invariant_named(q,
reaction_rules, reaction_rules,
entities, entities,
symb)?; symb)?;
let length = invariant.len(); let length = invariant.len();
Some((invariant, length, hoop)) } Some((invariant, length, hoop))
) })
.collect::<Option<Vec<_>>>() .collect::<Option<Vec<_>>>()
} }

View File

@ -1,7 +1,7 @@
#![allow(dead_code)] #![allow(dead_code)]
use std::collections::HashMap;
use crate::rsprocess::perpetual::lollipops_only_loop_decomposed_q; use crate::rsprocess::perpetual::lollipops_only_loop_decomposed_q;
use std::collections::HashMap;
use super::perpetual::lollipops_only_loop_named; use super::perpetual::lollipops_only_loop_named;
use super::structure::{RSreaction, RSset, RSsystem}; use super::structure::{RSreaction, RSset, RSsystem};
@ -12,37 +12,40 @@ use super::translator::IdType;
pub struct Frequency { pub struct Frequency {
pub frequency_map: HashMap<IdType, Vec<u32>>, pub frequency_map: HashMap<IdType, Vec<u32>>,
pub totals: Vec<usize>, pub totals: Vec<usize>,
pub weights: Vec<u32> pub weights: Vec<u32>,
} }
impl Frequency { impl Frequency {
pub fn new() -> Self { pub fn new() -> Self {
Frequency { frequency_map: HashMap::new(), totals: vec![], weights: vec![] } Frequency {
frequency_map: HashMap::new(),
totals: vec![],
weights: vec![],
}
} }
pub fn add(&mut self, e: &RSset, run: usize) { pub fn add(&mut self, e: &RSset, run: usize) {
for &el in e.iter() { for &el in e.iter() {
self.frequency_map.entry(el).or_insert(vec![0; run+1])[run] += 1 self.frequency_map.entry(el).or_insert(vec![0; run + 1])[run] += 1
} }
self.totals[run] += 1 self.totals[run] += 1
} }
pub fn append_weight(&mut self, new_weight: u32) { pub fn append_weight(&mut self, new_weight: u32) {
self.weights.push(new_weight) self.weights.push(new_weight)
} }
pub fn total_weights(&self) -> u32 { pub fn total_weights(&self) -> u32 {
self.weights.iter().sum() self.weights.iter().sum()
} }
} }
impl Default for Frequency { impl Default for Frequency {
fn default() -> Self { fn default() -> Self {
Frequency::new() Frequency::new()
} }
} }
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// see naiveFreq, assume the system is finite, calculate the frequency of // see naiveFreq, assume the system is finite, calculate the frequency of
@ -66,7 +69,7 @@ pub fn loop_frequency(system: &RSsystem, symb: IdType) -> Frequency {
freq.append_weight(1); freq.append_weight(1);
if let Some(hoop) = lollipops_only_loop_named(system.clone(), symb) { if let Some(hoop) = lollipops_only_loop_named(system.clone(), symb) {
hoop.iter().for_each(|e| freq.add(e, 0)); hoop.iter().for_each(|e| freq.add(e, 0));
} }
freq freq
} }
@ -76,15 +79,15 @@ pub fn loop_frequency(system: &RSsystem, symb: IdType) -> Frequency {
pub fn limit_frequency( pub fn limit_frequency(
q: &[RSset], q: &[RSset],
reaction_rules: &[RSreaction], reaction_rules: &[RSreaction],
available_entities: &RSset available_entities: &RSset,
) -> Option<Frequency> { ) -> Option<Frequency> {
let mut available_entities = available_entities.clone(); let mut available_entities = available_entities.clone();
for q in q.iter().rev().skip(1).rev() { for q in q.iter().rev().skip(1).rev() {
let res = lollipops_only_loop_decomposed_q(q, let res = lollipops_only_loop_decomposed_q(q,
reaction_rules, reaction_rules,
&available_entities); &available_entities);
available_entities = res.into_iter().next()?; available_entities = res.into_iter().next()?;
} }
let mut freq = Frequency::new(); let mut freq = Frequency::new();
@ -93,18 +96,18 @@ pub fn limit_frequency(
lollipops_only_loop_decomposed_q(q.last().unwrap(), lollipops_only_loop_decomposed_q(q.last().unwrap(),
reaction_rules, reaction_rules,
&available_entities) &available_entities)
.iter().for_each(|e| freq.add(e, 0)); .iter()
.for_each(|e| freq.add(e, 0));
Some(freq) Some(freq)
} }
// see fastFreq, q[i] is given enough times such that the stabilizes in a loop, // 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. // calculate the frequency of the symbols in any state in any loop, weighted.
pub fn fast_frequency( pub fn fast_frequency(
q: &[RSset], q: &[RSset],
reaction_rules: &[RSreaction], reaction_rules: &[RSreaction],
available_entities: &RSset, available_entities: &RSset,
weights: &[u32] weights: &[u32],
) -> Option<Frequency> { ) -> Option<Frequency> {
// FIXME: we return the empty frequency or do we not return anything? // FIXME: we return the empty frequency or do we not return anything?
let mut available_entities = available_entities.clone(); let mut available_entities = available_entities.clone();
@ -112,12 +115,12 @@ pub fn fast_frequency(
let mut freq = Frequency::new(); let mut freq = Frequency::new();
for (pos, (q, &w)) in q.iter().zip(weights).enumerate() { for (pos, (q, &w)) in q.iter().zip(weights).enumerate() {
freq.append_weight(w); freq.append_weight(w);
let hoop = lollipops_only_loop_decomposed_q(q, let hoop = lollipops_only_loop_decomposed_q(q,
reaction_rules, reaction_rules,
&available_entities); &available_entities);
hoop.iter().for_each(|e| freq.add(e, pos)); hoop.iter().for_each(|e| freq.add(e, pos));
available_entities = hoop.into_iter().next()?; available_entities = hoop.into_iter().next()?;
} }
Some(freq) Some(freq)
} }

View File

@ -64,7 +64,8 @@ pub Reactions: Vec<RSreaction> = {
Reaction: RSreaction = { Reaction: RSreaction = {
"[" <r: Set> "," <i: Set> "," <p: Set> "]" => RSreaction::from(r, i, p), "[" <r: Set> "," <i: Set> "," <p: Set> "]" => RSreaction::from(r, i, p),
"[" "r:" <r: Set> "," "i:" <i: Set> "," "p:" <p: Set> "]" => RSreaction::from(r, i, p), "[" "r:" <r: Set> "," "i:" <i: Set> "," "p:" <p: Set> "]" =>
RSreaction::from(r, i, p),
} }
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
@ -87,14 +88,18 @@ CTX_process: RSprocess = {
RSprocess::EntitySet{ entities: c, next_process: Rc::new(k) }, RSprocess::EntitySet{ entities: c, next_process: Rc::new(k) },
"(" <k: CTX_process> ")" => k, "(" <k: CTX_process> ")" => k,
"(" <k: Separeted<CTX_process, "+">> ")" => "(" <k: Separeted<CTX_process, "+">> ")" =>
RSprocess::Summation{ children: k.into_iter().map(Rc::new).collect::<Vec<_>>() }, RSprocess::Summation{
children: k.into_iter().map(Rc::new).collect::<Vec<_>>()
},
"<" <n: Num> <k1: CTX_process> ">" "." <k: CTX_process> => "<" <n: Num> <k1: CTX_process> ">" "." <k: CTX_process> =>
RSprocess::WaitEntity{ repeat: n, RSprocess::WaitEntity{ repeat: n,
repeated_process: Rc::new(k1), repeated_process: Rc::new(k1),
next_process: Rc::new(k)}, next_process: Rc::new(k) },
"nil" => RSprocess::Nill, "nil" => RSprocess::Nill,
<identifier: Literal> => <identifier: Literal> =>
RSprocess::RecursiveIdentifier{ identifier: translator.encode(identifier) } RSprocess::RecursiveIdentifier{
identifier: translator.encode(identifier)
}
}; };
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
@ -165,5 +170,8 @@ pub System: RSsystem = {
"Initial Entities:" <available_entities: Set> "Initial Entities:" <available_entities: Set>
"Context:" <context_process: Context> "Context:" <context_process: Context>
"Reactions:" <reaction_rules: Reactions> "Reactions:" <reaction_rules: Reactions>
=> RSsystem::from(delta.into(), available_entities, context_process, Rc::new(reaction_rules)) => RSsystem::from(delta.into(),
available_entities,
context_process,
Rc::new(reaction_rules))
} }

View File

@ -1,9 +1,9 @@
pub mod translator;
pub mod structure;
pub mod support_structures;
pub mod classical; pub mod classical;
pub mod transitions;
pub mod perpetual;
pub mod confluence; pub mod confluence;
pub mod frequency; pub mod frequency;
pub mod perpetual;
pub mod statistics; pub mod statistics;
pub mod structure;
pub mod support_structures;
pub mod transitions;
pub mod translator;

View File

@ -1,15 +1,14 @@
#![allow(dead_code)] #![allow(dead_code)]
use super::classical::compute_all_owned; use super::classical::compute_all_owned;
use super::translator::IdType;
use super::structure::{RSenvironment, RSprocess, RSreaction, RSset, RSsystem}; 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>( fn split<'a>(
set: &'a RSset, set: &'a RSset,
trace: &'a [RSset] trace: &'a [RSset]
) -> Option<(&'a[RSset], &'a[RSset])> { ) -> Option<(&'a [RSset], &'a [RSset])> {
let position = trace.iter().rposition(|x| x == set); let position = trace.iter().rposition(|x| x == set);
position.map(|pos| trace.split_at(pos)) position.map(|pos| trace.split_at(pos))
} }
@ -23,35 +22,37 @@ fn find_loop(
let mut entities = entities; let mut entities = entities;
let mut trace = vec![]; let mut trace = vec![];
loop { loop {
if let Some((prefix, hoop)) = split(&entities, &trace) { if let Some((prefix, hoop)) = split(&entities, &trace) {
return (prefix.to_vec(), hoop.to_vec()); return (prefix.to_vec(), hoop.to_vec());
} else { } else {
let t = entities.union(q); let t = entities.union(q);
let products = compute_all_owned(&t, rs); let products = compute_all_owned(&t, rs);
trace.push(entities.clone()); trace.push(entities.clone());
entities = products; entities = products;
} }
} }
} }
// finds the loops by simulating the system // finds the loops by simulating the system
fn find_only_loop(rs: &[RSreaction], entities: RSset, q: &RSset) -> Vec<RSset> { fn find_only_loop(
rs: &[RSreaction],
entities: RSset,
q: &RSset
) -> Vec<RSset> {
let mut entities = entities; let mut entities = entities;
let mut trace = vec![]; let mut trace = vec![];
loop { loop {
if let Some((_prefix, hoop)) = split(&entities, &trace) { if let Some((_prefix, hoop)) = split(&entities, &trace) {
return hoop.to_vec(); return hoop.to_vec();
} else { } else {
let t = entities.union(q); let t = entities.union(q);
let products = compute_all_owned(&t, rs); let products = compute_all_owned(&t, rs);
trace.push(entities.clone()); trace.push(entities.clone());
entities = products; 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( fn find_prefix_len_loop(
rs: &[RSreaction], rs: &[RSreaction],
@ -61,14 +62,14 @@ fn find_prefix_len_loop(
let mut entities = entities; let mut entities = entities;
let mut trace = vec![]; let mut trace = vec![];
loop { loop {
if let Some((prefix, hoop)) = split(&entities, &trace) { if let Some((prefix, hoop)) = split(&entities, &trace) {
return (prefix.len(), hoop.to_vec()); return (prefix.len(), hoop.to_vec());
} else { } else {
let t = entities.union(q); let t = entities.union(q);
let products = compute_all_owned(&t, rs); let products = compute_all_owned(&t, rs);
trace.push(entities.clone()); trace.push(entities.clone());
entities = products; entities = products;
} }
} }
} }
@ -80,22 +81,25 @@ fn filter_delta<'a>(x: (&IdType, &'a RSprocess)) -> Option<&'a RSset> {
use super::structure::RSprocess::*; use super::structure::RSprocess::*;
let (id, rest) = x; let (id, rest) = x;
if let EntitySet{ entities, next_process} = rest { if let EntitySet {
if let RecursiveIdentifier{ identifier } = &**next_process { entities,
if identifier == id { next_process,
return Some(entities); } = rest
} {
} if let RecursiveIdentifier { identifier } = &**next_process {
if identifier == id {
return Some(entities);
}
}
} }
None None
} }
// see lollipop // see lollipop
pub fn lollipops_decomposed( pub fn lollipops_decomposed(
delta: &RSenvironment, delta: &RSenvironment,
reaction_rules: &[RSreaction], reaction_rules: &[RSreaction],
available_entities: &RSset available_entities: &RSset,
) -> Vec<(Vec<RSset>, Vec<RSset>)> { ) -> Vec<(Vec<RSset>, Vec<RSset>)> {
// FIXME: i think we are only interested in "x", not all symbols that // FIXME: i think we are only interested in "x", not all symbols that
// satisfy X = pre(Q, rec(X)) // satisfy X = pre(Q, rec(X))
@ -110,9 +114,11 @@ pub fn lollipops_decomposed(
// see lollipop // see lollipop
pub fn lollipops(system: RSsystem) -> Vec<(Vec<RSset>, Vec<RSset>)> { pub fn lollipops(system: RSsystem) -> Vec<(Vec<RSset>, Vec<RSset>)> {
lollipops_decomposed(system.get_delta(), lollipops_decomposed(
system.get_reaction_rules(), system.get_delta(),
system.get_available_entities()) system.get_reaction_rules(),
system.get_available_entities(),
)
} }
// see loop // see loop
@ -121,18 +127,21 @@ pub fn lollipops_only_loop(system: RSsystem) -> Vec<Vec<RSset>> {
// satisfy X = pre(Q, rec(X)) // satisfy X = pre(Q, rec(X))
let filtered = system.get_delta().iter().filter_map(filter_delta); let filtered = system.get_delta().iter().filter_map(filter_delta);
let find_loop_fn = |q| find_only_loop(system.get_reaction_rules(), let find_loop_fn = |q| {
system.get_available_entities().clone(), find_only_loop(
q); system.get_reaction_rules(),
system.get_available_entities().clone(),
q,
)
};
filtered.map(find_loop_fn).collect::<Vec<_>>() filtered.map(find_loop_fn).collect::<Vec<_>>()
} }
pub fn lollipops_prefix_len_loop_decomposed( pub fn lollipops_prefix_len_loop_decomposed(
delta: &RSenvironment, delta: &RSenvironment,
reaction_rules: &[RSreaction], reaction_rules: &[RSreaction],
available_entities: &RSset available_entities: &RSset,
) -> Vec<(usize, Vec<RSset>)> { ) -> Vec<(usize, Vec<RSset>)> {
// FIXME: i think we are only interested in "x", not all symbols that // FIXME: i think we are only interested in "x", not all symbols that
// satisfy X = pre(Q, rec(X)) // satisfy X = pre(Q, rec(X))
@ -149,15 +158,15 @@ pub fn lollipops_prefix_len_loop_decomposed(
pub fn lollipops_only_loop_decomposed( pub fn lollipops_only_loop_decomposed(
delta: &RSenvironment, delta: &RSenvironment,
reaction_rules: &[RSreaction], reaction_rules: &[RSreaction],
available_entities: &RSset available_entities: &RSset,
) -> Vec<Vec<RSset>> { ) -> Vec<Vec<RSset>> {
// FIXME: i think we are only interested in "x", not all symbols that // FIXME: i think we are only interested in "x", not all symbols that
// satisfy X = pre(Q, rec(X)) // satisfy X = pre(Q, rec(X))
let filtered = delta.iter().filter_map(filter_delta); let filtered = delta.iter().filter_map(filter_delta);
let find_loop_fn = |q| find_only_loop(reaction_rules, let find_loop_fn = |q| find_only_loop(reaction_rules,
available_entities.clone(), available_entities.clone(),
q); q);
filtered.map(find_loop_fn).collect::<Vec<_>>() filtered.map(find_loop_fn).collect::<Vec<_>>()
} }
@ -175,15 +184,19 @@ fn filter_delta_named<'a>(
use super::structure::RSprocess::*; use super::structure::RSprocess::*;
let (id, rest) = x; let (id, rest) = x;
if id != symb { if id != symb {
return None; return None;
} }
if let EntitySet{ entities, next_process} = rest { if let EntitySet {
if let RecursiveIdentifier{ identifier } = &**next_process { entities,
if identifier == id { next_process,
return Some(entities); } = rest
} {
} if let RecursiveIdentifier { identifier } = &**next_process {
if identifier == id {
return Some(entities);
}
}
} }
None None
} }
@ -193,9 +206,12 @@ pub fn lollipops_decomposed_named(
delta: &RSenvironment, delta: &RSenvironment,
reaction_rules: &[RSreaction], reaction_rules: &[RSreaction],
available_entities: &RSset, available_entities: &RSset,
symb: IdType symb: IdType,
) -> Option<(Vec<RSset>, Vec<RSset>)> { ) -> Option<(Vec<RSset>, Vec<RSset>)> {
let filtered = delta.iter().filter_map(|x| filter_delta_named(x, &symb)).next(); let filtered = delta
.iter()
.filter_map(|x| filter_delta_named(x, &symb))
.next();
let find_loop_fn = |q| find_loop(reaction_rules, let find_loop_fn = |q| find_loop(reaction_rules,
available_entities.clone(), available_entities.clone(),
@ -209,10 +225,12 @@ pub fn lollipops_named(
system: RSsystem, system: RSsystem,
symb: IdType symb: IdType
) -> Option<(Vec<RSset>, Vec<RSset>)> { ) -> Option<(Vec<RSset>, Vec<RSset>)> {
lollipops_decomposed_named(system.get_delta(), lollipops_decomposed_named(
system.get_reaction_rules(), system.get_delta(),
system.get_available_entities(), system.get_reaction_rules(),
symb) system.get_available_entities(),
symb,
)
} }
// see loop // see loop
@ -220,13 +238,19 @@ pub fn lollipops_only_loop_named(
system: RSsystem, system: RSsystem,
symb: IdType symb: IdType
) -> Option<Vec<RSset>> { ) -> Option<Vec<RSset>> {
let filtered = system.get_delta().iter() let filtered = system
.filter_map(|x| filter_delta_named(x, &symb)).next(); .get_delta()
.iter()
.filter_map(|x| filter_delta_named(x, &symb))
.next();
let find_loop_fn = let find_loop_fn = |q| {
|q| find_only_loop(system.get_reaction_rules(), find_only_loop(
system.get_available_entities().clone(), system.get_reaction_rules(),
q); system.get_available_entities().clone(),
q,
)
};
filtered.map(find_loop_fn) filtered.map(find_loop_fn)
} }
@ -235,10 +259,12 @@ pub fn lollipops_prefix_len_loop_decomposed_named(
delta: &RSenvironment, delta: &RSenvironment,
reaction_rules: &[RSreaction], reaction_rules: &[RSreaction],
available_entities: &RSset, available_entities: &RSset,
symb: IdType symb: IdType,
) -> Option<(usize, Vec<RSset>)> { ) -> Option<(usize, Vec<RSset>)> {
let filtered = delta.iter() let filtered = delta
.filter_map(|x| filter_delta_named(x, &symb)).next(); .iter()
.filter_map(|x| filter_delta_named(x, &symb))
.next();
let find_loop_fn = |q| find_prefix_len_loop(reaction_rules, let find_loop_fn = |q| find_prefix_len_loop(reaction_rules,
available_entities.clone(), available_entities.clone(),
@ -252,10 +278,12 @@ pub fn lollipops_only_loop_decomposed_named(
delta: &RSenvironment, delta: &RSenvironment,
reaction_rules: &[RSreaction], reaction_rules: &[RSreaction],
available_entities: &RSset, available_entities: &RSset,
symb: IdType symb: IdType,
) -> Option<Vec<RSset>> { ) -> Option<Vec<RSset>> {
let filtered = delta.iter() let filtered = delta
.filter_map(|x| filter_delta_named(x, &symb)).next(); .iter()
.filter_map(|x| filter_delta_named(x, &symb))
.next();
let find_loop_fn = |q| find_only_loop(reaction_rules, let find_loop_fn = |q| find_only_loop(reaction_rules,
available_entities.clone(), available_entities.clone(),

View File

@ -10,122 +10,119 @@ pub fn of_RSsystem<'a>(translator: &'a Translator, system: &'a RSsystem) -> Stri
result.push_str( result.push_str(
"=============================================================\n" "=============================================================\n"
); );
result.push_str( result.push_str(&format!(
&format!("the initial state has {} entities:\n", "the initial state has {} entities:\n",
system.get_available_entities().len()) system.get_available_entities().len()
); ));
result.push_str( result.push_str(&format!(
&format!("{}\n", "{}\n",
WithTranslator::from_RSset(translator, WithTranslator::from_RSset(translator, system.get_available_entities())
system.get_available_entities())) ));
);
let reactants = let reactants = system
system .get_reaction_rules()
.get_reaction_rules() .iter()
.iter() .fold(RSset::new(), |acc, new| acc.union(new.reactants()));
.fold(RSset::new(), |acc, new| acc.union(new.reactants())); result.push_str(&format!(
result.push_str( "The reactants are {}:\n{}\n",
&format!("The reactants are {}:\n{}\n", reactants.len(),
reactants.len(), WithTranslator::from_RSset(translator, &reactants)
WithTranslator::from_RSset(translator, &reactants)) ));
);
let inhibitors = let inhibitors = system
system .get_reaction_rules()
.get_reaction_rules() .iter()
.iter() .fold(RSset::new(), |acc, new| acc.union(new.inihibitors()));
.fold(RSset::new(), |acc, new| acc.union(new.inihibitors())); result.push_str(&format!(
result.push_str( "The inhibitors are {}:\n{}\n",
&format!("The inhibitors are {}:\n{}\n", inhibitors.len(),
inhibitors.len(), WithTranslator::from_RSset(translator, &inhibitors)
WithTranslator::from_RSset(translator, &inhibitors)) ));
);
let products =
system
.get_reaction_rules()
.iter()
.fold(RSset::new(), |acc, new| acc.union(new.products()));
result.push_str(
&format!("The products are {}:\n{}\n",
products.len(),
WithTranslator::from_RSset(translator, &products))
);
let products = system
.get_reaction_rules()
.iter()
.fold(RSset::new(), |acc, new| acc.union(new.products()));
result.push_str(&format!(
"The products are {}:\n{}\n",
products.len(),
WithTranslator::from_RSset(translator, &products)
));
let total = reactants.union(&inhibitors.union(&products)); let total = reactants.union(&inhibitors.union(&products));
result.push_str( result.push_str(&format!(
&format!("The reactions involve {} entities:\n{}\n", "The reactions involve {} entities:\n{}\n",
total.len(), total.len(),
WithTranslator::from_RSset(translator, &total)) WithTranslator::from_RSset(translator, &total)
); ));
let entities_env = system.get_delta().all_elements(); let entities_env = system.get_delta().all_elements();
result.push_str( result.push_str(&format!(
&format!("The environment involves {} entities:\n{}\n", "The environment involves {} entities:\n{}\n",
entities_env.len(), entities_env.len(),
WithTranslator::from_RSset(translator, &entities_env)) WithTranslator::from_RSset(translator, &entities_env)
); ));
let entities_context = system.get_context_process().all_elements(); let entities_context = system.get_context_process().all_elements();
result.push_str( result.push_str(&format!(
&format!("The context involves {} entities:\n{}\n", "The context involves {} entities:\n{}\n",
entities_context.len(), entities_context.len(),
WithTranslator::from_RSset(translator, &entities_context)) WithTranslator::from_RSset(translator, &entities_context)
); ));
let entities_all = total.union(&entities_env) let entities_all = total
.union(&entities_context) .union(&entities_env)
.union(system.get_available_entities()); .union(&entities_context)
.union(system.get_available_entities());
result.push_str( result.push_str(&format!(
&format!("The whole RS involves {} entities:\n{}\n", "The whole RS involves {} entities:\n{}\n",
entities_all.len(), entities_all.len(),
WithTranslator::from_RSset(translator, &entities_all)) WithTranslator::from_RSset(translator, &entities_all)
); ));
let possible_e = products.union(system.get_available_entities()) let possible_e = products
.union(&entities_context); .union(system.get_available_entities())
.union(&entities_context);
let missing_e = reactants.subtraction(&possible_e); let missing_e = reactants.subtraction(&possible_e);
result.push_str( result.push_str(&format!(
&format!("There are {} reactants that will never be available:\n{}\n", "There are {} reactants that will never be available:\n{}\n",
missing_e.len(), missing_e.len(),
WithTranslator::from_RSset(translator, &missing_e)) WithTranslator::from_RSset(translator, &missing_e)
); ));
let entities_not_needed = entities_context.subtraction(&total); let entities_not_needed = entities_context.subtraction(&total);
result.push_str( result.push_str(&format!(
&format!("The context can provide {} entities that will never be used:\n{}\n", "The context can provide {} entities that will never be used:\n{}\n",
entities_not_needed.len(), entities_not_needed.len(),
WithTranslator::from_RSset(translator, &entities_not_needed)) WithTranslator::from_RSset(translator, &entities_not_needed)
); ));
result.push_str( result.push_str(&format!(
&format!("There are {} reactions in total.\n", "There are {} reactions in total.\n",
system.get_reaction_rules().len()) system.get_reaction_rules().len()
); ));
let mut admissible_reactions = vec![]; let mut admissible_reactions = vec![];
let mut nonadmissible_reactions = vec![]; let mut nonadmissible_reactions = vec![];
for reaction in system.get_reaction_rules().iter() { for reaction in system.get_reaction_rules().iter() {
if reaction.reactants().is_disjoint(&missing_e) { if reaction.reactants().is_disjoint(&missing_e) {
admissible_reactions.push(reaction); admissible_reactions.push(reaction);
} else { } else {
nonadmissible_reactions.push(reaction); nonadmissible_reactions.push(reaction);
} }
} }
result.push_str( result.push_str(&format!(
&format!("- the applicable reactions are {}.\n", "- the applicable reactions are {}.\n",
admissible_reactions.len()) admissible_reactions.len()
); ));
result.push_str( result.push_str(&format!(
&format!("- there are {} reactions that will never be enabled.\n", "- there are {} reactions that will never be enabled.\n",
nonadmissible_reactions.len()) nonadmissible_reactions.len()
); ));
result.push_str( result.push_str(
"=============================================================" "============================================================="
); );

View File

@ -1,104 +1,116 @@
#![allow(dead_code)] #![allow(dead_code)]
use super::translator::IdType;
use std::collections::{BTreeSet, HashMap, VecDeque}; use std::collections::{BTreeSet, HashMap, VecDeque};
use std::hash::Hash; use std::hash::Hash;
use std::rc::Rc; use std::rc::Rc;
use super::translator::{IdType};
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// RSset // RSset
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct RSset { pub struct RSset {
identifiers: BTreeSet<IdType> identifiers: BTreeSet<IdType>,
} }
impl<const N: usize> From<[IdType; N]> for RSset { impl<const N: usize> From<[IdType; N]> for RSset {
fn from(arr: [IdType; N]) -> Self { fn from(arr: [IdType; N]) -> Self {
RSset{identifiers: BTreeSet::from(arr)} RSset {
identifiers: BTreeSet::from(arr),
}
} }
} }
impl From<&[IdType]> for RSset { impl From<&[IdType]> for RSset {
fn from(arr: &[IdType]) -> Self { fn from(arr: &[IdType]) -> Self {
RSset{identifiers: BTreeSet::from_iter(arr.to_vec())} RSset {
identifiers: BTreeSet::from_iter(arr.to_vec()),
}
} }
} }
impl From<Vec<IdType>> for RSset { impl From<Vec<IdType>> for RSset {
fn from(arr: Vec<IdType>) -> Self { fn from(arr: Vec<IdType>) -> Self {
RSset{identifiers: BTreeSet::from_iter(arr)} RSset {
identifiers: BTreeSet::from_iter(arr),
}
} }
} }
impl RSset { impl RSset {
pub fn new() -> Self { pub fn new() -> Self {
RSset{identifiers: BTreeSet::new()} RSset {
identifiers: BTreeSet::new(),
}
} }
pub fn is_subset(&self, b: &RSset) -> bool { pub fn is_subset(&self, b: &RSset) -> bool {
self.identifiers.is_subset(&b.identifiers) self.identifiers.is_subset(&b.identifiers)
} }
pub fn is_disjoint(&self, b: &RSset) -> bool { pub fn is_disjoint(&self, b: &RSset) -> bool {
self.identifiers.is_disjoint(&b.identifiers) self.identifiers.is_disjoint(&b.identifiers)
} }
pub fn union(&self, b: &RSset) -> RSset { pub fn union(&self, b: &RSset) -> RSset {
// TODO maybe find more efficient way without copy/clone // TODO maybe find more efficient way without copy/clone
let mut ret: RSset = b.clone(); let mut ret: RSset = b.clone();
ret.identifiers.extend(self.identifiers.iter()); ret.identifiers.extend(self.identifiers.iter());
ret ret
} }
pub fn union_option(&self, b: Option<&RSset>) -> RSset { pub fn union_option(&self, b: Option<&RSset>) -> RSset {
if let Some(b) = b { if let Some(b) = b {
self.union(b) self.union(b)
} else { } else {
self.clone() self.clone()
} }
} }
pub fn intersection(&self, b: &RSset) -> RSset { pub fn intersection(&self, b: &RSset) -> RSset {
// TODO maybe find more efficient way without copy/clone // TODO maybe find more efficient way without copy/clone
let res: BTreeSet<_> = b.identifiers.intersection(&self.identifiers) let res: BTreeSet<_> = b
.copied() .identifiers
.collect(); .intersection(&self.identifiers)
RSset { identifiers: res } .copied()
.collect();
RSset { identifiers: res }
} }
pub fn subtraction(&self, b: &RSset) -> RSset { pub fn subtraction(&self, b: &RSset) -> RSset {
// TODO maybe find more efficient way without copy/clone // TODO maybe find more efficient way without copy/clone
let res: BTreeSet<_> = self.identifiers.difference(&b.identifiers) let res: BTreeSet<_> = self
.copied() .identifiers
.collect(); .difference(&b.identifiers)
RSset { identifiers: res } .copied()
.collect();
RSset { identifiers: res }
} }
pub fn set(&self) -> &BTreeSet<IdType> { pub fn set(&self) -> &BTreeSet<IdType> {
&self.identifiers &self.identifiers
} }
pub fn iter(&self) -> std::collections::btree_set::Iter<'_, IdType> { pub fn iter(&self) -> std::collections::btree_set::Iter<'_, IdType> {
self.identifiers.iter() self.identifiers.iter()
} }
pub fn len(&self) -> usize { pub fn len(&self) -> usize {
self.identifiers.len() self.identifiers.len()
} }
pub fn insert(&mut self, el: IdType) -> bool { pub fn insert(&mut self, el: IdType) -> bool {
self.identifiers.insert(el) self.identifiers.insert(el)
} }
pub fn push(&mut self, b: &RSset) { pub fn push(&mut self, b: &RSset) {
self.identifiers.extend(b.iter()) self.identifiers.extend(b.iter())
} }
} }
impl Default for RSset { impl Default for RSset {
fn default() -> Self { fn default() -> Self {
RSset::new() RSset::new()
} }
} }
@ -107,11 +119,10 @@ impl IntoIterator for RSset {
type IntoIter = std::collections::btree_set::IntoIter<Self::Item>; type IntoIter = std::collections::btree_set::IntoIter<Self::Item>;
fn into_iter(self) -> Self::IntoIter { fn into_iter(self) -> Self::IntoIter {
self.identifiers.into_iter() self.identifiers.into_iter()
} }
} }
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// RSreaction // RSreaction
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
@ -119,124 +130,141 @@ impl IntoIterator for RSset {
pub struct RSreaction { pub struct RSreaction {
reactants: RSset, reactants: RSset,
inihibitors: RSset, inihibitors: RSset,
products: RSset products: RSset,
} }
impl RSreaction { impl RSreaction {
pub fn new() -> Self { pub fn new() -> Self {
RSreaction{ reactants: RSset::new(), RSreaction {
inihibitors: RSset::new(), reactants: RSset::new(),
products: RSset::new(), } inihibitors: RSset::new(),
products: RSset::new(),
}
} }
pub fn from(reactants: RSset, inihibitors: RSset, products: RSset) -> Self { pub fn from(reactants: RSset, inihibitors: RSset, products: RSset) -> Self {
RSreaction{ reactants, RSreaction {
inihibitors, reactants,
products } inihibitors,
products,
}
} }
// see enable // see enable
pub fn enabled(&self, current_state: &RSset) -> bool { pub fn enabled(&self, current_state: &RSset) -> bool {
self.reactants.is_subset(current_state) self.reactants.is_subset(current_state)
&& self.inihibitors.is_disjoint(current_state) && self.inihibitors.is_disjoint(current_state)
} }
pub fn products_clone(&self) -> RSset { pub fn products_clone(&self) -> RSset {
self.products.clone() self.products.clone()
} }
pub fn reactants(&self) -> &RSset { pub fn reactants(&self) -> &RSset {
&self.reactants &self.reactants
} }
pub fn inihibitors(&self) -> &RSset { pub fn inihibitors(&self) -> &RSset {
&self.inihibitors &self.inihibitors
} }
pub fn products(&self) -> &RSset { pub fn products(&self) -> &RSset {
&self.products &self.products
} }
} }
impl Default for RSreaction { impl Default for RSreaction {
fn default() -> Self { fn default() -> Self {
RSreaction::new() RSreaction::new()
} }
} }
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// RSprocess // RSprocess
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub enum RSprocess { pub enum RSprocess {
Nill, Nill,
RecursiveIdentifier{ identifier: IdType }, RecursiveIdentifier {
EntitySet{ entities: RSset, identifier: IdType,
next_process: Rc<RSprocess> }, },
WaitEntity{ repeat: i64, EntitySet {
repeated_process: Rc<RSprocess>, entities: RSset,
next_process: Rc<RSprocess> }, next_process: Rc<RSprocess>,
Summation{ children: Vec<Rc<RSprocess>> }, },
NondeterministicChoice{ children: Vec<Rc<RSprocess>> } WaitEntity {
repeat: i64,
repeated_process: Rc<RSprocess>,
next_process: Rc<RSprocess>,
},
Summation {
children: Vec<Rc<RSprocess>>,
},
NondeterministicChoice {
children: Vec<Rc<RSprocess>>,
},
} }
impl RSprocess { impl RSprocess {
// TODO: remove all the clone() // TODO: remove all the clone()
pub fn concat(&self, new: &RSprocess) -> RSprocess{ pub fn concat(&self, new: &RSprocess) -> RSprocess {
match (self, new) { match (self, new) {
(RSprocess::NondeterministicChoice{children: c1}, (
RSprocess::NondeterministicChoice{children: c2}) => { RSprocess::NondeterministicChoice { children: c1 },
RSprocess::NondeterministicChoice { RSprocess::NondeterministicChoice { children: c2 },
children: [c1.clone(), ) => RSprocess::NondeterministicChoice {
c2.clone()].concat() children: [c1.clone(), c2.clone()].concat(),
} },
}, (RSprocess::NondeterministicChoice { children }, new)
(RSprocess::NondeterministicChoice{children}, new) | | (new, RSprocess::NondeterministicChoice { children }) => {
(new, RSprocess::NondeterministicChoice{children}) => { let mut new_children = children.clone();
let mut new_children = children.clone(); new_children.push(Rc::new(new.clone()));
new_children.push(Rc::new(new.clone())); RSprocess::NondeterministicChoice {
RSprocess::NondeterministicChoice{ children: new_children } children: new_children,
}, }
(_, _) => { }
RSprocess::NondeterministicChoice { (_, _) => RSprocess::NondeterministicChoice {
children: vec![Rc::new(self.clone()), children: vec![Rc::new(self.clone()), Rc::new(new.clone())],
Rc::new(new.clone())] },
} }
}
}
} }
pub fn all_elements(&self) -> RSset { pub fn all_elements(&self) -> RSset {
let mut queue = VecDeque::from([self]); let mut queue = VecDeque::from([self]);
let mut elements = RSset::new(); let mut elements = RSset::new();
while let Some(el) = queue.pop_front() { while let Some(el) = queue.pop_front() {
match el { match el {
Self::Nill => {} Self::Nill => {}
Self::RecursiveIdentifier { identifier: _ } => {} Self::RecursiveIdentifier { identifier: _ } => {}
Self::EntitySet { entities, next_process } => { Self::EntitySet {
elements.push(entities); entities,
queue.push_back(next_process); next_process,
} } => {
Self::WaitEntity { repeat: _, repeated_process, next_process } => { elements.push(entities);
queue.push_back(repeated_process); queue.push_back(next_process);
queue.push_back(next_process); }
} Self::WaitEntity {
Self::Summation { children } => { repeat: _,
for c in children { repeated_process,
queue.push_back(c); next_process,
} } => {
} queue.push_back(repeated_process);
Self::NondeterministicChoice { children } => { queue.push_back(next_process);
for c in children { }
queue.push_back(c); Self::Summation { children } => {
} for c in children {
} queue.push_back(c);
} }
} }
elements Self::NondeterministicChoice { children } => {
for c in children {
queue.push_back(c);
}
}
}
}
elements
} }
} }
@ -245,52 +273,60 @@ impl RSprocess {
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct RSchoices { pub struct RSchoices {
context_moves: Vec<(Rc<RSset>, Rc<RSprocess>)> context_moves: Vec<(Rc<RSset>, Rc<RSprocess>)>,
} }
impl RSchoices { impl RSchoices {
pub fn new() -> Self { pub fn new() -> Self {
RSchoices{ context_moves: vec![] } RSchoices {
context_moves: vec![],
}
} }
pub fn new_not_empty() -> Self { pub fn new_not_empty() -> Self {
RSchoices{ context_moves: vec![(Rc::new(RSset::new()), RSchoices {
Rc::new(RSprocess::Nill))] } context_moves: vec![(Rc::new(RSset::new()),
Rc::new(RSprocess::Nill))],
}
} }
pub fn append(&mut self, a: &mut RSchoices) { pub fn append(&mut self, a: &mut RSchoices) {
self.context_moves.append(&mut a.context_moves); self.context_moves.append(&mut a.context_moves);
} }
pub fn replace(&mut self, a: Rc<RSprocess>) { pub fn replace(&mut self, a: Rc<RSprocess>) {
self.context_moves = self.context_moves = self
self.context_moves .context_moves
.iter_mut() .iter_mut()
.map(|(c1, _)| (Rc::clone(c1), Rc::clone(&a))).collect::<Vec<_>>(); .map(|(c1, _)| (Rc::clone(c1), Rc::clone(&a)))
.collect::<Vec<_>>();
} }
pub fn shuffle(&mut self, choices: RSchoices) { pub fn shuffle(&mut self, choices: RSchoices) {
match (self.context_moves.is_empty(), choices.context_moves.is_empty()){ match (
(true, true) => {} self.context_moves.is_empty(),
(true, false) => { self.context_moves = choices.context_moves } choices.context_moves.is_empty(),
(false, true) => {} ) {
(false, false) => { (true, true) => {}
let mut new_self = vec![]; (true, false) => self.context_moves = choices.context_moves,
for item_self in &self.context_moves { (false, true) => {}
for item_choices in &choices.context_moves { (false, false) => {
new_self.push( let mut new_self = vec![];
(Rc::new(item_self.0.union(&item_choices.0)), for item_self in &self.context_moves {
Rc::new(item_self.1.concat(&item_choices.1))) for item_choices in &choices.context_moves {
); new_self.push((
} Rc::new(item_self.0.union(&item_choices.0)),
} Rc::new(item_self.1.concat(&item_choices.1)),
self.context_moves = new_self; ));
} }
} }
self.context_moves = new_self;
}
}
} }
pub fn iter(&self) -> std::slice::Iter<'_, (Rc<RSset>, Rc<RSprocess>)> { pub fn iter(&self) -> std::slice::Iter<'_, (Rc<RSset>, Rc<RSprocess>)> {
self.context_moves.iter() self.context_moves.iter()
} }
} }
@ -299,26 +335,29 @@ impl IntoIterator for RSchoices {
type IntoIter = std::vec::IntoIter<Self::Item>; type IntoIter = std::vec::IntoIter<Self::Item>;
fn into_iter(self) -> Self::IntoIter { fn into_iter(self) -> Self::IntoIter {
self.context_moves.into_iter() self.context_moves.into_iter()
} }
} }
impl<const N: usize> From<[(Rc<RSset>, Rc<RSprocess>); N]> for RSchoices { impl<const N: usize> From<[(Rc<RSset>, Rc<RSprocess>); N]> for RSchoices {
fn from(arr: [(Rc<RSset>, Rc<RSprocess>); N]) -> Self { fn from(arr: [(Rc<RSset>, Rc<RSprocess>); N]) -> Self {
RSchoices{context_moves: arr.to_vec()} RSchoices {
context_moves: arr.to_vec(),
}
} }
} }
impl From<&[(Rc<RSset>, Rc<RSprocess>)]> for RSchoices { impl From<&[(Rc<RSset>, Rc<RSprocess>)]> for RSchoices {
fn from(arr: &[(Rc<RSset>, Rc<RSprocess>)]) -> Self { fn from(arr: &[(Rc<RSset>, Rc<RSprocess>)]) -> Self {
RSchoices{context_moves: arr.to_vec()} RSchoices {
context_moves: arr.to_vec(),
}
} }
} }
impl From<Vec<(Rc<RSset>, Rc<RSprocess>)>> for RSchoices { impl From<Vec<(Rc<RSset>, Rc<RSprocess>)>> for RSchoices {
fn from(arr: Vec<(Rc<RSset>, Rc<RSprocess>)>) -> Self { fn from(arr: Vec<(Rc<RSset>, Rc<RSprocess>)>) -> Self {
RSchoices{context_moves: arr} RSchoices { context_moves: arr }
} }
} }
@ -332,47 +371,55 @@ pub struct RSenvironment {
impl RSenvironment { impl RSenvironment {
pub fn new() -> RSenvironment { pub fn new() -> RSenvironment {
RSenvironment{definitions: HashMap::new()} RSenvironment {
definitions: HashMap::new(),
}
} }
pub fn get(&self, k: IdType) -> Option<&RSprocess> { pub fn get(&self, k: IdType) -> Option<&RSprocess> {
self.definitions.get(&k) self.definitions.get(&k)
} }
pub fn iter(&self) -> std::collections::hash_map::Iter<'_, u32, RSprocess> { pub fn iter(&self) -> std::collections::hash_map::Iter<'_, u32, RSprocess> {
self.definitions.iter() self.definitions.iter()
} }
pub fn all_elements(&self) -> RSset { pub fn all_elements(&self) -> RSset {
let mut acc = RSset::new(); let mut acc = RSset::new();
for (_, process) in self.definitions.iter() { for (_, process) in self.definitions.iter() {
acc.push(&process.all_elements()); acc.push(&process.all_elements());
} }
acc acc
} }
} }
impl Default for RSenvironment { impl Default for RSenvironment {
fn default() -> Self { fn default() -> Self {
RSenvironment::new() RSenvironment::new()
} }
} }
impl<const N: usize> From<[(IdType, RSprocess); N]> for RSenvironment { impl<const N: usize> From<[(IdType, RSprocess); N]> for RSenvironment {
fn from(arr: [(IdType, RSprocess); N]) -> Self { fn from(arr: [(IdType, RSprocess); N]) -> Self {
RSenvironment{definitions: HashMap::from(arr)} RSenvironment {
definitions: HashMap::from(arr),
}
} }
} }
impl From<&[(IdType, RSprocess)]> for RSenvironment { impl From<&[(IdType, RSprocess)]> for RSenvironment {
fn from(arr: &[(IdType, RSprocess)]) -> Self { fn from(arr: &[(IdType, RSprocess)]) -> Self {
RSenvironment{definitions: HashMap::from_iter(arr.to_vec())} RSenvironment {
definitions: HashMap::from_iter(arr.to_vec()),
}
} }
} }
impl From<Vec<(IdType, RSprocess)>> for RSenvironment { impl From<Vec<(IdType, RSprocess)>> for RSenvironment {
fn from(arr: Vec<(IdType, RSprocess)>) -> Self { fn from(arr: Vec<(IdType, RSprocess)>) -> Self {
RSenvironment{definitions: HashMap::from_iter(arr)} RSenvironment {
definitions: HashMap::from_iter(arr),
}
} }
} }
@ -389,44 +436,48 @@ pub struct RSsystem {
impl RSsystem { impl RSsystem {
pub fn new() -> RSsystem { pub fn new() -> RSsystem {
RSsystem { RSsystem {
delta: Rc::new(RSenvironment::new()), delta: Rc::new(RSenvironment::new()),
available_entities: RSset::new(), available_entities: RSset::new(),
context_process: RSprocess::Nill, context_process: RSprocess::Nill,
reaction_rules: Rc::new(vec![]), reaction_rules: Rc::new(vec![]),
} }
} }
pub fn from(delta: Rc<RSenvironment>, pub fn from(
available_entities: RSset, delta: Rc<RSenvironment>,
context_process: RSprocess, available_entities: RSset,
reaction_rules: Rc<Vec<RSreaction>>) -> RSsystem { context_process: RSprocess,
RSsystem { delta: Rc::clone(&delta), reaction_rules: Rc<Vec<RSreaction>>,
available_entities, ) -> RSsystem {
context_process, RSsystem {
reaction_rules: Rc::clone(&reaction_rules) } delta: Rc::clone(&delta),
available_entities,
context_process,
reaction_rules: Rc::clone(&reaction_rules),
}
} }
pub fn get_delta(&self) -> &Rc<RSenvironment> { pub fn get_delta(&self) -> &Rc<RSenvironment> {
&self.delta &self.delta
} }
pub fn get_available_entities(&self) -> &RSset { pub fn get_available_entities(&self) -> &RSset {
&self.available_entities &self.available_entities
} }
pub fn get_context_process(&self) -> &RSprocess { pub fn get_context_process(&self) -> &RSprocess {
&self.context_process &self.context_process
} }
pub fn get_reaction_rules(&self) -> &Rc<Vec<RSreaction>> { pub fn get_reaction_rules(&self) -> &Rc<Vec<RSreaction>> {
&self.reaction_rules &self.reaction_rules
} }
} }
impl Default for RSsystem { impl Default for RSsystem {
fn default() -> Self { fn default() -> Self {
RSsystem::new() RSsystem::new()
} }
} }
@ -437,7 +488,8 @@ impl Default for RSsystem {
pub struct RSlabel { pub struct RSlabel {
pub available_entities: RSset, pub available_entities: RSset,
pub context: RSset, pub context: RSset,
pub t: RSset, /// union of available_entities and context pub t: RSset,
/// union of available_entities and context
pub reactants: RSset, pub reactants: RSset,
pub reactantsi: RSset, // reactants absent pub reactantsi: RSset, // reactants absent
pub inihibitors: RSset, pub inihibitors: RSset,
@ -447,42 +499,51 @@ pub struct RSlabel {
impl RSlabel { impl RSlabel {
pub fn new() -> Self { pub fn new() -> Self {
RSlabel { available_entities: RSset::new(), RSlabel {
context: RSset::new(), available_entities: RSset::new(),
t: RSset::new(), context: RSset::new(),
reactants: RSset::new(), t: RSset::new(),
reactantsi: RSset::new(), reactants: RSset::new(),
inihibitors: RSset::new(), reactantsi: RSset::new(),
ireactants: RSset::new(), inihibitors: RSset::new(),
products: RSset::new() } ireactants: RSset::new(),
products: RSset::new(),
}
} }
#[allow(clippy::too_many_arguments)] #[allow(clippy::too_many_arguments)]
pub fn from(available_entities: RSset, pub fn from(
context: RSset, available_entities: RSset,
t: RSset, context: RSset,
reactants: RSset, t: RSset,
reactantsi: RSset, reactants: RSset,
inihibitors: RSset, reactantsi: RSset,
ireactants: RSset, inihibitors: RSset,
products: RSset,) -> Self { ireactants: RSset,
RSlabel { available_entities, products: RSset,
context, ) -> Self {
t, RSlabel {
reactants, available_entities,
reactantsi, context,
inihibitors, t,
ireactants, reactants,
products } reactantsi,
inihibitors,
ireactants,
products,
}
} }
pub fn get_context(&self) -> (RSset, RSset, RSset) { pub fn get_context(&self) -> (RSset, RSset, RSset) {
// TODO remove clone? // TODO remove clone?
(self.available_entities.clone(), self.context.clone(), self.t.clone()) (
self.available_entities.clone(),
self.context.clone(),
self.t.clone(),
)
} }
} }
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// RSassertOp // RSassertOp
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
@ -491,7 +552,7 @@ pub enum RSassertOp {
InW, InW,
InR, InR,
InI, InI,
InP InP,
} }
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
@ -504,7 +565,7 @@ pub enum RSassert {
Or(Vec<RSassert>), Or(Vec<RSassert>),
And(Vec<RSassert>), And(Vec<RSassert>),
Sub(RSset, RSassertOp), Sub(RSset, RSassertOp),
NonEmpty(RSassertOp) NonEmpty(RSassertOp),
} }
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
@ -518,5 +579,5 @@ pub enum RSBHML {
Or(Vec<RSBHML>), Or(Vec<RSBHML>),
And(Vec<RSBHML>), And(Vec<RSBHML>),
Diamond(Box<RSassert>, Box<RSBHML>), Diamond(Box<RSassert>, Box<RSBHML>),
Box(Box<RSassert>, Box<RSBHML>) Box(Box<RSassert>, Box<RSBHML>),
} }

View File

@ -10,7 +10,9 @@ pub struct TransitionsIterator<'a> {
} }
impl<'a> TransitionsIterator<'a> { impl<'a> TransitionsIterator<'a> {
pub fn from(system: &'a RSsystem) -> Result<TransitionsIterator<'a>, String> { pub fn from(
system: &'a RSsystem
) -> Result<TransitionsIterator<'a>, String> {
match unfold(system.get_delta(), system.get_context_process()) { match unfold(system.get_delta(), system.get_context_process()) {
Ok(o) => Ok(TransitionsIterator { Ok(o) => Ok(TransitionsIterator {
choices_iterator: o.into_iter(), choices_iterator: o.into_iter(),
@ -38,13 +40,13 @@ impl<'a> Iterator for TransitionsIterator<'a> {
), ),
|acc, reaction| { |acc, reaction| {
if reaction.enabled(&t) { if reaction.enabled(&t) {
( (
acc.0.union(reaction.reactants()), acc.0.union(reaction.reactants()),
acc.1, acc.1,
acc.2.union(reaction.inihibitors()), acc.2.union(reaction.inihibitors()),
acc.3, acc.3,
acc.4.union(reaction.products()), acc.4.union(reaction.products()),
) )
} else { } else {
( (
acc.0, acc.0,

View File

@ -1,8 +1,11 @@
#![allow(dead_code)] #![allow(dead_code)]
use super::structure::{ use super::structure::{RSchoices,
RSchoices, RSenvironment, RSlabel, RSprocess, RSset, RSsystem RSenvironment,
}; RSlabel,
RSprocess,
RSset,
RSsystem};
use super::support_structures::TransitionsIterator; use super::support_structures::TransitionsIterator;
use std::rc::Rc; use std::rc::Rc;
@ -12,87 +15,87 @@ pub fn unfold(
context_process: &RSprocess, context_process: &RSprocess,
) -> Result<RSchoices, String> { ) -> Result<RSchoices, String> {
match context_process { match context_process {
RSprocess::Nill => Ok(RSchoices::new()), RSprocess::Nill => Ok(RSchoices::new()),
RSprocess::RecursiveIdentifier { identifier } => { RSprocess::RecursiveIdentifier { identifier } => {
let newprocess = environment.get(*identifier); let newprocess = environment.get(*identifier);
if let Some(newprocess) = newprocess { if let Some(newprocess) = newprocess {
unfold(environment, newprocess) unfold(environment, newprocess)
} else { } else {
Err(format!("Recursive call to missing symbol: {identifier}")) Err(format!("Recursive call to missing symbol: {identifier}"))
} }
} }
RSprocess::EntitySet { RSprocess::EntitySet {
entities, entities,
next_process, next_process,
} => Ok(RSchoices::from(vec![( } => Ok(RSchoices::from(vec![(
Rc::new(entities.clone()), Rc::new(entities.clone()),
Rc::clone(next_process), Rc::clone(next_process),
)])), )])),
RSprocess::WaitEntity { RSprocess::WaitEntity {
repeat, repeat,
repeated_process: _, repeated_process: _,
next_process, next_process,
} if *repeat <= 0 => unfold(environment, next_process), } if *repeat <= 0 => unfold(environment, next_process),
RSprocess::WaitEntity { RSprocess::WaitEntity {
repeat, repeat,
repeated_process, repeated_process,
next_process, next_process,
} if *repeat == 1 => { } if *repeat == 1 => {
let mut choices1 = unfold(environment, repeated_process)?; let mut choices1 = unfold(environment, repeated_process)?;
choices1.replace(Rc::clone(next_process)); choices1.replace(Rc::clone(next_process));
Ok(choices1) Ok(choices1)
} }
RSprocess::WaitEntity { RSprocess::WaitEntity {
repeat, repeat,
repeated_process, repeated_process,
next_process, next_process,
} => { } => {
let mut choices1 = unfold(environment, repeated_process)?; let mut choices1 = unfold(environment, repeated_process)?;
choices1.replace(Rc::new(RSprocess::WaitEntity { choices1.replace(Rc::new(RSprocess::WaitEntity {
repeat: (*repeat - 1), repeat: (*repeat - 1),
repeated_process: Rc::clone(repeated_process), repeated_process: Rc::clone(repeated_process),
next_process: Rc::clone(next_process), next_process: Rc::clone(next_process),
})); }));
Ok(choices1) Ok(choices1)
} }
RSprocess::Summation { children } => { RSprocess::Summation { children } => {
// short-circuits with try_fold. // short-circuits with try_fold.
children.iter().try_fold(RSchoices::new(), |mut acc, x| { children.iter().try_fold(RSchoices::new(), |mut acc, x| {
match unfold(environment, x) { match unfold(environment, x) {
Ok(mut choices) => { Ok(mut choices) => {
acc.append(&mut choices); acc.append(&mut choices);
Ok(acc) Ok(acc)
} }
Err(e) => Err(e), Err(e) => Err(e),
} }
}) })
} }
RSprocess::NondeterministicChoice { children } => { RSprocess::NondeterministicChoice { children } => {
// short-circuits with try_fold. // short-circuits with try_fold.
if children.is_empty() { if children.is_empty() {
Ok(RSchoices::from(vec![( Ok(RSchoices::from(vec![(
Rc::new(RSset::new()), Rc::new(RSset::new()),
Rc::new(RSprocess::Nill), Rc::new(RSprocess::Nill),
)])) )]))
} else { } else {
children.iter().try_fold(RSchoices::new(), |mut acc, x| { children.iter().try_fold(RSchoices::new(), |mut acc, x| {
acc.shuffle(unfold(environment, x)?); acc.shuffle(unfold(environment, x)?);
Ok(acc) Ok(acc)
}) })
} }
} }
} }
} }
pub fn iterator_transitions<'a>( pub fn iterator_transitions<'a>(
system: &'a RSsystem, system: &'a RSsystem
) -> Result<TransitionsIterator<'a>, String> { ) -> Result<TransitionsIterator<'a>, String> {
TransitionsIterator::from(system) TransitionsIterator::from(system)
} }
// see oneTransition, transition, smartTransition, smartOneTransition // see oneTransition, transition, smartTransition, smartOneTransition
pub fn one_transition( pub fn one_transition(
system: &RSsystem, system: &RSsystem
) -> Result<Option<(RSlabel, RSsystem)>, String> { ) -> Result<Option<(RSlabel, RSsystem)>, String> {
let mut tr = TransitionsIterator::from(system)?; let mut tr = TransitionsIterator::from(system)?;
Ok(tr.next()) Ok(tr.next())
@ -100,23 +103,25 @@ pub fn one_transition(
// see allTransitions, smartAllTransitions // see allTransitions, smartAllTransitions
pub fn all_transitions( pub fn all_transitions(
system: &RSsystem, system: &RSsystem
) -> Result<Vec<(RSlabel, RSsystem)>, String> { ) -> Result<Vec<(RSlabel, RSsystem)>, String> {
let tr = TransitionsIterator::from(system)?; let tr = TransitionsIterator::from(system)?;
Ok(tr.collect::<Vec<_>>()) Ok(tr.collect::<Vec<_>>())
} }
// see oneTarget, smartOneTarget, target, smartTarget // see oneTarget, smartOneTarget, target, smartTarget
pub fn target(system: &RSsystem) -> Result<(i64, RSset), String> { pub fn target(
system: &RSsystem
) -> Result<(i64, RSset), String> {
let current = one_transition(system)?; let current = one_transition(system)?;
if current.is_none() { if current.is_none() {
return Ok((0, system.get_available_entities().clone())); return Ok((0, system.get_available_entities().clone()));
} }
let mut n = 1; let mut n = 1;
let mut current = current.unwrap().1; let mut current = current.unwrap().1;
while let Some((_, next)) = one_transition(&current)? { while let Some((_, next)) = one_transition(&current)? {
current = next; current = next;
n += 1; n += 1;
} }
Ok((n, current.get_available_entities().clone())) Ok((n, current.get_available_entities().clone()))
} }
@ -125,7 +130,7 @@ pub fn target(system: &RSsystem) -> Result<(i64, RSset), String> {
pub fn run(system: RSsystem) -> Result<Vec<Rc<RSsystem>>, String> { pub fn run(system: RSsystem) -> Result<Vec<Rc<RSsystem>>, String> {
let mut res = vec![Rc::new(system)]; let mut res = vec![Rc::new(system)];
while let Some((_, next_sys)) = one_transition(res.last().unwrap())? { while let Some((_, next_sys)) = one_transition(res.last().unwrap())? {
res.push(Rc::new(next_sys)); res.push(Rc::new(next_sys));
} }
Ok(res) Ok(res)
} }
@ -137,14 +142,14 @@ pub fn run_separated(
let mut res = vec![]; let mut res = vec![];
let current = one_transition(system)?; let current = one_transition(system)?;
if current.is_none() { if current.is_none() {
return Ok(res); return Ok(res);
} }
let current = current.unwrap(); let current = current.unwrap();
res.push(current.0.get_context()); res.push(current.0.get_context());
let mut current = current.1; let mut current = current.1;
while let Some((label, next)) = one_transition(&current)? { while let Some((label, next)) = one_transition(&current)? {
current = next; current = next;
res.push(label.get_context()); res.push(label.get_context());
} }
Ok(res) Ok(res)
} }

View File

@ -22,7 +22,7 @@ impl Translator {
impl Default for Translator { impl Default for Translator {
fn default() -> Self { fn default() -> Self {
Translator::new() Translator::new()
} }
} }
@ -47,10 +47,13 @@ impl Translator {
} }
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
use super::{frequency::Frequency, structure::{ use super::{
RSassert, RSassertOp, RSchoices, RSenvironment, RSlabel, RSprocess, frequency::Frequency,
RSreaction, RSset, RSsystem, RSBHML, structure::{
}}; RSBHML, RSassert, RSassertOp, RSchoices, RSenvironment, RSlabel,
RSprocess, RSreaction, RSset, RSsystem,
},
};
use std::fmt; use std::fmt;
#[allow(clippy::large_enum_variant)] #[allow(clippy::large_enum_variant)]
@ -98,9 +101,9 @@ pub enum WithTranslator<'a> {
bhml: &'a RSBHML, bhml: &'a RSBHML,
}, },
Frequency { Frequency {
translator: &'a Translator, translator: &'a Translator,
frequency: &'a Frequency, frequency: &'a Frequency,
} },
} }
macro_rules! from_RS { macro_rules! from_RS {
@ -125,7 +128,12 @@ impl<'a> WithTranslator<'a> {
from_RS!(from_RSchoices, RSchoices, choices, RSchoices); from_RS!(from_RSchoices, RSchoices, choices, RSchoices);
from_RS!(from_RSenvironment, RSenvironment, environment, RSenvironment); from_RS!(
from_RSenvironment,
RSenvironment,
environment,
RSenvironment
);
from_RS!(from_RSsystem, RSsystem, system, RSsystem); from_RS!(from_RSsystem, RSsystem, system, RSsystem);
@ -216,8 +224,11 @@ fn print_process(
let mut it = children.iter().peekable(); let mut it = children.iter().peekable();
while let Some(child) = it.next() { while let Some(child) = it.next() {
if it.peek().is_none() { if it.peek().is_none() {
write!(f, "{}", write!(
WithTranslator::from_RSprocess(translator, child))?; f,
"{}",
WithTranslator::from_RSprocess(translator, child)
)?;
} else { } else {
write!( write!(
f, f,
@ -233,11 +244,17 @@ fn print_process(
let mut it = children.iter().peekable(); let mut it = children.iter().peekable();
while let Some(child) = it.next() { while let Some(child) = it.next() {
if it.peek().is_none() { if it.peek().is_none() {
write!(f, "{}", write!(
WithTranslator::from_RSprocess(translator, child))?; f,
"{}",
WithTranslator::from_RSprocess(translator, child)
)?;
} else { } else {
write!(f, "{}, ", write!(
WithTranslator::from_RSprocess(translator, child))?; f,
"{}, ",
WithTranslator::from_RSprocess(translator, child)
)?;
} }
} }
write!(f, "]") write!(f, "]")
@ -327,15 +344,17 @@ fn print_label(
translator: &Translator, translator: &Translator,
label: &RSlabel label: &RSlabel
) -> fmt::Result { ) -> fmt::Result {
write!(f, "{{available_entities: {}, context: {}, t: {}, reactants: {}, reactantsi: {}, inihibitors: {}, ireactants: {}, products: {}}}", write!(
WithTranslator::from_RSset(translator, &label.available_entities), f,
WithTranslator::from_RSset(translator, &label.context), "{{available_entities: {}, context: {}, t: {}, reactants: {}, reactantsi: {}, inihibitors: {}, ireactants: {}, products: {}}}",
WithTranslator::from_RSset(translator, &label.t), WithTranslator::from_RSset(translator, &label.available_entities),
WithTranslator::from_RSset(translator, &label.reactants), WithTranslator::from_RSset(translator, &label.context),
WithTranslator::from_RSset(translator, &label.reactantsi), WithTranslator::from_RSset(translator, &label.t),
WithTranslator::from_RSset(translator, &label.inihibitors), WithTranslator::from_RSset(translator, &label.reactants),
WithTranslator::from_RSset(translator, &label.ireactants), WithTranslator::from_RSset(translator, &label.reactantsi),
WithTranslator::from_RSset(translator, &label.products), WithTranslator::from_RSset(translator, &label.inihibitors),
WithTranslator::from_RSset(translator, &label.ireactants),
WithTranslator::from_RSset(translator, &label.products),
) )
} }
@ -388,33 +407,33 @@ fn print_frequency(
let mut freq_it = frequency.frequency_map.iter().peekable(); let mut freq_it = frequency.frequency_map.iter().peekable();
while let Some((e, freq)) = freq_it.next() { while let Some((e, freq)) = freq_it.next() {
write!(f, "{} -> ", translator.decode(*e))?; write!(f, "{} -> ", translator.decode(*e))?;
let mut iter = freq.iter() let mut iter = freq
.zip(frequency.totals.iter() .iter()
.zip(frequency.weights.iter())) .zip(frequency.totals.iter().zip(frequency.weights.iter()))
.peekable(); .peekable();
let mut total_freq = 0.; let mut total_freq = 0.;
while let Some((freq_e, (total, weight))) = iter.next() { while let Some((freq_e, (total, weight))) = iter.next() {
let weighted_freq = (*freq_e as f32 * *weight as f32 * 100.)/(*total as f32); let weighted_freq = (*freq_e as f32 * *weight as f32 * 100.) / (*total as f32);
if iter.peek().is_none() {
write!(f, "{weighted_freq:.2}")?;
} else {
write!(f, "{weighted_freq:.2}, ")?;
}
total_freq += weighted_freq;
}
total_freq /= frequency.total_weights() as f32; if iter.peek().is_none() {
write!(f, "{weighted_freq:.2}")?;
} else {
write!(f, "{weighted_freq:.2}, ")?;
}
total_freq += weighted_freq;
}
write!(f, "(total: {total_freq:.2})")?; total_freq /= frequency.total_weights() as f32;
if freq_it.peek().is_some() { write!(f, "(total: {total_freq:.2})")?;
writeln!(f, ",")?;
} if freq_it.peek().is_some() {
writeln!(f, ",")?;
}
} }
write!(f, "]") write!(f, "]")
} }
@ -422,28 +441,50 @@ fn print_frequency(
impl<'a> fmt::Display for WithTranslator<'a> { impl<'a> fmt::Display for WithTranslator<'a> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self { match self {
WithTranslator::RSset { translator, set, } => WithTranslator::RSset {
print_set(f, translator, set), translator,
WithTranslator::RSreaction { translator, reaction, } => set
print_reaction(f, translator, reaction), } => print_set(f, translator, set),
WithTranslator::RSprocess { translator, process, } => WithTranslator::RSreaction {
print_process(f, translator, process), translator,
WithTranslator::RSchoices { translator, choices, } => reaction,
print_choices(f, translator, choices), } => print_reaction(f, translator, reaction),
WithTranslator::RSenvironment { translator, environment, } => WithTranslator::RSprocess {
print_environment(f, translator, environment), translator,
WithTranslator::RSsystem { translator, system, } => process,
print_system(f, translator, system), } => print_process(f, translator, process),
WithTranslator::RSlabel { translator, label, } => WithTranslator::RSchoices {
print_label(f, translator, label), translator,
WithTranslator::RSassertOp { translator, assert_op, } => choices,
print_assert_op(f, translator, assert_op), } => print_choices(f, translator, choices),
WithTranslator::RSassert { translator, assert, } => WithTranslator::RSenvironment {
print_assert(f, translator, assert), translator,
WithTranslator::RSBHML { translator, bhml, } => environment,
print_bhml(f, translator, bhml), } => print_environment(f, translator, environment),
WithTranslator::Frequency { translator, frequency } => WithTranslator::RSsystem {
print_frequency(f, translator, frequency), translator,
system
} => print_system(f, translator, system),
WithTranslator::RSlabel {
translator,
label
} => print_label(f, translator, label),
WithTranslator::RSassertOp {
translator,
assert_op,
} => print_assert_op(f, translator, assert_op),
WithTranslator::RSassert {
translator,
assert
} => print_assert(f, translator, assert),
WithTranslator::RSBHML {
translator,
bhml
} => print_bhml(f, translator, bhml),
WithTranslator::Frequency {
translator,
frequency,
} => print_frequency(f, translator, frequency),
} }
} }
} }

View File

@ -1,4 +1,4 @@
Environment: [x = {a}.y, y =({a}.x + {b}.y)] Environment: [x = {a}.y, y =({a}.nill + {b}.nill)]
Initial Entities: {a, b} Initial Entities: {a, b}
Context: [({a,b}.{a}.{a,c}.x + {a,b}.{a}.{a}.nil)] Context: [({a,b}.{a}.{a,c}.x + {a,b}.{a}.{a}.nil)]
Reactions: ([r: {a,b}, i: {c}, p: {b}]) Reactions: ([r: {a,b}, i: {c}, p: {b}])