exprt summarizer_bw_termt::compute_precondition( local_SSAt &SSA, summaryt &summary, const exprt::operandst &postconditions, incremental_solvert &solver, template_generator_summaryt &template_generator, bool context_sensitive) { exprt postcond=not_exprt(conjunction(postconditions)); // compute backward summary exprt bw_transformer, bw_invariant, bw_precondition; if(!template_generator.out_vars().empty()) { ssa_analyzert analyzer; analyzer.set_message_handler(get_message_handler()); analyzer(solver, SSA, postcond, template_generator); analyzer.get_result(bw_transformer, template_generator.inout_vars()); analyzer.get_result(bw_invariant, template_generator.loop_vars()); analyzer.get_result(bw_precondition, template_generator.out_vars()); // statistics solver_instances+=analyzer.get_number_of_solver_instances(); solver_calls+=analyzer.get_number_of_solver_calls(); } #if 1 // TODO: yet another workaround for ssa_analyzer // not being able to handle empty templates properly else { solver << SSA; solver.new_context(); solver << SSA.get_enabling_exprs(); solver << postcond; exprt result=true_exprt(); if(solver()==decision_proceduret::D_UNSATISFIABLE) result=false_exprt(); solver.pop_context(); bw_transformer=result; bw_invariant=result; bw_precondition=result; } #endif bw_transformer=not_exprt(bw_transformer); bw_invariant=not_exprt(bw_invariant); bw_precondition=not_exprt(bw_precondition); if(context_sensitive && !summary.bw_postcondition.is_true()) { bw_transformer=implies_exprt(summary.bw_postcondition, bw_transformer); bw_invariant=implies_exprt(summary.bw_postcondition, bw_invariant); bw_precondition=implies_exprt(summary.bw_postcondition, bw_precondition); } // join // TODO: should go into summaryt if(summary.bw_transformer.is_nil()) { summary.bw_transformer=bw_transformer; summary.bw_invariant=bw_invariant; summary.bw_precondition=bw_precondition; } else { summary.bw_transformer=or_exprt(summary.bw_transformer, bw_transformer); summary.bw_invariant=or_exprt(summary.bw_invariant, bw_invariant); summary.bw_precondition=or_exprt(summary.bw_precondition, bw_precondition); } return bw_precondition; }
void ssa_analyzert::operator()( incremental_solvert &solver, local_SSAt &SSA, const exprt &precondition, template_generator_baset &template_generator) { if(SSA.goto_function.body.instructions.empty()) return; solver << SSA; SSA.mark_nodes(); solver.new_context(); solver << SSA.get_enabling_exprs(); // add precondition (or conjunction of asssertion in backward analysis) solver << precondition; domain=template_generator.domain(); // get strategy solver from options strategy_solver_baset *strategy_solver; if(template_generator.options.get_bool_option("compute-ranking-functions")) { if(template_generator.options.get_bool_option( "monolithic-ranking-function")) { strategy_solver=new ranking_solver_enumerationt( *static_cast<linrank_domaint *>(domain), solver, SSA.ns, template_generator.options.get_unsigned_int_option( "max-inner-ranking-iterations")); result=new linrank_domaint::templ_valuet(); } else { strategy_solver=new lexlinrank_solver_enumerationt( *static_cast<lexlinrank_domaint *>(domain), solver, SSA.ns, template_generator.options.get_unsigned_int_option( "lexicographic-ranking-function"), template_generator.options.get_unsigned_int_option( "max-inner-ranking-iterations")); result=new lexlinrank_domaint::templ_valuet(); } } else if(template_generator.options.get_bool_option("equalities")) { strategy_solver=new strategy_solver_equalityt( *static_cast<equality_domaint *>(domain), solver, SSA.ns); result=new equality_domaint::equ_valuet(); } else { if(template_generator.options.get_bool_option("enum-solver")) { result=new tpolyhedra_domaint::templ_valuet(); strategy_solver=new strategy_solver_enumerationt( *static_cast<tpolyhedra_domaint *>(domain), solver, SSA.ns); } else if(template_generator.options.get_bool_option("predabs-solver")) { result=new predabs_domaint::templ_valuet(); strategy_solver=new strategy_solver_predabst( *static_cast<predabs_domaint *>(domain), solver, SSA.ns); } else if(template_generator.options.get_bool_option("binsearch-solver")) { result=new tpolyhedra_domaint::templ_valuet(); strategy_solver=new BINSEARCH_SOLVER; } else if(template_generator.options.get_bool_option("max-solver")) { result=new predabs_domaint::templ_valuet(); strategy_solver=new max_solver_binsearcht( *static_cast<tpolyhedra_domaint *>(domain), solver, SSA.ns); } else assert(false); } strategy_solver->set_message_handler(get_message_handler()); // initialize inv domain->initialize(*result); // iterate while(strategy_solver->iterate(*result)) {} solver.pop_context(); // statistics solver_instances+=strategy_solver->get_number_of_solver_instances(); solver_calls+=strategy_solver->get_number_of_solver_calls(); solver_instances+=strategy_solver->get_number_of_solver_instances(); delete strategy_solver; }
bool summarizer_bw_termt::bootstrap_preconditions( local_SSAt &SSA, summaryt &summary, incremental_solvert &solver, template_generator_rankingt &template_generator1, template_generator_summaryt &template_generator2, exprt &termination_argument) { // bootstrap with a concrete model for input variables const domaint::var_sett &invars=template_generator2.out_vars(); solver.new_context(); unsigned number_bootstraps=0; termination_argument=true_exprt(); exprt::operandst checked_candidates; while(number_bootstraps++<MAX_BOOTSTRAP_ATTEMPTS) { // find new ones solver << not_exprt(summary.bw_precondition); // last node should be reachable solver << SSA.guard_symbol(--SSA.goto_function.body.instructions.end()); // statistics solver_calls++; // solve exprt precondition; if(solver()==decision_proceduret::D_SATISFIABLE) { exprt::operandst c; for(domaint::var_sett::const_iterator it=invars.begin(); it!=invars.end(); it++) { c.push_back(equal_exprt(*it, solver.solver->get(*it))); } precondition=conjunction(c); debug() << "bootstrap model for precondition: " << from_expr(SSA.ns, "", precondition) << eom; solver.pop_context(); } else // whole precondition space covered { solver.pop_context(); break; } termination_argument= compute_termination_argument( SSA, precondition, solver, template_generator1); if(summarizer_fw_termt::check_termination_argument( termination_argument)==YES) { return true; } solver.new_context(); checked_candidates.push_back(precondition); solver << not_exprt(disjunction(checked_candidates)); // next one, please! } return false; }