14
14
15
15
// / Add axioms ensuring the result `res` corresponds to `s1` where we
16
16
// / inserted `s2` at position `offset`.
17
+ // / We write offset' for `max(0, min(res.length, offset))`.
18
+ // / These axioms are:
19
+ // / 1. res.length = s1.length + s2.length
20
+ // / 2. forall i < offset' . res[i] = s1[i]
21
+ // / 3. forall i < s2.length. res[i + offset'] = s2[i]
22
+ // / 4. forall i in [offset', s1.length). res[i + s2.length] = s1[i]
17
23
// / This is equivalent to
18
- // / `res=concat(substring(s1, 0, offset), concat(s2, substring(s1, offset)))`.
24
+ // / `res=concat(substring(s1, 0, offset' ), concat(s2, substring(s1, offset' )))`.
19
25
// / \param res: array of characters expression
20
26
// / \param s1: array of characters expression
21
27
// / \param s2: array of characters expression
@@ -30,25 +36,37 @@ exprt string_constraint_generatort::add_axioms_for_insert(
30
36
{
31
37
PRECONDITION (offset.type ()==s1.length ().type ());
32
38
const typet &index_type = s1.length ().type ();
33
- const typet &char_type = s1.content ().type ().subtype ();
34
- array_string_exprt pref = fresh_string (index_type, char_type);
35
- exprt return_code1 =
36
- add_axioms_for_substring (pref, s1, from_integer (0 , offset.type ()), offset);
37
- array_string_exprt suf = fresh_string (index_type, char_type);
38
- exprt return_code2 = add_axioms_for_substring (suf, s1, offset, s1.length ());
39
- array_string_exprt concat1 = fresh_string (index_type, char_type);
40
- exprt return_code3 = add_axioms_for_concat (concat1, pref, s2);
41
- exprt return_code4 = add_axioms_for_concat (res, concat1, suf);
42
- return if_exprt (
43
- equal_exprt (return_code1, from_integer (0 , return_code1.type ())),
44
- if_exprt (
45
- equal_exprt (return_code2, from_integer (0 , return_code1.type ())),
46
- if_exprt (
47
- equal_exprt (return_code3, from_integer (0 , return_code1.type ())),
48
- return_code4,
49
- return_code3),
50
- return_code2),
51
- return_code1);
39
+ const exprt offset1 =
40
+ maximum (from_integer (0 , index_type), minimum (s1.length (), offset));
41
+
42
+ // Axiom 1.
43
+ lemmas.push_back (
44
+ equal_exprt (res.length (), plus_exprt (s1.length (), s2.length ())));
45
+
46
+ // Axiom 2.
47
+ constraints.push_back ([&] { // NOLINT
48
+ const symbol_exprt i = fresh_symbol (" QA_insert1" , index_type);
49
+ return string_constraintt (i, offset1, equal_exprt (res[i], s1[i]));
50
+ }());
51
+
52
+ // Axiom 3.
53
+ constraints.push_back ([&] { // NOLINT
54
+ const symbol_exprt i = fresh_symbol (" QA_insert2" , index_type);
55
+ return string_constraintt (
56
+ i, s2.length (), equal_exprt (res[plus_exprt (i, offset1)], s2[i]));
57
+ }());
58
+
59
+ // Axiom 4.
60
+ constraints.push_back ([&] { // NOLINT
61
+ const symbol_exprt i = fresh_symbol (" QA_insert3" , index_type);
62
+ return string_constraintt (
63
+ i,
64
+ offset1,
65
+ s1.length (),
66
+ equal_exprt (res[plus_exprt (i, s2.length ())], s1[i]));
67
+ }());
68
+
69
+ return from_integer (0 , get_return_code_type ());
52
70
}
53
71
54
72
// / Insertion of a string in another at a specific index
0 commit comments