@@ -209,16 +209,17 @@ string_exprt string_constraint_generatort::add_axioms_from_bool(
209
209
210
210
// / add axioms to say the string corresponds to the result of String.valueOf(I)
211
211
// / or String.valueOf(J) java functions applied on the integer expression
212
- // / \par parameters : a signed integer expression, and a maximal size for the
213
- // / string
214
- // / representation
212
+ // / \param i : a signed integer expression
213
+ // / \param max_size: a maximal size for the string representation
214
+ // / \param ref_type: type for refined strings
215
215
// / \return a string expression
216
216
string_exprt string_constraint_generatort::add_axioms_from_int (
217
217
const exprt &i, size_t max_size, const refined_string_typet &ref_type)
218
218
{
219
+ PRECONDITION (i.type ().id ()==ID_signedbv);
220
+ PRECONDITION (max_size<std::numeric_limits<size_t >::max ());
219
221
string_exprt res=fresh_string (ref_type);
220
222
const typet &type=i.type ();
221
- assert (type.id ()==ID_signedbv);
222
223
exprt ten=from_integer (10 , type);
223
224
const typet &char_type=ref_type.get_char_type ();
224
225
const typet &index_type=ref_type.get_index_type ();
@@ -262,12 +263,20 @@ string_exprt string_constraint_generatort::add_axioms_from_int(
262
263
not_exprt (equal_exprt (res[1 ], zero_char)));
263
264
axioms.push_back (a4);
264
265
265
- assert (max_size<std::numeric_limits<size_t >::max ());
266
-
267
266
for (size_t size=1 ; size<=max_size; size++)
268
267
{
269
- // For each possible size, we add axioms:
270
- // a5 : forall 1 <= j < size. '0' <= res[j] <= '9' && sum == 10 * (sum/10)
268
+ // For each possible size, we have:
269
+ // sum_0 = starts_with_digit ? res[0]-'0' : 0
270
+ // sum_j = 10 * sum_{j-1} + res[i] - '0'
271
+ // and add axioms:
272
+ // a5 : |res| == size =>
273
+ // forall 1 <= j < size.
274
+ // is_number && (j >= max_size-2 => no_overflow)
275
+ // where is_number := '0' <= res[j] <= '9'
276
+ // and no_overflow := sum_{j-1} = (10 * sum_{j-1} / 10)
277
+ // && sum_j >= sum_{j - 1}
278
+ // (the first part avoid overflows in multiplication and
279
+ // the second one in additions)
271
280
// a6 : |res| == size && '0' <= res[0] <= '9' => i == sum
272
281
// a7 : |res| == size && res[0] == '-' => i == -sum
273
282
@@ -288,7 +297,11 @@ string_exprt string_constraint_generatort::add_axioms_from_int(
288
297
binary_relation_exprt (res[j], ID_le, nine_char));
289
298
digit_constraints.push_back (is_number);
290
299
291
- if (j>=max_size-1 )
300
+ // An overflow can happen when reaching the last index of a string of
301
+ // maximal size which is `max_size` for negative numbers and
302
+ // `max_size - 1` for positive numbers because of the abscence of a `-`
303
+ // sign.
304
+ if (j>=max_size-2 )
292
305
{
293
306
// check for overflows if the size is big
294
307
and_exprt no_overflow (
@@ -299,10 +312,10 @@ string_exprt string_constraint_generatort::add_axioms_from_int(
299
312
sum=new_sum;
300
313
}
301
314
302
- exprt a5=conjunction (digit_constraints);
315
+ equal_exprt premise=res.axiom_for_has_length (size);
316
+ implies_exprt a5 (premise, conjunction (digit_constraints));
303
317
axioms.push_back (a5);
304
318
305
- equal_exprt premise=res.axiom_for_has_length (size);
306
319
implies_exprt a6 (
307
320
and_exprt (premise, starts_with_digit), equal_exprt (i, sum));
308
321
axioms.push_back (a6);
0 commit comments