use crate::semantics::semantics::Semantics;
use ebi_objects::{
Activity, AutomatonSemantics, AutomatonState, DeterministicFiniteAutomaton,
DirectlyFollowsGraph, DirectlyFollowsModel, StochasticDeterministicFiniteAutomaton,
StochasticDirectlyFollowsModel, StochasticNondeterministicFiniteAutomaton,
anyhow::{Result, anyhow},
ebi_objects::labelled_petri_net::TransitionIndex,
};
macro_rules! aut {
($t:ty) => {
impl Semantics for $t {
type SemState = AutomatonState;
fn get_initial_state(&self) -> Option<<Self as Semantics>::SemState> {
AutomatonSemantics::initial_state(self)
}
fn execute_transition(
&self,
state: &mut <Self as Semantics>::SemState,
transition: TransitionIndex,
) -> Result<()> {
*state = self
.transition_2_target(transition)
.ok_or_else(|| anyhow!("Non-existing state."))?;
Ok(())
}
fn is_final_state(&self, state: &<Self as Semantics>::SemState) -> bool {
AutomatonSemantics::is_state_final(self, *state)
}
fn is_transition_silent(
&self,
transition: TransitionIndex,
_state: &<Self as Semantics>::SemState,
) -> bool {
AutomatonSemantics::is_transition_silent(self, transition)
}
fn get_transition_activity(
&self,
transition: TransitionIndex,
_state: &<Self as Semantics>::SemState,
) -> Option<Activity> {
AutomatonSemantics::transition_2_activity(self, transition)
}
fn get_enabled_transitions(
&self,
state: &<Self as Semantics>::SemState,
) -> Vec<TransitionIndex> {
AutomatonSemantics::outgoing_transitions(self, *state)
}
}
};
}
aut!(DeterministicFiniteAutomaton);
aut!(DirectlyFollowsGraph);
aut!(StochasticDeterministicFiniteAutomaton);
aut!(StochasticNondeterministicFiniteAutomaton);
aut!(DirectlyFollowsModel);
aut!(StochasticDirectlyFollowsModel);
#[cfg(test)]
mod tests {
use crate::semantics::semantics::Semantics;
use ebi_objects::{DirectlyFollowsGraph, HasActivityKey};
use std::fs;
#[cfg(test)]
macro_rules! assert_execute_expect {
($tree:ident, $state:ident, $t:expr, $e:expr) => {
println!("execute {} {}", ::std::stringify!($t), $t);
assert!($tree.get_enabled_transitions(&$state).contains(&$t));
$tree.execute_transition(&mut $state, $t).unwrap();
println!("state {}\n", $state);
assert_eq!($tree.get_enabled_transitions(&$state), $e);
};
}
#[test]
fn dfg_semantics() {
let fin = fs::read_to_string("testfiles/bpic12-a.xes.gz-dfg.dfg").unwrap();
let mut dfg = fin.parse::<DirectlyFollowsGraph>().unwrap();
let a_submitted = dfg.activity_key_mut().process_activity("A_SUBMITTED");
let a_partlysubmitted = dfg.activity_key_mut().process_activity("A_PARTLYSUBMITTED");
println!("{:?}", dfg.activity_key);
println!("node_2_activity {:?}", dfg.state_2_activity);
println!(
"start activities {:?}",
dfg.start_activities().collect::<Vec<_>>()
);
let mut state = dfg.get_initial_state().unwrap();
println!("state {}\n", state);
assert_eq!(dfg.get_enabled_transitions(&state), [16]);
assert_eq!(
dfg.get_transition_activity(16, &state).unwrap(),
a_submitted
);
assert_execute_expect!(dfg, state, 16, [0]);
assert_eq!(
dfg.get_transition_activity(0, &state).unwrap(),
a_partlysubmitted
);
}
}