1
#![forbid(unsafe_code)]
2

            
3
use clap::ValueEnum;
4
use merc_lts::LTS;
5
use merc_lts::LabelledTransitionSystem;
6
use merc_utilities::Timing;
7

            
8
use crate::branching_bisim_sigref;
9
use crate::branching_bisim_sigref_naive;
10
use crate::quotient_lts_block;
11
use crate::quotient_lts_naive;
12
use crate::strong_bisim_sigref;
13
use crate::strong_bisim_sigref_naive;
14
use crate::weak_bisim_sigref_naive;
15
use crate::weak_bisimulation;
16

            
17
#[derive(Copy, Clone, Debug, ValueEnum)]
18
pub enum Equivalence {
19
    /// Partition based refinement algorithms.
20
    WeakBisim,
21
    /// Various signature based reduction algorithms.
22
    WeakBisimSigref,
23
    StrongBisim,
24
    StrongBisimNaive,
25
    BranchingBisim,
26
    BranchingBisimNaive,
27
}
28

            
29
/// Reduces the given LTS modulo the given equivalence using signature refinement
30
300
pub fn reduce_lts<L: LTS>(lts: L, equivalence: Equivalence, timing: &mut Timing) -> LabelledTransitionSystem<L::Label> {
31
300
    let (result, mut timer) = match equivalence {
32
        Equivalence::WeakBisim => {
33
100
            let (lts, partition) = weak_bisimulation(lts, timing);
34
100
            let quotient_time = timing.start("quotient");
35
100
            (quotient_lts_naive(&lts, &partition, true), quotient_time)
36
        }
37
        Equivalence::WeakBisimSigref => {
38
100
            let (lts, partition) = weak_bisim_sigref_naive(lts, timing);
39
100
            let quotient_time = timing.start("quotient");
40
100
            (quotient_lts_naive(&lts, &partition, true), quotient_time)
41
        }
42
        Equivalence::StrongBisim => {
43
100
            let (lts, partition) = strong_bisim_sigref(lts, timing);
44
100
            let quotient_time = timing.start("quotient");
45
100
            (quotient_lts_block::<_, false>(&lts, &partition), quotient_time)
46
        }
47
        Equivalence::StrongBisimNaive => {
48
            let (lts, partition) = strong_bisim_sigref_naive(lts, timing);
49
            let quotient_time = timing.start("quotient");
50
            (quotient_lts_naive(&lts, &partition, false), quotient_time)
51
        }
52
        Equivalence::BranchingBisim => {
53
            let (lts, partition) = branching_bisim_sigref(lts, timing);
54
            let quotient_time = timing.start("quotient");
55
            (quotient_lts_block::<_, true>(&lts, &partition), quotient_time)
56
        }
57
        Equivalence::BranchingBisimNaive => {
58
            let (lts, partition) = branching_bisim_sigref_naive(lts, timing);
59
            let quotient_time = timing.start("quotient");
60
            (quotient_lts_naive(&lts, &partition, true), quotient_time)
61
        }
62
    };
63

            
64
300
    timer.finish();
65
300
    result
66
300
}