1
use std::collections::VecDeque;
2
use std::fmt;
3

            
4
use merc_lts::LabelIndex;
5
use merc_lts::TransitionLabel;
6
use merc_utilities::TagIndex;
7

            
8
/// Represents a counter example.
9
pub enum CounterExample<L: TransitionLabel> {
10
    /// Represents a simple trace formula `<a0.a1. ... .a_n>true`.
11
    Trace(Vec<L>),
12
    /// Represents a weak trace formula `<tau*.a0.tau*.a1. ... .a_n.tau*>true`.
13
    WeakTrace(Vec<L>),
14
    /// Represents a stable failures formula `<tau*.a0.tau*.a1. ... .a_n.tau*>([refusal_0]false && ... [refusal_k]false)`.
15
    StableFailures(Vec<L>, Vec<L>),
16
    /// Represents a divergence formula `<tau*.a0.tau*.a1. ... .a_n.tau*>nu X. <tau>X`.
17
    Divergence(Vec<L>),
18
    /// Represents an impossible futures formula `<tau*.a0.tau*.a1. ... .a_n.tau*>([future_0. ...]false && ... [future_k. ...]false)`.
19
    ImpossibleFutures(Vec<L>, Vec<Vec<L>>),
20
}
21

            
22
/// A unique type for vertices in the counterexample tree.
23
pub struct CounterTag {}
24

            
25
/// The index type for vertices in the counterexample tree.
26
pub type CounterIndex = TagIndex<usize, CounterTag>;
27

            
28
/// A generic trait for counterexample tree structures.
29
///
30
/// # Details
31
///
32
/// This is useful such that we can both provide a concrete implementation that
33
/// constructs a counterexample tree, but also a placeholder implementation that
34
/// does nothing when no counterexample is needed.
35
pub trait CounterExampleTree {
36
    type Index: Clone + Copy;
37

            
38
    /// Returns the index of the root of the counterexample tree.
39
    fn root_index(&self) -> Self::Index;
40

            
41
    /// Adds an edge to the counterexample tree.
42
    fn add_edge(&mut self, label: LabelIndex, to: Self::Index) -> Self::Index;
43
}
44

            
45
/// A class that can be used to store a counter example tree from which a
46
/// counter example trace can be extracted.
47
pub struct CounterExampleConstructor {
48
    /// The backward tree is stored in a deque.
49
    backward_tree: VecDeque<(LabelIndex, CounterIndex)>,
50
}
51

            
52
impl CounterExampleConstructor {
53
    /// Creates a new counterexample constructor.    
54
2978
    pub fn new() -> Self {
55
2978
        Self {
56
2978
            // Add the root such that index 0 is the root.
57
2978
            backward_tree: VecDeque::from([(LabelIndex::default(), TagIndex::default())]),
58
2978
        }
59
2978
    }
60

            
61
    /// Reconstructs the trace from the counterexample tree given the index
62
    /// of the leaf node.
63
2150
    pub fn reconstruct_trace(&self, mut index: CounterIndex) -> Vec<LabelIndex> {
64
2150
        let mut trace = Vec::new();
65

            
66
5435
        while index != self.root_index() {
67
3285
            let (label, parent) = &self.backward_tree[*index];
68
3285
            trace.push(*label);
69
3285
            index = *parent;
70
3285
        }
71

            
72
2150
        trace.reverse();
73
2150
        trace
74
2150
    }
75
}
76

            
77
impl fmt::Debug for CounterExampleConstructor {
78
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
79
        f.debug_struct("CounterExampleConstructor")
80
            .field("backward_tree", &self.backward_tree)
81
            .finish()
82
    }
83
}
84

            
85
impl CounterExampleTree for CounterExampleConstructor {
86
    type Index = CounterIndex;
87

            
88
8231
    fn add_edge(&mut self, label: LabelIndex, to: Self::Index) -> Self::Index {
89
8231
        self.backward_tree.push_back((label, to));
90
8231
        TagIndex::new(self.backward_tree.len() - 1)
91
8231
    }
92

            
93
8413
    fn root_index(&self) -> Self::Index {
94
8413
        TagIndex::new(0)
95
8413
    }
96
}
97

            
98
impl Default for CounterExampleConstructor {
99
    fn default() -> Self {
100
        Self::new()
101
    }
102
}
103

            
104
impl CounterExampleTree for () {
105
    type Index = ();
106

            
107
2659
    fn add_edge(&mut self, _label: LabelIndex, _to: Self::Index) -> Self::Index {
108
        // Do nothing
109
2659
    }
110

            
111
834
    fn root_index(&self) -> Self::Index {}
112
}