1
use rand::Rng;
2
use rand::seq::IndexedRandom;
3
use rand::seq::IteratorRandom;
4

            
5
use merc_aterm::ATermString;
6
use merc_data::DataExpression;
7
use merc_data::DataSpecification;
8
use merc_data::DataVariable;
9
use merc_ldd::from_iter;
10
use merc_ldd::random_vector_set;
11
use merc_ldd::Storage;
12
use merc_lts::LtsMultiAction;
13
use merc_lts::TransitionLabel;
14
use merc_utilities::MercError;
15

            
16
use crate::SummandGroup;
17
use crate::SymbolicLts;
18

            
19
/// Generates random symbolic LTSs for testing purposes.
20
200
pub fn random_symbolic_lts(
21
200
    rng: &mut impl Rng,
22
200
    storage: &mut Storage,
23
200
    num_state_variables: usize,
24
200
    num_action_labels: usize,
25
200
) -> Result<SymbolicLts, MercError> {
26
200
    let num_of_values = 5usize;
27

            
28
    // Determine the state set.
29
200
    let states = random_vector_set(rng, 100, num_state_variables, num_of_values as u32);
30
200
    let initial_state = states.iter().choose(rng).ok_or("at least one state generated")?;
31

            
32
    // The action labels
33
200
    let mut action_labels = Vec::new();
34
1000
    for i in 0..num_action_labels {
35
1000
        action_labels.push(LtsMultiAction::from_index(i));
36
1000
    }
37

            
38
    // The parameter values
39
200
    let mut parameter_values = Vec::new();
40
200
    let value = DataExpression::from_string("1")?;
41
2000
    for _ in 0..num_state_variables {
42
2000
        parameter_values.push(Vec::from_iter(std::iter::repeat_n(value.clone(), num_of_values)));
43
2000
    }
44

            
45
    // The parameter names
46
200
    let parameters = (0..num_state_variables)
47
2000
        .map(|i| DataVariable::new(ATermString::new(format!("p{i}"))))
48
200
        .collect::<Vec<_>>();
49

            
50
    // Determine the summand groups.
51
200
    let mut summand_groups = Vec::new();
52
200
    for _ in 0..5 {
53
1000
        let num_of_read_variables = rng.random_range(0..parameters.len());
54
1000
        let read_parameters = parameters
55
1000
            .choose_multiple(rng, num_of_read_variables)
56
1000
            .cloned()
57
1000
            .collect::<Vec<_>>();
58

            
59
1000
        let num_of_write_variables = rng.random_range(0..parameters.len());
60
1000
        let write_parameters = parameters
61
1000
            .choose_multiple(rng, num_of_write_variables)
62
1000
            .cloned()
63
1000
            .collect::<Vec<_>>();
64

            
65
        // Reserve additional space for action labels.
66
1000
        let relation = random_vector_set(rng, 10, read_parameters.len() + write_parameters.len() + 1, 5);
67
1000
        let relation_bdd = from_iter(storage, relation.iter());
68

            
69
1000
        summand_groups.push(SummandGroup::new(
70
1000
            storage,
71
1000
            &parameters,
72
1000
            read_parameters,
73
1000
            write_parameters,
74
1000
            relation_bdd,
75
        )?)
76
    }
77

            
78
200
    let initial_state_ldd = from_iter(storage, std::iter::once(initial_state));
79
200
    let states_ldd = from_iter(storage, states.iter());
80

            
81
200
    Ok(SymbolicLts::new(
82
200
        DataSpecification::default(),
83
200
        states_ldd,
84
200
        initial_state_ldd,
85
200
        summand_groups,
86
200
        action_labels,
87
200
        parameter_values,
88
200
    ))
89
200
}