@@ -163,6 +163,38 @@ bool code_contractst::has_contract(const irep_idt fun_name)
163
163
return type.has_contract ();
164
164
}
165
165
166
+ void code_contractst::add_quantified_variable (
167
+ exprt expression, replace_symbolt &replace, irep_idt mode)
168
+ {
169
+ // If the expression is a quantified expression, this function adds
170
+ // the quantified variable to the symbol table and to the expression map
171
+
172
+ // TODO Currently only works if the contract contains only a single quantified formula
173
+ // i.e. (1) the top-level element is a quantifier formula
174
+ // and (2) there are no inner quantifier formulae
175
+ if (expression.id ()==ID_exists || expression.id ()==ID_forall)
176
+ {
177
+
178
+ // get quantified symbol
179
+ exprt tuple = expression.operands ().front ();
180
+ exprt quantified_variable = tuple.operands ().front ();
181
+ symbol_exprt quantified_symbol = to_symbol_expr (quantified_variable);
182
+
183
+ // create fresh symbol
184
+ symbolt new_symbol = get_fresh_aux_symbol (
185
+ quantified_symbol.type (),
186
+ id2string (quantified_symbol.get_identifier ()),
187
+ " tmp" ,
188
+ quantified_symbol.source_location (),
189
+ mode,
190
+ symbol_table);
191
+
192
+ // add created fresh symbol to expression map
193
+ symbol_exprt q (quantified_symbol.get_identifier (), quantified_symbol.type ());
194
+ replace.insert (q, new_symbol.symbol_expr ());
195
+ }
196
+ }
197
+
166
198
bool code_contractst::apply_function_contract (
167
199
const irep_idt &function_id,
168
200
goto_programt &goto_program,
@@ -243,26 +275,11 @@ bool code_contractst::apply_function_contract(
243
275
}
244
276
}
245
277
246
- // Replace quantified variables
247
- // TODO go at more depths
248
- // TODO Generalize
249
- if (ensures.id ()==ID_exists || ensures.id ()==ID_forall)
250
- {
251
- exprt tuple = ensures.operands ().front ();
252
- exprt quantified_variable = tuple.operands ().front ();
253
- symbol_exprt quantified_symbol = to_symbol_expr (quantified_variable);
254
-
255
- symbolt new_symbol = get_fresh_aux_symbol (
256
- quantified_symbol.type (),
257
- id2string (quantified_symbol.get_identifier ()),
258
- " tmp" ,
259
- quantified_symbol.source_location (),
260
- symbol_table.lookup_ref (function).mode ,
261
- symbol_table);
278
+ // Add quantified variables in contracts to the symbol map
279
+ irep_idt mode = symbol_table.lookup_ref (function).mode ;
280
+ code_contractst::add_quantified_variable (ensures, replace, mode);
281
+ code_contractst::add_quantified_variable (requires , replace, mode);
262
282
263
- symbol_exprt q (quantified_symbol.get_identifier (), quantified_symbol.type ());
264
- replace.insert (q, new_symbol.symbol_expr ());
265
- }
266
283
// Replace expressions in the contract components.
267
284
replace (assigns);
268
285
replace (requires );
@@ -798,6 +815,10 @@ void code_contractst::add_contract_check(
798
815
replace.insert (parameter_symbol.symbol_expr (), p);
799
816
}
800
817
818
+ // Add quantified variables in contracts to the symbol map
819
+ code_contractst::add_quantified_variable (ensures, replace, function_symbol.mode );
820
+ code_contractst::add_quantified_variable (requires , replace, function_symbol.mode );
821
+
801
822
// assume(requires)
802
823
if (requires .is_not_nil ())
803
824
{
0 commit comments