formatting with rustfmt
This commit is contained in:
@ -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(())
|
||||||
}
|
}
|
||||||
|
|||||||
10
src/main.rs
10
src/main.rs
@ -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(())
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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))
|
})
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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<_>>>()
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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))
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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;
|
||||||
|
|||||||
@ -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(),
|
||||||
|
|||||||
@ -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(
|
||||||
"============================================================="
|
"============================================================="
|
||||||
);
|
);
|
||||||
|
|||||||
@ -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>),
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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,
|
||||||
|
|||||||
@ -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(¤t)? {
|
while let Some((_, next)) = one_transition(¤t)? {
|
||||||
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(¤t)? {
|
while let Some((label, next)) = one_transition(¤t)? {
|
||||||
current = next;
|
current = next;
|
||||||
res.push(label.get_context());
|
res.push(label.get_context());
|
||||||
}
|
}
|
||||||
Ok(res)
|
Ok(res)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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}])
|
||||||
|
|||||||
Reference in New Issue
Block a user