sat: factor the creation of temporary files

* src/misc/satsolver.hh, src/misc/satsolver.cc: Present
the SAT solver as an object with a stream interface, to
prepare for a better implementation.
* src/tgbaalgos/dtbasat.cc, src/tgbaalgos/dtgbasat.cc:
Adjust to the new interface, removing all the handling
of temporary files.
* src/tgbatest/readsat.cc: Adjust.
This commit is contained in:
Alexandre Duret-Lutz 2013-12-06 18:42:19 +01:00
parent 1853bdd53b
commit 9c98975c19
5 changed files with 110 additions and 168 deletions

View file

@ -18,7 +18,6 @@
// along with this program. If not, see <http://www.gnu.org/licenses/>.
#include <iostream>
#include <fstream>
#include <sstream>
#include "dtgbasat.hh"
#include "reachiter.hh"
@ -29,26 +28,17 @@
#include "ltlast/constant.hh"
#include "stats.hh"
#include "ltlenv/defaultenv.hh"
#include "misc/tmpfile.hh"
#include "misc/satsolver.hh"
#include "isweakscc.hh"
// If the following DEBUG macro is set to 1, the temporary files used
// to communicate with the SAT-solver will be left in the current
// directory. (The files dtgba-sat.cnf and dtgba-sat.out contain the
// input and output for the last successful minimization attempted, or
// for the only failed attempt if the minimization failed.)
// If you set the SPOT_TMPKEEP environment variable the temporary
// file used to communicate with the sat solver will be left in
// the current directory.
//
// Additionally, the CNF file will be output with a comment before
// each clause, and an additional output file (dtgba-sat.dbg) will be
// created with a list of all positive variables in the result and
// their meaning.
//
// Note that the code use unique temporary filenames, so it is safe to
// run several such minimizations in parallel. It only when DEBUG=1
// that some of these files will be renamed to the above hard-coded
// names, possibly causing confusion if multiple minimizations are
// debugged in parallel and in the same directory.
// Additionally, if the following DEBUG macro is set to 1, the CNF
// file will be output with a comment before each clause, and an
// additional output file (dtgba-sat.dbg) will be created with a list
// of all positive variables in the result and their meaning.
#define DEBUG 0
#if DEBUG
@ -851,8 +841,8 @@ namespace spot
}
static tgba_explicit_number*
sat_build(const sat_solution& solution, dict& satdict, const tgba* aut,
bool state_based)
sat_build(const satsolver::solution& solution, dict& satdict,
const tgba* aut, bool state_based)
{
bdd_dict* autdict = aut->get_dict();
tgba_explicit_number* a = new tgba_explicit_number(autdict);
@ -876,7 +866,7 @@ namespace spot
dout << "--- transition variables ---\n";
std::map<int, bdd> state_acc;
std::set<src_cond> seen_trans;
for (sat_solution::const_iterator i = solution.begin();
for (satsolver::solution::const_iterator i = solution.begin();
i != solution.end(); ++i)
{
int v = *i;
@ -950,17 +940,6 @@ namespace spot
return a;
}
static bool
xrename(const char* from, const char* to)
{
if (!rename(from, to))
return false;
std::ostringstream msg;
msg << "cannot rename " << from << " to " << to;
perror(msg.str().c_str());
return true;
}
}
tgba_explicit_number*
@ -970,51 +949,21 @@ namespace spot
trace << "dtgba_sat_synthetize(..., acc = " << target_acc_number
<< ", states = " << target_state_number
<< ", state_based = " << state_based << ")\n";
dict* current = 0;
temporary_file* cnf = 0;
temporary_file* out = 0;
current = new dict(a);
current->cand_size = target_state_number;
current->cand_nacc = target_acc_number;
dict d(a);
d.cand_size = target_state_number;
d.cand_nacc = target_acc_number;
try
{
cnf = create_tmpfile("dtgba-sat-", ".cnf");
std::fstream cnfs(cnf->name(),
std::ios_base::trunc | std::ios_base::out);
cnfs.exceptions(std::ifstream::failbit | std::ifstream::badbit);
dtgba_to_sat(cnfs, a, *current, state_based);
cnfs.close();
}
catch (...)
{
if (DEBUG)
xrename(cnf->name(), "dgtba-sat.cnf");
delete current;
delete cnf;
throw;
}
satsolver solver;
satsolver::solution_pair solution;
out = create_tmpfile("dtgba-sat-", ".out");
satsolver(cnf, out);
sat_solution solution = satsolver_get_solution(out->name());
dtgba_to_sat(solver(), a, d, state_based);
solution = solver.get_solution();
tgba_explicit_number* res = 0;
if (!solution.empty())
res = sat_build(solution, *current, a, state_based);
if (!solution.second.empty())
res = sat_build(solution.second, d, a, state_based);
delete current;
if (DEBUG)
{
xrename(out->name(), "dtgba-sat.out");
xrename(cnf->name(), "dtgba-sat.cnf");
}
delete out;
delete cnf;
trace << "dtgba_sat_synthetize(...) = " << res << "\n";
return res;
}