1
use merc_data::DataExpression;
2
use merc_data::DataSpecification;
3
use merc_lts::LtsAction;
4
use merc_lts::LtsMultiAction;
5
use oxidd::ldd::LDDFunction;
6

            
7
use crate::SummandGroup;
8
use crate::SymbolicLPS;
9
use crate::SymbolicLTS;
10

            
11
/// Represents a symbolic LTS encoded by a disjunctive transition relation and a set of states.
12
pub struct SymbolicLts {
13
    data_specification: DataSpecification,
14
    states: LDDFunction,
15

            
16
    /// A singleton LDD representing the initial state.
17
    initial_state: LDDFunction,
18
    summand_groups: Vec<SummandGroup>,
19

            
20
    /// The action labels of the LTS, stored as their string representation,
21
    /// their position corresponds to the LDD values.
22
    action_labels: Vec<String>,
23

            
24
    /// The possible values for each process parameter, their position
25
    /// corresponds to the LDD values.
26
    parameter_values: Vec<Vec<DataExpression>>,
27
}
28

            
29
impl SymbolicLts {
30
    /// Creates a new symbolic LTS.
31
    ///
32
    /// `states` is the known state space (pass `initial_state.clone()` when the full set is not
33
    /// yet known, or provide the reachable set computed by [crate::reachability]).
34
406
    pub fn new(
35
406
        data_specification: DataSpecification,
36
406
        states: LDDFunction,
37
406
        initial_state: LDDFunction,
38
406
        summand_groups: Vec<SummandGroup>,
39
406
        action_labels: Vec<LtsMultiAction<LtsAction>>,
40
406
        parameter_values: Vec<Vec<DataExpression>>,
41
406
    ) -> Self {
42
406
        let action_labels = action_labels
43
406
            .into_iter()
44
2335
            .map(|aterm| format!("{}", aterm))
45
406
            .collect::<Vec<String>>();
46

            
47
406
        Self {
48
406
            data_specification,
49
406
            states,
50
406
            initial_state,
51
406
            summand_groups,
52
406
            action_labels,
53
406
            parameter_values,
54
406
        }
55
406
    }
56

            
57
    /// Returns the data specification of the LTS.
58
    pub fn data_specification(&self) -> &DataSpecification {
59
        &self.data_specification
60
    }
61

            
62
    pub fn parameter_values(&self) -> &[Vec<DataExpression>] {
63
        &self.parameter_values
64
    }
65
}
66

            
67
impl SymbolicLPS for SymbolicLts {
68
    type Group = SummandGroup;
69

            
70
905
    fn initial_state(&self) -> &LDDFunction {
71
905
        &self.initial_state
72
905
    }
73

            
74
28458
    fn transition_groups(&self) -> &[Self::Group] {
75
28458
        &self.summand_groups
76
28458
    }
77

            
78
339
    fn transition_groups_mut(&mut self) -> &mut [Self::Group] {
79
339
        &mut self.summand_groups
80
339
    }
81

            
82
100
    fn create_context(&self) {}
83
}
84

            
85
impl SymbolicLTS for SymbolicLts {
86
1812
    fn states(&self) -> &LDDFunction {
87
1812
        &self.states
88
1812
    }
89

            
90
537887
    fn action_labels(&self) -> &[String] {
91
537887
        &self.action_labels
92
537887
    }
93

            
94
504
    fn parameter_values(&self) -> &[Vec<DataExpression>] {
95
504
        &self.parameter_values
96
504
    }
97
}