Converting to library and commenting code
refactoring and removing useless functions
This commit is contained in:
@ -11,7 +11,7 @@ use std::io;
|
|||||||
use std::io::prelude::*;
|
use std::io::prelude::*;
|
||||||
use std::rc::Rc;
|
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
|
// the code
|
||||||
use super::grammar;
|
use super::grammar;
|
||||||
|
|
||||||
|
|||||||
7
src/lib.rs
Normal file
7
src/lib.rs
Normal 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
|
||||||
|
);
|
||||||
27
src/main.rs
27
src/main.rs
@ -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<()> {
|
fn main() -> std::io::Result<()> {
|
||||||
// let now = std::time::Instant::now();
|
// let now = std::time::Instant::now();
|
||||||
// std::thread::sleep(std::time::Duration::new(2, 0));
|
|
||||||
// println!("{}", now.elapsed().as_micros());
|
// println!("{}", now.elapsed().as_micros());
|
||||||
|
|
||||||
// examples::stats()?;
|
reactionsystems::examples::digraph()?;
|
||||||
|
|
||||||
// examples::freq()?;
|
reactionsystems::examples::adversarial()?;
|
||||||
|
|
||||||
// examples::hoop()?;
|
|
||||||
|
|
||||||
// examples::target()?;
|
|
||||||
|
|
||||||
// examples::run()?;
|
|
||||||
|
|
||||||
// examples::limit_freq()?;
|
|
||||||
|
|
||||||
// examples::fast_freq()?;
|
|
||||||
|
|
||||||
examples::digraph()?;
|
|
||||||
|
|
||||||
examples::adversarial()?;
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|||||||
@ -4,13 +4,11 @@
|
|||||||
//! Reaction System (RS) Framework.
|
//! Reaction System (RS) Framework.
|
||||||
//! The data is held in RSset or RSreaction, in the latter the reagents,
|
//! The data is held in RSset or RSreaction, in the latter the reagents,
|
||||||
//! inhibitors and products are held.
|
//! inhibitors and products are held.
|
||||||
#![allow(dead_code)]
|
|
||||||
|
|
||||||
use super::structure::{RSreaction, RSset};
|
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.
|
||||||
// see result
|
/// see result
|
||||||
pub fn compute_step<'a>(
|
pub fn compute_step<'a>(
|
||||||
current_state: &'a RSset,
|
current_state: &'a RSset,
|
||||||
reaction: &'a RSreaction
|
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
|
/// Computes the result of a series of reactions. Returns the union of all
|
||||||
/// products.
|
/// products.
|
||||||
// see result
|
/// see result
|
||||||
pub fn compute_all<'a>(
|
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,
|
current_state: &'a RSset,
|
||||||
reactions: &'a [RSreaction]
|
reactions: &'a [RSreaction]
|
||||||
) -> RSset {
|
) -> RSset {
|
||||||
reactions.iter().fold(RSset::new(), |acc, r| {
|
reactions.iter().fold(RSset::new(), |mut acc, r| {
|
||||||
acc.union_option(compute_step(current_state, r))
|
acc.union_option(compute_step(current_state, r));
|
||||||
|
acc
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,5 +1,3 @@
|
|||||||
#![allow(dead_code)]
|
|
||||||
|
|
||||||
use super::perpetual::{
|
use super::perpetual::{
|
||||||
lollipops_decomposed_named, lollipops_prefix_len_loop_decomposed,
|
lollipops_decomposed_named, lollipops_prefix_len_loop_decomposed,
|
||||||
lollipops_prefix_len_loop_decomposed_named,
|
lollipops_prefix_len_loop_decomposed_named,
|
||||||
@ -9,7 +7,13 @@ use super::translator::IdType;
|
|||||||
use std::cmp;
|
use std::cmp;
|
||||||
use std::collections::HashSet;
|
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(
|
pub fn confluent(
|
||||||
delta: &RSenvironment,
|
delta: &RSenvironment,
|
||||||
reaction_rules: &[RSreaction],
|
reaction_rules: &[RSreaction],
|
||||||
@ -27,7 +31,6 @@ pub fn confluent(
|
|||||||
lollipops_prefix_len_loop_decomposed(delta,
|
lollipops_prefix_len_loop_decomposed(delta,
|
||||||
reaction_rules,
|
reaction_rules,
|
||||||
available_entities);
|
available_entities);
|
||||||
// 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()?;
|
||||||
|
|
||||||
if new_hoop.len() != dimension || !hoop.contains(new_hoop.first()?) {
|
if new_hoop.len() != dimension || !hoop.contains(new_hoop.first()?) {
|
||||||
@ -38,7 +41,12 @@ pub fn confluent(
|
|||||||
Some((max_distance, dimension, hoop))
|
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(
|
pub fn confluent_named(
|
||||||
delta: &RSenvironment,
|
delta: &RSenvironment,
|
||||||
reaction_rules: &[RSreaction],
|
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(
|
pub fn invariant_named(
|
||||||
delta: &RSenvironment,
|
delta: &RSenvironment,
|
||||||
reaction_rules: &[RSreaction],
|
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(
|
pub fn loop_confluent_named(
|
||||||
deltas: &[RSenvironment],
|
deltas: &[RSenvironment],
|
||||||
reaction_rules: &[RSreaction],
|
reaction_rules: &[RSreaction],
|
||||||
@ -126,7 +147,12 @@ pub fn loop_confluent_named(
|
|||||||
.collect::<Option<Vec<_>>>()
|
.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)]
|
#[allow(clippy::type_complexity)]
|
||||||
pub fn strong_confluent_named(
|
pub fn strong_confluent_named(
|
||||||
deltas: &[RSenvironment],
|
deltas: &[RSenvironment],
|
||||||
@ -146,3 +172,5 @@ pub fn strong_confluent_named(
|
|||||||
})
|
})
|
||||||
.collect::<Option<Vec<_>>>()
|
.collect::<Option<Vec<_>>>()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: weak confluence
|
||||||
|
|||||||
@ -1,5 +1,3 @@
|
|||||||
#![allow(dead_code)]
|
|
||||||
|
|
||||||
use crate::rsprocess::perpetual::lollipops_only_loop_decomposed_q;
|
use crate::rsprocess::perpetual::lollipops_only_loop_decomposed_q;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
@ -8,6 +6,8 @@ use super::structure::{RSreaction, RSset, RSsystem};
|
|||||||
use super::transitions::run_separated;
|
use super::transitions::run_separated;
|
||||||
use super::translator::IdType;
|
use super::translator::IdType;
|
||||||
|
|
||||||
|
/// structure that holds the frequency of elements of a run or multiple runs,
|
||||||
|
/// weighted
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct Frequency {
|
pub struct Frequency {
|
||||||
pub frequency_map: HashMap<IdType, Vec<u32>>,
|
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
|
/// assume the system is finite, calculate the frequency of each symbol in all
|
||||||
// each symbol in all traversed states
|
/// traversed states
|
||||||
|
/// see naiveFreq
|
||||||
pub fn naive_frequency(system: &RSsystem) -> Result<Frequency, String> {
|
pub fn naive_frequency(system: &RSsystem) -> Result<Frequency, String> {
|
||||||
let ect = run_separated(system)?;
|
let ect = run_separated(system)?;
|
||||||
let es = ect.iter().map(|(e, _, _)| e).collect::<Vec<_>>();
|
let es = ect.iter().map(|(e, _, _)| e).collect::<Vec<_>>();
|
||||||
@ -70,8 +71,9 @@ pub fn naive_frequency(system: &RSsystem) -> Result<Frequency, String> {
|
|||||||
Ok(freq)
|
Ok(freq)
|
||||||
}
|
}
|
||||||
|
|
||||||
// see loopFreq, assume the system stabilizes in a loop, calculate the frequency
|
/// assume the system stabilizes in a loop, calculate the frequency of each
|
||||||
// of each symbol in all states of the loop
|
/// symbol in all states of the loop
|
||||||
|
/// see loopFreq
|
||||||
pub fn loop_frequency(system: &RSsystem, symb: IdType) -> Frequency {
|
pub fn loop_frequency(system: &RSsystem, symb: IdType) -> Frequency {
|
||||||
let mut freq = Frequency::new();
|
let mut freq = Frequency::new();
|
||||||
freq.append_weight(1);
|
freq.append_weight(1);
|
||||||
@ -82,8 +84,9 @@ pub fn loop_frequency(system: &RSsystem, symb: IdType) -> Frequency {
|
|||||||
freq
|
freq
|
||||||
}
|
}
|
||||||
|
|
||||||
// see limitFreq, q[i] is given enough times such that the stabilizes in a loop,
|
/// ```q[i]``` is given enough times such that the stabilizes in a loop, calculate the
|
||||||
// calculate the frequency of the symbols in any state in the last loop
|
/// frequency of the symbols in any state in the last loop
|
||||||
|
/// see limitFreq
|
||||||
pub fn limit_frequency(
|
pub fn limit_frequency(
|
||||||
q: &[RSset],
|
q: &[RSset],
|
||||||
reaction_rules: &[RSreaction],
|
reaction_rules: &[RSreaction],
|
||||||
@ -109,8 +112,9 @@ pub fn limit_frequency(
|
|||||||
Some(freq)
|
Some(freq)
|
||||||
}
|
}
|
||||||
|
|
||||||
// see fastFreq, q[i] is given enough times such that the stabilizes in a loop,
|
/// ```q[i]``` is given enough times such that the stabilizes in a loop, calculate the
|
||||||
// calculate the frequency of the symbols in any state in any loop, weighted.
|
/// frequency of the symbols in any state in any loop, weighted.
|
||||||
|
/// see fastFreq
|
||||||
pub fn fast_frequency(
|
pub fn fast_frequency(
|
||||||
q: &[RSset],
|
q: &[RSset],
|
||||||
reaction_rules: &[RSreaction],
|
reaction_rules: &[RSreaction],
|
||||||
|
|||||||
@ -1,5 +1,3 @@
|
|||||||
#![allow(dead_code)]
|
|
||||||
|
|
||||||
use petgraph::{Graph, Directed};
|
use petgraph::{Graph, Directed};
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use super::structure::{RSlabel, RSsystem, RSset, RSprocess};
|
use super::structure::{RSlabel, RSsystem, RSset, RSprocess};
|
||||||
@ -9,6 +7,7 @@ use std::rc::Rc;
|
|||||||
|
|
||||||
type RSgraph = Graph<RSsystem, RSlabel, Directed, u32>;
|
type RSgraph = Graph<RSsystem, RSlabel, Directed, u32>;
|
||||||
|
|
||||||
|
/// creates a graph starting from a system as root node
|
||||||
pub fn digraph(
|
pub fn digraph(
|
||||||
system: RSsystem
|
system: RSsystem
|
||||||
) -> Result<RSgraph, String> {
|
) -> Result<RSgraph, String> {
|
||||||
@ -27,10 +26,7 @@ pub fn digraph(
|
|||||||
current = stack.pop().unwrap();
|
current = stack.pop().unwrap();
|
||||||
let current_node = *association.get(¤t).unwrap();
|
let current_node = *association.get(¤t).unwrap();
|
||||||
|
|
||||||
// cycle through all next nodes
|
for (label, next) in TransitionsIterator::from(¤t)? {
|
||||||
let tr = TransitionsIterator::from(¤t)?;
|
|
||||||
|
|
||||||
for (label, next) in tr {
|
|
||||||
// if not already visited
|
// if not already visited
|
||||||
let next_node = association.entry(next.clone()).or_insert_with(|| {
|
let next_node = association.entry(next.clone()).or_insert_with(|| {
|
||||||
stack.push(next.clone());
|
stack.push(next.clone());
|
||||||
@ -49,6 +45,7 @@ pub fn digraph(
|
|||||||
|
|
||||||
// Nodes -----------------------------------------------------------------------
|
// Nodes -----------------------------------------------------------------------
|
||||||
|
|
||||||
|
/// Helper structure that specifies what information to display for nodes.
|
||||||
pub enum GraphMapNodes {
|
pub enum GraphMapNodes {
|
||||||
Hide,
|
Hide,
|
||||||
Entities,
|
Entities,
|
||||||
@ -57,6 +54,8 @@ pub enum GraphMapNodes {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type GraphMapNodesFnTy = dyn Fn(petgraph::prelude::NodeIndex, &RSsystem) -> String;
|
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 {
|
pub struct GraphMapNodesTy {
|
||||||
function: Box<GraphMapNodesFnTy>
|
function: Box<GraphMapNodesFnTy>
|
||||||
}
|
}
|
||||||
@ -131,6 +130,7 @@ impl From<GraphMapNodesTy> for Box<GraphMapNodesFnTy> {
|
|||||||
|
|
||||||
// Edges -----------------------------------------------------------------------
|
// Edges -----------------------------------------------------------------------
|
||||||
|
|
||||||
|
/// Helper structure that specifies what information to display for edges
|
||||||
pub enum GraphMapEdges {
|
pub enum GraphMapEdges {
|
||||||
Hide,
|
Hide,
|
||||||
Products,
|
Products,
|
||||||
@ -150,6 +150,8 @@ pub enum GraphMapEdges {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type GraphMapEdgesFnTy = dyn Fn(petgraph::prelude::EdgeIndex, &RSlabel) -> String;
|
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 {
|
pub struct GraphMapEdgesTy {
|
||||||
function: Box<GraphMapEdgesFnTy>
|
function: Box<GraphMapEdgesFnTy>
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,10 +1,8 @@
|
|||||||
#![allow(dead_code)]
|
use super::classical::compute_all;
|
||||||
|
|
||||||
use super::classical::compute_all_owned;
|
|
||||||
use super::structure::{RSenvironment, RSprocess, RSreaction, RSset, RSsystem};
|
use super::structure::{RSenvironment, RSprocess, RSreaction, RSset, RSsystem};
|
||||||
use super::translator::IdType;
|
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]
|
||||||
@ -13,7 +11,7 @@ fn split<'a>(
|
|||||||
position.map(|pos| trace.split_at(pos))
|
position.map(|pos| trace.split_at(pos))
|
||||||
}
|
}
|
||||||
|
|
||||||
// finds the loops by simulating the system
|
/// finds the loops by simulating the system
|
||||||
fn find_loop(
|
fn find_loop(
|
||||||
rs: &[RSreaction],
|
rs: &[RSreaction],
|
||||||
entities: RSset,
|
entities: RSset,
|
||||||
@ -26,14 +24,14 @@ fn find_loop(
|
|||||||
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(&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(
|
fn find_only_loop(
|
||||||
rs: &[RSreaction],
|
rs: &[RSreaction],
|
||||||
entities: RSset,
|
entities: RSset,
|
||||||
@ -46,14 +44,14 @@ fn find_only_loop(
|
|||||||
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(&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],
|
||||||
entities: RSset,
|
entities: RSset,
|
||||||
@ -66,7 +64,7 @@ fn find_prefix_len_loop(
|
|||||||
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(&t, rs);
|
||||||
trace.push(entities.clone());
|
trace.push(entities.clone());
|
||||||
entities = products;
|
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))
|
/// finds only the rules X = pre(Q, rec(X)), but not only x = pre(Q, rec(x))
|
||||||
// to use in filter_map
|
/// to use in filter_map
|
||||||
fn filter_delta<'a>(x: (&IdType, &'a RSprocess)) -> Option<&'a RSset> {
|
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;
|
||||||
@ -95,7 +93,14 @@ fn filter_delta<'a>(x: (&IdType, &'a RSprocess)) -> Option<&'a RSset> {
|
|||||||
None
|
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(
|
pub fn lollipops_decomposed(
|
||||||
delta: &RSenvironment,
|
delta: &RSenvironment,
|
||||||
reaction_rules: &[RSreaction],
|
reaction_rules: &[RSreaction],
|
||||||
@ -112,7 +117,14 @@ pub fn lollipops_decomposed(
|
|||||||
filtered.map(find_loop_fn).collect::<Vec<_>>()
|
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>)> {
|
pub fn lollipops(system: RSsystem) -> Vec<(Vec<RSset>, Vec<RSset>)> {
|
||||||
lollipops_decomposed(
|
lollipops_decomposed(
|
||||||
&system.delta,
|
&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>> {
|
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 filtered = system.delta.iter().filter_map(filter_delta);
|
||||||
|
|
||||||
let find_loop_fn = |q| {
|
let find_loop_fn = |q| {
|
||||||
@ -143,8 +154,6 @@ pub fn lollipops_prefix_len_loop_decomposed(
|
|||||||
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
|
|
||||||
// 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_prefix_len_loop(reaction_rules,
|
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<_>>()
|
filtered.map(find_loop_fn).collect::<Vec<_>>()
|
||||||
}
|
}
|
||||||
|
|
||||||
// see loop
|
/// see loop
|
||||||
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
|
|
||||||
// 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,
|
||||||
@ -175,8 +182,8 @@ pub fn lollipops_only_loop_decomposed(
|
|||||||
// Named versions
|
// Named versions
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
// finds only the rules symb = pre(Q, rec(symb)), get symb from a translator
|
/// finds only the rules symb = pre(Q, rec(symb)), get symb from a translator
|
||||||
// to use in filter_map
|
/// to use in filter_map
|
||||||
fn filter_delta_named<'a>(
|
fn filter_delta_named<'a>(
|
||||||
x: (&IdType, &'a RSprocess),
|
x: (&IdType, &'a RSprocess),
|
||||||
symb: &IdType
|
symb: &IdType
|
||||||
@ -201,7 +208,14 @@ fn filter_delta_named<'a>(
|
|||||||
None
|
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(
|
pub fn lollipops_decomposed_named(
|
||||||
delta: &RSenvironment,
|
delta: &RSenvironment,
|
||||||
reaction_rules: &[RSreaction],
|
reaction_rules: &[RSreaction],
|
||||||
@ -220,7 +234,14 @@ pub fn lollipops_decomposed_named(
|
|||||||
filtered.map(find_loop_fn)
|
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(
|
pub fn lollipops_named(
|
||||||
system: RSsystem,
|
system: RSsystem,
|
||||||
symb: IdType
|
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(
|
pub fn lollipops_only_loop_named(
|
||||||
system: RSsystem,
|
system: RSsystem,
|
||||||
symb: IdType
|
symb: IdType
|
||||||
@ -273,7 +295,7 @@ pub fn lollipops_prefix_len_loop_decomposed_named(
|
|||||||
filtered.map(find_loop_fn)
|
filtered.map(find_loop_fn)
|
||||||
}
|
}
|
||||||
|
|
||||||
// see loop
|
/// see loop
|
||||||
pub fn lollipops_only_loop_decomposed_named(
|
pub fn lollipops_only_loop_decomposed_named(
|
||||||
delta: &RSenvironment,
|
delta: &RSenvironment,
|
||||||
reaction_rules: &[RSreaction],
|
reaction_rules: &[RSreaction],
|
||||||
@ -292,7 +314,7 @@ pub fn lollipops_only_loop_decomposed_named(
|
|||||||
filtered.map(find_loop_fn)
|
filtered.map(find_loop_fn)
|
||||||
}
|
}
|
||||||
|
|
||||||
// see loop/5
|
/// see loop/5
|
||||||
pub fn lollipops_only_loop_decomposed_q(
|
pub fn lollipops_only_loop_decomposed_q(
|
||||||
q: &RSset,
|
q: &RSset,
|
||||||
reaction_rules: &[RSreaction],
|
reaction_rules: &[RSreaction],
|
||||||
|
|||||||
@ -1,6 +1,5 @@
|
|||||||
//! Slightly modified Simple graphviz dot file format output.
|
//! Slightly modified Simple graphviz dot file format output.
|
||||||
//! See petgraph::dot::mod.
|
//! See petgraph::dot::mod.
|
||||||
#![allow(dead_code)]
|
|
||||||
|
|
||||||
// use alloc::string::String;
|
// use alloc::string::String;
|
||||||
use core::fmt::{self, Display, Write};
|
use core::fmt::{self, Display, Write};
|
||||||
|
|||||||
@ -1,10 +1,10 @@
|
|||||||
#![allow(dead_code)]
|
|
||||||
|
|
||||||
use super::structure::RSset;
|
use super::structure::RSset;
|
||||||
use super::structure::RSsystem;
|
use super::structure::RSsystem;
|
||||||
use super::translator;
|
use super::translator;
|
||||||
use super::translator::Translator;
|
use super::translator::Translator;
|
||||||
|
|
||||||
|
/// Returns statistics about the system
|
||||||
|
/// see main_do(stat,MissingE)
|
||||||
#[allow(non_snake_case)]
|
#[allow(non_snake_case)]
|
||||||
pub fn of_RSsystem<'a>(translator: &'a Translator, system: &'a RSsystem) -> String {
|
pub fn of_RSsystem<'a>(translator: &'a Translator, system: &'a RSsystem) -> String {
|
||||||
let mut result: String = "Statistics:\n".into();
|
let mut result: String = "Statistics:\n".into();
|
||||||
|
|||||||
@ -1,5 +1,3 @@
|
|||||||
#![allow(dead_code)]
|
|
||||||
|
|
||||||
use super::translator::IdType;
|
use super::translator::IdType;
|
||||||
use std::collections::{BTreeSet, HashMap, VecDeque};
|
use std::collections::{BTreeSet, HashMap, VecDeque};
|
||||||
use std::hash::Hash;
|
use std::hash::Hash;
|
||||||
@ -8,6 +6,7 @@ use std::rc::Rc;
|
|||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
// RSset
|
// RSset
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||||
pub struct RSset {
|
pub struct RSset {
|
||||||
pub identifiers: BTreeSet<IdType>,
|
pub identifiers: BTreeSet<IdType>,
|
||||||
@ -52,18 +51,16 @@ impl RSset {
|
|||||||
self.identifiers.is_disjoint(&b.identifiers)
|
self.identifiers.is_disjoint(&b.identifiers)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// returns the new set a \cup b
|
||||||
pub fn union(&self, b: &RSset) -> RSset {
|
pub fn union(&self, b: &RSset) -> RSset {
|
||||||
// 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(&mut self, b: Option<&RSset>) {
|
||||||
if let Some(b) = b {
|
if let Some(b) = b {
|
||||||
self.union(b)
|
self.identifiers.extend(b.iter());
|
||||||
} else {
|
|
||||||
self.clone()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -78,7 +75,7 @@ impl RSset {
|
|||||||
RSset { identifiers: res }
|
RSset { identifiers: res }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// returns the new set a - b
|
/// returns the new set a \ b
|
||||||
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
|
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 {
|
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)
|
||||||
@ -215,6 +213,7 @@ impl RSprocess {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// returns all elements used
|
||||||
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();
|
||||||
@ -316,6 +315,12 @@ impl RSchoices {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Default for RSchoices {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self::new()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl IntoIterator for RSchoices {
|
impl IntoIterator for RSchoices {
|
||||||
type Item = (Rc<RSset>, Rc<RSprocess>);
|
type Item = (Rc<RSset>, Rc<RSprocess>);
|
||||||
type IntoIter = std::vec::IntoIter<Self::Item>;
|
type IntoIter = std::vec::IntoIter<Self::Item>;
|
||||||
@ -536,6 +541,12 @@ impl RSlabel {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Default for RSlabel {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self::new()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
// RSassertOp
|
// RSassertOp
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
|||||||
@ -1,4 +1,3 @@
|
|||||||
#![allow(dead_code)]
|
|
||||||
use super::structure::{RSlabel, RSprocess, RSset, RSsystem};
|
use super::structure::{RSlabel, RSprocess, RSset, RSsystem};
|
||||||
use super::transitions::unfold;
|
use super::transitions::unfold;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
@ -29,13 +28,19 @@ impl<'a> Iterator for TransitionsIterator<'a> {
|
|||||||
fn next(&mut self) -> Option<(RSlabel, RSsystem)> {
|
fn next(&mut self) -> Option<(RSlabel, RSsystem)> {
|
||||||
let (c, k) = self.choices_iterator.next()?;
|
let (c, k) = self.choices_iterator.next()?;
|
||||||
let t = self.system.available_entities.union(c.as_ref());
|
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(
|
self.system.reaction_rules.iter().fold(
|
||||||
(
|
(
|
||||||
RSset::new(), // reactants
|
RSset::new(), // reactants
|
||||||
RSset::new(), // reactantsi
|
RSset::new(), // reactants_absent
|
||||||
RSset::new(), // inihibitors
|
RSset::new(), // inihibitors
|
||||||
RSset::new(), // ireactants
|
RSset::new(), // inihibitors_present
|
||||||
RSset::new(), // products
|
RSset::new(), // products
|
||||||
),
|
),
|
||||||
|acc, reaction| {
|
|acc, reaction| {
|
||||||
@ -64,9 +69,9 @@ impl<'a> Iterator for TransitionsIterator<'a> {
|
|||||||
(*c).clone(),
|
(*c).clone(),
|
||||||
t,
|
t,
|
||||||
reactants,
|
reactants,
|
||||||
reactantsi,
|
reactants_absent,
|
||||||
inihibitors,
|
inihibitors,
|
||||||
ireactants,
|
inihibitors_present,
|
||||||
products.clone(),
|
products.clone(),
|
||||||
);
|
);
|
||||||
let new_system = RSsystem::from(
|
let new_system = RSsystem::from(
|
||||||
|
|||||||
@ -1,5 +1,3 @@
|
|||||||
#![allow(dead_code)]
|
|
||||||
|
|
||||||
use super::structure::{RSchoices,
|
use super::structure::{RSchoices,
|
||||||
RSenvironment,
|
RSenvironment,
|
||||||
RSlabel,
|
RSlabel,
|
||||||
@ -9,7 +7,10 @@ use super::structure::{RSchoices,
|
|||||||
use super::support_structures::TransitionsIterator;
|
use super::support_structures::TransitionsIterator;
|
||||||
use std::rc::Rc;
|
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(
|
pub fn unfold(
|
||||||
environment: &RSenvironment,
|
environment: &RSenvironment,
|
||||||
context_process: &RSprocess,
|
context_process: &RSprocess,
|
||||||
@ -93,7 +94,7 @@ pub fn iterator_transitions<'a>(
|
|||||||
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> {
|
||||||
@ -101,7 +102,7 @@ pub fn one_transition(
|
|||||||
Ok(tr.next())
|
Ok(tr.next())
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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> {
|
||||||
@ -109,7 +110,7 @@ pub fn all_transitions(
|
|||||||
Ok(tr.collect::<Vec<_>>())
|
Ok(tr.collect::<Vec<_>>())
|
||||||
}
|
}
|
||||||
|
|
||||||
// see oneTarget, smartOneTarget, target, smartTarget
|
/// see oneTarget, smartOneTarget, target, smartTarget
|
||||||
pub fn target(
|
pub fn target(
|
||||||
system: &RSsystem
|
system: &RSsystem
|
||||||
) -> Result<(i64, RSset), String> {
|
) -> Result<(i64, RSset), String> {
|
||||||
@ -126,7 +127,7 @@ pub fn target(
|
|||||||
Ok((n, current.available_entities.clone()))
|
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> {
|
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())? {
|
||||||
@ -135,7 +136,7 @@ pub fn run(system: RSsystem) -> Result<Vec<Rc<RSsystem>>, String> {
|
|||||||
Ok(res)
|
Ok(res)
|
||||||
}
|
}
|
||||||
|
|
||||||
// see smartOneRunECT, smartRunECT
|
/// see smartOneRunECT, smartRunECT
|
||||||
pub fn run_separated(
|
pub fn run_separated(
|
||||||
system: &RSsystem
|
system: &RSsystem
|
||||||
) -> Result<Vec<(RSset, RSset, RSset)>, String> {
|
) -> Result<Vec<(RSset, RSset, RSset)>, String> {
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
// translate and keeps track of strings
|
//! Module for translation and keeping track of strings.
|
||||||
use std::{cmp::max, collections::HashMap};
|
use std::{cmp::max, collections::HashMap};
|
||||||
|
|
||||||
|
/// precision for printing frequencies
|
||||||
static PRECISION: &usize = &2;
|
static PRECISION: &usize = &2;
|
||||||
|
|
||||||
pub type IdType = u32;
|
pub type IdType = u32;
|
||||||
@ -29,6 +30,7 @@ impl Default for Translator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Translator {
|
impl Translator {
|
||||||
|
/// converts a string into an id
|
||||||
pub fn encode(&mut self, s: impl Into<String>) -> IdType {
|
pub fn encode(&mut self, s: impl Into<String>) -> IdType {
|
||||||
let s = s.into();
|
let s = s.into();
|
||||||
let id = *(self.strings.entry(s.clone()).or_insert({
|
let id = *(self.strings.entry(s.clone()).or_insert({
|
||||||
@ -39,6 +41,7 @@ impl Translator {
|
|||||||
id
|
id
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// converts an id into the corresponding string
|
||||||
pub fn decode(&self, el: IdType) -> Option<String> {
|
pub fn decode(&self, el: IdType) -> Option<String> {
|
||||||
self.reverse
|
self.reverse
|
||||||
.get(&el)
|
.get(&el)
|
||||||
|
|||||||
Reference in New Issue
Block a user