31 const irept &parse_tree,
32 const std::unordered_map<irep_idt, smt_identifier_termt> &identifier_table);
35 template <
typename argumentt,
typename... argumentst>
37 std::vector<std::string> &collected_error_messages,
40 if(
const auto messages = argument.get_if_error())
42 collected_error_messages.insert(
43 collected_error_messages.end(), messages->cbegin(), messages->end());
48 template <
typename argumentt,
typename... argumentst>
50 std::vector<std::string> &collected_error_messages,
52 argumentst &&... arguments)
62 template <
typename... argumentst>
65 std::vector<std::string> collected_error_messages;
67 return collected_error_messages;
85 typename smt_to_constructt,
86 typename smt_baset = smt_to_constructt,
87 typename... argumentst>
91 if(!collected_error_messages.empty())
96 smt_to_constructt{(*arguments.get_if_valid())...}};
108 return parse_tree.
pretty(0, 0);
114 if(!parse_tree.
get_sub().empty())
128 static std::optional<response_or_errort<smt_responset>>
134 if(parse_tree.
get_sub().empty())
136 if(parse_tree.
get_sub().at(0).id() !=
"error")
140 if(parse_tree.
get_sub().size() == 1)
143 {
"Error response is missing the error message."}}}};
145 if(parse_tree.
get_sub().size() > 2)
148 {
"Error response has multiple error messages - \"" +
151 return validation_propagating<smt_error_responset, smt_responset>(
160 [](
const irept &sub) { return sub.get_sub().size() == 2; });
165 static std::optional<smt_termt>
168 if(parse_tree.
get_sub().size() != 3)
170 if(parse_tree.
get_sub().at(0).id() !=
"_")
173 std::smatch match_results;
174 static const std::regex bv_value_regex{R
"(^bv(\d+)$)", std::regex::optimize};
175 if(!std::regex_search(value_string, match_results, bv_value_regex))
178 match_results.size() == 2,
179 "Match results should include digits sub-expression if regex is matched.");
180 const std::string value_digits = match_results[1];
183 const auto bit_width =
194 if(!parse_tree.
get_sub().empty())
196 if(parse_tree.
id() == ID_true)
198 if(parse_tree.
id() == ID_false)
205 static const std::regex binary_format{
"#b[01]+"};
206 if(!std::regex_match(text, binary_format))
210 const std::size_t width = text.size() - 2;
216 static const std::regex hex_format{
"#x[0-9A-Za-z]+"};
217 if(!std::regex_match(text, hex_format))
219 const std::string hex{text.begin() + 2, text.end()};
224 const std::size_t width = (text.size() - 2) * 4;
228 static std::optional<smt_termt>
235 const auto value_string =
id2string(parse_tree.
id());
244 const irept &parse_tree,
245 const std::unordered_map<irep_idt, smt_identifier_termt> &identifier_table)
247 if(parse_tree.
get_sub().empty())
249 if(parse_tree.
get_sub()[0].id() !=
"select")
251 if(parse_tree.
get_sub().size() != 3)
254 {
"\"select\" is expected to have 2 arguments, but " +
261 if(!error_messages.empty())
264 *array.get_if_valid(), *index.get_if_valid())};
268 const irept &parse_tree,
269 const std::unordered_map<irep_idt, smt_identifier_termt> &identifier_table)
275 const auto find_result = identifier_table.find(parse_tree.
id());
276 if(find_result != identifier_table.end())
279 const auto select_validation =
282 return *select_validation;
290 const irept &pair_parse_tree,
291 const std::unordered_map<irep_idt, smt_identifier_termt> &identifier_table)
295 const auto descriptor_validation =
297 const auto value_validation =
299 const auto error_messages =
301 if(!error_messages.empty())
302 return resultt{error_messages};
303 const auto &valid_descriptor = *descriptor_validation.get_if_valid();
304 const auto &valid_value = *value_validation.get_if_valid();
305 if(valid_descriptor.get_sort() != valid_value.get_sort())
308 {
"Mismatched descriptor and value sorts in - " +
324 static std::optional<response_or_errort<smt_responset>>
326 const irept &parse_tree,
327 const std::unordered_map<irep_idt, smt_identifier_termt> &identifier_table)
332 if(parse_tree.
get_sub().empty())
336 std::vector<std::string> error_messages;
337 std::vector<smt_get_value_responset::valuation_pairt> valuation_pairs;
338 for(
const auto &pair : parse_tree.
get_sub())
340 const auto pair_validation_result =
342 if(
const auto error = pair_validation_result.get_if_error())
343 error_messages.insert(error_messages.end(), error->begin(), error->end());
344 if(
const auto valid_pair = pair_validation_result.get_if_valid())
345 valuation_pairs.push_back(*valid_pair);
347 if(!error_messages.empty())
357 const irept &parse_tree,
358 const std::unordered_map<irep_idt, smt_identifier_termt> &identifier_table)
360 if(parse_tree.
id() ==
"sat")
363 if(parse_tree.
id() ==
"unsat")
366 if(parse_tree.
id() ==
"unknown")
370 return *error_response;
371 if(parse_tree.
id() ==
"success")
373 if(parse_tree.
id() ==
"unsupported")
376 const auto get_value_response =
379 return *get_value_response;
382 {
"Invalid SMT response \"" +
id2string(parse_tree.
id()) +
"\""}}};
There are a large number of kinds of tree structured or tree-like data in CPROVER.
std::string pretty(unsigned indent=0, unsigned max_indent=0) const
const irep_idt & id() const
Holds either a valid parsed response or response sub-tree of type.
static const smt_function_application_termt::factoryt< selectt > select
const std::string & id2string(const irep_idt &d)
const mp_integer string2integer(const std::string &n, unsigned base)
resultt
The result of goto verifying.
Ranges: pair of begin and end iterators, which can be initialized from containers,...
ranget< iteratort > make_range(iteratort begin, iteratort end)
static std::optional< response_or_errort< smt_responset > > valid_smt_error_response(const irept &parse_tree)
static std::string print_parse_tree(const irept &parse_tree)
Produces a human-readable representation of the given parse_tree, for use in error messaging.
response_or_errort< smt_baset > validation_propagating(argumentst &&... arguments)
Given a class to construct and a set of arguments to its constructor which may include errors,...
void collect_error_messages_impl(std::vector< std::string > &collected_error_messages, argumentt &&argument)
static std::optional< response_or_errort< smt_responset > > valid_smt_get_value_response(const irept &parse_tree, const std::unordered_map< irep_idt, smt_identifier_termt > &identifier_table)
static response_or_errort< smt_termt > validate_term(const irept &parse_tree, const std::unordered_map< irep_idt, smt_identifier_termt > &identifier_table)
static response_or_errort< smt_get_value_responset::valuation_pairt > validate_valuation_pair(const irept &pair_parse_tree, const std::unordered_map< irep_idt, smt_identifier_termt > &identifier_table)
static std::optional< smt_termt > valid_smt_bit_vector_constant(const irept &parse_tree)
static std::optional< smt_termt > valid_smt_binary(const std::string &text)
static bool all_subs_are_pairs(const irept &parse_tree)
static std::optional< smt_termt > valid_smt_bool(const irept &parse_tree)
static std::optional< smt_termt > valid_smt_hex(const std::string &text)
static std::optional< smt_termt > valid_smt_indexed_bit_vector(const irept &parse_tree)
Checks for valid bit vector constants of the form (_ bv(value) (width)) for example - (_ bv4 64).
response_or_errort< smt_responset > validate_smt_response(const irept &parse_tree, const std::unordered_map< irep_idt, smt_identifier_termt > &identifier_table)
static response_or_errort< irep_idt > validate_string_literal(const irept &parse_tree)
std::vector< std::string > collect_error_messages(argumentst &&... arguments)
Builds a collection of error messages composed all error messages in the response_or_errort typed arg...
static std::optional< response_or_errort< smt_termt > > try_select_validation(const irept &parse_tree, const std::unordered_map< irep_idt, smt_identifier_termt > &identifier_table)
std::string smt_to_smt2_string(const smt_indext &index)
Streaming SMT data structures to a string based output stream.
#define PRECONDITION(CONDITION)
#define INVARIANT(CONDITION, REASON)
This macro uses the wrapper function 'invariant_violated_string'.
std::string to_string(const string_not_contains_constraintt &expr)
Used for debug printing.