Skip to content

Commit b2990b7

Browse files
author
Enrico Steffinlongo
committed
Add --dump-smt-formula argument
--dump-smt-formula logs the full SMT formula that is being passed to the solver to a file while also running the solver.
1 parent 8d6f87b commit b2990b7

File tree

4 files changed

+48
-8
lines changed

4 files changed

+48
-8
lines changed

src/goto-checker/solver_factory.cpp

Lines changed: 27 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -331,7 +331,8 @@ solver_factoryt::get_string_refinement()
331331

332332
std::unique_ptr<std::ofstream> open_outfile_and_check(
333333
const std::string &filename,
334-
message_handlert &message_handler)
334+
message_handlert &message_handler,
335+
const std::string &arg_name)
335336
{
336337
if(filename.empty())
337338
return nullptr;
@@ -345,7 +346,7 @@ std::unique_ptr<std::ofstream> open_outfile_and_check(
345346
if(!*out)
346347
{
347348
throw invalid_command_line_argument_exceptiont(
348-
"failed to open file: " + filename, "--outfile");
349+
"failed to open file: " + filename, arg_name);
349350
}
350351

351352
messaget log(message_handler);
@@ -360,22 +361,38 @@ solver_factoryt::get_incremental_smt2(std::string solver_command)
360361
no_beautification();
361362

362363
const std::string outfile_arg = options.get_option("outfile");
364+
const std::string dump_smt_formula = options.get_option("dump-smt-formula");
365+
366+
if(!outfile_arg.empty() && !dump_smt_formula.empty())
367+
{
368+
throw invalid_command_line_argument_exceptiont(
369+
"Argument --outfile is incompatible with --dump-smt-formula. ",
370+
"--outfile");
371+
}
363372

364373
std::unique_ptr<smt_base_solver_processt> solver_process = nullptr;
365374

366375
if(!outfile_arg.empty())
367376
{
368377
bool on_std_out = outfile_arg == "-";
369378
std::unique_ptr<std::ostream> outfile =
370-
on_std_out ? nullptr
371-
: open_outfile_and_check(outfile_arg, message_handler);
379+
on_std_out
380+
? nullptr
381+
: open_outfile_and_check(outfile_arg, message_handler, "--outfile");
372382
solver_process = util_make_unique<smt_incremental_dry_run_solvert>(
373383
message_handler, on_std_out ? std::cout : *outfile, std::move(outfile));
374384
}
375385
else
376386
{
387+
const auto out_filename = options.get_option("dump-smt-formula");
388+
389+
// If no out_filename is provided `open_outfile_and_check` will return
390+
// `nullptr`, and the solver will work normally without any logging.
377391
solver_process = util_make_unique<smt_piped_solver_processt>(
378-
std::move(solver_command), message_handler);
392+
std::move(solver_command),
393+
message_handler,
394+
open_outfile_and_check(
395+
out_filename, message_handler, "--dump-smt-formula"));
379396
}
380397

381398
return util_make_unique<solvert>(
@@ -432,7 +449,7 @@ solver_factoryt::get_smt2(smt2_dect::solvert solver)
432449
}
433450
else
434451
{
435-
auto out = open_outfile_and_check(filename, message_handler);
452+
auto out = open_outfile_and_check(filename, message_handler, "--outfile");
436453

437454
auto smt2_conv = util_make_unique<smt2_convt>(
438455
ns,
@@ -574,6 +591,10 @@ void parse_solver_options(const cmdlinet &cmdline, optionst &options)
574591
if(cmdline.isset("outfile"))
575592
options.set_option("outfile", cmdline.get_value("outfile"));
576593

594+
if(cmdline.isset("dump-smt-formula"))
595+
options.set_option(
596+
"dump-smt-formula", cmdline.get_value("dump-smt-formula"));
597+
577598
if(cmdline.isset("write-solver-stats-to"))
578599
{
579600
options.set_option(

src/goto-checker/solver_factory.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,7 @@ void parse_solver_options(const cmdlinet &cmdline, optionst &options);
113113
"(refine-arrays)" \
114114
"(refine-arithmetic)" \
115115
"(outfile):" \
116+
"(dump-smt-formula):" \
116117
"(write-solver-stats-to):"
117118

118119
#define HELP_SOLVER \
@@ -140,6 +141,8 @@ void parse_solver_options(const cmdlinet &cmdline, optionst &options);
140141
" command to invoke external SMT solver for\n" \
141142
" incremental solving (experimental)\n" \
142143
" --outfile filename output formula to given file\n" \
144+
" --dump-smt-formula filename output smt incremental formula to the\n" \
145+
" given file\n" \
143146
" --write-solver-stats-to json-file\n" \
144147
" collect the solver query complexity\n"
145148

src/solvers/smt2_incremental/smt_solver_process.cpp

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,10 @@
1111

1212
smt_piped_solver_processt::smt_piped_solver_processt(
1313
std::string command_line,
14-
message_handlert &message_handler)
14+
message_handlert &message_handler,
15+
std::unique_ptr<std::ostream> out_stream)
1516
: command_line_description{"\"" + command_line + "\""},
17+
out_stream(std::move(out_stream)),
1618
process{split_string(command_line, ' ', false, true), message_handler},
1719
log{message_handler}
1820
{
@@ -28,6 +30,15 @@ void smt_piped_solver_processt::send(const smt_commandt &smt_command)
2830
const std::string command_string = smt_to_smt2_string(smt_command);
2931
log.debug() << "Sending command to SMT2 solver - " << command_string
3032
<< messaget::eom;
33+
34+
if(out_stream != nullptr)
35+
{
36+
// Using `std::endl` instead of '\n' to also flush the stream as it is a
37+
// debugging functionality, to guarantee a consistent output in case of
38+
// hanging after `(check-sat)`
39+
*out_stream << command_string << std::endl;
40+
}
41+
3142
const auto response = process.send(command_string + "\n");
3243
switch(response)
3344
{

src/solvers/smt2_incremental/smt_solver_process.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,12 @@ class smt_piped_solver_processt : public smt_base_solver_processt
3737
/// The command and arguments for invoking the smt2 solver.
3838
/// \param message_handler:
3939
/// The messaging system to be used for logging purposes.
40+
/// \param out_stream:
41+
/// Pointer to the stream to print the SMT formula. `nullptr` if no output.
4042
smt_piped_solver_processt(
4143
std::string command_line,
42-
message_handlert &message_handler);
44+
message_handlert &message_handler,
45+
std::unique_ptr<std::ostream> out_stream);
4346

4447
const std::string &description() override;
4548

@@ -54,6 +57,8 @@ class smt_piped_solver_processt : public smt_base_solver_processt
5457
protected:
5558
/// The command line used to start the process.
5659
std::string command_line_description;
60+
/// Pointer to the stream to print the SMT formula. `nullptr` if no output.
61+
std::unique_ptr<std::ostream> out_stream;
5762
/// The raw solver sub process.
5863
piped_processt process;
5964
/// For buffering / combining communications from the solver to cbmc.

0 commit comments

Comments
 (0)