@@ -511,25 +511,35 @@ exprt string_constraint_generatort::add_axioms_for_correct_number_format(
511
511
binary_relation_exprt (chr, ID_ge, zero_char),
512
512
binary_relation_exprt (chr, ID_le, nine_char));
513
513
514
+ // TODO: we should have implications in the other direction for correct
515
+ // correct => |str| > 0
516
+ exprt non_empty=str.axiom_for_is_longer_than (from_integer (1 , index_type));
517
+ axioms.push_back (implies_exprt (correct, non_empty));
518
+
519
+ // correct => (str[0] = '+' or '-' || '0' <= str[0] <= '9')
514
520
or_exprt correct_first (
515
521
or_exprt (starts_with_minus, starts_with_plus), starts_with_digit);
516
- exprt has_first=str.axiom_for_is_longer_than (from_integer (1 , index_type));
517
- implies_exprt a1 (correct, and_exprt (has_first, correct_first));
518
- axioms.push_back (a1);
522
+ axioms.push_back (implies_exprt (correct, correct_first));
519
523
520
- exprt not_too_long=str.axiom_for_is_shorter_than (max_size);
521
- axioms.push_back (not_too_long);
524
+ // correct => str[0]='+' or '-' ==> |str| > 1
525
+ implies_exprt contains_digit (
526
+ or_exprt (starts_with_minus, starts_with_plus),
527
+ str.axiom_for_is_longer_than (from_integer (2 , index_type)));
528
+ axioms.push_back (implies_exprt (correct, contains_digit));
522
529
523
- symbol_exprt qvar=fresh_univ_index (" number_format" , index_type);
530
+ // correct => |str| < max_size
531
+ axioms.push_back (
532
+ implies_exprt (correct, str.axiom_for_is_shorter_than (max_size)));
524
533
534
+ // forall 1 <= qvar < |str| . correct => '0'<= str[qvar] <= '9'
535
+ symbol_exprt qvar=fresh_univ_index (" number_format" , index_type);
525
536
and_exprt is_digit (
526
537
binary_relation_exprt (str[qvar], ID_ge, zero_char),
527
538
binary_relation_exprt (str[qvar], ID_le, nine_char));
528
-
529
- string_constraintt a2 (
539
+ string_constraintt all_digits (
530
540
qvar, from_integer (1 , index_type), str.length (), correct, is_digit);
541
+ axioms.push_back (all_digits);
531
542
532
- axioms.push_back (a2);
533
543
return correct;
534
544
}
535
545
@@ -575,10 +585,29 @@ exprt string_constraint_generatort::add_axioms_for_parse_int(
575
585
576
586
for (unsigned j=1 ; j<size; j++)
577
587
{
578
- sum=plus_exprt (
579
- mult_exprt (sum, ten),
588
+ mult_exprt ten_sum (sum, ten);
589
+ if (j>=9 )
590
+ {
591
+ // We have to be careful about overflows
592
+ div_exprt div (sum, ten);
593
+ equal_exprt no_overflow (div , sum);
594
+ axioms.push_back (no_overflow);
595
+ }
596
+
597
+ sum=plus_exprt_with_overflow_check (
598
+ ten_sum,
580
599
typecast_exprt (minus_exprt (str[j], zero_char), type));
581
- first_value=mult_exprt (first_value, ten);
600
+
601
+ mult_exprt first (first_value, ten);
602
+ if (j>=9 )
603
+ {
604
+ // We have to be careful about overflows
605
+ div_exprt div_first (first, ten);
606
+ implies_exprt no_overflow_first (
607
+ starts_with_digit, equal_exprt (div_first, first_value));
608
+ axioms.push_back (no_overflow_first);
609
+ }
610
+ first_value=first;
582
611
}
583
612
584
613
// If the length is `size`, we add axioms:
0 commit comments