Esempio n. 1
0
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;
      }
    }
  }
}
Esempio n. 2
0
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;
    }
}
Esempio n. 3
0
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;
}
Esempio n. 4
0
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;
}
Esempio n. 5
0
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;
}
Esempio n. 6
0
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
}
Esempio n. 7
0
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;
}