Exemplo n.º 1
0
void concurrency_instrumentationt::instrument(exprt &expr)
{
  std::set<exprt> symbols;

  find_symbols(expr, symbols);

  replace_symbolt replace_symbol;

  for(std::set<exprt>::const_iterator
      s_it=symbols.begin();
      s_it!=symbols.end();
      s_it++)
  {
    if(s_it->id()==ID_symbol)
    {
      const irep_idt identifier=
        to_symbol_expr(*s_it).get_identifier();

      shared_varst::const_iterator
        v_it=shared_vars.find(identifier);

      if(v_it!=shared_vars.end())
      {
        index_exprt new_expr;
        //new_expr.array()=symbol_expr();
        //new_expr.index()=symbol_expr();

        replace_symbol.insert(identifier, new_expr);
      }
    }
  }
}
Exemplo n.º 2
0
int
main ( int argc, char **argv )
{
    read_args ( argc, argv );
    yyparse ();

#ifdef DUMPTREES
    FILE *pre = fopen ( "pre.tree", "w" ),
        *post = fopen ( "post.tree", "w" );
    print_node ( pre, root, 0 );
#endif

    root = simplify_tree ( root );

#ifdef DUMPTREES
    print_node ( post, root, 0 );
    fclose ( pre );
    fclose ( post );
#endif

    init_scopes ( 256 );

    find_symbols ( root );

    destroy_scopes ();
    destroy_subtree ( root );
    exit ( EXIT_SUCCESS );
}
Exemplo n.º 3
0
bool  find_symbols(expression const  e, std::function<bool(symbol)> const  selector,
                   std::unordered_set<symbol,symbol::hash>&  output)
{
    if (selector(get_symbol(e)))
        output.insert(get_symbol(e));
    for (uint64_t  i = 0ULL; i < num_parameters(e); ++i)
        find_symbols(argument(e,i),selector,output);
    return !output.empty();
}
Exemplo n.º 4
0
void preconditiont::compute_rec(exprt &dest)
{
  if(dest.id()==ID_address_of)
  {
    // only do index!
    assert(dest.operands().size()==1);
    compute_address_of(dest.op0());
  }
  else if(dest.id()==ID_symbol)
  {
    if(dest.get(ID_identifier)==
       s.get_original_name(SSA_step.ssa_lhs.get_identifier()))
    {
      dest=SSA_step.ssa_rhs;
      s.get_original_name(dest);
    }
  }
  else if(dest.id()==ID_dereference)
  {
    assert(dest.operands().size()==1);

    const irep_idt &lhs_identifier=
      s.get_original_name(SSA_step.ssa_lhs.get_identifier());
  
    // aliasing may happen here

    value_setst::valuest expr_set;
    value_sets.get_values(target, dest.op0(), expr_set);
    hash_set_cont<irep_idt, irep_id_hash> symbols;

    for(value_setst::valuest::const_iterator
        it=expr_set.begin();
        it!=expr_set.end();
        it++)
      find_symbols(*it, symbols);
    
    if(symbols.find(lhs_identifier)!=symbols.end())
    {
      // may alias!
      exprt tmp;
      tmp.swap(dest.op0());
      dereference(target, tmp, ns, value_sets);
      dest.swap(tmp);
      compute_rec(dest);
    }
    else
    {
      // nah, ok
      compute_rec(dest.op0());
    }
  }
  else
    Forall_operands(it, dest)
      compute_rec(*it);
}
Exemplo n.º 5
0
/*******************************************************************\

Function: acdl_analyze_conflict_baset::get_first_contradiction

 Inputs:

 Outputs:

 Purpose:

\*******************************************************************/
int acdl_analyze_conflict_baset::first_contradiction_on_trail(
  const exprt& expr, acdl_conflict_grapht &graph, int trail_start, int trail_end)
{
  acdl_domaint::valuet relevant_expr;
  acdl_domaint::varst exp_symbols;
  find_symbols(expr, exp_symbols);

  for(int i=trail_start; i<=trail_end; i++)
  {
    exprt& trail_exp=graph.prop_trail[i];
    acdl_domaint::varst v_symbol;
    find_symbols(trail_exp, v_symbol);
    for(acdl_domaint::varst::iterator it1=v_symbol.begin(); it1!=v_symbol.end(); it1++) {
      bool is_in=exp_symbols.find(*it1)!=exp_symbols.end();
      if(is_in) {
        bool status=domain.compare(expr, trail_exp);
        if(status==domain.CONFLICT)
          return i;
      }
    }
  }
  assert(0);
}
Exemplo n.º 6
0
void bv_refinementt::freeze_lazy_constraints()
{
  if(!lazy_arrays) return;

  for(std::list<lazy_constraintt>::iterator 
	l_it = lazy_array_constraints.begin();
      l_it != lazy_array_constraints.end(); ++l_it)
  {
    std::set<symbol_exprt> symbols;
    find_symbols(l_it->lazy,symbols);
    for(std::set<symbol_exprt>::const_iterator it = symbols.begin();
	it != symbols.end(); ++it)
    {
      bvt bv = convert_bv(l_it->lazy);
      forall_literals(b_it, bv) 
	if(!b_it->is_constant()) prop.set_frozen(*b_it);
    }
  }
}
Exemplo n.º 7
0
void predabs_domaint::project_on_vars(
  valuet &value,
  const var_sett &vars,
  exprt &result)
{
  const templ_valuet &v=static_cast<const templ_valuet &>(value);

  assert(v.size()==templ.size());
  exprt::operandst c;
  for(std::size_t row=0; row<templ.size(); row++)
  {
    const template_rowt &templ_row=templ[row];

    std::set<symbol_exprt> symbols;
    find_symbols(templ_row.expr, symbols);

    bool pure=true;
    for(const auto &symbol : symbols)
    {
      if(vars.find(symbol)==vars.end())
      {
        pure=false;
        break;
      }
    }
    if(!pure)
      continue;

    const row_valuet &row_v=v[row];
    if(templ_row.kind==LOOP)
    {
      c.push_back(
        implies_exprt(
          templ_row.pre_guard,
          implies_exprt(row_v, templ_row.expr)));
    }
    else
    {
      c.push_back(implies_exprt(row_v, templ_row.expr));
    }
  }
  result=conjunction(c);
}
Exemplo n.º 8
0
void concurrency_instrumentationt::collect(const exprt &expr)
{
  std::set<exprt> symbols;

  find_symbols(expr, symbols);

  for(std::set<exprt>::const_iterator
      s_it=symbols.begin();
      s_it!=symbols.end();
      s_it++)
  {
    if(s_it->id()==ID_symbol)
    {
      const irep_idt identifier=
        to_symbol_expr(*s_it).get_identifier();

      namespacet ns(symbol_table);
      const symbolt &symbol=ns.lookup(identifier);

      if(!symbol.is_state_var)
        continue;

      if(symbol.is_thread_local)
      {
        if(thread_local_vars.find(identifier)!=thread_local_vars.end())
          continue;

        thread_local_vart &thread_local_var=thread_local_vars[identifier];
        thread_local_var.type=symbol.type;
      }
      else
      {
        if(shared_vars.find(identifier)!=shared_vars.end())
          continue;

        shared_vart &shared_var=shared_vars[identifier];
        shared_var.type=symbol.type;
      }
    }
  }

}
Exemplo n.º 9
0
literalt dplib_convt::convert_rest(const exprt &expr)
{
    //dplib_prop.out << "%% E: " << expr << std::endl;

    literalt l=prop.new_variable();

    find_symbols(expr);

    if(expr.id()==ID_equal || expr.id()==ID_notequal)
    {
        assert(expr.operands().size()==2);

        dplib_prop.out << "ASSERT " << dplib_prop.dplib_literal(l) << " <=> (";
        convert_dplib_expr(expr.op0());
        dplib_prop.out << ((expr.id()==ID_equal)?"=":"/=");
        convert_dplib_expr(expr.op1());
        dplib_prop.out << ");" << std::endl;
    }

    return l;
}
Exemplo n.º 10
0
literalt cvc_convt::convert(const exprt &expr)
{
    //out << "%% E: " << expr << std::endl;

    if(expr.type().id()!=ID_bool)
    {
        std::string msg="cvc_convt::convert got "
                        "non-boolean expression: ";
        msg+=expr.pretty();
        throw msg;
    }

    // Three special cases in which we don't need to generate
    // a handle.

    if(expr.is_true())
        return const_literal(true);
    else if(expr.is_false())
        return const_literal(false);
    else if(expr.id()==ID_literal)
        return to_literal_expr(expr).get_literal();

    // Generate new handle

    literalt l(no_boolean_variables, false);
    no_boolean_variables++;

    find_symbols(expr);

    // define new handle
    out << "ASSERT ";
    convert_literal(l);
    out << " <=> (";
    convert_expr(expr);
    out << ");" << std::endl << std::endl;

    return l;
}
Exemplo n.º 11
0
void polynomial_acceleratort::stash_variables(scratch_programt &program,
                                              expr_sett modified,
                                              substitutiont &substitution) {
  find_symbols_sett vars;

  for (expr_sett::iterator it = modified.begin();
       it != modified.end();
       ++it) {
    find_symbols(*it, vars);
  }

  irep_idt loop_counter_name = to_symbol_expr(loop_counter).get_identifier();
  vars.erase(loop_counter_name);

  for (find_symbols_sett::iterator it = vars.begin();
       it != vars.end();
       ++it) {
    symbolt orig = symbol_table.lookup(*it);
    symbolt stashed_sym = utils.fresh_symbol("polynomial::stash", orig.type);
    substitution[orig.symbol_expr()] = stashed_sym.symbol_expr();
    program.assign(stashed_sym.symbol_expr(), orig.symbol_expr());
  }
}
Exemplo n.º 12
0
unsigned acdl_analyze_conflict_baset::get_earliest_contradiction(
  const local_SSAt &SSA, acdl_conflict_grapht &graph, acdl_domaint::meet_irreduciblet &exp)
{
  acdl_domaint::varst exp_symbols;
  // get symbols from this meet irreducible
  find_symbols(exp, exp_symbols);

#ifdef DEBUG
  std::cout << "Searching for earliest contradiction of literal " << from_expr(SSA.ns, "", exp) << std::endl;
#endif
  // search for contradiction from beginning

  unsigned lower_index, upper_index;
  unsigned control_trail_size=graph.control_trail.size();
  unsigned search_level=0;
  while(search_level<=control_trail_size-1) {
    acdl_domaint::valuet val_perdecision;

#ifdef DEBUG
    std::cout << "searching for contradiction at level " << search_level << std::endl;
#endif
    upper_index=graph.control_trail[search_level];
    if(search_level==0)
      lower_index=0;
    else
      lower_index=graph.control_trail[search_level-1];
#ifdef DEBUG
    std::cout << "Upper index is " << upper_index << "lower index is " << lower_index << std::endl;
#endif
    // [TODO] check for empty propagation trail
    if(upper_index==lower_index) {
      search_level=search_level+1;
      continue;
    }
    // now traverse the prop_trail
    for(unsigned k=lower_index;k<=upper_index-1;k++) {
      // std::cout << "The matched expression is: " << from_expr(SSA.ns, "", graph.prop_trail[k]) << std::endl;
      assert(k >= 0);
      exprt prop_exp=graph.prop_trail[k];
      val_perdecision.push_back(prop_exp);
      if(k==upper_index-1) break;
    }
    // assert that the deductions for this decision are consistent
    assert(domain.check_val_consistency(val_perdecision));
    // push the contradicted literal
    val_perdecision.push_back(exp);
    bool status=domain.check_val_satisfaction(val_perdecision);
    if(status==0)
    {
#ifdef DEBUG
      std::cout << "Found contradiction at decision level " << search_level << "for " << from_expr(SSA.ns, "", exp) << std::endl;
#endif
      return search_level;
    }
    search_level=search_level+1;
  }

#ifdef DEBUG
  std::cout << "searching for contradiction at the current level" << std::endl;
#endif
  acdl_domaint::valuet matched_expr;
  int control_point=graph.control_trail.back();
  // traverse from the back of prop_trail, last element is false_exprt
  // since the deduction at the current level leads to conflict,
  // so the deduction are by construction UNSAT
  // so, we need to iterate over all elements explicitly
  // for this segment of propagation trail which corresponds to
  // the current decision level. For other decision levels, we do
  // not need to explicitly traverse the propagation trail segment
  for(unsigned j=control_point;j<=graph.prop_trail.size()-1;j++)
  {
    // std::cout << "The matched expression is: " << from_expr(SSA.ns, "", graph.prop_trail[j]) << std::endl;
    assert(graph.prop_trail[graph.prop_trail.size()-1]==false_exprt());
    // find contradiction by traversing the prop_trail
    // and finding the relevant meet irreducibles
    exprt prop_exp=graph.prop_trail[j];
    acdl_domaint::varst prop_symbols;
    // get symbols from this meet irreducible
    find_symbols(prop_exp, prop_symbols);
    // check if this symbol is in dec_symbols
    for(acdl_domaint::varst::iterator it=prop_symbols.begin(); it!=prop_symbols.end(); it++)
    {
      bool is_in=exp_symbols.find(*it)!=exp_symbols.end();
      if(is_in) {
        // std::cout << "Hey !!! found contradiction with " << from_expr(SSA.ns, "", prop_exp) << std::endl;
        matched_expr.push_back(prop_exp);
        break;
      }
    }
#if 0
    exprt prop_exp=graph.prop_trail[j];
    if(prop_exp!=false_exprt()) {
      std::cout << "The matched expression is: " << from_expr(SSA.ns, "", prop_exp) << std::endl;
      matched_expr.push_back(prop_exp);
    }
#endif
  }
  // push the contradicted literal
  matched_expr.push_back(exp);
  bool status=domain.check_val_satisfaction(matched_expr);
  if(status==0)
  {
#ifdef DEBUG
    std::cout << "Found contradiction at current decision level for " << from_expr(SSA.ns, "", exp) << std::endl;
#endif
    return graph.current_level;
  }
  // if the control reaches here, 
  // that means no contradiction 
  // has been found at previous levels
  return 0;
}
Exemplo n.º 13
0
bool  find_unintepreted_symbols(expression const  e, std::unordered_set<symbol,symbol::hash>&  output)
{
    return find_symbols(e,std::not1(std::function<bool(symbol)>(&symbol_is_interpreted)),output);
}
Exemplo n.º 14
0
void acdl_analyze_conflict_baset::get_ai_reason(const local_SSAt &SSA,
                                                acdl_conflict_grapht &graph, acdl_domaint::valuet &reason)
{
#if 0
  // collect all propagations in the reason
  // upto the point where first decision was made
  // iterate upto trail_size-2 since the last node
  // is a FALSE node
  int control_point=graph.control_trail[0];
  for(unsigned i=control_point;i<graph.prop_trail.size()-2;i++)
  {
    exprt prop_exp=graph.prop_trail[i];
    reason.push_back(prop_exp);
  }
#endif

  // just take all decisions as reason
  for(unsigned i=0;i<graph.dec_trail.size();i++)
  {
    exprt dec_exp=graph.dec_trail[i];
    reason.push_back(dec_exp);
  }
  // now normalize the reason since there may be
  // lot of redundant decisions
  // domain.normalize(reason);

#if 0
  // Step 1: collect all decision variables by traversing the decision trail
  // (decisions follow the templates x<=0, y>10)
  // Step 2: traverse the prop_trail from back and collect the meet
  // irreducibles involving these variables
  // Step 3: Store these meet irreducibles from step 2 in reason

  acdl_domaint::varst dec_symbols;
  for(unsigned i=0;i<graph.dec_trail.size();i++)
  {
    exprt dec_exp=graph.dec_trail[i];
    acdl_domaint::varst symbols;
    find_symbols(dec_exp, symbols);
    dec_symbols.insert(symbols.begin(), symbols.end());
  }
#ifdef DEBUG
  std::cout << "Print all decision symbols so far: " << std::endl;
  for(acdl_domaint::varst::iterator it=dec_symbols.begin(); it!=dec_symbols.end(); it++)
    std::cout << *it << std::endl;
#endif

  int control_point=graph.control_trail.back();
  // traverse from the back of prop_trail to
  // get the latest value, retrieve latest values
  // from only this deduction stage
  for(unsigned j=graph.prop_trail.size()-1;j>control_point;j--)
  {
    exprt prop_exp=graph.prop_trail[j];
    acdl_domaint::varst prop_symbols;
    // get symbols from this meet irreducible
    find_symbols(prop_exp, prop_symbols);
    // check if this symbol is in dec_symbols
    for(acdl_domaint::varst::iterator it=prop_symbols.begin(); it!=prop_symbols.end(); it++)
    {
      bool is_in=dec_symbols.find(*it)!=dec_symbols.end();
      if(is_in) {
        reason.push_back(prop_exp);
        break;
      }
    }
  }
#endif
}
Exemplo n.º 15
0
bodyt termination_baset::get_body(
  goto_tracet::stepst::const_iterator &loop_begin,
  const goto_tracet &trace)
{
  bodyt result_body;
  exprt::operandst op;
  const goto_trace_stept &assertion=trace.steps.back();

  // let's get a loop number as well:
  assert(assertion.pc->guard.id()=="=>");
  std::string c_str = assertion.pc->guard.op0().get_string("identifier");
  std::string prefix = termination_prefix+
                       c_str.substr(c_str.rfind("_")+1) + "::";

  // find out what we actually need
  required_stepst required_steps;
  find_required_steps(trace, loop_begin, required_steps, prefix);

  /* We perform a new SSA-conversion. However, since we can only
     get a single path through the program, there are no joins and
     thus no phi-functions. We just increment counters. */

  std::map<irep_idt, unsigned> ssa_counters;
  replace_idt replace_id;

  // get the required body constraints
  for(goto_tracet::stepst::const_iterator step=loop_begin;
      step!=--trace.steps.end();
      step++)
  {
    last_path.push_back(step->pc);

    // required_stepst::const_iterator fit=required_steps.find(&(*step));
    // if(fit==required_steps.end()) continue;

    switch(step->pc->type)
    {
      case ASSIGN:
      {
        const code_assignt &code=to_code_assign(step->pc->code);
        find_symbols_sett w;
        find_symbols_w(code.lhs(), w);

        equal_exprt equality(code.lhs(), code.rhs());
        replace_id.replace(equality.rhs());

        // All the written ones get their SSA-ID updated
        for(find_symbols_sett::const_iterator it=w.begin();
            it!=w.end();
            it++)
        {
          // Are we writing a pre-variable?
          if(has_prefix(id2string(*it), prefix))
          {
            assert(code.rhs().id()==ID_symbol);
            const irep_idt &post_id=code.rhs().get(ID_identifier);
            const irep_idt &pre_id=code.lhs().get(ID_identifier);
            result_body.variable_map[post_id]=pre_id;

            // the RHS gets a #0 id
            irep_idt new_id=id2string(post_id)+"!0";
            replace_id.insert(post_id, new_id);
            equality.rhs().set(ID_identifier, new_id);
          }
          else
          {
            const irep_idt &old_id=*it;
            unsigned cur=++ssa_counters[old_id]; // 0 is never used

            // gets a new ID
            irep_idt new_id=id2string(old_id)+"!"+i2string(cur);
            replace_id.insert(old_id, new_id);
          }
        }

        replace_id.replace(equality.lhs());
        op.push_back(equality);
        break;
      }
      case ASSUME:
      case ASSERT:
      {
        if(!step->cond_expr.is_true() && !step->cond_expr.is_nil())
        {
          exprt guard=step->cond_expr; // That's SSA!
          remove_ssa_ids(guard);
//          exprt guard=step->pc->guard;

          find_symbols_sett syms;
          find_symbols(guard, syms);

          for(find_symbols_sett::const_iterator it=syms.begin();
              it!=syms.end();
              it++)
          {
            if(ssa_counters.find(*it)==ssa_counters.end())
            {
              irep_idt new_id=id2string(*it)+"!"+i2string(++ssa_counters[*it]);
              replace_id.insert(*it, new_id);
            }
          }

          replace_id.replace(guard);
          if(!step->cond_value) guard.negate();
          op.push_back(guard);
        }
        break;
      }
      case GOTO:
      {
        if(!step->cond_expr.is_nil())
        {
//          exprt guard=step->pc->guard;
          exprt guard=step->cond_expr;
          remove_ssa_ids(guard);

          find_symbols_sett syms;
          find_symbols(guard, syms);

          for(find_symbols_sett::const_iterator it=syms.begin();
              it!=syms.end();
              it++)
          {
            if(ssa_counters.find(*it)==ssa_counters.end())
            {
              ssa_counters[*it]=0;
              irep_idt new_id=id2string(*it)+"!"+i2string(0);
              replace_id.insert(*it, new_id);
            }
          }

          replace_id.replace(guard);
          if(!step->cond_value)
            guard.negate();
          op.push_back(guard);
        }
        break;
      }
      case DECL: /* nothing */ break;
	    case LOCATION: /* These can show up here? */ break;
      default:
        throw std::string("unexpected instruction type.");
    }
  }

  // the final result, which (again) contains SSA variables
  exprt &body_expr = result_body.body_relation;
  body_expr = and_exprt(op);

  if(result_body.variable_map.empty())
  {
    // used to be:
    // throw "BUG: No variables found; path missing.";
    // Though: No variable is ever saved, i.e., this loop
    // must be completely nondeterministic.
    warning("No pre-variables found; this "
            "loop is completely non-deterministic.");
    body_expr=false_exprt();
  }

  // The last SSA-occurrence of a variable is the
  // output variable and it gets its non-SSA name.
  replace_idt last_map;
  for(std::map<irep_idt, unsigned>::const_iterator it=ssa_counters.begin();
      it!=ssa_counters.end();
      it++)
  {
    const irep_idt &id=it->first;
    unsigned last=it->second;

    irep_idt last_name=id2string(id)+"!"+i2string(last);
    last_map.insert(last_name, id);
  }

  last_map.replace(body_expr);

  replace_nondet_sideeffects(body_expr);

  return result_body;
}
Exemplo n.º 16
0
void acceleratet::add_dirty_checks()
{
  for(expr_mapt::iterator it=dirty_vars_map.begin();
      it!=dirty_vars_map.end();
      ++it)
  {
    goto_programt::instructiont assign(ASSIGN);
    assign.code=code_assignt(it->second, false_exprt());
    program.insert_before_swap(program.instructions.begin(), assign);
  }

  goto_programt::targett next;

  for(goto_programt::targett it=program.instructions.begin();
       it!=program.instructions.end();
       it=next)
  {
    next=it;
    ++next;

    // If this is an assign to a tracked variable, clear the dirty flag.
    // Note: this order of insertions means that we assume each of the read
    // variables is clean _before_ clearing any dirty flags.
    if(it->is_assign())
    {
      exprt &lhs=it->code.op0();
      expr_mapt::iterator dirty_var=dirty_vars_map.find(lhs);

      if(dirty_var!=dirty_vars_map.end())
      {
        goto_programt::instructiont clear_flag(ASSIGN);
        clear_flag.code=code_assignt(dirty_var->second, false_exprt());
        program.insert_before_swap(it, clear_flag);
      }
    }

    // Find which symbols are read, i.e. those appearing in a guard or on
    // the right hand side of an assignment.  Assume each is not dirty.
    find_symbols_sett read;

    find_symbols(it->guard, read);

    if(it->is_assign())
    {
      find_symbols(it->code.op1(), read);
    }

    for(find_symbols_sett::iterator jt=read.begin();
        jt!=read.end();
        ++jt)
    {
      const exprt &var=ns.lookup(*jt).symbol_expr();
      expr_mapt::iterator dirty_var=dirty_vars_map.find(var);

      if(dirty_var==dirty_vars_map.end())
      {
        continue;
      }

      goto_programt::instructiont not_dirty(ASSUME);
      not_dirty.guard=not_exprt(dirty_var->second);
      program.insert_before_swap(it, not_dirty);
    }
  }
}
Exemplo n.º 17
0
void
acdl_worklist_orderedt::initialize (const local_SSAt &SSA, const exprt &assertion, const exprt& additional_constraint)
{

  // **********************************************************************
  // Initialization Strategy: Guarantees top-down and bottom-up propagation
  // Assertions -- Top
  // Leaf node  -- Middle
  // Rest       -- Bottom
  // **********************************************************************
  typedef std::list<acdl_domaint::statementt> assert_worklistt;
  assert_worklistt assert_worklist;
  typedef std::list<acdl_domaint::statementt> predecs_worklistt;
  predecs_worklistt predecs_worklist;
  typedef std::list<acdl_domaint::statementt> leaf_worklistt;
  leaf_worklistt leaf_worklist;
  typedef std::list<acdl_domaint::statementt> inter_worklistt;
  inter_worklistt inter_worklist;
  assert_listt assert_list;

  #if 0
  if (SSA.nodes.empty ())
    return;
  #endif
  if(statements.empty()) return;

  // insert the assertions like (!(a1 && a2 && a3)) on to the worklist
  #if 0
  and_exprt::operandst and_expr;
  for (local_SSAt::nodest::const_iterator n_it=SSA.nodes.begin ();
      n_it!=SSA.nodes.end (); n_it++)
  {
    for (local_SSAt::nodet::assertionst::const_iterator a_it=
        n_it->assertions.begin (); a_it!=n_it->assertions.end (); a_it++)
    {
       push_into_list(assert_worklist, *a_it);
       and_expr.push_back(*a_it);
       push_into_assertion_list(assert_list, not_exprt(*a_it));
       // push into worklist_vars
       acdl_domaint::varst avars;
       find_symbols(*a_it, avars);
       worklist_vars.insert(avars.begin(), avars.end());
    }
  }
  #endif
  push_into_list(assert_worklist, assertion);
  push_into_assertion_list(assert_list, not_exprt(assertion));
  acdl_domaint::varst avars;
  find_symbols(assertion, avars);
  worklist_vars.insert(avars.begin(), avars.end());

  // Now compute the transitive dependencies
  // compute fixpoint mu X. assert_nodes u predecessor(X)
  while(!assert_worklist.empty() > 0) {
#ifdef DEBUG
    std::cout << "Populating the worklist" << std::endl;
#endif
    // collect all the leaf nodes
    const acdl_domaint::statementt statement=pop_from_list(assert_worklist);

    // select vars in the present statement
    acdl_domaint::varst vars;
    select_vars (statement, vars);
    // compute the predecessors
    update(SSA, vars, predecs_worklist, statement, assertion);

    // std::list<acdl_domaint::statementt>::iterator
    //  iterassert=std::find(assert_list.begin(), assert_list.end(), statement);

    for(std::list<acdl_domaint::statementt>::const_iterator
      it=predecs_worklist.begin(); it!=predecs_worklist.end(); ++it) {
      std::list<acdl_domaint::statementt>::iterator finditer=
                  std::find(worklist.begin(), worklist.end(), *it);

      // This is required to prevent inserting
      // individual assertions to the worklist
      std::list<acdl_domaint::statementt>::iterator iterassert=
        std::find(assert_list.begin(), assert_list.end(), *it);
      if(finditer==worklist.end() && iterassert==assert_list.end())
      {
        // never seen this statement before
        push(*it);
        push_into_assertion_list(assert_worklist, *it);
      }
    }
  }


#ifdef DEBUG
   std::cout << "The content of the sliced but unordered worklist is as follows: " << std::endl;
    for(std::list<acdl_domaint::statementt>::const_iterator it=worklist.begin(); it!=worklist.end(); ++it) {
    std::cout << "Sliced Unordered Worklist Element::" << from_expr(SSA.ns, "", *it) << std::endl;
    }
#endif

  // order the leaf nodes right after all assertions
  for(std::list<acdl_domaint::statementt>::const_iterator
    it=worklist.begin(); it!=worklist.end(); ++it)
  {
    if(it->id()==ID_equal) {
     exprt expr_rhs=to_equal_expr(*it).rhs();
     if(expr_rhs.id()==ID_constant || expr_rhs.is_true() || expr_rhs.is_false()) {
       push_into_list(leaf_worklist, *it);
     }
     else if(expr_rhs.type().id()!=ID_constant) {
       push_into_list(inter_worklist, *it);
     }
    }
    else {
       push_into_list(inter_worklist, *it);
    }
  }

#if 0
  // order the leaf nodes right after all assertions
  for(std::list<acdl_domaint::statementt>::const_iterator
    it=worklist.begin(); it!=worklist.end(); ++it)
  {
    // Do we need to separately treat ID_constraint ?
    if(it->id()==ID_equal) {
     exprt expr_rhs=to_equal_expr(*it).rhs();
     if(expr_rhs.id()==ID_constant)
       push_into_list(leaf_worklist, *it);
    // We do not push nondet elements in to the worklist
    /* std::string str("nondet");
     std::string rhs_str=id2string(expr_rhs.get(ID_identifier));
    std::size_t found=rhs_str.find(str);
    // push the nondet statement in rhs
    if(found!=std::string::npos)
      push_into_list(leaf_worklist, *it);
    */
     // exprt expr_rhs=expr.rhs();
     // select vars in the present statement
     acdl_domaint::varst vars_rhs;
     select_vars (expr_rhs, vars_rhs);

     for(std::list<acdl_domaint::statementt>::const_iterator it1=worklist.begin(); it1!=worklist.end(); ++it1)
      {
        if(*it==*it1) continue;
        /*else {
         if(!(check_statement(*it1, vars_rhs))) {
           // *it is a leaf node
           // push_into_worklist(leaf_worklist, *it);
        }*/
         // this is an intermediate node, not leaf
         else {
           // pop the element from the list
           // const acdl_domaint::statementt statement=pop_from_worklist(worklist);
           push_into_list(inter_worklist, *it);
         }
      }
    }
  }
#endif

#ifdef DEBUG
    for(std::list<acdl_domaint::statementt>::const_iterator it=leaf_worklist.begin(); it!=leaf_worklist.end(); ++it) {
    std::cout << "Leaf Element::" << from_expr(SSA.ns, "", *it) << std::endl;
    }
    for(std::list<acdl_domaint::statementt>::const_iterator it=inter_worklist.begin(); it!=inter_worklist.end(); ++it) {
    std::cout << "Intermediate Worklist Element::" << from_expr(SSA.ns, "", *it) << std::endl;
    }
#endif
  // Now prepare the final worklist
  worklist.clear();

#if 0
  // insert assertions
  // Push the negation of the assertions into the worklist
  unsigned int size=and_expr.size();
  exprt::operandst::const_iterator it=and_expr.begin();
  if(size==1) {
    exprt::operandst::const_iterator it=and_expr.begin();
#ifdef DEBUG
    std::cout << "First single assertion push: " << *it << std::endl;
#endif
    exprt exp=*it;
    // push this into worklist at the end as TOP element
    not_exprt not_exp(exp);
    worklist.push_back(not_exp);
  }
  else {
    and_exprt final_and;
    std::swap(final_and.operands(), and_expr);
    not_exprt not_exp(final_and);
#ifdef DEBUG
    // push this into worklist at the end as TOP element
    std::cout << "First push: " << not_exp.pretty() << std::endl;
#endif
    worklist.push_back(not_exp);
  }
#endif
  // push the assertion and additional constriant
  // in to the worklist
  worklist.push_back(not_exprt(assertion));
  if(additional_constraint!=true_exprt())
   worklist.push_back(additional_constraint);

  acdl_domaint::varst var_leaf;
  // insert leaf nodes
  while(!leaf_worklist.empty() > 0) {
    const acdl_domaint::statementt statement=pop_from_list(leaf_worklist);
    push_into_list (worklist, statement);
    acdl_domaint::varst lvars;
    find_symbols(statement, lvars);
    var_leaf.insert(lvars.begin(), lvars.end());
  }

  // insert intermediate nodes
  while(!inter_worklist.empty() > 0) {
    const acdl_domaint::statementt statement=pop_from_list(inter_worklist);
    push_into_list (worklist, statement);
    // push into worklist_vars
    acdl_domaint::varst avars;
    find_symbols(statement, avars);
    // do not insert any leaf variables
    for(acdl_domaint::varst::const_iterator it=avars.begin(); it!=avars.end(); ++it) {
     if(var_leaf.find(*it)==var_leaf.end())
       worklist_vars.insert(*it);
    }
  }

#ifdef DEBUG
   std::cout << "The content of the ordered worklist is as follows: " << std::endl;
    for(std::list<acdl_domaint::statementt>::const_iterator
      it=worklist.begin(); it!=worklist.end(); ++it)
    std::cout << "Worklist Element::" << from_expr(SSA.ns, "", *it) << std::endl;
#endif


#if 0
  // **********************************************
  // Initialization Strategy: Add only assertions
  // **********************************************
  if (SSA.nodes.empty ())
    return;

  // insert the assertions like (!(a1 && a2 && a3)) on to the worklist
  and_exprt::operandst and_expr;
  for (local_SSAt::nodest::const_iterator n_it=SSA.nodes.begin ();
      n_it!=SSA.nodes.end (); n_it++)
  {
    for (local_SSAt::nodet::assertionst::const_iterator a_it=
        n_it->assertions.begin (); a_it!=n_it->assertions.end (); a_it++)
    {
       and_expr.push_back(*a_it);
    }
  }
  unsigned int size=and_expr.size();
#ifdef DEBUG
  std::cout << "The number of Assertions are : " << size << std::endl;
#endif
  exprt::operandst::const_iterator it=and_expr.begin();
  std::cout << "First single assertion push: " << *it << std::endl;
  if(size==1) {
    exprt::operandst::const_iterator it=and_expr.begin();
#ifdef DEBUG
    std::cout << "First single assertion push: " << *it << std::endl;
#endif
    exprt exp=*it;
    not_exprt not_exp(exp);
    push(worklist, not_exp);
  }
  else {
    and_exprt final_and;
    std::swap(final_and.operands(), and_expr);
    not_exprt not_exp(final_and);
#ifdef DEBUG
    std::cout << "First push: " << not_exp.pretty() << std::endl;
#endif
    push(worklist, not_exp);
  }
#endif

#if 0
  // **************************************************
  // Initialization Strategy: Add the first SSA element
  // **************************************************

  // check for equalities or constraints or next node
  if (SSA.nodes.empty ())
    return;
  assert(!SSA.nodes.front ().equalities.empty ());
  // insert the first SSA element on to the worklist
  push(worklist, SSA.nodes.front ().equalities.front ());
  #ifdef DEBUG
  std::cout << "First push: " << from_expr (SSA.ns, "", SSA.nodes.front().equalities.front ()) << std::endl;
  #endif
#endif
}
Exemplo n.º 18
0
void termination_baset::find_required_steps(
  const goto_tracet &goto_trace,
  goto_tracet::stepst::const_iterator &loop_begin,
  required_stepst &required_steps,
  const std::string &prefix) const
{
  find_symbols_sett required_symbols;
  unsigned before=0, after=1;

  // initialize: find all (potential) loop exits and
  // remember the symbols in them
  for(goto_tracet::stepst::const_iterator it1=loop_begin;
      it1!=goto_trace.steps.end();
      it1++)
  {
    if(it1->pc->is_goto() &&
       it1->pc->function==loop_begin->pc->function)
    {
      bool found_next=false, found_target=false;
      goto_programt::const_targett next=it1->pc; next++;
      goto_programt::const_targett target=it1->pc->targets.front();

      for(goto_tracet::stepst::const_iterator it2=loop_begin;
          it2!=goto_trace.steps.end();
          it2++)
      {
        if(it1!=it2)
        {
          if(it2->pc==next)
            found_next=true;
          else if(it2->pc==target)
            found_target=true;
        }
      }

      if(!found_target || !found_next)
      {
        exprt temp=it1->cond_expr;
        remove_ssa_ids(temp);
        find_symbols(temp, required_symbols);
      }
    }
  }

  #if 0
  std::cout << "INITIAL SYMBOLS: ";
  for(find_symbols_sett::const_iterator it=required_symbols.begin();
      it!=required_symbols.end();
      it++)
    std::cout << *it << ", ";
  std::cout << std::endl;
  #endif

  // get the fixpoint
  while(before!=after)
  {
    before=required_symbols.size();

    for(goto_tracet::stepst::const_iterator step=loop_begin;
        step!=goto_trace.steps.end();
        step++)
    {
      find_symbols_sett intersection;

      if(step->is_assignment())
      {
        exprt lhs, rhs;

        const codet &code=to_code(step->pc->code);

        if(code.get_statement()==ID_assign)
        {
          const code_assignt &acode=to_code_assign(step->pc->code);
          lhs=acode.lhs();
          rhs=acode.rhs();
        }
        else if(code.get_statement()==ID_function_call)
        {
          const code_function_callt fcode=to_code_function_call(step->pc->code);
          lhs=fcode.lhs();
          rhs=fcode.op2();
        }
        else
          throw "Unexpected assign statement";

        if(lhs.id()==ID_symbol &&
           has_prefix(lhs.get_string(ID_identifier), prefix))
        {
          // if we depend on the RHS syms, we also need the pre-symbol
          find_symbols_sett rhs_sym;
          find_symbols(rhs, rhs_sym);

          if(intersects(rhs_sym, required_symbols))
          {
            find_symbols(lhs, required_symbols);
            required_steps.insert(&(*step));
          }
        }
        else
        {
          find_symbols_sett lhs_sym;

          if(lhs.id()==ID_index)
            find_symbols(lhs.op0(), lhs_sym); // we're not modifying the index
          else
            find_symbols(lhs, lhs_sym);

           if(intersects(lhs_sym, required_symbols))
           {
             find_symbols(rhs, required_symbols);
             required_steps.insert(&(*step));
           }
        }
      }
      else if(step->is_assume())
      {
        find_symbols_sett syms;
        find_symbols(step->pc->guard, syms);

        if(intersects(syms, required_symbols))
        {
          required_symbols.insert(syms.begin(), syms.end());
          required_steps.insert(&(*step));
        }
      }
    }

    after=required_symbols.size();

  #if 0
  std::cout << "REQUIRED SYMBOLS: ";
  for(find_symbols_sett::const_iterator it=required_symbols.begin();
      it!=required_symbols.end();
      it++)
    std::cout << *it << ", ";
  std::cout << std::endl;
  #endif
  }
}
Exemplo n.º 19
0
acdl_domaint::meet_irreduciblet acdl_decision_heuristics_randt::operator()
  (const local_SSAt &SSA, const acdl_domaint::valuet &value)
{
#ifdef DEBUG
  std::cout << "Printing all decision variables" << std::endl;
  for(std::set<exprt>::const_iterator
        it=decision_variables.begin(); it!=decision_variables.end(); it++)
    std::cout << from_expr(SSA.ns, "", *it) << "  , " << std::endl;
#endif

  // copy the value to non-constant value
  acdl_domaint::valuet v;
  for(unsigned k=0;k<value.size();k++)
    v.push_back(value[k]);

  // collect the non-singleton variables
  std::vector<exprt> non_singletons;
  std::vector<exprt> singletons;
  acdl_domaint::meet_irreduciblet val;
  for(std::set<exprt>::const_iterator
        it=decision_variables.begin(); it!=decision_variables.end(); ++it) {
    val=domain.split(value, *it);
    if(!val.is_false())
      non_singletons.push_back(val);
    // collect all singleton variables
    else
      singletons.push_back(*it);
  }

  // [TODO] Do not pop decision variables since it
  // is possible that a decision has to be made on
  // a singleton variable after backtracking when it
  // is no more a singleton variable.
  /*for(std::vector<exprt>::const_iterator
    it=singletons.begin(); it!=singletons.end(); ++it)
    decision_variables.erase(decision_variables.find(*it));
  */

  // no more decisions can be made
  if(non_singletons.size()==0) {
#ifdef DEBUG
    std::cout << "NO DECISIONS CAN BE MADE " << std::endl;
#endif
    return false_exprt();
  }

#ifdef DEBUG
  std::cout << "Printing all non-singletons decision variables" << std::endl;
  for(std::vector<exprt>::const_iterator
        it=non_singletons.begin(); it!=non_singletons.end(); ++it)
    std::cout << from_expr(SSA.ns, "", *it) << "  , " << std::endl;
#endif

  std::vector<exprt> non_cond;
  std::vector<exprt> cond;
  std::string str("cond");
  std::string name;
  // separate the non-singleton cond and non_cond variables
  for(std::vector<exprt>::const_iterator
        it=non_singletons.begin(); it!=non_singletons.end(); ++it) {
    // check if it is not of type x<=10 or x>=10 but
    // something like !cond or cond
    const exprt &e=*it;
    if(e.id()!=ID_le && e.id()!=ID_ge && e.id()!=ID_lt && e.id()!=ID_gt)
    {
      exprt exp=it->op0();
      const irep_idt &identifier=exp.get(ID_identifier);
      name=id2string(identifier);
      std::size_t found=name.find(str);
      if (found!=std::string::npos)
        cond.push_back(*it);
      // cond.push_back(*it);
    }
    else
      non_cond.push_back(*it);
  }

  bool decision=false;
  // Make a decision
  while(!decision) {
    if(cond.size()==0) {
#if 0
      // choose non-cond decision variables that
      // are nondet-vars
      // choose input nondet variables
      if(nondet_var.size()>0) {
        const acdl_domaint::meet_irreduciblet dec_expr_nondet=
          nondet_var[rand() % nondet_var.size()];
        // now search for nondet_vars that are not singletons
        acdl_domaint::varst sym1;
        find_symbols(dec_expr_nondet, sym1);
        for(int i=0;i<non_cond.size();i++) {
          acdl_domaint::varst sym2;
          find_symbols(non_cond[i], sym2);
          for(acdl_domaint::varst::iterator it1=sym2.begin(); it1!=sym2.end(); it1++) {
            bool is_in=sym1.find(*it1)!=sym1.end();
            if(is_in)
              return non_cond[i];
          }
        }
      }
#endif
      // select non-cond decision variables
      acdl_domaint::meet_irreduciblet dec_expr_rand=
        non_cond[rand() % non_cond.size()];
#ifdef DEBUG
      std::cout << "[NON-COND DECISION] " << dec_expr_rand << std::endl;
#endif
      unsigned status=domain.compare_val_lit(v, dec_expr_rand);
      if(status!=0) { // not conflicting
        decision=true;
        return dec_expr_rand;
      }
      else
        continue;
    }
    else {
      // select cond decision variables
      acdl_domaint::meet_irreduciblet dec_expr_rand=
        cond[rand() % cond.size()];
#ifdef DEBUG
      std::cout << "[COND DECISION] " << dec_expr_rand << std::endl;
#endif
      unsigned status=domain.compare_val_lit(v, dec_expr_rand);
      if(status!=0) { // not conflicting
        decision=true;
        return dec_expr_rand;
      }
      else
        continue;
    }
  }
  // returns false if no decision in made
  // and the control reaches here
  return false_exprt();
}