1
use std::error::Error;
2
use std::fs::File;
3
use std::io::stdout;
4
use std::io::BufWriter;
5
use std::process::ExitCode;
6

            
7
use clap::Parser;
8
use clap::ValueEnum;
9
use io::io_aut::read_aut;
10
use io::io_aut::write_aut;
11
use lts::branching_bisim_sigref;
12
use lts::branching_bisim_sigref_naive;
13
use lts::quotient_lts;
14
use lts::strong_bisim_sigref;
15
use lts::strong_bisim_sigref_naive;
16
use lts::IndexedPartition;
17

            
18
#[cfg(feature = "measure-allocs")]
19
#[global_allocator]
20
static MEASURE_ALLOC: unsafety::AllocCounter = unsafety::AllocCounter;
21

            
22
#[cfg(feature = "measure-allocs")]
23
use log::info;
24
use utilities::Timing;
25

            
26
#[cfg(not(target_env = "msvc"))]
27
#[cfg(not(feature = "measure-allocs"))]
28
#[global_allocator]
29
static ALLOC: tikv_jemallocator::Jemalloc = tikv_jemallocator::Jemalloc;
30

            
31
#[derive(Clone, Debug, ValueEnum)]
32
enum Equivalence {
33
    StrongBisim,
34
    StrongBisimNaive,
35
    BranchingBisim,
36
    BranchingBisimNaive,
37
}
38

            
39
#[derive(clap::Parser, Debug)]
40
#[command(name = "Maurice Laveaux", about = "A command line rewriting tool")]
41
struct Cli {
42
    equivalence: Equivalence,
43

            
44
    filename: String,
45

            
46
    output: Option<String>,
47

            
48
    #[arg(short, long)]
49
    tau: Option<Vec<String>>,
50

            
51
    #[arg(long)]
52
    time: bool,
53
}
54

            
55
fn main() -> Result<ExitCode, Box<dyn Error>> {
56
    env_logger::init();
57

            
58
    let cli = Cli::parse();
59

            
60
    let file = File::open(cli.filename)?;
61

            
62
    let mut timing = Timing::new();
63
    let lts = read_aut(&file, cli.tau.unwrap_or_default())?;
64

            
65
    let partition: IndexedPartition = match cli.equivalence {
66
        Equivalence::StrongBisim => strong_bisim_sigref(&lts, &mut timing),
67
        Equivalence::StrongBisimNaive => strong_bisim_sigref_naive(&lts, &mut timing),
68
        Equivalence::BranchingBisim => branching_bisim_sigref(&lts, &mut timing),
69
        Equivalence::BranchingBisimNaive => branching_bisim_sigref_naive(&lts, &mut timing),
70
    };
71

            
72
    let mut quotient_time = timing.start("quotient");
73
    let quotient_lts = quotient_lts(
74
        &lts,
75
        &partition,
76
        matches!(cli.equivalence, Equivalence::BranchingBisim)
77
            || matches!(cli.equivalence, Equivalence::BranchingBisimNaive),
78
    );
79
    if let Some(file) = cli.output {
80
        let mut writer = BufWriter::new(File::create(file)?);
81
        write_aut(&mut writer, &quotient_lts)?;
82
    } else {
83
        write_aut(&mut stdout(), &quotient_lts)?;
84
    }
85
    quotient_time.finish();
86

            
87
    if cli.time {
88
        timing.print();
89
    }
90

            
91
    #[cfg(feature = "measure-allocs")]
92
    eprintln!("allocations: {}", MEASURE_ALLOC.number_of_allocations());
93

            
94
    Ok(ExitCode::SUCCESS)
95
}