sat-solver/build_automata.cpp
2025-03-07 09:45:39 -06:00

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;
}