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;
}
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. 3
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;
}