void fault_localizationt::goal_covered( const cover_goalst::goalt &) { for(auto &g : goal_map) { // failed already? if(g.second.status==goalt::statust::FAILURE) continue; // check whether failed for(auto &c : g.second.instances) { literalt cond=c->cond_literal; if(solver.l_get(cond).is_false()) { g.second.status=goalt::statust::FAILURE; symex_target_equationt::SSA_stepst::iterator next=c; next++; // include the assertion build_goto_trace(bmc.equation, next, solver, bmc.ns, g.second.goto_trace); // localize faults run(g.first); break; } } } }
void build_goto_trace( const symex_target_equationt &target, const prop_convt &prop_conv, const namespacet &ns, goto_tracet &goto_trace) { build_goto_trace( target, target.SSA_steps.end(), prop_conv, ns, goto_trace); // Now delete anything after first failed assertion for(goto_tracet::stepst::iterator s_it1=goto_trace.steps.begin(); s_it1!=goto_trace.steps.end(); s_it1++) if(s_it1->is_assert() && !s_it1->cond_value) { s_it1++; for(goto_tracet::stepst::iterator s_it2=s_it1; s_it2!=goto_trace.steps.end(); s_it2=goto_trace.steps.erase(s_it2)); break; } }
void path_searcht::check_assertion( statet &state, const namespacet &ns) { // keep statistics number_of_VCCs++; const goto_programt::instructiont &instruction= *state.get_instruction(); irep_idt property_name=instruction.location.get_property_id(); property_entryt &property_entry=property_map[property_name]; if(property_entry.status==FAIL) return; // already failed else if(property_entry.status==NOT_REACHED) property_entry.status=PASS; // well, for now! // the assertion in SSA exprt assertion= state.read(instruction.guard); if(assertion.is_true()) return; // no error, trivially // keep statistics number_of_VCCs_after_simplification++; status() << "Checking property " << property_name << eom; // take the time absolute_timet sat_start_time=current_time(); satcheckt satcheck; bv_pointerst bv_pointers(ns, satcheck); satcheck.set_message_handler(get_message_handler()); bv_pointers.set_message_handler(get_message_handler()); if(!state.check_assertion(bv_pointers)) { build_goto_trace(state, bv_pointers, property_entry.error_trace); property_entry.status=FAIL; number_of_failed_properties++; } sat_time+=current_time()-sat_start_time; }
bool simulator_symext::check_full_trace( const abstract_counterexamplet &abstract_counterexample, prefixt &prefix, goto_symex_statet &state, concrete_counterexamplet &concrete_counterexample, fail_infot &fail_info) { assert(!prefix.equation.SSA_steps.empty()); assert(prefix.equation.SSA_steps.back().is_assert()); status("Prefix of size "+i2string(prefix.equation.SSA_steps.size())); symex_target_equationt::SSA_stepst::const_iterator c_it= --prefix.equation.SSA_steps.end(); simulator_sat_dect satcheck(concrete_model.ns); prefix.equation.convert(satcheck); if(is_satisfiable(satcheck)) { // grab counterexample! build_goto_trace( prefix.equation, satcheck, concrete_model.ns, concrete_counterexample.goto_trace); return false; } get_fail_info( abstract_counterexample, satcheck, prefix, c_it, fail_info); // cannot be simulated, its spurious status("Spurious counterexample."); return true; }
bool simulator_loop_detectiont::check_phase_I_equation( symex_target_equationt &equation, goto_symex_statet &state, const abstract_counterexamplet &abstract_counterexample, concrete_counterexamplet &phase_I_counterexample, prefixt::step_mapt &step_map, fail_infot &fail_info ) { minimization_listt symbols; // run SAT symex_target_equationt::SSA_stepst::iterator c_it; for(c_it=equation.SSA_steps.begin(); c_it!=equation.SSA_steps.end(); c_it++) { if(c_it->is_assignment()) { const exprt &rhs=c_it->ssa_rhs; recurrence_solver::referenced_parameters(state, rhs, symbols); continue; } if(c_it->is_location() || (c_it->is_assume() && c_it->cond_expr.is_true())) continue; bv_minimizing_dect satcheck(concrete_model.ns); symex_target_equationt::SSA_stepst SSA_steps; SSA_steps.splice(SSA_steps.end(), equation.SSA_steps, equation.SSA_steps.begin(), ++c_it); equation.SSA_steps.swap(SSA_steps); equation.convert(satcheck); equation.SSA_steps.splice(equation.SSA_steps.end(), SSA_steps, SSA_steps.begin(), SSA_steps.end()); --c_it; // solve it if(!is_satisfiable(satcheck)) break; // spurious! if(c_it->is_assert()) // we reached the assertion { for (minimization_listt::const_iterator m_it = symbols.begin(); m_it!=symbols.end(); m_it++) std::cout << from_expr (concrete_model.ns, "", *m_it) << ", "; std::cout << std::endl; satcheck.minimize(symbols); build_goto_trace( equation, satcheck, concrete_model.ns, phase_I_counterexample.goto_trace); return false; } } assert(c_it !=equation.SSA_steps.end()); // cannot be simulated, its spurious status("Phase I Counterexample is spurious"); // fill fail_info fail_info.all_steps = abstract_counterexample.steps; assert(c_it->source.pc->is_assert() || c_it->source.pc->is_assume() || c_it->source.pc->is_goto()); // get the corresponding abstract step prefixt::step_mapt::const_iterator s_it=step_map.find(c_it); assert (s_it!=step_map.end()); abstract_counterexamplet::stepst::const_iterator a_it = s_it->second; // and fill the steps fail_info.steps.clear(); for(abstract_counterexamplet::stepst::const_iterator it=abstract_counterexample.steps.begin(); it!=abstract_counterexample.steps.end(); it++) { fail_info.steps.push_back(*it); if(it==a_it) break; } fail_info.guard=c_it->source.pc->guard; // we might need to negate it if (c_it->source.pc->is_goto()) if (c_it->guard_expr.is_false()) fail_info.guard.make_not(); return true; }
void cover_goals_extt::assignment() { // check loop head choices in model bool invariants_involved=false; if(spurious_check) { for(exprt::operandst::const_iterator l_it=loophead_selects.begin(); l_it!=loophead_selects.end(); l_it++) { if(solver.get(l_it->op0()).is_true()) { invariants_involved=true; break; } } } if(!invariants_involved || !spurious_check) { std::list<cover_goals_extt::cover_goalt>::const_iterator g_it=goals.begin(); for(goal_mapt::const_iterator it=goal_map.begin(); it!=goal_map.end(); it++, g_it++) { if(property_map[it->first].result==property_checkert::UNKNOWN && solver.l_get(g_it->condition).is_true()) { property_map[it->first].result=property_checkert::FAIL; if(build_error_trace) { ssa_build_goto_tracet build_goto_trace(SSA, solver.get_solver()); build_goto_trace(property_map[it->first].error_trace); if(!all_properties) break; } } } return; } solver.new_context(); // force avoiding paths going through invariants solver << conjunction(loophead_selects); switch(solver()) { case decision_proceduret::D_SATISFIABLE: { std::list<cover_goals_extt::cover_goalt>::const_iterator g_it=goals.begin(); for(goal_mapt::const_iterator it=goal_map.begin(); it!=goal_map.end(); it++, g_it++) { if(property_map[it->first].result==property_checkert::UNKNOWN && solver.l_get(g_it->condition).is_true()) { property_map[it->first].result=property_checkert::FAIL; if(build_error_trace) { ssa_build_goto_tracet build_goto_trace(SSA, solver.get_solver()); build_goto_trace(property_map[it->first].error_trace); #if 0 show_raw_countermodel( it->first, SSA, *solver.solver, debug(), get_message_handler()); #endif if(!all_properties) break; } } } break; } case decision_proceduret::D_UNSATISFIABLE: break; case decision_proceduret::D_ERROR: default: throw "error from decision procedure"; } solver.pop_context(); _iterations++; // statistics }
bool simulator_symext::check_prefix_equation( const abstract_counterexamplet &abstract_counterexample, prefixt &prefix, goto_symex_statet &state, concrete_counterexamplet &concrete_counterexample, fail_infot &fail_info) { unsigned int left = 0; /* leftmost index of search interval */ unsigned int right = 0; /* rightmost index of search interval */ unsigned int step = 1; /* the current step size */ unsigned int index = 0; /* the current index into the array */ // first of all, that should end with an assertion // if not, it's spurious for sure assert(!prefix.equation.SSA_steps.empty()); assert(prefix.equation.SSA_steps.back().is_assert()); status("Unprocessed prefix of size "+ i2string (prefix.equation.SSA_steps.size ())); symex_target_equationt::SSA_stepst::iterator c_it; /* construct an array of iterators (for binary search) */ std::vector<symex_target_equationt::SSA_stepst::iterator> state_array; for(c_it=prefix.equation.SSA_steps.begin(); c_it!=prefix.equation.SSA_steps.end(); c_it++) { /* assignments and locations don't make a path infeasible */ if(!(c_it->is_assignment() || c_it->is_location())) { if(!(c_it->is_assume() && c_it->cond_expr.is_true())) { state_array.push_back(c_it); // this must be an assumption, an assertion or a goto assert(c_it->source.pc->is_assert() || c_it->source.pc->is_assume() || c_it->source.pc->is_goto()); } } } assert(!state_array.empty()); // we expect at least one element! status("Processed prefix of size "+ i2string (state_array.size ())); right=state_array.size(); do { assert(index<state_array.size()); assert(index>=left); assert(index<right); status("Simulating prefix of size "+i2string(index+1)); c_it=state_array[index]; simulator_sat_dect satcheck(concrete_model.ns); symex_target_equationt::SSA_stepst SSA_steps; SSA_steps.splice(SSA_steps.end(), prefix.equation.SSA_steps, prefix.equation.SSA_steps.begin(), ++c_it); prefix.equation.SSA_steps.swap(SSA_steps); prefix.equation.convert(satcheck); prefix.equation.SSA_steps.splice(prefix.equation.SSA_steps.end(), SSA_steps, SSA_steps.begin(), SSA_steps.end()); --c_it; if(is_satisfiable(satcheck)) { // it's the assertion? grab counterexample! if(c_it->is_assert()) { build_goto_trace( prefix.equation, satcheck, concrete_model.ns, concrete_counterexample.goto_trace); return false; } // otherwise decrease the search interval size left=index; /* feasible element */ } else // unsatisfiable { right = index; /* infeasible element */ step = 1; /* reset the step size */ index = left; /* and restart from left */ get_fail_info( abstract_counterexample, satcheck, prefix, c_it, fail_info); } /* now increase the index and the step interval */ index = (left + step < right)? (left + step) : (right - 1); step = 2 * step; } while(left+1<right); // cannot be simulated, its spurious status("Spurious counterexample"); // report the location status("Simulation failed at "+ fail_info.last_step().pc->location.as_string()); return true; }