mirror of
https://github.com/Jaxan/hybrid-ads.git
synced 2025-06-04 23:57:43 +02:00
Adds -e options, which will reduce memory usage. Adds -l option which allows an initial segment to be randomised.
This commit is contained in:
parent
687784bcf9
commit
f23946f00c
3 changed files with 45 additions and 8 deletions
|
@ -9,9 +9,13 @@ using namespace std;
|
||||||
void test(const mealy & specification, const transfer_sequences & prefixes,
|
void test(const mealy & specification, const transfer_sequences & prefixes,
|
||||||
const separating_family & separating_family, size_t k_max, const writer & output) {
|
const separating_family & separating_family, size_t k_max, const writer & output) {
|
||||||
vector<word> all_sequences(1);
|
vector<word> all_sequences(1);
|
||||||
|
test(specification, prefixes, all_sequences, separating_family, k_max, output);
|
||||||
|
}
|
||||||
|
|
||||||
for (size_t k = 0; k <= k_max; ++k) {
|
void test(const mealy & specification, const transfer_sequences & prefixes,
|
||||||
// clog << "*** K = " << k << endl;
|
vector<word> & all_sequences, const separating_family & separating_family,
|
||||||
|
size_t k_max, const writer & output) {
|
||||||
|
for (size_t k = 0; k < k_max; ++k) {
|
||||||
|
|
||||||
for (state s = 0; s < specification.graph_size; ++s) {
|
for (state s = 0; s < specification.graph_size; ++s) {
|
||||||
const auto prefix = prefixes[s];
|
const auto prefix = prefixes[s];
|
||||||
|
|
|
@ -6,16 +6,21 @@
|
||||||
#include "types.hpp"
|
#include "types.hpp"
|
||||||
|
|
||||||
#include <functional>
|
#include <functional>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
struct writer {
|
struct writer {
|
||||||
std::function<void(word)> apply; // store a part of a word
|
std::function<void(word)> apply; // store a part of a word
|
||||||
std::function<bool(void)> reset; // flush, if flase is returned, testing is stopped
|
std::function<bool(void)> reset; // flush, if flase is returned, testing is stopped
|
||||||
};
|
};
|
||||||
|
|
||||||
/// \brief Performs exhaustive tests with \p k_max extra states (harmonized, e.g. HSI / DS)
|
/// \brief Performs exhaustive tests with mid sequences < \p k_max (harmonized, e.g. HSI / DS)
|
||||||
void test(mealy const & specification, transfer_sequences const & prefixes,
|
void test(mealy const & specification, transfer_sequences const & prefixes,
|
||||||
separating_family const & separating_family, size_t k_max, writer const & output);
|
separating_family const & separating_family, size_t k_max, writer const & output);
|
||||||
|
|
||||||
|
void test(const mealy & specification, const transfer_sequences & prefixes,
|
||||||
|
std::vector<word> & all_sequences, const separating_family & separating_family,
|
||||||
|
size_t k_max, const writer & output);
|
||||||
|
|
||||||
/// \brief Performs random non-exhaustive tests for more states (harmonized, e.g. HSI / DS)
|
/// \brief Performs random non-exhaustive tests for more states (harmonized, e.g. HSI / DS)
|
||||||
void randomized_test(mealy const & specification, transfer_sequences const & prefixes,
|
void randomized_test(mealy const & specification, transfer_sequences const & prefixes,
|
||||||
separating_family const & separating_family, size_t min_k, size_t rnd_length,
|
separating_family const & separating_family, size_t min_k, size_t rnd_length,
|
||||||
|
|
38
src/main.cpp
38
src/main.cpp
|
@ -47,8 +47,10 @@ static const char USAGE[] =
|
||||||
-p <arg> How to generate prefixes: minimal, lexmin, buggy, longest
|
-p <arg> How to generate prefixes: minimal, lexmin, buggy, longest
|
||||||
-s <arg> How to generate suffixes: hsi, hads, none
|
-s <arg> How to generate suffixes: hsi, hads, none
|
||||||
-k <num> Number of extra states to check for (minus 1)
|
-k <num> Number of extra states to check for (minus 1)
|
||||||
|
-l <num> (l <= k) Redundancy free part of tests
|
||||||
-r <num> Expected length of random infix word
|
-r <num> Expected length of random infix word
|
||||||
-x <seed> 32 bits seeds for deterministic execution (0 is not valid)
|
-x <seed> 32 bits seeds for deterministic execution (0 is not valid)
|
||||||
|
-e More memory efficient
|
||||||
-f <filename> Input filename ('-' or don't specify for stdin)
|
-f <filename> Input filename ('-' or don't specify for stdin)
|
||||||
-o <filename> Output filename ('-' or don't specify for stdout)
|
-o <filename> Output filename ('-' or don't specify for stdout)
|
||||||
)";
|
)";
|
||||||
|
@ -61,11 +63,14 @@ struct main_options {
|
||||||
bool help = false;
|
bool help = false;
|
||||||
bool version = false;
|
bool version = false;
|
||||||
|
|
||||||
|
bool skip_dup = true;
|
||||||
|
|
||||||
Mode mode = ALL;
|
Mode mode = ALL;
|
||||||
PrefixMode prefix_mode = MIN;
|
PrefixMode prefix_mode = MIN;
|
||||||
SuffixMode suffix_mode = HADS;
|
SuffixMode suffix_mode = HADS;
|
||||||
|
|
||||||
unsigned long k_max = 3; // 3 means 2 extra states
|
unsigned long k_max = 3; // 3 means 2 extra states
|
||||||
|
unsigned long l = 2; // length 0, 1 will be redundancy free
|
||||||
unsigned long rnd_length = 8; // in addition to k_max
|
unsigned long rnd_length = 8; // in addition to k_max
|
||||||
unsigned long seed = 0; // 0 for unset/noise
|
unsigned long seed = 0; // 0 for unset/noise
|
||||||
|
|
||||||
|
@ -85,7 +90,7 @@ main_options parse_options(int argc, char ** argv) {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
int c;
|
int c;
|
||||||
while ((c = getopt(argc, argv, "hvm:p:s:k:r:x:f:o:")) != -1) {
|
while ((c = getopt(argc, argv, "hvem:p:s:k:l:r:x:f:o:")) != -1) {
|
||||||
switch (c) {
|
switch (c) {
|
||||||
case 'h': // show help message
|
case 'h': // show help message
|
||||||
opts.help = true;
|
opts.help = true;
|
||||||
|
@ -105,12 +110,18 @@ main_options parse_options(int argc, char ** argv) {
|
||||||
case 'k': // select extra states / k-value
|
case 'k': // select extra states / k-value
|
||||||
opts.k_max = stoul(optarg);
|
opts.k_max = stoul(optarg);
|
||||||
break;
|
break;
|
||||||
|
case 'l': //
|
||||||
|
opts.l = stoul(optarg);
|
||||||
|
break;
|
||||||
case 'r': // expected random length
|
case 'r': // expected random length
|
||||||
opts.rnd_length = stoul(optarg);
|
opts.rnd_length = stoul(optarg);
|
||||||
break;
|
break;
|
||||||
case 'x': // seed
|
case 'x': // seed
|
||||||
opts.seed = stoul(optarg);
|
opts.seed = stoul(optarg);
|
||||||
break;
|
break;
|
||||||
|
case 'e':
|
||||||
|
opts.skip_dup = false;
|
||||||
|
break;
|
||||||
case 'f': // input filename
|
case 'f': // input filename
|
||||||
opts.input_filename = optarg;
|
opts.input_filename = optarg;
|
||||||
break;
|
break;
|
||||||
|
@ -130,6 +141,7 @@ main_options parse_options(int argc, char ** argv) {
|
||||||
exit(2);
|
exit(2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
opts.l = min(opts.l, opts.k_max);
|
||||||
return opts;
|
return opts;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -302,7 +314,9 @@ int main(int argc, char * argv[]) try {
|
||||||
// For the exhaustive/preset part we first collect all words
|
// For the exhaustive/preset part we first collect all words
|
||||||
// (while removing redundant ones) before outputting them.
|
// (while removing redundant ones) before outputting them.
|
||||||
time_logger t("outputting all preset tests");
|
time_logger t("outputting all preset tests");
|
||||||
test(machine, transfer_sequences, separating_family, args.k_max,
|
|
||||||
|
vector<word> mid_sequences(1);
|
||||||
|
test(machine, transfer_sequences, mid_sequences, separating_family, args.l + 1,
|
||||||
{[&buffer](auto const & w) { buffer.insert(buffer.end(), w.begin(), w.end()); },
|
{[&buffer](auto const & w) { buffer.insert(buffer.end(), w.begin(), w.end()); },
|
||||||
[&buffer, &test_suite]() {
|
[&buffer, &test_suite]() {
|
||||||
test_suite.insert(buffer);
|
test_suite.insert(buffer);
|
||||||
|
@ -310,7 +324,21 @@ int main(int argc, char * argv[]) try {
|
||||||
return true;
|
return true;
|
||||||
}});
|
}});
|
||||||
|
|
||||||
test_suite.for_each(output_word);
|
auto first_suite = flatten(test_suite);
|
||||||
|
mt19937 g;
|
||||||
|
shuffle(first_suite.begin(), first_suite.end(), g);
|
||||||
|
for (auto const & w : first_suite) output_word(w);
|
||||||
|
first_suite.clear();
|
||||||
|
|
||||||
|
test(machine, transfer_sequences, mid_sequences, separating_family, args.k_max - args.l,
|
||||||
|
{[&buffer](auto const & w) { buffer.insert(buffer.end(), w.begin(), w.end()); },
|
||||||
|
[&buffer, &test_suite, &output_word, &args]() {
|
||||||
|
if (!args.skip_dup || test_suite.insert(buffer)) {
|
||||||
|
output_word(buffer);
|
||||||
|
}
|
||||||
|
buffer.clear();
|
||||||
|
return bool(cout);
|
||||||
|
}});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (random_part) {
|
if (random_part) {
|
||||||
|
@ -323,9 +351,9 @@ int main(int argc, char * argv[]) try {
|
||||||
randomized_test(
|
randomized_test(
|
||||||
machine, transfer_sequences, separating_family, k_max_, args.rnd_length,
|
machine, transfer_sequences, separating_family, k_max_, args.rnd_length,
|
||||||
{[&buffer](auto const & w) { buffer.insert(buffer.end(), w.begin(), w.end()); },
|
{[&buffer](auto const & w) { buffer.insert(buffer.end(), w.begin(), w.end()); },
|
||||||
[&buffer, &test_suite, &output_word]() {
|
[&buffer, &test_suite, &output_word, &args]() {
|
||||||
// TODO: probably we want to bound the size of the prefix tree
|
// TODO: probably we want to bound the size of the prefix tree
|
||||||
if (test_suite.insert(buffer)) {
|
if (!args.skip_dup || test_suite.insert(buffer)) {
|
||||||
output_word(buffer);
|
output_word(buffer);
|
||||||
}
|
}
|
||||||
buffer.clear();
|
buffer.clear();
|
||||||
|
|
Loading…
Add table
Reference in a new issue