Files
ReactionSystems/src/rsprocess/confluence.rs

106 lines
3.0 KiB
Rust
Raw Normal View History

2025-06-22 16:09:31 +02:00
#![allow(dead_code)]
use super::perpetual::{
2025-06-22 19:37:57 +02:00
lollipops_decomposed_named,
lollipops_named,
lollipops_only_loop_decomposed,
lollipops_only_loop_decomposed_named,
lollipops_prefix_len_loop_decomposed,
lollipops_prefix_len_loop_decomposed_named
};
2025-06-22 16:09:31 +02:00
use super::structure::{RSenvironment, RSreaction, RSset};
use super::translator::IdType;
use std::cmp;
2025-06-22 18:57:35 +02:00
// see confluent, confluents
2025-06-22 16:09:31 +02:00
pub fn confluent(
delta: &RSenvironment,
reaction_rules: &[RSreaction],
entities: &[RSset],
) -> Option<(usize, usize, Vec<RSset>)> {
2025-06-22 19:37:57 +02:00
let all_loops = lollipops_prefix_len_loop_decomposed(delta,
reaction_rules,
entities.first()?);
let (prefix_len, hoop) = all_loops.first()?.clone();
let dimension = hoop.len();
let mut max_distance = prefix_len;
2025-06-22 16:09:31 +02:00
for available_entities in entities.iter().skip(1) {
2025-06-22 19:37:57 +02:00
let all_loops = lollipops_prefix_len_loop_decomposed(delta,
reaction_rules,
available_entities);
2025-06-22 16:09:31 +02:00
// FIXME we take just the first? do we compare all?
2025-06-22 19:37:57 +02:00
let (prefix_len, new_hoop) = all_loops.first()?;
2025-06-22 20:55:35 +02:00
if new_hoop.len() != dimension || !hoop.contains(new_hoop.first()?) {
2025-06-22 16:09:31 +02:00
return None;
}
2025-06-22 19:37:57 +02:00
max_distance = cmp::max(max_distance, *prefix_len);
2025-06-22 16:09:31 +02:00
}
Some((max_distance, dimension, hoop))
}
2025-06-22 18:57:35 +02:00
// see confluent, confluents
2025-06-22 16:09:31 +02:00
pub fn confluent_named(
delta: &RSenvironment,
reaction_rules: &[RSreaction],
entities: &[RSset],
symb: IdType
) -> Option<(usize, usize, Vec<RSset>)> {
2025-06-22 19:37:57 +02:00
let (prefix_len, first_hoop) =
lollipops_prefix_len_loop_decomposed_named(delta,
reaction_rules,
entities.first()?,
symb)?;
let dimension = first_hoop.len();
let mut max_distance = prefix_len;
let hoop = first_hoop;
2025-06-22 16:09:31 +02:00
for available_entities in entities.iter().skip(1) {
2025-06-22 19:37:57 +02:00
let (prefix_len, new_hoop) =
2025-06-22 18:57:35 +02:00
lollipops_prefix_len_loop_decomposed_named(delta,
reaction_rules,
available_entities,
2025-06-22 19:37:57 +02:00
symb)?;
2025-06-22 20:55:35 +02:00
if new_hoop.len() != dimension || !hoop.contains(new_hoop.first()?) {
2025-06-22 16:09:31 +02:00
return None;
}
2025-06-22 19:37:57 +02:00
max_distance = cmp::max(max_distance, prefix_len);
2025-06-22 16:09:31 +02:00
}
Some((max_distance, dimension, hoop))
}
2025-06-22 20:55:35 +02:00
// -----------------------------------------------------------------------------
pub fn invariant_named(
delta: &RSenvironment,
reaction_rules: &[RSreaction],
entities: &[RSset],
symb: IdType
) -> Option<(Vec<RSset>, Vec<RSset>)> {
let (prefix, hoop) = lollipops_decomposed_named(delta,
reaction_rules,
entities.first()?,
symb)?;
let mut invariant = vec![];
invariant.append(&mut prefix.clone());
invariant.append(&mut hoop.clone());
let dimension = hoop.len();
for available_entities in entities {
let (new_prefix, new_hoop) = lollipops_decomposed_named(delta,
reaction_rules,
available_entities,
symb)?;
if new_hoop.len() != dimension || !hoop.contains(new_hoop.first()?) {
return None
}
invariant.append(&mut new_prefix.clone());
}
Some((invariant, hoop))
}