Refactoring
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@ -116,3 +116,4 @@ Temporary Items
|
|||||||
.nfs*
|
.nfs*
|
||||||
|
|
||||||
*.cbor
|
*.cbor
|
||||||
|
*.graphml
|
||||||
|
|||||||
445
src/examples.rs
445
src/examples.rs
@ -1,445 +0,0 @@
|
|||||||
use super::rsprocess::structure::{RSset, RSsystem};
|
|
||||||
use super::rsprocess::{graph, rsdot, translator};
|
|
||||||
use super::rsprocess::translator::Translator;
|
|
||||||
use super::rsprocess::{frequency, perpetual, statistics, transitions};
|
|
||||||
use super::rsprocess::serialize;
|
|
||||||
|
|
||||||
use std::env;
|
|
||||||
use std::fs::{self, File};
|
|
||||||
use std::io;
|
|
||||||
use std::io::prelude::*;
|
|
||||||
use std::rc::Rc;
|
|
||||||
|
|
||||||
// grammar is defined in lib.rs, calling lalrpop_mod! twice, generates twice
|
|
||||||
// the code
|
|
||||||
use super::grammar;
|
|
||||||
|
|
||||||
fn read_file<T, F>(
|
|
||||||
translator: &mut Translator,
|
|
||||||
path: std::path::PathBuf,
|
|
||||||
parser: F
|
|
||||||
) -> std::io::Result<T>
|
|
||||||
where
|
|
||||||
F: Fn(&mut Translator, String) -> T
|
|
||||||
{
|
|
||||||
// we read the file with a buffer
|
|
||||||
let f = fs::File::open(path.clone())?;
|
|
||||||
let mut buf_reader = io::BufReader::new(f);
|
|
||||||
let mut contents = String::new();
|
|
||||||
buf_reader.read_to_string(&mut contents)?;
|
|
||||||
|
|
||||||
// parse
|
|
||||||
let result = parser(translator, contents);
|
|
||||||
|
|
||||||
Ok(result)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn save_file(
|
|
||||||
contents: String,
|
|
||||||
path: std::path::PathBuf
|
|
||||||
) -> std::io::Result<()>
|
|
||||||
{
|
|
||||||
let mut f = fs::File::create(path.clone())?;
|
|
||||||
write!(f, "{contents}")?;
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn parser_system(translator: &mut Translator, contents: String) -> RSsystem {
|
|
||||||
grammar::SystemParser::new()
|
|
||||||
.parse(translator, &contents)
|
|
||||||
.unwrap()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn parser_experiment(translator: &mut Translator, contents: String) -> (Vec<u32>, Vec<RSset>) {
|
|
||||||
grammar::ExperimentParser::new()
|
|
||||||
.parse(translator, &contents)
|
|
||||||
.unwrap()
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// equivalent main_do(stat) or main_do(stat, MissingE)
|
|
||||||
pub fn stats() -> std::io::Result<()> {
|
|
||||||
let mut translator = Translator::new();
|
|
||||||
|
|
||||||
let mut path = env::current_dir()?;
|
|
||||||
// file to read is inside testing/
|
|
||||||
path = path.join("testing/first.system");
|
|
||||||
let system = read_file(&mut translator, path, parser_system)?;
|
|
||||||
|
|
||||||
// print statistics to screan
|
|
||||||
println!("{}", statistics::of_RSsystem(&translator, &system));
|
|
||||||
|
|
||||||
// to write to file:
|
|
||||||
//// path = path.with_extension("stats");
|
|
||||||
//// let mut f = std::fs::File::create(path)?;
|
|
||||||
//// writeln!(f, "{}", statistics::of_RSsystem(translator, &result))?;
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
// equivalent to main_do(target, E)
|
|
||||||
pub fn target() -> std::io::Result<()> {
|
|
||||||
let mut translator = Translator::new();
|
|
||||||
|
|
||||||
let mut path = env::current_dir()?;
|
|
||||||
// file to read is inside testing/
|
|
||||||
path = path.join("testing/first.system");
|
|
||||||
let system = read_file(&mut translator, path, parser_system)?;
|
|
||||||
|
|
||||||
// the system needs to terminate to return
|
|
||||||
let res = match transitions::target(&system) {
|
|
||||||
Ok(o) => o,
|
|
||||||
Err(e) => {
|
|
||||||
println!("Error computing target: {e}");
|
|
||||||
return Ok(());
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
println!(
|
|
||||||
"After {} steps we arrive at state:\n{}",
|
|
||||||
res.0,
|
|
||||||
translator::RSsetDisplay::from(&translator, &res.1)
|
|
||||||
);
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
// equivalent to main_do(run,Es)
|
|
||||||
pub fn run() -> std::io::Result<()> {
|
|
||||||
let mut translator = Translator::new();
|
|
||||||
|
|
||||||
let mut path = env::current_dir()?;
|
|
||||||
// file to read is inside testing/
|
|
||||||
path = path.join("testing/first.system");
|
|
||||||
let system = read_file(&mut translator, path, parser_system)?;
|
|
||||||
|
|
||||||
// the system needs to terminate to return
|
|
||||||
let res = match transitions::run_separated(&system) {
|
|
||||||
Ok(o) => o,
|
|
||||||
Err(e) => {
|
|
||||||
println!("Error computing target: {e}");
|
|
||||||
return Ok(());
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
println!("The trace is composed by the set of entities:");
|
|
||||||
|
|
||||||
for (e, _c, _t) in res {
|
|
||||||
println!("{}", translator::RSsetDisplay::from(&translator, &e));
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
// equivalent to main_do(loop,Es)
|
|
||||||
pub fn hoop() -> std::io::Result<()> {
|
|
||||||
let mut translator = Translator::new();
|
|
||||||
|
|
||||||
let mut path = env::current_dir()?;
|
|
||||||
// file to read is inside testing/
|
|
||||||
path = path.join("testing/first.system");
|
|
||||||
let system = read_file(&mut translator, path, parser_system)?;
|
|
||||||
|
|
||||||
// we retrieve the id for "x" and use it to find the corresponding loop
|
|
||||||
let res =
|
|
||||||
match perpetual::lollipops_only_loop_named(system,
|
|
||||||
translator.encode("x")) {
|
|
||||||
Some(o) => o,
|
|
||||||
None => {
|
|
||||||
println!("No loop found.");
|
|
||||||
return Ok(());
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
println!("The loop is composed by the sets:");
|
|
||||||
|
|
||||||
for e in res {
|
|
||||||
println!("{}", translator::RSsetDisplay::from(&translator, &e));
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
// equivalent to main_do(freq, PairList)
|
|
||||||
pub fn freq() -> std::io::Result<()> {
|
|
||||||
let mut translator = Translator::new();
|
|
||||||
|
|
||||||
let mut path = env::current_dir()?;
|
|
||||||
// file to read is inside testing/
|
|
||||||
path = path.join("testing/first.system");
|
|
||||||
let system = read_file(&mut translator, path, parser_system)?;
|
|
||||||
|
|
||||||
let res = match frequency::naive_frequency(&system) {
|
|
||||||
Ok(f) => f,
|
|
||||||
Err(e) => {
|
|
||||||
println!("Error computing target: {e}");
|
|
||||||
return Ok(());
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
println!(
|
|
||||||
"Frequency of encountered symbols:\n{}",
|
|
||||||
translator::FrequencyDisplay::from(&translator, &res)
|
|
||||||
);
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
// equivalent to main_do(limitfreq, PairList)
|
|
||||||
pub fn limit_freq() -> std::io::Result<()> {
|
|
||||||
let mut translator = Translator::new();
|
|
||||||
|
|
||||||
let mut path = env::current_dir()?;
|
|
||||||
// file to read is inside testing/
|
|
||||||
path = path.join("testing/first.system");
|
|
||||||
let system = read_file(&mut translator, path, parser_system)?;
|
|
||||||
|
|
||||||
path = env::current_dir()?;
|
|
||||||
path = path.join("testing/first.experiment");
|
|
||||||
let (_, sets) = read_file(&mut translator, path, parser_experiment)?;
|
|
||||||
|
|
||||||
let res = match frequency::limit_frequency(&sets,
|
|
||||||
&system.reaction_rules,
|
|
||||||
&system.available_entities) {
|
|
||||||
Some(e) => e,
|
|
||||||
None => {return Ok(());}
|
|
||||||
};
|
|
||||||
|
|
||||||
println!(
|
|
||||||
"Frequency of encountered symbols:\n{}",
|
|
||||||
translator::FrequencyDisplay::from(&translator, &res)
|
|
||||||
);
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
// equivalent to main_do(fastfreq, PairList)
|
|
||||||
pub fn fast_freq() -> std::io::Result<()> {
|
|
||||||
let mut translator = Translator::new();
|
|
||||||
|
|
||||||
let mut path = env::current_dir()?;
|
|
||||||
// file to read is inside testing/
|
|
||||||
path = path.join("testing/first.system");
|
|
||||||
let system = read_file(&mut translator, path, parser_system)?;
|
|
||||||
|
|
||||||
path = env::current_dir()?;
|
|
||||||
path = path.join("testing/first.experiment");
|
|
||||||
let (weights, sets) = read_file(&mut translator, path, parser_experiment)?;
|
|
||||||
|
|
||||||
let res = match frequency::fast_frequency(&sets,
|
|
||||||
&system.reaction_rules,
|
|
||||||
&system.available_entities,
|
|
||||||
&weights) {
|
|
||||||
Some(e) => e,
|
|
||||||
None => {return Ok(());}
|
|
||||||
};
|
|
||||||
|
|
||||||
println!(
|
|
||||||
"Frequency of encountered symbols:\n{}",
|
|
||||||
translator::FrequencyDisplay::from(&translator, &res)
|
|
||||||
);
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
// equivalent to main_do(digraph, Arcs)
|
|
||||||
pub fn digraph() -> std::io::Result<()> {
|
|
||||||
let mut translator = Translator::new();
|
|
||||||
|
|
||||||
let mut path = env::current_dir()?;
|
|
||||||
// file to read is inside testing/
|
|
||||||
path = path.join("testing/first.system");
|
|
||||||
let system = read_file(&mut translator, path, parser_system)?;
|
|
||||||
|
|
||||||
// the system needs to terminate to return
|
|
||||||
let res = match graph::digraph(system) {
|
|
||||||
Ok(o) => o,
|
|
||||||
Err(e) => {
|
|
||||||
println!("Error computing target: {e}");
|
|
||||||
return Ok(());
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
let rc_translator = Rc::new(translator);
|
|
||||||
|
|
||||||
let old_res = Rc::new(res.clone());
|
|
||||||
|
|
||||||
// map each value to the corresponding value we want to display
|
|
||||||
let res = res.map(
|
|
||||||
|id, node|
|
|
||||||
graph::GraphMapNodesTy::from(graph::GraphMapNodes::Entities,
|
|
||||||
Rc::clone(&rc_translator)).get()(id, node)
|
|
||||||
+ "; " +
|
|
||||||
&graph::GraphMapNodesTy::from(graph::GraphMapNodes::Context,
|
|
||||||
Rc::clone(&rc_translator)).get()(id, node),
|
|
||||||
graph::GraphMapEdgesTy::from(graph::GraphMapEdges::EntitiesAdded,
|
|
||||||
Rc::clone(&rc_translator)).get()
|
|
||||||
);
|
|
||||||
|
|
||||||
println!("Generated graph in dot notation:\n{}",
|
|
||||||
rsdot::RSDot::with_attr_getters(
|
|
||||||
&res,
|
|
||||||
&[],
|
|
||||||
&graph::default_edge_formatter(Rc::clone(&old_res)),
|
|
||||||
&graph::default_node_formatter(Rc::clone(&old_res)),
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn graphml() -> std::io::Result<()> {
|
|
||||||
let mut translator = Translator::new();
|
|
||||||
|
|
||||||
let mut path = env::current_dir()?;
|
|
||||||
// file to read is inside testing/
|
|
||||||
path = path.join("testing/first.system");
|
|
||||||
let system = read_file(&mut translator, path.clone(), parser_system)?;
|
|
||||||
|
|
||||||
// the system needs to terminate to return
|
|
||||||
let res = match graph::digraph(system) {
|
|
||||||
Ok(o) => o,
|
|
||||||
Err(e) => {
|
|
||||||
println!("Error computing target: {e}");
|
|
||||||
return Ok(());
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
let rc_translator = Rc::new(translator);
|
|
||||||
|
|
||||||
//let old_res = Rc::new(res.clone());
|
|
||||||
|
|
||||||
// map each value to the corresponding value we want to display
|
|
||||||
let res = res.map(
|
|
||||||
|id, node|
|
|
||||||
graph::GraphMapNodesTy::from(graph::GraphMapNodes::Entities,
|
|
||||||
Rc::clone(&rc_translator)).get()(id, node)
|
|
||||||
+ "; " +
|
|
||||||
&graph::GraphMapNodesTy::from(graph::GraphMapNodes::Context,
|
|
||||||
Rc::clone(&rc_translator)).get()(id, node),
|
|
||||||
graph::GraphMapEdgesTy::from(graph::GraphMapEdges::EntitiesAdded,
|
|
||||||
Rc::clone(&rc_translator)).get()
|
|
||||||
);
|
|
||||||
|
|
||||||
path.set_extension("graphml");
|
|
||||||
|
|
||||||
use petgraph_graphml::GraphMl;
|
|
||||||
let graphml = GraphMl::new(&res)
|
|
||||||
.pretty_print(true)
|
|
||||||
.export_node_weights_display()
|
|
||||||
.export_edge_weights_display();
|
|
||||||
println!("Generated graph in graphml notation:\n{graphml}");
|
|
||||||
save_file(graphml.to_string(), path)?;
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
// equivalent to main_do(advdigraph, Arcs)
|
|
||||||
pub fn adversarial() -> std::io::Result<()> {
|
|
||||||
let mut translator = Translator::new();
|
|
||||||
|
|
||||||
let mut path = env::current_dir()?;
|
|
||||||
// file to read is inside testing/
|
|
||||||
path = path.join("testing/adversarial.system");
|
|
||||||
let system = read_file(&mut translator, path, parser_system)?;
|
|
||||||
|
|
||||||
// the system needs to terminate to return
|
|
||||||
let res = match graph::digraph(system) {
|
|
||||||
Ok(o) => o,
|
|
||||||
Err(e) => {
|
|
||||||
println!("Error computing target: {e}");
|
|
||||||
return Ok(());
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
let rc_translator = Rc::new(translator);
|
|
||||||
|
|
||||||
let old_res = Rc::new(res.clone());
|
|
||||||
|
|
||||||
// map each value to the corresponding value we want to display
|
|
||||||
let res = res.map(
|
|
||||||
|id, node|
|
|
||||||
graph::GraphMapNodesTy::from(graph::GraphMapNodes::Entities,
|
|
||||||
Rc::clone(&rc_translator)).get()(id, node)
|
|
||||||
+ "; " +
|
|
||||||
&graph::GraphMapNodesTy::from(graph::GraphMapNodes::Context,
|
|
||||||
Rc::clone(&rc_translator)).get()(id, node),
|
|
||||||
graph::GraphMapEdgesTy::from(graph::GraphMapEdges::EntitiesAdded,
|
|
||||||
Rc::clone(&rc_translator)).get()
|
|
||||||
);
|
|
||||||
|
|
||||||
println!("Generated graph in dot notation:\n{}",
|
|
||||||
rsdot::RSDot::with_attr_getters(
|
|
||||||
&res,
|
|
||||||
&[],
|
|
||||||
&graph::default_edge_formatter(Rc::clone(&old_res)),
|
|
||||||
&graph::default_node_formatter(Rc::clone(&old_res)),
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn serialize() -> std::io::Result<()> {
|
|
||||||
let mut translator = Translator::new();
|
|
||||||
|
|
||||||
let mut path = env::current_dir()?;
|
|
||||||
// file to read is inside testing/
|
|
||||||
path = path.join("testing/adversarial.system");
|
|
||||||
let system = read_file(&mut translator, path, parser_system)?;
|
|
||||||
|
|
||||||
// the system needs to terminate to return
|
|
||||||
let graph = match graph::digraph(system) {
|
|
||||||
Ok(o) => o,
|
|
||||||
Err(e) => {
|
|
||||||
println!("Error computing target: {e}");
|
|
||||||
return Ok(());
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
let mut path = env::current_dir()?;
|
|
||||||
path = path.join("testing/adversarial.cbor");
|
|
||||||
|
|
||||||
let file = File::create(path)?;
|
|
||||||
|
|
||||||
serialize::sr(file, &graph, &translator).unwrap();
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn deserialize() -> std::io::Result<()> {
|
|
||||||
let mut path = env::current_dir()?;
|
|
||||||
path = path.join("testing/adversarial.cbor");
|
|
||||||
|
|
||||||
let file = File::open(path)?;
|
|
||||||
|
|
||||||
let (graph, translator) = serialize::dsr(file).unwrap();
|
|
||||||
|
|
||||||
let rc_translator = Rc::new(translator);
|
|
||||||
|
|
||||||
let old_res = Rc::new(graph.clone());
|
|
||||||
|
|
||||||
// map each value to the corresponding value we want to display
|
|
||||||
let graph = graph.map(
|
|
||||||
|id, node|
|
|
||||||
graph::GraphMapNodesTy::from(graph::GraphMapNodes::Entities,
|
|
||||||
Rc::clone(&rc_translator)).get()(id, node)
|
|
||||||
+ "; " +
|
|
||||||
&graph::GraphMapNodesTy::from(graph::GraphMapNodes::Context,
|
|
||||||
Rc::clone(&rc_translator)).get()(id, node),
|
|
||||||
graph::GraphMapEdgesTy::from(graph::GraphMapEdges::EntitiesAdded,
|
|
||||||
Rc::clone(&rc_translator)).get()
|
|
||||||
);
|
|
||||||
|
|
||||||
println!("Generated graph in dot notation:\n{}",
|
|
||||||
rsdot::RSDot::with_attr_getters(
|
|
||||||
&graph,
|
|
||||||
&[],
|
|
||||||
&graph::default_edge_formatter(Rc::clone(&old_res)),
|
|
||||||
&graph::default_node_formatter(Rc::clone(&old_res)),
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
@ -1,7 +1,6 @@
|
|||||||
//! Module root
|
//! Module root
|
||||||
|
|
||||||
pub mod rsprocess;
|
pub mod rsprocess;
|
||||||
pub mod examples;
|
|
||||||
|
|
||||||
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
|
||||||
|
|||||||
@ -1,8 +1,8 @@
|
|||||||
fn main() -> std::io::Result<()> {
|
fn main() {
|
||||||
// let now = std::time::Instant::now();
|
// let now = std::time::Instant::now();
|
||||||
// println!("{}", now.elapsed().as_micros());
|
// println!("{}", now.elapsed().as_micros());
|
||||||
|
|
||||||
reactionsystems::examples::graphml()?;
|
let (g, t) = reactionsystems::rsprocess::presets::digraph("testing/first.system".into()).unwrap();
|
||||||
|
|
||||||
Ok(())
|
reactionsystems::rsprocess::presets::dot(&g, &t, "testing/first.dot".into()).unwrap();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -86,8 +86,8 @@ pub fn loop_frequency(system: &RSsystem, symb: IdType) -> Frequency {
|
|||||||
freq
|
freq
|
||||||
}
|
}
|
||||||
|
|
||||||
/// ```q[i]``` is given enough times such that the stabilizes in a loop, calculate the
|
/// ```q[i]``` is given enough times such that the stabilizes in a loop,
|
||||||
/// frequency of the symbols in any state in the last loop
|
/// calculate the frequency of the symbols in any state in the last loop
|
||||||
/// see limitFreq
|
/// see limitFreq
|
||||||
pub fn limit_frequency(
|
pub fn limit_frequency(
|
||||||
q: &[RSset],
|
q: &[RSset],
|
||||||
@ -114,8 +114,8 @@ pub fn limit_frequency(
|
|||||||
Some(freq)
|
Some(freq)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// ```q[i]``` is given enough times such that the stabilizes in a loop, calculate the
|
/// ```q[i]``` is given enough times such that the stabilizes in a loop,
|
||||||
/// frequency of the symbols in any state in any loop, weighted.
|
/// calculate the frequency of the symbols in any state in any loop, weighted.
|
||||||
/// see fastFreq
|
/// see fastFreq
|
||||||
pub fn fast_frequency(
|
pub fn fast_frequency(
|
||||||
q: &[RSset],
|
q: &[RSset],
|
||||||
|
|||||||
@ -12,3 +12,4 @@ pub mod translator;
|
|||||||
pub mod graph;
|
pub mod graph;
|
||||||
pub mod rsdot;
|
pub mod rsdot;
|
||||||
pub mod serialize;
|
pub mod serialize;
|
||||||
|
pub mod presets;
|
||||||
|
|||||||
488
src/rsprocess/presets.rs
Normal file
488
src/rsprocess/presets.rs
Normal file
@ -0,0 +1,488 @@
|
|||||||
|
//! Module that holds useful presets for interacting with other modules.
|
||||||
|
|
||||||
|
use std::env;
|
||||||
|
use std::fs;
|
||||||
|
use std::io;
|
||||||
|
use std::io::prelude::*;
|
||||||
|
use std::rc::Rc;
|
||||||
|
|
||||||
|
use lalrpop_util::ParseError;
|
||||||
|
use petgraph::Graph;
|
||||||
|
|
||||||
|
// grammar is defined in lib.rs, calling lalrpop_mod! twice, generates twice
|
||||||
|
// the code
|
||||||
|
use crate::grammar;
|
||||||
|
|
||||||
|
use super::structure::RSlabel;
|
||||||
|
use super::structure::{RSset, RSsystem};
|
||||||
|
use super::translator::Translator;
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
// Helper Functions
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
fn read_file<T, F>(
|
||||||
|
translator: &mut Translator,
|
||||||
|
path_string: String,
|
||||||
|
parser: F
|
||||||
|
) -> Result<T, String>
|
||||||
|
where
|
||||||
|
F: Fn(&mut Translator, String) -> Result<T, String>
|
||||||
|
{
|
||||||
|
// relative path
|
||||||
|
let mut path = match env::current_dir() {
|
||||||
|
Ok(p) => p,
|
||||||
|
Err(_) => return Err("Error getting current directory.".into())
|
||||||
|
};
|
||||||
|
path = path.join(path_string);
|
||||||
|
|
||||||
|
// we read the file with a buffer
|
||||||
|
let f = match fs::File::open(path) {
|
||||||
|
Ok(f) => f,
|
||||||
|
Err(_) => return Err("Error opening file.".into())
|
||||||
|
};
|
||||||
|
let mut buf_reader = io::BufReader::new(f);
|
||||||
|
let mut contents = String::new();
|
||||||
|
match buf_reader.read_to_string(&mut contents) {
|
||||||
|
Ok(_) => {},
|
||||||
|
Err(_) => return Err("Error reading file.".into())
|
||||||
|
}
|
||||||
|
|
||||||
|
// parse
|
||||||
|
let result = parser(translator, contents)?;
|
||||||
|
|
||||||
|
Ok(result)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn save_file(
|
||||||
|
contents: String,
|
||||||
|
path_string: String,
|
||||||
|
extension: String
|
||||||
|
) -> Result<(), String>
|
||||||
|
{
|
||||||
|
// relative path
|
||||||
|
let mut path = match env::current_dir() {
|
||||||
|
Ok(p) => p,
|
||||||
|
Err(_) => return Err("Error getting current directory.".into())
|
||||||
|
};
|
||||||
|
path = path.join(path_string);
|
||||||
|
path.set_extension(extension);
|
||||||
|
|
||||||
|
let mut f = match fs::File::create(&path) {
|
||||||
|
Ok(f) => f,
|
||||||
|
Err(_) => return Err(format!("Error creating file {}.",
|
||||||
|
path.to_str().unwrap()))
|
||||||
|
};
|
||||||
|
match write!(f, "{contents}") {
|
||||||
|
Ok(_) => {}
|
||||||
|
Err(_) => return Err("Error writing to file.".into())
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn parser_system(
|
||||||
|
translator: &mut Translator,
|
||||||
|
contents: String
|
||||||
|
) -> Result<RSsystem, String>
|
||||||
|
{
|
||||||
|
match grammar::SystemParser::new()
|
||||||
|
.parse(translator, &contents)
|
||||||
|
{
|
||||||
|
Ok(sys) => Ok(sys),
|
||||||
|
Err(e) => {
|
||||||
|
match e {
|
||||||
|
ParseError::ExtraToken { token: (l, t, r) } => {
|
||||||
|
Err(format!(
|
||||||
|
"Unexpected token \"{t}\" \
|
||||||
|
between positions {l} and {r}."
|
||||||
|
))
|
||||||
|
},
|
||||||
|
ParseError::UnrecognizedEof { location: _, expected: _ } => {
|
||||||
|
Err("End of file encountered while parsing.".into())
|
||||||
|
},
|
||||||
|
ParseError::InvalidToken { location } => {
|
||||||
|
Err(format!("Invalid token at position {location}."))
|
||||||
|
},
|
||||||
|
ParseError::UnrecognizedToken { token: (l, t, r), expected: _ }
|
||||||
|
=> {
|
||||||
|
Err(format!(
|
||||||
|
"Unexpected token \"{t}\" \
|
||||||
|
between positions {l} and {r}."
|
||||||
|
))
|
||||||
|
},
|
||||||
|
ParseError::User { error } => {
|
||||||
|
Err(error.to_string())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn parser_experiment(
|
||||||
|
translator: &mut Translator,
|
||||||
|
contents: String
|
||||||
|
) -> Result<(Vec<u32>, Vec<RSset>), String>
|
||||||
|
{
|
||||||
|
match grammar::ExperimentParser::new()
|
||||||
|
.parse(translator, &contents)
|
||||||
|
{
|
||||||
|
Ok(sys) => Ok(sys),
|
||||||
|
Err(e) => {
|
||||||
|
match e {
|
||||||
|
ParseError::ExtraToken { token: (l, t, r) } => {
|
||||||
|
Err(format!(
|
||||||
|
"Unexpected token \"{t}\" \
|
||||||
|
between positions {l} and {r}."
|
||||||
|
))
|
||||||
|
},
|
||||||
|
ParseError::UnrecognizedEof { location: _, expected: _ } => {
|
||||||
|
Err("End of file encountered while parsing.".into())
|
||||||
|
},
|
||||||
|
ParseError::InvalidToken { location } => {
|
||||||
|
Err(format!("Invalid token at position {location}."))
|
||||||
|
},
|
||||||
|
ParseError::UnrecognizedToken { token: (l, t, r), expected: _ }
|
||||||
|
=> {
|
||||||
|
Err(format!(
|
||||||
|
"Unexpected token \"{t}\" \
|
||||||
|
between positions {l} and {r}."
|
||||||
|
))
|
||||||
|
},
|
||||||
|
ParseError::User { error } => {
|
||||||
|
Err(error.to_string())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
// Methods
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/// Prints statistics of the system.
|
||||||
|
/// Equivalent main_do(stat) or main_do(stat, MissingE)
|
||||||
|
pub fn stats(path_string: String) -> Result<(), String> {
|
||||||
|
let mut translator = Translator::new();
|
||||||
|
|
||||||
|
let system = read_file(&mut translator, path_string, parser_system)?;
|
||||||
|
|
||||||
|
// print statistics to screan
|
||||||
|
println!("{}", statistics::of_RSsystem(&translator, &system));
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// Prints a final set of entities in a terminating Reaction System.
|
||||||
|
/// Equivalent to main_do(target, E)
|
||||||
|
pub fn target(path_string: String) -> Result<(), String> {
|
||||||
|
let mut translator = Translator::new();
|
||||||
|
|
||||||
|
let system = read_file(&mut translator, path_string, parser_system)?;
|
||||||
|
|
||||||
|
// the system needs to terminate to return
|
||||||
|
let res = transitions::target(&system)?;
|
||||||
|
|
||||||
|
println!(
|
||||||
|
"After {} steps we arrive at state:\n{}",
|
||||||
|
res.0,
|
||||||
|
translator::RSsetDisplay::from(&translator, &res.1)
|
||||||
|
);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Finds the list of traversed states in a (deterministic) terminating
|
||||||
|
/// reaction.
|
||||||
|
/// equivalent to main_do(run,Es)
|
||||||
|
pub fn run(path_string: String) -> Result<(), String> {
|
||||||
|
let mut translator = Translator::new();
|
||||||
|
|
||||||
|
let system = read_file(&mut translator, path_string, parser_system)?;
|
||||||
|
|
||||||
|
// the system needs to terminate to return
|
||||||
|
let res = transitions::run_separated(&system)?;
|
||||||
|
|
||||||
|
println!("The trace is composed by the set of entities:");
|
||||||
|
for (e, _c, _t) in res {
|
||||||
|
println!("{}", translator::RSsetDisplay::from(&translator, &e));
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/// Finds the looping list of states in a reaction system with a perpetual
|
||||||
|
/// context IMPORTANT: for loops, we assume Delta defines the process constant
|
||||||
|
/// x = Q.x and the context process is x .
|
||||||
|
/// equivalent to main_do(loop,Es)
|
||||||
|
pub fn hoop(path_string: String) -> Result<(), String> {
|
||||||
|
let mut translator = Translator::new();
|
||||||
|
|
||||||
|
let system = read_file(&mut translator, path_string, parser_system)?;
|
||||||
|
|
||||||
|
// we retrieve the id for "x" and use it to find the corresponding loop
|
||||||
|
let res =
|
||||||
|
match perpetual::lollipops_only_loop_named(system,
|
||||||
|
translator.encode("x")) {
|
||||||
|
Some(o) => o,
|
||||||
|
None => {
|
||||||
|
return Err("No loop found.".into());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
println!("The loop is composed by the sets:");
|
||||||
|
for e in res {
|
||||||
|
println!("{}", translator::RSsetDisplay::from(&translator, &e));
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Finds the frequency of each entity in the traversed states for a
|
||||||
|
/// (deterministic) terminating Reaction System.
|
||||||
|
/// equivalent to main_do(freq, PairList)
|
||||||
|
pub fn freq(path_string: String) -> Result<(), String> {
|
||||||
|
let mut translator = Translator::new();
|
||||||
|
|
||||||
|
let system = read_file(&mut translator, path_string, parser_system)?;
|
||||||
|
|
||||||
|
let res = frequency::naive_frequency(&system)?;
|
||||||
|
|
||||||
|
println!(
|
||||||
|
"Frequency of encountered symbols:\n{}",
|
||||||
|
translator::FrequencyDisplay::from(&translator, &res)
|
||||||
|
);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// Finds the frequency of each entity in the limit loop of a nonterminating
|
||||||
|
/// Reaction System whose context has the form Q1 ... Q1.Q2 ... Q2 ... Qn ...
|
||||||
|
/// equivalent to main_do(limitfreq, PairList)
|
||||||
|
pub fn limit_freq(
|
||||||
|
path_string_system: String,
|
||||||
|
path_string_experiment: String
|
||||||
|
) -> Result<(), String>
|
||||||
|
{
|
||||||
|
let mut translator = Translator::new();
|
||||||
|
|
||||||
|
let system = read_file(&mut translator,
|
||||||
|
path_string_system,
|
||||||
|
parser_system)?;
|
||||||
|
|
||||||
|
let (_, sets) = read_file(&mut translator,
|
||||||
|
path_string_experiment,
|
||||||
|
parser_experiment)?;
|
||||||
|
|
||||||
|
let res = match frequency::limit_frequency(&sets,
|
||||||
|
&system.reaction_rules,
|
||||||
|
&system.available_entities) {
|
||||||
|
Some(e) => e,
|
||||||
|
None => {return Err("Error calculating frequency.".into());}
|
||||||
|
};
|
||||||
|
|
||||||
|
println!(
|
||||||
|
"Frequency of encountered symbols:\n{}",
|
||||||
|
translator::FrequencyDisplay::from(&translator, &res)
|
||||||
|
);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// Finds the frequency of each entity in the traversed loops of a terminating
|
||||||
|
/// reaction system whose context has the form
|
||||||
|
/// Q1 ... Q1.Q2 ... Q2 ... Qn ... Qn.nil and each Qi is repeated Wi times
|
||||||
|
/// read from a corresponding file.
|
||||||
|
/// equivalent to main_do(fastfreq, PairList)
|
||||||
|
pub fn fast_freq(
|
||||||
|
path_string_system: String,
|
||||||
|
path_string_experiment: String
|
||||||
|
) -> Result<(), String>
|
||||||
|
{
|
||||||
|
let mut translator = Translator::new();
|
||||||
|
|
||||||
|
let system = read_file(&mut translator,
|
||||||
|
path_string_system,
|
||||||
|
parser_system)?;
|
||||||
|
|
||||||
|
let (weights, sets) = read_file(&mut translator,
|
||||||
|
path_string_experiment,
|
||||||
|
parser_experiment)?;
|
||||||
|
|
||||||
|
let res = match frequency::fast_frequency(&sets,
|
||||||
|
&system.reaction_rules,
|
||||||
|
&system.available_entities,
|
||||||
|
&weights) {
|
||||||
|
Some(e) => e,
|
||||||
|
None => {return Err("Error calculating frequency.".into());}
|
||||||
|
};
|
||||||
|
|
||||||
|
println!(
|
||||||
|
"Frequency of encountered symbols:\n{}",
|
||||||
|
translator::FrequencyDisplay::from(&translator, &res)
|
||||||
|
);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Computes the LTS.
|
||||||
|
/// equivalent to main_do(digraph, Arcs) or to main_do(advdigraph, Arcs)
|
||||||
|
pub fn digraph(
|
||||||
|
path_string: String
|
||||||
|
) -> Result<(Graph<RSsystem, RSlabel>, Translator), String> {
|
||||||
|
let mut translator = Translator::new();
|
||||||
|
|
||||||
|
let system = read_file(&mut translator, path_string, parser_system)?;
|
||||||
|
|
||||||
|
// the system needs to terminate to return
|
||||||
|
let res = graph::digraph(system)?;
|
||||||
|
Ok((res, translator))
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// Output Functions
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/// Writes the specified graph to a file in .dot format.
|
||||||
|
pub fn dot(
|
||||||
|
graph: &Graph<RSsystem, RSlabel>,
|
||||||
|
translator: &Translator,
|
||||||
|
output: String
|
||||||
|
) -> Result<(), String>
|
||||||
|
{
|
||||||
|
let rc_translator = Rc::new(translator.to_owned());
|
||||||
|
|
||||||
|
// map each value to the corresponding value we want to display
|
||||||
|
let modified_graph = graph.map(
|
||||||
|
|id, node|
|
||||||
|
graph::GraphMapNodesTy::from(
|
||||||
|
graph::GraphMapNodes::Entities,
|
||||||
|
Rc::clone(&rc_translator)
|
||||||
|
).get()(id, node)
|
||||||
|
+ "; " +
|
||||||
|
&graph::GraphMapNodesTy::from(
|
||||||
|
graph::GraphMapNodes::Context,
|
||||||
|
Rc::clone(&rc_translator)
|
||||||
|
).get()(id, node),
|
||||||
|
graph::GraphMapEdgesTy::from(
|
||||||
|
graph::GraphMapEdges::EntitiesAdded,
|
||||||
|
Rc::clone(&rc_translator)
|
||||||
|
).get()
|
||||||
|
);
|
||||||
|
|
||||||
|
let graph = Rc::new(graph.to_owned());
|
||||||
|
|
||||||
|
let edge_formatter = graph::default_edge_formatter(Rc::clone(&graph));
|
||||||
|
let node_formatter = graph::default_node_formatter(Rc::clone(&graph));
|
||||||
|
|
||||||
|
let dot = rsdot::RSDot::with_attr_getters(
|
||||||
|
&modified_graph,
|
||||||
|
&[],
|
||||||
|
&edge_formatter,
|
||||||
|
&node_formatter,
|
||||||
|
);
|
||||||
|
|
||||||
|
save_file(format!("{dot}"), output, "dot".into())?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Writes the specified graph to a file in .graphml format.
|
||||||
|
pub fn graphml(
|
||||||
|
graph: &Graph<RSsystem, RSlabel>,
|
||||||
|
translator: &Translator,
|
||||||
|
output: String
|
||||||
|
) -> Result<(), String>
|
||||||
|
{
|
||||||
|
let rc_translator = Rc::new(translator.to_owned());
|
||||||
|
|
||||||
|
// map each value to the corresponding value we want to display
|
||||||
|
let modified_graph = graph.map(
|
||||||
|
|id, node|
|
||||||
|
graph::GraphMapNodesTy::from(
|
||||||
|
graph::GraphMapNodes::Entities,
|
||||||
|
Rc::clone(&rc_translator)
|
||||||
|
).get()(id, node)
|
||||||
|
+ "; " +
|
||||||
|
&graph::GraphMapNodesTy::from(
|
||||||
|
graph::GraphMapNodes::Context,
|
||||||
|
Rc::clone(&rc_translator)
|
||||||
|
).get()(id, node),
|
||||||
|
graph::GraphMapEdgesTy::from(graph::GraphMapEdges::EntitiesAdded,
|
||||||
|
Rc::clone(&rc_translator)).get()
|
||||||
|
);
|
||||||
|
|
||||||
|
use petgraph_graphml::GraphMl;
|
||||||
|
let graphml = GraphMl::new(&modified_graph)
|
||||||
|
.pretty_print(true)
|
||||||
|
.export_node_weights_display()
|
||||||
|
.export_edge_weights_display();
|
||||||
|
|
||||||
|
save_file(format!("{graphml}"), output, "graphml".into())?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Writes the specified graph, translator tuple to file.
|
||||||
|
/// N.B. graph size in memory might be much larger after serialization and
|
||||||
|
/// deserialization.
|
||||||
|
pub fn serialize(
|
||||||
|
graph: &Graph<RSsystem, RSlabel>,
|
||||||
|
translator: &Translator,
|
||||||
|
output_path: String
|
||||||
|
) -> Result<(), String>
|
||||||
|
{
|
||||||
|
// relative path
|
||||||
|
let mut path = match env::current_dir() {
|
||||||
|
Ok(p) => p,
|
||||||
|
Err(_) => return Err("Error getting current directory.".into())
|
||||||
|
};
|
||||||
|
path = path.join(output_path);
|
||||||
|
path.set_extension("cbor");
|
||||||
|
|
||||||
|
let f = match fs::File::create(&path) {
|
||||||
|
Ok(f) => f,
|
||||||
|
Err(_) => return Err(format!("Error creating file {}.",
|
||||||
|
path.to_str().unwrap()))
|
||||||
|
};
|
||||||
|
|
||||||
|
match serialize::ser(f, graph, translator) {
|
||||||
|
Ok(_) => Ok(()),
|
||||||
|
Err(_) => Err("Error during serialization.".into())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Reads the specified serialized system from a file.
|
||||||
|
/// N.B. graph size in memory might be much larger after serialization and
|
||||||
|
/// deserialization
|
||||||
|
pub fn deserialize(
|
||||||
|
input_path: String
|
||||||
|
) -> Result<(Graph<RSsystem, RSlabel>, Translator), String>
|
||||||
|
{
|
||||||
|
// relative path
|
||||||
|
let mut path = match env::current_dir() {
|
||||||
|
Ok(p) => p,
|
||||||
|
Err(_) => return Err("Error getting current directory.".into())
|
||||||
|
};
|
||||||
|
path = path.join(input_path);
|
||||||
|
path.set_extension("cbor");
|
||||||
|
|
||||||
|
let f = match fs::File::open(&path) {
|
||||||
|
Ok(f) => f,
|
||||||
|
Err(_) => return Err(format!("Error opening file {}.",
|
||||||
|
path.to_str().unwrap()))
|
||||||
|
};
|
||||||
|
|
||||||
|
match serialize::de(f) {
|
||||||
|
Ok(a) => Ok(a),
|
||||||
|
Err(_) => Err("Error during deserialization.".into())
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,6 +1,8 @@
|
|||||||
//! Slightly modified Simple graphviz dot file format output.
|
//! Slightly modified Simple graphviz dot file format output.
|
||||||
//! See petgraph::dot::mod.
|
//! See petgraph::dot::mod.
|
||||||
|
|
||||||
|
static PRINTNAMES: bool = false;
|
||||||
|
|
||||||
use core::fmt::{self, Display, Write};
|
use core::fmt::{self, Display, Write};
|
||||||
use petgraph::
|
use petgraph::
|
||||||
{
|
{
|
||||||
@ -205,10 +207,15 @@ where
|
|||||||
|
|
||||||
// output all labels
|
// output all labels
|
||||||
for node in g.node_references() {
|
for node in g.node_references() {
|
||||||
|
if PRINTNAMES {
|
||||||
write!(f, "{INDENT}\"")?;
|
write!(f, "{INDENT}\"")?;
|
||||||
// Escaped(FnFmt(node.weight(), &node_fmt)).fmt(f)?;
|
Escaped(FnFmt(node.weight(), &node_fmt)).fmt(f)?;
|
||||||
write!(f, "{}", g.to_index(node.id()))?;
|
|
||||||
write!(f, "\" [ ")?;
|
write!(f, "\" [ ")?;
|
||||||
|
} else {
|
||||||
|
write!(f, "{INDENT}")?;
|
||||||
|
write!(f, "{}", g.to_index(node.id()))?;
|
||||||
|
write!(f, " [ ")?;
|
||||||
|
}
|
||||||
|
|
||||||
write!(f, "label = \"")?;
|
write!(f, "label = \"")?;
|
||||||
Escaped(FnFmt(node.weight(), &node_fmt)).fmt(f)?;
|
Escaped(FnFmt(node.weight(), &node_fmt)).fmt(f)?;
|
||||||
@ -218,15 +225,21 @@ where
|
|||||||
}
|
}
|
||||||
// output all edges
|
// output all edges
|
||||||
for edge in g.edge_references() {
|
for edge in g.edge_references() {
|
||||||
|
if PRINTNAMES {
|
||||||
write!(f, "{INDENT}\"")?;
|
write!(f, "{INDENT}\"")?;
|
||||||
// let node_source_weight = g.node_weight(edge.source()).unwrap();
|
let node_source_weight = g.node_weight(edge.source()).unwrap();
|
||||||
// Escaped(FnFmt(node_source_weight, &node_fmt)).fmt(f)?;
|
Escaped(FnFmt(node_source_weight, &node_fmt)).fmt(f)?;
|
||||||
write!(f, "{}", g.to_index(edge.source()))?;
|
|
||||||
write!(f, "\" {} \"", EDGE[g.is_directed() as usize])?;
|
write!(f, "\" {} \"", EDGE[g.is_directed() as usize])?;
|
||||||
// let node_target_weight = g.node_weight(edge.target()).unwrap();
|
let node_target_weight = g.node_weight(edge.target()).unwrap();
|
||||||
// Escaped(FnFmt(node_target_weight, &node_fmt)).fmt(f)?;
|
Escaped(FnFmt(node_target_weight, &node_fmt)).fmt(f)?;
|
||||||
write!(f, "{}", g.to_index(edge.target()))?;
|
|
||||||
write!(f, "\" [ ")?;
|
write!(f, "\" [ ")?;
|
||||||
|
} else {
|
||||||
|
write!(f, "{INDENT}")?;
|
||||||
|
write!(f, "{} ", g.to_index(edge.source()))?;
|
||||||
|
write!(f, "{} ", EDGE[g.is_directed() as usize])?;
|
||||||
|
write!(f, "{} ", g.to_index(edge.target()))?;
|
||||||
|
write!(f, "[ ")?;
|
||||||
|
}
|
||||||
|
|
||||||
write!(f, "label = \"")?;
|
write!(f, "label = \"")?;
|
||||||
Escaped(FnFmt(edge.weight(), &edge_fmt)).fmt(f)?;
|
Escaped(FnFmt(edge.weight(), &edge_fmt)).fmt(f)?;
|
||||||
|
|||||||
@ -18,7 +18,7 @@ struct GraphAndTranslator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Serializer for graph and translator.
|
/// Serializer for graph and translator.
|
||||||
pub fn sr<W>(
|
pub fn ser<W>(
|
||||||
writer: W,
|
writer: W,
|
||||||
graph: &Graph<RSsystem, RSlabel>,
|
graph: &Graph<RSsystem, RSlabel>,
|
||||||
translator: &Translator
|
translator: &Translator
|
||||||
@ -34,7 +34,7 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Deserializer for file that contains graph and translator.
|
/// Deserializer for file that contains graph and translator.
|
||||||
pub fn dsr<R>(
|
pub fn de<R>(
|
||||||
reader: R
|
reader: R
|
||||||
) -> Result<(Graph<RSsystem, RSlabel>, Translator), serde_cbor_2::Error>
|
) -> Result<(Graph<RSsystem, RSlabel>, Translator), serde_cbor_2::Error>
|
||||||
where
|
where
|
||||||
|
|||||||
@ -4,7 +4,6 @@ use super::structure::{RSlabel, RSprocess, RSset, RSsystem};
|
|||||||
use super::transitions::unfold;
|
use super::transitions::unfold;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|
||||||
///
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct TransitionsIterator<'a> {
|
pub struct TransitionsIterator<'a> {
|
||||||
choices_iterator: std::vec::IntoIter<(Rc<RSset>, Rc<RSprocess>)>,
|
choices_iterator: std::vec::IntoIter<(Rc<RSset>, Rc<RSprocess>)>,
|
||||||
|
|||||||
Reference in New Issue
Block a user