use crate::logic::proof::Verdict;
use super::action::Action;
#[derive(Debug)]
pub struct TraceEntry<A: Action> {
pub step: usize,
pub situation_before: A::Sit,
pub action: A,
pub precondition_verdicts: Vec<Verdict>,
pub situation_after: Option<A::Sit>,
}
impl<A: Action> TraceEntry<A> {
pub fn preconditions_all_hold(&self) -> bool {
self.precondition_verdicts.iter().all(|v| v.is_ok())
}
pub fn applied(&self) -> bool {
self.situation_after.is_some() && self.preconditions_all_hold()
}
}
#[derive(Debug)]
pub struct Trace<A: Action> {
entries: Vec<TraceEntry<A>>,
}
impl<A: Action> Default for Trace<A> {
fn default() -> Self {
Self {
entries: Vec::new(),
}
}
}
impl<A: Action> Trace<A> {
pub fn new() -> Self {
Self::default()
}
pub fn entries(&self) -> &[TraceEntry<A>] {
&self.entries
}
pub fn record(&mut self, entry: TraceEntry<A>) {
self.entries.push(entry);
}
pub fn successful_steps(&self) -> usize {
self.entries.iter().filter(|e| e.applied()).count()
}
pub fn violations(&self) -> usize {
self.entries.iter().filter(|e| !e.applied()).count()
}
pub fn violation_entries(&self) -> Vec<&TraceEntry<A>> {
self.entries.iter().filter(|e| !e.applied()).collect()
}
pub fn last(&self) -> Option<&TraceEntry<A>> {
self.entries.last()
}
}