@@ -413,47 +413,35 @@ void string_constraint_generatort::add_axioms_for_correct_number_format(
413
413
}
414
414
}
415
415
416
- // / add axioms corresponding to the Integer.parseInt java function
417
- // / \param f: a function application with either one string expression or one
418
- // / string expression and an integer expression for the radix
419
- // / \return an integer expression
420
- exprt string_constraint_generatort::add_axioms_for_parse_int (
421
- const function_application_exprt &f)
416
+ // / Add axioms connecting the characters in the input string to the value of the
417
+ // / output integer
418
+ // / \param x: symbol for abs(integer represented by str)
419
+ // / \param type: the type for x
420
+ // / \param char_type: the type to use for characters
421
+ // / \param index_type: the type to use for indexes
422
+ // / \param str: input string
423
+ // / \param max_string_length: the maximum length str can have
424
+ // / \param radix: the radix, with the same type as x
425
+ // / \return an expression for the integer represented by the string
426
+ exprt string_constraint_generatort::add_axioms_for_characters_in_integer_string (
427
+ const symbol_exprt& x,
428
+ const typet& type,
429
+ const typet& char_type,
430
+ const typet& index_type,
431
+ const string_exprt& str,
432
+ const std::size_t max_string_length,
433
+ const exprt& radix)
422
434
{
423
- PRECONDITION (f.arguments ().size ()==1 || f.arguments ().size ()==2 );
424
- const string_exprt str=get_string_expr (f.arguments ()[0 ]);
425
- const typet &type=f.type ();
426
- PRECONDITION (type.id ()==ID_signedbv);
427
- const exprt radix=
428
- f.arguments ().size ()==1 ?
429
- static_cast <exprt>(from_integer (10 , type)):
430
- static_cast <exprt>(typecast_exprt (f.arguments ()[1 ], type));
431
-
432
- const symbol_exprt x=fresh_symbol (" parsed_int" , type);
433
- const refined_string_typet &ref_type=to_refined_string_type (str.type ());
434
- const typet &char_type=ref_type.get_char_type ();
435
- const typet &index_type=ref_type.get_index_type ();
436
- const exprt minus_char=constant_char (' -' , char_type);
437
- const exprt zero_expr=from_integer (0 , type);
438
-
439
- // / We experimented with making the max_string_length depend on the base, but
440
- // / this did not make any difference to the speed of execution.
441
- const std::size_t max_string_length=to_bitvector_type (type).get_width ()+1 ;
442
-
443
- // / TODO: we should throw an exception when this does not hold:
444
- // / Note that the only thing stopping us from taking longer strings with many
445
- // / leading zeros is the axioms for correct number format
446
- add_axioms_for_correct_number_format (
447
- str, typecast_exprt (radix, char_type), max_string_length);
448
-
449
435
// / TODO(OJones): Fix the below algorithm to make it work for min_int. There
450
436
// / are two problems. (1) Because we build i as positive and then negate it if
451
437
// / the first character is '-', we hit overflow for min_int because
452
438
// / |min_int| > max_int. (2) radix^63 overflows. I think we'll have to
453
439
// / special-case it.
454
440
441
+ const exprt zero_expr=from_integer (0 , type);
455
442
axioms.push_back (binary_relation_exprt (x, ID_ge, zero_expr));
456
443
444
+ const exprt one_index_type=from_integer (1 , index_type);
457
445
exprt radix_to_power_of_i;
458
446
exprt no_overflow;
459
447
@@ -462,8 +450,7 @@ exprt string_constraint_generatort::add_axioms_for_parse_int(
462
450
// / We are counting backwards from the end of the string, i.e. i refers
463
451
// / to str[j] where j=str.length()-i-1
464
452
const constant_exprt i_expr=from_integer (i, index_type);
465
- const minus_exprt j (
466
- minus_exprt (str.length (), i_expr), from_integer (1 , index_type));
453
+ const minus_exprt j (minus_exprt (str.length (), i_expr), one_index_type);
467
454
468
455
if (i==0 )
469
456
{
@@ -472,7 +459,7 @@ exprt string_constraint_generatort::add_axioms_for_parse_int(
472
459
}
473
460
else
474
461
{
475
- exprt radix_to_power_of_i_minus_one=radix_to_power_of_i;
462
+ const exprt radix_to_power_of_i_minus_one=radix_to_power_of_i;
476
463
// / Note that power_exprt is probably designed for floating point. Also,
477
464
// / it doesn't work when the exponent isn't a constant, hence why this
478
465
// / loop is indexed by i instead of j. It is faster than
@@ -494,7 +481,7 @@ exprt string_constraint_generatort::add_axioms_for_parse_int(
494
481
const if_exprt digit_value (
495
482
i_is_valid,
496
483
get_numeric_value_from_character (str[j], char_type, type),
497
- from_integer ( 0 , type) );
484
+ zero_expr );
498
485
499
486
// / when there is no overflow, str[j] = (x/radix^i)%radix
500
487
const equal_exprt contribution_of_str_j (
@@ -506,7 +493,47 @@ exprt string_constraint_generatort::add_axioms_for_parse_int(
506
493
not_exprt (no_overflow), equal_exprt (digit_value, zero_expr)));
507
494
}
508
495
509
- return if_exprt (equal_exprt (str[0 ], minus_char), unary_minus_exprt (x), x);
496
+ return if_exprt (
497
+ equal_exprt (str[0 ], constant_char (' -' , char_type)),
498
+ unary_minus_exprt (x),
499
+ x);
500
+ }
501
+
502
+ // / add axioms corresponding to the Integer.parseInt java function
503
+ // / \param f: a function application with either one string expression or one
504
+ // / string expression and an integer expression for the radix
505
+ // / \return an integer expression
506
+ exprt string_constraint_generatort::add_axioms_for_parse_int (
507
+ const function_application_exprt &f)
508
+ {
509
+ PRECONDITION (f.arguments ().size ()==1 || f.arguments ().size ()==2 );
510
+ const string_exprt str=get_string_expr (f.arguments ()[0 ]);
511
+ const typet &type=f.type ();
512
+ PRECONDITION (type.id ()==ID_signedbv);
513
+ const exprt radix=
514
+ f.arguments ().size ()==1 ?
515
+ static_cast <exprt>(from_integer (10 , type)):
516
+ static_cast <exprt>(typecast_exprt (f.arguments ()[1 ], type));
517
+
518
+ const symbol_exprt x=fresh_symbol (" abs_parsed_int" , type);
519
+ const refined_string_typet &ref_type=to_refined_string_type (str.type ());
520
+ const typet &char_type=ref_type.get_char_type ();
521
+ const typet &index_type=ref_type.get_index_type ();
522
+
523
+ // / We experimented with making the max_string_length depend on the base, but
524
+ // / this did not make any difference to the speed of execution.
525
+ const std::size_t max_string_length=to_bitvector_type (type).get_width ()+1 ;
526
+
527
+ // / TODO: we should throw an exception when this does not hold:
528
+ // / Note that the only thing stopping us from taking longer strings with many
529
+ // / leading zeros is the axioms for correct number format
530
+ add_axioms_for_correct_number_format (
531
+ str, typecast_exprt (radix, char_type), max_string_length);
532
+
533
+ exprt parsed_int_expr=add_axioms_for_characters_in_integer_string (
534
+ x, type, char_type, index_type, str, max_string_length, radix);
535
+
536
+ return parsed_int_expr;
510
537
}
511
538
512
539
// / Check if a character is a digit with respect to the given radix, e.g. if the
0 commit comments