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,
statistics,
transitions,
perpetual};
#![allow(dead_code)]
use crate::rsprocess::structure::RSsystem;
use crate::rsprocess::translator::{Translator, WithTranslator};
use crate::rsprocess::{frequency, perpetual, statistics, transitions};
use std::env;
use std::fs;
use std::io::prelude::*;
use std::io;
use std::io::prelude::*;
// grammar is defined in main.rs, calling lalrpop_mod! twice, generates twice
// the code
use super::grammar;
fn read_system(
translator: &mut Translator,
path: std::path::PathBuf
) -> std::io::Result<RSsystem> {
fn read_system(translator: &mut Translator, path: std::path::PathBuf) -> std::io::Result<RSsystem> {
// we read the file with a buffer
let f = fs::File::open(path.clone())?;
let mut buf_reader = io::BufReader::new(f);
@ -25,7 +21,9 @@ fn read_system(
buf_reader.read_to_string(&mut contents)?;
// parse
let result = grammar::SystemParser::new().parse(translator, &contents).unwrap();
let result = grammar::SystemParser::new()
.parse(translator, &contents)
.unwrap();
Ok(result)
}
@ -39,7 +37,6 @@ pub fn stats() -> std::io::Result<()> {
path = path.join("testing/first.system");
let system = read_system(&mut translator, path)?;
// print statistics to screan
println!("{}", statistics::of_RSsystem(&translator, &system));
@ -63,12 +60,17 @@ pub fn target() -> std::io::Result<()> {
// the system needs to terminate to return
let res = match transitions::target(&system) {
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!(
"After {} steps we arrive at state:\n{}",
res.0,
WithTranslator::from_RSset(&translator, &res.1));
WithTranslator::from_RSset(&translator, &res.1)
);
Ok(())
}
@ -85,7 +87,10 @@ pub fn run() -> std::io::Result<()> {
// the system needs to terminate to return
let res = match transitions::run_separated(&system) {
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:");
@ -109,7 +114,10 @@ pub fn hoop() -> std::io::Result<()> {
// 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")) {
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:");
@ -131,10 +139,16 @@ pub fn freq() -> std::io::Result<()> {
let res = match frequency::naive_frequency(&system) {
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(())
}

View File

@ -1,5 +1,5 @@
mod rsprocess;
mod examples;
mod rsprocess;
lalrpop_util::lalrpop_mod!(
#[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));
// println!("{}", now.elapsed().as_micros());
examples::stats()?;
// examples::stats()?;
examples::freq()?;
examples::hoop()?;
// examples::hoop()?;
examples::target()?;
// examples::target()?;
examples::run()?;
// examples::run()?;
Ok(())
}

View File

@ -6,7 +6,7 @@
//! inhibitors and products are held.
#![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)
/// otherwise returns None.
@ -29,18 +29,16 @@ 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))
)
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(), |acc, r| {
acc.union_option(compute_step(current_state, r))
})
}

View File

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

View File

@ -1,7 +1,7 @@
#![allow(dead_code)]
use std::collections::HashMap;
use crate::rsprocess::perpetual::lollipops_only_loop_decomposed_q;
use std::collections::HashMap;
use super::perpetual::lollipops_only_loop_named;
use super::structure::{RSreaction, RSset, RSsystem};
@ -12,12 +12,16 @@ use super::translator::IdType;
pub struct Frequency {
pub frequency_map: HashMap<IdType, Vec<u32>>,
pub totals: Vec<usize>,
pub weights: Vec<u32>
pub weights: Vec<u32>,
}
impl Frequency {
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) {
@ -42,7 +46,6 @@ impl Default for Frequency {
}
}
// -----------------------------------------------------------------------------
// see naiveFreq, assume the system is finite, calculate the frequency of
@ -76,7 +79,7 @@ pub fn loop_frequency(system: &RSsystem, symb: IdType) -> Frequency {
pub fn limit_frequency(
q: &[RSset],
reaction_rules: &[RSreaction],
available_entities: &RSset
available_entities: &RSset,
) -> Option<Frequency> {
let mut available_entities = available_entities.clone();
@ -93,18 +96,18 @@ pub fn limit_frequency(
lollipops_only_loop_decomposed_q(q.last().unwrap(),
reaction_rules,
&available_entities)
.iter().for_each(|e| freq.add(e, 0));
.iter()
.for_each(|e| freq.add(e, 0));
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.
pub fn fast_frequency(
q: &[RSset],
reaction_rules: &[RSreaction],
available_entities: &RSset,
weights: &[u32]
weights: &[u32],
) -> Option<Frequency> {
// FIXME: we return the empty frequency or do we not return anything?
let mut available_entities = available_entities.clone();

View File

@ -64,7 +64,8 @@ pub Reactions: Vec<RSreaction> = {
Reaction: RSreaction = {
"[" <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) },
"(" <k: CTX_process> ")" => k,
"(" <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> =>
RSprocess::WaitEntity{ repeat: n,
repeated_process: Rc::new(k1),
next_process: Rc::new(k) },
"nil" => RSprocess::Nill,
<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>
"Context:" <context_process: Context>
"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 transitions;
pub mod perpetual;
pub mod confluence;
pub mod frequency;
pub mod perpetual;
pub mod statistics;
pub mod structure;
pub mod support_structures;
pub mod transitions;
pub mod translator;

View File

@ -1,9 +1,8 @@
#![allow(dead_code)]
use super::classical::compute_all_owned;
use super::translator::IdType;
use super::structure::{RSenvironment, RSprocess, RSreaction, RSset, RSsystem};
use super::translator::IdType;
// returns the prefix and the loop from a trace
fn split<'a>(
@ -34,9 +33,12 @@ fn find_loop(
}
}
// 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 trace = vec![];
loop {
@ -51,7 +53,6 @@ fn find_only_loop(rs: &[RSreaction], entities: RSset, q: &RSset) -> Vec<RSset> {
}
}
// finds the loops and the length of the prefix by simulating the system
fn find_prefix_len_loop(
rs: &[RSreaction],
@ -80,7 +81,11 @@ fn filter_delta<'a>(x: (&IdType, &'a RSprocess)) -> Option<&'a RSset> {
use super::structure::RSprocess::*;
let (id, rest) = x;
if let EntitySet{ entities, next_process} = rest {
if let EntitySet {
entities,
next_process,
} = rest
{
if let RecursiveIdentifier { identifier } = &**next_process {
if identifier == id {
return Some(entities);
@ -90,12 +95,11 @@ fn filter_delta<'a>(x: (&IdType, &'a RSprocess)) -> Option<&'a RSset> {
None
}
// see lollipop
pub fn lollipops_decomposed(
delta: &RSenvironment,
reaction_rules: &[RSreaction],
available_entities: &RSset
available_entities: &RSset,
) -> Vec<(Vec<RSset>, Vec<RSset>)> {
// FIXME: i think we are only interested in "x", not all symbols that
// satisfy X = pre(Q, rec(X))
@ -110,9 +114,11 @@ pub fn lollipops_decomposed(
// see lollipop
pub fn lollipops(system: RSsystem) -> Vec<(Vec<RSset>, Vec<RSset>)> {
lollipops_decomposed(system.get_delta(),
lollipops_decomposed(
system.get_delta(),
system.get_reaction_rules(),
system.get_available_entities())
system.get_available_entities(),
)
}
// see loop
@ -121,18 +127,21 @@ pub fn lollipops_only_loop(system: RSsystem) -> Vec<Vec<RSset>> {
// satisfy X = pre(Q, rec(X))
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| {
find_only_loop(
system.get_reaction_rules(),
system.get_available_entities().clone(),
q);
q,
)
};
filtered.map(find_loop_fn).collect::<Vec<_>>()
}
pub fn lollipops_prefix_len_loop_decomposed(
delta: &RSenvironment,
reaction_rules: &[RSreaction],
available_entities: &RSset
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))
@ -149,7 +158,7 @@ pub fn lollipops_prefix_len_loop_decomposed(
pub fn lollipops_only_loop_decomposed(
delta: &RSenvironment,
reaction_rules: &[RSreaction],
available_entities: &RSset
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))
@ -178,7 +187,11 @@ fn filter_delta_named<'a>(
return None;
}
if let EntitySet{ entities, next_process} = rest {
if let EntitySet {
entities,
next_process,
} = rest
{
if let RecursiveIdentifier { identifier } = &**next_process {
if identifier == id {
return Some(entities);
@ -193,9 +206,12 @@ pub fn lollipops_decomposed_named(
delta: &RSenvironment,
reaction_rules: &[RSreaction],
available_entities: &RSset,
symb: IdType
symb: IdType,
) -> 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,
available_entities.clone(),
@ -209,10 +225,12 @@ pub fn lollipops_named(
system: RSsystem,
symb: IdType
) -> Option<(Vec<RSset>, Vec<RSset>)> {
lollipops_decomposed_named(system.get_delta(),
lollipops_decomposed_named(
system.get_delta(),
system.get_reaction_rules(),
system.get_available_entities(),
symb)
symb,
)
}
// see loop
@ -220,13 +238,19 @@ pub fn lollipops_only_loop_named(
system: RSsystem,
symb: IdType
) -> Option<Vec<RSset>> {
let filtered = system.get_delta().iter()
.filter_map(|x| filter_delta_named(x, &symb)).next();
let filtered = system
.get_delta()
.iter()
.filter_map(|x| filter_delta_named(x, &symb))
.next();
let find_loop_fn =
|q| find_only_loop(system.get_reaction_rules(),
let find_loop_fn = |q| {
find_only_loop(
system.get_reaction_rules(),
system.get_available_entities().clone(),
q);
q,
)
};
filtered.map(find_loop_fn)
}
@ -235,10 +259,12 @@ pub fn lollipops_prefix_len_loop_decomposed_named(
delta: &RSenvironment,
reaction_rules: &[RSreaction],
available_entities: &RSset,
symb: IdType
symb: IdType,
) -> Option<(usize, 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_prefix_len_loop(reaction_rules,
available_entities.clone(),
@ -252,10 +278,12 @@ pub fn lollipops_only_loop_decomposed_named(
delta: &RSenvironment,
reaction_rules: &[RSreaction],
available_entities: &RSset,
symb: IdType
symb: IdType,
) -> Option<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_only_loop(reaction_rules,
available_entities.clone(),

View File

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

View File

@ -1,39 +1,47 @@
#![allow(dead_code)]
use super::translator::IdType;
use std::collections::{BTreeSet, HashMap, VecDeque};
use std::hash::Hash;
use std::rc::Rc;
use super::translator::{IdType};
// -----------------------------------------------------------------------------
// RSset
// -----------------------------------------------------------------------------
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct RSset {
identifiers: BTreeSet<IdType>
identifiers: BTreeSet<IdType>,
}
impl<const N: usize> From<[IdType; N]> for RSset {
fn from(arr: [IdType; N]) -> Self {
RSset{identifiers: BTreeSet::from(arr)}
RSset {
identifiers: BTreeSet::from(arr),
}
}
}
impl From<&[IdType]> for RSset {
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 {
fn from(arr: Vec<IdType>) -> Self {
RSset{identifiers: BTreeSet::from_iter(arr)}
RSset {
identifiers: BTreeSet::from_iter(arr),
}
}
}
impl RSset {
pub fn new() -> Self {
RSset{identifiers: BTreeSet::new()}
RSset {
identifiers: BTreeSet::new(),
}
}
pub fn is_subset(&self, b: &RSset) -> bool {
@ -61,7 +69,9 @@ impl RSset {
pub fn intersection(&self, b: &RSset) -> RSset {
// TODO maybe find more efficient way without copy/clone
let res: BTreeSet<_> = b.identifiers.intersection(&self.identifiers)
let res: BTreeSet<_> = b
.identifiers
.intersection(&self.identifiers)
.copied()
.collect();
RSset { identifiers: res }
@ -69,7 +79,9 @@ impl RSset {
pub fn subtraction(&self, b: &RSset) -> RSset {
// TODO maybe find more efficient way without copy/clone
let res: BTreeSet<_> = self.identifiers.difference(&b.identifiers)
let res: BTreeSet<_> = self
.identifiers
.difference(&b.identifiers)
.copied()
.collect();
RSset { identifiers: res }
@ -111,7 +123,6 @@ impl IntoIterator for RSset {
}
}
// -----------------------------------------------------------------------------
// RSreaction
// -----------------------------------------------------------------------------
@ -119,20 +130,24 @@ impl IntoIterator for RSset {
pub struct RSreaction {
reactants: RSset,
inihibitors: RSset,
products: RSset
products: RSset,
}
impl RSreaction {
pub fn new() -> Self {
RSreaction{ reactants: RSset::new(),
RSreaction {
reactants: RSset::new(),
inihibitors: RSset::new(),
products: RSset::new(), }
products: RSset::new(),
}
}
pub fn from(reactants: RSset, inihibitors: RSset, products: RSset) -> Self {
RSreaction{ reactants,
RSreaction {
reactants,
inihibitors,
products }
products,
}
}
// see enable
@ -164,47 +179,53 @@ impl Default for RSreaction {
}
}
// -----------------------------------------------------------------------------
// RSprocess
// -----------------------------------------------------------------------------
#[derive(Clone, Debug)]
pub enum RSprocess {
Nill,
RecursiveIdentifier{ identifier: IdType },
EntitySet{ entities: RSset,
next_process: Rc<RSprocess> },
WaitEntity{ repeat: i64,
RecursiveIdentifier {
identifier: IdType,
},
EntitySet {
entities: RSset,
next_process: Rc<RSprocess>,
},
WaitEntity {
repeat: i64,
repeated_process: Rc<RSprocess>,
next_process: Rc<RSprocess> },
Summation{ children: Vec<Rc<RSprocess>> },
NondeterministicChoice{ children: Vec<Rc<RSprocess>> }
next_process: Rc<RSprocess>,
},
Summation {
children: Vec<Rc<RSprocess>>,
},
NondeterministicChoice {
children: Vec<Rc<RSprocess>>,
},
}
impl RSprocess {
// TODO: remove all the clone()
pub fn concat(&self, new: &RSprocess) -> RSprocess {
match (self, new) {
(RSprocess::NondeterministicChoice{children: c1},
RSprocess::NondeterministicChoice{children: c2}) => {
RSprocess::NondeterministicChoice {
children: [c1.clone(),
c2.clone()].concat()
}
(
RSprocess::NondeterministicChoice { children: c1 },
RSprocess::NondeterministicChoice { children: c2 },
) => RSprocess::NondeterministicChoice {
children: [c1.clone(), c2.clone()].concat(),
},
(RSprocess::NondeterministicChoice{children}, new) |
(new, RSprocess::NondeterministicChoice{children}) => {
(RSprocess::NondeterministicChoice { children }, new)
| (new, RSprocess::NondeterministicChoice { children }) => {
let mut new_children = children.clone();
new_children.push(Rc::new(new.clone()));
RSprocess::NondeterministicChoice{ children: new_children }
},
(_, _) => {
RSprocess::NondeterministicChoice {
children: vec![Rc::new(self.clone()),
Rc::new(new.clone())]
children: new_children,
}
}
(_, _) => RSprocess::NondeterministicChoice {
children: vec![Rc::new(self.clone()), Rc::new(new.clone())],
},
}
}
@ -216,11 +237,18 @@ impl RSprocess {
match el {
Self::Nill => {}
Self::RecursiveIdentifier { identifier: _ } => {}
Self::EntitySet { entities, next_process } => {
Self::EntitySet {
entities,
next_process,
} => {
elements.push(entities);
queue.push_back(next_process);
}
Self::WaitEntity { repeat: _, repeated_process, next_process } => {
Self::WaitEntity {
repeat: _,
repeated_process,
next_process,
} => {
queue.push_back(repeated_process);
queue.push_back(next_process);
}
@ -245,17 +273,21 @@ impl RSprocess {
// -----------------------------------------------------------------------------
#[derive(Clone, Debug)]
pub struct RSchoices {
context_moves: Vec<(Rc<RSset>, Rc<RSprocess>)>
context_moves: Vec<(Rc<RSset>, Rc<RSprocess>)>,
}
impl RSchoices {
pub fn new() -> Self {
RSchoices{ context_moves: vec![] }
RSchoices {
context_moves: vec![],
}
}
pub fn new_not_empty() -> Self {
RSchoices{ context_moves: vec![(Rc::new(RSset::new()),
Rc::new(RSprocess::Nill))] }
RSchoices {
context_moves: vec![(Rc::new(RSset::new()),
Rc::new(RSprocess::Nill))],
}
}
pub fn append(&mut self, a: &mut RSchoices) {
@ -263,25 +295,29 @@ impl RSchoices {
}
pub fn replace(&mut self, a: Rc<RSprocess>) {
self.context_moves =
self.context_moves
self.context_moves = self
.context_moves
.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) {
match (self.context_moves.is_empty(), choices.context_moves.is_empty()){
match (
self.context_moves.is_empty(),
choices.context_moves.is_empty(),
) {
(true, true) => {}
(true, false) => { self.context_moves = choices.context_moves }
(true, false) => self.context_moves = choices.context_moves,
(false, true) => {}
(false, false) => {
let mut new_self = vec![];
for item_self in &self.context_moves {
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)))
);
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;
@ -303,16 +339,19 @@ impl IntoIterator for RSchoices {
}
}
impl<const N: usize> From<[(Rc<RSset>, Rc<RSprocess>); N]> for RSchoices {
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 {
fn from(arr: &[(Rc<RSset>, Rc<RSprocess>)]) -> Self {
RSchoices{context_moves: arr.to_vec()}
RSchoices {
context_moves: arr.to_vec(),
}
}
}
@ -332,7 +371,9 @@ pub struct RSenvironment {
impl RSenvironment {
pub fn new() -> RSenvironment {
RSenvironment{definitions: HashMap::new()}
RSenvironment {
definitions: HashMap::new(),
}
}
pub fn get(&self, k: IdType) -> Option<&RSprocess> {
@ -360,19 +401,25 @@ impl Default for RSenvironment {
impl<const N: usize> From<[(IdType, RSprocess); N]> for RSenvironment {
fn from(arr: [(IdType, RSprocess); N]) -> Self {
RSenvironment{definitions: HashMap::from(arr)}
RSenvironment {
definitions: HashMap::from(arr),
}
}
}
impl From<&[(IdType, RSprocess)]> for RSenvironment {
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 {
fn from(arr: Vec<(IdType, RSprocess)>) -> Self {
RSenvironment{definitions: HashMap::from_iter(arr)}
RSenvironment {
definitions: HashMap::from_iter(arr),
}
}
}
@ -397,14 +444,18 @@ impl RSsystem {
}
}
pub fn from(delta: Rc<RSenvironment>,
pub fn from(
delta: Rc<RSenvironment>,
available_entities: RSset,
context_process: RSprocess,
reaction_rules: Rc<Vec<RSreaction>>) -> RSsystem {
RSsystem { delta: Rc::clone(&delta),
reaction_rules: Rc<Vec<RSreaction>>,
) -> RSsystem {
RSsystem {
delta: Rc::clone(&delta),
available_entities,
context_process,
reaction_rules: Rc::clone(&reaction_rules) }
reaction_rules: Rc::clone(&reaction_rules),
}
}
pub fn get_delta(&self) -> &Rc<RSenvironment> {
@ -437,7 +488,8 @@ impl Default for RSsystem {
pub struct RSlabel {
pub available_entities: 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 reactantsi: RSset, // reactants absent
pub inihibitors: RSset,
@ -447,42 +499,51 @@ pub struct RSlabel {
impl RSlabel {
pub fn new() -> Self {
RSlabel { available_entities: RSset::new(),
RSlabel {
available_entities: RSset::new(),
context: RSset::new(),
t: RSset::new(),
reactants: RSset::new(),
reactantsi: RSset::new(),
inihibitors: RSset::new(),
ireactants: RSset::new(),
products: RSset::new() }
products: RSset::new(),
}
}
#[allow(clippy::too_many_arguments)]
pub fn from(available_entities: RSset,
pub fn from(
available_entities: RSset,
context: RSset,
t: RSset,
reactants: RSset,
reactantsi: RSset,
inihibitors: RSset,
ireactants: RSset,
products: RSset,) -> Self {
RSlabel { available_entities,
products: RSset,
) -> Self {
RSlabel {
available_entities,
context,
t,
reactants,
reactantsi,
inihibitors,
ireactants,
products }
products,
}
}
pub fn get_context(&self) -> (RSset, RSset, RSset) {
// TODO remove clone?
(self.available_entities.clone(), self.context.clone(), self.t.clone())
(
self.available_entities.clone(),
self.context.clone(),
self.t.clone(),
)
}
}
// -----------------------------------------------------------------------------
// RSassertOp
// -----------------------------------------------------------------------------
@ -491,7 +552,7 @@ pub enum RSassertOp {
InW,
InR,
InI,
InP
InP,
}
// -----------------------------------------------------------------------------
@ -504,7 +565,7 @@ pub enum RSassert {
Or(Vec<RSassert>),
And(Vec<RSassert>),
Sub(RSset, RSassertOp),
NonEmpty(RSassertOp)
NonEmpty(RSassertOp),
}
// -----------------------------------------------------------------------------
@ -518,5 +579,5 @@ pub enum RSBHML {
Or(Vec<RSBHML>),
And(Vec<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> {
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()) {
Ok(o) => Ok(TransitionsIterator {
choices_iterator: o.into_iter(),

View File

@ -1,8 +1,11 @@
#![allow(dead_code)]
use super::structure::{
RSchoices, RSenvironment, RSlabel, RSprocess, RSset, RSsystem
};
use super::structure::{RSchoices,
RSenvironment,
RSlabel,
RSprocess,
RSset,
RSsystem};
use super::support_structures::TransitionsIterator;
use std::rc::Rc;
@ -85,14 +88,14 @@ pub fn unfold(
}
pub fn iterator_transitions<'a>(
system: &'a RSsystem,
system: &'a RSsystem
) -> Result<TransitionsIterator<'a>, String> {
TransitionsIterator::from(system)
}
// see oneTransition, transition, smartTransition, smartOneTransition
pub fn one_transition(
system: &RSsystem,
system: &RSsystem
) -> Result<Option<(RSlabel, RSsystem)>, String> {
let mut tr = TransitionsIterator::from(system)?;
Ok(tr.next())
@ -100,14 +103,16 @@ pub fn one_transition(
// see allTransitions, smartAllTransitions
pub fn all_transitions(
system: &RSsystem,
system: &RSsystem
) -> Result<Vec<(RSlabel, RSsystem)>, String> {
let tr = TransitionsIterator::from(system)?;
Ok(tr.collect::<Vec<_>>())
}
// 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)?;
if current.is_none() {
return Ok((0, system.get_available_entities().clone()));

View File

@ -47,10 +47,13 @@ impl Translator {
}
// -----------------------------------------------------------------------------
use super::{frequency::Frequency, structure::{
RSassert, RSassertOp, RSchoices, RSenvironment, RSlabel, RSprocess,
RSreaction, RSset, RSsystem, RSBHML,
}};
use super::{
frequency::Frequency,
structure::{
RSBHML, RSassert, RSassertOp, RSchoices, RSenvironment, RSlabel,
RSprocess, RSreaction, RSset, RSsystem,
},
};
use std::fmt;
#[allow(clippy::large_enum_variant)]
@ -100,7 +103,7 @@ pub enum WithTranslator<'a> {
Frequency {
translator: &'a Translator,
frequency: &'a Frequency,
}
},
}
macro_rules! from_RS {
@ -125,7 +128,12 @@ impl<'a> WithTranslator<'a> {
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);
@ -216,8 +224,11 @@ fn print_process(
let mut it = children.iter().peekable();
while let Some(child) = it.next() {
if it.peek().is_none() {
write!(f, "{}",
WithTranslator::from_RSprocess(translator, child))?;
write!(
f,
"{}",
WithTranslator::from_RSprocess(translator, child)
)?;
} else {
write!(
f,
@ -233,11 +244,17 @@ fn print_process(
let mut it = children.iter().peekable();
while let Some(child) = it.next() {
if it.peek().is_none() {
write!(f, "{}",
WithTranslator::from_RSprocess(translator, child))?;
write!(
f,
"{}",
WithTranslator::from_RSprocess(translator, child)
)?;
} else {
write!(f, "{}, ",
WithTranslator::from_RSprocess(translator, child))?;
write!(
f,
"{}, ",
WithTranslator::from_RSprocess(translator, child)
)?;
}
}
write!(f, "]")
@ -327,7 +344,9 @@ fn print_label(
translator: &Translator,
label: &RSlabel
) -> fmt::Result {
write!(f, "{{available_entities: {}, context: {}, t: {}, reactants: {}, reactantsi: {}, inihibitors: {}, ireactants: {}, products: {}}}",
write!(
f,
"{{available_entities: {}, context: {}, t: {}, reactants: {}, reactantsi: {}, inihibitors: {}, ireactants: {}, products: {}}}",
WithTranslator::from_RSset(translator, &label.available_entities),
WithTranslator::from_RSset(translator, &label.context),
WithTranslator::from_RSset(translator, &label.t),
@ -390,9 +409,9 @@ fn print_frequency(
while let Some((e, freq)) = freq_it.next() {
write!(f, "{} -> ", translator.decode(*e))?;
let mut iter = freq.iter()
.zip(frequency.totals.iter()
.zip(frequency.weights.iter()))
let mut iter = freq
.iter()
.zip(frequency.totals.iter().zip(frequency.weights.iter()))
.peekable();
let mut total_freq = 0.;
@ -422,28 +441,50 @@ fn print_frequency(
impl<'a> fmt::Display for WithTranslator<'a> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
WithTranslator::RSset { translator, set, } =>
print_set(f, translator, set),
WithTranslator::RSreaction { translator, reaction, } =>
print_reaction(f, translator, reaction),
WithTranslator::RSprocess { translator, process, } =>
print_process(f, translator, process),
WithTranslator::RSchoices { translator, choices, } =>
print_choices(f, translator, choices),
WithTranslator::RSenvironment { translator, environment, } =>
print_environment(f, translator, environment),
WithTranslator::RSsystem { 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),
WithTranslator::RSset {
translator,
set
} => print_set(f, translator, set),
WithTranslator::RSreaction {
translator,
reaction,
} => print_reaction(f, translator, reaction),
WithTranslator::RSprocess {
translator,
process,
} => print_process(f, translator, process),
WithTranslator::RSchoices {
translator,
choices,
} => print_choices(f, translator, choices),
WithTranslator::RSenvironment {
translator,
environment,
} => print_environment(f, translator, environment),
WithTranslator::RSsystem {
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}
Context: [({a,b}.{a}.{a,c}.x + {a,b}.{a}.{a}.nil)]
Reactions: ([r: {a,b}, i: {c}, p: {b}])