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
5654
    pub fn new() -> Self {
55
5654
        Self {
56
5654
            // Add the root such that index 0 is the root.
57
5654
            backward_tree: VecDeque::from([(LabelIndex::default(), TagIndex::default())]),
58
5654
        }
59
5654
    }
60

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

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

            
72
4058
        trace.reverse();
73
4058
        trace
74
4058
    }
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
14327
    fn add_edge(&mut self, label: LabelIndex, to: Self::Index) -> Self::Index {
89
14327
        self.backward_tree.push_back((label, to));
90
14327
        TagIndex::new(self.backward_tree.len() - 1)
91
14327
    }
92

            
93
15778
    fn root_index(&self) -> Self::Index {
94
15778
        TagIndex::new(0)
95
15778
    }
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
4290
    fn add_edge(&mut self, _label: LabelIndex, _to: Self::Index) -> Self::Index {
108
        // Do nothing
109
4290
    }
110

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