14
14
#include < solvers/refinement/string_constraint_generator.h>
15
15
16
16
// / Add axioms enforcing that `res` is the concatenation of `s1` with
17
- // / the substring of `s2` starting at index `start_index` and ending
18
- // / at index `end_index`.
19
- // /
20
- // / If `start_index >= end_index`, the value returned is `s1`.
21
- // / If `end_index > |s2|` and/or `start_index < 0`, the appended string will
22
- // / be of length `end_index - start_index` and padded with non-deterministic
23
- // / values.
17
+ // / the substring of `s2` starting at index `start_index'` and ending
18
+ // / at index `end_index'`.
19
+ // / Where start_index' is max(0, start_index) and end_index' is
20
+ // / max(min(end_index, s2.length), start_index')
24
21
// /
25
22
// / These axioms are:
26
- // / 1. \f$end\_index > start\_index \Rightarrow |res| = |s_1| + end\_index -
27
- // / start\_index
28
- // / \f$
29
- // / 2. \f$end\_index \le start\_index \Rightarrow res = s_1 \f$
30
- // / 3. \f$\forall i<|s_1|. res[i]=s_1[i] \f$
31
- // / 4. \f$\forall i< end\_index - start\_index.\ res[i+|s_1|]
32
- // / = s_2[start\_index+i]\f$
23
+ // / 1. \f$|res| = |s_1| + end\_index' - start\_index' \f$
24
+ // / 2. \f$\forall i<|s_1|. res[i]=s_1[i] \f$
25
+ // / 3. \f$\forall i< end\_index' - start\_index'.\ res[i+|s_1|]
26
+ // / = s_2[start\_index'+i]\f$
33
27
// /
34
28
// / \param res: an array of characters expression
35
29
// / \param s1: an array of characters expression
@@ -44,28 +38,33 @@ exprt string_constraint_generatort::add_axioms_for_concat_substr(
44
38
const exprt &start_index,
45
39
const exprt &end_index)
46
40
{
47
- binary_relation_exprt prem (end_index, ID_gt, start_index);
48
-
49
- exprt res_length=plus_exprt_with_overflow_check (
50
- s1.length (), minus_exprt (end_index, start_index));
51
- implies_exprt a1 (prem, equal_exprt (res.length (), res_length));
52
- lemmas.push_back (a1);
53
-
54
- implies_exprt a2 (not_exprt (prem), equal_exprt (res.length (), s1.length ()));
55
- lemmas.push_back (a2);
41
+ const typet &index_type = start_index.type ();
42
+ const exprt start1 = maximum (start_index, from_integer (0 , index_type));
43
+ const exprt end1 = maximum (minimum (end_index, s2.length ()), start1);
44
+
45
+ // Axiom 1.
46
+ lemmas.push_back ([&] { // NOLINT
47
+ const plus_exprt res_length (s1.length (), minus_exprt (end1, start1));
48
+ return equal_exprt (res.length (), res_length);
49
+ }());
50
+
51
+ // Axiom 2.
52
+ constraints.push_back ([&] { // NOLINT
53
+ const symbol_exprt idx =
54
+ fresh_univ_index (" QA_index_concat" , res.length ().type ());
55
+ return string_constraintt (idx, s1.length (), equal_exprt (s1[idx], res[idx]));
56
+ }());
57
+
58
+ // Axiom 3.
59
+ constraints.push_back ([&] { // NOLINT
60
+ const symbol_exprt idx2 =
61
+ fresh_univ_index (" QA_index_concat2" , res.length ().type ());
62
+ const equal_exprt res_eq (
63
+ res[plus_exprt (idx2, s1.length ())], s2[plus_exprt (start1, idx2)]);
64
+ return string_constraintt (idx2, minus_exprt (end1, start1), res_eq);
65
+ }());
56
66
57
- symbol_exprt idx=fresh_univ_index (" QA_index_concat" , res.length ().type ());
58
- string_constraintt a3 (idx, s1.length (), equal_exprt (s1[idx], res[idx]));
59
- constraints.push_back (a3);
60
-
61
- symbol_exprt idx2=fresh_univ_index (" QA_index_concat2" , res.length ().type ());
62
- equal_exprt res_eq (
63
- res[plus_exprt (idx2, s1.length ())], s2[plus_exprt (start_index, idx2)]);
64
- string_constraintt a4 (idx2, minus_exprt (end_index, start_index), res_eq);
65
- constraints.push_back (a4);
66
-
67
- // We should have a enum type for the possible error codes
68
- return from_integer (0 , res.length ().type ());
67
+ return from_integer (0 , get_return_code_type ());
69
68
}
70
69
71
70
// / Add axioms enforcing that `res` is the concatenation of `s1` with
0 commit comments