@@ -38,15 +38,46 @@ Date: February 2016
38
38
// This is used in the implementation of multidimensional decreases clauses.
39
39
static exprt create_lexicographic_less_than (
40
40
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)
44
42
{
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);
50
81
}
51
82
52
83
void code_contractst::check_apply_loop_contracts (
@@ -67,10 +98,11 @@ void code_contractst::check_apply_loop_contracts(
67
98
loop_end = t;
68
99
69
100
// see whether we have an invariant and a decreases clause
70
- exprt invariant = static_cast <const exprt &>(
101
+ auto invariant = static_cast <const exprt &>(
71
102
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 &>(
73
104
loop_end->get_condition ().find (ID_C_spec_decreases));
105
+
74
106
if (invariant.is_nil ())
75
107
{
76
108
if (decreases_clause.is_nil ())
@@ -92,12 +124,12 @@ void code_contractst::check_apply_loop_contracts(
92
124
}
93
125
94
126
// 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 ();
96
128
97
129
// Temporary variables for storing the multidimensional decreases clause
98
130
// 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 ;
101
133
102
134
// change
103
135
// H: loop;
@@ -159,10 +191,10 @@ void code_contractst::check_apply_loop_contracts(
159
191
// decreases clause's value before and after the loop
160
192
for (const auto &clause : decreases_clause.operands ())
161
193
{
162
- old_temporary_variables .push_back (
194
+ old_decreases_vars .push_back (
163
195
new_tmp_symbol (clause.type (), loop_head->source_location , mode)
164
196
.symbol_expr ());
165
- new_temporary_variables .push_back (
197
+ new_decreases_vars .push_back (
166
198
new_tmp_symbol (clause.type (), loop_head->source_location , mode)
167
199
.symbol_expr ());
168
200
}
@@ -171,18 +203,18 @@ void code_contractst::check_apply_loop_contracts(
171
203
{
172
204
// Generate: declarations of the temporary variables that stores the
173
205
// 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 )
175
207
{
176
208
havoc_code.add (
177
209
goto_programt::make_decl (old_temp_var, loop_head->source_location ));
178
210
}
179
211
180
212
// Generate: assignments to store the multidimensional decreases clause's
181
213
// 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++)
183
215
{
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]};
186
218
old_decreases_assignment.add_source_location () =
187
219
loop_head->source_location ;
188
220
converter.goto_convert (old_decreases_assignment, havoc_code, mode);
@@ -217,18 +249,18 @@ void code_contractst::check_apply_loop_contracts(
217
249
// Generate: declarations of temporary variables that stores the
218
250
// multidimensional decreases clause's value after one arbitrary iteration
219
251
// of the loop
220
- for (const auto &new_temp_var : new_temporary_variables )
252
+ for (const auto &new_temp_var : new_decreases_vars )
221
253
{
222
254
havoc_code.add (
223
255
goto_programt::make_decl (new_temp_var, loop_head->source_location ));
224
256
}
225
257
226
258
// Generate: assignments to store the multidimensional decreases clause's
227
259
// 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++)
229
261
{
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]};
232
264
new_decreases_assignment.add_source_location () =
233
265
loop_head->source_location ;
234
266
converter.goto_convert (new_decreases_assignment, havoc_code, mode);
@@ -238,20 +270,20 @@ void code_contractst::check_apply_loop_contracts(
238
270
// after the loop is smaller than the value before the loop.
239
271
// Here, we use the lexicographic order.
240
272
code_assertt monotonic_decreasing_assertion{create_lexicographic_less_than (
241
- new_temporary_variables, old_temporary_variables )};
273
+ new_decreases_vars, old_decreases_vars )};
242
274
monotonic_decreasing_assertion.add_source_location () =
243
275
loop_head->source_location ;
244
276
converter.goto_convert (monotonic_decreasing_assertion, havoc_code, mode);
245
277
havoc_code.instructions .back ().source_location .set_comment (
246
278
" Check decreases clause on loop iteration" );
247
279
248
280
// 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++)
250
282
{
251
283
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 ));
253
285
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 ));
255
287
}
256
288
}
257
289
@@ -268,52 +300,6 @@ void code_contractst::check_apply_loop_contracts(
268
300
loop_end->set_condition (boolean_negate (loop_end->get_condition ()));
269
301
}
270
302
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
-
317
303
bool code_contractst::has_contract (const irep_idt fun_name)
318
304
{
319
305
const symbolt &function_symbol = ns.lookup (fun_name);
0 commit comments