Skip to content

Commit 78d23cf

Browse files
committed
[code contracts] minor refactor
1 parent e6f6970 commit 78d23cf

File tree

1 file changed

+59
-73
lines changed

1 file changed

+59
-73
lines changed

src/goto-instrument/contracts/contracts.cpp

Lines changed: 59 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -38,15 +38,46 @@ Date: February 2016
3838
// This is used in the implementation of multidimensional decreases clauses.
3939
static exprt create_lexicographic_less_than(
4040
const std::vector<symbol_exprt> &lhs,
41-
const std::vector<symbol_exprt> &rhs);
42-
43-
exprt get_size(const typet &type, const namespacet &ns, messaget &log)
41+
const std::vector<symbol_exprt> &rhs)
4442
{
45-
auto size_of_opt = size_of_expr(type, ns);
46-
CHECK_RETURN(size_of_opt.has_value());
47-
exprt result = size_of_opt.value();
48-
result.add(ID_C_c_sizeof_type) = type;
49-
return result;
43+
PRECONDITION(lhs.size() == rhs.size());
44+
45+
if(lhs.empty())
46+
{
47+
return false_exprt();
48+
}
49+
50+
// Store conjunctions of equalities.
51+
// For example, suppose that the two input vectors are <s1, s2, s3> and <l1,
52+
// l2, l3>.
53+
// Then this vector stores <s1 == l1, s1 == l1 && s2 == l2,
54+
// s1 == l1 && s2 == l2 && s3 == l3>.
55+
// In fact, the last element is unnecessary, so we do not create it.
56+
exprt::operandst equality_conjunctions(lhs.size());
57+
equality_conjunctions[0] = binary_relation_exprt(lhs[0], ID_equal, rhs[0]);
58+
for(unsigned int i = 1; i < equality_conjunctions.size() - 1; i++)
59+
{
60+
binary_relation_exprt component_i_equality{lhs[i], ID_equal, rhs[i]};
61+
equality_conjunctions[i] =
62+
and_exprt(equality_conjunctions[i - 1], component_i_equality);
63+
}
64+
65+
// Store inequalities between the i-th components of the input vectors
66+
// (i.e. lhs and rhs).
67+
// For example, suppose that the two input vectors are <s1, s2, s3> and <l1,
68+
// l2, l3>.
69+
// Then this vector stores <s1 < l1, s1 == l1 && s2 < l2, s1 == l1 &&
70+
// s2 == l2 && s3 < l3>.
71+
exprt::operandst lexicographic_individual_comparisons(lhs.size());
72+
lexicographic_individual_comparisons[0] =
73+
binary_relation_exprt(lhs[0], ID_lt, rhs[0]);
74+
for(unsigned int i = 1; i < lexicographic_individual_comparisons.size(); i++)
75+
{
76+
binary_relation_exprt component_i_less_than{lhs[i], ID_lt, rhs[i]};
77+
lexicographic_individual_comparisons[i] =
78+
and_exprt(equality_conjunctions[i - 1], component_i_less_than);
79+
}
80+
return disjunction(lexicographic_individual_comparisons);
5081
}
5182

5283
void code_contractst::check_apply_loop_contracts(
@@ -67,10 +98,11 @@ void code_contractst::check_apply_loop_contracts(
6798
loop_end = t;
6899

69100
// see whether we have an invariant and a decreases clause
70-
exprt invariant = static_cast<const exprt &>(
101+
auto invariant = static_cast<const exprt &>(
71102
loop_end->get_condition().find(ID_C_spec_loop_invariant));
72-
exprt decreases_clause = static_cast<const exprt &>(
103+
auto decreases_clause = static_cast<const exprt &>(
73104
loop_end->get_condition().find(ID_C_spec_decreases));
105+
74106
if(invariant.is_nil())
75107
{
76108
if(decreases_clause.is_nil())
@@ -92,12 +124,12 @@ void code_contractst::check_apply_loop_contracts(
92124
}
93125

94126
// Vector representing a (possibly multidimensional) decreases clause
95-
const auto decreases_clause_vector = decreases_clause.operands();
127+
const auto &decreases_clause_exprs = decreases_clause.operands();
96128

97129
// Temporary variables for storing the multidimensional decreases clause
98130
// at the start of and end of a loop body
99-
std::vector<symbol_exprt> old_temporary_variables;
100-
std::vector<symbol_exprt> new_temporary_variables;
131+
std::vector<symbol_exprt> old_decreases_vars;
132+
std::vector<symbol_exprt> new_decreases_vars;
101133

102134
// change
103135
// H: loop;
@@ -159,10 +191,10 @@ void code_contractst::check_apply_loop_contracts(
159191
// decreases clause's value before and after the loop
160192
for(const auto &clause : decreases_clause.operands())
161193
{
162-
old_temporary_variables.push_back(
194+
old_decreases_vars.push_back(
163195
new_tmp_symbol(clause.type(), loop_head->source_location, mode)
164196
.symbol_expr());
165-
new_temporary_variables.push_back(
197+
new_decreases_vars.push_back(
166198
new_tmp_symbol(clause.type(), loop_head->source_location, mode)
167199
.symbol_expr());
168200
}
@@ -171,18 +203,18 @@ void code_contractst::check_apply_loop_contracts(
171203
{
172204
// Generate: declarations of the temporary variables that stores the
173205
// multidimensional decreases clause's value before the loop
174-
for(const auto &old_temp_var : old_temporary_variables)
206+
for(const auto &old_temp_var : old_decreases_vars)
175207
{
176208
havoc_code.add(
177209
goto_programt::make_decl(old_temp_var, loop_head->source_location));
178210
}
179211

180212
// Generate: assignments to store the multidimensional decreases clause's
181213
// value before the loop
182-
for(size_t i = 0; i < old_temporary_variables.size(); i++)
214+
for(size_t i = 0; i < old_decreases_vars.size(); i++)
183215
{
184-
code_assignt old_decreases_assignment{old_temporary_variables[i],
185-
decreases_clause_vector[i]};
216+
code_assignt old_decreases_assignment{old_decreases_vars[i],
217+
decreases_clause_exprs[i]};
186218
old_decreases_assignment.add_source_location() =
187219
loop_head->source_location;
188220
converter.goto_convert(old_decreases_assignment, havoc_code, mode);
@@ -217,18 +249,18 @@ void code_contractst::check_apply_loop_contracts(
217249
// Generate: declarations of temporary variables that stores the
218250
// multidimensional decreases clause's value after one arbitrary iteration
219251
// of the loop
220-
for(const auto &new_temp_var : new_temporary_variables)
252+
for(const auto &new_temp_var : new_decreases_vars)
221253
{
222254
havoc_code.add(
223255
goto_programt::make_decl(new_temp_var, loop_head->source_location));
224256
}
225257

226258
// Generate: assignments to store the multidimensional decreases clause's
227259
// value after one iteration of the loop
228-
for(size_t i = 0; i < new_temporary_variables.size(); i++)
260+
for(size_t i = 0; i < new_decreases_vars.size(); i++)
229261
{
230-
code_assignt new_decreases_assignment{new_temporary_variables[i],
231-
decreases_clause_vector[i]};
262+
code_assignt new_decreases_assignment{new_decreases_vars[i],
263+
decreases_clause_exprs[i]};
232264
new_decreases_assignment.add_source_location() =
233265
loop_head->source_location;
234266
converter.goto_convert(new_decreases_assignment, havoc_code, mode);
@@ -238,20 +270,20 @@ void code_contractst::check_apply_loop_contracts(
238270
// after the loop is smaller than the value before the loop.
239271
// Here, we use the lexicographic order.
240272
code_assertt monotonic_decreasing_assertion{create_lexicographic_less_than(
241-
new_temporary_variables, old_temporary_variables)};
273+
new_decreases_vars, old_decreases_vars)};
242274
monotonic_decreasing_assertion.add_source_location() =
243275
loop_head->source_location;
244276
converter.goto_convert(monotonic_decreasing_assertion, havoc_code, mode);
245277
havoc_code.instructions.back().source_location.set_comment(
246278
"Check decreases clause on loop iteration");
247279

248280
// Discard the temporary variables that store decreases clause's value
249-
for(size_t i = 0; i < old_temporary_variables.size(); i++)
281+
for(size_t i = 0; i < old_decreases_vars.size(); i++)
250282
{
251283
havoc_code.add(goto_programt::make_dead(
252-
old_temporary_variables[i], loop_head->source_location));
284+
old_decreases_vars[i], loop_head->source_location));
253285
havoc_code.add(goto_programt::make_dead(
254-
new_temporary_variables[i], loop_head->source_location));
286+
new_decreases_vars[i], loop_head->source_location));
255287
}
256288
}
257289

@@ -268,52 +300,6 @@ void code_contractst::check_apply_loop_contracts(
268300
loop_end->set_condition(boolean_negate(loop_end->get_condition()));
269301
}
270302

271-
// Create a lexicographic less-than relation between two tuples of variables.
272-
// This is used in the implementation of multidimensional decreases clauses.
273-
static exprt create_lexicographic_less_than(
274-
const std::vector<symbol_exprt> &lhs,
275-
const std::vector<symbol_exprt> &rhs)
276-
{
277-
PRECONDITION(lhs.size() == rhs.size());
278-
279-
if(lhs.empty())
280-
{
281-
return false_exprt();
282-
}
283-
284-
// Store conjunctions of equalities.
285-
// For example, suppose that the two input vectors are <s1, s2, s3> and <l1,
286-
// l2, l3>.
287-
// Then this vector stores <s1 == l1, s1 == l1 && s2 == l2,
288-
// s1 == l1 && s2 == l2 && s3 == l3>.
289-
// In fact, the last element is unnecessary, so we do not create it.
290-
exprt::operandst equality_conjunctions(lhs.size());
291-
equality_conjunctions[0] = binary_relation_exprt(lhs[0], ID_equal, rhs[0]);
292-
for(unsigned int i = 1; i < equality_conjunctions.size() - 1; i++)
293-
{
294-
binary_relation_exprt component_i_equality{lhs[i], ID_equal, rhs[i]};
295-
equality_conjunctions[i] =
296-
and_exprt(equality_conjunctions[i - 1], component_i_equality);
297-
}
298-
299-
// Store inequalities between the i-th components of the input vectors
300-
// (i.e. lhs and rhs).
301-
// For example, suppose that the two input vectors are <s1, s2, s3> and <l1,
302-
// l2, l3>.
303-
// Then this vector stores <s1 < l1, s1 == l1 && s2 < l2, s1 == l1 &&
304-
// s2 == l2 && s3 < l3>.
305-
exprt::operandst lexicographic_individual_comparisons(lhs.size());
306-
lexicographic_individual_comparisons[0] =
307-
binary_relation_exprt(lhs[0], ID_lt, rhs[0]);
308-
for(unsigned int i = 1; i < lexicographic_individual_comparisons.size(); i++)
309-
{
310-
binary_relation_exprt component_i_less_than{lhs[i], ID_lt, rhs[i]};
311-
lexicographic_individual_comparisons[i] =
312-
and_exprt(equality_conjunctions[i - 1], component_i_less_than);
313-
}
314-
return disjunction(lexicographic_individual_comparisons);
315-
}
316-
317303
bool code_contractst::has_contract(const irep_idt fun_name)
318304
{
319305
const symbolt &function_symbol = ns.lookup(fun_name);

0 commit comments

Comments
 (0)