Skip to content

Commit 8c8fa40

Browse files
thomasspriggsNlightNFotis
authored andcommitted
QnD add validation of bv constant descriptors
Needs clean-up, formatting and unit tests.
1 parent a329ff8 commit 8c8fa40

File tree

1 file changed

+42
-12
lines changed

1 file changed

+42
-12
lines changed

src/solvers/smt2_incremental/smt_response_validation.cpp

Lines changed: 42 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -190,17 +190,6 @@ static bool all_subs_are_pairs(const irept &parse_tree)
190190
[](const irept &sub) { return sub.get_sub().size() == 2; });
191191
}
192192

193-
static response_or_errort<irep_idt>
194-
validate_smt_identifier(const irept &parse_tree)
195-
{
196-
if(!parse_tree.get_sub().empty() || parse_tree.id().empty())
197-
{
198-
return response_or_errort<irep_idt>(
199-
"Expected identifier, found - \"" + print_parse_tree(parse_tree) + "\".");
200-
}
201-
return response_or_errort<irep_idt>(parse_tree.id());
202-
}
203-
204193
static optionalt<smt_termt> valid_smt_bool(const irept &parse_tree)
205194
{
206195
if(!parse_tree.get_sub().empty())
@@ -237,9 +226,25 @@ static optionalt<smt_termt> valid_smt_hex(const std::string &text)
237226
return {smt_bit_vector_constant_termt{value, width}};
238227
}
239228

229+
#include <util/prefix.h>
230+
#include <util/arith_tools.h>
231+
240232
static optionalt<smt_termt>
241233
valid_smt_bit_vector_constant(const irept &parse_tree)
242234
{
235+
// Match `(_ bv(value) (width))` for example - `(_ bv4 64)`
236+
if(parse_tree.get_sub().size() == 3 &&
237+
parse_tree.get_sub().at(0).id() == "_" &&
238+
parse_tree.get_sub().at(0).get_sub().empty() &&
239+
has_prefix(id2string(parse_tree.get_sub().at(1).id()), "bv"))
240+
{
241+
const auto value_string = id2string(parse_tree.get_sub().at(1).id());
242+
const std::string value_digits{value_string.begin() + 2, value_string.end()};
243+
const auto bit_width_string = id2string(parse_tree.get_sub().at(2).id());
244+
smt_bit_vector_constant_termt term{string2integer(value_string),
245+
numeric_cast_v<std::size_t>(string2integer(bit_width_string))};
246+
return term;
247+
}
243248
if(!parse_tree.get_sub().empty() || parse_tree.id().empty())
244249
return {};
245250
const auto value_string = id2string(parse_tree.id());
@@ -260,14 +265,39 @@ static response_or_errort<smt_termt> validate_term(const irept &parse_tree)
260265
print_parse_tree(parse_tree) + "\"."};
261266
}
262267

268+
static response_or_errort<smt_termt>
269+
validate_smt_descriptor(const irept &parse_tree, const smt_sortt &sort)
270+
{
271+
INVARIANT(parse_tree.get_sub().empty() != parse_tree.id().empty(), "");
272+
if(parse_tree.get_sub().empty() && !parse_tree.id().empty())
273+
{
274+
return response_or_errort<smt_termt>{smt_identifier_termt{parse_tree.id(), sort}};
275+
}
276+
if(!parse_tree.get_sub().empty() && parse_tree.id().empty())
277+
{
278+
auto temp = validate_term(parse_tree);
279+
if(const auto term = temp.get_if_valid())
280+
INVARIANT(term->get_sort() == sort, "");
281+
return temp;
282+
}
283+
UNREACHABLE;
284+
}
285+
263286
static response_or_errort<smt_get_value_responset::valuation_pairt>
264287
validate_valuation_pair(const irept &pair_parse_tree)
265288
{
266289
PRECONDITION(pair_parse_tree.get_sub().size() == 2);
267290
const auto &descriptor = pair_parse_tree.get_sub()[0];
268291
const auto &value = pair_parse_tree.get_sub()[1];
292+
const response_or_errort<smt_termt> value_validation = validate_term(value);
293+
if(const auto value_errors = value_validation.get_if_error())
294+
{
295+
return response_or_errort<smt_get_value_responset::valuation_pairt>{*value_errors};
296+
}
297+
const auto value_term = value_validation.get_if_valid();
298+
INVARIANT(value_term != nullptr, "");
269299
return validation_propagating<smt_get_value_responset::valuation_pairt>(
270-
validate_smt_identifier(descriptor), validate_term(value));
300+
validate_smt_descriptor(descriptor, value_term->get_sort()), validate_term(value));
271301
}
272302

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

0 commit comments

Comments
 (0)