use wasm4pm::models::PetriNet;
use wasm4pm_compat::event_log::EventLog as CompatEventLog;
pub struct IlpDiscoveryResult {
pub petri_net: PetriNet,
pub fitness: f64,
pub precision: f64,
}
pub fn discover_ilp_real(
log: &CompatEventLog,
activity_key: &str,
) -> anyhow::Result<IlpDiscoveryResult> {
let native_log: wasm4pm::models::EventLog = log.clone().into();
let (petri_net, fitness, precision) =
wasm4pm::ilp_discovery::discover_ilp_petri_net_from_log(&native_log, activity_key);
Ok(IlpDiscoveryResult {
petri_net,
fitness,
precision,
})
}
#[cfg(test)]
mod tests {
use super::*;
use wasm4pm_compat::event_log::{Event, Trace};
fn build_small_log() -> CompatEventLog {
let trace1 = Trace::new(
"case-1".to_string(),
vec![
Event::with_activity("a"),
Event::with_activity("b"),
Event::with_activity("c"),
],
);
let trace2 = Trace::new(
"case-2".to_string(),
vec![
Event::with_activity("a"),
Event::with_activity("b"),
Event::with_activity("c"),
],
);
let trace3 = Trace::new(
"case-3".to_string(),
vec![
Event::with_activity("a"),
Event::with_activity("b"),
Event::with_activity("c"),
],
);
CompatEventLog {
attributes: Vec::new(),
traces: vec![trace1, trace2, trace3],
extensions: None,
classifiers: None,
global_trace_attrs: None,
global_event_attrs: None,
}
}
#[test]
fn discover_ilp_real_runs_on_small_log_and_finds_causal_places() {
let log = build_small_log();
let result = discover_ilp_real(&log, "concept:name")
.expect("ILP discovery should run without panicking");
assert!(
!result.petri_net.transitions.is_empty(),
"expected transitions for a, b, c, got {:?}",
result.petri_net.transitions
);
assert!(
result.petri_net.places.len() > 2,
"expected source/sink plus at least one causal region place, got places: {:?}",
result.petri_net.places
);
assert!(
result.fitness > 0.0,
"expected positive replay fitness for a log that is fully covered by its own \
discovered model, got fitness={}",
result.fitness
);
}
}