@@ -190,17 +190,6 @@ static bool all_subs_are_pairs(const irept &parse_tree)
190
190
[](const irept &sub) { return sub.get_sub ().size () == 2 ; });
191
191
}
192
192
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
-
204
193
static optionalt<smt_termt> valid_smt_bool (const irept &parse_tree)
205
194
{
206
195
if (!parse_tree.get_sub ().empty ())
@@ -237,9 +226,25 @@ static optionalt<smt_termt> valid_smt_hex(const std::string &text)
237
226
return {smt_bit_vector_constant_termt{value, width}};
238
227
}
239
228
229
+ #include < util/prefix.h>
230
+ #include < util/arith_tools.h>
231
+
240
232
static optionalt<smt_termt>
241
233
valid_smt_bit_vector_constant (const irept &parse_tree)
242
234
{
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
+ }
243
248
if (!parse_tree.get_sub ().empty () || parse_tree.id ().empty ())
244
249
return {};
245
250
const auto value_string = id2string (parse_tree.id ());
@@ -260,14 +265,39 @@ static response_or_errort<smt_termt> validate_term(const irept &parse_tree)
260
265
print_parse_tree (parse_tree) + " \" ." };
261
266
}
262
267
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
+
263
286
static response_or_errort<smt_get_value_responset::valuation_pairt>
264
287
validate_valuation_pair (const irept &pair_parse_tree)
265
288
{
266
289
PRECONDITION (pair_parse_tree.get_sub ().size () == 2 );
267
290
const auto &descriptor = pair_parse_tree.get_sub ()[0 ];
268
291
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 , " " );
269
299
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));
271
301
}
272
302
273
303
// / \returns: A response or error in the case where the parse tree appears to be
0 commit comments