35
35
#include < java_bytecode/java_types.h>
36
36
#include < util/optional.h>
37
37
38
+ // / Convert exprt to a specific type. Throw bad_cast if conversion
39
+ // / cannot be performed
40
+ // / Generic case doesn't exist, specialize for different types accordingly
41
+ // / TODO: this should go to util
42
+ template <typename T>
43
+ optionalt<T> expr_cast (const exprt&);
44
+
45
+ template <>
46
+ optionalt<mp_integer> expr_cast<mp_integer>(const exprt& expr)
47
+ {
48
+ mp_integer out;
49
+ if (to_integer (expr, out))
50
+ return { };
51
+ return out;
52
+ }
53
+
54
+ template <>
55
+ optionalt<std::size_t > expr_cast<std::size_t >(const exprt& expr)
56
+ {
57
+ if (const auto tmp=expr_cast<mp_integer>(expr))
58
+ {
59
+ if (tmp->is_long () && *tmp >= 0 )
60
+ return tmp->to_long ();
61
+ }
62
+ return { };
63
+ }
64
+
65
+ template <typename T>
66
+ T expr_cast_v (const exprt& expr) {
67
+ const auto maybe=expr_cast<T>(expr);
68
+ INVARIANT (maybe, " Bad conversion" );
69
+ return *maybe;
70
+ }
71
+
38
72
static bool validate (const string_refinementt::infot &info)
39
73
{
40
74
PRECONDITION (info.ns );
@@ -296,33 +330,6 @@ bool string_refinementt::add_axioms_for_string_assigns(
296
330
return true ;
297
331
}
298
332
299
- // / Convert exprt to a specific type. Throw bad_cast if conversion
300
- // / cannot be performed
301
- // / Generic case doesn't exist, specialize for different types accordingly
302
- // / TODO: this should go to util
303
- template <typename T>
304
- optionalt<T> expr_cast (const exprt&);
305
-
306
- template <>
307
- optionalt<mp_integer> expr_cast<mp_integer>(const exprt& expr)
308
- {
309
- mp_integer out;
310
- if (to_integer (expr, out))
311
- return { };
312
- return out;
313
- }
314
-
315
- template <>
316
- optionalt<std::size_t > expr_cast<std::size_t >(const exprt& expr)
317
- {
318
- if (const auto tmp=expr_cast<mp_integer>(expr))
319
- {
320
- if (tmp->is_long () && *tmp >= 0 )
321
- return tmp->to_long ();
322
- }
323
- return { };
324
- }
325
-
326
333
// / If the expression is of type string, then adds constants to the index set to
327
334
// / force the solver to pick concrete values for each character, and fill the
328
335
// / maps `found_length` and `found_content`.
@@ -343,10 +350,9 @@ void string_refinementt::concretize_string(const exprt &expr)
343
350
exprt content=str.content ();
344
351
replace_expr (symbol_resolve, content);
345
352
found_length[content]=length;
346
- const auto string_length=expr_cast<std::size_t >(length);
347
- INVARIANT (string_length, " Bad integer conversion" );
353
+ const auto string_length=expr_cast_v<std::size_t >(length);
348
354
INVARIANT (
349
- * string_length<=generator.max_string_length ,
355
+ string_length<=generator.max_string_length ,
350
356
string_refinement_invariantt (" string length must be less than the max "
351
357
" length" ));
352
358
if (index_set[str.content ()].empty ())
@@ -357,14 +363,11 @@ void string_refinementt::concretize_string(const exprt &expr)
357
363
for (const auto &i : index_set[str.content ()])
358
364
{
359
365
const exprt simple_i=simplify_expr (get (i), ns);
360
- mp_integer mpi_index;
361
- bool conversion_failure=to_integer (simple_i, mpi_index);
362
- if (!conversion_failure && mpi_index>=0 && mpi_index<*string_length)
366
+ if (const auto index =expr_cast<std::size_t >(simple_i))
363
367
{
364
368
const exprt str_i=simplify_expr (str[simple_i], ns);
365
369
const exprt value=simplify_expr (get (str_i), ns);
366
- std::size_t index =mpi_index.to_long ();
367
- map.emplace (index , value);
370
+ map.emplace (*index , value);
368
371
}
369
372
else
370
373
{
@@ -904,10 +907,9 @@ exprt fill_in_array_with_expr(const exprt &expr, std::size_t string_max_length)
904
907
// statements
905
908
const with_exprt with_expr=to_with_expr (it);
906
909
const exprt &then_expr=with_expr.new_value ();
907
- const auto index =expr_cast<std::size_t >(with_expr.where ());
908
- INVARIANT (index , " Bad integer conversion" );
909
- if (*index <string_max_length)
910
- initial_map.emplace (*index , then_expr);
910
+ const auto index =expr_cast_v<std::size_t >(with_expr.where ());
911
+ if (index <string_max_length)
912
+ initial_map.emplace (index , then_expr);
911
913
}
912
914
913
915
array_exprt result (to_array_type (expr.type ()));
@@ -1026,23 +1028,18 @@ static exprt negation_of_not_contains_constraint(
1026
1028
const symbol_exprt &univ_var)
1027
1029
{
1028
1030
// If the for all is vacuously true, the negation is false.
1029
- exprt lbu=axiom.univ_lower_bound ();
1030
- exprt ubu=axiom.univ_upper_bound ();
1031
+ const exprt lbu=axiom.univ_lower_bound ();
1032
+ const exprt ubu=axiom.univ_upper_bound ();
1031
1033
if (lbu.id ()==ID_constant && ubu.id ()==ID_constant)
1032
1034
{
1033
- mp_integer lb_int, ub_int;
1034
- to_integer (to_constant_expr (lbu), lb_int);
1035
- to_integer (to_constant_expr (ubu), ub_int);
1036
- if (ub_int<=lb_int)
1035
+ const auto lb_int=expr_cast<mp_integer>(lbu);
1036
+ const auto ub_int=expr_cast<mp_integer>(ubu);
1037
+ if (!lb_int || !ub_int || *ub_int<=*lb_int)
1037
1038
return false_exprt ();
1038
1039
}
1039
1040
1040
- exprt lbe=axiom.exists_lower_bound ();
1041
- exprt ube=axiom.exists_upper_bound ();
1042
-
1043
- mp_integer lbe_int, ube_int;
1044
- to_integer (to_constant_expr (lbe), lbe_int);
1045
- to_integer (to_constant_expr (ube), ube_int);
1041
+ const auto lbe=expr_cast_v<mp_integer>(axiom.exists_lower_bound ());
1042
+ const auto ube=expr_cast_v<mp_integer>(axiom.exists_upper_bound ());
1046
1043
1047
1044
// If the premise is false, the implication is trivially true, so the
1048
1045
// negation is false.
@@ -1056,7 +1053,7 @@ static exprt negation_of_not_contains_constraint(
1056
1053
// The negated existential becomes an universal, and this is the unrolling of
1057
1054
// that universal quantifier.
1058
1055
std::vector<exprt> conjuncts;
1059
- for (mp_integer i=lbe_int ; i<ube_int ; ++i)
1056
+ for (mp_integer i=lbe ; i<ube ; ++i)
1060
1057
{
1061
1058
const constant_exprt i_exprt=from_integer (i, univ_var.type ());
1062
1059
const equal_exprt equal_chars (
@@ -1085,10 +1082,9 @@ static exprt negation_of_constraint(const string_constraintt &axiom)
1085
1082
exprt ub=axiom.upper_bound ();
1086
1083
if (lb.id ()==ID_constant && ub.id ()==ID_constant)
1087
1084
{
1088
- mp_integer lb_int, ub_int;
1089
- to_integer (to_constant_expr (lb), lb_int);
1090
- to_integer (to_constant_expr (ub), ub_int);
1091
- if (ub_int<=lb_int)
1085
+ const auto lb_int=expr_cast<mp_integer>(lb);
1086
+ const auto ub_int=expr_cast<mp_integer>(ub);
1087
+ if (!lb_int || !ub_int || ub_int<=lb_int)
1092
1088
return false_exprt ();
1093
1089
}
1094
1090
@@ -1512,18 +1508,12 @@ static std::vector<exprt> sub_arrays(const exprt &array_expr)
1512
1508
void string_refinementt::add_to_index_set (const exprt &s, exprt i)
1513
1509
{
1514
1510
simplify (i, ns);
1515
- if (i.id ()== ID_constant)
1511
+ if (i.id ()!= ID_constant || expr_cast< size_t >(i) )
1516
1512
{
1517
- mp_integer mpi;
1518
- to_integer (i, mpi);
1519
- if (mpi<0 )
1520
- return ;
1513
+ for (const auto &sub : sub_arrays (s))
1514
+ if (index_set[sub].insert (i).second )
1515
+ current_index_set[sub].insert (i);
1521
1516
}
1522
-
1523
- std::vector<exprt> subs=sub_arrays (s);
1524
- for (const auto &sub : subs)
1525
- if (index_set[sub].insert (i).second )
1526
- current_index_set[sub].insert (i);
1527
1517
}
1528
1518
1529
1519
void string_refinementt::initial_index_set (const string_constraintt &axiom)
@@ -1707,14 +1697,13 @@ exprt substitute_array_lists(exprt expr, size_t string_max_length)
1707
1697
array_typet arr_type (char_type, infinity_exprt (char_type));
1708
1698
exprt ret_expr=array_of_exprt (from_integer (0 , char_type), arr_type);
1709
1699
1710
- for (size_t i=0 ; i<expr.operands ().size ()/ 2 ; i++ )
1700
+ for (size_t i=0 ; i<expr.operands ().size (); i+= 2 )
1711
1701
{
1712
- const exprt &index =expr.operands ()[i*2 ];
1713
- const exprt &value=expr.operands ()[i*2 +1 ];
1714
- mp_integer index_value;
1715
- bool not_constant=to_integer (index , index_value);
1716
- if (not_constant ||
1717
- (index_value>=0 && index_value<string_max_length))
1702
+ const exprt &index =expr.operands ()[i];
1703
+ const exprt &value=expr.operands ()[i+1 ];
1704
+ const auto index_value=expr_cast<std::size_t >(index );
1705
+ if (!index .is_constant () ||
1706
+ (index_value && *index_value<string_max_length))
1718
1707
ret_expr=with_exprt (ret_expr, index , value);
1719
1708
}
1720
1709
return ret_expr;
0 commit comments