]> git.unchartedbackwaters.co.uk Git - francis/stp.git/commitdiff
added scripts to do emacs formatting
authorvijay_ganesh <vijay_ganesh@e59a4935-1847-0410-ae03-e826735625c1>
Thu, 3 Sep 2009 19:22:47 +0000 (19:22 +0000)
committervijay_ganesh <vijay_ganesh@e59a4935-1847-0410-ae03-e826735625c1>
Thu, 3 Sep 2009 19:22:47 +0000 (19:22 +0000)
git-svn-id: https://stp-fast-prover.svn.sourceforge.net/svnroot/stp-fast-prover/trunk/stp@174 e59a4935-1847-0410-ae03-e826735625c1

26 files changed:
scripts/emacs-format-file [new file with mode: 0644]
scripts/emacs-format.sh [new file with mode: 0755]
src/AST/AST.cpp
src/AST/AST.h
src/AST/ASTUtil.cpp
src/AST/ASTUtil.h
src/AST/AbstractionRefinement.cpp
src/AST/BitBlast.cpp
src/AST/SimpBool.cpp
src/AST/ToCNF.cpp
src/AST/ToSAT.cpp
src/AST/Transform.cpp
src/AST/asttest.cpp
src/AST/bbtest.cpp
src/AST/cnftest.cpp
src/bitvec/consteval.cpp
src/c_interface/c_interface.cpp
src/c_interface/c_interface.h
src/c_interface/fdstream.h
src/constantbv/constantbv.cpp
src/constantbv/constantbv.h
src/parser/let-funcs.cpp
src/parser/main.cpp
src/simplifier/bvsolver.cpp
src/simplifier/bvsolver.h
src/simplifier/simplifier.cpp

diff --git a/scripts/emacs-format-file b/scripts/emacs-format-file
new file mode 100644 (file)
index 0000000..ba8754f
--- /dev/null
@@ -0,0 +1,11 @@
+;;; File: emacs-format-file
+;;; Stan Warford
+;;; 17 May 2006
+
+(defun emacs-format-function ()
+   "Format the whole buffer."
+      (c-set-style "gnu")
+         (indent-region (point-min) (point-max) nil)
+           (untabify (point-min) (point-max))
+              (save-buffer)
+)
diff --git a/scripts/emacs-format.sh b/scripts/emacs-format.sh
new file mode 100755 (executable)
index 0000000..7a5a6fa
--- /dev/null
@@ -0,0 +1,36 @@
+#!/bin/sh
+# File: my-indent
+# Opens a set of files in emacs and executes the emacs-format-function.
+# Assumes the function named emacs-format-function is defined in the
+# file named emacs-format-file.
+
+loadpath=`pwd`
+if [ $# == 0 ]
+then
+   echo "my-indent requires at least one argument." 1>&2
+      echo "Usage: my-indent files-to-indent" 1>&2
+         exit 1
+fi
+
+while [ $# -ge 1 ]
+do
+ if [ -d $1 ]
+ then
+   echo "Argument of my-indent $1 cannot be a directory." 1>&2
+   exit 1
+ fi
+
+ # Check for existence of file:
+ ls $1 2> /dev/null | grep $1 > /dev/null
+ if [ $? != 0 ]
+ then
+   echo "my-indent: $1 not found." 1>&2
+   exit 1
+ fi
+ echo "Indenting $1 with emacs in batch mode"
+ emacs -batch $1 -l $loadpath/scripts/emacs-format-file -f emacs-format-function
+ echo
+ shift 1
+done
+exit 0
+
index 4ecef9dbaf18e4699208eea92d936316cb68013e..7ecd09c5dd79a2272ceeba94ce0dcfcc7e816b63 100644 (file)
 
 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_flag = false;
-//print DAG nodes
-bool print_nodes_flag = false;
-//run STP in optimized mode
-bool optimize_flag = 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_flag = true;
-//flag to control write refinement
-bool arraywrite_refinement_flag = true;
-//check the counterexample against the original input to STP
-bool check_counterexample_flag = false;
-//construct the counterexample in terms of original variable based
-//on the counterexample returned by SAT solver
-bool construct_counterexample_flag = true;
-bool print_counterexample_flag = false;
-bool print_binary_flag = 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_flag = false;
-//flag to decide whether to print "valid/invalid" or not
-bool print_output_flag = false;
-//print the variable order chosen by the sat solver while it is
-//solving.
-bool print_sat_varorder_flag = false;
-//turn on word level bitvector solver
-bool wordlevel_solve_flag = true;
-//turn off XOR flattening
-bool xor_flatten_flag = false;
-//Flag to switch on the smtlib parser
-bool smtlib_parser_flag = false;
-//print the input back
-bool print_STPinput_back_flag = false;
-
-// If enabled. division, mod and remainder by zero will evaluate to 1.
-bool division_by_zero_returns_one = false;
-
-enum 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);
-       }
-}
-
-
-
-//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()
-
-
-
-////////////////////////////////////////////////////////////////
-//  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;
-}
-
-//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
-
-       int shift_amount = (sizeof(unsigned long) << 3);
-       while (copied + (sizeof(unsigned long) << 3) < width)
-       {
-               CONSTANTBV::BitVector_Chunk_Store(bv, shift_amount, copied, c_val);
-               bvconst = bvconst >> shift_amount;
-               c_val = (~((unsigned long) 0)) & bvconst;
-               copied += shift_amount;
-       }
-       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();
-}
-
-// 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)
-{
-       if (n._int_node_ptr)
-       {
-               n._int_node_ptr->IncRef();
-       }
-}
-
-// If there is a lot of sharing in the graph, this will take a long
-// time.  it doesn't mark subgraphs as already having been
-// typechecked.
-bool BeevMgr::BVTypeCheckRecursive(const ASTNode& n)
-{
-       const ASTVec& c = n.GetChildren();
-
-       BVTypeCheck(n);
-
-       for (ASTVec::const_iterator it = c.begin(), itend = c.end(); it != itend; it++)
-               BVTypeCheckRecursive(*it);
-
-       return true;
-}
-
-
-
-/* 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.
- *
- * If this returns, this ALWAYS returns true. If there is an error it
- * will call FatalError() and abort.
- */
-
-
-bool 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 true;
-                       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.GetChildren().size() !=2)
-                                       FatalError("2 params to 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);
-                               }
-                               if (ARRAY_TYPE != n[0].GetType())
-                                       FatalError("First parameter to read should be an array", n[0]);
-                               if (BITVECTOR_TYPE != n[1].GetType())
-                                       FatalError("Second parameter to read should be a bitvector", n[1]);
-                               break;
-                       case WRITE:
-                               if (n.GetChildren().size() !=3)
-                                       FatalError("3 params to 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);
-                               if (ARRAY_TYPE != n[0].GetType())
-                                       FatalError("First parameter to read should be an array", n[0]);
-                               if (BITVECTOR_TYPE != n[1].GetType())
-                                       FatalError("Second parameter to read should be a bitvector", n[1]);
-                               if (BITVECTOR_TYPE != n[2].GetType())
-                                       FatalError("Third parameter to read should be a bitvector", n[2]);
-
-                               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);
-                               }
-                               if ((v.size() != 2))
-                                               FatalError("BVTypeCheck:BVSX must have two arguments. The second is the new width\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);
-                               }
-                               if ((v.size() != 2))
-                                               FatalError("BVTypeCheck:BVZX must have two arguments. The second is the new width\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 true;
-                       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;
-                       case FOR:
-                         //FIXME: Todo
-                               break;
-                       default:
-                               FatalError("BVTypeCheck: Unrecognized kind: ", ASTUndefined);
-                               break;
-               }
-       }
-       return true;
-} //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_flag)
-               return;
-
-       StatInfoSet.clear();
-       //print node size:
-       cout << endl << "Printing: " << c;
-       if (print_nodes_flag)
-       {
-               //a.PL_Print(cout,0);
-               //cout << endl;
-               cout << a << endl;
-       }
-       cout << "Node size is: ";
-       cout << NodeSize(a) << endl << endl;
-}
-
-ostream &ASTNode::LispPrint(ostream &os, int indentation) const
-{
-       printer::Lisp_Print(os, *this, indentation);
-}
-
-ostream &ASTNode::LispPrint_indent(ostream &os, int indentation) const
-{
-       printer::Lisp_Print_indent(os, *this, indentation);
-}
-
-ostream& ASTNode::PL_Print(ostream &os,  int indentation) const
-{
-       printer::PL_Print(os, *this, indentation);
-}
-
-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();
-       ReferenceCount->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();
-       ReferenceCount->clear();
-       SolverMap.clear();
-       AlwaysTrueFormMap.clear();
-       _arrayread_ite.clear();
-       _arrayread_symbol.clear();
-       _introduced_symbols.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 << "!";
-       }
-       printer::PL_Print(cout,vv, 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 ReferenceCount;
-}
+  //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_flag = false;
+  //print DAG nodes
+  bool print_nodes_flag = false;
+  //run STP in optimized mode
+  bool optimize_flag = 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_flag = true;
+  //flag to control write refinement
+  bool arraywrite_refinement_flag = true;
+  //check the counterexample against the original input to STP
+  bool check_counterexample_flag = false;
+  //construct the counterexample in terms of original variable based
+  //on the counterexample returned by SAT solver
+  bool construct_counterexample_flag = true;
+  bool print_counterexample_flag = false;
+  bool print_binary_flag = 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_flag = false;
+  //flag to decide whether to print "valid/invalid" or not
+  bool print_output_flag = false;
+  //print the variable order chosen by the sat solver while it is
+  //solving.
+  bool print_sat_varorder_flag = false;
+  //turn on word level bitvector solver
+  bool wordlevel_solve_flag = true;
+  //turn off XOR flattening
+  bool xor_flatten_flag = false;
+  //Flag to switch on the smtlib parser
+  bool smtlib_parser_flag = false;
+  //print the input back
+  bool print_STPinput_back_flag = false;
+
+  // If enabled. division, mod and remainder by zero will evaluate to 1.
+  bool division_by_zero_returns_one = false;
+
+  enum 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);
+      }
+  }
+
+
+
+  //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()
+
+
+
+  ////////////////////////////////////////////////////////////////
+  //  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;
+  }
+
+  //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
+
+    int shift_amount = (sizeof(unsigned long) << 3);
+    while (copied + (sizeof(unsigned long) << 3) < width)
+      {
+        CONSTANTBV::BitVector_Chunk_Store(bv, shift_amount, copied, c_val);
+        bvconst = bvconst >> shift_amount;
+        c_val = (~((unsigned long) 0)) & bvconst;
+        copied += shift_amount;
+      }
+    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();
+  }
+
+  // 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)
+  {
+    if (n._int_node_ptr)
+      {
+        n._int_node_ptr->IncRef();
+      }
+  }
+
+  // If there is a lot of sharing in the graph, this will take a long
+  // time.  it doesn't mark subgraphs as already having been
+  // typechecked.
+  bool BeevMgr::BVTypeCheckRecursive(const ASTNode& n)
+  {
+    const ASTVec& c = n.GetChildren();
+
+    BVTypeCheck(n);
+
+    for (ASTVec::const_iterator it = c.begin(), itend = c.end(); it != itend; it++)
+      BVTypeCheckRecursive(*it);
+
+    return true;
+  }
+
+
+
+  /* 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.
  *
  * If this returns, this ALWAYS returns true. If there is an error it
  * will call FatalError() and abort.
  */
+
+
+  bool 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 true;
+          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.GetChildren().size() !=2)
+              FatalError("2 params to 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);
+              }
+            if (ARRAY_TYPE != n[0].GetType())
+              FatalError("First parameter to read should be an array", n[0]);
+            if (BITVECTOR_TYPE != n[1].GetType())
+              FatalError("Second parameter to read should be a bitvector", n[1]);
+            break;
+          case WRITE:
+            if (n.GetChildren().size() !=3)
+              FatalError("3 params to 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);
+            if (ARRAY_TYPE != n[0].GetType())
+              FatalError("First parameter to read should be an array", n[0]);
+            if (BITVECTOR_TYPE != n[1].GetType())
+              FatalError("Second parameter to read should be a bitvector", n[1]);
+            if (BITVECTOR_TYPE != n[2].GetType())
+              FatalError("Third parameter to read should be a bitvector", n[2]);
+
+            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);
+              }
+            if ((v.size() != 2))
+              FatalError("BVTypeCheck:BVSX must have two arguments. The second is the new width\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);
+              }
+            if ((v.size() != 2))
+              FatalError("BVTypeCheck:BVZX must have two arguments. The second is the new width\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 true;
+          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;
+          case FOR:
+            //FIXME: Todo
+            break;
+          default:
+            FatalError("BVTypeCheck: Unrecognized kind: ", ASTUndefined);
+            break;
+          }
+      }
+    return true;
+  } //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_flag)
+      return;
+
+    StatInfoSet.clear();
+    //print node size:
+    cout << endl << "Printing: " << c;
+    if (print_nodes_flag)
+      {
+        //a.PL_Print(cout,0);
+        //cout << endl;
+        cout << a << endl;
+      }
+    cout << "Node size is: ";
+    cout << NodeSize(a) << endl << endl;
+  }
+
+  ostream &ASTNode::LispPrint(ostream &os, int indentation) const
+  {
+    printer::Lisp_Print(os, *this, indentation);
+  }
+
+  ostream &ASTNode::LispPrint_indent(ostream &os, int indentation) const
+  {
+    printer::Lisp_Print_indent(os, *this, indentation);
+  }
+
+  ostream& ASTNode::PL_Print(ostream &os,  int indentation) const
+  {
+    printer::PL_Print(os, *this, indentation);
+  }
+
+  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();
+    ReferenceCount->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();
+    ReferenceCount->clear();
+    SolverMap.clear();
+    AlwaysTrueFormMap.clear();
+    _arrayread_ite.clear();
+    _arrayread_symbol.clear();
+    _introduced_symbols.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 << "!";
+      }
+    printer::PL_Print(cout,vv, 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 ReferenceCount;
+  }
 
 }
 ; // end namespace
index 9e568b07a92e79e110f39c2b7fd0f830e580fbb0..6caaefeaa3b67c5c368e081ff4a3cfd465c6f894 100644 (file)
  *****************************************************************************/
 namespace BEEV
 {
-using namespace std;
-using namespace MINISAT;
+  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;
-
-       // 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
-       const CBV GetBVConst() const;
-
-       /*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;
-       ostream &LispPrint_indent(ostream &os, int indentation) const;
-
-
-       //Presentation Language Printer
-       ostream& PL_Print(ostream &os, int indentation = 0) 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
-{
+  //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;
+
+    // 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
+    const CBV GetBVConst() const;
+
+    /*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;
+    ostream &LispPrint_indent(ostream &os, int indentation) const;
+
+
+    //Presentation Language Printer
+    ostream& PL_Print(ostream &os, int indentation = 0) 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.
+    void IncRef()
+    {
+      ++_ref_count;
+    }
+
+    // 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();
 
-       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.
-       void IncRef()
-       {
-               ++_ref_count;
-       }
-
-       // 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?
-/***************************************************************************
+    // 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
-{
 ***************************************************************************/
+  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
-               {
+    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    */
-/***************************************************************************/
-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(print_binary_flag) {
-                 res = CONSTANTBV::BitVector_to_Bin(_bvconst);
-                 if (c_friendly)
-                       {
-                               prefix = "0b";
-                       }
-                       else
-                       {
-                               prefix = "0bin";
-                       }
-               }
-               else 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
-
-/***************************************************************************
- * 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;
-
-typedef hash_map<ASTNode, 
-                int32_t, 
-                ASTNode::ASTNodeHasher, 
-                ASTNode::ASTNodeEqual> ASTNodeCountMap;
-
-
-// Function to dump contents of ASTNodeMap
-ostream &operator<<(ostream &os, const ASTNodeMap &nmap);
-
-/***************************************************************************
+        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    */
+  /***************************************************************************/
+  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(print_binary_flag) {
+        res = CONSTANTBV::BitVector_to_Bin(_bvconst);
+        if (c_friendly)
+          {
+            prefix = "0b";
+          }
+        else
+          {
+            prefix = "0bin";
+          }
+      }
+      else 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
+
+  /***************************************************************************
  * 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;
+
+  typedef hash_map<ASTNode, 
+                   int32_t, 
+                   ASTNode::ASTNodeHasher, 
+                   ASTNode::ASTNodeEqual> ASTNodeCountMap;
+
+
+  // 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_set<ASTNode, 
+                   ASTNode::ASTNodeHasher, 
+                   ASTNode::ASTNodeEqual> ASTNodeSet;
 
-typedef hash_multiset<ASTNode, 
-                     ASTNode::ASTNodeHasher, 
-                     ASTNode::ASTNodeEqual> ASTNodeMultiSet;
+  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;
+  //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
-{
 ***************************************************************************/
+  class LispPrinter
+  {
 
-public:
-       ASTNode _node;
+  public:
+    ASTNode _node;
 
-       // number of spaces to print before first real character of
-       // object.
-       int _indentation;
+    // 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)
-       {
-       }
+    // 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);
-       }
-       ;
+    friend ostream &operator<<(ostream &os, const LispPrinter &lp)
+    {
+      return lp._node.LispPrint(os, lp._indentation);
+    }
+    ;
 
-}; //End of ListPrinter
+  }; //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
-{
+  //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;
+  }
 
-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;
-}
-
-/***************************************************************************
- * 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;
-
-       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;
-
-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 BBRSignedShift(ASTVec& x, unsigned int shift);
-       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, ASTNodeMap* VarConstMap=NULL);
-       ASTNode SimplifyFormula_TopLevel(const ASTNode& a, bool pushNeg);
-       ASTNode SimplifyTerm_TopLevel(const ASTNode& b);
-
-       ASTNode SimplifyFormula(const ASTNode& a, bool pushNeg, ASTNodeMap* VarConstMap=NULL);
-       ASTNode SimplifyTerm(const ASTNode& inputterm, ASTNodeMap* VarConstMap=NULL);
-       void CheckSimplifyInvariant(const ASTNode& a, const ASTNode& output);
-       void BuildReferenceCountMap(const ASTNode& b);
-
-private:
-       //memo table for simplifcation
-       ASTNodeMap *SimplifyMap;
-       ASTNodeMap *SimplifyNegMap;
-       ASTNodeMap SolverMap;
-       ASTNodeSet AlwaysTrueFormMap;
-       ASTNodeMap MultInverseMap;
-
-
-       // The number of direct parents of each node. i.e. the number
-       // of times the pointer is in "children".  When we simplify we
-       // want to be careful sometimes about using the context of a
-       // node. For example, given ((x + 23) = 2), the obvious
-       // simplification is to join the constants. However, if there
-       // are lots of references to the plus node. Then each time we
-       // simplify, we'll create an additional plus.
-       // nextpoweroftwo064.smt is the motivating benchmark. The
-       // splitting increased the number of pluses from 1 to 65.
-       ASTNodeCountMap *ReferenceCount;
-
-public:
-       ASTNode SimplifyAtomicFormula(const ASTNode& a, bool pushNeg, ASTNodeMap* VarConstMap=NULL);
-       ASTNode CreateSimplifiedEQ(const ASTNode& t1, const ASTNode& t2);
-       ASTNode ITEOpt_InEqs(const ASTNode& in1, ASTNodeMap* VarConstMap=NULL);
-       ASTNode PullUpITE(const ASTNode& in);
-       ASTNode RemoveContradictionsFromAND(const ASTNode& in);
-       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, ASTNodeMap* VarConstMap=NULL);
-       ASTNode SimplifyAndOrFormula(const ASTNode& a, bool pushNeg, ASTNodeMap* VarConstMap=NULL);
-       ASTNode SimplifyXorFormula(const ASTNode& a, bool pushNeg, ASTNodeMap* VarConstMap=NULL);
-       ASTNode SimplifyNandFormula(const ASTNode& a, bool pushNeg, ASTNodeMap* VarConstMap=NULL);
-       ASTNode SimplifyNorFormula(const ASTNode& a, bool pushNeg, ASTNodeMap* VarConstMap=NULL);
-       ASTNode SimplifyImpliesFormula(const ASTNode& a, bool pushNeg, ASTNodeMap* VarConstMap=NULL);
-       ASTNode SimplifyIffFormula(const ASTNode& a, bool pushNeg, ASTNodeMap* VarConstMap=NULL);
-       ASTNode SimplifyIteFormula(const ASTNode& a, bool pushNeg, ASTNodeMap* VarConstMap=NULL);
-        ASTNode SimplifyForFormula(const ASTNode& a, bool pushNeg, ASTNodeMap* VarConstMap=NULL);
-       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);
-       
-        int SATBased_FiniteLoop_Refinement(MINISAT::Solver& newS, const ASTNode& orig_input);
-        int Expand_FiniteLoop(const ASTNode& finiteloop, ASTNodeMap* ParamToCurrentValMap);
-        ASTNode FiniteLoop_Extract_SingleFormula(const ASTNode& finiteloop_formulabody, 
-                                                ASTNodeMap* VarConstMap);
-
-        //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);
-
-       void printCacheStatus();
-
-       //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;
-
-       //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. TransformArray should be a non-member function,
-       // but it accesses private elements. Move it later.
-       ASTNode TransformFormula_TopLevel(const ASTNode& form);
-       ASTNode TransformArray(const ASTNode& term);
-       ASTNode TransformFiniteFor(const ASTNode& form);
-
-
-       //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, ASTNodeMap* VarConstMap=NULL);
-       ASTNode ReadOverWrite_To_ITE(const ASTNode& term, ASTNodeMap* VarConstMap=NULL);
-
-       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;
-
-        //For finiteloop construct
-        //
-        //A list of all finiteloop constructs in the input formula
-        ASTVec List_Of_FiniteLoops;
-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
-
-       // NB: The boolean value is always true!
-       bool BVTypeCheck(const ASTNode& n);
-
-       // Checks recursively all the way down.
-       bool BVTypeCheckRecursive(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);
-
-        //Check the map passed to SimplifyTerm
-        bool CheckMap(ASTNodeMap* VarConstMap, const ASTNode& key, ASTNode& output);
-
-
-       //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);
-               ReferenceCount = new ASTNodeCountMap(INITIAL_SIMPLIFY_MAP_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 of Class CompleteCounterExample
-
-
-/*****************************************************************
- * 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();
-}
+  /***************************************************************************/
+  /*  Class LispVecPrinter:iomanipulator for printing vector of ASTNodes     */
+  /***************************************************************************/
+  class LispVecPrinter
+  {
 
-// 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();
-}
+  public:
+    const ASTVec * _vec;
+    // number of spaces to print before first real
+    // character of object.
+    int _indentation;
 
-// Access node number
-inline int ASTNode::GetNodeNum() const
-{
-       return _int_node_ptr->_node_num;
-}
+    // Constructor to build the LispPrinter object
+    LispVecPrinter(const ASTVec &vec, int indentation)
+    {
+      _vec = &vec;
+      _indentation = indentation;
+    }
 
-inline unsigned int ASTNode::GetIndexWidth() const
-{
-       return _int_node_ptr->_index_width;
-}
+    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 void ASTNode::SetIndexWidth(unsigned int iw) const
-{
-       _int_node_ptr->_index_width = iw;
-}
+  /***************************************************************************
+   * 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;
+
+    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;
+
+  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 BBRSignedShift(ASTVec& x, unsigned int shift);
+    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;
+    }
 
-inline unsigned int ASTNode::GetValueWidth() const
-{
-       return _int_node_ptr->_value_width;
-}
+    // Table for DAG printing.
+    ASTNodeSet AlreadyPrintedSet;
 
-inline void ASTNode::SetValueWidth(unsigned int vw) const
-{
-       _int_node_ptr->_value_width = vw;
-}
+    //Tables for Presentation language printing
 
-//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.
-inline ASTNode::ASTNode(ASTInternal *in) :
-       _int_node_ptr(in)
-{
-       if (in)
-               in->IncRef();
-}
+    //Nodes seen so far
+    ASTNodeSet PLPrintNodeSet;
 
-// 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.
+    //Map from ASTNodes to LetVars
+    ASTNodeMap NodeLetVarMap;
 
-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 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();
-       }
-}
+    //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;
 
-inline BeevMgr& ASTNode::GetBeevMgr() const
-{
-       return _int_node_ptr->_bm;
-}
+    //a partial Map from ASTNodes to LetVars. Needed in order to
+    //correctly print shared subterms inside the LET itself
+    ASTNodeMap NodeLetVarMap1;
 
-//Return the unsigned constant value of the input 'n'
-inline unsigned int GetUnsignedConst(const ASTNode n)
-{
-  if(BVCONST != n.GetKind()){
-    FatalError("GetUnsignedConst: cannot extract an "\
-              "unsigned value from a non-bvconst");
+    //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, ASTNodeMap* VarConstMap=NULL);
+    ASTNode SimplifyFormula_TopLevel(const ASTNode& a, bool pushNeg);
+    ASTNode SimplifyTerm_TopLevel(const ASTNode& b);
+
+    ASTNode SimplifyFormula(const ASTNode& a, bool pushNeg, ASTNodeMap* VarConstMap=NULL);
+    ASTNode SimplifyTerm(const ASTNode& inputterm, ASTNodeMap* VarConstMap=NULL);
+    void CheckSimplifyInvariant(const ASTNode& a, const ASTNode& output);
+    void BuildReferenceCountMap(const ASTNode& b);
+
+  private:
+    //memo table for simplifcation
+    ASTNodeMap *SimplifyMap;
+    ASTNodeMap *SimplifyNegMap;
+    ASTNodeMap SolverMap;
+    ASTNodeSet AlwaysTrueFormMap;
+    ASTNodeMap MultInverseMap;
+
+
+    // The number of direct parents of each node. i.e. the number
+    // of times the pointer is in "children".  When we simplify we
+    // want to be careful sometimes about using the context of a
+    // node. For example, given ((x + 23) = 2), the obvious
+    // simplification is to join the constants. However, if there
+    // are lots of references to the plus node. Then each time we
+    // simplify, we'll create an additional plus.
+    // nextpoweroftwo064.smt is the motivating benchmark. The
+    // splitting increased the number of pluses from 1 to 65.
+    ASTNodeCountMap *ReferenceCount;
+
+  public:
+    ASTNode SimplifyAtomicFormula(const ASTNode& a, bool pushNeg, ASTNodeMap* VarConstMap=NULL);
+    ASTNode CreateSimplifiedEQ(const ASTNode& t1, const ASTNode& t2);
+    ASTNode ITEOpt_InEqs(const ASTNode& in1, ASTNodeMap* VarConstMap=NULL);
+    ASTNode PullUpITE(const ASTNode& in);
+    ASTNode RemoveContradictionsFromAND(const ASTNode& in);
+    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, ASTNodeMap* VarConstMap=NULL);
+    ASTNode SimplifyAndOrFormula(const ASTNode& a, bool pushNeg, ASTNodeMap* VarConstMap=NULL);
+    ASTNode SimplifyXorFormula(const ASTNode& a, bool pushNeg, ASTNodeMap* VarConstMap=NULL);
+    ASTNode SimplifyNandFormula(const ASTNode& a, bool pushNeg, ASTNodeMap* VarConstMap=NULL);
+    ASTNode SimplifyNorFormula(const ASTNode& a, bool pushNeg, ASTNodeMap* VarConstMap=NULL);
+    ASTNode SimplifyImpliesFormula(const ASTNode& a, bool pushNeg, ASTNodeMap* VarConstMap=NULL);
+    ASTNode SimplifyIffFormula(const ASTNode& a, bool pushNeg, ASTNodeMap* VarConstMap=NULL);
+    ASTNode SimplifyIteFormula(const ASTNode& a, bool pushNeg, ASTNodeMap* VarConstMap=NULL);
+    ASTNode SimplifyForFormula(const ASTNode& a, bool pushNeg, ASTNodeMap* VarConstMap=NULL);
+    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);
+        
+    int SATBased_FiniteLoop_Refinement(MINISAT::Solver& newS, const ASTNode& orig_input);
+    int Expand_FiniteLoop(const ASTNode& finiteloop, ASTNodeMap* ParamToCurrentValMap);
+    ASTNode FiniteLoop_Extract_SingleFormula(const ASTNode& finiteloop_formulabody, 
+                                             ASTNodeMap* VarConstMap);
+
+    //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);
+
+    void printCacheStatus();
+
+    //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;
+
+    //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. TransformArray should be a non-member function,
+    // but it accesses private elements. Move it later.
+    ASTNode TransformFormula_TopLevel(const ASTNode& form);
+    ASTNode TransformArray(const ASTNode& term);
+    ASTNode TransformFiniteFor(const ASTNode& form);
+
+
+    //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, ASTNodeMap* VarConstMap=NULL);
+    ASTNode ReadOverWrite_To_ITE(const ASTNode& term, ASTNodeMap* VarConstMap=NULL);
+
+    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;
+
+    //For finiteloop construct
+    //
+    //A list of all finiteloop constructs in the input formula
+    ASTVec List_Of_FiniteLoops;
+  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
+
+    // NB: The boolean value is always true!
+    bool BVTypeCheck(const ASTNode& n);
+
+    // Checks recursively all the way down.
+    bool BVTypeCheckRecursive(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);
+
+    //Check the map passed to SimplifyTerm
+    bool CheckMap(ASTNodeMap* VarConstMap, const ASTNode& key, ASTNode& output);
+
+
+    //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);
+      ReferenceCount = new ASTNodeCountMap(INITIAL_SIMPLIFY_MAP_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 of Class CompleteCounterExample
+
+
+  /*****************************************************************
+   * 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();
   }
 
-  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");
-       }
+  // 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.
+  inline ASTNode::ASTNode(ASTInternal *in) :
+    _int_node_ptr(in)
+  {
+    if (in)
+      in->IncRef();
+  }
+
+  // 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.
+
+  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 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 BeevMgr& ASTNode::GetBeevMgr() const
+  {
+    return _int_node_ptr->_bm;
+  }
+
+  //Return the unsigned constant value of the input 'n'
+  inline unsigned int GetUnsignedConst(const ASTNode n)
+  {
+    if(BVCONST != n.GetKind()){
+      FatalError("GetUnsignedConst: cannot extract an "\
+                 "unsigned value from a non-bvconst");
     }
-  return (unsigned int) *((unsigned int *) n.GetBVConst());
-} //end of GetUnsignedConst
+
+    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());
+  } //end of GetUnsignedConst
 
 }; // end namespace BEEV
 #endif
index 435c8e022e75c7f24782a859d11c10d0026de162..c860d5c7bbb2a285920b832366bb9e209d9a2f9d 100644 (file)
 #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;
-}
+  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;
+  //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 (stats_flag)
-       {
+    if (stats_flag)
+      {
 
-               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 (!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 e0c8827ea162b102bdfac920a0b6c5191cfee986..e6df5a55815170aa833b4297e21e4ef2ad0f51c1 100644 (file)
@@ -77,10 +77,10 @@ namespace BEEV {
 
   enum inputStatus
     {
-         NOT_DECLARED =0, // Not included in the input file / stream
-         TO_BE_SATISFIABLE,
-         TO_BE_UNSATISFIABLE,
-         TO_BE_UNKNOWN // Specified in the input file as unknown.
+      NOT_DECLARED =0, // Not included in the input file / stream
+      TO_BE_SATISFIABLE,
+      TO_BE_UNSATISFIABLE,
+      TO_BE_UNKNOWN // Specified in the input file as unknown.
     };
 
   extern enum inputStatus input_status;
@@ -110,10 +110,10 @@ namespace BEEV {
   // Table for storing function count stats.
 #ifdef TR1_UNORDERED_MAP
   typedef tr1::unordered_map<const char*,int,
-                             tr1::hash<const char *>,eqstr> function_counters;
+    tr1::hash<const char *>,eqstr> function_counters;
 #else
   typedef hash_map<const char*,int,
-                  hash<char *>,eqstr> function_counters;
+    hash<char *>,eqstr> function_counters;
 #endif
 
   void CountersAndStats(const char * functionname);
@@ -121,6 +121,6 @@ namespace BEEV {
   //global function which accepts an integer and looks up the
   //corresponding ASTNode and prints a char* of that ASTNode
   void Convert_MINISATVar_To_ASTNode_Print(int minisat_var,
-                                          int decision, int polarity=0);
+                                           int decision, int polarity=0);
 }; // end namespace.
 #endif
index 8e074dcfb279ffa91cd547b337c382bbfd22179e..02375fe279f8253ed59681a70dd2d4264adfb7aa 100644 (file)
 
 namespace BEEV
 {
-
   /******************************************************************
    * Abstraction Refinement related functions
-   ******************************************************************/
-
-//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_flag)
-               FatalError("SATBased_ArrayReadRefinement: Control should not reach here");
+   ******************************************************************/  
+  
+  int BeevMgr::SATBased_ArrayReadRefinement(MINISAT::Solver& newS, 
+                                            const ASTNode& q, const ASTNode& orig_input) {
+    //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).
+    
+    //printf("doing array read refinement\n");
+    if (!arrayread_refinement_flag)
+      FatalError("SATBased_ArrayReadRefinement: Control should not reach here");
+    
+    ASTVec FalseAxiomsVec, RemainingAxiomsVec;
+    RemainingAxiomsVec.push_back(ASTTrue);
+    FalseAxiomsVec.push_back(ASTTrue);
+    unsigned int oldFalseAxiomsSize = 0;
 
-       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;
+              }
 
-       //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);
 
-                       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;
 
-                       //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);
 
-                               //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 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() > 0)
+            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 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() > 0)
-                       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 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()
 
-       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();
 
-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_TopLevel(writeAxiom);
+            FalseAxioms.push_back(writeAxiom);
+          }
+        else
+          {
+            writeAxiom = TransformFormula_TopLevel(writeAxiom);
+            RemainingAxioms.push_back(writeAxiom);
+          }
+      }
 
-       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_TopLevel(writeAxiom);
-                       FalseAxioms.push_back(writeAxiom);
-               }
-               else
-               {
-                       writeAxiom = TransformFormula_TopLevel(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 = (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;
+      }
 
-       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
 
-       return 2;
-} //end of SATBased_ArrayWriteRefinement
-
-//Expands all finite-for-loops using counterexample-guided
-//abstraction-refinement.
-int BeevMgr::SATBased_FiniteLoop_Refinement(MINISAT::Solver& newS, 
-                                           const ASTNode& orig_input)
-{
-  /*
-   * For each 'finiteloop' in the global list 'List_Of_FiniteLoops'
-   *
-   * Expand_FiniteLoop(finiteloop);
-   *
-   * The 'Expand_FiniteLoop' function expands the 'finiteloop' in a
-   * counterexample-guided refinement fashion
-   *
-   * Once all the finiteloops have been expanded, we need to go back
-   * and recheck that every discarded constraint is true with the
-   * final model. A flag 'done' is set to false if atleast one
-   * constraint is false during model-check, and is set to true if all
-   * constraints are true during model-check.
-   *
-   * if the 'done' flag is true, then we terminate this refinement
-   * loop.
-   */
-}
+  //Expands all finite-for-loops using counterexample-guided
+  //abstraction-refinement.
+  int BeevMgr::SATBased_FiniteLoop_Refinement(MINISAT::Solver& newS, 
+                                              const ASTNode& orig_input)
+  {
+    /*
+     * For each 'finiteloop' in the global list 'List_Of_FiniteLoops'
+     *
+     * Expand_FiniteLoop(finiteloop);
+     *
+     * The 'Expand_FiniteLoop' function expands the 'finiteloop' in a
+     * counterexample-guided refinement fashion
+     *
+     * Once all the finiteloops have been expanded, we need to go back
+     * and recheck that every discarded constraint is true with the
+     * final model. A flag 'done' is set to false if atleast one
+     * constraint is false during model-check, and is set to true if all
+     * constraints are true during model-check.
+     *
+     * if the 'done' flag is true, then we terminate this refinement
+     * loop.
+     */
+  }
 
-int BeevMgr::Expand_FiniteLoop(const ASTNode& finiteloop,
-                              ASTNodeMap* ParamToCurrentValMap) {
   /*
    * 'finiteloop' is the finite loop to be expanded
    * 
@@ -267,63 +266,64 @@ int BeevMgr::Expand_FiniteLoop(const ASTNode& finiteloop,
    *
    *    3.2: We have SAT, and it is indeed a satisfying model
    */
+  int BeevMgr::Expand_FiniteLoop(const ASTNode& finiteloop,
+                                 ASTNodeMap* ParamToCurrentValMap) {
+    //Make sure that the parameter is a variable
+    ASTNode parameter     = finiteloop[0];
+    int paramInit         = GetUnsignedConst(finiteloop[1]);
+    int paramLimit        = GetUnsignedConst(finiteloop[2]);
+    int paramIncrement    = GetUnsignedConst(finiteloop[3]);
+    ASTNode formulabody   = finiteloop[4];
+    int paramCurrentValue = paramInit;
 
-  //Make sure that the parameter is a variable
-  ASTNode parameter     = finiteloop[0];
-  int paramInit         = GetUnsignedConst(finiteloop[1]);
-  int paramLimit        = GetUnsignedConst(finiteloop[2]);
-  int paramIncrement    = GetUnsignedConst(finiteloop[3]);
-  ASTNode formulabody   = finiteloop[4];
-  int paramCurrentValue = paramInit;
-
-  //Update ParamToCurrentValMap with parameter and its current
-  //value. Here paramCurrentValue is the initial value
-  unsigned width = 32;
-  (*ParamToCurrentValMap)[parameter] = CreateBVConst(32,paramCurrentValue);
+    //Update ParamToCurrentValMap with parameter and its current
+    //value. Here paramCurrentValue is the initial value
+    unsigned width = 32;
+    (*ParamToCurrentValMap)[parameter] = CreateBVConst(32,paramCurrentValue);
     
-  //Go recursively thru' all the FOR-constructs.
-  if(FOR == formulabody.GetKind()) { 
-    while(paramCurrentValue < paramLimit) {
-      Expand_FiniteLoop(formulabody, ParamToCurrentValMap);
-      paramCurrentValue = paramCurrentValue + paramIncrement;
+    //Go recursively thru' all the FOR-constructs.
+    if(FOR == formulabody.GetKind()) { 
+      while(paramCurrentValue < paramLimit) {
+        Expand_FiniteLoop(formulabody, ParamToCurrentValMap);
+        paramCurrentValue = paramCurrentValue + paramIncrement;
 
-      //Update ParamToCurrentValMap with parameter and its current
-      //value
-      //
-      //FIXME: Possible leak since I am not freeing the previous
-      //'value' for the same 'key'            
-      (*ParamToCurrentValMap)[parameter] = CreateBVConst(32,paramCurrentValue);
-    } //end of While
-  }
-  else {
-    //Expand the leaf level FOR-construct completely
-    for(; 
-       paramCurrentValue < paramLimit; 
-       paramCurrentValue = paramCurrentValue + paramIncrement) {
-      ASTNode currentformula = 
-       FiniteLoop_Extract_SingleFormula(formulabody, ParamToCurrentValMap);
+        //Update ParamToCurrentValMap with parameter and its current
+        //value
+        //
+        //FIXME: Possible leak since I am not freeing the previous
+        //'value' for the same 'key'            
+        (*ParamToCurrentValMap)[parameter] = CreateBVConst(32,paramCurrentValue);
+      } //end of While
+    }
+    else {
+      //Expand the leaf level FOR-construct completely
+      for(; 
+          paramCurrentValue < paramLimit; 
+          paramCurrentValue = paramCurrentValue + paramIncrement) {
+        ASTNode currentformula = 
+          FiniteLoop_Extract_SingleFormula(formulabody, ParamToCurrentValMap);
       
-      //Check the currentformula against the model, and add it to the
-      //SAT solver if it is false against the model
+        //Check the currentformula against the model, and add it to the
+        //SAT solver if it is false against the model
 
-      //Update ParamToCurrentValMap with parameter and its current
-      //value 
-      //
-      //FIXME: Possible leak since I am not freeing the previous
-      //'value' for the same 'key'
-      (*ParamToCurrentValMap)[parameter] = CreateBVConst(32,paramCurrentValue);
-    }
-  } //end of else
-} //end of the Expand_FiniteLoop()
+        //Update ParamToCurrentValMap with parameter and its current
+        //value 
+        //
+        //FIXME: Possible leak since I am not freeing the previous
+        //'value' for the same 'key'
+        (*ParamToCurrentValMap)[parameter] = CreateBVConst(32,paramCurrentValue);
+      }
+    } //end of else
+  } //end of the Expand_FiniteLoop()
 
-ASTNode BeevMgr::FiniteLoop_Extract_SingleFormula(const ASTNode& formulabody, 
-                                                 ASTNodeMap* VarToConstantMap)
-{
-  /* 
-   * Takes a formula 'formulabody', and simplifies it against
-   * variable-to-constant map 'VarToConstantMap'
-   */
-  return SimplifyFormula(formulabody, VarToConstantMap);
-} //end of FiniteLoop_Extract_SingleFormula()
+  ASTNode BeevMgr::FiniteLoop_Extract_SingleFormula(const ASTNode& formulabody, 
+                                                    ASTNodeMap* VarToConstantMap)
+  {
+    /* 
+     * Takes a formula 'formulabody', and simplifies it against
+     * variable-to-constant map 'VarToConstantMap'
+     */
+    return SimplifyFormula(formulabody, VarToConstantMap);
+  } //end of FiniteLoop_Extract_SingleFormula()
 
 };// end of namespace BEEV
index ad882b625d7b11f7db8b6cc542108aad6928c6ae..f18d33029cd017bb0de65d2430e32cdc2cb340ac 100644 (file)
 #include "AST.h"
 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.
-// FIXME:  Check resource limits and generate an exception when exceeded.
-// FIXME:  THis does a lot of unnecessary copying of vectors.
-//    Had to be careful not to modify memoized vectors!
-// FIXME:  Might be some redundant variables.
-
-// accepts a term, and returns a vector of bitblasted bits(ASTVec)
-
-
-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++)
-                               {
-                                       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;
-               }
-
-               case BVRIGHTSHIFT:
-               case BVSRSHIFT:
-               {
-                       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.
-
-                               if (BVRIGHTSHIFT == k)
-                                       BBRShift(children, shift);
-                               else
-                                       BBRSignedShift(children, shift);
-
-                               result = CreateNode(BOOLVEC, children);
-                       }
-                       else
-                       {
-                               // Barrel shifter
-                               const ASTVec& bbarg1 = BBTerm(term[0]).GetChildren();
-                               const ASTVec& bbarg2 = BBTerm(term[1]).GetChildren();
-
-
-                               // Signed right shift, need to copy the sign bit.
-                               ASTNode toFill;
-                               if (BVRIGHTSHIFT == k)
-                                       toFill = ASTFalse;
-                               else
-                                       toFill = bbarg1.back();
-
-                               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], toFill, 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 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);
-                       CBV bv = term.GetBVConst();
-                       for (unsigned int i = 0; i < num_bits; i++)
-                       {
-                               tmp_res[i] = 
-                                 CONSTANTBV::BitVector_bit_test(bv, i) ? ASTTrue : ASTFalse;
-                       }
-                       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);
-
-}
-
-// bit blast a formula (boolean term).  Result is one bit wide,
-// so it returns a single ASTNode.
-// FIXME:  Add IsNegated flag.
-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);
-}
-
-// 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;
-
-}
-
-// Stores result - x in result, destructively
-void BeevMgr::BBSub(ASTVec& result, const ASTVec& y)
-{
-       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;
-}
-
-// Increment bit-blasted vector and return result.
-ASTVec BeevMgr::BBInc(ASTVec& x)
-{
-       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)
-{
-       // 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;
-}
-
-// Compute unary minus
-ASTVec BeevMgr::BBUminus(const ASTVec& x)
-{
-       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;
-}
-
-// This implements a variant of binary long division.
-// q and r are "out" parameters.  rwidth puts a bound on the
-// 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);
-       }
-}
-
-// 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;
-}
-// 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;
-}
-
-// 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
-// to this by swapping args or complementing the result bit.
-// FIXME:  If this were done MSB first, it would enable a fast exit sometimes
-// when the MSB is constant, deciding the result without looking at the rest
-// 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;
-}
-
-// Left shift by 1 within fixed field inserting zeros at LSB.
-// Writes result into first argument.
-// 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  within fixed field inserting zeros at LSB.
-// Writes result into first argument.
-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.
-       }
-}
-
-// Right shift within fixed field inserting zeros at MSB.
-// Writes result into first argument.
-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 within fixed field copying the MSB.
-// Writes result into first argument.
-void BeevMgr::BBRSignedShift(ASTVec& x, unsigned int shift)
-{
-       // right shift x (destructively) within width.
-       ASTNode & MSB = x.back();
-       ASTVec::iterator xend = x.end();
-       ASTVec::iterator xit = x.begin();
-       for (; xit < xend; xit++)
-       {
-               if (xit + shift < xend)
-                       *xit = *(xit + shift);
-               else
-                       *xit = MSB; // 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.
-}
-
-// 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;
-}
-
-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);
-}
+  //  extern void lpvec(ASTVec &vec);
+
+  // FIXME: Assert no zero-length bit vectors!!!
+  // FIXME: Need top-level functions that create and destroy the memo tables.
+  // FIXME:  Check resource limits and generate an exception when exceeded.
+  // FIXME:  THis does a lot of unnecessary copying of vectors.
+  //    Had to be careful not to modify memoized vectors!
+  // FIXME:  Might be some redundant variables.
+
+  // accepts a term, and returns a vector of bitblasted bits(ASTVec)
+
+
+  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++)
+                {
+                  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;
+        }
+
+      case BVRIGHTSHIFT:
+      case BVSRSHIFT:
+        {
+          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.
+
+              if (BVRIGHTSHIFT == k)
+                BBRShift(children, shift);
+              else
+                BBRSignedShift(children, shift);
+
+              result = CreateNode(BOOLVEC, children);
+            }
+          else
+            {
+              // Barrel shifter
+              const ASTVec& bbarg1 = BBTerm(term[0]).GetChildren();
+              const ASTVec& bbarg2 = BBTerm(term[1]).GetChildren();
+
+
+              // Signed right shift, need to copy the sign bit.
+              ASTNode toFill;
+              if (BVRIGHTSHIFT == k)
+                toFill = ASTFalse;
+              else
+                toFill = bbarg1.back();
+
+              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], toFill, 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 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);
+          CBV bv = term.GetBVConst();
+          for (unsigned int i = 0; i < num_bits; i++)
+            {
+              tmp_res[i] = 
+                CONSTANTBV::BitVector_bit_test(bv, i) ? ASTTrue : ASTFalse;
+            }
+          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);
+
+  }
+
+  // bit blast a formula (boolean term).  Result is one bit wide,
+  // so it returns a single ASTNode.
+  // FIXME:  Add IsNegated flag.
+  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);
+  }
+
+  // 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;
+
+  }
+
+  // Stores result - x in result, destructively
+  void BeevMgr::BBSub(ASTVec& result, const ASTVec& y)
+  {
+    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;
+  }
+
+  // Increment bit-blasted vector and return result.
+  ASTVec BeevMgr::BBInc(ASTVec& x)
+  {
+    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)
+  {
+    // 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;
+  }
+
+  // Compute unary minus
+  ASTVec BeevMgr::BBUminus(const ASTVec& x)
+  {
+    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;
+  }
+
+  // This implements a variant of binary long division.
+  // q and r are "out" parameters.  rwidth puts a bound on the
+  // 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);
+      }
+  }
+
+  // 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;
+  }
+  // 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;
+  }
+
+  // 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
+  // to this by swapping args or complementing the result bit.
+  // FIXME:  If this were done MSB first, it would enable a fast exit sometimes
+  // when the MSB is constant, deciding the result without looking at the rest
+  // 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;
+  }
+
+  // Left shift by 1 within fixed field inserting zeros at LSB.
+  // Writes result into first argument.
+  // 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  within fixed field inserting zeros at LSB.
+  // Writes result into first argument.
+  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.
+      }
+  }
+
+  // Right shift within fixed field inserting zeros at MSB.
+  // Writes result into first argument.
+  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 within fixed field copying the MSB.
+  // Writes result into first argument.
+  void BeevMgr::BBRSignedShift(ASTVec& x, unsigned int shift)
+  {
+    // right shift x (destructively) within width.
+    ASTNode & MSB = x.back();
+    ASTVec::iterator xend = x.end();
+    ASTVec::iterator xit = x.begin();
+    for (; xit < xend; xit++)
+      {
+        if (xit + shift < xend)
+          *xit = *(xit + shift);
+        else
+          *xit = MSB; // 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.
+  }
+
+  // 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;
+  }
+
+  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);
+  }
 } // BEEV namespace
index 1e06da08d3d07641b32f929e25d053315b441c93..ea486c0d57f6005334a7f9f6f399c6a33ace0fc6 100644 (file)
@@ -27,480 +27,480 @@ static bool _disable_simpbool = 0;
 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_flag)
-       {
-               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;
-}
-
-// 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_flag)
-       {
-               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;
-}
-
-// 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;
-}
+  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_flag)
+      {
+        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;
+  }
+
+  // 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_flag)
+      {
+        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;
+  }
+
+  // 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;
+  }
 } // BEEV namespace
index 4045087ce1af473339cd9526d41c89809b63e7e6..7b3b5169112db431178da8a31186a9f61f398810 100644 (file)
 namespace BEEV
 {
 
-class CNFMgr
-{
+  class CNFMgr
+  {
 
-public:
-
-       //########################################
-       //########################################
-       // constructor
-
-       CNFMgr(BeevMgr *bmgr)
-       {
-               bm = bmgr;
-       }
-
-       //########################################
-       //########################################
-       // destructor
-
-       ~CNFMgr()
-       {
-               ASTNodeToASTNodePtrMap::const_iterator it1 = store.begin();
-               for (; it1 != store.end(); it1++)
-               {
-                       delete it1->second;
-               }
-
-               store.clear();
-
-       }
-
-       //########################################
-       //########################################
-       // 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;
-       }
-
-       void DELETE(BeevMgr::ClauseList* varphi)
-       {
-               BeevMgr::ClauseList::const_iterator it = varphi->begin();
-               for (; it != varphi->end(); it++)
-               {
-                       delete *it;
-               }
-
-               delete varphi;
-       }
-
-private:
-
-       //########################################
-       //########################################
-       // 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);
-       }
-
-       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();
-               psi->reserve(varphi1.size() * varphi2.size());
-
-               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->reserve(clause1->size() + clause2->size());
-                               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)
-       {
-               ASTVec::const_iterator it = varphi.GetChildren().begin();
-               for (; it != varphi.GetChildren().end(); it++)
-    {
-                 convertFormulaToCNF(*it, defs); // make pos and neg clause sets
-    }
-               BeevMgr::ClauseList* psi = convertFormulaToCNFPosXORAux(varphi, 0, defs);
-               info[varphi]->clausespos = psi;
-               ASTVec::const_iterator it2 = varphi.GetChildren().begin();
-               for (; it2 != varphi.GetChildren().end(); it2++){
-                 reduceMemoryFootprintPos(*it2);
-                 reduceMemoryFootprintNeg(*it2);
-    }
-       }
-
-       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])
-                       //****************************************
-                       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]]);
-                       }
-
-                       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);
-
-                       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]]);
-                       }
-
-                       psi1 = PRODUCT(*(info[varphi[idx]]->clausespos), *theta1);
-                       psi2 = PRODUCT(*(info[varphi[idx]]->clausesneg), *theta2);
-                       DELETE(theta1);
-                       DELETE(theta2);
-                       NOCOPY_INPLACE_UNION(psi1, psi2);
-
-                       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)
-       {
-               ASTVec::const_iterator it = varphi.GetChildren().begin();
-               for (; it != varphi.GetChildren().end(); it++)
-    {
-                 convertFormulaToCNF(*it, defs); // make pos and neg clause sets
-    }
-               BeevMgr::ClauseList* psi = convertFormulaToCNFNegXORAux(varphi, 0, defs);
-               info[varphi]->clausesneg = psi;
-               ASTVec::const_iterator it2 = varphi.GetChildren().begin();
-               for (; it2 != varphi.GetChildren().end(); it2++){
-                 reduceMemoryFootprintPos(*it2);
-                 reduceMemoryFootprintNeg(*it2);
-    }
-       }
-
-       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], defs);
-                       renamesibs = (info[varphi[idx]]->clausespos)->size() > 1 ? true : false;
-                       if (renamesibs)
-                       {
-                               setDoSibRenamingNeg(*info[varphi[idx + 1]]);
-                       }
-
-                       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);
-
-                       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]]);
-                       }
-
-                       psi1 = PRODUCT(*(info[varphi[idx]]->clausesneg), *theta1);
-                       psi2 = PRODUCT(*(info[varphi[idx]]->clausespos), *theta2);
-                       DELETE(theta1);
-                       DELETE(theta2);
-                       NOCOPY_INPLACE_UNION(psi1, psi2);
-
-                       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;
-               CNFInfo* toDelete = info[varphi]; // get the thing to delete.
-               info.erase(varphi);                               // remove it from the hashtable
-               delete toDelete;
-
-
-               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)
-{
+  public:
 
-       ASTNode q = CreateNode(AND, inputasserts, CreateNode(NOT, query));
-       return TopLevelSATAux(q);
-}
+    //########################################
+    //########################################
+    // constructor
 
-//############################################################
-//############################################################
+    CNFMgr(BeevMgr *bmgr)
+    {
+      bm = bmgr;
+    }
 
+    //########################################
+    //########################################
+    // destructor
 
-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_flag)
-               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_flag && print_nodes_flag)
-               {
-                       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_flag && print_nodes_flag)
-                       {
-                               cout << "Supposedly bogus one: \n";
-                               bool tmp = print_counterexample_flag;
-                               print_counterexample_flag = true;
-                               PrintCounterExample(true);
-                               print_counterexample_flag = tmp;
-                       }
-
-                       return 2;
-               }
-       }
-       else
-       {
-               PrintOutput(true);
-               return -100;
-       }
-} //end of CALLSAT_ResultCheck
+    ~CNFMgr()
+    {
+      ASTNodeToASTNodePtrMap::const_iterator it1 = store.begin();
+      for (; it1 != store.end(); it1++)
+        {
+          delete it1->second;
+        }
+
+      store.clear();
+
+    }
+
+    //########################################
+    //########################################
+    // 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;
+    }
+
+    void DELETE(BeevMgr::ClauseList* varphi)
+    {
+      BeevMgr::ClauseList::const_iterator it = varphi->begin();
+      for (; it != varphi->end(); it++)
+        {
+          delete *it;
+        }
+
+      delete varphi;
+    }
+
+  private:
+
+    //########################################
+    //########################################
+    // 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);
+    }
+
+    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();
+      psi->reserve(varphi1.size() * varphi2.size());
+
+      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->reserve(clause1->size() + clause2->size());
+              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)
+    {
+      ASTVec::const_iterator it = varphi.GetChildren().begin();
+      for (; it != varphi.GetChildren().end(); it++)
+        {
+          convertFormulaToCNF(*it, defs); // make pos and neg clause sets
+        }
+      BeevMgr::ClauseList* psi = convertFormulaToCNFPosXORAux(varphi, 0, defs);
+      info[varphi]->clausespos = psi;
+      ASTVec::const_iterator it2 = varphi.GetChildren().begin();
+      for (; it2 != varphi.GetChildren().end(); it2++){
+        reduceMemoryFootprintPos(*it2);
+        reduceMemoryFootprintNeg(*it2);
+      }
+    }
+
+    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])
+          //****************************************
+          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]]);
+            }
+
+          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);
+
+          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]]);
+            }
+
+          psi1 = PRODUCT(*(info[varphi[idx]]->clausespos), *theta1);
+          psi2 = PRODUCT(*(info[varphi[idx]]->clausesneg), *theta2);
+          DELETE(theta1);
+          DELETE(theta2);
+          NOCOPY_INPLACE_UNION(psi1, psi2);
+
+          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)
+    {
+      ASTVec::const_iterator it = varphi.GetChildren().begin();
+      for (; it != varphi.GetChildren().end(); it++)
+        {
+          convertFormulaToCNF(*it, defs); // make pos and neg clause sets
+        }
+      BeevMgr::ClauseList* psi = convertFormulaToCNFNegXORAux(varphi, 0, defs);
+      info[varphi]->clausesneg = psi;
+      ASTVec::const_iterator it2 = varphi.GetChildren().begin();
+      for (; it2 != varphi.GetChildren().end(); it2++){
+        reduceMemoryFootprintPos(*it2);
+        reduceMemoryFootprintNeg(*it2);
+      }
+    }
+
+    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], defs);
+          renamesibs = (info[varphi[idx]]->clausespos)->size() > 1 ? true : false;
+          if (renamesibs)
+            {
+              setDoSibRenamingNeg(*info[varphi[idx + 1]]);
+            }
+
+          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);
+
+          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]]);
+            }
+
+          psi1 = PRODUCT(*(info[varphi[idx]]->clausesneg), *theta1);
+          psi2 = PRODUCT(*(info[varphi[idx]]->clausespos), *theta2);
+          DELETE(theta1);
+          DELETE(theta2);
+          NOCOPY_INPLACE_UNION(psi1, psi2);
+
+          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;
+      CNFInfo* toDelete = info[varphi]; // get the thing to delete.
+      info.erase(varphi);                                 // remove it from the hashtable
+      delete toDelete;
+
+
+      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_flag)
+      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_flag && print_nodes_flag)
+          {
+            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_flag && print_nodes_flag)
+              {
+                cout << "Supposedly bogus one: \n";
+                bool tmp = print_counterexample_flag;
+                print_counterexample_flag = true;
+                PrintCounterExample(true);
+                print_counterexample_flag = tmp;
+              }
+
+            return 2;
+          }
+      }
+    else
+      {
+        PrintOutput(true);
+        return -100;
+      }
+  } //end of CALLSAT_ResultCheck
 
 
 } // end namespace
index 6e67b1ddac4c44945fbb59ec84862d10f535dabe..6d5265d8c9358278296e89d12c336c23acd3c2d8 100644 (file)
 
 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();
-       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_flag)
-               return;
-       double cpu_time = MINISAT::cpuTime();
-       uint64_t mem_used = MINISAT::memUsed();
-        reportf("restarts              : %llu\n",                      s.starts);
-        reportf("conflicts             : %llu   (%.0f /sec)\n",        s.conflicts   , s.conflicts   /cpu_time);
-        reportf("decisions             : %llu   (%.0f /sec)\n",        s.decisions   , s.decisions   /cpu_time);
-        reportf("propagations          : %llu   (%.0f /sec)\n",        s.propagations, s.propagations/cpu_time);
-        reportf("conflict literals     : %llu   (%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_flag && print_nodes_flag))
-               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);
-                               }
-                               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;
-                       }
-
-               }
-       }
-
-       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_flag)
-               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;
-                                               }
-                                       }
-                               }
-                       }
-               }
-       }
-
-       //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);
-                       }
-                       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);
-                       }
-
-
-                       if (WRITE == arrName.GetKind()) //READ over a WRITE
-                       {
-                               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);
-                               assert(ArrayReadFlag || (BVCONST == rtterm.GetKind()));
-                               return rtterm;
-                       }
-                       else if (ITE == arrName.GetKind()) //READ over an ITE
-                       {
-                               // The "then" and "else" branch are arrays.
-                               ASTNode indexVal = TermToConstTermUsingModel(index, ArrayReadFlag);
-
-                               ASTNode condcompute = ComputeFormulaUsingModel(arrName[0]); // Get the truth value.
-                               if (ASTTrue == condcompute)
-                               {
-                                       const ASTNode & result = TermToConstTermUsingModel(CreateTerm(READ, arrName.GetValueWidth(), arrName[1], indexVal), ArrayReadFlag);
-                                       assert(ArrayReadFlag || (BVCONST == result.GetKind()));
-                                       return result;
-                               }
-                               else if (ASTFalse == condcompute)
-                               {
-                                       const ASTNode & result =  TermToConstTermUsingModel(CreateTerm(READ, arrName.GetValueWidth(), arrName[2], indexVal), ArrayReadFlag);
-                                       assert(ArrayReadFlag || (BVCONST == result.GetKind()));
-                                       return result;
-                               }
-                               else
-                               {
-                                       cerr << "TermToConstTermUsingModel: termITE: value of conditional is wrong: " << condcompute << endl;
-                                       FatalError(" TermToConstTermUsingModel: termITE: cannot compute ITE conditional against model: ", term);
-                               }
-                               FatalError("bn23143 Never Here");
-                       }
-
-                       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;
-               }
-       }
-
-       assert(ArrayReadFlag || (BVCONST == output.GetKind()));
-
-       //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;
-} //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_flag)
-       {
-               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_flag)
-       {
-               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_flag)
-       {
-               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;
-               }
-       }
-       //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_flag)
-               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_flag)
-               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";
-                       }
-               }
-       }
-       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
-
-//##################################################
-//##################################################
-
-
-void BeevMgr::printCacheStatus()
-{
-       cerr << SimplifyMap->size() << endl;
-       cerr << SimplifyNegMap->size() << endl;
-       cerr << ReferenceCount->size() << endl;
-       cerr << TermsAlreadySeenMap.size() << endl;
-
-       cerr << SimplifyMap->bucket_count() << endl;
-       cerr << SimplifyNegMap->bucket_count() << endl;
-       cerr << ReferenceCount->bucket_count() << endl;
-       cerr << TermsAlreadySeenMap.bucket_count() << endl;
-
-
-
-}
-
-// 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_flag) ? 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_TopLevel(newq);
-       ASTNodeStats("after transformation: ", newq);
-       TermsAlreadySeenMap.clear();
-
-       //if(stats_flag)
-       //      printCacheStatus();
-
-       int res;
-       //solver instantiated here
-       MINISAT::Solver newS;
-       //MINISAT::SimpSolver newS;
-       //MINISAT::UnsoundSimpSolver newS;
-       if (arrayread_refinement_flag)
-       {
-               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("TopLevelSATAux: 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
-
-/*******************************************************************
- * Helper Functions
- *******************************************************************/
-//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);
-}
-
-//This function prints the output of the STP solver
-void BeevMgr::PrintOutput(bool true_iff_valid)
-{
+  /* 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();
+    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_flag)
+      return;
+    double cpu_time = MINISAT::cpuTime();
+    uint64_t mem_used = MINISAT::memUsed();
+    reportf("restarts              : %llu\n",                      s.starts);
+    reportf("conflicts             : %llu   (%.0f /sec)\n",        s.conflicts   , s.conflicts   /cpu_time);
+    reportf("decisions             : %llu   (%.0f /sec)\n",        s.decisions   , s.decisions   /cpu_time);
+    reportf("propagations          : %llu   (%.0f /sec)\n",        s.propagations, s.propagations/cpu_time);
+    reportf("conflict literals     : %llu   (%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_flag && print_nodes_flag))
+      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);
+                }
+              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;
+            }
+
+        }
+      }
+
+    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_flag)
+      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;
+                          }
+                      }
+                  }
+              }
+          }
+      }
+
+    //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);
+              }
+            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);
+            }
+
+
+          if (WRITE == arrName.GetKind()) //READ over a WRITE
+            {
+              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);
+              assert(ArrayReadFlag || (BVCONST == rtterm.GetKind()));
+              return rtterm;
+            }
+          else if (ITE == arrName.GetKind()) //READ over an ITE
+            {
+              // The "then" and "else" branch are arrays.
+              ASTNode indexVal = TermToConstTermUsingModel(index, ArrayReadFlag);
+
+              ASTNode condcompute = ComputeFormulaUsingModel(arrName[0]); // Get the truth value.
+              if (ASTTrue == condcompute)
+                {
+                  const ASTNode & result = TermToConstTermUsingModel(CreateTerm(READ, arrName.GetValueWidth(), arrName[1], indexVal), ArrayReadFlag);
+                  assert(ArrayReadFlag || (BVCONST == result.GetKind()));
+                  return result;
+                }
+              else if (ASTFalse == condcompute)
+                {
+                  const ASTNode & result =  TermToConstTermUsingModel(CreateTerm(READ, arrName.GetValueWidth(), arrName[2], indexVal), ArrayReadFlag);
+                  assert(ArrayReadFlag || (BVCONST == result.GetKind()));
+                  return result;
+                }
+              else
+                {
+                  cerr << "TermToConstTermUsingModel: termITE: value of conditional is wrong: " << condcompute << endl;
+                  FatalError(" TermToConstTermUsingModel: termITE: cannot compute ITE conditional against model: ", term);
+                }
+              FatalError("bn23143 Never Here");
+            }
+
+          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;
+        }
+      }
+
+    assert(ArrayReadFlag || (BVCONST == output.GetKind()));
+
+    //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;
+  } //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_flag)
+      {
+        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_flag)
+      {
+        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_flag)
+      {
+        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;
+          }
+      }
+    //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_flag)
+      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_flag)
+      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";
+              }
+          }
+      }
+    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
+
+  //##################################################
+  //##################################################
+
+
+  void BeevMgr::printCacheStatus()
+  {
+    cerr << SimplifyMap->size() << endl;
+    cerr << SimplifyNegMap->size() << endl;
+    cerr << ReferenceCount->size() << endl;
+    cerr << TermsAlreadySeenMap.size() << endl;
+
+    cerr << SimplifyMap->bucket_count() << endl;
+    cerr << SimplifyNegMap->bucket_count() << endl;
+    cerr << ReferenceCount->bucket_count() << endl;
+    cerr << TermsAlreadySeenMap.bucket_count() << endl;
+
+
+
+  }
+
+  // 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_flag) ? 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_TopLevel(newq);
+    ASTNodeStats("after transformation: ", newq);
+    TermsAlreadySeenMap.clear();
+
+    //if(stats_flag)
+    //  printCacheStatus();
+
+    int res;
+    //solver instantiated here
+    MINISAT::Solver newS;
+    //MINISAT::SimpSolver newS;
+    //MINISAT::UnsoundSimpSolver newS;
+    if (arrayread_refinement_flag)
+      {
+        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("TopLevelSATAux: 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
+
+  /*******************************************************************
+   * Helper Functions
+   *******************************************************************/
+  //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);
+  }
+
+  //This function prints the output of the STP solver
+  void BeevMgr::PrintOutput(bool true_iff_valid)
+  {
+    if (print_output_flag)
+      {
+        if (smtlib_parser_flag)
+          {
+            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_flag)
-       {
-               if (smtlib_parser_flag)
-               {
-                 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_flag)
-               {
-                       if (smtlib_parser_flag)
-                               cout << "unsat\n";
-                       else
-                               cout << "Valid.\n";
-               }
-       }
-       else
-       {
-               ValidFlag = false;
-               if (print_output_flag)
-               {
-                       if (smtlib_parser_flag)
-                               cout << "sat\n";
-                       else
-                               cout << "Invalid.\n";
-               }
-       }
-}
+          {
+            if (smtlib_parser_flag)
+              cout << "unsat\n";
+            else
+              cout << "Valid.\n";
+          }
+      }
+    else
+      {
+        ValidFlag = false;
+        if (print_output_flag)
+          {
+            if (smtlib_parser_flag)
+              cout << "sat\n";
+            else
+              cout << "Invalid.\n";
+          }
+      }
+  }
 }
 ; //end of namespace BEEV
index 84b3988cb235719a9872743f4821d505cc9afb2a..11265b0eab5a0040d648c0de8331814470d387d3 100644 (file)
 namespace BEEV
 {
 
-ASTNode TransformFormula(const ASTNode& form);
-ASTNode TranslateSignedDivModRem(const ASTNode& in);
-ASTNode TransformTerm(const ASTNode& inputterm);
-void assertTransformPostConditions(const ASTNode & term);
-
-ASTNodeMap* TransformMap;
-
-const bool debug_transform = false;
-
-// NB: This is the only function that should be called externally. It sets
-// up the cache that the others use.
-ASTNode BeevMgr::TransformFormula_TopLevel(const ASTNode& form)
-{
-       assert(TransformMap == NULL);
-       TransformMap = new ASTNodeMap(100);
-       ASTNode result = TransformFormula(form);
-       if (debug_transform)
-               assertTransformPostConditions(result);
-       TransformMap->clear();
-       delete TransformMap;
-       TransformMap = NULL;
-       return result;
-}
-
-//Translates signed BVDIV,BVMOD and BVREM into unsigned variety
-ASTNode TranslateSignedDivModRem(const ASTNode& in)
-{
-       BeevMgr& bm = in.GetBeevMgr();
-       assert(in.GetChildren().size() ==2);
-
-       ASTNode dividend = in[0];
-       ASTNode divisor = in[1];
-       unsigned len = in.GetValueWidth();
-
-       ASTNode hi1 = bm.CreateBVConst(32, len - 1);
-       ASTNode one = bm.CreateOneConst(1);
-       ASTNode zero = bm.CreateZeroConst(1);
-       // create the condition for the dividend
-       ASTNode cond_dividend = bm.CreateNode(EQ, one, bm.CreateTerm(BVEXTRACT, 1, dividend, hi1, hi1));
-       // create the condition for the divisor
-       ASTNode cond_divisor = bm.CreateNode(EQ, one, bm.CreateTerm(BVEXTRACT, 1, divisor, hi1, hi1));
-
-       if (SBVREM == in.GetKind())
-       {
-               //BVMOD is an expensive operation. So have the fewest bvmods possible. Just one.
-
-               //Take absolute value.
-               ASTNode pos_dividend = bm.CreateTerm(ITE, len, cond_dividend, bm.CreateTerm(BVUMINUS, len, dividend), dividend);
-               ASTNode pos_divisor = bm.CreateTerm(ITE, len, cond_divisor, bm.CreateTerm(BVUMINUS, len, divisor), divisor);
-
-               //create the modulus term
-               ASTNode modnode = bm.CreateTerm(BVMOD, len, pos_dividend, pos_divisor);
-
-               //If the dividend is <0 take the unary minus.
-               ASTNode n = bm.CreateTerm(ITE, len, cond_dividend, bm.CreateTerm(BVUMINUS, len, modnode), modnode);
-
-               //put everything together, simplify, and return
-               return bm.SimplifyTerm_TopLevel(n);
-       }
-
-       // This is the modulus of dividing rounding to -infinity.
-       // Except if the signs are different, and it perfectly divides
-       // the modulus is the divisor (not zero).
-       else 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)))))))
-
-               //Take absolute value.
-               ASTNode pos_dividend = bm.CreateTerm(ITE, len, cond_dividend, bm.CreateTerm(BVUMINUS, len, dividend), dividend);
-               ASTNode pos_divisor = bm.CreateTerm(ITE, len, cond_divisor, bm.CreateTerm(BVUMINUS, len, divisor), divisor);
-
-               ASTNode urem_node = bm.CreateTerm(BVMOD, len, pos_dividend, pos_divisor);
-
-               // If the dividend is <0, then we negate the whole thing.
-               ASTNode rev_node = bm.CreateTerm(ITE, len, cond_dividend, bm.CreateTerm(BVUMINUS, len, urem_node), urem_node);
-
-               // if It's XOR <0 then add t (not its absolute value).
-               ASTNode xor_node = bm.CreateNode(XOR, cond_dividend, cond_divisor);
-               ASTNode n = bm.CreateTerm(ITE, len, xor_node, bm.CreateTerm(BVPLUS, len, rev_node, divisor), rev_node);
-
-               return bm.SimplifyTerm_TopLevel(n);
-       }
-       else if (SBVDIV == in.GetKind())
-       {
-               //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)
-
-               //Take absolute value.
-               ASTNode pos_dividend = bm.CreateTerm(ITE, len, cond_dividend, bm.CreateTerm(BVUMINUS, len, dividend), dividend);
-               ASTNode pos_divisor = bm.CreateTerm(ITE, len, cond_divisor, bm.CreateTerm(BVUMINUS, len, divisor), divisor);
-
-               ASTNode divnode = bm.CreateTerm(BVDIV, len, pos_dividend, pos_divisor);
-
-               // A little confusing. Only negate the result if they are XOR <0.
-               ASTNode xor_node = bm.CreateNode(XOR, cond_dividend, cond_divisor);
-               ASTNode n = bm.CreateTerm(ITE, len, xor_node, bm.CreateTerm(BVUMINUS, len, divnode), divnode);
-
-               return bm.SimplifyTerm_TopLevel(n);
-       }
-
-       FatalError("TranslateSignedDivModRem: input must be signed DIV/MOD/REM", in);
-       return bm.CreateNode(UNDEFINED);
-
-}//end of TranslateSignedDivModRem()
-
-// Check that the transformations have occurred.
-void assertTransformPostConditions(const ASTNode & term)
-{
-       const Kind k = term.GetKind();
-
-       // Check the signed operations have been removed.
-       assert( SBVDIV != k);
-       assert( SBVMOD != k);
-       assert( SBVREM !=k);
-
-       // Check the array reads / writes have been removed
-       assert( READ !=k );
-       assert( WRITE !=k);
-
-       // There should be no nodes left of type array.
-       assert(0 == term.GetIndexWidth());
-
-       ASTVec c = term.GetChildren();
-       ASTVec::iterator it = c.begin();
-       ASTVec::iterator itend = c.end();
-       ASTVec o;
-       for (; it != itend; it++)
-       {
-               assertTransformPostConditions(*it);
-       }
-}
-
-ASTNode TransformFormula(const ASTNode& form)
-{
-       BeevMgr& bm = form.GetBeevMgr();
-
-       assert(TransformMap != null);
-
-       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 = bm.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 = bm.CreateNode(k, c);
-                       break;
-               }
-               case EQ:
-               {
-                       ASTNode term1 = TransformTerm(simpleForm[0]);
-                       ASTNode term2 = TransformTerm(simpleForm[1]);
-                       result = bm.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 = bm.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: ", bm.CreateNode(UNDEFINED), k);
-                       }
-                       break;
-       }
-
-       if (simpleForm.GetChildren().size() > 0)
-               (*TransformMap)[simpleForm] = result;
-       return result;
-} //End of TransformFormula
-
-ASTNode TransformTerm(const ASTNode& inputterm)
-{
-       assert(TransformMap != null);
-
-       BeevMgr& bm = inputterm.GetBeevMgr();
-
-       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 = bm.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 = bm.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 = bm.CreateTerm(k, width, o);
-                       result.SetIndexWidth(indexwidth);
-
-                       Kind k = result.GetKind();
-
-                       if (BVDIV == k || BVMOD == k || SBVDIV == k || SBVREM == k || SBVMOD == k)
-                       {
-                               ASTNode bottom = result[1];
-
-                               if (SBVDIV == result.GetKind() || SBVREM == result.GetKind() || SBVMOD == result.GetKind())
-                               {
-                                       result = TranslateSignedDivModRem(result);
-                               }
-
-                               if (division_by_zero_returns_one)
-                               {
-                                       // This is a difficult rule to introduce in other places because it's recursive. i.e.
-                                       // result is embedded unchanged inside the result.
-
-                                       unsigned inputValueWidth = result.GetValueWidth();
-                                       ASTNode zero = bm.CreateZeroConst(inputValueWidth);
-                                       ASTNode one = bm.CreateOneConst(inputValueWidth);
-                                       result = bm.CreateTerm(ITE, inputValueWidth, bm.CreateNode(EQ, zero, bottom), one, result);
-                               }
-                       }
-               }
-                       ////////////////////////////////////////////////////////////////////////////////////
-
-
-                       break;
-       }
-
-       if (term.GetChildren().size() > 0)
-               (*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)
- *
- */
-ASTNode BeevMgr::TransformArray(const ASTNode& term)
-{
-       assert(TransformMap != null);
-
-       ASTNode result = term;
-
-       const unsigned int width = term.GetValueWidth();
-
-       if (READ != term.GetKind())
-               FatalError("TransformArray: input term is of wrong kind: ", ASTUndefined);
-
-       ASTNodeMap::iterator iter;
-       if ((iter = TransformMap->find(term)) != TransformMap->end())
-               return iter->second;
-
-       //'term' is of the form READ(arrName, readIndex)
-       const ASTNode & arrName = term[0];
-       const ASTNode & readIndex = TransformTerm(term[1]);
-
-       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 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.
-                       const ASTVec & readIndices = _arrayname_readindices[arrName];
-
-                       //construct the ITE structure for this array-read
-                       ASTNode ite = CurrentSymbol;
-                       _introduced_symbols.insert(CurrentSymbol);
-                       assert(BVTypeCheck(ite));
-
-                       if (arrayread_refinement_flag)
-                       {
-                               // ite is really a variable here; it is an ite in the
-                               // else-branch
-                               result = ite;
-                       }
-                       else
-                       {
-                               // Full Array transform if we're not doing read refinement.
-                               ASTVec::const_reverse_iterator it2 = readIndices.rbegin();
-                               ASTVec::const_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);
-                                       assert(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 writeIndex = TransformTerm(arrName[1]);
-                       ASTNode writeVal = TransformTerm(arrName[2]);
-
-                       if (ARRAY_TYPE != arrName[0].GetType())
-                               FatalError("TransformArray: An array write is being attempted on a non-array:", term);
-
-                       if ((SYMBOL == arrName[0].GetKind() || WRITE == arrName[0].GetKind()))
-                       {
-                               ASTNode cond = CreateSimplifiedEQ(writeIndex, readIndex);
-                               BVTypeCheck(cond);
-
-                               ASTNode readTerm = CreateTerm(READ, width, arrName[0], readIndex);
-                               BVTypeCheck(readTerm);
-
-                               ASTNode readPushedIn = TransformArray(readTerm);
-                               BVTypeCheck(readPushedIn);
-
-                               result = CreateSimplifiedTermITE(cond, writeVal, readPushedIn);
-
-                               BVTypeCheck(result);
-                       }
-                       else if (ITE == arrName[0].GetKind())
-                       {
-                               // pull out the ite from the write // pushes the write through.
-                               ASTNode writeTrue = CreateNode(WRITE, (arrName[0][1]), writeIndex, writeVal);
-                               writeTrue.SetIndexWidth(writeIndex.GetValueWidth());
-                               writeTrue.SetValueWidth(writeVal.GetValueWidth());
-                               assert(ARRAY_TYPE == writeTrue.GetType());
-
-                               ASTNode writeFalse = CreateNode(WRITE, (arrName[0][2]), writeIndex, writeVal);
-                               writeFalse.SetIndexWidth(writeIndex.GetValueWidth());
-                               writeFalse.SetValueWidth(writeVal.GetValueWidth());
-                               assert(ARRAY_TYPE == writeFalse.GetType());
-
-                               result = CreateSimplifiedTermITE(TransformFormula(arrName[0][0]), writeTrue, writeFalse);
-                               result.SetIndexWidth(writeIndex.GetValueWidth());
-                               result.SetValueWidth(writeVal.GetValueWidth());
-                               assert(ARRAY_TYPE == result.GetType());
-
-                               result = CreateTerm(READ, writeVal.GetValueWidth(), result, readIndex);
-                               BVTypeCheck(result);
-                               result = TransformArray(result);
-                       }
-                       else
-                               FatalError("TransformArray: Write over bad type.");
-                       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))
-                        */
-
-                       // pull out the ite from the read // pushes the read through.
-
-                       //(ITE cond thn els)
-
-                       ASTNode cond = arrName[0];
-                       cond = TransformFormula(cond);
-
-                       const ASTNode& thn = arrName[1];
-                       const ASTNode& els = arrName[2];
-
-                       //(READ thn j)
-                       ASTNode thnRead = CreateTerm(READ, width, thn, readIndex);
-                       BVTypeCheck(thnRead);
-                       thnRead = TransformArray(thnRead);
-
-                       //(READ els j)
-                       ASTNode elsRead = CreateTerm(READ, width, els, readIndex);
-                       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;
-       }
-
-       (*TransformMap)[term] = result;
-       return result;
-} //end of TransformArray()
-
-ASTNode BeevMgr::TransformFiniteFor(const ASTNode& form)
-{
-  return form;
-}
+  ASTNode TransformFormula(const ASTNode& form);
+  ASTNode TranslateSignedDivModRem(const ASTNode& in);
+  ASTNode TransformTerm(const ASTNode& inputterm);
+  void assertTransformPostConditions(const ASTNode & term);
+
+  ASTNodeMap* TransformMap;
+
+  const bool debug_transform = false;
+
+  // NB: This is the only function that should be called externally. It sets
+  // up the cache that the others use.
+  ASTNode BeevMgr::TransformFormula_TopLevel(const ASTNode& form)
+  {
+    assert(TransformMap == NULL);
+    TransformMap = new ASTNodeMap(100);
+    ASTNode result = TransformFormula(form);
+    if (debug_transform)
+      assertTransformPostConditions(result);
+    TransformMap->clear();
+    delete TransformMap;
+    TransformMap = NULL;
+    return result;
+  }
+
+  //Translates signed BVDIV,BVMOD and BVREM into unsigned variety
+  ASTNode TranslateSignedDivModRem(const ASTNode& in)
+  {
+    BeevMgr& bm = in.GetBeevMgr();
+    assert(in.GetChildren().size() ==2);
+
+    ASTNode dividend = in[0];
+    ASTNode divisor = in[1];
+    unsigned len = in.GetValueWidth();
+
+    ASTNode hi1 = bm.CreateBVConst(32, len - 1);
+    ASTNode one = bm.CreateOneConst(1);
+    ASTNode zero = bm.CreateZeroConst(1);
+    // create the condition for the dividend
+    ASTNode cond_dividend = bm.CreateNode(EQ, one, bm.CreateTerm(BVEXTRACT, 1, dividend, hi1, hi1));
+    // create the condition for the divisor
+    ASTNode cond_divisor = bm.CreateNode(EQ, one, bm.CreateTerm(BVEXTRACT, 1, divisor, hi1, hi1));
+
+    if (SBVREM == in.GetKind())
+      {
+        //BVMOD is an expensive operation. So have the fewest bvmods possible. Just one.
+
+        //Take absolute value.
+        ASTNode pos_dividend = bm.CreateTerm(ITE, len, cond_dividend, bm.CreateTerm(BVUMINUS, len, dividend), dividend);
+        ASTNode pos_divisor = bm.CreateTerm(ITE, len, cond_divisor, bm.CreateTerm(BVUMINUS, len, divisor), divisor);
+
+        //create the modulus term
+        ASTNode modnode = bm.CreateTerm(BVMOD, len, pos_dividend, pos_divisor);
+
+        //If the dividend is <0 take the unary minus.
+        ASTNode n = bm.CreateTerm(ITE, len, cond_dividend, bm.CreateTerm(BVUMINUS, len, modnode), modnode);
+
+        //put everything together, simplify, and return
+        return bm.SimplifyTerm_TopLevel(n);
+      }
+
+    // This is the modulus of dividing rounding to -infinity.
+    // Except if the signs are different, and it perfectly divides
+    // the modulus is the divisor (not zero).
+    else 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)))))))
+
+        //Take absolute value.
+        ASTNode pos_dividend = bm.CreateTerm(ITE, len, cond_dividend, bm.CreateTerm(BVUMINUS, len, dividend), dividend);
+        ASTNode pos_divisor = bm.CreateTerm(ITE, len, cond_divisor, bm.CreateTerm(BVUMINUS, len, divisor), divisor);
+
+        ASTNode urem_node = bm.CreateTerm(BVMOD, len, pos_dividend, pos_divisor);
+
+        // If the dividend is <0, then we negate the whole thing.
+        ASTNode rev_node = bm.CreateTerm(ITE, len, cond_dividend, bm.CreateTerm(BVUMINUS, len, urem_node), urem_node);
+
+        // if It's XOR <0 then add t (not its absolute value).
+        ASTNode xor_node = bm.CreateNode(XOR, cond_dividend, cond_divisor);
+        ASTNode n = bm.CreateTerm(ITE, len, xor_node, bm.CreateTerm(BVPLUS, len, rev_node, divisor), rev_node);
+
+        return bm.SimplifyTerm_TopLevel(n);
+      }
+    else if (SBVDIV == in.GetKind())
+      {
+        //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)
+
+        //Take absolute value.
+        ASTNode pos_dividend = bm.CreateTerm(ITE, len, cond_dividend, bm.CreateTerm(BVUMINUS, len, dividend), dividend);
+        ASTNode pos_divisor = bm.CreateTerm(ITE, len, cond_divisor, bm.CreateTerm(BVUMINUS, len, divisor), divisor);
+
+        ASTNode divnode = bm.CreateTerm(BVDIV, len, pos_dividend, pos_divisor);
+
+        // A little confusing. Only negate the result if they are XOR <0.
+        ASTNode xor_node = bm.CreateNode(XOR, cond_dividend, cond_divisor);
+        ASTNode n = bm.CreateTerm(ITE, len, xor_node, bm.CreateTerm(BVUMINUS, len, divnode), divnode);
+
+        return bm.SimplifyTerm_TopLevel(n);
+      }
+
+    FatalError("TranslateSignedDivModRem: input must be signed DIV/MOD/REM", in);
+    return bm.CreateNode(UNDEFINED);
+
+  }//end of TranslateSignedDivModRem()
+
+  // Check that the transformations have occurred.
+  void assertTransformPostConditions(const ASTNode & term)
+  {
+    const Kind k = term.GetKind();
+
+    // Check the signed operations have been removed.
+    assert( SBVDIV != k);
+    assert( SBVMOD != k);
+    assert( SBVREM !=k);
+
+    // Check the array reads / writes have been removed
+    assert( READ !=k );
+    assert( WRITE !=k);
+
+    // There should be no nodes left of type array.
+    assert(0 == term.GetIndexWidth());
+
+    ASTVec c = term.GetChildren();
+    ASTVec::iterator it = c.begin();
+    ASTVec::iterator itend = c.end();
+    ASTVec o;
+    for (; it != itend; it++)
+      {
+        assertTransformPostConditions(*it);
+      }
+  }
+
+  ASTNode TransformFormula(const ASTNode& form)
+  {
+    BeevMgr& bm = form.GetBeevMgr();
+
+    assert(TransformMap != null);
+
+    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 = bm.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 = bm.CreateNode(k, c);
+          break;
+        }
+      case EQ:
+        {
+          ASTNode term1 = TransformTerm(simpleForm[0]);
+          ASTNode term2 = TransformTerm(simpleForm[1]);
+          result = bm.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 = bm.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: ", bm.CreateNode(UNDEFINED), k);
+          }
+        break;
+      }
+
+    if (simpleForm.GetChildren().size() > 0)
+      (*TransformMap)[simpleForm] = result;
+    return result;
+  } //End of TransformFormula
+
+  ASTNode TransformTerm(const ASTNode& inputterm)
+  {
+    assert(TransformMap != null);
+
+    BeevMgr& bm = inputterm.GetBeevMgr();
+
+    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 = bm.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 = bm.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 = bm.CreateTerm(k, width, o);
+          result.SetIndexWidth(indexwidth);
+
+          Kind k = result.GetKind();
+
+          if (BVDIV == k || BVMOD == k || SBVDIV == k || SBVREM == k || SBVMOD == k)
+            {
+              ASTNode bottom = result[1];
+
+              if (SBVDIV == result.GetKind() || SBVREM == result.GetKind() || SBVMOD == result.GetKind())
+                {
+                  result = TranslateSignedDivModRem(result);
+                }
+
+              if (division_by_zero_returns_one)
+                {
+                  // This is a difficult rule to introduce in other places because it's recursive. i.e.
+                  // result is embedded unchanged inside the result.
+
+                  unsigned inputValueWidth = result.GetValueWidth();
+                  ASTNode zero = bm.CreateZeroConst(inputValueWidth);
+                  ASTNode one = bm.CreateOneConst(inputValueWidth);
+                  result = bm.CreateTerm(ITE, inputValueWidth, bm.CreateNode(EQ, zero, bottom), one, result);
+                }
+            }
+        }
+        ////////////////////////////////////////////////////////////////////////////////////
+
+
+        break;
+      }
+
+    if (term.GetChildren().size() > 0)
+      (*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)
  *
  */
+  ASTNode BeevMgr::TransformArray(const ASTNode& term)
+  {
+    assert(TransformMap != null);
+
+    ASTNode result = term;
+
+    const unsigned int width = term.GetValueWidth();
+
+    if (READ != term.GetKind())
+      FatalError("TransformArray: input term is of wrong kind: ", ASTUndefined);
+
+    ASTNodeMap::iterator iter;
+    if ((iter = TransformMap->find(term)) != TransformMap->end())
+      return iter->second;
+
+    //'term' is of the form READ(arrName, readIndex)
+    const ASTNode & arrName = term[0];
+    const ASTNode & readIndex = TransformTerm(term[1]);
+
+    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 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.
+          const ASTVec & readIndices = _arrayname_readindices[arrName];
+
+          //construct the ITE structure for this array-read
+          ASTNode ite = CurrentSymbol;
+          _introduced_symbols.insert(CurrentSymbol);
+          assert(BVTypeCheck(ite));
+
+          if (arrayread_refinement_flag)
+            {
+              // ite is really a variable here; it is an ite in the
+              // else-branch
+              result = ite;
+            }
+          else
+            {
+              // Full Array transform if we're not doing read refinement.
+              ASTVec::const_reverse_iterator it2 = readIndices.rbegin();
+              ASTVec::const_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);
+                  assert(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 writeIndex = TransformTerm(arrName[1]);
+          ASTNode writeVal = TransformTerm(arrName[2]);
+
+          if (ARRAY_TYPE != arrName[0].GetType())
+            FatalError("TransformArray: An array write is being attempted on a non-array:", term);
+
+          if ((SYMBOL == arrName[0].GetKind() || WRITE == arrName[0].GetKind()))
+            {
+              ASTNode cond = CreateSimplifiedEQ(writeIndex, readIndex);
+              BVTypeCheck(cond);
+
+              ASTNode readTerm = CreateTerm(READ, width, arrName[0], readIndex);
+              BVTypeCheck(readTerm);
+
+              ASTNode readPushedIn = TransformArray(readTerm);
+              BVTypeCheck(readPushedIn);
+
+              result = CreateSimplifiedTermITE(cond, writeVal, readPushedIn);
+
+              BVTypeCheck(result);
+            }
+          else if (ITE == arrName[0].GetKind())
+            {
+              // pull out the ite from the write // pushes the write through.
+              ASTNode writeTrue = CreateNode(WRITE, (arrName[0][1]), writeIndex, writeVal);
+              writeTrue.SetIndexWidth(writeIndex.GetValueWidth());
+              writeTrue.SetValueWidth(writeVal.GetValueWidth());
+              assert(ARRAY_TYPE == writeTrue.GetType());
+
+              ASTNode writeFalse = CreateNode(WRITE, (arrName[0][2]), writeIndex, writeVal);
+              writeFalse.SetIndexWidth(writeIndex.GetValueWidth());
+              writeFalse.SetValueWidth(writeVal.GetValueWidth());
+              assert(ARRAY_TYPE == writeFalse.GetType());
+
+              result = CreateSimplifiedTermITE(TransformFormula(arrName[0][0]), writeTrue, writeFalse);
+              result.SetIndexWidth(writeIndex.GetValueWidth());
+              result.SetValueWidth(writeVal.GetValueWidth());
+              assert(ARRAY_TYPE == result.GetType());
+
+              result = CreateTerm(READ, writeVal.GetValueWidth(), result, readIndex);
+              BVTypeCheck(result);
+              result = TransformArray(result);
+            }
+          else
+            FatalError("TransformArray: Write over bad type.");
+          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))
+           */
+
+          // pull out the ite from the read // pushes the read through.
+
+          //(ITE cond thn els)
+
+          ASTNode cond = arrName[0];
+          cond = TransformFormula(cond);
+
+          const ASTNode& thn = arrName[1];
+          const ASTNode& els = arrName[2];
+
+          //(READ thn j)
+          ASTNode thnRead = CreateTerm(READ, width, thn, readIndex);
+          BVTypeCheck(thnRead);
+          thnRead = TransformArray(thnRead);
+
+          //(READ els j)
+          ASTNode elsRead = CreateTerm(READ, width, els, readIndex);
+          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;
+      }
+
+    (*TransformMap)[term] = result;
+    return result;
+  } //end of TransformArray()
+
+  ASTNode BeevMgr::TransformFiniteFor(const ASTNode& form)
+  {
+    return form;
+  }
 
 } //end of namespace BEEV
index f2a8c60f166d2dba53e713d2748656e1ed84f249..1baafe5bcb8211ea21db22d29d65dc0d6b14741a 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 7fd5c95c28596a123c60e257716a11244d6e9a15..900ddc361cac104355ab59891202d7ab835d21a9 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 2c337c447c003670b816ae6cb34616d3a7ed5626..7db61663a1fbc6a401e1de89fb6094986fa0d281 100644 (file)
@@ -8,40 +8,40 @@ using namespace BEEV;
 
 int main()
 {
-       const int size = 1;
+  const int size = 1;
 
-       BeevMgr *bm = new BeevMgr();
-       ASTNode s1 = bm->CreateSymbol("x");
-       s1.SetValueWidth(size);
+  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 << "s1" << s1 << endl;
+  ASTNode s2 = bm->CreateSymbol("y");
+  s2.SetValueWidth(size);
 
-       cout << "s2" << s2 << endl;
-       ASTNode s3 = bm->CreateSymbol("z");
-       s3.SetValueWidth(size);
+  cout << "s2" << s2 << endl;
+  ASTNode s3 = bm->CreateSymbol("z");
+  s3.SetValueWidth(size);
 
-       cout << "s3" << s3 << endl;
+  cout << "s3" << s3 << endl;
 
-       ASTNode bbs1 = bm->BBForm(s1);
-       cout << "bitblasted s1" << endl << bbs1 << endl;
-       bm->PrintClauseList(cout, bm->ToCNF(bbs1));
+  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 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 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;
+  ASTNode a4 = bm->CreateNode(EQ, s1, s2);
+  ASTNode bba4 = bm->BBForm(a4);
+  cout << "bitblasted a4 " << endl << bba4 << endl;
 
-       bm->PrintClauseList(cout, bm->ToCNF(bba4));
+  bm->PrintClauseList(cout, bm->ToCNF(bba4));
 
 }
index 2a54a80b6e07b131d286eb92704f25bb2fd5bb00..adacde631fc35a21d9556790721419374a500761 100644 (file)
 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);
-}
-
-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:
-               case BVSRSHIFT:
-               {
-                       bool msb = CONSTANTBV::BitVector_msb_(tmp0);
-
-                       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);
-
-                       if (BVSRSHIFT == k && msb)
-                       {
-                               // signed shift, and the number was originally negative.
-                               // Shift may be larger than the inputwidth.
-                               for (unsigned int i = 0; i < min(shift, inputwidth); i++)
-                               {
-                                       CONSTANTBV::BitVector_Bit_On(output, (inputwidth - 1 - i));
-                               }
-                               assert(CONSTANTBV::BitVector_Sign(output) == -1); //must be negative.
-                       }
-
-                       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;
-               }
-
-                       // SBVREM : Result of rounding the quotient towards zero. i.e. (-10)/3, has a remainder of -1
-                       // SBVMOD : Result of rounding the quotient towards -infinity. i.e. (-10)/3, has a modulus of 2.
-                       //          EXCEPT THAT if it divides exactly and the signs are different, then it's equal to the dividend.
-               case SBVDIV:
-               case SBVREM:
-               {
-                       CBV quotient = CONSTANTBV::BitVector_Create(inputwidth, true);
-                       CBV remainder = CONSTANTBV::BitVector_Create(inputwidth, true);
-
-                       if (division_by_zero_returns_one && CONSTANTBV::BitVector_is_empty(tmp1))
-                       {
-                               // Expecting a division by zero. Just return one.
-                               OutputNode = CreateOneConst(outputwidth);
-                       }
-                       else
-                       {
-                               CONSTANTBV::ErrCode e = CONSTANTBV::BitVector_Divide(quotient, tmp0, tmp1, remainder);
-
-                               if (e != 0)
-                               {
-                                       cerr << "WARNING" << endl;
-                                       FatalError((const char*) CONSTANTBV::BitVector_Error(e));
-                               }
-
-                               if (SBVDIV == k)
-                               {
-                                       OutputNode = CreateBVConst(quotient, outputwidth);
-                                       CONSTANTBV::BitVector_Destroy(remainder);
-                               }
-                               else
-                               {
-                                       OutputNode = CreateBVConst(remainder, outputwidth);
-                                       CONSTANTBV::BitVector_Destroy(quotient);
-
-                               }
-                       }
-                       break;
-               }
-
-               case SBVMOD:
-               {
-                       /* Definition taken from the SMTLIB website
-                        (bvsmod s t) abbreviates
-                        (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)))))))
-                        */
-
-                       assert(t[0].GetValueWidth() == t[1].GetValueWidth());
-
-                       bool isNegativeS = CONSTANTBV::BitVector_msb_(tmp0);
-                       bool isNegativeT = CONSTANTBV::BitVector_msb_(tmp1);
-
-                       CBV quotient = CONSTANTBV::BitVector_Create(inputwidth, true);
-                       CBV remainder = CONSTANTBV::BitVector_Create(inputwidth, true);
-                       tmp0 = CONSTANTBV::BitVector_Clone(tmp0);
-                       tmp1 = CONSTANTBV::BitVector_Clone(tmp1);
-
-                       if (division_by_zero_returns_one && CONSTANTBV::BitVector_is_empty(tmp1))
-                       {
-                               // Expecting a division by zero. Just return one.
-                               OutputNode = CreateOneConst(outputwidth);
-
-                       }
-                       else
-                       {
-                               if (!isNegativeS && !isNegativeT)
-                               {
-                                       // Signs are both positive
-                                       CONSTANTBV::ErrCode e = CONSTANTBV::BitVector_Div_Pos(quotient, tmp0, tmp1, remainder);
-                                       if (e != CONSTANTBV::ErrCode_Ok)
-                                       {
-                                               cerr << "Error code was:" << e << endl;
-                                               assert(e == CONSTANTBV::ErrCode_Ok);
-                                       }
-                                       OutputNode = CreateBVConst(remainder, outputwidth);
-                               }
-                               else if (isNegativeS && !isNegativeT)
-                               {
-                                       // S negative, T positive.
-                                       CBV tmp0b = CONSTANTBV::BitVector_Create(inputwidth, true);
-                                       CONSTANTBV::BitVector_Negate(tmp0b, tmp0);
-
-                                       CONSTANTBV::ErrCode e = CONSTANTBV::BitVector_Div_Pos(quotient, tmp0b, tmp1, remainder);
-
-                                       assert(e == CONSTANTBV::ErrCode_Ok);
-
-                                       CBV remb = CONSTANTBV::BitVector_Create(inputwidth, true);
-                                       CONSTANTBV::BitVector_Negate(remb, remainder);
-
-                                       bool carry = false;
-                                       CBV res = CONSTANTBV::BitVector_Create(inputwidth, true);
-                                       CONSTANTBV::BitVector_add(res, remb, tmp1, &carry);
-
-                                       OutputNode = CreateBVConst(res, outputwidth);
-
-                                       CONSTANTBV::BitVector_Destroy(tmp0b);
-                                       CONSTANTBV::BitVector_Destroy(remb);
-                                       CONSTANTBV::BitVector_Destroy(remainder);
-                               }
-                               else if (!isNegativeS && isNegativeT)
-                               {
-                                       // If s is positive and t is negative
-                                       CBV tmp1b = CONSTANTBV::BitVector_Create(inputwidth, true);
-                                       CONSTANTBV::BitVector_Negate(tmp1b, tmp1);
-
-                                       CONSTANTBV::ErrCode e = CONSTANTBV::BitVector_Div_Pos(quotient, tmp0, tmp1b, remainder);
-
-                                       assert(e == CONSTANTBV::ErrCode_Ok);
-
-                                       bool carry = false;
-                                       CBV res = CONSTANTBV::BitVector_Create(inputwidth, true);
-                                       CONSTANTBV::BitVector_add(res, remainder, tmp1, &carry);
-
-                                       OutputNode = CreateBVConst(res, outputwidth);
-
-                                       CONSTANTBV::BitVector_Destroy(tmp1b);
-                                       CONSTANTBV::BitVector_Destroy(remainder);
-                               }
-                               else if (isNegativeS && isNegativeT)
-                               {
-                                       // Signs are both negative
-                                       CBV tmp0b = CONSTANTBV::BitVector_Create(inputwidth, true);
-                                       CBV tmp1b = CONSTANTBV::BitVector_Create(inputwidth, true);
-                                       CONSTANTBV::BitVector_Negate(tmp0b, tmp0);
-                                       CONSTANTBV::BitVector_Negate(tmp1b, tmp1);
-
-                                       CONSTANTBV::ErrCode e = CONSTANTBV::BitVector_Div_Pos(quotient, tmp0b, tmp1b, remainder);
-                                       assert(e == CONSTANTBV::ErrCode_Ok);
-
-                                       CBV remb = CONSTANTBV::BitVector_Create(inputwidth, true);
-                                       CONSTANTBV::BitVector_Negate(remb, remainder);
-
-                                       OutputNode = CreateBVConst(remb, outputwidth);
-                                       CONSTANTBV::BitVector_Destroy(tmp0b);
-                                       CONSTANTBV::BitVector_Destroy(tmp1b);
-                                       CONSTANTBV::BitVector_Destroy(remainder);
-                               }
-                               else
-                               {
-                                       FatalError("never get called");
-                               }
-                       }
-
-                       CONSTANTBV::BitVector_Destroy(tmp0);
-                       CONSTANTBV::BitVector_Destroy(tmp1);
-                       CONSTANTBV::BitVector_Destroy(quotient);
-               }
-                       break;
-
-               case BVDIV:
-               case BVMOD:
-               {
-                       CBV quotient = CONSTANTBV::BitVector_Create(inputwidth, true);
-                       CBV remainder = CONSTANTBV::BitVector_Create(inputwidth, true);
-
-                       if (division_by_zero_returns_one && CONSTANTBV::BitVector_is_empty(tmp1))
-                       {
-                               // Expecting a division by zero. Just return one.
-                               OutputNode = CreateOneConst(outputwidth);
-                       }
-                       else
-                       {
-
-                               // 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:
-               {
-                       ASTNode tmp0 = t[0]; // Should this run BVConstEvaluator??
-
-                       if (ASTTrue == tmp0)
-                               OutputNode = BVConstEvaluator(t[1]);
-                       else if (ASTFalse == tmp0)
-                               OutputNode = BVConstEvaluator(t[2]);
-                       else
-                       {
-                               cerr << tmp0;
-                               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;
-} //End of BVConstEvaluator
+  //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);
+  }
+
+  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:
+      case BVSRSHIFT:
+        {
+          bool msb = CONSTANTBV::BitVector_msb_(tmp0);
+
+          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);
+
+          if (BVSRSHIFT == k && msb)
+            {
+              // signed shift, and the number was originally negative.
+              // Shift may be larger than the inputwidth.
+              for (unsigned int i = 0; i < min(shift, inputwidth); i++)
+                {
+                  CONSTANTBV::BitVector_Bit_On(output, (inputwidth - 1 - i));
+                }
+              assert(CONSTANTBV::BitVector_Sign(output) == -1); //must be negative.
+            }
+
+          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;
+        }
+
+        // SBVREM : Result of rounding the quotient towards zero. i.e. (-10)/3, has a remainder of -1
+        // SBVMOD : Result of rounding the quotient towards -infinity. i.e. (-10)/3, has a modulus of 2.
+        //          EXCEPT THAT if it divides exactly and the signs are different, then it's equal to the dividend.
+      case SBVDIV:
+      case SBVREM:
+        {
+          CBV quotient = CONSTANTBV::BitVector_Create(inputwidth, true);
+          CBV remainder = CONSTANTBV::BitVector_Create(inputwidth, true);
+
+          if (division_by_zero_returns_one && CONSTANTBV::BitVector_is_empty(tmp1))
+            {
+              // Expecting a division by zero. Just return one.
+              OutputNode = CreateOneConst(outputwidth);
+            }
+          else
+            {
+              CONSTANTBV::ErrCode e = CONSTANTBV::BitVector_Divide(quotient, tmp0, tmp1, remainder);
+
+              if (e != 0)
+                {
+                  cerr << "WARNING" << endl;
+                  FatalError((const char*) CONSTANTBV::BitVector_Error(e));
+                }
+
+              if (SBVDIV == k)
+                {
+                  OutputNode = CreateBVConst(quotient, outputwidth);
+                  CONSTANTBV::BitVector_Destroy(remainder);
+                }
+              else
+                {
+                  OutputNode = CreateBVConst(remainder, outputwidth);
+                  CONSTANTBV::BitVector_Destroy(quotient);
+
+                }
+            }
+          break;
+        }
+
+      case SBVMOD:
+        {
+          /* Definition taken from the SMTLIB website
+             (bvsmod s t) abbreviates
+             (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)))))))
+          */
+
+          assert(t[0].GetValueWidth() == t[1].GetValueWidth());
+
+          bool isNegativeS = CONSTANTBV::BitVector_msb_(tmp0);
+          bool isNegativeT = CONSTANTBV::BitVector_msb_(tmp1);
+
+          CBV quotient = CONSTANTBV::BitVector_Create(inputwidth, true);
+          CBV remainder = CONSTANTBV::BitVector_Create(inputwidth, true);
+          tmp0 = CONSTANTBV::BitVector_Clone(tmp0);
+          tmp1 = CONSTANTBV::BitVector_Clone(tmp1);
+
+          if (division_by_zero_returns_one && CONSTANTBV::BitVector_is_empty(tmp1))
+            {
+              // Expecting a division by zero. Just return one.
+              OutputNode = CreateOneConst(outputwidth);
+
+            }
+          else
+            {
+              if (!isNegativeS && !isNegativeT)
+                {
+                  // Signs are both positive
+                  CONSTANTBV::ErrCode e = CONSTANTBV::BitVector_Div_Pos(quotient, tmp0, tmp1, remainder);
+                  if (e != CONSTANTBV::ErrCode_Ok)
+                    {
+                      cerr << "Error code was:" << e << endl;
+                      assert(e == CONSTANTBV::ErrCode_Ok);
+                    }
+                  OutputNode = CreateBVConst(remainder, outputwidth);
+                }
+              else if (isNegativeS && !isNegativeT)
+                {
+                  // S negative, T positive.
+                  CBV tmp0b = CONSTANTBV::BitVector_Create(inputwidth, true);
+                  CONSTANTBV::BitVector_Negate(tmp0b, tmp0);
+
+                  CONSTANTBV::ErrCode e = CONSTANTBV::BitVector_Div_Pos(quotient, tmp0b, tmp1, remainder);
+
+                  assert(e == CONSTANTBV::ErrCode_Ok);
+
+                  CBV remb = CONSTANTBV::BitVector_Create(inputwidth, true);
+                  CONSTANTBV::BitVector_Negate(remb, remainder);
+
+                  bool carry = false;
+                  CBV res = CONSTANTBV::BitVector_Create(inputwidth, true);
+                  CONSTANTBV::BitVector_add(res, remb, tmp1, &carry);
+
+                  OutputNode = CreateBVConst(res, outputwidth);
+
+                  CONSTANTBV::BitVector_Destroy(tmp0b);
+                  CONSTANTBV::BitVector_Destroy(remb);
+                  CONSTANTBV::BitVector_Destroy(remainder);
+                }
+              else if (!isNegativeS && isNegativeT)
+                {
+                  // If s is positive and t is negative
+                  CBV tmp1b = CONSTANTBV::BitVector_Create(inputwidth, true);
+                  CONSTANTBV::BitVector_Negate(tmp1b, tmp1);
+
+                  CONSTANTBV::ErrCode e = CONSTANTBV::BitVector_Div_Pos(quotient, tmp0, tmp1b, remainder);
+
+                  assert(e == CONSTANTBV::ErrCode_Ok);
+
+                  bool carry = false;
+                  CBV res = CONSTANTBV::BitVector_Create(inputwidth, true);
+                  CONSTANTBV::BitVector_add(res, remainder, tmp1, &carry);
+
+                  OutputNode = CreateBVConst(res, outputwidth);
+
+                  CONSTANTBV::BitVector_Destroy(tmp1b);
+                  CONSTANTBV::BitVector_Destroy(remainder);
+                }
+              else if (isNegativeS && isNegativeT)
+                {
+                  // Signs are both negative
+                  CBV tmp0b = CONSTANTBV::BitVector_Create(inputwidth, true);
+                  CBV tmp1b = CONSTANTBV::BitVector_Create(inputwidth, true);
+                  CONSTANTBV::BitVector_Negate(tmp0b, tmp0);
+                  CONSTANTBV::BitVector_Negate(tmp1b, tmp1);
+
+                  CONSTANTBV::ErrCode e = CONSTANTBV::BitVector_Div_Pos(quotient, tmp0b, tmp1b, remainder);
+                  assert(e == CONSTANTBV::ErrCode_Ok);
+
+                  CBV remb = CONSTANTBV::BitVector_Create(inputwidth, true);
+                  CONSTANTBV::BitVector_Negate(remb, remainder);
+
+                  OutputNode = CreateBVConst(remb, outputwidth);
+                  CONSTANTBV::BitVector_Destroy(tmp0b);
+                  CONSTANTBV::BitVector_Destroy(tmp1b);
+                  CONSTANTBV::BitVector_Destroy(remainder);
+                }
+              else
+                {
+                  FatalError("never get called");
+                }
+            }
+
+          CONSTANTBV::BitVector_Destroy(tmp0);
+          CONSTANTBV::BitVector_Destroy(tmp1);
+          CONSTANTBV::BitVector_Destroy(quotient);
+        }
+        break;
+
+      case BVDIV:
+      case BVMOD:
+        {
+          CBV quotient = CONSTANTBV::BitVector_Create(inputwidth, true);
+          CBV remainder = CONSTANTBV::BitVector_Create(inputwidth, true);
+
+          if (division_by_zero_returns_one && CONSTANTBV::BitVector_is_empty(tmp1))
+            {
+              // Expecting a division by zero. Just return one.
+              OutputNode = CreateOneConst(outputwidth);
+            }
+          else
+            {
+
+              // 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:
+        {
+          ASTNode tmp0 = t[0]; // Should this run BVConstEvaluator??
+
+          if (ASTTrue == tmp0)
+            OutputNode = BVConstEvaluator(t[1]);
+          else if (ASTFalse == tmp0)
+            OutputNode = BVConstEvaluator(t[2]);
+          else
+            {
+              cerr << tmp0;
+              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;
+  } //End of BVConstEvaluator
 }; //end of namespace BEEV
index e5dbbcad832e6aef24df6097663e8acda6a12bce..b0e3b9941071b7ac0334439879574e5810d2ce1a 100644 (file)
@@ -129,12 +129,12 @@ void vc_printExpr(VC vc, Expr e) {
 
 char * vc_printSMTLIB(VC vc, Expr e) 
 {
-       stringstream ss;
- printer::SMTLIB_Print(ss,*((nodestar)e), 0);
+  stringstream ss;
 printer::SMTLIB_Print(ss,*((nodestar)e), 0);
   string s = ss.str();
   char *copy = strdup(s.c_str());
   return copy;
-       
+        
 }
 
 // prints Expr 'e' to stdout as C code
@@ -384,12 +384,12 @@ int vc_query(VC vc, Expr e) {
   nodestar a = (nodestar)e;
   bmstar b = (bmstar)vc;
 
- if(!BEEV::is_Form_kind(a->GetKind()))
 if(!BEEV::is_Form_kind(a->GetKind()))
     BEEV::FatalError("CInterface: Trying to QUERY a NON formula: ",*a);
 
- //printf("kill all humans\n");
- //a->LispPrint(cout, 0);
- //printf("##################################################\n");
 //printf("kill all humans\n");
 //a->LispPrint(cout, 0);
 //printf("##################################################\n");
   b->BVTypeCheck(*a);
   b->AddQuery(*a);
 
@@ -481,7 +481,7 @@ int vc_getBVLength(VC vc, Expr ex) {
 //! Create a variable with a given name and type 
 /*! The type cannot be a function type. */
 Expr vc_varExpr1(VC vc, char* name, 
-               int indexwidth, int valuewidth) {
+                 int indexwidth, int valuewidth) {
   bmstar b = (bmstar)vc;
 
   node o = b->CreateSymbol(name);
@@ -729,7 +729,7 @@ Type vc_bvType(VC vc, int num_bits) {
   
   if(!(0 < num_bits))
     BEEV::FatalError("CInterface: number of bits in a bvtype must be a positive integer:", 
-                    b->CreateNode(BEEV::UNDEFINED));
+                     b->CreateNode(BEEV::UNDEFINED));
 
   node e = b->CreateBVConst(32, num_bits);
   nodestar output = new node(b->CreateNode(BEEV::BITVECTOR,e));
@@ -765,8 +765,8 @@ Expr vc_bvConstExprFromStr(VC vc, char* binary_repr) {
 }
 
 Expr vc_bvConstExprFromInt(VC vc,
-                          int n_bits, 
-                          unsigned int value) {
+                           int n_bits, 
+                           unsigned int value) {
   bmstar b = (bmstar)vc;
 
   unsigned long long int v = (unsigned long long int)value;
@@ -778,8 +778,8 @@ Expr vc_bvConstExprFromInt(VC vc,
 }
 
 Expr vc_bvConstExprFromLL(VC vc,
-                         int n_bits, 
-                         unsigned long long value) {
+                          int n_bits, 
+                          unsigned long long value) {
   bmstar b = (bmstar)vc;
   
   node n = b->CreateBVConst(n_bits, value);
@@ -798,7 +798,7 @@ Expr vc_bvConcatExpr(VC vc, Expr left, Expr right) {
   b->BVTypeCheck(*r);
   node o =
     b->CreateTerm(BEEV::BVCONCAT,
-                 l->GetValueWidth()+ r->GetValueWidth(),*l,*r);
+                  l->GetValueWidth()+ r->GetValueWidth(),*l,*r);
   b->BVTypeCheck(o);
   nodestar output = new node(o);
   //if(cinterface_exprdelete_on) created_exprs.push_back(output);
@@ -1179,10 +1179,10 @@ Expr vc_bvVar32LeftShiftExpr(VC vc, Expr sh_amt, Expr child) {
   for(int count=32; count >= 0; count--){
     if(count != 32) {
       ifpart = vc_eqExpr(vc, sh_amt, 
-                        vc_bvConstExprFromInt(vc, shift_width, count));
+                         vc_bvConstExprFromInt(vc, shift_width, count));
       thenpart = vc_bvExtract(vc,
-                             vc_bvLeftShiftExpr(vc, count, child),
-                             child_width-1, 0);
+                              vc_bvLeftShiftExpr(vc, count, child),
+                              child_width-1, 0);
 
       ite = vc_iteExpr(vc,ifpart,thenpart,elsepart);
       elsepart = ite;
@@ -1202,7 +1202,7 @@ Expr vc_bvVar32DivByPowOfTwoExpr(VC vc, Expr child, Expr rhs) {
   for(int count=32; count >= 0; count--){
     if(count != 32) {
       ifpart = vc_eqExpr(vc, rhs, 
-                        vc_bvConstExprFromInt(vc, 32, 1 << count));      
+                         vc_bvConstExprFromInt(vc, 32, 1 << count));      
       thenpart = vc_bvRightShiftExpr(vc, count, child);      
       ite = vc_iteExpr(vc,ifpart,thenpart,elsepart);
       elsepart = ite;
@@ -1227,7 +1227,7 @@ Expr vc_bvVar32RightShiftExpr(VC vc, Expr sh_amt, Expr child) {
   for(int count=32; count >= 0; count--){
     if(count != 32) {
       ifpart = vc_eqExpr(vc, sh_amt, 
-                        vc_bvConstExprFromInt(vc, shift_width, count));      
+                         vc_bvConstExprFromInt(vc, shift_width, count));      
       thenpart = vc_bvRightShiftExpr(vc, count, child);      
       ite = vc_iteExpr(vc,ifpart,thenpart,elsepart);
       elsepart = ite;
@@ -1325,7 +1325,7 @@ unsigned long long int getBVUnsignedLongLong(Expr e) {
 
   if(BEEV::BVCONST != a->GetKind())
     BEEV::FatalError("getBVUnsigned: Attempting to extract int value"\
-                    "from a NON-constant BITVECTOR: ",*a);
+                     "from a NON-constant BITVECTOR: ",*a);
   unsigned* bv = a->GetBVConst();
 
   char * str_bv  = (char *)CONSTANTBV::BitVector_to_Bin(bv);
@@ -1369,8 +1369,8 @@ Expr vc_bvCreateMemoryArray(VC vc, char * arrayName) {
 }
 
 Expr vc_bvReadMemoryArray(VC vc, 
-                         Expr array, 
-                         Expr byteIndex, int numOfBytes) {
+                          Expr array, 
+                          Expr byteIndex, int numOfBytes) {
   if(!(numOfBytes > 0))
     BEEV::FatalError("numOfBytes must be greater than 0");
 
@@ -1381,10 +1381,10 @@ Expr vc_bvReadMemoryArray(VC vc,
     Expr a = vc_readExpr(vc,array,byteIndex);
     while(--numOfBytes > 0) {
       Expr b = vc_readExpr(vc,array,
-                          /*vc_simplify(vc, */
-                                      vc_bvPlusExpr(vc, 32, 
-                                                    byteIndex,
-                                                    vc_bvConstExprFromInt(vc,32,count)))/*)*/;
+                           /*vc_simplify(vc, */
+                           vc_bvPlusExpr(vc, 32, 
+                                         byteIndex,
+                                         vc_bvConstExprFromInt(vc,32,count)))/*)*/;
       a = vc_bvConcatExpr(vc,b,a);
       count++;
     }
@@ -1393,11 +1393,11 @@ Expr vc_bvReadMemoryArray(VC vc,
 }
 
 Expr vc_bvWriteToMemoryArray(VC vc, 
-                            Expr array, Expr byteIndex, 
-                            Expr element, int numOfBytes) {
+                             Expr array, Expr byteIndex, 
+                             Expr element, int numOfBytes) {
   if(!(numOfBytes > 0))
     BEEV::FatalError("numOfBytes must be greater than 0");
-           
+            
   int newBitsPerElem = numOfBytes*8;
   if(numOfBytes == 1)
     return vc_writeExpr(vc, array, byteIndex, element);
@@ -1418,9 +1418,9 @@ Expr vc_bvWriteToMemoryArray(VC vc,
 
       c = vc_bvExtract(vc, element, hi_elem, low_elem);
       newarray = 
-       vc_writeExpr(vc, newarray,
-                    vc_bvPlusExpr(vc, 32, byteIndex, vc_bvConstExprFromInt(vc,32,count)),
-                    c);
+        vc_writeExpr(vc, newarray,
+                     vc_bvPlusExpr(vc, 32, byteIndex, vc_bvConstExprFromInt(vc,32,count)),
+                     c);
       count++;
     }
     return newarray;
@@ -1434,17 +1434,17 @@ Expr vc_bv32ConstExprFromInt(VC vc, unsigned int value){
 
 #if 0
 static char *val_to_binary_str(unsigned nbits, unsigned long long val) {
-        char s[65];
-
-       assert(nbits < sizeof s);
-        strcpy(s, "");
-        while(nbits-- > 0) {
-                if((val >> nbits) & 1)
-                        strcat(s, "1");
-                else
-                        strcat(s, "0");
-        }
-        return strdup(s);
+  char s[65];
+
+  assert(nbits < sizeof s);
+  strcpy(s, "");
+  while(nbits-- > 0) {
+    if((val >> nbits) & 1)
+      strcat(s, "1");
+    else
+      strcat(s, "0");
+  }
+  return strdup(s);
 }
 #endif
 
@@ -1569,7 +1569,7 @@ int vc_isBool(Expr e) {
 void vc_Destroy(VC vc) {
   bmstar b = (bmstar)vc;
   // for(std::vector<BEEV::ASTNode *>::iterator it=created_exprs.begin(),
-  //   itend=created_exprs.end();it!=itend;it++) {
+  //    itend=created_exprs.end();it!=itend;it++) {
   //     BEEV::ASTNode * aaa = *it;
   //     delete aaa;
   //   }
@@ -1631,11 +1631,11 @@ void vc_printCounterExampleFile(VC vc, int fd) {
 }
 
 const char* exprName(Expr e){
-    return ((nodestar)e)->GetName();
+  return ((nodestar)e)->GetName();
 }
 
 int getExprID (Expr ex) {
-    BEEV::ASTNode q = (*(nodestar)ex);
+  BEEV::ASTNode q = (*(nodestar)ex);
 
-    return q.GetNodeNum();
+  return q.GetNodeNum();
 }
index 78ebf4a220a2c55372047d5020e168e23518b7ed..0f4d1d5de1f041c3ee7e8d325cec8f37731b5af6 100644 (file)
@@ -65,7 +65,7 @@ extern "C" {
   //The var name can contain only variables, numerals and
   //underscore. If you use any other symbol, you will get a segfault.
   Expr vc_varExpr1(VC vc, char* name, 
-                 int indexwidth, int valuewidth);
+                   int indexwidth, int valuewidth);
 
   //! Get the expression and type associated with a name.
   /*!  If there is no such Expr, a NULL Expr is returned. */
@@ -120,7 +120,7 @@ extern "C" {
   //! Prints 'e' to stdout as C code
   void vc_printExprCCode(VC vc, Expr e);
 
-       //! print in smtlib format
+  //! print in smtlib format
   char * vc_printSMTLIB(VC vc, Expr e);
 
   //! Prints 'e' into an open file descriptor 'fd'
@@ -152,7 +152,7 @@ extern "C" {
   //simplify_print must be set to "1" if you wish simplification to
   //occur dring printing. It must be set to "0" otherwise
   void vc_printQueryStateToBuffer(VC vc, Expr e, 
-                                 char **buf, unsigned long *len, int simplify_print);
+                                  char **buf, unsigned long *len, int simplify_print);
 
   //! Similar to vc_printQueryStateToBuffer()
   void vc_printCounterExampleToBuffer(VC vc, char **buf,unsigned long *len);
@@ -206,7 +206,7 @@ extern "C" {
   Type vc_bvType(VC vc, int no_bits);
   Type vc_bv32Type(VC vc);
   
-  Expr vc_bvConstExprFromDecStr(VC vc, const size_t width, char* decimalInput );               
+  Expr vc_bvConstExprFromDecStr(VC vc, const size_t width, char* decimalInput );                
   Expr vc_bvConstExprFromStr(VC vc, char* binary_repr);
   Expr vc_bvConstExprFromInt(VC vc, int n_bits, unsigned int value);
   Expr vc_bvConstExprFromLL(VC vc, int n_bits, unsigned long long value);
@@ -268,10 +268,10 @@ extern "C" {
   /*C pointer support:  C interface to support C memory arrays in CVCL */
   Expr vc_bvCreateMemoryArray(VC vc, char * arrayName);
   Expr vc_bvReadMemoryArray(VC vc, 
-                         Expr array, Expr byteIndex, int numOfBytes);
+                            Expr array, Expr byteIndex, int numOfBytes);
   Expr vc_bvWriteToMemoryArray(VC vc, 
-                              Expr array, Expr  byteIndex, 
-                              Expr element, int numOfBytes);
+                               Expr array, Expr  byteIndex, 
+                               Expr element, int numOfBytes);
   Expr vc_bv32ConstExprFromInt(VC vc, unsigned int value);
   
   // return a string representation of the Expr e. The caller is responsible
@@ -310,68 +310,68 @@ extern "C" {
 
   //Kinds of Expr
   enum exprkind_t{
-      UNDEFINED,
-      SYMBOL,
-      BVCONST,
-      BVNEG,
-      BVCONCAT,
-      BVOR,
-      BVAND,
-      BVXOR,
-      BVNAND,
-      BVNOR,
-      BVXNOR,
-      BVEXTRACT,
-      BVLEFTSHIFT,
-      BVRIGHTSHIFT,
-      BVSRSHIFT,
-      BVVARSHIFT,
-      BVPLUS,
-      BVSUB,
-      BVUMINUS,
-      BVMULTINVERSE,
-      BVMULT,
-      BVDIV,
-      BVMOD,
-      SBVDIV,
-      SBVREM,
-      BVSX,
-      BOOLVEC,
-      ITE,
-      BVGETBIT,
-      BVLT,
-      BVLE,
-      BVGT,
-      BVGE,
-      BVSLT,
-      BVSLE,
-      BVSGT,
-      BVSGE,
-      EQ,
-      NEQ,
-      FALSE,
-      TRUE,
-      NOT,
-      AND,
-      OR,
-      NAND,
-      NOR,
-      XOR,
-      IFF,
-      IMPLIES,
-      READ,
-      WRITE,
-      ARRAY,
-      BITVECTOR,
-      BOOLEAN,
+    UNDEFINED,
+    SYMBOL,
+    BVCONST,
+    BVNEG,
+    BVCONCAT,
+    BVOR,
+    BVAND,
+    BVXOR,
+    BVNAND,
+    BVNOR,
+    BVXNOR,
+    BVEXTRACT,
+    BVLEFTSHIFT,
+    BVRIGHTSHIFT,
+    BVSRSHIFT,
+    BVVARSHIFT,
+    BVPLUS,
+    BVSUB,
+    BVUMINUS,
+    BVMULTINVERSE,
+    BVMULT,
+    BVDIV,
+    BVMOD,
+    SBVDIV,
+    SBVREM,
+    BVSX,
+    BOOLVEC,
+    ITE,
+    BVGETBIT,
+    BVLT,
+    BVLE,
+    BVGT,
+    BVGE,
+    BVSLT,
+    BVSLE,
+    BVSGT,
+    BVSGE,
+    EQ,
+    NEQ,
+    FALSE,
+    TRUE,
+    NOT,
+    AND,
+    OR,
+    NAND,
+    NOR,
+    XOR,
+    IFF,
+    IMPLIES,
+    READ,
+    WRITE,
+    ARRAY,
+    BITVECTOR,
+    BOOLEAN,
   };
 
   // type of expression
   enum type_t {
-      BOOLEAN_TYPE = 0,
-      BITVECTOR_TYPE,
-      ARRAY_TYPE,
-      UNKNOWN_TYPE
+    BOOLEAN_TYPE = 0,
+    BITVECTOR_TYPE,
+    ARRAY_TYPE,
+    UNKNOWN_TYPE
   };
 
   // get the kind of the expression
index 2cff613cf12ddb27aa811702d86e11dcb567253a..0c7bfdfff742b9d2fc53e31f39c68f09259de29f 100644 (file)
 namespace std {
 
 
-/************************************************************
- * fdostream
- * - a stream that writes on a file descriptor
- ************************************************************/
+  /************************************************************
  * fdostream
  * - a stream that writes on a file descriptor
  ************************************************************/
 
 
-class fdoutbuf : public std::streambuf {
+  class fdoutbuf : public std::streambuf {
   protected:
     int fd;    // file descriptor
   public:
@@ -69,38 +69,38 @@ class fdoutbuf : public std::streambuf {
   protected:
     // write one character
     virtual int_type overflow (int_type c) {
-        if (c != EOF) {
-            char z = c;
-            if (write (fd, &z, 1) != 1) {
-                return EOF;
-            }
+      if (c != EOF) {
+        char z = c;
+        if (write (fd, &z, 1) != 1) {
+          return EOF;
         }
-        return c;
+      }
+      return c;
     }
     // write multiple characters
     virtual
-    std::streamsize xsputn (const char* s,
-                            std::streamsize num) {
-        return write(fd,s,num);
+      std::streamsize xsputn (const char* s,
+                              std::streamsize num) {
+      return write(fd,s,num);
     }
-};
+  };
 
-class fdostream : public std::ostream {
+  class fdostream : public std::ostream {
   protected:
     fdoutbuf buf;
   public:
     fdostream (int fd) : std::ostream(0), buf(fd) {
-        rdbuf(&buf);
+      rdbuf(&buf);
     }
-};
+  };
 
 
-/************************************************************
- * fdistream
- * - a stream that reads on a file descriptor
- ************************************************************/
+  /************************************************************
  * fdistream
  * - a stream that reads on a file descriptor
  ************************************************************/
 
-class fdinbuf : public std::streambuf {
+  class fdinbuf : public std::streambuf {
   protected:
     int fd;    // file descriptor
   protected:
@@ -120,65 +120,65 @@ class fdinbuf : public std::streambuf {
      * => force underflow()
      */
     fdinbuf (int _fd) : fd(_fd) {
-        setg (buffer+pbSize,     // beginning of putback area
-              buffer+pbSize,     // read position
-              buffer+pbSize);    // end position
+      setg (buffer+pbSize,     // beginning of putback area
+            buffer+pbSize,     // read position
+            buffer+pbSize);    // end position
     }
 
   protected:
     // insert new characters into the buffer
     virtual int_type underflow () {
 #ifndef _MSC_VER
-        using std::memmove;
+      using std::memmove;
 #endif
 
-        // is read position before end of buffer?
-        if (gptr() < egptr()) {
-            return traits_type::to_int_type(*gptr());
-        }
-
-        /* process size of putback area
-         * - use number of characters read
-         * - but at most size of putback area
-         */
-        int numPutback;
-        numPutback = gptr() - eback();
-        if (numPutback > pbSize) {
-            numPutback = pbSize;
-        }
-
-        /* copy up to pbSize characters previously read into
-         * the putback area
-         */
-        memmove (buffer+(pbSize-numPutback), gptr()-numPutback,
-                numPutback);
-
-        // read at most bufSize new characters
-        int num;
-        num = read (fd, buffer+pbSize, bufSize);
-        if (num <= 0) {
-            // ERROR or EOF
-            return EOF;
-        }
-
-        // reset buffer pointers
-        setg (buffer+(pbSize-numPutback),   // beginning of putback area
-              buffer+pbSize,                // read position
-              buffer+pbSize+num);           // end of buffer
-
-        // return next character
+      // is read position before end of buffer?
+      if (gptr() < egptr()) {
         return traits_type::to_int_type(*gptr());
+      }
+
+      /* process size of putback area
+       * - use number of characters read
+       * - but at most size of putback area
+       */
+      int numPutback;
+      numPutback = gptr() - eback();
+      if (numPutback > pbSize) {
+        numPutback = pbSize;
+      }
+
+      /* copy up to pbSize characters previously read into
+       * the putback area
+       */
+      memmove (buffer+(pbSize-numPutback), gptr()-numPutback,
+               numPutback);
+
+      // read at most bufSize new characters
+      int num;
+      num = read (fd, buffer+pbSize, bufSize);
+      if (num <= 0) {
+        // ERROR or EOF
+        return EOF;
+      }
+
+      // reset buffer pointers
+      setg (buffer+(pbSize-numPutback),   // beginning of putback area
+            buffer+pbSize,                // read position
+            buffer+pbSize+num);           // end of buffer
+
+      // return next character
+      return traits_type::to_int_type(*gptr());
     }
-};
+  };
 
-class fdistream : public std::istream {
+  class fdistream : public std::istream {
   protected:
     fdinbuf buf;
   public:
     fdistream (int fd) : std::istream(0), buf(fd) {
-        rdbuf(&buf);
+      rdbuf(&buf);
     }
-};
+  };
 
 
 } // END namespace boost
index d874d43b8755c4b19eac528ccb5e2543389c6725..cd05ed37283f6c265cbeb8092bcb9c9470c0e9d7 100644 (file)
 #include "constantbv.h"
 
 namespace CONSTANTBV {
-/*****************************************************************************/
-/*  MODULE IMPLEMENTATION:                                                   */
-/*****************************************************************************/
-    /**********************************************/
-    /* global implementation-intrinsic constants: */
-    /**********************************************/
+  /*****************************************************************************/
+  /*  MODULE IMPLEMENTATION:                                                   */
+  /*****************************************************************************/
+  /**********************************************/
+  /* global implementation-intrinsic constants: */
+  /**********************************************/
 
 #define BIT_VECTOR_HIDDEN_WORDS 3
 
-    /*****************************************************************/
-    /* global machine-dependent constants (set by "BitVector_Boot"): */
-    /*****************************************************************/
+  /*****************************************************************/
+  /* global machine-dependent constants (set by "BitVector_Boot"): */
+  /*****************************************************************/
 
-static unsigned int BITS;     /* = # of bits in machine word (must be power of 2)  */
-static unsigned int MODMASK;  /* = BITS - 1 (mask for calculating modulo BITS)     */
-static unsigned int LOGBITS;  /* = ld(BITS) (logarithmus dualis)                   */
-static unsigned int FACTOR;   /* = ld(BITS / 8) (ld of # of bytes)                 */
+  static unsigned int BITS;     /* = # of bits in machine word (must be power of 2)  */
+  static unsigned int MODMASK;  /* = BITS - 1 (mask for calculating modulo BITS)     */
+  static unsigned int LOGBITS;  /* = ld(BITS) (logarithmus dualis)                   */
+  static unsigned int FACTOR;   /* = ld(BITS / 8) (ld of # of bytes)                 */
 
-static unsigned int LSB = 1;  /* = mask for least significant bit                  */
-static unsigned int MSB;      /* = mask for most significant bit                   */
+  static unsigned int LSB = 1;  /* = mask for least significant bit                  */
+  static unsigned int MSB;      /* = mask for most significant bit                   */
 
-static unsigned int LONGBITS; /* = # of bits in unsigned long                      */
+  static unsigned int LONGBITS; /* = # of bits in unsigned long                      */
 
-static unsigned int LOG10;    /* = logarithm to base 10 of BITS - 1                */
-static unsigned int EXP10;    /* = largest possible power of 10 in signed int      */
+  static unsigned int LOG10;    /* = logarithm to base 10 of BITS - 1                */
+  static unsigned int EXP10;    /* = largest possible power of 10 in signed int      */
 
-    /********************************************************************/
-    /* global bit mask table for fast access (set by "BitVector_Boot"): */
-    /********************************************************************/
+  /********************************************************************/
+  /* global bit mask table for fast access (set by "BitVector_Boot"): */
+  /********************************************************************/
 
-static unsigned int BITMASKTAB[sizeof(unsigned int) << 3];
+  static unsigned int BITMASKTAB[sizeof(unsigned int) << 3];
 
-    /*****************************/
-    /* global macro definitions: */
-    /*****************************/
+  /*****************************/
+  /* global macro definitions: */
+  /*****************************/
 
 #define BIT_VECTOR_ZERO_WORDS(target,count) \
     while (count-- > 0) *target++ = 0;
@@ -118,97 +118,97 @@ static unsigned int BITMASKTAB[sizeof(unsigned int) << 3];
     digit -= value * 10; \
     digit += (type) '0';
 
-    /*********************************************************/
-    /* private low-level functions (potentially dangerous!): */
-    /*********************************************************/
+  /*********************************************************/
+  /* private low-level functions (potentially dangerous!): */
+  /*********************************************************/
 
-static unsigned int power10(unsigned int x) {
+  static unsigned int power10(unsigned int x) {
     unsigned int y = 1;
 
     while (x-- > 0) y *= 10;
     return(y);
-}
+  }
 
-static void BIT_VECTOR_zro_words(unsigned int *  addr, unsigned int count) {
+  static void BIT_VECTOR_zro_words(unsigned int *  addr, unsigned int count) {
     BIT_VECTOR_ZERO_WORDS(addr,count)
-}
+      }
 
-static void BIT_VECTOR_cpy_words(unsigned int *  target, 
-                                unsigned int *  source, unsigned int count) {
+  static void BIT_VECTOR_cpy_words(unsigned int *  target, 
+                                   unsigned int *  source, unsigned int count) {
     BIT_VECTOR_COPY_WORDS(target,source,count)
-}
+      }
 
-static void BIT_VECTOR_mov_words(unsigned int *  target, 
-                                unsigned int *  source, unsigned int count) {
+  static void BIT_VECTOR_mov_words(unsigned int *  target, 
+                                   unsigned int *  source, unsigned int count) {
     if (target != source) {
-        if (target < source) BIT_VECTOR_COPY_WORDS(target,source,count)
-        else                 BIT_VECTOR_BACK_WORDS(target,source,count)
-    }
-}
+      if (target < source) BIT_VECTOR_COPY_WORDS(target,source,count)
+                             else                 BIT_VECTOR_BACK_WORDS(target,source,count)
+                                                    }
+  }
 
-static void BIT_VECTOR_ins_words(unsigned int *  addr, 
-                                unsigned int total, unsigned int count, boolean clear) {
+  static void BIT_VECTOR_ins_words(unsigned int *  addr, 
+                                   unsigned int total, unsigned int count, boolean clear) {
     unsigned int length;
 
     if ((total > 0) && (count > 0)) {
-        if (count > total) count = total;
-        length = total - count;
-        if (length > 0) BIT_VECTOR_mov_words(addr+count,addr,length);
-        if (clear)      BIT_VECTOR_zro_words(addr,count);
+      if (count > total) count = total;
+      length = total - count;
+      if (length > 0) BIT_VECTOR_mov_words(addr+count,addr,length);
+      if (clear)      BIT_VECTOR_zro_words(addr,count);
     }
-}
+  }
 
-static void BIT_VECTOR_del_words(unsigned int *  addr, 
-                                unsigned int total, unsigned int count, boolean clear) {
+  static void BIT_VECTOR_del_words(unsigned int *  addr, 
+                                   unsigned int total, unsigned int count, boolean clear) {
     unsigned int length;
 
     if ((total > 0) && (count > 0)) {
-        if (count > total) count = total;
-        length = total - count;
-        if (length > 0) BIT_VECTOR_mov_words(addr,addr+count,length);
-        if (clear)      BIT_VECTOR_zro_words(addr+length,count);
+      if (count > total) count = total;
+      length = total - count;
+      if (length > 0) BIT_VECTOR_mov_words(addr,addr+count,length);
+      if (clear)      BIT_VECTOR_zro_words(addr+length,count);
     }
-}
+  }
 
-static void BIT_VECTOR_reverse(unsigned char * string, unsigned int length) {
+  static void BIT_VECTOR_reverse(unsigned char * string, unsigned int length) {
     unsigned char * last;
     unsigned char  temp;
 
     if (length > 1) {
-        last = string + length - 1;
-        while (string < last) {
-            temp = *string;
-            *string = *last;
-            *last = temp;
-            string++;
-            last--;
-        }
+      last = string + length - 1;
+      while (string < last) {
+        temp = *string;
+        *string = *last;
+        *last = temp;
+        string++;
+        last--;
+      }
     }
-}
+  }
 
-static unsigned int BIT_VECTOR_int2str(unsigned char * string, unsigned int value) {
+  static unsigned int BIT_VECTOR_int2str(unsigned char * string, unsigned int value) {
     unsigned int  length;
     unsigned int  digit;
     unsigned char * work;
 
     work = string;
     if (value > 0) {
-        length = 0;
-        while (value > 0) {
-            BIT_VECTOR_DIGITIZE(unsigned int,value,digit)
-            *work++ = (unsigned char) digit;
-            length++;
-        }
-        BIT_VECTOR_reverse(string,length);
+      length = 0;
+      while (value > 0) {
+        BIT_VECTOR_DIGITIZE(unsigned int,value,digit)
+          *work++ = (unsigned char) digit;
+        length++;
+      }
+      BIT_VECTOR_reverse(string,length);
     }
     else {
-        length = 1;
-        *work++ = (unsigned char) '0';
+      length = 1;
+      *work++ = (unsigned char) '0';
     }
     return(length);
-}
+  }
 
-static unsigned int BIT_VECTOR_str2int(unsigned char * string, unsigned int *value) {
+  static unsigned int BIT_VECTOR_str2int(unsigned char * string, unsigned int *value) {
     unsigned int  length;
     unsigned int  digit;
 
@@ -217,55 +217,55 @@ static unsigned int BIT_VECTOR_str2int(unsigned char * string, unsigned int *val
     digit = (unsigned int) *string++;
     /* separate because isdigit() is likely a macro! */
     while (isdigit((int)digit) != 0) {
-        length++;
-        digit -= (unsigned int) '0';
-        if (*value) *value *= 10;
-        *value += digit;
-        digit = (unsigned int) *string++;
+      length++;
+      digit -= (unsigned int) '0';
+      if (*value) *value *= 10;
+      *value += digit;
+      digit = (unsigned int) *string++;
     }
     return(length);
-}
+  }
 
-    /********************************************/
-    /* routine to convert error code to string: */
-    /********************************************/
+  /********************************************/
+  /* routine to convert error code to string: */
+  /********************************************/
 
-unsigned char * BitVector_Error(ErrCode error) {
+  unsigned char * BitVector_Error(ErrCode error) {
     switch (error) {
-        case ErrCode_Ok:   return( (unsigned char *)     NULL     ); break;
-        case ErrCode_Type: return( (unsigned char *) ERRCODE_TYPE ); break;
-        case ErrCode_Bits: return( (unsigned char *) ERRCODE_BITS ); break;
-        case ErrCode_Word: return( (unsigned char *) ERRCODE_WORD ); break;
-        case ErrCode_Long: return( (unsigned char *) ERRCODE_LONG ); break;
-        case ErrCode_Powr: return( (unsigned char *) ERRCODE_POWR ); break;
-        case ErrCode_Loga: return( (unsigned char *) ERRCODE_LOGA ); break;
-        case ErrCode_Null: return( (unsigned char *) ERRCODE_NULL ); break;
-        case ErrCode_Indx: return( (unsigned char *) ERRCODE_INDX ); break;
-        case ErrCode_Ordr: return( (unsigned char *) ERRCODE_ORDR ); break;
-        case ErrCode_Size: return( (unsigned char *) ERRCODE_SIZE ); break;
-        case ErrCode_Pars: return( (unsigned char *) ERRCODE_PARS ); break;
-        case ErrCode_Ovfl: return( (unsigned char *) ERRCODE_OVFL ); break;
-        case ErrCode_Same: return( (unsigned char *) ERRCODE_SAME ); break;
-        case ErrCode_Expo: return( (unsigned char *) ERRCODE_EXPO ); break;
-        case ErrCode_Zero: return( (unsigned char *) ERRCODE_ZERO ); break;
-        default:           return( (unsigned char *) ERRCODE_OOPS ); break;
+    case ErrCode_Ok:   return( (unsigned char *)     NULL     ); break;
+    case ErrCode_Type: return( (unsigned char *) ERRCODE_TYPE ); break;
+    case ErrCode_Bits: return( (unsigned char *) ERRCODE_BITS ); break;
+    case ErrCode_Word: return( (unsigned char *) ERRCODE_WORD ); break;
+    case ErrCode_Long: return( (unsigned char *) ERRCODE_LONG ); break;
+    case ErrCode_Powr: return( (unsigned char *) ERRCODE_POWR ); break;
+    case ErrCode_Loga: return( (unsigned char *) ERRCODE_LOGA ); break;
+    case ErrCode_Null: return( (unsigned char *) ERRCODE_NULL ); break;
+    case ErrCode_Indx: return( (unsigned char *) ERRCODE_INDX ); break;
+    case ErrCode_Ordr: return( (unsigned char *) ERRCODE_ORDR ); break;
+    case ErrCode_Size: return( (unsigned char *) ERRCODE_SIZE ); break;
+    case ErrCode_Pars: return( (unsigned char *) ERRCODE_PARS ); break;
+    case ErrCode_Ovfl: return( (unsigned char *) ERRCODE_OVFL ); break;
+    case ErrCode_Same: return( (unsigned char *) ERRCODE_SAME ); break;
+    case ErrCode_Expo: return( (unsigned char *) ERRCODE_EXPO ); break;
+    case ErrCode_Zero: return( (unsigned char *) ERRCODE_ZERO ); break;
+    default:           return( (unsigned char *) ERRCODE_OOPS ); break;
     }
-}
-
-    /*****************************************/
-    /* automatic self-configuration routine: */
-    /*****************************************/
-
-    /*******************************************************/
-    /*                                                     */
-    /*   MUST be called once prior to any other function   */
-    /*   to initialize the machine dependent constants     */
-    /*   of this package! (But call only ONCE, or you      */
-    /*   will suffer memory leaks!)                        */
-    /*                                                     */
-    /*******************************************************/
-
-ErrCode BitVector_Boot(void) {
+  }
+
+  /*****************************************/
+  /* automatic self-configuration routine: */
+  /*****************************************/
+
+  /*******************************************************/
+  /*                                                     */
+  /*   MUST be called once prior to any other function   */
+  /*   to initialize the machine dependent constants     */
+  /*   of this package! (But call only ONCE, or you      */
+  /*   will suffer memory leaks!)                        */
+  /*                                                     */
+  /*******************************************************/
+
+  ErrCode BitVector_Boot(void) {
     unsigned long longsample = 1L;
     unsigned int sample = LSB;
     unsigned int lsb;
@@ -288,8 +288,8 @@ ErrCode BitVector_Boot(void) {
     sample = BITS;
     lsb = (sample & LSB);
     while ((sample >>= 1) && (! lsb)) {
-        LOGBITS++;
-        lsb = (sample & LSB);
+      LOGBITS++;
+      lsb = (sample & LSB);
     }
 
     if (sample) return(ErrCode_Powr);      /* # of bits is not a power of 2! */
@@ -301,90 +301,90 @@ ErrCode BitVector_Boot(void) {
     MSB = (LSB << MODMASK);
 
     for ( sample = 0; sample < BITS; sample++ ) {
-        BITMASKTAB[sample] = (LSB << sample);
+      BITMASKTAB[sample] = (LSB << sample);
     }
 
     LOG10 = (unsigned int) (MODMASK * 0.30103); /* = (BITS - 1) * ( ln 2 / ln 10 ) */
     EXP10 = power10(LOG10);
 
     return(ErrCode_Ok);
-}
+  }
 
-unsigned int BitVector_Size(unsigned int bits) {          /* bit vector size (# of words)  */
+  unsigned int BitVector_Size(unsigned int bits) {          /* bit vector size (# of words)  */
     unsigned int size;
 
     size = bits >> LOGBITS;
     if (bits & MODMASK) size++;
     return(size);
-}
+  }
 
-unsigned int BitVector_Mask(unsigned int bits)           /* bit vector mask (unused bits) */
-{
+  unsigned int BitVector_Mask(unsigned int bits)           /* bit vector mask (unused bits) */
+  {
     unsigned int mask;
 
     mask = bits & MODMASK;
     if (mask) mask = (unsigned int) ~(~0L << mask); else mask = (unsigned int) ~0L;
     return(mask);
-}
+  }
 
-unsigned char * BitVector_Version(void)
-{
+  unsigned char * BitVector_Version(void)
+  {
     return((unsigned char *)"6.4");
-}
+  }
 
-unsigned int BitVector_Word_Bits(void)
-{
+  unsigned int BitVector_Word_Bits(void)
+  {
     return(BITS);
-}
+  }
 
-unsigned int BitVector_Long_Bits(void)
-{
+  unsigned int BitVector_Long_Bits(void)
+  {
     return(LONGBITS);
-}
-
-/********************************************************************/
-/*                                                                  */
-/*  WARNING: Do not "free()" constant character strings, i.e.,      */
-/*           don't call "BitVector_Dispose()" for strings returned  */
-/*           by "BitVector_Error()" or "BitVector_Version()"!       */
-/*                                                                  */
-/*  ONLY call this function for strings allocated with "malloc()",  */
-/*  i.e., the strings returned by the functions "BitVector_to_*()"  */
-/*  and "BitVector_Block_Read()"!                                   */
-/*                                                                  */
-/********************************************************************/
-
-void BitVector_Dispose(unsigned char * string)                      /* free string   */
-{
+  }
+
+  /********************************************************************/
+  /*                                                                  */
+  /*  WARNING: Do not "free()" constant character strings, i.e.,      */
+  /*           don't call "BitVector_Dispose()" for strings returned  */
+  /*           by "BitVector_Error()" or "BitVector_Version()"!       */
+  /*                                                                  */
+  /*  ONLY call this function for strings allocated with "malloc()",  */
+  /*  i.e., the strings returned by the functions "BitVector_to_*()"  */
+  /*  and "BitVector_Block_Read()"!                                   */
+  /*                                                                  */
+  /********************************************************************/
+
+  void BitVector_Dispose(unsigned char * string)                      /* free string   */
+  {
     if (string != NULL) free((void *) string);
-}
+  }
 
-void BitVector_Destroy(unsigned int *  addr)                        /* free bitvec   */
-{
+  void BitVector_Destroy(unsigned int *  addr)                        /* free bitvec   */
+  {
     if (addr != NULL)
-    {
+      {
         addr -= BIT_VECTOR_HIDDEN_WORDS;
         free((void *) addr);
-    }
-}
+      }
+  }
 
-void BitVector_Destroy_List(unsigned int *  *  list, unsigned int count)      /* free list     */
-{
+  void BitVector_Destroy_List(unsigned int *  *  list, unsigned int count)      /* free list     */
+  {
     unsigned int *  *  slot;
 
     if (list != NULL)
-    {
+      {
         slot = list;
         while (count-- > 0)
-        {
+          {
             BitVector_Destroy(*slot++);
-        }
+          }
         free((void *) list);
-    }
-}
+      }
+  }
 
-unsigned int *  BitVector_Create(unsigned int bits, boolean clear)         /* malloc        */
-{
+  unsigned int *  BitVector_Create(unsigned int bits, boolean clear)         /* malloc        */
+  {
     unsigned int  size;
     unsigned int  mask;
     unsigned int  bytes;
@@ -396,49 +396,49 @@ unsigned int *  BitVector_Create(unsigned int bits, boolean clear)         /* ma
     bytes = (size + BIT_VECTOR_HIDDEN_WORDS) << FACTOR;
     addr = (unsigned int * ) malloc((size_t) bytes);
     if (addr != NULL)
-    {
+      {
         *addr++ = bits;
         *addr++ = size;
         *addr++ = mask;
         if (clear)
-        {
+          {
             zero = addr;
             BIT_VECTOR_ZERO_WORDS(zero,size)
-        }
-    }
+              }
+      }
     return(addr);
-}
+  }
 
-unsigned int *  *  BitVector_Create_List(unsigned int bits, boolean clear, unsigned int count)
-{
+  unsigned int *  *  BitVector_Create_List(unsigned int bits, boolean clear, unsigned int count)
+  {
     unsigned int *  *  list = NULL;
     unsigned int *  *  slot;
     unsigned int *  addr;
     unsigned int   i;
 
     if (count > 0)
-    {
+      {
         list = (unsigned int *  * ) malloc(sizeof(unsigned int * ) * count);
         if (list != NULL)
-        {
+          {
             slot = list;
             for ( i = 0; i < count; i++ )
-            {
+              {
                 addr = BitVector_Create(bits,clear);
                 if (addr == NULL)
-                {
+                  {
                     BitVector_Destroy_List(list,i);
                     return(NULL);
-                }
+                  }
                 *slot++ = addr;
-            }
-        }
-    }
+              }
+          }
+      }
     return(list);
-}
+  }
 
-unsigned int *  BitVector_Resize(unsigned int *  oldaddr, unsigned int bits)       /* realloc       */
-{
+  unsigned int *  BitVector_Resize(unsigned int *  oldaddr, unsigned int bits)       /* realloc       */
+  {
     unsigned int  bytes;
     unsigned int  oldsize;
     unsigned int  oldmask;
@@ -454,19 +454,19 @@ unsigned int *  BitVector_Resize(unsigned int *  oldaddr, unsigned int bits)
     newmask = BitVector_Mask(bits);
     if (oldsize > 0) *(oldaddr+oldsize-1) &= oldmask;
     if (newsize <= oldsize)
-    {
+      {
         newaddr = oldaddr;
         bits_(newaddr) = bits;
         size_(newaddr) = newsize;
         mask_(newaddr) = newmask;
         if (newsize > 0) *(newaddr+newsize-1) &= newmask;
-    }
+      }
     else
-    {
+      {
         bytes = (newsize + BIT_VECTOR_HIDDEN_WORDS) << FACTOR;
         newaddr = (unsigned int * ) malloc((size_t) bytes);
         if (newaddr != NULL)
-        {
+          {
             *newaddr++ = bits;
             *newaddr++ = newsize;
             *newaddr++ = newmask;
@@ -474,32 +474,32 @@ unsigned int *  BitVector_Resize(unsigned int *  oldaddr, unsigned int bits)
             source = oldaddr;
             newsize -= oldsize;
             BIT_VECTOR_COPY_WORDS(target,source,oldsize)
-            BIT_VECTOR_ZERO_WORDS(target,newsize)
-        }
+              BIT_VECTOR_ZERO_WORDS(target,newsize)
+              }
         BitVector_Destroy(oldaddr);
-    }
+      }
     return(newaddr);
-}
+  }
 
-unsigned int *  BitVector_Shadow(unsigned int *  addr)     /* makes new, same size but empty */
-{
+  unsigned int *  BitVector_Shadow(unsigned int *  addr)     /* makes new, same size but empty */
+  {
     return( BitVector_Create(bits_(addr),true) );
-}
+  }
 
-unsigned int *  BitVector_Clone(unsigned int *  addr)               /* makes exact duplicate */
-{
+  unsigned int *  BitVector_Clone(unsigned int *  addr)               /* makes exact duplicate */
+  {
     unsigned int  bits;
     unsigned int *  twin;
 
     bits = bits_(addr);
     twin = BitVector_Create(bits,false);
     if ((twin != NULL) && (bits > 0))
-        BIT_VECTOR_cpy_words(twin,addr,size_(addr));
+      BIT_VECTOR_cpy_words(twin,addr,size_(addr));
     return(twin);
-}
+  }
 
-unsigned int *  BitVector_Concat(unsigned int *  X, unsigned int *  Y)      /* returns concatenation */
-{
+  unsigned int *  BitVector_Concat(unsigned int *  X, unsigned int *  Y)      /* returns concatenation */
+  {
     /* BEWARE that X = most significant part, Y = least significant part! */
 
     unsigned int  bitsX;
@@ -512,16 +512,16 @@ unsigned int *  BitVector_Concat(unsigned int *  X, unsigned int *  Y)      /* r
     bitsZ = bitsX + bitsY;
     Z = BitVector_Create(bitsZ,false);
     if ((Z != NULL) && (bitsZ > 0))
-    {
+      {
         BIT_VECTOR_cpy_words(Z,Y,size_(Y));
         BitVector_Interval_Copy(Z,X,bitsY,0,bitsX);
         *(Z+size_(Z)-1) &= mask_(Z);
-    }
+      }
     return(Z);
-}
+  }
 
-void BitVector_Copy(unsigned int *  X, unsigned int *  Y)                           /* X = Y */
-{
+  void BitVector_Copy(unsigned int *  X, unsigned int *  Y)                           /* X = Y */
+  {
     unsigned int  sizeX = size_(X);
     unsigned int  sizeY = size_(Y);
     unsigned int  maskX = mask_(X);
@@ -531,65 +531,65 @@ void BitVector_Copy(unsigned int *  X, unsigned int *  Y)
     unsigned int *  lastY;
 
     if ((X != Y) && (sizeX > 0))
-    {
+      {
         lastX = X + sizeX - 1;
         if (sizeY > 0)
-        {
+          {
             lastY = Y + sizeY - 1;
             if ( (*lastY & (maskY & ~ (maskY >> 1))) == 0 ) *lastY &= maskY;
             else
-            {
+              {
                 fill = (unsigned int) ~0L;
                 *lastY |= ~ maskY;
-            }
+              }
             while ((sizeX > 0) && (sizeY > 0))
-            {
+              {
                 *X++ = *Y++;
                 sizeX--;
                 sizeY--;
-            }
+              }
             *lastY &= maskY;
-        }
+          }
         while (sizeX-- > 0) *X++ = fill;
         *lastX &= maskX;
-    }
-}
+      }
+  }
 
-void BitVector_Empty(unsigned int *  addr)                        /* X = {}  clr all */
-{
+  void BitVector_Empty(unsigned int *  addr)                        /* X = {}  clr all */
+  {
     unsigned int size = size_(addr);
 
     BIT_VECTOR_ZERO_WORDS(addr,size)
-}
+      }
 
-void BitVector_Fill(unsigned int *  addr)                         /* X = ~{} set all */
-{
+  void BitVector_Fill(unsigned int *  addr)                         /* X = ~{} set all */
+  {
     unsigned int size = size_(addr);
     unsigned int mask = mask_(addr);
     unsigned int fill = (unsigned int) ~0L;
 
     if (size > 0)
-    {
+      {
         BIT_VECTOR_FILL_WORDS(addr,fill,size)
-        *(--addr) &= mask;
-    }
-}
+          *(--addr) &= mask;
+      }
+  }
 
-void BitVector_Flip(unsigned int *  addr)                         /* X = ~X flip all */
-{
+  void BitVector_Flip(unsigned int *  addr)                         /* X = ~X flip all */
+  {
     unsigned int size = size_(addr);
     unsigned int mask = mask_(addr);
     unsigned int flip = (unsigned int) ~0L;
 
     if (size > 0)
-    {
+      {
         BIT_VECTOR_FLIP_WORDS(addr,flip,size)
-        *(--addr) &= mask;
-    }
-}
+          *(--addr) &= mask;
+      }
+  }
 
-void BitVector_Primes(unsigned int *  addr)
-{
+  void BitVector_Primes(unsigned int *  addr)
+  {
     unsigned int  bits = bits_(addr);
     unsigned int  size = size_(addr);
     unsigned int *  work;
@@ -597,69 +597,69 @@ void BitVector_Primes(unsigned int *  addr)
     unsigned int  i,j;
 
     if (size > 0)
-    {
+      {
         temp = 0xAAAA;
         i = BITS >> 4;
         while (--i > 0)
-        {
+          {
             temp <<= 16;
             temp |= 0xAAAA;
-        }
+          }
         i = size;
         work = addr;
         *work++ = temp ^ 0x0006;
         while (--i > 0) *work++ = temp;
         for ( i = 3; (j = i * i) < bits; i += 2 )
-        {
+          {
             for ( ; j < bits; j += i ) BIT_VECTOR_CLR_BIT(addr,j)
-        }
+                                         }
         *(addr+size-1) &= mask_(addr);
-    }
-}
+      }
+  }
 
-void BitVector_Reverse(unsigned int *  X, unsigned int *  Y)
-{
+  void BitVector_Reverse(unsigned int *  X, unsigned int *  Y)
+  {
     unsigned int bits = bits_(X);
     unsigned int mask;
     unsigned int bit;
     unsigned int value;
 
     if (bits > 0)
-    {
+      {
         if (X == Y) BitVector_Interval_Reverse(X,0,bits-1);
         else if (bits == bits_(Y))
-        {
-/*          mask = mask_(Y);  */
-/*          mask &= ~ (mask >> 1);  */
+          {
+            /*          mask = mask_(Y);  */
+            /*          mask &= ~ (mask >> 1);  */
             mask = BITMASKTAB[(bits-1) & MODMASK];
             Y += size_(Y) - 1;
             value = 0;
             bit = LSB;
             while (bits-- > 0)
-            {
+              {
                 if ((*Y & mask) != 0)
-                {
+                  {
                     value |= bit;
-                }
+                  }
                 if (! (mask >>= 1))
-                {
+                  {
                     Y--;
                     mask = MSB;
-                }
+                  }
                 if (! (bit <<= 1))
-                {
+                  {
                     *X++ = value;
                     value = 0;
                     bit = LSB;
-                }
-            }
+                  }
+              }
             if (bit > LSB) *X = value;
-        }
-    }
-}
+          }
+      }
+  }
 
-void BitVector_Interval_Empty(unsigned int *  addr, unsigned int lower, unsigned int upper)
-{                                                  /* X = X \ [lower..upper] */
+  void BitVector_Interval_Empty(unsigned int *  addr, unsigned int lower, unsigned int upper)
+  {                                                  /* X = X \ [lower..upper] */
     unsigned int  bits = bits_(addr);
     unsigned int  size = size_(addr);
     unsigned int *  loaddr;
@@ -671,7 +671,7 @@ void BitVector_Interval_Empty(unsigned int *  addr, unsigned int lower, unsigned
     unsigned int  diff;
 
     if ((size > 0) && (lower < bits) && (upper < bits) && (lower <= upper))
-    {
+      {
         lobase = lower >> LOGBITS;
         hibase = upper >> LOGBITS;
         diff = hibase - lobase;
@@ -682,23 +682,23 @@ void BitVector_Interval_Empty(unsigned int *  addr, unsigned int lower, unsigned
         himask = (unsigned int) ~((~0L << (upper & MODMASK)) << 1);
 
         if (diff == 0)
-        {
+          {
             *loaddr &= ~ (lomask & himask);
-        }
+          }
         else
-        {
+          {
             *loaddr++ &= ~ lomask;
             while (--diff > 0)
-            {
+              {
                 *loaddr++ = 0;
-            }
+              }
             *hiaddr &= ~ himask;
-        }
-    }
-}
+          }
+      }
+  }
 
-void BitVector_Interval_Fill(unsigned int *  addr, unsigned int lower, unsigned int upper)
-{                                                  /* X = X + [lower..upper] */
+  void BitVector_Interval_Fill(unsigned int *  addr, unsigned int lower, unsigned int upper)
+  {                                                  /* X = X + [lower..upper] */
     unsigned int  bits = bits_(addr);
     unsigned int  size = size_(addr);
     unsigned int  fill = (unsigned int) ~0L;
@@ -711,7 +711,7 @@ void BitVector_Interval_Fill(unsigned int *  addr, unsigned int lower, unsigned
     unsigned int  diff;
 
     if ((size > 0) && (lower < bits) && (upper < bits) && (lower <= upper))
-    {
+      {
         lobase = lower >> LOGBITS;
         hibase = upper >> LOGBITS;
         diff = hibase - lobase;
@@ -722,24 +722,24 @@ void BitVector_Interval_Fill(unsigned int *  addr, unsigned int lower, unsigned
         himask = (unsigned int) ~((~0L << (upper & MODMASK)) << 1);
 
         if (diff == 0)
-        {
+          {
             *loaddr |= (lomask & himask);
-        }
+          }
         else
-        {
+          {
             *loaddr++ |= lomask;
             while (--diff > 0)
-            {
+              {
                 *loaddr++ = fill;
-            }
+              }
             *hiaddr |= himask;
-        }
+          }
         *(addr+size-1) &= mask_(addr);
-    }
-}
+      }
+  }
 
-void BitVector_Interval_Flip(unsigned int *  addr, unsigned int lower, unsigned int upper)
-{                                                  /* X = X ^ [lower..upper] */
+  void BitVector_Interval_Flip(unsigned int *  addr, unsigned int lower, unsigned int upper)
+  {                                                  /* X = X ^ [lower..upper] */
     unsigned int  bits = bits_(addr);
     unsigned int  size = size_(addr);
     unsigned int  flip = (unsigned int) ~0L;
@@ -752,7 +752,7 @@ void BitVector_Interval_Flip(unsigned int *  addr, unsigned int lower, unsigned
     unsigned int  diff;
 
     if ((size > 0) && (lower < bits) && (upper < bits) && (lower <= upper))
-    {
+      {
         lobase = lower >> LOGBITS;
         hibase = upper >> LOGBITS;
         diff = hibase - lobase;
@@ -763,24 +763,24 @@ void BitVector_Interval_Flip(unsigned int *  addr, unsigned int lower, unsigned
         himask = (unsigned int) ~((~0L << (upper & MODMASK)) << 1);
 
         if (diff == 0)
-        {
+          {
             *loaddr ^= (lomask & himask);
-        }
+          }
         else
-        {
+          {
             *loaddr++ ^= lomask;
             while (--diff > 0)
-            {
+              {
                 *loaddr++ ^= flip;
-            }
+              }
             *hiaddr ^= himask;
-        }
+          }
         *(addr+size-1) &= mask_(addr);
-    }
-}
+      }
+  }
 
-void BitVector_Interval_Reverse(unsigned int *  addr, unsigned int lower, unsigned int upper)
-{
+  void BitVector_Interval_Reverse(unsigned int *  addr, unsigned int lower, unsigned int upper)
+  {
     unsigned int  bits = bits_(addr);
     unsigned int *  loaddr;
     unsigned int *  hiaddr;
@@ -788,35 +788,35 @@ void BitVector_Interval_Reverse(unsigned int *  addr, unsigned int lower, unsign
     unsigned int  himask;
 
     if ((bits > 0) && (lower < bits) && (upper < bits) && (lower < upper))
-    {
+      {
         loaddr = addr + (lower >> LOGBITS);
         hiaddr = addr + (upper >> LOGBITS);
         lomask = BITMASKTAB[lower & MODMASK];
         himask = BITMASKTAB[upper & MODMASK];
         for ( bits = upper - lower + 1; bits > 1; bits -= 2 )
-        {
+          {
             if (((*loaddr & lomask) != 0) ^ ((*hiaddr & himask) != 0))
-            {
+              {
                 *loaddr ^= lomask;  /* swap bits only if they differ! */
                 *hiaddr ^= himask;
-            }
+              }
             if (! (lomask <<= 1))
-            {
+              {
                 lomask = LSB;
                 loaddr++;
-            }
+              }
             if (! (himask >>= 1))
-            {
+              {
                 himask = MSB;
                 hiaddr--;
-            }
-        }
-    }
-}
+              }
+          }
+      }
+  }
 
-boolean BitVector_interval_scan_inc(unsigned int *  addr, unsigned int start,
-                                    unsigned int * min, unsigned int * max)
-{
+  boolean BitVector_interval_scan_inc(unsigned int *  addr, unsigned int start,
+                                      unsigned int * min, unsigned int * max)
+  {
     unsigned int  size = size_(addr);
     unsigned int  mask = mask_(addr);
     unsigned int  offset;
@@ -841,56 +841,56 @@ boolean BitVector_interval_scan_inc(unsigned int *  addr, unsigned int start,
 
     value = *addr++;
     if ((value & bitmask) == 0)
-    {
+      {
         value &= mask;
         if (value == 0)
-        {
+          {
             offset++;
             empty = true;
             while (empty && (--size > 0))
-            {
+              {
                 if ((value = *addr++)) empty = false; else offset++;
-            }
+              }
             if (empty) return(false);
-        }
+          }
         start = offset << LOGBITS;
         bitmask = LSB;
         mask = value;
         while (! (mask & LSB))
-        {
+          {
             bitmask <<= 1;
             mask >>= 1;
             start++;
-        }
+          }
         mask = ~ (bitmask | (bitmask - 1));
         *min = start;
         *max = start;
-    }
+      }
     value = ~ value;
     value &= mask;
     if (value == 0)
-    {
+      {
         offset++;
         empty = true;
         while (empty && (--size > 0))
-        {
+          {
             if ((value = ~ *addr++)) empty = false; else offset++;
-        }
+          }
         if (empty) value = LSB;
-    }
+      }
     start = offset << LOGBITS;
     while (! (value & LSB))
-    {
+      {
         value >>= 1;
         start++;
-    }
+      }
     *max = --start;
     return(true);
-}
+  }
 
-boolean BitVector_interval_scan_dec(unsigned int *  addr, unsigned int start,
-                                    unsigned int * min, unsigned int * max)
-{
+  boolean BitVector_interval_scan_dec(unsigned int *  addr, unsigned int start,
+                                      unsigned int * min, unsigned int * max)
+  {
     unsigned int  size = size_(addr);
     unsigned int  mask = mask_(addr);
     unsigned int offset;
@@ -917,56 +917,56 @@ boolean BitVector_interval_scan_dec(unsigned int *  addr, unsigned int start,
 
     value = *addr--;
     if ((value & bitmask) == 0)
-    {
+      {
         value &= mask;
         if (value == 0)
-        {
+          {
             offset--;
             empty = true;
             while (empty && (--size > 0))
-            {
+              {
                 if ((value = *addr--)) empty = false; else offset--;
-            }
+              }
             if (empty) return(false);
-        }
+          }
         start = offset << LOGBITS;
         bitmask = MSB;
         mask = value;
         while (! (mask & MSB))
-        {
+          {
             bitmask >>= 1;
             mask <<= 1;
             start--;
-        }
+          }
         mask = (bitmask - 1);
         *max = --start;
         *min = start;
-    }
+      }
     value = ~ value;
     value &= mask;
     if (value == 0)
-    {
+      {
         offset--;
         empty = true;
         while (empty && (--size > 0))
-        {
+          {
             if ((value = ~ *addr--)) empty = false; else offset--;
-        }
+          }
         if (empty) value = MSB;
-    }
+      }
     start = offset << LOGBITS;
     while (! (value & MSB))
-    {
+      {
         value <<= 1;
         start--;
-    }
+      }
     *min = start;
     return(true);
-}
+  }
 
-void BitVector_Interval_Copy(unsigned int *  X, unsigned int *  Y, unsigned int Xoffset,
-                             unsigned int Yoffset, unsigned int length)
-{
+  void BitVector_Interval_Copy(unsigned int *  X, unsigned int *  Y, unsigned int Xoffset,
+                               unsigned int Yoffset, unsigned int length)
+  {
     unsigned int  bitsX = bits_(X);
     unsigned int  bitsY = bits_(Y);
     unsigned int  source = 0;        /* silence compiler warning */
@@ -998,7 +998,7 @@ void BitVector_Interval_Copy(unsigned int *  X, unsigned int *  Y, unsigned int
     unsigned int *  Z = X;
 
     if ((length > 0) && (Xoffset < bitsX) && (Yoffset < bitsY))
-    {
+      {
         if ((Xoffset + length) > bitsX) length = bitsX - Xoffset;
         if ((Yoffset + length) > bitsY) length = bitsY - Yoffset;
 
@@ -1017,327 +1017,327 @@ void BitVector_Interval_Copy(unsigned int *  X, unsigned int *  Y, unsigned int
         t_hi_bit = Xoffset & MODMASK;
 
         if (ascending)
-        {
+          {
             s_base = s_lo_base;
             t_base = t_lo_base;
-        }
+          }
         else
-        {
+          {
             s_base = s_hi_base;
             t_base = t_hi_base;
-        }
+          }
         s_bits = 0;
         t_bits = 0;
         Y += s_base;
         X += t_base;
         notfirst = false;
         while (true)
-        {
+          {
             if (t_bits == 0)
-            {
+              {
                 if (notfirst)
-                {
+                  {
                     *X = target;
                     if (ascending)
-                    {
+                      {
                         if (t_base == t_hi_base) break;
                         t_base++;
                         X++;
-                    }
+                      }
                     else
-                    {
+                      {
                         if (t_base == t_lo_base) break;
                         t_base--;
                         X--;
-                    }
-                }
+                      }
+                  }
                 select = ((t_base == t_hi_base) << 1) | (t_base == t_lo_base);
                 switch (select)
-                {
-                    case 0:
-                        t_lower = 0;
-                        t_upper = BITS - 1;
-                        t_bits = BITS;
-                        target = 0;
-                        break;
-                    case 1:
-                        t_lower = t_lo_bit;
-                        t_upper = BITS - 1;
-                        t_bits = BITS - t_lo_bit;
-                        mask = (unsigned int) (~0L << t_lower);
-                        target = *X & ~ mask;
-                        break;
-                    case 2:
-                        t_lower = 0;
-                        t_upper = t_hi_bit;
-                        t_bits = t_hi_bit + 1;
-                        mask = (unsigned int) ((~0L << t_upper) << 1);
-                        target = *X & mask;
-                        break;
-                    case 3:
-                        t_lower = t_lo_bit;
-                        t_upper = t_hi_bit;
-                        t_bits = t_hi_bit - t_lo_bit + 1;
-                        mask = (unsigned int) (~0L << t_lower);
-                        mask &= (unsigned int) ~((~0L << t_upper) << 1);
-                        target = *X & ~ mask;
-                        break;
-                }
-            }
+                  {
+                  case 0:
+                    t_lower = 0;
+                    t_upper = BITS - 1;
+                    t_bits = BITS;
+                    target = 0;
+                    break;
+                  case 1:
+                    t_lower = t_lo_bit;
+                    t_upper = BITS - 1;
+                    t_bits = BITS - t_lo_bit;
+                    mask = (unsigned int) (~0L << t_lower);
+                    target = *X & ~ mask;
+                    break;
+                  case 2:
+                    t_lower = 0;
+                    t_upper = t_hi_bit;
+                    t_bits = t_hi_bit + 1;
+                    mask = (unsigned int) ((~0L << t_upper) << 1);
+                    target = *X & mask;
+                    break;
+                  case 3:
+                    t_lower = t_lo_bit;
+                    t_upper = t_hi_bit;
+                    t_bits = t_hi_bit - t_lo_bit + 1;
+                    mask = (unsigned int) (~0L << t_lower);
+                    mask &= (unsigned int) ~((~0L << t_upper) << 1);
+                    target = *X & ~ mask;
+                    break;
+                  }
+              }
             if (s_bits == 0)
-            {
+              {
                 if (notfirst)
-                {
+                  {
                     if (ascending)
-                    {
+                      {
                         if (s_base == s_hi_base) break;
                         s_base++;
                         Y++;
-                    }
+                      }
                     else
-                    {
+                      {
                         if (s_base == s_lo_base) break;
                         s_base--;
                         Y--;
-                    }
-                }
+                      }
+                  }
                 source = *Y;
                 select = ((s_base == s_hi_base) << 1) | (s_base == s_lo_base);
                 switch (select)
-                {
-                    case 0:
-                        s_lower = 0;
-                        s_upper = BITS - 1;
-                        s_bits = BITS;
-                        break;
-                    case 1:
-                        s_lower = s_lo_bit;
-                        s_upper = BITS - 1;
-                        s_bits = BITS - s_lo_bit;
-                        break;
-                    case 2:
-                        s_lower = 0;
-                        s_upper = s_hi_bit;
-                        s_bits = s_hi_bit + 1;
-                        break;
-                    case 3:
-                        s_lower = s_lo_bit;
-                        s_upper = s_hi_bit;
-                        s_bits = s_hi_bit - s_lo_bit + 1;
-                        break;
-                }
-            }
+                  {
+                  case 0:
+                    s_lower = 0;
+                    s_upper = BITS - 1;
+                    s_bits = BITS;
+                    break;
+                  case 1:
+                    s_lower = s_lo_bit;
+                    s_upper = BITS - 1;
+                    s_bits = BITS - s_lo_bit;
+                    break;
+                  case 2:
+                    s_lower = 0;
+                    s_upper = s_hi_bit;
+                    s_bits = s_hi_bit + 1;
+                    break;
+                  case 3:
+                    s_lower = s_lo_bit;
+                    s_upper = s_hi_bit;
+                    s_bits = s_hi_bit - s_lo_bit + 1;
+                    break;
+                  }
+              }
             notfirst = true;
             if (s_bits > t_bits)
-            {
+              {
                 bits = t_bits - 1;
                 if (ascending)
-                {
+                  {
                     s_min = s_lower;
                     s_max = s_lower + bits;
-                }
+                  }
                 else
-                {
+                  {
                     s_max = s_upper;
                     s_min = s_upper - bits;
-                }
+                  }
                 t_min = t_lower;
-            }
+              }
             else
-            {
+              {
                 bits = s_bits - 1;
                 if (ascending) t_min = t_lower;
                 else           t_min = t_upper - bits;
                 s_min = s_lower;
                 s_max = s_upper;
-            }
+              }
             bits++;
             mask = (unsigned int) (~0L << s_min);
             mask &= (unsigned int) ~((~0L << s_max) << 1);
             if (s_min == t_min) target |= (source & mask);
             else
-            {
+              {
                 if (s_min < t_min) target |= (source & mask) << (t_min-s_min);
                 else               target |= (source & mask) >> (s_min-t_min);
-            }
+              }
             if (ascending)
-            {
+              {
                 s_lower += bits;
                 t_lower += bits;
-            }
+              }
             else
-            {
+              {
                 s_upper -= bits;
                 t_upper -= bits;
-            }
+              }
             s_bits -= bits;
             t_bits -= bits;
-        }
+          }
         *(Z+size_(Z)-1) &= mask_(Z);
-    }
-}
+      }
+  }
 
 
-unsigned int *  BitVector_Interval_Substitute(unsigned int *  X, unsigned int *  Y,
-                                      unsigned int Xoffset, unsigned int Xlength,
-                                      unsigned int Yoffset, unsigned int Ylength)
-{
+  unsigned int *  BitVector_Interval_Substitute(unsigned int *  X, unsigned int *  Y,
+                                                unsigned int Xoffset, unsigned int Xlength,
+                                                unsigned int Yoffset, unsigned int Ylength)
+  {
     unsigned int Xbits = bits_(X);
     unsigned int Ybits = bits_(Y);
     unsigned int limit;
     unsigned int diff;
 
     if ((Xoffset <= Xbits) && (Yoffset <= Ybits))
-    {
+      {
         limit = Xoffset + Xlength;
         if (limit > Xbits)
-        {
+          {
             limit = Xbits;
             Xlength = Xbits - Xoffset;
-        }
+          }
         if ((Yoffset + Ylength) > Ybits)
-        {
+          {
             Ylength = Ybits - Yoffset;
-        }
+          }
         if (Xlength == Ylength)
-        {
+          {
             if ((Ylength > 0) && ((X != Y) || (Xoffset != Yoffset)))
-            {
+              {
                 BitVector_Interval_Copy(X,Y,Xoffset,Yoffset,Ylength);
-            }
-        }
+              }
+          }
         else /* Xlength != Ylength */
-        {
+          {
             if (Xlength > Ylength)
-            {
+              {
                 diff = Xlength - Ylength;
                 if (Ylength > 0) BitVector_Interval_Copy(X,Y,Xoffset,Yoffset,Ylength);
                 if (limit < Xbits) BitVector_Delete(X,Xoffset+Ylength,diff,false);
                 if ((X = BitVector_Resize(X,Xbits-diff)) == NULL) return(NULL);
-            }
+              }
             else /* Ylength > Xlength  ==>  Ylength > 0 */
-            {
+              {
                 diff = Ylength - Xlength;
                 if (X != Y)
-                {
+                  {
                     if ((X = BitVector_Resize(X,Xbits+diff)) == NULL) return(NULL);
                     if (limit < Xbits) BitVector_Insert(X,limit,diff,false);
                     BitVector_Interval_Copy(X,Y,Xoffset,Yoffset,Ylength);
-                }
+                  }
                 else /* in-place */
-                {
+                  {
                     if ((Y = X = BitVector_Resize(X,Xbits+diff)) == NULL) return(NULL);
                     if (limit >= Xbits)
-                    {
+                      {
                         BitVector_Interval_Copy(X,Y,Xoffset,Yoffset,Ylength);
-                    }
+                      }
                     else /* limit < Xbits */
-                    {
+                      {
                         BitVector_Insert(X,limit,diff,false);
                         if ((Yoffset+Ylength) <= limit)
-                        {
+                          {
                             BitVector_Interval_Copy(X,Y,Xoffset,Yoffset,Ylength);
-                        }
+                          }
                         else /* overlaps or lies above critical area */
-                        {
+                          {
                             if (limit <= Yoffset)
-                            {
+                              {
                                 Yoffset += diff;
                                 BitVector_Interval_Copy(X,Y,Xoffset,Yoffset,Ylength);
-                            }
+                              }
                             else /* Yoffset < limit */
-                            {
+                              {
                                 Xlength = limit - Yoffset;
                                 BitVector_Interval_Copy(X,Y,Xoffset,Yoffset,Xlength);
                                 Yoffset = Xoffset + Ylength; /* = limit + diff */
                                 Xoffset += Xlength;
                                 Ylength -= Xlength;
                                 BitVector_Interval_Copy(X,Y,Xoffset,Yoffset,Ylength);
-                            }
-                        }
-                    }
-                }
-            }
-        }
-    }
+                              }
+                          }
+                      }
+                  }
+              }
+          }
+      }
     return(X);
-}
+  }
 
-boolean BitVector_is_empty(unsigned int *  addr)                    /* X == {} ?     */
-{
+  boolean BitVector_is_empty(unsigned int *  addr)                    /* X == {} ?     */
+  {
     unsigned int  size = size_(addr);
     boolean r = true;
 
     if (size > 0)
-    {
+      {
         *(addr+size-1) &= mask_(addr);
         while (r && (size-- > 0)) r = ( *addr++ == 0 );
-    }
+      }
     return(r);
-}
+  }
 
-boolean BitVector_is_full(unsigned int *  addr)                     /* X == ~{} ?    */
-{
+  boolean BitVector_is_full(unsigned int *  addr)                     /* X == ~{} ?    */
+  {
     unsigned int  size = size_(addr);
     unsigned int  mask = mask_(addr);
     boolean r = false;
     unsigned int *  last;
 
     if (size > 0)
-    {
+      {
         r = true;
         last = addr + size - 1;
         *last |= ~ mask;
         while (r && (size-- > 0)) r = ( ~ *addr++ == 0 );
         *last &= mask;
-    }
+      }
     return(r);
-}
+  }
 
-boolean BitVector_equal(unsigned int *  X, unsigned int *  Y)               /* X == Y ?      */
-{
+  boolean BitVector_equal(unsigned int *  X, unsigned int *  Y)               /* X == Y ?      */
+  {
     unsigned int  size = size_(X);
     unsigned int  mask = mask_(X);
     boolean r = false;
 
     if (bits_(X) == bits_(Y))
-    {
+      {
         r = true;
         if (size > 0)
-        {
+          {
             *(X+size-1) &= mask;
             *(Y+size-1) &= mask;
             while (r && (size-- > 0)) r = (*X++ == *Y++);
-        }
-    }
+          }
+      }
     return(r);
-}
+  }
 
-/* X <,=,> Y ?     : unsigned     */
-signed int BitVector_Lexicompare(unsigned int *  X, unsigned int *  Y) {
+  /* X <,=,> Y ?     : unsigned     */
+  signed int BitVector_Lexicompare(unsigned int *  X, unsigned int *  Y) {
     unsigned int  bitsX = bits_(X);
     unsigned int  bitsY = bits_(Y);
     unsigned int  size  = size_(X);
     boolean r = true;
 
     if (bitsX == bitsY) {
-        if (size > 0) {
-            X += size;
-            Y += size;
-            while (r && (size-- > 0)) r = (*(--X) == *(--Y));
-        }
-        if (r) return((signed int) 0);
-        else {
-            if (*X < *Y) return((signed int) -1); else return((signed int) 1);
-        }
+      if (size > 0) {
+        X += size;
+        Y += size;
+        while (r && (size-- > 0)) r = (*(--X) == *(--Y));
+      }
+      if (r) return((signed int) 0);
+      else {
+        if (*X < *Y) return((signed int) -1); else return((signed int) 1);
+      }
     }
     else {
-        if (bitsX < bitsY) return((signed int) -1); else return((signed int) 1);
+      if (bitsX < bitsY) return((signed int) -1); else return((signed int) 1);
     }
-}
+  }
 
-signed int BitVector_Compare(unsigned int *  X, unsigned int *  Y)               /* X <,=,> Y ?   */
-{                                                           /*   signed      */
+  signed int BitVector_Compare(unsigned int *  X, unsigned int *  Y)               /* X <,=,> Y ?   */
+  {                                                           /*   signed      */
     unsigned int  bitsX = bits_(X);
     unsigned int  bitsY = bits_(Y);
     unsigned int  size  = size_(X);
@@ -1346,66 +1346,66 @@ signed int BitVector_Compare(unsigned int *  X, unsigned int *  Y)
     boolean r = true;
 
     if (bitsX == bitsY)
-    {
+      {
         if (size > 0)
-        {
+          {
             X += size;
             Y += size;
             mask &= ~ (mask >> 1);
             if ((sign = (*(X-1) & mask)) != (*(Y-1) & mask))
-            {
+              {
                 if (sign) return((signed int) -1); else return((signed int) 1);
-            }
+              }
             while (r && (size-- > 0)) r = (*(--X) == *(--Y));
-        }
+          }
         if (r) return((signed int) 0);
         else
-        {
+          {
             if (*X < *Y) return((signed int) -1); else return((signed int) 1);
-        }
-    }
+          }
+      }
     else
-    {
+      {
         if (bitsX < bitsY) return((signed int) -1); else return((signed int) 1);
-    }
-}
-
-size_t BitVector_Hash(unsigned int * addr)
-{
-  unsigned int  bits = bits_(addr);
-  unsigned int  size = size_(addr);
-  unsigned int  value;
-  unsigned int  count;
-  unsigned int  digit;
-  unsigned int  length;
+      }
+  }
+
+  size_t BitVector_Hash(unsigned int * addr)
+  {
+    unsigned int  bits = bits_(addr);
+    unsigned int  size = size_(addr);
+    unsigned int  value;
+    unsigned int  count;
+    unsigned int  digit;
+    unsigned int  length;
     
-  size_t result = 0;
-
-  length = bits >> 2;
-  if (bits & 0x0003) length++;
-  if (size > 0)
-    {
-      *(addr+size-1) &= mask_(addr);
-      while ((size-- > 0) && (length > 0))
-        {
-          value = *addr++;
-          count = BITS >> 2;
-          while ((count-- > 0) && (length > 0))
-            {
-              digit = value & 0x000F;
-              if (digit > 9) digit += (unsigned int) 'A' - 10;
-              else           digit += (unsigned int) '0';
-              result = 5*result + digit; length--;
-              if ((count > 0) && (length > 0)) value >>= 4;
-            }
-        }
-    }
-  return result;
-}
+    size_t result = 0;
+
+    length = bits >> 2;
+    if (bits & 0x0003) length++;
+    if (size > 0)
+      {
+        *(addr+size-1) &= mask_(addr);
+        while ((size-- > 0) && (length > 0))
+          {
+            value = *addr++;
+            count = BITS >> 2;
+            while ((count-- > 0) && (length > 0))
+              {
+                digit = value & 0x000F;
+                if (digit > 9) digit += (unsigned int) 'A' - 10;
+                else           digit += (unsigned int) '0';
+                result = 5*result + digit; length--;
+                if ((count > 0) && (length > 0)) value >>= 4;
+              }
+          }
+      }
+    return result;
+  }
 
 
-unsigned char * BitVector_to_Hex(unsigned int *  addr)
-{
+  unsigned char * BitVector_to_Hex(unsigned int *  addr)
+  {
     unsigned int  bits = bits_(addr);
     unsigned int  size = size_(addr);
     unsigned int  value;
@@ -1421,27 +1421,27 @@ unsigned char * BitVector_to_Hex(unsigned int *  addr)
     string += length;
     *string = (unsigned char) '\0';
     if (size > 0)
-    {
+      {
         *(addr+size-1) &= mask_(addr);
         while ((size-- > 0) && (length > 0))
-        {
+          {
             value = *addr++;
             count = BITS >> 2;
             while ((count-- > 0) && (length > 0))
-            {
+              {
                 digit = value & 0x000F;
                 if (digit > 9) digit += (unsigned int) 'A' - 10;
                 else           digit += (unsigned int) '0';
                 *(--string) = (unsigned char) digit; length--;
                 if ((count > 0) && (length > 0)) value >>= 4;
-            }
-        }
-    }
+              }
+          }
+      }
     return(string);
-}
+  }
 
-ErrCode BitVector_from_Hex(unsigned int *  addr, unsigned char * string)
-{
+  ErrCode BitVector_from_Hex(unsigned int *  addr, unsigned char * string)
+  {
     unsigned int  size = size_(addr);
     unsigned int  mask = mask_(addr);
     boolean ok = true;
@@ -1451,34 +1451,34 @@ ErrCode BitVector_from_Hex(unsigned int *  addr, unsigned char * string)
     int     digit;
 
     if (size > 0)
-    {
+      {
         length = strlen((char *) string);
         string += length;
         while (size-- > 0)
-        {
+          {
             value = 0;
             for ( count = 0; (ok && (length > 0) && (count < BITS)); count += 4 )
-            {
+              {
                 digit = (int) *(--string); length--;
                 /* separate because toupper() is likely a macro! */
                 digit = toupper(digit);
                 if ((ok = (isxdigit(digit) != 0)))
-                {
-                 if (digit >= (int) 'A') digit -= (int) 'A' - 10;
-                 else                    digit -= (int) '0';
-                 value |= (((unsigned int) digit) << count);
-                }
-            }
+                  {
+                    if (digit >= (int) 'A') digit -= (int) 'A' - 10;
+                    else                    digit -= (int) '0';
+                    value |= (((unsigned int) digit) << count);
+                  }
+              }
             *addr++ = value;
-        }
+          }
         *(--addr) &= mask;
-    }
+      }
     if (ok) return(ErrCode_Ok);
     else    return(ErrCode_Pars);
-}
+  }
 
-unsigned char * BitVector_to_Bin(unsigned int *  addr)
-{
+  unsigned char * BitVector_to_Bin(unsigned int *  addr)
+  {
     unsigned int  size = size_(addr);
     unsigned int  value;
     unsigned int  count;
@@ -1492,27 +1492,27 @@ unsigned char * BitVector_to_Bin(unsigned int *  addr)
     string += length;
     *string = (unsigned char) '\0';
     if (size > 0)
-    {
+      {
         *(addr+size-1) &= mask_(addr);
         while (size-- > 0)
-        {
+          {
             value = *addr++;
             count = BITS;
             if (count > length) count = length;
             while (count-- > 0)
-            {
+              {
                 digit = value & 0x0001;
                 digit += (unsigned int) '0';
                 *(--string) = (unsigned char) digit; length--;
                 if (count > 0) value >>= 1;
-            }
-        }
-    }
+              }
+          }
+      }
     return(string);
-}
+  }
 
-ErrCode BitVector_from_Bin(unsigned int *  addr, unsigned char * string)
-{
+  ErrCode BitVector_from_Bin(unsigned int *  addr, unsigned char * string)
+  {
     unsigned int  size = size_(addr);
     unsigned int  mask = mask_(addr);
     boolean ok = true;
@@ -1522,37 +1522,37 @@ ErrCode BitVector_from_Bin(unsigned int *  addr, unsigned char * string)
     int     digit;
 
     if (size > 0)
-    {
+      {
         length = strlen((char *) string);
         string += length;
         while (size-- > 0)
-        {
+          {
             value = 0;
             for ( count = 0; (ok && (length > 0) && (count < BITS)); count++ )
-            {
+              {
                 digit = (int) *(--string); length--;
                 switch (digit)
-                {
-                    case (int) '0':
-                        break;
-                    case (int) '1':
-                        value |= BITMASKTAB[count];
-                        break;
-                    default:
-                        ok = false;
-                        break;
-                }
-            }
+                  {
+                  case (int) '0':
+                    break;
+                  case (int) '1':
+                    value |= BITMASKTAB[count];
+                    break;
+                  default:
+                    ok = false;
+                    break;
+                  }
+              }
             *addr++ = value;
-        }
+          }
         *(--addr) &= mask;
-    }
+      }
     if (ok) return(ErrCode_Ok);
     else    return(ErrCode_Pars);
-}
+  }
 
-unsigned char * BitVector_to_Dec(unsigned int *  addr)
-{
+  unsigned char * BitVector_to_Dec(unsigned int *  addr)
+  {
     unsigned int  bits = bits_(addr);
     unsigned int  length;
     unsigned int  digits;
@@ -1575,98 +1575,98 @@ unsigned char * BitVector_to_Dec(unsigned int *  addr)
     string = result;
     sign = BitVector_Sign(addr);
     if ((bits < 4) || (sign == 0))
-    {
+      {
         if (bits > 0) digits = *addr; else digits = (unsigned int) 0;
         if (sign < 0) digits = ((unsigned int)(-((signed int)digits))) & mask_(addr);
         *string++ = (unsigned char) digits + (unsigned char) '0';
         digits = 1;
-    }
+      }
     else
-    {
+      {
         quot = BitVector_Create(bits,false);
         if (quot == NULL)
-        {
+          {
             BitVector_Dispose(result);
             return(NULL);
-        }
+          }
         rest = BitVector_Create(bits,false);
         if (rest == NULL)
-        {
+          {
             BitVector_Dispose(result);
             BitVector_Destroy(quot);
             return(NULL);
-        }
+          }
         temp = BitVector_Create(bits,false);
         if (temp == NULL)
-        {
+          {
             BitVector_Dispose(result);
             BitVector_Destroy(quot);
             BitVector_Destroy(rest);
             return(NULL);
-        }
+          }
         base = BitVector_Create(bits,true);
         if (base == NULL)
-        {
+          {
             BitVector_Dispose(result);
             BitVector_Destroy(quot);
             BitVector_Destroy(rest);
             BitVector_Destroy(temp);
             return(NULL);
-        }
+          }
         if (sign < 0) BitVector_Negate(quot,addr);
         else           BitVector_Copy(quot,addr);
         digits = 0;
         *base = EXP10;
         loop = (bits >= BITS);
         do
-        {
+          {
             if (loop)
-            {
+              {
                 BitVector_Copy(temp,quot);
                 if (BitVector_Div_Pos(quot,temp,base,rest))
-                {
+                  {
                     BitVector_Dispose(result); /* emergency exit */
                     BitVector_Destroy(quot);
                     BitVector_Destroy(rest);   /* should never occur */
                     BitVector_Destroy(temp);   /* under normal operation */
                     BitVector_Destroy(base);
                     return(NULL);
-                }
+                  }
                 loop = ! BitVector_is_empty(quot);
                 q = *rest;
-            }
+              }
             else q = *quot;
             count = LOG10;
             while (((loop && (count-- > 0)) || ((! loop) && (q != 0))) &&
-                (digits < length))
-            {
+                   (digits < length))
+              {
                 if (q != 0)
-                {
+                  {
                     BIT_VECTOR_DIGITIZE(unsigned int,q,r)
-                }
+                      }
                 else r = (unsigned int) '0';
                 *string++ = (unsigned char) r;
                 digits++;
-            }
-        }
+              }
+          }
         while (loop && (digits < length));
         BitVector_Destroy(quot);
         BitVector_Destroy(rest);
         BitVector_Destroy(temp);
         BitVector_Destroy(base);
-    }
+      }
     if ((sign < 0) && (digits < length))
-    {
+      {
         *string++ = (unsigned char) '-';
         digits++;
-    }
+      }
     *string = (unsigned char) '\0';
     BIT_VECTOR_reverse(result,digits);
     return(result);
-}
+  }
 
-ErrCode BitVector_from_Dec(unsigned int *  addr, unsigned char * string)
-{
+  ErrCode BitVector_from_Dec(unsigned int *  addr, unsigned char * string)
+  {
     ErrCode error = ErrCode_Ok;
     unsigned int  bits = bits_(addr);
     unsigned int  mask = mask_(addr);
@@ -1686,127 +1686,127 @@ ErrCode BitVector_from_Dec(unsigned int *  addr, unsigned char * string)
     int     digit;
 
     if (bits > 0)
-    {
+      {
         length = strlen((char *) string);
         if (length == 0) return(ErrCode_Pars);
         digit = (int) *string;
         if ((minus = (digit == (int) '-')) ||
-                     (digit == (int) '+'))
-        {
+            (digit == (int) '+'))
+          {
             string++;
             if (--length == 0) return(ErrCode_Pars);
-        }
+          }
         string += length;
         term = BitVector_Create(BITS,false);
         if (term == NULL)
-        {
+          {
             return(ErrCode_Null);
-        }
+          }
         base = BitVector_Create(BITS,false);
         if (base == NULL)
-        {
+          {
             BitVector_Destroy(term);
             return(ErrCode_Null);
-        }
+          }
         prod = BitVector_Create(bits,init);
         if (prod == NULL)
-        {
+          {
             BitVector_Destroy(term);
             BitVector_Destroy(base);
             return(ErrCode_Null);
-        }
+          }
         rank = BitVector_Create(bits,init);
         if (rank == NULL)
-        {
+          {
             BitVector_Destroy(term);
             BitVector_Destroy(base);
             BitVector_Destroy(prod);
             return(ErrCode_Null);
-        }
+          }
         temp = BitVector_Create(bits,false);
         if (temp == NULL)
-        {
+          {
             BitVector_Destroy(term);
             BitVector_Destroy(base);
             BitVector_Destroy(prod);
             BitVector_Destroy(rank);
             return(ErrCode_Null);
-        }
+          }
         BitVector_Empty(addr);
         *base = EXP10;
         shift = false;
         while ((! error) && (length > 0))
-        {
+          {
             accu = 0;
             powr = 1;
             count = LOG10;
             while ((! error) && (length > 0) && (count-- > 0))
-            {
+              {
                 digit = (int) *(--string); length--;
                 /* separate because isdigit() is likely a macro! */
                 if (isdigit(digit) != 0)
-                {
+                  {
                     accu += ((unsigned int) digit - (unsigned int) '0') * powr;
                     powr *= 10;
-                }
+                  }
                 else error = ErrCode_Pars;
-            }
+              }
             if (! error)
-            {
+              {
                 if (shift)
-                {
+                  {
                     *term = accu;
                     BitVector_Copy(temp,rank);
                     error = BitVector_Mul_Pos(prod,temp,term,false);
-                }
+                  }
                 else
-                {
+                  {
                     *prod = accu;
                     if ((! init) && ((accu & ~ mask) != 0)) error = ErrCode_Ovfl;
-                }
+                  }
                 if (! error)
-                {
+                  {
                     carry = false;
                     BitVector_compute(addr,addr,prod,false,&carry);
                     /* ignores sign change (= overflow) but ! */
                     /* numbers too large (= carry) for resulting bit vector */
                     if (carry) error = ErrCode_Ovfl;
                     else
-                    {
+                      {
                         if (length > 0)
-                        {
+                          {
                             if (shift)
-                            {
+                              {
                                 BitVector_Copy(temp,rank);
                                 error = BitVector_Mul_Pos(rank,temp,base,false);
-                            }
+                              }
                             else
-                            {
+                              {
                                 *rank = *base;
                                 shift = true;
-                            }
-                        }
-                    }
-                }
-            }
-        }
+                              }
+                          }
+                      }
+                  }
+              }
+          }
         BitVector_Destroy(term);
         BitVector_Destroy(base);
         BitVector_Destroy(prod);
         BitVector_Destroy(rank);
         BitVector_Destroy(temp);
         if (! error && minus)
-        {
+          {
             BitVector_Negate(addr,addr);
             if ((*(addr + size_(addr) - 1) & mask & ~ (mask >> 1)) == 0)
-                error = ErrCode_Ovfl;
-        }
-    }
+              error = ErrCode_Ovfl;
+          }
+      }
     return(error);
-}
+  }
 
-unsigned char * BitVector_to_Enum(unsigned int *  addr)
-{
+  unsigned char * BitVector_to_Enum(unsigned int *  addr)
+  {
     unsigned int  bits = bits_(addr);
     unsigned int  sample;
     unsigned int  length;
@@ -1821,26 +1821,26 @@ unsigned char * BitVector_to_Enum(unsigned int *  addr)
     boolean comma;
 
     if (bits > 0)
-    {
+      {
         sample = bits - 1;  /* greatest possible index */
         length = 2;         /* account for index 0 && terminating '\0' */
         digits = 1;         /* account for intervening dashes && commas */
         factor = 1;
         power = 10;
         while (sample >= (power-1))
-        {
+          {
             length += ++digits * factor * 6;  /* 9,90,900,9000,... (9*2/3 = 6) */
             factor = power;
             power *= 10;
-        }
+          }
         if (sample > --factor)
-        {
+          {
             sample -= factor;
             factor = (unsigned int) ( sample / 3 );
             factor = (factor << 1) + (sample - (factor * 3));
             length += ++digits * factor;
-        }
-    }
+          }
+      }
     else length = 1;
     string = (unsigned char *) malloc((size_t) length);
     if (string == NULL) return(NULL);
@@ -1848,36 +1848,36 @@ unsigned char * BitVector_to_Enum(unsigned int *  addr)
     comma = false;
     target = string;
     while ((start < bits) && BitVector_interval_scan_inc(addr,start,&min,&max))
-    {
+      {
         start = max + 2;
         if (comma) *target++ = (unsigned char) ',';
         if (min == max)
-        {
+          {
             target += BIT_VECTOR_int2str(target,min);
-        }
+          }
         else
-        {
+          {
             if (min+1 == max)
-            {
+              {
                 target += BIT_VECTOR_int2str(target,min);
                 *target++ = (unsigned char) ',';
                 target += BIT_VECTOR_int2str(target,max);
-            }
+              }
             else
-            {
+              {
                 target += BIT_VECTOR_int2str(target,min);
                 *target++ = (unsigned char) '-';
                 target += BIT_VECTOR_int2str(target,max);
-            }
-        }
+              }
+          }
         comma = true;
-    }
+      }
     *target = (unsigned char) '\0';
     return(string);
-}
+  }
 
-ErrCode BitVector_from_Enum(unsigned int *  addr, unsigned char * string)
-{
+  ErrCode BitVector_from_Enum(unsigned int *  addr, unsigned char * string)
+  {
     ErrCode error = ErrCode_Ok;
     unsigned int  bits = bits_(addr);
     unsigned int  state = 1;
@@ -1886,176 +1886,176 @@ ErrCode BitVector_from_Enum(unsigned int *  addr, unsigned char * string)
     unsigned int  start = 0;         /* silence compiler warning */
 
     if (bits > 0)
-    {
+      {
         BitVector_Empty(addr);
         while ((! error) && (state != 0))
-        {
+          {
             token = (unsigned int) *string;
             /* separate because isdigit() is likely a macro! */
             if (isdigit((int)token) != 0)
-            {
+              {
                 string += BIT_VECTOR_str2int(string,&index);
                 if (index < bits) token = (unsigned int) '0';
                 else error = ErrCode_Indx;
-            }
+              }
             else string++;
             if (! error)
-            switch (state)
-            {
+              switch (state)
+                {
                 case 1:
-                    switch (token)
+                  switch (token)
                     {
-                        case (unsigned int) '0':
-                            state = 2;
-                            break;
-                        case (unsigned int) '\0':
-                            state = 0;
-                            break;
-                        default:
-                            error = ErrCode_Pars;
-                            break;
+                    case (unsigned int) '0':
+                      state = 2;
+                      break;
+                    case (unsigned int) '\0':
+                      state = 0;
+                      break;
+                    default:
+                      error = ErrCode_Pars;
+                      break;
                     }
-                    break;
+                  break;
                 case 2:
-                    switch (token)
+                  switch (token)
                     {
-                        case (unsigned int) '-':
-                            start = index;
-                            state = 3;
-                            break;
-                        case (unsigned int) ',':
-                            BIT_VECTOR_SET_BIT(addr,index)
-                            state = 5;
-                            break;
-                        case (unsigned int) '\0':
-                            BIT_VECTOR_SET_BIT(addr,index)
-                            state = 0;
-                            break;
-                        default:
-                            error = ErrCode_Pars;
-                            break;
+                    case (unsigned int) '-':
+                      start = index;
+                      state = 3;
+                      break;
+                    case (unsigned int) ',':
+                      BIT_VECTOR_SET_BIT(addr,index)
+                        state = 5;
+                      break;
+                    case (unsigned int) '\0':
+                      BIT_VECTOR_SET_BIT(addr,index)
+                        state = 0;
+                      break;
+                    default:
+                      error = ErrCode_Pars;
+                      break;
                     }
-                    break;
+                  break;
                 case 3:
-                    switch (token)
+                  switch (token)
                     {
-                        case (unsigned int) '0':
-                            if (start < index)
-                                BitVector_Interval_Fill(addr,start,index);
-                            else if (start == index)
-                                BIT_VECTOR_SET_BIT(addr,index)
-                            else error = ErrCode_Ordr;
-                            state = 4;
-                            break;
-                        default:
-                            error = ErrCode_Pars;
-                            break;
+                    case (unsigned int) '0':
+                      if (start < index)
+                        BitVector_Interval_Fill(addr,start,index);
+                      else if (start == index)
+                        BIT_VECTOR_SET_BIT(addr,index)
+                          else error = ErrCode_Ordr;
+                      state = 4;
+                      break;
+                    default:
+                      error = ErrCode_Pars;
+                      break;
                     }
-                    break;
+                  break;
                 case 4:
-                    switch (token)
+                  switch (token)
                     {
-                        case (unsigned int) ',':
-                            state = 5;
-                            break;
-                        case (unsigned int) '\0':
-                            state = 0;
-                            break;
-                        default:
-                            error = ErrCode_Pars;
-                            break;
+                    case (unsigned int) ',':
+                      state = 5;
+                      break;
+                    case (unsigned int) '\0':
+                      state = 0;
+                      break;
+                    default:
+                      error = ErrCode_Pars;
+                      break;
                     }
-                    break;
+                  break;
                 case 5:
-                    switch (token)
+                  switch (token)
                     {
-                        case (unsigned int) '0':
-                            state = 2;
-                            break;
-                        default:
-                            error = ErrCode_Pars;
-                            break;
+                    case (unsigned int) '0':
+                      state = 2;
+                      break;
+                    default:
+                      error = ErrCode_Pars;
+                      break;
                     }
-                    break;
-            }
-        }
-    }
+                  break;
+                }
+          }
+      }
     return(error);
-}
+  }
 
-void BitVector_Bit_Off(unsigned int *  addr, unsigned int index)           /* X = X \ {x}   */
-{
+  void BitVector_Bit_Off(unsigned int *  addr, unsigned int index)           /* X = X \ {x}   */
+  {
     if (index < bits_(addr)) BIT_VECTOR_CLR_BIT(addr,index)
-}
+                               }
 
-void BitVector_Bit_On(unsigned int *  addr, unsigned int index)            /* X = X + {x}   */
-{
+  void BitVector_Bit_On(unsigned int *  addr, unsigned int index)            /* X = X + {x}   */
+  {
     if (index < bits_(addr)) BIT_VECTOR_SET_BIT(addr,index)
-}
+                               }
 
-boolean BitVector_bit_flip(unsigned int *  addr, unsigned int index)   /* X=(X+{x})\(X*{x}) */
-{
+  boolean BitVector_bit_flip(unsigned int *  addr, unsigned int index)   /* X=(X+{x})\(X*{x}) */
+  {
     unsigned int mask;
 
     if (index < bits_(addr)) return( BIT_VECTOR_FLP_BIT(addr,index,mask) );
     else                     return( false );
-}
+  }
 
-boolean BitVector_bit_test(unsigned int *  addr, unsigned int index)       /* {x} in X ?    */
-{
+  boolean BitVector_bit_test(unsigned int *  addr, unsigned int index)       /* {x} in X ?    */
+  {
     if (index < bits_(addr)) return( BIT_VECTOR_TST_BIT(addr,index) );
     else                     return( false );
-}
+  }
 
-void BitVector_Bit_Copy(unsigned int *  addr, unsigned int index, boolean bit)
-{
+  void BitVector_Bit_Copy(unsigned int *  addr, unsigned int index, boolean bit)
+  {
     if (index < bits_(addr))
-    {
+      {
         if (bit) BIT_VECTOR_SET_BIT(addr,index)
-        else     BIT_VECTOR_CLR_BIT(addr,index)
-    }
-}
+                   else     BIT_VECTOR_CLR_BIT(addr,index)
+                              }
+  }
 
-void BitVector_LSB(unsigned int *  addr, boolean bit)
-{
+  void BitVector_LSB(unsigned int *  addr, boolean bit)
+  {
     if (bits_(addr) > 0)
-    {
+      {
         if (bit) *addr |= LSB;
         else     *addr &= ~ LSB;
-    }
-}
+      }
+  }
 
-void BitVector_MSB(unsigned int *  addr, boolean bit)
-{
+  void BitVector_MSB(unsigned int *  addr, boolean bit)
+  {
     unsigned int size = size_(addr);
     unsigned int mask = mask_(addr);
 
     if (size-- > 0)
-    {
+      {
         if (bit) *(addr+size) |= mask & ~ (mask >> 1);
         else     *(addr+size) &= ~ mask | (mask >> 1);
-    }
-}
+      }
+  }
 
-boolean BitVector_lsb_(unsigned int *  addr)
-{
+  boolean BitVector_lsb_(unsigned int *  addr)
+  {
     if (size_(addr) > 0) return( (*addr & LSB) != 0 );
     else                 return( false );
-}
+  }
 
-boolean BitVector_msb_(unsigned int *  addr)
-{
+  boolean BitVector_msb_(unsigned int *  addr)
+  {
     unsigned int size = size_(addr);
     unsigned int mask = mask_(addr);
 
     if (size-- > 0)
-        return( (*(addr+size) & (mask & ~ (mask >> 1))) != 0 );
+      return( (*(addr+size) & (mask & ~ (mask >> 1))) != 0 );
     else
-        return( false );
-}
+      return( false );
+  }
 
-boolean BitVector_rotate_left(unsigned int *  addr)
-{
+  boolean BitVector_rotate_left(unsigned int *  addr)
+  {
     unsigned int  size = size_(addr);
     unsigned int  mask = mask_(addr);
     unsigned int  msb;
@@ -2063,27 +2063,27 @@ boolean BitVector_rotate_left(unsigned int *  addr)
     boolean carry_out = false;
 
     if (size > 0)
-    {
+      {
         msb = mask & ~ (mask >> 1);
         carry_in = ((*(addr+size-1) & msb) != 0);
         while (size-- > 1)
-        {
+          {
             carry_out = ((*addr & MSB) != 0);
             *addr <<= 1;
             if (carry_in) *addr |= LSB;
             carry_in = carry_out;
             addr++;
-        }
+          }
         carry_out = ((*addr & msb) != 0);
         *addr <<= 1;
         if (carry_in) *addr |= LSB;
         *addr &= mask;
-    }
+      }
     return(carry_out);
-}
+  }
 
-boolean BitVector_rotate_right(unsigned int *  addr)
-{
+  boolean BitVector_rotate_right(unsigned int *  addr)
+  {
     unsigned int  size = size_(addr);
     unsigned int  mask = mask_(addr);
     unsigned int  msb;
@@ -2091,7 +2091,7 @@ boolean BitVector_rotate_right(unsigned int *  addr)
     boolean carry_out = false;
 
     if (size > 0)
-    {
+      {
         msb = mask & ~ (mask >> 1);
         carry_in = ((*addr & LSB) != 0);
         addr += size-1;
@@ -2103,52 +2103,52 @@ boolean BitVector_rotate_right(unsigned int *  addr)
         addr--;
         size--;
         while (size-- > 0)
-        {
+          {
             carry_out = ((*addr & LSB) != 0);
             *addr >>= 1;
             if (carry_in) *addr |= MSB;
             carry_in = carry_out;
             addr--;
-        }
-    }
+          }
+      }
     return(carry_out);
-}
+  }
 
-boolean BitVector_shift_left(unsigned int *  addr, boolean carry_in)
-{
+  boolean BitVector_shift_left(unsigned int *  addr, boolean carry_in)
+  {
     unsigned int  size = size_(addr);
     unsigned int  mask = mask_(addr);
     unsigned int  msb;
     boolean carry_out = carry_in;
 
     if (size > 0)
-    {
+      {
         msb = mask & ~ (mask >> 1);
         while (size-- > 1)
-        {
+          {
             carry_out = ((*addr & MSB) != 0);
             *addr <<= 1;
             if (carry_in) *addr |= LSB;
             carry_in = carry_out;
             addr++;
-        }
+          }
         carry_out = ((*addr & msb) != 0);
         *addr <<= 1;
         if (carry_in) *addr |= LSB;
         *addr &= mask;
-    }
+      }
     return(carry_out);
-}
+  }
 
-boolean BitVector_shift_right(unsigned int *  addr, boolean carry_in)
-{
+  boolean BitVector_shift_right(unsigned int *  addr, boolean carry_in)
+  {
     unsigned int  size = size_(addr);
     unsigned int  mask = mask_(addr);
     unsigned int  msb;
     boolean carry_out = carry_in;
 
     if (size > 0)
-    {
+      {
         msb = mask & ~ (mask >> 1);
         addr += size-1;
         *addr &= mask;
@@ -2159,128 +2159,128 @@ boolean BitVector_shift_right(unsigned int *  addr, boolean carry_in)
         addr--;
         size--;
         while (size-- > 0)
-        {
+          {
             carry_out = ((*addr & LSB) != 0);
             *addr >>= 1;
             if (carry_in) *addr |= MSB;
             carry_in = carry_out;
             addr--;
-        }
-    }
+          }
+      }
     return(carry_out);
-}
+  }
 
-void BitVector_Move_Left(unsigned int *  addr, unsigned int bits)
-{
+  void BitVector_Move_Left(unsigned int *  addr, unsigned int bits)
+  {
     unsigned int count;
     unsigned int words;
 
     if (bits > 0)
-    {
+      {
         count = bits & MODMASK;
         words = bits >> LOGBITS;
         if (bits >= bits_(addr)) BitVector_Empty(addr);
         else
-        {
+          {
             while (count-- > 0) BitVector_shift_left(addr,0);
             BitVector_Word_Insert(addr,0,words,true);
-        }
-    }
-}
+          }
+      }
+  }
 
-void BitVector_Move_Right(unsigned int *  addr, unsigned int bits)
-{
+  void BitVector_Move_Right(unsigned int *  addr, unsigned int bits)
+  {
     unsigned int count;
     unsigned int words;
 
     if (bits > 0)
-    {
+      {
         count = bits & MODMASK;
         words = bits >> LOGBITS;
         if (bits >= bits_(addr)) BitVector_Empty(addr);
         else
-        {
+          {
             while (count-- > 0) BitVector_shift_right(addr,0);
             BitVector_Word_Delete(addr,0,words,true);
-        }
-    }
-}
+          }
+      }
+  }
 
-void BitVector_Insert(unsigned int *  addr, unsigned int offset, unsigned int count, boolean clear)
-{
+  void BitVector_Insert(unsigned int *  addr, unsigned int offset, unsigned int count, boolean clear)
+  {
     unsigned int bits = bits_(addr);
     unsigned int last;
 
     if ((count > 0) && (offset < bits))
-    {
+      {
         last = offset + count;
         if (last < bits)
-        {
+          {
             BitVector_Interval_Copy(addr,addr,last,offset,(bits-last));
-        }
+          }
         else last = bits;
         if (clear) BitVector_Interval_Empty(addr,offset,(last-1));
-    }
-}
+      }
+  }
 
-void BitVector_Delete(unsigned int *  addr, unsigned int offset, unsigned int count, boolean clear)
-{
+  void BitVector_Delete(unsigned int *  addr, unsigned int offset, unsigned int count, boolean clear)
+  {
     unsigned int bits = bits_(addr);
     unsigned int last;
 
     if ((count > 0) && (offset < bits))
-    {
+      {
         last = offset + count;
         if (last < bits)
-        {
+          {
             BitVector_Interval_Copy(addr,addr,offset,last,(bits-last));
-        }
+          }
         else count = bits - offset;
         if (clear) BitVector_Interval_Empty(addr,(bits-count),(bits-1));
-    }
-}
+      }
+  }
 
-boolean BitVector_increment(unsigned int *  addr)                   /* X++           */
-{
+  boolean BitVector_increment(unsigned int *  addr)                   /* X++           */
+  {
     unsigned int  size  = size_(addr);
     unsigned int  mask  = mask_(addr);
     unsigned int *  last  = addr + size - 1;
     boolean carry = true;
 
     if (size > 0)
-    {
+      {
         *last |= ~ mask;
         while (carry && (size-- > 0))
-        {
+          {
             carry = (++(*addr++) == 0);
-        }
+          }
         *last &= mask;
-    }
+      }
     return(carry);
-}
+  }
 
-boolean BitVector_decrement(unsigned int *  addr)                   /* X--           */
-{
+  boolean BitVector_decrement(unsigned int *  addr)                   /* X--           */
+  {
     unsigned int  size  = size_(addr);
     unsigned int  mask  = mask_(addr);
     unsigned int *  last  = addr + size - 1;
     boolean carry = true;
 
     if (size > 0)
-    {
+      {
         *last &= mask;
         while (carry && (size-- > 0))
-        {
+          {
             carry = (*addr == 0);
             --(*addr++);
-        }
+          }
         *last &= mask;
-    }
+      }
     return(carry);
-}
+  }
 
-boolean BitVector_compute(unsigned int *  X, unsigned int *  Y, unsigned int *  Z, boolean minus, boolean *carry)
-{
+  boolean BitVector_compute(unsigned int *  X, unsigned int *  Y, unsigned int *  Z, boolean minus, boolean *carry)
+  {
     unsigned int size = size_(X);
     unsigned int mask = mask_(X);
     unsigned int vv = 0;
@@ -2292,12 +2292,12 @@ boolean BitVector_compute(unsigned int *  X, unsigned int *  Y, unsigned int *
     unsigned int hi;
 
     if (size > 0)
-    {
+      {
         if (minus) cc = (*carry == 0);
         else       cc = (*carry != 0);
         /* deal with (size-1) least significant full words first: */
         while (--size > 0)
-        {
+          {
             yy = *Y++;
             if (minus) zz = (unsigned int) ~ ( Z ? *Z++ : 0 );
             else       zz = (unsigned int)     ( Z ? *Z++ : 0 );
@@ -2305,24 +2305,24 @@ boolean BitVector_compute(unsigned int *  X, unsigned int *  Y, unsigned int *
             hi = (yy >> 1) + (zz >> 1) + (lo >> 1);
             cc = ((hi & MSB) != 0);
             *X++ = (hi << 1) | (lo & LSB);
-        }
+          }
         /* deal with most significant word (may be used only partially): */
         yy = *Y & mask;
         if (minus) zz = (unsigned int) ~ ( Z ? *Z : 0 );
         else       zz = (unsigned int)     ( Z ? *Z : 0 );
         zz &= mask;
         if (mask == LSB) /* special case, only one bit used */
-        {
+          {
             vv = cc;
             lo = yy + zz + cc;
             cc = (lo >> 1);
             vv ^= cc;
             *X = lo & LSB;
-        }
+          }
         else
-        {
+          {
             if (~ mask) /* not all bits are used, but more than one */
-            {
+              {
                 mm = (mask >> 1);
                 vv = (yy & mm) + (zz & mm) + cc;
                 mm = mask & ~ mm;
@@ -2332,9 +2332,9 @@ boolean BitVector_compute(unsigned int *  X, unsigned int *  Y, unsigned int *
                 vv &= mm;
                 cc &= mm;
                 *X = lo & mask;
-            }
+              }
             else /* other special case, all bits are used */
-            {
+              {
                 mm = ~ MSB;
                 lo = (yy & mm) + (zz & mm) + cc;
                 vv = lo & MSB;
@@ -2342,95 +2342,95 @@ boolean BitVector_compute(unsigned int *  X, unsigned int *  Y, unsigned int *
                 cc = hi & MSB;
                 vv ^= cc;
                 *X = (hi << 1) | (lo & mm);
-            }
-        }
+              }
+          }
         if (minus) *carry = (cc == 0);
         else       *carry = (cc != 0);
-    }
+      }
     return(vv != 0);
-}
+  }
 
-boolean BitVector_add(unsigned int *  X, unsigned int *  Y, unsigned int *  Z, boolean *carry)
-{
+  boolean BitVector_add(unsigned int *  X, unsigned int *  Y, unsigned int *  Z, boolean *carry)
+  {
     return(BitVector_compute(X,Y,Z,false,carry));
-}
+  }
 
-boolean BitVector_sub(unsigned int *  X, unsigned int *  Y, unsigned int *  Z, boolean *carry)
-{
+  boolean BitVector_sub(unsigned int *  X, unsigned int *  Y, unsigned int *  Z, boolean *carry)
+  {
     return(BitVector_compute(X,Y,Z,true,carry));
-}
+  }
 
-boolean BitVector_inc(unsigned int *  X, unsigned int *  Y)
-{
+  boolean BitVector_inc(unsigned int *  X, unsigned int *  Y)
+  {
     boolean carry = true;
 
     return(BitVector_compute(X,Y,NULL,false,&carry));
-}
+  }
 
-boolean BitVector_dec(unsigned int *  X, unsigned int *  Y)
-{
+  boolean BitVector_dec(unsigned int *  X, unsigned int *  Y)
+  {
     boolean carry = true;
 
     return(BitVector_compute(X,Y,NULL,true,&carry));
-}
+  }
 
-void BitVector_Negate(unsigned int *  X, unsigned int *  Y)
-{
+  void BitVector_Negate(unsigned int *  X, unsigned int *  Y)
+  {
     unsigned int  size  = size_(X);
     unsigned int  mask  = mask_(X);
     boolean carry = true;
 
     if (size > 0)
-    {
+      {
         while (size-- > 0)
-        {
+          {
             *X = ~ *Y++;
             if (carry)
-            {
+              {
                 carry = (++(*X) == 0);
-            }
+              }
             X++;
-        }
+          }
         *(--X) &= mask;
-    }
-}
+      }
+  }
 
-void BitVector_Absolute(unsigned int *  X, unsigned int *  Y)
-{
+  void BitVector_Absolute(unsigned int *  X, unsigned int *  Y)
+  {
     unsigned int size = size_(Y);
     unsigned int mask = mask_(Y);
 
     if (size > 0)
-    {
+      {
         if (*(Y+size-1) & (mask & ~ (mask >> 1))) BitVector_Negate(X,Y);
         else                                             BitVector_Copy(X,Y);
-    }
-}
+      }
+  }
 
-// FIXME:  What the hell does the return value of this mean?
-// It returns 0, 1, or -1 under mysterious circumstances.
-signed int BitVector_Sign(unsigned int *  addr)
-{
+  // FIXME:  What the hell does the return value of this mean?
+  // It returns 0, 1, or -1 under mysterious circumstances.
+  signed int BitVector_Sign(unsigned int *  addr)
+  {
     unsigned int  size = size_(addr);
     unsigned int  mask = mask_(addr);
     unsigned int *  last = addr + size - 1;
     boolean r    = true;
 
     if (size > 0)
-    {
+      {
         *last &= mask;
         while (r && (size-- > 0)) r = ( *addr++ == 0 );
-    }
+      }
     if (r) return((signed int) 0);
     else
-    {
+      {
         if (*last & (mask & ~ (mask >> 1))) return((signed int) -1);
         else                                      return((signed int)  1);
-    }
-}
+      }
+  }
 
-ErrCode BitVector_Mul_Pos(unsigned int *  X, unsigned int *  Y, unsigned int *  Z, boolean strict)
-{
+  ErrCode BitVector_Mul_Pos(unsigned int *  X, unsigned int *  Y, unsigned int *  Z, boolean strict)
+  {
     unsigned int  mask;
     unsigned int  limit;
     unsigned int  count;
@@ -2441,13 +2441,13 @@ ErrCode BitVector_Mul_Pos(unsigned int *  X, unsigned int *  Y, unsigned int *
     boolean ok = true;
 
     /*
-       Requirements:
-         -  X, Y && Z must be distinct
-         -  X && Y must have equal sizes (whereas Z may be any size!)
-         -  Z should always contain the SMALLER of the two factors Y && Z
-       Constraints:
-         -  The contents of Y (&& of X, of course) are destroyed
-            (only Z is preserved!)
+      Requirements:
+      -  X, Y && Z must be distinct
+      -  X && Y must have equal sizes (whereas Z may be any size!)
+      -  Z should always contain the SMALLER of the two factors Y && Z
+      Constraints:
+      -  The contents of Y (&& of X, of course) are destroyed
+      (only Z is preserved!)
     */
 
     if ((X == Y) || (X == Z) || (Y == Z)) return(ErrCode_Same);
@@ -2461,30 +2461,30 @@ ErrCode BitVector_Mul_Pos(unsigned int *  X, unsigned int *  Y, unsigned int *
     *sign &= mask;
     mask &= ~ (mask >> 1);
     for ( count = 0; (ok && (count <= limit)); count++ )
-    {
+      {
         if ( BIT_VECTOR_TST_BIT(Z,count) )
-        {
+          {
             carry = false;
             overflow = BitVector_compute(X,X,Y,false,&carry);
             if (strict) ok = ! (carry || overflow);
             else        ok = !  carry;
-        }
+          }
         if (ok && (count < limit))
-        {
+          {
             carry = BitVector_shift_left(Y,0);
             if (strict)
-            {
+              {
                 overflow = ((*sign & mask) != 0);
                 ok = ! (carry || overflow);
-            }
+              }
             else ok = ! carry;
-        }
-    }
+          }
+      }
     if (ok) return(ErrCode_Ok); else return(ErrCode_Ovfl);
-}
+  }
 
-ErrCode BitVector_Multiply(unsigned int *  X, unsigned int *  Y, unsigned int *  Z)
-{
+  ErrCode BitVector_Multiply(unsigned int *  X, unsigned int *  Y, unsigned int *  Z)
+  {
     ErrCode error = ErrCode_Ok;
     unsigned int  bit_x = bits_(X);
     unsigned int  bit_y = bits_(Y);
@@ -2502,22 +2502,22 @@ ErrCode BitVector_Multiply(unsigned int *  X, unsigned int *  Y, unsigned int *
     unsigned int *  B;
 
     /*
-       Requirements:
-         -  Y && Z must have equal sizes
-         -  X must have at least the same size as Y && Z but may be larger (!)
-       Features:
-         -  The contents of Y && Z are preserved
-         -  X may be identical with Y or Z (or both!)
-            (in-place multiplication is possible!)
+      Requirements:
+      -  Y && Z must have equal sizes
+      -  X must have at least the same size as Y && Z but may be larger (!)
+      Features:
+      -  The contents of Y && Z are preserved
+      -  X may be identical with Y or Z (or both!)
+      (in-place multiplication is possible!)
     */
 
     if ((bit_y != bit_z) || (bit_x < bit_y)) return(ErrCode_Size);
     if (BitVector_is_empty(Y) || BitVector_is_empty(Z))
-    {
+      {
         BitVector_Empty(X);
-    }
+      }
     else
-    {
+      {
         A = BitVector_Create(bit_y,false);
         if (A == NULL) return(ErrCode_Null);
         B = BitVector_Create(bit_z,false);
@@ -2534,37 +2534,37 @@ ErrCode BitVector_Multiply(unsigned int *  X, unsigned int *  Y, unsigned int *
         ptr_z = B + size;
         zero = true;
         while (zero && (size-- > 0))
-        {
+          {
             zero &= (*(--ptr_y) == 0);
             zero &= (*(--ptr_z) == 0);
-        }
+          }
         if (*ptr_y > *ptr_z)
-        {
+          {
             if (bit_x > bit_y)
-            {
+              {
                 A = BitVector_Resize(A,bit_x);
                 if (A == NULL) { BitVector_Destroy(B); return(ErrCode_Null); }
-            }
+              }
             error = BitVector_Mul_Pos(X,A,B,true);
-        }
+          }
         else
-        {
+          {
             if (bit_x > bit_z)
-            {
+              {
                 B = BitVector_Resize(B,bit_x);
                 if (B == NULL) { BitVector_Destroy(A); return(ErrCode_Null); }
-            }
+              }
             error = BitVector_Mul_Pos(X,B,A,true);
-        }
+          }
         if ((! error) && sgn_x) BitVector_Negate(X,X);
         BitVector_Destroy(A);
         BitVector_Destroy(B);
-    }
+      }
     return(error);
-}
+  }
 
-ErrCode BitVector_Div_Pos(unsigned int *  Q, unsigned int *  X, unsigned int *  Y, unsigned int *  R)
-{
+  ErrCode BitVector_Div_Pos(unsigned int *  Q, unsigned int *  X, unsigned int *  Y, unsigned int *  R)
+  {
     unsigned int  bits = bits_(Q);
     unsigned int  mask;
     unsigned int *  addr;
@@ -2573,56 +2573,56 @@ ErrCode BitVector_Div_Pos(unsigned int *  Q, unsigned int *  X, unsigned int *
     boolean copy = false; /* flags whether valid rest is in R (0) || X (1) */
 
     /*
-       Requirements:
-         -  All bit vectors must have equal sizes
-         -  Q, X, Y && R must all be distinct bit vectors
-         -  Y must be non-zero (of course!)
-       Constraints:
-         -  The contents of X (&& Q && R, of course) are destroyed
-            (only Y is preserved!)
+      Requirements:
+      -  All bit vectors must have equal sizes
+      -  Q, X, Y && R must all be distinct bit vectors
+      -  Y must be non-zero (of course!)
+      Constraints:
+      -  The contents of X (&& Q && R, of course) are destroyed
+      (only Y is preserved!)
     */
 
     if ((bits != bits_(X)) || (bits != bits_(Y)) || (bits != bits_(R)))
-        return(ErrCode_Size);
+      return(ErrCode_Size);
     if ((Q == X) || (Q == Y) || (Q == R) || (X == Y) || (X == R) || (Y == R))
-        return(ErrCode_Same);
+      return(ErrCode_Same);
     if (BitVector_is_empty(Y))
-        return(ErrCode_Zero);
+      return(ErrCode_Zero);
 
     BitVector_Empty(R);
     BitVector_Copy(Q,X);
     if ((last = Set_Max(Q)) < 0L) return(ErrCode_Ok);
     bits = (unsigned int) ++last;
     while (bits-- > 0)
-    {
+      {
         addr = Q + (bits >> LOGBITS);
         mask = BITMASKTAB[bits & MODMASK];
         flag = ((*addr & mask) != 0);
         if (copy)
-        {
+          {
             BitVector_shift_left(X,flag);
             flag = false;
             BitVector_compute(R,X,Y,true,&flag);
-        }
+          }
         else
-        {
+          {
             BitVector_shift_left(R,flag);
             flag = false;
             BitVector_compute(X,R,Y,true,&flag);
-        }
+          }
         if (flag) *addr &= ~ mask;
         else
-        {
+          {
             *addr |= mask;
             copy = ! copy;
-        }
-    }
+          }
+      }
     if (copy) BitVector_Copy(R,X);
     return(ErrCode_Ok);
-}
+  }
 
-ErrCode BitVector_Divide(unsigned int *  Q, unsigned int *  X, unsigned int *  Y, unsigned int *  R)
-{
+  ErrCode BitVector_Divide(unsigned int *  Q, unsigned int *  X, unsigned int *  Y, unsigned int *  R)
+  {
     ErrCode error = ErrCode_Ok;
     unsigned int  bits = bits_(Q);
     unsigned int  size = size_(Q);
@@ -2635,32 +2635,32 @@ ErrCode BitVector_Divide(unsigned int *  Q, unsigned int *  X, unsigned int *  Y
     unsigned int *  B;
 
     /*
-       Requirements:
-         -  All bit vectors must have equal sizes
-         -  Q && R must be two distinct bit vectors
-         -  Y must be non-zero (of course!)
-       Features:
-         -  The contents of X && Y are preserved
-         -  Q may be identical with X || Y (or both)
-            (in-place division is possible!)
-         -  R may be identical with X || Y (or both)
-            (but not identical with Q!)
+      Requirements:
+      -  All bit vectors must have equal sizes
+      -  Q && R must be two distinct bit vectors
+      -  Y must be non-zero (of course!)
+      Features:
+      -  The contents of X && Y are preserved
+      -  Q may be identical with X || Y (or both)
+      (in-place division is possible!)
+      -  R may be identical with X || Y (or both)
+      (but not identical with Q!)
     */
 
     if ((bits != bits_(X)) || (bits != bits_(Y)) || (bits != bits_(R)))
-        return(ErrCode_Size);
+      return(ErrCode_Size);
     if (Q == R)
-        return(ErrCode_Same);
+      return(ErrCode_Same);
     if (BitVector_is_empty(Y))
-        return(ErrCode_Zero);
+      return(ErrCode_Zero);
 
     if (BitVector_is_empty(X))
-    {
+      {
         BitVector_Empty(Q);
         BitVector_Empty(R);
-    }
+      }
     else
-    {
+      {
         A = BitVector_Create(bits,false);
         if (A == NULL) return(ErrCode_Null);
         B = BitVector_Create(bits,false);
@@ -2672,18 +2672,18 @@ ErrCode BitVector_Divide(unsigned int *  Q, unsigned int *  X, unsigned int *  Y
         if (sgn_x) BitVector_Negate(A,X); else BitVector_Copy(A,X);
         if (sgn_y) BitVector_Negate(B,Y); else BitVector_Copy(B,Y);
         if (! (error = BitVector_Div_Pos(Q,A,B,R)))
-        {
+          {
             if (sgn_q) BitVector_Negate(Q,Q);
             if (sgn_x) BitVector_Negate(R,R);
-        }
+          }
         BitVector_Destroy(A);
         BitVector_Destroy(B);
-    }
+      }
     return(error);
-}
+  }
 
-ErrCode BitVector_GCD(unsigned int *  X, unsigned int *  Y, unsigned int *  Z)
-{
+  ErrCode BitVector_GCD(unsigned int *  X, unsigned int *  Y, unsigned int *  Z)
+  {
     ErrCode error = ErrCode_Ok;
     unsigned int  bits = bits_(X);
     unsigned int  size = size_(X);
@@ -2699,82 +2699,82 @@ ErrCode BitVector_GCD(unsigned int *  X, unsigned int *  Y, unsigned int *  Z)
     unsigned int *  T;
 
     /*
-       Requirements:
-         -  All bit vectors must have equal sizes
-       Features:
-         -  The contents of Y && Z are preserved
-         -  X may be identical with Y || Z (or both)
-            (in-place is possible!)
-         -  GCD(0,z) == GCD(z,0) == z
-         -  negative values are h&&led correctly
+      Requirements:
+      -  All bit vectors must have equal sizes
+      Features:
+      -  The contents of Y && Z are preserved
+      -  X may be identical with Y || Z (or both)
+      (in-place is possible!)
+      -  GCD(0,z) == GCD(z,0) == z
+      -  negative values are h&&led correctly
     */
 
     if ((bits != bits_(Y)) || (bits != bits_(Z))) return(ErrCode_Size);
     if (BitVector_is_empty(Y))
-    {
+      {
         if (X != Z) BitVector_Copy(X,Z);
         return(ErrCode_Ok);
-    }
+      }
     if (BitVector_is_empty(Z))
-    {
+      {
         if (X != Y) BitVector_Copy(X,Y);
         return(ErrCode_Ok);
-    }
+      }
     Q = BitVector_Create(bits,false);
     if (Q == NULL)
-    {
+      {
         return(ErrCode_Null);
-    }
+      }
     R = BitVector_Create(bits,false);
     if (R == NULL)
-    {
+      {
         BitVector_Destroy(Q);
         return(ErrCode_Null);
-    }
+      }
     A = BitVector_Create(bits,false);
     if (A == NULL)
-    {
+      {
         BitVector_Destroy(Q);
         BitVector_Destroy(R);
         return(ErrCode_Null);
-    }
+      }
     B = BitVector_Create(bits,false);
     if (B == NULL)
-    {
+      {
         BitVector_Destroy(Q);
         BitVector_Destroy(R);
         BitVector_Destroy(A);
         return(ErrCode_Null);
-    }
+      }
     size--;
     sgn_a = (((*(Y+size) &= mask) & msb) != 0);
     sgn_b = (((*(Z+size) &= mask) & msb) != 0);
     if (sgn_a) BitVector_Negate(A,Y); else BitVector_Copy(A,Y);
     if (sgn_b) BitVector_Negate(B,Z); else BitVector_Copy(B,Z);
     while (! error)
-    {
+      {
         if (! (error = BitVector_Div_Pos(Q,A,B,R)))
-        {
+          {
             if (BitVector_is_empty(R)) break;
             T = A; sgn_r = sgn_a;
             A = B; sgn_a = sgn_b;
             B = R; sgn_b = sgn_r;
             R = T;
-        }
-    }
+          }
+      }
     if (! error)
-    {
+      {
         if (sgn_b) BitVector_Negate(X,B); else BitVector_Copy(X,B);
-    }
+      }
     BitVector_Destroy(Q);
     BitVector_Destroy(R);
     BitVector_Destroy(A);
     BitVector_Destroy(B);
     return(error);
-}
+  }
 
-ErrCode BitVector_GCD2(unsigned int *  U, unsigned int *  V, unsigned int *  W, unsigned int *  X, unsigned int *  Y)
-{
+  ErrCode BitVector_GCD2(unsigned int *  U, unsigned int *  V, unsigned int *  W, unsigned int *  X, unsigned int *  Y)
+  {
     ErrCode error = ErrCode_Ok;
     unsigned int  bits = bits_(U);
     unsigned int  size = size_(U);
@@ -2803,49 +2803,49 @@ ErrCode BitVector_GCD2(unsigned int *  U, unsigned int *  V, unsigned int *  W,
     unsigned int *  Z;
 
     /*
-       Requirements:
-         -  All bit vectors must have equal sizes
-         -  U, V, && W must all be distinct bit vectors
-       Features:
-         -  The contents of X && Y are preserved
-         -  U, V && W may be identical with X || Y (or both,
-            provided that U, V && W are mutually distinct)
-            (i.e., in-place is possible!)
-         -  GCD(0,z) == GCD(z,0) == z
-         -  negative values are h&&led correctly
+      Requirements:
+      -  All bit vectors must have equal sizes
+      -  U, V, && W must all be distinct bit vectors
+      Features:
+      -  The contents of X && Y are preserved
+      -  U, V && W may be identical with X || Y (or both,
+      provided that U, V && W are mutually distinct)
+      (i.e., in-place is possible!)
+      -  GCD(0,z) == GCD(z,0) == z
+      -  negative values are h&&led correctly
     */
 
     if ((bits != bits_(V)) ||
         (bits != bits_(W)) ||
         (bits != bits_(X)) ||
         (bits != bits_(Y)))
-    {
+      {
         return(ErrCode_Size);
-    }
+      }
     if ((U == V) || (U == W) || (V == W))
-    {
+      {
         return(ErrCode_Same);
-    }
+      }
     if (BitVector_is_empty(X))
-    {
+      {
         if (U != Y) BitVector_Copy(U,Y);
         BitVector_Empty(V);
         BitVector_Empty(W);
         *W = 1;
         return(ErrCode_Ok);
-    }
+      }
     if (BitVector_is_empty(Y))
-    {
+      {
         if (U != X) BitVector_Copy(U,X);
         BitVector_Empty(V);
         BitVector_Empty(W);
         *V = 1;
         return(ErrCode_Ok);
-    }
+      }
     if ((L = BitVector_Create_List(bits,false,11)) == NULL)
-    {
+      {
         return(ErrCode_Null);
-    }
+      }
     Q  = L[0];
     R  = L[1];
     A  = L[2];
@@ -2871,43 +2871,43 @@ ErrCode BitVector_GCD2(unsigned int *  U, unsigned int *  V, unsigned int *  W,
     sgn_x = false;
     sgn_y = false;
     while (! error)
-    {
+      {
         if ((error = BitVector_Div_Pos(Q,A,B,R)))
-        {
+          {
             break;
-        }
+          }
         if (BitVector_is_empty(R))
-        {
+          {
             break;
-        }
+          }
         sgn_q = sgn_a ^ sgn_b;
 
         if (sgn_x) BitVector_Negate(Z,X2); else BitVector_Copy(Z,X2);
         if ((error = BitVector_Mul_Pos(X3,Z,Q,true)))
-        {
+          {
             break;
-        }
+          }
         minus = ! (sgn_x ^ sgn_q);
         carry = 0;
         if (BitVector_compute(X3,X1,X3,minus,&carry))
-        {
+          {
             error = ErrCode_Ovfl;
             break;
-        }
+          }
         sgn_x = (((*(X3+size) &= mask) & msb) != 0);
 
         if (sgn_y) BitVector_Negate(Z,Y2); else BitVector_Copy(Z,Y2);
         if ((error = BitVector_Mul_Pos(Y3,Z,Q,true)))
-        {
+          {
             break;
-        }
+          }
         minus = ! (sgn_y ^ sgn_q);
         carry = 0;
         if (BitVector_compute(Y3,Y1,Y3,minus,&carry))
-        {
+          {
             error = ErrCode_Ovfl;
             break;
-        }
+          }
         sgn_y = (((*(Y3+size) &= mask) & msb) != 0);
 
         T = A; sgn_r = sgn_a;
@@ -2924,19 +2924,19 @@ ErrCode BitVector_GCD2(unsigned int *  U, unsigned int *  V, unsigned int *  W,
         Y1 = Y2;
         Y2 = Y3;
         Y3 = T;
-    }
+      }
     if (! error)
-    {
+      {
         if (sgn_b) BitVector_Negate(U,B); else BitVector_Copy(U,B);
         BitVector_Copy(V,X2);
         BitVector_Copy(W,Y2);
-    }
+      }
     BitVector_Destroy_List(L,11);
     return(error);
-}
+  }
 
-ErrCode BitVector_Power(unsigned int *  X, unsigned int *  Y, unsigned int *  Z)
-{
+  ErrCode BitVector_Power(unsigned int *  X, unsigned int *  Y, unsigned int *  Z)
+  {
     ErrCode error = ErrCode_Ok;
     unsigned int  bits  = bits_(X);
     boolean first = true;
@@ -2946,56 +2946,56 @@ ErrCode BitVector_Power(unsigned int *  X, unsigned int *  Y, unsigned int *  Z)
     unsigned int *  T;
 
     /*
-       Requirements:
-         -  X must have at least the same size as Y but may be larger (!)
-         -  X may not be identical with Z
-         -  Z must be positive
-       Features:
-         -  The contents of Y && Z are preserved
+      Requirements:
+      -  X must have at least the same size as Y but may be larger (!)
+      -  X may not be identical with Z
+      -  Z must be positive
+      Features:
+      -  The contents of Y && Z are preserved
     */
 
     if (X == Z) return(ErrCode_Same);
     if (bits < bits_(Y)) return(ErrCode_Size);
     if (BitVector_msb_(Z)) return(ErrCode_Expo);
     if ((last = Set_Max(Z)) < 0L)
-    {
+      {
         if (bits < 2) return(ErrCode_Ovfl);
         BitVector_Empty(X);
         *X |= LSB;
         return(ErrCode_Ok);                             /* anything ^ 0 == 1 */
-    }
+      }
     if (BitVector_is_empty(Y))
-    {
+      {
         if (X != Y) BitVector_Empty(X);
         return(ErrCode_Ok);                    /* 0 ^ anything ! zero == 0 */
-    }
+      }
     T = BitVector_Create(bits,false);
     if (T == NULL) return(ErrCode_Null);
     limit = (unsigned int) last;
     for ( count = 0; ((!error) && (count <= limit)); count++ )
-    {
+      {
         if ( BIT_VECTOR_TST_BIT(Z,count) )
-        {
+          {
             if (first)
-            {
+              {
                 first = false;
                 if (count) {             BitVector_Copy(X,T); }
                 else       { if (X != Y) BitVector_Copy(X,Y); }
-            }
+              }
             else error = BitVector_Multiply(X,T,X); /* order important because T > X */
-        }
+          }
         if ((!error) && (count < limit))
-        {
+          {
             if (count) error = BitVector_Multiply(T,T,T);
             else       error = BitVector_Multiply(T,Y,Y);
-        }
-    }
+          }
+      }
     BitVector_Destroy(T);
     return(error);
-}
+  }
 
-void BitVector_Block_Store(unsigned int *  addr, unsigned char * buffer, unsigned int length)
-{
+  void BitVector_Block_Store(unsigned int *  addr, unsigned char * buffer, unsigned int length)
+  {
     unsigned int  size = size_(addr);
     unsigned int  mask = mask_(addr);
     unsigned int  value;
@@ -3003,22 +3003,22 @@ void BitVector_Block_Store(unsigned int *  addr, unsigned char * buffer, unsigne
 
     /* provide translation for independence of endian-ness: */
     if (size > 0)
-    {
+      {
         while (size-- > 0)
-        {
+          {
             value = 0;
             for ( count = 0; (length > 0) && (count < BITS); count += 8 )
-            {
+              {
                 value |= (((unsigned int) *buffer++) << count); length--;
-            }
+              }
             *addr++ = value;
-        }
+          }
         *(--addr) &= mask;
-    }
-}
+      }
+  }
 
-unsigned char * BitVector_Block_Read(unsigned int *  addr, unsigned int * length)
-{
+  unsigned char * BitVector_Block_Read(unsigned int *  addr, unsigned int * length)
+  {
     unsigned int  size = size_(addr);
     unsigned int  value;
     unsigned int  count;
@@ -3031,100 +3031,100 @@ unsigned char * BitVector_Block_Read(unsigned int *  addr, unsigned int * length
     if (buffer == NULL) return(NULL);
     target = buffer;
     if (size > 0)
-    {
+      {
         *(addr+size-1) &= mask_(addr);
         while (size-- > 0)
-        {
+          {
             value = *addr++;
             count = BITS >> 3;
             while (count-- > 0)
-            {
+              {
                 *target++ = (unsigned char) (value & 0x00FF);
                 if (count > 0) value >>= 8;
-            }
-        }
-    }
+              }
+          }
+      }
     *target = (unsigned char) '\0';
     return(buffer);
-}
+  }
 
-void BitVector_Word_Store(unsigned int *  addr, unsigned int offset, unsigned int value)
-{
+  void BitVector_Word_Store(unsigned int *  addr, unsigned int offset, unsigned int value)
+  {
     unsigned int size = size_(addr);
 
     if (size > 0)
-    {
+      {
         if (offset < size) *(addr+offset) = value;
         *(addr+size-1) &= mask_(addr);
-    }
-}
+      }
+  }
 
-unsigned int BitVector_Word_Read(unsigned int *  addr, unsigned int offset)
-{
+  unsigned int BitVector_Word_Read(unsigned int *  addr, unsigned int offset)
+  {
     unsigned int size = size_(addr);
 
     if (size > 0)
-    {
+      {
         *(addr+size-1) &= mask_(addr);
         if (offset < size) return( *(addr+offset) );
-    }
+      }
     return( (unsigned int) 0 );
-}
+  }
 
-void BitVector_Word_Insert(unsigned int *  addr, unsigned int offset, unsigned int count,
-                           boolean clear)
-{
+  void BitVector_Word_Insert(unsigned int *  addr, unsigned int offset, unsigned int count,
+                             boolean clear)
+  {
     unsigned int  size = size_(addr);
     unsigned int  mask = mask_(addr);
     unsigned int *  last = addr+size-1;
 
     if (size > 0)
-    {
+      {
         *last &= mask;
         if (offset > size) offset = size;
         BIT_VECTOR_ins_words(addr+offset,size-offset,count,clear);
         *last &= mask;
-    }
-}
+      }
+  }
 
-void BitVector_Word_Delete(unsigned int *  addr, unsigned int offset, unsigned int count,
-                           boolean clear)
-{
+  void BitVector_Word_Delete(unsigned int *  addr, unsigned int offset, unsigned int count,
+                             boolean clear)
+  {
     unsigned int  size = size_(addr);
     unsigned int  mask = mask_(addr);
     unsigned int *  last = addr+size-1;
 
     if (size > 0)
-    {
+      {
         *last &= mask;
         if (offset > size) offset = size;
         BIT_VECTOR_del_words(addr+offset,size-offset,count,clear);
         *last &= mask;
-    }
-}
+      }
+  }
 
-void BitVector_Chunk_Store(unsigned int *  addr, unsigned int chunksize, unsigned int offset,
-                           unsigned long value)
-{
+  void BitVector_Chunk_Store(unsigned int *  addr, unsigned int chunksize, unsigned int offset,
+                             unsigned long value)
+  {
     unsigned int bits = bits_(addr);
     unsigned int mask;
     unsigned int temp;
 
     if ((chunksize > 0) && (offset < bits))
-    {
+      {
         if (chunksize > LONGBITS) chunksize = LONGBITS;
         if ((offset + chunksize) > bits) chunksize = bits - offset;
         addr += offset >> LOGBITS;
         offset &= MODMASK;
         while (chunksize > 0)
-        {
+          {
             mask = (unsigned int) (~0L << offset);
             bits = offset + chunksize;
             if (bits < BITS)
-            {
+              {
                 mask &= (unsigned int) ~(~0L << bits);
                 bits = chunksize;
-            }
+              }
             else bits = BITS - offset;
             temp = (unsigned int) (value << offset);
             temp &= mask;
@@ -3133,12 +3133,12 @@ void BitVector_Chunk_Store(unsigned int *  addr, unsigned int chunksize, unsigne
             value >>= bits;
             chunksize -= bits;
             offset = 0;
-        }
-    }
-}
+          }
+      }
+  }
 
-unsigned long BitVector_Chunk_Read(unsigned int *  addr, unsigned int chunksize, unsigned int offset)
-{
+  unsigned long BitVector_Chunk_Read(unsigned int *  addr, unsigned int chunksize, unsigned int offset)
+  {
     unsigned int bits = bits_(addr);
     unsigned int chunkbits = 0;
     unsigned long value = 0L;
@@ -3146,121 +3146,121 @@ unsigned long BitVector_Chunk_Read(unsigned int *  addr, unsigned int chunksize,
     unsigned int mask;
 
     if ((chunksize > 0) && (offset < bits))
-    {
+      {
         if (chunksize > LONGBITS) chunksize = LONGBITS;
         if ((offset + chunksize) > bits) chunksize = bits - offset;
         addr += offset >> LOGBITS;
         offset &= MODMASK;
         while (chunksize > 0)
-        {
+          {
             bits = offset + chunksize;
             if (bits < BITS)
-            {
+              {
                 mask = (unsigned int) ~(~0L << bits);
                 bits = chunksize;
-            }
+              }
             else
-            {
+              {
                 mask = (unsigned int) ~0L;
                 bits = BITS - offset;
-            }
+              }
             temp = (unsigned long) ((*addr++ & mask) >> offset);
             value |= temp << chunkbits;
             chunkbits += bits;
             chunksize -= bits;
             offset = 0;
-        }
-    }
+          }
+      }
     return(value);
-}
+  }
 
-    /*******************/
-    /* set operations: */
-    /*******************/
+  /*******************/
+  /* set operations: */
+  /*******************/
 
-void Set_Union(unsigned int *  X, unsigned int *  Y, unsigned int *  Z)             /* X = Y + Z     */
-{
+  void Set_Union(unsigned int *  X, unsigned int *  Y, unsigned int *  Z)             /* X = Y + Z     */
+  {
     unsigned int bits = bits_(X);
     unsigned int size = size_(X);
     unsigned int mask = mask_(X);
 
     if ((size > 0) && (bits == bits_(Y)) && (bits == bits_(Z)))
-    {
+      {
         while (size-- > 0) *X++ = *Y++ | *Z++;
         *(--X) &= mask;
-    }
-}
+      }
+  }
 
-void Set_Intersection(unsigned int *  X, unsigned int *  Y, unsigned int *  Z)      /* X = Y * Z     */
-{
+  void Set_Intersection(unsigned int *  X, unsigned int *  Y, unsigned int *  Z)      /* X = Y * Z     */
+  {
     unsigned int bits = bits_(X);
     unsigned int size = size_(X);
     unsigned int mask = mask_(X);
 
     if ((size > 0) && (bits == bits_(Y)) && (bits == bits_(Z)))
-    {
+      {
         while (size-- > 0) *X++ = *Y++ & *Z++;
         *(--X) &= mask;
-    }
-}
+      }
+  }
 
-void Set_Difference(unsigned int *  X, unsigned int *  Y, unsigned int *  Z)        /* X = Y \ Z     */
-{
+  void Set_Difference(unsigned int *  X, unsigned int *  Y, unsigned int *  Z)        /* X = Y \ Z     */
+  {
     unsigned int bits = bits_(X);
     unsigned int size = size_(X);
     unsigned int mask = mask_(X);
 
     if ((size > 0) && (bits == bits_(Y)) && (bits == bits_(Z)))
-    {
+      {
         while (size-- > 0) *X++ = *Y++ & ~ *Z++;
         *(--X) &= mask;
-    }
-}
+      }
+  }
 
-void Set_ExclusiveOr(unsigned int *  X, unsigned int *  Y, unsigned int *  Z)       /* X=(Y+Z)\(Y*Z) */
-{
+  void Set_ExclusiveOr(unsigned int *  X, unsigned int *  Y, unsigned int *  Z)       /* X=(Y+Z)\(Y*Z) */
+  {
     unsigned int bits = bits_(X);
     unsigned int size = size_(X);
     unsigned int mask = mask_(X);
 
     if ((size > 0) && (bits == bits_(Y)) && (bits == bits_(Z)))
-    {
+      {
         while (size-- > 0) *X++ = *Y++ ^ *Z++;
         *(--X) &= mask;
-    }
-}
+      }
+  }
 
-void Set_Complement(unsigned int *  X, unsigned int *  Y)                   /* X = ~Y        */
-{
+  void Set_Complement(unsigned int *  X, unsigned int *  Y)                   /* X = ~Y        */
+  {
     unsigned int size = size_(X);
     unsigned int mask = mask_(X);
 
     if ((size > 0) && (bits_(X) == bits_(Y)))
-    {
+      {
         while (size-- > 0) *X++ = ~ *Y++;
         *(--X) &= mask;
-    }
-}
+      }
+  }
 
-    /******************/
-    /* set functions: */
-    /******************/
+  /******************/
+  /* set functions: */
+  /******************/
 
-boolean Set_subset(unsigned int *  X, unsigned int *  Y)                    /* X subset Y ?  */
-{
+  boolean Set_subset(unsigned int *  X, unsigned int *  Y)                    /* X subset Y ?  */
+  {
     unsigned int size = size_(X);
     boolean r = false;
 
     if ((size > 0) && (bits_(X) == bits_(Y)))
-    {
+      {
         r = true;
         while (r && (size-- > 0)) r = ((*X++ & ~ *Y++) == 0);
-    }
+      }
     return(r);
-}
+  }
 
-unsigned int Set_Norm(unsigned int *  addr)                                /* = | X |       */
-{
+  unsigned int Set_Norm(unsigned int *  addr)                                /* = | X |       */
+  {
     unsigned char * byte;
     unsigned int  bytes;
     unsigned int   n;
@@ -3269,76 +3269,76 @@ unsigned int Set_Norm(unsigned int *  addr)                                /* =
     bytes = size_(addr) << FACTOR;
     n = 0;
     while (bytes-- > 0)
-    {
+      {
         n += BitVector_BYTENORM[*byte++];
-    }
+      }
     return(n);
-}
+  }
 
-unsigned int Set_Norm2(unsigned int *  addr)                               /* = | X |       */
-{
+  unsigned int Set_Norm2(unsigned int *  addr)                               /* = | X |       */
+  {
     unsigned int  size = size_(addr);
     unsigned int  w0,w1;
     unsigned int   n,k;
 
     n = 0;
     while (size-- > 0)
-    {
+      {
         k = 0;
         w1 = ~ (w0 = *addr++);
         while (w0 && w1)
-        {
+          {
             w0 &= w0 - 1;
             w1 &= w1 - 1;
             k++;
-        }
+          }
         if (w0 == 0) n += k;
         else         n += BITS - k;
-    }
+      }
     return(n);
-}
+  }
 
-unsigned int Set_Norm3(unsigned int *  addr)                               /* = | X |       */
-{
+  unsigned int Set_Norm3(unsigned int *  addr)                               /* = | X |       */
+  {
     unsigned int  size  = size_(addr);
     unsigned int   count = 0;
     unsigned int  c;
 
     while (size-- > 0)
-    {
+      {
         c = *addr++;
         while (c)
-        {
+          {
             c &= c - 1;
             count++;
-        }
-    }
+          }
+      }
     return(count);
-}
+  }
 
-signed long Set_Min(unsigned int *  addr)                                /* = min(X)      */
-{
+  signed long Set_Min(unsigned int *  addr)                                /* = min(X)      */
+  {
     boolean empty = true;
     unsigned int  size  = size_(addr);
     unsigned int  i     = 0;
     unsigned int  c     = 0;         /* silence compiler warning */
 
     while (empty && (size-- > 0))
-    {
+      {
         if ((c = *addr++)) empty = false; else i++;
-    }
+      }
     if (empty) return((signed long) LONG_MAX);                  /* plus infinity  */
     i <<= LOGBITS;
     while (! (c & LSB))
-    {
+      {
         c >>= 1;
         i++;
-    }
+      }
     return((signed long) i);
-}
+  }
 
-signed long Set_Max(unsigned int *  addr)                                /* = max(X)      */
-{
+  signed long Set_Max(unsigned int *  addr)                                /* = max(X)      */
+  {
     boolean empty = true;
     unsigned int  size  = size_(addr);
     unsigned int  i     = size;
@@ -3346,27 +3346,27 @@ signed long Set_Max(unsigned int *  addr)                                /* = ma
 
     addr += size-1;
     while (empty && (size-- > 0))
-    {
+      {
         if ((c = *addr--)) empty = false; else i--;
-    }
+      }
     if (empty) return((signed long) LONG_MIN);                  /* minus infinity */
     i <<= LOGBITS;
     while (! (c & MSB))
-    {
+      {
         c <<= 1;
         i--;
-    }
+      }
     return((signed long) --i);
-}
+  }
 
-    /**********************************/
-    /* matrix-of-booleans operations: */
-    /**********************************/
+  /**********************************/
+  /* matrix-of-booleans operations: */
+  /**********************************/
 
-void Matrix_Multiplication(unsigned int *  X, unsigned int rowsX, unsigned int colsX,
-                           unsigned int *  Y, unsigned int rowsY, unsigned int colsY,
-                           unsigned int *  Z, unsigned int rowsZ, unsigned int colsZ)
-{
+  void Matrix_Multiplication(unsigned int *  X, unsigned int rowsX, unsigned int colsX,
+                             unsigned int *  Y, unsigned int rowsY, unsigned int colsY,
+                             unsigned int *  Z, unsigned int rowsZ, unsigned int colsZ)
+  {
     unsigned int i;
     unsigned int j;
     unsigned int k;
@@ -3377,37 +3377,37 @@ void Matrix_Multiplication(unsigned int *  X, unsigned int rowsX, unsigned int c
     unsigned int termY;
     unsigned int sum;
 
-  if ((colsY == rowsZ) && (rowsX == rowsY) && (colsX == colsZ) &&
-      (bits_(X) == rowsX*colsX) &&
-      (bits_(Y) == rowsY*colsY) &&
-      (bits_(Z) == rowsZ*colsZ))
-  {
-    for ( i = 0; i < rowsY; i++ )
-    {
-        termX = i * colsX;
-        termY = i * colsY;
-        for ( j = 0; j < colsZ; j++ )
-        {
-            indxX = termX + j;
-            sum = 0;
-            for ( k = 0; k < colsY; k++ )
-            {
-                indxY = termY + k;
-                indxZ = k * colsZ + j;
-                if ( BIT_VECTOR_TST_BIT(Y,indxY) &
-                     BIT_VECTOR_TST_BIT(Z,indxZ) ) sum ^= 1;
-            }
-            if (sum) BIT_VECTOR_SET_BIT(X,indxX)
-            else     BIT_VECTOR_CLR_BIT(X,indxX)
-        }
-    }
+    if ((colsY == rowsZ) && (rowsX == rowsY) && (colsX == colsZ) &&
+        (bits_(X) == rowsX*colsX) &&
+        (bits_(Y) == rowsY*colsY) &&
+        (bits_(Z) == rowsZ*colsZ))
+      {
+        for ( i = 0; i < rowsY; i++ )
+          {
+            termX = i * colsX;
+            termY = i * colsY;
+            for ( j = 0; j < colsZ; j++ )
+              {
+                indxX = termX + j;
+                sum = 0;
+                for ( k = 0; k < colsY; k++ )
+                  {
+                    indxY = termY + k;
+                    indxZ = k * colsZ + j;
+                    if ( BIT_VECTOR_TST_BIT(Y,indxY) &
+                         BIT_VECTOR_TST_BIT(Z,indxZ) ) sum ^= 1;
+                  }
+                if (sum) BIT_VECTOR_SET_BIT(X,indxX)
+                           else     BIT_VECTOR_CLR_BIT(X,indxX)
+                                      }
+          }
+      }
   }
-}
 
-void Matrix_Product(unsigned int *  X, unsigned int rowsX, unsigned int colsX,
-                    unsigned int *  Y, unsigned int rowsY, unsigned int colsY,
-                    unsigned int *  Z, unsigned int rowsZ, unsigned int colsZ)
-{
+  void Matrix_Product(unsigned int *  X, unsigned int rowsX, unsigned int colsX,
+                      unsigned int *  Y, unsigned int rowsY, unsigned int colsY,
+                      unsigned int *  Z, unsigned int rowsZ, unsigned int colsZ)
+  {
     unsigned int i;
     unsigned int j;
     unsigned int k;
@@ -3418,35 +3418,35 @@ void Matrix_Product(unsigned int *  X, unsigned int rowsX, unsigned int colsX,
     unsigned int termY;
     unsigned int sum;
 
-  if ((colsY == rowsZ) && (rowsX == rowsY) && (colsX == colsZ) &&
-      (bits_(X) == rowsX*colsX) &&
-      (bits_(Y) == rowsY*colsY) &&
-      (bits_(Z) == rowsZ*colsZ))
-  {
-    for ( i = 0; i < rowsY; i++ )
-    {
-        termX = i * colsX;
-        termY = i * colsY;
-        for ( j = 0; j < colsZ; j++ )
-        {
-            indxX = termX + j;
-            sum = 0;
-            for ( k = 0; k < colsY; k++ )
-            {
-                indxY = termY + k;
-                indxZ = k * colsZ + j;
-                if ( BIT_VECTOR_TST_BIT(Y,indxY) &
-                     BIT_VECTOR_TST_BIT(Z,indxZ) ) sum |= 1;
-            }
-            if (sum) BIT_VECTOR_SET_BIT(X,indxX)
-            else     BIT_VECTOR_CLR_BIT(X,indxX)
-        }
-    }
+    if ((colsY == rowsZ) && (rowsX == rowsY) && (colsX == colsZ) &&
+        (bits_(X) == rowsX*colsX) &&
+        (bits_(Y) == rowsY*colsY) &&
+        (bits_(Z) == rowsZ*colsZ))
+      {
+        for ( i = 0; i < rowsY; i++ )
+          {
+            termX = i * colsX;
+            termY = i * colsY;
+            for ( j = 0; j < colsZ; j++ )
+              {
+                indxX = termX + j;
+                sum = 0;
+                for ( k = 0; k < colsY; k++ )
+                  {
+                    indxY = termY + k;
+                    indxZ = k * colsZ + j;
+                    if ( BIT_VECTOR_TST_BIT(Y,indxY) &
+                         BIT_VECTOR_TST_BIT(Z,indxZ) ) sum |= 1;
+                  }
+                if (sum) BIT_VECTOR_SET_BIT(X,indxX)
+                           else     BIT_VECTOR_CLR_BIT(X,indxX)
+                                      }
+          }
+      }
   }
-}
 
-void Matrix_Closure(unsigned int *  addr, unsigned int rows, unsigned int cols)
-{
+  void Matrix_Closure(unsigned int *  addr, unsigned int rows, unsigned int cols)
+  {
     unsigned int i;
     unsigned int j;
     unsigned int k;
@@ -3457,36 +3457,36 @@ void Matrix_Closure(unsigned int *  addr, unsigned int rows, unsigned int cols)
     unsigned int termi;
     unsigned int termk;
 
-  if ((rows == cols) && (bits_(addr) == rows*cols))
-  {
-    for ( i = 0; i < rows; i++ )
-    {
-        ii = i * cols + i;
-        BIT_VECTOR_SET_BIT(addr,ii)
-    }
-    for ( k = 0; k < rows; k++ )
-    {
-        termk = k * cols;
+    if ((rows == cols) && (bits_(addr) == rows*cols))
+      {
         for ( i = 0; i < rows; i++ )
-        {
-            termi = i * cols;
-            ik = termi + k;
-            for ( j = 0; j < rows; j++ )
-            {
-                ij = termi + j;
-                kj = termk + j;
-                if ( BIT_VECTOR_TST_BIT(addr,ik) &
-                     BIT_VECTOR_TST_BIT(addr,kj) )
-                     BIT_VECTOR_SET_BIT(addr,ij)
-            }
-        }
-    }
+          {
+            ii = i * cols + i;
+            BIT_VECTOR_SET_BIT(addr,ii)
+              }
+        for ( k = 0; k < rows; k++ )
+          {
+            termk = k * cols;
+            for ( i = 0; i < rows; i++ )
+              {
+                termi = i * cols;
+                ik = termi + k;
+                for ( j = 0; j < rows; j++ )
+                  {
+                    ij = termi + j;
+                    kj = termk + j;
+                    if ( BIT_VECTOR_TST_BIT(addr,ik) &
+                         BIT_VECTOR_TST_BIT(addr,kj) )
+                      BIT_VECTOR_SET_BIT(addr,ij)
+                        }
+              }
+          }
+      }
   }
-}
 
-void Matrix_Transpose(unsigned int *  X, unsigned int rowsX, unsigned int colsX,
-                      unsigned int *  Y, unsigned int rowsY, unsigned int colsY)
-{
+  void Matrix_Transpose(unsigned int *  X, unsigned int rowsX, unsigned int colsX,
+                        unsigned int *  Y, unsigned int rowsY, unsigned int colsY)
+  {
     unsigned int  i;
     unsigned int  j;
     unsigned int  ii;
@@ -3502,66 +3502,66 @@ void Matrix_Transpose(unsigned int *  X, unsigned int rowsX, unsigned int colsX,
     unsigned int  termj;
     boolean swap;
 
-  /* BEWARE that "in-place" is ONLY possible if the matrix is quadratic!! */
-
-  if ((rowsX == colsY) && (colsX == rowsY) &&
-      (bits_(X) == rowsX*colsX) &&
-      (bits_(Y) == rowsY*colsY))
-  {
-    if (rowsY == colsY) /* in-place is possible! */
-    {
-        for ( i = 0; i < rowsY; i++ )
-        {
-            termi = i * colsY;
-            for ( j = 0; j < i; j++ )
-            {
-                termj = j * colsX;
-                ij = termi + j;
-                ji = termj + i;
-                addij = ij >> LOGBITS;
-                addji = ji >> LOGBITS;
-                bitij = BITMASKTAB[ij & MODMASK];
-                bitji = BITMASKTAB[ji & MODMASK];
-                swap = ((*(Y+addij) & bitij) != 0);
-                if ((*(Y+addji) & bitji) != 0)
-                     *(X+addij) |=     bitij;
-                else
-                     *(X+addij) &= ~ bitij;
-                if (swap)
-                     *(X+addji) |=     bitji;
-                else
-                     *(X+addji) &= ~ bitji;
-            }
-            ii = termi + i;
-            addii = ii >> LOGBITS;
-            bitii = BITMASKTAB[ii & MODMASK];
-            if ((*(Y+addii) & bitii) != 0)
-                 *(X+addii) |=     bitii;
-            else
-                 *(X+addii) &= ~ bitii;
-        }
-    }
-    else /* rowsX != colsX, in-place is ~ possible! */
-    {
-        for ( i = 0; i < rowsY; i++ )
-        {
-            termi = i * colsY;
-            for ( j = 0; j < colsY; j++ )
-            {
-                termj = j * colsX;
-                ij = termi + j;
-                ji = termj + i;
-                addij = ij >> LOGBITS;
-                addji = ji >> LOGBITS;
-                bitij = BITMASKTAB[ij & MODMASK];
-                bitji = BITMASKTAB[ji & MODMASK];
-                if ((*(Y+addij) & bitij) != 0)
-                     *(X+addji) |=     bitji;
+    /* BEWARE that "in-place" is ONLY possible if the matrix is quadratic!! */
+
+    if ((rowsX == colsY) && (colsX == rowsY) &&
+        (bits_(X) == rowsX*colsX) &&
+        (bits_(Y) == rowsY*colsY))
+      {
+        if (rowsY == colsY) /* in-place is possible! */
+          {
+            for ( i = 0; i < rowsY; i++ )
+              {
+                termi = i * colsY;
+                for ( j = 0; j < i; j++ )
+                  {
+                    termj = j * colsX;
+                    ij = termi + j;
+                    ji = termj + i;
+                    addij = ij >> LOGBITS;
+                    addji = ji >> LOGBITS;
+                    bitij = BITMASKTAB[ij & MODMASK];
+                    bitji = BITMASKTAB[ji & MODMASK];
+                    swap = ((*(Y+addij) & bitij) != 0);
+                    if ((*(Y+addji) & bitji) != 0)
+                      *(X+addij) |=     bitij;
+                    else
+                      *(X+addij) &= ~ bitij;
+                    if (swap)
+                      *(X+addji) |=     bitji;
+                    else
+                      *(X+addji) &= ~ bitji;
+                  }
+                ii = termi + i;
+                addii = ii >> LOGBITS;
+                bitii = BITMASKTAB[ii & MODMASK];
+                if ((*(Y+addii) & bitii) != 0)
+                  *(X+addii) |=     bitii;
                 else
-                     *(X+addji) &= ~ bitji;
-            }
-        }
-    }
+                  *(X+addii) &= ~ bitii;
+              }
+          }
+        else /* rowsX != colsX, in-place is ~ possible! */
+          {
+            for ( i = 0; i < rowsY; i++ )
+              {
+                termi = i * colsY;
+                for ( j = 0; j < colsY; j++ )
+                  {
+                    termj = j * colsX;
+                    ij = termi + j;
+                    ji = termj + i;
+                    addij = ij >> LOGBITS;
+                    addji = ji >> LOGBITS;
+                    bitij = BITMASKTAB[ij & MODMASK];
+                    bitji = BITMASKTAB[ji & MODMASK];
+                    if ((*(Y+addij) & bitij) != 0)
+                      *(X+addji) |=     bitji;
+                    else
+                      *(X+addji) &= ~ bitji;
+                  }
+              }
+          }
+      }
   }
-}
 }; //end of namespace CONSTANTBV
index 47e0c56f20b776b30454af351b1d53277e472818..3241b4555643b0b2be28fedebfd53f79fc0b11af 100644 (file)
@@ -62,23 +62,23 @@ namespace CONSTANTBV {
 #endif
 
     typedef enum {
-        ErrCode_Ok = 0,    /* everything went allright                       */        
-        ErrCode_Type,      /* types word and size_t have incompatible sizes  */
-        ErrCode_Bits,      /* bits of word and sizeof(word) are inconsistent */
-        ErrCode_Word,      /* size of word is less than 16 bits              */
-        ErrCode_Long,      /* size of word is greater than size of long      */
-        ErrCode_Powr,      /* number of bits of word is not a power of two   */
-        ErrCode_Loga,      /* error in calculation of logarithm              */        
-        ErrCode_Null,      /* unable to allocate memory                      */        
-        ErrCode_Indx,      /* index out of range                             */
-        ErrCode_Ordr,      /* minimum > maximum index                        */
-        ErrCode_Size,      /* bit vector size mismatch                       */
-        ErrCode_Pars,      /* input string syntax error                      */
-        ErrCode_Ovfl,      /* numeric overflow error                         */
-        ErrCode_Same,      /* operands must be distinct                      */
-        ErrCode_Expo,      /* exponent must be positive                      */
-        ErrCode_Zero       /* division by zero error                         */
-      } ErrCode;
+      ErrCode_Ok = 0,    /* everything went allright                       */   
+      ErrCode_Type,      /* types word and size_t have incompatible sizes  */
+      ErrCode_Bits,      /* bits of word and sizeof(word) are inconsistent */
+      ErrCode_Word,      /* size of word is less than 16 bits              */
+      ErrCode_Long,      /* size of word is greater than size of long      */
+      ErrCode_Powr,      /* number of bits of word is not a power of two   */
+      ErrCode_Loga,      /* error in calculation of logarithm              */   
+      ErrCode_Null,      /* unable to allocate memory                      */   
+      ErrCode_Indx,      /* index out of range                             */
+      ErrCode_Ordr,      /* minimum > maximum index                        */
+      ErrCode_Size,      /* bit vector size mismatch                       */
+      ErrCode_Pars,      /* input string syntax error                      */
+      ErrCode_Ovfl,      /* numeric overflow error                         */
+      ErrCode_Same,      /* operands must be distinct                      */
+      ErrCode_Expo,      /* exponent must be positive                      */
+      ErrCode_Zero       /* division by zero error                         */
+    } ErrCode;
 
 
     /* ===> MISCELLANEOUS BASIC FUNCTIONS: <=== */
@@ -129,14 +129,14 @@ namespace CONSTANTBV {
     void    BitVector_Interval_Reverse    (unsigned int * addr, unsigned int lower, unsigned int upper);
     
     boolean BitVector_interval_scan_inc   (unsigned int * addr, unsigned int start,
-                                          unsigned int * min, unsigned int * max);
+                                           unsigned int * min, unsigned int * max);
     boolean BitVector_interval_scan_dec   (unsigned int * addr, unsigned int start,
-                                          unsigned int * min, unsigned int * max);
+                                           unsigned int * min, unsigned int * max);
     void    BitVector_Interval_Copy       (unsigned int * X, unsigned int * Y, 
-                                          unsigned int Xoffset, unsigned int Yoffset, unsigned int length);
+                                           unsigned int Xoffset, unsigned int Yoffset, unsigned int length);
     unsigned int * BitVector_Interval_Substitute(unsigned int * X, unsigned int * Y,
-                                                unsigned int Xoffset, unsigned int Xlength,
-                                                unsigned int Yoffset, unsigned int Ylength);
+                                                 unsigned int Xoffset, unsigned int Xlength,
+                                                 unsigned int Yoffset, unsigned int Ylength);
 
     /* ===> bit vector test functions: */
     boolean BitVector_is_empty            (unsigned int * addr);                         /* X == {} ?   */
@@ -176,19 +176,19 @@ namespace CONSTANTBV {
     
     /* ===> bit vector insert/delete bits: */
     void    BitVector_Insert              (unsigned int * addr, 
-                                          unsigned int offset, unsigned int count, boolean clear);
+                                           unsigned int offset, unsigned int count, boolean clear);
     void    BitVector_Delete              (unsigned int * addr, 
-                                          unsigned int offset, unsigned int count, boolean clear);
+                                           unsigned int offset, unsigned int count, boolean clear);
     
     /* ===> bit vector arithmetic: */
     boolean BitVector_increment           (unsigned int * addr);                        /*  X++  */
     boolean BitVector_decrement           (unsigned int * addr);                        /*  X--  */
     boolean BitVector_compute             (unsigned int * X, unsigned int * Y, 
-                                          unsigned int * Z, boolean minus, boolean *carry);
+                                           unsigned int * Z, boolean minus, boolean *carry);
     boolean BitVector_add                 (unsigned int * X, 
-                                          unsigned int * Y, unsigned int * Z, boolean *carry);
+                                           unsigned int * Y, unsigned int * Z, boolean *carry);
     boolean BitVector_sub                 (unsigned int * X, 
-                                          unsigned int * Y, unsigned int * Z, boolean *carry); /* X = Y-Z*/
+                                           unsigned int * Y, unsigned int * Z, boolean *carry); /* X = Y-Z*/
     boolean BitVector_inc                 (unsigned int * X, unsigned int * Y);
     boolean BitVector_dec                 (unsigned int * X, unsigned int * Y);
     
@@ -196,33 +196,33 @@ namespace CONSTANTBV {
     void    BitVector_Absolute            (unsigned int * X, unsigned int * Y);
     signed int   BitVector_Sign           (unsigned int * addr);
     ErrCode BitVector_Mul_Pos             (unsigned int * X, 
-                                          unsigned int * Y, unsigned int * Z, boolean strict);
+                                           unsigned int * Y, unsigned int * Z, boolean strict);
     ErrCode BitVector_Multiply            (unsigned int * X, unsigned int * Y, unsigned int * Z);
     ErrCode BitVector_Div_Pos             (unsigned int * Q, unsigned int * X, unsigned int * Y, unsigned int * R);
     ErrCode BitVector_Divide              (unsigned int * Q, unsigned int * X, unsigned int * Y, unsigned int * R);
     ErrCode BitVector_GCD                 (unsigned int * X, unsigned int * Y, unsigned int * Z);
     ErrCode BitVector_GCD2                (unsigned int * U, unsigned int * V, unsigned int * W,      /*   O   */
-                                          unsigned int * X, unsigned int * Y);     /*   I   */
+                                           unsigned int * X, unsigned int * Y);     /*   I   */
     ErrCode BitVector_Power               (unsigned int * X, unsigned int * Y, unsigned int * Z);
     
     /* ===> direct memory access functions: */
     void    BitVector_Block_Store         (unsigned int * addr, 
-                                          unsigned char * buffer, unsigned int length);
+                                           unsigned char * buffer, unsigned int length);
     unsigned char * BitVector_Block_Read  (unsigned int * addr, unsigned int * length);
     
     /* ===> word array functions: */
     void    BitVector_Word_Store          (unsigned int * addr, unsigned int offset, unsigned int value);
     unsigned int   BitVector_Word_Read    (unsigned int * addr, unsigned int offset);
     void    BitVector_Word_Insert         (unsigned int * addr, 
-                                          unsigned int offset, unsigned int count, boolean clear);
+                                           unsigned int offset, unsigned int count, boolean clear);
     void    BitVector_Word_Delete         (unsigned int * addr, 
-                                          unsigned int offset, unsigned int count, boolean clear);
+                                           unsigned int offset, unsigned int count, boolean clear);
     
     /* ===> arbitrary size chunk functions: */
     void    BitVector_Chunk_Store         (unsigned int * addr, unsigned int chunksize,
-                                          unsigned int offset, unsigned long value);
+                                           unsigned int offset, unsigned long value);
     unsigned long  BitVector_Chunk_Read   (unsigned int * addr, 
-                                          unsigned int chunksize,unsigned int offset);
+                                           unsigned int chunksize,unsigned int offset);
     
     /* ===> set operations: */
     void    Set_Union                     (unsigned int * X, unsigned int * Y, unsigned int * Z); /* X = Y + Z */
@@ -241,14 +241,14 @@ namespace CONSTANTBV {
     
     /* ===> matrix-of-booleans operations: */
     void    Matrix_Multiplication         (unsigned int * X, unsigned int rowsX, unsigned int colsX,
-                                          unsigned int * Y, unsigned int rowsY, unsigned int colsY,
-                                          unsigned int * Z, unsigned int rowsZ, unsigned int colsZ);
+                                           unsigned int * Y, unsigned int rowsY, unsigned int colsY,
+                                           unsigned int * Z, unsigned int rowsZ, unsigned int colsZ);
     void    Matrix_Product                (unsigned int * X, unsigned int rowsX, unsigned int colsX,
-                                          unsigned int * Y, unsigned int rowsY, unsigned int colsY,
-                                          unsigned int * Z, unsigned int rowsZ, unsigned int colsZ);
+                                           unsigned int * Y, unsigned int rowsY, unsigned int colsY,
+                                           unsigned int * Z, unsigned int rowsZ, unsigned int colsZ);
     void    Matrix_Closure                (unsigned int * addr, unsigned int rows, unsigned int cols);
     void    Matrix_Transpose              (unsigned int * X, unsigned int rowsX, unsigned int colsX,
-                                          unsigned int * Y, unsigned int rowsY, unsigned int colsY);
+                                           unsigned int * Y, unsigned int rowsY, unsigned int colsY);
     
     /*****************************************************************************/
     /*  MODULE RESOURCES:                                                        */
index 659a91c4eecf88cb8ad0a0b42d521ca766e74d99..0f65e21ccefe170736e63dae7bda314c06c97b58 100644 (file)
@@ -44,7 +44,7 @@ namespace BEEV {
   //returns the var.
   ASTNode BeevMgr::ResolveID(const ASTNode& v) {
     if (_letid_expr_map == NULL)
-         InitializeLetIDMap();
+      InitializeLetIDMap();
 
     if(v.GetKind() != SYMBOL) {
       return v;
@@ -57,9 +57,9 @@ namespace BEEV {
     ASTNodeMap::iterator it;
     if((it =_letid_expr_map->find(v)) != _letid_expr_map->end()) {
       if(it->second == ASTUndefined) 
-       FatalError("Unresolved Identifier: ",v);
+        FatalError("Unresolved Identifier: ",v);
       else
-       return it->second;
+        return it->second;
     }
 
     //this is to mark the let-var as undefined. the let var is defined
@@ -76,28 +76,28 @@ namespace BEEV {
   // This function simply cleans up the LetID -> LetExpr Map.   
   void BeevMgr::CleanupLetIDMap(void) { 
 
-   // ext/hash_map::clear() is very expensive on big empty lists. shortcut. 
+    // ext/hash_map::clear() is very expensive on big empty lists. shortcut. 
     if (_letid_expr_map->size()  ==0)
-       return;
+      return;
 
 
     ASTNodeMap::iterator it = _letid_expr_map->begin();
     ASTNodeMap::iterator itend = _letid_expr_map->end();
     for(;it!=itend;it++) {
       if(it->second != ASTUndefined) {
-       it->first.SetValueWidth(0);
-       it->first.SetIndexWidth(0);
+        it->first.SetValueWidth(0);
+        it->first.SetIndexWidth(0);
       }
     }
 
-  // May contain lots of buckets, so reset.
+    // May contain lots of buckets, so reset.
     delete _letid_expr_map;
     _letid_expr_map = new ASTNodeMap();
 
   }
 
- void BeevMgr::InitializeLetIDMap(void)
 void BeevMgr::InitializeLetIDMap(void)
   {
-       _letid_expr_map = new ASTNodeMap();
+    _letid_expr_map = new ASTNodeMap();
   }
 };
index 73d87cc1e87d0e23d5a0542289b8ea9905c33f6b..0cb181e073b0e47ad40ab73993563a472b46c23f 100644 (file)
@@ -24,7 +24,7 @@
 #include <unistd.h>
 
 #ifdef EXT_HASH_MAP
-  using namespace __gnu_cxx;
+using namespace __gnu_cxx;
 #endif
 
 /* GLOBAL FUNCTION: parser
@@ -35,8 +35,8 @@ extern int cvcparse();
 
 namespace BEEV
 {
-extern BEEV::ASTNode SingleBitOne;
-extern BEEV::ASTNode SingleBitZero;
+  extern BEEV::ASTNode SingleBitOne;
+  extern BEEV::ASTNode SingleBitZero;
 }
 
 const string version = "$Id$";
@@ -99,96 +99,96 @@ int main(int argc, char ** argv) {
     if(argv[i][0] == '-') {
       switch(argv[i][1]) {
       case 'a' :
-       BEEV::optimize_flag = false;
-       break;
+        BEEV::optimize_flag = false;
+        break;
       case 'b':
-       BEEV::print_STPinput_back_flag = true;
-       break;
+        BEEV::print_STPinput_back_flag = true;
+        break;
       case 'c':
-       BEEV::construct_counterexample_flag = true;
-       break;
+        BEEV::construct_counterexample_flag = true;
+        break;
       case 'd':
-       BEEV::construct_counterexample_flag = true;
-       BEEV::check_counterexample_flag = true;
-       break;
+        BEEV::construct_counterexample_flag = true;
+        BEEV::check_counterexample_flag = true;
+        break;
       case 'h':
-       fprintf(stderr,usage,prog);
-       cout << helpstring;
-       //BEEV::FatalError("");
-       return -1;
-       break;
+        fprintf(stderr,usage,prog);
+        cout << helpstring;
+        //BEEV::FatalError("");
+        return -1;
+        break;
       case 'n':
-       BEEV::print_output_flag = true;
-       break;
+        BEEV::print_output_flag = true;
+        break;
       case 'm':
-       BEEV::smtlib_parser_flag=true;
-       BEEV::division_by_zero_returns_one = true;
-       break;
+        BEEV::smtlib_parser_flag=true;
+        BEEV::division_by_zero_returns_one = true;
+        break;
       case 'p':
-       BEEV::print_counterexample_flag = true;
-       break;
+        BEEV::print_counterexample_flag = true;
+        break;
       case 'y':
-       BEEV::print_binary_flag = true;
-       break;
+        BEEV::print_binary_flag = true;
+        break;
       case 'q':
-       BEEV::print_arrayval_declaredorder_flag = true;
-       break;
+        BEEV::print_arrayval_declaredorder_flag = true;
+        break;
       case 'r':
-       BEEV::arrayread_refinement_flag = false;
-       break;
+        BEEV::arrayread_refinement_flag = false;
+        break;
       case 's' :
-       BEEV::stats_flag = true;
-       break;
+        BEEV::stats_flag = true;
+        break;
       case 'u':
-       BEEV::arraywrite_refinement_flag = false;
-       break;
+        BEEV::arraywrite_refinement_flag = false;
+        break;
       case 'v' :
-       BEEV::print_nodes_flag = true;
-       break;
+        BEEV::print_nodes_flag = true;
+        break;
       case 'w':
-       BEEV::wordlevel_solve_flag = false;
-       break;
+        BEEV::wordlevel_solve_flag = false;
+        break;
       case 'x':
-       BEEV::xor_flatten_flag = true;
-       break;
+        BEEV::xor_flatten_flag = true;
+        break;
       case 'z':
-       BEEV::print_sat_varorder_flag = true;
-       break;
+        BEEV::print_sat_varorder_flag = true;
+        break;
       default:
-       fprintf(stderr,usage,prog);
-       cout << helpstring;
-       //BEEV::FatalError("");
-       return -1;
-       break;
+        fprintf(stderr,usage,prog);
+        cout << helpstring;
+        //BEEV::FatalError("");
+        return -1;
+        break;
       }
       if(argv[i][2]) {
-       fprintf(stderr, "Multiple character options are not allowed.\n");
-       fprintf(stderr, "(for example: -ab is not an abbreviation for -a -b)\n");
-       fprintf(stderr,usage,prog);
-       cout << helpstring;
-       return -1;
+        fprintf(stderr, "Multiple character options are not allowed.\n");
+        fprintf(stderr, "(for example: -ab is not an abbreviation for -a -b)\n");
+        fprintf(stderr,usage,prog);
+        cout << helpstring;
+        return -1;
       }
     } else {
       infile = argv[i];
 
       if (BEEV::smtlib_parser_flag)
-       {
-         smtin = fopen(infile,"r");
-         if(smtin == NULL)
-           {
-             fprintf(stderr,"%s: Error: cannot open %s\n",prog,infile);
-             BEEV::FatalError("");
-           }
-       }
+        {
+          smtin = fopen(infile,"r");
+          if(smtin == NULL)
+            {
+              fprintf(stderr,"%s: Error: cannot open %s\n",prog,infile);
+              BEEV::FatalError("");
+            }
+        }
       else
-       {
-         cvcin = fopen(infile,"r");
-         if(cvcin == NULL)
-           {
-             fprintf(stderr,"%s: Error: cannot open %s\n",prog,infile);
-             BEEV::FatalError("");
-           }
-       }
+        {
+          cvcin = fopen(infile,"r");
+          if(cvcin == NULL)
+            {
+              fprintf(stderr,"%s: Error: cannot open %s\n",prog,infile);
+              BEEV::FatalError("");
+            }
+        }
     }
   }
 
index cd1ff6c5103f918c68f2e1a20f72d71c670e355c..4d68ab63fdd7416ea7b3ef5496874602cc18521d 100644 (file)
 //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
-               {
-                       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;
-                               }
-                       }
-                       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;
-                       }
-                       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_flag && 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 READ:
-//             {
-//               if(BVCONST != lhs[1].GetKind() || READ != rhs.GetKind() || 
-//                    BVCONST != rhs[1].GetKind() || lhs == rhs) 
-//               {
-//                 return eq;
-//               }
-//               else 
-//               {
-//                 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_flag)
-       {
-               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;              
-               //_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_flag && 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 CheckEvenEqn
-
-//solve an eqn whose monomials have only even coefficients
-ASTNode BVSolver::BVSolve_Even(const ASTNode& input)
-{
-       if (!wordlevel_solve_flag)
-       {
-               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;
-                       }
-
-                       //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()
+  //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
+          {
+            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;
+                }
+            }
+          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;
+              }
+            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_flag && 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 READ:
+        //              {
+        //                if(BVCONST != lhs[1].GetKind() || READ != rhs.GetKind() || 
+        //                     BVCONST != rhs[1].GetKind() || lhs == rhs) 
+        //                {
+        //                  return eq;
+        //                }
+        //                else 
+        //                {
+        //                  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_flag)
+      {
+        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;              
+        //_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_flag && 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 CheckEvenEqn
+
+  //solve an eqn whose monomials have only even coefficients
+  ASTNode BVSolver::BVSolve_Even(const ASTNode& input)
+  {
+    if (!wordlevel_solve_flag)
+      {
+        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;
+              }
+
+            //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 1d4409b1723bd23aa582a5cf2b6ef8c2468c2f18..49adb53dc500b7fef524a8302dca23e8f7010af6 100644 (file)
 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
+  //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 44e523758003e6bdd09e271b110b355d93e358ce..b4920d3b89cad5619a3d803447b56c70ab7ddd2e 100644 (file)
 namespace BEEV
 {
 
-bool BeevMgr::CheckMap(ASTNodeMap* VarConstMap, 
-                      const ASTNode& key, ASTNode& output)
-{
-        if(NULL == VarConstMap)
-       {
-                return false;
-       }
-       ASTNodeMap::iterator it;
-       if ((it = VarConstMap->find(key)) != VarConstMap->end())
-       {
-               output = it->second;
-               return true;
-       }
-       return false;
-}
-
-
-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;
-}
-
-// Push any reference count used by the key to the value.
-void BeevMgr::UpdateSimplifyMap(const ASTNode& key, const ASTNode& value, bool pushNeg)
-{
-       // If there are references to the key, add them to the references of the value.
-       ASTNodeCountMap::const_iterator itKey, itValue;
-       itKey = ReferenceCount->find(key);
-       if (itKey != ReferenceCount->end())
-       {
-               itValue = ReferenceCount->find(value);
-               if (itValue != ReferenceCount->end())
-                       (*ReferenceCount)[value] = itValue->second + itKey->second;
-               else
-                       (*ReferenceCount)[value] = itKey->second;
-       }
-
-
-       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;
-
-       assert(e0 != e1); // One side should be a variable, the other a constant.
-
-       //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))
-       {
-               assert((e1.GetKind() == TRUE) || (e1.GetKind() == FALSE) || (e1.GetKind() == BVCONST));
-               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))
-       {
-               assert((e0.GetKind() == TRUE) || (e0.GetKind() == FALSE) || (e0.GetKind() == BVCONST));
-               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)))
-               // ||
-               //            k2 == READ && b[0].GetKind() == SYMBOL && b[1].GetKind() == 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, ASTNodeMap* VarConstMap)
-{
-       Begin_RemoveWrites = false;
-       ASTNode out = SimplifyFormula(b, pushNeg, VarConstMap);
-       return out;
-}
-
-void BeevMgr::BuildReferenceCountMap(const ASTNode& b)
-{
-       if (b.GetChildren().size() == 0)
-               return;
-
-       ASTNodeCountMap::iterator it, itend;
-
-       it = ReferenceCount->find(b);
-       if (it == ReferenceCount->end())
-       {
-               (*ReferenceCount)[b] = 1;
-       }
-       else
-       {
-               (*ReferenceCount)[b] = it->second + 1;
-               return;
-       }
-
-       const ASTVec& c = b.GetChildren();
-       ASTVec::const_iterator itC = c.begin();
-       ASTVec::const_iterator itendC = c.end();
-       for (; itC != itendC; itC++)
-       {
-               BuildReferenceCountMap(*itC);
-       }
-}
-
-ASTNode BeevMgr::SimplifyFormula_TopLevel(const ASTNode& b, bool pushNeg)
-{
-       ResetSimplifyMaps();
-       BuildReferenceCountMap(b);
-       ASTNode out = SimplifyFormula(b, pushNeg);
-       ResetSimplifyMaps();
-       return out;
-}
-
-ASTNode BeevMgr::SimplifyFormula(const ASTNode& b, bool pushNeg, ASTNodeMap* VarConstMap)
-{
-       if (!optimize_flag)
-               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 || FOR == kind || isAtomic(kind)))
-       {
-               SortByArith(ca);
-               a = CreateNode(kind, ca);
-       }
-
-       ASTNode output;
-       if (CheckSimplifyMap(a, output, pushNeg))
-               return output;
-
-       a = PullUpITE(a);
-       kind = a.GetKind(); // pullUpITE can change the Kind of the node.
-
-       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;
-               case FOR:
-                       output = SimplifyForFormula(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::SimplifyForFormula(const ASTNode& a, bool pushNeg, ASTNodeMap* VarConstMap) {
-        //FIXME: Code this up properly later. Mainly pushing the negation down
+  bool BeevMgr::CheckMap(ASTNodeMap* VarConstMap, 
+                         const ASTNode& key, ASTNode& output)
+  {
+    if(NULL == VarConstMap)
+      {
+        return false;
+      }
+    ASTNodeMap::iterator it;
+    if ((it = VarConstMap->find(key)) != VarConstMap->end())
+      {
+        output = it->second;
+        return true;
+      }
+    return false;
+  }
+
+
+  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;
+  }
+
+  // Push any reference count used by the key to the value.
+  void BeevMgr::UpdateSimplifyMap(const ASTNode& key, const ASTNode& value, bool pushNeg)
+  {
+    // If there are references to the key, add them to the references of the value.
+    ASTNodeCountMap::const_iterator itKey, itValue;
+    itKey = ReferenceCount->find(key);
+    if (itKey != ReferenceCount->end())
+      {
+        itValue = ReferenceCount->find(value);
+        if (itValue != ReferenceCount->end())
+          (*ReferenceCount)[value] = itValue->second + itKey->second;
+        else
+          (*ReferenceCount)[value] = itKey->second;
+      }
+
+
+    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;
+
+    assert(e0 != e1); // One side should be a variable, the other a constant.
+
+    //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))
+      {
+        assert((e1.GetKind() == TRUE) || (e1.GetKind() == FALSE) || (e1.GetKind() == BVCONST));
+        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))
+      {
+        assert((e0.GetKind() == TRUE) || (e0.GetKind() == FALSE) || (e0.GetKind() == BVCONST));
+        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)))
+      // ||
+      //              k2 == READ && b[0].GetKind() == SYMBOL && b[1].GetKind() == 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, ASTNodeMap* VarConstMap)
+  {
+    Begin_RemoveWrites = false;
+    ASTNode out = SimplifyFormula(b, pushNeg, VarConstMap);
+    return out;
+  }
+
+  void BeevMgr::BuildReferenceCountMap(const ASTNode& b)
+  {
+    if (b.GetChildren().size() == 0)
+      return;
+
+    ASTNodeCountMap::iterator it, itend;
+
+    it = ReferenceCount->find(b);
+    if (it == ReferenceCount->end())
+      {
+        (*ReferenceCount)[b] = 1;
+      }
+    else
+      {
+        (*ReferenceCount)[b] = it->second + 1;
+        return;
+      }
+
+    const ASTVec& c = b.GetChildren();
+    ASTVec::const_iterator itC = c.begin();
+    ASTVec::const_iterator itendC = c.end();
+    for (; itC != itendC; itC++)
+      {
+        BuildReferenceCountMap(*itC);
+      }
+  }
+
+  ASTNode BeevMgr::SimplifyFormula_TopLevel(const ASTNode& b, bool pushNeg)
+  {
+    ResetSimplifyMaps();
+    BuildReferenceCountMap(b);
+    ASTNode out = SimplifyFormula(b, pushNeg);
+    ResetSimplifyMaps();
+    return out;
+  }
+
+  ASTNode BeevMgr::SimplifyFormula(const ASTNode& b, bool pushNeg, ASTNodeMap* VarConstMap)
+  {
+    if (!optimize_flag)
+      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 || FOR == kind || isAtomic(kind)))
+      {
+        SortByArith(ca);
+        a = CreateNode(kind, ca);
+      }
+
+    ASTNode output;
+    if (CheckSimplifyMap(a, output, pushNeg))
+      return output;
+
+    a = PullUpITE(a);
+    kind = a.GetKind(); // pullUpITE can change the Kind of the node.
+
+    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;
+      case FOR:
+        output = SimplifyForFormula(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::SimplifyForFormula(const ASTNode& a, bool pushNeg, ASTNodeMap* VarConstMap) {
+    //FIXME: Code this up properly later. Mainly pushing the negation down
+    return a;
+  }
+
+  ASTNode BeevMgr::SimplifyAtomicFormula(const ASTNode& a, bool pushNeg, ASTNodeMap* VarConstMap)
+  {
+    if (!optimize_flag)
+      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;
+  }
+
+  //Look through the AND Node for terms that contradict.
+  //Should be made significantly more general..
+  ASTNode BeevMgr::RemoveContradictionsFromAND(const ASTNode& in)
+  {
+    assert(AND == in.GetKind());
+    const int childrenSize = in.GetChildren().size();
+
+    for (int i = 0; i < childrenSize; i++)
+      {
+        if (BVLT != in[i].GetKind())
+          continue;
+
+        for (int j = i + 1; j < childrenSize; j++)
+          {
+            if (BVLT != in[j].GetKind())
+              continue;
+            if (in[i][0] == in[j][1] && in[i][1] == in[j][0]) // parameters are swapped.
+              return ASTFalse;
+          }
+      }
+    return in;
+  }
+
+  // turns say (bvslt (ite a  b c) (ite a d e)) INTO (ite a (bvslt b d) (bvslt c e))
+  // Expensive. But makes some other simplifications possible.
+  ASTNode BeevMgr::PullUpITE(const ASTNode& in)
+  {
+    if (2 != in.GetChildren().size())
+      return in;
+    if (ITE != in[0].GetKind())
+      return in;
+    if (ITE != in[1].GetKind())
+      return in;
+    if (in[0][0] != in[1][0]) // if the conditional is not equal.
+      return in;
+
+    // Consider equals. It takes bitvectors and returns a boolean.
+    // Consider add. It takes bitvectors and returns bitvectors.
+    // Consider concat. The bitwidth of each side could vary.
+
+    ASTNode l1;
+    ASTNode l2;
+    ASTNode result;
+
+    if (in.GetType() == BOOLEAN_TYPE)
+      {
+        l1 = CreateNode(in.GetKind(), in[0][1], in[1][1]);
+        l2 = CreateNode(in.GetKind(), in[0][2], in[1][2]);
+        result = CreateNode(ITE, in[0][0], l1, l2);
+      }
+    else
+      {
+        l1 = CreateTerm(in.GetKind(), in.GetValueWidth(), in[0][1], in[1][1]);
+        l2 = CreateTerm(in.GetKind(), in.GetValueWidth(), in[0][2], in[1][2]);
+        result = CreateTerm(ITE, in.GetValueWidth(), in[0][0], l1, l2);
+      }
+
+    assert(result.GetType() == in.GetType());
+    assert(result.GetValueWidth() == in.GetValueWidth());
+    assert(result.GetIndexWidth() == in.GetIndexWidth());
+    assert(BVTypeCheck(result));
+
+    return result;
+  }
+
+  //takes care of some simple ITE Optimizations in the context of equations
+  ASTNode BeevMgr::ITEOpt_InEqs(const ASTNode& in, ASTNodeMap* VarConstMap)
+  {
+    CountersAndStats("ITEOpts_InEqs");
+
+    if (!(EQ == in.GetKind() && optimize_flag))
+      {
+        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, VarConstMap);
+            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, VarConstMap);
+            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_flag)
+    //  {
+    //          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_flag)
+      {
+        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_flag)
+      {
+        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;
+          }
+      }
+    ASTNode result = CreateNode(ITE, t0, t1, t2);
+    BVTypeCheck(result);
+    return result;
+  }
+
+  ASTNode BeevMgr::SimplifyAndOrFormula(const ASTNode& a, bool pushNeg, ASTNodeMap* VarConstMap)
+  {
+    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, VarConstMap);
+        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, VarConstMap);
+          }
+        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, VarConstMap);
+          break;
+        }
+      default:
+        {
+          output = (isAnd) ? (pushNeg ? CreateNode(OR, outvec) : CreateNode(AND, outvec)) : (pushNeg ? CreateNode(AND, outvec) : CreateNode(OR,
+                                                                                                                                            outvec));
+          //output = FlattenOneLevel(output);
+          break;
+        }
+      }
+
+    // I haven't verified this is useful.
+    //if (output.GetKind() == AND)
+    //  output = RemoveContradictionsFromAND(output);
+
+    //memoize
+    UpdateSimplifyMap(a, output, pushNeg);
+    //cerr << "output:\n" << output << endl;
+    return output;
+  } //end of SimplifyAndOrFormula
+
+
+  ASTNode BeevMgr::SimplifyNotFormula(const ASTNode& a, bool pushNeg, ASTNodeMap* VarConstMap)
+  {
+    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, VarConstMap);
+      }
+    //memoize
+    UpdateSimplifyMap(o, output, pn);
+    UpdateSimplifyMap(a, output, pushNeg);
+    return output;
+  }
+
+  ASTNode BeevMgr::SimplifyXorFormula(const ASTNode& a, bool pushNeg, ASTNodeMap* VarConstMap)
+  {
+    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, VarConstMap);
+    ASTNode a1 = SimplifyFormula(a[1], false, VarConstMap);
+    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, ASTNodeMap* VarConstMap)
+  {
+    ASTNode output, a0, a1;
+    if (CheckSimplifyMap(a, output, pushNeg))
+      return output;
+
+    //the two NOTs cancel out
+    if (pushNeg)
+      {
+        a0 = SimplifyFormula(a[0], false, VarConstMap);
+        a1 = SimplifyFormula(a[1], false, VarConstMap);
+        output = CreateNode(AND, a0, a1);
+      }
+    else
+      {
+        //push the NOT implicit in the NAND
+        a0 = SimplifyFormula(a[0], true, VarConstMap);
+        a1 = SimplifyFormula(a[1], true, VarConstMap);
+        output = CreateNode(OR, a0, a1);
+      }
+
+    //memoize
+    UpdateSimplifyMap(a, output, pushNeg);
+    return output;
+  }
+
+  ASTNode BeevMgr::SimplifyNorFormula(const ASTNode& a, bool pushNeg, ASTNodeMap* VarConstMap)
+  {
+    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, VarConstMap);
+        output = CreateNode(OR, a0, a1);
+      }
+    else
+      {
+        //push the NOT implicit in the NAND
+        a0 = SimplifyFormula(a[0], true, VarConstMap);
+        a1 = SimplifyFormula(a[1], true, VarConstMap);
+        output = CreateNode(AND, a0, a1);
+      }
+
+    //memoize
+    UpdateSimplifyMap(a, output, pushNeg);
+    return output;
+  }
+
+  ASTNode BeevMgr::SimplifyImpliesFormula(const ASTNode& a, bool pushNeg, ASTNodeMap* VarConstMap)
+  {
+    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, VarConstMap);
+        c1 = SimplifyFormula(a[1], true, VarConstMap);
+        output = CreateNode(AND, c0, c1);
+      }
+    else
+      {
+        c0 = SimplifyFormula(a[0], false, VarConstMap);
+        c1 = SimplifyFormula(a[1], false, VarConstMap);
+        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, ASTNodeMap* VarConstMap)
+  {
+    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, VarConstMap);
+
+    if (pushNeg)
+      c0 = SimplifyFormula(c0, true, VarConstMap);
+    else
+      c0 = SimplifyFormula(c0, false, VarConstMap);
+
+    if (ASTTrue == c0)
+      {
+        output = c1;
+      }
+    else if (ASTFalse == c0)
+      {
+        output = SimplifyFormula(c1, true, VarConstMap);
+      }
+    else if (ASTTrue == c1)
+      {
+        output = c0;
+      }
+    else if (ASTFalse == c1)
+      {
+        output = SimplifyFormula(c0, true, VarConstMap);
+      }
+    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, ASTNodeMap* VarConstMap)
+  {
+    if (!optimize_flag)
+      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, VarConstMap);
+    ASTNode t1, t2;
+    if (pushNeg)
+      {
+        t1 = SimplifyFormula(a[1], true, VarConstMap);
+        t2 = SimplifyFormula(a[2], true, VarConstMap);
+      }
+    else
+      {
+        t1 = SimplifyFormula(a[1], false, VarConstMap);
+        t2 = SimplifyFormula(a[2], false, VarConstMap);
+      }
+
+    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, VarConstMap);
+      }
+    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 BeevMgr::SimplifyAtomicFormula(const ASTNode& a, bool pushNeg, ASTNodeMap* VarConstMap)
-{
-       if (!optimize_flag)
-               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;
-}
-
-//Look through the AND Node for terms that contradict.
-//Should be made significantly more general..
-ASTNode BeevMgr::RemoveContradictionsFromAND(const ASTNode& in)
-{
-       assert(AND == in.GetKind());
-       const int childrenSize = in.GetChildren().size();
-
-       for (int i = 0; i < childrenSize; i++)
-       {
-               if (BVLT != in[i].GetKind())
-                       continue;
-
-               for (int j = i + 1; j < childrenSize; j++)
-               {
-                       if (BVLT != in[j].GetKind())
-                               continue;
-                       if (in[i][0] == in[j][1] && in[i][1] == in[j][0]) // parameters are swapped.
-                               return ASTFalse;
-               }
-       }
-       return in;
-}
-
-// turns say (bvslt (ite a  b c) (ite a d e)) INTO (ite a (bvslt b d) (bvslt c e))
-// Expensive. But makes some other simplifications possible.
-ASTNode BeevMgr::PullUpITE(const ASTNode& in)
-{
-       if (2 != in.GetChildren().size())
-               return in;
-       if (ITE != in[0].GetKind())
-               return in;
-       if (ITE != in[1].GetKind())
-               return in;
-       if (in[0][0] != in[1][0]) // if the conditional is not equal.
-               return in;
-
-       // Consider equals. It takes bitvectors and returns a boolean.
-       // Consider add. It takes bitvectors and returns bitvectors.
-       // Consider concat. The bitwidth of each side could vary.
-
-       ASTNode l1;
-       ASTNode l2;
-       ASTNode result;
-
-       if (in.GetType() == BOOLEAN_TYPE)
-       {
-               l1 = CreateNode(in.GetKind(), in[0][1], in[1][1]);
-               l2 = CreateNode(in.GetKind(), in[0][2], in[1][2]);
-               result = CreateNode(ITE, in[0][0], l1, l2);
-       }
-       else
-       {
-               l1 = CreateTerm(in.GetKind(), in.GetValueWidth(), in[0][1], in[1][1]);
-               l2 = CreateTerm(in.GetKind(), in.GetValueWidth(), in[0][2], in[1][2]);
-               result = CreateTerm(ITE, in.GetValueWidth(), in[0][0], l1, l2);
-       }
-
-       assert(result.GetType() == in.GetType());
-       assert(result.GetValueWidth() == in.GetValueWidth());
-       assert(result.GetIndexWidth() == in.GetIndexWidth());
-       assert(BVTypeCheck(result));
-
-       return result;
-}
-
-//takes care of some simple ITE Optimizations in the context of equations
-ASTNode BeevMgr::ITEOpt_InEqs(const ASTNode& in, ASTNodeMap* VarConstMap)
-{
-       CountersAndStats("ITEOpts_InEqs");
-
-       if (!(EQ == in.GetKind() && optimize_flag))
-       {
-               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, VarConstMap);
-                       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, VarConstMap);
-                       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_flag)
-       //      {
-       //              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_flag)
-       {
-               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_flag)
-       {
-               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;
-               }
-       }
-       ASTNode result = CreateNode(ITE, t0, t1, t2);
-       BVTypeCheck(result);
-       return result;
-}
-
-ASTNode BeevMgr::SimplifyAndOrFormula(const ASTNode& a, bool pushNeg, ASTNodeMap* VarConstMap)
-{
-       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, VarConstMap);
-               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, VarConstMap);
-               }
-               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, VarConstMap);
-                       break;
-               }
-               default:
-               {
-                       output = (isAnd) ? (pushNeg ? CreateNode(OR, outvec) : CreateNode(AND, outvec)) : (pushNeg ? CreateNode(AND, outvec) : CreateNode(OR,
-                                       outvec));
-                       //output = FlattenOneLevel(output);
-                       break;
-               }
-       }
-
-       // I haven't verified this is useful.
-       //if (output.GetKind() == AND)
-       //      output = RemoveContradictionsFromAND(output);
-
-       //memoize
-       UpdateSimplifyMap(a, output, pushNeg);
-       //cerr << "output:\n" << output << endl;
-       return output;
-} //end of SimplifyAndOrFormula
-
-
-ASTNode BeevMgr::SimplifyNotFormula(const ASTNode& a, bool pushNeg, ASTNodeMap* VarConstMap)
-{
-       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, VarConstMap);
-       }
-       //memoize
-       UpdateSimplifyMap(o, output, pn);
-       UpdateSimplifyMap(a, output, pushNeg);
-       return output;
-}
-
-ASTNode BeevMgr::SimplifyXorFormula(const ASTNode& a, bool pushNeg, ASTNodeMap* VarConstMap)
-{
-       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, VarConstMap);
-       ASTNode a1 = SimplifyFormula(a[1], false, VarConstMap);
-       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, ASTNodeMap* VarConstMap)
-{
-       ASTNode output, a0, a1;
-       if (CheckSimplifyMap(a, output, pushNeg))
-               return output;
-
-       //the two NOTs cancel out
-       if (pushNeg)
-       {
-               a0 = SimplifyFormula(a[0], false, VarConstMap);
-               a1 = SimplifyFormula(a[1], false, VarConstMap);
-               output = CreateNode(AND, a0, a1);
-       }
-       else
-       {
-               //push the NOT implicit in the NAND
-               a0 = SimplifyFormula(a[0], true, VarConstMap);
-               a1 = SimplifyFormula(a[1], true, VarConstMap);
-               output = CreateNode(OR, a0, a1);
-       }
-
-       //memoize
-       UpdateSimplifyMap(a, output, pushNeg);
-       return output;
-}
-
-ASTNode BeevMgr::SimplifyNorFormula(const ASTNode& a, bool pushNeg, ASTNodeMap* VarConstMap)
-{
-       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, VarConstMap);
-               output = CreateNode(OR, a0, a1);
-       }
-       else
-       {
-               //push the NOT implicit in the NAND
-               a0 = SimplifyFormula(a[0], true, VarConstMap);
-               a1 = SimplifyFormula(a[1], true, VarConstMap);
-               output = CreateNode(AND, a0, a1);
-       }
-
-       //memoize
-       UpdateSimplifyMap(a, output, pushNeg);
-       return output;
-}
-
-ASTNode BeevMgr::SimplifyImpliesFormula(const ASTNode& a, bool pushNeg, ASTNodeMap* VarConstMap)
-{
-       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, VarConstMap);
-               c1 = SimplifyFormula(a[1], true, VarConstMap);
-               output = CreateNode(AND, c0, c1);
-       }
-       else
-       {
-               c0 = SimplifyFormula(a[0], false, VarConstMap);
-               c1 = SimplifyFormula(a[1], false, VarConstMap);
-               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, ASTNodeMap* VarConstMap)
-{
-       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, VarConstMap);
-
-       if (pushNeg)
-               c0 = SimplifyFormula(c0, true, VarConstMap);
-       else
-               c0 = SimplifyFormula(c0, false, VarConstMap);
-
-       if (ASTTrue == c0)
-       {
-               output = c1;
-       }
-       else if (ASTFalse == c0)
-       {
-               output = SimplifyFormula(c1, true, VarConstMap);
-       }
-       else if (ASTTrue == c1)
-       {
-               output = c0;
-       }
-       else if (ASTFalse == c1)
-       {
-               output = SimplifyFormula(c0, true, VarConstMap);
-       }
-       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, ASTNodeMap* VarConstMap)
-{
-       if (!optimize_flag)
-               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, VarConstMap);
-       ASTNode t1, t2;
-       if (pushNeg)
-       {
-               t1 = SimplifyFormula(a[1], true, VarConstMap);
-               t2 = SimplifyFormula(a[2], true, VarConstMap);
-       }
-       else
-       {
-               t1 = SimplifyFormula(a[1], false, VarConstMap);
-               t2 = SimplifyFormula(a[2], false, VarConstMap);
-       }
-
-       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, VarConstMap);
-       }
-       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& actualInputterm, ASTNodeMap* VarConstMap)
-{
-       ASTNode inputterm(actualInputterm); // mutable local copy.
-
-       //cout << "SimplifyTerm: input: " << a << endl;
-       if (!optimize_flag)
-       {
-               return inputterm;
-       }
-
-       ASTNode output;
-       assert(BVTypeCheck(inputterm));
-       
-       //########################################
-       //########################################
-
-       if (CheckSubstitutionMap(inputterm, output))
-       {
-               //cout << "SolverMap:" << inputterm << " output: " << output << endl;
-               return SimplifyTerm(output);
-       }
-
-       if (CheckSimplifyMap(inputterm, output, false))
-       {
-               //cerr << "SimplifierMap:" << inputterm << " output: " << 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();
-
-       inputterm = PullUpITE(inputterm);
-       k = inputterm.GetKind(); // pull up ITE can change the kind of the node
-
-       switch (k)
-       {
-               case BVCONST:
-                       output = inputterm;
-                       break;
-               case SYMBOL:
-                       if(CheckMap(VarConstMap, inputterm, output)) 
-                       {
-                         return output;
-                       }
-                       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, VarConstMap);
-                                       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, VarConstMap);
-                       ASTNode t1 = SimplifyTerm(inputterm[1]);
-                       ASTNode t2 = SimplifyTerm(inputterm[2]);
-                       output = CreateSimplifiedTermITE(t0, t1, t2);
-                       break;
-               }
-               case SBVREM:
-               case SBVDIV:
-               case SBVMOD:
-               {
-                       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()
-
-
-//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;
-       }
-
-       ASTNodeCountMap::const_iterator it;
-       it = ReferenceCount->find(lhs);
-       if (it != ReferenceCount->end())
-       {
-               if (it->second > 1)
-                       return eq;
-       }
-
-       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, ASTNodeMap* VarConstMap)
-{
-       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, VarConstMap);
-
-               //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 (WRITE == 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();
-
-       // May be a symbol, or an ITE.
-
-       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, ASTNodeMap* VarConstMap)
-{
-       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, VarConstMap);
-               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();
-
-       //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);
-
-       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 (!wordlevel_solve_flag)
-               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]);
-
-               ASTNode c1 = SimplifyTerm(c[1]);
-               if (SYMBOL == c[0].GetKind() && VarSeenInTerm(c[0], c1))
-               {
-                       return a;
-               }
-
-               if (1 == TermOrder(c[0], c[1]) && READ == c[0].GetKind() && VarSeenInTerm(c[0][1], c1))
-               {
-                       return a;
-               }
-               bool updated = UpdateSubstitutionMap(c[0], c1);
-               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()
-{
-       SimplifyMap->clear();
-       delete SimplifyMap;
-       SimplifyMap = new ASTNodeMap(INITIAL_SIMPLIFY_MAP_SIZE);
-
-       SimplifyNegMap->clear();
-       delete SimplifyNegMap;
-       SimplifyNegMap = new ASTNodeMap(INITIAL_SIMPLIFY_MAP_SIZE);
-
-       ReferenceCount->clear();
-       delete ReferenceCount;
-       ReferenceCount = new ASTNodeCountMap(INITIAL_SIMPLIFY_MAP_SIZE);
-}
+      }
+
+    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& actualInputterm, ASTNodeMap* VarConstMap)
+  {
+    ASTNode inputterm(actualInputterm); // mutable local copy.
+
+    //cout << "SimplifyTerm: input: " << a << endl;
+    if (!optimize_flag)
+      {
+        return inputterm;
+      }
+
+    ASTNode output;
+    assert(BVTypeCheck(inputterm));
+        
+    //########################################
+    //########################################
+
+    if (CheckSubstitutionMap(inputterm, output))
+      {
+        //cout << "SolverMap:" << inputterm << " output: " << output << endl;
+        return SimplifyTerm(output);
+      }
+
+    if (CheckSimplifyMap(inputterm, output, false))
+      {
+        //cerr << "SimplifierMap:" << inputterm << " output: " << 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();
+
+    inputterm = PullUpITE(inputterm);
+    k = inputterm.GetKind(); // pull up ITE can change the kind of the node
+
+    switch (k)
+      {
+      case BVCONST:
+        output = inputterm;
+        break;
+      case SYMBOL:
+        if(CheckMap(VarConstMap, inputterm, output)) 
+          {
+            return output;
+          }
+        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, VarConstMap);
+                  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, VarConstMap);
+          ASTNode t1 = SimplifyTerm(inputterm[1]);
+          ASTNode t2 = SimplifyTerm(inputterm[2]);
+          output = CreateSimplifiedTermITE(t0, t1, t2);
+          break;
+        }
+      case SBVREM:
+      case SBVDIV:
+      case SBVMOD:
+        {
+          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()
+
+
+  //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;
+      }
+
+    ASTNodeCountMap::const_iterator it;
+    it = ReferenceCount->find(lhs);
+    if (it != ReferenceCount->end())
+      {
+        if (it->second > 1)
+          return eq;
+      }
+
+    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, ASTNodeMap* VarConstMap)
+  {
+    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, VarConstMap);
+
+        //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 (WRITE == 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();
+
+    // May be a symbol, or an ITE.
+
+    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, ASTNodeMap* VarConstMap)
+  {
+    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, VarConstMap);
+        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();
+
+    //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);
+
+    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 (!wordlevel_solve_flag)
+      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]);
+
+        ASTNode c1 = SimplifyTerm(c[1]);
+        if (SYMBOL == c[0].GetKind() && VarSeenInTerm(c[0], c1))
+          {
+            return a;
+          }
+
+        if (1 == TermOrder(c[0], c[1]) && READ == c[0].GetKind() && VarSeenInTerm(c[0][1], c1))
+          {
+            return a;
+          }
+        bool updated = UpdateSubstitutionMap(c[0], c1);
+        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()
+  {
+    SimplifyMap->clear();
+    delete SimplifyMap;
+    SimplifyMap = new ASTNodeMap(INITIAL_SIMPLIFY_MAP_SIZE);
+
+    SimplifyNegMap->clear();
+    delete SimplifyNegMap;
+    SimplifyNegMap = new ASTNodeMap(INITIAL_SIMPLIFY_MAP_SIZE);
+
+    ReferenceCount->clear();
+    delete ReferenceCount;
+    ReferenceCount = new ASTNodeCountMap(INITIAL_SIMPLIFY_MAP_SIZE);
+  }
 
 }
 ;//end of namespace