@@ -267,23 +267,6 @@ string_exprt string_constraint_generatort::add_axioms_from_bool(
267267
268268/* ******************************************************************\
269269
270- Function: smallest_by_digit
271-
272- Inputs: number of digit
273-
274- Outputs: an integer with the right number of digit
275-
276- Purpose: gives the smallest integer with the specified number of digits
277-
278- \*******************************************************************/
279-
280- static mp_integer smallest_by_digit (int nb)
281- {
282- return power (10 , nb-1 );
283- }
284-
285- /* ******************************************************************\
286-
287270Function: string_constraint_generatort::add_axioms_from_int
288271
289272 Inputs: a signed integer expression, and a maximal size for the string
@@ -313,102 +296,90 @@ string_exprt string_constraint_generatort::add_axioms_from_int(
313296 exprt max=from_integer (max_size, index_type);
314297
315298 // We add axioms:
316- // a1 : 0 <|res|<=max_size
317- // a2 : (res[0]='-')||('0'<=res[0]<='9')
318-
319- and_exprt a1 (res.axiom_for_is_strictly_longer_than (zero),
320- res.axiom_for_is_shorter_than (max));
299+ // a1 : i < 0 => 1 <|res|<=max_size && res[0]='-'
300+ // a2 : i >= 0 => 0 <|res|<=max_size-1 && '0'<=res[0]<='9'
301+ // a3 : |res|>1 && '0'<=res[0]<='9' => res[0]!='0'
302+ // a4 : |res|>1 && res[0]='-' => res[1]!='0'
303+
304+ binary_relation_exprt is_negative (i, ID_lt, zero);
305+ and_exprt correct_length1 (
306+ res.axiom_for_is_strictly_longer_than (1 ),
307+ res.axiom_for_is_shorter_than (max));
308+ equal_exprt starts_with_minus (res[0 ], minus_char);
309+ implies_exprt a1 (is_negative, and_exprt (correct_length1, starts_with_minus));
321310 axioms.push_back (a1);
322311
323- exprt chr=res[0 ];
324- equal_exprt starts_with_minus (chr, minus_char);
312+ not_exprt is_positive (is_negative);
325313 and_exprt starts_with_digit (
326- binary_relation_exprt (chr, ID_ge, zero_char),
327- binary_relation_exprt (chr, ID_le, nine_char));
328- or_exprt a2 (starts_with_digit, starts_with_minus);
314+ binary_relation_exprt (res[0 ], ID_ge, zero_char),
315+ binary_relation_exprt (res[0 ], ID_le, nine_char));
316+ and_exprt correct_length2 (
317+ res.axiom_for_is_strictly_longer_than (0 ),
318+ res.axiom_for_is_strictly_shorter_than (max));
319+ implies_exprt a2 (is_positive, and_exprt (correct_length2, starts_with_digit));
329320 axioms.push_back (a2);
330321
331- // These are constraints to detect number that requiere the maximum number
332- // of digits
333- exprt smallest_with_max_digits=
334- from_integer (smallest_by_digit (max_size-1 ), type);
335- binary_relation_exprt big_negative (
336- i, ID_le, unary_minus_exprt (smallest_with_max_digits));
337- binary_relation_exprt big_positive (i, ID_ge, smallest_with_max_digits);
338- or_exprt requieres_max_digits (big_negative, big_positive);
322+ implies_exprt a3 (
323+ and_exprt (res.axiom_for_is_strictly_longer_than (1 ), starts_with_digit),
324+ not_exprt (equal_exprt (res[0 ], zero_char)));
325+ axioms.push_back (a3);
326+
327+ implies_exprt a4 (
328+ and_exprt (res.axiom_for_is_strictly_longer_than (1 ), starts_with_minus),
329+ not_exprt (equal_exprt (res[1 ], zero_char)));
330+ axioms.push_back (a4);
331+
332+ assert (max_size<std::numeric_limits<size_t >::max ());
339333
340334 for (size_t size=1 ; size<=max_size; size++)
341335 {
342336 // For each possible size, we add axioms:
343- // all_numbers: forall 1<=i<=size. '0'<=res[i]<='9'
344- // a3 : |res|=size&&'0'<=res[0]<='9' =>
345- // i=sum+str[0]-'0' &&all_numbers
346- // a4 : |res|=size&&res[0]='-' => i=-sum
347- // a5 : size>1 => |res|=size&&'0'<=res[0]<='9' => res[0]!='0'
348- // a6 : size>1 => |res|=size&&res[0]'-' => res[1]!='0'
349- // a7 : size==max_size => i>1000000000
350- exprt sum=from_integer (0 , type);
351- exprt all_numbers=true_exprt ();
352- chr=res[0 ];
353- exprt first_value=typecast_exprt (minus_exprt (chr, zero_char), type);
337+ // a5 : forall 1 <= j < size. '0' <= res[j] <= '9' && sum == 10 * (sum/10)
338+ // a6 : |res| == size && '0' <= res[0] <= '9' => i == sum
339+ // a7 : |res| == size && res[0] == '-' => i == -sum
340+
341+ exprt::operandst digit_constraints;
342+ exprt sum=if_exprt (
343+ starts_with_digit,
344+ typecast_exprt (minus_exprt (res[0 ], zero_char), type),
345+ from_integer (0 , type));
354346
355347 for (size_t j=1 ; j<size; j++)
356348 {
357- chr=res[j];
358- sum=plus_exprt (
359- mult_exprt (sum, ten),
360- typecast_exprt (minus_exprt (chr, zero_char), type));
361- first_value=mult_exprt (first_value, ten);
349+ mult_exprt ten_sum (sum, ten);
350+ // sum = 10 * sum + (res[j] - '0')
351+ exprt new_sum=plus_exprt (
352+ ten_sum, typecast_exprt (minus_exprt (res[j], zero_char), type));
362353 and_exprt is_number (
363- binary_relation_exprt (chr, ID_ge, zero_char),
364- binary_relation_exprt (chr, ID_le, nine_char));
365- all_numbers=and_exprt (all_numbers, is_number);
354+ binary_relation_exprt (res[j], ID_ge, zero_char),
355+ binary_relation_exprt (res[j], ID_le, nine_char));
356+ digit_constraints.push_back (is_number);
357+
358+ if (j>=max_size-1 )
359+ {
360+ // check for overflows if the size is big
361+ and_exprt no_overflow (
362+ equal_exprt (sum, div_exprt (ten_sum, ten)),
363+ binary_relation_exprt (new_sum, ID_ge, ten_sum));
364+ digit_constraints.push_back (no_overflow);
365+ }
366+ sum=new_sum;
366367 }
367368
368- axioms.push_back (all_numbers);
369+ exprt a5=conjunction (digit_constraints);
370+ axioms.push_back (a5);
369371
370372 equal_exprt premise=res.axiom_for_has_length (size);
371- equal_exprt constr3 (i, plus_exprt (sum, first_value));
372- implies_exprt a3 ( and_exprt (premise, starts_with_digit), constr3 );
373- axioms.push_back (a3 );
373+ implies_exprt a6 (
374+ and_exprt (premise, starts_with_digit), equal_exprt (i, sum) );
375+ axioms.push_back (a6 );
374376
375- implies_exprt a4 (
377+ implies_exprt a7 (
376378 and_exprt (premise, starts_with_minus),
377379 equal_exprt (i, unary_minus_exprt (sum)));
378- axioms.push_back (a4);
379-
380- // disallow 0s at the beginning
381- if (size>1 )
382- {
383- equal_exprt r0_zero (res[zero], zero_char);
384- implies_exprt a5 (
385- and_exprt (premise, starts_with_digit),
386- not_exprt (r0_zero));
387- axioms.push_back (a5);
388-
389- exprt one=from_integer (1 , index_type);
390- equal_exprt r1_zero (res[one], zero_char);
391- implies_exprt a6 (
392- and_exprt (premise, starts_with_minus),
393- not_exprt (r1_zero));
394- axioms.push_back (a6);
395- }
396-
397- // when the size is close to the maximum, either the number is very big
398- // or it is negative
399- if (size==max_size-1 )
400- {
401- implies_exprt a7 (premise, or_exprt (requieres_max_digits,
402- starts_with_minus));
403- axioms.push_back (a7);
404- }
405- // when we reach the maximal size the number is very big in the negative
406- if (size==max_size)
407- {
408- implies_exprt a7 (premise, and_exprt (starts_with_minus, big_negative));
409- axioms.push_back (a7);
410- }
380+ axioms.push_back (a7);
411381 }
382+
412383 return res;
413384}
414385
0 commit comments