Skip to content

Commit 7cb7ba6

Browse files
committed
Add support for validating get-value responses with bit vectors
1 parent b972b82 commit 7cb7ba6

File tree

2 files changed

+62
-0
lines changed

2 files changed

+62
-0
lines changed

src/solvers/smt2_incremental/smt_response_validation.cpp

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,11 @@
1212

1313
#include <solvers/smt2_incremental/smt_response_validation.h>
1414

15+
#include <util/mp_arith.h>
16+
#include <util/range.h>
17+
18+
#include <regex>
19+
1520
template <class smtt>
1621
response_or_errort<smtt>::response_or_errort(smtt smt) : smt{std::move(smt)}
1722
{
@@ -201,10 +206,49 @@ static optionalt<smt_termt> valid_smt_bool(const irept &parse_tree)
201206
return {};
202207
}
203208

209+
static optionalt<smt_termt> valid_smt_binary(const std::string &text)
210+
{
211+
static const std::regex binary_format{"#b[01]+"};
212+
if(!std::regex_match(text, binary_format))
213+
return {};
214+
const mp_integer value = string2integer({text.begin() + 2, text.end()}, 2);
215+
// Width is number of bit values minus the "#b" prefix.
216+
const std::size_t width = text.size() - 2;
217+
return {smt_bit_vector_constant_termt{value, width}};
218+
}
219+
220+
static optionalt<smt_termt> valid_smt_hex(const std::string &text)
221+
{
222+
static const std::regex hex_format{"#x[0-9A-Za-z]+"};
223+
if(!std::regex_match(text, hex_format))
224+
return {};
225+
const std::string hex{text.begin() + 2, text.end()};
226+
// SMT-LIB 2 allows hex characters to be upper of lower case, but they should
227+
// be upper case for mp_integer.
228+
const mp_integer value = string2integer(make_range(hex).map(::toupper), 16);
229+
const std::size_t width = (text.size() - 2) * 4;
230+
return {smt_bit_vector_constant_termt{value, width}};
231+
}
232+
233+
static optionalt<smt_termt>
234+
valid_smt_bit_vector_constant(const irept &parse_tree)
235+
{
236+
if(!parse_tree.get_sub().empty() || parse_tree.id().empty())
237+
return {};
238+
const auto value_string = id2string(parse_tree.id());
239+
if(const auto smt_binary = valid_smt_binary(value_string))
240+
return *smt_binary;
241+
if(const auto smt_hex = valid_smt_hex(value_string))
242+
return *smt_hex;
243+
return {};
244+
}
245+
204246
static response_or_errort<smt_termt> validate_term(const irept &parse_tree)
205247
{
206248
if(const auto smt_bool = valid_smt_bool(parse_tree))
207249
return response_or_errort<smt_termt>{*smt_bool};
250+
if(const auto bit_vector_constant = valid_smt_bit_vector_constant(parse_tree))
251+
return response_or_errort<smt_termt>{*bit_vector_constant};
208252
return response_or_errort<smt_termt>{"Unrecognised SMT term - \"" +
209253
print_parse_tree(parse_tree) + "\"."};
210254
}

unit/solvers/smt2_incremental/smt_response_validation.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#include <testing-utils/use_catch.h>
55

66
#include <solvers/smt2_incremental/smt_response_validation.h>
7+
#include <util/mp_arith.h>
78

89
// Debug printer for `smt_responset`. This will be used by the catch framework
910
// for printing in the case of failed checks / requirements.
@@ -111,4 +112,21 @@ TEST_CASE("smt get-value response validation", "[core][smt2_incremental]")
111112
smt_identifier_termt{"a", smt_bool_sortt{}},
112113
smt_bool_literal_termt{false}}}});
113114
}
115+
SECTION("Bit vector sorted values.")
116+
{
117+
const response_or_errort<smt_responset> response_255 =
118+
validate_smt_response(*smt2irep("((a #xff))").parsed_output);
119+
CHECK(
120+
*response_255.get_if_valid() ==
121+
smt_get_value_responset{{smt_get_value_responset::valuation_pairt{
122+
smt_identifier_termt{"a", smt_bit_vector_sortt{8}},
123+
smt_bit_vector_constant_termt{255, 8}}}});
124+
const response_or_errort<smt_responset> response_42 =
125+
validate_smt_response(*smt2irep("((a #b00101010))").parsed_output);
126+
CHECK(
127+
*response_42.get_if_valid() ==
128+
smt_get_value_responset{{smt_get_value_responset::valuation_pairt{
129+
smt_identifier_termt{"a", smt_bit_vector_sortt{8}},
130+
smt_bit_vector_constant_termt{42, 8}}}});
131+
}
114132
}

0 commit comments

Comments
 (0)