use std::sync::Arc;
use rustc_hash::FxHashMap;
use varpulis_zdd::{ZddArena, ZddHandle};
use super::types::{
Predicate, SharedEvent, StackEntry, MAX_ENUMERATION_RESULTS, MAX_KLEENE_EVENTS,
};
use crate::clock::Timestamp;
#[derive(Debug, Clone)]
pub struct KleeneCapture {
arena: ZddArena,
handle: ZddHandle,
pub events: Vec<SharedEvent>,
aliases: Vec<Option<String>>,
pub(crate) next_var: u32,
pub deferred_predicate: Option<Predicate>,
pub(crate) needs_zdd: bool,
}
impl KleeneCapture {
pub fn new() -> Self {
let arena = ZddArena::new();
let handle = arena.base(); Self {
arena,
handle,
events: Vec::new(),
aliases: Vec::new(),
next_var: 0,
deferred_predicate: None,
needs_zdd: false,
}
}
pub fn extend(&mut self, event: SharedEvent, alias: Option<String>) {
let var = self.next_var;
self.next_var += 1;
self.events.push(event);
self.aliases.push(alias);
self.handle = self.arena.product_with_optional(self.handle, var);
}
#[inline]
pub fn extend_simple(&mut self, event: SharedEvent, alias: Option<String>) {
self.next_var += 1;
self.events.push(event);
self.aliases.push(alias);
}
pub fn combination_count(&mut self) -> usize {
self.arena.count(self.handle)
}
pub fn event_count(&self) -> usize {
self.events.len()
}
pub fn node_count(&self) -> usize {
self.arena.node_count()
}
pub fn is_empty(&self) -> bool {
self.events.is_empty()
}
pub fn iter_combinations(&self) -> impl Iterator<Item = Vec<StackEntry>> + '_ {
self.arena.iter(self.handle).map(move |indices| {
indices
.into_iter()
.map(|idx| {
let idx = idx as usize;
StackEntry {
event: Arc::clone(&self.events[idx]),
alias: self.aliases[idx].clone(),
timestamp: Timestamp::now(),
}
})
.collect()
})
}
pub fn get_combination_captured(&self, indices: &[u32]) -> FxHashMap<String, SharedEvent> {
let mut captured = FxHashMap::default();
for &idx in indices {
let idx = idx as usize;
if let Some(ref alias) = self.aliases[idx] {
captured.insert(alias.clone(), Arc::clone(&self.events[idx]));
}
}
captured
}
}
impl Default for KleeneCapture {
fn default() -> Self {
Self::new()
}
}
#[derive(Debug, Clone, Copy)]
pub(crate) struct KleeneLimits {
pub(crate) max_events: u32,
pub(crate) max_results: usize,
}
impl Default for KleeneLimits {
fn default() -> Self {
Self {
max_events: MAX_KLEENE_EVENTS,
max_results: MAX_ENUMERATION_RESULTS,
}
}
}