Пример #1
0
exprt summarizer_bw_termt::compute_precondition(
  local_SSAt &SSA,
  summaryt &summary,
  const exprt::operandst &postconditions,
  incremental_solvert &solver,
  template_generator_summaryt &template_generator,
  bool context_sensitive)
{
  exprt postcond=not_exprt(conjunction(postconditions));

  // compute backward summary
  exprt bw_transformer, bw_invariant, bw_precondition;
  if(!template_generator.out_vars().empty())
  {
    ssa_analyzert analyzer;
    analyzer.set_message_handler(get_message_handler());
    analyzer(solver, SSA, postcond, template_generator);
    analyzer.get_result(bw_transformer, template_generator.inout_vars());
    analyzer.get_result(bw_invariant, template_generator.loop_vars());
    analyzer.get_result(bw_precondition, template_generator.out_vars());

    // statistics
    solver_instances+=analyzer.get_number_of_solver_instances();
    solver_calls+=analyzer.get_number_of_solver_calls();
  }
#if 1
  // TODO: yet another workaround for ssa_analyzer
  //  not being able to handle empty templates properly
  else
  {
    solver << SSA;
    solver.new_context();
    solver << SSA.get_enabling_exprs();
    solver << postcond;
    exprt result=true_exprt();
    if(solver()==decision_proceduret::D_UNSATISFIABLE)
      result=false_exprt();
    solver.pop_context();
    bw_transformer=result;
    bw_invariant=result;
    bw_precondition=result;
  }
#endif

  bw_transformer=not_exprt(bw_transformer);
  bw_invariant=not_exprt(bw_invariant);
  bw_precondition=not_exprt(bw_precondition);

  if(context_sensitive && !summary.bw_postcondition.is_true())
  {
    bw_transformer=implies_exprt(summary.bw_postcondition, bw_transformer);
    bw_invariant=implies_exprt(summary.bw_postcondition, bw_invariant);
    bw_precondition=implies_exprt(summary.bw_postcondition, bw_precondition);
  }

  // join // TODO: should go into summaryt
  if(summary.bw_transformer.is_nil())
  {
    summary.bw_transformer=bw_transformer;
    summary.bw_invariant=bw_invariant;
    summary.bw_precondition=bw_precondition;
  }
  else
  {
    summary.bw_transformer=or_exprt(summary.bw_transformer, bw_transformer);
    summary.bw_invariant=or_exprt(summary.bw_invariant, bw_invariant);
    summary.bw_precondition=or_exprt(summary.bw_precondition, bw_precondition);
  }

  return bw_precondition;
}
Пример #2
0
void ssa_analyzert::operator()(
  incremental_solvert &solver,
  local_SSAt &SSA,
  const exprt &precondition,
  template_generator_baset &template_generator)
{
  if(SSA.goto_function.body.instructions.empty())
    return;

  solver << SSA;
  SSA.mark_nodes();

  solver.new_context();
  solver << SSA.get_enabling_exprs();

  // add precondition (or conjunction of asssertion in backward analysis)
  solver << precondition;

  domain=template_generator.domain();

  // get strategy solver from options
  strategy_solver_baset *strategy_solver;
  if(template_generator.options.get_bool_option("compute-ranking-functions"))
  {
    if(template_generator.options.get_bool_option(
         "monolithic-ranking-function"))
    {
      strategy_solver=new ranking_solver_enumerationt(
        *static_cast<linrank_domaint *>(domain), solver, SSA.ns,
        template_generator.options.get_unsigned_int_option(
          "max-inner-ranking-iterations"));
      result=new linrank_domaint::templ_valuet();
    }
    else
    {
      strategy_solver=new lexlinrank_solver_enumerationt(
        *static_cast<lexlinrank_domaint *>(domain), solver, SSA.ns,
        template_generator.options.get_unsigned_int_option(
          "lexicographic-ranking-function"),
        template_generator.options.get_unsigned_int_option(
          "max-inner-ranking-iterations"));
      result=new lexlinrank_domaint::templ_valuet();
    }
  }
  else if(template_generator.options.get_bool_option("equalities"))
  {
    strategy_solver=new strategy_solver_equalityt(
      *static_cast<equality_domaint *>(domain), solver, SSA.ns);
    result=new equality_domaint::equ_valuet();
  }
  else
  {
    if(template_generator.options.get_bool_option("enum-solver"))
    {
      result=new tpolyhedra_domaint::templ_valuet();
      strategy_solver=new strategy_solver_enumerationt(
        *static_cast<tpolyhedra_domaint *>(domain), solver, SSA.ns);
    }
    else if(template_generator.options.get_bool_option("predabs-solver"))
    {
      result=new predabs_domaint::templ_valuet();
      strategy_solver=new strategy_solver_predabst(
        *static_cast<predabs_domaint *>(domain), solver, SSA.ns);
    }
    else if(template_generator.options.get_bool_option("binsearch-solver"))
    {
      result=new tpolyhedra_domaint::templ_valuet();
      strategy_solver=new BINSEARCH_SOLVER;
    }
    else if(template_generator.options.get_bool_option("max-solver"))
    {
      result=new predabs_domaint::templ_valuet();
      strategy_solver=new max_solver_binsearcht(
        *static_cast<tpolyhedra_domaint *>(domain), solver, SSA.ns);
    }
    else
      assert(false);
  }

  strategy_solver->set_message_handler(get_message_handler());

  // initialize inv
  domain->initialize(*result);

  // iterate
  while(strategy_solver->iterate(*result)) {}

  solver.pop_context();

  // statistics
  solver_instances+=strategy_solver->get_number_of_solver_instances();
  solver_calls+=strategy_solver->get_number_of_solver_calls();
  solver_instances+=strategy_solver->get_number_of_solver_instances();

  delete strategy_solver;
}
Пример #3
0
bool summarizer_bw_termt::bootstrap_preconditions(
  local_SSAt &SSA,
  summaryt &summary,
  incremental_solvert &solver,
  template_generator_rankingt &template_generator1,
  template_generator_summaryt &template_generator2,
  exprt &termination_argument)
{
  // bootstrap with a concrete model for input variables
  const domaint::var_sett &invars=template_generator2.out_vars();
  solver.new_context();

  unsigned number_bootstraps=0;
  termination_argument=true_exprt();
  exprt::operandst checked_candidates;
  while(number_bootstraps++<MAX_BOOTSTRAP_ATTEMPTS)
  {
    // find new ones
    solver << not_exprt(summary.bw_precondition);
    // last node should be reachable
    solver << SSA.guard_symbol(--SSA.goto_function.body.instructions.end());

    // statistics
    solver_calls++;

    // solve
    exprt precondition;
    if(solver()==decision_proceduret::D_SATISFIABLE)
    {
      exprt::operandst c;
      for(domaint::var_sett::const_iterator it=invars.begin();
          it!=invars.end(); it++)
      {
        c.push_back(equal_exprt(*it, solver.solver->get(*it)));
      }
      precondition=conjunction(c);
      debug() << "bootstrap model for precondition: "
              << from_expr(SSA.ns, "", precondition) << eom;
      solver.pop_context();
    }
    else // whole precondition space covered
    {
      solver.pop_context();
      break;
    }

    termination_argument=
      compute_termination_argument(
        SSA, precondition, solver, template_generator1);

    if(summarizer_fw_termt::check_termination_argument(
         termination_argument)==YES)
    {
      return true;
    }

    solver.new_context();
    checked_candidates.push_back(precondition);
    solver << not_exprt(disjunction(checked_candidates)); // next one, please!
  }

  return false;
}