]> git.unchartedbackwaters.co.uk Git - francis/stp.git/commitdiff
No semantic change. Automatically layout the code using Eclipse. The layout configuat...
authortrevor_hansen <trevor_hansen@e59a4935-1847-0410-ae03-e826735625c1>
Sat, 25 Jul 2009 06:14:49 +0000 (06:14 +0000)
committertrevor_hansen <trevor_hansen@e59a4935-1847-0410-ae03-e826735625c1>
Sat, 25 Jul 2009 06:14:49 +0000 (06:14 +0000)
git-svn-id: https://stp-fast-prover.svn.sourceforge.net/svnroot/stp-fast-prover/trunk/stp@87 e59a4935-1847-0410-ae03-e826735625c1

20 files changed:
AST/AST.cpp
AST/AST.h
AST/ASTUtil.cpp
AST/BitBlast.cpp
AST/SimpBool.cpp
AST/ToCNF.cpp
AST/ToSAT.cpp
AST/Transform.cpp
AST/asttest.cpp
AST/bbtest.cpp
AST/cnftest.cpp
AST/printer/CPrinter.cpp
AST/printer/SMTLIBPrinter.cpp
AST/printer/dotPrinter.cpp
AST/printer/printers.h
bitvec/consteval.cpp
format_config.xml [new file with mode: 0644]
simplifier/bvsolver.cpp
simplifier/bvsolver.h
simplifier/simplifier.cpp

index 6f7c6e5d5227434ab6e24b1dd3c18b5b11e8f132..a03283350150654ebc52940f6981c03126c87d1b 100644 (file)
 
 #include <assert.h>
 
-namespace BEEV {
-  //some global variables that are set through commandline options. it
-  //is best that these variables remain global. Default values set
-  //here
-  //
-  //collect statistics on certain functions
-  bool stats = false;
-  //print DAG nodes
-  bool print_nodes = false;
-  //tentative global var to allow for variable activity optimization
-  //in the SAT solver. deprecated.
-  bool variable_activity_optimize = false;
-  //run STP in optimized mode
-  bool optimize = true;
-  //do sat refinement, i.e. underconstraint the problem, and feed to
-  //SAT. if this works, great. else, add a set of suitable constraints
-  //to re-constraint the problem correctly, and call SAT again, until
-  //all constraints have been added.
-  bool arrayread_refinement = true;
-  //flag to control write refinement
-  bool arraywrite_refinement = true;
-  //check the counterexample against the original input to STP
-  bool check_counterexample = false;
-  //construct the counterexample in terms of original variable based
-  //on the counterexample returned by SAT solver
-  bool construct_counterexample = true;
-  bool print_counterexample = false;
-  //if this option is true then print the way dawson wants using a
-  //different printer. do not use this printer.
-  bool print_arrayval_declaredorder = false;
-  //flag to decide whether to print "valid/invalid" or not
-  bool print_output = false;
-  //do linear search in the array values of an input array. experimental
-  bool linear_search = false;
-  //print the variable order chosen by the sat solver while it is
-  //solving.
-  bool print_sat_varorder = false; 
-  //turn on word level bitvector solver
-  bool wordlevel_solve = true;
-  //turn off XOR flattening
-  bool xor_flatten = false;
-
-  //the smtlib parser has been turned on
-  bool smtlib_parser_enable = false;
-  //print the input back
-  bool print_STPinput_back = false;
-  
-  enum BEEV::inputStatus input_status = NOT_DECLARED;
-
-  // Used only in smtlib lexer/parser
-  ASTNode SingleBitOne;
-  ASTNode SingleBitZero;
-
-  //global BEEVMGR for the parser
-  BeevMgr * globalBeevMgr_for_parser;
-
-  void (*vc_error_hdlr)(const char* err_msg) = NULL;
-  /** This is reusable empty vector, for representing empty children arrays */
-  ASTVec _empty_ASTVec;  
-  ////////////////////////////////////////////////////////////////
-  //  ASTInternal members
-  ////////////////////////////////////////////////////////////////  
-  /** Trivial but virtual destructor */
-  ASTInternal::~ASTInternal() { }
-
-  ////////////////////////////////////////////////////////////////
-  //  ASTInterior members
-  ////////////////////////////////////////////////////////////////
-  /** Copy constructor */
-  // ASTInterior::ASTInterior(const ASTInterior &int_node)
-  // {
-  //   _kind = int_node._kind;
-  //   _children = int_node._children;
-  // }
-  
-  /** Trivial but virtual destructor */
-  ASTInterior::~ASTInterior() { }
-  
-  // FIXME: Darn it! I think this ends up copying the children twice!
-  /** Either return an old node or create it if it doesn't exist. 
-      Note that nodes are physically allocated in the hash table. */
-  
-  // There is  an inelegance here that  I don't know how  to solve.  I'd
-  // like to heap allocate and do some other initialization on keys only
-  // if  they aren't  in  the hash  table.   It would  be  great if  the
-  // "insert"  method took a  "creator" class  so that  I could  do that
-  // between  when it  notices that  the key  is not  there and  when it
-  // inserts it.  Alternatively, it would be great if I could insert the
-  // temporary key and replace it  if it actually got inserted.  But STL
-  // hash_set  doesn't have  the creator  feature  and paternalistically
-  // declares that keys are immutable, even though (it seems to me) that
-  // they  could be  mutated if  the hash  value and  eq values  did not
-  // change.
-  
-  ASTInterior *BeevMgr::LookupOrCreateInterior(ASTInterior *n_ptr) {
-    ASTInteriorSet::iterator it;
-    
-    if ((it = _interior_unique_table.find(n_ptr)) == _interior_unique_table.end()) {
-      // Make a new ASTInterior node
-      // We want (NOT alpha) always to have alpha.nodenum + 1.
-      if (n_ptr->GetKind() == NOT) {
-       n_ptr->SetNodeNum(n_ptr->GetChildren()[0].GetNodeNum()+1);
-      }
-      else {
-       n_ptr->SetNodeNum(NewNodeNum());
-      }
-      pair<ASTInteriorSet::const_iterator, bool> p = _interior_unique_table.insert(n_ptr);
-      return *(p.first);
-    }
-    else
-      // Delete the temporary node, and return the found node.
-      delete n_ptr;
-      return *it;
-  }
-  
-  size_t ASTInterior::ASTInteriorHasher::operator() (const ASTInterior *int_node_ptr) const {
-    //size_t hashval = 0;
-    size_t hashval = ((size_t) int_node_ptr->GetKind());
-    const ASTVec &ch = int_node_ptr->GetChildren();
-    ASTVec::const_iterator iend = ch.end();
-    for (ASTVec::const_iterator i = ch.begin(); i != iend; i++) {
-      //Using "One at a time hash" by Bob Jenkins
-      hashval += i->Hash();
-      hashval += (hashval << 10);
-      hashval ^= (hashval >> 6);
-    }
-
-    hashval += (hashval << 3);
-    hashval ^= (hashval >> 11);
-    hashval += (hashval << 15);
-    return hashval;
-    //return hashval += ((size_t) int_node_ptr->GetKind());
-  }
-  
-
-  void ASTInterior::CleanUp() {
-    // cout << "Deleting node " << this->GetNodeNum() << endl;
-    _bm._interior_unique_table.erase(this);
-    delete this;
-  }
-
-  ////////////////////////////////////////////////////////////////
-  //  ASTNode members
-  ////////////////////////////////////////////////////////////////
-  //ASTNode constructors are inlined in AST.h
-  bool ASTNode::IsAlreadyPrinted() const {
-    BeevMgr &bm = GetBeevMgr();
-    return (bm.AlreadyPrintedSet.find(*this) != bm.AlreadyPrintedSet.end());
-  }
-
-  void ASTNode::nodeprint(ostream& os, bool c_friendly) const
-  {
+namespace BEEV
+{
+//some global variables that are set through commandline options. it
+//is best that these variables remain global. Default values set
+//here
+//
+//collect statistics on certain functions
+bool stats = false;
+//print DAG nodes
+bool print_nodes = false;
+//tentative global var to allow for variable activity optimization
+//in the SAT solver. deprecated.
+bool variable_activity_optimize = false;
+//run STP in optimized mode
+bool optimize = true;
+//do sat refinement, i.e. underconstraint the problem, and feed to
+//SAT. if this works, great. else, add a set of suitable constraints
+//to re-constraint the problem correctly, and call SAT again, until
+//all constraints have been added.
+bool arrayread_refinement = true;
+//flag to control write refinement
+bool arraywrite_refinement = true;
+//check the counterexample against the original input to STP
+bool check_counterexample = false;
+//construct the counterexample in terms of original variable based
+//on the counterexample returned by SAT solver
+bool construct_counterexample = true;
+bool print_counterexample = false;
+//if this option is true then print the way dawson wants using a
+//different printer. do not use this printer.
+bool print_arrayval_declaredorder = false;
+//flag to decide whether to print "valid/invalid" or not
+bool print_output = false;
+//do linear search in the array values of an input array. experimental
+bool linear_search = false;
+//print the variable order chosen by the sat solver while it is
+//solving.
+bool print_sat_varorder = false;
+//turn on word level bitvector solver
+bool wordlevel_solve = true;
+//turn off XOR flattening
+bool xor_flatten = false;
+
+//the smtlib parser has been turned on
+bool smtlib_parser_enable = false;
+//print the input back
+bool print_STPinput_back = false;
+
+enum BEEV::inputStatus input_status = NOT_DECLARED;
+
+// Used only in smtlib lexer/parser
+ASTNode SingleBitOne;
+ASTNode SingleBitZero;
+
+//global BEEVMGR for the parser
+BeevMgr * globalBeevMgr_for_parser;
+
+void (*vc_error_hdlr)(const char* err_msg) = NULL;
+/** This is reusable empty vector, for representing empty children arrays */
+ASTVec _empty_ASTVec;
+////////////////////////////////////////////////////////////////
+//  ASTInternal members
+////////////////////////////////////////////////////////////////
+/** Trivial but virtual destructor */
+ASTInternal::~ASTInternal()
+{
+}
+
+////////////////////////////////////////////////////////////////
+//  ASTInterior members
+////////////////////////////////////////////////////////////////
+/** Copy constructor */
+// ASTInterior::ASTInterior(const ASTInterior &int_node)
+// {
+//   _kind = int_node._kind;
+//   _children = int_node._children;
+// }
+
+/** Trivial but virtual destructor */
+ASTInterior::~ASTInterior()
+{
+}
+
+// FIXME: Darn it! I think this ends up copying the children twice!
+/** Either return an old node or create it if it doesn't exist.
+ Note that nodes are physically allocated in the hash table. */
+
+// There is  an inelegance here that  I don't know how  to solve.  I'd
+// like to heap allocate and do some other initialization on keys only
+// if  they aren't  in  the hash  table.   It would  be  great if  the
+// "insert"  method took a  "creator" class  so that  I could  do that
+// between  when it  notices that  the key  is not  there and  when it
+// inserts it.  Alternatively, it would be great if I could insert the
+// temporary key and replace it  if it actually got inserted.  But STL
+// hash_set  doesn't have  the creator  feature  and paternalistically
+// declares that keys are immutable, even though (it seems to me) that
+// they  could be  mutated if  the hash  value and  eq values  did not
+// change.
+
+ASTInterior *BeevMgr::LookupOrCreateInterior(ASTInterior *n_ptr)
+{
+       ASTInteriorSet::iterator it;
+
+       if ((it = _interior_unique_table.find(n_ptr)) == _interior_unique_table.end())
+       {
+               // Make a new ASTInterior node
+               // We want (NOT alpha) always to have alpha.nodenum + 1.
+               if (n_ptr->GetKind() == NOT)
+               {
+                       n_ptr->SetNodeNum(n_ptr->GetChildren()[0].GetNodeNum() + 1);
+               }
+               else
+               {
+                       n_ptr->SetNodeNum(NewNodeNum());
+               }
+               pair<ASTInteriorSet::const_iterator, bool> p = _interior_unique_table.insert(n_ptr);
+               return *(p.first);
+       }
+       else
+               // Delete the temporary node, and return the found node.
+               delete n_ptr;
+       return *it;
+}
+
+size_t ASTInterior::ASTInteriorHasher::operator()(const ASTInterior *int_node_ptr) const
+{
+       //size_t hashval = 0;
+       size_t hashval = ((size_t) int_node_ptr->GetKind());
+       const ASTVec &ch = int_node_ptr->GetChildren();
+       ASTVec::const_iterator iend = ch.end();
+       for (ASTVec::const_iterator i = ch.begin(); i != iend; i++)
+       {
+               //Using "One at a time hash" by Bob Jenkins
+               hashval += i->Hash();
+               hashval += (hashval << 10);
+               hashval ^= (hashval >> 6);
+       }
+
+       hashval += (hashval << 3);
+       hashval ^= (hashval >> 11);
+       hashval += (hashval << 15);
+       return hashval;
+       //return hashval += ((size_t) int_node_ptr->GetKind());
+}
+
+void ASTInterior::CleanUp()
+{
+       // cout << "Deleting node " << this->GetNodeNum() << endl;
+       _bm._interior_unique_table.erase(this);
+       delete this;
+}
+
+////////////////////////////////////////////////////////////////
+//  ASTNode members
+////////////////////////////////////////////////////////////////
+//ASTNode constructors are inlined in AST.h
+bool ASTNode::IsAlreadyPrinted() const
+{
+       BeevMgr &bm = GetBeevMgr();
+       return (bm.AlreadyPrintedSet.find(*this) != bm.AlreadyPrintedSet.end());
+}
+
+void ASTNode::nodeprint(ostream& os, bool c_friendly) const
+{
        _int_node_ptr->nodeprint(os, c_friendly);
-  }
-
-  void ASTNode::MarkAlreadyPrinted() const {
-    // FIXME: Fetching BeevMgr is annoying.  Can we put this in lispprinter class?
-    BeevMgr &bm = GetBeevMgr();
-    bm.AlreadyPrintedSet.insert(*this);
-  }
-
-  // Get the name from a symbol (char *).  It's an error if kind != SYMBOL
-  const char * const ASTNode::GetName() const {
-    if (GetKind() != SYMBOL)
-      FatalError("GetName: Called GetName on a non-symbol: ", *this);
-    return ((ASTSymbol *) _int_node_ptr)->GetName();    
-  }
-
-  void ASTNode::NFASTPrint(int l, int max, int prefix) const {
-     //****************************************
-     // stop
-     //****************************************
-     if(l > max){
-        return;
-     }
-
-     //****************************************
-     // print
-     //****************************************
-     printf("[%10d]", 0);
-     for(int i = 0; i < prefix; i++){
-        printf("    ");
-     }
-     cout << GetKind();
-     printf("\n");
-
-     //****************************************
-     // recurse
-     //****************************************
-
-     const ASTVec &children = GetChildren();
-     ASTVec::const_iterator it = children.begin();
-     for(; it != children.end(); it++) {
-        it->NFASTPrint(l+1, max, prefix+1);
-     }
-  }
-  
-  // Print in lisp format
-  ostream &ASTNode::LispPrint(ostream &os, int indentation) const {
-    // Clear the PrintMap
-    BeevMgr& bm = GetBeevMgr(); 
-    bm.AlreadyPrintedSet.clear();
-    LispPrint_indent(os, indentation);
-    printf("\n");
-    return os;
-  }
-
-  // Print newline and indentation, then print the thing.
-  ostream &ASTNode::LispPrint_indent(ostream &os,
-                                    int indentation) const
-  {
-    os << endl << spaces(indentation);
-    LispPrint1(os, indentation);
-    return os;
-  }
-  
-  /** Internal function to print in lisp format.  Assume newline
-      and indentation printed already before first line.  Recursive
-      calls will have newline & indent, though */
-  ostream &ASTNode::LispPrint1(ostream &os, int indentation) const {
-    if (!IsDefined()) {
-      os << "<undefined>";
-      return os;
-    }
-    Kind kind = GetKind();
-    // FIXME: figure out how to avoid symbols with same names as kinds.
-//    if (kind == READ) {
-//      const ASTVec &children = GetChildren();
-//      children[0].LispPrint1(os, indentation);
-//     os << "[" << children[1] << "]";
-//    } else 
-    if(kind == BVGETBIT) {
-      const ASTVec &children = GetChildren();
-      // child 0 is a symbol.  Print without the NodeNum.
-      os << GetNodeNum() << ":";
-
-
-
-      children[0]._int_node_ptr->nodeprint(os);
-      //os << "{" << children[1].GetBVConst() << "}";
-      os << "{";
-      children[1]._int_node_ptr->nodeprint(os);
-      os << "}";
-    } else if (kind == NOT) {
-      const ASTVec &children = GetChildren();
-      os << GetNodeNum() << ":";       
-      os << "(NOT ";
-      children[0].LispPrint1(os, indentation);
-      os << ")";
-    }
-    else if (Degree() == 0) {
-      // Symbol or a kind with no children print as index:NAME if shared,
-      // even if they have been printed before.        
-      os << GetNodeNum() << ":";
-      _int_node_ptr->nodeprint(os); 
-      // os << "(" << _int_node_ptr->_ref_count << ")";
-      // os << "{" << GetValueWidth() << "}";
-    }
-    else if (IsAlreadyPrinted()) {
-      // print non-symbols as "[index]" if seen before.
-      os << "[" << GetNodeNum() << "]";
-      //          << "(" << _int_node_ptr->_ref_count << ")";
-    }
-    else {
-      MarkAlreadyPrinted();
-      const ASTVec &children = GetChildren();
-      os << GetNodeNum() << ":"
-       //<< "(" << _int_node_ptr->_ref_count << ")" 
-        << "(" << kind << " ";
-      // os << "{" << GetValueWidth() << "}";
-      ASTVec::const_iterator iend = children.end();
-      for (ASTVec::const_iterator i = children.begin(); i != iend; i++) {
-       i->LispPrint_indent(os, indentation+2);
+}
+
+void ASTNode::MarkAlreadyPrinted() const
+{
+       // FIXME: Fetching BeevMgr is annoying.  Can we put this in lispprinter class?
+       BeevMgr &bm = GetBeevMgr();
+       bm.AlreadyPrintedSet.insert(*this);
+}
+
+// Get the name from a symbol (char *).  It's an error if kind != SYMBOL
+const char * const ASTNode::GetName() const
+{
+       if (GetKind() != SYMBOL)
+               FatalError("GetName: Called GetName on a non-symbol: ", *this);
+       return ((ASTSymbol *) _int_node_ptr)->GetName();
+}
+
+void ASTNode::NFASTPrint(int l, int max, int prefix) const
+{
+       //****************************************
+       // stop
+       //****************************************
+       if (l > max)
+       {
+               return;
        }
-      os << ")";       
-    }
-    return os;
-  }
-
-  //print in PRESENTATION LANGUAGE
-  //
-  //two pass algorithm: 
-  //
-  //1. In the first pass, letize this Node, N: i.e. if a node
-  //1. appears more than once in N, then record this fact.
-  //
-  //2. In the second pass print a "global let" and then print N
-  //2. as follows: Every occurence of a node occuring more than
-  //2. once is replaced with the corresponding let variable.
-  ostream& ASTNode::PL_Print(ostream &os,
-                            int indentation) const {
-    // Clear the PrintMap
-    BeevMgr& bm = GetBeevMgr(); 
-    bm.PLPrintNodeSet.clear();
-    bm.NodeLetVarMap.clear();
-    bm.NodeLetVarVec.clear();
-    bm.NodeLetVarMap1.clear();
-
-    //pass 1: letize the node
-    LetizeNode();
-
-    //pass 2: 
-    //
-    //2. print all the let variables and their counterpart expressions
-    //2. as follows (LET var1 = expr1, var2 = expr2, ...
-    //
-    //3. Then print the Node itself, replacing every occurence of
-    //3. expr1 with var1, expr2 with var2, ...
-    //os << "(";
-    if(0 < bm.NodeLetVarMap.size()) {
-      //ASTNodeMap::iterator it=bm.NodeLetVarMap.begin();
-      //ASTNodeMap::iterator itend=bm.NodeLetVarMap.end();
-      std::vector<pair<ASTNode,ASTNode> >::iterator it = bm.NodeLetVarVec.begin();
-      std::vector<pair<ASTNode,ASTNode> >::iterator itend = bm.NodeLetVarVec.end();
-
-      os << "(LET ";      
-      //print the let var first
-      it->first.PL_Print1(os,indentation,false);
-      os << " = ";
-      //print the expr
-      it->second.PL_Print1(os,indentation,false);
-
-      //update the second map for proper printing of LET
-      bm.NodeLetVarMap1[it->second] = it->first;
-
-      for(it++;it!=itend;it++) {
-        os << "," << endl;
-       //print the let var first
-       it->first.PL_Print1(os,indentation,false);
-       os << " = ";
-       //print the expr
-       it->second.PL_Print1(os,indentation,false);
-
-        //update the second map for proper printing of LET
-        bm.NodeLetVarMap1[it->second] = it->first;
-      }
-    
-      os << " IN " << endl;      
-      PL_Print1(os,indentation, true);
-      os << ") ";
-    }
-    else
-      PL_Print1(os,indentation, false);
-    //os << " )";
-    os << " ";
-    return os;
-  } //end of PL_Print()
-
-  //traverse "*this", and construct "let variables" for terms that
-  //occur more than once in "*this".
-  void ASTNode::LetizeNode(void) const {
-    Kind kind = this->GetKind();
-
-    if(kind == SYMBOL  || 
-       kind == BVCONST ||
-       kind == FALSE   ||
-       kind == TRUE)
-      return;
-
-    //FIXME: this is ugly.
-    BeevMgr& bm = GetBeevMgr();     
-    const ASTVec &c = this->GetChildren();
-    for(ASTVec::const_iterator it=c.begin(),itend=c.end();it!=itend;it++){
-      ASTNode ccc = *it;
-      if(bm.PLPrintNodeSet.find(ccc) == bm.PLPrintNodeSet.end()){
-       //If branch: if *it is not in NodeSet then,
-       //
-       //1. add it to NodeSet
-       //
-       //2. Letize its childNodes
-
-       //FIXME: Fetching BeevMgr is annoying.  Can we put this in
-       //some kind of a printer class
-       bm.PLPrintNodeSet.insert(ccc);
-       //debugging
-       //cerr << ccc;
-       ccc.LetizeNode();
-      } 
-      else{
-       Kind k = ccc.GetKind();
-       if(k == SYMBOL  || 
-          k == BVCONST ||
-          k == FALSE   ||
-          k == TRUE)
-         continue;
-       
-       //0. Else branch: Node has been seen before
+
+       //****************************************
+       // print
+       //****************************************
+       printf("[%10d]", 0);
+       for (int i = 0; i < prefix; i++)
+       {
+               printf("    ");
+       }
+       cout << GetKind();
+       printf("\n");
+
+       //****************************************
+       // recurse
+       //****************************************
+
+       const ASTVec &children = GetChildren();
+       ASTVec::const_iterator it = children.begin();
+       for (; it != children.end(); it++)
+       {
+               it->NFASTPrint(l + 1, max, prefix + 1);
+       }
+}
+
+// Print in lisp format
+ostream &ASTNode::LispPrint(ostream &os, int indentation) const
+{
+       // Clear the PrintMap
+       BeevMgr& bm = GetBeevMgr();
+       bm.AlreadyPrintedSet.clear();
+       LispPrint_indent(os, indentation);
+       printf("\n");
+       return os;
+}
+
+// Print newline and indentation, then print the thing.
+ostream &ASTNode::LispPrint_indent(ostream &os, int indentation) const
+{
+       os << endl << spaces(indentation);
+       LispPrint1(os, indentation);
+       return os;
+}
+
+/** Internal function to print in lisp format.  Assume newline
+ and indentation printed already before first line.  Recursive
+ calls will have newline & indent, though */
+ostream &ASTNode::LispPrint1(ostream &os, int indentation) const
+{
+       if (!IsDefined())
+       {
+               os << "<undefined>";
+               return os;
+       }
+       Kind kind = GetKind();
+       // FIXME: figure out how to avoid symbols with same names as kinds.
+       //    if (kind == READ) {
+       //      const ASTVec &children = GetChildren();
+       //      children[0].LispPrint1(os, indentation);
+       //      os << "[" << children[1] << "]";
+       //    } else
+       if (kind == BVGETBIT)
+       {
+               const ASTVec &children = GetChildren();
+               // child 0 is a symbol.  Print without the NodeNum.
+               os << GetNodeNum() << ":";
+
+               children[0]._int_node_ptr->nodeprint(os);
+               //os << "{" << children[1].GetBVConst() << "}";
+               os << "{";
+               children[1]._int_node_ptr->nodeprint(os);
+               os << "}";
+       }
+       else if (kind == NOT)
+       {
+               const ASTVec &children = GetChildren();
+               os << GetNodeNum() << ":";
+               os << "(NOT ";
+               children[0].LispPrint1(os, indentation);
+               os << ")";
+       }
+       else if (Degree() == 0)
+       {
+               // Symbol or a kind with no children print as index:NAME if shared,
+               // even if they have been printed before.
+               os << GetNodeNum() << ":";
+               _int_node_ptr->nodeprint(os);
+               // os << "(" << _int_node_ptr->_ref_count << ")";
+               // os << "{" << GetValueWidth() << "}";
+       }
+       else if (IsAlreadyPrinted())
+       {
+               // print non-symbols as "[index]" if seen before.
+               os << "[" << GetNodeNum() << "]";
+               //         << "(" << _int_node_ptr->_ref_count << ")";
+       }
+       else
+       {
+               MarkAlreadyPrinted();
+               const ASTVec &children = GetChildren();
+               os << GetNodeNum() << ":"
+               //<< "(" << _int_node_ptr->_ref_count << ")"
+                               << "(" << kind << " ";
+               // os << "{" << GetValueWidth() << "}";
+               ASTVec::const_iterator iend = children.end();
+               for (ASTVec::const_iterator i = children.begin(); i != iend; i++)
+               {
+                       i->LispPrint_indent(os, indentation + 2);
+               }
+               os << ")";
+       }
+       return os;
+}
+
+//print in PRESENTATION LANGUAGE
+//
+//two pass algorithm:
+//
+//1. In the first pass, letize this Node, N: i.e. if a node
+//1. appears more than once in N, then record this fact.
+//
+//2. In the second pass print a "global let" and then print N
+//2. as follows: Every occurence of a node occuring more than
+//2. once is replaced with the corresponding let variable.
+ostream& ASTNode::PL_Print(ostream &os, int indentation) const
+{
+       // Clear the PrintMap
+       BeevMgr& bm = GetBeevMgr();
+       bm.PLPrintNodeSet.clear();
+       bm.NodeLetVarMap.clear();
+       bm.NodeLetVarVec.clear();
+       bm.NodeLetVarMap1.clear();
+
+       //pass 1: letize the node
+       LetizeNode();
+
+       //pass 2:
        //
-       //1. Check if the node has a corresponding letvar in the
-       //1. NodeLetVarMap.
+       //2. print all the let variables and their counterpart expressions
+       //2. as follows (LET var1 = expr1, var2 = expr2, ...
        //
-       //2. if no, then create a new var and add it to the
-       //2. NodeLetVarMap
-       if(bm.NodeLetVarMap.find(ccc) == bm.NodeLetVarMap.end()) {
-         //Create a new symbol. Get some name. if it conflicts with a
-         //declared name, too bad. 
-         int sz = bm.NodeLetVarMap.size();
-         ostringstream oss;
-         oss << "let_k_" << sz;
-
-         ASTNode CurrentSymbol = bm.CreateSymbol(oss.str().c_str());
-         CurrentSymbol.SetValueWidth(this->GetValueWidth());
-         CurrentSymbol.SetIndexWidth(this->GetIndexWidth());     
-         /* If for some reason the variable being created here is
-          * already declared by the user then the printed output will
-          * not be a legal input to the system. too bad. I refuse to
-          * check for this.  [Vijay is the author of this comment.]
-          */
-         
-         bm.NodeLetVarMap[ccc] = CurrentSymbol;
-         std::pair<ASTNode,ASTNode> node_letvar_pair(CurrentSymbol,ccc);
-         bm.NodeLetVarVec.push_back(node_letvar_pair);
+       //3. Then print the Node itself, replacing every occurence of
+       //3. expr1 with var1, expr2 with var2, ...
+       //os << "(";
+       if (0 < bm.NodeLetVarMap.size())
+       {
+               //ASTNodeMap::iterator it=bm.NodeLetVarMap.begin();
+               //ASTNodeMap::iterator itend=bm.NodeLetVarMap.end();
+               std::vector<pair<ASTNode, ASTNode> >::iterator it = bm.NodeLetVarVec.begin();
+               std::vector<pair<ASTNode, ASTNode> >::iterator itend = bm.NodeLetVarVec.end();
+
+               os << "(LET ";
+               //print the let var first
+               it->first.PL_Print1(os, indentation, false);
+               os << " = ";
+               //print the expr
+               it->second.PL_Print1(os, indentation, false);
+
+               //update the second map for proper printing of LET
+               bm.NodeLetVarMap1[it->second] = it->first;
+
+               for (it++; it != itend; it++)
+               {
+                       os << "," << endl;
+                       //print the let var first
+                       it->first.PL_Print1(os, indentation, false);
+                       os << " = ";
+                       //print the expr
+                       it->second.PL_Print1(os, indentation, false);
+
+                       //update the second map for proper printing of LET
+                       bm.NodeLetVarMap1[it->second] = it->first;
+               }
+
+               os << " IN " << endl;
+               PL_Print1(os, indentation, true);
+               os << ") ";
+       }
+       else
+               PL_Print1(os, indentation, false);
+       //os << " )";
+       os << " ";
+       return os;
+} //end of PL_Print()
+
+//traverse "*this", and construct "let variables" for terms that
+//occur more than once in "*this".
+void ASTNode::LetizeNode(void) const
+{
+       Kind kind = this->GetKind();
+
+       if (kind == SYMBOL || kind == BVCONST || kind == FALSE || kind == TRUE)
+               return;
+
+       //FIXME: this is ugly.
+       BeevMgr& bm = GetBeevMgr();
+       const ASTVec &c = this->GetChildren();
+       for (ASTVec::const_iterator it = c.begin(), itend = c.end(); it != itend; it++)
+       {
+               ASTNode ccc = *it;
+               if (bm.PLPrintNodeSet.find(ccc) == bm.PLPrintNodeSet.end())
+               {
+                       //If branch: if *it is not in NodeSet then,
+                       //
+                       //1. add it to NodeSet
+                       //
+                       //2. Letize its childNodes
+
+                       //FIXME: Fetching BeevMgr is annoying.  Can we put this in
+                       //some kind of a printer class
+                       bm.PLPrintNodeSet.insert(ccc);
+                       //debugging
+                       //cerr << ccc;
+                       ccc.LetizeNode();
+               }
+               else
+               {
+                       Kind k = ccc.GetKind();
+                       if (k == SYMBOL || k == BVCONST || k == FALSE || k == TRUE)
+                               continue;
+
+                       //0. Else branch: Node has been seen before
+                       //
+                       //1. Check if the node has a corresponding letvar in the
+                       //1. NodeLetVarMap.
+                       //
+                       //2. if no, then create a new var and add it to the
+                       //2. NodeLetVarMap
+                       if (bm.NodeLetVarMap.find(ccc) == bm.NodeLetVarMap.end())
+                       {
+                               //Create a new symbol. Get some name. if it conflicts with a
+                               //declared name, too bad.
+                               int sz = bm.NodeLetVarMap.size();
+                               ostringstream oss;
+                               oss << "let_k_" << sz;
+
+                               ASTNode CurrentSymbol = bm.CreateSymbol(oss.str().c_str());
+                               CurrentSymbol.SetValueWidth(this->GetValueWidth());
+                               CurrentSymbol.SetIndexWidth(this->GetIndexWidth());
+                               /* If for some reason the variable being created here is
+                                * already declared by the user then the printed output will
+                                * not be a legal input to the system. too bad. I refuse to
+                                * check for this.  [Vijay is the author of this comment.]
+                                */
+
+                               bm.NodeLetVarMap[ccc] = CurrentSymbol;
+                               std::pair<ASTNode, ASTNode> node_letvar_pair(CurrentSymbol, ccc);
+                               bm.NodeLetVarVec.push_back(node_letvar_pair);
+                       }
+               }
+       }
+} //end of LetizeNode()
+
+void ASTNode::PL_Print1(ostream& os, int indentation, bool letize) const
+{
+       //os << spaces(indentation);
+       //os << endl << spaces(indentation);
+       if (!IsDefined())
+       {
+               os << "<undefined>";
+               return;
+       }
+
+       //if this node is present in the letvar Map, then print the letvar
+       BeevMgr &bm = GetBeevMgr();
+
+       //this is to print letvars for shared subterms inside the printing
+       //of "(LET v0 = term1, v1=term1@term2,...
+       if ((bm.NodeLetVarMap1.find(*this) != bm.NodeLetVarMap1.end()) && !letize)
+       {
+               (bm.NodeLetVarMap1[*this]).PL_Print1(os, indentation, letize);
+               return;
        }
-      }    
-    }
-  } //end of LetizeNode()
-
-  void ASTNode::PL_Print1(ostream& os,
-                         int indentation, 
-                         bool letize) const {
-    //os << spaces(indentation);
-    //os << endl << spaces(indentation);
-    if (!IsDefined()) {
-      os << "<undefined>";
-      return;
-    }
-    
-    //if this node is present in the letvar Map, then print the letvar
-    BeevMgr &bm = GetBeevMgr();
-
-    //this is to print letvars for shared subterms inside the printing
-    //of "(LET v0 = term1, v1=term1@term2,...
-    if((bm.NodeLetVarMap1.find(*this) != bm.NodeLetVarMap1.end()) && !letize) {
-      (bm.NodeLetVarMap1[*this]).PL_Print1(os,indentation,letize);
-      return;
-    }
-
-    //this is to print letvars for shared subterms inside the actual
-    //term to be printed
-    if((bm.NodeLetVarMap.find(*this) != bm.NodeLetVarMap.end()) && letize) {
-      (bm.NodeLetVarMap[*this]).PL_Print1(os,indentation,letize);
-      return;
-    }
-    
-    //otherwise print it normally
-    Kind kind = GetKind();
-    const ASTVec &c = GetChildren();     
-    switch(kind) {
-    case BVGETBIT:
-      c[0].PL_Print1(os,indentation,letize);
-      os << "{";
-      c[1].PL_Print1(os,indentation,letize);
-      os << "}";
-      break;
-    case BITVECTOR:
-      os << "BITVECTOR(";
-      unsigned char * str;
-      str = CONSTANTBV::BitVector_to_Hex(c[0].GetBVConst());
-      os << str << ")";
-      CONSTANTBV::BitVector_Dispose(str);
-      break;
-    case BOOLEAN:
-      os << "BOOLEAN";
-      break;
-    case FALSE:
-    case TRUE:
-      os << kind;
-      break;
-    case BVCONST:
-    case SYMBOL:
-      _int_node_ptr->nodeprint(os); 
-      break;
-    case READ:
-      c[0].PL_Print1(os, indentation,letize);
-      os << "[";
-      c[1].PL_Print1(os,indentation,letize);
-      os << "]";
-      break;
-    case WRITE:
-      os << "(";
-      c[0].PL_Print1(os,indentation,letize);
-      os << " WITH [";
-      c[1].PL_Print1(os,indentation,letize);
-      os << "] := ";
-      c[2].PL_Print1(os,indentation,letize);
-      os << ")";
-      os << endl;
-      break;
-    case BVUMINUS:
-      os << kind << "( ";
-      c[0].PL_Print1(os,indentation,letize);
-      os << ")";
-      break;
-    case NOT:
-      os << "NOT(";
-      c[0].PL_Print1(os,indentation,letize);
-      os << ") " << endl;
-      break;
-    case BVNEG:
-      os << " ~(";
-      c[0].PL_Print1(os,indentation,letize);
-      os << ")";
-      break;
-    case BVCONCAT:
-      os << "(";
-      c[0].PL_Print1(os,indentation,letize);
-      os << " @ ";
-      c[1].PL_Print1(os,indentation,letize);
-      os << ")" << endl;
-      break;
-    case BVOR:
-      os << "(";
-      c[0].PL_Print1(os,indentation,letize);
-      os << " | ";
-      c[1].PL_Print1(os,indentation,letize);
-      os << ")";
-      break;
-    case BVAND:
-      os << "(";
-      c[0].PL_Print1(os,indentation,letize);
-      os << " & ";
-      c[1].PL_Print1(os,indentation,letize);
-      os << ")";
-      break;
-    case BVEXTRACT:
-      c[0].PL_Print1(os,indentation,letize);
-      os << "[";
-      os << GetUnsignedConst(c[1]);
-      os << ":";
-      os << GetUnsignedConst(c[2]);
-      os << "]";
-      break;
-    case BVLEFTSHIFT:
-      os << "(";
-      c[0].PL_Print1(os,indentation,letize);
-      os << " << ";
-      os << GetUnsignedConst(c[1]);
-      os << ")";
-      break;
-    case BVRIGHTSHIFT:
-      os << "(";
-      c[0].PL_Print1(os,indentation,letize);
-      os << " >> ";
-      os << GetUnsignedConst(c[1]);
-      os << ")";
-      break;
-    case BVMULT:
-    case BVSUB:
-    case BVPLUS:
-    case SBVDIV:      
-    case SBVREM:
-    case BVDIV:      
-    case BVMOD:
-      os << kind << "(";
-      os << this->GetValueWidth();
-      for(ASTVec::const_iterator it=c.begin(),itend=c.end();it!=itend;it++) {
-       os << ", " << endl;
-       it->PL_Print1(os,indentation,letize);   
-      }
-      os << ")" << endl;
-      break;    
-    case ITE:
-      os << "IF(";
-      c[0].PL_Print1(os,indentation,letize);
-      os << ")" << endl;
-      os << "THEN ";
-      c[1].PL_Print1(os,indentation,letize);
-      os << endl << "ELSE ";
-      c[2].PL_Print1(os,indentation,letize);
-      os << endl << "ENDIF";
-      break;
-    case BVLT:
-    case BVLE:
-    case BVGT:
-    case BVGE:
-    case BVXOR:
-    case BVNAND:
-    case BVNOR:
-    case BVXNOR:
-      os << kind << "(";
-      c[0].PL_Print1(os,indentation,letize);
-      os << ",";
-      c[1].PL_Print1(os,indentation,letize);
-      os << ")" << endl;
-      break;
-    case BVSLT:
-      os << "SBVLT" << "(";
-      c[0].PL_Print1(os,indentation,letize);
-      os << ",";
-      c[1].PL_Print1(os,indentation,letize);
-      os << ")" << endl;
-      break;
-    case BVSLE:
-      os << "SBVLE" << "(";
-      c[0].PL_Print1(os,indentation,letize);
-      os << ",";
-      c[1].PL_Print1(os,indentation,letize);
-      os << ")" << endl;
-      break;
-    case BVSGT:
-      os << "SBVGT" << "(";
-      c[0].PL_Print1(os,indentation,letize);
-      os << ",";
-      c[1].PL_Print1(os,indentation,letize);
-      os << ")" << endl;
-      break;
-    case BVSGE:
-      os << "SBVGE" << "(";
-      c[0].PL_Print1(os,indentation,letize);
-      os << ",";
-      c[1].PL_Print1(os,indentation,letize);
-      os << ")" << endl;
-      break;
-    case EQ:
-      c[0].PL_Print1(os,indentation,letize);
-      os << " = ";
-      c[1].PL_Print1(os,indentation,letize);      
-      os << endl;
-      break;
-    case NEQ:
-      c[0].PL_Print1(os,indentation,letize);
-      os << " /= ";
-      c[1].PL_Print1(os,indentation,letize);      
-      os << endl;
-      break;
-    case AND:
-    case OR:
-    case NAND:
-    case NOR:
-    case XOR: {
-      os << "(";
-      c[0].PL_Print1(os,indentation,letize);
-      ASTVec::const_iterator it=c.begin();
-      ASTVec::const_iterator itend=c.end();
-
-      it++;
-      for(;it!=itend;it++) {
-       os << " " << kind << " ";
-       it->PL_Print1(os,indentation,letize);
-       os << endl;
-      }
-      os << ")";
-      break;
-    }
-    case IFF:
-      os << "(";
-      os << "(";
-      c[0].PL_Print1(os,indentation,letize);
-      os << ")";
-      os << " <=> ";
-      os << "(";
-      c[1].PL_Print1(os,indentation,letize);      
-      os << ")";
-      os << ")";
-      os << endl;
-      break;
-    case IMPLIES:
-      os << "(";
-      os << "(";
-      c[0].PL_Print1(os,indentation,letize);
-      os << ")";
-      os << " => ";
-      os << "(";
-      c[1].PL_Print1(os,indentation,letize);
-      os << ")";
-      os << ")";
-      os << endl;
-      break;
-    case BVSX:
-    case BVZX: 
-      os << kind << "(";
-      c[0].PL_Print1(os,indentation,letize);
-      os << ",";
-      os << this->GetValueWidth();
-      os << ")" << endl;
-      break;
-    default:
-      //remember to use LispPrinter here. Otherwise this function will
-      //go into an infinite loop. Recall that "<<" is overloaded to
-      //the lisp printer. FatalError uses lispprinter
-      FatalError("PL_Print1: printing not implemented for this kind: ",*this);
-      break;
-    }
-  } //end of PL_Print1()
-
-  ////////////////////////////////////////////////////////////////
-  //  BeevMgr members
-  ////////////////////////////////////////////////////////////////
-  ASTNode BeevMgr::CreateNode(Kind kind, const ASTVec & back_children) {
-    // create a new node.  Children will be modified.
-    ASTInterior *n_ptr = new ASTInterior(kind, *this);
-
-    // insert all of children at end of new_children.
-    ASTNode n(CreateInteriorNode(kind, n_ptr, back_children));
-    return n;
-  }
-
-  ASTNode BeevMgr::CreateNode(Kind kind,
-                             const ASTNode& child0,
-                             const ASTVec & back_children) {
-
-    ASTInterior *n_ptr = new ASTInterior(kind, *this);
-    ASTVec &front_children = n_ptr->_children;
-    front_children.push_back(child0);
-    ASTNode n(CreateInteriorNode(kind, n_ptr,  back_children));
-    return n;
-  }
-  
-  ASTNode BeevMgr::CreateNode(Kind kind,
-                             const ASTNode& child0,
-                             const ASTNode& child1,
-                             const ASTVec & back_children) {
-
-    ASTInterior *n_ptr = new ASTInterior(kind, *this);
-    ASTVec &front_children = n_ptr->_children;
-    front_children.push_back(child0);
-    front_children.push_back(child1);
-    ASTNode n(CreateInteriorNode(kind, n_ptr, back_children));
-    return n;
-  }
-  
-  
-  ASTNode BeevMgr::CreateNode(Kind kind,
-                             const ASTNode& child0,
-                             const ASTNode& child1,
-                             const ASTNode& child2,
-                             const ASTVec & back_children) {
-    ASTInterior *n_ptr = new ASTInterior(kind, *this);
-    ASTVec &front_children = n_ptr->_children;
-    front_children.push_back(child0);
-    front_children.push_back(child1);
-    front_children.push_back(child2);
-    ASTNode n(CreateInteriorNode(kind, n_ptr, back_children));
-    return n;
-  }
-  
-  
-  ASTInterior *BeevMgr::CreateInteriorNode(Kind kind,
-                                          // children array of this node will be modified.
-                                          ASTInterior *n_ptr,
-                                          const ASTVec & back_children) {
-
-    // insert back_children at end of front_children
-    ASTVec &front_children = n_ptr->_children;
-
-    front_children.insert(front_children.end(), back_children.begin(), back_children.end());
-
-    // check for undefined nodes.
-    ASTVec::const_iterator it_end = front_children.end();
-    for (ASTVec::const_iterator it = front_children.begin(); it != it_end; it++) {
-      if (it->IsNull())
-       FatalError("CreateInteriorNode: Undefined childnode in CreateInteriorNode: ", ASTUndefined);      
-    }
-
-    return LookupOrCreateInterior(n_ptr);
-  }
-    
-  /** Trivial but virtual destructor */
-  ASTSymbol::~ASTSymbol() {}
-  
-  ostream &operator<<(ostream &os, const ASTNodeMap &nmap)
-  {
-    ASTNodeMap::const_iterator iend = nmap.end();
-    for (ASTNodeMap::const_iterator i = nmap.begin(); i!=iend; i++) {
-      os << "Key: " << i->first << endl;
-      os << "Value: " << i->second << endl;
-    }
-    return os;
-  }
-  
-  ////////////////////////////////////////////////////////////////
-  // BeevMgr member functions to create ASTSymbol and ASTBVConst
-  ////////////////////////////////////////////////////////////////
-  ASTNode BeevMgr::CreateSymbol(const char * const name) 
-  { 
-    ASTSymbol temp_sym(name, *this);
-    ASTNode n(LookupOrCreateSymbol(temp_sym));
-    return n;
-  }
+
+       //this is to print letvars for shared subterms inside the actual
+       //term to be printed
+       if ((bm.NodeLetVarMap.find(*this) != bm.NodeLetVarMap.end()) && letize)
+       {
+               (bm.NodeLetVarMap[*this]).PL_Print1(os, indentation, letize);
+               return;
+       }
+
+       //otherwise print it normally
+       Kind kind = GetKind();
+       const ASTVec &c = GetChildren();
+       switch (kind)
+       {
+               case BVGETBIT:
+                       c[0].PL_Print1(os, indentation, letize);
+                       os << "{";
+                       c[1].PL_Print1(os, indentation, letize);
+                       os << "}";
+                       break;
+               case BITVECTOR:
+                       os << "BITVECTOR(";
+                       unsigned char * str;
+                       str = CONSTANTBV::BitVector_to_Hex(c[0].GetBVConst());
+                       os << str << ")";
+                       CONSTANTBV::BitVector_Dispose(str);
+                       break;
+               case BOOLEAN:
+                       os << "BOOLEAN";
+                       break;
+               case FALSE:
+               case TRUE:
+                       os << kind;
+                       break;
+               case BVCONST:
+               case SYMBOL:
+                       _int_node_ptr->nodeprint(os);
+                       break;
+               case READ:
+                       c[0].PL_Print1(os, indentation, letize);
+                       os << "[";
+                       c[1].PL_Print1(os, indentation, letize);
+                       os << "]";
+                       break;
+               case WRITE:
+                       os << "(";
+                       c[0].PL_Print1(os, indentation, letize);
+                       os << " WITH [";
+                       c[1].PL_Print1(os, indentation, letize);
+                       os << "] := ";
+                       c[2].PL_Print1(os, indentation, letize);
+                       os << ")";
+                       os << endl;
+                       break;
+               case BVUMINUS:
+                       os << kind << "( ";
+                       c[0].PL_Print1(os, indentation, letize);
+                       os << ")";
+                       break;
+               case NOT:
+                       os << "NOT(";
+                       c[0].PL_Print1(os, indentation, letize);
+                       os << ") " << endl;
+                       break;
+               case BVNEG:
+                       os << " ~(";
+                       c[0].PL_Print1(os, indentation, letize);
+                       os << ")";
+                       break;
+               case BVCONCAT:
+                       os << "(";
+                       c[0].PL_Print1(os, indentation, letize);
+                       os << " @ ";
+                       c[1].PL_Print1(os, indentation, letize);
+                       os << ")" << endl;
+                       break;
+               case BVOR:
+                       os << "(";
+                       c[0].PL_Print1(os, indentation, letize);
+                       os << " | ";
+                       c[1].PL_Print1(os, indentation, letize);
+                       os << ")";
+                       break;
+               case BVAND:
+                       os << "(";
+                       c[0].PL_Print1(os, indentation, letize);
+                       os << " & ";
+                       c[1].PL_Print1(os, indentation, letize);
+                       os << ")";
+                       break;
+               case BVEXTRACT:
+                       c[0].PL_Print1(os, indentation, letize);
+                       os << "[";
+                       os << GetUnsignedConst(c[1]);
+                       os << ":";
+                       os << GetUnsignedConst(c[2]);
+                       os << "]";
+                       break;
+               case BVLEFTSHIFT:
+                       os << "(";
+                       c[0].PL_Print1(os, indentation, letize);
+                       os << " << ";
+                       os << GetUnsignedConst(c[1]);
+                       os << ")";
+                       break;
+               case BVRIGHTSHIFT:
+                       os << "(";
+                       c[0].PL_Print1(os, indentation, letize);
+                       os << " >> ";
+                       os << GetUnsignedConst(c[1]);
+                       os << ")";
+                       break;
+               case BVMULT:
+               case BVSUB:
+               case BVPLUS:
+               case SBVDIV:
+               case SBVREM:
+               case BVDIV:
+               case BVMOD:
+                       os << kind << "(";
+                       os << this->GetValueWidth();
+                       for (ASTVec::const_iterator it = c.begin(), itend = c.end(); it != itend; it++)
+                       {
+                               os << ", " << endl;
+                               it->PL_Print1(os, indentation, letize);
+                       }
+                       os << ")" << endl;
+                       break;
+               case ITE:
+                       os << "IF(";
+                       c[0].PL_Print1(os, indentation, letize);
+                       os << ")" << endl;
+                       os << "THEN ";
+                       c[1].PL_Print1(os, indentation, letize);
+                       os << endl << "ELSE ";
+                       c[2].PL_Print1(os, indentation, letize);
+                       os << endl << "ENDIF";
+                       break;
+               case BVLT:
+               case BVLE:
+               case BVGT:
+               case BVGE:
+               case BVXOR:
+               case BVNAND:
+               case BVNOR:
+               case BVXNOR:
+                       os << kind << "(";
+                       c[0].PL_Print1(os, indentation, letize);
+                       os << ",";
+                       c[1].PL_Print1(os, indentation, letize);
+                       os << ")" << endl;
+                       break;
+               case BVSLT:
+                       os << "SBVLT" << "(";
+                       c[0].PL_Print1(os, indentation, letize);
+                       os << ",";
+                       c[1].PL_Print1(os, indentation, letize);
+                       os << ")" << endl;
+                       break;
+               case BVSLE:
+                       os << "SBVLE" << "(";
+                       c[0].PL_Print1(os, indentation, letize);
+                       os << ",";
+                       c[1].PL_Print1(os, indentation, letize);
+                       os << ")" << endl;
+                       break;
+               case BVSGT:
+                       os << "SBVGT" << "(";
+                       c[0].PL_Print1(os, indentation, letize);
+                       os << ",";
+                       c[1].PL_Print1(os, indentation, letize);
+                       os << ")" << endl;
+                       break;
+               case BVSGE:
+                       os << "SBVGE" << "(";
+                       c[0].PL_Print1(os, indentation, letize);
+                       os << ",";
+                       c[1].PL_Print1(os, indentation, letize);
+                       os << ")" << endl;
+                       break;
+               case EQ:
+                       c[0].PL_Print1(os, indentation, letize);
+                       os << " = ";
+                       c[1].PL_Print1(os, indentation, letize);
+                       os << endl;
+                       break;
+               case NEQ:
+                       c[0].PL_Print1(os, indentation, letize);
+                       os << " /= ";
+                       c[1].PL_Print1(os, indentation, letize);
+                       os << endl;
+                       break;
+               case AND:
+               case OR:
+               case NAND:
+               case NOR:
+               case XOR:
+               {
+                       os << "(";
+                       c[0].PL_Print1(os, indentation, letize);
+                       ASTVec::const_iterator it = c.begin();
+                       ASTVec::const_iterator itend = c.end();
+
+                       it++;
+                       for (; it != itend; it++)
+                       {
+                               os << " " << kind << " ";
+                               it->PL_Print1(os, indentation, letize);
+                               os << endl;
+                       }
+                       os << ")";
+                       break;
+               }
+               case IFF:
+                       os << "(";
+                       os << "(";
+                       c[0].PL_Print1(os, indentation, letize);
+                       os << ")";
+                       os << " <=> ";
+                       os << "(";
+                       c[1].PL_Print1(os, indentation, letize);
+                       os << ")";
+                       os << ")";
+                       os << endl;
+                       break;
+               case IMPLIES:
+                       os << "(";
+                       os << "(";
+                       c[0].PL_Print1(os, indentation, letize);
+                       os << ")";
+                       os << " => ";
+                       os << "(";
+                       c[1].PL_Print1(os, indentation, letize);
+                       os << ")";
+                       os << ")";
+                       os << endl;
+                       break;
+               case BVSX:
+               case BVZX:
+                       os << kind << "(";
+                       c[0].PL_Print1(os, indentation, letize);
+                       os << ",";
+                       os << this->GetValueWidth();
+                       os << ")" << endl;
+                       break;
+               default:
+                       //remember to use LispPrinter here. Otherwise this function will
+                       //go into an infinite loop. Recall that "<<" is overloaded to
+                       //the lisp printer. FatalError uses lispprinter
+                       FatalError("PL_Print1: printing not implemented for this kind: ", *this);
+                       break;
+       }
+} //end of PL_Print1()
+
+////////////////////////////////////////////////////////////////
+//  BeevMgr members
+////////////////////////////////////////////////////////////////
+ASTNode BeevMgr::CreateNode(Kind kind, const ASTVec & back_children)
+{
+       // create a new node.  Children will be modified.
+       ASTInterior *n_ptr = new ASTInterior(kind, *this);
+
+       // insert all of children at end of new_children.
+       ASTNode n(CreateInteriorNode(kind, n_ptr, back_children));
+       return n;
+}
+
+ASTNode BeevMgr::CreateNode(Kind kind, const ASTNode& child0, const ASTVec & back_children)
+{
+
+       ASTInterior *n_ptr = new ASTInterior(kind, *this);
+       ASTVec &front_children = n_ptr->_children;
+       front_children.push_back(child0);
+       ASTNode n(CreateInteriorNode(kind, n_ptr, back_children));
+       return n;
+}
+
+ASTNode BeevMgr::CreateNode(Kind kind, const ASTNode& child0, const ASTNode& child1, const ASTVec & back_children)
+{
+
+       ASTInterior *n_ptr = new ASTInterior(kind, *this);
+       ASTVec &front_children = n_ptr->_children;
+       front_children.push_back(child0);
+       front_children.push_back(child1);
+       ASTNode n(CreateInteriorNode(kind, n_ptr, back_children));
+       return n;
+}
+
+ASTNode BeevMgr::CreateNode(Kind kind, const ASTNode& child0, const ASTNode& child1, const ASTNode& child2, const ASTVec & back_children)
+{
+       ASTInterior *n_ptr = new ASTInterior(kind, *this);
+       ASTVec &front_children = n_ptr->_children;
+       front_children.push_back(child0);
+       front_children.push_back(child1);
+       front_children.push_back(child2);
+       ASTNode n(CreateInteriorNode(kind, n_ptr, back_children));
+       return n;
+}
+
+ASTInterior *BeevMgr::CreateInteriorNode(Kind kind,
+// children array of this node will be modified.
+               ASTInterior *n_ptr,
+               const ASTVec & back_children)
+{
+
+       // insert back_children at end of front_children
+       ASTVec &front_children = n_ptr->_children;
+
+       front_children.insert(front_children.end(), back_children.begin(), back_children.end());
+
+       // check for undefined nodes.
+       ASTVec::const_iterator it_end = front_children.end();
+       for (ASTVec::const_iterator it = front_children.begin(); it != it_end; it++)
+       {
+               if (it->IsNull())
+                       FatalError("CreateInteriorNode: Undefined childnode in CreateInteriorNode: ", ASTUndefined);
+       }
+
+       return LookupOrCreateInterior(n_ptr);
+}
+
+/** Trivial but virtual destructor */
+ASTSymbol::~ASTSymbol()
+{
+}
+
+ostream &operator<<(ostream &os, const ASTNodeMap &nmap)
+{
+       ASTNodeMap::const_iterator iend = nmap.end();
+       for (ASTNodeMap::const_iterator i = nmap.begin(); i != iend; i++)
+       {
+               os << "Key: " << i->first << endl;
+               os << "Value: " << i->second << endl;
+       }
+       return os;
+}
+
+////////////////////////////////////////////////////////////////
+// BeevMgr member functions to create ASTSymbol and ASTBVConst
+////////////////////////////////////////////////////////////////
+ASTNode BeevMgr::CreateSymbol(const char * const name)
+{
+       ASTSymbol temp_sym(name, *this);
+       ASTNode n(LookupOrCreateSymbol(temp_sym));
+       return n;
+}
 
 #ifndef NATIVE_C_ARITH
-  //Create a ASTBVConst node
-  ASTNode BeevMgr::CreateBVConst(unsigned int width, 
-                                unsigned long long int bvconst){ 
-    if(width > (sizeof(unsigned long long int)<<3) || width <= 0)
-      FatalError("CreateBVConst: trying to create a bvconst of width: ", ASTUndefined, width);
-    
-
-    CBV bv = CONSTANTBV::BitVector_Create(width, true);
-    unsigned long c_val = (~((unsigned long)0)) & bvconst;
-    unsigned int copied = 0;
-
-    // sizeof(unsigned long) returns the number of bytes in unsigned
-    // long. In order to convert it to bits, we need to shift left by
-    // 3. Hence, sizeof(unsigned long) << 3
-
-    //The algo below works as follows: It starts by copying the
-    //lower-order bits of the input "bvconst" in chunks of size =
-    //number of bits in unsigned long. The variable "copied" keeps
-    //track of the number of chunks copied so far
-
-    while(copied + (sizeof(unsigned long)<<3) < width){
-      CONSTANTBV::BitVector_Chunk_Store(bv, sizeof(unsigned long)<<3,copied,c_val);
-      bvconst = bvconst >> (sizeof(unsigned long) << 3);
-      c_val = (~((unsigned long)0)) & bvconst;
-      copied += sizeof(unsigned long) << 3;
-    }
-    CONSTANTBV::BitVector_Chunk_Store(bv,width - copied,copied,c_val);
-    return CreateBVConst(bv,width);
-  }
-
- ASTNode BeevMgr::CreateBVConst(string*& strval, int base,  int bit_width) {
-
-   if(!(2 == base || 10 == base || 16 == base))
-     {
-      FatalError("CreateBVConst: unsupported base: ",ASTUndefined,base);
-     }
-
-    //checking if the input is in the correct format
-    CBV bv = CONSTANTBV::BitVector_Create(bit_width,true);
-    CONSTANTBV::ErrCode e;
-    if(2 == base){
-      e = CONSTANTBV::BitVector_from_Bin(bv, (unsigned char*) strval->c_str());
-    }else if(10 == base){
-      e = CONSTANTBV::BitVector_from_Dec(bv, (unsigned char*) strval->c_str());
-    }else if(16 == base){
-      e = CONSTANTBV::BitVector_from_Hex(bv, (unsigned char*) strval->c_str());
-    }else{
-      e = CONSTANTBV::ErrCode_Pars;
-    }
-
-    if(0 != e) {
-      cerr << "CreateBVConst: " << BitVector_Error(e);
-      FatalError("",ASTUndefined);
-    }
-
-    return CreateBVConst(bv, bit_width);
-  }
-
-
-
-  //Create a ASTBVConst node from std::string
-  ASTNode BeevMgr::CreateBVConst(const char* const strval, int base) {
-    size_t width = strlen((const char *)strval);    
-    if(!(2 == base || 10 == base || 16 == base)){
-      FatalError("CreateBVConst: unsupported base: ",ASTUndefined,base);
-    }
-    //FIXME Tim: Earlier versions of the code assume that the length of
-    //binary strings is 32 bits.
-    if(10 == base) width = 32;
-    if(16 == base) width = width * 4;
-
-    //checking if the input is in the correct format
-    CBV bv = CONSTANTBV::BitVector_Create(width,true);
-    CONSTANTBV::ErrCode e;
-    if(2 == base){
-      e = CONSTANTBV::BitVector_from_Bin(bv, (unsigned char*)strval);
-    }else if(10 == base){
-      e = CONSTANTBV::BitVector_from_Dec(bv, (unsigned char*)strval);
-    }else if(16 == base){
-      e = CONSTANTBV::BitVector_from_Hex(bv, (unsigned char*)strval);
-    }else{
-      e = CONSTANTBV::ErrCode_Pars;
-    }
-
-    if(0 != e) {
-      cerr << "CreateBVConst: " << BitVector_Error(e);
-      FatalError("",ASTUndefined);
-    }
-
-    //FIXME 
-    return CreateBVConst(bv, width);
-  }
-  
-
-  //FIXME Code currently assumes that it will destroy the bitvector passed to it
-  ASTNode BeevMgr::CreateBVConst(CBV bv, unsigned width){
-     ASTBVConst temp_bvconst(bv, width, *this);
-     ASTNode n(LookupOrCreateBVConst(temp_bvconst));
-     
-     CONSTANTBV::BitVector_Destroy(bv);
-     
-     return n;
-  }
-
-  ASTNode BeevMgr::CreateZeroConst(unsigned width) {
-    CBV z = CONSTANTBV::BitVector_Create(width, true);
-    return CreateBVConst(z, width);
-  }
-  
-  ASTNode BeevMgr::CreateOneConst(unsigned width) {
-    CBV o = CONSTANTBV::BitVector_Create(width, true);
-    CONSTANTBV::BitVector_increment(o);
-    
-    return CreateBVConst(o,width);
-  }
-
-  ASTNode BeevMgr::CreateTwoConst(unsigned width) {
-    CBV two = CONSTANTBV::BitVector_Create(width, true);
-    CONSTANTBV::BitVector_increment(two);
-    CONSTANTBV::BitVector_increment(two);
-
-    return CreateBVConst(two,width);
-  }
-
-  ASTNode BeevMgr::CreateMaxConst(unsigned width) {
-    CBV max = CONSTANTBV::BitVector_Create(width, false);
-    CONSTANTBV::BitVector_Fill(max);
-
-    return CreateBVConst(max,width);
-  }
-
-  //To ensure unique BVConst nodes, lookup the node in unique-table
-  //before creating a new one.
-  ASTBVConst *BeevMgr::LookupOrCreateBVConst(ASTBVConst &s) {
-    ASTBVConst *s_ptr = &s;  // it's a temporary key.
-    
-    // Do an explicit lookup to see if we need to create a copy of the string.    
-    ASTBVConstSet::const_iterator it;
-    if ((it = _bvconst_unique_table.find(s_ptr)) == _bvconst_unique_table.end()) {
-      // Make a new ASTBVConst with duplicated string (can't assign
-      // _name because it's const).  Can cast the iterator to
-      // non-const -- carefully.
-
-      ASTBVConst * s_copy = new ASTBVConst(s);      
-      s_copy->SetNodeNum(NewNodeNum());
-      
-      pair<ASTBVConstSet::const_iterator, bool> p = _bvconst_unique_table.insert(s_copy);
-      return *p.first;
-    }
-    else{
-      // return symbol found in table.
-      return *it;
-    }
-  }
-
-  // Inline because we need to wait until unique_table is defined
-  void ASTBVConst::CleanUp() {
-    //  cout << "Deleting node " << this->GetNodeNum() << endl;
-    _bm._bvconst_unique_table.erase(this);
-    delete this;
-  }
-
-  // Get the value of bvconst from a bvconst.  It's an error if kind != BVCONST
-  CBV const ASTNode::GetBVConst() const {
-    if(GetKind() != BVCONST)
-      FatalError("GetBVConst: non bitvector-constant: ",*this);
-    return ((ASTBVConst *) _int_node_ptr)->GetBVConst();      
-  }
+//Create a ASTBVConst node
+ASTNode BeevMgr::CreateBVConst(unsigned int width, unsigned long long int bvconst)
+{
+       if (width > (sizeof(unsigned long long int) << 3) || width <= 0)
+               FatalError("CreateBVConst: trying to create a bvconst of width: ", ASTUndefined, width);
+
+       CBV bv = CONSTANTBV::BitVector_Create(width, true);
+       unsigned long c_val = (~((unsigned long) 0)) & bvconst;
+       unsigned int copied = 0;
+
+       // sizeof(unsigned long) returns the number of bytes in unsigned
+       // long. In order to convert it to bits, we need to shift left by
+       // 3. Hence, sizeof(unsigned long) << 3
+
+       //The algo below works as follows: It starts by copying the
+       //lower-order bits of the input "bvconst" in chunks of size =
+       //number of bits in unsigned long. The variable "copied" keeps
+       //track of the number of chunks copied so far
+
+       while (copied + (sizeof(unsigned long) << 3) < width)
+       {
+               CONSTANTBV::BitVector_Chunk_Store(bv, sizeof(unsigned long) << 3, copied, c_val);
+               bvconst = bvconst >> (sizeof(unsigned long) << 3);
+               c_val = (~((unsigned long) 0)) & bvconst;
+               copied += sizeof(unsigned long) << 3;
+       }
+       CONSTANTBV::BitVector_Chunk_Store(bv, width - copied, copied, c_val);
+       return CreateBVConst(bv, width);
+}
+
+ASTNode BeevMgr::CreateBVConst(string*& strval, int base, int bit_width)
+{
+
+       if (!(2 == base || 10 == base || 16 == base))
+       {
+               FatalError("CreateBVConst: unsupported base: ", ASTUndefined, base);
+       }
+
+       //checking if the input is in the correct format
+       CBV bv = CONSTANTBV::BitVector_Create(bit_width, true);
+       CONSTANTBV::ErrCode e;
+       if (2 == base)
+       {
+               e = CONSTANTBV::BitVector_from_Bin(bv, (unsigned char*) strval->c_str());
+       }
+       else if (10 == base)
+       {
+               e = CONSTANTBV::BitVector_from_Dec(bv, (unsigned char*) strval->c_str());
+       }
+       else if (16 == base)
+       {
+               e = CONSTANTBV::BitVector_from_Hex(bv, (unsigned char*) strval->c_str());
+       }
+       else
+       {
+               e = CONSTANTBV::ErrCode_Pars;
+       }
+
+       if (0 != e)
+       {
+               cerr << "CreateBVConst: " << BitVector_Error(e);
+               FatalError("", ASTUndefined);
+       }
+
+       return CreateBVConst(bv, bit_width);
+}
+
+//Create a ASTBVConst node from std::string
+ASTNode BeevMgr::CreateBVConst(const char* const strval, int base)
+{
+       size_t width = strlen((const char *) strval);
+       if (!(2 == base || 10 == base || 16 == base))
+       {
+               FatalError("CreateBVConst: unsupported base: ", ASTUndefined, base);
+       }
+       //FIXME Tim: Earlier versions of the code assume that the length of
+       //binary strings is 32 bits.
+       if (10 == base)
+               width = 32;
+       if (16 == base)
+               width = width * 4;
+
+       //checking if the input is in the correct format
+       CBV bv = CONSTANTBV::BitVector_Create(width, true);
+       CONSTANTBV::ErrCode e;
+       if (2 == base)
+       {
+               e = CONSTANTBV::BitVector_from_Bin(bv, (unsigned char*) strval);
+       }
+       else if (10 == base)
+       {
+               e = CONSTANTBV::BitVector_from_Dec(bv, (unsigned char*) strval);
+       }
+       else if (16 == base)
+       {
+               e = CONSTANTBV::BitVector_from_Hex(bv, (unsigned char*) strval);
+       }
+       else
+       {
+               e = CONSTANTBV::ErrCode_Pars;
+       }
+
+       if (0 != e)
+       {
+               cerr << "CreateBVConst: " << BitVector_Error(e);
+               FatalError("", ASTUndefined);
+       }
+
+       //FIXME
+       return CreateBVConst(bv, width);
+}
+
+//FIXME Code currently assumes that it will destroy the bitvector passed to it
+ASTNode BeevMgr::CreateBVConst(CBV bv, unsigned width)
+{
+       ASTBVConst temp_bvconst(bv, width, *this);
+       ASTNode n(LookupOrCreateBVConst(temp_bvconst));
+
+       CONSTANTBV::BitVector_Destroy(bv);
+
+       return n;
+}
+
+ASTNode BeevMgr::CreateZeroConst(unsigned width)
+{
+       CBV z = CONSTANTBV::BitVector_Create(width, true);
+       return CreateBVConst(z, width);
+}
+
+ASTNode BeevMgr::CreateOneConst(unsigned width)
+{
+       CBV o = CONSTANTBV::BitVector_Create(width, true);
+       CONSTANTBV::BitVector_increment(o);
+
+       return CreateBVConst(o, width);
+}
+
+ASTNode BeevMgr::CreateTwoConst(unsigned width)
+{
+       CBV two = CONSTANTBV::BitVector_Create(width, true);
+       CONSTANTBV::BitVector_increment(two);
+       CONSTANTBV::BitVector_increment(two);
+
+       return CreateBVConst(two, width);
+}
+
+ASTNode BeevMgr::CreateMaxConst(unsigned width)
+{
+       CBV max = CONSTANTBV::BitVector_Create(width, false);
+       CONSTANTBV::BitVector_Fill(max);
+
+       return CreateBVConst(max, width);
+}
+
+//To ensure unique BVConst nodes, lookup the node in unique-table
+//before creating a new one.
+ASTBVConst *BeevMgr::LookupOrCreateBVConst(ASTBVConst &s)
+{
+       ASTBVConst *s_ptr = &s; // it's a temporary key.
+
+       // Do an explicit lookup to see if we need to create a copy of the string.
+       ASTBVConstSet::const_iterator it;
+       if ((it = _bvconst_unique_table.find(s_ptr)) == _bvconst_unique_table.end())
+       {
+               // Make a new ASTBVConst with duplicated string (can't assign
+               // _name because it's const).  Can cast the iterator to
+               // non-const -- carefully.
+
+               ASTBVConst * s_copy = new ASTBVConst(s);
+               s_copy->SetNodeNum(NewNodeNum());
+
+               pair<ASTBVConstSet::const_iterator, bool> p = _bvconst_unique_table.insert(s_copy);
+               return *p.first;
+       }
+       else
+       {
+               // return symbol found in table.
+               return *it;
+       }
+}
+
+// Inline because we need to wait until unique_table is defined
+void ASTBVConst::CleanUp()
+{
+       //  cout << "Deleting node " << this->GetNodeNum() << endl;
+       _bm._bvconst_unique_table.erase(this);
+       delete this;
+}
+
+// Get the value of bvconst from a bvconst.  It's an error if kind != BVCONST
+CBV const ASTNode::GetBVConst() const
+{
+       if (GetKind() != BVCONST)
+               FatalError("GetBVConst: non bitvector-constant: ", *this);
+       return ((ASTBVConst *) _int_node_ptr)->GetBVConst();
+}
 #else
-  //Create a ASTBVConst node
-  ASTNode BeevMgr::CreateBVConst(const unsigned int width, 
-                                const unsigned long long int bvconst) { 
-    if(width > 64 || width <= 0)
-      FatalError("Fatal Error: CreateBVConst: trying to create a bvconst of width:", ASTUndefined, width);
-    
-    //64 bit mask
-    unsigned long long int mask = 0xffffffffffffffffLL;
-    mask = mask >> (64 - width);
-
-    unsigned long long int bv = bvconst;
-    bv = bv & mask;
-
-    ASTBVConst temp_bvconst(bv, *this);
-    temp_bvconst._value_width = width;    
-    ASTNode n(LookupOrCreateBVConst(temp_bvconst));
-    n.SetValueWidth(width);
-    n.SetIndexWidth(0);
-    return n;
-  }
-  //Create a ASTBVConst node from std::string
-  ASTNode BeevMgr::CreateBVConst(const char* strval, int base) {    
-    if(!(base == 2 || base == 16 || base == 10))
-      FatalError("CreateBVConst: This base is not supported: ", ASTUndefined, base);
-
-    if(10 != base) {
-      unsigned int width = (base == 2) ? strlen(strval) : strlen(strval)*4;
-      unsigned long long int val =  strtoull(strval, NULL, base);
-      ASTNode bvcon = CreateBVConst(width, val);
-      return bvcon;
-    }
-    else {
-      //this is an ugly hack to accomodate SMTLIB format
-      //restrictions. SMTLIB format represents bitvector constants in
-      //base 10 (what a terrible idea, but i have no choice but to
-      //support it), and make an implicit assumption that the length
-      //is 32 (another terrible idea).
-      unsigned width = 32;
-      unsigned long long int val = strtoull(strval, NULL, base);
-      ASTNode bvcon = CreateBVConst(width, val);
-      return bvcon;
-    }
-  }
-  
-  //To ensure unique BVConst nodes, lookup the node in unique-table
-  //before creating a new one.
-  ASTBVConst *BeevMgr::LookupOrCreateBVConst(ASTBVConst &s) {
-    ASTBVConst *s_ptr = &s;    // it's a temporary key.
-
-    // Do an explicit lookup to see if we need to create a copy of the
-    // string.
-    ASTBVConstSet::const_iterator it;
-    if ((it = _bvconst_unique_table.find(s_ptr)) == _bvconst_unique_table.end()) {
-      // Make a new ASTBVConst. Can cast the iterator to non-const --
-      // carefully.
-      unsigned int width = s_ptr->_value_width;
-      ASTBVConst * s_ptr1 = new ASTBVConst(s_ptr->GetBVConst(), *this);
-      s_ptr1->SetNodeNum(NewNodeNum());
-      s_ptr1->_value_width = width;
-      pair<ASTBVConstSet::const_iterator, bool> p = _bvconst_unique_table.insert(s_ptr1);
-      return *p.first;
-    }
-    else
-      // return BVConst found in table.
-      return *it;
-  }
-
-  // Inline because we need to wait until unique_table is defined
-  void ASTBVConst::CleanUp() {
-    //  cout << "Deleting node " << this->GetNodeNum() << endl;
-    _bm._bvconst_unique_table.erase(this);
-    delete this;
-  }
-
-  // Get the value of bvconst from a bvconst.  It's an error if kind
-  // != BVCONST
-  unsigned long long int ASTNode::GetBVConst() const {
-    if(GetKind() != BVCONST)
-      FatalError("GetBVConst: non bitvector-constant: ", *this);
-    return ((ASTBVConstTmp *) _int_node_ptr)->GetBVConst();
-  }
-
-  ASTNode BeevMgr::CreateZeroConst(unsigned width) {
-    return CreateBVConst(width,0);
-  }
-  
-  ASTNode BeevMgr::CreateOneConst(unsigned width) {
-    return CreateBVConst(width,1);
-  }
-
-  ASTNode BeevMgr::CreateTwoConst(unsigned width) {
-    return CreateBVConst(width,2);
-  }
-
-  ASTNode BeevMgr::CreateMaxConst(unsigned width) {
-    std::string s;
-    s.insert(s.end(),width,'1');
-    return CreateBVConst(s.c_str(),2);
-  }
-
-#endif  
-
-  // FIXME: _name is now a constant field, and this assigns to it
-  // because it tries not to copy the string unless it needs to.  How
-  // do I avoid copying children in ASTInterior?  Perhaps I don't!
-  
-  // Note: There seems to be a limitation of hash_set, in that insert
-  // returns a const iterator to the value.  That prevents us from
-  // modifying the name (in a hash-preserving way) after the symbol is
-  // inserted.  FIXME: Is there a way to do this with insert?  Need a
-  // function to make a new object in the middle of insert.  Read STL
-  // documentation.
-  
-  ASTSymbol *BeevMgr::LookupOrCreateSymbol(ASTSymbol& s) {
-    ASTSymbol *s_ptr = &s;  // it's a temporary key.
-    
-    // Do an explicit lookup to see if we need to create a copy of the string.    
-    ASTSymbolSet::const_iterator it;
-    if ((it = _symbol_unique_table.find(s_ptr)) == _symbol_unique_table.end()) {
-      // Make a new ASTSymbol with duplicated string (can't assign
-      // _name because it's const).  Can cast the iterator to
-      // non-const -- carefully.
-      //std::string strname(s_ptr->GetName());
-      ASTSymbol * s_ptr1 = new ASTSymbol(strdup(s_ptr->GetName()), *this);
-      s_ptr1->SetNodeNum(NewNodeNum());
-      s_ptr1->_value_width = s_ptr->_value_width;
-      pair<ASTSymbolSet::const_iterator, bool> p = _symbol_unique_table.insert(s_ptr1);
-      return *p.first;
-    }
-    else
-      // return symbol found in table.
-      return *it;    
-  }
-
-  bool BeevMgr::LookupSymbol(ASTSymbol& s) {
-    ASTSymbol* s_ptr = &s;  // it's a temporary key.
-
-    if(_symbol_unique_table.find(s_ptr) == _symbol_unique_table.end()) 
-      return false;
-    else
-      return true;
-  }
-
-  // Inline because we need to wait until unique_table is defined
-  void ASTSymbol::CleanUp() {
-    //  cout << "Deleting node " << this->GetNodeNum() << endl;
-    _bm._symbol_unique_table.erase(this);
-    //FIXME This is a HUGE free to invoke.
-    //TEST IT!
-    free((char*) this->_name);
-    delete this;
-  }
-  
-  ////////////////////////////////////////////////////////////////
-  //
-  //  IO manipulators for Lisp format printing of AST.
-  //
-  ////////////////////////////////////////////////////////////////
-  
-  // FIXME: Additional controls
-  //   * Print node numbers  (addresses/nums)
-  //   * Printlength limit
-  //   * Printdepth limit
-  
-  /** Print a vector of ASTNodes in lisp format */
-  ostream &LispPrintVec(ostream &os, const ASTVec &v, int indentation)
-  {
-    // Print the children
-    ASTVec::const_iterator iend = v.end();
-    for (ASTVec::const_iterator i = v.begin(); i != iend; i++) {
-      i->LispPrint_indent(os, indentation);
-    }
-    return os;
-  }
-
-  ostream &LispPrintVecSpecial(ostream &os, const vector<const ASTNode*> &v, int indentation)
-  {
-    // Print the children
-    vector<const ASTNode*>::const_iterator iend = v.end();
-    for (vector<const ASTNode*>::const_iterator i = v.begin(); i != iend; i++) {
-      (*i)->LispPrint_indent(os, indentation);
-    }
-    return os;
-  }
-
-  // FIXME: Made non-ref in the hope that it would work better.
-  void lp(ASTNode node)
-  {
-    cout << lisp(node) << endl;
-  }
-
-  void lpvec(const ASTVec &vec)
-  {
-    vec[0].GetBeevMgr().AlreadyPrintedSet.clear();
-    LispPrintVec(cout, vec, 0);
-    cout << endl;
-  }
-
-  // Copy constructor.  Maintain _ref_count
-  ASTNode::ASTNode(const ASTNode &n) : _int_node_ptr(n._int_node_ptr) {
-#ifndef SMTLIB    
-    if (n._int_node_ptr) {
-      n._int_node_ptr->IncRef();
-    }
+//Create a ASTBVConst node
+ASTNode BeevMgr::CreateBVConst(const unsigned int width,
+               const unsigned long long int bvconst)
+{
+       if(width > 64 || width <= 0)
+       FatalError("Fatal Error: CreateBVConst: trying to create a bvconst of width:", ASTUndefined, width);
+
+       //64 bit mask
+       unsigned long long int mask = 0xffffffffffffffffLL;
+       mask = mask >> (64 - width);
+
+       unsigned long long int bv = bvconst;
+       bv = bv & mask;
+
+       ASTBVConst temp_bvconst(bv, *this);
+       temp_bvconst._value_width = width;
+       ASTNode n(LookupOrCreateBVConst(temp_bvconst));
+       n.SetValueWidth(width);
+       n.SetIndexWidth(0);
+       return n;
+}
+//Create a ASTBVConst node from std::string
+ASTNode BeevMgr::CreateBVConst(const char* strval, int base)
+{
+       if(!(base == 2 || base == 16 || base == 10))
+       FatalError("CreateBVConst: This base is not supported: ", ASTUndefined, base);
+
+       if(10 != base)
+       {
+               unsigned int width = (base == 2) ? strlen(strval) : strlen(strval)*4;
+               unsigned long long int val = strtoull(strval, NULL, base);
+               ASTNode bvcon = CreateBVConst(width, val);
+               return bvcon;
+       }
+       else
+       {
+               //this is an ugly hack to accomodate SMTLIB format
+               //restrictions. SMTLIB format represents bitvector constants in
+               //base 10 (what a terrible idea, but i have no choice but to
+               //support it), and make an implicit assumption that the length
+               //is 32 (another terrible idea).
+               unsigned width = 32;
+               unsigned long long int val = strtoull(strval, NULL, base);
+               ASTNode bvcon = CreateBVConst(width, val);
+               return bvcon;
+       }
+}
+
+//To ensure unique BVConst nodes, lookup the node in unique-table
+//before creating a new one.
+ASTBVConst *BeevMgr::LookupOrCreateBVConst(ASTBVConst &s)
+{
+       ASTBVConst *s_ptr = &s; // it's a temporary key.
+
+       // Do an explicit lookup to see if we need to create a copy of the
+       // string.
+       ASTBVConstSet::const_iterator it;
+       if ((it = _bvconst_unique_table.find(s_ptr)) == _bvconst_unique_table.end())
+       {
+               // Make a new ASTBVConst. Can cast the iterator to non-const --
+               // carefully.
+               unsigned int width = s_ptr->_value_width;
+               ASTBVConst * s_ptr1 = new ASTBVConst(s_ptr->GetBVConst(), *this);
+               s_ptr1->SetNodeNum(NewNodeNum());
+               s_ptr1->_value_width = width;
+               pair<ASTBVConstSet::const_iterator, bool> p = _bvconst_unique_table.insert(s_ptr1);
+               return *p.first;
+       }
+       else
+       // return BVConst found in table.
+       return *it;
+}
+
+// Inline because we need to wait until unique_table is defined
+void ASTBVConst::CleanUp()
+{
+       //  cout << "Deleting node " << this->GetNodeNum() << endl;
+       _bm._bvconst_unique_table.erase(this);
+       delete this;
+}
+
+// Get the value of bvconst from a bvconst.  It's an error if kind
+// != BVCONST
+unsigned long long int ASTNode::GetBVConst() const
+{
+       if(GetKind() != BVCONST)
+       FatalError("GetBVConst: non bitvector-constant: ", *this);
+       return ((ASTBVConstTmp *) _int_node_ptr)->GetBVConst();
+}
+
+ASTNode BeevMgr::CreateZeroConst(unsigned width)
+{
+       return CreateBVConst(width,0);
+}
+
+ASTNode BeevMgr::CreateOneConst(unsigned width)
+{
+       return CreateBVConst(width,1);
+}
+
+ASTNode BeevMgr::CreateTwoConst(unsigned width)
+{
+       return CreateBVConst(width,2);
+}
+
+ASTNode BeevMgr::CreateMaxConst(unsigned width)
+{
+       std::string s;
+       s.insert(s.end(),width,'1');
+       return CreateBVConst(s.c_str(),2);
+}
+
+#endif
+
+// FIXME: _name is now a constant field, and this assigns to it
+// because it tries not to copy the string unless it needs to.  How
+// do I avoid copying children in ASTInterior?  Perhaps I don't!
+
+// Note: There seems to be a limitation of hash_set, in that insert
+// returns a const iterator to the value.  That prevents us from
+// modifying the name (in a hash-preserving way) after the symbol is
+// inserted.  FIXME: Is there a way to do this with insert?  Need a
+// function to make a new object in the middle of insert.  Read STL
+// documentation.
+
+ASTSymbol *BeevMgr::LookupOrCreateSymbol(ASTSymbol& s)
+{
+       ASTSymbol *s_ptr = &s; // it's a temporary key.
+
+       // Do an explicit lookup to see if we need to create a copy of the string.
+       ASTSymbolSet::const_iterator it;
+       if ((it = _symbol_unique_table.find(s_ptr)) == _symbol_unique_table.end())
+       {
+               // Make a new ASTSymbol with duplicated string (can't assign
+               // _name because it's const).  Can cast the iterator to
+               // non-const -- carefully.
+               //std::string strname(s_ptr->GetName());
+               ASTSymbol * s_ptr1 = new ASTSymbol(strdup(s_ptr->GetName()), *this);
+               s_ptr1->SetNodeNum(NewNodeNum());
+               s_ptr1->_value_width = s_ptr->_value_width;
+               pair<ASTSymbolSet::const_iterator, bool> p = _symbol_unique_table.insert(s_ptr1);
+               return *p.first;
+       }
+       else
+               // return symbol found in table.
+               return *it;
+}
+
+bool BeevMgr::LookupSymbol(ASTSymbol& s)
+{
+       ASTSymbol* s_ptr = &s; // it's a temporary key.
+
+       if (_symbol_unique_table.find(s_ptr) == _symbol_unique_table.end())
+               return false;
+       else
+               return true;
+}
+
+// Inline because we need to wait until unique_table is defined
+void ASTSymbol::CleanUp()
+{
+       //  cout << "Deleting node " << this->GetNodeNum() << endl;
+       _bm._symbol_unique_table.erase(this);
+       //FIXME This is a HUGE free to invoke.
+       //TEST IT!
+       free((char*) this->_name);
+       delete this;
+}
+
+////////////////////////////////////////////////////////////////
+//
+//  IO manipulators for Lisp format printing of AST.
+//
+////////////////////////////////////////////////////////////////
+
+// FIXME: Additional controls
+//   * Print node numbers  (addresses/nums)
+//   * Printlength limit
+//   * Printdepth limit
+
+/** Print a vector of ASTNodes in lisp format */
+ostream &LispPrintVec(ostream &os, const ASTVec &v, int indentation)
+{
+       // Print the children
+       ASTVec::const_iterator iend = v.end();
+       for (ASTVec::const_iterator i = v.begin(); i != iend; i++)
+       {
+               i->LispPrint_indent(os, indentation);
+       }
+       return os;
+}
+
+ostream &LispPrintVecSpecial(ostream &os, const vector<const ASTNode*> &v, int indentation)
+{
+       // Print the children
+       vector<const ASTNode*>::const_iterator iend = v.end();
+       for (vector<const ASTNode*>::const_iterator i = v.begin(); i != iend; i++)
+       {
+               (*i)->LispPrint_indent(os, indentation);
+       }
+       return os;
+}
+
+// FIXME: Made non-ref in the hope that it would work better.
+void lp(ASTNode node)
+{
+       cout << lisp(node) << endl;
+}
+
+void lpvec(const ASTVec &vec)
+{
+       vec[0].GetBeevMgr().AlreadyPrintedSet.clear();
+       LispPrintVec(cout, vec, 0);
+       cout << endl;
+}
+
+// Copy constructor.  Maintain _ref_count
+ASTNode::ASTNode(const ASTNode &n) :
+       _int_node_ptr(n._int_node_ptr)
+{
+#ifndef SMTLIB
+       if (n._int_node_ptr)
+       {
+               n._int_node_ptr->IncRef();
+       }
 #endif
-  }
-  
-
-  /* FUNCTION: Typechecker for terms and formulas
-   * 
-   * TypeChecker: Assumes that the immediate Children of the input
-   * ASTNode have been typechecked. This function is suitable in
-   * scenarios like where you are building the ASTNode Tree, and you
-   * typecheck as you go along. It is not suitable as a general
-   * typechecker      
-   */
-  void BeevMgr::BVTypeCheck(const ASTNode& n) {
-    Kind k = n.GetKind();
-    //The children of bitvector terms are in turn bitvectors.
-    const ASTVec& v = n.GetChildren();
-    if(is_Term_kind(k)) {
-      switch(k) {
-      case BVCONST:
-       if(BITVECTOR_TYPE != n.GetType())
-         FatalError("BVTypeCheck: The term t does not typecheck, where t = \n",n);
-       break;
-      case SYMBOL:
-       return;
-      case ITE:     
-       if (BOOLEAN_TYPE != n[0].GetType() || (n[1].GetType() != n[2].GetType()))
-         FatalError("BVTypeCheck: The term t does not typecheck, where t = \n",n);
-       if(n[1].GetValueWidth() != n[2].GetValueWidth())
-         FatalError("BVTypeCheck: length of THENbranch != length of ELSEbranch in the term t = \n",n);
-       if(n[1].GetIndexWidth() != n[2].GetIndexWidth())
-         FatalError("BVTypeCheck: length of THENbranch != length of ELSEbranch in the term t = \n",n);
-       break;
-      case READ:
-       if(n[0].GetIndexWidth() != n[1].GetValueWidth()) {
-         cerr << "Length of indexwidth of array: " << n[0] << " is : " << n[0].GetIndexWidth() << endl;
-         cerr << "Length of the actual index is: " << n[1] << " is : " << n[1].GetValueWidth() << endl;
-         FatalError("BVTypeCheck: length of indexwidth of array != length of actual index in the term t = \n",n);
+}
+
+/* FUNCTION: Typechecker for terms and formulas
+ *
+ * TypeChecker: Assumes that the immediate Children of the input
+ * ASTNode have been typechecked. This function is suitable in
+ * scenarios like where you are building the ASTNode Tree, and you
+ * typecheck as you go along. It is not suitable as a general
+ * typechecker
+ */
+void BeevMgr::BVTypeCheck(const ASTNode& n)
+{
+       Kind k = n.GetKind();
+       //The children of bitvector terms are in turn bitvectors.
+       const ASTVec& v = n.GetChildren();
+       if (is_Term_kind(k))
+       {
+               switch (k)
+               {
+                       case BVCONST:
+                               if (BITVECTOR_TYPE != n.GetType())
+                                       FatalError("BVTypeCheck: The term t does not typecheck, where t = \n", n);
+                               break;
+                       case SYMBOL:
+                               return;
+                       case ITE:
+                               if (BOOLEAN_TYPE != n[0].GetType() || (n[1].GetType() != n[2].GetType()))
+                                       FatalError("BVTypeCheck: The term t does not typecheck, where t = \n", n);
+                               if (n[1].GetValueWidth() != n[2].GetValueWidth())
+                                       FatalError("BVTypeCheck: length of THENbranch != length of ELSEbranch in the term t = \n", n);
+                               if (n[1].GetIndexWidth() != n[2].GetIndexWidth())
+                                       FatalError("BVTypeCheck: length of THENbranch != length of ELSEbranch in the term t = \n", n);
+                               break;
+                       case READ:
+                               if (n[0].GetIndexWidth() != n[1].GetValueWidth())
+                               {
+                                       cerr << "Length of indexwidth of array: " << n[0] << " is : " << n[0].GetIndexWidth() << endl;
+                                       cerr << "Length of the actual index is: " << n[1] << " is : " << n[1].GetValueWidth() << endl;
+                                       FatalError("BVTypeCheck: length of indexwidth of array != length of actual index in the term t = \n", n);
+                               }
+                               break;
+                       case WRITE:
+                               if (n[0].GetIndexWidth() != n[1].GetValueWidth())
+                                       FatalError("BVTypeCheck: length of indexwidth of array != length of actual index in the term t = \n", n);
+                               if (n[0].GetValueWidth() != n[2].GetValueWidth())
+                                       FatalError("BVTypeCheck: valuewidth of array != length of actual value in the term t = \n", n);
+                               break;
+                       case BVOR:
+                       case BVAND:
+                       case BVXOR:
+                       case BVNOR:
+                       case BVNAND:
+                       case BVXNOR:
+                       case BVPLUS:
+                       case BVMULT:
+                       case BVDIV:
+                       case BVMOD:
+                       case BVSUB:
+                       {
+                               if (!(v.size() >= 2))
+                                       FatalError("BVTypeCheck:bitwise Booleans and BV arith operators must have atleast two arguments\n", n);
+                               unsigned int width = n.GetValueWidth();
+                               for (ASTVec::const_iterator it = v.begin(), itend = v.end(); it != itend; it++)
+                               {
+                                       if (width != it->GetValueWidth())
+                                       {
+                                               cerr << "BVTypeCheck:Operands of bitwise-Booleans and BV arith operators must be of equal length\n";
+                                               cerr << n << endl;
+                                               cerr << "width of term:" << width << endl;
+                                               cerr << "width of offending operand:" << it->GetValueWidth() << endl;
+                                               FatalError("BVTypeCheck:Offending operand:\n", *it);
+                                       }
+                                       if (BITVECTOR_TYPE != it->GetType())
+                                               FatalError("BVTypeCheck: ChildNodes of bitvector-terms must be bitvectors\n", n);
+                               }
+                               break;
+                       }
+                       case BVSX:
+                               //in BVSX(n[0],len), the length of the BVSX term must be
+                               //greater than the length of n[0]
+                               if (n[0].GetValueWidth() > n.GetValueWidth())
+                               {
+                                       FatalError("BVTypeCheck: BVSX(t,bvsx_len) : length of 't' must be <= bvsx_len\n", n);
+                               }
+                               break;
+
+                       case BVZX:
+                               //in BVZX(n[0],len), the length of the BVZX term must be
+                               //greater than the length of n[0]
+                               if (n[0].GetValueWidth() > n.GetValueWidth())
+                               {
+                                       FatalError("BVTypeCheck: BVZX(t,bvzx_len) : length of 't' must be <= bvzx_len\n", n);
+                               }
+                               break;
+
+                       default:
+                               for (ASTVec::const_iterator it = v.begin(), itend = v.end(); it != itend; it++)
+                                       if (BITVECTOR_TYPE != it->GetType())
+                                       {
+                                               cerr << "The type is: " << it->GetType() << endl;
+                                               FatalError("BVTypeCheck:ChildNodes of bitvector-terms must be bitvectors\n", n);
+                                       }
+                               break;
+               }
+
+               switch (k)
+               {
+                       case BVCONCAT:
+                               if (n.Degree() != 2)
+                                       FatalError("BVTypeCheck: should have exactly 2 args\n", n);
+                               if (n.GetValueWidth() != n[0].GetValueWidth() + n[1].GetValueWidth())
+                                       FatalError("BVTypeCheck:BVCONCAT: lengths do not add up\n", n);
+                               break;
+                       case BVUMINUS:
+                       case BVNEG:
+                               if (n.Degree() != 1)
+                                       FatalError("BVTypeCheck: should have exactly 1 args\n", n);
+                               break;
+                       case BVEXTRACT:
+                               if (n.Degree() != 3)
+                                       FatalError("BVTypeCheck: should have exactly 3 args\n", n);
+                               if (!(BVCONST == n[1].GetKind() && BVCONST == n[2].GetKind()))
+                                       FatalError("BVTypeCheck: indices should be BVCONST\n", n);
+                               if (n.GetValueWidth() != GetUnsignedConst(n[1]) - GetUnsignedConst(n[2]) + 1)
+                                       FatalError("BVTypeCheck: length mismatch\n", n);
+                               break;
+                       case BVLEFTSHIFT:
+                       case BVRIGHTSHIFT:
+                               if (n.Degree() != 2)
+                                       FatalError("BVTypeCheck: should have exactly 2 args\n", n);
+                               break;
+                               //case BVVARSHIFT:
+                               //case BVSRSHIFT:
+                               break;
+                       default:
+                               break;
+               }
+       }
+       else
+       {
+               if (!(is_Form_kind(k) && BOOLEAN_TYPE == n.GetType()))
+                       FatalError("BVTypeCheck: not a formula:", n);
+               switch (k)
+               {
+                       case TRUE:
+                       case FALSE:
+                       case SYMBOL:
+                               return;
+                       case EQ:
+                       case NEQ:
+                               if (!(n[0].GetValueWidth() == n[1].GetValueWidth() && n[0].GetIndexWidth() == n[1].GetIndexWidth()))
+                               {
+                                       cerr << "valuewidth of lhs of EQ: " << n[0].GetValueWidth() << endl;
+                                       cerr << "valuewidth of rhs of EQ: " << n[1].GetValueWidth() << endl;
+                                       cerr << "indexwidth of lhs of EQ: " << n[0].GetIndexWidth() << endl;
+                                       cerr << "indexwidth of rhs of EQ: " << n[1].GetIndexWidth() << endl;
+                                       FatalError("BVTypeCheck: terms in atomic formulas must be of equal length", n);
+                               }
+                               break;
+                       case BVLT:
+                       case BVLE:
+                       case BVGT:
+                       case BVGE:
+                       case BVSLT:
+                       case BVSLE:
+                       case BVSGT:
+                       case BVSGE:
+                               if (BITVECTOR_TYPE != n[0].GetType() && BITVECTOR_TYPE != n[1].GetType())
+                                       FatalError("BVTypeCheck: terms in atomic formulas must be bitvectors", n);
+                               if (n[0].GetValueWidth() != n[1].GetValueWidth())
+                                       FatalError("BVTypeCheck: terms in atomic formulas must be of equal length", n);
+                               if (n[0].GetIndexWidth() != n[1].GetIndexWidth())
+                                       FatalError("BVTypeCheck: terms in atomic formulas must be of equal length", n);
+                               break;
+                       case NOT:
+                               if (1 != n.Degree())
+                                       FatalError("BVTypeCheck: NOT formula can have exactly one childNode", n);
+                               break;
+                       case AND:
+                       case OR:
+                       case XOR:
+                       case NAND:
+                       case NOR:
+                               if (2 > n.Degree())
+                                       FatalError("BVTypeCheck: AND/OR/XOR/NAND/NOR: must have atleast 2 ChildNodes", n);
+                               break;
+                       case IFF:
+                       case IMPLIES:
+                               if (2 != n.Degree())
+                                       FatalError("BVTypeCheck:IFF/IMPLIES must have exactly 2 ChildNodes", n);
+                               break;
+                       case ITE:
+                               if (3 != n.Degree())
+                                       FatalError("BVTypeCheck:ITE must have exactly 3 ChildNodes", n);
+                               break;
+                       default:
+                               FatalError("BVTypeCheck: Unrecognized kind: ", ASTUndefined);
+                               break;
+               }
+       }
+} //End of TypeCheck function
+
+//add an assertion to the current logical context
+void BeevMgr::AddAssert(const ASTNode& assert)
+{
+       if (!(is_Form_kind(assert.GetKind()) && BOOLEAN_TYPE == assert.GetType()))
+       {
+               FatalError("AddAssert:Trying to assert a non-formula:", assert);
+       }
+
+       ASTVec * v;
+       //if the stack of ASTVec is not empty, then take the top ASTVec
+       //and add the input assert to it
+       if (!_asserts.empty())
+       {
+               v = _asserts.back();
+               //v->push_back(TransformFormula(assert));
+               v->push_back(assert);
+       }
+       else
+       {
+               //else create a logical context, and add it to the top of the
+               //stack
+               v = new ASTVec();
+               //v->push_back(TransformFormula(assert));
+               v->push_back(assert);
+               _asserts.push_back(v);
+       }
+}
+
+void BeevMgr::Push(void)
+{
+       ASTVec * v;
+       v = new ASTVec();
+       _asserts.push_back(v);
+}
+
+void BeevMgr::Pop(void)
+{
+       if (!_asserts.empty())
+       {
+               ASTVec * c = _asserts.back();
+               //by calling the clear function we ensure that the ref count is
+               //decremented for the ASTNodes stored in c
+               c->clear();
+               delete c;
+               _asserts.pop_back();
+       }
+}
+
+void BeevMgr::AddQuery(const ASTNode& q)
+{
+       //_current_query = TransformFormula(q);
+       //cerr << "\nThe current query is: " << q << endl;
+       _current_query = q;
+}
+
+const ASTNode BeevMgr::PopQuery()
+{
+       ASTNode q = _current_query;
+       _current_query = ASTTrue;
+       return q;
+}
+
+const ASTNode BeevMgr::GetQuery()
+{
+       return _current_query;
+}
+
+const ASTVec BeevMgr::GetAsserts(void)
+{
+       vector<ASTVec *>::iterator it = _asserts.begin();
+       vector<ASTVec *>::iterator itend = _asserts.end();
+
+       ASTVec v;
+       for (; it != itend; it++)
+       {
+               if (!(*it)->empty())
+                       v.insert(v.end(), (*it)->begin(), (*it)->end());
+       }
+       return v;
+}
+
+//Create a new variable of ValueWidth 'n'
+ASTNode BeevMgr::NewArrayVar(unsigned int index, unsigned int value)
+{
+       std::string c("v");
+       char d[32];
+       sprintf(d, "%d", _symbol_count++);
+       std::string ccc(d);
+       c += "_writearray_" + ccc;
+
+       ASTNode CurrentSymbol = CreateSymbol(c.c_str());
+       CurrentSymbol.SetValueWidth(value);
+       CurrentSymbol.SetIndexWidth(index);
+       return CurrentSymbol;
+} //end of NewArrayVar()
+
+
+//Create a new variable of ValueWidth 'n'
+ASTNode BeevMgr::NewVar(unsigned int value)
+{
+       std::string c("v");
+       char d[32];
+       sprintf(d, "%d", _symbol_count++);
+       std::string ccc(d);
+       c += "_new_stp_var_" + ccc;
+
+       ASTNode CurrentSymbol = CreateSymbol(c.c_str());
+       CurrentSymbol.SetValueWidth(value);
+       CurrentSymbol.SetIndexWidth(0);
+       _introduced_symbols.insert(CurrentSymbol);
+       return CurrentSymbol;
+} //end of NewVar()
+
+//prints statistics for the ASTNode
+void BeevMgr::ASTNodeStats(const char * c, const ASTNode& a)
+{
+       if (!stats)
+               return;
+
+       StatInfoSet.clear();
+       //print node size:
+       cout << endl << "Printing: " << c;
+       if (print_nodes)
+       {
+               //a.PL_Print(cout,0);
+               //cout << endl;
+               cout << a << endl;
+       }
+       cout << "Node size is: ";
+       cout << NodeSize(a) << endl << endl;
+}
+
+unsigned int BeevMgr::NodeSize(const ASTNode& a, bool clearStatInfo)
+{
+       if (clearStatInfo)
+               StatInfoSet.clear();
+
+       ASTNodeSet::iterator it;
+       if ((it = StatInfoSet.find(a)) != StatInfoSet.end())
+               //has already been counted
+               return 0;
+
+       //record that you have seen this node already
+       StatInfoSet.insert(a);
+
+       //leaf node has a size of 1
+       if (a.Degree() == 0)
+               return 1;
+
+       unsigned newn = 1;
+       ASTVec c = a.GetChildren();
+       for (ASTVec::iterator it = c.begin(), itend = c.end(); it != itend; it++)
+               newn += NodeSize(*it);
+       return newn;
+}
+
+void BeevMgr::ClearAllTables(void)
+{
+       //clear all tables before calling toplevelsat
+       _ASTNode_to_SATVar.clear();
+       _SATVar_to_AST.clear();
+
+       for (ASTtoBitvectorMap::iterator it = _ASTNode_to_Bitvector.begin(), itend = _ASTNode_to_Bitvector.end(); it != itend; it++)
+       {
+               (it->second)->clear();
+               delete (it->second);
+       }
+       _ASTNode_to_Bitvector.clear();
+
+       /* OLD Destructor
+        * for(ASTNodeToVecMap::iterator ivec = BBTermMemo.begin(),
+        ivec_end=BBTermMemo.end();ivec!=ivec_end;ivec++) {
+        ivec->second.clear();
+        }*/
+
+       /*What should I do here? For ASTNodes?
+        * for(ASTNodeMap::iterator ivec = BBTermMemo.begin(),
+        ivec_end=BBTermMemo.end();ivec!=ivec_end;ivec++) {
+        ivec->second.clear();
+        }*/
+       BBTermMemo.clear();
+       BBFormMemo.clear();
+       NodeLetVarMap.clear();
+       NodeLetVarMap1.clear();
+       PLPrintNodeSet.clear();
+       AlreadyPrintedSet.clear();
+       SimplifyMap->clear();
+       SimplifyNegMap->clear();
+       SolverMap.clear();
+       AlwaysTrueFormMap.clear();
+       _arrayread_ite.clear();
+       _arrayread_symbol.clear();
+       _introduced_symbols.clear();
+       TransformMap.clear();
+       _letid_expr_map->clear();
+       CounterExampleMap.clear();
+       ComputeFormulaMap.clear();
+       StatInfoSet.clear();
+
+       // for(std::vector<ASTVec *>::iterator it=_asserts.begin(),
+       //        itend=_asserts.end();it!=itend;it++) {
+       //       (*it)->clear();
+       //     }
+       _asserts.clear();
+       for (ASTNodeToVecMap::iterator iset = _arrayname_readindices.begin(), iset_end = _arrayname_readindices.end(); iset != iset_end; iset++)
+       {
+               iset->second.clear();
+       }
+
+       _arrayname_readindices.clear();
+       _interior_unique_table.clear();
+       _symbol_unique_table.clear();
+       _bvconst_unique_table.clear();
+}
+
+void BeevMgr::ClearAllCaches(void)
+{
+       //clear all tables before calling toplevelsat
+       _ASTNode_to_SATVar.clear();
+       _SATVar_to_AST.clear();
+
+       for (ASTtoBitvectorMap::iterator it = _ASTNode_to_Bitvector.begin(), itend = _ASTNode_to_Bitvector.end(); it != itend; it++)
+       {
+               (it->second)->clear();
+               delete (it->second);
+       }
+       _ASTNode_to_Bitvector.clear();
+
+       /*OLD destructor
+        * for(ASTNodeToVecMap::iterator ivec = BBTermMemo.begin(),
+        ivec_end=BBTermMemo.end();ivec!=ivec_end;ivec++) {
+        ivec->second.clear();
+        }*/
+
+       /*What should I do here?
+        *for(ASTNodeMap::iterator ivec = BBTermMemo.begin(),
+        ivec_end=BBTermMemo.end();ivec!=ivec_end;ivec++) {
+        ivec->second.clear();
+        }*/
+       BBTermMemo.clear();
+       BBFormMemo.clear();
+       NodeLetVarMap.clear();
+       NodeLetVarMap1.clear();
+       PLPrintNodeSet.clear();
+       AlreadyPrintedSet.clear();
+       SimplifyMap->clear();
+       SimplifyNegMap->clear();
+       SolverMap.clear();
+       AlwaysTrueFormMap.clear();
+       _arrayread_ite.clear();
+       _arrayread_symbol.clear();
+       _introduced_symbols.clear();
+       TransformMap.clear();
+       _letid_expr_map->clear();
+       CounterExampleMap.clear();
+       ComputeFormulaMap.clear();
+       StatInfoSet.clear();
+
+       for (ASTNodeToVecMap::iterator iset = _arrayname_readindices.begin(), iset_end = _arrayname_readindices.end(); iset != iset_end; iset++)
+       {
+               iset->second.clear();
+       }
+
+       _arrayname_readindices.clear();
+       //_interior_unique_table.clear();
+       //_symbol_unique_table.clear();
+       //_bvconst_unique_table.clear();
+}
+
+void BeevMgr::CopySolverMap_To_CounterExample(void)
+{
+       if (!SolverMap.empty())
+       {
+               CounterExampleMap.insert(SolverMap.begin(), SolverMap.end());
        }
-       break;      
-      case WRITE:
-       if(n[0].GetIndexWidth() != n[1].GetValueWidth())
-         FatalError("BVTypeCheck: length of indexwidth of array != length of actual index in the term t = \n",n);
-       if(n[0].GetValueWidth() != n[2].GetValueWidth())
-         FatalError("BVTypeCheck: valuewidth of array != length of actual value in the term t = \n",n);
-       break;      
-      case BVOR:
-      case BVAND:
-      case BVXOR:
-      case BVNOR:
-      case BVNAND:
-      case BVXNOR: 
-      case BVPLUS: 
-      case BVMULT:
-      case BVDIV:
-      case BVMOD:
-      case BVSUB: {
-       if(!(v.size() >= 2))
-         FatalError("BVTypeCheck:bitwise Booleans and BV arith operators must have atleast two arguments\n",n);
-       unsigned int width = n.GetValueWidth();
-       for(ASTVec::const_iterator it=v.begin(),itend=v.end();it!=itend;it++){
-         if(width != it->GetValueWidth()) {
-           cerr << "BVTypeCheck:Operands of bitwise-Booleans and BV arith operators must be of equal length\n";
-           cerr << n << endl;
-           cerr << "width of term:" << width << endl;
-           cerr << "width of offending operand:" << it->GetValueWidth() << endl;
-           FatalError("BVTypeCheck:Offending operand:\n",*it);
-         }
-         if(BITVECTOR_TYPE != it->GetType())
-           FatalError("BVTypeCheck: ChildNodes of bitvector-terms must be bitvectors\n",n);
+}
+
+void FatalError(const char * str, const ASTNode& a, int w)
+{
+       if (a.GetKind() != UNDEFINED)
+       {
+               cerr << "Fatal Error: " << str << endl << a << endl;
+               cerr << w << endl;
        }
-       break;
-      }
-      case BVSX:
-       //in BVSX(n[0],len), the length of the BVSX term must be
-       //greater than the length of n[0]
-       if(n[0].GetValueWidth() > n.GetValueWidth()) {
-         FatalError("BVTypeCheck: BVSX(t,bvsx_len) : length of 't' must be <= bvsx_len\n",n);
-       } 
-       break;
-
-      case BVZX:
-       //in BVZX(n[0],len), the length of the BVZX term must be
-       //greater than the length of n[0]
-       if(n[0].GetValueWidth() > n.GetValueWidth()) {
-         FatalError("BVTypeCheck: BVZX(t,bvzx_len) : length of 't' must be <= bvzx_len\n",n);
+       else
+       {
+               cerr << "Fatal Error: " << str << endl;
+               cerr << w << endl;
        }
-       break;
-
-      default:
-       for(ASTVec::const_iterator it=v.begin(),itend=v.end();it!=itend;it++)
-         if(BITVECTOR_TYPE != it->GetType()) {
-           cerr << "The type is: " << it->GetType() << endl;
-           FatalError("BVTypeCheck:ChildNodes of bitvector-terms must be bitvectors\n",n);
-         }
-       break;
-      }
-      
-      switch(k) {
-      case BVCONCAT:
-       if(n.Degree() != 2)
-         FatalError("BVTypeCheck: should have exactly 2 args\n",n);
-       if(n.GetValueWidth() != n[0].GetValueWidth() + n[1].GetValueWidth())
-         FatalError("BVTypeCheck:BVCONCAT: lengths do not add up\n",n);        
-       break;
-      case BVUMINUS:
-      case BVNEG:
-       if(n.Degree() != 1)
-         FatalError("BVTypeCheck: should have exactly 1 args\n",n);
-       break;
-      case BVEXTRACT:
-       if(n.Degree() != 3)
-         FatalError("BVTypeCheck: should have exactly 3 args\n",n);
-       if(!(BVCONST == n[1].GetKind() && BVCONST == n[2].GetKind()))
-         FatalError("BVTypeCheck: indices should be BVCONST\n",n);
-       if(n.GetValueWidth() != GetUnsignedConst(n[1])- GetUnsignedConst(n[2])+1)
-         FatalError("BVTypeCheck: length mismatch\n",n);
-       break;
-      case BVLEFTSHIFT:
-      case BVRIGHTSHIFT:
-       if(n.Degree() != 2)
-         FatalError("BVTypeCheck: should have exactly 2 args\n",n);
-       break;
-       //case BVVARSHIFT:
-       //case BVSRSHIFT:
-       break;
-      default:
-       break;
-      }
-    }
-    else {
-      if(!(is_Form_kind(k) && BOOLEAN_TYPE == n.GetType()))
-       FatalError("BVTypeCheck: not a formula:",n);
-      switch(k){
-      case TRUE:
-      case FALSE:
-      case SYMBOL:
-       return;
-      case EQ:
-      case NEQ:         
-       if(!(n[0].GetValueWidth() == n[1].GetValueWidth() &&
-            n[0].GetIndexWidth() == n[1].GetIndexWidth())) {
-         cerr << "valuewidth of lhs of EQ: " << n[0].GetValueWidth() << endl;
-         cerr << "valuewidth of rhs of EQ: " << n[1].GetValueWidth() << endl;
-         cerr << "indexwidth of lhs of EQ: " << n[0].GetIndexWidth() << endl;
-         cerr << "indexwidth of rhs of EQ: " << n[1].GetIndexWidth() << endl;
-         FatalError("BVTypeCheck: terms in atomic formulas must be of equal length",n);
+       if (vc_error_hdlr)
+               vc_error_hdlr(str);
+       exit(-1);
+       //assert(0);
+}
+
+void FatalError(const char * str)
+{
+       cerr << "Fatal Error: " << str << endl;
+       if (vc_error_hdlr)
+               vc_error_hdlr(str);
+       exit(-1);
+       //assert(0);
+}
+
+//Variable Order Printer: A global function which converts a MINISAT
+//var into a ASTNODE var. It then prints this var along with
+//variable order dcisions taken by MINISAT.
+void Convert_MINISATVar_To_ASTNode_Print(int minisat_var, int decision_level, int polarity)
+{
+       BEEV::ASTNode vv = globalBeevMgr_for_parser->_SATVar_to_AST[minisat_var];
+       cout << spaces(decision_level);
+       if (polarity)
+       {
+               cout << "!";
        }
-       break;
-      case BVLT:
-      case BVLE:
-      case BVGT:
-      case BVGE:
-      case BVSLT:
-      case BVSLE:
-      case BVSGT:
-      case BVSGE:      
-       if(BITVECTOR_TYPE != n[0].GetType() && BITVECTOR_TYPE != n[1].GetType())
-         FatalError("BVTypeCheck: terms in atomic formulas must be bitvectors",n);
-       if(n[0].GetValueWidth() != n[1].GetValueWidth())
-         FatalError("BVTypeCheck: terms in atomic formulas must be of equal length",n);
-       if(n[0].GetIndexWidth() != n[1].GetIndexWidth())
-         FatalError("BVTypeCheck: terms in atomic formulas must be of equal length",n);
-       break;
-      case NOT:
-       if(1 != n.Degree())
-         FatalError("BVTypeCheck: NOT formula can have exactly one childNode",n);
-       break;
-      case AND:
-      case OR:
-      case XOR:
-      case NAND:
-      case NOR:
-       if(2 > n.Degree())
-         FatalError("BVTypeCheck: AND/OR/XOR/NAND/NOR: must have atleast 2 ChildNodes",n);
-       break;
-      case IFF:
-      case IMPLIES:    
-       if(2 != n.Degree())
-         FatalError("BVTypeCheck:IFF/IMPLIES must have exactly 2 ChildNodes",n);
-       break;
-      case ITE:
-       if(3 != n.Degree())
-         FatalError("BVTypeCheck:ITE must have exactly 3 ChildNodes",n);               
-       break;
-      default:
-       FatalError("BVTypeCheck: Unrecognized kind: ",ASTUndefined);
-       break;
-      }
-    }
-  } //End of TypeCheck function
-
-  //add an assertion to the current logical context
-  void BeevMgr::AddAssert(const ASTNode& assert) {
-    if(!(is_Form_kind(assert.GetKind()) && BOOLEAN_TYPE == assert.GetType())) {
-      FatalError("AddAssert:Trying to assert a non-formula:",assert);
-    }
-      
-    ASTVec * v;
-    //if the stack of ASTVec is not empty, then take the top ASTVec
-    //and add the input assert to it
-    if(!_asserts.empty()) {
-      v = _asserts.back();
-      //v->push_back(TransformFormula(assert));
-      v->push_back(assert);
-    }
-    else {
-      //else create a logical context, and add it to the top of the
-      //stack
-      v = new ASTVec();
-      //v->push_back(TransformFormula(assert));
-      v->push_back(assert);
-      _asserts.push_back(v);   
-    }
-  }
-  
-  void BeevMgr::Push(void) {
-    ASTVec * v;
-    v = new ASTVec();
-    _asserts.push_back(v);
-  }
-  
-  void BeevMgr::Pop(void) {
-    if(!_asserts.empty()) {
-       ASTVec * c = _asserts.back();
-             //by calling the clear function we ensure that the ref count is
-             //decremented for the ASTNodes stored in c
-             c->clear();
-             delete c;
-      _asserts.pop_back();
-    }
-  }
-
-  void BeevMgr::AddQuery(const ASTNode& q) {
-    //_current_query = TransformFormula(q);
-    //cerr << "\nThe current query is: " << q << endl;
-    _current_query = q;
-  }
-    
-  const ASTNode BeevMgr::PopQuery() {
-    ASTNode q = _current_query;
-    _current_query = ASTTrue;
-    return q;
-  }
-   
-  const ASTNode BeevMgr::GetQuery() {
-    return _current_query;
-  }
-  
-  const ASTVec BeevMgr::GetAsserts(void) {
-    vector<ASTVec *>::iterator it = _asserts.begin();
-    vector<ASTVec *>::iterator itend = _asserts.end();
-    
-    ASTVec v;
-    for(;it!=itend;it++) {
-      if(!(*it)->empty())
-         v.insert(v.end(),(*it)->begin(),(*it)->end());
-    }
-    return v;
-  }
-
-  //Create a new variable of ValueWidth 'n'
-  ASTNode BeevMgr::NewArrayVar(unsigned int index, unsigned int value) {
-    std:: string c("v");
-    char d[32];
-    sprintf(d,"%d",_symbol_count++);
-    std::string ccc(d);
-    c += "_writearray_" + ccc;
-    
-    ASTNode CurrentSymbol = CreateSymbol(c.c_str());
-    CurrentSymbol.SetValueWidth(value);
-    CurrentSymbol.SetIndexWidth(index);
-    return CurrentSymbol;
-  } //end of NewArrayVar()
-
-
-  //Create a new variable of ValueWidth 'n'
-  ASTNode BeevMgr::NewVar(unsigned int value) {
-    std:: string c("v");
-    char d[32];
-    sprintf(d,"%d",_symbol_count++);
-    std::string ccc(d);
-    c += "_new_stp_var_" + ccc;
-    
-    ASTNode CurrentSymbol = CreateSymbol(c.c_str());
-    CurrentSymbol.SetValueWidth(value);
-    CurrentSymbol.SetIndexWidth(0);
-    _introduced_symbols.insert(CurrentSymbol);
-    return CurrentSymbol;
-  } //end of NewVar()
-
-  //prints statistics for the ASTNode
-  void BeevMgr::ASTNodeStats(const char * c, const ASTNode& a){
-    if(!stats)
-      return;
-
-    StatInfoSet.clear();
-    //print node size:
-    cout << endl << "Printing: " << c;
-    if(print_nodes) {
-      //a.PL_Print(cout,0);
-      //cout << endl;
-      cout << a << endl;
-    }
-    cout << "Node size is: ";
-    cout << NodeSize(a) << endl << endl;    
-  }
-
-  unsigned int BeevMgr::NodeSize(const ASTNode& a, bool clearStatInfo) {    
-    if(clearStatInfo)
-      StatInfoSet.clear();
-
-    ASTNodeSet::iterator it;
-    if((it = StatInfoSet.find(a)) != StatInfoSet.end())
-      //has already been counted
-      return 0;
-
-    //record that you have seen this node already
-    StatInfoSet.insert(a);
-    
-    //leaf node has a size of 1
-    if(a.Degree() == 0)
-      return 1;
-
-    unsigned newn = 1;
-    ASTVec c = a.GetChildren();
-    for(ASTVec::iterator it=c.begin(),itend=c.end();it!=itend;it++)
-      newn += NodeSize(*it);
-    return newn;
-  }
-
-  void BeevMgr::ClearAllTables(void) {
-    //clear all tables before calling toplevelsat
-    _ASTNode_to_SATVar.clear();
-    _SATVar_to_AST.clear();
-
-    for(ASTtoBitvectorMap::iterator it=_ASTNode_to_Bitvector.begin(),
-         itend=_ASTNode_to_Bitvector.end();it!=itend;it++) {
-      (it->second)->clear();
-      delete (it->second);
-    }
-    _ASTNode_to_Bitvector.clear();
-    
-    /* OLD Destructor
-     * for(ASTNodeToVecMap::iterator ivec = BBTermMemo.begin(),
-         ivec_end=BBTermMemo.end();ivec!=ivec_end;ivec++) {
-      ivec->second.clear();
-    }*/
-
-    /*What should I do here? For ASTNodes?
-     * for(ASTNodeMap::iterator ivec = BBTermMemo.begin(),
-         ivec_end=BBTermMemo.end();ivec!=ivec_end;ivec++) {
-      ivec->second.clear();
-    }*/
-    BBTermMemo.clear();
-    BBFormMemo.clear();
-    NodeLetVarMap.clear();
-    NodeLetVarMap1.clear();
-    PLPrintNodeSet.clear();
-    AlreadyPrintedSet.clear();
-    SimplifyMap->clear();
-    SimplifyNegMap->clear();
-    SolverMap.clear();
-    AlwaysTrueFormMap.clear();
-    _arrayread_ite.clear();
-    _arrayread_symbol.clear();
-    _introduced_symbols.clear();
-    TransformMap.clear();
-    _letid_expr_map->clear();
-    CounterExampleMap.clear();
-    ComputeFormulaMap.clear();
-    StatInfoSet.clear();
-
-    // for(std::vector<ASTVec *>::iterator it=_asserts.begin(),
-    //           itend=_asserts.end();it!=itend;it++) {
-    //       (*it)->clear();
-    //     }
-    _asserts.clear();
-    for(ASTNodeToVecMap::iterator iset = _arrayname_readindices.begin(), 
-         iset_end = _arrayname_readindices.end();
-       iset!=iset_end;iset++) {
-      iset->second.clear();
-    }
-
-    _arrayname_readindices.clear();
-    _interior_unique_table.clear();
-    _symbol_unique_table.clear();
-    _bvconst_unique_table.clear();
-  }
-
-  void BeevMgr::ClearAllCaches(void) {
-    //clear all tables before calling toplevelsat
-    _ASTNode_to_SATVar.clear();
-    _SATVar_to_AST.clear();
-
-
-    for(ASTtoBitvectorMap::iterator it=_ASTNode_to_Bitvector.begin(),
-         itend=_ASTNode_to_Bitvector.end();it!=itend;it++) {
-      (it->second)->clear();
-      delete (it->second);
-    }
-    _ASTNode_to_Bitvector.clear();
-    
-    /*OLD destructor
-     * for(ASTNodeToVecMap::iterator ivec = BBTermMemo.begin(),
-         ivec_end=BBTermMemo.end();ivec!=ivec_end;ivec++) {
-      ivec->second.clear();
-    }*/
-
-    /*What should I do here?
-     *for(ASTNodeMap::iterator ivec = BBTermMemo.begin(),
-         ivec_end=BBTermMemo.end();ivec!=ivec_end;ivec++) {
-      ivec->second.clear();
-    }*/
-    BBTermMemo.clear();
-    BBFormMemo.clear();
-    NodeLetVarMap.clear();
-    NodeLetVarMap1.clear();
-    PLPrintNodeSet.clear();
-    AlreadyPrintedSet.clear();
-    SimplifyMap->clear();
-    SimplifyNegMap->clear();
-    SolverMap.clear();
-    AlwaysTrueFormMap.clear();
-    _arrayread_ite.clear();
-    _arrayread_symbol.clear();
-    _introduced_symbols.clear();
-    TransformMap.clear();
-    _letid_expr_map->clear();
-    CounterExampleMap.clear();
-    ComputeFormulaMap.clear();
-    StatInfoSet.clear();
-
-    for(ASTNodeToVecMap::iterator iset = _arrayname_readindices.begin(), 
-         iset_end = _arrayname_readindices.end();
-       iset!=iset_end;iset++) {
-      iset->second.clear();
-    }
-
-    _arrayname_readindices.clear();
-    //_interior_unique_table.clear();
-    //_symbol_unique_table.clear();
-    //_bvconst_unique_table.clear();
-  }
-
-  void BeevMgr::CopySolverMap_To_CounterExample(void) {
-    if(!SolverMap.empty()) {
-      CounterExampleMap.insert(SolverMap.begin(),SolverMap.end());
-    }
-  }
-
-  void FatalError(const char * str, const ASTNode& a, int w) {
-    if(a.GetKind() != UNDEFINED) {
-      cerr << "Fatal Error: " << str << endl << a << endl;
-      cerr << w << endl;
-    }
-    else {
-      cerr << "Fatal Error: " << str << endl;
-      cerr << w << endl;
-    }
-    if (vc_error_hdlr)
-      vc_error_hdlr(str);
-    exit(-1);
-    //assert(0);
-  }
-
-  void FatalError(const char * str) {
-    cerr << "Fatal Error: " << str << endl;
-    if (vc_error_hdlr)
-      vc_error_hdlr(str);
-    exit(-1);
-    //assert(0);
-  }
-
-  //Variable Order Printer: A global function which converts a MINISAT
-  //var into a ASTNODE var. It then prints this var along with
-  //variable order dcisions taken by MINISAT.
-  void Convert_MINISATVar_To_ASTNode_Print(int minisat_var, 
-                                          int decision_level, int polarity) {
-    BEEV::ASTNode vv = globalBeevMgr_for_parser->_SATVar_to_AST[minisat_var];
-    cout << spaces(decision_level);
-    if(polarity) {
-      cout << "!";
-    }
-    vv.PL_Print(cout,0);
-    cout << endl;
-  }
-
-  void SortByExprNum(ASTVec& v) {
-    sort(v.begin(), v.end(), exprless);    
-  }
-
-  void SortByArith(ASTVec& v) {
-    sort(v.begin(), v.end(), arithless);
-  }
-
-  bool isAtomic(Kind kind) {
-    if(TRUE == kind ||
-       FALSE == kind ||
-       EQ == kind ||
-       NEQ == kind ||
-       BVLT == kind ||
-       BVLE == kind ||
-       BVGT == kind ||
-       BVGE == kind ||
-       BVSLT == kind ||
-       BVSLE == kind ||
-       BVSGT == kind ||
-       BVSGE == kind ||
-       SYMBOL == kind ||
-       BVGETBIT == kind)
-      return true;
-    return false;
-  }
-
-  BeevMgr::~BeevMgr() {
-    ClearAllTables();
-    
-       delete SimplifyMap;
+       vv.PL_Print(cout, 0);
+       cout << endl;
+}
+
+void SortByExprNum(ASTVec& v)
+{
+       sort(v.begin(), v.end(), exprless);
+}
+
+void SortByArith(ASTVec& v)
+{
+       sort(v.begin(), v.end(), arithless);
+}
+
+bool isAtomic(Kind kind)
+{
+       if (TRUE == kind || FALSE == kind || EQ == kind || NEQ == kind || BVLT == kind || BVLE == kind || BVGT == kind || BVGE == kind || BVSLT == kind
+                       || BVSLE == kind || BVSGT == kind || BVSGE == kind || SYMBOL == kind || BVGETBIT == kind)
+               return true;
+       return false;
+}
+
+BeevMgr::~BeevMgr()
+{
+       ClearAllTables();
+
+       delete SimplifyMap;
        delete SimplifyNegMap;
-    delete _letid_expr_map;
-  }
+       delete _letid_expr_map;
+}
 
-}; // end namespace
+}
+; // end namespace
 
index a368d4e58ec4c990d1118b8e807ce8e8501a1512..3c487b255fc47b93eea4dd71c0edb2d4aa73b189 100644 (file)
--- a/AST/AST.h
+++ b/AST/AST.h
@@ -10,7 +10,6 @@
 #ifndef AST_H
 #define AST_H
 
-
 #include <vector>
 #ifdef EXT_HASH_MAP
 #include <ext/hash_set>
 #include "../constantbv/constantbv.h"
 #endif
 
-
-
 /*****************************************************************************
  * LIST OF CLASSES DECLARED IN THIS FILE:
  *
- * class BeevMgr;  
- * class ASTNode; 
- * class ASTInternal;  
- * class ASTInterior;  
+ * class BeevMgr;
+ * class ASTNode;
+ * class ASTInternal;
+ * class ASTInterior;
  * class ASTSymbol;
  * class ASTBVConst;
  *****************************************************************************/
-namespace BEEV {
-  using namespace std; 
-  using namespace MINISAT;
+namespace BEEV
+{
+using namespace std;
+using namespace MINISAT;
 #ifdef EXT_HASH_MAP
-  using namespace __gnu_cxx;
+using namespace __gnu_cxx;
 #endif
 
-  //return types for the GetType() function in ASTNode class
-  enum types {
-    BOOLEAN_TYPE = 0,
-    BITVECTOR_TYPE,
-    ARRAY_TYPE,
-    UNKNOWN_TYPE
-  };
-  
-  class BeevMgr;
-  class ASTNode; 
-  class ASTInternal;  
-  class ASTInterior;  
-  class ASTSymbol;
-  class ASTBVConst;
-  class BVSolver;
-
-  //Vector of ASTNodes, used for child nodes among other things.  
-  typedef vector<ASTNode> ASTVec;
-  extern ASTVec _empty_ASTVec;
-  extern BeevMgr * globalBeevMgr_for_parser;
-
-  typedef unsigned int * CBV;
-
-  /***************************************************************************/
-  /*  Class ASTNode: Smart pointer to actual ASTNode internal datastructure. */
-  /***************************************************************************/
-  class ASTNode {
-    friend class BeevMgr;
-    friend class CNFMgr;
-    friend class ASTInterior;
-    friend class vector<ASTNode>;
-    //Print the arguments in lisp format.
-    friend ostream &LispPrintVec(ostream &os, 
-                                const ASTVec &v, int indentation = 0); 
-    friend ostream &LispPrintVecSpecial(ostream &os, 
-                                const vector<const ASTNode*> &v, int indentation = 0); 
-
-  private:
-    // FIXME: make this into a reference?
-    ASTInternal * _int_node_ptr;       // The real data.
-
-    // Usual constructor.  
-    ASTNode(ASTInternal *in);
-
-    //Equal iff ASTIntNode pointers are the same.
-    friend bool operator==(const ASTNode node1, const ASTNode node2){
-      return ((size_t) node1._int_node_ptr) == ((size_t) node2._int_node_ptr);
-    }
-
-    //MKK: This shouldn't be necessary, but for some inexplicable reason I
-    //cannot get ToSAT.cpp to compile. The differences between the old files
-    //(AST.h, ToSAT.cpp) and the new files are very minor, mostly Solver ->
-    //Solver, and so the compiler errors are difficult to understand.
-    friend bool operator!=(const ASTNode node1, const ASTNode node2){
-       return ! (node1 == node2);
-      //return ((size_t) node1._int_node_ptr) == ((size_t) node2._int_node_ptr);
-    }
-    
-    /* FIXME:  Nondeterministic code *** */
-    /** questionable pointer comparison function */
-    friend bool operator<(const ASTNode node1, const ASTNode node2){
-      return ((size_t) node1._int_node_ptr) < ((size_t) node2._int_node_ptr);
-    }
-
-  public:
-    //Check if it points to a null node
-    bool IsNull () const { return _int_node_ptr == NULL; }
-
-    // This is for sorting by expression number (used in Boolean
-    //optimization).
-    // With any ordering operation, the properties of the order
-    // need to be carefully specified.  In this case, we just
-    // need identical exprs to be consecutive, and (NOT x) to
-    // follow "x" immediately.  For some time, this function was
-    // "arithless" (below), which separates x and (NOT x) in some
-    // cases.
-    // DO NOT MODIFY WITHOUT CHECKING WITH DAVID DILL FIRST!
-    friend bool exprless(const ASTNode n1, const ASTNode n2) {
-      return (n1.GetNodeNum() < n2.GetNodeNum());
-    } // end of exprless
-
-    // This is for sorting by arithmetic expressions (for 
-    // combining like terms, etc.)
-    friend bool arithless(const ASTNode n1, const ASTNode n2) {
-      Kind k1 = n1.GetKind();
-      Kind k2 = n2.GetKind();
-      
-      if (n1 == n2) {
-       // necessary for "strict weak ordering"
-       return false;
-      }
-      else if (BVCONST == k1 && BVCONST != k2) {
-       // put consts first
-       return true;
-      }
-      else if (BVCONST != k1 && BVCONST == k2) {
-       // put consts first
-       return false;
-      }
-      else if (SYMBOL == k1 && SYMBOL != k2) {
-       // put symbols next
-       return true;
-      }
-      else if (SYMBOL != k1 && SYMBOL == k2) {
-       // put symbols next
-       return false;
-      }
-      else {
-       // otherwise, sort by exprnum (descendents will appear
-       // before ancestors).
-       return (n1.GetNodeNum() < n2.GetNodeNum());
-      }
-    } //end of arithless
-    
-    // Internal lisp-form printer that does not clear _node_print_table
-    ostream &LispPrint1(ostream &os, int indentation) const;
-
-    ostream &LispPrint_indent(ostream &os, int indentation) const;
-
-    // For lisp DAG printing.  Has it been printed already, so we can
-    // just print the node number?
-    bool IsAlreadyPrinted() const;
-    void MarkAlreadyPrinted() const;
-
-    // delegates to the ASTInternal node.
-    void nodeprint(ostream& os, bool c_friendly = false) const;
-
-
-  public:
-    // Default constructor.  This gets used when declaring an ASTVec
-    // of a given size, in the hash table, etc.  For faster
-    // refcounting, create a symbol node for NULL.  Give it a big
-    // initial refcount.  Never free it.  also check, for ref-count
-    // overflow?
-    ASTNode() : _int_node_ptr(NULL) { };
-
-    // Copy constructor
-    ASTNode(const ASTNode &n);
-
-    // Destructor
-    ~ASTNode();
-
-    // Assignment (for ref counting)
-    ASTNode& operator=(const ASTNode& n);
-
-    BeevMgr &GetBeevMgr() const;
-
-    // Access node number
-    int GetNodeNum() const;
-
-    // Access kind.  Inlined later because of declaration ordering problems.
-    Kind GetKind() const;
-
-    // access Children
-    const ASTVec &GetChildren() const;
-    
-    // Return the number of child nodes
-    size_t Degree() const{ 
-      return GetChildren().size(); 
-    };    
-
-    // Get indexth childNode.
-    const ASTNode operator[](size_t index) const { 
-      return GetChildren()[index]; 
-    };    
-
-    // Get begin() iterator for child nodes
-    ASTVec::const_iterator begin() const{ 
-      return GetChildren().begin(); 
-    };  
-
-    // Get end() iterator for child nodes
-    ASTVec::const_iterator end() const{ 
-      return GetChildren().end(); 
-    };
-
-    //Get back() element for child nodes
-    const ASTNode back() const{
-      return GetChildren().back();
-    };  
-
-    // Get the name from a symbol (char *).  It's an error if kind != SYMBOL
-    const char * const GetName() const;
-
-    //Get the BVCONST value
+//return types for the GetType() function in ASTNode class
+enum types
+{
+       BOOLEAN_TYPE = 0, BITVECTOR_TYPE, ARRAY_TYPE, UNKNOWN_TYPE
+};
+
+class BeevMgr;
+class ASTNode;
+class ASTInternal;
+class ASTInterior;
+class ASTSymbol;
+class ASTBVConst;
+class BVSolver;
+
+//Vector of ASTNodes, used for child nodes among other things.
+typedef vector<ASTNode> ASTVec;
+extern ASTVec _empty_ASTVec;
+extern BeevMgr * globalBeevMgr_for_parser;
+
+typedef unsigned int * CBV;
+
+/***************************************************************************/
+/*  Class ASTNode: Smart pointer to actual ASTNode internal datastructure. */
+/***************************************************************************/
+class ASTNode
+{
+       friend class BeevMgr;
+       friend class CNFMgr;
+       friend class ASTInterior;
+       friend class vector<ASTNode> ;
+       //Print the arguments in lisp format.
+       friend ostream &LispPrintVec(ostream &os, const ASTVec &v, int indentation = 0);
+       friend ostream &LispPrintVecSpecial(ostream &os, const vector<const ASTNode*> &v, int indentation = 0);
+
+private:
+       // FIXME: make this into a reference?
+       ASTInternal * _int_node_ptr; // The real data.
+
+       // Usual constructor.
+       ASTNode(ASTInternal *in);
+
+       //Equal iff ASTIntNode pointers are the same.
+       friend bool operator==(const ASTNode node1, const ASTNode node2)
+       {
+               return ((size_t) node1._int_node_ptr) == ((size_t) node2._int_node_ptr);
+       }
+
+       //MKK: This shouldn't be necessary, but for some inexplicable reason I
+       //cannot get ToSAT.cpp to compile. The differences between the old files
+       //(AST.h, ToSAT.cpp) and the new files are very minor, mostly Solver ->
+       //Solver, and so the compiler errors are difficult to understand.
+       friend bool operator!=(const ASTNode node1, const ASTNode node2)
+       {
+               return !(node1 == node2);
+               //return ((size_t) node1._int_node_ptr) == ((size_t) node2._int_node_ptr);
+       }
+
+       /* FIXME:  Nondeterministic code *** */
+       /** questionable pointer comparison function */
+       friend bool operator<(const ASTNode node1, const ASTNode node2)
+       {
+               return ((size_t) node1._int_node_ptr) < ((size_t) node2._int_node_ptr);
+       }
+
+public:
+       //Check if it points to a null node
+       bool IsNull() const
+       {
+               return _int_node_ptr == NULL;
+       }
+
+       // This is for sorting by expression number (used in Boolean
+       //optimization).
+       // With any ordering operation, the properties of the order
+       // need to be carefully specified.  In this case, we just
+       // need identical exprs to be consecutive, and (NOT x) to
+       // follow "x" immediately.  For some time, this function was
+       // "arithless" (below), which separates x and (NOT x) in some
+       // cases.
+       // DO NOT MODIFY WITHOUT CHECKING WITH DAVID DILL FIRST!
+       friend bool exprless(const ASTNode n1, const ASTNode n2)
+       {
+               return (n1.GetNodeNum() < n2.GetNodeNum());
+       } // end of exprless
+
+       // This is for sorting by arithmetic expressions (for
+       // combining like terms, etc.)
+       friend bool arithless(const ASTNode n1, const ASTNode n2)
+       {
+               Kind k1 = n1.GetKind();
+               Kind k2 = n2.GetKind();
+
+               if (n1 == n2)
+               {
+                       // necessary for "strict weak ordering"
+                       return false;
+               }
+               else if (BVCONST == k1 && BVCONST != k2)
+               {
+                       // put consts first
+                       return true;
+               }
+               else if (BVCONST != k1 && BVCONST == k2)
+               {
+                       // put consts first
+                       return false;
+               }
+               else if (SYMBOL == k1 && SYMBOL != k2)
+               {
+                       // put symbols next
+                       return true;
+               }
+               else if (SYMBOL != k1 && SYMBOL == k2)
+               {
+                       // put symbols next
+                       return false;
+               }
+               else
+               {
+                       // otherwise, sort by exprnum (descendents will appear
+                       // before ancestors).
+                       return (n1.GetNodeNum() < n2.GetNodeNum());
+               }
+       } //end of arithless
+
+       // Internal lisp-form printer that does not clear _node_print_table
+       ostream &LispPrint1(ostream &os, int indentation) const;
+
+       ostream &LispPrint_indent(ostream &os, int indentation) const;
+
+       // For lisp DAG printing.  Has it been printed already, so we can
+       // just print the node number?
+       bool IsAlreadyPrinted() const;
+       void MarkAlreadyPrinted() const;
+
+       // delegates to the ASTInternal node.
+       void nodeprint(ostream& os, bool c_friendly = false) const;
+
+public:
+       // Default constructor.  This gets used when declaring an ASTVec
+       // of a given size, in the hash table, etc.  For faster
+       // refcounting, create a symbol node for NULL.  Give it a big
+       // initial refcount.  Never free it.  also check, for ref-count
+       // overflow?
+       ASTNode() :
+               _int_node_ptr(NULL)
+       {
+       }
+       ;
+
+       // Copy constructor
+       ASTNode(const ASTNode &n);
+
+       // Destructor
+       ~ASTNode();
+
+       // Assignment (for ref counting)
+       ASTNode& operator=(const ASTNode& n);
+
+       BeevMgr &GetBeevMgr() const;
+
+       // Access node number
+       int GetNodeNum() const;
+
+       // Access kind.  Inlined later because of declaration ordering problems.
+       Kind GetKind() const;
+
+       // access Children
+       const ASTVec &GetChildren() const;
+
+       // Return the number of child nodes
+       size_t Degree() const
+       {
+               return GetChildren().size();
+       }
+       ;
+
+       // Get indexth childNode.
+       const ASTNode operator[](size_t index) const
+       {
+               return GetChildren()[index];
+       }
+       ;
+
+       // Get begin() iterator for child nodes
+       ASTVec::const_iterator begin() const
+       {
+               return GetChildren().begin();
+       }
+       ;
+
+       // Get end() iterator for child nodes
+       ASTVec::const_iterator end() const
+       {
+               return GetChildren().end();
+       }
+       ;
+
+       //Get back() element for child nodes
+       const ASTNode back() const
+       {
+               return GetChildren().back();
+       }
+       ;
+
+       // Get the name from a symbol (char *).  It's an error if kind != SYMBOL
+       const char * const GetName() const;
+
+       //Get the BVCONST value
 #ifndef NATIVE_C_ARITH
-    const CBV GetBVConst() const;
+       const CBV GetBVConst() const;
 #else
-    unsigned long long int GetBVConst() const;
+       unsigned long long int GetBVConst() const;
 #endif
 
-    /*ASTNode is of type BV <==> ((indexwidth=0)&&(valuewidth>0))
-     *
-     *ASTNode is of type ARRAY <==> ((indexwidth>0)&&(valuewidth>0))
-     *
-     *ASTNode is of type BOOLEAN <==> ((indexwidth=0)&&(valuewidth=0))
-     *
-     *both indexwidth and valuewidth should never be less than 0
-     */
-    unsigned int GetIndexWidth () const;
-
-    // FIXME: This function is dangerous.  Try to eliminate it's use.
-    void SetIndexWidth (unsigned int iw) const;
-
-    unsigned int GetValueWidth () const;
-
-    // FIXME: This function is dangerous.  Try to eliminate it's use.
-    void SetValueWidth (unsigned int vw) const;
-
-    //return the type of the ASTNode
-    //0 iff BOOLEAN
-    //1 iff BITVECTOR
-    //2 iff ARRAY
-
-    /*ASTNode is of type BV <==> ((indexwidth=0)&&(valuewidth>0))
-     *
-     *ASTNode is of type ARRAY <==> ((indexwidth>0)&&(valuewidth>0))
-     *
-     *ASTNode is of type BOOLEAN <==> ((indexwidth=0)&&(valuewidth=0))
-     *
-     *both indexwidth and valuewidth should never be less than 0
-     */    
-    types GetType(void) const;
-
-    // Hash is pointer value of _int_node_ptr.
-    const size_t Hash() const{ 
-      return (size_t) _int_node_ptr; 
-      //return GetNodeNum(); 
-    }
-
-    void NFASTPrint(int l, int max, int prefix) const;
-
-    // lisp-form printer 
-    ostream& LispPrint(ostream &os, int indentation = 0) const;
-
-    //Presentation Language Printer
-    ostream& PL_Print(ostream &os, int indentation = 0) const;
-
-    void PL_Print1(ostream &os, int indentation = 0, bool b = false) const;
-
-    //Construct let variables for shared subterms
-    void LetizeNode(void) const;
-
-    // Attempt to define something that will work in the gdb
-    friend void lp(ASTNode &node);
-    friend void lpvec(const ASTVec &vec);
-
-    friend ostream &operator<<(ostream &os, const ASTNode &node) { 
-      node.LispPrint(os, 0); 
-      return os; 
-    };
-    
-    // Check whether the ASTNode points to anything.  Undefined nodes
-    // are created by the default constructor.  In binding table (for
-    // lambda args, etc.), undefined nodes are used to represent
-    // deleted entries.
-    bool IsDefined() const { return _int_node_ptr != NULL; }        
-
-    /* Hasher class for STL hash_maps and hash_sets that use ASTNodes
-     * as keys.  Needs to be public so people can define hash tables
-     * (and use ASTNodeMap class)*/
-    class ASTNodeHasher {
-    public:
-      size_t operator() (const ASTNode& n) const{ 
-       return (size_t) n._int_node_ptr; 
-       //return (size_t)n.GetNodeNum();
-      };
-    }; //End of ASTNodeHasher
-  
-    /* Equality for ASTNode hash_set and hash_map. Returns true iff
-     * internal pointers are the same.  Needs to be public so people
-     * can define hash tables (and use ASTNodeSet class)*/
-    class ASTNodeEqual {
-    public:
-      bool operator()(const ASTNode& n1, const ASTNode& n2) const{ 
-       return (n1._int_node_ptr == n2._int_node_ptr); 
-      }
-    }; //End of ASTNodeEqual
-  }; //End of Class ASTNode
-
-  void FatalError(const char * str, const ASTNode& a, int w = 0);
-  void FatalError(const char * str);
-  void SortByExprNum(ASTVec& c);
-  void SortByArith(ASTVec& c);
-  bool exprless(const ASTNode n1, const ASTNode n2);
-  bool arithless(const ASTNode n1, const ASTNode n2);
-  bool isAtomic(Kind k);
-
-  /***************************************************************************/
-  /*  Class ASTInternal:Abstract base class for internal node representation.*/
-  /*                    Requires Kind and ChildNodes so same traversal works */
-  /*                    on all nodes.                                        */
-  /***************************************************************************/
-  class ASTInternal {
-
-    friend class ASTNode;
-    friend class CNFMgr;
-
-  protected:    
-
-    // reference count.
-    int _ref_count;
-
-    // Kind.  It's a type tag and the operator.
-    Kind _kind;  
-
-    // The vector of children (*** should this be in ASTInterior? ***)
-    ASTVec _children;
-
-    // Manager object.  Having this backpointer means it's easy to
-    // find the manager when we need it.
-    BeevMgr &_bm;
-
-    //Nodenum is a unique positive integer for the node.  The nodenum
-    //of a node should always be greater than its descendents (which
-    //is easily achieved by incrementing the number each time a new
-    //node is created).
-    int _node_num;
-
-    // Length of bitvector type for array index.  The term is an
-    // array iff this is positive.  Otherwise, the term is a bitvector
-    // or a bit.
-    unsigned int _index_width;
-
-    // Length of bitvector type for scalar value or array element.
-    // If this is one, the term represents a single bit (same as a bitvector
-    // of length 1).  It must be 1 or greater.
-    unsigned int _value_width;
-
-    // Increment refcount.
+       /*ASTNode is of type BV <==> ((indexwidth=0)&&(valuewidth>0))
+        *
+        *ASTNode is of type ARRAY <==> ((indexwidth>0)&&(valuewidth>0))
+        *
+        *ASTNode is of type BOOLEAN <==> ((indexwidth=0)&&(valuewidth=0))
+        *
+        *both indexwidth and valuewidth should never be less than 0
+        */
+       unsigned int GetIndexWidth() const;
+
+       // FIXME: This function is dangerous.  Try to eliminate it's use.
+       void SetIndexWidth(unsigned int iw) const;
+
+       unsigned int GetValueWidth() const;
+
+       // FIXME: This function is dangerous.  Try to eliminate it's use.
+       void SetValueWidth(unsigned int vw) const;
+
+       //return the type of the ASTNode
+       //0 iff BOOLEAN
+       //1 iff BITVECTOR
+       //2 iff ARRAY
+
+       /*ASTNode is of type BV <==> ((indexwidth=0)&&(valuewidth>0))
+        *
+        *ASTNode is of type ARRAY <==> ((indexwidth>0)&&(valuewidth>0))
+        *
+        *ASTNode is of type BOOLEAN <==> ((indexwidth=0)&&(valuewidth=0))
+        *
+        *both indexwidth and valuewidth should never be less than 0
+        */
+       types GetType(void) const;
+
+       // Hash is pointer value of _int_node_ptr.
+       const size_t Hash() const
+       {
+               return (size_t) _int_node_ptr;
+               //return GetNodeNum();
+       }
+
+       void NFASTPrint(int l, int max, int prefix) const;
+
+       // lisp-form printer
+       ostream& LispPrint(ostream &os, int indentation = 0) const;
+
+       //Presentation Language Printer
+       ostream& PL_Print(ostream &os, int indentation = 0) const;
+
+       void PL_Print1(ostream &os, int indentation = 0, bool b = false) const;
+
+       //Construct let variables for shared subterms
+       void LetizeNode(void) const;
+
+       // Attempt to define something that will work in the gdb
+       friend void lp(ASTNode &node);
+       friend void lpvec(const ASTVec &vec);
+
+       friend ostream &operator<<(ostream &os, const ASTNode &node)
+       {
+               node.LispPrint(os, 0);
+               return os;
+       }
+       ;
+
+       // Check whether the ASTNode points to anything.  Undefined nodes
+       // are created by the default constructor.  In binding table (for
+       // lambda args, etc.), undefined nodes are used to represent
+       // deleted entries.
+       bool IsDefined() const
+       {
+               return _int_node_ptr != NULL;
+       }
+
+       /* Hasher class for STL hash_maps and hash_sets that use ASTNodes
+        * as keys.  Needs to be public so people can define hash tables
+        * (and use ASTNodeMap class)*/
+       class ASTNodeHasher
+       {
+       public:
+               size_t operator()(const ASTNode& n) const
+               {
+                       return (size_t) n._int_node_ptr;
+                       //return (size_t)n.GetNodeNum();
+               }
+               ;
+       }; //End of ASTNodeHasher
+
+       /* Equality for ASTNode hash_set and hash_map. Returns true iff
+        * internal pointers are the same.  Needs to be public so people
+        * can define hash tables (and use ASTNodeSet class)*/
+       class ASTNodeEqual
+       {
+       public:
+               bool operator()(const ASTNode& n1, const ASTNode& n2) const
+               {
+                       return (n1._int_node_ptr == n2._int_node_ptr);
+               }
+       }; //End of ASTNodeEqual
+}; //End of Class ASTNode
+
+void FatalError(const char * str, const ASTNode& a, int w = 0);
+void FatalError(const char * str);
+void SortByExprNum(ASTVec& c);
+void SortByArith(ASTVec& c);
+bool exprless(const ASTNode n1, const ASTNode n2);
+bool arithless(const ASTNode n1, const ASTNode n2);
+bool isAtomic(Kind k);
+
+/***************************************************************************/
+/*  Class ASTInternal:Abstract base class for internal node representation.*/
+/*                    Requires Kind and ChildNodes so same traversal works */
+/*                    on all nodes.                                        */
+/***************************************************************************/
+class ASTInternal
+{
+
+       friend class ASTNode;
+       friend class CNFMgr;
+
+protected:
+
+       // reference count.
+       int _ref_count;
+
+       // Kind.  It's a type tag and the operator.
+       Kind _kind;
+
+       // The vector of children (*** should this be in ASTInterior? ***)
+       ASTVec _children;
+
+       // Manager object.  Having this backpointer means it's easy to
+       // find the manager when we need it.
+       BeevMgr &_bm;
+
+       //Nodenum is a unique positive integer for the node.  The nodenum
+       //of a node should always be greater than its descendents (which
+       //is easily achieved by incrementing the number each time a new
+       //node is created).
+       int _node_num;
+
+       // Length of bitvector type for array index.  The term is an
+       // array iff this is positive.  Otherwise, the term is a bitvector
+       // or a bit.
+       unsigned int _index_width;
+
+       // Length of bitvector type for scalar value or array element.
+       // If this is one, the term represents a single bit (same as a bitvector
+       // of length 1).  It must be 1 or greater.
+       unsigned int _value_width;
+
+       // Increment refcount.
 #ifndef SMTLIB
-    void IncRef() { 
-      ++_ref_count; 
-    }
+       void IncRef()
+       {
+               ++_ref_count;
+       }
 #else
-    void IncRef() { }
+       void IncRef()
+       {}
 #endif
 
-    // DecRef is a potentially expensive, because it has to delete 
-    // the node from the unique table, in addition to freeing it.
-    // FIXME:  Consider putting in a backpointer (iterator) to the hash
-    // table entry so it can be deleted without looking it up again.
-    void DecRef();
-
-    virtual const Kind GetKind() const { return _kind; }
-
-    virtual ASTVec const &GetChildren() const { return _children; }
-
-    int GetNodeNum() const { return _node_num; }
-
-    void SetNodeNum(int nn) { _node_num = nn; };
-
-    // Constructor (bm only)
-    ASTInternal(BeevMgr &bm, int nodenum = 0) :
-      _ref_count(0),
-      _kind(UNDEFINED),
-      _bm(bm),
-      _node_num(nodenum),
-      _index_width(0),
-      _value_width(0) { }
-
-    // Constructor (kind only, empty children, int nodenum) 
-    ASTInternal(Kind kind, BeevMgr &bm, int nodenum = 0) : 
-      _ref_count(0),
-      _kind(kind),
-      _bm(bm),
-      _node_num(nodenum),
-      _index_width(0),
-      _value_width(0) { } 
-
-    // Constructor (kind and children).  This copies the contents of
-    // the child nodes.
-    // FIXME: is there a way to avoid repeating these?
-    ASTInternal(Kind kind, const ASTVec &children, BeevMgr &bm, int nodenum = 0) : 
-      _ref_count(0),
-      _kind(kind),
-      _children(children),
-      _bm(bm),
-      _node_num(nodenum),
-      _index_width(0),
-      _value_width(0) { } 
-
-    // Copy constructor.  This copies the contents of the child nodes
-    // array, along with everything else.  Assigning the smart pointer,
-    // ASTNode, does NOT invoke this; This should only be used for 
-    // temporary hash keys before uniquefication.
-    // FIXME:  I don't think children need to be copied.
-    ASTInternal(const ASTInternal &int_node, int nodenum = 0) :
-      _ref_count(0),
-      _kind(int_node._kind),
-      _children(int_node._children),
-      _bm(int_node._bm),
-      _node_num(int_node._node_num), 
-      _index_width(int_node._index_width),
-      _value_width(int_node._value_width) { } 
-
-    // Copying assign operator.  Also copies contents of children.
-    ASTInternal& operator=(const ASTInternal &int_node);
-
-    // Cleanup function for removing from hash table
-    virtual void CleanUp() = 0;
-
-    // Destructor (does nothing, but is declared virtual here.
-    virtual ~ASTInternal();
-
-    // Abstract virtual print function for internal node.
-    // (c_friendly is for printing hex. numbers that C compilers will accept)
-    virtual void nodeprint(ostream& os, bool c_friendly = false) { os << "*"; };
-  }; //End of Class ASTInternal
-
-  // FIXME: Should children be only in interior node type?
-  /***************************************************************************
-    Class ASTInterior: Internal representation of an interior
-       ASTNode.  Generally, these nodes should have at least one
-      child
-  ***************************************************************************/
-  class ASTInterior : public ASTInternal {    
-
-    friend class BeevMgr;
-    friend class ASTNodeHasher;
-    friend class ASTNodeEqual;   
-
-  private:
-
-    // Hasher for ASTInterior pointer nodes
-    class ASTInteriorHasher {
-    public:
-      size_t operator()(const ASTInterior *int_node_ptr) const;
-    };
-
-    // Equality for ASTInterior nodes
-    class ASTInteriorEqual {
-    public:
-      bool operator()(const ASTInterior *int_node_ptr1, 
-                     const ASTInterior *int_node_ptr2) const{
-       return (*int_node_ptr1 == *int_node_ptr2);
-      }
-    };
-
-    // Used in Equality class for hash tables
-    friend bool operator==(const ASTInterior &int_node1, 
-                          const ASTInterior &int_node2){
-      return (int_node1._kind == int_node2._kind) && 
-       (int_node1._children == int_node2._children);
-    }
-
-    // Call this when deleting a node that has been stored in the
-    // the unique table
-    virtual void CleanUp();
-
-    // Returns kinds.  "lispprinter" handles printing of parenthesis
-    // and childnodes.
-    // (c_friendly is for printing hex. numbers that C compilers will accept)
-    virtual void nodeprint(ostream& os, bool c_friendly = false) {
-      os << _kind_names[_kind];
-    }
-    public:
-
-    // FIXME: This should not be public, but has to be because the
-    // ASTInterior hash table insists on it.  I can't seem to make the
-    // private destructor visible to hash_set.  It does not even work
-    // to put "friend class hash_set<ASTInterior, ...>" in here.
-
-    // Basic constructors
-    ASTInterior(Kind kind,  BeevMgr &bm) :
-      ASTInternal(kind, bm) {  }    
-
-    ASTInterior(Kind kind, ASTVec &children, BeevMgr &bm) :
-      ASTInternal(kind, children, bm) {  }    
-
-    //Copy constructor.  This copies the contents of the child nodes
-    //array, along with everything else. Assigning the smart pointer,
-    //ASTNode, does NOT invoke this.
-    ASTInterior(const ASTInterior &int_node) : ASTInternal(int_node) { }
-
-    // Destructor (does nothing, but is declared virtual here.
-    virtual ~ASTInterior();
-
-  }; //End of ASTNodeInterior
-
-
-  /***************************************************************************/
-  /*  Class ASTSymbol:  Class to represent internals of Symbol node.         */
-  /***************************************************************************/
-  class ASTSymbol : public ASTInternal{
-    friend class BeevMgr;
-    friend class ASTNode;
-    friend class ASTNodeHasher;
-    friend class ASTNodeEqual;
-
-  private:
-    // The name of the symbol
-    const char * const _name;
-    
-    class ASTSymbolHasher{
-    public:
-      size_t operator() (const ASTSymbol *sym_ptr) const{ 
+       // DecRef is a potentially expensive, because it has to delete
+       // the node from the unique table, in addition to freeing it.
+       // FIXME:  Consider putting in a backpointer (iterator) to the hash
+       // table entry so it can be deleted without looking it up again.
+       void DecRef();
+
+       virtual const Kind GetKind() const
+       {
+               return _kind;
+       }
+
+       virtual ASTVec const &GetChildren() const
+       {
+               return _children;
+       }
+
+       int GetNodeNum() const
+       {
+               return _node_num;
+       }
+
+       void SetNodeNum(int nn)
+       {
+               _node_num = nn;
+       }
+       ;
+
+       // Constructor (bm only)
+       ASTInternal(BeevMgr &bm, int nodenum = 0) :
+               _ref_count(0), _kind(UNDEFINED), _bm(bm), _node_num(nodenum), _index_width(0), _value_width(0)
+       {
+       }
+
+       // Constructor (kind only, empty children, int nodenum)
+       ASTInternal(Kind kind, BeevMgr &bm, int nodenum = 0) :
+               _ref_count(0), _kind(kind), _bm(bm), _node_num(nodenum), _index_width(0), _value_width(0)
+       {
+       }
+
+       // Constructor (kind and children).  This copies the contents of
+       // the child nodes.
+       // FIXME: is there a way to avoid repeating these?
+       ASTInternal(Kind kind, const ASTVec &children, BeevMgr &bm, int nodenum = 0) :
+               _ref_count(0), _kind(kind), _children(children), _bm(bm), _node_num(nodenum), _index_width(0), _value_width(0)
+       {
+       }
+
+       // Copy constructor.  This copies the contents of the child nodes
+       // array, along with everything else.  Assigning the smart pointer,
+       // ASTNode, does NOT invoke this; This should only be used for
+       // temporary hash keys before uniquefication.
+       // FIXME:  I don't think children need to be copied.
+       ASTInternal(const ASTInternal &int_node, int nodenum = 0) :
+               _ref_count(0), _kind(int_node._kind), _children(int_node._children), _bm(int_node._bm), _node_num(int_node._node_num), _index_width(
+                               int_node._index_width), _value_width(int_node._value_width)
+       {
+       }
+
+       // Copying assign operator.  Also copies contents of children.
+       ASTInternal& operator=(const ASTInternal &int_node);
+
+       // Cleanup function for removing from hash table
+       virtual void CleanUp() = 0;
+
+       // Destructor (does nothing, but is declared virtual here.
+       virtual ~ASTInternal();
+
+       // Abstract virtual print function for internal node.
+       // (c_friendly is for printing hex. numbers that C compilers will accept)
+       virtual void nodeprint(ostream& os, bool c_friendly = false)
+       {
+               os << "*";
+       }
+       ;
+}; //End of Class ASTInternal
+
+// FIXME: Should children be only in interior node type?
+/***************************************************************************
+ Class ASTInterior: Internal representation of an interior
+ ASTNode.  Generally, these nodes should have at least one
+ child
+ ***************************************************************************/
+class ASTInterior: public ASTInternal
+{
+
+       friend class BeevMgr;
+       friend class ASTNodeHasher;
+       friend class ASTNodeEqual;
+
+private:
+
+       // Hasher for ASTInterior pointer nodes
+       class ASTInteriorHasher
+       {
+       public:
+               size_t operator()(const ASTInterior *int_node_ptr) const;
+       };
+
+       // Equality for ASTInterior nodes
+       class ASTInteriorEqual
+       {
+       public:
+               bool operator()(const ASTInterior *int_node_ptr1, const ASTInterior *int_node_ptr2) const
+               {
+                       return (*int_node_ptr1 == *int_node_ptr2);
+               }
+       };
+
+       // Used in Equality class for hash tables
+       friend bool operator==(const ASTInterior &int_node1, const ASTInterior &int_node2)
+       {
+               return (int_node1._kind == int_node2._kind) && (int_node1._children == int_node2._children);
+       }
+
+       // Call this when deleting a node that has been stored in the
+       // the unique table
+       virtual void CleanUp();
+
+       // Returns kinds.  "lispprinter" handles printing of parenthesis
+       // and childnodes.
+       // (c_friendly is for printing hex. numbers that C compilers will accept)
+       virtual void nodeprint(ostream& os, bool c_friendly = false)
+       {
+               os << _kind_names[_kind];
+       }
+public:
+
+       // FIXME: This should not be public, but has to be because the
+       // ASTInterior hash table insists on it.  I can't seem to make the
+       // private destructor visible to hash_set.  It does not even work
+       // to put "friend class hash_set<ASTInterior, ...>" in here.
+
+       // Basic constructors
+       ASTInterior(Kind kind, BeevMgr &bm) :
+               ASTInternal(kind, bm)
+       {
+       }
+
+       ASTInterior(Kind kind, ASTVec &children, BeevMgr &bm) :
+               ASTInternal(kind, children, bm)
+       {
+       }
+
+       //Copy constructor.  This copies the contents of the child nodes
+       //array, along with everything else. Assigning the smart pointer,
+       //ASTNode, does NOT invoke this.
+       ASTInterior(const ASTInterior &int_node) :
+               ASTInternal(int_node)
+       {
+       }
+
+       // Destructor (does nothing, but is declared virtual here.
+       virtual ~ASTInterior();
+
+}; //End of ASTNodeInterior
+
+
+/***************************************************************************/
+/*  Class ASTSymbol:  Class to represent internals of Symbol node.         */
+/***************************************************************************/
+class ASTSymbol: public ASTInternal
+{
+       friend class BeevMgr;
+       friend class ASTNode;
+       friend class ASTNodeHasher;
+       friend class ASTNodeEqual;
+
+private:
+       // The name of the symbol
+       const char * const _name;
+
+       class ASTSymbolHasher
+       {
+       public:
+               size_t operator()(const ASTSymbol *sym_ptr) const
+               {
 #ifdef TR1_UNORDERED_MAP
-       tr1::hash<string> h;
+                       tr1::hash<string> h;
 #else
-       hash<char*> h; 
+                       hash<char*> h;
 #endif
-       return h(sym_ptr->_name); 
-      };
-    };
-
-    // Equality for ASTInternal nodes
-    class ASTSymbolEqual{
-    public:
-      bool operator()(const ASTSymbol *sym_ptr1, const ASTSymbol *sym_ptr2) const{ 
-       return (*sym_ptr1 == *sym_ptr2); 
-      }
-    };
-
-    friend bool operator==(const ASTSymbol &sym1, const ASTSymbol &sym2){
-      return (strcmp(sym1._name, sym2._name) == 0);
-    }
-
-    const char * const GetName() const{return _name;}  
-
-    // Print function for symbol -- return name */
-    // (c_friendly is for printing hex. numbers that C compilers will accept)
-    virtual void nodeprint(ostream& os, bool c_friendly = false) { os << _name;}
-
-    // Call this when deleting a node that has been stored in the
-    // the unique table
-    virtual void CleanUp();
-
-    public:
-
-    // Default constructor
-    ASTSymbol(BeevMgr &bm) : ASTInternal(bm), _name(NULL) { }
-
-    // Constructor.  This does NOT copy its argument.
-    ASTSymbol(const char * const name, BeevMgr &bm) : ASTInternal(SYMBOL, bm), 
-                                                     _name(name) { }
-    
-    // Destructor (does nothing, but is declared virtual here.
-    virtual ~ASTSymbol();
-    
-    // Copy constructor
-    // FIXME: seems to be calling default constructor for astinternal
-    ASTSymbol(const ASTSymbol &sym) :
-      ASTInternal(sym._kind, sym._children, sym._bm), 
-      _name(sym._name) { } 
-  }; //End of ASTSymbol
-  
-
-  /***************************************************************************/
-  /*  Class ASTBVConst:  Class to represent internals of a bitvectorconst    */
-  /***************************************************************************/
+                       return h(sym_ptr->_name);
+               }
+               ;
+       };
+
+       // Equality for ASTInternal nodes
+       class ASTSymbolEqual
+       {
+       public:
+               bool operator()(const ASTSymbol *sym_ptr1, const ASTSymbol *sym_ptr2) const
+               {
+                       return (*sym_ptr1 == *sym_ptr2);
+               }
+       };
+
+       friend bool operator==(const ASTSymbol &sym1, const ASTSymbol &sym2)
+       {
+               return (strcmp(sym1._name, sym2._name) == 0);
+       }
+
+       const char * const GetName() const
+       {
+               return _name;
+       }
+
+       // Print function for symbol -- return name */
+       // (c_friendly is for printing hex. numbers that C compilers will accept)
+       virtual void nodeprint(ostream& os, bool c_friendly = false)
+       {
+               os << _name;
+       }
+
+       // Call this when deleting a node that has been stored in the
+       // the unique table
+       virtual void CleanUp();
+
+public:
+
+       // Default constructor
+       ASTSymbol(BeevMgr &bm) :
+               ASTInternal(bm), _name(NULL)
+       {
+       }
+
+       // Constructor.  This does NOT copy its argument.
+       ASTSymbol(const char * const name, BeevMgr &bm) :
+               ASTInternal(SYMBOL, bm), _name(name)
+       {
+       }
+
+       // Destructor (does nothing, but is declared virtual here.
+       virtual ~ASTSymbol();
+
+       // Copy constructor
+       // FIXME: seems to be calling default constructor for astinternal
+       ASTSymbol(const ASTSymbol &sym) :
+               ASTInternal(sym._kind, sym._children, sym._bm), _name(sym._name)
+       {
+       }
+}; //End of ASTSymbol
+
+
+/***************************************************************************/
+/*  Class ASTBVConst:  Class to represent internals of a bitvectorconst    */
+/***************************************************************************/
 
 #ifndef NATIVE_C_ARITH
 
-  class ASTBVConst : public ASTInternal {
-    friend class BeevMgr;
-    friend class ASTNode;
-    friend class ASTNodeHasher;
-    friend class ASTNodeEqual;
-    
-  private:
-    //This is the private copy of a bvconst currently
-    //This should not be changed at any point
-    CBV _bvconst;
-
-    class ASTBVConstHasher{
-    public:
-      size_t operator() (const ASTBVConst * bvc) const {
-        return CONSTANTBV::BitVector_Hash(bvc->_bvconst);
-      };
-    };
-
-    class ASTBVConstEqual{
-    public:
-      bool operator()(const ASTBVConst * bvc1, const ASTBVConst  * bvc2) const { 
-        if( bvc1->_value_width != bvc2->_value_width){
-         return false;
-       }  
-       return (0==CONSTANTBV::BitVector_Compare(bvc1->_bvconst,bvc2->_bvconst));
-      }
-    };
-    
-    //FIXME Keep an eye on this function
-    ASTBVConst(CBV bv, unsigned int width, BeevMgr &bm) :
-      ASTInternal(BVCONST, bm)
-    {
-      _bvconst = CONSTANTBV::BitVector_Clone(bv);
-      _value_width = width;
-    }
-
-    friend bool operator==(const ASTBVConst &bvc1, const ASTBVConst &bvc2){
-      if(bvc1._value_width != bvc2._value_width)
-        return false;
-      return (0==CONSTANTBV::BitVector_Compare(bvc1._bvconst,bvc2._bvconst));
-    }
-    // Call this when deleting a node that has been stored in the
-    // the unique table
-    virtual void CleanUp();
-
-    // Print function for bvconst -- return _bvconst value in bin format
-    // (c_friendly is for printing hex. numbers that C compilers will accept)
-    virtual void nodeprint(ostream& os, bool c_friendly = false) {
-      unsigned char *res;
-      const char *prefix;
-
-      if (_value_width%4 == 0) {
-        res = CONSTANTBV::BitVector_to_Hex(_bvconst);
-        if (c_friendly) {
-          prefix = "0x";
-        }
-        else {
-          prefix = "0hex";
-        }
-      } else {      
-        res = CONSTANTBV::BitVector_to_Bin(_bvconst);
-        if (c_friendly) {
-          prefix = "0b";
-        }
-        else {
-          prefix = "0bin";
-        }
-      }
-      if (NULL == res) {
-        os << "nodeprint: BVCONST : could not convert to string" << _bvconst;
-        FatalError("");
-      }
-      os << prefix << res;
-      CONSTANTBV::BitVector_Dispose(res);
-    }
-
-    // Copy constructor.     
-    ASTBVConst(const ASTBVConst &sym) : 
-      ASTInternal(sym._kind, sym._children, sym._bm)
-    {
-      _bvconst = CONSTANTBV::BitVector_Clone(sym._bvconst);
-      _value_width = sym._value_width;
-    }
-    
-  public:
-    virtual ~ASTBVConst(){
-       CONSTANTBV::BitVector_Destroy(_bvconst);
-    }
-
-    CBV GetBVConst() const {return _bvconst;}
-  }; //End of ASTBVConst
-
-
-  //FIXME This function is DEPRECATED
-  //Do not use in the future
- inline unsigned int GetUnsignedConst(const ASTNode n) 
-  {
-    if(sizeof(unsigned int) * 8  <= n.GetValueWidth())  
-      {
-       // It may only contain a small value in a bit type, which fits nicely into an unsigned int.
-       // This is common for functions like: bvshl(bv1[128], bv1[128])
-       // where both operands have the same type.
-       signed long maxBit = CONSTANTBV::Set_Max(n.GetBVConst());
-       if (maxBit >= ((signed long) sizeof(unsigned int)) * 8 )
-         {
-           n.LispPrint(cerr); //print the node so they can find it.
-           FatalError("GetUnsignedConst: cannot convert bvconst of length greater than 32 to unsigned int");
-         }
-      }
-    return (unsigned int) *((unsigned int *)n.GetBVConst());
-  }
+class ASTBVConst: public ASTInternal
+{
+       friend class BeevMgr;
+       friend class ASTNode;
+       friend class ASTNodeHasher;
+       friend class ASTNodeEqual;
+
+private:
+       //This is the private copy of a bvconst currently
+       //This should not be changed at any point
+       CBV _bvconst;
+
+       class ASTBVConstHasher
+       {
+       public:
+               size_t operator()(const ASTBVConst * bvc) const
+               {
+                       return CONSTANTBV::BitVector_Hash(bvc->_bvconst);
+               }
+               ;
+       };
+
+       class ASTBVConstEqual
+       {
+       public:
+               bool operator()(const ASTBVConst * bvc1, const ASTBVConst * bvc2) const
+               {
+                       if (bvc1->_value_width != bvc2->_value_width)
+                       {
+                               return false;
+                       }
+                       return (0 == CONSTANTBV::BitVector_Compare(bvc1->_bvconst, bvc2->_bvconst));
+               }
+       };
+
+       //FIXME Keep an eye on this function
+       ASTBVConst(CBV bv, unsigned int width, BeevMgr &bm) :
+               ASTInternal(BVCONST, bm)
+       {
+               _bvconst = CONSTANTBV::BitVector_Clone(bv);
+               _value_width = width;
+       }
+
+       friend bool operator==(const ASTBVConst &bvc1, const ASTBVConst &bvc2)
+       {
+               if (bvc1._value_width != bvc2._value_width)
+                       return false;
+               return (0 == CONSTANTBV::BitVector_Compare(bvc1._bvconst, bvc2._bvconst));
+       }
+       // Call this when deleting a node that has been stored in the
+       // the unique table
+       virtual void CleanUp();
+
+       // Print function for bvconst -- return _bvconst value in bin format
+       // (c_friendly is for printing hex. numbers that C compilers will accept)
+       virtual void nodeprint(ostream& os, bool c_friendly = false)
+       {
+               unsigned char *res;
+               const char *prefix;
+
+               if (_value_width % 4 == 0)
+               {
+                       res = CONSTANTBV::BitVector_to_Hex(_bvconst);
+                       if (c_friendly)
+                       {
+                               prefix = "0x";
+                       }
+                       else
+                       {
+                               prefix = "0hex";
+                       }
+               }
+               else
+               {
+                       res = CONSTANTBV::BitVector_to_Bin(_bvconst);
+                       if (c_friendly)
+                       {
+                               prefix = "0b";
+                       }
+                       else
+                       {
+                               prefix = "0bin";
+                       }
+               }
+               if (NULL == res)
+               {
+                       os << "nodeprint: BVCONST : could not convert to string" << _bvconst;
+                       FatalError("");
+               }
+               os << prefix << res;
+               CONSTANTBV::BitVector_Dispose(res);
+       }
+
+       // Copy constructor.
+       ASTBVConst(const ASTBVConst &sym) :
+               ASTInternal(sym._kind, sym._children, sym._bm)
+       {
+               _bvconst = CONSTANTBV::BitVector_Clone(sym._bvconst);
+               _value_width = sym._value_width;
+       }
+
+public:
+       virtual ~ASTBVConst()
+       {
+               CONSTANTBV::BitVector_Destroy(_bvconst);
+       }
+
+       CBV GetBVConst() const
+       {
+               return _bvconst;
+       }
+}; //End of ASTBVConst
+
+
+//FIXME This function is DEPRECATED
+//Do not use in the future
+inline unsigned int GetUnsignedConst(const ASTNode n)
+{
+       if (sizeof(unsigned int) * 8 <= n.GetValueWidth())
+       {
+               // It may only contain a small value in a bit type, which fits nicely into an unsigned int.
+               // This is common for functions like: bvshl(bv1[128], bv1[128])
+               // where both operands have the same type.
+               signed long maxBit = CONSTANTBV::Set_Max(n.GetBVConst());
+               if (maxBit >= ((signed long) sizeof(unsigned int)) * 8)
+               {
+                       n.LispPrint(cerr); //print the node so they can find it.
+                       FatalError("GetUnsignedConst: cannot convert bvconst of length greater than 32 to unsigned int");
+               }
+       }
+       return (unsigned int) *((unsigned int *) n.GetBVConst());
+}
 #else
-  class ASTBVConst : public ASTInternal {
-    friend class BeevMgr;
-    friend class ASTNode;
-    friend class ASTNodeHasher;
-    friend class ASTNodeEqual;
-
-  private:
-    // the bitvector contents. bitvector contents will be in two
-    // modes. one mode where all bitvectors are NATIVE and in this
-    // mode we use native unsigned long long int to represent the
-    // 32/64 bitvectors. The other for arbitrary length bitvector
-    // operations.
-    const unsigned long long int _bvconst;
-
-    class ASTBVConstHasher{
-    public:
-      size_t operator() (const ASTBVConst * bvc) const{ 
-       //Thomas Wang's 64 bit Mix Function
-       unsigned long long int key(bvc->_bvconst);
-       key += ~(key << 32);
-       key ^= (key  >> 22);
-       key += ~(key << 13);
-       key ^= (key  >> 8);
-       key += (key  << 3);
-       key ^= (key  >> 15);
-       key += ~(key << 27);
-       key ^= (key  >> 31);
-       
-       size_t return_key = key;
-       return return_key;
-      };
-    };
-
-    class ASTBVConstEqual{
-    public:
-      bool operator()(const ASTBVConst * bvc1, const ASTBVConst  * bvc2) const { 
-       return ((bvc1->_bvconst == bvc2->_bvconst) 
-               && (bvc1->_value_width == bvc2->_value_width));
-      }
-    };
-
-    // Call this when deleting a node that has been stored in the
-    // the unique table
-    virtual void CleanUp();
-  public:
-    // Default constructor
-    ASTBVConst(const unsigned long long int bv, BeevMgr &bm) : 
-      ASTInternal(BVCONST, bm), _bvconst(bv) { 
-    }
-
-    // Copy constructor. FIXME: figure out how this is supposed to
-    // work.
-    ASTBVConst(const ASTBVConst &sym) : 
-      ASTInternal(sym._kind, sym._children, sym._bm), 
-      _bvconst(sym._bvconst) { 
-      _value_width = sym._value_width;
-    } 
-
-    // Destructor (does nothing, but is declared virtual here)
-    virtual ~ASTBVConst() { } 
-    
-    friend bool operator==(const ASTBVConst &sym1, const ASTBVConst &sym2){
-      return ((sym1._bvconst == sym2._bvconst) && 
-             (sym1._value_width == sym2._value_width));
-    }
-
-    // Print function for bvconst -- return _bvconst value in binary format
-    virtual void nodeprint(ostream& os, bool c_friendly = false) {
-      string s = "0bin";
-      unsigned long long int bitmask = 0x8000000000000000LL;
-      bitmask = bitmask >> (64-_value_width);
-
-      for (; bitmask > 0; bitmask >>= 1)
-       s += (_bvconst & bitmask) ? '1' : '0';  
-      os << s;
-    }
-    
-    unsigned long long int GetBVConst() const  {return _bvconst;}
-  }; //End of ASTBVConst
-
-  //return value of bvconst
-  inline unsigned int GetUnsignedConst(const ASTNode n) {
-    if(32 < n.GetValueWidth())
-      FatalError("GetUnsignedConst: cannot convert bvconst of length greater than 32 to unsigned int:");    
-    return (unsigned int)n.GetBVConst();
-  }
+class ASTBVConst : public ASTInternal
+{
+       friend class BeevMgr;
+       friend class ASTNode;
+       friend class ASTNodeHasher;
+       friend class ASTNodeEqual;
+
+private:
+       // the bitvector contents. bitvector contents will be in two
+       // modes. one mode where all bitvectors are NATIVE and in this
+       // mode we use native unsigned long long int to represent the
+       // 32/64 bitvectors. The other for arbitrary length bitvector
+       // operations.
+       const unsigned long long int _bvconst;
+
+       class ASTBVConstHasher
+       {
+       public:
+               size_t operator() (const ASTBVConst * bvc) const
+               {
+                       //Thomas Wang's 64 bit Mix Function
+                       unsigned long long int key(bvc->_bvconst);
+                       key += ~(key << 32);
+                       key ^= (key >> 22);
+                       key += ~(key << 13);
+                       key ^= (key >> 8);
+                       key += (key << 3);
+                       key ^= (key >> 15);
+                       key += ~(key << 27);
+                       key ^= (key >> 31);
+
+                       size_t return_key = key;
+                       return return_key;
+               };
+       };
+
+       class ASTBVConstEqual
+       {
+       public:
+               bool operator()(const ASTBVConst * bvc1, const ASTBVConst * bvc2) const
+               {
+                       return ((bvc1->_bvconst == bvc2->_bvconst)
+                                       && (bvc1->_value_width == bvc2->_value_width));
+               }
+       };
+
+       // Call this when deleting a node that has been stored in the
+       // the unique table
+       virtual void CleanUp();
+public:
+       // Default constructor
+       ASTBVConst(const unsigned long long int bv, BeevMgr &bm) :
+       ASTInternal(BVCONST, bm), _bvconst(bv)
+       {
+       }
+
+       // Copy constructor. FIXME: figure out how this is supposed to
+       // work.
+       ASTBVConst(const ASTBVConst &sym) :
+       ASTInternal(sym._kind, sym._children, sym._bm),
+       _bvconst(sym._bvconst)
+       {
+               _value_width = sym._value_width;
+       }
+
+       // Destructor (does nothing, but is declared virtual here)
+       virtual ~ASTBVConst()
+       {}
+
+       friend bool operator==(const ASTBVConst &sym1, const ASTBVConst &sym2)
+       {
+               return ((sym1._bvconst == sym2._bvconst) &&
+                               (sym1._value_width == sym2._value_width));
+       }
+
+       // Print function for bvconst -- return _bvconst value in binary format
+       virtual void nodeprint(ostream& os, bool c_friendly = false)
+       {
+               string s = "0bin";
+               unsigned long long int bitmask = 0x8000000000000000LL;
+               bitmask = bitmask >> (64-_value_width);
+
+               for (; bitmask > 0; bitmask >>= 1)
+               s += (_bvconst & bitmask) ? '1' : '0';
+               os << s;
+       }
+
+       unsigned long long int GetBVConst() const
+       {       return _bvconst;}
+}; //End of ASTBVConst
+
+//return value of bvconst
+inline unsigned int GetUnsignedConst(const ASTNode n)
+{
+       if(32 < n.GetValueWidth())
+       FatalError("GetUnsignedConst: cannot convert bvconst of length greater than 32 to unsigned int:");
+       return (unsigned int)n.GetBVConst();
+}
 #endif
 /*
-#else
-  // the bitvector contents. bitvector contents will be in two
-  // modes. one mode where all bitvectors are NATIVE and in this mode
-  // we use native unsigned long long int to represent the 32/64
-  // bitvectors. The other for arbitrary length bitvector operations.
-
-  //BVCONST defined for arbitrary length bitvectors
-  class ASTBVConst : public ASTInternal{
-    friend class BeevMgr;
-    friend class ASTNode;
-    friend class ASTNodeHasher;
-    friend class ASTNodeEqual;
-
-  private:
-    const char * const _bvconst;
-
-    class ASTBVConstHasher{
-    public:
-      size_t operator() (const ASTBVConst * bvc) const{ 
-       hash<char*> h;  
-       return h(bvc->_bvconst);
-      };
-    };
-
-    class ASTBVConstEqual{
-    public:
-      bool operator()(const ASTBVConst * bvc1, const ASTBVConst  * bvc2) const { 
-       if(bvc1->_value_width != bvc2->_value_width)
-         return false;
-       return (0 == strncmp(bvc1->_bvconst,bvc2->_bvconst,bvc1->_value_width));
-      }
-    };
-    
-    ASTBVConst(const char * bv, BeevMgr &bm) : 
-      ASTInternal(BVCONST, bm), _bvconst(bv) { 
-      //_value_width = strlen(bv);
-    }
-
-    friend bool operator==(const ASTBVConst &bvc1, const ASTBVConst &bvc2){
-      if(bvc1._value_width != bvc2._value_width)
-       return false;
-      return (0 == strncmp(bvc1._bvconst,bvc2._bvconst,bvc1._value_width));
-    }
-
-    // Call this when deleting a node that has been stored in the
-    // the unique table
-    virtual void CleanUp();
-
-    // Print function for bvconst -- return _bvconst value in binary format
-    virtual void nodeprint(ostream& os) {
-      if(_value_width%4 == 0) {
-       unsigned int *  iii = CONSTANTBV::BitVector_Create(_value_width,true);
-       CONSTANTBV::ErrCode e = CONSTANTBV::BitVector_from_Bin(iii,(unsigned char*)_bvconst);
-       //error printing
-       if(0 != e) {
-         os << "nodeprint: BVCONST : wrong hex value: " << BitVector_Error(e);
-         FatalError("");
+ #else
+ // the bitvector contents. bitvector contents will be in two
+ // modes. one mode where all bitvectors are NATIVE and in this mode
+ // we use native unsigned long long int to represent the 32/64
+ // bitvectors. The other for arbitrary length bitvector operations.
+
+ //BVCONST defined for arbitrary length bitvectors
+ class ASTBVConst : public ASTInternal{
+ friend class BeevMgr;
+ friend class ASTNode;
+ friend class ASTNodeHasher;
+ friend class ASTNodeEqual;
+
+ private:
+ const char * const _bvconst;
+
+ class ASTBVConstHasher{
+ public:
+ size_t operator() (const ASTBVConst * bvc) const{
+ hash<char*> h;
+ return h(bvc->_bvconst);
+ };
+ };
+
+ class ASTBVConstEqual{
+ public:
+ bool operator()(const ASTBVConst * bvc1, const ASTBVConst  * bvc2) const {
+ if(bvc1->_value_width != bvc2->_value_width)
+ return false;
+ return (0 == strncmp(bvc1->_bvconst,bvc2->_bvconst,bvc1->_value_width));
+ }
+ };
+
+ ASTBVConst(const char * bv, BeevMgr &bm) :
+ ASTInternal(BVCONST, bm), _bvconst(bv) {
+ //_value_width = strlen(bv);
+ }
+
+ friend bool operator==(const ASTBVConst &bvc1, const ASTBVConst &bvc2){
+ if(bvc1._value_width != bvc2._value_width)
+ return false;
+ return (0 == strncmp(bvc1._bvconst,bvc2._bvconst,bvc1._value_width));
+ }
+
+ // Call this when deleting a node that has been stored in the
+ // the unique table
+ virtual void CleanUp();
+
+ // Print function for bvconst -- return _bvconst value in binary format
+ virtual void nodeprint(ostream& os) {
+ if(_value_width%4 == 0) {
+ unsigned int *  iii = CONSTANTBV::BitVector_Create(_value_width,true);
+ CONSTANTBV::ErrCode e = CONSTANTBV::BitVector_from_Bin(iii,(unsigned char*)_bvconst);
+ //error printing
+ if(0 != e) {
+ os << "nodeprint: BVCONST : wrong hex value: " << BitVector_Error(e);
+ FatalError("");
+ }
+ unsigned char * ccc = CONSTANTBV::BitVector_to_Hex(iii);
+ os << "0hex" << ccc;
+ CONSTANTBV::BitVector_Destroy(iii);
+ }
+ else {
+ std::string s(_bvconst,_value_width);
+ s = "0bin" + s;
+ os << s;
+ }
+ }
+
+ // Copy constructor.
+ ASTBVConst(const ASTBVConst &sym) : ASTInternal(sym._kind, sym._children, sym._bm),_bvconst(sym._bvconst) {
+ //checking if the input is in the correct format
+ for(unsigned int jj=0;jj<sym._value_width;jj++)
+ if(!(sym._bvconst[jj] == '0' || sym._bvconst[jj] == '1')) {
+ cerr << "Fatal Error: wrong input to ASTBVConst copy constructor:" << sym._bvconst << endl;
+ FatalError("");
+ }
+ _value_width = sym._value_width;
+ }
+ public:
+ // Destructor (does nothing, but is declared virtual here)
+ virtual ~ASTBVConst(){}
+
+ const char * const GetBVConst() const {return _bvconst;}
+ }; //End of ASTBVConst
+
+ unsigned int * ConvertToCONSTANTBV(const char * s);
+
+ //return value of bvconst
+ inline unsigned int GetUnsignedConst(const ASTNode n) {
+ if(32 < n.GetValueWidth())
+ FatalError("GetUnsignedConst: cannot convert bvconst of length greater than 32 to unsigned int:");
+ std::string s(n.GetBVConst(), n.GetValueWidth());
+ unsigned int output = strtoul(s.c_str(),NULL,2);
+ return output;
+ } //end of ASTBVConst class
+ #endif
+ */
+/***************************************************************************
+ * Typedef ASTNodeMap:  This is a hash table from ASTNodes to ASTNodes.
+ * It is very convenient for attributes that are not speed-critical
+ **************************************************************************/
+// These are generally useful for storing ASTNodes or attributes thereof
+// Hash table from ASTNodes to ASTNodes
+typedef hash_map<ASTNode, ASTNode, ASTNode::ASTNodeHasher, ASTNode::ASTNodeEqual> ASTNodeMap;
+
+// Function to dump contents of ASTNodeMap
+ostream &operator<<(ostream &os, const ASTNodeMap &nmap);
+
+/***************************************************************************
+ Typedef ASTNodeSet:  This is a hash set of ASTNodes.  Very useful
+ for representing things like "visited nodes"
+ ***************************************************************************/
+typedef hash_set<ASTNode, ASTNode::ASTNodeHasher, ASTNode::ASTNodeEqual> ASTNodeSet;
+
+typedef hash_multiset<ASTNode, ASTNode::ASTNodeHasher, ASTNode::ASTNodeEqual> ASTNodeMultiSet;
+
+//external parser table for declared symbols.
+//FIXME: move to a more appropriate place
+extern ASTNodeSet _parser_symbol_table;
+
+/***************************************************************************
+ Class LispPrinter:  iomanipulator for printing ASTNode or ASTVec
+ ***************************************************************************/
+class LispPrinter
+{
+
+public:
+       ASTNode _node;
+
+       // number of spaces to print before first real character of
+       // object.
+       int _indentation;
+
+       // FIXME: pass ASTNode by reference
+       // Constructor to build the LispPrinter object
+       LispPrinter(ASTNode node, int indentation) :
+               _node(node), _indentation(indentation)
+       {
        }
-       unsigned char * ccc = CONSTANTBV::BitVector_to_Hex(iii);
-       os << "0hex" << ccc;
-       CONSTANTBV::BitVector_Destroy(iii);
-      }
-      else {
-       std::string s(_bvconst,_value_width);
-       s = "0bin" + s;
-       os << s;
-      }
-    }
-
-    // Copy constructor.     
-    ASTBVConst(const ASTBVConst &sym) : ASTInternal(sym._kind, sym._children, sym._bm),_bvconst(sym._bvconst) { 
-      //checking if the input is in the correct format
-      for(unsigned int jj=0;jj<sym._value_width;jj++)
-       if(!(sym._bvconst[jj] == '0' || sym._bvconst[jj] == '1')) {
-         cerr << "Fatal Error: wrong input to ASTBVConst copy constructor:" << sym._bvconst << endl;
-         FatalError("");
+
+       friend ostream &operator<<(ostream &os, const LispPrinter &lp)
+       {
+               return lp._node.LispPrint(os, lp._indentation);
        }
-      _value_width = sym._value_width;
-    } 
-  public:
-    // Destructor (does nothing, but is declared virtual here)
-    virtual ~ASTBVConst(){}
-
-    const char * const GetBVConst() const {return _bvconst;}
-  }; //End of ASTBVConst
-
-  unsigned int * ConvertToCONSTANTBV(const char * s);
-
-  //return value of bvconst
-  inline unsigned int GetUnsignedConst(const ASTNode n) {
-    if(32 < n.GetValueWidth())
-      FatalError("GetUnsignedConst: cannot convert bvconst of length greater than 32 to unsigned int:");    
-    std::string s(n.GetBVConst(), n.GetValueWidth());
-      unsigned int output = strtoul(s.c_str(),NULL,2);
-      return output;
-  } //end of ASTBVConst class
-#endif
-*/
-  /***************************************************************************
-   * Typedef ASTNodeMap:  This is a hash table from ASTNodes to ASTNodes.
-   * It is very convenient for attributes that are not speed-critical
-   **************************************************************************/
-  // These are generally useful for storing ASTNodes or attributes thereof
-  // Hash table from ASTNodes to ASTNodes
-  typedef hash_map<ASTNode, ASTNode, 
-                  ASTNode::ASTNodeHasher, 
-                  ASTNode::ASTNodeEqual> ASTNodeMap;
-
-  // Function to dump contents of ASTNodeMap
-  ostream &operator<<(ostream &os, const ASTNodeMap &nmap);
-  
-  /***************************************************************************
-   Typedef ASTNodeSet:  This is a hash set of ASTNodes.  Very useful
-   for representing things like "visited nodes"
-  ***************************************************************************/
-  typedef hash_set<ASTNode, 
-                  ASTNode::ASTNodeHasher, 
-                  ASTNode::ASTNodeEqual> ASTNodeSet;
-
-  typedef hash_multiset<ASTNode, 
-                       ASTNode::ASTNodeHasher, 
-                       ASTNode::ASTNodeEqual> ASTNodeMultiSet;
-
-  //external parser table for declared symbols.
-  //FIXME: move to a more appropriate place
-  extern ASTNodeSet _parser_symbol_table;
-  
-  /***************************************************************************
-    Class LispPrinter:  iomanipulator for printing ASTNode or ASTVec       
-  ***************************************************************************/
-  class LispPrinter {
-
-  public:
-    ASTNode _node;
-
-    // number of spaces to print before first real character of
-    // object.
-    int _indentation;  
-
-    // FIXME: pass ASTNode by reference
-    // Constructor to build the LispPrinter object
-    LispPrinter(ASTNode node, int indentation): _node(node), _indentation(indentation) { }    
-
-    friend ostream &operator<<(ostream &os, const LispPrinter &lp){ 
-      return lp._node.LispPrint(os, lp._indentation); 
-    };
-
-  }; //End of ListPrinter
-  
-  //This is the IO manipulator.  It builds an object of class
-  //"LispPrinter" that has a special overloaded "<<" operator.
-  inline LispPrinter lisp(const ASTNode &node, int indentation = 0){
-    LispPrinter lp(node, indentation);
-    return lp;
-  }
-  
-  /***************************************************************************/
-  /*  Class LispVecPrinter:iomanipulator for printing vector of ASTNodes     */
-  /***************************************************************************/
-  class LispVecPrinter {
-
-  public:
-    const ASTVec * _vec;
-    // number of spaces to print before first real
-    // character of object.    
-    int _indentation;
-    
-    // Constructor to build the LispPrinter object
-    LispVecPrinter(const ASTVec &vec, int indentation){
-      _vec = &vec; _indentation = indentation; 
-    }
-    
-    friend ostream &operator<<(ostream &os, const LispVecPrinter &lvp){
-    LispPrintVec(os, *lvp._vec, lvp._indentation);
-    return os;
-    };
-  }; //End of Class ListVecPrinter
-
-  //iomanipulator. builds an object of class "LisPrinter" that has a
-  //special overloaded "<<" operator.
-  inline LispVecPrinter lisp(const ASTVec &vec, int indentation = 0){
-    LispVecPrinter lvp(vec, indentation);
-    return lvp;
-  }
-
-
-  /*****************************************************************
-   * INLINE METHODS from various classed, declared here because of
-   * dependencies on classes that are declared later.
-   *****************************************************************/
-  // ASTNode accessor function.
-  inline Kind ASTNode::GetKind() const { 
-    //cout << "GetKind: " << _int_node_ptr; 
-    return _int_node_ptr->GetKind(); 
-  }
-
-  // FIXME: should be const ASTVec const?  
-  // Declared here because of same ordering problem as  GetKind.
-  inline const ASTVec &ASTNode::GetChildren() const { 
-    return _int_node_ptr->GetChildren(); 
-  }
-
-  // Access node number
-  inline int ASTNode::GetNodeNum() const { 
-    return _int_node_ptr->_node_num; 
-  }
-
-  inline unsigned int ASTNode::GetIndexWidth () const { 
-    return _int_node_ptr->_index_width; 
-  }
-  
-  inline void ASTNode::SetIndexWidth (unsigned int iw) const { 
-    _int_node_ptr->_index_width = iw;
-  }
-  
-  inline unsigned int ASTNode::GetValueWidth () const { 
-    return _int_node_ptr->_value_width; 
-  }
-  
-  inline void ASTNode::SetValueWidth (unsigned int vw) const {
-    _int_node_ptr->_value_width = vw; 
-  }
-
-  //return the type of the ASTNode: 0 iff BOOLEAN; 1 iff BITVECTOR; 2
-  //iff ARRAY; 3 iff UNKNOWN;
-  inline types ASTNode::GetType() const {
-    if((GetIndexWidth() == 0) && (GetValueWidth() == 0)) //BOOLEAN
-      return BOOLEAN_TYPE;
-    if((GetIndexWidth() == 0) && (GetValueWidth() > 0))  //BITVECTOR
-      return BITVECTOR_TYPE;
-    if((GetIndexWidth() > 0) && (GetValueWidth() > 0)) //ARRAY
-      return ARRAY_TYPE;
-    return UNKNOWN_TYPE; 
-  }
-
-  // Constructor; creates a new pointer, increments refcount of
-  // pointed-to object.
+       ;
+
+}; //End of ListPrinter
+
+//This is the IO manipulator.  It builds an object of class
+//"LispPrinter" that has a special overloaded "<<" operator.
+inline LispPrinter lisp(const ASTNode &node, int indentation = 0)
+{
+       LispPrinter lp(node, indentation);
+       return lp;
+}
+
+/***************************************************************************/
+/*  Class LispVecPrinter:iomanipulator for printing vector of ASTNodes     */
+/***************************************************************************/
+class LispVecPrinter
+{
+
+public:
+       const ASTVec * _vec;
+       // number of spaces to print before first real
+       // character of object.
+       int _indentation;
+
+       // Constructor to build the LispPrinter object
+       LispVecPrinter(const ASTVec &vec, int indentation)
+       {
+               _vec = &vec;
+               _indentation = indentation;
+       }
+
+       friend ostream &operator<<(ostream &os, const LispVecPrinter &lvp)
+       {
+               LispPrintVec(os, *lvp._vec, lvp._indentation);
+               return os;
+       }
+       ;
+}; //End of Class ListVecPrinter
+
+//iomanipulator. builds an object of class "LisPrinter" that has a
+//special overloaded "<<" operator.
+inline LispVecPrinter lisp(const ASTVec &vec, int indentation = 0)
+{
+       LispVecPrinter lvp(vec, indentation);
+       return lvp;
+}
+
+/*****************************************************************
+ * INLINE METHODS from various classed, declared here because of
+ * dependencies on classes that are declared later.
+ *****************************************************************/
+// ASTNode accessor function.
+inline Kind ASTNode::GetKind() const
+{
+       //cout << "GetKind: " << _int_node_ptr;
+       return _int_node_ptr->GetKind();
+}
+
+// FIXME: should be const ASTVec const?
+// Declared here because of same ordering problem as  GetKind.
+inline const ASTVec &ASTNode::GetChildren() const
+{
+       return _int_node_ptr->GetChildren();
+}
+
+// Access node number
+inline int ASTNode::GetNodeNum() const
+{
+       return _int_node_ptr->_node_num;
+}
+
+inline unsigned int ASTNode::GetIndexWidth() const
+{
+       return _int_node_ptr->_index_width;
+}
+
+inline void ASTNode::SetIndexWidth(unsigned int iw) const
+{
+       _int_node_ptr->_index_width = iw;
+}
+
+inline unsigned int ASTNode::GetValueWidth() const
+{
+       return _int_node_ptr->_value_width;
+}
+
+inline void ASTNode::SetValueWidth(unsigned int vw) const
+{
+       _int_node_ptr->_value_width = vw;
+}
+
+//return the type of the ASTNode: 0 iff BOOLEAN; 1 iff BITVECTOR; 2
+//iff ARRAY; 3 iff UNKNOWN;
+inline types ASTNode::GetType() const
+{
+       if ((GetIndexWidth() == 0) && (GetValueWidth() == 0)) //BOOLEAN
+               return BOOLEAN_TYPE;
+       if ((GetIndexWidth() == 0) && (GetValueWidth() > 0)) //BITVECTOR
+               return BITVECTOR_TYPE;
+       if ((GetIndexWidth() > 0) && (GetValueWidth() > 0)) //ARRAY
+               return ARRAY_TYPE;
+       return UNKNOWN_TYPE;
+}
+
+// Constructor; creates a new pointer, increments refcount of
+// pointed-to object.
 #ifndef SMTLIB
-  inline ASTNode::ASTNode(ASTInternal *in) : _int_node_ptr(in) { 
-    if (in) in->IncRef(); 
-  }
+inline ASTNode::ASTNode(ASTInternal *in) :
+       _int_node_ptr(in)
+{
+       if (in)
+               in->IncRef();
+}
 #else
-  inline ASTNode::ASTNode(ASTInternal *in) : _int_node_ptr(in) { };
+inline ASTNode::ASTNode(ASTInternal *in) : _int_node_ptr(in)
+{};
 #endif
 
-  // Assignment.  Increment refcount of new value, decrement refcount
-  // of old value and destroy if this was the last pointer.  FIXME:
-  // accelerate this by creating an intnode with a ref counter instead
-  // of pointing to NULL.  Need a special check in CleanUp to make
-  // sure the null node never gets freed.
+// Assignment.  Increment refcount of new value, decrement refcount
+// of old value and destroy if this was the last pointer.  FIXME:
+// accelerate this by creating an intnode with a ref counter instead
+// of pointing to NULL.  Need a special check in CleanUp to make
+// sure the null node never gets freed.
 
 #ifndef SMTLIB
-  inline ASTNode& ASTNode::operator=(const ASTNode& n) {
-    if (n._int_node_ptr) {
-      n._int_node_ptr->IncRef();
-    }
-    if (_int_node_ptr) {
-      _int_node_ptr->DecRef();
-    }
-    _int_node_ptr = n._int_node_ptr;
-    return *this;
-  }
+inline ASTNode& ASTNode::operator=(const ASTNode& n)
+{
+       if (n._int_node_ptr)
+       {
+               n._int_node_ptr->IncRef();
+       }
+       if (_int_node_ptr)
+       {
+               _int_node_ptr->DecRef();
+       }
+       _int_node_ptr = n._int_node_ptr;
+       return *this;
+}
 #else
-  inline ASTNode& ASTNode::operator=(const ASTNode& n) {
-    _int_node_ptr = n._int_node_ptr;
-    return *this;
-  }
+inline ASTNode& ASTNode::operator=(const ASTNode& n)
+{
+       _int_node_ptr = n._int_node_ptr;
+       return *this;
+}
 #endif
 
 #ifndef SMTLIB
-  inline void ASTInternal::DecRef()
-  {
-    if (--_ref_count == 0) {
-      // Delete node from unique table and kill it.
-      CleanUp();
-    }
-  }
-
-  // Destructor
-  inline ASTNode::~ASTNode()
-  {
-    if (_int_node_ptr) {
-      _int_node_ptr->DecRef();
-    }
-  };
+inline void ASTInternal::DecRef()
+{
+       if (--_ref_count == 0)
+       {
+               // Delete node from unique table and kill it.
+               CleanUp();
+       }
+}
+
+// Destructor
+inline ASTNode::~ASTNode()
+{
+       if (_int_node_ptr)
+       {
+               _int_node_ptr->DecRef();
+       }
+}
+;
 #else
-  // No refcounting
-  inline void ASTInternal::DecRef()
-  {
-  }
-
-  // Destructor
-  inline ASTNode::~ASTNode()
-  {
-  };
+// No refcounting
+inline void ASTInternal::DecRef()
+{
+}
+
+// Destructor
+inline ASTNode::~ASTNode()
+{
+};
 #endif
 
-  inline BeevMgr& ASTNode::GetBeevMgr() const { return _int_node_ptr->_bm; }
-
-  /***************************************************************************
-   * Class BeevMgr.  This holds all "global" variables for the system, such as
-   * unique tables for the various kinds of nodes.
-   ***************************************************************************/
-  class BeevMgr {
-    friend class ASTNode;      // ASTNode modifies AlreadyPrintedSet
-                               // in BeevMgr
-    friend class ASTInterior;
-    friend class ASTBVConst;
-    friend class ASTSymbol;
-
-    // FIXME: The values appear to be the same regardless of the value of SMTLIB
-    // initial hash table sizes, to save time on resizing.
+inline BeevMgr& ASTNode::GetBeevMgr() const
+{
+       return _int_node_ptr->_bm;
+}
+
+/***************************************************************************
+ * Class BeevMgr.  This holds all "global" variables for the system, such as
+ * unique tables for the various kinds of nodes.
+ ***************************************************************************/
+class BeevMgr
+{
+       friend class ASTNode; // ASTNode modifies AlreadyPrintedSet
+       // in BeevMgr
+       friend class ASTInterior;
+       friend class ASTBVConst;
+       friend class ASTSymbol;
+
+       // FIXME: The values appear to be the same regardless of the value of SMTLIB
+       // initial hash table sizes, to save time on resizing.
 #ifdef SMTLIB
-    static const int INITIAL_INTERIOR_UNIQUE_TABLE_SIZE = 100;
-    static const int INITIAL_SYMBOL_UNIQUE_TABLE_SIZE = 100;
-    static const int INITIAL_BVCONST_UNIQUE_TABLE_SIZE = 100;
-    static const int INITIAL_BBTERM_MEMO_TABLE_SIZE = 100;
-    static const int INITIAL_BBFORM_MEMO_TABLE_SIZE = 100;
-
-    static const int INITIAL_SIMPLIFY_MAP_SIZE = 100;
-    static const int INITIAL_SOLVER_MAP_SIZE = 100;
-    static const int INITIAL_ARRAYREAD_SYMBOL_SIZE = 100;
-    static const int INITIAL_INTRODUCED_SYMBOLS_SIZE = 100;
+       static const int INITIAL_INTERIOR_UNIQUE_TABLE_SIZE = 100;
+       static const int INITIAL_SYMBOL_UNIQUE_TABLE_SIZE = 100;
+       static const int INITIAL_BVCONST_UNIQUE_TABLE_SIZE = 100;
+       static const int INITIAL_BBTERM_MEMO_TABLE_SIZE = 100;
+       static const int INITIAL_BBFORM_MEMO_TABLE_SIZE = 100;
+
+       static const int INITIAL_SIMPLIFY_MAP_SIZE = 100;
+       static const int INITIAL_SOLVER_MAP_SIZE = 100;
+       static const int INITIAL_ARRAYREAD_SYMBOL_SIZE = 100;
+       static const int INITIAL_INTRODUCED_SYMBOLS_SIZE = 100;
 #else
-    // these are the STL defaults
-    static const int INITIAL_INTERIOR_UNIQUE_TABLE_SIZE = 100;
-    static const int INITIAL_SYMBOL_UNIQUE_TABLE_SIZE = 100;
-    static const int INITIAL_BVCONST_UNIQUE_TABLE_SIZE = 100;
-    static const int INITIAL_BBTERM_MEMO_TABLE_SIZE = 100;
-    static const int INITIAL_BBFORM_MEMO_TABLE_SIZE = 100;
-
-    static const int INITIAL_SIMPLIFY_MAP_SIZE = 100;
-    static const int INITIAL_SOLVER_MAP_SIZE = 100;
-    static const int INITIAL_ARRAYREAD_SYMBOL_SIZE = 100;
-    static const int INITIAL_INTRODUCED_SYMBOLS_SIZE = 100;
+       // these are the STL defaults
+       static const int INITIAL_INTERIOR_UNIQUE_TABLE_SIZE = 100;
+       static const int INITIAL_SYMBOL_UNIQUE_TABLE_SIZE = 100;
+       static const int INITIAL_BVCONST_UNIQUE_TABLE_SIZE = 100;
+       static const int INITIAL_BBTERM_MEMO_TABLE_SIZE = 100;
+       static const int INITIAL_BBFORM_MEMO_TABLE_SIZE = 100;
+
+       static const int INITIAL_SIMPLIFY_MAP_SIZE = 100;
+       static const int INITIAL_SOLVER_MAP_SIZE = 100;
+       static const int INITIAL_ARRAYREAD_SYMBOL_SIZE = 100;
+       static const int INITIAL_INTRODUCED_SYMBOLS_SIZE = 100;
 #endif
 
-  private:
-    // Typedef for unique Interior node table. 
-    typedef hash_set<ASTInterior *, 
-                    ASTInterior::ASTInteriorHasher, 
-                    ASTInterior::ASTInteriorEqual> ASTInteriorSet;
-
-    // Typedef for unique Symbol node (leaf) table.
-    typedef hash_set<ASTSymbol *, 
-                    ASTSymbol::ASTSymbolHasher, 
-                    ASTSymbol::ASTSymbolEqual> ASTSymbolSet;
-
-    // Unique tables to share nodes whenever possible.
-    ASTInteriorSet _interior_unique_table;
-    //The _symbol_unique_table is also the symbol table to be used
-    //during parsing/semantic analysis
-    ASTSymbolSet _symbol_unique_table;
-    
-    //Typedef for unique BVConst node (leaf) table.
-    typedef hash_set<ASTBVConst *, 
-                    ASTBVConst::ASTBVConstHasher,
-                    ASTBVConst::ASTBVConstEqual> ASTBVConstSet;
-
-    //table to uniquefy bvconst
-    ASTBVConstSet _bvconst_unique_table;
-
-    // type of memo table.
-    typedef hash_map<ASTNode, ASTVec,
-                    ASTNode::ASTNodeHasher, 
-                    ASTNode::ASTNodeEqual> ASTNodeToVecMap;
-
-    typedef hash_map<ASTNode,ASTNodeSet,
-                    ASTNode::ASTNodeHasher,
-                    ASTNode::ASTNodeEqual> ASTNodeToSetMap;
-    
-    // Memo table for bit blasted terms.  If a node has already been
-    // bitblasted, it is mapped to a vector of Boolean formulas for
-    // the bits.
-    
-    //OLD: ASTNodeToVecMap BBTermMemo;
-    ASTNodeMap BBTermMemo;
-    
-    // Memo table for bit blasted formulas.  If a node has already
-    // been bitblasted, it is mapped to a node representing the
-    // bitblasted equivalent
-    ASTNodeMap BBFormMemo;
-
-    //public:
-    // Get vector of Boolean formulas for sum of two
-    // vectors of Boolean formulas
-    void BBPlus2(ASTVec& sum, const ASTVec& y, ASTNode cin);
-    // Increment
-    ASTVec BBInc(ASTVec& x);
-    // Add one bit to a vector of bits.
-    ASTVec BBAddOneBit(ASTVec& x, ASTNode cin);
-    // Bitwise complement
-    ASTVec BBNeg(const ASTVec& x);
-    // Unary minus
-    ASTVec BBUminus(const ASTVec& x);
-    // Multiply.
-    ASTVec BBMult(const ASTVec& x, const ASTVec& y);
-    // AND each bit of vector y with single bit b and return the result.
-    // (used in BBMult)
-    ASTVec BBAndBit(const ASTVec& y, ASTNode b);
-    // Returns ASTVec for result - y.  This destroys "result".
-    void BBSub(ASTVec& result, const ASTVec& y);
-    // build ITE's (ITE cond then[i] else[i]) for each i.
-    ASTVec BBITE(const ASTNode& cond, 
-                const ASTVec& thn, const ASTVec& els);
-    // Build a vector of zeros.
-    ASTVec BBfill(unsigned int width, ASTNode fillval);
-    // build an EQ formula
-    ASTNode BBEQ(const ASTVec& left, const ASTVec& right);
-
-    // This implements a variant of binary long division.
-    // q and r are "out" parameters.  rwidth puts a bound on the
-    // recursion depth.   Unsigned only, for now.
-    void BBDivMod(const ASTVec &y,
-                 const ASTVec &x,
-                 ASTVec &q,
-                 ASTVec &r,
-                 unsigned int rwidth);
-    
-    // Return formula for majority function of three formulas.
-    ASTNode Majority(const ASTNode& a, const ASTNode& b, const ASTNode& c);
-
-    // Internal bit blasting routines.
-    ASTNode BBBVLE(const ASTVec& x, const ASTVec& y, bool is_signed);
-
-    // Return bit-blasted form for BVLE, BVGE, BVGT, SBLE, etc. 
-    ASTNode BBcompare(const ASTNode& form);
-
-    // Left and right shift one.  Writes into x.
-    void BBLShift(ASTVec& x);
-    void BBRShift(ASTVec& x);
-
-    void BBLShift(ASTVec& x, unsigned int shift);
-    void BBRShift(ASTVec& x, unsigned int shift);
-
-  public:
-    // Simplifying create functions
-    ASTNode CreateSimpForm(Kind kind, ASTVec &children);
-    ASTNode CreateSimpForm(Kind kind, const ASTNode& child0);
-    ASTNode CreateSimpForm(Kind kind,
-                                   const ASTNode& child0,
-                                   const ASTNode& child1);
-    ASTNode CreateSimpForm(Kind kind,
-                                   const ASTNode& child0,
-                                   const ASTNode& child1,
-                                   const ASTNode& child2);
-
-    ASTNode CreateSimpNot(const ASTNode& form);
-
-    // These are for internal use only.
-    // FIXME: Find a way to make this local to SimpBool, so they're
-    // not in AST.h
-    ASTNode CreateSimpXor(const ASTNode& form1,
-                         const ASTNode& form2);
-    ASTNode CreateSimpXor(ASTVec &children);
-    ASTNode CreateSimpAndOr(bool isAnd,
-                                    const ASTNode& form1,
-                                    const ASTNode& form2);
-    ASTNode CreateSimpAndOr(bool IsAnd, ASTVec &children);
-    ASTNode CreateSimpFormITE(const ASTNode& child0,
-                                      const ASTNode& child1,
-                                      const ASTNode& child2);
-    
-
-    // Declarations of BitBlaster functions (BitBlast.cpp)
-  public:
-    // Adds or removes a NOT as necessary to negate a literal.
-    ASTNode Negate(const ASTNode& form);
-
-    // Bit blast a bitvector term.  The term must have a kind for a
-    // bitvector term.  Result is a ref to a vector of formula nodes
-    // representing the boolean formula.
-    const ASTNode BBTerm(const ASTNode& term);
-
-    const ASTNode BBForm(const ASTNode& formula);
-
-    // Declarations of CNF conversion (ToCNF.cpp)
-  public:
-    // ToCNF converts a bit-blasted Boolean formula to Conjunctive
-    //         Normal Form, suitable for many SAT solvers.  Our CNF representation
-    //         is an STL vector of STL vectors, for independence from any particular
-    //         SAT solver's representation.  There needs to be a separate driver to
-    //         convert our clauselist to the representation used by the SAT solver.    
-    //         Currently, there is only one such solver and its driver is "ToSAT"
-    
-    // Datatype for clauses
-    typedef vector<const ASTNode*>* ClausePtr;
-    
-    // Datatype for Clauselists
-    typedef vector<ClausePtr> ClauseList;
-
-    // Convert a Boolean formula to an equisatisfiable CNF formula.
-    ClauseList *ToCNF(const ASTNode& form);
-
-    // Print function for debugging
-    void PrintClauseList(ostream& os, ClauseList& cll); 
-
-    // Free the clause list and all its clauses.
-    void DeleteClauseList(BeevMgr::ClauseList *cllp);
-
-    // Map from formulas to representative literals, for debugging.
-    ASTNodeMap RepLitMap;
-
-  private:
-    // Global for assigning new node numbers.
-    int _max_node_num;
-    
-    const ASTNode ASTFalse, ASTTrue, ASTUndefined;
-    
-    // I just did this so I could put it in as a fake return value in
-    // methods that return a ASTNode &, to make -Wall shut up.
-    ASTNode dummy_node;
-
-    //BeevMgr Constructor, Destructor and other misc. functions
-  public:
-
-    int NewNodeNum() { _max_node_num += 2; return _max_node_num; } 
-    
-    // Table for DAG printing.
-    ASTNodeSet AlreadyPrintedSet;
-
-    //Tables for Presentation language printing
-
-    //Nodes seen so far
-    ASTNodeSet PLPrintNodeSet;
-
-    //Map from ASTNodes to LetVars
-    ASTNodeMap NodeLetVarMap;
-    
-    //This is a vector which stores the Node to LetVars pairs. It
-    //allows for sorted printing, as opposed to NodeLetVarMap
-    std::vector<pair<ASTNode,ASTNode> > NodeLetVarVec;
-
-    //a partial Map from ASTNodes to LetVars. Needed in order to
-    //correctly print shared subterms inside the LET itself
-    ASTNodeMap NodeLetVarMap1;
-
-    //functions to lookup nodes from the memo tables. these should be
-    //private.
-  private:
-    //Destructively appends back_child nodes to front_child nodes.
-    //If back_child nodes is NULL, no appending is done.  back_child
-    //nodes are not modified.  Then it returns the hashed copy of the
-    //node, which is created if necessary.
-    ASTInterior *CreateInteriorNode(Kind kind,
-                                   ASTInterior *new_node,
-                                   // this is destructively modified.
-                                   const ASTVec & back_children = _empty_ASTVec);
-
-    // Create unique ASTInterior node.
-    ASTInterior *LookupOrCreateInterior(ASTInterior *n);
-
-    // Create unique ASTSymbol node. 
-    ASTSymbol *LookupOrCreateSymbol(ASTSymbol& s);
-    
-    // Called whenever we want to make sure that the Symbol is
-    // declared during semantic analysis
-    bool LookupSymbol(ASTSymbol& s);
-      
-    // Called by ASTNode constructors to uniqueify ASTBVConst
-    ASTBVConst *LookupOrCreateBVConst(ASTBVConst& s);
-
-    //Public functions for CreateNodes and Createterms
-  public:
-    // Create and return an ASTNode for a symbol
-    ASTNode CreateSymbol(const char * const name);
-
-    // Create and return an ASTNode for a symbol
-    // Width is number of bits.
-    ASTNode CreateBVConst(string*& strval, int base,  int bit_width);
-    ASTNode CreateBVConst(unsigned int width, unsigned long long int bvconst);
-    ASTNode CreateZeroConst(unsigned int width);
-    ASTNode CreateOneConst(unsigned int width);
-    ASTNode CreateTwoConst(unsigned int width);
-    ASTNode CreateMaxConst(unsigned int width);
-
-
-    // Create and return an ASTNode for a symbol
-    // Optional base was a problem because 0 could be an int or char *,
-    // so CreateBVConst was ambiguous.
-    ASTNode CreateBVConst(const char *strval, int base);
-
-    //FIXME This is a dangerous function 
-    ASTNode CreateBVConst(CBV bv, unsigned width);
-
-    // Create and return an interior ASTNode
-    ASTNode CreateNode(Kind kind, const ASTVec &children = _empty_ASTVec);
-
-    ASTNode CreateNode(Kind kind,
-                      const ASTNode& child0,
-                      const ASTVec &children = _empty_ASTVec);
-
-    ASTNode CreateNode(Kind kind,
-                      const ASTNode& child0,
-                      const ASTNode& child1,
-                      const ASTVec &children = _empty_ASTVec);    
-
-    ASTNode CreateNode(Kind kind,
-                      const ASTNode& child0,
-                      const ASTNode& child1,
-                      const ASTNode& child2,
-                      const ASTVec &children = _empty_ASTVec);
-
-    // Create and return an ASTNode for a term
-    inline ASTNode CreateTerm(Kind kind, 
-                      unsigned int width, 
-                      const ASTVec &children = _empty_ASTVec) {
-      if(!is_Term_kind(kind))
-       FatalError("CreateTerm:  Illegal kind to CreateTerm:",ASTUndefined, kind);
-      ASTNode n = CreateNode(kind, children);
-      n.SetValueWidth(width);
-
-      //by default we assume that the term is a Bitvector. If
-      //necessary the indexwidth can be changed later
-      n.SetIndexWidth(0);
-      return n;
-    }
-
-    inline ASTNode CreateTerm(Kind kind,
-                      unsigned int width,
-                      const ASTNode& child0,
-                      const ASTVec &children = _empty_ASTVec) {
-      if(!is_Term_kind(kind))
-       FatalError("CreateTerm:  Illegal kind to CreateTerm:",ASTUndefined, kind);
-      ASTNode n = CreateNode(kind, child0, children);
-      n.SetValueWidth(width);
-      return n;
-    }
-     
-    inline ASTNode CreateTerm(Kind kind,
-                      unsigned int width,
-                      const ASTNode& child0,
-                      const ASTNode& child1,
-                      const ASTVec &children = _empty_ASTVec) {
-      if(!is_Term_kind(kind))
-       FatalError("CreateTerm:  Illegal kind to CreateTerm:",ASTUndefined, kind);
-      ASTNode n = CreateNode(kind, child0, child1, children);
-      n.SetValueWidth(width);
-      return n;
-    }
-
-    inline ASTNode CreateTerm(Kind kind,
-                      unsigned int width,
-                      const ASTNode& child0,
-                      const ASTNode& child1,
-                      const ASTNode& child2,
-                      const ASTVec &children = _empty_ASTVec) {
-      if(!is_Term_kind(kind))
-       FatalError("CreateTerm:  Illegal kind to CreateTerm:",ASTUndefined, kind);
-      ASTNode n = CreateNode(kind, child0, child1, child2, children);
-      n.SetValueWidth(width);
-      return n;
-    }
-
-    ASTNode SimplifyFormula_NoRemoveWrites(const ASTNode& a, bool pushNeg);
-    ASTNode SimplifyFormula_TopLevel(const ASTNode& a, bool pushNeg);
-    ASTNode SimplifyFormula(const ASTNode& a, bool pushNeg);
-    ASTNode SimplifyTerm_TopLevel(const ASTNode& b);
-    ASTNode SimplifyTerm(const ASTNode& a);
-    ASTNode SimplifyTermAux(const ASTNode& a);
-    void CheckSimplifyInvariant(const ASTNode& a, const ASTNode& output);    
-  private:
-    //memo table for simplifcation
-    ASTNodeMap *SimplifyMap;
-    ASTNodeMap *SimplifyNegMap;
-    ASTNodeMap SolverMap;
-    ASTNodeSet AlwaysTrueFormMap;
-    ASTNodeMap MultInverseMap;
-
-  public:
-    ASTNode SimplifyAtomicFormula(const ASTNode& a, bool pushNeg);
-    ASTNode CreateSimplifiedEQ(const ASTNode& t1, const ASTNode& t2);
-    ASTNode ITEOpt_InEqs(const ASTNode& in1);
-    ASTNode CreateSimplifiedTermITE(const ASTNode& t1, const ASTNode& t2, const ASTNode& t3);
-    ASTNode CreateSimplifiedFormulaITE(const ASTNode& in0, const ASTNode& in1, const ASTNode& in2);
-    ASTNode CreateSimplifiedINEQ(Kind k, const ASTNode& a0, const ASTNode& a1, bool pushNeg);
-    ASTNode SimplifyNotFormula(const ASTNode& a, bool pushNeg);
-    ASTNode SimplifyAndOrFormula(const ASTNode& a, bool pushNeg);
-    ASTNode SimplifyXorFormula(const ASTNode& a, bool pushNeg);
-    ASTNode SimplifyNandFormula(const ASTNode& a, bool pushNeg);
-    ASTNode SimplifyNorFormula(const ASTNode& a, bool pushNeg);
-    ASTNode SimplifyImpliesFormula(const ASTNode& a, bool pushNeg);
-    ASTNode SimplifyIffFormula(const ASTNode& a, bool pushNeg);
-    ASTNode SimplifyIteFormula(const ASTNode& a, bool pushNeg);
-    ASTNode FlattenOneLevel(const ASTNode& a);
-    ASTNode FlattenAndOr(const ASTNode& a);
-    ASTNode CombineLikeTerms(const ASTNode& a);
-    ASTNode LhsMinusRhs(const ASTNode& eq);
-    ASTNode DistributeMultOverPlus(const ASTNode& a, 
-                                  bool startdistribution=false);
-    ASTNode ConvertBVSXToITE(const ASTNode& a);
-    //checks if the input constant is odd or not
-    bool BVConstIsOdd(const ASTNode& c);
-    //computes the multiplicatve inverse of the input
-    ASTNode MultiplicativeInverse(const ASTNode& c);
-    void ClearAllTables(void);
-    void ClearAllCaches(void);
-    int  BeforeSAT_ResultCheck(const ASTNode& q);
-    int  CallSAT_ResultCheck(MINISAT::Solver& newS, 
-                            const ASTNode& q, const ASTNode& orig_input);   
-    int  SATBased_ArrayReadRefinement(MINISAT::Solver& newS, 
-                                     const ASTNode& q, const ASTNode& orig_input);
-    int SATBased_ArrayWriteRefinement(MINISAT::Solver& newS, const ASTNode& orig_input);
-    //creates array write axiom only for the input term or formula, if
-    //necessary. If there are no axioms to produce then it simply
-    //generates TRUE
-    ASTNode Create_ArrayWriteAxioms(const ASTNode& array_readoverwrite_term, const ASTNode& array_newname);
-    ASTVec ArrayWrite_RemainingAxioms;
-    //variable indicates that counterexample will now be checked by
-    //the counterexample checker, and hence simplifyterm must switch
-    //off certain optimizations. In particular, array write
-    //optimizations
-    bool start_abstracting;
-    bool Begin_RemoveWrites;
-    bool SimplifyWrites_InPlace_Flag;
-
-    void CopySolverMap_To_CounterExample(void);
-    //int LinearSearch(const ASTNode& orig_input);    
-    //Datastructures and functions needed for counterexample
-    //generation, and interface with MINISAT
-  private:
-    /* MAP: This is a map from ASTNodes to MINISAT::Vars. 
-     *
-     * The map is populated while ASTclauses are read from the AST
-     * ClauseList returned by CNF converter. For every new boolean
-     * variable in ASTClause a new MINISAT::Var is created (these vars
-     * typedefs for ints)
-     */
-    typedef hash_map<ASTNode, MINISAT::Var, 
-                    ASTNode::ASTNodeHasher, 
-                    ASTNode::ASTNodeEqual> ASTtoSATMap;        
-    ASTtoSATMap _ASTNode_to_SATVar;
-
-
-  public:  
-    //converts the clause to SAT and calls SAT solver
-    bool toSATandSolve(MINISAT::Solver& S, ClauseList& cll);
-
-    ///print SAT solver statistics
-    void PrintStats(MINISAT::Solver& stats);
-
-      //from v8
-    int TopLevelSATAux(const ASTNode& query);
-
-    //##################################################
-    //##################################################
-
-    //accepts query and returns the answer. if query is valid, return
-    //true, else return false. Automatically constructs counterexample
-    //for invalid queries, and prints them upon request.
-    int TopLevelSAT(const ASTNode& query, const ASTNode& asserts);
-
-    // Debugging function to find problems in BitBlast and ToCNF.
-    // See body in ToSAT.cpp for more explanation.
-    ASTNode CheckBBandCNF(MINISAT::Solver& newS, ASTNode form);
-
-    // Internal recursive body of above.
-    ASTNode CheckBBandCNF_int(MINISAT::Solver& newS, ASTNode form);
-
-    // Helper function for CheckBBandCNF
-    ASTNode SymbolTruthValue(MINISAT::Solver &newS, ASTNode form); 
-
-    //looksup a MINISAT var from the minisat-var memo-table. if none
-    //exists, then creates one.
-    const MINISAT::Var LookupOrCreateSATVar(MINISAT::Solver& S, const ASTNode& n);
-
-    // Memo table for CheckBBandCNF debugging function
-    ASTNodeMap CheckBBandCNFMemo;
-
-
-    //Data structures for Array Read Transformations
-  private:
-    /* MAP: This is a map from Array Names to list of array-read
-     * indices in the input. This map is used by the TransformArray()
-     * function
-     *
-     * This map is useful in converting array reads into nested ITE
-     * constructs. Suppose there are two array reads in the input
-     * Read(A,i) and Read(A,j). Then Read(A,i) is replaced with a
-     * symbolic constant, say v1, and Read(A,j) is replaced with the
-     * following ITE:
-     *
-     * ITE(i=j,v1,v2)
-     */
-    //CAUTION: I tried using a set instead of vector for
-    //readindicies. for some odd reason the performance went down
-    //considerably. this is totally inexplicable.
-    ASTNodeToVecMap _arrayname_readindices;
-        
-    /* MAP: This is a map from Array Names to nested ITE constructs,
-     * which are built as described below. This map is used by the
-     * TransformArray() function
-     *
-     * This map is useful in converting array reads into nested ITE
-     * constructs. Suppose there are two array reads in the input
-     * Read(A,i) and Read(A,j). Then Read(A,i) is replaced with a
-     * symbolic constant, say v1, and Read(A,j) is replaced with the
-     * following ITE:
-     *
-     * ITE(i=j,v1,v2)
-     */
-    ASTNodeMap _arrayread_ite;
-
-    /*MAP: This is a map from array-reads to symbolic constants. This
-     *map is used by the TransformArray()
-     */
-    ASTNodeMap _arrayread_symbol;
-
-    ASTNodeSet _introduced_symbols;
-
-    /*Memoization map for TransformFormula/TransformTerm/TransformArray function
-     */
-    ASTNodeMap TransformMap;
-    
-    //count to keep track of new symbolic constants introduced
-    //corresponding to Array Reads
-    unsigned int _symbol_count;
-
-    //Formula/Term Transformers. Let Expr Manager, Type Checker
-  public:
-    //Functions that Transform ASTNodes
-    ASTNode TransformFormula(const ASTNode& query);
-    ASTNode TransformTerm(const ASTNode& term);
-    ASTNode TransformArray(const ASTNode& term);
-    ASTNode TranslateSignedDivMod(const ASTNode& term);
-
-    //LET Management
-  private:
-    // MAP: This map is from bound IDs that occur in LETs to
-    // expression. The map is useful in checking replacing the IDs
-    // with the corresponding expressions.
-    ASTNodeMap *_letid_expr_map;
-  public:
-
-    ASTNode ResolveID(const ASTNode& var);
-
-    //Functions that are used to manage LET expressions
-    void LetExprMgr(const ASTNode& var, const ASTNode& letExpr);
-
-    //Delete Letid Map
-    void CleanupLetIDMap(void);
-
-    //Allocate LetID map
-    void InitializeLetIDMap(void);
-
-    //Substitute Let-vars with LetExprs
-    ASTNode SubstituteLetExpr(ASTNode inExpr);
-
-    /* MAP: This is a map from MINISAT::Vars to ASTNodes
-     *
-     * This is a reverse map, useful in constructing
-     * counterexamples. MINISAT returns a model in terms of MINISAT
-     * Vars, and this map helps us convert it to a model over ASTNode
-     * variables.
-     */    
-    vector<ASTNode> _SATVar_to_AST;
-
-  private:        
-    /* MAP: This is a map from ASTNodes to vectors of bits
-     *
-     * This map is used in constructing and printing
-     * counterexamples. MINISAT returns values for each bit (a
-     * BVGETBIT Node), and this maps allows us to assemble the bits
-     * into bitvectors.
-     */    
-    typedef hash_map<ASTNode, hash_map<unsigned int, bool> *, 
-                    ASTNode::ASTNodeHasher, 
-                    ASTNode::ASTNodeEqual> ASTtoBitvectorMap;        
-    ASTtoBitvectorMap _ASTNode_to_Bitvector;
-
-    //Data structure that holds the counter-model
-    ASTNodeMap CounterExampleMap;
-
-    //Checks if the counter_example is ok. In order for the
-    //counter_example to be ok, Every assert must evaluate to true 
-    //w.r.t couner_example and the query must evaluate to
-    //false. Otherwise the counter_example is bogus.
-    void CheckCounterExample(bool t);    
-
-    //Converts a vector of bools to a BVConst
-    ASTNode BoolVectoBVConst(hash_map<unsigned,bool> * w, unsigned int l);
-
-    //accepts a term and turns it into a constant-term w.r.t counter_example 
-    ASTNode TermToConstTermUsingModel(const ASTNode& term, bool ArrayReadFlag = true);
-    ASTNode Expand_ReadOverWrite_UsingModel(const ASTNode& term, bool ArrayReadFlag = true);
-    //Computes the truth value of a formula w.r.t counter_example
-    ASTNode ComputeFormulaUsingModel(const ASTNode& form);
-
-    //Replaces WRITE(Arr,i,val) with ITE(j=i, val, READ(Arr,j))
-    ASTNode RemoveWrites_TopLevel(const ASTNode& term);
-    ASTNode RemoveWrites(const ASTNode& term);
-    ASTNode SimplifyWrites_InPlace(const ASTNode& term);
-    ASTNode ReadOverWrite_To_ITE(const ASTNode& term);
-
-    ASTNode NewArrayVar(unsigned int index, unsigned int value);
-    ASTNode NewVar(unsigned int valuewidth);
-    //For ArrayWrite Abstraction: map from read-over-write term to
-    //newname.
-    ASTNodeMap ReadOverWrite_NewName_Map;
-    //For ArrayWrite Refinement: Map new arraynames to Read-Over-Write
-    //terms
-    ASTNodeMap NewName_ReadOverWrite_Map;
-    
-  public:
-    //print the STP solver output
-    void PrintOutput(bool true_iff_valid);
-
-    //Converts MINISAT counterexample into an AST memotable (i.e. the
-    //function populates the datastructure CounterExampleMap)
-    void ConstructCounterExample(MINISAT::Solver& S);
-
-    //Prints the counterexample to stdout
-    void PrintCounterExample(bool t,std::ostream& os=cout);
-
-    //Prints the counterexample to stdout
-    void PrintCounterExample_InOrder(bool t);
-
-    //queries the counterexample, and returns the value corresponding
-    //to e
-    ASTNode GetCounterExample(bool t, const ASTNode& e);
-
-    int CounterExampleSize(void) const {return CounterExampleMap.size();}
-
-    //FIXME: This is bloody dangerous function. Hack attack to take
-    //care of requests from users who want to store complete
-    //counter-examples in their own data structures.
-    ASTNodeMap GetCompleteCounterExample() {return CounterExampleMap;}
-
-    // prints MINISAT assigment one bit at a time, for debugging.
-    void PrintSATModel(MINISAT::Solver& S);
-
-    //accepts constant input and normalizes it. 
-    ASTNode BVConstEvaluator(const ASTNode& t);
-
-    //FUNCTION TypeChecker: Assumes that the immediate Children of the
-    //input ASTNode have been typechecked. This function is suitable
-    //in scenarios like where you are building the ASTNode Tree, and
-    //you typecheck as you go along. It is not suitable as a general
-    //typechecker
-    void BVTypeCheck(const ASTNode& n);
-    
-  private:
-    //stack of Logical Context. each entry in the stack is a logical
-    //context. A logical context is a vector of assertions. The
-    //logical context is represented by a ptr to a vector of
-    //assertions in that logical context. Logical contexts are created
-    //by PUSH/POP
-    std::vector<ASTVec *>  _asserts;
-    //The query for the current logical context.
-    ASTNode _current_query;
-
-    //this flag, when true, indicates that counterexample is being
-    //checked by the counterexample checker
-    bool counterexample_checking_during_refinement;
-
-    //this flag indicates as to whether the input has been determined to
-    //be valid or not by this tool
-    bool ValidFlag;
-
-    //this flag, when true, indicates that a BVDIV divide by zero
-    //exception occured. However, the program must not exit with a
-    //fatalerror. Instead, it should evaluate the whole formula (which
-    //contains the BVDIV term) to be FALSE.
-    bool bvdiv_exception_occured;
-
-  public:
-    //set of functions that manipulate Logical Contexts.
-    //
-    //add an assertion to the current logical context
-    void AddAssert(const ASTNode& assert);
-    void Push(void);
-    void Pop(void);
-    void AddQuery(const ASTNode& q);    
-    const ASTNode PopQuery();
-    const ASTNode GetQuery();
-    const ASTVec GetAsserts(void);
-
-    //reports node size.  Second arg is "clearstatinfo", whatever that is.
-    unsigned int NodeSize(const ASTNode& a, bool t = false);
-
-  private:
-    //This memo map is used by the ComputeFormulaUsingModel()
-    ASTNodeMap ComputeFormulaMap;
-    //Map for statiscal purposes
-    ASTNodeSet StatInfoSet;
-
-
-    ASTNodeMap TermsAlreadySeenMap;
-    ASTNode CreateSubstitutionMap(const ASTNode& a);
-  public:
-    //prints statistics for the ASTNode. can add a prefix string c
-    void ASTNodeStats(const char * c, const ASTNode& a);
-
-    //substitution
-    bool CheckSubstitutionMap(const ASTNode& a, ASTNode& output);  
-    bool CheckSubstitutionMap(const ASTNode& a);
-    bool UpdateSubstitutionMap(const ASTNode& e0, const ASTNode& e1);
-    //if (a > b) in the termorder, then return 1
-    //elseif (a < b) in the termorder, then return -1
-    //else return 0
-    int TermOrder(const ASTNode& a, const ASTNode& b);
-    //fill the arrayname_readindices vector if e0 is a READ(Arr,index)
-    //and index is a BVCONST
-    void FillUp_ArrReadIndex_Vec(const ASTNode& e0, const ASTNode& e1);
-    bool VarSeenInTerm(const ASTNode& var, const ASTNode& term);
-
-    //functions for checking and updating simplifcation map
-    bool CheckSimplifyMap(const ASTNode& key, ASTNode& output, bool pushNeg);
-    void UpdateSimplifyMap(const ASTNode& key, const ASTNode& value, bool pushNeg);
-    void ResetSimplifyMaps();
-    bool CheckAlwaysTrueFormMap(const ASTNode& key);
-    void UpdateAlwaysTrueFormMap(const ASTNode& val);
-    bool CheckMultInverseMap(const ASTNode& key, ASTNode& output);
-    void UpdateMultInverseMap(const ASTNode& key, const ASTNode& value);
-
-    //Map for solved variables
-    bool CheckSolverMap(const ASTNode& a, ASTNode& output);
-    bool CheckSolverMap(const ASTNode& a);
-    bool UpdateSolverMap(const ASTNode& e0, const ASTNode& e1);
-
-  public:
-    //FIXME: HACK_ATTACK. this vector was hacked into the code to
-    //support a special request by Dawson' group. They want the
-    //counterexample to be printed in the order of variables declared.
-    //TO BE COMMENTED LATER (say by 1st week of march,2006)
-    ASTVec _special_print_set;
-
-
-    //prints the initial activity levels of variables
-    //void PrintActivityLevels_Of_SATVars(char * init_msg, MINISAT::Solver& newS);
-
-    //this function biases the activity levels of MINISAT variables.
-    //void ChangeActivityLevels_Of_SATVars(MINISAT::Solver& n);
-
-    // Constructor
-    BeevMgr() : _interior_unique_table(INITIAL_INTERIOR_UNIQUE_TABLE_SIZE),
-               _symbol_unique_table(INITIAL_SYMBOL_UNIQUE_TABLE_SIZE),
-               _bvconst_unique_table(INITIAL_BVCONST_UNIQUE_TABLE_SIZE),
-               BBTermMemo(INITIAL_BBTERM_MEMO_TABLE_SIZE),
-               BBFormMemo(INITIAL_BBFORM_MEMO_TABLE_SIZE),
-               _max_node_num(0),
-               ASTFalse(CreateNode(FALSE)),
-               ASTTrue(CreateNode(TRUE)),
-               ASTUndefined(CreateNode(UNDEFINED)),
-               SolverMap(INITIAL_SOLVER_MAP_SIZE),
-               _arrayread_symbol(INITIAL_ARRAYREAD_SYMBOL_SIZE),
-               _introduced_symbols(INITIAL_INTRODUCED_SYMBOLS_SIZE),
-               _symbol_count(0) { 
-      _current_query = ASTUndefined;
-      ValidFlag = false;
-      bvdiv_exception_occured = false;
-      counterexample_checking_during_refinement = false;
-      start_abstracting = false;
-      Begin_RemoveWrites = false;
-      SimplifyWrites_InPlace_Flag = false;
-      SimplifyMap = new ASTNodeMap(INITIAL_SIMPLIFY_MAP_SIZE);
-      SimplifyNegMap = new ASTNodeMap(INITIAL_SIMPLIFY_MAP_SIZE);
-      _letid_expr_map = new ASTNodeMap(INITIAL_INTRODUCED_SYMBOLS_SIZE);
-    };
-    
-    //destructor
-    ~BeevMgr();
-  }; //End of Class BeevMgr
-
-
-  class CompleteCounterExample {
-    ASTNodeMap counterexample;
-    BeevMgr * bv;
-  public:
-    CompleteCounterExample(ASTNodeMap a, BeevMgr* beev) : counterexample(a), bv(beev){} 
-    ASTNode GetCounterExample(ASTNode e) {
-      if(BOOLEAN_TYPE == e.GetType() && SYMBOL != e.GetKind()) {
-       FatalError("You must input a term or propositional variables\n",e);
-      }
-      if(counterexample.find(e) != counterexample.end()) {
-       return counterexample[e];
-      }
-      else {
-       if(SYMBOL == e.GetKind() && BOOLEAN_TYPE == e.GetType()) {
-         return bv->CreateNode(BEEV::FALSE);
+private:
+       // Typedef for unique Interior node table.
+       typedef hash_set<ASTInterior *, ASTInterior::ASTInteriorHasher, ASTInterior::ASTInteriorEqual> ASTInteriorSet;
+
+       // Typedef for unique Symbol node (leaf) table.
+       typedef hash_set<ASTSymbol *, ASTSymbol::ASTSymbolHasher, ASTSymbol::ASTSymbolEqual> ASTSymbolSet;
+
+       // Unique tables to share nodes whenever possible.
+       ASTInteriorSet _interior_unique_table;
+       //The _symbol_unique_table is also the symbol table to be used
+       //during parsing/semantic analysis
+       ASTSymbolSet _symbol_unique_table;
+
+       //Typedef for unique BVConst node (leaf) table.
+       typedef hash_set<ASTBVConst *, ASTBVConst::ASTBVConstHasher, ASTBVConst::ASTBVConstEqual> ASTBVConstSet;
+
+       //table to uniquefy bvconst
+       ASTBVConstSet _bvconst_unique_table;
+
+       // type of memo table.
+       typedef hash_map<ASTNode, ASTVec, ASTNode::ASTNodeHasher, ASTNode::ASTNodeEqual> ASTNodeToVecMap;
+
+       typedef hash_map<ASTNode, ASTNodeSet, ASTNode::ASTNodeHasher, ASTNode::ASTNodeEqual> ASTNodeToSetMap;
+
+       // Memo table for bit blasted terms.  If a node has already been
+       // bitblasted, it is mapped to a vector of Boolean formulas for
+       // the bits.
+
+       //OLD: ASTNodeToVecMap BBTermMemo;
+       ASTNodeMap BBTermMemo;
+
+       // Memo table for bit blasted formulas.  If a node has already
+       // been bitblasted, it is mapped to a node representing the
+       // bitblasted equivalent
+       ASTNodeMap BBFormMemo;
+
+       //public:
+       // Get vector of Boolean formulas for sum of two
+       // vectors of Boolean formulas
+       void BBPlus2(ASTVec& sum, const ASTVec& y, ASTNode cin);
+       // Increment
+       ASTVec BBInc(ASTVec& x);
+       // Add one bit to a vector of bits.
+       ASTVec BBAddOneBit(ASTVec& x, ASTNode cin);
+       // Bitwise complement
+       ASTVec BBNeg(const ASTVec& x);
+       // Unary minus
+       ASTVec BBUminus(const ASTVec& x);
+       // Multiply.
+       ASTVec BBMult(const ASTVec& x, const ASTVec& y);
+       // AND each bit of vector y with single bit b and return the result.
+       // (used in BBMult)
+       ASTVec BBAndBit(const ASTVec& y, ASTNode b);
+       // Returns ASTVec for result - y.  This destroys "result".
+       void BBSub(ASTVec& result, const ASTVec& y);
+       // build ITE's (ITE cond then[i] else[i]) for each i.
+       ASTVec BBITE(const ASTNode& cond, const ASTVec& thn, const ASTVec& els);
+       // Build a vector of zeros.
+       ASTVec BBfill(unsigned int width, ASTNode fillval);
+       // build an EQ formula
+       ASTNode BBEQ(const ASTVec& left, const ASTVec& right);
+
+       // This implements a variant of binary long division.
+       // q and r are "out" parameters.  rwidth puts a bound on the
+       // recursion depth.   Unsigned only, for now.
+       void BBDivMod(const ASTVec &y, const ASTVec &x, ASTVec &q, ASTVec &r, unsigned int rwidth);
+
+       // Return formula for majority function of three formulas.
+       ASTNode Majority(const ASTNode& a, const ASTNode& b, const ASTNode& c);
+
+       // Internal bit blasting routines.
+       ASTNode BBBVLE(const ASTVec& x, const ASTVec& y, bool is_signed);
+
+       // Return bit-blasted form for BVLE, BVGE, BVGT, SBLE, etc.
+       ASTNode BBcompare(const ASTNode& form);
+
+       // Left and right shift one.  Writes into x.
+       void BBLShift(ASTVec& x);
+       void BBRShift(ASTVec& x);
+
+       void BBLShift(ASTVec& x, unsigned int shift);
+       void BBRShift(ASTVec& x, unsigned int shift);
+
+public:
+       // Simplifying create functions
+       ASTNode CreateSimpForm(Kind kind, ASTVec &children);
+       ASTNode CreateSimpForm(Kind kind, const ASTNode& child0);
+       ASTNode CreateSimpForm(Kind kind, const ASTNode& child0, const ASTNode& child1);
+       ASTNode CreateSimpForm(Kind kind, const ASTNode& child0, const ASTNode& child1, const ASTNode& child2);
+
+       ASTNode CreateSimpNot(const ASTNode& form);
+
+       // These are for internal use only.
+       // FIXME: Find a way to make this local to SimpBool, so they're
+       // not in AST.h
+       ASTNode CreateSimpXor(const ASTNode& form1, const ASTNode& form2);
+       ASTNode CreateSimpXor(ASTVec &children);
+       ASTNode CreateSimpAndOr(bool isAnd, const ASTNode& form1, const ASTNode& form2);
+       ASTNode CreateSimpAndOr(bool IsAnd, ASTVec &children);
+       ASTNode CreateSimpFormITE(const ASTNode& child0, const ASTNode& child1, const ASTNode& child2);
+
+       // Declarations of BitBlaster functions (BitBlast.cpp)
+public:
+       // Adds or removes a NOT as necessary to negate a literal.
+       ASTNode Negate(const ASTNode& form);
+
+       // Bit blast a bitvector term.  The term must have a kind for a
+       // bitvector term.  Result is a ref to a vector of formula nodes
+       // representing the boolean formula.
+       const ASTNode BBTerm(const ASTNode& term);
+
+       const ASTNode BBForm(const ASTNode& formula);
+
+       // Declarations of CNF conversion (ToCNF.cpp)
+public:
+       // ToCNF converts a bit-blasted Boolean formula to Conjunctive
+       //      Normal Form, suitable for many SAT solvers.  Our CNF representation
+       //      is an STL vector of STL vectors, for independence from any particular
+       //      SAT solver's representation.  There needs to be a separate driver to
+       //      convert our clauselist to the representation used by the SAT solver.
+       //      Currently, there is only one such solver and its driver is "ToSAT"
+
+       // Datatype for clauses
+       typedef vector<const ASTNode*>* ClausePtr;
+
+       // Datatype for Clauselists
+       typedef vector<ClausePtr> ClauseList;
+
+       // Convert a Boolean formula to an equisatisfiable CNF formula.
+       ClauseList *ToCNF(const ASTNode& form);
+
+       // Print function for debugging
+       void PrintClauseList(ostream& os, ClauseList& cll);
+
+       // Free the clause list and all its clauses.
+       void DeleteClauseList(BeevMgr::ClauseList *cllp);
+
+       // Map from formulas to representative literals, for debugging.
+       ASTNodeMap RepLitMap;
+
+private:
+       // Global for assigning new node numbers.
+       int _max_node_num;
+
+       const ASTNode ASTFalse, ASTTrue, ASTUndefined;
+
+       // I just did this so I could put it in as a fake return value in
+       // methods that return a ASTNode &, to make -Wall shut up.
+       ASTNode dummy_node;
+
+       //BeevMgr Constructor, Destructor and other misc. functions
+public:
+
+       int NewNodeNum()
+       {
+               _max_node_num += 2;
+               return _max_node_num;
        }
 
-       if(SYMBOL == e.GetKind()) {
-         ASTNode z = bv->CreateZeroConst(e.GetValueWidth());
-         return z;
+       // Table for DAG printing.
+       ASTNodeSet AlreadyPrintedSet;
+
+       //Tables for Presentation language printing
+
+       //Nodes seen so far
+       ASTNodeSet PLPrintNodeSet;
+
+       //Map from ASTNodes to LetVars
+       ASTNodeMap NodeLetVarMap;
+
+       //This is a vector which stores the Node to LetVars pairs. It
+       //allows for sorted printing, as opposed to NodeLetVarMap
+       std::vector<pair<ASTNode, ASTNode> > NodeLetVarVec;
+
+       //a partial Map from ASTNodes to LetVars. Needed in order to
+       //correctly print shared subterms inside the LET itself
+       ASTNodeMap NodeLetVarMap1;
+
+       //functions to lookup nodes from the memo tables. these should be
+       //private.
+private:
+       //Destructively appends back_child nodes to front_child nodes.
+       //If back_child nodes is NULL, no appending is done.  back_child
+       //nodes are not modified.  Then it returns the hashed copy of the
+       //node, which is created if necessary.
+       ASTInterior *CreateInteriorNode(Kind kind, ASTInterior *new_node,
+       // this is destructively modified.
+                       const ASTVec & back_children = _empty_ASTVec);
+
+       // Create unique ASTInterior node.
+       ASTInterior *LookupOrCreateInterior(ASTInterior *n);
+
+       // Create unique ASTSymbol node.
+       ASTSymbol *LookupOrCreateSymbol(ASTSymbol& s);
+
+       // Called whenever we want to make sure that the Symbol is
+       // declared during semantic analysis
+       bool LookupSymbol(ASTSymbol& s);
+
+       // Called by ASTNode constructors to uniqueify ASTBVConst
+       ASTBVConst *LookupOrCreateBVConst(ASTBVConst& s);
+
+       //Public functions for CreateNodes and Createterms
+public:
+       // Create and return an ASTNode for a symbol
+       ASTNode CreateSymbol(const char * const name);
+
+       // Create and return an ASTNode for a symbol
+       // Width is number of bits.
+       ASTNode CreateBVConst(string*& strval, int base, int bit_width);
+       ASTNode CreateBVConst(unsigned int width, unsigned long long int bvconst);
+       ASTNode CreateZeroConst(unsigned int width);
+       ASTNode CreateOneConst(unsigned int width);
+       ASTNode CreateTwoConst(unsigned int width);
+       ASTNode CreateMaxConst(unsigned int width);
+
+       // Create and return an ASTNode for a symbol
+       // Optional base was a problem because 0 could be an int or char *,
+       // so CreateBVConst was ambiguous.
+       ASTNode CreateBVConst(const char *strval, int base);
+
+       //FIXME This is a dangerous function
+       ASTNode CreateBVConst(CBV bv, unsigned width);
+
+       // Create and return an interior ASTNode
+       ASTNode CreateNode(Kind kind, const ASTVec &children = _empty_ASTVec);
+
+       ASTNode CreateNode(Kind kind, const ASTNode& child0, const ASTVec &children = _empty_ASTVec);
+
+       ASTNode CreateNode(Kind kind, const ASTNode& child0, const ASTNode& child1, const ASTVec &children = _empty_ASTVec);
+
+       ASTNode CreateNode(Kind kind, const ASTNode& child0, const ASTNode& child1, const ASTNode& child2, const ASTVec &children = _empty_ASTVec);
+
+       // Create and return an ASTNode for a term
+       inline ASTNode CreateTerm(Kind kind, unsigned int width, const ASTVec &children = _empty_ASTVec)
+       {
+               if (!is_Term_kind(kind))
+                       FatalError("CreateTerm:  Illegal kind to CreateTerm:", ASTUndefined, kind);
+               ASTNode n = CreateNode(kind, children);
+               n.SetValueWidth(width);
+
+               //by default we assume that the term is a Bitvector. If
+               //necessary the indexwidth can be changed later
+               n.SetIndexWidth(0);
+               return n;
+       }
+
+       inline ASTNode CreateTerm(Kind kind, unsigned int width, const ASTNode& child0, const ASTVec &children = _empty_ASTVec)
+       {
+               if (!is_Term_kind(kind))
+                       FatalError("CreateTerm:  Illegal kind to CreateTerm:", ASTUndefined, kind);
+               ASTNode n = CreateNode(kind, child0, children);
+               n.SetValueWidth(width);
+               return n;
+       }
+
+       inline ASTNode CreateTerm(Kind kind, unsigned int width, const ASTNode& child0, const ASTNode& child1, const ASTVec &children = _empty_ASTVec)
+       {
+               if (!is_Term_kind(kind))
+                       FatalError("CreateTerm:  Illegal kind to CreateTerm:", ASTUndefined, kind);
+               ASTNode n = CreateNode(kind, child0, child1, children);
+               n.SetValueWidth(width);
+               return n;
+       }
+
+       inline ASTNode CreateTerm(Kind kind,
+                       unsigned int width,
+                       const ASTNode& child0,
+                       const ASTNode& child1,
+                       const ASTNode& child2,
+                       const ASTVec &children = _empty_ASTVec)
+       {
+               if (!is_Term_kind(kind))
+                       FatalError("CreateTerm:  Illegal kind to CreateTerm:", ASTUndefined, kind);
+               ASTNode n = CreateNode(kind, child0, child1, child2, children);
+               n.SetValueWidth(width);
+               return n;
        }
 
-       return e;         
-      }
-    }
-  };
+       ASTNode SimplifyFormula_NoRemoveWrites(const ASTNode& a, bool pushNeg);
+       ASTNode SimplifyFormula_TopLevel(const ASTNode& a, bool pushNeg);
+       ASTNode SimplifyFormula(const ASTNode& a, bool pushNeg);
+       ASTNode SimplifyTerm_TopLevel(const ASTNode& b);
+       ASTNode SimplifyTerm(const ASTNode& a);
+       ASTNode SimplifyTermAux(const ASTNode& a);
+       void CheckSimplifyInvariant(const ASTNode& a, const ASTNode& output);
+private:
+       //memo table for simplifcation
+       ASTNodeMap *SimplifyMap;
+       ASTNodeMap *SimplifyNegMap;
+       ASTNodeMap SolverMap;
+       ASTNodeSet AlwaysTrueFormMap;
+       ASTNodeMap MultInverseMap;
+
+public:
+       ASTNode SimplifyAtomicFormula(const ASTNode& a, bool pushNeg);
+       ASTNode CreateSimplifiedEQ(const ASTNode& t1, const ASTNode& t2);
+       ASTNode ITEOpt_InEqs(const ASTNode& in1);
+       ASTNode CreateSimplifiedTermITE(const ASTNode& t1, const ASTNode& t2, const ASTNode& t3);
+       ASTNode CreateSimplifiedFormulaITE(const ASTNode& in0, const ASTNode& in1, const ASTNode& in2);
+       ASTNode CreateSimplifiedINEQ(Kind k, const ASTNode& a0, const ASTNode& a1, bool pushNeg);
+       ASTNode SimplifyNotFormula(const ASTNode& a, bool pushNeg);
+       ASTNode SimplifyAndOrFormula(const ASTNode& a, bool pushNeg);
+       ASTNode SimplifyXorFormula(const ASTNode& a, bool pushNeg);
+       ASTNode SimplifyNandFormula(const ASTNode& a, bool pushNeg);
+       ASTNode SimplifyNorFormula(const ASTNode& a, bool pushNeg);
+       ASTNode SimplifyImpliesFormula(const ASTNode& a, bool pushNeg);
+       ASTNode SimplifyIffFormula(const ASTNode& a, bool pushNeg);
+       ASTNode SimplifyIteFormula(const ASTNode& a, bool pushNeg);
+       ASTNode FlattenOneLevel(const ASTNode& a);
+       ASTNode FlattenAndOr(const ASTNode& a);
+       ASTNode CombineLikeTerms(const ASTNode& a);
+       ASTNode LhsMinusRhs(const ASTNode& eq);
+       ASTNode DistributeMultOverPlus(const ASTNode& a, bool startdistribution = false);
+       ASTNode ConvertBVSXToITE(const ASTNode& a);
+       //checks if the input constant is odd or not
+       bool BVConstIsOdd(const ASTNode& c);
+       //computes the multiplicatve inverse of the input
+       ASTNode MultiplicativeInverse(const ASTNode& c);
+
+       void ClearAllTables(void);
+       void ClearAllCaches(void);
+       int BeforeSAT_ResultCheck(const ASTNode& q);
+       int CallSAT_ResultCheck(MINISAT::Solver& newS, const ASTNode& q, const ASTNode& orig_input);
+       int SATBased_ArrayReadRefinement(MINISAT::Solver& newS, const ASTNode& q, const ASTNode& orig_input);
+       int SATBased_ArrayWriteRefinement(MINISAT::Solver& newS, const ASTNode& orig_input);
+       //creates array write axiom only for the input term or formula, if
+       //necessary. If there are no axioms to produce then it simply
+       //generates TRUE
+       ASTNode Create_ArrayWriteAxioms(const ASTNode& array_readoverwrite_term, const ASTNode& array_newname);
+       ASTVec ArrayWrite_RemainingAxioms;
+       //variable indicates that counterexample will now be checked by
+       //the counterexample checker, and hence simplifyterm must switch
+       //off certain optimizations. In particular, array write
+       //optimizations
+       bool start_abstracting;
+       bool Begin_RemoveWrites;
+       bool SimplifyWrites_InPlace_Flag;
+
+       void CopySolverMap_To_CounterExample(void);
+       //int LinearSearch(const ASTNode& orig_input);
+       //Datastructures and functions needed for counterexample
+       //generation, and interface with MINISAT
+private:
+       /* MAP: This is a map from ASTNodes to MINISAT::Vars.
+        *
+        * The map is populated while ASTclauses are read from the AST
+        * ClauseList returned by CNF converter. For every new boolean
+        * variable in ASTClause a new MINISAT::Var is created (these vars
+        * typedefs for ints)
+        */
+       typedef hash_map<ASTNode, MINISAT::Var, ASTNode::ASTNodeHasher, ASTNode::ASTNodeEqual> ASTtoSATMap;
+       ASTtoSATMap _ASTNode_to_SATVar;
+
+public:
+       //converts the clause to SAT and calls SAT solver
+       bool toSATandSolve(MINISAT::Solver& S, ClauseList& cll);
+
+       ///print SAT solver statistics
+       void PrintStats(MINISAT::Solver& stats);
+
+       //from v8
+       int TopLevelSATAux(const ASTNode& query);
+
+       //##################################################
+       //##################################################
+
+       //accepts query and returns the answer. if query is valid, return
+       //true, else return false. Automatically constructs counterexample
+       //for invalid queries, and prints them upon request.
+       int TopLevelSAT(const ASTNode& query, const ASTNode& asserts);
+
+       // Debugging function to find problems in BitBlast and ToCNF.
+       // See body in ToSAT.cpp for more explanation.
+       ASTNode CheckBBandCNF(MINISAT::Solver& newS, ASTNode form);
+
+       // Internal recursive body of above.
+       ASTNode CheckBBandCNF_int(MINISAT::Solver& newS, ASTNode form);
+
+       // Helper function for CheckBBandCNF
+       ASTNode SymbolTruthValue(MINISAT::Solver &newS, ASTNode form);
+
+       //looksup a MINISAT var from the minisat-var memo-table. if none
+       //exists, then creates one.
+       const MINISAT::Var LookupOrCreateSATVar(MINISAT::Solver& S, const ASTNode& n);
+
+       // Memo table for CheckBBandCNF debugging function
+       ASTNodeMap CheckBBandCNFMemo;
+
+       //Data structures for Array Read Transformations
+private:
+       /* MAP: This is a map from Array Names to list of array-read
+        * indices in the input. This map is used by the TransformArray()
+        * function
+        *
+        * This map is useful in converting array reads into nested ITE
+        * constructs. Suppose there are two array reads in the input
+        * Read(A,i) and Read(A,j). Then Read(A,i) is replaced with a
+        * symbolic constant, say v1, and Read(A,j) is replaced with the
+        * following ITE:
+        *
+        * ITE(i=j,v1,v2)
+        */
+       //CAUTION: I tried using a set instead of vector for
+       //readindicies. for some odd reason the performance went down
+       //considerably. this is totally inexplicable.
+       ASTNodeToVecMap _arrayname_readindices;
+
+       /* MAP: This is a map from Array Names to nested ITE constructs,
+        * which are built as described below. This map is used by the
+        * TransformArray() function
+        *
+        * This map is useful in converting array reads into nested ITE
+        * constructs. Suppose there are two array reads in the input
+        * Read(A,i) and Read(A,j). Then Read(A,i) is replaced with a
+        * symbolic constant, say v1, and Read(A,j) is replaced with the
+        * following ITE:
+        *
+        * ITE(i=j,v1,v2)
+        */
+       ASTNodeMap _arrayread_ite;
+
+       /*MAP: This is a map from array-reads to symbolic constants. This
+        *map is used by the TransformArray()
+        */
+       ASTNodeMap _arrayread_symbol;
+
+       ASTNodeSet _introduced_symbols;
+
+       /*Memoization map for TransformFormula/TransformTerm/TransformArray function
+        */
+       ASTNodeMap TransformMap;
+
+       //count to keep track of new symbolic constants introduced
+       //corresponding to Array Reads
+       unsigned int _symbol_count;
+
+       //Formula/Term Transformers. Let Expr Manager, Type Checker
+public:
+       //Functions that Transform ASTNodes
+       ASTNode TransformFormula(const ASTNode& query);
+       ASTNode TransformTerm(const ASTNode& term);
+       ASTNode TransformArray(const ASTNode& term);
+       ASTNode TranslateSignedDivMod(const ASTNode& term);
+
+       //LET Management
+private:
+       // MAP: This map is from bound IDs that occur in LETs to
+       // expression. The map is useful in checking replacing the IDs
+       // with the corresponding expressions.
+       ASTNodeMap *_letid_expr_map;
+public:
+
+       ASTNode ResolveID(const ASTNode& var);
+
+       //Functions that are used to manage LET expressions
+       void LetExprMgr(const ASTNode& var, const ASTNode& letExpr);
+
+       //Delete Letid Map
+       void CleanupLetIDMap(void);
+
+       //Allocate LetID map
+       void InitializeLetIDMap(void);
+
+       //Substitute Let-vars with LetExprs
+       ASTNode SubstituteLetExpr(ASTNode inExpr);
+
+       /* MAP: This is a map from MINISAT::Vars to ASTNodes
+        *
+        * This is a reverse map, useful in constructing
+        * counterexamples. MINISAT returns a model in terms of MINISAT
+        * Vars, and this map helps us convert it to a model over ASTNode
+        * variables.
+        */
+       vector<ASTNode> _SATVar_to_AST;
+
+private:
+       /* MAP: This is a map from ASTNodes to vectors of bits
+        *
+        * This map is used in constructing and printing
+        * counterexamples. MINISAT returns values for each bit (a
+        * BVGETBIT Node), and this maps allows us to assemble the bits
+        * into bitvectors.
+        */
+       typedef hash_map<ASTNode, hash_map<unsigned int, bool> *, ASTNode::ASTNodeHasher, ASTNode::ASTNodeEqual> ASTtoBitvectorMap;
+       ASTtoBitvectorMap _ASTNode_to_Bitvector;
+
+       //Data structure that holds the counter-model
+       ASTNodeMap CounterExampleMap;
+
+       //Checks if the counter_example is ok. In order for the
+       //counter_example to be ok, Every assert must evaluate to true
+       //w.r.t couner_example and the query must evaluate to
+       //false. Otherwise the counter_example is bogus.
+       void CheckCounterExample(bool t);
+
+       //Converts a vector of bools to a BVConst
+       ASTNode BoolVectoBVConst(hash_map<unsigned, bool> * w, unsigned int l);
+
+       //accepts a term and turns it into a constant-term w.r.t counter_example
+       ASTNode TermToConstTermUsingModel(const ASTNode& term, bool ArrayReadFlag = true);
+       ASTNode Expand_ReadOverWrite_UsingModel(const ASTNode& term, bool ArrayReadFlag = true);
+       //Computes the truth value of a formula w.r.t counter_example
+       ASTNode ComputeFormulaUsingModel(const ASTNode& form);
+
+       //Replaces WRITE(Arr,i,val) with ITE(j=i, val, READ(Arr,j))
+       ASTNode RemoveWrites_TopLevel(const ASTNode& term);
+       ASTNode RemoveWrites(const ASTNode& term);
+       ASTNode SimplifyWrites_InPlace(const ASTNode& term);
+       ASTNode ReadOverWrite_To_ITE(const ASTNode& term);
+
+       ASTNode NewArrayVar(unsigned int index, unsigned int value);
+       ASTNode NewVar(unsigned int valuewidth);
+       //For ArrayWrite Abstraction: map from read-over-write term to
+       //newname.
+       ASTNodeMap ReadOverWrite_NewName_Map;
+       //For ArrayWrite Refinement: Map new arraynames to Read-Over-Write
+       //terms
+       ASTNodeMap NewName_ReadOverWrite_Map;
+
+public:
+       //print the STP solver output
+       void PrintOutput(bool true_iff_valid);
+
+       //Converts MINISAT counterexample into an AST memotable (i.e. the
+       //function populates the datastructure CounterExampleMap)
+       void ConstructCounterExample(MINISAT::Solver& S);
+
+       //Prints the counterexample to stdout
+       void PrintCounterExample(bool t, std::ostream& os = cout);
+
+       //Prints the counterexample to stdout
+       void PrintCounterExample_InOrder(bool t);
+
+       //queries the counterexample, and returns the value corresponding
+       //to e
+       ASTNode GetCounterExample(bool t, const ASTNode& e);
+
+       int CounterExampleSize(void) const
+       {
+               return CounterExampleMap.size();
+       }
+
+       //FIXME: This is bloody dangerous function. Hack attack to take
+       //care of requests from users who want to store complete
+       //counter-examples in their own data structures.
+       ASTNodeMap GetCompleteCounterExample()
+       {
+               return CounterExampleMap;
+       }
+
+       // prints MINISAT assigment one bit at a time, for debugging.
+       void PrintSATModel(MINISAT::Solver& S);
+
+       //accepts constant input and normalizes it.
+       ASTNode BVConstEvaluator(const ASTNode& t);
+
+       //FUNCTION TypeChecker: Assumes that the immediate Children of the
+       //input ASTNode have been typechecked. This function is suitable
+       //in scenarios like where you are building the ASTNode Tree, and
+       //you typecheck as you go along. It is not suitable as a general
+       //typechecker
+       void BVTypeCheck(const ASTNode& n);
+
+private:
+       //stack of Logical Context. each entry in the stack is a logical
+       //context. A logical context is a vector of assertions. The
+       //logical context is represented by a ptr to a vector of
+       //assertions in that logical context. Logical contexts are created
+       //by PUSH/POP
+       std::vector<ASTVec *> _asserts;
+       //The query for the current logical context.
+       ASTNode _current_query;
+
+       //this flag, when true, indicates that counterexample is being
+       //checked by the counterexample checker
+       bool counterexample_checking_during_refinement;
+
+       //this flag indicates as to whether the input has been determined to
+       //be valid or not by this tool
+       bool ValidFlag;
+
+       //this flag, when true, indicates that a BVDIV divide by zero
+       //exception occured. However, the program must not exit with a
+       //fatalerror. Instead, it should evaluate the whole formula (which
+       //contains the BVDIV term) to be FALSE.
+       bool bvdiv_exception_occured;
+
+public:
+       //set of functions that manipulate Logical Contexts.
+       //
+       //add an assertion to the current logical context
+       void AddAssert(const ASTNode& assert);
+       void Push(void);
+       void Pop(void);
+       void AddQuery(const ASTNode& q);
+       const ASTNode PopQuery();
+       const ASTNode GetQuery();
+       const ASTVec GetAsserts(void);
+
+       //reports node size.  Second arg is "clearstatinfo", whatever that is.
+       unsigned int NodeSize(const ASTNode& a, bool t = false);
+
+private:
+       //This memo map is used by the ComputeFormulaUsingModel()
+       ASTNodeMap ComputeFormulaMap;
+       //Map for statiscal purposes
+       ASTNodeSet StatInfoSet;
+
+       ASTNodeMap TermsAlreadySeenMap;
+       ASTNode CreateSubstitutionMap(const ASTNode& a);
+public:
+       //prints statistics for the ASTNode. can add a prefix string c
+       void ASTNodeStats(const char * c, const ASTNode& a);
+
+       //substitution
+       bool CheckSubstitutionMap(const ASTNode& a, ASTNode& output);
+       bool CheckSubstitutionMap(const ASTNode& a);
+       bool UpdateSubstitutionMap(const ASTNode& e0, const ASTNode& e1);
+       //if (a > b) in the termorder, then return 1
+       //elseif (a < b) in the termorder, then return -1
+       //else return 0
+       int TermOrder(const ASTNode& a, const ASTNode& b);
+       //fill the arrayname_readindices vector if e0 is a READ(Arr,index)
+       //and index is a BVCONST
+       void FillUp_ArrReadIndex_Vec(const ASTNode& e0, const ASTNode& e1);
+       bool VarSeenInTerm(const ASTNode& var, const ASTNode& term);
+
+       //functions for checking and updating simplifcation map
+       bool CheckSimplifyMap(const ASTNode& key, ASTNode& output, bool pushNeg);
+       void UpdateSimplifyMap(const ASTNode& key, const ASTNode& value, bool pushNeg);
+       void ResetSimplifyMaps();
+       bool CheckAlwaysTrueFormMap(const ASTNode& key);
+       void UpdateAlwaysTrueFormMap(const ASTNode& val);
+       bool CheckMultInverseMap(const ASTNode& key, ASTNode& output);
+       void UpdateMultInverseMap(const ASTNode& key, const ASTNode& value);
+
+       //Map for solved variables
+       bool CheckSolverMap(const ASTNode& a, ASTNode& output);
+       bool CheckSolverMap(const ASTNode& a);
+       bool UpdateSolverMap(const ASTNode& e0, const ASTNode& e1);
+
+public:
+       //FIXME: HACK_ATTACK. this vector was hacked into the code to
+       //support a special request by Dawson' group. They want the
+       //counterexample to be printed in the order of variables declared.
+       //TO BE COMMENTED LATER (say by 1st week of march,2006)
+       ASTVec _special_print_set;
+
+       //prints the initial activity levels of variables
+       //void PrintActivityLevels_Of_SATVars(char * init_msg, MINISAT::Solver& newS);
+
+       //this function biases the activity levels of MINISAT variables.
+       //void ChangeActivityLevels_Of_SATVars(MINISAT::Solver& n);
+
+       // Constructor
+       BeevMgr() :
+               _interior_unique_table(INITIAL_INTERIOR_UNIQUE_TABLE_SIZE), _symbol_unique_table(INITIAL_SYMBOL_UNIQUE_TABLE_SIZE), _bvconst_unique_table(
+                               INITIAL_BVCONST_UNIQUE_TABLE_SIZE), BBTermMemo(INITIAL_BBTERM_MEMO_TABLE_SIZE), BBFormMemo(INITIAL_BBFORM_MEMO_TABLE_SIZE),
+                               _max_node_num(0), ASTFalse(CreateNode(FALSE)), ASTTrue(CreateNode(TRUE)), ASTUndefined(CreateNode(UNDEFINED)), SolverMap(
+                                               INITIAL_SOLVER_MAP_SIZE), _arrayread_symbol(INITIAL_ARRAYREAD_SYMBOL_SIZE), _introduced_symbols(
+                                               INITIAL_INTRODUCED_SYMBOLS_SIZE), _symbol_count(0)
+       {
+               _current_query = ASTUndefined;
+               ValidFlag = false;
+               bvdiv_exception_occured = false;
+               counterexample_checking_during_refinement = false;
+               start_abstracting = false;
+               Begin_RemoveWrites = false;
+               SimplifyWrites_InPlace_Flag = false;
+               SimplifyMap = new ASTNodeMap(INITIAL_SIMPLIFY_MAP_SIZE);
+               SimplifyNegMap = new ASTNodeMap(INITIAL_SIMPLIFY_MAP_SIZE);
+               _letid_expr_map = new ASTNodeMap(INITIAL_INTRODUCED_SYMBOLS_SIZE);
+       }
+       ;
+
+       //destructor
+       ~BeevMgr();
+}; //End of Class BeevMgr
+
+
+class CompleteCounterExample
+{
+       ASTNodeMap counterexample;
+       BeevMgr * bv;
+public:
+       CompleteCounterExample(ASTNodeMap a, BeevMgr* beev) :
+               counterexample(a), bv(beev)
+       {
+       }
+       ASTNode GetCounterExample(ASTNode e)
+       {
+               if (BOOLEAN_TYPE == e.GetType() && SYMBOL != e.GetKind())
+               {
+                       FatalError("You must input a term or propositional variables\n", e);
+               }
+               if (counterexample.find(e) != counterexample.end())
+               {
+                       return counterexample[e];
+               }
+               else
+               {
+                       if (SYMBOL == e.GetKind() && BOOLEAN_TYPE == e.GetType())
+                       {
+                               return bv->CreateNode(BEEV::FALSE);
+                       }
+
+                       if (SYMBOL == e.GetKind())
+                       {
+                               ASTNode z = bv->CreateZeroConst(e.GetValueWidth());
+                               return z;
+                       }
+
+                       return e;
+               }
+       }
+};
 
-}; // end namespace BEEV
+}
+; // end namespace BEEV
 #endif
index c14d175610b3600054cd2d497b7be515e2341438..d7a3b2bf61915793610720f71f90a6acca503587 100644 (file)
@@ -8,38 +8,44 @@
 // -*- c++ -*-
 
 #include "ASTUtil.h"
-namespace BEEV {
-  ostream &operator<<(ostream &os, const Spacer &sp) {
-    // Instead of wrapping lines with hundreds of spaces, prints
-    // a "+" at the beginning of the line for each wrap-around.
-    // so lines print like: +14+               (XOR ...
-    int blanks = sp._spaces % 60;
-    int wraps = sp._spaces / 60;
-    if (wraps > 0) {
-      os << "+" << wraps;
-    }
-    for (int i = 0; i < blanks; i++)
-      os << " ";  
-    return os;
-  }
-   
-  //this function accepts the name of a function (as a char *), and
-  //records some stats about it. if the input is "print_func_stats",
-  //the function will then print the stats that it has collected.
-  void CountersAndStats(const char * functionname) {
-    static function_counters s;
+namespace BEEV
+{
+ostream &operator<<(ostream &os, const Spacer &sp)
+{
+       // Instead of wrapping lines with hundreds of spaces, prints
+       // a "+" at the beginning of the line for each wrap-around.
+       // so lines print like: +14+            (XOR ...
+       int blanks = sp._spaces % 60;
+       int wraps = sp._spaces / 60;
+       if (wraps > 0)
+       {
+               os << "+" << wraps;
+       }
+       for (int i = 0; i < blanks; i++)
+               os << " ";
+       return os;
+}
 
-    if (stats) {
+//this function accepts the name of a function (as a char *), and
+//records some stats about it. if the input is "print_func_stats",
+//the function will then print the stats that it has collected.
+void CountersAndStats(const char * functionname)
+{
+       static function_counters s;
 
-      if(!strcmp(functionname,"print_func_stats")) {
-       cout << endl;
-       for(function_counters::iterator it=s.begin(),itend=s.end();
-           it!=itend;it++)
-         cout << "Number of times the function: " << it->first << ": is called: " << it->second << endl;
-       return;
-      }
-      s[functionname] += 1;
+       if (stats)
+       {
 
-    }
-  }
-};// end of namespace
+               if (!strcmp(functionname, "print_func_stats"))
+               {
+                       cout << endl;
+                       for (function_counters::iterator it = s.begin(), itend = s.end(); it != itend; it++)
+                               cout << "Number of times the function: " << it->first << ": is called: " << it->second << endl;
+                       return;
+               }
+               s[functionname] += 1;
+
+       }
+}
+}
+;// end of namespace
index c9f50237fcde7419d32bc403833719c624d88375..8f50ccf41adf0413ed3146aea13ad4df1a60e8ea 100644 (file)
@@ -19,8 +19,9 @@
 // The 0th element of the vector corresponds to bit 0 -- the low-order bit.
 
 #include "AST.h"
-namespace BEEV {
-  //  extern void lpvec(ASTVec &vec);
+namespace BEEV
+{
+//  extern void lpvec(ASTVec &vec);
 
 // FIXME: Assert no zero-length bit vectors!!!
 // FIXME: Need top-level functions that create and destroy the memo tables.
@@ -33,510 +34,542 @@ namespace BEEV {
 
 
 ASTNode ASTJunk;
-const ASTNode BeevMgr::BBTerm(const ASTNode& term) {
-
-
-  //CHANGED TermMemo is now an ASTNodeMap. Based on BBFormMemo
-  ASTNodeMap::iterator it = BBTermMemo.find(term);
-  if (it != BBTermMemo.end()) {
-    // already there.  Just return it.
-    return it->second;
-  }
-
-//  ASTNode& result = ASTJunk;
-  ASTNode result;
-
-  /*
-  bool weregood = false;
-  if(term.GetNodeNum() == 17408){
-     weregood = true;
-  }
-  */
-
-
-  Kind k = term.GetKind();
-  if (!is_Term_kind(k))
-    FatalError("BBTerm: Illegal kind to BBTerm",term);
-
-  ASTVec::const_iterator kids_end = term.end(); 
-  unsigned int num_bits = term.GetValueWidth();
-  switch (k) {
-  case BVNEG: {
-    // bitwise complement
-    // bitblast the child.
-    //FIXME Uses a tempory const ASTNode
-    const ASTNode& bbkids = BBTerm(term[0]);
-    result = CreateNode(BOOLVEC, BBNeg(bbkids.GetChildren()));
-    break;
-  }
-
-  case BVLEFTSHIFT:
-   {
-     if (BVCONST == term[1].GetKind())
-       {
-        // Constant shifts should be removed during simplification.
-        unsigned int shift = GetUnsignedConst(term[1]);
-
-        ASTNode term0 = BBTerm(term[0]);
-        ASTVec children(term0.GetChildren()); // mutable copy of the children.
-        BBLShift(children, shift);
-        
-        result = CreateNode(BOOLVEC, children);
-      }
-     else
-     {
-     // Barrel shifter
-       const ASTVec& bbarg1 = BBTerm(term[0]).GetChildren();
-       const ASTVec& bbarg2 = BBTerm(term[1]).GetChildren();  
-       
-       ASTVec temp_result(bbarg1);
-       
-       for (unsigned int i =0; i < bbarg2.size(); i++)
+const ASTNode BeevMgr::BBTerm(const ASTNode& term)
+{
+
+       //CHANGED TermMemo is now an ASTNodeMap. Based on BBFormMemo
+       ASTNodeMap::iterator it = BBTermMemo.find(term);
+       if (it != BBTermMemo.end())
+       {
+               // already there.  Just return it.
+               return it->second;
+       }
+
+       //  ASTNode& result = ASTJunk;
+       ASTNode result;
+
+       /*
+        bool weregood = false;
+        if(term.GetNodeNum() == 17408){
+        weregood = true;
+        }
+        */
+
+       Kind k = term.GetKind();
+       if (!is_Term_kind(k))
+               FatalError("BBTerm: Illegal kind to BBTerm", term);
+
+       ASTVec::const_iterator kids_end = term.end();
+       unsigned int num_bits = term.GetValueWidth();
+       switch (k)
+       {
+               case BVNEG:
                {
-                       if (bbarg2[i] == ASTFalse) 
-                               continue;  // Not shifting by anything.
-                       
-                       unsigned int shift_amount = 1 << i;
-                       
-                       bool done = false;
-                       
-                       for (unsigned int j=temp_result.size()-1; !done; j--)
+                       // bitwise complement
+                       // bitblast the child.
+                       //FIXME Uses a tempory const ASTNode
+                       const ASTNode& bbkids = BBTerm(term[0]);
+                       result = CreateNode(BOOLVEC, BBNeg(bbkids.GetChildren()));
+                       break;
+               }
+
+               case BVLEFTSHIFT:
+               {
+                       if (BVCONST == term[1].GetKind())
+                       {
+                               // Constant shifts should be removed during simplification.
+                               unsigned int shift = GetUnsignedConst(term[1]);
+
+                               ASTNode term0 = BBTerm(term[0]);
+                               ASTVec children(term0.GetChildren()); // mutable copy of the children.
+                               BBLShift(children, shift);
+
+                               result = CreateNode(BOOLVEC, children);
+                       }
+                       else
                        {
-                               if (j < shift_amount)
-                                       temp_result[j] = CreateSimpForm(ITE, bbarg2[i],ASTFalse,temp_result[j]);
-                               else
-                                       temp_result[j] = CreateSimpForm(ITE, bbarg2[i],temp_result[j-shift_amount],temp_result[j]);
-                               
-               // want the loop to finish after j=0, but when j=0, j-1 == MAX_INT. Hence this weird idiom.
-                               if (j ==0)
-                                       done = true;
+                               // Barrel shifter
+                               const ASTVec& bbarg1 = BBTerm(term[0]).GetChildren();
+                               const ASTVec& bbarg2 = BBTerm(term[1]).GetChildren();
+
+                               ASTVec temp_result(bbarg1);
+
+                               for (unsigned int i = 0; i < bbarg2.size(); i++)
+                               {
+                                       if (bbarg2[i] == ASTFalse)
+                                               continue; // Not shifting by anything.
+
+                                       unsigned int shift_amount = 1 << i;
+
+                                       bool done = false;
+
+                                       for (unsigned int j = temp_result.size() - 1; !done; j--)
+                                       {
+                                               if (j < shift_amount)
+                                                       temp_result[j] = CreateSimpForm(ITE, bbarg2[i], ASTFalse, temp_result[j]);
+                                               else
+                                                       temp_result[j] = CreateSimpForm(ITE, bbarg2[i], temp_result[j - shift_amount], temp_result[j]);
+
+                                               // want the loop to finish after j=0, but when j=0, j-1 == MAX_INT. Hence this weird idiom.
+                                               if (j == 0)
+                                                       done = true;
+                                       }
+                               }
+
+                               result = CreateNode(BOOLVEC, temp_result);
                        }
+                       break;
                }
 
-       result =  CreateNode(BOOLVEC, temp_result);
-  }
-       break;
-   }
-   
-   case BVRIGHTSHIFT:
-   {
-    if (BVCONST == term[1].GetKind())
-      {
-               // Constant shifts should be removed during simplification.
-               
-           unsigned int shift = GetUnsignedConst(term[1]);
-
-       ASTNode term0 = BBTerm(term[0]);
-       ASTVec children(term0.GetChildren()); // mutable copy of the children.
-       BBRShift(children, shift);
-
-       result = CreateNode(BOOLVEC, children);
-      }
-     else
-       {
-       // Barrel shifter
-       const ASTVec& bbarg1 = BBTerm(term[0]).GetChildren();
-       const ASTVec& bbarg2 = BBTerm(term[1]).GetChildren();  
-       
-       ASTVec temp_result(bbarg1);
-       
-       for (unsigned int i =0; i < bbarg2.size(); i++)
-         {
-           if (bbarg2[i] == ASTFalse) 
-             continue;  // Not shifting by anything.
-           
-           unsigned int shift_amount = 1 << i;
-           
-           bool done = false;
-           
-           for (unsigned int j=0; j < temp_result.size(); j++)
-             {
-               if (j + shift_amount >= temp_result.size())
-                 temp_result[j] = CreateSimpForm(ITE, bbarg2[i],ASTFalse,temp_result[j]);
-               else
-                 temp_result[j] = CreateSimpForm(ITE, bbarg2[i],temp_result[j+shift_amount],temp_result[j]);
-               
-               if (j ==0)
-                 done = true;
-             }
-         }
-
-       
-       result =  CreateNode(BOOLVEC, temp_result);
-
-       /*      cerr << result << endl;
-       cerr << term[0] << endl;
-       cerr << term[1] << endl;
-       cerr << "right shift. Node size is:" << NodeSize(result) << endl;
-       cerr << "input size: " << NodeSize(term[0]) << " " << NodeSize(term[1]) << endl;
-       */
-       }
-   }
-       break;
-   
-
-
-  case BVSRSHIFT:
-  case BVVARSHIFT: 
-    FatalError("BBTerm: These kinds have not been implemented in the BitBlaster: ", term);
-    break;
-  case ITE: {
-    // Term version of ITE.
-
-    // Blast the args
-    // FIXME Uses temporary const ASTNodes and an ASTVec&
-    //const ASTNode& cond = BBForm(term[0]);
-    const ASTNode& cond = BBForm(term[0]);
-    const ASTNode& thn = BBTerm(term[1]);
-    const ASTNode& els = BBTerm(term[2]);
-    result = 
-       CreateNode(BOOLVEC, BBITE(cond, thn.GetChildren(), els.GetChildren()));
-    break;
-  }
-
-
-  case BVSX: {
-    // Replicate high-order bit as many times as necessary.
-    // Arg 0 is expression to be sign extended.
-    const ASTNode& arg = term[0];
-    unsigned long result_width = term.GetValueWidth();
-    unsigned long arg_width = arg.GetValueWidth();
-    //FIXME Uses a temporary const ASTNode reference
-    const ASTNode& bbarg = BBTerm(arg);
-
-    if (result_width == arg_width) {
-      //nothing to sign extend
-      break;
-    }
-    else {
-      //we need to sign extend
-      const ASTNode& msbX = bbarg.back();
-      //const ASTNode& msb1 = msbX;
-      
-      ASTVec ccc = msbX.GetChildren();
-      const ASTNode& msb = CreateSimpForm(msbX.GetKind(),ccc);
-
-     //  Old version
-     //  ASTNode msb = bbarg.back();
-     //  const ASTNode msb1 = msb;
-      
-     //  ASTVec ccc = msb.GetChildren();
-     //  msb = CreateSimpForm(msb.GetKind(),ccc);
-
-      // DD 1/14/07 Simplify silently drops all but first two args of XOR.
-      // I expanded XOR to N args with flattening optimization.
-      // This bug took 2 days to track down!
-
-      // msb = SimplifyFormula(msb,false);
-
-      // cout << "!!!!!!!!!!!!!!!!" << endl
-      // << "Simplify msb:" << msb2 << endl
-      // << "Simplify result:" << msb << endl;
-
-      //FIXME Dynamically allocate the result vector?
-      //Is this doing multiple copies?
-      //ASTVec& tmp_res = *(new ASTVec(result_width));
-      ASTVec tmp_res(result_width);
-
-      //FIXME Should these be gotten from result?
-      ASTVec::const_iterator bb_it = bbarg.begin();
-      ASTVec::iterator res_it = tmp_res.begin();
-      ASTVec::iterator res_ext = res_it+arg_width; // first bit of extended part
-      ASTVec::iterator res_end = tmp_res.end();
-      // copy LSBs directly from bbvec
-      for( ; res_it < res_ext; (res_it++, bb_it++)) {
-       *res_it = *bb_it;
-      }
-      // repeat MSB to fill up rest of result.
-      for( ; res_it < res_end; (res_it++)) {
-       *res_it = msb;
-      }
-      
-       //Temporary debugging code
-       //    cout << "Sign extending:" << endl 
-       //              << "  Vec ";
-       //    lpvec( bbarg.GetChildren() );
-       //    cout << "  Extended to ";
-       //    lp(result);
-       //    cout << endl;
-      
-      result = CreateNode(BOOLVEC, tmp_res);
-
-      break;
-    }
-  }
-
- case BVZX: {
-    // Fill the high-order bits with as many zeroes as needed.
-    // Arg 0 is expression to be sign extended.
-    const ASTNode& arg = term[0];
-    unsigned long result_width = term.GetValueWidth();
-    unsigned long arg_width = arg.GetValueWidth();
-
-      //FIXME Uses a temporary const ASTNode reference
-      const ASTNode& bbarg = BBTerm(arg);
-      ASTVec tmp_res(result_width);
-
-      //FIXME Should these be gotten from result?
-      ASTVec::const_iterator bb_it = bbarg.begin();
-      ASTVec::iterator res_it = tmp_res.begin();
-      ASTVec::iterator res_ext = res_it+arg_width; // first bit of extended part
-      ASTVec::iterator res_end = tmp_res.end();
-      // copy LSBs directly from bbvec
-      for( ; res_it < res_ext; (res_it++, bb_it++)) {
-       *res_it = *bb_it;
-      }
-      // repeat zero to fill up rest of result.
-      for( ; res_it < res_end; (res_it++)) {
-               *res_it = ASTFalse;
-      }
-      
-      // Temporary debugging code
-      //         cout << "Zero extending:" << endl 
-      //               << "  Vec ";
-      //    lpvec( bbarg.GetChildren() );
-      //     cout << "  Extended to ";
-      //          cout << result;
-      //   cout << endl;
-      
-      result = CreateNode(BOOLVEC, tmp_res);
-
-      break;
-    }
-
-
-
-
-  case BVEXTRACT: {
-    // bitblast the child, then extract the relevant bits.
-    // Note: This could be optimized by not bitblasting the bits
-    // that aren't fetched.  But that would be tricky, especially
-    // with memo-ization.
-
-    //FIXME Using const ASTNode w/out reference
-    /*
-    if(weregood){
-       printf("spot01\n");
-       term[0].LispPrint(cout, 0);
-    }
-    */
-    const ASTNode& bbkids = BBTerm(term[0]); 
-    /*
-    if(weregood){
-       printf("spot02, kids:\n");
-       bbkids.LispPrint(cout, 0);
-    }
-    */
-    unsigned int high = GetUnsignedConst(term[1]);
-    /*
-    if(weregood){
-       printf("spot03, high: %d\n", high);
-    }
-    */
-    unsigned int low = GetUnsignedConst(term[2]);
-    /*
-    if(weregood){
-       printf("spot04, low: %d\n", low);
-    }
-    */
-
-    ASTVec::const_iterator bbkfit = bbkids.begin();
-    // I should have used pointers to ASTVec, to avoid this crock
-    
-    //FIXME Creates a new local ASTVec and does the CreateNode from that
-    result = CreateNode(BOOLVEC, ASTVec(bbkfit+low, bbkfit+high+1));
-    /*
-    if(weregood){
-       printf("spot05\n");
-    }
-    */
-    break;
-  }
-  case BVCONCAT: {
-    //FIXME Using temporary const ASTNodes 
-    const ASTNode& vec1 = BBTerm(term[0]);
-    const ASTNode& vec2 = BBTerm(term[1]);
-
-    //FIXME This has to be an unnessecary copy and a memory leak
-    //Leaking ASTVec tmp_res = *(new ASTVec(vec2.GetChildren()));
-    ASTVec tmp_res(vec2.GetChildren());
-    tmp_res.insert(tmp_res.end(), vec1.begin(), vec1.end());
-    result = CreateNode(BOOLVEC, tmp_res);
-    break;
-  }
-  case BVPLUS: {
-    // ASSERT: at least one child.
-    // ASSERT: all children and result are the same size.
-    // Previous phase must make sure this is true.
-    // Add children pairwise and accumulate in BBsum
-
-    // FIXME: Unnecessary array copies.
-    ASTVec::const_iterator it = term.begin();
-    ASTVec tmp_res = BBTerm(*it).GetChildren();
-    for (++it; it < kids_end; it++) {
-      const ASTVec& tmp = BBTerm(*it).GetChildren();
-      BBPlus2(tmp_res, tmp, ASTFalse);
-    }
-
-    result = CreateNode(BOOLVEC, tmp_res);
-    break;
-  }
-  case BVUMINUS: {
-    //FIXME Using const ASTNode reference
-    const ASTNode& bbkid = BBTerm(term[0]);
-    result = CreateNode(BOOLVEC, BBUminus(bbkid.GetChildren()));
-    break;
-  }
-  case BVSUB: {
-    // complement of subtrahend
-    // copy, since BBSub writes into it.
-    
-    //FIXME: Unnecessary array copies?
-    ASTVec tmp_res = BBTerm(term[0]).GetChildren(); 
-
-    const ASTVec& bbkid1 = BBTerm(term[1]).GetChildren();
-    BBSub(tmp_res, bbkid1);
-    result = CreateNode(BOOLVEC, tmp_res);
-    break;
-  }
-  case BVMULT: {
-    // ASSERT 2 arguments, same length, result is same length.
-
-    const ASTNode& t0 = term[0];
-    const ASTNode& t1 = term[1];
-
-    const ASTNode& mpcd1 = BBTerm(t0);
-    const ASTNode& mpcd2 = BBTerm(t1);
-    //Reverese the order of the nodes w/out the need for temporaries
-    //This is needed because t0 an t1 must be const
-    if ((BVCONST != t0.GetKind()) && (BVCONST == t1.GetKind())) {
-      result = CreateNode(BOOLVEC, 
-        BBMult(mpcd2.GetChildren(), mpcd1.GetChildren()) );
-    }else{
-      result = CreateNode(BOOLVEC, 
-        BBMult(mpcd1.GetChildren(), mpcd2.GetChildren()) );
-    }
-    break;
-  }
-  case BVDIV:
-  case BVMOD: {
-    const ASTNode& dvdd = BBTerm(term[0]);
-    const ASTNode& dvsr = BBTerm(term[1]);
-    unsigned int width = dvdd.Degree();
-    ASTVec q(width); 
-    ASTVec r(width); 
-    BBDivMod(dvdd.GetChildren(),  dvsr.GetChildren(), q, r, width);
-    if (k == BVDIV)
-      result = CreateNode(BOOLVEC, q);    
-    else
-      result = CreateNode(BOOLVEC, r);
-    break;
-  }
-  //  n-ary bitwise operators.
-  case BVXOR:
-  case BVXNOR:
-  case BVAND:
-  case BVOR:
-  case BVNOR:
-  case BVNAND: {
-    // Add children pairwise and accumulate in BBsum
-    ASTVec::const_iterator it = term.begin();
-    Kind bk = UNDEFINED;  // Kind of individual bit op.
-    switch (k) {
-    case BVXOR: bk = XOR;  break;
-    case BVXNOR: bk = IFF; break;
-    case BVAND: bk = AND; break;
-    case BVOR: bk = OR; break;
-    case BVNOR: bk = NOR; break;
-    case BVNAND: bk = NAND; break;
-    default:
-      FatalError("BBTerm: Illegal kind to BBTerm",term);
-      break;
-    }
-
-    // Sum is destructively modified in the loop, so make a copy of value
-    // returned by BBTerm.
-    ASTNode temp = BBTerm(*it);
-    ASTVec sum(temp.GetChildren());    // First operand.
-
-    // Iterate over remaining bitvector term operands
-    for (++it; it < kids_end; it++) {
-      //FIXME FIXME FIXME: Why does using a temp. var change the behavior?
-      temp = BBTerm(*it);
-      const ASTVec& y = temp.GetChildren();
-      
-      // Iterate over bits
-      // FIXME: Why is this not using an iterator???
-      int n = y.size();
-      for (int i = 0; i < n; i++) {
-       sum[i] = CreateSimpForm(bk, sum[i], y[i]);
-      }
-    }
-    result = CreateNode(BOOLVEC, sum);
-    break;
-  }
-  case SYMBOL: {
-    // ASSERT: IndexWidth = 0?  Semantic analysis should check.
-    //Leaking ASTVec& bbvec = *(new ASTVec);
-    
-    //FIXME Why is isn't this ASTVEC bbvec(num_bits) ?
-    ASTVec bbvec;
-    /*
-    if(term.GetNodeNum() == 17132){
-       weregood = true;
-    }
-    */
-
-    /*
-    if(weregood){
-       printf("number of bits for node 17132: %d\n", num_bits);
-    }
-    */
-    for (unsigned int i = 0; i < num_bits; i++) {
-      ASTNode bit_node =
-       CreateNode(BVGETBIT, term, CreateBVConst(32,i));
-      bbvec.push_back(bit_node); 
-    }
-    result = CreateNode(BOOLVEC, bbvec);
-    /*
-    if(weregood){
-      printf("done\n");
-    }
-    */
-    break;
-  }
-  case BVCONST: {
-    ASTVec tmp_res(num_bits);
+               case BVRIGHTSHIFT:
+               {
+                       if (BVCONST == term[1].GetKind())
+                       {
+                               // Constant shifts should be removed during simplification.
+
+                               unsigned int shift = GetUnsignedConst(term[1]);
+
+                               ASTNode term0 = BBTerm(term[0]);
+                               ASTVec children(term0.GetChildren()); // mutable copy of the children.
+                               BBRShift(children, shift);
+
+                               result = CreateNode(BOOLVEC, children);
+                       }
+                       else
+                       {
+                               // Barrel shifter
+                               const ASTVec& bbarg1 = BBTerm(term[0]).GetChildren();
+                               const ASTVec& bbarg2 = BBTerm(term[1]).GetChildren();
+
+                               ASTVec temp_result(bbarg1);
+
+                               for (unsigned int i = 0; i < bbarg2.size(); i++)
+                               {
+                                       if (bbarg2[i] == ASTFalse)
+                                               continue; // Not shifting by anything.
+
+                                       unsigned int shift_amount = 1 << i;
+
+                                       bool done = false;
+
+                                       for (unsigned int j = 0; j < temp_result.size(); j++)
+                                       {
+                                               if (j + shift_amount >= temp_result.size())
+                                                       temp_result[j] = CreateSimpForm(ITE, bbarg2[i], ASTFalse, temp_result[j]);
+                                               else
+                                                       temp_result[j] = CreateSimpForm(ITE, bbarg2[i], temp_result[j + shift_amount], temp_result[j]);
+
+                                               if (j == 0)
+                                                       done = true;
+                                       }
+                               }
+
+                               result = CreateNode(BOOLVEC, temp_result);
+
+                               /*      cerr << result << endl;
+                                cerr << term[0] << endl;
+                                cerr << term[1] << endl;
+                                cerr << "right shift. Node size is:" << NodeSize(result) << endl;
+                                cerr << "input size: " << NodeSize(term[0]) << " " << NodeSize(term[1]) << endl;
+                                */
+                       }
+               }
+                       break;
+
+               case BVSRSHIFT:
+               case BVVARSHIFT:
+                       FatalError("BBTerm: These kinds have not been implemented in the BitBlaster: ", term);
+                       break;
+               case ITE:
+               {
+                       // Term version of ITE.
+
+                       // Blast the args
+                       // FIXME Uses temporary const ASTNodes and an ASTVec&
+                       //const ASTNode& cond = BBForm(term[0]);
+                       const ASTNode& cond = BBForm(term[0]);
+                       const ASTNode& thn = BBTerm(term[1]);
+                       const ASTNode& els = BBTerm(term[2]);
+                       result = CreateNode(BOOLVEC, BBITE(cond, thn.GetChildren(), els.GetChildren()));
+                       break;
+               }
+
+               case BVSX:
+               {
+                       // Replicate high-order bit as many times as necessary.
+                       // Arg 0 is expression to be sign extended.
+                       const ASTNode& arg = term[0];
+                       unsigned long result_width = term.GetValueWidth();
+                       unsigned long arg_width = arg.GetValueWidth();
+                       //FIXME Uses a temporary const ASTNode reference
+                       const ASTNode& bbarg = BBTerm(arg);
+
+                       if (result_width == arg_width)
+                       {
+                               //nothing to sign extend
+                               break;
+                       }
+                       else
+                       {
+                               //we need to sign extend
+                               const ASTNode& msbX = bbarg.back();
+                               //const ASTNode& msb1 = msbX;
+
+                               ASTVec ccc = msbX.GetChildren();
+                               const ASTNode& msb = CreateSimpForm(msbX.GetKind(), ccc);
+
+                               //  Old version
+                               //  ASTNode msb = bbarg.back();
+                               //  const ASTNode msb1 = msb;
+
+                               //  ASTVec ccc = msb.GetChildren();
+                               //  msb = CreateSimpForm(msb.GetKind(),ccc);
+
+                               // DD 1/14/07 Simplify silently drops all but first two args of XOR.
+                               // I expanded XOR to N args with flattening optimization.
+                               // This bug took 2 days to track down!
+
+                               // msb = SimplifyFormula(msb,false);
+
+                               // cout << "!!!!!!!!!!!!!!!!" << endl
+                               // << "Simplify msb:" << msb2 << endl
+                               // << "Simplify result:" << msb << endl;
+
+                               //FIXME Dynamically allocate the result vector?
+                               //Is this doing multiple copies?
+                               //ASTVec& tmp_res = *(new ASTVec(result_width));
+                               ASTVec tmp_res(result_width);
+
+                               //FIXME Should these be gotten from result?
+                               ASTVec::const_iterator bb_it = bbarg.begin();
+                               ASTVec::iterator res_it = tmp_res.begin();
+                               ASTVec::iterator res_ext = res_it + arg_width; // first bit of extended part
+                               ASTVec::iterator res_end = tmp_res.end();
+                               // copy LSBs directly from bbvec
+                               for (; res_it < res_ext; (res_it++, bb_it++))
+                               {
+                                       *res_it = *bb_it;
+                               }
+                               // repeat MSB to fill up rest of result.
+                               for (; res_it < res_end; (res_it++))
+                               {
+                                       *res_it = msb;
+                               }
+
+                               //Temporary debugging code
+                               //    cout << "Sign extending:" << endl
+                               //              << "  Vec ";
+                               //    lpvec( bbarg.GetChildren() );
+                               //    cout << "  Extended to ";
+                               //    lp(result);
+                               //    cout << endl;
+
+                               result = CreateNode(BOOLVEC, tmp_res);
+
+                               break;
+                       }
+               }
+
+               case BVZX:
+               {
+                       // Fill the high-order bits with as many zeroes as needed.
+                       // Arg 0 is expression to be sign extended.
+                       const ASTNode& arg = term[0];
+                       unsigned long result_width = term.GetValueWidth();
+                       unsigned long arg_width = arg.GetValueWidth();
+
+                       //FIXME Uses a temporary const ASTNode reference
+                       const ASTNode& bbarg = BBTerm(arg);
+                       ASTVec tmp_res(result_width);
+
+                       //FIXME Should these be gotten from result?
+                       ASTVec::const_iterator bb_it = bbarg.begin();
+                       ASTVec::iterator res_it = tmp_res.begin();
+                       ASTVec::iterator res_ext = res_it + arg_width; // first bit of extended part
+                       ASTVec::iterator res_end = tmp_res.end();
+                       // copy LSBs directly from bbvec
+                       for (; res_it < res_ext; (res_it++, bb_it++))
+                       {
+                               *res_it = *bb_it;
+                       }
+                       // repeat zero to fill up rest of result.
+                       for (; res_it < res_end; (res_it++))
+                       {
+                               *res_it = ASTFalse;
+                       }
+
+                       // Temporary debugging code
+                       //         cout << "Zero extending:" << endl
+                       //              << "  Vec ";
+                       //    lpvec( bbarg.GetChildren() );
+                       //     cout << "  Extended to ";
+                       //         cout << result;
+                       //   cout << endl;
+
+                       result = CreateNode(BOOLVEC, tmp_res);
+
+                       break;
+               }
+
+               case BVEXTRACT:
+               {
+                       // bitblast the child, then extract the relevant bits.
+                       // Note: This could be optimized by not bitblasting the bits
+                       // that aren't fetched.  But that would be tricky, especially
+                       // with memo-ization.
+
+                       //FIXME Using const ASTNode w/out reference
+                       /*
+                        if(weregood){
+                        printf("spot01\n");
+                        term[0].LispPrint(cout, 0);
+                        }
+                        */
+                       const ASTNode& bbkids = BBTerm(term[0]);
+                       /*
+                        if(weregood){
+                        printf("spot02, kids:\n");
+                        bbkids.LispPrint(cout, 0);
+                        }
+                        */
+                       unsigned int high = GetUnsignedConst(term[1]);
+                       /*
+                        if(weregood){
+                        printf("spot03, high: %d\n", high);
+                        }
+                        */
+                       unsigned int low = GetUnsignedConst(term[2]);
+                       /*
+                        if(weregood){
+                        printf("spot04, low: %d\n", low);
+                        }
+                        */
+
+                       ASTVec::const_iterator bbkfit = bbkids.begin();
+                       // I should have used pointers to ASTVec, to avoid this crock
+
+                       //FIXME Creates a new local ASTVec and does the CreateNode from that
+                       result = CreateNode(BOOLVEC, ASTVec(bbkfit + low, bbkfit + high + 1));
+                       /*
+                        if(weregood){
+                        printf("spot05\n");
+                        }
+                        */
+                       break;
+               }
+               case BVCONCAT:
+               {
+                       //FIXME Using temporary const ASTNodes
+                       const ASTNode& vec1 = BBTerm(term[0]);
+                       const ASTNode& vec2 = BBTerm(term[1]);
+
+                       //FIXME This has to be an unnessecary copy and a memory leak
+                       //Leaking ASTVec tmp_res = *(new ASTVec(vec2.GetChildren()));
+                       ASTVec tmp_res(vec2.GetChildren());
+                       tmp_res.insert(tmp_res.end(), vec1.begin(), vec1.end());
+                       result = CreateNode(BOOLVEC, tmp_res);
+                       break;
+               }
+               case BVPLUS:
+               {
+                       // ASSERT: at least one child.
+                       // ASSERT: all children and result are the same size.
+                       // Previous phase must make sure this is true.
+                       // Add children pairwise and accumulate in BBsum
+
+                       // FIXME: Unnecessary array copies.
+                       ASTVec::const_iterator it = term.begin();
+                       ASTVec tmp_res = BBTerm(*it).GetChildren();
+                       for (++it; it < kids_end; it++)
+                       {
+                               const ASTVec& tmp = BBTerm(*it).GetChildren();
+                               BBPlus2(tmp_res, tmp, ASTFalse);
+                       }
+
+                       result = CreateNode(BOOLVEC, tmp_res);
+                       break;
+               }
+               case BVUMINUS:
+               {
+                       //FIXME Using const ASTNode reference
+                       const ASTNode& bbkid = BBTerm(term[0]);
+                       result = CreateNode(BOOLVEC, BBUminus(bbkid.GetChildren()));
+                       break;
+               }
+               case BVSUB:
+               {
+                       // complement of subtrahend
+                       // copy, since BBSub writes into it.
+
+                       //FIXME: Unnecessary array copies?
+                       ASTVec tmp_res = BBTerm(term[0]).GetChildren();
+
+                       const ASTVec& bbkid1 = BBTerm(term[1]).GetChildren();
+                       BBSub(tmp_res, bbkid1);
+                       result = CreateNode(BOOLVEC, tmp_res);
+                       break;
+               }
+               case BVMULT:
+               {
+                       // ASSERT 2 arguments, same length, result is same length.
+
+                       const ASTNode& t0 = term[0];
+                       const ASTNode& t1 = term[1];
+
+                       const ASTNode& mpcd1 = BBTerm(t0);
+                       const ASTNode& mpcd2 = BBTerm(t1);
+                       //Reverese the order of the nodes w/out the need for temporaries
+                       //This is needed because t0 an t1 must be const
+                       if ((BVCONST != t0.GetKind()) && (BVCONST == t1.GetKind()))
+                       {
+                               result = CreateNode(BOOLVEC, BBMult(mpcd2.GetChildren(), mpcd1.GetChildren()));
+                       }
+                       else
+                       {
+                               result = CreateNode(BOOLVEC, BBMult(mpcd1.GetChildren(), mpcd2.GetChildren()));
+                       }
+                       break;
+               }
+               case BVDIV:
+               case BVMOD:
+               {
+                       const ASTNode& dvdd = BBTerm(term[0]);
+                       const ASTNode& dvsr = BBTerm(term[1]);
+                       unsigned int width = dvdd.Degree();
+                       ASTVec q(width);
+                       ASTVec r(width);
+                       BBDivMod(dvdd.GetChildren(), dvsr.GetChildren(), q, r, width);
+                       if (k == BVDIV)
+                               result = CreateNode(BOOLVEC, q);
+                       else
+                               result = CreateNode(BOOLVEC, r);
+                       break;
+               }
+                       //  n-ary bitwise operators.
+               case BVXOR:
+               case BVXNOR:
+               case BVAND:
+               case BVOR:
+               case BVNOR:
+               case BVNAND:
+               {
+                       // Add children pairwise and accumulate in BBsum
+                       ASTVec::const_iterator it = term.begin();
+                       Kind bk = UNDEFINED; // Kind of individual bit op.
+                       switch (k)
+                       {
+                               case BVXOR:
+                                       bk = XOR;
+                                       break;
+                               case BVXNOR:
+                                       bk = IFF;
+                                       break;
+                               case BVAND:
+                                       bk = AND;
+                                       break;
+                               case BVOR:
+                                       bk = OR;
+                                       break;
+                               case BVNOR:
+                                       bk = NOR;
+                                       break;
+                               case BVNAND:
+                                       bk = NAND;
+                                       break;
+                               default:
+                                       FatalError("BBTerm: Illegal kind to BBTerm", term);
+                                       break;
+                       }
+
+                       // Sum is destructively modified in the loop, so make a copy of value
+                       // returned by BBTerm.
+                       ASTNode temp = BBTerm(*it);
+                       ASTVec sum(temp.GetChildren()); // First operand.
+
+                       // Iterate over remaining bitvector term operands
+                       for (++it; it < kids_end; it++)
+                       {
+                               //FIXME FIXME FIXME: Why does using a temp. var change the behavior?
+                               temp = BBTerm(*it);
+                               const ASTVec& y = temp.GetChildren();
+
+                               // Iterate over bits
+                               // FIXME: Why is this not using an iterator???
+                               int n = y.size();
+                               for (int i = 0; i < n; i++)
+                               {
+                                       sum[i] = CreateSimpForm(bk, sum[i], y[i]);
+                               }
+                       }
+                       result = CreateNode(BOOLVEC, sum);
+                       break;
+               }
+               case SYMBOL:
+               {
+                       // ASSERT: IndexWidth = 0?  Semantic analysis should check.
+                       //Leaking ASTVec& bbvec = *(new ASTVec);
+
+                       //FIXME Why is isn't this ASTVEC bbvec(num_bits) ?
+                       ASTVec bbvec;
+                       /*
+                        if(term.GetNodeNum() == 17132){
+                        weregood = true;
+                        }
+                        */
+
+                       /*
+                        if(weregood){
+                        printf("number of bits for node 17132: %d\n", num_bits);
+                        }
+                        */
+                       for (unsigned int i = 0; i < num_bits; i++)
+                       {
+                               ASTNode bit_node = CreateNode(BVGETBIT, term, CreateBVConst(32, i));
+                               bbvec.push_back(bit_node);
+                       }
+                       result = CreateNode(BOOLVEC, bbvec);
+                       /*
+                        if(weregood){
+                        printf("done\n");
+                        }
+                        */
+                       break;
+               }
+               case BVCONST:
+               {
+                       ASTVec tmp_res(num_bits);
 #ifndef NATIVE_C_ARITH
-    CBV bv = term.GetBVConst();
-    for(unsigned int i = 0; i < num_bits; i++){
-      tmp_res[i] = CONSTANTBV::BitVector_bit_test(bv,i) ? ASTTrue : ASTFalse; 
-    }  
+                       CBV bv = term.GetBVConst();
+                       for (unsigned int i = 0; i < num_bits; i++)
+                       {
+                               tmp_res[i] = CONSTANTBV::BitVector_bit_test(bv, i) ? ASTTrue : ASTFalse;
+                       }
 #else
-    const unsigned long long int c = term.GetBVConst();
-    unsigned long long int bitmask = 0x00000000000000001LL;
-    for (unsigned int i = 0; i < num_bits; i++, bitmask <<= 1)
-      tmp_res[i] = ((c & (bitmask)) ? ASTTrue : ASTFalse);    
+                       const unsigned long long int c = term.GetBVConst();
+                       unsigned long long int bitmask = 0x00000000000000001LL;
+                       for (unsigned int i = 0; i < num_bits; i++, bitmask <<= 1)
+                       tmp_res[i] = ((c & (bitmask)) ? ASTTrue : ASTFalse);
 #endif
-    result = CreateNode(BOOLVEC, tmp_res);
-    break;
-  }              
-  case BOOLVEC: {
-    cerr << "Hit a boolvec! what to do?" << endl;
-    break;
-  }
-  default:
-    FatalError("BBTerm: Illegal kind to BBTerm",term);
-  }
-
-  //if(result == ASTJunk)
-  //  cout<<"result does not change"<<endl;
-  // cout << "================" << endl << "BBTerm:" << term << endl;
-  // cout << "----------------" << endl << "BBTerm result:";
-  // lpvec(result);
-  // cout << endl;
-
-  return (BBTermMemo[term] = result);
+                       result = CreateNode(BOOLVEC, tmp_res);
+                       break;
+               }
+               case BOOLVEC:
+               {
+                       cerr << "Hit a boolvec! what to do?" << endl;
+                       break;
+               }
+               default:
+                       FatalError("BBTerm: Illegal kind to BBTerm", term);
+       }
+
+       //if(result == ASTJunk)
+       //  cout<<"result does not change"<<endl;
+       // cout << "================" << endl << "BBTerm:" << term << endl;
+       // cout << "----------------" << endl << "BBTerm result:";
+       // lpvec(result);
+       // cout << endl;
+
+       return (BBTermMemo[term] = result);
 
 }
 
@@ -546,258 +579,277 @@ const ASTNode BeevMgr::BBTerm(const ASTNode& term) {
 const ASTNode BeevMgr::BBForm(const ASTNode& form)
 {
 
-  ASTNodeMap::iterator it = BBFormMemo.find(form);
-  if (it != BBFormMemo.end()) {
-    // already there.  Just return it.
-    return it->second;
-  }
-
-  ASTNode result = ASTUndefined;
-
-  Kind k = form.GetKind();
-  if (!is_Form_kind(k)) {
-    FatalError("BBForm: Illegal kind: ",form);
-  }
-
-  //  Not returning until end, and memoizing everything, makes it easier
-  // to trace coherently.
-    
-  // Various special cases
-  switch (k) {
-  case TRUE:
-  case FALSE: {
-    result = form;
-    break;
-  }
-
-  case SYMBOL:
-    //printf("bit-blasting SYMBOL\n");
-    if (form.GetType() != BOOLEAN_TYPE) {
-      FatalError("BBForm: Symbol represents more than one bit", form);
-    }
-
-    result = form;
-    break;
-
-  case BVGETBIT: {
-    // exactly two children
-    const ASTNode bbchild = BBTerm(form[0]);
-    unsigned int index =  GetUnsignedConst(form[1]);
-    result = bbchild[index];
-    break;
-  }
-
-  case NOT:
-    result = CreateSimpNot(BBForm(form[0]));
-    break;  
-
-  case ITE:
-    // FIXME: SHould this be CreateSimpITE?
-    result = CreateNode(ITE, BBForm(form[0]), BBForm(form[1]), BBForm(form[2]));
-    break;
-
-  case AND: 
-  case OR: 
-  case NAND: 
-  case NOR: 
-  case IFF: 
-  case XOR:
-  case IMPLIES: {
-    //printf("bit-blasting AND or OR\n");
-    ASTVec bbkids;             // bit-blasted children (formulas)
-
-    // FIXME: Put in fast exits for AND/OR/NAND/NOR/IMPLIES
-    ASTVec::const_iterator kids_end = form.end(); 
-    for (ASTVec::const_iterator it = form.begin(); it != kids_end; it++) {
-      bbkids.push_back(BBForm(*it));
-    }
-    result = CreateSimpForm(k, bbkids);
-    break;
-  }
-
-  case NEQ: {
-    ASTNode bbkid = BBForm(CreateNode(EQ, form.GetChildren()));
-    result = CreateSimpNot(bbkid);
-    break;
-  }
-
-  case EQ: {
-    //printf("bit-blasting EQ\n");
-    //form.LispPrint(cout, 0);
-    // Common code for binary operations
-    // FIXME:  This ought to be in a semantic analysis phase.
-    //printf("spot01\n");
-    const ASTNode left = BBTerm(form[0]);
-    //printf("spot02\n");
-    const ASTNode right = BBTerm(form[1]);
-    //printf("spot03\n");
-    if (left.Degree() != right.Degree()) {
-      cerr << "BBForm: Size mismatch" << endl << form[0] << endl << form[1] << endl;
-      FatalError("",ASTUndefined);
-    }
-    result = BBEQ(left.GetChildren(), right.GetChildren());
-    //printf("spot04\n");
-    break;
-  }
-
-  case BVLE: 
-  case BVGE: 
-  case BVGT: 
-  case BVLT: 
-  case BVSLE:
-  case BVSGE:
-  case BVSGT:
-  case BVSLT: {
-    result = BBcompare(form);
-    break;
-  }
-  default:
-    FatalError("BBForm: Illegal kind: ", form);
-    break;
-  }
-
-  // cout << "================" << endl
-  // << "BBForm: " << form << endl
-  // << "----------------" << endl
-  // << "BBForm Result: " << result << endl;
-
-  return (BBFormMemo[form] = result);
+       ASTNodeMap::iterator it = BBFormMemo.find(form);
+       if (it != BBFormMemo.end())
+       {
+               // already there.  Just return it.
+               return it->second;
+       }
+
+       ASTNode result = ASTUndefined;
+
+       Kind k = form.GetKind();
+       if (!is_Form_kind(k))
+       {
+               FatalError("BBForm: Illegal kind: ", form);
+       }
+
+       //  Not returning until end, and memoizing everything, makes it easier
+       // to trace coherently.
+
+       // Various special cases
+       switch (k)
+       {
+               case TRUE:
+               case FALSE:
+               {
+                       result = form;
+                       break;
+               }
+
+               case SYMBOL:
+                       //printf("bit-blasting SYMBOL\n");
+                       if (form.GetType() != BOOLEAN_TYPE)
+                       {
+                               FatalError("BBForm: Symbol represents more than one bit", form);
+                       }
+
+                       result = form;
+                       break;
+
+               case BVGETBIT:
+               {
+                       // exactly two children
+                       const ASTNode bbchild = BBTerm(form[0]);
+                       unsigned int index = GetUnsignedConst(form[1]);
+                       result = bbchild[index];
+                       break;
+               }
+
+               case NOT:
+                       result = CreateSimpNot(BBForm(form[0]));
+                       break;
+
+               case ITE:
+                       // FIXME: SHould this be CreateSimpITE?
+                       result = CreateNode(ITE, BBForm(form[0]), BBForm(form[1]), BBForm(form[2]));
+                       break;
+
+               case AND:
+               case OR:
+               case NAND:
+               case NOR:
+               case IFF:
+               case XOR:
+               case IMPLIES:
+               {
+                       //printf("bit-blasting AND or OR\n");
+                       ASTVec bbkids; // bit-blasted children (formulas)
+
+                       // FIXME: Put in fast exits for AND/OR/NAND/NOR/IMPLIES
+                       ASTVec::const_iterator kids_end = form.end();
+                       for (ASTVec::const_iterator it = form.begin(); it != kids_end; it++)
+                       {
+                               bbkids.push_back(BBForm(*it));
+                       }
+                       result = CreateSimpForm(k, bbkids);
+                       break;
+               }
+
+               case NEQ:
+               {
+                       ASTNode bbkid = BBForm(CreateNode(EQ, form.GetChildren()));
+                       result = CreateSimpNot(bbkid);
+                       break;
+               }
+
+               case EQ:
+               {
+                       //printf("bit-blasting EQ\n");
+                       //form.LispPrint(cout, 0);
+                       // Common code for binary operations
+                       // FIXME:  This ought to be in a semantic analysis phase.
+                       //printf("spot01\n");
+                       const ASTNode left = BBTerm(form[0]);
+                       //printf("spot02\n");
+                       const ASTNode right = BBTerm(form[1]);
+                       //printf("spot03\n");
+                       if (left.Degree() != right.Degree())
+                       {
+                               cerr << "BBForm: Size mismatch" << endl << form[0] << endl << form[1] << endl;
+                               FatalError("", ASTUndefined);
+                       }
+                       result = BBEQ(left.GetChildren(), right.GetChildren());
+                       //printf("spot04\n");
+                       break;
+               }
+
+               case BVLE:
+               case BVGE:
+               case BVGT:
+               case BVLT:
+               case BVSLE:
+               case BVSGE:
+               case BVSGT:
+               case BVSLT:
+               {
+                       result = BBcompare(form);
+                       break;
+               }
+               default:
+                       FatalError("BBForm: Illegal kind: ", form);
+                       break;
+       }
+
+       // cout << "================" << endl
+       // << "BBForm: " << form << endl
+       // << "----------------" << endl
+       // << "BBForm Result: " << result << endl;
+
+       return (BBFormMemo[form] = result);
 }
-  
+
 // Bit blast a sum of two equal length BVs.
 // Update sum vector destructively with new sum.
 void BeevMgr::BBPlus2(ASTVec& sum, const ASTVec& y, ASTNode cin)
 {
-//   cout << "Bitblasting plus.  Operand 1: " << endl;
-//   lpvec(sum);
-//   cout << endl << " operand 2: " << endl;
-//   lpvec(y);
-//   cout << endl << "carry: " << endl << cin << endl;
-
-
-  int n = sum.size();
-  // ASSERT: y.size() == x.size()
-  // FIXME: Don't bother computing i+1 carry, which is discarded.
-  for (int i = 0; i < n; i++) {
-    ASTNode nextcin = Majority(sum[i], y[i], cin); 
-    sum[i] = CreateSimpForm(XOR, CreateSimpForm(XOR, sum[i], y[i]), cin);
-    cin = nextcin;
-  }
-
-//   cout << "----------------" << endl << "Result: " << endl;
-//   lpvec(sum);
-//   cout << endl;
+       //   cout << "Bitblasting plus.  Operand 1: " << endl;
+       //   lpvec(sum);
+       //   cout << endl << " operand 2: " << endl;
+       //   lpvec(y);
+       //   cout << endl << "carry: " << endl << cin << endl;
+
+
+       int n = sum.size();
+       // ASSERT: y.size() == x.size()
+       // FIXME: Don't bother computing i+1 carry, which is discarded.
+       for (int i = 0; i < n; i++)
+       {
+               ASTNode nextcin = Majority(sum[i], y[i], cin);
+               sum[i] = CreateSimpForm(XOR, CreateSimpForm(XOR, sum[i], y[i]), cin);
+               cin = nextcin;
+       }
+
+       //   cout << "----------------" << endl << "Result: " << endl;
+       //   lpvec(sum);
+       //   cout << endl;
 
 }
 
 // Stores result - x in result, destructively
 void BeevMgr::BBSub(ASTVec& result, const ASTVec& y)
 {
-  ASTVec compsubtrahend  = BBNeg(y);
-  BBPlus2(result, compsubtrahend, ASTTrue);
+       ASTVec compsubtrahend = BBNeg(y);
+       BBPlus2(result, compsubtrahend, ASTTrue);
 }
 
 // Add one bit
 ASTVec BeevMgr::BBAddOneBit(ASTVec& x, ASTNode cin)
 {
-  ASTVec result = ASTVec(0);
-  ASTVec::const_iterator itend = x.end();
-  for (ASTVec::const_iterator it = x.begin(); it < itend; it++) {
-    ASTNode nextcin = CreateSimpForm(AND, *it, cin); 
-    result.push_back(CreateSimpForm(XOR, *it, cin));
-    cin = nextcin;
-  }
-  // FIXME: unnecessary array copy on return?
-  return result;
+       ASTVec result = ASTVec(0);
+       ASTVec::const_iterator itend = x.end();
+       for (ASTVec::const_iterator it = x.begin(); it < itend; it++)
+       {
+               ASTNode nextcin = CreateSimpForm(AND, *it, cin);
+               result.push_back(CreateSimpForm(XOR, *it, cin));
+               cin = nextcin;
+       }
+       // FIXME: unnecessary array copy on return?
+       return result;
 }
 
 // Increment bit-blasted vector and return result.
 ASTVec BeevMgr::BBInc(ASTVec& x)
 {
-  return BBAddOneBit(x, ASTTrue);
+       return BBAddOneBit(x, ASTTrue);
 }
 
 // Return formula for majority function of three bits.
 // Pass arguments by reference to reduce refcounting.
-ASTNode BeevMgr::Majority(const ASTNode& a, const ASTNode& b,const ASTNode& c)
+ASTNode BeevMgr::Majority(const ASTNode& a, const ASTNode& b, const ASTNode& c)
 {
-  // Checking explicitly for constant a, b and c could
-  // be more efficient, because they are repeated in the logic.
-  if (ASTTrue == a) {
-    return CreateSimpForm(OR, b, c);
-  }
-  else if (ASTFalse == a) {
-    return CreateSimpForm(AND, b, c);
-  }
-  else if (ASTTrue == b) {
-    return CreateSimpForm(OR, a, c);
-  }
-  else if (ASTFalse == b) {
-    return CreateSimpForm(AND, a, c);
-  }
-  else if (ASTTrue == c) {
-    return CreateSimpForm(OR, a, b);
-  }
-  else if (ASTFalse == c) {
-    return CreateSimpForm(AND, a, b);
-  }
-  // there are lots more simplifications, but I'm not sure they're
-  // worth doing explicitly (e.g., a = b, a = ~b, etc.) 
-  else {
-    return
-      CreateSimpForm(OR,
-                    CreateSimpForm(AND, a, b),
-                    CreateSimpForm(AND, b, c),
-                    CreateSimpForm(AND, a, c));
-  }
+       // Checking explicitly for constant a, b and c could
+       // be more efficient, because they are repeated in the logic.
+       if (ASTTrue == a)
+       {
+               return CreateSimpForm(OR, b, c);
+       }
+       else if (ASTFalse == a)
+       {
+               return CreateSimpForm(AND, b, c);
+       }
+       else if (ASTTrue == b)
+       {
+               return CreateSimpForm(OR, a, c);
+       }
+       else if (ASTFalse == b)
+       {
+               return CreateSimpForm(AND, a, c);
+       }
+       else if (ASTTrue == c)
+       {
+               return CreateSimpForm(OR, a, b);
+       }
+       else if (ASTFalse == c)
+       {
+               return CreateSimpForm(AND, a, b);
+       }
+       // there are lots more simplifications, but I'm not sure they're
+       // worth doing explicitly (e.g., a = b, a = ~b, etc.)
+       else
+       {
+               return CreateSimpForm(OR, CreateSimpForm(AND, a, b), CreateSimpForm(AND, b, c), CreateSimpForm(AND, a, c));
+       }
 }
 
-
 // Bitwise complement
 ASTVec BeevMgr::BBNeg(const ASTVec& x)
 {
-  ASTVec result = ASTVec(0);           // FIXME: faster to preallocate n entries?
-  // Negate each bit.
-  ASTVec::const_iterator xend = x.end();
-  for (ASTVec::const_iterator it = x.begin(); it < xend; it++) {
-    result.push_back(CreateSimpNot(*it));
-  }
-  // FIXME: unecessary array copy when it returns?
-  return result;
+       ASTVec result = ASTVec(0); // FIXME: faster to preallocate n entries?
+       // Negate each bit.
+       ASTVec::const_iterator xend = x.end();
+       for (ASTVec::const_iterator it = x.begin(); it < xend; it++)
+       {
+               result.push_back(CreateSimpNot(*it));
+       }
+       // FIXME: unecessary array copy when it returns?
+       return result;
 }
 
 // Compute unary minus
 ASTVec BeevMgr::BBUminus(const ASTVec& x)
 {
-  ASTVec xneg = BBNeg(x);
-  return BBInc(xneg);
+       ASTVec xneg = BBNeg(x);
+       return BBInc(xneg);
 }
 
 // Multiply two bitblasted numbers
 ASTVec BeevMgr::BBMult(const ASTVec& x, const ASTVec& y)
 {
-  ASTVec ycopy(y);
-  ASTVec::const_iterator xend = x.end();
-  ASTVec::const_iterator xit = x.begin();
-  // start prod with first partial product.
-  // FIXME: This is unnecessary. Clean it up.
-  ASTVec prod = ASTVec(BBAndBit(y, *xit));
-  // start loop at next bit.
-  for(xit++; xit < xend; xit++) {
-    // shift first
-    BBLShift(ycopy);
-
-    if (ASTFalse == *xit) {
-      // If this bit is zero, the partial product will
-      // be zero.  No reason to add that in.
-      continue;
-    }
-
-    ASTVec pprod = BBAndBit(ycopy, *xit);
-    // accumulate in the product.
-    BBPlus2(prod, pprod, ASTFalse);
-  }
-  return prod;
+       ASTVec ycopy(y);
+       ASTVec::const_iterator xend = x.end();
+       ASTVec::const_iterator xit = x.begin();
+       // start prod with first partial product.
+       // FIXME: This is unnecessary. Clean it up.
+       ASTVec prod = ASTVec(BBAndBit(y, *xit));
+       // start loop at next bit.
+       for (xit++; xit < xend; xit++)
+       {
+               // shift first
+               BBLShift(ycopy);
+
+               if (ASTFalse == *xit)
+               {
+                       // If this bit is zero, the partial product will
+                       // be zero.  No reason to add that in.
+                       continue;
+               }
+
+               ASTVec pprod = BBAndBit(ycopy, *xit);
+               // accumulate in the product.
+               BBPlus2(prod, pprod, ASTFalse);
+       }
+       return prod;
 }
 
 // This implements a variant of binary long division.
@@ -805,86 +857,92 @@ ASTVec BeevMgr::BBMult(const ASTVec& x, const ASTVec& y)
 // recursion depth.
 void BeevMgr::BBDivMod(const ASTVec &y, const ASTVec &x, ASTVec &q, ASTVec &r, unsigned int rwidth)
 {
-  unsigned int width = y.size();
-  if (rwidth == 0) {
-    // When we have shifted the entire width, y is guaranteed to be 0.
-    q = BBfill(width, ASTFalse);
-    r = BBfill(width, ASTFalse);
-  }
-  else {
-    ASTVec q1, r1;
-    ASTVec yrshift1(y);
-    BBRShift(yrshift1);
-
-    // recursively divide y/2 by x.
-    BBDivMod(yrshift1, x, q1, r1, rwidth-1);
-
-    ASTVec q1lshift1(q1);
-    BBLShift(q1lshift1);
-
-    ASTVec r1lshift1(r1);
-    BBLShift(r1lshift1);
-    
-    ASTVec r1lshift1plusyodd = BBAddOneBit(r1lshift1, y[0]);
-    ASTVec rminusx(r1lshift1plusyodd);
-    BBSub(rminusx, x);
-
-    // Adjusted q, r values when when r is too large.
-    ASTNode rtoolarge = BBBVLE(x, r1lshift1plusyodd, false);
-    ASTVec ygtrxqval = BBITE(rtoolarge, BBInc(q1lshift1), q1lshift1);
-    ASTVec ygtrxrval = BBITE(rtoolarge, rminusx, r1lshift1plusyodd);
-
-    // q & r values when y >= x
-    ASTNode yeqx = BBEQ(y, x);
-    // *** Problem: the bbfill for qval is wrong.  Should be 1, not -1.
-    ASTVec one = BBfill(width, ASTFalse);
-    one[0] = ASTTrue;
-    ASTVec notylessxqval = BBITE(yeqx, one, ygtrxqval);
-    ASTVec notylessxrval = BBITE(yeqx, BBfill(width, ASTFalse), ygtrxrval);
-    // y < x <=> not x >= y.
-    ASTNode ylessx = CreateSimpNot(BBBVLE(x, y, false));
-    // final values of q and r
-    q = BBITE(ylessx, BBfill(width, ASTFalse), notylessxqval);
-    r = BBITE(ylessx, y, notylessxrval);
-  }
+       unsigned int width = y.size();
+       if (rwidth == 0)
+       {
+               // When we have shifted the entire width, y is guaranteed to be 0.
+               q = BBfill(width, ASTFalse);
+               r = BBfill(width, ASTFalse);
+       }
+       else
+       {
+               ASTVec q1, r1;
+               ASTVec yrshift1(y);
+               BBRShift(yrshift1);
+
+               // recursively divide y/2 by x.
+               BBDivMod(yrshift1, x, q1, r1, rwidth - 1);
+
+               ASTVec q1lshift1(q1);
+               BBLShift(q1lshift1);
+
+               ASTVec r1lshift1(r1);
+               BBLShift(r1lshift1);
+
+               ASTVec r1lshift1plusyodd = BBAddOneBit(r1lshift1, y[0]);
+               ASTVec rminusx(r1lshift1plusyodd);
+               BBSub(rminusx, x);
+
+               // Adjusted q, r values when when r is too large.
+               ASTNode rtoolarge = BBBVLE(x, r1lshift1plusyodd, false);
+               ASTVec ygtrxqval = BBITE(rtoolarge, BBInc(q1lshift1), q1lshift1);
+               ASTVec ygtrxrval = BBITE(rtoolarge, rminusx, r1lshift1plusyodd);
+
+               // q & r values when y >= x
+               ASTNode yeqx = BBEQ(y, x);
+               // *** Problem: the bbfill for qval is wrong.  Should be 1, not -1.
+               ASTVec one = BBfill(width, ASTFalse);
+               one[0] = ASTTrue;
+               ASTVec notylessxqval = BBITE(yeqx, one, ygtrxqval);
+               ASTVec notylessxrval = BBITE(yeqx, BBfill(width, ASTFalse), ygtrxrval);
+               // y < x <=> not x >= y.
+               ASTNode ylessx = CreateSimpNot(BBBVLE(x, y, false));
+               // final values of q and r
+               q = BBITE(ylessx, BBfill(width, ASTFalse), notylessxqval);
+               r = BBITE(ylessx, y, notylessxrval);
+       }
 }
 
 // build ITE's (ITE cond then[i] else[i]) for each i.
 ASTVec BeevMgr::BBITE(const ASTNode& cond, const ASTVec& thn, const ASTVec& els)
 {
-  // Fast exits.
-  if (ASTTrue == cond) {
-    return thn;
-  }
-  else if (ASTFalse == cond) {
-    return els;
-  }
-
-  ASTVec result(0);
-  ASTVec::const_iterator th_it_end = thn.end();
-  ASTVec::const_iterator el_it = els.begin();
-  for (ASTVec::const_iterator th_it = thn.begin(); th_it < th_it_end; th_it++, el_it++) {
-    result.push_back(CreateSimpForm(ITE, cond, *th_it, *el_it));
-  }
-  return result;
+       // Fast exits.
+       if (ASTTrue == cond)
+       {
+               return thn;
+       }
+       else if (ASTFalse == cond)
+       {
+               return els;
+       }
+
+       ASTVec result(0);
+       ASTVec::const_iterator th_it_end = thn.end();
+       ASTVec::const_iterator el_it = els.begin();
+       for (ASTVec::const_iterator th_it = thn.begin(); th_it < th_it_end; th_it++, el_it++)
+       {
+               result.push_back(CreateSimpForm(ITE, cond, *th_it, *el_it));
+       }
+       return result;
 }
 // AND each bit of vector y with single bit b and return the result.
 ASTVec BeevMgr::BBAndBit(const ASTVec& y, ASTNode b)
 {
-  ASTVec result(0); 
-
-  if (ASTTrue == b) {
-    return y;
-  }
-  // FIXME: put in fast exits when b is constant 0. 
-
-  ASTVec::const_iterator yend = y.end();
-  for(ASTVec::const_iterator yit = y.begin(); yit < yend; yit++) {
-    result.push_back(CreateSimpForm(AND, *yit, b));
-  }
-  return result;
-}
+       ASTVec result(0);
+
+       if (ASTTrue == b)
+       {
+               return y;
+       }
+       // FIXME: put in fast exits when b is constant 0.
 
+       ASTVec::const_iterator yend = y.end();
+       for (ASTVec::const_iterator yit = y.begin(); yit < yend; yit++)
+       {
+               result.push_back(CreateSimpForm(AND, *yit, b));
+       }
+       return result;
+}
 
 // Workhorse for comparison routines.  This does a signed BVLE if is_signed
 // is true, else it's unsigned.  All other comparison operators can be reduced
@@ -894,44 +952,40 @@ ASTVec BeevMgr::BBAndBit(const ASTVec& y, ASTNode b)
 // of the bits.
 ASTNode BeevMgr::BBBVLE(const ASTVec& left, const ASTVec& right, bool is_signed)
 {
-  // "thisbit" represents BVLE of the suffixes of the BVs
-  // from that position .  if R < L, return TRUE, else if L < R
-  // return FALSE, else return BVLE of lower-order bits.  MSB is
-  // treated separately, because signed comparison is done by
-  // complementing the MSB of each BV, then doing an unsigned
-  // comparison.
-  ASTVec::const_iterator lit = left.begin();
-  ASTVec::const_iterator litend = left.end();
-  ASTVec::const_iterator rit = right.begin();
-  ASTNode prevbit = ASTTrue;
-  for ( ; lit  < litend-1; lit++, rit++) {
-    ASTNode neglit = CreateSimpNot(*lit);
-    ASTNode thisbit =
-      CreateSimpForm(OR,
-                CreateSimpForm(AND,neglit,*rit), // TRUE if l < r
-                CreateSimpForm(AND,
-                           CreateSimpForm(OR, neglit, *rit), // false if not equal
-                           prevbit)); // else prevbit
-    prevbit = thisbit;
-  }
-
-  // Handle MSB -- negate MSBs if signed comparison
-  // FIXME: make into refs after it's debugged.
-  ASTNode lmsb = *lit;
-  ASTNode rmsb = *rit;
-  if (is_signed) {
-    lmsb = CreateSimpNot(*lit);
-    rmsb = CreateSimpNot(*rit);
-  }
-
-  ASTNode neglmsb = CreateSimpNot(lmsb);
-  ASTNode msb =
-    CreateSimpForm(OR,
-              CreateSimpForm(AND,neglmsb, rmsb), // TRUE if l < r
-              CreateSimpForm(AND,
-                         CreateSimpForm(OR, neglmsb, rmsb), // false if not equal
-                         prevbit)); // else prevbit
-  return msb;
+       // "thisbit" represents BVLE of the suffixes of the BVs
+       // from that position .  if R < L, return TRUE, else if L < R
+       // return FALSE, else return BVLE of lower-order bits.  MSB is
+       // treated separately, because signed comparison is done by
+       // complementing the MSB of each BV, then doing an unsigned
+       // comparison.
+       ASTVec::const_iterator lit = left.begin();
+       ASTVec::const_iterator litend = left.end();
+       ASTVec::const_iterator rit = right.begin();
+       ASTNode prevbit = ASTTrue;
+       for (; lit < litend - 1; lit++, rit++)
+       {
+               ASTNode neglit = CreateSimpNot(*lit);
+               ASTNode thisbit = CreateSimpForm(OR, CreateSimpForm(AND, neglit, *rit), // TRUE if l < r
+                               CreateSimpForm(AND, CreateSimpForm(OR, neglit, *rit), // false if not equal
+                                               prevbit)); // else prevbit
+               prevbit = thisbit;
+       }
+
+       // Handle MSB -- negate MSBs if signed comparison
+       // FIXME: make into refs after it's debugged.
+       ASTNode lmsb = *lit;
+       ASTNode rmsb = *rit;
+       if (is_signed)
+       {
+               lmsb = CreateSimpNot(*lit);
+               rmsb = CreateSimpNot(*rit);
+       }
+
+       ASTNode neglmsb = CreateSimpNot(lmsb);
+       ASTNode msb = CreateSimpForm(OR, CreateSimpForm(AND, neglmsb, rmsb), // TRUE if l < r
+                       CreateSimpForm(AND, CreateSimpForm(OR, neglmsb, rmsb), // false if not equal
+                                       prevbit)); // else prevbit
+       return msb;
 }
 
 // Left shift by 1 within fixed field inserting zeros at LSB.
@@ -939,121 +993,159 @@ ASTNode BeevMgr::BBBVLE(const ASTVec& left, const ASTVec& right, bool is_signed)
 // Fixme: generalize to n bits
 void BeevMgr::BBLShift(ASTVec& x)
 {
-  // left shift x (destructively) within width.
-  // loop backwards so that copy to self works correctly. (DON'T use STL insert!)
-  ASTVec::iterator xbeg = x.begin();
-  for(ASTVec::iterator xit = x.end()-1; xit > xbeg; xit--) {
-    *xit = *(xit-1);
-  }
-  *xbeg = ASTFalse;            // new LSB is zero.
-  // cout << "Shifted result" << endl;
-  // lpvec(x);
+       // left shift x (destructively) within width.
+       // loop backwards so that copy to self works correctly. (DON'T use STL insert!)
+       ASTVec::iterator xbeg = x.begin();
+       for (ASTVec::iterator xit = x.end() - 1; xit > xbeg; xit--)
+       {
+               *xit = *(xit - 1);
+       }
+       *xbeg = ASTFalse; // new LSB is zero.
+       // cout << "Shifted result" << endl;
+       // lpvec(x);
 }
 
 // Left shift  within fixed field inserting zeros at LSB.
 // Writes result into first argument.
-  void BeevMgr::BBLShift(ASTVec& x, unsigned int shift)
+void BeevMgr::BBLShift(ASTVec& x, unsigned int shift)
 {
-  // left shift x (destructively) within width.
-  // loop backwards so that copy to self works correctly. (DON'T use STL insert!)
-  ASTVec::iterator xbeg = x.begin();
-  ASTVec::iterator xit = x.end()-1;
-  for(; xit >= xbeg; xit--) {
-    if (xit-shift >= xbeg)
-      *xit = *(xit-shift);
-    else
-      *xit= ASTFalse; // new LSB is zero.
-  }
+       // left shift x (destructively) within width.
+       // loop backwards so that copy to self works correctly. (DON'T use STL insert!)
+       ASTVec::iterator xbeg = x.begin();
+       ASTVec::iterator xit = x.end() - 1;
+       for (; xit >= xbeg; xit--)
+       {
+               if (xit - shift >= xbeg)
+                       *xit = *(xit - shift);
+               else
+                       *xit = ASTFalse; // new LSB is zero.
+       }
 }
 
 // Right shift within fixed field inserting zeros at MSB.
 // Writes result into first argument.
-  void BeevMgr::BBRShift(ASTVec& x, unsigned int shift)
+void BeevMgr::BBRShift(ASTVec& x, unsigned int shift)
 {
-  // right shift x (destructively) within width.
-  ASTVec::iterator xend = x.end();
-  ASTVec::iterator xit = x.begin();
-  for(; xit < xend; xit++) {
-    if (xit+shift < xend)
-      *xit = *(xit+shift);
-    else
-      *xit= ASTFalse; // new MSB is zero.
-  }
+       // right shift x (destructively) within width.
+       ASTVec::iterator xend = x.end();
+       ASTVec::iterator xit = x.begin();
+       for (; xit < xend; xit++)
+       {
+               if (xit + shift < xend)
+                       *xit = *(xit + shift);
+               else
+                       *xit = ASTFalse; // new MSB is zero.
+       }
 }
 
-
-
-
 // Right shift by 1 within fixed field, inserting new zeros at MSB.
 // Writes result into first argument.
 // Fixme: generalize to n bits.
 void BeevMgr::BBRShift(ASTVec& x)
 {
-  ASTVec::iterator xend = x.end() - 1;
-  ASTVec::iterator xit = x.begin();
-  for( ; xit < xend; xit++) {
-    *xit = *(xit+1);
-  }
-  *xit = ASTFalse;             // new MSB is zero.
+       ASTVec::iterator xend = x.end() - 1;
+       ASTVec::iterator xit = x.begin();
+       for (; xit < xend; xit++)
+       {
+               *xit = *(xit + 1);
+       }
+       *xit = ASTFalse; // new MSB is zero.
 }
 
-// Return bit-blasted form for BVLE, BVGE, BVGT, SBLE, etc. 
-ASTNode BeevMgr::BBcompare(const ASTNode& form) {
-  const ASTNode lnode = BBTerm(form[0]);
-  const ASTNode rnode = BBTerm(form[1]);
-  const ASTVec& left = lnode.GetChildren();
-  const ASTVec& right = rnode.GetChildren();
-
-  //const ASTVec& left = BBTerm(form[0]).GetChildren();
-  //const ASTVec& right = BBTerm(form[1]).GetChildren();
-
-  Kind k = form.GetKind();
-  switch(k) {
-  case BVLE: { return BBBVLE(left, right, false); break; }
-  case BVGE: { return BBBVLE(right, left, false); break; }
-  case BVGT: { return CreateSimpNot(BBBVLE(left, right, false)); break; }
-  case BVLT: { return CreateSimpNot(BBBVLE(right, left, false)); break; }
-  case BVSLE: { return BBBVLE(left, right, true); break; }
-  case BVSGE: { return BBBVLE(right, left, true); break; }
-  case BVSGT: { return CreateSimpNot(BBBVLE(left, right, true)); break; }
-  case BVSLT: { return CreateSimpNot(BBBVLE(right, left, true)); break; }
-  default:
-    cerr << "BBCompare: Illegal kind" << form << endl;    
-    FatalError("",ASTUndefined);
-  }
-  return ASTUndefined;
+// Return bit-blasted form for BVLE, BVGE, BVGT, SBLE, etc.
+ASTNode BeevMgr::BBcompare(const ASTNode& form)
+{
+       const ASTNode lnode = BBTerm(form[0]);
+       const ASTNode rnode = BBTerm(form[1]);
+       const ASTVec& left = lnode.GetChildren();
+       const ASTVec& right = rnode.GetChildren();
+
+       //const ASTVec& left = BBTerm(form[0]).GetChildren();
+       //const ASTVec& right = BBTerm(form[1]).GetChildren();
+
+       Kind k = form.GetKind();
+       switch (k)
+       {
+               case BVLE:
+               {
+                       return BBBVLE(left, right, false);
+                       break;
+               }
+               case BVGE:
+               {
+                       return BBBVLE(right, left, false);
+                       break;
+               }
+               case BVGT:
+               {
+                       return CreateSimpNot(BBBVLE(left, right, false));
+                       break;
+               }
+               case BVLT:
+               {
+                       return CreateSimpNot(BBBVLE(right, left, false));
+                       break;
+               }
+               case BVSLE:
+               {
+                       return BBBVLE(left, right, true);
+                       break;
+               }
+               case BVSGE:
+               {
+                       return BBBVLE(right, left, true);
+                       break;
+               }
+               case BVSGT:
+               {
+                       return CreateSimpNot(BBBVLE(left, right, true));
+                       break;
+               }
+               case BVSLT:
+               {
+                       return CreateSimpNot(BBBVLE(right, left, true));
+                       break;
+               }
+               default:
+                       cerr << "BBCompare: Illegal kind" << form << endl;
+                       FatalError("", ASTUndefined);
+       }
+       return ASTUndefined;
 }
 
-
 // return a vector with n copies of fillval
 ASTVec BeevMgr::BBfill(unsigned int width, ASTNode fillval)
 {
-  ASTVec zvec(width, fillval);
-  return zvec;
+       ASTVec zvec(width, fillval);
+       return zvec;
 }
 
 ASTNode BeevMgr::BBEQ(const ASTVec& left, const ASTVec& right)
 {
-  ASTVec andvec;
-  ASTVec::const_iterator lit = left.begin();
-  ASTVec::const_iterator litend = left.end();
-  ASTVec::const_iterator rit = right.begin();
-  
-  if(left.size() > 1) {
-    for(; lit != litend; lit++, rit++) {
-      ASTNode biteq = CreateSimpForm(IFF, *lit, *rit);
-      // fast path exit
-      if (biteq == ASTFalse) {
-       return ASTFalse;
-      }
-      else {
-       andvec.push_back(biteq);
-      }
-    }
-    ASTNode n = CreateSimpForm(AND, andvec);  
-    return n;
-  }
-  else
-    return CreateSimpForm(IFF,*lit,*rit);
+       ASTVec andvec;
+       ASTVec::const_iterator lit = left.begin();
+       ASTVec::const_iterator litend = left.end();
+       ASTVec::const_iterator rit = right.begin();
+
+       if (left.size() > 1)
+       {
+               for (; lit != litend; lit++, rit++)
+               {
+                       ASTNode biteq = CreateSimpForm(IFF, *lit, *rit);
+                       // fast path exit
+                       if (biteq == ASTFalse)
+                       {
+                               return ASTFalse;
+                       }
+                       else
+                       {
+                               andvec.push_back(biteq);
+                       }
+               }
+               ASTNode n = CreateSimpForm(AND, andvec);
+               return n;
+       }
+       else
+               return CreateSimpForm(IFF, *lit, *rit);
 }
 } // BEEV namespace
index 7dc24eff96bf97486e68f6948120005c35986f8a..85e19164ff99d71ff4faa916de5b3332d5fca9d5 100644 (file)
@@ -24,400 +24,483 @@ static bool _disable_simpbool = 0;
 // children to reduce growing of vectors.
 //BEEV::ASTVec child_stack;
 
-namespace BEEV {
-
-  ASTNode BeevMgr::CreateSimpForm(Kind kind, ASTVec &children = _empty_ASTVec) {
-    if (_disable_simpbool) {
-      return CreateNode(kind, children);
-    }
-    else {
-      switch (kind) {
-      case NOT: return CreateSimpNot(children[0]); break; 
-      case AND: return CreateSimpAndOr(1, children); break; 
-      case OR: return CreateSimpAndOr(0, children); break;
-      case NAND: return CreateSimpNot(CreateSimpAndOr(1, children)); break;
-      case NOR: return CreateSimpNot(CreateSimpAndOr(0, children)); break;
-      case IFF: {
-       // Not sure children can ever be empty, but what the heck.
-       //      if (children.size() == 0) {
-       //        return ASTTrue;
-       //      }
-       // Convert IFF to XOR ASAP to simplify flattening. 
-       children[0] = CreateSimpNot(children[0]);
-       return CreateSimpXor(children); break;
-      }
-      case XOR: 
-       return CreateSimpXor(children); break;
-       // FIXME: Earlier, check that this only has two arguments
-      case IMPLIES: return CreateSimpAndOr(0, CreateSimpNot(children[0]), children[1]); break;
-      case ITE: return CreateSimpFormITE(children[0], children[1], children[2]);
-      default: return CreateNode(kind, children);
-      }
-    }
-  }
-
-  // specialized versions
-  
-  ASTNode BeevMgr::CreateSimpForm(Kind kind,
-                                 const ASTNode& child0) {
-    ASTVec children;
-    //child_stack.clear();     // could just reset top pointer.
-    children.push_back(child0);
-    //child_stack.push_back(child0);
-    return CreateSimpForm(kind, children);
-    //return CreateSimpForm(kind, child_stack);
-  }
-  
-  ASTNode BeevMgr::CreateSimpForm(Kind kind,
-                                 const ASTNode& child0,
-                                 const ASTNode& child1) {
-    ASTVec children;
-    //child_stack.clear();     // could just reset top pointer.
-    children.push_back(child0);
-    //child_stack.push_back(child0);
-    children.push_back(child1);
-    //child_stack.push_back(child1);
-    return CreateSimpForm(kind, children);
-    //return CreateSimpForm(kind, child_stack);
-  }
-  
-  
-  ASTNode BeevMgr::CreateSimpForm(Kind kind,
-                                 const ASTNode& child0,
-                                 const ASTNode& child1,
-                                 const ASTNode& child2) {
-    ASTVec children;
-    //child_stack.clear();     // could just reset top pointer.
-    children.push_back(child0);
-    //child_stack.push_back(child0);
-    children.push_back(child1);
-    //child_stack.push_back(child1);
-    children.push_back(child2);
-    //child_stack.push_back(child2);
-    return CreateSimpForm(kind, children);
-    //return CreateSimpForm(kind, child_stack);
-  }
-    
-  ASTNode BeevMgr::CreateSimpNot(const ASTNode& form) {
-    Kind k = form.GetKind();
-    switch (k) {
-    case FALSE: { return ASTTrue; }
-    case TRUE: { return ASTFalse; }
-    case NOT: { return form[0]; } // NOT NOT cancellation
-    case XOR: {
-      // Push negation down in this case.
-      // FIXME: Separate pre-pass to push negation down?
-      // CreateSimp should be local, and this isn't.  
-      // It isn't memoized.  Arg.
-      ASTVec children = form.GetChildren();
-      children[0] = CreateSimpNot(children[0]);
-      return CreateSimpXor(children);
-    }
-    default: { return CreateNode(NOT, form); }
-    }
-  }
-
-  // I don't think this is even called, since it called
-  // CreateSimpAndOr instead of CreateSimpXor until 1/9/07 with no
-  // ill effects.  Calls seem to go to the version that takes a vector
-  // of children.
-  ASTNode BeevMgr::CreateSimpXor(const ASTNode& form1, const ASTNode& form2) {
-    ASTVec children;
-    children.push_back(form1);
-    children.push_back(form2);
-    return CreateSimpXor(children);
-  }
-
-  // Flatten (k ... (k ci cj) ...) to (k ... ci cj ...)
-  // This is local to this file.
-  ASTVec FlattenKind(Kind k, ASTVec &children) {
-    
-    ASTVec flat_children;
-    
-    ASTVec::const_iterator ch_end = children.end();
-    
-    bool fflag = 0;            // ***Temp debugging
-    
-    // Experimental flattening code.
-    
-    for(ASTVec::iterator it = children.begin(); it != ch_end; it++) {
-      Kind ck = it->GetKind();
-      const ASTVec &gchildren = it->GetChildren();
-      if (k == ck) {
-       fflag = 1;              // For selective debug printing (below).
-       // append grandchildren to children
-       flat_children.insert(flat_children.end(), gchildren.begin(), gchildren.end());
-      }
-      else {
-       flat_children.push_back(*it);
-      }
-    }
-    
-    if (_trace_simpbool && fflag) {
-      cout << "========" << endl;
-      cout << "Flattening " << k << ":" << endl;
-      lpvec(children);
-      
-      cout << "--------" << endl;
-      cout << "Flattening result: " << endl;
-      lpvec(flat_children);
-    }
-
-    // FIXME: This unnecessarily copies the array.
-    return flat_children;
-  }
-
-  ASTNode BeevMgr::CreateSimpAndOr(bool IsAnd, const ASTNode& form1, const ASTNode& form2) {
-    ASTVec children;
-    children.push_back(form1);
-    children.push_back(form2);
-    return CreateSimpAndOr(IsAnd, children);
-  }
-
-  // FIXME: Could also handle (AND ... (NOT (OR ...) ...)
-  ASTNode BeevMgr::CreateSimpAndOr(bool IsAnd, ASTVec &children) {
-
-    Kind k = IsAnd ? AND : OR;
-
-    if (_trace_simpbool) {
-      cout << "========" << endl << "CreateSimpAndOr " << k << " ";
-      lpvec(children);
-      cout << endl;
-    }
-
-    ASTVec new_children;
-
-    ASTVec flat_children;
-    if (xor_flatten) {
-      flat_children = FlattenKind(k, children);
-    }
-    else {
-      flat_children = children;
-    }
-
-    // sort so that identical nodes occur in sequential runs, followed by
-    // their negations.
-    SortByExprNum(flat_children);
-    
-    ASTNode annihilator = (IsAnd ? ASTFalse : ASTTrue);
-    ASTNode identity = (IsAnd ? ASTTrue : ASTFalse);
-
-    ASTNode retval;
-
-    ASTVec::const_iterator it_end = flat_children.end();
-    ASTVec::const_iterator next_it;
-    for(ASTVec::const_iterator it = flat_children.begin(); it != it_end; it = next_it) {
-      next_it = it + 1;
-      bool nextexists = (next_it < it_end);
-
-      if (*it == annihilator) {
-       retval = annihilator;
-       if (_trace_simpbool) {
-         cout << "returns " << retval << endl;
+namespace BEEV
+{
+
+ASTNode BeevMgr::CreateSimpForm(Kind kind, ASTVec &children = _empty_ASTVec)
+{
+       if (_disable_simpbool)
+       {
+               return CreateNode(kind, children);
+       }
+       else
+       {
+               switch (kind)
+               {
+                       case NOT:
+                               return CreateSimpNot(children[0]);
+                               break;
+                       case AND:
+                               return CreateSimpAndOr(1, children);
+                               break;
+                       case OR:
+                               return CreateSimpAndOr(0, children);
+                               break;
+                       case NAND:
+                               return CreateSimpNot(CreateSimpAndOr(1, children));
+                               break;
+                       case NOR:
+                               return CreateSimpNot(CreateSimpAndOr(0, children));
+                               break;
+                       case IFF:
+                       {
+                               // Not sure children can ever be empty, but what the heck.
+                               //      if (children.size() == 0) {
+                               //        return ASTTrue;
+                               //      }
+                               // Convert IFF to XOR ASAP to simplify flattening.
+                               children[0] = CreateSimpNot(children[0]);
+                               return CreateSimpXor(children);
+                               break;
+                       }
+                       case XOR:
+                               return CreateSimpXor(children);
+                               break;
+                               // FIXME: Earlier, check that this only has two arguments
+                       case IMPLIES:
+                               return CreateSimpAndOr(0, CreateSimpNot(children[0]), children[1]);
+                               break;
+                       case ITE:
+                               return CreateSimpFormITE(children[0], children[1], children[2]);
+                       default:
+                               return CreateNode(kind, children);
+               }
+       }
+}
+
+// specialized versions
+
+ASTNode BeevMgr::CreateSimpForm(Kind kind, const ASTNode& child0)
+{
+       ASTVec children;
+       //child_stack.clear();  // could just reset top pointer.
+       children.push_back(child0);
+       //child_stack.push_back(child0);
+       return CreateSimpForm(kind, children);
+       //return CreateSimpForm(kind, child_stack);
+}
+
+ASTNode BeevMgr::CreateSimpForm(Kind kind, const ASTNode& child0, const ASTNode& child1)
+{
+       ASTVec children;
+       //child_stack.clear();  // could just reset top pointer.
+       children.push_back(child0);
+       //child_stack.push_back(child0);
+       children.push_back(child1);
+       //child_stack.push_back(child1);
+       return CreateSimpForm(kind, children);
+       //return CreateSimpForm(kind, child_stack);
+}
+
+ASTNode BeevMgr::CreateSimpForm(Kind kind, const ASTNode& child0, const ASTNode& child1, const ASTNode& child2)
+{
+       ASTVec children;
+       //child_stack.clear();  // could just reset top pointer.
+       children.push_back(child0);
+       //child_stack.push_back(child0);
+       children.push_back(child1);
+       //child_stack.push_back(child1);
+       children.push_back(child2);
+       //child_stack.push_back(child2);
+       return CreateSimpForm(kind, children);
+       //return CreateSimpForm(kind, child_stack);
+}
+
+ASTNode BeevMgr::CreateSimpNot(const ASTNode& form)
+{
+       Kind k = form.GetKind();
+       switch (k)
+       {
+               case FALSE:
+               {
+                       return ASTTrue;
+               }
+               case TRUE:
+               {
+                       return ASTFalse;
+               }
+               case NOT:
+               {
+                       return form[0];
+               } // NOT NOT cancellation
+               case XOR:
+               {
+                       // Push negation down in this case.
+                       // FIXME: Separate pre-pass to push negation down?
+                       // CreateSimp should be local, and this isn't.
+                       // It isn't memoized.  Arg.
+                       ASTVec children = form.GetChildren();
+                       children[0] = CreateSimpNot(children[0]);
+                       return CreateSimpXor(children);
+               }
+               default:
+               {
+                       return CreateNode(NOT, form);
+               }
+       }
+}
+
+// I don't think this is even called, since it called
+// CreateSimpAndOr instead of CreateSimpXor until 1/9/07 with no
+// ill effects.  Calls seem to go to the version that takes a vector
+// of children.
+ASTNode BeevMgr::CreateSimpXor(const ASTNode& form1, const ASTNode& form2)
+{
+       ASTVec children;
+       children.push_back(form1);
+       children.push_back(form2);
+       return CreateSimpXor(children);
+}
+
+// Flatten (k ... (k ci cj) ...) to (k ... ci cj ...)
+// This is local to this file.
+ASTVec FlattenKind(Kind k, ASTVec &children)
+{
+
+       ASTVec flat_children;
+
+       ASTVec::const_iterator ch_end = children.end();
+
+       bool fflag = 0; // ***Temp debugging
+
+       // Experimental flattening code.
+
+       for (ASTVec::iterator it = children.begin(); it != ch_end; it++)
+       {
+               Kind ck = it->GetKind();
+               const ASTVec &gchildren = it->GetChildren();
+               if (k == ck)
+               {
+                       fflag = 1; // For selective debug printing (below).
+                       // append grandchildren to children
+                       flat_children.insert(flat_children.end(), gchildren.begin(), gchildren.end());
+               }
+               else
+               {
+                       flat_children.push_back(*it);
+               }
+       }
+
+       if (_trace_simpbool && fflag)
+       {
+               cout << "========" << endl;
+               cout << "Flattening " << k << ":" << endl;
+               lpvec(children);
+
+               cout << "--------" << endl;
+               cout << "Flattening result: " << endl;
+               lpvec(flat_children);
+       }
+
+       // FIXME: This unnecessarily copies the array.
+       return flat_children;
+}
+
+ASTNode BeevMgr::CreateSimpAndOr(bool IsAnd, const ASTNode& form1, const ASTNode& form2)
+{
+       ASTVec children;
+       children.push_back(form1);
+       children.push_back(form2);
+       return CreateSimpAndOr(IsAnd, children);
+}
+
+// FIXME: Could also handle (AND ... (NOT (OR ...) ...)
+ASTNode BeevMgr::CreateSimpAndOr(bool IsAnd, ASTVec &children)
+{
+
+       Kind k = IsAnd ? AND : OR;
+
+       if (_trace_simpbool)
+       {
+               cout << "========" << endl << "CreateSimpAndOr " << k << " ";
+               lpvec(children);
+               cout << endl;
+       }
+
+       ASTVec new_children;
+
+       ASTVec flat_children;
+       if (xor_flatten)
+       {
+               flat_children = FlattenKind(k, children);
+       }
+       else
+       {
+               flat_children = children;
+       }
+
+       // sort so that identical nodes occur in sequential runs, followed by
+       // their negations.
+       SortByExprNum(flat_children);
+
+       ASTNode annihilator = (IsAnd ? ASTFalse : ASTTrue);
+       ASTNode identity = (IsAnd ? ASTTrue : ASTFalse);
+
+       ASTNode retval;
+
+       ASTVec::const_iterator it_end = flat_children.end();
+       ASTVec::const_iterator next_it;
+       for (ASTVec::const_iterator it = flat_children.begin(); it != it_end; it = next_it)
+       {
+               next_it = it + 1;
+               bool nextexists = (next_it < it_end);
+
+               if (*it == annihilator)
+               {
+                       retval = annihilator;
+                       if (_trace_simpbool)
+                       {
+                               cout << "returns " << retval << endl;
+                       }
+                       return retval;
+               }
+               else if (*it == identity)
+               {
+                       // just drop it
+               }
+               else if (nextexists && (*next_it == *it))
+               {
+                       // drop it
+                       //      cout << "Dropping [" << it->GetNodeNum() << "]" << endl;
+               }
+               else if (nextexists && (next_it->GetKind() == NOT) && ((*next_it)[0] == *it))
+               {
+                       // form and negation -- return FALSE for AND, TRUE for OR.
+                       retval = annihilator;
+                       // cout << "X and/or NOT X" << endl;
+                       if (_trace_simpbool)
+                       {
+                               cout << "returns " << retval << endl;
+                       }
+                       return retval;
+               }
+               else
+               {
+                       // add to children
+                       new_children.push_back(*it);
+               }
+       }
+
+       // If we get here, we saw no annihilators, and children should
+       // be only the non-True nodes.
+       if (new_children.size() < 2)
+       {
+               if (0 == new_children.size())
+               {
+                       retval = identity;
+               }
+               else
+               {
+                       // there is just one child
+                       retval = new_children[0];
+               }
+       }
+       else
+       {
+               // 2 or more children.  Create a new node.
+               retval = CreateNode(IsAnd ? AND : OR, new_children);
+       }
+       if (_trace_simpbool)
+       {
+               cout << "returns " << retval << endl;
        }
        return retval;
-      }
-      else if (*it == identity) {
-       // just drop it
-      }
-      else if (nextexists && (*next_it == *it)) {
-       // drop it
-       //      cout << "Dropping [" << it->GetNodeNum() << "]" << endl;
-      }
-      else if (nextexists && (next_it->GetKind() == NOT) && ((*next_it)[0] == *it)) {
-       // form and negation -- return FALSE for AND, TRUE for OR.
-       retval = annihilator;
-       // cout << "X and/or NOT X" << endl; 
-       if (_trace_simpbool) {
-         cout << "returns " << retval << endl;
+}
+
+// Constant children are accumulated in "accumconst".
+ASTNode BeevMgr::CreateSimpXor(ASTVec &children)
+{
+
+       if (_trace_simpbool)
+       {
+               cout << "========" << endl << "CreateSimpXor ";
+               lpvec(children);
+               cout << endl;
+       }
+
+       ASTVec flat_children; // empty vector
+       ASTVec::const_iterator it_end = children.end();
+
+       if (xor_flatten)
+       {
+               flat_children = FlattenKind(XOR, children);
+       }
+       else
+       {
+               flat_children = children;
+       }
+
+       // sort so that identical nodes occur in sequential runs, followed by
+       // their negations.
+       SortByExprNum(flat_children);
+
+       ASTNode retval;
+
+       // This is the C Boolean value of all constant args seen.  It is initially
+       // 0.  TRUE children cause it to change value.
+       bool accumconst = 0;
+
+       ASTVec new_children;
+
+       it_end = flat_children.end();
+       ASTVec::iterator next_it;
+       for (ASTVec::iterator it = flat_children.begin(); it != it_end; it++)
+       {
+               next_it = it + 1;
+               bool nextexists = (next_it < it_end);
+
+               if (ASTTrue == *it)
+               {
+                       accumconst = !accumconst;
+               }
+               else if (ASTFalse == *it)
+               {
+                       // Ignore it
+               }
+               else if (nextexists && (*next_it == *it))
+               {
+                       // x XOR x = FALSE.  Skip current, write "false" into next_it
+                       // so that it gets tossed, too.
+                       *next_it = ASTFalse;
+               }
+               else if (nextexists && (next_it->GetKind() == NOT) && ((*next_it)[0] == *it))
+               {
+                       // x XOR NOT x = TRUE.  Skip current, write "true" into next_it
+                       // so that it gets tossed, too.
+                       *next_it = ASTTrue;
+               }
+               else if (NOT == it->GetKind())
+               {
+                       // If child is (NOT alpha), we can flip accumconst and use alpha.
+                       // This is ok because (NOT alpha) == TRUE XOR alpha
+                       accumconst = !accumconst;
+                       // CreateSimpNot just takes child of not.
+                       new_children.push_back(CreateSimpNot(*it));
+               }
+               else
+               {
+                       new_children.push_back(*it);
+               }
+       }
+
+       // Children should be non-constant.
+       if (new_children.size() < 2)
+       {
+               if (0 == new_children.size())
+               {
+                       // XOR(TRUE, FALSE) -- accumconst will be 1.
+                       if (accumconst)
+                       {
+                               retval = ASTTrue;
+                       }
+                       else
+                       {
+                               retval = ASTFalse;
+                       }
+               }
+               else
+               {
+                       // there is just one child
+                       // XOR(x, TRUE) -- accumconst will be 1.
+                       if (accumconst)
+                       {
+                               retval = CreateSimpNot(new_children[0]);
+                       }
+                       else
+                       {
+                               retval = new_children[0];
+                       }
+               }
+       }
+       else
+       {
+               // negate first child if accumconst == 1
+               if (accumconst)
+               {
+                       new_children[0] = CreateSimpNot(new_children[0]);
+               }
+               retval = CreateNode(XOR, new_children);
+       }
+
+       if (_trace_simpbool)
+       {
+               cout << "returns " << retval << endl;
        }
        return retval;
-      }
-      else {
-       // add to children
-       new_children.push_back(*it);
-      }
-    }
-
-    // If we get here, we saw no annihilators, and children should
-    // be only the non-True nodes.
-    if (new_children.size() < 2) {
-      if (0 == new_children.size()) {
-       retval = identity;
-      }
-      else {
-       // there is just one child
-       retval = new_children[0];
-      }
-    }
-    else {
-      // 2 or more children.  Create a new node.
-      retval = CreateNode(IsAnd ? AND : OR, new_children);
-    }
-    if (_trace_simpbool) {
-      cout << "returns " << retval << endl;
-    }
-    return retval;
-  }
-
-  // Constant children are accumulated in "accumconst".  
-  ASTNode BeevMgr::CreateSimpXor(ASTVec &children) {
-
-    if (_trace_simpbool) {
-      cout << "========" << endl
-          << "CreateSimpXor ";
-      lpvec(children);
-      cout << endl;
-    }
-
-    ASTVec flat_children;              // empty vector
-    ASTVec::const_iterator it_end = children.end();
-
-    if (xor_flatten) {
-      flat_children = FlattenKind(XOR, children);
-    }
-    else {
-      flat_children = children;
-    }
-
-    // sort so that identical nodes occur in sequential runs, followed by
-    // their negations.
-    SortByExprNum(flat_children);
-
-    ASTNode retval;
-
-    // This is the C Boolean value of all constant args seen.  It is initially
-    // 0.  TRUE children cause it to change value.
-    bool accumconst = 0;
-
-    ASTVec new_children;
-
-    it_end = flat_children.end();
-    ASTVec::iterator next_it;
-    for(ASTVec::iterator it = flat_children.begin(); it != it_end; it++) {
-      next_it = it + 1;
-      bool nextexists = (next_it < it_end);
-
-      if (ASTTrue == *it) {
-       accumconst = !accumconst;
-      }
-      else if (ASTFalse == *it) {
-       // Ignore it
-      }
-      else if (nextexists && (*next_it == *it)) {
-       // x XOR x = FALSE.  Skip current, write "false" into next_it
-       // so that it gets tossed, too.
-       *next_it = ASTFalse;
-      }
-      else if (nextexists && (next_it->GetKind() == NOT) && ((*next_it)[0] == *it)) {
-       // x XOR NOT x = TRUE.  Skip current, write "true" into next_it
-       // so that it gets tossed, too.
-       *next_it = ASTTrue;
-      }
-      else if (NOT == it->GetKind()) {
-       // If child is (NOT alpha), we can flip accumconst and use alpha.
-       // This is ok because (NOT alpha) == TRUE XOR alpha
-       accumconst = !accumconst;
-       // CreateSimpNot just takes child of not.
-       new_children.push_back(CreateSimpNot(*it));
-      }
-      else {
-       new_children.push_back(*it);
-      }
-    }
-
-    // Children should be non-constant.
-    if (new_children.size() < 2) {
-      if (0 == new_children.size()) {
-       // XOR(TRUE, FALSE) -- accumconst will be 1.
-       if (accumconst) {
-         retval = ASTTrue;
+}
+
+// FIXME:  How do I know whether ITE is a formula or not?
+ASTNode BeevMgr::CreateSimpFormITE(const ASTNode& child0, const ASTNode& child1, const ASTNode& child2)
+{
+
+       ASTNode retval;
+
+       if (_trace_simpbool)
+       {
+               cout << "========" << endl << "CreateSimpFormITE " << child0 << child1 << child2 << endl;
+       }
+
+       if (ASTTrue == child0)
+       {
+               retval = child1;
+       }
+       else if (ASTFalse == child0)
+       {
+               retval = child2;
+       }
+       else if (child1 == child2)
+       {
+               retval = child1;
+       }
+       // ITE(x, TRUE, y ) == x OR y
+       else if (ASTTrue == child1)
+       {
+               retval = CreateSimpAndOr(0, child0, child2);
        }
-       else {
-         retval = ASTFalse;
+       // ITE(x, FALSE, y ) == (!x AND y)
+       else if (ASTFalse == child1)
+       {
+               retval = CreateSimpAndOr(1, CreateSimpNot(child0), child2);
        }
-      }
-      else {
-       // there is just one child
-       // XOR(x, TRUE) -- accumconst will be 1.
-       if (accumconst) {
-         retval =  CreateSimpNot(new_children[0]);
+       // ITE(x, y, TRUE ) == (!x OR y)
+       else if (ASTTrue == child2)
+       {
+               retval = CreateSimpAndOr(0, CreateSimpNot(child0), child1);
        }
-       else {
-         retval = new_children[0];
+       // ITE(x, y, FALSE ) == (x AND y)
+       else if (ASTFalse == child2)
+       {
+               retval = CreateSimpAndOr(1, child0, child1);
        }
-      }
-    }
-    else {
-      // negate first child if accumconst == 1
-      if (accumconst) {
-       new_children[0] = CreateSimpNot(new_children[0]);
-      }
-      retval = CreateNode(XOR, new_children);
-    }
-
-    if (_trace_simpbool) {    
-      cout << "returns " << retval << endl;
-    }
-    return retval;
-  }
-
-  // FIXME:  How do I know whether ITE is a formula or not?
-  ASTNode BeevMgr::CreateSimpFormITE(const ASTNode& child0,
-                                    const ASTNode& child1,
-                                    const ASTNode& child2) {
-
-    ASTNode retval;
-    
-    if (_trace_simpbool) {
-      cout << "========" << endl << "CreateSimpFormITE "
-          << child0 
-          << child1 
-          << child2 << endl;
-    }
-
-    if (ASTTrue == child0) {
-      retval = child1;
-    }
-    else if (ASTFalse == child0) {
-      retval = child2;
-    }
-    else if (child1 == child2) {
-      retval = child1;
-    }    
-    // ITE(x, TRUE, y ) == x OR y
-    else if (ASTTrue == child1) {
-      retval = CreateSimpAndOr(0, child0, child2);
-    }
-    // ITE(x, FALSE, y ) == (!x AND y)
-    else if (ASTFalse == child1) {
-      retval = CreateSimpAndOr(1, CreateSimpNot(child0), child2); 
-    }
-    // ITE(x, y, TRUE ) == (!x OR y)
-    else if (ASTTrue == child2) {
-      retval = CreateSimpAndOr(0, CreateSimpNot(child0), child1); 
-    }
-    // ITE(x, y, FALSE ) == (x AND y)
-    else if (ASTFalse == child2) {
-      retval = CreateSimpAndOr(1, child0, child1); 
-    }
-    // ITE (x, !y, y) == x XOR y
-//     else if (NOT == child1.GetKind() && (child1[0] == child2)) {
-//       retval = CreateSimpXor(child0, child2);
-//     }
-//     // ITE (x, y, !y) == x IFF y.  I think other cases are covered
-//     // by XOR/IFF optimizations
-//     else if (NOT == child2.GetKind() && (child2[0] == child1)) {
-//       retval = CreateSimpXor(CreateSimpNot(child0), child2);
-//     }
-    else {
-      retval = CreateNode(ITE, child0, child1, child2);
-    }
-
-    if (_trace_simpbool) {
-      cout << "returns " << retval << endl;
-    }
-
-    return retval;
-  }
+       // ITE (x, !y, y) == x XOR y
+       //     else if (NOT == child1.GetKind() && (child1[0] == child2)) {
+       //       retval = CreateSimpXor(child0, child2);
+       //     }
+       //     // ITE (x, y, !y) == x IFF y.  I think other cases are covered
+       //     // by XOR/IFF optimizations
+       //     else if (NOT == child2.GetKind() && (child2[0] == child1)) {
+       //       retval = CreateSimpXor(CreateSimpNot(child0), child2);
+       //     }
+       else
+       {
+               retval = CreateNode(ITE, child0, child1, child2);
+       }
+
+       if (_trace_simpbool)
+       {
+               cout << "returns " << retval << endl;
+       }
+
+       return retval;
+}
 } // BEEV namespace
index d66a7d0a4ab03431bbb82d7b260feba1a5bebbf1..672fd4017e2a0c393d9b29abc116bf9e13a577d4 100644 (file)
 #include "AST.h"
 #include "../simplifier/bvsolver.h"
 
-namespace BEEV {
+namespace BEEV
+{
 
-class CNFMgr {
+class CNFMgr
+{
 
 public:
 
-   //########################################
-   //########################################
-   // constructor
+       //########################################
+       //########################################
+       // constructor
 
-   CNFMgr(BeevMgr *bmgr){
-      bm = bmgr;
-   }
+       CNFMgr(BeevMgr *bmgr)
+       {
+               bm = bmgr;
+       }
 
-   //########################################
-   //########################################
-   // destructor
+       //########################################
+       //########################################
+       // destructor
 
-   ~CNFMgr(){
-      ASTNodeToASTNodePtrMap::const_iterator it1 = store.begin();
-      for(; it1 != store.end(); it1++){
-         delete it1->second;
-      }
+       ~CNFMgr()
+       {
+               ASTNodeToASTNodePtrMap::const_iterator it1 = store.begin();
+               for (; it1 != store.end(); it1++)
+               {
+                       delete it1->second;
+               }
 
-      store.clear();
+               store.clear();
 
-   }
+       }
 
-   //########################################
-   //########################################
-   // top-level conversion function
+       //########################################
+       //########################################
+       // top-level conversion function
+
+       BeevMgr::ClauseList* convertToCNF(const ASTNode& varphi)
+       {
+               scanFormula(varphi, true);
+               ASTNode dummy_true_var = bm->CreateSymbol("*TrueDummy*");
+               BeevMgr::ClauseList* defs = SINGLETON(dummy_true_var);
+               convertFormulaToCNF(varphi, defs);
+               BeevMgr::ClauseList* top = info[varphi]->clausespos;
+               defs->insert(defs->begin() + 1, top->begin(), top->end());
+
+               cleanup(varphi);
+               return defs;
+       }
 
-   BeevMgr::ClauseList* convertToCNF(const ASTNode& varphi){
-      scanFormula(varphi, true);
-      ASTNode dummy_true_var = bm->CreateSymbol("*TrueDummy*");
-      BeevMgr::ClauseList* defs = SINGLETON(dummy_true_var);
-      convertFormulaToCNF(varphi, defs);
-      BeevMgr::ClauseList* top = info[varphi]->clausespos;
-      defs->insert(defs->begin() + 1, top->begin(), top->end());
+       void DELETE(BeevMgr::ClauseList* varphi)
+       {
+               BeevMgr::ClauseList::const_iterator it = varphi->begin();
+               for (; it != varphi->end(); it++)
+               {
+                       delete *it;
+               }
 
-      cleanup(varphi);
-      return defs;
-   }
+               delete varphi;
+       }
 
-   void DELETE(BeevMgr::ClauseList* varphi){
-      BeevMgr::ClauseList::const_iterator it = varphi->begin();
-      for(; it != varphi->end(); it++){
-         delete *it;
-      }
+private:
 
-      delete varphi;
-   }
+       //########################################
+       //########################################
+       // data types
+
+       // for the meaning of control bits, see "utilities for contol bits".
+       typedef struct
+       {
+               int control;
+               BeevMgr::ClauseList* clausespos;
+               union
+               {
+                       BeevMgr::ClauseList* clausesneg;
+                       ASTNode* termforcnf;
+               };
+       } CNFInfo;
+
+       typedef hash_map<ASTNode, CNFInfo*, ASTNode::ASTNodeHasher, ASTNode::ASTNodeEqual> ASTNodeToCNFInfoMap;
+
+       typedef hash_map<ASTNode, ASTNode*, ASTNode::ASTNodeHasher, ASTNode::ASTNodeEqual> ASTNodeToASTNodePtrMap;
+
+       //########################################
+       //########################################
+       // this is the data
+
+       BeevMgr *bm;
+       ASTNodeToCNFInfoMap info;
+       ASTNodeToASTNodePtrMap store;
+
+       //########################################
+       //########################################
+       // utility predicates
+
+       bool isAtom(const ASTNode& varphi)
+       {
+               bool result;
+
+               Kind k = varphi.GetKind();
+               switch (k)
+               {
+                       case TRUE:
+                       {
+                               result = true;
+                               break;
+                       }
+                       case FALSE:
+                       {
+                               result = true;
+                               break;
+                       }
+                       case SYMBOL:
+                       {
+                               result = true;
+                               break;
+                       }
+                       case BVCONST:
+                       {
+                               result = true;
+                               break;
+                       }
+                       default:
+                       {
+                               result = false;
+                               break;
+                       }
+               }
+
+               return result;
+       }
 
-private:
+       bool isPred(const ASTNode& varphi)
+       {
+               bool result;
+
+               Kind k = varphi.GetKind();
+               switch (k)
+               {
+                       case BVLT:
+                       {
+                               result = true;
+                               break;
+                       }
+                       case BVLE:
+                       {
+                               result = true;
+                               break;
+                       }
+                       case BVGT:
+                       {
+                               result = true;
+                               break;
+                       }
+                       case BVGE:
+                       {
+                               result = true;
+                               break;
+                       }
+                       case BVSLT:
+                       {
+                               result = true;
+                               break;
+                       }
+                       case BVSLE:
+                       {
+                               result = true;
+                               break;
+                       }
+                       case BVSGT:
+                       {
+                               result = true;
+                               break;
+                       }
+                       case BVSGE:
+                       {
+                               result = true;
+                               break;
+                       }
+                       case EQ:
+                       {
+                               result = true;
+                               break;
+                       }
+                       case NEQ:
+                       {
+                               result = true;
+                               break;
+                       }
+                       default:
+                       {
+                               result = false;
+                               break;
+                       }
+               }
+
+               return result;
+       }
+
+       bool isITE(const ASTNode& varphi)
+       {
+               bool result;
+
+               Kind k = varphi.GetKind();
+               switch (k)
+               {
+                       case ITE:
+                       {
+                               result = true;
+                               break;
+                       }
+                       default:
+                       {
+                               result = false;
+                               break;
+                       }
+               }
+
+               return result;
+       }
+
+       bool onChildDoPos(const ASTNode& varphi, unsigned int idx)
+       {
+               bool result = true;
+
+               Kind k = varphi.GetKind();
+               switch (k)
+               {
+                       case NOT:
+                       {
+                               result = false;
+                               break;
+                       }
+                       case NAND:
+                       {
+                               result = false;
+                               break;
+                       }
+                       case NOR:
+                       {
+                               result = false;
+                               break;
+                       }
+                       case IMPLIES:
+                       {
+                               if (idx == 0)
+                               {
+                                       result = false;
+                               }
+                               break;
+                       }
+                       default:
+                       {
+                               break;
+                       }
+               }
+
+               return result;
+       }
+
+       bool onChildDoNeg(const ASTNode& varphi, unsigned int idx)
+       {
+               bool result = false;
+
+               Kind k = varphi.GetKind();
+               switch (k)
+               {
+                       case NOT:
+                       {
+                               result = true;
+                               break;
+                       }
+                       case NAND:
+                       {
+                               result = true;
+                               break;
+                       }
+                       case NOR:
+                       {
+                               result = true;
+                               break;
+                       }
+                       case XOR:
+                       {
+                               result = true;
+                               break;
+                       }
+                       case IFF:
+                       {
+                               result = true;
+                               break;
+                       }
+                       case IMPLIES:
+                       {
+                               if (idx == 0)
+                               {
+                                       result = true;
+                               }
+                               break;
+                       }
+                       case ITE:
+                       {
+                               if (idx == 0)
+                               {
+                                       result = true;
+                               }
+                               break;
+                       }
+                       default:
+                       {
+                               break;
+                       }
+               }
+
+               return result;
+       }
+
+       //########################################
+       //########################################
+       //utilities for control bits.
+
+       void initializeCNFInfo(CNFInfo& x)
+       {
+               x.control = 0;
+               x.clausespos = NULL;
+               x.clausesneg = NULL;
+       }
+
+       void incrementSharesPos(CNFInfo& x)
+       {
+               x.control += ((x.control & 3) < 2) ? 1 : 0;
+       }
+
+       int sharesPos(CNFInfo& x)
+       {
+               return (x.control & 3);
+       }
+
+       void incrementSharesNeg(CNFInfo& x)
+       {
+               x.control += ((x.control & 12) < 8) ? 4 : 0;
+       }
+
+       int sharesNeg(CNFInfo& x)
+       {
+               return ((x.control & 12) >> 2);
+       }
+
+       void setControlBit(CNFInfo& x, unsigned int idx)
+       {
+               x.control |= (1 << idx);
+       }
+
+       bool getControlBit(CNFInfo& x, unsigned int idx)
+       {
+               bool result = false;
+
+               if (x.control & (1 << idx))
+               {
+
+                       result = true;
+               }
+
+               return result;
+       }
+
+       void setIsTerm(CNFInfo& x)
+       {
+               setControlBit(x, 4);
+       }
+
+       bool isTerm(CNFInfo& x)
+       {
+               return getControlBit(x, 4);
+       }
+
+       void setDoRenamePos(CNFInfo& x)
+       {
+               setControlBit(x, 5);
+       }
+
+       bool doRenamePos(CNFInfo& x)
+       {
+               return getControlBit(x, 5);
+       }
+
+       void setWasRenamedPos(CNFInfo& x)
+       {
+               setControlBit(x, 6);
+       }
+
+       bool wasRenamedPos(CNFInfo& x)
+       {
+               return getControlBit(x, 6);
+       }
+
+       void setDoRenameNeg(CNFInfo& x)
+       {
+               setControlBit(x, 7);
+       }
+
+       bool doRenameNeg(CNFInfo& x)
+       {
+               return getControlBit(x, 7);
+       }
+
+       void setWasRenamedNeg(CNFInfo& x)
+       {
+               setControlBit(x, 8);
+       }
+
+       bool wasRenamedNeg(CNFInfo& x)
+       {
+               return getControlBit(x, 8);
+       }
+
+       void setDoSibRenamingPos(CNFInfo& x)
+       {
+               setControlBit(x, 9);
+       }
+
+       bool doSibRenamingPos(CNFInfo& x)
+       {
+               return getControlBit(x, 9);
+       }
+
+       void setDoSibRenamingNeg(CNFInfo& x)
+       {
+               setControlBit(x, 10);
+       }
+
+       bool doSibRenamingNeg(CNFInfo& x)
+       {
+               return getControlBit(x, 10);
+       }
+
+       void setWasVisited(CNFInfo& x)
+       {
+               setControlBit(x, 11);
+       }
+
+       bool wasVisited(CNFInfo& x)
+       {
+               return getControlBit(x, 11);
+       }
+
+       //########################################
+       //########################################
+       //utilities for clause sets
+
+
+       BeevMgr::ClauseList* COPY(const BeevMgr::ClauseList& varphi)
+       {
+               BeevMgr::ClauseList* psi = new BeevMgr::ClauseList();
+
+               BeevMgr::ClauseList::const_iterator it = varphi.begin();
+               for (; it != varphi.end(); it++)
+               {
+                       psi->push_back(new vector<const ASTNode*> (**it));
+               }
+
+               return psi;
+       }
+
+       BeevMgr::ClauseList* SINGLETON(const ASTNode& varphi)
+       {
+               ASTNode* copy = ASTNodeToASTNodePtr(varphi);
+
+               BeevMgr::ClausePtr clause = new vector<const ASTNode*> ();
+               clause->push_back(copy);
+
+               BeevMgr::ClauseList* psi = new BeevMgr::ClauseList();
+               psi->push_back(clause);
+               return psi;
+       }
+
+       BeevMgr::ClauseList* UNION(const BeevMgr::ClauseList& varphi1, const BeevMgr::ClauseList& varphi2)
+       {
+
+               BeevMgr::ClauseList* psi1 = COPY(varphi1);
+               BeevMgr::ClauseList* psi2 = COPY(varphi2);
+               psi1->insert(psi1->end(), psi2->begin(), psi2->end());
+               delete psi2;
+
+               return psi1;
+
+       }
+
+       void INPLACE_UNION(BeevMgr::ClauseList* varphi1, const BeevMgr::ClauseList& varphi2)
+       {
+
+               BeevMgr::ClauseList* psi2 = COPY(varphi2);
+               varphi1->insert(varphi1->end(), psi2->begin(), psi2->end());
+               delete psi2;
+       }
+
+       void NOCOPY_INPLACE_UNION(BeevMgr::ClauseList* varphi1, BeevMgr::ClauseList* varphi2)
+       {
+
+               varphi1->insert(varphi1->end(), varphi2->begin(), varphi2->end());
+               delete varphi2;
+       }
+
+       BeevMgr::ClauseList* PRODUCT(const BeevMgr::ClauseList& varphi1, const BeevMgr::ClauseList& varphi2)
+       {
+
+               BeevMgr::ClauseList* psi = new BeevMgr::ClauseList();
+
+               BeevMgr::ClauseList::const_iterator it1 = varphi1.begin();
+               for (; it1 != varphi1.end(); it1++)
+               {
+                       BeevMgr::ClausePtr clause1 = *it1;
+                       BeevMgr::ClauseList::const_iterator it2 = varphi2.begin();
+                       for (; it2 != varphi2.end(); it2++)
+                       {
+                               BeevMgr::ClausePtr clause2 = *it2;
+                               BeevMgr::ClausePtr clause = new vector<const ASTNode*> ();
+                               clause->insert(clause->end(), clause1->begin(), clause1->end());
+                               clause->insert(clause->end(), clause2->begin(), clause2->end());
+                               psi->push_back(clause);
+                       }
+               }
+
+               return psi;
+       }
+
+       //########################################
+       //########################################
+       //prep. for cnf conversion
+
+       void scanFormula(const ASTNode& varphi, bool isPos)
+       {
+
+               CNFInfo* x;
+
+               //########################################
+               // step 1, get the info associated with this node
+               //########################################
+
+               if (info.find(varphi) == info.end())
+               {
+                       x = new CNFInfo();
+                       initializeCNFInfo(*x);
+                       info[varphi] = x;
+               }
+               else
+               {
+                       x = info[varphi];
+               }
+
+               //########################################
+               // step 2, we only need to know if shares >= 2
+               //########################################
+
+               if (isPos && sharesPos(*x) == 2)
+               {
+                       return;
+               }
+
+               if (!isPos && sharesNeg(*x) == 2)
+               {
+                       return;
+               }
+
+               //########################################
+               // step 3, set appropriate information fields
+               //########################################
+
+               if (isPos)
+               {
+                       incrementSharesPos(*x);
+               }
+
+               if (!isPos)
+               {
+                       incrementSharesNeg(*x);
+               }
+
+               //########################################
+               // step 4, recurse over children
+               //########################################
+
+               if (isAtom(varphi))
+               {
+                       return;
+               }
+               else if (isPred(varphi))
+               {
+                       for (unsigned int i = 0; i < varphi.GetChildren().size(); i++)
+                       {
+                               scanTerm(varphi[i]);
+                       }
+               }
+               else
+               {
+                       for (unsigned int i = 0; i < varphi.GetChildren().size(); i++)
+                       {
+                               if (onChildDoPos(varphi, i))
+                               {
+                                       scanFormula(varphi[i], isPos);
+                               }
+                               if (onChildDoNeg(varphi, i))
+                               {
+                                       scanFormula(varphi[i], !isPos);
+                               }
+                       }
+               }
+       }
+
+       void scanTerm(const ASTNode& varphi)
+       {
+
+               CNFInfo* x;
+
+               //########################################
+               // step 1, get the info associated with this node
+               //########################################
+
+               if (info.find(varphi) == info.end())
+               {
+                       x = new CNFInfo();
+                       initializeCNFInfo(*x);
+                       info[varphi] = x;
+               }
+               else
+               {
+                       x = info[varphi];
+               }
+
+               //########################################
+               // step 2, need two hits because of term ITEs.
+               //########################################
+
+               if (sharesPos(*x) == 2)
+               {
+                       return;
+               }
+
+               //########################################
+               // step 3, set appropriate data fields, always rename
+               // term ITEs
+               //########################################
+
+               incrementSharesPos(*x);
+               setIsTerm(*x);
+
+               //########################################
+               // step 4, recurse over children
+               //########################################
+
+               if (isAtom(varphi))
+               {
+                       return;
+               }
+               else if (isITE(varphi))
+               {
+                       scanFormula(varphi[0], true);
+                       scanFormula(varphi[0], false);
+                       scanTerm(varphi[1]);
+                       scanTerm(varphi[2]);
+               }
+               else
+               {
+                       for (unsigned int i = 0; i < varphi.GetChildren().size(); i++)
+                       {
+                               scanTerm(varphi[i]);
+                       }
+               }
+       }
+
+       //########################################
+       //########################################
+       // main cnf conversion function
+
+       void convertFormulaToCNF(const ASTNode& varphi, BeevMgr::ClauseList* defs)
+       {
+
+               CNFInfo* x = info[varphi];
+
+               //########################################
+               // divert to special case if term (word-level cnf)
+
+               if (isTerm(*x))
+               {
+                       convertTermForCNF(varphi, defs);
+                       setWasVisited(*x);
+                       return;
+               }
+
+               //########################################
+               // do work
+
+               if (sharesPos(*x) > 0 && !wasVisited(*x))
+               {
+                       convertFormulaToCNFPosCases(varphi, defs);
+               }
+
+               if (x->clausespos != NULL && x->clausespos->size() > 1)
+               {
+                       if (doSibRenamingPos(*x) || sharesPos(*x) > 1)
+                       {
+                               doRenamingPos(varphi, defs);
+                       }
+               }
+
+               if (sharesNeg(*x) > 0 && !wasVisited(*x))
+               {
+                       convertFormulaToCNFNegCases(varphi, defs);
+               }
+
+               if (x->clausesneg != NULL && x->clausesneg->size() > 1)
+               {
+                       if (doSibRenamingNeg(*x) || sharesNeg(*x) > 1)
+                       {
+                               doRenamingNeg(varphi, defs);
+                       }
+               }
+
+               //########################################
+               //mark that we've already done the hard work
+
+               setWasVisited(*x);
+       }
+
+       void convertTermForCNF(const ASTNode& varphi, BeevMgr::ClauseList* defs)
+       {
+
+               CNFInfo* x = info[varphi];
+
+               //########################################
+               // step 1, done if we've already visited
+               //########################################
+
+               if (x->termforcnf != NULL)
+               {
+                       return;
+               }
+
+               //########################################
+               // step 2, ITE's always get renamed
+               //########################################
+
+               if (isITE(varphi))
+               {
+                       x->termforcnf = doRenameITE(varphi, defs);
+                       reduceMemoryFootprintPos(varphi[0]);
+                       reduceMemoryFootprintNeg(varphi[0]);
+
+               }
+               else if (isAtom(varphi))
+               {
+                       x->termforcnf = ASTNodeToASTNodePtr(varphi);
+               }
+               else
+               {
+
+                       ASTVec psis;
+                       ASTVec::const_iterator it = varphi.GetChildren().begin();
+                       for (; it != varphi.GetChildren().end(); it++)
+                       {
+                               convertTermForCNF(*it, defs);
+                               psis.push_back(*(info[*it]->termforcnf));
+                       }
+
+                       ASTNode psi = bm->CreateNode(varphi.GetKind(), psis);
+                       psi.SetValueWidth(varphi.GetValueWidth());
+                       psi.SetIndexWidth(varphi.GetIndexWidth());
+                       x->termforcnf = ASTNodeToASTNodePtr(psi);
+               }
+       }
+
+       //########################################
+       //########################################
+       // functions for renaming nodes during cnf conversion
+
+       ASTNode* doRenameITE(const ASTNode& varphi, BeevMgr::ClauseList* defs)
+       {
+
+               ASTNode psi;
+
+               //########################################
+               // step 1, old "RepLit" code
+               //########################################
+
+               ostringstream oss;
+               oss << "cnf" << "{" << varphi.GetNodeNum() << "}";
+               psi = bm->CreateSymbol(oss.str().c_str());
+
+               //########################################
+               // step 2, set widths appropriately
+               //########################################
 
-   //########################################
-   //########################################
-   // data types
-
-   // for the meaning of control bits, see "utilities for contol bits".
-   typedef struct {
-       int control; 
-       BeevMgr::ClauseList* clausespos;
-       union {BeevMgr::ClauseList* clausesneg; ASTNode* termforcnf;};
-    } CNFInfo;
-
-   typedef hash_map< ASTNode
-            , CNFInfo*
-            , ASTNode::ASTNodeHasher
-            , ASTNode::ASTNodeEqual
-      > ASTNodeToCNFInfoMap;
-
-   typedef hash_map< ASTNode
-            , ASTNode*
-            , ASTNode::ASTNodeHasher
-            , ASTNode::ASTNodeEqual
-      > ASTNodeToASTNodePtrMap;
-
-
-   //########################################
-   //########################################
-   // this is the data
-
-   BeevMgr *bm;
-   ASTNodeToCNFInfoMap info;
-   ASTNodeToASTNodePtrMap store;
-
-   //########################################
-   //########################################
-   // utility predicates
-   
-   bool isAtom(const ASTNode& varphi){
-      bool result;
-
-      Kind k = varphi.GetKind();
-      switch(k){
-         case TRUE: {
-            result = true;
-            break;
-         }
-         case FALSE: {
-            result = true;
-            break;
-         }
-         case SYMBOL: {
-            result = true;
-            break;
-         }
-         case BVCONST: {
-            result = true;
-            break;
-         }
-         default: {
-            result = false;
-            break;
-         }
-      }
-
-      return result;
-   }
-
-   bool isPred(const ASTNode& varphi){
-      bool result;
-
-      Kind k = varphi.GetKind();
-      switch(k){
-         case BVLT: {
-            result = true;
-            break;
-         }
-         case BVLE: {
-            result = true;
-            break;
-         }
-         case BVGT: {
-            result = true;
-            break;
-         }
-         case BVGE: {
-            result = true;
-            break;
-         }
-         case BVSLT: {
-            result = true;
-            break;
-         }
-         case BVSLE: {
-            result = true;
-            break;
-         }
-         case BVSGT: {
-            result = true;
-            break;
-         }
-         case BVSGE: {
-            result = true;
-            break;
-         }
-         case EQ: {
-            result = true;
-            break;
-         }
-         case NEQ: {
-            result = true;
-            break;
-         }
-         default: {
-            result = false;
-            break;
-         }
-      }
-
-      return result;
-   }
-
-   bool isITE(const ASTNode& varphi){
-      bool result;
-
-      Kind k = varphi.GetKind();
-      switch(k){
-         case ITE: {
-            result = true;
-            break;
-         }
-         default: {
-            result = false;
-            break;
-         }
-      }
-
-      return result;
-   }
-
-
-   bool onChildDoPos(const ASTNode& varphi, unsigned int idx){
-      bool result = true;
-
-      Kind k = varphi.GetKind();
-      switch(k){
-         case NOT: {
-            result = false;
-            break;
-         }
-         case NAND: {
-            result = false;
-            break;
-         }
-         case NOR: {
-            result = false;
-            break;
-         }
-         case IMPLIES: {
-            if(idx == 0){
-               result = false;
-            }
-            break;
-         }
-         default: {
-            break;
-         }
-      }
-
-      return result;
-   }
-
-   bool onChildDoNeg(const ASTNode& varphi, unsigned int idx){
-      bool result = false;
-
-      Kind k = varphi.GetKind();
-      switch(k){
-         case NOT: {
-            result = true;
-            break;
-         }
-         case NAND: {
-            result = true;
-            break;
-         }
-         case NOR: {
-            result = true;
-            break;
-         }
-         case XOR: {
-            result = true;
-            break;
-         }
-         case IFF: {
-            result = true;
-            break;
-         }
-         case IMPLIES: {
-            if(idx == 0){
-               result = true;
-            }
-            break;
-         }
-         case ITE: {
-            if(idx == 0){
-               result = true;
-            }
-            break;
-         }
-         default: {
-            break;
-         }
-      }
-
-      return result;
-   }
-
-   //########################################
-   //########################################
-   //utilities for control bits.
-   
-   void initializeCNFInfo(CNFInfo& x){
-      x.control = 0;
-      x.clausespos = NULL;
-      x.clausesneg = NULL;
-   }
-
-   void incrementSharesPos(CNFInfo& x){
-      x.control += ((x.control & 3) < 2) ? 1 : 0;
-   }
-
-   int sharesPos(CNFInfo& x){
-      return (x.control & 3);
-   }
-
-   void incrementSharesNeg(CNFInfo& x){
-      x.control += ((x.control & 12) < 8) ? 4 : 0;
-   }
-
-   int sharesNeg(CNFInfo& x){
-      return ((x.control & 12) >> 2);
-   }
-
-   void setControlBit(CNFInfo& x, unsigned int idx){
-      x.control |= (1 << idx);
-   }
-
-   bool getControlBit(CNFInfo& x, unsigned int idx){
-      bool result = false;
-
-      if(x.control & (1 << idx)){
-
-         result = true;
-      }
-
-      return result;
-   }
-
-   void setIsTerm(CNFInfo& x){
-      setControlBit(x, 4);
-   }
-
-   bool isTerm(CNFInfo& x){
-      return getControlBit(x, 4);
-   }
-
-   void setDoRenamePos(CNFInfo& x){
-      setControlBit(x, 5);
-   }
-
-   bool doRenamePos(CNFInfo& x){
-      return getControlBit(x, 5);
-   }
-
-   void setWasRenamedPos(CNFInfo& x){
-      setControlBit(x, 6);
-   }
-
-   bool wasRenamedPos(CNFInfo& x){
-      return getControlBit(x, 6);
-   }
-
-   void setDoRenameNeg(CNFInfo& x){
-      setControlBit(x, 7);
-   }
-
-   bool doRenameNeg(CNFInfo& x){
-      return getControlBit(x, 7);
-   }
-
-   void setWasRenamedNeg(CNFInfo& x){
-      setControlBit(x, 8);
-   }
-
-   bool wasRenamedNeg(CNFInfo& x){
-      return getControlBit(x, 8);
-   }
-
-   void setDoSibRenamingPos(CNFInfo& x){
-      setControlBit(x, 9);
-   }
-
-   bool doSibRenamingPos(CNFInfo& x){
-      return getControlBit(x, 9);
-   }
-
-   void setDoSibRenamingNeg(CNFInfo& x){
-      setControlBit(x, 10);
-   }
+               psi.SetValueWidth(varphi.GetValueWidth());
+               psi.SetIndexWidth(varphi.GetIndexWidth());
 
-   bool doSibRenamingNeg(CNFInfo& x){
-      return getControlBit(x, 10);
-   }
+               //########################################
+               // step 3, recurse over children
+               //########################################
 
-   void setWasVisited(CNFInfo& x){
-      setControlBit(x, 11);
-   }
+               convertFormulaToCNF(varphi[0], defs);
+               convertTermForCNF(varphi[1], defs);
+               ASTNode t1 = *(info[varphi[1]]->termforcnf);
+               convertTermForCNF(varphi[2], defs);
+               ASTNode t2 = *(info[varphi[2]]->termforcnf);
 
-   bool wasVisited(CNFInfo& x){
-      return getControlBit(x, 11);
-   }
+               //########################################
+               // step 4, add def clauses
+               //########################################
 
-   //########################################
-   //########################################
-   //utilities for clause sets
+               BeevMgr::ClauseList* cl1 = SINGLETON(bm->CreateNode(EQ, psi, t1));
+               BeevMgr::ClauseList* cl2 = PRODUCT(*(info[varphi[0]]->clausesneg), *cl1);
+               DELETE(cl1);
+               defs->insert(defs->end(), cl2->begin(), cl2->end());
 
+               BeevMgr::ClauseList* cl3 = SINGLETON(bm->CreateNode(EQ, psi, t2));
+               BeevMgr::ClauseList* cl4 = PRODUCT(*(info[varphi[0]]->clausespos), *cl3);
+               DELETE(cl3);
+               defs->insert(defs->end(), cl4->begin(), cl4->end());
 
-   BeevMgr::ClauseList* COPY(const BeevMgr::ClauseList& varphi){
-      BeevMgr::ClauseList* psi = new BeevMgr::ClauseList(); 
+               return ASTNodeToASTNodePtr(psi);
+       }
+
+       void doRenamingPos(const ASTNode& varphi, BeevMgr::ClauseList* defs)
+       {
+
+               CNFInfo* x = info[varphi];
+
+               //########################################
+               // step 1, calc new variable
+               //########################################
+
+               ostringstream oss;
+               oss << "cnf" << "{" << varphi.GetNodeNum() << "}";
+               ASTNode psi = bm->CreateSymbol(oss.str().c_str());
+
+               //########################################
+               // step 2, add defs
+               //########################################
+
+               BeevMgr::ClauseList* cl1;
+               cl1 = SINGLETON(bm->CreateNode(NOT, psi));
+               BeevMgr::ClauseList* cl2 = PRODUCT(*(info[varphi]->clausespos), *cl1);
+               defs->insert(defs->end(), cl2->begin(), cl2->end());
+               DELETE(info[varphi]->clausespos);
+               DELETE(cl1);
+               delete cl2;
+
+               //########################################
+               // step 3, update info[varphi]
+               //########################################
+
+               x->clausespos = SINGLETON(psi);
+               setWasRenamedPos(*x);
+       }
+
+       void doRenamingNeg(const ASTNode& varphi, BeevMgr::ClauseList* defs)
+       {
+
+               CNFInfo* x = info[varphi];
+
+               //########################################
+               // step 2, calc new variable
+               //########################################
 
-      BeevMgr::ClauseList::const_iterator it = varphi.begin();
-      for(; it != varphi.end(); it++){
-         psi->push_back(new vector<const ASTNode*>(**it));
-      }
+               ostringstream oss;
+               oss << "cnf" << "{" << varphi.GetNodeNum() << "}";
+               ASTNode psi = bm->CreateSymbol(oss.str().c_str());
 
-      return psi;
-   }
+               //########################################
+               // step 3, add defs
+               //########################################
 
-   BeevMgr::ClauseList* SINGLETON(const ASTNode& varphi){
-      ASTNode* copy = ASTNodeToASTNodePtr(varphi);
+               BeevMgr::ClauseList* cl1;
+               cl1 = SINGLETON(psi);
+               BeevMgr::ClauseList* cl2 = PRODUCT(*(info[varphi]->clausesneg), *cl1);
+               defs->insert(defs->end(), cl2->begin(), cl2->end());
+               DELETE(info[varphi]->clausesneg);
+               DELETE(cl1);
+               delete cl2;
 
-      BeevMgr::ClausePtr clause = new vector<const ASTNode*>();
-      clause->push_back(copy);
+               //########################################
+               // step 4, update info[varphi]
+               //########################################
+
+               x->clausesneg = SINGLETON(bm->CreateNode(NOT, psi));
+               setWasRenamedNeg(*x);
+
+       }
+
+       //########################################
+       //########################################
+       //main switch for individual cnf conversion cases
+
+       void convertFormulaToCNFPosCases(const ASTNode& varphi, BeevMgr::ClauseList* defs)
+       {
+
+               if (isPred(varphi))
+               {
+                       convertFormulaToCNFPosPred(varphi, defs);
+                       return;
+               }
+
+               Kind k = varphi.GetKind();
+               switch (k)
+               {
+                       case FALSE:
+                       {
+                               convertFormulaToCNFPosFALSE(varphi, defs);
+                               break;
+                       }
+                       case TRUE:
+                       {
+                               convertFormulaToCNFPosTRUE(varphi, defs);
+                               break;
+                       }
+                       case BVGETBIT:
+                       {
+                               convertFormulaToCNFPosBVGETBIT(varphi, defs);
+                               break;
+                       }
+                       case SYMBOL:
+                       {
+                               convertFormulaToCNFPosSYMBOL(varphi, defs);
+                               break;
+                       }
+                       case NOT:
+                       {
+                               convertFormulaToCNFPosNOT(varphi, defs);
+                               break;
+                       }
+                       case AND:
+                       {
+                               convertFormulaToCNFPosAND(varphi, defs);
+                               break;
+                       }
+                       case NAND:
+                       {
+                               convertFormulaToCNFPosNAND(varphi, defs);
+                               break;
+                       }
+                       case OR:
+                       {
+                               convertFormulaToCNFPosOR(varphi, defs);
+                               break;
+                       }
+                       case NOR:
+                       {
+                               convertFormulaToCNFPosNOR(varphi, defs);
+                               break;
+                       }
+                       case XOR:
+                       {
+                               convertFormulaToCNFPosXOR(varphi, defs);
+                               break;
+                       }
+                       case IMPLIES:
+                       {
+                               convertFormulaToCNFPosIMPLIES(varphi, defs);
+                               break;
+                       }
+                       case ITE:
+                       {
+                               convertFormulaToCNFPosITE(varphi, defs);
+                               break;
+                       }
+                       default:
+                       {
+                               fprintf(stderr, "convertFormulaToCNFPosCases: doesn't handle kind %d\n", k);
+                               FatalError("");
+                       }
+               }
+       }
+
+       void convertFormulaToCNFNegCases(const ASTNode& varphi, BeevMgr::ClauseList* defs)
+       {
+
+               if (isPred(varphi))
+               {
+                       convertFormulaToCNFNegPred(varphi, defs);
+                       return;
+               }
+
+               Kind k = varphi.GetKind();
+               switch (k)
+               {
+                       case FALSE:
+                       {
+                               convertFormulaToCNFNegFALSE(varphi, defs);
+                               break;
+                       }
+                       case TRUE:
+                       {
+                               convertFormulaToCNFNegTRUE(varphi, defs);
+                               break;
+                       }
+                       case BVGETBIT:
+                       {
+                               convertFormulaToCNFNegBVGETBIT(varphi, defs);
+                               break;
+                       }
+                       case SYMBOL:
+                       {
+                               convertFormulaToCNFNegSYMBOL(varphi, defs);
+                               break;
+                       }
+                       case NOT:
+                       {
+                               convertFormulaToCNFNegNOT(varphi, defs);
+                               break;
+                       }
+                       case AND:
+                       {
+                               convertFormulaToCNFNegAND(varphi, defs);
+                               break;
+                       }
+                       case NAND:
+                       {
+                               convertFormulaToCNFNegNAND(varphi, defs);
+                               break;
+                       }
+                       case OR:
+                       {
+                               convertFormulaToCNFNegOR(varphi, defs);
+                               break;
+                       }
+                       case NOR:
+                       {
+                               convertFormulaToCNFNegNOR(varphi, defs);
+                               break;
+                       }
+                       case XOR:
+                       {
+                               convertFormulaToCNFNegXOR(varphi, defs);
+                               break;
+                       }
+                       case IMPLIES:
+                       {
+                               convertFormulaToCNFNegIMPLIES(varphi, defs);
+                               break;
+                       }
+                       case ITE:
+                       {
+                               convertFormulaToCNFNegITE(varphi, defs);
+                               break;
+                       }
+                       default:
+                       {
+                               fprintf(stderr, "convertFormulaToCNFNegCases: doesn't handle kind %d\n", k);
+                               FatalError("");
+                       }
+               }
+       }
+
+       //########################################
+       //########################################
+       // individual cnf conversion cases
+
+       void convertFormulaToCNFPosPred(const ASTNode& varphi, BeevMgr::ClauseList* defs)
+       {
+
+               ASTVec psis;
+
+               ASTVec::const_iterator it = varphi.GetChildren().begin();
+               for (; it != varphi.GetChildren().end(); it++)
+               {
+                       convertTermForCNF(*it, defs);
+                       psis.push_back(*(info[*it]->termforcnf));
+               }
+
+               info[varphi]->clausespos = SINGLETON(bm->CreateNode(varphi.GetKind(), psis));
+       }
 
-      BeevMgr::ClauseList* psi = new BeevMgr::ClauseList();
-      psi->push_back(clause);
-      return psi;
-   }
+       void convertFormulaToCNFPosFALSE(const ASTNode& varphi, BeevMgr::ClauseList* defs)
+       {
+               ASTNode dummy_false_var = bm->CreateNode(NOT, bm->CreateSymbol("*TrueDummy*"));
+               info[varphi]->clausespos = SINGLETON(dummy_false_var);
+       }
+
+       void convertFormulaToCNFPosTRUE(const ASTNode& varphi, BeevMgr::ClauseList* defs)
+       {
+               ASTNode dummy_true_var = bm->CreateSymbol("*TrueDummy*");
+               info[varphi]->clausespos = SINGLETON(dummy_true_var);
+       }
+
+       void convertFormulaToCNFPosBVGETBIT(const ASTNode& varphi, BeevMgr::ClauseList* defs)
+       {
+               info[varphi]->clausespos = SINGLETON(varphi);
+       }
+
+       void convertFormulaToCNFPosSYMBOL(const ASTNode& varphi, BeevMgr::ClauseList* defs)
+       {
+               info[varphi]->clausespos = SINGLETON(varphi);
+       }
+
+       void convertFormulaToCNFPosNOT(const ASTNode& varphi, BeevMgr::ClauseList* defs)
+       {
+               convertFormulaToCNF(varphi[0], defs);
+               info[varphi]->clausespos = COPY(*(info[varphi[0]]->clausesneg));
+               reduceMemoryFootprintNeg(varphi[0]);
+       }
+
+       void convertFormulaToCNFPosAND(const ASTNode& varphi, BeevMgr::ClauseList* defs)
+       {
+               //****************************************
+               // (pos) AND ~> UNION
+               //****************************************
+               ASTVec::const_iterator it = varphi.GetChildren().begin();
+               convertFormulaToCNF(*it, defs);
+               BeevMgr::ClauseList* psi = COPY(*(info[*it]->clausespos));
+               for (it++; it != varphi.GetChildren().end(); it++)
+               {
+                       convertFormulaToCNF(*it, defs);
+                       INPLACE_UNION(psi, *(info[*it]->clausespos));
+                       reduceMemoryFootprintPos(*it);
+               }
+
+               info[varphi]->clausespos = psi;
+       }
+
+       void convertFormulaToCNFPosNAND(const ASTNode& varphi, BeevMgr::ClauseList* defs)
+       {
+               bool renamesibs = false;
+               BeevMgr::ClauseList* clauses;
+               BeevMgr::ClauseList* psi;
+               BeevMgr::ClauseList* oldpsi;
+
+               //****************************************
+               // (pos) NAND ~> PRODUCT NOT
+               //****************************************
+
+               ASTVec::const_iterator it = varphi.GetChildren().begin();
+               convertFormulaToCNF(*it, defs);
+               clauses = info[*it]->clausesneg;
+               if (clauses->size() > 1)
+               {
+                       renamesibs = true;
+               }
+               psi = COPY(*clauses);
+               reduceMemoryFootprintNeg(*it);
+
+               for (it++; it != varphi.GetChildren().end(); it++)
+               {
+                       if (renamesibs)
+                       {
+                               setDoSibRenamingNeg(*(info[*it]));
+                       }
+                       convertFormulaToCNF(*it, defs);
+                       clauses = info[*it]->clausesneg;
+                       if (clauses->size() > 1)
+                       {
+                               renamesibs = true;
+                       }
+                       oldpsi = psi;
+                       psi = PRODUCT(*psi, *clauses);
+                       reduceMemoryFootprintNeg(*it);
+                       DELETE(oldpsi);
+               }
+
+               info[varphi]->clausespos = psi;
+       }
+
+       void convertFormulaToCNFPosOR(const ASTNode& varphi, BeevMgr::ClauseList* defs)
+       {
+               bool renamesibs = false;
+               BeevMgr::ClauseList* clauses;
+               BeevMgr::ClauseList* psi;
+               BeevMgr::ClauseList* oldpsi;
+
+               //****************************************
+               // (pos) OR ~> PRODUCT
+               //****************************************
+               ASTVec::const_iterator it = varphi.GetChildren().begin();
+               convertFormulaToCNF(*it, defs);
+               clauses = info[*it]->clausespos;
+               if (clauses->size() > 1)
+               {
+                       renamesibs = true;
+               }
+               psi = COPY(*clauses);
+               reduceMemoryFootprintPos(*it);
+
+               for (it++; it != varphi.GetChildren().end(); it++)
+               {
+                       if (renamesibs)
+                       {
+                               setDoSibRenamingPos(*(info[*it]));
+                       }
+                       convertFormulaToCNF(*it, defs);
+                       clauses = info[*it]->clausespos;
+                       if (clauses->size() > 1)
+                       {
+                               renamesibs = true;
+                       }
+                       oldpsi = psi;
+                       psi = PRODUCT(*psi, *clauses);
+                       reduceMemoryFootprintPos(*it);
+                       DELETE(oldpsi);
+               }
+
+               info[varphi]->clausespos = psi;
+       }
+
+       void convertFormulaToCNFPosNOR(const ASTNode& varphi, BeevMgr::ClauseList* defs)
+       {
+               //****************************************
+               // (pos) NOR ~> UNION NOT
+               //****************************************
+               ASTVec::const_iterator it = varphi.GetChildren().begin();
+               convertFormulaToCNF(*it, defs);
+               BeevMgr::ClauseList* psi = COPY(*(info[*it]->clausesneg));
+               reduceMemoryFootprintNeg(*it);
+               for (it++; it != varphi.GetChildren().end(); it++)
+               {
+                       convertFormulaToCNF(*it, defs);
+                       INPLACE_UNION(psi, *(info[*it]->clausesneg));
+                       reduceMemoryFootprintNeg(*it);
+               }
+
+               info[varphi]->clausespos = psi;
+       }
+
+       void convertFormulaToCNFPosIMPLIES(const ASTNode& varphi, BeevMgr::ClauseList* defs)
+       {
+               //****************************************
+               // (pos) IMPLIES ~> PRODUCT NOT [0] ; [1]
+               //****************************************
+               CNFInfo* x0 = info[varphi[0]];
+               CNFInfo* x1 = info[varphi[1]];
+               convertFormulaToCNF(varphi[0], defs);
+               if (x0->clausesneg->size() > 1)
+               {
+                       setDoSibRenamingPos(*x1);
+               }
+               convertFormulaToCNF(varphi[1], defs);
+               BeevMgr::ClauseList* psi = PRODUCT(*(x0->clausesneg), *(x1->clausespos));
+               reduceMemoryFootprintNeg(varphi[0]);
+               reduceMemoryFootprintPos(varphi[1]);
+               info[varphi]->clausespos = psi;
+       }
+
+       void convertFormulaToCNFPosITE(const ASTNode& varphi, BeevMgr::ClauseList* defs)
+       {
+               //****************************************
+               // (pos) ITE ~> UNION (PRODUCT NOT [0] ; [1])
+               //  ; (PRODUCT [0] ; [2])
+               //****************************************
+               CNFInfo* x0 = info[varphi[0]];
+               CNFInfo* x1 = info[varphi[1]];
+               CNFInfo* x2 = info[varphi[2]];
+               convertFormulaToCNF(varphi[0], defs);
+               if (x0->clausesneg->size() > 1)
+               {
+                       setDoSibRenamingPos(*x1);
+               }
+               convertFormulaToCNF(varphi[1], defs);
+               if (x0->clausespos->size() > 1)
+               {
+                       setDoSibRenamingPos(*x2);
+               }
+               convertFormulaToCNF(varphi[2], defs);
+               BeevMgr::ClauseList* psi1 = PRODUCT(*(x0->clausesneg), *(x1->clausespos));
+               BeevMgr::ClauseList* psi2 = PRODUCT(*(x0->clausespos), *(x2->clausespos));
+               NOCOPY_INPLACE_UNION(psi1, psi2);
+               reduceMemoryFootprintNeg(varphi[0]);
+               reduceMemoryFootprintPos(varphi[1]);
+               reduceMemoryFootprintPos(varphi[0]);
+               reduceMemoryFootprintPos(varphi[2]);
+
+               info[varphi]->clausespos = psi1;
+       }
+
+       void convertFormulaToCNFPosXOR(const ASTNode& varphi, BeevMgr::ClauseList* defs)
+       {
+               BeevMgr::ClauseList* psi = convertFormulaToCNFPosXORAux(varphi, 0, defs);
+               info[varphi]->clausespos = psi;
+       }
+
+       BeevMgr::ClauseList* convertFormulaToCNFPosXORAux(const ASTNode& varphi, unsigned int idx, BeevMgr::ClauseList* defs)
+       {
+
+               bool renamesibs;
+               BeevMgr::ClauseList* psi;
+               BeevMgr::ClauseList* psi1;
+               BeevMgr::ClauseList* psi2;
+
+               if (idx == varphi.GetChildren().size() - 2)
+               {
+                       //****************************************
+                       // (pos) XOR ~> UNION
+                       //    (PRODUCT       [idx]   ;     [idx+1])
+                       //  ; (PRODUCT NOT   [idx]   ; NOT [idx+1])
+                       //****************************************
+                       convertFormulaToCNF(varphi[idx], defs);
+                       renamesibs = (info[varphi[idx]]->clausespos)->size() > 1 ? true : false;
+                       if (renamesibs)
+                       {
+                               setDoSibRenamingPos(*info[varphi[idx + 1]]);
+                       }
+                       renamesibs = (info[varphi[idx]]->clausesneg)->size() > 1 ? true : false;
+                       if (renamesibs)
+                       {
+                               setDoSibRenamingNeg(*info[varphi[idx + 1]]);
+                       }
+                       convertFormulaToCNF(varphi[idx + 1], defs);
+
+                       psi1 = PRODUCT(*(info[varphi[idx]]->clausespos), *(info[varphi[idx + 1]]->clausespos));
+                       psi2 = PRODUCT(*(info[varphi[idx]]->clausesneg), *(info[varphi[idx + 1]]->clausesneg));
+                       NOCOPY_INPLACE_UNION(psi1, psi2);
+                       reduceMemoryFootprintPos(varphi[idx]);
+                       reduceMemoryFootprintPos(varphi[idx + 1]);
+                       reduceMemoryFootprintNeg(varphi[idx]);
+                       reduceMemoryFootprintNeg(varphi[idx + 1]);
+
+                       psi = psi1;
+               }
+               else
+               {
+                       //****************************************
+                       // (pos) XOR ~> UNION
+                       //    (PRODUCT       [idx] ; XOR      [idx+1..])
+                       //  ; (PRODUCT NOT   [idx] ; NOT XOR  [idx+1..])
+                       //****************************************
+                       BeevMgr::ClauseList* theta1;
+                       theta1 = convertFormulaToCNFPosXORAux(varphi, idx + 1, defs);
+                       renamesibs = theta1->size() > 1 ? true : false;
+                       if (renamesibs)
+                       {
+                               setDoSibRenamingPos(*info[varphi[idx]]);
+                       }
+                       BeevMgr::ClauseList* theta2;
+                       theta2 = convertFormulaToCNFNegXORAux(varphi, idx + 1, defs);
+                       renamesibs = theta2->size() > 1 ? true : false;
+                       if (renamesibs)
+                       {
+                               setDoSibRenamingNeg(*info[varphi[idx]]);
+                       }
+                       convertFormulaToCNF(varphi[idx], defs);
+
+                       psi1 = PRODUCT(*(info[varphi[idx]]->clausespos), *theta1);
+                       psi2 = PRODUCT(*(info[varphi[idx]]->clausesneg), *theta2);
+                       DELETE(theta1);
+                       DELETE(theta2);
+                       NOCOPY_INPLACE_UNION(psi1, psi2);
+                       reduceMemoryFootprintPos(varphi[idx]);
+                       reduceMemoryFootprintNeg(varphi[idx]);
+
+                       psi = psi1;
+               }
+
+               return psi;
+       }
 
-   BeevMgr::ClauseList* UNION(const BeevMgr::ClauseList& varphi1
-        , const BeevMgr::ClauseList& varphi2){ 
-
-      BeevMgr::ClauseList* psi1 = COPY(varphi1);
-      BeevMgr::ClauseList* psi2 = COPY(varphi2);
-      psi1->insert(psi1->end(), psi2->begin(), psi2->end());
-      delete psi2;
-
-      return psi1;
-
-   }
-
-   void INPLACE_UNION(BeevMgr::ClauseList* varphi1
-        , const BeevMgr::ClauseList& varphi2){ 
-
-      BeevMgr::ClauseList* psi2 = COPY(varphi2);
-      varphi1->insert(varphi1->end(), psi2->begin(), psi2->end());
-      delete psi2;
-   }
-
-   void NOCOPY_INPLACE_UNION(BeevMgr::ClauseList* varphi1
-        , BeevMgr::ClauseList* varphi2){ 
-
-      varphi1->insert(varphi1->end(), varphi2->begin(), varphi2->end());
-      delete varphi2;
-   }
-
-   BeevMgr::ClauseList* PRODUCT(const BeevMgr::ClauseList& varphi1
-        , const BeevMgr::ClauseList& varphi2){ 
-
-      BeevMgr::ClauseList* psi = new BeevMgr::ClauseList();
-
-      BeevMgr::ClauseList::const_iterator it1 = varphi1.begin();
-      for(; it1 != varphi1.end(); it1++){
-         BeevMgr::ClausePtr clause1 = *it1;
-         BeevMgr::ClauseList::const_iterator it2 = varphi2.begin();
-         for(; it2 != varphi2.end(); it2++){
-            BeevMgr::ClausePtr clause2 = *it2;
-            BeevMgr::ClausePtr clause = new vector<const ASTNode*>();
-            clause->insert(clause->end()
-                  , clause1->begin()
-                  , clause1->end()
-               );
-            clause->insert(clause->end()
-                  , clause2->begin()
-                  , clause2->end()
-               );
-            psi->push_back(clause);
-         }
-      }
-
-      return psi;
-   }
-
-   //########################################
-   //########################################
-   //prep. for cnf conversion
-
-   void scanFormula(const ASTNode& varphi, bool isPos){
-
-      CNFInfo* x;
-
-      //########################################
-      // step 1, get the info associated with this node
-      //########################################
-
-      if(info.find(varphi) == info.end()){
-         x = new CNFInfo();
-         initializeCNFInfo(*x);
-         info[varphi] = x;
-      } else {
-          x = info[varphi];
-      }
-
-      //########################################
-      // step 2, we only need to know if shares >= 2
-      //########################################
-
-      if(isPos && sharesPos(*x) == 2){
-         return;
-      }
-
-      if(!isPos && sharesNeg(*x) == 2){
-         return;
-      }
-      
-      //########################################
-      // step 3, set appropriate information fields
-      //########################################
-
-      if(isPos){
-         incrementSharesPos(*x);
-      }
-
-      if(!isPos){
-         incrementSharesNeg(*x);
-      }
-
-      //########################################
-      // step 4, recurse over children
-      //########################################
-      
-      if(isAtom(varphi)){
-         return;
-      } else if(isPred(varphi)){
-         for(unsigned int i = 0; i < varphi.GetChildren().size(); i++){
-            scanTerm(varphi[i]);
-         }
-      } else {
-         for(unsigned int i = 0; i < varphi.GetChildren().size(); i++){
-            if(onChildDoPos(varphi, i)){
-               scanFormula(varphi[i], isPos);
-            }
-            if(onChildDoNeg(varphi, i)){
-               scanFormula(varphi[i], !isPos);
-            }
-         }
-      }
-   }
-
-   void scanTerm(const ASTNode& varphi){
-
-      CNFInfo* x;
-
-      //########################################
-      // step 1, get the info associated with this node
-      //########################################
-
-      if(info.find(varphi) == info.end()){
-         x = new CNFInfo();
-         initializeCNFInfo(*x);
-         info[varphi] = x;
-      } else {
-          x = info[varphi];
-      }
-
-      //########################################
-      // step 2, need two hits because of term ITEs. 
-      //########################################
-
-      if(sharesPos(*x) == 2){
-         return;
-      }
-
-      //########################################
-      // step 3, set appropriate data fields, always rename
-      // term ITEs
-      //########################################
-
-      incrementSharesPos(*x);
-      setIsTerm(*x);
-
-      //########################################
-      // step 4, recurse over children
-      //########################################
-      
-      if(isAtom(varphi)){
-         return;
-      } else if(isITE(varphi)){
-         scanFormula(varphi[0], true);
-         scanFormula(varphi[0], false);
-         scanTerm(varphi[1]);
-         scanTerm(varphi[2]);
-      } else {
-         for(unsigned int i = 0; i < varphi.GetChildren().size(); i++){
-            scanTerm(varphi[i]);
-         }
-      }
-   }
-
-   //########################################
-   //########################################
-   // main cnf conversion function
-   
-   void convertFormulaToCNF(const ASTNode& varphi, BeevMgr::ClauseList* defs){
-
-      CNFInfo* x = info[varphi];
-
-      //########################################
-      // divert to special case if term (word-level cnf)
-
-      if(isTerm(*x)){
-         convertTermForCNF(varphi, defs);
-         setWasVisited(*x);
-         return;
-      }
-
-      //########################################
-      // do work
-     
-      if(sharesPos(*x) > 0 && !wasVisited(*x)){
-         convertFormulaToCNFPosCases(varphi, defs);
-      }
-
-      if(x->clausespos != NULL && x->clausespos->size() > 1){
-         if(doSibRenamingPos(*x) || sharesPos(*x) > 1){
-            doRenamingPos(varphi, defs);
-         }
-      }
-
-      if(sharesNeg(*x) > 0 && !wasVisited(*x)){
-         convertFormulaToCNFNegCases(varphi, defs);
-      }
-
-      if(x->clausesneg != NULL && x->clausesneg->size() > 1){
-         if(doSibRenamingNeg(*x) || sharesNeg(*x) > 1){
-            doRenamingNeg(varphi, defs);
-         }
-      }
-
-      //########################################
-      //mark that we've already done the hard work
-
-      setWasVisited(*x);
-   }
-
-   void convertTermForCNF(const ASTNode& varphi, BeevMgr::ClauseList* defs){
-
-      CNFInfo* x = info[varphi];
-
-      //########################################
-      // step 1, done if we've already visited
-      //########################################
-
-      if(x->termforcnf != NULL){
-         return;
-      }
-
-      //########################################
-      // step 2, ITE's always get renamed
-      //########################################
-
-      if(isITE(varphi)){
-         x->termforcnf = doRenameITE(varphi, defs);
-         reduceMemoryFootprintPos(varphi[0]);
-         reduceMemoryFootprintNeg(varphi[0]);
-
-      } else if(isAtom(varphi)){
-         x->termforcnf = ASTNodeToASTNodePtr(varphi);
-      } else {
-
-         ASTVec psis;
-         ASTVec::const_iterator it = varphi.GetChildren().begin();
-         for(; it != varphi.GetChildren().end(); it++){
-            convertTermForCNF(*it, defs);
-            psis.push_back(*(info[*it]->termforcnf));
-         }
-
-         ASTNode psi = bm->CreateNode(varphi.GetKind(), psis);
-         psi.SetValueWidth(varphi.GetValueWidth());
-         psi.SetIndexWidth(varphi.GetIndexWidth());
-         x->termforcnf = ASTNodeToASTNodePtr(psi);
-      }
-   }
-
-   //########################################
-   //########################################
-   // functions for renaming nodes during cnf conversion
-
-   ASTNode* doRenameITE(const ASTNode& varphi, BeevMgr::ClauseList* defs){
-
-      ASTNode psi;
-
-      //########################################
-      // step 1, old "RepLit" code
-      //########################################
-
-      ostringstream oss;
-      oss << "cnf" << "{" << varphi.GetNodeNum() << "}";
-      psi = bm->CreateSymbol(oss.str().c_str());
-
-      //########################################
-      // step 2, set widths appropriately
-      //########################################
-
-      psi.SetValueWidth(varphi.GetValueWidth());
-      psi.SetIndexWidth(varphi.GetIndexWidth());
-
-      //########################################
-      // step 3, recurse over children
-      //########################################
-
-      convertFormulaToCNF(varphi[0], defs);
-      convertTermForCNF(varphi[1], defs);
-      ASTNode t1 = *(info[varphi[1]]->termforcnf);
-      convertTermForCNF(varphi[2], defs);
-      ASTNode t2 = *(info[varphi[2]]->termforcnf);
-
-      //########################################
-      // step 4, add def clauses
-      //########################################
-
-      BeevMgr::ClauseList* cl1 = SINGLETON(bm->CreateNode(EQ, psi, t1));
-      BeevMgr::ClauseList* cl2 = PRODUCT(*(info[varphi[0]]->clausesneg), *cl1);
-      DELETE(cl1);
-      defs->insert(defs->end(), cl2->begin(), cl2->end());
-
-      BeevMgr::ClauseList* cl3 = SINGLETON(bm->CreateNode(EQ, psi, t2));
-      BeevMgr::ClauseList* cl4 = PRODUCT(*(info[varphi[0]]->clausespos), *cl3);
-      DELETE(cl3);
-      defs->insert(defs->end(), cl4->begin(), cl4->end());
-
-      return ASTNodeToASTNodePtr(psi);
-   }
-
-   void doRenamingPos(const ASTNode& varphi, BeevMgr::ClauseList* defs){
-
-      CNFInfo* x = info[varphi];
-
-      //########################################
-      // step 1, calc new variable
-      //########################################
-
-      ostringstream oss;
-      oss << "cnf" << "{" << varphi.GetNodeNum() << "}";
-      ASTNode psi = bm->CreateSymbol(oss.str().c_str());
-
-      //########################################
-      // step 2, add defs
-      //########################################
-      
-      BeevMgr::ClauseList* cl1;
-      cl1 = SINGLETON(bm->CreateNode(NOT, psi));
-      BeevMgr::ClauseList* cl2 = PRODUCT(*(info[varphi]->clausespos), *cl1);
-      defs->insert(defs->end(), cl2->begin(), cl2->end());
-      DELETE(info[varphi]->clausespos);
-      DELETE(cl1);
-      delete cl2;
-
-      //########################################
-      // step 3, update info[varphi]
-      //########################################
-
-      x->clausespos = SINGLETON(psi);
-      setWasRenamedPos(*x);
-   }
-
-   void doRenamingNeg(const ASTNode& varphi, BeevMgr::ClauseList* defs){
-
-      CNFInfo* x = info[varphi];
-
-      //########################################
-      // step 2, calc new variable
-      //########################################
-
-      ostringstream oss;
-      oss << "cnf" << "{" << varphi.GetNodeNum() << "}";
-      ASTNode psi = bm->CreateSymbol(oss.str().c_str());
-
-      //########################################
-      // step 3, add defs
-      //########################################
-      
-      BeevMgr::ClauseList* cl1;
-      cl1 = SINGLETON(psi);
-      BeevMgr::ClauseList* cl2 = PRODUCT(*(info[varphi]->clausesneg), *cl1);
-      defs->insert(defs->end(), cl2->begin(), cl2->end());
-      DELETE(info[varphi]->clausesneg);
-      DELETE(cl1);
-      delete cl2;
-
-      //########################################
-      // step 4, update info[varphi]
-      //########################################
-
-      x->clausesneg = SINGLETON(bm->CreateNode(NOT, psi));
-      setWasRenamedNeg(*x);
-
-   }
-
-   //########################################
-   //########################################
-   //main switch for individual cnf conversion cases
-   
-   void convertFormulaToCNFPosCases(const ASTNode& varphi, BeevMgr::ClauseList* defs){
-
-      if(isPred(varphi)){
-         convertFormulaToCNFPosPred(varphi, defs);
-         return;
-      }
-
-
-      Kind k = varphi.GetKind();
-      switch ( k ){
-         case FALSE:    {
-            convertFormulaToCNFPosFALSE(varphi, defs);
-            break;
-         }
-         case TRUE:     {
-            convertFormulaToCNFPosTRUE(varphi, defs);
-            break;
-         }
-         case BVGETBIT: {
-            convertFormulaToCNFPosBVGETBIT(varphi, defs);
-            break;
-         }
-         case SYMBOL:   {
-            convertFormulaToCNFPosSYMBOL(varphi, defs);
-            break;
-         }
-         case NOT:      {
-            convertFormulaToCNFPosNOT(varphi, defs);
-            break;
-         }
-         case AND:      {
-            convertFormulaToCNFPosAND(varphi, defs);
-            break;
-         }
-         case NAND:     {
-            convertFormulaToCNFPosNAND(varphi, defs);
-            break;
-         }
-         case OR:       {
-            convertFormulaToCNFPosOR(varphi, defs);
-            break;
-         }
-         case NOR:      {
-            convertFormulaToCNFPosNOR(varphi, defs);
-            break;
-         }
-         case XOR:      {
-            convertFormulaToCNFPosXOR(varphi, defs);
-            break;
-         }
-         case IMPLIES:  {
-            convertFormulaToCNFPosIMPLIES(varphi, defs);
-            break;
-         }
-         case ITE:      {
-            convertFormulaToCNFPosITE(varphi, defs);
-            break;
-         }
-         default: {
-            fprintf(stderr, "convertFormulaToCNFPosCases: doesn't handle kind %d\n", k);
-            FatalError("");
-         }
-      }
-   }
-
-   void convertFormulaToCNFNegCases(const ASTNode& varphi, BeevMgr::ClauseList* defs){
-
-      if(isPred(varphi)){
-         convertFormulaToCNFNegPred(varphi, defs);
-         return;
-      }
-
-
-      Kind k = varphi.GetKind();
-      switch ( k ){
-         case FALSE:    {
-            convertFormulaToCNFNegFALSE(varphi, defs);
-            break;
-         }
-         case TRUE:     {
-            convertFormulaToCNFNegTRUE(varphi, defs);
-            break;
-         }
-         case BVGETBIT: {
-            convertFormulaToCNFNegBVGETBIT(varphi, defs);
-            break;
-         }
-         case SYMBOL:   {
-            convertFormulaToCNFNegSYMBOL(varphi, defs);
-            break;
-         }
-         case NOT:      {
-            convertFormulaToCNFNegNOT(varphi, defs);
-            break;
-         }
-         case AND:      {
-            convertFormulaToCNFNegAND(varphi, defs);
-            break;
-         }
-         case NAND:     {
-            convertFormulaToCNFNegNAND(varphi, defs);
-            break;
-         }
-         case OR:       {
-            convertFormulaToCNFNegOR(varphi, defs);
-            break;
-         }
-         case NOR:      {
-            convertFormulaToCNFNegNOR(varphi, defs);
-            break;
-         }
-         case XOR:      {
-            convertFormulaToCNFNegXOR(varphi, defs);
-            break;
-         }
-         case IMPLIES:  {
-            convertFormulaToCNFNegIMPLIES(varphi, defs);
-            break;
-         }
-         case ITE:      {
-            convertFormulaToCNFNegITE(varphi, defs);
-            break;
-         }
-         default: {
-            fprintf(stderr, "convertFormulaToCNFNegCases: doesn't handle kind %d\n", k);
-            FatalError("");
-         }
-      }
-   }
-
-   //########################################
-   //########################################
-   // individual cnf conversion cases
-   
-   void convertFormulaToCNFPosPred(const ASTNode& varphi, BeevMgr::ClauseList* defs){
-
-      ASTVec psis;
-
-      ASTVec::const_iterator it = varphi.GetChildren().begin();
-      for(; it != varphi.GetChildren().end(); it++){
-         convertTermForCNF(*it, defs);
-         psis.push_back(*(info[*it]->termforcnf));
-      }
-
-      info[varphi]->clausespos = SINGLETON(bm->CreateNode(varphi.GetKind(), psis));
-   }
-
-   void convertFormulaToCNFPosFALSE(const ASTNode& varphi, BeevMgr::ClauseList* defs){
-      ASTNode dummy_false_var = bm->CreateNode(NOT, bm->CreateSymbol("*TrueDummy*"));
-      info[varphi]->clausespos = SINGLETON(dummy_false_var);
-   }
-
-   void convertFormulaToCNFPosTRUE(const ASTNode& varphi, BeevMgr::ClauseList* defs){
-      ASTNode dummy_true_var = bm->CreateSymbol("*TrueDummy*");
-      info[varphi]->clausespos = SINGLETON(dummy_true_var);
-   }
-
-   void convertFormulaToCNFPosBVGETBIT(const ASTNode& varphi, BeevMgr::ClauseList* defs){
-      info[varphi]->clausespos = SINGLETON(varphi);
-   }
-
-   void convertFormulaToCNFPosSYMBOL(const ASTNode& varphi, BeevMgr::ClauseList* defs){
-      info[varphi]->clausespos = SINGLETON(varphi);
-   }
-
-   void convertFormulaToCNFPosNOT(const ASTNode& varphi, BeevMgr::ClauseList* defs){
-      convertFormulaToCNF(varphi[0], defs);
-      info[varphi]->clausespos = COPY(*(info[varphi[0]]->clausesneg));
-      reduceMemoryFootprintNeg(varphi[0]);
-   }
-
-   void convertFormulaToCNFPosAND(const ASTNode& varphi, BeevMgr::ClauseList* defs){
-      //****************************************
-      // (pos) AND ~> UNION
-      //****************************************
-      ASTVec::const_iterator it = varphi.GetChildren().begin();
-      convertFormulaToCNF(*it, defs);
-      BeevMgr::ClauseList* psi = COPY(*(info[*it]->clausespos));
-      for(it++; it != varphi.GetChildren().end(); it++){
-         convertFormulaToCNF(*it, defs);
-         INPLACE_UNION(psi, *(info[*it]->clausespos));
-         reduceMemoryFootprintPos(*it);
-      }
-
-      info[varphi]->clausespos = psi;
-   }
-
-   void convertFormulaToCNFPosNAND(const ASTNode& varphi, BeevMgr::ClauseList* defs){
-      bool renamesibs = false;
-      BeevMgr::ClauseList* clauses;
-      BeevMgr::ClauseList* psi;
-      BeevMgr::ClauseList* oldpsi;
-
-      //****************************************
-      // (pos) NAND ~> PRODUCT NOT
-      //****************************************
-
-      ASTVec::const_iterator it = varphi.GetChildren().begin();
-      convertFormulaToCNF(*it, defs);
-      clauses = info[*it]->clausesneg;
-      if(clauses->size() > 1){
-         renamesibs = true;
-      }
-      psi = COPY(*clauses);
-      reduceMemoryFootprintNeg(*it);
-
-      for(it++; it != varphi.GetChildren().end(); it++){
-         if(renamesibs){
-            setDoSibRenamingNeg(*(info[*it]));
-         }
-         convertFormulaToCNF(*it, defs);
-         clauses = info[*it]->clausesneg;
-         if(clauses->size() > 1){
-            renamesibs = true;
-         }
-         oldpsi = psi;
-         psi = PRODUCT(*psi, *clauses);
-         reduceMemoryFootprintNeg(*it);
-         DELETE(oldpsi);
-      }
-
-      info[varphi]->clausespos = psi;
-   }
-
-   void convertFormulaToCNFPosOR(const ASTNode& varphi, BeevMgr::ClauseList* defs){
-      bool renamesibs = false;
-      BeevMgr::ClauseList* clauses;
-      BeevMgr::ClauseList* psi;
-      BeevMgr::ClauseList* oldpsi;
-
-      //****************************************
-      // (pos) OR ~> PRODUCT
-      //****************************************
-      ASTVec::const_iterator it = varphi.GetChildren().begin();
-      convertFormulaToCNF(*it, defs);
-      clauses = info[*it]->clausespos;
-      if(clauses->size() > 1){
-         renamesibs = true;
-      }
-      psi = COPY(*clauses);
-      reduceMemoryFootprintPos(*it);
-
-      for(it++; it != varphi.GetChildren().end(); it++){
-         if(renamesibs){
-            setDoSibRenamingPos(*(info[*it]));
-         }
-         convertFormulaToCNF(*it, defs);
-         clauses = info[*it]->clausespos;
-         if(clauses->size() > 1){
-            renamesibs = true;
-         }
-         oldpsi = psi;
-         psi = PRODUCT(*psi, *clauses);
-         reduceMemoryFootprintPos(*it);
-         DELETE(oldpsi);
-      }
-
-      info[varphi]->clausespos = psi;
-   }
-
-   void convertFormulaToCNFPosNOR(const ASTNode& varphi, BeevMgr::ClauseList* defs){
-      //****************************************
-      // (pos) NOR ~> UNION NOT
-      //****************************************
-      ASTVec::const_iterator it = varphi.GetChildren().begin();
-      convertFormulaToCNF(*it, defs);
-      BeevMgr::ClauseList* psi = COPY(*(info[*it]->clausesneg));
-      reduceMemoryFootprintNeg(*it);
-      for(it++; it != varphi.GetChildren().end(); it++){
-         convertFormulaToCNF(*it, defs);
-         INPLACE_UNION(psi, *(info[*it]->clausesneg));
-         reduceMemoryFootprintNeg(*it);
-      }
-
-      info[varphi]->clausespos = psi;
-   }
-
-   void convertFormulaToCNFPosIMPLIES(const ASTNode& varphi, BeevMgr::ClauseList* defs){
-      //****************************************
-      // (pos) IMPLIES ~> PRODUCT NOT [0] ; [1]
-      //****************************************
-      CNFInfo* x0 = info[varphi[0]];
-      CNFInfo* x1 = info[varphi[1]];
-      convertFormulaToCNF(varphi[0], defs);
-      if(x0->clausesneg->size() > 1){
-         setDoSibRenamingPos(*x1);
-      }
-      convertFormulaToCNF(varphi[1], defs);
-      BeevMgr::ClauseList* psi = 
-         PRODUCT(*(x0->clausesneg), *(x1->clausespos));
-      reduceMemoryFootprintNeg(varphi[0]);
-      reduceMemoryFootprintPos(varphi[1]);
-      info[varphi]->clausespos = psi;
-   }
-
-   void convertFormulaToCNFPosITE(const ASTNode& varphi, BeevMgr::ClauseList* defs){
-      //****************************************
-      // (pos) ITE ~> UNION (PRODUCT NOT [0] ; [1])
-      //  ; (PRODUCT [0] ; [2])
-      //****************************************
-      CNFInfo* x0 = info[varphi[0]];
-      CNFInfo* x1 = info[varphi[1]];
-      CNFInfo* x2 = info[varphi[2]];
-      convertFormulaToCNF(varphi[0], defs);
-      if(x0->clausesneg->size() > 1){
-         setDoSibRenamingPos(*x1);
-      }
-      convertFormulaToCNF(varphi[1], defs);
-      if(x0->clausespos->size() > 1){
-         setDoSibRenamingPos(*x2);
-      }
-      convertFormulaToCNF(varphi[2], defs);
-      BeevMgr::ClauseList* psi1 = PRODUCT(*(x0->clausesneg)
-         , *(x1->clausespos));
-      BeevMgr::ClauseList* psi2 = PRODUCT(*(x0->clausespos)
-         , *(x2->clausespos));
-      NOCOPY_INPLACE_UNION(psi1, psi2);
-      reduceMemoryFootprintNeg(varphi[0]);
-      reduceMemoryFootprintPos(varphi[1]);
-      reduceMemoryFootprintPos(varphi[0]);
-      reduceMemoryFootprintPos(varphi[2]);
-
-      info[varphi]->clausespos = psi1;
-   }
-
-   void convertFormulaToCNFPosXOR(const ASTNode& varphi, BeevMgr::ClauseList* defs){
-      BeevMgr::ClauseList* psi = convertFormulaToCNFPosXORAux(varphi, 0, defs);
-      info[varphi]->clausespos = psi;
-   }
-
-   BeevMgr::ClauseList* convertFormulaToCNFPosXORAux(const ASTNode& varphi
-         , unsigned int idx, BeevMgr::ClauseList* defs){
-
-      bool renamesibs;
-      BeevMgr::ClauseList* psi;
-      BeevMgr::ClauseList* psi1;
-      BeevMgr::ClauseList* psi2;
-
-      if(idx == varphi.GetChildren().size() - 2){
-      //****************************************
-      // (pos) XOR ~> UNION 
-      //    (PRODUCT       [idx]   ;     [idx+1])
-      //  ; (PRODUCT NOT   [idx]   ; NOT [idx+1])
-      //****************************************
-         convertFormulaToCNF(varphi[idx], defs);
-         renamesibs = (info[varphi[idx]]->clausespos)->size() > 1 ? true : false;
-         if(renamesibs){
-            setDoSibRenamingPos(*info[varphi[idx+1]]);
-         }
-         renamesibs = (info[varphi[idx]]->clausesneg)->size() > 1 ? true : false;
-         if(renamesibs){
-            setDoSibRenamingNeg(*info[varphi[idx+1]]);
-         }
-         convertFormulaToCNF(varphi[idx+1], defs);
-
-         psi1 = PRODUCT(*(info[varphi[idx]]->clausespos), *(info[varphi[idx+1]]->clausespos));
-         psi2 = PRODUCT(*(info[varphi[idx]]->clausesneg), *(info[varphi[idx+1]]->clausesneg));
-         NOCOPY_INPLACE_UNION(psi1, psi2);
-         reduceMemoryFootprintPos(varphi[idx]);
-         reduceMemoryFootprintPos(varphi[idx+1]);
-         reduceMemoryFootprintNeg(varphi[idx]);
-         reduceMemoryFootprintNeg(varphi[idx+1]);
-
-         psi = psi1;
-      } else {
-      //****************************************
-      // (pos) XOR ~> UNION 
-      //    (PRODUCT       [idx] ; XOR      [idx+1..])
-      //  ; (PRODUCT NOT   [idx] ; NOT XOR  [idx+1..])
-      //****************************************
-         BeevMgr::ClauseList* theta1;
-         theta1 = convertFormulaToCNFPosXORAux(varphi, idx+1, defs);
-         renamesibs = theta1->size() > 1 ? true : false;
-         if(renamesibs){
-            setDoSibRenamingPos(*info[varphi[idx]]);
-         }
-         BeevMgr::ClauseList* theta2;
-         theta2 = convertFormulaToCNFNegXORAux(varphi, idx+1, defs);
-         renamesibs = theta2->size() > 1 ? true : false;
-         if(renamesibs){
-            setDoSibRenamingNeg(*info[varphi[idx]]);
-         }
-         convertFormulaToCNF(varphi[idx], defs);
-
-         psi1 = PRODUCT(*(info[varphi[idx]]->clausespos), *theta1);
-         psi2 = PRODUCT(*(info[varphi[idx]]->clausesneg), *theta2);
-         DELETE(theta1);
-         DELETE(theta2);
-         NOCOPY_INPLACE_UNION(psi1, psi2);
-         reduceMemoryFootprintPos(varphi[idx]);
-         reduceMemoryFootprintNeg(varphi[idx]);
-
-         psi = psi1;
-      }
-
-      return psi;
-   }
-
-   void convertFormulaToCNFNegPred(const ASTNode& varphi, BeevMgr::ClauseList* defs){
-
-      ASTVec psis;
-
-      ASTVec::const_iterator it = varphi.GetChildren().begin();
-      for(; it != varphi.GetChildren().end(); it++){
-         convertFormulaToCNF(*it, defs);
-         psis.push_back(*(info[*it]->termforcnf));
-      }
-
-      info[varphi]->clausesneg = SINGLETON(bm->CreateNode(NOT, bm->CreateNode(varphi.GetKind(), psis)));
-   }
-
-   void convertFormulaToCNFNegFALSE(const ASTNode& varphi, BeevMgr::ClauseList* defs){
-      ASTNode dummy_true_var = bm->CreateSymbol("*TrueDummy*");
-      info[varphi]->clausesneg = SINGLETON(dummy_true_var);
-   }
-
-   void convertFormulaToCNFNegTRUE(const ASTNode& varphi, BeevMgr::ClauseList* defs){
-      ASTNode dummy_false_var = bm->CreateNode(NOT, bm->CreateSymbol("*TrueDummy*"));
-      info[varphi]->clausesneg = SINGLETON(dummy_false_var);
-   }
-
-   void convertFormulaToCNFNegBVGETBIT(const ASTNode& varphi, BeevMgr::ClauseList* defs){
-      BeevMgr::ClauseList* psi = SINGLETON(bm->CreateNode(NOT, varphi));
-      info[varphi]->clausesneg = psi;
-   }
-
-   void convertFormulaToCNFNegSYMBOL(const ASTNode& varphi, BeevMgr::ClauseList* defs){
-      info[varphi]->clausesneg = SINGLETON(bm->CreateNode(NOT, varphi));
-   }
-
-   void convertFormulaToCNFNegNOT(const ASTNode& varphi, BeevMgr::ClauseList* defs){
-      convertFormulaToCNF(varphi[0], defs);
-      info[varphi]->clausesneg = COPY(*(info[varphi[0]]->clausespos));
-      reduceMemoryFootprintPos(varphi[0]);
-   }
-
-   void convertFormulaToCNFNegAND(const ASTNode& varphi, BeevMgr::ClauseList* defs){
-      bool renamesibs = false;
-      BeevMgr::ClauseList* clauses;
-      BeevMgr::ClauseList* psi;
-      BeevMgr::ClauseList* oldpsi;
-
-      //****************************************
-      // (neg) AND ~> PRODUCT NOT
-      //****************************************
-
-      ASTVec::const_iterator it = varphi.GetChildren().begin();
-      convertFormulaToCNF(*it, defs);
-      clauses = info[*it]->clausesneg;
-      if(clauses->size() > 1){
-         renamesibs = true;
-      } 
-      psi = COPY(*clauses);
-      reduceMemoryFootprintNeg(*it);
-
-      for(it++; it != varphi.GetChildren().end(); it++){
-         if(renamesibs){
-            setDoSibRenamingNeg(*(info[*it]));
-         }
-         convertFormulaToCNF(*it, defs);
-         clauses = info[*it]->clausesneg;
-         if(clauses->size() > 1){
-            renamesibs = true;
-         }
-         oldpsi = psi;
-         psi = PRODUCT(*psi, *clauses);
-         reduceMemoryFootprintNeg(*it);
-         DELETE(oldpsi);
-      }
-
-      info[varphi]->clausesneg = psi;
-   }
-
-   void convertFormulaToCNFNegNAND(const ASTNode& varphi, BeevMgr::ClauseList* defs){
-      //****************************************
-      // (neg) NAND ~> UNION
-      //****************************************
-      ASTVec::const_iterator it = varphi.GetChildren().begin();
-      convertFormulaToCNF(*it, defs);
-      BeevMgr::ClauseList* psi = COPY(*(info[*it]->clausespos));
-      reduceMemoryFootprintPos(*it);
-      for(it++; it != varphi.GetChildren().end(); it++){
-         convertFormulaToCNF(*it, defs);
-         INPLACE_UNION(psi, *(info[*it]->clausespos));
-         reduceMemoryFootprintPos(*it);
-      }
-
-      info[varphi]->clausespos = psi;
-   }
-
-   void convertFormulaToCNFNegOR(const ASTNode& varphi, BeevMgr::ClauseList* defs){
-      //****************************************
-      // (neg) OR ~> UNION NOT
-      //****************************************
-      ASTVec::const_iterator it = varphi.GetChildren().begin();
-      convertFormulaToCNF(*it, defs);
-      BeevMgr::ClauseList* psi = COPY(*(info[*it]->clausesneg));
-      reduceMemoryFootprintNeg(*it);
-      for(it++; it != varphi.GetChildren().end(); it++){
-         convertFormulaToCNF(*it, defs);
-         INPLACE_UNION(psi, *(info[*it]->clausesneg));
-         reduceMemoryFootprintNeg(*it);
-      }
-
-      info[varphi]->clausesneg = psi;
-   }
-
-   void convertFormulaToCNFNegNOR(const ASTNode& varphi, BeevMgr::ClauseList* defs){
-      bool renamesibs = false;
-      BeevMgr::ClauseList* clauses;
-      BeevMgr::ClauseList* psi;
-      BeevMgr::ClauseList* oldpsi;
-
-      //****************************************
-      // (neg) NOR ~> PRODUCT
-      //****************************************
-      ASTVec::const_iterator it = varphi.GetChildren().begin();
-      convertFormulaToCNF(*it, defs);
-      clauses = info[*it]->clausespos;
-      if(clauses->size() > 1){
-         renamesibs = true;
-      }
-      psi = COPY(*clauses);
-      reduceMemoryFootprintPos(*it);
-
-      for(it++; it != varphi.GetChildren().end(); it++){
-         if(renamesibs){
-            setDoSibRenamingPos(*(info[*it]));
-         }
-         convertFormulaToCNF(*it, defs);
-         clauses = info[*it]->clausespos;
-         if(clauses->size() > 1){
-            renamesibs = true;
-         }
-         oldpsi = psi;
-         psi = PRODUCT(*psi, *clauses);
-         reduceMemoryFootprintPos(*it);
-         DELETE(oldpsi);
-      }
-
-      info[varphi]->clausesneg = psi;
-   }
-
-   void convertFormulaToCNFNegIMPLIES(const ASTNode& varphi, BeevMgr::ClauseList* defs){
-      //****************************************
-      // (neg) IMPLIES ~> UNION [0] ; NOT [1]
-      //****************************************
-      CNFInfo* x0 = info[varphi[0]];
-      CNFInfo* x1 = info[varphi[1]];
-      convertFormulaToCNF(varphi[0], defs);
-      convertFormulaToCNF(varphi[1], defs);
-      BeevMgr::ClauseList* psi = 
-         UNION(*(x0->clausespos), *(x1->clausesneg));
-      info[varphi]->clausesneg = psi;
-      reduceMemoryFootprintPos(varphi[0]);
-      reduceMemoryFootprintNeg(varphi[1]);
-   }
-
-   void convertFormulaToCNFNegITE(const ASTNode& varphi, BeevMgr::ClauseList* defs){
-      //****************************************
-      // (neg) ITE ~> UNION (PRODUCT NOT [0] ; NOT [1])
-      //  ; (PRODUCT [0] ; NOT [2])
-      //****************************************
-      CNFInfo* x0 = info[varphi[0]];
-      CNFInfo* x1 = info[varphi[1]];
-      CNFInfo* x2 = info[varphi[2]];
-      convertFormulaToCNF(varphi[0], defs);
-      if(x0->clausesneg->size() > 1){
-         setDoSibRenamingNeg(*x1);
-      }
-      convertFormulaToCNF(varphi[1], defs);
-      if(x0->clausespos->size() > 1){
-         setDoSibRenamingNeg(*x2);
-      }
-      convertFormulaToCNF(varphi[2], defs);
-      BeevMgr::ClauseList* psi1 = PRODUCT(*(x0->clausesneg)
-         , *(x1->clausesneg));
-      BeevMgr::ClauseList* psi2 = PRODUCT(*(x0->clausespos)
-         , *(x2->clausesneg));
-      NOCOPY_INPLACE_UNION(psi1, psi2);
-      reduceMemoryFootprintNeg(varphi[0]);
-      reduceMemoryFootprintNeg(varphi[1]);
-      reduceMemoryFootprintPos(varphi[0]);
-      reduceMemoryFootprintNeg(varphi[2]);
-
-      info[varphi]->clausesneg = psi1;
-   }
-
-   void convertFormulaToCNFNegXOR(const ASTNode& varphi, BeevMgr::ClauseList* defs){
-      BeevMgr::ClauseList* psi = convertFormulaToCNFNegXORAux(varphi, 0, defs);
-      info[varphi]->clausesneg = psi;
-   }
-
-   BeevMgr::ClauseList* convertFormulaToCNFNegXORAux(const ASTNode& varphi
-         , unsigned int idx, BeevMgr::ClauseList* defs){
-
-      bool renamesibs;
-      BeevMgr::ClauseList* psi;
-      BeevMgr::ClauseList* psi1;
-      BeevMgr::ClauseList* psi2;
-
-      if(idx == varphi.GetChildren().size() - 2){
-
-      //****************************************
-      // (neg) XOR ~> UNION 
-      //    (PRODUCT NOT   [idx]   ;     [idx+1])
-      //  ; (PRODUCT       [idx]   ; NOT [idx+1])
-      //****************************************
-         convertFormulaToCNF(varphi[idx], defs);
-         renamesibs = (info[varphi[idx]]->clausesneg)->size() > 1 ? true : false;
-         if(renamesibs){
-            setDoSibRenamingPos(*info[varphi[idx+1]]);
-         }
-         convertFormulaToCNF(varphi[idx+1], defs);
-
-
-         convertFormulaToCNF(varphi[idx], defs);
-         renamesibs = (info[varphi[idx]]->clausespos)->size() > 1 ? true : false;
-         if(renamesibs){
-            setDoSibRenamingNeg(*info[varphi[idx+1]]);
-         }
-         convertFormulaToCNF(varphi[idx+1], defs);
-
-         psi1 = PRODUCT(*(info[varphi[idx]]->clausesneg), *(info[varphi[idx+1]]->clausespos));
-         psi2 = PRODUCT(*(info[varphi[idx]]->clausespos), *(info[varphi[idx+1]]->clausesneg));
-         NOCOPY_INPLACE_UNION(psi1, psi2);
-         reduceMemoryFootprintNeg(varphi[idx]);
-         reduceMemoryFootprintPos(varphi[idx+1]);
-         reduceMemoryFootprintPos(varphi[idx]);
-         reduceMemoryFootprintNeg(varphi[idx+1]);
-
-         psi = psi1;
-      } else {
-
-      //****************************************
-      // (neg) XOR ~> UNION 
-      //    (PRODUCT NOT   [idx] ; XOR      [idx+1..])
-      //  ; (PRODUCT       [idx] ; NOT XOR  [idx+1..])
-      //****************************************
-         BeevMgr::ClauseList* theta1;
-         theta1 = convertFormulaToCNFPosXORAux(varphi, idx+1, defs);
-         renamesibs = theta1->size() > 1 ? true : false;
-         if(renamesibs){
-            setDoSibRenamingNeg(*info[varphi[idx]]);
-         }
-         convertFormulaToCNF(varphi[idx], defs);
-
-
-         BeevMgr::ClauseList* theta2;
-         theta2 = convertFormulaToCNFNegXORAux(varphi, idx+1, defs);
-         renamesibs = theta2->size() > 1 ? true : false;
-         if(renamesibs){
-            setDoSibRenamingPos(*info[varphi[idx]]);
-         }
-         convertFormulaToCNF(varphi[idx], defs);
-         
-         psi1 = PRODUCT(*(info[varphi[idx]]->clausesneg), *theta1);
-         psi2 = PRODUCT(*(info[varphi[idx]]->clausespos), *theta2);
-         DELETE(theta1);
-         DELETE(theta2);
-         NOCOPY_INPLACE_UNION(psi1, psi2);
-         reduceMemoryFootprintNeg(varphi[idx]);
-         reduceMemoryFootprintPos(varphi[idx]);
-
-         psi = psi1;
-      }
-
-      return psi;
-   }
-
-   //########################################
-   //########################################
-   // utilities for reclaiming memory.
-   
-   void reduceMemoryFootprintPos(const ASTNode& varphi){
-
-      CNFInfo* x = info[varphi];
-      if(sharesPos(*x) == 1){
-         DELETE(x->clausespos);
-         x->clausespos = NULL;
-         if(x->clausesneg == NULL){
-            delete x;
-            info.erase(varphi);
-         }
-      }
-   }
-
-   void reduceMemoryFootprintNeg(const ASTNode& varphi){
-
-      CNFInfo* x = info[varphi];
-      if(sharesNeg(*x) == 1){
-         DELETE(x->clausesneg);
-         x->clausesneg = NULL;
-         if(x->clausespos == NULL){
-            delete x;
-            info.erase(varphi);
-         }
-      }
-   }
-
-   //########################################
-   //########################################
-   
-   ASTNode* ASTNodeToASTNodePtr(const ASTNode& varphi){
-      ASTNode* psi;
-
-      if(store.find(varphi) != store.end()){
-         psi = store[varphi];
-      } else {
-         psi = new ASTNode(varphi);
-         store[varphi] = psi;
-      }
-
-      return psi;
-   }
-
-   //########################################
-   //########################################
-
-   void cleanup(const ASTNode& varphi){
-      delete info[varphi]->clausespos;
-      info.erase(varphi);
-
-      ASTNodeToCNFInfoMap::const_iterator it1 = info.begin();
-      for(; it1 != info.end(); it1++){
-         CNFInfo* x = it1->second;
-         if(x->clausespos != NULL){
-            DELETE(x->clausespos);
-         }
-         if(x->clausesneg != NULL){
-            if(!isTerm(*x)){
-               DELETE(x->clausesneg);
-            }
-         }
-         delete x;
-      }
-
-      info.clear();
-   }
+       void convertFormulaToCNFNegPred(const ASTNode& varphi, BeevMgr::ClauseList* defs)
+       {
+
+               ASTVec psis;
+
+               ASTVec::const_iterator it = varphi.GetChildren().begin();
+               for (; it != varphi.GetChildren().end(); it++)
+               {
+                       convertFormulaToCNF(*it, defs);
+                       psis.push_back(*(info[*it]->termforcnf));
+               }
+
+               info[varphi]->clausesneg = SINGLETON(bm->CreateNode(NOT, bm->CreateNode(varphi.GetKind(), psis)));
+       }
+
+       void convertFormulaToCNFNegFALSE(const ASTNode& varphi, BeevMgr::ClauseList* defs)
+       {
+               ASTNode dummy_true_var = bm->CreateSymbol("*TrueDummy*");
+               info[varphi]->clausesneg = SINGLETON(dummy_true_var);
+       }
+
+       void convertFormulaToCNFNegTRUE(const ASTNode& varphi, BeevMgr::ClauseList* defs)
+       {
+               ASTNode dummy_false_var = bm->CreateNode(NOT, bm->CreateSymbol("*TrueDummy*"));
+               info[varphi]->clausesneg = SINGLETON(dummy_false_var);
+       }
+
+       void convertFormulaToCNFNegBVGETBIT(const ASTNode& varphi, BeevMgr::ClauseList* defs)
+       {
+               BeevMgr::ClauseList* psi = SINGLETON(bm->CreateNode(NOT, varphi));
+               info[varphi]->clausesneg = psi;
+       }
+
+       void convertFormulaToCNFNegSYMBOL(const ASTNode& varphi, BeevMgr::ClauseList* defs)
+       {
+               info[varphi]->clausesneg = SINGLETON(bm->CreateNode(NOT, varphi));
+       }
+
+       void convertFormulaToCNFNegNOT(const ASTNode& varphi, BeevMgr::ClauseList* defs)
+       {
+               convertFormulaToCNF(varphi[0], defs);
+               info[varphi]->clausesneg = COPY(*(info[varphi[0]]->clausespos));
+               reduceMemoryFootprintPos(varphi[0]);
+       }
+
+       void convertFormulaToCNFNegAND(const ASTNode& varphi, BeevMgr::ClauseList* defs)
+       {
+               bool renamesibs = false;
+               BeevMgr::ClauseList* clauses;
+               BeevMgr::ClauseList* psi;
+               BeevMgr::ClauseList* oldpsi;
+
+               //****************************************
+               // (neg) AND ~> PRODUCT NOT
+               //****************************************
+
+               ASTVec::const_iterator it = varphi.GetChildren().begin();
+               convertFormulaToCNF(*it, defs);
+               clauses = info[*it]->clausesneg;
+               if (clauses->size() > 1)
+               {
+                       renamesibs = true;
+               }
+               psi = COPY(*clauses);
+               reduceMemoryFootprintNeg(*it);
+
+               for (it++; it != varphi.GetChildren().end(); it++)
+               {
+                       if (renamesibs)
+                       {
+                               setDoSibRenamingNeg(*(info[*it]));
+                       }
+                       convertFormulaToCNF(*it, defs);
+                       clauses = info[*it]->clausesneg;
+                       if (clauses->size() > 1)
+                       {
+                               renamesibs = true;
+                       }
+                       oldpsi = psi;
+                       psi = PRODUCT(*psi, *clauses);
+                       reduceMemoryFootprintNeg(*it);
+                       DELETE(oldpsi);
+               }
+
+               info[varphi]->clausesneg = psi;
+       }
+
+       void convertFormulaToCNFNegNAND(const ASTNode& varphi, BeevMgr::ClauseList* defs)
+       {
+               //****************************************
+               // (neg) NAND ~> UNION
+               //****************************************
+               ASTVec::const_iterator it = varphi.GetChildren().begin();
+               convertFormulaToCNF(*it, defs);
+               BeevMgr::ClauseList* psi = COPY(*(info[*it]->clausespos));
+               reduceMemoryFootprintPos(*it);
+               for (it++; it != varphi.GetChildren().end(); it++)
+               {
+                       convertFormulaToCNF(*it, defs);
+                       INPLACE_UNION(psi, *(info[*it]->clausespos));
+                       reduceMemoryFootprintPos(*it);
+               }
+
+               info[varphi]->clausespos = psi;
+       }
+
+       void convertFormulaToCNFNegOR(const ASTNode& varphi, BeevMgr::ClauseList* defs)
+       {
+               //****************************************
+               // (neg) OR ~> UNION NOT
+               //****************************************
+               ASTVec::const_iterator it = varphi.GetChildren().begin();
+               convertFormulaToCNF(*it, defs);
+               BeevMgr::ClauseList* psi = COPY(*(info[*it]->clausesneg));
+               reduceMemoryFootprintNeg(*it);
+               for (it++; it != varphi.GetChildren().end(); it++)
+               {
+                       convertFormulaToCNF(*it, defs);
+                       INPLACE_UNION(psi, *(info[*it]->clausesneg));
+                       reduceMemoryFootprintNeg(*it);
+               }
+
+               info[varphi]->clausesneg = psi;
+       }
+
+       void convertFormulaToCNFNegNOR(const ASTNode& varphi, BeevMgr::ClauseList* defs)
+       {
+               bool renamesibs = false;
+               BeevMgr::ClauseList* clauses;
+               BeevMgr::ClauseList* psi;
+               BeevMgr::ClauseList* oldpsi;
+
+               //****************************************
+               // (neg) NOR ~> PRODUCT
+               //****************************************
+               ASTVec::const_iterator it = varphi.GetChildren().begin();
+               convertFormulaToCNF(*it, defs);
+               clauses = info[*it]->clausespos;
+               if (clauses->size() > 1)
+               {
+                       renamesibs = true;
+               }
+               psi = COPY(*clauses);
+               reduceMemoryFootprintPos(*it);
+
+               for (it++; it != varphi.GetChildren().end(); it++)
+               {
+                       if (renamesibs)
+                       {
+                               setDoSibRenamingPos(*(info[*it]));
+                       }
+                       convertFormulaToCNF(*it, defs);
+                       clauses = info[*it]->clausespos;
+                       if (clauses->size() > 1)
+                       {
+                               renamesibs = true;
+                       }
+                       oldpsi = psi;
+                       psi = PRODUCT(*psi, *clauses);
+                       reduceMemoryFootprintPos(*it);
+                       DELETE(oldpsi);
+               }
+
+               info[varphi]->clausesneg = psi;
+       }
+
+       void convertFormulaToCNFNegIMPLIES(const ASTNode& varphi, BeevMgr::ClauseList* defs)
+       {
+               //****************************************
+               // (neg) IMPLIES ~> UNION [0] ; NOT [1]
+               //****************************************
+               CNFInfo* x0 = info[varphi[0]];
+               CNFInfo* x1 = info[varphi[1]];
+               convertFormulaToCNF(varphi[0], defs);
+               convertFormulaToCNF(varphi[1], defs);
+               BeevMgr::ClauseList* psi = UNION(*(x0->clausespos), *(x1->clausesneg));
+               info[varphi]->clausesneg = psi;
+               reduceMemoryFootprintPos(varphi[0]);
+               reduceMemoryFootprintNeg(varphi[1]);
+       }
+
+       void convertFormulaToCNFNegITE(const ASTNode& varphi, BeevMgr::ClauseList* defs)
+       {
+               //****************************************
+               // (neg) ITE ~> UNION (PRODUCT NOT [0] ; NOT [1])
+               //  ; (PRODUCT [0] ; NOT [2])
+               //****************************************
+               CNFInfo* x0 = info[varphi[0]];
+               CNFInfo* x1 = info[varphi[1]];
+               CNFInfo* x2 = info[varphi[2]];
+               convertFormulaToCNF(varphi[0], defs);
+               if (x0->clausesneg->size() > 1)
+               {
+                       setDoSibRenamingNeg(*x1);
+               }
+               convertFormulaToCNF(varphi[1], defs);
+               if (x0->clausespos->size() > 1)
+               {
+                       setDoSibRenamingNeg(*x2);
+               }
+               convertFormulaToCNF(varphi[2], defs);
+               BeevMgr::ClauseList* psi1 = PRODUCT(*(x0->clausesneg), *(x1->clausesneg));
+               BeevMgr::ClauseList* psi2 = PRODUCT(*(x0->clausespos), *(x2->clausesneg));
+               NOCOPY_INPLACE_UNION(psi1, psi2);
+               reduceMemoryFootprintNeg(varphi[0]);
+               reduceMemoryFootprintNeg(varphi[1]);
+               reduceMemoryFootprintPos(varphi[0]);
+               reduceMemoryFootprintNeg(varphi[2]);
+
+               info[varphi]->clausesneg = psi1;
+       }
+
+       void convertFormulaToCNFNegXOR(const ASTNode& varphi, BeevMgr::ClauseList* defs)
+       {
+               BeevMgr::ClauseList* psi = convertFormulaToCNFNegXORAux(varphi, 0, defs);
+               info[varphi]->clausesneg = psi;
+       }
+
+       BeevMgr::ClauseList* convertFormulaToCNFNegXORAux(const ASTNode& varphi, unsigned int idx, BeevMgr::ClauseList* defs)
+       {
+
+               bool renamesibs;
+               BeevMgr::ClauseList* psi;
+               BeevMgr::ClauseList* psi1;
+               BeevMgr::ClauseList* psi2;
+
+               if (idx == varphi.GetChildren().size() - 2)
+               {
+
+                       //****************************************
+                       // (neg) XOR ~> UNION
+                       //    (PRODUCT NOT   [idx]   ;     [idx+1])
+                       //  ; (PRODUCT       [idx]   ; NOT [idx+1])
+                       //****************************************
+                       convertFormulaToCNF(varphi[idx], defs);
+                       renamesibs = (info[varphi[idx]]->clausesneg)->size() > 1 ? true : false;
+                       if (renamesibs)
+                       {
+                               setDoSibRenamingPos(*info[varphi[idx + 1]]);
+                       }
+                       convertFormulaToCNF(varphi[idx + 1], defs);
+
+                       convertFormulaToCNF(varphi[idx], defs);
+                       renamesibs = (info[varphi[idx]]->clausespos)->size() > 1 ? true : false;
+                       if (renamesibs)
+                       {
+                               setDoSibRenamingNeg(*info[varphi[idx + 1]]);
+                       }
+                       convertFormulaToCNF(varphi[idx + 1], defs);
+
+                       psi1 = PRODUCT(*(info[varphi[idx]]->clausesneg), *(info[varphi[idx + 1]]->clausespos));
+                       psi2 = PRODUCT(*(info[varphi[idx]]->clausespos), *(info[varphi[idx + 1]]->clausesneg));
+                       NOCOPY_INPLACE_UNION(psi1, psi2);
+                       reduceMemoryFootprintNeg(varphi[idx]);
+                       reduceMemoryFootprintPos(varphi[idx + 1]);
+                       reduceMemoryFootprintPos(varphi[idx]);
+                       reduceMemoryFootprintNeg(varphi[idx + 1]);
+
+                       psi = psi1;
+               }
+               else
+               {
+
+                       //****************************************
+                       // (neg) XOR ~> UNION
+                       //    (PRODUCT NOT   [idx] ; XOR      [idx+1..])
+                       //  ; (PRODUCT       [idx] ; NOT XOR  [idx+1..])
+                       //****************************************
+                       BeevMgr::ClauseList* theta1;
+                       theta1 = convertFormulaToCNFPosXORAux(varphi, idx + 1, defs);
+                       renamesibs = theta1->size() > 1 ? true : false;
+                       if (renamesibs)
+                       {
+                               setDoSibRenamingNeg(*info[varphi[idx]]);
+                       }
+                       convertFormulaToCNF(varphi[idx], defs);
+
+                       BeevMgr::ClauseList* theta2;
+                       theta2 = convertFormulaToCNFNegXORAux(varphi, idx + 1, defs);
+                       renamesibs = theta2->size() > 1 ? true : false;
+                       if (renamesibs)
+                       {
+                               setDoSibRenamingPos(*info[varphi[idx]]);
+                       }
+                       convertFormulaToCNF(varphi[idx], defs);
+
+                       psi1 = PRODUCT(*(info[varphi[idx]]->clausesneg), *theta1);
+                       psi2 = PRODUCT(*(info[varphi[idx]]->clausespos), *theta2);
+                       DELETE(theta1);
+                       DELETE(theta2);
+                       NOCOPY_INPLACE_UNION(psi1, psi2);
+                       reduceMemoryFootprintNeg(varphi[idx]);
+                       reduceMemoryFootprintPos(varphi[idx]);
+
+                       psi = psi1;
+               }
+
+               return psi;
+       }
+
+       //########################################
+       //########################################
+       // utilities for reclaiming memory.
+
+       void reduceMemoryFootprintPos(const ASTNode& varphi)
+       {
+
+               CNFInfo* x = info[varphi];
+               if (sharesPos(*x) == 1)
+               {
+                       DELETE(x->clausespos);
+                       x->clausespos = NULL;
+                       if (x->clausesneg == NULL)
+                       {
+                               delete x;
+                               info.erase(varphi);
+                       }
+               }
+       }
+
+       void reduceMemoryFootprintNeg(const ASTNode& varphi)
+       {
+
+               CNFInfo* x = info[varphi];
+               if (sharesNeg(*x) == 1)
+               {
+                       DELETE(x->clausesneg);
+                       x->clausesneg = NULL;
+                       if (x->clausespos == NULL)
+                       {
+                               delete x;
+                               info.erase(varphi);
+                       }
+               }
+       }
+
+       //########################################
+       //########################################
+
+       ASTNode* ASTNodeToASTNodePtr(const ASTNode& varphi)
+       {
+               ASTNode* psi;
+
+               if (store.find(varphi) != store.end())
+               {
+                       psi = store[varphi];
+               }
+               else
+               {
+                       psi = new ASTNode(varphi);
+                       store[varphi] = psi;
+               }
+
+               return psi;
+       }
+
+       //########################################
+       //########################################
+
+       void cleanup(const ASTNode& varphi)
+       {
+               delete info[varphi]->clausespos;
+               info.erase(varphi);
+
+               ASTNodeToCNFInfoMap::const_iterator it1 = info.begin();
+               for (; it1 != info.end(); it1++)
+               {
+                       CNFInfo* x = it1->second;
+                       if (x->clausespos != NULL)
+                       {
+                               DELETE(x->clausespos);
+                       }
+                       if (x->clausesneg != NULL)
+                       {
+                               if (!isTerm(*x))
+                               {
+                                       DELETE(x->clausesneg);
+                               }
+                       }
+                       delete x;
+               }
+
+               info.clear();
+       }
 
 }; // end of CNFMgr class
 
-   int BeevMgr::TopLevelSAT( const ASTNode& inputasserts, const ASTNode& query) {  
-
-      ASTNode q = CreateNode(AND, inputasserts, CreateNode(NOT,query));
-      return TopLevelSATAux(q);
-   }
-
-   //############################################################
-   //############################################################
-
-
-  void BeevMgr::PrintClauseList(ostream& os, BeevMgr::ClauseList& cll)
-  {
-    int num_clauses = cll.size();
-    os << "Clauses: " << endl << "=========================================" << endl;
-    for(int i=0; i < num_clauses; i++) {
-      os << "Clause " << i << endl
-        << "-------------------------------------------" << endl;
-      LispPrintVecSpecial(os, *cll[i], 0);
-      os << endl
-        << "-------------------------------------------" << endl;
-    }
-  }
-
-  void BeevMgr::DeleteClauseList(BeevMgr::ClauseList *cllp)
-  {
-    BeevMgr::ClauseList::const_iterator iend = cllp->end();
-    for (BeevMgr::ClauseList::const_iterator i = cllp->begin(); i < iend; i++) {
-      delete *i;
-    }
-    delete cllp;
-  }
-
-  int BeevMgr::CallSAT_ResultCheck(MINISAT::Solver& newS, 
-                                  const ASTNode& q, const ASTNode& orig_input) {
-    ASTNode BBFormula = BBForm(q);
-    CNFMgr* cm = new CNFMgr(this);
-    ClauseList* cl = cm->convertToCNF(BBFormula);
-    if(stats)
-      cerr << "Number of clauses:" << cl->size() << endl;
-       //PrintClauseList(cout, *cl);
-    bool sat = toSATandSolve(newS,*cl);    
-    cm->DELETE(cl);
-    delete cm;
-
-    if(!sat) {
-      PrintOutput(true);
-      return 1;
-    }
-    else if(newS.okay()) {
-      CounterExampleMap.clear();
-      ConstructCounterExample(newS);
-      if (stats && print_nodes) {
-       PrintSATModel(newS);
-      }
-      //check if the counterexample is good or not
-      ComputeFormulaMap.clear();
-      if(counterexample_checking_during_refinement)
-       bvdiv_exception_occured = false;
-      ASTNode orig_result = ComputeFormulaUsingModel(orig_input);
-      if(!(ASTTrue == orig_result || ASTFalse == orig_result))
-       FatalError("TopLevelSat: Original input must compute to true or false against model");
-      
-//       if(!arrayread_refinement && !(ASTTrue == orig_result)) {
-//     print_counterexample = true;
-//     PrintCounterExample(true);
-//             FatalError("counterexample bogus : arrayread_refinement is switched off: " 
-//                        "EITHER all LA axioms have not been added OR bitblaster() or ToCNF()"
-//                "or satsolver() or counterexamplechecker() have a bug");
-//       }
-
-      // if the counterexample is indeed a good one, then return
-      // invalid
-      if(ASTTrue == orig_result) {
-       //CheckCounterExample(newS.okay());
-       PrintOutput(false);
-       PrintCounterExample(newS.okay());
-       PrintCounterExample_InOrder(newS.okay());
-       return 0;       
-      }
-      // counterexample is bogus: flag it
-      else {
-       if(stats && print_nodes) {
-         cout << "Supposedly bogus one: \n";
-         bool tmp = print_counterexample;
-         print_counterexample = true;
-         PrintCounterExample(true);
-         print_counterexample = tmp;
-       }
-
-       return 2;
-      }
-    }
-    else {
-      PrintOutput(true);
-      return -100;
-    }
-  } //end of CALLSAT_ResultCheck
+int BeevMgr::TopLevelSAT(const ASTNode& inputasserts, const ASTNode& query)
+{
+
+       ASTNode q = CreateNode(AND, inputasserts, CreateNode(NOT, query));
+       return TopLevelSATAux(q);
+}
+
+//############################################################
+//############################################################
+
+
+void BeevMgr::PrintClauseList(ostream& os, BeevMgr::ClauseList& cll)
+{
+       int num_clauses = cll.size();
+       os << "Clauses: " << endl << "=========================================" << endl;
+       for (int i = 0; i < num_clauses; i++)
+       {
+               os << "Clause " << i << endl << "-------------------------------------------" << endl;
+               LispPrintVecSpecial(os, *cll[i], 0);
+               os << endl << "-------------------------------------------" << endl;
+       }
+}
+
+void BeevMgr::DeleteClauseList(BeevMgr::ClauseList *cllp)
+{
+       BeevMgr::ClauseList::const_iterator iend = cllp->end();
+       for (BeevMgr::ClauseList::const_iterator i = cllp->begin(); i < iend; i++)
+       {
+               delete *i;
+       }
+       delete cllp;
+}
+
+int BeevMgr::CallSAT_ResultCheck(MINISAT::Solver& newS, const ASTNode& q, const ASTNode& orig_input)
+{
+       ASTNode BBFormula = BBForm(q);
+       CNFMgr* cm = new CNFMgr(this);
+       ClauseList* cl = cm->convertToCNF(BBFormula);
+       if (stats)
+               cerr << "Number of clauses:" << cl->size() << endl;
+       //PrintClauseList(cout, *cl);
+       bool sat = toSATandSolve(newS, *cl);
+       cm->DELETE(cl);
+       delete cm;
+
+       if (!sat)
+       {
+               PrintOutput(true);
+               return 1;
+       }
+       else if (newS.okay())
+       {
+               CounterExampleMap.clear();
+               ConstructCounterExample(newS);
+               if (stats && print_nodes)
+               {
+                       PrintSATModel(newS);
+               }
+               //check if the counterexample is good or not
+               ComputeFormulaMap.clear();
+               if (counterexample_checking_during_refinement)
+                       bvdiv_exception_occured = false;
+               ASTNode orig_result = ComputeFormulaUsingModel(orig_input);
+               if (!(ASTTrue == orig_result || ASTFalse == orig_result))
+                       FatalError("TopLevelSat: Original input must compute to true or false against model");
+
+               //       if(!arrayread_refinement && !(ASTTrue == orig_result)) {
+               //      print_counterexample = true;
+               //      PrintCounterExample(true);
+               //              FatalError("counterexample bogus : arrayread_refinement is switched off: "
+               //                         "EITHER all LA axioms have not been added OR bitblaster() or ToCNF()"
+               //                 "or satsolver() or counterexamplechecker() have a bug");
+               //       }
+
+               // if the counterexample is indeed a good one, then return
+               // invalid
+               if (ASTTrue == orig_result)
+               {
+                       //CheckCounterExample(newS.okay());
+                       PrintOutput(false);
+                       PrintCounterExample(newS.okay());
+                       PrintCounterExample_InOrder(newS.okay());
+                       return 0;
+               }
+               // counterexample is bogus: flag it
+               else
+               {
+                       if (stats && print_nodes)
+                       {
+                               cout << "Supposedly bogus one: \n";
+                               bool tmp = print_counterexample;
+                               print_counterexample = true;
+                               PrintCounterExample(true);
+                               print_counterexample = tmp;
+                       }
+
+                       return 2;
+               }
+       }
+       else
+       {
+               PrintOutput(true);
+               return -100;
+       }
+} //end of CALLSAT_ResultCheck
 
 
 } // end namespace
index af3f0b4ea154d6dc7c6ec57474a62a9149082723..f0505242c537759539e93d0029ad8abeb52c1e3b 100644 (file)
 #include "../simplifier/bvsolver.h"
 #include <math.h>
 
+namespace BEEV
+{
+/* FUNCTION: lookup or create a new MINISAT literal
+ * lookup or create new MINISAT Vars from the global MAP
+ * _ASTNode_to_SATVar.
+ */
+const MINISAT::Var BeevMgr::LookupOrCreateSATVar(MINISAT::Solver& newS, const ASTNode& n)
+{
+       ASTtoSATMap::iterator it;
+       MINISAT::Var v;
+
+       //look for the symbol in the global map from ASTNodes to ints. if
+       //not found, create a S.newVar(), else use the existing one.
+       if ((it = _ASTNode_to_SATVar.find(n)) == _ASTNode_to_SATVar.end())
+       {
+               v = newS.newVar();
+               _ASTNode_to_SATVar[n] = v;
+
+               //ASSUMPTION: I am assuming that the newS.newVar() call increments v
+               //by 1 each time it is called, and the initial value of a
+               //MINISAT::Var is 0.
+               _SATVar_to_AST.push_back(n);
+       }
+       else
+               v = it->second;
+       return v;
+}
+
+/* FUNCTION: convert ASTClauses to MINISAT clauses and solve.
+ * Accepts ASTClauses and converts them to MINISAT clauses. Then adds
+ * the newly minted MINISAT clauses to the local SAT instance, and
+ * calls solve(). If solve returns unsat, then stop and return
+ * unsat. else continue.
+ */
+// FIXME: Still need to deal with TRUE/FALSE in clauses!
+//bool BeevMgr::toSATandSolve(MINISAT::Solver& newS, BeevMgr::ClauseList& cll, ASTNodeToIntMap& heuristic)
+bool BeevMgr::toSATandSolve(MINISAT::Solver& newS, BeevMgr::ClauseList& cll)
+{
+       CountersAndStats("SAT Solver");
+
+       //iterate through the list (conjunction) of ASTclauses cll
+       BeevMgr::ClauseList::const_iterator i = cll.begin(), iend = cll.end();
+
+       if (i == iend)
+               FatalError("toSATandSolve: Nothing to Solve", ASTUndefined);
+
+       //turnOffSubsumption
+       // MKK: My understanding is that the rougly equivalent effect is had
+       // through setting the second argument of MINISAT::Solver::solve to
+       // true
+       //newS.turnOffSubsumption();
+
+       // (*i) is an ASTVec-ptr which denotes an ASTclause
+       //****************************************
+       // *i = vector<const ASTNode*>*
+       //****************************************
+       for (; i != iend; i++)
+       {
+               //Clause for the SATSolver
+               MINISAT::vec<MINISAT::Lit> satSolverClause;
+
+               //now iterate through the internals of the ASTclause itself
+               vector<const ASTNode*>::const_iterator j = (*i)->begin(), jend = (*i)->end();
+               //j is a disjunct in the ASTclause (*i)
+               for (; j != jend; j++)
+               {
+                       ASTNode node = **j;
+
+                       bool negate = (NOT == node.GetKind()) ? true : false;
+                       ASTNode n = negate ? node[0] : node;
+
+                       //Lookup or create the MINISAT::Var corresponding to the Booelan
+                       //ASTNode Variable, and push into sat Solver clause
+                       MINISAT::Var v = LookupOrCreateSATVar(newS, n);
+                       MINISAT::Lit l(v, negate);
+                       satSolverClause.push(l);
+               }
+               newS.addClause(satSolverClause);
+               // clause printing.
+               // (printClause<MINISAT::vec<MINISAT::Lit> >)(satSolverClause);
+               // cout << " 0 ";
+               // cout << endl;
+
+               if (newS.okay())
+               {
+                       continue;
+               }
+               else
+               {
+                       PrintStats(newS);
+                       return false;
+               }
+
+               if (!newS.simplify())
+               {
+                       PrintStats(newS);
+                       return false;
+               }
+       }
+
+       // if input is UNSAT return false, else return true
+       if (!newS.simplify())
+       {
+               PrintStats(newS);
+               return false;
+       }
+
+       //PrintActivityLevels_Of_SATVars("Before SAT:",newS);
+       //ChangeActivityLevels_Of_SATVars(newS);
+       //PrintActivityLevels_Of_SATVars("Before SAT and after initial bias:",newS);
+       newS.solve();
+       //PrintActivityLevels_Of_SATVars("After SAT",newS);
 
-namespace BEEV {
-  /* FUNCTION: lookup or create a new MINISAT literal
-   * lookup or create new MINISAT Vars from the global MAP
-   * _ASTNode_to_SATVar.
-   */
-  const MINISAT::Var BeevMgr::LookupOrCreateSATVar(MINISAT::Solver& newS, const ASTNode& n) {  
-    ASTtoSATMap::iterator it;  
-    MINISAT::Var v;
-    
-    //look for the symbol in the global map from ASTNodes to ints. if
-    //not found, create a S.newVar(), else use the existing one.
-    if((it = _ASTNode_to_SATVar.find(n)) == _ASTNode_to_SATVar.end()) {
-      v = newS.newVar();
-      _ASTNode_to_SATVar[n] = v;       
-      
-      //ASSUMPTION: I am assuming that the newS.newVar() call increments v
-      //by 1 each time it is called, and the initial value of a
-      //MINISAT::Var is 0.
-      _SATVar_to_AST.push_back(n);
-    }
-    else
-      v = it->second;
-    return v;
-  }
-  
-  /* FUNCTION: convert ASTClauses to MINISAT clauses and solve.
-   * Accepts ASTClauses and converts them to MINISAT clauses. Then adds
-   * the newly minted MINISAT clauses to the local SAT instance, and
-   * calls solve(). If solve returns unsat, then stop and return
-   * unsat. else continue.
-   */  
-  // FIXME: Still need to deal with TRUE/FALSE in clauses!
- //bool BeevMgr::toSATandSolve(MINISAT::Solver& newS, BeevMgr::ClauseList& cll, ASTNodeToIntMap& heuristic)
- bool BeevMgr::toSATandSolve(MINISAT::Solver& newS, BeevMgr::ClauseList& cll)
- {
-    CountersAndStats("SAT Solver");
-
-    //iterate through the list (conjunction) of ASTclauses cll
-    BeevMgr::ClauseList::const_iterator i = cll.begin(), iend = cll.end();
-    
-    if(i == iend)
-      FatalError("toSATandSolve: Nothing to Solve",ASTUndefined);
-    
-    //turnOffSubsumption
-    // MKK: My understanding is that the rougly equivalent effect is had
-    // through setting the second argument of MINISAT::Solver::solve to
-    // true
-    //newS.turnOffSubsumption();
-
-    // (*i) is an ASTVec-ptr which denotes an ASTclause
-    //****************************************
-    // *i = vector<const ASTNode*>*
-    //****************************************
-    for(; i!=iend; i++) {    
-      //Clause for the SATSolver
-      MINISAT::vec<MINISAT::Lit> satSolverClause;
-      
-      //now iterate through the internals of the ASTclause itself
-      vector<const ASTNode*>::const_iterator j = (*i)->begin(), jend = (*i)->end();
-      //j is a disjunct in the ASTclause (*i)
-      for(;j!=jend;j++) {
-         ASTNode node = **j;
-
-       bool negate = (NOT == node.GetKind()) ? true : false;           
-       ASTNode n = negate ? node[0] : node;
-       
-       //Lookup or create the MINISAT::Var corresponding to the Booelan
-       //ASTNode Variable, and push into sat Solver clause
-       MINISAT::Var v = LookupOrCreateSATVar(newS,n);
-       MINISAT::Lit l(v, negate);
-       satSolverClause.push(l);
-      }
-      newS.addClause(satSolverClause);
-      // clause printing.
-      // (printClause<MINISAT::vec<MINISAT::Lit> >)(satSolverClause);
-      // cout << " 0 ";
-      // cout << endl;
-      
-      if(newS.okay()) {
-       continue;
-      }
-      else {
        PrintStats(newS);
-       return false;
-      }
-      
-      if(!newS.simplify()) {
-       PrintStats(newS);
-       return false;
-      }
-    }
-
-    // if input is UNSAT return false, else return true    
-    if(!newS.simplify()) {
-      PrintStats(newS);
-      return false;
-    }
-    
-    //PrintActivityLevels_Of_SATVars("Before SAT:",newS);
-    //ChangeActivityLevels_Of_SATVars(newS);
-    //PrintActivityLevels_Of_SATVars("Before SAT and after initial bias:",newS); 
-    newS.solve();
-    //PrintActivityLevels_Of_SATVars("After SAT",newS);
-
-    PrintStats(newS);
-    if (newS.okay())
-      return true;
-    else
-      return false;
-  }
-
-  // GLOBAL FUNCTION: Prints statistics from the MINISAT Solver   
-  void BeevMgr::PrintStats(MINISAT::Solver& s) {
-    if(!stats)
-      return;
-    double  cpu_time = MINISAT::cpuTime();
-    uint64_t   mem_used = MINISAT::memUsed();
-    /*
-    reportf("restarts              : %"I64_fmt"\n", s.starts);
-    reportf("conflicts             : %-12"I64_fmt"   (%.0f /sec)\n", s.conflicts   , s.conflicts   /cpu_time);
-    reportf("decisions             : %-12"I64_fmt"   (%.0f /sec)\n", s.decisions   , s.decisions   /cpu_time);
-    reportf("propagations          : %-12"I64_fmt"   (%.0f /sec)\n", s.propagations, s.propagations/cpu_time);
-    reportf("conflict literals     : %-12"I64_fmt"   (%4.2f %% deleted)\n", 
-           s.tot_literals, 
-           (s.max_literals - s.tot_literals)*100 / (double)s.max_literals);
-    */
-    if (mem_used != 0) reportf("Memory used           : %.2f MB\n", mem_used / 1048576.0);
-    reportf("CPU time              : %g s\n", cpu_time);
-  }
-  
-  // Prints Satisfying assignment directly, for debugging.
-  void BeevMgr::PrintSATModel(MINISAT::Solver& newS) {
-    if(!newS.okay())
-      FatalError("PrintSATModel: NO COUNTEREXAMPLE TO PRINT",ASTUndefined);
-    // FIXME: Don't put tests like this in the print functions.  The print functions
-    // should print unconditionally.  Put a conditional around the call if you don't 
-    // want them to print
-    if(!(stats && print_nodes))
-      return;
-
-    int num_vars = newS.nVars();
-    cout << "Satisfying assignment: " << endl;
-    for (int i = 0; i < num_vars; i++) {
-      if (newS.model[i] == MINISAT::l_True) {
-       ASTNode s = _SATVar_to_AST[i];
-       cout << s << endl;
-      }
-      else if (newS.model[i] == MINISAT::l_False) {
-       ASTNode s = _SATVar_to_AST[i];
-       cout << CreateNode(NOT, s) << endl;
-      }
-    }
-  }
-
-
-  // Looks up truth value of ASTNode SYMBOL in MINISAT satisfying assignment.
-  // Returns ASTTrue if true, ASTFalse if false or undefined.
-  ASTNode BeevMgr::SymbolTruthValue(MINISAT::Solver &newS, ASTNode form) 
-  {
-    MINISAT::Var satvar = _ASTNode_to_SATVar[form];
-    if (newS.model[satvar] == MINISAT::l_True) {
-      return ASTTrue;
-    }
-    else {
-      // False or undefined.
-      return ASTFalse;
-    }
-  }
-
-
-  // This function is for debugging problems with BitBlast and especially
-  // ToCNF. It evaluates the bit-blasted formula in the satisfying
-  // assignment.  While doing that, it checks that every subformula has
-  // the same truth value as its representative literal, if it has one.
-  // If this condition is violated, it halts immediately (on the leftmost
-  // lowest term).
-  // Use CreateSimpForm to evaluate, even though it's expensive, so that
-  // we can use the partial truth assignment.
-  ASTNode BeevMgr::CheckBBandCNF(MINISAT::Solver& newS, ASTNode form)
-  {
-    // Clear memo table (in case newS has changed).
-    CheckBBandCNFMemo.clear();
-    // Call recursive version that does the work.
-    return CheckBBandCNF_int(newS, form);
-  }
-
-  // Recursive body CheckBBandCNF
-  // FIXME:  Modify this to just check if result is true, and print mismatch 
-  // if not.   Might have a trace flag for the other stuff.
-  ASTNode BeevMgr::CheckBBandCNF_int(MINISAT::Solver& newS, ASTNode form)
-  {
-
-    //    cout << "++++++++++++++++" << endl << "CheckBBandCNF_int form = " <<
-    //      form << endl;
-  
-    ASTNodeMap::iterator memoit = CheckBBandCNFMemo.find(form);
-    if (memoit != CheckBBandCNFMemo.end()) {
-      // found it.  Return memoized value.
-      return memoit->second;
-    }
-
-    ASTNode result;            // return value, to memoize.
-
-    Kind k = form.GetKind();
-    switch (k) {
-    case TRUE:
-    case FALSE: {
-      return form;
-      break;
-    }
-    case SYMBOL: 
-    case BVGETBIT:  {
-      // Look up the truth value
-      // ASTNode -> Sat -> Truthvalue -> ASTTrue or ASTFalse;
-      // FIXME: Could make up a fresh var in undefined case.
-
-      result = SymbolTruthValue(newS, form);
-
-      cout << "================" << endl << "Checking BB formula:" << form << endl;
-      cout << "----------------" << endl << "Result:" << result << endl;
-
-      break;
-    }
-    default: {
-      // Evaluate the children recursively.
-      ASTVec eval_children;
-      ASTVec ch = form.GetChildren();
-      ASTVec::iterator itend = ch.end();
-      for(ASTVec::iterator it = ch.begin(); it < itend; it++) {
-       eval_children.push_back(CheckBBandCNF_int(newS, *it));
-      }
-      result = CreateSimpForm(k, eval_children);
-
-      cout << "================" << endl << "Checking BB formula:" << form << endl;
-      cout << "----------------" << endl << "Result:" << result << endl;
-
-      ASTNode replit_eval;
-      // Compare with replit, if there is one.
-      ASTNodeMap::iterator replit_it = RepLitMap.find(form);
-      if (replit_it != RepLitMap.end()) {
-       ASTNode replit = RepLitMap[form];
-       // Replit is symbol or not symbol.
-       if (SYMBOL == replit.GetKind()) {
-         replit_eval = SymbolTruthValue(newS, replit);
+       if (newS.okay())
+               return true;
+       else
+               return false;
+}
+
+// GLOBAL FUNCTION: Prints statistics from the MINISAT Solver
+void BeevMgr::PrintStats(MINISAT::Solver& s)
+{
+       if (!stats)
+               return;
+       double cpu_time = MINISAT::cpuTime();
+       uint64_t mem_used = MINISAT::memUsed();
+       /*
+        reportf("restarts              : %"I64_fmt"\n", s.starts);
+        reportf("conflicts             : %-12"I64_fmt"   (%.0f /sec)\n", s.conflicts   , s.conflicts   /cpu_time);
+        reportf("decisions             : %-12"I64_fmt"   (%.0f /sec)\n", s.decisions   , s.decisions   /cpu_time);
+        reportf("propagations          : %-12"I64_fmt"   (%.0f /sec)\n", s.propagations, s.propagations/cpu_time);
+        reportf("conflict literals     : %-12"I64_fmt"   (%4.2f %% deleted)\n",
+        s.tot_literals,
+        (s.max_literals - s.tot_literals)*100 / (double)s.max_literals);
+        */
+       if (mem_used != 0)
+               reportf("Memory used           : %.2f MB\n", mem_used / 1048576.0);
+       reportf("CPU time              : %g s\n", cpu_time);
+}
+
+// Prints Satisfying assignment directly, for debugging.
+void BeevMgr::PrintSATModel(MINISAT::Solver& newS)
+{
+       if (!newS.okay())
+               FatalError("PrintSATModel: NO COUNTEREXAMPLE TO PRINT", ASTUndefined);
+       // FIXME: Don't put tests like this in the print functions.  The print functions
+       // should print unconditionally.  Put a conditional around the call if you don't
+       // want them to print
+       if (!(stats && print_nodes))
+               return;
+
+       int num_vars = newS.nVars();
+       cout << "Satisfying assignment: " << endl;
+       for (int i = 0; i < num_vars; i++)
+       {
+               if (newS.model[i] == MINISAT::l_True)
+               {
+                       ASTNode s = _SATVar_to_AST[i];
+                       cout << s << endl;
+               }
+               else if (newS.model[i] == MINISAT::l_False)
+               {
+                       ASTNode s = _SATVar_to_AST[i];
+                       cout << CreateNode(NOT, s) << endl;
+               }
+       }
+}
+
+// Looks up truth value of ASTNode SYMBOL in MINISAT satisfying assignment.
+// Returns ASTTrue if true, ASTFalse if false or undefined.
+ASTNode BeevMgr::SymbolTruthValue(MINISAT::Solver &newS, ASTNode form)
+{
+       MINISAT::Var satvar = _ASTNode_to_SATVar[form];
+       if (newS.model[satvar] == MINISAT::l_True)
+       {
+               return ASTTrue;
        }
-       else {
-         // It's (NOT sym).  Get value of sym and complement.
-         replit_eval = CreateSimpNot(SymbolTruthValue(newS, replit[0]));
+       else
+       {
+               // False or undefined.
+               return ASTFalse;
+       }
+}
+
+// This function is for debugging problems with BitBlast and especially
+// ToCNF. It evaluates the bit-blasted formula in the satisfying
+// assignment.  While doing that, it checks that every subformula has
+// the same truth value as its representative literal, if it has one.
+// If this condition is violated, it halts immediately (on the leftmost
+// lowest term).
+// Use CreateSimpForm to evaluate, even though it's expensive, so that
+// we can use the partial truth assignment.
+ASTNode BeevMgr::CheckBBandCNF(MINISAT::Solver& newS, ASTNode form)
+{
+       // Clear memo table (in case newS has changed).
+       CheckBBandCNFMemo.clear();
+       // Call recursive version that does the work.
+       return CheckBBandCNF_int(newS, form);
+}
+
+// Recursive body CheckBBandCNF
+// FIXME:  Modify this to just check if result is true, and print mismatch
+// if not.   Might have a trace flag for the other stuff.
+ASTNode BeevMgr::CheckBBandCNF_int(MINISAT::Solver& newS, ASTNode form)
+{
+
+       //    cout << "++++++++++++++++" << endl << "CheckBBandCNF_int form = " <<
+       //      form << endl;
+
+       ASTNodeMap::iterator memoit = CheckBBandCNFMemo.find(form);
+       if (memoit != CheckBBandCNFMemo.end())
+       {
+               // found it.  Return memoized value.
+               return memoit->second;
        }
 
-       cout << "----------------" << endl << "Rep lit: " << replit << endl;
-       cout << "----------------" << endl << "Rep lit value: " << replit_eval << endl;
+       ASTNode result; // return value, to memoize.
+
+       Kind k = form.GetKind();
+       switch (k)
+       {
+               case TRUE:
+               case FALSE:
+               {
+                       return form;
+                       break;
+               }
+               case SYMBOL:
+               case BVGETBIT:
+               {
+                       // Look up the truth value
+                       // ASTNode -> Sat -> Truthvalue -> ASTTrue or ASTFalse;
+                       // FIXME: Could make up a fresh var in undefined case.
+
+                       result = SymbolTruthValue(newS, form);
+
+                       cout << "================" << endl << "Checking BB formula:" << form << endl;
+                       cout << "----------------" << endl << "Result:" << result << endl;
 
-       if (result != replit_eval) {
-         // Hit the panic button.
-         FatalError("Truth value of BitBlasted formula disagrees with representative literal in CNF.");
+                       break;
+               }
+               default:
+               {
+                       // Evaluate the children recursively.
+                       ASTVec eval_children;
+                       ASTVec ch = form.GetChildren();
+                       ASTVec::iterator itend = ch.end();
+                       for (ASTVec::iterator it = ch.begin(); it < itend; it++)
+                       {
+                               eval_children.push_back(CheckBBandCNF_int(newS, *it));
+                       }
+                       result = CreateSimpForm(k, eval_children);
+
+                       cout << "================" << endl << "Checking BB formula:" << form << endl;
+                       cout << "----------------" << endl << "Result:" << result << endl;
+
+                       ASTNode replit_eval;
+                       // Compare with replit, if there is one.
+                       ASTNodeMap::iterator replit_it = RepLitMap.find(form);
+                       if (replit_it != RepLitMap.end())
+                       {
+                               ASTNode replit = RepLitMap[form];
+                               // Replit is symbol or not symbol.
+                               if (SYMBOL == replit.GetKind())
+                               {
+                                       replit_eval = SymbolTruthValue(newS, replit);
+                               }
+                               else
+                               {
+                                       // It's (NOT sym).  Get value of sym and complement.
+                                       replit_eval = CreateSimpNot(SymbolTruthValue(newS, replit[0]));
+                               }
+
+                               cout << "----------------" << endl << "Rep lit: " << replit << endl;
+                               cout << "----------------" << endl << "Rep lit value: " << replit_eval << endl;
+
+                               if (result != replit_eval)
+                               {
+                                       // Hit the panic button.
+                                       FatalError("Truth value of BitBlasted formula disagrees with representative literal in CNF.");
+                               }
+                       }
+                       else
+                       {
+                               cout << "----------------" << endl << "No rep lit" << endl;
+                       }
+
+               }
        }
-      }
-      else {
-       cout << "----------------" << endl << "No rep lit" << endl;
-      }
-
-    }
-    }
-
-    return (CheckBBandCNFMemo[form] = result);
-  }
-
-  /*FUNCTION: constructs counterexample from MINISAT counterexample
-   * step1 : iterate through MINISAT counterexample and assemble the
-   * bits for each AST term. Store it in a map from ASTNode to vector
-   * of bools (bits).
-   *
-   * step2: Iterate over the map from ASTNodes->Vector-of-Bools and
-   * populate the CounterExampleMap data structure (ASTNode -> BVConst)
-   */
-  void BeevMgr::ConstructCounterExample(MINISAT::Solver& newS) {
-    //iterate over MINISAT counterexample and construct a map from AST
-    //terms to vector of bools. We need this iteration step because
-    //MINISAT might return the various bits of a term out of
-    //order. Therfore, we need to collect all the bits and assemble
-    //them properly
-    
-    if(!newS.okay())
-      return;
-    if(!construct_counterexample)
-      return;    
-
-    CopySolverMap_To_CounterExample();
-    for (int i = 0; i < newS.nVars(); i++) {
-      //Make sure that the MINISAT::Var is defined
-      if (newS.model[i] != MINISAT::l_Undef) {
-       
-       //mapping from MINISAT::Vars to ASTNodes. We do not need to
-       //print MINISAT vars or CNF vars.
-       ASTNode s = _SATVar_to_AST[i];
-       
-       //assemble the counterexample here
-       if(s.GetKind() == BVGETBIT && s[0].GetKind() == SYMBOL) {
-         ASTNode symbol = s[0];
-         unsigned int symbolWidth = symbol.GetValueWidth();
-         
-         //'v' is the map from bit-index to bit-value
-         hash_map<unsigned,bool> * v;  
-         if(_ASTNode_to_Bitvector.find(symbol) == _ASTNode_to_Bitvector.end())
-           _ASTNode_to_Bitvector[symbol] = new hash_map<unsigned,bool>(symbolWidth);   
-         
-         //v holds the map from bit-index to bit-value
-         v = _ASTNode_to_Bitvector[symbol];
-         
-         //kk is the index of BVGETBIT
-         unsigned int kk = GetUnsignedConst(s[1]);     
-         
-         //Collect the bits of 'symbol' and store in v. Store in reverse order.
-         if(newS.model[i]==MINISAT::l_True)
-           (*v)[(symbolWidth-1) - kk] = true;
-         else
-           (*v)[(symbolWidth-1) - kk] = false;
+
+       return (CheckBBandCNFMemo[form] = result);
+}
+
+/*FUNCTION: constructs counterexample from MINISAT counterexample
+ * step1 : iterate through MINISAT counterexample and assemble the
+ * bits for each AST term. Store it in a map from ASTNode to vector
+ * of bools (bits).
+ *
+ * step2: Iterate over the map from ASTNodes->Vector-of-Bools and
+ * populate the CounterExampleMap data structure (ASTNode -> BVConst)
+ */
+void BeevMgr::ConstructCounterExample(MINISAT::Solver& newS)
+{
+       //iterate over MINISAT counterexample and construct a map from AST
+       //terms to vector of bools. We need this iteration step because
+       //MINISAT might return the various bits of a term out of
+       //order. Therfore, we need to collect all the bits and assemble
+       //them properly
+
+       if (!newS.okay())
+               return;
+       if (!construct_counterexample)
+               return;
+
+       CopySolverMap_To_CounterExample();
+       for (int i = 0; i < newS.nVars(); i++)
+       {
+               //Make sure that the MINISAT::Var is defined
+               if (newS.model[i] != MINISAT::l_Undef)
+               {
+
+                       //mapping from MINISAT::Vars to ASTNodes. We do not need to
+                       //print MINISAT vars or CNF vars.
+                       ASTNode s = _SATVar_to_AST[i];
+
+                       //assemble the counterexample here
+                       if (s.GetKind() == BVGETBIT && s[0].GetKind() == SYMBOL)
+                       {
+                               ASTNode symbol = s[0];
+                               unsigned int symbolWidth = symbol.GetValueWidth();
+
+                               //'v' is the map from bit-index to bit-value
+                               hash_map<unsigned, bool> * v;
+                               if (_ASTNode_to_Bitvector.find(symbol) == _ASTNode_to_Bitvector.end())
+                                       _ASTNode_to_Bitvector[symbol] = new hash_map<unsigned, bool> (symbolWidth);
+
+                               //v holds the map from bit-index to bit-value
+                               v = _ASTNode_to_Bitvector[symbol];
+
+                               //kk is the index of BVGETBIT
+                               unsigned int kk = GetUnsignedConst(s[1]);
+
+                               //Collect the bits of 'symbol' and store in v. Store in reverse order.
+                               if (newS.model[i] == MINISAT::l_True)
+                                       (*v)[(symbolWidth - 1) - kk] = true;
+                               else
+                                       (*v)[(symbolWidth - 1) - kk] = false;
+                       }
+                       else
+                       {
+                               if (s.GetKind() == SYMBOL && s.GetType() == BOOLEAN_TYPE)
+                               {
+                                       const char * zz = s.GetName();
+                                       //if the variables are not cnf variables then add them to the counterexample
+                                       if (0 != strncmp("cnf", zz, 3) && 0 != strcmp("*TrueDummy*", zz))
+                                       {
+                                               if (newS.model[i] == MINISAT::l_True)
+                                                       CounterExampleMap[s] = ASTTrue;
+                                               else if (newS.model[i] == MINISAT::l_False)
+                                                       CounterExampleMap[s] = ASTFalse;
+                                               else
+                                               {
+                                                       int seed = 10000;
+                                                       srand(seed);
+                                                       CounterExampleMap[s] = (rand() > seed) ? ASTFalse : ASTTrue;
+                                               }
+                                       }
+                               }
+                       }
+               }
        }
-       else {   
-         if(s.GetKind() == SYMBOL && s.GetType() == BOOLEAN_TYPE) {
-           const char * zz = s.GetName();
-           //if the variables are not cnf variables then add them to the counterexample
-           if(0 != strncmp("cnf",zz,3) && 0 != strcmp("*TrueDummy*",zz)) {
-             if(newS.model[i]==MINISAT::l_True)
-               CounterExampleMap[s] = ASTTrue;
-             else if(newS.model[i]==MINISAT::l_False)
-               CounterExampleMap[s] = ASTFalse;
-             else {
-               int seed = 10000;
-               srand(seed);
-               CounterExampleMap[s] = (rand() > seed) ? ASTFalse : ASTTrue;
-             }
-           }
-         }
+
+       //iterate over the ASTNode_to_Bitvector data-struct and construct
+       //the the aggregate value of the bitvector, and populate the
+       //CounterExampleMap datastructure
+       for (ASTtoBitvectorMap::iterator it = _ASTNode_to_Bitvector.begin(), itend = _ASTNode_to_Bitvector.end(); it != itend; it++)
+       {
+               ASTNode var = it->first;
+               //debugging
+               //cerr << var;
+               if (SYMBOL != var.GetKind())
+                       FatalError("ConstructCounterExample: error while constructing counterexample: not a variable: ", var);
+
+               //construct the bitvector value
+               hash_map<unsigned, bool> * w = it->second;
+               ASTNode value = BoolVectoBVConst(w, var.GetValueWidth());
+               //debugging
+               //cerr << value;
+
+               //populate the counterexample datastructure. add only scalars
+               //variables which were declared in the input and newly
+               //introduced variables for array reads
+               CounterExampleMap[var] = value;
        }
-      }
-    }
-
-    //iterate over the ASTNode_to_Bitvector data-struct and construct
-    //the the aggregate value of the bitvector, and populate the
-    //CounterExampleMap datastructure
-    for(ASTtoBitvectorMap::iterator it=_ASTNode_to_Bitvector.begin(),itend=_ASTNode_to_Bitvector.end();
-       it!=itend;it++) {
-      ASTNode var = it->first;      
-      //debugging
-      //cerr << var;
-      if(SYMBOL != var.GetKind())
-       FatalError("ConstructCounterExample: error while constructing counterexample: not a variable: ",var);
-
-      //construct the bitvector value
-      hash_map<unsigned,bool> * w = it->second;
-      ASTNode value = BoolVectoBVConst(w, var.GetValueWidth());      
-      //debugging
-      //cerr << value;
-
-      //populate the counterexample datastructure. add only scalars
-      //variables which were declared in the input and newly
-      //introduced variables for array reads
-      CounterExampleMap[var] = value;
-    }
-    
-    //In this loop, we compute the value of each array read, the
-    //corresponding ITE against the counterexample generated above.
-    for(ASTNodeMap::iterator it=_arrayread_ite.begin(),itend=_arrayread_ite.end();
-       it!=itend;it++){
-      //the array read
-      ASTNode arrayread = it->first;
-      ASTNode value_ite = _arrayread_ite[arrayread];
-      
-      //convert it to a constant array-read and store it in the
-      //counter-example. First convert the index into a constant. then
-      //construct the appropriate array-read and store it in the
-      //counterexample
-      ASTNode arrayread_index = TermToConstTermUsingModel(arrayread[1]);
-      ASTNode key = CreateTerm(READ,arrayread.GetValueWidth(),arrayread[0],arrayread_index);
-
-      //Get the ITE corresponding to the array-read and convert it
-      //to a constant against the model
-      ASTNode value = TermToConstTermUsingModel(value_ite);
-      //save the result in the counter_example
-      if(!CheckSubstitutionMap(key))
-       CounterExampleMap[key] = value;      
-    }
-  } //End of ConstructCounterExample
-
-  // FUNCTION: accepts a non-constant term, and returns the
-  // corresponding constant term with respect to a model. 
-  //
-  // term READ(A,i) is treated as follows:
-  //
-  //1. If (the boolean variable 'ArrayReadFlag' is true && ArrayRead
-  //1. has value in counterexample), then return the value of the
-  //1. arrayread.
-  //
-  //2. If (the boolean variable 'ArrayReadFlag' is true && ArrayRead
-  //2. doesn't have value in counterexample), then return the
-  //2. arrayread itself (normalized such that arrayread has a constant
-  //2. index)
-  //
-  //3. If (the boolean variable 'ArrayReadFlag' is false) && ArrayRead
-  //3. has a value in the counterexample then return the value of the
-  //3. arrayread.
-  //
-  //4. If (the boolean variable 'ArrayReadFlag' is false) && ArrayRead
-  //4. doesn't have a value in the counterexample then return 0 as the
-  //4. value of the arrayread.
-  ASTNode BeevMgr::TermToConstTermUsingModel(const ASTNode& t, bool ArrayReadFlag) {
-    Begin_RemoveWrites = false;
-    SimplifyWrites_InPlace_Flag = false;
-    //ASTNode term = SimplifyTerm(t);
-    ASTNode term = t;
-    Kind k = term.GetKind();
-    
-
-    //cerr << "Input to TermToConstTermUsingModel: " << term << endl;
-    if(!is_Term_kind(k)) {
-      FatalError("TermToConstTermUsingModel: The input is not a term: ",term);
-    }
-    if(k == WRITE) {
-      FatalError("TermToConstTermUsingModel: The input has wrong kind: WRITE : ",term);
-    }
-    if(k == SYMBOL && BOOLEAN_TYPE == term.GetType()) {
-      FatalError("TermToConstTermUsingModel: The input has wrong kind: Propositional variable : ",term);
-    }
-
-    ASTNodeMap::iterator it1;
-    if((it1 = CounterExampleMap.find(term)) != CounterExampleMap.end()) {
-      ASTNode val = it1->second;
-      if(BVCONST != val.GetKind()) {
-       //CounterExampleMap has two maps rolled into
-       //one. SubstitutionMap and SolverMap.
-       //
-       //recursion is fine here. There are two maps that are checked
-       //here. One is the substitutionmap. We garuntee that the value
-       //of a key in the substitutionmap is always a constant.
-       //
-       //in the SolverMap we garuntee that "term" does not occur in
-       //the value part of the map
-       if(term == val) {
-         FatalError("TermToConstTermUsingModel: The input term is stored as-is "
-                    "in the CounterExample: Not ok: ",term);    
+
+       //In this loop, we compute the value of each array read, the
+       //corresponding ITE against the counterexample generated above.
+       for (ASTNodeMap::iterator it = _arrayread_ite.begin(), itend = _arrayread_ite.end(); it != itend; it++)
+       {
+               //the array read
+               ASTNode arrayread = it->first;
+               ASTNode value_ite = _arrayread_ite[arrayread];
+
+               //convert it to a constant array-read and store it in the
+               //counter-example. First convert the index into a constant. then
+               //construct the appropriate array-read and store it in the
+               //counterexample
+               ASTNode arrayread_index = TermToConstTermUsingModel(arrayread[1]);
+               ASTNode key = CreateTerm(READ, arrayread.GetValueWidth(), arrayread[0], arrayread_index);
+
+               //Get the ITE corresponding to the array-read and convert it
+               //to a constant against the model
+               ASTNode value = TermToConstTermUsingModel(value_ite);
+               //save the result in the counter_example
+               if (!CheckSubstitutionMap(key))
+                       CounterExampleMap[key] = value;
+       }
+} //End of ConstructCounterExample
+
+// FUNCTION: accepts a non-constant term, and returns the
+// corresponding constant term with respect to a model.
+//
+// term READ(A,i) is treated as follows:
+//
+//1. If (the boolean variable 'ArrayReadFlag' is true && ArrayRead
+//1. has value in counterexample), then return the value of the
+//1. arrayread.
+//
+//2. If (the boolean variable 'ArrayReadFlag' is true && ArrayRead
+//2. doesn't have value in counterexample), then return the
+//2. arrayread itself (normalized such that arrayread has a constant
+//2. index)
+//
+//3. If (the boolean variable 'ArrayReadFlag' is false) && ArrayRead
+//3. has a value in the counterexample then return the value of the
+//3. arrayread.
+//
+//4. If (the boolean variable 'ArrayReadFlag' is false) && ArrayRead
+//4. doesn't have a value in the counterexample then return 0 as the
+//4. value of the arrayread.
+ASTNode BeevMgr::TermToConstTermUsingModel(const ASTNode& t, bool ArrayReadFlag)
+{
+       Begin_RemoveWrites = false;
+       SimplifyWrites_InPlace_Flag = false;
+       //ASTNode term = SimplifyTerm(t);
+       ASTNode term = t;
+       Kind k = term.GetKind();
+
+       //cerr << "Input to TermToConstTermUsingModel: " << term << endl;
+       if (!is_Term_kind(k))
+       {
+               FatalError("TermToConstTermUsingModel: The input is not a term: ", term);
+       }
+       if (k == WRITE)
+       {
+               FatalError("TermToConstTermUsingModel: The input has wrong kind: WRITE : ", term);
        }
-       return TermToConstTermUsingModel(val,ArrayReadFlag);
-      }
-      else {
-       return val;
-      }
-    }
-
-    ASTNode output;
-    switch(k) {
-    case BVCONST:
-      output = term;
-      break;
-    case SYMBOL: {
-      if(term.GetType() == ARRAY_TYPE) {
-       return term;
-      }
-
-      //when all else fails set symbol values to some constant by
-      //default. if the variable is queried the second time then add 1
-      //to and return the new value.
-      ASTNode zero = CreateZeroConst(term.GetValueWidth());
-      output = zero;
-      break;    
-    }
-    case READ: {      
-      ASTNode arrName = term[0];
-      ASTNode index = term[1];
-      if(0 == arrName.GetIndexWidth()) {
-       FatalError("TermToConstTermUsingModel: array has 0 index width: ",arrName);
-      }
-      
-      //READ over a WRITE
-      if(WRITE == arrName.GetKind()) {
-       ASTNode wrtterm = Expand_ReadOverWrite_UsingModel(term, ArrayReadFlag);
-       if(wrtterm == term) {
-         FatalError("TermToConstTermUsingModel: Read_Over_Write term must be expanded into an ITE", term);
+       if (k == SYMBOL && BOOLEAN_TYPE == term.GetType())
+       {
+               FatalError("TermToConstTermUsingModel: The input has wrong kind: Propositional variable : ", term);
        }
-       ASTNode rtterm = TermToConstTermUsingModel(wrtterm,ArrayReadFlag);      
-       return rtterm;
-      } 
-      //READ over an ITE
-      if(ITE == arrName.GetKind()) {
-       arrName = TermToConstTermUsingModel(arrName,ArrayReadFlag);
-      }
-
-      ASTNode modelentry;
-      if(CounterExampleMap.find(index) != CounterExampleMap.end()) {   
-       //index has a const value in the CounterExampleMap
-       //ASTNode indexVal = CounterExampleMap[index];
-   ASTNode indexVal = TermToConstTermUsingModel(CounterExampleMap[index], ArrayReadFlag);
-       modelentry = CreateTerm(READ, arrName.GetValueWidth(), arrName, indexVal);
-      }
-      else { 
-       //index does not have a const value in the CounterExampleMap. compute it.
-       ASTNode indexconstval = TermToConstTermUsingModel(index,ArrayReadFlag);
-       //update model with value of the index
-       //CounterExampleMap[index] = indexconstval;
-       modelentry = CreateTerm(READ,arrName.GetValueWidth(), arrName,indexconstval);   
-      }
-      //modelentry is now an arrayread over a constant index
-      BVTypeCheck(modelentry);
-      
-      //if a value exists in the CounterExampleMap then return it
-      if(CounterExampleMap.find(modelentry) != CounterExampleMap.end()) {
-       output = TermToConstTermUsingModel(CounterExampleMap[modelentry],ArrayReadFlag);
-      }
-      else if(ArrayReadFlag) {
-       //return the array read over a constantindex
-       output = modelentry;
-      }
-      else {
-       //when all else fails set symbol values to some constant by
-       //default. if the variable is queried the second time then add 1
-       //to and return the new value.
-       ASTNode zero = CreateZeroConst(modelentry.GetValueWidth());
-       output = zero;
-      }
-      break;
-    }
-    case ITE: {
-      ASTNode condcompute = ComputeFormulaUsingModel(term[0]);
-      if(ASTTrue == condcompute) {
-       output = TermToConstTermUsingModel(term[1],ArrayReadFlag);
-      }
-      else if(ASTFalse == condcompute) {
-       output = TermToConstTermUsingModel(term[2],ArrayReadFlag);
-      } 
-      else {
-       cerr << "TermToConstTermUsingModel: termITE: value of conditional is wrong: " << condcompute << endl; 
-       FatalError(" TermToConstTermUsingModel: termITE: cannot compute ITE conditional against model: ",term);
-      }
-      break;
-    }
-    default: {
-      ASTVec c = term.GetChildren();
-      ASTVec o;
-      for(ASTVec::iterator it=c.begin(),itend=c.end();it!=itend;it++) {
-       ASTNode ff = TermToConstTermUsingModel(*it,ArrayReadFlag);
-       o.push_back(ff);
-      }
-      output = CreateTerm(k,term.GetValueWidth(),o);
-      //output is a CONST expression. compute its value and store it
-      //in the CounterExampleMap
-      ASTNode oo = BVConstEvaluator(output);
-      //the return value
-      output = oo;
-      break;
-    }
-    }
-
-    //when this flag is false, we should compute the arrayread to a
-    //constant. this constant is stored in the counter_example
-    //datastructure
-    if(!ArrayReadFlag) {
-      CounterExampleMap[term] = output;
-    }
-    
-    //cerr << "Output to TermToConstTermUsingModel: " << output << endl;
-    return output;
-  } //End of TermToConstTermUsingModel
-
-  //Expands read-over-write by evaluating (readIndex=writeIndex) for
-  //every writeindex until, either it evaluates to TRUE or all
-  //(readIndex=writeIndex) evaluate to FALSE
-  ASTNode BeevMgr::Expand_ReadOverWrite_UsingModel(const ASTNode& term, bool arrayread_flag) {
-    if(READ != term.GetKind() && 
-       WRITE != term[0].GetKind()) {
-      FatalError("RemovesWrites: Input must be a READ over a WRITE",term);
-    }
-
-    ASTNode output;
-    ASTNodeMap::iterator it1;    
-    if((it1 = CounterExampleMap.find(term)) != CounterExampleMap.end()) {
-      ASTNode val = it1->second;
-      if(BVCONST != val.GetKind()) {
-       //recursion is fine here. There are two maps that are checked
-       //here. One is the substitutionmap. We garuntee that the value
-       //of a key in the substitutionmap is always a constant.
-       if(term == val) {
-         FatalError("TermToConstTermUsingModel: The input term is stored as-is "
-                    "in the CounterExample: Not ok: ",term);    
+
+       ASTNodeMap::iterator it1;
+       if ((it1 = CounterExampleMap.find(term)) != CounterExampleMap.end())
+       {
+               ASTNode val = it1->second;
+               if (BVCONST != val.GetKind())
+               {
+                       //CounterExampleMap has two maps rolled into
+                       //one. SubstitutionMap and SolverMap.
+                       //
+                       //recursion is fine here. There are two maps that are checked
+                       //here. One is the substitutionmap. We garuntee that the value
+                       //of a key in the substitutionmap is always a constant.
+                       //
+                       //in the SolverMap we garuntee that "term" does not occur in
+                       //the value part of the map
+                       if (term == val)
+                       {
+                               FatalError("TermToConstTermUsingModel: The input term is stored as-is "
+                                       "in the CounterExample: Not ok: ", term);
+                       }
+                       return TermToConstTermUsingModel(val, ArrayReadFlag);
+               }
+               else
+               {
+                       return val;
+               }
+       }
+
+       ASTNode output;
+       switch (k)
+       {
+               case BVCONST:
+                       output = term;
+                       break;
+               case SYMBOL:
+               {
+                       if (term.GetType() == ARRAY_TYPE)
+                       {
+                               return term;
+                       }
+
+                       //when all else fails set symbol values to some constant by
+                       //default. if the variable is queried the second time then add 1
+                       //to and return the new value.
+                       ASTNode zero = CreateZeroConst(term.GetValueWidth());
+                       output = zero;
+                       break;
+               }
+               case READ:
+               {
+                       ASTNode arrName = term[0];
+                       ASTNode index = term[1];
+                       if (0 == arrName.GetIndexWidth())
+                       {
+                               FatalError("TermToConstTermUsingModel: array has 0 index width: ", arrName);
+                       }
+
+                       //READ over a WRITE
+                       if (WRITE == arrName.GetKind())
+                       {
+                               ASTNode wrtterm = Expand_ReadOverWrite_UsingModel(term, ArrayReadFlag);
+                               if (wrtterm == term)
+                               {
+                                       FatalError("TermToConstTermUsingModel: Read_Over_Write term must be expanded into an ITE", term);
+                               }
+                               ASTNode rtterm = TermToConstTermUsingModel(wrtterm, ArrayReadFlag);
+                               return rtterm;
+                       }
+                       //READ over an ITE
+                       if (ITE == arrName.GetKind())
+                       {
+                               arrName = TermToConstTermUsingModel(arrName, ArrayReadFlag);
+                       }
+
+                       ASTNode modelentry;
+                       if (CounterExampleMap.find(index) != CounterExampleMap.end())
+                       {
+                               //index has a const value in the CounterExampleMap
+                               //ASTNode indexVal = CounterExampleMap[index];
+                               ASTNode indexVal = TermToConstTermUsingModel(CounterExampleMap[index], ArrayReadFlag);
+                               modelentry = CreateTerm(READ, arrName.GetValueWidth(), arrName, indexVal);
+                       }
+                       else
+                       {
+                               //index does not have a const value in the CounterExampleMap. compute it.
+                               ASTNode indexconstval = TermToConstTermUsingModel(index, ArrayReadFlag);
+                               //update model with value of the index
+                               //CounterExampleMap[index] = indexconstval;
+                               modelentry = CreateTerm(READ, arrName.GetValueWidth(), arrName, indexconstval);
+                       }
+                       //modelentry is now an arrayread over a constant index
+                       BVTypeCheck(modelentry);
+
+                       //if a value exists in the CounterExampleMap then return it
+                       if (CounterExampleMap.find(modelentry) != CounterExampleMap.end())
+                       {
+                               output = TermToConstTermUsingModel(CounterExampleMap[modelentry], ArrayReadFlag);
+                       }
+                       else if (ArrayReadFlag)
+                       {
+                               //return the array read over a constantindex
+                               output = modelentry;
+                       }
+                       else
+                       {
+                               //when all else fails set symbol values to some constant by
+                               //default. if the variable is queried the second time then add 1
+                               //to and return the new value.
+                               ASTNode zero = CreateZeroConst(modelentry.GetValueWidth());
+                               output = zero;
+                       }
+                       break;
+               }
+               case ITE:
+               {
+                       ASTNode condcompute = ComputeFormulaUsingModel(term[0]);
+                       if (ASTTrue == condcompute)
+                       {
+                               output = TermToConstTermUsingModel(term[1], ArrayReadFlag);
+                       }
+                       else if (ASTFalse == condcompute)
+                       {
+                               output = TermToConstTermUsingModel(term[2], ArrayReadFlag);
+                       }
+                       else
+                       {
+                               cerr << "TermToConstTermUsingModel: termITE: value of conditional is wrong: " << condcompute << endl;
+                               FatalError(" TermToConstTermUsingModel: termITE: cannot compute ITE conditional against model: ", term);
+                       }
+                       break;
+               }
+               default:
+               {
+                       ASTVec c = term.GetChildren();
+                       ASTVec o;
+                       for (ASTVec::iterator it = c.begin(), itend = c.end(); it != itend; it++)
+                       {
+                               ASTNode ff = TermToConstTermUsingModel(*it, ArrayReadFlag);
+                               o.push_back(ff);
+                       }
+                       output = CreateTerm(k, term.GetValueWidth(), o);
+                       //output is a CONST expression. compute its value and store it
+                       //in the CounterExampleMap
+                       ASTNode oo = BVConstEvaluator(output);
+                       //the return value
+                       output = oo;
+                       break;
+               }
        }
-       return TermToConstTermUsingModel(val,arrayread_flag);
-      }
-      else {
-       return val;
-      }
-    }
-
-    unsigned int width = term.GetValueWidth();
-    ASTNode writeA = ASTTrue; 
-    ASTNode newRead = term;
-    ASTNode readIndex = TermToConstTermUsingModel(newRead[1],false);
-    //iteratively expand read-over-write, and evaluate against the
-    //model at every iteration
-    do {
-      ASTNode write = newRead[0];
-      writeA = write[0];
-      ASTNode writeIndex = TermToConstTermUsingModel(write[1],false);
-      ASTNode writeVal = TermToConstTermUsingModel(write[2],false);
-      
-      ASTNode cond = ComputeFormulaUsingModel(CreateSimplifiedEQ(writeIndex,readIndex));
-      if(ASTTrue == cond) {
-       //found the write-value. return it
-       output = writeVal;
+
+       //when this flag is false, we should compute the arrayread to a
+       //constant. this constant is stored in the counter_example
+       //datastructure
+       if (!ArrayReadFlag)
+       {
+               CounterExampleMap[term] = output;
+       }
+
+       //cerr << "Output to TermToConstTermUsingModel: " << output << endl;
+       return output;
+} //End of TermToConstTermUsingModel
+
+//Expands read-over-write by evaluating (readIndex=writeIndex) for
+//every writeindex until, either it evaluates to TRUE or all
+//(readIndex=writeIndex) evaluate to FALSE
+ASTNode BeevMgr::Expand_ReadOverWrite_UsingModel(const ASTNode& term, bool arrayread_flag)
+{
+       if (READ != term.GetKind() && WRITE != term[0].GetKind())
+       {
+               FatalError("RemovesWrites: Input must be a READ over a WRITE", term);
+       }
+
+       ASTNode output;
+       ASTNodeMap::iterator it1;
+       if ((it1 = CounterExampleMap.find(term)) != CounterExampleMap.end())
+       {
+               ASTNode val = it1->second;
+               if (BVCONST != val.GetKind())
+               {
+                       //recursion is fine here. There are two maps that are checked
+                       //here. One is the substitutionmap. We garuntee that the value
+                       //of a key in the substitutionmap is always a constant.
+                       if (term == val)
+                       {
+                               FatalError("TermToConstTermUsingModel: The input term is stored as-is "
+                                       "in the CounterExample: Not ok: ", term);
+                       }
+                       return TermToConstTermUsingModel(val, arrayread_flag);
+               }
+               else
+               {
+                       return val;
+               }
+       }
+
+       unsigned int width = term.GetValueWidth();
+       ASTNode writeA = ASTTrue;
+       ASTNode newRead = term;
+       ASTNode readIndex = TermToConstTermUsingModel(newRead[1], false);
+       //iteratively expand read-over-write, and evaluate against the
+       //model at every iteration
+       do
+       {
+               ASTNode write = newRead[0];
+               writeA = write[0];
+               ASTNode writeIndex = TermToConstTermUsingModel(write[1], false);
+               ASTNode writeVal = TermToConstTermUsingModel(write[2], false);
+
+               ASTNode cond = ComputeFormulaUsingModel(CreateSimplifiedEQ(writeIndex, readIndex));
+               if (ASTTrue == cond)
+               {
+                       //found the write-value. return it
+                       output = writeVal;
+                       CounterExampleMap[term] = output;
+                       return output;
+               }
+
+               newRead = CreateTerm(READ, width, writeA, readIndex);
+       } while (READ == newRead.GetKind() && WRITE == newRead[0].GetKind());
+
+       output = TermToConstTermUsingModel(newRead, arrayread_flag);
+
+       //memoize
        CounterExampleMap[term] = output;
        return output;
-      }
-
-      newRead = CreateTerm(READ,width,writeA,readIndex);
-    } while(READ == newRead.GetKind() && WRITE == newRead[0].GetKind());
-    
-    output = TermToConstTermUsingModel(newRead,arrayread_flag);
-        
-    //memoize
-    CounterExampleMap[term] = output;
-    return output;  
-  } //Exand_ReadOverWrite_To_ITE_UsingModel()
-
-  /* FUNCTION: accepts a non-constant formula, and checks if the
-   * formula is ASTTrue or ASTFalse w.r.t to a model
-   */
-  ASTNode BeevMgr::ComputeFormulaUsingModel(const ASTNode& form) {
-    ASTNode in = form;
-    Kind k = form.GetKind();
-    if(!(is_Form_kind(k) && BOOLEAN_TYPE == form.GetType())) {
-      FatalError(" ComputeConstFormUsingModel: The input is a non-formula: ", form);
-    }
-
-    //cerr << "Input to ComputeFormulaUsingModel:" << form << endl;
-    ASTNodeMap::iterator it1;
-    if((it1 = ComputeFormulaMap.find(form)) != ComputeFormulaMap.end()) {
-      ASTNode res = it1->second;
-      if(ASTTrue == res || ASTFalse == res) {
-       return res;
-      }
-      else {
-       FatalError("ComputeFormulaUsingModel: The value of a formula must be TRUE or FALSE:", form);
-      }
-    }
-    
-    ASTNode t0,t1;
-    ASTNode output = ASTFalse;
-    switch(k) {
-    case TRUE:
-    case FALSE:
-      output = form;      
-      break;
-    case SYMBOL:
-      if(BOOLEAN_TYPE != form.GetType())
-       FatalError(" ComputeFormulaUsingModel: Non-Boolean variables are not formulas",form);
-      if(CounterExampleMap.find(form) != CounterExampleMap.end()) {
-       ASTNode counterexample_val = CounterExampleMap[form];
-       if(!VarSeenInTerm(form,counterexample_val)) {
-         output = ComputeFormulaUsingModel(counterexample_val);
+} //Exand_ReadOverWrite_To_ITE_UsingModel()
+
+/* FUNCTION: accepts a non-constant formula, and checks if the
+ * formula is ASTTrue or ASTFalse w.r.t to a model
+ */
+ASTNode BeevMgr::ComputeFormulaUsingModel(const ASTNode& form)
+{
+       ASTNode in = form;
+       Kind k = form.GetKind();
+       if (!(is_Form_kind(k) && BOOLEAN_TYPE == form.GetType()))
+       {
+               FatalError(" ComputeConstFormUsingModel: The input is a non-formula: ", form);
+       }
+
+       //cerr << "Input to ComputeFormulaUsingModel:" << form << endl;
+       ASTNodeMap::iterator it1;
+       if ((it1 = ComputeFormulaMap.find(form)) != ComputeFormulaMap.end())
+       {
+               ASTNode res = it1->second;
+               if (ASTTrue == res || ASTFalse == res)
+               {
+                       return res;
+               }
+               else
+               {
+                       FatalError("ComputeFormulaUsingModel: The value of a formula must be TRUE or FALSE:", form);
+               }
+       }
+
+       ASTNode t0, t1;
+       ASTNode output = ASTFalse;
+       switch (k)
+       {
+               case TRUE:
+               case FALSE:
+                       output = form;
+                       break;
+               case SYMBOL:
+                       if (BOOLEAN_TYPE != form.GetType())
+                               FatalError(" ComputeFormulaUsingModel: Non-Boolean variables are not formulas", form);
+                       if (CounterExampleMap.find(form) != CounterExampleMap.end())
+                       {
+                               ASTNode counterexample_val = CounterExampleMap[form];
+                               if (!VarSeenInTerm(form, counterexample_val))
+                               {
+                                       output = ComputeFormulaUsingModel(counterexample_val);
+                               }
+                               else
+                               {
+                                       output = counterexample_val;
+                               }
+                       }
+                       else
+                               output = ASTFalse;
+                       break;
+               case EQ:
+               case NEQ:
+               case BVLT:
+               case BVLE:
+               case BVGT:
+               case BVGE:
+               case BVSLT:
+               case BVSLE:
+               case BVSGT:
+               case BVSGE:
+                       //convert form[0] into a constant term
+                       t0 = TermToConstTermUsingModel(form[0], false);
+                       //convert form[0] into a constant term
+                       t1 = TermToConstTermUsingModel(form[1], false);
+                       output = BVConstEvaluator(CreateNode(k, t0, t1));
+
+                       //evaluate formula to false if bvdiv execption occurs while
+                       //counterexample is being checked during refinement.
+                       if (bvdiv_exception_occured && counterexample_checking_during_refinement)
+                       {
+                               output = ASTFalse;
+                       }
+                       break;
+               case NAND:
+               {
+                       ASTNode o = ASTTrue;
+                       for (ASTVec::const_iterator it = form.begin(), itend = form.end(); it != itend; it++)
+                               if (ASTFalse == ComputeFormulaUsingModel(*it))
+                               {
+                                       o = ASTFalse;
+                                       break;
+                               }
+                       if (o == ASTTrue)
+                               output = ASTFalse;
+                       else
+                               output = ASTTrue;
+                       break;
+               }
+               case NOR:
+               {
+                       ASTNode o = ASTFalse;
+                       for (ASTVec::const_iterator it = form.begin(), itend = form.end(); it != itend; it++)
+                               if (ASTTrue == ComputeFormulaUsingModel(*it))
+                               {
+                                       o = ASTTrue;
+                                       break;
+                               }
+                       if (o == ASTTrue)
+                               output = ASTFalse;
+                       else
+                               output = ASTTrue;
+                       break;
+               }
+               case NOT:
+                       if (ASTTrue == ComputeFormulaUsingModel(form[0]))
+                               output = ASTFalse;
+                       else
+                               output = ASTTrue;
+                       break;
+               case OR:
+                       for (ASTVec::const_iterator it = form.begin(), itend = form.end(); it != itend; it++)
+                               if (ASTTrue == ComputeFormulaUsingModel(*it))
+                                       output = ASTTrue;
+                       break;
+               case AND:
+                       output = ASTTrue;
+                       for (ASTVec::const_iterator it = form.begin(), itend = form.end(); it != itend; it++)
+                       {
+                               if (ASTFalse == ComputeFormulaUsingModel(*it))
+                               {
+                                       output = ASTFalse;
+                                       break;
+                               }
+                       }
+                       break;
+               case XOR:
+                       t0 = ComputeFormulaUsingModel(form[0]);
+                       t1 = ComputeFormulaUsingModel(form[1]);
+                       if ((ASTTrue == t0 && ASTTrue == t1) || (ASTFalse == t0 && ASTFalse == t1))
+                               output = ASTFalse;
+                       else
+                               output = ASTTrue;
+                       break;
+               case IFF:
+                       t0 = ComputeFormulaUsingModel(form[0]);
+                       t1 = ComputeFormulaUsingModel(form[1]);
+                       if ((ASTTrue == t0 && ASTTrue == t1) || (ASTFalse == t0 && ASTFalse == t1))
+                               output = ASTTrue;
+                       else
+                               output = ASTFalse;
+                       break;
+               case IMPLIES:
+                       t0 = ComputeFormulaUsingModel(form[0]);
+                       t1 = ComputeFormulaUsingModel(form[1]);
+                       if ((ASTFalse == t0) || (ASTTrue == t0 && ASTTrue == t1))
+                               output = ASTTrue;
+                       else
+                               output = ASTFalse;
+                       break;
+               case ITE:
+                       t0 = ComputeFormulaUsingModel(form[0]);
+                       if (ASTTrue == t0)
+                               output = ComputeFormulaUsingModel(form[1]);
+                       else if (ASTFalse == t0)
+                               output = ComputeFormulaUsingModel(form[2]);
+                       else
+                               FatalError("ComputeFormulaUsingModel: ITE: something is wrong with the formula: ", form);
+                       break;
+               default:
+                       FatalError(" ComputeFormulaUsingModel: the kind has not been implemented", ASTUndefined);
+                       break;
+       }
+
+       //cout << "ComputeFormulaUsingModel output is:" << output << endl;
+       ComputeFormulaMap[form] = output;
+       return output;
+}
+
+void BeevMgr::CheckCounterExample(bool t)
+{
+       // FIXME:  Code is more useful if enable flags are check OUTSIDE the method.
+       // If I want to check a counterexample somewhere, I don't want to have to set
+       // the flag in order to make it actualy happen!
+
+       printf("checking counterexample\n");
+       if (!check_counterexample)
+       {
+               return;
+       }
+
+       //input is valid, no counterexample to check
+       if (ValidFlag)
+               return;
+
+       //t is true if SAT solver generated a counterexample, else it is false
+       if (!t)
+               FatalError("CheckCounterExample: No CounterExample to check", ASTUndefined);
+       const ASTVec c = GetAsserts();
+       for (ASTVec::const_iterator it = c.begin(), itend = c.end(); it != itend; it++)
+               if (ASTFalse == ComputeFormulaUsingModel(*it))
+                       FatalError("CheckCounterExample:counterexample bogus:"
+                               "assert evaluates to FALSE under counterexample: NOT OK", *it);
+
+       if (ASTTrue == ComputeFormulaUsingModel(_current_query))
+               FatalError("CheckCounterExample:counterexample bogus:"
+                       "query evaluates to TRUE under counterexample: NOT OK", _current_query);
+}
+
+/* FUNCTION: prints a counterexample for INVALID inputs.  iterate
+ * through the CounterExampleMap data structure and print it to
+ * stdout
+ */
+void BeevMgr::PrintCounterExample(bool t, std::ostream& os)
+{
+       //global command-line option
+       // FIXME: This should always print the counterexample.  If you want
+       // to turn it off, check the switch at the point of call.
+       if (!print_counterexample)
+       {
+               return;
+       }
+
+       //input is valid, no counterexample to print
+       if (ValidFlag)
+       {
+               return;
+       }
+
+       //if this option is true then print the way dawson wants using a
+       //different printer. do not use this printer.
+       if (print_arrayval_declaredorder)
+       {
+               return;
+       }
+
+       //t is true if SAT solver generated a counterexample, else it is
+       //false
+       if (!t)
+       {
+               cerr << "PrintCounterExample: No CounterExample to print: " << endl;
+               return;
+       }
+
+       //os << "\nCOUNTEREXAMPLE: \n" << endl;
+       ASTNodeMap::iterator it = CounterExampleMap.begin();
+       ASTNodeMap::iterator itend = CounterExampleMap.end();
+       for (; it != itend; it++)
+       {
+               ASTNode f = it->first;
+               ASTNode se = it->second;
+
+               if (ARRAY_TYPE == se.GetType())
+               {
+                       FatalError("TermToConstTermUsingModel: entry in counterexample is an arraytype. bogus:", se);
+               }
+
+               //skip over introduced variables
+               if (f.GetKind() == SYMBOL && (_introduced_symbols.find(f) != _introduced_symbols.end()))
+                       continue;
+               if (f.GetKind() == SYMBOL || (f.GetKind() == READ && f[0].GetKind() == SYMBOL && f[1].GetKind() == BVCONST))
+               {
+                       os << "ASSERT( ";
+                       f.PL_Print(os, 0);
+                       os << " = ";
+                       if (BITVECTOR_TYPE == se.GetType())
+                       {
+                               TermToConstTermUsingModel(se, false).PL_Print(os, 0);
+                       }
+                       else
+                       {
+                               se.PL_Print(os, 0);
+                       }
+                       os << " );" << endl;
+               }
        }
-       else {
-         output = counterexample_val;
+       //os << "\nEND OF COUNTEREXAMPLE" << endl;
+} //End of PrintCounterExample
+
+/* iterate through the CounterExampleMap data structure and print it
+ * to stdout. this function prints only the declared array variables
+ * IN the ORDER in which they were declared. It also assumes that
+ * the variables are of the form 'varname_number'. otherwise it will
+ * not print anything. This function was specifically written for
+ * Dawson Engler's group (bug finding research group at Stanford)
+ */
+void BeevMgr::PrintCounterExample_InOrder(bool t)
+{
+       //global command-line option to print counterexample. we do not
+       //want both counterexample printers to print at the sametime.
+       // FIXME: This should always print the counterexample.  If you want
+       // to turn it off, check the switch at the point of call.
+       if (print_counterexample)
+               return;
+
+       //input is valid, no counterexample to print
+       if (ValidFlag)
+               return;
+
+       //print if the commandline option is '-q'. allows printing the
+       //counterexample in order.
+       if (!print_arrayval_declaredorder)
+               return;
+
+       //t is true if SAT solver generated a counterexample, else it is
+       //false
+       if (!t)
+       {
+               cerr << "PrintCounterExample: No CounterExample to print: " << endl;
+               return;
        }
-      }
-      else
-       output = ASTFalse;
-      break;  
-    case EQ:
-    case NEQ:
-    case BVLT:
-    case BVLE:
-    case BVGT:
-    case BVGE:
-    case BVSLT:
-    case BVSLE:
-    case BVSGT:
-    case BVSGE:
-      //convert form[0] into a constant term
-      t0 = TermToConstTermUsingModel(form[0],false);
-      //convert form[0] into a constant term
-      t1 = TermToConstTermUsingModel(form[1],false);
-      output = BVConstEvaluator(CreateNode(k,t0,t1));
-      
-      //evaluate formula to false if bvdiv execption occurs while
-      //counterexample is being checked during refinement.
-      if(bvdiv_exception_occured && 
-        counterexample_checking_during_refinement) {
-       output = ASTFalse;
-      }
-      break;   
-    case NAND: {
-      ASTNode o = ASTTrue;
-      for(ASTVec::const_iterator it=form.begin(),itend=form.end();it!=itend;it++)
-       if(ASTFalse == ComputeFormulaUsingModel(*it)) {
-         o = ASTFalse;
-         break;
-       }      
-      if(o == ASTTrue) 
-       output = ASTFalse;
-      else 
-       output = ASTTrue;
-      break;
-    }
-    case NOR: {
-      ASTNode o = ASTFalse;
-      for(ASTVec::const_iterator it=form.begin(),itend=form.end();it!=itend;it++)
-       if(ASTTrue == ComputeFormulaUsingModel(*it)) {
-         o = ASTTrue;
-         break;
+
+       //vector to store the integer values
+       std::vector<int> out_int;
+       cout << "% ";
+       for (ASTVec::iterator it = _special_print_set.begin(), itend = _special_print_set.end(); it != itend; it++)
+       {
+               if (ARRAY_TYPE == it->GetType())
+               {
+                       //get the name of the variable
+                       const char * c = it->GetName();
+                       std::string ss(c);
+                       if (!(0 == strncmp(ss.c_str(), "ini_", 4)))
+                               continue;
+                       reverse(ss.begin(), ss.end());
+
+                       //cout << "debugging: " << ss;
+                       size_t pos = ss.find('_', 0);
+                       if (!((0 < pos) && (pos < ss.size())))
+                               continue;
+
+                       //get the associated length
+                       std::string sss = ss.substr(0, pos);
+                       reverse(sss.begin(), sss.end());
+                       int n = atoi(sss.c_str());
+
+                       it->PL_Print(cout, 2);
+                       for (int j = 0; j < n; j++)
+                       {
+                               ASTNode index = CreateBVConst(it->GetIndexWidth(), j);
+                               ASTNode readexpr = CreateTerm(READ, it->GetValueWidth(), *it, index);
+                               ASTNode val = GetCounterExample(t, readexpr);
+                               //cout << "ASSERT( ";
+                               //cout << " = ";
+                               out_int.push_back(GetUnsignedConst(val));
+                               //cout << "\n";
+                       }
+               }
        }
-      if(o == ASTTrue) 
-       output = ASTFalse;
-      else 
-       output = ASTTrue;
-      break;
-    }
-    case NOT:
-      if(ASTTrue == ComputeFormulaUsingModel(form[0]))
-       output = ASTFalse;
-      else
-       output = ASTTrue;
-      break;
-    case OR:
-      for(ASTVec::const_iterator it=form.begin(),itend=form.end();it!=itend;it++) 
-       if(ASTTrue == ComputeFormulaUsingModel(*it))
-         output = ASTTrue;
-      break;
-    case AND:
-      output = ASTTrue;
-      for(ASTVec::const_iterator it=form.begin(),itend=form.end();it!=itend;it++) {
-       if(ASTFalse == ComputeFormulaUsingModel(*it)) {     
-         output = ASTFalse;
-         break;          
+       cout << endl;
+       for (unsigned int jj = 0; jj < out_int.size(); jj++)
+               cout << out_int[jj] << endl;
+       cout << endl;
+} //End of PrintCounterExample_InOrder
+
+/* FUNCTION: queries the CounterExampleMap object with 'expr' and
+ * returns the corresponding counterexample value.
+ */
+ASTNode BeevMgr::GetCounterExample(bool t, const ASTNode& expr)
+{
+       //input is valid, no counterexample to get
+       if (ValidFlag)
+               return ASTUndefined;
+
+       if (BOOLEAN_TYPE == expr.GetType())
+       {
+               return ComputeFormulaUsingModel(expr);
        }
-      }
-      break;
-    case XOR:
-      t0 = ComputeFormulaUsingModel(form[0]);
-      t1 = ComputeFormulaUsingModel(form[1]);
-      if((ASTTrue == t0 && ASTTrue == t1) || (ASTFalse == t0 && ASTFalse == t1))
-       output = ASTFalse;
-      else
-       output = ASTTrue;
-      break;
-    case IFF:
-      t0 = ComputeFormulaUsingModel(form[0]);
-      t1 = ComputeFormulaUsingModel(form[1]);
-      if((ASTTrue == t0 && ASTTrue == t1) || (ASTFalse == t0 && ASTFalse == t1))
-       output = ASTTrue;
-      else
-       output = ASTFalse;
-      break;
-    case IMPLIES:
-      t0 = ComputeFormulaUsingModel(form[0]);
-      t1 = ComputeFormulaUsingModel(form[1]);
-      if((ASTFalse == t0) || (ASTTrue == t0 && ASTTrue == t1))
-       output = ASTTrue;
-      else
-       output = ASTFalse;
-      break;    
-    case ITE:
-      t0 = ComputeFormulaUsingModel(form[0]);
-      if(ASTTrue == t0)
-       output = ComputeFormulaUsingModel(form[1]);
-      else if(ASTFalse == t0)
-       output = ComputeFormulaUsingModel(form[2]);
-      else 
-       FatalError("ComputeFormulaUsingModel: ITE: something is wrong with the formula: ",form);
-      break;
-    default:
-      FatalError(" ComputeFormulaUsingModel: the kind has not been implemented", ASTUndefined);
-      break;
-    }
-
-    //cout << "ComputeFormulaUsingModel output is:" << output << endl;
-    ComputeFormulaMap[form] = output;
-    return output;
-  }
-
-  void BeevMgr::CheckCounterExample(bool t) {
-    // FIXME:  Code is more useful if enable flags are check OUTSIDE the method.
-    // If I want to check a counterexample somewhere, I don't want to have to set
-    // the flag in order to make it actualy happen!
-
-     printf("checking counterexample\n");
-    if(!check_counterexample) {
-      return;
-    }
-
-    //input is valid, no counterexample to check
-    if(ValidFlag)
-      return;
-
-    //t is true if SAT solver generated a counterexample, else it is false
-    if(!t)
-      FatalError("CheckCounterExample: No CounterExample to check", ASTUndefined);
-    const ASTVec c = GetAsserts();    
-    for(ASTVec::const_iterator it=c.begin(),itend=c.end();it!=itend;it++)
-      if(ASTFalse == ComputeFormulaUsingModel(*it))
-       FatalError("CheckCounterExample:counterexample bogus:"\
-                  "assert evaluates to FALSE under counterexample: NOT OK",*it);
-        
-    if(ASTTrue == ComputeFormulaUsingModel(_current_query))
-      FatalError("CheckCounterExample:counterexample bogus:"\
-                "query evaluates to TRUE under counterexample: NOT OK",_current_query);
-  }
-
-  /* FUNCTION: prints a counterexample for INVALID inputs.  iterate
-   * through the CounterExampleMap data structure and print it to
-   * stdout
-   */
-  void BeevMgr::PrintCounterExample(bool t, std::ostream& os) {
-    //global command-line option
-    // FIXME: This should always print the counterexample.  If you want
-    // to turn it off, check the switch at the point of call.
-    if(!print_counterexample){
-      return;
-    }
-
-    //input is valid, no counterexample to print
-    if(ValidFlag){
-      return;
-    }
-
-    //if this option is true then print the way dawson wants using a
-    //different printer. do not use this printer.
-    if(print_arrayval_declaredorder){
-      return;
-    }
-
-    //t is true if SAT solver generated a counterexample, else it is
-    //false
-    if(!t) {
-      cerr << "PrintCounterExample: No CounterExample to print: " << endl;
-      return;
-    }
-
-    //os << "\nCOUNTEREXAMPLE: \n" << endl;
-    ASTNodeMap::iterator it  = CounterExampleMap.begin();
-    ASTNodeMap::iterator itend = CounterExampleMap.end();
-    for(;it!=itend;it++) {
-      ASTNode f = it->first;
-      ASTNode se = it->second;
-      
-      if(ARRAY_TYPE == se.GetType()) {
-       FatalError("TermToConstTermUsingModel: entry in counterexample is an arraytype. bogus:",se);
-      }
-
-      //skip over introduced variables
-      if(f.GetKind() == SYMBOL && (_introduced_symbols.find(f) != _introduced_symbols.end())) 
-       continue;
-      if(f.GetKind() == SYMBOL || 
-        (f.GetKind() == READ && f[0].GetKind() == SYMBOL && f[1].GetKind() == BVCONST)) {
-       os << "ASSERT( ";
-       f.PL_Print(os,0);
-       os << " = ";    
-       if(BITVECTOR_TYPE == se.GetType()) {
-         TermToConstTermUsingModel(se,false).PL_Print(os,0);
+
+       if (BVCONST == expr.GetKind())
+       {
+               return expr;
        }
-       else {
-         se.PL_Print(os,0);
+
+       ASTNodeMap::iterator it;
+       ASTNode output;
+       if ((it = CounterExampleMap.find(expr)) != CounterExampleMap.end())
+               output = TermToConstTermUsingModel(CounterExampleMap[expr], false);
+       else
+               output = CreateZeroConst(expr.GetValueWidth());
+       return output;
+} //End of GetCounterExample
+
+//##################################################
+//##################################################
+
+// FIXME:  Don't use numeric codes.  Use an enum type!
+//Acceps a query, calls the SAT solver and generates Valid/InValid.
+//if returned 0 then input is INVALID
+//if returned 1 then input is VALID
+//if returned 2 then ERROR
+int BeevMgr::TopLevelSATAux(const ASTNode& inputasserts)
+{
+       ASTNode q = inputasserts;
+       ASTNode orig_input = q;
+       ASTNodeStats("input asserts and query: ", q);
+
+       ASTNode newq = q;
+       //round of substitution, solving, and simplification. ensures that
+       //DAG is minimized as much as possibly, and ideally should
+       //garuntee that all liketerms in BVPLUSes have been combined.
+       BVSolver bvsolver(this);
+       SimplifyWrites_InPlace_Flag = false;
+       Begin_RemoveWrites = false;
+       start_abstracting = false;
+       TermsAlreadySeenMap.clear();
+       do
+       {
+               q = newq;
+               newq = CreateSubstitutionMap(newq);
+               //printf("##################################################\n");
+               //ASTNodeStats("after pure substitution: ", newq);
+               newq = SimplifyFormula_TopLevel(newq, false);
+               //ASTNodeStats("after simplification: ", newq);
+               newq = bvsolver.TopLevelBVSolve(newq);
+               //ASTNodeStats("after solving: ", newq);
+       } while (q != newq);
+
+       ASTNodeStats("Before SimplifyWrites_Inplace begins: ", newq);
+       SimplifyWrites_InPlace_Flag = true;
+       Begin_RemoveWrites = false;
+       start_abstracting = false;
+       TermsAlreadySeenMap.clear();
+       do
+       {
+               q = newq;
+               newq = CreateSubstitutionMap(newq);
+               //ASTNodeStats("after pure substitution: ", newq);
+               newq = SimplifyFormula_TopLevel(newq, false);
+               //ASTNodeStats("after simplification: ", newq);
+               newq = bvsolver.TopLevelBVSolve(newq);
+               //ASTNodeStats("after solving: ", newq);
+       } while (q != newq);
+       ASTNodeStats("After SimplifyWrites_Inplace: ", newq);
+
+       start_abstracting = (arraywrite_refinement) ? true : false;
+       SimplifyWrites_InPlace_Flag = false;
+       Begin_RemoveWrites = (start_abstracting) ? false : true;
+       if (start_abstracting)
+       {
+               ASTNodeStats("before abstraction round begins: ", newq);
        }
-       os << " );" << endl;
-      }
-    }        
-    //os << "\nEND OF COUNTEREXAMPLE" << endl;
-  } //End of PrintCounterExample
-
-  /* iterate through the CounterExampleMap data structure and print it
-   * to stdout. this function prints only the declared array variables
-   * IN the ORDER in which they were declared. It also assumes that
-   * the variables are of the form 'varname_number'. otherwise it will
-   * not print anything. This function was specifically written for
-   * Dawson Engler's group (bug finding research group at Stanford)
-   */
-  void BeevMgr::PrintCounterExample_InOrder(bool t) {
-    //global command-line option to print counterexample. we do not
-    //want both counterexample printers to print at the sametime.
-    // FIXME: This should always print the counterexample.  If you want
-    // to turn it off, check the switch at the point of call.
-    if(print_counterexample)
-      return;
-
-    //input is valid, no counterexample to print
-    if(ValidFlag)
-      return;
-    
-    //print if the commandline option is '-q'. allows printing the
-    //counterexample in order.
-    if(!print_arrayval_declaredorder)
-      return;
-
-    //t is true if SAT solver generated a counterexample, else it is
-    //false
-    if(!t) {
-      cerr << "PrintCounterExample: No CounterExample to print: " << endl;
-      return;
-    }
-    
-    //vector to store the integer values
-    std::vector<int> out_int;  
-    cout << "% ";
-    for(ASTVec::iterator it=_special_print_set.begin(),itend=_special_print_set.end();
-       it!=itend;it++) {
-      if(ARRAY_TYPE == it->GetType()) {
-       //get the name of the variable
-       const char * c = it->GetName();
-       std::string ss(c);
-       if(!(0 == strncmp(ss.c_str(),"ini_",4)))
-         continue;
-       reverse(ss.begin(),ss.end());
-
-       //cout << "debugging: " << ss;
-       size_t pos = ss.find('_',0);
-       if(!((0 < pos) && (pos < ss.size())))
-         continue;
-
-       //get the associated length
-       std::string sss = ss.substr(0,pos);
-       reverse(sss.begin(),sss.end());
-       int n = atoi(sss.c_str());
-
-       it->PL_Print(cout,2);
-       for(int j=0;j < n; j++) {
-         ASTNode index = CreateBVConst(it->GetIndexWidth(),j);
-         ASTNode readexpr = CreateTerm(READ,it->GetValueWidth(),*it,index);
-         ASTNode val = GetCounterExample(t, readexpr);
-         //cout << "ASSERT( ";
-         //cout << " = ";        
-         out_int.push_back(GetUnsignedConst(val));
-         //cout << "\n";
+
+       TermsAlreadySeenMap.clear();
+       do
+       {
+               q = newq;
+               //newq = CreateSubstitutionMap(newq);
+               //Begin_RemoveWrites = true;
+               //ASTNodeStats("after pure substitution: ", newq);
+               newq = SimplifyFormula_TopLevel(newq, false);
+               //ASTNodeStats("after simplification: ", newq);
+               //newq = bvsolver.TopLevelBVSolve(newq);
+               //ASTNodeStats("after solving: ", newq);
+       } while (q != newq);
+
+       if (start_abstracting)
+       {
+               ASTNodeStats("After abstraction: ", newq);
        }
-      }
-    }
-    cout << endl;
-    for(unsigned int jj=0; jj < out_int.size();jj++)
-      cout << out_int[jj] << endl;
-    cout << endl;
-  } //End of PrintCounterExample_InOrder
-
-  /* FUNCTION: queries the CounterExampleMap object with 'expr' and
-   * returns the corresponding counterexample value.
-   */
-  ASTNode BeevMgr::GetCounterExample(bool t, const ASTNode& expr) {    
-    //input is valid, no counterexample to get
-    if(ValidFlag)
-      return ASTUndefined;
-    
-    if(BOOLEAN_TYPE == expr.GetType()) {
-      return ComputeFormulaUsingModel(expr);
-    }
-
-    if(BVCONST == expr.GetKind()) {
-      return expr;
-    }
-
-    ASTNodeMap::iterator it;
-    ASTNode output;
-    if((it = CounterExampleMap.find(expr)) != CounterExampleMap.end())
-      output =  TermToConstTermUsingModel(CounterExampleMap[expr],false);
-    else
-      output = CreateZeroConst(expr.GetValueWidth());
-    return output;
-  } //End of GetCounterExample
-
-  //##################################################
-  //##################################################
-
-  // FIXME:  Don't use numeric codes.  Use an enum type!
-  //Acceps a query, calls the SAT solver and generates Valid/InValid.
-  //if returned 0 then input is INVALID
-  //if returned 1 then input is VALID
-  //if returned 2 then ERROR
-  int BeevMgr::TopLevelSATAux( const ASTNode& inputasserts) {  
-    ASTNode q = inputasserts;
-    ASTNode orig_input = q;
-    ASTNodeStats("input asserts and query: ", q);
-
-    ASTNode newq = q;
-    //round of substitution, solving, and simplification. ensures that
-    //DAG is minimized as much as possibly, and ideally should
-    //garuntee that all liketerms in BVPLUSes have been combined.
-    BVSolver bvsolver(this);
-    SimplifyWrites_InPlace_Flag = false;
-    Begin_RemoveWrites = false;
-    start_abstracting = false;    
-    TermsAlreadySeenMap.clear();
-    do {
-      q = newq;
-      newq = CreateSubstitutionMap(newq);
-      //printf("##################################################\n");
-      //ASTNodeStats("after pure substitution: ", newq);
-      newq = SimplifyFormula_TopLevel(newq,false);
-      //ASTNodeStats("after simplification: ", newq);
-      newq = bvsolver.TopLevelBVSolve(newq);
-      //ASTNodeStats("after solving: ", newq);      
-    }while(q!=newq);
-
-
-    ASTNodeStats("Before SimplifyWrites_Inplace begins: ", newq);
-    SimplifyWrites_InPlace_Flag = true;
-    Begin_RemoveWrites = false;
-    start_abstracting = false;
-    TermsAlreadySeenMap.clear();
-    do {
-      q = newq;
-      newq = CreateSubstitutionMap(newq);
-      //ASTNodeStats("after pure substitution: ", newq);
-      newq = SimplifyFormula_TopLevel(newq,false);
-      //ASTNodeStats("after simplification: ", newq);
-      newq = bvsolver.TopLevelBVSolve(newq);
-      //ASTNodeStats("after solving: ", newq);      
-    }while(q!=newq);
-    ASTNodeStats("After SimplifyWrites_Inplace: ", newq);        
-
-    start_abstracting = (arraywrite_refinement) ? true : false;
-    SimplifyWrites_InPlace_Flag = false;
-    Begin_RemoveWrites = (start_abstracting) ? false : true;    
-    if(start_abstracting) {
-      ASTNodeStats("before abstraction round begins: ", newq);
-    }
-
-    TermsAlreadySeenMap.clear();
-    do {
-      q = newq;
-      //newq = CreateSubstitutionMap(newq);
-      //Begin_RemoveWrites = true;
-      //ASTNodeStats("after pure substitution: ", newq);
-      newq = SimplifyFormula_TopLevel(newq,false);
-      //ASTNodeStats("after simplification: ", newq);
-      //newq = bvsolver.TopLevelBVSolve(newq);
-      //ASTNodeStats("after solving: ", newq);
-    }while(q!=newq);
-
-    if(start_abstracting) {
-      ASTNodeStats("After abstraction: ", newq);
-    }
-    start_abstracting = false;
-    SimplifyWrites_InPlace_Flag = false;
-    Begin_RemoveWrites = false;    
-    
-    newq = TransformFormula(newq);
-    ASTNodeStats("after transformation: ", newq);
-    TermsAlreadySeenMap.clear();
-
-    int res;    
-    //solver instantiated here
-    MINISAT::Solver newS;
-    if(arrayread_refinement) {
-      counterexample_checking_during_refinement = true;
-    }
-
-    res = CallSAT_ResultCheck(newS,newq,orig_input);
-    if(2 != res) {
-      CountersAndStats("print_func_stats");
-      return res;
-    }
-
-    res = SATBased_ArrayReadRefinement(newS,newq,orig_input);
-    if(2 != res) {
-      CountersAndStats("print_func_stats");
-      return res;
-    }
-    res = SATBased_ArrayWriteRefinement(newS,orig_input);
-    if(2 != res) {
-      CountersAndStats("print_func_stats");
-      return res;
-    }          
-
-    res = SATBased_ArrayReadRefinement(newS,newq,orig_input);
-    if(2 != res) {
-      CountersAndStats("print_func_stats");
-      return res;
-    }
-
-    FatalError("TopLevelSAT: reached the end without proper conclusion:" 
-              "either a divide by zero in the input or a bug in STP");
-    //bogus return to make the compiler shut up
-    return 2;
-  } //End of TopLevelSAT
-
-  //go over the list of indices for each array, and generate Leibnitz
-  //axioms. Then assert these axioms into the SAT solver. Check if the
-  //addition of the new constraints has made the bogus counterexample
-  //go away. if yes, return the correct answer. if no, continue adding
-  //Leibnitz axioms systematically.
-  // FIXME:  What it really does is, for each array, loop over each index i.
-  // inside that loop, it finds all the true and false axioms with i as first
-  // index.  When it's got them all, it adds the false axioms to the formula
-  // and re-solves, and returns if the result is correct.  Otherwise, it
-  // goes on to the next index.
-  // If it gets through all the indices without a correct result (which I think
-  // is impossible, but this is pretty confusing), it then solves with all
-  // the true axioms, too.
-  // This is not the most obvious way to do it, and I don't know how it 
-  // compares with other approaches (e.g., one false axiom at a time or
-  // all the false axioms each time).
-  int BeevMgr::SATBased_ArrayReadRefinement(MINISAT::Solver& newS, 
-                                           const ASTNode& q, const ASTNode& orig_input) {
-     //printf("doing array read refinement\n");
-    if(!arrayread_refinement)
-      FatalError("SATBased_ArrayReadRefinement: Control should not reach here");
-
-    ASTVec FalseAxiomsVec, RemainingAxiomsVec;
-    RemainingAxiomsVec.push_back(ASTTrue);   
-    FalseAxiomsVec.push_back(ASTTrue);
-    unsigned int oldFalseAxiomsSize = 0;
-
-    //in these loops we try to construct Leibnitz axioms and add it to
-    //the solve(). We add only those axioms that are false in the
-    //current counterexample. we keep adding the axioms until there
-    //are no more axioms to add
-    //
-    //for each array, fetch its list of indices seen so far
-    for(ASTNodeToVecMap::iterator iset = _arrayname_readindices.begin(), iset_end = _arrayname_readindices.end();
-       iset!=iset_end;iset++) {
-      ASTVec listOfIndices = iset->second;
-      //loop over the list of indices for the array and create LA, and add to q
-      for(ASTVec::iterator it=listOfIndices.begin(),itend=listOfIndices.end();it!=itend;it++) {
-       if(BVCONST == it->GetKind()) {
-         continue;
-       }       
-
-       ASTNode the_index = *it;
-       //get the arrayname
-       ASTNode ArrName = iset->first;
-       // if(SYMBOL != ArrName.GetKind())
-       //        FatalError("SATBased_ArrayReadRefinement: arrname is not a SYMBOL",ArrName);
-       ASTNode arr_read1 = CreateTerm(READ, ArrName.GetValueWidth(), ArrName, the_index);
-       //get the variable corresponding to the array_read1
-       ASTNode arrsym1 = _arrayread_symbol[arr_read1];
-       if(!(SYMBOL == arrsym1.GetKind() || BVCONST == arrsym1.GetKind()))
-         FatalError("TopLevelSAT: refinementloop:term arrsym1 corresponding to READ must be a var", arrsym1);
-
-       //we have nonconst index here. create Leibnitz axiom for it
-       //w.r.t every index in listOfIndices
-       for(ASTVec::iterator it1=listOfIndices.begin(),itend1=listOfIndices.end();
-           it1!=itend1;it1++) {
-         ASTNode compare_index = *it1;
-         //do not compare with yourself
-         if(the_index == compare_index)
-           continue;
-         
-         //prepare for SAT LOOP 
-         //first construct the antecedent for the LA axiom
-         ASTNode eqOfIndices = 
-           (exprless(the_index,compare_index)) ? 
-           CreateSimplifiedEQ(the_index,compare_index) : CreateSimplifiedEQ(compare_index,the_index);
-                 
-         ASTNode arr_read2 = CreateTerm(READ, ArrName.GetValueWidth(), ArrName, compare_index);
-         //get the variable corresponding to the array_read2
-         ASTNode arrsym2 = _arrayread_symbol[arr_read2];
-         if(!(SYMBOL == arrsym2.GetKind() || BVCONST == arrsym2.GetKind()))
-           FatalError("TopLevelSAT: refinement loop:"
-                      "term arrsym2 corresponding to READ must be a var", arrsym2);
-         
-         ASTNode eqOfReads = CreateSimplifiedEQ(arrsym1,arrsym2);
-         //construct appropriate Leibnitz axiom
-         ASTNode LeibnitzAxiom = CreateNode(IMPLIES, eqOfIndices, eqOfReads);
-         if(ASTFalse == ComputeFormulaUsingModel(LeibnitzAxiom))
-           //FalseAxioms = CreateNode(AND,FalseAxioms,LeibnitzAxiom);
-           FalseAxiomsVec.push_back(LeibnitzAxiom);
-         else
-           //RemainingAxioms = CreateNode(AND,RemainingAxioms,LeibnitzAxiom);
-           RemainingAxiomsVec.push_back(LeibnitzAxiom);
+       start_abstracting = false;
+       SimplifyWrites_InPlace_Flag = false;
+       Begin_RemoveWrites = false;
+
+       newq = TransformFormula(newq);
+       ASTNodeStats("after transformation: ", newq);
+       TermsAlreadySeenMap.clear();
+
+       int res;
+       //solver instantiated here
+       MINISAT::Solver newS;
+       if (arrayread_refinement)
+       {
+               counterexample_checking_during_refinement = true;
        }
-       ASTNode FalseAxioms = (FalseAxiomsVec.size()>1) ? CreateNode(AND,FalseAxiomsVec) : FalseAxiomsVec[0];
-       ASTNodeStats("adding false readaxioms to SAT: ", FalseAxioms);  
-   //printf("spot 01\n");
-   int res2 = 2;
-   if(FalseAxiomsVec.size() > oldFalseAxiomsSize){
-          res2 = CallSAT_ResultCheck(newS,FalseAxioms,orig_input);
-      oldFalseAxiomsSize = FalseAxiomsVec.size();
-   }
-   //printf("spot 02, res2 = %d\n", res2);
-       if(2!=res2) {
-         return res2;
-       }       
-      }
-    }
-    ASTNode RemainingAxioms = (RemainingAxiomsVec.size()>1) ? CreateNode(AND,RemainingAxiomsVec):RemainingAxiomsVec[0];
-    ASTNodeStats("adding remaining readaxioms to SAT: ", RemainingAxioms);  
-    return CallSAT_ResultCheck(newS,RemainingAxioms,orig_input);
-  } //end of SATBased_ArrayReadRefinement
-
-  ASTNode BeevMgr::Create_ArrayWriteAxioms(const ASTNode& term, const ASTNode& newvar) {
-    if(READ != term.GetKind() && WRITE != term[0].GetKind()) {
-      FatalError("Create_ArrayWriteAxioms: Input must be a READ over a WRITE",term);
-    }
-    
-    ASTNode lhs = newvar;
-    ASTNode rhs = term;
-    ASTNode arraywrite_axiom = CreateSimplifiedEQ(lhs,rhs);
-    return arraywrite_axiom;
-  }//end of Create_ArrayWriteAxioms()
-
-  int BeevMgr::SATBased_ArrayWriteRefinement(MINISAT::Solver& newS, const ASTNode& orig_input) {
-    ASTNode writeAxiom;
-    ASTNodeMap::iterator it = ReadOverWrite_NewName_Map.begin();
-    ASTNodeMap::iterator itend = ReadOverWrite_NewName_Map.end();
-    unsigned int oldFalseAxiomsSize = 0;
-    //int count = 0;
-    //int num_write_axioms = ReadOverWrite_NewName_Map.size();
-
-    ASTVec FalseAxioms, RemainingAxioms;
-    FalseAxioms.push_back(ASTTrue);
-    RemainingAxioms.push_back(ASTTrue);
-    for(;it!=itend;it++) {
-      //Guided refinement starts here
-      ComputeFormulaMap.clear();      
-      writeAxiom = Create_ArrayWriteAxioms(it->first,it->second);
-      if(ASTFalse == ComputeFormulaUsingModel(writeAxiom)) {
-       writeAxiom = TransformFormula(writeAxiom);
-       FalseAxioms.push_back(writeAxiom);
-      }
-      else {
-       writeAxiom = TransformFormula(writeAxiom);
-       RemainingAxioms.push_back(writeAxiom);
-      }
-    }
-      
-    writeAxiom = (FalseAxioms.size() != 1) ? CreateNode(AND,FalseAxioms) : FalseAxioms[0];
-    ASTNodeStats("adding false writeaxiom to SAT: ", writeAxiom);
-   int res2 = 2;
-   if(FalseAxioms.size() > oldFalseAxiomsSize){
-          res2 = CallSAT_ResultCheck(newS,writeAxiom,orig_input);
-      oldFalseAxiomsSize = FalseAxioms.size();
-   }
-    if(2!=res2) {
-      return res2;
-    }
-    
-    writeAxiom = (RemainingAxioms.size() != 1) ? CreateNode(AND,RemainingAxioms) : RemainingAxioms[0];
-    ASTNodeStats("adding remaining writeaxiom to SAT: ", writeAxiom);
-    res2 = CallSAT_ResultCheck(newS,writeAxiom,orig_input);
-    if(2!=res2) {
-       return res2;
-    }
-    
-    return 2;
-  } //end of SATBased_ArrayWriteRefinement
 
-#ifdef PHONY
-  //Check result after calling SAT FIXME: Document arguments in
-  //comments, and give them meaningful names.  How is anyone supposed
-  //to know what "q" is?
-  int BeevMgr::CallSAT_ResultCheck(MINISAT::Solver& newS, 
-                                  const ASTNode& q, const ASTNode& orig_input) {
-    //Bitblast, CNF, call SAT now
-    ASTNode BBFormula = BBForm(q);
-    //ASTNodeStats("after bitblasting", BBFormula);    
-    //ClauseList *cllp = ToCNF(BBFormula);
-    // if(stats && print_nodes) {
-    //       cout << "\nClause list" << endl;
-    //       PrintClauseList(cout, *cllp);
-    //       cerr << "\n finished printing clauselist\n";
-    //     }
-
-    //****************************************
-    // TOCNF CONVERSION
-    //****************************************
-      CNFMgr *cm = new CNFMgr(this);
-      
-      ClauseList* cllp = new ClauseList();
-      cm->NOCOPY_INPLACE_UNION(cllp, cm->SINGLETON(cm->dummy_true_var));
-      cm->CountSharesPos(BBFormula);
-      cm->ToCNFModRenamingPos(BBFormula);
-      cm->INPLACE_UNION(cllp, *((cm->ClausesPos)[BBFormula]));
-      cm->AddDefs(cllp);
-    //****************************************
-    // TOCNF CONVERSION
-    //****************************************
-
-    bool sat = toSATandSolve(newS,*cllp);    
-    // Temporary debugging call.
-    // CheckBBandCNF(newS, BBFormula);
-
-    //****************************************
-    // TOCNF CLEANUP
-    //****************************************
-      cm->CLEAR();
-      cm->DELETE(cllp);
-      delete cm;
-    //****************************************
-    // TOCNF CLEANUP
-    //****************************************
-
-    if(!sat) {
-      PrintOutput(true);
-      return 1;
-    }
-    else if(newS.okay()) {
-      CounterExampleMap.clear();
-      ConstructCounterExample(newS);
-      if (stats && print_nodes) {
-       PrintSATModel(newS);
-      }
-      //check if the counterexample is good or not
-      ComputeFormulaMap.clear();
-      if(counterexample_checking_during_refinement)
-       bvdiv_exception_occured = false;
-      ASTNode orig_result = ComputeFormulaUsingModel(orig_input);
-      if(!(ASTTrue == orig_result || ASTFalse == orig_result))
-       FatalError("TopLevelSat: Original input must compute to true or false against model");
-      
-//       if(!arrayread_refinement && !(ASTTrue == orig_result)) {
-//     print_counterexample = true;
-//     PrintCounterExample(true);
-//             FatalError("counterexample bogus : arrayread_refinement is switched off: " 
-//                        "EITHER all LA axioms have not been added OR bitblaster() or ToCNF()"
-//                "or satsolver() or counterexamplechecker() have a bug");
-//       }
-
-      // if the counterexample is indeed a good one, then return
-      // invalid
-      if(ASTTrue == orig_result) {
-       CheckCounterExample(newS.okay());
-       PrintOutput(false);
-       PrintCounterExample(newS.okay());
-       PrintCounterExample_InOrder(newS.okay());
-       return 0;       
-      }
-      // counterexample is bogus: flag it
-      else {
-       if(stats && print_nodes) {
-         cout << "Supposedly bogus one: \n";
-         bool tmp = print_counterexample;
-         print_counterexample = true;
-         PrintCounterExample(true);
-         print_counterexample = tmp;
+       res = CallSAT_ResultCheck(newS, newq, orig_input);
+       if (2 != res)
+       {
+               CountersAndStats("print_func_stats");
+               return res;
        }
 
+       res = SATBased_ArrayReadRefinement(newS, newq, orig_input);
+       if (2 != res)
+       {
+               CountersAndStats("print_func_stats");
+               return res;
+       }
+
+       res = SATBased_ArrayWriteRefinement(newS, orig_input);
+       if (2 != res)
+       {
+               CountersAndStats("print_func_stats");
+               return res;
+       }
+
+       res = SATBased_ArrayReadRefinement(newS, newq, orig_input);
+       if (2 != res)
+       {
+               CountersAndStats("print_func_stats");
+               return res;
+       }
+
+       FatalError("TopLevelSAT: reached the end without proper conclusion:"
+               "either a divide by zero in the input or a bug in STP");
+       //bogus return to make the compiler shut up
        return 2;
-      }
-    }
-    else {
-      PrintOutput(true);
-      return -100;
-    }
-  } //end of CALLSAT_ResultCheck
-#endif
+} //End of TopLevelSAT
+
+//go over the list of indices for each array, and generate Leibnitz
+//axioms. Then assert these axioms into the SAT solver. Check if the
+//addition of the new constraints has made the bogus counterexample
+//go away. if yes, return the correct answer. if no, continue adding
+//Leibnitz axioms systematically.
+// FIXME:  What it really does is, for each array, loop over each index i.
+// inside that loop, it finds all the true and false axioms with i as first
+// index.  When it's got them all, it adds the false axioms to the formula
+// and re-solves, and returns if the result is correct.  Otherwise, it
+// goes on to the next index.
+// If it gets through all the indices without a correct result (which I think
+// is impossible, but this is pretty confusing), it then solves with all
+// the true axioms, too.
+// This is not the most obvious way to do it, and I don't know how it
+// compares with other approaches (e.g., one false axiom at a time or
+// all the false axioms each time).
+int BeevMgr::SATBased_ArrayReadRefinement(MINISAT::Solver& newS, const ASTNode& q, const ASTNode& orig_input)
+{
+       //printf("doing array read refinement\n");
+       if (!arrayread_refinement)
+               FatalError("SATBased_ArrayReadRefinement: Control should not reach here");
+
+       ASTVec FalseAxiomsVec, RemainingAxiomsVec;
+       RemainingAxiomsVec.push_back(ASTTrue);
+       FalseAxiomsVec.push_back(ASTTrue);
+       unsigned int oldFalseAxiomsSize = 0;
+
+       //in these loops we try to construct Leibnitz axioms and add it to
+       //the solve(). We add only those axioms that are false in the
+       //current counterexample. we keep adding the axioms until there
+       //are no more axioms to add
+       //
+       //for each array, fetch its list of indices seen so far
+       for (ASTNodeToVecMap::iterator iset = _arrayname_readindices.begin(), iset_end = _arrayname_readindices.end(); iset != iset_end; iset++)
+       {
+               ASTVec listOfIndices = iset->second;
+               //loop over the list of indices for the array and create LA, and add to q
+               for (ASTVec::iterator it = listOfIndices.begin(), itend = listOfIndices.end(); it != itend; it++)
+               {
+                       if (BVCONST == it->GetKind())
+                       {
+                               continue;
+                       }
+
+                       ASTNode the_index = *it;
+                       //get the arrayname
+                       ASTNode ArrName = iset->first;
+                       // if(SYMBOL != ArrName.GetKind())
+                       //        FatalError("SATBased_ArrayReadRefinement: arrname is not a SYMBOL",ArrName);
+                       ASTNode arr_read1 = CreateTerm(READ, ArrName.GetValueWidth(), ArrName, the_index);
+                       //get the variable corresponding to the array_read1
+                       ASTNode arrsym1 = _arrayread_symbol[arr_read1];
+                       if (!(SYMBOL == arrsym1.GetKind() || BVCONST == arrsym1.GetKind()))
+                               FatalError("TopLevelSAT: refinementloop:term arrsym1 corresponding to READ must be a var", arrsym1);
+
+                       //we have nonconst index here. create Leibnitz axiom for it
+                       //w.r.t every index in listOfIndices
+                       for (ASTVec::iterator it1 = listOfIndices.begin(), itend1 = listOfIndices.end(); it1 != itend1; it1++)
+                       {
+                               ASTNode compare_index = *it1;
+                               //do not compare with yourself
+                               if (the_index == compare_index)
+                                       continue;
+
+                               //prepare for SAT LOOP
+                               //first construct the antecedent for the LA axiom
+                               ASTNode eqOfIndices = (exprless(the_index, compare_index)) ? CreateSimplifiedEQ(the_index, compare_index) : CreateSimplifiedEQ(
+                                               compare_index, the_index);
+
+                               ASTNode arr_read2 = CreateTerm(READ, ArrName.GetValueWidth(), ArrName, compare_index);
+                               //get the variable corresponding to the array_read2
+                               ASTNode arrsym2 = _arrayread_symbol[arr_read2];
+                               if (!(SYMBOL == arrsym2.GetKind() || BVCONST == arrsym2.GetKind()))
+                                       FatalError("TopLevelSAT: refinement loop:"
+                                               "term arrsym2 corresponding to READ must be a var", arrsym2);
+
+                               ASTNode eqOfReads = CreateSimplifiedEQ(arrsym1, arrsym2);
+                               //construct appropriate Leibnitz axiom
+                               ASTNode LeibnitzAxiom = CreateNode(IMPLIES, eqOfIndices, eqOfReads);
+                               if (ASTFalse == ComputeFormulaUsingModel(LeibnitzAxiom))
+                                       //FalseAxioms = CreateNode(AND,FalseAxioms,LeibnitzAxiom);
+                                       FalseAxiomsVec.push_back(LeibnitzAxiom);
+                               else
+                                       //RemainingAxioms = CreateNode(AND,RemainingAxioms,LeibnitzAxiom);
+                                       RemainingAxiomsVec.push_back(LeibnitzAxiom);
+                       }
+                       ASTNode FalseAxioms = (FalseAxiomsVec.size() > 1) ? CreateNode(AND, FalseAxiomsVec) : FalseAxiomsVec[0];
+                       ASTNodeStats("adding false readaxioms to SAT: ", FalseAxioms);
+                       //printf("spot 01\n");
+                       int res2 = 2;
+                       if (FalseAxiomsVec.size() > oldFalseAxiomsSize)
+                       {
+                               res2 = CallSAT_ResultCheck(newS, FalseAxioms, orig_input);
+                               oldFalseAxiomsSize = FalseAxiomsVec.size();
+                       }
+                       //printf("spot 02, res2 = %d\n", res2);
+                       if (2 != res2)
+                       {
+                               return res2;
+                       }
+               }
+       }
+       ASTNode RemainingAxioms = (RemainingAxiomsVec.size() > 1) ? CreateNode(AND, RemainingAxiomsVec) : RemainingAxiomsVec[0];
+       ASTNodeStats("adding remaining readaxioms to SAT: ", RemainingAxioms);
+       return CallSAT_ResultCheck(newS, RemainingAxioms, orig_input);
+} //end of SATBased_ArrayReadRefinement
+
+ASTNode BeevMgr::Create_ArrayWriteAxioms(const ASTNode& term, const ASTNode& newvar)
+{
+       if (READ != term.GetKind() && WRITE != term[0].GetKind())
+       {
+               FatalError("Create_ArrayWriteAxioms: Input must be a READ over a WRITE", term);
+       }
 
+       ASTNode lhs = newvar;
+       ASTNode rhs = term;
+       ASTNode arraywrite_axiom = CreateSimplifiedEQ(lhs, rhs);
+       return arraywrite_axiom;
+}//end of Create_ArrayWriteAxioms()
+
+int BeevMgr::SATBased_ArrayWriteRefinement(MINISAT::Solver& newS, const ASTNode& orig_input)
+{
+       ASTNode writeAxiom;
+       ASTNodeMap::iterator it = ReadOverWrite_NewName_Map.begin();
+       ASTNodeMap::iterator itend = ReadOverWrite_NewName_Map.end();
+       unsigned int oldFalseAxiomsSize = 0;
+       //int count = 0;
+       //int num_write_axioms = ReadOverWrite_NewName_Map.size();
+
+       ASTVec FalseAxioms, RemainingAxioms;
+       FalseAxioms.push_back(ASTTrue);
+       RemainingAxioms.push_back(ASTTrue);
+       for (; it != itend; it++)
+       {
+               //Guided refinement starts here
+               ComputeFormulaMap.clear();
+               writeAxiom = Create_ArrayWriteAxioms(it->first, it->second);
+               if (ASTFalse == ComputeFormulaUsingModel(writeAxiom))
+               {
+                       writeAxiom = TransformFormula(writeAxiom);
+                       FalseAxioms.push_back(writeAxiom);
+               }
+               else
+               {
+                       writeAxiom = TransformFormula(writeAxiom);
+                       RemainingAxioms.push_back(writeAxiom);
+               }
+       }
+
+       writeAxiom = (FalseAxioms.size() != 1) ? CreateNode(AND, FalseAxioms) : FalseAxioms[0];
+       ASTNodeStats("adding false writeaxiom to SAT: ", writeAxiom);
+       int res2 = 2;
+       if (FalseAxioms.size() > oldFalseAxiomsSize)
+       {
+               res2 = CallSAT_ResultCheck(newS, writeAxiom, orig_input);
+               oldFalseAxiomsSize = FalseAxioms.size();
+       }
+       if (2 != res2)
+       {
+               return res2;
+       }
+
+       writeAxiom = (RemainingAxioms.size() != 1) ? CreateNode(AND, RemainingAxioms) : RemainingAxioms[0];
+       ASTNodeStats("adding remaining writeaxiom to SAT: ", writeAxiom);
+       res2 = CallSAT_ResultCheck(newS, writeAxiom, orig_input);
+       if (2 != res2)
+       {
+               return res2;
+       }
+
+       return 2;
+} //end of SATBased_ArrayWriteRefinement
 
-  //FUNCTION: this function accepts a boolvector and returns a BVConst   
-  ASTNode BeevMgr::BoolVectoBVConst(hash_map<unsigned,bool> * w, unsigned int l) {    
-    unsigned len = w->size();
-    if(l < len)
-      FatalError("BoolVectorBVConst : length of bitvector does not match hash_map size:",ASTUndefined,l);
-    std::string cc;
-    for(unsigned int jj = 0; jj < l; jj++) {
-      if((*w)[jj] == true)
-       cc += '1';
-      else if((*w)[jj] == false)
-       cc += '0';
-      else 
-       cc += '0';
-    }
-    return CreateBVConst(cc.c_str(),2);
-  }
-
-  /*
-  void BeevMgr::PrintActivityLevels_Of_SATVars(char * init_msg, MINISAT::Solver& newS) {
-    if(!print_sat_varorder)
-      return;
-
-    ASTtoSATMap::iterator itbegin = _ASTNode_to_SATVar.begin();   
-    ASTtoSATMap::iterator itend = _ASTNode_to_SATVar.end();
-   
-    cout << init_msg;
-    cout << ": Printing activity levels of variables\n";
-    for(ASTtoSATMap::iterator it=itbegin;it!=itend;it++){
-      cout << (it->second) << "  :  ";
-      (it->first).PL_Print(cout,0);
-      cout << "   :   ";
-      cout << newS.returnActivity(it->second) << endl;
-    }
-  }
-
-  //this function biases the activity levels of MINISAT variables.
-  void BeevMgr::ChangeActivityLevels_Of_SATVars(MINISAT::Solver& newS) {
-    if(!variable_activity_optimize)
-      return;
-
-    ASTtoSATMap::iterator itbegin = _ASTNode_to_SATVar.begin();   
-    ASTtoSATMap::iterator itend = _ASTNode_to_SATVar.end();
-   
-    unsigned int index=1;
-    double base = 2;
-    for(ASTtoSATMap::iterator it=itbegin;it!=itend;it++){
-      ASTNode n = it->first;
-
-      if(BVGETBIT == n.GetKind() || NOT == n.GetKind()) {
-       if(BVGETBIT == n.GetKind())
-         index = GetUnsignedConst(n[1]);
-       else if (NOT == n.GetKind() && BVGETBIT == n[0].GetKind())
-         index = GetUnsignedConst(n[0][1]);
-       else 
-         index = 0;
-       double initial_activity = pow(base,(double)index);
-       newS.updateInitialActivity(it->second,initial_activity);
-      } 
-      else {
-       double initial_activity = pow(base,pow(base,(double)index));
-       newS.updateInitialActivity(it->second,initial_activity);        
-      }    
-    }
-  }
-  */
-
-  //This function prints the output of the STP solver
-  void BeevMgr::PrintOutput(bool true_iff_valid) {
-    //self-explanatory
-      if(print_output) {
-       if(smtlib_parser_enable)
-         {
-           if (true_iff_valid && (BEEV::input_status == TO_BE_SATISFIABLE))
-             {
-               cerr << "Warning. Expected satisfiable, FOUND unsatisfiable" << endl;
-             }
-           else
-             if (!true_iff_valid && (BEEV::input_status == TO_BE_UNSATISFIABLE))
+#ifdef PHONY
+//Check result after calling SAT FIXME: Document arguments in
+//comments, and give them meaningful names.  How is anyone supposed
+//to know what "q" is?
+int BeevMgr::CallSAT_ResultCheck(MINISAT::Solver& newS,
+               const ASTNode& q, const ASTNode& orig_input)
+{
+       //Bitblast, CNF, call SAT now
+       ASTNode BBFormula = BBForm(q);
+       //ASTNodeStats("after bitblasting", BBFormula);
+       //ClauseList *cllp = ToCNF(BBFormula);
+       // if(stats && print_nodes) {
+       //       cout << "\nClause list" << endl;
+       //       PrintClauseList(cout, *cllp);
+       //       cerr << "\n finished printing clauselist\n";
+       //     }
+
+       //****************************************
+       // TOCNF CONVERSION
+       //****************************************
+       CNFMgr *cm = new CNFMgr(this);
+
+       ClauseList* cllp = new ClauseList();
+       cm->NOCOPY_INPLACE_UNION(cllp, cm->SINGLETON(cm->dummy_true_var));
+       cm->CountSharesPos(BBFormula);
+       cm->ToCNFModRenamingPos(BBFormula);
+       cm->INPLACE_UNION(cllp, *((cm->ClausesPos)[BBFormula]));
+       cm->AddDefs(cllp);
+       //****************************************
+       // TOCNF CONVERSION
+       //****************************************
+
+       bool sat = toSATandSolve(newS,*cllp);
+       // Temporary debugging call.
+       // CheckBBandCNF(newS, BBFormula);
+
+       //****************************************
+       // TOCNF CLEANUP
+       //****************************************
+       cm->CLEAR();
+       cm->DELETE(cllp);
+       delete cm;
+       //****************************************
+       // TOCNF CLEANUP
+       //****************************************
+
+       if(!sat)
+       {
+               PrintOutput(true);
+               return 1;
+       }
+       else if(newS.okay())
+       {
+               CounterExampleMap.clear();
+               ConstructCounterExample(newS);
+               if (stats && print_nodes)
                {
-                 cerr << "Warning. Expected unsatisfiable, FOUND satisfiable" << endl;
+                       PrintSATModel(newS);
                }
-         }
-      }
-
-    if(true_iff_valid) {
-      ValidFlag = true;
-      if(print_output) {
-       if(smtlib_parser_enable)
-         cout << "unsat\n";
+               //check if the counterexample is good or not
+               ComputeFormulaMap.clear();
+               if(counterexample_checking_during_refinement)
+               bvdiv_exception_occured = false;
+               ASTNode orig_result = ComputeFormulaUsingModel(orig_input);
+               if(!(ASTTrue == orig_result || ASTFalse == orig_result))
+               FatalError("TopLevelSat: Original input must compute to true or false against model");
+
+               //       if(!arrayread_refinement && !(ASTTrue == orig_result)) {
+               //      print_counterexample = true;
+               //      PrintCounterExample(true);
+               //              FatalError("counterexample bogus : arrayread_refinement is switched off: "
+               //                         "EITHER all LA axioms have not been added OR bitblaster() or ToCNF()"
+               //                 "or satsolver() or counterexamplechecker() have a bug");
+               //       }
+
+               // if the counterexample is indeed a good one, then return
+               // invalid
+               if(ASTTrue == orig_result)
+               {
+                       CheckCounterExample(newS.okay());
+                       PrintOutput(false);
+                       PrintCounterExample(newS.okay());
+                       PrintCounterExample_InOrder(newS.okay());
+                       return 0;
+               }
+               // counterexample is bogus: flag it
+
+               else
+               {
+                       if(stats && print_nodes)
+                       {
+                               cout << "Supposedly bogus one: \n";
+                               bool tmp = print_counterexample;
+                               print_counterexample = true;
+                               PrintCounterExample(true);
+                               print_counterexample = tmp;
+                       }
+
+                       return 2;
+               }
+       }
        else
-         cout << "Valid.\n";
-      }
-    }
-    else {
-      ValidFlag = false;
-      if(print_output) {
-       if(smtlib_parser_enable)
-         cout << "sat\n";
+       {
+               PrintOutput(true);
+               return -100;
+       }
+} //end of CALLSAT_ResultCheck
+#endif
+
+//FUNCTION: this function accepts a boolvector and returns a BVConst
+ASTNode BeevMgr::BoolVectoBVConst(hash_map<unsigned, bool> * w, unsigned int l)
+{
+       unsigned len = w->size();
+       if (l < len)
+               FatalError("BoolVectorBVConst : length of bitvector does not match hash_map size:", ASTUndefined, l);
+       std::string cc;
+       for (unsigned int jj = 0; jj < l; jj++)
+       {
+               if ((*w)[jj] == true)
+                       cc += '1';
+               else if ((*w)[jj] == false)
+                       cc += '0';
+               else
+                       cc += '0';
+       }
+       return CreateBVConst(cc.c_str(), 2);
+}
+
+/*
+ void BeevMgr::PrintActivityLevels_Of_SATVars(char * init_msg, MINISAT::Solver& newS) {
+ if(!print_sat_varorder)
+ return;
+
+ ASTtoSATMap::iterator itbegin = _ASTNode_to_SATVar.begin();
+ ASTtoSATMap::iterator itend = _ASTNode_to_SATVar.end();
+
+ cout << init_msg;
+ cout << ": Printing activity levels of variables\n";
+ for(ASTtoSATMap::iterator it=itbegin;it!=itend;it++){
+ cout << (it->second) << "  :  ";
+ (it->first).PL_Print(cout,0);
+ cout << "   :   ";
+ cout << newS.returnActivity(it->second) << endl;
+ }
+ }
+
+ //this function biases the activity levels of MINISAT variables.
+ void BeevMgr::ChangeActivityLevels_Of_SATVars(MINISAT::Solver& newS) {
+ if(!variable_activity_optimize)
+ return;
+
+ ASTtoSATMap::iterator itbegin = _ASTNode_to_SATVar.begin();
+ ASTtoSATMap::iterator itend = _ASTNode_to_SATVar.end();
+
+ unsigned int index=1;
+ double base = 2;
+ for(ASTtoSATMap::iterator it=itbegin;it!=itend;it++){
+ ASTNode n = it->first;
+
+ if(BVGETBIT == n.GetKind() || NOT == n.GetKind()) {
+ if(BVGETBIT == n.GetKind())
+ index = GetUnsignedConst(n[1]);
+ else if (NOT == n.GetKind() && BVGETBIT == n[0].GetKind())
+ index = GetUnsignedConst(n[0][1]);
+ else
+ index = 0;
+ double initial_activity = pow(base,(double)index);
+ newS.updateInitialActivity(it->second,initial_activity);
+ }
+ else {
+ double initial_activity = pow(base,pow(base,(double)index));
+ newS.updateInitialActivity(it->second,initial_activity);
+ }
+ }
+ }
+ */
+
+//This function prints the output of the STP solver
+void BeevMgr::PrintOutput(bool true_iff_valid)
+{
+       //self-explanatory
+       if (print_output)
+       {
+               if (smtlib_parser_enable)
+               {
+                       if (true_iff_valid && (BEEV::input_status == TO_BE_SATISFIABLE))
+                       {
+                               cerr << "Warning. Expected satisfiable, FOUND unsatisfiable" << endl;
+                       }
+                       else if (!true_iff_valid && (BEEV::input_status == TO_BE_UNSATISFIABLE))
+                       {
+                               cerr << "Warning. Expected unsatisfiable, FOUND satisfiable" << endl;
+                       }
+               }
+       }
+
+       if (true_iff_valid)
+       {
+               ValidFlag = true;
+               if (print_output)
+               {
+                       if (smtlib_parser_enable)
+                               cout << "unsat\n";
+                       else
+                               cout << "Valid.\n";
+               }
+       }
        else
-         cout << "Invalid.\n";
-      }
-    }
-  }
-}; //end of namespace BEEV
+       {
+               ValidFlag = false;
+               if (print_output)
+               {
+                       if (smtlib_parser_enable)
+                               cout << "sat\n";
+                       else
+                               cout << "Invalid.\n";
+               }
+       }
+}
+}
+; //end of namespace BEEV
index a9d8274e5b80529e8a2d13427edce7cc8552907f..ecb522348f35e25d7b7afc0c78dcdadae09dfc1c 100644 (file)
 #include "AST.h"
 #include <stdlib.h>
 #include <stdio.h>
-namespace BEEV {  
-  
-  //Translates signed BVDIV/BVMOD into unsigned variety
-  ASTNode BeevMgr::TranslateSignedDivMod(const ASTNode& in) {
-    if(!(SBVREM == in.GetKind() || SBVDIV == in.GetKind())) {
-      FatalError("TranslateSignedDivMod: input must be signed DIV/MOD\n",in);
-    }
-
-    ASTNode dividend = in[0];
-    ASTNode divisor  = in[1];      
-    unsigned len = in.GetValueWidth();
-
-    ASTNode hi1  = CreateBVConst(32,len-1);
-    ASTNode one  = CreateOneConst(1);
-    ASTNode zero = CreateZeroConst(1);
-    // create the condition for the dividend
-    ASTNode cond_dividend = CreateNode(EQ,one,CreateTerm(BVEXTRACT,1,dividend,hi1,hi1));
-    // create the condition for the divisor
-    ASTNode cond_divisor = CreateNode(EQ,one,CreateTerm(BVEXTRACT,1,divisor,hi1,hi1));
-
-    if(SBVREM == in.GetKind()) {
-      //if(TopBit(dividend)==1) 
-      //
-      //then -BVMOD(-dividend,abs(divisor)) 
-      //
-      //else BVMOD(dividend,abs(divisor))
-
-      //create the condition and conditional for the divisor
-      ASTNode pos_divisor  = CreateTerm(ITE,len,cond_divisor,CreateTerm(BVUMINUS,len,divisor),divisor);
-
-      //create the modulus term for each case
-      ASTNode modnode = CreateTerm(BVMOD,len,dividend,pos_divisor);
-      ASTNode minus_modnode = CreateTerm(BVMOD,len,CreateTerm(BVUMINUS,len,dividend),pos_divisor);
-      minus_modnode = CreateTerm(BVUMINUS,len,minus_modnode);
-
-      //put everything together, simplify, and return
-      ASTNode n = CreateTerm(ITE,len,cond_dividend,minus_modnode,modnode);
-      return SimplifyTerm_TopLevel(n);
-    }
-
-    if(SBVMOD == in.GetKind()) {
-        // (let (?msb_s (extract[|m-1|:|m-1|] s))
-        // (let (?msb_t (extract[|m-1|:|m-1|] t))
-        // (ite (and (= ?msb_s bit0) (= ?msb_t bit0))
-        //      (bvurem s t)
-        // (ite (and (= ?msb_s bit1) (= ?msb_t bit0))
-        //      (bvadd (bvneg (bvurem (bvneg s) t)) t)
-        // (ite (and (= ?msb_s bit0) (= ?msb_t bit1))
-        //      (bvadd (bvurem s (bvneg t)) t)
-        //      (bvneg (bvurem (bvneg s) (bvneg t)))))))
-        ASTNode & s = dividend;
-        ASTNode & t = divisor;
-        ASTNode & msb_s = cond_dividend;
-        ASTNode & msb_t = cond_divisor;
-        
-        ASTNode isSPos = CreateNode(EQ, msb_s, zero); // (= ?msb_s bit0)
-        ASTNode isSNeg = CreateNode(EQ, msb_s, one); // (= ?msb_s bit1)
-        ASTNode isTPos = CreateNode(EQ, msb_t, zero); // (= ?msb_t bit0)
-        ASTNode isTNeg = CreateNode(EQ, msb_t, one); // (= ?msb_t bit1)
-
-        ASTNode negS = CreateTerm(BVUMINUS, len, s); // (bvneg s)
-        ASTNode negT = CreateTerm(BVUMINUS, len, t); // (bvneg s)
-
-        // (bvneg (bvurem (bvneg s) (bvneg t)))
-        ASTNode branch4 = CreateTerm(BVUMINUS, len, CreateTerm(BVMOD, len, negS, negT));
-        // (bvadd (bvurem s (bvneg t)) t)
-        ASTNode branch3 = CreateTerm(BVPLUS, len, CreateTerm(BVMOD, len, s, negT), t);
-        // (bvadd (bvneg (bvurem (bvneg s) t)) t)
-        ASTNode branch2 = CreateTerm(BVPLUS, len, CreateTerm(BVUMINUS, len, CreateTerm(BVMOD, len, negS, t)), t);
-        // (bvurem s t)
-        ASTNode branch1 = CreateTerm(BVMOD, len, s, t);
-
-        ASTNode ite3 = CreateTerm(ITE, len, CreateNode(AND, isSPos, isTNeg), branch3, branch4);
-        ASTNode ite2 = CreateTerm(ITE, len, CreateNode(AND, isSNeg, isTPos), branch2, ite3);
-        ASTNode ite1 = CreateTerm(ITE, len, CreateNode(AND, isSPos, isTPos), branch1, ite2);
-
-        return SimplifyTerm_TopLevel(ite1);
-    }
-    
-    //now handle the BVDIV case
-    //if topBit(dividend) is 1 and topBit(divisor) is 0
-    //
-    //then output is -BVDIV(-dividend,divisor)
-    //
-    //elseif topBit(dividend) is 0 and topBit(divisor) is 1
-    //
-    //then output is -BVDIV(dividend,-divisor)
-    //
-    //elseif topBit(dividend) is 1 and topBit(divisor) is 1
-    //
-    // then output is BVDIV(-dividend,-divisor)
-    //
-    //else simply output BVDIV(dividend,divisor)
-    ASTNode divnode = CreateTerm(BVDIV, len, dividend, divisor);
-
-    ASTNode cond1 = CreateNode(AND,
-                              CreateNode(EQ,zero,CreateTerm(BVEXTRACT,1,dividend,hi1,hi1)),
-                              CreateNode(EQ,one, CreateTerm(BVEXTRACT,1,divisor,hi1,hi1)));
-    ASTNode minus_divnode1 = CreateTerm(BVDIV,len,
-                                       dividend,
-                                       CreateTerm(BVUMINUS,len,divisor));
-    minus_divnode1 = CreateTerm(BVUMINUS,len,minus_divnode1);
-
-    ASTNode cond2 = CreateNode(AND,
-                              CreateNode(EQ,one,CreateTerm(BVEXTRACT,1,dividend,hi1,hi1)),
-                              CreateNode(EQ,zero,CreateTerm(BVEXTRACT,1,divisor,hi1,hi1)));
-    ASTNode minus_divnode2 = CreateTerm(BVDIV,len,
-                                       CreateTerm(BVUMINUS,len,dividend),
-                                       divisor);
-    minus_divnode2 = CreateTerm(BVUMINUS,len,minus_divnode2);
-
-    ASTNode cond3 = CreateNode(AND,
-                              CreateNode(EQ,one,CreateTerm(BVEXTRACT,1,dividend,hi1,hi1)),
-                              CreateNode(EQ,one,CreateTerm(BVEXTRACT,1,divisor,hi1,hi1)));
-    ASTNode minus_divnode3 = CreateTerm(BVDIV,len,
-                                       CreateTerm(BVUMINUS,len,dividend),
-                                       CreateTerm(BVUMINUS,len,divisor));
-    ASTNode n = CreateTerm(ITE,len,
-                          cond1,
-                          minus_divnode1,
-                          CreateTerm(ITE,len,
-                                     cond2,
-                                     minus_divnode2,
-                                     CreateTerm(ITE,len,
-                                                cond3,
-                                                minus_divnode3,
-                                                divnode)));
-  return SimplifyTerm_TopLevel(n);
-  }//end of TranslateSignedDivMod()
-
-  /*
-  //Translates signed BVDIV/BVMOD into unsigned variety
-  ASTNode BeevMgr::TranslateSignedDivMod(const ASTNode& in) {
-    if(!(SBVREM == in.GetKind() || SBVDIV == in.GetKind())) {
-      FatalError("TranslateSignedDivMod: input must be signed DIV/MOD\n",in);
-    }
-
-    ASTNode dividend = in[0];
-    ASTNode divisor  = in[1];      
-    unsigned len = in.GetValueWidth();
-    if(SBVMOD == in.GetKind()) {
-      //if(TopBit(dividend)==1) 
-      //
-      //then -BVMOD(-dividend,abs(divisor)) 
-      //
-      //else BVMOD(dividend,abs(divisor))
-
-      //create the condition for the dividend
-      ASTNode hi1  = CreateBVConst(32,len-1);
-      ASTNode one  = CreateOneConst(1);
-      ASTNode cond = CreateNode(EQ,one,CreateTerm(BVEXTRACT,1,dividend,hi1,hi1));
-
-      //create the condition and conditional for the divisor
-      ASTNode cond_divisor = CreateNode(EQ,one,CreateTerm(BVEXTRACT,1,divisor,hi1,hi1));
-      ASTNode pos_divisor  = CreateTerm(ITE,len,cond_divisor,CreateTerm(BVUMINUS,len,divisor),divisor);
-
-      //create the modulus term for each case
-      ASTNode modnode = CreateTerm(BVMOD,len,dividend,pos_divisor);
-      ASTNode minus_modnode = CreateTerm(BVMOD,len,CreateTerm(BVUMINUS,len,dividend),pos_divisor);
-      minus_modnode = CreateTerm(BVUMINUS,len,minus_modnode);
-
-      //put everything together, simplify, and return
-      ASTNode n = CreateTerm(ITE,len,cond,minus_modnode,modnode);
-      return SimplifyTerm_TopLevel(n);
-    }
-    
-    //now handle the BVDIV case
-    //if topBit(dividend) is 1 and topBit(divisor) is 0
-    //
-    //then output is -BVDIV(-dividend,divisor)
-    //
-    //elseif topBit(dividend) is 0 and topBit(divisor) is 1
-    //
-    //then output is -BVDIV(dividend,-divisor)
-    //
-    //elseif topBit(dividend) is 1 and topBit(divisor) is 1
-    //
-    // then output is BVDIV(-dividend,-divisor)
-    //
-    //else simply output BVDIV(dividend,divisor)
-    ASTNode hi1 = CreateBVConst(32,len-1);
-    ASTNode zero = CreateZeroConst(1);
-    ASTNode one = CreateOneConst(1);
-    ASTNode divnode = CreateTerm(BVDIV, len, dividend, divisor);
-
-    ASTNode cond1 = CreateNode(AND,
-                              CreateNode(EQ,zero,CreateTerm(BVEXTRACT,1,dividend,hi1,hi1)),
-                              CreateNode(EQ,one, CreateTerm(BVEXTRACT,1,divisor,hi1,hi1)));
-    ASTNode minus_divnode1 = CreateTerm(BVDIV,len,
-                                       dividend,
-                                       CreateTerm(BVUMINUS,len,divisor));
-    minus_divnode1 = CreateTerm(BVUMINUS,len,minus_divnode1);
-
-    ASTNode cond2 = CreateNode(AND,
-                              CreateNode(EQ,one,CreateTerm(BVEXTRACT,1,dividend,hi1,hi1)),
-                              CreateNode(EQ,zero,CreateTerm(BVEXTRACT,1,divisor,hi1,hi1)));
-    ASTNode minus_divnode2 = CreateTerm(BVDIV,len,
-                                       CreateTerm(BVUMINUS,len,dividend),
-                                       divisor);
-    minus_divnode2 = CreateTerm(BVUMINUS,len,minus_divnode2);
-
-    ASTNode cond3 = CreateNode(AND,
-                              CreateNode(EQ,one,CreateTerm(BVEXTRACT,1,dividend,hi1,hi1)),
-                              CreateNode(EQ,one,CreateTerm(BVEXTRACT,1,divisor,hi1,hi1)));
-    ASTNode minus_divnode3 = CreateTerm(BVDIV,len,
-                                       CreateTerm(BVUMINUS,len,dividend),
-                                       CreateTerm(BVUMINUS,len,divisor));
-    ASTNode n = CreateTerm(ITE,len,
-                          cond1,
-                          minus_divnode1,
-                          CreateTerm(ITE,len,
-                                     cond2,
-                                     minus_divnode2,
-                                     CreateTerm(ITE,len,
-                                                cond3,
-                                                minus_divnode3,
-                                                divnode)));
-  return SimplifyTerm_TopLevel(n);
-  }//end of TranslateSignedDivMod()
-  */
-
-  ASTNode BeevMgr::TransformFormula(const ASTNode& form) {
-    ASTNode result;
-
-    ASTNode simpleForm = form;
-    Kind k = simpleForm.GetKind();
-    if(!(is_Form_kind(k) && BOOLEAN_TYPE == simpleForm.GetType())) {
-      //FIXME: "You have inputted a NON-formula"?
-      FatalError("TransformFormula: You have input a NON-formula",simpleForm);
-    }
-
-    ASTNodeMap::iterator iter;
-    if((iter = TransformMap.find(simpleForm)) != TransformMap.end())
-      return iter->second;
-
-    switch(k) {
-    case TRUE:
-    case FALSE: {
-      result = simpleForm;
-      break;
-    }
-    case NOT: {
-      ASTVec c;
-      c.push_back(TransformFormula(simpleForm[0]));
-      result = CreateNode(NOT,c);      
-      break;
-    }
-    case BVLT:
-    case BVLE:
-    case BVGT:
-    case BVGE:
-    case BVSLT:
-    case BVSLE:
-    case BVSGT:
-    case BVSGE:      
-    case NEQ: {
-      ASTVec c;
-      c.push_back(TransformTerm(simpleForm[0]));      
-      c.push_back(TransformTerm(simpleForm[1]));
-      result = CreateNode(k,c);
-      break;
-    }
-    case EQ: {
-      ASTNode term1 = TransformTerm(simpleForm[0]);      
-      ASTNode term2 = TransformTerm(simpleForm[1]);
-      result = CreateSimplifiedEQ(term1,term2);     
-      break;
-    }
-    case AND:
-    case OR: 
-    case NAND:
-    case NOR:
-    case IFF:
-    case XOR:
-    case ITE:
-    case IMPLIES: {
-      ASTVec vec;
-      ASTNode o;
-      for (ASTVec::const_iterator it = simpleForm.begin(),itend=simpleForm.end(); it != itend; it++){
-       o = TransformFormula(*it);      
-       vec.push_back(o);
-      }
-
-      result = CreateNode(k, vec);
-      break;
-    }
-    default:
-      if(k == SYMBOL && BOOLEAN_TYPE == simpleForm.GetType())
-       result = simpleForm;      
-      else {
-       cerr << "The input is: " << simpleForm << endl;
-       cerr << "The valuewidth of input is : " << simpleForm.GetValueWidth() << endl;
-       FatalError("TransformFormula: Illegal kind: ",ASTUndefined, k);
-      }
-      break;    
-    } 
-    //BVTypeCheck(result);
-    TransformMap[simpleForm] = result;
-    return result;
-  } //End of TransformFormula
-
-  ASTNode BeevMgr::TransformTerm(const ASTNode& inputterm) {
-    ASTNode result;
-    ASTNode term = inputterm;
-
-    Kind k = term.GetKind();
-    if(!is_Term_kind(k))
-      FatalError("TransformTerm: Illegal kind: You have input a nonterm:", inputterm, k);
-    ASTNodeMap::iterator iter;
-    if((iter = TransformMap.find(term)) != TransformMap.end())
-      return iter->second;
-    switch(k) {
-    case SYMBOL: {
-      // ASTNodeMap::iterator itsym;
-//       if((itsym = CounterExampleMap.find(term)) != CounterExampleMap.end()) 
-//             result = itsym->second;
-//       else
-       result = term;
-      break;
-    }
-    case BVCONST:
-      result = term;
-      break;
-    case WRITE:
-      FatalError("TransformTerm: this kind is not supported",term);
-      break;
-    case READ:
-      result = TransformArray(term);
-      break;
-    case ITE: {
-      ASTNode cond = term[0];
-      ASTNode thn  = term[1];
-      ASTNode els  = term[2];
-      cond = TransformFormula(cond);
-      thn = TransformTerm(thn);
-      els = TransformTerm(els);
-      //result = CreateTerm(ITE,term.GetValueWidth(),cond,thn,els);
-      result = CreateSimplifiedTermITE(cond,thn,els);
-      result.SetIndexWidth(term.GetIndexWidth());
-      break;
-    }
-    default: {
-      ASTVec c = term.GetChildren();
-      ASTVec::iterator it = c.begin();
-      ASTVec::iterator itend = c.end();
-      unsigned width = term.GetValueWidth();
-      unsigned indexwidth = term.GetIndexWidth();
-      ASTVec o;
-      for(;it!=itend;it++) {
-       o.push_back(TransformTerm(*it));
-      }
-
-      result = CreateTerm(k,width,o);
-      result.SetIndexWidth(indexwidth);
-
-      if(SBVDIV == result.GetKind() || SBVREM == result.GetKind() || SBVMOD == result.GetKind()) {
-       result = TranslateSignedDivMod(result);
-      }
-      break;
-    }
-    }
-
-    TransformMap[term] = result;
-    if(term.GetValueWidth() != result.GetValueWidth())
-      FatalError("TransformTerm: result and input terms are of different length", result);
-    if(term.GetIndexWidth() != result.GetIndexWidth()) {
-      cerr << "TransformTerm: input term is : " << term << endl;
-      FatalError("TransformTerm: result and input terms have different index length", result);
-    }
-    return result;
-  } //End of TransformTerm
-
-  /* This function transforms Array Reads, Read over Writes, Read over
-   * ITEs into flattened form.
-   *
-   * Transform1: Suppose there are two array reads in the input
-   * Read(A,i) and Read(A,j) over the same array. Then Read(A,i) is
-   * replaced with a symbolic constant, say v1, and Read(A,j) is
-   * replaced with the following ITE:
-   *
-   * ITE(i=j,v1,v2)
-   *
-   * Transform2:
-   * 
-   * Transform3:
-   */
-  ASTNode BeevMgr::TransformArray(const ASTNode& term) {
-    ASTNode result = term;
-
-    unsigned int width = term.GetValueWidth();
-    Kind k = term.GetKind();
-    if (!is_Term_kind(k))
-      FatalError("TransformArray: Illegal kind: You have input a nonterm:", ASTUndefined, k);
-    ASTNodeMap::iterator iter;
-    if((iter = TransformMap.find(term)) != TransformMap.end())
-      return iter->second;
-
-    switch(k) {
-      //'term' is of the form READ(arrName, readIndex) 
-    case READ: {
-      ASTNode arrName = term[0];
-      switch (arrName.GetKind()) {
-      case SYMBOL: {
-       /* input is of the form: READ(A, readIndex)
-        * 
-        * output is of the from: A1, if this is the first READ over A
-         *                           
-        *                        ITE(previous_readIndex=readIndex,A1,A2)
-        *                        
-         *                        .....
-        */
-
-       //  Recursively transform read index, which may also contain reads.
-       ASTNode readIndex = TransformTerm(term[1]);     
-       ASTNode processedTerm = CreateTerm(READ,width,arrName,readIndex);
-       
-       //check if the 'processedTerm' has a corresponding ITE construct
-       //already. if so, return it. else continue processing.
-       ASTNodeMap::iterator it;
-       if((it = _arrayread_ite.find(processedTerm)) != _arrayread_ite.end()) {
-         result = it->second;  
-         break;
+namespace BEEV
+{
+
+//Translates signed BVDIV/BVMOD into unsigned variety
+ASTNode BeevMgr::TranslateSignedDivMod(const ASTNode& in)
+{
+       if (!(SBVREM == in.GetKind() || SBVDIV == in.GetKind()))
+       {
+               FatalError("TranslateSignedDivMod: input must be signed DIV/MOD\n", in);
        }
-       //Constructing Symbolic variable corresponding to 'processedTerm'
-       ASTNode CurrentSymbol;
-       ASTNodeMap::iterator it1;
-       // First, check if read index is constant and it has a constant value in the substitution map.
-       if(CheckSubstitutionMap(processedTerm,CurrentSymbol)) {
-         _arrayread_symbol[processedTerm] = CurrentSymbol;
+
+       ASTNode dividend = in[0];
+       ASTNode divisor = in[1];
+       unsigned len = in.GetValueWidth();
+
+       ASTNode hi1 = CreateBVConst(32, len - 1);
+       ASTNode one = CreateOneConst(1);
+       ASTNode zero = CreateZeroConst(1);
+       // create the condition for the dividend
+       ASTNode cond_dividend = CreateNode(EQ, one, CreateTerm(BVEXTRACT, 1, dividend, hi1, hi1));
+       // create the condition for the divisor
+       ASTNode cond_divisor = CreateNode(EQ, one, CreateTerm(BVEXTRACT, 1, divisor, hi1, hi1));
+
+       if (SBVREM == in.GetKind())
+       {
+               //if(TopBit(dividend)==1)
+               //
+               //then -BVMOD(-dividend,abs(divisor))
+               //
+               //else BVMOD(dividend,abs(divisor))
+
+               //create the condition and conditional for the divisor
+               ASTNode pos_divisor = CreateTerm(ITE, len, cond_divisor, CreateTerm(BVUMINUS, len, divisor), divisor);
+
+               //create the modulus term for each case
+               ASTNode modnode = CreateTerm(BVMOD, len, dividend, pos_divisor);
+               ASTNode minus_modnode = CreateTerm(BVMOD, len, CreateTerm(BVUMINUS, len, dividend), pos_divisor);
+               minus_modnode = CreateTerm(BVUMINUS, len, minus_modnode);
+
+               //put everything together, simplify, and return
+               ASTNode n = CreateTerm(ITE, len, cond_dividend, minus_modnode, modnode);
+               return SimplifyTerm_TopLevel(n);
        }
-       // Check if it already has an abstract variable.
-       else if((it1 = _arrayread_symbol.find(processedTerm)) != _arrayread_symbol.end()) {
-         CurrentSymbol = it1->second;
+
+       if (SBVMOD == in.GetKind())
+       {
+               // (let (?msb_s (extract[|m-1|:|m-1|] s))
+               // (let (?msb_t (extract[|m-1|:|m-1|] t))
+               // (ite (and (= ?msb_s bit0) (= ?msb_t bit0))
+               //      (bvurem s t)
+               // (ite (and (= ?msb_s bit1) (= ?msb_t bit0))
+               //      (bvadd (bvneg (bvurem (bvneg s) t)) t)
+               // (ite (and (= ?msb_s bit0) (= ?msb_t bit1))
+               //      (bvadd (bvurem s (bvneg t)) t)
+               //      (bvneg (bvurem (bvneg s) (bvneg t)))))))
+               ASTNode & s = dividend;
+               ASTNode & t = divisor;
+               ASTNode & msb_s = cond_dividend;
+               ASTNode & msb_t = cond_divisor;
+
+               ASTNode isSPos = CreateNode(EQ, msb_s, zero); // (= ?msb_s bit0)
+               ASTNode isSNeg = CreateNode(EQ, msb_s, one); // (= ?msb_s bit1)
+               ASTNode isTPos = CreateNode(EQ, msb_t, zero); // (= ?msb_t bit0)
+               ASTNode isTNeg = CreateNode(EQ, msb_t, one); // (= ?msb_t bit1)
+
+               ASTNode negS = CreateTerm(BVUMINUS, len, s); // (bvneg s)
+               ASTNode negT = CreateTerm(BVUMINUS, len, t); // (bvneg s)
+
+               // (bvneg (bvurem (bvneg s) (bvneg t)))
+               ASTNode branch4 = CreateTerm(BVUMINUS, len, CreateTerm(BVMOD, len, negS, negT));
+               // (bvadd (bvurem s (bvneg t)) t)
+               ASTNode branch3 = CreateTerm(BVPLUS, len, CreateTerm(BVMOD, len, s, negT), t);
+               // (bvadd (bvneg (bvurem (bvneg s) t)) t)
+               ASTNode branch2 = CreateTerm(BVPLUS, len, CreateTerm(BVUMINUS, len, CreateTerm(BVMOD, len, negS, t)), t);
+               // (bvurem s t)
+               ASTNode branch1 = CreateTerm(BVMOD, len, s, t);
+
+               ASTNode ite3 = CreateTerm(ITE, len, CreateNode(AND, isSPos, isTNeg), branch3, branch4);
+               ASTNode ite2 = CreateTerm(ITE, len, CreateNode(AND, isSNeg, isTPos), branch2, ite3);
+               ASTNode ite1 = CreateTerm(ITE, len, CreateNode(AND, isSPos, isTPos), branch1, ite2);
+
+               return SimplifyTerm_TopLevel(ite1);
        }
-       else {
-         // Make up a new abstract variable.
-         // FIXME: Make this into a method (there already may BE a method) and
-         // get rid of the fixed-length buffer!
-         //build symbolic name corresponding to array read. The symbolic
-         //name has 2 components: stringname, and a count
-         const char * b = arrName.GetName();
-         std::string c(b);
-         char d[32];
-         sprintf(d,"%d",_symbol_count++);
-         std::string ccc(d);
-         c += "array_" + ccc;
-         
-         CurrentSymbol = CreateSymbol(c.c_str());
-         CurrentSymbol.SetValueWidth(processedTerm.GetValueWidth());
-         CurrentSymbol.SetIndexWidth(processedTerm.GetIndexWidth());
-         _arrayread_symbol[processedTerm] = CurrentSymbol;       
+
+       //now handle the BVDIV case
+       //if topBit(dividend) is 1 and topBit(divisor) is 0
+       //
+       //then output is -BVDIV(-dividend,divisor)
+       //
+       //elseif topBit(dividend) is 0 and topBit(divisor) is 1
+       //
+       //then output is -BVDIV(dividend,-divisor)
+       //
+       //elseif topBit(dividend) is 1 and topBit(divisor) is 1
+       //
+       // then output is BVDIV(-dividend,-divisor)
+       //
+       //else simply output BVDIV(dividend,divisor)
+       ASTNode divnode = CreateTerm(BVDIV, len, dividend, divisor);
+
+       ASTNode cond1 = CreateNode(AND, CreateNode(EQ, zero, CreateTerm(BVEXTRACT, 1, dividend, hi1, hi1)), CreateNode(EQ, one, CreateTerm(BVEXTRACT, 1,
+                       divisor, hi1, hi1)));
+       ASTNode minus_divnode1 = CreateTerm(BVDIV, len, dividend, CreateTerm(BVUMINUS, len, divisor));
+       minus_divnode1 = CreateTerm(BVUMINUS, len, minus_divnode1);
+
+       ASTNode cond2 = CreateNode(AND, CreateNode(EQ, one, CreateTerm(BVEXTRACT, 1, dividend, hi1, hi1)), CreateNode(EQ, zero, CreateTerm(BVEXTRACT, 1,
+                       divisor, hi1, hi1)));
+       ASTNode minus_divnode2 = CreateTerm(BVDIV, len, CreateTerm(BVUMINUS, len, dividend), divisor);
+       minus_divnode2 = CreateTerm(BVUMINUS, len, minus_divnode2);
+
+       ASTNode cond3 = CreateNode(AND, CreateNode(EQ, one, CreateTerm(BVEXTRACT, 1, dividend, hi1, hi1)), CreateNode(EQ, one, CreateTerm(BVEXTRACT, 1,
+                       divisor, hi1, hi1)));
+       ASTNode minus_divnode3 = CreateTerm(BVDIV, len, CreateTerm(BVUMINUS, len, dividend), CreateTerm(BVUMINUS, len, divisor));
+       ASTNode n = CreateTerm(ITE, len, cond1, minus_divnode1, CreateTerm(ITE, len, cond2, minus_divnode2, CreateTerm(ITE, len, cond3, minus_divnode3,
+                       divnode)));
+       return SimplifyTerm_TopLevel(n);
+}//end of TranslateSignedDivMod()
+
+/*
+ //Translates signed BVDIV/BVMOD into unsigned variety
+ ASTNode BeevMgr::TranslateSignedDivMod(const ASTNode& in) {
+ if(!(SBVREM == in.GetKind() || SBVDIV == in.GetKind())) {
+ FatalError("TranslateSignedDivMod: input must be signed DIV/MOD\n",in);
+ }
+
+ ASTNode dividend = in[0];
+ ASTNode divisor  = in[1];
+ unsigned len = in.GetValueWidth();
+ if(SBVMOD == in.GetKind()) {
+ //if(TopBit(dividend)==1)
+ //
+ //then -BVMOD(-dividend,abs(divisor))
+ //
+ //else BVMOD(dividend,abs(divisor))
+
+ //create the condition for the dividend
+ ASTNode hi1  = CreateBVConst(32,len-1);
+ ASTNode one  = CreateOneConst(1);
+ ASTNode cond = CreateNode(EQ,one,CreateTerm(BVEXTRACT,1,dividend,hi1,hi1));
+
+ //create the condition and conditional for the divisor
+ ASTNode cond_divisor = CreateNode(EQ,one,CreateTerm(BVEXTRACT,1,divisor,hi1,hi1));
+ ASTNode pos_divisor  = CreateTerm(ITE,len,cond_divisor,CreateTerm(BVUMINUS,len,divisor),divisor);
+
+ //create the modulus term for each case
+ ASTNode modnode = CreateTerm(BVMOD,len,dividend,pos_divisor);
+ ASTNode minus_modnode = CreateTerm(BVMOD,len,CreateTerm(BVUMINUS,len,dividend),pos_divisor);
+ minus_modnode = CreateTerm(BVUMINUS,len,minus_modnode);
+
+ //put everything together, simplify, and return
+ ASTNode n = CreateTerm(ITE,len,cond,minus_modnode,modnode);
+ return SimplifyTerm_TopLevel(n);
+ }
+
+ //now handle the BVDIV case
+ //if topBit(dividend) is 1 and topBit(divisor) is 0
+ //
+ //then output is -BVDIV(-dividend,divisor)
+ //
+ //elseif topBit(dividend) is 0 and topBit(divisor) is 1
+ //
+ //then output is -BVDIV(dividend,-divisor)
+ //
+ //elseif topBit(dividend) is 1 and topBit(divisor) is 1
+ //
+ // then output is BVDIV(-dividend,-divisor)
+ //
+ //else simply output BVDIV(dividend,divisor)
+ ASTNode hi1 = CreateBVConst(32,len-1);
+ ASTNode zero = CreateZeroConst(1);
+ ASTNode one = CreateOneConst(1);
+ ASTNode divnode = CreateTerm(BVDIV, len, dividend, divisor);
+
+ ASTNode cond1 = CreateNode(AND,
+ CreateNode(EQ,zero,CreateTerm(BVEXTRACT,1,dividend,hi1,hi1)),
+ CreateNode(EQ,one, CreateTerm(BVEXTRACT,1,divisor,hi1,hi1)));
+ ASTNode minus_divnode1 = CreateTerm(BVDIV,len,
+ dividend,
+ CreateTerm(BVUMINUS,len,divisor));
+ minus_divnode1 = CreateTerm(BVUMINUS,len,minus_divnode1);
+
+ ASTNode cond2 = CreateNode(AND,
+ CreateNode(EQ,one,CreateTerm(BVEXTRACT,1,dividend,hi1,hi1)),
+ CreateNode(EQ,zero,CreateTerm(BVEXTRACT,1,divisor,hi1,hi1)));
+ ASTNode minus_divnode2 = CreateTerm(BVDIV,len,
+ CreateTerm(BVUMINUS,len,dividend),
+ divisor);
+ minus_divnode2 = CreateTerm(BVUMINUS,len,minus_divnode2);
+
+ ASTNode cond3 = CreateNode(AND,
+ CreateNode(EQ,one,CreateTerm(BVEXTRACT,1,dividend,hi1,hi1)),
+ CreateNode(EQ,one,CreateTerm(BVEXTRACT,1,divisor,hi1,hi1)));
+ ASTNode minus_divnode3 = CreateTerm(BVDIV,len,
+ CreateTerm(BVUMINUS,len,dividend),
+ CreateTerm(BVUMINUS,len,divisor));
+ ASTNode n = CreateTerm(ITE,len,
+ cond1,
+ minus_divnode1,
+ CreateTerm(ITE,len,
+ cond2,
+ minus_divnode2,
+ CreateTerm(ITE,len,
+ cond3,
+ minus_divnode3,
+ divnode)));
+ return SimplifyTerm_TopLevel(n);
+ }//end of TranslateSignedDivMod()
+ */
+
+ASTNode BeevMgr::TransformFormula(const ASTNode& form)
+{
+       ASTNode result;
+
+       ASTNode simpleForm = form;
+       Kind k = simpleForm.GetKind();
+       if (!(is_Form_kind(k) && BOOLEAN_TYPE == simpleForm.GetType()))
+       {
+               //FIXME: "You have inputted a NON-formula"?
+               FatalError("TransformFormula: You have input a NON-formula", simpleForm);
        }
-       
-       //list of array-read indices corresponding to arrName, seen while
-       //traversing the AST tree. we need this list to construct the ITEs
-       // Dill: we hope to make this irrelevant.  Harmless for now.
-       ASTVec readIndices = _arrayname_readindices[arrName];
-       
-       //construct the ITE structure for this array-read
-       ASTNode ite = CurrentSymbol;
-       _introduced_symbols.insert(CurrentSymbol);
-       BVTypeCheck(ite);
-       
-       if(arrayread_refinement) {
-         // ite is really a variable here; it is an ite in the
-         // else-branch
-         result = ite;
+
+       ASTNodeMap::iterator iter;
+       if ((iter = TransformMap.find(simpleForm)) != TransformMap.end())
+               return iter->second;
+
+       switch (k)
+       {
+               case TRUE:
+               case FALSE:
+               {
+                       result = simpleForm;
+                       break;
+               }
+               case NOT:
+               {
+                       ASTVec c;
+                       c.push_back(TransformFormula(simpleForm[0]));
+                       result = CreateNode(NOT, c);
+                       break;
+               }
+               case BVLT:
+               case BVLE:
+               case BVGT:
+               case BVGE:
+               case BVSLT:
+               case BVSLE:
+               case BVSGT:
+               case BVSGE:
+               case NEQ:
+               {
+                       ASTVec c;
+                       c.push_back(TransformTerm(simpleForm[0]));
+                       c.push_back(TransformTerm(simpleForm[1]));
+                       result = CreateNode(k, c);
+                       break;
+               }
+               case EQ:
+               {
+                       ASTNode term1 = TransformTerm(simpleForm[0]);
+                       ASTNode term2 = TransformTerm(simpleForm[1]);
+                       result = CreateSimplifiedEQ(term1, term2);
+                       break;
+               }
+               case AND:
+               case OR:
+               case NAND:
+               case NOR:
+               case IFF:
+               case XOR:
+               case ITE:
+               case IMPLIES:
+               {
+                       ASTVec vec;
+                       ASTNode o;
+                       for (ASTVec::const_iterator it = simpleForm.begin(), itend = simpleForm.end(); it != itend; it++)
+                       {
+                               o = TransformFormula(*it);
+                               vec.push_back(o);
+                       }
+
+                       result = CreateNode(k, vec);
+                       break;
+               }
+               default:
+                       if (k == SYMBOL && BOOLEAN_TYPE == simpleForm.GetType())
+                               result = simpleForm;
+                       else
+                       {
+                               cerr << "The input is: " << simpleForm << endl;
+                               cerr << "The valuewidth of input is : " << simpleForm.GetValueWidth() << endl;
+                               FatalError("TransformFormula: Illegal kind: ", ASTUndefined, k);
+                       }
+                       break;
        }
-       else {
-         // Full Seshia transform if we're not doing read refinement.
-         //do not loop if the current readIndex is a BVCONST
-         // if(BVCONST == term[1].GetKind() && !SeenNonConstReadIndex && optimize) {
-         //        result = ite; 
-         //      }
-         //      else {          
-           //else part: SET the SeenNonConstReadIndex var, and do the hard work
-           //SeenNonConstReadIndex = true;
-           ASTVec::reverse_iterator it2=readIndices.rbegin();
-           ASTVec::reverse_iterator it2end=readIndices.rend();
-           for(;it2!=it2end;it2++) {
-             ASTNode cond = CreateSimplifiedEQ(readIndex,*it2);
-             if(ASTFalse == cond)
-               continue;
-             
-             ASTNode arrRead = CreateTerm(READ,width,arrName,*it2);
-             //Good idea to TypeCheck internally constructed nodes
-             BVTypeCheck(arrRead);
-             
-             ASTNode arrayreadSymbol = _arrayread_symbol[arrRead];
-             if(arrayreadSymbol.IsNull())
-               FatalError("TransformArray:symbolic variable for processedTerm, p," 
-                          "does not exist:p = ",arrRead);
-             ite = CreateSimplifiedTermITE(cond,arrayreadSymbol,ite);
-           }
-           result = ite;
-           //}
+       //BVTypeCheck(result);
+       TransformMap[simpleForm] = result;
+       return result;
+} //End of TransformFormula
+
+ASTNode BeevMgr::TransformTerm(const ASTNode& inputterm)
+{
+       ASTNode result;
+       ASTNode term = inputterm;
+
+       Kind k = term.GetKind();
+       if (!is_Term_kind(k))
+               FatalError("TransformTerm: Illegal kind: You have input a nonterm:", inputterm, k);
+       ASTNodeMap::iterator iter;
+       if ((iter = TransformMap.find(term)) != TransformMap.end())
+               return iter->second;
+       switch (k)
+       {
+               case SYMBOL:
+               {
+                       // ASTNodeMap::iterator itsym;
+                       //       if((itsym = CounterExampleMap.find(term)) != CounterExampleMap.end())
+                       //              result = itsym->second;
+                       //       else
+                       result = term;
+                       break;
+               }
+               case BVCONST:
+                       result = term;
+                       break;
+               case WRITE:
+                       FatalError("TransformTerm: this kind is not supported", term);
+                       break;
+               case READ:
+                       result = TransformArray(term);
+                       break;
+               case ITE:
+               {
+                       ASTNode cond = term[0];
+                       ASTNode thn = term[1];
+                       ASTNode els = term[2];
+                       cond = TransformFormula(cond);
+                       thn = TransformTerm(thn);
+                       els = TransformTerm(els);
+                       //result = CreateTerm(ITE,term.GetValueWidth(),cond,thn,els);
+                       result = CreateSimplifiedTermITE(cond, thn, els);
+                       result.SetIndexWidth(term.GetIndexWidth());
+                       break;
+               }
+               default:
+               {
+                       ASTVec c = term.GetChildren();
+                       ASTVec::iterator it = c.begin();
+                       ASTVec::iterator itend = c.end();
+                       unsigned width = term.GetValueWidth();
+                       unsigned indexwidth = term.GetIndexWidth();
+                       ASTVec o;
+                       for (; it != itend; it++)
+                       {
+                               o.push_back(TransformTerm(*it));
+                       }
+
+                       result = CreateTerm(k, width, o);
+                       result.SetIndexWidth(indexwidth);
+
+                       if (SBVDIV == result.GetKind() || SBVREM == result.GetKind() || SBVMOD == result.GetKind())
+                       {
+                               result = TranslateSignedDivMod(result);
+                       }
+                       break;
+               }
        }
-       
-       _arrayname_readindices[arrName].push_back(readIndex);   
-       //save the ite corresponding to 'processedTerm'
-       _arrayread_ite[processedTerm] = result;
-       break;
-      } //end of READ over a SYMBOL
-      case WRITE:{     
-       /* The input to this case is: READ((WRITE A i val) j)
-        *
-        * The output of this case is: ITE( (= i j) val (READ A i))
-        */
-       
-       /* 1. arrName or term[0] is infact a WRITE(A,i,val) expression
-        *
-        * 2. term[1] is the read-index j
-        *
-        * 3. arrName[0] is the new arrName i.e. A. A can be either a
-              SYMBOL or a nested WRITE. no other possibility
-        *
-        * 4. arrName[1] is the WRITE index i.e. i
-        *
-        * 5. arrName[2] is the WRITE value i.e. val (val can inturn
-        *    be an array read)
-        */
-       ASTNode readIndex = TransformTerm(term[1]);
-       ASTNode writeIndex = TransformTerm(arrName[1]);
-       ASTNode writeVal = TransformTerm(arrName[2]);
-       
-       if(!(SYMBOL == arrName[0].GetKind() || 
-            WRITE == arrName[0].GetKind())) 
-         FatalError("TransformArray: An array write is being attempted on a non-array:",term);
-       if(ARRAY_TYPE != arrName[0].GetType())
-         FatalError("TransformArray: An array write is being attempted on a non-array:",term);
-       
-       ASTNode cond = CreateSimplifiedEQ(writeIndex,readIndex);
-       //TypeCheck internally created node
-       BVTypeCheck(cond);
-       ASTNode readTerm = CreateTerm(READ,width,arrName[0],readIndex);
-       //TypeCheck internally created node
-       BVTypeCheck(readTerm);
-       ASTNode readPushedIn = TransformArray(readTerm);
-       //TypeCheck internally created node
-       BVTypeCheck(readPushedIn);
-       //result = CreateTerm(ITE, arrName[0].GetValueWidth(),cond,writeVal,readPushedIn);
-       result = CreateSimplifiedTermITE(cond,writeVal,readPushedIn);
-
-       //Good idea to typecheck terms created inside the system
-       BVTypeCheck(result);
-       break;
-      } //end of READ over a WRITE
-      case ITE: {
-       /* READ((ITE cond thn els) j) 
-        *
-        * is transformed into
-        *
-        * (ITE cond (READ thn j) (READ els j))
-        */
-       
-       //(ITE cond thn els)
-       ASTNode term0 = term[0];
-       //READINDEX j
-       ASTNode j = TransformTerm(term[1]);
-       
-       ASTNode cond = term0[0];
-       //first array 
-       ASTNode t01  = term0[1];
-       //second array
-       ASTNode t02  = term0[2];
-       
-       cond = TransformFormula(cond);
-       ASTNode thn = TransformTerm(t01);
-       ASTNode els = TransformTerm(t02);
-       
-       if(!(t01.GetValueWidth() == t02.GetValueWidth() &&
-            t01.GetValueWidth() == thn.GetValueWidth() &&
-            t01.GetValueWidth() == els.GetValueWidth()))
-         FatalError("TransformArray: length of THENbranch != length of ELSEbranch in the term t = \n",term);
-
-       if(!(t01.GetIndexWidth() == t02.GetIndexWidth() &&
-            t01.GetIndexWidth() == thn.GetIndexWidth() &&
-            t01.GetIndexWidth() == els.GetIndexWidth()))
-         FatalError("TransformArray: length of THENbranch != length of ELSEbranch in the term t = \n",term);
-
-       //(READ thn j)
-       ASTNode thnRead = CreateTerm(READ,width,thn,j);
-       BVTypeCheck(thnRead);
-       thnRead = TransformArray(thnRead);
-       
-       //(READ els j)
-       ASTNode elsRead = CreateTerm(READ,width,els,j);
-       BVTypeCheck(elsRead);
-       elsRead = TransformArray(elsRead);
-       
-       //(ITE cond (READ thn j) (READ els j))
-       result = CreateSimplifiedTermITE(cond,thnRead,elsRead);
-       BVTypeCheck(result);
-      break;
-      }
-      default:
-       FatalError("TransformArray: The READ is NOT over SYMBOL/WRITE/ITE",term);
-       break;
-      } 
-      break;
-    } //end of READ switch
-    default:
-      FatalError("TransformArray: input term is of wrong kind: ",ASTUndefined);
-      break;
-    }
-    
-    TransformMap[term] = result;
-    return result;
-  } //end of TransformArray()  
+
+       TransformMap[term] = result;
+       if (term.GetValueWidth() != result.GetValueWidth())
+               FatalError("TransformTerm: result and input terms are of different length", result);
+       if (term.GetIndexWidth() != result.GetIndexWidth())
+       {
+               cerr << "TransformTerm: input term is : " << term << endl;
+               FatalError("TransformTerm: result and input terms have different index length", result);
+       }
+       return result;
+} //End of TransformTerm
+
+/* This function transforms Array Reads, Read over Writes, Read over
+ * ITEs into flattened form.
+ *
+ * Transform1: Suppose there are two array reads in the input
+ * Read(A,i) and Read(A,j) over the same array. Then Read(A,i) is
+ * replaced with a symbolic constant, say v1, and Read(A,j) is
+ * replaced with the following ITE:
+ *
+ * ITE(i=j,v1,v2)
+ *
+ * Transform2:
+ *
+ * Transform3:
+ */
+ASTNode BeevMgr::TransformArray(const ASTNode& term)
+{
+       ASTNode result = term;
+
+       unsigned int width = term.GetValueWidth();
+       Kind k = term.GetKind();
+       if (!is_Term_kind(k))
+               FatalError("TransformArray: Illegal kind: You have input a nonterm:", ASTUndefined, k);
+       ASTNodeMap::iterator iter;
+       if ((iter = TransformMap.find(term)) != TransformMap.end())
+               return iter->second;
+
+       switch (k)
+       {
+               //'term' is of the form READ(arrName, readIndex)
+               case READ:
+               {
+                       ASTNode arrName = term[0];
+                       switch (arrName.GetKind())
+                       {
+                               case SYMBOL:
+                               {
+                                       /* input is of the form: READ(A, readIndex)
+                                        *
+                                        * output is of the from: A1, if this is the first READ over A
+                                        *
+                                        *                        ITE(previous_readIndex=readIndex,A1,A2)
+                                        *
+                                        *                        .....
+                                        */
+
+                                       //  Recursively transform read index, which may also contain reads.
+                                       ASTNode readIndex = TransformTerm(term[1]);
+                                       ASTNode processedTerm = CreateTerm(READ, width, arrName, readIndex);
+
+                                       //check if the 'processedTerm' has a corresponding ITE construct
+                                       //already. if so, return it. else continue processing.
+                                       ASTNodeMap::iterator it;
+                                       if ((it = _arrayread_ite.find(processedTerm)) != _arrayread_ite.end())
+                                       {
+                                               result = it->second;
+                                               break;
+                                       }
+                                       //Constructing Symbolic variable corresponding to 'processedTerm'
+                                       ASTNode CurrentSymbol;
+                                       ASTNodeMap::iterator it1;
+                                       // First, check if read index is constant and it has a constant value in the substitution map.
+                                       if (CheckSubstitutionMap(processedTerm, CurrentSymbol))
+                                       {
+                                               _arrayread_symbol[processedTerm] = CurrentSymbol;
+                                       }
+                                       // Check if it already has an abstract variable.
+                                       else if ((it1 = _arrayread_symbol.find(processedTerm)) != _arrayread_symbol.end())
+                                       {
+                                               CurrentSymbol = it1->second;
+                                       }
+                                       else
+                                       {
+                                               // Make up a new abstract variable.
+                                               // FIXME: Make this into a method (there already may BE a method) and
+                                               // get rid of the fixed-length buffer!
+                                               //build symbolic name corresponding to array read. The symbolic
+                                               //name has 2 components: stringname, and a count
+                                               const char * b = arrName.GetName();
+                                               std::string c(b);
+                                               char d[32];
+                                               sprintf(d, "%d", _symbol_count++);
+                                               std::string ccc(d);
+                                               c += "array_" + ccc;
+
+                                               CurrentSymbol = CreateSymbol(c.c_str());
+                                               CurrentSymbol.SetValueWidth(processedTerm.GetValueWidth());
+                                               CurrentSymbol.SetIndexWidth(processedTerm.GetIndexWidth());
+                                               _arrayread_symbol[processedTerm] = CurrentSymbol;
+                                       }
+
+                                       //list of array-read indices corresponding to arrName, seen while
+                                       //traversing the AST tree. we need this list to construct the ITEs
+                                       // Dill: we hope to make this irrelevant.  Harmless for now.
+                                       ASTVec readIndices = _arrayname_readindices[arrName];
+
+                                       //construct the ITE structure for this array-read
+                                       ASTNode ite = CurrentSymbol;
+                                       _introduced_symbols.insert(CurrentSymbol);
+                                       BVTypeCheck(ite);
+
+                                       if (arrayread_refinement)
+                                       {
+                                               // ite is really a variable here; it is an ite in the
+                                               // else-branch
+                                               result = ite;
+                                       }
+                                       else
+                                       {
+                                               // Full Seshia transform if we're not doing read refinement.
+                                               //do not loop if the current readIndex is a BVCONST
+                                               // if(BVCONST == term[1].GetKind() && !SeenNonConstReadIndex && optimize) {
+                                               //          result = ite;
+                                               //        }
+                                               //        else {
+                                               //else part: SET the SeenNonConstReadIndex var, and do the hard work
+                                               //SeenNonConstReadIndex = true;
+                                               ASTVec::reverse_iterator it2 = readIndices.rbegin();
+                                               ASTVec::reverse_iterator it2end = readIndices.rend();
+                                               for (; it2 != it2end; it2++)
+                                               {
+                                                       ASTNode cond = CreateSimplifiedEQ(readIndex, *it2);
+                                                       if (ASTFalse == cond)
+                                                               continue;
+
+                                                       ASTNode arrRead = CreateTerm(READ, width, arrName, *it2);
+                                                       //Good idea to TypeCheck internally constructed nodes
+                                                       BVTypeCheck(arrRead);
+
+                                                       ASTNode arrayreadSymbol = _arrayread_symbol[arrRead];
+                                                       if (arrayreadSymbol.IsNull())
+                                                               FatalError("TransformArray:symbolic variable for processedTerm, p,"
+                                                                       "does not exist:p = ", arrRead);
+                                                       ite = CreateSimplifiedTermITE(cond, arrayreadSymbol, ite);
+                                               }
+                                               result = ite;
+                                               //}
+                                       }
+
+                                       _arrayname_readindices[arrName].push_back(readIndex);
+                                       //save the ite corresponding to 'processedTerm'
+                                       _arrayread_ite[processedTerm] = result;
+                                       break;
+                               } //end of READ over a SYMBOL
+                               case WRITE:
+                               {
+                                       /* The input to this case is: READ((WRITE A i val) j)
+                                        *
+                                        * The output of this case is: ITE( (= i j) val (READ A i))
+                                        */
+
+                                       /* 1. arrName or term[0] is infact a WRITE(A,i,val) expression
+                                        *
+                                        * 2. term[1] is the read-index j
+                                        *
+                                        * 3. arrName[0] is the new arrName i.e. A. A can be either a
+                                        SYMBOL or a nested WRITE. no other possibility
+                                        *
+                                        * 4. arrName[1] is the WRITE index i.e. i
+                                        *
+                                        * 5. arrName[2] is the WRITE value i.e. val (val can inturn
+                                        *    be an array read)
+                                        */
+                                       ASTNode readIndex = TransformTerm(term[1]);
+                                       ASTNode writeIndex = TransformTerm(arrName[1]);
+                                       ASTNode writeVal = TransformTerm(arrName[2]);
+
+                                       if (!(SYMBOL == arrName[0].GetKind() || WRITE == arrName[0].GetKind()))
+                                               FatalError("TransformArray: An array write is being attempted on a non-array:", term);
+                                       if (ARRAY_TYPE != arrName[0].GetType())
+                                               FatalError("TransformArray: An array write is being attempted on a non-array:", term);
+
+                                       ASTNode cond = CreateSimplifiedEQ(writeIndex, readIndex);
+                                       //TypeCheck internally created node
+                                       BVTypeCheck(cond);
+                                       ASTNode readTerm = CreateTerm(READ, width, arrName[0], readIndex);
+                                       //TypeCheck internally created node
+                                       BVTypeCheck(readTerm);
+                                       ASTNode readPushedIn = TransformArray(readTerm);
+                                       //TypeCheck internally created node
+                                       BVTypeCheck(readPushedIn);
+                                       //result = CreateTerm(ITE, arrName[0].GetValueWidth(),cond,writeVal,readPushedIn);
+                                       result = CreateSimplifiedTermITE(cond, writeVal, readPushedIn);
+
+                                       //Good idea to typecheck terms created inside the system
+                                       BVTypeCheck(result);
+                                       break;
+                               } //end of READ over a WRITE
+                               case ITE:
+                               {
+                                       /* READ((ITE cond thn els) j)
+                                        *
+                                        * is transformed into
+                                        *
+                                        * (ITE cond (READ thn j) (READ els j))
+                                        */
+
+                                       //(ITE cond thn els)
+                                       ASTNode term0 = term[0];
+                                       //READINDEX j
+                                       ASTNode j = TransformTerm(term[1]);
+
+                                       ASTNode cond = term0[0];
+                                       //first array
+                                       ASTNode t01 = term0[1];
+                                       //second array
+                                       ASTNode t02 = term0[2];
+
+                                       cond = TransformFormula(cond);
+                                       ASTNode thn = TransformTerm(t01);
+                                       ASTNode els = TransformTerm(t02);
+
+                                       if (!(t01.GetValueWidth() == t02.GetValueWidth() && t01.GetValueWidth() == thn.GetValueWidth() && t01.GetValueWidth()
+                                                       == els.GetValueWidth()))
+                                               FatalError("TransformArray: length of THENbranch != length of ELSEbranch in the term t = \n", term);
+
+                                       if (!(t01.GetIndexWidth() == t02.GetIndexWidth() && t01.GetIndexWidth() == thn.GetIndexWidth() && t01.GetIndexWidth()
+                                                       == els.GetIndexWidth()))
+                                               FatalError("TransformArray: length of THENbranch != length of ELSEbranch in the term t = \n", term);
+
+                                       //(READ thn j)
+                                       ASTNode thnRead = CreateTerm(READ, width, thn, j);
+                                       BVTypeCheck(thnRead);
+                                       thnRead = TransformArray(thnRead);
+
+                                       //(READ els j)
+                                       ASTNode elsRead = CreateTerm(READ, width, els, j);
+                                       BVTypeCheck(elsRead);
+                                       elsRead = TransformArray(elsRead);
+
+                                       //(ITE cond (READ thn j) (READ els j))
+                                       result = CreateSimplifiedTermITE(cond, thnRead, elsRead);
+                                       BVTypeCheck(result);
+                                       break;
+                               }
+                               default:
+                                       FatalError("TransformArray: The READ is NOT over SYMBOL/WRITE/ITE", term);
+                                       break;
+                       }
+                       break;
+               } //end of READ switch
+               default:
+                       FatalError("TransformArray: input term is of wrong kind: ", ASTUndefined);
+                       break;
+       }
+
+       TransformMap[term] = result;
+       return result;
+} //end of TransformArray()
 } //end of namespace BEEV
index 57f3d20cc1c0a463d07a81f605a4bc51b135759e..f2a8c60f166d2dba53e713d2748656e1ed84f249 100644 (file)
@@ -5,25 +5,25 @@ using namespace BEEV;
 int main()
 {
 
-  BeevMgr * bm = new BeevMgr();
-  ASTNode s1 = bm->CreateSymbol("foo");
-  s1 = bm->CreateSymbol("foo1");
-  s1 = bm->CreateSymbol("foo2");
-  ASTNode s2 = bm->CreateSymbol("bar");
-  cout << "s1" <<  s1 << endl;
-  cout << "s2" <<  s2 << endl;
+       BeevMgr * bm = new BeevMgr();
+       ASTNode s1 = bm->CreateSymbol("foo");
+       s1 = bm->CreateSymbol("foo1");
+       s1 = bm->CreateSymbol("foo2");
+       ASTNode s2 = bm->CreateSymbol("bar");
+       cout << "s1" << s1 << endl;
+       cout << "s2" << s2 << endl;
 
-  ASTNode b1 = bm->CreateBVConst(5,12);
-  ASTNode b2 = bm->CreateBVConst(6,36);
-  cout << "b1: " <<  b1 << endl;
-  cout << "b2: " <<  b2 << endl;
+       ASTNode b1 = bm->CreateBVConst(5, 12);
+       ASTNode b2 = bm->CreateBVConst(6, 36);
+       cout << "b1: " << b1 << endl;
+       cout << "b2: " << b2 << endl;
 
-  ASTNode a1 = bm->CreateNode(EQ, s1, s2);
-  ASTNode a2 = bm->CreateNode(AND, s1, s2);
-  a1 = bm->CreateNode(OR, s1, s2);
-  ASTNode a3 = bm->CreateNode(IMPLIES, a1, a2);
-  ASTNode a4 = bm->CreateNode(IMPLIES, s1, a2);
-  cout << "a3" <<  a3 << endl;
-  cout << "a4" <<  a4 << endl;
-  return 0;
+       ASTNode a1 = bm->CreateNode(EQ, s1, s2);
+       ASTNode a2 = bm->CreateNode(AND, s1, s2);
+       a1 = bm->CreateNode(OR, s1, s2);
+       ASTNode a3 = bm->CreateNode(IMPLIES, a1, a2);
+       ASTNode a4 = bm->CreateNode(IMPLIES, s1, a2);
+       cout << "a3" << a3 << endl;
+       cout << "a4" << a4 << endl;
+       return 0;
 }
index 83aa6a4ea3cf300e3ed02c95d6960108e93b9ea9..7fd5c95c28596a123c60e257716a11244d6e9a15 100644 (file)
@@ -4,93 +4,93 @@ using namespace BEEV;
 
 int main()
 {
-  const int size = 32;
-
-  BeevMgr *bm = new BeevMgr();
-  ASTNode s1 = bm->CreateSymbol("x");
-  s1.SetValueWidth(size);
-  cout << "s1" <<  s1 << endl;
-  ASTNode s2 = bm->CreateSymbol("y");
-  s2.SetValueWidth(size);
-  cout << "s2" <<  s2 << endl;
-  ASTNode s3 = bm->CreateSymbol("z");
-  s3.SetValueWidth(size);
-  cout << "s3" <<  s3 << endl;
-
-  ASTNode c1 = bm->CreateBVConst(size,0);
-  cout << "c1" <<  c1 << endl;
-  ASTVec bbc1 = bm->BBTerm(c1);
-  cout << "bitblasted c1 " << endl;
-  LispPrintVec(cout, bbc1, 0);
-  cout << endl;
-  bm->AlreadyPrintedSet.clear();
-
-  ASTNode c2 = bm->CreateBVConst(size,1);
-  c2.SetValueWidth(size);
-  cout << "c2" <<  c2 << endl;
-  ASTVec bbc2 = bm->BBTerm(c2);
-  cout << "bitblasted c2 " << endl;
-  LispPrintVec(cout, bbc2, 0);
-  cout << endl;
-  bm->AlreadyPrintedSet.clear();
-
-  ASTNode c3 = bm->CreateBVConst(size, 0xFFFFFFFF);
-  c3.SetValueWidth(size);
-  cout << "c3" <<  c3 << endl;
-  ASTVec bbc3 = bm->BBTerm(c3);
-  cout << "bitblasted c3 " << endl;
-  LispPrintVec(cout, bbc3, 0);
-  cout << endl;
-  bm->AlreadyPrintedSet.clear();
-
-  ASTNode c4 = bm->CreateBVConst(size, 0xAAAAAAAA);
-  c4.SetValueWidth(size);
-  cout << "c4" <<  c4 << endl;
-  ASTVec bbc4 = bm->BBTerm(c4);
-  cout << "bitblasted c4 " << endl;
-  LispPrintVec(cout, bbc4, 0);
-  cout << endl;
-  bm->AlreadyPrintedSet.clear();
-
-//   ASTNode b1 = bm->CreateBVConst(12);
-//   ASTNode b2 = bm->CreateBVConst(36);
-//   cout << "b1: " <<  b1 << endl;
-//   cout << "b2: " <<  b2 << endl;
-
-  ASTNode a1 = bm->CreateNode(BVPLUS, s1, s2);
-  a1.SetValueWidth(size);
-
-  ASTVec& bba1 = bm->BBTerm(a1);
-  cout << "bitblasted a1 " << endl;
-  LispPrintVec(cout, bba1, 0);
-  cout << endl;
-  bm->AlreadyPrintedSet.clear();
-
-  ASTNode a2 = bm->CreateNode(BVPLUS, s1, s2, s3);
-  a1.SetValueWidth(2);
-
-  ASTVec& bba2 = bm->BBTerm(a2);
-  cout << "bitblasted a2 " << endl;
-  LispPrintVec(cout, bba2, 0);
-  cout << endl;
-  bm->AlreadyPrintedSet.clear();
-
-  ASTNode a3 = bm->CreateNode(BVXOR, s1, s2);
-  a3.SetValueWidth(2);
-
-  ASTVec& bba3 = bm->BBTerm(a3);
-  cout << "bitblasted a3 " << endl;
-  LispPrintVec(cout, bba3, 0);
-  cout << endl;
-  bm->AlreadyPrintedSet.clear();
-
-  ASTNode a4 = bm->CreateNode(EQ, s1, s2);
-  ASTNode bba4 = bm->BBForm(a4);
-  cout << "bitblasted a4 " << endl << bba4 << endl;
-
-  ASTNode a5 = bm->CreateNode(BVLE, s1, s2);
-  ASTNode bba5 = bm->BBForm(a5);
-  cout << "bitblasted a5 " << endl << bba5 << endl;
-
-  return 0;
+       const int size = 32;
+
+       BeevMgr *bm = new BeevMgr();
+       ASTNode s1 = bm->CreateSymbol("x");
+       s1.SetValueWidth(size);
+       cout << "s1" << s1 << endl;
+       ASTNode s2 = bm->CreateSymbol("y");
+       s2.SetValueWidth(size);
+       cout << "s2" << s2 << endl;
+       ASTNode s3 = bm->CreateSymbol("z");
+       s3.SetValueWidth(size);
+       cout << "s3" << s3 << endl;
+
+       ASTNode c1 = bm->CreateBVConst(size, 0);
+       cout << "c1" << c1 << endl;
+       ASTVec bbc1 = bm->BBTerm(c1);
+       cout << "bitblasted c1 " << endl;
+       LispPrintVec(cout, bbc1, 0);
+       cout << endl;
+       bm->AlreadyPrintedSet.clear();
+
+       ASTNode c2 = bm->CreateBVConst(size, 1);
+       c2.SetValueWidth(size);
+       cout << "c2" << c2 << endl;
+       ASTVec bbc2 = bm->BBTerm(c2);
+       cout << "bitblasted c2 " << endl;
+       LispPrintVec(cout, bbc2, 0);
+       cout << endl;
+       bm->AlreadyPrintedSet.clear();
+
+       ASTNode c3 = bm->CreateBVConst(size, 0xFFFFFFFF);
+       c3.SetValueWidth(size);
+       cout << "c3" << c3 << endl;
+       ASTVec bbc3 = bm->BBTerm(c3);
+       cout << "bitblasted c3 " << endl;
+       LispPrintVec(cout, bbc3, 0);
+       cout << endl;
+       bm->AlreadyPrintedSet.clear();
+
+       ASTNode c4 = bm->CreateBVConst(size, 0xAAAAAAAA);
+       c4.SetValueWidth(size);
+       cout << "c4" << c4 << endl;
+       ASTVec bbc4 = bm->BBTerm(c4);
+       cout << "bitblasted c4 " << endl;
+       LispPrintVec(cout, bbc4, 0);
+       cout << endl;
+       bm->AlreadyPrintedSet.clear();
+
+       //   ASTNode b1 = bm->CreateBVConst(12);
+       //   ASTNode b2 = bm->CreateBVConst(36);
+       //   cout << "b1: " <<  b1 << endl;
+       //   cout << "b2: " <<  b2 << endl;
+
+       ASTNode a1 = bm->CreateNode(BVPLUS, s1, s2);
+       a1.SetValueWidth(size);
+
+       ASTVec& bba1 = bm->BBTerm(a1);
+       cout << "bitblasted a1 " << endl;
+       LispPrintVec(cout, bba1, 0);
+       cout << endl;
+       bm->AlreadyPrintedSet.clear();
+
+       ASTNode a2 = bm->CreateNode(BVPLUS, s1, s2, s3);
+       a1.SetValueWidth(2);
+
+       ASTVec& bba2 = bm->BBTerm(a2);
+       cout << "bitblasted a2 " << endl;
+       LispPrintVec(cout, bba2, 0);
+       cout << endl;
+       bm->AlreadyPrintedSet.clear();
+
+       ASTNode a3 = bm->CreateNode(BVXOR, s1, s2);
+       a3.SetValueWidth(2);
+
+       ASTVec& bba3 = bm->BBTerm(a3);
+       cout << "bitblasted a3 " << endl;
+       LispPrintVec(cout, bba3, 0);
+       cout << endl;
+       bm->AlreadyPrintedSet.clear();
+
+       ASTNode a4 = bm->CreateNode(EQ, s1, s2);
+       ASTNode bba4 = bm->BBForm(a4);
+       cout << "bitblasted a4 " << endl << bba4 << endl;
+
+       ASTNode a5 = bm->CreateNode(BVLE, s1, s2);
+       ASTNode bba5 = bm->BBForm(a5);
+       cout << "bitblasted a5 " << endl << bba5 << endl;
+
+       return 0;
 }
index 7ce270c8c108dbb67f6d0c544e45acd4551af716..2c337c447c003670b816ae6cb34616d3a7ed5626 100644 (file)
@@ -8,40 +8,40 @@ using namespace BEEV;
 
 int main()
 {
-  const int size = 1;
-  
-  BeevMgr *bm = new BeevMgr();
-  ASTNode s1 = bm->CreateSymbol("x");
-  s1.SetValueWidth(size);
-  
-  cout << "s1" <<  s1 << endl;
-  ASTNode s2 = bm->CreateSymbol("y");
-  s2.SetValueWidth(size);
-
-  cout << "s2" <<  s2 << endl;
-  ASTNode s3 = bm->CreateSymbol("z");
-  s3.SetValueWidth(size);
-  
-  cout << "s3" <<  s3 << endl;
-
-  ASTNode bbs1 = bm->BBForm(s1);
-  cout << "bitblasted s1" << endl << bbs1 << endl;
-  bm->PrintClauseList(cout, bm->ToCNF(bbs1));
-
-  ASTNode a2 = bm->CreateNode(AND, s1, s2);
-  ASTNode bba2 = bm->BBForm(a2);
-  cout << "bitblasted a2" << endl << bba2 << endl;
-  bm->PrintClauseList(cout, bm->ToCNF(bba2));
-
-  ASTNode a3 = bm->CreateNode(OR, s1, s2);
-  ASTNode bba3 = bm->BBForm(a3);
-  cout << "bitblasted a3" << endl << bba3 << endl;
-  bm->PrintClauseList(cout, bm->ToCNF(bba3));
-
-  ASTNode a4 = bm->CreateNode(EQ, s1, s2);
-  ASTNode bba4 = bm->BBForm(a4);
-  cout << "bitblasted a4 " << endl << bba4 << endl;
-
-  bm->PrintClauseList(cout, bm->ToCNF(bba4));
+       const int size = 1;
+
+       BeevMgr *bm = new BeevMgr();
+       ASTNode s1 = bm->CreateSymbol("x");
+       s1.SetValueWidth(size);
+
+       cout << "s1" << s1 << endl;
+       ASTNode s2 = bm->CreateSymbol("y");
+       s2.SetValueWidth(size);
+
+       cout << "s2" << s2 << endl;
+       ASTNode s3 = bm->CreateSymbol("z");
+       s3.SetValueWidth(size);
+
+       cout << "s3" << s3 << endl;
+
+       ASTNode bbs1 = bm->BBForm(s1);
+       cout << "bitblasted s1" << endl << bbs1 << endl;
+       bm->PrintClauseList(cout, bm->ToCNF(bbs1));
+
+       ASTNode a2 = bm->CreateNode(AND, s1, s2);
+       ASTNode bba2 = bm->BBForm(a2);
+       cout << "bitblasted a2" << endl << bba2 << endl;
+       bm->PrintClauseList(cout, bm->ToCNF(bba2));
+
+       ASTNode a3 = bm->CreateNode(OR, s1, s2);
+       ASTNode bba3 = bm->BBForm(a3);
+       cout << "bitblasted a3" << endl << bba3 << endl;
+       bm->PrintClauseList(cout, bm->ToCNF(bba3));
+
+       ASTNode a4 = bm->CreateNode(EQ, s1, s2);
+       ASTNode bba4 = bm->BBForm(a4);
+       cout << "bitblasted a4 " << endl << bba4 << endl;
+
+       bm->PrintClauseList(cout, bm->ToCNF(bba4));
 
 }
index 482c72a3720a1739f96a09cd81014d2b7727bb2c..34358bb269417201de0c356d50ed2f6bcc309738 100644 (file)
@@ -1,11 +1,11 @@
 #include "printers.h"
 
-namespace printer {
+namespace printer
+{
 
 using std::string;
 using namespace BEEV;
 
-
 // printer for C code (copied from PL_Print())
 // TODO: this does not fully implement printing of all of the STP
 // language - FatalError calls inserted for unimplemented
@@ -13,14 +13,16 @@ using namespace BEEV;
 //   FatalError("C_Print1: printing not implemented for this kind: ",*this);
 
 // helper function for printing C code (copied from PL_Print1())
-void C_Print1(ostream& os, const ASTNode n, int indentation, bool letize) {
+void C_Print1(ostream& os, const ASTNode n, int indentation, bool letize)
+{
 
        unsigned int upper, lower, num_bytes;
        Kind LHSkind, RHSkind;
 
        //os << spaces(indentation);
        //os << endl << spaces(indentation);
-       if (!n.IsDefined()) {
+       if (!n.IsDefined())
+       {
                os << "<undefined>";
                return;
        }
@@ -30,14 +32,16 @@ void C_Print1(ostream& os, const ASTNode n, int indentation, bool letize) {
 
        //this is to print letvars for shared subterms inside the printing
        //of "(LET v0 = term1, v1=term1@term2,...
-       if ((bm.NodeLetVarMap1.find(n) != bm.NodeLetVarMap1.end()) && !letize) {
+       if ((bm.NodeLetVarMap1.find(n) != bm.NodeLetVarMap1.end()) && !letize)
+       {
                C_Print1(os, (bm.NodeLetVarMap1[n]), indentation, letize);
                return;
        }
 
        //this is to print letvars for shared subterms inside the actual
        //term to be printed
-       if ((bm.NodeLetVarMap.find(n) != bm.NodeLetVarMap.end()) && letize) {
+       if ((bm.NodeLetVarMap.find(n) != bm.NodeLetVarMap.end()) && letize)
+       {
                C_Print1(os, (bm.NodeLetVarMap[n]), indentation, letize);
                return;
        }
@@ -45,7 +49,8 @@ void C_Print1(ostream& os, const ASTNode n, int indentation, bool letize) {
        //otherwise print it normally
        Kind kind = n.GetKind();
        const ASTVec &c = n.GetChildren();
-       switch (kind) {
+       switch (kind)
+       {
                case BVGETBIT:
                        FatalError("C_Print1: printing not implemented for this kind: ", n);
                        C_Print1(os, c[0], indentation, letize);
@@ -110,7 +115,7 @@ void C_Print1(ostream& os, const ASTNode n, int indentation, bool letize) {
                case BVCONCAT:
                        FatalError("C_Print1: printing not implemented for this kind: ", n); // stopgap for un-implemented features
                        os << "(";
-                       C_Print1(os,c[0], indentation, letize);
+                       C_Print1(os, c[0], indentation, letize);
                        os << " @ ";
                        C_Print1(os, c[1], indentation, letize);
                        os << ")" << endl;
@@ -143,13 +148,15 @@ void C_Print1(ostream& os, const ASTNode n, int indentation, bool letize) {
                        assert (num_bytes > 0);
 
                        // for multi-byte extraction, use the ADDRESS
-                       if (num_bytes > 1) {
+                       if (num_bytes > 1)
+                       {
                                os << "&";
                                C_Print1(os, c[0], indentation, letize);
                                os << "[" << lower / 8 << "]";
                        }
                        // for single-byte extraction, use the VALUE
-                       else {
+                       else
+                       {
                                C_Print1(os, c[0], indentation, letize);
                                os << "[" << lower / 8 << "]";
                        }
@@ -166,7 +173,7 @@ void C_Print1(ostream& os, const ASTNode n, int indentation, bool letize) {
                case BVRIGHTSHIFT:
                        FatalError("C_Print1: printing not implemented for this kind: ", n); // stopgap for un-implemented features
                        os << "(";
-                       C_Print1(os,c[0], indentation, letize);
+                       C_Print1(os, c[0], indentation, letize);
                        os << " >> ";
                        os << GetUnsignedConst(c[1]);
                        os << ")";
@@ -180,7 +187,8 @@ void C_Print1(ostream& os, const ASTNode n, int indentation, bool letize) {
                case BVMOD:
                        os << kind << "(";
                        os << n.GetValueWidth();
-                       for (ASTVec::const_iterator it = c.begin(), itend = c.end(); it != itend; it++) {
+                       for (ASTVec::const_iterator it = c.begin(), itend = c.end(); it != itend; it++)
+                       {
                                os << ", " << endl;
                                C_Print1(os, *it, indentation, letize);
                        }
@@ -284,34 +292,39 @@ void C_Print1(ostream& os, const ASTNode n, int indentation, bool letize) {
 
                        // try to figure out whether it's a single-byte or multi-byte
                        // comparison
-                       if (LHSkind == BVEXTRACT) {
+                       if (LHSkind == BVEXTRACT)
+                       {
                                upper = GetUnsignedConst(c[0].GetChildren()[1]);
                                lower = GetUnsignedConst(c[0].GetChildren()[2]);
                                num_bytes = (upper - lower + 1) / 8;
                        }
-                       else if (RHSkind == BVEXTRACT) {
+                       else if (RHSkind == BVEXTRACT)
+                       {
                                upper = GetUnsignedConst(c[1].GetChildren()[1]);
                                lower = GetUnsignedConst(c[1].GetChildren()[2]);
                                num_bytes = (upper - lower + 1) / 8;
                        }
 
-                       if (num_bytes > 1) {
+                       if (num_bytes > 1)
+                       {
                                os << "(memcmp(";
-                               C_Print1(os,c[0], indentation, letize);
+                               C_Print1(os, c[0], indentation, letize);
                                os << ", ";
                                C_Print1(os, c[1], indentation, letize);
                                os << ", ";
                                os << num_bytes;
                                os << ") == 0)";
                        }
-                       else if (num_bytes == 1) {
+                       else if (num_bytes == 1)
+                       {
                                os << "(";
                                C_Print1(os, c[0], indentation, letize);
                                os << " == ";
                                C_Print1(os, c[1], indentation, letize);
                                os << ")";
                        }
-                       else {
+                       else
+                       {
                                FatalError("C_Print1: ugh problem in implementing ==");
                        }
 
@@ -326,15 +339,18 @@ void C_Print1(ostream& os, const ASTNode n, int indentation, bool letize) {
                case OR:
                case NAND:
                case NOR:
-               case XOR: {
+               case XOR:
+               {
                        os << "(";
                        C_Print1(os, c[0], indentation, letize);
                        ASTVec::const_iterator it = c.begin();
                        ASTVec::const_iterator itend = c.end();
 
                        it++;
-                       for (; it != itend; it++) {
-                               switch (kind) {
+                       for (; it != itend; it++)
+                       {
+                               switch (kind)
+                               {
                                        case AND:
                                                os << " && ";
                                                break;
@@ -362,11 +378,11 @@ void C_Print1(ostream& os, const ASTNode n, int indentation, bool letize) {
                        FatalError("C_Print1: printing not implemented for this kind: ", n); // stopgap for un-implemented features
                        os << "(";
                        os << "(";
-                       C_Print1(os,c[0], indentation, letize);
+                       C_Print1(os, c[0], indentation, letize);
                        os << ")";
                        os << " <=> ";
                        os << "(";
-                       C_Print1(os,c[1], indentation, letize);
+                       C_Print1(os, c[1], indentation, letize);
                        os << ")";
                        os << ")";
                        os << endl;
@@ -375,7 +391,7 @@ void C_Print1(ostream& os, const ASTNode n, int indentation, bool letize) {
                        FatalError("C_Print1: printing not implemented for this kind: ", n); // stopgap for un-implemented features
                        os << "(";
                        os << "(";
-                       C_Print1(os, c[0],indentation, letize);
+                       C_Print1(os, c[0], indentation, letize);
                        os << ")";
                        os << " => ";
                        os << "(";
@@ -388,7 +404,7 @@ void C_Print1(ostream& os, const ASTNode n, int indentation, bool letize) {
                        FatalError("C_Print1: printing not implemented for this kind: ", n); // stopgap for un-implemented features
 
                        os << kind << "(";
-                       C_Print1(os, c[0],indentation, letize);
+                       C_Print1(os, c[0], indentation, letize);
                        os << ",";
                        os << n.GetValueWidth();
                        os << ")" << endl;
@@ -411,7 +427,8 @@ void C_Print1(ostream& os, const ASTNode n, int indentation, bool letize) {
 //2. In the second pass print a "global let" and then print N
 //2. as follows: Every occurence of a node occuring more than
 //2. once is replaced with the corresponding let variable.
-ostream& C_Print(ostream &os, const ASTNode n,  int indentation)  {
+ostream& C_Print(ostream &os, const ASTNode n, int indentation)
+{
        // Clear the PrintMap
        BeevMgr& bm = n.GetBeevMgr();
        bm.PLPrintNodeSet.clear();
@@ -432,7 +449,8 @@ ostream& C_Print(ostream &os, const ASTNode n,  int indentation)  {
        //3. Then print the Node itself, replacing every occurence of
        //3. expr1 with var1, expr2 with var2, ...
        //os << "(";
-       if (0 < bm.NodeLetVarMap.size()) {
+       if (0 < bm.NodeLetVarMap.size())
+       {
                //ASTNodeMap::iterator it=bm.NodeLetVarMap.begin();
                //ASTNodeMap::iterator itend=bm.NodeLetVarMap.end();
                std::vector<pair<ASTNode, ASTNode> >::iterator it = bm.NodeLetVarVec.begin();
@@ -441,10 +459,12 @@ ostream& C_Print(ostream &os, const ASTNode n,  int indentation)  {
                // start a new block to create new static scope
                os << "{" << endl;
 
-               for (; it != itend; it++) {
+               for (; it != itend; it++)
+               {
 
                        // see if it's a BVEXTRACT, and if so, whether it's multi-byte
-                       if (it->second.GetKind() == BVEXTRACT) {
+                       if (it->second.GetKind() == BVEXTRACT)
+                       {
                                upper = GetUnsignedConst(it->second.GetChildren()[1]);
                                lower = GetUnsignedConst(it->second.GetChildren()[2]);
                                num_bytes = (upper - lower + 1) / 8;
@@ -452,25 +472,27 @@ ostream& C_Print(ostream &os, const ASTNode n,  int indentation)  {
                        }
 
                        //print the let var first
-                       if (num_bytes > 1) {
+                       if (num_bytes > 1)
+                       {
                                // for multi-byte assignment, use 'memcpy' and array notation
                                os << "unsigned char ";
-                               C_Print1(os, it->first,indentation, false);
+                               C_Print1(os, it->first, indentation, false);
                                os << "[" << num_bytes << "]; ";
                                os << "memcpy(";
-                               C_Print1(os,it->first, indentation, false);
+                               C_Print1(os, it->first, indentation, false);
                                os << ", ";
                                //print the expr
-                               C_Print1(os,it->second, indentation, false);
+                               C_Print1(os, it->second, indentation, false);
                                os << ", " << num_bytes << ");";
                        }
-                       else {
+                       else
+                       {
                                // for single-byte assignment, use '='
                                os << "unsigned char ";
-                               C_Print1(os, it->first,indentation, false);
+                               C_Print1(os, it->first, indentation, false);
                                os << " = ";
                                //print the expr
-                               C_Print1(os, it->second,indentation, false);
+                               C_Print1(os, it->second, indentation, false);
                                os << ";" << endl;
                        }
 
@@ -483,7 +505,8 @@ ostream& C_Print(ostream &os, const ASTNode n,  int indentation)  {
 
                os << ";" << endl << "}";
        }
-       else {
+       else
+       {
                os << "stp_assert ";
                C_Print1(os, n, indentation, false);
                os << ";";
index c04167753470dbfcf6269c768f9fe2c6923d3321..d761fe637ccf02e554c3d74046bee1d34d732167 100644 (file)
@@ -1,6 +1,7 @@
 #include "printers.h"
 
-namespace printer {
+namespace printer
+{
 
 using std::string;
 using namespace BEEV;
@@ -8,15 +9,18 @@ using namespace BEEV;
 string functionToSMTLIBName(const BEEV::Kind k);
 void SMTLIB_Print1(ostream& os, const BEEV::ASTNode n, int indentation, bool letize);
 
-void outputBitVec(const ASTNode n, ostream& os) {
+void outputBitVec(const ASTNode n, ostream& os)
+{
        Kind k = n.GetKind();
        const ASTVec &c = n.GetChildren();
        ASTNode op;
 
-       if (BITVECTOR == k) {
+       if (BITVECTOR == k)
+       {
                op = c[0];
        }
-       else if (BVCONST == k) {
+       else if (BVCONST == k)
+       {
                op = n;
        }
        else
@@ -33,10 +37,12 @@ void outputBitVec(const ASTNode n, ostream& os) {
        CONSTANTBV::BitVector_Dispose(str);
 }
 
-void SMTLIB_Print1(ostream& os, const ASTNode n, int indentation, bool letize) {
+void SMTLIB_Print1(ostream& os, const ASTNode n, int indentation, bool letize)
+{
        //os << spaces(indentation);
        //os << endl << spaces(indentation);
-       if (!n.IsDefined()) {
+       if (!n.IsDefined())
+       {
                os << "<undefined>";
                return;
        }
@@ -46,14 +52,16 @@ void SMTLIB_Print1(ostream& os, const ASTNode n, int indentation, bool letize) {
 
        //this is to print letvars for shared subterms inside the printing
        //of "(LET v0 = term1, v1=term1@term2,...
-       if ((bm.NodeLetVarMap1.find(n) != bm.NodeLetVarMap1.end()) && !letize) {
+       if ((bm.NodeLetVarMap1.find(n) != bm.NodeLetVarMap1.end()) && !letize)
+       {
                SMTLIB_Print1(os, (bm.NodeLetVarMap1[n]), indentation, letize);
                return;
        }
 
        //this is to print letvars for shared subterms inside the actual
        //term to be printed
-       if ((bm.NodeLetVarMap.find(n) != bm.NodeLetVarMap.end()) && letize) {
+       if ((bm.NodeLetVarMap.find(n) != bm.NodeLetVarMap.end()) && letize)
+       {
                SMTLIB_Print1(os, (bm.NodeLetVarMap[n]), indentation, letize);
                return;
        }
@@ -61,7 +69,8 @@ void SMTLIB_Print1(ostream& os, const ASTNode n, int indentation, bool letize) {
        //otherwise print it normally
        Kind kind = n.GetKind();
        const ASTVec &c = n.GetChildren();
-       switch (kind) {
+       switch (kind)
+       {
                case BITVECTOR:
                case BVCONST:
                        outputBitVec(n, os);
@@ -78,7 +87,8 @@ void SMTLIB_Print1(ostream& os, const ASTNode n, int indentation, bool letize) {
                        break;
 
                case BVSX:
-               case BVZX: {
+               case BVZX:
+               {
                        unsigned int amount = GetUnsignedConst(c[1]);
                        if (BVZX == kind)
                                os << "(zero_extend[";
@@ -90,7 +100,8 @@ void SMTLIB_Print1(ostream& os, const ASTNode n, int indentation, bool letize) {
                        os << ")";
                }
                        break;
-               case BVEXTRACT: {
+               case BVEXTRACT:
+               {
                        unsigned int upper = GetUnsignedConst(c[1]);
                        unsigned int lower = GetUnsignedConst(c[2]);
                        assert(upper >= lower);
@@ -99,11 +110,13 @@ void SMTLIB_Print1(ostream& os, const ASTNode n, int indentation, bool letize) {
                        os << ")";
                }
                        break;
-               default: {
+               default:
+               {
                        os << "(" << functionToSMTLIBName(kind);
 
                        ASTVec::const_iterator iend = c.end();
-                       for (ASTVec::const_iterator i = c.begin(); i != iend; i++) {
+                       for (ASTVec::const_iterator i = c.begin(); i != iend; i++)
+                       {
                                os << " ";
                                SMTLIB_Print1(os, *i, 0, letize);
                        }
@@ -114,7 +127,8 @@ void SMTLIB_Print1(ostream& os, const ASTNode n, int indentation, bool letize) {
 }
 
 // copied from Presentation Langauge printer.
-ostream& SMTLIB_Print(ostream &os, const ASTNode n, const int indentation) {
+ostream& SMTLIB_Print(ostream &os, const ASTNode n, const int indentation)
+{
        // Clear the PrintMap
        BeevMgr& bm = n.GetBeevMgr();
        bm.PLPrintNodeSet.clear();
@@ -133,7 +147,8 @@ ostream& SMTLIB_Print(ostream &os, const ASTNode n, const int indentation) {
        //3. Then print the Node itself, replacing every occurence of
        //3. expr1 with var1, expr2 with var2, ...
        //os << "(";
-       if (0 < bm.NodeLetVarMap.size()) {
+       if (0 < bm.NodeLetVarMap.size())
+       {
                //ASTNodeMap::iterator it=bm.NodeLetVarMap.begin();
                //ASTNodeMap::iterator itend=bm.NodeLetVarMap.end();
                std::vector<pair<ASTNode, ASTNode> >::iterator it = bm.NodeLetVarVec.begin();
@@ -149,7 +164,8 @@ ostream& SMTLIB_Print(ostream &os, const ASTNode n, const int indentation) {
                //update the second map for proper printing of LET
                bm.NodeLetVarMap1[it->second] = it->first;
 
-               for (it++; it != itend; it++) {
+               for (it++; it != itend; it++)
+               {
                        os << "," << endl;
                        //print the let var first
                        SMTLIB_Print1(os, it->first, indentation, false);
@@ -172,8 +188,10 @@ ostream& SMTLIB_Print(ostream &os, const ASTNode n, const int indentation) {
        return os;
 }
 
-string functionToSMTLIBName(const Kind k) {
-       switch (k) {
+string functionToSMTLIBName(const Kind k)
+{
+       switch (k)
+       {
                case AND:
                case BVAND:
                case BVNAND:
@@ -233,7 +251,8 @@ string functionToSMTLIBName(const Kind k) {
                case SBVREM:
                        return "bvsrem";
 
-               default: {
+               default:
+               {
                        cerr << "Unknown name when outputting:";
                        FatalError(_kind_names[k]);
                        return ""; // to quieten compiler/
index 0ffd9f2031eff2b1f789eec7799421b8079e03e6..703856714dd73a7ea2fc0d4356e7bf2d07c7d9d7 100644 (file)
@@ -4,14 +4,16 @@
  * Outputs in DOT graph format. Can be layed out by the dotty/neato tools.
  */
 
-namespace printer {
+namespace printer
+{
 
 using std::string;
 using namespace BEEV;
 
 void outputBitVec(const ASTNode n, ostream& os);
 
-void Dot_Print1(ostream &os, const ASTNode n, hash_set<int> *alreadyOutput) {
+void Dot_Print1(ostream &os, const ASTNode n, hash_set<int> *alreadyOutput)
+{
 
        // check if this node has already been printed. If so return.
        if (alreadyOutput->find(n.GetNodeNum()) != alreadyOutput->end())
@@ -20,7 +22,7 @@ void Dot_Print1(ostream &os, const ASTNode n, hash_set<int> *alreadyOutput) {
        alreadyOutput->insert(n.GetNodeNum());
 
        os << "n" << n.GetNodeNum() << "[label =\"";
-       switch(n.GetKind())
+       switch (n.GetKind())
        {
                case SYMBOL:
                        n.nodeprint(os);
@@ -35,27 +37,26 @@ void Dot_Print1(ostream &os, const ASTNode n, hash_set<int> *alreadyOutput) {
                        os << _kind_names[n.GetKind()];
        }
 
-
-       os  << "\"];" << endl;
-
+       os << "\"];" << endl;
 
        // print the edges to each child.
-    ASTVec ch = n.GetChildren();
-    ASTVec::iterator itend = ch.end();
-    int i =0;
-    for(ASTVec::iterator it = ch.begin(); it < itend; it++)
-    {
-       os << "n" << n.GetNodeNum() << " -> " << "n" << it->GetNodeNum() << "[label=" << i++ << "];" << endl;
-    }
-
-    // print each of the children.
-    for(ASTVec::iterator it = ch.begin(); it < itend; it++)
-    {
-       Dot_Print1(os, *it, alreadyOutput);
-    }
+       ASTVec ch = n.GetChildren();
+       ASTVec::iterator itend = ch.end();
+       int i = 0;
+       for (ASTVec::iterator it = ch.begin(); it < itend; it++)
+       {
+               os << "n" << n.GetNodeNum() << " -> " << "n" << it->GetNodeNum() << "[label=" << i++ << "];" << endl;
+       }
+
+       // print each of the children.
+       for (ASTVec::iterator it = ch.begin(); it < itend; it++)
+       {
+               Dot_Print1(os, *it, alreadyOutput);
+       }
 }
 
-ostream& Dot_Print(ostream &os, const ASTNode n) {
+ostream& Dot_Print(ostream &os, const ASTNode n)
+{
 
        os << "digraph G{" << endl;
 
index fb996585895944535c16b94b1c1eb9599e0cfbcd..ae38669a2eade17c0ddc2aa6e7b8454bcd6c9069 100644 (file)
@@ -5,13 +5,12 @@
 #include "../ASTUtil.h"
 #include "../ASTKind.h"
 
-
 namespace printer
 {
 
-       ostream& Dot_Print(ostream &os, const BEEV::ASTNode n);
-       ostream& SMTLIB_Print(ostream &os, const BEEV::ASTNode n, const int indentation=0);
-       ostream& C_Print(ostream &os, const BEEV::ASTNode n, const int indentation=0);
+ostream& Dot_Print(ostream &os, const BEEV::ASTNode n);
+ostream& SMTLIB_Print(ostream &os, const BEEV::ASTNode n, const int indentation = 0);
+ostream& C_Print(ostream &os, const BEEV::ASTNode n, const int indentation = 0);
 }
 
 #endif /* PRINTERS_H_ */
index 86837633dfb129d40e178f3d7bd9b7e2071e0271..e6ca42aac706264783937721ed85000ccdcda2ad 100644 (file)
 
 #include "../AST/AST.h"
 #include "../AST/ASTUtil.h"
-namespace BEEV {
+namespace BEEV
+{
 
-  //error printing
-  static void BVConstEvaluatorError(CONSTANTBV::ErrCode e, const ASTNode& t){
-    std::string ss("BVConstEvaluator:");
-    ss += (const char*)BitVector_Error(e);     
-    FatalError(ss.c_str(), t);
-  }
+//error printing
+static void BVConstEvaluatorError(CONSTANTBV::ErrCode e, const ASTNode& t)
+{
+       std::string ss("BVConstEvaluator:");
+       ss += (const char*) BitVector_Error(e);
+       FatalError(ss.c_str(), t);
+}
 
 #ifndef NATIVE_C_ARITH
-  ASTNode BeevMgr::BVConstEvaluator(const ASTNode& t) {
-    ASTNode OutputNode;
-    Kind k = t.GetKind();
-
-    if(CheckSolverMap(t,OutputNode))
-      return OutputNode;
-    OutputNode = t;
-
-    unsigned int inputwidth = t.GetValueWidth();
-    unsigned int outputwidth = inputwidth;
-    CBV output = NULL;
-
-    CBV tmp0 = NULL;
-    CBV tmp1 = NULL;
-
-    //saving some typing. BVPLUS does not use these variables. if the
-    //input BVPLUS has two nodes, then we want to avoid setting these
-    //variables.
-    if(1 == t.Degree() ){
-      tmp0 = BVConstEvaluator(t[0]).GetBVConst();
-    }else if(2 == t.Degree() && k != BVPLUS ) {
-      tmp0 = BVConstEvaluator(t[0]).GetBVConst();
-      tmp1 = BVConstEvaluator(t[1]).GetBVConst();
-    }
-
-    switch(k) {
-    case UNDEFINED:
-    case READ:
-    case WRITE:
-    case SYMBOL:
-      FatalError("BVConstEvaluator: term is not a constant-term",t);
-      break;
-    case BVCONST:
-      //FIXME Handle this special case better
-      OutputNode = t;
-      break;
-    case BVNEG:{
-      output = CONSTANTBV::BitVector_Create(inputwidth,true);
-      CONSTANTBV::Set_Complement(output,tmp0);
-      OutputNode = CreateBVConst(output,outputwidth);
-      break;
-    }
-    case BVSX: {
-      output = CONSTANTBV::BitVector_Create(inputwidth,true);
-      //unsigned * out0 = BVConstEvaluator(t[0]).GetBVConst();
-      unsigned t0_width = t[0].GetValueWidth();
-      if(inputwidth == t0_width) {
-        CONSTANTBV::BitVector_Copy(output, tmp0);
-        OutputNode = CreateBVConst(output, outputwidth);    
-      }
-      else {
-        bool topbit_sign = (CONSTANTBV::BitVector_Sign(tmp0) < 0 );
-
-        if(topbit_sign){
-          CONSTANTBV::BitVector_Fill(output);
-        }
-        CONSTANTBV::BitVector_Interval_Copy(output, tmp0, 0, 0, t0_width);
-        OutputNode = CreateBVConst(output, outputwidth);    
-      }
-      break;
-    }
-
-    case BVZX: {
-      output = CONSTANTBV::BitVector_Create(inputwidth,true);
-      unsigned t0_width = t[0].GetValueWidth();
-      if(inputwidth == t0_width) {
-        CONSTANTBV::BitVector_Copy(output, tmp0);
-        OutputNode = CreateBVConst(output, outputwidth);
-      }
-      else {
-        CONSTANTBV::BitVector_Interval_Copy(output, tmp0, 0, 0, t0_width);
-        OutputNode = CreateBVConst(output, outputwidth);
-      }
-      break;
-    }
-
-
-   case BVLEFTSHIFT: 
-     {
-      output = CONSTANTBV::BitVector_Create(inputwidth,true);
-
-      // the shift is destructive, get a copy.
-      CONSTANTBV::BitVector_Interval_Copy(output, tmp0, 0, 0, inputwidth);
-
-      // get the number of bits to shift it.
-      unsigned int shift = GetUnsignedConst(BVConstEvaluator(t[1]));
-
-      CONSTANTBV::BitVector_Move_Left(output,shift);
-      OutputNode = CreateBVConst(output,outputwidth);
-      break;
-    }
-    case BVRIGHTSHIFT: 
-      {
-       output = CONSTANTBV::BitVector_Create(inputwidth,true);
-
-      // the shift is destructive, get a copy.
-      CONSTANTBV::BitVector_Interval_Copy(output, tmp0, 0, 0, inputwidth);
-
-      // get the number of bits to shift it.
-      unsigned int shift = GetUnsignedConst(BVConstEvaluator(t[1]));
-
-      CONSTANTBV::BitVector_Move_Right(output,shift);
-      OutputNode = CreateBVConst(output,outputwidth);
-      break;
-    }
-
-
-    case BVAND: {
-      output = CONSTANTBV::BitVector_Create(inputwidth,true);
-      CONSTANTBV::Set_Intersection(output,tmp0,tmp1);
-      OutputNode = CreateBVConst(output, outputwidth);
-      break;
-    }
-    case BVOR: {
-      output = CONSTANTBV::BitVector_Create(inputwidth,true);
-      CONSTANTBV::Set_Union(output,tmp0,tmp1);
-      OutputNode = CreateBVConst(output, outputwidth);
-      break;
-    }
-    case BVXOR: {
-      output = CONSTANTBV::BitVector_Create(inputwidth,true);
-      CONSTANTBV::Set_ExclusiveOr(output,tmp0,tmp1);
-      OutputNode = CreateBVConst(output, outputwidth);
-      break;
-    }
-    case BVSUB: {
-      output = CONSTANTBV::BitVector_Create(inputwidth,true);
-      bool carry = false;
-      CONSTANTBV::BitVector_sub(output,tmp0,tmp1,&carry);
-      OutputNode = CreateBVConst(output, outputwidth);    
-      break;
-    }
-    case BVUMINUS: {
-      output = CONSTANTBV::BitVector_Create(inputwidth,true);
-      CONSTANTBV::BitVector_Negate(output, tmp0);
-      OutputNode = CreateBVConst(output, outputwidth);    
-      break;
-    }
-    case BVEXTRACT: {
-      output = CONSTANTBV::BitVector_Create(inputwidth,true);
-      tmp0 = BVConstEvaluator(t[0]).GetBVConst();
-      unsigned int hi = GetUnsignedConst(BVConstEvaluator(t[1]));
-      unsigned int low = GetUnsignedConst(BVConstEvaluator(t[2]));
-      unsigned int len = hi-low+1;
-
-      CONSTANTBV::BitVector_Destroy(output);
-      output = CONSTANTBV::BitVector_Create(len, false);
-      CONSTANTBV::BitVector_Interval_Copy(output, tmp0, 0, low, len);
-      outputwidth = len;
-      OutputNode = CreateBVConst(output, outputwidth);
-      break;
-    }
-    //FIXME Only 2 inputs?
-    case BVCONCAT: {
-       output = CONSTANTBV::BitVector_Create(inputwidth,true);
-      unsigned t0_width = t[0].GetValueWidth();
-      unsigned t1_width = t[1].GetValueWidth();
-      CONSTANTBV::BitVector_Destroy(output);
-      
-      output = CONSTANTBV::BitVector_Concat(tmp0, tmp1);
-      outputwidth = t0_width + t1_width;
-      OutputNode = CreateBVConst(output, outputwidth);
-      
-      break;
-    }
-    case BVMULT: {
-       output = CONSTANTBV::BitVector_Create(inputwidth,true);
-      CBV tmp = CONSTANTBV::BitVector_Create(2*inputwidth,true);
-      CONSTANTBV::ErrCode e = CONSTANTBV::BitVector_Multiply(tmp,tmp0,tmp1);
-      
-      if(0 != e) {
-        BVConstEvaluatorError(e,t);
-      }
-      //FIXME WHAT IS MY OUTPUT???? THE SECOND HALF of tmp?
-      //CONSTANTBV::BitVector_Interval_Copy(output, tmp, 0, inputwidth, inputwidth);
-      CONSTANTBV::BitVector_Interval_Copy(output, tmp, 0, 0, inputwidth);
-      OutputNode = CreateBVConst(output, outputwidth);
-      CONSTANTBV::BitVector_Destroy(tmp);
-      break;
-    }
-    case BVPLUS: {
-       output = CONSTANTBV::BitVector_Create(inputwidth,true);
-      bool carry = false;
-      ASTVec c = t.GetChildren();
-      for(ASTVec::iterator it=c.begin(),itend=c.end();it!=itend;it++) {
-       CBV kk = BVConstEvaluator(*it).GetBVConst();
-       CONSTANTBV::BitVector_add(output,output,kk,&carry);
-       carry = false;
-       //CONSTANTBV::BitVector_Destroy(kk);
-      }
-      OutputNode = CreateBVConst(output, outputwidth);
-      break;
-    }
-    //FIXME ANOTHER SPECIAL CASE
-    case SBVDIV:
-    case SBVREM:{
-      OutputNode = BVConstEvaluator(TranslateSignedDivMod(t));
-      break;
-    }
-    case BVDIV: 
-    case BVMOD: {
-      CBV quotient = CONSTANTBV::BitVector_Create(inputwidth,true);
-      CBV remainder = CONSTANTBV::BitVector_Create(inputwidth,true);
-      
-      // tmp0 is dividend, tmp1 is the divisor
-      //All parameters to BitVector_Div_Pos must be distinct unlike BitVector_Divide
-      //FIXME the contents of the second parameter to Div_Pos is destroyed
-      //As tmp0 is currently the same as the copy belonging to an ASTNode t[0]
-      //this must be copied.
-      tmp0 = CONSTANTBV::BitVector_Clone(tmp0);      
-      CONSTANTBV::ErrCode e= CONSTANTBV::BitVector_Div_Pos(quotient,tmp0,tmp1,remainder);
-      CONSTANTBV::BitVector_Destroy(tmp0);
-      
-      if(0 != e) {
-       //error printing
-       if(counterexample_checking_during_refinement) {
-          output = CONSTANTBV::BitVector_Create(inputwidth,true);
-         OutputNode = CreateBVConst(output, outputwidth);
-         bvdiv_exception_occured = true;
-          
-          //  CONSTANTBV::BitVector_Destroy(output);
-         break;
+ASTNode BeevMgr::BVConstEvaluator(const ASTNode& t)
+{
+       ASTNode OutputNode;
+       Kind k = t.GetKind();
+
+       if (CheckSolverMap(t, OutputNode))
+               return OutputNode;
+       OutputNode = t;
+
+       unsigned int inputwidth = t.GetValueWidth();
+       unsigned int outputwidth = inputwidth;
+       CBV output = NULL;
+
+       CBV tmp0 = NULL;
+       CBV tmp1 = NULL;
+
+       //saving some typing. BVPLUS does not use these variables. if the
+       //input BVPLUS has two nodes, then we want to avoid setting these
+       //variables.
+       if (1 == t.Degree())
+       {
+               tmp0 = BVConstEvaluator(t[0]).GetBVConst();
        }
-       else {
-         BVConstEvaluatorError(e,t);
+       else if (2 == t.Degree() && k != BVPLUS)
+       {
+               tmp0 = BVConstEvaluator(t[0]).GetBVConst();
+               tmp1 = BVConstEvaluator(t[1]).GetBVConst();
        }
-      } //end of error printing
-
-      //FIXME Not very standard in the current scheme
-      if(BVDIV == k){
-        OutputNode = CreateBVConst(quotient, outputwidth);
-        CONSTANTBV::BitVector_Destroy(remainder);
-      }else{
-        OutputNode = CreateBVConst(remainder, outputwidth);
-        CONSTANTBV::BitVector_Destroy(quotient);
-      }
-
-      break;
-    }
-    case ITE:
-      if(ASTTrue == t[0])
-       OutputNode = BVConstEvaluator(t[1]);
-      else if(ASTFalse == t[0])
-       OutputNode = BVConstEvaluator(t[2]);
-      else
-       FatalError("BVConstEvaluator: ITE condiional must be either TRUE or FALSE:",t);
-      break;
-    case EQ: 
-      if(CONSTANTBV::BitVector_equal(tmp0,tmp1))
-       OutputNode = ASTTrue;
-      else
-       OutputNode = ASTFalse;
-      break;
-    case NEQ:
-      if(!CONSTANTBV::BitVector_equal(tmp0,tmp1))
-       OutputNode = ASTTrue;
-      else
-       OutputNode = ASTFalse;
-      break;
-    case BVLT:
-      if(-1 == CONSTANTBV::BitVector_Lexicompare(tmp0,tmp1))
-       OutputNode = ASTTrue;
-      else
-       OutputNode = ASTFalse;
-      break;
-    case BVLE: {
-      int comp = CONSTANTBV::BitVector_Lexicompare(tmp0,tmp1);
-      if(comp <= 0)
-       OutputNode = ASTTrue;
-      else
-       OutputNode = ASTFalse;
-      break;
-    }
-    case BVGT:
-      if(1 == CONSTANTBV::BitVector_Lexicompare(tmp0,tmp1))
-       OutputNode = ASTTrue;
-      else
-       OutputNode = ASTFalse;
-      break;
-    case BVGE: {
-      int comp = CONSTANTBV::BitVector_Lexicompare(tmp0,tmp1);
-      if(comp >= 0)
-       OutputNode = ASTTrue;
-      else
-       OutputNode = ASTFalse;
-      break;
-    } 
-    case BVSLT:
-      if(-1 == CONSTANTBV::BitVector_Compare(tmp0,tmp1))
-       OutputNode = ASTTrue;
-      else
-       OutputNode = ASTFalse;
-      break;
-    case BVSLE: {
-      signed int comp = CONSTANTBV::BitVector_Compare(tmp0,tmp1);
-      if(comp <= 0)
-       OutputNode = ASTTrue;
-      else
-       OutputNode = ASTFalse;
-      break;
-    }
-    case BVSGT:
-      if(1 == CONSTANTBV::BitVector_Compare(tmp0,tmp1))
-       OutputNode = ASTTrue;
-      else
-       OutputNode = ASTFalse;
-      break;
-    case BVSGE: {
-      int comp = CONSTANTBV::BitVector_Compare(tmp0,tmp1);
-      if(comp >= 0)
-       OutputNode = ASTTrue;
-      else
-       OutputNode = ASTFalse;
-      break;
-    } 
-    default:
-      FatalError("BVConstEvaluator: The input kind is not supported yet:",t);
-      break;
-    }
-/*
-    if(BVCONST != k){
-     cerr<<inputwidth<<endl;
-     cerr<<"------------------------"<<endl;
-     t.LispPrint(cerr);
-     cerr<<endl;
-     OutputNode.LispPrint(cerr);
-     cerr<<endl<<"------------------------"<<endl;
-    }
-*/
-    UpdateSolverMap(t,OutputNode);
-    //UpdateSimplifyMap(t,OutputNode,false);
-    return OutputNode;
-  }
-#else
-  //accepts 64 bit BVConst and sign extends it
-  static unsigned long long int SXBVConst64(const ASTNode& t) {
-    unsigned long long int c = t.GetBVConst();
-    unsigned int len = t.GetValueWidth();
-
-    unsigned long long int mask = 1;
-    mask = mask << len-1;
-
-    bool TopBit = (c & mask) ? true : false;
-    if(!TopBit) return c;
-    
-    unsigned long long int sign = 0xffffffffffffffffLL;
-    sign = sign << len-1;
-
-    return (c | sign);
-  }
-
-  //FIXME: Ideally I would like the ASTNodes to be able to operate on
-  //themselves (add, sub, concat, etc.) rather than doing a
-  //GetBVConst() and then do the operation externally. For now,
-  //this is the fastest path to completion.
-  ASTNode BeevMgr::BVConstEvaluator(const ASTNode& t) {
-    //cerr << "inside begin bcconstevaluator: " << t << endl;
-
-    ASTNode OutputNode;
-    if(CheckSolverMap(t,OutputNode))
-      return OutputNode;
-    OutputNode = ASTUndefined;
-
-    Kind k = t.GetKind();
-    unsigned long long int output = 0;
-    unsigned inputwidth = t.GetValueWidth();
-    ASTNode t0 = ASTUndefined;
-    ASTNode t1 = ASTUndefined;
-    if(2 == t.Degree()) {
-      t0 = BVConstEvaluator(t[0]);
-      t1 = BVConstEvaluator(t[1]);
-    }
-    switch(k) {
-    case READ:
-    case UNDEFINED:
-    case WRITE:
-    case SYMBOL:
-      cerr << t;
-      FatalError("BVConstEvaluator: term is not a constant-term",t);
-      break;
-    case BVCONST:
-      return t;
-      break;
-    case BVNEG:
-      //compute bitwise negation in C
-      output = ~(BVConstEvaluator(t[0]).GetBVConst());
-      break;
-    case BVSX:
-      output = SXBVConst64(BVConstEvaluator(t[0]));    
-      break;
-    case BVAND:
-      output = t0.GetBVConst() & t1.GetBVConst();
-      break;
-    case BVOR:
-      output = t0.GetBVConst() | t1.GetBVConst();
-      break;
-    case BVXOR:
-      output = t0.GetBVConst() ^ t1.GetBVConst();
-      break;
-    case BVSUB:
-      output = t0.GetBVConst() - t1.GetBVConst();
-      break;
-    case BVUMINUS:
-      output = ~(BVConstEvaluator(t[0]).GetBVConst()) + 1;
-      break;
-    case BVEXTRACT: {
-      unsigned long long int val = BVConstEvaluator(t[0]).GetBVConst();
-      unsigned int hi = GetUnsignedConst(BVConstEvaluator(t[1]));
-      unsigned int low = GetUnsignedConst(BVConstEvaluator(t[2]));
-
-      if(!(0 <= hi <= 64))
-       FatalError("ConstantEvaluator: hi bit in BVEXTRACT is > 32bits",t);
-      if(!(0 <= low <= hi <= 64))
-       FatalError("ConstantEvaluator: low bit in BVEXTRACT is > 32bits or hi",t);
-
-      //64 bit mask.
-      unsigned long long int mask1 = 0xffffffffffffffffLL;
-      mask1 >>= 64-(hi+1);
-      
-      //extract val[hi:0]
-      val &= mask1;
-      //extract val[hi:low]
-      val >>= low;
-      output = val;
-      break;
-    }
-    case BVCONCAT: {
-      unsigned long long int q = BVConstEvaluator(t0).GetBVConst();
-      unsigned long long int r = BVConstEvaluator(t1).GetBVConst();
-
-      unsigned int qlen = t[0].GetValueWidth();
-      unsigned int rlen = t[1].GetValueWidth();
-      unsigned int slen = t.GetValueWidth();
-      if(!(0 <  qlen + rlen  <= 64))
-       FatalError("BVConstEvaluator:"
-                  "lengths of childnodes of BVCONCAT are > 64:",t);
-
-      //64 bit mask for q
-      unsigned long long int qmask = 0xffffffffffffffffLL;     
-      qmask >>= 64-qlen;
-      //zero the useless bits of q
-      q &= qmask;
-
-      //64 bit mask for r
-      unsigned long long int rmask = 0xffffffffffffffffLL;     
-      rmask >>= 64-rlen;
-      //zero the useless bits of r
-      r &= rmask;
-      
-      //concatenate
-      q <<= rlen;
-      q |= r;
-
-      //64 bit mask for output s
-      unsigned long long int smask = 0xffffffffffffffffLL;
-      smask >>= 64-slen;
-      
-      //currently q has the output
-      output = q;      
-      output &= smask;
-      break;
-    }
-    case BVMULT: {
-      output = t0.GetBVConst() * t1.GetBVConst();
-
-      //64 bit mask
-      unsigned long long int mask = 0xffffffffffffffffLL;
-      mask = mask >> (64 - inputwidth);
-      output &= mask;
-      break;
-    }
-    case BVPLUS: {
-      ASTVec c = t.GetChildren();
-      for(ASTVec::iterator it=c.begin(),itend=c.end();it!=itend;it++)
-       output += BVConstEvaluator(*it).GetBVConst();
-
-      //64 bit mask
-      unsigned long long int mask = 0xffffffffffffffffLL;
-      mask = mask >> (64 -inputwidth);
-      output &= mask;
-      break;
-    }
-    case SBVDIV:
-    case SBVREM: {
-      output = BVConstEvaluator(TranslateSignedDivMod(t)).GetBVConst();
-      break;
-    }
-    case BVDIV: {
-      if(0 == t1.GetBVConst()) {
-       //if denominator is 0 then 
-       //  (if refinement is ON then output is set to 0) 
-       //   (else produce a fatal error)
-       if(counterexample_checking_during_refinement) {
-         output = 0;
-         bvdiv_exception_occured = true;
-         break;
-       }
-       else {
-         FatalError("BVConstEvaluator: divide by zero not allowed:",t);
+
+       switch (k)
+       {
+               case UNDEFINED:
+               case READ:
+               case WRITE:
+               case SYMBOL:
+                       FatalError("BVConstEvaluator: term is not a constant-term", t);
+                       break;
+               case BVCONST:
+                       //FIXME Handle this special case better
+                       OutputNode = t;
+                       break;
+               case BVNEG:
+               {
+                       output = CONSTANTBV::BitVector_Create(inputwidth, true);
+                       CONSTANTBV::Set_Complement(output, tmp0);
+                       OutputNode = CreateBVConst(output, outputwidth);
+                       break;
+               }
+               case BVSX:
+               {
+                       output = CONSTANTBV::BitVector_Create(inputwidth, true);
+                       //unsigned * out0 = BVConstEvaluator(t[0]).GetBVConst();
+                       unsigned t0_width = t[0].GetValueWidth();
+                       if (inputwidth == t0_width)
+                       {
+                               CONSTANTBV::BitVector_Copy(output, tmp0);
+                               OutputNode = CreateBVConst(output, outputwidth);
+                       }
+                       else
+                       {
+                               bool topbit_sign = (CONSTANTBV::BitVector_Sign(tmp0) < 0);
+
+                               if (topbit_sign)
+                               {
+                                       CONSTANTBV::BitVector_Fill(output);
+                               }
+                               CONSTANTBV::BitVector_Interval_Copy(output, tmp0, 0, 0, t0_width);
+                               OutputNode = CreateBVConst(output, outputwidth);
+                       }
+                       break;
+               }
+
+               case BVZX:
+               {
+                       output = CONSTANTBV::BitVector_Create(inputwidth, true);
+                       unsigned t0_width = t[0].GetValueWidth();
+                       if (inputwidth == t0_width)
+                       {
+                               CONSTANTBV::BitVector_Copy(output, tmp0);
+                               OutputNode = CreateBVConst(output, outputwidth);
+                       }
+                       else
+                       {
+                               CONSTANTBV::BitVector_Interval_Copy(output, tmp0, 0, 0, t0_width);
+                               OutputNode = CreateBVConst(output, outputwidth);
+                       }
+                       break;
+               }
+
+               case BVLEFTSHIFT:
+               {
+                       output = CONSTANTBV::BitVector_Create(inputwidth, true);
+
+                       // the shift is destructive, get a copy.
+                       CONSTANTBV::BitVector_Interval_Copy(output, tmp0, 0, 0, inputwidth);
+
+                       // get the number of bits to shift it.
+                       unsigned int shift = GetUnsignedConst(BVConstEvaluator(t[1]));
+
+                       CONSTANTBV::BitVector_Move_Left(output, shift);
+                       OutputNode = CreateBVConst(output, outputwidth);
+                       break;
+               }
+               case BVRIGHTSHIFT:
+               {
+                       output = CONSTANTBV::BitVector_Create(inputwidth, true);
+
+                       // the shift is destructive, get a copy.
+                       CONSTANTBV::BitVector_Interval_Copy(output, tmp0, 0, 0, inputwidth);
+
+                       // get the number of bits to shift it.
+                       unsigned int shift = GetUnsignedConst(BVConstEvaluator(t[1]));
+
+                       CONSTANTBV::BitVector_Move_Right(output, shift);
+                       OutputNode = CreateBVConst(output, outputwidth);
+                       break;
+               }
+
+               case BVAND:
+               {
+                       output = CONSTANTBV::BitVector_Create(inputwidth, true);
+                       CONSTANTBV::Set_Intersection(output, tmp0, tmp1);
+                       OutputNode = CreateBVConst(output, outputwidth);
+                       break;
+               }
+               case BVOR:
+               {
+                       output = CONSTANTBV::BitVector_Create(inputwidth, true);
+                       CONSTANTBV::Set_Union(output, tmp0, tmp1);
+                       OutputNode = CreateBVConst(output, outputwidth);
+                       break;
+               }
+               case BVXOR:
+               {
+                       output = CONSTANTBV::BitVector_Create(inputwidth, true);
+                       CONSTANTBV::Set_ExclusiveOr(output, tmp0, tmp1);
+                       OutputNode = CreateBVConst(output, outputwidth);
+                       break;
+               }
+               case BVSUB:
+               {
+                       output = CONSTANTBV::BitVector_Create(inputwidth, true);
+                       bool carry = false;
+                       CONSTANTBV::BitVector_sub(output, tmp0, tmp1, &carry);
+                       OutputNode = CreateBVConst(output, outputwidth);
+                       break;
+               }
+               case BVUMINUS:
+               {
+                       output = CONSTANTBV::BitVector_Create(inputwidth, true);
+                       CONSTANTBV::BitVector_Negate(output, tmp0);
+                       OutputNode = CreateBVConst(output, outputwidth);
+                       break;
+               }
+               case BVEXTRACT:
+               {
+                       output = CONSTANTBV::BitVector_Create(inputwidth, true);
+                       tmp0 = BVConstEvaluator(t[0]).GetBVConst();
+                       unsigned int hi = GetUnsignedConst(BVConstEvaluator(t[1]));
+                       unsigned int low = GetUnsignedConst(BVConstEvaluator(t[2]));
+                       unsigned int len = hi - low + 1;
+
+                       CONSTANTBV::BitVector_Destroy(output);
+                       output = CONSTANTBV::BitVector_Create(len, false);
+                       CONSTANTBV::BitVector_Interval_Copy(output, tmp0, 0, low, len);
+                       outputwidth = len;
+                       OutputNode = CreateBVConst(output, outputwidth);
+                       break;
+               }
+                       //FIXME Only 2 inputs?
+               case BVCONCAT:
+               {
+                       output = CONSTANTBV::BitVector_Create(inputwidth, true);
+                       unsigned t0_width = t[0].GetValueWidth();
+                       unsigned t1_width = t[1].GetValueWidth();
+                       CONSTANTBV::BitVector_Destroy(output);
+
+                       output = CONSTANTBV::BitVector_Concat(tmp0, tmp1);
+                       outputwidth = t0_width + t1_width;
+                       OutputNode = CreateBVConst(output, outputwidth);
+
+                       break;
+               }
+               case BVMULT:
+               {
+                       output = CONSTANTBV::BitVector_Create(inputwidth, true);
+                       CBV tmp = CONSTANTBV::BitVector_Create(2* inputwidth , true);
+                       CONSTANTBV::ErrCode e = CONSTANTBV::BitVector_Multiply(tmp, tmp0, tmp1);
+
+                       if (0 != e)
+                       {
+                               BVConstEvaluatorError(e, t);
+                       }
+                       //FIXME WHAT IS MY OUTPUT???? THE SECOND HALF of tmp?
+                       //CONSTANTBV::BitVector_Interval_Copy(output, tmp, 0, inputwidth, inputwidth);
+                       CONSTANTBV::BitVector_Interval_Copy(output, tmp, 0, 0, inputwidth);
+                       OutputNode = CreateBVConst(output, outputwidth);
+                       CONSTANTBV::BitVector_Destroy(tmp);
+                       break;
+               }
+               case BVPLUS:
+               {
+                       output = CONSTANTBV::BitVector_Create(inputwidth, true);
+                       bool carry = false;
+                       ASTVec c = t.GetChildren();
+                       for (ASTVec::iterator it = c.begin(), itend = c.end(); it != itend; it++)
+                       {
+                               CBV kk = BVConstEvaluator(*it).GetBVConst();
+                               CONSTANTBV::BitVector_add(output, output, kk, &carry);
+                               carry = false;
+                               //CONSTANTBV::BitVector_Destroy(kk);
+                       }
+                       OutputNode = CreateBVConst(output, outputwidth);
+                       break;
+               }
+                       //FIXME ANOTHER SPECIAL CASE
+               case SBVDIV:
+               case SBVREM:
+               {
+                       OutputNode = BVConstEvaluator(TranslateSignedDivMod(t));
+                       break;
+               }
+               case BVDIV:
+               case BVMOD:
+               {
+                       CBV quotient = CONSTANTBV::BitVector_Create(inputwidth, true);
+                       CBV remainder = CONSTANTBV::BitVector_Create(inputwidth, true);
+
+                       // tmp0 is dividend, tmp1 is the divisor
+                       //All parameters to BitVector_Div_Pos must be distinct unlike BitVector_Divide
+                       //FIXME the contents of the second parameter to Div_Pos is destroyed
+                       //As tmp0 is currently the same as the copy belonging to an ASTNode t[0]
+                       //this must be copied.
+                       tmp0 = CONSTANTBV::BitVector_Clone(tmp0);
+                       CONSTANTBV::ErrCode e = CONSTANTBV::BitVector_Div_Pos(quotient, tmp0, tmp1, remainder);
+                       CONSTANTBV::BitVector_Destroy(tmp0);
+
+                       if (0 != e)
+                       {
+                               //error printing
+                               if (counterexample_checking_during_refinement)
+                               {
+                                       output = CONSTANTBV::BitVector_Create(inputwidth, true);
+                                       OutputNode = CreateBVConst(output, outputwidth);
+                                       bvdiv_exception_occured = true;
+
+                                       //  CONSTANTBV::BitVector_Destroy(output);
+                                       break;
+                               }
+                               else
+                               {
+                                       BVConstEvaluatorError(e, t);
+                               }
+                       } //end of error printing
+
+                       //FIXME Not very standard in the current scheme
+                       if (BVDIV == k)
+                       {
+                               OutputNode = CreateBVConst(quotient, outputwidth);
+                               CONSTANTBV::BitVector_Destroy(remainder);
+                       }
+                       else
+                       {
+                               OutputNode = CreateBVConst(remainder, outputwidth);
+                               CONSTANTBV::BitVector_Destroy(quotient);
+                       }
+
+                       break;
+               }
+               case ITE:
+                       if (ASTTrue == t[0])
+                               OutputNode = BVConstEvaluator(t[1]);
+                       else if (ASTFalse == t[0])
+                               OutputNode = BVConstEvaluator(t[2]);
+                       else
+                               FatalError("BVConstEvaluator: ITE condiional must be either TRUE or FALSE:", t);
+                       break;
+               case EQ:
+                       if (CONSTANTBV::BitVector_equal(tmp0, tmp1))
+                               OutputNode = ASTTrue;
+                       else
+                               OutputNode = ASTFalse;
+                       break;
+               case NEQ:
+                       if (!CONSTANTBV::BitVector_equal(tmp0, tmp1))
+                               OutputNode = ASTTrue;
+                       else
+                               OutputNode = ASTFalse;
+                       break;
+               case BVLT:
+                       if (-1 == CONSTANTBV::BitVector_Lexicompare(tmp0, tmp1))
+                               OutputNode = ASTTrue;
+                       else
+                               OutputNode = ASTFalse;
+                       break;
+               case BVLE:
+               {
+                       int comp = CONSTANTBV::BitVector_Lexicompare(tmp0, tmp1);
+                       if (comp <= 0)
+                               OutputNode = ASTTrue;
+                       else
+                               OutputNode = ASTFalse;
+                       break;
+               }
+               case BVGT:
+                       if (1 == CONSTANTBV::BitVector_Lexicompare(tmp0, tmp1))
+                               OutputNode = ASTTrue;
+                       else
+                               OutputNode = ASTFalse;
+                       break;
+               case BVGE:
+               {
+                       int comp = CONSTANTBV::BitVector_Lexicompare(tmp0, tmp1);
+                       if (comp >= 0)
+                               OutputNode = ASTTrue;
+                       else
+                               OutputNode = ASTFalse;
+                       break;
+               }
+               case BVSLT:
+                       if (-1 == CONSTANTBV::BitVector_Compare(tmp0, tmp1))
+                               OutputNode = ASTTrue;
+                       else
+                               OutputNode = ASTFalse;
+                       break;
+               case BVSLE:
+               {
+                       signed int comp = CONSTANTBV::BitVector_Compare(tmp0, tmp1);
+                       if (comp <= 0)
+                               OutputNode = ASTTrue;
+                       else
+                               OutputNode = ASTFalse;
+                       break;
+               }
+               case BVSGT:
+                       if (1 == CONSTANTBV::BitVector_Compare(tmp0, tmp1))
+                               OutputNode = ASTTrue;
+                       else
+                               OutputNode = ASTFalse;
+                       break;
+               case BVSGE:
+               {
+                       int comp = CONSTANTBV::BitVector_Compare(tmp0, tmp1);
+                       if (comp >= 0)
+                               OutputNode = ASTTrue;
+                       else
+                               OutputNode = ASTFalse;
+                       break;
+               }
+               default:
+                       FatalError("BVConstEvaluator: The input kind is not supported yet:", t);
+                       break;
        }
-      }
-
-      output = t0.GetBVConst() / t1.GetBVConst();
-      //64 bit mask
-      unsigned long long int mask = 0xffffffffffffffffLL;
-      mask = mask >> (64 - inputwidth);
-      output &= mask;
-      break;
-    }
-    case BVMOD: {
-      if(0 == t1.GetBVConst()) {
-       //if denominator is 0 then 
-       //  (if refinement is ON then output is set to 0) 
-       //   (else produce a fatal error)
-       if(counterexample_checking_during_refinement) {
-         output = 0;
-         bvdiv_exception_occured = true;
-         break;
+       /*
+        if(BVCONST != k){
+        cerr<<inputwidth<<endl;
+        cerr<<"------------------------"<<endl;
+        t.LispPrint(cerr);
+        cerr<<endl;
+        OutputNode.LispPrint(cerr);
+        cerr<<endl<<"------------------------"<<endl;
+        }
+        */
+       UpdateSolverMap(t, OutputNode);
+       //UpdateSimplifyMap(t,OutputNode,false);
+       return OutputNode;
+}
+#else
+//accepts 64 bit BVConst and sign extends it
+static unsigned long long int SXBVConst64(const ASTNode& t)
+{
+       unsigned long long int c = t.GetBVConst();
+       unsigned int len = t.GetValueWidth();
+
+       unsigned long long int mask = 1;
+       mask = mask << len-1;
+
+       bool TopBit = (c & mask) ? true : false;
+       if(!TopBit) return c;
+
+       unsigned long long int sign = 0xffffffffffffffffLL;
+       sign = sign << len-1;
+
+       return (c | sign);
+}
+
+//FIXME: Ideally I would like the ASTNodes to be able to operate on
+//themselves (add, sub, concat, etc.) rather than doing a
+//GetBVConst() and then do the operation externally. For now,
+//this is the fastest path to completion.
+ASTNode BeevMgr::BVConstEvaluator(const ASTNode& t)
+{
+       //cerr << "inside begin bcconstevaluator: " << t << endl;
+
+       ASTNode OutputNode;
+       if(CheckSolverMap(t,OutputNode))
+       return OutputNode;
+       OutputNode = ASTUndefined;
+
+       Kind k = t.GetKind();
+       unsigned long long int output = 0;
+       unsigned inputwidth = t.GetValueWidth();
+       ASTNode t0 = ASTUndefined;
+       ASTNode t1 = ASTUndefined;
+       if(2 == t.Degree())
+       {
+               t0 = BVConstEvaluator(t[0]);
+               t1 = BVConstEvaluator(t[1]);
        }
-       else {
-         FatalError("BVConstEvaluator: divide by zero not allowed:",t);
+       switch(k)
+       {
+               case READ:
+               case UNDEFINED:
+               case WRITE:
+               case SYMBOL:
+               cerr << t;
+               FatalError("BVConstEvaluator: term is not a constant-term",t);
+               break;
+               case BVCONST:
+               return t;
+               break;
+               case BVNEG:
+               //compute bitwise negation in C
+               output = ~(BVConstEvaluator(t[0]).GetBVConst());
+               break;
+               case BVSX:
+               output = SXBVConst64(BVConstEvaluator(t[0]));
+               break;
+               case BVAND:
+               output = t0.GetBVConst() & t1.GetBVConst();
+               break;
+               case BVOR:
+               output = t0.GetBVConst() | t1.GetBVConst();
+               break;
+               case BVXOR:
+               output = t0.GetBVConst() ^ t1.GetBVConst();
+               break;
+               case BVSUB:
+               output = t0.GetBVConst() - t1.GetBVConst();
+               break;
+               case BVUMINUS:
+               output = ~(BVConstEvaluator(t[0]).GetBVConst()) + 1;
+               break;
+               case BVEXTRACT:
+               {
+                       unsigned long long int val = BVConstEvaluator(t[0]).GetBVConst();
+                       unsigned int hi = GetUnsignedConst(BVConstEvaluator(t[1]));
+                       unsigned int low = GetUnsignedConst(BVConstEvaluator(t[2]));
+
+                       if(!(0 <= hi <= 64))
+                       FatalError("ConstantEvaluator: hi bit in BVEXTRACT is > 32bits",t);
+                       if(!(0 <= low <= hi <= 64))
+                       FatalError("ConstantEvaluator: low bit in BVEXTRACT is > 32bits or hi",t);
+
+                       //64 bit mask.
+                       unsigned long long int mask1 = 0xffffffffffffffffLL;
+                       mask1 >>= 64-(hi+1);
+
+                       //extract val[hi:0]
+                       val &= mask1;
+                       //extract val[hi:low]
+                       val >>= low;
+                       output = val;
+                       break;
+               }
+               case BVCONCAT:
+               {
+                       unsigned long long int q = BVConstEvaluator(t0).GetBVConst();
+                       unsigned long long int r = BVConstEvaluator(t1).GetBVConst();
+
+                       unsigned int qlen = t[0].GetValueWidth();
+                       unsigned int rlen = t[1].GetValueWidth();
+                       unsigned int slen = t.GetValueWidth();
+                       if(!(0 < qlen + rlen <= 64))
+                       FatalError("BVConstEvaluator:"
+                                       "lengths of childnodes of BVCONCAT are > 64:",t);
+
+                       //64 bit mask for q
+                       unsigned long long int qmask = 0xffffffffffffffffLL;
+                       qmask >>= 64-qlen;
+                       //zero the useless bits of q
+                       q &= qmask;
+
+                       //64 bit mask for r
+                       unsigned long long int rmask = 0xffffffffffffffffLL;
+                       rmask >>= 64-rlen;
+                       //zero the useless bits of r
+                       r &= rmask;
+
+                       //concatenate
+                       q <<= rlen;
+                       q |= r;
+
+                       //64 bit mask for output s
+                       unsigned long long int smask = 0xffffffffffffffffLL;
+                       smask >>= 64-slen;
+
+                       //currently q has the output
+                       output = q;
+                       output &= smask;
+                       break;
+               }
+               case BVMULT:
+               {
+                       output = t0.GetBVConst() * t1.GetBVConst();
+
+                       //64 bit mask
+                       unsigned long long int mask = 0xffffffffffffffffLL;
+                       mask = mask >> (64 - inputwidth);
+                       output &= mask;
+                       break;
+               }
+               case BVPLUS:
+               {
+                       ASTVec c = t.GetChildren();
+                       for(ASTVec::iterator it=c.begin(),itend=c.end();it!=itend;it++)
+                       output += BVConstEvaluator(*it).GetBVConst();
+
+                       //64 bit mask
+                       unsigned long long int mask = 0xffffffffffffffffLL;
+                       mask = mask >> (64 -inputwidth);
+                       output &= mask;
+                       break;
+               }
+               case SBVDIV:
+               case SBVREM:
+               {
+                       output = BVConstEvaluator(TranslateSignedDivMod(t)).GetBVConst();
+                       break;
+               }
+               case BVDIV:
+               {
+                       if(0 == t1.GetBVConst())
+                       {
+                               //if denominator is 0 then
+                               //  (if refinement is ON then output is set to 0)
+                               //   (else produce a fatal error)
+                               if(counterexample_checking_during_refinement)
+                               {
+                                       output = 0;
+                                       bvdiv_exception_occured = true;
+                                       break;
+                               }
+                               else
+                               {
+                                       FatalError("BVConstEvaluator: divide by zero not allowed:",t);
+                               }
+                       }
+
+                       output = t0.GetBVConst() / t1.GetBVConst();
+                       //64 bit mask
+                       unsigned long long int mask = 0xffffffffffffffffLL;
+                       mask = mask >> (64 - inputwidth);
+                       output &= mask;
+                       break;
+               }
+               case BVMOD:
+               {
+                       if(0 == t1.GetBVConst())
+                       {
+                               //if denominator is 0 then
+                               //  (if refinement is ON then output is set to 0)
+                               //   (else produce a fatal error)
+                               if(counterexample_checking_during_refinement)
+                               {
+                                       output = 0;
+                                       bvdiv_exception_occured = true;
+                                       break;
+                               }
+                               else
+                               {
+                                       FatalError("BVConstEvaluator: divide by zero not allowed:",t);
+                               }
+                       }
+
+                       output = t0.GetBVConst() % t1.GetBVConst();
+                       //64 bit mask
+                       unsigned long long int mask = 0xffffffffffffffffLL;
+                       mask = mask >> (64 - inputwidth);
+                       output &= mask;
+                       break;
+               }
+               case ITE:
+               if(ASTTrue == t[0])
+               OutputNode = BVConstEvaluator(t[1]);
+               else if(ASTFalse == t[0])
+               OutputNode = BVConstEvaluator(t[2]);
+               else
+               FatalError("BVConstEvaluator:"
+                               "ITE condiional must be either TRUE or FALSE:",t);
+               break;
+               case EQ:
+               if(t0.GetBVConst() == t1.GetBVConst())
+               OutputNode = ASTTrue;
+               else
+               OutputNode = ASTFalse;
+               break;
+               case NEQ:
+               if(t0.GetBVConst() != t1.GetBVConst())
+               OutputNode = ASTTrue;
+               else
+               OutputNode = ASTFalse;
+               break;
+               break;
+               case BVLT:
+               {
+                       unsigned long long n0 = t0.GetBVConst();
+                       unsigned long long n1 = t1.GetBVConst();
+                       if(n0 < n1)
+                       OutputNode = ASTTrue;
+                       else
+                       OutputNode = ASTFalse;
+                       break;
+               }
+               case BVLE:
+               if(t0.GetBVConst() <= t1.GetBVConst())
+               OutputNode = ASTTrue;
+               else
+               OutputNode = ASTFalse;
+               break;
+               case BVGT:
+               if(t0.GetBVConst() > t1.GetBVConst())
+               OutputNode = ASTTrue;
+               else
+               OutputNode = ASTFalse;
+               break;
+               case BVGE:
+               if(t0.GetBVConst() >= t1.GetBVConst())
+               OutputNode = ASTTrue;
+               else
+               OutputNode = ASTFalse;
+               break;
+               case BVSLT:
+               {
+                       signed long long int n0 = SXBVConst64(t0);
+                       signed long long int n1 = SXBVConst64(t1);
+                       if(n0 < n1)
+                       OutputNode = ASTTrue;
+                       else
+                       OutputNode = ASTFalse;
+                       break;
+               }
+               case BVSLE:
+               {
+                       signed long long int n0 = SXBVConst64(t0);
+                       signed long long int n1 = SXBVConst64(t1);
+                       if(n0 <= n1)
+                       OutputNode = ASTTrue;
+                       else
+                       OutputNode = ASTFalse;
+                       break;
+               }
+               case BVSGT:
+               {
+                       signed long long int n0 = SXBVConst64(t0);
+                       signed long long int n1 = SXBVConst64(t1);
+                       if(n0 > n1)
+                       OutputNode = ASTTrue;
+                       else
+                       OutputNode = ASTFalse;
+                       break;
+               }
+               case BVSGE:
+               {
+                       signed long long int n0 = SXBVConst64(t0);
+                       signed long long int n1 = SXBVConst64(t1);
+                       if(n0 >= n1)
+                       OutputNode = ASTTrue;
+                       else
+                       OutputNode = ASTFalse;
+                       break;
+               }
+               default:
+               FatalError("BVConstEvaluator: The input kind is not supported yet:",t);
+               break;
        }
-      }
-
-      output = t0.GetBVConst() % t1.GetBVConst();
-      //64 bit mask
-      unsigned long long int mask = 0xffffffffffffffffLL;
-      mask = mask >> (64 - inputwidth);
-      output &= mask;
-      break;
-    }
-    case ITE:
-      if(ASTTrue == t[0])
-       OutputNode = BVConstEvaluator(t[1]);
-      else if(ASTFalse == t[0])
-       OutputNode = BVConstEvaluator(t[2]);
-      else
-       FatalError("BVConstEvaluator:" 
-                  "ITE condiional must be either TRUE or FALSE:",t);
-      break;
-    case EQ:
-      if(t0.GetBVConst() == t1.GetBVConst())
-       OutputNode = ASTTrue;
-      else
-       OutputNode = ASTFalse;
-      break;
-    case NEQ:
-      if(t0.GetBVConst() != t1.GetBVConst())
-       OutputNode = ASTTrue;
-      else
-       OutputNode = ASTFalse;
-      break;
-      break;
-    case BVLT: {
-      unsigned long long n0 = t0.GetBVConst();
-      unsigned long long n1 = t1.GetBVConst();
-      if(n0 < n1)
-       OutputNode = ASTTrue;
-      else
-       OutputNode = ASTFalse;
-      break;
-    }
-    case BVLE:
-      if(t0.GetBVConst() <= t1.GetBVConst())
-       OutputNode = ASTTrue;
-      else
-       OutputNode = ASTFalse;
-      break;
-    case BVGT:
-      if(t0.GetBVConst() > t1.GetBVConst())
-       OutputNode = ASTTrue;
-      else
-       OutputNode = ASTFalse;
-      break;
-    case BVGE:
-      if(t0.GetBVConst() >= t1.GetBVConst())
-       OutputNode = ASTTrue;
-      else
-       OutputNode = ASTFalse;
-      break;
-    case BVSLT: {
-      signed long long int n0 = SXBVConst64(t0);
-      signed long long int n1 = SXBVConst64(t1);
-      if(n0 < n1)
-       OutputNode = ASTTrue;
-      else
-       OutputNode = ASTFalse;
-      break;
-    }
-    case BVSLE: {
-      signed long long int n0 = SXBVConst64(t0);
-      signed long long int n1 = SXBVConst64(t1);
-      if(n0 <= n1)
-       OutputNode = ASTTrue;
-      else
-       OutputNode = ASTFalse;
-      break;
-    }
-    case BVSGT: {   
-      signed long long int n0 = SXBVConst64(t0);
-      signed long long int n1 = SXBVConst64(t1);
-      if(n0 > n1)
-       OutputNode = ASTTrue;
-      else
-       OutputNode = ASTFalse;
-      break;
-    }
-    case BVSGE: {   
-      signed long long int n0 = SXBVConst64(t0);
-      signed long long int n1 = SXBVConst64(t1);
-      if(n0 >= n1)
-       OutputNode = ASTTrue;
-      else
-       OutputNode = ASTFalse;
-      break;
-    }
-    default:
-      FatalError("BVConstEvaluator: The input kind is not supported yet:",t);
-      break;
-    }    
-   
-    if(ASTTrue  != OutputNode && ASTFalse != OutputNode)
-      OutputNode = CreateBVConst(inputwidth, output);
-    UpdateSolverMap(t,OutputNode);
-    //UpdateSimplifyMap(t,OutputNode,false);
-    return OutputNode;
-  } //End of BVConstEvaluator
+
+       if(ASTTrue != OutputNode && ASTFalse != OutputNode)
+       OutputNode = CreateBVConst(inputwidth, output);
+       UpdateSolverMap(t,OutputNode);
+       //UpdateSimplifyMap(t,OutputNode,false);
+       return OutputNode;
+} //End of BVConstEvaluator
 #endif
 //In the block below is the old string based version
 //It is included here as an easy reference while the current code is being worked on.
 
 /*
-  ASTNode BeevMgr::BVConstEvaluator(const ASTNode& t) {
-    ASTNode OutputNode;
-    Kind k = t.GetKind();
-
-    if(CheckSolverMap(t,OutputNode))
-      return OutputNode;
-    OutputNode = t;
-
-    unsigned int inputwidth = t.GetValueWidth();
-    unsigned * output = CONSTANTBV::BitVector_Create(inputwidth,true);
-    unsigned * One = CONSTANTBV::BitVector_Create(inputwidth,true);
-    CONSTANTBV::ErrCode e = CONSTANTBV::BitVector_from_Bin(One, (unsigned char*)"1");
-    //error printing
-    if(0 != e) {
-      std::string ss("BVConstEvaluator:");
-      ss += (const char*)BitVector_Error(e);   
-      FatalError(ss.c_str(), t);
-    }
-
-    unsigned * Zero = CONSTANTBV::BitVector_Create(inputwidth,true);
-    unsigned int * iii = One;
-    unsigned int * jjj = Zero;
-
-    //saving some typing. BVPLUS does not use these variables. if the
-    //input BVPLUS has two nodes, then we want to avoid setting these
-    //variables.
-    if(2 == t.Degree() && k != BVPLUS && k != BVCONCAT) {
-      iii = ConvertToCONSTANTBV(BVConstEvaluator(t[0]).GetBVConst());
-      jjj = ConvertToCONSTANTBV(BVConstEvaluator(t[1]).GetBVConst());
-    }
-
-    char * cccc;
-    switch(k) {
-    case UNDEFINED:
-    case READ:
-    case WRITE:
-    case SYMBOL:
-      FatalError("BVConstEvaluator: term is not a constant-term",t);
-      break;
-    case BVCONST:
-      OutputNode = t;
-      break;
-    case BVNEG:{
-      //AARON
-      if (iii != One) free(iii);
-      //AARON
-
-      iii = ConvertToCONSTANTBV(BVConstEvaluator(t[0]).GetBVConst());     
-      CONSTANTBV::Set_Complement(output,iii);
-      cccc = (char *)CONSTANTBV::BitVector_to_Bin(output);
-      OutputNode = CreateBVConst(cccc,2);
-      break;
-    }
-    case BVSX: {
-      unsigned * out0 = ConvertToCONSTANTBV(BVConstEvaluator(t[0]).GetBVConst());
-      unsigned t0_width = t[0].GetValueWidth();
-      if(inputwidth == t0_width) {
-       cccc = (char *)CONSTANTBV::BitVector_to_Bin(out0);
-       OutputNode = CreateBVConst(cccc,2);
-
-       //AARON
-       free(cccc);
-       //AARON
-
-       CONSTANTBV::BitVector_Destroy(out0);     
-      }
-      else {
-       // FIXME: (Dill) I'm guessing that BitVector sign returns 1 if the
-       // number is positive, 0 if 0, and -1 if negative.  But I'm only
-       // guessing.
-       signed int topbit_sign = (CONSTANTBV::BitVector_Sign(out0) < 0);
-       //out1 is the sign-extension bits
-       unsigned * out1 =  CONSTANTBV::BitVector_Create(inputwidth-t0_width,true);      
-       if(topbit_sign)
-         CONSTANTBV::BitVector_Fill(out1);
-
-       //AARON
-       CONSTANTBV::BitVector_Destroy(output);
-       //AARON
-
-       output = CONSTANTBV::BitVector_Concat(out1,out0);
-       cccc = (char *)CONSTANTBV::BitVector_to_Bin(output);
-       OutputNode = CreateBVConst(cccc,2);
-
-       //AARON
-       free(cccc);
-       //AARON
-
-       CONSTANTBV::BitVector_Destroy(out0);
-       CONSTANTBV::BitVector_Destroy(out1);
-      }
-      break;
-    }
-    case BVAND: {
-      CONSTANTBV::Set_Intersection(output,iii,jjj);
-      cccc = (char *)CONSTANTBV::BitVector_to_Bin(output);
-      OutputNode = CreateBVConst(cccc,2);
-
-      //AARON
-      free(cccc);
-      //AARON
-      
-      break;
-    }
-    case BVOR: {
-      CONSTANTBV::Set_Union(output,iii,jjj);
-      cccc = (char *)CONSTANTBV::BitVector_to_Bin(output);
-      OutputNode = CreateBVConst(cccc,2);
-
-      //AARON
-      free(cccc);
-      //AARON
-
-      break;
-    }
-    case BVXOR: {
-      CONSTANTBV::Set_ExclusiveOr(output,iii,jjj);
-      cccc = (char *)CONSTANTBV::BitVector_to_Bin(output);
-      OutputNode = CreateBVConst(cccc,2);
-
-      //AARON
-      free(cccc);
-      //AARON
-
-      break;
-    }
-    case BVSUB: {
-      bool carry = false;
-      CONSTANTBV::BitVector_sub(output,iii,jjj,&carry);
-      cccc = (char *)CONSTANTBV::BitVector_to_Bin(output);
-      OutputNode = CreateBVConst(cccc,2);
-
-      //AARON
-      free(cccc);
-      //AARON
-
-      break;
-    }
-    case BVUMINUS: {
-      bool carry = false;
-
-      //AARON
-      if (iii != One) free(iii);
-      //AARON
-
-      iii = ConvertToCONSTANTBV(BVConstEvaluator(t[0]).GetBVConst());
-      CONSTANTBV::Set_Complement(output,iii);
-      CONSTANTBV::BitVector_add(output,output,One,&carry);
-      cccc = (char *)CONSTANTBV::BitVector_to_Bin(output);
-      OutputNode = CreateBVConst(cccc,2);
-
-      //AARON
-      free(cccc);
-      //AARON
-
-      break;
-    }
-    case BVEXTRACT: {
-      string s(BVConstEvaluator(t[0]).GetBVConst());
-      unsigned int hi = GetUnsignedConst(BVConstEvaluator(t[1]));
-      unsigned int low = GetUnsignedConst(BVConstEvaluator(t[2]));
-
-      //length of substr to chop
-      unsigned int len = hi-low+1;
-      //distance from MSB
-      hi = s.size()-1 - hi;      
-      string ss = s.substr(hi,len);
-      OutputNode = CreateBVConst(ss.c_str(),2);
-      break;
-    }
-    case BVCONCAT: {
-      string s(BVConstEvaluator(t[0]).GetBVConst());
-      string r(BVConstEvaluator(t[1]).GetBVConst());
-  
-      string q(s+r);
-      OutputNode = CreateBVConst(q.c_str(),2);
-      break;
-    }
-    case BVMULT: {
-      unsigned * output1 = CONSTANTBV::BitVector_Create(2*inputwidth,true);
-      CONSTANTBV::ErrCode e = CONSTANTBV::BitVector_Multiply(output1,iii,jjj);
-      //error printing
-      if(0 != e) {
-       std::string ss("BVConstEvaluator:");
-       ss += (const char*)BitVector_Error(e);  
-       //destroy all the CONSTANTBV bitvectors
-       CONSTANTBV::BitVector_Destroy(iii);
-       CONSTANTBV::BitVector_Destroy(jjj);       
-       CONSTANTBV::BitVector_Destroy(One);
-       CONSTANTBV::BitVector_Destroy(Zero);
-       FatalError(ss.c_str(), t);
-      }
-
-      cccc = (char *)CONSTANTBV::BitVector_to_Bin(output1);
-      std::string s(cccc);
-
-      //AARON
-      free(cccc);
-      //AARON
-
-      s = s.substr(inputwidth,inputwidth);
-      OutputNode = CreateBVConst(s.c_str(),2);
-      CONSTANTBV::BitVector_Destroy(output1);
-      break;
-    }
-    case BVPLUS: {
-      bool carry = false;
-      ASTVec c = t.GetChildren();
-      for(ASTVec::iterator it=c.begin(),itend=c.end();it!=itend;it++) {
-       unsigned int * kk = ConvertToCONSTANTBV(BVConstEvaluator(*it).GetBVConst());
-       CONSTANTBV::BitVector_add(output,output,kk,&carry);
-       carry = false;
-       CONSTANTBV::BitVector_Destroy(kk);
-      }
-      cccc = (char *)CONSTANTBV::BitVector_to_Bin(output);
-      OutputNode = CreateBVConst(cccc,2);
-
-      //AARON
-      free(cccc);
-      //AARON
-
-      break;
-    }
-    case SBVDIV:
-    case SBVREM: {
-      OutputNode = BVConstEvaluator(TranslateSignedDivMod(t));
-      break;
-    }
-    case BVDIV: {      
-      unsigned * quotient = CONSTANTBV::BitVector_Create(inputwidth,true);
-      unsigned * remainder = CONSTANTBV::BitVector_Create(inputwidth,true);
-      // iii is dividend, jjj is the divisor
-      CONSTANTBV::ErrCode e = CONSTANTBV::BitVector_Div_Pos(quotient,iii,jjj,remainder);
-
-      if(0 != e) {
-       //error printing
-       if(counterexample_checking_during_refinement) {
-         OutputNode = CreateZeroConst(inputwidth);
-         bvdiv_exception_occured = true;
-         break;
-       }
-       else {
-         std::string ss("BVConstEvaluator:");
-         ss += (const char*)BitVector_Error(e);        
-         //destroy all the CONSTANTBV bitvectors
-         CONSTANTBV::BitVector_Destroy(iii);
-         CONSTANTBV::BitVector_Destroy(jjj);       
-         CONSTANTBV::BitVector_Destroy(One);
-         CONSTANTBV::BitVector_Destroy(Zero);
-
-         //AARON
-         iii = jjj = One = Zero = NULL;
-         //AARON
-
-         FatalError(ss.c_str(), t);
-       }
-      } //end of error printing
-
-      cccc = (char *)CONSTANTBV::BitVector_to_Bin(quotient);
-      OutputNode = CreateBVConst(cccc,2);
-
-      //AARON
-      free(cccc);
-      CONSTANTBV::BitVector_Destroy(quotient);
-      CONSTANTBV::BitVector_Destroy(remainder);
-      //AARON
-
-      break;
-    }
-   case BVMOD: {
-      unsigned * quotient = CONSTANTBV::BitVector_Create(inputwidth,true);
-      unsigned * remainder = CONSTANTBV::BitVector_Create(inputwidth,true);
-      // iii is dividend, jjj is the divisor
-      CONSTANTBV::ErrCode e = CONSTANTBV::BitVector_Div_Pos(quotient,iii,jjj,remainder);
-
-      if(0 != e) {
-       //error printing
-       if(counterexample_checking_during_refinement) {
-         OutputNode = CreateZeroConst(inputwidth);
-         bvdiv_exception_occured = true;
-         break;
-       }
-       else {
-         std::string ss("BVConstEvaluator:");
-         ss += (const char*)BitVector_Error(e);
-         //destroy all the CONSTANTBV bitvectors
-         CONSTANTBV::BitVector_Destroy(iii);
-         CONSTANTBV::BitVector_Destroy(jjj);       
-         CONSTANTBV::BitVector_Destroy(One);
-         CONSTANTBV::BitVector_Destroy(Zero);  
-
-         //AARON
-         iii = jjj = One = Zero = NULL;
-         //AARON
-
-         FatalError(ss.c_str(), t);
-       }
-      } //end of errory printing
-
-      cccc = (char *)CONSTANTBV::BitVector_to_Bin(remainder);
-      OutputNode = CreateBVConst(cccc,2);
-
-      //AARON
-      free(cccc);
-      CONSTANTBV::BitVector_Destroy(quotient);
-      CONSTANTBV::BitVector_Destroy(remainder);
-      //AARON
-
-      break;
-    }
-    case ITE:
-      if(ASTTrue == t[0])
-       OutputNode = BVConstEvaluator(t[1]);
-      else if(ASTFalse == t[0])
-       OutputNode = BVConstEvaluator(t[2]);
-      else
-       FatalError("BVConstEvaluator: ITE condiional must be either TRUE or FALSE:",t);
-      break;
-    case EQ: 
-      if(CONSTANTBV::BitVector_equal(iii,jjj))
-       OutputNode = ASTTrue;
-      else
-       OutputNode = ASTFalse;
-      break;
-    case NEQ:
-      if(!CONSTANTBV::BitVector_equal(iii,jjj))
-       OutputNode = ASTTrue;
-      else
-       OutputNode = ASTFalse;
-      break;
-    case BVLT:
-      if(-1 == CONSTANTBV::BitVector_Lexicompare(iii,jjj))
-       OutputNode = ASTTrue;
-      else
-       OutputNode = ASTFalse;
-      break;
-    case BVLE: {
-      int comp = CONSTANTBV::BitVector_Lexicompare(iii,jjj);
-      if(comp <= 0)
-       OutputNode = ASTTrue;
-      else
-       OutputNode = ASTFalse;
-      break;
-    }
-    case BVGT:
-      if(1 == CONSTANTBV::BitVector_Lexicompare(iii,jjj))
-       OutputNode = ASTTrue;
-      else
-       OutputNode = ASTFalse;
-      break;
-    case BVGE: {
-      int comp = CONSTANTBV::BitVector_Lexicompare(iii,jjj);
-      if(comp >= 0)
-       OutputNode = ASTTrue;
-      else
-       OutputNode = ASTFalse;
-      break;
-    } 
-    case BVSLT:
-      if(-1 == CONSTANTBV::BitVector_Compare(iii,jjj))
-       OutputNode = ASTTrue;
-      else
-       OutputNode = ASTFalse;
-      break;
-    case BVSLE: {
-      signed int comp = CONSTANTBV::BitVector_Compare(iii,jjj);
-      if(comp <= 0)
-       OutputNode = ASTTrue;
-      else
-       OutputNode = ASTFalse;
-      break;
-    }
-    case BVSGT:
-      if(1 == CONSTANTBV::BitVector_Compare(iii,jjj))
-       OutputNode = ASTTrue;
-      else
-       OutputNode = ASTFalse;
-      break;
-    case BVSGE: {
-      int comp = CONSTANTBV::BitVector_Compare(iii,jjj);
-      if(comp >= 0)
-       OutputNode = ASTTrue;
-      else
-       OutputNode = ASTFalse;
-      break;
-    } 
-    default:
-      FatalError("BVConstEvaluator: The input kind is not supported yet:",t);
-      break;
-    }
-
-
-
-    // //destroy all the CONSTANTBV bitvectors
-//     CONSTANTBV::BitVector_Destroy(iii);
-//     CONSTANTBV::BitVector_Destroy(jjj);
-//     CONSTANTBV::BitVector_Destroy(output);
-
-//     if(k == BVNEG || k == BVUMINUS)
-//       CONSTANTBV::BitVector_Destroy(One);
-//     else if(k == BVAND   || k == BVOR  || k == BVXOR   || k == BVSUB || 
-//         k == BVMULT  || k == EQ    || k == NEQ     || k == BVLT  ||
-//         k == BVLE    || k == BVGT  || k == BVGE    || k == BVSLT ||
-//         k == BVSLE   || k == BVSGT || k == BVSGE) {
-//       CONSTANTBV::BitVector_Destroy(One);
-//       CONSTANTBV::BitVector_Destroy(Zero);
-//     }    
-
-    //AARON
-    if (output != NULL) CONSTANTBV::BitVector_Destroy(output);
-    if (One != NULL) CONSTANTBV::BitVector_Destroy(One);
-    if (Zero != NULL) CONSTANTBV::BitVector_Destroy(Zero);
-    if (iii != NULL && iii != One) CONSTANTBV::BitVector_Destroy(iii);
-    if (jjj != NULL && jjj != Zero) CONSTANTBV::BitVector_Destroy(jjj);
-    //AARON
-   
-    UpdateSolverMap(t,OutputNode);
-    //UpdateSimplifyMap(t,OutputNode,false);
-    return OutputNode;
-  }
-
-
-  unsigned int * ConvertToCONSTANTBV(const char * s) {
-    unsigned int length = strlen(s);
-    unsigned char * ccc = (unsigned char *)s;
-    unsigned *  iii = CONSTANTBV::BitVector_Create(length,true);
-    CONSTANTBV::ErrCode e = CONSTANTBV::BitVector_from_Bin(iii,ccc);
-    //error printing
-    if(0 != e) {
-      cerr << "ConverToCONSTANTBV: wrong bin value: " << BitVector_Error(e);      
-      FatalError("");
-    }
-    
-    return iii;
-  }
-*/
-}; //end of namespace BEEV
+ ASTNode BeevMgr::BVConstEvaluator(const ASTNode& t) {
+ ASTNode OutputNode;
+ Kind k = t.GetKind();
+
+ if(CheckSolverMap(t,OutputNode))
+ return OutputNode;
+ OutputNode = t;
+
+ unsigned int inputwidth = t.GetValueWidth();
+ unsigned * output = CONSTANTBV::BitVector_Create(inputwidth,true);
+ unsigned * One = CONSTANTBV::BitVector_Create(inputwidth,true);
+ CONSTANTBV::ErrCode e = CONSTANTBV::BitVector_from_Bin(One, (unsigned char*)"1");
+ //error printing
+ if(0 != e) {
+ std::string ss("BVConstEvaluator:");
+ ss += (const char*)BitVector_Error(e);
+ FatalError(ss.c_str(), t);
+ }
+
+ unsigned * Zero = CONSTANTBV::BitVector_Create(inputwidth,true);
+ unsigned int * iii = One;
+ unsigned int * jjj = Zero;
+
+ //saving some typing. BVPLUS does not use these variables. if the
+ //input BVPLUS has two nodes, then we want to avoid setting these
+ //variables.
+ if(2 == t.Degree() && k != BVPLUS && k != BVCONCAT) {
+ iii = ConvertToCONSTANTBV(BVConstEvaluator(t[0]).GetBVConst());
+ jjj = ConvertToCONSTANTBV(BVConstEvaluator(t[1]).GetBVConst());
+ }
+
+ char * cccc;
+ switch(k) {
+ case UNDEFINED:
+ case READ:
+ case WRITE:
+ case SYMBOL:
+ FatalError("BVConstEvaluator: term is not a constant-term",t);
+ break;
+ case BVCONST:
+ OutputNode = t;
+ break;
+ case BVNEG:{
+ //AARON
+ if (iii != One) free(iii);
+ //AARON
+
+ iii = ConvertToCONSTANTBV(BVConstEvaluator(t[0]).GetBVConst());
+ CONSTANTBV::Set_Complement(output,iii);
+ cccc = (char *)CONSTANTBV::BitVector_to_Bin(output);
+ OutputNode = CreateBVConst(cccc,2);
+ break;
+ }
+ case BVSX: {
+ unsigned * out0 = ConvertToCONSTANTBV(BVConstEvaluator(t[0]).GetBVConst());
+ unsigned t0_width = t[0].GetValueWidth();
+ if(inputwidth == t0_width) {
+ cccc = (char *)CONSTANTBV::BitVector_to_Bin(out0);
+ OutputNode = CreateBVConst(cccc,2);
+
+ //AARON
+ free(cccc);
+ //AARON
+
+ CONSTANTBV::BitVector_Destroy(out0);
+ }
+ else {
+ // FIXME: (Dill) I'm guessing that BitVector sign returns 1 if the
+ // number is positive, 0 if 0, and -1 if negative.  But I'm only
+ // guessing.
+ signed int topbit_sign = (CONSTANTBV::BitVector_Sign(out0) < 0);
+ //out1 is the sign-extension bits
+ unsigned * out1 =  CONSTANTBV::BitVector_Create(inputwidth-t0_width,true);
+ if(topbit_sign)
+ CONSTANTBV::BitVector_Fill(out1);
+
+ //AARON
+ CONSTANTBV::BitVector_Destroy(output);
+ //AARON
+
+ output = CONSTANTBV::BitVector_Concat(out1,out0);
+ cccc = (char *)CONSTANTBV::BitVector_to_Bin(output);
+ OutputNode = CreateBVConst(cccc,2);
+
+ //AARON
+ free(cccc);
+ //AARON
+
+ CONSTANTBV::BitVector_Destroy(out0);
+ CONSTANTBV::BitVector_Destroy(out1);
+ }
+ break;
+ }
+ case BVAND: {
+ CONSTANTBV::Set_Intersection(output,iii,jjj);
+ cccc = (char *)CONSTANTBV::BitVector_to_Bin(output);
+ OutputNode = CreateBVConst(cccc,2);
+
+ //AARON
+ free(cccc);
+ //AARON
+
+ break;
+ }
+ case BVOR: {
+ CONSTANTBV::Set_Union(output,iii,jjj);
+ cccc = (char *)CONSTANTBV::BitVector_to_Bin(output);
+ OutputNode = CreateBVConst(cccc,2);
+
+ //AARON
+ free(cccc);
+ //AARON
+
+ break;
+ }
+ case BVXOR: {
+ CONSTANTBV::Set_ExclusiveOr(output,iii,jjj);
+ cccc = (char *)CONSTANTBV::BitVector_to_Bin(output);
+ OutputNode = CreateBVConst(cccc,2);
+
+ //AARON
+ free(cccc);
+ //AARON
+
+ break;
+ }
+ case BVSUB: {
+ bool carry = false;
+ CONSTANTBV::BitVector_sub(output,iii,jjj,&carry);
+ cccc = (char *)CONSTANTBV::BitVector_to_Bin(output);
+ OutputNode = CreateBVConst(cccc,2);
+
+ //AARON
+ free(cccc);
+ //AARON
+
+ break;
+ }
+ case BVUMINUS: {
+ bool carry = false;
+
+ //AARON
+ if (iii != One) free(iii);
+ //AARON
+
+ iii = ConvertToCONSTANTBV(BVConstEvaluator(t[0]).GetBVConst());
+ CONSTANTBV::Set_Complement(output,iii);
+ CONSTANTBV::BitVector_add(output,output,One,&carry);
+ cccc = (char *)CONSTANTBV::BitVector_to_Bin(output);
+ OutputNode = CreateBVConst(cccc,2);
+
+ //AARON
+ free(cccc);
+ //AARON
+
+ break;
+ }
+ case BVEXTRACT: {
+ string s(BVConstEvaluator(t[0]).GetBVConst());
+ unsigned int hi = GetUnsignedConst(BVConstEvaluator(t[1]));
+ unsigned int low = GetUnsignedConst(BVConstEvaluator(t[2]));
+
+ //length of substr to chop
+ unsigned int len = hi-low+1;
+ //distance from MSB
+ hi = s.size()-1 - hi;
+ string ss = s.substr(hi,len);
+ OutputNode = CreateBVConst(ss.c_str(),2);
+ break;
+ }
+ case BVCONCAT: {
+ string s(BVConstEvaluator(t[0]).GetBVConst());
+ string r(BVConstEvaluator(t[1]).GetBVConst());
+
+ string q(s+r);
+ OutputNode = CreateBVConst(q.c_str(),2);
+ break;
+ }
+ case BVMULT: {
+ unsigned * output1 = CONSTANTBV::BitVector_Create(2*inputwidth,true);
+ CONSTANTBV::ErrCode e = CONSTANTBV::BitVector_Multiply(output1,iii,jjj);
+ //error printing
+ if(0 != e) {
+ std::string ss("BVConstEvaluator:");
+ ss += (const char*)BitVector_Error(e);
+ //destroy all the CONSTANTBV bitvectors
+ CONSTANTBV::BitVector_Destroy(iii);
+ CONSTANTBV::BitVector_Destroy(jjj);
+ CONSTANTBV::BitVector_Destroy(One);
+ CONSTANTBV::BitVector_Destroy(Zero);
+ FatalError(ss.c_str(), t);
+ }
+
+ cccc = (char *)CONSTANTBV::BitVector_to_Bin(output1);
+ std::string s(cccc);
+
+ //AARON
+ free(cccc);
+ //AARON
+
+ s = s.substr(inputwidth,inputwidth);
+ OutputNode = CreateBVConst(s.c_str(),2);
+ CONSTANTBV::BitVector_Destroy(output1);
+ break;
+ }
+ case BVPLUS: {
+ bool carry = false;
+ ASTVec c = t.GetChildren();
+ for(ASTVec::iterator it=c.begin(),itend=c.end();it!=itend;it++) {
+ unsigned int * kk = ConvertToCONSTANTBV(BVConstEvaluator(*it).GetBVConst());
+ CONSTANTBV::BitVector_add(output,output,kk,&carry);
+ carry = false;
+ CONSTANTBV::BitVector_Destroy(kk);
+ }
+ cccc = (char *)CONSTANTBV::BitVector_to_Bin(output);
+ OutputNode = CreateBVConst(cccc,2);
+
+ //AARON
+ free(cccc);
+ //AARON
+
+ break;
+ }
+ case SBVDIV:
+ case SBVREM: {
+ OutputNode = BVConstEvaluator(TranslateSignedDivMod(t));
+ break;
+ }
+ case BVDIV: {
+ unsigned * quotient = CONSTANTBV::BitVector_Create(inputwidth,true);
+ unsigned * remainder = CONSTANTBV::BitVector_Create(inputwidth,true);
+ // iii is dividend, jjj is the divisor
+ CONSTANTBV::ErrCode e = CONSTANTBV::BitVector_Div_Pos(quotient,iii,jjj,remainder);
+
+ if(0 != e) {
+ //error printing
+ if(counterexample_checking_during_refinement) {
+ OutputNode = CreateZeroConst(inputwidth);
+ bvdiv_exception_occured = true;
+ break;
+ }
+ else {
+ std::string ss("BVConstEvaluator:");
+ ss += (const char*)BitVector_Error(e);
+ //destroy all the CONSTANTBV bitvectors
+ CONSTANTBV::BitVector_Destroy(iii);
+ CONSTANTBV::BitVector_Destroy(jjj);
+ CONSTANTBV::BitVector_Destroy(One);
+ CONSTANTBV::BitVector_Destroy(Zero);
+
+ //AARON
+ iii = jjj = One = Zero = NULL;
+ //AARON
+
+ FatalError(ss.c_str(), t);
+ }
+ } //end of error printing
+
+ cccc = (char *)CONSTANTBV::BitVector_to_Bin(quotient);
+ OutputNode = CreateBVConst(cccc,2);
+
+ //AARON
+ free(cccc);
+ CONSTANTBV::BitVector_Destroy(quotient);
+ CONSTANTBV::BitVector_Destroy(remainder);
+ //AARON
+
+ break;
+ }
+ case BVMOD: {
+ unsigned * quotient = CONSTANTBV::BitVector_Create(inputwidth,true);
+ unsigned * remainder = CONSTANTBV::BitVector_Create(inputwidth,true);
+ // iii is dividend, jjj is the divisor
+ CONSTANTBV::ErrCode e = CONSTANTBV::BitVector_Div_Pos(quotient,iii,jjj,remainder);
+
+ if(0 != e) {
+ //error printing
+ if(counterexample_checking_during_refinement) {
+ OutputNode = CreateZeroConst(inputwidth);
+ bvdiv_exception_occured = true;
+ break;
+ }
+ else {
+ std::string ss("BVConstEvaluator:");
+ ss += (const char*)BitVector_Error(e);
+ //destroy all the CONSTANTBV bitvectors
+ CONSTANTBV::BitVector_Destroy(iii);
+ CONSTANTBV::BitVector_Destroy(jjj);
+ CONSTANTBV::BitVector_Destroy(One);
+ CONSTANTBV::BitVector_Destroy(Zero);
+
+ //AARON
+ iii = jjj = One = Zero = NULL;
+ //AARON
+
+ FatalError(ss.c_str(), t);
+ }
+ } //end of errory printing
+
+ cccc = (char *)CONSTANTBV::BitVector_to_Bin(remainder);
+ OutputNode = CreateBVConst(cccc,2);
+
+ //AARON
+ free(cccc);
+ CONSTANTBV::BitVector_Destroy(quotient);
+ CONSTANTBV::BitVector_Destroy(remainder);
+ //AARON
+
+ break;
+ }
+ case ITE:
+ if(ASTTrue == t[0])
+ OutputNode = BVConstEvaluator(t[1]);
+ else if(ASTFalse == t[0])
+ OutputNode = BVConstEvaluator(t[2]);
+ else
+ FatalError("BVConstEvaluator: ITE condiional must be either TRUE or FALSE:",t);
+ break;
+ case EQ:
+ if(CONSTANTBV::BitVector_equal(iii,jjj))
+ OutputNode = ASTTrue;
+ else
+ OutputNode = ASTFalse;
+ break;
+ case NEQ:
+ if(!CONSTANTBV::BitVector_equal(iii,jjj))
+ OutputNode = ASTTrue;
+ else
+ OutputNode = ASTFalse;
+ break;
+ case BVLT:
+ if(-1 == CONSTANTBV::BitVector_Lexicompare(iii,jjj))
+ OutputNode = ASTTrue;
+ else
+ OutputNode = ASTFalse;
+ break;
+ case BVLE: {
+ int comp = CONSTANTBV::BitVector_Lexicompare(iii,jjj);
+ if(comp <= 0)
+ OutputNode = ASTTrue;
+ else
+ OutputNode = ASTFalse;
+ break;
+ }
+ case BVGT:
+ if(1 == CONSTANTBV::BitVector_Lexicompare(iii,jjj))
+ OutputNode = ASTTrue;
+ else
+ OutputNode = ASTFalse;
+ break;
+ case BVGE: {
+ int comp = CONSTANTBV::BitVector_Lexicompare(iii,jjj);
+ if(comp >= 0)
+ OutputNode = ASTTrue;
+ else
+ OutputNode = ASTFalse;
+ break;
+ }
+ case BVSLT:
+ if(-1 == CONSTANTBV::BitVector_Compare(iii,jjj))
+ OutputNode = ASTTrue;
+ else
+ OutputNode = ASTFalse;
+ break;
+ case BVSLE: {
+ signed int comp = CONSTANTBV::BitVector_Compare(iii,jjj);
+ if(comp <= 0)
+ OutputNode = ASTTrue;
+ else
+ OutputNode = ASTFalse;
+ break;
+ }
+ case BVSGT:
+ if(1 == CONSTANTBV::BitVector_Compare(iii,jjj))
+ OutputNode = ASTTrue;
+ else
+ OutputNode = ASTFalse;
+ break;
+ case BVSGE: {
+ int comp = CONSTANTBV::BitVector_Compare(iii,jjj);
+ if(comp >= 0)
+ OutputNode = ASTTrue;
+ else
+ OutputNode = ASTFalse;
+ break;
+ }
+ default:
+ FatalError("BVConstEvaluator: The input kind is not supported yet:",t);
+ break;
+ }
+
+
+
+ // //destroy all the CONSTANTBV bitvectors
+ //     CONSTANTBV::BitVector_Destroy(iii);
+ //     CONSTANTBV::BitVector_Destroy(jjj);
+ //     CONSTANTBV::BitVector_Destroy(output);
+
+ //     if(k == BVNEG || k == BVUMINUS)
+ //       CONSTANTBV::BitVector_Destroy(One);
+ //     else if(k == BVAND   || k == BVOR  || k == BVXOR   || k == BVSUB ||
+ //        k == BVMULT  || k == EQ    || k == NEQ     || k == BVLT  ||
+ //        k == BVLE    || k == BVGT  || k == BVGE    || k == BVSLT ||
+ //        k == BVSLE   || k == BVSGT || k == BVSGE) {
+ //       CONSTANTBV::BitVector_Destroy(One);
+ //       CONSTANTBV::BitVector_Destroy(Zero);
+ //     }
+
+ //AARON
+ if (output != NULL) CONSTANTBV::BitVector_Destroy(output);
+ if (One != NULL) CONSTANTBV::BitVector_Destroy(One);
+ if (Zero != NULL) CONSTANTBV::BitVector_Destroy(Zero);
+ if (iii != NULL && iii != One) CONSTANTBV::BitVector_Destroy(iii);
+ if (jjj != NULL && jjj != Zero) CONSTANTBV::BitVector_Destroy(jjj);
+ //AARON
+
+ UpdateSolverMap(t,OutputNode);
+ //UpdateSimplifyMap(t,OutputNode,false);
+ return OutputNode;
+ }
+
+
+ unsigned int * ConvertToCONSTANTBV(const char * s) {
+ unsigned int length = strlen(s);
+ unsigned char * ccc = (unsigned char *)s;
+ unsigned *  iii = CONSTANTBV::BitVector_Create(length,true);
+ CONSTANTBV::ErrCode e = CONSTANTBV::BitVector_from_Bin(iii,ccc);
+ //error printing
+ if(0 != e) {
+ cerr << "ConverToCONSTANTBV: wrong bin value: " << BitVector_Error(e);
+ FatalError("");
+ }
+
+ return iii;
+ }
+ */
+}
+; //end of namespace BEEV
diff --git a/format_config.xml b/format_config.xml
new file mode 100644 (file)
index 0000000..d2f242f
--- /dev/null
@@ -0,0 +1,151 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<profiles version="1">
+<profile kind="CodeFormatterProfile" name="BSD/Allman - without wrapping" version="1">
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_opening_paren_in_method_declaration" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_after_opening_paren_in_for" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_new_line_in_empty_block" value="insert"/>
+<setting id="org.eclipse.cdt.core.formatter.lineSplit" value="150"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_comma_in_base_types" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.keep_else_statement_on_same_line" value="false"/>
+<setting id="org.eclipse.cdt.core.formatter.indent_switchstatements_compare_to_switch" value="true"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_after_opening_brace_in_array_initializer" value="insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_after_opening_paren_in_if" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_after_comma_in_base_types" value="insert"/>
+<setting id="org.eclipse.cdt.core.formatter.indent_body_declarations_compare_to_access_specifier" value="true"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_after_comma_in_template_arguments" value="insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_opening_brace_in_block" value="insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_closing_paren_in_method_declaration" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.use_tabs_only_for_leading_indentations" value="false"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_colon_in_labeled_statement" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_after_colon_in_case" value="insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_after_comma_in_array_initializer" value="insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_after_comma_in_enum_declarations" value="insert"/>
+<setting id="org.eclipse.cdt.core.formatter.alignment_for_expressions_in_array_initializer" value="16"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_after_comma_in_declarator_list" value="insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_opening_bracket" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_closing_paren_in_for" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_prefix_operator" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.tabulation.size" value="4"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_new_line_before_else_in_if_statement" value="insert"/>
+<setting id="org.eclipse.cdt.core.formatter.alignment_for_enumerator_list" value="48"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_between_empty_parens_in_method_declaration" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.alignment_for_declarator_list" value="16"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_closing_paren_in_switch" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.indent_empty_lines" value="false"/>
+<setting id="org.eclipse.cdt.core.formatter.indent_switchstatements_compare_to_cases" value="true"/>
+<setting id="org.eclipse.cdt.core.formatter.keep_empty_array_initializer_on_one_line" value="false"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_opening_brace_in_method_declaration" value="insert"/>
+<setting id="org.eclipse.cdt.core.formatter.put_empty_statement_on_new_line" value="true"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_opening_brace_in_switch" value="insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_closing_paren_in_cast" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_between_empty_braces_in_array_initializer" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.brace_position_for_method_declaration" value="next_line"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_closing_paren_in_while" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_after_question_in_conditional" value="insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_semicolon" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_after_closing_angle_bracket_in_template_arguments" value="insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_colon_in_base_clause" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.indent_breaks_compare_to_cases" value="true"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_unary_operator" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_comma_in_declarator_list" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.alignment_for_arguments_in_method_invocation" value="16"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_opening_paren_in_while" value="insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_between_empty_brackets" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_after_opening_bracket" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.alignment_for_parameters_in_method_declaration" value="80"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.number_of_empty_lines_to_preserve" value="1"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_after_opening_paren_in_method_invocation" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_closing_brace_in_array_initializer" value="insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_semicolon_in_for" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.brace_position_for_block" value="next_line"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_colon_in_conditional" value="insert"/>
+<setting id="org.eclipse.cdt.core.formatter.brace_position_for_type_declaration" value="next_line"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_assignment_operator" value="insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_opening_angle_bracket_in_template_arguments" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_comma_in_expression_list" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_after_opening_angle_bracket_in_template_parameters" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.continuation_indentation" value="2"/>
+<setting id="org.eclipse.cdt.core.formatter.alignment_for_expression_list" value="0"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_after_opening_paren_in_method_declaration" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_comma_in_template_parameters" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_after_binary_operator" value="insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_colon_in_default" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.alignment_for_conditional_expression" value="80"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_between_empty_parens_in_method_invocation" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_comma_in_array_initializer" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_closing_paren_in_if" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.format_guardian_clause_on_one_line" value="false"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_after_opening_paren_in_cast" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.indent_access_specifier_compare_to_type_header" value="false"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_opening_brace_in_type_declaration" value="insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_after_colon_in_labeled_statement" value="insert"/>
+<setting id="org.eclipse.cdt.core.formatter.continuation_indentation_for_array_initializer" value="2"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters" value="insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_after_semicolon_in_for" value="insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_closing_paren_in_method_invocation" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.indent_body_declarations_compare_to_namespace_header" value="false"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_after_closing_brace_in_block" value="insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_after_assignment_operator" value="insert"/>
+<setting id="org.eclipse.cdt.core.formatter.alignment_for_compact_if" value="0"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_opening_brace_in_array_initializer" value="insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_new_line_at_end_of_file_if_missing" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_after_comma_in_template_parameters" value="insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_after_comma_in_expression_list" value="insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_question_in_conditional" value="insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_binary_operator" value="insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_new_line_before_identifier_in_function_declaration" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.alignment_for_base_clause_in_type_declaration" value="80"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_comma_in_method_declaration_throws" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.indent_declaration_compare_to_template_header" value="false"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_after_unary_operator" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_opening_paren_in_switch" value="insert"/>
+<setting id="org.eclipse.cdt.core.formatter.indent_statements_compare_to_body" value="true"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_after_comma_in_method_declaration_throws" value="insert"/>
+<setting id="org.eclipse.cdt.core.formatter.indent_statements_compare_to_block" value="true"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_comma_in_template_arguments" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_new_line_before_catch_in_try_statement" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.alignment_for_throws_clause_in_method_declaration" value="16"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_opening_paren_in_method_invocation" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_after_closing_paren_in_cast" value="insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_closing_paren_in_catch" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_opening_angle_bracket_in_template_parameters" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.tabulation.char" value="tab"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_closing_angle_bracket_in_template_parameters" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_after_opening_paren_in_while" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments" value="insert"/>
+<setting id="org.eclipse.cdt.core.formatter.brace_position_for_block_in_case" value="next_line"/>
+<setting id="org.eclipse.cdt.core.formatter.compact_else_if" value="true"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_after_postfix_operator" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_after_colon_in_base_clause" value="insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_new_line_after_template_declaration" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_after_opening_paren_in_catch" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.keep_then_statement_on_same_line" value="false"/>
+<setting id="org.eclipse.cdt.core.formatter.brace_position_for_switch" value="next_line"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_opening_paren_in_if" value="insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_after_opening_paren_in_switch" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.keep_imple_if_on_one_line" value="false"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.indentation.size" value="4"/>
+<setting id="org.eclipse.cdt.core.formatter.brace_position_for_namespace_declaration" value="next_line"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_after_colon_in_conditional" value="insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_comma_in_enum_declarations" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_after_prefix_operator" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_closing_angle_bracket_in_template_arguments" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.brace_position_for_array_initializer" value="end_of_line"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_colon_in_case" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_opening_paren_in_catch" value="insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_opening_brace_in_namespace_declaration" value="insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_postfix_operator" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_closing_bracket" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_new_line_before_while_in_do_statement" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_opening_paren_in_for" value="insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_after_closing_angle_bracket_in_template_parameters" value="insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_after_opening_angle_bracket_in_template_arguments" value="do not insert"/>
+</profile>
+</profiles>
index 1c08f30b844c038dd69ff3eb7bcb48f2725b79a4..f873d4ebc19680bab86d935c6efeacd30afabd15 100644 (file)
 #include "../AST/ASTUtil.h"
 #include "bvsolver.h"
 
-  //This file contains the implementation of member functions of
-  //bvsolver class, which represents the bitvector arithmetic linear
-  //solver. Please also refer the STP's CAV 2007 paper for the
-  //complete description of the linear solver algorithm
-  //
-  //The bitvector solver is a partial solver, i.e. it does not solve
-  //for all variables in the system of equations. it is
-  //best-effort. it relies on the SAT solver to be complete.
-  //
-  //The BVSolver assumes that the input equations are normalized, and
-  //have liketerms combined etc.
-  //
-  //0. Traverse top-down over the input DAG, looking for a conjunction
-  //0. of equations. if you find one, then for each equation in the
-  //0. conjunction, do the following steps.
-  //
-  //1. check for Linearity of the input equation
-  //
-  //2. Solve for a "chosen" variable. The variable should occur
-  //2. exactly once and must have an odd coeff. Refer STP's CAV 2007
-  //2. paper for actual solving procedure
-  //
-  //4. Outside the solver, Substitute and Re-normalize the input DAG 
-namespace BEEV {  
-  //check the solver map for 'key'. If key is present, then return the
-  //value by reference in the argument 'output'
-  bool BVSolver::CheckAlreadySolvedMap(const ASTNode& key, ASTNode& output) {
-    ASTNodeMap::iterator it;
-    if((it = FormulasAlreadySolvedMap.find(key)) != FormulasAlreadySolvedMap.end()) {
-      output = it->second;
-      return true;
-    }
-    return false;
-  } //CheckAlreadySolvedMap()
-
-  void BVSolver::UpdateAlreadySolvedMap(const ASTNode& key, const ASTNode& value) {
-    FormulasAlreadySolvedMap[key] = value;
-  } //end of UpdateAlreadySolvedMap()
-
-  //FIXME This is doing way more arithmetic than it needs to.
-  //accepts an even number "in", and splits it into an odd number and
-  //a power of 2. i.e " in = b.(2^k) ". returns the odd number, and
-  //the power of two by reference
-  ASTNode BVSolver::SplitEven_into_Oddnum_PowerOf2(const ASTNode& in, 
-                                               unsigned int& number_shifts) {
-    if(BVCONST != in.GetKind() || _bm->BVConstIsOdd(in)) {
-      FatalError("BVSolver:SplitNum_Odd_PowerOf2: input must be a BVCONST and even\n",in);
-    }
-    
-    unsigned int len = in.GetValueWidth();
-    ASTNode zero = _bm->CreateZeroConst(len);
-    ASTNode two = _bm->CreateTwoConst(len);
-    ASTNode div_by_2 = in;
-    ASTNode mod_by_2 = 
-      _bm->BVConstEvaluator(_bm->CreateTerm(BVMOD,len,div_by_2,two)); 
-    while(mod_by_2 == zero) {
-      div_by_2 = 
-       _bm->BVConstEvaluator(_bm->CreateTerm(BVDIV,len,div_by_2,two));
-      number_shifts++;
-      mod_by_2 = 
-       _bm->BVConstEvaluator(_bm->CreateTerm(BVMOD,len,div_by_2,two));
-    }
-    return div_by_2;
-  } //end of SplitEven_into_Oddnum_PowerOf2()
-
-  //Checks if there are any ARRAYREADS in the term, after the
-  //alreadyseenmap is cleared, i.e. traversing a new term altogether
-  bool BVSolver::CheckForArrayReads_TopLevel(const ASTNode& term) {
-    TermsAlreadySeenMap.clear();
-    return CheckForArrayReads(term);
-  }
-  
-  //Checks if there are any ARRAYREADS in the term
-  bool BVSolver::CheckForArrayReads(const ASTNode& term) {
-    ASTNode a = term;
-    ASTNodeMap::iterator it;    
-    if((it = TermsAlreadySeenMap.find(term)) != TermsAlreadySeenMap.end()) {
-      //if the term has been seen, then simply return true, else
-      //return false
-      if(ASTTrue == (it->second)) {
-       return true;
-      }
-      else {
+//This file contains the implementation of member functions of
+//bvsolver class, which represents the bitvector arithmetic linear
+//solver. Please also refer the STP's CAV 2007 paper for the
+//complete description of the linear solver algorithm
+//
+//The bitvector solver is a partial solver, i.e. it does not solve
+//for all variables in the system of equations. it is
+//best-effort. it relies on the SAT solver to be complete.
+//
+//The BVSolver assumes that the input equations are normalized, and
+//have liketerms combined etc.
+//
+//0. Traverse top-down over the input DAG, looking for a conjunction
+//0. of equations. if you find one, then for each equation in the
+//0. conjunction, do the following steps.
+//
+//1. check for Linearity of the input equation
+//
+//2. Solve for a "chosen" variable. The variable should occur
+//2. exactly once and must have an odd coeff. Refer STP's CAV 2007
+//2. paper for actual solving procedure
+//
+//4. Outside the solver, Substitute and Re-normalize the input DAG
+namespace BEEV
+{
+//check the solver map for 'key'. If key is present, then return the
+//value by reference in the argument 'output'
+bool BVSolver::CheckAlreadySolvedMap(const ASTNode& key, ASTNode& output)
+{
+       ASTNodeMap::iterator it;
+       if ((it = FormulasAlreadySolvedMap.find(key)) != FormulasAlreadySolvedMap.end())
+       {
+               output = it->second;
+               return true;
+       }
        return false;
-      }
-    }
-
-    switch(term.GetKind()) {
-    case READ:
-      //an array read has been seen. Make an entry in the map and
-      //return true
-      TermsAlreadySeenMap[term] = ASTTrue;
-      return true;
-    default: {
-      ASTVec c = term.GetChildren();
-      for(ASTVec::iterator it=c.begin(),itend=c.end();it!=itend;it++) {
-       if(CheckForArrayReads(*it)) {
-         return true;
+} //CheckAlreadySolvedMap()
+
+void BVSolver::UpdateAlreadySolvedMap(const ASTNode& key, const ASTNode& value)
+{
+       FormulasAlreadySolvedMap[key] = value;
+} //end of UpdateAlreadySolvedMap()
+
+//FIXME This is doing way more arithmetic than it needs to.
+//accepts an even number "in", and splits it into an odd number and
+//a power of 2. i.e " in = b.(2^k) ". returns the odd number, and
+//the power of two by reference
+ASTNode BVSolver::SplitEven_into_Oddnum_PowerOf2(const ASTNode& in, unsigned int& number_shifts)
+{
+       if (BVCONST != in.GetKind() || _bm->BVConstIsOdd(in))
+       {
+               FatalError("BVSolver:SplitNum_Odd_PowerOf2: input must be a BVCONST and even\n", in);
        }
-      }
-      break;
-    }
-    }
-
-    //If control is here, then it means that no arrayread was seen for
-    //the input 'term'. Make an entry in the map with the term as key
-    //and FALSE as value.
-    TermsAlreadySeenMap[term] = ASTFalse;
-    return false;
-  } //end of CheckForArrayReads()
-  
-  //check the solver map for 'key'. If key is present, then return the
-  //value by reference in the argument 'output'
-  bool BeevMgr::CheckSolverMap(const ASTNode& key, ASTNode& output) {
-    ASTNodeMap::iterator it;
-    if((it = SolverMap.find(key)) != SolverMap.end()) {
-      output = it->second;
-      return true;
-    }
-    return false;
-  } //end of CheckSolverMap()
-
-  bool BeevMgr::CheckSolverMap(const ASTNode& key) {
-    if(SolverMap.find(key) != SolverMap.end()) 
-      return true;
-    else
-      return false;
-  } //end of CheckSolverMap()
-  
-  //update solvermap with (key,value) pair
-  bool BeevMgr::UpdateSolverMap(const ASTNode& key, const ASTNode& value) {
-    ASTNode var = (BVEXTRACT == key.GetKind()) ? key[0] : key;
-    if(!CheckSolverMap(var) && key != value) {
-      SolverMap[key] = value;
-      return true;
-    }  
-    return false;
-  } //end of UpdateSolverMap()
-
-  //collects the vars in the term 'lhs' into the multiset Vars
-  void BVSolver::VarsInTheTerm_TopLevel(const ASTNode& lhs, ASTNodeMultiSet& Vars) {
-    TermsAlreadySeenMap.clear();
-    VarsInTheTerm(lhs,Vars);
-  }
-
-  //collects the vars in the term 'lhs' into the multiset Vars
-  void BVSolver::VarsInTheTerm(const ASTNode& term, ASTNodeMultiSet& Vars) {
-    ASTNode a = term;
-    ASTNodeMap::iterator it;    
-    if((it = TermsAlreadySeenMap.find(term)) != TermsAlreadySeenMap.end()) {
-      //if the term has been seen, then simply return
-      return;
-    }
-
-    switch(term.GetKind()) {
-    case BVCONST:
-      return;
-    case SYMBOL:
-      //cerr << "debugging: symbol added: " << term << endl;
-      Vars.insert(term);
-      break;
-    case READ:
-      //skip the arrayname, provided the arrayname is a SYMBOL
-      if(SYMBOL == term[0].GetKind()) {
-       VarsInTheTerm(term[1],Vars);
-      }
-      else {
-       VarsInTheTerm(term[0],Vars);
-       VarsInTheTerm(term[1],Vars);
-      }
-      break;
-    default: {
-      ASTVec c = term.GetChildren();
-      for(ASTVec::iterator it=c.begin(),itend=c.end();it!=itend;it++) {
-         VarsInTheTerm(*it,Vars);        
-      }
-      break;
-    }
-    }
-
-    //ensures that you don't double count. if you have seen the term
-    //once, then memoize
-    TermsAlreadySeenMap[term] = ASTTrue;
-    return;
-  } //end of VarsInTheTerm()  
-
-  bool BVSolver::DoNotSolveThis(const ASTNode& var) {
-    if(DoNotSolve_TheseVars.find(var) != DoNotSolve_TheseVars.end()) {
-      return true;
-    }
-    return false;
-  }
-
-  //chooses a variable in the lhs and returns the chosen variable
-  ASTNode BVSolver::ChooseMonom(const ASTNode& eq, ASTNode& modifiedlhs) {
-    if(!(EQ == eq.GetKind() && BVPLUS == eq[0].GetKind())) {
-      FatalError("ChooseMonom: input must be a EQ",eq);
-    }
-
-    ASTNode lhs = eq[0];
-    ASTNode rhs = eq[1];
-    ASTNode zero = _bm->CreateZeroConst(32);
-
-    //collect all the vars in the lhs and rhs
-    ASTNodeMultiSet Vars;
-    VarsInTheTerm_TopLevel(lhs,Vars);
-
-    //handle BVPLUS case
-    ASTVec c = lhs.GetChildren();
-    ASTVec o;    
-    ASTNode outmonom = _bm->CreateNode(UNDEFINED);
-    bool chosen_symbol = false;
-    bool chosen_odd = false;
-
-    //choose variables with no coeffs
-    for(ASTVec::iterator it=c.begin(),itend=c.end();it!=itend;it++) {
-      ASTNode monom = *it;
-      if(SYMBOL == monom.GetKind() &&
-        Vars.count(monom) == 1    &&    
-        !_bm->VarSeenInTerm(monom,rhs) &&
-        !DoNotSolveThis(monom)   &&
-        !chosen_symbol) {
-       outmonom = monom;
-       chosen_symbol = true;
-      }
-      else if(BVUMINUS == monom.GetKind()  &&
-             SYMBOL == monom[0].GetKind() &&
-             Vars.count(monom[0]) == 1    &&
-             !DoNotSolveThis(monom[0])   &&
-             !_bm->VarSeenInTerm(monom[0],rhs) &&
-             !chosen_symbol) {
-       //cerr << "Chosen Monom: " << monom << endl;
-       outmonom = monom;
-       chosen_symbol = true;
-      }
-      else {
-       o.push_back(monom);
-      }
-    }
-
-    //try to choose only odd coeffed variables first
-    if(!chosen_symbol) {
-      o.clear();
-      for(ASTVec::iterator it=c.begin(),itend=c.end();it!=itend;it++) {
-       ASTNode monom = *it;
-       ASTNode var = (BVMULT == monom.GetKind()) ? monom[1] : _bm->CreateNode(UNDEFINED);
-
-       if(BVMULT == monom.GetKind()     && 
-          BVCONST == monom[0].GetKind() &&
-          _bm->BVConstIsOdd(monom[0])   &&
-          ((SYMBOL == var.GetKind()  && 
-            Vars.count(var) == 1) 
-           || 
-           (BVEXTRACT == var.GetKind()  && 
-            SYMBOL == var[0].GetKind()  && 
-            BVCONST == var[1].GetKind() && 
-            zero == var[2] && 
-            !_bm->VarSeenInTerm(var[0],rhs) &&
-            !DoNotSolveThis(var[0]))       
-           ) &&
-          !DoNotSolveThis(var)     &&
-          !_bm->VarSeenInTerm(var,rhs)  &&
-          !chosen_odd) {
-         //monom[0] is odd.
-         outmonom = monom;
-         chosen_odd = true;
+
+       unsigned int len = in.GetValueWidth();
+       ASTNode zero = _bm->CreateZeroConst(len);
+       ASTNode two = _bm->CreateTwoConst(len);
+       ASTNode div_by_2 = in;
+       ASTNode mod_by_2 = _bm->BVConstEvaluator(_bm->CreateTerm(BVMOD, len, div_by_2, two));
+       while (mod_by_2 == zero)
+       {
+               div_by_2 = _bm->BVConstEvaluator(_bm->CreateTerm(BVDIV, len, div_by_2, two));
+               number_shifts++;
+               mod_by_2 = _bm->BVConstEvaluator(_bm->CreateTerm(BVMOD, len, div_by_2, two));
        }
-       else {
-       o.push_back(monom);
+       return div_by_2;
+} //end of SplitEven_into_Oddnum_PowerOf2()
+
+//Checks if there are any ARRAYREADS in the term, after the
+//alreadyseenmap is cleared, i.e. traversing a new term altogether
+bool BVSolver::CheckForArrayReads_TopLevel(const ASTNode& term)
+{
+       TermsAlreadySeenMap.clear();
+       return CheckForArrayReads(term);
+}
+
+//Checks if there are any ARRAYREADS in the term
+bool BVSolver::CheckForArrayReads(const ASTNode& term)
+{
+       ASTNode a = term;
+       ASTNodeMap::iterator it;
+       if ((it = TermsAlreadySeenMap.find(term)) != TermsAlreadySeenMap.end())
+       {
+               //if the term has been seen, then simply return true, else
+               //return false
+               if (ASTTrue == (it->second))
+               {
+                       return true;
+               }
+               else
+               {
+                       return false;
+               }
        }
-      }
-    }
-
-    modifiedlhs = (o.size() > 1) ? _bm->CreateTerm(BVPLUS,lhs.GetValueWidth(),o) : o[0];
-    return outmonom;
-  } //end of choosemonom()
-
-  //solver function which solves for variables with odd coefficient
-  ASTNode BVSolver::BVSolve_Odd(const ASTNode& input) {
-    ASTNode eq = input;
-    //cerr << "Input to BVSolve_Odd()" << eq << endl;
-    if(!(wordlevel_solve && EQ == eq.GetKind())) {
-      return input;
-    }
-
-    ASTNode output = input;
-    if(CheckAlreadySolvedMap(input,output)) {
-      return output;
-    }
-
-    //get the lhs and the rhs, and case-split on the lhs kind
-    ASTNode lhs = eq[0];
-    ASTNode rhs = eq[1];
-    if(BVPLUS == lhs.GetKind()) {
-      ASTNode chosen_monom = _bm->CreateNode(UNDEFINED);
-      ASTNode leftover_lhs;
-
-      //choose monom makes sure that it gets only those vars that
-      //occur exactly once in lhs and rhs put together
-      chosen_monom = ChooseMonom(eq, leftover_lhs);
-      if(chosen_monom == _bm->CreateNode(UNDEFINED)) {
-       //no monomial was chosen
-       return eq;
-      }
-      
-      //if control is here then it means that a monom was chosen
-      //
-      //construct:  rhs - (lhs without the chosen monom)
-      unsigned int len = lhs.GetValueWidth();
-      leftover_lhs = _bm->SimplifyTerm_TopLevel(_bm->CreateTerm(BVUMINUS,len,leftover_lhs));      
-      ASTNode newrhs = _bm->SimplifyTerm(_bm->CreateTerm(BVPLUS,len,rhs,leftover_lhs));
-      lhs = chosen_monom;
-      rhs = newrhs;
-    } //end of if(BVPLUS ...)
-
-    if(BVUMINUS == lhs.GetKind()) {
-      //equation is of the form (-lhs0) = rhs
-      ASTNode lhs0 = lhs[0];
-      rhs = _bm->SimplifyTerm(_bm->CreateTerm(BVUMINUS,rhs.GetValueWidth(),rhs));
-      lhs = lhs0;      
-    }
-
-    switch(lhs.GetKind()) {
-    case SYMBOL: {     
-      //input is of the form x = rhs first make sure that the lhs
-      //symbol does not occur on the rhs or that it has not been
-      //solved for
-      if(_bm->VarSeenInTerm(lhs,rhs)) {
-       //found the lhs in the rhs. Abort!
-       DoNotSolve_TheseVars.insert(lhs);
-       return eq;
-      }
-      
-      //rhs should not have arrayreads in it. it complicates matters
-      //during transformation
-      // if(CheckForArrayReads_TopLevel(rhs)) {
-      //               return eq;
-      //       }
-
-      DoNotSolve_TheseVars.insert(lhs);
-      if(!_bm->UpdateSolverMap(lhs,rhs)) {
-       return eq;
-      }
-
-      output = ASTTrue;
-      break;
-    }
-    case BVEXTRACT: {
-      ASTNode zero = _bm->CreateZeroConst(32);
-      
-      if(!(SYMBOL == lhs[0].GetKind()  && 
-          BVCONST == lhs[1].GetKind() && 
-          zero == lhs[2] && 
-          !_bm->VarSeenInTerm(lhs[0],rhs) &&
-          !DoNotSolveThis(lhs[0]))) {
-       return eq;
-      }
-      
-      if(_bm->VarSeenInTerm(lhs[0],rhs)) {
-       DoNotSolve_TheseVars.insert(lhs[0]);
-       return eq;
-      }
-      
-      DoNotSolve_TheseVars.insert(lhs[0]);
-      if(!_bm->UpdateSolverMap(lhs,rhs)) {
-       return eq;
-      }
-
-      //if the extract of x[i:0] = t is entered into the solvermap,
-      //then also add another entry for x = x1@t
-      ASTNode var = lhs[0];
-      ASTNode newvar = NewVar(var.GetValueWidth() - lhs.GetValueWidth());
-      newvar = _bm->CreateTerm(BVCONCAT,var.GetValueWidth(),newvar,rhs);
-      _bm->UpdateSolverMap(var,newvar);      
-      output = ASTTrue;
-      break;
-    }
-    case BVMULT: {
-      //the input is of the form a*x = t. If 'a' is odd, then compute
-      //its multiplicative inverse a^-1, multiply 't' with it, and
-      //update the solver map
-      if(BVCONST != lhs[0].GetKind()) {
-       return eq;
-      }
-      
-      if(!(SYMBOL == lhs[1].GetKind() ||
-          (BVEXTRACT == lhs[1].GetKind() &&
-          SYMBOL == lhs[1][0].GetKind()))) {
-       return eq;
-      }
 
-      bool ChosenVar_Is_Extract = (BVEXTRACT == lhs[1].GetKind()) ? true : false;
+       switch (term.GetKind())
+       {
+               case READ:
+                       //an array read has been seen. Make an entry in the map and
+                       //return true
+                       TermsAlreadySeenMap[term] = ASTTrue;
+                       return true;
+               default:
+               {
+                       ASTVec c = term.GetChildren();
+                       for (ASTVec::iterator it = c.begin(), itend = c.end(); it != itend; it++)
+                       {
+                               if (CheckForArrayReads(*it))
+                               {
+                                       return true;
+                               }
+                       }
+                       break;
+               }
+       }
 
-      //if coeff is even, then we know that all the coeffs in the eqn
-      //are even. Simply return the eqn
-      if(!_bm->BVConstIsOdd(lhs[0])) {
-       return eq;
-      }
-
-      ASTNode a = _bm->MultiplicativeInverse(lhs[0]);
-      ASTNode chosenvar = (BVEXTRACT == lhs[1].GetKind()) ? lhs[1][0] : lhs[1];
-      ASTNode chosenvar_value = 
-       _bm->SimplifyTerm(_bm->CreateTerm(BVMULT,rhs.GetValueWidth(),a,rhs));
-      
-      //if chosenvar is seen in chosenvar_value then abort
-      if(_bm->VarSeenInTerm(chosenvar,chosenvar_value)) {
-       //abort solving
-       DoNotSolve_TheseVars.insert(lhs);
-       return eq;
-      }
-
-      //rhs should not have arrayreads in it. it complicates matters
-      //during transformation
-      // if(CheckForArrayReads_TopLevel(chosenvar_value)) {
-      //               return eq;
-      //       }
-            
-      //found a variable to solve
-      DoNotSolve_TheseVars.insert(chosenvar);
-      chosenvar = lhs[1];
-      if(!_bm->UpdateSolverMap(chosenvar,chosenvar_value)) {
-       return eq;
-      }
-
-      if(ChosenVar_Is_Extract) {
-       ASTNode var = lhs[1][0];
-       ASTNode newvar = NewVar(var.GetValueWidth() - lhs[1].GetValueWidth());
-       newvar = _bm->CreateTerm(BVCONCAT,var.GetValueWidth(),newvar,chosenvar_value);
-       _bm->UpdateSolverMap(var,newvar);
-      }
-      output = ASTTrue;
-      break;
-    }    
-    default:
-      output = eq;
-      break;
-    }
-    
-    UpdateAlreadySolvedMap(input,output);
-    return output;
-  } //end of BVSolve_Odd()
-
-  //Create a new variable of ValueWidth 'n'
-  ASTNode BVSolver::NewVar(unsigned int n) {
-    std:: string c("v");
-    char d[32];
-    sprintf(d,"%d",_symbol_count++);
-    std::string ccc(d);
-    c += "_solver_" + ccc;
-    
-    ASTNode CurrentSymbol = _bm->CreateSymbol(c.c_str());
-    CurrentSymbol.SetValueWidth(n);
-    CurrentSymbol.SetIndexWidth(0);
-    return CurrentSymbol;
-  } //end of NewVar()
-
-  //The toplevel bvsolver(). Checks if the formula has already been
-  //solved. If not, the solver() is invoked. If yes, then simply drop
-  //the formula
-  ASTNode BVSolver::TopLevelBVSolve(const ASTNode& input) {
-    if(!wordlevel_solve) {
-      return input;
-    }
-    
-    Kind k = input.GetKind();
-    if(!(EQ == k || AND == k)) {
-      return input;
-    }
-
-    ASTNode output = input;
-    if(CheckAlreadySolvedMap(input,output)) {
-      //output is TRUE. The formula is thus dropped
-      return output;
-    }
-    ASTVec o;
-    ASTVec c;
-    if(EQ == k) 
-      c.push_back(input);
-    else 
-      c = input.GetChildren();
-    ASTVec eveneqns;
-    ASTNode solved = ASTFalse;
-    for(ASTVec::iterator it = c.begin(), itend = c.end();it != itend;it++) { 
-      //_bm->ASTNodeStats("Printing before calling simplifyformula inside the solver:", *it);
-      ASTNode aaa = (ASTTrue == solved && EQ == it->GetKind()) ? _bm->SimplifyFormula(*it,false) : *it;
-      //ASTNode aaa = *it;
-      //_bm->ASTNodeStats("Printing after calling simplifyformula inside the solver:", aaa);
-      aaa = BVSolve_Odd(aaa);
-      //_bm->ASTNodeStats("Printing after oddsolver:", aaa);
-      bool even = false;
-      aaa = CheckEvenEqn(aaa, even);
-      if(even) {
-       eveneqns.push_back(aaa);
-      }
-      else {
-       if(ASTTrue != aaa) {
-         o.push_back(aaa);
+       //If control is here, then it means that no arrayread was seen for
+       //the input 'term'. Make an entry in the map with the term as key
+       //and FALSE as value.
+       TermsAlreadySeenMap[term] = ASTFalse;
+       return false;
+} //end of CheckForArrayReads()
+
+//check the solver map for 'key'. If key is present, then return the
+//value by reference in the argument 'output'
+bool BeevMgr::CheckSolverMap(const ASTNode& key, ASTNode& output)
+{
+       ASTNodeMap::iterator it;
+       if ((it = SolverMap.find(key)) != SolverMap.end())
+       {
+               output = it->second;
+               return true;
+       }
+       return false;
+} //end of CheckSolverMap()
+
+bool BeevMgr::CheckSolverMap(const ASTNode& key)
+{
+       if (SolverMap.find(key) != SolverMap.end())
+               return true;
+       else
+               return false;
+} //end of CheckSolverMap()
+
+//update solvermap with (key,value) pair
+bool BeevMgr::UpdateSolverMap(const ASTNode& key, const ASTNode& value)
+{
+       ASTNode var = (BVEXTRACT == key.GetKind()) ? key[0] : key;
+       if (!CheckSolverMap(var) && key != value)
+       {
+               SolverMap[key] = value;
+               return true;
+       }
+       return false;
+} //end of UpdateSolverMap()
+
+//collects the vars in the term 'lhs' into the multiset Vars
+void BVSolver::VarsInTheTerm_TopLevel(const ASTNode& lhs, ASTNodeMultiSet& Vars)
+{
+       TermsAlreadySeenMap.clear();
+       VarsInTheTerm(lhs, Vars);
+}
+
+//collects the vars in the term 'lhs' into the multiset Vars
+void BVSolver::VarsInTheTerm(const ASTNode& term, ASTNodeMultiSet& Vars)
+{
+       ASTNode a = term;
+       ASTNodeMap::iterator it;
+       if ((it = TermsAlreadySeenMap.find(term)) != TermsAlreadySeenMap.end())
+       {
+               //if the term has been seen, then simply return
+               return;
+       }
+
+       switch (term.GetKind())
+       {
+               case BVCONST:
+                       return;
+               case SYMBOL:
+                       //cerr << "debugging: symbol added: " << term << endl;
+                       Vars.insert(term);
+                       break;
+               case READ:
+                       //skip the arrayname, provided the arrayname is a SYMBOL
+                       if (SYMBOL == term[0].GetKind())
+                       {
+                               VarsInTheTerm(term[1], Vars);
+                       }
+                       else
+                       {
+                               VarsInTheTerm(term[0], Vars);
+                               VarsInTheTerm(term[1], Vars);
+                       }
+                       break;
+               default:
+               {
+                       ASTVec c = term.GetChildren();
+                       for (ASTVec::iterator it = c.begin(), itend = c.end(); it != itend; it++)
+                       {
+                               VarsInTheTerm(*it, Vars);
+                       }
+                       break;
+               }
+       }
+
+       //ensures that you don't double count. if you have seen the term
+       //once, then memoize
+       TermsAlreadySeenMap[term] = ASTTrue;
+       return;
+} //end of VarsInTheTerm()
+
+bool BVSolver::DoNotSolveThis(const ASTNode& var)
+{
+       if (DoNotSolve_TheseVars.find(var) != DoNotSolve_TheseVars.end())
+       {
+               return true;
+       }
+       return false;
+}
+
+//chooses a variable in the lhs and returns the chosen variable
+ASTNode BVSolver::ChooseMonom(const ASTNode& eq, ASTNode& modifiedlhs)
+{
+       if (!(EQ == eq.GetKind() && BVPLUS == eq[0].GetKind()))
+       {
+               FatalError("ChooseMonom: input must be a EQ", eq);
+       }
+
+       ASTNode lhs = eq[0];
+       ASTNode rhs = eq[1];
+       ASTNode zero = _bm->CreateZeroConst(32);
+
+       //collect all the vars in the lhs and rhs
+       ASTNodeMultiSet Vars;
+       VarsInTheTerm_TopLevel(lhs, Vars);
+
+       //handle BVPLUS case
+       ASTVec c = lhs.GetChildren();
+       ASTVec o;
+       ASTNode outmonom = _bm->CreateNode(UNDEFINED);
+       bool chosen_symbol = false;
+       bool chosen_odd = false;
+
+       //choose variables with no coeffs
+       for (ASTVec::iterator it = c.begin(), itend = c.end(); it != itend; it++)
+       {
+               ASTNode monom = *it;
+               if (SYMBOL == monom.GetKind() && Vars.count(monom) == 1 && !_bm->VarSeenInTerm(monom, rhs) && !DoNotSolveThis(monom) && !chosen_symbol)
+               {
+                       outmonom = monom;
+                       chosen_symbol = true;
+               }
+               else if (BVUMINUS == monom.GetKind() && SYMBOL == monom[0].GetKind() && Vars.count(monom[0]) == 1 && !DoNotSolveThis(monom[0])
+                               && !_bm->VarSeenInTerm(monom[0], rhs) && !chosen_symbol)
+               {
+                       //cerr << "Chosen Monom: " << monom << endl;
+                       outmonom = monom;
+                       chosen_symbol = true;
+               }
+               else
+               {
+                       o.push_back(monom);
+               }
+       }
+
+       //try to choose only odd coeffed variables first
+       if (!chosen_symbol)
+       {
+               o.clear();
+               for (ASTVec::iterator it = c.begin(), itend = c.end(); it != itend; it++)
+               {
+                       ASTNode monom = *it;
+                       ASTNode var = (BVMULT == monom.GetKind()) ? monom[1] : _bm->CreateNode(UNDEFINED);
+
+                       if (BVMULT == monom.GetKind() && BVCONST == monom[0].GetKind() && _bm->BVConstIsOdd(monom[0]) && ((SYMBOL == var.GetKind() && Vars.count(
+                                       var) == 1) || (BVEXTRACT == var.GetKind() && SYMBOL == var[0].GetKind() && BVCONST == var[1].GetKind() && zero == var[2]
+                                       && !_bm->VarSeenInTerm(var[0], rhs) && !DoNotSolveThis(var[0]))) && !DoNotSolveThis(var) && !_bm->VarSeenInTerm(var, rhs)
+                                       && !chosen_odd)
+                       {
+                               //monom[0] is odd.
+                               outmonom = monom;
+                               chosen_odd = true;
+                       }
+                       else
+                       {
+                               o.push_back(monom);
+                       }
+               }
+       }
+
+       modifiedlhs = (o.size() > 1) ? _bm->CreateTerm(BVPLUS, lhs.GetValueWidth(), o) : o[0];
+       return outmonom;
+} //end of choosemonom()
+
+//solver function which solves for variables with odd coefficient
+ASTNode BVSolver::BVSolve_Odd(const ASTNode& input)
+{
+       ASTNode eq = input;
+       //cerr << "Input to BVSolve_Odd()" << eq << endl;
+       if (!(wordlevel_solve && EQ == eq.GetKind()))
+       {
+               return input;
        }
-      }
-      solved = aaa;
-    }
-
-    ASTNode evens;
-    if(eveneqns.size() > 0) {
-      //if there is a system of even equations then solve them
-      evens = (eveneqns.size() > 1) ? _bm->CreateNode(AND,eveneqns) : eveneqns[0];
-      //evens = _bm->SimplifyFormula(evens,false);
-      evens = BVSolve_Even(evens);
-      _bm->ASTNodeStats("Printing after evensolver:", evens);
-    }
-    else {
-      evens = ASTTrue;
-    }
-    output = (o.size() > 0) ? ((o.size() > 1) ? _bm->CreateNode(AND,o) : o[0]) : ASTTrue;
-    output = _bm->CreateNode(AND,output,evens);
-
-    UpdateAlreadySolvedMap(input,output);
-    return output;
-  } //end of TopLevelBVSolve()
-
-  ASTNode BVSolver::CheckEvenEqn(const ASTNode& input, bool& evenflag) {
-    ASTNode eq = input;
-    //cerr << "Input to BVSolve_Odd()" << eq << endl;
-    if(!(wordlevel_solve && EQ == eq.GetKind())) {
-      evenflag = false;
-      return eq;
-    }
-
-    ASTNode lhs = eq[0];
-    ASTNode rhs = eq[1];
-    ASTNode zero = _bm->CreateZeroConst(rhs.GetValueWidth());
-    //lhs must be a BVPLUS, and rhs must be a BVCONST
-    if(!(BVPLUS == lhs.GetKind() && zero == rhs)) {
-      evenflag = false;
-      return eq;
-    }
-    
-    ASTVec lhs_c = lhs.GetChildren();
-    ASTNode savetheconst = rhs;
-    for(ASTVec::iterator it=lhs_c.begin(),itend=lhs_c.end();it!=itend;it++) {
-      ASTNode aaa = *it;
-      Kind itk = aaa.GetKind();
-
-      if(BVCONST == itk){
-       //check later if the constant is even or not
-       savetheconst = aaa;
-       continue;
-      }
-      
-      if(!(BVMULT == itk &&
-          BVCONST == aaa[0].GetKind() &&
-          SYMBOL == aaa[1].GetKind() &&
-          !_bm->BVConstIsOdd(aaa[0]))) {
-       //If the monomials of the lhs are NOT of the form 'a*x' where
-       //'a' is even, then return the false
-       evenflag = false;
+
+       ASTNode output = input;
+       if (CheckAlreadySolvedMap(input, output))
+       {
+               return output;
+       }
+
+       //get the lhs and the rhs, and case-split on the lhs kind
+       ASTNode lhs = eq[0];
+       ASTNode rhs = eq[1];
+       if (BVPLUS == lhs.GetKind())
+       {
+               ASTNode chosen_monom = _bm->CreateNode(UNDEFINED);
+               ASTNode leftover_lhs;
+
+               //choose monom makes sure that it gets only those vars that
+               //occur exactly once in lhs and rhs put together
+               chosen_monom = ChooseMonom(eq, leftover_lhs);
+               if (chosen_monom == _bm->CreateNode(UNDEFINED))
+               {
+                       //no monomial was chosen
+                       return eq;
+               }
+
+               //if control is here then it means that a monom was chosen
+               //
+               //construct:  rhs - (lhs without the chosen monom)
+               unsigned int len = lhs.GetValueWidth();
+               leftover_lhs = _bm->SimplifyTerm_TopLevel(_bm->CreateTerm(BVUMINUS, len, leftover_lhs));
+               ASTNode newrhs = _bm->SimplifyTerm(_bm->CreateTerm(BVPLUS, len, rhs, leftover_lhs));
+               lhs = chosen_monom;
+               rhs = newrhs;
+       } //end of if(BVPLUS ...)
+
+       if (BVUMINUS == lhs.GetKind())
+       {
+               //equation is of the form (-lhs0) = rhs
+               ASTNode lhs0 = lhs[0];
+               rhs = _bm->SimplifyTerm(_bm->CreateTerm(BVUMINUS, rhs.GetValueWidth(), rhs));
+               lhs = lhs0;
+       }
+
+       switch (lhs.GetKind())
+       {
+               case SYMBOL:
+               {
+                       //input is of the form x = rhs first make sure that the lhs
+                       //symbol does not occur on the rhs or that it has not been
+                       //solved for
+                       if (_bm->VarSeenInTerm(lhs, rhs))
+                       {
+                               //found the lhs in the rhs. Abort!
+                               DoNotSolve_TheseVars.insert(lhs);
+                               return eq;
+                       }
+
+                       //rhs should not have arrayreads in it. it complicates matters
+                       //during transformation
+                       // if(CheckForArrayReads_TopLevel(rhs)) {
+                       //              return eq;
+                       //       }
+
+                       DoNotSolve_TheseVars.insert(lhs);
+                       if (!_bm->UpdateSolverMap(lhs, rhs))
+                       {
+                               return eq;
+                       }
+
+                       output = ASTTrue;
+                       break;
+               }
+               case BVEXTRACT:
+               {
+                       ASTNode zero = _bm->CreateZeroConst(32);
+
+                       if (!(SYMBOL == lhs[0].GetKind() && BVCONST == lhs[1].GetKind() && zero == lhs[2] && !_bm->VarSeenInTerm(lhs[0], rhs) && !DoNotSolveThis(
+                                       lhs[0])))
+                       {
+                               return eq;
+                       }
+
+                       if (_bm->VarSeenInTerm(lhs[0], rhs))
+                       {
+                               DoNotSolve_TheseVars.insert(lhs[0]);
+                               return eq;
+                       }
+
+                       DoNotSolve_TheseVars.insert(lhs[0]);
+                       if (!_bm->UpdateSolverMap(lhs, rhs))
+                       {
+                               return eq;
+                       }
+
+                       //if the extract of x[i:0] = t is entered into the solvermap,
+                       //then also add another entry for x = x1@t
+                       ASTNode var = lhs[0];
+                       ASTNode newvar = NewVar(var.GetValueWidth() - lhs.GetValueWidth());
+                       newvar = _bm->CreateTerm(BVCONCAT, var.GetValueWidth(), newvar, rhs);
+                       _bm->UpdateSolverMap(var, newvar);
+                       output = ASTTrue;
+                       break;
+               }
+               case BVMULT:
+               {
+                       //the input is of the form a*x = t. If 'a' is odd, then compute
+                       //its multiplicative inverse a^-1, multiply 't' with it, and
+                       //update the solver map
+                       if (BVCONST != lhs[0].GetKind())
+                       {
+                               return eq;
+                       }
+
+                       if (!(SYMBOL == lhs[1].GetKind() || (BVEXTRACT == lhs[1].GetKind() && SYMBOL == lhs[1][0].GetKind())))
+                       {
+                               return eq;
+                       }
+
+                       bool ChosenVar_Is_Extract = (BVEXTRACT == lhs[1].GetKind()) ? true : false;
+
+                       //if coeff is even, then we know that all the coeffs in the eqn
+                       //are even. Simply return the eqn
+                       if (!_bm->BVConstIsOdd(lhs[0]))
+                       {
+                               return eq;
+                       }
+
+                       ASTNode a = _bm->MultiplicativeInverse(lhs[0]);
+                       ASTNode chosenvar = (BVEXTRACT == lhs[1].GetKind()) ? lhs[1][0] : lhs[1];
+                       ASTNode chosenvar_value = _bm->SimplifyTerm(_bm->CreateTerm(BVMULT, rhs.GetValueWidth(), a, rhs));
+
+                       //if chosenvar is seen in chosenvar_value then abort
+                       if (_bm->VarSeenInTerm(chosenvar, chosenvar_value))
+                       {
+                               //abort solving
+                               DoNotSolve_TheseVars.insert(lhs);
+                               return eq;
+                       }
+
+                       //rhs should not have arrayreads in it. it complicates matters
+                       //during transformation
+                       // if(CheckForArrayReads_TopLevel(chosenvar_value)) {
+                       //              return eq;
+                       //       }
+
+                       //found a variable to solve
+                       DoNotSolve_TheseVars.insert(chosenvar);
+                       chosenvar = lhs[1];
+                       if (!_bm->UpdateSolverMap(chosenvar, chosenvar_value))
+                       {
+                               return eq;
+                       }
+
+                       if (ChosenVar_Is_Extract)
+                       {
+                               ASTNode var = lhs[1][0];
+                               ASTNode newvar = NewVar(var.GetValueWidth() - lhs[1].GetValueWidth());
+                               newvar = _bm->CreateTerm(BVCONCAT, var.GetValueWidth(), newvar, chosenvar_value);
+                               _bm->UpdateSolverMap(var, newvar);
+                       }
+                       output = ASTTrue;
+                       break;
+               }
+               default:
+                       output = eq;
+                       break;
+       }
+
+       UpdateAlreadySolvedMap(input, output);
+       return output;
+} //end of BVSolve_Odd()
+
+//Create a new variable of ValueWidth 'n'
+ASTNode BVSolver::NewVar(unsigned int n)
+{
+       std::string c("v");
+       char d[32];
+       sprintf(d, "%d", _symbol_count++);
+       std::string ccc(d);
+       c += "_solver_" + ccc;
+
+       ASTNode CurrentSymbol = _bm->CreateSymbol(c.c_str());
+       CurrentSymbol.SetValueWidth(n);
+       CurrentSymbol.SetIndexWidth(0);
+       return CurrentSymbol;
+} //end of NewVar()
+
+//The toplevel bvsolver(). Checks if the formula has already been
+//solved. If not, the solver() is invoked. If yes, then simply drop
+//the formula
+ASTNode BVSolver::TopLevelBVSolve(const ASTNode& input)
+{
+       if (!wordlevel_solve)
+       {
+               return input;
+       }
+
+       Kind k = input.GetKind();
+       if (!(EQ == k || AND == k))
+       {
+               return input;
+       }
+
+       ASTNode output = input;
+       if (CheckAlreadySolvedMap(input, output))
+       {
+               //output is TRUE. The formula is thus dropped
+               return output;
+       }
+       ASTVec o;
+       ASTVec c;
+       if (EQ == k)
+               c.push_back(input);
+       else
+               c = input.GetChildren();
+       ASTVec eveneqns;
+       ASTNode solved = ASTFalse;
+       for (ASTVec::iterator it = c.begin(), itend = c.end(); it != itend; it++)
+       {
+               //_bm->ASTNodeStats("Printing before calling simplifyformula inside the solver:", *it);
+               ASTNode aaa = (ASTTrue == solved && EQ == it->GetKind()) ? _bm->SimplifyFormula(*it, false) : *it;
+               //ASTNode aaa = *it;
+               //_bm->ASTNodeStats("Printing after calling simplifyformula inside the solver:", aaa);
+               aaa = BVSolve_Odd(aaa);
+               //_bm->ASTNodeStats("Printing after oddsolver:", aaa);
+               bool even = false;
+               aaa = CheckEvenEqn(aaa, even);
+               if (even)
+               {
+                       eveneqns.push_back(aaa);
+               }
+               else
+               {
+                       if (ASTTrue != aaa)
+                       {
+                               o.push_back(aaa);
+                       }
+               }
+               solved = aaa;
+       }
+
+       ASTNode evens;
+       if (eveneqns.size() > 0)
+       {
+               //if there is a system of even equations then solve them
+               evens = (eveneqns.size() > 1) ? _bm->CreateNode(AND, eveneqns) : eveneqns[0];
+               //evens = _bm->SimplifyFormula(evens,false);
+               evens = BVSolve_Even(evens);
+               _bm->ASTNodeStats("Printing after evensolver:", evens);
+       }
+       else
+       {
+               evens = ASTTrue;
+       }
+       output = (o.size() > 0) ? ((o.size() > 1) ? _bm->CreateNode(AND, o) : o[0]) : ASTTrue;
+       output = _bm->CreateNode(AND, output, evens);
+
+       UpdateAlreadySolvedMap(input, output);
+       return output;
+} //end of TopLevelBVSolve()
+
+ASTNode BVSolver::CheckEvenEqn(const ASTNode& input, bool& evenflag)
+{
+       ASTNode eq = input;
+       //cerr << "Input to BVSolve_Odd()" << eq << endl;
+       if (!(wordlevel_solve && EQ == eq.GetKind()))
+       {
+               evenflag = false;
+               return eq;
+       }
+
+       ASTNode lhs = eq[0];
+       ASTNode rhs = eq[1];
+       ASTNode zero = _bm->CreateZeroConst(rhs.GetValueWidth());
+       //lhs must be a BVPLUS, and rhs must be a BVCONST
+       if (!(BVPLUS == lhs.GetKind() && zero == rhs))
+       {
+               evenflag = false;
+               return eq;
+       }
+
+       ASTVec lhs_c = lhs.GetChildren();
+       ASTNode savetheconst = rhs;
+       for (ASTVec::iterator it = lhs_c.begin(), itend = lhs_c.end(); it != itend; it++)
+       {
+               ASTNode aaa = *it;
+               Kind itk = aaa.GetKind();
+
+               if (BVCONST == itk)
+               {
+                       //check later if the constant is even or not
+                       savetheconst = aaa;
+                       continue;
+               }
+
+               if (!(BVMULT == itk && BVCONST == aaa[0].GetKind() && SYMBOL == aaa[1].GetKind() && !_bm->BVConstIsOdd(aaa[0])))
+               {
+                       //If the monomials of the lhs are NOT of the form 'a*x' where
+                       //'a' is even, then return the false
+                       evenflag = false;
+                       return eq;
+               }
+       }//end of for loop
+
+       //if control is here then it means that all coeffs are even. the
+       //only remaining thing is to check if the constant is even or not
+       if (_bm->BVConstIsOdd(savetheconst))
+       {
+               //the constant turned out to be odd. we have UNSAT eqn
+               evenflag = false;
+               return ASTFalse;
+       }
+
+       //all is clear. the eqn in even, through and through
+       evenflag = true;
        return eq;
-      }  
-    }//end of for loop
-
-    //if control is here then it means that all coeffs are even. the
-    //only remaining thing is to check if the constant is even or not
-    if(_bm->BVConstIsOdd(savetheconst)) {
-      //the constant turned out to be odd. we have UNSAT eqn
-      evenflag = false;
-      return ASTFalse;
-    }
-    
-    //all is clear. the eqn in even, through and through
-    evenflag = true;
-    return eq;
-  } //end of CheckEvenEqn
-
-  //solve an eqn whose monomials have only even coefficients
-  ASTNode BVSolver::BVSolve_Even(const ASTNode& input) {
-    if(!wordlevel_solve) {
-      return input;
-    }
-
-    if(!(EQ == input.GetKind() || AND == input.GetKind())) {
-      return input;
-    }
-
-    ASTNode output;
-    if(CheckAlreadySolvedMap(input,output)) {
-      return output;
-    }
-
-    ASTVec input_c;
-    if(EQ == input.GetKind()) {
-      input_c.push_back(input);
-    }
-    else {
-      input_c = input.GetChildren();
-    }
-
-    //power_of_2 holds the exponent of 2 in the coeff
-    unsigned int power_of_2 = 0;
-    //we need this additional variable to find the lowest power of 2
-    unsigned int power_of_2_lowest = 0xffffffff;
-    //the monom which has the least power of 2 in the coeff
-    ASTNode monom_with_best_coeff;
-    for(ASTVec::iterator jt=input_c.begin(),jtend=input_c.end();jt!=jtend;jt++) {
-      ASTNode eq = *jt;
-      ASTNode lhs = eq[0];
-      ASTNode rhs = eq[1];
-      ASTNode zero = _bm->CreateZeroConst(rhs.GetValueWidth());
-      //lhs must be a BVPLUS, and rhs must be a BVCONST
-      if(!(BVPLUS == lhs.GetKind() && zero == rhs)) {
-       return input;
-      }
-    
-      ASTVec lhs_c = lhs.GetChildren();
-      ASTNode odd;
-      for(ASTVec::iterator it=lhs_c.begin(),itend=lhs_c.end();it!=itend;it++) {
-       ASTNode aaa = *it;
-       Kind itk = aaa.GetKind();
-       if(!(BVCONST == itk &&
-            !_bm->BVConstIsOdd(aaa)) &&
-          !(BVMULT == itk &&
-            BVCONST == aaa[0].GetKind() &&
-            SYMBOL == aaa[1].GetKind() &&
-            !_bm->BVConstIsOdd(aaa[0]))) {
-         //If the monomials of the lhs are NOT of the form 'a*x' or 'a'
-         //where 'a' is even, then return the eqn
-         return input;
+} //end of CheckEvenEqn
+
+//solve an eqn whose monomials have only even coefficients
+ASTNode BVSolver::BVSolve_Even(const ASTNode& input)
+{
+       if (!wordlevel_solve)
+       {
+               return input;
+       }
+
+       if (!(EQ == input.GetKind() || AND == input.GetKind()))
+       {
+               return input;
        }
-       
-       //we are gauranteed that if control is here then the monomial is
-       //of the form 'a*x' or 'a', where 'a' is even
-       ASTNode coeff = (BVCONST == itk) ? aaa : aaa[0];
-       odd = SplitEven_into_Oddnum_PowerOf2(coeff,power_of_2);
-       if(power_of_2  < power_of_2_lowest) {
-         power_of_2_lowest = power_of_2;
-         monom_with_best_coeff = aaa;
+
+       ASTNode output;
+       if (CheckAlreadySolvedMap(input, output))
+       {
+               return output;
        }
-       power_of_2 = 0;
-      }//end of inner for loop
-    } //end of outer for loop    
-
-    //get the exponent
-    power_of_2 = power_of_2_lowest;
-    
-    //if control is here, we are gauranteed that we have chosen a
-    //monomial with fewest powers of 2
-    ASTVec formula_out;
-    for(ASTVec::iterator jt=input_c.begin(),jtend=input_c.end();jt!=jtend;jt++) {
-      ASTNode eq = *jt;      
-      ASTNode lhs = eq[0];
-      ASTNode rhs = eq[1];
-      ASTNode zero = _bm->CreateZeroConst(rhs.GetValueWidth());
-      //lhs must be a BVPLUS, and rhs must be a BVCONST
-      if(!(BVPLUS == lhs.GetKind() && zero == rhs)) {
-       return input;
-      }
-      
-      unsigned len = lhs.GetValueWidth();
-      ASTNode hi = _bm->CreateBVConst(32,len-1);
-      ASTNode low = _bm->CreateBVConst(32,len - power_of_2);
-      ASTNode low_minus_one = _bm->CreateBVConst(32,len - power_of_2 - 1);
-      ASTNode low_zero = _bm->CreateZeroConst(32);
-      unsigned newlen = len - power_of_2;
-      ASTNode two_const = _bm->CreateTwoConst(len);
-
-      unsigned count = power_of_2;
-      ASTNode two = two_const;
-      while(--count) {
-       two = _bm->BVConstEvaluator(_bm->CreateTerm(BVMULT,len,two_const,two));
-      }
-      ASTVec lhs_c = lhs.GetChildren();
-      ASTVec lhs_out;
-      for(ASTVec::iterator it=lhs_c.begin(),itend=lhs_c.end();it!=itend;it++) {
-       ASTNode aaa = *it;
-       Kind itk = aaa.GetKind();
-       if(BVCONST == itk) {
-         aaa = _bm->BVConstEvaluator(_bm->CreateTerm(BVDIV,len,aaa,two));
-         aaa = _bm->BVConstEvaluator(_bm->CreateTerm(BVEXTRACT,newlen,aaa,low_minus_one,low_zero));
+
+       ASTVec input_c;
+       if (EQ == input.GetKind())
+       {
+               input_c.push_back(input);
        }
-       else {
-         //it must be of the form a*x
-         ASTNode coeff = _bm->BVConstEvaluator(_bm->CreateTerm(BVDIV,len,aaa[0],two));
-         coeff = _bm->BVConstEvaluator(_bm->CreateTerm(BVEXTRACT,newlen,coeff,low_minus_one,low_zero));
-         ASTNode upper_x, lower_x;
-         //upper_x = _bm->SimplifyTerm(_bm->CreateTerm(BVEXTRACT, power_of_2, aaa[1], hi, low));
-         lower_x = _bm->SimplifyTerm(_bm->CreateTerm(BVEXTRACT, newlen,aaa[1],low_minus_one,low_zero));
-         aaa = _bm->CreateTerm(BVMULT,newlen,coeff,lower_x);
+       else
+       {
+               input_c = input.GetChildren();
        }
-       lhs_out.push_back(aaa);
-      }//end of inner forloop()
-      rhs = _bm->CreateZeroConst(newlen);
-      lhs = _bm->CreateTerm(BVPLUS,newlen,lhs_out);     
-      formula_out.push_back(_bm->CreateSimplifiedEQ(lhs,rhs));
-    } //end of outer forloop()
-
-    output = 
-      (formula_out.size() > 0) ? (formula_out.size() > 1) ? _bm->CreateNode(AND,formula_out) : formula_out[0] : ASTTrue;
-
-    UpdateAlreadySolvedMap(input,output);
-    return output;
-  } //end of BVSolve_Even()
-};//end of namespace BEEV
+
+       //power_of_2 holds the exponent of 2 in the coeff
+       unsigned int power_of_2 = 0;
+       //we need this additional variable to find the lowest power of 2
+       unsigned int power_of_2_lowest = 0xffffffff;
+       //the monom which has the least power of 2 in the coeff
+       ASTNode monom_with_best_coeff;
+       for (ASTVec::iterator jt = input_c.begin(), jtend = input_c.end(); jt != jtend; jt++)
+       {
+               ASTNode eq = *jt;
+               ASTNode lhs = eq[0];
+               ASTNode rhs = eq[1];
+               ASTNode zero = _bm->CreateZeroConst(rhs.GetValueWidth());
+               //lhs must be a BVPLUS, and rhs must be a BVCONST
+               if (!(BVPLUS == lhs.GetKind() && zero == rhs))
+               {
+                       return input;
+               }
+
+               ASTVec lhs_c = lhs.GetChildren();
+               ASTNode odd;
+               for (ASTVec::iterator it = lhs_c.begin(), itend = lhs_c.end(); it != itend; it++)
+               {
+                       ASTNode aaa = *it;
+                       Kind itk = aaa.GetKind();
+                       if (!(BVCONST == itk && !_bm->BVConstIsOdd(aaa)) && !(BVMULT == itk && BVCONST == aaa[0].GetKind() && SYMBOL == aaa[1].GetKind()
+                                       && !_bm->BVConstIsOdd(aaa[0])))
+                       {
+                               //If the monomials of the lhs are NOT of the form 'a*x' or 'a'
+                               //where 'a' is even, then return the eqn
+                               return input;
+                       }
+
+                       //we are gauranteed that if control is here then the monomial is
+                       //of the form 'a*x' or 'a', where 'a' is even
+                       ASTNode coeff = (BVCONST == itk) ? aaa : aaa[0];
+                       odd = SplitEven_into_Oddnum_PowerOf2(coeff, power_of_2);
+                       if (power_of_2 < power_of_2_lowest)
+                       {
+                               power_of_2_lowest = power_of_2;
+                               monom_with_best_coeff = aaa;
+                       }
+                       power_of_2 = 0;
+               }//end of inner for loop
+       } //end of outer for loop
+
+       //get the exponent
+       power_of_2 = power_of_2_lowest;
+
+       //if control is here, we are gauranteed that we have chosen a
+       //monomial with fewest powers of 2
+       ASTVec formula_out;
+       for (ASTVec::iterator jt = input_c.begin(), jtend = input_c.end(); jt != jtend; jt++)
+       {
+               ASTNode eq = *jt;
+               ASTNode lhs = eq[0];
+               ASTNode rhs = eq[1];
+               ASTNode zero = _bm->CreateZeroConst(rhs.GetValueWidth());
+               //lhs must be a BVPLUS, and rhs must be a BVCONST
+               if (!(BVPLUS == lhs.GetKind() && zero == rhs))
+               {
+                       return input;
+               }
+
+               unsigned len = lhs.GetValueWidth();
+               ASTNode hi = _bm->CreateBVConst(32, len - 1);
+               ASTNode low = _bm->CreateBVConst(32, len - power_of_2);
+               ASTNode low_minus_one = _bm->CreateBVConst(32, len - power_of_2 - 1);
+               ASTNode low_zero = _bm->CreateZeroConst(32);
+               unsigned newlen = len - power_of_2;
+               ASTNode two_const = _bm->CreateTwoConst(len);
+
+               unsigned count = power_of_2;
+               ASTNode two = two_const;
+               while (--count)
+               {
+                       two = _bm->BVConstEvaluator(_bm->CreateTerm(BVMULT, len, two_const, two));
+               }
+               ASTVec lhs_c = lhs.GetChildren();
+               ASTVec lhs_out;
+               for (ASTVec::iterator it = lhs_c.begin(), itend = lhs_c.end(); it != itend; it++)
+               {
+                       ASTNode aaa = *it;
+                       Kind itk = aaa.GetKind();
+                       if (BVCONST == itk)
+                       {
+                               aaa = _bm->BVConstEvaluator(_bm->CreateTerm(BVDIV, len, aaa, two));
+                               aaa = _bm->BVConstEvaluator(_bm->CreateTerm(BVEXTRACT, newlen, aaa, low_minus_one, low_zero));
+                       }
+                       else
+                       {
+                               //it must be of the form a*x
+                               ASTNode coeff = _bm->BVConstEvaluator(_bm->CreateTerm(BVDIV, len, aaa[0], two));
+                               coeff = _bm->BVConstEvaluator(_bm->CreateTerm(BVEXTRACT, newlen, coeff, low_minus_one, low_zero));
+                               ASTNode upper_x, lower_x;
+                               //upper_x = _bm->SimplifyTerm(_bm->CreateTerm(BVEXTRACT, power_of_2, aaa[1], hi, low));
+                               lower_x = _bm->SimplifyTerm(_bm->CreateTerm(BVEXTRACT, newlen, aaa[1], low_minus_one, low_zero));
+                               aaa = _bm->CreateTerm(BVMULT, newlen, coeff, lower_x);
+                       }
+                       lhs_out.push_back(aaa);
+               }//end of inner forloop()
+               rhs = _bm->CreateZeroConst(newlen);
+               lhs = _bm->CreateTerm(BVPLUS, newlen, lhs_out);
+               formula_out.push_back(_bm->CreateSimplifiedEQ(lhs, rhs));
+       } //end of outer forloop()
+
+       output = (formula_out.size() > 0) ? (formula_out.size() > 1) ? _bm->CreateNode(AND, formula_out) : formula_out[0] : ASTTrue;
+
+       UpdateAlreadySolvedMap(input, output);
+       return output;
+} //end of BVSolve_Even()
+}
+;//end of namespace BEEV
index bb76718f91cf7b7619f3b49ff653c6544f6fd8d4..c19b52973a5898f55de6762bc00beb4f498fd2c2 100644 (file)
 
 #include "../AST/AST.h"
 #include "../AST/ASTUtil.h"
-namespace BEEV {
-
-  //This class represents the bitvector arithmetic linear solver.
-  //
-  //The bitvector solver is a partial solver, i.e. it does not solve
-  //for all variables in the system of equations. it is
-  //best-effort. it relies on the SAT solver to be complete.
-  //
-  //The BVSolver assumes that the input equations are normalized, and
-  //have liketerms combined etc.
-  //
-  //0. Traverse top-down over the input DAG, looking for a conjunction
-  //0. of equations. if you find one, then for each equation in the
-  //0. conjunction, do the following steps.
-  //
-  //1. check for Linearity of the input equation
-  //
-  //2. Solve for a "chosen" variable. The variable should occur
-  //2. exactly once and must have an odd coeff. Refer STP's CAV 2007
-  //2. paper for actual solving procedure
-  //
-  //4. Outside the solver, Substitute and Re-normalize the input DAG 
-  class BVSolver {
-    //Ptr to toplevel manager that manages bit-vector expressions
-    //(i.e. construct various kinds of expressions), and also has
-    //member functions that simplify bit-vector expressions
-    BeevMgr * _bm;
-    ASTNode ASTTrue, ASTFalse;
-
-    //Those formulas which have already been solved. If the same
-    //formula occurs twice then do not solve the second occurence, and
-    //instead drop it
-    ASTNodeMap FormulasAlreadySolvedMap;
-
-    //this map is useful while traversing terms and uniquely
-    //identifying variables in the those terms. Prevents double
-    //counting.
-    ASTNodeMap TermsAlreadySeenMap;
-    ASTNodeMap TermsAlreadySeenMap_ForArrays;
-
-    //count is used in the creation of new variables
-    unsigned int _symbol_count;
-
-    //solved variables list: If a variable has been solved for then do
-    //not solve for it again
-    ASTNodeSet DoNotSolve_TheseVars;
-
-    //checks if var has been solved for or not. if yes, then return
-    //true else return false
-    bool DoNotSolveThis(const ASTNode& var);
-
-    //traverses a term, and creates a multiset of all variables in the
-    //term. Does memoization to avoid double counting.
-    void VarsInTheTerm(const ASTNode& lhs, ASTNodeMultiSet& v);
-    void VarsInTheTerm_TopLevel(const ASTNode& lhs, ASTNodeMultiSet& v);
-
-    //choose a suitable var from the term
-    ASTNode ChooseMonom(const ASTNode& eq, ASTNode& modifiedterm);
-    //accepts an equation and solves for a variable or a monom in it
-    ASTNode BVSolve_Odd(const ASTNode& eq);
-
-    //solves equations of the form a*x=t where 'a' is even. Has a
-    //return value, unlike the normal BVSolve()
-    ASTNode BVSolve_Even(const ASTNode& eq);
-    ASTNode CheckEvenEqn(const ASTNode& input, bool& evenflag);
-
-    //Checks for arrayreads in a term. if yes then returns true, else
-    //return false
-    bool CheckForArrayReads(const ASTNode& term);
-    bool CheckForArrayReads_TopLevel(const ASTNode& term);
-
-    //Creates new variables used in solving
-    ASTNode NewVar(unsigned int n);
-
-    //this function return true if the var occurs in term, else the
-    //function returns false
-    bool VarSeenInTerm(const ASTNode& var, const ASTNode& term);
-    
-    //takes an even number "in" as input, and returns an odd number
-    //(return value) and a power of 2 (as number_shifts by reference),
-    //such that in = (odd_number * power_of_2).
-    //
-    //Refer STP's CAV 2007 (or Clark Barrett's 1998 paper on
-    //bit-vector arithmetic published in DAC 1998) paper for precise
-    //understanding of the algorithm
-    ASTNode SplitEven_into_Oddnum_PowerOf2(const ASTNode& in, unsigned int& number_shifts);
-
-    //Once a formula has been solved, then update the alreadysolvedmap
-    //with the formula, and the solved value. The solved value can be
-    //described using the following example: Suppose input to the
-    //solver is
-    //
-    // input key: x = 2 AND y = x + t
-    //
-    // output value: y = 2 + t
-    void UpdateAlreadySolvedMap(const ASTNode& key, const ASTNode& value);
-
-    //This function checks if the key (formula) has already been
-    //solved for.
-    //
-    //If yes it returns TRUE and fills the "output" with the
-    //solved-value (call by reference argument),
-    //
-    //else returns FALSE
-    bool CheckAlreadySolvedMap(const ASTNode& key, ASTNode& output);
-  public:
-    //constructor
-    BVSolver(BeevMgr * bm) : _bm(bm), _symbol_count(0) {
-      ASTTrue = _bm->CreateNode(TRUE);
-      ASTFalse = _bm->CreateNode(FALSE);
-    };
-
-    //Destructor
-    ~BVSolver() {
-      TermsAlreadySeenMap.clear();
-      DoNotSolve_TheseVars.clear();
-      FormulasAlreadySolvedMap.clear();
-      TermsAlreadySeenMap_ForArrays.clear();
-    }
-
-    //Top Level Solver: Goes over the input DAG, identifies the
-    //equation to be solved, solves them,
-    ASTNode TopLevelBVSolve(const ASTNode& a);
-  }; //end of class bvsolver
-};//end of namespace BEEV
+namespace BEEV
+{
+
+//This class represents the bitvector arithmetic linear solver.
+//
+//The bitvector solver is a partial solver, i.e. it does not solve
+//for all variables in the system of equations. it is
+//best-effort. it relies on the SAT solver to be complete.
+//
+//The BVSolver assumes that the input equations are normalized, and
+//have liketerms combined etc.
+//
+//0. Traverse top-down over the input DAG, looking for a conjunction
+//0. of equations. if you find one, then for each equation in the
+//0. conjunction, do the following steps.
+//
+//1. check for Linearity of the input equation
+//
+//2. Solve for a "chosen" variable. The variable should occur
+//2. exactly once and must have an odd coeff. Refer STP's CAV 2007
+//2. paper for actual solving procedure
+//
+//4. Outside the solver, Substitute and Re-normalize the input DAG
+class BVSolver
+{
+       //Ptr to toplevel manager that manages bit-vector expressions
+       //(i.e. construct various kinds of expressions), and also has
+       //member functions that simplify bit-vector expressions
+       BeevMgr * _bm;
+       ASTNode ASTTrue, ASTFalse;
+
+       //Those formulas which have already been solved. If the same
+       //formula occurs twice then do not solve the second occurence, and
+       //instead drop it
+       ASTNodeMap FormulasAlreadySolvedMap;
+
+       //this map is useful while traversing terms and uniquely
+       //identifying variables in the those terms. Prevents double
+       //counting.
+       ASTNodeMap TermsAlreadySeenMap;
+       ASTNodeMap TermsAlreadySeenMap_ForArrays;
+
+       //count is used in the creation of new variables
+       unsigned int _symbol_count;
+
+       //solved variables list: If a variable has been solved for then do
+       //not solve for it again
+       ASTNodeSet DoNotSolve_TheseVars;
+
+       //checks if var has been solved for or not. if yes, then return
+       //true else return false
+       bool DoNotSolveThis(const ASTNode& var);
+
+       //traverses a term, and creates a multiset of all variables in the
+       //term. Does memoization to avoid double counting.
+       void VarsInTheTerm(const ASTNode& lhs, ASTNodeMultiSet& v);
+       void VarsInTheTerm_TopLevel(const ASTNode& lhs, ASTNodeMultiSet& v);
+
+       //choose a suitable var from the term
+       ASTNode ChooseMonom(const ASTNode& eq, ASTNode& modifiedterm);
+       //accepts an equation and solves for a variable or a monom in it
+       ASTNode BVSolve_Odd(const ASTNode& eq);
+
+       //solves equations of the form a*x=t where 'a' is even. Has a
+       //return value, unlike the normal BVSolve()
+       ASTNode BVSolve_Even(const ASTNode& eq);
+       ASTNode CheckEvenEqn(const ASTNode& input, bool& evenflag);
+
+       //Checks for arrayreads in a term. if yes then returns true, else
+       //return false
+       bool CheckForArrayReads(const ASTNode& term);
+       bool CheckForArrayReads_TopLevel(const ASTNode& term);
+
+       //Creates new variables used in solving
+       ASTNode NewVar(unsigned int n);
+
+       //this function return true if the var occurs in term, else the
+       //function returns false
+       bool VarSeenInTerm(const ASTNode& var, const ASTNode& term);
+
+       //takes an even number "in" as input, and returns an odd number
+       //(return value) and a power of 2 (as number_shifts by reference),
+       //such that in = (odd_number * power_of_2).
+       //
+       //Refer STP's CAV 2007 (or Clark Barrett's 1998 paper on
+       //bit-vector arithmetic published in DAC 1998) paper for precise
+       //understanding of the algorithm
+       ASTNode SplitEven_into_Oddnum_PowerOf2(const ASTNode& in, unsigned int& number_shifts);
+
+       //Once a formula has been solved, then update the alreadysolvedmap
+       //with the formula, and the solved value. The solved value can be
+       //described using the following example: Suppose input to the
+       //solver is
+       //
+       // input key: x = 2 AND y = x + t
+       //
+       // output value: y = 2 + t
+       void UpdateAlreadySolvedMap(const ASTNode& key, const ASTNode& value);
+
+       //This function checks if the key (formula) has already been
+       //solved for.
+       //
+       //If yes it returns TRUE and fills the "output" with the
+       //solved-value (call by reference argument),
+       //
+       //else returns FALSE
+       bool CheckAlreadySolvedMap(const ASTNode& key, ASTNode& output);
+public:
+       //constructor
+       BVSolver(BeevMgr * bm) :
+               _bm(bm), _symbol_count(0)
+       {
+               ASTTrue = _bm->CreateNode(TRUE);
+               ASTFalse = _bm->CreateNode(FALSE);
+       }
+       ;
+
+       //Destructor
+       ~BVSolver()
+       {
+               TermsAlreadySeenMap.clear();
+               DoNotSolve_TheseVars.clear();
+               FormulasAlreadySolvedMap.clear();
+               TermsAlreadySeenMap_ForArrays.clear();
+       }
+
+       //Top Level Solver: Goes over the input DAG, identifies the
+       //equation to be solved, solves them,
+       ASTNode TopLevelBVSolve(const ASTNode& a);
+}; //end of class bvsolver
+}
+;//end of namespace BEEV
index d1406a5c649206fc10ecd994fe14f33c3f328ab2..77c374fd6af7176c35b0b30800ab2557e4830f78 100644 (file)
 
 #include "../AST/AST.h"
 #include "../AST/ASTUtil.h"
-namespace BEEV {
-
-  bool BeevMgr::CheckSimplifyMap(const ASTNode& key,
-                                ASTNode& output, bool pushNeg) {
-    ASTNodeMap::iterator it, itend;
-    it = pushNeg ? SimplifyNegMap->find(key) : SimplifyMap->find(key);
-    itend = pushNeg ? SimplifyNegMap->end() : SimplifyMap->end();
-
-    if(it != itend) {
-      output = it->second;
-      CountersAndStats("Successful_CheckSimplifyMap");
-      return true;
-    }
-
-    if(pushNeg && (it = SimplifyMap->find(key)) != SimplifyMap->end()) {
-      output =
-       (ASTFalse == it->second) ?
-       ASTTrue :
-       (ASTTrue == it->second) ? ASTFalse : CreateNode(NOT, it->second);
-      CountersAndStats("2nd_Successful_CheckSimplifyMap");
-      return true;
-    }
-
-    return false;
-  }
-
-  void BeevMgr::UpdateSimplifyMap(const ASTNode& key, const ASTNode& value, bool pushNeg) {
-    if(pushNeg)
-      (*SimplifyNegMap)[key] = value;
-    else
-      (*SimplifyMap)[key] = value;
-  }
-
-  bool BeevMgr::CheckSubstitutionMap(const ASTNode& key, ASTNode& output) {
-    ASTNodeMap::iterator it;
-    if((it = SolverMap.find(key)) != SolverMap.end()) {
-      output = it->second;
-      return true;
-    }
-    return false;
-  }
-
-  bool BeevMgr::CheckSubstitutionMap(const ASTNode& key) {
-    if(SolverMap.find(key) != SolverMap.end())
-      return true;
-    else
-      return false;
-  }
-
-  bool BeevMgr::UpdateSubstitutionMap(const ASTNode& e0, const ASTNode& e1) {
-    int i = TermOrder(e0,e1);
-    if(0 == i)
-      return false;
-
-    //e0 is of the form READ(Arr,const), and e1 is const, or
-    //e0 is of the form var, and e1 is const
-    if(1 == i && !CheckSubstitutionMap(e0)) {
-      SolverMap[e0] = e1;
-      return true;
-    }
-
-    //e1 is of the form READ(Arr,const), and e0 is const, or
-    //e1 is of the form var, and e0 is const
-    if (-1 == i && !CheckSubstitutionMap(e1)) {
-      SolverMap[e1] = e0;
-      return true;
-    }
-
-    return false;
-  }
-
-  bool BeevMgr::CheckMultInverseMap(const ASTNode& key, ASTNode& output) {
-    ASTNodeMap::iterator it;
-    if((it = MultInverseMap.find(key)) != MultInverseMap.end()) {
-      output = it->second;
-      return true;
-    }
-    return false;
-  }
-
-  void BeevMgr::UpdateMultInverseMap(const ASTNode& key, const ASTNode& value) {
-      MultInverseMap[key] = value;
-  }
-
-
-  bool BeevMgr::CheckAlwaysTrueFormMap(const ASTNode& key) {
-    ASTNodeSet::iterator it = AlwaysTrueFormMap.find(key);
-    ASTNodeSet::iterator itend = AlwaysTrueFormMap.end();
-
-    if(it != itend) {
-      //cerr << "found:" << *it << endl;
-      CountersAndStats("Successful_CheckAlwaysTrueFormMap");
-      return true;
-    }
-
-    return false;
-  }
-
-  void BeevMgr::UpdateAlwaysTrueFormMap(const ASTNode& key) {
-    AlwaysTrueFormMap.insert(key);
-  }
-
-  //if a is READ(Arr,const) or SYMBOL, and b is BVCONST then return 1
-  //if b is READ(Arr,const) or SYMBOL, and a is BVCONST then return -1
-  //
-  //else return 0 by default
-   int BeevMgr::TermOrder(const ASTNode& a, const ASTNode& b) {
-    Kind k1 = a.GetKind();
-    Kind k2 = b.GetKind();
-
-    //a is of the form READ(Arr,const), and b is const, or
-    //a is of the form var, and b is const
-    if((k1 == READ
-       &&
-       a[0].GetKind() == SYMBOL &&
-       a[1].GetKind() == BVCONST
-       )
-       &&
-       (k2 == BVCONST)
-       )
-      return 1;
-
-    if(SYMBOL == k1 && (BVCONST == k2 || TRUE == k2 || FALSE == k2))
-      return 1;
-
-    //b is of the form READ(Arr,const), and a is const, or
-    //b is of the form var, and a is const
-    if((k1  == BVCONST)
-       &&
-       ((k2 == READ
-        &&
-        b[0].GetKind() == SYMBOL &&
-        b[1].GetKind() == BVCONST
-        )
-       ))
-      return -1;
-
-    if(SYMBOL == k2 && (BVCONST == k1 || TRUE == k1 || FALSE == k1))
-      return -1;
-
-    return 0;
-  }
-
-  //This function records all the const-indices seen so far for each
-  //array. It populates the map '_arrayname_readindices' whose key is
-  //the arrayname, and vlaue is a vector of read-indices.
-  //
-  //fill the arrayname_readindices vector if e0 is a READ(Arr,index)
-  //and index is a BVCONST.
-  //
-  //Since these arrayreads are being nuked and recorded in the
-  //substitutionmap, we have to also record the fact that each
-  //arrayread (e0 is of the form READ(Arr,const) here is represented
-  //by a BVCONST (e1). This is necessary for later Leibnitz Axiom
-  //generation
-  void BeevMgr::FillUp_ArrReadIndex_Vec(const ASTNode& e0, const ASTNode& e1) {
-    int i = TermOrder(e0,e1);
-    if(0 == i) return;
-
-    if(1 == i && e0.GetKind() != SYMBOL && !CheckSubstitutionMap(e0)) {
-      _arrayname_readindices[e0[0]].push_back(e0[1]);
-      //e0 is the array read : READ(A,i) and e1 is a bvconst
-      _arrayread_symbol[e0] = e1;
-      return;
-    }
-    if(-1 == i && e1.GetKind() != SYMBOL &&  !CheckSubstitutionMap(e1)) {
-      _arrayname_readindices[e1[0]].push_back(e1[1]);
-      //e0 is the array read : READ(A,i) and e1 is a bvconst
-      _arrayread_symbol[e1] = e0;
-      return;
-    }
-  }
-
-  ASTNode BeevMgr::SimplifyFormula_NoRemoveWrites(const ASTNode& b, bool pushNeg) {
-    Begin_RemoveWrites = false;
-    ASTNode out = SimplifyFormula(b,pushNeg);
-    return out;
-  }
-
-  ASTNode BeevMgr::SimplifyFormula_TopLevel(const ASTNode& b, bool pushNeg) {
-    ResetSimplifyMaps();
-    ASTNode out = SimplifyFormula(b,pushNeg);
-    ResetSimplifyMaps();
-    return out;
-  }
-
-  ASTNode BeevMgr::SimplifyFormula(const ASTNode& b, bool pushNeg){
-    if(!optimize)
-      return b;
-
-    Kind kind = b.GetKind();
-    if(BOOLEAN_TYPE != b.GetType()) {
-      FatalError(" SimplifyFormula: You have input a nonformula kind: ",ASTUndefined,kind);
-    }
-
-    ASTNode a = b;
-    ASTVec ca = a.GetChildren();
-    if(!(IMPLIES == kind ||
-        ITE == kind ||
-        isAtomic(kind))) {
-      SortByArith(ca);
-      a = CreateNode(kind,ca);
-    }
-
-    ASTNode output;
-    if(CheckSimplifyMap(a,output,pushNeg))
-      return output;
-
-    switch(kind){
-    case AND:
-    case OR:
-      output = SimplifyAndOrFormula(a,pushNeg);
-      break;
-    case NOT:
-      output = SimplifyNotFormula(a,pushNeg);
-      break;
-    case XOR:
-      output = SimplifyXorFormula(a,pushNeg);
-      break;
-    case NAND:
-      output = SimplifyNandFormula(a,pushNeg);
-      break;
-    case NOR:
-      output = SimplifyNorFormula(a,pushNeg);
-      break;
-    case IFF:
-      output = SimplifyIffFormula(a,pushNeg);
-      break;
-    case IMPLIES:
-      output = SimplifyImpliesFormula(a,pushNeg);
-      break;
-    case ITE:
-      output = SimplifyIteFormula(a,pushNeg);
-      break;
-    default:
-      //kind can be EQ,NEQ,BVLT,BVLE,... or a propositional variable
-      output = SimplifyAtomicFormula(a,pushNeg);
-      //output = pushNeg ? CreateNode(NOT,a) : a;
-      break;
-    }
-
-    //memoize
-    UpdateSimplifyMap(a,output, pushNeg);
-    return output;
-  }
-
-  ASTNode BeevMgr::SimplifyAtomicFormula(const ASTNode& a, bool pushNeg) {
-    if(!optimize) {
-      return a;
-    }
-
-    ASTNode output;
-    if(CheckSimplifyMap(a,output,pushNeg)) {
-      return output;
-    }
-
-    ASTNode left,right;
-    if(a.Degree() == 2) {
-      //cerr << "Input to simplifyterm: left: " << a[0] << endl;
-      left = SimplifyTerm(a[0]);
-      //cerr << "Output of simplifyterm:left: " << left << endl;
-      //cerr << "Input to simplifyterm: right: " << a[1] << endl;
-      right = SimplifyTerm(a[1]);
-      //cerr << "Output of simplifyterm:left: " << right << endl;
-    }
-
-    Kind kind = a.GetKind();
-    switch(kind) {
-    case TRUE:
-      output = pushNeg ? ASTFalse : ASTTrue;
-      break;
-    case FALSE:
-      output = pushNeg ? ASTTrue : ASTFalse;
-      break;
-    case SYMBOL:
-      if(!CheckSolverMap(a,output)) {
-       output = a;
-      }
-      output = pushNeg ? CreateNode(NOT,output) : output;
-      break;
-    case BVGETBIT: {
-      ASTNode term = SimplifyTerm(a[0]);
-      ASTNode thebit = a[1];
-      ASTNode zero = CreateZeroConst(1);
-      ASTNode one = CreateOneConst(1);
-      ASTNode getthebit = SimplifyTerm(CreateTerm(BVEXTRACT,1,term,thebit,thebit));
-      if(getthebit == zero)
-       output = pushNeg ? ASTTrue : ASTFalse;
-      else if(getthebit == one)
-       output = pushNeg ? ASTFalse : ASTTrue;
-      else {
-       output = CreateNode(BVGETBIT,term,thebit);
-       output = pushNeg ? CreateNode(NOT,output) : output;
-      }
-      break;
-    }
-    case EQ:{
-      output = CreateSimplifiedEQ(left,right);
-      output = LhsMinusRhs(output);
-      output = ITEOpt_InEqs(output);
-      if(output == ASTTrue)
-       output = pushNeg ? ASTFalse : ASTTrue;
-      else if (output == ASTFalse)
-       output = pushNeg ? ASTTrue : ASTFalse;
-      else
-       output = pushNeg ? CreateNode(NOT,output) : output;
-      break;
-    }
-    case NEQ: {
-      output = CreateSimplifiedEQ(left,right);
-      output = LhsMinusRhs(output);
-      if(output == ASTTrue)
-       output = pushNeg ? ASTTrue : ASTFalse;
-      else if (output == ASTFalse)
-       output = pushNeg ? ASTFalse : ASTTrue;
-      else
-       output = pushNeg ? output : CreateNode(NOT,output);
-      break;
-    }
-    case BVLT:
-    case BVLE:
-    case BVGT:
-    case BVGE:
-    case BVSLT:
-    case BVSLE:
-    case BVSGT:
-    case BVSGE: {
-      //output = CreateNode(kind,left,right);
-      //output = pushNeg ? CreateNode(NOT,output) : output;
-      output = CreateSimplifiedINEQ(kind,left,right,pushNeg);
-      break;
-    }
-    default:
-      FatalError("SimplifyAtomicFormula: NO atomic formula of the kind: ",ASTUndefined,kind);
-      break;
-    }
-
-    //memoize
-    UpdateSimplifyMap(a,output,pushNeg);
-    return output;
-  } //end of SimplifyAtomicFormula()
-
-  ASTNode BeevMgr::CreateSimplifiedINEQ(Kind k,
-                                       const ASTNode& left,
-                                       const ASTNode& right,
-                                       bool pushNeg) {
-    ASTNode output;
-    if(BVCONST == left.GetKind() && BVCONST == right.GetKind()) {
-      output = BVConstEvaluator(CreateNode(k,left,right));
-      output = pushNeg ? (ASTFalse == output) ? ASTTrue : ASTFalse : output;
-      return output;
-    }
-
-    unsigned len = left.GetValueWidth();
-    ASTNode zero = CreateZeroConst(len);
-    ASTNode one = CreateOneConst(len);
-    ASTNode max = CreateMaxConst(len);
-    switch(k){
-    case BVLT:
-      if(right == zero) {
-       output = pushNeg ? ASTTrue : ASTFalse;
-      }
-      else if(left == right) {
-       output = pushNeg ? ASTTrue : ASTFalse;
-      }
-      else if(one == right) {
-       output = CreateSimplifiedEQ(left,zero);
-       output = pushNeg ? CreateNode(NOT,output) : output;
-      }
-      else {
-       output = pushNeg ? CreateNode(BVLE,right,left) : CreateNode(BVLT,left,right);
-      }
-      break;
-    case BVLE:
-      if(left == zero) {
-       output = pushNeg ? ASTFalse : ASTTrue;
-      }
-      else if(left == right) {
-       output = pushNeg ? ASTFalse : ASTTrue;
-      }
-      else if(max == right) {
-       output = pushNeg ? ASTFalse : ASTTrue;
-      }
-      else if(zero == right) {
-       output = CreateSimplifiedEQ(left,zero);
-       output = pushNeg ? CreateNode(NOT,output) : output;
-      }
-      else {
-       output = pushNeg ? CreateNode(BVLT,right,left) : CreateNode(BVLE,left,right);
-      }
-      break;
-    case BVGT:
-      if(left == zero) {
-       output = pushNeg ? ASTTrue : ASTFalse;
-      }
-      else if(left == right) {
-       output = pushNeg ? ASTTrue : ASTFalse;
-      }
-      else {
-      output = pushNeg ? CreateNode(BVLE,left,right) : CreateNode(BVLT,right,left);
-      }
-      break;
-    case BVGE:
-      if(right == zero) {
-       output = pushNeg ? ASTFalse : ASTTrue;
-      }
-      else if(left == right) {
-       output = pushNeg ? ASTFalse : ASTTrue;
-      }
-      else {
-      output = pushNeg ? CreateNode(BVLT,left,right) : CreateNode(BVLE,right,left);
-      }
-      break;
-    case BVSLT:
-    case BVSLE:
-    case BVSGE:
-    case BVSGT: {
-      output = CreateNode(k,left,right);
-      output = pushNeg ? CreateNode(NOT,output) : output;
-    }
-      break;
-    default:
-      FatalError("Wrong Kind");
-      break;
-    }
-
-    return output;
-  }
-
-  //takes care of some simple ITE Optimizations in the context of equations
-  ASTNode BeevMgr::ITEOpt_InEqs(const ASTNode& in) {
-    CountersAndStats("ITEOpts_InEqs");
-
-    if(!(EQ == in.GetKind() && optimize)) {
-      return in;
-    }
-
-    ASTNode output;
-    if(CheckSimplifyMap(in,output,false)) {
-      return output;
-    }
-
-    ASTNode in1 = in[0];
-    ASTNode in2 = in[1];
-    Kind k1 = in1.GetKind();
-    Kind k2 = in2.GetKind();
-    if(in1 == in2) {
-      //terms are syntactically the same
-      output = ASTTrue;
-    }
-    else if(BVCONST == k1 && BVCONST == k2) {
-      //here the terms are definitely not syntactically equal but may
-      //be semantically equal.
-      output = ASTFalse;
-    }
-    else if(ITE == k1 &&
-           BVCONST == in1[1].GetKind() &&
-           BVCONST == in1[2].GetKind() && BVCONST == k2) {
-      //if one side is a BVCONST and the other side is an ITE over
-      //BVCONST then we can do the following optimization:
-      //
-      // c = ITE(cond,c,d) <=> cond
-      //
-      // similarly ITE(cond,c,d) = c <=> cond
-      //
-      // c = ITE(cond,d,c) <=> NOT(cond)
-      //
-      //similarly ITE(cond,d,c) = d <=> NOT(cond)
-      ASTNode cond = in1[0];
-      if(in1[1] == in2) {
-       //ITE(cond, c, d) = c <=> cond
-       output = cond;
-      }
-      else if(in1[2] == in2) {
-       cond = SimplifyFormula(cond,true);
-       output = cond;
-      }
-      else {
-       //last resort is to CreateNode
-       output = CreateNode(EQ,in1,in2);
-      }
-    }
-    else if(ITE == k2 &&
-           BVCONST == in2[1].GetKind() &&
-           BVCONST == in2[2].GetKind() && BVCONST == k1) {
-      ASTNode cond = in2[0];
-      if(in2[1] == in1) {
-       //ITE(cond, c, d) = c <=> cond
-       output = cond;
-      }
-      else if(in2[2] == in1) {
-       cond = SimplifyFormula(cond,true);
-       output = cond;
-      }
-      else {
+namespace BEEV
+{
+
+bool BeevMgr::CheckSimplifyMap(const ASTNode& key, ASTNode& output, bool pushNeg)
+{
+       ASTNodeMap::iterator it, itend;
+       it = pushNeg ? SimplifyNegMap->find(key) : SimplifyMap->find(key);
+       itend = pushNeg ? SimplifyNegMap->end() : SimplifyMap->end();
+
+       if (it != itend)
+       {
+               output = it->second;
+               CountersAndStats("Successful_CheckSimplifyMap");
+               return true;
+       }
+
+       if (pushNeg && (it = SimplifyMap->find(key)) != SimplifyMap->end())
+       {
+               output = (ASTFalse == it->second) ? ASTTrue : (ASTTrue == it->second) ? ASTFalse : CreateNode(NOT, it->second);
+               CountersAndStats("2nd_Successful_CheckSimplifyMap");
+               return true;
+       }
+
+       return false;
+}
+
+void BeevMgr::UpdateSimplifyMap(const ASTNode& key, const ASTNode& value, bool pushNeg)
+{
+       if (pushNeg)
+               (*SimplifyNegMap)[key] = value;
+       else
+               (*SimplifyMap)[key] = value;
+}
+
+bool BeevMgr::CheckSubstitutionMap(const ASTNode& key, ASTNode& output)
+{
+       ASTNodeMap::iterator it;
+       if ((it = SolverMap.find(key)) != SolverMap.end())
+       {
+               output = it->second;
+               return true;
+       }
+       return false;
+}
+
+bool BeevMgr::CheckSubstitutionMap(const ASTNode& key)
+{
+       if (SolverMap.find(key) != SolverMap.end())
+               return true;
+       else
+               return false;
+}
+
+bool BeevMgr::UpdateSubstitutionMap(const ASTNode& e0, const ASTNode& e1)
+{
+       int i = TermOrder(e0, e1);
+       if (0 == i)
+               return false;
+
+       //e0 is of the form READ(Arr,const), and e1 is const, or
+       //e0 is of the form var, and e1 is const
+       if (1 == i && !CheckSubstitutionMap(e0))
+       {
+               SolverMap[e0] = e1;
+               return true;
+       }
+
+       //e1 is of the form READ(Arr,const), and e0 is const, or
+       //e1 is of the form var, and e0 is const
+       if (-1 == i && !CheckSubstitutionMap(e1))
+       {
+               SolverMap[e1] = e0;
+               return true;
+       }
+
+       return false;
+}
+
+bool BeevMgr::CheckMultInverseMap(const ASTNode& key, ASTNode& output)
+{
+       ASTNodeMap::iterator it;
+       if ((it = MultInverseMap.find(key)) != MultInverseMap.end())
+       {
+               output = it->second;
+               return true;
+       }
+       return false;
+}
+
+void BeevMgr::UpdateMultInverseMap(const ASTNode& key, const ASTNode& value)
+{
+       MultInverseMap[key] = value;
+}
+
+bool BeevMgr::CheckAlwaysTrueFormMap(const ASTNode& key)
+{
+       ASTNodeSet::iterator it = AlwaysTrueFormMap.find(key);
+       ASTNodeSet::iterator itend = AlwaysTrueFormMap.end();
+
+       if (it != itend)
+       {
+               //cerr << "found:" << *it << endl;
+               CountersAndStats("Successful_CheckAlwaysTrueFormMap");
+               return true;
+       }
+
+       return false;
+}
+
+void BeevMgr::UpdateAlwaysTrueFormMap(const ASTNode& key)
+{
+       AlwaysTrueFormMap.insert(key);
+}
+
+//if a is READ(Arr,const) or SYMBOL, and b is BVCONST then return 1
+//if b is READ(Arr,const) or SYMBOL, and a is BVCONST then return -1
+//
+//else return 0 by default
+int BeevMgr::TermOrder(const ASTNode& a, const ASTNode& b)
+{
+       Kind k1 = a.GetKind();
+       Kind k2 = b.GetKind();
+
+       //a is of the form READ(Arr,const), and b is const, or
+       //a is of the form var, and b is const
+       if ((k1 == READ && a[0].GetKind() == SYMBOL && a[1].GetKind() == BVCONST) && (k2 == BVCONST))
+               return 1;
+
+       if (SYMBOL == k1 && (BVCONST == k2 || TRUE == k2 || FALSE == k2))
+               return 1;
+
+       //b is of the form READ(Arr,const), and a is const, or
+       //b is of the form var, and a is const
+       if ((k1 == BVCONST) && ((k2 == READ && b[0].GetKind() == SYMBOL && b[1].GetKind() == BVCONST)))
+               return -1;
+
+       if (SYMBOL == k2 && (BVCONST == k1 || TRUE == k1 || FALSE == k1))
+               return -1;
+
+       return 0;
+}
+
+//This function records all the const-indices seen so far for each
+//array. It populates the map '_arrayname_readindices' whose key is
+//the arrayname, and vlaue is a vector of read-indices.
+//
+//fill the arrayname_readindices vector if e0 is a READ(Arr,index)
+//and index is a BVCONST.
+//
+//Since these arrayreads are being nuked and recorded in the
+//substitutionmap, we have to also record the fact that each
+//arrayread (e0 is of the form READ(Arr,const) here is represented
+//by a BVCONST (e1). This is necessary for later Leibnitz Axiom
+//generation
+void BeevMgr::FillUp_ArrReadIndex_Vec(const ASTNode& e0, const ASTNode& e1)
+{
+       int i = TermOrder(e0, e1);
+       if (0 == i)
+               return;
+
+       if (1 == i && e0.GetKind() != SYMBOL && !CheckSubstitutionMap(e0))
+       {
+               _arrayname_readindices[e0[0]].push_back(e0[1]);
+               //e0 is the array read : READ(A,i) and e1 is a bvconst
+               _arrayread_symbol[e0] = e1;
+               return;
+       }
+       if (-1 == i && e1.GetKind() != SYMBOL && !CheckSubstitutionMap(e1))
+       {
+               _arrayname_readindices[e1[0]].push_back(e1[1]);
+               //e0 is the array read : READ(A,i) and e1 is a bvconst
+               _arrayread_symbol[e1] = e0;
+               return;
+       }
+}
+
+ASTNode BeevMgr::SimplifyFormula_NoRemoveWrites(const ASTNode& b, bool pushNeg)
+{
+       Begin_RemoveWrites = false;
+       ASTNode out = SimplifyFormula(b, pushNeg);
+       return out;
+}
+
+ASTNode BeevMgr::SimplifyFormula_TopLevel(const ASTNode& b, bool pushNeg)
+{
+       ResetSimplifyMaps();
+       ASTNode out = SimplifyFormula(b, pushNeg);
+       ResetSimplifyMaps();
+       return out;
+}
+
+ASTNode BeevMgr::SimplifyFormula(const ASTNode& b, bool pushNeg)
+{
+       if (!optimize)
+               return b;
+
+       Kind kind = b.GetKind();
+       if (BOOLEAN_TYPE != b.GetType())
+       {
+               FatalError(" SimplifyFormula: You have input a nonformula kind: ", ASTUndefined, kind);
+       }
+
+       ASTNode a = b;
+       ASTVec ca = a.GetChildren();
+       if (!(IMPLIES == kind || ITE == kind || isAtomic(kind)))
+       {
+               SortByArith(ca);
+               a = CreateNode(kind, ca);
+       }
+
+       ASTNode output;
+       if (CheckSimplifyMap(a, output, pushNeg))
+               return output;
+
+       switch (kind)
+       {
+               case AND:
+               case OR:
+                       output = SimplifyAndOrFormula(a, pushNeg);
+                       break;
+               case NOT:
+                       output = SimplifyNotFormula(a, pushNeg);
+                       break;
+               case XOR:
+                       output = SimplifyXorFormula(a, pushNeg);
+                       break;
+               case NAND:
+                       output = SimplifyNandFormula(a, pushNeg);
+                       break;
+               case NOR:
+                       output = SimplifyNorFormula(a, pushNeg);
+                       break;
+               case IFF:
+                       output = SimplifyIffFormula(a, pushNeg);
+                       break;
+               case IMPLIES:
+                       output = SimplifyImpliesFormula(a, pushNeg);
+                       break;
+               case ITE:
+                       output = SimplifyIteFormula(a, pushNeg);
+                       break;
+               default:
+                       //kind can be EQ,NEQ,BVLT,BVLE,... or a propositional variable
+                       output = SimplifyAtomicFormula(a, pushNeg);
+                       //output = pushNeg ? CreateNode(NOT,a) : a;
+                       break;
+       }
+
+       //memoize
+       UpdateSimplifyMap(a, output, pushNeg);
+       return output;
+}
+
+ASTNode BeevMgr::SimplifyAtomicFormula(const ASTNode& a, bool pushNeg)
+{
+       if (!optimize)
+       {
+               return a;
+       }
+
+       ASTNode output;
+       if (CheckSimplifyMap(a, output, pushNeg))
+       {
+               return output;
+       }
+
+       ASTNode left, right;
+       if (a.Degree() == 2)
+       {
+               //cerr << "Input to simplifyterm: left: " << a[0] << endl;
+               left = SimplifyTerm(a[0]);
+               //cerr << "Output of simplifyterm:left: " << left << endl;
+               //cerr << "Input to simplifyterm: right: " << a[1] << endl;
+               right = SimplifyTerm(a[1]);
+               //cerr << "Output of simplifyterm:left: " << right << endl;
+       }
+
+       Kind kind = a.GetKind();
+       switch (kind)
+       {
+               case TRUE:
+                       output = pushNeg ? ASTFalse : ASTTrue;
+                       break;
+               case FALSE:
+                       output = pushNeg ? ASTTrue : ASTFalse;
+                       break;
+               case SYMBOL:
+                       if (!CheckSolverMap(a, output))
+                       {
+                               output = a;
+                       }
+                       output = pushNeg ? CreateNode(NOT, output) : output;
+                       break;
+               case BVGETBIT:
+               {
+                       ASTNode term = SimplifyTerm(a[0]);
+                       ASTNode thebit = a[1];
+                       ASTNode zero = CreateZeroConst(1);
+                       ASTNode one = CreateOneConst(1);
+                       ASTNode getthebit = SimplifyTerm(CreateTerm(BVEXTRACT, 1, term, thebit, thebit));
+                       if (getthebit == zero)
+                               output = pushNeg ? ASTTrue : ASTFalse;
+                       else if (getthebit == one)
+                               output = pushNeg ? ASTFalse : ASTTrue;
+                       else
+                       {
+                               output = CreateNode(BVGETBIT, term, thebit);
+                               output = pushNeg ? CreateNode(NOT, output) : output;
+                       }
+                       break;
+               }
+               case EQ:
+               {
+                       output = CreateSimplifiedEQ(left, right);
+                       output = LhsMinusRhs(output);
+                       output = ITEOpt_InEqs(output);
+                       if (output == ASTTrue)
+                               output = pushNeg ? ASTFalse : ASTTrue;
+                       else if (output == ASTFalse)
+                               output = pushNeg ? ASTTrue : ASTFalse;
+                       else
+                               output = pushNeg ? CreateNode(NOT, output) : output;
+                       break;
+               }
+               case NEQ:
+               {
+                       output = CreateSimplifiedEQ(left, right);
+                       output = LhsMinusRhs(output);
+                       if (output == ASTTrue)
+                               output = pushNeg ? ASTTrue : ASTFalse;
+                       else if (output == ASTFalse)
+                               output = pushNeg ? ASTFalse : ASTTrue;
+                       else
+                               output = pushNeg ? output : CreateNode(NOT, output);
+                       break;
+               }
+               case BVLT:
+               case BVLE:
+               case BVGT:
+               case BVGE:
+               case BVSLT:
+               case BVSLE:
+               case BVSGT:
+               case BVSGE:
+               {
+                       //output = CreateNode(kind,left,right);
+                       //output = pushNeg ? CreateNode(NOT,output) : output;
+                       output = CreateSimplifiedINEQ(kind, left, right, pushNeg);
+                       break;
+               }
+               default:
+                       FatalError("SimplifyAtomicFormula: NO atomic formula of the kind: ", ASTUndefined, kind);
+                       break;
+       }
+
+       //memoize
+       UpdateSimplifyMap(a, output, pushNeg);
+       return output;
+} //end of SimplifyAtomicFormula()
+
+ASTNode BeevMgr::CreateSimplifiedINEQ(Kind k, const ASTNode& left, const ASTNode& right, bool pushNeg)
+{
+       ASTNode output;
+       if (BVCONST == left.GetKind() && BVCONST == right.GetKind())
+       {
+               output = BVConstEvaluator(CreateNode(k, left, right));
+               output = pushNeg ? (ASTFalse == output) ? ASTTrue : ASTFalse : output;
+               return output;
+       }
+
+       unsigned len = left.GetValueWidth();
+       ASTNode zero = CreateZeroConst(len);
+       ASTNode one = CreateOneConst(len);
+       ASTNode max = CreateMaxConst(len);
+       switch (k)
+       {
+               case BVLT:
+                       if (right == zero)
+                       {
+                               output = pushNeg ? ASTTrue : ASTFalse;
+                       }
+                       else if (left == right)
+                       {
+                               output = pushNeg ? ASTTrue : ASTFalse;
+                       }
+                       else if (one == right)
+                       {
+                               output = CreateSimplifiedEQ(left, zero);
+                               output = pushNeg ? CreateNode(NOT, output) : output;
+                       }
+                       else
+                       {
+                               output = pushNeg ? CreateNode(BVLE, right, left) : CreateNode(BVLT, left, right);
+                       }
+                       break;
+               case BVLE:
+                       if (left == zero)
+                       {
+                               output = pushNeg ? ASTFalse : ASTTrue;
+                       }
+                       else if (left == right)
+                       {
+                               output = pushNeg ? ASTFalse : ASTTrue;
+                       }
+                       else if (max == right)
+                       {
+                               output = pushNeg ? ASTFalse : ASTTrue;
+                       }
+                       else if (zero == right)
+                       {
+                               output = CreateSimplifiedEQ(left, zero);
+                               output = pushNeg ? CreateNode(NOT, output) : output;
+                       }
+                       else
+                       {
+                               output = pushNeg ? CreateNode(BVLT, right, left) : CreateNode(BVLE, left, right);
+                       }
+                       break;
+               case BVGT:
+                       if (left == zero)
+                       {
+                               output = pushNeg ? ASTTrue : ASTFalse;
+                       }
+                       else if (left == right)
+                       {
+                               output = pushNeg ? ASTTrue : ASTFalse;
+                       }
+                       else
+                       {
+                               output = pushNeg ? CreateNode(BVLE, left, right) : CreateNode(BVLT, right, left);
+                       }
+                       break;
+               case BVGE:
+                       if (right == zero)
+                       {
+                               output = pushNeg ? ASTFalse : ASTTrue;
+                       }
+                       else if (left == right)
+                       {
+                               output = pushNeg ? ASTFalse : ASTTrue;
+                       }
+                       else
+                       {
+                               output = pushNeg ? CreateNode(BVLT, left, right) : CreateNode(BVLE, right, left);
+                       }
+                       break;
+               case BVSLT:
+               case BVSLE:
+               case BVSGE:
+               case BVSGT:
+               {
+                       output = CreateNode(k, left, right);
+                       output = pushNeg ? CreateNode(NOT, output) : output;
+               }
+                       break;
+               default:
+                       FatalError("Wrong Kind");
+                       break;
+       }
+
+       return output;
+}
+
+//takes care of some simple ITE Optimizations in the context of equations
+ASTNode BeevMgr::ITEOpt_InEqs(const ASTNode& in)
+{
+       CountersAndStats("ITEOpts_InEqs");
+
+       if (!(EQ == in.GetKind() && optimize))
+       {
+               return in;
+       }
+
+       ASTNode output;
+       if (CheckSimplifyMap(in, output, false))
+       {
+               return output;
+       }
+
+       ASTNode in1 = in[0];
+       ASTNode in2 = in[1];
+       Kind k1 = in1.GetKind();
+       Kind k2 = in2.GetKind();
+       if (in1 == in2)
+       {
+               //terms are syntactically the same
+               output = ASTTrue;
+       }
+       else if (BVCONST == k1 && BVCONST == k2)
+       {
+               //here the terms are definitely not syntactically equal but may
+               //be semantically equal.
+               output = ASTFalse;
+       }
+       else if (ITE == k1 && BVCONST == in1[1].GetKind() && BVCONST == in1[2].GetKind() && BVCONST == k2)
+       {
+               //if one side is a BVCONST and the other side is an ITE over
+               //BVCONST then we can do the following optimization:
+               //
+               // c = ITE(cond,c,d) <=> cond
+               //
+               // similarly ITE(cond,c,d) = c <=> cond
+               //
+               // c = ITE(cond,d,c) <=> NOT(cond)
+               //
+               //similarly ITE(cond,d,c) = d <=> NOT(cond)
+               ASTNode cond = in1[0];
+               if (in1[1] == in2)
+               {
+                       //ITE(cond, c, d) = c <=> cond
+                       output = cond;
+               }
+               else if (in1[2] == in2)
+               {
+                       cond = SimplifyFormula(cond, true);
+                       output = cond;
+               }
+               else
+               {
+                       //last resort is to CreateNode
+                       output = CreateNode(EQ, in1, in2);
+               }
+       }
+       else if (ITE == k2 && BVCONST == in2[1].GetKind() && BVCONST == in2[2].GetKind() && BVCONST == k1)
+       {
+               ASTNode cond = in2[0];
+               if (in2[1] == in1)
+               {
+                       //ITE(cond, c, d) = c <=> cond
+                       output = cond;
+               }
+               else if (in2[2] == in1)
+               {
+                       cond = SimplifyFormula(cond, true);
+                       output = cond;
+               }
+               else
+               {
+                       //last resort is to CreateNode
+                       output = CreateNode(EQ, in1, in2);
+               }
+       }
+       else
+       {
+               //last resort is to CreateNode
+               output = CreateNode(EQ, in1, in2);
+       }
+
+       UpdateSimplifyMap(in, output, false);
+       return output;
+} //End of ITEOpts_InEqs()
+
+//Tries to simplify the input to TRUE/FALSE. if it fails, then
+//return the constructed equality
+ASTNode BeevMgr::CreateSimplifiedEQ(const ASTNode& in1, const ASTNode& in2)
+{
+       CountersAndStats("CreateSimplifiedEQ");
+       Kind k1 = in1.GetKind();
+       Kind k2 = in2.GetKind();
+
+       if (!optimize)
+       {
+               return CreateNode(EQ, in1, in2);
+       }
+
+       if (in1 == in2)
+               //terms are syntactically the same
+               return ASTTrue;
+
+       //here the terms are definitely not syntactically equal but may be
+       //semantically equal.
+       if (BVCONST == k1 && BVCONST == k2)
+               return ASTFalse;
+
        //last resort is to CreateNode
-       output = CreateNode(EQ,in1,in2);
-      }
-    }
-    else {
-      //last resort is to CreateNode
-      output = CreateNode(EQ,in1,in2);
-    }
-
-    UpdateSimplifyMap(in,output,false);
-    return output;
- } //End of ITEOpts_InEqs()
-
-  //Tries to simplify the input to TRUE/FALSE. if it fails, then
-  //return the constructed equality
-  ASTNode BeevMgr::CreateSimplifiedEQ(const ASTNode& in1, const ASTNode& in2) {
-    CountersAndStats("CreateSimplifiedEQ");
-    Kind k1 = in1.GetKind();
-    Kind k2 = in2.GetKind();
-
-    if(!optimize) {
-      return CreateNode(EQ,in1,in2);
-    }
-
-    if(in1 == in2)
-      //terms are syntactically the same
-      return ASTTrue;
-
-    //here the terms are definitely not syntactically equal but may be
-    //semantically equal.
-    if(BVCONST == k1 && BVCONST == k2)
-      return ASTFalse;
-
-
-    //last resort is to CreateNode
-    return CreateNode(EQ,in1,in2);
-  }
-
-  //accepts cond == t1, then part is t2, and else part is t3
-  ASTNode BeevMgr::CreateSimplifiedTermITE(const ASTNode& in0,
-                                          const ASTNode& in1, const ASTNode& in2) {
-    ASTNode t0 = in0;
-    ASTNode t1 = in1;
-    ASTNode t2 = in2;
-    CountersAndStats("CreateSimplifiedITE");
-    if(!optimize) {
-      if(t1.GetValueWidth() != t2.GetValueWidth()) {
-       cerr << "t2 is : = " << t2;
-       FatalError("CreateSimplifiedTermITE: the lengths of then and else branches don't match",t1);
-      }
-      if(t1.GetIndexWidth() != t2.GetIndexWidth()) {
-       cerr << "t2 is : = " << t2;
-       FatalError("CreateSimplifiedTermITE: the lengths of then and else branches don't match",t1);
-      }
-      return CreateTerm(ITE,t1.GetValueWidth(),t0,t1,t2);
-    }
-
-    if(t0 == ASTTrue)
-      return t1;
-    if (t0 == ASTFalse)
-      return t2;
-    if(t1 == t2)
-      return t1;
-    if(CheckAlwaysTrueFormMap(t0)) {
-       return t1;
-    }
-    if(CheckAlwaysTrueFormMap(CreateNode(NOT,t0)) ||
-       (NOT == t0.GetKind() && CheckAlwaysTrueFormMap(t0[0]))) {
-      return t2;
-    }
-
-    return CreateTerm(ITE,t1.GetValueWidth(),t0,t1,t2);
-  }
-
-ASTNode BeevMgr::CreateSimplifiedFormulaITE(const ASTNode& in0, const ASTNode& in1, const ASTNode& in2) {
+       return CreateNode(EQ, in1, in2);
+}
+
+//accepts cond == t1, then part is t2, and else part is t3
+ASTNode BeevMgr::CreateSimplifiedTermITE(const ASTNode& in0, const ASTNode& in1, const ASTNode& in2)
+{
+       ASTNode t0 = in0;
+       ASTNode t1 = in1;
+       ASTNode t2 = in2;
+       CountersAndStats("CreateSimplifiedITE");
+       if (!optimize)
+       {
+               if (t1.GetValueWidth() != t2.GetValueWidth())
+               {
+                       cerr << "t2 is : = " << t2;
+                       FatalError("CreateSimplifiedTermITE: the lengths of then and else branches don't match", t1);
+               }
+               if (t1.GetIndexWidth() != t2.GetIndexWidth())
+               {
+                       cerr << "t2 is : = " << t2;
+                       FatalError("CreateSimplifiedTermITE: the lengths of then and else branches don't match", t1);
+               }
+               return CreateTerm(ITE, t1.GetValueWidth(), t0, t1, t2);
+       }
+
+       if (t0 == ASTTrue)
+               return t1;
+       if (t0 == ASTFalse)
+               return t2;
+       if (t1 == t2)
+               return t1;
+       if (CheckAlwaysTrueFormMap(t0))
+       {
+               return t1;
+       }
+       if (CheckAlwaysTrueFormMap(CreateNode(NOT, t0)) || (NOT == t0.GetKind() && CheckAlwaysTrueFormMap(t0[0])))
+       {
+               return t2;
+       }
+
+       return CreateTerm(ITE, t1.GetValueWidth(), t0, t1, t2);
+}
+
+ASTNode BeevMgr::CreateSimplifiedFormulaITE(const ASTNode& in0, const ASTNode& in1, const ASTNode& in2)
+{
        ASTNode t0 = in0;
        ASTNode t1 = in1;
        ASTNode t2 = in2;
        CountersAndStats("CreateSimplifiedFormulaITE");
 
-       if (optimize) {
+       if (optimize)
+       {
                if (t0 == ASTTrue)
                        return t1;
                if (t0 == ASTFalse)
                        return t2;
                if (t1 == t2)
                        return t1;
-               if (CheckAlwaysTrueFormMap(t0)) {
+               if (CheckAlwaysTrueFormMap(t0))
+               {
                        return t1;
                }
-               if (CheckAlwaysTrueFormMap(CreateNode(NOT, t0)) || (NOT == t0.GetKind() && CheckAlwaysTrueFormMap(t0[0]))) {
+               if (CheckAlwaysTrueFormMap(CreateNode(NOT, t0)) || (NOT == t0.GetKind() && CheckAlwaysTrueFormMap(t0[0])))
+               {
                        return t2;
                }
        }
@@ -603,2629 +656,2918 @@ ASTNode BeevMgr::CreateSimplifiedFormulaITE(const ASTNode& in0, const ASTNode& i
        return result;
 }
 
+ASTNode BeevMgr::SimplifyAndOrFormula(const ASTNode& a, bool pushNeg)
+{
+       ASTNode output;
+       //cerr << "input:\n" << a << endl;
+
+       if (CheckSimplifyMap(a, output, pushNeg))
+               return output;
+
+       ASTVec c, outvec;
+       c = a.GetChildren();
+       ASTNode flat = FlattenOneLevel(a);
+       c = flat.GetChildren();
+       SortByArith(c);
+
+       Kind k = a.GetKind();
+       bool isAnd = (k == AND) ? true : false;
+
+       ASTNode annihilator = isAnd ? (pushNeg ? ASTTrue : ASTFalse) : (pushNeg ? ASTFalse : ASTTrue);
+
+       ASTNode identity = isAnd ? (pushNeg ? ASTFalse : ASTTrue) : (pushNeg ? ASTTrue : ASTFalse);
+
+       //do the work
+       ASTVec::const_iterator next_it;
+       for (ASTVec::const_iterator i = c.begin(), iend = c.end(); i != iend; i++)
+       {
+               ASTNode aaa = *i;
+               next_it = i + 1;
+               bool nextexists = (next_it < iend);
+
+               aaa = SimplifyFormula(aaa, pushNeg);
+               if (annihilator == aaa)
+               {
+                       //memoize
+                       UpdateSimplifyMap(*i, annihilator, pushNeg);
+                       UpdateSimplifyMap(a, annihilator, pushNeg);
+                       //cerr << "annihilator1: output:\n" << annihilator << endl;
+                       return annihilator;
+               }
+               ASTNode bbb = ASTFalse;
+               if (nextexists)
+               {
+                       bbb = SimplifyFormula(*next_it, pushNeg);
+               }
+               if (nextexists && bbb == aaa)
+               {
+                       //skip the duplicate aaa. *next_it will be included
+               }
+               else if (nextexists && ((bbb.GetKind() == NOT && bbb[0] == aaa)))
+               {
+                       //memoize
+                       UpdateSimplifyMap(a, annihilator, pushNeg);
+                       //cerr << "annihilator2: output:\n" << annihilator << endl;
+                       return annihilator;
+               }
+               else if (identity == aaa)
+               {
+                       // //drop identites
+               }
+               else if ((!isAnd && !pushNeg) || (isAnd && pushNeg))
+               {
+                       outvec.push_back(aaa);
+               }
+               else if ((isAnd && !pushNeg) || (!isAnd && pushNeg))
+               {
+                       outvec.push_back(aaa);
+               }
+               else
+               {
+                       outvec.push_back(aaa);
+               }
+       }
 
-  ASTNode BeevMgr::SimplifyAndOrFormula(const ASTNode& a, bool pushNeg) {
-    ASTNode output;
-    //cerr << "input:\n" << a << endl;
-
-    if(CheckSimplifyMap(a,output,pushNeg))
-      return output;
+       switch (outvec.size())
+       {
+               case 0:
+               {
+                       //only identities were dropped
+                       output = identity;
+                       break;
+               }
+               case 1:
+               {
+                       output = SimplifyFormula(outvec[0], false);
+                       break;
+               }
+               default:
+               {
+                       output = (isAnd) ? (pushNeg ? CreateNode(OR, outvec) : CreateNode(AND, outvec)) : (pushNeg ? CreateNode(AND, outvec) : CreateNode(OR,
+                                       outvec));
+                       //output = FlattenOneLevel(output);
+                       break;
+               }
+       }
+       //memoize
+       UpdateSimplifyMap(a, output, pushNeg);
+       //cerr << "output:\n" << output << endl;
+       return output;
+} //end of SimplifyAndOrFormula
 
-    ASTVec c, outvec;
-    c = a.GetChildren();
-    ASTNode flat = FlattenOneLevel(a);
-    c = flat.GetChildren();
-    SortByArith(c);
 
-    Kind k = a.GetKind();
-    bool isAnd = (k == AND) ? true : false;
+ASTNode BeevMgr::SimplifyNotFormula(const ASTNode& a, bool pushNeg)
+{
+       ASTNode output;
+       if (CheckSimplifyMap(a, output, pushNeg))
+               return output;
+
+       if (!(a.Degree() == 1 && NOT == a.GetKind()))
+               FatalError("SimplifyNotFormula: input vector with more than 1 node", ASTUndefined);
+
+       //if pushNeg is set then there is NOT on top
+       unsigned int NotCount = pushNeg ? 1 : 0;
+       ASTNode o = a;
+       //count the number of NOTs in 'a'
+       while (NOT == o.GetKind())
+       {
+               o = o[0];
+               NotCount++;
+       }
 
-    ASTNode annihilator = isAnd ?
-      (pushNeg ? ASTTrue : ASTFalse):
-      (pushNeg ? ASTFalse : ASTTrue);
+       //pushnegation if there are odd number of NOTs
+       bool pn = (NotCount % 2 == 0) ? false : true;
 
-    ASTNode identity = isAnd ?
-      (pushNeg ? ASTFalse : ASTTrue):
-      (pushNeg ? ASTTrue : ASTFalse);
+       if (CheckAlwaysTrueFormMap(o))
+       {
+               output = pn ? ASTFalse : ASTTrue;
+               return output;
+       }
 
-    //do the work
-    ASTVec::const_iterator next_it;
-    for(ASTVec::const_iterator i=c.begin(),iend=c.end();i!=iend;i++) {
-      ASTNode aaa = *i;
-      next_it = i+1;
-      bool nextexists = (next_it < iend);
+       if (CheckSimplifyMap(o, output, pn))
+       {
+               return output;
+       }
 
-      aaa = SimplifyFormula(aaa,pushNeg);
-      if(annihilator == aaa) {
-       //memoize
-       UpdateSimplifyMap(*i,annihilator,pushNeg);
-       UpdateSimplifyMap(a, annihilator,pushNeg);
-       //cerr << "annihilator1: output:\n" << annihilator << endl;
-       return annihilator;
-      }
-      ASTNode bbb = ASTFalse;
-      if(nextexists) {
-       bbb = SimplifyFormula(*next_it,pushNeg);
-      }
-      if(nextexists &&  bbb == aaa) {
-       //skip the duplicate aaa. *next_it will be included
-      }
-      else if(nextexists &&
-             ((bbb.GetKind() == NOT && bbb[0] == aaa))) {
-       //memoize
-       UpdateSimplifyMap(a, annihilator,pushNeg);
-       //cerr << "annihilator2: output:\n" << annihilator << endl;
-       return annihilator;
-      }
-      else if(identity == aaa) {
-       // //drop identites
-      }
-      else if((!isAnd && !pushNeg) ||
-             (isAnd && pushNeg)) {
-       outvec.push_back(aaa);
-      }
-      else if((isAnd && !pushNeg) ||
-             (!isAnd && pushNeg)) {
-       outvec.push_back(aaa);
-      }
-      else {
-       outvec.push_back(aaa);
-      }
-    }
-
-    switch(outvec.size()) {
-    case 0: {
-      //only identities were dropped
-      output = identity;
-      break;
-    }
-    case 1: {
-      output = SimplifyFormula(outvec[0],false);
-      break;
-    }
-    default: {
-      output = (isAnd) ?
-       (pushNeg ? CreateNode(OR,outvec) : CreateNode(AND,outvec)):
-       (pushNeg ? CreateNode(AND,outvec) : CreateNode(OR,outvec));
-      //output = FlattenOneLevel(output);
-      break;
-    }
-    }
-    //memoize
-    UpdateSimplifyMap(a,output,pushNeg);
-    //cerr << "output:\n" << output << endl;
-    return output;
-  } //end of SimplifyAndOrFormula
-
-
-  ASTNode BeevMgr::SimplifyNotFormula(const ASTNode& a, bool pushNeg) {
-    ASTNode output;
-    if(CheckSimplifyMap(a,output,pushNeg))
-      return output;
-
-    if(!(a.Degree() == 1 && NOT == a.GetKind()))
-      FatalError("SimplifyNotFormula: input vector with more than 1 node",ASTUndefined);
-
-    //if pushNeg is set then there is NOT on top
-    unsigned int NotCount = pushNeg ? 1 : 0;
-    ASTNode o = a;
-    //count the number of NOTs in 'a'
-    while(NOT == o.GetKind()) {
-      o = o[0];
-      NotCount++;
-    }
-
-    //pushnegation if there are odd number of NOTs
-    bool pn = (NotCount % 2 == 0) ? false : true;
-
-    if(CheckAlwaysTrueFormMap(o)) {
-      output = pn ? ASTFalse : ASTTrue;
-      return output;
-    }
-
-    if(CheckSimplifyMap(o,output,pn)) {
-      return output;
-    }
-
-    if (ASTTrue == o) {
-      output = pn ? ASTFalse : ASTTrue;
-    }
-    else if (ASTFalse == o) {
-      output = pn ? ASTTrue : ASTFalse;
-    }
-    else {
-      output = SimplifyFormula(o,pn);
-    }
-    //memoize
-    UpdateSimplifyMap(o,output,pn);
-    UpdateSimplifyMap(a,output,pushNeg);
-    return output;
-  }
-
-  ASTNode BeevMgr::SimplifyXorFormula(const ASTNode& a, bool pushNeg) {
-    ASTNode output;
-    if(CheckSimplifyMap(a,output,pushNeg))
-      return output;
-
-    if (a.GetChildren().size() > 2) {
-      FatalError("Simplify got an XOR with more than two children.");
-    }
-
-    ASTNode a0 = SimplifyFormula(a[0],false);
-    ASTNode a1 = SimplifyFormula(a[1],false);
-    output = pushNeg ? CreateNode(IFF,a0,a1) : CreateNode(XOR,a0,a1);
-
-    if(XOR == output.GetKind()) {
-      a0 = output[0];
-      a1 = output[1];
-      if(a0 == a1)
-       output = ASTFalse;
-      else if(a0 == ASTTrue  && a1 == ASTFalse ||
-             a0 == ASTFalse && a1 == ASTTrue)
-       output = ASTTrue;
-    }
-
-    //memoize
-    UpdateSimplifyMap(a,output,pushNeg);
-    return output;
-  }
-
-  ASTNode BeevMgr::SimplifyNandFormula(const ASTNode& a, bool pushNeg) {
-    ASTNode output,a0,a1;
-    if(CheckSimplifyMap(a,output,pushNeg))
-      return output;
-
-    //the two NOTs cancel out
-    if(pushNeg) {
-      a0 = SimplifyFormula(a[0],false);
-      a1 = SimplifyFormula(a[1],false);
-      output = CreateNode(AND,a0,a1);
-    }
-    else {
-      //push the NOT implicit in the NAND
-      a0 = SimplifyFormula(a[0],true);
-      a1 = SimplifyFormula(a[1],true);
-      output = CreateNode(OR,a0,a1);
-    }
-
-    //memoize
-    UpdateSimplifyMap(a,output,pushNeg);
-    return output;
-  }
-
-  ASTNode BeevMgr::SimplifyNorFormula(const ASTNode& a, bool pushNeg) {
-    ASTNode output,a0,a1;
-    if(CheckSimplifyMap(a,output,pushNeg))
-      return output;
-
-    //the two NOTs cancel out
-    if(pushNeg) {
-      a0 = SimplifyFormula(a[0],false);
-      a1 = SimplifyFormula(a[1],false);
-      output = CreateNode(OR,a0,a1);
-    }
-    else {
-      //push the NOT implicit in the NAND
-      a0 = SimplifyFormula(a[0],true);
-      a1 = SimplifyFormula(a[1],true);
-      output = CreateNode(AND,a0,a1);
-    }
-
-    //memoize
-    UpdateSimplifyMap(a,output,pushNeg);
-    return output;
-  }
-
-  ASTNode BeevMgr::SimplifyImpliesFormula(const ASTNode& a, bool pushNeg) {
-    ASTNode output;
-    if(CheckSimplifyMap(a,output,pushNeg))
-      return output;
-
-    if(!(a.Degree()==2 && IMPLIES==a.GetKind()))
-      FatalError("SimplifyImpliesFormula: vector with wrong num of nodes",ASTUndefined);
-
-    ASTNode c0,c1;
-    if(pushNeg) {
-      c0 = SimplifyFormula(a[0],false);
-      c1 = SimplifyFormula(a[1],true);
-      output = CreateNode(AND,c0,c1);
-    }
-    else {
-      c0 = SimplifyFormula(a[0],false);
-      c1 = SimplifyFormula(a[1],false);
-      if(ASTFalse == c0) {
-       output = ASTTrue;
-      }
-      else if (ASTTrue == c0) {
-       output = c1;
-      }
-      else if (c0 == c1) {
-       output = ASTTrue;
-      }
-      else if(CheckAlwaysTrueFormMap(c0)) {
-       // c0 AND (~c0 OR c1) <==> c1
-       //
-       //applying modus ponens
-       output = c1;
-      }
-      else if(CheckAlwaysTrueFormMap(c1)       ||
-             CheckAlwaysTrueFormMap(CreateNode(NOT,c0)) ||
-             (NOT == c0.GetKind() && CheckAlwaysTrueFormMap(c0[0]))) {
-       //(~c0 AND (~c0 OR c1)) <==> TRUE
-       //
-       //(c0 AND ~c0->c1) <==> TRUE
-       output = ASTTrue;
-      }
-      else if (CheckAlwaysTrueFormMap(CreateNode(NOT,c1)) ||
-              (NOT == c1.GetKind() && CheckAlwaysTrueFormMap(c1[0]))) {
-       //(~c1 AND c0->c1) <==> (~c1 AND ~c1->~c0) <==> ~c0
-       //(c1 AND c0->~c1) <==> (c1 AND c1->~c0) <==> ~c0
-       output = CreateNode(NOT,c0);
-      }
-      else {
-       if(NOT == c0.GetKind()) {
-         output = CreateNode(OR,c0[0],c1);
-       }
-       else {
-         output = CreateNode(OR,CreateNode(NOT,c0),c1);
-       }
-      }
-    }
-
-    //memoize
-    UpdateSimplifyMap(a,output,pushNeg);
-    return output;
-  }
-
-  ASTNode BeevMgr::SimplifyIffFormula(const ASTNode& a, bool pushNeg) {
-    ASTNode output;
-    if(CheckSimplifyMap(a,output,pushNeg))
-      return output;
-
-    if(!(a.Degree()==2 && IFF==a.GetKind()))
-      FatalError("SimplifyIffFormula: vector with wrong num of nodes",ASTUndefined);
-
-    ASTNode c0 = a[0];
-    ASTNode c1 = SimplifyFormula(a[1],false);
-
-    if(pushNeg)
-      c0 = SimplifyFormula(c0,true);
-    else
-      c0 = SimplifyFormula(c0,false);
-
-    if(ASTTrue == c0) {
-      output = c1;
-    }
-    else if (ASTFalse == c0) {
-      output = SimplifyFormula(c1,true);
-    }
-    else if (ASTTrue == c1) {
-      output = c0;
-    }
-    else if (ASTFalse == c1) {
-      output = SimplifyFormula(c0,true);
-    }
-    else if (c0 == c1) {
-      output = ASTTrue;
-    }
-    else if((NOT == c0.GetKind() && c0[0] == c1) ||
-           (NOT == c1.GetKind() && c0 == c1[0])) {
-      output = ASTFalse;
-    }
-    else if(CheckAlwaysTrueFormMap(c0)) {
-      output = c1;
-    }
-    else if(CheckAlwaysTrueFormMap(c1)) {
-      output = c0;
-    }
-    else if(CheckAlwaysTrueFormMap(CreateNode(NOT,c0))) {
-      output = CreateNode(NOT,c1);
-    }
-    else if(CheckAlwaysTrueFormMap(CreateNode(NOT,c1))) {
-      output = CreateNode(NOT,c0);
-    }
-    else {
-      output = CreateNode(IFF,c0,c1);
-    }
-
-    //memoize
-    UpdateSimplifyMap(a,output,pushNeg);
-    return output;
-  }
-
-  ASTNode BeevMgr::SimplifyIteFormula(const ASTNode& b, bool pushNeg) {
-    if(!optimize)
-      return b;
-
-    ASTNode output;
-    if(CheckSimplifyMap(b,output,pushNeg))
-      return output;
-
-    if(!(b.Degree() == 3 && ITE == b.GetKind()))
-      FatalError("SimplifyIteFormula: vector with wrong num of nodes",ASTUndefined);
-
-    ASTNode a = b;
-    ASTNode t0 = SimplifyFormula(a[0],false);
-    ASTNode t1,t2;
-    if(pushNeg) {
-      t1 = SimplifyFormula(a[1],true);
-      t2 = SimplifyFormula(a[2],true);
-    }
-    else {
-      t1 = SimplifyFormula(a[1],false);
-      t2 = SimplifyFormula(a[2],false);
-    }
-
-    if(ASTTrue == t0) {
-      output = t1;
-    }
-    else if (ASTFalse == t0) {
-      output = t2;
-    }
-    else if (t1 == t2) {
-      output = t1;
-    }
-    else if(ASTTrue == t1 && ASTFalse == t2) {
-      output = t0;
-    }
-    else if(ASTFalse == t1 && ASTTrue == t2) {
-      output = SimplifyFormula(t0,true);
-    }
-    else if(ASTTrue == t1) {
-      output = CreateNode(OR,t0,t2);
-    }
-    else if(ASTFalse == t1) {
-      output = CreateNode(AND,CreateNode(NOT,t0),t2);
-    }
-    else if(ASTTrue == t2) {
-      output = CreateNode(OR,CreateNode(NOT,t0),t1);
-    }
-    else if(ASTFalse == t2) {
-      output = CreateNode(AND,t0,t1);
-    }
-    else if(CheckAlwaysTrueFormMap(t0)) {
-      output = t1;
-    }
-    else if(CheckAlwaysTrueFormMap(CreateNode(NOT,t0)) ||
-           (NOT == t0.GetKind() && CheckAlwaysTrueFormMap(t0[0]))) {
-      output = t2;
-    }
-    else {
-      output = CreateNode(ITE,t0,t1,t2);
-    }
-
-    //memoize
-    UpdateSimplifyMap(a,output,pushNeg);
-    return output;
-  }
-
-  //one level deep flattening
-  ASTNode BeevMgr::FlattenOneLevel(const ASTNode& a) {
-    Kind k = a.GetKind();
-    if(!(BVPLUS == k ||
-        AND == k || OR == k
-        //|| BVAND == k
-        //|| BVOR == k
-        )
-       ) {
-      return a;
-    }
-
-    ASTNode output;
-    // if(CheckSimplifyMap(a,output,false)) {
-    //       //check memo table
-    //       //cerr << "output of SimplifyTerm Cache: " << output << endl;
-    //       return output;
-    //     }
-
-    ASTVec c = a.GetChildren();
-    ASTVec o;
-    for(ASTVec::iterator it=c.begin(),itend=c.end();it!=itend;it++) {
-      ASTNode aaa = *it;
-      if(k == aaa.GetKind()) {
-       ASTVec ac = aaa.GetChildren();
-       o.insert(o.end(),ac.begin(),ac.end());
-      }
-      else
-       o.push_back(aaa);
-    }
-
-    if(is_Form_kind(k))
-      output = CreateNode(k,o);
-    else
-      output = CreateTerm(k,a.GetValueWidth(),o);
-
-    //UpdateSimplifyMap(a,output,false);
-    return output;
-    //memoize
-  } //end of flattenonelevel()
-
-  ASTNode BeevMgr::SimplifyTerm_TopLevel(const ASTNode& b) {
-    ResetSimplifyMaps();
-    ASTNode out = SimplifyTerm(b);
-    ResetSimplifyMaps();
-    return out;
-  }
-
-  //This function simplifies terms based on their kind
-  ASTNode BeevMgr::SimplifyTerm(const ASTNode& inputterm) {
-    //cout << "SimplifyTerm: input: " << a << endl;
-    if(!optimize) {
-      return inputterm;
-    }
-
-    ASTNode output;
-    BVTypeCheck(inputterm);
-
-    //########################################
-    //########################################
-
-    if(wordlevel_solve && CheckSolverMap(inputterm,output)) {
-      //cout << "SimplifyTerm: output: " << output << endl;
-      return SimplifyTerm(output);
-    }
-
-
-    if(CheckSimplifyMap(inputterm,output,false)) {
-      //cerr << "output of SimplifyTerm Cache: " << output << endl;
-      return output;
-    }
-    //########################################
-    //########################################
-
-    Kind k = inputterm.GetKind();
-    if(!is_Term_kind(k)) {
-      FatalError("SimplifyTerm: You have input a Non-term",ASTUndefined);
-    }
-
-    unsigned int inputValueWidth = inputterm.GetValueWidth();
-    switch(k) {
-    case BVCONST:
-      output = inputterm;
-      break;
-    case SYMBOL:
-      if(CheckSolverMap(inputterm,output)) {
-       return SimplifyTerm(output);
-      }
-      output = inputterm;
-      break;
-    case BVMULT:
-   {
-      if(2 != inputterm.Degree())
-      {
-               FatalError("SimplifyTerm: We assume that BVMULT is binary",inputterm);
-      }
-
-      // Described nicely by Warren, Hacker's Delight pg 135.
-      // Turn sequences of one bits into subtractions.
-      // 28*x == 32x - 4x (two instructions), rather than 16x+ 8x+ 4x.
-      // When fully implemented. I.e. supporting sequences of 1 anywhere.
-      // Other simplifications will try to fold these back in. So need to be careful
-      // about when the simplifications are applied. But in this version it won't
-      // be simplified down by anything else.
-
-
-      // This (temporary) version only simplifies if all the left most bits are set.
-      // All the leftmost bits being set simplifies very nicely down.
-      const ASTNode& n0 = inputterm.GetChildren()[0];
-      const ASTNode& n1 = inputterm.GetChildren()[1];
-
-      // This implementation has two problems.
-      // 1) It causes a segfault for cmu-model15,16,17
-      // 2) It doesn't count the number of bits saved, so if there is a single
-      // leading bit it will invert it. Even though that will take more shifts
-      // and adds when it's finally done.
-
-      // disabled.
-      if (false && (BVCONST == n0.GetKind()) ^ (BVCONST == n1.GetKind()))
-      {
-               CBV constant = (BVCONST == n0.GetKind())? n0.GetBVConst(): n1.GetBVConst();
-               ASTNode other = (BVCONST == n0.GetKind())? n1: n0;
-
-               int startSequence = 0;
-               for (unsigned int i = 0; i < inputValueWidth; i++)
-               {
-                       if (!CONSTANTBV::BitVector_bit_test(constant,i))
-                               startSequence = i;
-               }
-
-               if((inputValueWidth - startSequence) > 3)
-               {
-                       // turn off all bits from "startSequence to the end", then add one.
-                       CBV maskedPlusOne = CONSTANTBV::BitVector_Create(inputValueWidth,true);
-                       for (int i=0; i < startSequence;i++)
-                       {
-                               if (!CONSTANTBV::BitVector_bit_test(constant,i)) // swap
-                                       CONSTANTBV::BitVector_Bit_On(maskedPlusOne, i);
-                       }
-                       CONSTANTBV::BitVector_increment(maskedPlusOne);
-                       ASTNode temp = CreateTerm(BVMULT,inputValueWidth, CreateBVConst(maskedPlusOne,inputValueWidth),other);
-                       output = CreateTerm(BVNEG, inputValueWidth, temp);
-               }
-      }
-
-   }
-   if(NULL != output)
-          break;
-
-    case BVPLUS:{
-
-      ASTVec c = FlattenOneLevel(inputterm).GetChildren();
-      SortByArith(c);
-      ASTVec constkids, nonconstkids;
-
-      //go through the childnodes, and separate constant and
-      //nonconstant nodes. combine the constant nodes using the
-      //constevaluator. if the resultant constant is zero and k ==
-      //BVPLUS, then ignore it (similarily for 1 and BVMULT).  else,
-      //add the computed constant to the nonconst vector, flatten,
-      //sort, and create BVPLUS/BVMULT and return
-      for(ASTVec::iterator it=c.begin(),itend=c.end();it!=itend;it++) {
-       ASTNode aaa = SimplifyTerm(*it);
-       if(BVCONST == aaa.GetKind()) {
-         constkids.push_back(aaa);
-       }
-       else {
-         nonconstkids.push_back(aaa);
-       }
-      }
-
-      ASTNode one = CreateOneConst(inputValueWidth);
-      ASTNode max = CreateMaxConst(inputValueWidth);
-      ASTNode zero = CreateZeroConst(inputValueWidth);
-
-      //initialize constoutput to zero, in case there are no elements
-      //in constkids
-      ASTNode constoutput = (k == BVPLUS) ? zero : one;
-
-      if(1 == constkids.size()) {
-       //only one element in constkids
-       constoutput = constkids[0];
-      }
-      else if (1 < constkids.size()) {
-       //many elements in constkids. simplify it
-       constoutput = CreateTerm(k,inputterm.GetValueWidth(),constkids);
-       constoutput = BVConstEvaluator(constoutput);
-      }
-
-      if(BVMULT == k && zero == constoutput) {
-       output = zero;
-      }
-      else if(BVMULT == k &&
-             1 == nonconstkids.size() &&
-             constoutput == max) {
-       //useful special case opt: when input is BVMULT(max_const,t),
-       //then output = BVUMINUS(t). this is easier on the bitblaster
-       output = CreateTerm(BVUMINUS,inputValueWidth,nonconstkids);
-      }
-      else {
-       if(0 < nonconstkids.size()) {
-         //nonconstkids is not empty. First, combine const and
-         //nonconstkids
-         if(BVPLUS == k && constoutput != zero) {
-           nonconstkids.push_back(constoutput);
-         }
-         else if(BVMULT == k && constoutput != one) {
-           nonconstkids.push_back(constoutput);
-         }
-
-         if(1 == nonconstkids.size()) {
-           //exactly one element in nonconstkids. output is exactly
-           //nonconstkids[0]
-           output = nonconstkids[0];
-         }
-         else {
-           //more than 1 element in nonconstkids. create BVPLUS term
-           SortByArith(nonconstkids);
-           output = CreateTerm(k,inputValueWidth,nonconstkids);
-           output = FlattenOneLevel(output);
-           output = DistributeMultOverPlus(output,true);
-           output = CombineLikeTerms(output);
-         }
-       }
-       else {
-         //nonconstkids was empty, all childnodes were constant, hence
-         //constoutput is the output.
-         output = constoutput;
-       }
-      }
-      if(BVMULT == output.GetKind()
-        || BVPLUS == output.GetKind()
-        ) {
-       ASTVec d = output.GetChildren();
-       SortByArith(d);
-       output = CreateTerm(output.GetKind(),output.GetValueWidth(),d);
-      }
-      break;
-    }
-    case BVSUB: {
-      ASTVec c = inputterm.GetChildren();
-      ASTNode a0 = SimplifyTerm(inputterm[0]);
-      ASTNode a1 = SimplifyTerm(inputterm[1]);
-      unsigned int l = inputValueWidth;
-      if(a0 == a1)
-       output = CreateZeroConst(l);
-      else {
-       //covert x-y into x+(-y) and simplify. this transformation
-       //triggers more simplifications
-   //
-       a1 = SimplifyTerm(CreateTerm(BVUMINUS,l,a1));
-       output = SimplifyTerm(CreateTerm(BVPLUS,l,a0,a1));
-      }
-      break;
-    }
-    case BVUMINUS: {
-      //important to treat BVUMINUS as a special case, because it
-      //helps in arithmetic transformations. e.g.  x + BVUMINUS(x) is
-      //actually 0. One way to reveal this fact is to strip bvuminus
-      //out, and replace with something else so that combineliketerms
-      //can catch this fact.
-      ASTNode a0 = SimplifyTerm(inputterm[0]);
-      Kind k1 = a0.GetKind();
-      unsigned int l = a0.GetValueWidth();
-      ASTNode one = CreateOneConst(l);
-      switch(k1) {
-      case BVUMINUS:
-       output = a0[0];
-       break;
-      case BVCONST: {
-       output = BVConstEvaluator(CreateTerm(BVUMINUS,l,a0));
-       break;
-      }
-      case BVNEG: {
-       output = SimplifyTerm(CreateTerm(BVPLUS,l,a0[0],one));
-       break;
-      }
-      case BVMULT: {
-       if(BVUMINUS == a0[0].GetKind()) {
-         output = CreateTerm(BVMULT,l,a0[0][0],a0[1]);
-       }
-       else if(BVUMINUS == a0[1].GetKind()) {
-         output = CreateTerm(BVMULT,l,a0[0],a0[1][0]);
-       }
-       else {
-         ASTNode a00 = SimplifyTerm(CreateTerm(BVUMINUS,l,a0[0]));
-         output = CreateTerm(BVMULT,l,a00,a0[1]);
-       }
-       break;
-      }
-      case BVPLUS: {
-       //push BVUMINUS over all the monomials of BVPLUS. Simplify
-       //along the way
-       //
-       //BVUMINUS(a1x1 + a2x2 + ...) <=> BVPLUS(BVUMINUS(a1x1) +
-       //BVUMINUS(a2x2) + ...
-       ASTVec c = a0.GetChildren();
-       ASTVec o;
-       for(ASTVec::iterator it=c.begin(),itend=c.end();it!=itend;it++) {
-         //Simplify(BVUMINUS(a1x1))
-         ASTNode aaa = SimplifyTerm(CreateTerm(BVUMINUS,l,*it));
-         o.push_back(aaa);
-       }
-       //simplify the bvplus
-       output = SimplifyTerm(CreateTerm(BVPLUS,l,o));
-       break;
-      }
-      case BVSUB: {
-       //BVUMINUS(BVSUB(x,y)) <=> BVSUB(y,x)
-       output = SimplifyTerm(CreateTerm(BVSUB,l,a0[1],a0[0]));
-       break;
-      }
-      case ITE: {
-       //BVUMINUS(ITE(c,t1,t2)) <==> ITE(c,BVUMINUS(t1),BVUMINUS(t2))
-       ASTNode c = a0[0];
-       ASTNode t1 = SimplifyTerm(CreateTerm(BVUMINUS,l,a0[1]));
-       ASTNode t2 = SimplifyTerm(CreateTerm(BVUMINUS,l,a0[2]));
-       output = CreateSimplifiedTermITE(c,t1,t2);
-       break;
-      }
-      default: {
-       output = CreateTerm(BVUMINUS,l,a0);
-       break;
-      }
-      }
-      break;
-    }
-    case BVEXTRACT:{
-      //it is important to take care of wordlevel transformation in
-      //BVEXTRACT. it exposes oppurtunities for later simplification
-      //and solving (variable elimination)
-      ASTNode a0 = SimplifyTerm(inputterm[0]);
-      Kind k1 = a0.GetKind();
-      unsigned int a_len = inputValueWidth;
-
-      //indices for BVEXTRACT
-      ASTNode i = inputterm[1];
-      ASTNode j = inputterm[2];
-      ASTNode zero = CreateBVConst(32,0);
-      //recall that the indices of BVEXTRACT are always 32 bits
-      //long. therefore doing a GetBVUnsigned is ok.
-      unsigned int i_val = GetUnsignedConst(i);
-      unsigned int j_val = GetUnsignedConst(j);
-
-      // a0[i:0] and len(a0)=i+1, then return a0
-      if(0 == j_val && a_len == a0.GetValueWidth())
-       return a0;
-
-      switch(k1) {
-      case BVCONST: {
-       //extract the constant
-       output = BVConstEvaluator(CreateTerm(BVEXTRACT,a_len,a0,i,j));
-       break;
-      }
-      case BVCONCAT:{
-       //assumes concatenation is binary
-       //
-       //input is of the form a0[i:j]
-       //
-       //a0 is the conatentation t@u, and a0[0] is t, and a0[1] is u
-       ASTNode t = a0[0];
-       ASTNode u = a0[1];
-       unsigned int len_a0 = a0.GetValueWidth();
-       unsigned int len_u = u.GetValueWidth();
-
-       if(len_u > i_val) {
-         //Apply the following rule:
-         // (t@u)[i:j] <==> u[i:j], if len(u) > i
-         //
-         output = SimplifyTerm(CreateTerm(BVEXTRACT,a_len,u,i,j));
-       }
-       else if(len_a0 > i_val && j_val >= len_u) {
-         //Apply the rule:
-         // (t@u)[i:j] <==> t[i-len_u:j-len_u], if len(t@u) > i >= j >= len(u)
-         i = CreateBVConst(32, i_val - len_u);
-         j = CreateBVConst(32, j_val - len_u);
-         output = SimplifyTerm(CreateTerm(BVEXTRACT,a_len,t,i,j));
-       }
-       else {
-         //Apply the rule:
-         // (t@u)[i:j] <==> t[i-len_u:0] @ u[len_u-1:j]
-         i = CreateBVConst(32,i_val-len_u);
-         ASTNode m = CreateBVConst(32, len_u-1);
-         t = SimplifyTerm(CreateTerm(BVEXTRACT,i_val-len_u+1,t,i,zero));
-         u = SimplifyTerm(CreateTerm(BVEXTRACT,len_u-j_val,u,m,j));
-         output = CreateTerm(BVCONCAT,a_len,t,u);
-       }
-       break;
-      }
-      case BVPLUS:
-      case BVMULT: {
-       // (BVMULT(n,t,u))[i:j] <==> BVMULT(i+1,t[i:0],u[i:0])[i:j]
-       //similar rule for BVPLUS
-       ASTVec c = a0.GetChildren();
-       ASTVec o;
-       for(ASTVec::iterator jt=c.begin(),jtend=c.end();jt!=jtend;jt++) {
-         ASTNode aaa = *jt;
-         aaa = SimplifyTerm(CreateTerm(BVEXTRACT,i_val+1,aaa,i,zero));
-         o.push_back(aaa);
-       }
-       output = CreateTerm(a0.GetKind(),i_val+1,o);
-       if(j_val != 0) {
-         //add extraction only if j is not zero
-         output = CreateTerm(BVEXTRACT,a_len,output,i,j);
-       }
-       break;
-      }
-      case BVAND:
-      case BVOR:
-      case BVXOR: {
-       //assumes these operators are binary
-       //
-       // (t op u)[i:j] <==> t[i:j] op u[i:j]
-       ASTNode t = a0[0];
-       ASTNode u = a0[1];
-       t = SimplifyTerm(CreateTerm(BVEXTRACT,a_len,t,i,j));
-       u = SimplifyTerm(CreateTerm(BVEXTRACT,a_len,u,i,j));
-       BVTypeCheck(t);
-       BVTypeCheck(u);
-       output = CreateTerm(k1,a_len,t,u);
-       break;
-      }
-      case BVNEG:{
-       // (~t)[i:j] <==> ~(t[i:j])
-       ASTNode t = a0[0];
-       t = SimplifyTerm(CreateTerm(BVEXTRACT,a_len,t,i,j));
-       output = CreateTerm(BVNEG,a_len,t);
-       break;
-      }
-      // case BVSX:{
-//     //(BVSX(t,n)[i:j] <==> BVSX(t,i+1), if n >= i+1 and j=0
-//     ASTNode t = a0[0];
-//     unsigned int bvsx_len = a0.GetValueWidth();
-//     if(bvsx_len < a_len) {
-//       FatalError("SimplifyTerm: BVEXTRACT over BVSX:"
-//                  "the length of BVSX term must be greater than extract-len",inputterm);
-//     }
-//     if(j != zero) {
-//       output = CreateTerm(BVEXTRACT,a_len,a0,i,j);
-//     }
-//     else {
-//       output = CreateTerm(BVSX,a_len,t,CreateBVConst(32,a_len));
-//     }
-//     break;
-//       }
-      case ITE: {
-       ASTNode t0 = a0[0];
-       ASTNode t1 = SimplifyTerm(CreateTerm(BVEXTRACT,a_len,a0[1],i,j));
-       ASTNode t2 = SimplifyTerm(CreateTerm(BVEXTRACT,a_len,a0[2],i,j));
-       output = CreateSimplifiedTermITE(t0,t1,t2);
-       break;
-      }
-      default: {
-       output = CreateTerm(BVEXTRACT,a_len,a0,i,j);
-       break;
-      }
-      }
-      break;
-    }
-    case BVNEG: {
-      ASTNode a0 = SimplifyTerm(inputterm[0]);
-      unsigned len = inputValueWidth;
-      switch(a0.GetKind()) {
-      case BVCONST:
-       output = BVConstEvaluator(CreateTerm(BVNEG,len,a0));
-       break;
-      case BVNEG:
-       output = a0[0];
-       break;
-      // case ITE: {
-//     ASTNode cond = a0[0];
-//     ASTNode thenpart = SimplifyTerm(CreateTerm(BVNEG,len,a0[1]));
-//     ASTNode elsepart = SimplifyTerm(CreateTerm(BVNEG,len,a0[2]));
-//     output = CreateSimplifiedTermITE(cond,thenpart,elsepart);
-//     break;
-//       }
-      default:
-       output = CreateTerm(BVNEG,len,a0);
-       break;
-      }
-      break;
-    }
-
-   case BVZX:
-      {
-       ASTNode a0 = SimplifyTerm(inputterm[0]);
-       if (a0.GetKind() ==  BVCONST)
-         output = BVConstEvaluator(CreateTerm(BVZX,inputValueWidth,a0,inputterm[1]));
+       if (ASTTrue == o)
+       {
+               output = pn ? ASTFalse : ASTTrue;
+       }
+       else if (ASTFalse == o)
+       {
+               output = pn ? ASTTrue : ASTFalse;
+       }
        else
-         output = CreateTerm(BVZX,inputValueWidth,a0,inputterm[1]);
-      }
-       break;
-
-
-    case BVSX:{
-      //a0 is the expr which is being sign extended
-      ASTNode a0 = SimplifyTerm(inputterm[0]);
-      //a1 represents the length of the term BVSX(a0)
-      ASTNode a1 = inputterm[1];
-      //output length of the BVSX term
-      unsigned len = inputValueWidth;
-
-      if(a0.GetValueWidth() == len) {
-       //nothing to signextend
-       return a0;
-      }
-
-      switch(a0.GetKind()) {
-      case BVCONST:
-       output = BVConstEvaluator(CreateTerm(BVSX,len,a0,a1));
-       break;
-      case BVNEG:
-       output = CreateTerm(a0.GetKind(),len,CreateTerm(BVSX,len,a0[0],a1));
-       break;
-      case BVAND:
-      case BVOR:
-       //assuming BVAND and BVOR are binary
-       output = CreateTerm(a0.GetKind(),len,
-                           CreateTerm(BVSX,len,a0[0],a1),
-                           CreateTerm(BVSX,len,a0[1],a1));
-       break;
-      case BVPLUS: {
-       //BVSX(m,BVPLUS(n,BVSX(t1),BVSX(t2))) <==> BVPLUS(m,BVSX(m,t1),BVSX(m,t2))
-       ASTVec c = a0.GetChildren();
-       bool returnflag = false;
-       for(ASTVec::iterator it=c.begin(),itend=c.end();it!=itend;it++) {
-         if(BVSX != it->GetKind()) {
-           returnflag = true;
-           break;
-         }
-       }
-       if(returnflag) {
-         output = CreateTerm(BVSX,len,a0,a1);
-       }
-       else {
-         ASTVec o;
-         for(ASTVec::iterator it=c.begin(),itend=c.end();it!=itend;it++) {
-           ASTNode aaa = SimplifyTerm(CreateTerm(BVSX,len,*it,a1));
-           o.push_back(aaa);
-         }
-         output = CreateTerm(a0.GetKind(),len,o);
-       }
-       break;
-      }
-      case BVSX: {
-       //if you have BVSX(m,BVSX(n,a)) then you can drop the inner
-       //BVSX provided m is greater than n.
-       a0 = SimplifyTerm(a0[0]);
-       output = CreateTerm(BVSX,len,a0,a1);
-       break;
-      }
-      case ITE: {
-       ASTNode cond = a0[0];
-       ASTNode thenpart = SimplifyTerm(CreateTerm(BVSX,len,a0[1],a1));
-       ASTNode elsepart = SimplifyTerm(CreateTerm(BVSX,len,a0[2],a1));
-       output = CreateSimplifiedTermITE(cond,thenpart,elsepart);
-       break;
-      }
-      default:
-       output = CreateTerm(BVSX,len,a0,a1);
-       break;
-      }
-      break;
-    }
-    case BVAND:
-    case BVOR:{
-      ASTNode max = CreateMaxConst(inputValueWidth);
-      ASTNode zero = CreateZeroConst(inputValueWidth);
-
-      ASTNode identity = (BVAND == k) ? max : zero;
-      ASTNode annihilator = (BVAND == k) ? zero : max;
-      ASTVec c = FlattenOneLevel(inputterm).GetChildren();
-      SortByArith(c);
-      ASTVec o;
-      bool constant = true;
-      for(ASTVec::iterator it=c.begin(),itend=c.end();it!=itend;it++) {
-       ASTNode aaa = SimplifyTerm(*it);
-       if(BVCONST != aaa.GetKind()) {
-         constant = false;
-       }
-
-       if(aaa == annihilator) {
-         output = annihilator;
-         //memoize
-         UpdateSimplifyMap(inputterm,output,false);
-         //cerr << "output of SimplifyTerm: " << output << endl;
-         return output;
-       }
-
-       if(aaa != identity) {
-         o.push_back(aaa);
-       }
-      }
-
-      switch(o.size()) {
-      case 0:
-       output = identity;
-       break;
-      case 1:
-       output = o[0];
-       break;
-      default:
-       SortByArith(o);
-       output = CreateTerm(k,inputValueWidth,o);
-       if(constant) {
-         output = BVConstEvaluator(output);
-       }
-       break;
-      }
-      break;
-    }
-    case BVCONCAT:{
-      ASTNode t = SimplifyTerm(inputterm[0]);
-      ASTNode u = SimplifyTerm(inputterm[1]);
-      Kind tkind = t.GetKind();
-      Kind ukind = u.GetKind();
-
-
-      if(BVCONST == tkind && BVCONST == ukind) {
-       output = BVConstEvaluator(CreateTerm(BVCONCAT,inputValueWidth,t,u));
-      }
-      else if(BVEXTRACT == tkind &&
-             BVEXTRACT == ukind &&
-             t[0] == u[0]) {
-       //to handle the case x[m:n]@x[n-1:k] <==> x[m:k]
-       ASTNode t_hi = t[1];
-       ASTNode t_low = t[2];
-       ASTNode u_hi = u[1];
-       ASTNode u_low = u[2];
-       ASTNode c = BVConstEvaluator(CreateTerm(BVPLUS,32,u_hi,CreateOneConst(32)));
-       if(t_low == c) {
-         output = CreateTerm(BVEXTRACT,inputValueWidth,t[0],t_hi,u_low);
-       }
-       else {
-         output = CreateTerm(BVCONCAT,inputValueWidth,t,u);
-       }
-      }
-      else {
-       output = CreateTerm(BVCONCAT,inputValueWidth,t,u);
-      }
-      break;
-    }
-    case BVXOR:
-    case BVXNOR:
-    case BVNAND:
-    case BVNOR:
-    case BVLEFTSHIFT:
-    case BVRIGHTSHIFT:
-    case BVVARSHIFT:
-    case BVSRSHIFT:
-    case BVDIV:
-    case BVMOD: {
-      ASTVec c = inputterm.GetChildren();
-      ASTVec o;
-      bool constant = true;
-      for(ASTVec::iterator it=c.begin(),itend=c.end();it!=itend;it++) {
-       ASTNode aaa = SimplifyTerm(*it);
-       if(BVCONST != aaa.GetKind()) {
-         constant = false;
-       }
-       o.push_back(aaa);
-      }
-      output = CreateTerm(k,inputValueWidth,o);
-      if(constant)
-       output = BVConstEvaluator(output);
-      break;
-    }
-    case READ: {
-      ASTNode out1;
-      //process only if not  in the substitution map. simplifymap
-      //has been checked already
-      if(!CheckSubstitutionMap(inputterm,out1)) {
-       if(WRITE == inputterm[0].GetKind()) {
-         //get rid of all writes
-         ASTNode nowrites = RemoveWrites_TopLevel(inputterm);
-         out1 = nowrites;
-       }
-       else if (ITE == inputterm[0].GetKind()){
-         ASTNode cond = SimplifyFormula(inputterm[0][0],false);
-         ASTNode index = SimplifyTerm(inputterm[1]);
-
-         ASTNode read1 = CreateTerm(READ,inputValueWidth,inputterm[0][1],index);
-         ASTNode read2 = CreateTerm(READ,inputValueWidth,inputterm[0][2],index);
-
-         read1 = SimplifyTerm(read1);
-         read2 = SimplifyTerm(read2);
-         out1 = CreateSimplifiedTermITE(cond,read1,read2);
-       }
-       else {
-         //arr is a SYMBOL for sure
-         ASTNode arr = inputterm[0];
-         ASTNode index = SimplifyTerm(inputterm[1]);
-         out1 = CreateTerm(READ,inputValueWidth,arr,index);
-       }
-      }
-      //it is possible that after all the procesing the READ term
-      //reduces to READ(Symbol,const) and hence we should check the
-      //substitutionmap once again.
-      if(!CheckSubstitutionMap(out1,output))
-       output = out1;
-      break;
-    }
-    case ITE: {
-      ASTNode t0 = SimplifyFormula(inputterm[0],false);
-      ASTNode t1 = SimplifyTerm(inputterm[1]);
-      ASTNode t2 = SimplifyTerm(inputterm[2]);
-      output = CreateSimplifiedTermITE(t0,t1,t2);
-      break;
-    }
-    case SBVREM:
-    case SBVDIV: {
-      ASTVec c = inputterm.GetChildren();
-      ASTVec o;
-      for(ASTVec::iterator it=c.begin(),itend=c.end();it!=itend;it++) {
-       ASTNode aaa = SimplifyTerm(*it);
-       o.push_back(aaa);
-      }
-      output = CreateTerm(k,inputValueWidth,o);
-      break;
-    }
-    case WRITE:
-    default:
-      FatalError("SimplifyTerm: Control should never reach here:", inputterm, k);
-      return inputterm;
-      break;
-    }
-       assert(NULL != output);
+       {
+               output = SimplifyFormula(o, pn);
+       }
+       //memoize
+       UpdateSimplifyMap(o, output, pn);
+       UpdateSimplifyMap(a, output, pushNeg);
+       return output;
+}
 
+ASTNode BeevMgr::SimplifyXorFormula(const ASTNode& a, bool pushNeg)
+{
+       ASTNode output;
+       if (CheckSimplifyMap(a, output, pushNeg))
+               return output;
 
-    //memoize
-    UpdateSimplifyMap(inputterm,output,false);
-    //cerr << "SimplifyTerm: output" << output << endl;
-    // CheckSimplifyInvariant(inputterm,output);
-
-    return output;
-  } //end of SimplifyTerm()
-
-  ASTNode BeevMgr::SimplifyTermAux(const ASTNode& inputterm) {
-    //cout << "SimplifyTerm: input: " << a << endl;
-    if(!optimize) {
-      return inputterm;
-    }
-
-    ASTNode output;
-    BVTypeCheck(inputterm);
-
-    //########################################
-    //########################################
-
-    if(wordlevel_solve && CheckSolverMap(inputterm,output)) {
-      //cout << "SimplifyTerm: output: " << output << endl;
-      return SimplifyTermAux(output);
-    }
-
-    Kind k = inputterm.GetKind();
-    if(!is_Term_kind(k)) {
-      FatalError("SimplifyTerm: You have input a Non-term",ASTUndefined);
-    }
-
-    unsigned int inputValueWidth = inputterm.GetValueWidth();
-    switch(k) {
-    case BVCONST:
-      output = inputterm;
-      break;
-    case SYMBOL:
-      if(CheckSolverMap(inputterm,output)) {
-       return SimplifyTerm(output);
-      }
-      output = inputterm;
-      break;
-    case BVMULT:
-    case BVPLUS:{
-      if(BVMULT == k && 2 != inputterm.Degree()) {
-       FatalError("SimplifyTerm: We assume that BVMULT is binary",inputterm);
-      }
-
-      ASTVec c = FlattenOneLevel(inputterm).GetChildren();
-      SortByArith(c);
-      ASTVec constkids, nonconstkids;
-
-      //go through the childnodes, and separate constant and
-      //nonconstant nodes. combine the constant nodes using the
-      //constevaluator. if the resultant constant is zero and k ==
-      //BVPLUS, then ignore it (similarily for 1 and BVMULT).  else,
-      //add the computed constant to the nonconst vector, flatten,
-      //sort, and create BVPLUS/BVMULT and return
-      for(ASTVec::iterator it=c.begin(),itend=c.end();it!=itend;it++) {
-       ASTNode aaa = SimplifyTerm(*it);
-       if(BVCONST == aaa.GetKind()) {
-         constkids.push_back(aaa);
-       }
-       else {
-         nonconstkids.push_back(aaa);
-       }
-      }
-
-      ASTNode one = CreateOneConst(inputValueWidth);
-      ASTNode max = CreateMaxConst(inputValueWidth);
-      ASTNode zero = CreateZeroConst(inputValueWidth);
-
-      //initialize constoutput to zero, in case there are no elements
-      //in constkids
-      ASTNode constoutput = (k == BVPLUS) ? zero : one;
-
-      if(1 == constkids.size()) {
-       //only one element in constkids
-       constoutput = constkids[0];
-      }
-      else if (1 < constkids.size()) {
-       //many elements in constkids. simplify it
-       constoutput = CreateTerm(k,inputterm.GetValueWidth(),constkids);
-       constoutput = BVConstEvaluator(constoutput);
-      }
-
-      if(BVMULT == k && zero == constoutput) {
-       output = zero;
-      }
-      else if(BVMULT == k &&
-             1 == nonconstkids.size() &&
-             constoutput == max) {
-       //useful special case opt: when input is BVMULT(max_const,t),
-       //then output = BVUMINUS(t). this is easier on the bitblaster
-       output = CreateTerm(BVUMINUS,inputValueWidth,nonconstkids);
-      }
-      else {
-       if(0 < nonconstkids.size()) {
-         //nonconstkids is not empty. First, combine const and
-         //nonconstkids
-         if(BVPLUS == k && constoutput != zero) {
-           nonconstkids.push_back(constoutput);
-         }
-         else if(BVMULT == k && constoutput != one) {
-           nonconstkids.push_back(constoutput);
-         }
-
-         if(1 == nonconstkids.size()) {
-           //exactly one element in nonconstkids. output is exactly
-           //nonconstkids[0]
-           output = nonconstkids[0];
-         }
-         else {
-           //more than 1 element in nonconstkids. create BVPLUS term
-           SortByArith(nonconstkids);
-           output = CreateTerm(k,inputValueWidth,nonconstkids);
-           output = FlattenOneLevel(output);
-           output = DistributeMultOverPlus(output,true);
-           output = CombineLikeTerms(output);
-         }
-       }
-       else {
-         //nonconstkids was empty, all childnodes were constant, hence
-         //constoutput is the output.
-         output = constoutput;
-       }
-      }
-      if(BVMULT == output.GetKind()
-        || BVPLUS == output.GetKind()
-        ) {
-       ASTVec d = output.GetChildren();
-       SortByArith(d);
-       output = CreateTerm(output.GetKind(),output.GetValueWidth(),d);
-      }
-      break;
-    }
-    case BVSUB: {
-      ASTVec c = inputterm.GetChildren();
-      ASTNode a0 = SimplifyTerm(inputterm[0]);
-      ASTNode a1 = SimplifyTerm(inputterm[1]);
-      unsigned int l = inputValueWidth;
-      if(a0 == a1)
-       output = CreateZeroConst(l);
-      else {
-       //covert x-y into x+(-y) and simplify. this transformation
-       //triggers more simplifications
-   //
-       a1 = SimplifyTerm(CreateTerm(BVUMINUS,l,a1));
-       output = SimplifyTerm(CreateTerm(BVPLUS,l,a0,a1));
-      }
-      break;
-    }
-    case BVUMINUS: {
-      //important to treat BVUMINUS as a special case, because it
-      //helps in arithmetic transformations. e.g.  x + BVUMINUS(x) is
-      //actually 0. One way to reveal this fact is to strip bvuminus
-      //out, and replace with something else so that combineliketerms
-      //can catch this fact.
-      ASTNode a0 = SimplifyTerm(inputterm[0]);
-      Kind k1 = a0.GetKind();
-      unsigned int l = a0.GetValueWidth();
-      ASTNode one = CreateOneConst(l);
-      switch(k1) {
-      case BVUMINUS:
-       output = a0[0];
-       break;
-      case BVCONST: {
-       output = BVConstEvaluator(CreateTerm(BVUMINUS,l,a0));
-       break;
-      }
-      case BVNEG: {
-       output = SimplifyTerm(CreateTerm(BVPLUS,l,a0[0],one));
-       break;
-      }
-      case BVMULT: {
-       if(BVUMINUS == a0[0].GetKind()) {
-         output = CreateTerm(BVMULT,l,a0[0][0],a0[1]);
-       }
-       else if(BVUMINUS == a0[1].GetKind()) {
-         output = CreateTerm(BVMULT,l,a0[0],a0[1][0]);
-       }
-       else {
-         ASTNode a00 = SimplifyTerm(CreateTerm(BVUMINUS,l,a0[0]));
-         output = CreateTerm(BVMULT,l,a00,a0[1]);
-       }
-       break;
-      }
-      case BVPLUS: {
-       //push BVUMINUS over all the monomials of BVPLUS. Simplify
-       //along the way
-       //
-       //BVUMINUS(a1x1 + a2x2 + ...) <=> BVPLUS(BVUMINUS(a1x1) +
-       //BVUMINUS(a2x2) + ...
-       ASTVec c = a0.GetChildren();
-       ASTVec o;
-       for(ASTVec::iterator it=c.begin(),itend=c.end();it!=itend;it++) {
-         //Simplify(BVUMINUS(a1x1))
-         ASTNode aaa = SimplifyTerm(CreateTerm(BVUMINUS,l,*it));
-         o.push_back(aaa);
-       }
-       //simplify the bvplus
-       output = SimplifyTerm(CreateTerm(BVPLUS,l,o));
-       break;
-      }
-      case BVSUB: {
-       //BVUMINUS(BVSUB(x,y)) <=> BVSUB(y,x)
-       output = SimplifyTerm(CreateTerm(BVSUB,l,a0[1],a0[0]));
-       break;
-      }
-      case ITE: {
-       //BVUMINUS(ITE(c,t1,t2)) <==> ITE(c,BVUMINUS(t1),BVUMINUS(t2))
-       ASTNode c = a0[0];
-       ASTNode t1 = SimplifyTerm(CreateTerm(BVUMINUS,l,a0[1]));
-       ASTNode t2 = SimplifyTerm(CreateTerm(BVUMINUS,l,a0[2]));
-       output = CreateSimplifiedTermITE(c,t1,t2);
-       break;
-      }
-      default: {
-       output = CreateTerm(BVUMINUS,l,a0);
-       break;
-      }
-      }
-      break;
-    }
-    case BVEXTRACT:{
-      //it is important to take care of wordlevel transformation in
-      //BVEXTRACT. it exposes oppurtunities for later simplification
-      //and solving (variable elimination)
-      ASTNode a0 = SimplifyTerm(inputterm[0]);
-      Kind k1 = a0.GetKind();
-      unsigned int a_len = inputValueWidth;
-
-      //indices for BVEXTRACT
-      ASTNode i = inputterm[1];
-      ASTNode j = inputterm[2];
-      ASTNode zero = CreateBVConst(32,0);
-      //recall that the indices of BVEXTRACT are always 32 bits
-      //long. therefore doing a GetBVUnsigned is ok.
-      unsigned int i_val = GetUnsignedConst(i);
-      unsigned int j_val = GetUnsignedConst(j);
-
-      // a0[i:0] and len(a0)=i+1, then return a0
-      if(0 == j_val && a_len == a0.GetValueWidth())
-       return a0;
-
-      switch(k1) {
-      case BVCONST: {
-       //extract the constant
-       output = BVConstEvaluator(CreateTerm(BVEXTRACT,a_len,a0,i,j));
-       break;
-      }
-      case BVCONCAT:{
-       //assumes concatenation is binary
-       //
-       //input is of the form a0[i:j]
-       //
-       //a0 is the conatentation t@u, and a0[0] is t, and a0[1] is u
-       ASTNode t = a0[0];
-       ASTNode u = a0[1];
-       unsigned int len_a0 = a0.GetValueWidth();
-       unsigned int len_u = u.GetValueWidth();
-
-       if(len_u > i_val) {
-         //Apply the following rule:
-         // (t@u)[i:j] <==> u[i:j], if len(u) > i
-         //
-         output = SimplifyTerm(CreateTerm(BVEXTRACT,a_len,u,i,j));
-       }
-       else if(len_a0 > i_val && j_val >= len_u) {
-         //Apply the rule:
-         // (t@u)[i:j] <==> t[i-len_u:j-len_u], if len(t@u) > i >= j >= len(u)
-         i = CreateBVConst(32, i_val - len_u);
-         j = CreateBVConst(32, j_val - len_u);
-         output = SimplifyTerm(CreateTerm(BVEXTRACT,a_len,t,i,j));
-       }
-       else {
-         //Apply the rule:
-         // (t@u)[i:j] <==> t[i-len_u:0] @ u[len_u-1:j]
-         i = CreateBVConst(32,i_val-len_u);
-         ASTNode m = CreateBVConst(32, len_u-1);
-         t = SimplifyTerm(CreateTerm(BVEXTRACT,i_val-len_u+1,t,i,zero));
-         u = SimplifyTerm(CreateTerm(BVEXTRACT,len_u-j_val,u,m,j));
-         output = CreateTerm(BVCONCAT,a_len,t,u);
-       }
-       break;
-      }
-      case BVPLUS:
-      case BVMULT: {
-       // (BVMULT(n,t,u))[i:j] <==> BVMULT(i+1,t[i:0],u[i:0])[i:j]
-       //similar rule for BVPLUS
-       ASTVec c = a0.GetChildren();
-       ASTVec o;
-       for(ASTVec::iterator jt=c.begin(),jtend=c.end();jt!=jtend;jt++) {
-         ASTNode aaa = *jt;
-         aaa = SimplifyTerm(CreateTerm(BVEXTRACT,i_val+1,aaa,i,zero));
-         o.push_back(aaa);
-       }
-       output = CreateTerm(a0.GetKind(),i_val+1,o);
-       if(j_val != 0) {
-         //add extraction only if j is not zero
-         output = CreateTerm(BVEXTRACT,a_len,output,i,j);
-       }
-       break;
-      }
-      case BVAND:
-      case BVOR:
-      case BVXOR: {
-       //assumes these operators are binary
-       //
-       // (t op u)[i:j] <==> t[i:j] op u[i:j]
-       ASTNode t = a0[0];
-       ASTNode u = a0[1];
-       t = SimplifyTerm(CreateTerm(BVEXTRACT,a_len,t,i,j));
-       u = SimplifyTerm(CreateTerm(BVEXTRACT,a_len,u,i,j));
-       BVTypeCheck(t);
-       BVTypeCheck(u);
-       output = CreateTerm(k1,a_len,t,u);
-       break;
-      }
-      case BVNEG:{
-       // (~t)[i:j] <==> ~(t[i:j])
-       ASTNode t = a0[0];
-       t = SimplifyTerm(CreateTerm(BVEXTRACT,a_len,t,i,j));
-       output = CreateTerm(BVNEG,a_len,t);
-       break;
-      }
-      // case BVSX:{
-//     //(BVSX(t,n)[i:j] <==> BVSX(t,i+1), if n >= i+1 and j=0
-//     ASTNode t = a0[0];
-//     unsigned int bvsx_len = a0.GetValueWidth();
-//     if(bvsx_len < a_len) {
-//       FatalError("SimplifyTerm: BVEXTRACT over BVSX:"
-//                  "the length of BVSX term must be greater than extract-len",inputterm);
-//     }
-//     if(j != zero) {
-//       output = CreateTerm(BVEXTRACT,a_len,a0,i,j);
-//     }
-//     else {
-//       output = CreateTerm(BVSX,a_len,t,CreateBVConst(32,a_len));
-//     }
-//     break;
-//       }
-      case ITE: {
-       ASTNode t0 = a0[0];
-       ASTNode t1 = SimplifyTerm(CreateTerm(BVEXTRACT,a_len,a0[1],i,j));
-       ASTNode t2 = SimplifyTerm(CreateTerm(BVEXTRACT,a_len,a0[2],i,j));
-       output = CreateSimplifiedTermITE(t0,t1,t2);
-       break;
-      }
-      default: {
-       output = CreateTerm(BVEXTRACT,a_len,a0,i,j);
-       break;
-      }
-      }
-      break;
-    }
-    case BVNEG: {
-      ASTNode a0 = SimplifyTerm(inputterm[0]);
-      unsigned len = inputValueWidth;
-      switch(a0.GetKind()) {
-      case BVCONST:
-       output = BVConstEvaluator(CreateTerm(BVNEG,len,a0));
-       break;
-      case BVNEG:
-       output = a0[0];
-       break;
-      // case ITE: {
-//     ASTNode cond = a0[0];
-//     ASTNode thenpart = SimplifyTerm(CreateTerm(BVNEG,len,a0[1]));
-//     ASTNode elsepart = SimplifyTerm(CreateTerm(BVNEG,len,a0[2]));
-//     output = CreateSimplifiedTermITE(cond,thenpart,elsepart);
-//     break;
-//       }
-      default:
-       output = CreateTerm(BVNEG,len,a0);
-       break;
-      }
-      break;
-    }
-    case BVZX:
-      {
-      //a0 is the expr which is being zero extended
-      ASTNode a0 = SimplifyTerm(inputterm[0]);
-      //a1 represents the length of the term BVZX(a0)
-      ASTNode a1 = inputterm[1];
-      //output length of the BVSX term
-      unsigned len = inputValueWidth;
-
-       output = CreateTerm(BVZX,len,a0,a1);
-       break;
-      }
-      break;
-
-    case BVSX:{
-      //a0 is the expr which is being sign extended
-      ASTNode a0 = SimplifyTerm(inputterm[0]);
-      //a1 represents the length of the term BVSX(a0)
-      ASTNode a1 = inputterm[1];
-      //output length of the BVSX term
-      unsigned len = inputValueWidth;
-
-      if(a0.GetValueWidth() == len) {
-       //nothing to signextend
-       return a0;
-      }
-
-      switch(a0.GetKind()) {
-      case BVCONST:
-       output = BVConstEvaluator(CreateTerm(BVSX,len,a0,a1));
-       break;
-      case BVNEG:
-       output = CreateTerm(a0.GetKind(),len,CreateTerm(BVSX,len,a0[0],a1));
-       break;
-      case BVAND:
-      case BVOR:
-       //assuming BVAND and BVOR are binary
-       output = CreateTerm(a0.GetKind(),len,
-                           CreateTerm(BVSX,len,a0[0],a1),
-                           CreateTerm(BVSX,len,a0[1],a1));
-       break;
-      case BVPLUS: {
-       //BVSX(m,BVPLUS(n,BVSX(t1),BVSX(t2))) <==> BVPLUS(m,BVSX(m,t1),BVSX(m,t2))
-       ASTVec c = a0.GetChildren();
-       bool returnflag = false;
-       for(ASTVec::iterator it=c.begin(),itend=c.end();it!=itend;it++) {
-         if(BVSX != it->GetKind()) {
-           returnflag = true;
-           break;
-         }
-       }
-       if(returnflag) {
-         output = CreateTerm(BVSX,len,a0,a1);
-       }
-       else {
-         ASTVec o;
-         for(ASTVec::iterator it=c.begin(),itend=c.end();it!=itend;it++) {
-           ASTNode aaa = SimplifyTerm(CreateTerm(BVSX,len,*it,a1));
-           o.push_back(aaa);
-         }
-         output = CreateTerm(a0.GetKind(),len,o);
-       }
-       break;
-      }
-      case BVSX: {
-       //if you have BVSX(m,BVSX(n,a)) then you can drop the inner
-       //BVSX provided m is greater than n.
-       a0 = SimplifyTerm(a0[0]);
-       output = CreateTerm(BVSX,len,a0,a1);
-       break;
-      }
-      case ITE: {
-       ASTNode cond = a0[0];
-       ASTNode thenpart = SimplifyTerm(CreateTerm(BVSX,len,a0[1],a1));
-       ASTNode elsepart = SimplifyTerm(CreateTerm(BVSX,len,a0[2],a1));
-       output = CreateSimplifiedTermITE(cond,thenpart,elsepart);
-       break;
-      }
-      default:
-       output = CreateTerm(BVSX,len,a0,a1);
-       break;
-      }
-      break;
-    }
-    case BVAND:
-    case BVOR:{
-      ASTNode max = CreateMaxConst(inputValueWidth);
-      ASTNode zero = CreateZeroConst(inputValueWidth);
-
-      ASTNode identity = (BVAND == k) ? max : zero;
-      ASTNode annihilator = (BVAND == k) ? zero : max;
-      ASTVec c = FlattenOneLevel(inputterm).GetChildren();
-      SortByArith(c);
-      ASTVec o;
-      bool constant = true;
-      for(ASTVec::iterator it=c.begin(),itend=c.end();it!=itend;it++) {
-       ASTNode aaa = SimplifyTerm(*it);
-       if(BVCONST != aaa.GetKind()) {
-         constant = false;
-       }
-
-       if(aaa == annihilator) {
-         output = annihilator;
-         return output;
-       }
-
-       if(aaa != identity) {
-         o.push_back(aaa);
-       }
-      }
-
-      switch(o.size()) {
-      case 0:
-       output = identity;
-       break;
-      case 1:
-       output = o[0];
-       break;
-      default:
-       SortByArith(o);
-       output = CreateTerm(k,inputValueWidth,o);
-       if(constant) {
-         output = BVConstEvaluator(output);
-       }
-       break;
-      }
-      break;
-    }
-    case BVCONCAT:{
-      ASTNode t = SimplifyTerm(inputterm[0]);
-      ASTNode u = SimplifyTerm(inputterm[1]);
-      Kind tkind = t.GetKind();
-      Kind ukind = u.GetKind();
-
-
-      if(BVCONST == tkind && BVCONST == ukind) {
-       output = BVConstEvaluator(CreateTerm(BVCONCAT,inputValueWidth,t,u));
-      }
-      else if(BVEXTRACT == tkind &&
-             BVEXTRACT == ukind &&
-             t[0] == u[0]) {
-       //to handle the case x[m:n]@x[n-1:k] <==> x[m:k]
-       ASTNode t_hi = t[1];
-       ASTNode t_low = t[2];
-       ASTNode u_hi = u[1];
-       ASTNode u_low = u[2];
-       ASTNode c = BVConstEvaluator(CreateTerm(BVPLUS,32,u_hi,CreateOneConst(32)));
-       if(t_low == c) {
-         output = CreateTerm(BVEXTRACT,inputValueWidth,t[0],t_hi,u_low);
-       }
-       else {
-         output = CreateTerm(BVCONCAT,inputValueWidth,t,u);
-       }
-      }
-      else {
-       output = CreateTerm(BVCONCAT,inputValueWidth,t,u);
-      }
-      break;
-    }
-    case BVXOR:
-    case BVXNOR:
-    case BVNAND:
-    case BVNOR:
-    case BVLEFTSHIFT:
-    case BVRIGHTSHIFT:
-    case BVVARSHIFT:
-    case BVSRSHIFT:
-    case BVDIV:
-    case BVMOD: {
-      ASTVec c = inputterm.GetChildren();
-      ASTVec o;
-      bool constant = true;
-      for(ASTVec::iterator it=c.begin(),itend=c.end();it!=itend;it++) {
-       ASTNode aaa = SimplifyTerm(*it);
-       if(BVCONST != aaa.GetKind()) {
-         constant = false;
-       }
-       o.push_back(aaa);
-      }
-      output = CreateTerm(k,inputValueWidth,o);
-      if(constant)
-       output = BVConstEvaluator(output);
-      break;
-    }
-    case READ: {
-      ASTNode out1;
-      //process only if not  in the substitution map. simplifymap
-      //has been checked already
-      if(!CheckSubstitutionMap(inputterm,out1)) {
-       if(WRITE == inputterm[0].GetKind()) {
-         //get rid of all writes
-         ASTNode nowrites = RemoveWrites_TopLevel(inputterm);
-         out1 = nowrites;
-       }
-       else if (ITE == inputterm[0].GetKind()){
-         ASTNode cond = SimplifyFormula(inputterm[0][0],false);
-         ASTNode index = SimplifyTerm(inputterm[1]);
-
-         ASTNode read1 = CreateTerm(READ,inputValueWidth,inputterm[0][1],index);
-         ASTNode read2 = CreateTerm(READ,inputValueWidth,inputterm[0][2],index);
-
-         read1 = SimplifyTerm(read1);
-         read2 = SimplifyTerm(read2);
-         out1 = CreateSimplifiedTermITE(cond,read1,read2);
-       }
-       else {
-         //arr is a SYMBOL for sure
-         ASTNode arr = inputterm[0];
-         ASTNode index = SimplifyTerm(inputterm[1]);
-         out1 = CreateTerm(READ,inputValueWidth,arr,index);
-       }
-      }
-      //it is possible that after all the procesing the READ term
-      //reduces to READ(Symbol,const) and hence we should check the
-      //substitutionmap once again.
-      if(!CheckSubstitutionMap(out1,output))
-       output = out1;
-      break;
-    }
-    case ITE: {
-      ASTNode t0 = SimplifyFormula(inputterm[0],false);
-      ASTNode t1 = SimplifyTerm(inputterm[1]);
-      ASTNode t2 = SimplifyTerm(inputterm[2]);
-      output = CreateSimplifiedTermITE(t0,t1,t2);
-      break;
-    }
-    case SBVREM:
-    case SBVMOD:
-    case SBVDIV: {
-      ASTVec c = inputterm.GetChildren();
-      ASTVec o;
-      for(ASTVec::iterator it=c.begin(),itend=c.end();it!=itend;it++) {
-       ASTNode aaa = SimplifyTerm(*it);
-       o.push_back(aaa);
-      }
-      output = CreateTerm(k,inputValueWidth,o);
-      break;
-    }
-    case WRITE:
-    default:
-      FatalError("SimplifyTermAux: Control should never reach here:", inputterm, k);
-      return inputterm;
-      break;
-    }
-
-    return output;
-  }
-
-  //At the end of each simplification call, we want the output to be
-  //always smaller or equal to the input in size.
-  void BeevMgr::CheckSimplifyInvariant(const ASTNode& a, const ASTNode& output) {
-
-    if(NodeSize(a,true) + 1  < NodeSize(output,true)) {
-      cerr << "lhs := " << a << endl;
-      cerr << "NodeSize of lhs is: " << NodeSize(a, true) << endl;
-      cerr << endl;
-      cerr << "rhs := " << output << endl;
-      cerr << "NodeSize of rhs is: " << NodeSize(output, true) << endl;
-      //  FatalError("SimplifyFormula: The nodesize shoudl decrease from lhs to rhs: ",ASTUndefined);
-    }
-  }
-
-  //this function assumes that the input is a vector of childnodes of
-  //a BVPLUS term. it combines like terms and returns a bvplus
-  //term. e.g. 1.x + 2.x is converted to 3.x
-  ASTNode BeevMgr::CombineLikeTerms(const ASTNode& a) {
-    if(BVPLUS != a.GetKind())
-      return a;
-
-    ASTNode output;
-    if(CheckSimplifyMap(a,output,false)) {
-      //check memo table
-      //cerr << "output of SimplifyTerm Cache: " << output << endl;
-      return output;
-    }
-
-    const ASTVec& c = a.GetChildren();
-    //map from variables to vector of constants
-    ASTNodeToVecMap vars_to_consts;
-    //vector to hold constants
-    ASTVec constkids;
-    ASTVec outputvec;
-
-    //useful constants
-    unsigned int len = c[0].GetValueWidth();
-    ASTNode one = CreateOneConst(len);
-    ASTNode zero = CreateZeroConst(len);
-    ASTNode max = CreateMaxConst(len);
-
-    //go over the childnodes of the input bvplus, and collect like
-    //terms in a map. the key of the map are the variables, and the
-    //values are stored in a ASTVec
-    for(ASTVec::const_iterator it=c.begin(),itend=c.end();it!=itend;it++){
-      ASTNode aaa = *it;
-      if(SYMBOL == aaa.GetKind()) {
-       vars_to_consts[aaa].push_back(one);
-      }
-      else if(BVMULT == aaa.GetKind() &&
-             BVUMINUS == aaa[0].GetKind() &&
-             BVCONST == aaa[0][0].GetKind()) {
-       //(BVUMINUS(c))*(y) <==> compute(BVUMINUS(c))*y
-       ASTNode compute_const = BVConstEvaluator(aaa[0]);
-       vars_to_consts[aaa[1]].push_back(compute_const);
-      }
-      else if(BVMULT == aaa.GetKind() &&
-             BVUMINUS == aaa[1].GetKind() &&
-             BVCONST == aaa[0].GetKind()) {
-       //c*(BVUMINUS(y)) <==> compute(BVUMINUS(c))*y
-       ASTNode cccc = BVConstEvaluator(CreateTerm(BVUMINUS,len,aaa[0]));
-       vars_to_consts[aaa[1][0]].push_back(cccc);
-      }
-      else if(BVMULT == aaa.GetKind() && BVCONST == aaa[0].GetKind()) {
-       //assumes that BVMULT is binary
-       vars_to_consts[aaa[1]].push_back(aaa[0]);
-      }
-      else if(BVMULT == aaa.GetKind() && BVUMINUS == aaa[0].GetKind()) {
-       //(-1*x)*(y) <==> -1*(xy)
-       ASTNode cccc = CreateTerm(BVMULT,len,aaa[0][0],aaa[1]);
-       ASTVec cNodes = cccc.GetChildren();
-       SortByArith(cNodes);
-       vars_to_consts[cccc].push_back(max);
-      }
-      else if(BVMULT == aaa.GetKind() && BVUMINUS == aaa[1].GetKind()) {
-       //x*(-1*y) <==> -1*(xy)
-       ASTNode cccc = CreateTerm(BVMULT,len,aaa[0],aaa[1][0]);
-       ASTVec cNodes = cccc.GetChildren();
-       SortByArith(cNodes);
-       vars_to_consts[cccc].push_back(max);
-      }
-      else if(BVCONST == aaa.GetKind()) {
-       constkids.push_back(aaa);
-      }
-      else if(BVUMINUS == aaa.GetKind()) {
-       //helps to convert BVUMINUS into a BVMULT. here the max
-       //constant represents -1. this transformation allows us to
-       //conclude that x + BVUMINUS(x) is 0.
-       vars_to_consts[aaa[0]].push_back(max);
-      }
-      else
-       vars_to_consts[aaa].push_back(one);
-    } //end of for loop
-
-    //go over the map from variables to vector of values. combine the
-    //vector of values, multiply to the variable, and put the
-    //resultant monomial in the output BVPLUS.
-    for(ASTNodeToVecMap::iterator it=vars_to_consts.begin(),itend=vars_to_consts.end();
-       it!=itend;it++){
-      ASTVec ccc = it->second;
-
-      ASTNode constant;
-      if(1 < ccc.size()) {
-       constant = CreateTerm(BVPLUS,ccc[0].GetValueWidth(),ccc);
-       constant = BVConstEvaluator(constant);
-      }
-      else
-       constant = ccc[0];
-
-      //constant * var
-      ASTNode monom;
-      if(zero == constant)
-       monom = zero;
-      else if (one == constant)
-       monom = it->first;
-      else{
-       monom =
-         SimplifyTerm(CreateTerm(BVMULT,constant.GetValueWidth(),constant,it->first));
-      }
-      if(zero != monom) {
-       outputvec.push_back(monom);
-      }
-    } //end of for loop
-
-    if(constkids.size() > 1) {
-      ASTNode output = CreateTerm(BVPLUS,constkids[0].GetValueWidth(),constkids);
-      output = BVConstEvaluator(output);
-      if(output != zero)
-       outputvec.push_back(output);
-    }
-    else if (constkids.size() == 1) {
-      if(constkids[0] != zero)
-       outputvec.push_back(constkids[0]);
-    }
-
-    if (outputvec.size() > 1) {
-      output = CreateTerm(BVPLUS,len,outputvec);
-    }
-    else if(outputvec.size() == 1) {
-      output = outputvec[0];
-    }
-    else {
-      output = zero;
-    }
-
-    //memoize
-    //UpdateSimplifyMap(a,output,false);
-    return output;
-  } //end of CombineLikeTerms()
-
-  //accepts lhs and rhs, and returns lhs - rhs = 0. The function
-  //assumes that lhs and rhs have already been simplified. although
-  //this assumption is not needed for correctness, it is essential for
-  //performance. The function also assumes that lhs is a BVPLUS
-  ASTNode BeevMgr::LhsMinusRhs(const ASTNode& eq) {
-    //if input is not an equality, simply return it
-    if(EQ != eq.GetKind())
-      return eq;
-
-    ASTNode lhs = eq[0];
-    ASTNode rhs = eq[1];
-    Kind k_lhs = lhs.GetKind();
-    Kind k_rhs = rhs.GetKind();
-    //either the lhs has to be a BVPLUS or the rhs has to be a
-    //BVPLUS
-    if(!(BVPLUS == k_lhs ||
-        BVPLUS == k_rhs ||
-        (BVMULT == k_lhs &&
-         BVMULT == k_rhs)
-        )) {
-      return eq;
-    }
-
-    ASTNode output;
-    if(CheckSimplifyMap(eq,output,false)) {
-      //check memo table
-      //cerr << "output of SimplifyTerm Cache: " << output << endl;
-      return output;
-    }
-
-    //if the lhs is not a BVPLUS, but the rhs is a BVPLUS, then swap
-    //the lhs and rhs
-    bool swap_flag = false;
-    if(BVPLUS != k_lhs && BVPLUS == k_rhs) {
-      ASTNode swap = lhs;
-      lhs = rhs;
-      rhs = swap;
-      swap_flag = true;
-    }
-
-    unsigned int len = lhs.GetValueWidth();
-    ASTNode zero = CreateZeroConst(len);
-    //right is -1*(rhs): Simplify(-1*rhs)
-    rhs = SimplifyTerm(CreateTerm(BVUMINUS,len,rhs));
-
-    ASTVec lvec = lhs.GetChildren();
-    ASTVec rvec = rhs.GetChildren();
-    ASTNode lhsplusrhs;
-    if(BVPLUS != lhs.GetKind() && BVPLUS != rhs.GetKind()) {
-      lhsplusrhs = CreateTerm(BVPLUS,len,lhs,rhs);
-    }
-    else if(BVPLUS == lhs.GetKind() && BVPLUS == rhs.GetKind()) {
-      //combine the childnodes of the left and the right
-      lvec.insert(lvec.end(),rvec.begin(),rvec.end());
-      lhsplusrhs = CreateTerm(BVPLUS,len,lvec);
-    }
-    else if(BVPLUS == lhs.GetKind() && BVPLUS != rhs.GetKind()){
-      lvec.push_back(rhs);
-      lhsplusrhs = CreateTerm(BVPLUS,len,lvec);
-    }
-    else {
-      //Control should never reach here
-      FatalError("LhsMinusRhs: Control should never reach here\n");
-    }
-
-    //combine like terms
-    output = CombineLikeTerms(lhsplusrhs);
-    output = SimplifyTerm(output);
-    //
-    //Now make output into: lhs-rhs = 0
-    output = CreateSimplifiedEQ(output,zero);
-    //sort if BVPLUS
-    if(BVPLUS == output.GetKind()) {
-      ASTVec outv = output.GetChildren();
-      SortByArith(outv);
-      output = CreateTerm(BVPLUS,len,outv);
-    }
-
-    //memoize
-    //UpdateSimplifyMap(eq,output,false);
-    return output;
-  } //end of LhsMinusRHS()
-
-  //THis function accepts a BVMULT(t1,t2) and distributes the mult
-  //over plus if either or both t1 and t2 are BVPLUSes.
-  //
-  // x*(y1 + y2 + ...+ yn) <==> x*y1 + x*y2 + ... + x*yn
-  //
-  // (y1 + y2 + ...+ yn)*x <==> x*y1 + x*y2 + ... + x*yn
-  //
-  // The function assumes that the BVPLUSes have been flattened
-  ASTNode BeevMgr::DistributeMultOverPlus(const ASTNode& a, bool startdistribution) {
-    if(!startdistribution)
-      return a;
-    Kind k = a.GetKind();
-    if(BVMULT != k)
-      return a;
-
-    ASTNode left = a[0];
-    ASTNode right = a[1];
-    Kind left_kind = left.GetKind();
-    Kind right_kind = right.GetKind();
-
-    ASTNode output;
-    if(CheckSimplifyMap(a,output,false)) {
-      //check memo table
-      //cerr << "output of SimplifyTerm Cache: " << output << endl;
-      return output;
-    }
-
-    //special case optimization: c1*(c2*t1) <==> (c1*c2)*t1
-    if(BVCONST == left_kind &&
-       BVMULT == right_kind &&
-       BVCONST == right[0].GetKind()) {
-      ASTNode c = BVConstEvaluator(CreateTerm(BVMULT,a.GetValueWidth(),left,right[0]));
-      c = CreateTerm(BVMULT,a.GetValueWidth(),c,right[1]);
-      return c;
-      left = c[0];
-      right = c[1];
-      left_kind = left.GetKind();
-      right_kind = right.GetKind();
-    }
-
-    //special case optimization: c1*(t1*c2) <==> (c1*c2)*t1
-    if(BVCONST == left_kind &&
-       BVMULT == right_kind &&
-       BVCONST == right[1].GetKind()) {
-      ASTNode c = BVConstEvaluator(CreateTerm(BVMULT,a.GetValueWidth(),left,right[1]));
-      c = CreateTerm(BVMULT,a.GetValueWidth(),c,right[0]);
-      return c;
-      left = c[0];
-      right = c[1];
-      left_kind = left.GetKind();
-      right_kind = right.GetKind();
-    }
-
-    //atleast one of left or right have to be BVPLUS
-    if(!(BVPLUS == left_kind || BVPLUS == right_kind)) {
-      return a;
-    }
-
-    //if left is BVPLUS and right is not, then swap left and right. we
-    //can do this since BVMULT is communtative
-    ASTNode swap;
-    if(BVPLUS == left_kind && BVPLUS != right_kind) {
-      swap = left;
-      left = right;
-      right = swap;
-    }
-    left_kind = left.GetKind();
-    right_kind = right.GetKind();
-
-    //by this point we are gauranteed that right is a BVPLUS, but left
-    //may not be
-    ASTVec rightnodes = right.GetChildren();
-    ASTVec outputvec;
-    unsigned len = a.GetValueWidth();
-    ASTNode zero = CreateZeroConst(len);
-    ASTNode one = CreateOneConst(len);
-    if(BVPLUS != left_kind) {
-      //if the multiplier is not a BVPLUS then we have a special case
-      // x*(y1 + y2 + ...+ yn) <==> x*y1 + x*y2 + ... + x*yn
-      if(zero == left) {
-       outputvec.push_back(zero);
-      }
-      else if(one == left) {
-       outputvec.push_back(left);
-      }
-      else {
-       for(ASTVec::iterator j=rightnodes.begin(),jend=rightnodes.end();
-           j!=jend;j++) {
-         ASTNode out = SimplifyTerm(CreateTerm(BVMULT,len,left,*j));
-         outputvec.push_back(out);
-       }
-      }
-    }
-    else {
-      ASTVec leftnodes = left.GetChildren();
-      // (x1 + x2 + ... + xm)*(y1 + y2 + ...+ yn) <==> x1*y1 + x1*y2 +
-      // ... + x2*y1 + ... + xm*yn
-      for(ASTVec::iterator i=leftnodes.begin(),iend=leftnodes.end();
-         i!=iend;i++) {
-       ASTNode multiplier = *i;
-       for(ASTVec::iterator j=rightnodes.begin(),jend=rightnodes.end();
-           j!=jend;j++) {
-         ASTNode out = SimplifyTerm(CreateTerm(BVMULT,len,multiplier,*j));
-         outputvec.push_back(out);
-       }
-      }
-    }
-
-    //compute output here
-    if(outputvec.size() > 1) {
-      output = CombineLikeTerms(CreateTerm(BVPLUS,len,outputvec));
-      output = SimplifyTerm(output);
-    }
-    else
-      output = SimplifyTerm(outputvec[0]);
-
-    //memoize
-    //UpdateSimplifyMap(a,output,false);
-    return output;
-  } //end of distributemultoverplus()
-
-  //converts the BVSX(len, a0) operator into ITE( check top bit,
-  //extend a0 by 1, extend a0 by 0)
-  ASTNode BeevMgr::ConvertBVSXToITE(const ASTNode& a) {
-    if(BVSX != a.GetKind())
-      return a;
-
-    ASTNode output;
-    if(CheckSimplifyMap(a,output,false)) {
-      //check memo table
-      //cerr << "output of ConvertBVSXToITE Cache: " << output << endl;
-      return output;
-    }
-
-    ASTNode a0 = a[0];
-    unsigned a_len = a.GetValueWidth();
-    unsigned a0_len = a0.GetValueWidth();
-
-    if(a0_len > a_len){
-      FatalError("Trying to sign_extend a larger BV into a smaller BV");
-      return ASTUndefined; //to stop the compiler from producing bogus warnings
-    }
-
-    //sign extend
-    unsigned extensionlen = a_len-a0_len;
-    if(0 == extensionlen) {
-      UpdateSimplifyMap(a,output,false);
-      return a;
-    }
-
-    std::string ones;
-    for(unsigned c=0; c < extensionlen;c++)
-      ones += '1';
-    std::string zeros;
-    for(unsigned c=0; c < extensionlen;c++)
-      zeros += '0';
-
-    //string of oness of length extensionlen
-    BEEV::ASTNode BVOnes = CreateBVConst(ones.c_str(),2);
-    //string of zeros of length extensionlen
-    BEEV::ASTNode BVZeros = CreateBVConst(zeros.c_str(),2);
-
-    //string of ones BVCONCAT a0
-    BEEV::ASTNode concatOnes = CreateTerm(BEEV::BVCONCAT,a_len,BVOnes,a0);
-    //string of zeros BVCONCAT a0
-    BEEV::ASTNode concatZeros = CreateTerm(BEEV::BVCONCAT,a_len,BVZeros,a0);
-
-    //extract top bit of a0
-    BEEV::ASTNode hi = CreateBVConst(32,a0_len-1);
-    BEEV::ASTNode low = CreateBVConst(32,a0_len-1);
-    BEEV::ASTNode topBit = CreateTerm(BEEV::BVEXTRACT,1,a0,hi,low);
-
-    //compare topBit of a0 with 0bin1
-    BEEV::ASTNode condition = CreateSimplifiedEQ(CreateBVConst(1,1),topBit);
-
-    //ITE(topbit = 0bin1, 0bin1111...a0, 0bin000...a0)
-    output = CreateSimplifiedTermITE(condition,concatOnes,concatZeros);
-    UpdateSimplifyMap(a,output,false);
-    return output;
-  } //end of ConvertBVSXToITE()
-
-
-  ASTNode BeevMgr::RemoveWrites_TopLevel(const ASTNode& term) {
-    if(READ != term.GetKind() && WRITE != term[0].GetKind()) {
-      FatalError("RemovesWrites: Input must be a READ over a WRITE",term);
-    }
-
-    if(!Begin_RemoveWrites &&
-       !SimplifyWrites_InPlace_Flag &&
-       !start_abstracting) {
-      return term;
-    }
-    else if(!Begin_RemoveWrites &&
-           SimplifyWrites_InPlace_Flag &&
-           !start_abstracting) {
-      //return term;
-      return SimplifyWrites_InPlace(term);
-    }
-    else {
-      return RemoveWrites(term);
-    }
-  } //end of RemoveWrites_TopLevel()
-
-  ASTNode BeevMgr::SimplifyWrites_InPlace(const ASTNode& term) {
-    ASTNodeMultiSet WriteIndicesSeenSoFar;
-    bool SeenNonConstWriteIndex = false;
-
-    if(READ != term.GetKind() &&
-       WRITE != term[0].GetKind()) {
-      FatalError("RemovesWrites: Input must be a READ over a WRITE",term);
-    }
-
-    ASTNode output;
-    if(CheckSimplifyMap(term,output,false)) {
-      return output;
-    }
-
-    ASTVec writeIndices, writeValues;
-    unsigned int width = term.GetValueWidth();
-    ASTNode write = term[0];
-    unsigned indexwidth = write.GetIndexWidth();
-    ASTNode readIndex = SimplifyTerm(term[1]);
-
-    do {
-      ASTNode writeIndex = SimplifyTerm(write[1]);
-      ASTNode writeVal = SimplifyTerm(write[2]);
-
-      //compare the readIndex and the current writeIndex and see if they
-      //simplify to TRUE or FALSE or UNDETERMINABLE at this stage
-      ASTNode compare_readwrite_indices =
-       SimplifyFormula(CreateSimplifiedEQ(writeIndex,readIndex),false);
-
-      //if readIndex and writeIndex are equal
-      if(ASTTrue == compare_readwrite_indices && !SeenNonConstWriteIndex) {
-       UpdateSimplifyMap(term,writeVal,false);
-       return writeVal;
-      }
-
-      if(!(ASTTrue == compare_readwrite_indices ||
-          ASTFalse == compare_readwrite_indices)) {
-       SeenNonConstWriteIndex = true;
-      }
-
-      //if (readIndex=writeIndex <=> FALSE)
-      if(ASTFalse == compare_readwrite_indices
-        ||
-        (WriteIndicesSeenSoFar.find(writeIndex) != WriteIndicesSeenSoFar.end())
-        ) {
-       //drop the current level write
-       //do nothing
-      }
-      else {
-       writeIndices.push_back(writeIndex);
-       writeValues.push_back(writeVal);
-      }
-
-      //record the write indices seen so far
-      //if(BVCONST == writeIndex.GetKind()) {
-       WriteIndicesSeenSoFar.insert(writeIndex);
-       //}
-
-      //Setup the write for the new iteration, one level inner write
-      write = write[0];
-    }while (SYMBOL != write.GetKind());
-
-    ASTVec::reverse_iterator it_index = writeIndices.rbegin();
-    ASTVec::reverse_iterator itend_index = writeIndices.rend();
-    ASTVec::reverse_iterator it_values = writeValues.rbegin();
-    ASTVec::reverse_iterator itend_values = writeValues.rend();
-
-    //"write" must be a symbol at the control point before the
-    //begining of the "for loop"
-
-    for(;it_index!=itend_index;it_index++,it_values++) {
-      write = CreateTerm(WRITE,width,write,*it_index,*it_values);
-      write.SetIndexWidth(indexwidth);
-    }
-
-    output = CreateTerm(READ,width,write,readIndex);
-    UpdateSimplifyMap(term,output,false);
-    return output;
-  } //end of SimplifyWrites_In_Place()
-
-  //accepts a read over a write and returns a term without the write
-  //READ(WRITE(A i val) j) <==> ITE(i=j,val,READ(A,j)). We use a memo
-  //table for this function called RemoveWritesMemoMap
-  ASTNode BeevMgr::RemoveWrites(const ASTNode& input) {
-    //unsigned int width = input.GetValueWidth();
-    if(READ != input.GetKind() || WRITE != input[0].GetKind()) {
-      FatalError("RemovesWrites: Input must be a READ over a WRITE",input);
-    }
-
-    ASTNodeMap::iterator it;
-    ASTNode output = input;
-    if(CheckSimplifyMap(input,output,false)) {
-      return output;
-    }
-
-    if(!start_abstracting && Begin_RemoveWrites) {
-      output= ReadOverWrite_To_ITE(input);
-    }
-
-    if(start_abstracting) {
-      ASTNode newVar;
-      if(!CheckSimplifyMap(input,newVar,false)) {
-       newVar = NewVar(input.GetValueWidth());
-       ReadOverWrite_NewName_Map[input] = newVar;
-       NewName_ReadOverWrite_Map[newVar] = input;
-
-       UpdateSimplifyMap(input,newVar,false);
-       ASTNodeStats("New Var Name which replace Read_Over_Write: ", newVar);
-      }
-      output = newVar;
-    } //end of start_abstracting if condition
-
-    //memoize
-    UpdateSimplifyMap(input,output,false);
-    return output;
-  } //end of RemoveWrites()
-
-  ASTNode BeevMgr::ReadOverWrite_To_ITE(const ASTNode& term) {
-    unsigned int width = term.GetValueWidth();
-    ASTNode input = term;
-    if(READ != term.GetKind() || WRITE != term[0].GetKind()) {
-      FatalError("RemovesWrites: Input must be a READ over a WRITE",term);
-    }
-
-    ASTNodeMap::iterator it;
-    ASTNode output;
-    // if(CheckSimplifyMap(term,output,false)) {
-    //       return output;
-    //     }
-
-    ASTNode partialITE = term;
-    ASTNode writeA = ASTTrue;
-    ASTNode oldRead = term;
-    //iteratively expand read-over-write
-    do {
-      ASTNode write = input[0];
-      ASTNode readIndex = SimplifyTerm(input[1]);
-      //DO NOT CALL SimplifyTerm() on write[0]. You will go into an
-      //infinite loop
-      writeA = write[0];
-      ASTNode writeIndex = SimplifyTerm(write[1]);
-      ASTNode writeVal = SimplifyTerm(write[2]);
-
-      ASTNode cond = SimplifyFormula(CreateSimplifiedEQ(writeIndex,readIndex),false);
-      ASTNode newRead = CreateTerm(READ,width,writeA,readIndex);
-      ASTNode newRead_memoized = newRead;
-      if(CheckSimplifyMap(newRead, newRead_memoized,false)) {
-       newRead = newRead_memoized;
-      }
-
-      if(ASTTrue == cond && (term == partialITE)) {
-       //found the write-value in the first iteration itself. return
-       //it
-       output = writeVal;
-       UpdateSimplifyMap(term,output,false);
-       return output;
-      }
-
-      if(READ == partialITE.GetKind() && WRITE == partialITE[0].GetKind()) {
-       //first iteration or (previous cond==ASTFALSE and partialITE is a "READ over WRITE")
-       partialITE = CreateSimplifiedTermITE(cond, writeVal, newRead);
-      }
-      else if (ITE == partialITE.GetKind()){
-       //ITE(i1 = j, v1, R(A,j))
-       ASTNode ElseITE = CreateSimplifiedTermITE(cond, writeVal, newRead);
-       //R(W(A,i1,v1),j) <==> ITE(i1 = j, v1, R(A,j))
-       UpdateSimplifyMap(oldRead,ElseITE,false);
-       //ITE(i2 = j, v2, R(W(A,i1,v1),j)) <==> ITE(i2 = j, v2, ITE(i1 = j, v1, R(A,j)))
-       partialITE = SimplifyTerm(partialITE);
-      }
-      else {
-       FatalError("RemoveWrites: Control should not reach here\n");
-      }
-
-      if(ASTTrue == cond) {
-       //no more iterations required
-       output = partialITE;
-       UpdateSimplifyMap(term,output,false);
+       if (a.GetChildren().size() > 2)
+       {
+               FatalError("Simplify got an XOR with more than two children.");
+       }
+
+       ASTNode a0 = SimplifyFormula(a[0], false);
+       ASTNode a1 = SimplifyFormula(a[1], false);
+       output = pushNeg ? CreateNode(IFF, a0, a1) : CreateNode(XOR, a0, a1);
+
+       if (XOR == output.GetKind())
+       {
+               a0 = output[0];
+               a1 = output[1];
+               if (a0 == a1)
+                       output = ASTFalse;
+               else if (a0 == ASTTrue && a1 == ASTFalse || a0 == ASTFalse && a1 == ASTTrue)
+                       output = ASTTrue;
+       }
+
+       //memoize
+       UpdateSimplifyMap(a, output, pushNeg);
        return output;
-      }
+}
+
+ASTNode BeevMgr::SimplifyNandFormula(const ASTNode& a, bool pushNeg)
+{
+       ASTNode output, a0, a1;
+       if (CheckSimplifyMap(a, output, pushNeg))
+               return output;
+
+       //the two NOTs cancel out
+       if (pushNeg)
+       {
+               a0 = SimplifyFormula(a[0], false);
+               a1 = SimplifyFormula(a[1], false);
+               output = CreateNode(AND, a0, a1);
+       }
+       else
+       {
+               //push the NOT implicit in the NAND
+               a0 = SimplifyFormula(a[0], true);
+               a1 = SimplifyFormula(a[1], true);
+               output = CreateNode(OR, a0, a1);
+       }
 
-      input = newRead;
-      oldRead = newRead;
-    } while(READ == input.GetKind() && WRITE == input[0].GetKind());
+       //memoize
+       UpdateSimplifyMap(a, output, pushNeg);
+       return output;
+}
 
-    output = partialITE;
+ASTNode BeevMgr::SimplifyNorFormula(const ASTNode& a, bool pushNeg)
+{
+       ASTNode output, a0, a1;
+       if (CheckSimplifyMap(a, output, pushNeg))
+               return output;
+
+       //the two NOTs cancel out
+       if (pushNeg)
+       {
+               a0 = SimplifyFormula(a[0], false);
+               a1 = SimplifyFormula(a[1], false);
+               output = CreateNode(OR, a0, a1);
+       }
+       else
+       {
+               //push the NOT implicit in the NAND
+               a0 = SimplifyFormula(a[0], true);
+               a1 = SimplifyFormula(a[1], true);
+               output = CreateNode(AND, a0, a1);
+       }
 
-    //memoize
-    //UpdateSimplifyMap(term,output,false);
-    return output;
-  } //ReadOverWrite_To_ITE()
+       //memoize
+       UpdateSimplifyMap(a, output, pushNeg);
+       return output;
+}
 
-  //compute the multiplicative inverse of the input
-  ASTNode BeevMgr::MultiplicativeInverse(const ASTNode& d) {
-    ASTNode c = d;
-    if(BVCONST != c.GetKind()) {
-      FatalError("Input must be a constant", c);
-    }
+ASTNode BeevMgr::SimplifyImpliesFormula(const ASTNode& a, bool pushNeg)
+{
+       ASTNode output;
+       if (CheckSimplifyMap(a, output, pushNeg))
+               return output;
+
+       if (!(a.Degree() == 2 && IMPLIES == a.GetKind()))
+               FatalError("SimplifyImpliesFormula: vector with wrong num of nodes", ASTUndefined);
+
+       ASTNode c0, c1;
+       if (pushNeg)
+       {
+               c0 = SimplifyFormula(a[0], false);
+               c1 = SimplifyFormula(a[1], true);
+               output = CreateNode(AND, c0, c1);
+       }
+       else
+       {
+               c0 = SimplifyFormula(a[0], false);
+               c1 = SimplifyFormula(a[1], false);
+               if (ASTFalse == c0)
+               {
+                       output = ASTTrue;
+               }
+               else if (ASTTrue == c0)
+               {
+                       output = c1;
+               }
+               else if (c0 == c1)
+               {
+                       output = ASTTrue;
+               }
+               else if (CheckAlwaysTrueFormMap(c0))
+               {
+                       // c0 AND (~c0 OR c1) <==> c1
+                       //
+                       //applying modus ponens
+                       output = c1;
+               }
+               else if (CheckAlwaysTrueFormMap(c1) || CheckAlwaysTrueFormMap(CreateNode(NOT, c0)) || (NOT == c0.GetKind() && CheckAlwaysTrueFormMap(c0[0])))
+               {
+                       //(~c0 AND (~c0 OR c1)) <==> TRUE
+                       //
+                       //(c0 AND ~c0->c1) <==> TRUE
+                       output = ASTTrue;
+               }
+               else if (CheckAlwaysTrueFormMap(CreateNode(NOT, c1)) || (NOT == c1.GetKind() && CheckAlwaysTrueFormMap(c1[0])))
+               {
+                       //(~c1 AND c0->c1) <==> (~c1 AND ~c1->~c0) <==> ~c0
+                       //(c1 AND c0->~c1) <==> (c1 AND c1->~c0) <==> ~c0
+                       output = CreateNode(NOT, c0);
+               }
+               else
+               {
+                       if (NOT == c0.GetKind())
+                       {
+                               output = CreateNode(OR, c0[0], c1);
+                       }
+                       else
+                       {
+                               output = CreateNode(OR, CreateNode(NOT, c0), c1);
+                       }
+               }
+       }
 
-    if(!BVConstIsOdd(c)) {
-      FatalError("MultiplicativeInverse: Input must be odd: ",c);
-    }
+       //memoize
+       UpdateSimplifyMap(a, output, pushNeg);
+       return output;
+}
 
-    //cerr << "input to multinverse function is: " << d << endl;
-    ASTNode inverse;
-    if(CheckMultInverseMap(d,inverse)) {
-      //cerr << "found the inverse of: " << d << "and it is: " << inverse << endl;
-      return inverse;
-    }
+ASTNode BeevMgr::SimplifyIffFormula(const ASTNode& a, bool pushNeg)
+{
+       ASTNode output;
+       if (CheckSimplifyMap(a, output, pushNeg))
+               return output;
 
-    inverse = c;
-    unsigned inputwidth = c.GetValueWidth();
+       if (!(a.Degree() == 2 && IFF == a.GetKind()))
+               FatalError("SimplifyIffFormula: vector with wrong num of nodes", ASTUndefined);
 
-#ifdef NATIVE_C_ARITH
-    ASTNode one = CreateOneConst(inputwidth);
-    while(c != one) {
-      //c = c*c
-      c = BVConstEvaluator(CreateTerm(BVMULT,inputwidth,c,c));
-      //inverse = invsere*c
-      inverse = BVConstEvaluator(CreateTerm(BVMULT,inputwidth,inverse,c));
-    }
-#else
-    //Compute the multiplicative inverse of c using the extended
-    //euclidian algorithm
-    //
-    //create a '0' which is 1 bit long
-    ASTNode onebit_zero = CreateZeroConst(1);
-    //zero pad t0, i.e. 0 @ t0
-    c = BVConstEvaluator(CreateTerm(BVCONCAT,inputwidth+1,onebit_zero,c));
-
-    //construct 2^(inputwidth), i.e. a bitvector of length
-    //'inputwidth+1', which is max(inputwidth)+1
-    //
-    //all 1's
-    ASTNode max = CreateMaxConst(inputwidth);
-    //zero pad max
-    max = BVConstEvaluator(CreateTerm(BVCONCAT,inputwidth+1,onebit_zero,max));
-    //Create a '1' which has leading zeros of length 'inputwidth'
-    ASTNode inputwidthplusone_one = CreateOneConst(inputwidth+1);
-    //add 1 to max
-    max = CreateTerm(BVPLUS,inputwidth+1,max,inputwidthplusone_one);
-    max = BVConstEvaluator(max);
-
-    ASTNode zero = CreateZeroConst(inputwidth+1);
-    ASTNode max_bvgt_0 = CreateNode(BVGT,max,zero);
-    ASTNode quotient, remainder;
-    ASTNode x, x1, x2;
-
-    //x1 initialized to zero
-    x1 = zero;
-    //x2 initialized to one
-    x2 = CreateOneConst(inputwidth+1);
-    while (ASTTrue == BVConstEvaluator(max_bvgt_0)) {
-      //quotient = (c divided by max)
-      quotient = BVConstEvaluator(CreateTerm(BVDIV,inputwidth+1, c, max));
-
-      //remainder of (c divided by max)
-      remainder = BVConstEvaluator(CreateTerm(BVMOD,inputwidth+1, c, max));
-
-      //x = x2 - q*x1
-      x = CreateTerm(BVSUB,inputwidth+1,x2,CreateTerm(BVMULT,inputwidth+1,quotient,x1));
-      x = BVConstEvaluator(x);
-
-      //fix the inputs to the extended euclidian algo
-      c = max;
-      max = remainder;
-      max_bvgt_0 = CreateNode(BVGT,max,zero);
-
-      x2 = x1;
-      x1 = x;
-    }
-
-    ASTNode hi = CreateBVConst(32,inputwidth-1);
-    ASTNode low = CreateZeroConst(32);
-    inverse = CreateTerm(BVEXTRACT,inputwidth,x2,hi,low);
-    inverse = BVConstEvaluator(inverse);
-#endif
+       ASTNode c0 = a[0];
+       ASTNode c1 = SimplifyFormula(a[1], false);
 
-    UpdateMultInverseMap(d,inverse);
-    //cerr << "output of multinverse function is: " << inverse << endl;
-    return inverse;
-  } //end of MultiplicativeInverse()
-
-  //returns true if the input is odd
-  bool BeevMgr::BVConstIsOdd(const ASTNode& c) {
-    if(BVCONST != c.GetKind()) {
-      FatalError("Input must be a constant", c);
-    }
-
-    ASTNode zero = CreateZeroConst(1);
-    ASTNode hi = CreateZeroConst(32);
-    ASTNode low = hi;
-    ASTNode lowestbit = CreateTerm(BVEXTRACT,1,c,hi,low);
-    lowestbit =  BVConstEvaluator(lowestbit);
-
-    if(lowestbit == zero) {
-      return false;
-    }
-    else {
-      return true;
-    }
-  } //end of BVConstIsOdd()
-
-  //The big substitution function
-  ASTNode BeevMgr::CreateSubstitutionMap(const ASTNode& a){
-    if(!optimize)
-      return a;
-
-    ASTNode output = a;
-    //if the variable has been solved for, then simply return it
-    if(CheckSolverMap(a,output))
-      return output;
-
-    //traverse a and populate the SubstitutionMap
-    Kind k = a.GetKind();
-    if(SYMBOL == k && BOOLEAN_TYPE == a.GetType()) {
-      bool updated = UpdateSubstitutionMap(a,ASTTrue);
-      output = updated ? ASTTrue : a;
-      return output;
-    }
-    if(NOT == k
-       && SYMBOL == a[0].GetKind()) {
-      bool updated = UpdateSubstitutionMap(a[0],ASTFalse);
-      output = updated ? ASTTrue : a;
-      return output;
-    }
-
-    if(IFF == k) {
-      ASTVec c = a.GetChildren();
-      SortByArith(c);
-      if(SYMBOL != c[0].GetKind() ||
-        VarSeenInTerm(c[0],SimplifyFormula_NoRemoveWrites(c[1],false))) {
-       return a;
-      }
-      bool updated = UpdateSubstitutionMap(c[0], SimplifyFormula(c[1],false));
-      output = updated ? ASTTrue : a;
-      return output;
-    }
-
-    if(EQ == k) {
-      //fill the arrayname readindices vector if e0 is a
-      //READ(Arr,index) and index is a BVCONST
-      ASTVec c = a.GetChildren();
-      SortByArith(c);
-      FillUp_ArrReadIndex_Vec(c[0],c[1]);
-
-      if(SYMBOL == c[0].GetKind() &&
-        VarSeenInTerm(c[0],SimplifyTermAux(c[1]))) {
-       return a;
-      }
-
-      if(1 == TermOrder(c[0],c[1]) &&
-        READ == c[0].GetKind() &&
-        VarSeenInTerm(c[0][0],SimplifyTermAux(c[1]))) {
-       return a;
-      }
-      bool updated = UpdateSubstitutionMap(c[0], SimplifyTermAux(c[1]));
-      output = updated ? ASTTrue : a;
-      return output;
-    }
-
-    if(AND == k){
-      ASTVec o;
-      ASTVec c = a.GetChildren();
-      for(ASTVec::iterator it = c.begin(),itend=c.end();it!=itend;it++) {
-       UpdateAlwaysTrueFormMap(*it);
-       ASTNode aaa = CreateSubstitutionMap(*it);
-
-       if(ASTTrue != aaa) {
-         if(ASTFalse == aaa)
-           return ASTFalse;
-         else
-           o.push_back(aaa);
-       }
-      }
-      if(o.size() == 0)
-       return ASTTrue;
-
-      if(o.size() == 1)
-       return o[0];
-
-      return CreateNode(AND,o);
-    }
-
-    //printf("I gave up on kind: %d node: %d\n", k, a.GetNodeNum());
-    return output;
-  } //end of CreateSubstitutionMap()
-
-
-  bool BeevMgr::VarSeenInTerm(const ASTNode& var, const ASTNode& term) {
-    if(READ == term.GetKind() &&
-       WRITE == term[0].GetKind() && !Begin_RemoveWrites) {
-      return false;
-    }
-
-    if(READ == term.GetKind() &&
-       WRITE == term[0].GetKind() && Begin_RemoveWrites) {
-      return true;
-    }
-
-    ASTNodeMap::iterator it;
-    if((it = TermsAlreadySeenMap.find(term)) != TermsAlreadySeenMap.end()) {
-      if(it->second == var) {
-       return false;
-      }
-    }
-
-    if(var == term) {
-      return true;
-    }
-
-    for(ASTVec::const_iterator it=term.begin(),itend=term.end();it!=itend;it++){
-      if(VarSeenInTerm(var,*it)) {
-       return true;
-      }
-      else {
-       TermsAlreadySeenMap[*it] = var;
-      }
-    }
-
-    TermsAlreadySeenMap[term] = var;
-    return false;
-  }
+       if (pushNeg)
+               c0 = SimplifyFormula(c0, true);
+       else
+               c0 = SimplifyFormula(c0, false);
 
-// in ext/hash_map, and tr/unordered_map, there is no provision to shrink down
-// the number of buckets in a hash map. If the hash_map has previously held a
-// lot of data, then it will have  a lot of buckets. Slowing down iterators and
-// clears() in particular.
-void BeevMgr::ResetSimplifyMaps()
-{
-  delete SimplifyMap;
-  SimplifyMap = new ASTNodeMap(INITIAL_SIMPLIFY_MAP_SIZE);
+       if (ASTTrue == c0)
+       {
+               output = c1;
+       }
+       else if (ASTFalse == c0)
+       {
+               output = SimplifyFormula(c1, true);
+       }
+       else if (ASTTrue == c1)
+       {
+               output = c0;
+       }
+       else if (ASTFalse == c1)
+       {
+               output = SimplifyFormula(c0, true);
+       }
+       else if (c0 == c1)
+       {
+               output = ASTTrue;
+       }
+       else if ((NOT == c0.GetKind() && c0[0] == c1) || (NOT == c1.GetKind() && c0 == c1[0]))
+       {
+               output = ASTFalse;
+       }
+       else if (CheckAlwaysTrueFormMap(c0))
+       {
+               output = c1;
+       }
+       else if (CheckAlwaysTrueFormMap(c1))
+       {
+               output = c0;
+       }
+       else if (CheckAlwaysTrueFormMap(CreateNode(NOT, c0)))
+       {
+               output = CreateNode(NOT, c1);
+       }
+       else if (CheckAlwaysTrueFormMap(CreateNode(NOT, c1)))
+       {
+               output = CreateNode(NOT, c0);
+       }
+       else
+       {
+               output = CreateNode(IFF, c0, c1);
+       }
 
-  delete SimplifyNegMap;
-  SimplifyNegMap = new ASTNodeMap(INITIAL_SIMPLIFY_MAP_SIZE);
+       //memoize
+       UpdateSimplifyMap(a, output, pushNeg);
+       return output;
 }
 
+ASTNode BeevMgr::SimplifyIteFormula(const ASTNode& b, bool pushNeg)
+{
+       if (!optimize)
+               return b;
+
+       ASTNode output;
+       if (CheckSimplifyMap(b, output, pushNeg))
+               return output;
+
+       if (!(b.Degree() == 3 && ITE == b.GetKind()))
+               FatalError("SimplifyIteFormula: vector with wrong num of nodes", ASTUndefined);
+
+       ASTNode a = b;
+       ASTNode t0 = SimplifyFormula(a[0], false);
+       ASTNode t1, t2;
+       if (pushNeg)
+       {
+               t1 = SimplifyFormula(a[1], true);
+               t2 = SimplifyFormula(a[2], true);
+       }
+       else
+       {
+               t1 = SimplifyFormula(a[1], false);
+               t2 = SimplifyFormula(a[2], false);
+       }
+
+       if (ASTTrue == t0)
+       {
+               output = t1;
+       }
+       else if (ASTFalse == t0)
+       {
+               output = t2;
+       }
+       else if (t1 == t2)
+       {
+               output = t1;
+       }
+       else if (ASTTrue == t1 && ASTFalse == t2)
+       {
+               output = t0;
+       }
+       else if (ASTFalse == t1 && ASTTrue == t2)
+       {
+               output = SimplifyFormula(t0, true);
+       }
+       else if (ASTTrue == t1)
+       {
+               output = CreateNode(OR, t0, t2);
+       }
+       else if (ASTFalse == t1)
+       {
+               output = CreateNode(AND, CreateNode(NOT, t0), t2);
+       }
+       else if (ASTTrue == t2)
+       {
+               output = CreateNode(OR, CreateNode(NOT, t0), t1);
+       }
+       else if (ASTFalse == t2)
+       {
+               output = CreateNode(AND, t0, t1);
+       }
+       else if (CheckAlwaysTrueFormMap(t0))
+       {
+               output = t1;
+       }
+       else if (CheckAlwaysTrueFormMap(CreateNode(NOT, t0)) || (NOT == t0.GetKind() && CheckAlwaysTrueFormMap(t0[0])))
+       {
+               output = t2;
+       }
+       else
+       {
+               output = CreateNode(ITE, t0, t1, t2);
+       }
+
+       //memoize
+       UpdateSimplifyMap(a, output, pushNeg);
+       return output;
+}
+
+//one level deep flattening
+ASTNode BeevMgr::FlattenOneLevel(const ASTNode& a)
+{
+       Kind k = a.GetKind();
+       if (!(BVPLUS == k || AND == k || OR == k
+       //|| BVAND == k
+       //|| BVOR == k
+       ))
+       {
+               return a;
+       }
+
+       ASTNode output;
+       // if(CheckSimplifyMap(a,output,false)) {
+       //       //check memo table
+       //       //cerr << "output of SimplifyTerm Cache: " << output << endl;
+       //       return output;
+       //     }
+
+       ASTVec c = a.GetChildren();
+       ASTVec o;
+       for (ASTVec::iterator it = c.begin(), itend = c.end(); it != itend; it++)
+       {
+               ASTNode aaa = *it;
+               if (k == aaa.GetKind())
+               {
+                       ASTVec ac = aaa.GetChildren();
+                       o.insert(o.end(), ac.begin(), ac.end());
+               }
+               else
+                       o.push_back(aaa);
+       }
+
+       if (is_Form_kind(k))
+               output = CreateNode(k, o);
+       else
+               output = CreateTerm(k, a.GetValueWidth(), o);
+
+       //UpdateSimplifyMap(a,output,false);
+       return output;
+       //memoize
+} //end of flattenonelevel()
+
+ASTNode BeevMgr::SimplifyTerm_TopLevel(const ASTNode& b)
+{
+       ResetSimplifyMaps();
+       ASTNode out = SimplifyTerm(b);
+       ResetSimplifyMaps();
+       return out;
+}
+
+//This function simplifies terms based on their kind
+ASTNode BeevMgr::SimplifyTerm(const ASTNode& inputterm)
+{
+       //cout << "SimplifyTerm: input: " << a << endl;
+       if (!optimize)
+       {
+               return inputterm;
+       }
+
+       ASTNode output;
+       BVTypeCheck(inputterm);
+
+       //########################################
+       //########################################
+
+       if (wordlevel_solve && CheckSolverMap(inputterm, output))
+       {
+               //cout << "SimplifyTerm: output: " << output << endl;
+               return SimplifyTerm(output);
+       }
+
+       if (CheckSimplifyMap(inputterm, output, false))
+       {
+               //cerr << "output of SimplifyTerm Cache: " << output << endl;
+               return output;
+       }
+       //########################################
+       //########################################
+
+       Kind k = inputterm.GetKind();
+       if (!is_Term_kind(k))
+       {
+               FatalError("SimplifyTerm: You have input a Non-term", ASTUndefined);
+       }
+
+       unsigned int inputValueWidth = inputterm.GetValueWidth();
+       switch (k)
+       {
+               case BVCONST:
+                       output = inputterm;
+                       break;
+               case SYMBOL:
+                       if (CheckSolverMap(inputterm, output))
+                       {
+                               return SimplifyTerm(output);
+                       }
+                       output = inputterm;
+                       break;
+               case BVMULT:
+               {
+                       if (2 != inputterm.Degree())
+                       {
+                               FatalError("SimplifyTerm: We assume that BVMULT is binary", inputterm);
+                       }
+
+                       // Described nicely by Warren, Hacker's Delight pg 135.
+                       // Turn sequences of one bits into subtractions.
+                       // 28*x == 32x - 4x (two instructions), rather than 16x+ 8x+ 4x.
+                       // When fully implemented. I.e. supporting sequences of 1 anywhere.
+                       // Other simplifications will try to fold these back in. So need to be careful
+                       // about when the simplifications are applied. But in this version it won't
+                       // be simplified down by anything else.
+
+
+                       // This (temporary) version only simplifies if all the left most bits are set.
+                       // All the leftmost bits being set simplifies very nicely down.
+                       const ASTNode& n0 = inputterm.GetChildren()[0];
+                       const ASTNode& n1 = inputterm.GetChildren()[1];
+
+                       // This implementation has two problems.
+                       // 1) It causes a segfault for cmu-model15,16,17
+                       // 2) It doesn't count the number of bits saved, so if there is a single
+                       // leading bit it will invert it. Even though that will take more shifts
+                       // and adds when it's finally done.
+
+                       // disabled.
+                       if (false && (BVCONST == n0.GetKind()) ^ (BVCONST == n1.GetKind()))
+                       {
+                               CBV constant = (BVCONST == n0.GetKind()) ? n0.GetBVConst() : n1.GetBVConst();
+                               ASTNode other = (BVCONST == n0.GetKind()) ? n1 : n0;
+
+                               int startSequence = 0;
+                               for (unsigned int i = 0; i < inputValueWidth; i++)
+                               {
+                                       if (!CONSTANTBV::BitVector_bit_test(constant, i))
+                                               startSequence = i;
+                               }
+
+                               if ((inputValueWidth - startSequence) > 3)
+                               {
+                                       // turn off all bits from "startSequence to the end", then add one.
+                                       CBV maskedPlusOne = CONSTANTBV::BitVector_Create(inputValueWidth, true);
+                                       for (int i = 0; i < startSequence; i++)
+                                       {
+                                               if (!CONSTANTBV::BitVector_bit_test(constant, i)) // swap
+                                                       CONSTANTBV::BitVector_Bit_On(maskedPlusOne, i);
+                                       }
+                                       CONSTANTBV::BitVector_increment(maskedPlusOne);
+                                       ASTNode temp = CreateTerm(BVMULT, inputValueWidth, CreateBVConst(maskedPlusOne, inputValueWidth), other);
+                                       output = CreateTerm(BVNEG, inputValueWidth, temp);
+                               }
+                       }
+
+               }
+                       if (NULL != output)
+                               break;
+
+               case BVPLUS:
+               {
+
+                       ASTVec c = FlattenOneLevel(inputterm).GetChildren();
+                       SortByArith(c);
+                       ASTVec constkids, nonconstkids;
+
+                       //go through the childnodes, and separate constant and
+                       //nonconstant nodes. combine the constant nodes using the
+                       //constevaluator. if the resultant constant is zero and k ==
+                       //BVPLUS, then ignore it (similarily for 1 and BVMULT).  else,
+                       //add the computed constant to the nonconst vector, flatten,
+                       //sort, and create BVPLUS/BVMULT and return
+                       for (ASTVec::iterator it = c.begin(), itend = c.end(); it != itend; it++)
+                       {
+                               ASTNode aaa = SimplifyTerm(*it);
+                               if (BVCONST == aaa.GetKind())
+                               {
+                                       constkids.push_back(aaa);
+                               }
+                               else
+                               {
+                                       nonconstkids.push_back(aaa);
+                               }
+                       }
+
+                       ASTNode one = CreateOneConst(inputValueWidth);
+                       ASTNode max = CreateMaxConst(inputValueWidth);
+                       ASTNode zero = CreateZeroConst(inputValueWidth);
+
+                       //initialize constoutput to zero, in case there are no elements
+                       //in constkids
+                       ASTNode constoutput = (k == BVPLUS) ? zero : one;
+
+                       if (1 == constkids.size())
+                       {
+                               //only one element in constkids
+                               constoutput = constkids[0];
+                       }
+                       else if (1 < constkids.size())
+                       {
+                               //many elements in constkids. simplify it
+                               constoutput = CreateTerm(k, inputterm.GetValueWidth(), constkids);
+                               constoutput = BVConstEvaluator(constoutput);
+                       }
+
+                       if (BVMULT == k && zero == constoutput)
+                       {
+                               output = zero;
+                       }
+                       else if (BVMULT == k && 1 == nonconstkids.size() && constoutput == max)
+                       {
+                               //useful special case opt: when input is BVMULT(max_const,t),
+                               //then output = BVUMINUS(t). this is easier on the bitblaster
+                               output = CreateTerm(BVUMINUS, inputValueWidth, nonconstkids);
+                       }
+                       else
+                       {
+                               if (0 < nonconstkids.size())
+                               {
+                                       //nonconstkids is not empty. First, combine const and
+                                       //nonconstkids
+                                       if (BVPLUS == k && constoutput != zero)
+                                       {
+                                               nonconstkids.push_back(constoutput);
+                                       }
+                                       else if (BVMULT == k && constoutput != one)
+                                       {
+                                               nonconstkids.push_back(constoutput);
+                                       }
+
+                                       if (1 == nonconstkids.size())
+                                       {
+                                               //exactly one element in nonconstkids. output is exactly
+                                               //nonconstkids[0]
+                                               output = nonconstkids[0];
+                                       }
+                                       else
+                                       {
+                                               //more than 1 element in nonconstkids. create BVPLUS term
+                                               SortByArith(nonconstkids);
+                                               output = CreateTerm(k, inputValueWidth, nonconstkids);
+                                               output = FlattenOneLevel(output);
+                                               output = DistributeMultOverPlus(output, true);
+                                               output = CombineLikeTerms(output);
+                                       }
+                               }
+                               else
+                               {
+                                       //nonconstkids was empty, all childnodes were constant, hence
+                                       //constoutput is the output.
+                                       output = constoutput;
+                               }
+                       }
+                       if (BVMULT == output.GetKind() || BVPLUS == output.GetKind())
+                       {
+                               ASTVec d = output.GetChildren();
+                               SortByArith(d);
+                               output = CreateTerm(output.GetKind(), output.GetValueWidth(), d);
+                       }
+                       break;
+               }
+               case BVSUB:
+               {
+                       ASTVec c = inputterm.GetChildren();
+                       ASTNode a0 = SimplifyTerm(inputterm[0]);
+                       ASTNode a1 = SimplifyTerm(inputterm[1]);
+                       unsigned int l = inputValueWidth;
+                       if (a0 == a1)
+                               output = CreateZeroConst(l);
+                       else
+                       {
+                               //covert x-y into x+(-y) and simplify. this transformation
+                               //triggers more simplifications
+                               //
+                               a1 = SimplifyTerm(CreateTerm(BVUMINUS, l, a1));
+                               output = SimplifyTerm(CreateTerm(BVPLUS, l, a0, a1));
+                       }
+                       break;
+               }
+               case BVUMINUS:
+               {
+                       //important to treat BVUMINUS as a special case, because it
+                       //helps in arithmetic transformations. e.g.  x + BVUMINUS(x) is
+                       //actually 0. One way to reveal this fact is to strip bvuminus
+                       //out, and replace with something else so that combineliketerms
+                       //can catch this fact.
+                       ASTNode a0 = SimplifyTerm(inputterm[0]);
+                       Kind k1 = a0.GetKind();
+                       unsigned int l = a0.GetValueWidth();
+                       ASTNode one = CreateOneConst(l);
+                       switch (k1)
+                       {
+                               case BVUMINUS:
+                                       output = a0[0];
+                                       break;
+                               case BVCONST:
+                               {
+                                       output = BVConstEvaluator(CreateTerm(BVUMINUS, l, a0));
+                                       break;
+                               }
+                               case BVNEG:
+                               {
+                                       output = SimplifyTerm(CreateTerm(BVPLUS, l, a0[0], one));
+                                       break;
+                               }
+                               case BVMULT:
+                               {
+                                       if (BVUMINUS == a0[0].GetKind())
+                                       {
+                                               output = CreateTerm(BVMULT, l, a0[0][0], a0[1]);
+                                       }
+                                       else if (BVUMINUS == a0[1].GetKind())
+                                       {
+                                               output = CreateTerm(BVMULT, l, a0[0], a0[1][0]);
+                                       }
+                                       else
+                                       {
+                                               ASTNode a00 = SimplifyTerm(CreateTerm(BVUMINUS, l, a0[0]));
+                                               output = CreateTerm(BVMULT, l, a00, a0[1]);
+                                       }
+                                       break;
+                               }
+                               case BVPLUS:
+                               {
+                                       //push BVUMINUS over all the monomials of BVPLUS. Simplify
+                                       //along the way
+                                       //
+                                       //BVUMINUS(a1x1 + a2x2 + ...) <=> BVPLUS(BVUMINUS(a1x1) +
+                                       //BVUMINUS(a2x2) + ...
+                                       ASTVec c = a0.GetChildren();
+                                       ASTVec o;
+                                       for (ASTVec::iterator it = c.begin(), itend = c.end(); it != itend; it++)
+                                       {
+                                               //Simplify(BVUMINUS(a1x1))
+                                               ASTNode aaa = SimplifyTerm(CreateTerm(BVUMINUS, l, *it));
+                                               o.push_back(aaa);
+                                       }
+                                       //simplify the bvplus
+                                       output = SimplifyTerm(CreateTerm(BVPLUS, l, o));
+                                       break;
+                               }
+                               case BVSUB:
+                               {
+                                       //BVUMINUS(BVSUB(x,y)) <=> BVSUB(y,x)
+                                       output = SimplifyTerm(CreateTerm(BVSUB, l, a0[1], a0[0]));
+                                       break;
+                               }
+                               case ITE:
+                               {
+                                       //BVUMINUS(ITE(c,t1,t2)) <==> ITE(c,BVUMINUS(t1),BVUMINUS(t2))
+                                       ASTNode c = a0[0];
+                                       ASTNode t1 = SimplifyTerm(CreateTerm(BVUMINUS, l, a0[1]));
+                                       ASTNode t2 = SimplifyTerm(CreateTerm(BVUMINUS, l, a0[2]));
+                                       output = CreateSimplifiedTermITE(c, t1, t2);
+                                       break;
+                               }
+                               default:
+                               {
+                                       output = CreateTerm(BVUMINUS, l, a0);
+                                       break;
+                               }
+                       }
+                       break;
+               }
+               case BVEXTRACT:
+               {
+                       //it is important to take care of wordlevel transformation in
+                       //BVEXTRACT. it exposes oppurtunities for later simplification
+                       //and solving (variable elimination)
+                       ASTNode a0 = SimplifyTerm(inputterm[0]);
+                       Kind k1 = a0.GetKind();
+                       unsigned int a_len = inputValueWidth;
+
+                       //indices for BVEXTRACT
+                       ASTNode i = inputterm[1];
+                       ASTNode j = inputterm[2];
+                       ASTNode zero = CreateBVConst(32, 0);
+                       //recall that the indices of BVEXTRACT are always 32 bits
+                       //long. therefore doing a GetBVUnsigned is ok.
+                       unsigned int i_val = GetUnsignedConst(i);
+                       unsigned int j_val = GetUnsignedConst(j);
+
+                       // a0[i:0] and len(a0)=i+1, then return a0
+                       if (0 == j_val && a_len == a0.GetValueWidth())
+                               return a0;
+
+                       switch (k1)
+                       {
+                               case BVCONST:
+                               {
+                                       //extract the constant
+                                       output = BVConstEvaluator(CreateTerm(BVEXTRACT, a_len, a0, i, j));
+                                       break;
+                               }
+                               case BVCONCAT:
+                               {
+                                       //assumes concatenation is binary
+                                       //
+                                       //input is of the form a0[i:j]
+                                       //
+                                       //a0 is the conatentation t@u, and a0[0] is t, and a0[1] is u
+                                       ASTNode t = a0[0];
+                                       ASTNode u = a0[1];
+                                       unsigned int len_a0 = a0.GetValueWidth();
+                                       unsigned int len_u = u.GetValueWidth();
+
+                                       if (len_u > i_val)
+                                       {
+                                               //Apply the following rule:
+                                               // (t@u)[i:j] <==> u[i:j], if len(u) > i
+                                               //
+                                               output = SimplifyTerm(CreateTerm(BVEXTRACT, a_len, u, i, j));
+                                       }
+                                       else if (len_a0 > i_val && j_val >= len_u)
+                                       {
+                                               //Apply the rule:
+                                               // (t@u)[i:j] <==> t[i-len_u:j-len_u], if len(t@u) > i >= j >= len(u)
+                                               i = CreateBVConst(32, i_val - len_u);
+                                               j = CreateBVConst(32, j_val - len_u);
+                                               output = SimplifyTerm(CreateTerm(BVEXTRACT, a_len, t, i, j));
+                                       }
+                                       else
+                                       {
+                                               //Apply the rule:
+                                               // (t@u)[i:j] <==> t[i-len_u:0] @ u[len_u-1:j]
+                                               i = CreateBVConst(32, i_val - len_u);
+                                               ASTNode m = CreateBVConst(32, len_u - 1);
+                                               t = SimplifyTerm(CreateTerm(BVEXTRACT, i_val - len_u + 1, t, i, zero));
+                                               u = SimplifyTerm(CreateTerm(BVEXTRACT, len_u - j_val, u, m, j));
+                                               output = CreateTerm(BVCONCAT, a_len, t, u);
+                                       }
+                                       break;
+                               }
+                               case BVPLUS:
+                               case BVMULT:
+                               {
+                                       // (BVMULT(n,t,u))[i:j] <==> BVMULT(i+1,t[i:0],u[i:0])[i:j]
+                                       //similar rule for BVPLUS
+                                       ASTVec c = a0.GetChildren();
+                                       ASTVec o;
+                                       for (ASTVec::iterator jt = c.begin(), jtend = c.end(); jt != jtend; jt++)
+                                       {
+                                               ASTNode aaa = *jt;
+                                               aaa = SimplifyTerm(CreateTerm(BVEXTRACT, i_val + 1, aaa, i, zero));
+                                               o.push_back(aaa);
+                                       }
+                                       output = CreateTerm(a0.GetKind(), i_val + 1, o);
+                                       if (j_val != 0)
+                                       {
+                                               //add extraction only if j is not zero
+                                               output = CreateTerm(BVEXTRACT, a_len, output, i, j);
+                                       }
+                                       break;
+                               }
+                               case BVAND:
+                               case BVOR:
+                               case BVXOR:
+                               {
+                                       //assumes these operators are binary
+                                       //
+                                       // (t op u)[i:j] <==> t[i:j] op u[i:j]
+                                       ASTNode t = a0[0];
+                                       ASTNode u = a0[1];
+                                       t = SimplifyTerm(CreateTerm(BVEXTRACT, a_len, t, i, j));
+                                       u = SimplifyTerm(CreateTerm(BVEXTRACT, a_len, u, i, j));
+                                       BVTypeCheck(t);
+                                       BVTypeCheck(u);
+                                       output = CreateTerm(k1, a_len, t, u);
+                                       break;
+                               }
+                               case BVNEG:
+                               {
+                                       // (~t)[i:j] <==> ~(t[i:j])
+                                       ASTNode t = a0[0];
+                                       t = SimplifyTerm(CreateTerm(BVEXTRACT, a_len, t, i, j));
+                                       output = CreateTerm(BVNEG, a_len, t);
+                                       break;
+                               }
+                                       // case BVSX:{
+                                       //      //(BVSX(t,n)[i:j] <==> BVSX(t,i+1), if n >= i+1 and j=0
+                                       //      ASTNode t = a0[0];
+                                       //      unsigned int bvsx_len = a0.GetValueWidth();
+                                       //      if(bvsx_len < a_len) {
+                                       //        FatalError("SimplifyTerm: BVEXTRACT over BVSX:"
+                                       //                   "the length of BVSX term must be greater than extract-len",inputterm);
+                                       //      }
+                                       //      if(j != zero) {
+                                       //        output = CreateTerm(BVEXTRACT,a_len,a0,i,j);
+                                       //      }
+                                       //      else {
+                                       //        output = CreateTerm(BVSX,a_len,t,CreateBVConst(32,a_len));
+                                       //      }
+                                       //      break;
+                                       //       }
+                               case ITE:
+                               {
+                                       ASTNode t0 = a0[0];
+                                       ASTNode t1 = SimplifyTerm(CreateTerm(BVEXTRACT, a_len, a0[1], i, j));
+                                       ASTNode t2 = SimplifyTerm(CreateTerm(BVEXTRACT, a_len, a0[2], i, j));
+                                       output = CreateSimplifiedTermITE(t0, t1, t2);
+                                       break;
+                               }
+                               default:
+                               {
+                                       output = CreateTerm(BVEXTRACT, a_len, a0, i, j);
+                                       break;
+                               }
+                       }
+                       break;
+               }
+               case BVNEG:
+               {
+                       ASTNode a0 = SimplifyTerm(inputterm[0]);
+                       unsigned len = inputValueWidth;
+                       switch (a0.GetKind())
+                       {
+                               case BVCONST:
+                                       output = BVConstEvaluator(CreateTerm(BVNEG, len, a0));
+                                       break;
+                               case BVNEG:
+                                       output = a0[0];
+                                       break;
+                                       // case ITE: {
+                                       //      ASTNode cond = a0[0];
+                                       //      ASTNode thenpart = SimplifyTerm(CreateTerm(BVNEG,len,a0[1]));
+                                       //      ASTNode elsepart = SimplifyTerm(CreateTerm(BVNEG,len,a0[2]));
+                                       //      output = CreateSimplifiedTermITE(cond,thenpart,elsepart);
+                                       //      break;
+                                       //       }
+                               default:
+                                       output = CreateTerm(BVNEG, len, a0);
+                                       break;
+                       }
+                       break;
+               }
+
+               case BVZX:
+               {
+                       ASTNode a0 = SimplifyTerm(inputterm[0]);
+                       if (a0.GetKind() == BVCONST)
+                               output = BVConstEvaluator(CreateTerm(BVZX, inputValueWidth, a0, inputterm[1]));
+                       else
+                               output = CreateTerm(BVZX, inputValueWidth, a0, inputterm[1]);
+               }
+                       break;
+
+               case BVSX:
+               {
+                       //a0 is the expr which is being sign extended
+                       ASTNode a0 = SimplifyTerm(inputterm[0]);
+                       //a1 represents the length of the term BVSX(a0)
+                       ASTNode a1 = inputterm[1];
+                       //output length of the BVSX term
+                       unsigned len = inputValueWidth;
+
+                       if (a0.GetValueWidth() == len)
+                       {
+                               //nothing to signextend
+                               return a0;
+                       }
+
+                       switch (a0.GetKind())
+                       {
+                               case BVCONST:
+                                       output = BVConstEvaluator(CreateTerm(BVSX, len, a0, a1));
+                                       break;
+                               case BVNEG:
+                                       output = CreateTerm(a0.GetKind(), len, CreateTerm(BVSX, len, a0[0], a1));
+                                       break;
+                               case BVAND:
+                               case BVOR:
+                                       //assuming BVAND and BVOR are binary
+                                       output = CreateTerm(a0.GetKind(), len, CreateTerm(BVSX, len, a0[0], a1), CreateTerm(BVSX, len, a0[1], a1));
+                                       break;
+                               case BVPLUS:
+                               {
+                                       //BVSX(m,BVPLUS(n,BVSX(t1),BVSX(t2))) <==> BVPLUS(m,BVSX(m,t1),BVSX(m,t2))
+                                       ASTVec c = a0.GetChildren();
+                                       bool returnflag = false;
+                                       for (ASTVec::iterator it = c.begin(), itend = c.end(); it != itend; it++)
+                                       {
+                                               if (BVSX != it->GetKind())
+                                               {
+                                                       returnflag = true;
+                                                       break;
+                                               }
+                                       }
+                                       if (returnflag)
+                                       {
+                                               output = CreateTerm(BVSX, len, a0, a1);
+                                       }
+                                       else
+                                       {
+                                               ASTVec o;
+                                               for (ASTVec::iterator it = c.begin(), itend = c.end(); it != itend; it++)
+                                               {
+                                                       ASTNode aaa = SimplifyTerm(CreateTerm(BVSX, len, *it, a1));
+                                                       o.push_back(aaa);
+                                               }
+                                               output = CreateTerm(a0.GetKind(), len, o);
+                                       }
+                                       break;
+                               }
+                               case BVSX:
+                               {
+                                       //if you have BVSX(m,BVSX(n,a)) then you can drop the inner
+                                       //BVSX provided m is greater than n.
+                                       a0 = SimplifyTerm(a0[0]);
+                                       output = CreateTerm(BVSX, len, a0, a1);
+                                       break;
+                               }
+                               case ITE:
+                               {
+                                       ASTNode cond = a0[0];
+                                       ASTNode thenpart = SimplifyTerm(CreateTerm(BVSX, len, a0[1], a1));
+                                       ASTNode elsepart = SimplifyTerm(CreateTerm(BVSX, len, a0[2], a1));
+                                       output = CreateSimplifiedTermITE(cond, thenpart, elsepart);
+                                       break;
+                               }
+                               default:
+                                       output = CreateTerm(BVSX, len, a0, a1);
+                                       break;
+                       }
+                       break;
+               }
+               case BVAND:
+               case BVOR:
+               {
+                       ASTNode max = CreateMaxConst(inputValueWidth);
+                       ASTNode zero = CreateZeroConst(inputValueWidth);
+
+                       ASTNode identity = (BVAND == k) ? max : zero;
+                       ASTNode annihilator = (BVAND == k) ? zero : max;
+                       ASTVec c = FlattenOneLevel(inputterm).GetChildren();
+                       SortByArith(c);
+                       ASTVec o;
+                       bool constant = true;
+                       for (ASTVec::iterator it = c.begin(), itend = c.end(); it != itend; it++)
+                       {
+                               ASTNode aaa = SimplifyTerm(*it);
+                               if (BVCONST != aaa.GetKind())
+                               {
+                                       constant = false;
+                               }
+
+                               if (aaa == annihilator)
+                               {
+                                       output = annihilator;
+                                       //memoize
+                                       UpdateSimplifyMap(inputterm, output, false);
+                                       //cerr << "output of SimplifyTerm: " << output << endl;
+                                       return output;
+                               }
+
+                               if (aaa != identity)
+                               {
+                                       o.push_back(aaa);
+                               }
+                       }
+
+                       switch (o.size())
+                       {
+                               case 0:
+                                       output = identity;
+                                       break;
+                               case 1:
+                                       output = o[0];
+                                       break;
+                               default:
+                                       SortByArith(o);
+                                       output = CreateTerm(k, inputValueWidth, o);
+                                       if (constant)
+                                       {
+                                               output = BVConstEvaluator(output);
+                                       }
+                                       break;
+                       }
+                       break;
+               }
+               case BVCONCAT:
+               {
+                       ASTNode t = SimplifyTerm(inputterm[0]);
+                       ASTNode u = SimplifyTerm(inputterm[1]);
+                       Kind tkind = t.GetKind();
+                       Kind ukind = u.GetKind();
+
+                       if (BVCONST == tkind && BVCONST == ukind)
+                       {
+                               output = BVConstEvaluator(CreateTerm(BVCONCAT, inputValueWidth, t, u));
+                       }
+                       else if (BVEXTRACT == tkind && BVEXTRACT == ukind && t[0] == u[0])
+                       {
+                               //to handle the case x[m:n]@x[n-1:k] <==> x[m:k]
+                               ASTNode t_hi = t[1];
+                               ASTNode t_low = t[2];
+                               ASTNode u_hi = u[1];
+                               ASTNode u_low = u[2];
+                               ASTNode c = BVConstEvaluator(CreateTerm(BVPLUS, 32, u_hi, CreateOneConst(32)));
+                               if (t_low == c)
+                               {
+                                       output = CreateTerm(BVEXTRACT, inputValueWidth, t[0], t_hi, u_low);
+                               }
+                               else
+                               {
+                                       output = CreateTerm(BVCONCAT, inputValueWidth, t, u);
+                               }
+                       }
+                       else
+                       {
+                               output = CreateTerm(BVCONCAT, inputValueWidth, t, u);
+                       }
+                       break;
+               }
+               case BVXOR:
+               case BVXNOR:
+               case BVNAND:
+               case BVNOR:
+               case BVLEFTSHIFT:
+               case BVRIGHTSHIFT:
+               case BVVARSHIFT:
+               case BVSRSHIFT:
+               case BVDIV:
+               case BVMOD:
+               {
+                       ASTVec c = inputterm.GetChildren();
+                       ASTVec o;
+                       bool constant = true;
+                       for (ASTVec::iterator it = c.begin(), itend = c.end(); it != itend; it++)
+                       {
+                               ASTNode aaa = SimplifyTerm(*it);
+                               if (BVCONST != aaa.GetKind())
+                               {
+                                       constant = false;
+                               }
+                               o.push_back(aaa);
+                       }
+                       output = CreateTerm(k, inputValueWidth, o);
+                       if (constant)
+                               output = BVConstEvaluator(output);
+                       break;
+               }
+               case READ:
+               {
+                       ASTNode out1;
+                       //process only if not  in the substitution map. simplifymap
+                       //has been checked already
+                       if (!CheckSubstitutionMap(inputterm, out1))
+                       {
+                               if (WRITE == inputterm[0].GetKind())
+                               {
+                                       //get rid of all writes
+                                       ASTNode nowrites = RemoveWrites_TopLevel(inputterm);
+                                       out1 = nowrites;
+                               }
+                               else if (ITE == inputterm[0].GetKind())
+                               {
+                                       ASTNode cond = SimplifyFormula(inputterm[0][0], false);
+                                       ASTNode index = SimplifyTerm(inputterm[1]);
+
+                                       ASTNode read1 = CreateTerm(READ, inputValueWidth, inputterm[0][1], index);
+                                       ASTNode read2 = CreateTerm(READ, inputValueWidth, inputterm[0][2], index);
+
+                                       read1 = SimplifyTerm(read1);
+                                       read2 = SimplifyTerm(read2);
+                                       out1 = CreateSimplifiedTermITE(cond, read1, read2);
+                               }
+                               else
+                               {
+                                       //arr is a SYMBOL for sure
+                                       ASTNode arr = inputterm[0];
+                                       ASTNode index = SimplifyTerm(inputterm[1]);
+                                       out1 = CreateTerm(READ, inputValueWidth, arr, index);
+                               }
+                       }
+                       //it is possible that after all the procesing the READ term
+                       //reduces to READ(Symbol,const) and hence we should check the
+                       //substitutionmap once again.
+                       if (!CheckSubstitutionMap(out1, output))
+                               output = out1;
+                       break;
+               }
+               case ITE:
+               {
+                       ASTNode t0 = SimplifyFormula(inputterm[0], false);
+                       ASTNode t1 = SimplifyTerm(inputterm[1]);
+                       ASTNode t2 = SimplifyTerm(inputterm[2]);
+                       output = CreateSimplifiedTermITE(t0, t1, t2);
+                       break;
+               }
+               case SBVREM:
+               case SBVDIV:
+               {
+                       ASTVec c = inputterm.GetChildren();
+                       ASTVec o;
+                       for (ASTVec::iterator it = c.begin(), itend = c.end(); it != itend; it++)
+                       {
+                               ASTNode aaa = SimplifyTerm(*it);
+                               o.push_back(aaa);
+                       }
+                       output = CreateTerm(k, inputValueWidth, o);
+                       break;
+               }
+               case WRITE:
+               default:
+                       FatalError("SimplifyTerm: Control should never reach here:", inputterm, k);
+                       return inputterm;
+                       break;
+       }
+       assert(NULL != output);
+
+       //memoize
+       UpdateSimplifyMap(inputterm, output, false);
+       //cerr << "SimplifyTerm: output" << output << endl;
+       // CheckSimplifyInvariant(inputterm,output);
+
+       return output;
+} //end of SimplifyTerm()
+
+ASTNode BeevMgr::SimplifyTermAux(const ASTNode& inputterm)
+{
+       //cout << "SimplifyTerm: input: " << a << endl;
+       if (!optimize)
+       {
+               return inputterm;
+       }
+
+       ASTNode output;
+       BVTypeCheck(inputterm);
+
+       //########################################
+       //########################################
+
+       if (wordlevel_solve && CheckSolverMap(inputterm, output))
+       {
+               //cout << "SimplifyTerm: output: " << output << endl;
+               return SimplifyTermAux(output);
+       }
 
-};//end of namespace
+       Kind k = inputterm.GetKind();
+       if (!is_Term_kind(k))
+       {
+               FatalError("SimplifyTerm: You have input a Non-term", ASTUndefined);
+       }
+
+       unsigned int inputValueWidth = inputterm.GetValueWidth();
+       switch (k)
+       {
+               case BVCONST:
+                       output = inputterm;
+                       break;
+               case SYMBOL:
+                       if (CheckSolverMap(inputterm, output))
+                       {
+                               return SimplifyTerm(output);
+                       }
+                       output = inputterm;
+                       break;
+               case BVMULT:
+               case BVPLUS:
+               {
+                       if (BVMULT == k && 2 != inputterm.Degree())
+                       {
+                               FatalError("SimplifyTerm: We assume that BVMULT is binary", inputterm);
+                       }
+
+                       ASTVec c = FlattenOneLevel(inputterm).GetChildren();
+                       SortByArith(c);
+                       ASTVec constkids, nonconstkids;
+
+                       //go through the childnodes, and separate constant and
+                       //nonconstant nodes. combine the constant nodes using the
+                       //constevaluator. if the resultant constant is zero and k ==
+                       //BVPLUS, then ignore it (similarily for 1 and BVMULT).  else,
+                       //add the computed constant to the nonconst vector, flatten,
+                       //sort, and create BVPLUS/BVMULT and return
+                       for (ASTVec::iterator it = c.begin(), itend = c.end(); it != itend; it++)
+                       {
+                               ASTNode aaa = SimplifyTerm(*it);
+                               if (BVCONST == aaa.GetKind())
+                               {
+                                       constkids.push_back(aaa);
+                               }
+                               else
+                               {
+                                       nonconstkids.push_back(aaa);
+                               }
+                       }
+
+                       ASTNode one = CreateOneConst(inputValueWidth);
+                       ASTNode max = CreateMaxConst(inputValueWidth);
+                       ASTNode zero = CreateZeroConst(inputValueWidth);
+
+                       //initialize constoutput to zero, in case there are no elements
+                       //in constkids
+                       ASTNode constoutput = (k == BVPLUS) ? zero : one;
+
+                       if (1 == constkids.size())
+                       {
+                               //only one element in constkids
+                               constoutput = constkids[0];
+                       }
+                       else if (1 < constkids.size())
+                       {
+                               //many elements in constkids. simplify it
+                               constoutput = CreateTerm(k, inputterm.GetValueWidth(), constkids);
+                               constoutput = BVConstEvaluator(constoutput);
+                       }
+
+                       if (BVMULT == k && zero == constoutput)
+                       {
+                               output = zero;
+                       }
+                       else if (BVMULT == k && 1 == nonconstkids.size() && constoutput == max)
+                       {
+                               //useful special case opt: when input is BVMULT(max_const,t),
+                               //then output = BVUMINUS(t). this is easier on the bitblaster
+                               output = CreateTerm(BVUMINUS, inputValueWidth, nonconstkids);
+                       }
+                       else
+                       {
+                               if (0 < nonconstkids.size())
+                               {
+                                       //nonconstkids is not empty. First, combine const and
+                                       //nonconstkids
+                                       if (BVPLUS == k && constoutput != zero)
+                                       {
+                                               nonconstkids.push_back(constoutput);
+                                       }
+                                       else if (BVMULT == k && constoutput != one)
+                                       {
+                                               nonconstkids.push_back(constoutput);
+                                       }
+
+                                       if (1 == nonconstkids.size())
+                                       {
+                                               //exactly one element in nonconstkids. output is exactly
+                                               //nonconstkids[0]
+                                               output = nonconstkids[0];
+                                       }
+                                       else
+                                       {
+                                               //more than 1 element in nonconstkids. create BVPLUS term
+                                               SortByArith(nonconstkids);
+                                               output = CreateTerm(k, inputValueWidth, nonconstkids);
+                                               output = FlattenOneLevel(output);
+                                               output = DistributeMultOverPlus(output, true);
+                                               output = CombineLikeTerms(output);
+                                       }
+                               }
+                               else
+                               {
+                                       //nonconstkids was empty, all childnodes were constant, hence
+                                       //constoutput is the output.
+                                       output = constoutput;
+                               }
+                       }
+                       if (BVMULT == output.GetKind() || BVPLUS == output.GetKind())
+                       {
+                               ASTVec d = output.GetChildren();
+                               SortByArith(d);
+                               output = CreateTerm(output.GetKind(), output.GetValueWidth(), d);
+                       }
+                       break;
+               }
+               case BVSUB:
+               {
+                       ASTVec c = inputterm.GetChildren();
+                       ASTNode a0 = SimplifyTerm(inputterm[0]);
+                       ASTNode a1 = SimplifyTerm(inputterm[1]);
+                       unsigned int l = inputValueWidth;
+                       if (a0 == a1)
+                               output = CreateZeroConst(l);
+                       else
+                       {
+                               //covert x-y into x+(-y) and simplify. this transformation
+                               //triggers more simplifications
+                               //
+                               a1 = SimplifyTerm(CreateTerm(BVUMINUS, l, a1));
+                               output = SimplifyTerm(CreateTerm(BVPLUS, l, a0, a1));
+                       }
+                       break;
+               }
+               case BVUMINUS:
+               {
+                       //important to treat BVUMINUS as a special case, because it
+                       //helps in arithmetic transformations. e.g.  x + BVUMINUS(x) is
+                       //actually 0. One way to reveal this fact is to strip bvuminus
+                       //out, and replace with something else so that combineliketerms
+                       //can catch this fact.
+                       ASTNode a0 = SimplifyTerm(inputterm[0]);
+                       Kind k1 = a0.GetKind();
+                       unsigned int l = a0.GetValueWidth();
+                       ASTNode one = CreateOneConst(l);
+                       switch (k1)
+                       {
+                               case BVUMINUS:
+                                       output = a0[0];
+                                       break;
+                               case BVCONST:
+                               {
+                                       output = BVConstEvaluator(CreateTerm(BVUMINUS, l, a0));
+                                       break;
+                               }
+                               case BVNEG:
+                               {
+                                       output = SimplifyTerm(CreateTerm(BVPLUS, l, a0[0], one));
+                                       break;
+                               }
+                               case BVMULT:
+                               {
+                                       if (BVUMINUS == a0[0].GetKind())
+                                       {
+                                               output = CreateTerm(BVMULT, l, a0[0][0], a0[1]);
+                                       }
+                                       else if (BVUMINUS == a0[1].GetKind())
+                                       {
+                                               output = CreateTerm(BVMULT, l, a0[0], a0[1][0]);
+                                       }
+                                       else
+                                       {
+                                               ASTNode a00 = SimplifyTerm(CreateTerm(BVUMINUS, l, a0[0]));
+                                               output = CreateTerm(BVMULT, l, a00, a0[1]);
+                                       }
+                                       break;
+                               }
+                               case BVPLUS:
+                               {
+                                       //push BVUMINUS over all the monomials of BVPLUS. Simplify
+                                       //along the way
+                                       //
+                                       //BVUMINUS(a1x1 + a2x2 + ...) <=> BVPLUS(BVUMINUS(a1x1) +
+                                       //BVUMINUS(a2x2) + ...
+                                       ASTVec c = a0.GetChildren();
+                                       ASTVec o;
+                                       for (ASTVec::iterator it = c.begin(), itend = c.end(); it != itend; it++)
+                                       {
+                                               //Simplify(BVUMINUS(a1x1))
+                                               ASTNode aaa = SimplifyTerm(CreateTerm(BVUMINUS, l, *it));
+                                               o.push_back(aaa);
+                                       }
+                                       //simplify the bvplus
+                                       output = SimplifyTerm(CreateTerm(BVPLUS, l, o));
+                                       break;
+                               }
+                               case BVSUB:
+                               {
+                                       //BVUMINUS(BVSUB(x,y)) <=> BVSUB(y,x)
+                                       output = SimplifyTerm(CreateTerm(BVSUB, l, a0[1], a0[0]));
+                                       break;
+                               }
+                               case ITE:
+                               {
+                                       //BVUMINUS(ITE(c,t1,t2)) <==> ITE(c,BVUMINUS(t1),BVUMINUS(t2))
+                                       ASTNode c = a0[0];
+                                       ASTNode t1 = SimplifyTerm(CreateTerm(BVUMINUS, l, a0[1]));
+                                       ASTNode t2 = SimplifyTerm(CreateTerm(BVUMINUS, l, a0[2]));
+                                       output = CreateSimplifiedTermITE(c, t1, t2);
+                                       break;
+                               }
+                               default:
+                               {
+                                       output = CreateTerm(BVUMINUS, l, a0);
+                                       break;
+                               }
+                       }
+                       break;
+               }
+               case BVEXTRACT:
+               {
+                       //it is important to take care of wordlevel transformation in
+                       //BVEXTRACT. it exposes oppurtunities for later simplification
+                       //and solving (variable elimination)
+                       ASTNode a0 = SimplifyTerm(inputterm[0]);
+                       Kind k1 = a0.GetKind();
+                       unsigned int a_len = inputValueWidth;
+
+                       //indices for BVEXTRACT
+                       ASTNode i = inputterm[1];
+                       ASTNode j = inputterm[2];
+                       ASTNode zero = CreateBVConst(32, 0);
+                       //recall that the indices of BVEXTRACT are always 32 bits
+                       //long. therefore doing a GetBVUnsigned is ok.
+                       unsigned int i_val = GetUnsignedConst(i);
+                       unsigned int j_val = GetUnsignedConst(j);
+
+                       // a0[i:0] and len(a0)=i+1, then return a0
+                       if (0 == j_val && a_len == a0.GetValueWidth())
+                               return a0;
+
+                       switch (k1)
+                       {
+                               case BVCONST:
+                               {
+                                       //extract the constant
+                                       output = BVConstEvaluator(CreateTerm(BVEXTRACT, a_len, a0, i, j));
+                                       break;
+                               }
+                               case BVCONCAT:
+                               {
+                                       //assumes concatenation is binary
+                                       //
+                                       //input is of the form a0[i:j]
+                                       //
+                                       //a0 is the conatentation t@u, and a0[0] is t, and a0[1] is u
+                                       ASTNode t = a0[0];
+                                       ASTNode u = a0[1];
+                                       unsigned int len_a0 = a0.GetValueWidth();
+                                       unsigned int len_u = u.GetValueWidth();
+
+                                       if (len_u > i_val)
+                                       {
+                                               //Apply the following rule:
+                                               // (t@u)[i:j] <==> u[i:j], if len(u) > i
+                                               //
+                                               output = SimplifyTerm(CreateTerm(BVEXTRACT, a_len, u, i, j));
+                                       }
+                                       else if (len_a0 > i_val && j_val >= len_u)
+                                       {
+                                               //Apply the rule:
+                                               // (t@u)[i:j] <==> t[i-len_u:j-len_u], if len(t@u) > i >= j >= len(u)
+                                               i = CreateBVConst(32, i_val - len_u);
+                                               j = CreateBVConst(32, j_val - len_u);
+                                               output = SimplifyTerm(CreateTerm(BVEXTRACT, a_len, t, i, j));
+                                       }
+                                       else
+                                       {
+                                               //Apply the rule:
+                                               // (t@u)[i:j] <==> t[i-len_u:0] @ u[len_u-1:j]
+                                               i = CreateBVConst(32, i_val - len_u);
+                                               ASTNode m = CreateBVConst(32, len_u - 1);
+                                               t = SimplifyTerm(CreateTerm(BVEXTRACT, i_val - len_u + 1, t, i, zero));
+                                               u = SimplifyTerm(CreateTerm(BVEXTRACT, len_u - j_val, u, m, j));
+                                               output = CreateTerm(BVCONCAT, a_len, t, u);
+                                       }
+                                       break;
+                               }
+                               case BVPLUS:
+                               case BVMULT:
+                               {
+                                       // (BVMULT(n,t,u))[i:j] <==> BVMULT(i+1,t[i:0],u[i:0])[i:j]
+                                       //similar rule for BVPLUS
+                                       ASTVec c = a0.GetChildren();
+                                       ASTVec o;
+                                       for (ASTVec::iterator jt = c.begin(), jtend = c.end(); jt != jtend; jt++)
+                                       {
+                                               ASTNode aaa = *jt;
+                                               aaa = SimplifyTerm(CreateTerm(BVEXTRACT, i_val + 1, aaa, i, zero));
+                                               o.push_back(aaa);
+                                       }
+                                       output = CreateTerm(a0.GetKind(), i_val + 1, o);
+                                       if (j_val != 0)
+                                       {
+                                               //add extraction only if j is not zero
+                                               output = CreateTerm(BVEXTRACT, a_len, output, i, j);
+                                       }
+                                       break;
+                               }
+                               case BVAND:
+                               case BVOR:
+                               case BVXOR:
+                               {
+                                       //assumes these operators are binary
+                                       //
+                                       // (t op u)[i:j] <==> t[i:j] op u[i:j]
+                                       ASTNode t = a0[0];
+                                       ASTNode u = a0[1];
+                                       t = SimplifyTerm(CreateTerm(BVEXTRACT, a_len, t, i, j));
+                                       u = SimplifyTerm(CreateTerm(BVEXTRACT, a_len, u, i, j));
+                                       BVTypeCheck(t);
+                                       BVTypeCheck(u);
+                                       output = CreateTerm(k1, a_len, t, u);
+                                       break;
+                               }
+                               case BVNEG:
+                               {
+                                       // (~t)[i:j] <==> ~(t[i:j])
+                                       ASTNode t = a0[0];
+                                       t = SimplifyTerm(CreateTerm(BVEXTRACT, a_len, t, i, j));
+                                       output = CreateTerm(BVNEG, a_len, t);
+                                       break;
+                               }
+                                       // case BVSX:{
+                                       //      //(BVSX(t,n)[i:j] <==> BVSX(t,i+1), if n >= i+1 and j=0
+                                       //      ASTNode t = a0[0];
+                                       //      unsigned int bvsx_len = a0.GetValueWidth();
+                                       //      if(bvsx_len < a_len) {
+                                       //        FatalError("SimplifyTerm: BVEXTRACT over BVSX:"
+                                       //                   "the length of BVSX term must be greater than extract-len",inputterm);
+                                       //      }
+                                       //      if(j != zero) {
+                                       //        output = CreateTerm(BVEXTRACT,a_len,a0,i,j);
+                                       //      }
+                                       //      else {
+                                       //        output = CreateTerm(BVSX,a_len,t,CreateBVConst(32,a_len));
+                                       //      }
+                                       //      break;
+                                       //       }
+                               case ITE:
+                               {
+                                       ASTNode t0 = a0[0];
+                                       ASTNode t1 = SimplifyTerm(CreateTerm(BVEXTRACT, a_len, a0[1], i, j));
+                                       ASTNode t2 = SimplifyTerm(CreateTerm(BVEXTRACT, a_len, a0[2], i, j));
+                                       output = CreateSimplifiedTermITE(t0, t1, t2);
+                                       break;
+                               }
+                               default:
+                               {
+                                       output = CreateTerm(BVEXTRACT, a_len, a0, i, j);
+                                       break;
+                               }
+                       }
+                       break;
+               }
+               case BVNEG:
+               {
+                       ASTNode a0 = SimplifyTerm(inputterm[0]);
+                       unsigned len = inputValueWidth;
+                       switch (a0.GetKind())
+                       {
+                               case BVCONST:
+                                       output = BVConstEvaluator(CreateTerm(BVNEG, len, a0));
+                                       break;
+                               case BVNEG:
+                                       output = a0[0];
+                                       break;
+                                       // case ITE: {
+                                       //      ASTNode cond = a0[0];
+                                       //      ASTNode thenpart = SimplifyTerm(CreateTerm(BVNEG,len,a0[1]));
+                                       //      ASTNode elsepart = SimplifyTerm(CreateTerm(BVNEG,len,a0[2]));
+                                       //      output = CreateSimplifiedTermITE(cond,thenpart,elsepart);
+                                       //      break;
+                                       //       }
+                               default:
+                                       output = CreateTerm(BVNEG, len, a0);
+                                       break;
+                       }
+                       break;
+               }
+               case BVZX:
+               {
+                       //a0 is the expr which is being zero extended
+                       ASTNode a0 = SimplifyTerm(inputterm[0]);
+                       //a1 represents the length of the term BVZX(a0)
+                       ASTNode a1 = inputterm[1];
+                       //output length of the BVSX term
+                       unsigned len = inputValueWidth;
+
+                       output = CreateTerm(BVZX, len, a0, a1);
+                       break;
+               }
+                       break;
+
+               case BVSX:
+               {
+                       //a0 is the expr which is being sign extended
+                       ASTNode a0 = SimplifyTerm(inputterm[0]);
+                       //a1 represents the length of the term BVSX(a0)
+                       ASTNode a1 = inputterm[1];
+                       //output length of the BVSX term
+                       unsigned len = inputValueWidth;
+
+                       if (a0.GetValueWidth() == len)
+                       {
+                               //nothing to signextend
+                               return a0;
+                       }
+
+                       switch (a0.GetKind())
+                       {
+                               case BVCONST:
+                                       output = BVConstEvaluator(CreateTerm(BVSX, len, a0, a1));
+                                       break;
+                               case BVNEG:
+                                       output = CreateTerm(a0.GetKind(), len, CreateTerm(BVSX, len, a0[0], a1));
+                                       break;
+                               case BVAND:
+                               case BVOR:
+                                       //assuming BVAND and BVOR are binary
+                                       output = CreateTerm(a0.GetKind(), len, CreateTerm(BVSX, len, a0[0], a1), CreateTerm(BVSX, len, a0[1], a1));
+                                       break;
+                               case BVPLUS:
+                               {
+                                       //BVSX(m,BVPLUS(n,BVSX(t1),BVSX(t2))) <==> BVPLUS(m,BVSX(m,t1),BVSX(m,t2))
+                                       ASTVec c = a0.GetChildren();
+                                       bool returnflag = false;
+                                       for (ASTVec::iterator it = c.begin(), itend = c.end(); it != itend; it++)
+                                       {
+                                               if (BVSX != it->GetKind())
+                                               {
+                                                       returnflag = true;
+                                                       break;
+                                               }
+                                       }
+                                       if (returnflag)
+                                       {
+                                               output = CreateTerm(BVSX, len, a0, a1);
+                                       }
+                                       else
+                                       {
+                                               ASTVec o;
+                                               for (ASTVec::iterator it = c.begin(), itend = c.end(); it != itend; it++)
+                                               {
+                                                       ASTNode aaa = SimplifyTerm(CreateTerm(BVSX, len, *it, a1));
+                                                       o.push_back(aaa);
+                                               }
+                                               output = CreateTerm(a0.GetKind(), len, o);
+                                       }
+                                       break;
+                               }
+                               case BVSX:
+                               {
+                                       //if you have BVSX(m,BVSX(n,a)) then you can drop the inner
+                                       //BVSX provided m is greater than n.
+                                       a0 = SimplifyTerm(a0[0]);
+                                       output = CreateTerm(BVSX, len, a0, a1);
+                                       break;
+                               }
+                               case ITE:
+                               {
+                                       ASTNode cond = a0[0];
+                                       ASTNode thenpart = SimplifyTerm(CreateTerm(BVSX, len, a0[1], a1));
+                                       ASTNode elsepart = SimplifyTerm(CreateTerm(BVSX, len, a0[2], a1));
+                                       output = CreateSimplifiedTermITE(cond, thenpart, elsepart);
+                                       break;
+                               }
+                               default:
+                                       output = CreateTerm(BVSX, len, a0, a1);
+                                       break;
+                       }
+                       break;
+               }
+               case BVAND:
+               case BVOR:
+               {
+                       ASTNode max = CreateMaxConst(inputValueWidth);
+                       ASTNode zero = CreateZeroConst(inputValueWidth);
+
+                       ASTNode identity = (BVAND == k) ? max : zero;
+                       ASTNode annihilator = (BVAND == k) ? zero : max;
+                       ASTVec c = FlattenOneLevel(inputterm).GetChildren();
+                       SortByArith(c);
+                       ASTVec o;
+                       bool constant = true;
+                       for (ASTVec::iterator it = c.begin(), itend = c.end(); it != itend; it++)
+                       {
+                               ASTNode aaa = SimplifyTerm(*it);
+                               if (BVCONST != aaa.GetKind())
+                               {
+                                       constant = false;
+                               }
+
+                               if (aaa == annihilator)
+                               {
+                                       output = annihilator;
+                                       return output;
+                               }
+
+                               if (aaa != identity)
+                               {
+                                       o.push_back(aaa);
+                               }
+                       }
+
+                       switch (o.size())
+                       {
+                               case 0:
+                                       output = identity;
+                                       break;
+                               case 1:
+                                       output = o[0];
+                                       break;
+                               default:
+                                       SortByArith(o);
+                                       output = CreateTerm(k, inputValueWidth, o);
+                                       if (constant)
+                                       {
+                                               output = BVConstEvaluator(output);
+                                       }
+                                       break;
+                       }
+                       break;
+               }
+               case BVCONCAT:
+               {
+                       ASTNode t = SimplifyTerm(inputterm[0]);
+                       ASTNode u = SimplifyTerm(inputterm[1]);
+                       Kind tkind = t.GetKind();
+                       Kind ukind = u.GetKind();
+
+                       if (BVCONST == tkind && BVCONST == ukind)
+                       {
+                               output = BVConstEvaluator(CreateTerm(BVCONCAT, inputValueWidth, t, u));
+                       }
+                       else if (BVEXTRACT == tkind && BVEXTRACT == ukind && t[0] == u[0])
+                       {
+                               //to handle the case x[m:n]@x[n-1:k] <==> x[m:k]
+                               ASTNode t_hi = t[1];
+                               ASTNode t_low = t[2];
+                               ASTNode u_hi = u[1];
+                               ASTNode u_low = u[2];
+                               ASTNode c = BVConstEvaluator(CreateTerm(BVPLUS, 32, u_hi, CreateOneConst(32)));
+                               if (t_low == c)
+                               {
+                                       output = CreateTerm(BVEXTRACT, inputValueWidth, t[0], t_hi, u_low);
+                               }
+                               else
+                               {
+                                       output = CreateTerm(BVCONCAT, inputValueWidth, t, u);
+                               }
+                       }
+                       else
+                       {
+                               output = CreateTerm(BVCONCAT, inputValueWidth, t, u);
+                       }
+                       break;
+               }
+               case BVXOR:
+               case BVXNOR:
+               case BVNAND:
+               case BVNOR:
+               case BVLEFTSHIFT:
+               case BVRIGHTSHIFT:
+               case BVVARSHIFT:
+               case BVSRSHIFT:
+               case BVDIV:
+               case BVMOD:
+               {
+                       ASTVec c = inputterm.GetChildren();
+                       ASTVec o;
+                       bool constant = true;
+                       for (ASTVec::iterator it = c.begin(), itend = c.end(); it != itend; it++)
+                       {
+                               ASTNode aaa = SimplifyTerm(*it);
+                               if (BVCONST != aaa.GetKind())
+                               {
+                                       constant = false;
+                               }
+                               o.push_back(aaa);
+                       }
+                       output = CreateTerm(k, inputValueWidth, o);
+                       if (constant)
+                               output = BVConstEvaluator(output);
+                       break;
+               }
+               case READ:
+               {
+                       ASTNode out1;
+                       //process only if not  in the substitution map. simplifymap
+                       //has been checked already
+                       if (!CheckSubstitutionMap(inputterm, out1))
+                       {
+                               if (WRITE == inputterm[0].GetKind())
+                               {
+                                       //get rid of all writes
+                                       ASTNode nowrites = RemoveWrites_TopLevel(inputterm);
+                                       out1 = nowrites;
+                               }
+                               else if (ITE == inputterm[0].GetKind())
+                               {
+                                       ASTNode cond = SimplifyFormula(inputterm[0][0], false);
+                                       ASTNode index = SimplifyTerm(inputterm[1]);
+
+                                       ASTNode read1 = CreateTerm(READ, inputValueWidth, inputterm[0][1], index);
+                                       ASTNode read2 = CreateTerm(READ, inputValueWidth, inputterm[0][2], index);
+
+                                       read1 = SimplifyTerm(read1);
+                                       read2 = SimplifyTerm(read2);
+                                       out1 = CreateSimplifiedTermITE(cond, read1, read2);
+                               }
+                               else
+                               {
+                                       //arr is a SYMBOL for sure
+                                       ASTNode arr = inputterm[0];
+                                       ASTNode index = SimplifyTerm(inputterm[1]);
+                                       out1 = CreateTerm(READ, inputValueWidth, arr, index);
+                               }
+                       }
+                       //it is possible that after all the procesing the READ term
+                       //reduces to READ(Symbol,const) and hence we should check the
+                       //substitutionmap once again.
+                       if (!CheckSubstitutionMap(out1, output))
+                               output = out1;
+                       break;
+               }
+               case ITE:
+               {
+                       ASTNode t0 = SimplifyFormula(inputterm[0], false);
+                       ASTNode t1 = SimplifyTerm(inputterm[1]);
+                       ASTNode t2 = SimplifyTerm(inputterm[2]);
+                       output = CreateSimplifiedTermITE(t0, t1, t2);
+                       break;
+               }
+               case SBVREM:
+               case SBVMOD:
+               case SBVDIV:
+               {
+                       ASTVec c = inputterm.GetChildren();
+                       ASTVec o;
+                       for (ASTVec::iterator it = c.begin(), itend = c.end(); it != itend; it++)
+                       {
+                               ASTNode aaa = SimplifyTerm(*it);
+                               o.push_back(aaa);
+                       }
+                       output = CreateTerm(k, inputValueWidth, o);
+                       break;
+               }
+               case WRITE:
+               default:
+                       FatalError("SimplifyTermAux: Control should never reach here:", inputterm, k);
+                       return inputterm;
+                       break;
+       }
+
+       return output;
+}
+
+//At the end of each simplification call, we want the output to be
+//always smaller or equal to the input in size.
+void BeevMgr::CheckSimplifyInvariant(const ASTNode& a, const ASTNode& output)
+{
+
+       if (NodeSize(a, true) + 1 < NodeSize(output, true))
+       {
+               cerr << "lhs := " << a << endl;
+               cerr << "NodeSize of lhs is: " << NodeSize(a, true) << endl;
+               cerr << endl;
+               cerr << "rhs := " << output << endl;
+               cerr << "NodeSize of rhs is: " << NodeSize(output, true) << endl;
+               //  FatalError("SimplifyFormula: The nodesize shoudl decrease from lhs to rhs: ",ASTUndefined);
+       }
+}
+
+//this function assumes that the input is a vector of childnodes of
+//a BVPLUS term. it combines like terms and returns a bvplus
+//term. e.g. 1.x + 2.x is converted to 3.x
+ASTNode BeevMgr::CombineLikeTerms(const ASTNode& a)
+{
+       if (BVPLUS != a.GetKind())
+               return a;
+
+       ASTNode output;
+       if (CheckSimplifyMap(a, output, false))
+       {
+               //check memo table
+               //cerr << "output of SimplifyTerm Cache: " << output << endl;
+               return output;
+       }
+
+       const ASTVec& c = a.GetChildren();
+       //map from variables to vector of constants
+       ASTNodeToVecMap vars_to_consts;
+       //vector to hold constants
+       ASTVec constkids;
+       ASTVec outputvec;
+
+       //useful constants
+       unsigned int len = c[0].GetValueWidth();
+       ASTNode one = CreateOneConst(len);
+       ASTNode zero = CreateZeroConst(len);
+       ASTNode max = CreateMaxConst(len);
+
+       //go over the childnodes of the input bvplus, and collect like
+       //terms in a map. the key of the map are the variables, and the
+       //values are stored in a ASTVec
+       for (ASTVec::const_iterator it = c.begin(), itend = c.end(); it != itend; it++)
+       {
+               ASTNode aaa = *it;
+               if (SYMBOL == aaa.GetKind())
+               {
+                       vars_to_consts[aaa].push_back(one);
+               }
+               else if (BVMULT == aaa.GetKind() && BVUMINUS == aaa[0].GetKind() && BVCONST == aaa[0][0].GetKind())
+               {
+                       //(BVUMINUS(c))*(y) <==> compute(BVUMINUS(c))*y
+                       ASTNode compute_const = BVConstEvaluator(aaa[0]);
+                       vars_to_consts[aaa[1]].push_back(compute_const);
+               }
+               else if (BVMULT == aaa.GetKind() && BVUMINUS == aaa[1].GetKind() && BVCONST == aaa[0].GetKind())
+               {
+                       //c*(BVUMINUS(y)) <==> compute(BVUMINUS(c))*y
+                       ASTNode cccc = BVConstEvaluator(CreateTerm(BVUMINUS, len, aaa[0]));
+                       vars_to_consts[aaa[1][0]].push_back(cccc);
+               }
+               else if (BVMULT == aaa.GetKind() && BVCONST == aaa[0].GetKind())
+               {
+                       //assumes that BVMULT is binary
+                       vars_to_consts[aaa[1]].push_back(aaa[0]);
+               }
+               else if (BVMULT == aaa.GetKind() && BVUMINUS == aaa[0].GetKind())
+               {
+                       //(-1*x)*(y) <==> -1*(xy)
+                       ASTNode cccc = CreateTerm(BVMULT, len, aaa[0][0], aaa[1]);
+                       ASTVec cNodes = cccc.GetChildren();
+                       SortByArith(cNodes);
+                       vars_to_consts[cccc].push_back(max);
+               }
+               else if (BVMULT == aaa.GetKind() && BVUMINUS == aaa[1].GetKind())
+               {
+                       //x*(-1*y) <==> -1*(xy)
+                       ASTNode cccc = CreateTerm(BVMULT, len, aaa[0], aaa[1][0]);
+                       ASTVec cNodes = cccc.GetChildren();
+                       SortByArith(cNodes);
+                       vars_to_consts[cccc].push_back(max);
+               }
+               else if (BVCONST == aaa.GetKind())
+               {
+                       constkids.push_back(aaa);
+               }
+               else if (BVUMINUS == aaa.GetKind())
+               {
+                       //helps to convert BVUMINUS into a BVMULT. here the max
+                       //constant represents -1. this transformation allows us to
+                       //conclude that x + BVUMINUS(x) is 0.
+                       vars_to_consts[aaa[0]].push_back(max);
+               }
+               else
+                       vars_to_consts[aaa].push_back(one);
+       } //end of for loop
+
+       //go over the map from variables to vector of values. combine the
+       //vector of values, multiply to the variable, and put the
+       //resultant monomial in the output BVPLUS.
+       for (ASTNodeToVecMap::iterator it = vars_to_consts.begin(), itend = vars_to_consts.end(); it != itend; it++)
+       {
+               ASTVec ccc = it->second;
+
+               ASTNode constant;
+               if (1 < ccc.size())
+               {
+                       constant = CreateTerm(BVPLUS, ccc[0].GetValueWidth(), ccc);
+                       constant = BVConstEvaluator(constant);
+               }
+               else
+                       constant = ccc[0];
+
+               //constant * var
+               ASTNode monom;
+               if (zero == constant)
+                       monom = zero;
+               else if (one == constant)
+                       monom = it->first;
+               else
+               {
+                       monom = SimplifyTerm(CreateTerm(BVMULT, constant.GetValueWidth(), constant, it->first));
+               }
+               if (zero != monom)
+               {
+                       outputvec.push_back(monom);
+               }
+       } //end of for loop
+
+       if (constkids.size() > 1)
+       {
+               ASTNode output = CreateTerm(BVPLUS, constkids[0].GetValueWidth(), constkids);
+               output = BVConstEvaluator(output);
+               if (output != zero)
+                       outputvec.push_back(output);
+       }
+       else if (constkids.size() == 1)
+       {
+               if (constkids[0] != zero)
+                       outputvec.push_back(constkids[0]);
+       }
+
+       if (outputvec.size() > 1)
+       {
+               output = CreateTerm(BVPLUS, len, outputvec);
+       }
+       else if (outputvec.size() == 1)
+       {
+               output = outputvec[0];
+       }
+       else
+       {
+               output = zero;
+       }
+
+       //memoize
+       //UpdateSimplifyMap(a,output,false);
+       return output;
+} //end of CombineLikeTerms()
+
+//accepts lhs and rhs, and returns lhs - rhs = 0. The function
+//assumes that lhs and rhs have already been simplified. although
+//this assumption is not needed for correctness, it is essential for
+//performance. The function also assumes that lhs is a BVPLUS
+ASTNode BeevMgr::LhsMinusRhs(const ASTNode& eq)
+{
+       //if input is not an equality, simply return it
+       if (EQ != eq.GetKind())
+               return eq;
+
+       ASTNode lhs = eq[0];
+       ASTNode rhs = eq[1];
+       Kind k_lhs = lhs.GetKind();
+       Kind k_rhs = rhs.GetKind();
+       //either the lhs has to be a BVPLUS or the rhs has to be a
+       //BVPLUS
+       if (!(BVPLUS == k_lhs || BVPLUS == k_rhs || (BVMULT == k_lhs && BVMULT == k_rhs)))
+       {
+               return eq;
+       }
+
+       ASTNode output;
+       if (CheckSimplifyMap(eq, output, false))
+       {
+               //check memo table
+               //cerr << "output of SimplifyTerm Cache: " << output << endl;
+               return output;
+       }
+
+       //if the lhs is not a BVPLUS, but the rhs is a BVPLUS, then swap
+       //the lhs and rhs
+       bool swap_flag = false;
+       if (BVPLUS != k_lhs && BVPLUS == k_rhs)
+       {
+               ASTNode swap = lhs;
+               lhs = rhs;
+               rhs = swap;
+               swap_flag = true;
+       }
+
+       unsigned int len = lhs.GetValueWidth();
+       ASTNode zero = CreateZeroConst(len);
+       //right is -1*(rhs): Simplify(-1*rhs)
+       rhs = SimplifyTerm(CreateTerm(BVUMINUS, len, rhs));
+
+       ASTVec lvec = lhs.GetChildren();
+       ASTVec rvec = rhs.GetChildren();
+       ASTNode lhsplusrhs;
+       if (BVPLUS != lhs.GetKind() && BVPLUS != rhs.GetKind())
+       {
+               lhsplusrhs = CreateTerm(BVPLUS, len, lhs, rhs);
+       }
+       else if (BVPLUS == lhs.GetKind() && BVPLUS == rhs.GetKind())
+       {
+               //combine the childnodes of the left and the right
+               lvec.insert(lvec.end(), rvec.begin(), rvec.end());
+               lhsplusrhs = CreateTerm(BVPLUS, len, lvec);
+       }
+       else if (BVPLUS == lhs.GetKind() && BVPLUS != rhs.GetKind())
+       {
+               lvec.push_back(rhs);
+               lhsplusrhs = CreateTerm(BVPLUS, len, lvec);
+       }
+       else
+       {
+               //Control should never reach here
+               FatalError("LhsMinusRhs: Control should never reach here\n");
+       }
+
+       //combine like terms
+       output = CombineLikeTerms(lhsplusrhs);
+       output = SimplifyTerm(output);
+       //
+       //Now make output into: lhs-rhs = 0
+       output = CreateSimplifiedEQ(output, zero);
+       //sort if BVPLUS
+       if (BVPLUS == output.GetKind())
+       {
+               ASTVec outv = output.GetChildren();
+               SortByArith(outv);
+               output = CreateTerm(BVPLUS, len, outv);
+       }
+
+       //memoize
+       //UpdateSimplifyMap(eq,output,false);
+       return output;
+} //end of LhsMinusRHS()
+
+//THis function accepts a BVMULT(t1,t2) and distributes the mult
+//over plus if either or both t1 and t2 are BVPLUSes.
+//
+// x*(y1 + y2 + ...+ yn) <==> x*y1 + x*y2 + ... + x*yn
+//
+// (y1 + y2 + ...+ yn)*x <==> x*y1 + x*y2 + ... + x*yn
+//
+// The function assumes that the BVPLUSes have been flattened
+ASTNode BeevMgr::DistributeMultOverPlus(const ASTNode& a, bool startdistribution)
+{
+       if (!startdistribution)
+               return a;
+       Kind k = a.GetKind();
+       if (BVMULT != k)
+               return a;
+
+       ASTNode left = a[0];
+       ASTNode right = a[1];
+       Kind left_kind = left.GetKind();
+       Kind right_kind = right.GetKind();
+
+       ASTNode output;
+       if (CheckSimplifyMap(a, output, false))
+       {
+               //check memo table
+               //cerr << "output of SimplifyTerm Cache: " << output << endl;
+               return output;
+       }
+
+       //special case optimization: c1*(c2*t1) <==> (c1*c2)*t1
+       if (BVCONST == left_kind && BVMULT == right_kind && BVCONST == right[0].GetKind())
+       {
+               ASTNode c = BVConstEvaluator(CreateTerm(BVMULT, a.GetValueWidth(), left, right[0]));
+               c = CreateTerm(BVMULT, a.GetValueWidth(), c, right[1]);
+               return c;
+               left = c[0];
+               right = c[1];
+               left_kind = left.GetKind();
+               right_kind = right.GetKind();
+       }
+
+       //special case optimization: c1*(t1*c2) <==> (c1*c2)*t1
+       if (BVCONST == left_kind && BVMULT == right_kind && BVCONST == right[1].GetKind())
+       {
+               ASTNode c = BVConstEvaluator(CreateTerm(BVMULT, a.GetValueWidth(), left, right[1]));
+               c = CreateTerm(BVMULT, a.GetValueWidth(), c, right[0]);
+               return c;
+               left = c[0];
+               right = c[1];
+               left_kind = left.GetKind();
+               right_kind = right.GetKind();
+       }
+
+       //atleast one of left or right have to be BVPLUS
+       if (!(BVPLUS == left_kind || BVPLUS == right_kind))
+       {
+               return a;
+       }
+
+       //if left is BVPLUS and right is not, then swap left and right. we
+       //can do this since BVMULT is communtative
+       ASTNode swap;
+       if (BVPLUS == left_kind && BVPLUS != right_kind)
+       {
+               swap = left;
+               left = right;
+               right = swap;
+       }
+       left_kind = left.GetKind();
+       right_kind = right.GetKind();
+
+       //by this point we are gauranteed that right is a BVPLUS, but left
+       //may not be
+       ASTVec rightnodes = right.GetChildren();
+       ASTVec outputvec;
+       unsigned len = a.GetValueWidth();
+       ASTNode zero = CreateZeroConst(len);
+       ASTNode one = CreateOneConst(len);
+       if (BVPLUS != left_kind)
+       {
+               //if the multiplier is not a BVPLUS then we have a special case
+               // x*(y1 + y2 + ...+ yn) <==> x*y1 + x*y2 + ... + x*yn
+               if (zero == left)
+               {
+                       outputvec.push_back(zero);
+               }
+               else if (one == left)
+               {
+                       outputvec.push_back(left);
+               }
+               else
+               {
+                       for (ASTVec::iterator j = rightnodes.begin(), jend = rightnodes.end(); j != jend; j++)
+                       {
+                               ASTNode out = SimplifyTerm(CreateTerm(BVMULT, len, left, *j));
+                               outputvec.push_back(out);
+                       }
+               }
+       }
+       else
+       {
+               ASTVec leftnodes = left.GetChildren();
+               // (x1 + x2 + ... + xm)*(y1 + y2 + ...+ yn) <==> x1*y1 + x1*y2 +
+               // ... + x2*y1 + ... + xm*yn
+               for (ASTVec::iterator i = leftnodes.begin(), iend = leftnodes.end(); i != iend; i++)
+               {
+                       ASTNode multiplier = *i;
+                       for (ASTVec::iterator j = rightnodes.begin(), jend = rightnodes.end(); j != jend; j++)
+                       {
+                               ASTNode out = SimplifyTerm(CreateTerm(BVMULT, len, multiplier, *j));
+                               outputvec.push_back(out);
+                       }
+               }
+       }
+
+       //compute output here
+       if (outputvec.size() > 1)
+       {
+               output = CombineLikeTerms(CreateTerm(BVPLUS, len, outputvec));
+               output = SimplifyTerm(output);
+       }
+       else
+               output = SimplifyTerm(outputvec[0]);
+
+       //memoize
+       //UpdateSimplifyMap(a,output,false);
+       return output;
+} //end of distributemultoverplus()
+
+//converts the BVSX(len, a0) operator into ITE( check top bit,
+//extend a0 by 1, extend a0 by 0)
+ASTNode BeevMgr::ConvertBVSXToITE(const ASTNode& a)
+{
+       if (BVSX != a.GetKind())
+               return a;
+
+       ASTNode output;
+       if (CheckSimplifyMap(a, output, false))
+       {
+               //check memo table
+               //cerr << "output of ConvertBVSXToITE Cache: " << output << endl;
+               return output;
+       }
+
+       ASTNode a0 = a[0];
+       unsigned a_len = a.GetValueWidth();
+       unsigned a0_len = a0.GetValueWidth();
+
+       if (a0_len > a_len)
+       {
+               FatalError("Trying to sign_extend a larger BV into a smaller BV");
+               return ASTUndefined; //to stop the compiler from producing bogus warnings
+       }
+
+       //sign extend
+       unsigned extensionlen = a_len - a0_len;
+       if (0 == extensionlen)
+       {
+               UpdateSimplifyMap(a, output, false);
+               return a;
+       }
+
+       std::string ones;
+       for (unsigned c = 0; c < extensionlen; c++)
+               ones += '1';
+       std::string zeros;
+       for (unsigned c = 0; c < extensionlen; c++)
+               zeros += '0';
+
+       //string of oness of length extensionlen
+       BEEV::ASTNode BVOnes = CreateBVConst(ones.c_str(), 2);
+       //string of zeros of length extensionlen
+       BEEV::ASTNode BVZeros = CreateBVConst(zeros.c_str(), 2);
+
+       //string of ones BVCONCAT a0
+       BEEV::ASTNode concatOnes = CreateTerm(BEEV::BVCONCAT, a_len, BVOnes, a0);
+       //string of zeros BVCONCAT a0
+       BEEV::ASTNode concatZeros = CreateTerm(BEEV::BVCONCAT, a_len, BVZeros, a0);
+
+       //extract top bit of a0
+       BEEV::ASTNode hi = CreateBVConst(32, a0_len - 1);
+       BEEV::ASTNode low = CreateBVConst(32, a0_len - 1);
+       BEEV::ASTNode topBit = CreateTerm(BEEV::BVEXTRACT, 1, a0, hi, low);
+
+       //compare topBit of a0 with 0bin1
+       BEEV::ASTNode condition = CreateSimplifiedEQ(CreateBVConst(1, 1), topBit);
+
+       //ITE(topbit = 0bin1, 0bin1111...a0, 0bin000...a0)
+       output = CreateSimplifiedTermITE(condition, concatOnes, concatZeros);
+       UpdateSimplifyMap(a, output, false);
+       return output;
+} //end of ConvertBVSXToITE()
+
+
+ASTNode BeevMgr::RemoveWrites_TopLevel(const ASTNode& term)
+{
+       if (READ != term.GetKind() && WRITE != term[0].GetKind())
+       {
+               FatalError("RemovesWrites: Input must be a READ over a WRITE", term);
+       }
+
+       if (!Begin_RemoveWrites && !SimplifyWrites_InPlace_Flag && !start_abstracting)
+       {
+               return term;
+       }
+       else if (!Begin_RemoveWrites && SimplifyWrites_InPlace_Flag && !start_abstracting)
+       {
+               //return term;
+               return SimplifyWrites_InPlace(term);
+       }
+       else
+       {
+               return RemoveWrites(term);
+       }
+} //end of RemoveWrites_TopLevel()
+
+ASTNode BeevMgr::SimplifyWrites_InPlace(const ASTNode& term)
+{
+       ASTNodeMultiSet WriteIndicesSeenSoFar;
+       bool SeenNonConstWriteIndex = false;
+
+       if (READ != term.GetKind() && WRITE != term[0].GetKind())
+       {
+               FatalError("RemovesWrites: Input must be a READ over a WRITE", term);
+       }
+
+       ASTNode output;
+       if (CheckSimplifyMap(term, output, false))
+       {
+               return output;
+       }
+
+       ASTVec writeIndices, writeValues;
+       unsigned int width = term.GetValueWidth();
+       ASTNode write = term[0];
+       unsigned indexwidth = write.GetIndexWidth();
+       ASTNode readIndex = SimplifyTerm(term[1]);
+
+       do
+       {
+               ASTNode writeIndex = SimplifyTerm(write[1]);
+               ASTNode writeVal = SimplifyTerm(write[2]);
+
+               //compare the readIndex and the current writeIndex and see if they
+               //simplify to TRUE or FALSE or UNDETERMINABLE at this stage
+               ASTNode compare_readwrite_indices = SimplifyFormula(CreateSimplifiedEQ(writeIndex, readIndex), false);
+
+               //if readIndex and writeIndex are equal
+               if (ASTTrue == compare_readwrite_indices && !SeenNonConstWriteIndex)
+               {
+                       UpdateSimplifyMap(term, writeVal, false);
+                       return writeVal;
+               }
+
+               if (!(ASTTrue == compare_readwrite_indices || ASTFalse == compare_readwrite_indices))
+               {
+                       SeenNonConstWriteIndex = true;
+               }
+
+               //if (readIndex=writeIndex <=> FALSE)
+               if (ASTFalse == compare_readwrite_indices || (WriteIndicesSeenSoFar.find(writeIndex) != WriteIndicesSeenSoFar.end()))
+               {
+                       //drop the current level write
+                       //do nothing
+               }
+               else
+               {
+                       writeIndices.push_back(writeIndex);
+                       writeValues.push_back(writeVal);
+               }
+
+               //record the write indices seen so far
+               //if(BVCONST == writeIndex.GetKind()) {
+               WriteIndicesSeenSoFar.insert(writeIndex);
+               //}
+
+               //Setup the write for the new iteration, one level inner write
+               write = write[0];
+       } while (SYMBOL != write.GetKind());
+
+       ASTVec::reverse_iterator it_index = writeIndices.rbegin();
+       ASTVec::reverse_iterator itend_index = writeIndices.rend();
+       ASTVec::reverse_iterator it_values = writeValues.rbegin();
+       ASTVec::reverse_iterator itend_values = writeValues.rend();
+
+       //"write" must be a symbol at the control point before the
+       //begining of the "for loop"
+
+       for (; it_index != itend_index; it_index++, it_values++)
+       {
+               write = CreateTerm(WRITE, width, write, *it_index, *it_values);
+               write.SetIndexWidth(indexwidth);
+       }
+
+       output = CreateTerm(READ, width, write, readIndex);
+       UpdateSimplifyMap(term, output, false);
+       return output;
+} //end of SimplifyWrites_In_Place()
+
+//accepts a read over a write and returns a term without the write
+//READ(WRITE(A i val) j) <==> ITE(i=j,val,READ(A,j)). We use a memo
+//table for this function called RemoveWritesMemoMap
+ASTNode BeevMgr::RemoveWrites(const ASTNode& input)
+{
+       //unsigned int width = input.GetValueWidth();
+       if (READ != input.GetKind() || WRITE != input[0].GetKind())
+       {
+               FatalError("RemovesWrites: Input must be a READ over a WRITE", input);
+       }
+
+       ASTNodeMap::iterator it;
+       ASTNode output = input;
+       if (CheckSimplifyMap(input, output, false))
+       {
+               return output;
+       }
+
+       if (!start_abstracting && Begin_RemoveWrites)
+       {
+               output = ReadOverWrite_To_ITE(input);
+       }
+
+       if (start_abstracting)
+       {
+               ASTNode newVar;
+               if (!CheckSimplifyMap(input, newVar, false))
+               {
+                       newVar = NewVar(input.GetValueWidth());
+                       ReadOverWrite_NewName_Map[input] = newVar;
+                       NewName_ReadOverWrite_Map[newVar] = input;
+
+                       UpdateSimplifyMap(input, newVar, false);
+                       ASTNodeStats("New Var Name which replace Read_Over_Write: ", newVar);
+               }
+               output = newVar;
+       } //end of start_abstracting if condition
+
+       //memoize
+       UpdateSimplifyMap(input, output, false);
+       return output;
+} //end of RemoveWrites()
+
+ASTNode BeevMgr::ReadOverWrite_To_ITE(const ASTNode& term)
+{
+       unsigned int width = term.GetValueWidth();
+       ASTNode input = term;
+       if (READ != term.GetKind() || WRITE != term[0].GetKind())
+       {
+               FatalError("RemovesWrites: Input must be a READ over a WRITE", term);
+       }
+
+       ASTNodeMap::iterator it;
+       ASTNode output;
+       // if(CheckSimplifyMap(term,output,false)) {
+       //       return output;
+       //     }
+
+       ASTNode partialITE = term;
+       ASTNode writeA = ASTTrue;
+       ASTNode oldRead = term;
+       //iteratively expand read-over-write
+       do
+       {
+               ASTNode write = input[0];
+               ASTNode readIndex = SimplifyTerm(input[1]);
+               //DO NOT CALL SimplifyTerm() on write[0]. You will go into an
+               //infinite loop
+               writeA = write[0];
+               ASTNode writeIndex = SimplifyTerm(write[1]);
+               ASTNode writeVal = SimplifyTerm(write[2]);
+
+               ASTNode cond = SimplifyFormula(CreateSimplifiedEQ(writeIndex, readIndex), false);
+               ASTNode newRead = CreateTerm(READ, width, writeA, readIndex);
+               ASTNode newRead_memoized = newRead;
+               if (CheckSimplifyMap(newRead, newRead_memoized, false))
+               {
+                       newRead = newRead_memoized;
+               }
+
+               if (ASTTrue == cond && (term == partialITE))
+               {
+                       //found the write-value in the first iteration itself. return
+                       //it
+                       output = writeVal;
+                       UpdateSimplifyMap(term, output, false);
+                       return output;
+               }
+
+               if (READ == partialITE.GetKind() && WRITE == partialITE[0].GetKind())
+               {
+                       //first iteration or (previous cond==ASTFALSE and partialITE is a "READ over WRITE")
+                       partialITE = CreateSimplifiedTermITE(cond, writeVal, newRead);
+               }
+               else if (ITE == partialITE.GetKind())
+               {
+                       //ITE(i1 = j, v1, R(A,j))
+                       ASTNode ElseITE = CreateSimplifiedTermITE(cond, writeVal, newRead);
+                       //R(W(A,i1,v1),j) <==> ITE(i1 = j, v1, R(A,j))
+                       UpdateSimplifyMap(oldRead, ElseITE, false);
+                       //ITE(i2 = j, v2, R(W(A,i1,v1),j)) <==> ITE(i2 = j, v2, ITE(i1 = j, v1, R(A,j)))
+                       partialITE = SimplifyTerm(partialITE);
+               }
+               else
+               {
+                       FatalError("RemoveWrites: Control should not reach here\n");
+               }
+
+               if (ASTTrue == cond)
+               {
+                       //no more iterations required
+                       output = partialITE;
+                       UpdateSimplifyMap(term, output, false);
+                       return output;
+               }
+
+               input = newRead;
+               oldRead = newRead;
+       } while (READ == input.GetKind() && WRITE == input[0].GetKind());
+
+       output = partialITE;
+
+       //memoize
+       //UpdateSimplifyMap(term,output,false);
+       return output;
+} //ReadOverWrite_To_ITE()
+
+//compute the multiplicative inverse of the input
+ASTNode BeevMgr::MultiplicativeInverse(const ASTNode& d)
+{
+       ASTNode c = d;
+       if (BVCONST != c.GetKind())
+       {
+               FatalError("Input must be a constant", c);
+       }
+
+       if (!BVConstIsOdd(c))
+       {
+               FatalError("MultiplicativeInverse: Input must be odd: ", c);
+       }
+
+       //cerr << "input to multinverse function is: " << d << endl;
+       ASTNode inverse;
+       if (CheckMultInverseMap(d, inverse))
+       {
+               //cerr << "found the inverse of: " << d << "and it is: " << inverse << endl;
+               return inverse;
+       }
+
+       inverse = c;
+       unsigned inputwidth = c.GetValueWidth();
+
+#ifdef NATIVE_C_ARITH
+       ASTNode one = CreateOneConst(inputwidth);
+       while(c != one)
+       {
+               //c = c*c
+               c = BVConstEvaluator(CreateTerm(BVMULT,inputwidth,c,c));
+               //inverse = invsere*c
+               inverse = BVConstEvaluator(CreateTerm(BVMULT,inputwidth,inverse,c));
+       }
+#else
+       //Compute the multiplicative inverse of c using the extended
+       //euclidian algorithm
+       //
+       //create a '0' which is 1 bit long
+       ASTNode onebit_zero = CreateZeroConst(1);
+       //zero pad t0, i.e. 0 @ t0
+       c = BVConstEvaluator(CreateTerm(BVCONCAT, inputwidth + 1, onebit_zero, c));
+
+       //construct 2^(inputwidth), i.e. a bitvector of length
+       //'inputwidth+1', which is max(inputwidth)+1
+       //
+       //all 1's
+       ASTNode max = CreateMaxConst(inputwidth);
+       //zero pad max
+       max = BVConstEvaluator(CreateTerm(BVCONCAT, inputwidth + 1, onebit_zero, max));
+       //Create a '1' which has leading zeros of length 'inputwidth'
+       ASTNode inputwidthplusone_one = CreateOneConst(inputwidth + 1);
+       //add 1 to max
+       max = CreateTerm(BVPLUS, inputwidth + 1, max, inputwidthplusone_one);
+       max = BVConstEvaluator(max);
+
+       ASTNode zero = CreateZeroConst(inputwidth + 1);
+       ASTNode max_bvgt_0 = CreateNode(BVGT, max, zero);
+       ASTNode quotient, remainder;
+       ASTNode x, x1, x2;
+
+       //x1 initialized to zero
+       x1 = zero;
+       //x2 initialized to one
+       x2 = CreateOneConst(inputwidth + 1);
+       while (ASTTrue == BVConstEvaluator(max_bvgt_0))
+       {
+               //quotient = (c divided by max)
+               quotient = BVConstEvaluator(CreateTerm(BVDIV, inputwidth + 1, c, max));
+
+               //remainder of (c divided by max)
+               remainder = BVConstEvaluator(CreateTerm(BVMOD, inputwidth + 1, c, max));
+
+               //x = x2 - q*x1
+               x = CreateTerm(BVSUB, inputwidth + 1, x2, CreateTerm(BVMULT, inputwidth + 1, quotient, x1));
+               x = BVConstEvaluator(x);
+
+               //fix the inputs to the extended euclidian algo
+               c = max;
+               max = remainder;
+               max_bvgt_0 = CreateNode(BVGT, max, zero);
+
+               x2 = x1;
+               x1 = x;
+       }
+
+       ASTNode hi = CreateBVConst(32, inputwidth - 1);
+       ASTNode low = CreateZeroConst(32);
+       inverse = CreateTerm(BVEXTRACT, inputwidth, x2, hi, low);
+       inverse = BVConstEvaluator(inverse);
+#endif
+
+       UpdateMultInverseMap(d, inverse);
+       //cerr << "output of multinverse function is: " << inverse << endl;
+       return inverse;
+} //end of MultiplicativeInverse()
+
+//returns true if the input is odd
+bool BeevMgr::BVConstIsOdd(const ASTNode& c)
+{
+       if (BVCONST != c.GetKind())
+       {
+               FatalError("Input must be a constant", c);
+       }
+
+       ASTNode zero = CreateZeroConst(1);
+       ASTNode hi = CreateZeroConst(32);
+       ASTNode low = hi;
+       ASTNode lowestbit = CreateTerm(BVEXTRACT, 1, c, hi, low);
+       lowestbit = BVConstEvaluator(lowestbit);
+
+       if (lowestbit == zero)
+       {
+               return false;
+       }
+       else
+       {
+               return true;
+       }
+} //end of BVConstIsOdd()
+
+//The big substitution function
+ASTNode BeevMgr::CreateSubstitutionMap(const ASTNode& a)
+{
+       if (!optimize)
+               return a;
+
+       ASTNode output = a;
+       //if the variable has been solved for, then simply return it
+       if (CheckSolverMap(a, output))
+               return output;
+
+       //traverse a and populate the SubstitutionMap
+       Kind k = a.GetKind();
+       if (SYMBOL == k && BOOLEAN_TYPE == a.GetType())
+       {
+               bool updated = UpdateSubstitutionMap(a, ASTTrue);
+               output = updated ? ASTTrue : a;
+               return output;
+       }
+       if (NOT == k && SYMBOL == a[0].GetKind())
+       {
+               bool updated = UpdateSubstitutionMap(a[0], ASTFalse);
+               output = updated ? ASTTrue : a;
+               return output;
+       }
+
+       if (IFF == k)
+       {
+               ASTVec c = a.GetChildren();
+               SortByArith(c);
+               if (SYMBOL != c[0].GetKind() || VarSeenInTerm(c[0], SimplifyFormula_NoRemoveWrites(c[1], false)))
+               {
+                       return a;
+               }
+               bool updated = UpdateSubstitutionMap(c[0], SimplifyFormula(c[1], false));
+               output = updated ? ASTTrue : a;
+               return output;
+       }
+
+       if (EQ == k)
+       {
+               //fill the arrayname readindices vector if e0 is a
+               //READ(Arr,index) and index is a BVCONST
+               ASTVec c = a.GetChildren();
+               SortByArith(c);
+               FillUp_ArrReadIndex_Vec(c[0], c[1]);
+
+               if (SYMBOL == c[0].GetKind() && VarSeenInTerm(c[0], SimplifyTermAux(c[1])))
+               {
+                       return a;
+               }
+
+               if (1 == TermOrder(c[0], c[1]) && READ == c[0].GetKind() && VarSeenInTerm(c[0][0], SimplifyTermAux(c[1])))
+               {
+                       return a;
+               }
+               bool updated = UpdateSubstitutionMap(c[0], SimplifyTermAux(c[1]));
+               output = updated ? ASTTrue : a;
+               return output;
+       }
+
+       if (AND == k)
+       {
+               ASTVec o;
+               ASTVec c = a.GetChildren();
+               for (ASTVec::iterator it = c.begin(), itend = c.end(); it != itend; it++)
+               {
+                       UpdateAlwaysTrueFormMap(*it);
+                       ASTNode aaa = CreateSubstitutionMap(*it);
+
+                       if (ASTTrue != aaa)
+                       {
+                               if (ASTFalse == aaa)
+                                       return ASTFalse;
+                               else
+                                       o.push_back(aaa);
+                       }
+               }
+               if (o.size() == 0)
+                       return ASTTrue;
+
+               if (o.size() == 1)
+                       return o[0];
+
+               return CreateNode(AND, o);
+       }
+
+       //printf("I gave up on kind: %d node: %d\n", k, a.GetNodeNum());
+       return output;
+} //end of CreateSubstitutionMap()
+
+
+bool BeevMgr::VarSeenInTerm(const ASTNode& var, const ASTNode& term)
+{
+       if (READ == term.GetKind() && WRITE == term[0].GetKind() && !Begin_RemoveWrites)
+       {
+               return false;
+       }
+
+       if (READ == term.GetKind() && WRITE == term[0].GetKind() && Begin_RemoveWrites)
+       {
+               return true;
+       }
+
+       ASTNodeMap::iterator it;
+       if ((it = TermsAlreadySeenMap.find(term)) != TermsAlreadySeenMap.end())
+       {
+               if (it->second == var)
+               {
+                       return false;
+               }
+       }
+
+       if (var == term)
+       {
+               return true;
+       }
+
+       for (ASTVec::const_iterator it = term.begin(), itend = term.end(); it != itend; it++)
+       {
+               if (VarSeenInTerm(var, *it))
+               {
+                       return true;
+               }
+               else
+               {
+                       TermsAlreadySeenMap[*it] = var;
+               }
+       }
+
+       TermsAlreadySeenMap[term] = var;
+       return false;
+}
+
+// in ext/hash_map, and tr/unordered_map, there is no provision to shrink down
+// the number of buckets in a hash map. If the hash_map has previously held a
+// lot of data, then it will have  a lot of buckets. Slowing down iterators and
+// clears() in particular.
+void BeevMgr::ResetSimplifyMaps()
+{
+       delete SimplifyMap;
+       SimplifyMap = new ASTNodeMap(INITIAL_SIMPLIFY_MAP_SIZE);
+
+       delete SimplifyNegMap;
+       SimplifyNegMap = new ASTNodeMap(INITIAL_SIMPLIFY_MAP_SIZE);
+}
+
+}
+;//end of namespace