@@ -39,26 +39,33 @@ exprt string_constraint_generatort::add_axioms_for_equals(
39
39
40
40
typet index_type=s1.length ().type ();
41
41
42
-
43
- implies_exprt a1 (eq, equal_exprt (s1.length (), s2.length ()));
44
- lemmas.push_back (a1);
45
-
46
- symbol_exprt qvar=fresh_univ_index (" QA_equal" , index_type);
47
- string_constraintt a2 (
48
- qvar, s1.length (), implies_exprt (eq, equal_exprt (s1[qvar], s2[qvar])));
49
- constraints.push_back (a2);
50
-
51
- symbol_exprt witness=fresh_exist_index (" witness_unequal" , index_type);
52
- exprt zero=from_integer (0 , index_type);
53
- and_exprt bound_witness (
54
- binary_relation_exprt (witness, ID_lt, s1.length ()),
55
- binary_relation_exprt (witness, ID_ge, zero));
56
- and_exprt witnessing (bound_witness, notequal_exprt (s1[witness], s2[witness]));
57
- and_exprt diff_length (
58
- notequal_exprt (s1.length (), s2.length ()),
59
- equal_exprt (witness, from_integer (-1 , index_type)));
60
- implies_exprt a3 (not_exprt (eq), or_exprt (diff_length, witnessing));
61
- lemmas.push_back (a3);
42
+ // Axiom 1.
43
+ lemmas.push_back (implies_exprt (eq, equal_exprt (s1.length (), s2.length ())));
44
+
45
+ // Axiom 2.
46
+ constraints.push_back ([&] {
47
+ const symbol_exprt qvar = fresh_univ_index (" QA_equal" , index_type);
48
+ return string_constraintt (
49
+ qvar,
50
+ zero_if_negative (s1.length ()),
51
+ implies_exprt (eq, equal_exprt (s1[qvar], s2[qvar])));
52
+ }());
53
+
54
+ // Axiom 3.
55
+ lemmas.push_back ([&] {
56
+ const symbol_exprt witness =
57
+ fresh_exist_index (" witness_unequal" , index_type);
58
+ const exprt zero = from_integer (0 , index_type);
59
+ const and_exprt bound_witness (
60
+ binary_relation_exprt (witness, ID_lt, s1.length ()),
61
+ binary_relation_exprt (witness, ID_ge, zero));
62
+ const and_exprt witnessing (
63
+ bound_witness, notequal_exprt (s1[witness], s2[witness]));
64
+ const and_exprt diff_length (
65
+ notequal_exprt (s1.length (), s2.length ()),
66
+ equal_exprt (witness, from_integer (-1 , index_type)));
67
+ return implies_exprt (not_exprt (eq), or_exprt (diff_length, witnessing));
68
+ }());
62
69
63
70
return tc_eq;
64
71
}
@@ -132,7 +139,8 @@ exprt string_constraint_generatort::add_axioms_for_equals_ignore_case(
132
139
fresh_univ_index (" QA_equal_ignore_case" , index_type);
133
140
const exprt constr2 =
134
141
character_equals_ignore_case (s1[qvar], s2[qvar], char_a, char_A, char_Z);
135
- const string_constraintt a2 (qvar, s1.length (), implies_exprt (eq, constr2));
142
+ const string_constraintt a2 (
143
+ qvar, zero_if_negative (s1.length ()), implies_exprt (eq, constr2));
136
144
constraints.push_back (a2);
137
145
138
146
const symbol_exprt witness =
@@ -226,7 +234,9 @@ exprt string_constraint_generatort::add_axioms_for_compare_to(
226
234
227
235
const symbol_exprt i = fresh_univ_index (" QA_compare_to" , index_type);
228
236
const string_constraintt a2 (
229
- i, s1.length (), implies_exprt (res_null, equal_exprt (s1[i], s2[i])));
237
+ i,
238
+ zero_if_negative (s1.length ()),
239
+ implies_exprt (res_null, equal_exprt (s1[i], s2[i])));
230
240
constraints.push_back (a2);
231
241
232
242
const symbol_exprt x = fresh_exist_index (" index_compare_to" , index_type);
@@ -257,7 +267,9 @@ exprt string_constraint_generatort::add_axioms_for_compare_to(
257
267
258
268
const symbol_exprt i2 = fresh_univ_index (" QA_compare_to" , index_type);
259
269
const string_constraintt a4 (
260
- i2, x, implies_exprt (not_exprt (res_null), equal_exprt (s1[i2], s2[i2])));
270
+ i2,
271
+ zero_if_negative (x),
272
+ implies_exprt (not_exprt (res_null), equal_exprt (s1[i2], s2[i2])));
261
273
constraints.push_back (a4);
262
274
263
275
return res;
0 commit comments