sat_minimize: improve logs and document Python bindings

* spot/priv/satcommon.cc, spot/priv/satcommon.hh: Make it possible to
set the log file without setting the environment variable.  Adjust
print_log to take the input state and print it as a new column.
* spot/twaalgos/dtbasat.cc, spot/twaalgos/dtwasat.cc: Adjust all
calls to print_log.  Fix log output for incremental approaches.
Prefer purge_unreachable_states() over stats_reachable().  Do
not call scc_filter() on colored automata.
* spot/twaalgos/dtwasat.hh: Document the new "log" option.
* NEWS: Mention the changes.
* tests/python/satmin.ipynb: New file.
* tests/Makefile.am: Add it.
* doc/org/satmin.org, doc/org/tut.org: Link to it.
* doc/org/satmin.org, bin/man/spot-x.x: Adjust description
of CSV files.
* bench/dtgbasat/gen.py, bench/dtgbasat/tabl.pl,
bench/dtgbasat/tabl1.pl, bench/dtgbasat/tabl2.pl,
bench/dtgbasat/tabl3.pl, bench/dtgbasat/tabl4.pl: Adjust for
the new column.
* spot/misc/satsolver.cc, spot/misc/satsolver.hh (stats): Make it
const.
* python/spot/__init__.py (sat_minimize): Add display_log and
return_log options.
* tests/python/ipnbdoctest.py: Adjust to not compare SAT-minimization
logs as they contain timings.
This commit is contained in:
Alexandre Duret-Lutz 2018-03-30 11:31:46 +02:00
parent 5266010889
commit c766f58d5d
21 changed files with 5076 additions and 177 deletions

View file

@ -142,50 +142,63 @@ namespace spot
return buffer.str();
}
static std::string satlog_filename;
void
print_log(timer_map& t, int target_state_number,
twa_graph_ptr& res, satsolver& solver)
set_satlog_filename(const std::string& filename)
{
satlog_filename = filename;
}
void
print_log(timer_map& t,
int input_state_number, int target_state_number,
const twa_graph_ptr& res, const satsolver& solver)
{
// Always copy the environment variable into a static string,
// so that we (1) look it up once, but (2) won't crash if the
// environment is changed.
static std::string log = []()
static std::string envlog = []()
{
auto s = getenv("SPOT_SATLOG");
return s ? s : "";
}();
if (!log.empty())
const std::string log = satlog_filename.empty() ? envlog : satlog_filename;
if (log.empty())
return;
std::ofstream out(log, std::ios_base::ate | std::ios_base::app);
out.exceptions(std::ifstream::failbit | std::ifstream::badbit);
if (out.tellp() == 0)
out <<
("input.states,target.states,reachable.states,edges,transitions,"
"variables,clauses,enc.user,enc.sys,sat.user,sat.sys,automaton\n");
const timer& te = t.timer("encode");
const timer& ts = t.timer("solve");
out << input_state_number << ',' << target_state_number << ',';
if (res)
{
std::fstream out(log,
std::ios_base::app | std::ios_base::out);
out.exceptions(std::ifstream::failbit | std::ifstream::badbit);
const timer& te = t.timer("encode");
const timer& ts = t.timer("solve");
out << target_state_number << ',';
if (res)
{
twa_sub_statistics st = sub_stats_reachable(res);
out << st.states << ',' << st.edges << ',' << st.transitions;
}
else
{
out << ",,";
}
std::pair<int, int> s = solver.stats(); // sat_stats
out << ','
<< s.first << ',' << s.second << ','
<< te.utime() + te.cutime() << ','
<< te.stime() + te.cstime() << ','
<< ts.utime() + ts.cutime() << ','
<< ts.stime() + ts.cstime() << ",\"";
if (res)
{
std::ostringstream f;
print_hoa(f, res, "l");
escape_rfc4180(out, f.str());
}
out << "\"\n";
twa_sub_statistics st = sub_stats_reachable(res);
out << st.states << ',' << st.edges << ',' << st.transitions;
}
else
{
out << ",,";
}
std::pair<int, int> s = solver.stats();
out << ',' << s.first << ',' << s.second << ','
<< te.utime() + te.cutime() << ','
<< te.stime() + te.cstime() << ','
<< ts.utime() + ts.cutime() << ','
<< ts.stime() + ts.cstime() << ',';
if (res)
{
std::ostringstream f;
print_hoa(f, res, "l");
escape_rfc4180(out << '"', f.str()) << '"';
}
out << std::endl;
}
int