Files
ReactionSystems/rsprocess/src/process.rs

528 lines
16 KiB
Rust
Raw Normal View History

use std::collections::VecDeque;
2025-08-29 17:59:49 +02:00
use std::fmt::Debug;
use std::hash::Hash;
2025-10-31 16:36:28 +01:00
use std::sync::Arc;
2025-09-11 02:49:14 +02:00
use serde::{Deserialize, Serialize};
use super::element::{IdState, IdType};
2025-08-29 17:59:49 +02:00
use super::reaction::{PositiveReaction, Reaction};
use super::set::{BasicSet, PositiveSet, Set};
use super::translator::{Formatter, PrintableWithTranslator, Translator};
2025-08-29 17:59:49 +02:00
pub trait BasicProcess
where
2025-09-10 22:41:40 +02:00
Self: Clone
+ Debug
+ Default
+ PartialEq
+ Eq
+ Hash
+ Serialize
+ PrintableWithTranslator,
for<'a> Self: Deserialize<'a>,
{
2025-08-29 17:59:49 +02:00
type Id;
type Set: BasicSet;
fn concat(&self, new: &Self) -> Self;
fn all_elements(&self) -> Self::Set;
fn filter_delta(&self, id: &Self::Id) -> Option<&Self::Set>;
}
// -----------------------------------------------------------------------------
#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub enum Process {
Nill,
RecursiveIdentifier {
identifier: IdType,
},
EntitySet {
2025-09-11 02:49:14 +02:00
entities: Set,
2025-10-31 16:36:28 +01:00
next_process: Arc<Process>,
},
Guarded {
2025-09-11 02:49:14 +02:00
reaction: Reaction,
2025-10-31 16:36:28 +01:00
next_process: Arc<Process>,
},
WaitEntity {
repeat: i64,
2025-10-31 16:36:28 +01:00
repeated_process: Arc<Process>,
next_process: Arc<Process>,
},
Summation {
2025-10-31 16:36:28 +01:00
children: Vec<Arc<Process>>,
},
NondeterministicChoice {
2025-10-31 16:36:28 +01:00
children: Vec<Arc<Process>>,
},
}
2025-08-29 17:59:49 +02:00
impl BasicProcess for Process {
type Id = IdType;
type Set = Set;
fn concat(&self, new: &Self) -> Self {
match (self, new) {
2025-09-11 02:49:14 +02:00
| (
Self::NondeterministicChoice { children: c1 },
Self::NondeterministicChoice { children: c2 },
) => Self::NondeterministicChoice {
children: [c1.clone(), c2.clone()].concat(),
},
2025-09-11 02:49:14 +02:00
| (Self::NondeterministicChoice { children }, new)
| (new, Self::NondeterministicChoice { children }) => {
let mut new_children = children.clone();
2025-10-31 16:36:28 +01:00
new_children.push(Arc::new(new.clone()));
Self::NondeterministicChoice {
children: new_children,
}
2025-09-11 02:49:14 +02:00
},
| (_, _) => Self::NondeterministicChoice {
2025-10-31 16:36:28 +01:00
children: vec![Arc::new(self.clone()), Arc::new(new.clone())],
},
}
}
/// returns all elements used
2025-08-29 17:59:49 +02:00
fn all_elements(&self) -> Self::Set {
let mut queue = VecDeque::from([self]);
let mut elements = Self::Set::default();
while let Some(el) = queue.pop_front() {
match el {
2025-09-11 02:49:14 +02:00
| Self::Nill => {},
| Self::RecursiveIdentifier { identifier: _ } => {},
| Self::EntitySet {
entities,
next_process,
} => {
elements.push(entities);
queue.push_back(next_process);
2025-09-11 02:49:14 +02:00
},
| Self::Guarded {
reaction,
next_process,
} => {
elements.push(&reaction.reactants);
elements.push(&reaction.inhibitors);
elements.push(&reaction.products);
queue.push_back(next_process);
2025-09-11 02:49:14 +02:00
},
| Self::WaitEntity {
repeat: _,
repeated_process,
next_process,
} => {
queue.push_back(repeated_process);
queue.push_back(next_process);
2025-09-11 02:49:14 +02:00
},
| Self::Summation { children } =>
for c in children {
queue.push_back(c);
2025-09-11 02:49:14 +02:00
},
| Self::NondeterministicChoice { children } => {
for c in children {
queue.push_back(c);
}
2025-09-11 02:49:14 +02:00
},
}
}
elements
}
/// Finds only the rules X = pre(Q, rec(X)), but not only x = pre(Q, rec(x))
/// to use in filter_map.
fn filter_delta<'a>(&'a self, id: &Self::Id) -> Option<&'a Self::Set> {
2025-09-17 00:57:16 +02:00
#[allow(clippy::collapsible_if)]
if let Self::EntitySet {
entities,
next_process,
} = self
{
if let Self::RecursiveIdentifier { identifier } = &**next_process {
if identifier == id {
return Some(entities);
}
2025-09-17 00:57:16 +02:00
}
}
None
}
}
2025-08-29 17:59:49 +02:00
impl Default for Process {
fn default() -> Self {
Self::Nill
2025-08-29 17:59:49 +02:00
}
}
impl PrintableWithTranslator for Process {
2025-09-10 22:41:40 +02:00
fn print(
&self,
f: &mut std::fmt::Formatter,
translator: &Translator,
) -> std::fmt::Result {
match self {
2025-09-11 02:49:14 +02:00
| Self::Nill => {
write!(f, "Nill")
2025-09-11 02:49:14 +02:00
},
| Self::RecursiveIdentifier { identifier } => {
write!(
f,
"[{}]",
translator.decode(*identifier).unwrap_or("Missing".into())
)
2025-09-11 02:49:14 +02:00
},
| Self::EntitySet {
entities,
next_process,
} => {
write!(
f,
"{}.{}",
Formatter::from(translator, entities),
Formatter::from(translator, &**next_process)
)
2025-09-11 02:49:14 +02:00
},
| Self::Guarded {
reaction,
next_process,
} => {
write!(
f,
"?{}?.{}",
Formatter::from(translator, reaction),
Formatter::from(translator, &**next_process)
)
2025-09-11 02:49:14 +02:00
},
| Self::WaitEntity {
repeat,
repeated_process,
next_process,
} => {
write!(
f,
"({})^{repeat}.{}",
Formatter::from(translator, &**repeated_process),
Formatter::from(translator, &**next_process)
)
2025-09-11 02:49:14 +02:00
},
| Self::Summation { children } => {
write!(f, "[")?;
let mut it = children.iter().peekable();
while let Some(child) = it.next() {
if it.peek().is_none() {
write!(f, "{}", Formatter::from(translator, &**child))?;
} else {
2025-09-10 22:41:40 +02:00
write!(
f,
"{} + ",
Formatter::from(translator, &**child)
)?;
}
}
write!(f, "]")
2025-09-11 02:49:14 +02:00
},
| Self::NondeterministicChoice { children } => {
write!(f, "[")?;
let mut it = children.iter().peekable();
while let Some(child) = it.next() {
if it.peek().is_none() {
write!(f, "{}", Formatter::from(translator, &**child))?;
} else {
2025-09-10 22:41:40 +02:00
write!(
f,
"{}, ",
Formatter::from(translator, &**child)
)?;
}
}
write!(f, "]")
2025-09-11 02:49:14 +02:00
},
}
}
}
2025-08-29 17:59:49 +02:00
// -----------------------------------------------------------------------------
#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub enum PositiveProcess {
Nill,
RecursiveIdentifier {
identifier: IdType,
2025-08-29 17:59:49 +02:00
},
EntitySet {
2025-09-11 02:49:14 +02:00
entities: PositiveSet,
2025-10-31 16:36:28 +01:00
next_process: Arc<PositiveProcess>,
2025-08-29 17:59:49 +02:00
},
Guarded {
2025-09-11 02:49:14 +02:00
reaction: PositiveReaction,
2025-10-31 16:36:28 +01:00
next_process: Arc<PositiveProcess>,
2025-08-29 17:59:49 +02:00
},
WaitEntity {
repeat: i64,
2025-10-31 16:36:28 +01:00
repeated_process: Arc<PositiveProcess>,
next_process: Arc<PositiveProcess>,
2025-08-29 17:59:49 +02:00
},
Summation {
2025-10-31 16:36:28 +01:00
children: Vec<Arc<PositiveProcess>>,
2025-08-29 17:59:49 +02:00
},
NondeterministicChoice {
2025-10-31 16:36:28 +01:00
children: Vec<Arc<PositiveProcess>>,
2025-08-29 17:59:49 +02:00
},
}
impl BasicProcess for PositiveProcess {
type Id = IdType;
type Set = PositiveSet;
fn concat(&self, new: &Self) -> Self {
match (self, new) {
2025-09-11 02:49:14 +02:00
| (
Self::NondeterministicChoice { children: c1 },
Self::NondeterministicChoice { children: c2 },
) => Self::NondeterministicChoice {
children: [c1.clone(), c2.clone()].concat(),
},
2025-09-11 02:49:14 +02:00
| (Self::NondeterministicChoice { children }, new)
| (new, Self::NondeterministicChoice { children }) => {
let mut new_children = children.clone();
2025-10-31 16:36:28 +01:00
new_children.push(Arc::new(new.clone()));
Self::NondeterministicChoice {
children: new_children,
}
2025-09-11 02:49:14 +02:00
},
| (_, _) => Self::NondeterministicChoice {
2025-10-31 16:36:28 +01:00
children: vec![Arc::new(self.clone()), Arc::new(new.clone())],
},
}
2025-08-29 17:59:49 +02:00
}
/// returns all elements used
fn all_elements(&self) -> Self::Set {
let mut queue = VecDeque::from([self]);
let mut elements = Self::Set::default();
2025-08-29 17:59:49 +02:00
while let Some(el) = queue.pop_front() {
match el {
2025-09-11 02:49:14 +02:00
| Self::Nill => {},
| Self::RecursiveIdentifier { identifier: _ } => {},
| Self::EntitySet {
entities,
next_process,
} => {
elements.push(entities);
queue.push_back(next_process);
2025-09-11 02:49:14 +02:00
},
| Self::Guarded {
reaction,
next_process,
} => {
elements.push(&reaction.reactants);
elements.push(&reaction.products);
queue.push_back(next_process);
2025-09-11 02:49:14 +02:00
},
| Self::WaitEntity {
repeat: _,
repeated_process,
next_process,
} => {
queue.push_back(repeated_process);
queue.push_back(next_process);
2025-09-11 02:49:14 +02:00
},
| Self::Summation { children } =>
for c in children {
queue.push_back(c);
2025-09-11 02:49:14 +02:00
},
| Self::NondeterministicChoice { children } => {
for c in children {
queue.push_back(c);
}
2025-09-11 02:49:14 +02:00
},
}
}
elements
2025-08-29 17:59:49 +02:00
}
/// Finds only the rules X = pre(Q, rec(X)), but not only x = pre(Q, rec(x))
/// to use in filter_map.
fn filter_delta(&self, id: &Self::Id) -> Option<&Self::Set> {
2025-09-17 00:57:16 +02:00
#[allow(clippy::collapsible_if)]
if let Self::EntitySet {
entities,
next_process,
} = self
{
if let Self::RecursiveIdentifier { identifier } = &**next_process {
if identifier == id {
return Some(entities);
}
2025-09-17 00:57:16 +02:00
}
}
None
2025-08-29 17:59:49 +02:00
}
}
impl Default for PositiveProcess {
fn default() -> Self {
Self::Nill
2025-08-29 17:59:49 +02:00
}
}
impl PrintableWithTranslator for PositiveProcess {
2025-09-10 22:41:40 +02:00
fn print(
&self,
f: &mut std::fmt::Formatter,
translator: &Translator,
) -> std::fmt::Result {
match self {
2025-09-11 02:49:14 +02:00
| Self::Nill => {
write!(f, "Nill")
2025-09-11 02:49:14 +02:00
},
| Self::RecursiveIdentifier { identifier } => {
write!(
f,
"[{}]",
translator.decode(*identifier).unwrap_or("Missing".into())
)
2025-09-11 02:49:14 +02:00
},
| Self::EntitySet {
entities,
next_process,
} => {
write!(
f,
"{}.{}",
Formatter::from(translator, entities),
Formatter::from(translator, &**next_process)
)
2025-09-11 02:49:14 +02:00
},
| Self::Guarded {
reaction,
next_process,
} => {
write!(
f,
"?{}?.{}",
Formatter::from(translator, reaction),
Formatter::from(translator, &**next_process)
)
2025-09-11 02:49:14 +02:00
},
| Self::WaitEntity {
repeat,
repeated_process,
next_process,
} => {
write!(
f,
"({})^{repeat}.{}",
Formatter::from(translator, &**repeated_process),
Formatter::from(translator, &**next_process)
)
2025-09-11 02:49:14 +02:00
},
| Self::Summation { children } => {
write!(f, "[")?;
let mut it = children.iter().peekable();
while let Some(child) = it.next() {
if it.peek().is_none() {
write!(f, "{}", Formatter::from(translator, &**child))?;
} else {
2025-09-10 22:41:40 +02:00
write!(
f,
"{} + ",
Formatter::from(translator, &**child)
)?;
}
}
write!(f, "]")
2025-09-11 02:49:14 +02:00
},
| Self::NondeterministicChoice { children } => {
write!(f, "[")?;
let mut it = children.iter().peekable();
while let Some(child) = it.next() {
if it.peek().is_none() {
write!(f, "{}", Formatter::from(translator, &**child))?;
} else {
2025-09-10 22:41:40 +02:00
write!(
f,
"{}, ",
Formatter::from(translator, &**child)
)?;
}
}
write!(f, "]")
2025-09-11 02:49:14 +02:00
},
}
2025-08-29 17:59:49 +02:00
}
}
impl From<&Process> for PositiveProcess {
fn from(value: &Process) -> Self {
match value {
2025-09-11 02:49:14 +02:00
| Process::Nill => Self::Nill,
| Process::EntitySet {
entities,
next_process,
} => Self::EntitySet {
2025-09-11 02:49:14 +02:00
entities: entities.to_positive_set(IdState::Positive),
2025-10-31 16:36:28 +01:00
next_process: Arc::new((&**next_process).into()),
},
2025-09-11 02:49:14 +02:00
| Process::RecursiveIdentifier { identifier } =>
2025-09-10 22:41:40 +02:00
Self::RecursiveIdentifier {
identifier: *identifier,
2025-09-11 02:49:14 +02:00
},
| Process::Guarded {
reaction,
next_process,
} =>
// TODO: is this right?
Self::Guarded {
2025-09-11 02:49:14 +02:00
reaction: PositiveReaction {
reactants: reaction
.reactants
.to_positive_set(IdState::Positive)
2025-09-10 22:41:40 +02:00
.union(
&reaction
.inhibitors
.to_positive_set(IdState::Negative),
),
2025-09-11 02:49:14 +02:00
products: reaction
2025-09-10 22:41:40 +02:00
.products
.to_positive_set(IdState::Positive),
},
2025-10-31 16:36:28 +01:00
next_process: Arc::new((&**next_process).into()),
2025-09-11 02:49:14 +02:00
},
| Process::WaitEntity {
repeat,
repeated_process,
next_process,
} => Self::WaitEntity {
repeat: *repeat,
2025-10-31 16:36:28 +01:00
repeated_process: Arc::new((&**repeated_process).into()),
next_process: Arc::new((&**next_process).into()),
},
2025-09-11 02:49:14 +02:00
| Process::Summation { children } => Self::Summation {
2025-09-10 22:41:40 +02:00
children: children
.iter()
2025-10-31 16:36:28 +01:00
.map(|c| Arc::new((&**c).into()))
2025-09-10 22:41:40 +02:00
.collect(),
},
2025-09-11 02:49:14 +02:00
| Process::NondeterministicChoice { children } =>
2025-09-10 22:41:40 +02:00
Self::NondeterministicChoice {
children: children
.iter()
2025-10-31 16:36:28 +01:00
.map(|c| Arc::new((&**c).into()))
2025-09-10 22:41:40 +02:00
.collect(),
2025-09-11 02:49:14 +02:00
},
}
2025-08-29 17:59:49 +02:00
}
}
impl From<Process> for PositiveProcess {
2025-08-29 17:59:49 +02:00
fn from(value: Process) -> Self {
(&value).into()
2025-08-29 17:59:49 +02:00
}
}