Beispiel #1
0
literalt boolbvt::convert_equality(const equal_exprt &expr)
{
  if(!base_type_eq(expr.lhs().type(), expr.rhs().type(), ns))
  {
    std::cout << "######### lhs: " << expr.lhs().pretty() << '\n';
    std::cout << "######### rhs: " << expr.rhs().pretty() << '\n';
    throw "equality without matching types";
  }

  // see if it is an unbounded array
  if(is_unbounded_array(expr.lhs().type()))
  {
    // flatten byte_update/byte_extract operators if needed

    if(has_byte_operator(expr))
    {
      exprt tmp=flatten_byte_operators(expr, ns);
      return record_array_equality(to_equal_expr(tmp));
    }

    return record_array_equality(expr);
  }

  const bvt &bv0=convert_bv(expr.lhs());
  const bvt &bv1=convert_bv(expr.rhs());

  if(bv0.size()!=bv1.size())
  {
    std::cerr << "lhs: " << expr.lhs().pretty() << '\n';
    std::cerr << "lhs size: " << bv0.size() << '\n';
    std::cerr << "rhs: " << expr.rhs().pretty() << '\n';
    std::cerr << "rhs size: " << bv1.size() << '\n';
    throw "unexpected size mismatch on equality";
  }

  if(bv0.empty())
  {
    // An empty bit-vector comparison. It's not clear
    // what this is meant to say.
    return prop.new_variable();
  }

  return bv_utils.equal(bv0, bv1);
}
void
acdl_worklist_orderedt::dec_update (const local_SSAt &SSA, const acdl_domaint::meet_irreduciblet &stmt, const exprt& assertion)
{
  // **********************************************************************
  // Initialization Strategy: Guarantees top-down and bottom-up propagation
  // Decision -- 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 (SSA.nodes.empty ())
    return;

  push_into_list(assert_worklist, stmt);
  // Now compute the transitive dependencies
  // compute fixpoint mu X. assert_nodes u predecessor(X)
  while(!assert_worklist.empty() > 0) {
    // 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);
        // push into map
        live_var_list.clear();
        push_into_map(*it, live_var_list);
      }
    }
  }
#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

  // 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

  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.type().id()==ID_constant) {
       std::cout << "The type is " << expr_rhs.type().id() << std::endl;
       std::cout << "pushing equalities into leaf" << std::endl;
       push_into_list(leaf_worklist, *it);
     }
     else if(expr_rhs.type().id()!=ID_constant) {
       std::cout << "pushing equalities into inter" << std::endl;
       push_into_list(inter_worklist, *it);
     }
    }
    else {
       std::cout << "pushing constraint" << std::endl;
       push_into_list(inter_worklist, *it);
    }
  }
#endif
    #if 0
    // 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 {*/
           push_into_list(inter_worklist, *it);
        }
      }
    }
  }
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
}