void acdl_analyze_conflict_baset::get_conflict_clause
(const local_SSAt &SSA, acdl_conflict_grapht &graph, acdl_domaint::valuet &conf_clause)
{
  // PROPOSITIONAL proof
  if(last_proof==PROPOSITIONAL) {
    assert(conflicting_clause!=-1);
    conf_clause=learned_clauses[conflicting_clause];
#ifdef DEBUG
    std::cout << "Conflict is purely Propositional" << std::endl;
#endif
  }
  // conflict is caused by Abstract Interpretation proof
  else if(last_proof==ABSINT) {
    acdl_domaint::valuet reason;
    get_ai_reason(SSA, graph, reason);
    // print the reason
#ifdef DEBUG
    std::cout << "Reason: " << from_expr(SSA.ns, "", disjunction(reason)) << std::endl;
#endif

    for(acdl_domaint::valuet::iterator it=reason.begin();
        it!=reason.end(); it++)
    {
      negate(*it, conf_clause);
    }
#ifdef DEBUG
    std::cout << "Conflict is purely from Abstract Interpretation Proof" << std::endl;
#endif
  }

#ifdef DEBUG
  std::cout << "Conflict at decision level is " << graph.current_level  <<std::endl;
#endif
  if(conf_clause.size()==0)
    backtrack_level=-1;
  else
    find_uip(SSA, graph, conf_clause, graph.current_level);

  // print the conflict clause
#ifdef DEBUG
  std::cout << "learnt clause: " << from_expr(SSA.ns, "", disjunction(conf_clause)) << std::endl;
#endif
}
Esempio n. 2
0
void cover_goals_extt::constraint()
{
  exprt::operandst disjuncts;

  for(std::list<cover_goalt>::const_iterator
        g_it=goals.begin();
      g_it!=goals.end();
      g_it++)
    if(!g_it->covered && !g_it->condition.is_false())
      disjuncts.push_back(literal_exprt(g_it->condition));

  // this is 'false' if there are no disjuncts
  solver << disjunction(disjuncts);
}
Esempio n. 3
0
void cover_goalst::constraint()
{
  exprt::operandst disjuncts;

  // cover at least one unknown goal

  for(std::list<goalt>::const_iterator
      g_it=goals.begin();
      g_it!=goals.end();
      g_it++)
    if(g_it->status==goalt::statust::UNKNOWN &&
       !g_it->condition.is_false())
      disjuncts.push_back(literal_exprt(g_it->condition));

  // this is 'false' if there are no disjuncts
  prop_conv.set_to_true(disjunction(disjuncts));
}
bool strategy_solver_binsearch3t::iterate(invariantt &_inv)
{
  tpolyhedra_domaint::templ_valuet &inv=
    static_cast<tpolyhedra_domaint::templ_valuet &>(_inv);

  bool improved=false;

  solver.new_context(); // for improvement check

  exprt inv_expr=tpolyhedra_domain.to_pre_constraints(inv);

#if 0
  debug() << "improvement check: " << eom;
  debug() << "pre-inv: " << from_expr(ns, "", inv_expr) << eom;
#endif

  solver << inv_expr;

  exprt::operandst strategy_cond_exprs;
  tpolyhedra_domain.make_not_post_constraints(
    inv, strategy_cond_exprs, strategy_value_exprs);

  strategy_cond_literals.resize(strategy_cond_exprs.size());

#if 0
  debug() << "post-inv: ";
#endif
  for(std::size_t i=0; i<strategy_cond_exprs.size(); i++)
  {
#if 0
    debug() << (i>0 ? " || " : "") << from_expr(ns, "", strategy_cond_exprs[i]);
#endif
    strategy_cond_literals[i]=solver.convert(strategy_cond_exprs[i]);
    strategy_cond_exprs[i]=literal_exprt(strategy_cond_literals[i]);
  }
  debug() << eom;

  solver << disjunction(strategy_cond_exprs);

#if 0
  debug() << "solve(): ";
#endif

  std::set<tpolyhedra_domaint::rowt> improve_rows;
  std::map<tpolyhedra_domaint::rowt, symbol_exprt> symb_values;
  std::map<tpolyhedra_domaint::rowt, constant_exprt> lower_values;
  exprt::operandst blocking_constraint;
  bool improved_from_neginf=false;
  while(solver()==decision_proceduret::D_SATISFIABLE) // improvement check
  {
#if 0
    debug() << "SAT" << eom;
#endif
    improved=true;

    std::size_t row=0;
    for(; row<strategy_cond_literals.size(); row++)
    {
      if(solver.l_get(strategy_cond_literals[row]).is_true())
      {
#if 1
        debug() << "improve row " << row  << eom;
#endif
        improve_rows.insert(row);
        symb_values[row]=tpolyhedra_domain.get_row_symb_value(row);
        lower_values[row]=
          simplify_const(solver.get(strategy_value_exprs[row]));
        blocking_constraint.push_back(
          literal_exprt(!strategy_cond_literals[row]));
        if(tpolyhedra_domain.is_row_value_neginf(
             tpolyhedra_domain.get_row_value(row, inv)))
          improved_from_neginf=true;
      }
    }
    solver << conjunction(blocking_constraint);
  }
  solver.pop_context(); // improvement check

  if(!improved) // done
  {
#if 0
    debug() << "UNSAT" << eom;
#endif
    return improved;
  }

  // symbolic value system
  exprt pre_inv_expr=
    tpolyhedra_domain.to_symb_pre_constraints(inv, improve_rows);
  exprt post_inv_expr=
    tpolyhedra_domain.to_symb_post_constraints(improve_rows);

  assert(lower_values.size()>=1);
  std::map<tpolyhedra_domaint::rowt, symbol_exprt>::iterator
    it=symb_values.begin();
  exprt _lower=lower_values[it->first];
#if 1
  debug() << "update row " << it->first << ": "
          << from_expr(ns, "", lower_values[it->first]) << eom;
#endif
  tpolyhedra_domain.set_row_value(it->first, lower_values[it->first], inv);
  exprt _upper=
    tpolyhedra_domain.get_max_row_value(it->first);
  exprt sum=it->second;
  for(++it; it!=symb_values.end(); ++it)
  {
    sum=plus_exprt(sum, it->second);
    _upper=plus_exprt(_upper, tpolyhedra_domain.get_max_row_value(it->first));
    _lower=plus_exprt(_lower, lower_values[it->first]);

#if 1
    debug() << "update row " << it->first << ": "
            << from_expr(ns, "", lower_values[it->first]) << eom;
#endif
    tpolyhedra_domain.set_row_value(it->first, lower_values[it->first], inv);
  }

  // do not solve system if we have just reached a new loop
  //   (the system will be very large!)
  if(improved_from_neginf)
    return improved;

  solver.new_context(); // symbolic value system
  solver << pre_inv_expr;
  solver << post_inv_expr;

#if 1
  debug() << "symbolic value system: " << eom;
  debug() << "pre-inv: " << from_expr(ns, "", pre_inv_expr) << eom;
  debug() << "post-inv: " << from_expr(ns, "", post_inv_expr) << eom;
#endif

  extend_expr_types(sum);
  extend_expr_types(_upper);
  extend_expr_types(_lower);
  tpolyhedra_domaint::row_valuet upper=simplify_const(_upper);
  tpolyhedra_domaint::row_valuet lower=simplify_const(_lower);
  assert(sum.type()==upper.type());
  assert(sum.type()==lower.type());

  symbol_exprt sum_bound(
    SUM_BOUND_VAR+i2string(sum_bound_counter++),
    sum.type());
  solver << equal_exprt(sum_bound, sum);

#if 1
  debug() << from_expr(ns, "", equal_exprt(sum_bound, sum)) << eom;
#endif

  while(tpolyhedra_domain.less_than(lower, upper))
  {
    tpolyhedra_domaint::row_valuet middle=
      tpolyhedra_domain.between(lower, upper);
    if(!tpolyhedra_domain.less_than(lower, middle))
      middle=upper;

    // row_symb_value >= middle
    assert(sum_bound.type()==middle.type());
    exprt c=binary_relation_exprt(sum_bound, ID_ge, middle);

#if 1
    debug() << "upper: " << from_expr(ns, "", upper) << eom;
    debug() << "middle: " << from_expr(ns, "", middle) << eom;
    debug() << "lower: " << from_expr(ns, "", lower) << eom;
#endif

    solver.new_context(); // binary search iteration

#if 1
    debug() << "constraint: " << from_expr(ns, "", c) << eom;
#endif

    solver << c;

    if(solver()==decision_proceduret::D_SATISFIABLE)
    {
#if 0
      debug() << "SAT" << eom;
#endif

      lower=middle;

      for(const auto &sv : symb_values)
      {
#if 1
        debug() << "update row " << sv.first << " "
                << from_expr(ns, "", sv.second) << ": ";
#endif
        constant_exprt lower_row=
          simplify_const(solver.get(sv.second));
#if 1
        debug() << from_expr(ns, "", lower_row) << eom;
#endif
        tpolyhedra_domain.set_row_value(sv.first, lower_row, inv);
      }
    }
    else
    {
#if 0
      debug() << "UNSAT" << eom;
#endif

      if(!tpolyhedra_domain.less_than(middle, upper))
        middle=lower;

      upper=middle;
    }
    solver.pop_context(); // binary search iteration
  }

  solver.pop_context();  // symbolic value system

  return improved;
}
Esempio n. 5
0
void symex_target_equationt::convert_assertions(
  prop_convt &prop_conv)
{
  // we find out if there is only _one_ assertion,
  // which allows for a simpler formula

  unsigned number_of_assertions=count_assertions();

  if(number_of_assertions==0)
    return;

  if(number_of_assertions==1)
  {
    for(auto & it : SSA_steps)
    {
      if(it.is_assert())
      {
        prop_conv.set_to_false(it.cond_expr);
        it.cond_literal=const_literal(false);
        return; // prevent further assumptions!
      }
      else if(it.is_assume())
        prop_conv.set_to_true(it.cond_expr);
    }

    assert(false); // unreachable
  }

  // We do (NOT a1) OR (NOT a2) ...
  // where the a's are the assertions
  or_exprt::operandst disjuncts;
  disjuncts.reserve(number_of_assertions);

  exprt assumption=true_exprt();

  for(auto & it : SSA_steps)
  {
    if(it.is_assert())
    {
      implies_exprt implication(
        assumption,
        it.cond_expr);
      
      // do the conversion
      it.cond_literal=prop_conv.convert(implication);

      // store disjunct
      disjuncts.push_back(literal_exprt(!it.cond_literal));
    }
    else if(it.is_assume())
    {
      // the assumptions have been converted before
      // avoid deep nesting of ID_and expressions
      if(assumption.id()==ID_and)
        assumption.copy_to_operands(literal_exprt(it.cond_literal));
      else
        assumption=
          and_exprt(assumption, literal_exprt(it.cond_literal));
    }
  }

  // the below is 'true' if there are no assertions
  prop_conv.set_to_true(disjunction(disjuncts));
}
Esempio n. 6
0
void local_SSAt::build_guard(locationt loc)
{
  const guard_mapt::entryt &entry=guard_map[loc];
  
  // anything to be built?
  if(!entry.has_guard) return;
  
  exprt::operandst sources;

  // the very first 'loc' trivially gets 'true' as source
  if(loc==goto_function.body.instructions.begin())
    sources.push_back(true_exprt());
    
  for(guard_mapt::incomingt::const_iterator
      i_it=entry.incoming.begin();
      i_it!=entry.incoming.end();
      i_it++)
  {
    const guard_mapt::edget &edge=*i_it;
    
    exprt source;
    
    // might be backwards branch taken edge
    if(edge.is_branch_taken() &&
       edge.from->is_backwards_goto())
    {
      // The loop selector indicates whether the path comes from
      // above (entering the loop) or below (iterating).
      // By convention, we use the loop select symbol for the location
      // of the backwards goto.
      symbol_exprt loop_select=
        name(guard_symbol(), LOOP_SELECT, edge.from);

      #if 0
      source=false_exprt();
      #else
      // need constraing for edge.cond
      source=loop_select;
      #endif
    }
    else
    {
      // the other cases are basically similar
      
      symbol_exprt gs=name(guard_symbol(), OUT, edge.guard_source);
      exprt cond;
      
      if(edge.is_branch_taken() ||
         edge.is_assume() ||
         edge.is_function_call())
        cond=cond_symbol(edge.from);
      else if(edge.is_branch_not_taken())
        cond=boolean_negate(cond_symbol(edge.from));
      else if(edge.is_successor())
        cond=true_exprt();
      else
        assert(false);

      source=and_exprt(gs, cond);
    }
    
    sources.push_back(source);
  }

  // the below produces 'false' if there is no source
  exprt rhs=disjunction(sources);
  
  equal_exprt equality(guard_symbol(loc), rhs);
  nodes[loc].equalities.push_back(equality);
}
bool strategy_solver_binsearcht::iterate(invariantt &_inv)
{
  tpolyhedra_domaint::templ_valuet &inv=
    static_cast<tpolyhedra_domaint::templ_valuet &>(_inv);

  bool improved=false;

  solver.new_context(); // for improvement check

  exprt inv_expr=tpolyhedra_domain.to_pre_constraints(inv);

#if 0
  debug() << "improvement check: " << eom;
  debug() << "pre-inv: " << from_expr(ns, "", inv_expr) << eom;
#endif

  solver << inv_expr;

  exprt::operandst strategy_cond_exprs;
  tpolyhedra_domain.make_not_post_constraints(
    inv, strategy_cond_exprs, strategy_value_exprs);

  strategy_cond_literals.resize(strategy_cond_exprs.size());

#if 0
  debug() << "post-inv: ";
#endif
  for(std::size_t i=0; i<strategy_cond_exprs.size(); i++)
  {
#if 0
    debug() << (i>0 ? " || " : "") << from_expr(ns, "", strategy_cond_exprs[i]);
#endif
    strategy_cond_literals[i]=solver.convert(strategy_cond_exprs[i]);
    // solver.set_frozen(strategy_cond_literals[i]);
    strategy_cond_exprs[i]=literal_exprt(strategy_cond_literals[i]);
  }
#if 0
  debug() << eom;
#endif

  solver << or_exprt(disjunction(strategy_cond_exprs),
		     literal_exprt(assertion_check));

#if 0
  debug() << "solve(): ";
#endif

  if(solver()==decision_proceduret::D_SATISFIABLE) // improvement check
  {
#if 0
    debug() << "SAT" << eom;
#endif

#if 0
    for(std::size_t i=0; i<solver.formula.size(); i++)
    {
      debug() << "literal: " << solver.formula[i]
              << " " << solver.l_get(solver.formula[i]) << eom;
    }

    for(std::size_t i=0; i<tpolyhedra_domain.template_size(); i++)
    {
      exprt c=tpolyhedra_domain.get_row_post_constraint(i, inv[i]);
      debug() << "cond: " << from_expr(ns, "", c) << " "
              << from_expr(ns, "", solver.get(c)) << eom;
      debug() << "expr: " << from_expr(ns, "", strategy_value_exprs[i]) << " "
              << from_expr(
                ns, "", simplify_const(solver.get(strategy_value_exprs[i])))
              << eom;
      debug() << "guards: "
              << from_expr(ns, "", tpolyhedra_domain.templ[i].pre_guard) << " "
              << from_expr(
                ns, "", solver.get(tpolyhedra_domain.templ[i].pre_guard))
              << eom;
      debug() << "guards: "
              << from_expr(ns, "", tpolyhedra_domain.templ[i].post_guard)
              << " "
              << from_expr(
                ns, "", solver.get(tpolyhedra_domain.templ[i].post_guard))
              << eom;
    }
#endif


    std::size_t row=0;
    for(; row<strategy_cond_literals.size(); row++)
    {
      if(solver.l_get(strategy_cond_literals[row]).is_true())
        break;  // we've found a row to improve
    }

    if(row==strategy_cond_literals.size())
    { // No, we haven't found one.
      // This can only happen if the assertions failed.
      solver.pop_context();
      return FAILED;
    }

    debug() << "improving row: " << row << eom;
    std::set<tpolyhedra_domaint::rowt> improve_rows;
    improve_rows.insert(row);

    tpolyhedra_domaint::row_valuet upper=
      tpolyhedra_domain.get_max_row_value(row);
    tpolyhedra_domaint::row_valuet lower=
      simplify_const(solver.get(strategy_value_exprs[row]));

    solver.pop_context();  // improvement check

    solver.new_context(); // symbolic value system

    exprt pre_inv_expr=
      tpolyhedra_domain.to_symb_pre_constraints(inv, improve_rows);

    solver << pre_inv_expr;

    exprt post_inv_expr=tpolyhedra_domain.get_row_symb_post_constraint(row);

    solver << post_inv_expr;

#if 0
    debug() << "symbolic value system: " << eom;
    debug() << "pre-inv: " << from_expr(ns, "", pre_inv_expr) << eom;
    debug() << "post-inv: " << from_expr(ns, "", post_inv_expr) << eom;
#endif

    while(tpolyhedra_domain.less_than(lower, upper))
    {
      tpolyhedra_domaint::row_valuet middle=
        tpolyhedra_domain.between(lower, upper);
      if(!tpolyhedra_domain.less_than(lower, middle))
        middle=upper;

      // row_symb_value >= middle
      exprt c=
        tpolyhedra_domain.get_row_symb_value_constraint(row, middle, true);

#if 0
      debug() << "upper: " << from_expr(ns, "", upper) << eom;
      debug() << "middle: " << from_expr(ns, "", middle) << eom;
      debug() << "lower: " << from_expr(ns, "", lower) << eom;
#endif

      solver.new_context(); // binary search iteration

#if 0
      debug() << "constraint: " << from_expr(ns, "", c) << eom;
#endif

      solver << c;

      if(solver()==decision_proceduret::D_SATISFIABLE)
      {
#if 0
        debug() << "SAT" << eom;
#endif

#if 0
        for(std::size_t i=0; i<tpolyhedra_domain.template_size(); i++)
        {
          debug() << from_expr(ns, "", tpolyhedra_domain.get_row_symb_value(i))
                  << " " << from_expr(
                    ns, "", solver.get(tpolyhedra_domain.get_row_symb_value(i)))
                  << eom;
        }
#endif

#if 0
        for(const auto &rm : renaming_map)
        {
          debug() << "replace_map (1st): "
                  << from_expr(ns, "", rm.first) << " "
                  << from_expr(ns, "", solver.get(rm.first)) << eom;
          debug() << "replace_map (2nd): "
                  << from_expr(ns, "", rm.second) << " "
                  << from_expr(ns, "", solver.get(rm.second)) << eom;
        }
#endif

        lower=simplify_const(
          solver.get(tpolyhedra_domain.get_row_symb_value(row)));
      }
      else
      {
#if 0
        debug() << "UNSAT" << eom;
#endif

#if 0
        for(std::size_t i=0; i<solver.formula.size(); ++i)
        {
          if(solver.solver->is_in_conflict(solver.formula[i]))
            debug() << "is_in_conflict: " << solver.formula[i] << eom;
          else
            debug() << "not_in_conflict: " << solver.formula[i] << eom;
        }
#endif

        if(!tpolyhedra_domain.less_than(middle, upper))
          middle=lower;
        upper=middle;
      }
      solver.pop_context(); // binary search iteration
    }

    debug() << "update value: " << from_expr(ns, "", lower) << eom;

    solver.pop_context();  // symbolic value system

    tpolyhedra_domain.set_row_value(row, lower, inv);
    improved=true;
  }
  else
  {
#if 0
    debug() << "UNSAT" << eom;
#endif

#ifdef DEBUG_FORMULA
    for(std::size_t i=0; i<solver.formula.size(); ++i)
    {
      if(solver.solver->is_in_conflict(solver.formula[i]))
        debug() << "is_in_conflict: " << solver.formula[i] << eom;
      else
        debug() << "not_in_conflict: " << solver.formula[i] << eom;
    }
#endif

    solver.pop_context(); // improvement check
  }

  return improved;
}
/*******************************************************************\

Function: acdl_analyze_conflict_baset::operator()

  Inputs:

 Outputs:

 Purpose:

 \*******************************************************************/
bool acdl_analyze_conflict_baset::operator() (const local_SSAt &SSA, acdl_conflict_grapht &graph)
{
  if(disable_backjumping) {
    return(chronological_backtrack(SSA, graph));
  }

  acdl_domaint::valuet conf_clause;
  get_conflict_clause(SSA, graph, conf_clause);

  // no further backtrack possible
  if(backtrack_level<0) {
    return false;
  }

#ifdef DEBUG
  std::cout << "Decision trail before backtracking" << std::endl;
#endif
  graph.dump_dec_trail(SSA);

  // print the conflict clause
#ifdef DEBUG
  std::cout << "Unnormalized Learnt Clause is " << from_expr(SSA.ns, "", disjunction(conf_clause)) << std::endl;
#endif

  // [TEMPORARY USE] save the
  // present decision level before backtracking
  //int present_dl=graph.current_level;
  // save the last decision before backtracking
  exprt dec_expr=graph.dec_trail.back();

  // backtrack
  std::cout << "****************" << std::endl;
  std::cout << "BACKTRACK PHASE" << std::endl;
  std::cout << "****************" << std::endl;
#ifdef DEBUG
  std::cout << "backtrack to dlevel: " << backtrack_level << std::endl;
#endif
  cancel_until(SSA, graph, backtrack_level);
#ifdef DEBUG
  std::cout << "Trail after backtracking" << std::endl;
  graph.dump_trail(SSA);
#endif

#ifdef DEBUG
  std::cout << "Decision trail after backtracking" << std::endl;
  graph.dump_dec_trail(SSA);
#endif

  backtracks++;

  /*
    Steps to follow for application of unit rule to learnt clause:
    -- Step 1: Construct the learnt clause
    -- Step 2: Normalize the learnt clause without UIP
    -- Step 3: Normalize the current partial assignment
    -- Step 4: The learnt clause should be UNIT !
  */
  // The above steps holds true for
  // monotonic and non-monotonic decision
  // Note that the learnt clause can have redundant
  // literals, so normalize the learnt clause without UIP
  // The normalisation steps guarantee the following
  //  -- leads to shorter clause
  //  -- normalisation is equivalent transformation
  //  -- backtrack level is unaffected by normalisation
  //  -- unit rule must hold after normalisation


  // -- Step 2: Normalize the learnt clause without UIP
  // Note that the last element of the
  // learnt clause is the UIP
  acdl_domaint::valuet norm_conf_clause;
  for(unsigned i=0;i<conf_clause.size()-1;i++)
    norm_conf_clause.push_back(conf_clause[i]);
  domain.normalize(norm_conf_clause);
  // now push the uip into the learnt clause
  norm_conf_clause.push_back(conf_clause.back());

  // add the conflict clause to the learned clause database
#ifdef DEBUG
  std::cout << "Normalized Learnt Clause is " << from_expr(SSA.ns, "", disjunction(norm_conf_clause)) << std::endl;
#endif
  learned_clauses.push_back(norm_conf_clause);

  exprt unit_lit;
  acdl_domaint::valuet v;
  graph.to_value(v);
  // check that the clause is unit,
  // this causes one propagation because
  // the clause is unit
  int result=domain.unit_rule(SSA, v, norm_conf_clause, unit_lit);

  // the learned clause must be asserting
  assert(result==domain.UNIT);

  // push the new deductions from unit_rule
  // to the conflict graph explicitly
  // [NOTE] the conflict_analysis is followed
  // by deductions on learned clause where same
  // deduction may happen, but we push the deductions
  // in the graph here because the following
  // deduction should return SATISFIABLE and
  // does not yield that the same deduction
  graph.assign(unit_lit);

  // the prop_trail is never emptied because it always
  // contains elements from first deduction which is
  // agnostic to any decisions, hence the elements of
  // first deduction are always consistent
  assert(graph.prop_trail.size()-graph.control_trail.size() >= 2);

  just_backtracked=true;
#ifdef DEBUG
  std::cout << "Successfully backtracked" << std::endl;
#endif

  // check graph consistency
  graph.check_consistency();
  return true;
}
Esempio n. 9
0
bool solver_enumerationt::iterate(invariantt &_inv)
{
  tpolyhedra_domaint::templ_valuet &inv = 
    static_cast<tpolyhedra_domaint::templ_valuet &>(_inv);

  bool improved = false;

  literalt activation_literal = new_context();

  exprt inv_expr = tpolyhedra_domain.to_pre_constraints(inv);
  debug() << "pre-inv: " << from_expr(ns,"",inv_expr) << eom;

#ifndef DEBUG_FORMULA
  solver << or_exprt(inv_expr, literal_exprt(activation_literal));
#else
  debug() << "literal " << activation_literal << eom;
  literalt l = solver.convert(or_exprt(inv_expr, literal_exprt(activation_literal)));
  if(!l.is_constant()) 
  {
    debug() << "literal " << l << ": " << from_expr(ns,"",or_exprt(inv_expr, literal_exprt(activation_literal))) <<eom;
    formula.push_back(l);
  }
#endif

  exprt::operandst strategy_cond_exprs;
  tpolyhedra_domain.make_not_post_constraints(inv, 
    strategy_cond_exprs, strategy_value_exprs); 

#ifndef DEBUG_FORMULA
  solver << or_exprt(disjunction(strategy_cond_exprs),
		     literal_exprt(activation_literal));
#else

  exprt expr_act=
    or_exprt(disjunction(strategy_cond_exprs),
	       literal_exprt(activation_literal));

  l = solver.convert(expr_act);
  if(!l.is_constant()) 
  {
    debug() << "literal " << l << ": " << 
      from_expr(ns,"", expr_act) <<eom;
    formula.push_back(l);
  }
#endif

  debug() << "solve(): ";

#ifdef DEBUG_FORMULA
  bvt whole_formula = formula;
  whole_formula.insert(whole_formula.end(),activation_literals.begin(),activation_literals.end());
  solver.set_assumptions(whole_formula);
#endif

  if(solve() == decision_proceduret::D_SATISFIABLE) 
  { 
    debug() << "SAT" << eom;
      
    #if 0
    for(unsigned i=0; i<whole_formula.size(); i++) 
    {
      debug() << "literal: " << whole_formula[i] << " " << 
        solver.l_get(whole_formula[i]) << eom;
    }
          
    for(unsigned i=0; i<tpolyhedra_domain.template_size(); i++) 
    {
      exprt c = tpolyhedra_domain.get_row_constraint(i,inv[i]);
      debug() << "cond: " << from_expr(ns, "", c) << " " << 
          from_expr(ns, "", solver.get(c)) << eom;
      debug() << "guards: " << from_expr(ns, "", tpolyhedra_domain.templ.pre_guards[i]) << 
          " " << from_expr(ns, "", solver.get(tpolyhedra_domain.templ.pre_guards[i])) << eom;
      debug() << "guards: " << from_expr(ns, "", tpolyhedra_domain.templ.post_guards[i]) << " " 
          << from_expr(ns, "", solver.get(tpolyhedra_domain.templ.post_guards[i])) << eom; 	     	     }    
          
    for(replace_mapt::const_iterator
          it=renaming_map.begin();
          it!=renaming_map.end();    
          ++it)
          
    {
      debug() << "replace_map (1st): " << from_expr(ns, "", it->first) << " " << 
          from_expr(ns, "", solver.get(it->first)) << eom;
      debug() << "replace_map (2nd): " << from_expr(ns, "", it->second) << " " << 
          from_expr(ns, "", solver.get(it->second)) << eom;
    }
                  
    #endif
      
    tpolyhedra_domaint::templ_valuet new_value;
    tpolyhedra_domain.initialize(new_value);
    for(unsigned row=0;row<tpolyhedra_domain.template_size(); row++)
    {
      tpolyhedra_domaint::row_valuet v = 
	simplify_const(solver.get(strategy_value_exprs[row]));
      tpolyhedra_domain.set_row_value(row,v,new_value);

      debug() << "value: " << from_expr(ns,"",v) << eom;
    }
    tpolyhedra_domain.join(inv,new_value);

    improved = true;
  }
  else 
  {
    debug() << "UNSAT" << eom;

#ifdef DEBUG_FORMULA
    for(unsigned i=0; i<whole_formula.size(); i++) 
    {
      if(solver.is_in_conflict(whole_formula[i]))
        debug() << "is_in_conflict: " << whole_formula[i] << eom;
      else
        debug() << "not_in_conflict: " << whole_formula[i] << eom;
     }
#endif    
  }
  pop_context();

  return improved;
}
Esempio n. 10
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;
}