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; }
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; }
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; }