Skip to content

Commit 21d4907

Browse files
author
Enrico Steffinlongo
committed
Log SMT formula to file for new incremental solver
1 parent 8b5d37a commit 21d4907

File tree

3 files changed

+119
-14
lines changed

3 files changed

+119
-14
lines changed

src/goto-checker/solver_factory.cpp

+45-13
Original file line numberDiff line numberDiff line change
@@ -329,12 +329,54 @@ solver_factoryt::get_string_refinement()
329329
std::move(decision_procedure), std::move(prop));
330330
}
331331

332+
std::unique_ptr<std::ofstream> open_outfile_and_check(
333+
const std::string &filename,
334+
message_handlert &message_handler)
335+
{
336+
if(filename.empty())
337+
return nullptr;
338+
339+
#ifdef _MSC_VER
340+
auto out = util_make_unique<std::ofstream>(widen(filename));
341+
#else
342+
auto out = util_make_unique<std::ofstream>(filename);
343+
#endif
344+
345+
if(!*out)
346+
{
347+
throw invalid_command_line_argument_exceptiont(
348+
"failed to open file: " + filename, "--outfile");
349+
}
350+
351+
messaget log(message_handler);
352+
log.status() << "Outputting SMTLib formula to file: " << filename
353+
<< messaget::eom;
354+
return out;
355+
}
356+
332357
std::unique_ptr<solver_factoryt::solvert>
333358
solver_factoryt::get_incremental_smt2(std::string solver_command)
334359
{
335360
no_beautification();
336-
auto solver_process = util_make_unique<smt_piped_solver_processt>(
337-
std::move(solver_command), message_handler);
361+
362+
const std::string outfile_arg = options.get_option("outfile");
363+
364+
std::unique_ptr<smt_base_solver_processt> solver_process = nullptr;
365+
366+
if(!outfile_arg.empty())
367+
{
368+
bool on_std_out = outfile_arg == "-";
369+
std::unique_ptr<std::ostream> outfile =
370+
on_std_out ? nullptr
371+
: open_outfile_and_check(outfile_arg, message_handler);
372+
solver_process = util_make_unique<smt_incremental_dry_run_solvert>(
373+
message_handler, on_std_out ? std::cout : *outfile, std::move(outfile));
374+
}
375+
else
376+
{
377+
solver_process = util_make_unique<smt_piped_solver_processt>(
378+
std::move(solver_command), message_handler);
379+
}
338380

339381
return util_make_unique<solvert>(
340382
util_make_unique<smt2_incremental_decision_proceduret>(
@@ -390,17 +432,7 @@ solver_factoryt::get_smt2(smt2_dect::solvert solver)
390432
}
391433
else
392434
{
393-
#ifdef _MSC_VER
394-
auto out = util_make_unique<std::ofstream>(widen(filename));
395-
#else
396-
auto out = util_make_unique<std::ofstream>(filename);
397-
#endif
398-
399-
if(!*out)
400-
{
401-
throw invalid_command_line_argument_exceptiont(
402-
"failed to open file: " + filename, "--outfile");
403-
}
435+
auto out = open_outfile_and_check(filename, message_handler);
404436

405437
auto smt2_conv = util_make_unique<smt2_convt>(
406438
ns,

src/solvers/smt2_incremental/smt_solver_process.cpp

+30
Original file line numberDiff line numberDiff line change
@@ -68,3 +68,33 @@ smt_responset smt_piped_solver_processt::receive_response(
6868
handle_invalid_smt(*validation_errors, log);
6969
return *validation_result.get_if_valid();
7070
}
71+
72+
smt_incremental_dry_run_solvert::smt_incremental_dry_run_solvert(
73+
message_handlert &message_handler,
74+
std::ostream &out_stream,
75+
std::unique_ptr<std::ostream> file_stream)
76+
: file_stream(std::move(file_stream)),
77+
out_stream(out_stream),
78+
log(message_handler)
79+
{
80+
}
81+
82+
const std::string &smt_incremental_dry_run_solvert::description()
83+
{
84+
return desc;
85+
}
86+
87+
void smt_incremental_dry_run_solvert::send(const smt_commandt &smt_command)
88+
{
89+
out_stream << smt_to_smt2_string(smt_command) << '\n';
90+
}
91+
92+
smt_responset smt_incremental_dry_run_solvert::receive_response(
93+
const std::unordered_map<irep_idt, smt_identifier_termt> &identifier_table)
94+
{
95+
// Using `smt_unsat_responset` as response because the decision-procedure will
96+
// terminate anyway (stop-on-fail), it is not reported to the user as for
97+
// `unknown`, and does not trigger a subsequent invocation to get the model
98+
// (as a `smt_sat_responset` answer will trigger).
99+
return smt_check_sat_responset{smt_unsat_responset{}};
100+
}

src/solvers/smt2_incremental/smt_solver_process.h

+44-1
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,12 @@
55

66
class smt_commandt;
77

8-
#include <solvers/smt2_incremental/smt_responses.h>
98
#include <util/message.h>
109
#include <util/piped_process.h>
1110

11+
#include <solvers/smt2_incremental/smt_responses.h>
12+
13+
#include <memory>
1214
#include <sstream>
1315
#include <string>
1416

@@ -60,4 +62,45 @@ class smt_piped_solver_processt : public smt_base_solver_processt
6062
messaget log;
6163
};
6264

65+
/// Class for an incremental SMT solver used in combination with `--outfile`
66+
/// argument where the solver is never run.
67+
class smt_incremental_dry_run_solvert : public smt_base_solver_processt
68+
{
69+
public:
70+
/// \param message_handler:
71+
/// The messaging system to be used for logging purposes.
72+
/// \param out_stream:
73+
/// Reference to the stream to print the SMT formula.
74+
/// \param file_stream:
75+
/// Pointer to the file stream to print the SMT formula into. `nullptr` if
76+
/// output is to `std::cout`.
77+
smt_incremental_dry_run_solvert(
78+
message_handlert &message_handler,
79+
std::ostream &out_stream,
80+
std::unique_ptr<std::ostream> file_stream);
81+
82+
const std::string &description() override;
83+
84+
void send(const smt_commandt &smt_command) override;
85+
86+
/// \note This function returns always a valid unsat response.
87+
smt_responset receive_response(
88+
const std::unordered_map<irep_idt, smt_identifier_termt> &identifier_table)
89+
override;
90+
91+
~smt_incremental_dry_run_solvert() override = default;
92+
93+
protected:
94+
/// Pointer to the file stream to print the SMT formula. `nullptr` if output
95+
/// is to `std::cout`.
96+
std::unique_ptr<std::ostream> file_stream;
97+
/// The output stream reference to print the SMT formula to.
98+
std::ostream &out_stream;
99+
/// For debug printing.
100+
messaget log;
101+
102+
/// Description of the current solver
103+
const std::string desc = "SMT2 incremental dry-run";
104+
};
105+
63106
#endif // CPROVER_SOLVERS_SMT2_INCREMENTAL_SMT_SOLVER_PROCESS_H

0 commit comments

Comments
 (0)