@@ -209,16 +209,17 @@ string_exprt string_constraint_generatort::add_axioms_from_bool(
209209
210210// / add axioms to say the string corresponds to the result of String.valueOf(I)
211211// / 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
215215// / \return a string expression
216216string_exprt string_constraint_generatort::add_axioms_from_int (
217217 const exprt &i, size_t max_size, const refined_string_typet &ref_type)
218218{
219+ PRECONDITION (i.type ().id ()==ID_signedbv);
220+ PRECONDITION (max_size<std::numeric_limits<size_t >::max ());
219221 string_exprt res=fresh_string (ref_type);
220222 const typet &type=i.type ();
221- assert (type.id ()==ID_signedbv);
222223 exprt ten=from_integer (10 , type);
223224 const typet &char_type=ref_type.get_char_type ();
224225 const typet &index_type=ref_type.get_index_type ();
@@ -262,12 +263,20 @@ string_exprt string_constraint_generatort::add_axioms_from_int(
262263 not_exprt (equal_exprt (res[1 ], zero_char)));
263264 axioms.push_back (a4);
264265
265- assert (max_size<std::numeric_limits<size_t >::max ());
266-
267266 for (size_t size=1 ; size<=max_size; size++)
268267 {
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)
271280 // a6 : |res| == size && '0' <= res[0] <= '9' => i == sum
272281 // a7 : |res| == size && res[0] == '-' => i == -sum
273282
@@ -288,7 +297,11 @@ string_exprt string_constraint_generatort::add_axioms_from_int(
288297 binary_relation_exprt (res[j], ID_le, nine_char));
289298 digit_constraints.push_back (is_number);
290299
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 )
292305 {
293306 // check for overflows if the size is big
294307 and_exprt no_overflow (
@@ -299,10 +312,10 @@ string_exprt string_constraint_generatort::add_axioms_from_int(
299312 sum=new_sum;
300313 }
301314
302- exprt a5=conjunction (digit_constraints);
315+ equal_exprt premise=res.axiom_for_has_length (size);
316+ implies_exprt a5 (premise, conjunction (digit_constraints));
303317 axioms.push_back (a5);
304318
305- equal_exprt premise=res.axiom_for_has_length (size);
306319 implies_exprt a6 (
307320 and_exprt (premise, starts_with_digit), equal_exprt (i, sum));
308321 axioms.push_back (a6);
0 commit comments