103 lines
2.2 KiB
C++
103 lines
2.2 KiB
C++
|
|
#include <assert.h>
|
|
#include <stdio.h>
|
|
|
|
#include <automata.hpp>
|
|
|
|
#include <print.hpp>
|
|
|
|
#include "find_solution.hpp"
|
|
|
|
static bool is_empty_solution_space(
|
|
unsigned number_of_variables,
|
|
const struct automata* start)
|
|
{
|
|
const struct automata* moving = start;
|
|
|
|
while (moving && number_of_variables--)
|
|
{
|
|
moving = moving->on[0] ?: moving->on[1];
|
|
}
|
|
|
|
return !moving || !moving->is_accepting;
|
|
}
|
|
|
|
refcounted<class solution> find_solution(
|
|
refcounted<problem> problem,
|
|
const struct automata* start)
|
|
{
|
|
refcounted<solution> found_solution = NULL;
|
|
|
|
auto number_of_variables = problem->number_of_variables;
|
|
|
|
// there are three cases:
|
|
// 1. solutions for no inputs
|
|
// 2. solutions for all inputs
|
|
// 3. solutions for some inputs
|
|
|
|
// consider case 1: (solutions for no inputs)
|
|
if (!found_solution)
|
|
{
|
|
if (is_empty_solution_space(number_of_variables, start))
|
|
{
|
|
found_solution = new solution(solution::none);
|
|
}
|
|
}
|
|
|
|
// consider case 2: (solutions for all inputs)
|
|
if (!found_solution)
|
|
{
|
|
// to do this, we'll dis-prove the opposite: that the complement of the
|
|
// solution space is empty.
|
|
|
|
struct automata* complement = automata::complement(start);
|
|
|
|
if (is_empty_solution_space(number_of_variables, complement))
|
|
{
|
|
found_solution = new solution(solution::all);
|
|
}
|
|
|
|
automata::free(complement);
|
|
}
|
|
|
|
// consider case 3: (solutions for some inputs)
|
|
if (!found_solution)
|
|
{
|
|
int* input = new int[number_of_variables];
|
|
|
|
const struct automata* moving = start;
|
|
|
|
for (unsigned i = 0; i < number_of_variables; i++)
|
|
{
|
|
if (moving->on[0])
|
|
{
|
|
input[i] = 0, moving = moving->on[0];
|
|
}
|
|
else
|
|
{
|
|
input[i] = 1, moving = moving->on[1];
|
|
}
|
|
}
|
|
|
|
assert(moving && moving->is_accepting);
|
|
|
|
found_solution = new solution(number_of_variables, input);
|
|
}
|
|
|
|
return found_solution;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|