now workspaces for modular compilation (maybe faster)
This commit is contained in:
20
Cargo.toml
20
Cargo.toml
@ -1,21 +1,7 @@
|
|||||||
[package]
|
[workspace]
|
||||||
name = "reactionsystems"
|
resolver = "3"
|
||||||
version = "0.1.0"
|
members = [ "analysis", "assert", "bisimilarity", "execution","grammar", "rsprocess"]
|
||||||
edition = "2024"
|
|
||||||
exclude = ["*.system", "*.experiment", "/testing/", "*.serial", "*.dot", "*.trace", "*.svg"]
|
exclude = ["*.system", "*.experiment", "/testing/", "*.serial", "*.dot", "*.trace", "*.svg"]
|
||||||
|
|
||||||
[build-dependencies]
|
|
||||||
lalrpop = "0.22"
|
|
||||||
|
|
||||||
[dependencies]
|
|
||||||
rand = { version = "*" }
|
|
||||||
colored = { version = "*" }
|
|
||||||
regex = { version = "1", features = ["unicode-bool"] }
|
|
||||||
lalrpop-util = { version = "*", features = ["lexer", "unicode"] }
|
|
||||||
petgraph = { version = "*", features = ["serde-1"] }
|
|
||||||
petgraph-graphml = { version = "5" }
|
|
||||||
serde = { version = "1", features = ["derive", "rc"] }
|
|
||||||
serde_cbor_2 = { version = "*" }
|
|
||||||
|
|
||||||
[profile.dev]
|
[profile.dev]
|
||||||
split-debuginfo = "unpacked"
|
split-debuginfo = "unpacked"
|
||||||
|
|||||||
11
analysis/Cargo.toml
Normal file
11
analysis/Cargo.toml
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
[package]
|
||||||
|
name = "analysis"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2024"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
rsprocess = { path = "../rsprocess/" }
|
||||||
|
execution = { path = "../execution/" }
|
||||||
|
grammar = { path = "../grammar/" }
|
||||||
|
colored = { version = "*" }
|
||||||
|
lalrpop-util = { version = "*", features = ["lexer", "unicode"] }
|
||||||
113
analysis/src/helper.rs
Normal file
113
analysis/src/helper.rs
Normal file
@ -0,0 +1,113 @@
|
|||||||
|
use execution::presets;
|
||||||
|
use lalrpop_util::ParseError;
|
||||||
|
use std::fmt::Display;
|
||||||
|
use grammar::grammar;
|
||||||
|
|
||||||
|
pub struct Parsers {}
|
||||||
|
|
||||||
|
impl presets::FileParsers for Parsers {
|
||||||
|
fn parse_experiment(
|
||||||
|
translator: &mut rsprocess::translator::Translator,
|
||||||
|
contents: String,
|
||||||
|
) -> Result<(Vec<u32>, Vec<rsprocess::set::Set>), String> {
|
||||||
|
match grammar::ExperimentParser::new().parse(translator, &contents) {
|
||||||
|
| Ok(sys) => Ok(sys),
|
||||||
|
| Err(e) => reformat_error(e, &contents),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn parse_instructions(
|
||||||
|
translator: &mut rsprocess::translator::Translator,
|
||||||
|
contents: String,
|
||||||
|
) -> Result<presets::Instructions, String> {
|
||||||
|
match grammar::RunParser::new().parse(translator, &contents) {
|
||||||
|
| Ok(sys) => Ok(sys),
|
||||||
|
| Err(e) => reformat_error(e, &contents),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn reformat_error<T, S>(
|
||||||
|
e: ParseError<usize, T, &'static str>,
|
||||||
|
input_str: &str,
|
||||||
|
) -> Result<S, String>
|
||||||
|
where
|
||||||
|
T: Display,
|
||||||
|
{
|
||||||
|
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,
|
||||||
|
} => {
|
||||||
|
use colored::Colorize;
|
||||||
|
|
||||||
|
let mut err = format!(
|
||||||
|
"Unrecognized token {}{}{} \
|
||||||
|
between positions {l} and {r}.",
|
||||||
|
"\"".red(),
|
||||||
|
t.to_string().red(),
|
||||||
|
"\"".red(),
|
||||||
|
);
|
||||||
|
|
||||||
|
// Temporary debug.
|
||||||
|
err.push_str("\nExpected: ");
|
||||||
|
let mut it = expected.iter().peekable();
|
||||||
|
while let Some(s) = it.next() {
|
||||||
|
err.push('(');
|
||||||
|
err.push_str(&format!("{}", s.green()));
|
||||||
|
err.push(')');
|
||||||
|
if it.peek().is_some() {
|
||||||
|
err.push(',');
|
||||||
|
err.push(' ');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let right_new_line = input_str[l..]
|
||||||
|
.find("\n")
|
||||||
|
.map(|pos| pos + l)
|
||||||
|
.unwrap_or(input_str.len());
|
||||||
|
let left_new_line = input_str[..r]
|
||||||
|
.rfind("\n")
|
||||||
|
.map(|pos| pos + 1)
|
||||||
|
.unwrap_or_default();
|
||||||
|
|
||||||
|
let line_number = input_str[..l].match_indices('\n').count() + 1;
|
||||||
|
let pre_no_color = format!("{line_number} |");
|
||||||
|
let pre = format!("{}", pre_no_color.blue());
|
||||||
|
|
||||||
|
let line_pos_l = l - left_new_line;
|
||||||
|
let line_pos_r = r - left_new_line;
|
||||||
|
|
||||||
|
err.push_str(&format!(
|
||||||
|
"\nLine {} position {} to {}:\n{}{}{}{}",
|
||||||
|
line_number,
|
||||||
|
line_pos_l,
|
||||||
|
line_pos_r,
|
||||||
|
&pre,
|
||||||
|
&input_str[left_new_line..l].green(),
|
||||||
|
&input_str[l..r].red(),
|
||||||
|
&input_str[r..right_new_line],
|
||||||
|
));
|
||||||
|
err.push('\n');
|
||||||
|
err.push_str(&" ".repeat(pre_no_color.len() - 1));
|
||||||
|
err.push_str(&format!("{}", "|".blue()));
|
||||||
|
err.push_str(&" ".repeat(l - left_new_line));
|
||||||
|
err.push_str(&format!("{}", &"↑".red()));
|
||||||
|
if r - l > 2 {
|
||||||
|
err.push_str(&" ".repeat(r - l - 2));
|
||||||
|
err.push_str(&format!("{}", &"↑".red()));
|
||||||
|
}
|
||||||
|
|
||||||
|
Err(err)
|
||||||
|
},
|
||||||
|
| ParseError::User { error } => Err(error.to_string()),
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,5 +1,7 @@
|
|||||||
|
mod helper;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
use reactionsystems::rsprocess::presets;
|
use execution::presets;
|
||||||
|
|
||||||
let mut input = String::new();
|
let mut input = String::new();
|
||||||
std::io::stdin().read_line(&mut input).unwrap();
|
std::io::stdin().read_line(&mut input).unwrap();
|
||||||
@ -7,7 +9,7 @@ fn main() {
|
|||||||
|
|
||||||
let now = std::time::Instant::now();
|
let now = std::time::Instant::now();
|
||||||
|
|
||||||
match presets::run(input) {
|
match presets::run::<helper::Parsers>(input) {
|
||||||
| Ok(()) => {},
|
| Ok(()) => {},
|
||||||
| Err(e) => println!("{e}"),
|
| Err(e) => println!("{e}"),
|
||||||
}
|
}
|
||||||
10
assert/Cargo.toml
Normal file
10
assert/Cargo.toml
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
[package]
|
||||||
|
name = "assert"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2024"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
rand = { version = "*" }
|
||||||
|
rsprocess = { path = "../rsprocess/" }
|
||||||
|
petgraph = { version = "*", features = ["serde-1"] }
|
||||||
|
petgraph-graphml = { version = "*" }
|
||||||
@ -1,7 +1,7 @@
|
|||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
use super::super::set::BasicSet;
|
use rsprocess::set::BasicSet;
|
||||||
use super::super::{element, graph, label, process, set, system, translator};
|
use rsprocess::{element, graph, label, process, set, system, translator};
|
||||||
|
|
||||||
/// If changing IntegerType in assert.rs, also change from Num to another
|
/// If changing IntegerType in assert.rs, also change from Num to another
|
||||||
/// similar parser with different return type in grammar.lalrpop in
|
/// similar parser with different return type in grammar.lalrpop in
|
||||||
@ -3,7 +3,7 @@
|
|||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
|
||||||
use super::super::translator::{
|
use rsprocess::translator::{
|
||||||
Formatter, PrintableWithTranslator, Translator,
|
Formatter, PrintableWithTranslator, Translator,
|
||||||
};
|
};
|
||||||
use super::dsl::*;
|
use super::dsl::*;
|
||||||
@ -1,8 +1,8 @@
|
|||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
use super::super::{graph, label, set, system, translator};
|
|
||||||
use super::dsl::*;
|
use super::dsl::*;
|
||||||
use crate::rsprocess::translator::PrintableWithTranslator;
|
use rsprocess::{graph, label, set, system, translator};
|
||||||
|
use rsprocess::translator::PrintableWithTranslator;
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
// Specific Assert Implementation
|
// Specific Assert Implementation
|
||||||
@ -1,4 +1,4 @@
|
|||||||
use super::super::{environment, label, process, set, system, translator};
|
use rsprocess::{environment, label, process, set, system, translator};
|
||||||
use super::dsl::*;
|
use super::dsl::*;
|
||||||
use super::rsassert::*;
|
use super::rsassert::*;
|
||||||
|
|
||||||
7
bisimilarity/Cargo.toml
Normal file
7
bisimilarity/Cargo.toml
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
[package]
|
||||||
|
name = "bisimilarity"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2024"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
petgraph = { version = "0.8", features = ["serde-1"] }
|
||||||
2
build.rs
2
build.rs
@ -1,3 +1,3 @@
|
|||||||
fn main() {
|
fn main() {
|
||||||
lalrpop::process_src().unwrap();
|
// lalrpop::process_src().unwrap();
|
||||||
}
|
}
|
||||||
|
|||||||
13
execution/Cargo.toml
Normal file
13
execution/Cargo.toml
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
[package]
|
||||||
|
name = "execution"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2024"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
rsprocess = { path = "../rsprocess/" }
|
||||||
|
assert = { path = "../assert/" }
|
||||||
|
bisimilarity = { path = "../bisimilarity/" }
|
||||||
|
colored = { version = "*" }
|
||||||
|
petgraph = { version = "0.8", features = ["serde-1"] }
|
||||||
|
petgraph-graphml = { version = "*" }
|
||||||
|
lalrpop-util = { version = "*", features = ["lexer", "unicode"] }
|
||||||
63
execution/src/data.rs
Normal file
63
execution/src/data.rs
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
use rsprocess::translator;
|
||||||
|
use rsprocess::system::System;
|
||||||
|
use rsprocess::label::Label;
|
||||||
|
use rsprocess::graph::SystemGraph;
|
||||||
|
use petgraph::{Graph, Directed};
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
// helper functions
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/// Very inelegant way to provide our graph with a map method where the edges
|
||||||
|
/// are mapped until the first error.
|
||||||
|
pub trait MapEdges<'a, N: 'a, E, Ty, Ix>
|
||||||
|
where
|
||||||
|
Ty: petgraph::EdgeType,
|
||||||
|
Ix: petgraph::graph::IndexType,
|
||||||
|
{
|
||||||
|
fn map_edges(
|
||||||
|
&self,
|
||||||
|
edge_map: &assert::relabel::Assert,
|
||||||
|
translator: &mut translator::Translator,
|
||||||
|
) -> Result<
|
||||||
|
Graph<System, assert::relabel::AssertReturnValue, Ty, Ix>,
|
||||||
|
String,
|
||||||
|
>;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> MapEdges<'a, System, Label, Directed, u32> for SystemGraph {
|
||||||
|
fn map_edges(
|
||||||
|
&self,
|
||||||
|
edge_map: &assert::relabel::Assert,
|
||||||
|
translator: &mut translator::Translator,
|
||||||
|
) -> Result<
|
||||||
|
Graph<System, assert::relabel::AssertReturnValue, Directed, u32>,
|
||||||
|
String,
|
||||||
|
> {
|
||||||
|
use petgraph::graph::EdgeIndex;
|
||||||
|
|
||||||
|
let mut g = Graph::with_capacity(self.node_count(), self.edge_count());
|
||||||
|
let nodes = self.raw_nodes();
|
||||||
|
let edges = self.raw_edges();
|
||||||
|
|
||||||
|
let edges = edges
|
||||||
|
.iter()
|
||||||
|
.enumerate()
|
||||||
|
.map(|(i, edge)| {
|
||||||
|
match edge_map.execute(self, &EdgeIndex::new(i), translator) {
|
||||||
|
| Err(e) => Err(e),
|
||||||
|
| Ok(val) => Ok((edge.source(), edge.target(), val)),
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.collect::<Result<Vec<_>, _>>()?;
|
||||||
|
nodes.iter().for_each(|node| {
|
||||||
|
g.add_node(node.weight.clone());
|
||||||
|
});
|
||||||
|
|
||||||
|
edges.into_iter().for_each(|(source, target, v)| {
|
||||||
|
g.add_edge(source, target, v);
|
||||||
|
});
|
||||||
|
|
||||||
|
Ok(g)
|
||||||
|
}
|
||||||
|
}
|
||||||
2
execution/src/lib.rs
Normal file
2
execution/src/lib.rs
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
pub mod data;
|
||||||
|
pub mod presets;
|
||||||
@ -1,20 +1,30 @@
|
|||||||
//! Module that holds useful presets for interacting with other modules.
|
//! Module that holds useful presets for interacting with other modules.
|
||||||
|
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::fmt::Display;
|
|
||||||
use std::io::prelude::*;
|
use std::io::prelude::*;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use std::{env, fs, io};
|
use std::{env, fs, io};
|
||||||
|
|
||||||
use lalrpop_util::ParseError;
|
|
||||||
use petgraph::Graph;
|
use petgraph::Graph;
|
||||||
|
|
||||||
use super::super::grammar;
|
use crate::data::MapEdges;
|
||||||
use super::graph::MapEdges;
|
use rsprocess::set::Set;
|
||||||
use super::set::Set;
|
use rsprocess::system::ExtensionsSystem;
|
||||||
use super::system::ExtensionsSystem;
|
use rsprocess::translator::Translator;
|
||||||
use super::translator::Translator;
|
use rsprocess::*;
|
||||||
use super::*;
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
pub trait FileParsers {
|
||||||
|
fn parse_experiment(
|
||||||
|
translator: &mut Translator,
|
||||||
|
contents: String,
|
||||||
|
) -> Result<(Vec<u32>, Vec<Set>), String>;
|
||||||
|
|
||||||
|
fn parse_instructions(
|
||||||
|
translator: &mut Translator,
|
||||||
|
contents: String,
|
||||||
|
) -> Result<Instructions, String>;
|
||||||
|
}
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
// Structures
|
// Structures
|
||||||
@ -207,112 +217,6 @@ where
|
|||||||
Ok(result)
|
Ok(result)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn reformat_error<T, S>(
|
|
||||||
e: ParseError<usize, T, &'static str>,
|
|
||||||
input_str: &str,
|
|
||||||
) -> Result<S, String>
|
|
||||||
where
|
|
||||||
T: Display,
|
|
||||||
{
|
|
||||||
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,
|
|
||||||
} => {
|
|
||||||
use colored::Colorize;
|
|
||||||
|
|
||||||
let mut err = format!(
|
|
||||||
"Unrecognized token {}{}{} \
|
|
||||||
between positions {l} and {r}.",
|
|
||||||
"\"".red(),
|
|
||||||
t.to_string().red(),
|
|
||||||
"\"".red(),
|
|
||||||
);
|
|
||||||
|
|
||||||
// Temporary debug.
|
|
||||||
err.push_str("\nExpected: ");
|
|
||||||
let mut it = expected.iter().peekable();
|
|
||||||
while let Some(s) = it.next() {
|
|
||||||
err.push('(');
|
|
||||||
err.push_str(&format!("{}", s.green()));
|
|
||||||
err.push(')');
|
|
||||||
if it.peek().is_some() {
|
|
||||||
err.push(',');
|
|
||||||
err.push(' ');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
let right_new_line = input_str[l..]
|
|
||||||
.find("\n")
|
|
||||||
.map(|pos| pos + l)
|
|
||||||
.unwrap_or(input_str.len());
|
|
||||||
let left_new_line = input_str[..r]
|
|
||||||
.rfind("\n")
|
|
||||||
.map(|pos| pos + 1)
|
|
||||||
.unwrap_or_default();
|
|
||||||
|
|
||||||
let line_number = input_str[..l].match_indices('\n').count() + 1;
|
|
||||||
let pre_no_color = format!("{line_number} |");
|
|
||||||
let pre = format!("{}", pre_no_color.blue());
|
|
||||||
|
|
||||||
let line_pos_l = l - left_new_line;
|
|
||||||
let line_pos_r = r - left_new_line;
|
|
||||||
|
|
||||||
err.push_str(&format!(
|
|
||||||
"\nLine {} position {} to {}:\n{}{}{}{}",
|
|
||||||
line_number,
|
|
||||||
line_pos_l,
|
|
||||||
line_pos_r,
|
|
||||||
&pre,
|
|
||||||
&input_str[left_new_line..l].green(),
|
|
||||||
&input_str[l..r].red(),
|
|
||||||
&input_str[r..right_new_line],
|
|
||||||
));
|
|
||||||
err.push('\n');
|
|
||||||
err.push_str(&" ".repeat(pre_no_color.len() - 1));
|
|
||||||
err.push_str(&format!("{}", "|".blue()));
|
|
||||||
err.push_str(&" ".repeat(l - left_new_line));
|
|
||||||
err.push_str(&format!("{}", &"↑".red()));
|
|
||||||
if r - l > 2 {
|
|
||||||
err.push_str(&" ".repeat(r - l - 2));
|
|
||||||
err.push_str(&format!("{}", &"↑".red()));
|
|
||||||
}
|
|
||||||
|
|
||||||
Err(err)
|
|
||||||
},
|
|
||||||
| ParseError::User { error } => Err(error.to_string()),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn parser_experiment(
|
|
||||||
translator: &mut Translator,
|
|
||||||
contents: String,
|
|
||||||
) -> Result<(Vec<u32>, Vec<Set>), String> {
|
|
||||||
match grammar::ExperimentParser::new().parse(translator, &contents) {
|
|
||||||
| Ok(sys) => Ok(sys),
|
|
||||||
| Err(e) => reformat_error(e, &contents),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn parser_instructions(
|
|
||||||
translator: &mut Translator,
|
|
||||||
contents: String,
|
|
||||||
) -> Result<Instructions, String> {
|
|
||||||
match grammar::RunParser::new().parse(translator, &contents) {
|
|
||||||
| Ok(sys) => Ok(sys),
|
|
||||||
| Err(e) => reformat_error(e, &contents),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn save_file(contents: &String, path_string: String) -> Result<(), String> {
|
fn save_file(contents: &String, path_string: String) -> Result<(), String> {
|
||||||
// relative path
|
// relative path
|
||||||
let mut path = match env::current_dir() {
|
let mut path = match env::current_dir() {
|
||||||
@ -475,10 +379,14 @@ pub fn freq(system: &EvaluatedSystem) -> Result<String, String> {
|
|||||||
/// Finds the frequency of each entity in the limit loop of a nonterminating
|
/// 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 ...
|
/// Reaction System whose context has the form Q1 ... Q1.Q2 ... Q2 ... Qn ...
|
||||||
/// equivalent to main_do(limitfreq, PairList)
|
/// equivalent to main_do(limitfreq, PairList)
|
||||||
pub fn limit_freq(
|
pub fn limit_freq<F>(
|
||||||
system: &mut EvaluatedSystem,
|
system: &mut EvaluatedSystem,
|
||||||
experiment: String,
|
experiment: String,
|
||||||
) -> Result<String, String> {
|
parser_experiment: F,
|
||||||
|
) -> Result<String, String>
|
||||||
|
where
|
||||||
|
F: Fn(&mut Translator, String) -> Result<(Vec<u32>, Vec<Set>), String>
|
||||||
|
{
|
||||||
use frequency::BasicFrequency;
|
use frequency::BasicFrequency;
|
||||||
|
|
||||||
let (sys, translator): (&system::System, &mut Translator) = match system {
|
let (sys, translator): (&system::System, &mut Translator) = match system {
|
||||||
@ -515,10 +423,14 @@ pub fn limit_freq(
|
|||||||
/// Q1 ... Q1.Q2 ... Q2 ... Qn ... Qn.nil and each Qi is repeated Wi times
|
/// Q1 ... Q1.Q2 ... Q2 ... Qn ... Qn.nil and each Qi is repeated Wi times
|
||||||
/// read from a corresponding file.
|
/// read from a corresponding file.
|
||||||
/// equivalent to main_do(fastfreq, PairList)
|
/// equivalent to main_do(fastfreq, PairList)
|
||||||
pub fn fast_freq(
|
pub fn fast_freq<F>(
|
||||||
system: &mut EvaluatedSystem,
|
system: &mut EvaluatedSystem,
|
||||||
experiment: String,
|
experiment: String,
|
||||||
) -> Result<String, String> {
|
parser_experiment: F,
|
||||||
|
) -> Result<String, String>
|
||||||
|
where
|
||||||
|
F: Fn(&mut Translator, String) -> Result<(Vec<u32>, Vec<Set>), String>
|
||||||
|
{
|
||||||
use frequency::BasicFrequency;
|
use frequency::BasicFrequency;
|
||||||
|
|
||||||
let (sys, translator): (&system::System, &mut Translator) = match system {
|
let (sys, translator): (&system::System, &mut Translator) = match system {
|
||||||
@ -618,11 +530,15 @@ pub fn grouping(
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Computes bisimularity of two provided systems
|
/// Computes bisimularity of two provided systems
|
||||||
pub fn bisimilar(
|
pub fn bisimilar<F>(
|
||||||
system_a: &mut EvaluatedSystem,
|
system_a: &mut EvaluatedSystem,
|
||||||
edge_relabeler: &assert::relabel::Assert,
|
edge_relabeler: &assert::relabel::Assert,
|
||||||
system_b: String,
|
system_b: String,
|
||||||
) -> Result<String, String> {
|
parser_instructions: F
|
||||||
|
) -> Result<String, String>
|
||||||
|
where
|
||||||
|
F: Fn(&mut Translator, String) -> Result<Instructions, String>
|
||||||
|
{
|
||||||
use assert::relabel::AssertReturnValue;
|
use assert::relabel::AssertReturnValue;
|
||||||
|
|
||||||
let system_b = read_file(
|
let system_b = read_file(
|
||||||
@ -834,7 +750,7 @@ macro_rules! save_options {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
fn execute(
|
fn execute<P: FileParsers>(
|
||||||
instruction: Instruction,
|
instruction: Instruction,
|
||||||
system: &mut EvaluatedSystem,
|
system: &mut EvaluatedSystem,
|
||||||
) -> Result<(), String> {
|
) -> Result<(), String> {
|
||||||
@ -855,10 +771,10 @@ fn execute(
|
|||||||
save_options!(freq(system)?, so);
|
save_options!(freq(system)?, so);
|
||||||
},
|
},
|
||||||
| Instruction::LimitFrequency { experiment, so } => {
|
| Instruction::LimitFrequency { experiment, so } => {
|
||||||
save_options!(limit_freq(system, experiment)?, so);
|
save_options!(limit_freq(system, experiment, P::parse_experiment)?, so);
|
||||||
},
|
},
|
||||||
| Instruction::FastFrequency { experiment, so } => {
|
| Instruction::FastFrequency { experiment, so } => {
|
||||||
save_options!(fast_freq(system, experiment)?, so);
|
save_options!(fast_freq(system, experiment, P::parse_experiment)?, so);
|
||||||
},
|
},
|
||||||
| Instruction::Digraph { group, gso } => {
|
| Instruction::Digraph { group, gso } => {
|
||||||
digraph(system)?;
|
digraph(system)?;
|
||||||
@ -898,7 +814,7 @@ fn execute(
|
|||||||
so,
|
so,
|
||||||
} => {
|
} => {
|
||||||
edge_relabeler.typecheck()?;
|
edge_relabeler.typecheck()?;
|
||||||
save_options!(bisimilar(system, &edge_relabeler, system_b)?, so);
|
save_options!(bisimilar(system, &edge_relabeler, system_b, P::parse_instructions)?, so);
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
@ -906,18 +822,22 @@ fn execute(
|
|||||||
|
|
||||||
/// Interprets file at supplied path, then executes the code specified as
|
/// Interprets file at supplied path, then executes the code specified as
|
||||||
/// instructions inside the file.
|
/// instructions inside the file.
|
||||||
pub fn run(path: String) -> Result<(), String> {
|
pub fn run<P: FileParsers>(
|
||||||
|
path: String,
|
||||||
|
) -> Result<(), String> {
|
||||||
let mut translator = Translator::new();
|
let mut translator = Translator::new();
|
||||||
|
|
||||||
let Instructions {
|
let Instructions {
|
||||||
system,
|
system,
|
||||||
instructions,
|
instructions,
|
||||||
} = read_file(&mut translator, path, parser_instructions)?;
|
} = read_file(&mut translator,
|
||||||
|
path,
|
||||||
|
P::parse_instructions)?;
|
||||||
|
|
||||||
let mut system = system.compute(translator)?;
|
let mut system = system.compute(translator)?;
|
||||||
|
|
||||||
for instr in instructions {
|
for instr in instructions {
|
||||||
execute(instr, &mut system)?;
|
execute::<P>(instr, &mut system)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
14
grammar/Cargo.toml
Normal file
14
grammar/Cargo.toml
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
[package]
|
||||||
|
name = "grammar"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2024"
|
||||||
|
|
||||||
|
[build-dependencies]
|
||||||
|
lalrpop = "*"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
rsprocess = { path = "../rsprocess/" }
|
||||||
|
assert = { path = "../assert/" }
|
||||||
|
execution = { path = "../execution/" }
|
||||||
|
regex = { version = "*", features = ["unicode-bool"] }
|
||||||
|
lalrpop-util = { version = "*", features = ["lexer", "unicode"] }
|
||||||
3
grammar/build.rs
Normal file
3
grammar/build.rs
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
fn main() {
|
||||||
|
lalrpop::process_src().unwrap();
|
||||||
|
}
|
||||||
@ -1,12 +1,13 @@
|
|||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
use lalrpop_util::ParseError;
|
use lalrpop_util::ParseError;
|
||||||
use crate::rsprocess::{set, reaction, process, environment, system, label};
|
|
||||||
use crate::rsprocess::element::IdType;
|
use assert::{relabel, grouping};
|
||||||
use crate::rsprocess::translator::Translator;
|
use rsprocess::{set, reaction, process, environment, system, label};
|
||||||
use crate::rsprocess::presets;
|
use rsprocess::element::IdType;
|
||||||
use crate::rsprocess::assert::{relabel, grouping};
|
use rsprocess::translator::Translator;
|
||||||
use crate::rsprocess::graph;
|
use execution::presets;
|
||||||
|
use rsprocess::graph;
|
||||||
|
|
||||||
grammar(translator: &mut Translator);
|
grammar(translator: &mut Translator);
|
||||||
|
|
||||||
@ -1,8 +1,4 @@
|
|||||||
//! Module root
|
|
||||||
|
|
||||||
pub mod rsprocess;
|
|
||||||
|
|
||||||
lalrpop_util::lalrpop_mod!(
|
lalrpop_util::lalrpop_mod!(
|
||||||
#[allow(clippy::uninlined_format_args)] pub grammar, // name of module
|
#[allow(clippy::uninlined_format_args)] pub grammar, // name of module
|
||||||
"/rsprocess/grammar.rs" // location of parser
|
"/grammar.rs" // location of parser
|
||||||
);
|
);
|
||||||
10
rsprocess/Cargo.toml
Normal file
10
rsprocess/Cargo.toml
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
[package]
|
||||||
|
name = "rsprocess"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2024"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
petgraph = { version = "*", features = ["serde-1"] }
|
||||||
|
petgraph-graphml = { version = "*" }
|
||||||
|
serde = { version = "*", features = ["derive", "rc"] }
|
||||||
|
serde_cbor_2 = { version = "*" }
|
||||||
@ -94,63 +94,6 @@ common_label!(
|
|||||||
.intersection(&acc)
|
.intersection(&acc)
|
||||||
);
|
);
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
|
||||||
// helper functions
|
|
||||||
// -----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
/// Very inelegant way to provide our graph with a map method where the edges
|
|
||||||
/// are mapped until the first error.
|
|
||||||
pub trait MapEdges<'a, N: 'a, E, Ty, Ix>
|
|
||||||
where
|
|
||||||
Ty: petgraph::EdgeType,
|
|
||||||
Ix: petgraph::graph::IndexType,
|
|
||||||
{
|
|
||||||
fn map_edges(
|
|
||||||
&self,
|
|
||||||
edge_map: &super::assert::relabel::Assert,
|
|
||||||
translator: &mut super::translator::Translator,
|
|
||||||
) -> Result<
|
|
||||||
Graph<System, super::assert::relabel::AssertReturnValue, Ty, Ix>,
|
|
||||||
String,
|
|
||||||
>;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a> MapEdges<'a, System, Label, Directed, u32> for SystemGraph {
|
|
||||||
fn map_edges(
|
|
||||||
&self,
|
|
||||||
edge_map: &super::assert::relabel::Assert,
|
|
||||||
translator: &mut super::translator::Translator,
|
|
||||||
) -> Result<
|
|
||||||
Graph<System, super::assert::relabel::AssertReturnValue, Directed, u32>,
|
|
||||||
String,
|
|
||||||
> {
|
|
||||||
use petgraph::graph::EdgeIndex;
|
|
||||||
|
|
||||||
let mut g = Graph::with_capacity(self.node_count(), self.edge_count());
|
|
||||||
let nodes = self.raw_nodes();
|
|
||||||
let edges = self.raw_edges();
|
|
||||||
|
|
||||||
let edges = edges
|
|
||||||
.iter()
|
|
||||||
.enumerate()
|
|
||||||
.map(|(i, edge)| {
|
|
||||||
match edge_map.execute(self, &EdgeIndex::new(i), translator) {
|
|
||||||
| Err(e) => Err(e),
|
|
||||||
| Ok(val) => Ok((edge.source(), edge.target(), val)),
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.collect::<Result<Vec<_>, _>>()?;
|
|
||||||
nodes.iter().for_each(|node| {
|
|
||||||
g.add_node(node.weight.clone());
|
|
||||||
});
|
|
||||||
|
|
||||||
edges.into_iter().for_each(|(source, target, v)| {
|
|
||||||
g.add_edge(source, target, v);
|
|
||||||
});
|
|
||||||
|
|
||||||
Ok(g)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Nodes -----------------------------------------------------------------------
|
// Nodes -----------------------------------------------------------------------
|
||||||
|
|
||||||
@ -12,12 +12,9 @@ pub mod reaction;
|
|||||||
pub mod set;
|
pub mod set;
|
||||||
pub mod system;
|
pub mod system;
|
||||||
|
|
||||||
pub mod assert;
|
|
||||||
pub mod bisimilarity;
|
|
||||||
pub mod dot;
|
pub mod dot;
|
||||||
pub mod frequency;
|
pub mod frequency;
|
||||||
pub mod graph;
|
pub mod graph;
|
||||||
pub mod presets;
|
|
||||||
pub mod serialize;
|
pub mod serialize;
|
||||||
pub mod transitions;
|
pub mod transitions;
|
||||||
|
|
||||||
@ -1,5 +1,5 @@
|
|||||||
use crate::rsprocess::set::PositiveSet;
|
use super::set::PositiveSet;
|
||||||
use crate::rsprocess::system::BasicSystem;
|
use super::system::BasicSystem;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn one_transition() {
|
fn one_transition() {
|
||||||
Reference in New Issue
Block a user