Starting to convert main_do, statistics, frequency not working
frequency not working, also need to look into perpetual better
This commit is contained in:
@ -1,11 +1,22 @@
|
||||
use std::rc::Rc;
|
||||
use std::str::FromStr;
|
||||
use lalrpop_util::ParseError;
|
||||
use crate::rsprocess::structure::{RSset, RSprocess, RSenvironment, RSassert, RSassertOp, RSBHML};
|
||||
use crate::rsprocess::structure::{RSset,
|
||||
RSprocess,
|
||||
RSenvironment,
|
||||
RSassert,
|
||||
RSassertOp,
|
||||
RSBHML,
|
||||
RSsystem,
|
||||
RSreaction};
|
||||
use crate::rsprocess::translator::{Translator, IdType};
|
||||
|
||||
grammar(translator: &mut Translator);
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Helpers
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
// matches words (letter followed by numbers, letters or _)
|
||||
Literal = { r"[[:alpha:]][[:word:]]*" };
|
||||
|
||||
@ -26,7 +37,9 @@ Separeted<T, C>: Vec<T> = {
|
||||
}
|
||||
};
|
||||
|
||||
// ----- SetParser -----
|
||||
// -----------------------------------------------------------------------------
|
||||
// SetParser
|
||||
// -----------------------------------------------------------------------------
|
||||
pub Set: RSset = {
|
||||
<s: Set_of_entities> => s
|
||||
};
|
||||
@ -38,18 +51,31 @@ Set_of_entities: RSset = {
|
||||
RSset::from(t.into_iter().map(|t| translator.encode(t)).collect::<Vec<_>>())
|
||||
};
|
||||
|
||||
// ----- ContextParser -----
|
||||
pub Context: Box<RSprocess> = {
|
||||
// "[" "]" => Box::new(RSprocess::Nill),
|
||||
// "[" <t: CTX_process> "]" => Box::new(t),
|
||||
// "[" <t: Separeted<Boxed_CTX_process, ",">> "]" =>
|
||||
// Box::new(RSprocess::NondeterministicChoice{ children: t })
|
||||
|
||||
"[" "]" => Box::new(RSprocess::NondeterministicChoice{ children: vec![] }),
|
||||
// -----------------------------------------------------------------------------
|
||||
// ReactionParser
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
pub Reactions: Vec<RSreaction> = {
|
||||
"(" ")" => vec![],
|
||||
"(" <r: Reaction> ")" => vec![r],
|
||||
"(" <s: Separeted<Reaction, ";">> ")" => s
|
||||
}
|
||||
|
||||
Reaction: RSreaction = {
|
||||
"[" <r: Set> "," <i: Set> "," <p: Set> "]" => RSreaction::from(r, i, p),
|
||||
"[" "r:" <r: Set> "," "i:" <i: Set> "," "p:" <p: Set> "]" => RSreaction::from(r, i, p),
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// ContextParser
|
||||
// -----------------------------------------------------------------------------
|
||||
pub Context: RSprocess = {
|
||||
"[" "]" => RSprocess::NondeterministicChoice{ children: vec![] },
|
||||
"[" <t: CTX_process> "]" =>
|
||||
Box::new(RSprocess::NondeterministicChoice{children: vec![Rc::new(t)]}),
|
||||
RSprocess::NondeterministicChoice{children: vec![Rc::new(t)]},
|
||||
"[" <t: Separeted<Boxed_CTX_process, ",">> "]" =>
|
||||
Box::new(RSprocess::NondeterministicChoice{ children: t })
|
||||
RSprocess::NondeterministicChoice{ children: t }
|
||||
};
|
||||
|
||||
Boxed_CTX_process: Rc<RSprocess> = {
|
||||
@ -71,7 +97,9 @@ CTX_process: RSprocess = {
|
||||
RSprocess::RecursiveIdentifier{ identifier: translator.encode(identifier) }
|
||||
};
|
||||
|
||||
// ----- EnvironmentParser -----
|
||||
// -----------------------------------------------------------------------------
|
||||
// EnvironmentParser
|
||||
// -----------------------------------------------------------------------------
|
||||
pub Environment: Box<RSenvironment> = {
|
||||
"[" "]" => Box::new(RSenvironment::new()),
|
||||
"[" <t:Env_term> "]" => Box::new(RSenvironment::from(vec![t])),
|
||||
@ -83,7 +111,9 @@ Env_term: (IdType, RSprocess) = {
|
||||
(translator.encode(identifier), k)
|
||||
};
|
||||
|
||||
// ----- AssertParser -----
|
||||
// -----------------------------------------------------------------------------
|
||||
// AssertParser
|
||||
// -----------------------------------------------------------------------------
|
||||
pub Assert: Box<RSassert> = {
|
||||
<f: Formula_Assert> => Box::new(f)
|
||||
};
|
||||
@ -104,7 +134,9 @@ Formula_Assert: RSassert = {
|
||||
"?" "inP" => RSassert::NonEmpty(RSassertOp::InP),
|
||||
};
|
||||
|
||||
// ----- BHMLParser -----
|
||||
// -----------------------------------------------------------------------------
|
||||
// BHMLParser
|
||||
// -----------------------------------------------------------------------------
|
||||
pub BHML: Box<RSBHML> = {
|
||||
<g: Formula_BHML> => Box::new(g)
|
||||
};
|
||||
@ -119,3 +151,19 @@ Formula_BHML: RSBHML = {
|
||||
"[" <f: Formula_Assert> "]" <g: Formula_BHML> =>
|
||||
RSBHML::Box(Box::new(f), Box::new(g)),
|
||||
};
|
||||
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// File Parsing
|
||||
// -----------------------------------------------------------------------------
|
||||
// system
|
||||
// a system is an environment, a set of entities as initial state, a context and
|
||||
// a set of reaction rules.
|
||||
|
||||
pub System: RSsystem = {
|
||||
"Environment:" <delta: Environment>
|
||||
"Initial Entities:" <available_entities: Set>
|
||||
"Context:" <context_process: Context>
|
||||
"Reactions:" <reaction_rules: Reactions>
|
||||
=> RSsystem::from(delta.into(), available_entities, context_process, Rc::new(reaction_rules))
|
||||
}
|
||||
|
||||
@ -6,3 +6,4 @@ pub mod transitions;
|
||||
pub mod perpetual;
|
||||
pub mod confluence;
|
||||
pub mod frequency;
|
||||
pub mod statistics;
|
||||
|
||||
134
src/rsprocess/statistics.rs
Normal file
134
src/rsprocess/statistics.rs
Normal file
@ -0,0 +1,134 @@
|
||||
#![allow(dead_code)]
|
||||
|
||||
use super::structure::RSset;
|
||||
use super::structure::RSsystem;
|
||||
use super::translator::{Translator, WithTranslator};
|
||||
|
||||
#[allow(non_snake_case)]
|
||||
pub fn of_RSsystem<'a>(translator: &'a Translator, system: &'a RSsystem) -> String {
|
||||
let mut result: String = "Statistics:\n".into();
|
||||
result.push_str(
|
||||
"=============================================================\n"
|
||||
);
|
||||
result.push_str(
|
||||
&format!("the initial state has {} entities:\n",
|
||||
system.get_available_entities().len())
|
||||
);
|
||||
result.push_str(
|
||||
&format!("{}\n",
|
||||
WithTranslator::from_RSset(translator,
|
||||
system.get_available_entities()))
|
||||
);
|
||||
|
||||
let reactants =
|
||||
system
|
||||
.get_reaction_rules()
|
||||
.iter()
|
||||
.fold(RSset::new(), |acc, new| acc.union(new.reactants()));
|
||||
result.push_str(
|
||||
&format!("The reactants are {}:\n{}\n",
|
||||
reactants.len(),
|
||||
WithTranslator::from_RSset(translator, &reactants))
|
||||
);
|
||||
|
||||
let inhibitors =
|
||||
system
|
||||
.get_reaction_rules()
|
||||
.iter()
|
||||
.fold(RSset::new(), |acc, new| acc.union(new.inihibitors()));
|
||||
result.push_str(
|
||||
&format!("The inhibitors are {}:\n{}\n",
|
||||
inhibitors.len(),
|
||||
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 total = reactants.union(&inhibitors.union(&products));
|
||||
result.push_str(
|
||||
&format!("The reactions involve {} entities:\n{}\n",
|
||||
total.len(),
|
||||
WithTranslator::from_RSset(translator, &total))
|
||||
);
|
||||
|
||||
let entities_env = system.get_delta().all_elements();
|
||||
result.push_str(
|
||||
&format!("The environment involves {} entities:\n{}\n",
|
||||
entities_env.len(),
|
||||
WithTranslator::from_RSset(translator, &entities_env))
|
||||
);
|
||||
|
||||
let entities_context = system.get_context_process().all_elements();
|
||||
result.push_str(
|
||||
&format!("The context involves {} entities:\n{}\n",
|
||||
entities_context.len(),
|
||||
WithTranslator::from_RSset(translator, &entities_context))
|
||||
);
|
||||
|
||||
let entities_all = total.union(&entities_env)
|
||||
.union(&entities_context)
|
||||
.union(system.get_available_entities());
|
||||
|
||||
result.push_str(
|
||||
&format!("The whole RS involves {} entities:\n{}\n",
|
||||
entities_all.len(),
|
||||
WithTranslator::from_RSset(translator, &entities_all))
|
||||
);
|
||||
|
||||
let possible_e = products.union(system.get_available_entities())
|
||||
.union(&entities_context);
|
||||
let missing_e = reactants.subtraction(&possible_e);
|
||||
result.push_str(
|
||||
&format!("There are {} reactants that will never be available:\n{}\n",
|
||||
missing_e.len(),
|
||||
WithTranslator::from_RSset(translator, &missing_e))
|
||||
);
|
||||
|
||||
let entities_not_needed = entities_context.subtraction(&total);
|
||||
result.push_str(
|
||||
&format!("The context can provide {} entities that will never be used:\n{}\n",
|
||||
entities_not_needed.len(),
|
||||
WithTranslator::from_RSset(translator, &entities_not_needed))
|
||||
);
|
||||
|
||||
result.push_str(
|
||||
&format!("There are {} reactions in total.\n",
|
||||
system.get_reaction_rules().len())
|
||||
);
|
||||
|
||||
let mut admissible_reactions = vec![];
|
||||
let mut nonadmissible_reactions = vec![];
|
||||
|
||||
for reaction in system.get_reaction_rules().iter() {
|
||||
if reaction.reactants().is_disjoint(&missing_e) {
|
||||
admissible_reactions.push(reaction);
|
||||
} else {
|
||||
nonadmissible_reactions.push(reaction);
|
||||
}
|
||||
}
|
||||
|
||||
result.push_str(
|
||||
&format!("- the applicable reactions are {}.\n",
|
||||
admissible_reactions.len())
|
||||
);
|
||||
|
||||
result.push_str(
|
||||
&format!("- there are {} reactions that will never be enabled.\n",
|
||||
nonadmissible_reactions.len())
|
||||
);
|
||||
result.push_str(
|
||||
"============================================================="
|
||||
);
|
||||
|
||||
result
|
||||
}
|
||||
@ -1,6 +1,6 @@
|
||||
#![allow(dead_code)]
|
||||
|
||||
use std::collections::{BTreeSet, HashMap, HashSet};
|
||||
use std::collections::{BTreeSet, HashMap, HashSet, VecDeque};
|
||||
use std::hash::{Hash, Hasher};
|
||||
use std::rc::Rc;
|
||||
use super::translator::{IdType};
|
||||
@ -75,13 +75,31 @@ impl RSset {
|
||||
RSset { identifiers: res }
|
||||
}
|
||||
|
||||
pub fn hashset(&self) -> &BTreeSet<IdType> {
|
||||
pub fn set(&self) -> &BTreeSet<IdType> {
|
||||
&self.identifiers
|
||||
}
|
||||
|
||||
pub fn iter(&self) -> std::collections::btree_set::Iter<'_, IdType> {
|
||||
self.identifiers.iter()
|
||||
}
|
||||
|
||||
pub fn len(&self) -> usize {
|
||||
self.identifiers.len()
|
||||
}
|
||||
|
||||
pub fn insert(&mut self, el: IdType) -> bool {
|
||||
self.identifiers.insert(el)
|
||||
}
|
||||
|
||||
pub fn push(&mut self, b: &RSset) {
|
||||
self.identifiers.extend(b.iter())
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for RSset {
|
||||
fn default() -> Self {
|
||||
RSset::new()
|
||||
}
|
||||
}
|
||||
|
||||
impl IntoIterator for RSset {
|
||||
@ -140,6 +158,12 @@ impl RSreaction {
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for RSreaction {
|
||||
fn default() -> Self {
|
||||
RSreaction::new()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
@ -183,8 +207,42 @@ impl RSprocess {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn all_elements(&self) -> RSset {
|
||||
let mut queue = VecDeque::from([self]);
|
||||
let mut elements = RSset::new();
|
||||
|
||||
while let Some(el) = queue.pop_front() {
|
||||
match el {
|
||||
Self::Nill => {}
|
||||
Self::RecursiveIdentifier { identifier: _ } => {}
|
||||
Self::EntitySet { entities, next_process } => {
|
||||
elements.push(entities);
|
||||
queue.push_back(next_process);
|
||||
}
|
||||
Self::WaitEntity { repeat: _, repeated_process, next_process } => {
|
||||
queue.push_back(repeated_process);
|
||||
queue.push_back(next_process);
|
||||
}
|
||||
Self::Summation { children } => {
|
||||
for c in children {
|
||||
queue.push_back(c);
|
||||
}
|
||||
}
|
||||
Self::NondeterministicChoice { children } => {
|
||||
for c in children {
|
||||
queue.push_back(c);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
elements
|
||||
}
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// RSchoices
|
||||
// -----------------------------------------------------------------------------
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct RSchoices {
|
||||
context_moves: Vec<(Rc<RSset>, Rc<RSprocess>)>
|
||||
@ -284,6 +342,20 @@ impl RSenvironment {
|
||||
pub fn iter(&self) -> std::collections::hash_map::Iter<'_, u32, RSprocess> {
|
||||
self.definitions.iter()
|
||||
}
|
||||
|
||||
pub fn all_elements(&self) -> RSset {
|
||||
let mut acc = RSset::new();
|
||||
for (_, process) in self.definitions.iter() {
|
||||
acc.push(&process.all_elements());
|
||||
}
|
||||
acc
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for RSenvironment {
|
||||
fn default() -> Self {
|
||||
RSenvironment::new()
|
||||
}
|
||||
}
|
||||
|
||||
impl<const N: usize> From<[(IdType, RSprocess); N]> for RSenvironment {
|
||||
@ -352,6 +424,12 @@ impl RSsystem {
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for RSsystem {
|
||||
fn default() -> Self {
|
||||
RSsystem::new()
|
||||
}
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// RSsystem
|
||||
// -----------------------------------------------------------------------------
|
||||
@ -361,9 +439,9 @@ pub struct RSlabel {
|
||||
pub context: RSset,
|
||||
pub t: RSset, /// union of available_entities and context
|
||||
pub reactants: RSset,
|
||||
pub reactantsi: RSset,
|
||||
pub reactantsi: RSset, // reactants absent
|
||||
pub inihibitors: RSset,
|
||||
pub ireactants: RSset,
|
||||
pub ireactants: RSset, // inhibitors present
|
||||
pub products: RSset,
|
||||
}
|
||||
|
||||
@ -399,7 +477,7 @@ impl RSlabel {
|
||||
}
|
||||
|
||||
pub fn get_context(&self) -> (RSset, RSset, RSset) {
|
||||
// FIXME clone?
|
||||
// TODO remove clone?
|
||||
(self.available_entities.clone(), self.context.clone(), self.t.clone())
|
||||
}
|
||||
}
|
||||
|
||||
@ -20,6 +20,12 @@ impl Translator {
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for Translator {
|
||||
fn default() -> Self {
|
||||
Translator::new()
|
||||
}
|
||||
}
|
||||
|
||||
impl Translator {
|
||||
pub fn encode(&mut self, s: impl Into<String>) -> IdType {
|
||||
let s = s.into();
|
||||
@ -144,7 +150,7 @@ fn print_set(
|
||||
set: &RSset
|
||||
) -> fmt::Result {
|
||||
write!(f, "{{")?;
|
||||
let mut it = set.hashset().iter().peekable();
|
||||
let mut it = set.iter().peekable();
|
||||
while let Some(el) = it.next() {
|
||||
if it.peek().is_none() {
|
||||
write!(f, "{}", translator.decode(*el))?;
|
||||
|
||||
Reference in New Issue
Block a user