void acdl_analyze_conflict_baset::get_conflict_clause (const local_SSAt &SSA, acdl_conflict_grapht &graph, acdl_domaint::valuet &conf_clause) { // PROPOSITIONAL proof if(last_proof==PROPOSITIONAL) { assert(conflicting_clause!=-1); conf_clause=learned_clauses[conflicting_clause]; #ifdef DEBUG std::cout << "Conflict is purely Propositional" << std::endl; #endif } // conflict is caused by Abstract Interpretation proof else if(last_proof==ABSINT) { acdl_domaint::valuet reason; get_ai_reason(SSA, graph, reason); // print the reason #ifdef DEBUG std::cout << "Reason: " << from_expr(SSA.ns, "", disjunction(reason)) << std::endl; #endif for(acdl_domaint::valuet::iterator it=reason.begin(); it!=reason.end(); it++) { negate(*it, conf_clause); } #ifdef DEBUG std::cout << "Conflict is purely from Abstract Interpretation Proof" << std::endl; #endif } #ifdef DEBUG std::cout << "Conflict at decision level is " << graph.current_level <<std::endl; #endif if(conf_clause.size()==0) backtrack_level=-1; else find_uip(SSA, graph, conf_clause, graph.current_level); // print the conflict clause #ifdef DEBUG std::cout << "learnt clause: " << from_expr(SSA.ns, "", disjunction(conf_clause)) << std::endl; #endif }
void cover_goals_extt::constraint() { exprt::operandst disjuncts; for(std::list<cover_goalt>::const_iterator g_it=goals.begin(); g_it!=goals.end(); g_it++) if(!g_it->covered && !g_it->condition.is_false()) disjuncts.push_back(literal_exprt(g_it->condition)); // this is 'false' if there are no disjuncts solver << disjunction(disjuncts); }
void cover_goalst::constraint() { exprt::operandst disjuncts; // cover at least one unknown goal for(std::list<goalt>::const_iterator g_it=goals.begin(); g_it!=goals.end(); g_it++) if(g_it->status==goalt::statust::UNKNOWN && !g_it->condition.is_false()) disjuncts.push_back(literal_exprt(g_it->condition)); // this is 'false' if there are no disjuncts prop_conv.set_to_true(disjunction(disjuncts)); }
bool strategy_solver_binsearch3t::iterate(invariantt &_inv) { tpolyhedra_domaint::templ_valuet &inv= static_cast<tpolyhedra_domaint::templ_valuet &>(_inv); bool improved=false; solver.new_context(); // for improvement check exprt inv_expr=tpolyhedra_domain.to_pre_constraints(inv); #if 0 debug() << "improvement check: " << eom; debug() << "pre-inv: " << from_expr(ns, "", inv_expr) << eom; #endif solver << inv_expr; exprt::operandst strategy_cond_exprs; tpolyhedra_domain.make_not_post_constraints( inv, strategy_cond_exprs, strategy_value_exprs); strategy_cond_literals.resize(strategy_cond_exprs.size()); #if 0 debug() << "post-inv: "; #endif for(std::size_t i=0; i<strategy_cond_exprs.size(); i++) { #if 0 debug() << (i>0 ? " || " : "") << from_expr(ns, "", strategy_cond_exprs[i]); #endif strategy_cond_literals[i]=solver.convert(strategy_cond_exprs[i]); strategy_cond_exprs[i]=literal_exprt(strategy_cond_literals[i]); } debug() << eom; solver << disjunction(strategy_cond_exprs); #if 0 debug() << "solve(): "; #endif std::set<tpolyhedra_domaint::rowt> improve_rows; std::map<tpolyhedra_domaint::rowt, symbol_exprt> symb_values; std::map<tpolyhedra_domaint::rowt, constant_exprt> lower_values; exprt::operandst blocking_constraint; bool improved_from_neginf=false; while(solver()==decision_proceduret::D_SATISFIABLE) // improvement check { #if 0 debug() << "SAT" << eom; #endif improved=true; std::size_t row=0; for(; row<strategy_cond_literals.size(); row++) { if(solver.l_get(strategy_cond_literals[row]).is_true()) { #if 1 debug() << "improve row " << row << eom; #endif improve_rows.insert(row); symb_values[row]=tpolyhedra_domain.get_row_symb_value(row); lower_values[row]= simplify_const(solver.get(strategy_value_exprs[row])); blocking_constraint.push_back( literal_exprt(!strategy_cond_literals[row])); if(tpolyhedra_domain.is_row_value_neginf( tpolyhedra_domain.get_row_value(row, inv))) improved_from_neginf=true; } } solver << conjunction(blocking_constraint); } solver.pop_context(); // improvement check if(!improved) // done { #if 0 debug() << "UNSAT" << eom; #endif return improved; } // symbolic value system exprt pre_inv_expr= tpolyhedra_domain.to_symb_pre_constraints(inv, improve_rows); exprt post_inv_expr= tpolyhedra_domain.to_symb_post_constraints(improve_rows); assert(lower_values.size()>=1); std::map<tpolyhedra_domaint::rowt, symbol_exprt>::iterator it=symb_values.begin(); exprt _lower=lower_values[it->first]; #if 1 debug() << "update row " << it->first << ": " << from_expr(ns, "", lower_values[it->first]) << eom; #endif tpolyhedra_domain.set_row_value(it->first, lower_values[it->first], inv); exprt _upper= tpolyhedra_domain.get_max_row_value(it->first); exprt sum=it->second; for(++it; it!=symb_values.end(); ++it) { sum=plus_exprt(sum, it->second); _upper=plus_exprt(_upper, tpolyhedra_domain.get_max_row_value(it->first)); _lower=plus_exprt(_lower, lower_values[it->first]); #if 1 debug() << "update row " << it->first << ": " << from_expr(ns, "", lower_values[it->first]) << eom; #endif tpolyhedra_domain.set_row_value(it->first, lower_values[it->first], inv); } // do not solve system if we have just reached a new loop // (the system will be very large!) if(improved_from_neginf) return improved; solver.new_context(); // symbolic value system solver << pre_inv_expr; solver << post_inv_expr; #if 1 debug() << "symbolic value system: " << eom; debug() << "pre-inv: " << from_expr(ns, "", pre_inv_expr) << eom; debug() << "post-inv: " << from_expr(ns, "", post_inv_expr) << eom; #endif extend_expr_types(sum); extend_expr_types(_upper); extend_expr_types(_lower); tpolyhedra_domaint::row_valuet upper=simplify_const(_upper); tpolyhedra_domaint::row_valuet lower=simplify_const(_lower); assert(sum.type()==upper.type()); assert(sum.type()==lower.type()); symbol_exprt sum_bound( SUM_BOUND_VAR+i2string(sum_bound_counter++), sum.type()); solver << equal_exprt(sum_bound, sum); #if 1 debug() << from_expr(ns, "", equal_exprt(sum_bound, sum)) << eom; #endif while(tpolyhedra_domain.less_than(lower, upper)) { tpolyhedra_domaint::row_valuet middle= tpolyhedra_domain.between(lower, upper); if(!tpolyhedra_domain.less_than(lower, middle)) middle=upper; // row_symb_value >= middle assert(sum_bound.type()==middle.type()); exprt c=binary_relation_exprt(sum_bound, ID_ge, middle); #if 1 debug() << "upper: " << from_expr(ns, "", upper) << eom; debug() << "middle: " << from_expr(ns, "", middle) << eom; debug() << "lower: " << from_expr(ns, "", lower) << eom; #endif solver.new_context(); // binary search iteration #if 1 debug() << "constraint: " << from_expr(ns, "", c) << eom; #endif solver << c; if(solver()==decision_proceduret::D_SATISFIABLE) { #if 0 debug() << "SAT" << eom; #endif lower=middle; for(const auto &sv : symb_values) { #if 1 debug() << "update row " << sv.first << " " << from_expr(ns, "", sv.second) << ": "; #endif constant_exprt lower_row= simplify_const(solver.get(sv.second)); #if 1 debug() << from_expr(ns, "", lower_row) << eom; #endif tpolyhedra_domain.set_row_value(sv.first, lower_row, inv); } } else { #if 0 debug() << "UNSAT" << eom; #endif if(!tpolyhedra_domain.less_than(middle, upper)) middle=lower; upper=middle; } solver.pop_context(); // binary search iteration } solver.pop_context(); // symbolic value system return improved; }
void symex_target_equationt::convert_assertions( prop_convt &prop_conv) { // we find out if there is only _one_ assertion, // which allows for a simpler formula unsigned number_of_assertions=count_assertions(); if(number_of_assertions==0) return; if(number_of_assertions==1) { for(auto & it : SSA_steps) { if(it.is_assert()) { prop_conv.set_to_false(it.cond_expr); it.cond_literal=const_literal(false); return; // prevent further assumptions! } else if(it.is_assume()) prop_conv.set_to_true(it.cond_expr); } assert(false); // unreachable } // We do (NOT a1) OR (NOT a2) ... // where the a's are the assertions or_exprt::operandst disjuncts; disjuncts.reserve(number_of_assertions); exprt assumption=true_exprt(); for(auto & it : SSA_steps) { if(it.is_assert()) { implies_exprt implication( assumption, it.cond_expr); // do the conversion it.cond_literal=prop_conv.convert(implication); // store disjunct disjuncts.push_back(literal_exprt(!it.cond_literal)); } else if(it.is_assume()) { // the assumptions have been converted before // avoid deep nesting of ID_and expressions if(assumption.id()==ID_and) assumption.copy_to_operands(literal_exprt(it.cond_literal)); else assumption= and_exprt(assumption, literal_exprt(it.cond_literal)); } } // the below is 'true' if there are no assertions prop_conv.set_to_true(disjunction(disjuncts)); }
void local_SSAt::build_guard(locationt loc) { const guard_mapt::entryt &entry=guard_map[loc]; // anything to be built? if(!entry.has_guard) return; exprt::operandst sources; // the very first 'loc' trivially gets 'true' as source if(loc==goto_function.body.instructions.begin()) sources.push_back(true_exprt()); for(guard_mapt::incomingt::const_iterator i_it=entry.incoming.begin(); i_it!=entry.incoming.end(); i_it++) { const guard_mapt::edget &edge=*i_it; exprt source; // might be backwards branch taken edge if(edge.is_branch_taken() && edge.from->is_backwards_goto()) { // The loop selector indicates whether the path comes from // above (entering the loop) or below (iterating). // By convention, we use the loop select symbol for the location // of the backwards goto. symbol_exprt loop_select= name(guard_symbol(), LOOP_SELECT, edge.from); #if 0 source=false_exprt(); #else // need constraing for edge.cond source=loop_select; #endif } else { // the other cases are basically similar symbol_exprt gs=name(guard_symbol(), OUT, edge.guard_source); exprt cond; if(edge.is_branch_taken() || edge.is_assume() || edge.is_function_call()) cond=cond_symbol(edge.from); else if(edge.is_branch_not_taken()) cond=boolean_negate(cond_symbol(edge.from)); else if(edge.is_successor()) cond=true_exprt(); else assert(false); source=and_exprt(gs, cond); } sources.push_back(source); } // the below produces 'false' if there is no source exprt rhs=disjunction(sources); equal_exprt equality(guard_symbol(loc), rhs); nodes[loc].equalities.push_back(equality); }
bool strategy_solver_binsearcht::iterate(invariantt &_inv) { tpolyhedra_domaint::templ_valuet &inv= static_cast<tpolyhedra_domaint::templ_valuet &>(_inv); bool improved=false; solver.new_context(); // for improvement check exprt inv_expr=tpolyhedra_domain.to_pre_constraints(inv); #if 0 debug() << "improvement check: " << eom; debug() << "pre-inv: " << from_expr(ns, "", inv_expr) << eom; #endif solver << inv_expr; exprt::operandst strategy_cond_exprs; tpolyhedra_domain.make_not_post_constraints( inv, strategy_cond_exprs, strategy_value_exprs); strategy_cond_literals.resize(strategy_cond_exprs.size()); #if 0 debug() << "post-inv: "; #endif for(std::size_t i=0; i<strategy_cond_exprs.size(); i++) { #if 0 debug() << (i>0 ? " || " : "") << from_expr(ns, "", strategy_cond_exprs[i]); #endif strategy_cond_literals[i]=solver.convert(strategy_cond_exprs[i]); // solver.set_frozen(strategy_cond_literals[i]); strategy_cond_exprs[i]=literal_exprt(strategy_cond_literals[i]); } #if 0 debug() << eom; #endif solver << or_exprt(disjunction(strategy_cond_exprs), literal_exprt(assertion_check)); #if 0 debug() << "solve(): "; #endif if(solver()==decision_proceduret::D_SATISFIABLE) // improvement check { #if 0 debug() << "SAT" << eom; #endif #if 0 for(std::size_t i=0; i<solver.formula.size(); i++) { debug() << "literal: " << solver.formula[i] << " " << solver.l_get(solver.formula[i]) << eom; } for(std::size_t i=0; i<tpolyhedra_domain.template_size(); i++) { exprt c=tpolyhedra_domain.get_row_post_constraint(i, inv[i]); debug() << "cond: " << from_expr(ns, "", c) << " " << from_expr(ns, "", solver.get(c)) << eom; debug() << "expr: " << from_expr(ns, "", strategy_value_exprs[i]) << " " << from_expr( ns, "", simplify_const(solver.get(strategy_value_exprs[i]))) << eom; debug() << "guards: " << from_expr(ns, "", tpolyhedra_domain.templ[i].pre_guard) << " " << from_expr( ns, "", solver.get(tpolyhedra_domain.templ[i].pre_guard)) << eom; debug() << "guards: " << from_expr(ns, "", tpolyhedra_domain.templ[i].post_guard) << " " << from_expr( ns, "", solver.get(tpolyhedra_domain.templ[i].post_guard)) << eom; } #endif std::size_t row=0; for(; row<strategy_cond_literals.size(); row++) { if(solver.l_get(strategy_cond_literals[row]).is_true()) break; // we've found a row to improve } if(row==strategy_cond_literals.size()) { // No, we haven't found one. // This can only happen if the assertions failed. solver.pop_context(); return FAILED; } debug() << "improving row: " << row << eom; std::set<tpolyhedra_domaint::rowt> improve_rows; improve_rows.insert(row); tpolyhedra_domaint::row_valuet upper= tpolyhedra_domain.get_max_row_value(row); tpolyhedra_domaint::row_valuet lower= simplify_const(solver.get(strategy_value_exprs[row])); solver.pop_context(); // improvement check solver.new_context(); // symbolic value system exprt pre_inv_expr= tpolyhedra_domain.to_symb_pre_constraints(inv, improve_rows); solver << pre_inv_expr; exprt post_inv_expr=tpolyhedra_domain.get_row_symb_post_constraint(row); solver << post_inv_expr; #if 0 debug() << "symbolic value system: " << eom; debug() << "pre-inv: " << from_expr(ns, "", pre_inv_expr) << eom; debug() << "post-inv: " << from_expr(ns, "", post_inv_expr) << eom; #endif while(tpolyhedra_domain.less_than(lower, upper)) { tpolyhedra_domaint::row_valuet middle= tpolyhedra_domain.between(lower, upper); if(!tpolyhedra_domain.less_than(lower, middle)) middle=upper; // row_symb_value >= middle exprt c= tpolyhedra_domain.get_row_symb_value_constraint(row, middle, true); #if 0 debug() << "upper: " << from_expr(ns, "", upper) << eom; debug() << "middle: " << from_expr(ns, "", middle) << eom; debug() << "lower: " << from_expr(ns, "", lower) << eom; #endif solver.new_context(); // binary search iteration #if 0 debug() << "constraint: " << from_expr(ns, "", c) << eom; #endif solver << c; if(solver()==decision_proceduret::D_SATISFIABLE) { #if 0 debug() << "SAT" << eom; #endif #if 0 for(std::size_t i=0; i<tpolyhedra_domain.template_size(); i++) { debug() << from_expr(ns, "", tpolyhedra_domain.get_row_symb_value(i)) << " " << from_expr( ns, "", solver.get(tpolyhedra_domain.get_row_symb_value(i))) << eom; } #endif #if 0 for(const auto &rm : renaming_map) { debug() << "replace_map (1st): " << from_expr(ns, "", rm.first) << " " << from_expr(ns, "", solver.get(rm.first)) << eom; debug() << "replace_map (2nd): " << from_expr(ns, "", rm.second) << " " << from_expr(ns, "", solver.get(rm.second)) << eom; } #endif lower=simplify_const( solver.get(tpolyhedra_domain.get_row_symb_value(row))); } else { #if 0 debug() << "UNSAT" << eom; #endif #if 0 for(std::size_t i=0; i<solver.formula.size(); ++i) { if(solver.solver->is_in_conflict(solver.formula[i])) debug() << "is_in_conflict: " << solver.formula[i] << eom; else debug() << "not_in_conflict: " << solver.formula[i] << eom; } #endif if(!tpolyhedra_domain.less_than(middle, upper)) middle=lower; upper=middle; } solver.pop_context(); // binary search iteration } debug() << "update value: " << from_expr(ns, "", lower) << eom; solver.pop_context(); // symbolic value system tpolyhedra_domain.set_row_value(row, lower, inv); improved=true; } else { #if 0 debug() << "UNSAT" << eom; #endif #ifdef DEBUG_FORMULA for(std::size_t i=0; i<solver.formula.size(); ++i) { if(solver.solver->is_in_conflict(solver.formula[i])) debug() << "is_in_conflict: " << solver.formula[i] << eom; else debug() << "not_in_conflict: " << solver.formula[i] << eom; } #endif solver.pop_context(); // improvement check } return improved; }
/*******************************************************************\ Function: acdl_analyze_conflict_baset::operator() Inputs: Outputs: Purpose: \*******************************************************************/ bool acdl_analyze_conflict_baset::operator() (const local_SSAt &SSA, acdl_conflict_grapht &graph) { if(disable_backjumping) { return(chronological_backtrack(SSA, graph)); } acdl_domaint::valuet conf_clause; get_conflict_clause(SSA, graph, conf_clause); // no further backtrack possible if(backtrack_level<0) { return false; } #ifdef DEBUG std::cout << "Decision trail before backtracking" << std::endl; #endif graph.dump_dec_trail(SSA); // print the conflict clause #ifdef DEBUG std::cout << "Unnormalized Learnt Clause is " << from_expr(SSA.ns, "", disjunction(conf_clause)) << std::endl; #endif // [TEMPORARY USE] save the // present decision level before backtracking //int present_dl=graph.current_level; // save the last decision before backtracking exprt dec_expr=graph.dec_trail.back(); // backtrack std::cout << "****************" << std::endl; std::cout << "BACKTRACK PHASE" << std::endl; std::cout << "****************" << std::endl; #ifdef DEBUG std::cout << "backtrack to dlevel: " << backtrack_level << std::endl; #endif cancel_until(SSA, graph, backtrack_level); #ifdef DEBUG std::cout << "Trail after backtracking" << std::endl; graph.dump_trail(SSA); #endif #ifdef DEBUG std::cout << "Decision trail after backtracking" << std::endl; graph.dump_dec_trail(SSA); #endif backtracks++; /* Steps to follow for application of unit rule to learnt clause: -- Step 1: Construct the learnt clause -- Step 2: Normalize the learnt clause without UIP -- Step 3: Normalize the current partial assignment -- Step 4: The learnt clause should be UNIT ! */ // The above steps holds true for // monotonic and non-monotonic decision // Note that the learnt clause can have redundant // literals, so normalize the learnt clause without UIP // The normalisation steps guarantee the following // -- leads to shorter clause // -- normalisation is equivalent transformation // -- backtrack level is unaffected by normalisation // -- unit rule must hold after normalisation // -- Step 2: Normalize the learnt clause without UIP // Note that the last element of the // learnt clause is the UIP acdl_domaint::valuet norm_conf_clause; for(unsigned i=0;i<conf_clause.size()-1;i++) norm_conf_clause.push_back(conf_clause[i]); domain.normalize(norm_conf_clause); // now push the uip into the learnt clause norm_conf_clause.push_back(conf_clause.back()); // add the conflict clause to the learned clause database #ifdef DEBUG std::cout << "Normalized Learnt Clause is " << from_expr(SSA.ns, "", disjunction(norm_conf_clause)) << std::endl; #endif learned_clauses.push_back(norm_conf_clause); exprt unit_lit; acdl_domaint::valuet v; graph.to_value(v); // check that the clause is unit, // this causes one propagation because // the clause is unit int result=domain.unit_rule(SSA, v, norm_conf_clause, unit_lit); // the learned clause must be asserting assert(result==domain.UNIT); // push the new deductions from unit_rule // to the conflict graph explicitly // [NOTE] the conflict_analysis is followed // by deductions on learned clause where same // deduction may happen, but we push the deductions // in the graph here because the following // deduction should return SATISFIABLE and // does not yield that the same deduction graph.assign(unit_lit); // the prop_trail is never emptied because it always // contains elements from first deduction which is // agnostic to any decisions, hence the elements of // first deduction are always consistent assert(graph.prop_trail.size()-graph.control_trail.size() >= 2); just_backtracked=true; #ifdef DEBUG std::cout << "Successfully backtracked" << std::endl; #endif // check graph consistency graph.check_consistency(); return true; }
bool solver_enumerationt::iterate(invariantt &_inv) { tpolyhedra_domaint::templ_valuet &inv = static_cast<tpolyhedra_domaint::templ_valuet &>(_inv); bool improved = false; literalt activation_literal = new_context(); exprt inv_expr = tpolyhedra_domain.to_pre_constraints(inv); debug() << "pre-inv: " << from_expr(ns,"",inv_expr) << eom; #ifndef DEBUG_FORMULA solver << or_exprt(inv_expr, literal_exprt(activation_literal)); #else debug() << "literal " << activation_literal << eom; literalt l = solver.convert(or_exprt(inv_expr, literal_exprt(activation_literal))); if(!l.is_constant()) { debug() << "literal " << l << ": " << from_expr(ns,"",or_exprt(inv_expr, literal_exprt(activation_literal))) <<eom; formula.push_back(l); } #endif exprt::operandst strategy_cond_exprs; tpolyhedra_domain.make_not_post_constraints(inv, strategy_cond_exprs, strategy_value_exprs); #ifndef DEBUG_FORMULA solver << or_exprt(disjunction(strategy_cond_exprs), literal_exprt(activation_literal)); #else exprt expr_act= or_exprt(disjunction(strategy_cond_exprs), literal_exprt(activation_literal)); l = solver.convert(expr_act); if(!l.is_constant()) { debug() << "literal " << l << ": " << from_expr(ns,"", expr_act) <<eom; formula.push_back(l); } #endif debug() << "solve(): "; #ifdef DEBUG_FORMULA bvt whole_formula = formula; whole_formula.insert(whole_formula.end(),activation_literals.begin(),activation_literals.end()); solver.set_assumptions(whole_formula); #endif if(solve() == decision_proceduret::D_SATISFIABLE) { debug() << "SAT" << eom; #if 0 for(unsigned i=0; i<whole_formula.size(); i++) { debug() << "literal: " << whole_formula[i] << " " << solver.l_get(whole_formula[i]) << eom; } for(unsigned i=0; i<tpolyhedra_domain.template_size(); i++) { exprt c = tpolyhedra_domain.get_row_constraint(i,inv[i]); debug() << "cond: " << from_expr(ns, "", c) << " " << from_expr(ns, "", solver.get(c)) << eom; debug() << "guards: " << from_expr(ns, "", tpolyhedra_domain.templ.pre_guards[i]) << " " << from_expr(ns, "", solver.get(tpolyhedra_domain.templ.pre_guards[i])) << eom; debug() << "guards: " << from_expr(ns, "", tpolyhedra_domain.templ.post_guards[i]) << " " << from_expr(ns, "", solver.get(tpolyhedra_domain.templ.post_guards[i])) << eom; } for(replace_mapt::const_iterator it=renaming_map.begin(); it!=renaming_map.end(); ++it) { debug() << "replace_map (1st): " << from_expr(ns, "", it->first) << " " << from_expr(ns, "", solver.get(it->first)) << eom; debug() << "replace_map (2nd): " << from_expr(ns, "", it->second) << " " << from_expr(ns, "", solver.get(it->second)) << eom; } #endif tpolyhedra_domaint::templ_valuet new_value; tpolyhedra_domain.initialize(new_value); for(unsigned row=0;row<tpolyhedra_domain.template_size(); row++) { tpolyhedra_domaint::row_valuet v = simplify_const(solver.get(strategy_value_exprs[row])); tpolyhedra_domain.set_row_value(row,v,new_value); debug() << "value: " << from_expr(ns,"",v) << eom; } tpolyhedra_domain.join(inv,new_value); improved = true; } else { debug() << "UNSAT" << eom; #ifdef DEBUG_FORMULA for(unsigned i=0; i<whole_formula.size(); i++) { if(solver.is_in_conflict(whole_formula[i])) debug() << "is_in_conflict: " << whole_formula[i] << eom; else debug() << "not_in_conflict: " << whole_formula[i] << eom; } #endif } pop_context(); return improved; }
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; }