Converting to library and commenting code

refactoring and removing useless functions
This commit is contained in:
elvis
2025-07-09 19:34:15 +02:00
parent 1b9c0ce44b
commit ed49d6fa52
14 changed files with 170 additions and 121 deletions

View File

@ -11,7 +11,7 @@ use std::io;
use std::io::prelude::*;
use std::rc::Rc;
// grammar is defined in main.rs, calling lalrpop_mod! twice, generates twice
// grammar is defined in lib.rs, calling lalrpop_mod! twice, generates twice
// the code
use super::grammar;

7
src/lib.rs Normal file
View File

@ -0,0 +1,7 @@
pub mod rsprocess;
pub mod examples;
lalrpop_util::lalrpop_mod!(
#[allow(clippy::uninlined_format_args)] pub grammar, // name of module
"/rsprocess/grammar.rs" // location of parser
);

View File

@ -1,33 +1,10 @@
mod examples;
mod rsprocess;
lalrpop_util::lalrpop_mod!(
#[allow(clippy::uninlined_format_args)] pub grammar, // name of module
"/rsprocess/grammar.rs" // location of parser
);
fn main() -> std::io::Result<()> {
// let now = std::time::Instant::now();
// std::thread::sleep(std::time::Duration::new(2, 0));
// println!("{}", now.elapsed().as_micros());
// examples::stats()?;
reactionsystems::examples::digraph()?;
// examples::freq()?;
// examples::hoop()?;
// examples::target()?;
// examples::run()?;
// examples::limit_freq()?;
// examples::fast_freq()?;
examples::digraph()?;
examples::adversarial()?;
reactionsystems::examples::adversarial()?;
Ok(())
}

View File

@ -4,13 +4,11 @@
//! Reaction System (RS) Framework.
//! The data is held in RSset or RSreaction, in the latter the reagents,
//! inhibitors and products are held.
#![allow(dead_code)]
use super::structure::{RSreaction, RSset};
/// Computes the result of a single reaction (if enabled returns the products)
/// otherwise returns None.
// see result
/// see result
pub fn compute_step<'a>(
current_state: &'a RSset,
reaction: &'a RSreaction
@ -24,21 +22,13 @@ pub fn compute_step<'a>(
/// Computes the result of a series of reactions. Returns the union of all
/// products.
// see result
/// see result
pub fn compute_all<'a>(
current_state: &'a RSset,
reactions: Vec<&'a RSreaction>
) -> RSset {
reactions.iter().fold(RSset::new(), |acc, r| {
acc.union_option(compute_step(current_state, r))
})
}
pub fn compute_all_owned<'a>(
current_state: &'a RSset,
reactions: &'a [RSreaction]
) -> RSset {
reactions.iter().fold(RSset::new(), |acc, r| {
acc.union_option(compute_step(current_state, r))
reactions.iter().fold(RSset::new(), |mut acc, r| {
acc.union_option(compute_step(current_state, r));
acc
})
}

View File

@ -1,5 +1,3 @@
#![allow(dead_code)]
use super::perpetual::{
lollipops_decomposed_named, lollipops_prefix_len_loop_decomposed,
lollipops_prefix_len_loop_decomposed_named,
@ -9,7 +7,13 @@ use super::translator::IdType;
use std::cmp;
use std::collections::HashSet;
// see confluent, confluents
/// Two set of entities E1 and E2 are confluent w.r.t. the perpetual context
/// delta iff they reach the same loop.
/// confluent checks if all the sets of entities in ```entities``` are confluent
/// and if so returns the maximal length of prefixes traversed to reached the
/// loop, its dimension (length) and the loop.
/// see confluent, confluents
pub fn confluent(
delta: &RSenvironment,
reaction_rules: &[RSreaction],
@ -27,7 +31,6 @@ pub fn confluent(
lollipops_prefix_len_loop_decomposed(delta,
reaction_rules,
available_entities);
// FIXME we take just the first? do we compare all?
let (prefix_len, new_hoop) = all_loops.first()?;
if new_hoop.len() != dimension || !hoop.contains(new_hoop.first()?) {
@ -38,7 +41,12 @@ pub fn confluent(
Some((max_distance, dimension, hoop))
}
// see confluent, confluents
/// Two set of entities E1 and E2 are confluent w.r.t. the perpetual context Q
/// iff they reach the same loop.
/// The predicate confluent(Rs,Q,Es,Loop,Distance,Dimension) checks if all the
/// sets of entities in Es are confluent and if so returns the Loop, the maximal
/// length of prefixes traversed to reached the loop and its dimension (length).
/// see confluent, confluents
pub fn confluent_named(
delta: &RSenvironment,
reaction_rules: &[RSreaction],
@ -72,7 +80,9 @@ pub fn confluent_named(
// -----------------------------------------------------------------------------
// see invariant
/// invariant_named checks if all the sets of entities in ```entities``` are
/// confluent and if so returns the set of all traversed states, together with the loop.
/// see invariant
pub fn invariant_named(
delta: &RSenvironment,
reaction_rules: &[RSreaction],
@ -113,7 +123,18 @@ pub fn invariant_named(
// -----------------------------------------------------------------------------
// see loop_confluent
/// Suppose the context has the form
/// Q1. ... Q1.Q2. ... Q2. ... Qn. ... Qn. ...
/// and that each context Q1, Q2, ... , Q(n-1) is provided for a large number
/// of times, enough to stabilize the system in a loop (while Qn is provided
/// infinitely many times). Then it can be the case that when the context
/// switches from Qi to Q(i+1), no matter what is the current state of the loop
/// for Qi at the moment of the switching, the system will stabilize in the same
/// loop for Q(i+1): if this is the case the system is called "loop confluent".
/// loop_confluent_named checks this property over the list of contexts
/// [Q1,Q2,...,Qn] and returns the lists of Loops, Distances and Dimensions for
/// all Qi's.
/// see loop_confluent
pub fn loop_confluent_named(
deltas: &[RSenvironment],
reaction_rules: &[RSreaction],
@ -126,7 +147,12 @@ pub fn loop_confluent_named(
.collect::<Option<Vec<_>>>()
}
// see strong_confluent
/// "strong confluence" requires loop confluence and additionally check
/// that even if the context is switched BEFORE REACHING THE LOOP for Qi
/// the traversed states are still confluent for Q(i+1)
/// IMPORTANT: this notion of confluence assumes each context can be executed 0
/// or more times
/// see strong_confluent
#[allow(clippy::type_complexity)]
pub fn strong_confluent_named(
deltas: &[RSenvironment],
@ -146,3 +172,5 @@ pub fn strong_confluent_named(
})
.collect::<Option<Vec<_>>>()
}
// TODO: weak confluence

View File

@ -1,5 +1,3 @@
#![allow(dead_code)]
use crate::rsprocess::perpetual::lollipops_only_loop_decomposed_q;
use std::collections::HashMap;
@ -8,6 +6,8 @@ use super::structure::{RSreaction, RSset, RSsystem};
use super::transitions::run_separated;
use super::translator::IdType;
/// structure that holds the frequency of elements of a run or multiple runs,
/// weighted
#[derive(Debug, Clone)]
pub struct Frequency {
pub frequency_map: HashMap<IdType, Vec<u32>>,
@ -56,8 +56,9 @@ impl Default for Frequency {
// -----------------------------------------------------------------------------
// see naiveFreq, assume the system is finite, calculate the frequency of
// each symbol in all traversed states
/// assume the system is finite, calculate the frequency of each symbol in all
/// traversed states
/// see naiveFreq
pub fn naive_frequency(system: &RSsystem) -> Result<Frequency, String> {
let ect = run_separated(system)?;
let es = ect.iter().map(|(e, _, _)| e).collect::<Vec<_>>();
@ -70,8 +71,9 @@ pub fn naive_frequency(system: &RSsystem) -> Result<Frequency, String> {
Ok(freq)
}
// see loopFreq, assume the system stabilizes in a loop, calculate the frequency
// of each symbol in all states of the loop
/// assume the system stabilizes in a loop, calculate the frequency of each
/// symbol in all states of the loop
/// see loopFreq
pub fn loop_frequency(system: &RSsystem, symb: IdType) -> Frequency {
let mut freq = Frequency::new();
freq.append_weight(1);
@ -82,8 +84,9 @@ pub fn loop_frequency(system: &RSsystem, symb: IdType) -> Frequency {
freq
}
// see limitFreq, q[i] is given enough times such that the stabilizes in a loop,
// calculate the frequency of the symbols in any state in the last loop
/// ```q[i]``` is given enough times such that the stabilizes in a loop, calculate the
/// frequency of the symbols in any state in the last loop
/// see limitFreq
pub fn limit_frequency(
q: &[RSset],
reaction_rules: &[RSreaction],
@ -109,8 +112,9 @@ pub fn limit_frequency(
Some(freq)
}
// see fastFreq, q[i] is given enough times such that the stabilizes in a loop,
// calculate the frequency of the symbols in any state in any loop, weighted.
/// ```q[i]``` is given enough times such that the stabilizes in a loop, calculate the
/// frequency of the symbols in any state in any loop, weighted.
/// see fastFreq
pub fn fast_frequency(
q: &[RSset],
reaction_rules: &[RSreaction],

View File

@ -1,5 +1,3 @@
#![allow(dead_code)]
use petgraph::{Graph, Directed};
use std::collections::HashMap;
use super::structure::{RSlabel, RSsystem, RSset, RSprocess};
@ -9,6 +7,7 @@ use std::rc::Rc;
type RSgraph = Graph<RSsystem, RSlabel, Directed, u32>;
/// creates a graph starting from a system as root node
pub fn digraph(
system: RSsystem
) -> Result<RSgraph, String> {
@ -27,10 +26,7 @@ pub fn digraph(
current = stack.pop().unwrap();
let current_node = *association.get(&current).unwrap();
// cycle through all next nodes
let tr = TransitionsIterator::from(&current)?;
for (label, next) in tr {
for (label, next) in TransitionsIterator::from(&current)? {
// if not already visited
let next_node = association.entry(next.clone()).or_insert_with(|| {
stack.push(next.clone());
@ -49,6 +45,7 @@ pub fn digraph(
// Nodes -----------------------------------------------------------------------
/// Helper structure that specifies what information to display for nodes.
pub enum GraphMapNodes {
Hide,
Entities,
@ -57,6 +54,8 @@ pub enum GraphMapNodes {
}
type GraphMapNodesFnTy = dyn Fn(petgraph::prelude::NodeIndex, &RSsystem) -> String;
/// Helper structure that holds a formatting function from node as RSsystem to
/// string
pub struct GraphMapNodesTy {
function: Box<GraphMapNodesFnTy>
}
@ -131,6 +130,7 @@ impl From<GraphMapNodesTy> for Box<GraphMapNodesFnTy> {
// Edges -----------------------------------------------------------------------
/// Helper structure that specifies what information to display for edges
pub enum GraphMapEdges {
Hide,
Products,
@ -150,6 +150,8 @@ pub enum GraphMapEdges {
}
type GraphMapEdgesFnTy = dyn Fn(petgraph::prelude::EdgeIndex, &RSlabel) -> String;
/// Helper structure that holds a formatting function from node as RSsystem to
/// string
pub struct GraphMapEdgesTy {
function: Box<GraphMapEdgesFnTy>
}

View File

@ -1,10 +1,8 @@
#![allow(dead_code)]
use super::classical::compute_all_owned;
use super::classical::compute_all;
use super::structure::{RSenvironment, RSprocess, RSreaction, RSset, RSsystem};
use super::translator::IdType;
// returns the prefix and the loop from a trace
/// returns the prefix and the loop from a trace
fn split<'a>(
set: &'a RSset,
trace: &'a [RSset]
@ -13,7 +11,7 @@ fn split<'a>(
position.map(|pos| trace.split_at(pos))
}
// finds the loops by simulating the system
/// finds the loops by simulating the system
fn find_loop(
rs: &[RSreaction],
entities: RSset,
@ -26,14 +24,14 @@ fn find_loop(
return (prefix.to_vec(), hoop.to_vec());
} else {
let t = entities.union(q);
let products = compute_all_owned(&t, rs);
let products = compute_all(&t, rs);
trace.push(entities.clone());
entities = products;
}
}
}
// finds the loops by simulating the system
/// finds the loops by simulating the system
fn find_only_loop(
rs: &[RSreaction],
entities: RSset,
@ -46,14 +44,14 @@ fn find_only_loop(
return hoop.to_vec();
} else {
let t = entities.union(q);
let products = compute_all_owned(&t, rs);
let products = compute_all(&t, rs);
trace.push(entities.clone());
entities = products;
}
}
}
// finds the loops and the length of the prefix by simulating the system
/// finds the loops and the length of the prefix by simulating the system
fn find_prefix_len_loop(
rs: &[RSreaction],
entities: RSset,
@ -66,7 +64,7 @@ fn find_prefix_len_loop(
return (prefix.len(), hoop.to_vec());
} else {
let t = entities.union(q);
let products = compute_all_owned(&t, rs);
let products = compute_all(&t, rs);
trace.push(entities.clone());
entities = products;
}
@ -75,8 +73,8 @@ fn find_prefix_len_loop(
// -----------------------------------------------------------------------------
// finds only the rules X = pre(Q, rec(X)), but not only x = pre(Q, rec(x))
// to use in filter_map
/// finds only the rules X = pre(Q, rec(X)), but not only x = pre(Q, rec(x))
/// to use in filter_map
fn filter_delta<'a>(x: (&IdType, &'a RSprocess)) -> Option<&'a RSset> {
use super::structure::RSprocess::*;
let (id, rest) = x;
@ -95,7 +93,14 @@ fn filter_delta<'a>(x: (&IdType, &'a RSprocess)) -> Option<&'a RSset> {
None
}
// see lollipop
/// A special case of systems is when the context recursively provides always
/// the same set of entities. The corresponding computation is infinite. It
/// consists of a finite sequence of states followed by a looping sequence.
/// IMPORTANT: We return all loops for all X = Q.X, by varing X. The set of
/// reactions Rs and the context x are constant. Each state of the computation
/// is distinguished by the current entities E. Under these assumptions, the
/// predicate lollipop finds the Prefixes and the Loops sequences of entities.
/// see lollipop
pub fn lollipops_decomposed(
delta: &RSenvironment,
reaction_rules: &[RSreaction],
@ -112,7 +117,14 @@ pub fn lollipops_decomposed(
filtered.map(find_loop_fn).collect::<Vec<_>>()
}
// see lollipop
/// A special case of systems is when the context recursively provides always
/// the same set of entities. The corresponding computation is infinite. It
/// consists of a finite sequence of states followed by a looping sequence.
/// IMPORTANT: We return all loops for all X = Q.X, by varing X. The set of
/// reactions Rs and the context x are constant. Each state of the computation
/// is distinguished by the current entities E. Under these assumptions, the
/// predicate lollipop finds the Prefixes and the Loops sequences of entities.
/// see lollipop
pub fn lollipops(system: RSsystem) -> Vec<(Vec<RSset>, Vec<RSset>)> {
lollipops_decomposed(
&system.delta,
@ -121,10 +133,9 @@ pub fn lollipops(system: RSsystem) -> Vec<(Vec<RSset>, Vec<RSset>)> {
)
}
// see loop
/// Only returns the loop part of the lollipop, returns for all X, where X = Q.X
/// see loop
pub fn lollipops_only_loop(system: RSsystem) -> Vec<Vec<RSset>> {
// FIXME: i think we are only interested in "x", not all symbols that
// satisfy X = pre(Q, rec(X))
let filtered = system.delta.iter().filter_map(filter_delta);
let find_loop_fn = |q| {
@ -143,8 +154,6 @@ pub fn lollipops_prefix_len_loop_decomposed(
reaction_rules: &[RSreaction],
available_entities: &RSset,
) -> Vec<(usize, Vec<RSset>)> {
// FIXME: i think we are only interested in "x", not all symbols that
// satisfy X = pre(Q, rec(X))
let filtered = delta.iter().filter_map(filter_delta);
let find_loop_fn = |q| find_prefix_len_loop(reaction_rules,
@ -154,14 +163,12 @@ pub fn lollipops_prefix_len_loop_decomposed(
filtered.map(find_loop_fn).collect::<Vec<_>>()
}
// see loop
/// see loop
pub fn lollipops_only_loop_decomposed(
delta: &RSenvironment,
reaction_rules: &[RSreaction],
available_entities: &RSset,
) -> Vec<Vec<RSset>> {
// FIXME: i think we are only interested in "x", not all symbols that
// satisfy X = pre(Q, rec(X))
let filtered = delta.iter().filter_map(filter_delta);
let find_loop_fn = |q| find_only_loop(reaction_rules,
@ -175,8 +182,8 @@ pub fn lollipops_only_loop_decomposed(
// Named versions
// -----------------------------------------------------------------------------
// finds only the rules symb = pre(Q, rec(symb)), get symb from a translator
// to use in filter_map
/// finds only the rules symb = pre(Q, rec(symb)), get symb from a translator
/// to use in filter_map
fn filter_delta_named<'a>(
x: (&IdType, &'a RSprocess),
symb: &IdType
@ -201,7 +208,14 @@ fn filter_delta_named<'a>(
None
}
// see lollipop
/// A special case of systems is when the context recursively provides always
/// the same set of entities. The corresponding computation is infinite. It
/// consists of a finite sequence of states followed by a looping sequence.
/// IMPORTANT: We return all loops for all X = Q.X, by varing X. The set of
/// reactions Rs and the context x are constant. Each state of the computation
/// is distinguished by the current entities E. Under these assumptions, the
/// predicate lollipop finds the Prefixes and the Loops sequences of entities.
/// see lollipop
pub fn lollipops_decomposed_named(
delta: &RSenvironment,
reaction_rules: &[RSreaction],
@ -220,7 +234,14 @@ pub fn lollipops_decomposed_named(
filtered.map(find_loop_fn)
}
// see lollipop
/// A special case of systems is when the context recursively provides always
/// the same set of entities. The corresponding computation is infinite. It
/// consists of a finite sequence of states followed by a looping sequence.
/// IMPORTANT: We return all loops for all X = Q.X, by varing X. The set of
/// reactions Rs and the context x are constant. Each state of the computation
/// is distinguished by the current entities E. Under these assumptions, the
/// predicate lollipop finds the Prefixes and the Loops sequences of entities.
/// see lollipop
pub fn lollipops_named(
system: RSsystem,
symb: IdType
@ -233,7 +254,8 @@ pub fn lollipops_named(
)
}
// see loop
/// Only returns the loop part of the lollipop, returns for all X, where X = Q.X
/// see loop
pub fn lollipops_only_loop_named(
system: RSsystem,
symb: IdType
@ -273,7 +295,7 @@ pub fn lollipops_prefix_len_loop_decomposed_named(
filtered.map(find_loop_fn)
}
// see loop
/// see loop
pub fn lollipops_only_loop_decomposed_named(
delta: &RSenvironment,
reaction_rules: &[RSreaction],
@ -292,7 +314,7 @@ pub fn lollipops_only_loop_decomposed_named(
filtered.map(find_loop_fn)
}
// see loop/5
/// see loop/5
pub fn lollipops_only_loop_decomposed_q(
q: &RSset,
reaction_rules: &[RSreaction],

View File

@ -1,6 +1,5 @@
//! Slightly modified Simple graphviz dot file format output.
//! See petgraph::dot::mod.
#![allow(dead_code)]
// use alloc::string::String;
use core::fmt::{self, Display, Write};

View File

@ -1,10 +1,10 @@
#![allow(dead_code)]
use super::structure::RSset;
use super::structure::RSsystem;
use super::translator;
use super::translator::Translator;
/// Returns statistics about the system
/// see main_do(stat,MissingE)
#[allow(non_snake_case)]
pub fn of_RSsystem<'a>(translator: &'a Translator, system: &'a RSsystem) -> String {
let mut result: String = "Statistics:\n".into();

View File

@ -1,5 +1,3 @@
#![allow(dead_code)]
use super::translator::IdType;
use std::collections::{BTreeSet, HashMap, VecDeque};
use std::hash::Hash;
@ -8,6 +6,7 @@ use std::rc::Rc;
// -----------------------------------------------------------------------------
// RSset
// -----------------------------------------------------------------------------
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct RSset {
pub identifiers: BTreeSet<IdType>,
@ -52,18 +51,16 @@ impl RSset {
self.identifiers.is_disjoint(&b.identifiers)
}
// returns the new set a \cup b
pub fn union(&self, b: &RSset) -> RSset {
// TODO maybe find more efficient way without copy/clone
let mut ret: RSset = b.clone();
ret.identifiers.extend(self.identifiers.iter());
ret
}
pub fn union_option(&self, b: Option<&RSset>) -> RSset {
pub fn union_option(&mut self, b: Option<&RSset>) {
if let Some(b) = b {
self.union(b)
} else {
self.clone()
self.identifiers.extend(b.iter());
}
}
@ -78,7 +75,7 @@ impl RSset {
RSset { identifiers: res }
}
/// returns the new set a - b
/// returns the new set a \ b
pub fn subtraction(&self, b: &RSset) -> RSset {
// TODO maybe find more efficient way without copy/clone
let res: BTreeSet<_> = self
@ -152,7 +149,8 @@ impl RSreaction {
}
}
// see enable
/// returns true if ```current_state``` enables the reaction
/// see enable
pub fn enabled(&self, current_state: &RSset) -> bool {
self.reactants.is_subset(current_state)
&& self.inihibitors.is_disjoint(current_state)
@ -215,6 +213,7 @@ impl RSprocess {
}
}
/// returns all elements used
pub fn all_elements(&self) -> RSset {
let mut queue = VecDeque::from([self]);
let mut elements = RSset::new();
@ -316,6 +315,12 @@ impl RSchoices {
}
}
impl Default for RSchoices {
fn default() -> Self {
Self::new()
}
}
impl IntoIterator for RSchoices {
type Item = (Rc<RSset>, Rc<RSprocess>);
type IntoIter = std::vec::IntoIter<Self::Item>;
@ -536,6 +541,12 @@ impl RSlabel {
}
}
impl Default for RSlabel {
fn default() -> Self {
Self::new()
}
}
// -----------------------------------------------------------------------------
// RSassertOp
// -----------------------------------------------------------------------------

View File

@ -1,4 +1,3 @@
#![allow(dead_code)]
use super::structure::{RSlabel, RSprocess, RSset, RSsystem};
use super::transitions::unfold;
use std::rc::Rc;
@ -29,13 +28,19 @@ impl<'a> Iterator for TransitionsIterator<'a> {
fn next(&mut self) -> Option<(RSlabel, RSsystem)> {
let (c, k) = self.choices_iterator.next()?;
let t = self.system.available_entities.union(c.as_ref());
let (reactants, reactantsi, inihibitors, ireactants, products) =
let (
reactants,
reactants_absent,
inihibitors,
inihibitors_present,
products
) =
self.system.reaction_rules.iter().fold(
(
RSset::new(), // reactants
RSset::new(), // reactantsi
RSset::new(), // reactants_absent
RSset::new(), // inihibitors
RSset::new(), // ireactants
RSset::new(), // inihibitors_present
RSset::new(), // products
),
|acc, reaction| {
@ -64,9 +69,9 @@ impl<'a> Iterator for TransitionsIterator<'a> {
(*c).clone(),
t,
reactants,
reactantsi,
reactants_absent,
inihibitors,
ireactants,
inihibitors_present,
products.clone(),
);
let new_system = RSsystem::from(

View File

@ -1,5 +1,3 @@
#![allow(dead_code)]
use super::structure::{RSchoices,
RSenvironment,
RSlabel,
@ -9,7 +7,10 @@ use super::structure::{RSchoices,
use super::support_structures::TransitionsIterator;
use std::rc::Rc;
// see unfold
/// unfold returns the list of choices for the context given the process
/// definitions environment. RSchoices is a list of context moves mapping a set
/// of entities and the continuation
/// see unfold
pub fn unfold(
environment: &RSenvironment,
context_process: &RSprocess,
@ -93,7 +94,7 @@ pub fn iterator_transitions<'a>(
TransitionsIterator::from(system)
}
// see oneTransition, transition, smartTransition, smartOneTransition
/// see oneTransition, transition, smartTransition, smartOneTransition
pub fn one_transition(
system: &RSsystem
) -> Result<Option<(RSlabel, RSsystem)>, String> {
@ -101,7 +102,7 @@ pub fn one_transition(
Ok(tr.next())
}
// see allTransitions, smartAllTransitions
/// see allTransitions, smartAllTransitions
pub fn all_transitions(
system: &RSsystem
) -> Result<Vec<(RSlabel, RSsystem)>, String> {
@ -109,7 +110,7 @@ pub fn all_transitions(
Ok(tr.collect::<Vec<_>>())
}
// see oneTarget, smartOneTarget, target, smartTarget
/// see oneTarget, smartOneTarget, target, smartTarget
pub fn target(
system: &RSsystem
) -> Result<(i64, RSset), String> {
@ -126,7 +127,7 @@ pub fn target(
Ok((n, current.available_entities.clone()))
}
// see oneRun, run, smartOneRunEK, smartRunEK
/// see oneRun, run, smartOneRunEK, smartRunEK
pub fn run(system: RSsystem) -> Result<Vec<Rc<RSsystem>>, String> {
let mut res = vec![Rc::new(system)];
while let Some((_, next_sys)) = one_transition(res.last().unwrap())? {
@ -135,7 +136,7 @@ pub fn run(system: RSsystem) -> Result<Vec<Rc<RSsystem>>, String> {
Ok(res)
}
// see smartOneRunECT, smartRunECT
/// see smartOneRunECT, smartRunECT
pub fn run_separated(
system: &RSsystem
) -> Result<Vec<(RSset, RSset, RSset)>, String> {

View File

@ -1,6 +1,7 @@
// translate and keeps track of strings
//! Module for translation and keeping track of strings.
use std::{cmp::max, collections::HashMap};
/// precision for printing frequencies
static PRECISION: &usize = &2;
pub type IdType = u32;
@ -29,6 +30,7 @@ impl Default for Translator {
}
impl Translator {
/// converts a string into an id
pub fn encode(&mut self, s: impl Into<String>) -> IdType {
let s = s.into();
let id = *(self.strings.entry(s.clone()).or_insert({
@ -39,6 +41,7 @@ impl Translator {
id
}
/// converts an id into the corresponding string
pub fn decode(&self, el: IdType) -> Option<String> {
self.reverse
.get(&el)