CBMC
smt_solver_process.cpp
Go to the documentation of this file.
1 // Author: Diffblue Ltd.
2 
4 
8 #include <util/exception_utils.h>
9 #include <util/invariant.h>
10 #include <util/string_utils.h>
11 
13  std::string command_line,
14  message_handlert &message_handler)
15  : command_line_description{"\"" + command_line + "\""},
16  process{split_string(command_line, ' ', false, true), message_handler},
17  log{message_handler}
18 {
19 }
20 
22 {
24 }
25 
27 {
28  const std::string command_string = smt_to_smt2_string(smt_command);
29  log.debug() << "Sending command to SMT2 solver - " << command_string
30  << messaget::eom;
31  const auto response = process.send(command_string + "\n");
32  switch(response)
33  {
35  return;
37  throw analysis_exceptiont{"Sending to SMT solver sub process failed."};
39  throw analysis_exceptiont{"SMT solver sub process is in error state."};
40  }
42 }
43 
45 static void handle_invalid_smt(
46  const std::vector<std::string> &validation_errors,
47  messaget &log)
48 {
49  for(const std::string &message : validation_errors)
50  {
51  log.error() << message << messaget::eom;
52  }
53  throw analysis_exceptiont{"Invalid SMT response received from solver."};
54 }
55 
57  const std::unordered_map<irep_idt, smt_identifier_termt> &identifier_table)
58 {
59  const auto response_text = process.wait_receive();
60  log.debug() << "Solver response - " << response_text << messaget::eom;
61  response_stream << response_text;
62  const auto parse_tree = smt2irep(response_stream, log.get_message_handler());
63  if(!parse_tree)
64  throw deserialization_exceptiont{"Incomplete SMT response."};
65  const auto validation_result =
66  validate_smt_response(*parse_tree, identifier_table);
67  if(const auto validation_errors = validation_result.get_if_error())
68  handle_invalid_smt(*validation_errors, log);
69  return *validation_result.get_if_valid();
70 }
messaget
Class that provides messages with a built-in verbosity 'level'.
Definition: message.h:154
UNREACHABLE
#define UNREACHABLE
This should be used to mark dead code.
Definition: invariant.h:503
exception_utils.h
smt_piped_solver_processt::process
piped_processt process
The raw solver sub process.
Definition: smt_solver_process.h:56
piped_processt::send_responset::FAILED
@ FAILED
string_utils.h
smt2irep
optionalt< irept > smt2irep(std::istream &in, message_handlert &message_handler)
returns an irep for an SMT-LIB2 expression read from a given stream returns {} when EOF is encountere...
Definition: smt2irep.cpp:91
deserialization_exceptiont
Thrown when failing to deserialize a value from some low level format, like JSON or raw bytes.
Definition: exception_utils.h:79
smt_solver_process.h
invariant.h
messaget::eom
static eomt eom
Definition: message.h:297
smt_piped_solver_processt::log
messaget log
For debug printing.
Definition: smt_solver_process.h:60
smt_piped_solver_processt::response_stream
std::stringstream response_stream
For buffering / combining communications from the solver to cbmc.
Definition: smt_solver_process.h:58
smt_piped_solver_processt::send
void send(const smt_commandt &smt_command) override
Converts given SMT2 command to SMT2 string and sends it to the solver process.
Definition: smt_solver_process.cpp:26
smt_response_validation.h
split_string
void split_string(const std::string &s, char delim, std::vector< std::string > &result, bool strip, bool remove_empty)
Definition: string_utils.cpp:39
messaget::error
mstreamt & error() const
Definition: message.h:399
validate_smt_response
response_or_errort< smt_responset > validate_smt_response(const irept &parse_tree, const std::unordered_map< irep_idt, smt_identifier_termt > &identifier_table)
Definition: smt_response_validation.cpp:352
smt_responset
Definition: smt_responses.h:9
handle_invalid_smt
static void handle_invalid_smt(const std::vector< std::string > &validation_errors, messaget &log)
Log messages and throw exception.
Definition: smt_solver_process.cpp:45
message_handlert
Definition: message.h:27
smt_commandt
Definition: smt_commands.h:13
smt_piped_solver_processt::command_line_description
std::string command_line_description
The command line used to start the process.
Definition: smt_solver_process.h:54
smt_to_smt2_string
std::string smt_to_smt2_string(const smt_indext &index)
Definition: smt_to_smt2_string.cpp:53
messaget::get_message_handler
message_handlert & get_message_handler()
Definition: message.h:184
smt_piped_solver_processt::smt_piped_solver_processt
smt_piped_solver_processt(std::string command_line, message_handlert &message_handler)
Definition: smt_solver_process.cpp:12
smt_piped_solver_processt::receive_response
smt_responset receive_response(const std::unordered_map< irep_idt, smt_identifier_termt > &identifier_table) override
Definition: smt_solver_process.cpp:56
piped_processt::send
send_responset send(const std::string &message)
Send a string message (command) to the child process.
Definition: piped_process.cpp:349
smt_piped_solver_processt::description
const std::string & description() override
Definition: smt_solver_process.cpp:21
piped_processt::send_responset::SUCCEEDED
@ SUCCEEDED
piped_processt::wait_receive
std::string wait_receive()
Wait until a string is available and read a string from the child process' output.
Definition: piped_process.cpp:440
messaget::debug
mstreamt & debug() const
Definition: message.h:429
smt_to_smt2_string.h
smt2irep.h
piped_processt::send_responset::ERRORED
@ ERRORED
analysis_exceptiont
Thrown when an unexpected error occurs during the analysis (e.g., when the SAT solver returns an erro...
Definition: exception_utils.h:153