示例#1
0
std::ostream& solver::display(std::ostream & out) const {
    expr_ref_vector fmls(get_manager());
    get_assertions(fmls);
    ast_pp_util visitor(get_manager());
    visitor.collect(fmls);
    visitor.display_decls(out);
    visitor.display_asserts(out, fmls, true);
    return out;
}
示例#2
0
void summarizer_fw_termt::inline_summaries(
  const function_namet &function_name,
  local_SSAt &SSA, exprt precondition,
  bool context_sensitive,
  threevalt &calls_terminate,
  bool &has_function_calls)
{
  for(local_SSAt::nodest::iterator n_it=SSA.nodes.begin();
      n_it!=SSA.nodes.end(); n_it++)
  {
    for(local_SSAt::nodet::function_callst::iterator f_it=
          n_it->function_calls.begin();
        f_it!=n_it->function_calls.end(); f_it++)
    {
      assert(f_it->function().id()==ID_symbol); // no function pointers

      exprt::operandst c;
      c.push_back(precondition);
      get_assertions(SSA, c); // assertions as assumptions
      precondition=conjunction(c);

      if(!options.get_bool_option("competition-mode") &&
         !check_call_reachable(
           function_name, SSA, n_it, f_it, precondition, true))
        continue;

      has_function_calls=true;
      irep_idt fname=to_symbol_expr(f_it->function()).get_identifier();

      if(!check_precondition(
           function_name, SSA, n_it, f_it, precondition, context_sensitive))
      {
        exprt precondition_call=true_exprt();
        if(context_sensitive)
          precondition_call=compute_calling_context(
            function_name, SSA, n_it, f_it, precondition, true);

        status() << "Recursively summarizing function " << fname << eom;
        compute_summary_rec(fname, precondition_call, context_sensitive);
        summaries_used++;
      }

      // get information about callee termination
      if(summary_db.exists(fname) && summary_db.get(fname).terminates!=YES)
      {
        // cannot propagate NO
        // because call reachability might be over-approximating
        calls_terminate=UNKNOWN;
        break;
      }
    }
  }
}
示例#3
0
void summarizer_fw_termt::do_termination(
  const function_namet &function_name,
  local_SSAt &SSA,
  summaryt &summary)
{
  // calling context, invariant, function call summaries
  exprt::operandst cond;
  if(!summary.fw_invariant.is_nil())
    cond.push_back(summary.fw_invariant);
  if(!summary.fw_precondition.is_nil())
    cond.push_back(summary.fw_precondition);
  cond.push_back(ssa_inliner.get_summaries(SSA));

  status() << "Synthesizing ranking function to prove termination" << eom;
  // solver
  incremental_solvert &solver=ssa_db.get_solver(function_name);
  solver.set_message_handler(get_message_handler());

  template_generator_rankingt template_generator1(
    options, ssa_db, ssa_unwinder.get(function_name));
  template_generator1.set_message_handler(get_message_handler());
  template_generator1(solver.next_domain_number(), SSA, true);

  if(template_generator1.all_vars().empty())
    return; // nothing to do

  get_assertions(SSA, cond); // add assertions as assumptions

  // compute ranking functions
  ssa_analyzert analyzer1;
  analyzer1.set_message_handler(get_message_handler());
  analyzer1(solver, SSA, conjunction(cond), template_generator1);
  analyzer1.get_result(
    summary.termination_argument, template_generator1.all_vars());

  // extract information whether a ranking function was found for all loops
  summary.terminates=check_termination_argument(summary.termination_argument);
  if(!summary.fw_precondition.is_true())
    summary.termination_argument=
      implies_exprt(summary.fw_precondition, summary.termination_argument);

  // statistics
  solver_instances+=analyzer1.get_number_of_solver_instances();
  solver_calls+=analyzer1.get_number_of_solver_calls();
  termargs_computed++;
}