Skip to content

Commit 67d8c9c

Browse files
Merge pull request #7094 from thomasspriggs/tas/get-value-sort-validation
Add validation messaging for sorts in SMT get-value responses
2 parents 7743751 + 34429a5 commit 67d8c9c

File tree

2 files changed

+56
-26
lines changed

2 files changed

+56
-26
lines changed

src/solvers/smt2_incremental/smt_response_validation.cpp

+42-26
Original file line numberDiff line numberDiff line change
@@ -22,47 +22,48 @@
2222
#include <util/range.h>
2323

2424
#include "smt_array_theory.h"
25+
#include "smt_to_smt2_string.h"
2526

2627
#include <regex>
2728

2829
static response_or_errort<smt_termt> validate_term(
2930
const irept &parse_tree,
3031
const std::unordered_map<irep_idt, smt_identifier_termt> &identifier_table);
3132

32-
// Implementation detail of `collect_messages` below.
33+
// Implementation detail of `collect_error_messages` below.
3334
template <typename argumentt, typename... argumentst>
34-
void collect_messages_impl(
35-
std::vector<std::string> &collected_messages,
35+
void collect_error_messages_impl(
36+
std::vector<std::string> &collected_error_messages,
3637
argumentt &&argument)
3738
{
3839
if(const auto messages = argument.get_if_error())
3940
{
40-
collected_messages.insert(
41-
collected_messages.end(), messages->cbegin(), messages->end());
41+
collected_error_messages.insert(
42+
collected_error_messages.end(), messages->cbegin(), messages->end());
4243
}
4344
}
4445

45-
// Implementation detail of `collect_messages` below.
46+
// Implementation detail of `collect_error_messages` below.
4647
template <typename argumentt, typename... argumentst>
47-
void collect_messages_impl(
48-
std::vector<std::string> &collected_messages,
48+
void collect_error_messages_impl(
49+
std::vector<std::string> &collected_error_messages,
4950
argumentt &&argument,
5051
argumentst &&... arguments)
5152
{
52-
collect_messages_impl(collected_messages, argument);
53-
collect_messages_impl(collected_messages, arguments...);
53+
collect_error_messages_impl(collected_error_messages, argument);
54+
collect_error_messages_impl(collected_error_messages, arguments...);
5455
}
5556

56-
/// Builds a collection of messages composed all messages in the
57+
/// Builds a collection of error messages composed all error messages in the
5758
/// `response_or_errort` typed arguments in \p arguments. This is a templated
5859
/// function in order to handle `response_or_errort` instances which are
5960
/// specialised differently.
6061
template <typename... argumentst>
61-
std::vector<std::string> collect_messages(argumentst &&... arguments)
62+
std::vector<std::string> collect_error_messages(argumentst &&... arguments)
6263
{
63-
std::vector<std::string> collected_messages;
64-
collect_messages_impl(collected_messages, arguments...);
65-
return collected_messages;
64+
std::vector<std::string> collected_error_messages;
65+
collect_error_messages_impl(collected_error_messages, arguments...);
66+
return collected_error_messages;
6667
}
6768

6869
/// \brief Given a class to construct and a set of arguments to its constructor
@@ -85,9 +86,9 @@ template <
8586
typename... argumentst>
8687
response_or_errort<smt_baset> validation_propagating(argumentst &&... arguments)
8788
{
88-
const auto collected_messages = collect_messages(arguments...);
89-
if(!collected_messages.empty())
90-
return response_or_errort<smt_baset>(collected_messages);
89+
const auto collected_error_messages = collect_error_messages(arguments...);
90+
if(!collected_error_messages.empty())
91+
return response_or_errort<smt_baset>(collected_error_messages);
9192
else
9293
{
9394
return response_or_errort<smt_baset>{
@@ -255,9 +256,9 @@ static optionalt<response_or_errort<smt_termt>> try_select_validation(
255256
}
256257
const auto array = validate_term(parse_tree.get_sub()[1], identifier_table);
257258
const auto index = validate_term(parse_tree.get_sub()[2], identifier_table);
258-
const auto messages = collect_messages(array, index);
259-
if(!messages.empty())
260-
return response_or_errort<smt_termt>{messages};
259+
const auto error_messages = collect_error_messages(array, index);
260+
if(!error_messages.empty())
261+
return response_or_errort<smt_termt>{error_messages};
261262
return {smt_array_theoryt::select.validation(
262263
*array.get_if_valid(), *index.get_if_valid())};
263264
}
@@ -288,12 +289,27 @@ validate_valuation_pair(
288289
const irept &pair_parse_tree,
289290
const std::unordered_map<irep_idt, smt_identifier_termt> &identifier_table)
290291
{
292+
using resultt = response_or_errort<smt_get_value_responset::valuation_pairt>;
291293
PRECONDITION(pair_parse_tree.get_sub().size() == 2);
292-
const auto &descriptor = pair_parse_tree.get_sub()[0];
293-
const auto &value = pair_parse_tree.get_sub()[1];
294-
return validation_propagating<smt_get_value_responset::valuation_pairt>(
295-
validate_term(descriptor, identifier_table),
296-
validate_term(value, identifier_table));
294+
const auto descriptor_validation =
295+
validate_term(pair_parse_tree.get_sub()[0], identifier_table);
296+
const auto value_validation =
297+
validate_term(pair_parse_tree.get_sub()[1], identifier_table);
298+
const auto error_messages =
299+
collect_error_messages(descriptor_validation, value_validation);
300+
if(!error_messages.empty())
301+
return resultt{error_messages};
302+
const auto &valid_descriptor = *descriptor_validation.get_if_valid();
303+
const auto &valid_value = *value_validation.get_if_valid();
304+
if(valid_descriptor.get_sort() != valid_value.get_sort())
305+
{
306+
return resultt{
307+
"Mismatched descriptor and value sorts in - " +
308+
print_parse_tree(pair_parse_tree) + "\nDescriptor has sort " +
309+
smt_to_smt2_string(valid_descriptor.get_sort()) + "\nValue has sort " +
310+
smt_to_smt2_string(valid_value.get_sort())};
311+
}
312+
return resultt{{valid_descriptor, valid_value}};
297313
}
298314

299315
/// \returns: A response or error in the case where the parse tree appears to be

unit/solvers/smt2_incremental/smt_response_validation.cpp

+14
Original file line numberDiff line numberDiff line change
@@ -339,5 +339,19 @@ TEST_CASE("smt get-value response validation", "[core][smt2_incremental]")
339339
*empty_pair.get_if_error() ==
340340
std::vector<std::string>{
341341
"Unrecognised SMT term - \"\".", "Unrecognised SMT term - \"\"."});
342+
SECTION("Mismatched descriptor and value sorts")
343+
{
344+
const response_or_errort<smt_responset> mismatched_pair =
345+
validate_smt_response(
346+
*smt2irep("((foo #x2A)))").parsed_output,
347+
table_with_identifiers({{"foo", smt_bool_sortt{}}}));
348+
CHECK(
349+
*mismatched_pair.get_if_error() ==
350+
std::vector<std::string>{"Mismatched descriptor and value sorts in - \n"
351+
"0: foo\n"
352+
"1: #x2A\n"
353+
"Descriptor has sort Bool\n"
354+
"Value has sort (_ BitVec 8)"});
355+
}
342356
}
343357
}

0 commit comments

Comments
 (0)