#include #include #include automata* build_automata( cmdln_flags& flags, refcounted p) { struct automata* automata_start = NULL; int depth = 0; for (const auto& clause: p->clauses) { struct automata* clause_start = NULL; if (flags.verbose) { printf("%*s" "building clause:\n", depth++, ""); } for (const auto& bundle: clause->bundles) { 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; } } 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::eliminate_dead_code( depth, flags.verbose, intersected); if (flags.dump_automata) { automata::dump(simped, "label = \"eliminate_dead_code\""); } 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) { automata::dump(automata_start, "label = \"abort early\""); break; } depth--; } return automata_start; }