From fb3256c4a77583f2c15ed7db7e3986bd68c530d6 Mon Sep 17 00:00:00 2001 From: elvis Date: Wed, 2 Jul 2025 17:27:36 +0200 Subject: [PATCH] finishing frequency --- src/examples.rs | 98 +++++++++++++++++++++++++++++++---- src/main.rs | 12 +++-- src/rsprocess/frequency.rs | 6 ++- src/rsprocess/grammar.lalrpop | 30 +++++++---- 4 files changed, 120 insertions(+), 26 deletions(-) diff --git a/src/examples.rs b/src/examples.rs index b083e8b..eccf0f2 100644 --- a/src/examples.rs +++ b/src/examples.rs @@ -1,6 +1,6 @@ #![allow(dead_code)] -use crate::rsprocess::structure::RSsystem; +use crate::rsprocess::structure::{RSset, RSsystem}; use crate::rsprocess::translator; use crate::rsprocess::translator::Translator; use crate::rsprocess::{frequency, perpetual, statistics, transitions}; @@ -14,7 +14,11 @@ use std::io::prelude::*; // the code use super::grammar; -fn read_system(translator: &mut Translator, path: std::path::PathBuf) -> std::io::Result { +fn read_file( + translator: &mut Translator, + path: std::path::PathBuf, + parser: F +) -> std::io::Result 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); @@ -22,13 +26,25 @@ fn read_system(translator: &mut Translator, path: std::path::PathBuf) -> std::io buf_reader.read_to_string(&mut contents)?; // parse - let result = grammar::SystemParser::new() - .parse(translator, &contents) - .unwrap(); + let result = parser(translator, contents); Ok(result) } +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, Vec) { + 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(); @@ -36,7 +52,7 @@ pub fn stats() -> std::io::Result<()> { let mut path = env::current_dir()?; // file to read is inside testing/ path = path.join("testing/first.system"); - let system = read_system(&mut translator, path)?; + let system = read_file(&mut translator, path, parser_system)?; // print statistics to screan println!("{}", statistics::of_RSsystem(&translator, &system)); @@ -56,7 +72,7 @@ pub fn target() -> std::io::Result<()> { let mut path = env::current_dir()?; // file to read is inside testing/ path = path.join("testing/first.system"); - let system = read_system(&mut translator, path)?; + let system = read_file(&mut translator, path, parser_system)?; // the system needs to terminate to return let res = match transitions::target(&system) { @@ -83,7 +99,7 @@ pub fn run() -> std::io::Result<()> { let mut path = env::current_dir()?; // file to read is inside testing/ path = path.join("testing/first.system"); - let system = read_system(&mut translator, path)?; + let system = read_file(&mut translator, path, parser_system)?; // the system needs to terminate to return let res = match transitions::run_separated(&system) { @@ -110,10 +126,12 @@ pub fn hoop() -> std::io::Result<()> { let mut path = env::current_dir()?; // file to read is inside testing/ path = path.join("testing/first.system"); - let system = read_system(&mut translator, path)?; + 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")) { + let res = + match perpetual::lollipops_only_loop_named(system, + translator.encode("x")) { Some(o) => o, None => { println!("No loop found."); @@ -130,13 +148,14 @@ pub fn hoop() -> std::io::Result<()> { 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_system(&mut translator, path)?; + let system = read_file(&mut translator, path, parser_system)?; let res = match frequency::naive_frequency(&system) { Ok(f) => f, @@ -153,3 +172,60 @@ pub fn freq() -> std::io::Result<()> { 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.get_reaction_rules(), + system.get_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.get_reaction_rules(), + system.get_available_entities(), + &weights) { + Some(e) => e, + None => {return Ok(());} + }; + + println!( + "Frequency of encountered symbols:\n{}", + translator::FrequencyDisplay::from(&translator, &res) + ); + + Ok(()) +} diff --git a/src/main.rs b/src/main.rs index 7afc2e5..f934a3b 100644 --- a/src/main.rs +++ b/src/main.rs @@ -13,13 +13,17 @@ fn main() -> std::io::Result<()> { // examples::stats()?; - examples::freq()?; + // examples::freq()?; - examples::hoop()?; + // examples::hoop()?; - examples::target()?; + // examples::target()?; - examples::run()?; + // examples::run()?; + + examples::limit_freq()?; + + examples::fast_freq()?; Ok(()) } diff --git a/src/rsprocess/frequency.rs b/src/rsprocess/frequency.rs index 17aa617..bf769ad 100644 --- a/src/rsprocess/frequency.rs +++ b/src/rsprocess/frequency.rs @@ -26,7 +26,11 @@ impl Frequency { pub fn add(&mut self, e: &RSset, run: usize) { for &el in e.iter() { - self.frequency_map.entry(el).or_insert(vec![0; run + 1])[run] += 1 + let entry = self.frequency_map.entry(el).or_insert(vec![0; run + 1]); + if entry.len() < run +1 { + entry.resize(run + 1, 0); + } + entry[run] += 1 } // TODO resize clones all prev values, replace with in place method if self.totals.len() < run + 1 { diff --git a/src/rsprocess/grammar.lalrpop b/src/rsprocess/grammar.lalrpop index 2967963..15e13d5 100644 --- a/src/rsprocess/grammar.lalrpop +++ b/src/rsprocess/grammar.lalrpop @@ -27,7 +27,7 @@ Num: i64 = { }; // macro for matching sequence of patterns with C as separator -Separeted: Vec = { +Separated: Vec = { C)+> => match e { None => v, Some(e) => { @@ -47,7 +47,7 @@ pub Set: RSset = { Set_of_entities: RSset = { "{" "}" => RSset::from(vec![]), "{" "}" => RSset::from(vec![translator.encode(t)]), - "{" > "}" => + "{" > "}" => RSset::from(t.into_iter().map(|t| translator.encode(t)).collect::>()) }; @@ -59,7 +59,7 @@ Set_of_entities: RSset = { pub Reactions: Vec = { "(" ")" => vec![], "(" ")" => vec![r], - "(" > ")" => s + "(" > ")" => s } Reaction: RSreaction = { @@ -75,7 +75,7 @@ pub Context: RSprocess = { "[" "]" => RSprocess::NondeterministicChoice{ children: vec![] }, "[" "]" => RSprocess::NondeterministicChoice{children: vec![Rc::new(t)]}, - "[" > "]" => + "[" > "]" => RSprocess::NondeterministicChoice{ children: t } }; @@ -87,7 +87,7 @@ CTX_process: RSprocess = { "." => RSprocess::EntitySet{ entities: c, next_process: Rc::new(k) }, "(" ")" => k, - "(" > ")" => + "(" > ")" => RSprocess::Summation{ children: k.into_iter().map(Rc::new).collect::>() }, @@ -108,7 +108,7 @@ CTX_process: RSprocess = { pub Environment: Box = { "[" "]" => Box::new(RSenvironment::new()), "[" "]" => Box::new(RSenvironment::from(vec![t])), - "[" > "]" => Box::new(RSenvironment::from(t)) + "[" > "]" => Box::new(RSenvironment::from(t)) }; Env_term: (IdType, RSprocess) = { @@ -127,8 +127,8 @@ Formula_Assert: RSassert = { "-" => RSassert::Not(Box::new(f)), "(" "^" ")" => RSassert::Xor(Box::new(f1), Box::new(f2)), - "(" > ")" => RSassert::Or(f), - "(" > ")" => RSassert::And(f), + "(" > ")" => RSassert::Or(f), + "(" > ")" => RSassert::And(f), "inW" => RSassert::Sub(c, RSassertOp::InW), "inR" => RSassert::Sub(c, RSassertOp::InR), "inI" => RSassert::Sub(c, RSassertOp::InI), @@ -149,8 +149,8 @@ pub BHML: Box = { Formula_BHML: RSBHML = { "true" => RSBHML::True, "false" => RSBHML::False, - "(" > ")" => RSBHML::Or(g), - "(" > ")" => RSBHML::And(g), + "(" > ")" => RSBHML::Or(g), + "(" > ")" => RSBHML::And(g), "<" ">" => RSBHML::Diamond(Box::new(f), Box::new(g)), "[" "]" => @@ -175,3 +175,13 @@ pub System: RSsystem = { context_process, Rc::new(reaction_rules)) } + +// experiment +// an experiment is composed by a sequence of weights and a sequence of sets of +// entities of equal length. + +pub Experiment: (Vec, Vec) = { + "Weights:" > + "Sets:" > + => (w.into_iter().map(|x| x as u32).collect::>(), s) +}