use crate::{
ebi_traits::{
ebi_trait_finite_language::EbiTraitFiniteLanguage, ebi_trait_semantics::EbiTraitSemantics,
},
semantics::semantics::Semantics,
};
use ebi_objects::{
DeterministicFiniteAutomaton, HasActivityKey, ProcessTree,
anyhow::{Result, anyhow},
ebi_objects::process_tree::{Node, Operator},
};
use std::collections::HashSet;
pub trait FlowerMinerTree {
fn mine_flower_tree(&self) -> ProcessTree;
}
pub trait FlowerMinerDFA {
fn mine_flower_dfa(&self) -> Result<DeterministicFiniteAutomaton>;
}
impl FlowerMinerTree for dyn EbiTraitFiniteLanguage {
fn mine_flower_tree(&self) -> ProcessTree {
let mut activities = HashSet::new();
for trace in self.iter_traces() {
for activity in trace {
activities.insert(activity);
}
}
let mut tree = vec![
Node::Operator(Operator::Loop, activities.len() + 1),
Node::Tau,
];
tree.append(
&mut activities
.iter()
.map(|a| Node::Activity(**a))
.collect::<Vec<_>>(),
);
(self.activity_key().clone(), tree).into()
}
}
impl FlowerMinerDFA for dyn EbiTraitFiniteLanguage {
fn mine_flower_dfa(&self) -> Result<DeterministicFiniteAutomaton> {
let mut activities = HashSet::new();
for trace in self.iter_traces() {
for activity in trace {
activities.insert(activity);
}
}
let mut result = DeterministicFiniteAutomaton::new();
result.set_activity_key(self.activity_key().clone());
let state = result
.get_initial_state()
.ok_or_else(|| anyhow!("no initial state found"))?;
result.set_final_state(state, true);
for activity in activities {
result.add_transition(state, *activity, state)?;
}
Ok(result)
}
}
impl FlowerMinerDFA for EbiTraitSemantics {
fn mine_flower_dfa(&self) -> Result<DeterministicFiniteAutomaton> {
let mut result = DeterministicFiniteAutomaton::new();
result.set_activity_key(self.activity_key().clone());
let state = result
.get_initial_state()
.ok_or_else(|| anyhow!("no initial state found"))?;
result.set_final_state(state, true);
let activities = result
.activity_key()
.get_activities()
.into_iter()
.cloned()
.collect::<Vec<_>>();
for activity in activities {
result.add_transition(state, activity, state)?;
}
Ok(result)
}
}
impl FlowerMinerTree for EbiTraitSemantics {
fn mine_flower_tree(&self) -> ProcessTree {
let activity_key = self.activity_key().clone();
let activities = activity_key
.get_activities()
.into_iter()
.cloned()
.collect::<Vec<_>>();
let mut tree = vec![
Node::Operator(Operator::Loop, activities.len() + 1),
Node::Tau,
];
tree.append(
&mut activities
.iter()
.map(|a| Node::Activity(*a))
.collect::<Vec<_>>(),
);
(activity_key, tree).into()
}
}
impl FlowerMinerDFA for dyn HasActivityKey {
fn mine_flower_dfa(&self) -> Result<DeterministicFiniteAutomaton> {
let mut result = DeterministicFiniteAutomaton::new();
result.set_activity_key(self.activity_key().clone());
let state = result
.get_initial_state()
.ok_or_else(|| anyhow!("no initial state found"))?;
result.set_final_state(state, true);
let activities = result
.activity_key()
.get_activities()
.into_iter()
.cloned()
.collect::<Vec<_>>();
for activity in activities {
result.add_transition(state, activity, state)?;
}
Ok(result)
}
}
impl FlowerMinerTree for dyn HasActivityKey {
fn mine_flower_tree(&self) -> ProcessTree {
let activity_key = self.activity_key().clone();
let activities = activity_key
.get_activities()
.into_iter()
.cloned()
.collect::<Vec<_>>();
let mut tree = vec![
Node::Operator(Operator::Loop, activities.len() + 1),
Node::Tau,
];
tree.append(
&mut activities
.iter()
.map(|a| Node::Activity(*a))
.collect::<Vec<_>>(),
);
(activity_key, tree).into()
}
}