@@ -639,25 +639,35 @@ exprt string_constraint_generatort::add_axioms_for_correct_number_format(
639
639
binary_relation_exprt (chr, ID_ge, zero_char),
640
640
binary_relation_exprt (chr, ID_le, nine_char));
641
641
642
+ // TODO: we should have implications in the other direction for correct
643
+ // correct => |str| > 0
644
+ exprt non_empty=str.axiom_for_is_longer_than (from_integer (1 , index_type));
645
+ axioms.push_back (implies_exprt (correct, non_empty));
646
+
647
+ // correct => (str[0] = '+' or '-' || '0' <= str[0] <= '9')
642
648
or_exprt correct_first (
643
649
or_exprt (starts_with_minus, starts_with_plus), starts_with_digit);
644
- exprt has_first=str.axiom_for_is_longer_than (from_integer (1 , index_type));
645
- implies_exprt a1 (correct, and_exprt (has_first, correct_first));
646
- axioms.push_back (a1);
650
+ axioms.push_back (implies_exprt (correct, correct_first));
647
651
648
- exprt not_too_long=str.axiom_for_is_shorter_than (max_size);
649
- axioms.push_back (not_too_long);
652
+ // correct => str[0]='+' or '-' ==> |str| > 1
653
+ implies_exprt contains_digit (
654
+ or_exprt (starts_with_minus, starts_with_plus),
655
+ str.axiom_for_is_longer_than (from_integer (2 , index_type)));
656
+ axioms.push_back (implies_exprt (correct, contains_digit));
650
657
651
- symbol_exprt qvar=fresh_univ_index (" number_format" , index_type);
658
+ // correct => |str| < max_size
659
+ axioms.push_back (
660
+ implies_exprt (correct, str.axiom_for_is_shorter_than (max_size)));
652
661
662
+ // forall 1 <= qvar < |str| . correct => '0'<= str[qvar] <= '9'
663
+ symbol_exprt qvar=fresh_univ_index (" number_format" , index_type);
653
664
and_exprt is_digit (
654
665
binary_relation_exprt (str[qvar], ID_ge, zero_char),
655
666
binary_relation_exprt (str[qvar], ID_le, nine_char));
656
-
657
- string_constraintt a2 (
667
+ string_constraintt all_digits (
658
668
qvar, from_integer (1 , index_type), str.length (), correct, is_digit);
669
+ axioms.push_back (all_digits);
659
670
660
- axioms.push_back (a2);
661
671
return correct;
662
672
}
663
673
@@ -703,10 +713,29 @@ exprt string_constraint_generatort::add_axioms_for_parse_int(
703
713
704
714
for (unsigned j=1 ; j<size; j++)
705
715
{
706
- sum=plus_exprt (
707
- mult_exprt (sum, ten),
716
+ mult_exprt ten_sum (sum, ten);
717
+ if (j>=9 )
718
+ {
719
+ // We have to be careful about overflows
720
+ div_exprt div (sum, ten);
721
+ equal_exprt no_overflow (div, sum);
722
+ axioms.push_back (no_overflow);
723
+ }
724
+
725
+ sum=plus_exprt_with_overflow_check (
726
+ ten_sum,
708
727
typecast_exprt (minus_exprt (str[j], zero_char), type));
709
- first_value=mult_exprt (first_value, ten);
728
+
729
+ mult_exprt first (first_value, ten);
730
+ if (j>=9 )
731
+ {
732
+ // We have to be careful about overflows
733
+ div_exprt div_first (first, ten);
734
+ implies_exprt no_overflow_first (
735
+ starts_with_digit, equal_exprt (div_first, first_value));
736
+ axioms.push_back (no_overflow_first);
737
+ }
738
+ first_value=first;
710
739
}
711
740
712
741
// If the length is `size`, we add axioms:
0 commit comments