literalt prop_minimizet::constraint() { std::vector<objectivet> &entry=current->second; bvt or_clause; for(std::vector<objectivet>::iterator o_it=entry.begin(); o_it!=entry.end(); ++o_it) { if(!o_it->fixed) or_clause.push_back(!o_it->condition); } // This returns false if the clause is empty, // i.e., no further improvement possible. if(or_clause.empty()) return const_literal(false); else if(or_clause.size()==1) return or_clause.front(); else { or_exprt or_expr; forall_literals(it, or_clause) or_expr.copy_to_operands(literal_exprt(*it)); return prop_conv.convert(or_expr); } }
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)); }
void prop_minimizet::fix_objectives() { std::vector<objectivet> &entry=current->second; bool found=false; for(std::vector<objectivet>::iterator o_it=entry.begin(); o_it!=entry.end(); ++o_it) { if(!o_it->fixed && prop_conv.l_get(o_it->condition).is_false()) { _number_satisfied++; _value+=current->first; prop_conv.set_to(literal_exprt(o_it->condition), false); // fix it o_it->fixed=true; found=true; } } assert(found); }
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)); }
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 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; }
void counterexample_beautificationt::operator()( bv_cbmct &bv_cbmc, const symex_target_equationt &equation, const namespacet &ns) { // find failed property failed=get_failed_property(bv_cbmc, equation); // lock the failed assertion bv_cbmc.set_to(literal_exprt(failed->cond_literal), false); { bv_cbmc.status() << "Beautifying counterexample (guards)" << messaget::eom; // compute weights for guards typedef std::map<literalt, unsigned> guard_countt; guard_countt guard_count; for(symex_target_equationt::SSA_stepst::const_iterator it=equation.SSA_steps.begin(); it!=equation.SSA_steps.end(); it++) { if(it->is_assignment() && it->assignment_type!=symex_targett::assignment_typet::HIDDEN) { if(!it->guard_literal.is_constant()) guard_count[it->guard_literal]++; } // reached failed assertion? if(it==failed) break; } // give to propositional minimizer prop_minimizet prop_minimize(bv_cbmc); prop_minimize.set_message_handler(bv_cbmc.get_message_handler()); for(const auto &g : guard_count) prop_minimize.objective(g.first, g.second); // minimize prop_minimize(); } { bv_cbmc.status() << "Beautifying counterexample (values)" << messaget::eom; // get symbols we care about minimization_listt minimization_list; get_minimization_list(bv_cbmc, equation, minimization_list); // minimize bv_minimizet bv_minimize(bv_cbmc); bv_minimize.set_message_handler(bv_cbmc.get_message_handler()); bv_minimize(minimization_list); } }