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