satmin: cleanup interfaces and minimization loops

* src/tgbaalgos/dtbasat.cc, src/tgbaalgos/dtbasat.hh:
(dtba_sat_minimize): Split into...
(dtba_sat_synthetize, dtba_sat_minimize): These.
(dtba_sat_minimize_dichotomy): New function.
* src/tgbaalgos/dtgbasat.cc, src/tgbaalgos/dtgbasat.hh
(dtgba_sat_minimize, dtgba_sat_synthetize): Likewise.
* src/tgbatest/ltl2tgba.cc: Adjust to new interface.
* src/tgbaalgos/postproc.cc, src/tgbaalgos/postproc.hh:
Cleanup option processing for SAT options.
* src/tgbatest/satmin.test: Adjust.
* src/bin/spot-x.cc, src/bin/man/spot-x.x, NEWS: Document.
This commit is contained in:
Alexandre Duret-Lutz 2013-08-22 15:49:30 +02:00
parent b09ef5bea9
commit fdb157bf94
11 changed files with 393 additions and 222 deletions

View file

@ -52,16 +52,16 @@
#define DEBUG 0
#if DEBUG
#define dout out << "c "
#define trace std::cerr
#else
#define dout while (0) out
#define dout while (0) std::cout
#define trace dout
#endif
namespace spot
{
namespace
{
static bdd_dict* debug_dict = 0;
struct transition
@ -477,9 +477,6 @@ namespace spot
sm.build_map();
bdd ap = sm.aprec_set_of(sm.initial());
#if DEBUG
debug_dict = ref->get_dict();
#endif
// Number all the SAT variable we may need.
{
@ -488,6 +485,12 @@ namespace spot
ref_size = f.size();
}
#if DEBUG
debug_dict = ref->get_dict();
dout << "ref_size: " << ref_size << "\n";
dout << "cand_size: " << d.cand_size << "\n";
#endif
// empty automaton is impossible
if (d.cand_size == 0)
{
@ -937,87 +940,96 @@ namespace spot
}
tgba_explicit_number*
dtgba_sat_minimize(const tgba* a, unsigned cand_nacc,
int target_state_number, bool state_based)
dtgba_sat_synthetize(const tgba* a, unsigned target_acc_number,
int target_state_number, bool state_based)
{
int ref_states =
target_state_number == -1
? stats_reachable(a).states - 1
: target_state_number;
std::string current_solution;
std::string last_solution;
dict* last = 0;
trace << "dtgba_sat_synthetize(..., acc = " << target_acc_number
<< ", states = " << target_state_number
<< ", state_based = " << state_based << ")\n";
std::string solution;
dict* current = 0;
temporary_file* cnf = 0;
temporary_file* out = 0;
do
{
if (DEBUG && current)
{
xrename(out->name(), "dtgba-sat.out");
xrename(cnf->name(), "dtgba-sat.cnf");
}
delete out;
delete cnf;
std::swap(current_solution, last_solution);
delete last;
last = current;
current = new dict(a);
current->cand_size = ref_states--;
current->cand_nacc = cand_nacc;
current = new dict(a);
current->cand_size = target_state_number;
current->cand_nacc = target_acc_number;
cnf = create_tmpfile("dtgba-sat-", ".cnf");
cnf = create_tmpfile("dtgba-sat-", ".cnf");
std::fstream cnfs(cnf->name(),
std::ios_base::trunc | std::ios_base::out);
dtgba_to_sat(cnfs, a, *current, state_based);
cnfs.close();
std::fstream cnfs(cnf->name(),
std::ios_base::trunc | std::ios_base::out);
dtgba_to_sat(cnfs, a, *current, state_based);
cnfs.close();
out = create_tmpfile("dtgba-sat-", ".out");
satsolver(cnf, out);
out = create_tmpfile("dtgba-sat-", ".out");
satsolver(cnf, out);
current_solution = get_solution(out->name());
}
while (target_state_number == -1 && !current_solution.empty());
solution = get_solution(out->name());
if (target_state_number != -1)
{
std::swap(current_solution, last_solution);
if (last_solution.empty())
{
last = 0;
delete current;
}
else
{
last = current;
}
}
else
{
delete current;
}
tgba_explicit_number* res = 0;
if (!solution.empty())
res = sat_build(solution, *current, a, state_based);
tgba_explicit_number* res;
if (last == 0)
delete current;
if (DEBUG)
{
res = 0;
if (DEBUG)
{
xrename(out->name(), "dtgba-sat.out");
xrename(cnf->name(), "dtgba-sat.cnf");
}
}
else
{
res = sat_build(last_solution, *last, a, state_based);
delete last;
xrename(out->name(), "dtgba-sat.out");
xrename(cnf->name(), "dtgba-sat.cnf");
}
delete out;
delete cnf;
trace << "dtgba_sat_synthetize(...) = " << res << "\n";
return res;
}
tgba_explicit_number*
dtgba_sat_minimize(const tgba* a, unsigned target_acc_number,
bool state_based)
{
int n_states = stats_reachable(a).states;
tgba_explicit_number* prev = 0;
for (;;)
{
tgba_explicit_number* next =
dtgba_sat_synthetize(prev ? prev : a, target_acc_number,
--n_states, state_based);
if (next == 0)
break;
delete prev;
prev = next;
}
return prev;
}
tgba_explicit_number*
dtgba_sat_minimize_dichotomy(const tgba* a, unsigned target_acc_number,
bool state_based)
{
int max_states = stats_reachable(a).states - 1;
int min_states = 1;
tgba_explicit_number* prev = 0;
while (min_states <= max_states)
{
int target = (max_states + min_states) / 2;
tgba_explicit_number* next =
dtgba_sat_synthetize(prev ? prev : a, target_acc_number, target,
state_based);
if (next == 0)
{
min_states = target + 1;
}
else
{
delete prev;
prev = next;
max_states = target - 1;
}
}
return prev;
}
}