aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorCristian Cadar <cristic@cs.stanford.edu>2012-07-31 17:27:46 +0000
committerCristian Cadar <cristic@cs.stanford.edu>2012-07-31 17:27:46 +0000
commit28aacfaeddbfe047ab0fba29b6843facc5e5e06a (patch)
tree59387f63c46e7c4ef6d5609dad1e31bef8424bbd
parentc582aa704b9f0d2729e76251aeb4676d4cb866a6 (diff)
downloadklee-28aacfaeddbfe047ab0fba29b6843facc5e5e06a.tar.gz
Forgot to remove the actual stp directory.
git-svn-id: https://llvm.org/svn/llvm-project/klee/trunk@161056 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--stp/AST/AST.cpp1579
-rw-r--r--stp/AST/AST.h1806
-rw-r--r--stp/AST/ASTKind.cpp118
-rw-r--r--stp/AST/ASTKind.h79
-rw-r--r--stp/AST/ASTKind.kinds71
-rw-r--r--stp/AST/ASTUtil.cpp45
-rw-r--r--stp/AST/ASTUtil.h107
-rw-r--r--stp/AST/BitBlast.cpp812
-rw-r--r--stp/AST/Makefile19
-rw-r--r--stp/AST/STLport_config.h20
-rw-r--r--stp/AST/SimpBool.cpp408
-rw-r--r--stp/AST/ToCNF.cpp506
-rw-r--r--stp/AST/ToSAT.cpp1386
-rw-r--r--stp/AST/Transform.cpp492
-rwxr-xr-xstp/AST/genkinds.pl123
-rw-r--r--stp/INSTALL10
-rw-r--r--stp/LICENSE17
-rw-r--r--stp/Makefile14
-rw-r--r--stp/README26
-rw-r--r--stp/bitvec/Makefile19
-rw-r--r--stp/bitvec/consteval.cpp1044
-rw-r--r--stp/c_interface/Makefile19
-rw-r--r--stp/c_interface/c_interface.cpp1548
-rw-r--r--stp/c_interface/c_interface.h401
-rw-r--r--stp/c_interface/fdstream.h186
-rw-r--r--stp/constantbv/Makefile16
-rw-r--r--stp/constantbv/constantbv.cpp3571
-rw-r--r--stp/constantbv/constantbv.h316
-rw-r--r--stp/sat/Global.h255
-rw-r--r--stp/sat/Heap.h151
-rw-r--r--stp/sat/LICENSE20
-rw-r--r--stp/sat/Makefile19
-rw-r--r--stp/sat/Simplifier.cpp542
-rw-r--r--stp/sat/Solver.cpp813
-rw-r--r--stp/sat/Solver.h356
-rw-r--r--stp/sat/SolverTypes.h132
-rw-r--r--stp/sat/Sort.h133
-rw-r--r--stp/sat/VarOrder.h146
-rw-r--r--stp/simplifier/Makefile19
-rw-r--r--stp/simplifier/bvsolver.cpp714
-rw-r--r--stp/simplifier/bvsolver.h134
-rw-r--r--stp/simplifier/simplifier.cpp2495
42 files changed, 0 insertions, 20687 deletions
diff --git a/stp/AST/AST.cpp b/stp/AST/AST.cpp
deleted file mode 100644
index 63319de9..00000000
--- a/stp/AST/AST.cpp
+++ /dev/null
@@ -1,1579 +0,0 @@
-/********************************************************************
- * AUTHORS: Vijay Ganesh, David L. Dill
- *
- * BEGIN DATE: November, 2005
- *
- * LICENSE: Please view LICENSE file in the home dir of this Program
- ********************************************************************/
-// -*- c++ -*-
-
-#include "AST.h"
-namespace BEEV {
- //some global variables that are set through commandline options. it
- //is best that these variables remain global. Default values set
- //here
- //
- //collect statistics on certain functions
- bool stats = false;
- //print DAG nodes
- bool print_nodes = false;
- //tentative global var to allow for variable activity optimization
- //in the SAT solver. deprecated.
- bool variable_activity_optimize = false;
- //run STP in optimized mode
- bool optimize = true;
- //do sat refinement, i.e. underconstraint the problem, and feed to
- //SAT. if this works, great. else, add a set of suitable constraints
- //to re-constraint the problem correctly, and call SAT again, until
- //all constraints have been added.
- bool arrayread_refinement = true;
- //flag to control write refinement
- bool arraywrite_refinement = true;
- //check the counterexample against the original input to STP
- bool check_counterexample = false;
- //construct the counterexample in terms of original variable based
- //on the counterexample returned by SAT solver
- bool construct_counterexample = true;
- bool print_counterexample = false;
- //if this option is true then print the way dawson wants using a
- //different printer. do not use this printer.
- bool print_arrayval_declaredorder = false;
- //flag to decide whether to print "valid/invalid" or not
- bool print_output = false;
- //do linear search in the array values of an input array. experimental
- bool linear_search = false;
- //print the variable order chosen by the sat solver while it is
- //solving.
- bool print_sat_varorder = false;
- //turn on word level bitvector solver
- bool wordlevel_solve = true;
- //turn off XOR flattening
- bool xor_flatten = false;
-
- //the smtlib parser has been turned on
- bool smtlib_parser_enable = false;
- //print the input back
- bool print_STPinput_back = false;
-
- //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::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 *ASTNode::GetName() const {
- if (GetKind() != SYMBOL)
- FatalError("GetName: Called GetName on a non-symbol: ", *this);
- return ((ASTSymbol *) _int_node_ptr)->GetName();
- }
-
- // Print in lisp format
- ostream &ASTNode::LispPrint(ostream &os, int indentation) const {
- // Clear the PrintMap
- BeevMgr& bm = GetBeevMgr();
- bm.AlreadyPrintedSet.clear();
- return LispPrint_indent(os, indentation);
- }
-
- // Print newline and indentation, then print the thing.
- ostream &ASTNode::LispPrint_indent(ostream &os,
- int indentation) const
- {
- os << endl << spaces(indentation);
- LispPrint1(os, indentation);
- return os;
- }
-
- /** Internal function to print in lisp format. Assume newline
- and indentation printed already before first line. Recursive
- calls will have newline & indent, though */
- ostream &ASTNode::LispPrint1(ostream &os, int indentation) const {
- if (!IsDefined()) {
- os << "<undefined>";
- return os;
- }
- Kind kind = GetKind();
- // FIXME: figure out how to avoid symbols with same names as kinds.
-// if (kind == READ) {
-// const ASTVec &children = GetChildren();
-// children[0].LispPrint1(os, indentation);
-// os << "[" << children[1] << "]";
-// } else
- if(kind == BVGETBIT) {
- const ASTVec &children = GetChildren();
- // child 0 is a symbol. Print without the NodeNum.
- os << GetNodeNum() << ":";
-
-
-
- children[0]._int_node_ptr->nodeprint(os);
- //os << "{" << children[1].GetBVConst() << "}";
- os << "{";
- children[1]._int_node_ptr->nodeprint(os);
- os << "}";
- } else if (kind == NOT) {
- const ASTVec &children = GetChildren();
- os << GetNodeNum() << ":";
- os << "(NOT ";
- children[0].LispPrint1(os, indentation);
- os << ")";
- }
- else if (Degree() == 0) {
- // Symbol or a kind with no children print as index:NAME if shared,
- // even if they have been printed before.
- os << GetNodeNum() << ":";
- _int_node_ptr->nodeprint(os);
- // os << "(" << _int_node_ptr->_ref_count << ")";
- // os << "{" << GetValueWidth() << "}";
- }
- else if (IsAlreadyPrinted()) {
- // print non-symbols as "[index]" if seen before.
- os << "[" << GetNodeNum() << "]";
- // << "(" << _int_node_ptr->_ref_count << ")";
- }
- else {
- MarkAlreadyPrinted();
- const ASTVec &children = GetChildren();
- os << GetNodeNum() << ":"
- //<< "(" << _int_node_ptr->_ref_count << ")"
- << "(" << kind << " ";
- // os << "{" << GetValueWidth() << "}";
- ASTVec::const_iterator iend = children.end();
- for (ASTVec::const_iterator i = children.begin(); i != iend; i++) {
- i->LispPrint_indent(os, indentation+2);
- }
- os << ")";
- }
- return os;
- }
-
- //print in PRESENTATION LANGUAGE
- //
- //two pass algorithm:
- //
- //1. In the first pass, letize this Node, N: i.e. if a node
- //1. appears more than once in N, then record this fact.
- //
- //2. In the second pass print a "global let" and then print N
- //2. as follows: Every occurence of a node occuring more than
- //2. once is replaced with the corresponding let variable.
- ostream& ASTNode::PL_Print(ostream &os,
- int indentation) const {
- // Clear the PrintMap
- BeevMgr& bm = GetBeevMgr();
- bm.PLPrintNodeSet.clear();
- bm.NodeLetVarMap.clear();
- bm.NodeLetVarVec.clear();
- bm.NodeLetVarMap1.clear();
-
- //pass 1: letize the node
- LetizeNode();
-
- //pass 2:
- //
- //2. print all the let variables and their counterpart expressions
- //2. as follows (LET var1 = expr1, var2 = expr2, ...
- //
- //3. Then print the Node itself, replacing every occurence of
- //3. expr1 with var1, expr2 with var2, ...
- //os << "(";
- if(0 < bm.NodeLetVarMap.size()) {
- //ASTNodeMap::iterator it=bm.NodeLetVarMap.begin();
- //ASTNodeMap::iterator itend=bm.NodeLetVarMap.end();
- std::vector<pair<ASTNode,ASTNode> >::iterator it = bm.NodeLetVarVec.begin();
- std::vector<pair<ASTNode,ASTNode> >::iterator itend = bm.NodeLetVarVec.end();
-
- os << "(LET ";
- //print the let var first
- it->first.PL_Print1(os,indentation,false);
- os << " = ";
- //print the expr
- it->second.PL_Print1(os,indentation,false);
-
- //update the second map for proper printing of LET
- bm.NodeLetVarMap1[it->second] = it->first;
-
- for(it++;it!=itend;it++) {
- os << "," << endl;
- //print the let var first
- it->first.PL_Print1(os,indentation,false);
- os << " = ";
- //print the expr
- it->second.PL_Print1(os,indentation,false);
-
- //update the second map for proper printing of LET
- bm.NodeLetVarMap1[it->second] = it->first;
- }
-
- os << " IN " << endl;
- PL_Print1(os,indentation, true);
- os << ") ";
- }
- else
- PL_Print1(os,indentation, false);
- //os << " )";
- os << " ";
- return os;
- } //end of PL_Print()
-
- //traverse "*this", and construct "let variables" for terms that
- //occur more than once in "*this".
- void ASTNode::LetizeNode(void) const {
- Kind kind = this->GetKind();
-
- if(kind == SYMBOL ||
- kind == BVCONST ||
- kind == FALSE ||
- kind == TRUE)
- return;
-
- //FIXME: this is ugly.
- BeevMgr& bm = GetBeevMgr();
- const ASTVec &c = this->GetChildren();
- for(ASTVec::const_iterator it=c.begin(),itend=c.end();it!=itend;it++){
- ASTNode ccc = *it;
- if(bm.PLPrintNodeSet.find(ccc) == bm.PLPrintNodeSet.end()){
- //If branch: if *it is not in NodeSet then,
- //
- //1. add it to NodeSet
- //
- //2. Letize its childNodes
-
- //FIXME: Fetching BeevMgr is annoying. Can we put this in
- //some kind of a printer class
- bm.PLPrintNodeSet.insert(ccc);
- //debugging
- //cerr << ccc;
- ccc.LetizeNode();
- }
- else{
- Kind k = ccc.GetKind();
- if(k == SYMBOL ||
- k == BVCONST ||
- k == FALSE ||
- k == TRUE)
- continue;
-
- //0. Else branch: Node has been seen before
- //
- //1. Check if the node has a corresponding letvar in the
- //1. NodeLetVarMap.
- //
- //2. if no, then create a new var and add it to the
- //2. NodeLetVarMap
- if(bm.NodeLetVarMap.find(ccc) == bm.NodeLetVarMap.end()) {
- //Create a new symbol. Get some name. if it conflicts with a
- //declared name, too bad.
- int sz = bm.NodeLetVarMap.size();
- ostringstream oss;
- oss << "let_k_" << sz;
-
- ASTNode CurrentSymbol = bm.CreateSymbol(oss.str().c_str());
- CurrentSymbol.SetValueWidth(this->GetValueWidth());
- CurrentSymbol.SetIndexWidth(this->GetIndexWidth());
- /* If for some reason the variable being created here is
- * already declared by the user then the printed output will
- * not be a legal input to the system. too bad. I refuse to
- * check for this. [Vijay is the author of this comment.]
- */
-
- bm.NodeLetVarMap[ccc] = CurrentSymbol;
- std::pair<ASTNode,ASTNode> node_letvar_pair(CurrentSymbol,ccc);
- bm.NodeLetVarVec.push_back(node_letvar_pair);
- }
- }
- }
- } //end of LetizeNode()
-
- void ASTNode::PL_Print1(ostream& os,
- int indentation,
- bool letize) const {
- //os << spaces(indentation);
- //os << endl << spaces(indentation);
- if (!IsDefined()) {
- os << "<undefined>";
- return;
- }
-
- //if this node is present in the letvar Map, then print the letvar
- BeevMgr &bm = GetBeevMgr();
-
- //this is to print letvars for shared subterms inside the printing
- //of "(LET v0 = term1, v1=term1@term2,...
- if((bm.NodeLetVarMap1.find(*this) != bm.NodeLetVarMap1.end()) && !letize) {
- (bm.NodeLetVarMap1[*this]).PL_Print1(os,indentation,letize);
- return;
- }
-
- //this is to print letvars for shared subterms inside the actual
- //term to be printed
- if((bm.NodeLetVarMap.find(*this) != bm.NodeLetVarMap.end()) && letize) {
- (bm.NodeLetVarMap[*this]).PL_Print1(os,indentation,letize);
- return;
- }
-
- //otherwise print it normally
- Kind kind = GetKind();
- const ASTVec &c = GetChildren();
- switch(kind) {
- case BVGETBIT:
- c[0].PL_Print1(os,indentation,letize);
- os << "{";
- c[1].PL_Print1(os,indentation,letize);
- os << "}";
- break;
- case BITVECTOR:
- os << "BITVECTOR(";
- unsigned char * str;
- str = CONSTANTBV::BitVector_to_Hex(c[0].GetBVConst());
- os << str << ")";
- CONSTANTBV::BitVector_Dispose(str);
- break;
- case BOOLEAN:
- os << "BOOLEAN";
- break;
- case FALSE:
- case TRUE:
- os << kind;
- break;
- case BVCONST:
- case SYMBOL:
- _int_node_ptr->nodeprint(os);
- break;
- case READ:
- c[0].PL_Print1(os, indentation,letize);
- os << "[";
- c[1].PL_Print1(os,indentation,letize);
- os << "]";
- break;
- case WRITE:
- os << "(";
- c[0].PL_Print1(os,indentation,letize);
- os << " WITH [";
- c[1].PL_Print1(os,indentation,letize);
- os << "] := ";
- c[2].PL_Print1(os,indentation,letize);
- os << ")";
- os << endl;
- break;
- case BVUMINUS:
- os << kind << "( ";
- c[0].PL_Print1(os,indentation,letize);
- os << ")";
- break;
- case NOT:
- os << "NOT(";
- c[0].PL_Print1(os,indentation,letize);
- os << ") " << endl;
- break;
- case BVNEG:
- os << " ~(";
- c[0].PL_Print1(os,indentation,letize);
- os << ")";
- break;
- case BVCONCAT:
- os << "(";
- c[0].PL_Print1(os,indentation,letize);
- os << " @ ";
- c[1].PL_Print1(os,indentation,letize);
- os << ")" << endl;
- break;
- case BVOR:
- os << "(";
- c[0].PL_Print1(os,indentation,letize);
- os << " | ";
- c[1].PL_Print1(os,indentation,letize);
- os << ")";
- break;
- case BVAND:
- os << "(";
- c[0].PL_Print1(os,indentation,letize);
- os << " & ";
- c[1].PL_Print1(os,indentation,letize);
- os << ")";
- break;
- case BVEXTRACT:
- c[0].PL_Print1(os,indentation,letize);
- os << "[";
- os << GetUnsignedConst(c[1]);
- os << ":";
- os << GetUnsignedConst(c[2]);
- os << "]";
- break;
- case BVLEFTSHIFT:
- os << "(";
- c[0].PL_Print1(os,indentation,letize);
- os << " << ";
- os << GetUnsignedConst(c[1]);
- os << ")";
- break;
- case BVRIGHTSHIFT:
- os << "(";
- c[0].PL_Print1(os,indentation,letize);
- os << " >> ";
- os << GetUnsignedConst(c[1]);
- os << ")";
- break;
- case BVMULT:
- case BVSUB:
- case BVPLUS:
- case SBVDIV:
- case SBVMOD:
- case BVDIV:
- case BVMOD:
- os << kind << "(";
- os << this->GetValueWidth();
- for(ASTVec::const_iterator it=c.begin(),itend=c.end();it!=itend;it++) {
- os << ", " << endl;
- it->PL_Print1(os,indentation,letize);
- }
- os << ")" << endl;
- break;
- case ITE:
- os << "IF(";
- c[0].PL_Print1(os,indentation,letize);
- os << ")" << endl;
- os << "THEN ";
- c[1].PL_Print1(os,indentation,letize);
- os << endl << "ELSE ";
- c[2].PL_Print1(os,indentation,letize);
- os << endl << "ENDIF";
- break;
- case BVLT:
- case BVLE:
- case BVGT:
- case BVGE:
- case BVXOR:
- case BVNAND:
- case BVNOR:
- case BVXNOR:
- os << kind << "(";
- c[0].PL_Print1(os,indentation,letize);
- os << ",";
- c[1].PL_Print1(os,indentation,letize);
- os << ")" << endl;
- break;
- case BVSLT:
- os << "SBVLT" << "(";
- c[0].PL_Print1(os,indentation,letize);
- os << ",";
- c[1].PL_Print1(os,indentation,letize);
- os << ")" << endl;
- break;
- case BVSLE:
- os << "SBVLE" << "(";
- c[0].PL_Print1(os,indentation,letize);
- os << ",";
- c[1].PL_Print1(os,indentation,letize);
- os << ")" << endl;
- break;
- case BVSGT:
- os << "SBVGT" << "(";
- c[0].PL_Print1(os,indentation,letize);
- os << ",";
- c[1].PL_Print1(os,indentation,letize);
- os << ")" << endl;
- break;
- case BVSGE:
- os << "SBVGE" << "(";
- c[0].PL_Print1(os,indentation,letize);
- os << ",";
- c[1].PL_Print1(os,indentation,letize);
- os << ")" << endl;
- break;
- case EQ:
- c[0].PL_Print1(os,indentation,letize);
- os << " = ";
- c[1].PL_Print1(os,indentation,letize);
- os << endl;
- break;
- case NEQ:
- c[0].PL_Print1(os,indentation,letize);
- os << " /= ";
- c[1].PL_Print1(os,indentation,letize);
- os << endl;
- break;
- case AND:
- case OR:
- case NAND:
- case NOR:
- case XOR: {
- os << "(";
- c[0].PL_Print1(os,indentation,letize);
- ASTVec::const_iterator it=c.begin();
- ASTVec::const_iterator itend=c.end();
-
- it++;
- for(;it!=itend;it++) {
- os << " " << kind << " ";
- it->PL_Print1(os,indentation,letize);
- os << endl;
- }
- os << ")";
- break;
- }
- case IFF:
- os << "(";
- os << "(";
- c[0].PL_Print1(os,indentation,letize);
- os << ")";
- os << " <=> ";
- os << "(";
- c[1].PL_Print1(os,indentation,letize);
- os << ")";
- os << ")";
- os << endl;
- break;
- case IMPLIES:
- os << "(";
- os << "(";
- c[0].PL_Print1(os,indentation,letize);
- os << ")";
- os << " => ";
- os << "(";
- c[1].PL_Print1(os,indentation,letize);
- os << ")";
- os << ")";
- os << endl;
- break;
- case BVSX:
- os << kind << "(";
- c[0].PL_Print1(os,indentation,letize);
- os << ",";
- os << this->GetValueWidth();
- os << ")" << endl;
- break;
- default:
- //remember to use LispPrinter here. Otherwise this function will
- //go into an infinite loop. Recall that "<<" is overloaded to
- //the lisp printer. FatalError uses lispprinter
- FatalError("PL_Print1: printing not implemented for this kind: ",*this);
- break;
- }
- } //end of PL_Print1()
-
- ////////////////////////////////////////////////////////////////
- // BeevMgr members
- ////////////////////////////////////////////////////////////////
- ASTNode BeevMgr::CreateNode(Kind kind, const ASTVec & back_children) {
- // create a new node. Children will be modified.
- ASTInterior *n_ptr = new ASTInterior(kind, *this);
-
- // insert all of children at end of new_children.
- ASTNode n(CreateInteriorNode(kind, n_ptr, back_children));
- return n;
- }
-
- ASTNode BeevMgr::CreateNode(Kind kind,
- const ASTNode& child0,
- const ASTVec & back_children) {
-
- ASTInterior *n_ptr = new ASTInterior(kind, *this);
- ASTVec &front_children = n_ptr->_children;
- front_children.push_back(child0);
- ASTNode n(CreateInteriorNode(kind, n_ptr, back_children));
- return n;
- }
-
- ASTNode BeevMgr::CreateNode(Kind kind,
- const ASTNode& child0,
- const ASTNode& child1,
- const ASTVec & back_children) {
-
- ASTInterior *n_ptr = new ASTInterior(kind, *this);
- ASTVec &front_children = n_ptr->_children;
- front_children.push_back(child0);
- front_children.push_back(child1);
- ASTNode n(CreateInteriorNode(kind, n_ptr, back_children));
- return n;
- }
-
-
- ASTNode BeevMgr::CreateNode(Kind kind,
- const ASTNode& child0,
- const ASTNode& child1,
- const ASTNode& child2,
- const ASTVec & back_children) {
- ASTInterior *n_ptr = new ASTInterior(kind, *this);
- ASTVec &front_children = n_ptr->_children;
- front_children.push_back(child0);
- front_children.push_back(child1);
- front_children.push_back(child2);
- ASTNode n(CreateInteriorNode(kind, n_ptr, back_children));
- return n;
- }
-
-
- ASTInterior *BeevMgr::CreateInteriorNode(Kind kind,
- // children array of this node will be modified.
- ASTInterior *n_ptr,
- const ASTVec & back_children) {
-
- // insert back_children at end of front_children
- ASTVec &front_children = n_ptr->_children;
-
- front_children.insert(front_children.end(), back_children.begin(), back_children.end());
-
- // check for undefined nodes.
- ASTVec::const_iterator it_end = front_children.end();
- for (ASTVec::const_iterator it = front_children.begin(); it != it_end; it++) {
- if (it->IsNull())
- FatalError("CreateInteriorNode: Undefined childnode in CreateInteriorNode: ", ASTUndefined);
- }
-
- return LookupOrCreateInterior(n_ptr);
- }
-
- /** Trivial but virtual destructor */
- ASTSymbol::~ASTSymbol() {}
-
- ostream &operator<<(ostream &os, const ASTNodeMap &nmap)
- {
- ASTNodeMap::const_iterator iend = nmap.end();
- for (ASTNodeMap::const_iterator i = nmap.begin(); i!=iend; i++) {
- os << "Key: " << i->first << endl;
- os << "Value: " << i->second << endl;
- }
- return os;
- }
-
- ////////////////////////////////////////////////////////////////
- // BeevMgr member functions to create ASTSymbol and ASTBVConst
- ////////////////////////////////////////////////////////////////
- ASTNode BeevMgr::CreateSymbol(const char * const name)
- {
- ASTSymbol temp_sym(name, *this);
- ASTNode n(LookupOrCreateSymbol(temp_sym));
- return n;
- }
-
-#ifndef NATIVE_C_ARITH
- //Create a ASTBVConst node
- ASTNode BeevMgr::CreateBVConst(unsigned int width,
- unsigned long long int bvconst){
- if(width == 0 || width > (sizeof(unsigned long long int)<<3))
- FatalError("CreateBVConst: trying to create a bvconst of width: ", ASTUndefined, width);
-
- CBV bv = CONSTANTBV::BitVector_Create(width, true);
-
- // Copy bvconst in using at most MaxChunkSize chunks, starting with the
- // least significant bits.
- const uint32_t MaxChunkSize = 32;
- for (unsigned offset = 0; offset != width;) {
- uint32_t numbits = std::min(MaxChunkSize, width - offset);
- uint32_t mask = ~0 >> (32 - numbits);
- CONSTANTBV::BitVector_Chunk_Store(bv, numbits, offset,
- (bvconst >> offset) & mask);
- offset += numbits;
- }
-
- return CreateBVConst(bv, 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 ASTNode::GetBVConst() const {
- if(GetKind() != BVCONST)
- FatalError("GetBVConst: non bitvector-constant: ",*this);
- return ((ASTBVConst *) _int_node_ptr)->GetBVConst();
- }
-#else
- //Create a ASTBVConst node
- ASTNode BeevMgr::CreateBVConst(const unsigned int width,
- const unsigned long long int bvconst) {
- if(width > 64 || width <= 0)
- FatalError("Fatal Error: CreateBVConst: trying to create a bvconst of width:", ASTUndefined, width);
-
- //64 bit mask
- unsigned long long int mask = 0xffffffffffffffffLL;
- mask = mask >> (64 - width);
-
- unsigned long long int bv = bvconst;
- bv = bv & mask;
-
- ASTBVConst temp_bvconst(bv, *this);
- temp_bvconst._value_width = width;
- ASTNode n(LookupOrCreateBVConst(temp_bvconst));
- n.SetValueWidth(width);
- n.SetIndexWidth(0);
- return n;
- }
- //Create a ASTBVConst node from std::string
- ASTNode BeevMgr::CreateBVConst(const char* strval, int base) {
- if(!(base == 2 || base == 16 || base == 10))
- FatalError("CreateBVConst: This base is not supported: ", ASTUndefined, base);
-
- if(10 != base) {
- unsigned int width = (base == 2) ? strlen(strval) : strlen(strval)*4;
- unsigned long long int val = strtoull(strval, NULL, base);
- ASTNode bvcon = CreateBVConst(width, val);
- return bvcon;
- }
- else {
- //this is an ugly hack to accomodate SMTLIB format
- //restrictions. SMTLIB format represents bitvector constants in
- //base 10 (what a terrible idea, but i have no choice but to
- //support it), and make an implicit assumption that the length
- //is 32 (another terrible idea).
- unsigned width = 32;
- unsigned long long int val = strtoull(strval, NULL, base);
- ASTNode bvcon = CreateBVConst(width, val);
- return bvcon;
- }
- }
-
- //To ensure unique BVConst nodes, lookup the node in unique-table
- //before creating a new one.
- ASTBVConst *BeevMgr::LookupOrCreateBVConst(ASTBVConst &s) {
- ASTBVConst *s_ptr = &s; // it's a temporary key.
-
- // Do an explicit lookup to see if we need to create a copy of the
- // string.
- ASTBVConstSet::const_iterator it;
- if ((it = _bvconst_unique_table.find(s_ptr)) == _bvconst_unique_table.end()) {
- // Make a new ASTBVConst. Can cast the iterator to non-const --
- // carefully.
- unsigned int width = s_ptr->_value_width;
- ASTBVConst * s_ptr1 = new ASTBVConst(s_ptr->GetBVConst(), *this);
- s_ptr1->SetNodeNum(NewNodeNum());
- s_ptr1->_value_width = width;
- pair<ASTBVConstSet::const_iterator, bool> p = _bvconst_unique_table.insert(s_ptr1);
- return *p.first;
- }
- else
- // return BVConst found in table.
- return *it;
- }
-
- // Inline because we need to wait until unique_table is defined
- void ASTBVConst::CleanUp() {
- // cout << "Deleting node " << this->GetNodeNum() << endl;
- _bm._bvconst_unique_table.erase(this);
- delete this;
- }
-
- // Get the value of bvconst from a bvconst. It's an error if kind
- // != BVCONST
- unsigned long long int ASTNode::GetBVConst() const {
- if(GetKind() != BVCONST)
- FatalError("GetBVConst: non bitvector-constant: ", *this);
- return ((ASTBVConstTmp *) _int_node_ptr)->GetBVConst();
- }
-
- ASTNode BeevMgr::CreateZeroConst(unsigned width) {
- return CreateBVConst(width,0);
- }
-
- ASTNode BeevMgr::CreateOneConst(unsigned width) {
- return CreateBVConst(width,1);
- }
-
- ASTNode BeevMgr::CreateTwoConst(unsigned width) {
- return CreateBVConst(width,2);
- }
-
- ASTNode BeevMgr::CreateMaxConst(unsigned width) {
- std::string s;
- s.insert(s.end(),width,'1');
- return CreateBVConst(s.c_str(),2);
- }
-
-#endif
-
- // FIXME: _name is now a constant field, and this assigns to it
- // because it tries not to copy the string unless it needs to. How
- // do I avoid copying children in ASTInterior? Perhaps I don't!
-
- // Note: There seems to be a limitation of hash_set, in that insert
- // returns a const iterator to the value. That prevents us from
- // modifying the name (in a hash-preserving way) after the symbol is
- // inserted. FIXME: Is there a way to do this with insert? Need a
- // function to make a new object in the middle of insert. Read STL
- // documentation.
-
- ASTSymbol *BeevMgr::LookupOrCreateSymbol(ASTSymbol& s) {
- ASTSymbol *s_ptr = &s; // it's a temporary key.
-
- // Do an explicit lookup to see if we need to create a copy of the string.
- ASTSymbolSet::const_iterator it;
- if ((it = _symbol_unique_table.find(s_ptr)) == _symbol_unique_table.end()) {
- // Make a new ASTSymbol with duplicated string (can't assign
- // _name because it's const). Can cast the iterator to
- // non-const -- carefully.
- //std::string strname(s_ptr->GetName());
- ASTSymbol * s_ptr1 = new ASTSymbol(strdup(s_ptr->GetName()), *this);
- s_ptr1->SetNodeNum(NewNodeNum());
- s_ptr1->_value_width = s_ptr->_value_width;
- pair<ASTSymbolSet::const_iterator, bool> p = _symbol_unique_table.insert(s_ptr1);
- return *p.first;
- }
- else
- // return symbol found in table.
- return *it;
- }
-
- bool BeevMgr::LookupSymbol(ASTSymbol& s) {
- ASTSymbol* s_ptr = &s; // it's a temporary key.
-
- if(_symbol_unique_table.find(s_ptr) == _symbol_unique_table.end())
- return false;
- else
- return true;
- }
-
- // Inline because we need to wait until unique_table is defined
- void ASTSymbol::CleanUp() {
- // cout << "Deleting node " << this->GetNodeNum() << endl;
- _bm._symbol_unique_table.erase(this);
- //FIXME This is a HUGE free to invoke.
- //TEST IT!
- free((char*) this->_name);
- delete this;
- }
-
- ////////////////////////////////////////////////////////////////
- //
- // IO manipulators for Lisp format printing of AST.
- //
- ////////////////////////////////////////////////////////////////
-
- // FIXME: Additional controls
- // * Print node numbers (addresses/nums)
- // * Printlength limit
- // * Printdepth limit
-
- /** Print a vector of ASTNodes in lisp format */
- ostream &LispPrintVec(ostream &os, const ASTVec &v, int indentation)
- {
- // Print the children
- ASTVec::const_iterator iend = v.end();
- for (ASTVec::const_iterator i = v.begin(); i != iend; i++) {
- i->LispPrint_indent(os, indentation);
- }
- return os;
- }
-
- // FIXME: Made non-ref in the hope that it would work better.
- void lp(ASTNode node)
- {
- cout << lisp(node) << endl;
- }
-
- void lpvec(const ASTVec &vec)
- {
- vec[0].GetBeevMgr().AlreadyPrintedSet.clear();
- LispPrintVec(cout, vec, 0);
- cout << endl;
- }
-
- // Copy constructor. Maintain _ref_count
- ASTNode::ASTNode(const ASTNode &n) : _int_node_ptr(n._int_node_ptr) {
-#ifndef SMTLIB
- if (n._int_node_ptr) {
- n._int_node_ptr->IncRef();
- }
-#endif
- }
-
-
- /* FUNCTION: Typechecker for terms and formulas
- *
- * TypeChecker: Assumes that the immediate Children of the input
- * ASTNode have been typechecked. This function is suitable in
- * scenarios like where you are building the ASTNode Tree, and you
- * typecheck as you go along. It is not suitable as a general
- * typechecker
- */
- void BeevMgr::BVTypeCheck(const ASTNode& n) {
- Kind k = n.GetKind();
- //The children of bitvector terms are in turn bitvectors.
- ASTVec v = n.GetChildren();
- if(is_Term_kind(k)) {
- switch(k) {
- case BVCONST:
- if(BITVECTOR_TYPE != n.GetType())
- FatalError("BVTypeCheck: The term t does not typecheck, where t = \n",n);
- break;
- case SYMBOL:
- return;
- case ITE:
- if(BOOLEAN_TYPE != n[0].GetType() &&
- BITVECTOR_TYPE != n[1].GetType() &&
- BITVECTOR_TYPE != n[2].GetType())
- FatalError("BVTypeCheck: The term t does not typecheck, where t = \n",n);
- if(n[1].GetValueWidth() != n[2].GetValueWidth())
- FatalError("BVTypeCheck: length of THENbranch != length of ELSEbranch in the term t = \n",n);
- if(n[1].GetIndexWidth() != n[2].GetIndexWidth())
- FatalError("BVTypeCheck: length of THENbranch != length of ELSEbranch in the term t = \n",n);
- break;
- case READ:
- if(n[0].GetIndexWidth() != n[1].GetValueWidth()) {
- cerr << "Length of indexwidth of array: " << n[0] << " is : " << n[0].GetIndexWidth() << endl;
- cerr << "Length of the actual index is: " << n[1] << " is : " << n[1].GetValueWidth() << endl;
- FatalError("BVTypeCheck: length of indexwidth of array != length of actual index in the term t = \n",n);
- }
- break;
- case WRITE:
- if(n[0].GetIndexWidth() != n[1].GetValueWidth())
- FatalError("BVTypeCheck: length of indexwidth of array != length of actual index in the term t = \n",n);
- if(n[0].GetValueWidth() != n[2].GetValueWidth())
- FatalError("BVTypeCheck: valuewidth of array != length of actual value in the term t = \n",n);
- break;
- case BVOR:
- case BVAND:
- case BVXOR:
- case BVNOR:
- case BVNAND:
- case BVXNOR:
- case BVPLUS:
- case BVMULT:
- case BVDIV:
- case BVMOD:
- case BVSUB: {
- if(!(v.size() >= 2))
- FatalError("BVTypeCheck:bitwise Booleans and BV arith operators must have atleast two arguments\n",n);
- unsigned int width = n.GetValueWidth();
- for(ASTVec::iterator it=v.begin(),itend=v.end();it!=itend;it++){
- if(width != it->GetValueWidth()) {
- cerr << "BVTypeCheck:Operands of bitwise-Booleans and BV arith operators must be of equal length\n";
- cerr << n << endl;
- cerr << "width of term:" << width << endl;
- cerr << "width of offending operand:" << it->GetValueWidth() << endl;
- FatalError("BVTypeCheck:Offending operand:\n",*it);
- }
- if(BITVECTOR_TYPE != it->GetType())
- FatalError("BVTypeCheck: ChildNodes of bitvector-terms must be bitvectors\n",n);
- }
- break;
- }
- case BVSX:
- //in BVSX(n[0],len), the length of the BVSX term must be
- //greater than the length of n[0]
- if(n[0].GetValueWidth() >= n.GetValueWidth()) {
- FatalError("BVTypeCheck: BVSX(t,bvsx_len) : length of 't' must be <= bvsx_len\n",n);
- }
- break;
- default:
- for(ASTVec::iterator it=v.begin(),itend=v.end();it!=itend;it++)
- if(BITVECTOR_TYPE != it->GetType()) {
- cerr << "The type is: " << it->GetType() << endl;
- FatalError("BVTypeCheck:ChildNodes of bitvector-terms must be bitvectors\n",n);
- }
- break;
- }
-
- switch(k) {
- case BVCONCAT:
- if(n.Degree() != 2)
- FatalError("BVTypeCheck: should have exactly 2 args\n",n);
- if(n.GetValueWidth() != n[0].GetValueWidth() + n[1].GetValueWidth())
- FatalError("BVTypeCheck:BVCONCAT: lengths do not add up\n",n);
- break;
- case BVUMINUS:
- case BVNEG:
- if(n.Degree() != 1)
- FatalError("BVTypeCheck: should have exactly 1 args\n",n);
- break;
- case BVEXTRACT:
- if(n.Degree() != 3)
- FatalError("BVTypeCheck: should have exactly 3 args\n",n);
- if(!(BVCONST == n[1].GetKind() && BVCONST == n[2].GetKind()))
- FatalError("BVTypeCheck: indices should be BVCONST\n",n);
- if(n.GetValueWidth() != GetUnsignedConst(n[1])- GetUnsignedConst(n[2])+1)
- FatalError("BVTypeCheck: length mismatch\n",n);
- break;
- case BVLEFTSHIFT:
- case BVRIGHTSHIFT:
- if(n.Degree() != 2)
- FatalError("BVTypeCheck: should have exactly 2 args\n",n);
- break;
- //case BVVARSHIFT:
- //case BVSRSHIFT:
- break;
- default:
- break;
- }
- }
- else {
- if(!(is_Form_kind(k) && BOOLEAN_TYPE == n.GetType()))
- FatalError("BVTypeCheck: not a formula:",n);
- switch(k){
- case TRUE:
- case FALSE:
- case SYMBOL:
- return;
- case EQ:
- case NEQ:
- if(!(n[0].GetValueWidth() == n[1].GetValueWidth() &&
- n[0].GetIndexWidth() == n[1].GetIndexWidth())) {
- cerr << "valuewidth of lhs of EQ: " << n[0].GetValueWidth() << endl;
- cerr << "valuewidth of rhs of EQ: " << n[1].GetValueWidth() << endl;
- cerr << "indexwidth of lhs of EQ: " << n[0].GetIndexWidth() << endl;
- cerr << "indexwidth of rhs of EQ: " << n[1].GetIndexWidth() << endl;
- FatalError("BVTypeCheck: terms in atomic formulas must be of equal length",n);
- }
- break;
- case BVLT:
- case BVLE:
- case BVGT:
- case BVGE:
- case BVSLT:
- case BVSLE:
- case BVSGT:
- case BVSGE:
- if(BITVECTOR_TYPE != n[0].GetType() && BITVECTOR_TYPE != n[1].GetType())
- FatalError("BVTypeCheck: terms in atomic formulas must be bitvectors",n);
- if(n[0].GetValueWidth() != n[1].GetValueWidth())
- FatalError("BVTypeCheck: terms in atomic formulas must be of equal length",n);
- if(n[0].GetIndexWidth() != n[1].GetIndexWidth())
- FatalError("BVTypeCheck: terms in atomic formulas must be of equal length",n);
- break;
- case NOT:
- if(1 != n.Degree())
- FatalError("BVTypeCheck: NOT formula can have exactly one childNode",n);
- break;
- case AND:
- case OR:
- case XOR:
- case NAND:
- case NOR:
- if(2 > n.Degree())
- FatalError("BVTypeCheck: AND/OR/XOR/NAND/NOR: must have atleast 2 ChildNodes",n);
- break;
- case IFF:
- case IMPLIES:
- if(2 != n.Degree())
- FatalError("BVTypeCheck:IFF/IMPLIES must have exactly 2 ChildNodes",n);
- break;
- case ITE:
- if(3 != n.Degree())
- FatalError("BVTypeCheck:ITE must have exactly 3 ChildNodes",n);
- break;
- default:
- FatalError("BVTypeCheck: Unrecognized kind: ",ASTUndefined);
- break;
- }
- }
- } //End of TypeCheck function
-
- //add an assertion to the current logical context
- void BeevMgr::AddAssert(const ASTNode& assert) {
- if(!(is_Form_kind(assert.GetKind()) && BOOLEAN_TYPE == assert.GetType())) {
- FatalError("AddAssert:Trying to assert a non-formula:",assert);
- }
-
- ASTVec * v;
- //if the stack of ASTVec is not empty, then take the top ASTVec
- //and add the input assert to it
- if(!_asserts.empty()) {
- v = _asserts.back();
- //v->push_back(TransformFormula(assert));
- v->push_back(assert);
- }
- else {
- //else create a logical context, and add it to the top of the
- //stack
- v = new ASTVec();
- //v->push_back(TransformFormula(assert));
- v->push_back(assert);
- _asserts.push_back(v);
- }
- }
-
- void BeevMgr::Push(void) {
- ASTVec * v;
- v = new ASTVec();
- _asserts.push_back(v);
- }
-
- void BeevMgr::Pop(void) {
- if(!_asserts.empty()) {
- ASTVec * c = _asserts.back();
- //by calling the clear function we ensure that the ref count is
- //decremented for the ASTNodes stored in c
- c->clear();
- delete c;
- _asserts.pop_back();
- }
- }
-
- void BeevMgr::AddQuery(const ASTNode& q) {
- //_current_query = TransformFormula(q);
- //cerr << "\nThe current query is: " << q << endl;
- _current_query = q;
- }
-
- const ASTNode BeevMgr::PopQuery() {
- ASTNode q = _current_query;
- _current_query = ASTTrue;
- return q;
- }
-
- const ASTNode BeevMgr::GetQuery() {
- return _current_query;
- }
-
- const ASTVec BeevMgr::GetAsserts(void) {
- vector<ASTVec *>::iterator it = _asserts.begin();
- vector<ASTVec *>::iterator itend = _asserts.end();
-
- ASTVec v;
- for(;it!=itend;it++) {
- if(!(*it)->empty())
- v.insert(v.end(),(*it)->begin(),(*it)->end());
- }
- return v;
- }
-
- //Create a new variable of ValueWidth 'n'
- ASTNode BeevMgr::NewArrayVar(unsigned int index, unsigned int value) {
- std:: string c("v");
- char d[32];
- sprintf(d,"%d",_symbol_count++);
- std::string ccc(d);
- c += "_writearray_" + ccc;
-
- ASTNode CurrentSymbol = CreateSymbol(c.c_str());
- CurrentSymbol.SetValueWidth(value);
- CurrentSymbol.SetIndexWidth(index);
- return CurrentSymbol;
- } //end of NewArrayVar()
-
-
- //Create a new variable of ValueWidth 'n'
- ASTNode BeevMgr::NewVar(unsigned int value) {
- std:: string c("v");
- char d[32];
- sprintf(d,"%d",_symbol_count++);
- std::string ccc(d);
- c += "_new_stp_var_" + ccc;
-
- ASTNode CurrentSymbol = CreateSymbol(c.c_str());
- CurrentSymbol.SetValueWidth(value);
- CurrentSymbol.SetIndexWidth(0);
- _introduced_symbols.insert(CurrentSymbol);
- return CurrentSymbol;
- } //end of NewVar()
-
- //prints statistics for the ASTNode
- void BeevMgr::ASTNodeStats(const char * c, const ASTNode& a){
- if(!stats)
- return;
-
- StatInfoSet.clear();
- //print node size:
- cout << endl << "Printing: " << c;
- if(print_nodes) {
- //a.PL_Print(cout,0);
- //cout << endl;
- cout << a << endl;
- }
- cout << "Node size is: ";
- cout << NodeSize(a) << endl << endl;
- }
-
- unsigned int BeevMgr::NodeSize(const ASTNode& a, bool clearStatInfo) {
- if(clearStatInfo)
- StatInfoSet.clear();
-
- ASTNodeSet::iterator it;
- if((it = StatInfoSet.find(a)) != StatInfoSet.end())
- //has already been counted
- return 0;
-
- //record that you have seen this node already
- StatInfoSet.insert(a);
-
- //leaf node has a size of 1
- if(a.Degree() == 0)
- return 1;
-
- unsigned newn = 1;
- ASTVec c = a.GetChildren();
- for(ASTVec::iterator it=c.begin(),itend=c.end();it!=itend;it++)
- newn += NodeSize(*it);
- return newn;
- }
-
- void BeevMgr::ClearAllTables(void) {
- //clear all tables before calling toplevelsat
- _ASTNode_to_SATVar.clear();
- _SATVar_to_AST.clear();
-
- for(ASTtoBitvectorMap::iterator it=_ASTNode_to_Bitvector.begin(),
- itend=_ASTNode_to_Bitvector.end();it!=itend;it++) {
- delete it->second;
- }
- _ASTNode_to_Bitvector.clear();
-
- /* OLD Destructor
- * for(ASTNodeToVecMap::iterator ivec = BBTermMemo.begin(),
- ivec_end=BBTermMemo.end();ivec!=ivec_end;ivec++) {
- ivec->second.clear();
- }*/
-
- /*What should I do here? For ASTNodes?
- * for(ASTNodeMap::iterator ivec = BBTermMemo.begin(),
- ivec_end=BBTermMemo.end();ivec!=ivec_end;ivec++) {
- ivec->second.clear();
- }*/
- BBTermMemo.clear();
- BBFormMemo.clear();
- NodeLetVarMap.clear();
- NodeLetVarMap1.clear();
- PLPrintNodeSet.clear();
- AlreadyPrintedSet.clear();
- SimplifyMap.clear();
- SimplifyNegMap.clear();
- SolverMap.clear();
- AlwaysTrueFormMap.clear();
- _arrayread_ite.clear();
- _arrayread_symbol.clear();
- _introduced_symbols.clear();
- TransformMap.clear();
- _letid_expr_map.clear();
- CounterExampleMap.clear();
- ComputeFormulaMap.clear();
- StatInfoSet.clear();
-
- // for(std::vector<ASTVec *>::iterator it=_asserts.begin(),
- // itend=_asserts.end();it!=itend;it++) {
- // (*it)->clear();
- // }
- _asserts.clear();
- for(ASTNodeToVecMap::iterator iset = _arrayname_readindices.begin(),
- iset_end = _arrayname_readindices.end();
- iset!=iset_end;iset++) {
- iset->second.clear();
- }
-
- _arrayname_readindices.clear();
- _interior_unique_table.clear();
- _symbol_unique_table.clear();
- _bvconst_unique_table.clear();
- }
-
- void BeevMgr::ClearAllCaches(void) {
- //clear all tables before calling toplevelsat
- _ASTNode_to_SATVar.clear();
- _SATVar_to_AST.clear();
-
-
- for(ASTtoBitvectorMap::iterator it=_ASTNode_to_Bitvector.begin(),
- itend=_ASTNode_to_Bitvector.end();it!=itend;it++) {
- delete it->second;
- }
- _ASTNode_to_Bitvector.clear();
-
- /*OLD destructor
- * for(ASTNodeToVecMap::iterator ivec = BBTermMemo.begin(),
- ivec_end=BBTermMemo.end();ivec!=ivec_end;ivec++) {
- ivec->second.clear();
- }*/
-
- /*What should I do here?
- *for(ASTNodeMap::iterator ivec = BBTermMemo.begin(),
- ivec_end=BBTermMemo.end();ivec!=ivec_end;ivec++) {
- ivec->second.clear();
- }*/
- BBTermMemo.clear();
- BBFormMemo.clear();
- NodeLetVarMap.clear();
- NodeLetVarMap1.clear();
- PLPrintNodeSet.clear();
- AlreadyPrintedSet.clear();
- SimplifyMap.clear();
- SimplifyNegMap.clear();
- SolverMap.clear();
- AlwaysTrueFormMap.clear();
- _arrayread_ite.clear();
- _arrayread_symbol.clear();
- _introduced_symbols.clear();
- TransformMap.clear();
- _letid_expr_map.clear();
- CounterExampleMap.clear();
- ComputeFormulaMap.clear();
- StatInfoSet.clear();
-
- for(ASTNodeToVecMap::iterator iset = _arrayname_readindices.begin(),
- iset_end = _arrayname_readindices.end();
- iset!=iset_end;iset++) {
- iset->second.clear();
- }
-
- _arrayname_readindices.clear();
- //_interior_unique_table.clear();
- //_symbol_unique_table.clear();
- //_bvconst_unique_table.clear();
- }
-
- void BeevMgr::CopySolverMap_To_CounterExample(void) {
- if(!SolverMap.empty()) {
- CounterExampleMap.insert(SolverMap.begin(),SolverMap.end());
- }
- }
-
- void FatalError(const char * str, const ASTNode& a, int w) {
- if(a.GetKind() != UNDEFINED) {
- cerr << "Fatal Error: " << str << endl << a << endl;
- cerr << w << endl;
- }
- else {
- cerr << "Fatal Error: " << str << endl;
- cerr << w << endl;
- }
- if (vc_error_hdlr)
- vc_error_hdlr(str);
- exit(-1);
- //assert(0);
- }
-
- void FatalError(const char * str) {
- cerr << "Fatal Error: " << str << endl;
- if (vc_error_hdlr)
- vc_error_hdlr(str);
- exit(-1);
- //assert(0);
- }
-
- //Variable Order Printer: A global function which converts a MINISAT
- //var into a ASTNODE var. It then prints this var along with
- //variable order dcisions taken by MINISAT.
- void Convert_MINISATVar_To_ASTNode_Print(int minisat_var,
- int decision_level, int polarity) {
- BEEV::ASTNode vv = globalBeevMgr_for_parser->_SATVar_to_AST[minisat_var];
- cout << spaces(decision_level);
- if(polarity) {
- cout << "!";
- }
- vv.PL_Print(cout,0);
- cout << endl;
- }
-
- void SortByExprNum(ASTVec& v) {
- sort(v.begin(), v.end(), exprless);
- }
-
- 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();
- }
-} // end namespace
-
diff --git a/stp/AST/AST.h b/stp/AST/AST.h
deleted file mode 100644
index 3052107f..00000000
--- a/stp/AST/AST.h
+++ /dev/null
@@ -1,1806 +0,0 @@
-// -*- c++ -*-
-/********************************************************************
- * AUTHORS: Vijay Ganesh, David L. Dill
- *
- * BEGIN DATE: November, 2005
- *
- * LICENSE: Please view LICENSE file in the home dir of this Program
- ********************************************************************/
-
-#ifndef AST_H
-#define AST_H
-#include <vector>
-#ifdef EXT_HASH_MAP
-#include <ext/hash_set>
-#include <ext/hash_map>
-#else
-#include <hash_set>
-#include <hash_map>
-#endif
-#include <iostream>
-#include <sstream>
-#include <string>
-#include <map>
-#include <set>
-#include "ASTUtil.h"
-#include "ASTKind.h"
-#include "../sat/Solver.h"
-#include "../sat/SolverTypes.h"
-#include <cstdlib>
-#include <stdint.h>
-#ifndef NATIVE_C_ARITH
-#include "../constantbv/constantbv.h"
-#endif
-/*****************************************************************************
- * LIST OF CLASSES DECLARED IN THIS FILE:
- *
- * class BeevMgr;
- * class ASTNode;
- * class ASTInternal;
- * class ASTInterior;
- * class ASTSymbol;
- * class ASTBVConst;
- *****************************************************************************/
-namespace BEEV {
- using namespace std;
- using namespace MINISAT;
-#ifdef EXT_HASH_MAP
- 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 vector<ASTNode>;
- //Print the arguments in lisp format.
- friend ostream &LispPrintVec(ostream &os,
- const ASTVec &v, int indentation = 0);
-
- private:
- // FIXME: make this into a reference?
- ASTInternal * _int_node_ptr; // The real data.
-
- // Usual constructor.
- ASTNode(ASTInternal *in);
-
- //Check if it points to a null node
- bool IsNull () const { return _int_node_ptr == NULL; }
-
- //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);
- }
-
- /* 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:
- // This is for sorting by expression number (used in Boolean
- //optimization)
- friend bool exprless(const ASTNode n1, const ASTNode n2) {
- Kind k1 = n1.GetKind();
- Kind k2 = n2.GetKind();
-
- if(BVCONST == k1 && BVCONST != k2){
- return true;
- }
- if(BVCONST != k1 && BVCONST == k2){
- return false;
- }
-
- if(SYMBOL == k1 && SYMBOL != k2) {
- return true;
- }
-
- if(SYMBOL != k1 && SYMBOL == k2) {
- return false;
- }
-
- return (n1.GetNodeNum() < n2.GetNodeNum());
- }//end of exprless
-
- // Internal lisp-form printer that does not clear _node_print_table
- ostream &LispPrint1(ostream &os, int indentation) const;
-
- ostream &LispPrint_indent(ostream &os, int indentation) const;
-
- // For lisp DAG printing. Has it been printed already, so we can
- // just print the node number?
- bool IsAlreadyPrinted() const;
- void MarkAlreadyPrinted() const;
-
- 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 *GetName() const;
-
- //Get the BVCONST value
-#ifndef NATIVE_C_ARITH
- CBV GetBVConst() const;
-#else
- unsigned long long int GetBVConst() const;
-#endif
-
- /*ASTNode is of type BV <==> ((indexwidth=0)&&(valuewidth>0))
- *
- *ASTNode is of type ARRAY <==> ((indexwidth>0)&&(valuewidth>0))
- *
- *ASTNode is of type BOOLEAN <==> ((indexwidth=0)&&(valuewidth=0))
- *
- *both indexwidth and valuewidth should never be less than 0
- */
- unsigned int GetIndexWidth () const;
-
- // FIXME: This function is dangerous. Try to eliminate it's use.
- void SetIndexWidth (unsigned int iw) const;
-
- unsigned int GetValueWidth () const;
-
- // FIXME: This function is dangerous. Try to eliminate it's use.
- void SetValueWidth (unsigned int vw) const;
-
- //return the type of the ASTNode
- //0 iff BOOLEAN
- //1 iff BITVECTOR
- //2 iff ARRAY
-
- /*ASTNode is of type BV <==> ((indexwidth=0)&&(valuewidth>0))
- *
- *ASTNode is of type ARRAY <==> ((indexwidth>0)&&(valuewidth>0))
- *
- *ASTNode is of type BOOLEAN <==> ((indexwidth=0)&&(valuewidth=0))
- *
- *both indexwidth and valuewidth should never be less than 0
- */
- types GetType(void) const;
-
- // Hash is pointer value of _int_node_ptr.
- size_t Hash() const{
- return (size_t) _int_node_ptr;
- //return GetNodeNum();
- }
-
- // lisp-form printer
- ostream& LispPrint(ostream &os, int indentation = 0) const;
-
- //Presentation Language Printer
- ostream& PL_Print(ostream &os, int indentation = 0) const;
-
- void PL_Print1(ostream &os, int indentation = 0, bool b = false) const;
-
- //Construct let variables for shared subterms
- void LetizeNode(void) const;
-
- // Attempt to define something that will work in the gdb
- friend void lp(ASTNode &node);
- friend void lpvec(const ASTVec &vec);
-
- friend ostream &operator<<(ostream &os, const ASTNode &node) {
- node.LispPrint(os, 0);
- return os;
- };
-
- // Check whether the ASTNode points to anything. Undefined nodes
- // are created by the default constructor. In binding table (for
- // lambda args, etc.), undefined nodes are used to represent
- // deleted entries.
- bool IsDefined() const { return _int_node_ptr != NULL; }
-
- /* Hasher class for STL hash_maps and hash_sets that use ASTNodes
- * as keys. Needs to be public so people can define hash tables
- * (and use ASTNodeMap class)*/
- class ASTNodeHasher {
- public:
- size_t operator() (const ASTNode& n) const{
- return (size_t) n._int_node_ptr;
- //return (size_t)n.GetNodeNum();
- };
- }; //End of ASTNodeHasher
-
- /* Equality for ASTNode hash_set and hash_map. Returns true iff
- * internal pointers are the same. Needs to be public so people
- * can define hash tables (and use ASTNodeSet class)*/
- class ASTNodeEqual {
- public:
- bool operator()(const ASTNode& n1, const ASTNode& n2) const{
- return (n1._int_node_ptr == n2._int_node_ptr);
- }
- }; //End of ASTNodeEqual
- }; //End of Class ASTNode
-
- void FatalError(const char * str, const ASTNode& a, int w = 0);
- void FatalError(const char * str);
- void SortByExprNum(ASTVec& c);
- bool exprless(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;
-
- protected:
-
- // reference count.
- int _ref_count;
-
- // Kind. It's a type tag and the operator.
- Kind _kind;
-
- // The vector of children (*** should this be in ASTInterior? ***)
- ASTVec _children;
-
- // Manager object. Having this backpointer means it's easy to
- // find the manager when we need it.
- BeevMgr &_bm;
-
- //Nodenum is a unique positive integer for the node. The nodenum
- //of a node should always be greater than its descendents (which
- //is easily achieved by incrementing the number each time a new
- //node is created).
- int _node_num;
-
- // Length of bitvector type for array index. The term is an
- // array iff this is positive. Otherwise, the term is a bitvector
- // or a bit.
- unsigned int _index_width;
-
- // Length of bitvector type for scalar value or array element.
- // If this is one, the term represents a single bit (same as a bitvector
- // of length 1). It must be 1 or greater.
- unsigned int _value_width;
-
- // Increment refcount.
-#ifndef SMTLIB
- void IncRef() { ++_ref_count; }
-#else
- void IncRef() { }
-#endif
-
- // DecRef is a potentially expensive, because it has to delete
- // the node from the unique table, in addition to freeing it.
- // FIXME: Consider putting in a backpointer (iterator) to the hash
- // table entry so it can be deleted without looking it up again.
- void DecRef();
-
- virtual 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.
- virtual void nodeprint(ostream& os) { os << "*"; };
- }; //End of Class ASTInternal
-
- // FIXME: Should children be only in interior node type?
- /***************************************************************************
- Class ASTInterior: Internal representation of an interior
- ASTNode. Generally, these nodes should have at least one
- child
- ***************************************************************************/
- class ASTInterior : public ASTInternal {
-
- friend class BeevMgr;
- friend class ASTNodeHasher;
- friend class ASTNodeEqual;
-
- private:
-
- // Hasher for ASTInterior pointer nodes
- class ASTInteriorHasher {
- public:
- size_t operator()(const ASTInterior *int_node_ptr) const;
- };
-
- // Equality for ASTInterior nodes
- class ASTInteriorEqual {
- public:
- bool operator()(const ASTInterior *int_node_ptr1,
- const ASTInterior *int_node_ptr2) const{
- return (*int_node_ptr1 == *int_node_ptr2);
- }
- };
-
- // Used in Equality class for hash tables
- friend bool operator==(const ASTInterior &int_node1,
- const ASTInterior &int_node2){
- return (int_node1._kind == int_node2._kind) &&
- (int_node1._children == int_node2._children);
- }
-
- // Call this when deleting a node that has been stored in the
- // the unique table
- virtual void CleanUp();
-
- // Returns kinds. "lispprinter" handles printing of parenthesis
- // and childnodes.
- virtual void nodeprint(ostream& os) {
- 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{
- hash<char*> h;
- 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 *GetName() const{return _name;}
-
- // Print function for symbol -- return name */
- virtual void nodeprint(ostream& os) { os << _name;}
-
- // Call this when deleting a node that has been stored in the
- // the unique table
- virtual void CleanUp();
-
- public:
-
- // Default constructor
- ASTSymbol(BeevMgr &bm) : ASTInternal(bm), _name(NULL) { }
-
- // Constructor. This does NOT copy its argument.
- ASTSymbol(const char * const name, BeevMgr &bm) : ASTInternal(SYMBOL, bm),
- _name(name) { }
-
- // Destructor (does nothing, but is declared virtual here.
- virtual ~ASTSymbol();
-
- // Copy constructor
- // FIXME: seems to be calling default constructor for astinternal
- ASTSymbol(const ASTSymbol &sym) :
- ASTInternal(sym._kind, sym._children, sym._bm),
- _name(sym._name) { }
- }; //End of ASTSymbol
-
-
- /***************************************************************************/
- /* Class ASTBVConst: Class to represent internals of a bitvectorconst */
- /***************************************************************************/
-
-#ifndef NATIVE_C_ARITH
-
- class ASTBVConst : public ASTInternal {
- friend class BeevMgr;
- friend class ASTNode;
- friend class ASTNodeHasher;
- friend class ASTNodeEqual;
-
- private:
- //This is the private copy of a bvconst currently
- //This should not be changed at any point
- CBV _bvconst;
-
- class ASTBVConstHasher{
- public:
- size_t operator() (const ASTBVConst * bvc) const {
- return CONSTANTBV::BitVector_Hash(bvc->_bvconst);
- };
- };
-
- class ASTBVConstEqual{
- public:
- bool operator()(const ASTBVConst * bvc1, const ASTBVConst * bvc2) const {
- if( bvc1->_value_width != bvc2->_value_width){
- return false;
- }
- return (0==CONSTANTBV::BitVector_Compare(bvc1->_bvconst,bvc2->_bvconst));
- }
- };
-
- //FIXME Keep an eye on this function
- ASTBVConst(CBV bv, unsigned int width, BeevMgr &bm) :
- ASTInternal(BVCONST, bm)
- {
- _bvconst = CONSTANTBV::BitVector_Clone(bv);
- _value_width = width;
- }
-
- friend bool operator==(const ASTBVConst &bvc1, const ASTBVConst &bvc2){
- if(bvc1._value_width != bvc2._value_width)
- return false;
- return (0==CONSTANTBV::BitVector_Compare(bvc1._bvconst,bvc2._bvconst));
- }
- // Call this when deleting a node that has been stored in the
- // the unique table
- virtual void CleanUp();
-
- // Print function for bvconst -- return _bvconst value in bin format
- virtual void nodeprint(ostream& os) {
- unsigned char *res;
- const char *prefix;
-
- if (_value_width%4 == 0) {
- res = CONSTANTBV::BitVector_to_Hex(_bvconst);
- prefix = "0hex";
- } else {
- res = CONSTANTBV::BitVector_to_Bin(_bvconst);
- prefix = "0bin";
- }
- if (NULL == res) {
- os << "nodeprint: BVCONST : could not convert to string" << _bvconst;
- FatalError("");
- }
- os << prefix << res;
- CONSTANTBV::BitVector_Dispose(res);
- }
-
- // Copy constructor.
- ASTBVConst(const ASTBVConst &sym) :
- ASTInternal(sym._kind, sym._children, sym._bm)
- {
- _bvconst = CONSTANTBV::BitVector_Clone(sym._bvconst);
- _value_width = sym._value_width;
- }
-
- public:
- virtual ~ASTBVConst(){
- CONSTANTBV::BitVector_Destroy(_bvconst);
- }
-
- CBV GetBVConst() const {return _bvconst;}
- }; //End of ASTBVConst
-
- //FIXME This function is DEPRICATED
- //Do not use in the future
- inline unsigned int GetUnsignedConst(const ASTNode n) {
- if(32 < n.GetValueWidth())
- FatalError("GetUnsignedConst: cannot convert bvconst of length greater than 32 to unsigned int:");
-
- return (unsigned int) *((unsigned int *)n.GetBVConst());
- }
-#else
- class ASTBVConst : public ASTInternal {
- friend class BeevMgr;
- friend class ASTNode;
- friend class ASTNodeHasher;
- friend class ASTNodeEqual;
-
- private:
- // the bitvector contents. bitvector contents will be in two
- // modes. one mode where all bitvectors are NATIVE and in this
- // mode we use native unsigned long long int to represent the
- // 32/64 bitvectors. The other for arbitrary length bitvector
- // operations.
- const unsigned long long int _bvconst;
-
- class ASTBVConstHasher{
- public:
- size_t operator() (const ASTBVConst * bvc) const{
- //Thomas Wang's 64 bit Mix Function
- unsigned long long int key(bvc->_bvconst);
- key += ~(key << 32);
- key ^= (key >> 22);
- key += ~(key << 13);
- key ^= (key >> 8);
- key += (key << 3);
- key ^= (key >> 15);
- key += ~(key << 27);
- key ^= (key >> 31);
-
- size_t return_key = key;
- return return_key;
- };
- };
-
- class ASTBVConstEqual{
- public:
- bool operator()(const ASTBVConst * bvc1, const ASTBVConst * bvc2) const {
- return ((bvc1->_bvconst == bvc2->_bvconst)
- && (bvc1->_value_width == bvc2->_value_width));
- }
- };
-
- // Call this when deleting a node that has been stored in the
- // the unique table
- virtual void CleanUp();
- public:
- // Default constructor
- ASTBVConst(const unsigned long long int bv, BeevMgr &bm) :
- ASTInternal(BVCONST, bm), _bvconst(bv) {
- }
-
- // Copy constructor. FIXME: figure out how this is supposed to
- // work.
- ASTBVConst(const ASTBVConst &sym) :
- ASTInternal(sym._kind, sym._children, sym._bm),
- _bvconst(sym._bvconst) {
- _value_width = sym._value_width;
- }
-
- // Destructor (does nothing, but is declared virtual here)
- virtual ~ASTBVConst() { }
-
- friend bool operator==(const ASTBVConst &sym1, const ASTBVConst &sym2){
- return ((sym1._bvconst == sym2._bvconst) &&
- (sym1._value_width == sym2._value_width));
- }
-
- // Print function for bvconst -- return _bvconst value in binary format
- virtual void nodeprint(ostream& os) {
- string s = "0bin";
- unsigned long long int bitmask = 0x8000000000000000LL;
- bitmask = bitmask >> (64-_value_width);
-
- for (; bitmask > 0; bitmask >>= 1)
- s += (_bvconst & bitmask) ? '1' : '0';
- os << s;
- }
-
- unsigned long long int GetBVConst() const {return _bvconst;}
- }; //End of ASTBVConst
-
- //return value of bvconst
- inline unsigned int GetUnsignedConst(const ASTNode n) {
- if(32 < n.GetValueWidth())
- FatalError("GetUnsignedConst: cannot convert bvconst of length greater than 32 to unsigned int:");
- return (unsigned int)n.GetBVConst();
- }
-#endif
-/*
-#else
- // the bitvector contents. bitvector contents will be in two
- // modes. one mode where all bitvectors are NATIVE and in this mode
- // we use native unsigned long long int to represent the 32/64
- // bitvectors. The other for arbitrary length bitvector operations.
-
- //BVCONST defined for arbitrary length bitvectors
- class ASTBVConst : public ASTInternal{
- friend class BeevMgr;
- friend class ASTNode;
- friend class ASTNodeHasher;
- friend class ASTNodeEqual;
-
- private:
- const char * const _bvconst;
-
- class ASTBVConstHasher{
- public:
- size_t operator() (const ASTBVConst * bvc) const{
- hash<char*> h;
- return h(bvc->_bvconst);
- };
- };
-
- class ASTBVConstEqual{
- public:
- bool operator()(const ASTBVConst * bvc1, const ASTBVConst * bvc2) const {
- if(bvc1->_value_width != bvc2->_value_width)
- return false;
- return (0 == strncmp(bvc1->_bvconst,bvc2->_bvconst,bvc1->_value_width));
- }
- };
-
- ASTBVConst(const char * bv, BeevMgr &bm) :
- ASTInternal(BVCONST, bm), _bvconst(bv) {
- //_value_width = strlen(bv);
- }
-
- friend bool operator==(const ASTBVConst &bvc1, const ASTBVConst &bvc2){
- if(bvc1._value_width != bvc2._value_width)
- return false;
- return (0 == strncmp(bvc1._bvconst,bvc2._bvconst,bvc1._value_width));
- }
-
- // Call this when deleting a node that has been stored in the
- // the unique table
- virtual void CleanUp();
-
- // Print function for bvconst -- return _bvconst value in binary format
- virtual void nodeprint(ostream& os) {
- if(_value_width%4 == 0) {
- unsigned int * iii = CONSTANTBV::BitVector_Create(_value_width,true);
- CONSTANTBV::ErrCode e = CONSTANTBV::BitVector_from_Bin(iii,(unsigned char*)_bvconst);
- //error printing
- if(0 != e) {
- os << "nodeprint: BVCONST : wrong hex value: " << BitVector_Error(e);
- FatalError("");
- }
- unsigned char * ccc = CONSTANTBV::BitVector_to_Hex(iii);
- os << "0hex" << ccc;
- CONSTANTBV::BitVector_Destroy(iii);
- }
- else {
- std::string s(_bvconst,_value_width);
- s = "0bin" + s;
- os << s;
- }
- }
-
- // Copy constructor.
- ASTBVConst(const ASTBVConst &sym) : ASTInternal(sym._kind, sym._children, sym._bm),_bvconst(sym._bvconst) {
- //checking if the input is in the correct format
- for(unsigned int jj=0;jj<sym._value_width;jj++)
- if(!(sym._bvconst[jj] == '0' || sym._bvconst[jj] == '1')) {
- cerr << "Fatal Error: wrong input to ASTBVConst copy constructor:" << sym._bvconst << endl;
- FatalError("");
- }
- _value_width = sym._value_width;
- }
- public:
- // Destructor (does nothing, but is declared virtual here)
- virtual ~ASTBVConst(){}
-
- const char * const GetBVConst() const {return _bvconst;}
- }; //End of ASTBVConst
-
- unsigned int * ConvertToCONSTANTBV(const char * s);
-
- //return value of bvconst
- inline unsigned int GetUnsignedConst(const ASTNode n) {
- if(32 < n.GetValueWidth())
- FatalError("GetUnsignedConst: cannot convert bvconst of length greater than 32 to unsigned int:");
- std::string s(n.GetBVConst(), n.GetValueWidth());
- unsigned int output = strtoul(s.c_str(),NULL,2);
- return output;
- } //end of ASTBVConst class
-#endif
-*/
- /***************************************************************************
- * Typedef ASTNodeMap: This is a hash table from ASTNodes to ASTNodes.
- * It is very convenient for attributes that are not speed-critical
- **************************************************************************/
- // These are generally useful for storing ASTNodes or attributes thereof
- // Hash table from ASTNodes to ASTNodes
- typedef hash_map<ASTNode, ASTNode,
- ASTNode::ASTNodeHasher,
- ASTNode::ASTNodeEqual> ASTNodeMap;
-
- // Function to dump contents of ASTNodeMap
- ostream &operator<<(ostream &os, const ASTNodeMap &nmap);
-
- /***************************************************************************
- Typedef ASTNodeSet: This is a hash set of ASTNodes. Very useful
- for representing things like "visited nodes"
- ***************************************************************************/
- typedef hash_set<ASTNode,
- ASTNode::ASTNodeHasher,
- ASTNode::ASTNodeEqual> ASTNodeSet;
-
- typedef hash_multiset<ASTNode,
- ASTNode::ASTNodeHasher,
- ASTNode::ASTNodeEqual> ASTNodeMultiSet;
-
- //external parser table for declared symbols.
- //FIXME: move to a more appropriate place
- extern ASTNodeSet _parser_symbol_table;
-
- /***************************************************************************
- Class LispPrinter: iomanipulator for printing ASTNode or ASTVec
- ***************************************************************************/
- class LispPrinter {
-
- public:
- ASTNode _node;
-
- // number of spaces to print before first real character of
- // object.
- int _indentation;
-
- // FIXME: pass ASTNode by reference
- // Constructor to build the LispPrinter object
- LispPrinter(ASTNode node, int indentation): _node(node), _indentation(indentation) { }
-
- friend ostream &operator<<(ostream &os, const LispPrinter &lp){
- return lp._node.LispPrint(os, lp._indentation);
- };
-
- }; //End of ListPrinter
-
- //This is the IO manipulator. It builds an object of class
- //"LispPrinter" that has a special overloaded "<<" operator.
- inline LispPrinter lisp(const ASTNode &node, int indentation = 0){
- LispPrinter lp(node, indentation);
- return lp;
- }
-
- /***************************************************************************/
- /* Class LispVecPrinter:iomanipulator for printing vector of ASTNodes */
- /***************************************************************************/
- class LispVecPrinter {
-
- public:
- const ASTVec * _vec;
- // number of spaces to print before first real
- // character of object.
- int _indentation;
-
- // Constructor to build the LispPrinter object
- LispVecPrinter(const ASTVec &vec, int indentation){
- _vec = &vec; _indentation = indentation;
- }
-
- friend ostream &operator<<(ostream &os, const LispVecPrinter &lvp){
- LispPrintVec(os, *lvp._vec, lvp._indentation);
- return os;
- };
- }; //End of Class ListVecPrinter
-
- //iomanipulator. builds an object of class "LisPrinter" that has a
- //special overloaded "<<" operator.
- inline LispVecPrinter lisp(const ASTVec &vec, int indentation = 0){
- LispVecPrinter lvp(vec, indentation);
- return lvp;
- }
-
-
- /*****************************************************************
- * INLINE METHODS from various classed, declared here because of
- * dependencies on classes that are declared later.
- *****************************************************************/
- // ASTNode accessor function.
- inline Kind ASTNode::GetKind() const {
- //cout << "GetKind: " << _int_node_ptr;
- return _int_node_ptr->GetKind();
- }
-
- // FIXME: should be const ASTVec const?
- // Declared here because of same ordering problem as GetKind.
- inline const ASTVec &ASTNode::GetChildren() const {
- return _int_node_ptr->GetChildren();
- }
-
- // Access node number
- inline int ASTNode::GetNodeNum() const {
- return _int_node_ptr->_node_num;
- }
-
- inline unsigned int ASTNode::GetIndexWidth () const {
- return _int_node_ptr->_index_width;
- }
-
- inline void ASTNode::SetIndexWidth (unsigned int iw) const {
- _int_node_ptr->_index_width = iw;
- }
-
- inline unsigned int ASTNode::GetValueWidth () const {
- return _int_node_ptr->_value_width;
- }
-
- inline void ASTNode::SetValueWidth (unsigned int vw) const {
- _int_node_ptr->_value_width = vw;
- }
-
- //return the type of the ASTNode: 0 iff BOOLEAN; 1 iff BITVECTOR; 2
- //iff ARRAY; 3 iff UNKNOWN;
- inline types ASTNode::GetType() const {
- if((GetIndexWidth() == 0) && (GetValueWidth() == 0)) //BOOLEAN
- return BOOLEAN_TYPE;
- if((GetIndexWidth() == 0) && (GetValueWidth() > 0)) //BITVECTOR
- return BITVECTOR_TYPE;
- if((GetIndexWidth() > 0) && (GetValueWidth() > 0)) //ARRAY
- return ARRAY_TYPE;
- return UNKNOWN_TYPE;
- }
-
- // Constructor; creates a new pointer, increments refcount of
- // pointed-to object.
-#ifndef SMTLIB
- inline ASTNode::ASTNode(ASTInternal *in) : _int_node_ptr(in) {
- if (in) in->IncRef();
- }
-#else
- inline ASTNode::ASTNode(ASTInternal *in) : _int_node_ptr(in) { };
-#endif
-
- // Assignment. Increment refcount of new value, decrement refcount
- // of old value and destroy if this was the last pointer. FIXME:
- // accelerate this by creating an intnode with a ref counter instead
- // of pointing to NULL. Need a special check in CleanUp to make
- // sure the null node never gets freed.
-
-#ifndef SMTLIB
- inline ASTNode& ASTNode::operator=(const ASTNode& n) {
- if (n._int_node_ptr) {
- n._int_node_ptr->IncRef();
- }
- if (_int_node_ptr) {
- _int_node_ptr->DecRef();
- }
- _int_node_ptr = n._int_node_ptr;
- return *this;
- }
-#else
- inline ASTNode& ASTNode::operator=(const ASTNode& n) {
- _int_node_ptr = n._int_node_ptr;
- return *this;
- }
-#endif
-
-#ifndef SMTLIB
- inline void ASTInternal::DecRef()
- {
- if (--_ref_count == 0) {
- // Delete node from unique table and kill it.
- CleanUp();
- }
- }
-
- // Destructor
- inline ASTNode::~ASTNode()
- {
- if (_int_node_ptr) {
- _int_node_ptr->DecRef();
- }
- }
-#else
- // No refcounting
- inline void ASTInternal::DecRef()
- {
- }
-
- // Destructor
- inline ASTNode::~ASTNode()
- {
- };
-#endif
-
- inline BeevMgr& ASTNode::GetBeevMgr() const { return _int_node_ptr->_bm; }
-
- /***************************************************************************
- * Class BeevMgr. This holds all "global" variables for the system, such as
- * unique tables for the various kinds of nodes.
- ***************************************************************************/
- class BeevMgr {
- friend class ASTNode; // ASTNode modifies AlreadyPrintedSet
- // in BeevMgr
- friend class ASTInterior;
- friend class ASTBVConst;
- friend class ASTSymbol;
-
- // FIXME: The values appear to be the same regardless of the value of SMTLIB
- // initial hash table sizes, to save time on resizing.
-#ifdef SMTLIB
- static const int INITIAL_INTERIOR_UNIQUE_TABLE_SIZE = 100;
- static const int INITIAL_SYMBOL_UNIQUE_TABLE_SIZE = 100;
- static const int INITIAL_BVCONST_UNIQUE_TABLE_SIZE = 100;
- static const int INITIAL_BBTERM_MEMO_TABLE_SIZE = 100;
- static const int INITIAL_BBFORM_MEMO_TABLE_SIZE = 100;
-
- static const int INITIAL_SIMPLIFY_MAP_SIZE = 100;
- static const int INITIAL_SOLVER_MAP_SIZE = 100;
- static const int INITIAL_ARRAYREAD_SYMBOL_SIZE = 100;
- static const int INITIAL_INTRODUCED_SYMBOLS_SIZE = 100;
-#else
- // these are the STL defaults
- static const int INITIAL_INTERIOR_UNIQUE_TABLE_SIZE = 100;
- static const int INITIAL_SYMBOL_UNIQUE_TABLE_SIZE = 100;
- static const int INITIAL_BVCONST_UNIQUE_TABLE_SIZE = 100;
- static const int INITIAL_BBTERM_MEMO_TABLE_SIZE = 100;
- static const int INITIAL_BBFORM_MEMO_TABLE_SIZE = 100;
-
- static const int INITIAL_SIMPLIFY_MAP_SIZE = 100;
- static const int INITIAL_SOLVER_MAP_SIZE = 100;
- static const int INITIAL_ARRAYREAD_SYMBOL_SIZE = 100;
- static const int INITIAL_INTRODUCED_SYMBOLS_SIZE = 100;
-#endif
-
- private:
- // Typedef for unique Interior node table.
- typedef hash_set<ASTInterior *,
- ASTInterior::ASTInteriorHasher,
- ASTInterior::ASTInteriorEqual> ASTInteriorSet;
-
- // Typedef for unique Symbol node (leaf) table.
- typedef hash_set<ASTSymbol *,
- ASTSymbol::ASTSymbolHasher,
- ASTSymbol::ASTSymbolEqual> ASTSymbolSet;
-
- // Unique tables to share nodes whenever possible.
- ASTInteriorSet _interior_unique_table;
- //The _symbol_unique_table is also the symbol table to be used
- //during parsing/semantic analysis
- ASTSymbolSet _symbol_unique_table;
-
- //Typedef for unique BVConst node (leaf) table.
- typedef hash_set<ASTBVConst *,
- ASTBVConst::ASTBVConstHasher,
- ASTBVConst::ASTBVConstEqual> ASTBVConstSet;
-
- //table to uniquefy bvconst
- ASTBVConstSet _bvconst_unique_table;
-
- // type of memo table.
- typedef hash_map<ASTNode, ASTVec,
- ASTNode::ASTNodeHasher,
- ASTNode::ASTNodeEqual> ASTNodeToVecMap;
-
- typedef hash_map<ASTNode,ASTNodeSet,
- ASTNode::ASTNodeHasher,
- ASTNode::ASTNodeEqual> ASTNodeToSetMap;
-
- // Memo table for bit blasted terms. If a node has already been
- // bitblasted, it is mapped to a vector of Boolean formulas for
- // the bits.
-
- //OLD: ASTNodeToVecMap BBTermMemo;
- ASTNodeMap BBTermMemo;
-
- // Memo table for bit blasted formulas. If a node has already
- // been bitblasted, it is mapped to a node representing the
- // bitblasted equivalent
- ASTNodeMap BBFormMemo;
-
- //public:
- // Get vector of Boolean formulas for sum of two
- // vectors of Boolean formulas
- void BBPlus2(ASTVec& sum, const ASTVec& y, ASTNode cin);
- // Increment
- ASTVec BBInc(ASTVec& x);
- // Add one bit to a vector of bits.
- ASTVec BBAddOneBit(ASTVec& x, ASTNode cin);
- // Bitwise complement
- ASTVec BBNeg(const ASTVec& x);
- // Unary minus
- ASTVec BBUminus(const ASTVec& x);
- // Multiply.
- ASTVec BBMult(const ASTVec& x, const ASTVec& y);
- // AND each bit of vector y with single bit b and return the result.
- // (used in BBMult)
- ASTVec BBAndBit(const ASTVec& y, ASTNode b);
- // Returns ASTVec for result - y. This destroys "result".
- void BBSub(ASTVec& result, const ASTVec& y);
- // build ITE's (ITE cond then[i] else[i]) for each i.
- ASTVec BBITE(const ASTNode& cond,
- const ASTVec& thn, const ASTVec& els);
- // Build a vector of zeros.
- ASTVec BBfill(unsigned int width, ASTNode fillval);
- // build an EQ formula
- ASTNode BBEQ(const ASTVec& left, const ASTVec& right);
-
- // This implements a variant of binary long division.
- // q and r are "out" parameters. rwidth puts a bound on the
- // recursion depth. Unsigned only, for now.
- void BBDivMod(const ASTVec &y,
- const ASTVec &x,
- ASTVec &q,
- ASTVec &r,
- unsigned int rwidth);
-
- // Return formula for majority function of three formulas.
- ASTNode Majority(const ASTNode& a, const ASTNode& b, const ASTNode& c);
-
- // Internal bit blasting routines.
- ASTNode BBBVLE(const ASTVec& x, const ASTVec& y, bool is_signed);
-
- // Return bit-blasted form for BVLE, BVGE, BVGT, SBLE, etc.
- ASTNode BBcompare(const ASTNode& form);
-
- // Left and right shift one. Writes into x.
- void BBLShift(ASTVec& x);
- void BBRShift(ASTVec& x);
-
- 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 ASTVec * 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(unsigned int width, unsigned long long int bvconst);
- ASTNode CreateZeroConst(unsigned int width);
- ASTNode CreateOneConst(unsigned int width);
- ASTNode CreateTwoConst(unsigned int width);
- ASTNode CreateMaxConst(unsigned int width);
-
- // Create and return an ASTNode for a symbol
- // Optional base was a problem because 0 could be an int or char *,
- // so CreateBVConst was ambiguous.
- ASTNode CreateBVConst(const char *strval, int base);
-
- //FIXME This is a dangerous function
- ASTNode CreateBVConst(CBV bv, unsigned width);
-
- // Create and return an interior ASTNode
- ASTNode CreateNode(Kind kind, const ASTVec &children = _empty_ASTVec);
-
- ASTNode CreateNode(Kind kind,
- const ASTNode& child0,
- const ASTVec &children = _empty_ASTVec);
-
- ASTNode CreateNode(Kind kind,
- const ASTNode& child0,
- const ASTNode& child1,
- const ASTVec &children = _empty_ASTVec);
-
- ASTNode CreateNode(Kind kind,
- const ASTNode& child0,
- const ASTNode& child1,
- const ASTNode& child2,
- const ASTVec &children = _empty_ASTVec);
-
- // Create and return an ASTNode for a term
- inline ASTNode CreateTerm(Kind kind,
- unsigned int width,
- const ASTVec &children = _empty_ASTVec) {
- if(!is_Term_kind(kind))
- FatalError("CreateTerm: Illegal kind to CreateTerm:",ASTUndefined, kind);
- ASTNode n = CreateNode(kind, children);
- n.SetValueWidth(width);
-
- //by default we assume that the term is a Bitvector. If
- //necessary the indexwidth can be changed later
- n.SetIndexWidth(0);
- return n;
- }
-
- inline ASTNode CreateTerm(Kind kind,
- unsigned int width,
- const ASTNode& child0,
- const ASTVec &children = _empty_ASTVec) {
- if(!is_Term_kind(kind))
- FatalError("CreateTerm: Illegal kind to CreateTerm:",ASTUndefined, kind);
- ASTNode n = CreateNode(kind, child0, children);
- n.SetValueWidth(width);
- return n;
- }
-
- inline ASTNode CreateTerm(Kind kind,
- unsigned int width,
- const ASTNode& child0,
- const ASTNode& child1,
- const ASTVec &children = _empty_ASTVec) {
- if(!is_Term_kind(kind))
- FatalError("CreateTerm: Illegal kind to CreateTerm:",ASTUndefined, kind);
- ASTNode n = CreateNode(kind, child0, child1, children);
- n.SetValueWidth(width);
- return n;
- }
-
- inline ASTNode CreateTerm(Kind kind,
- unsigned int width,
- const ASTNode& child0,
- const ASTNode& child1,
- const ASTNode& child2,
- const ASTVec &children = _empty_ASTVec) {
- if(!is_Term_kind(kind))
- FatalError("CreateTerm: Illegal kind to CreateTerm:",ASTUndefined, kind);
- ASTNode n = CreateNode(kind, child0, child1, child2, children);
- n.SetValueWidth(width);
- return n;
- }
-
- ASTNode SimplifyFormula_NoRemoveWrites(const ASTNode& a, bool pushNeg);
- ASTNode SimplifyFormula_TopLevel(const ASTNode& a, bool pushNeg);
- ASTNode SimplifyFormula(const ASTNode& a, bool pushNeg);
- ASTNode SimplifyTerm_TopLevel(const ASTNode& b);
- ASTNode SimplifyTerm(const ASTNode& a);
- void CheckSimplifyInvariant(const ASTNode& a, const ASTNode& output);
- private:
- //memo table for simplifcation
- ASTNodeMap SimplifyMap;
- ASTNodeMap SimplifyNegMap;
- ASTNodeMap SolverMap;
- ASTNodeSet AlwaysTrueFormMap;
- ASTNodeMap MultInverseMap;
-
- public:
- ASTNode SimplifyAtomicFormula(const ASTNode& a, bool pushNeg);
- ASTNode CreateSimplifiedEQ(const ASTNode& t1, const ASTNode& t2);
- ASTNode ITEOpt_InEqs(const ASTNode& in1);
- ASTNode CreateSimplifiedTermITE(const ASTNode& t1, const ASTNode& t2, const ASTNode& t3);
- ASTNode CreateSimplifiedINEQ(Kind k, const ASTNode& a0, const ASTNode& a1, bool pushNeg);
- ASTNode SimplifyNotFormula(const ASTNode& a, bool pushNeg);
- ASTNode SimplifyAndOrFormula(const ASTNode& a, bool pushNeg);
- ASTNode SimplifyXorFormula(const ASTNode& a, bool pushNeg);
- ASTNode SimplifyNandFormula(const ASTNode& a, bool pushNeg);
- ASTNode SimplifyNorFormula(const ASTNode& a, bool pushNeg);
- ASTNode SimplifyImpliesFormula(const ASTNode& a, bool pushNeg);
- ASTNode SimplifyIffFormula(const ASTNode& a, bool pushNeg);
- ASTNode SimplifyIteFormula(const ASTNode& a, bool pushNeg);
- ASTNode FlattenOneLevel(const ASTNode& a);
- ASTNode FlattenAndOr(const ASTNode& a);
- ASTNode CombineLikeTerms(const ASTNode& a);
- ASTNode LhsMinusRhs(const ASTNode& eq);
- ASTNode DistributeMultOverPlus(const ASTNode& a,
- bool startdistribution=false);
- ASTNode ConvertBVSXToITE(const ASTNode& a);
- //checks if the input constant is odd or not
- bool BVConstIsOdd(const ASTNode& c);
- //computes the multiplicatve inverse of the input
- ASTNode MultiplicativeInverse(const ASTNode& c);
-
- void ClearAllTables(void);
- void ClearAllCaches(void);
- int BeforeSAT_ResultCheck(const ASTNode& q);
- int CallSAT_ResultCheck(MINISAT::Solver& newS,
- const ASTNode& q, const ASTNode& orig_input);
- int SATBased_ArrayReadRefinement(MINISAT::Solver& newS,
- const ASTNode& q, const ASTNode& orig_input);
- int SATBased_ArrayWriteRefinement(MINISAT::Solver& newS, const ASTNode& orig_input);
- //creates array write axiom only for the input term or formula, if
- //necessary. If there are no axioms to produce then it simply
- //generates TRUE
- ASTNode Create_ArrayWriteAxioms(const ASTNode& array_readoverwrite_term, const ASTNode& array_newname);
- ASTVec ArrayWrite_RemainingAxioms;
- //variable indicates that counterexample will now be checked by
- //the counterexample checker, and hence simplifyterm must switch
- //off certain optimizations. In particular, array write
- //optimizations
- bool start_abstracting;
- bool Begin_RemoveWrites;
- bool SimplifyWrites_InPlace_Flag;
-
- void CopySolverMap_To_CounterExample(void);
- //int LinearSearch(const ASTNode& orig_input);
- //Datastructures and functions needed for counterexample
- //generation, and interface with MINISAT
- private:
- /* MAP: This is a map from ASTNodes to MINISAT::Vars.
- *
- * The map is populated while ASTclauses are read from the AST
- * ClauseList returned by CNF converter. For every new boolean
- * variable in ASTClause a new MINISAT::Var is created (these vars
- * typedefs for ints)
- */
- typedef hash_map<ASTNode, MINISAT::Var,
- ASTNode::ASTNodeHasher,
- ASTNode::ASTNodeEqual> ASTtoSATMap;
- ASTtoSATMap _ASTNode_to_SATVar;
-
- public:
- //converts the clause to SAT and calls SAT solver
- bool toSATandSolve(MINISAT::Solver& S, ClauseList& cll);
-
- ///print SAT solver statistics
- void PrintStats(MINISAT::SolverStats& stats);
-
- //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.
- MINISAT::Var LookupOrCreateSATVar(MINISAT::Solver& S, const ASTNode& n);
-
- // Memo table for CheckBBandCNF debugging function
- ASTNodeMap CheckBBandCNFMemo;
-
-
- //Data structures for Array Read Transformations
- private:
- /* MAP: This is a map from Array Names to list of array-read
- * indices in the input. This map is used by the TransformArray()
- * function
- *
- * This map is useful in converting array reads into nested ITE
- * constructs. Suppose there are two array reads in the input
- * Read(A,i) and Read(A,j). Then Read(A,i) is replaced with a
- * symbolic constant, say v1, and Read(A,j) is replaced with the
- * following ITE:
- *
- * ITE(i=j,v1,v2)
- */
- //CAUTION: I tried using a set instead of vector for
- //readindicies. for some odd reason the performance went down
- //considerably. this is totally inexplicable.
- ASTNodeToVecMap _arrayname_readindices;
-
- /* MAP: This is a map from Array Names to nested ITE constructs,
- * which are built as described below. This map is used by the
- * TransformArray() function
- *
- * This map is useful in converting array reads into nested ITE
- * constructs. Suppose there are two array reads in the input
- * Read(A,i) and Read(A,j). Then Read(A,i) is replaced with a
- * symbolic constant, say v1, and Read(A,j) is replaced with the
- * following ITE:
- *
- * ITE(i=j,v1,v2)
- */
- ASTNodeMap _arrayread_ite;
-
- /*MAP: This is a map from array-reads to symbolic constants. This
- *map is used by the TransformArray()
- */
- ASTNodeMap _arrayread_symbol;
-
- ASTNodeSet _introduced_symbols;
-
- /*Memoization map for TransformFormula/TransformTerm/TransformArray function
- */
- ASTNodeMap TransformMap;
-
- //count to keep track of new symbolic constants introduced
- //corresponding to Array Reads
- unsigned int _symbol_count;
-
- //Formula/Term Transformers. Let Expr Manager, Type Checker
- public:
- //Functions that Transform ASTNodes
- ASTNode TransformFormula(const ASTNode& query);
- ASTNode TransformTerm(const ASTNode& term);
- ASTNode TransformArray(const ASTNode& term);
- ASTNode TranslateSignedDivMod(const ASTNode& term);
-
- //LET Management
- private:
- // MAP: This map is from bound IDs that occur in LETs to
- // expression. The map is useful in checking replacing the IDs
- // with the corresponding expressions.
- ASTNodeMap _letid_expr_map;
- public:
-
- ASTNode ResolveID(const ASTNode& var);
-
- //Functions that are used to manage LET expressions
- void LetExprMgr(const ASTNode& var, const ASTNode& letExpr);
-
- //Delete Letid Map
- void CleanupLetIDMap(void);
-
- //Allocate LetID map
- void InitializeLetIDMap(void);
-
- //Substitute Let-vars with LetExprs
- ASTNode SubstituteLetExpr(ASTNode inExpr);
-
- /* MAP: This is a map from MINISAT::Vars to ASTNodes
- *
- * This is a reverse map, useful in constructing
- * counterexamples. MINISAT returns a model in terms of MINISAT
- * Vars, and this map helps us convert it to a model over ASTNode
- * variables.
- */
- vector<ASTNode> _SATVar_to_AST;
-
- private:
- /* MAP: This is a map from ASTNodes to vectors of bits
- *
- * This map is used in constructing and printing
- * counterexamples. MINISAT returns values for each bit (a
- * BVGETBIT Node), and this maps allows us to assemble the bits
- * into bitvectors.
- */
- typedef hash_map<ASTNode, hash_map<unsigned int, bool> *,
- ASTNode::ASTNodeHasher,
- ASTNode::ASTNodeEqual> ASTtoBitvectorMap;
- ASTtoBitvectorMap _ASTNode_to_Bitvector;
-
- //Data structure that holds the counter-model
- ASTNodeMap CounterExampleMap;
-
- //Checks if the counter_example is ok. In order for the
- //counter_example to be ok, Every assert must evaluate to true
- //w.r.t couner_example and the query must evaluate to
- //false. Otherwise the counter_example is bogus.
- void CheckCounterExample(bool t);
-
- //Converts a vector of bools to a BVConst
- ASTNode BoolVectoBVConst(hash_map<unsigned,bool> * w, unsigned int l);
-
- //accepts a term and turns it into a constant-term w.r.t counter_example
- ASTNode TermToConstTermUsingModel(const ASTNode& term, bool ArrayReadFlag = true);
- ASTNode Expand_ReadOverWrite_UsingModel(const ASTNode& term, bool ArrayReadFlag = true);
- //Computes the truth value of a formula w.r.t counter_example
- ASTNode ComputeFormulaUsingModel(const ASTNode& form);
-
- //Replaces WRITE(Arr,i,val) with ITE(j=i, val, READ(Arr,j))
- ASTNode RemoveWrites_TopLevel(const ASTNode& term);
- ASTNode RemoveWrites(const ASTNode& term);
- ASTNode SimplifyWrites_InPlace(const ASTNode& term);
- ASTNode ReadOverWrite_To_ITE(const ASTNode& term);
-
- ASTNode NewArrayVar(unsigned int index, unsigned int value);
- ASTNode NewVar(unsigned int valuewidth);
- //For ArrayWrite Abstraction: map from read-over-write term to
- //newname.
- ASTNodeMap ReadOverWrite_NewName_Map;
- //For ArrayWrite Refinement: Map new arraynames to Read-Over-Write
- //terms
- ASTNodeMap NewName_ReadOverWrite_Map;
-
- public:
- //print the STP solver output
- void PrintOutput(bool true_iff_valid);
-
- //Converts MINISAT counterexample into an AST memotable (i.e. the
- //function populates the datastructure CounterExampleMap)
- void ConstructCounterExample(MINISAT::Solver& S);
-
- //Prints the counterexample to stdout
- void PrintCounterExample(bool t,std::ostream& os=cout);
-
- //Prints the counterexample to stdout
- void PrintCounterExample_InOrder(bool t);
-
- //queries the counterexample, and returns the value corresponding
- //to e
- ASTNode GetCounterExample(bool t, const ASTNode& e);
-
- int CounterExampleSize(void) const {return CounterExampleMap.size();}
-
- //FIXME: This is bloody dangerous function. Hack attack to take
- //care of requests from users who want to store complete
- //counter-examples in their own data structures.
- ASTNodeMap GetCompleteCounterExample() {return CounterExampleMap;}
-
- // prints MINISAT assigment one bit at a time, for debugging.
- void PrintSATModel(MINISAT::Solver& S);
-
- //accepts constant input and normalizes it.
- ASTNode BVConstEvaluator(const ASTNode& t);
-
- //FUNCTION TypeChecker: Assumes that the immediate Children of the
- //input ASTNode have been typechecked. This function is suitable
- //in scenarios like where you are building the ASTNode Tree, and
- //you typecheck as you go along. It is not suitable as a general
- //typechecker
- void BVTypeCheck(const ASTNode& n);
-
- private:
- //stack of Logical Context. each entry in the stack is a logical
- //context. A logical context is a vector of assertions. The
- //logical context is represented by a ptr to a vector of
- //assertions in that logical context. Logical contexts are created
- //by PUSH/POP
- std::vector<ASTVec *> _asserts;
- //The query for the current logical context.
- ASTNode _current_query;
-
- //this flag, when true, indicates that counterexample is being
- //checked by the counterexample checker
- bool counterexample_checking_during_refinement;
-
- //this flag indicates as to whether the input has been determined to
- //be valid or not by this tool
- bool ValidFlag;
-
- //this flag, when true, indicates that a BVDIV divide by zero
- //exception occured. However, the program must not exit with a
- //fatalerror. Instead, it should evaluate the whole formula (which
- //contains the BVDIV term) to be FALSE.
- bool bvdiv_exception_occured;
-
- public:
- //set of functions that manipulate Logical Contexts.
- //
- //add an assertion to the current logical context
- void AddAssert(const ASTNode& assert);
- void Push(void);
- void Pop(void);
- void AddQuery(const ASTNode& q);
- const ASTNode PopQuery();
- const ASTNode GetQuery();
- const ASTVec GetAsserts(void);
-
- //reports node size. Second arg is "clearstatinfo", whatever that is.
- unsigned int NodeSize(const ASTNode& a, bool t = false);
-
- private:
- //This memo map is used by the ComputeFormulaUsingModel()
- ASTNodeMap ComputeFormulaMap;
- //Map for statiscal purposes
- ASTNodeSet StatInfoSet;
-
-
- ASTNodeMap TermsAlreadySeenMap;
- ASTNode CreateSubstitutionMap(const ASTNode& a);
- public:
- //prints statistics for the ASTNode. can add a prefix string c
- void ASTNodeStats(const char * c, const ASTNode& a);
-
- //substitution
- bool CheckSubstitutionMap(const ASTNode& a, ASTNode& output);
- bool CheckSubstitutionMap(const ASTNode& a);
- bool UpdateSubstitutionMap(const ASTNode& e0, const ASTNode& e1);
- //if (a > b) in the termorder, then return 1
- //elseif (a < b) in the termorder, then return -1
- //else return 0
- int TermOrder(const ASTNode& a, const ASTNode& b);
- //fill the arrayname_readindices vector if e0 is a READ(Arr,index)
- //and index is a BVCONST
- void FillUp_ArrReadIndex_Vec(const ASTNode& e0, const ASTNode& e1);
- bool VarSeenInTerm(const ASTNode& var, const ASTNode& term);
-
- //functions for checking and updating simplifcation map
- bool CheckSimplifyMap(const ASTNode& key, ASTNode& output, bool pushNeg);
- void UpdateSimplifyMap(const ASTNode& key, const ASTNode& value, bool pushNeg);
- 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)),
- SimplifyMap(INITIAL_SIMPLIFY_MAP_SIZE),
- SimplifyNegMap(INITIAL_SIMPLIFY_MAP_SIZE),
- 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;
- };
-
- //destructor
- ~BeevMgr();
- }; //End of Class BeevMgr
-
-
- class CompleteCounterExample {
- ASTNodeMap counterexample;
- BeevMgr * bv;
- public:
- CompleteCounterExample(ASTNodeMap a, BeevMgr* beev) : counterexample(a), bv(beev){}
- ASTNode GetCounterExample(ASTNode e) {
- if(BOOLEAN_TYPE == e.GetType() && SYMBOL != e.GetKind()) {
- FatalError("You must input a term or propositional variables\n",e);
- }
- if(counterexample.find(e) != counterexample.end()) {
- return counterexample[e];
- }
- else {
- if(SYMBOL == e.GetKind() && BOOLEAN_TYPE == e.GetType()) {
- return bv->CreateNode(BEEV::FALSE);
- }
-
- if(SYMBOL == e.GetKind()) {
- ASTNode z = bv->CreateZeroConst(e.GetValueWidth());
- return z;
- }
-
- return e;
- }
- }
- };
-
-} // end namespace BEEV
-#endif
diff --git a/stp/AST/ASTKind.cpp b/stp/AST/ASTKind.cpp
deleted file mode 100644
index 9a2392c9..00000000
--- a/stp/AST/ASTKind.cpp
+++ /dev/null
@@ -1,118 +0,0 @@
-// Generated automatically by genkinds.h from ASTKind.kinds Sun Apr 4 19:39:09 2010.
-// Do not edit
-namespace BEEV {
-const char * _kind_names[] = {
- "UNDEFINED",
- "SYMBOL",
- "BVCONST",
- "BVNEG",
- "BVCONCAT",
- "BVOR",
- "BVAND",
- "BVXOR",
- "BVNAND",
- "BVNOR",
- "BVXNOR",
- "BVEXTRACT",
- "BVLEFTSHIFT",
- "BVRIGHTSHIFT",
- "BVSRSHIFT",
- "BVVARSHIFT",
- "BVPLUS",
- "BVSUB",
- "BVUMINUS",
- "BVMULTINVERSE",
- "BVMULT",
- "BVDIV",
- "BVMOD",
- "SBVDIV",
- "SBVMOD",
- "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",
-};
-
-unsigned char _kind_categories[] = {
- 0,
- 3,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 3,
- 2,
- 2,
- 2,
- 2,
- 2,
- 2,
- 2,
- 2,
- 2,
- 2,
- 2,
- 2,
- 2,
- 2,
- 2,
- 2,
- 2,
- 2,
- 2,
- 2,
- 2,
- 1,
- 1,
- 0,
- 0,
- 0,
-};
-
-} // end namespace
diff --git a/stp/AST/ASTKind.h b/stp/AST/ASTKind.h
deleted file mode 100644
index 2480b6e6..00000000
--- a/stp/AST/ASTKind.h
+++ /dev/null
@@ -1,79 +0,0 @@
-// -*- c++ -*-
-#ifndef TESTKINDS_H
-#define TESTKINDS_H
-// Generated automatically by genkinds.pl from ASTKind.kinds Sun Apr 4 19:39:09 2010.
-// Do not edit
-namespace BEEV {
- typedef enum {
- UNDEFINED,
- SYMBOL,
- BVCONST,
- BVNEG,
- BVCONCAT,
- BVOR,
- BVAND,
- BVXOR,
- BVNAND,
- BVNOR,
- BVXNOR,
- BVEXTRACT,
- BVLEFTSHIFT,
- BVRIGHTSHIFT,
- BVSRSHIFT,
- BVVARSHIFT,
- BVPLUS,
- BVSUB,
- BVUMINUS,
- BVMULTINVERSE,
- BVMULT,
- BVDIV,
- BVMOD,
- SBVDIV,
- SBVMOD,
- 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
-} Kind;
-
-extern unsigned char _kind_categories[];
-
-inline bool is_Term_kind(Kind k) { return (_kind_categories[k] & 1); }
-
-inline bool is_Form_kind(Kind k) { return (_kind_categories[k] & 2); }
-
-extern const char *_kind_names[];
-
-/** Prints symbolic name of kind */
-inline ostream& operator<<(ostream &os, const Kind &kind) { os << _kind_names[kind]; return os; }
-
-
-} // end namespace
-
-
-#endif
diff --git a/stp/AST/ASTKind.kinds b/stp/AST/ASTKind.kinds
deleted file mode 100644
index 03112eb8..00000000
--- a/stp/AST/ASTKind.kinds
+++ /dev/null
@@ -1,71 +0,0 @@
-#Please refer LICENSE FILE in the home directory for licensing information
-# name minkids maxkids cat1 cat2 ...
-Categories: Term Form
-
-# Leaf nodes.
-UNDEFINED 0 0
-SYMBOL 0 0 Term Form
-
-# These always produce terms
-BVCONST 0 0 Term
-BVNEG 1 1 Term
-BVCONCAT 2 - Term
-BVOR 1 - Term
-BVAND 1 - Term
-BVXOR 1 - Term
-BVNAND 1 - Term
-BVNOR 1 - Term
-BVXNOR 1 - Term
-BVEXTRACT 3 3 Term
-BVLEFTSHIFT 3 3 Term
-BVRIGHTSHIFT 3 3 Term
-BVSRSHIFT 3 3 Term
-BVVARSHIFT 3 3 Term
-BVPLUS 1 - Term
-BVSUB 2 2 Term
-BVUMINUS 1 1 Term
-BVMULTINVERSE 1 1 Term
-BVMULT 1 - Term
-BVDIV 2 2 Term
-BVMOD 2 2 Term
-SBVDIV 2 2 Term
-SBVMOD 2 2 Term
-BVSX 1 1 Term
-BOOLVEC 0 - Term
-
-# Formula OR term, depending on context
-ITE 3 3 Term Form
-
-# These produce formulas.
-BVGETBIT 2 2 Form
-BVLT 2 2 Form
-BVLE 2 2 Form
-BVGT 2 2 Form
-BVGE 2 2 Form
-BVSLT 2 2 Form
-BVSLE 2 2 Form
-BVSGT 2 2 Form
-BVSGE 2 2 Form
-EQ 2 2 Form
-NEQ 2 2 Form
-FALSE 0 0 Form
-TRUE 0 0 Form
-NOT 1 1 Form
-AND 1 - Form
-OR 1 - Form
-NAND 1 - Form
-NOR 1 - Form
-XOR 1 - Form
-IFF 1 - Form
-IMPLIES 2 2 Form
-
-# array operations
-READ 2 2 Term
-WRITE 3 3 Term
-
-#Types: These kinds are used only in the API. Once processed inside
-#the API, they are never used again in the system
-ARRAY 0 0
-BITVECTOR 0 0
-BOOLEAN 0 0
-
diff --git a/stp/AST/ASTUtil.cpp b/stp/AST/ASTUtil.cpp
deleted file mode 100644
index ecb54a4a..00000000
--- a/stp/AST/ASTUtil.cpp
+++ /dev/null
@@ -1,45 +0,0 @@
-/********************************************************************
- * AUTHORS: Vijay Ganesh, David L. Dill
- *
- * BEGIN DATE: November, 2005
- *
- * LICENSE: Please view LICENSE file in the home dir of this Program
- ********************************************************************/
-// -*- c++ -*-
-
-#include "ASTUtil.h"
-#include <ostream>
-
-namespace BEEV {
- ostream &operator<<(ostream &os, const Spacer &sp) {
- // Instead of wrapping lines with hundreds of spaces, prints
- // a "+" at the beginning of the line for each wrap-around.
- // so lines print like: +14+ (XOR ...
- int blanks = sp._spaces % 60;
- int wraps = sp._spaces / 60;
- if (wraps > 0) {
- os << "+" << wraps;
- }
- for (int i = 0; i < blanks; i++)
- os << " ";
- return os;
- }
-
- //this function accepts the name of a function (as a char *), and
- //records some stats about it. if the input is "print_func_stats",
- //the function will then print the stats that it has collected.
- void CountersAndStats(const char * functionname) {
- if(!stats)
- return;
- static function_counters s;
-
- if(!strcmp(functionname,"print_func_stats")) {
- cout << endl;
- for(hash_map<const char*,int,hash<const char*>,eqstr>::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
diff --git a/stp/AST/ASTUtil.h b/stp/AST/ASTUtil.h
deleted file mode 100644
index c90ee0ce..00000000
--- a/stp/AST/ASTUtil.h
+++ /dev/null
@@ -1,107 +0,0 @@
-/********************************************************************
- * AUTHORS: Vijay Ganesh, David L. Dill
- *
- * BEGIN DATE: November, 2005
- *
- * LICENSE: Please view LICENSE file in the home dir of this Program
- ********************************************************************/
-// -*- c++ -*-
-
-#ifndef ASTUTIL_H
-#define ASTUTIL_H
-
-#include <cstring>
-#include <iostream>
-#include <vector>
-#ifdef EXT_HASH_MAP
-#include <ext/hash_set>
-#include <ext/hash_map>
-#else
-#include <hash_set>
-#include <hash_map>
-#endif
-
-using namespace std;
-namespace BEEV {
-#ifdef EXT_HASH_MAP
- using namespace __gnu_cxx;
-#endif
- //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
- extern bool stats;
- //print DAG nodes
- extern bool print_nodes;
- //tentative global var to allow for variable activity optimization
- //in the SAT solver. deprecated.
- extern bool variable_activity_optimize;
- //run STP in optimized mode
- extern bool optimize;
- //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.
- extern bool arrayread_refinement;
- //switch to control write refinements
- extern bool arraywrite_refinement;
- //check the counterexample against the original input to STP
- extern bool check_counterexample;
- //construct the counterexample in terms of original variable based
- //on the counterexample returned by SAT solver
- extern bool construct_counterexample;
- extern bool print_counterexample;
- //if this option is true then print the way dawson wants using a
- //different printer. do not use this printer.
- extern bool print_arrayval_declaredorder;
- //flag to decide whether to print "valid/invalid" or not
- extern bool print_output;
- //do linear search in the array values of an input array. experimental
- extern bool linear_search;
- //print the variable order chosen by the sat solver while it is
- //solving.
- extern bool print_sat_varorder;
- //turn on word level bitvector solver
- extern bool wordlevel_solve;
- //XOR flattening optimizations.
- extern bool xor_flatten;
- //this flag indicates that the BVSolver() succeeded
- extern bool toplevel_solved;
- //the smtlib parser has been turned on
- extern bool smtlib_parser_enable;
- //print the input back
- extern bool print_STPinput_back;
-
- extern void (*vc_error_hdlr)(const char* err_msg);
- /*Spacer class is basically just an int, but the new class allows
- overloading of << with a special definition that prints the int as
- that many spaces. */
- class Spacer {
- public:
- int _spaces;
- Spacer(int spaces) { _spaces = spaces; }
- friend ostream& operator<<(ostream& os, const Spacer &ind);
- };
-
- inline Spacer spaces(int width) {
- Spacer sp(width);
- return sp;
- }
-
- struct eqstr {
- bool operator()(const char* s1, const char* s2) const {
- return strcmp(s1, s2) == 0;
- }
- };
-
- typedef hash_map<const char*,int,
- hash<const char *>,eqstr> function_counters;
- void CountersAndStats(const char * functionname);
-
- //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);
-} // end namespace.
-#endif
diff --git a/stp/AST/BitBlast.cpp b/stp/AST/BitBlast.cpp
deleted file mode 100644
index de78ec74..00000000
--- a/stp/AST/BitBlast.cpp
+++ /dev/null
@@ -1,812 +0,0 @@
-/********************************************************************
- * AUTHORS: David L. Dill, Vijay Ganesh
- *
- * BEGIN DATE: November, 2005
- *
- * LICENSE: Please view LICENSE file in the home dir of this Program
- ********************************************************************/
-// -*- c++ -*-
-
-// BitBlast -- convert bitvector terms and formulas to boolean
-// formulas. A term is something that can represent a multi-bit
-// bitvector, such as BVPLUS or BVXOR (or a BV variable or constant).
-// A formula (form) represents a boolean value, such as EQ or BVLE.
-// Bit blasting a term representing an n-bit bitvector with BBTerm
-// yields a vector of n boolean formulas (returning ASTVec).
-// Bit blasting a formula returns a single boolean formula (type ASTNode).
-
-// A bitblasted term is a vector of ASTNodes for formulas.
-// The 0th element of the vector corresponds to bit 0 -- the low-order bit.
-
-#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;
-
- 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 BVSRSHIFT:
- case BVVARSHIFT:
- FatalError("BBTerm: These kinds have not been implemented in the BitBlaster: ", term);
- break;
- case ITE: {
- // Term version of ITE.
-
- // Blast the args
- // FIXME Uses temporary const ASTNodes and an ASTVec&
- const ASTNode& cond = BBForm(term[0]);
- const ASTNode& 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++, bb_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 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
- const ASTNode& bbkids = BBTerm(term[0]);
- unsigned int high = GetUnsignedConst(term[1]);
- unsigned int low = GetUnsignedConst(term[2]);
-
- 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));
- 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;
- 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);
- break;
- }
- case BVCONST: {
- ASTVec tmp_res(num_bits);
-#ifndef NATIVE_C_ARITH
- CBV bv = term.GetBVConst();
- for(unsigned int i = 0; i < num_bits; i++){
- tmp_res[i] = CONSTANTBV::BitVector_bit_test(bv,i) ? ASTTrue : ASTFalse;
- }
-#else
- const unsigned long long int c = term.GetBVConst();
- unsigned long long int bitmask = 0x00000000000000001LL;
- for (unsigned int i = 0; i < num_bits; i++, bitmask <<= 1)
- tmp_res[i] = ((c & (bitmask)) ? ASTTrue : ASTFalse);
-#endif
- result = CreateNode(BOOLVEC, tmp_res);
- break;
- }
- case BOOLVEC: {
- cerr << "Hit a boolvec! what to do?" << endl;
- break;
- }
- default:
- FatalError("BBTerm: Illegal kind to BBTerm",term);
- }
-
- //if(result == ASTJunk)
- // cout<<"result does not change"<<endl;
- // cout << "================" << endl << "BBTerm:" << term << endl;
- // cout << "----------------" << endl << "BBTerm result:";
- // lpvec(result);
- // cout << endl;
-
- return (BBTermMemo[term] = result);
-
-}
-
-// 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:
- 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: {
- 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: {
- // Common code for binary operations
- // FIXME: This ought to be in a semantic analysis phase.
- const ASTNode left = BBTerm(form[0]);
- const ASTNode right = BBTerm(form[1]);
- if (left.Degree() != right.Degree()) {
- cerr << "BBForm: Size mismatch" << endl << form[0] << endl << form[1] << endl;
- FatalError("",ASTUndefined);
- }
- result = BBEQ(left.GetChildren(), right.GetChildren());
- 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);
-}
-
-// 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
diff --git a/stp/AST/Makefile b/stp/AST/Makefile
deleted file mode 100644
index c3b54672..00000000
--- a/stp/AST/Makefile
+++ /dev/null
@@ -1,19 +0,0 @@
-#===-- stp/AST/Makefile ------------------------------------*- Makefile -*--===#
-#
-# The KLEE Symbolic Virtual Machine
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-#===------------------------------------------------------------------------===#
-
-LEVEL=../..
-
-LIBRARYNAME=stp_AST
-DONT_BUILD_RELINKED=1
-BUILD_ARCHIVE=1
-
-include $(LEVEL)/Makefile.common
-
-# HACK: Force -Wno-deprecated for ext container use.
-CXX.Flags += -Wno-deprecated
diff --git a/stp/AST/STLport_config.h b/stp/AST/STLport_config.h
deleted file mode 100644
index 9b7bc14f..00000000
--- a/stp/AST/STLport_config.h
+++ /dev/null
@@ -1,20 +0,0 @@
-/********************************************************************
- * AUTHORS: Vijay Ganesh, David L. Dill
- *
- * BEGIN DATE: November, 2005
- *
- * LICENSE: Please view LICENSE file in the home dir of this Program
- ********************************************************************/
-// -*- c++ -*-
-
-// STLport debug checking, if we use STLport threads flag is to get
-// rid of link errors, since iostreams compiles with threads. alloc
-// and uninitialized are extra checks Later on, if used with Purify or
-// Valgrind, may want to set flags to prevent reporting of false
-// leaks. For some reason, _STLP_THREADS works on the command line
-// but not here (?)
-#define _STLP_THREADS
-#define _STLP_DEBUG 1
-#define _STLP_DEBUG_LEVEL _STLP_STANDARD_DBG_LEVEL
-#define _STLP_DEBUG_ALLOC 1
-#define _STLP_DEBUG_UNINITIALIZED 1
diff --git a/stp/AST/SimpBool.cpp b/stp/AST/SimpBool.cpp
deleted file mode 100644
index 67f9825d..00000000
--- a/stp/AST/SimpBool.cpp
+++ /dev/null
@@ -1,408 +0,0 @@
-/********************************************************************
- * AUTHORS: Vijay Ganesh, David L. Dill
- *
- * BEGIN DATE: April, 2006
- *
- * LICENSE: Please view LICENSE file in the home dir of this Program
- ********************************************************************/
-
-// -*- c++ -*-
-
-// Simplifying create methods for Boolean operations.
-// These are only very simple local simplifications.
-
-// This is somewhat redundant with Vijay's simplifier code. They
-// need to be merged.
-// FIXME: control with optimize flag.
-
-static bool _trace_simpbool = 0;
-static bool _disable_simpbool = 0;
-
-#include "AST.h"
-
-// SMTLIB experimental hack. Try allocating a single stack here for
-// children to reduce growing of vectors.
-//BEEV::ASTVec child_stack;
-
-namespace BEEV {
-
- ASTNode BeevMgr::CreateSimpForm(Kind kind, ASTVec &children = _empty_ASTVec) {
- if (_disable_simpbool) {
- return CreateNode(kind, children);
- }
- else {
- switch (kind) {
- case NOT: return CreateSimpNot(children[0]); break;
- case AND: return CreateSimpAndOr(1, children); break;
- case OR: return CreateSimpAndOr(0, children); break;
- case NAND: return CreateSimpNot(CreateSimpAndOr(1, children)); break;
- case NOR: return CreateSimpNot(CreateSimpAndOr(0, children)); break;
- case IFF: {
- // Not sure children can ever be empty, but what the heck.
- // if (children.size() == 0) {
- // return ASTTrue;
- // }
- // Convert IFF to XOR ASAP. IFF is not associative, so this makes
- // flattening much easier.
- 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);
- }
-
-
- 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);
- }
-
- ASTNode BeevMgr::CreateSimpAndOr(bool IsAnd, ASTVec &children) {
-
- if (_trace_simpbool) {
- cout << "========" << endl << "CreateSimpAndOr " << (IsAnd ? "AND " : "OR ") ;
- lpvec(children);
- cout << endl;
- }
-
- ASTVec new_children;
-
- // sort so that identical nodes occur in sequential runs, followed by
- // their negations.
-
- SortByExprNum(children);
-
- ASTNode annihilator = (IsAnd ? ASTFalse : ASTTrue);
- ASTNode identity = (IsAnd ? ASTTrue : ASTFalse);
-
- ASTNode retval;
-
- ASTVec::const_iterator it_end = children.end();
- ASTVec::const_iterator next_it;
- for(ASTVec::const_iterator it = 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;
- }
-
- // Change this not to init to children if flattening code is present.
- // ASTVec flat_children = children; // empty vector
-
- ASTVec flat_children; // empty vector
-
- ASTVec::const_iterator it_end = children.end();
-
- if (xor_flatten) {
-
- bool fflag = 0; // ***Temp debugging
-
- // Experimental flattening code.
-
- for(ASTVec::iterator it = children.begin(); it != it_end; it++) {
- Kind ck = it->GetKind();
- const ASTVec &gchildren = it->GetChildren();
- if (XOR == ck) {
- fflag = 1;
- // 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: " << endl;
- lpvec(children);
-
- cout << "--------" << endl;
- cout << "Flattening result: " << endl;
- lpvec(flat_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
diff --git a/stp/AST/ToCNF.cpp b/stp/AST/ToCNF.cpp
deleted file mode 100644
index 2a18b3f5..00000000
--- a/stp/AST/ToCNF.cpp
+++ /dev/null
@@ -1,506 +0,0 @@
-/********************************************************************
- * AUTHORS: David L. Dill, Vijay Ganesh
- *
- * BEGIN DATE: November, 2005
- *
- * LICENSE: Please view LICENSE file in the home dir of this Program
- ********************************************************************/
-// -*- c++ -*-
-
-// THEORY: This code translates an arbitrary Boolean DAG, generated by
-// the BitBlast.cpp, to an equi-satisfiable CNF formula. There are
-// four kinds of variables in the CNF formula: (1) propositional
-// variables from the original formula; (2) BVGETBIT formulas from the
-// original formula (a precondition is that the BVGETBIT can only be
-// applied to bitvector-valued variables, array reads, or
-// uninterpreted functions); (3) TRUE; or (4) representative variables
-// (see below). Each literal in the CNF formula is one of these or
-// its negation.
-
-// It is convenient (though not perfectly efficient) to be able to add
-// TRUE and FALSE constants to clauses, which is not allowed in CNF.
-// So, there is a "dummy variable" representing TRUE, which is used in
-// its place (so FALSE is represented by the negation of the dummy
-// var). The CNF formula has a unit clause containing this dummy
-// variable, so that any satisfying assignment must make the dummy var
-// TRUE.
-
-// Every sub-formula of the input formula has a "representative
-// literal." A truth assignment satisfies the CNF formula iff the
-// restriction of that assignment to the original variables satisfies
-// the original formula, AND the rep lits have the same truth values
-// as the subformulas they represent in the original formula. In the
-// trivial cases, the representative literal is the input variable, or
-// dummy true var, or its negation. Representative literals may be
-// negated variables -- essentially, only AND formulas are translated,
-// and everything else is handled by rewriting or negating formulas.
-// The representative for (NOT alpha) is the negation of the
-// representative for alpha.
-
-// The translation is performed by ToCNF_int, which traverses the original
-// formula. ToCNF adds clauses that constrain the representative variables
-// to be equal to the truth values of the formulas they represent.
-// ToCNF always returns a literal whose value must be equivalent to the formula
-// it translated. In trivial cases, this literal is a literal from the original
-// formula, or the dummy true/false literals. If the formula is of the form
-// (not alpha), ToCNF_int negates the literal representing alpha (which may
-// itself be a negative literal) and returns it. Otherwise, ToCNF_int assigns
-// a new rep var, adds the clauses, and returns the new var. ToCNF_int is
-// memoized so that it doesn't assign more than one variable to a subformula,
-// and to prevent exponential numbers of redundant visits to shared subformulas.
-
-// In reality, only AND/OR/NOT formulas are translated directly. Everything
-// else (XOR, IFF, IMPLIES) is rewritten on-the-fly into these forms. I
-// could have done that in bit-blasting, but I thought that, in the future,
-// we might be able to translate these operations differently in different
-// contexts to optimize the CNF formula.
-
-// FIXME: Inspection of the clauses is kind of horrifying. In
-// addition to true/false, there are duplicate literals and duplicate
-// clauses all over the place.
-#include "AST.h"
-static bool CNF_trace = false;
-namespace BEEV {
-/** Statistics class. Total number of variables is best tracked in
- ToSAT. Number of clauses is just cll.size() */
-
-class CNFstats {
-public:
- int _num_new_rep_vars;
- int _num_clauses;
-
- // constructor
- CNFstats() : _num_new_rep_vars(0), _num_clauses(0) {}
-
- void printStats() {
- if(stats) {
- cout << "ToCNF statistics:" << endl;
- cout << "Number of new representative variables: "
- << _num_new_rep_vars << endl;
- cout << "Number of new clauses: "
- << _num_clauses << endl;
- }
- }
-
-};
-
-
-/** This class contains private data and function members for the
- CNF conversion */
-class CNFMgr {
-
- friend class BeevMgr;
-
-public:
-
- // Needed in the body of BeevMgr::ToCNF. It's not visible outside
- // this file, though.
- ASTNode dummy_true_var;
-
- // CNF Pre-pass
- ASTNodeMap ToCNFPrePassMemo;
-
- // CNF Memo Table.
- ASTNodeMap CNFMemo;
-
-
-private:
-
- // Pointer back to BeevMgr with the node tables, etc.
- BeevMgr *bm;
-
- // For ToCNF conversion. This holds a dummy variable representing
- // "True". It is added as a unit clause, so that it will be assigned
- // to true and propagated immediately by any CNF solver.
-
- ASTNode dummy_false_var; // not of dummy_true_var
-
- CNFstats stats;
-
- // constructor
- CNFMgr(BeevMgr *bmgr)
- {
- bm = bmgr;
-
- // Dummy variable so TRUE can be a literal.
- dummy_true_var = bm->CreateSymbol("*TrueDummy*");
- dummy_false_var = bm->CreateSimpNot(dummy_true_var);
- }
-
- // Returns true iff result has been memoized.
- // if it returns true, result is returned in by-ref parameter "result"
- // Consider just putitng this in-line.
- bool CNFIsMemoized(ASTNode &form, ASTNode &result)
- {
- ASTNodeMap::iterator it = CNFMemo.find(form);
- if (it != CNFMemo.end()) {
- result = it->second; //already there. Just return it.
- return true;
- }
- else {
- return false;
- }
- }
-
-
- // Convert a big XOR to a bunch of AND/ORs. Assumes subformulas have
- // already been converted.
- ASTNode convertXORs(ASTVec children)
- {
- ASTNode accum = children[0];
- ASTVec::iterator itend = children.end();
- for (ASTVec::iterator it = children.begin()+1; it < itend; it++) {
- // a XOR b -> (a | b) & (!a | !b)
-
- // For each XOR node with k children, creates approximately
- // 5*(k-1) nodes. AND + 2 OR + 2 NOT.
-
- ASTNode or1 = bm->CreateNode(OR, accum, *it);
- ASTNode or2 = bm->CreateNode(OR, bm->CreateSimpNot(accum), bm->CreateSimpNot(*it));
- accum = bm->CreateNode(AND, or1, or2);
-
- }
-
- return accum;
- }
-
-
- // Do preliminary transformations on bitblasted formula to make
- // CNF conversion easier.
- // Converts XORs to AND/OR form.
- ASTNode ToCNFPrePass(const ASTNode &form)
- {
-
- // Check memo table
- ASTNodeMap::iterator mem_it = ToCNFPrePassMemo.find(form);
- if (mem_it != ToCNFPrePassMemo.end()) {
- return mem_it->second;
- }
-
- ASTNode result;
-
- ASTVec new_children;
- ASTVec::const_iterator endit = form.end();
- for (ASTVec::const_iterator it = form.begin(); it != endit; it++) {
- ASTNode ch = ToCNFPrePass(*it);
- new_children.push_back(ch);
- }
-
- Kind k = form.GetKind();
-
- switch (k) {
- case FALSE:
- case TRUE:
- case SYMBOL:
- case BVGETBIT: {
- result = form;
- break;
- }
- case XOR: {
- // convertXORs can only be called once per XOR node.
- result = convertXORs(new_children);
-
- // cout << "convertXORs num args: " << new_children.size() << endl;
- // temporary node for node count.
- // ASTNode tmp = bm->CreateNode(XOR, new_children );
- // cout << "convertXORs size of [" << form.GetNodeNum() << "] " << bm->NodeSize(form, true) << endl;
- // cout << "convertXORs before size: " << bm->NodeSize(tmp, true) << endl;
- // cout << "convertXORs after size: " << bm->NodeSize(result, true) << endl;
- break;
- }
- default: {
- // Be cautious about using CreateSimpForm -- It makes big xors!
- result = bm->CreateNode(k, new_children);
- }
- }
-
-// cout << "================" << endl
-// << "ToCNFPrePass:" << form << endl
-// << "----------------" << endl
-// << "ToCNFPrePass Result:" << result << endl;
-
- return (ToCNFPrePassMemo[form] = result);
-
- }
-
- // Memoize and return formula value
- ASTNode CNFMemoize(ASTNode& form, ASTNode result)
- {
- CNFMemo[form] = result;
- return result;
- }
-
-
- // Create a representative variable for an original formula.
- // The convention is that the variable will have the same truth
- // value as the expression numbered "num."
- ASTNode RepLit(const char *name, int exprnum)
- {
- // FIXME: can this be done more efficiently with string type?
- ostringstream oss;
- oss << name << "{" << exprnum << "}";
- ASTNode t = bm->CreateSymbol(oss.str().c_str());
-
- // Track how many we're generating.
- stats._num_new_rep_vars++;
-
- //ASTNode is of type BOOLEAN <==> ((indexwidth=0)&&(valuewidth=0))
- t.SetIndexWidth(0);
- t.SetValueWidth(0);
- return t;
- }
-
- // Handle the cases where it's necessary to do n children.
- // This code translates ANDs, and converts NAND, NOR, OR by negating
- // the inputs or outputs of the AND.
- ASTNode ToCNF_AndLike(Kind k, BeevMgr::ClauseList& cll, ASTNode form)
- {
- // Build vectors of positive and negative rep lits for children
- ASTVec kidlits(0);
- ASTVec negkidlits(0);
- ASTVec::const_iterator kids_end = form.end();
- for (ASTVec::const_iterator it = form.begin(); it != kids_end; it++) {
- ASTNode kidreplit = ToCNF_int(cll, *it);
- kidlits.push_back(kidreplit);
- negkidlits.push_back(bm->CreateSimpNot(kidreplit));
- }
-
- ASTNode replit;
- // translate the AND, negating inputs as appropriate.
- if (k == OR || k == NOR) {
- replit = ToCNF_AND(cll, form.GetNodeNum(), negkidlits, kidlits);
- }
- else {
- replit = ToCNF_AND(cll, form.GetNodeNum(), kidlits, negkidlits);
- }
-
- // Reduce NAND/OR to AND by negating result.
- if (k == NAND || k == OR) {
- return CNFMemoize(form, bm->CreateSimpNot(replit));
- }
- else {
- return CNFMemoize(form, replit);
- }
- }
-
- ASTNode ToCNF_AND(BeevMgr::ClauseList& cll, int nodenum, ASTVec& kidlits, ASTVec& negkidlits)
- {
- // Translate an AND, given rep lits for children
- // Build clauses for (replit <-> a AND b AND c)
-
- ASTNode replit = RepLit("cnf", nodenum);
- ASTNode notreplit = bm->CreateSimpNot(replit);
-
- if (CNF_trace) {
- cout << "Translating AND" << endl << "-----------------------" << endl
- << "Rep lit =" << replit << endl
- << "-----------------------";
- }
-
- // (a AND b AND c -> replit) == (~a OR ~b OR ~c OR replit)
- BeevMgr::ClausePtr clp = new ASTVec(negkidlits);
- clp->push_back(replit);
-
- if (CNF_trace) {
- LispPrintVec(cout, *clp, 0);
- cout << endl << "-----------------------" << endl;
- }
-
- cll.push_back(clp);
-
- // (replit -> (a AND b AND c)) ==
- // (~replit OR a) AND (~replit OR b) AND (~replit OR c)
- ASTVec::const_iterator kidlits_end = kidlits.end();
- for (ASTVec::iterator it = kidlits.begin(); it != kidlits_end; it++) {
- clp = new ASTVec();
- clp->push_back(notreplit);
- clp->push_back(*it);
-
- if (CNF_trace) {
- LispPrintVec(cout, *clp, 0);
- cout << endl << "-----------------------" << endl;
- }
-
- cll.push_back(clp);
- }
-
- return replit;
- }
-
-public:
-
- /** Builds clauses globally and returns a literal.
- The literal can be a leaf from the expression, or a rep var
- made up to represent the subexpression. */
- ASTNode ToCNF_int(BeevMgr::BeevMgr::ClauseList& cll, ASTNode form) {
- // FIXME: assert indexwidth= 0, valuewidth = 1
-
- // FIXME: rewriting is top-down, which is not efficient.
- // It rewrites the top node of the tree, then does the children.
- // Either rewrite in a separate pass, or translate children
- // before rewriting somehow (might require handling rep lits
- // as though they were real lits, which is probably ok).
-
- // Return memoized value if seen before.
- ASTNode result;
- Kind k = form.GetKind();
-
- if (CNFIsMemoized(form, result)) {
- return result;
- }
-
- switch (k) {
- // handle the trivial cases here. If none apply, call the
- // heavy-duty function. If a constant or literal, just return
- // without creating a clause.
- case FALSE: {
- result = dummy_false_var;
- break;
- }
- case TRUE: {
- result = dummy_true_var;
- break;
- }
- case SYMBOL:
- case BVGETBIT: {
- result = form;
- break;
- }
-
- case NOT: {
- ASTNode replit = ToCNF_int(cll, form[0]);
- result = bm->CreateSimpNot(replit);
- break;
- }
-
- // For these, I can't think of anything better than expanding into ANDs/ORs
- case ITE: {
- // (ite a b c) == (~a OR b) AND (a OR c)
- ASTNode l = bm->CreateNode(OR, bm->CreateSimpNot(form[0]), form[1]);
- ASTNode r = bm->CreateNode(OR, form[0], form[2]);
- ASTNode andor = bm->CreateNode(AND, l, r);
- if (CNF_trace) {
- cout << "Rewriting " << form << endl
- << "to" << andor << endl
- << "-------------------" << endl;
- }
- result = ToCNF_int(cll, andor);
- break;
- }
- case IMPLIES: {
- // Just rewrite into (~a OR b)
- ASTNode l = bm->CreateSimpNot(form[0]);
- ASTNode andor = bm->CreateNode(OR, l, form[1]);
- if (CNF_trace) {
- cout << "Rewriting " << form << endl
- << "to" << andor << endl
- << "-------------------" << endl;
- }
- result = ToCNF_int(cll, andor);
- break;
- }
- case XOR: {
- FatalError("ToCNF_int: XORs should have been converted to AND/OR by this point.");
- break;
- }
-
- case IFF: {
- FatalError("BitBlaster failed to eliminate all IFFs.");
- break;
- }
-
- case AND:
- case OR:
- case NOR:
- case NAND: {
- result = ToCNF_AndLike(k, cll, form);
- break;
- }
- default:
- cerr << "ToCNF: can't handle this kind: " << k << endl;
- FatalError("");
- }
-
- if (CNF_trace) {
- cout << "ToCNF_int: Literal " << result << " represents formula " <<
- form << endl << "---------------" << endl;
- }
-
- return CNFMemoize(form, result);
- } //end of ToCNF_int()
-
-
-}; // end of CNFMgr class
-
- // These are the bodies of functions in the BeevMgr that are part of
- // the public interface.
-
- // Debug printing function.
- 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;
- LispPrintVec(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;
- }
-
- // Top level conversion function
- BeevMgr::ClauseList *BeevMgr::ToCNF(const ASTNode& form)
- {
-
- // FIXME: This is leaked as well.
- CNFMgr *cm = new CNFMgr(this);
-
- // Prepass
- ASTNode form1 = cm->ToCNFPrePass(form);
-
- // cout << "Number of nodes after ToCNFPrePass" << NodeSize(form1, true) << endl;
-
- // cout << "ToCNF: After ToCNFPrePass" << form1 << endl;
-
- // FIXME: Assert CNFMemo is empty.
-
- // The clause list we will be building up.
- // FIXME: This is never freed.
- ClauseList *cllp = new ClauseList();
-
- BeevMgr::ClausePtr dummy_true_unit_clause = new ASTVec();
- dummy_true_unit_clause->push_back(cm->dummy_true_var);
- cllp->push_back(dummy_true_unit_clause);
-
- // This is where the translation happens.
- ASTNode toplit = cm->ToCNF_int(*cllp, form1);
-
- // Add the top literal as a unit clause, since it must
- // be true when original formula is satsfied.
- BeevMgr::ClausePtr clp = new ASTVec(0);
- clp->push_back(toplit);
- cllp->push_back(clp);
-
- cm->stats._num_clauses = cllp->size();
- cm->stats.printStats();
-
- RepLitMap = cm->CNFMemo; // Save memo table for debugging (DD 1/13/07).
-
- cm->CNFMemo.clear(); // Important to do this so nodes get freed.
-
- delete cm;
-
- return cllp;
- }
-
-} // end namespace
diff --git a/stp/AST/ToSAT.cpp b/stp/AST/ToSAT.cpp
deleted file mode 100644
index 3ad21f93..00000000
--- a/stp/AST/ToSAT.cpp
+++ /dev/null
@@ -1,1386 +0,0 @@
-/********************************************************************
- * AUTHORS: Vijay Ganesh, David L. Dill
- *
- * BEGIN DATE: November, 2005
- *
- * LICENSE: Please view LICENSE file in the home dir of this Program
- ********************************************************************/
-// -*- c++ -*-
-#include "AST.h"
-#include "ASTUtil.h"
-#include "../simplifier/bvsolver.h"
-#include <math.h>
-
-
-namespace BEEV {
- /* FUNCTION: lookup or create a new MINISAT literal
- * lookup or create new MINISAT Vars from the global MAP
- * _ASTNode_to_SATVar.
- */
- 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)
- {
- 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
- newS.turnOffSubsumption();
-
- // (*i) is an ASTVec-ptr which denotes an ASTclause
- for(; i!=iend; i++) {
- //Clause for the SATSolver
- MINISAT::vec<MINISAT::Lit> satSolverClause;
-
- //now iterate through the internals of the ASTclause itself
- ASTVec::const_iterator j = (*i)->begin(), jend = (*i)->end();
- //j is a disjunct in the ASTclause (*i)
- for(;j!=jend;j++) {
-
- bool negate = (NOT == j->GetKind()) ? true : false;
- ASTNode n = negate ? (*j)[0] : *j;
-
- //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.stats);
- return false;
- }
-
- if(!newS.simplifyDB(false)) {
- PrintStats(newS.stats);
- return false;
- }
- }
-
- // if input is UNSAT return false, else return true
- if(!newS.simplifyDB(false)) {
- PrintStats(newS.stats);
- return false;
- }
-
- //PrintActivityLevels_Of_SATVars("Before SAT:",newS);
- //ChangeActivityLevels_Of_SATVars(newS);
- //PrintActivityLevels_Of_SATVars("Before SAT and after initial bias:",newS);
- newS.solve();
- //PrintActivityLevels_Of_SATVars("After SAT",newS);
-
- PrintStats(newS.stats);
- if (newS.okay())
- return true;
- else
- return false;
- }
-
- // GLOBAL FUNCTION: Prints statistics from the MINISAT Solver
- void BeevMgr::PrintStats(MINISAT::SolverStats& s) {
- if(!stats)
- return;
- double cpu_time = MINISAT::cpuTime();
- MINISAT::int64 mem_used = MINISAT::memUsed();
- printf("restarts : %"I64_fmt"\n", s.starts);
- printf("conflicts : %-12"I64_fmt" (%.0f /sec)\n", s.conflicts , s.conflicts /cpu_time);
- printf("decisions : %-12"I64_fmt" (%.0f /sec)\n", s.decisions , s.decisions /cpu_time);
- printf("propagations : %-12"I64_fmt" (%.0f /sec)\n", s.propagations, s.propagations/cpu_time);
- printf("conflict literals : %-12"I64_fmt" (%4.2f %% deleted)\n",
- s.tot_literals,
- (s.max_literals - s.tot_literals)*100 / (double)s.max_literals);
- if (mem_used != 0) printf("Memory used : %.2f MB\n", mem_used / 1048576.0);
- printf("CPU time : %g s\n", cpu_time);
- fflush(stdout);
- }
-
- // Prints Satisfying assignment directly, for debugging.
- void BeevMgr::PrintSATModel(MINISAT::Solver& newS) {
- if(!newS.okay())
- FatalError("PrintSATModel: NO COUNTEREXAMPLE TO PRINT",ASTUndefined);
- // FIXME: Don't put tests like this in the print functions. The print functions
- // should print unconditionally. Put a conditional around the call if you don't
- // want them to print
- if(!(stats && print_nodes))
- return;
-
- int num_vars = newS.nVars();
- cout << "Satisfying assignment: " << endl;
- for (int i = 0; i < num_vars; i++) {
- if (newS.model[i] == MINISAT::l_True) {
- ASTNode s = _SATVar_to_AST[i];
- cout << s << endl;
- }
- else if (newS.model[i] == MINISAT::l_False) {
- ASTNode s = _SATVar_to_AST[i];
- cout << CreateNode(NOT, s) << endl;
- }
- }
- }
-
-
- // Looks up truth value of ASTNode SYMBOL in MINISAT satisfying assignment.
- // Returns ASTTrue if true, ASTFalse if false or undefined.
- ASTNode BeevMgr::SymbolTruthValue(MINISAT::Solver &newS, ASTNode form)
- {
- MINISAT::Var satvar = _ASTNode_to_SATVar[form];
- if (newS.model[satvar] == MINISAT::l_True) {
- return ASTTrue;
- }
- else if (newS.model[satvar] == MINISAT::l_False){
- // False
- return ASTFalse;
- }
- else {
- return (rand() > 4096) ? ASTTrue : 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)
- 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
- CounterExampleMap[s] = ASTFalse;
- }
- }
- }
- }
- }
-
- //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);
- }
-
- //READ over a WRITE
- if(WRITE == arrName.GetKind()) {
- ASTNode wrtterm = Expand_ReadOverWrite_UsingModel(term, ArrayReadFlag);
- if(wrtterm == term) {
- FatalError("TermToConstTermUsingModel: Read_Over_Write term must be expanded into an ITE", term);
- }
- ASTNode rtterm = TermToConstTermUsingModel(wrtterm,ArrayReadFlag);
- return rtterm;
- }
- //READ over an ITE
- if(ITE == arrName.GetKind()) {
- arrName = TermToConstTermUsingModel(arrName,ArrayReadFlag);
- }
-
- ASTNode modelentry;
- if(CounterExampleMap.find(index) != CounterExampleMap.end()) {
- //index has a const value in the CounterExampleMap
- ASTNode indexVal = CounterExampleMap[index];
- modelentry = CreateTerm(READ, arrName.GetValueWidth(), arrName, indexVal);
- }
- else {
- //index does not have a const value in the CounterExampleMap. compute it.
- ASTNode indexconstval = TermToConstTermUsingModel(index,ArrayReadFlag);
- //update model with value of the index
- //CounterExampleMap[index] = indexconstval;
- modelentry = CreateTerm(READ,arrName.GetValueWidth(), arrName,indexconstval);
- }
- //modelentry is now an arrayread over a constant index
- BVTypeCheck(modelentry);
-
- //if a value exists in the CounterExampleMap then return it
- if(CounterExampleMap.find(modelentry) != CounterExampleMap.end()) {
- output = TermToConstTermUsingModel(CounterExampleMap[modelentry],ArrayReadFlag);
- }
- else if(ArrayReadFlag) {
- //return the array read over a constantindex
- output = modelentry;
- }
- else {
- //when all else fails set symbol values to some constant by
- //default. if the variable is queried the second time then add 1
- //to and return the new value.
- ASTNode zero = CreateZeroConst(modelentry.GetValueWidth());
- output = zero;
- }
- break;
- }
- case ITE: {
- ASTNode condcompute = ComputeFormulaUsingModel(term[0]);
- if(ASTTrue == condcompute) {
- output = TermToConstTermUsingModel(term[1],ArrayReadFlag);
- }
- else if(ASTFalse == condcompute) {
- output = TermToConstTermUsingModel(term[2],ArrayReadFlag);
- }
- else {
- cerr << "TermToConstTermUsingModel: termITE: value of conditional is wrong: " << condcompute << endl;
- FatalError(" TermToConstTermUsingModel: termITE: cannot compute ITE conditional against model: ",term);
- }
- break;
- }
- default: {
- ASTVec c = term.GetChildren();
- ASTVec o;
- for(ASTVec::iterator it=c.begin(),itend=c.end();it!=itend;it++) {
- ASTNode ff = TermToConstTermUsingModel(*it,ArrayReadFlag);
- o.push_back(ff);
- }
- output = CreateTerm(k,term.GetValueWidth(),o);
- //output is a CONST expression. compute its value and store it
- //in the CounterExampleMap
- ASTNode oo = BVConstEvaluator(output);
- //the return value
- output = oo;
- break;
- }
- }
-
- //when this flag is false, we should compute the arrayread to a
- //constant. this constant is stored in the counter_example
- //datastructure
- if(!ArrayReadFlag) {
- CounterExampleMap[term] = output;
- }
-
- //cerr << "Output to TermToConstTermUsingModel: " << output << endl;
- return output;
- } //End of TermToConstTermUsingModel
-
- //Expands read-over-write by evaluating (readIndex=writeIndex) for
- //every writeindex until, either it evaluates to TRUE or all
- //(readIndex=writeIndex) evaluate to FALSE
- ASTNode BeevMgr::Expand_ReadOverWrite_UsingModel(const ASTNode& term, bool arrayread_flag) {
- if(READ != term.GetKind() &&
- WRITE != term[0].GetKind()) {
- FatalError("RemovesWrites: Input must be a READ over a WRITE",term);
- }
-
- ASTNode output;
- ASTNodeMap::iterator it1;
- if((it1 = CounterExampleMap.find(term)) != CounterExampleMap.end()) {
- ASTNode val = it1->second;
- if(BVCONST != val.GetKind()) {
- //recursion is fine here. There are two maps that are checked
- //here. One is the substitutionmap. We garuntee that the value
- //of a key in the substitutionmap is always a constant.
- if(term == val) {
- FatalError("TermToConstTermUsingModel: The input term is stored as-is "
- "in the CounterExample: Not ok: ",term);
- }
- 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!
-
- if(!check_counterexample) {
- return;
- }
-
- //input is valid, no counterexample to check
- if(ValidFlag)
- return;
-
- //t is true if SAT solver generated a counterexample, else it is false
- if(!t)
- FatalError("CheckCounterExample: No CounterExample to check", ASTUndefined);
- const ASTVec c = GetAsserts();
- for(ASTVec::const_iterator it=c.begin(),itend=c.end();it!=itend;it++)
- if(ASTFalse == ComputeFormulaUsingModel(*it))
- FatalError("CheckCounterExample:counterexample bogus:"\
- "assert evaluates to FALSE under counterexample: NOT OK",*it);
-
- if(ASTTrue == ComputeFormulaUsingModel(_current_query))
- FatalError("CheckCounterExample:counterexample bogus:"\
- "query evaluates to TRUE under counterexample: NOT OK",_current_query);
- }
-
- /* FUNCTION: prints a counterexample for INVALID inputs. iterate
- * through the CounterExampleMap data structure and print it to
- * stdout
- */
- void BeevMgr::PrintCounterExample(bool t, std::ostream& os) {
- //global command-line option
- // FIXME: This should always print the counterexample. If you want
- // to turn it off, check the switch at the point of call.
- if(!print_counterexample)
- return;
-
- //input is valid, no counterexample to print
- if(ValidFlag)
- return;
-
- //if this option is true then print the way dawson wants using a
- //different printer. do not use this printer.
- if(print_arrayval_declaredorder)
- return;
-
- //t is true if SAT solver generated a counterexample, else it is
- //false
- if(!t) {
- cerr << "PrintCounterExample: No CounterExample to print: " << endl;
- return;
- }
-
- //os << "\nCOUNTEREXAMPLE: \n" << endl;
- ASTNodeMap::iterator it = CounterExampleMap.begin();
- ASTNodeMap::iterator itend = CounterExampleMap.end();
- for(;it!=itend;it++) {
- ASTNode f = it->first;
- ASTNode se = it->second;
-
- if(ARRAY_TYPE == se.GetType()) {
- FatalError("TermToConstTermUsingModel: entry in counterexample is an arraytype. bogus:",se);
- }
-
- //skip over introduced variables
- if(f.GetKind() == SYMBOL && (_introduced_symbols.find(f) != _introduced_symbols.end()))
- continue;
- if(f.GetKind() == SYMBOL ||
- (f.GetKind() == READ && f[0].GetKind() == SYMBOL && f[1].GetKind() == BVCONST)) {
- os << "ASSERT( ";
- f.PL_Print(os,0);
- os << " = ";
- if(BITVECTOR_TYPE == se.GetType()) {
- TermToConstTermUsingModel(se,false).PL_Print(os,0);
- }
- else {
- se.PL_Print(os,0);
- }
- os << " );" << endl;
- }
- }
- //os << "\nEND OF COUNTEREXAMPLE" << endl;
- } //End of PrintCounterExample
-
- /* iterate through the CounterExampleMap data structure and print it
- * to stdout. this function prints only the declared array variables
- * IN the ORDER in which they were declared. It also assumes that
- * the variables are of the form 'varname_number'. otherwise it will
- * not print anything. This function was specifically written for
- * Dawson Engler's group (bug finding research group at Stanford)
- */
- void BeevMgr::PrintCounterExample_InOrder(bool t) {
- //global command-line option to print counterexample. we do not
- //want both counterexample printers to print at the sametime.
- // FIXME: This should always print the counterexample. If you want
- // to turn it off, check the switch at the point of call.
- if(print_counterexample)
- return;
-
- //input is valid, no counterexample to print
- if(ValidFlag)
- return;
-
- //print if the commandline option is '-q'. allows printing the
- //counterexample in order.
- if(!print_arrayval_declaredorder)
- return;
-
- //t is true if SAT solver generated a counterexample, else it is
- //false
- if(!t) {
- cerr << "PrintCounterExample: No CounterExample to print: " << endl;
- return;
- }
-
- //vector to store the integer values
- std::vector<int> out_int;
- cout << "% ";
- for(ASTVec::iterator it=_special_print_set.begin(),itend=_special_print_set.end();
- it!=itend;it++) {
- if(ARRAY_TYPE == it->GetType()) {
- //get the name of the variable
- const char * c = it->GetName();
- std::string ss(c);
- if(!(0 == strncmp(ss.c_str(),"ini_",4)))
- continue;
- reverse(ss.begin(),ss.end());
-
- //cout << "debugging: " << ss;
- size_t pos = ss.find('_',0);
- if(!(0 < pos && pos < ss.size()))
- continue;
-
- //get the associated length
- std::string sss = ss.substr(0,pos);
- reverse(sss.begin(),sss.end());
- int n = atoi(sss.c_str());
-
- it->PL_Print(cout,2);
- for(int j=0;j < n; j++) {
- ASTNode index = CreateBVConst(it->GetIndexWidth(),j);
- ASTNode readexpr = CreateTerm(READ,it->GetValueWidth(),*it,index);
- ASTNode val = GetCounterExample(t, readexpr);
- //cout << "ASSERT( ";
- //cout << " = ";
- out_int.push_back(GetUnsignedConst(val));
- //cout << "\n";
- }
- }
- }
- cout << endl;
- for(unsigned int jj=0; jj < out_int.size();jj++)
- cout << out_int[jj] << endl;
- cout << endl;
- } //End of PrintCounterExample_InOrder
-
- /* FUNCTION: queries the CounterExampleMap object with 'expr' and
- * returns the corresponding counterexample value.
- */
- ASTNode BeevMgr::GetCounterExample(bool t, const ASTNode& expr) {
- //input is valid, no counterexample to get
- if(ValidFlag)
- return ASTUndefined;
-
- if(BOOLEAN_TYPE == expr.GetType()) {
- return ComputeFormulaUsingModel(expr);
- }
-
- if(BVCONST == expr.GetKind()) {
- return expr;
- }
-
- ASTNodeMap::iterator it;
- ASTNode output;
- if((it = CounterExampleMap.find(expr)) != CounterExampleMap.end())
- output = TermToConstTermUsingModel(CounterExampleMap[expr],false);
- else
- output = CreateZeroConst(expr.GetValueWidth());
- return output;
- } //End of GetCounterExample
-
- // FIXME: Don't use numeric codes. Use an enum type!
- //Acceps a query, calls the SAT solver and generates Valid/InValid.
- //if returned 0 then input is INVALID
- //if returned 1 then input is VALID
- //if returned 2 then ERROR
- int BeevMgr::TopLevelSAT( const ASTNode& inputasserts, const ASTNode& query) {
- /******start solving**********/
- ASTNode q = CreateNode(AND, inputasserts, CreateNode(NOT,query));
- 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);
- //ASTNodeStats("after pure substitution: ", newq);
- newq = SimplifyFormula_TopLevel(newq,false);
- //ASTNodeStats("after simplification: ", newq);
- //newq = bvsolver.TopLevelBVSolve(newq);
- //ASTNodeStats("after solving: ", newq);
- }while(q!=newq);
-
- ASTNodeStats("Before SimplifyWrites_Inplace begins: ", newq);
- SimplifyWrites_InPlace_Flag = true;
- Begin_RemoveWrites = false;
- start_abstracting = false;
- TermsAlreadySeenMap.clear();
- do {
- q = newq;
- //newq = CreateSubstitutionMap(newq);
- //ASTNodeStats("after pure substitution: ", newq);
- newq = SimplifyFormula_TopLevel(newq,false);
- //ASTNodeStats("after simplification: ", newq);
- newq = bvsolver.TopLevelBVSolve(newq);
- //ASTNodeStats("after solving: ", newq);
- }while(q!=newq);
- ASTNodeStats("After SimplifyWrites_Inplace: ", newq);
-
- start_abstracting = (arraywrite_refinement) ? true : false;
- SimplifyWrites_InPlace_Flag = false;
- Begin_RemoveWrites = (start_abstracting) ? false : true;
- if(start_abstracting) {
- ASTNodeStats("before abstraction round begins: ", newq);
- }
-
- TermsAlreadySeenMap.clear();
- do {
- q = newq;
- //newq = CreateSubstitutionMap(newq);
- //Begin_RemoveWrites = true;
- //ASTNodeStats("after pure substitution: ", newq);
- newq = SimplifyFormula_TopLevel(newq,false);
- //ASTNodeStats("after simplification: ", newq);
- //newq = bvsolver.TopLevelBVSolve(newq);
- //ASTNodeStats("after solving: ", newq);
- }while(q!=newq);
-
- if(start_abstracting) {
- ASTNodeStats("After abstraction: ", newq);
- }
- start_abstracting = false;
- SimplifyWrites_InPlace_Flag = false;
- Begin_RemoveWrites = false;
-
- newq = TransformFormula(newq);
- ASTNodeStats("after transformation: ", newq);
- TermsAlreadySeenMap.clear();
-
- int res;
- //solver instantiated here
- MINISAT::Solver newS;
- if(arrayread_refinement) {
- counterexample_checking_during_refinement = true;
- }
-
- //call SAT and check the result
- res = CallSAT_ResultCheck(newS,newq,orig_input);
- if(2 != res) {
- CountersAndStats("print_func_stats");
- return res;
- }
-
- res = SATBased_ArrayReadRefinement(newS,newq,orig_input);
- if(2 != res) {
- CountersAndStats("print_func_stats");
- return res;
- }
-
- res = SATBased_ArrayWriteRefinement(newS,orig_input);
- if(2 != res) {
- CountersAndStats("print_func_stats");
- return res;
- }
-
- res = SATBased_ArrayReadRefinement(newS,newq,orig_input);
- if(2 != res) {
- CountersAndStats("print_func_stats");
- return res;
- }
-
- FatalError("TopLevelSAT: reached the end without proper conclusion:"
- "either a divide by zero in the input or a bug in STP");
- //bogus return to make the compiler shut up
- return 2;
- } //End of TopLevelSAT
-
- //go over the list of indices for each array, and generate Leibnitz
- //axioms. Then assert these axioms into the SAT solver. Check if the
- //addition of the new constraints has made the bogus counterexample
- //go away. if yes, return the correct answer. if no, continue adding
- //Leibnitz axioms systematically.
- // FIXME: What it really does is, for each array, loop over each index i.
- // inside that loop, it finds all the true and false axioms with i as first
- // index. When it's got them all, it adds the false axioms to the formula
- // and re-solves, and returns if the result is correct. Otherwise, it
- // goes on to the next index.
- // If it gets through all the indices without a correct result (which I think
- // is impossible, but this is pretty confusing), it then solves with all
- // the true axioms, too.
- // This is not the most obvious way to do it, and I don't know how it
- // compares with other approaches (e.g., one false axiom at a time or
- // all the false axioms each time).
- int BeevMgr::SATBased_ArrayReadRefinement(MINISAT::Solver& newS,
- const ASTNode& q, const ASTNode& orig_input) {
- if(!arrayread_refinement)
- FatalError("SATBased_ArrayReadRefinement: Control should not reach here");
-
- ASTVec FalseAxiomsVec, RemainingAxiomsVec;
- RemainingAxiomsVec.push_back(ASTTrue);
- FalseAxiomsVec.push_back(ASTTrue);
-
- //in these loops we try to construct Leibnitz axioms and add it to
- //the solve(). We add only those axioms that are false in the
- //current counterexample. we keep adding the axioms until there
- //are no more axioms to add
- //
- //for each array, fetch its list of indices seen so far
- for(ASTNodeToVecMap::iterator iset = _arrayname_readindices.begin(), iset_end = _arrayname_readindices.end();
- iset!=iset_end;iset++) {
- ASTVec listOfIndices = iset->second;
- //loop over the list of indices for the array and create LA, and add to q
- for(ASTVec::iterator it=listOfIndices.begin(),itend=listOfIndices.end();it!=itend;it++) {
- if(BVCONST == it->GetKind()) {
- continue;
- }
-
- ASTNode the_index = *it;
- //get the arrayname
- ASTNode ArrName = iset->first;
- // if(SYMBOL != ArrName.GetKind())
- // FatalError("SATBased_ArrayReadRefinement: arrname is not a SYMBOL",ArrName);
- ASTNode arr_read1 = CreateTerm(READ, ArrName.GetValueWidth(), ArrName, the_index);
- //get the variable corresponding to the array_read1
- ASTNode arrsym1 = _arrayread_symbol[arr_read1];
- if(!(SYMBOL == arrsym1.GetKind() || BVCONST == arrsym1.GetKind()))
- FatalError("TopLevelSAT: refinementloop:term arrsym1 corresponding to READ must be a var", arrsym1);
-
- //we have nonconst index here. create Leibnitz axiom for it
- //w.r.t every index in listOfIndices
- for(ASTVec::iterator it1=listOfIndices.begin(),itend1=listOfIndices.end();
- it1!=itend1;it1++) {
- ASTNode compare_index = *it1;
- //do not compare with yourself
- if(the_index == compare_index)
- continue;
-
- //prepare for SAT LOOP
- //first construct the antecedent for the LA axiom
- ASTNode eqOfIndices =
- (exprless(the_index,compare_index)) ?
- CreateSimplifiedEQ(the_index,compare_index) : CreateSimplifiedEQ(compare_index,the_index);
-
- ASTNode arr_read2 = CreateTerm(READ, ArrName.GetValueWidth(), ArrName, compare_index);
- //get the variable corresponding to the array_read2
- ASTNode arrsym2 = _arrayread_symbol[arr_read2];
- if(!(SYMBOL == arrsym2.GetKind() || BVCONST == arrsym2.GetKind()))
- FatalError("TopLevelSAT: refinement loop:"
- "term arrsym2 corresponding to READ must be a var", arrsym2);
-
- ASTNode eqOfReads = CreateSimplifiedEQ(arrsym1,arrsym2);
- //construct appropriate Leibnitz axiom
- ASTNode LeibnitzAxiom = CreateNode(IMPLIES, eqOfIndices, eqOfReads);
- if(ASTFalse == ComputeFormulaUsingModel(LeibnitzAxiom))
- //FalseAxioms = CreateNode(AND,FalseAxioms,LeibnitzAxiom);
- FalseAxiomsVec.push_back(LeibnitzAxiom);
- else
- //RemainingAxioms = CreateNode(AND,RemainingAxioms,LeibnitzAxiom);
- RemainingAxiomsVec.push_back(LeibnitzAxiom);
- }
- ASTNode FalseAxioms = (FalseAxiomsVec.size()>1) ? CreateNode(AND,FalseAxiomsVec) : FalseAxiomsVec[0];
- ASTNodeStats("adding false readaxioms to SAT: ", FalseAxioms);
- int res2 = CallSAT_ResultCheck(newS,FalseAxioms,orig_input);
- if(2!=res2) {
- return res2;
- }
- }
- }
- ASTNode RemainingAxioms = (RemainingAxiomsVec.size()>1) ? CreateNode(AND,RemainingAxiomsVec):RemainingAxiomsVec[0];
- ASTNodeStats("adding remaining readaxioms to SAT: ", RemainingAxioms);
- return CallSAT_ResultCheck(newS,RemainingAxioms,orig_input);
- } //end of SATBased_ArrayReadRefinement
-
- ASTNode BeevMgr::Create_ArrayWriteAxioms(const ASTNode& term, const ASTNode& newvar) {
- if(READ != term.GetKind() && WRITE != term[0].GetKind()) {
- FatalError("Create_ArrayWriteAxioms: Input must be a READ over a WRITE",term);
- }
-
- ASTNode lhs = newvar;
- ASTNode rhs = term;
- ASTNode arraywrite_axiom = CreateSimplifiedEQ(lhs,rhs);
- return arraywrite_axiom;
- }//end of Create_ArrayWriteAxioms()
-
- int BeevMgr::SATBased_ArrayWriteRefinement(MINISAT::Solver& newS, const ASTNode& orig_input) {
- ASTNode writeAxiom;
- ASTNodeMap::iterator it = ReadOverWrite_NewName_Map.begin();
- ASTNodeMap::iterator itend = ReadOverWrite_NewName_Map.end();
- //int count = 0;
- //int num_write_axioms = ReadOverWrite_NewName_Map.size();
-
- ASTVec FalseAxioms, RemainingAxioms;
- FalseAxioms.push_back(ASTTrue);
- RemainingAxioms.push_back(ASTTrue);
- for(;it!=itend;it++) {
- //Guided refinement starts here
- ComputeFormulaMap.clear();
- writeAxiom = Create_ArrayWriteAxioms(it->first,it->second);
- if(ASTFalse == ComputeFormulaUsingModel(writeAxiom)) {
- writeAxiom = TransformFormula(writeAxiom);
- FalseAxioms.push_back(writeAxiom);
- }
- else {
- writeAxiom = TransformFormula(writeAxiom);
- RemainingAxioms.push_back(writeAxiom);
- }
- }
-
- writeAxiom = (FalseAxioms.size() != 1) ? CreateNode(AND,FalseAxioms) : FalseAxioms[0];
- ASTNodeStats("adding false writeaxiom to SAT: ", writeAxiom);
- int res2 = 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
-
- //Check result after calling SAT FIXME: Document arguments in
- //comments, and give them meaningful names. How is anyone supposed
- //to know what "q" is?
- int BeevMgr::CallSAT_ResultCheck(MINISAT::Solver& newS,
- const ASTNode& q, const ASTNode& orig_input) {
- //Bitblast, CNF, call SAT now
- ASTNode BBFormula = BBForm(q);
- //ASTNodeStats("after bitblasting", BBFormula);
- ClauseList *cllp = ToCNF(BBFormula);
- // if(stats && print_nodes) {
- // cout << "\nClause list" << endl;
- // PrintClauseList(cout, *cllp);
- // cerr << "\n finished printing clauselist\n";
- // }
-
- bool sat = toSATandSolve(newS,*cllp);
- // Temporary debugging call.
- // CheckBBandCNF(newS, BBFormula);
-
- DeleteClauseList(cllp);
- if(!sat) {
- PrintOutput(true);
- return 1;
- }
- else if(newS.okay()) {
- CounterExampleMap.clear();
- ConstructCounterExample(newS);
- if (stats && print_nodes) {
- PrintSATModel(newS);
- }
- //check if the counterexample is good or not
- ComputeFormulaMap.clear();
- if(counterexample_checking_during_refinement)
- bvdiv_exception_occured = false;
- ASTNode orig_result = ComputeFormulaUsingModel(orig_input);
- if(!(ASTTrue == orig_result || ASTFalse == orig_result))
- FatalError("TopLevelSat: Original input must compute to true or false against model");
-
-// if(!arrayread_refinement && !(ASTTrue == orig_result)) {
-// print_counterexample = true;
-// PrintCounterExample(true);
-// FatalError("counterexample bogus : arrayread_refinement is switched off: "
-// "EITHER all LA axioms have not been added OR bitblaster() or ToCNF()"
-// "or satsolver() or counterexamplechecker() have a bug");
-// }
-
- // if the counterexample is indeed a good one, then return
- // invalid
- if(ASTTrue == orig_result) {
- CheckCounterExample(newS.okay());
- PrintOutput(false);
- PrintCounterExample(newS.okay());
- PrintCounterExample_InOrder(newS.okay());
- return 0;
- }
- // counterexample is bogus: flag it
- else {
- if(stats && print_nodes) {
- cout << "Supposedly bogus one: \n";
- bool tmp = print_counterexample;
- print_counterexample = true;
- PrintCounterExample(true);
- print_counterexample = tmp;
- }
-
- return 2;
- }
- }
- else {
- PrintOutput(true);
- return -100;
- }
- } //end of CALLSAT_ResultCheck
-
-
- //FUNCTION: this function accepts a boolvector and returns a BVConst
- ASTNode BeevMgr::BoolVectoBVConst(hash_map<unsigned,bool> * w, unsigned int l) {
- unsigned len = w->size();
- if(l < len)
- FatalError("BoolVectorBVConst : length of bitvector does not match hash_map size:",ASTUndefined,l);
- std::string cc;
- for(unsigned int jj = 0; jj < l; jj++) {
- if((*w)[jj] == true)
- cc += '1';
- else if((*w)[jj] == false)
- cc += '0';
- else
- cc += '0';
- }
- return CreateBVConst(cc.c_str(),2);
- }
-
- void BeevMgr::PrintActivityLevels_Of_SATVars(char * init_msg, MINISAT::Solver& newS) {
- if(!print_sat_varorder)
- return;
-
- ASTtoSATMap::iterator itbegin = _ASTNode_to_SATVar.begin();
- ASTtoSATMap::iterator itend = _ASTNode_to_SATVar.end();
-
- cout << init_msg;
- cout << ": Printing activity levels of variables\n";
- for(ASTtoSATMap::iterator it=itbegin;it!=itend;it++){
- cout << (it->second) << " : ";
- (it->first).PL_Print(cout,0);
- cout << " : ";
- cout << newS.returnActivity(it->second) << endl;
- }
- }
-
- //this function biases the activity levels of MINISAT variables.
- void BeevMgr::ChangeActivityLevels_Of_SATVars(MINISAT::Solver& newS) {
- if(!variable_activity_optimize)
- return;
-
- ASTtoSATMap::iterator itbegin = _ASTNode_to_SATVar.begin();
- ASTtoSATMap::iterator itend = _ASTNode_to_SATVar.end();
-
- unsigned int index=1;
- double base = 2;
- for(ASTtoSATMap::iterator it=itbegin;it!=itend;it++){
- ASTNode n = it->first;
-
- if(BVGETBIT == n.GetKind() || NOT == n.GetKind()) {
- if(BVGETBIT == n.GetKind())
- index = GetUnsignedConst(n[1]);
- else if (NOT == n.GetKind() && BVGETBIT == n[0].GetKind())
- index = GetUnsignedConst(n[0][1]);
- else
- index = 0;
- double initial_activity = pow(base,(double)index);
- newS.updateInitialActivity(it->second,initial_activity);
- }
- else {
- double initial_activity = pow(base,pow(base,(double)index));
- newS.updateInitialActivity(it->second,initial_activity);
- }
- }
- }
-
- //This function prints the output of the STP solver
- void BeevMgr::PrintOutput(bool true_iff_valid) {
- //self-explanatory
- if(true_iff_valid) {
- ValidFlag = true;
- if(print_output) {
- if(smtlib_parser_enable)
- cout << "unsat\n";
- else
- cout << "Valid.\n";
- }
- }
- else {
- ValidFlag = false;
- if(print_output) {
- if(smtlib_parser_enable)
- cout << "sat\n";
- else
- cout << "Invalid.\n";
- }
- }
- }
-} //end of namespace BEEV
diff --git a/stp/AST/Transform.cpp b/stp/AST/Transform.cpp
deleted file mode 100644
index 598b831e..00000000
--- a/stp/AST/Transform.cpp
+++ /dev/null
@@ -1,492 +0,0 @@
-/********************************************************************
- * AUTHORS: Vijay Ganesh, David L. Dill
- *
- * BEGIN DATE: November, 2005
- *
- * LICENSE: Please view LICENSE file in the home dir of this Program
- ********************************************************************/
-// -*- c++ -*-
-
-#include "AST.h"
-#include <stdlib.h>
-#include <stdio.h>
-namespace BEEV {
-
- //Translates signed BVDIV/BVMOD into unsigned variety
- ASTNode BeevMgr::TranslateSignedDivMod(const ASTNode& in) {
- if(!(SBVMOD == in.GetKind() || SBVDIV == in.GetKind())) {
- FatalError("TranslateSignedDivMod: input must be signed DIV/MOD\n",in);
- }
-
- ASTNode dividend = in[0];
- ASTNode divisor = in[1];
- unsigned len = in.GetValueWidth();
- if(SBVMOD == in.GetKind()) {
- //if(TopBit(dividend)==1)
- //
- //then -BVMOD(-dividend,abs(divisor))
- //
- //else BVMOD(dividend,abs(divisor))
-
- //create the condition for the dividend
- ASTNode hi1 = CreateBVConst(32,len-1);
- ASTNode one = CreateOneConst(1);
- ASTNode cond = CreateNode(EQ,one,CreateTerm(BVEXTRACT,1,dividend,hi1,hi1));
-
- //create the condition and conditional for the divisor
- ASTNode cond_divisor = CreateNode(EQ,one,CreateTerm(BVEXTRACT,1,divisor,hi1,hi1));
- ASTNode pos_divisor = CreateTerm(ITE,len,cond_divisor,CreateTerm(BVUMINUS,len,divisor),divisor);
-
- //create the modulus term for each case
- ASTNode modnode = CreateTerm(BVMOD,len,dividend,pos_divisor);
- ASTNode minus_modnode = CreateTerm(BVMOD,len,CreateTerm(BVUMINUS,len,dividend),pos_divisor);
- minus_modnode = CreateTerm(BVUMINUS,len,minus_modnode);
-
- //put everything together, simplify, and return
- ASTNode n = CreateTerm(ITE,len,cond,minus_modnode,modnode);
- return SimplifyTerm_TopLevel(n);
- }
-
- //now handle the BVDIV case
- //if topBit(dividend) is 1 and topBit(divisor) is 0
- //
- //then output is -BVDIV(-dividend,divisor)
- //
- //elseif topBit(dividend) is 0 and topBit(divisor) is 1
- //
- //then output is -BVDIV(dividend,-divisor)
- //
- //elseif topBit(dividend) is 1 and topBit(divisor) is 1
- //
- // then output is BVDIV(-dividend,-divisor)
- //
- //else simply output BVDIV(dividend,divisor)
- ASTNode hi1 = CreateBVConst(32,len-1);
- ASTNode zero = CreateZeroConst(1);
- ASTNode one = CreateOneConst(1);
- ASTNode divnode = CreateTerm(BVDIV, len, dividend, divisor);
-
- ASTNode cond1 = CreateNode(AND,
- CreateNode(EQ,zero,CreateTerm(BVEXTRACT,1,dividend,hi1,hi1)),
- CreateNode(EQ,one, CreateTerm(BVEXTRACT,1,divisor,hi1,hi1)));
- ASTNode minus_divnode1 = CreateTerm(BVDIV,len,
- dividend,
- CreateTerm(BVUMINUS,len,divisor));
- minus_divnode1 = CreateTerm(BVUMINUS,len,minus_divnode1);
-
- ASTNode cond2 = CreateNode(AND,
- CreateNode(EQ,one,CreateTerm(BVEXTRACT,1,dividend,hi1,hi1)),
- CreateNode(EQ,zero,CreateTerm(BVEXTRACT,1,divisor,hi1,hi1)));
- ASTNode minus_divnode2 = CreateTerm(BVDIV,len,
- CreateTerm(BVUMINUS,len,dividend),
- divisor);
- minus_divnode2 = CreateTerm(BVUMINUS,len,minus_divnode2);
-
- ASTNode cond3 = CreateNode(AND,
- CreateNode(EQ,one,CreateTerm(BVEXTRACT,1,dividend,hi1,hi1)),
- CreateNode(EQ,one,CreateTerm(BVEXTRACT,1,divisor,hi1,hi1)));
- ASTNode minus_divnode3 = CreateTerm(BVDIV,len,
- CreateTerm(BVUMINUS,len,dividend),
- CreateTerm(BVUMINUS,len,divisor));
- ASTNode n = CreateTerm(ITE,len,
- cond1,
- minus_divnode1,
- CreateTerm(ITE,len,
- cond2,
- minus_divnode2,
- CreateTerm(ITE,len,
- cond3,
- minus_divnode3,
- divnode)));
- return SimplifyTerm_TopLevel(n);
- }//end of TranslateSignedDivMod()
-
- ASTNode BeevMgr::TransformFormula(const ASTNode& form) {
- ASTNode result;
-
- ASTNode simpleForm = form;
- Kind k = simpleForm.GetKind();
- if(!(is_Form_kind(k) && BOOLEAN_TYPE == simpleForm.GetType())) {
- //FIXME: "You have inputted a NON-formula"?
- FatalError("TransformFormula: You have input a NON-formula",simpleForm);
- }
-
- ASTNodeMap::iterator iter;
- if((iter = TransformMap.find(simpleForm)) != TransformMap.end())
- return iter->second;
-
- switch(k) {
- case TRUE:
- case FALSE: {
- result = simpleForm;
- break;
- }
- case NOT: {
- ASTVec c;
- c.push_back(TransformFormula(simpleForm[0]));
- result = CreateNode(NOT,c);
- break;
- }
- case BVLT:
- case BVLE:
- case BVGT:
- case BVGE:
- case BVSLT:
- case BVSLE:
- case BVSGT:
- case BVSGE:
- case NEQ: {
- ASTVec c;
- c.push_back(TransformTerm(simpleForm[0]));
- c.push_back(TransformTerm(simpleForm[1]));
- result = CreateNode(k,c);
- break;
- }
- case EQ: {
- ASTNode term1 = TransformTerm(simpleForm[0]);
- ASTNode term2 = TransformTerm(simpleForm[1]);
- result = CreateSimplifiedEQ(term1,term2);
- break;
- }
- case AND:
- case OR:
- case NAND:
- case NOR:
- case IFF:
- case XOR:
- case ITE:
- case IMPLIES: {
- ASTVec vec;
- ASTNode o;
- for (ASTVec::const_iterator it = simpleForm.begin(),itend=simpleForm.end(); it != itend; it++){
- o = TransformFormula(*it);
- vec.push_back(o);
- }
-
- result = CreateNode(k, vec);
- break;
- }
- default:
- if(k == SYMBOL && BOOLEAN_TYPE == simpleForm.GetType())
- result = simpleForm;
- else {
- cerr << "The input is: " << simpleForm << endl;
- cerr << "The valuewidth of input is : " << simpleForm.GetValueWidth() << endl;
- FatalError("TransformFormula: Illegal kind: ",ASTUndefined, k);
- }
- break;
- }
- //BVTypeCheck(result);
- TransformMap[simpleForm] = result;
- return result;
- } //End of TransformFormula
-
- ASTNode BeevMgr::TransformTerm(const ASTNode& inputterm) {
- ASTNode result;
- ASTNode term = inputterm;
-
- Kind k = term.GetKind();
- if(!is_Term_kind(k))
- FatalError("TransformTerm: Illegal kind: You have input a nonterm:", inputterm, k);
- ASTNodeMap::iterator iter;
- if((iter = TransformMap.find(term)) != TransformMap.end())
- return iter->second;
- switch(k) {
- case SYMBOL: {
- // ASTNodeMap::iterator itsym;
-// if((itsym = CounterExampleMap.find(term)) != CounterExampleMap.end())
-// result = itsym->second;
-// else
- result = term;
- break;
- }
- case BVCONST:
- result = term;
- break;
- case WRITE:
- FatalError("TransformTerm: this kind is not supported",term);
- break;
- case READ:
- result = TransformArray(term);
- break;
- case ITE: {
- ASTNode cond = term[0];
- ASTNode thn = term[1];
- ASTNode els = term[2];
- cond = TransformFormula(cond);
- thn = TransformTerm(thn);
- els = TransformTerm(els);
- //result = CreateTerm(ITE,term.GetValueWidth(),cond,thn,els);
- result = CreateSimplifiedTermITE(cond,thn,els);
- result.SetIndexWidth(term.GetIndexWidth());
- break;
- }
- default: {
- ASTVec c = term.GetChildren();
- ASTVec::iterator it = c.begin();
- ASTVec::iterator itend = c.end();
- unsigned width = term.GetValueWidth();
- unsigned indexwidth = term.GetIndexWidth();
- ASTVec o;
- for(;it!=itend;it++) {
- o.push_back(TransformTerm(*it));
- }
-
- result = CreateTerm(k,width,o);
- result.SetIndexWidth(indexwidth);
-
- if(SBVDIV == result.GetKind() || SBVMOD == result.GetKind()) {
- result = TranslateSignedDivMod(result);
- }
- break;
- }
- }
-
- TransformMap[term] = result;
- if(term.GetValueWidth() != result.GetValueWidth())
- FatalError("TransformTerm: result and input terms are of different length", result);
- if(term.GetIndexWidth() != result.GetIndexWidth()) {
- cerr << "TransformTerm: input term is : " << term << endl;
- FatalError("TransformTerm: result and input terms have different index length", result);
- }
- return result;
- } //End of TransformTerm
-
- /* This function transforms Array Reads, Read over Writes, Read over
- * ITEs into flattened form.
- *
- * Transform1: Suppose there are two array reads in the input
- * Read(A,i) and Read(A,j) over the same array. Then Read(A,i) is
- * replaced with a symbolic constant, say v1, and Read(A,j) is
- * replaced with the following ITE:
- *
- * ITE(i=j,v1,v2)
- *
- * Transform2:
- *
- * Transform3:
- */
- ASTNode BeevMgr::TransformArray(const ASTNode& term) {
- ASTNode result = term;
-
- unsigned int width = term.GetValueWidth();
- Kind k = term.GetKind();
- if (!is_Term_kind(k))
- FatalError("TransformArray: Illegal kind: You have input a nonterm:", ASTUndefined, k);
- ASTNodeMap::iterator iter;
- if((iter = TransformMap.find(term)) != TransformMap.end())
- return iter->second;
-
- switch(k) {
- //'term' is of the form READ(arrName, readIndex)
- case READ: {
- ASTNode arrName = term[0];
- switch (arrName.GetKind()) {
- case SYMBOL: {
- /* input is of the form: READ(A, readIndex)
- *
- * output is of the from: A1, if this is the first READ over A
- *
- * ITE(previous_readIndex=readIndex,A1,A2)
- *
- * .....
- */
-
- // Recursively transform read index, which may also contain reads.
- ASTNode readIndex = TransformTerm(term[1]);
- ASTNode processedTerm = CreateTerm(READ,width,arrName,readIndex);
-
- //check if the 'processedTerm' has a corresponding ITE construct
- //already. if so, return it. else continue processing.
- ASTNodeMap::iterator it;
- if((it = _arrayread_ite.find(processedTerm)) != _arrayread_ite.end()) {
- result = it->second;
- break;
- }
- //Constructing Symbolic variable corresponding to 'processedTerm'
- ASTNode CurrentSymbol;
- ASTNodeMap::iterator it1;
- // First, check if read index is constant and it has a constant value in the substitution map.
- if(CheckSubstitutionMap(processedTerm,CurrentSymbol)) {
- _arrayread_symbol[processedTerm] = CurrentSymbol;
- }
- // Check if it already has an abstract variable.
- else if((it1 = _arrayread_symbol.find(processedTerm)) != _arrayread_symbol.end()) {
- CurrentSymbol = it1->second;
- }
- else {
- // Make up a new abstract variable.
- // FIXME: Make this into a method (there already may BE a method) and
- // get rid of the fixed-length buffer!
- //build symbolic name corresponding to array read. The symbolic
- //name has 2 components: stringname, and a count
- const char * b = arrName.GetName();
- std::string c(b);
- char d[32];
- sprintf(d,"%d",_symbol_count++);
- std::string ccc(d);
- c += "array_" + ccc;
-
- CurrentSymbol = CreateSymbol(c.c_str());
- CurrentSymbol.SetValueWidth(processedTerm.GetValueWidth());
- CurrentSymbol.SetIndexWidth(processedTerm.GetIndexWidth());
- _arrayread_symbol[processedTerm] = CurrentSymbol;
- }
-
- //list of array-read indices corresponding to arrName, seen while
- //traversing the AST tree. we need this list to construct the ITEs
- // Dill: we hope to make this irrelevant. Harmless for now.
- ASTVec readIndices = _arrayname_readindices[arrName];
-
- //construct the ITE structure for this array-read
- ASTNode ite = CurrentSymbol;
- _introduced_symbols.insert(CurrentSymbol);
- BVTypeCheck(ite);
-
- if(arrayread_refinement) {
- // ite is really a variable here; it is an ite in the
- // else-branch
- result = ite;
- }
- else {
- // Full Seshia transform if we're not doing read refinement.
- //do not loop if the current readIndex is a BVCONST
- // if(BVCONST == term[1].GetKind() && !SeenNonConstReadIndex && optimize) {
- // result = ite;
- // }
- // else {
- //else part: SET the SeenNonConstReadIndex var, and do the hard work
- //SeenNonConstReadIndex = true;
- ASTVec::reverse_iterator it2=readIndices.rbegin();
- ASTVec::reverse_iterator it2end=readIndices.rend();
- for(;it2!=it2end;it2++) {
- ASTNode cond = CreateSimplifiedEQ(readIndex,*it2);
- if(ASTFalse == cond)
- continue;
-
- ASTNode arrRead = CreateTerm(READ,width,arrName,*it2);
- //Good idea to TypeCheck internally constructed nodes
- BVTypeCheck(arrRead);
-
- ASTNode arrayreadSymbol = _arrayread_symbol[arrRead];
- if(arrayreadSymbol.IsNull())
- FatalError("TransformArray:symbolic variable for processedTerm, p,"
- "does not exist:p = ",arrRead);
- ite = CreateSimplifiedTermITE(cond,arrayreadSymbol,ite);
- }
- result = ite;
- //}
- }
-
- _arrayname_readindices[arrName].push_back(readIndex);
- //save the ite corresponding to 'processedTerm'
- _arrayread_ite[processedTerm] = result;
- break;
- } //end of READ over a SYMBOL
- case WRITE:{
- /* The input to this case is: READ((WRITE A i val) j)
- *
- * The output of this case is: ITE( (= i j) val (READ A i))
- */
-
- /* 1. arrName or term[0] is infact a WRITE(A,i,val) expression
- *
- * 2. term[1] is the read-index j
- *
- * 3. arrName[0] is the new arrName i.e. A. A can be either a
- SYMBOL or a nested WRITE. no other possibility
- *
- * 4. arrName[1] is the WRITE index i.e. i
- *
- * 5. arrName[2] is the WRITE value i.e. val (val can inturn
- * be an array read)
- */
- ASTNode readIndex = TransformTerm(term[1]);
- ASTNode writeIndex = TransformTerm(arrName[1]);
- ASTNode writeVal = TransformTerm(arrName[2]);
-
- if(!(SYMBOL == arrName[0].GetKind() ||
- WRITE == arrName[0].GetKind()))
- FatalError("TransformArray: An array write is being attempted on a non-array:",term);
- if(ARRAY_TYPE != arrName[0].GetType())
- FatalError("TransformArray: An array write is being attempted on a non-array:",term);
-
- ASTNode cond = CreateSimplifiedEQ(writeIndex,readIndex);
- //TypeCheck internally created node
- BVTypeCheck(cond);
- ASTNode readTerm = CreateTerm(READ,width,arrName[0],readIndex);
- //TypeCheck internally created node
- BVTypeCheck(readTerm);
- ASTNode readPushedIn = TransformArray(readTerm);
- //TypeCheck internally created node
- BVTypeCheck(readPushedIn);
- //result = CreateTerm(ITE, arrName[0].GetValueWidth(),cond,writeVal,readPushedIn);
- result = CreateSimplifiedTermITE(cond,writeVal,readPushedIn);
-
- //Good idea to typecheck terms created inside the system
- BVTypeCheck(result);
- break;
- } //end of READ over a WRITE
- case ITE: {
- /* READ((ITE cond thn els) j)
- *
- * is transformed into
- *
- * (ITE cond (READ thn j) (READ els j))
- */
-
- //(ITE cond thn els)
- ASTNode term0 = term[0];
- //READINDEX j
- ASTNode j = TransformTerm(term[1]);
-
- ASTNode cond = term0[0];
- //first array
- ASTNode t01 = term0[1];
- //second array
- ASTNode t02 = term0[2];
-
- cond = TransformFormula(cond);
- ASTNode thn = TransformTerm(t01);
- ASTNode els = TransformTerm(t02);
-
- if(!(t01.GetValueWidth() == t02.GetValueWidth() &&
- t01.GetValueWidth() == thn.GetValueWidth() &&
- t01.GetValueWidth() == els.GetValueWidth()))
- FatalError("TransformArray: length of THENbranch != length of ELSEbranch in the term t = \n",term);
-
- if(!(t01.GetIndexWidth() == t02.GetIndexWidth() &&
- t01.GetIndexWidth() == thn.GetIndexWidth() &&
- t01.GetIndexWidth() == els.GetIndexWidth()))
- FatalError("TransformArray: length of THENbranch != length of ELSEbranch in the term t = \n",term);
-
- //(READ thn j)
- ASTNode thnRead = CreateTerm(READ,width,thn,j);
- BVTypeCheck(thnRead);
- thnRead = TransformArray(thnRead);
-
- //(READ els j)
- ASTNode elsRead = CreateTerm(READ,width,els,j);
- BVTypeCheck(elsRead);
- elsRead = TransformArray(elsRead);
-
- //(ITE cond (READ thn j) (READ els j))
- result = CreateSimplifiedTermITE(cond,thnRead,elsRead);
- BVTypeCheck(result);
- break;
- }
- default:
- FatalError("TransformArray: The READ is NOT over SYMBOL/WRITE/ITE",term);
- break;
- }
- break;
- } //end of READ switch
- default:
- FatalError("TransformArray: input term is of wrong kind: ",ASTUndefined);
- break;
- }
-
- TransformMap[term] = result;
- return result;
- } //end of TransformArray()
-} //end of namespace BEEV
diff --git a/stp/AST/genkinds.pl b/stp/AST/genkinds.pl
deleted file mode 100755
index 672481ad..00000000
--- a/stp/AST/genkinds.pl
+++ /dev/null
@@ -1,123 +0,0 @@
-#!/usr/bin/perl -w
-
-#AUTHORS: Vijay Ganesh, David L. Dill BEGIN DATE: November, 2005
-#LICENSE: Please view LICENSE file in the home dir of this Program
-#given a file containing kind names, one per line produces .h and .cpp
-#files for the kinds.
-
-#globals
-@kindnames = ();
-$minkids = 0;
-$maxkids = 0;
-@cat_bits = ();
-@category_names = ();
-%cat_index = ();
-
-$now = localtime time;
-
-sub read_kind_defs {
- open(KFILE, "< ASTKind.kinds") || die "Cannot open .kinds file: $!\n";
- @kindlines = <KFILE>;
- close(KFILE)
-}
-
-# create lists of things indexed by kinds.
-sub split_fields {
- my $kind_cat_bits;
- # matches anything with three whitespace-delimited alphanumeric fields,
- # followed by rest of line. Automatically ignores lines beginning with '#' and blank lines.
- for (@kindlines) {
- if (/Categories:\s+(.*)/) {
- @category_names = split(/\s+/, $1);
- $i = 0;
- for (@category_names) {
- $cat_index{$_} = $i++;
- # print "cat_index{$_} = $i\n";
- }
- }
- elsif (/^(\w+)\s+(\w+)\s+(\w+|-)\s+(.*)/) {
- push(@kindnames, $1);
- push(@minkids, $2);
- push(@maxkids, $3);
- @kind_cats = split(/\s+/, $4);
- # build a bit vector of categories.
- $kind_cat_bits = 0;
- for (@kind_cats) {
- $kind_cat_bits |= (1 << int($cat_index{$_}));
- }
- push(@cat_bits, $kind_cat_bits);
- }
- }
-}
-
-sub gen_h_file {
- open(HFILE, "> ASTKind.h") || die "Cannot open .h file: $!\n";
-
- print HFILE
- "// -*- c++ -*-\n",
- "#ifndef TESTKINDS_H\n",
- "#define TESTKINDS_H\n",
- "// Generated automatically by genkinds.pl from ASTKind.kinds $now.\n",
- "// Do not edit\n",
- "namespace BEEV {\n typedef enum {\n";
-
- for (@kindnames) {
- print HFILE " $_,\n";
- }
-
- print HFILE
- "} Kind;\n\n",
- "extern unsigned char _kind_categories[];\n\n";
-
- # For category named "cat", generate functions "bool is_cat_kind(k);"
-
-
- for (@category_names) {
- my $catname = $_;
- my $kind_cat_bit = (1 << int($cat_index{$catname}));
- print HFILE "inline bool is_", $catname, "_kind(Kind k) { return (_kind_categories[k] & $kind_cat_bit); }\n\n"
- }
-
- print HFILE
- "extern const char *_kind_names[];\n\n",
- "/** Prints symbolic name of kind */\n",
- "inline ostream& operator<<(ostream &os, const Kind &kind) { os << _kind_names[kind]; return os; }\n",
- "\n\n",
- "} // end namespace\n",
- "\n\n#endif\n";
-
- close(HFILE);
-}
-
-# generate the .cpp file
-
-sub gen_cpp_file {
- open(CPPFILE, "> ASTKind.cpp") || die "Cannot open .h file: $!\n";
-
- print CPPFILE
- "// Generated automatically by genkinds.h from ASTKind.kinds $now.\n",
- "// Do not edit\n",
- "namespace BEEV {\n",
- "const char * _kind_names[] = {\n";
- for (@kindnames) {
- print CPPFILE " \"$_\",\n";
- }
- print CPPFILE "};\n\n";
-
- # category bits
- print CPPFILE
- "unsigned char _kind_categories[] = {\n";
- for (@cat_bits) {
- print CPPFILE " $_,\n";
- }
- print CPPFILE
- "};\n",
- "\n} // end namespace\n";
-
- close(CPPFILE);
-}
-
-&read_kind_defs;
-&split_fields;
-&gen_h_file;
-&gen_cpp_file;
diff --git a/stp/INSTALL b/stp/INSTALL
deleted file mode 100644
index 12cee121..00000000
--- a/stp/INSTALL
+++ /dev/null
@@ -1,10 +0,0 @@
-1. To install STP perform the following steps on your Unix/GNU-Linux/MacOS X commandline:
-
-./configure --with-prefix=$HOME (or another installation directory)
-make clean
-make
-make install
-
-2. To test the system after installation:
-
-make regressall \ No newline at end of file
diff --git a/stp/LICENSE b/stp/LICENSE
deleted file mode 100644
index 41029509..00000000
--- a/stp/LICENSE
+++ /dev/null
@@ -1,17 +0,0 @@
-/*****************************************************************************/
-/* AUTHORS: Vijay Ganesh, David L. Dill DATE: Nov 2005 */
-/*****************************************************************************/
-/* Copyright (C) 2005 by the Board of Trustees of Leland Stanford */
-/* Junior University. */
-/* */
-/* License to use, copy, modify, sell and/or distribute this software */
-/* and its documentation for any purpose is hereby granted without */
-/* royalty, subject to the terms and conditions defined in the \ref */
-/* LICENSE file provided with this distribution. In particular: */
-/* */
-/* - The above copyright notice and this permission notice must appear */
-/* in all copies of the software and related documentation. */
-/* */
-/* - THE SOFTWARE IS PROVIDED "AS-IS", WITHOUT ANY WARRANTIES, */
-/* EXPRESSED OR IMPLIED. USE IT AT YOUR OWN RISK. */
-/*****************************************************************************/
diff --git a/stp/Makefile b/stp/Makefile
deleted file mode 100644
index c863d5b4..00000000
--- a/stp/Makefile
+++ /dev/null
@@ -1,14 +0,0 @@
-#===-- stp/Makefile ----------------------------------------*- Makefile -*--===#
-#
-# The KLEE Symbolic Virtual Machine
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-#===------------------------------------------------------------------------===#
-
-LEVEL=..
-
-PARALLEL_DIRS := AST bitvec c_interface constantbv sat simplifier
-
-include $(LEVEL)/Makefile.common
diff --git a/stp/README b/stp/README
deleted file mode 100644
index da0f9b96..00000000
--- a/stp/README
+++ /dev/null
@@ -1,26 +0,0 @@
-/********************************************************************
- * PROGRAM NAME: STP (Simple Theorem Prover)
- *
- * AUTHORS: Vijay Ganesh, David L. Dill
- *
- * BEGIN DATE: November, 2005
- *
- * LICENSE: Please view LICENSE file in the home dir of this Program
- ********************************************************************/
-
-Install
--------
-See INSTALL file in the home dir of this program
-
-Authors
--------
-Vijay Ganesh, Stanford University, Stanford, CA, USA
-David L. Dill, Stanford University, Stanford, CA, USA
-Tim King, Stanford University, Stanford, CA, USA
-
-Makefiles and configuration scripts
-------------------------------------
-Cristian Cadar, Stanford University, Stanford, CA, USA
-Paul Twohey, Stanford University, Stanford, CA, USA
-Sergey Berezin, ATG Synopsys, Mountain View, CA, USA
-Clark Barrett, New York University, New York, NY, USA
diff --git a/stp/bitvec/Makefile b/stp/bitvec/Makefile
deleted file mode 100644
index 2652be1d..00000000
--- a/stp/bitvec/Makefile
+++ /dev/null
@@ -1,19 +0,0 @@
-#===-- stp/bitvec/Makefile ---------------------------------*- Makefile -*--===#
-#
-# The KLEE Symbolic Virtual Machine
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-#===------------------------------------------------------------------------===#
-
-LEVEL=../..
-
-LIBRARYNAME=stp_bitvec
-DONT_BUILD_RELINKED=1
-BUILD_ARCHIVE=1
-
-include $(LEVEL)/Makefile.common
-
-# HACK: Force -Wno-deprecated for ext container use.
-CXX.Flags += -Wno-deprecated
diff --git a/stp/bitvec/consteval.cpp b/stp/bitvec/consteval.cpp
deleted file mode 100644
index 8fa652cf..00000000
--- a/stp/bitvec/consteval.cpp
+++ /dev/null
@@ -1,1044 +0,0 @@
-/********************************************************************
- * AUTHORS: Vijay Ganesh, David L. Dill
- *
- * BEGIN DATE: November, 2005
- *
- * LICENSE: Please view LICENSE file in the home dir of this Program
- ********************************************************************/
-// -*- c++ -*-
-
-#include "../AST/AST.h"
-#include "../AST/ASTUtil.h"
-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);
- }
-
-#ifndef NATIVE_C_ARITH
- ASTNode BeevMgr::BVConstEvaluator(const ASTNode& t) {
- ASTNode OutputNode;
- Kind k = t.GetKind();
-
- if(CheckSolverMap(t,OutputNode))
- return OutputNode;
- OutputNode = t;
-
- unsigned int inputwidth = t.GetValueWidth();
- unsigned int outputwidth = inputwidth;
- CBV output = NULL;
-
- CBV tmp0 = NULL;
- CBV tmp1 = NULL;
-
- //saving some typing. BVPLUS does not use these variables. if the
- //input BVPLUS has two nodes, then we want to avoid setting these
- //variables.
- if(1 == t.Degree() ){
- tmp0 = BVConstEvaluator(t[0]).GetBVConst();
- }else if(2 == t.Degree() && k != BVPLUS ) {
- tmp0 = BVConstEvaluator(t[0]).GetBVConst();
- tmp1 = BVConstEvaluator(t[1]).GetBVConst();
- }
-
- switch(k) {
- case UNDEFINED:
- case READ:
- case WRITE:
- case SYMBOL:
- FatalError("BVConstEvaluator: term is not a constant-term",t);
- break;
- case BVCONST:
- //FIXME Handle this special case better
- OutputNode = t;
- break;
- case BVNEG:{
- output = CONSTANTBV::BitVector_Create(inputwidth,true);
- CONSTANTBV::Set_Complement(output,tmp0);
- OutputNode = CreateBVConst(output,outputwidth);
- break;
- }
- case BVSX: {
- output = CONSTANTBV::BitVector_Create(inputwidth,true);
- //unsigned * out0 = BVConstEvaluator(t[0]).GetBVConst();
- unsigned t0_width = t[0].GetValueWidth();
- if(inputwidth == t0_width) {
- CONSTANTBV::BitVector_Copy(output, tmp0);
- OutputNode = CreateBVConst(output, outputwidth);
- }
- else {
- bool topbit_sign = (CONSTANTBV::BitVector_Sign(tmp0) < 0 );
-
- if(topbit_sign){
- CONSTANTBV::BitVector_Fill(output);
- }
- CONSTANTBV::BitVector_Interval_Copy(output, tmp0, 0, 0, t0_width);
- OutputNode = CreateBVConst(output, outputwidth);
- }
- break;
- }
- case BVAND: {
- output = CONSTANTBV::BitVector_Create(inputwidth,true);
- CONSTANTBV::Set_Intersection(output,tmp0,tmp1);
- OutputNode = CreateBVConst(output, outputwidth);
- break;
- }
- case BVOR: {
- output = CONSTANTBV::BitVector_Create(inputwidth,true);
- CONSTANTBV::Set_Union(output,tmp0,tmp1);
- OutputNode = CreateBVConst(output, outputwidth);
- break;
- }
- case BVXOR: {
- output = CONSTANTBV::BitVector_Create(inputwidth,true);
- CONSTANTBV::Set_ExclusiveOr(output,tmp0,tmp1);
- OutputNode = CreateBVConst(output, outputwidth);
- break;
- }
- case BVSUB: {
- output = CONSTANTBV::BitVector_Create(inputwidth,true);
- bool carry = false;
- CONSTANTBV::BitVector_sub(output,tmp0,tmp1,&carry);
- OutputNode = CreateBVConst(output, outputwidth);
- break;
- }
- case BVUMINUS: {
- output = CONSTANTBV::BitVector_Create(inputwidth,true);
- CONSTANTBV::BitVector_Negate(output, tmp0);
- OutputNode = CreateBVConst(output, outputwidth);
- break;
- }
- case BVEXTRACT: {
- output = CONSTANTBV::BitVector_Create(inputwidth,true);
- tmp0 = BVConstEvaluator(t[0]).GetBVConst();
- unsigned int hi = GetUnsignedConst(BVConstEvaluator(t[1]));
- unsigned int low = GetUnsignedConst(BVConstEvaluator(t[2]));
- unsigned int len = hi-low+1;
-
- CONSTANTBV::BitVector_Destroy(output);
- output = CONSTANTBV::BitVector_Create(len, false);
- CONSTANTBV::BitVector_Interval_Copy(output, tmp0, 0, low, len);
- outputwidth = len;
- OutputNode = CreateBVConst(output, outputwidth);
- break;
- }
- //FIXME Only 2 inputs?
- case BVCONCAT: {
- output = CONSTANTBV::BitVector_Create(inputwidth,true);
- unsigned t0_width = t[0].GetValueWidth();
- unsigned t1_width = t[1].GetValueWidth();
- CONSTANTBV::BitVector_Destroy(output);
-
- output = CONSTANTBV::BitVector_Concat(tmp0, tmp1);
- outputwidth = t0_width + t1_width;
- OutputNode = CreateBVConst(output, outputwidth);
-
- break;
- }
- case BVMULT: {
- output = CONSTANTBV::BitVector_Create(inputwidth,true);
- CBV tmp = CONSTANTBV::BitVector_Create(2*inputwidth,true);
- CONSTANTBV::ErrCode e = CONSTANTBV::BitVector_Multiply(tmp,tmp0,tmp1);
-
- if(0 != e) {
- BVConstEvaluatorError(e,t);
- }
- //FIXME WHAT IS MY OUTPUT???? THE SECOND HALF of tmp?
- //CONSTANTBV::BitVector_Interval_Copy(output, tmp, 0, inputwidth, inputwidth);
- CONSTANTBV::BitVector_Interval_Copy(output, tmp, 0, 0, inputwidth);
- OutputNode = CreateBVConst(output, outputwidth);
- CONSTANTBV::BitVector_Destroy(tmp);
- break;
- }
- case BVPLUS: {
- output = CONSTANTBV::BitVector_Create(inputwidth,true);
- bool carry = false;
- ASTVec c = t.GetChildren();
- for(ASTVec::iterator it=c.begin(),itend=c.end();it!=itend;it++) {
- CBV kk = BVConstEvaluator(*it).GetBVConst();
- CONSTANTBV::BitVector_add(output,output,kk,&carry);
- carry = false;
- //CONSTANTBV::BitVector_Destroy(kk);
- }
- OutputNode = CreateBVConst(output, outputwidth);
- break;
- }
- //FIXME ANOTHER SPECIAL CASE
- case SBVDIV:
- case SBVMOD:{
- OutputNode = BVConstEvaluator(TranslateSignedDivMod(t));
- break;
- }
- case BVDIV:
- case BVMOD: {
- CBV quotient = CONSTANTBV::BitVector_Create(inputwidth,true);
- CBV remainder = CONSTANTBV::BitVector_Create(inputwidth,true);
-
- // tmp0 is dividend, tmp1 is the divisor
- //All parameters to BitVector_Div_Pos must be distinct unlike BitVector_Divide
- //FIXME the contents of the second parameter to Div_Pos is destroyed
- //As tmp0 is currently the same as the copy belonging to an ASTNode t[0]
- //this must be copied.
- tmp0 = CONSTANTBV::BitVector_Clone(tmp0);
- CONSTANTBV::ErrCode e= CONSTANTBV::BitVector_Div_Pos(quotient,tmp0,tmp1,remainder);
- CONSTANTBV::BitVector_Destroy(tmp0);
-
- if(0 != e) {
- //error printing
- if(counterexample_checking_during_refinement) {
- output = CONSTANTBV::BitVector_Create(inputwidth,true);
- OutputNode = CreateBVConst(output, outputwidth);
- bvdiv_exception_occured = true;
-
- // CONSTANTBV::BitVector_Destroy(output);
- break;
- }
- else {
- BVConstEvaluatorError(e,t);
- }
- } //end of error printing
-
- //FIXME Not very standard in the current scheme
- if(BVDIV == k){
- OutputNode = CreateBVConst(quotient, outputwidth);
- CONSTANTBV::BitVector_Destroy(remainder);
- }else{
- OutputNode = CreateBVConst(remainder, outputwidth);
- CONSTANTBV::BitVector_Destroy(quotient);
- }
-
- break;
- }
- case ITE:
- if(ASTTrue == t[0])
- OutputNode = BVConstEvaluator(t[1]);
- else if(ASTFalse == t[0])
- OutputNode = BVConstEvaluator(t[2]);
- else
- FatalError("BVConstEvaluator: ITE condiional must be either TRUE or FALSE:",t);
- break;
- case EQ:
- if(CONSTANTBV::BitVector_equal(tmp0,tmp1))
- OutputNode = ASTTrue;
- else
- OutputNode = ASTFalse;
- break;
- case NEQ:
- if(!CONSTANTBV::BitVector_equal(tmp0,tmp1))
- OutputNode = ASTTrue;
- else
- OutputNode = ASTFalse;
- break;
- case BVLT:
- if(-1 == CONSTANTBV::BitVector_Lexicompare(tmp0,tmp1))
- OutputNode = ASTTrue;
- else
- OutputNode = ASTFalse;
- break;
- case BVLE: {
- int comp = CONSTANTBV::BitVector_Lexicompare(tmp0,tmp1);
- if(comp <= 0)
- OutputNode = ASTTrue;
- else
- OutputNode = ASTFalse;
- break;
- }
- case BVGT:
- if(1 == CONSTANTBV::BitVector_Lexicompare(tmp0,tmp1))
- OutputNode = ASTTrue;
- else
- OutputNode = ASTFalse;
- break;
- case BVGE: {
- int comp = CONSTANTBV::BitVector_Lexicompare(tmp0,tmp1);
- if(comp >= 0)
- OutputNode = ASTTrue;
- else
- OutputNode = ASTFalse;
- break;
- }
- case BVSLT:
- if(-1 == CONSTANTBV::BitVector_Compare(tmp0,tmp1))
- OutputNode = ASTTrue;
- else
- OutputNode = ASTFalse;
- break;
- case BVSLE: {
- signed int comp = CONSTANTBV::BitVector_Compare(tmp0,tmp1);
- if(comp <= 0)
- OutputNode = ASTTrue;
- else
- OutputNode = ASTFalse;
- break;
- }
- case BVSGT:
- if(1 == CONSTANTBV::BitVector_Compare(tmp0,tmp1))
- OutputNode = ASTTrue;
- else
- OutputNode = ASTFalse;
- break;
- case BVSGE: {
- int comp = CONSTANTBV::BitVector_Compare(tmp0,tmp1);
- if(comp >= 0)
- OutputNode = ASTTrue;
- else
- OutputNode = ASTFalse;
- break;
- }
- default:
- FatalError("BVConstEvaluator: The input kind is not supported yet:",t);
- break;
- }
-/*
- if(BVCONST != k){
- cerr<<inputwidth<<endl;
- cerr<<"------------------------"<<endl;
- t.LispPrint(cerr);
- cerr<<endl;
- OutputNode.LispPrint(cerr);
- cerr<<endl<<"------------------------"<<endl;
- }
-*/
- UpdateSolverMap(t,OutputNode);
- //UpdateSimplifyMap(t,OutputNode,false);
- return OutputNode;
- }
-#else
- //accepts 64 bit BVConst and sign extends it
- static unsigned long long int SXBVConst64(const ASTNode& t) {
- unsigned long long int c = t.GetBVConst();
- unsigned int len = t.GetValueWidth();
-
- unsigned long long int mask = 1;
- mask = mask << len-1;
-
- bool TopBit = (c & mask) ? true : false;
- if(!TopBit) return c;
-
- unsigned long long int sign = 0xffffffffffffffffLL;
- sign = sign << len-1;
-
- return (c | sign);
- }
-
- //FIXME: Ideally I would like the ASTNodes to be able to operate on
- //themselves (add, sub, concat, etc.) rather than doing a
- //GetBVConst() and then do the operation externally. For now,
- //this is the fastest path to completion.
- ASTNode BeevMgr::BVConstEvaluator(const ASTNode& t) {
- //cerr << "inside begin bcconstevaluator: " << t << endl;
-
- ASTNode OutputNode;
- if(CheckSolverMap(t,OutputNode))
- return OutputNode;
- OutputNode = ASTUndefined;
-
- Kind k = t.GetKind();
- unsigned long long int output = 0;
- unsigned inputwidth = t.GetValueWidth();
- ASTNode t0 = ASTUndefined;
- ASTNode t1 = ASTUndefined;
- if(2 == t.Degree()) {
- t0 = BVConstEvaluator(t[0]);
- t1 = BVConstEvaluator(t[1]);
- }
- switch(k) {
- case READ:
- case UNDEFINED:
- case WRITE:
- case SYMBOL:
- cerr << t;
- FatalError("BVConstEvaluator: term is not a constant-term",t);
- break;
- case BVCONST:
- return t;
- break;
- case BVNEG:
- //compute bitwise negation in C
- output = ~(BVConstEvaluator(t[0]).GetBVConst());
- break;
- case BVSX:
- output = SXBVConst64(BVConstEvaluator(t[0]));
- break;
- case BVAND:
- output = t0.GetBVConst() & t1.GetBVConst();
- break;
- case BVOR:
- output = t0.GetBVConst() | t1.GetBVConst();
- break;
- case BVXOR:
- output = t0.GetBVConst() ^ t1.GetBVConst();
- break;
- case BVSUB:
- output = t0.GetBVConst() - t1.GetBVConst();
- break;
- case BVUMINUS:
- output = ~(BVConstEvaluator(t[0]).GetBVConst()) + 1;
- break;
- case BVEXTRACT: {
- unsigned long long int val = BVConstEvaluator(t[0]).GetBVConst();
- unsigned int hi = GetUnsignedConst(BVConstEvaluator(t[1]));
- unsigned int low = GetUnsignedConst(BVConstEvaluator(t[2]));
-
- if(!(0 <= hi <= 64))
- FatalError("ConstantEvaluator: hi bit in BVEXTRACT is > 32bits",t);
- if(!(0 <= low <= hi <= 64))
- FatalError("ConstantEvaluator: low bit in BVEXTRACT is > 32bits or hi",t);
-
- //64 bit mask.
- unsigned long long int mask1 = 0xffffffffffffffffLL;
- mask1 >>= 64-(hi+1);
-
- //extract val[hi:0]
- val &= mask1;
- //extract val[hi:low]
- val >>= low;
- output = val;
- break;
- }
- case BVCONCAT: {
- unsigned long long int q = BVConstEvaluator(t0).GetBVConst();
- unsigned long long int r = BVConstEvaluator(t1).GetBVConst();
-
- unsigned int qlen = t[0].GetValueWidth();
- unsigned int rlen = t[1].GetValueWidth();
- unsigned int slen = t.GetValueWidth();
- if(!(0 < qlen + rlen <= 64))
- FatalError("BVConstEvaluator:"
- "lengths of childnodes of BVCONCAT are > 64:",t);
-
- //64 bit mask for q
- unsigned long long int qmask = 0xffffffffffffffffLL;
- qmask >>= 64-qlen;
- //zero the useless bits of q
- q &= qmask;
-
- //64 bit mask for r
- unsigned long long int rmask = 0xffffffffffffffffLL;
- rmask >>= 64-rlen;
- //zero the useless bits of r
- r &= rmask;
-
- //concatenate
- q <<= rlen;
- q |= r;
-
- //64 bit mask for output s
- unsigned long long int smask = 0xffffffffffffffffLL;
- smask >>= 64-slen;
-
- //currently q has the output
- output = q;
- output &= smask;
- break;
- }
- case BVMULT: {
- output = t0.GetBVConst() * t1.GetBVConst();
-
- //64 bit mask
- unsigned long long int mask = 0xffffffffffffffffLL;
- mask = mask >> (64 - inputwidth);
- output &= mask;
- break;
- }
- case BVPLUS: {
- ASTVec c = t.GetChildren();
- for(ASTVec::iterator it=c.begin(),itend=c.end();it!=itend;it++)
- output += BVConstEvaluator(*it).GetBVConst();
-
- //64 bit mask
- unsigned long long int mask = 0xffffffffffffffffLL;
- mask = mask >> (64 -inputwidth);
- output &= mask;
- break;
- }
- case SBVDIV:
- case SBVMOD: {
- output = BVConstEvaluator(TranslateSignedDivMod(t)).GetBVConst();
- break;
- }
- case BVDIV: {
- if(0 == t1.GetBVConst()) {
- //if denominator is 0 then
- // (if refinement is ON then output is set to 0)
- // (else produce a fatal error)
- if(counterexample_checking_during_refinement) {
- output = 0;
- bvdiv_exception_occured = true;
- break;
- }
- else {
- FatalError("BVConstEvaluator: divide by zero not allowed:",t);
- }
- }
-
- output = t0.GetBVConst() / t1.GetBVConst();
- //64 bit mask
- unsigned long long int mask = 0xffffffffffffffffLL;
- mask = mask >> (64 - inputwidth);
- output &= mask;
- break;
- }
- case BVMOD: {
- if(0 == t1.GetBVConst()) {
- //if denominator is 0 then
- // (if refinement is ON then output is set to 0)
- // (else produce a fatal error)
- if(counterexample_checking_during_refinement) {
- output = 0;
- bvdiv_exception_occured = true;
- break;
- }
- else {
- FatalError("BVConstEvaluator: divide by zero not allowed:",t);
- }
- }
-
- output = t0.GetBVConst() % t1.GetBVConst();
- //64 bit mask
- unsigned long long int mask = 0xffffffffffffffffLL;
- mask = mask >> (64 - inputwidth);
- output &= mask;
- break;
- }
- case ITE:
- if(ASTTrue == t[0])
- OutputNode = BVConstEvaluator(t[1]);
- else if(ASTFalse == t[0])
- OutputNode = BVConstEvaluator(t[2]);
- else
- FatalError("BVConstEvaluator:"
- "ITE condiional must be either TRUE or FALSE:",t);
- break;
- case EQ:
- if(t0.GetBVConst() == t1.GetBVConst())
- OutputNode = ASTTrue;
- else
- OutputNode = ASTFalse;
- break;
- case NEQ:
- if(t0.GetBVConst() != t1.GetBVConst())
- OutputNode = ASTTrue;
- else
- OutputNode = ASTFalse;
- break;
- break;
- case BVLT: {
- unsigned long long n0 = t0.GetBVConst();
- unsigned long long n1 = t1.GetBVConst();
- if(n0 < n1)
- OutputNode = ASTTrue;
- else
- OutputNode = ASTFalse;
- break;
- }
- case BVLE:
- if(t0.GetBVConst() <= t1.GetBVConst())
- OutputNode = ASTTrue;
- else
- OutputNode = ASTFalse;
- break;
- case BVGT:
- if(t0.GetBVConst() > t1.GetBVConst())
- OutputNode = ASTTrue;
- else
- OutputNode = ASTFalse;
- break;
- case BVGE:
- if(t0.GetBVConst() >= t1.GetBVConst())
- OutputNode = ASTTrue;
- else
- OutputNode = ASTFalse;
- break;
- case BVSLT: {
- signed long long int n0 = SXBVConst64(t0);
- signed long long int n1 = SXBVConst64(t1);
- if(n0 < n1)
- OutputNode = ASTTrue;
- else
- OutputNode = ASTFalse;
- break;
- }
- case BVSLE: {
- signed long long int n0 = SXBVConst64(t0);
- signed long long int n1 = SXBVConst64(t1);
- if(n0 <= n1)
- OutputNode = ASTTrue;
- else
- OutputNode = ASTFalse;
- break;
- }
- case BVSGT: {
- signed long long int n0 = SXBVConst64(t0);
- signed long long int n1 = SXBVConst64(t1);
- if(n0 > n1)
- OutputNode = ASTTrue;
- else
- OutputNode = ASTFalse;
- break;
- }
- case BVSGE: {
- signed long long int n0 = SXBVConst64(t0);
- signed long long int n1 = SXBVConst64(t1);
- if(n0 >= n1)
- OutputNode = ASTTrue;
- else
- OutputNode = ASTFalse;
- break;
- }
- default:
- FatalError("BVConstEvaluator: The input kind is not supported yet:",t);
- break;
- }
-
- if(ASTTrue != OutputNode && ASTFalse != OutputNode)
- OutputNode = CreateBVConst(inputwidth, output);
- UpdateSolverMap(t,OutputNode);
- //UpdateSimplifyMap(t,OutputNode,false);
- return OutputNode;
- } //End of BVConstEvaluator
-#endif
-//In the block below is the old string based version
-//It is included here as an easy reference while the current code is being worked on.
-
-/*
- ASTNode BeevMgr::BVConstEvaluator(const ASTNode& t) {
- ASTNode OutputNode;
- Kind k = t.GetKind();
-
- if(CheckSolverMap(t,OutputNode))
- return OutputNode;
- OutputNode = t;
-
- unsigned int inputwidth = t.GetValueWidth();
- unsigned * output = CONSTANTBV::BitVector_Create(inputwidth,true);
- unsigned * One = CONSTANTBV::BitVector_Create(inputwidth,true);
- CONSTANTBV::ErrCode e = CONSTANTBV::BitVector_from_Bin(One, (unsigned char*)"1");
- //error printing
- if(0 != e) {
- std::string ss("BVConstEvaluator:");
- ss += (const char*)BitVector_Error(e);
- FatalError(ss.c_str(), t);
- }
-
- unsigned * Zero = CONSTANTBV::BitVector_Create(inputwidth,true);
- unsigned int * iii = One;
- unsigned int * jjj = Zero;
-
- //saving some typing. BVPLUS does not use these variables. if the
- //input BVPLUS has two nodes, then we want to avoid setting these
- //variables.
- if(2 == t.Degree() && k != BVPLUS && k != BVCONCAT) {
- iii = ConvertToCONSTANTBV(BVConstEvaluator(t[0]).GetBVConst());
- jjj = ConvertToCONSTANTBV(BVConstEvaluator(t[1]).GetBVConst());
- }
-
- char * cccc;
- switch(k) {
- case UNDEFINED:
- case READ:
- case WRITE:
- case SYMBOL:
- FatalError("BVConstEvaluator: term is not a constant-term",t);
- break;
- case BVCONST:
- OutputNode = t;
- break;
- case BVNEG:{
- //AARON
- if (iii != One) free(iii);
- //AARON
-
- iii = ConvertToCONSTANTBV(BVConstEvaluator(t[0]).GetBVConst());
- CONSTANTBV::Set_Complement(output,iii);
- cccc = (char *)CONSTANTBV::BitVector_to_Bin(output);
- OutputNode = CreateBVConst(cccc,2);
- break;
- }
- case BVSX: {
- unsigned * out0 = ConvertToCONSTANTBV(BVConstEvaluator(t[0]).GetBVConst());
- unsigned t0_width = t[0].GetValueWidth();
- if(inputwidth == t0_width) {
- cccc = (char *)CONSTANTBV::BitVector_to_Bin(out0);
- OutputNode = CreateBVConst(cccc,2);
-
- //AARON
- free(cccc);
- //AARON
-
- CONSTANTBV::BitVector_Destroy(out0);
- }
- else {
- // FIXME: (Dill) I'm guessing that BitVector sign returns 1 if the
- // number is positive, 0 if 0, and -1 if negative. But I'm only
- // guessing.
- signed int topbit_sign = (CONSTANTBV::BitVector_Sign(out0) < 0);
- //out1 is the sign-extension bits
- unsigned * out1 = CONSTANTBV::BitVector_Create(inputwidth-t0_width,true);
- if(topbit_sign)
- CONSTANTBV::BitVector_Fill(out1);
-
- //AARON
- CONSTANTBV::BitVector_Destroy(output);
- //AARON
-
- output = CONSTANTBV::BitVector_Concat(out1,out0);
- cccc = (char *)CONSTANTBV::BitVector_to_Bin(output);
- OutputNode = CreateBVConst(cccc,2);
-
- //AARON
- free(cccc);
- //AARON
-
- CONSTANTBV::BitVector_Destroy(out0);
- CONSTANTBV::BitVector_Destroy(out1);
- }
- break;
- }
- case BVAND: {
- CONSTANTBV::Set_Intersection(output,iii,jjj);
- cccc = (char *)CONSTANTBV::BitVector_to_Bin(output);
- OutputNode = CreateBVConst(cccc,2);
-
- //AARON
- free(cccc);
- //AARON
-
- break;
- }
- case BVOR: {
- CONSTANTBV::Set_Union(output,iii,jjj);
- cccc = (char *)CONSTANTBV::BitVector_to_Bin(output);
- OutputNode = CreateBVConst(cccc,2);
-
- //AARON
- free(cccc);
- //AARON
-
- break;
- }
- case BVXOR: {
- CONSTANTBV::Set_ExclusiveOr(output,iii,jjj);
- cccc = (char *)CONSTANTBV::BitVector_to_Bin(output);
- OutputNode = CreateBVConst(cccc,2);
-
- //AARON
- free(cccc);
- //AARON
-
- break;
- }
- case BVSUB: {
- bool carry = false;
- CONSTANTBV::BitVector_sub(output,iii,jjj,&carry);
- cccc = (char *)CONSTANTBV::BitVector_to_Bin(output);
- OutputNode = CreateBVConst(cccc,2);
-
- //AARON
- free(cccc);
- //AARON
-
- break;
- }
- case BVUMINUS: {
- bool carry = false;
-
- //AARON
- if (iii != One) free(iii);
- //AARON
-
- iii = ConvertToCONSTANTBV(BVConstEvaluator(t[0]).GetBVConst());
- CONSTANTBV::Set_Complement(output,iii);
- CONSTANTBV::BitVector_add(output,output,One,&carry);
- cccc = (char *)CONSTANTBV::BitVector_to_Bin(output);
- OutputNode = CreateBVConst(cccc,2);
-
- //AARON
- free(cccc);
- //AARON
-
- break;
- }
- case BVEXTRACT: {
- string s(BVConstEvaluator(t[0]).GetBVConst());
- unsigned int hi = GetUnsignedConst(BVConstEvaluator(t[1]));
- unsigned int low = GetUnsignedConst(BVConstEvaluator(t[2]));
-
- //length of substr to chop
- unsigned int len = hi-low+1;
- //distance from MSB
- hi = s.size()-1 - hi;
- string ss = s.substr(hi,len);
- OutputNode = CreateBVConst(ss.c_str(),2);
- break;
- }
- case BVCONCAT: {
- string s(BVConstEvaluator(t[0]).GetBVConst());
- string r(BVConstEvaluator(t[1]).GetBVConst());
-
- string q(s+r);
- OutputNode = CreateBVConst(q.c_str(),2);
- break;
- }
- case BVMULT: {
- unsigned * output1 = CONSTANTBV::BitVector_Create(2*inputwidth,true);
- CONSTANTBV::ErrCode e = CONSTANTBV::BitVector_Multiply(output1,iii,jjj);
- //error printing
- if(0 != e) {
- std::string ss("BVConstEvaluator:");
- ss += (const char*)BitVector_Error(e);
- //destroy all the CONSTANTBV bitvectors
- CONSTANTBV::BitVector_Destroy(iii);
- CONSTANTBV::BitVector_Destroy(jjj);
- CONSTANTBV::BitVector_Destroy(One);
- CONSTANTBV::BitVector_Destroy(Zero);
- FatalError(ss.c_str(), t);
- }
-
- cccc = (char *)CONSTANTBV::BitVector_to_Bin(output1);
- std::string s(cccc);
-
- //AARON
- free(cccc);
- //AARON
-
- s = s.substr(inputwidth,inputwidth);
- OutputNode = CreateBVConst(s.c_str(),2);
- CONSTANTBV::BitVector_Destroy(output1);
- break;
- }
- case BVPLUS: {
- bool carry = false;
- ASTVec c = t.GetChildren();
- for(ASTVec::iterator it=c.begin(),itend=c.end();it!=itend;it++) {
- unsigned int * kk = ConvertToCONSTANTBV(BVConstEvaluator(*it).GetBVConst());
- CONSTANTBV::BitVector_add(output,output,kk,&carry);
- carry = false;
- CONSTANTBV::BitVector_Destroy(kk);
- }
- cccc = (char *)CONSTANTBV::BitVector_to_Bin(output);
- OutputNode = CreateBVConst(cccc,2);
-
- //AARON
- free(cccc);
- //AARON
-
- break;
- }
- case SBVDIV:
- case SBVMOD: {
- OutputNode = BVConstEvaluator(TranslateSignedDivMod(t));
- break;
- }
- case BVDIV: {
- unsigned * quotient = CONSTANTBV::BitVector_Create(inputwidth,true);
- unsigned * remainder = CONSTANTBV::BitVector_Create(inputwidth,true);
- // iii is dividend, jjj is the divisor
- CONSTANTBV::ErrCode e = CONSTANTBV::BitVector_Div_Pos(quotient,iii,jjj,remainder);
-
- if(0 != e) {
- //error printing
- if(counterexample_checking_during_refinement) {
- OutputNode = CreateZeroConst(inputwidth);
- bvdiv_exception_occured = true;
- break;
- }
- else {
- std::string ss("BVConstEvaluator:");
- ss += (const char*)BitVector_Error(e);
- //destroy all the CONSTANTBV bitvectors
- CONSTANTBV::BitVector_Destroy(iii);
- CONSTANTBV::BitVector_Destroy(jjj);
- CONSTANTBV::BitVector_Destroy(One);
- CONSTANTBV::BitVector_Destroy(Zero);
-
- //AARON
- iii = jjj = One = Zero = NULL;
- //AARON
-
- FatalError(ss.c_str(), t);
- }
- } //end of error printing
-
- cccc = (char *)CONSTANTBV::BitVector_to_Bin(quotient);
- OutputNode = CreateBVConst(cccc,2);
-
- //AARON
- free(cccc);
- CONSTANTBV::BitVector_Destroy(quotient);
- CONSTANTBV::BitVector_Destroy(remainder);
- //AARON
-
- break;
- }
- case BVMOD: {
- unsigned * quotient = CONSTANTBV::BitVector_Create(inputwidth,true);
- unsigned * remainder = CONSTANTBV::BitVector_Create(inputwidth,true);
- // iii is dividend, jjj is the divisor
- CONSTANTBV::ErrCode e = CONSTANTBV::BitVector_Div_Pos(quotient,iii,jjj,remainder);
-
- if(0 != e) {
- //error printing
- if(counterexample_checking_during_refinement) {
- OutputNode = CreateZeroConst(inputwidth);
- bvdiv_exception_occured = true;
- break;
- }
- else {
- std::string ss("BVConstEvaluator:");
- ss += (const char*)BitVector_Error(e);
- //destroy all the CONSTANTBV bitvectors
- CONSTANTBV::BitVector_Destroy(iii);
- CONSTANTBV::BitVector_Destroy(jjj);
- CONSTANTBV::BitVector_Destroy(One);
- CONSTANTBV::BitVector_Destroy(Zero);
-
- //AARON
- iii = jjj = One = Zero = NULL;
- //AARON
-
- FatalError(ss.c_str(), t);
- }
- } //end of errory printing
-
- cccc = (char *)CONSTANTBV::BitVector_to_Bin(remainder);
- OutputNode = CreateBVConst(cccc,2);
-
- //AARON
- free(cccc);
- CONSTANTBV::BitVector_Destroy(quotient);
- CONSTANTBV::BitVector_Destroy(remainder);
- //AARON
-
- break;
- }
- case ITE:
- if(ASTTrue == t[0])
- OutputNode = BVConstEvaluator(t[1]);
- else if(ASTFalse == t[0])
- OutputNode = BVConstEvaluator(t[2]);
- else
- FatalError("BVConstEvaluator: ITE condiional must be either TRUE or FALSE:",t);
- break;
- case EQ:
- if(CONSTANTBV::BitVector_equal(iii,jjj))
- OutputNode = ASTTrue;
- else
- OutputNode = ASTFalse;
- break;
- case NEQ:
- if(!CONSTANTBV::BitVector_equal(iii,jjj))
- OutputNode = ASTTrue;
- else
- OutputNode = ASTFalse;
- break;
- case BVLT:
- if(-1 == CONSTANTBV::BitVector_Lexicompare(iii,jjj))
- OutputNode = ASTTrue;
- else
- OutputNode = ASTFalse;
- break;
- case BVLE: {
- int comp = CONSTANTBV::BitVector_Lexicompare(iii,jjj);
- if(comp <= 0)
- OutputNode = ASTTrue;
- else
- OutputNode = ASTFalse;
- break;
- }
- case BVGT:
- if(1 == CONSTANTBV::BitVector_Lexicompare(iii,jjj))
- OutputNode = ASTTrue;
- else
- OutputNode = ASTFalse;
- break;
- case BVGE: {
- int comp = CONSTANTBV::BitVector_Lexicompare(iii,jjj);
- if(comp >= 0)
- OutputNode = ASTTrue;
- else
- OutputNode = ASTFalse;
- break;
- }
- case BVSLT:
- if(-1 == CONSTANTBV::BitVector_Compare(iii,jjj))
- OutputNode = ASTTrue;
- else
- OutputNode = ASTFalse;
- break;
- case BVSLE: {
- signed int comp = CONSTANTBV::BitVector_Compare(iii,jjj);
- if(comp <= 0)
- OutputNode = ASTTrue;
- else
- OutputNode = ASTFalse;
- break;
- }
- case BVSGT:
- if(1 == CONSTANTBV::BitVector_Compare(iii,jjj))
- OutputNode = ASTTrue;
- else
- OutputNode = ASTFalse;
- break;
- case BVSGE: {
- int comp = CONSTANTBV::BitVector_Compare(iii,jjj);
- if(comp >= 0)
- OutputNode = ASTTrue;
- else
- OutputNode = ASTFalse;
- break;
- }
- default:
- FatalError("BVConstEvaluator: The input kind is not supported yet:",t);
- break;
- }
-
-
-
- // //destroy all the CONSTANTBV bitvectors
-// CONSTANTBV::BitVector_Destroy(iii);
-// CONSTANTBV::BitVector_Destroy(jjj);
-// CONSTANTBV::BitVector_Destroy(output);
-
-// if(k == BVNEG || k == BVUMINUS)
-// CONSTANTBV::BitVector_Destroy(One);
-// else if(k == BVAND || k == BVOR || k == BVXOR || k == BVSUB ||
-// k == BVMULT || k == EQ || k == NEQ || k == BVLT ||
-// k == BVLE || k == BVGT || k == BVGE || k == BVSLT ||
-// k == BVSLE || k == BVSGT || k == BVSGE) {
-// CONSTANTBV::BitVector_Destroy(One);
-// CONSTANTBV::BitVector_Destroy(Zero);
-// }
-
- //AARON
- if (output != NULL) CONSTANTBV::BitVector_Destroy(output);
- if (One != NULL) CONSTANTBV::BitVector_Destroy(One);
- if (Zero != NULL) CONSTANTBV::BitVector_Destroy(Zero);
- if (iii != NULL && iii != One) CONSTANTBV::BitVector_Destroy(iii);
- if (jjj != NULL && jjj != Zero) CONSTANTBV::BitVector_Destroy(jjj);
- //AARON
-
- UpdateSolverMap(t,OutputNode);
- //UpdateSimplifyMap(t,OutputNode,false);
- return OutputNode;
- }
-
-
- unsigned int * ConvertToCONSTANTBV(const char * s) {
- unsigned int length = strlen(s);
- unsigned char * ccc = (unsigned char *)s;
- unsigned * iii = CONSTANTBV::BitVector_Create(length,true);
- CONSTANTBV::ErrCode e = CONSTANTBV::BitVector_from_Bin(iii,ccc);
- //error printing
- if(0 != e) {
- cerr << "ConverToCONSTANTBV: wrong bin value: " << BitVector_Error(e);
- FatalError("");
- }
-
- return iii;
- }
-*/
-} //end of namespace BEEV
diff --git a/stp/c_interface/Makefile b/stp/c_interface/Makefile
deleted file mode 100644
index 29b9006b..00000000
--- a/stp/c_interface/Makefile
+++ /dev/null
@@ -1,19 +0,0 @@
-#===-- stp/c_interface/Makefile ----------------------------*- Makefile -*--===#
-#
-# The KLEE Symbolic Virtual Machine
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-#===------------------------------------------------------------------------===#
-
-LEVEL=../..
-
-LIBRARYNAME=stp_c_interface
-DONT_BUILD_RELINKED=1
-BUILD_ARCHIVE=1
-
-include $(LEVEL)/Makefile.common
-
-# HACK: Force -Wno-deprecated for ext container use.
-CXX.Flags += -Wno-deprecated
diff --git a/stp/c_interface/c_interface.cpp b/stp/c_interface/c_interface.cpp
deleted file mode 100644
index 52c4df21..00000000
--- a/stp/c_interface/c_interface.cpp
+++ /dev/null
@@ -1,1548 +0,0 @@
-/********************************************************************
- * AUTHORS: Vijay Ganesh, David L. Dill
- *
- * BEGIN DATE: November, 2005
- *
- * LICENSE: Please view LICENSE file in the home dir of this Program
- ********************************************************************/
-// -*- c++ -*-
-#include "c_interface.h"
-
-#include <cstdlib>
-#include <cassert>
-#include <ostream>
-#include <iostream>
-#include "fdstream.h"
-#include "../AST/AST.h"
-
-//These typedefs lower the effort of using the keyboard to type (too
-//many overloaded meanings of the word type)
-typedef BEEV::ASTNode node;
-typedef BEEV::ASTNode* nodestar;
-typedef BEEV::BeevMgr* bmstar;
-typedef BEEV::ASTVec nodelist;
-typedef BEEV::CompleteCounterExample* CompleteCEStar;
-BEEV::ASTVec *decls = NULL;
-//vector<BEEV::ASTNode *> created_exprs;
-bool cinterface_exprdelete_on = false;
-
-void vc_setFlags(char c) {
- std::string helpstring = "Usage: stp [-option] [infile]\n\n";
- helpstring += "-r : switch refinement off (optimizations are ON by default)\n";
- helpstring += "-w : switch wordlevel solver off (optimizations are ON by default)\n";
- helpstring += "-a : switch optimizations off (optimizations are ON by default)\n";
- helpstring += "-s : print function statistics\n";
- helpstring += "-v : print nodes \n";
- helpstring += "-c : construct counterexample\n";
- helpstring += "-d : check counterexample\n";
- helpstring += "-p : print counterexample\n";
- helpstring += "-h : help\n";
-
- switch(c) {
- case 'a' :
- BEEV::optimize = false;
- BEEV::wordlevel_solve = false;
- break;
- case 'b':
- BEEV::print_STPinput_back = true;
- break;
- case 'c':
- BEEV::construct_counterexample = true;
- break;
- case 'd':
- BEEV::construct_counterexample = true;
- BEEV::check_counterexample = true;
- break;
- case 'e':
- BEEV::variable_activity_optimize = true;
- break;
- case 'f':
- BEEV::smtlib_parser_enable = true;
- break;
- case 'h':
- cout << helpstring;
- BEEV::FatalError("");
- break;
- case 'l' :
- BEEV::linear_search = true;
- break;
- case 'n':
- BEEV::print_output = true;
- break;
- case 'p':
- BEEV::print_counterexample = true;
- break;
- case 'q':
- BEEV::print_arrayval_declaredorder = true;
- break;
- case 'r':
- BEEV::arrayread_refinement = false;
- break;
- case 's' :
- BEEV::stats = true;
- break;
- case 'u':
- BEEV::arraywrite_refinement = true;
- break;
- case 'v' :
- BEEV::print_nodes = true;
- break;
- case 'w':
- BEEV::wordlevel_solve = false;
- break;
- case 'x':
- cinterface_exprdelete_on = true;
- break;
- case 'z':
- BEEV::print_sat_varorder = true;
- break;
- default:
- std::string s = "C_interface: vc_setFlags: Unrecognized commandline flag:\n";
- s += helpstring;
- BEEV::FatalError(s.c_str());
- break;
- }
-}
-
-//Create a validity Checker. This is the global BeevMgr
-VC vc_createValidityChecker(void) {
- vc_setFlags('d');
-#ifdef NATIVE_C_ARITH
-#else
- CONSTANTBV::ErrCode c = CONSTANTBV::BitVector_Boot();
- if(0 != c) {
- cout << CONSTANTBV::BitVector_Error(c) << endl;
- return 0;
- }
-#endif
- bmstar bm = new BEEV::BeevMgr();
- decls = new BEEV::ASTVec();
- //created_exprs.clear();
- return (VC)bm;
-}
-
-// Expr I/O
-void vc_printExpr(VC vc, Expr e) {
- //do not print in lisp mode
- //bmstar b = (bmstar)vc;
- BEEV::ASTNode q = (*(nodestar)e);
- // b->Begin_RemoveWrites = true;
- // BEEV::ASTNode q = b->SimplifyFormula_TopLevel(*((nodestar)e),false);
- // b->Begin_RemoveWrites = false;
- q.PL_Print(cout);
-}
-
-void vc_printExprFile(VC vc, Expr e, int fd) {
- fdostream os(fd);
- ((nodestar)e)->PL_Print(os);
- //os.flush();
-}
-
-static void vc_printVarDeclsToStream(VC vc, ostream &os) {
- for(BEEV::ASTVec::iterator i = decls->begin(),iend=decls->end();i!=iend;i++) {
- node a = *i;
- switch(a.GetType()) {
- case BEEV::BITVECTOR_TYPE:
- a.PL_Print(os);
- os << " : BITVECTOR(" << a.GetValueWidth() << ");" << endl;
- break;
- case BEEV::ARRAY_TYPE:
- a.PL_Print(os);
- os << " : ARRAY " << "BITVECTOR(" << a.GetIndexWidth() << ") OF ";
- os << "BITVECTOR(" << a.GetValueWidth() << ");" << endl;
- break;
- case BEEV::BOOLEAN_TYPE:
- a.PL_Print(os);
- os << " : BOOLEAN;" << endl;
- break;
- default:
- BEEV::FatalError("vc_printDeclsToStream: Unsupported type",a);
- break;
- }
- }
-}
-
-void vc_printVarDecls(VC vc) {
- vc_printVarDeclsToStream(vc, cout);
-}
-
-static void vc_printAssertsToStream(VC vc, ostream &os, int simplify_print) {
- bmstar b = (bmstar)vc;
- BEEV::ASTVec v = b->GetAsserts();
- for(BEEV::ASTVec::iterator i=v.begin(),iend=v.end();i!=iend;i++) {
- b->Begin_RemoveWrites = true;
- BEEV::ASTNode q = (simplify_print == 1) ? b->SimplifyFormula_TopLevel(*i,false) : *i;
- q = (simplify_print == 1) ? b->SimplifyFormula_TopLevel(q,false) : q;
- b->Begin_RemoveWrites = false;
- os << "ASSERT( ";
- q.PL_Print(os);
- os << ");" << endl;
- }
-}
-
-void vc_printAsserts(VC vc, int simplify_print) {
- vc_printAssertsToStream(vc, cout, simplify_print);
-}
-
-void vc_printQueryStateToBuffer(VC vc, Expr e, char **buf, unsigned long *len, int simplify_print){
- assert(vc);
- assert(e);
- assert(buf);
- assert(len);
- bmstar b = (bmstar)vc;
-
- // formate the state of the query
- stringstream os;
- vc_printVarDeclsToStream(vc, os);
- os << "%----------------------------------------------------" << endl;
- vc_printAssertsToStream(vc, os, simplify_print);
- os << "%----------------------------------------------------" << endl;
- os << "QUERY( ";
- b->Begin_RemoveWrites = true;
- BEEV::ASTNode q = (simplify_print == 1) ? b->SimplifyFormula_TopLevel(*((nodestar)e),false) : *(nodestar)e;
- b->Begin_RemoveWrites = false;
- q.PL_Print(os);
- os << " );" << endl;
-
- // convert to a c buffer
- string s = os.str();
- const char *cstr = s.c_str();
- unsigned long size = s.size() + 1; // number of chars + terminating null
- *buf = (char *)malloc(size);
- if (!(*buf)) {
- fprintf(stderr, "malloc(%lu) failed.", size);
- assert(*buf);
- }
- *len = size;
- memcpy(*buf, cstr, size);
-}
-
-void vc_printCounterExampleToBuffer(VC vc, char **buf, unsigned long *len) {
- assert(vc);
- assert(buf);
- assert(len);
- bmstar b = (bmstar)vc;
-
- // formate the state of the query
- std::ostringstream os;
- BEEV::print_counterexample = true;
- os << "COUNTEREXAMPLE BEGIN: \n";
- b->PrintCounterExample(true,os);
- os << "COUNTEREXAMPLE END: \n";
-
- // convert to a c buffer
- string s = os.str();
- const char *cstr = s.c_str();
- unsigned long size = s.size() + 1; // number of chars + terminating null
- *buf = (char *)malloc(size);
- if (!(*buf)) {
- fprintf(stderr, "malloc(%lu) failed.", size);
- assert(*buf);
- }
- *len = size;
- memcpy(*buf, cstr, size);
-}
-
-void vc_printExprToBuffer(VC vc, Expr e, char **buf, unsigned long * len) {
- stringstream os;
- //bmstar b = (bmstar)vc;
- BEEV::ASTNode q = *((nodestar)e);
- // b->Begin_RemoveWrites = true;
- // BEEV::ASTNode q = b->SimplifyFormula_TopLevel(*((nodestar)e),false);
- // b->Begin_RemoveWrites = false;
- q.PL_Print(os);
- //((nodestar)e)->PL_Print(os);
- string s = os.str();
- const char * cstr = s.c_str();
- unsigned long size = s.size() + 1; // number of chars + terminating null
- *buf = (char *)malloc(size);
- *len = size;
- memcpy(*buf, cstr, size);
-}
-
-void vc_printQuery(VC vc){
- ostream& os = std::cout;
- bmstar b = (bmstar)vc;
- os << "QUERY(";
- //b->Begin_RemoveWrites = true;
- //BEEV::ASTNode q = b->SimplifyFormula_TopLevel(b->GetQuery(),false);
- BEEV::ASTNode q = b->GetQuery();
- //b->Begin_RemoveWrites = false;
- q.PL_Print(os);
- // b->GetQuery().PL_Print(os);
- os << ");" << endl;
-}
-
-/////////////////////////////////////////////////////////////////////////////
-// Array-related methods //
-/////////////////////////////////////////////////////////////////////////////
-//! Create an array type
-Type vc_arrayType(VC vc, Type typeIndex, Type typeData) {
- bmstar b = (bmstar)vc;
- nodestar ti = (nodestar)typeIndex;
- nodestar td = (nodestar)typeData;
-
- if(!(ti->GetKind() == BEEV::BITVECTOR && (*ti)[0].GetKind() == BEEV::BVCONST))
- BEEV::FatalError("Tyring to build array whose indextype i is not a BITVECTOR, where i = ",*ti);
- if(!(td->GetKind() == BEEV::BITVECTOR && (*td)[0].GetKind() == BEEV::BVCONST))
- BEEV::FatalError("Trying to build an array whose valuetype v is not a BITVECTOR. where a = ",*td);
- nodestar output = new node(b->CreateNode(BEEV::ARRAY,(*ti)[0],(*td)[0]));
- //if(cinterface_exprdelete_on) created_exprs.push_back(output);
- return (Type)output;
-}
-
-//! Create an expression for the value of array at the given index
-Expr vc_readExpr(VC vc, Expr array, Expr index) {
- bmstar b = (bmstar)vc;
- nodestar a = (nodestar)array;
- nodestar i = (nodestar)index;
-
- b->BVTypeCheck(*a);
- b->BVTypeCheck(*i);
- node o = b->CreateTerm(BEEV::READ,a->GetValueWidth(),*a,*i);
- b->BVTypeCheck(o);
-
- nodestar output = new node(o);
- //if(cinterface_exprdelete_on) created_exprs.push_back(output);
- return output;
-}
-
-// //! Array update; equivalent to "array WITH [index] := newValue"
-Expr vc_writeExpr(VC vc, Expr array, Expr index, Expr newValue) {
- bmstar b = (bmstar)vc;
- nodestar a = (nodestar)array;
- nodestar i = (nodestar)index;
- nodestar n = (nodestar)newValue;
-
- b->BVTypeCheck(*a);
- b->BVTypeCheck(*i);
- b->BVTypeCheck(*n);
- node o = b->CreateTerm(BEEV::WRITE,a->GetValueWidth(),*a,*i,*n);
- o.SetIndexWidth(a->GetIndexWidth());
- b->BVTypeCheck(o);
-
- nodestar output = new node(o);
- //if(cinterface_exprdelete_on) created_exprs.push_back(output);
- return output;
-}
-
-/////////////////////////////////////////////////////////////////////////////
-// Context-related methods //
-/////////////////////////////////////////////////////////////////////////////
-//! Assert a new formula in the current context.
-/*! The formula must have Boolean type. */
-void vc_assertFormula(VC vc, Expr e) {
- nodestar a = (nodestar)e;
- bmstar b = (bmstar)vc;
-
- if(!BEEV::is_Form_kind(a->GetKind()))
- BEEV::FatalError("Trying to assert a NON formula: ",*a);
-
- b->BVTypeCheck(*a);
- b->AddAssert(*a);
-}
-
-//! Check validity of e in the current context.
-/*! If the result is true, then the resulting context is the same as
- * the starting context. If the result is false, then the resulting
- * context is a context in which e is false. e must have Boolean
- * type. */
-int vc_query(VC vc, Expr e) {
- nodestar a = (nodestar)e;
- bmstar b = (bmstar)vc;
-
- if(!BEEV::is_Form_kind(a->GetKind()))
- BEEV::FatalError("CInterface: Trying to QUERY a NON formula: ",*a);
-
- b->BVTypeCheck(*a);
- b->AddQuery(*a);
-
- const BEEV::ASTVec v = b->GetAsserts();
- node o;
- if(!v.empty()) {
- if(v.size()==1)
- return b->TopLevelSAT(v[0],*a);
- else
- return b->TopLevelSAT(b->CreateNode(BEEV::AND,v),*a);
- }
- else
- return b->TopLevelSAT(b->CreateNode(BEEV::TRUE),*a);
-}
-
-void vc_push(VC vc) {
- bmstar b = (bmstar)vc;
- b->ClearAllCaches();
- b->Push();
-}
-
-void vc_pop(VC vc) {
- bmstar b = (bmstar)vc;
- b->Pop();
-}
-
-void vc_printCounterExample(VC vc) {
- bmstar b = (bmstar)vc;
- BEEV::print_counterexample = true;
- cout << "COUNTEREXAMPLE BEGIN: \n";
- b->PrintCounterExample(true);
- cout << "COUNTEREXAMPLE END: \n";
-}
-
-// //! Return the counterexample after a failed query.
-// /*! This method should only be called after a query which returns
-// * false. It will try to return the simplest possible set of
-// * assertions which are sufficient to make the queried expression
-// * false. The caller is responsible for freeing the array when
-// * finished with it.
-// */
-
-Expr vc_getCounterExample(VC vc, Expr e) {
- nodestar a = (nodestar)e;
- bmstar b = (bmstar)vc;
-
- bool t = false;
- if(b->CounterExampleSize())
- t = true;
- nodestar output = new node(b->GetCounterExample(t, *a));
- //if(cinterface_exprdelete_on) created_exprs.push_back(output);
- return output;
-}
-
-int vc_counterexample_size(VC vc) {
- bmstar b = (bmstar)vc;
- return b->CounterExampleSize();
-}
-
-WholeCounterExample vc_getWholeCounterExample(VC vc) {
- bmstar b = (bmstar)vc;
- CompleteCEStar c =
- new BEEV::CompleteCounterExample(b->GetCompleteCounterExample(), b);
- return c;
-}
-
-Expr vc_getTermFromCounterExample(VC vc, Expr e, CompleteCEStar cc) {
- //bmstar b = (bmstar)vc;
- nodestar n = (nodestar)e;
- CompleteCEStar c = (CompleteCEStar)cc;
-
- nodestar output = new node(c->GetCounterExample(*n));
- return output;
-}
-
-int vc_getBVLength(VC vc, Expr ex) {
- nodestar e = (nodestar)ex;
-
- if(BEEV::BITVECTOR_TYPE != e->GetType()) {
- BEEV::FatalError("c_interface: vc_GetBVLength: Input expression must be a bit-vector");
- }
-
- return e->GetValueWidth();
-} // end of vc_getBVLength
-
-/////////////////////////////////////////////////////////////////////////////
-// Expr Creation methods //
-/////////////////////////////////////////////////////////////////////////////
-//! 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) {
- bmstar b = (bmstar)vc;
-
- node o = b->CreateSymbol(name);
- o.SetIndexWidth(indexwidth);
- o.SetValueWidth(valuewidth);
-
- nodestar output = new node(o);
- ////if(cinterface_exprdelete_on) created_exprs.push_back(output);
- b->BVTypeCheck(*output);
-
- //store the decls in a vector for printing purposes
- decls->push_back(o);
- return output;
-}
-
-Expr vc_varExpr(VC vc, char * name, Type type) {
- bmstar b = (bmstar)vc;
- nodestar a = (nodestar)type;
-
- node o = b->CreateSymbol(name);
- switch(a->GetKind()) {
- case BEEV::BITVECTOR:
- o.SetIndexWidth(0);
- o.SetValueWidth(GetUnsignedConst((*a)[0]));
- break;
- case BEEV::ARRAY:
- o.SetIndexWidth(GetUnsignedConst((*a)[0]));
- o.SetValueWidth(GetUnsignedConst((*a)[1]));
- break;
- case BEEV::BOOLEAN:
- o.SetIndexWidth(0);
- o.SetValueWidth(0);
- break;
- default:
- BEEV::FatalError("CInterface: vc_varExpr: Unsupported type",*a);
- break;
- }
- nodestar output = new node(o);
- ////if(cinterface_exprdelete_on) created_exprs.push_back(output);
- b->BVTypeCheck(*output);
-
- //store the decls in a vector for printing purposes
- decls->push_back(o);
- return output;
-}
-
-//! Create an equality expression. The two children must have the
-//same type.
-Expr vc_eqExpr(VC vc, Expr ccc0, Expr ccc1) {
- bmstar b = (bmstar)vc;
-
- nodestar a = (nodestar)ccc0;
- nodestar aa = (nodestar)ccc1;
- b->BVTypeCheck(*a);
- b->BVTypeCheck(*aa);
- node o = b->CreateNode(BEEV::EQ,*a,*aa);
-
- nodestar output = new node(o);
- //if(cinterface_exprdelete_on) created_exprs.push_back(output);
- return output;
-}
-
-Expr vc_boolType(VC vc) {
- bmstar b = (bmstar)vc;
-
- node o = b->CreateNode(BEEV::BOOLEAN);
- nodestar output = new node(o);
- //if(cinterface_exprdelete_on) created_exprs.push_back(output);
- return output;
-}
-
-/////////////////////////////////////////////////////////////////////////////
-// BOOLEAN EXPR Creation methods //
-/////////////////////////////////////////////////////////////////////////////
-// The following functions create Boolean expressions. The children
-// provided as arguments must be of type Boolean.
-Expr vc_trueExpr(VC vc) {
- bmstar b = (bmstar)vc;
- node c = b->CreateNode(BEEV::TRUE);
-
- nodestar d = new node(c);
- //if(cinterface_exprdelete_on) created_exprs.push_back(d);
- return d;
-}
-
-Expr vc_falseExpr(VC vc) {
- bmstar b = (bmstar)vc;
- node c = b->CreateNode(BEEV::FALSE);
-
- nodestar d = new node(c);
- //if(cinterface_exprdelete_on) created_exprs.push_back(d);
- return d;
-}
-
-Expr vc_notExpr(VC vc, Expr ccc) {
- bmstar b = (bmstar)vc;
- nodestar a = (nodestar)ccc;
-
- node o = b->CreateNode(BEEV::NOT,*a);
- b->BVTypeCheck(o);
-
- nodestar output = new node(o);
- //if(cinterface_exprdelete_on) created_exprs.push_back(output);
- return output;
-}
-
-Expr vc_andExpr(VC vc, Expr left, Expr right) {
- bmstar b = (bmstar)vc;
- nodestar l = (nodestar)left;
- nodestar r = (nodestar)right;
-
- node o = b->CreateNode(BEEV::AND,*l,*r);
- b->BVTypeCheck(o);
-
- nodestar output = new node(o);
- //if(cinterface_exprdelete_on) created_exprs.push_back(output);
- return output;
-}
-
-Expr vc_orExpr(VC vc, Expr left, Expr right) {
- bmstar b = (bmstar)vc;
- nodestar l = (nodestar)left;
- nodestar r = (nodestar)right;
-
- node o = b->CreateNode(BEEV::OR,*l,*r);
- b->BVTypeCheck(o);
- nodestar output = new node(o);
- //if(cinterface_exprdelete_on) created_exprs.push_back(output);
- return output;
-}
-
-Expr vc_andExprN(VC vc, Expr* cc, int n) {
- bmstar b = (bmstar)vc;
- nodestar * c = (nodestar *)cc;
- nodelist d;
-
- for(int i =0; i < n; i++)
- d.push_back(*c[i]);
-
- node o = b->CreateNode(BEEV::AND,d);
- b->BVTypeCheck(o);
-
- nodestar output = new node(o);
- //if(cinterface_exprdelete_on) created_exprs.push_back(output);
- return output;
-}
-
-
-Expr vc_orExprN(VC vc, Expr* cc, int n) {
- bmstar b = (bmstar)vc;
- nodestar * c = (nodestar *)cc;
- nodelist d;
-
- for(int i =0; i < n; i++)
- d.push_back(*c[i]);
-
- node o = b->CreateNode(BEEV::OR,d);
- b->BVTypeCheck(o);
-
- nodestar output = new node(o);
- //if(cinterface_exprdelete_on) created_exprs.push_back(output);
- return output;
-}
-
-Expr vc_iteExpr(VC vc, Expr cond, Expr thenpart, Expr elsepart){
- bmstar b = (bmstar)vc;
- nodestar c = (nodestar)cond;
- nodestar t = (nodestar)thenpart;
- nodestar e = (nodestar)elsepart;
-
- b->BVTypeCheck(*c);
- b->BVTypeCheck(*t);
- b->BVTypeCheck(*e);
- node o;
- //if the user asks for a formula then produce a formula, else
- //prodcue a term
- if(BEEV::BOOLEAN_TYPE == t->GetType())
- o = b->CreateNode(BEEV::ITE,*c,*t,*e);
- else {
- o = b->CreateTerm(BEEV::ITE,t->GetValueWidth(),*c,*t,*e);
- o.SetIndexWidth(t->GetIndexWidth());
- }
- b->BVTypeCheck(o);
- nodestar output = new node(o);
- //if(cinterface_exprdelete_on) created_exprs.push_back(output);
- return output;
-}
-
-Expr vc_impliesExpr(VC vc, Expr antecedent, Expr consequent){
- bmstar b = (bmstar)vc;
- nodestar c = (nodestar)antecedent;
- nodestar t = (nodestar)consequent;
-
- b->BVTypeCheck(*c);
- b->BVTypeCheck(*t);
- node o;
-
- o = b->CreateNode(BEEV::IMPLIES,*c,*t);
- b->BVTypeCheck(o);
- nodestar output = new node(o);
- //if(cinterface_exprdelete_on) created_exprs.push_back(output);
- return output;
-}
-
-Expr vc_iffExpr(VC vc, Expr e0, Expr e1){
- bmstar b = (bmstar)vc;
- nodestar c = (nodestar)e0;
- nodestar t = (nodestar)e1;
-
- b->BVTypeCheck(*c);
- b->BVTypeCheck(*t);
- node o;
-
- o = b->CreateNode(BEEV::IFF,*c,*t);
- b->BVTypeCheck(o);
- nodestar output = new node(o);
- //if(cinterface_exprdelete_on) created_exprs.push_back(output);
- return output;
-}
-
-Expr vc_boolToBVExpr(VC vc, Expr form) {
- bmstar b = (bmstar)vc;
- nodestar c = (nodestar)form;
-
- b->BVTypeCheck(*c);
- if(!is_Form_kind(c->GetKind()))
- BEEV::FatalError("CInterface: vc_BoolToBVExpr: You have input a NON formula:",*c);
-
- node o;
- node one = b->CreateOneConst(1);
- node zero = b->CreateZeroConst(1);
- o = b->CreateTerm(BEEV::ITE,1,*c,one,zero);
-
- b->BVTypeCheck(o);
- nodestar output = new node(o);
- //if(cinterface_exprdelete_on) created_exprs.push_back(output);
- return output;
-}
-
-/////////////////////////////////////////////////////////////////////////////
-// BITVECTOR EXPR Creation methods //
-/////////////////////////////////////////////////////////////////////////////
-Type vc_bvType(VC vc, int num_bits) {
- bmstar b = (bmstar)vc;
-
- if(!(0 < num_bits))
- BEEV::FatalError("CInterface: number of bits in a bvtype must be a positive integer:",
- b->CreateNode(BEEV::UNDEFINED));
-
- node e = b->CreateBVConst(32, num_bits);
- nodestar output = new node(b->CreateNode(BEEV::BITVECTOR,e));
- //if(cinterface_exprdelete_on) created_exprs.push_back(output);
- return output;
-}
-
-Type vc_bv32Type(VC vc) {
- return vc_bvType(vc,32);
-}
-
-
-Expr vc_bvConstExprFromStr(VC vc, char* binary_repr) {
- bmstar b = (bmstar)vc;
-
- node n = b->CreateBVConst(binary_repr,2);
- b->BVTypeCheck(n);
- nodestar output = new node(n);
- //if(cinterface_exprdelete_on) created_exprs.push_back(output);
- return output;
-}
-
-Expr vc_bvConstExprFromInt(VC vc,
- int n_bits,
- unsigned int value) {
- bmstar b = (bmstar)vc;
-
- unsigned long long int v = (unsigned long long int)value;
- node n = b->CreateBVConst(n_bits, v);
- b->BVTypeCheck(n);
- nodestar output = new node(n);
- //if(cinterface_exprdelete_on) created_exprs.push_back(output);
- return output;
-}
-
-Expr vc_bvConstExprFromLL(VC vc,
- int n_bits,
- unsigned long long value) {
- bmstar b = (bmstar)vc;
-
- node n = b->CreateBVConst(n_bits, value);
- b->BVTypeCheck(n);
- nodestar output = new node(n);
- //if(cinterface_exprdelete_on) created_exprs.push_back(output);
- return output;
-}
-
-Expr vc_bvConcatExpr(VC vc, Expr left, Expr right) {
- bmstar b = (bmstar)vc;
- nodestar l = (nodestar)left;
- nodestar r = (nodestar)right;
-
- b->BVTypeCheck(*l);
- b->BVTypeCheck(*r);
- node o =
- b->CreateTerm(BEEV::BVCONCAT,
- l->GetValueWidth()+ r->GetValueWidth(),*l,*r);
- b->BVTypeCheck(o);
- nodestar output = new node(o);
- //if(cinterface_exprdelete_on) created_exprs.push_back(output);
- return output;
-}
-
-Expr vc_bvPlusExpr(VC vc, int n_bits, Expr left, Expr right){
- bmstar b = (bmstar)vc;
- nodestar l = (nodestar)left;
- nodestar r = (nodestar)right;
-
- b->BVTypeCheck(*l);
- b->BVTypeCheck(*r);
- node o = b->CreateTerm(BEEV::BVPLUS,n_bits, *l, *r);
- b->BVTypeCheck(o);
- nodestar output = new node(o);
- //if(cinterface_exprdelete_on) created_exprs.push_back(output);
- return output;
-}
-
-
-Expr vc_bv32PlusExpr(VC vc, Expr left, Expr right) {
- return vc_bvPlusExpr(vc, 32, left, right);
-}
-
-
-Expr vc_bvMinusExpr(VC vc, int n_bits, Expr left, Expr right) {
- bmstar b = (bmstar)vc;
- nodestar l = (nodestar)left;
- nodestar r = (nodestar)right;
-
- b->BVTypeCheck(*l);
- b->BVTypeCheck(*r);
- node o = b->CreateTerm(BEEV::BVSUB,n_bits, *l, *r);
- b->BVTypeCheck(o);
- nodestar output = new node(o);
- //if(cinterface_exprdelete_on) created_exprs.push_back(output);
- return output;
-}
-
-
-Expr vc_bv32MinusExpr(VC vc, Expr left, Expr right) {
- return vc_bvMinusExpr(vc, 32, left, right);
-}
-
-
-Expr vc_bvMultExpr(VC vc, int n_bits, Expr left, Expr right) {
- bmstar b = (bmstar)vc;
- nodestar l = (nodestar)left;
- nodestar r = (nodestar)right;
-
- b->BVTypeCheck(*l);
- b->BVTypeCheck(*r);
- node o = b->CreateTerm(BEEV::BVMULT,n_bits, *l, *r);
- b->BVTypeCheck(o);
- nodestar output = new node(o);
- //if(cinterface_exprdelete_on) created_exprs.push_back(output);
- return output;
-}
-
-Expr vc_bvDivExpr(VC vc, int n_bits, Expr left, Expr right) {
- bmstar b = (bmstar)vc;
- nodestar l = (nodestar)left;
- nodestar r = (nodestar)right;
-
- b->BVTypeCheck(*l);
- b->BVTypeCheck(*r);
- node o = b->CreateTerm(BEEV::BVDIV,n_bits, *l, *r);
- b->BVTypeCheck(o);
- nodestar output = new node(o);
- //if(cinterface_exprdelete_on) created_exprs.push_back(output);
- return output;
-}
-
-Expr vc_bvModExpr(VC vc, int n_bits, Expr left, Expr right) {
- bmstar b = (bmstar)vc;
- nodestar l = (nodestar)left;
- nodestar r = (nodestar)right;
-
- b->BVTypeCheck(*l);
- b->BVTypeCheck(*r);
- node o = b->CreateTerm(BEEV::BVMOD,n_bits, *l, *r);
- b->BVTypeCheck(o);
- nodestar output = new node(o);
- //if(cinterface_exprdelete_on) created_exprs.push_back(output);
- return output;
-}
-
-Expr vc_sbvDivExpr(VC vc, int n_bits, Expr left, Expr right) {
- bmstar b = (bmstar)vc;
- nodestar l = (nodestar)left;
- nodestar r = (nodestar)right;
-
- b->BVTypeCheck(*l);
- b->BVTypeCheck(*r);
- node o = b->CreateTerm(BEEV::SBVDIV,n_bits, *l, *r);
- b->BVTypeCheck(o);
- nodestar output = new node(o);
- //if(cinterface_exprdelete_on) created_exprs.push_back(output);
- return output;
-}
-
-Expr vc_sbvModExpr(VC vc, int n_bits, Expr left, Expr right) {
- bmstar b = (bmstar)vc;
- nodestar l = (nodestar)left;
- nodestar r = (nodestar)right;
-
- b->BVTypeCheck(*l);
- b->BVTypeCheck(*r);
- node o = b->CreateTerm(BEEV::SBVMOD,n_bits, *l, *r);
- b->BVTypeCheck(o);
- nodestar output = new node(o);
- //if(cinterface_exprdelete_on) created_exprs.push_back(output);
- return output;
-}
-
-Expr vc_bv32MultExpr(VC vc, Expr left, Expr right) {
- return vc_bvMultExpr(vc, 32, left, right);
-}
-
-
-// unsigned comparators
-Expr vc_bvLtExpr(VC vc, Expr left, Expr right) {
- bmstar b = (bmstar)vc;
- nodestar l = (nodestar)left;
- nodestar r = (nodestar)right;
-
- b->BVTypeCheck(*l);
- b->BVTypeCheck(*r);
- node o = b->CreateNode(BEEV::BVLT, *l, *r);
- b->BVTypeCheck(o);
- nodestar output = new node(o);
- //if(cinterface_exprdelete_on) created_exprs.push_back(output);
- return output;
-}
-
-Expr vc_bvLeExpr(VC vc, Expr left, Expr right) {
- bmstar b = (bmstar)vc;
- nodestar l = (nodestar)left;
- nodestar r = (nodestar)right;
-
- b->BVTypeCheck(*l);
- b->BVTypeCheck(*r);
- node o = b->CreateNode(BEEV::BVLE, *l, *r);
- b->BVTypeCheck(o);
- nodestar output = new node(o);
- //if(cinterface_exprdelete_on) created_exprs.push_back(output);
- return output;
-}
-
-Expr vc_bvGtExpr(VC vc, Expr left, Expr right) {
- bmstar b = (bmstar)vc;
- nodestar l = (nodestar)left;
- nodestar r = (nodestar)right;
-
- b->BVTypeCheck(*l);
- b->BVTypeCheck(*r);
- node o = b->CreateNode(BEEV::BVGT, *l, *r);
- b->BVTypeCheck(o);
- nodestar output = new node(o);
- //if(cinterface_exprdelete_on) created_exprs.push_back(output);
- return output;
-}
-
-Expr vc_bvGeExpr(VC vc, Expr left, Expr right) {
- bmstar b = (bmstar)vc;
- nodestar l = (nodestar)left;
- nodestar r = (nodestar)right;
-
- b->BVTypeCheck(*l);
- b->BVTypeCheck(*r);
- node o = b->CreateNode(BEEV::BVGE, *l, *r);
- b->BVTypeCheck(o);
- nodestar output = new node(o);
- //if(cinterface_exprdelete_on) created_exprs.push_back(output);
- return output;
-}
-
-// signed comparators
-Expr vc_sbvLtExpr(VC vc, Expr left, Expr right) {
- bmstar b = (bmstar)vc;
- nodestar l = (nodestar)left;
- nodestar r = (nodestar)right;
-
- b->BVTypeCheck(*l);
- b->BVTypeCheck(*r);
- node o = b->CreateNode(BEEV::BVSLT, *l, *r);
- b->BVTypeCheck(o);
- nodestar output = new node(o);
- //if(cinterface_exprdelete_on) created_exprs.push_back(output);
- return output;
-}
-
-Expr vc_sbvLeExpr(VC vc, Expr left, Expr right) {
- bmstar b = (bmstar)vc;
- nodestar l = (nodestar)left;
- nodestar r = (nodestar)right;
-
- b->BVTypeCheck(*l);
- b->BVTypeCheck(*r);
- node o = b->CreateNode(BEEV::BVSLE, *l, *r);
- b->BVTypeCheck(o);
- nodestar output = new node(o);
- //if(cinterface_exprdelete_on) created_exprs.push_back(output);
- return output;
-}
-
-Expr vc_sbvGtExpr(VC vc, Expr left, Expr right) {
- bmstar b = (bmstar)vc;
- nodestar l = (nodestar)left;
- nodestar r = (nodestar)right;
-
- b->BVTypeCheck(*l);
- b->BVTypeCheck(*r);
- node o = b->CreateNode(BEEV::BVSGT, *l, *r);
- b->BVTypeCheck(o);
- nodestar output = new node(o);
- //if(cinterface_exprdelete_on) created_exprs.push_back(output);
- return output;
-}
-
-Expr vc_sbvGeExpr(VC vc, Expr left, Expr right) {
- bmstar b = (bmstar)vc;
- nodestar l = (nodestar)left;
- nodestar r = (nodestar)right;
-
- b->BVTypeCheck(*l);
- b->BVTypeCheck(*r);
- node o = b->CreateNode(BEEV::BVSGE, *l, *r);
- b->BVTypeCheck(o);
- nodestar output = new node(o);
- //if(cinterface_exprdelete_on) created_exprs.push_back(output);
- return output;
-}
-
-Expr vc_bvUMinusExpr(VC vc, Expr ccc) {
- bmstar b = (bmstar)vc;
- nodestar a = (nodestar)ccc;
- b->BVTypeCheck(*a);
-
- node o = b->CreateTerm(BEEV::BVUMINUS, a->GetValueWidth(), *a);
- b->BVTypeCheck(o);
- nodestar output = new node(o);
- //if(cinterface_exprdelete_on) created_exprs.push_back(output);
- return output;
-}
-
-// bitwise operations: these are terms not formulas
-Expr vc_bvAndExpr(VC vc, Expr left, Expr right) {
- bmstar b = (bmstar)vc;
- nodestar l = (nodestar)left;
- nodestar r = (nodestar)right;
-
- b->BVTypeCheck(*l);
- b->BVTypeCheck(*r);
- node o = b->CreateTerm(BEEV::BVAND, (*l).GetValueWidth(), *l, *r);
- b->BVTypeCheck(o);
- nodestar output = new node(o);
- //if(cinterface_exprdelete_on) created_exprs.push_back(output);
- return output;
-}
-
-Expr vc_bvOrExpr(VC vc, Expr left, Expr right) {
- bmstar b = (bmstar)vc;
- nodestar l = (nodestar)left;
- nodestar r = (nodestar)right;
-
- b->BVTypeCheck(*l);
- b->BVTypeCheck(*r);
- node o = b->CreateTerm(BEEV::BVOR, (*l).GetValueWidth(), *l, *r);
- b->BVTypeCheck(o);
- nodestar output = new node(o);
- //if(cinterface_exprdelete_on) created_exprs.push_back(output);
- return output;
-}
-
-Expr vc_bvXorExpr(VC vc, Expr left, Expr right) {
- bmstar b = (bmstar)vc;
- nodestar l = (nodestar)left;
- nodestar r = (nodestar)right;
-
- b->BVTypeCheck(*l);
- b->BVTypeCheck(*r);
- node o = b->CreateTerm(BEEV::BVXOR, (*l).GetValueWidth(), *l, *r);
- b->BVTypeCheck(o);
- nodestar output = new node(o);
- //if(cinterface_exprdelete_on) created_exprs.push_back(output);
- return output;
-}
-
-Expr vc_bvNotExpr(VC vc, Expr ccc) {
- bmstar b = (bmstar)vc;
- nodestar a = (nodestar)ccc;
-
- b->BVTypeCheck(*a);
- node o = b->CreateTerm(BEEV::BVNEG, a->GetValueWidth(), *a);
- b->BVTypeCheck(o);
- nodestar output = new node(o);
- //if(cinterface_exprdelete_on) created_exprs.push_back(output);
- return output;
-}
-
-Expr vc_bvLeftShiftExpr(VC vc, int sh_amt, Expr ccc) {
- bmstar b = (bmstar)vc;
- nodestar a = (nodestar)ccc;
- b->BVTypeCheck(*a);
-
- //convert leftshift to bvconcat
- if(0 != sh_amt) {
- node len = b->CreateBVConst(sh_amt, 0);
- node o = b->CreateTerm(BEEV::BVCONCAT, a->GetValueWidth() + sh_amt, *a, len);
- b->BVTypeCheck(o);
- nodestar output = new node(o);
- //if(cinterface_exprdelete_on) created_exprs.push_back(output);
- return output;
- }
- else
- return a;
-}
-
-Expr vc_bvRightShiftExpr(VC vc, int sh_amt, Expr ccc) {
- bmstar b = (bmstar)vc;
- nodestar a = (nodestar)ccc;
- b->BVTypeCheck(*a);
-
- unsigned int w = a->GetValueWidth();
- //the amount by which you are rightshifting
- //is less-than/equal-to the length of input
- //bitvector
- if(0 < (unsigned)sh_amt && (unsigned)sh_amt <= w) {
- node len = b->CreateBVConst(sh_amt, 0);
- node hi = b->CreateBVConst(32,w-1);
- node low = b->CreateBVConst(32,sh_amt);
- node extract = b->CreateTerm(BEEV::BVEXTRACT,w-sh_amt,*a,hi,low);
-
- node n = b->CreateTerm(BEEV::BVCONCAT, w,len, extract);
- b->BVTypeCheck(n);
- nodestar output = new node(n);
- //if(cinterface_exprdelete_on) created_exprs.push_back(output);
- return output;
- }
- else if(sh_amt == 0)
- return a;
- else {
- if(0== w)
- BEEV::FatalError("CInterface: vc_bvRightShiftExpr: cannot have a bitvector of length 0:",*a);
- nodestar output = new node(b->CreateBVConst(w,0));
- //if(cinterface_exprdelete_on) created_exprs.push_back(output);
- return output;
- }
-}
-
-/* Same as vc_bvLeftShift only that the answer in 32 bits long */
-Expr vc_bv32LeftShiftExpr(VC vc, int sh_amt, Expr child) {
- return vc_bvExtract(vc, vc_bvLeftShiftExpr(vc, sh_amt, child), 31, 0);
-}
-
-/* Same as vc_bvRightShift only that the answer in 32 bits long */
-Expr vc_bv32RightShiftExpr(VC vc, int sh_amt, Expr child) {
- return vc_bvExtract(vc, vc_bvRightShiftExpr(vc, sh_amt, child), 31, 0);
-}
-
-
-Expr vc_bvVar32LeftShiftExpr(VC vc, Expr sh_amt, Expr child) {
- Expr ifpart;
- Expr thenpart;
- Expr elsepart = vc_trueExpr(vc);
- Expr ite = vc_trueExpr(vc);
-
- for(int count=32; count >= 0; count--){
- if(count != 32) {
- ifpart = vc_eqExpr(vc, sh_amt,
- vc_bvConstExprFromInt(vc, 32, count));
- thenpart = vc_bvExtract(vc,
- vc_bvLeftShiftExpr(vc, count, child),
- 31, 0);
-
- ite = vc_iteExpr(vc,ifpart,thenpart,elsepart);
- elsepart = ite;
- }
- else
- elsepart = vc_bvConstExprFromInt(vc,32, 0);
- }
- return ite;
-}
-
-Expr vc_bvVar32DivByPowOfTwoExpr(VC vc, Expr child, Expr rhs) {
- Expr ifpart;
- Expr thenpart;
- Expr elsepart = vc_trueExpr(vc);
- Expr ite = vc_trueExpr(vc);
-
- for(int count=32; count >= 0; count--){
- if(count != 32) {
- ifpart = vc_eqExpr(vc, rhs,
- vc_bvConstExprFromInt(vc, 32, 1 << count));
- thenpart = vc_bvRightShiftExpr(vc, count, child);
- ite = vc_iteExpr(vc,ifpart,thenpart,elsepart);
- elsepart = ite;
- } else {
- elsepart = vc_bvConstExprFromInt(vc,32, 0);
- }
- }
- return ite;
-}
-
-Expr vc_bvVar32RightShiftExpr(VC vc, Expr sh_amt, Expr child) {
- Expr ifpart;
- Expr thenpart;
- Expr elsepart = vc_trueExpr(vc);
- Expr ite = vc_trueExpr(vc);
-
- for(int count=32; count >= 0; count--){
- if(count != 32) {
- ifpart = vc_eqExpr(vc, sh_amt,
- vc_bvConstExprFromInt(vc, 32, count));
- thenpart = vc_bvRightShiftExpr(vc, count, child);
- ite = vc_iteExpr(vc,ifpart,thenpart,elsepart);
- elsepart = ite;
- } else {
- elsepart = vc_bvConstExprFromInt(vc,32, 0);
- }
- }
- return ite;
-}
-
-Expr vc_bvExtract(VC vc, Expr ccc, int hi_num, int low_num) {
- bmstar b = (bmstar)vc;
- nodestar a = (nodestar)ccc;
- b->BVTypeCheck(*a);
-
- node hi = b->CreateBVConst(32,hi_num);
- node low = b->CreateBVConst(32,low_num);
- node o = b->CreateTerm(BEEV::BVEXTRACT,hi_num-low_num+1,*a,hi,low);
- b->BVTypeCheck(o);
- nodestar output = new node(o);
- //if(cinterface_exprdelete_on) created_exprs.push_back(output);
- return output;
-}
-
-Expr vc_bvBoolExtract(VC vc, Expr ccc, int bit_num) {
- bmstar b = (bmstar)vc;
- nodestar a = (nodestar)ccc;
- b->BVTypeCheck(*a);
-
- node bit = b->CreateBVConst(32,bit_num);
- //node o = b->CreateNode(BEEV::BVGETBIT,*a,bit);
- node zero = b->CreateBVConst(1,0);
- node oo = b->CreateTerm(BEEV::BVEXTRACT,1,*a,bit,bit);
- node o = b->CreateNode(BEEV::EQ,oo,zero);
- b->BVTypeCheck(o);
- nodestar output = new node(o);
- //if(cinterface_exprdelete_on) created_exprs.push_back(output);
- return output;
-}
-
-Expr vc_bvSignExtend(VC vc, Expr ccc, int nbits) {
- bmstar b = (bmstar)vc;
- nodestar a = (nodestar)ccc;
-
- //width of the expr which is being sign extended. nbits is the
- //resulting length of the signextended expr
- b->BVTypeCheck(*a);
-
- unsigned exprlen = a->GetValueWidth();
- unsigned outputlen = nbits;
- node n;
- if(exprlen >= outputlen) {
- //extract
- node hi = b->CreateBVConst(32,outputlen-1);
- node low = b->CreateBVConst(32,0);
- n = b->CreateTerm(BEEV::BVEXTRACT,nbits,*a,hi,low);
- b->BVTypeCheck(n);
- }
- else {
- //sign extend
- BEEV::ASTNode width = b->CreateBVConst(32,nbits);
- n = b->CreateTerm(BEEV::BVSX,nbits,*a, width);
- }
-
- b->BVTypeCheck(n);
- nodestar output = new node(n);
- //if(cinterface_exprdelete_on) created_exprs.push_back(output);
- return output;
-}
-
-//! Return an int from a constant bitvector expression
-int getBVInt(Expr e) {
- //bmstar b = (bmstar)vc;
- nodestar a = (nodestar)e;
-
- if(BEEV::BVCONST != a->GetKind())
- BEEV::FatalError("CInterface: getBVInt: Attempting to extract int value from a NON-constant BITVECTOR: ",*a);
- return (int)GetUnsignedConst(*a);
-}
-
-//! Return an unsigned int from a constant bitvector expression
-unsigned int getBVUnsigned(Expr e) {
- //bmstar b = (bmstar)vc;
- nodestar a = (nodestar)e;
-
- if(BEEV::BVCONST != a->GetKind())
- BEEV::FatalError("getBVUnsigned: Attempting to extract int value from a NON-constant BITVECTOR: ",*a);
- return (unsigned int)GetUnsignedConst(*a);
-}
-
-//! Return an unsigned long long int from a constant bitvector expression
-unsigned long long int getBVUnsignedLongLong(Expr e) {
- //bmstar b = (bmstar)vc;
- nodestar a = (nodestar)e;
-
- if(BEEV::BVCONST != a->GetKind())
- BEEV::FatalError("getBVUnsigned: Attempting to extract int value from a NON-constant BITVECTOR: ",*a);
-#ifdef NATIVE_C_ARITH
- return (unsigned long long int)a->GetBVConst();
-#else
- unsigned* bv = a->GetBVConst();
-
- char * str_bv = (char *)CONSTANTBV::BitVector_to_Bin(bv);
- unsigned long long int tmp = strtoull(str_bv,NULL,2);
- CONSTANTBV::BitVector_Dispose((unsigned char *)str_bv);
- return tmp;
-#endif
-}
-
-
-Expr vc_simplify(VC vc, Expr e) {
- bmstar b = (bmstar)vc;
- nodestar a = (nodestar)e;
-
- if(BEEV::BOOLEAN_TYPE == a->GetType()) {
- nodestar output = new node(b->SimplifyFormula_TopLevel(*a,false));
- //if(cinterface_exprdelete_on) created_exprs.push_back(output);
- b->Begin_RemoveWrites = true;
- output = new node(b->SimplifyFormula_TopLevel(*output,false));
- b->Begin_RemoveWrites = false;
- return output;
- }
- else {
- nodestar output = new node(b->SimplifyTerm(*a));
- //if(cinterface_exprdelete_on) created_exprs.push_back(output);
- b->Begin_RemoveWrites = true;
- output = new node(b->SimplifyTerm(*output));
- b->Begin_RemoveWrites = false;
- return output;
- }
-}
-
-/* C pointer support: C interface to support C memory arrays in CVCL */
-Expr vc_bvCreateMemoryArray(VC vc, char * arrayName) {
- Type bv8 = vc_bvType(vc,8);
- Type bv32 = vc_bvType(vc,32);
-
- Type malloced_mem0 = vc_arrayType(vc,bv32,bv8);
- return vc_varExpr(vc, arrayName, malloced_mem0);
-}
-
-Expr vc_bvReadMemoryArray(VC vc,
- Expr array,
- Expr byteIndex, int numOfBytes) {
- if(!(numOfBytes > 0))
- BEEV::FatalError("numOfBytes must be greater than 0");
-
- if(numOfBytes == 1)
- return vc_readExpr(vc,array,byteIndex);
- else {
- int count = 1;
- 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)))/*)*/;
- a = vc_bvConcatExpr(vc,b,a);
- count++;
- }
- return a;
- }
-}
-
-Expr vc_bvWriteToMemoryArray(VC vc,
- 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);
- else {
- int count = 1;
- int hi = newBitsPerElem - 1;
- int low = newBitsPerElem - 8;
- int low_elem = 0;
- int hi_elem = low_elem + 7;
- Expr c = vc_bvExtract(vc, element, hi_elem, low_elem);
- Expr newarray = vc_writeExpr(vc, array, byteIndex, c);
- while(--numOfBytes > 0) {
- hi = low-1;
- low = low-8;
-
- low_elem = low_elem + 8;
- hi_elem = low_elem + 7;
-
- 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);
- count++;
- }
- return newarray;
- }
-}
-
-Expr vc_bv32ConstExprFromInt(VC vc, unsigned int value){
- return vc_bvConstExprFromInt(vc, 32, 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);
-}
-#endif
-
-char* exprString(Expr e){
- stringstream ss;
- ((nodestar)e)->PL_Print(ss,0);
- string s = ss.str();
- char *copy = strdup(s.c_str());
- return copy;
-}
-
-char* typeString(Type t){
- stringstream ss;
- ((nodestar)t)->PL_Print(ss,0);
-
- string s = ss.str();
- char *copy = strdup(s.c_str());
- return copy;
-}
-
-Expr getChild(Expr e, int i){
- nodestar a = (nodestar)e;
-
- BEEV::ASTVec c = a->GetChildren();
- if ((unsigned)i < c.size()) {
- BEEV::ASTNode o = c[i];
- nodestar output = new node(o);
- //if(cinterface_exprdelete_on) created_exprs.push_back(output);
- return output;
- }
- else
- BEEV::FatalError("getChild: Error accessing childNode in expression: ",*a);
- return a;
-}
-
-void vc_registerErrorHandler(void (*error_hdlr)(const char* err_msg)) {
- BEEV::vc_error_hdlr = error_hdlr;
-}
-
-
-int vc_getHashQueryStateToBuffer(VC vc, Expr query) {
- assert(vc);
- assert(query);
- bmstar b = (bmstar)vc;
- nodestar qry = (nodestar)query;
- BEEV::ASTVec v = b->GetAsserts();
- BEEV::ASTNode out = b->CreateNode(BEEV::AND,b->CreateNode(BEEV::NOT,*qry),v);
- return out.Hash();
-}
-
-Type vc_getType(VC vc, Expr ex) {
- nodestar e = (nodestar)ex;
-
- switch(e->GetType()) {
- case BEEV::BOOLEAN_TYPE:
- return vc_boolType(vc);
- break;
- case BEEV::BITVECTOR_TYPE:
- return vc_bvType(vc,e->GetValueWidth());
- break;
- case BEEV::ARRAY_TYPE: {
- Type typeindex = vc_bvType(vc,e->GetIndexWidth());
- Type typedata = vc_bvType(vc,e->GetValueWidth());
- return vc_arrayType(vc,typeindex,typedata);
- break;
- }
- default:
- BEEV::FatalError("c_interface: vc_GetType: expression with bad typing: please check your expression construction");
- return vc_boolType(vc);
- break;
- }
-}// end of vc_gettype()
-
-//!if e is TRUE then return 1; if e is FALSE then return 0; otherwise
-//return -1
-int vc_isBool(Expr e) {
- nodestar input = (nodestar)e;
- if(BEEV::TRUE == input->GetKind()) {
- return 1;
- }
-
- if(BEEV::FALSE == input->GetKind()) {
- return 0;
- }
-
- return -1;
-}
-
-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++) {
- // BEEV::ASTNode * aaa = *it;
- // delete aaa;
- // }
- delete decls;
- delete b;
-}
-
-void vc_DeleteExpr(Expr e) {
- nodestar input = (nodestar)e;
- //bmstar b = (bmstar)vc;
- delete input;
-}
-
-exprkind_t getExprKind(Expr e) {
- nodestar input = (nodestar)e;
- return (exprkind_t)(input->GetKind());
-}
-
-int getDegree (Expr e) {
- nodestar input = (nodestar)e;
- return input->Degree();
-}
-
-int getBVLength(Expr ex) {
- nodestar e = (nodestar)ex;
-
- if(BEEV::BITVECTOR_TYPE != e->GetType()) {
- BEEV::FatalError("c_interface: vc_GetBVLength: Input expression must be a bit-vector");
- }
-
- return e->GetValueWidth();
-}
-
-type_t getType (Expr ex) {
- nodestar e = (nodestar)ex;
-
- return (type_t)(e->GetType());
-}
-
-int getVWidth (Expr ex) {
- nodestar e = (nodestar)ex;
-
- return e->GetValueWidth();
-}
-
-int getIWidth (Expr ex) {
- nodestar e = (nodestar)ex;
-
- return e->GetIndexWidth();
-}
-
-void vc_printCounterExampleFile(VC vc, int fd) {
- fdostream os(fd);
- bmstar b = (bmstar)vc;
- BEEV::print_counterexample = true;
- os << "COUNTEREXAMPLE BEGIN: \n";
- b->PrintCounterExample(true, os);
- os << "COUNTEREXAMPLE END: \n";
-}
-
-const char* exprName(Expr e){
- return ((nodestar)e)->GetName();
-}
-
-int getExprID (Expr ex) {
- BEEV::ASTNode q = (*(nodestar)ex);
-
- return q.GetNodeNum();
-}
diff --git a/stp/c_interface/c_interface.h b/stp/c_interface/c_interface.h
deleted file mode 100644
index a2fa8cd7..00000000
--- a/stp/c_interface/c_interface.h
+++ /dev/null
@@ -1,401 +0,0 @@
-/********************************************************************
- * AUTHORS: Vijay Ganesh, David L. Dill
- *
- * BEGIN DATE: November, 2005
- *
- * License to use, copy, modify, sell and/or distribute this software
- * and its documentation for any purpose is hereby granted without
- * royalty, subject to the terms and conditions defined in the \ref
- * LICENSE file provided with this distribution. In particular:
- *
- * - The above copyright notice and this permission notice must appear
- * in all copies of the software and related documentation.
- *
- * - THE SOFTWARE IS PROVIDED "AS-IS", WITHOUT ANY WARRANTIES,
- * EXPRESSED OR IMPLIED. USE IT AT YOUR OWN RISK.
- ********************************************************************/
-// -*- c++ -*-
-#ifndef _cvcl__include__c_interface_h_
-#define _cvcl__include__c_interface_h_
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#ifdef STP_STRONG_TYPING
-#else
- //This gives absolutely no pointer typing at compile-time. Most C
- //users prefer this over stronger typing. User is the king. A
- //stronger typed interface is in the works.
- typedef void* VC;
- typedef void* Expr;
- typedef void* Type;
- typedef void* WholeCounterExample;
-#endif
-
- // o : optimizations
- // c : check counterexample
- // p : print counterexample
- // h : help
- // s : stats
- // v : print nodes
- void vc_setFlags(char c);
-
- //! Flags can be NULL
- VC vc_createValidityChecker(void);
-
- // Basic types
- Type vc_boolType(VC vc);
-
- //! Create an array type
- Type vc_arrayType(VC vc, Type typeIndex, Type typeData);
-
- /////////////////////////////////////////////////////////////////////////////
- // Expr manipulation methods //
- /////////////////////////////////////////////////////////////////////////////
-
- //! Create a variable with a given name and type
- /*! The type cannot be a function type. The var name can contain
- only variables, numerals and underscore. If you use any other
- symbol, you will get a segfault. */
- Expr vc_varExpr(VC vc, char * name, Type type);
-
- //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);
-
- //! Get the expression and type associated with a name.
- /*! If there is no such Expr, a NULL Expr is returned. */
- //Expr vc_lookupVar(VC vc, char* name, Type* type);
-
- //! Get the type of the Expr.
- Type vc_getType(VC vc, Expr e);
-
- int vc_getBVLength(VC vc, Expr e);
-
- //! Create an equality expression. The two children must have the same type.
- Expr vc_eqExpr(VC vc, Expr child0, Expr child1);
-
- // Boolean expressions
-
- // The following functions create Boolean expressions. The children
- // provided as arguments must be of type Boolean (except for the
- // function vc_iteExpr(). In the case of vc_iteExpr() the
- // conditional must always be Boolean, but the ifthenpart
- // (resp. elsepart) can be bit-vector or Boolean type. But, the
- // ifthenpart and elsepart must be both of the same type)
- Expr vc_trueExpr(VC vc);
- Expr vc_falseExpr(VC vc);
- Expr vc_notExpr(VC vc, Expr child);
- Expr vc_andExpr(VC vc, Expr left, Expr right);
- Expr vc_andExprN(VC vc, Expr* children, int numOfChildNodes);
- Expr vc_orExpr(VC vc, Expr left, Expr right);
- Expr vc_orExprN(VC vc, Expr* children, int numOfChildNodes);
- Expr vc_impliesExpr(VC vc, Expr hyp, Expr conc);
- Expr vc_iffExpr(VC vc, Expr left, Expr right);
- //The output type of vc_iteExpr can be Boolean (formula-level ite)
- //or bit-vector (word-level ite)
- Expr vc_iteExpr(VC vc, Expr conditional, Expr ifthenpart, Expr elsepart);
-
- //Boolean to single bit BV Expression
- Expr vc_boolToBVExpr(VC vc, Expr form);
-
- // Arrays
-
- //! Create an expression for the value of array at the given index
- Expr vc_readExpr(VC vc, Expr array, Expr index);
-
- //! Array update; equivalent to "array WITH [index] := newValue"
- Expr vc_writeExpr(VC vc, Expr array, Expr index, Expr newValue);
-
- // Expr I/O
- //! Expr vc_parseExpr(VC vc, char* s);
-
- //! Prints 'e' to stdout.
- void vc_printExpr(VC vc, Expr e);
-
- //! Prints 'e' into an open file descriptor 'fd'
- void vc_printExprFile(VC vc, Expr e, int fd);
-
- //! Prints state of 'vc' into malloc'd buffer '*buf' and stores the
- // length into '*len'. It is the responsibility of the caller to
- // free the buffer.
- //void vc_printStateToBuffer(VC vc, char **buf, unsigned long *len);
-
- //! Prints 'e' to malloc'd buffer '*buf'. Sets '*len' to the length of
- // the buffer. It is the responsibility of the caller to free the buffer.
- void vc_printExprToBuffer(VC vc, Expr e, char **buf, unsigned long * len);
-
- //! Prints counterexample to stdout.
- void vc_printCounterExample(VC vc);
-
- //! Prints variable declarations to stdout.
- void vc_printVarDecls(VC vc);
-
- //! Prints asserts to stdout. The flag simplify_print must be set to
- //"1" if you wish simplification to occur dring printing. It must be
- //set to "0" otherwise
- void vc_printAsserts(VC vc, int simplify_print);
-
- //! Prints the state of the query to malloc'd buffer '*buf' and
- //stores ! the length of the buffer to '*len'. It is the
- //responsibility of the caller to free the buffer. The flag
- //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);
-
- //! Similar to vc_printQueryStateToBuffer()
- void vc_printCounterExampleToBuffer(VC vc, char **buf,unsigned long *len);
-
- //! Prints query to stdout.
- void vc_printQuery(VC vc);
-
- /////////////////////////////////////////////////////////////////////////////
- // Context-related methods //
- /////////////////////////////////////////////////////////////////////////////
-
- //! Assert a new formula in the current context.
- /*! The formula must have Boolean type. */
- void vc_assertFormula(VC vc, Expr e);
-
- //! Simplify e with respect to the current context
- Expr vc_simplify(VC vc, Expr e);
-
- //! Check validity of e in the current context. e must be a FORMULA
- //
- //if returned 0 then input is INVALID.
- //
- //if returned 1 then input is VALID
- //
- //if returned 2 then ERROR
- int vc_query(VC vc, Expr e);
-
- //! Return the counterexample after a failed query.
- Expr vc_getCounterExample(VC vc, Expr e);
-
- //! get size of counterexample, i.e. the number of variables/array
- //locations in the counterexample.
- int vc_counterexample_size(VC vc);
-
- //! Checkpoint the current context and increase the scope level
- void vc_push(VC vc);
-
- //! Restore the current context to its state at the last checkpoint
- void vc_pop(VC vc);
-
- //! Return an int from a constant bitvector expression
- int getBVInt(Expr e);
- //! Return an unsigned int from a constant bitvector expression
- unsigned int getBVUnsigned(Expr e);
- //! Return an unsigned long long int from a constant bitvector expressions
- unsigned long long int getBVUnsignedLongLong(Expr e);
-
- /**************************/
- /* BIT VECTOR OPERATIONS */
- /**************************/
- Type vc_bvType(VC vc, int no_bits);
- Type vc_bv32Type(VC vc);
-
- 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);
- Expr vc_bv32ConstExprFromInt(VC vc, unsigned int value);
-
- Expr vc_bvConcatExpr(VC vc, Expr left, Expr right);
- Expr vc_bvPlusExpr(VC vc, int n_bits, Expr left, Expr right);
- Expr vc_bv32PlusExpr(VC vc, Expr left, Expr right);
- Expr vc_bvMinusExpr(VC vc, int n_bits, Expr left, Expr right);
- Expr vc_bv32MinusExpr(VC vc, Expr left, Expr right);
- Expr vc_bvMultExpr(VC vc, int n_bits, Expr left, Expr right);
- Expr vc_bv32MultExpr(VC vc, Expr left, Expr right);
- // left divided by right i.e. left/right
- Expr vc_bvDivExpr(VC vc, int n_bits, Expr left, Expr right);
- // left modulo right i.e. left%right
- Expr vc_bvModExpr(VC vc, int n_bits, Expr left, Expr right);
- // signed left divided by right i.e. left/right
- Expr vc_sbvDivExpr(VC vc, int n_bits, Expr left, Expr right);
- // signed left modulo right i.e. left%right
- Expr vc_sbvModExpr(VC vc, int n_bits, Expr left, Expr right);
-
- Expr vc_bvLtExpr(VC vc, Expr left, Expr right);
- Expr vc_bvLeExpr(VC vc, Expr left, Expr right);
- Expr vc_bvGtExpr(VC vc, Expr left, Expr right);
- Expr vc_bvGeExpr(VC vc, Expr left, Expr right);
-
- Expr vc_sbvLtExpr(VC vc, Expr left, Expr right);
- Expr vc_sbvLeExpr(VC vc, Expr left, Expr right);
- Expr vc_sbvGtExpr(VC vc, Expr left, Expr right);
- Expr vc_sbvGeExpr(VC vc, Expr left, Expr right);
-
- Expr vc_bvUMinusExpr(VC vc, Expr child);
-
- // bitwise operations: these are terms not formulas
- Expr vc_bvAndExpr(VC vc, Expr left, Expr right);
- Expr vc_bvOrExpr(VC vc, Expr left, Expr right);
- Expr vc_bvXorExpr(VC vc, Expr left, Expr right);
- Expr vc_bvNotExpr(VC vc, Expr child);
-
- Expr vc_bvLeftShiftExpr(VC vc, int sh_amt, Expr child);
- Expr vc_bvRightShiftExpr(VC vc, int sh_amt, Expr child);
- /* Same as vc_bvLeftShift only that the answer in 32 bits long */
- Expr vc_bv32LeftShiftExpr(VC vc, int sh_amt, Expr child);
- /* Same as vc_bvRightShift only that the answer in 32 bits long */
- Expr vc_bv32RightShiftExpr(VC vc, int sh_amt, Expr child);
- Expr vc_bvVar32LeftShiftExpr(VC vc, Expr sh_amt, Expr child);
- Expr vc_bvVar32RightShiftExpr(VC vc, Expr sh_amt, Expr child);
- Expr vc_bvVar32DivByPowOfTwoExpr(VC vc, Expr child, Expr rhs);
-
- Expr vc_bvExtract(VC vc, Expr child, int high_bit_no, int low_bit_no);
-
- //accepts a bitvector and position, and returns a boolean
- //corresponding to that position. More precisely, it return the
- //equation (x[bit_no:bit_no] = 0)
- //FIXME = 1 ?
- Expr vc_bvBoolExtract(VC vc, Expr x, int bit_no);
- Expr vc_bvSignExtend(VC vc, Expr child, int nbits);
-
- /*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 vc_bvWriteToMemoryArray(VC vc,
- 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
- // for deallocating the string with free()
- char* exprString(Expr e);
-
- // return a string representation of the Type t. The caller is responsible
- // for deallocating the string with free()
- char* typeString(Type t);
-
- Expr getChild(Expr e, int i);
-
- //1.if input expr is TRUE then the function returns 1;
- //
- //2.if input expr is FALSE then function returns 0;
- //
- //3.otherwise the function returns -1
- int vc_isBool(Expr e);
-
- /* Register the given error handler to be called for each fatal error.*/
- void vc_registerErrorHandler(void (*error_hdlr)(const char* err_msg));
-
- int vc_getHashQueryStateToBuffer(VC vc, Expr query);
-
- //destroys the STP instance, and removes all the created expressions
- void vc_Destroy(VC vc);
-
- //deletes the expression e
- void vc_DeleteExpr(Expr e);
-
- //Get the whole counterexample from the current context
- WholeCounterExample vc_getWholeCounterExample(VC vc);
-
- //Get the value of a term expression from the CounterExample
- Expr vc_getTermFromCounterExample(VC vc, Expr e, WholeCounterExample 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,
- SBVMOD,
- 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
- };
-
- // get the kind of the expression
- exprkind_t getExprKind (Expr e);
-
- // get the number of children nodes
- int getDegree (Expr e);
-
- // get the bv length
- int getBVLength(Expr e);
-
- // get expression type
- type_t getType (Expr e);
-
- // get value bit width
- int getVWidth (Expr e);
-
- // get index bit width
- int getIWidth (Expr e);
-
- // Prints counterexample to an open file descriptor 'fd'
- void vc_printCounterExampleFile(VC vc, int fd);
-
- // get name of expression. must be a variable.
- const char* exprName(Expr e);
-
- // get the node ID of an Expr.
- int getExprID (Expr ex);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
-
-
diff --git a/stp/c_interface/fdstream.h b/stp/c_interface/fdstream.h
deleted file mode 100644
index 2cff613c..00000000
--- a/stp/c_interface/fdstream.h
+++ /dev/null
@@ -1,186 +0,0 @@
-/*! @brief The following code declares classes to read from and write to
- * file descriptore or file handles.
- *
- * See
- * http://www.josuttis.com/cppcode
- * for details and the latest version.
- *
- * - open:
- * - integrating BUFSIZ on some systems?
- * - optimized reading of multiple characters
- * - stream for reading AND writing
- * - i18n
- *
- * (C) Copyright Nicolai M. Josuttis 2001.
- * Permission to copy, use, modify, sell and distribute this software
- * is granted provided this copyright notice appears in all copies.
- * This software is provided "as is" without express or implied
- * warranty, and with no claim as to its suitability for any purpose.
- *
- * Version: Jul 28, 2002
- * History:
- * Jul 28, 2002: bugfix memcpy() => memmove()
- * fdinbuf::underflow(): cast for return statements
- * Aug 05, 2001: first public version
- */
-#ifndef BOOST_FDSTREAM_HPP
-#define BOOST_FDSTREAM_HPP
-
-#include <istream>
-#include <ostream>
-#include <streambuf>
-
-
-// for EOF:
-#include <cstdio>
-// for memmove():
-#include <cstring>
-
-
-// low-level read and write functions
-#ifdef _MSC_VER
-# include <io.h>
-#else
-# include <unistd.h>
-//extern "C" {
-// int write (int fd, const char* buf, int num);
-// int read (int fd, char* buf, int num);
-//}
-#endif
-
-
-// BEGIN namespace BOOST
-namespace std {
-
-
-/************************************************************
- * fdostream
- * - a stream that writes on a file descriptor
- ************************************************************/
-
-
-class fdoutbuf : public std::streambuf {
- protected:
- int fd; // file descriptor
- public:
- // constructor
- fdoutbuf (int _fd) : fd(_fd) {
- }
- 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;
- }
- }
- return c;
- }
- // write multiple characters
- virtual
- std::streamsize xsputn (const char* s,
- std::streamsize num) {
- return write(fd,s,num);
- }
-};
-
-class fdostream : public std::ostream {
- protected:
- fdoutbuf buf;
- public:
- fdostream (int fd) : std::ostream(0), buf(fd) {
- rdbuf(&buf);
- }
-};
-
-
-/************************************************************
- * fdistream
- * - a stream that reads on a file descriptor
- ************************************************************/
-
-class fdinbuf : public std::streambuf {
- protected:
- int fd; // file descriptor
- protected:
- /* data buffer:
- * - at most, pbSize characters in putback area plus
- * - at most, bufSize characters in ordinary read buffer
- */
- static const int pbSize = 4; // size of putback area
- static const int bufSize = 1024; // size of the data buffer
- char buffer[bufSize+pbSize]; // data buffer
-
- public:
- /* constructor
- * - initialize file descriptor
- * - initialize empty data buffer
- * - no putback area
- * => force underflow()
- */
- fdinbuf (int _fd) : fd(_fd) {
- 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;
-#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
- return traits_type::to_int_type(*gptr());
- }
-};
-
-class fdistream : public std::istream {
- protected:
- fdinbuf buf;
- public:
- fdistream (int fd) : std::istream(0), buf(fd) {
- rdbuf(&buf);
- }
-};
-
-
-} // END namespace boost
-
-#endif /*BOOST_FDSTREAM_HPP*/
diff --git a/stp/constantbv/Makefile b/stp/constantbv/Makefile
deleted file mode 100644
index ee8155cf..00000000
--- a/stp/constantbv/Makefile
+++ /dev/null
@@ -1,16 +0,0 @@
-#===-- stp/constantbv/Makefile -----------------------------*- Makefile -*--===#
-#
-# The KLEE Symbolic Virtual Machine
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-#===------------------------------------------------------------------------===#
-
-LEVEL=../..
-
-LIBRARYNAME=stp_constantbv
-DONT_BUILD_RELINKED=1
-BUILD_ARCHIVE=1
-
-include $(LEVEL)/Makefile.common
diff --git a/stp/constantbv/constantbv.cpp b/stp/constantbv/constantbv.cpp
deleted file mode 100644
index e01fa0ac..00000000
--- a/stp/constantbv/constantbv.cpp
+++ /dev/null
@@ -1,3571 +0,0 @@
-/*****************************************************************************/
-/* AUTHOR: */
-/*****************************************************************************/
-/* */
-/* Steffen Beyer */
-/* mailto:sb@engelschall.com */
-/* http://www.engelschall.com/u/sb/download/ */
-/* */
-/*****************************************************************************/
-/* COPYRIGHT: */
-/*****************************************************************************/
-/* */
-/* Copyright (c) 1995 - 2004 by Steffen Beyer. */
-/* All rights reserved. */
-/* */
-/*****************************************************************************/
-/* LICENSE: */
-/*****************************************************************************/
-/* */
-/* This library is free software; you can redistribute it and/or */
-/* modify it under the terms of the GNU Library General Public */
-/* License as published by the Free Software Foundation; either */
-/* version 2 of the License, || (at your option) any later version. */
-/* */
-/* This library is distributed in the hope that it will be useful, */
-/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
-/* MERCHANTABILITY || FITNESS FOR A PARTICULAR PURPOSE. See the GNU */
-/* Library General Public License for more details. */
-/* */
-/* You should have received a copy of the GNU Library General Public */
-/* License along with this library; if not, write to the */
-/* Free Software Foundation, Inc., */
-/* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-/* */
-/* || download a copy from ftp://ftp.gnu.org/pub/gnu/COPYING.LIB-2.0 */
-/* */
-/*****************************************************************************/
-
-/*****************************************************************************/
-/* MODULE NAME: constantbv.cpp MODULE TYPE:constantbv*/
-/*****************************************************************************/
-/* MODULE IMPORTS: */
-/*****************************************************************************/
-#include <stdio.h>
-#include <stdlib.h> /* MODULE TYPE: (sys) */
-#include <limits.h> /* MODULE TYPE: (sys) */
-#include <string.h> /* MODULE TYPE: (sys) */
-#include <ctype.h> /* MODULE TYPE: (sys) */
-#include "constantbv.h"
-
-namespace CONSTANTBV {
-/*****************************************************************************/
-/* MODULE IMPLEMENTATION: */
-/*****************************************************************************/
- /**********************************************/
- /* global implementation-intrinsic constants: */
- /**********************************************/
-
-#define BIT_VECTOR_HIDDEN_WORDS 3
-
- /*****************************************************************/
- /* 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 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 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"): */
- /********************************************************************/
-
-static unsigned int * BITMASKTAB;
-
- /*****************************/
- /* global macro definitions: */
- /*****************************/
-
-#define BIT_VECTOR_ZERO_WORDS(target,count) \
- while (count-- > 0) *target++ = 0;
-
-#define BIT_VECTOR_FILL_WORDS(target,fill,count) \
- while (count-- > 0) *target++ = fill;
-
-#define BIT_VECTOR_FLIP_WORDS(target,flip,count) \
- while (count-- > 0) *target++ ^= flip;
-
-#define BIT_VECTOR_COPY_WORDS(target,source,count) \
- while (count-- > 0) *target++ = *source++;
-
-#define BIT_VECTOR_BACK_WORDS(target,source,count) \
- { target += count; source += count; while (count-- > 0) *--target = *--source; }
-
-#define BIT_VECTOR_CLR_BIT(address,index) \
- *(address+(index>>LOGBITS)) &= ~ BITMASKTAB[index & MODMASK];
-
-#define BIT_VECTOR_SET_BIT(address,index) \
- *(address+(index>>LOGBITS)) |= BITMASKTAB[index & MODMASK];
-
-#define BIT_VECTOR_TST_BIT(address,index) \
- ((*(address+(index>>LOGBITS)) & BITMASKTAB[index & MODMASK]) != 0)
-
-#define BIT_VECTOR_FLP_BIT(address,index,mask) \
- (mask = BITMASKTAB[index & MODMASK]), \
- (((*(addr+(index>>LOGBITS)) ^= mask) & mask) != 0)
-
-#define BIT_VECTOR_DIGITIZE(type,value,digit) \
- value = (type) ((digit = value) / 10); \
- digit -= value * 10; \
- digit += (type) '0';
-
- /*********************************************************/
- /* private low-level functions (potentially dangerous!): */
- /*********************************************************/
-
-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) {
- BIT_VECTOR_ZERO_WORDS(addr,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) {
- if (target != source) {
- 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) {
- 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);
- }
-}
-
-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);
- }
-}
-
-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--;
- }
- }
-}
-
-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);
- }
- else {
- length = 1;
- *work++ = (unsigned char) '0';
- }
- return(length);
-}
-
-static unsigned int BIT_VECTOR_str2int(unsigned char * string, unsigned int *value) {
- unsigned int length;
- unsigned int digit;
-
- *value = 0;
- length = 0;
- 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++;
- }
- return(length);
-}
-
- /********************************************/
- /* routine to convert error code to string: */
- /********************************************/
-
-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;
- }
-}
-
- /*****************************************/
- /* 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;
-
- if (sizeof(unsigned int) > sizeof(size_t)) return(ErrCode_Type);
-
- BITS = 1;
- while (sample <<= 1) BITS++; /* determine # of bits in a machine word */
-
- if (BITS != (sizeof(unsigned int) << 3)) return(ErrCode_Bits);
-
- if (BITS < 16) return(ErrCode_Word);
-
- LONGBITS = 1;
- while (longsample <<= 1) LONGBITS++; /* = # of bits in an unsigned long */
-
- if (BITS > LONGBITS) return(ErrCode_Long);
-
- LOGBITS = 0;
- sample = BITS;
- lsb = (sample & LSB);
- while ((sample >>= 1) && (! lsb)) {
- LOGBITS++;
- lsb = (sample & LSB);
- }
-
- if (sample) return(ErrCode_Powr); /* # of bits is not a power of 2! */
-
- if (BITS != (LSB << LOGBITS)) return(ErrCode_Loga);
-
- MODMASK = BITS - 1;
- FACTOR = LOGBITS - 3; /* ld(BITS / 8) = ld(BITS) - ld(8) = ld(BITS) - 3 */
- MSB = (LSB << MODMASK);
-
- BITMASKTAB = (unsigned int * ) malloc((size_t) (BITS << FACTOR));
-
- if (BITMASKTAB == NULL) return(ErrCode_Null);
-
- for ( sample = 0; sample < BITS; 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 size;
-
- size = bits >> LOGBITS;
- if (bits & MODMASK) size++;
- return(size);
-}
-
-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)
-{
- return((unsigned char *)"6.4");
-}
-
-unsigned int BitVector_Word_Bits(void)
-{
- return(BITS);
-}
-
-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 */
-{
- if (string != NULL) free((void *) string);
-}
-
-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 */
-{
- 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 size;
- unsigned int mask;
- unsigned int bytes;
- unsigned int * addr;
- unsigned int * zero;
-
- size = BitVector_Size(bits);
- mask = BitVector_Mask(bits);
- 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 * * 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 bytes;
- unsigned int oldsize;
- unsigned int oldmask;
- unsigned int newsize;
- unsigned int newmask;
- unsigned int * newaddr;
- unsigned int * source;
- unsigned int * target;
-
- oldsize = size_(oldaddr);
- oldmask = mask_(oldaddr);
- newsize = BitVector_Size(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;
- target = newaddr;
- source = oldaddr;
- newsize -= oldsize;
- BIT_VECTOR_COPY_WORDS(target,source,oldsize)
- BIT_VECTOR_ZERO_WORDS(target,newsize)
- }
- BitVector_Destroy(oldaddr);
- }
- return(newaddr);
-}
-
-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 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));
- return(twin);
-}
-
-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;
- unsigned int bitsY;
- unsigned int bitsZ;
- unsigned int * Z;
-
- bitsX = bits_(X);
- bitsY = bits_(Y);
- 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 */
-{
- unsigned int sizeX = size_(X);
- unsigned int sizeY = size_(Y);
- unsigned int maskX = mask_(X);
- unsigned int maskY = mask_(Y);
- unsigned int fill = 0;
- unsigned int * lastX;
- 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 */
-{
- unsigned int size = size_(addr);
-
- BIT_VECTOR_ZERO_WORDS(addr,size)
-}
-
-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;
- }
-}
-
-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;
- }
-}
-
-void BitVector_Primes(unsigned int * addr)
-{
- unsigned int bits = bits_(addr);
- unsigned int size = size_(addr);
- unsigned int * work;
- unsigned int temp;
- 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)
-{
- 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 = 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] */
- unsigned int bits = bits_(addr);
- unsigned int size = size_(addr);
- unsigned int * loaddr;
- unsigned int * hiaddr;
- unsigned int lobase;
- unsigned int hibase;
- unsigned int lomask;
- unsigned int himask;
- unsigned int diff;
-
- if ((size > 0) && (lower < bits) && (upper < bits) && (lower <= upper))
- {
- lobase = lower >> LOGBITS;
- hibase = upper >> LOGBITS;
- diff = hibase - lobase;
- loaddr = addr + lobase;
- hiaddr = addr + hibase;
-
- lomask = (unsigned int) (~0L << (lower & MODMASK));
- 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] */
- unsigned int bits = bits_(addr);
- unsigned int size = size_(addr);
- unsigned int fill = (unsigned int) ~0L;
- unsigned int * loaddr;
- unsigned int * hiaddr;
- unsigned int lobase;
- unsigned int hibase;
- unsigned int lomask;
- unsigned int himask;
- unsigned int diff;
-
- if ((size > 0) && (lower < bits) && (upper < bits) && (lower <= upper))
- {
- lobase = lower >> LOGBITS;
- hibase = upper >> LOGBITS;
- diff = hibase - lobase;
- loaddr = addr + lobase;
- hiaddr = addr + hibase;
-
- lomask = (unsigned int) (~0L << (lower & MODMASK));
- 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] */
- unsigned int bits = bits_(addr);
- unsigned int size = size_(addr);
- unsigned int flip = (unsigned int) ~0L;
- unsigned int * loaddr;
- unsigned int * hiaddr;
- unsigned int lobase;
- unsigned int hibase;
- unsigned int lomask;
- unsigned int himask;
- unsigned int diff;
-
- if ((size > 0) && (lower < bits) && (upper < bits) && (lower <= upper))
- {
- lobase = lower >> LOGBITS;
- hibase = upper >> LOGBITS;
- diff = hibase - lobase;
- loaddr = addr + lobase;
- hiaddr = addr + hibase;
-
- lomask = (unsigned int) (~0L << (lower & MODMASK));
- 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)
-{
- unsigned int bits = bits_(addr);
- unsigned int * loaddr;
- unsigned int * hiaddr;
- unsigned int lomask;
- 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)
-{
- unsigned int size = size_(addr);
- unsigned int mask = mask_(addr);
- unsigned int offset;
- unsigned int bitmask;
- unsigned int value;
- boolean empty;
-
- if ((size == 0) || (start >= bits_(addr))) return(false);
-
- *min = start;
- *max = start;
-
- offset = start >> LOGBITS;
-
- *(addr+size-1) &= mask;
-
- addr += offset;
- size -= offset;
-
- bitmask = BITMASKTAB[start & MODMASK];
- mask = ~ (bitmask | (bitmask - 1));
-
- 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)
-{
- unsigned int size = size_(addr);
- unsigned int mask = mask_(addr);
- unsigned int offset;
- unsigned int bitmask;
- unsigned int value;
- boolean empty;
-
- if ((size == 0) || (start >= bits_(addr))) return(false);
-
- *min = start;
- *max = start;
-
- offset = start >> LOGBITS;
-
- if (offset >= size) return(false);
-
- *(addr+size-1) &= mask;
-
- addr += offset;
- size = ++offset;
-
- bitmask = BITMASKTAB[start & MODMASK];
- mask = (bitmask - 1);
-
- 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)
-{
- unsigned int bitsX = bits_(X);
- unsigned int bitsY = bits_(Y);
- unsigned int source = 0; /* silence compiler warning */
- unsigned int target = 0; /* silence compiler warning */
- unsigned int s_lo_base;
- unsigned int s_hi_base;
- unsigned int s_lo_bit;
- unsigned int s_hi_bit;
- unsigned int s_base;
- unsigned int s_lower = 0; /* silence compiler warning */
- unsigned int s_upper = 0; /* silence compiler warning */
- unsigned int s_bits;
- unsigned int s_min;
- unsigned int s_max;
- unsigned int t_lo_base;
- unsigned int t_hi_base;
- unsigned int t_lo_bit;
- unsigned int t_hi_bit;
- unsigned int t_base;
- unsigned int t_lower = 0; /* silence compiler warning */
- unsigned int t_upper = 0; /* silence compiler warning */
- unsigned int t_bits;
- unsigned int t_min;
- unsigned int mask;
- unsigned int bits;
- unsigned int select;
- boolean ascending;
- boolean notfirst;
- 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;
-
- ascending = (Xoffset <= Yoffset);
-
- s_lo_base = Yoffset >> LOGBITS;
- s_lo_bit = Yoffset & MODMASK;
- Yoffset += --length;
- s_hi_base = Yoffset >> LOGBITS;
- s_hi_bit = Yoffset & MODMASK;
-
- t_lo_base = Xoffset >> LOGBITS;
- t_lo_bit = Xoffset & MODMASK;
- Xoffset += length;
- t_hi_base = Xoffset >> LOGBITS;
- 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;
- }
- }
- 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;
- }
- }
- 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 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 == {} ? */
-{
- 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 == ~{} ? */
-{
- 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 ? */
-{
- 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) {
- 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);
- }
- }
- else {
- 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 */
- unsigned int bitsX = bits_(X);
- unsigned int bitsY = bits_(Y);
- unsigned int size = size_(X);
- unsigned int mask = mask_(X);
- unsigned int sign;
- 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 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 int bits = bits_(addr);
- unsigned int size = size_(addr);
- unsigned int value;
- unsigned int count;
- unsigned int digit;
- unsigned int length;
- unsigned char * string;
-
- length = bits >> 2;
- if (bits & 0x0003) length++;
- string = (unsigned char *) malloc((size_t) (length+1));
- if (string == NULL) return(NULL);
- 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)
-{
- unsigned int size = size_(addr);
- unsigned int mask = mask_(addr);
- boolean ok = true;
- unsigned int length;
- unsigned int value;
- unsigned int count;
- 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);
- }
- }
- *addr++ = value;
- }
- *(--addr) &= mask;
- }
- if (ok) return(ErrCode_Ok);
- else return(ErrCode_Pars);
-}
-
-unsigned char * BitVector_to_Bin(unsigned int * addr)
-{
- unsigned int size = size_(addr);
- unsigned int value;
- unsigned int count;
- unsigned int digit;
- unsigned int length;
- unsigned char * string;
-
- length = bits_(addr);
- string = (unsigned char *) malloc((size_t) (length+1));
- if (string == NULL) return(NULL);
- 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)
-{
- unsigned int size = size_(addr);
- unsigned int mask = mask_(addr);
- boolean ok = true;
- unsigned int length;
- unsigned int value;
- unsigned int count;
- 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;
- }
- }
- *addr++ = value;
- }
- *(--addr) &= mask;
- }
- if (ok) return(ErrCode_Ok);
- else return(ErrCode_Pars);
-}
-
-unsigned char * BitVector_to_Dec(unsigned int * addr)
-{
- unsigned int bits = bits_(addr);
- unsigned int length;
- unsigned int digits;
- unsigned int count;
- unsigned int q;
- unsigned int r;
- boolean loop;
- unsigned char * result;
- unsigned char * string;
- unsigned int * quot;
- unsigned int * rest;
- unsigned int * temp;
- unsigned int * base;
- signed int sign;
-
- length = (unsigned int) (bits / 3.3); /* digits = bits * ln(2) / ln(10) */
- length += 2; /* compensate for truncating & provide space for minus sign */
- result = (unsigned char *) malloc((size_t) (length+1)); /* remember the '\0'! */
- if (result == NULL) return(NULL);
- 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))
- {
- 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 error = ErrCode_Ok;
- unsigned int bits = bits_(addr);
- unsigned int mask = mask_(addr);
- boolean init = (bits > BITS);
- boolean minus;
- boolean shift;
- boolean carry;
- unsigned int * term;
- unsigned int * base;
- unsigned int * prod;
- unsigned int * rank;
- unsigned int * temp;
- unsigned int accu;
- unsigned int powr;
- unsigned int count;
- unsigned int length;
- int digit;
-
- if (bits > 0)
- {
- length = strlen((char *) string);
- if (length == 0) return(ErrCode_Pars);
- digit = (int) *string;
- if ((minus = (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;
- }
- }
- return(error);
-}
-
-unsigned char * BitVector_to_Enum(unsigned int * addr)
-{
- unsigned int bits = bits_(addr);
- unsigned int sample;
- unsigned int length;
- unsigned int digits;
- unsigned int factor;
- unsigned int power;
- unsigned int start;
- unsigned int min;
- unsigned int max;
- unsigned char * string;
- unsigned char * target;
- 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);
- start = 0;
- 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 error = ErrCode_Ok;
- unsigned int bits = bits_(addr);
- unsigned int state = 1;
- unsigned int token;
- unsigned int index = 0;
- 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)
- {
- case 1:
- switch (token)
- {
- case (unsigned int) '0':
- state = 2;
- break;
- case (unsigned int) '\0':
- state = 0;
- break;
- default:
- error = ErrCode_Pars;
- break;
- }
- break;
- case 2:
- 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;
- }
- break;
- case 3:
- 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;
- }
- break;
- case 4:
- switch (token)
- {
- case (unsigned int) ',':
- state = 5;
- break;
- case (unsigned int) '\0':
- state = 0;
- break;
- default:
- error = ErrCode_Pars;
- break;
- }
- break;
- case 5:
- switch (token)
- {
- case (unsigned int) '0':
- state = 2;
- break;
- default:
- error = ErrCode_Pars;
- break;
- }
- break;
- }
- }
- }
- return(error);
-}
-
-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} */
-{
- 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}) */
-{
- 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 ? */
-{
- 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)
-{
- if (index < bits_(addr))
- {
- if (bit) BIT_VECTOR_SET_BIT(addr,index)
- else BIT_VECTOR_CLR_BIT(addr,index)
- }
-}
-
-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)
-{
- 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)
-{
- if (size_(addr) > 0) return( (*addr & LSB) != 0 );
- else return( false );
-}
-
-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 );
- else
- return( false );
-}
-
-boolean BitVector_rotate_left(unsigned int * addr)
-{
- unsigned int size = size_(addr);
- unsigned int mask = mask_(addr);
- unsigned int msb;
- boolean carry_in;
- 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)
-{
- unsigned int size = size_(addr);
- unsigned int mask = mask_(addr);
- unsigned int msb;
- boolean carry_in;
- boolean carry_out = false;
-
- if (size > 0)
- {
- msb = mask & ~ (mask >> 1);
- carry_in = ((*addr & LSB) != 0);
- addr += size-1;
- *addr &= mask;
- carry_out = ((*addr & LSB) != 0);
- *addr >>= 1;
- if (carry_in) *addr |= msb;
- carry_in = carry_out;
- 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)
-{
- 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)
-{
- 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;
- carry_out = ((*addr & LSB) != 0);
- *addr >>= 1;
- if (carry_in) *addr |= msb;
- carry_in = carry_out;
- 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)
-{
- 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)
-{
- 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)
-{
- 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)
-{
- 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++ */
-{
- 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-- */
-{
- 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)
-{
- unsigned int size = size_(X);
- unsigned int mask = mask_(X);
- unsigned int vv = 0;
- unsigned int cc;
- unsigned int mm;
- unsigned int yy;
- unsigned int zz;
- unsigned int lo;
- 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 );
- lo = (yy & LSB) + (zz & LSB) + cc;
- 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;
- lo = yy + zz + cc;
- cc = (lo >> 1);
- vv ^= cc;
- 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;
- hi = ((yy & MSB) >> 1) + ((zz & MSB) >> 1) + (vv >> 1);
- 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)
-{
- return(BitVector_compute(X,Y,Z,false,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 carry = true;
-
- return(BitVector_compute(X,Y,NULL,false,&carry));
-}
-
-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)
-{
- 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)
-{
- 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)
-{
- 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)
-{
- unsigned int mask;
- unsigned int limit;
- unsigned int count;
- signed long last;
- unsigned int * sign;
- boolean carry;
- boolean overflow;
- 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!)
- */
-
- if ((X == Y) || (X == Z) || (Y == Z)) return(ErrCode_Same);
- if (bits_(X) != bits_(Y)) return(ErrCode_Size);
- BitVector_Empty(X);
- if (BitVector_is_empty(Y)) return(ErrCode_Ok); /* exit also taken if bits_(Y)==0 */
- if ((last = Set_Max(Z)) < 0L) return(ErrCode_Ok);
- limit = (unsigned int) last;
- sign = Y + size_(Y) - 1;
- mask = mask_(Y);
- *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 error = ErrCode_Ok;
- unsigned int bit_x = bits_(X);
- unsigned int bit_y = bits_(Y);
- unsigned int bit_z = bits_(Z);
- unsigned int size;
- unsigned int mask;
- unsigned int msb;
- unsigned int * ptr_y;
- unsigned int * ptr_z;
- boolean sgn_x;
- boolean sgn_y;
- boolean sgn_z;
- boolean zero;
- unsigned int * A;
- 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!)
- */
-
- 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);
- if (B == NULL) { BitVector_Destroy(A); return(ErrCode_Null); }
- size = size_(Y);
- mask = mask_(Y);
- msb = (mask & ~ (mask >> 1));
- sgn_y = (((*(Y+size-1) &= mask) & msb) != 0);
- sgn_z = (((*(Z+size-1) &= mask) & msb) != 0);
- sgn_x = sgn_y ^ sgn_z;
- if (sgn_y) BitVector_Negate(A,Y); else BitVector_Copy(A,Y);
- if (sgn_z) BitVector_Negate(B,Z); else BitVector_Copy(B,Z);
- ptr_y = A + size;
- 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)
-{
- unsigned int bits = bits_(Q);
- unsigned int mask;
- unsigned int * addr;
- signed long last;
- boolean flag;
- 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!)
- */
-
- if ((bits != bits_(X)) || (bits != bits_(Y)) || (bits != bits_(R)))
- return(ErrCode_Size);
- if ((Q == X) || (Q == Y) || (Q == R) || (X == Y) || (X == R) || (Y == R))
- return(ErrCode_Same);
- if (BitVector_is_empty(Y))
- 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 error = ErrCode_Ok;
- unsigned int bits = bits_(Q);
- unsigned int size = size_(Q);
- unsigned int mask = mask_(Q);
- unsigned int msb = (mask & ~ (mask >> 1));
- boolean sgn_q;
- boolean sgn_x;
- boolean sgn_y;
- unsigned int * A;
- 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!)
- */
-
- if ((bits != bits_(X)) || (bits != bits_(Y)) || (bits != bits_(R)))
- return(ErrCode_Size);
- if (Q == R)
- return(ErrCode_Same);
- if (BitVector_is_empty(Y))
- 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);
- if (B == NULL) { BitVector_Destroy(A); return(ErrCode_Null); }
- size--;
- sgn_x = (((*(X+size) &= mask) & msb) != 0);
- sgn_y = (((*(Y+size) &= mask) & msb) != 0);
- sgn_q = sgn_x ^ sgn_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 error = ErrCode_Ok;
- unsigned int bits = bits_(X);
- unsigned int size = size_(X);
- unsigned int mask = mask_(X);
- unsigned int msb = (mask & ~ (mask >> 1));
- boolean sgn_a;
- boolean sgn_b;
- boolean sgn_r;
- unsigned int * Q;
- unsigned int * R;
- unsigned int * A;
- unsigned int * B;
- 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
- */
-
- 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 error = ErrCode_Ok;
- unsigned int bits = bits_(U);
- unsigned int size = size_(U);
- unsigned int mask = mask_(U);
- unsigned int msb = (mask & ~ (mask >> 1));
- boolean minus;
- boolean carry;
- boolean sgn_q;
- boolean sgn_r;
- boolean sgn_a;
- boolean sgn_b;
- boolean sgn_x;
- boolean sgn_y;
- unsigned int * * L;
- unsigned int * Q;
- unsigned int * R;
- unsigned int * A;
- unsigned int * B;
- unsigned int * T;
- unsigned int * X1;
- unsigned int * X2;
- unsigned int * X3;
- unsigned int * Y1;
- unsigned int * Y2;
- unsigned int * Y3;
- 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
- */
-
- 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];
- B = L[3];
- X1 = L[4];
- X2 = L[5];
- X3 = L[6];
- Y1 = L[7];
- Y2 = L[8];
- Y3 = L[9];
- Z = L[10];
- size--;
- sgn_a = (((*(X+size) &= mask) & msb) != 0);
- sgn_b = (((*(Y+size) &= mask) & msb) != 0);
- if (sgn_a) BitVector_Negate(A,X); else BitVector_Copy(A,X);
- if (sgn_b) BitVector_Negate(B,Y); else BitVector_Copy(B,Y);
- BitVector_Empty(X1);
- BitVector_Empty(X2);
- *X1 = 1;
- BitVector_Empty(Y1);
- BitVector_Empty(Y2);
- *Y2 = 1;
- 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;
- A = B; sgn_a = sgn_b;
- B = R; sgn_b = sgn_r;
- R = T;
-
- T = X1;
- X1 = X2;
- X2 = X3;
- X3 = T;
-
- T = Y1;
- 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 error = ErrCode_Ok;
- unsigned int bits = bits_(X);
- boolean first = true;
- signed long last;
- unsigned int limit;
- unsigned int count;
- 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
- */
-
- 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)
-{
- unsigned int size = size_(addr);
- unsigned int mask = mask_(addr);
- unsigned int value;
- unsigned int count;
-
- /* 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 int size = size_(addr);
- unsigned int value;
- unsigned int count;
- unsigned char * buffer;
- unsigned char * target;
-
- /* provide translation for independence of endian-ness: */
- *length = size << FACTOR;
- buffer = (unsigned char *) malloc((size_t) ((*length)+1));
- 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)
-{
- 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 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)
-{
- 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)
-{
- 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)
-{
- 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;
- *addr &= ~ mask;
- *addr++ |= temp;
- value >>= bits;
- chunksize -= bits;
- offset = 0;
- }
- }
-}
-
-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;
- unsigned long temp;
- 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: */
- /*******************/
-
-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 */
-{
- 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 */
-{
- 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) */
-{
- 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 */
-{
- 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: */
- /******************/
-
-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 char * byte;
- unsigned int bytes;
- unsigned int n;
-
- byte = (unsigned char *) 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 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 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) */
-{
- 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) */
-{
- boolean empty = true;
- unsigned int size = size_(addr);
- unsigned int i = size;
- unsigned int c = 0; /* silence compiler warning */
-
- 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: */
- /**********************************/
-
-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;
- unsigned int indxX;
- unsigned int indxY;
- unsigned int indxZ;
- unsigned int termX;
- 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)
- }
- }
- }
-}
-
-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;
- unsigned int indxX;
- unsigned int indxY;
- unsigned int indxZ;
- unsigned int termX;
- 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)
- }
- }
- }
-}
-
-void Matrix_Closure(unsigned int * addr, unsigned int rows, unsigned int cols)
-{
- unsigned int i;
- unsigned int j;
- unsigned int k;
- unsigned int ii;
- unsigned int ij;
- unsigned int ik;
- unsigned int kj;
- 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;
- 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)
-{
- unsigned int i;
- unsigned int j;
- unsigned int ii;
- unsigned int ij;
- unsigned int ji;
- unsigned int addii;
- unsigned int addij;
- unsigned int addji;
- unsigned int bitii;
- unsigned int bitij;
- unsigned int bitji;
- unsigned int termi;
- 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;
- else
- *(X+addji) &= ~ bitji;
- }
- }
- }
- }
-}
-} //end of namespace CONSTANTBV
diff --git a/stp/constantbv/constantbv.h b/stp/constantbv/constantbv.h
deleted file mode 100644
index bd64132d..00000000
--- a/stp/constantbv/constantbv.h
+++ /dev/null
@@ -1,316 +0,0 @@
-#ifndef MODULE_BIT_VECTOR
-#define MODULE_BIT_VECTOR
-/*****************************************************************************/
-/* AUTHOR: */
-/*****************************************************************************/
-/* */
-/* Steffen Beyer */
-/* mailto:sb@engelschall.com */
-/* http://www.engelschall.com/u/sb/download/ */
-/* */
-/*****************************************************************************/
-/* COPYRIGHT: */
-/*****************************************************************************/
-/* */
-/* Copyright (c) 1995 - 2004 by Steffen Beyer. */
-/* All rights reserved. */
-/* */
-/*****************************************************************************/
-/* LICENSE: */
-/*****************************************************************************/
-/* */
-/* This library is free software; you can redistribute it and/or */
-/* modify it under the terms of the GNU Library General Public */
-/* License as published by the Free Software Foundation; either */
-/* version 2 of the License, or (at your option) any later version. */
-/* */
-/* This library is distributed in the hope that it will be useful, */
-/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
-/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU */
-/* Library General Public License for more details. */
-/* */
-/* You should have received a copy of the GNU Library General Public */
-/* License along with this library; if not, write to the */
-/* Free Software Foundation, Inc., */
-/* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-/* */
-/* or download a copy from ftp://ftp.gnu.org/pub/gnu/COPYING.LIB-2.0 */
-/* */
-/*****************************************************************************/
-
-
-/*****************************************************************************/
-/* MODULE NAME: BitVector.h MODULE TYPE: (adt) */
-/*****************************************************************************/
-/* MODULE IMPORTS: */
-/*****************************************************************************/
-#include <stdlib.h> /* MODULE TYPE: (sys) */
-#include <limits.h> /* MODULE TYPE: (sys) */
-#include <string.h> /* MODULE TYPE: (sys) */
-#include <ctype.h> /* MODULE TYPE: (sys) */
-/*****************************************************************************/
-/* MODULE INTERFACE: */
-/*****************************************************************************/
-
-namespace CONSTANTBV {
-
-#ifdef __cplusplus
- extern "C" {
- typedef bool boolean;
-#else
- typedef enum { false = (0!=0), true = (0==0) } boolean;
-#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;
-
-
- /* ===> MISCELLANEOUS BASIC FUNCTIONS: <=== */
- unsigned char * BitVector_Error(ErrCode error); /* return string for err code */
- ErrCode BitVector_Boot (void); /* 0 = ok, 1..7 = error */
- unsigned int BitVector_Size(unsigned int bits); /* bit vector size (# of words) */
- unsigned int BitVector_Mask(unsigned int bits); /* bit vector mask (unused bits) */
-
- /* ===> CLASS METHODS: <=== */
- unsigned char * BitVector_Version(void); /* return version string */
- unsigned int BitVector_Word_Bits(void); /* return # of bits in machine word */
- unsigned int BitVector_Long_Bits(void); /* return # of bits in unsigned long */
-
- /* ===> CONSTRUCTOR METHODS: <=== */
- unsigned int * BitVector_Create (unsigned int bits, boolean clear); /* malloc */
- unsigned int ** BitVector_Create_List (unsigned int bits, boolean clear, unsigned int count);
- unsigned int * BitVector_Resize (unsigned int * oldaddr, unsigned int bits); /* realloc */
- unsigned int * BitVector_Shadow (unsigned int * addr); /* make new same size but empty */
- unsigned int * BitVector_Clone (unsigned int * addr); /* make exact duplicate */
- unsigned int * BitVector_Concat (unsigned int * X, unsigned int * Y); /* return concatenation */
-
- /* ===> DESTRUCTOR METHODS: <=== */
- void BitVector_Dispose (unsigned char * string); /* string */
- void BitVector_Destroy (unsigned int * addr); /* bitvec */
- void BitVector_Destroy_List (unsigned int * * list, unsigned int count); /* list */
-
- /* ===> OBJECT METHODS: <=== */
-
- /* ===> bit vector hash: */
- size_t BitVector_Hash (unsigned int * X);
-
- /* ===> bit vector copy function: */
- void BitVector_Copy (unsigned int * X, unsigned int * Y); /* X := Y */
-
- /* ===> bit vector initialization: */
- void BitVector_Empty (unsigned int * addr); /* X = {} */
- void BitVector_Fill (unsigned int * addr); /* X = ~{} */
- void BitVector_Flip (unsigned int * addr); /* X = ~X */
- void BitVector_Primes (unsigned int * addr);
-
- /* ===> miscellaneous functions: */
- void BitVector_Reverse (unsigned int * X, unsigned int * Y);
-
- /* ===> bit vector interval operations and functions: */
- void BitVector_Interval_Empty (unsigned int * addr, unsigned int lower, unsigned int upper);
- void BitVector_Interval_Fill (unsigned int * addr, unsigned int lower, unsigned int upper);
- void BitVector_Interval_Flip (unsigned int * addr, unsigned int lower, unsigned int upper);
- 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);
- boolean BitVector_interval_scan_dec (unsigned int * addr, unsigned int start,
- 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 * BitVector_Interval_Substitute(unsigned int * X, unsigned int * Y,
- unsigned int Xoffset, unsigned int Xlength,
- unsigned int Yoffset, unsigned int Ylength);
-
- /* ===> bit vector test functions: */
- boolean BitVector_is_empty (unsigned int * addr); /* X == {} ? */
- boolean BitVector_is_full (unsigned int * addr); /* X == ~{} ? */
- boolean BitVector_equal (unsigned int * X, unsigned int * Y); /* X == Y ? */
- signed int BitVector_Lexicompare (unsigned int * X, unsigned int * Y); /* X <,=,> Y ? */
- signed int BitVector_Compare (unsigned int * X, unsigned int * Y); /* X <,=,> Y ? */
-
- /* ===> bit vector string conversion functions: */
- unsigned char * BitVector_to_Hex (unsigned int * addr);
- ErrCode BitVector_from_Hex (unsigned int * addr, unsigned char * string);
- unsigned char * BitVector_to_Bin (unsigned int * addr);
- ErrCode BitVector_from_Bin (unsigned int * addr, unsigned char * string);
- unsigned char * BitVector_to_Dec (unsigned int * addr);
- ErrCode BitVector_from_Dec (unsigned int * addr, unsigned char * string);
- unsigned char * BitVector_to_Enum (unsigned int * addr);
- ErrCode BitVector_from_Enum (unsigned int * addr, unsigned char * string);
-
- /* ===> bit vector bit operations, functions & tests: */
- void BitVector_Bit_Off (unsigned int * addr, unsigned int index); /* X = X \ {x} */
- void BitVector_Bit_On (unsigned int * addr, unsigned int index); /* X = X + {x} */
- boolean BitVector_bit_flip (unsigned int * addr, unsigned int index); /* (X+{x})\(X*{x}) */
- boolean BitVector_bit_test (unsigned int * addr, unsigned int index); /* {x} in X ? */
- void BitVector_Bit_Copy (unsigned int * addr, unsigned int index, boolean bit);
-
- /* ===> bit vector bit shift & rotate functions: */
- void BitVector_LSB (unsigned int * addr, boolean bit);
- void BitVector_MSB (unsigned int * addr, boolean bit);
- boolean BitVector_lsb_ (unsigned int * addr);
- boolean BitVector_msb_ (unsigned int * addr);
- boolean BitVector_rotate_left (unsigned int * addr);
- boolean BitVector_rotate_right (unsigned int * addr);
- boolean BitVector_shift_left (unsigned int * addr, boolean carry_in);
- boolean BitVector_shift_right (unsigned int * addr, boolean carry_in);
- void BitVector_Move_Left (unsigned int * addr, unsigned int bits);
- void BitVector_Move_Right (unsigned int * addr, unsigned int bits);
-
- /* ===> bit vector insert/delete bits: */
- void BitVector_Insert (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);
-
- /* ===> 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);
- boolean BitVector_add (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); /* X = Y-Z*/
- boolean BitVector_inc (unsigned int * X, unsigned int * Y);
- boolean BitVector_dec (unsigned int * X, unsigned int * Y);
-
- void BitVector_Negate (unsigned int * X, unsigned int * Y);
- 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);
- 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 */
- 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 * 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);
- void BitVector_Word_Delete (unsigned int * addr,
- 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 long BitVector_Chunk_Read (unsigned int * addr,
- unsigned int chunksize,unsigned int offset);
-
- /* ===> set operations: */
- void Set_Union (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 */
- void Set_Difference (unsigned int * X, unsigned int * Y, unsigned int * Z); /* X = Y \ Z */
- void Set_ExclusiveOr (unsigned int * X, unsigned int * Y, unsigned int * Z); /*(Y+Z)\(Y*Z)*/
- void Set_Complement (unsigned int * X, unsigned int * Y); /* X = ~Y */
-
- /* ===> set functions: */
- boolean Set_subset (unsigned int * X, unsigned int * Y); /* X in Y ? */
- unsigned int Set_Norm (unsigned int * addr); /* = | X | */
- unsigned int Set_Norm2 (unsigned int * addr); /* = | X | */
- unsigned int Set_Norm3 (unsigned int * addr); /* = | X | */
- signed long Set_Min (unsigned int * addr); /* = min(X) */
- signed long Set_Max (unsigned int * addr); /* = max(X) */
-
- /* ===> 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_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_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);
-
- /*****************************************************************************/
- /* MODULE RESOURCES: */
- /*****************************************************************************/
-#define bits_(BitVector) *(BitVector-3)
-#define size_(BitVector) *(BitVector-2)
-#define mask_(BitVector) *(BitVector-1)
-
-#define ERRCODE_TYPE "sizeof(word) > sizeof(size_t)"
-#define ERRCODE_BITS "bits(word) != sizeof(word)*8"
-#define ERRCODE_WORD "bits(word) < 16"
-#define ERRCODE_LONG "bits(word) > bits(long)"
-#define ERRCODE_POWR "bits(word) != 2^x"
-#define ERRCODE_LOGA "bits(word) != 2^ld(bits(word))"
-#define ERRCODE_NULL "unable to allocate memory"
-#define ERRCODE_INDX "index out of range"
-#define ERRCODE_ORDR "minimum > maximum index"
-#define ERRCODE_SIZE "bit vector size mismatch"
-#define ERRCODE_PARS "input string syntax error"
-#define ERRCODE_OVFL "numeric overflow error"
-#define ERRCODE_SAME "result vector(s) must be distinct"
-#define ERRCODE_EXPO "exponent must be positive"
-#define ERRCODE_ZERO "division by zero error"
-#define ERRCODE_OOPS "unexpected internal error - please contact author"
-
- const unsigned int BitVector_BYTENORM[256] = {
- 0x00, 0x01, 0x01, 0x02, 0x01, 0x02, 0x02, 0x03,
- 0x01, 0x02, 0x02, 0x03, 0x02, 0x03, 0x03, 0x04, /* 0x00 */
- 0x01, 0x02, 0x02, 0x03, 0x02, 0x03, 0x03, 0x04,
- 0x02, 0x03, 0x03, 0x04, 0x03, 0x04, 0x04, 0x05, /* 0x10 */
- 0x01, 0x02, 0x02, 0x03, 0x02, 0x03, 0x03, 0x04,
- 0x02, 0x03, 0x03, 0x04, 0x03, 0x04, 0x04, 0x05, /* 0x20 */
- 0x02, 0x03, 0x03, 0x04, 0x03, 0x04, 0x04, 0x05,
- 0x03, 0x04, 0x04, 0x05, 0x04, 0x05, 0x05, 0x06, /* 0x30 */
- 0x01, 0x02, 0x02, 0x03, 0x02, 0x03, 0x03, 0x04,
- 0x02, 0x03, 0x03, 0x04, 0x03, 0x04, 0x04, 0x05, /* 0x40 */
- 0x02, 0x03, 0x03, 0x04, 0x03, 0x04, 0x04, 0x05,
- 0x03, 0x04, 0x04, 0x05, 0x04, 0x05, 0x05, 0x06, /* 0x50 */
- 0x02, 0x03, 0x03, 0x04, 0x03, 0x04, 0x04, 0x05,
- 0x03, 0x04, 0x04, 0x05, 0x04, 0x05, 0x05, 0x06, /* 0x60 */
- 0x03, 0x04, 0x04, 0x05, 0x04, 0x05, 0x05, 0x06,
- 0x04, 0x05, 0x05, 0x06, 0x05, 0x06, 0x06, 0x07, /* 0x70 */
- 0x01, 0x02, 0x02, 0x03, 0x02, 0x03, 0x03, 0x04,
- 0x02, 0x03, 0x03, 0x04, 0x03, 0x04, 0x04, 0x05, /* 0x80 */
- 0x02, 0x03, 0x03, 0x04, 0x03, 0x04, 0x04, 0x05,
- 0x03, 0x04, 0x04, 0x05, 0x04, 0x05, 0x05, 0x06, /* 0x90 */
- 0x02, 0x03, 0x03, 0x04, 0x03, 0x04, 0x04, 0x05,
- 0x03, 0x04, 0x04, 0x05, 0x04, 0x05, 0x05, 0x06, /* 0xA0 */
- 0x03, 0x04, 0x04, 0x05, 0x04, 0x05, 0x05, 0x06,
- 0x04, 0x05, 0x05, 0x06, 0x05, 0x06, 0x06, 0x07, /* 0xB0 */
- 0x02, 0x03, 0x03, 0x04, 0x03, 0x04, 0x04, 0x05,
- 0x03, 0x04, 0x04, 0x05, 0x04, 0x05, 0x05, 0x06, /* 0xC0 */
- 0x03, 0x04, 0x04, 0x05, 0x04, 0x05, 0x05, 0x06,
- 0x04, 0x05, 0x05, 0x06, 0x05, 0x06, 0x06, 0x07, /* 0xD0 */
- 0x03, 0x04, 0x04, 0x05, 0x04, 0x05, 0x05, 0x06,
- 0x04, 0x05, 0x05, 0x06, 0x05, 0x06, 0x06, 0x07, /* 0xE0 */
- 0x04, 0x05, 0x05, 0x06, 0x05, 0x06, 0x06, 0x07,
- 0x05, 0x06, 0x06, 0x07, 0x06, 0x07, 0x07, 0x08 /* 0xF0 */
- };
-#ifdef __cplusplus
- }
-#endif
-} //end of namespace CONSTANTBV
-#endif
-
diff --git a/stp/sat/Global.h b/stp/sat/Global.h
deleted file mode 100644
index deaf8c24..00000000
--- a/stp/sat/Global.h
+++ /dev/null
@@ -1,255 +0,0 @@
-/****************************************************************************************[Global.h]
-MiniSat -- Copyright (c) 2003-2005, Niklas Een, Niklas Sorensson
-
-Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
-associated documentation files (the "Software"), to deal in the Software without restriction,
-including without limitation the rights to use, copy, modify, merge, publish, distribute,
-sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all copies or
-substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
-NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
-DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
-OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-**************************************************************************************************/
-
-#ifndef Global_h
-#define Global_h
-
-#include <cassert>
-#include <cstdio>
-#include <cstdlib>
-#include <cstring>
-#include <new>
-
-// PKT: needs to be outside namespace MINISAT or mac os x compilation breaks
-#ifdef _MSC_VER
-#else
-#include <unistd.h>
-#endif
-
-namespace MINISAT {
-//=================================================================================================
-// Basic Types & Minor Things:
-
-// DWD: This is needed on darwin.
-typedef unsigned int uint;
-
-#ifdef _MSC_VER
-
-typedef INT64 int64;
-typedef UINT64 uint64;
-typedef INT_PTR intp;
-typedef UINT_PTR uintp;
-#define I64_fmt "I64d"
-#else
-
-typedef long long int64;
-typedef unsigned long long uint64;
-typedef __PTRDIFF_TYPE__ intp;
-typedef unsigned __PTRDIFF_TYPE__ uintp;
-#define I64_fmt "lld"
-#endif
-
-template<class T> static inline T min(T x, T y) { return (x < y) ? x : y; }
-template<class T> static inline T max(T x, T y) { return (x > y) ? x : y; }
-
-template <bool> struct STATIC_ASSERTION_FAILURE;
-template <> struct STATIC_ASSERTION_FAILURE<true>{};
-#define TEMPLATE_FAIL STATIC_ASSERTION_FAILURE<false>()
-
-
-//=================================================================================================
-// 'malloc()'-style memory allocation -- never returns NULL; aborts instead:
-
-
-template<class T> static inline T* xmalloc(size_t size) {
- T* tmp = (T*)malloc(size * sizeof(T));
- assert(size == 0 || tmp != NULL);
- return tmp; }
-
-template<class T> static inline T* xrealloc(T* ptr, size_t size) {
- T* tmp = (T*)realloc((void*)ptr, size * sizeof(T));
- assert(size == 0 || tmp != NULL);
- return tmp; }
-
-template<class T> static inline void xfree(T *ptr) {
- if (ptr != NULL) free((void*)ptr); }
-
-
-//=================================================================================================
-// Random numbers:
-
-
-// Returns a random float 0 <= x < 1. Seed must never be 0.
-static inline double drand(double& seed) {
- seed *= 1389796;
- int q = (int)(seed / 2147483647);
- seed -= (double)q * 2147483647;
- return seed / 2147483647; }
-
-// Returns a random integer 0 <= x < size. Seed must never be 0.
-static inline int irand(double& seed, int size) {
- return (int)(drand(seed) * size); }
-
-
-//=================================================================================================
-// 'vec' -- automatically resizable arrays (via 'push()' method):
-
-
-// NOTE! Don't use this vector on datatypes that cannot be re-located in memory (with realloc)
-
-template<class T>
-class vec {
- T* data;
- int sz;
- int cap;
-
- void init(int size, const T& pad);
- void grow(int min_cap);
-
-public:
- // Types:
- typedef int Key;
- typedef T Datum;
-
- // Constructors:
- vec(void) : data(NULL) , sz(0) , cap(0) { }
- vec(int size) : data(NULL) , sz(0) , cap(0) { growTo(size); }
- vec(int size, const T& pad) : data(NULL) , sz(0) , cap(0) { growTo(size, pad); }
- vec(T* array, int size) : data(array), sz(size), cap(size) { } // (takes ownership of array -- will be deallocated with 'xfree()')
- ~vec(void) { clear(true); }
-
- // Ownership of underlying array:
- T* release (void) { T* ret = data; data = NULL; sz = 0; cap = 0; return ret; }
- operator T* (void) { return data; } // (unsafe but convenient)
- operator const T* (void) const { return data; }
-
- // Size operations:
- int size (void) const { return sz; }
- void shrink (int nelems) { assert(nelems <= sz); for (int i = 0; i < nelems; i++) sz--, data[sz].~T(); }
- void pop (void) { sz--, data[sz].~T(); }
- void growTo (int size);
- void growTo (int size, const T& pad);
- void clear (bool dealloc = false);
- void capacity (int size) { grow(size); }
-
- // Stack interface:
- void push (void) { if (sz == cap) grow(sz+1); new (&data[sz]) T() ; sz++; }
- void push (const T& elem) { if (sz == cap) grow(sz+1); new (&data[sz]) T(elem); sz++; }
- const T& last (void) const { return data[sz-1]; }
- T& last (void) { return data[sz-1]; }
-
- // Vector interface:
- const T& operator [] (int index) const { return data[index]; }
- T& operator [] (int index) { return data[index]; }
-
- // Don't allow copying (error prone):
- vec<T>& operator = (vec<T>& other) { TEMPLATE_FAIL; }
- vec (vec<T>& other) { TEMPLATE_FAIL; }
-
- // Duplicatation (preferred instead):
- void copyTo(vec<T>& copy) const { copy.clear(); copy.growTo(sz); for (int i = 0; i < sz; i++) new (&copy[i]) T(data[i]); }
- void moveTo(vec<T>& dest) { dest.clear(true); dest.data = data; dest.sz = sz; dest.cap = cap; data = NULL; sz = 0; cap = 0; }
-};
-
-template<class T>
-void vec<T>::grow(int min_cap) {
- if (min_cap <= cap) return;
- if (cap == 0) cap = (min_cap >= 2) ? min_cap : 2;
- else do cap = (cap*3+1) >> 1; while (cap < min_cap);
- data = xrealloc(data, cap); }
-
-template<class T>
-void vec<T>::growTo(int size, const T& pad) {
- if (sz >= size) return;
- grow(size);
- for (int i = sz; i < size; i++) new (&data[i]) T(pad);
- sz = size; }
-
-template<class T>
-void vec<T>::growTo(int size) {
- if (sz >= size) return;
- grow(size);
- for (int i = sz; i < size; i++) new (&data[i]) T();
- sz = size; }
-
-template<class T>
-void vec<T>::clear(bool dealloc) {
- if (data != NULL){
- for (int i = 0; i < sz; i++) data[i].~T();
- sz = 0;
- if (dealloc) xfree(data), data = NULL, cap = 0; } }
-
-
-//=================================================================================================
-// Useful functions on vectors
-
-
-template<class V, class T>
-void remove(V& ts, const T& t)
-{
- int j = 0;
- for (; j < ts.size() && ts[j] != t; j++) ;
- assert(j < ts.size());
- for (; j < ts.size()-1; j++) ts[j] = ts[j+1];
- ts.pop();
-}
-
-
-template<class V, class T>
-bool find(V& ts, const T& t)
-{
- int j = 0;
- for (; j < ts.size() && ts[j] != t; j++) ;
- return j < ts.size();
-}
-
-//=================================================================================================
-// Lifted booleans:
-
-
-class lbool {
- int value;
- explicit lbool(int v) : value(v) { }
-
-public:
- lbool() : value(0) { }
- lbool(bool x) : value((int)x*2-1) { }
- int toInt(void) const { return value; }
-
- bool operator == (const lbool& other) const { return value == other.value; }
- bool operator != (const lbool& other) const { return value != other.value; }
- lbool operator ~ (void) const { return lbool(-value); }
-
- friend int toInt (lbool l);
- friend lbool toLbool(int v);
-};
-inline int toInt (lbool l) { return l.toInt(); }
-inline lbool toLbool(int v) { return lbool(v); }
-
-const lbool l_True = toLbool( 1);
-const lbool l_False = toLbool(-1);
-const lbool l_Undef = toLbool( 0);
-
-
-//=================================================================================================
-// Relation operators -- extend definitions from '==' and '<'
-
-
-#ifndef __SGI_STL_INTERNAL_RELOPS // (be aware of SGI's STL implementation...)
-#define __SGI_STL_INTERNAL_RELOPS
-template <class T> static inline bool operator != (const T& x, const T& y) { return !(x == y); }
-template <class T> static inline bool operator > (const T& x, const T& y) { return y < x; }
-template <class T> static inline bool operator <= (const T& x, const T& y) { return !(y < x); }
-template <class T> static inline bool operator >= (const T& x, const T& y) { return !(x < y); }
-#endif
-
-
-//=================================================================================================
-}
-#endif
diff --git a/stp/sat/Heap.h b/stp/sat/Heap.h
deleted file mode 100644
index e3a82dd0..00000000
--- a/stp/sat/Heap.h
+++ /dev/null
@@ -1,151 +0,0 @@
-/******************************************************************************************[Heap.h]
-MiniSat -- Copyright (c) 2003-2005, Niklas Een, Niklas Sorensson
-
-Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
-associated documentation files (the "Software"), to deal in the Software without restriction,
-including without limitation the rights to use, copy, modify, merge, publish, distribute,
-sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all copies or
-substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
-NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
-DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
-OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-**************************************************************************************************/
-
-#ifndef Heap_h
-#define Heap_h
-
-#include "../AST/ASTUtil.h"
-namespace MINISAT {
-
-//=================================================================================================
-
-
-static inline int left (int i) { return i+i; }
-static inline int right (int i) { return i+i + 1; }
-static inline int parent(int i) { return i >> 1; }
-
-template<class C>
-class Heap {
- public:
- C comp;
- vec<int> heap; // heap of ints
- vec<int> indices; // int -> index in heap
-
- inline void percolateUp(int i)
- {
- int x = heap[i];
- while (parent(i) != 0 && comp(x,heap[parent(i)])){
- heap[i] = heap[parent(i)];
- indices[heap[i]] = i;
- i = parent(i);
- }
- heap [i] = x;
- indices[x] = i;
- }
-
- inline void percolateDown(int i)
- {
- int x = heap[i];
- while (left(i) < heap.size()){
- int child = right(i) < heap.size() && comp(heap[right(i)],heap[left(i)]) ? right(i) : left(i);
- if (!comp(heap[child],x)) break;
- heap[i] = heap[child];
- indices[heap[i]] = i;
- i = child;
- }
- heap [i] = x;
- indices[x] = i;
- }
-
- bool ok(int n) const {
- return n >= 0 && n < (int)indices.size(); }
-
- public:
- Heap(C c) : comp(c) { heap.push(-1); }
-
- void setBounds (int size) { assert(size >= 0); indices.growTo(size,0); }
- void increase (int n) { assert(ok(n)); assert(inHeap(n)); percolateUp(indices[n]); }
- bool inHeap (int n) const { assert(ok(n)); return indices[n] != 0; }
- int size () const { return heap.size()-1; }
- bool empty () const { return size() == 0; }
-
-
- void insert(int n) {
- assert(!inHeap(n));
- assert(ok(n));
- indices[n] = heap.size();
- heap.push(n);
- percolateUp(indices[n]);
- }
-
-
- int getmin() {
- //printing heap
- if(BEEV::print_sat_varorder) {
- // fprintf(stderr, "Vijay: heap before getmin: ");
- // for (uint i = 1; i < (uint)heap.size(); i++)
- // fprintf(stderr, "%d ", heap[i]);
- // fprintf(stderr, "\n");
- }
-
- int r = heap[1];
- heap[1] = heap.last();
- indices[heap[1]] = 1;
- indices[r] = 0;
- heap.pop();
- if (heap.size() > 1)
- percolateDown(1);
- return r;
- }
-
- // fool proof variant of insert/increase
- void update (int n) {
- //fprintf(stderr, "update heap: ");
- //for (uint i = 1; i < (uint)heap.size(); i++)
- // fprintf(stderr, "%d ", heap[i]);
- //fprintf(stderr, "\n");
- setBounds(n+1);
- if (!inHeap(n))
- insert(n);
- else {
- percolateUp(indices[n]);
- percolateDown(indices[n]);
- }
- }
-
-
- bool heapProperty() {
- return heapProperty(1); }
-
-
- bool heapProperty(int i) {
- return i >= heap.size()
- || ((parent(i) == 0 || !comp(heap[i],heap[parent(i)])) && heapProperty(left(i)) && heapProperty(right(i))); }
-
- template <class F> void filter(const F& filt) {
- int i,j;
- for (i = j = 1; i < heap.size(); i++)
- if (filt(heap[i])){
- heap[j] = heap[i];
- indices[heap[i]] = j++;
- }else
- indices[heap[i]] = 0;
-
- heap.shrink(i - j);
- for (int i = heap.size() / 2; i >= 1; i--)
- percolateDown(i);
-
- assert(heapProperty());
- }
-
-};
-
-//=================================================================================================
-}
-#endif
diff --git a/stp/sat/LICENSE b/stp/sat/LICENSE
deleted file mode 100644
index 590930bc..00000000
--- a/stp/sat/LICENSE
+++ /dev/null
@@ -1,20 +0,0 @@
-MiniSat -- Copyright (c) 2003-2005, Niklas Een, Niklas Sorensson
-
-Permission is hereby granted, free of charge, to any person obtaining a
-copy of this software and associated documentation files (the
-"Software"), to deal in the Software without restriction, including
-without limitation the rights to use, copy, modify, merge, publish,
-distribute, sublicense, and/or sell copies of the Software, and to
-permit persons to whom the Software is furnished to do so, subject to
-the following conditions:
-
-The above copyright notice and this permission notice shall be included
-in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/stp/sat/Makefile b/stp/sat/Makefile
deleted file mode 100644
index 25bb867f..00000000
--- a/stp/sat/Makefile
+++ /dev/null
@@ -1,19 +0,0 @@
-#===-- stp/sat/Makefile -----------------------------------*- Makefile -*--===#
-#
-# The KLEE Symbolic Virtual Machine
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-#===------------------------------------------------------------------------===#
-
-LEVEL=../..
-
-LIBRARYNAME=stp_sat
-DONT_BUILD_RELINKED=1
-BUILD_ARCHIVE=1
-
-include $(LEVEL)/Makefile.common
-
-# HACK: Force -Wno-deprecated for ext container use.
-CXX.Flags += -Wno-deprecated
diff --git a/stp/sat/Simplifier.cpp b/stp/sat/Simplifier.cpp
deleted file mode 100644
index 2e709066..00000000
--- a/stp/sat/Simplifier.cpp
+++ /dev/null
@@ -1,542 +0,0 @@
-/************************************************************************************[Simplifier.C]
-MiniSat -- Copyright (c) 2003-2006, Niklas Een, Niklas Sorensson
-
-Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
-associated documentation files (the "Software"), to deal in the Software without restriction,
-including without limitation the rights to use, copy, modify, merge, publish, distribute,
-sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all copies or
-substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
-NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
-DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
-OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-**************************************************************************************************/
-
-#include "Solver.h"
-
-namespace MINISAT {
-
-static const int grow = 0;
-
-//#define WEAKEN
-//#define MATING
-//#define ASSYMM
-
-bool Solver::assymmetricBranching(Clause& c)
-{
- assert(decisionLevel() == 0);
-
- //fprintf(stderr, "assymmetric branching on clause: "); printClause(c); fprintf(stderr, "\n");
- if (satisfied(c)){
- //fprintf(stderr, "subsumed.\n");
- return true; }
-
- int old;
- vec<Lit> copy; for (int i = 0; i < c.size(); i++) copy.push(c[i]);
-
- do {
- assert(copy.size() == c.size());
-
- old = copy.size();
-
- //fprintf(stderr, "checking that clause is normalized\n");
- //for (int i = 0; i < copy.size(); i++)
- // assert(value(copy[i]) == l_Undef);
-
- for (int i = 0; i < copy.size(); i++){
- trail_lim.push(trail.size());
- //fprintf(stderr, " -- trying to delete literal "); printLit(copy[i]);
- for (int j = 0; j < copy.size(); j++)
- if (j != i)
- check(enqueue(~copy[j]));
-
- if (propagate() != NULL){
- //fprintf(stderr, " succeeded\n");
- cancelUntil(0);
- Lit l = copy[i];
- assert(find(copy, l));
- remove(copy, l);
- if (!strengthen(c, l))
- return false;
- i--;
-
- if (c.size() == 1)
- return propagate() == NULL;
- else
- assert(qhead == trail.size());
- }
- else
- //fprintf(stderr, " failed\n");
-
- cancelUntil(0);
- }
-
- //} while (false);
- } while (copy.size() < old);
-
- return true;
-}
-
-// Returns FALSE if clause is always satisfied ('out_clause' should not be used).
-//bool Solver::merge(const Clause& _ps, const Clause& _qs, Var v, vec<Lit>& out_clause)
-bool Solver::merge(const Clause& _ps, const Clause& _qs, Var v, vec<Lit>& out_clause)
-{
- stats.merges++;
-
- bool ps_smallest = _ps.size() < _qs.size();
- const Clause& ps = ps_smallest ? _qs : _ps;
- const Clause& qs = ps_smallest ? _ps : _qs;
-
- for (int i = 0; i < qs.size(); i++){
- if (var(qs[i]) != v){
- for (int j = 0; j < ps.size(); j++)
- if (var(ps[j]) == var(qs[i])) {
- if (ps[j] == ~qs[i])
- return false;
- else
- goto next;
- }
- out_clause.push(qs[i]);
- }
- next:;
- }
-
- for (int i = 0; i < ps.size(); i++)
- if (var(ps[i]) != v)
- out_clause.push(ps[i]);
-
- return true;
-}
-
-
-void Solver::gather(vec<Clause*>& clauses)
-{
- //fprintf(stderr, "Gathering clauses for backwards subsumption\n");
- int ntouched = 0;
- assert(touched.size() == occurs.size());
- clauses.clear();
- for (int i = 0; i < touched.size(); i++)
- if (touched[i]){
- const vec<Clause*>& cs = getOccurs(i);
- ntouched++;
- for (int j = 0; j < cs.size(); j++)
- if (cs[j]->mark() == 0){
- clauses.push(cs[j]);
- cs[j]->mark(2);
- }
- touched[i] = 0;
- }
-
- //fprintf(stderr, "Touched variables %d of %d yields %d clauses to check\n", ntouched, touched.size(), clauses.size());
- for (int i = 0; i < clauses.size(); i++)
- clauses[i]->mark(0);
-}
-
-
-/*_________________________________________________________________________________________________
-|
-| subsumes : (_c : ClauseId) (c : Clause&) (_d : ClauseId) (d : Clause&) -> bool
-|
-| Description:
-| Checks if c subsumes d, and at the same time, if c can be used to simplify d by subsumption
-| resolution.
-|
-| Input:
-| Indices into the 'clauses' vector _c, _d, and references to the corresponding clauses c, d.
-|
-| Result:
-| lit_Error - No subsumption or simplification
-| lit_Undef - Clause c subsumes d
-| l - The literal l can be deleted from d
-|________________________________________________________________________________________________@*/
-inline Lit Solver::subsumes(const Clause& c, const Clause& d)
-{
- stats.subsumption_checks++;
- if (d.size() < c.size() || (c.abstraction() & ~d.abstraction()) != 0)
- return lit_Error;
-
- Lit ret = lit_Undef;
-
- for (int i = 0; i < c.size(); i++) {
- // search for c[i] or ~c[i]
- for (int j = 0; j < d.size(); j++)
- if (c[i] == d[j])
- goto ok;
- else if (ret == lit_Undef && c[i] == ~d[j]){
- ret = c[i];
- goto ok;
- }
-
- // did not find it
- stats.subsumption_misses++;
- return lit_Error;
- ok:;
- }
-
- return ret;
-}
-
-
-// Backward subsumption + backward subsumption resolution
-bool Solver::backwardSubsumptionCheck()
-{
- while (subsumption_queue.size() > 0 || qhead < trail.size()){
-
- // if propagation queue is non empty, take the first literal and
- // create a dummy unit clause
- if (qhead < trail.size()){
- Lit l = trail[qhead++];
- (*bwdsub_tmpunit)[0] = l;
- assert(bwdsub_tmpunit->mark() == 0);
- subsumption_queue.push(bwdsub_tmpunit);
- }
- Clause& c = *subsumption_queue.last(); subsumption_queue.pop();
-
- if (c.mark())
- continue;
-
- if (c.size() == 1 && !enqueue(c[0]))
- return false;
-
- // (1) find best variable to scan
- Var best = var(c[0]);
- for (int i = 1; i < c.size(); i++)
- if (occurs[var(c[i])].size() < occurs[best].size())
- best = var(c[i]);
-
- // (2) search all candidates
- const vec<Clause*>& cs = getOccurs(best);
-
- for (int j = 0; j < cs.size(); j++)
- if (cs[j] != &c){
- if (cs[j]->mark())
- continue;
- if (c.mark())
- break;
-
- //fprintf(stderr, "backward candidate "); printClause(*cs[j]); fprintf(stderr, "\n");
- Lit l = subsumes(c, *cs[j]);
- if (l == lit_Undef){
- //fprintf(stderr, "clause backwards subsumed\n");
- //fprintf(stderr, " >> clause %d: ", cs[j]->mark()); printClause(*cs[j]); fprintf(stderr, "\n");
- //fprintf(stderr, " >> clause %d: ", c.mark()); printClause(c); fprintf(stderr, "\n");
- removeClause(*cs[j], false);
- }else if (l != lit_Error){
- //fprintf(stderr, "backwards subsumption resolution\n");
- //fprintf(stderr, " >> clause %d: ", cs[j]->mark()); printClause(*cs[j]); fprintf(stderr, "\n");
- //fprintf(stderr, " >> clause %d: ", c.mark()); printClause(c); fprintf(stderr, "\n");
-
- assert(cs[j]->size() > 1);
- assert(find(*cs[j], ~l));
-
- subsumption_queue.push(cs[j]);
- if (!strengthen(*cs[j], ~l))
- return false;
-
- // did current candidate get deleted from cs? then check candidate at index j again
- if (var(l) == best)
- j--;
- }
- }
- }
-
- return true;
-}
-
-
-bool Solver::eliminateVar(Var v, bool fail)
-{
- assert(hasVarProp(v, p_frozen));
-
- vec<Clause*> pos, neg;
- const vec<Clause*>& cls = getOccurs(v);
-
- if (value(v) != l_Undef || cls.size() == 0)
- return true;
-
- //fprintf(stderr, "trying to eliminate var %d\n", v+1);
- for (int i = 0; i < cls.size(); i++){
- //fprintf(stderr, "clause: "); printClause(*cls[i]); fprintf(stderr, "\n");
- if (find(*cls[i], Lit(v)))
- pos.push(cls[i]);
- else{
- assert(find(*cls[i], ~Lit(v)));
- neg.push(cls[i]);
- }
- }
-
-#ifdef WEAKEN
- vec<int> posc(pos.size(), 0);
- vec<int> negc(neg.size(), 0);
-#endif
- // check if number of clauses decreases
- int cnt = 0;
- vec<Lit> resolvent;
- for (int i = 0; i < pos.size(); i++)
- for (int j = 0; j < neg.size(); j++){
- resolvent.clear();
- if (merge(*pos[i], *neg[j], v, resolvent)){
- cnt++;
-#ifdef WEAKEN
- posc[i]++;
- negc[j]++;
-#endif
- }
-#ifndef WEAKEN
- if (cnt > cls.size() + grow)
- return true;
-#else
-#ifdef MATING
- if (cnt > cls.size() + grow)
- if (posc[i] > 0)
- break;
-#endif
-#endif
- assert(pos.size() <= n_occ[toInt(Lit(v))]);
- assert(neg.size() <= n_occ[toInt(~Lit(v))]);
- }
-
-#ifdef WEAKEN
-#ifdef MATING
- for (int i = 0; i < neg.size(); i++)
- if (negc[i] == 0)
- for (int j = 0; j < pos.size(); j++){
- resolvent.clear();
- if (merge(*neg[i], *pos[j], v, resolvent)){
- negc[i]++;
- break;
- }
- }
-#endif
- for (int i = 0; i < pos.size(); i++)
- if (posc[i] == 0)
- removeClause(*pos[i], false);
-
- for (int i = 0; i < neg.size(); i++)
- if (negc[i] == 0)
- removeClause(*neg[i], false);
-
- if (cnt > cls.size() + grow)
- return true;
-#endif
- //if (pos.size() != n_occ[toInt(Lit(v))])
- // fprintf(stderr, "pos.size() = %d, n_occ[toInt(Lit(v))] = %d\n", pos.size(), n_occ[toInt(Lit(v))]);
- assert(pos.size() == n_occ[toInt(Lit(v))]);
- //if (neg.size() != n_occ[toInt(~Lit(v))])
- // fprintf(stderr, "neg.size() = %d, n_occ[toInt(Lit(v))] = %d\n", neg.size(), n_occ[toInt(Lit(v))]);
- assert(neg.size() == n_occ[toInt(~Lit(v))]);
- assert(cnt <= cls.size() + grow);
- setVarProp(v, p_decisionvar, false);
-
- // produce clauses in cross product
- int top = clauses.size();
- for (int i = 0; i < pos.size(); i++)
- for (int j = 0; j < neg.size(); j++){
- resolvent.clear();
-#ifdef WEAKEN
- if (pos[i]->mark() == 1)
- break;
- if (neg[j]->mark() == 1)
- continue;
-#endif
-
- if (merge(*pos[i], *neg[j], v, resolvent)){
- int i, j;
- for (i = j = 0; i < resolvent.size(); i++)
- if (value(resolvent[i]) == l_True)
- goto next;
- else if (value(resolvent[i]) == l_Undef)
- resolvent[j++] = resolvent[i];
- resolvent.shrink(i - j);
-
- if (resolvent.size() == 1){
- if (!enqueue(resolvent[0]))
- return false;
- }else{
- int apa = clauses.size();
- check(newClause(resolvent, false, true));
- assert(apa + 1 == clauses.size());
- }
- }
- next:;
- }
-
- if (fail){
- fprintf(stderr, "eliminated var %d, %d <= %d\n", v+1, cnt, cls.size());
- fprintf(stderr, "previous clauses:\n");
- for (int i = 0; i < cls.size(); i++){
- printClause(*cls[i]);
- fprintf(stderr, "\n");
- }
-
- fprintf(stderr, "new clauses:\n");
- for (int i = top; i < clauses.size(); i++){
- printClause(*clauses[i]);
- fprintf(stderr, "\n");
- }
-
- assert(0); }
-
- //fprintf(stderr, "eliminated var %d, %d <= %d\n", v+1, cnt, cls.size());
- //fprintf(stderr, "previous clauses:\n");
- //for (int i = 0; i < cls.size(); i++){
- // printClause(*cls[i]);
- // fprintf(stderr, "\n");
- //}
- //
- //fprintf(stderr, "new clauses:\n");
- //for (int i = top; i < clauses.size(); i++){
- // printClause(*clauses[i]);
- // fprintf(stderr, "\n");
- //}
-
- // delete + store old clauses
- eliminated_var.push(v);
- eliminated_lim.push(eliminated.size());
- for (int i = 0; i < cls.size(); i++){
- eliminated.push(Clause_new(*cls[i]));
-
-#ifdef WEAKEN
- if (cls[i]->mark() == 0)
-#endif
- removeClause(*cls[i], false);
-
- }
-
- assert(subsumption_queue.size() == 0);
- for (int i = top; i < clauses.size(); i++)
-#ifdef ASSYMM
- if (clauses[i]->mark() == 0)
- if (!assymmetricBranching(*clauses[i]))
- return false;
- else
- subsumption_queue.push(clauses[i]);
-#else
- if (clauses[i]->mark() == 0)
- subsumption_queue.push(clauses[i]);
-#endif
-
- return backwardSubsumptionCheck();
-}
-
-
-void Solver::extendModel()
-{
- assert(eliminated_var.size() == eliminated_lim.size());
- for (int i = eliminated_var.size()-1; i >= 0; i--){
- Var v = eliminated_var[i];
- Lit l = lit_Undef;
-
- //fprintf(stderr, "extending var %d\n", v+1);
-
- for (int j = eliminated_lim[i]; j < (i+1 >= eliminated_lim.size() ? eliminated.size() : eliminated_lim[i+1]); j++){
- assert(j < eliminated.size());
- Clause& c = *eliminated[j];
-
- //fprintf(stderr, "checking clause: "); printClause(c); fprintf(stderr, "\n");
-
- for (int k = 0; k < c.size(); k++)
- if (var(c[k]) == v)
- l = c[k];
- else if (value(c[k]) != l_False)
- goto next;
-
- assert(l != lit_Undef);
- //fprintf(stderr, "Fixing var %d to %d\n", v+1, !sign(l));
-
- assigns[v] = toInt(lbool(!sign(l)));
- break;
-
- next:;
- }
-
- if (value(v) == l_Undef)
- assigns[v] = toInt(l_True);
- }
-}
-
-
-bool Solver::eliminate()
-{
- assert(subsumption);
-
- int cnt = 0;
- //fprintf(stderr, "eliminating variables\n");
-
-#ifdef INVARIANTS
- // check that all clauses are simplified
- fprintf(stderr, "Checking that all clauses are normalized prior to variable elimination\n");
- for (int i = 0; i < clauses.size(); i++)
- if (clauses[i]->mark() == 0){
- Clause& c = *clauses[i];
- for (int j = 0; j < c.size(); j++)
- assert(value(c[j]) == l_Undef);
- }
- fprintf(stderr, "done.\n");
-#endif
-
- for (;;){
- gather(subsumption_queue);
-
- if (subsumption_queue.size() == 0 && heap.size() == 0)
- break;
-
- //fprintf(stderr, "backwards subsumption: %10d\n", subsumption_queue.size());
- if (!backwardSubsumptionCheck())
- return false;
-
- //fprintf(stderr, "variable elimination: %10d\n", heap.size());
- cnt = 0;
- for (;;){
- assert(!heap.empty() || heap.size() == 0);
- if (heap.empty())
- break;
-
- Var elim = heap.getmin();
-
- assert(hasVarProp(elim, p_frozen));
-
- //for (int i = 1; i < heap.heap.size(); i++)
- // assert(heap.comp(elim, heap.heap[i]) || !heap.comp(elim, heap.heap[i]));
-
- //if (cnt++ % 100 == 0)
- // fprintf(stderr, "left %10d\r", heap.size());
-
- if (!eliminateVar(elim))
- return false;
- }
- }
-#ifdef INVARIANTS
- // check that no more subsumption is possible
- fprintf(stderr, "Checking that no more subsumption is possible\n");
- cnt = 0;
- for (int i = 0; i < clauses.size(); i++){
- if (cnt++ % 1000 == 0)
- fprintf(stderr, "left %10d\r", clauses.size() - i);
- for (int j = 0; j < i; j++)
- assert(clauses[i]->mark() ||
- clauses[j]->mark() ||
- subsumes(*clauses[i], *clauses[j]) == lit_Error);
- }
- fprintf(stderr, "done.\n");
-
- // check that no more elimination is possible
- fprintf(stderr, "Checking that no more elimination is possible\n");
- for (int i = 0; i < nVars(); i++){
- if (hasVarProp(i, p_frozen))
- eliminateVar(i, true);
- }
- fprintf(stderr, "done.\n");
-
-#endif
-
- assert(qhead == trail.size());
-
- return true;
-}
-}
diff --git a/stp/sat/Solver.cpp b/stp/sat/Solver.cpp
deleted file mode 100644
index 9761c719..00000000
--- a/stp/sat/Solver.cpp
+++ /dev/null
@@ -1,813 +0,0 @@
-/****************************************************************************************[Solver.C]
-MiniSat -- Copyright (c) 2003-2005, Niklas Een, Niklas Sorensson
-
-Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
-associated documentation files (the "Software"), to deal in the Software without restriction,
-including without limitation the rights to use, copy, modify, merge, publish, distribute,
-sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all copies or
-substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
-NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
-DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
-OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-**************************************************************************************************/
-
-#include "Solver.h"
-#include "Sort.h"
-#include <cmath>
-
-namespace MINISAT {
-//=================================================================================================
-// Operations on clauses:
-
-
-/*_________________________________________________________________________________________________
-|
-| newClause : (ps : const vec<Lit>&) (learnt : bool) -> [void]
-|
-| Description:
-| Allocate and add a new clause to the SAT solvers clause database.
-|
-| Input:
-| ps - The new clause as a vector of literals.
-| learnt - Is the clause a learnt clause? For learnt clauses, 'ps[0]' is assumed to be the
-| asserting literal. An appropriate 'enqueue()' operation will be performed on this
-| literal. One of the watches will always be on this literal, the other will be set to
-| the literal with the highest decision level.
-|
-| Effect:
-| Activity heuristics are updated.
-|________________________________________________________________________________________________@*/
-bool Solver::newClause(const vec<Lit>& ps_, bool learnt, bool normalized)
-{
- vec<Lit> qs;
- if (!learnt && !normalized){
- assert(decisionLevel() == 0);
- ps_.copyTo(qs); // Make a copy of the input vector.
-
- // Remove duplicates:
- sortUnique(qs);
-
- // Check if clause is satisfied:
- for (int i = 0; i < qs.size()-1; i++){
- if (qs[i] == ~qs[i+1])
- return true; }
- for (int i = 0; i < qs.size(); i++){
- if (value(qs[i]) == l_True)
- return true; }
-
- // Remove false literals:
- int i, j;
- for (i = j = 0; i < qs.size(); i++)
- if (value(qs[i]) != l_False)
- qs[j++] = qs[i];
- qs.shrink(i - j);
- }
- const vec<Lit>& ps = learnt || normalized ? ps_ : qs; // 'ps' is now the (possibly) reduced vector of literals.
-
- if (ps.size() == 0)
- return false;
- else if (ps.size() == 1){
- assert(decisionLevel() == 0);
- return enqueue(ps[0]);
- }else{
- // Allocate clause:
- Clause* c = Clause_new(ps, learnt);
-
- if (learnt){
- // Put the second watch on the first literal with highest decision level:
- // (requires that this method is called at the level where the clause is asserting!)
- int i;
- for (i = 1; i < ps.size() && position(trailpos[var(ps[i])]) < trail_lim.last(); i++)
- ;
- (*c)[1] = ps[i];
- (*c)[i] = ps[1];
-
- // Bump, enqueue, store clause:
- claBumpActivity(*c); // (newly learnt clauses should be considered active)
- check(enqueue((*c)[0], c));
- learnts.push(c);
- stats.learnts_literals += c->size();
- }else{
- // Store clause:
- clauses.push(c);
- stats.clauses_literals += c->size();
-
- if (subsumption){
- c->calcAbstraction();
- for (int i = 0; i < c->size(); i++){
- assert(!find(occurs[var((*c)[i])], c));
- occurs[var((*c)[i])].push(c);
- n_occ[toInt((*c)[i])]++;
- touched[var((*c)[i])] = 1;
-
- if (heap.inHeap(var((*c)[i])))
- updateHeap(var((*c)[i]));
- }
- }
-
- }
- // Watch clause:
- watches[toInt(~(*c)[0])].push(c);
- watches[toInt(~(*c)[1])].push(c);
- }
-
- return true;
-}
-
-
-// Disposes a clauses and removes it from watcher lists. NOTE!
-// Low-level; does NOT change the 'clauses' and 'learnts' vector.
-//
-void Solver::removeClause(Clause& c, bool dealloc)
-{
- //fprintf(stderr, "delete %d: ", _c); printClause(c); fprintf(stderr, "\n");
- assert(c.mark() == 0);
-
- if (c.size() > 1){
- assert(find(watches[toInt(~c[0])], &c));
- assert(find(watches[toInt(~c[1])], &c));
- remove(watches[toInt(~c[0])], &c);
- remove(watches[toInt(~c[1])], &c); }
-
- if (c.learnt()) stats.learnts_literals -= c.size();
- else stats.clauses_literals -= c.size();
-
- if (subsumption && !c.learnt()){
- for (int i = 0; i < c.size(); i++){
- if (dealloc){
- assert(find(occurs[var(c[i])], &c));
- remove(occurs[var(c[i])], &c);
- }
- n_occ[toInt(c[i])]--;
- updateHeap(var(c[i]));
- }
- }
-
- if (dealloc)
- xfree(&c);
- else
- c.mark(1);
-}
-
-
-bool Solver::satisfied(Clause& c) const
-{
- for (int i = 0; i < c.size(); i++)
- if (value(c[i]) == l_True)
- return true;
- return false; }
-
-
-bool Solver::strengthen(Clause& c, Lit l)
-{
- assert(decisionLevel() == 0);
- assert(c.size() > 1);
- assert(c.mark() == 0);
-
- assert(toInt(~c[0]) < watches.size());
- assert(toInt(~c[1]) < watches.size());
-
- assert(find(watches[toInt(~c[0])], &c));
- assert(find(watches[toInt(~c[1])], &c));
- assert(find(c,l));
-
- if (c.learnt()) stats.learnts_literals -= 1;
- else stats.clauses_literals -= 1;
-
- if (c[0] == l || c[1] == l){
- assert(find(watches[toInt(~l)], &c));
- remove(c,l);
- remove(watches[toInt(~l)], &c);
- if (c.size() > 1){
- assert(!find(watches[toInt(~c[1])], &c));
- watches[toInt(~c[1])].push(&c); }
- else {
- assert(find(watches[toInt(~c[0])], &c));
- remove(watches[toInt(~c[0])], &c);
- removeClause(c, false);
- }
- }
- else
- remove(c,l);
-
- assert(c.size() == 1 || find(watches[toInt(~c[0])], &c));
- assert(c.size() == 1 || find(watches[toInt(~c[1])], &c));
-
- if (subsumption){
- assert(find(occurs[var(l)], &c));
- remove(occurs[var(l)], &c);
- assert(!find(occurs[var(l)], &c));
-
- c.calcAbstraction();
-
- n_occ[toInt(l)]--;
- updateHeap(var(l));
- }
-
- return c.size() == 1 ? enqueue(c[0]) : true;
-}
-
-
-//=================================================================================================
-// Minor methods:
-
-
-// Creates a new SAT variable in the solver. If 'decision_var' is cleared, variable will not be
-// used as a decision variable (NOTE! This has effects on the meaning of a SATISFIABLE result).
-//
-Var Solver::newVar(bool polarity, bool dvar) {
- int index;
- index = nVars();
- watches .push(); // (list for positive literal)
- watches .push(); // (list for negative literal)
- reason .push(NULL);
- assigns .push(toInt(l_Undef));
- trailpos .push(TrailPos(0,0));
- activity .push(0);
- order .newVar(polarity,dvar);
- seen .push(0);
- touched .push(0);
- if (subsumption){
- occurs .push();
- n_occ .push(0);
- n_occ .push(0);
- heap .setBounds(index+1);
- }
- return index; }
-
-
-// Returns FALSE if immediate conflict.
-bool Solver::assume(Lit p) {
- trail_lim.push(trail.size());
- return enqueue(p); }
-
-
-// Revert to the state at given level.
-void Solver::cancelUntil(int level) {
- if (decisionLevel() > level){
- for (int c = trail.size()-1; c >= trail_lim[level]; c--){
- Var x = var(trail[c]);
- assigns[x] = toInt(l_Undef);
- reason [x] = NULL;
- order.undo(x); }
- qhead = trail_lim[level];
- trail.shrink(trail.size() - trail_lim[level]);
- trail_lim.shrink(trail_lim.size() - level);
- }
-}
-
-
-//=================================================================================================
-// Major methods:
-
-
-/*_________________________________________________________________________________________________
-|
-| analyze : (confl : Clause*) (out_learnt : vec<Lit>&) (out_btlevel : int&) -> [void]
-|
-| Description:
-| Analyze conflict and produce a reason clause.
-|
-| Pre-conditions:
-| * 'out_learnt' is assumed to be cleared.
-| * Current decision level must be greater than root level.
-|
-| Post-conditions:
-| * 'out_learnt[0]' is the asserting literal at level 'out_btlevel'.
-|
-| Effect:
-| Will undo part of the trail, upto but not beyond the assumption of the current decision level.
-|________________________________________________________________________________________________@*/
-void Solver::analyze(Clause* confl, vec<Lit>& out_learnt, int& out_btlevel)
-{
- int pathC = 0;
- int btpos = -1;
- Lit p = lit_Undef;
-
- // Generate conflict clause:
- //
- out_learnt.push(); // (leave room for the asserting literal)
- int index = trail.size()-1;
- do{
- assert(confl != NULL); // (otherwise should be UIP)
- Clause& c = *confl;
-
- if (c.learnt())
- claBumpActivity(c);
-
- for (int j = (p == lit_Undef) ? 0 : 1; j < c.size(); j++){
- Lit q = c[j];
- if (!seen[var(q)] && position(trailpos[var(q)]) >= trail_lim[0]){
- varBumpActivity(q);
- seen[var(q)] = 1;
- if (position(trailpos[var(q)]) >= trail_lim.last())
- pathC++;
- else{
- out_learnt.push(q);
- btpos = max(btpos, position(trailpos[var(q)]));
- }
- }
- }
-
- // Select next clause to look at:
- while (!seen[var(trail[index--])]) ;
- p = trail[index+1];
- confl = reason[var(p)];
- seen[var(p)] = 0;
- pathC--;
-
- }while (pathC > 0);
- out_learnt[0] = ~p;
-
- // Find correct backtrack level
- for (out_btlevel = trail_lim.size()-1; out_btlevel > 0 && trail_lim[out_btlevel-1] > btpos; out_btlevel--)
- ;
-
- int i, j;
- if (expensive_ccmin){
- // Simplify conflict clause (a lot):
- //
- uint min_level = 0;
- for (i = 1; i < out_learnt.size(); i++)
- min_level |= abstractLevel(trailpos[var(out_learnt[i])]); // (maintain an abstraction of levels involved in conflict)
-
- out_learnt.copyTo(analyze_toclear);
- for (i = j = 1; i < out_learnt.size(); i++)
- if (reason[var(out_learnt[i])] == NULL || !analyze_removable(out_learnt[i], min_level))
- out_learnt[j++] = out_learnt[i];
- }else{
- // Simplify conflict clause (a little):
- //
- out_learnt.copyTo(analyze_toclear);
- for (i = j = 1; i < out_learnt.size(); i++){
- Clause& c = *reason[var(out_learnt[i])];
- for (int k = 1; k < c.size(); k++)
- if (!seen[var(c[k])] && position(trailpos[var(c[k])]) >= trail_lim[0]){
- out_learnt[j++] = out_learnt[i];
- break; }
- }
- }
-
- stats.max_literals += out_learnt.size();
- out_learnt.shrink(i - j);
- stats.tot_literals += out_learnt.size();
-
- for (int j = 0; j < analyze_toclear.size(); j++) seen[var(analyze_toclear[j])] = 0; // ('seen[]' is now cleared)
-}
-
-
-// Check if 'p' can be removed. 'min_level' is used to abort early if visiting literals at a level that cannot be removed.
-//
-bool Solver::analyze_removable(Lit p, uint min_level)
-{
- analyze_stack.clear(); analyze_stack.push(p);
- int top = analyze_toclear.size();
- while (analyze_stack.size() > 0){
- assert(reason[var(analyze_stack.last())] != NULL);
- Clause& c = *reason[var(analyze_stack.last())]; analyze_stack.pop();
-
- for (int i = 1; i < c.size(); i++){
- Lit p = c[i];
- TrailPos tp = trailpos[var(p)];
- if (!seen[var(p)] && position(tp) >= trail_lim[0]){
- if (reason[var(p)] != NULL && (abstractLevel(tp) & min_level) != 0){
- seen[var(p)] = 1;
- analyze_stack.push(p);
- analyze_toclear.push(p);
- }else{
- for (int j = top; j < analyze_toclear.size(); j++)
- seen[var(analyze_toclear[j])] = 0;
- analyze_toclear.shrink(analyze_toclear.size() - top);
- return false;
- }
- }
- }
- }
-
- return true;
-}
-
-
-/*_________________________________________________________________________________________________
-|
-| analyzeFinal : (p : Lit) -> [void]
-|
-| Description:
-| Specialized analysis procedure to express the final conflict in terms of assumptions.
-| Calculates the (possibly empty) set of assumptions that led to the assignment of 'p', and
-| stores the result in 'out_conflict'.
-|________________________________________________________________________________________________@*/
-void Solver::analyzeFinal(Lit p, vec<Lit>& out_conflict)
-{
- out_conflict.clear();
- out_conflict.push(p);
-
- if (decisionLevel() == 0)
- return;
-
- seen[var(p)] = 1;
-
- int start = position(trailpos[var(p)]);
- for (int i = start; i >= trail_lim[0]; i--){
- Var x = var(trail[i]);
- if (seen[x]){
- if (reason[x] == NULL){
- assert(position(trailpos[x]) >= trail_lim[0]);
- out_conflict.push(~trail[i]);
- }else{
- Clause& c = *reason[x];
- for (int j = 1; j < c.size(); j++)
- if (position(trailpos[var(c[j])]) >= trail_lim[0])
- seen[var(c[j])] = 1;
- }
- seen[x] = 0;
- }
- }
-}
-
-
-/*_________________________________________________________________________________________________
-|
-| enqueue : (p : Lit) (from : Clause*) -> [bool]
-|
-| Description:
-| Puts a new fact on the propagation queue as well as immediately updating the variable's value.
-| Should a conflict arise, FALSE is returned.
-|
-| Input:
-| p - The fact to enqueue
-| from - [Optional] Fact propagated from this (currently) unit clause. Stored in 'reason[]'.
-| Default value is NULL (no reason).
-|
-| Output:
-| TRUE if fact was enqueued without conflict, FALSE otherwise.
-|________________________________________________________________________________________________@*/
-bool Solver::enqueue(Lit p, Clause* from)
-{
-
- if (value(p) != l_Undef)
- return value(p) != l_False;
- else{
- assigns [var(p)] = toInt(lbool(!sign(p)));
- trailpos[var(p)] = TrailPos(trail.size(),decisionLevel());
- reason [var(p)] = from;
- trail.push(p);
- return true;
- }
-}
-
-
-/*_________________________________________________________________________________________________
-|
-| propagate : [void] -> [Clause*]
-|
-| Description:
-| Propagates all enqueued facts. If a conflict arises, the conflicting clause is returned,
-| otherwise NULL.
-|
-| Post-conditions:
-| * the propagation queue is empty, even if there was a conflict.
-|________________________________________________________________________________________________@*/
-Clause* Solver::propagate()
-{
- if (decisionLevel() == 0 && subsumption)
- return backwardSubsumptionCheck() ? NULL : propagate_tmpempty;
-
- Clause* confl = NULL;
- //fprintf(stderr, "propagate, qhead = %d, qtail = %d\n", qhead, qtail);
- while (qhead < trail.size()){
- stats.propagations++;
- simpDB_props--;
-
- Lit p = trail[qhead++]; // 'p' is enqueued fact to propagate.
- vec<Clause*>& ws = watches[toInt(p)];
- Clause **i, **j, **end;
-
- for (i = j = (Clause**)ws, end = i + ws.size(); i != end;){
- Clause& c = **i++;
-
- // Make sure the false literal is data[1]:
- Lit false_lit = ~p;
- if (c[0] == false_lit)
- c[0] = c[1], c[1] = false_lit;
-
- assert(c[1] == false_lit);
-
- // If 0th watch is true, then clause is already satisfied.
- Lit first = c[0];
- if (value(first) == l_True){
- *j++ = &c;
- }else{
- // Look for new watch:
- for (int k = 2; k < c.size(); k++)
- if (value(c[k]) != l_False){
- c[1] = c[k]; c[k] = false_lit;
- watches[toInt(~c[1])].push(&c);
- goto FoundWatch; }
-
- // Did not find watch -- clause is unit under assignment:
- *j++ = &c;
- if (!enqueue(first, &c)){
- confl = &c;
- qhead = trail.size();
- // Copy the remaining watches:
- while (i < end)
- *j++ = *i++;
- }
- FoundWatch:;
- }
- }
- ws.shrink(i - j);
- }
-
- return confl;
-}
-
-
-/*_________________________________________________________________________________________________
-|
-| reduceDB : () -> [void]
-|
-| Description:
-| Remove half of the learnt clauses, minus the clauses locked by the current assignment. Locked
-| clauses are clauses that are reason to some assignment. Binary clauses are never removed.
-|________________________________________________________________________________________________@*/
-struct reduceDB_lt { bool operator () (Clause* x, Clause* y) { return x->size() > 2 && (y->size() == 2 || x->activity() < y->activity()); } };
-void Solver::reduceDB()
-{
- int i, j;
- double extra_lim = cla_inc / learnts.size(); // Remove any clause below this activity
-
- sort(learnts, reduceDB_lt());
- for (i = j = 0; i < learnts.size() / 2; i++){
- if (learnts[i]->size() > 2 && !locked(*learnts[i]))
- removeClause(*learnts[i]);
- else
- learnts[j++] = learnts[i];
- }
- for (; i < learnts.size(); i++){
- if (learnts[i]->size() > 2 && !locked(*learnts[i]) && learnts[i]->activity() < extra_lim)
- removeClause(*learnts[i]);
- else
- learnts[j++] = learnts[i];
- }
- learnts.shrink(i - j);
-}
-
-
-/*_________________________________________________________________________________________________
-|
-| simplifyDB : [void] -> [bool]
-|
-| Description:
-| Simplify the clause database according to the current top-level assigment. Currently, the only
-| thing done here is the removal of satisfied clauses, but more things can be put here.
-|________________________________________________________________________________________________@*/
-bool Solver::simplifyDB(bool expensive)
-{
- assert(decisionLevel() == 0);
- if (!ok || propagate() != NULL)
- return ok = false;
-
- if (nAssigns() == simpDB_assigns ||
- (!subsumption && simpDB_props > 0)) // (nothing has changed or preformed a simplification too recently)
- return true;
-
- if (subsumption){
- if (expensive && !eliminate())
- return ok = false;
-
- // Move this cleanup code to its own method ?
- int i , j;
- vec<Var> dirty;
- for (i = 0; i < clauses.size(); i++)
- if (clauses[i]->mark() == 1){
- Clause& c = *clauses[i];
- for (int k = 0; k < c.size(); k++)
- if (!seen[var(c[k])]){
- seen[var(c[k])] = 1;
- dirty.push(var(c[k]));
- }
- }
-
- for (i = 0; i < dirty.size(); i++){
- cleanOcc(dirty[i]);
- seen[dirty[i]] = 0;
- }
-
- for (i = j = 0; i < clauses.size(); i++)
- if (clauses[i]->mark() == 1)
- xfree(clauses[i]);
- else
- clauses[j++] = clauses[i];
- clauses.shrink(i - j);
- }
-
- // Remove satisfied clauses:
- for (int type = 0; type < (subsumption ? 1 : 2); type++){ // (only scan learnt clauses if subsumption is on)
- vec<Clause*>& cs = type ? learnts : clauses;
- int j = 0;
- for (int i = 0; i < cs.size(); i++){
- assert(cs[i]->mark() == 0);
- if (satisfied(*cs[i]))
- removeClause(*cs[i]);
- else
- cs[j++] = cs[i];
- }
- cs.shrink(cs.size()-j);
- }
- order.cleanup();
-
- simpDB_assigns = nAssigns();
- simpDB_props = stats.clauses_literals + stats.learnts_literals; // (shouldn't depend on 'stats' really, but it will do for now)
-
- return true;
-}
-
-
-/*_________________________________________________________________________________________________
-|
-| search : (nof_conflicts : int) (nof_learnts : int) (params : const SearchParams&) -> [lbool]
-|
-| Description:
-| Search for a model the specified number of conflicts, keeping the number of learnt clauses
-| below the provided limit. NOTE! Use negative value for 'nof_conflicts' or 'nof_learnts' to
-| indicate infinity.
-|
-| Output:
-| 'l_True' if a partial assigment that is consistent with respect to the clauseset is found. If
-| all variables are decision variables, this means that the clause set is satisfiable. 'l_False'
-| if the clause set is unsatisfiable. 'l_Undef' if the bound on number of conflicts is reached.
-|________________________________________________________________________________________________@*/
-lbool Solver::search(int nof_conflicts, int nof_learnts)
-{
- assert(ok);
- int backtrack_level;
- int conflictC = 0;
- vec<Lit> learnt_clause;
-
- stats.starts++;
- var_decay = 1 / params.var_decay;
- cla_decay = 1 / params.clause_decay;
-
- for (;;){
- Clause* confl = propagate();
- if (confl != NULL){
- // CONFLICT
- stats.conflicts++; conflictC++;
- if (decisionLevel() == 0) return l_False;
-
- learnt_clause.clear();
- analyze(confl, learnt_clause, backtrack_level);
- cancelUntil(backtrack_level);
- newClause(learnt_clause, true);
- varDecayActivity();
- claDecayActivity();
-
- }else{
- // NO CONFLICT
-
- if (nof_conflicts >= 0 && conflictC >= nof_conflicts){
- // Reached bound on number of conflicts:
- progress_estimate = progressEstimate();
- cancelUntil(0);
- return l_Undef; }
-
- // Simplify the set of problem clauses:
- if (decisionLevel() == 0 && !simplifyDB())
- return l_False;
-
- if (nof_learnts >= 0 && learnts.size()-nAssigns() >= nof_learnts)
- // Reduce the set of learnt clauses:
- reduceDB();
-
- Lit next = lit_Undef;
-
- if (decisionLevel() < assumptions.size()){
- // Perform user provided assumption:
- next = assumptions[decisionLevel()];
- if (value(next) == l_False){
- analyzeFinal(~next, conflict);
- return l_False; }
- }else{
- // New variable decision:
- stats.decisions++;
- next = order.select(params.random_var_freq, decisionLevel());
- }
- if (next == lit_Undef)
- // Model found:
- return l_True;
-
- check(assume(next));
- }
- }
-}
-
-
-// Return search-space coverage. Not extremely reliable.
-//
-double Solver::progressEstimate()
-{
- double progress = 0;
- double F = 1.0 / nVars();
-
- for (int i = 0; i <= decisionLevel(); i++){
- int beg = i == 0 ? 0 : trail_lim[i - 1];
- int end = i == decisionLevel() ? trail.size() : trail_lim[i];
- progress += pow(F, i) * (end - beg);
- }
-
- return progress / nVars();
-}
-
-
-// Divide all variable activities by 1e100.
-//
-void Solver::varRescaleActivity()
-{
- for (int i = 0; i < nVars(); i++)
- activity[i] *= 1e-100;
- var_inc *= 1e-100;
-}
-
-
-// Divide all constraint activities by 1e100.
-//
-void Solver::claRescaleActivity()
-{
- for (int i = 0; i < learnts.size(); i++)
- learnts[i]->activity() *= 1e-20;
- cla_inc *= 1e-20;
-}
-
-
-/*_________________________________________________________________________________________________
-|
-| solve : (assumps : const vec<Lit>&) -> [bool]
-|
-| Description:
-| Top-level solve.
-|________________________________________________________________________________________________@*/
-bool Solver::solve(const vec<Lit>& assumps)
-{
- model.clear();
- conflict.clear();
-
- if (!simplifyDB(true)) return false;
-
-
- double nof_conflicts = params.restart_first;
- double nof_learnts = nClauses() * params.learntsize_factor;
- lbool status = l_Undef;
- assumps.copyTo(assumptions);
-
- if (verbosity >= 1){
- printf("==================================[MINISAT]====================================\n");
- printf("| Conflicts | ORIGINAL | LEARNT | Progress |\n");
- printf("| | Vars Clauses Literals | Limit Clauses Lit/Cl | |\n");
- printf("===============================================================================\n");
- }
-
- // Search:
- while (status == l_Undef){
- if (verbosity >= 1)
- //printf("| %9d | %7d %8d | %7d %7d %8d %7.1f | %6.3f %% |\n", (int)stats.conflicts, nClauses(), (int)stats.clauses_literals, (int)nof_learnts, nLearnts(), (int)stats.learnts_literals, (double)stats.learnts_literals/nLearnts(), progress_estimate*100);
- printf("| %9d | %7d %8d %8d | %8d %8d %6.0f | %6.3f %% |\n", (int)stats.conflicts, order.size(), nClauses(), (int)stats.clauses_literals, (int)nof_learnts, nLearnts(), (double)stats.learnts_literals/nLearnts(), progress_estimate*100);
- status = search((int)nof_conflicts, (int)nof_learnts);
- nof_conflicts *= params.restart_inc;
- nof_learnts *= params.learntsize_inc;
- }
-
- if (verbosity >= 1) {
- printf("==============================================================================\n");
- fflush(stdout);
- }
-
- if (status == l_True){
- // Copy model:
- extendModel();
-#if 1
- //fprintf(stderr, "Verifying model.\n");
- for (int i = 0; i < clauses.size(); i++)
- assert(satisfied(*clauses[i]));
- for (int i = 0; i < eliminated.size(); i++)
- assert(satisfied(*eliminated[i]));
-#endif
- model.growTo(nVars());
- for (int i = 0; i < nVars(); i++) model[i] = value(i);
- }else{
- assert(status == l_False);
- if (conflict.size() == 0)
- ok = false;
- }
-
- cancelUntil(0);
- return status == l_True;
-}
-} //end of MINISAT namespace
diff --git a/stp/sat/Solver.h b/stp/sat/Solver.h
deleted file mode 100644
index 0a6dc87e..00000000
--- a/stp/sat/Solver.h
+++ /dev/null
@@ -1,356 +0,0 @@
-/****************************************************************************************[Solver.h]
-MiniSat -- Copyright (c) 2003-2005, Niklas Een, Niklas Sorensson
-
-Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
-associated documentation files (the "Software"), to deal in the Software without restriction,
-including without limitation the rights to use, copy, modify, merge, publish, distribute,
-sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all copies or
-substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
-NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
-DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
-OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-**************************************************************************************************/
-
-#ifndef Solver_h
-#define Solver_h
-
-#include "SolverTypes.h"
-#include "VarOrder.h"
-
-namespace MINISAT {
-
-//=================================================================================================
-// Solver -- the main class:
-struct SolverStats {
- int64 starts, decisions, propagations, conflicts;
- int64 clauses_literals, learnts_literals, max_literals, tot_literals;
- int64 subsumption_checks, subsumption_misses, merges;
- SolverStats() :
- starts(0), decisions(0), propagations(0), conflicts(0)
- , clauses_literals(0), learnts_literals(0), max_literals(0), tot_literals(0)
- , subsumption_checks(0), subsumption_misses(0), merges(0)
- { }
-};
-
-
-struct SearchParams {
- double var_decay, clause_decay, random_var_freq;
- double restart_inc, learntsize_inc, learntsize_factor;
- int restart_first;
-
- SearchParams(double v = 0.95, double c = 0.999, double r = 0.02,
- double ri = 1.5, double li = 1.1, double lf = (double)1/(double)3,
- int rf = 100) :
- var_decay(v), clause_decay(c), random_var_freq(r),
- restart_inc(ri), learntsize_inc(li), learntsize_factor(lf),
- restart_first(rf) { }
-};
-
- struct ElimLt {
- const vec<int>& n_occ;
-
- ElimLt(const vec<int>& no) : n_occ(no) {}
- int cost (Var x) const { return n_occ[toInt(Lit(x))] * n_occ[toInt(~Lit(x))]; }
- bool operator()(Var x, Var y) const { return cost(x) < cost(y); }
- };
-
-class Solver {
-protected:
- // Solver state:
- bool ok; // If FALSE,the constraints are already unsatisfiable.
- // No part of solver state may be used!
- vec<Clause*> clauses; // List of problem clauses.
- vec<Clause*> learnts; // List of learnt clauses.
- int n_bin_clauses; // Keep track of number of binary clauses "inlined" into the watcher lists (we do this primarily to get identical behavior to the version without the binary clauses trick).
- double cla_inc; // Amount to bump next clause with.
- double cla_decay; // INVERSE decay factor for clause activity: stores 1/decay.
-
- vec<double> activity; // A heuristic measurement of the activity of a variable.
- double var_inc; // Amount to bump next variable with.
- double var_decay; // INVERSE decay factor for variable activity: stores 1/decay. Use negative value for static variable order.
- VarOrder order; // Keeps track of the decision variable order.
- vec<char> properties; // TODO: describe!!!
-
- vec<vec<Clause*> > watches; // 'watches[lit]' is a list of constraints watching 'lit' (will go there if literal becomes true).
- vec<char> assigns; // The current assignments (lbool:s stored as char:s).
- vec<Lit> trail; // Assignment stack; stores all assigments made in the order they were made.
- vec<int> trail_lim; // Separator indices for different decision levels in 'trail'.
- vec<Clause*> reason; // 'reason[var]' is the clause that implied the variables current value, or 'NULL' if none.
- vec<TrailPos> trailpos; // 'trailpos[var]' contains the position in the trail at wich the assigment was made.
- int qhead; // Head of queue (as index into the trail -- no more explicit propagation queue in MiniSat).
- int simpDB_assigns; // Number of top-level assignments since last execution of 'simplifyDB()'.
- int64 simpDB_props; // Remaining number of propagations that must be made before next execution of 'simplifyDB()'.
- vec<Lit> assumptions; // Current set of assumptions provided to solve by the user.
-
- bool subsumption;
- vec<char> touched;
- vec<vec<Clause*> > occurs;
- vec<int> n_occ;
- Heap<ElimLt> heap;
- vec<Clause*> subsumption_queue;
-
- vec<Clause*> eliminated;
- vec<int> eliminated_lim;
- vec<Var> eliminated_var;
-
- // Temporaries (to reduce allocation overhead). Each variable is prefixed by the method in which it is
- // used, exept 'seen' wich is used in several places.
- //
- vec<char> seen;
- vec<Lit> analyze_stack;
- vec<Lit> analyze_toclear;
- Clause* propagate_tmpempty;
- Clause* propagate_tmpbin;
- Clause* analyze_tmpbin;
- Clause* bwdsub_tmpunit;
-
- vec<Lit> addBinary_tmp;
- vec<Lit> addTernary_tmp;
-
- // Main internal methods:
- //
- bool assume (Lit p);
- void cancelUntil (int level);
- void record (const vec<Lit>& clause);
-
- void analyze (Clause* confl, vec<Lit>& out_learnt, int& out_btlevel); // (bt = backtrack)
- bool analyze_removable(Lit p, uint min_level); // (helper method for 'analyze()')
- void analyzeFinal (Lit p, vec<Lit>& out_conflict);
- bool enqueue (Lit fact, Clause* from = NULL);
- Clause* propagate ();
- void reduceDB ();
- Lit pickBranchLit ();
- lbool search (int nof_conflicts, int nof_learnts);
- double progressEstimate ();
-
- // Variable properties:
- void setVarProp (Var v, uint prop, bool b) { order.setVarProp(v, prop, b); }
- bool hasVarProp (Var v, uint prop) const { return order.hasVarProp(v, prop); }
- void updateHeap (Var v) {
- if (hasVarProp(v, p_frozen))
- heap.update(v); }
-
- // Simplification methods:
- //
- void cleanOcc (Var v) {
- assert(subsumption);
- vec<Clause*>& occ = occurs[v];
- int i, j;
- for (i = j = 0; i < occ.size(); i++)
- if (occ[i]->mark() != 1)
- occ[j++] = occ[i];
- occ.shrink(i - j);
- }
-
- vec<Clause*>& getOccurs (Var x) { cleanOcc(x); return occurs[x]; }
- void gather (vec<Clause*>& clauses);
- Lit subsumes (const Clause& c, const Clause& d);
- bool assymmetricBranching (Clause& c);
- bool merge (const Clause& _ps, const Clause& _qs, Var v, vec<Lit>& out_clause);
-
- bool backwardSubsumptionCheck ();
- bool eliminateVar (Var v, bool fail = false);
- bool eliminate ();
- void extendModel ();
-
- // Activity:
- //
- void varBumpActivity(Lit p) {
- if (var_decay < 0) return; // (negative decay means static variable order -- don't bump)
- if ( (activity[var(p)] += var_inc) > 1e100 ) varRescaleActivity();
- order.update(var(p)); }
- void varDecayActivity () { if (var_decay >= 0) var_inc *= var_decay; }
- void varRescaleActivity();
- void claDecayActivity () { cla_inc *= cla_decay; }
- void claRescaleActivity();
-
- // Operations on clauses:
- //
- bool newClause(const vec<Lit>& ps, bool learnt = false, bool normalized = false);
- void claBumpActivity (Clause& c) { if ( (c.activity() += cla_inc) > 1e20 ) claRescaleActivity(); }
- bool locked (const Clause& c) const { return reason[var(c[0])] == &c; }
- bool satisfied (Clause& c) const;
- bool strengthen (Clause& c, Lit l);
- void removeClause (Clause& c, bool dealloc = true);
-
- int decisionLevel() const { return trail_lim.size(); }
-
-public:
- Solver() : ok (true)
- , n_bin_clauses (0)
- , cla_inc (1)
- , cla_decay (1)
- , var_inc (1)
- , var_decay (1)
- , order (assigns, activity)
- , qhead (0)
- , simpDB_assigns (-1)
- , simpDB_props (0)
- , subsumption (true)
- , heap (n_occ)
- , params ()
- , expensive_ccmin (true)
- , verbosity (0)
- , progress_estimate(0)
- {
- vec<Lit> dummy(2,lit_Undef);
- propagate_tmpbin = Clause_new(dummy);
- analyze_tmpbin = Clause_new(dummy);
- dummy.pop();
- bwdsub_tmpunit = Clause_new(dummy);
- dummy.pop();
- propagate_tmpempty = Clause_new(dummy);
- addBinary_tmp .growTo(2);
- addTernary_tmp.growTo(3);
- }
-
- ~Solver() {
- xfree(propagate_tmpbin);
- xfree(analyze_tmpbin);
- xfree(bwdsub_tmpunit);
- xfree(propagate_tmpempty);
- for (int i = 0; i < eliminated.size(); i++) xfree(eliminated[i]);
- for (int i = 0; i < learnts.size(); i++) xfree(learnts[i]);
- for (int i = 0; i < clauses.size(); i++) xfree(clauses[i]); }
-
- // Helpers: (semi-internal)
- //
- lbool value(Var x) const { return toLbool(assigns[x]); }
- lbool value(Lit p) const { return sign(p) ? ~toLbool(assigns[var(p)]) : toLbool(assigns[var(p)]); }
-
- int nAssigns() { return trail.size(); }
- int nClauses() { return clauses.size(); }
- int nLearnts() { return learnts.size(); }
- int nConflicts() { return (int)stats.conflicts; }
-
- // Statistics: (read-only member variable)
- //
- SolverStats stats;
-
- // Mode of operation:
- //
- SearchParams params; // Restart frequency etc.
- bool expensive_ccmin; // Controls conflict clause minimization. TRUE by default.
- int verbosity; // Verbosity level. 0=silent, 1=some progress report, 2=everything
-
- // Problem specification:
- //
- Var newVar (bool polarity = true, bool dvar = true);
- int nVars () { return assigns.size(); }
- bool addUnit (Lit p) { return ok && (ok = enqueue(p)); }
- bool addBinary (Lit p, Lit q) { addBinary_tmp [0] = p; addBinary_tmp [1] = q; return addClause(addBinary_tmp); }
- bool addTernary(Lit p, Lit q, Lit r) { addTernary_tmp[0] = p; addTernary_tmp[1] = q; addTernary_tmp[2] = r; return addClause(addTernary_tmp); }
- bool addClause (const vec<Lit>& ps) { if (ok && !newClause(ps)) ok = false; return ok; }
-
- // Variable mode:
- //
- void freezeVar (Var v) { setVarProp(v, p_frozen, true); updateHeap(v); }
-
- // Solving:
- //
- bool okay () { return ok; } // FALSE means solver is in a conflicting state
- bool simplifyDB (bool expensive = true);
- bool solve (const vec<Lit>& assumps);
- bool solve () { vec<Lit> tmp; return solve(tmp); }
- void turnOffSubsumption() {
- subsumption = false;
- occurs.clear(true);
- n_occ.clear(true);
- }
-
- double progress_estimate; // Set by 'search()'.
- vec<lbool> model; // If problem is satisfiable, this vector contains the model (if any).
- vec<Lit> conflict; // If problem is unsatisfiable (possibly under assumptions), this vector represent the conflict clause expressed in the assumptions.
-
- double returnActivity(int i) { return activity[i];}
- void updateInitialActivity(int i, double act) {activity[i] = act; order.heap.update(i);}
-};
-
-
-//=================================================================================================
-// Debug:
-
-
-#define L_LIT "%sx%d"
-#define L_lit(p) sign(p)?"~":"", var(p)
-
-// Just like 'assert()' but expression will be evaluated in the release version as well.
-inline void check(bool expr) { assert(expr); }
-
-static void printLit(Lit l)
-{
- fprintf(stderr, "%s%d", sign(l) ? "-" : "", var(l)+1);
-}
-
-template<class C>
-static void printClause(const C& c)
-{
- for (int i = 0; i < c.size(); i++){
- printLit(c[i]);
- fprintf(stderr, " ");
- }
-}
-
-//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-#ifdef _MSC_VER
-
-#include <ctime>
-
-static inline double cpuTime(void) {
- return (double)clock() / CLOCKS_PER_SEC; }
-
-static inline int64 memUsed() {
- return 0; }
-
-//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-#else
-
-#include <sys/time.h>
-#include <sys/resource.h>
-
-static inline double cpuTime(void) {
- struct rusage ru;
- getrusage(RUSAGE_SELF, &ru);
- return (double)ru.ru_utime.tv_sec + (double)ru.ru_utime.tv_usec / 1000000; }
-
-#if defined(__linux__) || defined(__CYGWIN__)
-static inline int memReadStat(int field)
-{
- char name[256];
- pid_t pid = getpid();
- sprintf(name, "/proc/%d/statm", pid);
- FILE* in = fopen(name, "rb");
- if (in == NULL) return 0;
- int value;
- for (; field >= 0; field--) {
- int res = fscanf(in, "%d", &value);
- (void) res;
- }
- fclose(in);
- return value;
-}
-
-static inline int64 memUsed() { return (int64)memReadStat(0) * (int64)getpagesize(); }
-#else
-// use this by default. Mac OS X (Darwin) does not define an os type
-//defined(__FreeBSD__)
-
-static inline int64 memUsed(void) {
- struct rusage ru;
- getrusage(RUSAGE_SELF, &ru);
- return ru.ru_maxrss*1024; }
-
-#endif
-
-//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-#endif
-
-//=================================================================================================
-}
-#endif
diff --git a/stp/sat/SolverTypes.h b/stp/sat/SolverTypes.h
deleted file mode 100644
index fe15a968..00000000
--- a/stp/sat/SolverTypes.h
+++ /dev/null
@@ -1,132 +0,0 @@
-/***********************************************************************************[SolverTypes.h]
-MiniSat -- Copyright (c) 2003-2005, Niklas Een, Niklas Sorensson
-
-Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
-associated documentation files (the "Software"), to deal in the Software without restriction,
-including without limitation the rights to use, copy, modify, merge, publish, distribute,
-sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all copies or
-substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
-NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
-DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
-OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-**************************************************************************************************/
-
-
-#ifndef SolverTypes_h
-#define SolverTypes_h
-
-#include "Global.h"
-
-namespace MINISAT {
-
-//=================================================================================================
-// Variables, literals, clause IDs:
-
-
-// NOTE! Variables are just integers. No abstraction here. They should be chosen from 0..N,
-// so that they can be used as array indices.
-
-typedef int Var;
-#define var_Undef (-1)
-
-
-struct Lit {
- int x;
-
- Lit() : x(2*var_Undef) { } // (lit_Undef)
- explicit Lit(Var var, bool sign = false) : x((var+var) + (int)sign) { }
-};
-
-// Don't use these for constructing/deconstructing literals. Use the normal constructors instead.
-inline int toInt (Lit p) { return p.x; } // A "toInt" method that guarantees small, positive integers suitable for array indexing.
-inline Lit toLit (int i) { Lit p; p.x = i; return p; } // Inverse of 'toInt()'
-
-inline Lit operator ~(Lit p) { Lit q; q.x = p.x ^ 1; return q; }
-inline bool sign (Lit p) { return p.x & 1; }
-inline int var (Lit p) { return p.x >> 1; }
-inline Lit unsign (Lit p) { Lit q; q.x = p.x & ~1; return q; }
-inline Lit id (Lit p, bool sgn) { Lit q; q.x = p.x ^ (int)sgn; return q; }
-
-inline bool operator == (Lit p, Lit q) { return toInt(p) == toInt(q); }
-inline bool operator != (Lit p, Lit q) { return toInt(p) != toInt(q); }
-inline bool operator < (Lit p, Lit q) { return toInt(p) < toInt(q); } // '<' guarantees that p, ~p are adjacent in the ordering.
-
-
-const Lit lit_Undef(var_Undef, false); // }- Useful special constants.
-const Lit lit_Error(var_Undef, true ); // }
-
-
-//=================================================================================================
-// Clause -- a simple class for representing a clause:
-
-class Clause {
- uint size_etc;
- union { float act; uint abst; } apa;
- Lit data[1];
-public:
- // NOTE: This constructor cannot be used directly (doesn't allocate enough memory).
- template<class V>
- Clause(const V& ps, bool learnt) {
- size_etc = (ps.size() << 3) | (uint)learnt;
- for (int i = 0; i < ps.size(); i++) data[i] = ps[i];
- if (learnt) apa.act = 0; else apa.abst = 0; }
-
- // -- use this function instead:
- template<class V>
- friend Clause* Clause_new(const V& ps, bool learnt = false) {
- assert(sizeof(Lit) == sizeof(uint));
- assert(sizeof(float) == sizeof(uint));
-
- size_t aux_size = 0;
- if (ps.size() > 0)
- aux_size = sizeof(uint)*(ps.size() - 1);
-
- void* mem = xmalloc<char>(sizeof(Clause) + aux_size);
- return new (mem) Clause(ps, learnt); }
-
- int size () const { return size_etc >> 3; }
- void shrink (int i) { assert(i <= size()); size_etc = (((size_etc >> 3) - i) << 3) | (size_etc & 7); }
- void pop () { shrink(1); }
- bool learnt () const { return size_etc & 1; }
- uint mark () const { return (size_etc >> 1) & 3; }
- void mark (uint m) { size_etc = (size_etc & ~6) | ((m & 3) << 1); }
- Lit operator [] (int i) const { return data[i]; }
- Lit& operator [] (int i) { return data[i]; }
-
- float& activity () { return apa.act; }
-
- uint abstraction () const { return apa.abst; }
-
- void calcAbstraction() {
- uint abstraction = 0;
- for (int i = 0; i < size(); i++)
- abstraction |= 1 << (var(data[i]) & 31);
- apa.abst = abstraction; }
-};
-
-
-//=================================================================================================
-// TrailPos -- Stores an index into the trail as well as an approximation of a level. This data
-// is recorded for each assigment. (Replaces the old level information)
-
-
-class TrailPos {
- int tp;
- public:
- explicit TrailPos(int index, int level) : tp( (index << 5) + (level & 31) ) { }
-
- friend int abstractLevel(const TrailPos& p) { return 1 << (p.tp & 31); }
- friend int position (const TrailPos& p) { return p.tp >> 5; }
-
- bool operator == (TrailPos other) const { return tp == other.tp; }
- bool operator < (TrailPos other) const { return tp < other.tp; }
-};
-
-}
-#endif
diff --git a/stp/sat/Sort.h b/stp/sat/Sort.h
deleted file mode 100644
index 9def2990..00000000
--- a/stp/sat/Sort.h
+++ /dev/null
@@ -1,133 +0,0 @@
-/******************************************************************************************[Sort.h]
-MiniSat -- Copyright (c) 2003-2005, Niklas Een, Niklas Sorensson
-
-Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
-associated documentation files (the "Software"), to deal in the Software without restriction,
-including without limitation the rights to use, copy, modify, merge, publish, distribute,
-sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all copies or
-substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
-NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
-DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
-OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-**************************************************************************************************/
-
-#ifndef Sort_h
-#define Sort_h
-
-
-namespace MINISAT {
-//=================================================================================================
-
-
-template<class T>
-struct LessThan_default {
- bool operator () (T x, T y) { return x < y; }
-};
-
-
-//=================================================================================================
-
-
-template <class T, class LessThan>
-void selectionSort(T* array, int size, LessThan lt)
-{
- int i, j, best_i;
- T tmp;
-
- for (i = 0; i < size-1; i++){
- best_i = i;
- for (j = i+1; j < size; j++){
- if (lt(array[j], array[best_i]))
- best_i = j;
- }
- tmp = array[i]; array[i] = array[best_i]; array[best_i] = tmp;
- }
-}
-template <class T> static inline void selectionSort(T* array, int size) {
- selectionSort(array, size, LessThan_default<T>()); }
-
-
-template <class T, class LessThan>
-void sort(T* array, int size, LessThan lt, double& seed)
-{
- if (size <= 15)
- selectionSort(array, size, lt);
-
- else{
- T pivot = array[irand(seed, size)];
- T tmp;
- int i = -1;
- int j = size;
-
- for(;;){
- do i++; while(lt(array[i], pivot));
- do j--; while(lt(pivot, array[j]));
-
- if (i >= j) break;
-
- tmp = array[i]; array[i] = array[j]; array[j] = tmp;
- }
-
- sort(array , i , lt, seed);
- sort(&array[i], size-i, lt, seed);
- }
-}
-template <class T, class LessThan> void sort(T* array, int size, LessThan lt) {
- double seed = 91648253; sort(array, size, lt, seed); }
-template <class T> static inline void sort(T* array, int size) {
- sort(array, size, LessThan_default<T>()); }
-
-
-template <class T, class LessThan>
-void sortUnique(T* array, int& size, LessThan lt)
-{
- int i, j;
- T last;
-
- if (size == 0) return;
-
- sort(array, size, lt);
-
- i = 1;
- last = array[0];
- for (j = 1; j < size; j++){
- if (lt(last, array[j])){
- last = array[i] = array[j];
- i++; }
- }
-
- size = i;
-}
-template <class T> static inline void sortUnique(T* array, int& size) {
- sortUnique(array, size, LessThan_default<T>()); }
-
-
-//=================================================================================================
-// For 'vec's:
-
-
-template <class T, class LessThan> void sort(vec<T>& v, LessThan lt) {
- sort((T*)v, v.size(), lt); }
-template <class T> void sort(vec<T>& v) {
- sort(v, LessThan_default<T>()); }
-
-
-template <class T, class LessThan> void sortUnique(vec<T>& v, LessThan lt) {
- int size = v.size();
- T* data = v.release();
- sortUnique(data, size, lt);
- v.~vec<T>();
- new (&v) vec<T>(data, size); }
-template <class T> void sortUnique(vec<T>& v) {
- sortUnique(v, LessThan_default<T>()); }
-
-
-//=================================================================================================
-}
-#endif
diff --git a/stp/sat/VarOrder.h b/stp/sat/VarOrder.h
deleted file mode 100644
index 6d2a40f0..00000000
--- a/stp/sat/VarOrder.h
+++ /dev/null
@@ -1,146 +0,0 @@
-/**************************************************************************************[VarOrder.h]
-MiniSat -- Copyright (c) 2003-2005, Niklas Een, Niklas Sorensson
-
-Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
-associated documentation files (the "Software"), to deal in the Software without restriction,
-including without limitation the rights to use, copy, modify, merge, publish, distribute,
-sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all copies or
-substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
-NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
-DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
-OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-**************************************************************************************************/
-
-#ifndef VarOrder_h
-#define VarOrder_h
-
-#include "SolverTypes.h"
-#include "Solver.h"
-#include "Heap.h"
-#include "../AST/ASTUtil.h"
-
-namespace MINISAT {
- //=================================================================================================
-
- struct VarOrder_lt {
- const vec<double>& activity;
- bool operator () (Var x, Var y) { return activity[x] > activity[y]; }
- VarOrder_lt(const vec<double>& act) : activity(act) { }
- };
-
-
- enum { p_decisionvar = 0, p_polarity = 1, p_frozen = 2, p_dontcare = 3 };
-
-
- class VarOrder {
- const vec<char>& assigns; // var->val. Pointer to external assignment table.
- const vec<double>& activity; // var->act. Pointer to external activity table.
- vec<char> properties;
- //Heap<VarOrder_lt> heap;
- //double random_seed; // For the internal random number generator
-
- friend class VarFilter;
- public:
- //FIXME: Vijay: delete after experiments
- Heap<VarOrder_lt> heap;
- double random_seed; // For the internal random number generator
- //FIXME ENDS HERE
-
- VarOrder(const vec<char>& ass, const vec<double>& act) :
- assigns(ass), activity(act), heap(VarOrder_lt(act)), random_seed(2007)
- //assigns(ass), activity(act), heap(VarOrder_lt(act))
- { }
-
- int size () { return heap.size(); }
- void setVarProp (Var v, uint prop, bool b) { properties[v] = (properties[v] & ~(1 << prop)) | (b << prop); }
- bool hasVarProp (Var v, uint prop) const { return properties[v] & (1 << prop); }
- inline void cleanup ();
-
- inline void newVar(bool polarity, bool dvar);
- inline void update(Var x); // Called when variable increased in activity.
- inline void undo(Var x); // Called when variable is unassigned and may be selected again.
- //Selects a new, unassigned variable (or 'var_Undef' if none exists).
- inline Lit select(double random_freq =.0, int decision_level = 0);
- };
-
-
- struct VarFilter {
- const VarOrder& o;
- VarFilter(const VarOrder& _o) : o(_o) {}
- bool operator()(Var v) const { return toLbool(o.assigns[v]) == l_Undef && o.hasVarProp(v, p_decisionvar); }
- //bool operator()(Var v) const { return toLbool(o.assigns[v]) == l_Undef; }
- };
-
- void VarOrder::cleanup()
- {
- VarFilter f(*this);
- heap.filter(f);
- }
-
- void VarOrder::newVar(bool polarity, bool dvar)
- {
- Var v = assigns.size()-1;
- heap.setBounds(v+1);
- properties.push(0);
- setVarProp(v, p_decisionvar, dvar);
- setVarProp(v, p_polarity, polarity);
- undo(v);
- }
-
-
- void VarOrder::update(Var x)
- {
- if (heap.inHeap(x))
- heap.increase(x);
- }
-
-
- void VarOrder::undo(Var x)
- {
- if (!heap.inHeap(x) && hasVarProp(x, p_decisionvar))
- heap.insert(x);
- }
-
-
- Lit VarOrder::select(double random_var_freq, int decision_level)
- {
- Var next = var_Undef;
-
- if (drand(random_seed) < random_var_freq && !heap.empty())
- next = irand(random_seed,assigns.size());
-
- // Activity based decision:
- while (next == var_Undef || toLbool(assigns[next]) != l_Undef || !hasVarProp(next, p_decisionvar))
- if (heap.empty()){
- next = var_Undef;
- break;
- }else
- next = heap.getmin();
-
- //printing
- if(BEEV::print_sat_varorder) {
- if (next != var_Undef) {
- BEEV::Convert_MINISATVar_To_ASTNode_Print(next,
- decision_level,
- hasVarProp(next, p_polarity));
- // fprintf(stderr,"var = %d, prop = %d, decision = %d, polarity = %d, frozen = %d\n",
- // next+1, properties[next], hasVarProp(next, p_decisionvar),
- // hasVarProp(next, p_polarity), hasVarProp(next, p_frozen));
- }
- else
- fprintf(stderr, "var = undef\n");
- }
-
- return next == var_Undef ? lit_Undef : Lit(next, hasVarProp(next, p_polarity));
- }
-
-
- //=================================================================================================
-}
-#endif
diff --git a/stp/simplifier/Makefile b/stp/simplifier/Makefile
deleted file mode 100644
index 7aeb3ffc..00000000
--- a/stp/simplifier/Makefile
+++ /dev/null
@@ -1,19 +0,0 @@
-#===-- stp/simplifier/Makefile -----------------------------*- Makefile -*--===#
-#
-# The KLEE Symbolic Virtual Machine
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-#===------------------------------------------------------------------------===#
-
-LEVEL=../..
-
-LIBRARYNAME=stp_simplifier
-DONT_BUILD_RELINKED=1
-BUILD_ARCHIVE=1
-
-include $(LEVEL)/Makefile.common
-
-# HACK: Force -Wno-deprecated for ext container use.
-CXX.Flags += -Wno-deprecated
diff --git a/stp/simplifier/bvsolver.cpp b/stp/simplifier/bvsolver.cpp
deleted file mode 100644
index 369251db..00000000
--- a/stp/simplifier/bvsolver.cpp
+++ /dev/null
@@ -1,714 +0,0 @@
-/********************************************************************
- * AUTHORS: Vijay Ganesh, David L. Dill
- *
- * BEGIN DATE: November, 2005
- *
- * LICENSE: Please view LICENSE file in the home dir of this Program
- ********************************************************************/
-// -*- c++ -*-
-
-#include "../AST/AST.h"
-#include "../AST/ASTUtil.h"
-#include "bvsolver.h"
-
- //This file contains the implementation of member functions of
- //bvsolver class, which represents the bitvector arithmetic linear
- //solver. Please also refer the STP's CAV 2007 paper for the
- //complete description of the linear solver algorithm
- //
- //The bitvector solver is a partial solver, i.e. it does not solve
- //for all variables in the system of equations. it is
- //best-effort. it relies on the SAT solver to be complete.
- //
- //The BVSolver assumes that the input equations are normalized, and
- //have liketerms combined etc.
- //
- //0. Traverse top-down over the input DAG, looking for a conjunction
- //0. of equations. if you find one, then for each equation in the
- //0. conjunction, do the following steps.
- //
- //1. check for Linearity of the input equation
- //
- //2. Solve for a "chosen" variable. The variable should occur
- //2. exactly once and must have an odd coeff. Refer STP's CAV 2007
- //2. paper for actual solving procedure
- //
- //4. Outside the solver, Substitute and Re-normalize the input DAG
-namespace BEEV {
- //check the solver map for 'key'. If key is present, then return the
- //value by reference in the argument 'output'
- bool BVSolver::CheckAlreadySolvedMap(const ASTNode& key, ASTNode& output) {
- ASTNodeMap::iterator it;
- if((it = FormulasAlreadySolvedMap.find(key)) != FormulasAlreadySolvedMap.end()) {
- output = it->second;
- return true;
- }
- return false;
- } //CheckAlreadySolvedMap()
-
- void BVSolver::UpdateAlreadySolvedMap(const ASTNode& key, const ASTNode& value) {
- FormulasAlreadySolvedMap[key] = value;
- } //end of UpdateAlreadySolvedMap()
-
- //FIXME This is doing way more arithmetic than it needs to.
- //accepts an even number "in", and splits it into an odd number and
- //a power of 2. i.e " in = b.(2^k) ". returns the odd number, and
- //the power of two by reference
- ASTNode BVSolver::SplitEven_into_Oddnum_PowerOf2(const ASTNode& in,
- unsigned int& number_shifts) {
- if(BVCONST != in.GetKind() || _bm->BVConstIsOdd(in)) {
- FatalError("BVSolver:SplitNum_Odd_PowerOf2: input must be a BVCONST and even\n",in);
- }
-
- unsigned int len = in.GetValueWidth();
- ASTNode zero = _bm->CreateZeroConst(len);
- ASTNode two = _bm->CreateTwoConst(len);
- ASTNode div_by_2 = in;
- ASTNode mod_by_2 =
- _bm->BVConstEvaluator(_bm->CreateTerm(BVMOD,len,div_by_2,two));
- while(mod_by_2 == zero) {
- div_by_2 =
- _bm->BVConstEvaluator(_bm->CreateTerm(BVDIV,len,div_by_2,two));
- number_shifts++;
- mod_by_2 =
- _bm->BVConstEvaluator(_bm->CreateTerm(BVMOD,len,div_by_2,two));
- }
- return div_by_2;
- } //end of SplitEven_into_Oddnum_PowerOf2()
-
- //Checks if there are any ARRAYREADS in the term, after the
- //alreadyseenmap is cleared, i.e. traversing a new term altogether
- bool BVSolver::CheckForArrayReads_TopLevel(const ASTNode& term) {
- TermsAlreadySeenMap.clear();
- return CheckForArrayReads(term);
- }
-
- //Checks if there are any ARRAYREADS in the term
- bool BVSolver::CheckForArrayReads(const ASTNode& term) {
- ASTNode a = term;
- ASTNodeMap::iterator it;
- if((it = TermsAlreadySeenMap.find(term)) != TermsAlreadySeenMap.end()) {
- //if the term has been seen, then simply return true, else
- //return false
- if(ASTTrue == (it->second)) {
- return true;
- }
- else {
- 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 && EQ == eq.GetKind())) {
- return input;
- }
-
- ASTNode output = input;
- if(CheckAlreadySolvedMap(input,output)) {
- return output;
- }
-
- //get the lhs and the rhs, and case-split on the lhs kind
- ASTNode lhs = eq[0];
- ASTNode rhs = eq[1];
- if(BVPLUS == lhs.GetKind()) {
- ASTNode chosen_monom = _bm->CreateNode(UNDEFINED);
- ASTNode leftover_lhs;
-
- //choose monom makes sure that it gets only those vars that
- //occur exactly once in lhs and rhs put together
- chosen_monom = ChooseMonom(eq, leftover_lhs);
- if(chosen_monom == _bm->CreateNode(UNDEFINED)) {
- //no monomial was chosen
- return eq;
- }
-
- //if control is here then it means that a monom was chosen
- //
- //construct: rhs - (lhs without the chosen monom)
- unsigned int len = lhs.GetValueWidth();
- leftover_lhs = _bm->SimplifyTerm_TopLevel(_bm->CreateTerm(BVUMINUS,len,leftover_lhs));
- ASTNode newrhs = _bm->SimplifyTerm(_bm->CreateTerm(BVPLUS,len,rhs,leftover_lhs));
- lhs = chosen_monom;
- rhs = newrhs;
- } //end of if(BVPLUS ...)
-
- if(BVUMINUS == lhs.GetKind()) {
- //equation is of the form (-lhs0) = rhs
- ASTNode lhs0 = lhs[0];
- rhs = _bm->SimplifyTerm(_bm->CreateTerm(BVUMINUS,rhs.GetValueWidth(),rhs));
- lhs = lhs0;
- }
-
- switch(lhs.GetKind()) {
- case SYMBOL: {
- //input is of the form x = rhs first make sure that the lhs
- //symbol does not occur on the rhs or that it has not been
- //solved for
- if(_bm->VarSeenInTerm(lhs,rhs)) {
- //found the lhs in the rhs. Abort!
- DoNotSolve_TheseVars.insert(lhs);
- return eq;
- }
-
- //rhs should not have arrayreads in it. it complicates matters
- //during transformation
- // if(CheckForArrayReads_TopLevel(rhs)) {
- // return eq;
- // }
-
- DoNotSolve_TheseVars.insert(lhs);
- if(!_bm->UpdateSolverMap(lhs,rhs)) {
- return eq;
- }
-
- output = ASTTrue;
- break;
- }
- case BVEXTRACT: {
- ASTNode zero = _bm->CreateZeroConst(32);
-
- if(!(SYMBOL == lhs[0].GetKind() &&
- BVCONST == lhs[1].GetKind() &&
- zero == lhs[2] &&
- !_bm->VarSeenInTerm(lhs[0],rhs) &&
- !DoNotSolveThis(lhs[0]))) {
- return eq;
- }
-
- if(_bm->VarSeenInTerm(lhs[0],rhs)) {
- DoNotSolve_TheseVars.insert(lhs[0]);
- return eq;
- }
-
- DoNotSolve_TheseVars.insert(lhs[0]);
- if(!_bm->UpdateSolverMap(lhs,rhs)) {
- return eq;
- }
-
- //if the extract of x[i:0] = t is entered into the solvermap,
- //then also add another entry for x = x1@t
- ASTNode var = lhs[0];
- ASTNode newvar = NewVar(var.GetValueWidth() - lhs.GetValueWidth());
- newvar = _bm->CreateTerm(BVCONCAT,var.GetValueWidth(),newvar,rhs);
- _bm->UpdateSolverMap(var,newvar);
- output = ASTTrue;
- break;
- }
- case BVMULT: {
- //the input is of the form a*x = t. If 'a' is odd, then compute
- //its multiplicative inverse a^-1, multiply 't' with it, and
- //update the solver map
- if(BVCONST != lhs[0].GetKind()) {
- return eq;
- }
-
- if(!(SYMBOL == lhs[1].GetKind() ||
- (BVEXTRACT == lhs[1].GetKind() &&
- SYMBOL == lhs[1][0].GetKind()))) {
- return eq;
- }
-
- bool ChosenVar_Is_Extract = (BVEXTRACT == lhs[1].GetKind()) ? true : false;
-
- //if coeff is even, then we know that all the coeffs in the eqn
- //are even. Simply return the eqn
- if(!_bm->BVConstIsOdd(lhs[0])) {
- return eq;
- }
-
- ASTNode a = _bm->MultiplicativeInverse(lhs[0]);
- ASTNode chosenvar = (BVEXTRACT == lhs[1].GetKind()) ? lhs[1][0] : lhs[1];
- ASTNode chosenvar_value =
- _bm->SimplifyTerm(_bm->CreateTerm(BVMULT,rhs.GetValueWidth(),a,rhs));
-
- //if chosenvar is seen in chosenvar_value then abort
- if(_bm->VarSeenInTerm(chosenvar,chosenvar_value)) {
- //abort solving
- DoNotSolve_TheseVars.insert(lhs);
- return eq;
- }
-
- //rhs should not have arrayreads in it. it complicates matters
- //during transformation
- // if(CheckForArrayReads_TopLevel(chosenvar_value)) {
- // return eq;
- // }
-
- //found a variable to solve
- DoNotSolve_TheseVars.insert(chosenvar);
- chosenvar = lhs[1];
- if(!_bm->UpdateSolverMap(chosenvar,chosenvar_value)) {
- return eq;
- }
-
- if(ChosenVar_Is_Extract) {
- ASTNode var = lhs[1][0];
- ASTNode newvar = NewVar(var.GetValueWidth() - lhs[1].GetValueWidth());
- newvar = _bm->CreateTerm(BVCONCAT,var.GetValueWidth(),newvar,chosenvar_value);
- _bm->UpdateSolverMap(var,newvar);
- }
- output = ASTTrue;
- break;
- }
- default:
- output = eq;
- break;
- }
-
- UpdateAlreadySolvedMap(input,output);
- return output;
- } //end of BVSolve_Odd()
-
- //Create a new variable of ValueWidth 'n'
- ASTNode BVSolver::NewVar(unsigned int n) {
- std:: string c("v");
- char d[32];
- sprintf(d,"%d",_symbol_count++);
- std::string ccc(d);
- c += "_solver_" + ccc;
-
- ASTNode CurrentSymbol = _bm->CreateSymbol(c.c_str());
- CurrentSymbol.SetValueWidth(n);
- CurrentSymbol.SetIndexWidth(0);
- return CurrentSymbol;
- } //end of NewVar()
-
- //The toplevel bvsolver(). Checks if the formula has already been
- //solved. If not, the solver() is invoked. If yes, then simply drop
- //the formula
- ASTNode BVSolver::TopLevelBVSolve(const ASTNode& input) {
- if(!wordlevel_solve) {
- return input;
- }
-
- Kind k = input.GetKind();
- if(!(EQ == k || AND == k)) {
- return input;
- }
-
- ASTNode output = input;
- if(CheckAlreadySolvedMap(input,output)) {
- //output is TRUE. The formula is thus dropped
- return output;
- }
- ASTVec o;
- ASTVec c;
- if(EQ == k)
- c.push_back(input);
- else
- c = input.GetChildren();
- ASTVec eveneqns;
- ASTNode solved = ASTFalse;
- for(ASTVec::iterator it = c.begin(), itend = c.end();it != itend;it++) {
- //_bm->ASTNodeStats("Printing before calling simplifyformula inside the solver:", *it);
- ASTNode aaa = (ASTTrue == solved && EQ == it->GetKind()) ? _bm->SimplifyFormula(*it,false) : *it;
- //ASTNode aaa = *it;
- //_bm->ASTNodeStats("Printing after calling simplifyformula inside the solver:", aaa);
- aaa = BVSolve_Odd(aaa);
- //_bm->ASTNodeStats("Printing after oddsolver:", aaa);
- bool even = false;
- aaa = CheckEvenEqn(aaa, even);
- if(even) {
- eveneqns.push_back(aaa);
- }
- else {
- if(ASTTrue != aaa) {
- o.push_back(aaa);
- }
- }
- solved = aaa;
- }
-
- ASTNode evens;
- if(eveneqns.size() > 0) {
- //if there is a system of even equations then solve them
- evens = (eveneqns.size() > 1) ? _bm->CreateNode(AND,eveneqns) : eveneqns[0];
- //evens = _bm->SimplifyFormula(evens,false);
- evens = BVSolve_Even(evens);
- _bm->ASTNodeStats("Printing after evensolver:", evens);
- }
- else {
- evens = ASTTrue;
- }
- output = (o.size() > 0) ? ((o.size() > 1) ? _bm->CreateNode(AND,o) : o[0]) : ASTTrue;
- output = _bm->CreateNode(AND,output,evens);
-
- UpdateAlreadySolvedMap(input,output);
- return output;
- } //end of TopLevelBVSolve()
-
- ASTNode BVSolver::CheckEvenEqn(const ASTNode& input, bool& evenflag) {
- ASTNode eq = input;
- //cerr << "Input to BVSolve_Odd()" << eq << endl;
- if(!(wordlevel_solve && EQ == eq.GetKind())) {
- evenflag = false;
- return eq;
- }
-
- ASTNode lhs = eq[0];
- ASTNode rhs = eq[1];
- ASTNode zero = _bm->CreateZeroConst(rhs.GetValueWidth());
- //lhs must be a BVPLUS, and rhs must be a BVCONST
- if(!(BVPLUS == lhs.GetKind() && zero == rhs)) {
- evenflag = false;
- return eq;
- }
-
- ASTVec lhs_c = lhs.GetChildren();
- ASTNode savetheconst = rhs;
- for(ASTVec::iterator it=lhs_c.begin(),itend=lhs_c.end();it!=itend;it++) {
- ASTNode aaa = *it;
- Kind itk = aaa.GetKind();
-
- if(BVCONST == itk){
- //check later if the constant is even or not
- savetheconst = aaa;
- continue;
- }
-
- if(!(BVMULT == itk &&
- BVCONST == aaa[0].GetKind() &&
- SYMBOL == aaa[1].GetKind() &&
- !_bm->BVConstIsOdd(aaa[0]))) {
- //If the monomials of the lhs are NOT of the form 'a*x' where
- //'a' is even, then return the false
- evenflag = false;
- return eq;
- }
- }//end of for loop
-
- //if control is here then it means that all coeffs are even. the
- //only remaining thing is to check if the constant is even or not
- if(_bm->BVConstIsOdd(savetheconst)) {
- //the constant turned out to be odd. we have UNSAT eqn
- evenflag = false;
- return ASTFalse;
- }
-
- //all is clear. the eqn in even, through and through
- evenflag = true;
- return eq;
- } //end of CheckEvenEqn
-
- //solve an eqn whose monomials have only even coefficients
- ASTNode BVSolver::BVSolve_Even(const ASTNode& input) {
- if(!wordlevel_solve) {
- return input;
- }
-
- if(!(EQ == input.GetKind() || AND == input.GetKind())) {
- return input;
- }
-
- ASTNode output;
- if(CheckAlreadySolvedMap(input,output)) {
- return output;
- }
-
- ASTVec input_c;
- if(EQ == input.GetKind()) {
- input_c.push_back(input);
- }
- else {
- input_c = input.GetChildren();
- }
-
- //power_of_2 holds the exponent of 2 in the coeff
- unsigned int power_of_2 = 0;
- //we need this additional variable to find the lowest power of 2
- unsigned int power_of_2_lowest = 0xffffffff;
- //the monom which has the least power of 2 in the coeff
- ASTNode monom_with_best_coeff;
- for(ASTVec::iterator jt=input_c.begin(),jtend=input_c.end();jt!=jtend;jt++) {
- ASTNode eq = *jt;
- ASTNode lhs = eq[0];
- ASTNode rhs = eq[1];
- ASTNode zero = _bm->CreateZeroConst(rhs.GetValueWidth());
- //lhs must be a BVPLUS, and rhs must be a BVCONST
- if(!(BVPLUS == lhs.GetKind() && zero == rhs)) {
- return input;
- }
-
- ASTVec lhs_c = lhs.GetChildren();
- ASTNode odd;
- for(ASTVec::iterator it=lhs_c.begin(),itend=lhs_c.end();it!=itend;it++) {
- ASTNode aaa = *it;
- Kind itk = aaa.GetKind();
- if(!(BVCONST == itk &&
- !_bm->BVConstIsOdd(aaa)) &&
- !(BVMULT == itk &&
- BVCONST == aaa[0].GetKind() &&
- SYMBOL == aaa[1].GetKind() &&
- !_bm->BVConstIsOdd(aaa[0]))) {
- //If the monomials of the lhs are NOT of the form 'a*x' or 'a'
- //where 'a' is even, then return the eqn
- return input;
- }
-
- //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
diff --git a/stp/simplifier/bvsolver.h b/stp/simplifier/bvsolver.h
deleted file mode 100644
index 8df32042..00000000
--- a/stp/simplifier/bvsolver.h
+++ /dev/null
@@ -1,134 +0,0 @@
-/********************************************************************
- * AUTHORS: Vijay Ganesh, David L. Dill
- *
- * BEGIN DATE: November, 2005
- *
- * LICENSE: Please view LICENSE file in the home dir of this Program
- ********************************************************************/
-// -*- c++ -*-
-
-#include "../AST/AST.h"
-#include "../AST/ASTUtil.h"
-namespace BEEV {
-
- //This class represents the bitvector arithmetic linear solver.
- //
- //The bitvector solver is a partial solver, i.e. it does not solve
- //for all variables in the system of equations. it is
- //best-effort. it relies on the SAT solver to be complete.
- //
- //The BVSolver assumes that the input equations are normalized, and
- //have liketerms combined etc.
- //
- //0. Traverse top-down over the input DAG, looking for a conjunction
- //0. of equations. if you find one, then for each equation in the
- //0. conjunction, do the following steps.
- //
- //1. check for Linearity of the input equation
- //
- //2. Solve for a "chosen" variable. The variable should occur
- //2. exactly once and must have an odd coeff. Refer STP's CAV 2007
- //2. paper for actual solving procedure
- //
- //4. Outside the solver, Substitute and Re-normalize the input DAG
- class BVSolver {
- //Ptr to toplevel manager that manages bit-vector expressions
- //(i.e. construct various kinds of expressions), and also has
- //member functions that simplify bit-vector expressions
- BeevMgr * _bm;
- ASTNode ASTTrue, ASTFalse;
-
- //Those formulas which have already been solved. If the same
- //formula occurs twice then do not solve the second occurence, and
- //instead drop it
- ASTNodeMap FormulasAlreadySolvedMap;
-
- //this map is useful while traversing terms and uniquely
- //identifying variables in the those terms. Prevents double
- //counting.
- ASTNodeMap TermsAlreadySeenMap;
- ASTNodeMap TermsAlreadySeenMap_ForArrays;
-
- //count is used in the creation of new variables
- unsigned int _symbol_count;
-
- //solved variables list: If a variable has been solved for then do
- //not solve for it again
- ASTNodeSet DoNotSolve_TheseVars;
-
- //checks if var has been solved for or not. if yes, then return
- //true else return false
- bool DoNotSolveThis(const ASTNode& var);
-
- //traverses a term, and creates a multiset of all variables in the
- //term. Does memoization to avoid double counting.
- void VarsInTheTerm(const ASTNode& lhs, ASTNodeMultiSet& v);
- void VarsInTheTerm_TopLevel(const ASTNode& lhs, ASTNodeMultiSet& v);
-
- //choose a suitable var from the term
- ASTNode ChooseMonom(const ASTNode& eq, ASTNode& modifiedterm);
- //accepts an equation and solves for a variable or a monom in it
- ASTNode BVSolve_Odd(const ASTNode& eq);
-
- //solves equations of the form a*x=t where 'a' is even. Has a
- //return value, unlike the normal BVSolve()
- ASTNode BVSolve_Even(const ASTNode& eq);
- ASTNode CheckEvenEqn(const ASTNode& input, bool& evenflag);
-
- //Checks for arrayreads in a term. if yes then returns true, else
- //return false
- bool CheckForArrayReads(const ASTNode& term);
- bool CheckForArrayReads_TopLevel(const ASTNode& term);
-
- //Creates new variables used in solving
- ASTNode NewVar(unsigned int n);
-
- //this function return true if the var occurs in term, else the
- //function returns false
- bool VarSeenInTerm(const ASTNode& var, const ASTNode& term);
-
- //takes an even number "in" as input, and returns an odd number
- //(return value) and a power of 2 (as number_shifts by reference),
- //such that in = (odd_number * power_of_2).
- //
- //Refer STP's CAV 2007 (or Clark Barrett's 1998 paper on
- //bit-vector arithmetic published in DAC 1998) paper for precise
- //understanding of the algorithm
- ASTNode SplitEven_into_Oddnum_PowerOf2(const ASTNode& in, unsigned int& number_shifts);
-
- //Once a formula has been solved, then update the alreadysolvedmap
- //with the formula, and the solved value. The solved value can be
- //described using the following example: Suppose input to the
- //solver is
- //
- // input key: x = 2 AND y = x + t
- //
- // output value: y = 2 + t
- void UpdateAlreadySolvedMap(const ASTNode& key, const ASTNode& value);
-
- //This function checks if the key (formula) has already been
- //solved for.
- //
- //If yes it returns TRUE and fills the "output" with the
- //solved-value (call by reference argument),
- //
- //else returns FALSE
- bool CheckAlreadySolvedMap(const ASTNode& key, ASTNode& output);
- public:
- //constructor
- BVSolver(BeevMgr * bm) : _bm(bm), _symbol_count(0) {
- ASTTrue = _bm->CreateNode(TRUE);
- ASTFalse = _bm->CreateNode(FALSE);
- };
-
- //Destructor
- ~BVSolver() {
- TermsAlreadySeenMap.clear();
- DoNotSolve_TheseVars.clear();
- }
-
- //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
diff --git a/stp/simplifier/simplifier.cpp b/stp/simplifier/simplifier.cpp
deleted file mode 100644
index c0519e83..00000000
--- a/stp/simplifier/simplifier.cpp
+++ /dev/null
@@ -1,2495 +0,0 @@
-/********************************************************************
- * AUTHORS: Vijay Ganesh, David L. Dill
- *
- * BEGIN DATE: November, 2005
- *
- * LICENSE: Please view LICENSE file in the home dir of this Program
- ********************************************************************/
-// -*- c++ -*-
-
-#include "../AST/AST.h"
-#include "../AST/ASTUtil.h"
-namespace BEEV {
-
- bool BeevMgr::CheckSimplifyMap(const ASTNode& key,
- ASTNode& output, bool pushNeg) {
- ASTNodeMap::iterator it, itend;
- it = pushNeg ? SimplifyNegMap.find(key) : SimplifyMap.find(key);
- itend = pushNeg ? SimplifyNegMap.end() : SimplifyMap.end();
-
- if(it != itend) {
- output = it->second;
- CountersAndStats("Successful_CheckSimplifyMap");
- return true;
- }
-
- if(pushNeg && (it = SimplifyMap.find(key)) != SimplifyMap.end()) {
- output =
- (ASTFalse == it->second) ?
- ASTTrue :
- (ASTTrue == it->second) ? ASTFalse : CreateNode(NOT, it->second);
- CountersAndStats("2nd_Successful_CheckSimplifyMap");
- return true;
- }
-
- return false;
- }
-
- void BeevMgr::UpdateSimplifyMap(const ASTNode& key, const ASTNode& value, bool pushNeg) {
- if(pushNeg)
- SimplifyNegMap[key] = value;
- else
- SimplifyMap[key] = value;
- }
-
- bool BeevMgr::CheckSubstitutionMap(const ASTNode& key, ASTNode& output) {
- ASTNodeMap::iterator it;
- if((it = SolverMap.find(key)) != SolverMap.end()) {
- output = it->second;
- return true;
- }
- return false;
- }
-
- bool BeevMgr::CheckSubstitutionMap(const ASTNode& key) {
- if(SolverMap.find(key) != SolverMap.end())
- return true;
- else
- return false;
- }
-
- bool BeevMgr::UpdateSubstitutionMap(const ASTNode& e0, const ASTNode& e1) {
- int i = TermOrder(e0,e1);
- if(0 == i)
- return false;
-
- //e0 is of the form READ(Arr,const), and e1 is const, or
- //e0 is of the form var, and e1 is const
- if(1 == i && !CheckSubstitutionMap(e0)) {
- SolverMap[e0] = e1;
- return true;
- }
-
- //e1 is of the form READ(Arr,const), and e0 is const, or
- //e1 is of the form var, and e0 is const
- if (-1 == i && !CheckSubstitutionMap(e1)) {
- SolverMap[e1] = e0;
- return true;
- }
-
- return false;
- }
-
- bool BeevMgr::CheckMultInverseMap(const ASTNode& key, ASTNode& output) {
- ASTNodeMap::iterator it;
- if((it = MultInverseMap.find(key)) != MultInverseMap.end()) {
- output = it->second;
- return true;
- }
- return false;
- }
-
- void BeevMgr::UpdateMultInverseMap(const ASTNode& key, const ASTNode& value) {
- MultInverseMap[key] = value;
- }
-
-
- bool BeevMgr::CheckAlwaysTrueFormMap(const ASTNode& key) {
- ASTNodeSet::iterator it = AlwaysTrueFormMap.find(key);
- ASTNodeSet::iterator itend = AlwaysTrueFormMap.end();
-
- if(it != itend) {
- //cerr << "found:" << *it << endl;
- CountersAndStats("Successful_CheckAlwaysTrueFormMap");
- return true;
- }
-
- return false;
- }
-
- void BeevMgr::UpdateAlwaysTrueFormMap(const ASTNode& key) {
- AlwaysTrueFormMap.insert(key);
- }
-
- //if a is READ(Arr,const) or SYMBOL, and b is BVCONST then return 1
- //if b is READ(Arr,const) or SYMBOL, and a is BVCONST then return -1
- //
- //else return 0 by default
- int BeevMgr::TermOrder(const ASTNode& a, const ASTNode& b) {
- Kind k1 = a.GetKind();
- Kind k2 = b.GetKind();
-
- //a is of the form READ(Arr,const), and b is const, or
- //a is of the form var, and b is const
- if((k1 == READ
- &&
- a[0].GetKind() == SYMBOL &&
- a[1].GetKind() == BVCONST
- )
- &&
- (k2 == BVCONST)
- )
- return 1;
-
- if(k1 == SYMBOL)
- 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
- )
- ||
- k2 == SYMBOL
- ))
- return -1;
- return 0;
- }
-
- //This function records all the const-indices seen so far for each
- //array. It populates the map '_arrayname_readindices' whose key is
- //the arrayname, and vlaue is a vector of read-indices.
- //
- //fill the arrayname_readindices vector if e0 is a READ(Arr,index)
- //and index is a BVCONST.
- //
- //Since these arrayreads are being nuked and recorded in the
- //substitutionmap, we have to also record the fact that each
- //arrayread (e0 is of the form READ(Arr,const) here is represented
- //by a BVCONST (e1). This is necessary for later Leibnitz Axiom
- //generation
- void BeevMgr::FillUp_ArrReadIndex_Vec(const ASTNode& e0, const ASTNode& e1) {
- int i = TermOrder(e0,e1);
- if(0 == i) return;
-
- if(1 == i && e0.GetKind() != SYMBOL && !CheckSubstitutionMap(e0)) {
- _arrayname_readindices[e0[0]].push_back(e0[1]);
- //e0 is the array read : READ(A,i) and e1 is a bvconst
- _arrayread_symbol[e0] = e1;
- return;
- }
- if(-1 == i && e1.GetKind() != SYMBOL && !CheckSubstitutionMap(e1)) {
- _arrayname_readindices[e1[0]].push_back(e1[1]);
- //e0 is the array read : READ(A,i) and e1 is a bvconst
- _arrayread_symbol[e1] = e0;
- return;
- }
- }
-
- ASTNode BeevMgr::SimplifyFormula_NoRemoveWrites(const ASTNode& b, bool pushNeg) {
- Begin_RemoveWrites = false;
- ASTNode out = SimplifyFormula(b,pushNeg);
- return out;
- }
-
- ASTNode BeevMgr::SimplifyFormula_TopLevel(const ASTNode& b, bool pushNeg) {
- SimplifyMap.clear();
- SimplifyNegMap.clear();
- ASTNode out = SimplifyFormula(b,pushNeg);
- SimplifyMap.clear();
- SimplifyNegMap.clear();
- return out;
- }
-
- ASTNode BeevMgr::SimplifyFormula(const ASTNode& b, bool pushNeg){
- if(!optimize)
- return b;
-
- Kind kind = b.GetKind();
- if(BOOLEAN_TYPE != b.GetType()) {
- FatalError(" SimplifyFormula: You have input a nonformula kind: ",ASTUndefined,kind);
- }
-
- ASTNode a = b;
- ASTVec ca = a.GetChildren();
- if(!(IMPLIES == kind ||
- ITE == kind ||
- isAtomic(kind))) {
- SortByExprNum(ca);
- a = CreateNode(kind,ca);
- }
-
- ASTNode output;
- if(CheckSimplifyMap(a,output,pushNeg))
- return output;
-
- switch(kind){
- case AND:
- case OR:
- output = SimplifyAndOrFormula(a,pushNeg);
- break;
- case NOT:
- output = SimplifyNotFormula(a,pushNeg);
- break;
- case XOR:
- output = SimplifyXorFormula(a,pushNeg);
- break;
- case NAND:
- output = SimplifyNandFormula(a,pushNeg);
- break;
- case NOR:
- output = SimplifyNorFormula(a,pushNeg);
- break;
- case IFF:
- output = SimplifyIffFormula(a,pushNeg);
- break;
- case IMPLIES:
- output = SimplifyImpliesFormula(a,pushNeg);
- break;
- case ITE:
- output = SimplifyIteFormula(a,pushNeg);
- break;
- default:
- //kind can be EQ,NEQ,BVLT,BVLE,... or a propositional variable
- output = SimplifyAtomicFormula(a,pushNeg);
- //output = pushNeg ? CreateNode(NOT,a) : a;
- break;
- }
-
- //memoize
- UpdateSimplifyMap(a,output, pushNeg);
- return output;
- }
-
- ASTNode BeevMgr::SimplifyAtomicFormula(const ASTNode& a, bool pushNeg) {
- if(!optimize) {
- return a;
- }
-
- ASTNode output;
- if(CheckSimplifyMap(a,output,pushNeg)) {
- return output;
- }
-
- ASTNode left,right;
- if(a.Degree() == 2) {
- //cerr << "Input to simplifyterm: left: " << a[0] << endl;
- left = SimplifyTerm(a[0]);
- //cerr << "Output of simplifyterm:left: " << left << endl;
- //cerr << "Input to simplifyterm: right: " << a[1] << endl;
- right = SimplifyTerm(a[1]);
- //cerr << "Output of simplifyterm:left: " << right << endl;
- }
-
- Kind kind = a.GetKind();
- switch(kind) {
- case TRUE:
- output = pushNeg ? ASTFalse : ASTTrue;
- break;
- case FALSE:
- output = pushNeg ? ASTTrue : ASTFalse;
- break;
- case SYMBOL:
- if(!CheckSolverMap(a,output)) {
- output = a;
- }
- output = pushNeg ? CreateNode(NOT,output) : output;
- break;
- case BVGETBIT: {
- ASTNode term = SimplifyTerm(a[0]);
- ASTNode thebit = a[1];
- ASTNode zero = CreateZeroConst(1);
- ASTNode one = CreateOneConst(1);
- ASTNode getthebit = SimplifyTerm(CreateTerm(BVEXTRACT,1,term,thebit,thebit));
- if(getthebit == zero)
- output = pushNeg ? ASTTrue : ASTFalse;
- else if(getthebit == one)
- output = pushNeg ? ASTFalse : ASTTrue;
- else {
- output = CreateNode(BVGETBIT,term,thebit);
- output = pushNeg ? CreateNode(NOT,output) : output;
- }
- break;
- }
- case EQ:{
- output = CreateSimplifiedEQ(left,right);
- output = LhsMinusRhs(output);
- output = ITEOpt_InEqs(output);
- if(output == ASTTrue)
- output = pushNeg ? ASTFalse : ASTTrue;
- else if (output == ASTFalse)
- output = pushNeg ? ASTTrue : ASTFalse;
- else
- output = pushNeg ? CreateNode(NOT,output) : output;
- break;
- }
- case NEQ: {
- output = CreateSimplifiedEQ(left,right);
- output = LhsMinusRhs(output);
- if(output == ASTTrue)
- output = pushNeg ? ASTTrue : ASTFalse;
- else if (output == ASTFalse)
- output = pushNeg ? ASTFalse : ASTTrue;
- else
- output = pushNeg ? output : CreateNode(NOT,output);
- break;
- }
- case BVLT:
- case BVLE:
- case BVGT:
- case BVGE:
- case BVSLT:
- case BVSLE:
- case BVSGT:
- case BVSGE: {
- //output = CreateNode(kind,left,right);
- //output = pushNeg ? CreateNode(NOT,output) : output;
- output = CreateSimplifiedINEQ(kind,left,right,pushNeg);
- break;
- }
- default:
- FatalError("SimplifyAtomicFormula: NO atomic formula of the kind: ",ASTUndefined,kind);
- break;
- }
-
- //memoize
- UpdateSimplifyMap(a,output,pushNeg);
- return output;
- } //end of SimplifyAtomicFormula()
-
- ASTNode BeevMgr::CreateSimplifiedINEQ(Kind k,
- const ASTNode& left,
- const ASTNode& right,
- bool pushNeg) {
- ASTNode output;
- if(BVCONST == left.GetKind() && BVCONST == right.GetKind()) {
- output = BVConstEvaluator(CreateNode(k,left,right));
- output = pushNeg ? (ASTFalse == output) ? ASTTrue : ASTFalse : output;
- return output;
- }
-
- unsigned len = left.GetValueWidth();
- ASTNode zero = CreateZeroConst(len);
- ASTNode one = CreateOneConst(len);
- ASTNode max = CreateMaxConst(len);
- switch(k){
- case BVLT:
- if(right == zero) {
- output = pushNeg ? ASTTrue : ASTFalse;
- }
- else if(left == right) {
- output = pushNeg ? ASTTrue : ASTFalse;
- }
- else if(one == right) {
- output = CreateSimplifiedEQ(left,zero);
- output = pushNeg ? CreateNode(NOT,output) : output;
- }
- else {
- output = pushNeg ? CreateNode(BVLE,right,left) : CreateNode(BVLT,left,right);
- }
- break;
- case BVLE:
- if(left == zero) {
- output = pushNeg ? ASTFalse : ASTTrue;
- }
- else if(left == right) {
- output = pushNeg ? ASTFalse : ASTTrue;
- }
- else if(max == right) {
- output = pushNeg ? ASTFalse : ASTTrue;
- }
- else if(zero == right) {
- output = CreateSimplifiedEQ(left,zero);
- output = pushNeg ? CreateNode(NOT,output) : output;
- }
- else {
- output = pushNeg ? CreateNode(BVLT,right,left) : CreateNode(BVLE,left,right);
- }
- break;
- case BVGT:
- if(left == zero) {
- output = pushNeg ? ASTTrue : ASTFalse;
- }
- else if(left == right) {
- output = pushNeg ? ASTTrue : ASTFalse;
- }
- else {
- output = pushNeg ? CreateNode(BVLE,left,right) : CreateNode(BVLT,right,left);
- }
- break;
- case BVGE:
- if(right == zero) {
- output = pushNeg ? ASTFalse : ASTTrue;
- }
- else if(left == right) {
- output = pushNeg ? ASTFalse : ASTTrue;
- }
- else {
- output = pushNeg ? CreateNode(BVLT,left,right) : CreateNode(BVLE,right,left);
- }
- break;
- case BVSLT:
- case BVSLE:
- case BVSGE:
- case BVSGT: {
- output = CreateNode(k,left,right);
- output = pushNeg ? CreateNode(NOT,output) : output;
- }
- break;
- default:
- FatalError("Wrong Kind");
- break;
- }
-
- return output;
- }
-
- //takes care of some simple ITE Optimizations in the context of equations
- ASTNode BeevMgr::ITEOpt_InEqs(const ASTNode& in) {
- CountersAndStats("ITEOpts_InEqs");
-
- if(!(EQ == in.GetKind() && optimize)) {
- return in;
- }
-
- ASTNode output;
- if(CheckSimplifyMap(in,output,false)) {
- return output;
- }
-
- ASTNode in1 = in[0];
- ASTNode in2 = in[1];
- Kind k1 = in1.GetKind();
- Kind k2 = in2.GetKind();
- if(in1 == in2) {
- //terms are syntactically the same
- output = ASTTrue;
- }
- else if(BVCONST == k1 && BVCONST == k2) {
- //here the terms are definitely not syntactically equal but may
- //be semantically equal.
- output = ASTFalse;
- }
- else if(ITE == k1 &&
- BVCONST == in1[1].GetKind() &&
- BVCONST == in1[2].GetKind() && BVCONST == k2) {
- //if one side is a BVCONST and the other side is an ITE over
- //BVCONST then we can do the following optimization:
- //
- // c = ITE(cond,c,d) <=> cond
- //
- // similarly ITE(cond,c,d) = c <=> cond
- //
- // c = ITE(cond,d,c) <=> NOT(cond)
- //
- //similarly ITE(cond,d,c) = d <=> NOT(cond)
- ASTNode cond = in1[0];
- if(in1[1] == in2) {
- //ITE(cond, c, d) = c <=> cond
- output = cond;
- }
- else if(in1[2] == in2) {
- cond = SimplifyFormula(cond,true);
- output = cond;
- }
- else {
- //last resort is to CreateNode
- output = CreateNode(EQ,in1,in2);
- }
- }
- else if(ITE == k2 &&
- BVCONST == in2[1].GetKind() &&
- BVCONST == in2[2].GetKind() && BVCONST == k1) {
- ASTNode cond = in2[0];
- if(in2[1] == in1) {
- //ITE(cond, c, d) = c <=> cond
- output = cond;
- }
- else if(in2[2] == in1) {
- cond = SimplifyFormula(cond,true);
- output = cond;
- }
- else {
- //last resort is to CreateNode
- output = CreateNode(EQ,in1,in2);
- }
- }
- else {
- //last resort is to CreateNode
- output = CreateNode(EQ,in1,in2);
- }
-
- UpdateSimplifyMap(in,output,false);
- return output;
- } //End of ITEOpts_InEqs()
-
- //Tries to simplify the input to TRUE/FALSE. if it fails, then
- //return the constructed equality
- ASTNode BeevMgr::CreateSimplifiedEQ(const ASTNode& in1, const ASTNode& in2) {
- CountersAndStats("CreateSimplifiedEQ");
- Kind k1 = in1.GetKind();
- Kind k2 = in2.GetKind();
-
- if(!optimize) {
- return CreateNode(EQ,in1,in2);
- }
-
- if(in1 == in2)
- //terms are syntactically the same
- return ASTTrue;
-
- //here the terms are definitely not syntactically equal but may be
- //semantically equal.
- if(BVCONST == k1 && BVCONST == k2)
- return ASTFalse;
-
- //last resort is to CreateNode
- return CreateNode(EQ,in1,in2);
- }
-
- //accepts cond == t1, then part is t2, and else part is t3
- ASTNode BeevMgr::CreateSimplifiedTermITE(const ASTNode& in0,
- const ASTNode& in1, const ASTNode& in2) {
- ASTNode t0 = in0;
- ASTNode t1 = in1;
- ASTNode t2 = in2;
- CountersAndStats("CreateSimplifiedITE");
- if(!optimize) {
- if(t1.GetValueWidth() != t2.GetValueWidth()) {
- cerr << "t2 is : = " << t2;
- FatalError("CreateSimplifiedTermITE: the lengths of then and else branches don't match",t1);
- }
- if(t1.GetIndexWidth() != t2.GetIndexWidth()) {
- cerr << "t2 is : = " << t2;
- FatalError("CreateSimplifiedTermITE: the lengths of then and else branches don't match",t1);
- }
- return CreateTerm(ITE,t1.GetValueWidth(),t0,t1,t2);
- }
-
- if(t0 == ASTTrue)
- return t1;
- if (t0 == ASTFalse)
- return t2;
- if(t1 == t2)
- return t1;
- if(CheckAlwaysTrueFormMap(t0)) {
- return t1;
- }
- if(CheckAlwaysTrueFormMap(CreateNode(NOT,t0)) ||
- (NOT == t0.GetKind() && CheckAlwaysTrueFormMap(t0[0]))) {
- return t2;
- }
-
- return CreateTerm(ITE,t1.GetValueWidth(),t0,t1,t2);
- }
-
- ASTNode BeevMgr::SimplifyAndOrFormula(const ASTNode& a, bool pushNeg) {
- ASTNode output;
- //cerr << "input:\n" << a << endl;
-
- if(CheckSimplifyMap(a,output,pushNeg))
- return output;
-
- ASTVec c, outvec;
- c = a.GetChildren();
- ASTNode flat = FlattenOneLevel(a);
- c = flat.GetChildren();
- SortByExprNum(c);
-
- Kind k = a.GetKind();
- bool isAnd = (k == AND) ? true : false;
-
- ASTNode annihilator = isAnd ?
- (pushNeg ? ASTTrue : ASTFalse):
- (pushNeg ? ASTFalse : ASTTrue);
-
- ASTNode identity = isAnd ?
- (pushNeg ? ASTFalse : ASTTrue):
- (pushNeg ? ASTTrue : ASTFalse);
-
- //do the work
- ASTVec::const_iterator next_it;
- for(ASTVec::const_iterator i=c.begin(),iend=c.end();i!=iend;i++) {
- ASTNode aaa = *i;
- next_it = i+1;
- bool nextexists = (next_it < iend);
-
- aaa = SimplifyFormula(aaa,pushNeg);
- if(annihilator == aaa) {
- //memoize
- UpdateSimplifyMap(*i,annihilator,pushNeg);
- UpdateSimplifyMap(a, annihilator,pushNeg);
- //cerr << "annihilator1: output:\n" << annihilator << endl;
- return annihilator;
- }
- ASTNode bbb = ASTFalse;
- if(nextexists) {
- bbb = SimplifyFormula(*next_it,pushNeg);
- }
- if(nextexists && bbb == aaa) {
- //skip the duplicate aaa. *next_it will be included
- }
- else if(nextexists &&
- ((bbb.GetKind() == NOT && bbb[0] == aaa))) {
- //memoize
- UpdateSimplifyMap(a, annihilator,pushNeg);
- //cerr << "annihilator2: output:\n" << annihilator << endl;
- return annihilator;
- }
- else if(identity == aaa) {
- // //drop identites
- }
- else if((!isAnd && !pushNeg) ||
- (isAnd && pushNeg)) {
- outvec.push_back(aaa);
- }
- else if((isAnd && !pushNeg) ||
- (!isAnd && pushNeg)) {
- outvec.push_back(aaa);
- }
- else {
- outvec.push_back(aaa);
- }
- }
-
- switch(outvec.size()) {
- case 0: {
- //only identities were dropped
- output = identity;
- break;
- }
- case 1: {
- output = SimplifyFormula(outvec[0],false);
- break;
- }
- default: {
- output = (isAnd) ?
- (pushNeg ? CreateNode(OR,outvec) : CreateNode(AND,outvec)):
- (pushNeg ? CreateNode(AND,outvec) : CreateNode(OR,outvec));
- //output = FlattenOneLevel(output);
- break;
- }
- }
- //memoize
- UpdateSimplifyMap(a,output,pushNeg);
- //cerr << "output:\n" << output << endl;
- return output;
- } //end of SimplifyAndOrFormula
-
-
- ASTNode BeevMgr::SimplifyNotFormula(const ASTNode& a, bool pushNeg) {
- ASTNode output;
- if(CheckSimplifyMap(a,output,pushNeg))
- return output;
-
- if(!(a.Degree() == 1 && NOT == a.GetKind()))
- FatalError("SimplifyNotFormula: input vector with more than 1 node",ASTUndefined);
-
- //if pushNeg is set then there is NOT on top
- unsigned int NotCount = pushNeg ? 1 : 0;
- ASTNode o = a;
- //count the number of NOTs in 'a'
- while(NOT == o.GetKind()) {
- o = o[0];
- NotCount++;
- }
-
- //pushnegation if there are odd number of NOTs
- bool pn = (NotCount % 2 == 0) ? false : true;
-
- if(CheckAlwaysTrueFormMap(o)) {
- output = pn ? ASTFalse : ASTTrue;
- return output;
- }
-
- if(CheckSimplifyMap(o,output,pn)) {
- return output;
- }
-
- if (ASTTrue == o) {
- output = pn ? ASTFalse : ASTTrue;
- }
- else if (ASTFalse == o) {
- output = pn ? ASTTrue : ASTFalse;
- }
- else {
- output = SimplifyFormula(o,pn);
- }
- //memoize
- UpdateSimplifyMap(o,output,pn);
- UpdateSimplifyMap(a,output,pushNeg);
- return output;
- }
-
- ASTNode BeevMgr::SimplifyXorFormula(const ASTNode& a, bool pushNeg) {
- ASTNode output;
- if(CheckSimplifyMap(a,output,pushNeg))
- return output;
-
- if (a.GetChildren().size() > 2) {
- FatalError("Simplify got an XOR with more than two children.");
- }
-
- ASTNode a0 = SimplifyFormula(a[0],false);
- ASTNode a1 = SimplifyFormula(a[1],false);
- output = pushNeg ? CreateNode(IFF,a0,a1) : CreateNode(XOR,a0,a1);
-
- if(XOR == output.GetKind()) {
- a0 = output[0];
- a1 = output[1];
- if(a0 == a1)
- output = ASTFalse;
- else if((a0 == ASTTrue && a1 == ASTFalse) ||
- (a0 == ASTFalse && a1 == ASTTrue))
- output = ASTTrue;
- }
-
- //memoize
- UpdateSimplifyMap(a,output,pushNeg);
- return output;
- }
-
- ASTNode BeevMgr::SimplifyNandFormula(const ASTNode& a, bool pushNeg) {
- ASTNode output,a0,a1;
- if(CheckSimplifyMap(a,output,pushNeg))
- return output;
-
- //the two NOTs cancel out
- if(pushNeg) {
- a0 = SimplifyFormula(a[0],false);
- a1 = SimplifyFormula(a[1],false);
- output = CreateNode(AND,a0,a1);
- }
- else {
- //push the NOT implicit in the NAND
- a0 = SimplifyFormula(a[0],true);
- a1 = SimplifyFormula(a[1],true);
- output = CreateNode(OR,a0,a1);
- }
-
- //memoize
- UpdateSimplifyMap(a,output,pushNeg);
- return output;
- }
-
- ASTNode BeevMgr::SimplifyNorFormula(const ASTNode& a, bool pushNeg) {
- ASTNode output,a0,a1;
- if(CheckSimplifyMap(a,output,pushNeg))
- return output;
-
- //the two NOTs cancel out
- if(pushNeg) {
- a0 = SimplifyFormula(a[0],false);
- a1 = SimplifyFormula(a[1],false);
- output = CreateNode(OR,a0,a1);
- }
- else {
- //push the NOT implicit in the NAND
- a0 = SimplifyFormula(a[0],true);
- a1 = SimplifyFormula(a[1],true);
- output = CreateNode(AND,a0,a1);
- }
-
- //memoize
- UpdateSimplifyMap(a,output,pushNeg);
- return output;
- }
-
- ASTNode BeevMgr::SimplifyImpliesFormula(const ASTNode& a, bool pushNeg) {
- ASTNode output;
- if(CheckSimplifyMap(a,output,pushNeg))
- return output;
-
- if(!(a.Degree()==2 && IMPLIES==a.GetKind()))
- FatalError("SimplifyImpliesFormula: vector with wrong num of nodes",ASTUndefined);
-
- ASTNode c0,c1;
- if(pushNeg) {
- c0 = SimplifyFormula(a[0],false);
- c1 = SimplifyFormula(a[1],true);
- output = CreateNode(AND,c0,c1);
- }
- else {
- c0 = SimplifyFormula(a[0],false);
- c1 = SimplifyFormula(a[1],false);
- if(ASTFalse == c0) {
- output = ASTTrue;
- }
- else if (ASTTrue == c0) {
- output = c1;
- }
- else if (c0 == c1) {
- output = ASTTrue;
- }
- else if(CheckAlwaysTrueFormMap(c0)) {
- // c0 AND (~c0 OR c1) <==> c1
- //
- //applying modus ponens
- output = c1;
- }
- else if(CheckAlwaysTrueFormMap(c1) ||
- CheckAlwaysTrueFormMap(CreateNode(NOT,c0)) ||
- (NOT == c0.GetKind() && CheckAlwaysTrueFormMap(c0[0]))) {
- //(~c0 AND (~c0 OR c1)) <==> TRUE
- //
- //(c0 AND ~c0->c1) <==> TRUE
- output = ASTTrue;
- }
- else if (CheckAlwaysTrueFormMap(CreateNode(NOT,c1)) ||
- (NOT == c1.GetKind() && CheckAlwaysTrueFormMap(c1[0]))) {
- //(~c1 AND c0->c1) <==> (~c1 AND ~c1->~c0) <==> ~c0
- //(c1 AND c0->~c1) <==> (c1 AND c1->~c0) <==> ~c0
- output = CreateNode(NOT,c0);
- }
- else {
- if(NOT == c0.GetKind()) {
- output = CreateNode(OR,c0[0],c1);
- }
- else {
- output = CreateNode(OR,CreateNode(NOT,c0),c1);
- }
- }
- }
-
- //memoize
- UpdateSimplifyMap(a,output,pushNeg);
- return output;
- }
-
- ASTNode BeevMgr::SimplifyIffFormula(const ASTNode& a, bool pushNeg) {
- ASTNode output;
- if(CheckSimplifyMap(a,output,pushNeg))
- return output;
-
- if(!(a.Degree()==2 && IFF==a.GetKind()))
- FatalError("SimplifyIffFormula: vector with wrong num of nodes",ASTUndefined);
-
- ASTNode c0 = a[0];
- ASTNode c1 = SimplifyFormula(a[1],false);
-
- if(pushNeg)
- c0 = SimplifyFormula(c0,true);
- else
- c0 = SimplifyFormula(c0,false);
-
- if(ASTTrue == c0) {
- output = c1;
- }
- else if (ASTFalse == c0) {
- output = SimplifyFormula(c1,true);
- }
- else if (ASTTrue == c1) {
- output = c0;
- }
- else if (ASTFalse == c1) {
- output = SimplifyFormula(c0,true);
- }
- else if (c0 == c1) {
- output = ASTTrue;
- }
- else if((NOT == c0.GetKind() && c0[0] == c1) ||
- (NOT == c1.GetKind() && c0 == c1[0])) {
- output = ASTFalse;
- }
- else if(CheckAlwaysTrueFormMap(c0)) {
- output = c1;
- }
- else if(CheckAlwaysTrueFormMap(c1)) {
- output = c0;
- }
- else if(CheckAlwaysTrueFormMap(CreateNode(NOT,c0))) {
- output = CreateNode(NOT,c1);
- }
- else if(CheckAlwaysTrueFormMap(CreateNode(NOT,c1))) {
- output = CreateNode(NOT,c0);
- }
- else {
- output = CreateNode(IFF,c0,c1);
- }
-
- //memoize
- UpdateSimplifyMap(a,output,pushNeg);
- return output;
- }
-
- ASTNode BeevMgr::SimplifyIteFormula(const ASTNode& b, bool pushNeg) {
- if(!optimize)
- return b;
-
- ASTNode output;
- if(CheckSimplifyMap(b,output,pushNeg))
- return output;
-
- if(!(b.Degree() == 3 && ITE == b.GetKind()))
- FatalError("SimplifyIteFormula: vector with wrong num of nodes",ASTUndefined);
-
- ASTNode a = b;
- ASTNode t0 = SimplifyFormula(a[0],false);
- ASTNode t1,t2;
- if(pushNeg) {
- t1 = SimplifyFormula(a[1],true);
- t2 = SimplifyFormula(a[2],true);
- }
- else {
- t1 = SimplifyFormula(a[1],false);
- t2 = SimplifyFormula(a[2],false);
- }
-
- if(ASTTrue == t0) {
- output = t1;
- }
- else if (ASTFalse == t0) {
- output = t2;
- }
- else if (t1 == t2) {
- output = t1;
- }
- else if(ASTTrue == t1 && ASTFalse == t2) {
- output = t0;
- }
- else if(ASTFalse == t1 && ASTTrue == t2) {
- output = SimplifyFormula(t0,true);
- }
- else if(ASTTrue == t1) {
- output = CreateNode(OR,t0,t2);
- }
- else if(ASTFalse == t1) {
- output = CreateNode(AND,CreateNode(NOT,t0),t2);
- }
- else if(ASTTrue == t2) {
- output = CreateNode(OR,CreateNode(NOT,t0),t1);
- }
- else if(ASTFalse == t2) {
- output = CreateNode(AND,t0,t1);
- }
- else if(CheckAlwaysTrueFormMap(t0)) {
- output = t1;
- }
- else if(CheckAlwaysTrueFormMap(CreateNode(NOT,t0)) ||
- (NOT == t0.GetKind() && CheckAlwaysTrueFormMap(t0[0]))) {
- output = t2;
- }
- else {
- output = CreateNode(ITE,t0,t1,t2);
- }
-
- //memoize
- UpdateSimplifyMap(a,output,pushNeg);
- return output;
- }
-
- //one level deep flattening
- ASTNode BeevMgr::FlattenOneLevel(const ASTNode& a) {
- Kind k = a.GetKind();
- if(!(BVPLUS == k ||
- AND == k || OR == k
- //|| BVAND == k
- //|| BVOR == k
- )
- ) {
- return a;
- }
-
- ASTNode output;
- // if(CheckSimplifyMap(a,output,false)) {
- // //check memo table
- // //cerr << "output of SimplifyTerm Cache: " << output << endl;
- // return output;
- // }
-
- ASTVec c = a.GetChildren();
- ASTVec o;
- for(ASTVec::iterator it=c.begin(),itend=c.end();it!=itend;it++) {
- ASTNode aaa = *it;
- if(k == aaa.GetKind()) {
- ASTVec ac = aaa.GetChildren();
- o.insert(o.end(),ac.begin(),ac.end());
- }
- else
- o.push_back(aaa);
- }
-
- if(is_Form_kind(k))
- output = CreateNode(k,o);
- else
- output = CreateTerm(k,a.GetValueWidth(),o);
-
- //UpdateSimplifyMap(a,output,false);
- return output;
- //memoize
- } //end of flattenonelevel()
-
- ASTNode BeevMgr::SimplifyTerm_TopLevel(const ASTNode& b) {
- SimplifyMap.clear();
- SimplifyNegMap.clear();
- ASTNode out = SimplifyTerm(b);
- SimplifyNegMap.clear();
- SimplifyMap.clear();
- return out;
- }
-
- //This function simplifies terms based on their kind
- ASTNode BeevMgr::SimplifyTerm(const ASTNode& inputterm) {
- //cout << "SimplifyTerm: input: " << a << endl;
- if(!optimize) {
- return inputterm;
- }
-
- BVTypeCheck(inputterm);
- ASTNode output;
- if(wordlevel_solve && CheckSolverMap(inputterm,output)) {
- //cout << "SimplifyTerm: output: " << output << endl;
- return SimplifyTerm(output);
- }
-
- if(CheckSimplifyMap(inputterm,output,false)) {
- //cerr << "output of SimplifyTerm Cache: " << output << endl;
- return output;
- }
-
- Kind k = inputterm.GetKind();
- if(!is_Term_kind(k)) {
- FatalError("SimplifyTerm: You have input a Non-term",ASTUndefined);
- }
-
- unsigned int inputValueWidth = inputterm.GetValueWidth();
- switch(k) {
- case BVCONST:
- output = inputterm;
- break;
- case SYMBOL:
- if(CheckSolverMap(inputterm,output)) {
- return SimplifyTerm(output);
- }
- output = inputterm;
- break;
- case BVMULT:
- case BVPLUS:{
- if(BVMULT == k && 2 != inputterm.Degree()) {
- FatalError("SimplifyTerm: We assume that BVMULT is binary",inputterm);
- }
-
- ASTVec c = FlattenOneLevel(inputterm).GetChildren();
- SortByExprNum(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
- SortByExprNum(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();
- SortByExprNum(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 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();
- SortByExprNum(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:
- SortByExprNum(o);
- output = CreateTerm(k,inputValueWidth,o);
- if(constant) {
- output = BVConstEvaluator(output);
- }
- break;
- }
- break;
- }
- case BVCONCAT:{
- ASTNode t = SimplifyTerm(inputterm[0]);
- ASTNode u = SimplifyTerm(inputterm[1]);
- Kind tkind = t.GetKind();
- Kind ukind = u.GetKind();
-
-
- if(BVCONST == tkind && BVCONST == ukind) {
- output = BVConstEvaluator(CreateTerm(BVCONCAT,inputValueWidth,t,u));
- }
- else if(BVEXTRACT == tkind &&
- BVEXTRACT == ukind &&
- t[0] == u[0]) {
- //to handle the case x[m:n]@x[n-1:k] <==> x[m:k]
- ASTNode t_hi = t[1];
- ASTNode t_low = t[2];
- ASTNode u_hi = u[1];
- ASTNode u_low = u[2];
- ASTNode c = BVConstEvaluator(CreateTerm(BVPLUS,32,u_hi,CreateOneConst(32)));
- if(t_low == c) {
- output = CreateTerm(BVEXTRACT,inputValueWidth,t[0],t_hi,u_low);
- }
- else {
- output = CreateTerm(BVCONCAT,inputValueWidth,t,u);
- }
- }
- else {
- output = CreateTerm(BVCONCAT,inputValueWidth,t,u);
- }
- break;
- }
- case BVXOR:
- case BVXNOR:
- case BVNAND:
- case BVNOR:
- case BVLEFTSHIFT:
- case BVRIGHTSHIFT:
- case BVVARSHIFT:
- case BVSRSHIFT:
- case BVDIV:
- case BVMOD: {
- ASTVec c = inputterm.GetChildren();
- ASTVec o;
- bool constant = true;
- for(ASTVec::iterator it=c.begin(),itend=c.end();it!=itend;it++) {
- ASTNode aaa = SimplifyTerm(*it);
- if(BVCONST != aaa.GetKind()) {
- constant = false;
- }
- o.push_back(aaa);
- }
- output = CreateTerm(k,inputValueWidth,o);
- if(constant)
- output = BVConstEvaluator(output);
- break;
- }
- case READ: {
- ASTNode out1;
- //process only if not in the substitution map. simplifymap
- //has been checked already
- if(!CheckSubstitutionMap(inputterm,out1)) {
- if(WRITE == inputterm[0].GetKind()) {
- //get rid of all writes
- ASTNode nowrites = RemoveWrites_TopLevel(inputterm);
- out1 = nowrites;
- }
- else if (ITE == inputterm[0].GetKind()){
- ASTNode cond = SimplifyFormula(inputterm[0][0],false);
- ASTNode arr1 = SimplifyTerm(inputterm[0][1]);
- ASTNode arr2 = SimplifyTerm(inputterm[0][2]);
-
- ASTNode index = SimplifyTerm(inputterm[1]);
-
- ASTNode read1 = CreateTerm(READ,inputValueWidth,arr1,index);
- ASTNode read2 = CreateTerm(READ,inputValueWidth,arr2,index);
- out1 = CreateSimplifiedTermITE(cond,read1,read2);
- }
- else {
- //arr is a SYMBOL for sure
- ASTNode arr = inputterm[0];
- ASTNode index = SimplifyTerm(inputterm[1]);
- out1 = CreateTerm(READ,inputValueWidth,arr,index);
- }
- }
- //it is possible that after all the procesing the READ term
- //reduces to READ(Symbol,const) and hence we should check the
- //substitutionmap once again.
- if(!CheckSubstitutionMap(out1,output))
- output = out1;
- break;
- }
- case ITE: {
- ASTNode t0 = SimplifyFormula(inputterm[0],false);
- ASTNode t1 = SimplifyTerm(inputterm[1]);
- ASTNode t2 = SimplifyTerm(inputterm[2]);
- output = CreateSimplifiedTermITE(t0,t1,t2);
- break;
- }
- case SBVMOD:
- case SBVDIV: {
- ASTVec c = inputterm.GetChildren();
- ASTVec o;
- for(ASTVec::iterator it=c.begin(),itend=c.end();it!=itend;it++) {
- ASTNode aaa = SimplifyTerm(*it);
- o.push_back(aaa);
- }
- output = CreateTerm(k,inputValueWidth,o);
- break;
- }
- case WRITE:
- default:
- FatalError("SimplifyTerm: Control should never reach here:", inputterm, k);
- return inputterm;
- break;
- }
-
- //memoize
- UpdateSimplifyMap(inputterm,output,false);
- //cerr << "SimplifyTerm: output" << output << endl;
- 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) {
- //Don't do the check in optimized mode
- if(optimize)
- return;
-
- if(NodeSize(a,true) < 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;
- }
-
- 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();
- SortByExprNum(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();
- SortByExprNum(cNodes);
- vars_to_consts[cccc].push_back(max);
- }
- else if(BVCONST == aaa.GetKind()) {
- constkids.push_back(aaa);
- }
- else if(BVUMINUS == aaa.GetKind()) {
- //helps to convert BVUMINUS into a BVMULT. here the max
- //constant represents -1. this transformation allows us to
- //conclude that x + BVUMINUS(x) is 0.
- vars_to_consts[aaa[0]].push_back(max);
- }
- else
- vars_to_consts[aaa].push_back(one);
- } //end of for loop
-
- //go over the map from variables to vector of values. combine the
- //vector of values, multiply to the variable, and put the
- //resultant monomial in the output BVPLUS.
- for(ASTNodeToVecMap::iterator it=vars_to_consts.begin(),itend=vars_to_consts.end();
- it!=itend;it++){
- ASTVec ccc = it->second;
-
- ASTNode constant;
- if(1 < ccc.size()) {
- constant = CreateTerm(BVPLUS,ccc[0].GetValueWidth(),ccc);
- constant = BVConstEvaluator(constant);
- }
- else
- constant = ccc[0];
-
- //constant * var
- ASTNode monom;
- if(zero == constant)
- monom = zero;
- else if (one == constant)
- monom = it->first;
- else
- monom =
- SimplifyTerm(CreateTerm(BVMULT,constant.GetValueWidth(),constant,it->first));
- if(zero != monom) {
- outputvec.push_back(monom);
- }
- } //end of for loop
-
- if(constkids.size() > 1) {
- ASTNode output = CreateTerm(BVPLUS,constkids[0].GetValueWidth(),constkids);
- output = BVConstEvaluator(output);
- if(output != zero)
- outputvec.push_back(output);
- }
- else if (constkids.size() == 1) {
- if(constkids[0] != zero)
- outputvec.push_back(constkids[0]);
- }
-
- if (outputvec.size() > 1) {
- output = CreateTerm(BVPLUS,len,outputvec);
- }
- else if(outputvec.size() == 1) {
- output = outputvec[0];
- }
- else {
- output = zero;
- }
-
- //memoize
- //UpdateSimplifyMap(a,output,false);
- return output;
- } //end of CombineLikeTerms()
-
- //accepts lhs and rhs, and returns lhs - rhs = 0. The function
- //assumes that lhs and rhs have already been simplified. although
- //this assumption is not needed for correctness, it is essential for
- //performance. The function also assumes that lhs is a BVPLUS
- ASTNode BeevMgr::LhsMinusRhs(const ASTNode& eq) {
- //if input is not an equality, simply return it
- if(EQ != eq.GetKind())
- return eq;
-
- ASTNode lhs = eq[0];
- ASTNode rhs = eq[1];
- Kind k_lhs = lhs.GetKind();
- Kind k_rhs = rhs.GetKind();
- //either the lhs has to be a BVPLUS or the rhs has to be a
- //BVPLUS
- if(!(BVPLUS == k_lhs ||
- BVPLUS == k_rhs ||
- (BVMULT == k_lhs &&
- BVMULT == k_rhs)
- )) {
- return eq;
- }
-
- ASTNode output;
- if(CheckSimplifyMap(eq,output,false)) {
- //check memo table
- //cerr << "output of SimplifyTerm Cache: " << output << endl;
- return output;
- }
-
- //if the lhs is not a BVPLUS, but the rhs is a BVPLUS, then swap
- //the lhs and rhs
- bool swap_flag = false;
- if(BVPLUS != k_lhs && BVPLUS == k_rhs) {
- ASTNode swap = lhs;
- lhs = rhs;
- rhs = swap;
- swap_flag = true;
- }
-
- unsigned int len = lhs.GetValueWidth();
- ASTNode zero = CreateZeroConst(len);
- //right is -1*(rhs): Simplify(-1*rhs)
- rhs = SimplifyTerm(CreateTerm(BVUMINUS,len,rhs));
-
- ASTVec lvec = lhs.GetChildren();
- ASTVec rvec = rhs.GetChildren();
- ASTNode lhsplusrhs;
- if(BVPLUS != lhs.GetKind() && BVPLUS != rhs.GetKind()) {
- lhsplusrhs = CreateTerm(BVPLUS,len,lhs,rhs);
- }
- else if(BVPLUS == lhs.GetKind() && BVPLUS == rhs.GetKind()) {
- //combine the childnodes of the left and the right
- lvec.insert(lvec.end(),rvec.begin(),rvec.end());
- lhsplusrhs = CreateTerm(BVPLUS,len,lvec);
- }
- else if(BVPLUS == lhs.GetKind() && BVPLUS != rhs.GetKind()){
- lvec.push_back(rhs);
- lhsplusrhs = CreateTerm(BVPLUS,len,lvec);
- }
- else {
- //Control should never reach here
- FatalError("LhsMinusRhs: Control should never reach here\n");
- }
-
- //combine like terms
- output = CombineLikeTerms(lhsplusrhs);
- output = SimplifyTerm(output);
- //
- //Now make output into: lhs-rhs = 0
- output = CreateSimplifiedEQ(output,zero);
- //sort if BVPLUS
- if(BVPLUS == output.GetKind()) {
- ASTVec outv = output.GetChildren();
- SortByExprNum(outv);
- output = CreateTerm(BVPLUS,len,outv);
- }
-
- //memoize
- //UpdateSimplifyMap(eq,output,false);
- return output;
- } //end of LhsMinusRHS()
-
- //THis function accepts a BVMULT(t1,t2) and distributes the mult
- //over plus if either or both t1 and t2 are BVPLUSes.
- //
- // x*(y1 + y2 + ...+ yn) <==> x*y1 + x*y2 + ... + x*yn
- //
- // (y1 + y2 + ...+ yn)*x <==> x*y1 + x*y2 + ... + x*yn
- //
- // The function assumes that the BVPLUSes have been flattened
- ASTNode BeevMgr::DistributeMultOverPlus(const ASTNode& a, bool startdistribution) {
- if(!startdistribution)
- return a;
- Kind k = a.GetKind();
- if(BVMULT != k)
- return a;
-
- ASTNode left = a[0];
- ASTNode right = a[1];
- Kind left_kind = left.GetKind();
- Kind right_kind = right.GetKind();
-
- ASTNode output;
- if(CheckSimplifyMap(a,output,false)) {
- //check memo table
- //cerr << "output of SimplifyTerm Cache: " << output << endl;
- return output;
- }
-
- //special case optimization: c1*(c2*t1) <==> (c1*c2)*t1
- if(BVCONST == left_kind &&
- BVMULT == right_kind &&
- BVCONST == right[0].GetKind()) {
- ASTNode c = BVConstEvaluator(CreateTerm(BVMULT,a.GetValueWidth(),left,right[0]));
- c = CreateTerm(BVMULT,a.GetValueWidth(),c,right[1]);
- return c;
- left = c[0];
- right = c[1];
- left_kind = left.GetKind();
- right_kind = right.GetKind();
- }
-
- //special case optimization: c1*(t1*c2) <==> (c1*c2)*t1
- if(BVCONST == left_kind &&
- BVMULT == right_kind &&
- BVCONST == right[1].GetKind()) {
- ASTNode c = BVConstEvaluator(CreateTerm(BVMULT,a.GetValueWidth(),left,right[1]));
- c = CreateTerm(BVMULT,a.GetValueWidth(),c,right[0]);
- return c;
- left = c[0];
- right = c[1];
- left_kind = left.GetKind();
- right_kind = right.GetKind();
- }
-
- //atleast one of left or right have to be BVPLUS
- if(!(BVPLUS == left_kind || BVPLUS == right_kind)) {
- return a;
- }
-
- //if left is BVPLUS and right is not, then swap left and right. we
- //can do this since BVMULT is communtative
- ASTNode swap;
- if(BVPLUS == left_kind && BVPLUS != right_kind) {
- swap = left;
- left = right;
- right = swap;
- }
- left_kind = left.GetKind();
- right_kind = right.GetKind();
-
- //by this point we are gauranteed that right is a BVPLUS, but left
- //may not be
- ASTVec rightnodes = right.GetChildren();
- ASTVec outputvec;
- unsigned len = a.GetValueWidth();
- ASTNode zero = CreateZeroConst(len);
- ASTNode one = CreateOneConst(len);
- if(BVPLUS != left_kind) {
- //if the multiplier is not a BVPLUS then we have a special case
- // x*(y1 + y2 + ...+ yn) <==> x*y1 + x*y2 + ... + x*yn
- if(zero == left) {
- outputvec.push_back(zero);
- }
- else if(one == left) {
- outputvec.push_back(left);
- }
- else {
- for(ASTVec::iterator j=rightnodes.begin(),jend=rightnodes.end();
- j!=jend;j++) {
- ASTNode out = SimplifyTerm(CreateTerm(BVMULT,len,left,*j));
- outputvec.push_back(out);
- }
- }
- }
- else {
- ASTVec leftnodes = left.GetChildren();
- // (x1 + x2 + ... + xm)*(y1 + y2 + ...+ yn) <==> x1*y1 + x1*y2 +
- // ... + x2*y1 + ... + xm*yn
- for(ASTVec::iterator i=leftnodes.begin(),iend=leftnodes.end();
- i!=iend;i++) {
- ASTNode multiplier = *i;
- for(ASTVec::iterator j=rightnodes.begin(),jend=rightnodes.end();
- j!=jend;j++) {
- ASTNode out = SimplifyTerm(CreateTerm(BVMULT,len,multiplier,*j));
- outputvec.push_back(out);
- }
- }
- }
-
- //compute output here
- if(outputvec.size() > 1) {
- output = CombineLikeTerms(CreateTerm(BVPLUS,len,outputvec));
- output = SimplifyTerm(output);
- }
- else
- output = SimplifyTerm(outputvec[0]);
-
- //memoize
- //UpdateSimplifyMap(a,output,false);
- return output;
- } //end of distributemultoverplus()
-
- //converts the BVSX(len, a0) operator into ITE( check top bit,
- //extend a0 by 1, extend a0 by 0)
- ASTNode BeevMgr::ConvertBVSXToITE(const ASTNode& a) {
- if(BVSX != a.GetKind())
- return a;
-
- ASTNode output;
- if(CheckSimplifyMap(a,output,false)) {
- //check memo table
- //cerr << "output of ConvertBVSXToITE Cache: " << output << endl;
- return output;
- }
-
- ASTNode a0 = a[0];
- unsigned a_len = a.GetValueWidth();
- unsigned a0_len = a0.GetValueWidth();
-
- if(a0_len > a_len){
- FatalError("Trying to sign_extend a larger BV into a smaller BV");
- return ASTUndefined; //to stop the compiler from producing bogus warnings
- }
-
- //sign extend
- unsigned extensionlen = a_len-a0_len;
- if(0 == extensionlen) {
- UpdateSimplifyMap(a,output,false);
- return a;
- }
-
- std::string ones;
- for(unsigned c=0; c < extensionlen;c++)
- ones += '1';
- std::string zeros;
- for(unsigned c=0; c < extensionlen;c++)
- zeros += '0';
-
- //string of oness of length extensionlen
- BEEV::ASTNode BVOnes = CreateBVConst(ones.c_str(),2);
- //string of zeros of length extensionlen
- BEEV::ASTNode BVZeros = CreateBVConst(zeros.c_str(),2);
-
- //string of ones BVCONCAT a0
- BEEV::ASTNode concatOnes = CreateTerm(BEEV::BVCONCAT,a_len,BVOnes,a0);
- //string of zeros BVCONCAT a0
- BEEV::ASTNode concatZeros = CreateTerm(BEEV::BVCONCAT,a_len,BVZeros,a0);
-
- //extract top bit of a0
- BEEV::ASTNode hi = CreateBVConst(32,a0_len-1);
- BEEV::ASTNode low = CreateBVConst(32,a0_len-1);
- BEEV::ASTNode topBit = CreateTerm(BEEV::BVEXTRACT,1,a0,hi,low);
-
- //compare topBit of a0 with 0bin1
- BEEV::ASTNode condition = CreateSimplifiedEQ(CreateBVConst(1,1),topBit);
-
- //ITE(topbit = 0bin1, 0bin1111...a0, 0bin000...a0)
- output = CreateSimplifiedTermITE(condition,concatOnes,concatZeros);
- UpdateSimplifyMap(a,output,false);
- return output;
- } //end of ConvertBVSXToITE()
-
-
- ASTNode BeevMgr::RemoveWrites_TopLevel(const ASTNode& term) {
- if(READ != term.GetKind() && WRITE != term[0].GetKind()) {
- FatalError("RemovesWrites: Input must be a READ over a WRITE",term);
- }
-
- if(!Begin_RemoveWrites &&
- !SimplifyWrites_InPlace_Flag &&
- !start_abstracting) {
- return term;
- }
- else if(!Begin_RemoveWrites &&
- SimplifyWrites_InPlace_Flag &&
- !start_abstracting) {
- //return term;
- return SimplifyWrites_InPlace(term);
- }
- else {
- return RemoveWrites(term);
- }
- } //end of RemoveWrites_TopLevel()
-
- ASTNode BeevMgr::SimplifyWrites_InPlace(const ASTNode& term) {
- ASTNodeMultiSet WriteIndicesSeenSoFar;
- bool SeenNonConstWriteIndex = false;
-
- if(READ != term.GetKind() &&
- WRITE != term[0].GetKind()) {
- FatalError("RemovesWrites: Input must be a READ over a WRITE",term);
- }
-
- ASTNode output;
- if(CheckSimplifyMap(term,output,false)) {
- return output;
- }
-
- ASTVec writeIndices, writeValues;
- unsigned int width = term.GetValueWidth();
- ASTNode write = term[0];
- unsigned indexwidth = write.GetIndexWidth();
- ASTNode readIndex = SimplifyTerm(term[1]);
-
- do {
- ASTNode writeIndex = SimplifyTerm(write[1]);
- ASTNode writeVal = SimplifyTerm(write[2]);
-
- //compare the readIndex and the current writeIndex and see if they
- //simplify to TRUE or FALSE or UNDETERMINABLE at this stage
- ASTNode compare_readwrite_indices =
- SimplifyFormula(CreateSimplifiedEQ(writeIndex,readIndex),false);
-
- //if readIndex and writeIndex are equal
- if(ASTTrue == compare_readwrite_indices && !SeenNonConstWriteIndex) {
- UpdateSimplifyMap(term,writeVal,false);
- return writeVal;
- }
-
- if(!(ASTTrue == compare_readwrite_indices ||
- ASTFalse == compare_readwrite_indices)) {
- SeenNonConstWriteIndex = true;
- }
-
- //if (readIndex=writeIndex <=> FALSE)
- if(ASTFalse == compare_readwrite_indices
- ||
- (WriteIndicesSeenSoFar.find(writeIndex) != WriteIndicesSeenSoFar.end())
- ) {
- //drop the current level write
- //do nothing
- }
- else {
- writeIndices.push_back(writeIndex);
- writeValues.push_back(writeVal);
- }
-
- //record the write indices seen so far
- //if(BVCONST == writeIndex.GetKind()) {
- WriteIndicesSeenSoFar.insert(writeIndex);
- //}
-
- //Setup the write for the new iteration, one level inner write
- write = write[0];
- }while (SYMBOL != write.GetKind());
-
- ASTVec::reverse_iterator it_index = writeIndices.rbegin();
- ASTVec::reverse_iterator itend_index = writeIndices.rend();
- ASTVec::reverse_iterator it_values = writeValues.rbegin();
- ASTVec::reverse_iterator itend_values = writeValues.rend();
-
- //"write" must be a symbol at the control point before the
- //begining of the "for loop"
-
- for(;it_index!=itend_index;it_index++,it_values++) {
- write = CreateTerm(WRITE,width,write,*it_index,*it_values);
- write.SetIndexWidth(indexwidth);
- }
-
- output = CreateTerm(READ,width,write,readIndex);
- UpdateSimplifyMap(term,output,false);
- return output;
- } //end of SimplifyWrites_In_Place()
-
- //accepts a read over a write and returns a term without the write
- //READ(WRITE(A i val) j) <==> ITE(i=j,val,READ(A,j)). We use a memo
- //table for this function called RemoveWritesMemoMap
- ASTNode BeevMgr::RemoveWrites(const ASTNode& input) {
- //unsigned int width = input.GetValueWidth();
- if(READ != input.GetKind() || WRITE != input[0].GetKind()) {
- FatalError("RemovesWrites: Input must be a READ over a WRITE",input);
- }
-
- ASTNodeMap::iterator it;
- ASTNode output = input;
- if(CheckSimplifyMap(input,output,false)) {
- return output;
- }
-
- if(!start_abstracting && Begin_RemoveWrites) {
- output= ReadOverWrite_To_ITE(input);
- }
-
- if(start_abstracting) {
- ASTNode newVar;
- if(!CheckSimplifyMap(input,newVar,false)) {
- newVar = NewVar(input.GetValueWidth());
- ReadOverWrite_NewName_Map[input] = newVar;
- NewName_ReadOverWrite_Map[newVar] = input;
-
- UpdateSimplifyMap(input,newVar,false);
- ASTNodeStats("New Var Name which replace Read_Over_Write: ", newVar);
- }
- output = newVar;
- } //end of start_abstracting if condition
-
- //memoize
- UpdateSimplifyMap(input,output,false);
- return output;
- } //end of RemoveWrites()
-
- ASTNode BeevMgr::ReadOverWrite_To_ITE(const ASTNode& term) {
- unsigned int width = term.GetValueWidth();
- ASTNode input = term;
- if(READ != term.GetKind() || WRITE != term[0].GetKind()) {
- FatalError("RemovesWrites: Input must be a READ over a WRITE",term);
- }
-
- ASTNodeMap::iterator it;
- ASTNode output;
- // if(CheckSimplifyMap(term,output,false)) {
- // return output;
- // }
-
- ASTNode partialITE = term;
- ASTNode writeA = ASTTrue;
- ASTNode oldRead = term;
- //iteratively expand read-over-write
- do {
- ASTNode write = input[0];
- ASTNode readIndex = SimplifyTerm(input[1]);
- //DO NOT CALL SimplifyTerm() on write[0]. You will go into an
- //infinite loop
- writeA = write[0];
- ASTNode writeIndex = SimplifyTerm(write[1]);
- ASTNode writeVal = SimplifyTerm(write[2]);
-
- ASTNode cond = SimplifyFormula(CreateSimplifiedEQ(writeIndex,readIndex),false);
- ASTNode newRead = CreateTerm(READ,width,writeA,readIndex);
- ASTNode newRead_memoized = newRead;
- if(CheckSimplifyMap(newRead, newRead_memoized,false)) {
- newRead = newRead_memoized;
- }
-
- if(ASTTrue == cond && (term == partialITE)) {
- //found the write-value in the first iteration itself. return
- //it
- output = writeVal;
- UpdateSimplifyMap(term,output,false);
- return output;
- }
-
- if(READ == partialITE.GetKind() && WRITE == partialITE[0].GetKind()) {
- //first iteration or (previous cond==ASTFALSE and partialITE is a "READ over WRITE")
- partialITE = CreateSimplifiedTermITE(cond, writeVal, newRead);
- }
- else if (ITE == partialITE.GetKind()){
- //ITE(i1 = j, v1, R(A,j))
- ASTNode ElseITE = CreateSimplifiedTermITE(cond, writeVal, newRead);
- //R(W(A,i1,v1),j) <==> ITE(i1 = j, v1, R(A,j))
- UpdateSimplifyMap(oldRead,ElseITE,false);
- //ITE(i2 = j, v2, R(W(A,i1,v1),j)) <==> ITE(i2 = j, v2, ITE(i1 = j, v1, R(A,j)))
- partialITE = SimplifyTerm(partialITE);
- }
- else {
- FatalError("RemoveWrites: Control should not reach here\n");
- }
-
- if(ASTTrue == cond) {
- //no more iterations required
- output = partialITE;
- UpdateSimplifyMap(term,output,false);
- return output;
- }
-
- input = newRead;
- oldRead = newRead;
- } while(READ == input.GetKind() && WRITE == input[0].GetKind());
-
- output = partialITE;
-
- //memoize
- //UpdateSimplifyMap(term,output,false);
- return output;
- } //ReadOverWrite_To_ITE()
-
- //compute the multiplicative inverse of the input
- ASTNode BeevMgr::MultiplicativeInverse(const ASTNode& d) {
- ASTNode c = d;
- if(BVCONST != c.GetKind()) {
- FatalError("Input must be a constant", c);
- }
-
- if(!BVConstIsOdd(c)) {
- FatalError("MultiplicativeInverse: Input must be odd: ",c);
- }
-
- //cerr << "input to multinverse function is: " << d << endl;
- ASTNode inverse;
- if(CheckMultInverseMap(d,inverse)) {
- //cerr << "found the inverse of: " << d << "and it is: " << inverse << endl;
- return inverse;
- }
-
- inverse = c;
- unsigned inputwidth = c.GetValueWidth();
-
-#ifdef NATIVE_C_ARITH
- ASTNode one = CreateOneConst(inputwidth);
- while(c != one) {
- //c = c*c
- c = BVConstEvaluator(CreateTerm(BVMULT,inputwidth,c,c));
- //inverse = invsere*c
- inverse = BVConstEvaluator(CreateTerm(BVMULT,inputwidth,inverse,c));
- }
-#else
- //Compute the multiplicative inverse of c using the extended
- //euclidian algorithm
- //
- //create a '0' which is 1 bit long
- ASTNode onebit_zero = CreateZeroConst(1);
- //zero pad t0, i.e. 0 @ t0
- c = BVConstEvaluator(CreateTerm(BVCONCAT,inputwidth+1,onebit_zero,c));
-
- //construct 2^(inputwidth), i.e. a bitvector of length
- //'inputwidth+1', which is max(inputwidth)+1
- //
- //all 1's
- ASTNode max = CreateMaxConst(inputwidth);
- //zero pad max
- max = BVConstEvaluator(CreateTerm(BVCONCAT,inputwidth+1,onebit_zero,max));
- //Create a '1' which has leading zeros of length 'inputwidth'
- ASTNode inputwidthplusone_one = CreateOneConst(inputwidth+1);
- //add 1 to max
- max = CreateTerm(BVPLUS,inputwidth+1,max,inputwidthplusone_one);
- max = BVConstEvaluator(max);
-
- ASTNode zero = CreateZeroConst(inputwidth+1);
- ASTNode max_bvgt_0 = CreateNode(BVGT,max,zero);
- ASTNode quotient, remainder;
- ASTNode x, x1, x2;
-
- //x1 initialized to zero
- x1 = zero;
- //x2 initialized to one
- x2 = CreateOneConst(inputwidth+1);
- while (ASTTrue == BVConstEvaluator(max_bvgt_0)) {
- //quotient = (c divided by max)
- quotient = BVConstEvaluator(CreateTerm(BVDIV,inputwidth+1, c, max));
-
- //remainder of (c divided by max)
- remainder = BVConstEvaluator(CreateTerm(BVMOD,inputwidth+1, c, max));
-
- //x = x2 - q*x1
- x = CreateTerm(BVSUB,inputwidth+1,x2,CreateTerm(BVMULT,inputwidth+1,quotient,x1));
- x = BVConstEvaluator(x);
-
- //fix the inputs to the extended euclidian algo
- c = max;
- max = remainder;
- max_bvgt_0 = CreateNode(BVGT,max,zero);
-
- x2 = x1;
- x1 = x;
- }
-
- ASTNode hi = CreateBVConst(32,inputwidth-1);
- ASTNode low = CreateZeroConst(32);
- inverse = CreateTerm(BVEXTRACT,inputwidth,x2,hi,low);
- inverse = BVConstEvaluator(inverse);
-#endif
-
- UpdateMultInverseMap(d,inverse);
- //cerr << "output of multinverse function is: " << inverse << endl;
- return inverse;
- } //end of MultiplicativeInverse()
-
- //returns true if the input is odd
- bool BeevMgr::BVConstIsOdd(const ASTNode& c) {
- if(BVCONST != c.GetKind()) {
- FatalError("Input must be a constant", c);
- }
-
- ASTNode zero = CreateZeroConst(1);
- ASTNode hi = CreateZeroConst(32);
- ASTNode low = hi;
- ASTNode lowestbit = CreateTerm(BVEXTRACT,1,c,hi,low);
- lowestbit = BVConstEvaluator(lowestbit);
-
- if(lowestbit == zero) {
- return false;
- }
- else {
- return true;
- }
- } //end of BVConstIsOdd()
-
- //The big substitution function
- ASTNode BeevMgr::CreateSubstitutionMap(const ASTNode& a){
- if(!optimize)
- return a;
-
- ASTNode output = a;
- //if the variable has been solved for, then simply return it
- if(CheckSolverMap(a,output))
- return output;
-
- //traverse a and populate the SubstitutionMap
- Kind k = a.GetKind();
- if(SYMBOL == k && BOOLEAN_TYPE == a.GetType()) {
- bool updated = UpdateSubstitutionMap(a,ASTTrue);
- output = updated ? ASTTrue : a;
- return output;
- }
- if(NOT == k
- && SYMBOL == a[0].GetKind()) {
- bool updated = UpdateSubstitutionMap(a[0],ASTFalse);
- output = updated ? ASTTrue : a;
- return output;
- }
-
- if(IFF == k) {
- ASTVec c = a.GetChildren();
- SortByExprNum(c);
- if(SYMBOL != c[0].GetKind() ||
- VarSeenInTerm(c[0],SimplifyFormula_NoRemoveWrites(c[1],false))) {
- return a;
- }
- bool updated = UpdateSubstitutionMap(c[0],c[1]);
- 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();
- SortByExprNum(c);
- FillUp_ArrReadIndex_Vec(c[0],c[1]);
-
- if(SYMBOL == c[0].GetKind() &&
- VarSeenInTerm(c[0],SimplifyTerm(c[1]))) {
- return a;
- }
-
- if(1 == TermOrder(c[0],c[1]) &&
- READ == c[0].GetKind() &&
- VarSeenInTerm(c[0][0],SimplifyTerm(c[1]))) {
- return a;
- }
- bool updated = UpdateSubstitutionMap(c[0],c[1]);
- output = updated ? ASTTrue : a;
- return output;
- }
-
- if(AND == k){
- ASTVec o;
- ASTVec c = a.GetChildren();
- for(ASTVec::iterator it = c.begin(),itend=c.end();it!=itend;it++) {
- UpdateAlwaysTrueFormMap(*it);
- ASTNode aaa = CreateSubstitutionMap(*it);
-
- if(ASTTrue != aaa) {
- if(ASTFalse == aaa)
- return ASTFalse;
- else
- o.push_back(aaa);
- }
- }
- if(o.size() == 0)
- return ASTTrue;
-
- if(o.size() == 1)
- return o[0];
-
- return CreateNode(AND,o);
- }
- 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;
- }
-} //end of namespace