From 732683fd24a6396fd748a413d0b8d26d2a1024ef Mon Sep 17 00:00:00 2001 From: elvis Date: Thu, 19 Jun 2025 23:48:16 +0200 Subject: [PATCH] lollipop operator, fixed but in grammar-lalrpop for environment parsing --- src/main.rs | 47 ++++- src/rsprocess/classical.rs | 27 ++- src/rsprocess/grammar.lalrpop | 1 + src/rsprocess/perpetual.rs | 55 +++++ src/rsprocess/structure.rs | 3 +- src/rsprocess/transitions.rs | 9 +- src/rsprocess/translator.rs | 370 ++++++++++++++++++++-------------- 7 files changed, 343 insertions(+), 169 deletions(-) diff --git a/src/main.rs b/src/main.rs index a3cfdc3..4e8c65e 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,7 +1,8 @@ +#![allow(unused_imports)] mod rsprocess; use lalrpop_util::lalrpop_mod; +use std::rc::Rc; use rsprocess::translator::WithTranslator; -// use std::rc::Rc; // use std::io; fn main() -> Result<(), Box> { @@ -144,12 +145,44 @@ fn main() -> Result<(), Box> { // println!("{:?}", rsprocess::transitions::run_separated(&sys)); // ------------------------------------------------------------------------- + // list_to_assoc([x-pre([a, b], rec(x)), y-pre([d, e], rec(y))], Ass), + // lollipop(sys(Ass, [a, b, c, d], [], [react([a], [c], [a]), react([d], [f], [d])]), Prefix, Loop). - let tmp = rsprocess::structure::RSreaction::from( - rsprocess::structure::RSset::from(vec![translator.encode("a"), translator.encode("c")]), - rsprocess::structure::RSset::from(vec![translator.encode("c")]), - rsprocess::structure::RSset::from(vec![translator.encode("a")]) - ); - println!("{}", WithTranslator::from_RSreaction(&translator, &tmp)); + let env = grammar::EnvironmentParser::new().parse(&mut translator, "[x = {a,b}.x]").unwrap(); + let process = grammar::ContextParser::new().parse(&mut translator, "[]").unwrap(); + + let sys = rsprocess::structure::RSsystem::from(Rc::new(*env), + rsprocess::structure::RSset::from(vec![translator.encode("a"), + translator.encode("b"), + translator.encode("c"), + translator.encode("d")]), + *process, + Rc::new(vec![ + rsprocess::structure::RSreaction::from( + rsprocess::structure::RSset::from(vec![translator.encode("a")]), + rsprocess::structure::RSset::from(vec![translator.encode("c")]), + rsprocess::structure::RSset::from(vec![translator.encode("a")]) + ), + rsprocess::structure::RSreaction::from( + rsprocess::structure::RSset::from(vec![translator.encode("d")]), + rsprocess::structure::RSset::from(vec![translator.encode("f")]), + rsprocess::structure::RSset::from(vec![translator.encode("d")]) + ) + ])); + + let res = rsprocess::perpetual::lollipops(sys); + + println!("res:"); + for (prefix, hoop) in res { + print!("prefix: "); + for p in prefix { + print!("{}, ", WithTranslator::from_RSset(&translator, &p)); + } + print!("\nhoop: "); + for l in hoop { + print!("{}, ", WithTranslator::from_RSset(&translator, &l)); + } + println!(); + } Ok(()) } diff --git a/src/rsprocess/classical.rs b/src/rsprocess/classical.rs index 09a1c72..e7c3148 100644 --- a/src/rsprocess/classical.rs +++ b/src/rsprocess/classical.rs @@ -10,7 +10,11 @@ use super::structure::{RSset, RSreaction}; /// Computes the result of a single reaction (if enabled returns the products) /// otherwise returns None. -pub fn compute_step<'a>(current_state: &'a RSset, reaction: &'a RSreaction) -> Option<&'a RSset> { +// see result +pub fn compute_step<'a>( + current_state: &'a RSset, + reaction: &'a RSreaction +) -> Option<&'a RSset> { if reaction.enabled(current_state) { Some(reaction.products()) } else { @@ -20,6 +24,23 @@ pub fn compute_step<'a>(current_state: &'a RSset, reaction: &'a RSreaction) -> O /// Computes the result of a series of reactions. Returns the union of all /// products. -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))) +// see result +pub fn compute_all<'a>( + current_state: &'a RSset, + reactions: Vec<&'a RSreaction> +) -> RSset { + reactions.iter().fold( + RSset::new(), + |acc, r| acc.union_option(compute_step(current_state, r)) + ) +} + +pub fn compute_all_owned<'a>( + current_state: &'a RSset, + reactions: &'a [RSreaction] +) -> RSset { + reactions.iter().fold( + RSset::new(), + |acc, r| acc.union_option(compute_step(current_state, r)) + ) } diff --git a/src/rsprocess/grammar.lalrpop b/src/rsprocess/grammar.lalrpop index 0f94e0d..1c12e24 100644 --- a/src/rsprocess/grammar.lalrpop +++ b/src/rsprocess/grammar.lalrpop @@ -74,6 +74,7 @@ CTX_process: RSprocess = { // ----- EnvironmentParser ----- pub Environment: Box = { "[" "]" => Box::new(RSenvironment::new()), + "[" "]" => Box::new(RSenvironment::from(vec![t])), "[" > "]" => Box::new(RSenvironment::from(t)) }; diff --git a/src/rsprocess/perpetual.rs b/src/rsprocess/perpetual.rs index e69de29..8cb9055 100644 --- a/src/rsprocess/perpetual.rs +++ b/src/rsprocess/perpetual.rs @@ -0,0 +1,55 @@ +#![allow(dead_code)] + +use std::rc::Rc; + +use super::classical::compute_all_owned; +use super::translator::IdType; +use super::structure::{RSsystem, RSprocess, RSset, RSreaction}; + +fn split<'a>(set: &'a RSset, trace: &'a [RSset]) -> Option<(&'a[RSset], &'a[RSset])> { + let position = trace.iter().rposition(|x| x == set); + position.map(|pos| trace.split_at(pos)) +} + +fn find_loop(rs: &Rc>, e: RSset, q: &RSset) -> (Vec, Vec) { + let mut e = e; + let mut trace = vec![]; + loop { + if let Some((prefix, hoop)) = split(&e, &trace) { + return (prefix.to_vec(), hoop.to_vec()); + } else { + let t = e.union(q); + let p = compute_all_owned(&t, rs); + trace.push(e.clone()); + e = p; + } + } +} + +// see lollipop +pub fn lollipops(system: RSsystem) -> Vec<(Vec, Vec)> { + fn filter_delta<'a>(x: (&IdType, &'a RSprocess)) -> Option<&'a RSset> { + use super::structure::RSprocess::*; + let (id, rest) = x; + match rest { + EntitySet{ entities, next_process} => { + match &**next_process { + RecursiveIdentifier{ identifier } if identifier == id => { + Some(entities) + }, + _ => None + } + }, + _ => None + } + } + + // FIXME: what? i think we are only interested in "x", not all symbols that + // satisfy X = pre(Q, rec(X)) + let filtered = system.get_delta().iter().filter_map(filter_delta); + + filtered.map(|q| find_loop(system.get_reaction_rules(), + system.get_available_entities().clone(), + q) + ).collect::>() +} diff --git a/src/rsprocess/structure.rs b/src/rsprocess/structure.rs index 7380495..018ef79 100644 --- a/src/rsprocess/structure.rs +++ b/src/rsprocess/structure.rs @@ -7,7 +7,7 @@ use super::translator::{IdType}; // ----------------------------------------------------------------------------- // RSset // ----------------------------------------------------------------------------- -#[derive(Clone, Debug)] +#[derive(Clone, Debug, PartialEq, Eq)] pub struct RSset { identifiers: HashSet } @@ -103,6 +103,7 @@ impl RSreaction { products } } + // see enable pub fn enabled(&self, current_state: &RSset) -> bool { self.reactants.is_subset(current_state) && self.inihibitors.is_disjoint(current_state) diff --git a/src/rsprocess/transitions.rs b/src/rsprocess/transitions.rs index 0aa6040..553854a 100644 --- a/src/rsprocess/transitions.rs +++ b/src/rsprocess/transitions.rs @@ -1,9 +1,12 @@ #![allow(dead_code)] -use super::structure::{RSchoices, RSenvironment, RSlabel, RSprocess, RSset, RSsystem}; +use super::structure::{ + RSchoices, RSenvironment, RSlabel, RSprocess, RSset, RSsystem +}; use super::support_structures::TransitionsIterator; use std::rc::Rc; +// see unfold pub fn unfold( environment: &RSenvironment, context_process: &RSprocess, @@ -128,7 +131,9 @@ pub fn run(system: RSsystem) -> Result>, String> { } // see smartOneRunECT, smartRunECT -pub fn run_separated(system: &RSsystem) -> Result, String> { +pub fn run_separated( + system: &RSsystem +) -> Result, String> { let mut res = vec![]; let current = one_transition(system)?; if current.is_none() { diff --git a/src/rsprocess/translator.rs b/src/rsprocess/translator.rs index 44d5cf5..3bc895c 100644 --- a/src/rsprocess/translator.rs +++ b/src/rsprocess/translator.rs @@ -14,7 +14,7 @@ impl Translator { pub fn new() -> Self { Translator { strings: HashMap::new(), - reverse: HashMap::new(), + reverse: HashMap::new(), last_id: 0, } } @@ -22,27 +22,28 @@ impl Translator { impl Translator { pub fn encode(&mut self, s: impl Into) -> IdType { - let s = s.into(); - let id = *(self.strings.entry(s.clone()).or_insert({ + let s = s.into(); + let id = *(self.strings.entry(s.clone()).or_insert({ self.last_id += 1; self.last_id })); - self.reverse.insert(id, s.clone()); - id + self.reverse.insert(id, s.clone()); + id } pub fn decode(&self, el: IdType) -> String { - // TODO maybe find more efficient method?? - self.reverse.get(&el) - .map(|x| x.to_string()) - .unwrap_or(String::from("Not Found")) + // TODO maybe find more efficient method?? + self.reverse + .get(&el) + .map(|x| x.to_string()) + .unwrap_or(String::from("Not Found")) } } // ----------------------------------------------------------------------------- use super::structure::{ - RSassert, RSassertOp, RSchoices, RSenvironment, RSlabel, RSprocess, RSreaction, RSset, - RSsystem, RSBHML, + RSassert, RSassertOp, RSchoices, RSenvironment, RSlabel, RSprocess, + RSreaction, RSset, RSsystem, RSBHML, }; use std::fmt; @@ -94,9 +95,12 @@ pub enum WithTranslator<'a> { macro_rules! from_RS { ($name:ident, $type:ty, $dataname:ident, $type2: ident) => { - pub fn $name(translator: &'a Translator, $dataname: &'a $type) -> Self { - WithTranslator::$type2 { translator, $dataname } - } + pub fn $name(translator: &'a Translator, $dataname: &'a $type) -> Self { + WithTranslator::$type2 { + translator, + $dataname, + } + } }; } @@ -124,148 +128,193 @@ impl<'a> WithTranslator<'a> { from_RS!(from_RSBHML, RSBHML, bhml, RSBHML); } - // ----------------------------------------------------------------------------- // Printing functions // ----------------------------------------------------------------------------- -fn print_set(f: &mut fmt::Formatter, translator: &Translator, set: &RSset) -> fmt::Result { +fn print_set( + f: &mut fmt::Formatter, + translator: &Translator, + set: &RSset +) -> fmt::Result { write!(f, "{{")?; let mut it = set.hashset().iter().peekable(); while let Some(el) = it.next() { - if it.peek().is_none() { - write!(f, "{}", translator.decode(*el))?; - } else { - write!(f, "{}, ", translator.decode(*el))?; - } + if it.peek().is_none() { + write!(f, "{}", translator.decode(*el))?; + } else { + write!(f, "{}, ", translator.decode(*el))?; + } } write!(f, "}}") } -fn print_reaction(f: &mut fmt::Formatter, translator: &Translator, reaction: &RSreaction) -> fmt::Result { - write!(f, "(r: {}, i: {}, p: {})", - WithTranslator::from_RSset(translator, reaction.reactants()), - WithTranslator::from_RSset(translator, reaction.inihibitors()), - WithTranslator::from_RSset(translator, reaction.products())) +fn print_reaction( + f: &mut fmt::Formatter, + translator: &Translator, + reaction: &RSreaction, +) -> fmt::Result { + write!( + f, + "(r: {}, i: {}, p: {})", + WithTranslator::from_RSset(translator, reaction.reactants()), + WithTranslator::from_RSset(translator, reaction.inihibitors()), + WithTranslator::from_RSset(translator, reaction.products()) + ) } -fn print_process(f: &mut fmt::Formatter, translator: &Translator, process: &RSprocess) -> fmt::Result { +fn print_process( + f: &mut fmt::Formatter, + translator: &Translator, + process: &RSprocess, +) -> fmt::Result { use super::structure::RSprocess::*; match process { - Nill => { - write!(f, "[Nill]") - }, - RecursiveIdentifier{ identifier } => { - write!(f, "[{}]", translator.decode(*identifier)) - }, - EntitySet{ entities, - next_process } => { - write!(f, "[entities: {}, next_process: {}]", - WithTranslator::from_RSset(translator, entities), - WithTranslator::from_RSprocess(translator, next_process) - ) - }, - WaitEntity{ repeat, - repeated_process, - next_process } => { - write!(f, "[repeat: {repeat}, repeated_process: {}, next_process: {}]", - WithTranslator::from_RSprocess(translator, repeated_process), - WithTranslator::from_RSprocess(translator, next_process) - ) - }, - Summation{ children } => { - write!(f, "[")?; - let mut it = children.iter().peekable(); - while let Some(child) = it.next() { - if it.peek().is_none() { - write!(f, "{}", - WithTranslator::from_RSprocess(translator, child) - )?; - } else { - write!(f, "{} + ", - WithTranslator::from_RSprocess(translator, child) - )?; - } - } - write!(f, "]") - }, - NondeterministicChoice{ children } => { - write!(f, "[")?; - let mut it = children.iter().peekable(); - while let Some(child) = it.next() { - if it.peek().is_none() { - write!(f, "{}", - WithTranslator::from_RSprocess(translator, child) - )?; - } else { - write!(f, "{}, ", - WithTranslator::from_RSprocess(translator, child) - )?; - } - } - write!(f, "]") - } + Nill => { + write!(f, "[Nill]") + } + RecursiveIdentifier { identifier } => { + write!(f, "[{}]", translator.decode(*identifier)) + } + EntitySet { + entities, + next_process, + } => { + write!( + f, + "[entities: {}, next_process: {}]", + WithTranslator::from_RSset(translator, entities), + WithTranslator::from_RSprocess(translator, next_process) + ) + } + WaitEntity { + repeat, + repeated_process, + next_process, + } => { + write!( + f, + "[repeat: {repeat}, repeated_process: {}, next_process: {}]", + WithTranslator::from_RSprocess(translator, repeated_process), + WithTranslator::from_RSprocess(translator, next_process) + ) + } + Summation { children } => { + write!(f, "[")?; + let mut it = children.iter().peekable(); + while let Some(child) = it.next() { + if it.peek().is_none() { + write!(f, "{}", + WithTranslator::from_RSprocess(translator, child))?; + } else { + write!( + f, + "{} + ", + WithTranslator::from_RSprocess(translator, child) + )?; + } + } + write!(f, "]") + } + NondeterministicChoice { children } => { + write!(f, "[")?; + let mut it = children.iter().peekable(); + while let Some(child) = it.next() { + if it.peek().is_none() { + write!(f, "{}", + WithTranslator::from_RSprocess(translator, child))?; + } else { + write!(f, "{}, ", + WithTranslator::from_RSprocess(translator, child))?; + } + } + write!(f, "]") + } } } -fn print_choices(f: &mut fmt::Formatter, translator: &Translator, choices: &RSchoices) -> fmt::Result { +fn print_choices( + f: &mut fmt::Formatter, + translator: &Translator, + choices: &RSchoices, +) -> fmt::Result { write!(f, "[")?; let mut it = choices.iter().peekable(); while let Some(el) = it.next() { - if it.peek().is_none() { - write!(f, "[set: {}, process: {}]", - WithTranslator::from_RSset(translator, &el.0), - WithTranslator::from_RSprocess(translator, &el.1))?; - } else { - write!(f, "[set: {}, process: {}], ", - WithTranslator::from_RSset(translator, &el.0), - WithTranslator::from_RSprocess(translator, &el.1))?; - } + if it.peek().is_none() { + write!( + f, + "[set: {}, process: {}]", + WithTranslator::from_RSset(translator, &el.0), + WithTranslator::from_RSprocess(translator, &el.1) + )?; + } else { + write!( + f, + "[set: {}, process: {}], ", + WithTranslator::from_RSset(translator, &el.0), + WithTranslator::from_RSprocess(translator, &el.1) + )?; + } } write!(f, "]") } -fn print_environment(f: &mut fmt::Formatter, translator: &Translator, environment: &RSenvironment) -> fmt::Result { +fn print_environment( + f: &mut fmt::Formatter, + translator: &Translator, + environment: &RSenvironment, +) -> fmt::Result { write!(f, "{{env:")?; let mut it = environment.iter().peekable(); while let Some(el) = it.next() { - if it.peek().is_none() { - write!(f, "({} -> {})", - translator.decode(*el.0), - WithTranslator::from_RSprocess(translator, el.1) - )?; - } else { - write!(f, "({} -> {}), ", - translator.decode(*el.0), - WithTranslator::from_RSprocess(translator, el.1) - )?; - } + if it.peek().is_none() { + write!( + f, + "({} -> {})", + translator.decode(*el.0), + WithTranslator::from_RSprocess(translator, el.1) + )?; + } else { + write!( + f, + "({} -> {}), ", + translator.decode(*el.0), + WithTranslator::from_RSprocess(translator, el.1) + )?; + } } write!(f, "}}") } -fn print_system(f: &mut fmt::Formatter, translator: &Translator, system: &RSsystem) -> fmt::Result { - write!(f, "[delta: {}, available_entities: {}, context_process: {}, reaction_rules: [", - WithTranslator::from_RSenvironment(translator, system.get_delta()), - WithTranslator::from_RSset(translator, system.get_available_entities()), - WithTranslator::from_RSprocess(translator, system.get_context_process()) +fn print_system( + f: &mut fmt::Formatter, + translator: &Translator, + system: &RSsystem +) -> fmt::Result { + write!( + f, + "[delta: {}, available_entities: {}, context_process: {}, reaction_rules: [", + WithTranslator::from_RSenvironment(translator, system.get_delta()), + WithTranslator::from_RSset(translator, system.get_available_entities()), + WithTranslator::from_RSprocess(translator, system.get_context_process()) )?; let mut it = system.get_reaction_rules().iter().peekable(); while let Some(el) = it.next() { - if it.peek().is_none() { - write!(f, "{}", - WithTranslator::from_RSreaction(translator, el) - )?; - } else { - write!(f, "{}, ", - WithTranslator::from_RSreaction(translator, el) - )?; - } + if it.peek().is_none() { + write!(f, "{}", WithTranslator::from_RSreaction(translator, el))?; + } else { + write!(f, "{}, ", WithTranslator::from_RSreaction(translator, el))?; + } } write!(f, "] ]") } -fn print_label(f: &mut fmt::Formatter, translator: &Translator, label: &RSlabel) -> fmt::Result { +fn print_label( + f: &mut fmt::Formatter, + translator: &Translator, + label: &RSlabel +) -> fmt::Result { write!(f, "{{available_entities: {}, context: {}, t: {}, reactants: {}, reactantsi: {}, inihibitors: {}, ireactants: {}, products: {}}}", WithTranslator::from_RSset(translator, &label.available_entities), WithTranslator::from_RSset(translator, &label.context), @@ -278,60 +327,69 @@ fn print_label(f: &mut fmt::Formatter, translator: &Translator, label: &RSlabel) ) } -fn print_assert_op(f: &mut fmt::Formatter, _translator: &Translator, assert_op: &RSassertOp) -> fmt::Result { +fn print_assert_op( + f: &mut fmt::Formatter, + _translator: &Translator, + assert_op: &RSassertOp, +) -> fmt::Result { use super::structure::RSassertOp::*; match assert_op { - InW => {write!(f, "InW")}, - InR => {write!(f, "InR")}, - InI => {write!(f, "InI")}, - InP => {write!(f, "InP")}, + InW => { + write!(f, "InW") + } + InR => { + write!(f, "InR") + } + InI => { + write!(f, "InI") + } + InP => { + write!(f, "InP") + } } } #[allow(unused_variables)] -fn print_assert(f: &mut fmt::Formatter, translator: &Translator, assert: &RSassert) -> fmt::Result { +fn print_assert( + f: &mut fmt::Formatter, + translator: &Translator, + assert: &RSassert +) -> fmt::Result { todo!() } #[allow(unused_variables)] -fn print_bhml(f: &mut fmt::Formatter, translator: &Translator, bhml: &RSBHML) -> fmt::Result { +fn print_bhml( + f: &mut fmt::Formatter, + translator: &Translator, + bhml: &RSBHML +) -> fmt::Result { todo!() } impl<'a> fmt::Display for WithTranslator<'a> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self { - WithTranslator::RSset{translator, set} => { - print_set(f, translator, set) - }, - WithTranslator::RSreaction { translator, reaction } => { - print_reaction(f, translator, reaction) - }, - WithTranslator::RSprocess { translator, process } => { - print_process(f, translator, process) - }, - WithTranslator::RSchoices { translator, choices } => { - print_choices(f, translator, choices) - }, - WithTranslator::RSenvironment { translator, environment } => { - print_environment(f, translator, environment) - }, - WithTranslator::RSsystem { translator, system } => { - print_system(f, translator, system) - }, - WithTranslator::RSlabel { translator, label } => { - print_label(f, translator, label) - }, - WithTranslator::RSassertOp { translator, assert_op } => { - print_assert_op(f, translator, assert_op) - }, - WithTranslator::RSassert { translator, assert } => { - print_assert(f, translator, assert) - }, - WithTranslator::RSBHML { translator, bhml } => { - print_bhml(f, translator, bhml) - } - } + WithTranslator::RSset { translator, set, } => + print_set(f, translator, set), + WithTranslator::RSreaction { translator, reaction, } => + print_reaction(f, translator, reaction), + WithTranslator::RSprocess { translator, process, } => + print_process(f, translator, process), + WithTranslator::RSchoices { translator, choices, } => + print_choices(f, translator, choices), + WithTranslator::RSenvironment { translator, environment, } => + print_environment(f, translator, environment), + WithTranslator::RSsystem { translator, system, } => + print_system(f, translator, system), + WithTranslator::RSlabel { translator, label, } => + print_label(f, translator, label), + WithTranslator::RSassertOp { translator, assert_op, } => + print_assert_op(f, translator, assert_op), + WithTranslator::RSassert { translator, assert, } => + print_assert(f, translator, assert), + WithTranslator::RSBHML { translator, bhml, } => + print_bhml(f, translator, bhml), + } } } -