Skip to content

Commit de81183

Browse files
author
Joel Allred
committed
Read string length from array pool
Replace calls to str.length() by calls to array_pool.get_length(str).
1 parent 61a7e45 commit de81183

15 files changed

+229
-154
lines changed

jbmc/unit/solvers/strings/string_constraint_instantiation/instantiate_not_contains.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,8 @@ refined_string_exprt make_refined_string_exprt(
9494
const array_string_exprt &arr,
9595
array_poolt &array_pool)
9696
{
97-
return refined_string_exprt(arr.length(), get_data_pointer(arr));
97+
return refined_string_exprt(
98+
array_pool.get_length(arr), get_data_pointer(arr));
9899
}
99100

100101
/// For a constant `string_exprt`, creates a full index set.

src/solvers/strings/string_builtin_function.cpp

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -207,12 +207,12 @@ string_constraintst string_concat_char_builtin_functiont::constraints(
207207
constraints.universal.push_back([&] {
208208
const symbol_exprt idx =
209209
generator.fresh_symbol("QA_index_concat_char", result.length_type());
210-
const exprt upper_bound = zero_if_negative(input.length());
210+
const exprt upper_bound = zero_if_negative(array_pool.get_length(input));
211211
return string_constraintt(
212212
idx, upper_bound, equal_exprt(input[idx], result[idx]));
213213
}());
214214
constraints.existential.push_back(
215-
equal_exprt(result[input.length()], character));
215+
equal_exprt(result[array_pool.get_length(input)], character));
216216
constraints.existential.push_back(
217217
equal_exprt(return_code, from_integer(0, return_code.type())));
218218
return constraints;
@@ -256,38 +256,43 @@ string_constraintst string_set_char_builtin_functiont::constraints(
256256
constraints.existential.push_back(implies_exprt(
257257
and_exprt(
258258
binary_relation_exprt(from_integer(0, position.type()), ID_le, position),
259-
binary_relation_exprt(position, ID_lt, result.length())),
259+
binary_relation_exprt(position, ID_lt, array_pool.get_length(result))),
260260
equal_exprt(result[position], character)));
261261
constraints.universal.push_back([&] {
262262
const symbol_exprt q =
263263
generator.fresh_symbol("QA_char_set", position.type());
264264
const equal_exprt a3_body(result[q], input[q]);
265265
return string_constraintt(
266-
q, minimum(zero_if_negative(result.length()), position), a3_body);
266+
q,
267+
minimum(zero_if_negative(array_pool.get_length(result)), position),
268+
a3_body);
267269
}());
268270
constraints.universal.push_back([&] {
269271
const symbol_exprt q2 =
270272
generator.fresh_symbol("QA_char_set2", position.type());
271273
const plus_exprt lower_bound(position, from_integer(1, position.type()));
272274
const equal_exprt a4_body(result[q2], input[q2]);
273275
return string_constraintt(
274-
q2, lower_bound, zero_if_negative(result.length()), a4_body);
276+
q2,
277+
lower_bound,
278+
zero_if_negative(array_pool.get_length(result)),
279+
a4_body);
275280
}());
276281
return constraints;
277282
}
278283

279284
exprt string_set_char_builtin_functiont::length_constraint() const
280285
{
281286
const exprt out_of_bounds = or_exprt(
282-
binary_relation_exprt(position, ID_ge, input.length()),
287+
binary_relation_exprt(position, ID_ge, array_pool.get_length(input)),
283288
binary_relation_exprt(
284289
position, ID_lt, from_integer(0, input.length_type())));
285290
const exprt return_value = if_exprt(
286291
out_of_bounds,
287292
from_integer(1, return_code.type()),
288293
from_integer(0, return_code.type()));
289294
return and_exprt(
290-
equal_exprt(result.length(), input.length()),
295+
equal_exprt(array_pool.get_length(result), array_pool.get_length(input)),
291296
equal_exprt(return_code, return_value));
292297
}
293298

@@ -389,7 +394,9 @@ string_constraintst string_to_lower_case_builtin_functiont::constraints(
389394
return if_exprt(is_upper_case(input[idx]), converted, non_converted);
390395
}();
391396
return string_constraintt(
392-
idx, zero_if_negative(result.length()), conditional_convert);
397+
idx,
398+
zero_if_negative(array_pool.get_length(result)),
399+
conditional_convert);
393400
}());
394401
return constraints;
395402
}
@@ -433,7 +440,7 @@ string_constraintst string_to_upper_case_builtin_functiont::constraints(
433440
minus_exprt(input[idx], from_integer(0x20, char_type));
434441
return string_constraintt(
435442
idx,
436-
zero_if_negative(result.length()),
443+
zero_if_negative(array_pool.get_length(result)),
437444
equal_exprt(
438445
result[idx],
439446
if_exprt(is_lower_case(input[idx]), converted, input[idx])));
@@ -599,7 +606,7 @@ exprt string_of_int_builtin_functiont::length_constraint() const
599606

600607
const exprt size_expr_with_sign = if_exprt(
601608
negative_arg, plus_exprt(size_expr, from_integer(1, type)), size_expr);
602-
return equal_exprt(result.length(), size_expr_with_sign);
609+
return equal_exprt(array_pool.get_length(result), size_expr_with_sign);
603610
}
604611

605612
string_builtin_function_with_no_evalt::string_builtin_function_with_no_evalt(

src/solvers/strings/string_builtin_function.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -216,7 +216,7 @@ class string_to_lower_case_builtin_functiont
216216
exprt length_constraint() const override
217217
{
218218
return and_exprt(
219-
equal_exprt(result.length(), input.length()),
219+
equal_exprt(array_pool.get_length(result), array_pool.get_length(input)),
220220
equal_exprt(return_code, from_integer(0, return_code.type())));
221221
};
222222
};
@@ -267,7 +267,7 @@ class string_to_upper_case_builtin_functiont
267267
exprt length_constraint() const override
268268
{
269269
return and_exprt(
270-
equal_exprt(result.length(), input.length()),
270+
equal_exprt(array_pool.get_length(result), array_pool.get_length(input)),
271271
equal_exprt(return_code, from_integer(0, return_code.type())));
272272
};
273273
};

src/solvers/strings/string_constraint_generator_code_points.cpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -43,10 +43,10 @@ std::pair<exprt, string_constraintst> add_axioms_for_code_point(
4343
exprt hex0400 = from_integer(0x0400, type);
4444

4545
binary_relation_exprt small(code_point, ID_lt, hex010000);
46-
implies_exprt a1(small, equal_to(res.length(), 1));
46+
implies_exprt a1(small, equal_to(array_pool.get_length(res), 1));
4747
constraints.existential.push_back(a1);
4848

49-
implies_exprt a2(not_exprt(small), equal_to(res.length(), 2));
49+
implies_exprt a2(not_exprt(small), equal_to(array_pool.get_length(res), 2));
5050
constraints.existential.push_back(a2);
5151

5252
typecast_exprt code_point_as_char(code_point, char_type);
@@ -166,10 +166,10 @@ std::pair<exprt, string_constraintst> add_axioms_for_code_point_before(
166166
array_string_exprt str = get_string_expr(array_pool, args[0]);
167167
string_constraintst constraints;
168168

169-
const exprt &char1 =
170-
str[minus_exprt(args[1], from_integer(2, str.length().type()))];
171-
const exprt &char2 =
172-
str[minus_exprt(args[1], from_integer(1, str.length().type()))];
169+
const exprt &char1 = str[minus_exprt(
170+
args[1], from_integer(2, array_pool.get_length(str).type()))];
171+
const exprt &char2 = str[minus_exprt(
172+
args[1], from_integer(1, array_pool.get_length(str).type()))];
173173
const typecast_exprt char1_as_int(char1, return_type);
174174
const typecast_exprt char2_as_int(char2, return_type);
175175

src/solvers/strings/string_constraint_generator_comparison.cpp

Lines changed: 33 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -46,15 +46,15 @@ std::pair<exprt, string_constraintst> add_axioms_for_equals(
4646
typet index_type = s1.length_type();
4747

4848
// Axiom 1.
49-
constraints.existential.push_back(
50-
implies_exprt(eq, equal_exprt(s1.length(), s2.length())));
49+
constraints.existential.push_back(implies_exprt(
50+
eq, equal_exprt(array_pool.get_length(s1), array_pool.get_length(s2))));
5151

5252
// Axiom 2.
5353
constraints.universal.push_back([&] {
5454
const symbol_exprt qvar = fresh_symbol("QA_equal", index_type);
5555
return string_constraintt(
5656
qvar,
57-
zero_if_negative(s1.length()),
57+
zero_if_negative(array_pool.get_length(s1)),
5858
implies_exprt(eq, equal_exprt(s1[qvar], s2[qvar])));
5959
}());
6060

@@ -63,12 +63,12 @@ std::pair<exprt, string_constraintst> add_axioms_for_equals(
6363
const symbol_exprt witness = fresh_symbol("witness_unequal", index_type);
6464
const exprt zero = from_integer(0, index_type);
6565
const and_exprt bound_witness(
66-
binary_relation_exprt(witness, ID_lt, s1.length()),
66+
binary_relation_exprt(witness, ID_lt, array_pool.get_length(s1)),
6767
binary_relation_exprt(witness, ID_ge, zero));
6868
const and_exprt witnessing(
6969
bound_witness, notequal_exprt(s1[witness], s2[witness]));
7070
const and_exprt diff_length(
71-
notequal_exprt(s1.length(), s2.length()),
71+
notequal_exprt(array_pool.get_length(s1), array_pool.get_length(s2)),
7272
equal_exprt(witness, from_integer(-1, index_type)));
7373
return implies_exprt(not_exprt(eq), or_exprt(diff_length, witnessing));
7474
}());
@@ -147,29 +147,32 @@ std::pair<exprt, string_constraintst> add_axioms_for_equals_ignore_case(
147147
const exprt char_Z = from_integer('Z', char_type);
148148
const typet index_type = s1.length_type();
149149

150-
const implies_exprt a1(eq, equal_exprt(s1.length(), s2.length()));
150+
const implies_exprt a1(
151+
eq, equal_exprt(array_pool.get_length(s1), array_pool.get_length(s2)));
151152
constraints.existential.push_back(a1);
152153

153154
const symbol_exprt qvar = fresh_symbol("QA_equal_ignore_case", index_type);
154155
const exprt constr2 =
155156
character_equals_ignore_case(s1[qvar], s2[qvar], char_a, char_A, char_Z);
156157
const string_constraintt a2(
157-
qvar, zero_if_negative(s1.length()), implies_exprt(eq, constr2));
158+
qvar,
159+
zero_if_negative(array_pool.get_length(s1)),
160+
implies_exprt(eq, constr2));
158161
constraints.universal.push_back(a2);
159162

160163
const symbol_exprt witness =
161164
fresh_symbol("witness_unequal_ignore_case", index_type);
162165
const exprt zero = from_integer(0, witness.type());
163166
const and_exprt bound_witness(
164-
binary_relation_exprt(witness, ID_lt, s1.length()),
167+
binary_relation_exprt(witness, ID_lt, array_pool.get_length(s1)),
165168
binary_relation_exprt(witness, ID_ge, zero));
166169
const exprt witness_eq = character_equals_ignore_case(
167170
s1[witness], s2[witness], char_a, char_A, char_Z);
168171
const not_exprt witness_diff(witness_eq);
169172
const implies_exprt a3(
170173
not_exprt(eq),
171174
or_exprt(
172-
notequal_exprt(s1.length(), s2.length()),
175+
notequal_exprt(array_pool.get_length(s1), array_pool.get_length(s2)),
173176
and_exprt(bound_witness, witness_diff)));
174177
constraints.existential.push_back(a3);
175178

@@ -203,12 +206,14 @@ string_constraint_generatort::add_axioms_for_hash_code(
203206
{
204207
const symbol_exprt i = fresh_symbol("index_hash", index_type);
205208
const equal_exprt c1(it.second, hash);
206-
const notequal_exprt c2(it.first.length(), str.length());
209+
const notequal_exprt c2(
210+
array_pool.get_length(it.first), array_pool.get_length(str));
207211
const and_exprt c3(
208-
equal_exprt(it.first.length(), str.length()),
212+
equal_exprt(array_pool.get_length(it.first), array_pool.get_length(str)),
209213
and_exprt(
210214
notequal_exprt(str[i], it.first[i]),
211-
and_exprt(greater_than(str.length(), i), is_positive(i))));
215+
and_exprt(
216+
greater_than(array_pool.get_length(str), i), is_positive(i))));
212217
hash_constraints.existential.push_back(or_exprt(c1, or_exprt(c2, c3)));
213218
}
214219
return {hash, std::move(hash_constraints)};
@@ -250,13 +255,15 @@ std::pair<exprt, string_constraintst> add_axioms_for_compare_to(
250255
const typet &index_type = s1.length_type();
251256

252257
const equal_exprt res_null(res, from_integer(0, return_type));
253-
const implies_exprt a1(res_null, equal_exprt(s1.length(), s2.length()));
258+
const implies_exprt a1(
259+
res_null,
260+
equal_exprt(array_pool.get_length(s1), array_pool.get_length(s2)));
254261
constraints.existential.push_back(a1);
255262

256263
const symbol_exprt i = fresh_symbol("QA_compare_to", index_type);
257264
const string_constraintt a2(
258265
i,
259-
zero_if_negative(s1.length()),
266+
zero_if_negative(array_pool.get_length(s1)),
260267
implies_exprt(res_null, equal_exprt(s1[i], s2[i])));
261268
constraints.universal.push_back(a2);
262269

@@ -268,20 +275,24 @@ std::pair<exprt, string_constraintst> add_axioms_for_compare_to(
268275
const equal_exprt ret_length_diff(
269276
res,
270277
minus_exprt(
271-
typecast_exprt(s1.length(), return_type),
272-
typecast_exprt(s2.length(), return_type)));
278+
typecast_exprt(array_pool.get_length(s1), return_type),
279+
typecast_exprt(array_pool.get_length(s2), return_type)));
273280
const or_exprt guard1(
274281
and_exprt(
275-
less_than_or_equal_to(s1.length(), s2.length()),
276-
greater_than(s1.length(), x)),
282+
less_than_or_equal_to(
283+
array_pool.get_length(s1), array_pool.get_length(s2)),
284+
greater_than(array_pool.get_length(s1), x)),
277285
and_exprt(
278-
greater_or_equal_to(s1.length(), s2.length()),
279-
greater_than(s2.length(), x)));
286+
greater_or_equal_to(array_pool.get_length(s1), array_pool.get_length(s2)),
287+
greater_than(array_pool.get_length(s2), x)));
280288
const and_exprt cond1(ret_char_diff, guard1);
281289
const or_exprt guard2(
282-
and_exprt(greater_than(s2.length(), s1.length()), equal_to(s1.length(), x)),
283290
and_exprt(
284-
greater_than(s1.length(), s2.length()), equal_to(s2.length(), x)));
291+
greater_than(array_pool.get_length(s2), array_pool.get_length(s1)),
292+
equal_to(array_pool.get_length(s1), x)),
293+
and_exprt(
294+
greater_than(array_pool.get_length(s1), array_pool.get_length(s2)),
295+
equal_to(array_pool.get_length(s2), x)));
285296
const and_exprt cond2(ret_length_diff, guard2);
286297

287298
const implies_exprt a3(

src/solvers/strings/string_constraint_generator_concat.cpp

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,8 @@ std::pair<exprt, string_constraintst> add_axioms_for_concat_substr(
4848
string_constraintst constraints;
4949
const typet &index_type = start_index.type();
5050
const exprt start1 = maximum(start_index, from_integer(0, index_type));
51-
const exprt end1 = maximum(minimum(end_index, s2.length()), start1);
51+
const exprt end1 =
52+
maximum(minimum(end_index, array_pool.get_length(s2)), start1);
5253

5354
// Axiom 1.
5455
constraints.existential.push_back(length_constraint_for_concat_substr(
@@ -58,16 +59,20 @@ std::pair<exprt, string_constraintst> add_axioms_for_concat_substr(
5859
constraints.universal.push_back([&] {
5960
const symbol_exprt idx = fresh_symbol("QA_index_concat", res.length_type());
6061
return string_constraintt(
61-
idx, zero_if_negative(s1.length()), equal_exprt(s1[idx], res[idx]));
62+
idx,
63+
zero_if_negative(array_pool.get_length(s1)),
64+
equal_exprt(s1[idx], res[idx]));
6265
}());
6366

6467
// Axiom 3.
6568
constraints.universal.push_back([&] {
6669
const symbol_exprt idx2 =
6770
fresh_symbol("QA_index_concat2", res.length_type());
6871
const equal_exprt res_eq(
69-
res[plus_exprt(idx2, s1.length())], s2[plus_exprt(start1, idx2)]);
70-
const minus_exprt upper_bound(res.length(), s1.length());
72+
res[plus_exprt(idx2, array_pool.get_length(s1))],
73+
s2[plus_exprt(start1, idx2)]);
74+
const minus_exprt upper_bound(
75+
array_pool.get_length(res), array_pool.get_length(s1));
7176
return string_constraintt(idx2, zero_if_negative(upper_bound), res_eq);
7277
}());
7378

@@ -89,11 +94,13 @@ exprt length_constraint_for_concat_substr(
8994
{
9095
PRECONDITION(res.length_type().id() == ID_signedbv);
9196
const exprt start1 = maximum(start, from_integer(0, start.type()));
92-
const exprt end1 = maximum(minimum(end, s2.length()), start1);
93-
const plus_exprt res_length(s1.length(), minus_exprt(end1, start1));
97+
const exprt end1 = maximum(minimum(end, array_pool.get_length(s2)), start1);
98+
const plus_exprt res_length(
99+
array_pool.get_length(s1), minus_exprt(end1, start1));
94100
const exprt overflow = sum_overflows(res_length);
95101
const exprt max_int = to_signedbv_type(res.length_type()).largest_expr();
96-
return equal_exprt(res.length(), if_exprt(overflow, max_int, res_length));
102+
return equal_exprt(
103+
array_pool.get_length(res), if_exprt(overflow, max_int, res_length));
97104
}
98105

99106
/// Add axioms enforcing that the length of `res` is that of the concatenation
@@ -104,7 +111,9 @@ exprt length_constraint_for_concat(
104111
const array_string_exprt &s2,
105112
array_poolt &array_pool)
106113
{
107-
return equal_exprt(res.length(), plus_exprt(s1.length(), s2.length()));
114+
return equal_exprt(
115+
array_pool.get_length(res),
116+
plus_exprt(array_pool.get_length(s1), array_pool.get_length(s2)));
108117
}
109118

110119
/// Add axioms enforcing that the length of `res` is that of the concatenation
@@ -115,7 +124,8 @@ exprt length_constraint_for_concat_char(
115124
array_poolt &array_pool)
116125
{
117126
return equal_exprt(
118-
res.length(), plus_exprt(s1.length(), from_integer(1, s1.length_type())));
127+
array_pool.get_length(res),
128+
plus_exprt(array_pool.get_length(s1), from_integer(1, s1.length_type())));
119129
}
120130

121131
/// Add axioms enforcing that `res` is equal to the concatenation of `s1` and

src/solvers/strings/string_constraint_generator_constants.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ std::pair<exprt, string_constraintst> add_axioms_for_constant(
2828
const exprt &guard)
2929
{
3030
string_constraintst constraints;
31-
const typet &index_type = res.length().type();
31+
const typet index_type = array_pool.get_length(res).type();
3232
const typet &char_type = res.content().type().subtype();
3333
std::string c_str = id2string(sval);
3434
std::wstring str;
@@ -53,7 +53,7 @@ std::pair<exprt, string_constraintst> add_axioms_for_constant(
5353
const exprt s_length = from_integer(str.size(), index_type);
5454

5555
constraints.existential.push_back(
56-
implies_exprt(guard, equal_exprt(res.length(), s_length)));
56+
implies_exprt(guard, equal_exprt(array_pool.get_length(res), s_length)));
5757
return {from_integer(0, get_return_code_type()), std::move(constraints)};
5858
}
5959

0 commit comments

Comments
 (0)