|
17 | 17 |
|
18 | 18 | #include <solvers/smt2_incremental/smt_response_validation.h>
|
19 | 19 |
|
| 20 | +#include <util/mp_arith.h> |
| 21 | +#include <util/range.h> |
| 22 | + |
| 23 | +#include <regex> |
| 24 | + |
20 | 25 | template <class smtt>
|
21 | 26 | response_or_errort<smtt>::response_or_errort(smtt smt) : smt{std::move(smt)}
|
22 | 27 | {
|
@@ -206,10 +211,50 @@ static optionalt<smt_termt> valid_smt_bool(const irept &parse_tree)
|
206 | 211 | return {};
|
207 | 212 | }
|
208 | 213 |
|
| 214 | +static optionalt<smt_termt> valid_smt_binary(const std::string &text) |
| 215 | +{ |
| 216 | + static const std::regex binary_format{"#b[01]+"}; |
| 217 | + if(!std::regex_match(text, binary_format)) |
| 218 | + return {}; |
| 219 | + const mp_integer value = string2integer({text.begin() + 2, text.end()}, 2); |
| 220 | + // Width is number of bit values minus the "#b" prefix. |
| 221 | + const std::size_t width = text.size() - 2; |
| 222 | + return {smt_bit_vector_constant_termt{value, width}}; |
| 223 | +} |
| 224 | + |
| 225 | +static optionalt<smt_termt> valid_smt_hex(const std::string &text) |
| 226 | +{ |
| 227 | + static const std::regex hex_format{"#x[0-9A-Za-z]+"}; |
| 228 | + if(!std::regex_match(text, hex_format)) |
| 229 | + return {}; |
| 230 | + const std::string hex{text.begin() + 2, text.end()}; |
| 231 | + // SMT-LIB 2 allows hex characters to be upper of lower case, but they should |
| 232 | + // be upper case for mp_integer. |
| 233 | + const mp_integer value = |
| 234 | + string2integer(make_range(hex).map<std::function<int(int)>>(toupper), 16); |
| 235 | + const std::size_t width = (text.size() - 2) * 4; |
| 236 | + return {smt_bit_vector_constant_termt{value, width}}; |
| 237 | +} |
| 238 | + |
| 239 | +static optionalt<smt_termt> |
| 240 | +valid_smt_bit_vector_constant(const irept &parse_tree) |
| 241 | +{ |
| 242 | + if(!parse_tree.get_sub().empty() || parse_tree.id().empty()) |
| 243 | + return {}; |
| 244 | + const auto value_string = id2string(parse_tree.id()); |
| 245 | + if(const auto smt_binary = valid_smt_binary(value_string)) |
| 246 | + return *smt_binary; |
| 247 | + if(const auto smt_hex = valid_smt_hex(value_string)) |
| 248 | + return *smt_hex; |
| 249 | + return {}; |
| 250 | +} |
| 251 | + |
209 | 252 | static response_or_errort<smt_termt> validate_term(const irept &parse_tree)
|
210 | 253 | {
|
211 | 254 | if(const auto smt_bool = valid_smt_bool(parse_tree))
|
212 | 255 | return response_or_errort<smt_termt>{*smt_bool};
|
| 256 | + if(const auto bit_vector_constant = valid_smt_bit_vector_constant(parse_tree)) |
| 257 | + return response_or_errort<smt_termt>{*bit_vector_constant}; |
213 | 258 | return response_or_errort<smt_termt>{"Unrecognised SMT term - \"" +
|
214 | 259 | print_parse_tree(parse_tree) + "\"."};
|
215 | 260 | }
|
|
0 commit comments