From 00c1954ebabb8ea1cb74acd381d5f5dca2ecce3b Mon Sep 17 00:00:00 2001 From: Joshua Moerman Date: Fri, 18 Sep 2015 13:17:11 +0200 Subject: [PATCH] Adds better (and more) command line option handling --- src/main.cpp | 59 ++++++++++++++++++++++++++++++++++++------------ src/methods.cpp | 60 +++++++++++++++++++++++-------------------------- 2 files changed, 73 insertions(+), 46 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index e7bc044..7640400 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -8,6 +8,8 @@ #include #include +#include + #include #include #include @@ -16,27 +18,46 @@ using namespace std; +static const char USAGE[] = +R"(Generate a test suite + + Usage: + main [options] (all|fixed|random) + + Options: + -h, --help Show this screen + --version Show version + --seed 32 bits seeds for deterministic execution + --no-ds Only use the classical algorithm (hsi) + --random-ds Choose randomly between the ds method or hsi method + --no-suffix Dont calculate anything smart, just do the random stuff +)"; + using time_logger = silent_timer; int main(int argc, char *argv[]) try { - if(argc != 5 && argc != 6) { - cerr << "usage: main []" << endl; - return 1; - } - const string filename = argv[1]; - const bool use_stdio = filename == "--"; + const auto args = docopt::docopt(USAGE, {argv + 1, argv + argc}, true, "5 aug 11:00"); - const auto k_max = stoul(argv[2]); - const auto rnd_length = stoul(argv[3]); + const string filename = args.at("").asString(); + const bool use_stdio = filename == "="; - const string mode = argv[4]; - const bool streaming = mode == "all" || mode == "fixed"; - const bool random_part = mode == "all" || mode == "random"; + const auto k_max = args.at("").asLong(); + const auto rnd_length = args.at("").asLong(); - const bool seed_provided = argc == 6; - const uint_fast32_t seed = seed_provided ? stoul(argv[5]) : 0; + const bool streaming = args.at("all").asBool() || args.at("fixed").asBool(); + const bool random_part = args.at("all").asBool() || args.at("random").asBool(); + const bool no_suffix = args.at("--no-suffix").asBool(); - const bool use_distinguishing_sequence = true; + const bool seed_provided = bool(args.at("--seed")); + const uint_fast32_t seed = seed_provided ? args.at("--seed").asLong() : 0; + + const bool use_distinguishing_sequence = [&]{ + if(args.at("--random-ds").asBool()) { + random_device rd; + return rd() - rd.min() < (rd.max() - rd.min()) / 2; + } + return !args.at("--no-ds").asBool(); + }(); const bool randomize_prefixes = true; const bool randomize_hopcroft = true; const bool randomize_lee_yannakakis = true; @@ -75,6 +96,8 @@ int main(int argc, char *argv[]) try { }(); auto all_pair_separating_sequences = [&]{ + if(no_suffix) return splitting_tree(0, 0); + const auto splitting_tree_hopcroft = [&]{ time_logger t("creating hopcroft splitting tree"); return create_splitting_tree(machine, randomize_hopcroft ? randomized_hopcroft_style : hopcroft_style, random_seeds[0]); @@ -84,6 +107,8 @@ int main(int argc, char *argv[]) try { }(); auto sequence = [&]{ + if(no_suffix) return adaptive_distinguishing_sequence(0, 0); + const auto tree = [&]{ time_logger t("Lee & Yannakakis I"); if(use_distinguishing_sequence) @@ -112,6 +137,12 @@ int main(int argc, char *argv[]) try { auto inputs = create_reverse_map(translation.input_indices); const auto separating_family = [&]{ + if(no_suffix) { + separating_set s{{word{}}}; + vector suffixes(machine.graph_size, s); + return suffixes; + } + time_logger t("making seperating family"); return create_separating_family(sequence, all_pair_separating_sequences); }(); diff --git a/src/methods.cpp b/src/methods.cpp index 782d31b..03463be 100644 --- a/src/methods.cpp +++ b/src/methods.cpp @@ -5,6 +5,8 @@ #include #include +#include + #include #include #include @@ -12,28 +14,25 @@ using namespace std; -enum Method { - hsi_method, - ds_plus_method, -}; +static const char USAGE[] = +R"(FSM-based test methods -static Method parse_method(string const & s) { - if (s == "--W-method") return hsi_method; - if (s == "--DS-method") return ds_plus_method; - throw runtime_error("No valid method specified"); -} + Usage: + methods (hsi|ads) [options] + + Options: + -h, --help Show current help + --version Show version + -s , --seed Specify a seed + --non-random Iterate inputs in specified order (as occurring in input file) + -k Testing extra states [default: 0] +)"; int main(int argc, char * argv[]) { - if (argc != 4 && argc != 5) { - cerr << "usage: methods []\n"; - return 1; - } + const auto args = docopt::docopt(USAGE, {argv + 1, argv + argc}, true, __DATE__ __TIME__); - const string filename = argv[1]; - const Method method = parse_method(argv[2]); - const size_t k_max = std::stoul(argv[3]); - const bool seed_provided = argc == 5; - const uint_fast32_t seed = seed_provided ? stoul(argv[4]) : 0; + const string filename = args.at("").asString(); + const size_t k_max = args.at("-k").asLong() + 1; const auto machine = [&] { if (filename.find(".txt") != string::npos) { @@ -48,8 +47,8 @@ int main(int argc, char * argv[]) { const auto random_seeds = [&] { vector seeds(3); - if (seed_provided) { - seed_seq s{seed}; + if (args.at("--seed")) { + seed_seq s{args.at("--seed").asLong()}; s.generate(seeds.begin(), seeds.end()); } else { random_device rd; @@ -59,21 +58,22 @@ int main(int argc, char * argv[]) { }(); auto sequence_fut = async([&] { - if (method == hsi_method) { + if (args.at("hsi").asBool()) { return create_adaptive_distinguishing_sequence(result(machine.graph_size)); } - const auto tree = create_splitting_tree(machine, randomized_lee_yannakakis_style, random_seeds[0]); + const auto tree + = create_splitting_tree(machine, args.at("--non-random").asBool() ? lee_yannakakis_style : randomized_lee_yannakakis_style, random_seeds[0]); return create_adaptive_distinguishing_sequence(tree); }); auto pairs_fut = async([&] { - const auto tree = create_splitting_tree(machine, randomized_min_hopcroft_style, random_seeds[1]); + const auto tree + = create_splitting_tree(machine, args.at("--non-random").asBool() ? min_hopcroft_style : randomized_min_hopcroft_style, random_seeds[1]); return tree.root; }); - auto prefixes_fut = async([&] { - return create_randomized_transfer_sequences(machine, 0, random_seeds[2]); - }); + auto prefixes_fut + = async([&] { return create_randomized_transfer_sequences(machine, 0, random_seeds[2]); }); auto middles_fut = async([&] { vector all_sequences(1); @@ -85,18 +85,14 @@ int main(int argc, char * argv[]) { return all_sequences; }); - // clog << "getting sequence and pairs" << endl; - auto suffixes_fut = async([&] { - return create_separating_family(sequence_fut.get(), pairs_fut.get()); - }); + auto suffixes_fut + = async([&] { return create_separating_family(sequence_fut.get(), pairs_fut.get()); }); - // clog << "getting prefixes, middles and suffixes" << endl; const auto prefixes = prefixes_fut.get(); const auto middles = middles_fut.get(); const auto suffixes = suffixes_fut.get(); trie test_suite; - // clog << "start testing" << endl; const state start = 0; const word empty = {}; for (auto && p : prefixes) {