Skip to content

Commit e26991b

Browse files
Get rid of constraints field of constraint generator
The constraints should be a return value of the generator methods rather than a field.
1 parent 9705cc9 commit e26991b

5 files changed

+40
-27
lines changed

src/solvers/strings/string_constraint_generator.h

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -60,20 +60,24 @@ class string_constraint_generatort final
6060

6161
array_poolt array_pool;
6262

63-
string_constraintst constraints;
64-
6563
const namespacet ns;
6664

6765
/// Associate array to pointer, and array to length
6866
/// \return an expression if the given function application is one of
6967
/// associate pointer and associate length
7068
optionalt<exprt>
71-
make_array_pointer_association(const function_application_exprt &expr);
69+
make_array_pointer_association(
70+
const exprt &return_code,
71+
const function_application_exprt &expr);
7272

7373
private:
74-
exprt associate_array_to_pointer(const function_application_exprt &f);
74+
exprt associate_array_to_pointer(
75+
const exprt &return_code,
76+
const function_application_exprt &f);
7577

76-
exprt associate_length_to_array(const function_application_exprt &f);
78+
exprt associate_length_to_array(
79+
const exprt &return_code,
80+
const function_application_exprt &f);
7781
};
7882

7983
// Type used by primitives to signal errors

src/solvers/strings/string_constraint_generator_main.cpp

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ exprt sum_overflows(const plus_exprt &sum)
5858
/// \param f: a function application with argument a character array `arr` and
5959
/// a character pointer `ptr`.
6060
exprt string_constraint_generatort::associate_array_to_pointer(
61+
const exprt &return_code,
6162
const function_application_exprt &f)
6263
{
6364
PRECONDITION(f.arguments().size() == 2);
@@ -76,19 +77,22 @@ exprt string_constraint_generatort::associate_array_to_pointer(
7677

7778
/// Associate an integer length to a char array.
7879
/// This adds an axiom ensuring that `arr.length` and `length` are equal.
80+
/// \param return code: expression which is assigned the result of the function
7981
/// \param f: a function application with argument a character array `arr` and
8082
/// an integer `length`.
81-
/// \return integer expression equal to 0
83+
/// \return a constraint
8284
exprt string_constraint_generatort::associate_length_to_array(
85+
const exprt &return_code,
8386
const function_application_exprt &f)
8487
{
8588
PRECONDITION(f.arguments().size() == 2);
8689
array_string_exprt array_expr = to_array_string_expr(f.arguments()[0]);
8790
const exprt &new_length = f.arguments()[1];
8891

8992
const auto &length = array_pool.get_or_create_length(array_expr);
90-
constraints.existential.push_back(equal_exprt(length, new_length));
91-
return from_integer(0, f.type());
93+
return and_exprt{
94+
equal_exprt{return_code, from_integer(0, f.type())},
95+
equal_exprt(length, new_length)};
9296
}
9397

9498
void string_constraintst::clear()
@@ -200,13 +204,14 @@ static irep_idt get_function_name(const function_application_exprt &expr)
200204
}
201205

202206
optionalt<exprt> string_constraint_generatort::make_array_pointer_association(
207+
const exprt &return_code,
203208
const function_application_exprt &expr)
204209
{
205210
const irep_idt &id = get_function_name(expr);
206211
if(id == ID_cprover_associate_array_to_pointer_func)
207-
return associate_array_to_pointer(expr);
212+
return associate_array_to_pointer(return_code, expr);
208213
else if(id == ID_cprover_associate_length_to_array_func)
209-
return associate_length_to_array(expr);
214+
return associate_length_to_array(return_code, expr);
210215
return {};
211216
}
212217

src/solvers/strings/string_dependencies.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -328,7 +328,7 @@ void string_dependenciest::output_dot(std::ostream &stream) const
328328
stream << '}' << std::endl;
329329
}
330330

331-
void string_dependenciest::add_constraints(
331+
string_constraintst string_dependenciest::add_constraints(
332332
string_constraint_generatort &generator)
333333
{
334334
std::unordered_set<nodet, node_hash> test_dependencies;
@@ -346,16 +346,16 @@ void string_dependenciest::add_constraints(
346346
for_each_successor(n, f);
347347
});
348348

349+
string_constraintst constraints;
349350
for(const auto &node : builtin_function_nodes)
350351
{
351352
if(test_dependencies.count(nodet(node)))
352353
{
353354
const auto &builtin = builtin_function_nodes[node.index];
354-
string_constraintst constraints = builtin.data->constraints(generator);
355-
merge(generator.constraints, std::move(constraints));
355+
merge(constraints, builtin.data->constraints(generator));
356356
}
357357
else
358-
generator.constraints.existential.push_back(
359-
node.data->length_constraint());
358+
constraints.existential.push_back(node.data->length_constraint());
360359
}
360+
return constraints;
361361
}

src/solvers/strings/string_dependencies.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ Author: Diffblue Ltd.
1414

1515
#include <memory>
1616

17+
#include <util/nodiscard.h>
18+
1719
#include "string_builtin_function.h"
1820

1921
/// Keep track of dependencies between strings.
@@ -114,7 +116,8 @@ class string_dependenciest
114116
/// For all builtin call on which a test (or an unsupported buitin)
115117
/// result depends, add the corresponding constraints. For the other builtin
116118
/// only add constraints on the length.
117-
void add_constraints(string_constraint_generatort &generatort);
119+
NODISCARD string_constraintst add_constraints(
120+
string_constraint_generatort &generatort);
118121

119122
/// Clear the content of the dependency graph
120123
void clear();

src/solvers/strings/string_refinement.cpp

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -251,8 +251,10 @@ static void make_char_array_pointer_associations(
251251
const auto fun_app =
252252
expr_try_dynamic_cast<function_application_exprt>(eq.rhs()))
253253
{
254-
if(const auto result = generator.make_array_pointer_association(*fun_app))
255-
eq.rhs() = *result;
254+
const auto new_equation =
255+
generator.make_array_pointer_association(eq.lhs(), *fun_app);
256+
if(new_equation)
257+
eq = equal_exprt{true_exprt{}, *new_equation};
256258
}
257259
}
258260
}
@@ -645,9 +647,8 @@ decision_proceduret::resultt string_refinementt::dec_solve()
645647
}
646648
}
647649

648-
// Generator is also used by get, so we have to use it as a class member
649-
// but we make sure it is cleared at each `dec_solve` call.
650-
generator.constraints.clear();
650+
// Constraints start clear at each `dec_solve` call.
651+
string_constraintst constraints;
651652
make_char_array_pointer_associations(generator, equations);
652653

653654
#ifdef DEBUG
@@ -677,7 +678,7 @@ decision_proceduret::resultt string_refinementt::dec_solve()
677678
#endif
678679

679680
log.debug() << "dec_solve: add constraints" << messaget::eom;
680-
dependencies.add_constraints(generator);
681+
merge(constraints, dependencies.add_constraints(generator));
681682

682683
#ifdef DEBUG
683684
output_equations(log.debug(), equations);
@@ -702,8 +703,8 @@ decision_proceduret::resultt string_refinementt::dec_solve()
702703
}
703704

704705
std::transform(
705-
generator.constraints.universal.begin(),
706-
generator.constraints.universal.end(),
706+
constraints.universal.begin(),
707+
constraints.universal.end(),
707708
std::back_inserter(axioms.universal),
708709
[&](string_constraintt constraint) {
709710
constraint.replace_expr(symbol_resolve);
@@ -715,8 +716,8 @@ decision_proceduret::resultt string_refinementt::dec_solve()
715716
});
716717

717718
std::transform(
718-
generator.constraints.not_contains.begin(),
719-
generator.constraints.not_contains.end(),
719+
constraints.not_contains.begin(),
720+
constraints.not_contains.end(),
720721
std::back_inserter(axioms.not_contains),
721722
[&](string_not_contains_constraintt axiom) {
722723
replace(symbol_resolve, axiom);
@@ -737,7 +738,7 @@ decision_proceduret::resultt string_refinementt::dec_solve()
737738
nc_axiom, generator.fresh_symbol("not_contains_witness", witness_type));
738739
}
739740

740-
for(const exprt &lemma : generator.constraints.existential)
741+
for(const exprt &lemma : constraints.existential)
741742
{
742743
add_lemma(substitute_array_access(lemma, generator.fresh_symbol, true));
743744
}

0 commit comments

Comments
 (0)