shuffledimacs/
shuffledimacs.rs1use std::path::{Path, PathBuf};
9
10use anyhow::Context;
11use rustsat::instances::{self, BasicVarManager, RandReindVarManager};
12
13macro_rules! print_usage {
14 () => {{
15 eprintln!("Usage: shuffledimacs [dimacs [m,w]cnf file] [output path]");
16 panic!()
17 }};
18}
19
20enum FileType {
21 Cnf,
22 Wcnf,
23 Mcnf,
24}
25
26fn main() -> anyhow::Result<()> {
27 let in_path = PathBuf::from(&std::env::args().nth(1).unwrap_or_else(|| print_usage!()));
28 let out_path = PathBuf::from(&std::env::args().nth(2).unwrap_or_else(|| print_usage!()));
29
30 match determine_file_type(&in_path) {
31 FileType::Cnf => {
32 let inst = instances::SatInstance::<BasicVarManager>::from_dimacs_path(in_path)
33 .context("Could not parse CNF")?;
34 let n_vars = inst.n_vars();
35 let rand_reindexer = RandReindVarManager::init(n_vars);
36 inst.reindex(rand_reindexer)
37 .shuffle()
38 .write_dimacs_path(out_path)
39 .context("Could not write CNF")?;
40 }
41 FileType::Wcnf => {
42 let inst = instances::OptInstance::<BasicVarManager>::from_dimacs_path(in_path)
43 .context("Could not parse WCNF")?;
44 let n_vars = inst.constraints_ref().n_vars();
45 let rand_reindexer = RandReindVarManager::init(n_vars);
46 inst.reindex(rand_reindexer)
47 .shuffle()
48 .write_dimacs_path(out_path)
49 .context("Could not write WCNF")?;
50 }
51 FileType::Mcnf => {
52 let inst = instances::MultiOptInstance::<BasicVarManager>::from_dimacs_path(in_path)
53 .context("Could not parse MCNF")?;
54 let n_vars = inst.constraints_ref().n_vars();
55 let rand_reindexer = RandReindVarManager::init(n_vars);
56 inst.reindex(rand_reindexer)
57 .shuffle()
58 .write_dimacs_path(out_path)
59 .context("Could not write MCNF")?;
60 }
61 }
62 Ok(())
63}
64
65macro_rules! is_one_of {
66 ($a:expr, $($b:expr),*) => {
67 $( $a == $b || )* false
68 }
69}
70
71fn determine_file_type(in_path: &Path) -> FileType {
72 if let Some(ext) = in_path.extension() {
73 let path_without_compr = in_path.with_extension("");
74 let ext = if is_one_of!(ext, "gz", "bz2") {
75 match path_without_compr.extension() {
77 Some(ext) => ext,
78 None => return FileType::Cnf, }
80 } else {
81 ext
82 };
83 if "wcnf" == ext {
84 return FileType::Wcnf;
85 };
86 if "mcnf" == ext {
87 return FileType::Mcnf;
88 };
89 return FileType::Cnf; };
91 FileType::Cnf }