void summarizer_bwt::do_summary(const function_namet &function_name, local_SSAt &SSA, const summaryt &old_summary, summaryt &summary, bool context_sensitive) { bool sufficient = options.get_bool_option("sufficient"); status() << "Computing preconditions" << eom; // solver incremental_solvert &solver = ssa_db.get_solver(function_name); solver.set_message_handler(get_message_handler()); template_generator_summaryt template_generator( options,ssa_db,ssa_unwinder.get(function_name)); template_generator.set_message_handler(get_message_handler()); template_generator(solver.next_domain_number(),SSA,false); exprt::operandst c; c.push_back(old_summary.fw_precondition); c.push_back(old_summary.fw_invariant); c.push_back(ssa_inliner.get_summaries(SSA)); //forward summaries exprt::operandst postcond; ssa_inliner.get_summaries(SSA,false,postcond,c); //backward summaries collect_postconditions(function_name, SSA, summary, postcond,sufficient); if(!sufficient) { c.push_back(conjunction(postcond)); } else //sufficient { c.push_back(not_exprt(conjunction(postcond))); } if(!template_generator.out_vars().empty()) { ssa_analyzert analyzer; analyzer.set_message_handler(get_message_handler()); analyzer(solver,SSA,conjunction(c),template_generator); analyzer.get_result(summary.bw_transformer,template_generator.inout_vars()); analyzer.get_result(summary.bw_invariant,template_generator.loop_vars()); analyzer.get_result(summary.bw_precondition,template_generator.out_vars()); //statistics solver_instances += analyzer.get_number_of_solver_instances(); solver_calls += analyzer.get_number_of_solver_calls(); } else // TODO: yet another workaround for ssa_analyzer not being able to handle empty templates properly { solver << SSA; solver.new_context(); solver << SSA.get_enabling_exprs(); solver << conjunction(c); exprt result = true_exprt(); if(solver()==decision_proceduret::D_UNSATISFIABLE) result = false_exprt(); solver.pop_context(); summary.bw_transformer = result; summary.bw_invariant = result; summary.bw_precondition = result; } if(sufficient) { summary.bw_transformer = not_exprt(summary.bw_transformer); summary.bw_invariant = not_exprt(summary.bw_invariant); summary.bw_precondition = not_exprt(summary.bw_precondition); } if(context_sensitive && !summary.bw_postcondition.is_true()) { summary.bw_transformer = implies_exprt(summary.bw_postcondition,summary.bw_transformer); summary.bw_invariant = implies_exprt(summary.bw_postcondition,summary.bw_invariant); summary.bw_precondition = implies_exprt(summary.bw_postcondition,summary.bw_precondition); } }
exprt summarizer_bwt::compute_calling_context2( const function_namet &function_name, local_SSAt &SSA, summaryt old_summary, local_SSAt::nodest::const_iterator n_it, local_SSAt::nodet::function_callst::const_iterator f_it, const exprt &postcondition, bool sufficient) { assert(f_it->function().id()==ID_symbol); //no function pointers irep_idt fname = to_symbol_expr(f_it->function()).get_identifier(); status() << "Computing calling context for function " << fname << eom; // solver incremental_solvert &solver = ssa_db.get_solver(function_name); solver.set_message_handler(get_message_handler()); //analyze ssa_analyzert analyzer; analyzer.set_message_handler(get_message_handler()); template_generator_callingcontextt template_generator( options,ssa_db,ssa_unwinder.get(function_name)); template_generator.set_message_handler(get_message_handler()); template_generator(solver.next_domain_number(),SSA,n_it,f_it,false); // collect globals at call site std::map<local_SSAt::nodet::function_callst::const_iterator, local_SSAt::var_sett> cs_globals_out; SSA.get_globals(n_it->location,cs_globals_out[f_it],false); exprt::operandst c; c.push_back(old_summary.fw_precondition); c.push_back(old_summary.fw_invariant); c.push_back(ssa_inliner.get_summaries(SSA)); //forward summaries exprt::operandst postcond; ssa_inliner.get_summaries(SSA,false,postcond,c); //backward summaries old_summary.bw_postcondition = postcondition; //that's a bit awkward collect_postconditions(function_name, SSA, old_summary, postcond,sufficient); if(!sufficient) { c.push_back(conjunction(postcond)); } else //sufficient { c.push_back(not_exprt(conjunction(postcond))); } analyzer(solver,SSA,conjunction(c),template_generator); // set preconditions local_SSAt &fSSA = ssa_db.get(fname); exprt postcondition_call; analyzer.get_result(postcondition_call, template_generator.callingcontext_vars()); ssa_inliner.rename_to_callee(f_it, fSSA.params, cs_globals_out[f_it],fSSA.globals_out, postcondition_call); if(sufficient && !postcondition_call.is_true()) //TODO: this should actually be handled by ssa_analyzer using a "guard-reachabiliity-only" analysis if template is empty { postcondition_call = not_exprt(postcondition_call); } debug() << "Backward calling context for " << from_expr(SSA.ns, "", *f_it) << ": " << from_expr(SSA.ns, "", postcondition_call) << eom; //statistics solver_instances += analyzer.get_number_of_solver_instances(); solver_calls += analyzer.get_number_of_solver_calls(); return postcondition_call; }
void summarizer_fwt::do_summary(const function_namet &function_name, local_SSAt &SSA, summaryt &summary, exprt cond, bool context_sensitive) { status() << "Computing summary" << eom; // solver incremental_solvert &solver = ssa_db.get_solver(function_name); solver.set_message_handler(get_message_handler()); //analyze ssa_analyzert analyzer; analyzer.set_message_handler(get_message_handler()); template_generator_summaryt template_generator( options,ssa_db,ssa_unwinder.get(function_name)); template_generator.set_message_handler(get_message_handler()); template_generator(solver.next_domain_number(),SSA,true); exprt::operandst conds; conds.reserve(5); conds.push_back(cond); conds.push_back(summary.fw_precondition); conds.push_back(ssa_inliner.get_summaries(SSA)); #ifdef REUSE_INVARIANTS if(summary_db.exists(function_name)) //reuse existing invariants { const exprt &old_inv = summary_db.get(function_name).fw_invariant; exprt inv = ssa_unwinder.get(function_name).rename_invariant(old_inv); conds.push_back(inv); #if 0 std::ostringstream out; out << "(original inv)" << from_expr(SSA.ns,"",old_inv) << "\n"; debug() << out.str() << eom; out << "(renamed inv)" << from_expr(SSA.ns,"",inv)<<"\n"; debug() << out.str() << eom; #endif } #endif cond = conjunction(conds); bool assertions_check = false; //options.get_bool_option("k-induction"); bool assertions_hold = analyzer(solver,SSA,cond,template_generator, assertions_check); if(assertions_hold) { analyzer.get_result(summary.fw_transformer,template_generator.inout_vars()); analyzer.get_result(summary.fw_invariant,template_generator.loop_vars()); #ifdef SHOW_WHOLE_RESULT // to see all the custom template values exprt whole_result; analyzer.get_result(whole_result,template_generator.all_vars()); debug() << "whole result: " << from_expr(SSA.ns,"",whole_result) << eom; #endif if(context_sensitive && !summary.fw_precondition.is_true()) { summary.fw_transformer = implies_exprt(summary.fw_precondition,summary.fw_transformer); summary.fw_invariant = implies_exprt(summary.fw_precondition,summary.fw_invariant); } } else //!assertions_hold { nonpassed_assertions = true; summary.nonpassed_assertions = analyzer.get_nonpassed_assertions(); } solver_instances += analyzer.get_number_of_solver_instances(); solver_calls += analyzer.get_number_of_solver_calls(); }