1
use rand::Rng;
2
use rustc_hash::FxHashSet;
3

            
4
use crate::LabelledTransitionSystem;
5

            
6
/// Generates a monolithic LTS with the desired number of states, labels, out
7
/// degree and in degree for all the states.
8
9
pub fn random_lts(num_of_states: usize, num_of_labels: u32, outdegree: usize) -> LabelledTransitionSystem {
9
9
    // Introduce lower case letters for the labels.
10
9
    let tau_label = "tau".to_string();
11
9

            
12
9
    let mut labels: Vec<String> = vec![tau_label.clone()];
13
39
    for i in 0..num_of_labels {
14
39
        labels.push(char::from_digit(i + 10, 36).unwrap().to_string());
15
39
    }
16

            
17
9
    let mut rng = rand::rng();
18
9
    let mut transitions: FxHashSet<(usize, usize, usize)> = FxHashSet::default();
19

            
20
90
    for state_index in 0..num_of_states {
21
        // Introduce outgoing transitions for this state based on the desired out degree.
22
90
        for _ in 0..rng.random_range(0..outdegree) {
23
77
            // Pick a random label and state.
24
77
            let label = rng.random_range(0..num_of_labels);
25
77
            let to = rng.random_range(0..num_of_states);
26
77

            
27
77
            transitions.insert((state_index, label as usize, to));
28
77
        }
29
    }
30

            
31
9
    LabelledTransitionSystem::new(0, 
32
9
        Some(num_of_states),
33
18
        || transitions.iter().cloned(),
34
9
        labels, 
35
9
        vec![tau_label])
36
9
}
37

            
38
#[cfg(test)]
39
mod tests {
40
    use test_log::test;
41

            
42
    use super::*;
43

            
44
1
    #[test]
45
    fn test_random_lts() {
46
        let _lts = random_lts(10, 3, 3);
47
    }
48
}