15
15
#include < queue>
16
16
17
17
#include < util/std_expr.h>
18
+ #include < util/expr_util.h>
19
+ #include < util/format_expr.h>
18
20
#include < goto-programs/initialize_goto_model.h>
19
21
#include < goto-programs/link_goto_model.h>
20
22
@@ -206,7 +208,6 @@ const std::unordered_set<irep_idt> find_index_symbols(const goto_functiont &goto
206
208
if (it->is_function_call ())
207
209
{
208
210
const code_function_callt fc = it->get_function_call ();
209
- code_function_callt::argumentst new_arguments = fc.arguments ();
210
211
exprt new_lhs = fc.lhs ();
211
212
etr.add_expr (fc.lhs ());
212
213
@@ -232,7 +233,7 @@ void complete_abst_spec(const goto_functiont& goto_function, abstraction_spect &
232
233
{
233
234
for (const auto &ent: spec.get_abst_arrays ())
234
235
for (irep_idt index_name: find_index_symbols (goto_function, ent.first ))
235
- if (spec.get_abst_indices ().find (index_name) ! = spec.get_abst_indices ().end ())
236
+ if (spec.get_abst_indices ().find (index_name) = = spec.get_abst_indices ().end ())
236
237
spec.insert_entity (index_name, true );
237
238
}
238
239
}
@@ -274,18 +275,16 @@ find_function_calls(irep_idt func_name, goto_modelt &goto_model, const abstracti
274
275
// it is a function call that we potentially need to abstract
275
276
const code_function_callt fc = it->get_function_call ();
276
277
const irep_idt &new_func_name = to_symbol_expr (fc.function ()).get_identifier ();
278
+ const goto_functiont &new_function = goto_model.get_goto_function (new_func_name);
277
279
std::unordered_map<irep_idt, irep_idt> map;
278
280
for (size_t i=0 ; i<fc.arguments ().size (); i++)
279
281
{
280
282
// for each argument, we check whether we need to abstract it.
281
283
const exprt &arg = fc.arguments ()[i];
282
284
irep_idt symbol_name = check_expr_is_symbol (arg);
283
285
if (symbol_name != " " && abst_spec.has_entity (symbol_name))
284
- {
285
286
// if so, we push it into the map
286
- const goto_functiont &new_function = goto_model.get_goto_function (new_func_name);
287
287
map.insert ({symbol_name, new_function.parameter_identifiers [i]});
288
- }
289
288
}
290
289
if (!map.empty ()) // if map is not empty, we create a new entry in the result
291
290
result.push_back (std::make_tuple (new_func_name, map));
@@ -340,11 +339,39 @@ calculate_complete_abst_specs_for_funcs(goto_modelt &goto_model, abstraction_spe
340
339
complete_abst_spec (goto_model.get_goto_function (new_func_name), new_func_abst);
341
340
function_spec_map.insert ({new_func_name, new_func_abst});
342
341
}
342
+ else
343
+ {
344
+ // we need to compare if the structure is the same
345
+ abstraction_spect new_func_abst = function_spec_map[current_func_name].update_abst_spec (current_func_name, new_func_name, name_pairs);
346
+ if (!new_func_abst.compare_shape (function_spec_map[new_func_name]))
347
+ throw " Same function abstracted with different shape!" ;
348
+ }
343
349
}
344
350
}
345
351
return function_spec_map;
346
352
}
347
353
354
+ bool contains_an_abstracted_entity (const exprt &expr, const abstraction_spect &abst_spec)
355
+ {
356
+ struct match_abst_symbolt
357
+ {
358
+ match_abst_symbolt (const abstraction_spect &_abst_spec) : abst_spec(_abst_spec) {}
359
+ // check if expr is an entity symbol that we want to abstract
360
+ bool operator ()(const exprt &expr)
361
+ {
362
+ irep_idt symbol_name = check_expr_is_symbol (expr);
363
+ return symbol_name != " " && abst_spec.has_entity (symbol_name);
364
+ }
365
+ protected:
366
+ // we assume this abst_spec's life span covers
367
+ // the life span of the match_abst_symbolt object
368
+ const abstraction_spect &abst_spec;
369
+ };
370
+ match_abst_symbolt match_abst_symbol (abst_spec);
371
+ return has_subexpr (expr, match_abst_symbol);
372
+
373
+ }
374
+
348
375
void abstract_goto_program (goto_modelt &goto_model, abstraction_spect &abst_spec)
349
376
{
350
377
// A couple of spects are initialized from the json file. We should go from there and insert spects to other functions
@@ -353,6 +380,37 @@ void abstract_goto_program(goto_modelt &goto_model, abstraction_spect &abst_spec
353
380
for (auto &p: function_spec_map)
354
381
{
355
382
std::cout << " =========== " << p.first << " ===========" << std::endl;
383
+ std::cout << " ----------- " << " Entities to be abstracted" << " -----------" << std::endl;
356
384
p.second .print_entities ();
385
+ std::cout << " ----------- " << " Exprs containing the above entities" << " -----------" << std::endl;
386
+ const goto_functiont &goto_function = goto_model.get_goto_function (p.first );
387
+ const abstraction_spect &abst_spec = p.second ;
388
+ forall_goto_program_instructions (it, goto_function.body )
389
+ {
390
+ // go through conditions
391
+ if (it->has_condition ())
392
+ if (contains_an_abstracted_entity (it->get_condition (), abst_spec))
393
+ format_rec (std::cout, it->get_condition ()) << std::endl;
394
+
395
+ // go through all expressions
396
+ if (it->is_function_call ())
397
+ {
398
+ const code_function_callt fc = it->get_function_call ();
399
+ if (contains_an_abstracted_entity (fc.lhs (), abst_spec))
400
+ format_rec (std::cout, fc.lhs ()) << std::endl;
401
+
402
+ for (const auto &arg : fc.arguments ())
403
+ if (contains_an_abstracted_entity (arg, abst_spec))
404
+ format_rec (std::cout, arg) << std::endl;
405
+ }
406
+ else if (it->is_assign ())
407
+ {
408
+ const code_assignt as = it->get_assign ();
409
+ if (contains_an_abstracted_entity (as.lhs (), abst_spec))
410
+ format_rec (std::cout, as.lhs ()) << std::endl;
411
+ if (contains_an_abstracted_entity (as.rhs (), abst_spec))
412
+ format_rec (std::cout, as.rhs ()) << std::endl;
413
+ }
414
+ }
357
415
}
358
416
}
0 commit comments