136 lines
3.2 KiB
C++
136 lines
3.2 KiB
C++
|
|
#include <dict.hpp>
|
|
|
|
#include <print.hpp>
|
|
|
|
#include <build_automata.hpp>
|
|
|
|
automata* build_automata(
|
|
cmdln_flags& flags,
|
|
refcounted<problem> p)
|
|
{
|
|
struct automata* automata_start = NULL;
|
|
|
|
int depth = 0;
|
|
|
|
for (const auto& clause: p->clauses)
|
|
{
|
|
struct automata* clause_start = NULL;
|
|
|
|
depth++;
|
|
|
|
for (const auto& bundle: clause->bundles)
|
|
{
|
|
depth++;
|
|
|
|
unsigned index = bundle.variable - 1;
|
|
|
|
struct automata* variable_start = automata::new_variable(
|
|
depth, flags.verbose,
|
|
index, bundle.value,
|
|
p->number_of_variables);
|
|
|
|
if (flags.dump_automata)
|
|
{
|
|
automata::dump(variable_start,
|
|
"label = \"%i (%u) = %s\"",
|
|
bundle.variable, index,
|
|
bundle.value ? "true" : "false");
|
|
}
|
|
|
|
if (clause_start)
|
|
{
|
|
struct automata* old = clause_start;
|
|
|
|
struct automata* unioned = automata::union_(
|
|
depth, flags.verbose, old, variable_start);
|
|
|
|
if (flags.dump_automata)
|
|
{
|
|
automata::dump(unioned, "label = \"union\"");
|
|
}
|
|
|
|
struct automata* simped = automata::simplify(
|
|
depth, flags.verbose, unioned);
|
|
|
|
if (flags.dump_automata)
|
|
{
|
|
automata::dump(simped, "label = \"simped\"");
|
|
}
|
|
|
|
clause_start = simped;
|
|
|
|
automata::free(unioned);
|
|
|
|
automata::free(variable_start);
|
|
|
|
automata::free(old);
|
|
}
|
|
else
|
|
{
|
|
clause_start = variable_start;
|
|
}
|
|
|
|
depth--;
|
|
}
|
|
|
|
if (automata_start)
|
|
{
|
|
struct automata* old = automata_start;
|
|
|
|
struct automata* intersected = automata::intersect(
|
|
depth, flags.verbose, old, clause_start);
|
|
|
|
if (flags.dump_automata)
|
|
{
|
|
automata::dump(intersected, "label = \"intersect\"");
|
|
}
|
|
|
|
struct automata* simped = automata::simplify(
|
|
depth, flags.verbose, intersected);
|
|
|
|
if (flags.dump_automata)
|
|
{
|
|
automata::dump(simped, "label = \"simped\"");
|
|
}
|
|
|
|
automata_start = simped;
|
|
|
|
automata::free(intersected);
|
|
|
|
automata::free(clause_start);
|
|
|
|
automata::free(old);
|
|
}
|
|
else
|
|
{
|
|
automata_start = clause_start;
|
|
}
|
|
|
|
// if the solution space is empty, no further intersections are going
|
|
// to fix it.
|
|
if (!automata_start)
|
|
{
|
|
break;
|
|
}
|
|
|
|
depth--;
|
|
}
|
|
|
|
return automata_start;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|