Skip to content

Commit ac2a3c3

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 52fdbe3 commit ac2a3c3

15 files changed

+224
-151
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: 28 additions & 19 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

@@ -250,13 +253,15 @@ std::pair<exprt, string_constraintst> add_axioms_for_compare_to(
250253
const typet &index_type = s1.length_type();
251254

252255
const equal_exprt res_null(res, from_integer(0, return_type));
253-
const implies_exprt a1(res_null, equal_exprt(s1.length(), s2.length()));
256+
const implies_exprt a1(
257+
res_null,
258+
equal_exprt(array_pool.get_length(s1), array_pool.get_length(s2)));
254259
constraints.existential.push_back(a1);
255260

256261
const symbol_exprt i = fresh_symbol("QA_compare_to", index_type);
257262
const string_constraintt a2(
258263
i,
259-
zero_if_negative(s1.length()),
264+
zero_if_negative(array_pool.get_length(s1)),
260265
implies_exprt(res_null, equal_exprt(s1[i], s2[i])));
261266
constraints.universal.push_back(a2);
262267

@@ -268,20 +273,24 @@ std::pair<exprt, string_constraintst> add_axioms_for_compare_to(
268273
const equal_exprt ret_length_diff(
269274
res,
270275
minus_exprt(
271-
typecast_exprt(s1.length(), return_type),
272-
typecast_exprt(s2.length(), return_type)));
276+
typecast_exprt(array_pool.get_length(s1), return_type),
277+
typecast_exprt(array_pool.get_length(s2), return_type)));
273278
const or_exprt guard1(
274279
and_exprt(
275-
less_than_or_equal_to(s1.length(), s2.length()),
276-
greater_than(s1.length(), x)),
280+
less_than_or_equal_to(
281+
array_pool.get_length(s1), array_pool.get_length(s2)),
282+
greater_than(array_pool.get_length(s1), x)),
277283
and_exprt(
278-
greater_or_equal_to(s1.length(), s2.length()),
279-
greater_than(s2.length(), x)));
284+
greater_or_equal_to(array_pool.get_length(s1), array_pool.get_length(s2)),
285+
greater_than(array_pool.get_length(s2), x)));
280286
const and_exprt cond1(ret_char_diff, guard1);
281287
const or_exprt guard2(
282-
and_exprt(greater_than(s2.length(), s1.length()), equal_to(s1.length(), x)),
283288
and_exprt(
284-
greater_than(s1.length(), s2.length()), equal_to(s2.length(), x)));
289+
greater_than(array_pool.get_length(s2), array_pool.get_length(s1)),
290+
equal_to(array_pool.get_length(s1), x)),
291+
and_exprt(
292+
greater_than(array_pool.get_length(s1), array_pool.get_length(s2)),
293+
equal_to(array_pool.get_length(s2), x)));
285294
const and_exprt cond2(ret_length_diff, guard2);
286295

287296
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

src/solvers/strings/string_constraint_generator_float.cpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -281,7 +281,8 @@ std::pair<exprt, string_constraintst> add_axioms_for_fractional_part(
281281
// a3 : int_expr = sum_j 10^j (j < |res| ? res[j] - '0' : 0)
282282

283283
const and_exprt a1(
284-
greater_than(res.length(), 1), less_than_or_equal_to(res.length(), max));
284+
greater_than(array_pool.get_length(res), 1),
285+
less_than_or_equal_to(array_pool.get_length(res), max));
285286
constraints.existential.push_back(a1);
286287

287288
equal_exprt starts_with_dot(res[0], from_integer('.', char_type));
@@ -294,7 +295,7 @@ std::pair<exprt, string_constraintst> add_axioms_for_fractional_part(
294295
{
295296
// after_end is |res| <= j
296297
binary_relation_exprt after_end(
297-
res.length(), ID_le, from_integer(j, res.length_type()));
298+
array_pool.get_length(res), ID_le, from_integer(j, res.length_type()));
298299
mult_exprt ten_sum(sum, ten);
299300

300301
// sum = 10 * sum + after_end ? 0 : (res[j]-'0')
@@ -313,7 +314,8 @@ std::pair<exprt, string_constraintst> add_axioms_for_fractional_part(
313314
if(j > 1)
314315
{
315316
not_exprt no_trailing_zero(and_exprt(
316-
equal_exprt(res.length(), from_integer(j + 1, res.length_type())),
317+
equal_exprt(
318+
array_pool.get_length(res), from_integer(j + 1, res.length_type())),
317319
equal_exprt(res[j], zero_char)));
318320
digit_constraints.push_back(no_trailing_zero);
319321
}

0 commit comments

Comments
 (0)