|
12 | 12 |
|
13 | 13 | #include <solvers/smt2_incremental/smt_response_validation.h>
|
14 | 14 |
|
| 15 | +#include <util/mp_arith.h> |
| 16 | +#include <util/range.h> |
| 17 | + |
| 18 | +#include <regex> |
| 19 | + |
15 | 20 | template <class smtt>
|
16 | 21 | response_or_errort<smtt>::response_or_errort(smtt smt) : smt{std::move(smt)}
|
17 | 22 | {
|
@@ -201,10 +206,49 @@ static optionalt<smt_termt> valid_smt_bool(const irept &parse_tree)
|
201 | 206 | return {};
|
202 | 207 | }
|
203 | 208 |
|
| 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 | + |
204 | 246 | static response_or_errort<smt_termt> validate_term(const irept &parse_tree)
|
205 | 247 | {
|
206 | 248 | if(const auto smt_bool = valid_smt_bool(parse_tree))
|
207 | 249 | 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}; |
208 | 252 | return response_or_errort<smt_termt>{"Unrecognised SMT term - \"" +
|
209 | 253 | print_parse_tree(parse_tree) + "\"."};
|
210 | 254 | }
|
|
0 commit comments