Пример #1
0
bool state_projectiont::is_new(const statet &state, bool use_cache)
{
  // get the right map
  assert(!state.data().previous.is_null());
  
  state_listt &state_list=
    state_map[state.data().previous_PC];

  // first try syntactically
  
  for(state_listt::const_iterator
      it=state_list.begin();
      it!=state_list.end();
      it++)
    if(is_syntactically_equal(*it, state))
      return false; // not new
      
  // now try expensive comparison

  for(state_listt::const_iterator
      it=state_list.begin();
      it!=state_list.end();
      it++)
    if(is_equal(*it, state, use_cache))
    {
      // put into list anyways
      state_list.push_back(state);
      return false; // not new
    }

  // not found, it's new  
  state_list.push_back(state);
  
  return true;
}
Пример #2
0
void simulator_ctt::compute_goto_successors(
  const statet &state,
  queuet &queue)
{
  const instructiont &instruction=*state.data().threads.front().PC;
  unsigned count=0;

  // must have target
  assert(!instruction.targets.empty());

  formulat instantiated_guard=
    instantiate(state, 0, instruction.guard);

  formulat new_guard_taken;

  if(instantiated_guard.is_true())
    new_guard_taken=state.data().guard;
  else
  {
    new_guard_taken=formula_container.gen_and(
      instantiated_guard,
      state.data().guard);

    formulat new_guard_not_taken=formula_container.gen_and(
      formula_container.gen_not(instantiated_guard),
      state.data().guard);

    // do "guard is false" case

    statet new_state=state;
    new_state.data_w().threads.front().PC++;
    new_state.data_w().guard=new_guard_not_taken;
    new_state.data_w().taken=false;
    new_state.set_previous(state, 0);
    queue.add(new_state);

    count++;
  }

  for(program_formulat::formula_goto_programt::
        instructiont::targetst::const_iterator
      t_it=instruction.targets.begin();
      t_it!=instruction.targets.end();
      t_it++)
  {
    statet new_state=state;
    new_state.data_w().threads.front().PC=*t_it;
    new_state.data_w().guard=new_guard_taken;
    new_state.data_w().taken=true;
    new_state.set_previous(state, 0);
    queue.add(new_state);

    count++;
  }
  
  if(count>=2) path_counter+=count-1;
}
Пример #3
0
void simulatort::explore(
  const statet &state,
  queuet &queue)
{
  #ifdef DEBUG
  std::cout << "simulatort::explore1\n";
  #endif

  #if 0
  std::cout << "/////////////////////////////////////////////// "
            << "\n";

  for(unsigned thread=0; thread<program_formula.threads.size(); thread++)
  {
    std::cout << "Thread " << thread << " Location: ";
    if(state.data().PCs[thread]==
       program_formula.threads[thread].formula_goto_program.instructions.end())
      std::cout << "END" << std::endl;
    else
    {
      instructiont &instruction=*state.data().PCs[thread];
      std::cout << location_string(instruction.location) << std::endl;
    }
  }
  std::cout << std::endl;
  #endif

  // dump it if the guard is false
  if(state.data().guard.is_false())
    return;
    
  #ifdef DEBUG
  std::cout << "simulatort::explore2\n";
  #endif
  
  if(history.check_history(
    state, enable_qbf_cache, enable_small_history))
  {
    // we have seen it already
    #ifdef DEBUG
    std::cout << ">>>>>>>>>>>>>>>>>>>>>>>> SEEN ALREADY\n";
    #endif
    return;
  }
  
  #ifdef DEBUG
  std::cout << "simulatort::explore3\n";
  #endif
  
  compute_successor_states(state, true, queue);
  
  #ifdef DEBUG
  std::cout << "simulatort::explore4\n";
  #endif
}
Пример #4
0
bool state_projectiont::is_syntactically_equal(
  const statet &old_state,
  const statet &new_state)
{
  if(old_state.data().guard!=new_state.data().guard)
    return false;
  
  unsigned v=0;
  
  for(program_formulat::variablest::const_iterator
      it=program_formula.variables.begin();
      it!=program_formula.variables.end();
      it++, v++)
  {
    if(it->is_global)
    {
      assert(v<old_state.data().globals.size());
      assert(v<new_state.data().globals.size());

      if(old_state.data().globals[v]!=
         new_state.data().globals[v])
        return false;
    }
  }
  
  return true;  
}
Пример #5
0
void simulator_ctt::execute_assert(
  statet &state,
  const program_formulat::formula_goto_programt::instructiont &instruction)
{
  std::cout << "CHECKING ASSERTION\n";

  formulat condition=
    instantiate(state, 0, instruction.guard);
    
  formulat property=
    formula_container.gen_and(
      state.data().guard,
      formula_container.gen_not(condition));

  // see if it is reachable
  if(!property.is_false() &&
     is_satisfiable(property))
  {
    tracet trace;

    compute_trace(state, trace, true);
    dump_trace(trace, instruction);
    std::cout << "Assertion violated" << std::endl;
    std::cout << std::endl;

    error_state_found=true;
  }
  
  #if 0
  else
  {
    // otherwise, treat this like an assumption
    state.data_w().guard=
      formula_container.gen_and(state.data().guard, condition);
  }
  #endif
}
Пример #6
0
void simulator_ctt::execute_functioncall(
  const statet &state,
  edget &edge)
{
  const program_formulat::formula_goto_programt::instructiont
    &instruction=*state.data().threads.front().PC;
  const irep_idt &function_id=instruction.code.function;
  
  // find in program formula
  program_formulat::function_mapt::const_iterator
    f_it=program_formula.function_map.find(function_id);

  assert(f_it!=program_formula.function_map.end());
  
  const program_formulat::functiont &f=f_it->second;

  // produce a start state
  
  statet start_state(state);
  statet::threadt &thread=start_state.data_w().threads.back();
  
  // adjust PC
  thread.program=&(f.body);
  thread.PC=thread.start_pc();
  
  // assign args
  assert(instruction.code.function_args.size()==f.args.size());
  
  for(unsigned i=0; i<f.args.size(); i++)
  {
    formulat formula=instruction.code.function_args[i];
    formula=instantiate(state, 0, formula);
    start_state.data_w().set_var(f.args[i], 0, formula);
  }

  std::cout << "Adding edge for " << function_id << std::endl;
  
  // add edge
  edget &f_edge=new_edge(function_id, start_state);
  
  f_edge.calls.push_back(conft(edge, state));
}
Пример #7
0
void simulator_ctt::execute_return(const statet &state, edget &edge)
{
  // compute vector of return values
  std::vector<formulat> return_values;
  
  bool have_return=!state.data().threads.front().is_at_end();

  if(have_return)
  {
    const program_formulat::formula_goto_programt::instructiont
      &return_instruction=*state.data().threads.front().PC;
    
    return_values.resize(return_instruction.code.assigns.size());

    for(unsigned i=0; i<return_values.size(); i++)
    {
      formulat f1=return_instruction.code.assigns[i].value;
      formulat f2=instantiate(state, 0, f1);
      return_values[i]=f2;
    }
  }

  // propagate to all call sites
  for(callst::const_iterator it=edge.calls.begin();
      it!=edge.calls.end();
      it++)
  {
    const conft &conf=*it;

    // save PC
    const_targett PC=conf.state.data().threads.front().PC;

    const program_formulat::formula_goto_programt::instructiont
      &call_instruction=*PC;

    // get return PC
    PC++;

    statet new_state=state;
    
    // set PC to return location
    new_state.data_w().threads.front().PC=PC;
    new_state.data_w().threads.front().program=
      conf.state.data().threads.front().program;

    if(!call_instruction.code.function_lhs.empty())
    {
      if(have_return)
      {
        assert(call_instruction.code.function_lhs.size()==
               return_values.size());
        
        // do return value
        for(unsigned i=0; i<return_values.size(); i++)
        {
          if(call_instruction.code.function_lhs[i].in_use)
          {
            unsigned lhs=call_instruction.code.function_lhs[i].variable;
            new_state.data_w().set_var(lhs, 0, return_values[i]);
          }
        }
      }
    }
    
    std::cout << "Adding to queue of " << conf.edge->function << std::endl;
    
    // put it into the right queue
    conf.edge->queue.add(new_state);
    
    // make sure this is noticed
    active_edges.insert(conf.edge);
  }
}
Пример #8
0
bool match(
  formula_containert &container,
  const statet &state,
  const std::map<vart, bool> &values)
{
  // do the reset
  container.reset_prop();

  // build the SAT instance
  satcheckt satcheck;

  // 1st, the guard must hold
  {
    literalt l=state.data().guard.convert(satcheck);
    satcheck.l_set_to(l, true);
  }

  #if 0
  std::cout << "G: ";
  state.data().guard.output(std::cout);
  std::cout << std::endl;
  #endif
  
  // 2nd, the values must match
  for(std::map<vart, bool>::const_iterator
      it=values.begin();
      it!=values.end();
      it++)
  {
    const vart &var=it->first;
    formulat f=state.data().get_var(var.var_nr, var.thread_nr);
    literalt l=f.convert(satcheck);
    satcheck.l_set_to(l, it->second);
    
    #if 0
    std::cout << "V: ";
    state.data().values[v].output(std::cout);
    std::cout << std::endl;
    #endif
  }
  
  std::cout << "Running " << satcheck.solver_text() << ", "
            << satcheck.no_variables() << " variables, "
            << satcheck.no_clauses() << " clauses" << std::endl;

  switch(satcheck.prop_solve())
  {
  case propt::P_SATISFIABLE:
    // oh! match!
    return true;
    
  case propt::P_UNSATISFIABLE:
    // nah, no match
    return false;
    
  default:;
    assert(false);
  }

  assert(false);
  return false;
}