lollipop operator, fixed but in grammar-lalrpop for environment parsing

This commit is contained in:
elvis
2025-06-19 23:48:16 +02:00
parent bbff61f71a
commit 732683fd24
7 changed files with 343 additions and 169 deletions

View File

@ -1,7 +1,8 @@
#![allow(unused_imports)]
mod rsprocess; mod rsprocess;
use lalrpop_util::lalrpop_mod; use lalrpop_util::lalrpop_mod;
use std::rc::Rc;
use rsprocess::translator::WithTranslator; use rsprocess::translator::WithTranslator;
// use std::rc::Rc;
// use std::io; // use std::io;
fn main() -> Result<(), Box<dyn std::error::Error>> { fn main() -> Result<(), Box<dyn std::error::Error>> {
@ -144,12 +145,44 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
// println!("{:?}", rsprocess::transitions::run_separated(&sys)); // 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( let env = grammar::EnvironmentParser::new().parse(&mut translator, "[x = {a,b}.x]").unwrap();
rsprocess::structure::RSset::from(vec![translator.encode("a"), translator.encode("c")]), let process = grammar::ContextParser::new().parse(&mut translator, "[]").unwrap();
rsprocess::structure::RSset::from(vec![translator.encode("c")]),
rsprocess::structure::RSset::from(vec![translator.encode("a")]) let sys = rsprocess::structure::RSsystem::from(Rc::new(*env),
); rsprocess::structure::RSset::from(vec![translator.encode("a"),
println!("{}", WithTranslator::from_RSreaction(&translator, &tmp)); 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(()) Ok(())
} }

View File

@ -10,7 +10,11 @@ use super::structure::{RSset, RSreaction};
/// Computes the result of a single reaction (if enabled returns the products) /// Computes the result of a single reaction (if enabled returns the products)
/// otherwise returns None. /// otherwise returns None.
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) { if reaction.enabled(current_state) {
Some(reaction.products()) Some(reaction.products())
} else { } 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 /// Computes the result of a series of reactions. Returns the union of all
/// products. /// products.
pub fn compute_all<'a>(current_state: &'a RSset, reactions: Vec<&'a RSreaction>) -> RSset { // see result
reactions.iter().fold(RSset::new(), |acc, r| acc.union_option(compute_step(current_state, r))) 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))
)
} }

View File

@ -74,6 +74,7 @@ CTX_process: RSprocess = {
// ----- EnvironmentParser ----- // ----- EnvironmentParser -----
pub Environment: Box<RSenvironment> = { pub Environment: Box<RSenvironment> = {
"[" "]" => Box::new(RSenvironment::new()), "[" "]" => Box::new(RSenvironment::new()),
"[" <t:Env_term> "]" => Box::new(RSenvironment::from(vec![t])),
"[" <t: Separeted<Env_term, ",">> "]" => Box::new(RSenvironment::from(t)) "[" <t: Separeted<Env_term, ",">> "]" => Box::new(RSenvironment::from(t))
}; };

View File

@ -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<Vec<RSreaction>>, e: RSset, q: &RSset) -> (Vec<RSset>, Vec<RSset>) {
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<RSset>, Vec<RSset>)> {
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::<Vec<_>>()
}

View File

@ -7,7 +7,7 @@ use super::translator::{IdType};
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// RSset // RSset
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
#[derive(Clone, Debug)] #[derive(Clone, Debug, PartialEq, Eq)]
pub struct RSset { pub struct RSset {
identifiers: HashSet<IdType> identifiers: HashSet<IdType>
} }
@ -103,6 +103,7 @@ impl RSreaction {
products } products }
} }
// see enable
pub fn enabled(&self, current_state: &RSset) -> bool { pub fn enabled(&self, current_state: &RSset) -> bool {
self.reactants.is_subset(current_state) self.reactants.is_subset(current_state)
&& self.inihibitors.is_disjoint(current_state) && self.inihibitors.is_disjoint(current_state)

View File

@ -1,9 +1,12 @@
#![allow(dead_code)] #![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 super::support_structures::TransitionsIterator;
use std::rc::Rc; use std::rc::Rc;
// see unfold
pub fn unfold( pub fn unfold(
environment: &RSenvironment, environment: &RSenvironment,
context_process: &RSprocess, context_process: &RSprocess,
@ -128,7 +131,9 @@ pub fn run(system: RSsystem) -> Result<Vec<Rc<RSsystem>>, String> {
} }
// see smartOneRunECT, smartRunECT // see smartOneRunECT, smartRunECT
pub fn run_separated(system: &RSsystem) -> Result<Vec<(RSset, RSset, RSset)>, String> { pub fn run_separated(
system: &RSsystem
) -> Result<Vec<(RSset, RSset, RSset)>, String> {
let mut res = vec![]; let mut res = vec![];
let current = one_transition(system)?; let current = one_transition(system)?;
if current.is_none() { if current.is_none() {

View File

@ -14,7 +14,7 @@ impl Translator {
pub fn new() -> Self { pub fn new() -> Self {
Translator { Translator {
strings: HashMap::new(), strings: HashMap::new(),
reverse: HashMap::new(), reverse: HashMap::new(),
last_id: 0, last_id: 0,
} }
} }
@ -22,27 +22,28 @@ impl Translator {
impl Translator { impl Translator {
pub fn encode(&mut self, s: impl Into<String>) -> IdType { pub fn encode(&mut self, s: impl Into<String>) -> IdType {
let s = s.into(); let s = s.into();
let id = *(self.strings.entry(s.clone()).or_insert({ let id = *(self.strings.entry(s.clone()).or_insert({
self.last_id += 1; self.last_id += 1;
self.last_id self.last_id
})); }));
self.reverse.insert(id, s.clone()); self.reverse.insert(id, s.clone());
id id
} }
pub fn decode(&self, el: IdType) -> String { pub fn decode(&self, el: IdType) -> String {
// TODO maybe find more efficient method?? // TODO maybe find more efficient method??
self.reverse.get(&el) self.reverse
.map(|x| x.to_string()) .get(&el)
.unwrap_or(String::from("Not Found")) .map(|x| x.to_string())
.unwrap_or(String::from("Not Found"))
} }
} }
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
use super::structure::{ use super::structure::{
RSassert, RSassertOp, RSchoices, RSenvironment, RSlabel, RSprocess, RSreaction, RSset, RSassert, RSassertOp, RSchoices, RSenvironment, RSlabel, RSprocess,
RSsystem, RSBHML, RSreaction, RSset, RSsystem, RSBHML,
}; };
use std::fmt; use std::fmt;
@ -94,9 +95,12 @@ pub enum WithTranslator<'a> {
macro_rules! from_RS { macro_rules! from_RS {
($name:ident, $type:ty, $dataname:ident, $type2: ident) => { ($name:ident, $type:ty, $dataname:ident, $type2: ident) => {
pub fn $name(translator: &'a Translator, $dataname: &'a $type) -> Self { pub fn $name(translator: &'a Translator, $dataname: &'a $type) -> Self {
WithTranslator::$type2 { translator, $dataname } WithTranslator::$type2 {
} translator,
$dataname,
}
}
}; };
} }
@ -124,148 +128,193 @@ impl<'a> WithTranslator<'a> {
from_RS!(from_RSBHML, RSBHML, bhml, RSBHML); from_RS!(from_RSBHML, RSBHML, bhml, RSBHML);
} }
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// Printing functions // 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, "{{")?; write!(f, "{{")?;
let mut it = set.hashset().iter().peekable(); let mut it = set.hashset().iter().peekable();
while let Some(el) = it.next() { while let Some(el) = it.next() {
if it.peek().is_none() { if it.peek().is_none() {
write!(f, "{}", translator.decode(*el))?; write!(f, "{}", translator.decode(*el))?;
} else { } else {
write!(f, "{}, ", translator.decode(*el))?; write!(f, "{}, ", translator.decode(*el))?;
} }
} }
write!(f, "}}") write!(f, "}}")
} }
fn print_reaction(f: &mut fmt::Formatter, translator: &Translator, reaction: &RSreaction) -> fmt::Result { fn print_reaction(
write!(f, "(r: {}, i: {}, p: {})", f: &mut fmt::Formatter,
WithTranslator::from_RSset(translator, reaction.reactants()), translator: &Translator,
WithTranslator::from_RSset(translator, reaction.inihibitors()), reaction: &RSreaction,
WithTranslator::from_RSset(translator, reaction.products())) ) -> 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::*; use super::structure::RSprocess::*;
match process { match process {
Nill => { Nill => {
write!(f, "[Nill]") write!(f, "[Nill]")
}, }
RecursiveIdentifier{ identifier } => { RecursiveIdentifier { identifier } => {
write!(f, "[{}]", translator.decode(*identifier)) write!(f, "[{}]", translator.decode(*identifier))
}, }
EntitySet{ entities, EntitySet {
next_process } => { entities,
write!(f, "[entities: {}, next_process: {}]", next_process,
WithTranslator::from_RSset(translator, entities), } => {
WithTranslator::from_RSprocess(translator, next_process) write!(
) f,
}, "[entities: {}, next_process: {}]",
WaitEntity{ repeat, WithTranslator::from_RSset(translator, entities),
repeated_process, WithTranslator::from_RSprocess(translator, next_process)
next_process } => { )
write!(f, "[repeat: {repeat}, repeated_process: {}, next_process: {}]", }
WithTranslator::from_RSprocess(translator, repeated_process), WaitEntity {
WithTranslator::from_RSprocess(translator, next_process) repeat,
) repeated_process,
}, next_process,
Summation{ children } => { } => {
write!(f, "[")?; write!(
let mut it = children.iter().peekable(); f,
while let Some(child) = it.next() { "[repeat: {repeat}, repeated_process: {}, next_process: {}]",
if it.peek().is_none() { WithTranslator::from_RSprocess(translator, repeated_process),
write!(f, "{}", WithTranslator::from_RSprocess(translator, next_process)
WithTranslator::from_RSprocess(translator, child) )
)?; }
} else { Summation { children } => {
write!(f, "{} + ", write!(f, "[")?;
WithTranslator::from_RSprocess(translator, child) let mut it = children.iter().peekable();
)?; while let Some(child) = it.next() {
} if it.peek().is_none() {
} write!(f, "{}",
write!(f, "]") WithTranslator::from_RSprocess(translator, child))?;
}, } else {
NondeterministicChoice{ children } => { write!(
write!(f, "[")?; f,
let mut it = children.iter().peekable(); "{} + ",
while let Some(child) = it.next() { WithTranslator::from_RSprocess(translator, child)
if it.peek().is_none() { )?;
write!(f, "{}", }
WithTranslator::from_RSprocess(translator, child) }
)?; write!(f, "]")
} else { }
write!(f, "{}, ", NondeterministicChoice { children } => {
WithTranslator::from_RSprocess(translator, child) write!(f, "[")?;
)?; let mut it = children.iter().peekable();
} while let Some(child) = it.next() {
} if it.peek().is_none() {
write!(f, "]") 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, "[")?; write!(f, "[")?;
let mut it = choices.iter().peekable(); let mut it = choices.iter().peekable();
while let Some(el) = it.next() { while let Some(el) = it.next() {
if it.peek().is_none() { if it.peek().is_none() {
write!(f, "[set: {}, process: {}]", write!(
WithTranslator::from_RSset(translator, &el.0), f,
WithTranslator::from_RSprocess(translator, &el.1))?; "[set: {}, process: {}]",
} else { WithTranslator::from_RSset(translator, &el.0),
write!(f, "[set: {}, process: {}], ", WithTranslator::from_RSprocess(translator, &el.1)
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, "]") 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:")?; write!(f, "{{env:")?;
let mut it = environment.iter().peekable(); let mut it = environment.iter().peekable();
while let Some(el) = it.next() { while let Some(el) = it.next() {
if it.peek().is_none() { if it.peek().is_none() {
write!(f, "({} -> {})", write!(
translator.decode(*el.0), f,
WithTranslator::from_RSprocess(translator, el.1) "({} -> {})",
)?; translator.decode(*el.0),
} else { WithTranslator::from_RSprocess(translator, el.1)
write!(f, "({} -> {}), ", )?;
translator.decode(*el.0), } else {
WithTranslator::from_RSprocess(translator, el.1) write!(
)?; f,
} "({} -> {}), ",
translator.decode(*el.0),
WithTranslator::from_RSprocess(translator, el.1)
)?;
}
} }
write!(f, "}}") write!(f, "}}")
} }
fn print_system(f: &mut fmt::Formatter, translator: &Translator, system: &RSsystem) -> fmt::Result { fn print_system(
write!(f, "[delta: {}, available_entities: {}, context_process: {}, reaction_rules: [", f: &mut fmt::Formatter,
WithTranslator::from_RSenvironment(translator, system.get_delta()), translator: &Translator,
WithTranslator::from_RSset(translator, system.get_available_entities()), system: &RSsystem
WithTranslator::from_RSprocess(translator, system.get_context_process()) ) -> 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(); let mut it = system.get_reaction_rules().iter().peekable();
while let Some(el) = it.next() { while let Some(el) = it.next() {
if it.peek().is_none() { if it.peek().is_none() {
write!(f, "{}", write!(f, "{}", WithTranslator::from_RSreaction(translator, el))?;
WithTranslator::from_RSreaction(translator, el) } else {
)?; write!(f, "{}, ", WithTranslator::from_RSreaction(translator, el))?;
} else { }
write!(f, "{}, ",
WithTranslator::from_RSreaction(translator, el)
)?;
}
} }
write!(f, "] ]") 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: {}}}", write!(f, "{{available_entities: {}, context: {}, t: {}, reactants: {}, reactantsi: {}, inihibitors: {}, ireactants: {}, products: {}}}",
WithTranslator::from_RSset(translator, &label.available_entities), WithTranslator::from_RSset(translator, &label.available_entities),
WithTranslator::from_RSset(translator, &label.context), 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::*; use super::structure::RSassertOp::*;
match assert_op { match assert_op {
InW => {write!(f, "InW")}, InW => {
InR => {write!(f, "InR")}, write!(f, "InW")
InI => {write!(f, "InI")}, }
InP => {write!(f, "InP")}, InR => {
write!(f, "InR")
}
InI => {
write!(f, "InI")
}
InP => {
write!(f, "InP")
}
} }
} }
#[allow(unused_variables)] #[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!() todo!()
} }
#[allow(unused_variables)] #[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!() todo!()
} }
impl<'a> fmt::Display for WithTranslator<'a> { impl<'a> fmt::Display for WithTranslator<'a> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self { match self {
WithTranslator::RSset{translator, set} => { WithTranslator::RSset { translator, set, } =>
print_set(f, translator, set) print_set(f, translator, set),
}, WithTranslator::RSreaction { translator, reaction, } =>
WithTranslator::RSreaction { translator, reaction } => { print_reaction(f, translator, reaction),
print_reaction(f, translator, reaction) WithTranslator::RSprocess { translator, process, } =>
}, print_process(f, translator, process),
WithTranslator::RSprocess { translator, process } => { WithTranslator::RSchoices { translator, choices, } =>
print_process(f, translator, process) print_choices(f, translator, choices),
}, WithTranslator::RSenvironment { translator, environment, } =>
WithTranslator::RSchoices { translator, choices } => { print_environment(f, translator, environment),
print_choices(f, translator, choices) WithTranslator::RSsystem { translator, system, } =>
}, print_system(f, translator, system),
WithTranslator::RSenvironment { translator, environment } => { WithTranslator::RSlabel { translator, label, } =>
print_environment(f, translator, environment) print_label(f, translator, label),
}, WithTranslator::RSassertOp { translator, assert_op, } =>
WithTranslator::RSsystem { translator, system } => { print_assert_op(f, translator, assert_op),
print_system(f, translator, system) WithTranslator::RSassert { translator, assert, } =>
}, print_assert(f, translator, assert),
WithTranslator::RSlabel { translator, label } => { WithTranslator::RSBHML { translator, bhml, } =>
print_label(f, translator, label) print_bhml(f, translator, bhml),
}, }
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)
}
}
} }
} }