mirror of
https://github.com/Jaxan/hybrid-ads.git
synced 2025-04-27 23:17:44 +02:00
Adds the two families of automata occurring in Hopcrofts paper
This commit is contained in:
parent
01bc580081
commit
415689b04c
1 changed files with 65 additions and 28 deletions
|
@ -11,10 +11,12 @@
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
static const char USAGE[] =
|
static const char USAGE[] =
|
||||||
R"(Random Mealy machine generator
|
R"(Random Mealy machine generator
|
||||||
|
|
||||||
Usage:
|
Usage:
|
||||||
generator random [-mc] <states> <inputs> <outputs> <machines> [<seed>]
|
generator random [-mc] <states> <inputs> <outputs> <machines> [<seed>]
|
||||||
|
generator hopcroft a <states>
|
||||||
|
generator hopcroft b <states>
|
||||||
|
|
||||||
Options:
|
Options:
|
||||||
-h, --help Show this screen
|
-h, --help Show this screen
|
||||||
|
@ -51,8 +53,8 @@ static mealy generate_random_machine(size_t N, size_t P, size_t Q, mt19937 & gen
|
||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void print_machine(mealy const & m, size_t count) {
|
static void print_machine(string const & prefix, mealy const & m, size_t count) {
|
||||||
ofstream file("machine_" + to_string(m.graph_size) + "_" + to_string(m.input_size) + "_"
|
ofstream file(prefix + "_" + to_string(m.graph_size) + "_" + to_string(m.input_size) + "_"
|
||||||
+ to_string(m.output_size) + "_" + to_string(count) + ".txt");
|
+ to_string(m.output_size) + "_" + to_string(count) + ".txt");
|
||||||
for (state s = 0; s < m.graph_size; ++s) {
|
for (state s = 0; s < m.graph_size; ++s) {
|
||||||
for (input i = 0; i < m.input_size; ++i) {
|
for (input i = 0; i < m.input_size; ++i) {
|
||||||
|
@ -64,38 +66,73 @@ static void print_machine(mealy const & m, size_t count) {
|
||||||
|
|
||||||
int main(int argc, char * argv[]) {
|
int main(int argc, char * argv[]) {
|
||||||
const auto args = docopt::docopt(USAGE, {argv + 1, argv + argc}, true, __DATE__ __TIME__);
|
const auto args = docopt::docopt(USAGE, {argv + 1, argv + argc}, true, __DATE__ __TIME__);
|
||||||
for (auto const & arg : args) {
|
|
||||||
std::cout << arg.first << arg.second << std::endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto gen = [&] {
|
if (args.at("random").asBool()) {
|
||||||
if (args.at("<seed>")) {
|
auto gen = [&] {
|
||||||
auto seed = args.at("<seed>").asLong();
|
if (args.at("<seed>")) {
|
||||||
return mt19937(seed);
|
auto seed = args.at("<seed>").asLong();
|
||||||
|
return mt19937(seed);
|
||||||
|
}
|
||||||
|
random_device rd;
|
||||||
|
return mt19937(rd());
|
||||||
|
}();
|
||||||
|
|
||||||
|
size_t number_of_machines = args.at("<machines>").asLong();
|
||||||
|
size_t constructed = 0;
|
||||||
|
|
||||||
|
while (constructed < number_of_machines) {
|
||||||
|
auto const m = generate_random_machine(args.at("<states>").asLong(),
|
||||||
|
args.at("<inputs>").asLong(),
|
||||||
|
args.at("<outputs>").asLong(), gen);
|
||||||
|
|
||||||
|
if (args.at("--connected").asBool()) {
|
||||||
|
auto const m2 = reachable_submachine(m, 0);
|
||||||
|
if (m2.graph_size != m.graph_size) continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (args.at("--minimal").asBool()) {
|
||||||
|
auto const tree = create_splitting_tree(m, min_hopcroft_style, 0).root;
|
||||||
|
if (number_of_leaves(tree) != m.graph_size) continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
constructed++;
|
||||||
|
print_machine("machine", m, constructed);
|
||||||
}
|
}
|
||||||
random_device rd;
|
} else if (args.at("hopcroft").asBool() && args.at("a").asBool()) {
|
||||||
return mt19937(rd());
|
mealy m;
|
||||||
}();
|
|
||||||
|
|
||||||
size_t number_of_machines = args.at("<machines>").asLong();
|
m.graph_size = args.at("<states>").asLong();
|
||||||
size_t constructed = 0;
|
m.input_size = m.output_size = 2;
|
||||||
|
m.graph.assign(m.graph_size, vector<mealy::edge>(m.input_size));
|
||||||
|
|
||||||
while (constructed < number_of_machines) {
|
for (state s = 0; s < m.graph_size; ++s) {
|
||||||
auto const m
|
m.graph[s][0] = mealy::edge(s + 1, 0);
|
||||||
= generate_random_machine(args.at("<states>").asLong(), args.at("<inputs>").asLong(),
|
m.graph[s][1] = mealy::edge(s, 0);
|
||||||
args.at("<outputs>").asLong(), gen);
|
|
||||||
|
|
||||||
if (args.at("--connected").asBool()) {
|
|
||||||
auto const m2 = reachable_submachine(m, 0);
|
|
||||||
if (m2.graph_size != m.graph_size) continue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (args.at("--minimal").asBool()) {
|
// "accepting state"
|
||||||
auto const tree = create_splitting_tree(m, min_hopcroft_style, 0).root;
|
m.graph[m.graph_size - 1][0] = mealy::edge(m.graph_size - 1, 1);
|
||||||
if (number_of_leaves(tree) != m.graph_size) continue;
|
m.graph[m.graph_size - 1][1] = mealy::edge(m.graph_size - 1, 1);
|
||||||
|
|
||||||
|
print_machine("hopcroft_a", m, 1);
|
||||||
|
} else if (args.at("hopcroft").asBool() && args.at("b").asBool()) {
|
||||||
|
// In the original paper, the machine is not well defined...
|
||||||
|
// So I don't know what Hopcroft had in mind exactly...
|
||||||
|
mealy m;
|
||||||
|
|
||||||
|
auto n = m.graph_size = args.at("<states>").asLong();
|
||||||
|
m.input_size = m.output_size = 2;
|
||||||
|
m.graph.assign(m.graph_size, vector<mealy::edge>(m.input_size));
|
||||||
|
|
||||||
|
for (state s = 0; s < n; ++s) {
|
||||||
|
m.graph[s][0] = mealy::edge(s ? s - 1 : 0, s < n / 2 ? 0 : 1);
|
||||||
|
if (s < n / 2) {
|
||||||
|
m.graph[s][1] = mealy::edge(2 * s + 1, 0);
|
||||||
|
} else {
|
||||||
|
m.graph[s][1] = mealy::edge(s + (n - s) / 2, 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
constructed++;
|
print_machine("hopcroft_b", m, 1);
|
||||||
print_machine(m, constructed);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue