Skip to content

Commit 0fa9a43

Browse files
committed
Add interpretation of SMT check-sat responses
So that CBMC can report something useful rather than just reaching an UNIMPLEMENTED, when solving is complete.
1 parent b94fc17 commit 0fa9a43

File tree

3 files changed

+47
-1
lines changed

3 files changed

+47
-1
lines changed

src/solvers/smt2_incremental/smt2_incremental_decision_procedure.cpp

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,12 @@
55
#include <solvers/smt2_incremental/convert_expr_to_smt.h>
66
#include <solvers/smt2_incremental/smt_commands.h>
77
#include <solvers/smt2_incremental/smt_core_theory.h>
8+
#include <solvers/smt2_incremental/smt_responses.h>
89
#include <solvers/smt2_incremental/smt_solver_process.h>
910
#include <solvers/smt2_incremental/smt_terms.h>
1011
#include <util/expr.h>
1112
#include <util/namespace.h>
13+
#include <util/nodiscard.h>
1214
#include <util/range.h>
1315
#include <util/std_expr.h>
1416
#include <util/string_utils.h>
@@ -196,10 +198,29 @@ void smt2_incremental_decision_proceduret::pop()
196198
UNIMPLEMENTED_FEATURE("`pop`.");
197199
}
198200

201+
NODISCARD
202+
static decision_proceduret::resultt lookup_decision_procedure_result(
203+
const smt_check_sat_response_kindt &response_kind)
204+
{
205+
if(response_kind.cast<smt_sat_responset>())
206+
return decision_proceduret::resultt::D_SATISFIABLE;
207+
if(response_kind.cast<smt_unsat_responset>())
208+
return decision_proceduret::resultt::D_UNSATISFIABLE;
209+
if(response_kind.cast<smt_unknown_responset>())
210+
return decision_proceduret::resultt::D_ERROR;
211+
UNREACHABLE;
212+
}
213+
199214
decision_proceduret::resultt smt2_incremental_decision_proceduret::dec_solve()
200215
{
201216
++number_of_solver_calls;
202217
solver_process->send(smt_check_sat_commandt{});
203218
const smt_responset result = solver_process->receive_response();
219+
if(const auto check_sat_response = result.cast<smt_check_sat_responset>())
220+
{
221+
if(check_sat_response->kind().cast<smt_unknown_responset>())
222+
log.error() << "SMT2 solver returned \"unknown\"" << messaget::eom;
223+
return lookup_decision_procedure_result(check_sat_response->kind());
224+
}
204225
UNIMPLEMENTED_FEATURE("handling solver response.");
205226
}

src/solvers/smt2_incremental/smt_solver_process.cpp

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,10 @@
22

33
#include <solvers/smt2_incremental/smt_solver_process.h>
44

5+
#include <solvers/smt2/smt2irep.h>
6+
#include <solvers/smt2_incremental/smt_response_validation.h>
57
#include <solvers/smt2_incremental/smt_to_smt2_string.h>
8+
#include <util/exception_utils.h>
69
#include <util/invariant.h>
710
#include <util/string_utils.h>
811

@@ -28,9 +31,28 @@ void smt_piped_solver_processt::send(const smt_commandt &smt_command)
2831
process.send(command_string + "\n");
2932
}
3033

34+
/// Log messages and throw exception.
35+
static void handle_invalid_smt(
36+
const std::vector<std::string> &validation_errors,
37+
messaget &log)
38+
{
39+
for(const std::string &message : validation_errors)
40+
{
41+
log.error() << message << messaget::eom;
42+
}
43+
throw analysis_exceptiont{"Invalid SMT response received from solver."};
44+
}
45+
3146
smt_responset smt_piped_solver_processt::receive_response()
3247
{
3348
const auto response_text = process.wait_receive();
3449
log.debug() << "Solver response - " << response_text << messaget::eom;
35-
UNIMPLEMENTED_FEATURE("parsing of solver response.");
50+
response_stream << response_text;
51+
const auto parse_tree = smt2irep(response_stream, log.get_message_handler());
52+
if(!parse_tree)
53+
throw deserialization_exceptiont{"Incomplete SMT response."};
54+
const auto validation_result = validate_smt_response(*parse_tree);
55+
if(const auto validation_errors = validation_result.get_if_error())
56+
handle_invalid_smt(*validation_errors, log);
57+
return *validation_result.get_if_valid();
3658
}

src/solvers/smt2_incremental/smt_solver_process.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ class smt_commandt;
99
#include <util/message.h>
1010
#include <util/piped_process.h>
1111

12+
#include <sstream>
1213
#include <string>
1314

1415
class smt_base_solver_processt
@@ -49,6 +50,8 @@ class smt_piped_solver_processt : public smt_base_solver_processt
4950
std::string command_line_description;
5051
/// The raw solver sub process.
5152
piped_processt process;
53+
/// For buffering / combining communications from the solver to cbmc.
54+
std::stringstream response_stream;
5255
/// For debug printing.
5356
messaget log;
5457
};

0 commit comments

Comments
 (0)