Skip to content

Commit 2655a9b

Browse files
Rewrite axioms for insert
This reduces the number of universal formulas added (from 6 to 3), and avoid introducing new strings. Ideally the add_axioms_-function should not introduce new strings, that would make it easier to refactor and add new functionalities.
1 parent be5f194 commit 2655a9b

File tree

1 file changed

+38
-20
lines changed

1 file changed

+38
-20
lines changed

src/solvers/refinement/string_constraint_generator_insert.cpp

+38-20
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,14 @@ Author: Romain Brenguier, [email protected]
1414

1515
/// Add axioms ensuring the result `res` corresponds to `s1` where we
1616
/// 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]
1723
/// 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')))`.
1925
/// \param res: array of characters expression
2026
/// \param s1: array of characters expression
2127
/// \param s2: array of characters expression
@@ -30,25 +36,37 @@ exprt string_constraint_generatort::add_axioms_for_insert(
3036
{
3137
PRECONDITION(offset.type()==s1.length().type());
3238
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());
5270
}
5371

5472
/// Insertion of a string in another at a specific index

0 commit comments

Comments
 (0)