Skip to content

Commit cc3e3cc

Browse files
Merge pull request #805 from allredj/string-fix-172
Fix issue test-gen#172
2 parents 72e3e35 + 02f8697 commit cc3e3cc

File tree

1 file changed

+41
-12
lines changed

1 file changed

+41
-12
lines changed

src/solvers/refinement/string_constraint_generator_valueof.cpp

Lines changed: 41 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -639,25 +639,35 @@ exprt string_constraint_generatort::add_axioms_for_correct_number_format(
639639
binary_relation_exprt(chr, ID_ge, zero_char),
640640
binary_relation_exprt(chr, ID_le, nine_char));
641641

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')
642648
or_exprt correct_first(
643649
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));
647651

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));
650657

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)));
652661

662+
// forall 1 <= qvar < |str| . correct => '0'<= str[qvar] <= '9'
663+
symbol_exprt qvar=fresh_univ_index("number_format", index_type);
653664
and_exprt is_digit(
654665
binary_relation_exprt(str[qvar], ID_ge, zero_char),
655666
binary_relation_exprt(str[qvar], ID_le, nine_char));
656-
657-
string_constraintt a2(
667+
string_constraintt all_digits(
658668
qvar, from_integer(1, index_type), str.length(), correct, is_digit);
669+
axioms.push_back(all_digits);
659670

660-
axioms.push_back(a2);
661671
return correct;
662672
}
663673

@@ -703,10 +713,29 @@ exprt string_constraint_generatort::add_axioms_for_parse_int(
703713

704714
for(unsigned j=1; j<size; j++)
705715
{
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,
708727
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;
710739
}
711740

712741
// If the length is `size`, we add axioms:

0 commit comments

Comments
 (0)