1
use merc_lts::TransitionLabel;
2
use merc_syntax::ActFrm;
3
use merc_syntax::Action;
4
use merc_syntax::ModalityOperator;
5
use merc_syntax::MultiAction;
6
use merc_syntax::RegFrm;
7
use merc_syntax::StateFrm;
8

            
9
/// Represents a counter example.
10
pub enum CounterExample<L: TransitionLabel> {
11
    Trace(Vec<L>),
12
    WeakTrace(Vec<L>),
13
}
14

            
15
/// Generates a formula that characterizes the counter example trace.
16
178
pub fn generate_formula<L: TransitionLabel>(counter_example: &CounterExample<L>) -> StateFrm {
17
178
    let mut expr = StateFrm::True;
18

            
19
178
    match counter_example {
20
178
        CounterExample::Trace(trace) => {
21
            // We build the formula bottom up.
22
194
            for label in trace.iter().rev() {
23
194
                expr = StateFrm::Modality {
24
194
                    operator: ModalityOperator::Diamond,
25
194
                    formula: RegFrm::Action(ActFrm::MultAct(MultiAction::new(vec![Action::new(
26
194
                        label.to_string(),
27
194
                        Vec::new(),
28
194
                    )]))),
29
194
                    expr: Box::new(expr),
30
194
                }
31
            }
32
        }
33
        CounterExample::WeakTrace(trace) => {
34
            // Build the formula tau*
35
            let tau_star = RegFrm::Iteration(Box::new(RegFrm::Action(ActFrm::MultAct(MultiAction::new(vec![])))));
36

            
37
            // We build the formula bottom up: tau* . label ...
38
            for label in trace.iter().rev() {
39
                expr = StateFrm::Modality {
40
                    operator: ModalityOperator::Diamond,
41
                    formula: tau_star.clone(),
42
                    expr: Box::new(StateFrm::Modality {
43
                        operator: ModalityOperator::Diamond,
44
                        formula: RegFrm::Action(ActFrm::MultAct(MultiAction::new(vec![Action::new(
45
                            label.to_string(),
46
                            Vec::new(),
47
                        )]))),
48
                        expr: Box::new(expr),
49
                    }),
50
                }
51
            }
52
        }
53
    }
54

            
55
178
    expr
56
178
}