35
35
#include < java_bytecode/java_types.h>
36
36
#include < util/optional.h>
37
37
38
+ static exprt substitute_array_with_expr (const exprt &expr, const exprt &index);
38
39
static exprt instantiate (
39
40
const string_constraintt &axiom, const exprt &str, const exprt &val);
41
+ static bool is_char_array (const namespacet &ns, const typet &type);
42
+ exprt substitute_array_lists (exprt expr, size_t string_max_length);
43
+ exprt concretize_arrays_in_expression (
44
+ exprt expr, std::size_t string_max_length);
45
+
40
46
exprt simplify_sum (const exprt &f);
41
47
42
48
// / Convert exprt to a specific type. Throw bad_cast if conversion
@@ -83,6 +89,37 @@ T expr_cast_v(const exprt& expr) {
83
89
return *maybe;
84
90
}
85
91
92
+ // / Convert index-value map to a vector of values. If a value for an
93
+ // / index is not defined, set it to the value referenced by the next higher
94
+ // / index. The length of the resulting vector is the key of the map's
95
+ // / last element + 1
96
+ // / \param index_value: map containing values of specific vector cells
97
+ // / \return Vector containing values as described in the map
98
+ template <typename T>
99
+ static std::vector<T> fill_in_map_as_vector (
100
+ const std::map<std::size_t , T> &index_value)
101
+ {
102
+ std::vector<T> result;
103
+ if (!index_value.empty ())
104
+ {
105
+ result.resize (index_value.rbegin ()->first +1 );
106
+ for (auto it=index_value.rbegin (); it!=index_value.rend (); ++it)
107
+ {
108
+ const std::size_t index=it->first ;
109
+ const T value=it->second ;
110
+ const auto next=std::next (it);
111
+ const std::size_t leftmost_index_to_pad=
112
+ next!=index_value.rend ()
113
+ ? next->first +1
114
+ : 0 ;
115
+ for (std::size_t j=leftmost_index_to_pad; j<=index; j++)
116
+ result[j]=value;
117
+ }
118
+ }
119
+ return result;
120
+ }
121
+
122
+
86
123
static bool validate (const string_refinementt::infot &info)
87
124
{
88
125
PRECONDITION (info.ns );
@@ -263,13 +300,14 @@ void string_refinementt::set_char_array_equality(
263
300
// / remove functions applications and create the necessary axioms
264
301
// / \par parameters: an expression containing function applications
265
302
// / \return an expression containing no function application
266
- exprt string_refinementt::substitute_function_applications (exprt expr)
303
+ exprt substitute_function_applications (
304
+ string_constraint_generatort& generator, exprt expr)
267
305
{
268
306
for (size_t i=0 ; i<expr.operands ().size (); ++i)
269
307
{
270
308
// TODO: only copy when necessary
271
309
exprt op (expr.operands ()[i]);
272
- expr.operands ()[i]=substitute_function_applications (op);
310
+ expr.operands ()[i]=substitute_function_applications (generator, op);
273
311
}
274
312
275
313
if (expr.id ()==ID_function_application)
@@ -286,10 +324,10 @@ exprt string_refinementt::substitute_function_applications(exprt expr)
286
324
// / TODO: this is only for java char array and does not work for other languages
287
325
// / \param type: a type
288
326
// / \return true if the given type is an array of java characters
289
- bool string_refinementt:: is_char_array (const typet &type) const
327
+ static bool is_char_array (const namespacet &ns, const typet &type)
290
328
{
291
329
if (type.id ()==ID_symbol)
292
- return is_char_array (ns.follow (type));
330
+ return is_char_array (ns, ns .follow (type));
293
331
294
332
return (type.id ()==ID_array && type.subtype ()==java_char_type ());
295
333
}
@@ -302,7 +340,7 @@ bool string_refinementt::is_char_array(const typet &type) const
302
340
bool string_refinementt::add_axioms_for_string_assigns (
303
341
const exprt &lhs, const exprt &rhs)
304
342
{
305
- if (is_char_array (rhs.type ()))
343
+ if (is_char_array (ns, rhs.type ()))
306
344
{
307
345
set_char_array_equality (lhs, rhs);
308
346
if (rhs.id () == ID_symbol || rhs.id () == ID_array)
@@ -444,10 +482,10 @@ void string_refinementt::set_to(const exprt &expr, bool value)
444
482
const exprt &rhs=eq_expr.rhs ();
445
483
446
484
// The assignment of a string equality to false is not supported.
447
- PRECONDITION (value || !is_char_array (rhs.type ()));
485
+ PRECONDITION (value || !is_char_array (ns, rhs.type ()));
448
486
PRECONDITION (value || !is_refined_string_type (rhs.type ()));
449
487
450
- PRECONDITION (lhs.id ()==ID_symbol || !is_char_array (rhs.type ()));
488
+ PRECONDITION (lhs.id ()==ID_symbol || !is_char_array (ns, rhs.type ()));
451
489
PRECONDITION (lhs.id ()==ID_symbol || !is_refined_string_type (rhs.type ()));
452
490
453
491
// If lhs is not a symbol, let supert::set_to() handle it.
@@ -470,7 +508,7 @@ void string_refinementt::set_to(const exprt &expr, bool value)
470
508
debug () << " (sr::set_to) " << from_expr (ns, " " , lhs)
471
509
<< " = " << from_expr (ns, " " , rhs) << eom;
472
510
473
- const exprt subst_rhs=substitute_function_applications (rhs);
511
+ const exprt subst_rhs=substitute_function_applications (generator, rhs);
474
512
if (lhs.type ()!=subst_rhs.type ())
475
513
{
476
514
if (lhs.type ().id ()!=ID_array ||
@@ -832,7 +870,7 @@ void string_refinementt::debug_model()
832
870
else
833
871
{
834
872
INVARIANT (
835
- is_char_array (it.second .type ()),
873
+ is_char_array (ns, it.second .type ()),
836
874
string_refinement_invariantt (" symbol_resolve should only map to "
837
875
" refined_strings or to char_arrays, and refined_strings are already "
838
876
" handled" ));
@@ -868,8 +906,7 @@ void string_refinementt::debug_model()
868
906
// / expression
869
907
// / \param index: An index with which to build the equality condition
870
908
// / \return An expression containing no 'with' expression
871
- exprt string_refinementt::substitute_array_with_expr (
872
- const exprt &expr, const exprt &index) const
909
+ static exprt substitute_array_with_expr (const exprt &expr, const exprt &index)
873
910
{
874
911
if (expr.id ()==ID_with)
875
912
{
@@ -941,7 +978,7 @@ exprt fill_in_array_with_expr(const exprt &expr, std::size_t string_max_length)
941
978
// / `arr2 := {34}`, the constructed expression will be: `g1 ? 12 : 34`
942
979
// / \param expr: an expression containing array accesses
943
980
// / \return an expression containing no array access
944
- void string_refinementt:: substitute_array_access (exprt &expr) const
981
+ static void substitute_array_access (exprt &expr)
945
982
{
946
983
for (auto &op : expr.operands ())
947
984
substitute_array_access (op);
@@ -1732,7 +1769,7 @@ exprt string_refinementt::get(const exprt &expr) const
1732
1769
{
1733
1770
exprt ecopy (expr);
1734
1771
replace_expr (symbol_resolve, ecopy);
1735
- if (is_char_array (ecopy.type ()))
1772
+ if (is_char_array (ns, ecopy.type ()))
1736
1773
{
1737
1774
auto it_content=found_content.find (ecopy);
1738
1775
if (it_content!=found_content.end ())
0 commit comments