From 060db05a4330bdaeaa37cd535dddc333c69339fe Mon Sep 17 00:00:00 2001 From: vijay_ganesh Date: Sun, 11 Oct 2009 00:07:43 +0000 Subject: [PATCH] big reorganization almost complete. I believe there is a slight slowdown. git-svn-id: https://stp-fast-prover.svn.sourceforge.net/svnroot/stp-fast-prover/trunk/stp@284 e59a4935-1847-0410-ae03-e826735625c1 --- Makefile | 23 +- scripts/Makefile.in | 23 +- src/AST/AST.h | 30 +- src/AST/ASTBVConst.cpp | 8 +- src/AST/ASTBVConst.h | 8 +- src/AST/ASTInterior.cpp | 4 +- src/AST/ASTInternal.h | 25 + src/AST/ASTNode.cpp | 9 +- src/AST/ASTNode.h | 1 + src/AST/ASTSymbol.cpp | 35 +- src/AST/ASTSymbol.h | 31 +- src/AST/ASTmisc.cpp | 372 +++++++ .../{Transform.cpp => ArrayTransformer.cpp} | 276 +++-- src/AST/ArrayTransformer.h | 180 ++++ src/AST/Makefile | 2 +- src/AST/RunTimes.h | 90 +- src/AST/TopLevel.h | 34 +- src/{const-evaluator => STPManager}/Makefile | 9 +- src/STPManager/STP.cpp | 181 ++++ src/STPManager/STP.h | 66 ++ src/STPManager/STPManager.cpp | 715 +++++-------- src/STPManager/STPManager.h | 379 +++++++ .../AbsRefine_CounterExample.h | 213 ++++ .../AbstractionRefinement.cpp | 649 ++++++++++++ .../CounterExample.cpp | 968 +++++++++++++++++ .../Makefile | 1 + .../AbstractionRefinement.cpp | 635 ----------- src/c_interface/Makefile | 1 + src/c_interface/c_interface.cpp | 473 +++++---- src/counterexample/Makefile | 17 + src/main/Globals.cpp | 11 +- src/main/Globals.h | 18 +- src/main/Makefile | 9 +- src/main/main.cpp | 47 +- src/parser/CVC.lex | 18 +- src/parser/CVC.y | 324 +++--- src/parser/Makefile | 4 +- src/parser/let-funcs.h | 50 + src/parser/parser.h | 2 +- src/parser/smtlib.lex | 12 +- src/parser/smtlib.y | 257 ++--- src/printer/AssortedPrinters.cpp | 335 +----- src/printer/Makefile | 21 + src/printer/PLPrinter.cpp | 12 +- src/printer/SMTLIBPrinter.cpp | 3 +- src/printer/printers.h | 23 +- src/sat/core/Solver.h | 8 +- src/sat/core/depend.mk | 8 + src/sat/sat.h | 7 +- src/sat/simp/SimpSolver.h | 4 +- src/sat/simp/depend.mk | 20 +- src/sat/unsound/UnsoundSimpSolver.h | 4 +- src/sat/unsound/depend.mk | 16 + src/simplifier/bvsolver.cpp | 213 ++-- src/simplifier/bvsolver.h | 76 +- .../consteval.cpp | 71 +- src/simplifier/simplifier.cpp | 860 ++++++--------- src/simplifier/simplifier.h | 247 +++++ src/to-sat/CallSAT.cpp | 91 ++ src/to-sat/ToCNF.cpp | 4 +- src/to-sat/ToCNF.h | 1 - src/to-sat/ToSAT.cpp | 996 +----------------- src/to-sat/ToSAT.h | 123 +++ 63 files changed, 5509 insertions(+), 3844 deletions(-) create mode 100644 src/AST/ASTmisc.cpp rename src/AST/{Transform.cpp => ArrayTransformer.cpp} (72%) create mode 100644 src/AST/ArrayTransformer.h rename src/{const-evaluator => STPManager}/Makefile (59%) create mode 100644 src/STPManager/STP.cpp create mode 100644 src/STPManager/STP.h create mode 100644 src/STPManager/STPManager.h create mode 100644 src/absrefine_counterexample/AbsRefine_CounterExample.h create mode 100644 src/absrefine_counterexample/AbstractionRefinement.cpp create mode 100644 src/absrefine_counterexample/CounterExample.cpp rename src/{abstraction-refinement => absrefine_counterexample}/Makefile (85%) delete mode 100644 src/abstraction-refinement/AbstractionRefinement.cpp create mode 100644 src/counterexample/Makefile create mode 100644 src/parser/let-funcs.h create mode 100644 src/printer/Makefile create mode 100644 src/sat/core/depend.mk create mode 100644 src/sat/unsound/depend.mk rename src/{const-evaluator => simplifier}/consteval.cpp (88%) create mode 100644 src/simplifier/simplifier.h create mode 100644 src/to-sat/CallSAT.cpp create mode 100644 src/to-sat/ToSAT.h diff --git a/Makefile b/Makefile index c457f19..a4b8f8d 100644 --- a/Makefile +++ b/Makefile @@ -20,20 +20,20 @@ all: $(MAKE) -C $(SRC)/AST $(MAKE) -C $(SRC)/STPManager $(MAKE) -C $(SRC)/printer - $(MAKE) -C $(SRC)/abstraction-refinement + $(MAKE) -C $(SRC)/extlib-constbv + $(MAKE) -C $(SRC)/simplifier + $(MAKE) -C $(SRC)/absrefine_counterexample $(MAKE) -C $(SRC)/to-sat $(MAKE) -C $(SRC)/sat core # $(MAKE) -C $(SRC)/sat simp # $(MAKE) -C $(SRC)/sat unsound - $(MAKE) -C $(SRC)/simplifier - $(MAKE) -C $(SRC)/const-evaluator $(MAKE) -C $(SRC)/c_interface - $(MAKE) -C $(SRC)/extlib-constbv $(MAKE) -C $(SRC)/parser $(MAKE) -C $(SRC)/main - $(AR) rc libstp.a $(SRC)/AST/*.o $(SRC)/STPManager/*.o $(SRC)/printer/*.o $(SRC)/abstraction-refinement/*.o $(SRC)/to-sat/*.o \ - $(SRC)/sat/*.or $(SRC)/simplifier/*.o $(SRC)/const-evaluator/*.o $(SRC)/extlib-constbv/*.o $(SRC)/c_interface/*.o \ - $(SRC)/parser/let-funcs.o $(SRC)/parser/parseCVC.o $(SRC)/parser/lexCVC.o $(SRC)/main/*.o + $(AR) rc libstp.a $(SRC)/AST/*.o $(SRC)/STPManager/*.o $(SRC)/printer/*.o $(SRC)/absrefine_counterexample/*.o \ + $(SRC)/to-sat/*.o $(SRC)/sat/*.or $(SRC)/simplifier/*.o \ + $(SRC)/extlib-constbv/*.o $(SRC)/c_interface/*.o $(SRC)/parser/let-funcs.o \ + $(SRC)/parser/parseCVC.o $(SRC)/parser/lexCVC.o $(SRC)/main/*.o $(RANLIB) libstp.a @mkdir -p lib @mv libstp.a lib/ @@ -62,13 +62,12 @@ clean: $(MAKE) clean -C $(SRC)/AST $(MAKE) clean -C $(SRC)/STPManager $(MAKE) clean -C $(SRC)/printer - $(MAKE) clean -C $(SRC)/abstraction-refinement + $(MAKE) clean -C $(SRC)/extlib-constbv + $(MAKE) clean -C $(SRC)/simplifier + $(MAKE) clean -C $(SRC)/absrefine_counterexample $(MAKE) clean -C $(SRC)/to-sat $(MAKE) clean -C $(SRC)/sat - $(MAKE) clean -C $(SRC)/simplifier - $(MAKE) clean -C $(SRC)/const-evaluator - $(MAKE) clean -C $(SRC)/c_interface - $(MAKE) clean -C $(SRC)/extlib-constbv + $(MAKE) clean -C $(SRC)/c_interface $(MAKE) clean -C $(SRC)/parser $(MAKE) clean -C $(SRC)/main $(MAKE) clean -C tests/c-api-tests diff --git a/scripts/Makefile.in b/scripts/Makefile.in index c457f19..a4b8f8d 100644 --- a/scripts/Makefile.in +++ b/scripts/Makefile.in @@ -20,20 +20,20 @@ all: $(MAKE) -C $(SRC)/AST $(MAKE) -C $(SRC)/STPManager $(MAKE) -C $(SRC)/printer - $(MAKE) -C $(SRC)/abstraction-refinement + $(MAKE) -C $(SRC)/extlib-constbv + $(MAKE) -C $(SRC)/simplifier + $(MAKE) -C $(SRC)/absrefine_counterexample $(MAKE) -C $(SRC)/to-sat $(MAKE) -C $(SRC)/sat core # $(MAKE) -C $(SRC)/sat simp # $(MAKE) -C $(SRC)/sat unsound - $(MAKE) -C $(SRC)/simplifier - $(MAKE) -C $(SRC)/const-evaluator $(MAKE) -C $(SRC)/c_interface - $(MAKE) -C $(SRC)/extlib-constbv $(MAKE) -C $(SRC)/parser $(MAKE) -C $(SRC)/main - $(AR) rc libstp.a $(SRC)/AST/*.o $(SRC)/STPManager/*.o $(SRC)/printer/*.o $(SRC)/abstraction-refinement/*.o $(SRC)/to-sat/*.o \ - $(SRC)/sat/*.or $(SRC)/simplifier/*.o $(SRC)/const-evaluator/*.o $(SRC)/extlib-constbv/*.o $(SRC)/c_interface/*.o \ - $(SRC)/parser/let-funcs.o $(SRC)/parser/parseCVC.o $(SRC)/parser/lexCVC.o $(SRC)/main/*.o + $(AR) rc libstp.a $(SRC)/AST/*.o $(SRC)/STPManager/*.o $(SRC)/printer/*.o $(SRC)/absrefine_counterexample/*.o \ + $(SRC)/to-sat/*.o $(SRC)/sat/*.or $(SRC)/simplifier/*.o \ + $(SRC)/extlib-constbv/*.o $(SRC)/c_interface/*.o $(SRC)/parser/let-funcs.o \ + $(SRC)/parser/parseCVC.o $(SRC)/parser/lexCVC.o $(SRC)/main/*.o $(RANLIB) libstp.a @mkdir -p lib @mv libstp.a lib/ @@ -62,13 +62,12 @@ clean: $(MAKE) clean -C $(SRC)/AST $(MAKE) clean -C $(SRC)/STPManager $(MAKE) clean -C $(SRC)/printer - $(MAKE) clean -C $(SRC)/abstraction-refinement + $(MAKE) clean -C $(SRC)/extlib-constbv + $(MAKE) clean -C $(SRC)/simplifier + $(MAKE) clean -C $(SRC)/absrefine_counterexample $(MAKE) clean -C $(SRC)/to-sat $(MAKE) clean -C $(SRC)/sat - $(MAKE) clean -C $(SRC)/simplifier - $(MAKE) clean -C $(SRC)/const-evaluator - $(MAKE) clean -C $(SRC)/c_interface - $(MAKE) clean -C $(SRC)/extlib-constbv + $(MAKE) clean -C $(SRC)/c_interface $(MAKE) clean -C $(SRC)/parser $(MAKE) clean -C $(SRC)/main $(MAKE) clean -C tests/c-api-tests diff --git a/src/AST/AST.h b/src/AST/AST.h index 7d1bc43..a8070dc 100644 --- a/src/AST/AST.h +++ b/src/AST/AST.h @@ -10,9 +10,9 @@ #ifndef AST_H #define AST_H #include "TopLevel.h" +#include "ASTNode.h" #include "ASTInternal.h" #include "ASTInterior.h" -#include "ASTNode.h" #include "ASTSymbol.h" #include "ASTBVConst.h" @@ -26,6 +26,26 @@ namespace BEEV bool arithless(const ASTNode n1, const ASTNode n2); bool isAtomic(Kind k); + // 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); + + + //FUNCTION TypeCheck: Assumes that the immediate Children of the + //input ASTNode have been typechecked. This function is suitable + //in scenarios like where you are building the ASTNode Tree, and + //you typecheck as you go along. It is not suitable as a general + //typechecker + + // NB: The boolean value is always true! + bool BVTypeCheck(const ASTNode& n); + + // Checks recursively all the way down. + bool BVTypeCheckRecursive(const ASTNode& n); + + //Takes a BVCONST and returns its constant value + unsigned int GetUnsignedConst(const ASTNode n); + typedef hash_map< ASTNode, ASTNode, @@ -47,7 +67,13 @@ namespace BEEV ASTNode, ASTNode::ASTNodeHasher, ASTNode::ASTNodeEqual> ASTNodeMultiSet; - + + typedef hash_map< + ASTNode, + ASTVec, + ASTNode::ASTNodeHasher, + ASTNode::ASTNodeEqual> ASTNodeToVecMap; + // Datatype for clauses typedef vector* ClausePtr; diff --git a/src/AST/ASTBVConst.cpp b/src/AST/ASTBVConst.cpp index 57968c0..31296f0 100644 --- a/src/AST/ASTBVConst.cpp +++ b/src/AST/ASTBVConst.cpp @@ -8,7 +8,7 @@ ********************************************************************/ #include "AST.h" -#include "../STPManager/STPManager.h" +#include "../STPManager/STP.h" namespace BEEV { /**************************************************************** @@ -35,7 +35,7 @@ namespace BEEV // unique table void ASTBVConst::CleanUp() { - GlobalBeevMgr->_bvconst_unique_table.erase(this); + (GlobalSTP->bm)->_bvconst_unique_table.erase(this); delete this; } //End of Cleanup() @@ -108,14 +108,14 @@ namespace BEEV bool ASTBVConst::ASTBVConstEqual::operator()(const ASTBVConst * bvc1, - const ASTBVConst * bvc2) const + const ASTBVConst * bvc2) const { if (bvc1->_value_width != bvc2->_value_width) { return false; } return (0 == - CONSTANTBV::BitVector_Compare(bvc1->_bvconst, + CONSTANTBV::BitVector_Compare(bvc1->_bvconst, bvc2->_bvconst)); } //End of ASTBVConstEqual operator };//End of namespace diff --git a/src/AST/ASTBVConst.h b/src/AST/ASTBVConst.h index 88cd6c7..f93c565 100644 --- a/src/AST/ASTBVConst.h +++ b/src/AST/ASTBVConst.h @@ -34,7 +34,7 @@ namespace BEEV //CBV is actually an unsigned*. The bitvector constant is //represented using an external library in extlib-bvconst. CBV _bvconst; - + /**************************************************************** * Class ASTBVConstHasher: * * * @@ -45,7 +45,7 @@ namespace BEEV public: size_t operator()(const ASTBVConst * bvc) const; }; //End of class ASTBVConstHahser - + /**************************************************************** * Class ASTBVConstEqual: * * * @@ -57,7 +57,7 @@ namespace BEEV bool operator()(const ASTBVConst * bvc1, const ASTBVConst * bvc2) const; }; //End of class ASTBVConstEqual - + /**************************************************************** * Private Functions (virtual defs and friends) * ****************************************************************/ @@ -99,6 +99,6 @@ namespace BEEV // Return the bvconst. It is a const-value CBV GetBVConst() const; - }; //End of ASTBVConst + }; //End of ASTBVConst };//end of namespace #endif diff --git a/src/AST/ASTInterior.cpp b/src/AST/ASTInterior.cpp index f40a394..0302786 100644 --- a/src/AST/ASTInterior.cpp +++ b/src/AST/ASTInterior.cpp @@ -8,7 +8,7 @@ ********************************************************************/ #include "AST.h" -#include "../STPManager/STPManager.h" +#include "../STPManager/STP.h" namespace BEEV { /****************************************************************** @@ -19,7 +19,7 @@ namespace BEEV // the unique table void ASTInterior::CleanUp() { - GlobalBeevMgr->_interior_unique_table.erase(this); + (GlobalSTP->bm)->_interior_unique_table.erase(this); delete this; } //End of Cleanup() diff --git a/src/AST/ASTInternal.h b/src/AST/ASTInternal.h index 0547384..4cc565c 100644 --- a/src/AST/ASTInternal.h +++ b/src/AST/ASTInternal.h @@ -14,6 +14,31 @@ ********************************************************************/ namespace BEEV { + /****************************************************************** + * struct enumeration: * + * * + * Templated class that allows you to define the number of bytes * + * (using class T below) for the enumerated type class E. * + ******************************************************************/ + template + struct enumeration + { + typedef T type; + typedef E enum_type; + + enumeration() : e_(E()) + {} + + enumeration(E e) : e_(static_cast(e)) + {} + + operator E() const + { return static_cast(e_); } + + private: + T e_; + }; //end of Enumeration struct + /****************************************************************** * Class ASTInternal: * * * diff --git a/src/AST/ASTNode.cpp b/src/AST/ASTNode.cpp index b91329f..3f47d50 100644 --- a/src/AST/ASTNode.cpp +++ b/src/AST/ASTNode.cpp @@ -8,7 +8,8 @@ ********************************************************************/ #include "AST.h" -#include "../STPManager/STPManager.h" +#include "../STPManager/STP.h" + /******************************************************************** * This file gives the class definitions of the ASTNode class * ********************************************************************/ @@ -21,7 +22,9 @@ namespace BEEV _int_node_ptr(in) { if (in) - in->IncRef(); + { + in->IncRef(); + } } //End of Constructor // Copy constructor. Maintain _ref_count @@ -113,7 +116,7 @@ namespace BEEV BeevMgr* ASTNode::GetBeevMgr() const { - return GlobalBeevMgr; + return GlobalSTP->bm; } //End of GetBeevMgr() // Checks if the node has alreadybeen printed or not diff --git a/src/AST/ASTNode.h b/src/AST/ASTNode.h index 3f7b8a1..e41f0f4 100644 --- a/src/AST/ASTNode.h +++ b/src/AST/ASTNode.h @@ -288,6 +288,7 @@ namespace BEEV return (n1._int_node_ptr == n2._int_node_ptr); } }; //End of ASTNodeEqual + }; //End of Class ASTNode }; //end of namespace #endif diff --git a/src/AST/ASTSymbol.cpp b/src/AST/ASTSymbol.cpp index b8635aa..c6540f4 100644 --- a/src/AST/ASTSymbol.cpp +++ b/src/AST/ASTSymbol.cpp @@ -8,7 +8,7 @@ ********************************************************************/ #include "AST.h" -#include "../STPManager/STPManager.h" +#include "../STPManager/STP.h" namespace BEEV { /**************************************************************** @@ -32,30 +32,23 @@ namespace BEEV // unique table void ASTSymbol::CleanUp() { - GlobalBeevMgr->_symbol_unique_table.erase(this); + (GlobalSTP->bm)->_symbol_unique_table.erase(this); free((char*) this->_name); delete this; }//End of cleanup() - - /**************************************************************** - * ASTSymbolHasher and ASTSymbolEqual functions * - * * - ****************************************************************/ - size_t - ASTSymbol::ASTSymbolHasher::operator()(const ASTSymbol *sym_ptr) const + unsigned long hash(unsigned char *str) { -#ifdef TR1_UNORDERED_MAP - tr1::hash h; -#else - hash h; -#endif - return h(sym_ptr->_name); - } //End of ASTSymbolHasher operator + unsigned long hash = 5381; + int c; + + while (c = *str++) + hash = ((hash << 5) + hash) + c; /* hash * 33 + c */ + + //cout << "Hash value computed is: " << hash << endl; + + return hash; + } + - bool ASTSymbol::ASTSymbolEqual::operator()(const ASTSymbol *sym_ptr1, - const ASTSymbol *sym_ptr2) const - { - return (*sym_ptr1 == *sym_ptr2); - } //End of ASTSymbolEqual operator };//end of namespace diff --git a/src/AST/ASTSymbol.h b/src/AST/ASTSymbol.h index 06ec3dd..6bc8a5d 100644 --- a/src/AST/ASTSymbol.h +++ b/src/AST/ASTSymbol.h @@ -9,8 +9,11 @@ #ifndef ASTSYMBOL_H #define ASTSYMBOL_H + namespace BEEV { + unsigned long hash(unsigned char *str); + /****************************************************************** * Class ASTSymbol: * * * @@ -39,7 +42,18 @@ namespace BEEV class ASTSymbolHasher { public: - size_t operator()(const ASTSymbol *sym_ptr) const; + size_t operator()(const ASTSymbol *sym_ptr) const + { +#ifdef TR1_UNORDERED_MAP + tr1::hash h; +#else + //hash h; +#endif + //return h(sym_ptr->_name); + //cerr << "ASTSymbol hasher recieved name: " + //<< sym_ptr->_name << endl; + return (size_t)hash((unsigned char*)(sym_ptr->_name)); + }; }; // End of class ASTSymbolHasher /**************************************************************** @@ -51,9 +65,13 @@ namespace BEEV { public: bool operator()(const ASTSymbol *sym_ptr1, - const ASTSymbol *sym_ptr2) const; - }; //End of class ASTSymbolEqual - + const ASTSymbol *sym_ptr2) const + { + return (*sym_ptr1 == *sym_ptr2); + } + }; // End of class ASTSymbolEqual + + // comparator friend bool operator==(const ASTSymbol &sym1, const ASTSymbol &sym2) { @@ -82,7 +100,8 @@ namespace BEEV ****************************************************************/ // Default constructor - ASTSymbol() : ASTInternal(), _name(NULL) + ASTSymbol() : + ASTInternal(), _name(NULL) { } @@ -90,6 +109,7 @@ namespace BEEV ASTSymbol(const char * const name) : ASTInternal(SYMBOL), _name(name) { + //printf("inside ASTSymbol constructor %s\n", _name); } // Destructor (does nothing, but is declared virtual here. @@ -101,6 +121,7 @@ namespace BEEV ASTSymbol(const ASTSymbol &sym) : ASTInternal(sym._kind, sym._children), _name(sym._name) { + //printf("inside ASTSymbol constructor %s\n", _name); } }; //End of ASTSymbol }; //end of namespace diff --git a/src/AST/ASTmisc.cpp b/src/AST/ASTmisc.cpp new file mode 100644 index 0000000..d8e1343 --- /dev/null +++ b/src/AST/ASTmisc.cpp @@ -0,0 +1,372 @@ +// -*- c++ -*- +/******************************************************************** + * AUTHORS: Vijay Ganesh + * + * BEGIN DATE: November, 2005 + * + * LICENSE: Please view LICENSE file in the home dir of this Program + ********************************************************************/ + +#include "AST.h" + +namespace BEEV +{ + + /**************************************************************** + * Universal Helper Functions * + ****************************************************************/ + + 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); + } + + void SortByExprNum(ASTVec& v) + { + sort(v.begin(), v.end(), exprless); + } + + void SortByArith(ASTVec& v) + { + sort(v.begin(), v.end(), arithless); + } + + bool isAtomic(Kind kind) + { + if (TRUE == kind || FALSE == kind || + EQ == kind || + BVLT == kind || BVLE == kind || + BVGT == kind || BVGE == kind || + BVSLT == kind || BVSLE == kind || + BVSGT == kind || BVSGE == kind || + SYMBOL == kind || BVGETBIT == kind) + return true; + return false; + } + + + // If there is a lot of sharing in the graph, this will take a long + // time. it doesn't mark subgraphs as already having been + // typechecked. + bool BVTypeCheckRecursive(const ASTNode& n) + { + const ASTVec& c = n.GetChildren(); + + BVTypeCheck(n); + + for (ASTVec::const_iterator it = c.begin(), itend = c.end(); it != itend; it++) + BVTypeCheckRecursive(*it); + + return true; + } + + + + /* FUNCTION: Typechecker for terms and formulas + * + * TypeChecker: Assumes that the immediate Children of the input + * ASTNode have been typechecked. This function is suitable in + * scenarios like where you are building the ASTNode Tree, and you + * typecheck as you go along. It is not suitable as a general + * typechecker. + * + * If this returns, this ALWAYS returns true. If there is an error it + * will call FatalError() and abort. + */ + bool BVTypeCheck(const ASTNode& n) + { + Kind k = n.GetKind(); + //The children of bitvector terms are in turn bitvectors. + const ASTVec& v = n.GetChildren(); + if (is_Term_kind(k)) + { + switch (k) + { + case BVCONST: + if (BITVECTOR_TYPE != n.GetType()) + FatalError("BVTypeCheck: The term t does not typecheck, where t = \n", n); + break; + case SYMBOL: + return true; + case ITE: + if (BOOLEAN_TYPE != n[0].GetType() || (n[1].GetType() != n[2].GetType())) + FatalError("BVTypeCheck: The term t does not typecheck, where t = \n", n); + if (n[1].GetValueWidth() != n[2].GetValueWidth()) + FatalError("BVTypeCheck: length of THENbranch != length of ELSEbranch in the term t = \n", n); + if (n[1].GetIndexWidth() != n[2].GetIndexWidth()) + FatalError("BVTypeCheck: length of THENbranch != length of ELSEbranch in the term t = \n", n); + break; + case READ: + if (n.GetChildren().size() !=2) + FatalError("2 params to read."); + if (n[0].GetIndexWidth() != n[1].GetValueWidth()) + { + cerr << "Length of indexwidth of array: " << n[0] << " is : " << n[0].GetIndexWidth() << endl; + cerr << "Length of the actual index is: " << n[1] << " is : " << n[1].GetValueWidth() << endl; + FatalError("BVTypeCheck: length of indexwidth of array != length of actual index in the term t = \n", n); + } + if (ARRAY_TYPE != n[0].GetType()) + FatalError("First parameter to read should be an array", n[0]); + if (BITVECTOR_TYPE != n[1].GetType()) + FatalError("Second parameter to read should be a bitvector", n[1]); + break; + case WRITE: + if (n.GetChildren().size() !=3) + FatalError("3 params to write."); + if (n[0].GetIndexWidth() != n[1].GetValueWidth()) + FatalError("BVTypeCheck: length of indexwidth of array != length of actual index in the term t = \n", n); + if (n[0].GetValueWidth() != n[2].GetValueWidth()) + FatalError("BVTypeCheck: valuewidth of array != length of actual value in the term t = \n", n); + if (ARRAY_TYPE != n[0].GetType()) + FatalError("First parameter to read should be an array", n[0]); + if (BITVECTOR_TYPE != n[1].GetType()) + FatalError("Second parameter to read should be a bitvector", n[1]); + if (BITVECTOR_TYPE != n[2].GetType()) + FatalError("Third parameter to read should be a bitvector", n[2]); + + break; + case BVOR: + case BVAND: + case BVXOR: + case BVNOR: + case BVNAND: + case BVXNOR: + case BVPLUS: + case BVMULT: + case BVDIV: + case BVMOD: + case BVSUB: + { + if (!(v.size() >= 2)) + FatalError("BVTypeCheck:bitwise Booleans and BV arith operators must have atleast two arguments\n", n); + unsigned int width = n.GetValueWidth(); + for (ASTVec::const_iterator it = v.begin(), itend = v.end(); it != itend; it++) + { + if (width != it->GetValueWidth()) + { + cerr << "BVTypeCheck:Operands of bitwise-Booleans and BV arith operators must be of equal length\n"; + cerr << n << endl; + cerr << "width of term:" << width << endl; + cerr << "width of offending operand:" << it->GetValueWidth() << endl; + FatalError("BVTypeCheck:Offending operand:\n", *it); + } + if (BITVECTOR_TYPE != it->GetType()) + FatalError("BVTypeCheck: ChildNodes of bitvector-terms must be bitvectors\n", n); + } + break; + } + case BVSX: + //in BVSX(n[0],len), the length of the BVSX term must be + //greater than the length of n[0] + if (n[0].GetValueWidth() > n.GetValueWidth()) + { + FatalError("BVTypeCheck: BVSX(t,bvsx_len) : length of 't' must be <= bvsx_len\n", n); + } + if ((v.size() != 2)) + FatalError("BVTypeCheck:BVSX must have two arguments. The second is the new width\n", n); + break; + + default: + for (ASTVec::const_iterator it = v.begin(), itend = v.end(); it != itend; it++) + if (BITVECTOR_TYPE != it->GetType()) + { + cerr << "The type is: " << it->GetType() << endl; + FatalError("BVTypeCheck:ChildNodes of bitvector-terms must be bitvectors\n", n); + } + break; + } + + switch (k) + { + case BVCONCAT: + if (n.Degree() != 2) + FatalError("BVTypeCheck: should have exactly 2 args\n", n); + if (n.GetValueWidth() != n[0].GetValueWidth() + n[1].GetValueWidth()) + FatalError("BVTypeCheck:BVCONCAT: lengths do not add up\n", n); + break; + case BVUMINUS: + case BVNEG: + if (n.Degree() != 1) + FatalError("BVTypeCheck: should have exactly 1 args\n", n); + break; + case BVEXTRACT: + if (n.Degree() != 3) + FatalError("BVTypeCheck: should have exactly 3 args\n", n); + if (!(BVCONST == n[1].GetKind() && BVCONST == n[2].GetKind())) + FatalError("BVTypeCheck: indices should be BVCONST\n", n); + if (n.GetValueWidth() != GetUnsignedConst(n[1]) - GetUnsignedConst(n[2]) + 1) + FatalError("BVTypeCheck: length mismatch\n", n); + if (GetUnsignedConst(n[1]) >= n[0].GetValueWidth()) + FatalError("BVTypeCheck: Top index of select is greater or equal to the bitwidth.\n", n); + break; + case BVLEFTSHIFT: + case BVRIGHTSHIFT: + if (n.Degree() != 2) + FatalError("BVTypeCheck: should have exactly 2 args\n", n); + break; + //case BVVARSHIFT: + //case BVSRSHIFT: + //break; + default: + break; + } + } + else + { + if (!(is_Form_kind(k) && BOOLEAN_TYPE == n.GetType())) + FatalError("BVTypeCheck: not a formula:", n); + switch (k) + { + case TRUE: + case FALSE: + case SYMBOL: + return true; + case PARAMBOOL: + if(2 != n.Degree()) + FatalError("BVTypeCheck: PARAMBOOL formula can have exactly two childNodes", n); + break; + case EQ: + if (!(n[0].GetValueWidth() == n[1].GetValueWidth() && n[0].GetIndexWidth() == n[1].GetIndexWidth())) + { + cerr << "valuewidth of lhs of EQ: " << n[0].GetValueWidth() << endl; + cerr << "valuewidth of rhs of EQ: " << n[1].GetValueWidth() << endl; + cerr << "indexwidth of lhs of EQ: " << n[0].GetIndexWidth() << endl; + cerr << "indexwidth of rhs of EQ: " << n[1].GetIndexWidth() << endl; + FatalError("BVTypeCheck: terms in atomic formulas must be of equal length", n); + } + break; + case BVLT: + case BVLE: + case BVGT: + case BVGE: + case BVSLT: + case BVSLE: + case BVSGT: + case BVSGE: + if (BITVECTOR_TYPE != n[0].GetType() && BITVECTOR_TYPE != n[1].GetType()) + FatalError("BVTypeCheck: terms in atomic formulas must be bitvectors", n); + if (n[0].GetValueWidth() != n[1].GetValueWidth()) + FatalError("BVTypeCheck: terms in atomic formulas must be of equal length", n); + if (n[0].GetIndexWidth() != n[1].GetIndexWidth()) + FatalError("BVTypeCheck: terms in atomic formulas must be of equal length", n); + break; + case NOT: + if (1 != n.Degree()) + FatalError("BVTypeCheck: NOT formula can have exactly one childNode", n); + break; + case AND: + case OR: + case XOR: + case NAND: + case NOR: + if (2 > n.Degree()) + FatalError("BVTypeCheck: AND/OR/XOR/NAND/NOR: must have atleast 2 ChildNodes", n); + break; + case IFF: + case IMPLIES: + if (2 != n.Degree()) + FatalError("BVTypeCheck:IFF/IMPLIES must have exactly 2 ChildNodes", n); + break; + case ITE: + if (3 != n.Degree()) + FatalError("BVTypeCheck:ITE must have exactly 3 ChildNodes", n); + break; + case FOR: + //FIXME: Todo + break; + default: + + FatalError("BVTypeCheck: Unrecognized kind: "); + break; + } + } + return true; + } //End of TypeCheck function + + //Return the unsigned constant value of the input 'n' + unsigned int GetUnsignedConst(const ASTNode n) + { + if(BVCONST != n.GetKind()){ + FatalError("GetUnsignedConst: cannot extract an "\ + "unsigned value from a non-bvconst"); + } + + if (sizeof(unsigned int) * 8 <= n.GetValueWidth()) + { + // It may only contain a small value in a bit type, + // which fits nicely into an unsigned int. This is + // common for functions like: bvshl(bv1[128], + // bv1[128]) where both operands have the same type. + signed long maxBit = CONSTANTBV::Set_Max(n.GetBVConst()); + if (maxBit >= ((signed long) sizeof(unsigned int)) * 8) + { + n.LispPrint(cerr); //print the node so they can find it. + FatalError("GetUnsignedConst: cannot convert bvconst "\ + "of length greater than 32 to unsigned int"); + } + } + return (unsigned int) *((unsigned int *) n.GetBVConst()); + } //end of GetUnsignedConst + + //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 TermOrder(const ASTNode& a, const ASTNode& b) + { + Kind k1 = a.GetKind(); + Kind k2 = b.GetKind(); + + //a is of the form READ(Arr,const), and b is const, or + //a is of the form var, and b is const + if ((k1 == READ + && a[0].GetKind() == SYMBOL + && a[1].GetKind() == BVCONST + && (k2 == BVCONST))) + // || k2 == READ && b[0].GetKind() == SYMBOL && b[1].GetKind() + // == BVCONST))) + return 1; + + if (SYMBOL == k1 && (BVCONST == k2 || TRUE == k2 || FALSE == k2)) + return 1; + + //b is of the form READ(Arr,const), and a is const, or + //b is of the form var, and a is const + if ((k1 == BVCONST) + && ((k2 == READ + && b[0].GetKind() == SYMBOL + && b[1].GetKind() == BVCONST))) + return -1; + + if (SYMBOL == k2 + && (BVCONST == k1 + || TRUE == k1 + || FALSE == k1)) + return -1; + + return 0; + } //End of TermOrder() + +};//end of namespace diff --git a/src/AST/Transform.cpp b/src/AST/ArrayTransformer.cpp similarity index 72% rename from src/AST/Transform.cpp rename to src/AST/ArrayTransformer.cpp index e55c9f2..e96ab26 100644 --- a/src/AST/Transform.cpp +++ b/src/AST/ArrayTransformer.cpp @@ -7,39 +7,21 @@ * LICENSE: Please view LICENSE file in the home dir of this Program ********************************************************************/ - - /* Transform: * * Converts signed Div/signed remainder/signed modulus into their * unsigned counterparts. Removes array selects and stores from * formula. Arrays are replaced by equivalent bit-vector variables */ -#include -#include -#include -#include -#include -#include "AST.h" -#include "../STPManager/STPManager.h" +#include "ArrayTransformer.h" namespace BEEV { - - ASTNode TransformFormula(const ASTNode& form); - ASTNode TranslateSignedDivModRem(const ASTNode& in); - ASTNode TransformTerm(const ASTNode& inputterm); - void assertTransformPostConditions(const ASTNode & term); - - ASTNodeMap* TransformMap; - - const bool debug_transform = false; - // NB: This is the only function that should be called externally. It sets // up the cache that the others use. - ASTNode BeevMgr::TransformFormula_TopLevel(const ASTNode& form) + ASTNode ArrayTransformer::TransformFormula_TopLevel(const ASTNode& form) { - runTimes.start(RunTimes::Transforming); + runTimes->start(RunTimes::Transforming); assert(TransformMap == NULL); TransformMap = new ASTNodeMap(100); @@ -50,15 +32,14 @@ namespace BEEV delete TransformMap; TransformMap = NULL; - runTimes.stop(RunTimes::Transforming); + runTimes->stop(RunTimes::Transforming); return result; } //Translates signed BVDIV,BVMOD and BVREM into unsigned variety - ASTNode TranslateSignedDivModRem(const ASTNode& in) + ASTNode ArrayTransformer::TranslateSignedDivModRem(const ASTNode& in) { - BeevMgr* bm = GlobalBeevMgr; assert(in.GetChildren().size() ==2); ASTNode dividend = in[0]; @@ -69,17 +50,22 @@ namespace BEEV ASTNode one = bm->CreateOneConst(1); ASTNode zero = bm->CreateZeroConst(1); // create the condition for the dividend - ASTNode cond_dividend = bm->CreateNode(EQ, one, bm->CreateTerm(BVEXTRACT, 1, dividend, hi1, hi1)); + ASTNode cond_dividend = + bm->CreateNode(EQ, one, bm->CreateTerm(BVEXTRACT, 1, dividend, hi1, hi1)); // create the condition for the divisor - ASTNode cond_divisor = bm->CreateNode(EQ, one, bm->CreateTerm(BVEXTRACT, 1, divisor, hi1, hi1)); + ASTNode cond_divisor = + bm->CreateNode(EQ, one, bm->CreateTerm(BVEXTRACT, 1, divisor, hi1, hi1)); if (SBVREM == in.GetKind()) { - //BVMOD is an expensive operation. So have the fewest bvmods possible. Just one. + //BVMOD is an expensive operation. So have the fewest bvmods + //possible. Just one. //Take absolute value. - ASTNode pos_dividend = bm->CreateTerm(ITE, len, cond_dividend, bm->CreateTerm(BVUMINUS, len, dividend), dividend); - ASTNode pos_divisor = bm->CreateTerm(ITE, len, cond_divisor, bm->CreateTerm(BVUMINUS, len, divisor), divisor); + ASTNode pos_dividend = + bm->CreateTerm(ITE, len, cond_dividend, bm->CreateTerm(BVUMINUS, len, dividend), dividend); + ASTNode pos_divisor = + bm->CreateTerm(ITE, len, cond_divisor, bm->CreateTerm(BVUMINUS, len, divisor), divisor); //create the modulus term ASTNode modnode = bm->CreateTerm(BVMOD, len, pos_dividend, pos_divisor); @@ -88,7 +74,7 @@ namespace BEEV ASTNode n = bm->CreateTerm(ITE, len, cond_dividend, bm->CreateTerm(BVUMINUS, len, modnode), modnode); //put everything together, simplify, and return - return bm->SimplifyTerm_TopLevel(n); + return simp->SimplifyTerm_TopLevel(n); } // This is the modulus of dividing rounding to -infinity. @@ -119,7 +105,7 @@ namespace BEEV ASTNode xor_node = bm->CreateNode(XOR, cond_dividend, cond_divisor); ASTNode n = bm->CreateTerm(ITE, len, xor_node, bm->CreateTerm(BVPLUS, len, rev_node, divisor), rev_node); - return bm->SimplifyTerm_TopLevel(n); + return simp->SimplifyTerm_TopLevel(n); } else if (SBVDIV == in.GetKind()) { @@ -148,7 +134,7 @@ namespace BEEV ASTNode xor_node = bm->CreateNode(XOR, cond_dividend, cond_divisor); ASTNode n = bm->CreateTerm(ITE, len, xor_node, bm->CreateTerm(BVUMINUS, len, divnode), divnode); - return bm->SimplifyTerm_TopLevel(n); + return simp->SimplifyTerm_TopLevel(n); } FatalError("TranslateSignedDivModRem: input must be signed DIV/MOD/REM", in); @@ -157,7 +143,7 @@ namespace BEEV }//end of TranslateSignedDivModRem() // Check that the transformations have occurred. - void assertTransformPostConditions(const ASTNode & term) + void ArrayTransformer::assertTransformPostConditions(const ASTNode & term) { const Kind k = term.GetKind(); @@ -183,30 +169,12 @@ namespace BEEV } }//End of assertTransformPostConditions() - ASTNode BeevMgr::NewBooleanVar(const ASTNode& var, - const ASTNode& constant) - { - ostringstream outVar; - ostringstream outNum; - //Get the name of Boolean Var - var.PL_Print(outVar); - constant.PL_Print(outNum); - std::string str(outVar.str()); - str += "("; - str += outNum.str(); - str += ")"; - ASTNode CurrentSymbol = CreateSymbol(str.c_str()); - CurrentSymbol.SetValueWidth(0); - CurrentSymbol.SetIndexWidth(0); - return CurrentSymbol; - } - /******************************************************** * TransformFormula() * * Get rid of DIV/MODs, ARRAY read/writes, FOR constructs ********************************************************/ - ASTNode TransformFormula(const ASTNode& form) + ASTNode ArrayTransformer::TransformFormula(const ASTNode& form) { BeevMgr* bm = form.GetBeevMgr(); @@ -260,7 +228,7 @@ namespace BEEV { ASTNode term1 = TransformTerm(simpleForm[0]); ASTNode term2 = TransformTerm(simpleForm[1]); - result = bm->CreateSimplifiedEQ(term1, term2); + result = simp->CreateSimplifiedEQ(term1, term2); break; } case AND: @@ -286,7 +254,7 @@ namespace BEEV case FOR: { //Insert in a global list of FOR constructs. Return TRUE now - bm->GlobalList_Of_FiniteLoops.push_back(simpleForm); + //GlobalList_Of_FiniteLoops.push_back(simpleForm); return bm->CreateNode(TRUE); break; } @@ -300,7 +268,7 @@ namespace BEEV //VAR(expression), then simply return it if(BVCONST == simpleForm[1].GetKind()) { - result = bm->NewBooleanVar(simpleForm[0],simpleForm[1]); + result = bm->NewParameterized_BooleanVar(simpleForm[0],simpleForm[1]); } else { @@ -328,7 +296,7 @@ namespace BEEV } //End of TransformFormula - ASTNode TransformTerm(const ASTNode& inputterm) + ASTNode ArrayTransformer::TransformTerm(const ASTNode& inputterm) { assert(TransformMap != NULL); @@ -361,7 +329,7 @@ namespace BEEV FatalError("TransformTerm: this kind is not supported", term); break; case READ: - result = bm->TransformArray(term); + result = TransformArray(term); break; case ITE: { @@ -371,8 +339,7 @@ namespace BEEV cond = TransformFormula(cond); thn = TransformTerm(thn); els = TransformTerm(els); - //result = CreateTerm(ITE,term.GetValueWidth(),cond,thn,els); - result = bm->CreateSimplifiedTermITE(cond, thn, els); + result = simp->CreateSimplifiedTermITE(cond, thn, els); result.SetIndexWidth(term.GetIndexWidth()); break; } @@ -444,7 +411,7 @@ namespace BEEV * ITE(i=j,v1,v2) * */ - ASTNode BeevMgr::TransformArray(const ASTNode& term) + ASTNode ArrayTransformer::TransformArray(const ASTNode& term) { assert(TransformMap != NULL); @@ -477,12 +444,12 @@ namespace BEEV */ // Recursively transform read index, which may also contain reads. - ASTNode processedTerm = CreateTerm(READ, width, arrName, readIndex); + ASTNode processedTerm = bm->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()) + if ((it = Arrayread_IteMap->find(processedTerm)) != Arrayread_IteMap->end()) { result = it->second; break; @@ -491,12 +458,12 @@ namespace BEEV 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)) + if (simp->CheckSubstitutionMap(processedTerm, CurrentSymbol)) { - _arrayread_symbol[processedTerm] = CurrentSymbol; + Arrayread_SymbolMap[processedTerm] = CurrentSymbol; } // Check if it already has an abstract variable. - else if ((it1 = _arrayread_symbol.find(processedTerm)) != _arrayread_symbol.end()) + else if ((it1 = Arrayread_SymbolMap.find(processedTerm)) != Arrayread_SymbolMap.end()) { CurrentSymbol = it1->second; } @@ -514,20 +481,20 @@ namespace BEEV std::string ccc(d); c += "array_" + ccc; - CurrentSymbol = CreateSymbol(c.c_str()); + CurrentSymbol = bm->CreateSymbol(c.c_str()); CurrentSymbol.SetValueWidth(processedTerm.GetValueWidth()); CurrentSymbol.SetIndexWidth(processedTerm.GetIndexWidth()); - _arrayread_symbol[processedTerm] = CurrentSymbol; + Arrayread_SymbolMap[processedTerm] = CurrentSymbol; } //list of array-read indices corresponding to arrName, seen while //traversing the AST tree. we need this list to construct the ITEs // Dill: we hope to make this irrelevant. Harmless for now. - const ASTVec & readIndices = _arrayname_readindices[arrName]; + const ASTVec & readIndices = (*Arrayname_ReadindicesMap)[arrName]; //construct the ITE structure for this array-read ASTNode ite = CurrentSymbol; - _introduced_symbols.insert(CurrentSymbol); + Introduced_SymbolsSet.insert(CurrentSymbol); assert(BVTypeCheck(ite)); if (arrayread_refinement_flag) @@ -543,26 +510,26 @@ namespace BEEV ASTVec::const_reverse_iterator it2end = readIndices.rend(); for (; it2 != it2end; it2++) { - ASTNode cond = CreateSimplifiedEQ(readIndex, *it2); + ASTNode cond = simp->CreateSimplifiedEQ(readIndex, *it2); if (ASTFalse == cond) continue; - ASTNode arrRead = CreateTerm(READ, width, arrName, *it2); + ASTNode arrRead = bm->CreateTerm(READ, width, arrName, *it2); assert(BVTypeCheck(arrRead)); - ASTNode arrayreadSymbol = _arrayread_symbol[arrRead]; + ASTNode arrayreadSymbol = Arrayread_SymbolMap[arrRead]; if (arrayreadSymbol.IsNull()) FatalError("TransformArray:symbolic variable for processedTerm, p," "does not exist:p = ", arrRead); - ite = CreateSimplifiedTermITE(cond, arrayreadSymbol, ite); + ite = simp->CreateSimplifiedTermITE(cond, arrayreadSymbol, ite); } result = ite; //} } - _arrayname_readindices[arrName].push_back(readIndex); + (*Arrayname_ReadindicesMap)[arrName].push_back(readIndex); //save the ite corresponding to 'processedTerm' - _arrayread_ite[processedTerm] = result; + (*Arrayread_IteMap)[processedTerm] = result; break; } //end of READ over a SYMBOL case WRITE: @@ -593,38 +560,38 @@ namespace BEEV if ((SYMBOL == arrName[0].GetKind() || WRITE == arrName[0].GetKind())) { - ASTNode cond = CreateSimplifiedEQ(writeIndex, readIndex); + ASTNode cond = simp->CreateSimplifiedEQ(writeIndex, readIndex); BVTypeCheck(cond); - ASTNode readTerm = CreateTerm(READ, width, arrName[0], readIndex); + ASTNode readTerm = bm->CreateTerm(READ, width, arrName[0], readIndex); BVTypeCheck(readTerm); ASTNode readPushedIn = TransformArray(readTerm); BVTypeCheck(readPushedIn); - result = CreateSimplifiedTermITE(cond, writeVal, readPushedIn); + result = simp->CreateSimplifiedTermITE(cond, writeVal, readPushedIn); BVTypeCheck(result); } else if (ITE == arrName[0].GetKind()) { // pull out the ite from the write // pushes the write through. - ASTNode writeTrue = CreateNode(WRITE, (arrName[0][1]), writeIndex, writeVal); + ASTNode writeTrue = bm->CreateNode(WRITE, (arrName[0][1]), writeIndex, writeVal); writeTrue.SetIndexWidth(writeIndex.GetValueWidth()); writeTrue.SetValueWidth(writeVal.GetValueWidth()); assert(ARRAY_TYPE == writeTrue.GetType()); - ASTNode writeFalse = CreateNode(WRITE, (arrName[0][2]), writeIndex, writeVal); + ASTNode writeFalse = bm->CreateNode(WRITE, (arrName[0][2]), writeIndex, writeVal); writeFalse.SetIndexWidth(writeIndex.GetValueWidth()); writeFalse.SetValueWidth(writeVal.GetValueWidth()); assert(ARRAY_TYPE == writeFalse.GetType()); - result = CreateSimplifiedTermITE(TransformFormula(arrName[0][0]), writeTrue, writeFalse); + result = simp->CreateSimplifiedTermITE(TransformFormula(arrName[0][0]), writeTrue, writeFalse); result.SetIndexWidth(writeIndex.GetValueWidth()); result.SetValueWidth(writeVal.GetValueWidth()); assert(ARRAY_TYPE == result.GetType()); - result = CreateTerm(READ, writeVal.GetValueWidth(), result, readIndex); + result = bm->CreateTerm(READ, writeVal.GetValueWidth(), result, readIndex); BVTypeCheck(result); result = TransformArray(result); } @@ -652,17 +619,17 @@ namespace BEEV const ASTNode& els = arrName[2]; //(READ thn j) - ASTNode thnRead = CreateTerm(READ, width, thn, readIndex); + ASTNode thnRead = bm->CreateTerm(READ, width, thn, readIndex); BVTypeCheck(thnRead); thnRead = TransformArray(thnRead); //(READ els j) - ASTNode elsRead = CreateTerm(READ, width, els, readIndex); + ASTNode elsRead = bm->CreateTerm(READ, width, els, readIndex); BVTypeCheck(elsRead); elsRead = TransformArray(elsRead); //(ITE cond (READ thn j) (READ els j)) - result = CreateSimplifiedTermITE(cond, thnRead, elsRead); + result = simp->CreateSimplifiedTermITE(cond, thnRead, elsRead); BVTypeCheck(result); break; } @@ -674,4 +641,143 @@ namespace BEEV (*TransformMap)[term] = result; return result; } //end of TransformArray() + + //The big substitution function + ASTNode ArrayTransformer::CreateSubstitutionMap(const ASTNode& a) + { + if (!wordlevel_solve_flag) + return a; + + ASTNode output = a; + //if the variable has been solved for, then simply return it + if (simp->CheckSolverMap(a, output)) + return output; + + //traverse a and populate the SubstitutionMap + Kind k = a.GetKind(); + if (SYMBOL == k && BOOLEAN_TYPE == a.GetType()) + { + bool updated = simp->UpdateSubstitutionMap(a, ASTTrue); + output = updated ? ASTTrue : a; + return output; + } + if (NOT == k && SYMBOL == a[0].GetKind()) + { + bool updated = simp->UpdateSubstitutionMap(a[0], ASTFalse); + output = updated ? ASTTrue : a; + return output; + } + + if (IFF == k) + { + ASTVec c = a.GetChildren(); + SortByArith(c); + if (SYMBOL != c[0].GetKind() || + bm->VarSeenInTerm(c[0], + simp->SimplifyFormula_NoRemoveWrites(c[1], false))) + { + return a; + } + bool updated = + simp->UpdateSubstitutionMap(c[0], simp->SimplifyFormula(c[1], false)); + output = updated ? ASTTrue : a; + return output; + } + + if (EQ == k) + { + //fill the arrayname readindices vector if e0 is a + //READ(Arr,index) and index is a BVCONST + ASTVec c = a.GetChildren(); + SortByArith(c); + FillUp_ArrReadIndex_Vec(c[0], c[1]); + + ASTNode c1 = simp->SimplifyTerm(c[1]); + if (SYMBOL == c[0].GetKind() + && bm->VarSeenInTerm(c[0], c1)) + { + return a; + } + + if (1 == TermOrder(c[0], c[1]) + && READ == c[0].GetKind() + && bm->VarSeenInTerm(c[0][1], c1)) + { + return a; + } + bool updated = simp->UpdateSubstitutionMap(c[0], c1); + output = updated ? ASTTrue : a; + return output; + } + + if (AND == k) + { + ASTVec o; + ASTVec c = a.GetChildren(); + for (ASTVec::iterator it = c.begin(), itend = c.end(); it != itend; it++) + { + simp->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 bm->CreateNode(AND, o); + } + + //printf("I gave up on kind: %d node: %d\n", k, a.GetNodeNum()); + return output; + } //end of CreateSubstitutionMap() + + //This function records all the const-indices seen so far for each + //array. It populates the map 'Arrayname_ReadindicesMap' 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 ArrayTransformer::FillUp_ArrReadIndex_Vec(const ASTNode& e0, + const ASTNode& e1) + { + int i = TermOrder(e0, e1); + if (0 == i) + return; + + if (1 == i + && e0.GetKind() != SYMBOL + && !simp->CheckSubstitutionMap(e0)) + { + (*Arrayname_ReadindicesMap)[e0[0]].push_back(e0[1]); + //e0 is the array read : READ(A,i) and e1 is a bvconst + Arrayread_SymbolMap[e0] = e1; + return; + } + if (-1 == i + && e1.GetKind() != SYMBOL + && !simp->CheckSubstitutionMap(e1)) + { + (*Arrayname_ReadindicesMap)[e1[0]].push_back(e1[1]); + //e0 is the array read : READ(A,i) and e1 is a bvconst + Arrayread_SymbolMap[e1] = e0; + return; + } + } //End of Fillup + + } //end of namespace BEEV diff --git a/src/AST/ArrayTransformer.h b/src/AST/ArrayTransformer.h new file mode 100644 index 0000000..fdfb136 --- /dev/null +++ b/src/AST/ArrayTransformer.h @@ -0,0 +1,180 @@ +// -*- c++ -*- +/******************************************************************** + * AUTHORS: Vijay Ganesh + * + * BEGIN DATE: November, 2005 + * + * LICENSE: Please view LICENSE file in the home dir of this Program + ********************************************************************/ + +#ifndef TRANSFORM_H +#define TRANSFORM_H + +#include +#include +#include +#include +#include +#include "AST.h" +#include "../STPManager/STPManager.h" +#include "../simplifier/simplifier.h" + +namespace BEEV +{ + class ArrayTransformer + { + private: + + /**************************************************************** + * Private Typedefs and Data * + ****************************************************************/ + + // Handy defs + ASTNode ASTTrue, ASTFalse, ASTUndefined; + + // 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 read + // indicies. for some odd reason the performance went down + // considerably. this is totally inexplicable. + ASTNodeToVecMap * Arrayname_ReadindicesMap; + + // MAP: This is a map from array-reads to symbolic constants. This + // map is used by the TransformArray() + ASTNodeMap Arrayread_SymbolMap; + + // 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_IteMap; + + // Set of new symbols introduced that replace the array read terms + ASTNodeSet Introduced_SymbolsSet; + + // Count to keep track of new symbolic constants introduced + // corresponding to Array Reads + unsigned int _symbol_count; + + // Memo table used by the transformer while it is transforming the + // formulas and terms + ASTNodeMap* TransformMap; + + //Vector of array-write axioms not falsified in refinement + ASTVec ArrayWrite_RemainingAxioms; + + // For finiteloop construct. A list of all finiteloop constructs + // in the input formula + // + // ASTVec GlobalList_Of_FiniteLoops; + + // Flag for debuggin the transformer + const bool debug_transform; + + // Ptr to an external simplifier + Simplifier * simp; + + // Ptr to STPManager + BeevMgr * bm; + + // Ptr to class that records the runtimes for various parts of the + // code + RunTimes * runTimes; + + /**************************************************************** + * Private Member Functions * + ****************************************************************/ + + ASTNode TranslateSignedDivModRem(const ASTNode& in); + ASTNode TransformTerm(const ASTNode& inputterm); + void assertTransformPostConditions(const ASTNode & term); + + /**************************************************************** + * Helper functions to for creating substitution map * + ****************************************************************/ + + //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); + + ASTNode TransformArray(const ASTNode& term); + + public: + + /**************************************************************** + * Public Member Functions * + ****************************************************************/ + + // Constructor + ArrayTransformer(BeevMgr * bm, Simplifier* s) : + Arrayread_SymbolMap(INITIAL_TABLE_SIZE), + Introduced_SymbolsSet(INITIAL_TABLE_SIZE), + bm(bm), + simp(s), + debug_transform(0) + { + Arrayread_IteMap = new ASTNodeMap(INITIAL_TABLE_SIZE); + Arrayname_ReadindicesMap = new ASTNodeToVecMap(INITIAL_TABLE_SIZE); + runTimes = bm->GetRunTimes(); + ASTTrue = bm->CreateNode(TRUE); + ASTFalse = bm->CreateNode(FALSE); + ASTUndefined = bm->CreateNode(UNDEFINED); + } + + // Destructor + ~ArrayTransformer() + { + } + + // Takes a formula, transforms it by replacing array reads with + // variables, and returns the transformed formula + ASTNode TransformFormula_TopLevel(const ASTNode& form); + + ASTNode TransformFormula(const ASTNode& form); + + // Create Substitution Map function + ASTNode CreateSubstitutionMap(const ASTNode& a); + + const ASTNodeToVecMap * ArrayName_ReadIndicesMap() + { + return Arrayname_ReadindicesMap; + } //End of ArrayName_ReadIndicesMap + + const ASTNode ArrayRead_SymbolMap(const ASTNode& arrread) + { + ASTNode symbol = Arrayread_SymbolMap[arrread]; + return symbol; + } //End of ArrayRead_SymbolMap + + const ASTNodeMap * ArrayRead_IteMap() + { + return Arrayread_IteMap; + } //End of ArrayRead_IteMap + + ASTNode ArrayRead_Ite(const ASTNode& arrread) + { + return (*Arrayread_IteMap)[arrread]; + } //End of ArrayRead_Ite + + bool FoundIntroducedSymbolSet(const ASTNode& in) + { + if(Introduced_SymbolsSet.find(in) != Introduced_SymbolsSet.end()) + { + return true; + } + return false; + } // End of IntroduceSymbolSet + + }; //end of class Transformer + +};//end of namespace +#endif diff --git a/src/AST/Makefile b/src/AST/Makefile index e7b2cb1..63c5814 100644 --- a/src/AST/Makefile +++ b/src/AST/Makefile @@ -17,7 +17,7 @@ ASTKind.h ASTKind.cpp: ASTKind.kinds genkinds.pl .PHONY: clean clean: - rm -rf *.o *~ bbtest asttest cnftest *.a ASTKind.cpp ASTKind.h .#* + rm -rf *.o *~ bbtest asttest cnftest *.a ASTKind.cpp ASTKind.h depend .#* depend: $(SRCS) ASTKind.h ASTKind.cpp @$(CXX) -MM -MG $(CXXFLAGS) $(SRCS) > $@ diff --git a/src/AST/RunTimes.h b/src/AST/RunTimes.h index 832587c..e1bcb63 100644 --- a/src/AST/RunTimes.h +++ b/src/AST/RunTimes.h @@ -1,3 +1,12 @@ +// -*- c++ -*- +/******************************************************************** + * AUTHORS: Trevor Hansen + * + * BEGIN DATE: November, 2005 + * + * LICENSE: Please view LICENSE file in the home dir of this Program + ********************************************************************/ + #ifndef RUNTIMES_H #define RUNTIMES_H @@ -8,45 +17,50 @@ class RunTimes { public: - enum Category - { - Transforming = 0, SimplifyTopLevel, Parsing, CNFConversion, BitBlasting, Solving, BVSolver, CreateSubstitutionMap, SendingToSAT - }; - - static std::string CategoryNames[]; - - typedef std::pair Element; - -private: - RunTimes& operator =(const RunTimes&); - RunTimes(const RunTimes& other); - - std::map counts; - std::map times; - std::stack category_stack; - - // millisecond precision timer. - long getCurrentTime(); - void addTime(Category c, long milliseconds); - -public: - - void addCount(Category c); - void start(Category c); - void stop(Category c); - void print(); - - RunTimes(){} - - void clear() - { - counts.clear(); - times.clear(); - category_stack.empty(); - } - - + enum Category + { + Transforming = 0, + SimplifyTopLevel, + Parsing, + CNFConversion, + BitBlasting, + Solving, + BVSolver, + CreateSubstitutionMap, + SendingToSAT + }; + static std::string CategoryNames[]; + + typedef std::pair Element; + + private: + RunTimes& operator =(const RunTimes&); + RunTimes(const RunTimes& other); + + std::map counts; + std::map times; + std::stack category_stack; + + // millisecond precision timer. + long getCurrentTime(); + void addTime(Category c, long milliseconds); + + public: + + void addCount(Category c); + void start(Category c); + void stop(Category c); + void print(); + + RunTimes(){} + + void clear() + { + counts.clear(); + times.clear(); + category_stack.empty(); + } }; #endif diff --git a/src/AST/TopLevel.h b/src/AST/TopLevel.h index 8400ac0..11e482d 100644 --- a/src/AST/TopLevel.h +++ b/src/AST/TopLevel.h @@ -21,6 +21,8 @@ #include #include +#define INITIAL_TABLE_SIZE 100 + #ifdef EXT_HASH_MAP #include #include @@ -41,38 +43,17 @@ #include "../extlib-constbv/constantbv.h" #include "RunTimes.h" +#define HASHMAP hash_map; +#define HASHSET hash_set; + namespace BEEV { + using namespace std; using namespace MINISAT; #ifdef EXT_HASH_MAP using namespace __gnu_cxx; #endif - /****************************************************************** - * struct enumeration: * - * * - * Templated class that allows you to define the number of bytes * - * (using class T below) for the enumerated type class E. * - ******************************************************************/ - template - struct enumeration - { - typedef T type; - typedef E enum_type; - - enumeration() : e_(E()) - {} - - enumeration(E e) : e_(static_cast(e)) - {} - - operator E() const - { return static_cast(e_); } - - private: - T e_; - }; //end of Enumeration struct - /****************************************************************** * Important classes declared as part of AST datastructures * * * @@ -94,10 +75,7 @@ namespace BEEV { ******************************************************************/ typedef vector ASTVec; typedef unsigned int * CBV; -#define HASHMAP hash_map; -#define HASHSET hash_set; extern ASTVec _empty_ASTVec; - }; //end of namespace #endif diff --git a/src/const-evaluator/Makefile b/src/STPManager/Makefile similarity index 59% rename from src/const-evaluator/Makefile rename to src/STPManager/Makefile index a1849a5..50506a4 100644 --- a/src/const-evaluator/Makefile +++ b/src/STPManager/Makefile @@ -2,10 +2,11 @@ include ../../scripts/Makefile.common SRCS = $(wildcard *.cpp) OBJS = $(SRCS:.cpp=.o) +CFLAGS += -I../sat/mtl -I../sat/simp -I../sat/core -libconsteval.a: $(OBJS) depend - $(AR) rc $@ $(OBJS) - $(RANLIB) $@ +libstpmgr.a: $(OBJS) depend + $(AR) rc $@ $(OBJS) + $(RANLIB) $@ .PHONY: clean clean: @@ -14,4 +15,4 @@ clean: depend: $(SRCS) @$(CXX) -MM $(CXXFLAGS) $(SRCS) > $@ -#-include depend +#-include depend \ No newline at end of file diff --git a/src/STPManager/STP.cpp b/src/STPManager/STP.cpp new file mode 100644 index 0000000..893bf9f --- /dev/null +++ b/src/STPManager/STP.cpp @@ -0,0 +1,181 @@ +// -*- c++ -*- +/******************************************************************** + * AUTHORS: Vijay Ganesh + * + * BEGIN DATE: November, 2005 + * + * LICENSE: Please view LICENSE file in the home dir of this Program + ********************************************************************/ + +#include "STP.h" + +namespace BEEV { + + //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 UNDECIDED + SOLVER_RETURN_TYPE STP::TopLevelSATAux(const ASTNode& inputasserts_and_query) + { + ASTNode inputToSAT = inputasserts_and_query; + ASTNode orig_input = inputToSAT; + bm->ASTNodeStats("input asserts and query: ", inputToSAT); + + ASTNode simplified_solved_InputToSAT = inputToSAT; + //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. + bm->SimplifyWrites_InPlace_Flag = false; + bm->Begin_RemoveWrites = false; + bm->start_abstracting = false; + bm->TermsAlreadySeenMap_Clear(); + do + { + inputToSAT = simplified_solved_InputToSAT; + + if(optimize_flag) + { + + bm->GetRunTimes()->start(RunTimes::CreateSubstitutionMap); + simplified_solved_InputToSAT = + arrayTransformer->CreateSubstitutionMap(simplified_solved_InputToSAT); + bm->GetRunTimes()->stop(RunTimes::CreateSubstitutionMap); + //printf("##################################################\n"); + bm->ASTNodeStats("after pure substitution: ", simplified_solved_InputToSAT); + + + simplified_solved_InputToSAT = + simp->SimplifyFormula_TopLevel(simplified_solved_InputToSAT, false); + + bm->ASTNodeStats("after simplification: ", simplified_solved_InputToSAT); + } + + if(wordlevel_solve_flag) + { + simplified_solved_InputToSAT = + bvsolver->TopLevelBVSolve(simplified_solved_InputToSAT); + bm->ASTNodeStats("after solving: ", simplified_solved_InputToSAT); + } + + } + while (inputToSAT != simplified_solved_InputToSAT); + + bm->ASTNodeStats("Before SimplifyWrites_Inplace begins: ", + simplified_solved_InputToSAT); + + bm->SimplifyWrites_InPlace_Flag = true; + bm->Begin_RemoveWrites = false; + bm->start_abstracting = false; + bm->TermsAlreadySeenMap_Clear(); + do + { + inputToSAT = simplified_solved_InputToSAT; + + if(optimize_flag) + { + bm->GetRunTimes()->start(RunTimes::CreateSubstitutionMap); + simplified_solved_InputToSAT = + arrayTransformer->CreateSubstitutionMap(simplified_solved_InputToSAT); + bm->GetRunTimes()->stop(RunTimes::CreateSubstitutionMap); + bm->ASTNodeStats("after pure substitution: ", simplified_solved_InputToSAT); + + simplified_solved_InputToSAT = + simp->SimplifyFormula_TopLevel(simplified_solved_InputToSAT, false); + bm->ASTNodeStats("after simplification: ", simplified_solved_InputToSAT); + } + + if(wordlevel_solve_flag) + { + simplified_solved_InputToSAT = + bvsolver->TopLevelBVSolve(simplified_solved_InputToSAT); + bm->ASTNodeStats("after solving: ", simplified_solved_InputToSAT); + } + } while (inputToSAT != simplified_solved_InputToSAT); + + bm->ASTNodeStats("After SimplifyWrites_Inplace: ", simplified_solved_InputToSAT); + delete bvsolver; + bvsolver = NULL; + + bm->start_abstracting = (arraywrite_refinement_flag) ? true : false; + bm->SimplifyWrites_InPlace_Flag = false; + bm->Begin_RemoveWrites = (bm->start_abstracting) ? false : true; + if (bm->start_abstracting) + { + bm->ASTNodeStats("before abstraction round begins: ", + simplified_solved_InputToSAT); + } + + bm->TermsAlreadySeenMap_Clear(); + if (bm->start_abstracting) + { + bm->ASTNodeStats("After abstraction: ", simplified_solved_InputToSAT); + } + bm->start_abstracting = false; + bm->SimplifyWrites_InPlace_Flag = false; + bm->Begin_RemoveWrites = false; + + simplified_solved_InputToSAT = + arrayTransformer->TransformFormula_TopLevel(simplified_solved_InputToSAT); + bm->ASTNodeStats("after transformation: ", simplified_solved_InputToSAT); + bm->TermsAlreadySeenMap_Clear(); + + SOLVER_RETURN_TYPE res; + //solver instantiated here + MINISAT::Solver newS; + //MINISAT::SimpSolver newS; + //MINISAT::UnsoundSimpSolver newS; + if (arrayread_refinement_flag) + { + bm->counterexample_checking_during_refinement = true; + } + + res = + Ctr_Example->CallSAT_ResultCheck(newS, + simplified_solved_InputToSAT, + orig_input); + if (SOLVER_UNDECIDED != res) + { + CountersAndStats("print_func_stats"); + return res; + } + + // res = SATBased_AllFiniteLoops_Refinement(newS, orig_input); + // if (SOLVER_UNDECIDED != res) + // { + // CountersAndStats("print_func_stats"); + // return res; + // } + + res = + Ctr_Example->SATBased_ArrayReadRefinement(newS, + simplified_solved_InputToSAT, + orig_input); + if (SOLVER_UNDECIDED != res) + { + CountersAndStats("print_func_stats"); + return res; + } + + res = + Ctr_Example->SATBased_ArrayWriteRefinement(newS, orig_input); + if (SOLVER_UNDECIDED != res) + { + CountersAndStats("print_func_stats"); + return res; + } + + res = + Ctr_Example->SATBased_ArrayReadRefinement(newS, + simplified_solved_InputToSAT, + orig_input); + if (SOLVER_UNDECIDED != res) + { + CountersAndStats("print_func_stats"); + return res; + } + + FatalError("TopLevelSATAux: reached the end without proper conclusion:" + "either a divide by zero in the input or a bug in STP"); + //bogus return to make the compiler shut up + return SOLVER_ERROR; + } //End of TopLevelSATAux +}; //end of namespace diff --git a/src/STPManager/STP.h b/src/STPManager/STP.h new file mode 100644 index 0000000..03a356e --- /dev/null +++ b/src/STPManager/STP.h @@ -0,0 +1,66 @@ +// -*- c++ -*- +/******************************************************************** + * AUTHORS: Vijay Ganesh + * + * BEGIN DATE: November, 2005 + * + * LICENSE: Please view LICENSE file in the home dir of this Program + ********************************************************************/ + +#ifndef STP_H +#define STP_H + +#include "../AST/AST.h" +#include "../AST/ArrayTransformer.h" +#include "../STPManager/STPManager.h" +#include "../simplifier/bvsolver.h" +#include "../simplifier/simplifier.h" +#include "../to-sat/ToSAT.h" +#include "../parser/let-funcs.h" +#include "../absrefine_counterexample/AbsRefine_CounterExample.h" + + +namespace BEEV +{ + class STP { + public: + BeevMgr * bm; + Simplifier * simp; + BVSolver * bvsolver; + ArrayTransformer * arrayTransformer; + ToSAT * tosat; + AbsRefine_CounterExample * Ctr_Example; + + //Constructor + STP(BeevMgr* b, + Simplifier* s, + BVSolver* bsolv, + ArrayTransformer * a, + ToSAT * ts, + AbsRefine_CounterExample * ce) + { + bm = b; + simp = s; + tosat = ts; + bvsolver = bsolv; + arrayTransformer = a; + Ctr_Example = ce; + }// End of constructor + + SOLVER_RETURN_TYPE TopLevelSAT(const ASTNode& inputasserts, + const ASTNode& query) + { + ASTNode q = bm->CreateNode(AND, + inputasserts, + bm->CreateNode(NOT, query)); + return TopLevelSATAux(q); + } //End of TopLevelSAT() + + // Accepts query and returns the answer. if query is valid, + // returns VALID, else returns INVALID. Automatically constructs + // counterexample for invalid queries, and prints them upon + // request. + SOLVER_RETURN_TYPE TopLevelSATAux(const ASTNode& inputasserts_and_query); + }; //End of Class STP +};//end of namespace +#endif diff --git a/src/STPManager/STPManager.cpp b/src/STPManager/STPManager.cpp index 354ee49..e04f907 100644 --- a/src/STPManager/STPManager.cpp +++ b/src/STPManager/STPManager.cpp @@ -7,33 +7,22 @@ * LICENSE: Please view LICENSE file in the home dir of this Program ********************************************************************/ +// to get the PRIu64 macro from inttypes, this needs to be defined. +#define __STDC_FORMAT_MACROS +#include +#include +#include "../sat/sat.h" #include "../STPManager/STPManager.h" + namespace BEEV { - // 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()) + ASTInteriorSet::iterator it = _interior_unique_table.find(n_ptr); + if (it == _interior_unique_table.end()) { - // Make a new ASTInterior node - // We want (NOT alpha) always to have alpha.nodenum + 1. + // 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); @@ -42,7 +31,8 @@ namespace BEEV { n_ptr->SetNodeNum(NewNodeNum()); } - pair p = _interior_unique_table.insert(n_ptr); + pair p = + _interior_unique_table.insert(n_ptr); return *(p.first); } else @@ -66,7 +56,9 @@ namespace BEEV return n; } - ASTNode BeevMgr::CreateNode(Kind kind, const ASTNode& child0, const ASTVec & back_children) + ASTNode BeevMgr::CreateNode(Kind kind, + const ASTNode& child0, + const ASTVec & back_children) { ASTInterior *n_ptr = new ASTInterior(kind); @@ -76,9 +68,11 @@ namespace BEEV return n; } - ASTNode BeevMgr::CreateNode(Kind kind, const ASTNode& child0, const ASTNode& child1, const ASTVec & back_children) + ASTNode BeevMgr::CreateNode(Kind kind, + const ASTNode& child0, + const ASTNode& child1, + const ASTVec & back_children) { - ASTInterior *n_ptr = new ASTInterior(kind); ASTVec &front_children = n_ptr->_children; front_children.push_back(child0); @@ -87,7 +81,11 @@ namespace BEEV return n; } - ASTNode BeevMgr::CreateNode(Kind kind, const ASTNode& child0, const ASTNode& child1, const ASTNode& child2, const ASTVec & back_children) + ASTNode BeevMgr::CreateNode(Kind kind, + const ASTNode& child0, + const ASTNode& child1, + const ASTNode& child2, + const ASTVec & back_children) { ASTInterior *n_ptr = new ASTInterior(kind); ASTVec &front_children = n_ptr->_children; @@ -107,14 +105,20 @@ namespace BEEV // 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()); + 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); + { + FatalError("CreateInteriorNode:"\ + "Undefined childnode in CreateInteriorNode: ", + ASTUndefined); + } } return LookupOrCreateInterior(n_ptr); @@ -136,16 +140,68 @@ namespace BEEV //////////////////////////////////////////////////////////////// ASTNode BeevMgr::CreateSymbol(const char * const name) { - ASTSymbol temp_sym(name); + ASTSymbol temp_sym(name); ASTNode n(LookupOrCreateSymbol(temp_sym)); return n; } + // 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. + + //_symbol_unique_table.insert(s_ptr); + //return s_ptr; + // Do an explicit lookup to see if we need to create a copy of the + // string. + ASTSymbolSet::const_iterator it = _symbol_unique_table.find(s_ptr); + if (it == _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())); + s_ptr1->SetNodeNum(NewNodeNum()); + s_ptr1->_value_width = s_ptr->_value_width; + pair p = + _symbol_unique_table.insert(s_ptr1); + return *p.first; + } + else + { + // return symbol found in table. + return *it; + } + } // End of LookupOrCreateSymbol + + 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; + } + //Create a ASTBVConst node ASTNode BeevMgr::CreateBVConst(unsigned int width, unsigned long long int bvconst) { if (width > (sizeof(unsigned long long int) << 3) || width <= 0) - FatalError("CreateBVConst: trying to create a bvconst using unsigned long long of width: ", ASTUndefined, width); + FatalError("CreateBVConst: "\ + "trying to create a bvconst using unsigned long long of width: ", + ASTUndefined, width); CBV bv = CONSTANTBV::BitVector_Create(width, true); unsigned long c_val = (~((unsigned long) 0)) & bvconst; @@ -327,50 +383,6 @@ namespace BEEV } } - // 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())); - s_ptr1->SetNodeNum(NewNodeNum()); - s_ptr1->_value_width = s_ptr->_value_width; - pair 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; - } - // Create and return an ASTNode for a term ASTNode BeevMgr::CreateTerm(Kind kind, unsigned int width, @@ -397,6 +409,7 @@ namespace BEEV FatalError("CreateTerm: Illegal kind to CreateTerm:", ASTUndefined, kind); ASTNode n = CreateNode(kind, child0, children); n.SetValueWidth(width); + BVTypeCheck(n); return n; } @@ -462,245 +475,6 @@ namespace BEEV return os; } - // If there is a lot of sharing in the graph, this will take a long - // time. it doesn't mark subgraphs as already having been - // typechecked. - bool BeevMgr::BVTypeCheckRecursive(const ASTNode& n) - { - const ASTVec& c = n.GetChildren(); - - BVTypeCheck(n); - - for (ASTVec::const_iterator it = c.begin(), itend = c.end(); it != itend; it++) - BVTypeCheckRecursive(*it); - - return true; - } - - - - /* FUNCTION: Typechecker for terms and formulas - * - * TypeChecker: Assumes that the immediate Children of the input - * ASTNode have been typechecked. This function is suitable in - * scenarios like where you are building the ASTNode Tree, and you - * typecheck as you go along. It is not suitable as a general - * typechecker. - * - * If this returns, this ALWAYS returns true. If there is an error it - * will call FatalError() and abort. - */ - - - bool BeevMgr::BVTypeCheck(const ASTNode& n) - { - Kind k = n.GetKind(); - //The children of bitvector terms are in turn bitvectors. - const ASTVec& v = n.GetChildren(); - if (is_Term_kind(k)) - { - switch (k) - { - case BVCONST: - if (BITVECTOR_TYPE != n.GetType()) - FatalError("BVTypeCheck: The term t does not typecheck, where t = \n", n); - break; - case SYMBOL: - return true; - case ITE: - if (BOOLEAN_TYPE != n[0].GetType() || (n[1].GetType() != n[2].GetType())) - FatalError("BVTypeCheck: The term t does not typecheck, where t = \n", n); - if (n[1].GetValueWidth() != n[2].GetValueWidth()) - FatalError("BVTypeCheck: length of THENbranch != length of ELSEbranch in the term t = \n", n); - if (n[1].GetIndexWidth() != n[2].GetIndexWidth()) - FatalError("BVTypeCheck: length of THENbranch != length of ELSEbranch in the term t = \n", n); - break; - case READ: - if (n.GetChildren().size() !=2) - FatalError("2 params to read."); - if (n[0].GetIndexWidth() != n[1].GetValueWidth()) - { - cerr << "Length of indexwidth of array: " << n[0] << " is : " << n[0].GetIndexWidth() << endl; - cerr << "Length of the actual index is: " << n[1] << " is : " << n[1].GetValueWidth() << endl; - FatalError("BVTypeCheck: length of indexwidth of array != length of actual index in the term t = \n", n); - } - if (ARRAY_TYPE != n[0].GetType()) - FatalError("First parameter to read should be an array", n[0]); - if (BITVECTOR_TYPE != n[1].GetType()) - FatalError("Second parameter to read should be a bitvector", n[1]); - break; - case WRITE: - if (n.GetChildren().size() !=3) - FatalError("3 params to write."); - if (n[0].GetIndexWidth() != n[1].GetValueWidth()) - FatalError("BVTypeCheck: length of indexwidth of array != length of actual index in the term t = \n", n); - if (n[0].GetValueWidth() != n[2].GetValueWidth()) - FatalError("BVTypeCheck: valuewidth of array != length of actual value in the term t = \n", n); - if (ARRAY_TYPE != n[0].GetType()) - FatalError("First parameter to read should be an array", n[0]); - if (BITVECTOR_TYPE != n[1].GetType()) - FatalError("Second parameter to read should be a bitvector", n[1]); - if (BITVECTOR_TYPE != n[2].GetType()) - FatalError("Third parameter to read should be a bitvector", n[2]); - - break; - case BVOR: - case BVAND: - case BVXOR: - case BVNOR: - case BVNAND: - case BVXNOR: - case BVPLUS: - case BVMULT: - case BVDIV: - case BVMOD: - case BVSUB: - { - if (!(v.size() >= 2)) - FatalError("BVTypeCheck:bitwise Booleans and BV arith operators must have atleast two arguments\n", n); - unsigned int width = n.GetValueWidth(); - for (ASTVec::const_iterator it = v.begin(), itend = v.end(); it != itend; it++) - { - if (width != it->GetValueWidth()) - { - cerr << "BVTypeCheck:Operands of bitwise-Booleans and BV arith operators must be of equal length\n"; - cerr << n << endl; - cerr << "width of term:" << width << endl; - cerr << "width of offending operand:" << it->GetValueWidth() << endl; - FatalError("BVTypeCheck:Offending operand:\n", *it); - } - if (BITVECTOR_TYPE != it->GetType()) - FatalError("BVTypeCheck: ChildNodes of bitvector-terms must be bitvectors\n", n); - } - break; - } - case BVSX: - //in BVSX(n[0],len), the length of the BVSX term must be - //greater than the length of n[0] - if (n[0].GetValueWidth() > n.GetValueWidth()) - { - FatalError("BVTypeCheck: BVSX(t,bvsx_len) : length of 't' must be <= bvsx_len\n", n); - } - if ((v.size() != 2)) - FatalError("BVTypeCheck:BVSX must have two arguments. The second is the new width\n", n); - break; - - default: - for (ASTVec::const_iterator it = v.begin(), itend = v.end(); it != itend; it++) - if (BITVECTOR_TYPE != it->GetType()) - { - cerr << "The type is: " << it->GetType() << endl; - FatalError("BVTypeCheck:ChildNodes of bitvector-terms must be bitvectors\n", n); - } - break; - } - - switch (k) - { - case BVCONCAT: - if (n.Degree() != 2) - FatalError("BVTypeCheck: should have exactly 2 args\n", n); - if (n.GetValueWidth() != n[0].GetValueWidth() + n[1].GetValueWidth()) - FatalError("BVTypeCheck:BVCONCAT: lengths do not add up\n", n); - break; - case BVUMINUS: - case BVNEG: - if (n.Degree() != 1) - FatalError("BVTypeCheck: should have exactly 1 args\n", n); - break; - case BVEXTRACT: - if (n.Degree() != 3) - FatalError("BVTypeCheck: should have exactly 3 args\n", n); - if (!(BVCONST == n[1].GetKind() && BVCONST == n[2].GetKind())) - FatalError("BVTypeCheck: indices should be BVCONST\n", n); - if (n.GetValueWidth() != GetUnsignedConst(n[1]) - GetUnsignedConst(n[2]) + 1) - FatalError("BVTypeCheck: length mismatch\n", n); - if (GetUnsignedConst(n[1]) >= n[0].GetValueWidth()) - FatalError("BVTypeCheck: Top index of select is greater or equal to the bitwidth.\n", n); - break; - case BVLEFTSHIFT: - case BVRIGHTSHIFT: - if (n.Degree() != 2) - FatalError("BVTypeCheck: should have exactly 2 args\n", n); - break; - //case BVVARSHIFT: - //case BVSRSHIFT: - //break; - default: - break; - } - } - else - { - if (!(is_Form_kind(k) && BOOLEAN_TYPE == n.GetType())) - FatalError("BVTypeCheck: not a formula:", n); - switch (k) - { - case TRUE: - case FALSE: - case SYMBOL: - return true; - case PARAMBOOL: - if(2 != n.Degree()) - FatalError("BVTypeCheck: PARAMBOOL formula can have exactly two childNodes", n); - break; - case EQ: - if (!(n[0].GetValueWidth() == n[1].GetValueWidth() && n[0].GetIndexWidth() == n[1].GetIndexWidth())) - { - cerr << "valuewidth of lhs of EQ: " << n[0].GetValueWidth() << endl; - cerr << "valuewidth of rhs of EQ: " << n[1].GetValueWidth() << endl; - cerr << "indexwidth of lhs of EQ: " << n[0].GetIndexWidth() << endl; - cerr << "indexwidth of rhs of EQ: " << n[1].GetIndexWidth() << endl; - FatalError("BVTypeCheck: terms in atomic formulas must be of equal length", n); - } - break; - case BVLT: - case BVLE: - case BVGT: - case BVGE: - case BVSLT: - case BVSLE: - case BVSGT: - case BVSGE: - if (BITVECTOR_TYPE != n[0].GetType() && BITVECTOR_TYPE != n[1].GetType()) - FatalError("BVTypeCheck: terms in atomic formulas must be bitvectors", n); - if (n[0].GetValueWidth() != n[1].GetValueWidth()) - FatalError("BVTypeCheck: terms in atomic formulas must be of equal length", n); - if (n[0].GetIndexWidth() != n[1].GetIndexWidth()) - FatalError("BVTypeCheck: terms in atomic formulas must be of equal length", n); - break; - case NOT: - if (1 != n.Degree()) - FatalError("BVTypeCheck: NOT formula can have exactly one childNode", n); - break; - case AND: - case OR: - case XOR: - case NAND: - case NOR: - if (2 > n.Degree()) - FatalError("BVTypeCheck: AND/OR/XOR/NAND/NOR: must have atleast 2 ChildNodes", n); - break; - case IFF: - case IMPLIES: - if (2 != n.Degree()) - FatalError("BVTypeCheck:IFF/IMPLIES must have exactly 2 ChildNodes", n); - break; - case ITE: - if (3 != n.Degree()) - FatalError("BVTypeCheck:ITE must have exactly 3 ChildNodes", n); - break; - case FOR: - //FIXME: Todo - break; - default: - FatalError("BVTypeCheck: Unrecognized kind: ", ASTUndefined); - break; - } - } - return true; - } //End of TypeCheck function - //add an assertion to the current logical context void BeevMgr::AddAssert(const ASTNode& assert) { @@ -782,37 +556,20 @@ namespace BEEV 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::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; - - //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() +// ASTNode CurrentSymbol = CreateSymbol(c.c_str()); +// CurrentSymbol.SetValueWidth(value); +// CurrentSymbol.SetIndexWidth(index); +// return CurrentSymbol; +// } //end of NewArrayVar() //prints statistics for the ASTNode void BeevMgr::ASTNodeStats(const char * c, const ASTNode& a) @@ -861,155 +618,187 @@ namespace BEEV void BeevMgr::ClearAllTables(void) { - //clear all tables before calling toplevelsat - _ASTNode_to_SATVar.clear(); - _SATVar_to_AST.clear(); - - for (ASTtoBitvectorMap::iterator it = _ASTNode_to_Bitvector.begin(), itend = _ASTNode_to_Bitvector.end(); it != itend; it++) - { - (it->second)->clear(); - delete (it->second); - } - _ASTNode_to_Bitvector.clear(); - - NodeLetVarMap.clear(); - NodeLetVarMap1.clear(); - PLPrintNodeSet.clear(); - AlreadyPrintedSet.clear(); - SimplifyMap->clear(); - SimplifyNegMap->clear(); - ReferenceCount->clear(); - SolverMap.clear(); - AlwaysTrueFormMap.clear(); - _arrayread_ite.clear(); - _arrayread_symbol.clear(); - _introduced_symbols.clear(); - CounterExampleMap.clear(); - ComputeFormulaMap.clear(); - StatInfoSet.clear(); - - // for(std::vector::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(); +// //clear all tables before calling toplevelsat +// //_ASTNode_to_SATVar.clear(); +// //_SATVar_to_AST.clear(); + +// // for (ASTtoBitvectorMap::iterator it = _ASTNode_to_Bitvector.begin(), +// // itend = _ASTNode_to_Bitvector.end(); it != itend; it++) +// // { +// // (it->second)->clear(); +// // delete (it->second); +// // } +// // _ASTNode_to_Bitvector.clear(); + +// NodeLetVarMap.clear(); +// NodeLetVarMap1.clear(); +// PLPrintNodeSet.clear(); +// AlreadyPrintedSet.clear(); +// //ReferenceCount->clear(); +// //_arrayread_ite.clear(); +// //_introduced_symbols.clear(); +// //CounterExampleMap.clear(); +// //ComputeFormulaMap.clear(); +// StatInfoSet.clear(); + +// _asserts.clear(); + +// // for (ASTNodeToVecMap::iterator iset = +// // _arrayname_readindices.begin(), iset_end = +// // _arrayname_readindices.end(); iset != iset_end; iset++) { +// // iset->second.clear(); } +// // _arrayname_readindices.clear(); + +// _interior_unique_table.clear(); +// _symbol_unique_table->clear(); +// _bvconst_unique_table.clear(); } void BeevMgr::ClearAllCaches(void) { //clear all tables before calling toplevelsat - _ASTNode_to_SATVar.clear(); - _SATVar_to_AST.clear(); - - for (ASTtoBitvectorMap::iterator it = _ASTNode_to_Bitvector.begin(), itend = _ASTNode_to_Bitvector.end(); it != itend; it++) - { - (it->second)->clear(); - delete (it->second); - } - _ASTNode_to_Bitvector.clear(); - + //_ASTNode_to_SATVar.clear(); + //_SATVar_to_AST.clear(); + + // for (ASTtoBitvectorMap::iterator it = _ASTNode_to_Bitvector.begin(), + // itend = _ASTNode_to_Bitvector.end(); it != itend; it++) + // { + // (it->second)->clear(); + // delete (it->second); + // } + // _ASTNode_to_Bitvector.clear(); + NodeLetVarMap.clear(); NodeLetVarMap1.clear(); PLPrintNodeSet.clear(); AlreadyPrintedSet.clear(); - SimplifyMap->clear(); - SimplifyNegMap->clear(); - ReferenceCount->clear(); - SolverMap.clear(); - AlwaysTrueFormMap.clear(); - _arrayread_ite.clear(); - _arrayread_symbol.clear(); - _introduced_symbols.clear(); - CounterExampleMap.clear(); - ComputeFormulaMap.clear(); + // SimplifyMap->clear(); + // SimplifyNegMap->clear(); + // ReferenceCount->clear(); + // SolverMap.clear(); + //AlwaysTrueFormMap.clear(); + //_arrayread_ite.clear(); + //_arrayread_symbol.clear(); + //_introduced_symbols.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(); + // 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) + BeevMgr::~BeevMgr() { - if (!SolverMap.empty()) - { - CounterExampleMap.insert(SolverMap.begin(), SolverMap.end()); - } + ClearAllTables(); } - void FatalError(const char * str, const ASTNode& a, int w) + + // GLOBAL FUNCTION: Prints statistics from the MINISAT Solver + void BeevMgr::PrintStats(MINISAT::Solver& s) { - if (a.GetKind() != UNDEFINED) + if (!stats_flag) + return; + double cpu_time = MINISAT::cpuTime(); + uint64_t mem_used = MINISAT::memUsed(); + reportf("restarts : %"PRIu64"\n", s.starts); + reportf("conflicts : %"PRIu64" (%.0f /sec)\n", s.conflicts , s.conflicts /cpu_time); + reportf("decisions : %"PRIu64" (%.0f /sec)\n", s.decisions , s.decisions /cpu_time); + reportf("propagations : %"PRIu64" (%.0f /sec)\n", s.propagations, s.propagations/cpu_time); + reportf("conflict literals : %"PRIu64" (%4.2f %% deleted)\n", s.tot_literals, + (s.max_literals - s.tot_literals)*100 / (double)s.max_literals); + if (mem_used != 0) + reportf("Memory used : %.2f MB\n", mem_used / 1048576.0); + reportf("CPU time : %g s\n", cpu_time); + } //end of PrintStats() + + + //Create a new variable of ValueWidth 'n' + ASTNode BeevMgr::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 = CreateSymbol(c.c_str()); + CurrentSymbol.SetValueWidth(n); + CurrentSymbol.SetIndexWidth(0); + return CurrentSymbol; + } //end of NewVar() + + bool BeevMgr::VarSeenInTerm(const ASTNode& var, const ASTNode& term) + { + if (READ == term.GetKind() + && WRITE == term[0].GetKind() + && !GetRemoveWritesFlag()) { - cerr << "Fatal Error: " << str << endl << a << endl; - cerr << w << endl; + return false; } - else + + if (READ == term.GetKind() + && WRITE == term[0].GetKind() + && GetRemoveWritesFlag()) { - cerr << "Fatal Error: " << str << endl; - cerr << w << endl; + return true; } - 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); - } - - void SortByExprNum(ASTVec& v) - { - sort(v.begin(), v.end(), exprless); - } + ASTNodeMap::iterator it; + if ((it = TermsAlreadySeenMap.find(term)) != TermsAlreadySeenMap.end()) + { + if (it->second == var) + { + return false; + } + } - void SortByArith(ASTVec& v) - { - sort(v.begin(), v.end(), arithless); - } + if (var == term) + { + return true; + } - bool isAtomic(Kind kind) - { - if (TRUE == kind || FALSE == kind || - EQ == 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; - } + for (ASTVec::const_iterator it = term.begin(), itend = term.end(); it != itend; it++) + { + if (VarSeenInTerm(var, *it)) + { + return true; + } + else + { + TermsAlreadySeenMap[*it] = var; + } + } - BeevMgr::~BeevMgr() - { - ClearAllTables(); + TermsAlreadySeenMap[term] = var; + return false; + }//End of VarSeenInTerm - delete SimplifyMap; - delete SimplifyNegMap; - delete ReferenceCount; - } + + ASTNode BeevMgr::NewParameterized_BooleanVar(const ASTNode& var, + const ASTNode& constant) + { + ostringstream outVar; + ostringstream outNum; + //Get the name of Boolean Var + var.PL_Print(outVar); + constant.PL_Print(outNum); + std::string str(outVar.str()); + str += "("; + str += outNum.str(); + str += ")"; + ASTNode CurrentSymbol = CreateSymbol(str.c_str()); + CurrentSymbol.SetValueWidth(0); + CurrentSymbol.SetIndexWidth(0); + return CurrentSymbol; + } // End of NewParameterized_BooleanVar() }; // end namespace beev diff --git a/src/STPManager/STPManager.h b/src/STPManager/STPManager.h new file mode 100644 index 0000000..1cf2f00 --- /dev/null +++ b/src/STPManager/STPManager.h @@ -0,0 +1,379 @@ +// -*- c++ -*- +/******************************************************************** + * AUTHORS: Vijay Ganesh + * + * BEGIN DATE: November, 2005 + * + * LICENSE: Please view LICENSE file in the home dir of this Program + ********************************************************************/ + +#ifndef STPMGR_H +#define STPMGR_H + +#include "../AST/AST.h" +#include "../parser/let-funcs.h" + +namespace BEEV +{ + /***************************************************************** + * 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; + friend class ASTInterior; + friend class ASTBVConst; + friend class ASTSymbol; + + private: + /**************************************************************** + * Private Typedefs and Data * + ****************************************************************/ + + // 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; + + //Typedef for unique BVConst node (leaf) table. + typedef hash_set< + ASTBVConst *, + ASTBVConst::ASTBVConstHasher, + ASTBVConst::ASTBVConstEqual> ASTBVConstSet; + + // Unique node tables that enables common subexpression sharing + ASTInteriorSet _interior_unique_table; + + // Table for variable names, let names etc. + ASTSymbolSet _symbol_unique_table; + + // Table to uniquefy bvconst + ASTBVConstSet _bvconst_unique_table; + + typedef hash_map< + ASTNode, + ASTNodeSet, + ASTNode::ASTNodeHasher, + ASTNode::ASTNodeEqual> ASTNodeToSetMap; + + // Global for assigning new node numbers. + int _max_node_num; + + ASTNode dummy_node; + + //frequently used nodes + ASTNode ASTFalse, ASTTrue, ASTUndefined; + + // 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 _asserts; + + //bool Begin_RemoveWrites; + + // The query for the current logical context. + ASTNode _current_query; + + // Manager for let variables + LETMgr * letmgr; + + // Ptr to class that reports on the running time of various parts + // of the code + RunTimes * runTimes; + + // Memo table that tracks terms already seen + ASTNodeMap TermsAlreadySeenMap; + + //Map for computing ASTNode stats + ASTNodeSet StatInfoSet; + + /**************************************************************** + * Private Member Functions * + ****************************************************************/ + + // 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, + 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: + + /**************************************************************** + * Public Flags * + * FIXME: Make the private. Get rid of this inelegance * + ****************************************************************/ + + // 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; + + // Flags 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; + + //count is used in the creation of new variables + unsigned int _symbol_count; + + /**************************************************************** + * Public Member Functions * + ****************************************************************/ + + // Constructor + BeevMgr() : + _symbol_unique_table(INITIAL_TABLE_SIZE), + _bvconst_unique_table(INITIAL_TABLE_SIZE), + _interior_unique_table(INITIAL_TABLE_SIZE), + _symbol_count(0) + { + _max_node_num = 0; + Begin_RemoveWrites = false; + ValidFlag = false; + bvdiv_exception_occured = false; + counterexample_checking_during_refinement = false; + start_abstracting = false; + Begin_RemoveWrites = false; + SimplifyWrites_InPlace_Flag = false; + + ASTFalse = CreateNode(FALSE); + ASTTrue = CreateNode(TRUE); + ASTUndefined = CreateNode(UNDEFINED); + letmgr = new LETMgr(ASTUndefined); + runTimes = new RunTimes(); + _current_query = ASTUndefined; + } + + //destructor + ~BeevMgr(); + + //Return ptr to let-variables manager (see parser/let-funcs.h) + LETMgr * GetLetMgr(void) + { + return letmgr; + } + + RunTimes * GetRunTimes(void) + { + return runTimes; + } + + void SetRemoveWritesFlag(bool in) + { + Begin_RemoveWrites = in; + } + + bool GetRemoveWritesFlag(void) + { + return Begin_RemoveWrites; + } + + int NewNodeNum() + { + _max_node_num += 2; + return _max_node_num; + } + + //reports node size. Second arg is "clearstatinfo", whatever that + //is. + unsigned int NodeSize(const ASTNode& a, bool t = false); + + /**************************************************************** + * Simplifying create formula functions * + ****************************************************************/ + + // 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); + + 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); + + /**************************************************************** + * Create Symbol and BVConst functions * + ****************************************************************/ + + // 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 CreateOneConst(unsigned int width); + ASTNode CreateTwoConst(unsigned int width); + ASTNode CreateMaxConst(unsigned int width); + ASTNode CreateZeroConst(unsigned int width); + ASTNode CreateBVConst(CBV bv, unsigned width); + ASTNode CreateBVConst(const char *strval, int base); + ASTNode CreateBVConst(string*& strval, int base, int bit_width); + ASTNode CreateBVConst(unsigned int width, unsigned long long int bvconst); + + /**************************************************************** + * Create Node functions * + ****************************************************************/ + + // 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 Term functions * + ****************************************************************/ + + // Create and return an ASTNode for a term + ASTNode CreateTerm(Kind kind, + unsigned int width, + const ASTVec &children = _empty_ASTVec); + ASTNode CreateTerm(Kind kind, + unsigned int width, + const ASTNode& child0, + const ASTVec &children = _empty_ASTVec); + ASTNode CreateTerm(Kind kind, + unsigned int width, + const ASTNode& child0, + const ASTNode& child1, + const ASTVec &children = _empty_ASTVec); + ASTNode CreateTerm(Kind kind, + unsigned int width, + const ASTNode& child0, + const ASTNode& child1, + const ASTNode& child2, + const ASTVec &children = _empty_ASTVec); + + + /**************************************************************** + * Functions that manage logical context * + ****************************************************************/ + + void Pop(void); + void Push(void); + const ASTNode PopQuery(); + const ASTNode GetQuery(); + const ASTVec GetAsserts(void); + void AddQuery(const ASTNode& q); + //add an assertion to the current logical context + void AddAssert(const ASTNode& assert); + + void ClearAllTables(void); + void ClearAllCaches(void); + + /**************************************************************** + * Toplevel printing and stats functions * + ****************************************************************/ + + // For printing purposes + ASTVec ListOfDeclaredVars; + + // Table for DAG printing. + ASTNodeSet AlreadyPrintedSet; + + //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 > NodeLetVarVec; + + // A partial Map from ASTNodes to LetVars. Needed in order to + // correctly print shared subterms inside the LET itself + ASTNodeMap NodeLetVarMap1; + + //prints statistics for the ASTNode. + void ASTNodeStats(const char * c, const ASTNode& a); + + // Print variable to the input stream + void printVarDeclsToStream(ostream &os); + + // Print assertions to the input stream + void printAssertsToStream(ostream &os, int simplify); + + // Prints SAT solver statistics + void PrintStats(MINISAT::Solver& stats); + + // Create New Variables + ASTNode NewVar(unsigned int n); + + bool VarSeenInTerm(const ASTNode& var, const ASTNode& term); + + ASTNode NewParameterized_BooleanVar(const ASTNode& var, + const ASTNode& constant); + + void TermsAlreadySeenMap_Clear(void) + { + TermsAlreadySeenMap.clear(); + } + + };//End of Class BeevMgr +};//end of namespace +#endif diff --git a/src/absrefine_counterexample/AbsRefine_CounterExample.h b/src/absrefine_counterexample/AbsRefine_CounterExample.h new file mode 100644 index 0000000..bb4a655 --- /dev/null +++ b/src/absrefine_counterexample/AbsRefine_CounterExample.h @@ -0,0 +1,213 @@ +// -*- c++ -*- +/******************************************************************** + * AUTHORS: Vijay Ganesh + * + * BEGIN DATE: November, 2005 + * + * LICENSE: Please view LICENSE file in the home dir of this Program + ********************************************************************/ + +#ifndef CTREXAMPLE_H +#define CTREXAMPLE_H + +#include "../AST/AST.h" +#include "../STPManager/STPManager.h" +#include "../simplifier/simplifier.h" +#include "../AST/ArrayTransformer.h" +#include "../to-sat/ToSAT.h" + +namespace BEEV +{ + class AbsRefine_CounterExample + { + private: + + // Handy defs + ASTNode ASTTrue, ASTFalse, ASTUndefined; + + // Data structure that holds the counterexample + ASTNodeMap CounterExampleMap; + + // This map for building/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 *, + ASTNode::ASTNodeHasher, + ASTNode::ASTNodeEqual> ASTtoBitvectorMap; + + ASTtoBitvectorMap _ASTNode_to_Bitvector; + + // This memo map is used by the ComputeFormulaUsingModel() + ASTNodeMap ComputeFormulaMap; + + // Ptr to STPManager + BeevMgr * bm; + + // Ptr to Simplifier + Simplifier * simp; + + // Ptr to ArrayTransformer + ArrayTransformer * ArrayTransform; + + // Ptr to ToSAT + ToSAT * tosat; + + // Checks if the counterexample is good. In order for the + // counterexample to be ok, every assert must evaluate to true + // w.r.t couner_example, and the query must evaluate to + // false. Otherwise we know that the counter_example is bogus. + void CheckCounterExample(bool t); + + // 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); + + void CopySolverMap_To_CounterExample(void); + + //Converts a vector of bools to a BVConst + ASTNode BoolVectoBVConst(hash_map * w, unsigned int l); + + public: + + // Constructor + AbsRefine_CounterExample(BeevMgr * b, + Simplifier * s, + ArrayTransformer * at, + ToSAT * t) : + bm(b), simp(s), ArrayTransform(at), tosat(t) + { + ASTTrue = bm->CreateNode(TRUE); + ASTFalse = bm->CreateNode(FALSE); + ASTUndefined = bm->CreateNode(UNDEFINED); + } + + void ClearCounterExampleMap(void) + { + CounterExampleMap.clear(); + } + + void ClearComputeFormulaMap(void) + { + ComputeFormulaMap.clear(); + } + + //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; + } + + //Computes the truth value of a formula w.r.t counter_example + ASTNode ComputeFormulaUsingModel(const ASTNode& form); + + + // Prints MINISAT assigment one bit at a time, for debugging. + void PrintSATModel(MINISAT::Solver& S); + + /**************************************************************** + * Array Refinement functions * + ****************************************************************/ + SOLVER_RETURN_TYPE + CallSAT_ResultCheck(MINISAT::Solver& SatSolver, + const ASTNode& modified_input, + const ASTNode& original_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); + + SOLVER_RETURN_TYPE + SATBased_ArrayReadRefinement(MINISAT::Solver& newS, + const ASTNode& modified_input, + const ASTNode& original_input); + + SOLVER_RETURN_TYPE + SATBased_ArrayWriteRefinement(MINISAT::Solver& newS, + const ASTNode& orig_input); + + // SOLVER_RETURN_TYPE + // SATBased_AllFiniteLoops_Refinement(MINISAT::Solver& newS, + // const ASTNode& orig_input); + + // ASTVec SATBased_FiniteLoop_Refinement(MINISAT::Solver& + // SatSolver, const ASTNode& original_input, const ASTNode& + // finiteloop, ASTNodeMap* ParamToCurrentValMap, bool + // absrefine_flag=false); + + // ASTNode Check_FiniteLoop_UsingModel(const ASTNode& + // finiteloop, ASTNodeMap* ParamToCurrentValMap, bool + // CheckUsingModel_Or_Expand); + // + // ASTNode Expand_FiniteLoop_TopLevel(const ASTNode& + // finiteloop); ASTNode Check_FiniteLoop_UsingModel(const + // ASTNode& finiteloop); + + };//End of Class CounterExample + + class CompleteCounterExample + { + ASTNodeMap counterexample; + BeevMgr * bv; + public: + CompleteCounterExample(ASTNodeMap a, BeevMgr* beev) : + counterexample(a), bv(beev) + { + } + ASTNode GetCounterExample(ASTNode e) + { + if (BOOLEAN_TYPE == e.GetType() && SYMBOL != e.GetKind()) + { + FatalError("You must input a term or propositional variables\n", e); + } + if (counterexample.find(e) != counterexample.end()) + { + return counterexample[e]; + } + else + { + if (SYMBOL == e.GetKind() && BOOLEAN_TYPE == e.GetType()) + { + return bv->CreateNode(BEEV::FALSE); + } + + if (SYMBOL == e.GetKind()) + { + ASTNode z = bv->CreateZeroConst(e.GetValueWidth()); + return z; + } + + return e; + } + } + };//end of Class CompleteCounterExample +};//end of namespace +#endif diff --git a/src/absrefine_counterexample/AbstractionRefinement.cpp b/src/absrefine_counterexample/AbstractionRefinement.cpp new file mode 100644 index 0000000..838cba7 --- /dev/null +++ b/src/absrefine_counterexample/AbstractionRefinement.cpp @@ -0,0 +1,649 @@ +// -*- c++ -*- +/******************************************************************** + * AUTHORS: Vijay Ganesh + * + * BEGIN DATE: November, 2005 + * + * LICENSE: Please view LICENSE file in the home dir of this Program + ********************************************************************/ + +#include +#include +#include "../AST/AST.h" +#include "../STPManager/STPManager.h" +#include "AbsRefine_CounterExample.h" + +namespace BEEV +{ + + /****************************************************************** + * Abstraction Refinement related functions + ******************************************************************/ + + /****************************************************************** + * ARRAY READ ABSTRACTION REFINEMENT + * + * SATBased_ArrayReadRefinement() + * + * 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), 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). + *****************************************************************/ + SOLVER_RETURN_TYPE + AbsRefine_CounterExample::SATBased_ArrayReadRefinement(MINISAT::Solver& SatSolver, + const ASTNode& inputAlreadyInSAT, + const ASTNode& original_input) { + //printf("doing array read refinement\n"); + if (!arrayread_refinement_flag) + FatalError("SATBased_ArrayReadRefinement: Control should not reach here"); + + ASTVec FalseAxiomsVec, RemainingAxiomsVec; + RemainingAxiomsVec.push_back(ASTTrue); + FalseAxiomsVec.push_back(ASTTrue); + unsigned int oldFalseAxiomsSize = 0; + + //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::const_iterator + iset = ArrayTransform->ArrayName_ReadIndicesMap()->begin(), + iset_end = ArrayTransform->ArrayName_ReadIndicesMap()->end(); + iset != iset_end; iset++) + { + ASTVec listOfIndices = iset->second; + //loop over the list of indices for the array and create LA, + //and add to inputAlreadyInSAT + 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 = + bm->CreateTerm(READ, ArrName.GetValueWidth(), ArrName, the_index); + //get the variable corresponding to the array_read1 + //ASTNode arrsym1 = _arrayread_symbol[arr_read1]; + ASTNode arrsym1 = ArrayTransform->ArrayRead_SymbolMap(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)) ? + simp->CreateSimplifiedEQ(the_index, compare_index) : + simp->CreateSimplifiedEQ(compare_index, the_index); + + ASTNode arr_read2 = + bm->CreateTerm(READ, ArrName.GetValueWidth(), ArrName, compare_index); + //get the variable corresponding to the array_read2 + //ASTNode arrsym2 = _arrayread_symbol[arr_read2]; + ASTNode arrsym2 = ArrayTransform->ArrayRead_SymbolMap(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 = simp->CreateSimplifiedEQ(arrsym1, arrsym2); + //construct appropriate Leibnitz axiom + ASTNode LeibnitzAxiom = bm->CreateNode(IMPLIES, eqOfIndices, eqOfReads); + if (ASTFalse == ComputeFormulaUsingModel(LeibnitzAxiom)) + //FalseAxioms = bm->CreateNode(AND,FalseAxioms,LeibnitzAxiom); + FalseAxiomsVec.push_back(LeibnitzAxiom); + else + //RemainingAxioms = bm->CreateNode(AND,RemainingAxioms,LeibnitzAxiom); + RemainingAxiomsVec.push_back(LeibnitzAxiom); + } + ASTNode FalseAxioms = + (FalseAxiomsVec.size() > 1) ? + bm->CreateNode(AND, FalseAxiomsVec) : FalseAxiomsVec[0]; + bm->ASTNodeStats("adding false readaxioms to SAT: ", FalseAxioms); + //printf("spot 01\n"); + SOLVER_RETURN_TYPE res2 = SOLVER_UNDECIDED; + //if (FalseAxiomsVec.size() > 0) + if (FalseAxiomsVec.size() > oldFalseAxiomsSize) + { + res2 = + CallSAT_ResultCheck(SatSolver, + FalseAxioms, + original_input); + oldFalseAxiomsSize = FalseAxiomsVec.size(); + } + //printf("spot 02, res2 = %d\n", res2); + if (SOLVER_UNDECIDED != res2) + { + return res2; + } + } + } + ASTNode RemainingAxioms = + (RemainingAxiomsVec.size() > 1) ? + bm->CreateNode(AND, RemainingAxiomsVec) : RemainingAxiomsVec[0]; + bm->ASTNodeStats("adding remaining readaxioms to SAT: ", RemainingAxioms); + return CallSAT_ResultCheck(SatSolver, + RemainingAxioms, + original_input); + } //end of SATBased_ArrayReadRefinement + + + /****************************************************************** + * ARRAY WRITE ABSTRACTION REFINEMENT + * + * FIXME: Write Detailed Comment + *****************************************************************/ + SOLVER_RETURN_TYPE + AbsRefine_CounterExample:: + SATBased_ArrayWriteRefinement(MINISAT::Solver& SatSolver, + const ASTNode& original_input) + { + ASTNode writeAxiom; + ASTNodeMap::const_iterator it = simp->ReadOverWriteMap()->begin(); + ASTNodeMap::const_iterator itend = simp->ReadOverWriteMap()->end(); + unsigned int oldFalseAxiomsSize = 0; + //int count = 0; + //int num_write_axioms = ReadOverWrite_NewName_Map.size(); + + ASTVec FalseAxioms, RemainingAxioms; + FalseAxioms.push_back(ASTTrue); + RemainingAxioms.push_back(ASTTrue); + for (; it != itend; it++) + { + //Guided refinement starts here + ClearComputeFormulaMap(); + writeAxiom = Create_ArrayWriteAxioms(it->first, it->second); + if (ASTFalse == ComputeFormulaUsingModel(writeAxiom)) + { + writeAxiom = ArrayTransform->TransformFormula_TopLevel(writeAxiom); + FalseAxioms.push_back(writeAxiom); + } + else + { + writeAxiom = ArrayTransform->TransformFormula_TopLevel(writeAxiom); + RemainingAxioms.push_back(writeAxiom); + } + } + + writeAxiom = + (FalseAxioms.size() != 1) ? + bm->CreateNode(AND, FalseAxioms) : FalseAxioms[0]; + bm->ASTNodeStats("adding false writeaxiom to SAT: ", writeAxiom); + SOLVER_RETURN_TYPE res2 = SOLVER_UNDECIDED; + if (FalseAxioms.size() > oldFalseAxiomsSize) + { + res2 = CallSAT_ResultCheck(SatSolver, + writeAxiom, + original_input); + oldFalseAxiomsSize = FalseAxioms.size(); + } + if (SOLVER_UNDECIDED != res2) + { + return res2; + } + + writeAxiom = + (RemainingAxioms.size() != 1) ? + bm->CreateNode(AND, RemainingAxioms) : RemainingAxioms[0]; + bm->ASTNodeStats("adding remaining writeaxiom to SAT: ", writeAxiom); + res2 = CallSAT_ResultCheck(SatSolver, + writeAxiom, + original_input); + if (SOLVER_UNDECIDED != res2) + { + return res2; + } + + return SOLVER_UNDECIDED; + } //end of SATBased_ArrayWriteRefinement + + //bm->Creates Array Write Axioms + ASTNode AbsRefine_CounterExample::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 = simp->CreateSimplifiedEQ(lhs, rhs); + return arraywrite_axiom; + }//end of Create_ArrayWriteAxioms() + + +// static void ReplaceOrAddToMap(ASTNodeMap * VarToConstMap, +// const ASTNode& key, const ASTNode& value) +// { +// ASTNodeMap::iterator it = VarToConstMap->find(key); +// if(it != VarToConstMap->end()) +// { +// VarToConstMap->erase(it); +// } + +// (*VarToConstMap)[key] = value; +// return; +// } + + +// /****************************************************************** +// * FINITE FORLOOP ABSTRACTION REFINEMENT +// * +// * For each 'finiteloop' in the list 'GlobalList_Of_FiniteLoops' +// * +// * Expand_FiniteLoop(finiteloop); +// * +// * The 'Expand_FiniteLoop' function expands the 'finiteloop' in a +// * counterexample-guided refinement fashion +// * +// * Once all the finiteloops have been expanded, we need to go back +// * and recheck that every discarded constraint is true with the +// * final model. A flag 'done' is set to false if atleast one +// * constraint is false during model-check, and is set to true if all +// * constraints are true during model-check. +// * +// * if the 'done' flag is true, then we terminate this refinement +// * loop. +// *****************************************************************/ +// SOLVER_RETURN_TYPE +// AbsRefine_CounterExample::SATBased_AllFiniteLoops_Refinement(MINISAT::Solver& SatSolver, +// const ASTNode& original_input) +// { +// //cout << "The number of abs-refinement limit is " << num_absrefine << endl; +// for(int absrefine_count=0;absrefine_count < num_absrefine; absrefine_count++) +// { +// ASTVec Allretvec0; +// Allretvec0.push_back(ASTTrue); +// SOLVER_RETURN_TYPE res = SOLVER_UNDECIDED; +// for(ASTVec::iterator i = GlobalList_Of_FiniteLoops.begin(), +// iend=GlobalList_Of_FiniteLoops.end(); i!=iend; i++) +// { +// ASTVec retvec; +// ASTNodeMap ParamToCurrentValMap; +// retvec = SATBased_FiniteLoop_Refinement(SatSolver, +// original_input, +// *i, +// &ParamToCurrentValMap, +// true); //absrefine flag + +// for(ASTVec::iterator j=retvec.begin(),jend=retvec.end();j!=jend;j++) +// { +// Allretvec0.push_back(*j); +// } +// //Allretvec0.(Allretvec0.end(),retvec.begin(),retvec.end()); +// } //End of For + +// ASTNode retformula = +// (Allretvec0.size() == 1) ? +// Allretvec0[0] : bm->CreateNode(AND,Allretvec0); +// retformula = TransformFormula_TopLevel(retformula); + +// //Add the return value of all loops to the SAT Solver +// res = +// CallSAT_ResultCheck(SatSolver, retformula, original_input); +// if(SOLVER_UNDECIDED != res) +// { +// return res; +// } +// } //end of absrefine count + +// ASTVec Allretvec1; +// Allretvec1.push_back(ASTTrue); +// SOLVER_RETURN_TYPE res = SOLVER_UNDECIDED; +// for(ASTVec::iterator i = GlobalList_Of_FiniteLoops.begin(), +// iend=GlobalList_Of_FiniteLoops.end(); i!=iend; i++) +// { +// //cout << "The abs-refine didn't finish the job. Add the remaining formulas\n"; +// ASTNodeMap ParamToCurrentValMap; +// ASTVec retvec; +// retvec = SATBased_FiniteLoop_Refinement(SatSolver, +// original_input, +// *i, +// &ParamToCurrentValMap, +// false); //absrefine flag +// for(ASTVec::iterator j=retvec.begin(),jend=retvec.end();j!=jend;j++) +// { +// Allretvec1.push_back(*j); +// } +// } //End of For + +// ASTNode retformula = +// (Allretvec1.size() == 1) ? +// Allretvec1[0] : bm->CreateNode(AND,Allretvec1); +// retformula = TransformFormula_TopLevel(retformula); +// //Add the return value of all loops to the SAT Solver +// res = CallSAT_ResultCheck(SatSolver, retformula, original_input); +// return res; +// } //end of SATBased_AllFiniteLoops_Refinement() + + +// /***************************************************************** +// * SATBased_FiniteLoop_Refinement +// * +// * 'finiteloop' is the finite loop to be expanded +// * Every finiteloop has three parts: +// * 0) Parameter Name +// * 1) Parameter initialization +// * 2) Parameter limit value +// * 3) Increment formula +// * 4) Formula Body +// * +// * ParamToCurrentValMap contains a map from parameters to their +// * current values in the recursion +// * +// * Nested FORs are allowed, but only the innermost loop can have a +// * formula in it +// *****************************************************************/ +// //SATBased_FiniteLoop_Refinement +// // +// //Expand the finite loop, check against model, and add false +// //formulas to the SAT solver +// ASTVec +// AbsRefine_CounterExample::SATBased_FiniteLoop_Refinement(MINISAT::Solver& SatSolver, +// const ASTNode& original_input, +// const ASTNode& finiteloop, +// ASTNodeMap* ParamToCurrentValMap, +// bool absrefine_flag) +// { +// //BVTypeCheck should have already checked the sanity of the input +// //FOR-formula +// ASTNode parameter = finiteloop[0]; +// int paramInit = GetUnsignedConst(finiteloop[1]); +// int paramLimit = GetUnsignedConst(finiteloop[2]); +// int paramIncrement = GetUnsignedConst(finiteloop[3]); +// ASTNode exceptFormula = finiteloop[4]; +// ASTNode formulabody = finiteloop[5]; +// int paramCurrentValue = paramInit; +// int width = finiteloop[1].GetValueWidth(); + +// //Update ParamToCurrentValMap with parameter and its current +// //value. Here paramCurrentValue is the initial value +// ASTNode value = +// bm->CreateBVConst(width,paramCurrentValue); +// ReplaceOrAddToMap(ParamToCurrentValMap, parameter, value); + +// //Go recursively thru' all the FOR-constructs. +// if(FOR == formulabody.GetKind()) +// { +// ASTVec retvec; +// ASTVec retvec_innerfor; +// retvec.push_back(ASTTrue); +// while(paramCurrentValue < paramLimit) +// { +// retvec_innerfor = +// SATBased_FiniteLoop_Refinement(SatSolver, +// original_input, +// formulabody, +// ParamToCurrentValMap, +// absrefine_flag); + +// for(ASTVec::iterator i=retvec_innerfor.begin(), +// iend=retvec_innerfor.end();i!=iend;i++) +// { +// retvec.push_back(*i); +// } + +// //Update ParamToCurrentValMap with parameter and its +// //current value. +// paramCurrentValue = paramCurrentValue + paramIncrement; +// value = bm->CreateTerm(BVPLUS, +// width, +// (*ParamToCurrentValMap)[parameter], +// bm->CreateOneConst(width)); +// ReplaceOrAddToMap(ParamToCurrentValMap, parameter, value); +// } //end of While + +// return retvec; +// } //end of recursion FORs + +// //Expand the leaf level FOR-construct completely +// //increment of paramCurrentValue done inside loop +// int ThisForLoopAllTrue = 0; +// ASTVec ForloopVec; +// ForloopVec.push_back(ASTTrue); +// for(;paramCurrentValue < paramLimit;) +// { +// ASTNode currentFormula; +// ASTNode currentExceptFormula = exceptFormula; +// currentExceptFormula = +// SimplifyFormula(exceptFormula, false, ParamToCurrentValMap); +// if(ASTTrue == currentExceptFormula) +// { +// currentFormula = ASTTrue; +// } +// else +// { +// currentFormula = +// SimplifyFormula(formulabody, false, ParamToCurrentValMap); +// } + +// //Check the currentformula against the model, and add it to the +// //SAT solver if it is false against the model +// if(absrefine_flag +// && +// ASTFalse == ComputeFormulaUsingModel(currentFormula) +// ) +// { +// ForloopVec.push_back(currentFormula); +// } +// else +// { +// if(ASTTrue != currentFormula) +// { +// ForloopVec.push_back(currentFormula); +// } +// if(ASTFalse == currentFormula) +// { +// ForloopVec.push_back(ASTFalse); +// return ForloopVec; +// } +// } + +// //Update ParamToCurrentValMap with parameter and its current +// //value. +// paramCurrentValue = paramCurrentValue + paramIncrement; +// value = bm->CreateTerm(BVPLUS, +// width, +// (*ParamToCurrentValMap)[parameter], +// bm->CreateOneConst(width)); +// ReplaceOrAddToMap(ParamToCurrentValMap, parameter, value); +// } //end of expanding the FOR loop + +// return ForloopVec; +// } //end of the SATBased_FiniteLoop_Refinement() + +// //SATBased_FiniteLoop_Refinement_UsingModel(). Expand the finite +// //loop, check against model +// ASTNode +// AbsRefine_CounterExample::Check_FiniteLoop_UsingModel(const ASTNode& finiteloop, +// ASTNodeMap* ParamToCurrentValMap, +// bool checkusingmodel_flag = true) +// { +// /* +// * 'finiteloop' is the finite loop to be expanded +// * Every finiteloop has three parts: +// * 0) Parameter Name +// * 1) Parameter initialization +// * 2) Parameter limit value +// * 3) Increment formula +// * 4) Formula Body +// * +// * ParamToCurrentValMap contains a map from parameters to their +// * current values in the recursion +// * +// * Nested FORs are allowed, but only the innermost loop can have a +// * formula in it +// */ + +// //BVTypeCheck should have already checked the sanity of the input +// //FOR-formula +// ASTNode parameter = finiteloop[0]; +// int paramInit = GetUnsignedConst(finiteloop[1]); +// int paramLimit = GetUnsignedConst(finiteloop[2]); +// int paramIncrement = GetUnsignedConst(finiteloop[3]); +// ASTNode exceptFormula = finiteloop[4]; +// ASTNode formulabody = finiteloop[5]; +// int paramCurrentValue = paramInit; +// int width = finiteloop[1].GetValueWidth(); + +// //Update ParamToCurrentValMap with parameter and its current +// //value. Here paramCurrentValue is the initial value +// ASTNode value = +// bm->CreateBVConst(width,paramCurrentValue); +// ReplaceOrAddToMap(ParamToCurrentValMap, parameter, value); + +// ASTNode ret = ASTTrue; +// ASTVec returnVec; +// //Go recursively thru' all the FOR-constructs. +// if(FOR == formulabody.GetKind()) +// { +// while(paramCurrentValue < paramLimit) +// { +// ret = Check_FiniteLoop_UsingModel(formulabody, +// ParamToCurrentValMap, +// checkusingmodel_flag); +// if(ASTFalse == ret) +// { +// //no more expansion needed. Return immediately +// return ret; +// } +// else +// { +// returnVec.push_back(ret); +// } + +// //Update ParamToCurrentValMap with parameter and its +// //current value. +// paramCurrentValue = paramCurrentValue + paramIncrement; +// value = bm->CreateTerm(BVPLUS, +// width, +// (*ParamToCurrentValMap)[parameter], +// bm->CreateOneConst(width)); +// ReplaceOrAddToMap(ParamToCurrentValMap, parameter, value); +// } //end of While + +// ASTNode retFormula = +// (returnVec.size() > 1) ? +// bm->CreateNode(AND, returnVec) : +// (returnVec.size() == 1) ? +// returnVec[0] : +// ASTTrue; +// return retFormula; +// } + +// ASTVec forloopFormulaVector; +// //Expand the leaf level FOR-construct completely +// //incrementing of paramCurrentValue is done inside loop +// for(;paramCurrentValue < paramLimit;) +// { +// ASTNode currentFormula; + +// ASTNode currentExceptFormula = exceptFormula; +// currentExceptFormula = +// SimplifyFormula(exceptFormula, false, ParamToCurrentValMap); +// if(ASTTrue == currentExceptFormula) +// { +// currentFormula = ASTTrue; +// //continue; +// } +// else +// { +// currentFormula = +// SimplifyFormula(formulabody, false, ParamToCurrentValMap); +// } + +// if(checkusingmodel_flag) +// { +// //Check the currentformula against the model, and return +// //immediately +// //cout << "Printing current Formula: " << currentFormula << "\n"; +// ASTNode computedForm = ComputeFormulaUsingModel(currentFormula); +// //cout << "Printing computed Formula: " << computedForm << "\n"; +// if(ASTFalse == computedForm) +// { +// return ASTFalse; +// } +// } +// else +// { +// if(ASTTrue != currentFormula) +// { +// forloopFormulaVector.push_back(currentFormula); +// } +// } + +// //Update ParamToCurrentValMap with parameter and its current +// //value +// paramCurrentValue = paramCurrentValue + paramIncrement; +// value = bm->CreateTerm(BVPLUS, +// width, +// (*ParamToCurrentValMap)[parameter], +// bm->CreateOneConst(width)); +// ReplaceOrAddToMap(ParamToCurrentValMap, parameter, value); +// } //end of For + +// if(checkusingmodel_flag) +// { +// return ASTTrue; +// } +// else +// { +// ASTNode retFormula = +// (forloopFormulaVector.size() > 1) ? +// bm->CreateNode(AND, forloopFormulaVector) : +// (forloopFormulaVector.size() == 1) ? +// forloopFormulaVector[0] : +// ASTTrue; +// return retFormula; +// } +// } //end of the Check_FiniteLoop_UsingModel() + + +// //Expand_FiniteLoop_For_ModelCheck +// ASTNode +// AbsRefine_CounterExample::Expand_FiniteLoop_TopLevel(const ASTNode& finiteloop) +// { +// ASTNodeMap ParamToCurrentValMap; +// return Check_FiniteLoop_UsingModel(finiteloop, +// &ParamToCurrentValMap, false); +// } //end of Expand_FiniteLoop_TopLevel() + +// ASTNode +// AbsRefine_CounterExample::Check_FiniteLoop_UsingModel(const ASTNode& finiteloop) +// { +// ASTNodeMap ParamToCurrentValMap; +// return Check_FiniteLoop_UsingModel(finiteloop, +// &ParamToCurrentValMap, true); +// } //end of Check_FiniteLoop_UsingModel +};// end of namespace BEEV diff --git a/src/absrefine_counterexample/CounterExample.cpp b/src/absrefine_counterexample/CounterExample.cpp new file mode 100644 index 0000000..53f613c --- /dev/null +++ b/src/absrefine_counterexample/CounterExample.cpp @@ -0,0 +1,968 @@ +// -*- c++ -*- +/******************************************************************** + * AUTHORS: Vijay Ganesh + * + * BEGIN DATE: November, 2005 + * + * LICENSE: Please view LICENSE file in the home dir of this Program + ********************************************************************/ + +#include "../sat/sat.h" +#include "AbsRefine_CounterExample.h" + +namespace BEEV +{ + + /*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 AbsRefine_CounterExample::ConstructCounterExample(MINISAT::Solver& newS) + { + //iterate over MINISAT counterexample and construct a map from AST + //terms to vector of bools. We need this iteration step because + //MINISAT might return the various bits of a term out of + //order. Therfore, we need to collect all the bits and assemble + //them properly + + if (!newS.okay()) + return; + if (!construct_counterexample_flag) + return; + + CopySolverMap_To_CounterExample(); + for (int i = 0; i < newS.nVars(); i++) + { + //Make sure that the MINISAT::Var is defined + if (newS.model[i] != MINISAT::l_Undef) + { + + //mapping from MINISAT::Vars to ASTNodes. We do not need to + //print MINISAT vars or CNF vars. + ASTNode s = tosat->SATVar_to_ASTMap(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 * v; + if (_ASTNode_to_Bitvector.find(symbol) == _ASTNode_to_Bitvector.end()) + _ASTNode_to_Bitvector[symbol] = + new hash_map (symbolWidth); + + //v holds the map from bit-index to bit-value + v = _ASTNode_to_Bitvector[symbol]; + + //kk is the index of BVGETBIT + unsigned int kk = GetUnsignedConst(s[1]); + + //Collect the bits of 'symbol' and store in v. Store in reverse order. + if (newS.model[i] == MINISAT::l_True) + (*v)[(symbolWidth - 1) - kk] = true; + else + (*v)[(symbolWidth - 1) - kk] = false; + } + else + { + if (s.GetKind() == SYMBOL && s.GetType() == BOOLEAN_TYPE) + { + const char * zz = s.GetName(); + //if the variables are not cnf variables then add them to the counterexample + if (0 != strncmp("cnf", zz, 3) && 0 != strcmp("*TrueDummy*", zz)) + { + if (newS.model[i] == MINISAT::l_True) + CounterExampleMap[s] = ASTTrue; + else if (newS.model[i] == MINISAT::l_False) + CounterExampleMap[s] = ASTFalse; + else + { + int seed = 10000; + srand(seed); + CounterExampleMap[s] = (rand() > seed) ? ASTFalse : ASTTrue; + } + } + } + } + } + } + + //iterate over the ASTNode_to_Bitvector data-struct and construct + //the the aggregate value of the bitvector, and populate the + //CounterExampleMap datastructure + for (ASTtoBitvectorMap::iterator it = _ASTNode_to_Bitvector.begin(), + itend = _ASTNode_to_Bitvector.end(); it != itend; it++) + { + ASTNode var = it->first; + //debugging + //cerr << var; + if (SYMBOL != var.GetKind()) + FatalError("ConstructCounterExample: error while constructing counterexample: not a variable: ", var); + + //construct the bitvector value + hash_map * 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::const_iterator + it = ArrayTransform->ArrayRead_IteMap()->begin(), + itend = ArrayTransform->ArrayRead_IteMap()->end(); + it != itend; it++) + { + //the array read + ASTNode arrayread = it->first; + ASTNode value_ite = ArrayTransform->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 = bm->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 (!simp->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 AbsRefine_CounterExample::TermToConstTermUsingModel(const ASTNode& t, bool ArrayReadFlag) + { + bm->Begin_RemoveWrites = false; + bm->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 = bm->CreateZeroConst(term.GetValueWidth()); + output = zero; + break; + } + case READ: + { + ASTNode arrName = term[0]; + ASTNode index = term[1]; + if (0 == arrName.GetIndexWidth()) + { + FatalError("TermToConstTermUsingModel: array has 0 index width: ", arrName); + } + + + if (WRITE == arrName.GetKind()) //READ over a WRITE + { + ASTNode wrtterm = Expand_ReadOverWrite_UsingModel(term, ArrayReadFlag); + if (wrtterm == term) + { + FatalError("TermToConstTermUsingModel: Read_Over_Write term must be expanded into an ITE", term); + } + ASTNode rtterm = TermToConstTermUsingModel(wrtterm, ArrayReadFlag); + assert(ArrayReadFlag || (BVCONST == rtterm.GetKind())); + return rtterm; + } + else if (ITE == arrName.GetKind()) //READ over an ITE + { + // The "then" and "else" branch are arrays. + ASTNode indexVal = TermToConstTermUsingModel(index, ArrayReadFlag); + + ASTNode condcompute = ComputeFormulaUsingModel(arrName[0]); // Get the truth value. + if (ASTTrue == condcompute) + { + const ASTNode & result = TermToConstTermUsingModel(bm->CreateTerm(READ, arrName.GetValueWidth(), arrName[1], indexVal), ArrayReadFlag); + assert(ArrayReadFlag || (BVCONST == result.GetKind())); + return result; + } + else if (ASTFalse == condcompute) + { + const ASTNode & result = TermToConstTermUsingModel(bm->CreateTerm(READ, arrName.GetValueWidth(), arrName[2], indexVal), ArrayReadFlag); + assert(ArrayReadFlag || (BVCONST == result.GetKind())); + return result; + } + else + { + cerr << "TermToConstTermUsingModel: termITE: value of conditional is wrong: " << condcompute << endl; + FatalError(" TermToConstTermUsingModel: termITE: cannot compute ITE conditional against model: ", term); + } + FatalError("bn23143 Never Here"); + } + + ASTNode modelentry; + if (CounterExampleMap.find(index) != CounterExampleMap.end()) + { + //index has a const value in the CounterExampleMap + //ASTNode indexVal = CounterExampleMap[index]; + ASTNode indexVal = TermToConstTermUsingModel(CounterExampleMap[index], ArrayReadFlag); + modelentry = bm->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 = bm->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 = bm->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 = bm->CreateTerm(k, term.GetValueWidth(), o); + //output is a CONST expression. compute its value and store it + //in the CounterExampleMap + ASTNode oo = simp->BVConstEvaluator(output); + //the return value + output = oo; + break; + } + } + + assert(ArrayReadFlag || (BVCONST == output.GetKind())); + + //when this flag is false, we should compute the arrayread to a + //constant. this constant is stored in the counter_example + //datastructure + if (!ArrayReadFlag) + { + CounterExampleMap[term] = output; + } + + //cerr << "Output to TermToConstTermUsingModel: " << output << endl; + return output; + } //End of TermToConstTermUsingModel + + //Expands read-over-write by evaluating (readIndex=writeIndex) for + //every writeindex until, either it evaluates to TRUE or all + //(readIndex=writeIndex) evaluate to FALSE + ASTNode AbsRefine_CounterExample::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(simp->CreateSimplifiedEQ(writeIndex, readIndex)); + if (ASTTrue == cond) + { + //found the write-value. return it + output = writeVal; + CounterExampleMap[term] = output; + return output; + } + + newRead = bm->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 AbsRefine_CounterExample::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 (!bm->VarSeenInTerm(form, counterexample_val)) + { + output = ComputeFormulaUsingModel(counterexample_val); + } + else + { + output = counterexample_val; + } + } + else + { + CounterExampleMap[form] = ASTFalse; + output = ASTFalse; + } + break; + case EQ: + 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 = simp->BVConstEvaluator(bm->CreateNode(k, t0, t1)); + + //evaluate formula to false if bvdiv execption occurs while + //counterexample is being checked during refinement. + if (bm->bvdiv_exception_occured + && bm->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; + case PARAMBOOL: + output = bm->NewParameterized_BooleanVar(form[0],form[1]); + output = ComputeFormulaUsingModel(output); + break; + case FOR: + //output = Check_FiniteLoop_UsingModel(form); + output = ASTTrue; + break; + default: + FatalError(" ComputeFormulaUsingModel: "\ + "the kind has not been implemented", ASTUndefined); + break; + } + + //cout << "ComputeFormulaUsingModel output is:" << output << endl; + ComputeFormulaMap[form] = output; + return output; + } + + void AbsRefine_CounterExample::CheckCounterExample(bool t) + { + // FIXME: Code is more useful if enable flags are check OUTSIDE the method. + // If I want to check a counterexample somewhere, I don't want to have to set + // the flag in order to make it actualy happen! + + printf("checking counterexample\n"); + if (!check_counterexample_flag) + { + return; + } + + //input is valid, no counterexample to check + if (bm->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 = bm->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(bm->GetQuery())) + FatalError("CheckCounterExample:counterexample bogus:" + "query evaluates to TRUE under counterexample: NOT OK", bm->GetQuery()); + } + + /* FUNCTION: queries the CounterExampleMap object with 'expr' and + * returns the corresponding counterexample value. + */ + ASTNode AbsRefine_CounterExample::GetCounterExample(bool t, const ASTNode& expr) + { + //input is valid, no counterexample to get + if (bm->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 = bm->CreateZeroConst(expr.GetValueWidth()); + return output; + } //End of GetCounterExample + + // FUNCTION: prints a counterexample for INVALID inputs. iterate + // through the CounterExampleMap data structure and print it to + // stdout + void AbsRefine_CounterExample::PrintCounterExample(bool t, std::ostream& os) + { + //global command-line option + // FIXME: This should always print the counterexample. If you want + // to turn it off, check the switch at the point of call. + if (!print_counterexample_flag) + { + return; + } + + //input is valid, no counterexample to print + if (bm->ValidFlag) + { + return; + } + + //if this option is true then print the way dawson wants using a + //different printer. do not use this printer. + if (print_arrayval_declaredorder_flag) + { + return; + } + + //t is true if SAT solver generated a counterexample, else it is + //false + if (!t) + { + cerr << "PrintCounterExample: No CounterExample to print: " << endl; + return; + } + + //os << "\nCOUNTEREXAMPLE: \n" << endl; + ASTNodeMap::iterator it = CounterExampleMap.begin(); + ASTNodeMap::iterator itend = CounterExampleMap.end(); + for (; it != itend; it++) + { + ASTNode f = it->first; + ASTNode se = it->second; + + if (ARRAY_TYPE == se.GetType()) + { + FatalError("TermToConstTermUsingModel: "\ + "entry in counterexample is an arraytype. bogus:", se); + } + + //skip over introduced variables + if (f.GetKind() == SYMBOL && + (ArrayTransform->FoundIntroducedSymbolSet(f))) + { + continue; + } + if (f.GetKind() == SYMBOL || + (f.GetKind() == READ && + f[0].GetKind() == SYMBOL && + f[1].GetKind() == BVCONST)) + { + os << "ASSERT( "; + f.PL_Print(os,0); + if(BOOLEAN_TYPE == f.GetType()) + { + os << "<=>"; + } + else + { + 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 AbsRefine_CounterExample::PrintCounterExample_InOrder(bool t) + { + //global command-line option to print counterexample. we do not + //want both counterexample printers to print at the sametime. + // FIXME: This should always print the counterexample. If you want + // to turn it off, check the switch at the point of call. + if (print_counterexample_flag) + return; + + //input is valid, no counterexample to print + if (bm->ValidFlag) + return; + + //print if the commandline option is '-q'. allows printing the + //counterexample in order. + if (!print_arrayval_declaredorder_flag) + return; + + //t is true if SAT solver generated a counterexample, else it is + //false + if (!t) + { + cerr << "PrintCounterExample: No CounterExample to print: " << endl; + return; + } + + //vector to store the integer values + std::vector out_int; + cout << "% "; + for (ASTVec::iterator it = bm->ListOfDeclaredVars.begin(), + itend = bm->ListOfDeclaredVars.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 = bm->CreateBVConst(it->GetIndexWidth(), j); + ASTNode readexpr = bm->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 + + // Prints Satisfying assignment directly, for debugging. + void AbsRefine_CounterExample::PrintSATModel(MINISAT::Solver& newS) + { + if (!newS.okay()) + FatalError("PrintSATModel: NO COUNTEREXAMPLE TO PRINT", ASTUndefined); + // FIXME: Don't put tests like this in the print functions. The print functions + // should print unconditionally. Put a conditional around the call if you don't + // want them to print + if (!(stats_flag && print_nodes_flag)) + return; + + int num_vars = newS.nVars(); + cout << "Satisfying assignment: " << endl; + for (int i = 0; i < num_vars; i++) + { + if (newS.model[i] == MINISAT::l_True) + { + ASTNode s = tosat->SATVar_to_ASTMap(i); + cout << s << endl; + } + else if (newS.model[i] == MINISAT::l_False) + { + ASTNode s = tosat->SATVar_to_ASTMap(i); + cout << bm->CreateNode(NOT, s) << endl; + } + } + } //end of PrintSATModel() + + //FUNCTION: this function accepts a boolvector and returns a BVConst + ASTNode AbsRefine_CounterExample::BoolVectoBVConst(hash_map * 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 bm->CreateBVConst(cc.c_str(), 2); + } //end of BoolVectoBVConst() + + void AbsRefine_CounterExample::CopySolverMap_To_CounterExample(void) + { + + if (!simp->Return_SolverMap()->empty()) + { + CounterExampleMap.insert(simp->Return_SolverMap()->begin(), + simp->Return_SolverMap()->end()); + } + } + +SOLVER_RETURN_TYPE + AbsRefine_CounterExample:: + CallSAT_ResultCheck(MINISAT::Solver& SatSolver, + const ASTNode& modified_input, + const ASTNode& original_input) + { + bool sat = tosat->CallSAT(SatSolver, + modified_input, + original_input); + if (!sat) + { + //PrintOutput(true); + return SOLVER_VALID; + } + else if (SatSolver.okay()) + { + CounterExampleMap.clear(); + ConstructCounterExample(SatSolver); + if (stats_flag && print_nodes_flag) + { + PrintSATModel(SatSolver); + } + //check if the counterexample is good or not + ComputeFormulaMap.clear(); + if (bm->counterexample_checking_during_refinement) + bm->bvdiv_exception_occured = false; + ASTNode orig_result = ComputeFormulaUsingModel(original_input); + if (!(ASTTrue == orig_result || ASTFalse == orig_result)) + FatalError("TopLevelSat: Original input must compute to "\ + "true or false against model"); + + // if the counterexample is indeed a good one, then return + // invalid + if (ASTTrue == orig_result) + { + //CheckCounterExample(SatSolver.okay()); + //PrintOutput(false); + PrintCounterExample(SatSolver.okay()); + PrintCounterExample_InOrder(SatSolver.okay()); + return SOLVER_INVALID; + } + // counterexample is bogus: flag it + else + { + if (stats_flag && print_nodes_flag) + { + cout << "Supposedly bogus one: \n"; + bool tmp = print_counterexample_flag; + print_counterexample_flag = true; + PrintCounterExample(true); + print_counterexample_flag = tmp; + } + + return SOLVER_UNDECIDED; + } + } + else + { + //Control should never reach here + //PrintOutput(true); + return SOLVER_ERROR; + } + } //end of CALLSAT_ResultCheck() +}; diff --git a/src/abstraction-refinement/Makefile b/src/absrefine_counterexample/Makefile similarity index 85% rename from src/abstraction-refinement/Makefile rename to src/absrefine_counterexample/Makefile index 68f2884..11db03c 100644 --- a/src/abstraction-refinement/Makefile +++ b/src/absrefine_counterexample/Makefile @@ -2,6 +2,7 @@ include ../../scripts/Makefile.common SRCS = $(wildcard *.cpp) OBJS = $(SRCS:.cpp=.o) +CFLAGS += -I../sat/mtl -I../sat/simp -I../sat/core libabstractionrefinement.a: $(OBJS) depend $(AR) rc $@ $(OBJS) diff --git a/src/abstraction-refinement/AbstractionRefinement.cpp b/src/abstraction-refinement/AbstractionRefinement.cpp deleted file mode 100644 index a3b4998..0000000 --- a/src/abstraction-refinement/AbstractionRefinement.cpp +++ /dev/null @@ -1,635 +0,0 @@ -// -*- c++ -*- -/******************************************************************** - * AUTHORS: Vijay Ganesh - * - * BEGIN DATE: November, 2005 - * - * LICENSE: Please view LICENSE file in the home dir of this Program - ********************************************************************/ - -#include -#include -#include "../AST/AST.h" -#include "../STPManager/STPManager.h" - -namespace BEEV -{ - - /****************************************************************** - * Abstraction Refinement related functions - ******************************************************************/ - - /****************************************************************** - * ARRAY READ ABSTRACTION REFINEMENT - * - * SATBased_ArrayReadRefinement() - * - * 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), 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). - *****************************************************************/ - SOLVER_RETURN_TYPE - BeevMgr::SATBased_ArrayReadRefinement(MINISAT::Solver& SatSolver, - const ASTNode& inputAlreadyInSAT, - const ASTNode& original_input) { - //printf("doing array read refinement\n"); - if (!arrayread_refinement_flag) - FatalError("SATBased_ArrayReadRefinement: Control should not reach here"); - - ASTVec FalseAxiomsVec, RemainingAxiomsVec; - RemainingAxiomsVec.push_back(ASTTrue); - FalseAxiomsVec.push_back(ASTTrue); - unsigned int oldFalseAxiomsSize = 0; - - //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 inputAlreadyInSAT - for (ASTVec::iterator it = listOfIndices.begin(), - itend = listOfIndices.end(); it != itend; it++) - { - if (BVCONST == it->GetKind()) - { - continue; - } - - ASTNode the_index = *it; - //get the arrayname - ASTNode ArrName = iset->first; - // if(SYMBOL != ArrName.GetKind()) - // FatalError("SATBased_ArrayReadRefinement: "\ - // "arrname is not a SYMBOL",ArrName); - ASTNode arr_read1 = - CreateTerm(READ, ArrName.GetValueWidth(), ArrName, the_index); - //get the variable corresponding to the array_read1 - ASTNode arrsym1 = _arrayread_symbol[arr_read1]; - if (!(SYMBOL == arrsym1.GetKind() || BVCONST == arrsym1.GetKind())) - FatalError("TopLevelSAT: refinementloop:" - "term arrsym1 corresponding to READ must be a var", arrsym1); - - //we have nonconst index here. create Leibnitz axiom for it - //w.r.t every index in listOfIndices - for (ASTVec::iterator it1 = listOfIndices.begin(), - itend1 = listOfIndices.end(); it1 != itend1; it1++) - { - ASTNode compare_index = *it1; - //do not compare with yourself - if (the_index == compare_index) - continue; - - //prepare for SAT LOOP - //first construct the antecedent for the LA axiom - ASTNode eqOfIndices = - (exprless(the_index, compare_index)) ? - CreateSimplifiedEQ(the_index, compare_index) : - CreateSimplifiedEQ(compare_index, the_index); - - ASTNode arr_read2 = - CreateTerm(READ, ArrName.GetValueWidth(), ArrName, compare_index); - //get the variable corresponding to the array_read2 - ASTNode arrsym2 = _arrayread_symbol[arr_read2]; - if (!(SYMBOL == arrsym2.GetKind() || BVCONST == arrsym2.GetKind())) - FatalError("TopLevelSAT: refinement loop:" - "term arrsym2 corresponding to READ must be a var", arrsym2); - - ASTNode eqOfReads = CreateSimplifiedEQ(arrsym1, arrsym2); - //construct appropriate Leibnitz axiom - ASTNode LeibnitzAxiom = CreateNode(IMPLIES, eqOfIndices, eqOfReads); - if (ASTFalse == ComputeFormulaUsingModel(LeibnitzAxiom)) - //FalseAxioms = CreateNode(AND,FalseAxioms,LeibnitzAxiom); - FalseAxiomsVec.push_back(LeibnitzAxiom); - else - //RemainingAxioms = CreateNode(AND,RemainingAxioms,LeibnitzAxiom); - RemainingAxiomsVec.push_back(LeibnitzAxiom); - } - ASTNode FalseAxioms = - (FalseAxiomsVec.size() > 1) ? - CreateNode(AND, FalseAxiomsVec) : FalseAxiomsVec[0]; - ASTNodeStats("adding false readaxioms to SAT: ", FalseAxioms); - //printf("spot 01\n"); - SOLVER_RETURN_TYPE res2 = SOLVER_UNDECIDED; - //if (FalseAxiomsVec.size() > 0) - if (FalseAxiomsVec.size() > oldFalseAxiomsSize) - { - res2 = - CallSAT_ResultCheck(SatSolver, FalseAxioms, original_input); - oldFalseAxiomsSize = FalseAxiomsVec.size(); - } - //printf("spot 02, res2 = %d\n", res2); - if (SOLVER_UNDECIDED != res2) - { - return res2; - } - } - } - ASTNode RemainingAxioms = - (RemainingAxiomsVec.size() > 1) ? - CreateNode(AND, RemainingAxiomsVec) : RemainingAxiomsVec[0]; - ASTNodeStats("adding remaining readaxioms to SAT: ", RemainingAxioms); - return CallSAT_ResultCheck(SatSolver, RemainingAxioms, original_input); - } //end of SATBased_ArrayReadRefinement - - - /****************************************************************** - * ARRAY WRITE ABSTRACTION REFINEMENT - * - * FIXME: Write Detailed Comment - *****************************************************************/ - SOLVER_RETURN_TYPE - BeevMgr::SATBased_ArrayWriteRefinement(MINISAT::Solver& SatSolver, - const ASTNode& original_input) - { - ASTNode writeAxiom; - ASTNodeMap::iterator it = ReadOverWrite_NewName_Map.begin(); - ASTNodeMap::iterator itend = ReadOverWrite_NewName_Map.end(); - unsigned int oldFalseAxiomsSize = 0; - //int count = 0; - //int num_write_axioms = ReadOverWrite_NewName_Map.size(); - - ASTVec FalseAxioms, RemainingAxioms; - FalseAxioms.push_back(ASTTrue); - RemainingAxioms.push_back(ASTTrue); - for (; it != itend; it++) - { - //Guided refinement starts here - ComputeFormulaMap.clear(); - writeAxiom = Create_ArrayWriteAxioms(it->first, it->second); - if (ASTFalse == ComputeFormulaUsingModel(writeAxiom)) - { - writeAxiom = TransformFormula_TopLevel(writeAxiom); - FalseAxioms.push_back(writeAxiom); - } - else - { - writeAxiom = TransformFormula_TopLevel(writeAxiom); - RemainingAxioms.push_back(writeAxiom); - } - } - - writeAxiom = - (FalseAxioms.size() != 1) ? - CreateNode(AND, FalseAxioms) : FalseAxioms[0]; - ASTNodeStats("adding false writeaxiom to SAT: ", writeAxiom); - SOLVER_RETURN_TYPE res2 = SOLVER_UNDECIDED; - if (FalseAxioms.size() > oldFalseAxiomsSize) - { - res2 = CallSAT_ResultCheck(SatSolver, writeAxiom, original_input); - oldFalseAxiomsSize = FalseAxioms.size(); - } - if (SOLVER_UNDECIDED != res2) - { - return res2; - } - - writeAxiom = - (RemainingAxioms.size() != 1) ? - CreateNode(AND, RemainingAxioms) : RemainingAxioms[0]; - ASTNodeStats("adding remaining writeaxiom to SAT: ", writeAxiom); - res2 = CallSAT_ResultCheck(SatSolver, writeAxiom, original_input); - if (SOLVER_UNDECIDED != res2) - { - return res2; - } - - return SOLVER_UNDECIDED; - } //end of SATBased_ArrayWriteRefinement - - //Creates Array Write Axioms - 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() - - - static void ReplaceOrAddToMap(ASTNodeMap * VarToConstMap, - const ASTNode& key, const ASTNode& value) - { - ASTNodeMap::iterator it = VarToConstMap->find(key); - if(it != VarToConstMap->end()) - { - VarToConstMap->erase(it); - } - - (*VarToConstMap)[key] = value; - return; - } - - - /****************************************************************** - * FINITE FORLOOP ABSTRACTION REFINEMENT - * - * For each 'finiteloop' in the list 'GlobalList_Of_FiniteLoops' - * - * Expand_FiniteLoop(finiteloop); - * - * The 'Expand_FiniteLoop' function expands the 'finiteloop' in a - * counterexample-guided refinement fashion - * - * Once all the finiteloops have been expanded, we need to go back - * and recheck that every discarded constraint is true with the - * final model. A flag 'done' is set to false if atleast one - * constraint is false during model-check, and is set to true if all - * constraints are true during model-check. - * - * if the 'done' flag is true, then we terminate this refinement - * loop. - *****************************************************************/ - SOLVER_RETURN_TYPE - BeevMgr::SATBased_AllFiniteLoops_Refinement(MINISAT::Solver& SatSolver, - const ASTNode& original_input) - { - //cout << "The number of abs-refinement limit is " << num_absrefine << endl; - for(int absrefine_count=0;absrefine_count < num_absrefine; absrefine_count++) - { - ASTVec Allretvec0; - Allretvec0.push_back(ASTTrue); - SOLVER_RETURN_TYPE res = SOLVER_UNDECIDED; - for(ASTVec::iterator i = GlobalList_Of_FiniteLoops.begin(), - iend=GlobalList_Of_FiniteLoops.end(); i!=iend; i++) - { - ASTVec retvec; - ASTNodeMap ParamToCurrentValMap; - retvec = SATBased_FiniteLoop_Refinement(SatSolver, - original_input, - *i, - &ParamToCurrentValMap, - true); //absrefine flag - - for(ASTVec::iterator j=retvec.begin(),jend=retvec.end();j!=jend;j++) - { - Allretvec0.push_back(*j); - } - //Allretvec0.(Allretvec0.end(),retvec.begin(),retvec.end()); - } //End of For - - ASTNode retformula = - (Allretvec0.size() == 1) ? - Allretvec0[0] : CreateNode(AND,Allretvec0); - retformula = TransformFormula_TopLevel(retformula); - - //Add the return value of all loops to the SAT Solver - res = - CallSAT_ResultCheck(SatSolver, retformula, original_input); - if(SOLVER_UNDECIDED != res) - { - return res; - } - } //end of absrefine count - - ASTVec Allretvec1; - Allretvec1.push_back(ASTTrue); - SOLVER_RETURN_TYPE res = SOLVER_UNDECIDED; - for(ASTVec::iterator i = GlobalList_Of_FiniteLoops.begin(), - iend=GlobalList_Of_FiniteLoops.end(); i!=iend; i++) - { - //cout << "The abs-refine didn't finish the job. Add the remaining formulas\n"; - ASTNodeMap ParamToCurrentValMap; - ASTVec retvec; - retvec = SATBased_FiniteLoop_Refinement(SatSolver, - original_input, - *i, - &ParamToCurrentValMap, - false); //absrefine flag - for(ASTVec::iterator j=retvec.begin(),jend=retvec.end();j!=jend;j++) - { - Allretvec1.push_back(*j); - } - } //End of For - - ASTNode retformula = - (Allretvec1.size() == 1) ? - Allretvec1[0] : CreateNode(AND,Allretvec1); - retformula = TransformFormula_TopLevel(retformula); - //Add the return value of all loops to the SAT Solver - res = CallSAT_ResultCheck(SatSolver, retformula, original_input); - return res; - } //end of SATBased_AllFiniteLoops_Refinement() - - - /***************************************************************** - * SATBased_FiniteLoop_Refinement - * - * 'finiteloop' is the finite loop to be expanded - * Every finiteloop has three parts: - * 0) Parameter Name - * 1) Parameter initialization - * 2) Parameter limit value - * 3) Increment formula - * 4) Formula Body - * - * ParamToCurrentValMap contains a map from parameters to their - * current values in the recursion - * - * Nested FORs are allowed, but only the innermost loop can have a - * formula in it - *****************************************************************/ - //SATBased_FiniteLoop_Refinement - // - //Expand the finite loop, check against model, and add false - //formulas to the SAT solver - ASTVec - BeevMgr::SATBased_FiniteLoop_Refinement(MINISAT::Solver& SatSolver, - const ASTNode& original_input, - const ASTNode& finiteloop, - ASTNodeMap* ParamToCurrentValMap, - bool absrefine_flag) - { - //BVTypeCheck should have already checked the sanity of the input - //FOR-formula - ASTNode parameter = finiteloop[0]; - int paramInit = GetUnsignedConst(finiteloop[1]); - int paramLimit = GetUnsignedConst(finiteloop[2]); - int paramIncrement = GetUnsignedConst(finiteloop[3]); - ASTNode exceptFormula = finiteloop[4]; - ASTNode formulabody = finiteloop[5]; - int paramCurrentValue = paramInit; - int width = finiteloop[1].GetValueWidth(); - - //Update ParamToCurrentValMap with parameter and its current - //value. Here paramCurrentValue is the initial value - ASTNode value = - CreateBVConst(width,paramCurrentValue); - ReplaceOrAddToMap(ParamToCurrentValMap, parameter, value); - - //Go recursively thru' all the FOR-constructs. - if(FOR == formulabody.GetKind()) - { - ASTVec retvec; - ASTVec retvec_innerfor; - retvec.push_back(ASTTrue); - while(paramCurrentValue < paramLimit) - { - retvec_innerfor = - SATBased_FiniteLoop_Refinement(SatSolver, - original_input, - formulabody, - ParamToCurrentValMap, - absrefine_flag); - - for(ASTVec::iterator i=retvec_innerfor.begin(), - iend=retvec_innerfor.end();i!=iend;i++) - { - retvec.push_back(*i); - } - - //Update ParamToCurrentValMap with parameter and its - //current value. - paramCurrentValue = paramCurrentValue + paramIncrement; - value = CreateTerm(BVPLUS, - width, - (*ParamToCurrentValMap)[parameter], - CreateOneConst(width)); - ReplaceOrAddToMap(ParamToCurrentValMap, parameter, value); - } //end of While - - return retvec; - } //end of recursion FORs - - //Expand the leaf level FOR-construct completely - //increment of paramCurrentValue done inside loop - int ThisForLoopAllTrue = 0; - ASTVec ForloopVec; - ForloopVec.push_back(ASTTrue); - for(;paramCurrentValue < paramLimit;) - { - ASTNode currentFormula; - ASTNode currentExceptFormula = exceptFormula; - currentExceptFormula = - SimplifyFormula(exceptFormula, false, ParamToCurrentValMap); - if(ASTTrue == currentExceptFormula) - { - currentFormula = ASTTrue; - } - else - { - currentFormula = - SimplifyFormula(formulabody, false, ParamToCurrentValMap); - } - - //Check the currentformula against the model, and add it to the - //SAT solver if it is false against the model - if(absrefine_flag - && - ASTFalse == ComputeFormulaUsingModel(currentFormula) - ) - { - ForloopVec.push_back(currentFormula); - } - else - { - if(ASTTrue != currentFormula) - { - ForloopVec.push_back(currentFormula); - } - if(ASTFalse == currentFormula) - { - ForloopVec.push_back(ASTFalse); - return ForloopVec; - } - } - - //Update ParamToCurrentValMap with parameter and its current - //value. - paramCurrentValue = paramCurrentValue + paramIncrement; - value = CreateTerm(BVPLUS, - width, - (*ParamToCurrentValMap)[parameter], - CreateOneConst(width)); - ReplaceOrAddToMap(ParamToCurrentValMap, parameter, value); - } //end of expanding the FOR loop - - return ForloopVec; - } //end of the SATBased_FiniteLoop_Refinement() - - //SATBased_FiniteLoop_Refinement_UsingModel(). Expand the finite - //loop, check against model - ASTNode - BeevMgr::Check_FiniteLoop_UsingModel(const ASTNode& finiteloop, - ASTNodeMap* ParamToCurrentValMap, - bool checkusingmodel_flag = true) - { - /* - * 'finiteloop' is the finite loop to be expanded - * Every finiteloop has three parts: - * 0) Parameter Name - * 1) Parameter initialization - * 2) Parameter limit value - * 3) Increment formula - * 4) Formula Body - * - * ParamToCurrentValMap contains a map from parameters to their - * current values in the recursion - * - * Nested FORs are allowed, but only the innermost loop can have a - * formula in it - */ - - //BVTypeCheck should have already checked the sanity of the input - //FOR-formula - ASTNode parameter = finiteloop[0]; - int paramInit = GetUnsignedConst(finiteloop[1]); - int paramLimit = GetUnsignedConst(finiteloop[2]); - int paramIncrement = GetUnsignedConst(finiteloop[3]); - ASTNode exceptFormula = finiteloop[4]; - ASTNode formulabody = finiteloop[5]; - int paramCurrentValue = paramInit; - int width = finiteloop[1].GetValueWidth(); - - //Update ParamToCurrentValMap with parameter and its current - //value. Here paramCurrentValue is the initial value - ASTNode value = - CreateBVConst(width,paramCurrentValue); - ReplaceOrAddToMap(ParamToCurrentValMap, parameter, value); - - ASTNode ret = ASTTrue; - ASTVec returnVec; - //Go recursively thru' all the FOR-constructs. - if(FOR == formulabody.GetKind()) - { - while(paramCurrentValue < paramLimit) - { - ret = Check_FiniteLoop_UsingModel(formulabody, - ParamToCurrentValMap, - checkusingmodel_flag); - if(ASTFalse == ret) - { - //no more expansion needed. Return immediately - return ret; - } - else - { - returnVec.push_back(ret); - } - - //Update ParamToCurrentValMap with parameter and its - //current value. - paramCurrentValue = paramCurrentValue + paramIncrement; - value = CreateTerm(BVPLUS, - width, - (*ParamToCurrentValMap)[parameter], - CreateOneConst(width)); - ReplaceOrAddToMap(ParamToCurrentValMap, parameter, value); - } //end of While - - ASTNode retFormula = - (returnVec.size() > 1) ? - CreateNode(AND, returnVec) : - (returnVec.size() == 1) ? - returnVec[0] : - ASTTrue; - return retFormula; - } - - ASTVec forloopFormulaVector; - //Expand the leaf level FOR-construct completely - //incrementing of paramCurrentValue is done inside loop - for(;paramCurrentValue < paramLimit;) - { - ASTNode currentFormula; - - ASTNode currentExceptFormula = exceptFormula; - currentExceptFormula = - SimplifyFormula(exceptFormula, false, ParamToCurrentValMap); - if(ASTTrue == currentExceptFormula) - { - currentFormula = ASTTrue; - //continue; - } - else - { - currentFormula = - SimplifyFormula(formulabody, false, ParamToCurrentValMap); - } - - if(checkusingmodel_flag) - { - //Check the currentformula against the model, and return - //immediately - //cout << "Printing current Formula: " << currentFormula << "\n"; - ASTNode computedForm = ComputeFormulaUsingModel(currentFormula); - //cout << "Printing computed Formula: " << computedForm << "\n"; - if(ASTFalse == computedForm) - { - return ASTFalse; - } - } - else - { - if(ASTTrue != currentFormula) - { - forloopFormulaVector.push_back(currentFormula); - } - } - - //Update ParamToCurrentValMap with parameter and its current - //value - paramCurrentValue = paramCurrentValue + paramIncrement; - value = CreateTerm(BVPLUS, - width, - (*ParamToCurrentValMap)[parameter], - CreateOneConst(width)); - ReplaceOrAddToMap(ParamToCurrentValMap, parameter, value); - } //end of For - - if(checkusingmodel_flag) - { - return ASTTrue; - } - else - { - ASTNode retFormula = - (forloopFormulaVector.size() > 1) ? - CreateNode(AND, forloopFormulaVector) : - (forloopFormulaVector.size() == 1) ? - forloopFormulaVector[0] : - ASTTrue; - return retFormula; - } - } //end of the Check_FiniteLoop_UsingModel() - - - //Expand_FiniteLoop_For_ModelCheck - ASTNode - BeevMgr::Expand_FiniteLoop_TopLevel(const ASTNode& finiteloop) - { - ASTNodeMap ParamToCurrentValMap; - return Check_FiniteLoop_UsingModel(finiteloop, - &ParamToCurrentValMap, false); - } //end of Expand_FiniteLoop_TopLevel() - - ASTNode - BeevMgr::Check_FiniteLoop_UsingModel(const ASTNode& finiteloop) - { - ASTNodeMap ParamToCurrentValMap; - return Check_FiniteLoop_UsingModel(finiteloop, - &ParamToCurrentValMap, true); - } //end of Check_FiniteLoop_UsingModel -};// end of namespace BEEV diff --git a/src/c_interface/Makefile b/src/c_interface/Makefile index 306d418..c4f09ca 100644 --- a/src/c_interface/Makefile +++ b/src/c_interface/Makefile @@ -2,6 +2,7 @@ include ../../scripts/Makefile.common SRCS = $(wildcard *.cpp) OBJS = $(SRCS:.cpp=.o) +CFLAGS += -I../sat/mtl -I../sat/simp -I../sat/core libcinterface.a: $(OBJS) depend $(AR) rc $@ $(OBJS) diff --git a/src/c_interface/c_interface.cpp b/src/c_interface/c_interface.cpp index bc5c65c..54fdbd7 100644 --- a/src/c_interface/c_interface.cpp +++ b/src/c_interface/c_interface.cpp @@ -11,16 +11,19 @@ #include #include #include "fdstream.h" -#include "../AST/AST.h" #include "../printer/printers.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; +typedef BEEV::ASTNode node; +typedef BEEV::ASTNode* nodestar; +typedef BEEV::BeevMgr* bmstar; +typedef BEEV::STP* stpstar; +typedef BEEV::Simplifier* simpstar; +typedef BEEV::BVSolver* bvsolverstar; +typedef BEEV::AbsRefine_CounterExample * ctrexamplestar; +typedef BEEV::ASTVec nodelist; +typedef BEEV::CompleteCounterExample* CompleteCEStar; BEEV::ASTVec *decls = NULL; //vector created_exprs; bool cinterface_exprdelete_on_flag = false; @@ -124,11 +127,24 @@ VC vc_createValidityChecker(void) { cout << CONSTANTBV::BitVector_Error(c) << endl; return 0; } - bmstar bm = new BEEV::BeevMgr(); - BEEV::GlobalBeevMgr = bm; + + BEEV::BeevMgr * bm = new BEEV::BeevMgr(); + BEEV::Simplifier * simp = new BEEV::Simplifier(bm); + BEEV::BVSolver* bvsolver = new BEEV::BVSolver(bm, simp); + BEEV::ToSAT * tosat = new BEEV::ToSAT(bm, simp); + BEEV::ArrayTransformer * arrayTransformer = new BEEV::ArrayTransformer(bm, simp); + BEEV::AbsRefine_CounterExample * Ctr_Example = + new BEEV::AbsRefine_CounterExample(bm, simp, arrayTransformer, tosat); + + BEEV::ParserBM = bm; + stpstar stp = new BEEV::STP(bm, simp, + bvsolver, arrayTransformer, + tosat, Ctr_Example); + + BEEV::GlobalSTP = stp; decls = new BEEV::ASTVec(); //created_exprs.clear(); - return (VC)bm; + return (VC)stp; } // Expr I/O @@ -155,7 +171,7 @@ char * vc_printSMTLIB(VC vc, Expr e) // prints Expr 'e' to stdout as C code void vc_printExprCCode(VC vc, Expr e) { BEEV::ASTNode q = (*(nodestar)e); - bmstar b = (bmstar)vc; + bmstar b = (bmstar)(((stpstar)vc)->bm); // print variable declarations BEEV::ASTVec declsFromParser = (nodelist)b->ListOfDeclaredVars; @@ -216,12 +232,13 @@ void vc_printVarDecls(VC vc) { } static void vc_printAssertsToStream(VC vc, ostream &os, int simplify_print) { - bmstar b = (bmstar)vc; + bmstar b = (bmstar)(((stpstar)vc)->bm); BEEV::ASTVec v = b->GetAsserts(); + BEEV::Simplifier * simp = new BEEV::Simplifier(b); 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; + BEEV::ASTNode q = (simplify_print == 1) ? simp->SimplifyFormula_TopLevel(*i,false) : *i; + q = (simplify_print == 1) ? simp->SimplifyFormula_TopLevel(q,false) : q; b->Begin_RemoveWrites = false; os << "ASSERT( "; q.PL_Print(os); @@ -238,7 +255,8 @@ void vc_printQueryStateToBuffer(VC vc, Expr e, char **buf, unsigned long *len, i assert(e); assert(buf); assert(len); - bmstar b = (bmstar)vc; + bmstar b = (bmstar)(((stpstar)vc)->bm); + BEEV::Simplifier * simp = new BEEV::Simplifier(b); // formate the state of the query stringstream os; @@ -248,7 +266,10 @@ void vc_printQueryStateToBuffer(VC vc, Expr e, char **buf, unsigned long *len, i os << "%----------------------------------------------------" << endl; os << "QUERY( "; b->Begin_RemoveWrites = true; - BEEV::ASTNode q = (simplify_print == 1) ? b->SimplifyFormula_TopLevel(*((nodestar)e),false) : *(nodestar)e; + BEEV::ASTNode q = + (simplify_print == 1) ? + simp->SimplifyFormula_TopLevel(*((nodestar)e),false) : + *(nodestar)e; b->Begin_RemoveWrites = false; q.PL_Print(os); os << " );" << endl; @@ -270,13 +291,14 @@ void vc_printCounterExampleToBuffer(VC vc, char **buf, unsigned long *len) { assert(vc); assert(buf); assert(len); - bmstar b = (bmstar)vc; + bmstar b = (bmstar)(((stpstar)vc)->bm); + ctrexamplestar ce = (ctrexamplestar)(((stpstar)vc)->Ctr_Example); // formate the state of the query std::ostringstream os; BEEV::print_counterexample_flag = true; os << "COUNTEREXAMPLE BEGIN: \n"; - b->PrintCounterExample(true,os); + ce->PrintCounterExample(true,os); os << "COUNTEREXAMPLE END: \n"; // convert to a c buffer @@ -294,7 +316,7 @@ void vc_printCounterExampleToBuffer(VC vc, char **buf, unsigned long *len) { void vc_printExprToBuffer(VC vc, Expr e, char **buf, unsigned long * len) { stringstream os; - //bmstar b = (bmstar)vc; + //bmstar b = (bmstar)(((stpstar)vc)->bm); BEEV::ASTNode q = *((nodestar)e); // b->Begin_RemoveWrites = true; // BEEV::ASTNode q = b->SimplifyFormula_TopLevel(*((nodestar)e),false); @@ -311,7 +333,7 @@ void vc_printExprToBuffer(VC vc, Expr e, char **buf, unsigned long * len) { void vc_printQuery(VC vc){ ostream& os = std::cout; - bmstar b = (bmstar)vc; + bmstar b = (bmstar)(((stpstar)vc)->bm); os << "QUERY("; //b->Begin_RemoveWrites = true; //BEEV::ASTNode q = b->SimplifyFormula_TopLevel(b->GetQuery(),false); @@ -327,7 +349,7 @@ void vc_printQuery(VC vc){ ///////////////////////////////////////////////////////////////////////////// //! Create an array type Type vc_arrayType(VC vc, Type typeIndex, Type typeData) { - bmstar b = (bmstar)vc; + bmstar b = (bmstar)(((stpstar)vc)->bm); nodestar ti = (nodestar)typeIndex; nodestar td = (nodestar)typeData; @@ -342,14 +364,14 @@ Type vc_arrayType(VC vc, Type typeIndex, Type typeData) { //! 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; + bmstar b = (bmstar)(((stpstar)vc)->bm); nodestar a = (nodestar)array; nodestar i = (nodestar)index; - b->BVTypeCheck(*a); - b->BVTypeCheck(*i); + BVTypeCheck(*a); + BVTypeCheck(*i); node o = b->CreateTerm(BEEV::READ,a->GetValueWidth(),*a,*i); - b->BVTypeCheck(o); + BVTypeCheck(o); nodestar output = new node(o); //if(cinterface_exprdelete_on) created_exprs.push_back(output); @@ -358,17 +380,17 @@ 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) { - bmstar b = (bmstar)vc; + bmstar b = (bmstar)(((stpstar)vc)->bm); nodestar a = (nodestar)array; nodestar i = (nodestar)index; nodestar n = (nodestar)newValue; - b->BVTypeCheck(*a); - b->BVTypeCheck(*i); - b->BVTypeCheck(*n); + BVTypeCheck(*a); + BVTypeCheck(*i); + BVTypeCheck(*n); node o = b->CreateTerm(BEEV::WRITE,a->GetValueWidth(),*a,*i,*n); o.SetIndexWidth(a->GetIndexWidth()); - b->BVTypeCheck(o); + BVTypeCheck(o); nodestar output = new node(o); //if(cinterface_exprdelete_on) created_exprs.push_back(output); @@ -382,12 +404,12 @@ Expr vc_writeExpr(VC vc, Expr array, Expr index, Expr newValue) { /*! The formula must have Boolean type. */ void vc_assertFormula(VC vc, Expr e, int absrefine_num) { nodestar a = (nodestar)e; - bmstar b = (bmstar)vc; + bmstar b = (bmstar)(((stpstar)vc)->bm); if(!BEEV::is_Form_kind(a->GetKind())) BEEV::FatalError("Trying to assert a NON formula: ",*a); - b->BVTypeCheck(*a); + BVTypeCheck(*a); b->AddAssert(*a); } @@ -407,14 +429,15 @@ void vc_assertFormula(VC vc, Expr e, int absrefine_num) { * type. */ int vc_query(VC vc, Expr e) { nodestar a = (nodestar)e; - bmstar b = (bmstar)vc; + stpstar stp = ((stpstar)vc); + bmstar b = (bmstar)(stp->bm); if(!BEEV::is_Form_kind(a->GetKind())) BEEV::FatalError("CInterface: Trying to QUERY a NON formula: ",*a); //a->LispPrint(cout, 0); //printf("##################################################\n"); - b->BVTypeCheck(*a); + BVTypeCheck(*a); b->AddQuery(*a); const BEEV::ASTVec v = b->GetAsserts(); @@ -422,28 +445,28 @@ int vc_query(VC vc, Expr e) { int output; if(!v.empty()) { if(v.size()==1) { - output = b->TopLevelSAT(v[0],*a); + output = stp->TopLevelSAT(v[0],*a); } else { - output = b->TopLevelSAT(b->CreateNode(BEEV::AND,v),*a); + output = stp->TopLevelSAT(b->CreateNode(BEEV::AND,v),*a); } } else { - output = b->TopLevelSAT(b->CreateNode(BEEV::TRUE),*a); + output = stp->TopLevelSAT(b->CreateNode(BEEV::TRUE),*a); } return output; } //end of vc_query // int vc_absRefineQuery(VC vc, Expr e) { // nodestar a = (nodestar)e; -// bmstar b = (bmstar)vc; +// bmstar b = (bmstar)(((stpstar)vc)->bm); // if(!BEEV::is_Form_kind(a->GetKind())) // BEEV::FatalError("CInterface: Trying to QUERY a NON formula: ",*a); // //a->LispPrint(cout, 0); // //printf("##################################################\n"); -// b->BVTypeCheck(*a); +// BVTypeCheck(*a); // b->AddQuery(*a); // const BEEV::ASTVec v = b->GetAsserts(); @@ -459,21 +482,23 @@ int vc_query(VC vc, Expr e) { // } void vc_push(VC vc) { - bmstar b = (bmstar)vc; + bmstar b = (bmstar)(((stpstar)vc)->bm); b->ClearAllCaches(); b->Push(); } void vc_pop(VC vc) { - bmstar b = (bmstar)vc; + bmstar b = (bmstar)(((stpstar)vc)->bm); b->Pop(); } void vc_printCounterExample(VC vc) { - bmstar b = (bmstar)vc; + bmstar b = (bmstar)(((stpstar)vc)->bm); + ctrexamplestar ce = (ctrexamplestar)(((stpstar)vc)->Ctr_Example); + BEEV::print_counterexample_flag = true; cout << "COUNTEREXAMPLE BEGIN: \n"; - b->PrintCounterExample(true); + ce->PrintCounterExample(true); cout << "COUNTEREXAMPLE END: \n"; } @@ -487,30 +512,35 @@ void vc_printCounterExample(VC vc) { Expr vc_getCounterExample(VC vc, Expr e) { nodestar a = (nodestar)e; - bmstar b = (bmstar)vc; + bmstar b = (bmstar)(((stpstar)vc)->bm); + ctrexamplestar ce = (ctrexamplestar)(((stpstar)vc)->Ctr_Example); bool t = false; - if(b->CounterExampleSize()) + if(ce->CounterExampleSize()) t = true; - nodestar output = new node(b->GetCounterExample(t, *a)); + nodestar output = new node(ce->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(); + bmstar b = (bmstar)(((stpstar)vc)->bm); + ctrexamplestar ce = (ctrexamplestar)(((stpstar)vc)->Ctr_Example); + + return ce->CounterExampleSize(); } WholeCounterExample vc_getWholeCounterExample(VC vc) { - bmstar b = (bmstar)vc; + bmstar b = (bmstar)(((stpstar)vc)->bm); + ctrexamplestar ce = (ctrexamplestar)(((stpstar)vc)->Ctr_Example); + CompleteCEStar c = - new BEEV::CompleteCounterExample(b->GetCompleteCounterExample(), b); + new BEEV::CompleteCounterExample(ce->GetCompleteCounterExample(), b); return c; } Expr vc_getTermFromCounterExample(VC vc, Expr e, CompleteCEStar cc) { - //bmstar b = (bmstar)vc; + //bmstar b = (bmstar)(((stpstar)vc)->bm); nodestar n = (nodestar)e; CompleteCEStar c = (CompleteCEStar)cc; @@ -535,7 +565,7 @@ int vc_getBVLength(VC vc, Expr ex) { /*! The type cannot be a function type. */ Expr vc_varExpr1(VC vc, const char* name, int indexwidth, int valuewidth) { - bmstar b = (bmstar)vc; + bmstar b = (bmstar)(((stpstar)vc)->bm); node o = b->CreateSymbol(name); o.SetIndexWidth(indexwidth); @@ -543,7 +573,7 @@ Expr vc_varExpr1(VC vc, const char* name, nodestar output = new node(o); ////if(cinterface_exprdelete_on) created_exprs.push_back(output); - b->BVTypeCheck(*output); + BVTypeCheck(*output); //store the decls in a vector for printing purposes decls->push_back(o); @@ -551,7 +581,7 @@ Expr vc_varExpr1(VC vc, const char* name, } Expr vc_varExpr(VC vc, const char * name, Type type) { - bmstar b = (bmstar)vc; + bmstar b = (bmstar)(((stpstar)vc)->bm); nodestar a = (nodestar)type; node o = b->CreateSymbol(name); @@ -574,7 +604,7 @@ Expr vc_varExpr(VC vc, const char * name, Type type) { } nodestar output = new node(o); ////if(cinterface_exprdelete_on) created_exprs.push_back(output); - b->BVTypeCheck(*output); + BVTypeCheck(*output); //store the decls in a vector for printing purposes decls->push_back(o); @@ -584,12 +614,12 @@ Expr vc_varExpr(VC vc, const char * name, Type type) { //! 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; + bmstar b = (bmstar)(((stpstar)vc)->bm); nodestar a = (nodestar)ccc0; nodestar aa = (nodestar)ccc1; - b->BVTypeCheck(*a); - b->BVTypeCheck(*aa); + BVTypeCheck(*a); + BVTypeCheck(*aa); node o = b->CreateNode(BEEV::EQ,*a,*aa); nodestar output = new node(o); @@ -598,7 +628,7 @@ Expr vc_eqExpr(VC vc, Expr ccc0, Expr ccc1) { } Expr vc_boolType(VC vc) { - bmstar b = (bmstar)vc; + bmstar b = (bmstar)(((stpstar)vc)->bm); node o = b->CreateNode(BEEV::BOOLEAN); nodestar output = new node(o); @@ -612,7 +642,7 @@ Expr vc_boolType(VC vc) { // 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; + bmstar b = (bmstar)(((stpstar)vc)->bm); node c = b->CreateNode(BEEV::TRUE); nodestar d = new node(c); @@ -621,7 +651,7 @@ Expr vc_trueExpr(VC vc) { } Expr vc_falseExpr(VC vc) { - bmstar b = (bmstar)vc; + bmstar b = (bmstar)(((stpstar)vc)->bm); node c = b->CreateNode(BEEV::FALSE); nodestar d = new node(c); @@ -630,11 +660,11 @@ Expr vc_falseExpr(VC vc) { } Expr vc_notExpr(VC vc, Expr ccc) { - bmstar b = (bmstar)vc; + bmstar b = (bmstar)(((stpstar)vc)->bm); nodestar a = (nodestar)ccc; node o = b->CreateNode(BEEV::NOT,*a); - b->BVTypeCheck(o); + BVTypeCheck(o); nodestar output = new node(o); //if(cinterface_exprdelete_on) created_exprs.push_back(output); @@ -642,12 +672,12 @@ Expr vc_notExpr(VC vc, Expr ccc) { } Expr vc_andExpr(VC vc, Expr left, Expr right) { - bmstar b = (bmstar)vc; + bmstar b = (bmstar)(((stpstar)vc)->bm); nodestar l = (nodestar)left; nodestar r = (nodestar)right; node o = b->CreateNode(BEEV::AND,*l,*r); - b->BVTypeCheck(o); + BVTypeCheck(o); nodestar output = new node(o); //if(cinterface_exprdelete_on) created_exprs.push_back(output); @@ -655,19 +685,19 @@ Expr vc_andExpr(VC vc, Expr left, Expr right) { } Expr vc_orExpr(VC vc, Expr left, Expr right) { - bmstar b = (bmstar)vc; + bmstar b = (bmstar)(((stpstar)vc)->bm); nodestar l = (nodestar)left; nodestar r = (nodestar)right; node o = b->CreateNode(BEEV::OR,*l,*r); - b->BVTypeCheck(o); + 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; + bmstar b = (bmstar)(((stpstar)vc)->bm); nodestar * c = (nodestar *)cc; nodelist d; @@ -675,7 +705,7 @@ Expr vc_andExprN(VC vc, Expr* cc, int n) { d.push_back(*c[i]); node o = b->CreateNode(BEEV::AND,d); - b->BVTypeCheck(o); + BVTypeCheck(o); nodestar output = new node(o); //if(cinterface_exprdelete_on) created_exprs.push_back(output); @@ -684,7 +714,7 @@ Expr vc_andExprN(VC vc, Expr* cc, int n) { Expr vc_orExprN(VC vc, Expr* cc, int n) { - bmstar b = (bmstar)vc; + bmstar b = (bmstar)(((stpstar)vc)->bm); nodestar * c = (nodestar *)cc; nodelist d; @@ -692,7 +722,7 @@ Expr vc_orExprN(VC vc, Expr* cc, int n) { d.push_back(*c[i]); node o = b->CreateNode(BEEV::OR,d); - b->BVTypeCheck(o); + BVTypeCheck(o); nodestar output = new node(o); //if(cinterface_exprdelete_on) created_exprs.push_back(output); @@ -700,7 +730,7 @@ Expr vc_orExprN(VC vc, Expr* cc, int n) { } Expr vc_bvPlusExprN(VC vc, int n_bits, Expr* cc, int n) { - bmstar b = (bmstar)vc; + bmstar b = (bmstar)(((stpstar)vc)->bm); nodestar * c = (nodestar *)cc; nodelist d; @@ -708,7 +738,7 @@ Expr vc_bvPlusExprN(VC vc, int n_bits, Expr* cc, int n) { d.push_back(*c[i]); node o = b->CreateTerm(BEEV::BVPLUS, n_bits, d); - b->BVTypeCheck(o); + BVTypeCheck(o); nodestar output = new node(o); //if(cinterface_exprdelete_on) created_exprs.push_back(output); @@ -717,14 +747,14 @@ Expr vc_bvPlusExprN(VC vc, int n_bits, Expr* cc, int n) { Expr vc_iteExpr(VC vc, Expr cond, Expr thenpart, Expr elsepart){ - bmstar b = (bmstar)vc; + bmstar b = (bmstar)(((stpstar)vc)->bm); nodestar c = (nodestar)cond; nodestar t = (nodestar)thenpart; nodestar e = (nodestar)elsepart; - b->BVTypeCheck(*c); - b->BVTypeCheck(*t); - b->BVTypeCheck(*e); + BVTypeCheck(*c); + BVTypeCheck(*t); + BVTypeCheck(*e); node o; //if the user asks for a formula then produce a formula, else //prodcue a term @@ -734,49 +764,49 @@ Expr vc_iteExpr(VC vc, Expr cond, Expr thenpart, Expr elsepart){ o = b->CreateTerm(BEEV::ITE,t->GetValueWidth(),*c,*t,*e); o.SetIndexWidth(t->GetIndexWidth()); } - b->BVTypeCheck(o); + 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; + bmstar b = (bmstar)(((stpstar)vc)->bm); nodestar c = (nodestar)antecedent; nodestar t = (nodestar)consequent; - b->BVTypeCheck(*c); - b->BVTypeCheck(*t); + BVTypeCheck(*c); + BVTypeCheck(*t); node o; o = b->CreateNode(BEEV::IMPLIES,*c,*t); - b->BVTypeCheck(o); + 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; + bmstar b = (bmstar)(((stpstar)vc)->bm); nodestar c = (nodestar)e0; nodestar t = (nodestar)e1; - b->BVTypeCheck(*c); - b->BVTypeCheck(*t); + BVTypeCheck(*c); + BVTypeCheck(*t); node o; o = b->CreateNode(BEEV::IFF,*c,*t); - b->BVTypeCheck(o); + 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; + bmstar b = (bmstar)(((stpstar)vc)->bm); nodestar c = (nodestar)form; - b->BVTypeCheck(*c); + BVTypeCheck(*c); if(!is_Form_kind(c->GetKind())) BEEV::FatalError("CInterface: vc_BoolToBVExpr: You have input a NON formula:",*c); @@ -785,23 +815,23 @@ Expr vc_boolToBVExpr(VC vc, Expr form) { node zero = b->CreateZeroConst(1); o = b->CreateTerm(BEEV::ITE,1,*c,one,zero); - b->BVTypeCheck(o); + BVTypeCheck(o); nodestar output = new node(o); //if(cinterface_exprdelete_on) created_exprs.push_back(output); return output; } Expr vc_paramBoolExpr(VC vc, Expr boolvar, Expr parameter){ - bmstar b = (bmstar)vc; + bmstar b = (bmstar)(((stpstar)vc)->bm); nodestar c = (nodestar)boolvar; nodestar t = (nodestar)parameter; - b->BVTypeCheck(*c); - b->BVTypeCheck(*t); + BVTypeCheck(*c); + BVTypeCheck(*t); node o; o = b->CreateNode(BEEV::PARAMBOOL,*c,*t); - //b->BVTypeCheck(o); + //BVTypeCheck(o); nodestar output = new node(o); //if(cinterface_exprdelete_on) created_exprs.push_back(output); return output; @@ -812,7 +842,7 @@ Expr vc_paramBoolExpr(VC vc, Expr boolvar, Expr parameter){ // BITVECTOR EXPR Creation methods // ///////////////////////////////////////////////////////////////////////////// Type vc_bvType(VC vc, int num_bits) { - bmstar b = (bmstar)vc; + bmstar b = (bmstar)(((stpstar)vc)->bm); if(!(0 < num_bits)) BEEV::FatalError("CInterface: number of bits in a bvtype must be a positive integer:", @@ -829,12 +859,12 @@ Type vc_bv32Type(VC vc) { } Expr vc_bvConstExprFromDecStr(VC vc, const size_t width, const char* decimalInput ) { - bmstar b = (bmstar)vc; + bmstar b = (bmstar)(((stpstar)vc)->bm); string *param = new string(decimalInput); // funny type to get it to compile. fix later when I understand what this does. node n = b->CreateBVConst((string*&)param, (int)10,(int)width); - b->BVTypeCheck(n); + BVTypeCheck(n); nodestar output = new node(n); delete param; return output; @@ -842,10 +872,10 @@ Expr vc_bvConstExprFromDecStr(VC vc, const size_t width, const char* decimalInpu Expr vc_bvConstExprFromStr(VC vc, const char* binary_repr) { - bmstar b = (bmstar)vc; + bmstar b = (bmstar)(((stpstar)vc)->bm); node n = b->CreateBVConst(binary_repr,2); - b->BVTypeCheck(n); + BVTypeCheck(n); nodestar output = new node(n); //if(cinterface_exprdelete_on) created_exprs.push_back(output); return output; @@ -854,7 +884,7 @@ Expr vc_bvConstExprFromStr(VC vc, const char* binary_repr) { Expr vc_bvConstExprFromInt(VC vc, int n_bits, unsigned int value) { - bmstar b = (bmstar)vc; + bmstar b = (bmstar)(((stpstar)vc)->bm); unsigned long long int v = (unsigned long long int)value; unsigned long long int max_n_bits = 0xFFFFFFFFFFFFFFFFULL >> 64-n_bits; @@ -865,7 +895,7 @@ Expr vc_bvConstExprFromInt(VC vc, BEEV::FatalError("FatalError"); } node n = b->CreateBVConst(n_bits, v); - b->BVTypeCheck(n); + BVTypeCheck(n); nodestar output = new node(n); //if(cinterface_exprdelete_on) created_exprs.push_back(output); return output; @@ -874,40 +904,40 @@ Expr vc_bvConstExprFromInt(VC vc, Expr vc_bvConstExprFromLL(VC vc, int n_bits, unsigned long long value) { - bmstar b = (bmstar)vc; + bmstar b = (bmstar)(((stpstar)vc)->bm); node n = b->CreateBVConst(n_bits, value); - b->BVTypeCheck(n); + 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; + bmstar b = (bmstar)(((stpstar)vc)->bm); nodestar l = (nodestar)left; nodestar r = (nodestar)right; - b->BVTypeCheck(*l); - b->BVTypeCheck(*r); + BVTypeCheck(*l); + BVTypeCheck(*r); node o = b->CreateTerm(BEEV::BVCONCAT, l->GetValueWidth()+ r->GetValueWidth(),*l,*r); - b->BVTypeCheck(o); + 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; + bmstar b = (bmstar)(((stpstar)vc)->bm); nodestar l = (nodestar)left; nodestar r = (nodestar)right; - b->BVTypeCheck(*l); - b->BVTypeCheck(*r); + BVTypeCheck(*l); + BVTypeCheck(*r); node o = b->CreateTerm(BEEV::BVPLUS,n_bits, *l, *r); - b->BVTypeCheck(o); + BVTypeCheck(o); nodestar output = new node(o); //if(cinterface_exprdelete_on) created_exprs.push_back(output); return output; @@ -920,14 +950,14 @@ Expr vc_bv32PlusExpr(VC vc, Expr left, Expr right) { Expr vc_bvMinusExpr(VC vc, int n_bits, Expr left, Expr right) { - bmstar b = (bmstar)vc; + bmstar b = (bmstar)(((stpstar)vc)->bm); nodestar l = (nodestar)left; nodestar r = (nodestar)right; - b->BVTypeCheck(*l); - b->BVTypeCheck(*r); + BVTypeCheck(*l); + BVTypeCheck(*r); node o = b->CreateTerm(BEEV::BVSUB,n_bits, *l, *r); - b->BVTypeCheck(o); + BVTypeCheck(o); nodestar output = new node(o); //if(cinterface_exprdelete_on) created_exprs.push_back(output); return output; @@ -940,70 +970,70 @@ Expr vc_bv32MinusExpr(VC vc, Expr left, Expr right) { Expr vc_bvMultExpr(VC vc, int n_bits, Expr left, Expr right) { - bmstar b = (bmstar)vc; + bmstar b = (bmstar)(((stpstar)vc)->bm); nodestar l = (nodestar)left; nodestar r = (nodestar)right; - b->BVTypeCheck(*l); - b->BVTypeCheck(*r); + BVTypeCheck(*l); + BVTypeCheck(*r); node o = b->CreateTerm(BEEV::BVMULT,n_bits, *l, *r); - b->BVTypeCheck(o); + 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; + bmstar b = (bmstar)(((stpstar)vc)->bm); nodestar l = (nodestar)left; nodestar r = (nodestar)right; - b->BVTypeCheck(*l); - b->BVTypeCheck(*r); + BVTypeCheck(*l); + BVTypeCheck(*r); node o = b->CreateTerm(BEEV::BVDIV,n_bits, *l, *r); - b->BVTypeCheck(o); + 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; + bmstar b = (bmstar)(((stpstar)vc)->bm); nodestar l = (nodestar)left; nodestar r = (nodestar)right; - b->BVTypeCheck(*l); - b->BVTypeCheck(*r); + BVTypeCheck(*l); + BVTypeCheck(*r); node o = b->CreateTerm(BEEV::BVMOD,n_bits, *l, *r); - b->BVTypeCheck(o); + 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; + bmstar b = (bmstar)(((stpstar)vc)->bm); nodestar l = (nodestar)left; nodestar r = (nodestar)right; - b->BVTypeCheck(*l); - b->BVTypeCheck(*r); + BVTypeCheck(*l); + BVTypeCheck(*r); node o = b->CreateTerm(BEEV::SBVDIV,n_bits, *l, *r); - b->BVTypeCheck(o); + 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; + bmstar b = (bmstar)(((stpstar)vc)->bm); nodestar l = (nodestar)left; nodestar r = (nodestar)right; - b->BVTypeCheck(*l); - b->BVTypeCheck(*r); + BVTypeCheck(*l); + BVTypeCheck(*r); node o = b->CreateTerm(BEEV::SBVREM,n_bits, *l, *r); - b->BVTypeCheck(o); + BVTypeCheck(o); nodestar output = new node(o); //if(cinterface_exprdelete_on) created_exprs.push_back(output); return output; @@ -1016,56 +1046,56 @@ Expr vc_bv32MultExpr(VC vc, Expr left, Expr right) { // unsigned comparators Expr vc_bvLtExpr(VC vc, Expr left, Expr right) { - bmstar b = (bmstar)vc; + bmstar b = (bmstar)(((stpstar)vc)->bm); nodestar l = (nodestar)left; nodestar r = (nodestar)right; - b->BVTypeCheck(*l); - b->BVTypeCheck(*r); + BVTypeCheck(*l); + BVTypeCheck(*r); node o = b->CreateNode(BEEV::BVLT, *l, *r); - b->BVTypeCheck(o); + 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; + bmstar b = (bmstar)(((stpstar)vc)->bm); nodestar l = (nodestar)left; nodestar r = (nodestar)right; - b->BVTypeCheck(*l); - b->BVTypeCheck(*r); + BVTypeCheck(*l); + BVTypeCheck(*r); node o = b->CreateNode(BEEV::BVLE, *l, *r); - b->BVTypeCheck(o); + 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; + bmstar b = (bmstar)(((stpstar)vc)->bm); nodestar l = (nodestar)left; nodestar r = (nodestar)right; - b->BVTypeCheck(*l); - b->BVTypeCheck(*r); + BVTypeCheck(*l); + BVTypeCheck(*r); node o = b->CreateNode(BEEV::BVGT, *l, *r); - b->BVTypeCheck(o); + 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; + bmstar b = (bmstar)(((stpstar)vc)->bm); nodestar l = (nodestar)left; nodestar r = (nodestar)right; - b->BVTypeCheck(*l); - b->BVTypeCheck(*r); + BVTypeCheck(*l); + BVTypeCheck(*r); node o = b->CreateNode(BEEV::BVGE, *l, *r); - b->BVTypeCheck(o); + BVTypeCheck(o); nodestar output = new node(o); //if(cinterface_exprdelete_on) created_exprs.push_back(output); return output; @@ -1073,68 +1103,68 @@ Expr vc_bvGeExpr(VC vc, Expr left, Expr right) { // signed comparators Expr vc_sbvLtExpr(VC vc, Expr left, Expr right) { - bmstar b = (bmstar)vc; + bmstar b = (bmstar)(((stpstar)vc)->bm); nodestar l = (nodestar)left; nodestar r = (nodestar)right; - b->BVTypeCheck(*l); - b->BVTypeCheck(*r); + BVTypeCheck(*l); + BVTypeCheck(*r); node o = b->CreateNode(BEEV::BVSLT, *l, *r); - b->BVTypeCheck(o); + 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; + bmstar b = (bmstar)(((stpstar)vc)->bm); nodestar l = (nodestar)left; nodestar r = (nodestar)right; - b->BVTypeCheck(*l); - b->BVTypeCheck(*r); + BVTypeCheck(*l); + BVTypeCheck(*r); node o = b->CreateNode(BEEV::BVSLE, *l, *r); - b->BVTypeCheck(o); + 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; + bmstar b = (bmstar)(((stpstar)vc)->bm); nodestar l = (nodestar)left; nodestar r = (nodestar)right; - b->BVTypeCheck(*l); - b->BVTypeCheck(*r); + BVTypeCheck(*l); + BVTypeCheck(*r); node o = b->CreateNode(BEEV::BVSGT, *l, *r); - b->BVTypeCheck(o); + 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; + bmstar b = (bmstar)(((stpstar)vc)->bm); nodestar l = (nodestar)left; nodestar r = (nodestar)right; - b->BVTypeCheck(*l); - b->BVTypeCheck(*r); + BVTypeCheck(*l); + BVTypeCheck(*r); node o = b->CreateNode(BEEV::BVSGE, *l, *r); - b->BVTypeCheck(o); + 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; + bmstar b = (bmstar)(((stpstar)vc)->bm); nodestar a = (nodestar)ccc; - b->BVTypeCheck(*a); + BVTypeCheck(*a); node o = b->CreateTerm(BEEV::BVUMINUS, a->GetValueWidth(), *a); - b->BVTypeCheck(o); + BVTypeCheck(o); nodestar output = new node(o); //if(cinterface_exprdelete_on) created_exprs.push_back(output); return output; @@ -1142,69 +1172,69 @@ Expr vc_bvUMinusExpr(VC vc, Expr ccc) { // bitwise operations: these are terms not formulas Expr vc_bvAndExpr(VC vc, Expr left, Expr right) { - bmstar b = (bmstar)vc; + bmstar b = (bmstar)(((stpstar)vc)->bm); nodestar l = (nodestar)left; nodestar r = (nodestar)right; - b->BVTypeCheck(*l); - b->BVTypeCheck(*r); + BVTypeCheck(*l); + BVTypeCheck(*r); node o = b->CreateTerm(BEEV::BVAND, (*l).GetValueWidth(), *l, *r); - b->BVTypeCheck(o); + 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; + bmstar b = (bmstar)(((stpstar)vc)->bm); nodestar l = (nodestar)left; nodestar r = (nodestar)right; - b->BVTypeCheck(*l); - b->BVTypeCheck(*r); + BVTypeCheck(*l); + BVTypeCheck(*r); node o = b->CreateTerm(BEEV::BVOR, (*l).GetValueWidth(), *l, *r); - b->BVTypeCheck(o); + 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; + bmstar b = (bmstar)(((stpstar)vc)->bm); nodestar l = (nodestar)left; nodestar r = (nodestar)right; - b->BVTypeCheck(*l); - b->BVTypeCheck(*r); + BVTypeCheck(*l); + BVTypeCheck(*r); node o = b->CreateTerm(BEEV::BVXOR, (*l).GetValueWidth(), *l, *r); - b->BVTypeCheck(o); + 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; + bmstar b = (bmstar)(((stpstar)vc)->bm); nodestar a = (nodestar)ccc; - b->BVTypeCheck(*a); + BVTypeCheck(*a); node o = b->CreateTerm(BEEV::BVNEG, a->GetValueWidth(), *a); - b->BVTypeCheck(o); + 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; + bmstar b = (bmstar)(((stpstar)vc)->bm); nodestar a = (nodestar)ccc; - b->BVTypeCheck(*a); + 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); + BVTypeCheck(o); nodestar output = new node(o); //if(cinterface_exprdelete_on) created_exprs.push_back(output); return output; @@ -1214,9 +1244,9 @@ Expr vc_bvLeftShiftExpr(VC vc, int sh_amt, Expr ccc) { } Expr vc_bvRightShiftExpr(VC vc, int sh_amt, Expr ccc) { - bmstar b = (bmstar)vc; + bmstar b = (bmstar)(((stpstar)vc)->bm); nodestar a = (nodestar)ccc; - b->BVTypeCheck(*a); + BVTypeCheck(*a); unsigned int w = a->GetValueWidth(); //the amount by which you are rightshifting @@ -1229,7 +1259,7 @@ Expr vc_bvRightShiftExpr(VC vc, int sh_amt, Expr ccc) { node extract = b->CreateTerm(BEEV::BVEXTRACT,w-sh_amt,*a,hi,low); node n = b->CreateTerm(BEEV::BVCONCAT, w,len, extract); - b->BVTypeCheck(n); + BVTypeCheck(n); nodestar output = new node(n); //if(cinterface_exprdelete_on) created_exprs.push_back(output); return output; @@ -1333,74 +1363,74 @@ Expr vc_bvVar32RightShiftExpr(VC vc, Expr sh_amt, Expr child) { } Expr vc_bvExtract(VC vc, Expr ccc, int hi_num, int low_num) { - bmstar b = (bmstar)vc; + bmstar b = (bmstar)(((stpstar)vc)->bm); nodestar a = (nodestar)ccc; - b->BVTypeCheck(*a); + 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); + 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; + bmstar b = (bmstar)(((stpstar)vc)->bm); nodestar a = (nodestar)ccc; - b->BVTypeCheck(*a); + 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); + BVTypeCheck(o); nodestar output = new node(o); //if(cinterface_exprdelete_on) created_exprs.push_back(output); return output; } Expr vc_bvBoolExtract_Zero(VC vc, Expr ccc, int bit_num) { - bmstar b = (bmstar)vc; + bmstar b = (bmstar)(((stpstar)vc)->bm); nodestar a = (nodestar)ccc; - b->BVTypeCheck(*a); + 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); + BVTypeCheck(o); nodestar output = new node(o); //if(cinterface_exprdelete_on) created_exprs.push_back(output); return output; } Expr vc_bvBoolExtract_One(VC vc, Expr ccc, int bit_num) { - bmstar b = (bmstar)vc; + bmstar b = (bmstar)(((stpstar)vc)->bm); nodestar a = (nodestar)ccc; - b->BVTypeCheck(*a); + BVTypeCheck(*a); node bit = b->CreateBVConst(32,bit_num); //node o = b->CreateNode(BEEV::BVGETBIT,*a,bit); node one = b->CreateBVConst(1,1); node oo = b->CreateTerm(BEEV::BVEXTRACT,1,*a,bit,bit); node o = b->CreateNode(BEEV::EQ,oo,one); - b->BVTypeCheck(o); + 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; + bmstar b = (bmstar)(((stpstar)vc)->bm); 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); + BVTypeCheck(*a); unsigned exprlen = a->GetValueWidth(); unsigned outputlen = nbits; @@ -1410,7 +1440,7 @@ Expr vc_bvSignExtend(VC vc, Expr ccc, int nbits) { 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); + BVTypeCheck(n); } else { //sign extend @@ -1418,7 +1448,7 @@ Expr vc_bvSignExtend(VC vc, Expr ccc, int nbits) { n = b->CreateTerm(BEEV::BVSX,nbits,*a, width); } - b->BVTypeCheck(n); + BVTypeCheck(n); nodestar output = new node(n); //if(cinterface_exprdelete_on) created_exprs.push_back(output); return output; @@ -1426,7 +1456,7 @@ Expr vc_bvSignExtend(VC vc, Expr ccc, int nbits) { //! Return an int from a constant bitvector expression int getBVInt(Expr e) { - //bmstar b = (bmstar)vc; + //bmstar b = (bmstar)(((stpstar)vc)->bm); nodestar a = (nodestar)e; if(BEEV::BVCONST != a->GetKind()) @@ -1436,7 +1466,7 @@ int getBVInt(Expr e) { //! Return an unsigned int from a constant bitvector expression unsigned int getBVUnsigned(Expr e) { - //bmstar b = (bmstar)vc; + //bmstar b = (bmstar)(((stpstar)vc)->bm); nodestar a = (nodestar)e; if(BEEV::BVCONST != a->GetKind()) @@ -1446,7 +1476,7 @@ unsigned int getBVUnsigned(Expr e) { //! Return an unsigned long long int from a constant bitvector expression unsigned long long int getBVUnsignedLongLong(Expr e) { - //bmstar b = (bmstar)vc; + //bmstar b = (bmstar)(((stpstar)vc)->bm); nodestar a = (nodestar)e; if(BEEV::BVCONST != a->GetKind()) @@ -1462,22 +1492,23 @@ unsigned long long int getBVUnsignedLongLong(Expr e) { Expr vc_simplify(VC vc, Expr e) { - bmstar b = (bmstar)vc; + bmstar b = (bmstar)(((stpstar)vc)->bm); nodestar a = (nodestar)e; + simpstar simp = (simpstar)(((stpstar)vc)->simp); if(BEEV::BOOLEAN_TYPE == a->GetType()) { - nodestar round1 = new node(b->SimplifyFormula_TopLevel(*a,false)); + nodestar round1 = new node(simp->SimplifyFormula_TopLevel(*a,false)); b->Begin_RemoveWrites = true; - nodestar output = new node(b->SimplifyFormula_TopLevel(*round1,false)); + nodestar output = new node(simp->SimplifyFormula_TopLevel(*round1,false)); //if(cinterface_exprdelete_on) created_exprs.push_back(output); b->Begin_RemoveWrites = false; delete round1; return output; } else { - nodestar round1 = new node(b->SimplifyTerm(*a)); + nodestar round1 = new node(simp->SimplifyTerm(*a)); b->Begin_RemoveWrites = true; - nodestar output = new node(b->SimplifyTerm(*round1)); + nodestar output = new node(simp->SimplifyTerm(*round1)); //if(cinterface_exprdelete_on) created_exprs.push_back(output); b->Begin_RemoveWrites = false; delete round1; @@ -1575,7 +1606,7 @@ static char *val_to_binary_str(unsigned nbits, unsigned long long val) { #endif Expr vc_parseExpr(VC vc, const char* infile) { - bmstar b = (bmstar)vc; + bmstar b = (bmstar)(((stpstar)vc)->bm); extern FILE* cvcin; const char * prog = "stp"; @@ -1585,7 +1616,7 @@ Expr vc_parseExpr(VC vc, const char* infile) { BEEV::FatalError(""); } - BEEV::GlobalBeevMgr = b; + //BEEV::GlobalSTP = (stpstar)vc; CONSTANTBV::ErrCode c = CONSTANTBV::BitVector_Boot(); if(0 != c) { cout << CONSTANTBV::BitVector_Error(c) << endl; @@ -1644,7 +1675,7 @@ void vc_registerErrorHandler(void (*error_hdlr)(const char* err_msg)) { int vc_getHashQueryStateToBuffer(VC vc, Expr query) { assert(vc); assert(query); - bmstar b = (bmstar)vc; + bmstar b = (bmstar)(((stpstar)vc)->bm); nodestar qry = (nodestar)query; BEEV::ASTVec v = b->GetAsserts(); BEEV::ASTNode out = b->CreateNode(BEEV::AND,b->CreateNode(BEEV::NOT,*qry),v); @@ -1690,7 +1721,7 @@ int vc_isBool(Expr e) { } void vc_Destroy(VC vc) { - bmstar b = (bmstar)vc; + bmstar b = (bmstar)(((stpstar)vc)->bm); // for(std::vector::iterator it=created_exprs.begin(), // itend=created_exprs.end();it!=itend;it++) { // BEEV::ASTNode * aaa = *it; @@ -1702,7 +1733,7 @@ void vc_Destroy(VC vc) { void vc_DeleteExpr(Expr e) { nodestar input = (nodestar)e; - //bmstar b = (bmstar)vc; + //bmstar b = (bmstar)(((stpstar)vc)->bm); delete input; } @@ -1746,10 +1777,12 @@ int getIWidth (Expr ex) { void vc_printCounterExampleFile(VC vc, int fd) { fdostream os(fd); - bmstar b = (bmstar)vc; + bmstar b = (bmstar)(((stpstar)vc)->bm); + ctrexamplestar ce = (ctrexamplestar)(((stpstar)vc)->Ctr_Example); + BEEV::print_counterexample_flag = true; os << "COUNTEREXAMPLE BEGIN: \n"; - b->PrintCounterExample(true, os); + ce->PrintCounterExample(true, os); os << "COUNTEREXAMPLE END: \n"; } diff --git a/src/counterexample/Makefile b/src/counterexample/Makefile new file mode 100644 index 0000000..f87ad6f --- /dev/null +++ b/src/counterexample/Makefile @@ -0,0 +1,17 @@ +include ../../scripts/Makefile.common + +SRCS = $(wildcard *.cpp) +OBJS = $(SRCS:.cpp=.o) +CFLAGS += -I../sat/mtl -I../sat/simp -I../sat/core + +libcounterexample.a: $(OBJS) depend + $(AR) rc $@ $(OBJS) + $(RANLIB) $@ + +clean: + rm -rf *.o *~ *.a .#* depend + +depend: $(SRCS) + @$(CXX) -MM $(CXXFLAGS) $(SRCS) > $@ + +#-include depend \ No newline at end of file diff --git a/src/main/Globals.cpp b/src/main/Globals.cpp index cc6e725..f195a37 100644 --- a/src/main/Globals.cpp +++ b/src/main/Globals.cpp @@ -8,6 +8,9 @@ // -*- c++ -*- #include "../AST/AST.h" +#include "../STPManager/STPManager.h" +#include "../STPManager/STP.h" + namespace BEEV { //some global variables that are set through commandline options. it @@ -77,11 +80,13 @@ namespace BEEV // 1. bool division_by_zero_returns_one = false; + bool quick_statistics_flag=false; + enum inputStatus input_status = NOT_DECLARED; - - //global BEEVMGR for the parser - BeevMgr * GlobalBeevMgr; + //global BEEVMGR for the parser. Use exclusively for parsing + STP * GlobalSTP; + BeevMgr * ParserBM; void (*vc_error_hdlr)(const char* err_msg) = NULL; /** This is reusable empty vector, for representing empty children diff --git a/src/main/Globals.h b/src/main/Globals.h index 1a475d5..8df7b81 100644 --- a/src/main/Globals.h +++ b/src/main/Globals.h @@ -35,6 +35,7 @@ namespace BEEV class ASTSymbol; class ASTBVConst; class BVSolver; + class STP; //some global variables that are set through commandline options. it //is best that these variables remain global. Default values set @@ -103,6 +104,8 @@ namespace BEEV extern bool division_by_zero_returns_one; + extern bool quick_statistics_flag; + enum inputStatus { NOT_DECLARED =0, // Not included in the input file / stream @@ -115,16 +118,23 @@ namespace BEEV //return types for the GetType() function in ASTNode class enum types { - BOOLEAN_TYPE = 0, BITVECTOR_TYPE, ARRAY_TYPE, UNKNOWN_TYPE + BOOLEAN_TYPE = 0, + BITVECTOR_TYPE, + ARRAY_TYPE, + UNKNOWN_TYPE }; enum SOLVER_RETURN_TYPE { - SOLVER_INVALID=0, SOLVER_VALID=1, SOLVER_UNDECIDED=2, SOLVER_ERROR=-100 + SOLVER_INVALID=0, + SOLVER_VALID=1, + SOLVER_UNDECIDED=2, + SOLVER_ERROR=-100 }; - //Useful global variables. There are very few them - extern BeevMgr * GlobalBeevMgr; + //Useful global variables. Use for parsing only + extern STP * GlobalSTP; + extern BeevMgr * ParserBM; //Empty vector extern std::vector _empty_ASTVec; diff --git a/src/main/Makefile b/src/main/Makefile index 695b70b..e6ccafe 100644 --- a/src/main/Makefile +++ b/src/main/Makefile @@ -5,13 +5,12 @@ OBJS = $(SRCS:.cpp=.o) LIBS = -L../to-sat -ltosat \ -L../STPManager -lstpmgr \ - -L../AST -last \ - -L../printer -lprinter \ - -L../abstraction-refinement -labstractionrefinement \ - -L../sat -lminisat \ + -L../absrefine_counterexample -labstractionrefinement \ -L../simplifier -lsimplifier \ - -L../const-evaluator -lconsteval \ + -L../printer -lprinter \ + -L../AST -last \ -L../extlib-constbv -lconstantbv \ + -L../sat -lminisat \ -L../parser -lparser # This rebuilds each time, because the target "parser" is not created diff --git a/src/main/main.cpp b/src/main/main.cpp index 4826384..59576c2 100644 --- a/src/main/main.cpp +++ b/src/main/main.cpp @@ -9,6 +9,8 @@ #include "../AST/AST.h" #include "../printer/AssortedPrinters.h" #include "../printer/printers.h" +#include "../STPManager/STPManager.h" +#include "../STPManager/STP.h" #ifdef EXT_HASH_MAP using namespace __gnu_cxx; @@ -42,8 +44,24 @@ int main(int argc, char ** argv) { FatalError("Initial allocation of memory failed."); } - bool quick_statistics_flag=false; + BeevMgr * bm = new BeevMgr(); + Simplifier * simp = new Simplifier(bm); + BVSolver* bvsolver = new BVSolver(bm, simp); + ArrayTransformer * arrayTransformer = new ArrayTransformer(bm, simp); + ToSAT * tosat = new ToSAT(bm, simp); + AbsRefine_CounterExample * Ctr_Example = + new AbsRefine_CounterExample(bm, simp, arrayTransformer, tosat); + + ParserBM = bm; + GlobalSTP = + new STP(bm, + simp, + bvsolver, + arrayTransformer, + tosat, + Ctr_Example); + //populate the help string helpstring += "STP version: " + version + "\n\n"; helpstring += "-a : switch optimizations off (optimizations are ON by default)\n"; @@ -171,18 +189,16 @@ int main(int argc, char ** argv) { } } + //want to print the output always from the commandline. + print_output_flag = true; + ASTVec * AssertsQuery = new ASTVec; CONSTANTBV::ErrCode c = CONSTANTBV::BitVector_Boot(); if(0 != c) { cout << CONSTANTBV::BitVector_Error(c) << endl; return 0; } - - //want to print the output always from the commandline. - print_output_flag = true; - GlobalBeevMgr = new BeevMgr(); - ASTVec * AssertsQuery = new ASTVec; - - GlobalBeevMgr->runTimes.start(RunTimes::Parsing); + + bm->GetRunTimes()->start(RunTimes::Parsing); if (smtlib_parser_flag) { smtparse((void*)AssertsQuery); @@ -191,7 +207,7 @@ int main(int argc, char ** argv) { { cvcparse((void*)AssertsQuery); } - GlobalBeevMgr->runTimes.stop(RunTimes::Parsing); + bm->GetRunTimes()->stop(RunTimes::Parsing); ASTNode asserts = (*(ASTVec*)AssertsQuery)[0]; ASTNode query = (*(ASTVec*)AssertsQuery)[1]; @@ -199,7 +215,8 @@ int main(int argc, char ** argv) { { if(smtlib_parser_flag) { - // don't pass the query. It's not returned by the smtlib parser. + // don't pass the query. It's not returned by the smtlib + // parser. printer::SMTLIB_PrintBack(cout, asserts); } else @@ -209,9 +226,11 @@ int main(int argc, char ** argv) { return 0; } //end of PrintBack if - SOLVER_RETURN_TYPE ret = GlobalBeevMgr->TopLevelSAT(asserts, query); - if (quick_statistics_flag) - GlobalBeevMgr->runTimes.print(); - GlobalBeevMgr->PrintOutput(ret); + SOLVER_RETURN_TYPE ret = GlobalSTP->TopLevelSAT(asserts, query); + if (quick_statistics_flag) + { + bm->GetRunTimes()->print(); + } + (GlobalSTP->tosat)->PrintOutput(ret); return 0; }//end of Main diff --git a/src/parser/CVC.lex b/src/parser/CVC.lex index b9cb95a..ee6b990 100644 --- a/src/parser/CVC.lex +++ b/src/parser/CVC.lex @@ -12,8 +12,7 @@ #include "parseCVC_defs.h" using namespace std; - using namespace BEEV; - + using namespace BEEV; extern char *yytext; extern int cvcerror (const char *msg); %} @@ -37,11 +36,11 @@ ANYTHING ({LETTER}|{DIGIT}|{OPCHAR}) [\n] { /*Skip new line */ } [ \t\r\f] { /* skip whitespace */ } -0b{BITS}+ { cvclval.node = new BEEV::ASTNode(BEEV::GlobalBeevMgr->CreateBVConst(yytext+2, 2)); return BVCONST_TOK;} -0bin{BITS}+ { cvclval.node = new BEEV::ASTNode(BEEV::GlobalBeevMgr->CreateBVConst(yytext+4, 2)); return BVCONST_TOK;} -0x{HEX}+ { cvclval.node = new BEEV::ASTNode(BEEV::GlobalBeevMgr->CreateBVConst(yytext+2, 16)); return BVCONST_TOK;} -0h{HEX}+ { cvclval.node = new BEEV::ASTNode(BEEV::GlobalBeevMgr->CreateBVConst(yytext+2, 16)); return BVCONST_TOK;} -0hex{HEX}+ { cvclval.node = new BEEV::ASTNode(BEEV::GlobalBeevMgr->CreateBVConst(yytext+4, 16)); return BVCONST_TOK;} +0b{BITS}+ { cvclval.node = new BEEV::ASTNode(BEEV::ParserBM->CreateBVConst(yytext+2, 2)); return BVCONST_TOK;} +0bin{BITS}+ { cvclval.node = new BEEV::ASTNode(BEEV::ParserBM->CreateBVConst(yytext+4, 2)); return BVCONST_TOK;} +0x{HEX}+ { cvclval.node = new BEEV::ASTNode(BEEV::ParserBM->CreateBVConst(yytext+2, 16)); return BVCONST_TOK;} +0h{HEX}+ { cvclval.node = new BEEV::ASTNode(BEEV::ParserBM->CreateBVConst(yytext+2, 16)); return BVCONST_TOK;} +0hex{HEX}+ { cvclval.node = new BEEV::ASTNode(BEEV::ParserBM->CreateBVConst(yytext+4, 16)); return BVCONST_TOK;} {DIGIT}+ { cvclval.uintval = strtoul(yytext, NULL, 10); return NUMERAL_TOK;} "%" { BEGIN COMMENT;} @@ -119,12 +118,13 @@ ANYTHING ({LETTER}|{DIGIT}|{OPCHAR}) "POP" { return POP_TOK;} (({LETTER})|(_)({ANYTHING}))({ANYTHING})* { - BEEV::ASTNode nptr = BEEV::GlobalBeevMgr->CreateSymbol(yytext); + BEEV::ASTNode nptr = (BEEV::ParserBM)->CreateSymbol(yytext); // Check valuesize to see if it's a prop var. I don't like doing // type determination in the lexer, but it's easier than rewriting // the whole grammar to eliminate the term/formula distinction. - cvclval.node = new BEEV::ASTNode(BEEV::GlobalBeevMgr->GetLetMgr()->ResolveID(nptr)); + cvclval.node = + new BEEV::ASTNode((BEEV::ParserBM->GetLetMgr())->ResolveID(nptr)); //cvclval.node = new BEEV::ASTNode(nptr); if ((cvclval.node)->GetType() == BOOLEAN_TYPE) return FORMID_TOK; diff --git a/src/parser/CVC.y b/src/parser/CVC.y index 2c49432..777e08c 100644 --- a/src/parser/CVC.y +++ b/src/parser/CVC.y @@ -12,7 +12,7 @@ using namespace std; using namespace BEEV; - + // Suppress the bogus warning suppression in bison (it generates // compile error) #undef __GNUC_MINOR__ @@ -22,17 +22,19 @@ #define YYERROR_VERBOSE 1 #define YY_EXIT_FAILURE -1 #define YYPARSE_PARAM AssertsQuery - - - extern int cvclex(void); - extern char* yytext; - extern int cvclineno; - int yyerror(const char *s) { - cout << "syntax error: line " << cvclineno << "\n" << s << endl; - FatalError(""); - return YY_EXIT_FAILURE; - }; - %} + + //BeevMgr * ParserBM = GlobalSTP->bm; + + extern int cvclex(void); + extern char* yytext; + extern int cvclineno; + int yyerror(const char *s) { + cout << "syntax error: line " << cvclineno << "\n" << s << endl; + FatalError(""); + return YY_EXIT_FAILURE; + }; + +%} %union { @@ -176,31 +178,35 @@ cmd : other_cmd counterexample : COUNTEREXAMPLE_TOK ';' { print_counterexample_flag = true; - GlobalBeevMgr->PrintCounterExample(true); + (GlobalSTP->Ctr_Example)->PrintCounterExample(true); } ; other_cmd : other_cmd1 | Query { - ((ASTVec*)AssertsQuery)->push_back(GlobalBeevMgr->CreateNode(TRUE)); + ((ASTVec*)AssertsQuery)->push_back(ParserBM->CreateNode(TRUE)); ((ASTVec*)AssertsQuery)->push_back(*$1); delete $1; } | VarDecls Query { - ((ASTVec*)AssertsQuery)->push_back(GlobalBeevMgr->CreateNode(TRUE)); + ((ASTVec*)AssertsQuery)->push_back(ParserBM->CreateNode(TRUE)); ((ASTVec*)AssertsQuery)->push_back(*$2); delete $2; } | other_cmd1 Query { - ASTVec aaa = GlobalBeevMgr->GetAsserts(); + ASTVec aaa = ParserBM->GetAsserts(); if(aaa.size() == 0) { yyerror("Fatal Error: parsing: GetAsserts() call: no assertions: "); } - ASTNode asserts = GlobalBeevMgr->CreateNode(AND,aaa); + + ASTNode asserts = + aaa.size() == 1 ? + aaa[0] : + ParserBM->CreateNode(AND, aaa); ((ASTVec*)AssertsQuery)->push_back(asserts); ((ASTVec*)AssertsQuery)->push_back(*$2); delete $2; @@ -223,14 +229,14 @@ other_cmd1 : VarDecls Asserts /* push : PUSH_TOK */ /* { */ -/* GlobalBeevMgr->Push(); */ +/* ParserBM->Push(); */ /* } */ /* | */ /* ; */ /* pop : POP_TOK */ /* { */ -/* GlobalBeevMgr->Pop(); */ +/* ParserBM->Pop(); */ /* } */ /* | */ /* ; */ @@ -239,13 +245,13 @@ Asserts : Assert { $$ = new ASTVec; $$->push_back(*$1); - GlobalBeevMgr->AddAssert(*$1); + ParserBM->AddAssert(*$1); delete $1; } | Asserts Assert { $1->push_back(*$2); - GlobalBeevMgr->AddAssert(*$2); + ParserBM->AddAssert(*$2); $$ = $1; delete $2; } @@ -254,7 +260,7 @@ Asserts : Assert Assert : ASSERT_TOK Formula ';' { $$ = $2; } ; -Query : QUERY_TOK Formula ';' { GlobalBeevMgr->AddQuery(*$2); $$ = $2;} +Query : QUERY_TOK Formula ';' { ParserBM->AddQuery(*$2); $$ = $2;} ; @@ -273,14 +279,14 @@ VarDecl : FORM_IDs ':' Type _parser_symbol_table.insert(*i); i->SetIndexWidth($3.indexwidth); i->SetValueWidth($3.valuewidth); - GlobalBeevMgr->ListOfDeclaredVars.push_back(*i); + ParserBM->ListOfDeclaredVars.push_back(*i); } delete $1; } | FORM_IDs ':' Type '=' Expr { //do type checking. if doesn't pass then abort - GlobalBeevMgr->BVTypeCheck(*$5); + BVTypeCheck(*$5); if($3.indexwidth != $5->GetIndexWidth()) yyerror("Fatal Error: parsing: LET Expr: Type check fail: "); if($3.valuewidth != $5->GetValueWidth()) @@ -291,14 +297,14 @@ VarDecl : FORM_IDs ':' Type i->SetValueWidth($5->GetValueWidth()); i->SetIndexWidth($5->GetIndexWidth()); - GlobalBeevMgr->GetLetMgr()->LetExprMgr(*i,*$5); + ParserBM->GetLetMgr()->LetExprMgr(*i,*$5); delete $5; } } | FORM_IDs ':' Type '=' Formula { //do type checking. if doesn't pass then abort - GlobalBeevMgr->BVTypeCheck(*$5); + BVTypeCheck(*$5); if($3.indexwidth != $5->GetIndexWidth()) yyerror("Fatal Error: parsing: LET Expr: Type check fail: "); if($3.valuewidth != $5->GetValueWidth()) @@ -309,7 +315,7 @@ VarDecl : FORM_IDs ':' Type i->SetValueWidth($5->GetValueWidth()); i->SetIndexWidth($5->GetIndexWidth()); - GlobalBeevMgr->GetLetMgr()->LetExprMgr(*i,*$5); + ParserBM->GetLetMgr()->LetExprMgr(*i,*$5); delete $5; } } @@ -384,12 +390,12 @@ IfExpr : IF_TOK Formula THEN_TOK Expr ElseRestExpr if($4->GetIndexWidth() != $5->GetIndexWidth()) yyerror("Width mismatch in IF-THEN-ELSE"); - GlobalBeevMgr->BVTypeCheck(*$2); - GlobalBeevMgr->BVTypeCheck(*$4); - GlobalBeevMgr->BVTypeCheck(*$5); - $$ = new ASTNode(GlobalBeevMgr->CreateTerm(ITE, width, *$2, *$4, *$5)); + BVTypeCheck(*$2); + BVTypeCheck(*$4); + BVTypeCheck(*$5); + $$ = new ASTNode(ParserBM->CreateTerm(ITE, width, *$2, *$4, *$5)); $$->SetIndexWidth($5->GetIndexWidth()); - GlobalBeevMgr->BVTypeCheck(*$$); + BVTypeCheck(*$$); delete $2; delete $4; delete $5; @@ -405,12 +411,12 @@ ElseRestExpr : ELSE_TOK Expr ENDIF_TOK { $$ = $2; } if ($2->GetIndexWidth() != $4->GetValueWidth() || $2->GetIndexWidth() != $5->GetValueWidth()) yyerror("Width mismatch in IF-THEN-ELSE"); - GlobalBeevMgr->BVTypeCheck(*$2); - GlobalBeevMgr->BVTypeCheck(*$4); - GlobalBeevMgr->BVTypeCheck(*$5); - $$ = new ASTNode(GlobalBeevMgr->CreateTerm(ITE, width, *$2, *$4, *$5)); + BVTypeCheck(*$2); + BVTypeCheck(*$4); + BVTypeCheck(*$5); + $$ = new ASTNode(ParserBM->CreateTerm(ITE, width, *$2, *$4, *$5)); $$->SetIndexWidth($5->GetIndexWidth()); - GlobalBeevMgr->BVTypeCheck(*$$); + BVTypeCheck(*$$); delete $2; delete $4; delete $5; @@ -424,11 +430,11 @@ Formula : '(' Formula ')' } | FORMID_TOK { - $$ = new ASTNode(GlobalBeevMgr->GetLetMgr()->ResolveID(*$1)); delete $1; + $$ = new ASTNode(ParserBM->GetLetMgr()->ResolveID(*$1)); delete $1; } | FORMID_TOK '(' Expr ')' { - $$ = new ASTNode(GlobalBeevMgr->CreateNode(PARAMBOOL,*$1,*$3)); + $$ = new ASTNode(ParserBM->CreateNode(PARAMBOOL,*$1,*$3)); delete $1; delete $3; } @@ -438,29 +444,29 @@ Formula : '(' Formula ')' if(width <= (unsigned)$5) yyerror("Fatal Error: BOOLEXTRACT: trying to boolextract a bit which beyond range"); - ASTNode hi = GlobalBeevMgr->CreateBVConst(32, $5); - ASTNode low = GlobalBeevMgr->CreateBVConst(32, $5); - ASTNode * n = new ASTNode(GlobalBeevMgr->CreateTerm(BVEXTRACT,1,*$3,hi,low)); - GlobalBeevMgr->BVTypeCheck(*n); - ASTNode zero = GlobalBeevMgr->CreateBVConst(1,0); - ASTNode * out = new ASTNode(GlobalBeevMgr->CreateNode(EQ,*n,zero)); - GlobalBeevMgr->BVTypeCheck(*out); + ASTNode hi = ParserBM->CreateBVConst(32, $5); + ASTNode low = ParserBM->CreateBVConst(32, $5); + ASTNode * n = new ASTNode(ParserBM->CreateTerm(BVEXTRACT,1,*$3,hi,low)); + BVTypeCheck(*n); + ASTNode zero = ParserBM->CreateBVConst(1,0); + ASTNode * out = new ASTNode(ParserBM->CreateNode(EQ,*n,zero)); + BVTypeCheck(*out); $$ = out; delete $3; } | Expr '=' Expr { - ASTNode * n = new ASTNode(GlobalBeevMgr->CreateNode(EQ, *$1, *$3)); - GlobalBeevMgr->BVTypeCheck(*n); + ASTNode * n = new ASTNode(ParserBM->CreateNode(EQ, *$1, *$3)); + BVTypeCheck(*n); $$ = n; delete $1; delete $3; } | Expr NEQ_TOK Expr { - ASTNode * n = new ASTNode(GlobalBeevMgr->CreateNode(NOT, GlobalBeevMgr->CreateNode(EQ, *$1, *$3))); - GlobalBeevMgr->BVTypeCheck(*n); + ASTNode * n = new ASTNode(ParserBM->CreateNode(NOT, ParserBM->CreateNode(EQ, *$1, *$3))); + BVTypeCheck(*n); $$ = n; delete $1; delete $3; @@ -488,8 +494,8 @@ Formula : '(' Formula ')' vec.push_back(*$9); vec.push_back(*$12); vec.push_back(*$15); - ASTNode * n = new ASTNode(GlobalBeevMgr->CreateNode(FOR,vec)); - GlobalBeevMgr->BVTypeCheck(*n); + ASTNode * n = new ASTNode(ParserBM->CreateNode(FOR,vec)); + BVTypeCheck(*n); $$ = n; delete $3; delete $5; @@ -519,10 +525,10 @@ Formula : '(' Formula ')' vec.push_back(*$5); vec.push_back(*$7); vec.push_back(*$9); - vec.push_back(GlobalBeevMgr->CreateNode(FALSE)); + vec.push_back(ParserBM->CreateNode(FALSE)); vec.push_back(*$12); - ASTNode * n = new ASTNode(GlobalBeevMgr->CreateNode(FOR,vec)); - GlobalBeevMgr->BVTypeCheck(*n); + ASTNode * n = new ASTNode(ParserBM->CreateNode(FOR,vec)); + BVTypeCheck(*n); $$ = n; delete $3; delete $5; @@ -532,111 +538,111 @@ Formula : '(' Formula ')' } | NOT_TOK Formula { - $$ = new ASTNode(GlobalBeevMgr->CreateNode(NOT, *$2)); + $$ = new ASTNode(ParserBM->CreateNode(NOT, *$2)); delete $2; } | Formula OR_TOK Formula %prec OR_TOK { - $$ = new ASTNode(GlobalBeevMgr->CreateNode(OR, *$1, *$3)); + $$ = new ASTNode(ParserBM->CreateNode(OR, *$1, *$3)); delete $1; delete $3; } | Formula NOR_TOK Formula { - $$ = new ASTNode(GlobalBeevMgr->CreateNode(NOR, *$1, *$3)); + $$ = new ASTNode(ParserBM->CreateNode(NOR, *$1, *$3)); delete $1; delete $3; } | Formula AND_TOK Formula %prec AND_TOK { - $$ = new ASTNode(GlobalBeevMgr->CreateNode(AND, *$1, *$3)); + $$ = new ASTNode(ParserBM->CreateNode(AND, *$1, *$3)); delete $1; delete $3; } | Formula NAND_TOK Formula { - $$ = new ASTNode(GlobalBeevMgr->CreateNode(NAND, *$1, *$3)); + $$ = new ASTNode(ParserBM->CreateNode(NAND, *$1, *$3)); delete $1; delete $3; } | Formula IMPLIES_TOK Formula { - $$ = new ASTNode(GlobalBeevMgr->CreateNode(IMPLIES, *$1, *$3)); + $$ = new ASTNode(ParserBM->CreateNode(IMPLIES, *$1, *$3)); delete $1; delete $3; } | Formula IFF_TOK Formula { - $$ = new ASTNode(GlobalBeevMgr->CreateNode(IFF, *$1, *$3)); + $$ = new ASTNode(ParserBM->CreateNode(IFF, *$1, *$3)); delete $1; delete $3; } | Formula XOR_TOK Formula { - $$ = new ASTNode(GlobalBeevMgr->CreateNode(XOR, *$1, *$3)); + $$ = new ASTNode(ParserBM->CreateNode(XOR, *$1, *$3)); delete $1; delete $3; } | BVLT_TOK '(' Expr ',' Expr ')' { - ASTNode * n = new ASTNode(GlobalBeevMgr->CreateNode(BVLT, *$3, *$5)); - GlobalBeevMgr->BVTypeCheck(*n); + ASTNode * n = new ASTNode(ParserBM->CreateNode(BVLT, *$3, *$5)); + BVTypeCheck(*n); $$ = n; delete $3; delete $5; } | BVGT_TOK '(' Expr ',' Expr ')' { - ASTNode * n = new ASTNode(GlobalBeevMgr->CreateNode(BVGT, *$3, *$5)); - GlobalBeevMgr->BVTypeCheck(*n); + ASTNode * n = new ASTNode(ParserBM->CreateNode(BVGT, *$3, *$5)); + BVTypeCheck(*n); $$ = n; delete $3; delete $5; } | BVLE_TOK '(' Expr ',' Expr ')' { - ASTNode * n = new ASTNode(GlobalBeevMgr->CreateNode(BVLE, *$3, *$5)); - GlobalBeevMgr->BVTypeCheck(*n); + ASTNode * n = new ASTNode(ParserBM->CreateNode(BVLE, *$3, *$5)); + BVTypeCheck(*n); $$ = n; delete $3; delete $5; } | BVGE_TOK '(' Expr ',' Expr ')' { - ASTNode * n = new ASTNode(GlobalBeevMgr->CreateNode(BVGE, *$3, *$5)); - GlobalBeevMgr->BVTypeCheck(*n); + ASTNode * n = new ASTNode(ParserBM->CreateNode(BVGE, *$3, *$5)); + BVTypeCheck(*n); $$ = n; delete $3; delete $5; } | BVSLT_TOK '(' Expr ',' Expr ')' { - ASTNode * n = new ASTNode(GlobalBeevMgr->CreateNode(BVSLT, *$3, *$5)); - GlobalBeevMgr->BVTypeCheck(*n); + ASTNode * n = new ASTNode(ParserBM->CreateNode(BVSLT, *$3, *$5)); + BVTypeCheck(*n); $$ = n; delete $3; delete $5; } | BVSGT_TOK '(' Expr ',' Expr ')' { - ASTNode * n = new ASTNode(GlobalBeevMgr->CreateNode(BVSGT, *$3, *$5)); - GlobalBeevMgr->BVTypeCheck(*n); + ASTNode * n = new ASTNode(ParserBM->CreateNode(BVSGT, *$3, *$5)); + BVTypeCheck(*n); $$ = n; delete $3; delete $5; } | BVSLE_TOK '(' Expr ',' Expr ')' { - ASTNode * n = new ASTNode(GlobalBeevMgr->CreateNode(BVSLE, *$3, *$5)); - GlobalBeevMgr->BVTypeCheck(*n); + ASTNode * n = new ASTNode(ParserBM->CreateNode(BVSLE, *$3, *$5)); + BVTypeCheck(*n); $$ = n; delete $3; delete $5; } | BVSGE_TOK '(' Expr ',' Expr ')' { - ASTNode * n = new ASTNode(GlobalBeevMgr->CreateNode(BVSGE, *$3, *$5)); - GlobalBeevMgr->BVTypeCheck(*n); + ASTNode * n = new ASTNode(ParserBM->CreateNode(BVSGE, *$3, *$5)); + BVTypeCheck(*n); $$ = n; delete $3; delete $5; @@ -644,13 +650,13 @@ Formula : '(' Formula ')' | IfForm | TRUELIT_TOK { - $$ = new ASTNode(GlobalBeevMgr->CreateNode(TRUE)); + $$ = new ASTNode(ParserBM->CreateNode(TRUE)); $$->SetIndexWidth(0); $$->SetValueWidth(0); } | FALSELIT_TOK { - $$ = new ASTNode(GlobalBeevMgr->CreateNode(FALSE)); + $$ = new ASTNode(ParserBM->CreateNode(FALSE)); $$->SetIndexWidth(0); $$->SetValueWidth(0); } @@ -659,14 +665,14 @@ Formula : '(' Formula ')' { $$ = $4; //Cleanup the LetIDToExprMap - GlobalBeevMgr->GetLetMgr()->CleanupLetIDMap(); + ParserBM->GetLetMgr()->CleanupLetIDMap(); } ; /*Grammar for ITEs which are Formulas */ IfForm : IF_TOK Formula THEN_TOK Formula ElseRestForm { - $$ = new ASTNode(GlobalBeevMgr->CreateNode(ITE, *$2, *$4, *$5)); + $$ = new ASTNode(ParserBM->CreateNode(ITE, *$2, *$4, *$5)); delete $2; delete $4; delete $5; @@ -676,7 +682,7 @@ IfForm : IF_TOK Formula THEN_TOK Formula ElseRestForm ElseRestForm : ELSE_TOK Formula ENDIF_TOK { $$ = $2; } | ELSIF_TOK Formula THEN_TOK Formula ElseRestForm { - $$ = new ASTNode(GlobalBeevMgr->CreateNode(ITE, *$2, *$4, *$5)); + $$ = new ASTNode(ParserBM->CreateNode(ITE, *$2, *$4, *$5)); delete $2; delete $4; delete $5; @@ -687,39 +693,39 @@ ElseRestForm : ELSE_TOK Formula ENDIF_TOK { $$ = $2; } Exprs : Expr { $$ = new ASTVec; - GlobalBeevMgr->BVTypeCheck(*$1); + BVTypeCheck(*$1); $$->push_back(*$1); delete $1; } | Exprs ',' Expr { $1->push_back(*$3); - GlobalBeevMgr->BVTypeCheck(*$3); + BVTypeCheck(*$3); $$ = $1; delete $3; } ; /* Grammar for Expr */ -Expr : TERMID_TOK { $$ = new ASTNode(GlobalBeevMgr->GetLetMgr()->ResolveID(*$1)); delete $1;} +Expr : TERMID_TOK { $$ = new ASTNode(ParserBM->GetLetMgr()->ResolveID(*$1)); delete $1;} | '(' Expr ')' { $$ = $2; } | BVCONST_TOK { $$ = $1; } | BOOL_TO_BV_TOK '(' Formula ')' { - GlobalBeevMgr->BVTypeCheck(*$3); - ASTNode one = GlobalBeevMgr->CreateBVConst(1,1); - ASTNode zero = GlobalBeevMgr->CreateBVConst(1,0); + BVTypeCheck(*$3); + ASTNode one = ParserBM->CreateBVConst(1,1); + ASTNode zero = ParserBM->CreateBVConst(1,0); //return ITE(*$3, length(1), 0bin1, 0bin0) - $$ = new ASTNode(GlobalBeevMgr->CreateTerm(ITE,1,*$3,one,zero)); + $$ = new ASTNode(ParserBM->CreateTerm(ITE,1,*$3,one,zero)); delete $3; } | Expr '[' Expr ']' { // valuewidth is same as array, indexwidth is 0. unsigned int width = $1->GetValueWidth(); - ASTNode * n = new ASTNode(GlobalBeevMgr->CreateTerm(READ, width, *$1, *$3)); - GlobalBeevMgr->BVTypeCheck(*n); + ASTNode * n = new ASTNode(ParserBM->CreateTerm(READ, width, *$1, *$3)); + BVTypeCheck(*n); $$ = n; delete $1; @@ -729,8 +735,8 @@ Expr : TERMID_TOK { $$ = new ASTNode(GlobalBeevMgr->GetLetMgr()->ResolveID { // valuewidth is same as array, indexwidth is 0. unsigned int width = $1->GetValueWidth(); - ASTNode * n = new ASTNode(GlobalBeevMgr->CreateTerm(READ, width, *$1, *$3)); - GlobalBeevMgr->BVTypeCheck(*n); + ASTNode * n = new ASTNode(ParserBM->CreateTerm(READ, width, *$1, *$3)); + BVTypeCheck(*n); $$ = n; delete $1; @@ -745,18 +751,18 @@ Expr : TERMID_TOK { $$ = new ASTNode(GlobalBeevMgr->GetLetMgr()->ResolveID if((unsigned)$3 >= $1->GetValueWidth()) yyerror("Parsing: Wrong width in BVEXTRACT\n"); - ASTNode hi = GlobalBeevMgr->CreateBVConst(32, $3); - ASTNode low = GlobalBeevMgr->CreateBVConst(32, $5); - ASTNode * n = new ASTNode(GlobalBeevMgr->CreateTerm(BVEXTRACT, width, *$1,hi,low)); - GlobalBeevMgr->BVTypeCheck(*n); + ASTNode hi = ParserBM->CreateBVConst(32, $3); + ASTNode low = ParserBM->CreateBVConst(32, $5); + ASTNode * n = new ASTNode(ParserBM->CreateTerm(BVEXTRACT, width, *$1,hi,low)); + BVTypeCheck(*n); $$ = n; delete $1; } | BVNEG_TOK Expr { unsigned int width = $2->GetValueWidth(); - ASTNode * n = new ASTNode(GlobalBeevMgr->CreateTerm(BVNEG, width, *$2)); - GlobalBeevMgr->BVTypeCheck(*n); + ASTNode * n = new ASTNode(ParserBM->CreateTerm(BVNEG, width, *$2)); + BVTypeCheck(*n); $$ = n; delete $2; } @@ -766,8 +772,8 @@ Expr : TERMID_TOK { $$ = new ASTNode(GlobalBeevMgr->GetLetMgr()->ResolveID if (width != $3->GetValueWidth()) { yyerror("Width mismatch in AND"); } - ASTNode * n = new ASTNode(GlobalBeevMgr->CreateTerm(BVAND, width, *$1, *$3)); - GlobalBeevMgr->BVTypeCheck(*n); + ASTNode * n = new ASTNode(ParserBM->CreateTerm(BVAND, width, *$1, *$3)); + BVTypeCheck(*n); $$ = n; delete $1; delete $3; @@ -778,8 +784,8 @@ Expr : TERMID_TOK { $$ = new ASTNode(GlobalBeevMgr->GetLetMgr()->ResolveID if (width != $3->GetValueWidth()) { yyerror("Width mismatch in OR"); } - ASTNode * n = new ASTNode(GlobalBeevMgr->CreateTerm(BVOR, width, *$1, *$3)); - GlobalBeevMgr->BVTypeCheck(*n); + ASTNode * n = new ASTNode(ParserBM->CreateTerm(BVOR, width, *$1, *$3)); + BVTypeCheck(*n); $$ = n; delete $1; delete $3; @@ -790,8 +796,8 @@ Expr : TERMID_TOK { $$ = new ASTNode(GlobalBeevMgr->GetLetMgr()->ResolveID if (width != $5->GetValueWidth()) { yyerror("Width mismatch in XOR"); } - ASTNode * n = new ASTNode(GlobalBeevMgr->CreateTerm(BVXOR, width, *$3, *$5)); - GlobalBeevMgr->BVTypeCheck(*n); + ASTNode * n = new ASTNode(ParserBM->CreateTerm(BVXOR, width, *$3, *$5)); + BVTypeCheck(*n); $$ = n; delete $3; delete $5; @@ -802,8 +808,8 @@ Expr : TERMID_TOK { $$ = new ASTNode(GlobalBeevMgr->GetLetMgr()->ResolveID if (width != $5->GetValueWidth()) { yyerror("Width mismatch in NAND"); } - ASTNode * n = new ASTNode(GlobalBeevMgr->CreateTerm(BVNAND, width, *$3, *$5)); - GlobalBeevMgr->BVTypeCheck(*n); + ASTNode * n = new ASTNode(ParserBM->CreateTerm(BVNAND, width, *$3, *$5)); + BVTypeCheck(*n); $$ = n; delete $3; @@ -815,8 +821,8 @@ Expr : TERMID_TOK { $$ = new ASTNode(GlobalBeevMgr->GetLetMgr()->ResolveID if (width != $5->GetValueWidth()) { yyerror("Width mismatch in NOR"); } - ASTNode * n = new ASTNode(GlobalBeevMgr->CreateTerm(BVNOR, width, *$3, *$5)); - GlobalBeevMgr->BVTypeCheck(*n); + ASTNode * n = new ASTNode(ParserBM->CreateTerm(BVNOR, width, *$3, *$5)); + BVTypeCheck(*n); $$ = n; delete $3; @@ -828,8 +834,8 @@ Expr : TERMID_TOK { $$ = new ASTNode(GlobalBeevMgr->GetLetMgr()->ResolveID if (width != $5->GetValueWidth()) { yyerror("Width mismatch in NOR"); } - ASTNode * n = new ASTNode(GlobalBeevMgr->CreateTerm(BVXNOR, width, *$3, *$5)); - GlobalBeevMgr->BVTypeCheck(*n); + ASTNode * n = new ASTNode(ParserBM->CreateTerm(BVXNOR, width, *$3, *$5)); + BVTypeCheck(*n); $$ = n; delete $3; @@ -840,15 +846,15 @@ Expr : TERMID_TOK { $$ = new ASTNode(GlobalBeevMgr->GetLetMgr()->ResolveID //width of the expr which is being sign //extended. $5 is the resulting length of the //signextended expr - GlobalBeevMgr->BVTypeCheck(*$3); + BVTypeCheck(*$3); if($3->GetValueWidth() == $5) { $$ = $3; } else { - ASTNode width = GlobalBeevMgr->CreateBVConst(32,$5); + ASTNode width = ParserBM->CreateBVConst(32,$5); ASTNode *n = - new ASTNode(GlobalBeevMgr->CreateTerm(BVSX, $5,*$3,width)); - GlobalBeevMgr->BVTypeCheck(*n); + new ASTNode(ParserBM->CreateTerm(BVSX, $5,*$3,width)); + BVTypeCheck(*n); $$ = n; delete $3; } @@ -856,8 +862,8 @@ Expr : TERMID_TOK { $$ = new ASTNode(GlobalBeevMgr->GetLetMgr()->ResolveID | Expr BVCONCAT_TOK Expr { unsigned int width = $1->GetValueWidth() + $3->GetValueWidth(); - ASTNode * n = new ASTNode(GlobalBeevMgr->CreateTerm(BVCONCAT, width, *$1, *$3)); - GlobalBeevMgr->BVTypeCheck(*n); + ASTNode * n = new ASTNode(ParserBM->CreateTerm(BVCONCAT, width, *$1, *$3)); + BVTypeCheck(*n); $$ = n; delete $1; @@ -865,47 +871,47 @@ Expr : TERMID_TOK { $$ = new ASTNode(GlobalBeevMgr->GetLetMgr()->ResolveID } | Expr BVLEFTSHIFT_TOK NUMERAL_TOK { - ASTNode zero_bits = GlobalBeevMgr->CreateZeroConst($3); + ASTNode zero_bits = ParserBM->CreateZeroConst($3); ASTNode * n = - new ASTNode(GlobalBeevMgr->CreateTerm(BVCONCAT, + new ASTNode(ParserBM->CreateTerm(BVCONCAT, $1->GetValueWidth() + $3, *$1, zero_bits)); - GlobalBeevMgr->BVTypeCheck(*n); + BVTypeCheck(*n); $$ = n; delete $1; } | Expr BVRIGHTSHIFT_TOK NUMERAL_TOK { - ASTNode len = GlobalBeevMgr->CreateZeroConst($3); + ASTNode len = ParserBM->CreateZeroConst($3); unsigned int w = $1->GetValueWidth(); //the amount by which you are rightshifting //is less-than/equal-to the length of input //bitvector if((unsigned)$3 < w) { - ASTNode hi = GlobalBeevMgr->CreateBVConst(32,w-1); - ASTNode low = GlobalBeevMgr->CreateBVConst(32,$3); - ASTNode extract = GlobalBeevMgr->CreateTerm(BVEXTRACT,w-$3,*$1,hi,low); - ASTNode * n = new ASTNode(GlobalBeevMgr->CreateTerm(BVCONCAT, w,len, extract)); - GlobalBeevMgr->BVTypeCheck(*n); + ASTNode hi = ParserBM->CreateBVConst(32,w-1); + ASTNode low = ParserBM->CreateBVConst(32,$3); + ASTNode extract = ParserBM->CreateTerm(BVEXTRACT,w-$3,*$1,hi,low); + ASTNode * n = new ASTNode(ParserBM->CreateTerm(BVCONCAT, w,len, extract)); + BVTypeCheck(*n); $$ = n; } else - $$ = new ASTNode(GlobalBeevMgr->CreateZeroConst(w)); + $$ = new ASTNode(ParserBM->CreateZeroConst(w)); delete $1; } | BVPLUS_TOK '(' NUMERAL_TOK ',' Exprs ')' { - ASTNode * n = new ASTNode(GlobalBeevMgr->CreateTerm(BVPLUS, $3, *$5)); - GlobalBeevMgr->BVTypeCheck(*n); + ASTNode * n = new ASTNode(ParserBM->CreateTerm(BVPLUS, $3, *$5)); + BVTypeCheck(*n); $$ = n; delete $5; } | BVSUB_TOK '(' NUMERAL_TOK ',' Expr ',' Expr ')' { - ASTNode * n = new ASTNode(GlobalBeevMgr->CreateTerm(BVSUB, $3, *$5, *$7)); - GlobalBeevMgr->BVTypeCheck(*n); + ASTNode * n = new ASTNode(ParserBM->CreateTerm(BVSUB, $3, *$5, *$7)); + BVTypeCheck(*n); $$ = n; delete $5; @@ -914,15 +920,15 @@ Expr : TERMID_TOK { $$ = new ASTNode(GlobalBeevMgr->GetLetMgr()->ResolveID | BVUMINUS_TOK '(' Expr ')' { unsigned width = $3->GetValueWidth(); - ASTNode * n = new ASTNode(GlobalBeevMgr->CreateTerm(BVUMINUS,width,*$3)); - GlobalBeevMgr->BVTypeCheck(*n); + ASTNode * n = new ASTNode(ParserBM->CreateTerm(BVUMINUS,width,*$3)); + BVTypeCheck(*n); $$ = n; delete $3; } | BVMULT_TOK '(' NUMERAL_TOK ',' Expr ',' Expr ')' { - ASTNode * n = new ASTNode(GlobalBeevMgr->CreateTerm(BVMULT, $3, *$5, *$7)); - GlobalBeevMgr->BVTypeCheck(*n); + ASTNode * n = new ASTNode(ParserBM->CreateTerm(BVMULT, $3, *$5, *$7)); + BVTypeCheck(*n); $$ = n; delete $5; @@ -930,8 +936,8 @@ Expr : TERMID_TOK { $$ = new ASTNode(GlobalBeevMgr->GetLetMgr()->ResolveID } | BVDIV_TOK '(' NUMERAL_TOK ',' Expr ',' Expr ')' { - ASTNode * n = new ASTNode(GlobalBeevMgr->CreateTerm(BVDIV, $3, *$5, *$7)); - GlobalBeevMgr->BVTypeCheck(*n); + ASTNode * n = new ASTNode(ParserBM->CreateTerm(BVDIV, $3, *$5, *$7)); + BVTypeCheck(*n); $$ = n; delete $5; @@ -939,8 +945,8 @@ Expr : TERMID_TOK { $$ = new ASTNode(GlobalBeevMgr->GetLetMgr()->ResolveID } | BVMOD_TOK '(' NUMERAL_TOK ',' Expr ',' Expr ')' { - ASTNode * n = new ASTNode(GlobalBeevMgr->CreateTerm(BVMOD, $3, *$5, *$7)); - GlobalBeevMgr->BVTypeCheck(*n); + ASTNode * n = new ASTNode(ParserBM->CreateTerm(BVMOD, $3, *$5, *$7)); + BVTypeCheck(*n); $$ = n; delete $5; @@ -948,8 +954,8 @@ Expr : TERMID_TOK { $$ = new ASTNode(GlobalBeevMgr->GetLetMgr()->ResolveID } | SBVDIV_TOK '(' NUMERAL_TOK ',' Expr ',' Expr ')' { - ASTNode * n = new ASTNode(GlobalBeevMgr->CreateTerm(SBVDIV, $3, *$5, *$7)); - GlobalBeevMgr->BVTypeCheck(*n); + ASTNode * n = new ASTNode(ParserBM->CreateTerm(SBVDIV, $3, *$5, *$7)); + BVTypeCheck(*n); $$ = n; delete $5; @@ -957,8 +963,8 @@ Expr : TERMID_TOK { $$ = new ASTNode(GlobalBeevMgr->GetLetMgr()->ResolveID } | SBVREM_TOK '(' NUMERAL_TOK ',' Expr ',' Expr ')' { - ASTNode * n = new ASTNode(GlobalBeevMgr->CreateTerm(SBVREM, $3, *$5, *$7)); - GlobalBeevMgr->BVTypeCheck(*n); + ASTNode * n = new ASTNode(ParserBM->CreateTerm(SBVREM, $3, *$5, *$7)); + BVTypeCheck(*n); $$ = n; delete $5; delete $7; @@ -969,7 +975,7 @@ Expr : TERMID_TOK { $$ = new ASTNode(GlobalBeevMgr->GetLetMgr()->ResolveID { $$ = $4; //Cleanup the LetIDToExprMap - //GlobalBeevMgr->CleanupLetIDMap(); + //ParserBM->CleanupLetIDMap(); } ; @@ -981,23 +987,23 @@ ArrayUpdateExpr : Expr WITH_TOK Updates ASTNodeMap::iterator it = $3->begin(); ASTNodeMap::iterator itend = $3->end(); - result = new ASTNode(GlobalBeevMgr->CreateTerm(WRITE, + result = new ASTNode(ParserBM->CreateTerm(WRITE, width, *$1, (*it).first, (*it).second)); result->SetIndexWidth($1->GetIndexWidth()); - GlobalBeevMgr->BVTypeCheck(*result); + BVTypeCheck(*result); for(it++;it!=itend;it++) { - result = new ASTNode(GlobalBeevMgr->CreateTerm(WRITE, + result = new ASTNode(ParserBM->CreateTerm(WRITE, width, *result, (*it).first, (*it).second)); result->SetIndexWidth($1->GetIndexWidth()); - GlobalBeevMgr->BVTypeCheck(*result); + BVTypeCheck(*result); } - GlobalBeevMgr->BVTypeCheck(*result); + BVTypeCheck(*result); $$ = result; delete $3; } @@ -1022,7 +1028,7 @@ LetDecls : LetDecl LetDecl : FORMID_TOK '=' Expr { //Expr must typecheck - GlobalBeevMgr->BVTypeCheck(*$3); + BVTypeCheck(*$3); //set the valuewidth of the identifier $1->SetValueWidth($3->GetValueWidth()); @@ -1036,14 +1042,14 @@ LetDecl : FORMID_TOK '=' Expr // //2. Ensure that LET variables are not //2. defined more than once - GlobalBeevMgr->GetLetMgr()->LetExprMgr(*$1,*$3); + ParserBM->GetLetMgr()->LetExprMgr(*$1,*$3); delete $1; delete $3; } | FORMID_TOK ':' Type '=' Expr { //do type checking. if doesn't pass then abort - GlobalBeevMgr->BVTypeCheck(*$5); + BVTypeCheck(*$5); if($3.indexwidth != $5->GetIndexWidth()) yyerror("Fatal Error: parsing: LET Expr: Type check fail: "); @@ -1054,28 +1060,28 @@ LetDecl : FORMID_TOK '=' Expr $1->SetValueWidth($5->GetValueWidth()); $1->SetIndexWidth($5->GetIndexWidth()); - GlobalBeevMgr->GetLetMgr()->LetExprMgr(*$1,*$5); + ParserBM->GetLetMgr()->LetExprMgr(*$1,*$5); delete $1; delete $5; } | FORMID_TOK '=' Formula { //Expr must typecheck - GlobalBeevMgr->BVTypeCheck(*$3); + BVTypeCheck(*$3); //set the valuewidth of the identifier $1->SetValueWidth($3->GetValueWidth()); $1->SetIndexWidth($3->GetIndexWidth()); //Do LET-expr management - GlobalBeevMgr->GetLetMgr()->LetExprMgr(*$1,*$3); + ParserBM->GetLetMgr()->LetExprMgr(*$1,*$3); delete $1; delete $3; } | FORMID_TOK ':' Type '=' Formula { //do type checking. if doesn't pass then abort - GlobalBeevMgr->BVTypeCheck(*$5); + BVTypeCheck(*$5); if($3.indexwidth != $5->GetIndexWidth()) yyerror("Fatal Error: parsing: LET Expr: Type check fail: "); @@ -1087,7 +1093,7 @@ LetDecl : FORMID_TOK '=' Expr $1->SetIndexWidth($5->GetIndexWidth()); //Do LET-expr management - GlobalBeevMgr->GetLetMgr()->LetExprMgr(*$1,*$5); + ParserBM->GetLetMgr()->LetExprMgr(*$1,*$5); delete $1; delete $5; } diff --git a/src/parser/Makefile b/src/parser/Makefile index 1a1b6a4..210d0dd 100644 --- a/src/parser/Makefile +++ b/src/parser/Makefile @@ -8,8 +8,6 @@ OBJS = $(SRCS:.cpp=.o) LIBS = -L../AST -last -L../sat -lminisat -L../simplifier -lsimplifier -L../bitvec -lconsteval -L../constantbv -lconstantbv CFLAGS += -I../sat/mtl -I../sat/core -I../sat/simp -I../sat/unsound -#all: parseSMT.cpp lexSMT.cpp parseCVC.cpp lexCVC.cpp let-funcs.cpp parser parseCVC.o lexCVC.o let-funcs.o - libparser.a: $(OBJS) $(AR) rc $@ $^ $(RANLIB) $@ @@ -31,4 +29,4 @@ parseSMT_defs.h parseSMT.cpp:smtlib.y @cp y.tab.h parseSMT_defs.h clean: - rm -rf *.o parseCVC_defs.h parseSMT_defs.h *~ lexSMT.cpp parseSMT.cpp lexCVC.cpp parseCVC.cpp *.output parser y.tab.* lex.yy.c .#* + rm -rf *.o *.a parseCVC_defs.h parseSMT_defs.h *~ lexSMT.cpp parseSMT.cpp lexCVC.cpp parseCVC.cpp *.output parser y.tab.* lex.yy.c .#* diff --git a/src/parser/let-funcs.h b/src/parser/let-funcs.h new file mode 100644 index 0000000..33b42f7 --- /dev/null +++ b/src/parser/let-funcs.h @@ -0,0 +1,50 @@ +// -*- c++ -*- +/******************************************************************** + * AUTHORS: Vijay Ganesh + * + * BEGIN DATE: November, 2005 + * + * LICENSE: Please view LICENSE file in the home dir of this Program + ********************************************************************/ + +#ifndef LET_H +#define LET_H + +#include "../AST/AST.h" +namespace BEEV +{ + //LET Management + class LETMgr + { + 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; + ASTNode ASTUndefined; + + public: + + LETMgr(ASTNode undefined) + { + _letid_expr_map = new ASTNodeMap(); + ASTUndefined = undefined; + } + + 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); + };// End of class LETMgr +}; //end of namespace +#endif diff --git a/src/parser/parser.h b/src/parser/parser.h index 06267d6..09e28ba 100644 --- a/src/parser/parser.h +++ b/src/parser/parser.h @@ -12,11 +12,11 @@ #include "../AST/AST.h" #include "../STPManager/STPManager.h" +#include "../STPManager/STP.h" namespace BEEV { //external parser table for declared symbols. extern ASTNodeSet _parser_symbol_table; - }; //end of namespace #endif diff --git a/src/parser/smtlib.lex b/src/parser/smtlib.lex index db20a16..ab44d03 100644 --- a/src/parser/smtlib.lex +++ b/src/parser/smtlib.lex @@ -42,7 +42,9 @@ extern char *smttext; extern int smterror (const char *msg); - + + //BeevMgr * ParserBM = GlobalSTP->bm; + // File-static (local to this file) variables and functions static std::string _string_lit; static char escapeChar(char c) { @@ -79,10 +81,10 @@ ANYTHING ({LETTER}|{DIGIT}|{OPCHAR}) bit{DIGIT}+ { char c = smttext[3]; if (c == '1') { - smtlval.node = new BEEV::ASTNode(GlobalBeevMgr->CreateOneConst(1)); + smtlval.node = new BEEV::ASTNode(ParserBM->CreateOneConst(1)); } else { - smtlval.node = new BEEV::ASTNode(GlobalBeevMgr->CreateZeroConst(1)); + smtlval.node = new BEEV::ASTNode(ParserBM->CreateZeroConst(1)); } return BITCONST_TOK; }; @@ -215,12 +217,12 @@ bit{DIGIT}+ { "boolbv" { return BOOL_TO_BV_TOK;} (({LETTER})|(_)({ANYTHING}))({ANYTHING})* { - BEEV::ASTNode nptr = BEEV::GlobalBeevMgr->CreateSymbol(smttext); + BEEV::ASTNode nptr = ParserBM->CreateSymbol(smttext); // Check valuesize to see if it's a prop var. I don't like doing // type determination in the lexer, but it's easier than rewriting // the whole grammar to eliminate the term/formula distinction. - smtlval.node = new BEEV::ASTNode(BEEV::GlobalBeevMgr->GetLetMgr()->ResolveID(nptr)); + smtlval.node = new BEEV::ASTNode((ParserBM->GetLetMgr())->ResolveID(nptr)); //smtlval.node = new BEEV::ASTNode(nptr); if ((smtlval.node)->GetType() == BOOLEAN_TYPE) return FORMID_TOK; diff --git a/src/parser/smtlib.y b/src/parser/smtlib.y index 9727ff3..a8c0482 100644 --- a/src/parser/smtlib.y +++ b/src/parser/smtlib.y @@ -46,9 +46,10 @@ extern char* smttext; extern int smtlineno; - extern int smtlex(void); + //BEEV::BeevMgr * ParserBM = GlobalSTP->bm; + int yyerror(const char *s) { cout << "syntax error: line " << smtlineno << "\n" << s << endl; cout << " token: " << smttext << endl; @@ -208,7 +209,7 @@ cmd: ASTNode assumptions; if($1 == NULL) { - assumptions = GlobalBeevMgr->CreateNode(TRUE); + assumptions = ParserBM->CreateNode(TRUE); } else { @@ -217,7 +218,7 @@ cmd: if(query.IsNull()) { - query = GlobalBeevMgr->CreateNode(FALSE); + query = ParserBM->CreateNode(FALSE); } ((ASTVec*)AssertsQuery)->push_back(assumptions); @@ -232,7 +233,7 @@ benchmark: { if($4 != NULL){ if($4->size() > 1) - $$ = new ASTNode(GlobalBeevMgr->CreateNode(AND,*$4)); + $$ = new ASTNode(ParserBM->CreateNode(AND,*$4)); else $$ = new ASTNode((*$4)[0]); delete $4; @@ -258,7 +259,7 @@ bench_attributes: $$ = new ASTVec; if ($1 != NULL) { $$->push_back(*$1); - GlobalBeevMgr->AddAssert(*$1); + ParserBM->AddAssert(*$1); delete $1; } } @@ -266,7 +267,7 @@ bench_attributes: { if ($1 != NULL && $2 != NULL) { $1->push_back(*$2); - GlobalBeevMgr->AddAssert(*$2); + ParserBM->AddAssert(*$2); $$ = $1; delete $2; } @@ -416,7 +417,7 @@ var_decl: $2->SetIndexWidth($3.indexwidth); $2->SetValueWidth($3.valuewidth); if(print_STPinput_back_flag) - GlobalBeevMgr->ListOfDeclaredVars.push_back(*$2); + ParserBM->ListOfDeclaredVars.push_back(*$2); } | LPAREN_TOK FORMID_TOK RPAREN_TOK { @@ -426,7 +427,7 @@ var_decl: $2->SetIndexWidth(0); $2->SetValueWidth(0); if(print_STPinput_back_flag) - GlobalBeevMgr->ListOfDeclaredVars.push_back(*$2); + ParserBM->ListOfDeclaredVars.push_back(*$2); } ; @@ -453,13 +454,13 @@ an_formulas: an_formula: TRUE_TOK { - $$ = new ASTNode(GlobalBeevMgr->CreateNode(TRUE)); + $$ = new ASTNode(ParserBM->CreateNode(TRUE)); $$->SetIndexWidth(0); $$->SetValueWidth(0); } | FALSE_TOK { - $$ = new ASTNode(GlobalBeevMgr->CreateNode(FALSE)); + $$ = new ASTNode(ParserBM->CreateNode(FALSE)); $$->SetIndexWidth(0); $$->SetValueWidth(0); } @@ -470,8 +471,8 @@ an_formula: | LPAREN_TOK EQ_TOK an_term an_term RPAREN_TOK //| LPAREN_TOK EQ_TOK an_term an_term annotations RPAREN_TOK { - ASTNode * n = new ASTNode(GlobalBeevMgr->CreateSimplifiedEQ(*$3, *$4)); - GlobalBeevMgr->BVTypeCheck(*n); + ASTNode * n = new ASTNode((GlobalSTP->simp)->CreateSimplifiedEQ(*$3, *$4)); + BVTypeCheck(*n); $$ = n; delete $3; delete $4; @@ -486,9 +487,9 @@ an_formula: for(ASTVec::const_iterator it=terms.begin(),itend=terms.end(); it!=itend; it++) { for(ASTVec::const_iterator it2=it+1; it2!=itend; it2++) { - ASTNode * n = new ASTNode(GlobalBeevMgr->CreateNode(NOT, GlobalBeevMgr->CreateNode(EQ, *it, *it2))); + ASTNode * n = new ASTNode(ParserBM->CreateNode(NOT, ParserBM->CreateNode(EQ, *it, *it2))); - GlobalBeevMgr->BVTypeCheck(*n); + BVTypeCheck(*n); forms.push_back(*n); } @@ -499,7 +500,7 @@ an_formula: $$ = (forms.size() == 1) ? new ASTNode(forms[0]) : - new ASTNode(GlobalBeevMgr->CreateNode(AND, forms)); + new ASTNode(ParserBM->CreateNode(AND, forms)); delete $3; } @@ -507,8 +508,8 @@ an_formula: | LPAREN_TOK BVSLT_TOK an_term an_term RPAREN_TOK //| LPAREN_TOK BVSLT_TOK an_term an_term annotations RPAREN_TOK { - ASTNode * n = new ASTNode(GlobalBeevMgr->CreateNode(BVSLT, *$3, *$4)); - GlobalBeevMgr->BVTypeCheck(*n); + ASTNode * n = new ASTNode(ParserBM->CreateNode(BVSLT, *$3, *$4)); + BVTypeCheck(*n); $$ = n; delete $3; delete $4; @@ -516,8 +517,8 @@ an_formula: | LPAREN_TOK BVSLE_TOK an_term an_term RPAREN_TOK //| LPAREN_TOK BVSLE_TOK an_term an_term annotations RPAREN_TOK { - ASTNode * n = new ASTNode(GlobalBeevMgr->CreateNode(BVSLE, *$3, *$4)); - GlobalBeevMgr->BVTypeCheck(*n); + ASTNode * n = new ASTNode(ParserBM->CreateNode(BVSLE, *$3, *$4)); + BVTypeCheck(*n); $$ = n; delete $3; delete $4; @@ -525,8 +526,8 @@ an_formula: | LPAREN_TOK BVSGT_TOK an_term an_term RPAREN_TOK //| LPAREN_TOK BVSGT_TOK an_term an_term annotations RPAREN_TOK { - ASTNode * n = new ASTNode(GlobalBeevMgr->CreateNode(BVSGT, *$3, *$4)); - GlobalBeevMgr->BVTypeCheck(*n); + ASTNode * n = new ASTNode(ParserBM->CreateNode(BVSGT, *$3, *$4)); + BVTypeCheck(*n); $$ = n; delete $3; delete $4; @@ -534,8 +535,8 @@ an_formula: | LPAREN_TOK BVSGE_TOK an_term an_term RPAREN_TOK //| LPAREN_TOK BVSGE_TOK an_term an_term annotations RPAREN_TOK { - ASTNode * n = new ASTNode(GlobalBeevMgr->CreateNode(BVSGE, *$3, *$4)); - GlobalBeevMgr->BVTypeCheck(*n); + ASTNode * n = new ASTNode(ParserBM->CreateNode(BVSGE, *$3, *$4)); + BVTypeCheck(*n); $$ = n; delete $3; delete $4; @@ -543,8 +544,8 @@ an_formula: | LPAREN_TOK BVLT_TOK an_term an_term RPAREN_TOK //| LPAREN_TOK BVLT_TOK an_term an_term annotations RPAREN_TOK { - ASTNode * n = new ASTNode(GlobalBeevMgr->CreateNode(BVLT, *$3, *$4)); - GlobalBeevMgr->BVTypeCheck(*n); + ASTNode * n = new ASTNode(ParserBM->CreateNode(BVLT, *$3, *$4)); + BVTypeCheck(*n); $$ = n; delete $3; delete $4; @@ -552,8 +553,8 @@ an_formula: | LPAREN_TOK BVLE_TOK an_term an_term RPAREN_TOK //| LPAREN_TOK BVLE_TOK an_term an_term annotations RPAREN_TOK { - ASTNode * n = new ASTNode(GlobalBeevMgr->CreateNode(BVLE, *$3, *$4)); - GlobalBeevMgr->BVTypeCheck(*n); + ASTNode * n = new ASTNode(ParserBM->CreateNode(BVLE, *$3, *$4)); + BVTypeCheck(*n); $$ = n; delete $3; delete $4; @@ -561,8 +562,8 @@ an_formula: | LPAREN_TOK BVGT_TOK an_term an_term RPAREN_TOK //| LPAREN_TOK BVGT_TOK an_term an_term annotations RPAREN_TOK { - ASTNode * n = new ASTNode(GlobalBeevMgr->CreateNode(BVGT, *$3, *$4)); - GlobalBeevMgr->BVTypeCheck(*n); + ASTNode * n = new ASTNode(ParserBM->CreateNode(BVGT, *$3, *$4)); + BVTypeCheck(*n); $$ = n; delete $3; delete $4; @@ -570,8 +571,8 @@ an_formula: | LPAREN_TOK BVGE_TOK an_term an_term RPAREN_TOK //| LPAREN_TOK BVGE_TOK an_term an_term annotations RPAREN_TOK { - ASTNode * n = new ASTNode(GlobalBeevMgr->CreateNode(BVGE, *$3, *$4)); - GlobalBeevMgr->BVTypeCheck(*n); + ASTNode * n = new ASTNode(ParserBM->CreateNode(BVGE, *$3, *$4)); + BVTypeCheck(*n); $$ = n; delete $3; delete $4; @@ -582,41 +583,41 @@ an_formula: } | LPAREN_TOK NOT_TOK an_formula RPAREN_TOK { - $$ = new ASTNode(GlobalBeevMgr->CreateNode(NOT, *$3)); + $$ = new ASTNode(ParserBM->CreateNode(NOT, *$3)); delete $3; } | LPAREN_TOK IMPLIES_TOK an_formula an_formula RPAREN_TOK { - $$ = new ASTNode(GlobalBeevMgr->CreateNode(IMPLIES, *$3, *$4)); + $$ = new ASTNode(ParserBM->CreateNode(IMPLIES, *$3, *$4)); delete $3; delete $4; } | LPAREN_TOK ITE_TOK an_formula an_formula an_formula RPAREN_TOK { - $$ = new ASTNode(GlobalBeevMgr->CreateSimplifiedFormulaITE(*$3, *$4, *$5)); + $$ = new ASTNode((GlobalSTP->simp)->CreateSimplifiedFormulaITE(*$3, *$4, *$5)); delete $3; delete $4; delete $5; } | LPAREN_TOK AND_TOK an_formulas RPAREN_TOK { - $$ = new ASTNode(GlobalBeevMgr->CreateNode(AND, *$3)); + $$ = new ASTNode(ParserBM->CreateNode(AND, *$3)); delete $3; } | LPAREN_TOK OR_TOK an_formulas RPAREN_TOK { - $$ = new ASTNode(GlobalBeevMgr->CreateNode(OR, *$3)); + $$ = new ASTNode(ParserBM->CreateNode(OR, *$3)); delete $3; } | LPAREN_TOK XOR_TOK an_formula an_formula RPAREN_TOK { - $$ = new ASTNode(GlobalBeevMgr->CreateNode(XOR, *$3, *$4)); + $$ = new ASTNode(ParserBM->CreateNode(XOR, *$3, *$4)); delete $3; delete $4; } | LPAREN_TOK IFF_TOK an_formula an_formula RPAREN_TOK { - $$ = new ASTNode(GlobalBeevMgr->CreateNode(IFF, *$3, *$4)); + $$ = new ASTNode(ParserBM->CreateNode(IFF, *$3, *$4)); delete $3; delete $4; } @@ -625,7 +626,7 @@ an_formula: { $$ = $2; //Cleanup the LetIDToExprMap - GlobalBeevMgr->GetLetMgr()->CleanupLetIDMap(); + ParserBM->GetLetMgr()->CleanupLetIDMap(); } ; @@ -633,7 +634,7 @@ letexpr_mgmt: LPAREN_TOK LET_TOK LPAREN_TOK QUESTION_TOK FORMID_TOK an_term RPAREN_TOK { //Expr must typecheck - GlobalBeevMgr->BVTypeCheck(*$6); + BVTypeCheck(*$6); //set the valuewidth of the identifier $5->SetValueWidth($6->GetValueWidth()); @@ -647,21 +648,21 @@ letexpr_mgmt: // //2. Ensure that LET variables are not //2. defined more than once - GlobalBeevMgr->GetLetMgr()->LetExprMgr(*$5,*$6); + ParserBM->GetLetMgr()->LetExprMgr(*$5,*$6); delete $5; delete $6; } | LPAREN_TOK FLET_TOK LPAREN_TOK DOLLAR_TOK FORMID_TOK an_formula RPAREN_TOK { //Expr must typecheck - GlobalBeevMgr->BVTypeCheck(*$6); + BVTypeCheck(*$6); //set the valuewidth of the identifier $5->SetValueWidth($6->GetValueWidth()); $5->SetIndexWidth($6->GetIndexWidth()); //Do LET-expr management - GlobalBeevMgr->GetLetMgr()->LetExprMgr(*$5,*$6); + ParserBM->GetLetMgr()->LetExprMgr(*$5,*$6); delete $5; delete $6; } @@ -689,11 +690,11 @@ an_terms: an_term: BVCONST_TOK { - $$ = new ASTNode(GlobalBeevMgr->CreateBVConst($1, 10, 32)); + $$ = new ASTNode(ParserBM->CreateBVConst($1, 10, 32)); } | BVCONST_TOK LBRACKET_TOK NUMERAL_TOK RBRACKET_TOK { - $$ = new ASTNode(GlobalBeevMgr->CreateBVConst($1,10,$3)); + $$ = new ASTNode(ParserBM->CreateBVConst($1,10,$3)); delete $1; } | an_nonbvconst_term @@ -703,14 +704,14 @@ an_nonbvconst_term: BITCONST_TOK { $$ = $1; } | var { - $$ = new ASTNode(GlobalBeevMgr->GetLetMgr()->ResolveID(*$1)); + $$ = new ASTNode(ParserBM->GetLetMgr()->ResolveID(*$1)); delete $1; } | LPAREN_TOK an_term RPAREN_TOK //| LPAREN_TOK an_term annotations RPAREN_TOK { $$ = $2; - //$$ = new ASTNode(GlobalBeevMgr->SimplifyTerm(*$2)); + //$$ = new ASTNode(ParserBM->SimplifyTerm(*$2)); //delete $2; } | SELECT_TOK an_term an_term @@ -721,8 +722,8 @@ an_nonbvconst_term: ASTNode index = *$3; unsigned int width = array.GetValueWidth(); ASTNode * n = - new ASTNode(GlobalBeevMgr->CreateTerm(READ, width, array, index)); - GlobalBeevMgr->BVTypeCheck(*n); + new ASTNode(ParserBM->CreateTerm(READ, width, array, index)); + BVTypeCheck(*n); $$ = n; delete $2; delete $3; @@ -734,9 +735,9 @@ an_nonbvconst_term: ASTNode array = *$2; ASTNode index = *$3; ASTNode writeval = *$4; - ASTNode write_term = GlobalBeevMgr->CreateTerm(WRITE,width,array,index,writeval); + ASTNode write_term = ParserBM->CreateTerm(WRITE,width,array,index,writeval); write_term.SetIndexWidth($2->GetIndexWidth()); - GlobalBeevMgr->BVTypeCheck(write_term); + BVTypeCheck(write_term); ASTNode * n = new ASTNode(write_term); $$ = n; delete $2; @@ -752,11 +753,11 @@ an_nonbvconst_term: if((unsigned)$3 >= $7->GetValueWidth()) yyerror("Parsing: Wrong width in BVEXTRACT\n"); - ASTNode hi = GlobalBeevMgr->CreateBVConst(32, $3); - ASTNode low = GlobalBeevMgr->CreateBVConst(32, $5); - ASTNode output = GlobalBeevMgr->CreateTerm(BVEXTRACT, width, *$7,hi,low); + ASTNode hi = ParserBM->CreateBVConst(32, $3); + ASTNode low = ParserBM->CreateBVConst(32, $5); + ASTNode output = ParserBM->CreateTerm(BVEXTRACT, width, *$7,hi,low); ASTNode * n = new ASTNode(output); - GlobalBeevMgr->BVTypeCheck(*n); + BVTypeCheck(*n); $$ = n; delete $7; } @@ -771,13 +772,13 @@ an_nonbvconst_term: if($3->GetIndexWidth() != $4->GetIndexWidth()) yyerror("Width mismatch in IF-THEN-ELSE"); - GlobalBeevMgr->BVTypeCheck(*$2); - GlobalBeevMgr->BVTypeCheck(*$3); - GlobalBeevMgr->BVTypeCheck(*$4); - $$ = new ASTNode(GlobalBeevMgr->CreateSimplifiedTermITE(*$2, *$3, *$4)); - //$$ = new ASTNode(GlobalBeevMgr->CreateTerm(ITE,width,*$2, *$3, *$4)); + BVTypeCheck(*$2); + BVTypeCheck(*$3); + BVTypeCheck(*$4); + $$ = new ASTNode((GlobalSTP->simp)->CreateSimplifiedTermITE(*$2, *$3, *$4)); + //$$ = new ASTNode(ParserBM->CreateTerm(ITE,width,*$2, *$3, *$4)); $$->SetIndexWidth($4->GetIndexWidth()); - GlobalBeevMgr->BVTypeCheck(*$$); + BVTypeCheck(*$$); delete $2; delete $3; delete $4; @@ -785,8 +786,8 @@ an_nonbvconst_term: | BVCONCAT_TOK an_term an_term { unsigned int width = $2->GetValueWidth() + $3->GetValueWidth(); - ASTNode * n = new ASTNode(GlobalBeevMgr->CreateTerm(BVCONCAT, width, *$2, *$3)); - GlobalBeevMgr->BVTypeCheck(*n); + ASTNode * n = new ASTNode(ParserBM->CreateTerm(BVCONCAT, width, *$2, *$3)); + BVTypeCheck(*n); $$ = n; delete $2; @@ -796,8 +797,8 @@ an_nonbvconst_term: { //this is the BVNEG (term) in the CVCL language unsigned int width = $2->GetValueWidth(); - ASTNode * n = new ASTNode(GlobalBeevMgr->CreateTerm(BVNEG, width, *$2)); - GlobalBeevMgr->BVTypeCheck(*n); + ASTNode * n = new ASTNode(ParserBM->CreateTerm(BVNEG, width, *$2)); + BVTypeCheck(*n); $$ = n; delete $2; } @@ -805,8 +806,8 @@ an_nonbvconst_term: { //this is the BVUMINUS term in CVCL langauge unsigned width = $2->GetValueWidth(); - ASTNode * n = new ASTNode(GlobalBeevMgr->CreateTerm(BVUMINUS,width,*$2)); - GlobalBeevMgr->BVTypeCheck(*n); + ASTNode * n = new ASTNode(ParserBM->CreateTerm(BVUMINUS,width,*$2)); + BVTypeCheck(*n); $$ = n; delete $2; } @@ -816,8 +817,8 @@ an_nonbvconst_term: if (width != $3->GetValueWidth()) { yyerror("Width mismatch in AND"); } - ASTNode * n = new ASTNode(GlobalBeevMgr->CreateTerm(BVAND, width, *$2, *$3)); - GlobalBeevMgr->BVTypeCheck(*n); + ASTNode * n = new ASTNode(ParserBM->CreateTerm(BVAND, width, *$2, *$3)); + BVTypeCheck(*n); $$ = n; delete $2; delete $3; @@ -828,8 +829,8 @@ an_nonbvconst_term: if (width != $3->GetValueWidth()) { yyerror("Width mismatch in OR"); } - ASTNode * n = new ASTNode(GlobalBeevMgr->CreateTerm(BVOR, width, *$2, *$3)); - GlobalBeevMgr->BVTypeCheck(*n); + ASTNode * n = new ASTNode(ParserBM->CreateTerm(BVOR, width, *$2, *$3)); + BVTypeCheck(*n); $$ = n; delete $2; delete $3; @@ -840,8 +841,8 @@ an_nonbvconst_term: if (width != $3->GetValueWidth()) { yyerror("Width mismatch in XOR"); } - ASTNode * n = new ASTNode(GlobalBeevMgr->CreateTerm(BVXOR, width, *$2, *$3)); - GlobalBeevMgr->BVTypeCheck(*n); + ASTNode * n = new ASTNode(ParserBM->CreateTerm(BVXOR, width, *$2, *$3)); + BVTypeCheck(*n); $$ = n; delete $2; delete $3; @@ -852,8 +853,8 @@ an_nonbvconst_term: if (width != $3->GetValueWidth()) { yyerror("Width mismatch in BVSUB"); } - ASTNode * n = new ASTNode(GlobalBeevMgr->CreateTerm(BVSUB, width, *$2, *$3)); - GlobalBeevMgr->BVTypeCheck(*n); + ASTNode * n = new ASTNode(ParserBM->CreateTerm(BVSUB, width, *$2, *$3)); + BVTypeCheck(*n); $$ = n; delete $2; delete $3; @@ -864,8 +865,8 @@ an_nonbvconst_term: if (width != $3->GetValueWidth()) { yyerror("Width mismatch in BVPLUS"); } - ASTNode * n = new ASTNode(GlobalBeevMgr->CreateTerm(BVPLUS, width, *$2, *$3)); - GlobalBeevMgr->BVTypeCheck(*n); + ASTNode * n = new ASTNode(ParserBM->CreateTerm(BVPLUS, width, *$2, *$3)); + BVTypeCheck(*n); $$ = n; delete $2; delete $3; @@ -877,8 +878,8 @@ an_nonbvconst_term: if (width != $3->GetValueWidth()) { yyerror("Width mismatch in BVMULT"); } - ASTNode * n = new ASTNode(GlobalBeevMgr->CreateTerm(BVMULT, width, *$2, *$3)); - GlobalBeevMgr->BVTypeCheck(*n); + ASTNode * n = new ASTNode(ParserBM->CreateTerm(BVMULT, width, *$2, *$3)); + BVTypeCheck(*n); $$ = n; delete $2; delete $3; @@ -890,8 +891,8 @@ an_nonbvconst_term: if (width != $3->GetValueWidth()) { yyerror("Width mismatch in BVDIV"); } - ASTNode * n = new ASTNode(GlobalBeevMgr->CreateTerm(BVDIV, width, *$2, *$3)); - GlobalBeevMgr->BVTypeCheck(*n); + ASTNode * n = new ASTNode(ParserBM->CreateTerm(BVDIV, width, *$2, *$3)); + BVTypeCheck(*n); $$ = n; delete $2; @@ -903,8 +904,8 @@ an_nonbvconst_term: if (width != $3->GetValueWidth()) { yyerror("Width mismatch in BVMOD"); } - ASTNode * n = new ASTNode(GlobalBeevMgr->CreateTerm(BVMOD, width, *$2, *$3)); - GlobalBeevMgr->BVTypeCheck(*n); + ASTNode * n = new ASTNode(ParserBM->CreateTerm(BVMOD, width, *$2, *$3)); + BVTypeCheck(*n); $$ = n; delete $2; @@ -916,8 +917,8 @@ an_nonbvconst_term: if (width != $3->GetValueWidth()) { yyerror("Width mismatch in SBVDIV"); } - ASTNode * n = new ASTNode(GlobalBeevMgr->CreateTerm(SBVDIV, width, *$2, *$3)); - GlobalBeevMgr->BVTypeCheck(*n); + ASTNode * n = new ASTNode(ParserBM->CreateTerm(SBVDIV, width, *$2, *$3)); + BVTypeCheck(*n); $$ = n; delete $2; @@ -929,8 +930,8 @@ an_nonbvconst_term: if (width != $3->GetValueWidth()) { yyerror("Width mismatch in SBVREM"); } - ASTNode * n = new ASTNode(GlobalBeevMgr->CreateTerm(SBVREM, width, *$2, *$3)); - GlobalBeevMgr->BVTypeCheck(*n); + ASTNode * n = new ASTNode(ParserBM->CreateTerm(SBVREM, width, *$2, *$3)); + BVTypeCheck(*n); $$ = n; delete $2; delete $3; @@ -941,8 +942,8 @@ an_nonbvconst_term: if (width != $3->GetValueWidth()) { yyerror("Width mismatch in SBVMOD"); } - ASTNode * n = new ASTNode(GlobalBeevMgr->CreateTerm(SBVMOD, width, *$2, *$3)); - GlobalBeevMgr->BVTypeCheck(*n); + ASTNode * n = new ASTNode(ParserBM->CreateTerm(SBVMOD, width, *$2, *$3)); + BVTypeCheck(*n); $$ = n; delete $2; delete $3; @@ -958,8 +959,8 @@ an_nonbvconst_term: if (width != $3->GetValueWidth()) { yyerror("Width mismatch in BVNAND"); } - ASTNode * n = new ASTNode(GlobalBeevMgr->CreateTerm(BVNAND, width, *$2, *$3)); - GlobalBeevMgr->BVTypeCheck(*n); + ASTNode * n = new ASTNode(ParserBM->CreateTerm(BVNAND, width, *$2, *$3)); + BVTypeCheck(*n); $$ = n; delete $2; delete $3; @@ -970,8 +971,8 @@ an_nonbvconst_term: if (width != $3->GetValueWidth()) { yyerror("Width mismatch in BVNOR"); } - ASTNode * n = new ASTNode(GlobalBeevMgr->CreateTerm(BVNOR, width, *$2, *$3)); - GlobalBeevMgr->BVTypeCheck(*n); + ASTNode * n = new ASTNode(ParserBM->CreateTerm(BVNOR, width, *$2, *$3)); + BVTypeCheck(*n); $$ = n; delete $2; delete $3; @@ -980,8 +981,8 @@ an_nonbvconst_term: { // shifting left by who know how much? unsigned int w = $2->GetValueWidth(); - ASTNode * n = new ASTNode(GlobalBeevMgr->CreateTerm(BVLEFTSHIFT,w,*$2,*$3)); - GlobalBeevMgr->BVTypeCheck(*n); + ASTNode * n = new ASTNode(ParserBM->CreateTerm(BVLEFTSHIFT,w,*$2,*$3)); + BVTypeCheck(*n); $$ = n; delete $2; } @@ -989,8 +990,8 @@ an_nonbvconst_term: { // shifting right by who know how much? unsigned int w = $2->GetValueWidth(); - ASTNode * n = new ASTNode(GlobalBeevMgr->CreateTerm(BVRIGHTSHIFT,w,*$2,*$3)); - GlobalBeevMgr->BVTypeCheck(*n); + ASTNode * n = new ASTNode(ParserBM->CreateTerm(BVRIGHTSHIFT,w,*$2,*$3)); + BVTypeCheck(*n); $$ = n; delete $2; } @@ -998,14 +999,14 @@ an_nonbvconst_term: { // shifting arithmetic right by who know how much? unsigned int w = $2->GetValueWidth(); - ASTNode * n = new ASTNode(GlobalBeevMgr->CreateTerm(BVSRSHIFT,w,*$2,*$3)); - GlobalBeevMgr->BVTypeCheck(*n); + ASTNode * n = new ASTNode(ParserBM->CreateTerm(BVSRSHIFT,w,*$2,*$3)); + BVTypeCheck(*n); $$ = n; delete $2; } | BVROTATE_LEFT_TOK LBRACKET_TOK NUMERAL_TOK RBRACKET_TOK an_term { - GlobalBeevMgr->BVTypeCheck(*$5); + BVTypeCheck(*$5); ASTNode *n; unsigned width = $5->GetValueWidth(); @@ -1016,14 +1017,14 @@ an_nonbvconst_term: } else if (rotate < width) { - ASTNode high = GlobalBeevMgr->CreateBVConst(32,width-1); - ASTNode zero = GlobalBeevMgr->CreateBVConst(32,0); - ASTNode cut = GlobalBeevMgr->CreateBVConst(32,width-rotate); - ASTNode cutMinusOne = GlobalBeevMgr->CreateBVConst(32,width-rotate-1); + ASTNode high = ParserBM->CreateBVConst(32,width-1); + ASTNode zero = ParserBM->CreateBVConst(32,0); + ASTNode cut = ParserBM->CreateBVConst(32,width-rotate); + ASTNode cutMinusOne = ParserBM->CreateBVConst(32,width-rotate-1); - ASTNode top = GlobalBeevMgr->CreateTerm(BVEXTRACT,rotate,*$5,high, cut); - ASTNode bottom = GlobalBeevMgr->CreateTerm(BVEXTRACT,width-rotate,*$5,cutMinusOne,zero); - n = new ASTNode(GlobalBeevMgr->CreateTerm(BVCONCAT,width,bottom,top)); + ASTNode top = ParserBM->CreateTerm(BVEXTRACT,rotate,*$5,high, cut); + ASTNode bottom = ParserBM->CreateTerm(BVEXTRACT,width-rotate,*$5,cutMinusOne,zero); + n = new ASTNode(ParserBM->CreateTerm(BVCONCAT,width,bottom,top)); delete $5; } else @@ -1032,13 +1033,13 @@ an_nonbvconst_term: yyerror("Rotate must be strictly less than the width."); } - GlobalBeevMgr->BVTypeCheck(*n); + BVTypeCheck(*n); $$ = n; } | BVROTATE_RIGHT_TOK LBRACKET_TOK NUMERAL_TOK RBRACKET_TOK an_term { - GlobalBeevMgr->BVTypeCheck(*$5); + BVTypeCheck(*$5); ASTNode *n; unsigned width = $5->GetValueWidth(); @@ -1049,14 +1050,14 @@ an_nonbvconst_term: } else if (rotate < width) { - ASTNode high = GlobalBeevMgr->CreateBVConst(32,width-1); - ASTNode zero = GlobalBeevMgr->CreateBVConst(32,0); - ASTNode cut = GlobalBeevMgr->CreateBVConst(32,rotate); - ASTNode cutMinusOne = GlobalBeevMgr->CreateBVConst(32,rotate-1); + ASTNode high = ParserBM->CreateBVConst(32,width-1); + ASTNode zero = ParserBM->CreateBVConst(32,0); + ASTNode cut = ParserBM->CreateBVConst(32,rotate); + ASTNode cutMinusOne = ParserBM->CreateBVConst(32,rotate-1); - ASTNode bottom = GlobalBeevMgr->CreateTerm(BVEXTRACT,rotate,*$5,cutMinusOne, zero); - ASTNode top = GlobalBeevMgr->CreateTerm(BVEXTRACT,width-rotate,*$5,high,cut); - n = new ASTNode(GlobalBeevMgr->CreateTerm(BVCONCAT,width,bottom,top)); + ASTNode bottom = ParserBM->CreateTerm(BVEXTRACT,rotate,*$5,cutMinusOne, zero); + ASTNode top = ParserBM->CreateTerm(BVEXTRACT,width-rotate,*$5,high,cut); + n = new ASTNode(ParserBM->CreateTerm(BVCONCAT,width,bottom,top)); delete $5; } else @@ -1065,29 +1066,29 @@ an_nonbvconst_term: yyerror("Rotate must be strictly less than the width."); } - GlobalBeevMgr->BVTypeCheck(*n); + BVTypeCheck(*n); $$ = n; } | BVSX_TOK LBRACKET_TOK NUMERAL_TOK RBRACKET_TOK an_term { - GlobalBeevMgr->BVTypeCheck(*$5); + BVTypeCheck(*$5); unsigned w = $5->GetValueWidth() + $3; - ASTNode width = GlobalBeevMgr->CreateBVConst(32,w); - ASTNode *n = new ASTNode(GlobalBeevMgr->CreateTerm(BVSX,w,*$5,width)); - GlobalBeevMgr->BVTypeCheck(*n); + ASTNode width = ParserBM->CreateBVConst(32,w); + ASTNode *n = new ASTNode(ParserBM->CreateTerm(BVSX,w,*$5,width)); + BVTypeCheck(*n); $$ = n; delete $5; } | BVZX_TOK LBRACKET_TOK NUMERAL_TOK RBRACKET_TOK an_term { - GlobalBeevMgr->BVTypeCheck(*$5); + BVTypeCheck(*$5); if (0 != $3) { unsigned w = $5->GetValueWidth() + $3; - ASTNode leading_zeroes = GlobalBeevMgr->CreateZeroConst($3); - ASTNode *n = new ASTNode(GlobalBeevMgr->CreateTerm(BVCONCAT,w,leading_zeroes,*$5)); - GlobalBeevMgr->BVTypeCheck(*n); + ASTNode leading_zeroes = ParserBM->CreateZeroConst($3); + ASTNode *n = new ASTNode(ParserBM->CreateTerm(BVCONCAT,w,leading_zeroes,*$5)); + BVTypeCheck(*n); $$ = n; delete $5; } @@ -1136,12 +1137,12 @@ sort_symb: var: FORMID_TOK { - $$ = new ASTNode(GlobalBeevMgr->GetLetMgr()->ResolveID(*$1)); + $$ = new ASTNode(ParserBM->GetLetMgr()->ResolveID(*$1)); delete $1; } | TERMID_TOK { - $$ = new ASTNode(GlobalBeevMgr->GetLetMgr()->ResolveID(*$1)); + $$ = new ASTNode(ParserBM->GetLetMgr()->ResolveID(*$1)); delete $1; } | QUESTION_TOK TERMID_TOK @@ -1157,7 +1158,7 @@ fvar: } | FORMID_TOK { - $$ = new ASTNode(GlobalBeevMgr->GetLetMgr()->ResolveID(*$1)); + $$ = new ASTNode(ParserBM->GetLetMgr()->ResolveID(*$1)); delete $1; } ; diff --git a/src/printer/AssortedPrinters.cpp b/src/printer/AssortedPrinters.cpp index 3a0a87b..2f960b5 100644 --- a/src/printer/AssortedPrinters.cpp +++ b/src/printer/AssortedPrinters.cpp @@ -70,301 +70,33 @@ namespace BEEV cout << endl; } - // GLOBAL FUNCTION: Prints statistics from the MINISAT Solver - void BeevMgr::PrintStats(MINISAT::Solver& s) - { - if (!stats_flag) - return; - double cpu_time = MINISAT::cpuTime(); - uint64_t mem_used = MINISAT::memUsed(); - reportf("restarts : %"PRIu64"\n", s.starts); - reportf("conflicts : %"PRIu64" (%.0f /sec)\n", s.conflicts , s.conflicts /cpu_time); - reportf("decisions : %"PRIu64" (%.0f /sec)\n", s.decisions , s.decisions /cpu_time); - reportf("propagations : %"PRIu64" (%.0f /sec)\n", s.propagations, s.propagations/cpu_time); - reportf("conflict literals : %"PRIu64" (%4.2f %% deleted)\n", s.tot_literals, - (s.max_literals - s.tot_literals)*100 / (double)s.max_literals); - if (mem_used != 0) - reportf("Memory used : %.2f MB\n", mem_used / 1048576.0); - reportf("CPU time : %g s\n", cpu_time); - } //end of PrintStats() - - // Prints Satisfying assignment directly, for debugging. - void BeevMgr::PrintSATModel(MINISAT::Solver& newS) - { - if (!newS.okay()) - FatalError("PrintSATModel: NO COUNTEREXAMPLE TO PRINT", ASTUndefined); - // FIXME: Don't put tests like this in the print functions. The print functions - // should print unconditionally. Put a conditional around the call if you don't - // want them to print - if (!(stats_flag && print_nodes_flag)) - return; - - int num_vars = newS.nVars(); - cout << "Satisfying assignment: " << endl; - for (int i = 0; i < num_vars; i++) - { - if (newS.model[i] == MINISAT::l_True) - { - ASTNode s = _SATVar_to_AST[i]; - cout << s << endl; - } - else if (newS.model[i] == MINISAT::l_False) - { - ASTNode s = _SATVar_to_AST[i]; - cout << CreateNode(NOT, s) << endl; - } - } - } //end of PrintSATModel() - - - /* FUNCTION: prints a counterexample for INVALID inputs. iterate - * through the CounterExampleMap data structure and print it to - * stdout - */ - void BeevMgr::PrintCounterExample(bool t, std::ostream& os) - { - //global command-line option - // FIXME: This should always print the counterexample. If you want - // to turn it off, check the switch at the point of call. - if (!print_counterexample_flag) - { - return; - } - - //input is valid, no counterexample to print - if (ValidFlag) - { - return; - } - - //if this option is true then print the way dawson wants using a - //different printer. do not use this printer. - if (print_arrayval_declaredorder_flag) - { - return; - } - - //t is true if SAT solver generated a counterexample, else it is - //false - if (!t) - { - cerr << "PrintCounterExample: No CounterExample to print: " << endl; - return; - } - - //os << "\nCOUNTEREXAMPLE: \n" << endl; - ASTNodeMap::iterator it = CounterExampleMap.begin(); - ASTNodeMap::iterator itend = CounterExampleMap.end(); - for (; it != itend; it++) - { - ASTNode f = it->first; - ASTNode se = it->second; - - if (ARRAY_TYPE == se.GetType()) - { - FatalError("TermToConstTermUsingModel: entry in counterexample is an arraytype. bogus:", se); - } - - //skip over introduced variables - if (f.GetKind() == SYMBOL && - (_introduced_symbols.find(f) != _introduced_symbols.end())) - { - continue; - } - if (f.GetKind() == SYMBOL || - (f.GetKind() == READ && - f[0].GetKind() == SYMBOL && - f[1].GetKind() == BVCONST)) - { - os << "ASSERT( "; - f.PL_Print(os,0); - if(BOOLEAN_TYPE == f.GetType()) - { - os << "<=>"; - } - else - { - os << " = "; - } - if (BITVECTOR_TYPE == se.GetType()) - { - TermToConstTermUsingModel(se, false).PL_Print(os, 0); - } - else - { - se.PL_Print(os, 0); - } - os << " );" << endl; - } - } - //os << "\nEND OF COUNTEREXAMPLE" << endl; - } //End of PrintCounterExample - - - /* iterate through the CounterExampleMap data structure and print it - * to stdout. this function prints only the declared array variables - * IN the ORDER in which they were declared. It also assumes that - * the variables are of the form 'varname_number'. otherwise it will - * not print anything. This function was specifically written for - * Dawson Engler's group (bug finding research group at Stanford) - */ - void BeevMgr::PrintCounterExample_InOrder(bool t) - { - //global command-line option to print counterexample. we do not - //want both counterexample printers to print at the sametime. - // FIXME: This should always print the counterexample. If you want - // to turn it off, check the switch at the point of call. - if (print_counterexample_flag) - return; - - //input is valid, no counterexample to print - if (ValidFlag) - return; - - //print if the commandline option is '-q'. allows printing the - //counterexample in order. - if (!print_arrayval_declaredorder_flag) - return; - - //t is true if SAT solver generated a counterexample, else it is - //false - if (!t) - { - cerr << "PrintCounterExample: No CounterExample to print: " << endl; - return; - } - - //vector to store the integer values - std::vector out_int; - cout << "% "; - for (ASTVec::iterator it = ListOfDeclaredVars.begin(), itend = ListOfDeclaredVars.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 - - - void BeevMgr::printCacheStatus() - { - cerr << SimplifyMap->size() << endl; - cerr << SimplifyNegMap->size() << endl; - cerr << ReferenceCount->size() << endl; - cerr << TermsAlreadySeenMap.size() << endl; - - cerr << SimplifyMap->bucket_count() << endl; - cerr << SimplifyNegMap->bucket_count() << endl; - cerr << ReferenceCount->bucket_count() << endl; - cerr << TermsAlreadySeenMap.bucket_count() << endl; - } //printCacheStatus() - - //This function prints the output of the STP solver - void BeevMgr::PrintOutput(SOLVER_RETURN_TYPE ret) - { - bool true_iff_valid = (SOLVER_VALID == ret); - - if (print_output_flag) - { - if (smtlib_parser_flag) - { - if (true_iff_valid && - (input_status == TO_BE_SATISFIABLE)) - { - cerr << "Warning. Expected satisfiable, FOUND unsatisfiable" << endl; - } - else if (!true_iff_valid && - (input_status == TO_BE_UNSATISFIABLE)) - { - cerr << "Warning. Expected unsatisfiable, FOUND satisfiable" << endl; - } - } - } - - if (true_iff_valid) - { - ValidFlag = true; - if (print_output_flag) - { - if (smtlib_parser_flag) - cout << "unsat\n"; - else - cout << "Valid.\n"; - } - } - else - { - ValidFlag = false; - if (print_output_flag) - { - if (smtlib_parser_flag) - cout << "sat\n"; - else - cout << "Invalid.\n"; - } - } - } //end of PrintOutput() - - -// void BeevMgr::PrintClauseList(ostream& os, BeevMgr::ClauseList& cll) -// { -// int num_clauses = cll.size(); -// os << "Clauses: " << endl << "=========================================" << endl; -// for (int i = 0; i < num_clauses; i++) -// { -// os << "Clause " << i << endl << "-------------------------------------------" << endl; -// LispPrintVecSpecial(os, *cll[i], 0); -// os << endl << "-------------------------------------------" << endl; -// } -// } //end of PrintClauseList() - - //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 = BEEV::GlobalBeevMgr->_SATVar_to_AST[minisat_var]; - cout << spaces(decision_level); - if (polarity) - { - cout << "!"; - } - printer::PL_Print(cout,vv, 0); - cout << endl; - } //end of Convert_MINISATVar_To_ASTNode_Print() + // void BeevMgr::PrintClauseList(ostream& os, BeevMgr::ClauseList& cll) + // { + // int num_clauses = cll.size(); + // os << "Clauses: " << endl << "=========================================" << endl; + // for (int i = 0; i < num_clauses; i++) + // { + // os << "Clause " << i << endl << "-------------------------------------------" << endl; + // LispPrintVecSpecial(os, *cll[i], 0); + // os << endl << "-------------------------------------------" << endl; + // } + // } //end of PrintClauseList() + + // //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 = BEEV::GlobalBeevMgr->_SATVar_to_AST[minisat_var]; + // cout << spaces(decision_level); + // if (polarity) + // { + // cout << "!"; + // } + // printer::PL_Print(cout,vv, 0); + // cout << endl; + // } //end of Convert_MINISATVar_To_ASTNode_Print() void BeevMgr::printVarDeclsToStream(ostream &os) { for(ASTVec::iterator i = ListOfDeclaredVars.begin(),iend=ListOfDeclaredVars.end();i!=iend;i++) { @@ -395,10 +127,11 @@ namespace BEEV void BeevMgr::printAssertsToStream(ostream &os, int simplify_print) { ASTVec v = GetAsserts(); for(ASTVec::iterator i=v.begin(),iend=v.end();i!=iend;i++) { - Begin_RemoveWrites = true; - ASTNode q = (simplify_print == 1) ? SimplifyFormula_TopLevel(*i,false) : *i; - q = (simplify_print == 1) ? SimplifyFormula_TopLevel(q,false) : q; - Begin_RemoveWrites = false; + //Begin_RemoveWrites = true; + //ASTNode q = (simplify_print == 1) ? SimplifyFormula_TopLevel(*i,false) : *i; + //q = (simplify_print == 1) ? SimplifyFormula_TopLevel(q,false) : q; + ASTNode q = *i; + //Begin_RemoveWrites = false; os << "ASSERT( "; q.PL_Print(os); os << ");" << endl; @@ -406,8 +139,8 @@ namespace BEEV } void print_STPInput_Back(const ASTNode& asserts, const ASTNode& query) { - BEEV::GlobalBeevMgr->printVarDeclsToStream(cout); - BEEV::GlobalBeevMgr->printAssertsToStream(cout,0); + (BEEV::GlobalSTP->bm)->printVarDeclsToStream(cout); + (BEEV::GlobalSTP->bm)->printAssertsToStream(cout,0); cout << "QUERY("; query.PL_Print(cout); cout << ");\n"; diff --git a/src/printer/Makefile b/src/printer/Makefile new file mode 100644 index 0000000..ac2be0d --- /dev/null +++ b/src/printer/Makefile @@ -0,0 +1,21 @@ +include ../../scripts/Makefile.common + +SRCS=$(wildcard *.cpp) +OBJS = $(SRCS:.cpp=.o) +CFLAGS += -I../sat/mtl -I../sat/core + +#Make the ast library for use by other modules +libprinter.a:$(OBJS) depend + -rm -rf $@ + $(AR) rc $@ $(OBJS) + $(RANLIB) $@ + +.PHONY: clean +clean: + rm -rf *.o *~ *.a depend + +depend: $(SRCS) + @$(CXX) -MM -MG $(CXXFLAGS) $(SRCS) > $@ + +#-include ./depend + diff --git a/src/printer/PLPrinter.cpp b/src/printer/PLPrinter.cpp index 2c5f18f..50aadc8 100644 --- a/src/printer/PLPrinter.cpp +++ b/src/printer/PLPrinter.cpp @@ -180,12 +180,12 @@ namespace printer os << ")"; break; case FOR: - if(expand_finitefor_flag) - { - ASTNode expandedfor = bm->Expand_FiniteLoop_TopLevel(n); - PL_Print1(os, expandedfor, indentation, letize); - } - else + // if(expand_finitefor_flag) + // { + // ASTNode expandedfor = bm->Expand_FiniteLoop_TopLevel(n); + // PL_Print1(os, expandedfor, indentation, letize); + // } + // else { os << "FOR("; PL_Print1(os, c[0], indentation, letize); diff --git a/src/printer/SMTLIBPrinter.cpp b/src/printer/SMTLIBPrinter.cpp index 1313761..cd544d4 100644 --- a/src/printer/SMTLIBPrinter.cpp +++ b/src/printer/SMTLIBPrinter.cpp @@ -36,7 +36,8 @@ namespace printer } void printVarDeclsToStream( const BeevMgr* mgr, ostream &os) { - for(ASTVec::const_iterator i = mgr->ListOfDeclaredVars.begin(),iend=mgr->ListOfDeclaredVars.end();i!=iend;i++) { + for(ASTVec::const_iterator i = mgr->ListOfDeclaredVars.begin(), + iend=mgr->ListOfDeclaredVars.end();i!=iend;i++) { const BEEV::ASTNode& a = *i; // Should be a symbol. diff --git a/src/printer/printers.h b/src/printer/printers.h index 00667a5..f63448a 100644 --- a/src/printer/printers.h +++ b/src/printer/printers.h @@ -13,21 +13,26 @@ #include "../AST/AST.h" #include "../AST/ASTUtil.h" #include "../AST/ASTKind.h" -#include "../STPManager/STPManager.h" +#include "../STPManager/STP.h" namespace printer { ostream& Dot_Print(ostream &os, const BEEV::ASTNode n); - ostream& SMTLIB_Print(ostream &os, const BEEV::ASTNode n, const int indentation = 0); - ostream& C_Print(ostream &os, const BEEV::ASTNode n, const int indentation = 0); - ostream& PL_Print(ostream &os, const BEEV::ASTNode& n, int indentation=0); - - ostream& Lisp_Print(ostream &os, const BEEV::ASTNode& n, int indentation=0); - ostream& Lisp_Print_indent(ostream &os, const BEEV::ASTNode& n,int indentation=0); - - void SMTLIB_PrintBack(ostream &os, const BEEV::ASTNode& n ); + ostream& SMTLIB_Print(ostream &os, + const BEEV::ASTNode n, const int indentation = 0); + ostream& C_Print(ostream &os, + const BEEV::ASTNode n, const int indentation = 0); + ostream& PL_Print(ostream &os, + const BEEV::ASTNode& n, int indentation=0); + + ostream& Lisp_Print(ostream &os, + const BEEV::ASTNode& n, int indentation=0); + ostream& Lisp_Print_indent(ostream &os, + const BEEV::ASTNode& n,int indentation=0); + void SMTLIB_PrintBack(ostream &os, + const BEEV::ASTNode& n ); } diff --git a/src/sat/core/Solver.h b/src/sat/core/Solver.h index 15252da..2550711 100644 --- a/src/sat/core/Solver.h +++ b/src/sat/core/Solver.h @@ -22,10 +22,10 @@ OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWA #include -#include "Map.h" -#include "Vec.h" -#include "Heap.h" -#include "Alg.h" +#include "../mtl/Map.h" +#include "../mtl/Vec.h" +#include "../mtl/Heap.h" +#include "../mtl/Alg.h" #include "SolverTypes.h" diff --git a/src/sat/core/depend.mk b/src/sat/core/depend.mk new file mode 100644 index 0000000..222feae --- /dev/null +++ b/src/sat/core/depend.mk @@ -0,0 +1,8 @@ +Solver.o: Solver.C Solver.h ../mtl/Map.h ../mtl/Vec.h ../mtl/Vec.h \ + ../mtl/Heap.h ../mtl/Alg.h SolverTypes.h ../mtl/Sort.h +Solver.op: Solver.C Solver.h ../mtl/Map.h ../mtl/Vec.h ../mtl/Vec.h \ + ../mtl/Heap.h ../mtl/Alg.h SolverTypes.h ../mtl/Sort.h +Solver.od: Solver.C Solver.h ../mtl/Map.h ../mtl/Vec.h ../mtl/Vec.h \ + ../mtl/Heap.h ../mtl/Alg.h SolverTypes.h ../mtl/Sort.h +Solver.or: Solver.C Solver.h ../mtl/Map.h ../mtl/Vec.h ../mtl/Vec.h \ + ../mtl/Heap.h ../mtl/Alg.h SolverTypes.h ../mtl/Sort.h diff --git a/src/sat/sat.h b/src/sat/sat.h index c6e9224..d753d3d 100644 --- a/src/sat/sat.h +++ b/src/sat/sat.h @@ -3,8 +3,7 @@ #include "core/Solver.h" #include "core/SolverTypes.h" -#include "../sat/simp/SimpSolver.h" -//#include "../sat/unsound/UnsoundSimpSolver.h" +//#include "simp/SimpSolver.h" +//#include "unsound/UnsoundSimpSolver.h" - -#endif /* SAT_H_ */ +#endif diff --git a/src/sat/simp/SimpSolver.h b/src/sat/simp/SimpSolver.h index ea05f85..98d4a8b 100644 --- a/src/sat/simp/SimpSolver.h +++ b/src/sat/simp/SimpSolver.h @@ -23,8 +23,8 @@ OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWA #include #include -#include "Queue.h" -#include "Solver.h" +#include "../mtl/Queue.h" +#include "../core/Solver.h" namespace MINISAT { diff --git a/src/sat/simp/depend.mk b/src/sat/simp/depend.mk index 1323fd9..4a0512e 100644 --- a/src/sat/simp/depend.mk +++ b/src/sat/simp/depend.mk @@ -1,12 +1,16 @@ SimpSolver.o: SimpSolver.C ../mtl/Sort.h ../mtl/Vec.h SimpSolver.h \ - ../mtl/Queue.h ../core/Solver.h ../mtl/Map.h ../mtl/Vec.h ../mtl/Heap.h \ - ../mtl/Alg.h ../core/SolverTypes.h + ../mtl/Queue.h ../core/Solver.h ../core/../mtl/Map.h \ + ../core/../mtl/Vec.h ../core/../mtl/Vec.h ../core/../mtl/Heap.h \ + ../core/../mtl/Alg.h ../core/SolverTypes.h SimpSolver.op: SimpSolver.C ../mtl/Sort.h ../mtl/Vec.h SimpSolver.h \ - ../mtl/Queue.h ../core/Solver.h ../mtl/Map.h ../mtl/Vec.h ../mtl/Heap.h \ - ../mtl/Alg.h ../core/SolverTypes.h + ../mtl/Queue.h ../core/Solver.h ../core/../mtl/Map.h \ + ../core/../mtl/Vec.h ../core/../mtl/Vec.h ../core/../mtl/Heap.h \ + ../core/../mtl/Alg.h ../core/SolverTypes.h SimpSolver.od: SimpSolver.C ../mtl/Sort.h ../mtl/Vec.h SimpSolver.h \ - ../mtl/Queue.h ../core/Solver.h ../mtl/Map.h ../mtl/Vec.h ../mtl/Heap.h \ - ../mtl/Alg.h ../core/SolverTypes.h + ../mtl/Queue.h ../core/Solver.h ../core/../mtl/Map.h \ + ../core/../mtl/Vec.h ../core/../mtl/Vec.h ../core/../mtl/Heap.h \ + ../core/../mtl/Alg.h ../core/SolverTypes.h SimpSolver.or: SimpSolver.C ../mtl/Sort.h ../mtl/Vec.h SimpSolver.h \ - ../mtl/Queue.h ../core/Solver.h ../mtl/Map.h ../mtl/Vec.h ../mtl/Heap.h \ - ../mtl/Alg.h ../core/SolverTypes.h + ../mtl/Queue.h ../core/Solver.h ../core/../mtl/Map.h \ + ../core/../mtl/Vec.h ../core/../mtl/Vec.h ../core/../mtl/Heap.h \ + ../core/../mtl/Alg.h ../core/SolverTypes.h diff --git a/src/sat/unsound/UnsoundSimpSolver.h b/src/sat/unsound/UnsoundSimpSolver.h index d3e395e..0d58019 100644 --- a/src/sat/unsound/UnsoundSimpSolver.h +++ b/src/sat/unsound/UnsoundSimpSolver.h @@ -26,8 +26,8 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include -#include "Queue.h" -#include "Solver.h" +#include "../mtl/Queue.h" +#include "../core/Solver.h" namespace MINISAT { diff --git a/src/sat/unsound/depend.mk b/src/sat/unsound/depend.mk new file mode 100644 index 0000000..81e0015 --- /dev/null +++ b/src/sat/unsound/depend.mk @@ -0,0 +1,16 @@ +UnsoundSimpSolver.o: UnsoundSimpSolver.C ../mtl/Sort.h ../mtl/Vec.h \ + UnsoundSimpSolver.h ../mtl/Queue.h ../core/Solver.h \ + ../core/../mtl/Map.h ../core/../mtl/Vec.h ../core/../mtl/Vec.h \ + ../core/../mtl/Heap.h ../core/../mtl/Alg.h ../core/SolverTypes.h +UnsoundSimpSolver.op: UnsoundSimpSolver.C ../mtl/Sort.h ../mtl/Vec.h \ + UnsoundSimpSolver.h ../mtl/Queue.h ../core/Solver.h \ + ../core/../mtl/Map.h ../core/../mtl/Vec.h ../core/../mtl/Vec.h \ + ../core/../mtl/Heap.h ../core/../mtl/Alg.h ../core/SolverTypes.h +UnsoundSimpSolver.od: UnsoundSimpSolver.C ../mtl/Sort.h ../mtl/Vec.h \ + UnsoundSimpSolver.h ../mtl/Queue.h ../core/Solver.h \ + ../core/../mtl/Map.h ../core/../mtl/Vec.h ../core/../mtl/Vec.h \ + ../core/../mtl/Heap.h ../core/../mtl/Alg.h ../core/SolverTypes.h +UnsoundSimpSolver.or: UnsoundSimpSolver.C ../mtl/Sort.h ../mtl/Vec.h \ + UnsoundSimpSolver.h ../mtl/Queue.h ../core/Solver.h \ + ../core/../mtl/Map.h ../core/../mtl/Vec.h ../core/../mtl/Vec.h \ + ../core/../mtl/Heap.h ../core/../mtl/Alg.h ../core/SolverTypes.h diff --git a/src/simplifier/bvsolver.cpp b/src/simplifier/bvsolver.cpp index a0c5e2b..ca8e19b 100644 --- a/src/simplifier/bvsolver.cpp +++ b/src/simplifier/bvsolver.cpp @@ -61,7 +61,7 @@ namespace BEEV //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)) + if (BVCONST != in.GetKind() || _simp->BVConstIsOdd(in)) { FatalError("BVSolver:SplitNum_Odd_PowerOf2: input must be a BVCONST and even\n", in); } @@ -70,12 +70,12 @@ namespace BEEV 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)); + ASTNode mod_by_2 = _simp->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)); + div_by_2 = _simp->BVConstEvaluator(_bm->CreateTerm(BVDIV, len, div_by_2, two)); number_shifts++; - mod_by_2 = _bm->BVConstEvaluator(_bm->CreateTerm(BVMOD, len, div_by_2, two)); + mod_by_2 = _simp->BVConstEvaluator(_bm->CreateTerm(BVMOD, len, div_by_2, two)); } return div_by_2; } //end of SplitEven_into_Oddnum_PowerOf2() @@ -95,7 +95,7 @@ namespace BEEV ASTNodeMap::iterator it; if ((it = TermsAlreadySeenMap.find(term)) != TermsAlreadySeenMap.end()) { - //if the term has been seen, then simply return true, else + //if the term has been seen, then _simply return true, else //return false if (ASTTrue == (it->second)) { @@ -137,10 +137,10 @@ namespace BEEV //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) + bool Simplifier::CheckSolverMap(const ASTNode& key, ASTNode& output) { ASTNodeMap::iterator it; - if ((it = SolverMap.find(key)) != SolverMap.end()) + if ((it = SolverMap->find(key)) != SolverMap->end()) { output = it->second; return true; @@ -148,21 +148,21 @@ namespace BEEV return false; } //end of CheckSolverMap() - bool BeevMgr::CheckSolverMap(const ASTNode& key) + bool Simplifier::CheckSolverMap(const ASTNode& key) { - if (SolverMap.find(key) != SolverMap.end()) + 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) + bool Simplifier::UpdateSolverMap(const ASTNode& key, const ASTNode& value) { ASTNode var = (BVEXTRACT == key.GetKind()) ? key[0] : key; if (!CheckSolverMap(var) && key != value) { - SolverMap[key] = value; + (*SolverMap)[key] = value; return true; } return false; @@ -259,13 +259,20 @@ namespace BEEV 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) + if (SYMBOL == monom.GetKind() + && Vars.count(monom) == 1 + && !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) + else if (BVUMINUS == monom.GetKind() + && SYMBOL == monom[0].GetKind() + && Vars.count(monom[0]) == 1 + && !DoNotSolveThis(monom[0]) + && !VarSeenInTerm(monom[0], rhs) + && !chosen_symbol) { //cerr << "Chosen Monom: " << monom << endl; outmonom = monom; @@ -284,11 +291,24 @@ namespace BEEV 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) + ASTNode var = + (BVMULT == monom.GetKind()) ? + monom[1] : + _bm->CreateNode(UNDEFINED); + + if (BVMULT == monom.GetKind() + && BVCONST == monom[0].GetKind() + && _simp->BVConstIsOdd(monom[0]) + && ((SYMBOL == var.GetKind() + && Vars.count(var) == 1) + || (BVEXTRACT == var.GetKind() + && SYMBOL == var[0].GetKind() + && BVCONST == var[1].GetKind() + && zero == var[2] + && !VarSeenInTerm(var[0], rhs) + && !DoNotSolveThis(var[0]))) + && !DoNotSolveThis(var) + && !VarSeenInTerm(var, rhs) && !chosen_odd) { //monom[0] is odd. @@ -302,7 +322,10 @@ namespace BEEV } } - modifiedlhs = (o.size() > 1) ? _bm->CreateTerm(BVPLUS, lhs.GetValueWidth(), o) : o[0]; + modifiedlhs = + (o.size() > 1) ? + _bm->CreateTerm(BVPLUS, lhs.GetValueWidth(), o) : + o[0]; return outmonom; } //end of choosemonom() @@ -343,8 +366,10 @@ namespace BEEV // //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)); + leftover_lhs = + _simp->SimplifyTerm_TopLevel(_bm->CreateTerm(BVUMINUS, len, leftover_lhs)); + ASTNode newrhs = + _simp->SimplifyTerm(_bm->CreateTerm(BVPLUS, len, rhs, leftover_lhs)); lhs = chosen_monom; rhs = newrhs; } //end of if(BVPLUS ...) @@ -353,7 +378,7 @@ namespace BEEV { //equation is of the form (-lhs0) = rhs ASTNode lhs0 = lhs[0]; - rhs = _bm->SimplifyTerm(_bm->CreateTerm(BVUMINUS, rhs.GetValueWidth(), rhs)); + rhs = _simp->SimplifyTerm(_bm->CreateTerm(BVUMINUS, rhs.GetValueWidth(), rhs)); lhs = lhs0; } @@ -364,7 +389,7 @@ namespace BEEV //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)) + if (VarSeenInTerm(lhs, rhs)) { //found the lhs in the rhs. Abort! DoNotSolve_TheseVars.insert(lhs); @@ -378,7 +403,7 @@ namespace BEEV // } DoNotSolve_TheseVars.insert(lhs); - if (!_bm->UpdateSolverMap(lhs, rhs)) + if (!_simp->UpdateSolverMap(lhs, rhs)) { return eq; } @@ -396,7 +421,7 @@ namespace BEEV // else // { // DoNotSolve_TheseVars.insert(lhs); - // if (!_bm->UpdateSolverMap(lhs, rhs)) + // if (!_simp->UpdateSolverMap(lhs, rhs)) // { // return eq; // } @@ -409,20 +434,23 @@ namespace BEEV { 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]))) + if (!(SYMBOL == lhs[0].GetKind() + && BVCONST == lhs[1].GetKind() + && zero == lhs[2] + && !VarSeenInTerm(lhs[0], rhs) + && !DoNotSolveThis(lhs[0]))) { return eq; } - if (_bm->VarSeenInTerm(lhs[0], rhs)) + if (VarSeenInTerm(lhs[0], rhs)) { DoNotSolve_TheseVars.insert(lhs[0]); return eq; } DoNotSolve_TheseVars.insert(lhs[0]); - if (!_bm->UpdateSolverMap(lhs, rhs)) + if (!_simp->UpdateSolverMap(lhs, rhs)) { return eq; } @@ -430,9 +458,11 @@ namespace BEEV //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); + ASTNode newvar = + _bm->NewVar(var.GetValueWidth() - lhs.GetValueWidth()); + newvar = + _bm->CreateTerm(BVCONCAT, var.GetValueWidth(), newvar, rhs); + _simp->UpdateSolverMap(var, newvar); output = ASTTrue; break; } @@ -455,17 +485,18 @@ namespace BEEV //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])) + if (!_simp->BVConstIsOdd(lhs[0])) { return eq; } - ASTNode a = _bm->MultiplicativeInverse(lhs[0]); + ASTNode a = _simp->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)); + ASTNode chosenvar_value = + _simp->SimplifyTerm(_bm->CreateTerm(BVMULT, rhs.GetValueWidth(), a, rhs)); //if chosenvar is seen in chosenvar_value then abort - if (_bm->VarSeenInTerm(chosenvar, chosenvar_value)) + if (VarSeenInTerm(chosenvar, chosenvar_value)) { //abort solving DoNotSolve_TheseVars.insert(lhs); @@ -481,7 +512,7 @@ namespace BEEV //found a variable to solve DoNotSolve_TheseVars.insert(chosenvar); chosenvar = lhs[1]; - if (!_bm->UpdateSolverMap(chosenvar, chosenvar_value)) + if (!_simp->UpdateSolverMap(chosenvar, chosenvar_value)) { return eq; } @@ -489,9 +520,13 @@ namespace BEEV 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); + ASTNode newvar = + _bm->NewVar(var.GetValueWidth() - lhs[1].GetValueWidth()); + newvar = + _bm->CreateTerm(BVCONCAT, + var.GetValueWidth(), + newvar, chosenvar_value); + _simp->UpdateSolverMap(var, newvar); } output = ASTTrue; break; @@ -505,21 +540,6 @@ namespace BEEV 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 @@ -543,7 +563,7 @@ namespace BEEV return output; } - _bm->runTimes.start(RunTimes::BVSolver); + _bm->GetRunTimes()->start(RunTimes::BVSolver); ASTVec o; ASTVec c; if (EQ == k) @@ -555,7 +575,7 @@ namespace BEEV 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 = (ASTTrue == solved && EQ == it->GetKind()) ? _simp->SimplifyFormula(*it, false) : *it; //_bm->ASTNodeStats("Printing after calling simplifyformula inside the solver:", aaa); aaa = BVSolve_Odd(aaa); //_bm->ASTNodeStats("Printing after oddsolver:", aaa); @@ -580,7 +600,7 @@ namespace BEEV { //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 = _simp->SimplifyFormula(evens,false); evens = BVSolve_Even(evens); _bm->ASTNodeStats("Printing after evensolver:", evens); } @@ -592,7 +612,7 @@ namespace BEEV output = _bm->CreateNode(AND, output, evens); UpdateAlreadySolvedMap(input, output); - _bm->runTimes.stop(RunTimes::BVSolver); + _bm->GetRunTimes()->stop(RunTimes::BVSolver); return output; } //end of TopLevelBVSolve() @@ -630,7 +650,7 @@ namespace BEEV continue; } - if (!(BVMULT == itk && BVCONST == aaa[0].GetKind() && SYMBOL == aaa[1].GetKind() && !_bm->BVConstIsOdd(aaa[0]))) + if (!(BVMULT == itk && BVCONST == aaa[0].GetKind() && SYMBOL == aaa[1].GetKind() && !_simp->BVConstIsOdd(aaa[0]))) { //If the monomials of the lhs are NOT of the form 'a*x' where //'a' is even, then return the false @@ -641,7 +661,7 @@ namespace BEEV //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)) + if (_simp->BVConstIsOdd(savetheconst)) { //the constant turned out to be odd. we have UNSAT eqn evenflag = false; @@ -706,8 +726,8 @@ namespace BEEV { 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 (!(BVCONST == itk && !_simp->BVConstIsOdd(aaa)) && !(BVMULT == itk && BVCONST == aaa[0].GetKind() && SYMBOL == aaa[1].GetKind() + && !_simp->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 @@ -757,7 +777,7 @@ namespace BEEV ASTNode two = two_const; while (--count) { - two = _bm->BVConstEvaluator(_bm->CreateTerm(BVMULT, len, two_const, two)); + two = _simp->BVConstEvaluator(_bm->CreateTerm(BVMULT, len, two_const, two)); } ASTVec lhs_c = lhs.GetChildren(); ASTVec lhs_out; @@ -767,24 +787,24 @@ namespace BEEV 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)); + aaa = _simp->BVConstEvaluator(_bm->CreateTerm(BVDIV, len, aaa, two)); + aaa = _simp->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 coeff = _simp->BVConstEvaluator(_bm->CreateTerm(BVDIV, len, aaa[0], two)); + coeff = _simp->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)); + //upper_x = _simp->SimplifyTerm(_bm->CreateTerm(BVEXTRACT, power_of_2, aaa[1], hi, low)); + lower_x = _simp->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)); + formula_out.push_back(_simp->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; @@ -792,5 +812,50 @@ namespace BEEV UpdateAlreadySolvedMap(input, output); return output; } //end of BVSolve_Even() -} -;//end of namespace BEEV + + bool BVSolver::VarSeenInTerm(const ASTNode& var, const ASTNode& term) + { + if (READ == term.GetKind() + && WRITE == term[0].GetKind() + && !_bm->GetRemoveWritesFlag()) + { + return false; + } + + if (READ == term.GetKind() + && WRITE == term[0].GetKind() + && _bm->GetRemoveWritesFlag()) + { + 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 VarSeenInTerm +};//end of namespace BEEV diff --git a/src/simplifier/bvsolver.h b/src/simplifier/bvsolver.h index c4b8db6..d5784dd 100644 --- a/src/simplifier/bvsolver.h +++ b/src/simplifier/bvsolver.h @@ -7,37 +7,49 @@ ********************************************************************/ // -*- c++ -*- -#include "../AST/AST.h" -#include "../AST/ASTUtil.h" +#ifndef BVSOLVER_H +#define BVSOLVER_H + +#include "simplifier.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 + /****************************************************************** + * This class represents the bitvector arithmetic linear solver. + * + * The bitvector solver is a partial solver, i.e. it doesn't 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, & + * have liketerms combined etc. + * + * 0. Traverse top-down over the input DAG, looking for a + * 0. conjunction of equations. if you find one, then for each + * 0. equation in the 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 CAV 2007 + * 2. paper on STP 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 + private: + // 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; + + // Ptr to Simplifier + Simplifier * _simp; + + // ASTNode ASTTrue, ASTFalse, ASTUndefined; //Those formulas which have already been solved. If the same @@ -51,9 +63,6 @@ namespace BEEV 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; @@ -96,7 +105,8 @@ namespace BEEV //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); + 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 @@ -116,10 +126,10 @@ namespace BEEV // //else returns FALSE bool CheckAlreadySolvedMap(const ASTNode& key, ASTNode& output); + public: //constructor - BVSolver(BeevMgr * bm) : - _bm(bm), _symbol_count(0) + BVSolver(BeevMgr * bm, Simplifier * simp) : _bm(bm), _simp(simp) { ASTTrue = _bm->CreateNode(TRUE); ASTFalse = _bm->CreateNode(FALSE); @@ -140,5 +150,5 @@ namespace BEEV //equation to be solved, solves them, ASTNode TopLevelBVSolve(const ASTNode& a); }; //end of class bvsolver -} -;//end of namespace BEEV +};//end of namespace BEEV +#endif diff --git a/src/const-evaluator/consteval.cpp b/src/simplifier/consteval.cpp similarity index 88% rename from src/const-evaluator/consteval.cpp rename to src/simplifier/consteval.cpp index 2c21018..3779060 100644 --- a/src/const-evaluator/consteval.cpp +++ b/src/simplifier/consteval.cpp @@ -8,9 +8,7 @@ ********************************************************************/ #include -#include "../AST/AST.h" -#include "../STPManager/STPManager.h" - +#include "simplifier.h" namespace BEEV { @@ -23,7 +21,7 @@ namespace BEEV FatalError(ss.c_str(), t); } - ASTNode BeevMgr::BVConstEvaluator(const ASTNode& t) + ASTNode Simplifier::BVConstEvaluator(const ASTNode& t) { ASTNode OutputNode; Kind k = t.GetKind(); @@ -68,7 +66,7 @@ namespace BEEV { output = CONSTANTBV::BitVector_Create(inputwidth, true); CONSTANTBV::Set_Complement(output, tmp0); - OutputNode = CreateBVConst(output, outputwidth); + OutputNode = _bm->CreateBVConst(output, outputwidth); break; } case BVSX: @@ -79,7 +77,7 @@ namespace BEEV if (inputwidth == t0_width) { CONSTANTBV::BitVector_Copy(output, tmp0); - OutputNode = CreateBVConst(output, outputwidth); + OutputNode = _bm->CreateBVConst(output, outputwidth); } else { @@ -90,7 +88,7 @@ namespace BEEV CONSTANTBV::BitVector_Fill(output); } CONSTANTBV::BitVector_Interval_Copy(output, tmp0, 0, 0, t0_width); - OutputNode = CreateBVConst(output, outputwidth); + OutputNode = _bm->CreateBVConst(output, outputwidth); } break; } @@ -142,7 +140,7 @@ namespace BEEV } } - OutputNode = CreateBVConst(output, outputwidth); + OutputNode = _bm->CreateBVConst(output, outputwidth); CONSTANTBV::BitVector_Destroy(width); break; @@ -153,21 +151,21 @@ namespace BEEV { output = CONSTANTBV::BitVector_Create(inputwidth, true); CONSTANTBV::Set_Intersection(output, tmp0, tmp1); - OutputNode = CreateBVConst(output, outputwidth); + OutputNode = _bm->CreateBVConst(output, outputwidth); break; } case BVOR: { output = CONSTANTBV::BitVector_Create(inputwidth, true); CONSTANTBV::Set_Union(output, tmp0, tmp1); - OutputNode = CreateBVConst(output, outputwidth); + OutputNode = _bm->CreateBVConst(output, outputwidth); break; } case BVXOR: { output = CONSTANTBV::BitVector_Create(inputwidth, true); CONSTANTBV::Set_ExclusiveOr(output, tmp0, tmp1); - OutputNode = CreateBVConst(output, outputwidth); + OutputNode = _bm->CreateBVConst(output, outputwidth); break; } case BVSUB: @@ -175,14 +173,14 @@ namespace BEEV output = CONSTANTBV::BitVector_Create(inputwidth, true); bool carry = false; CONSTANTBV::BitVector_sub(output, tmp0, tmp1, &carry); - OutputNode = CreateBVConst(output, outputwidth); + OutputNode = _bm->CreateBVConst(output, outputwidth); break; } case BVUMINUS: { output = CONSTANTBV::BitVector_Create(inputwidth, true); CONSTANTBV::BitVector_Negate(output, tmp0); - OutputNode = CreateBVConst(output, outputwidth); + OutputNode = _bm->CreateBVConst(output, outputwidth); break; } case BVEXTRACT: @@ -197,7 +195,7 @@ namespace BEEV output = CONSTANTBV::BitVector_Create(len, false); CONSTANTBV::BitVector_Interval_Copy(output, tmp0, 0, low, len); outputwidth = len; - OutputNode = CreateBVConst(output, outputwidth); + OutputNode = _bm->CreateBVConst(output, outputwidth); break; } @@ -211,7 +209,7 @@ namespace BEEV output = CONSTANTBV::BitVector_Concat(tmp0, tmp1); outputwidth = t0_width + t1_width; - OutputNode = CreateBVConst(output, outputwidth); + OutputNode = _bm->CreateBVConst(output, outputwidth); break; } @@ -228,7 +226,7 @@ namespace BEEV //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); + OutputNode = _bm->CreateBVConst(output, outputwidth); CONSTANTBV::BitVector_Destroy(tmp); break; } @@ -244,7 +242,7 @@ namespace BEEV carry = false; //CONSTANTBV::BitVector_Destroy(kk); } - OutputNode = CreateBVConst(output, outputwidth); + OutputNode = _bm->CreateBVConst(output, outputwidth); break; } @@ -260,7 +258,7 @@ namespace BEEV if (division_by_zero_returns_one && CONSTANTBV::BitVector_is_empty(tmp1)) { // Expecting a division by zero. Just return one. - OutputNode = CreateOneConst(outputwidth); + OutputNode = _bm->CreateOneConst(outputwidth); } else { @@ -274,12 +272,12 @@ namespace BEEV if (SBVDIV == k) { - OutputNode = CreateBVConst(quotient, outputwidth); + OutputNode = _bm->CreateBVConst(quotient, outputwidth); CONSTANTBV::BitVector_Destroy(remainder); } else { - OutputNode = CreateBVConst(remainder, outputwidth); + OutputNode = _bm->CreateBVConst(remainder, outputwidth); CONSTANTBV::BitVector_Destroy(quotient); } @@ -315,7 +313,7 @@ namespace BEEV if (division_by_zero_returns_one && CONSTANTBV::BitVector_is_empty(tmp1)) { // Expecting a division by zero. Just return one. - OutputNode = CreateOneConst(outputwidth); + OutputNode = _bm->CreateOneConst(outputwidth); } else @@ -329,7 +327,7 @@ namespace BEEV cerr << "Error code was:" << e << endl; assert(e == CONSTANTBV::ErrCode_Ok); } - OutputNode = CreateBVConst(remainder, outputwidth); + OutputNode = _bm->CreateBVConst(remainder, outputwidth); } else if (isNegativeS && !isNegativeT) { @@ -348,7 +346,7 @@ namespace BEEV CBV res = CONSTANTBV::BitVector_Create(inputwidth, true); CONSTANTBV::BitVector_add(res, remb, tmp1, &carry); - OutputNode = CreateBVConst(res, outputwidth); + OutputNode = _bm->CreateBVConst(res, outputwidth); CONSTANTBV::BitVector_Destroy(tmp0b); CONSTANTBV::BitVector_Destroy(remb); @@ -368,7 +366,7 @@ namespace BEEV CBV res = CONSTANTBV::BitVector_Create(inputwidth, true); CONSTANTBV::BitVector_add(res, remainder, tmp1, &carry); - OutputNode = CreateBVConst(res, outputwidth); + OutputNode = _bm->CreateBVConst(res, outputwidth); CONSTANTBV::BitVector_Destroy(tmp1b); CONSTANTBV::BitVector_Destroy(remainder); @@ -387,7 +385,7 @@ namespace BEEV CBV remb = CONSTANTBV::BitVector_Create(inputwidth, true); CONSTANTBV::BitVector_Negate(remb, remainder); - OutputNode = CreateBVConst(remb, outputwidth); + OutputNode = _bm->CreateBVConst(remb, outputwidth); CONSTANTBV::BitVector_Destroy(tmp0b); CONSTANTBV::BitVector_Destroy(tmp1b); CONSTANTBV::BitVector_Destroy(remainder); @@ -413,16 +411,17 @@ namespace BEEV if (division_by_zero_returns_one && CONSTANTBV::BitVector_is_empty(tmp1)) { // Expecting a division by zero. Just return one. - OutputNode = CreateOneConst(outputwidth); + OutputNode = _bm->CreateOneConst(outputwidth); } else { - // tmp0 is dividend, tmp1 is the divisor - //All parameters to BitVector_Div_Pos must be distinct unlike BitVector_Divide - //FIXME the contents of the second parameter to Div_Pos is destroyed - //As tmp0 is currently the same as the copy belonging to an ASTNode t[0] - //this must be copied. + // tmp0 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); @@ -430,11 +429,11 @@ namespace BEEV if (0 != e) { //error printing - if (counterexample_checking_during_refinement) + if (_bm->counterexample_checking_during_refinement) { output = CONSTANTBV::BitVector_Create(inputwidth, true); - OutputNode = CreateBVConst(output, outputwidth); - bvdiv_exception_occured = true; + OutputNode = _bm->CreateBVConst(output, outputwidth); + _bm->bvdiv_exception_occured = true; // CONSTANTBV::BitVector_Destroy(output); break; @@ -448,12 +447,12 @@ namespace BEEV //FIXME Not very standard in the current scheme if (BVDIV == k) { - OutputNode = CreateBVConst(quotient, outputwidth); + OutputNode = _bm->CreateBVConst(quotient, outputwidth); CONSTANTBV::BitVector_Destroy(remainder); } else { - OutputNode = CreateBVConst(remainder, outputwidth); + OutputNode = _bm->CreateBVConst(remainder, outputwidth); CONSTANTBV::BitVector_Destroy(quotient); } } diff --git a/src/simplifier/simplifier.cpp b/src/simplifier/simplifier.cpp index 365407f..2f16073 100644 --- a/src/simplifier/simplifier.cpp +++ b/src/simplifier/simplifier.cpp @@ -9,30 +9,28 @@ #include #include -#include "../AST/AST.h" -//#include "../AST/ASTUtil.h" -#include "../STPManager/STPManager.h" +#include "simplifier.h" namespace BEEV { -ASTNode Flatten(const ASTNode& a) -{ + ASTNode Simplifier::Flatten(const ASTNode& a) + { ASTNode n = a; while (true) - { - ASTNode& nold = n; - n = a.GetBeevMgr()->FlattenOneLevel(n); - if ((n == nold)) - break; - } - + { + ASTNode& nold = n; + n = FlattenOneLevel(n); + if ((n == nold)) + break; + } + return n; -} + } - bool BeevMgr::CheckMap(ASTNodeMap* VarConstMap, + bool Simplifier::CheckMap(ASTNodeMap* VarConstMap, const ASTNode& key, ASTNode& output) { if(NULL == VarConstMap) @@ -49,7 +47,7 @@ ASTNode Flatten(const ASTNode& a) } - bool BeevMgr::CheckSimplifyMap(const ASTNode& key, + bool Simplifier::CheckSimplifyMap(const ASTNode& key, ASTNode& output, bool pushNeg, ASTNodeMap* VarConstMap) { @@ -74,7 +72,7 @@ ASTNode Flatten(const ASTNode& a) (ASTFalse == it->second) ? ASTTrue : (ASTTrue == it->second) ? - ASTFalse : CreateNode(NOT, it->second); + ASTFalse : _bm->CreateNode(NOT, it->second); CountersAndStats("2nd_Successful_CheckSimplifyMap"); return true; } @@ -83,7 +81,7 @@ ASTNode Flatten(const ASTNode& a) } // Push any reference count used by the key to the value. - void BeevMgr::UpdateSimplifyMap(const ASTNode& key, + void Simplifier::UpdateSimplifyMap(const ASTNode& key, const ASTNode& value, bool pushNeg, ASTNodeMap* VarConstMap) { @@ -96,6 +94,7 @@ ASTNode Flatten(const ASTNode& a) // to cache. if (0 == key.Degree()) return; + // If there are references to the key, add them to the references of the value. ASTNodeCountMap::const_iterator itKey, itValue; itKey = ReferenceCount->find(key); @@ -115,10 +114,11 @@ ASTNode Flatten(const ASTNode& a) (*SimplifyMap)[key] = value; } - bool BeevMgr::CheckSubstitutionMap(const ASTNode& key, ASTNode& output) + bool Simplifier::CheckSubstitutionMap(const ASTNode& key, ASTNode& output) { - ASTNodeMap::iterator it; - if ((it = SolverMap.find(key)) != SolverMap.end()) + ASTNode k = key; + ASTNodeMap::iterator it = SolverMap->find(key); + if (it != SolverMap->end()) { output = it->second; return true; @@ -126,15 +126,15 @@ ASTNode Flatten(const ASTNode& a) return false; } - bool BeevMgr::CheckSubstitutionMap(const ASTNode& key) + bool Simplifier::CheckSubstitutionMap(const ASTNode& key) { - if (SolverMap.find(key) != SolverMap.end()) + if (SolverMap->find(key) != SolverMap->end()) return true; else return false; } - bool BeevMgr::UpdateSubstitutionMap(const ASTNode& e0, const ASTNode& e1) + bool Simplifier::UpdateSubstitutionMap(const ASTNode& e0, const ASTNode& e1) { int i = TermOrder(e0, e1); if (0 == i) @@ -149,7 +149,7 @@ ASTNode Flatten(const ASTNode& a) assert((e1.GetKind() == TRUE) || (e1.GetKind() == FALSE) || (e1.GetKind() == BVCONST)); - SolverMap[e0] = e1; + (*SolverMap)[e0] = e1; return true; } @@ -160,14 +160,14 @@ ASTNode Flatten(const ASTNode& a) assert((e0.GetKind() == TRUE) || (e0.GetKind() == FALSE) || (e0.GetKind() == BVCONST)); - SolverMap[e1] = e0; + (*SolverMap)[e1] = e0; return true; } return false; } - bool BeevMgr::CheckMultInverseMap(const ASTNode& key, ASTNode& output) + bool Simplifier::CheckMultInverseMap(const ASTNode& key, ASTNode& output) { ASTNodeMap::iterator it; if ((it = MultInverseMap.find(key)) != MultInverseMap.end()) @@ -178,12 +178,12 @@ ASTNode Flatten(const ASTNode& a) return false; } - void BeevMgr::UpdateMultInverseMap(const ASTNode& key, const ASTNode& value) + void Simplifier::UpdateMultInverseMap(const ASTNode& key, const ASTNode& value) { MultInverseMap[key] = value; } - bool BeevMgr::CheckAlwaysTrueFormMap(const ASTNode& key) + bool Simplifier::CheckAlwaysTrueFormMap(const ASTNode& key) { ASTNodeSet::iterator it = AlwaysTrueFormMap.find(key); ASTNodeSet::iterator itend = AlwaysTrueFormMap.end(); @@ -198,91 +198,21 @@ ASTNode Flatten(const ASTNode& a) return false; } - void BeevMgr::UpdateAlwaysTrueFormMap(const ASTNode& key) + void Simplifier::UpdateAlwaysTrueFormMap(const ASTNode& key) { AlwaysTrueFormMap.insert(key); } - //if a is READ(Arr,const) or SYMBOL, and b is BVCONST then return 1 - //if b is READ(Arr,const) or SYMBOL, and a is BVCONST then return -1 - // - //else return 0 by default - int BeevMgr::TermOrder(const ASTNode& a, const ASTNode& b) - { - Kind k1 = a.GetKind(); - Kind k2 = b.GetKind(); - - //a is of the form READ(Arr,const), and b is const, or - //a is of the form var, and b is const - if ((k1 == READ && - a[0].GetKind() == SYMBOL && - a[1].GetKind() == BVCONST && - (k2 == BVCONST))) - // || k2 == READ && b[0].GetKind() == SYMBOL && b[1].GetKind() - // == BVCONST))) - return 1; - - if (SYMBOL == k1 && (BVCONST == k2 || TRUE == k2 || FALSE == k2)) - return 1; - - //b is of the form READ(Arr,const), and a is const, or - //b is of the form var, and a is const - if ((k1 == BVCONST) && - ((k2 == READ && - b[0].GetKind() == SYMBOL && - b[1].GetKind() == BVCONST))) - return -1; - - if (SYMBOL == k2 && (BVCONST == k1 || TRUE == k1 || FALSE == k1)) - return -1; - - return 0; - } - - //This function records all the const-indices seen so far for each - //array. It populates the map '_arrayname_readindices' whose key is - //the arrayname, and vlaue is a vector of read-indices. - // - //fill the arrayname_readindices vector if e0 is a READ(Arr,index) - //and index is a BVCONST. - // - //Since these arrayreads are being nuked and recorded in the - //substitutionmap, we have to also record the fact that each - //arrayread (e0 is of the form READ(Arr,const) here is represented - //by a BVCONST (e1). This is necessary for later Leibnitz Axiom - //generation - void BeevMgr::FillUp_ArrReadIndex_Vec(const ASTNode& e0, const ASTNode& e1) - { - int i = TermOrder(e0, e1); - if (0 == i) - return; - - if (1 == i && e0.GetKind() != SYMBOL && !CheckSubstitutionMap(e0)) - { - _arrayname_readindices[e0[0]].push_back(e0[1]); - //e0 is the array read : READ(A,i) and e1 is a bvconst - _arrayread_symbol[e0] = e1; - return; - } - if (-1 == i && e1.GetKind() != SYMBOL && !CheckSubstitutionMap(e1)) - { - _arrayname_readindices[e1[0]].push_back(e1[1]); - //e0 is the array read : READ(A,i) and e1 is a bvconst - _arrayread_symbol[e1] = e0; - return; - } - } - ASTNode - BeevMgr::SimplifyFormula_NoRemoveWrites(const ASTNode& b, + Simplifier::SimplifyFormula_NoRemoveWrites(const ASTNode& b, bool pushNeg, ASTNodeMap* VarConstMap) { - Begin_RemoveWrites = false; + _bm->Begin_RemoveWrites = false; ASTNode out = SimplifyFormula(b, pushNeg, VarConstMap); return out; } - void BeevMgr::BuildReferenceCountMap(const ASTNode& b) + void Simplifier::BuildReferenceCountMap(const ASTNode& b) { if (b.GetChildren().size() == 0) return; @@ -311,30 +241,30 @@ ASTNode Flatten(const ASTNode& a) // The SimplifyMaps on entry to the topLevel functions may contain useful entries. // E.g. The BVSolver calls SimplifyTerm() - ASTNode BeevMgr::SimplifyFormula_TopLevel(const ASTNode& b, + ASTNode Simplifier::SimplifyFormula_TopLevel(const ASTNode& b, bool pushNeg, ASTNodeMap* VarConstMap) { - runTimes.start(RunTimes::SimplifyTopLevel); + _bm->GetRunTimes()->start(RunTimes::SimplifyTopLevel); if (smtlib_parser_flag) BuildReferenceCountMap(b); ASTNode out = SimplifyFormula(b, pushNeg, VarConstMap); ResetSimplifyMaps(); - runTimes.stop(RunTimes::SimplifyTopLevel); + _bm->GetRunTimes()->stop(RunTimes::SimplifyTopLevel); return out; } -ASTNode BeevMgr::SimplifyTerm_TopLevel(const ASTNode& b) +ASTNode Simplifier::SimplifyTerm_TopLevel(const ASTNode& b) { - runTimes.start(RunTimes::SimplifyTopLevel); + _bm->GetRunTimes()->start(RunTimes::SimplifyTopLevel); ASTNode out = SimplifyTerm(b); ResetSimplifyMaps(); - runTimes.stop(RunTimes::SimplifyTopLevel); + _bm->GetRunTimes()->stop(RunTimes::SimplifyTopLevel); return out; } ASTNode - BeevMgr::SimplifyFormula(const ASTNode& b, + Simplifier::SimplifyFormula(const ASTNode& b, bool pushNeg, ASTNodeMap* VarConstMap) { // if (!optimize_flag) @@ -356,7 +286,7 @@ ASTNode BeevMgr::SimplifyTerm_TopLevel(const ASTNode& b) isAtomic(kind))) { SortByArith(ca); - a = CreateNode(kind, ca); + a = _bm->CreateNode(kind, ca); } ASTNode output; @@ -399,7 +329,7 @@ ASTNode BeevMgr::SimplifyTerm_TopLevel(const ASTNode& b) default: //kind can be EQ,NEQ,BVLT,BVLE,... or a propositional variable output = SimplifyAtomicFormula(a, pushNeg, VarConstMap); - //output = pushNeg ? CreateNode(NOT,a) : a; + //output = pushNeg ? _bm->CreateNode(NOT,a) : a; break; } @@ -409,7 +339,7 @@ ASTNode BeevMgr::SimplifyTerm_TopLevel(const ASTNode& b) } ASTNode - BeevMgr::SimplifyForFormula(const ASTNode& a, + Simplifier::SimplifyForFormula(const ASTNode& a, bool pushNeg, ASTNodeMap* VarConstMap) { //FIXME: Code this up properly later. Mainly pushing the negation @@ -418,7 +348,7 @@ ASTNode BeevMgr::SimplifyTerm_TopLevel(const ASTNode& b) } ASTNode - BeevMgr::SimplifyAtomicFormula(const ASTNode& a, + Simplifier::SimplifyAtomicFormula(const ASTNode& a, bool pushNeg, ASTNodeMap* VarConstMap) { // if (!optimize_flag) @@ -455,31 +385,31 @@ ASTNode BeevMgr::SimplifyTerm_TopLevel(const ASTNode& b) { output = a; } - output = pushNeg ? CreateNode(NOT, output) : output; + output = pushNeg ? _bm->CreateNode(NOT, output) : output; break; case PARAMBOOL: { ASTNode term = SimplifyTerm(a[1], VarConstMap); - output = CreateNode(PARAMBOOL, a[0], term); - output = pushNeg ? CreateNode(NOT, output) : output; + output = _bm->CreateNode(PARAMBOOL, a[0], term); + output = pushNeg ? _bm->CreateNode(NOT, output) : output; break; } case BVGETBIT: { ASTNode term = SimplifyTerm(a[0], VarConstMap); ASTNode thebit = a[1]; - ASTNode zero = CreateZeroConst(1); - ASTNode one = CreateOneConst(1); + ASTNode zero = _bm->CreateZeroConst(1); + ASTNode one = _bm->CreateOneConst(1); ASTNode getthebit = - SimplifyTerm(CreateTerm(BVEXTRACT, 1, term, thebit, thebit), VarConstMap); + SimplifyTerm(_bm->CreateTerm(BVEXTRACT, 1, term, thebit, thebit), VarConstMap); 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; + output = _bm->CreateNode(BVGETBIT, term, thebit); + output = pushNeg ? _bm->CreateNode(NOT, output) : output; } break; } @@ -493,7 +423,7 @@ ASTNode BeevMgr::SimplifyTerm_TopLevel(const ASTNode& b) else if (output == ASTFalse) output = pushNeg ? ASTTrue : ASTFalse; else - output = pushNeg ? CreateNode(NOT, output) : output; + output = pushNeg ? _bm->CreateNode(NOT, output) : output; break; } case BVLT: @@ -505,8 +435,8 @@ ASTNode BeevMgr::SimplifyTerm_TopLevel(const ASTNode& b) case BVSGT: case BVSGE: { - //output = CreateNode(kind,left,right); - //output = pushNeg ? CreateNode(NOT,output) : output; + //output = _bm->CreateNode(kind,left,right); + //output = pushNeg ? _bm->CreateNode(NOT,output) : output; output = CreateSimplifiedINEQ(kind, left, right, pushNeg); break; } @@ -521,22 +451,22 @@ ASTNode BeevMgr::SimplifyTerm_TopLevel(const ASTNode& b) return output; } //end of SimplifyAtomicFormula() - ASTNode BeevMgr::CreateSimplifiedINEQ(Kind k, + ASTNode Simplifier::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 = BVConstEvaluator(_bm->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); + ASTNode zero = _bm->CreateZeroConst(len); + ASTNode one = _bm->CreateOneConst(len); + ASTNode max = _bm->CreateMaxConst(len); switch (k) { case BVLT: @@ -551,14 +481,14 @@ ASTNode BeevMgr::SimplifyTerm_TopLevel(const ASTNode& b) else if (one == right) { output = CreateSimplifiedEQ(left, zero); - output = pushNeg ? CreateNode(NOT, output) : output; + output = pushNeg ? _bm->CreateNode(NOT, output) : output; } else { output = pushNeg ? - CreateNode(BVLE, right, left) : - CreateNode(BVLT, left, right); + _bm->CreateNode(BVLE, right, left) : + _bm->CreateNode(BVLT, left, right); } break; case BVLE: @@ -577,14 +507,14 @@ ASTNode BeevMgr::SimplifyTerm_TopLevel(const ASTNode& b) else if (zero == right) { output = CreateSimplifiedEQ(left, zero); - output = pushNeg ? CreateNode(NOT, output) : output; + output = pushNeg ? _bm->CreateNode(NOT, output) : output; } else { output = pushNeg ? - CreateNode(BVLT, right, left) : - CreateNode(BVLE, left, right); + _bm->CreateNode(BVLT, right, left) : + _bm->CreateNode(BVLE, left, right); } break; case BVGT: @@ -600,8 +530,8 @@ ASTNode BeevMgr::SimplifyTerm_TopLevel(const ASTNode& b) { output = pushNeg ? - CreateNode(BVLE, left, right) : - CreateNode(BVLT, right, left); + _bm->CreateNode(BVLE, left, right) : + _bm->CreateNode(BVLT, right, left); } break; case BVGE: @@ -617,8 +547,8 @@ ASTNode BeevMgr::SimplifyTerm_TopLevel(const ASTNode& b) { output = pushNeg ? - CreateNode(BVLT, left, right) : - CreateNode(BVLE, right, left); + _bm->CreateNode(BVLT, left, right) : + _bm->CreateNode(BVLE, right, left); } break; case BVSLT: @@ -626,8 +556,8 @@ ASTNode BeevMgr::SimplifyTerm_TopLevel(const ASTNode& b) case BVSGE: case BVSGT: { - output = CreateNode(k, left, right); - output = pushNeg ? CreateNode(NOT, output) : output; + output = _bm->CreateNode(k, left, right); + output = pushNeg ? _bm->CreateNode(NOT, output) : output; } break; default: @@ -640,7 +570,7 @@ ASTNode BeevMgr::SimplifyTerm_TopLevel(const ASTNode& b) //Look through the AND Node for terms that contradict. //Should be made significantly more general.. - ASTNode BeevMgr::RemoveContradictionsFromAND(const ASTNode& in) + ASTNode Simplifier::RemoveContradictionsFromAND(const ASTNode& in) { assert(AND == in.GetKind()); const int childrenSize = in.GetChildren().size(); @@ -665,7 +595,7 @@ ASTNode BeevMgr::SimplifyTerm_TopLevel(const ASTNode& b) // turns say (bvslt (ite a b c) (ite a d e)) INTO (ite a (bvslt b d) // (bvslt c e)) Expensive. But makes some other simplifications // possible. - ASTNode BeevMgr::PullUpITE(const ASTNode& in) + ASTNode Simplifier::PullUpITE(const ASTNode& in) { if (2 != in.GetChildren().size()) return in; @@ -686,15 +616,15 @@ ASTNode BeevMgr::SimplifyTerm_TopLevel(const ASTNode& b) if (in.GetType() == BOOLEAN_TYPE) { - l1 = CreateNode(in.GetKind(), in[0][1], in[1][1]); - l2 = CreateNode(in.GetKind(), in[0][2], in[1][2]); - result = CreateNode(ITE, in[0][0], l1, l2); + l1 = _bm->CreateNode(in.GetKind(), in[0][1], in[1][1]); + l2 = _bm->CreateNode(in.GetKind(), in[0][2], in[1][2]); + result = _bm->CreateNode(ITE, in[0][0], l1, l2); } else { - l1 = CreateTerm(in.GetKind(), in.GetValueWidth(), in[0][1], in[1][1]); - l2 = CreateTerm(in.GetKind(), in.GetValueWidth(), in[0][2], in[1][2]); - result = CreateTerm(ITE, in.GetValueWidth(), in[0][0], l1, l2); + l1 = _bm->CreateTerm(in.GetKind(), in.GetValueWidth(), in[0][1], in[1][1]); + l2 = _bm->CreateTerm(in.GetKind(), in.GetValueWidth(), in[0][2], in[1][2]); + result = _bm->CreateTerm(ITE, in.GetValueWidth(), in[0][0], l1, l2); } assert(result.GetType() == in.GetType()); @@ -706,7 +636,7 @@ ASTNode BeevMgr::SimplifyTerm_TopLevel(const ASTNode& b) } //takes care of some simple ITE Optimizations in the context of equations - ASTNode BeevMgr::ITEOpt_InEqs(const ASTNode& in, ASTNodeMap* VarConstMap) + ASTNode Simplifier::ITEOpt_InEqs(const ASTNode& in, ASTNodeMap* VarConstMap) { CountersAndStats("ITEOpts_InEqs"); @@ -763,8 +693,8 @@ ASTNode BeevMgr::SimplifyTerm_TopLevel(const ASTNode& b) } else { - //last resort is to CreateNode - output = CreateNode(EQ, in1, in2); + //last resort is to _bm->CreateNode + output = _bm->CreateNode(EQ, in1, in2); } } else if (ITE == k2 && @@ -785,13 +715,13 @@ ASTNode BeevMgr::SimplifyTerm_TopLevel(const ASTNode& b) else { //last resort is to CreateNode - output = CreateNode(EQ, in1, in2); + output = _bm->CreateNode(EQ, in1, in2); } } else { //last resort is to CreateNode - output = CreateNode(EQ, in1, in2); + output = _bm->CreateNode(EQ, in1, in2); } UpdateSimplifyMap(in, output, false, VarConstMap); @@ -800,7 +730,7 @@ ASTNode BeevMgr::SimplifyTerm_TopLevel(const ASTNode& b) //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) + ASTNode Simplifier::CreateSimplifiedEQ(const ASTNode& in1, const ASTNode& in2) { CountersAndStats("CreateSimplifiedEQ"); Kind k1 = in1.GetKind(); @@ -821,11 +751,11 @@ ASTNode BeevMgr::SimplifyTerm_TopLevel(const ASTNode& b) return ASTFalse; //last resort is to CreateNode - return CreateNode(EQ, in1, in2); + return _bm->CreateNode(EQ, in1, in2); } //accepts cond == t1, then part is t2, and else part is t3 - ASTNode BeevMgr::CreateSimplifiedTermITE(const ASTNode& in0, + ASTNode Simplifier::CreateSimplifiedTermITE(const ASTNode& in0, const ASTNode& in1, const ASTNode& in2) { @@ -847,7 +777,7 @@ ASTNode BeevMgr::SimplifyTerm_TopLevel(const ASTNode& b) FatalError("CreateSimplifiedTermITE: "\ "the lengths of the two branches don't match", t1); } - return CreateTerm(ITE, t1.GetValueWidth(), t0, t1, t2); + return _bm->CreateTerm(ITE, t1.GetValueWidth(), t0, t1, t2); } if (t0 == ASTTrue) @@ -860,15 +790,15 @@ ASTNode BeevMgr::SimplifyTerm_TopLevel(const ASTNode& b) { return t1; } - if (CheckAlwaysTrueFormMap(CreateNode(NOT, t0)) || (NOT == t0.GetKind() && CheckAlwaysTrueFormMap(t0[0]))) + if (CheckAlwaysTrueFormMap(_bm->CreateNode(NOT, t0)) || (NOT == t0.GetKind() && CheckAlwaysTrueFormMap(t0[0]))) { return t2; } - return CreateTerm(ITE, t1.GetValueWidth(), t0, t1, t2); + return _bm->CreateTerm(ITE, t1.GetValueWidth(), t0, t1, t2); } - ASTNode BeevMgr::CreateSimplifiedFormulaITE(const ASTNode& in0, const ASTNode& in1, const ASTNode& in2) + ASTNode Simplifier::CreateSimplifiedFormulaITE(const ASTNode& in0, const ASTNode& in1, const ASTNode& in2) { ASTNode t0 = in0; ASTNode t1 = in1; @@ -887,17 +817,17 @@ ASTNode BeevMgr::SimplifyTerm_TopLevel(const ASTNode& b) { return t1; } - if (CheckAlwaysTrueFormMap(CreateNode(NOT, t0)) || (NOT == t0.GetKind() && CheckAlwaysTrueFormMap(t0[0]))) + if (CheckAlwaysTrueFormMap(_bm->CreateNode(NOT, t0)) || (NOT == t0.GetKind() && CheckAlwaysTrueFormMap(t0[0]))) { return t2; } } - ASTNode result = CreateNode(ITE, t0, t1, t2); + ASTNode result = _bm->CreateNode(ITE, t0, t1, t2); BVTypeCheck(result); return result; } - ASTNode BeevMgr::SimplifyAndOrFormula(const ASTNode& a, bool pushNeg, ASTNodeMap* VarConstMap) + ASTNode Simplifier::SimplifyAndOrFormula(const ASTNode& a, bool pushNeg, ASTNodeMap* VarConstMap) { ASTNode output; //cerr << "input:\n" << a << endl; @@ -986,9 +916,9 @@ ASTNode BeevMgr::SimplifyTerm_TopLevel(const ASTNode& b) { output = (isAnd) ? (pushNeg ? - CreateNode(OR, outvec) : - CreateNode(AND, outvec)) : - (pushNeg ? CreateNode(AND, outvec) : CreateNode(OR,outvec)); + _bm->CreateNode(OR, outvec) : + _bm->CreateNode(AND, outvec)) : + (pushNeg ? _bm->CreateNode(AND, outvec) : _bm->CreateNode(OR,outvec)); //output = FlattenOneLevel(output); break; } @@ -1006,7 +936,7 @@ ASTNode BeevMgr::SimplifyTerm_TopLevel(const ASTNode& b) ASTNode - BeevMgr::SimplifyNotFormula(const ASTNode& a, + Simplifier::SimplifyNotFormula(const ASTNode& a, bool pushNeg, ASTNodeMap* VarConstMap) { ASTNode output; @@ -1058,7 +988,7 @@ ASTNode BeevMgr::SimplifyTerm_TopLevel(const ASTNode& b) return output; } - ASTNode BeevMgr::SimplifyXorFormula(const ASTNode& a, bool pushNeg, ASTNodeMap* VarConstMap) + ASTNode Simplifier::SimplifyXorFormula(const ASTNode& a, bool pushNeg, ASTNodeMap* VarConstMap) { ASTNode output; if (CheckSimplifyMap(a, output, pushNeg, VarConstMap)) @@ -1071,7 +1001,7 @@ ASTNode BeevMgr::SimplifyTerm_TopLevel(const ASTNode& b) ASTNode a0 = SimplifyFormula(a[0], false, VarConstMap); ASTNode a1 = SimplifyFormula(a[1], false, VarConstMap); - output = pushNeg ? CreateNode(IFF, a0, a1) : CreateNode(XOR, a0, a1); + output = pushNeg ? _bm->CreateNode(IFF, a0, a1) : _bm->CreateNode(XOR, a0, a1); if (XOR == output.GetKind()) { @@ -1088,7 +1018,7 @@ ASTNode BeevMgr::SimplifyTerm_TopLevel(const ASTNode& b) return output; } - ASTNode BeevMgr::SimplifyNandFormula(const ASTNode& a, bool pushNeg, ASTNodeMap* VarConstMap) + ASTNode Simplifier::SimplifyNandFormula(const ASTNode& a, bool pushNeg, ASTNodeMap* VarConstMap) { ASTNode output, a0, a1; if (CheckSimplifyMap(a, output, pushNeg, VarConstMap)) @@ -1099,14 +1029,14 @@ ASTNode BeevMgr::SimplifyTerm_TopLevel(const ASTNode& b) { a0 = SimplifyFormula(a[0], false, VarConstMap); a1 = SimplifyFormula(a[1], false, VarConstMap); - output = CreateNode(AND, a0, a1); + output = _bm->CreateNode(AND, a0, a1); } else { //push the NOT implicit in the NAND a0 = SimplifyFormula(a[0], true, VarConstMap); a1 = SimplifyFormula(a[1], true, VarConstMap); - output = CreateNode(OR, a0, a1); + output = _bm->CreateNode(OR, a0, a1); } //memoize @@ -1114,7 +1044,7 @@ ASTNode BeevMgr::SimplifyTerm_TopLevel(const ASTNode& b) return output; } - ASTNode BeevMgr::SimplifyNorFormula(const ASTNode& a, bool pushNeg, ASTNodeMap* VarConstMap) + ASTNode Simplifier::SimplifyNorFormula(const ASTNode& a, bool pushNeg, ASTNodeMap* VarConstMap) { ASTNode output, a0, a1; if (CheckSimplifyMap(a, output, pushNeg, VarConstMap)) @@ -1125,14 +1055,14 @@ ASTNode BeevMgr::SimplifyTerm_TopLevel(const ASTNode& b) { a0 = SimplifyFormula(a[0], false); a1 = SimplifyFormula(a[1], false, VarConstMap); - output = CreateNode(OR, a0, a1); + output = _bm->CreateNode(OR, a0, a1); } else { //push the NOT implicit in the NAND a0 = SimplifyFormula(a[0], true, VarConstMap); a1 = SimplifyFormula(a[1], true, VarConstMap); - output = CreateNode(AND, a0, a1); + output = _bm->CreateNode(AND, a0, a1); } //memoize @@ -1140,7 +1070,7 @@ ASTNode BeevMgr::SimplifyTerm_TopLevel(const ASTNode& b) return output; } - ASTNode BeevMgr::SimplifyImpliesFormula(const ASTNode& a, bool pushNeg, ASTNodeMap* VarConstMap) + ASTNode Simplifier::SimplifyImpliesFormula(const ASTNode& a, bool pushNeg, ASTNodeMap* VarConstMap) { ASTNode output; if (CheckSimplifyMap(a, output, pushNeg, VarConstMap)) @@ -1154,7 +1084,7 @@ ASTNode BeevMgr::SimplifyTerm_TopLevel(const ASTNode& b) { c0 = SimplifyFormula(a[0], false, VarConstMap); c1 = SimplifyFormula(a[1], true, VarConstMap); - output = CreateNode(AND, c0, c1); + output = _bm->CreateNode(AND, c0, c1); } else { @@ -1180,7 +1110,7 @@ ASTNode BeevMgr::SimplifyTerm_TopLevel(const ASTNode& b) output = c1; } else if (CheckAlwaysTrueFormMap(c1) || - CheckAlwaysTrueFormMap(CreateNode(NOT, c0)) || + CheckAlwaysTrueFormMap(_bm->CreateNode(NOT, c0)) || (NOT == c0.GetKind() && CheckAlwaysTrueFormMap(c0[0]))) { //(~c0 AND (~c0 OR c1)) <==> TRUE @@ -1188,22 +1118,22 @@ ASTNode BeevMgr::SimplifyTerm_TopLevel(const ASTNode& b) //(c0 AND ~c0->c1) <==> TRUE output = ASTTrue; } - else if (CheckAlwaysTrueFormMap(CreateNode(NOT, c1)) || + else if (CheckAlwaysTrueFormMap(_bm->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); + output = _bm->CreateNode(NOT, c0); } else { if (NOT == c0.GetKind()) { - output = CreateNode(OR, c0[0], c1); + output = _bm->CreateNode(OR, c0[0], c1); } else { - output = CreateNode(OR, CreateNode(NOT, c0), c1); + output = _bm->CreateNode(OR, _bm->CreateNode(NOT, c0), c1); } } } @@ -1213,7 +1143,7 @@ ASTNode BeevMgr::SimplifyTerm_TopLevel(const ASTNode& b) return output; } - ASTNode BeevMgr::SimplifyIffFormula(const ASTNode& a, bool pushNeg, ASTNodeMap* VarConstMap) + ASTNode Simplifier::SimplifyIffFormula(const ASTNode& a, bool pushNeg, ASTNodeMap* VarConstMap) { ASTNode output; if (CheckSimplifyMap(a, output, pushNeg, VarConstMap)) @@ -1262,17 +1192,17 @@ ASTNode BeevMgr::SimplifyTerm_TopLevel(const ASTNode& b) { output = c0; } - else if (CheckAlwaysTrueFormMap(CreateNode(NOT, c0))) + else if (CheckAlwaysTrueFormMap(_bm->CreateNode(NOT, c0))) { - output = CreateNode(NOT, c1); + output = _bm->CreateNode(NOT, c1); } - else if (CheckAlwaysTrueFormMap(CreateNode(NOT, c1))) + else if (CheckAlwaysTrueFormMap(_bm->CreateNode(NOT, c1))) { - output = CreateNode(NOT, c0); + output = _bm->CreateNode(NOT, c0); } else { - output = CreateNode(IFF, c0, c1); + output = _bm->CreateNode(IFF, c0, c1); } //memoize @@ -1280,7 +1210,7 @@ ASTNode BeevMgr::SimplifyTerm_TopLevel(const ASTNode& b) return output; } - ASTNode BeevMgr::SimplifyIteFormula(const ASTNode& b, bool pushNeg, ASTNodeMap* VarConstMap) + ASTNode Simplifier::SimplifyIteFormula(const ASTNode& b, bool pushNeg, ASTNodeMap* VarConstMap) { // if (!optimize_flag) // return b; @@ -1328,32 +1258,32 @@ ASTNode BeevMgr::SimplifyTerm_TopLevel(const ASTNode& b) } else if (ASTTrue == t1) { - output = CreateNode(OR, t0, t2); + output = _bm->CreateNode(OR, t0, t2); } else if (ASTFalse == t1) { - output = CreateNode(AND, CreateNode(NOT, t0), t2); + output = _bm->CreateNode(AND, _bm->CreateNode(NOT, t0), t2); } else if (ASTTrue == t2) { - output = CreateNode(OR, CreateNode(NOT, t0), t1); + output = _bm->CreateNode(OR, _bm->CreateNode(NOT, t0), t1); } else if (ASTFalse == t2) { - output = CreateNode(AND, t0, t1); + output = _bm->CreateNode(AND, t0, t1); } else if (CheckAlwaysTrueFormMap(t0)) { output = t1; } - else if (CheckAlwaysTrueFormMap(CreateNode(NOT, t0)) || + else if (CheckAlwaysTrueFormMap(_bm->CreateNode(NOT, t0)) || (NOT == t0.GetKind() && CheckAlwaysTrueFormMap(t0[0]))) { output = t2; } else { - output = CreateNode(ITE, t0, t1, t2); + output = _bm->CreateNode(ITE, t0, t1, t2); } //memoize @@ -1362,7 +1292,7 @@ ASTNode BeevMgr::SimplifyTerm_TopLevel(const ASTNode& b) } //one level deep flattening - ASTNode BeevMgr::FlattenOneLevel(const ASTNode& a) + ASTNode Simplifier::FlattenOneLevel(const ASTNode& a) { Kind k = a.GetKind(); if (!(BVPLUS == k || AND == k || OR == k @@ -1395,9 +1325,9 @@ ASTNode BeevMgr::SimplifyTerm_TopLevel(const ASTNode& b) } if (is_Form_kind(k)) - output = CreateNode(k, o); + output = _bm->CreateNode(k, o); else - output = CreateTerm(k, a.GetValueWidth(), o); + output = _bm->CreateTerm(k, a.GetValueWidth(), o); //UpdateSimplifyMap(a,output,false); return output; @@ -1406,7 +1336,7 @@ ASTNode BeevMgr::SimplifyTerm_TopLevel(const ASTNode& b) //This function simplifies terms based on their kind ASTNode - BeevMgr::SimplifyTerm(const ASTNode& actualInputterm, ASTNodeMap* VarConstMap) + Simplifier::SimplifyTerm(const ASTNode& actualInputterm, ASTNodeMap* VarConstMap) { ASTNode inputterm(actualInputterm); // mutable local copy. @@ -1416,7 +1346,7 @@ ASTNode BeevMgr::SimplifyTerm_TopLevel(const ASTNode& b) // return inputterm; // } - ASTNode output; + ASTNode output = inputterm; assert(BVTypeCheck(inputterm)); //######################################## @@ -1514,14 +1444,14 @@ ASTNode BeevMgr::SimplifyTerm_TopLevel(const ASTNode& b) } CONSTANTBV::BitVector_increment(maskedPlusOne); ASTNode temp = - CreateTerm(BVMULT, inputValueWidth, - CreateBVConst(maskedPlusOne, inputValueWidth), other); - output = CreateTerm(BVNEG, inputValueWidth, temp); + _bm->CreateTerm(BVMULT, inputValueWidth, + _bm->CreateBVConst(maskedPlusOne, inputValueWidth), other); + output = _bm->CreateTerm(BVNEG, inputValueWidth, temp); } } } - if (NULL != output) + if (output.IsNull()) break; case BVPLUS: @@ -1551,9 +1481,9 @@ ASTNode BeevMgr::SimplifyTerm_TopLevel(const ASTNode& b) } } - ASTNode one = CreateOneConst(inputValueWidth); - ASTNode max = CreateMaxConst(inputValueWidth); - ASTNode zero = CreateZeroConst(inputValueWidth); + ASTNode one = _bm->CreateOneConst(inputValueWidth); + ASTNode max = _bm->CreateMaxConst(inputValueWidth); + ASTNode zero = _bm->CreateZeroConst(inputValueWidth); //initialize constoutput to zero, in case there are no elements //in constkids @@ -1567,7 +1497,7 @@ ASTNode BeevMgr::SimplifyTerm_TopLevel(const ASTNode& b) else if (1 < constkids.size()) { //many elements in constkids. simplify it - constoutput = CreateTerm(k, inputterm.GetValueWidth(), constkids); + constoutput = _bm->CreateTerm(k, inputterm.GetValueWidth(), constkids); constoutput = BVConstEvaluator(constoutput); } @@ -1579,7 +1509,7 @@ ASTNode BeevMgr::SimplifyTerm_TopLevel(const ASTNode& b) { //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); + output = _bm->CreateTerm(BVUMINUS, inputValueWidth, nonconstkids); } else { @@ -1606,7 +1536,7 @@ ASTNode BeevMgr::SimplifyTerm_TopLevel(const ASTNode& b) { //more than 1 element in nonconstkids. create BVPLUS term SortByArith(nonconstkids); - output = CreateTerm(k, inputValueWidth, nonconstkids); + output = _bm->CreateTerm(k, inputValueWidth, nonconstkids); output = Flatten(output); output = DistributeMultOverPlus(output, true); output = CombineLikeTerms(output); @@ -1636,10 +1566,10 @@ ASTNode BeevMgr::SimplifyTerm_TopLevel(const ASTNode& b) if (uminus != 0) { SortByArith(d); - output = CreateTerm(BVMULT, output.GetValueWidth(), d); + output = _bm->CreateTerm(BVMULT, output.GetValueWidth(), d); if ((uminus & 0x1) != 0) // odd, pull up the uminus. { - output = CreateTerm(BVUMINUS, output.GetValueWidth(), output); + output = _bm->CreateTerm(BVUMINUS, output.GetValueWidth(), output); } } } @@ -1650,7 +1580,7 @@ ASTNode BeevMgr::SimplifyTerm_TopLevel(const ASTNode& b) { ASTVec d = output.GetChildren(); SortByArith(d); - output = CreateTerm(output.GetKind(), output.GetValueWidth(), d); + output = _bm->CreateTerm(output.GetKind(), output.GetValueWidth(), d); } @@ -1665,14 +1595,14 @@ ASTNode BeevMgr::SimplifyTerm_TopLevel(const ASTNode& b) ASTNode a1 = SimplifyTerm(inputterm[1], VarConstMap); unsigned int l = inputValueWidth; if (a0 == a1) - output = CreateZeroConst(l); + output = _bm->CreateZeroConst(l); else { //covert x-y into x+(-y) and simplify. this transformation //triggers more simplifications // - a1 = SimplifyTerm(CreateTerm(BVUMINUS, l, a1), VarConstMap); - output = SimplifyTerm(CreateTerm(BVPLUS, l, a0, a1), VarConstMap); + a1 = SimplifyTerm(_bm->CreateTerm(BVUMINUS, l, a1), VarConstMap); + output = SimplifyTerm(_bm->CreateTerm(BVPLUS, l, a0, a1), VarConstMap); } break; } @@ -1686,7 +1616,7 @@ ASTNode BeevMgr::SimplifyTerm_TopLevel(const ASTNode& b) ASTNode a0 = SimplifyTerm(inputterm[0], VarConstMap); Kind k1 = a0.GetKind(); unsigned int l = a0.GetValueWidth(); - ASTNode one = CreateOneConst(l); + ASTNode one = _bm->CreateOneConst(l); switch (k1) { case BVUMINUS: @@ -1694,23 +1624,23 @@ ASTNode BeevMgr::SimplifyTerm_TopLevel(const ASTNode& b) break; case BVCONST: { - output = BVConstEvaluator(CreateTerm(BVUMINUS, l, a0)); + output = BVConstEvaluator(_bm->CreateTerm(BVUMINUS, l, a0)); break; } case BVNEG: { - output = SimplifyTerm(CreateTerm(BVPLUS, l, a0[0], one), VarConstMap); + output = SimplifyTerm(_bm->CreateTerm(BVPLUS, l, a0[0], one), VarConstMap); break; } case BVMULT: { if (BVUMINUS == a0[0].GetKind()) { - output = CreateTerm(BVMULT, l, a0[0][0], a0[1]); + output = _bm->CreateTerm(BVMULT, l, a0[0][0], a0[1]); } else if (BVUMINUS == a0[1].GetKind()) { - output = CreateTerm(BVMULT, l, a0[0], a0[1][0]); + output = _bm->CreateTerm(BVMULT, l, a0[0], a0[1][0]); } else { @@ -1720,11 +1650,11 @@ ASTNode BeevMgr::SimplifyTerm_TopLevel(const ASTNode& b) // not -(3*x). if (BVCONST == a0[0].GetKind()) { - ASTNode a00 = SimplifyTerm(CreateTerm(BVUMINUS, l, a0[0]), VarConstMap); - output = CreateTerm(BVMULT, l, a00, a0[1]); + ASTNode a00 = SimplifyTerm(_bm->CreateTerm(BVUMINUS, l, a0[0]), VarConstMap); + output = _bm->CreateTerm(BVMULT, l, a00, a0[1]); } else - output = CreateTerm(BVUMINUS, l, a0); + output = _bm->CreateTerm(BVUMINUS, l, a0); } break; } @@ -1740,31 +1670,31 @@ ASTNode BeevMgr::SimplifyTerm_TopLevel(const ASTNode& b) for (ASTVec::iterator it = c.begin(), itend = c.end(); it != itend; it++) { //Simplify(BVUMINUS(a1x1)) - ASTNode aaa = SimplifyTerm(CreateTerm(BVUMINUS, l, *it), VarConstMap); + ASTNode aaa = SimplifyTerm(_bm->CreateTerm(BVUMINUS, l, *it), VarConstMap); o.push_back(aaa); } //simplify the bvplus - output = SimplifyTerm(CreateTerm(BVPLUS, l, o), VarConstMap); + output = SimplifyTerm(_bm->CreateTerm(BVPLUS, l, o), VarConstMap); break; } case BVSUB: { //BVUMINUS(BVSUB(x,y)) <=> BVSUB(y,x) - output = SimplifyTerm(CreateTerm(BVSUB, l, a0[1], a0[0]), VarConstMap); + output = SimplifyTerm(_bm->CreateTerm(BVSUB, l, a0[1], a0[0]), VarConstMap); 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]), VarConstMap); - ASTNode t2 = SimplifyTerm(CreateTerm(BVUMINUS, l, a0[2]), VarConstMap); + ASTNode t1 = SimplifyTerm(_bm->CreateTerm(BVUMINUS, l, a0[1]), VarConstMap); + ASTNode t2 = SimplifyTerm(_bm->CreateTerm(BVUMINUS, l, a0[2]), VarConstMap); output = CreateSimplifiedTermITE(c, t1, t2); break; } default: { - output = CreateTerm(BVUMINUS, l, a0); + output = _bm->CreateTerm(BVUMINUS, l, a0); break; } } @@ -1782,7 +1712,7 @@ ASTNode BeevMgr::SimplifyTerm_TopLevel(const ASTNode& b) //indices for BVEXTRACT ASTNode i = inputterm[1]; ASTNode j = inputterm[2]; - ASTNode zero = CreateBVConst(32, 0); + ASTNode zero = _bm->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); @@ -1797,7 +1727,7 @@ ASTNode BeevMgr::SimplifyTerm_TopLevel(const ASTNode& b) case BVCONST: { //extract the constant - output = BVConstEvaluator(CreateTerm(BVEXTRACT, a_len, a0, i, j)); + output = BVConstEvaluator(_bm->CreateTerm(BVEXTRACT, a_len, a0, i, j)); break; } case BVCONCAT: @@ -1817,25 +1747,25 @@ ASTNode BeevMgr::SimplifyTerm_TopLevel(const ASTNode& b) //Apply the following rule: // (t@u)[i:j] <==> u[i:j], if len(u) > i // - output = SimplifyTerm(CreateTerm(BVEXTRACT, a_len, u, i, j), VarConstMap); + output = SimplifyTerm(_bm->CreateTerm(BVEXTRACT, a_len, u, i, j), VarConstMap); } 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), VarConstMap); + i = _bm->CreateBVConst(32, i_val - len_u); + j = _bm->CreateBVConst(32, j_val - len_u); + output = SimplifyTerm(_bm->CreateTerm(BVEXTRACT, a_len, t, i, j), VarConstMap); } 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), VarConstMap); - u = SimplifyTerm(CreateTerm(BVEXTRACT, len_u - j_val, u, m, j), VarConstMap); - output = CreateTerm(BVCONCAT, a_len, t, u); + i = _bm->CreateBVConst(32, i_val - len_u); + ASTNode m = _bm->CreateBVConst(32, len_u - 1); + t = SimplifyTerm(_bm->CreateTerm(BVEXTRACT, i_val - len_u + 1, t, i, zero), VarConstMap); + u = SimplifyTerm(_bm->CreateTerm(BVEXTRACT, len_u - j_val, u, m, j), VarConstMap); + output = _bm->CreateTerm(BVCONCAT, a_len, t, u); } break; } @@ -1849,14 +1779,14 @@ ASTNode BeevMgr::SimplifyTerm_TopLevel(const ASTNode& b) 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), VarConstMap); + aaa = SimplifyTerm(_bm->CreateTerm(BVEXTRACT, i_val + 1, aaa, i, zero), VarConstMap); o.push_back(aaa); } - output = CreateTerm(a0.GetKind(), i_val + 1, o); + output = _bm->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); + output = _bm->CreateTerm(BVEXTRACT, a_len, output, i, j); } break; } @@ -1869,19 +1799,19 @@ ASTNode BeevMgr::SimplifyTerm_TopLevel(const ASTNode& b) // (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), VarConstMap); - u = SimplifyTerm(CreateTerm(BVEXTRACT, a_len, u, i, j), VarConstMap); + t = SimplifyTerm(_bm->CreateTerm(BVEXTRACT, a_len, t, i, j), VarConstMap); + u = SimplifyTerm(_bm->CreateTerm(BVEXTRACT, a_len, u, i, j), VarConstMap); BVTypeCheck(t); BVTypeCheck(u); - output = CreateTerm(k1, a_len, t, u); + output = _bm->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), VarConstMap); - output = CreateTerm(BVNEG, a_len, t); + t = SimplifyTerm(_bm->CreateTerm(BVEXTRACT, a_len, t, i, j), VarConstMap); + output = _bm->CreateTerm(BVNEG, a_len, t); break; } // case BVSX:{ @@ -1893,24 +1823,24 @@ ASTNode BeevMgr::SimplifyTerm_TopLevel(const ASTNode& b) // "the length of BVSX term must be greater than extract-len",inputterm); // } // if(j != zero) { - // output = CreateTerm(BVEXTRACT,a_len,a0,i,j); + // output = _bm->CreateTerm(BVEXTRACT,a_len,a0,i,j); // } // else { - // output = CreateTerm(BVSX,a_len,t,CreateBVConst(32,a_len)); + // output = _bm->CreateTerm(BVSX,a_len,t,_bm->CreateBVConst(32,a_len)); // } // break; // } case ITE: { ASTNode t0 = a0[0]; - ASTNode t1 = SimplifyTerm(CreateTerm(BVEXTRACT, a_len, a0[1], i, j), VarConstMap); - ASTNode t2 = SimplifyTerm(CreateTerm(BVEXTRACT, a_len, a0[2], i, j), VarConstMap); + ASTNode t1 = SimplifyTerm(_bm->CreateTerm(BVEXTRACT, a_len, a0[1], i, j), VarConstMap); + ASTNode t2 = SimplifyTerm(_bm->CreateTerm(BVEXTRACT, a_len, a0[2], i, j), VarConstMap); output = CreateSimplifiedTermITE(t0, t1, t2); break; } default: { - output = CreateTerm(BVEXTRACT, a_len, a0, i, j); + output = _bm->CreateTerm(BVEXTRACT, a_len, a0, i, j); break; } } @@ -1923,20 +1853,20 @@ ASTNode BeevMgr::SimplifyTerm_TopLevel(const ASTNode& b) switch (a0.GetKind()) { case BVCONST: - output = BVConstEvaluator(CreateTerm(BVNEG, len, a0)); + output = BVConstEvaluator(_bm->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]), VarConstMap); - // ASTNode elsepart = SimplifyTerm(CreateTerm(BVNEG,len,a0[2]), VarConstMap); - // output = CreateSimplifiedTermITE(cond,thenpart,elsepart); + // ASTNode thenpart = SimplifyTerm(_bm->CreateTerm(BVNEG,len,a0[1]), VarConstMap); + // ASTNode elsepart = SimplifyTerm(_bm->CreateTerm(BVNEG,len,a0[2]), VarConstMap); + // output = _bm->CreateSimplifiedTermITE(cond,thenpart,elsepart); // break; // } default: - output = CreateTerm(BVNEG, len, a0); + output = _bm->CreateTerm(BVNEG, len, a0); break; } break; @@ -1960,15 +1890,15 @@ ASTNode BeevMgr::SimplifyTerm_TopLevel(const ASTNode& b) switch (a0.GetKind()) { case BVCONST: - output = BVConstEvaluator(CreateTerm(BVSX, len, a0, a1)); + output = BVConstEvaluator(_bm->CreateTerm(BVSX, len, a0, a1)); break; case BVNEG: - output = CreateTerm(a0.GetKind(), len, CreateTerm(BVSX, len, a0[0], a1)); + output = _bm->CreateTerm(a0.GetKind(), len, _bm->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)); + output = _bm->CreateTerm(a0.GetKind(), len, _bm->CreateTerm(BVSX, len, a0[0], a1), _bm->CreateTerm(BVSX, len, a0[1], a1)); break; case BVPLUS: { @@ -1985,17 +1915,17 @@ ASTNode BeevMgr::SimplifyTerm_TopLevel(const ASTNode& b) } if (returnflag) { - output = CreateTerm(BVSX, len, a0, a1); + output = _bm->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), VarConstMap); + ASTNode aaa = SimplifyTerm(_bm->CreateTerm(BVSX, len, *it, a1), VarConstMap); o.push_back(aaa); } - output = CreateTerm(a0.GetKind(), len, o); + output = _bm->CreateTerm(a0.GetKind(), len, o); } break; } @@ -2004,19 +1934,19 @@ ASTNode BeevMgr::SimplifyTerm_TopLevel(const ASTNode& b) //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], VarConstMap); - output = CreateTerm(BVSX, len, a0, a1); + output = _bm->CreateTerm(BVSX, len, a0, a1); break; } case ITE: { ASTNode cond = a0[0]; - ASTNode thenpart = SimplifyTerm(CreateTerm(BVSX, len, a0[1], a1), VarConstMap); - ASTNode elsepart = SimplifyTerm(CreateTerm(BVSX, len, a0[2], a1), VarConstMap); + ASTNode thenpart = SimplifyTerm(_bm->CreateTerm(BVSX, len, a0[1], a1), VarConstMap); + ASTNode elsepart = SimplifyTerm(_bm->CreateTerm(BVSX, len, a0[2], a1), VarConstMap); output = CreateSimplifiedTermITE(cond, thenpart, elsepart); break; } default: - output = CreateTerm(BVSX, len, a0, a1); + output = _bm->CreateTerm(BVSX, len, a0, a1); break; } break; @@ -2024,8 +1954,8 @@ ASTNode BeevMgr::SimplifyTerm_TopLevel(const ASTNode& b) case BVAND: case BVOR: { - ASTNode max = CreateMaxConst(inputValueWidth); - ASTNode zero = CreateZeroConst(inputValueWidth); + ASTNode max = _bm->CreateMaxConst(inputValueWidth); + ASTNode zero = _bm->CreateZeroConst(inputValueWidth); ASTNode identity = (BVAND == k) ? max : zero; ASTNode annihilator = (BVAND == k) ? zero : max; @@ -2066,7 +1996,7 @@ ASTNode BeevMgr::SimplifyTerm_TopLevel(const ASTNode& b) break; default: SortByArith(o); - output = CreateTerm(k, inputValueWidth, o); + output = _bm->CreateTerm(k, inputValueWidth, o); if (constant) { output = BVConstEvaluator(output); @@ -2084,7 +2014,7 @@ ASTNode BeevMgr::SimplifyTerm_TopLevel(const ASTNode& b) if (BVCONST == tkind && BVCONST == ukind) { - output = BVConstEvaluator(CreateTerm(BVCONCAT, inputValueWidth, t, u)); + output = BVConstEvaluator(_bm->CreateTerm(BVCONCAT, inputValueWidth, t, u)); } else if (BVEXTRACT == tkind && BVEXTRACT == ukind && t[0] == u[0]) { @@ -2093,19 +2023,19 @@ ASTNode BeevMgr::SimplifyTerm_TopLevel(const ASTNode& b) 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))); + ASTNode c = BVConstEvaluator(_bm->CreateTerm(BVPLUS, 32, u_hi, _bm->CreateOneConst(32))); if (t_low == c) { - output = CreateTerm(BVEXTRACT, inputValueWidth, t[0], t_hi, u_low); + output = _bm->CreateTerm(BVEXTRACT, inputValueWidth, t[0], t_hi, u_low); } else { - output = CreateTerm(BVCONCAT, inputValueWidth, t, u); + output = _bm->CreateTerm(BVCONCAT, inputValueWidth, t, u); } } else { - output = CreateTerm(BVCONCAT, inputValueWidth, t, u); + output = _bm->CreateTerm(BVCONCAT, inputValueWidth, t, u); } break; } @@ -2124,14 +2054,14 @@ ASTNode BeevMgr::SimplifyTerm_TopLevel(const ASTNode& b) { // Intended to remove shifts by very large amounts that don't fit into the unsigned. // at thhe start of the "else" branch. - output = CreateZeroConst(width); + output = _bm->CreateZeroConst(width); } else { const unsigned int shift = GetUnsignedConst(b); if (shift > width) { - output = CreateZeroConst(width); + output = _bm->CreateZeroConst(width); } else if (shift == 0) { @@ -2141,22 +2071,22 @@ ASTNode BeevMgr::SimplifyTerm_TopLevel(const ASTNode& b) { if (k == BVLEFTSHIFT) { - ASTNode zero = CreateZeroConst(shift); - ASTNode hi = CreateBVConst(32, width - shift -1); - ASTNode low = CreateBVConst(32, 0); - ASTNode extract = CreateTerm(BVEXTRACT, width - shift, a, hi, low); + ASTNode zero = _bm->CreateZeroConst(shift); + ASTNode hi = _bm->CreateBVConst(32, width - shift -1); + ASTNode low = _bm->CreateBVConst(32, 0); + ASTNode extract = _bm->CreateTerm(BVEXTRACT, width - shift, a, hi, low); BVTypeCheck(extract); - output = CreateTerm(BVCONCAT, width, extract, zero); + output = _bm->CreateTerm(BVCONCAT, width, extract, zero); BVTypeCheck(output); } else if (k == BVRIGHTSHIFT) { - ASTNode zero = CreateZeroConst(shift); - ASTNode hi = CreateBVConst(32, width -1); - ASTNode low = CreateBVConst(32, shift); - ASTNode extract = CreateTerm(BVEXTRACT, width - shift, a, hi, low); + ASTNode zero = _bm->CreateZeroConst(shift); + ASTNode hi = _bm->CreateBVConst(32, width -1); + ASTNode low = _bm->CreateBVConst(32, shift); + ASTNode extract = _bm->CreateTerm(BVEXTRACT, width - shift, a, hi, low); BVTypeCheck(extract); - output = CreateTerm(BVCONCAT, width, zero, extract); + output = _bm->CreateTerm(BVCONCAT, width, zero, extract); BVTypeCheck(output); } else @@ -2165,7 +2095,7 @@ ASTNode BeevMgr::SimplifyTerm_TopLevel(const ASTNode& b) } } else - output = CreateTerm(k, width, a, b); + output = _bm->CreateTerm(k, width, a, b); } break; @@ -2191,7 +2121,7 @@ ASTNode BeevMgr::SimplifyTerm_TopLevel(const ASTNode& b) } o.push_back(aaa); } - output = CreateTerm(k, inputValueWidth, o); + output = _bm->CreateTerm(k, inputValueWidth, o); if (constant) output = BVConstEvaluator(output); break; @@ -2214,8 +2144,8 @@ ASTNode BeevMgr::SimplifyTerm_TopLevel(const ASTNode& b) ASTNode cond = SimplifyFormula(inputterm[0][0], false, VarConstMap); ASTNode index = SimplifyTerm(inputterm[1], VarConstMap); - ASTNode read1 = CreateTerm(READ, inputValueWidth, inputterm[0][1], index); - ASTNode read2 = CreateTerm(READ, inputValueWidth, inputterm[0][2], index); + ASTNode read1 = _bm->CreateTerm(READ, inputValueWidth, inputterm[0][1], index); + ASTNode read2 = _bm->CreateTerm(READ, inputValueWidth, inputterm[0][2], index); read1 = SimplifyTerm(read1, VarConstMap); read2 = SimplifyTerm(read2, VarConstMap); @@ -2226,7 +2156,7 @@ ASTNode BeevMgr::SimplifyTerm_TopLevel(const ASTNode& b) //arr is a SYMBOL for sure ASTNode arr = inputterm[0]; ASTNode index = SimplifyTerm(inputterm[1], VarConstMap); - out1 = CreateTerm(READ, inputValueWidth, arr, index); + out1 = _bm->CreateTerm(READ, inputValueWidth, arr, index); } } //it is possible that after all the procesing the READ term @@ -2255,7 +2185,7 @@ ASTNode BeevMgr::SimplifyTerm_TopLevel(const ASTNode& b) ASTNode aaa = SimplifyTerm(*it, VarConstMap); o.push_back(aaa); } - output = CreateTerm(k, inputValueWidth, o); + output = _bm->CreateTerm(k, inputValueWidth, o); break; } case WRITE: @@ -2264,7 +2194,7 @@ ASTNode BeevMgr::SimplifyTerm_TopLevel(const ASTNode& b) return inputterm; break; } - assert(NULL != output); + assert(!output.IsNull()); //memoize UpdateSimplifyMap(inputterm, output, false, VarConstMap); @@ -2277,16 +2207,16 @@ ASTNode BeevMgr::SimplifyTerm_TopLevel(const ASTNode& b) //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) + void Simplifier::CheckSimplifyInvariant(const ASTNode& a, const ASTNode& output) { - if (NodeSize(a, true) + 1 < NodeSize(output, true)) + if (_bm->NodeSize(a, true) + 1 < _bm->NodeSize(output, true)) { cerr << "lhs := " << a << endl; - cerr << "NodeSize of lhs is: " << NodeSize(a, true) << endl; + cerr << "NodeSize of lhs is: " << _bm->NodeSize(a, true) << endl; cerr << endl; cerr << "rhs := " << output << endl; - cerr << "NodeSize of rhs is: " << NodeSize(output, true) << endl; + cerr << "NodeSize of rhs is: " << _bm->NodeSize(output, true) << endl; // FatalError("SimplifyFormula: The nodesize shoudl decrease from lhs to rhs: ",ASTUndefined); } } @@ -2294,7 +2224,7 @@ ASTNode BeevMgr::SimplifyTerm_TopLevel(const ASTNode& b) //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) + ASTNode Simplifier::CombineLikeTerms(const ASTNode& a) { if (BVPLUS != a.GetKind()) return a; @@ -2316,9 +2246,9 @@ ASTNode BeevMgr::SimplifyTerm_TopLevel(const ASTNode& b) //useful constants unsigned int len = c[0].GetValueWidth(); - ASTNode one = CreateOneConst(len); - ASTNode zero = CreateZeroConst(len); - ASTNode max = CreateMaxConst(len); + ASTNode one = _bm->CreateOneConst(len); + ASTNode zero = _bm->CreateZeroConst(len); + ASTNode max = _bm->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 @@ -2339,7 +2269,7 @@ ASTNode BeevMgr::SimplifyTerm_TopLevel(const ASTNode& b) 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])); + ASTNode cccc = BVConstEvaluator(_bm->CreateTerm(BVUMINUS, len, aaa[0])); vars_to_consts[aaa[1][0]].push_back(cccc); } else if (BVMULT == aaa.GetKind() && BVCONST == aaa[0].GetKind()) @@ -2350,7 +2280,7 @@ ASTNode BeevMgr::SimplifyTerm_TopLevel(const ASTNode& b) else if (BVMULT == aaa.GetKind() && BVUMINUS == aaa[0].GetKind()) { //(-1*x)*(y) <==> -1*(xy) - ASTNode cccc = CreateTerm(BVMULT, len, aaa[0][0], aaa[1]); + ASTNode cccc = _bm->CreateTerm(BVMULT, len, aaa[0][0], aaa[1]); ASTVec cNodes = cccc.GetChildren(); SortByArith(cNodes); vars_to_consts[cccc].push_back(max); @@ -2358,7 +2288,7 @@ ASTNode BeevMgr::SimplifyTerm_TopLevel(const ASTNode& b) else if (BVMULT == aaa.GetKind() && BVUMINUS == aaa[1].GetKind()) { //x*(-1*y) <==> -1*(xy) - ASTNode cccc = CreateTerm(BVMULT, len, aaa[0], aaa[1][0]); + ASTNode cccc = _bm->CreateTerm(BVMULT, len, aaa[0], aaa[1][0]); ASTVec cNodes = cccc.GetChildren(); SortByArith(cNodes); vars_to_consts[cccc].push_back(max); @@ -2388,7 +2318,7 @@ ASTNode BeevMgr::SimplifyTerm_TopLevel(const ASTNode& b) ASTNode constant; if (1 < ccc.size()) { - constant = CreateTerm(BVPLUS, ccc[0].GetValueWidth(), ccc); + constant = _bm->CreateTerm(BVPLUS, ccc[0].GetValueWidth(), ccc); constant = BVConstEvaluator(constant); } else @@ -2402,7 +2332,7 @@ ASTNode BeevMgr::SimplifyTerm_TopLevel(const ASTNode& b) monom = it->first; else { - monom = SimplifyTerm(CreateTerm(BVMULT, constant.GetValueWidth(), constant, it->first)); + monom = SimplifyTerm(_bm->CreateTerm(BVMULT, constant.GetValueWidth(), constant, it->first)); } if (zero != monom) { @@ -2412,7 +2342,7 @@ ASTNode BeevMgr::SimplifyTerm_TopLevel(const ASTNode& b) if (constkids.size() > 1) { - ASTNode output = CreateTerm(BVPLUS, constkids[0].GetValueWidth(), constkids); + ASTNode output = _bm->CreateTerm(BVPLUS, constkids[0].GetValueWidth(), constkids); output = BVConstEvaluator(output); if (output != zero) outputvec.push_back(output); @@ -2425,7 +2355,7 @@ ASTNode BeevMgr::SimplifyTerm_TopLevel(const ASTNode& b) if (outputvec.size() > 1) { - output = CreateTerm(BVPLUS, len, outputvec); + output = _bm->CreateTerm(BVPLUS, len, outputvec); } else if (outputvec.size() == 1) { @@ -2445,7 +2375,7 @@ ASTNode BeevMgr::SimplifyTerm_TopLevel(const ASTNode& b) //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) + ASTNode Simplifier::LhsMinusRhs(const ASTNode& eq) { //if input is not an equality, simply return it if (EQ != eq.GetKind()) @@ -2490,27 +2420,27 @@ ASTNode BeevMgr::SimplifyTerm_TopLevel(const ASTNode& b) } unsigned int len = lhs.GetValueWidth(); - ASTNode zero = CreateZeroConst(len); + ASTNode zero = _bm->CreateZeroConst(len); //right is -1*(rhs): Simplify(-1*rhs) - rhs = SimplifyTerm(CreateTerm(BVUMINUS, len, rhs)); + rhs = SimplifyTerm(_bm->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); + lhsplusrhs = _bm->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); + lhsplusrhs = _bm->CreateTerm(BVPLUS, len, lvec); } else if (BVPLUS == lhs.GetKind() && BVPLUS != rhs.GetKind()) { lvec.push_back(rhs); - lhsplusrhs = CreateTerm(BVPLUS, len, lvec); + lhsplusrhs = _bm->CreateTerm(BVPLUS, len, lvec); } else { @@ -2529,7 +2459,7 @@ ASTNode BeevMgr::SimplifyTerm_TopLevel(const ASTNode& b) { ASTVec outv = output.GetChildren(); SortByArith(outv); - output = CreateTerm(BVPLUS, len, outv); + output = _bm->CreateTerm(BVPLUS, len, outv); } //memoize @@ -2545,7 +2475,7 @@ ASTNode BeevMgr::SimplifyTerm_TopLevel(const ASTNode& b) // (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) + ASTNode Simplifier::DistributeMultOverPlus(const ASTNode& a, bool startdistribution) { if (!startdistribution) return a; @@ -2569,8 +2499,8 @@ ASTNode BeevMgr::SimplifyTerm_TopLevel(const ASTNode& b) //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]); + ASTNode c = BVConstEvaluator(_bm->CreateTerm(BVMULT, a.GetValueWidth(), left, right[0])); + c = _bm->CreateTerm(BVMULT, a.GetValueWidth(), c, right[1]); return c; left = c[0]; right = c[1]; @@ -2581,8 +2511,8 @@ ASTNode BeevMgr::SimplifyTerm_TopLevel(const ASTNode& b) //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]); + ASTNode c = BVConstEvaluator(_bm->CreateTerm(BVMULT, a.GetValueWidth(), left, right[1])); + c = _bm->CreateTerm(BVMULT, a.GetValueWidth(), c, right[0]); return c; left = c[0]; right = c[1]; @@ -2613,8 +2543,8 @@ ASTNode BeevMgr::SimplifyTerm_TopLevel(const ASTNode& b) ASTVec rightnodes = right.GetChildren(); ASTVec outputvec; unsigned len = a.GetValueWidth(); - ASTNode zero = CreateZeroConst(len); - ASTNode one = CreateOneConst(len); + ASTNode zero = _bm->CreateZeroConst(len); + ASTNode one = _bm->CreateOneConst(len); if (BVPLUS != left_kind) { //if the multiplier is not a BVPLUS then we have a special case @@ -2631,7 +2561,7 @@ ASTNode BeevMgr::SimplifyTerm_TopLevel(const ASTNode& b) { for (ASTVec::iterator j = rightnodes.begin(), jend = rightnodes.end(); j != jend; j++) { - ASTNode out = SimplifyTerm(CreateTerm(BVMULT, len, left, *j)); + ASTNode out = SimplifyTerm(_bm->CreateTerm(BVMULT, len, left, *j)); outputvec.push_back(out); } } @@ -2646,7 +2576,7 @@ ASTNode BeevMgr::SimplifyTerm_TopLevel(const ASTNode& b) ASTNode multiplier = *i; for (ASTVec::iterator j = rightnodes.begin(), jend = rightnodes.end(); j != jend; j++) { - ASTNode out = SimplifyTerm(CreateTerm(BVMULT, len, multiplier, *j)); + ASTNode out = SimplifyTerm(_bm->CreateTerm(BVMULT, len, multiplier, *j)); outputvec.push_back(out); } } @@ -2655,7 +2585,7 @@ ASTNode BeevMgr::SimplifyTerm_TopLevel(const ASTNode& b) //compute output here if (outputvec.size() > 1) { - output = CombineLikeTerms(CreateTerm(BVPLUS, len, outputvec)); + output = CombineLikeTerms(_bm->CreateTerm(BVPLUS, len, outputvec)); output = SimplifyTerm(output); } else @@ -2668,7 +2598,7 @@ ASTNode BeevMgr::SimplifyTerm_TopLevel(const ASTNode& b) //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) + ASTNode Simplifier::ConvertBVSXToITE(const ASTNode& a) { if (BVSX != a.GetKind()) return a; @@ -2707,22 +2637,22 @@ ASTNode BeevMgr::SimplifyTerm_TopLevel(const ASTNode& b) zeros += '0'; //string of oness of length extensionlen - BEEV::ASTNode BVOnes = CreateBVConst(ones.c_str(), 2); + BEEV::ASTNode BVOnes = _bm->CreateBVConst(ones.c_str(), 2); //string of zeros of length extensionlen - BEEV::ASTNode BVZeros = CreateBVConst(zeros.c_str(), 2); + BEEV::ASTNode BVZeros = _bm->CreateBVConst(zeros.c_str(), 2); //string of ones BVCONCAT a0 - BEEV::ASTNode concatOnes = CreateTerm(BEEV::BVCONCAT, a_len, BVOnes, a0); + BEEV::ASTNode concatOnes = _bm->CreateTerm(BEEV::BVCONCAT, a_len, BVOnes, a0); //string of zeros BVCONCAT a0 - BEEV::ASTNode concatZeros = CreateTerm(BEEV::BVCONCAT, a_len, BVZeros, a0); + BEEV::ASTNode concatZeros = _bm->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); + BEEV::ASTNode hi = _bm->CreateBVConst(32, a0_len - 1); + BEEV::ASTNode low = _bm->CreateBVConst(32, a0_len - 1); + BEEV::ASTNode topBit = _bm->CreateTerm(BEEV::BVEXTRACT, 1, a0, hi, low); //compare topBit of a0 with 0bin1 - BEEV::ASTNode condition = CreateSimplifiedEQ(CreateBVConst(1, 1), topBit); + BEEV::ASTNode condition = CreateSimplifiedEQ(_bm->CreateBVConst(1, 1), topBit); //ITE(topbit = 0bin1, 0bin1111...a0, 0bin000...a0) output = CreateSimplifiedTermITE(condition, concatOnes, concatZeros); @@ -2731,18 +2661,22 @@ ASTNode BeevMgr::SimplifyTerm_TopLevel(const ASTNode& b) } //end of ConvertBVSXToITE() - ASTNode BeevMgr::RemoveWrites_TopLevel(const ASTNode& term) + ASTNode Simplifier::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) + if (!_bm->Begin_RemoveWrites + && !_bm->SimplifyWrites_InPlace_Flag + && !_bm->start_abstracting) { return term; } - else if (!Begin_RemoveWrites && SimplifyWrites_InPlace_Flag && !start_abstracting) + else if (!_bm->Begin_RemoveWrites + && _bm->SimplifyWrites_InPlace_Flag + && !_bm->start_abstracting) { //return term; return SimplifyWrites_InPlace(term); @@ -2753,7 +2687,7 @@ ASTNode BeevMgr::SimplifyTerm_TopLevel(const ASTNode& b) } } //end of RemoveWrites_TopLevel() - ASTNode BeevMgr::SimplifyWrites_InPlace(const ASTNode& term, ASTNodeMap* VarConstMap) + ASTNode Simplifier::SimplifyWrites_InPlace(const ASTNode& term, ASTNodeMap* VarConstMap) { ASTNodeMultiSet WriteIndicesSeenSoFar; bool SeenNonConstWriteIndex = false; @@ -2826,11 +2760,11 @@ ASTNode BeevMgr::SimplifyTerm_TopLevel(const ASTNode& b) for (; it_index != itend_index; it_index++, it_values++) { - write = CreateTerm(WRITE, width, write, *it_index, *it_values); + write = _bm->CreateTerm(WRITE, width, write, *it_index, *it_values); write.SetIndexWidth(indexwidth); } - output = CreateTerm(READ, width, write, readIndex); + output = _bm->CreateTerm(READ, width, write, readIndex); UpdateSimplifyMap(term, output, false); return output; } //end of SimplifyWrites_In_Place() @@ -2838,7 +2772,7 @@ ASTNode BeevMgr::SimplifyTerm_TopLevel(const ASTNode& b) //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) + ASTNode Simplifier::RemoveWrites(const ASTNode& input) { //unsigned int width = input.GetValueWidth(); if (READ != input.GetKind() || WRITE != input[0].GetKind()) @@ -2853,22 +2787,23 @@ ASTNode BeevMgr::SimplifyTerm_TopLevel(const ASTNode& b) return output; } - if (!start_abstracting && Begin_RemoveWrites) + if (!_bm->start_abstracting + && _bm->Begin_RemoveWrites) { output = ReadOverWrite_To_ITE(input); } - if (start_abstracting) + if (_bm->start_abstracting) { ASTNode newVar; if (!CheckSimplifyMap(input, newVar, false)) { - newVar = NewVar(input.GetValueWidth()); - ReadOverWrite_NewName_Map[input] = newVar; + newVar = _bm->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); + _bm->ASTNodeStats("New Var Name which replace Read_Over_Write: ", newVar); } output = newVar; } //end of start_abstracting if condition @@ -2878,7 +2813,7 @@ ASTNode BeevMgr::SimplifyTerm_TopLevel(const ASTNode& b) return output; } //end of RemoveWrites() - ASTNode BeevMgr::ReadOverWrite_To_ITE(const ASTNode& term, ASTNodeMap* VarConstMap) + ASTNode Simplifier::ReadOverWrite_To_ITE(const ASTNode& term, ASTNodeMap* VarConstMap) { unsigned int width = term.GetValueWidth(); ASTNode input = term; @@ -2908,7 +2843,7 @@ ASTNode BeevMgr::SimplifyTerm_TopLevel(const ASTNode& b) ASTNode writeVal = SimplifyTerm(write[2]); ASTNode cond = SimplifyFormula(CreateSimplifiedEQ(writeIndex, readIndex), false, VarConstMap); - ASTNode newRead = CreateTerm(READ, width, writeA, readIndex); + ASTNode newRead = _bm->CreateTerm(READ, width, writeA, readIndex); ASTNode newRead_memoized = newRead; if (CheckSimplifyMap(newRead, newRead_memoized, false)) { @@ -2963,7 +2898,7 @@ ASTNode BeevMgr::SimplifyTerm_TopLevel(const ASTNode& b) } //ReadOverWrite_To_ITE() //compute the multiplicative inverse of the input - ASTNode BeevMgr::MultiplicativeInverse(const ASTNode& d) + ASTNode Simplifier::MultiplicativeInverse(const ASTNode& d) { ASTNode c = d; if (BVCONST != c.GetKind()) @@ -2991,56 +2926,56 @@ ASTNode BeevMgr::SimplifyTerm_TopLevel(const ASTNode& b) //euclidian algorithm // //create a '0' which is 1 bit long - ASTNode onebit_zero = CreateZeroConst(1); + ASTNode onebit_zero = _bm->CreateZeroConst(1); //zero pad t0, i.e. 0 @ t0 - c = BVConstEvaluator(CreateTerm(BVCONCAT, inputwidth + 1, onebit_zero, c)); + c = BVConstEvaluator(_bm->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); + ASTNode max = _bm->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); + max = BVConstEvaluator(_bm->CreateTerm(BVCONCAT, inputwidth + 1, onebit_zero, max)); + //_bm->Create a '1' which has leading zeros of length 'inputwidth' + ASTNode inputwidthplusone_one = _bm->CreateOneConst(inputwidth + 1); //add 1 to max - max = CreateTerm(BVPLUS, inputwidth + 1, max, inputwidthplusone_one); + max = _bm->CreateTerm(BVPLUS, inputwidth + 1, max, inputwidthplusone_one); max = BVConstEvaluator(max); - ASTNode zero = CreateZeroConst(inputwidth + 1); - ASTNode max_bvgt_0 = CreateNode(BVGT, max, zero); + ASTNode zero = _bm->CreateZeroConst(inputwidth + 1); + ASTNode max_bvgt_0 = _bm->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); + x2 = _bm->CreateOneConst(inputwidth + 1); while (ASTTrue == BVConstEvaluator(max_bvgt_0)) { //quotient = (c divided by max) - quotient = BVConstEvaluator(CreateTerm(BVDIV, inputwidth + 1, c, max)); + quotient = BVConstEvaluator(_bm->CreateTerm(BVDIV, inputwidth + 1, c, max)); //remainder of (c divided by max) - remainder = BVConstEvaluator(CreateTerm(BVMOD, inputwidth + 1, c, max)); + remainder = BVConstEvaluator(_bm->CreateTerm(BVMOD, inputwidth + 1, c, max)); //x = x2 - q*x1 - x = CreateTerm(BVSUB, inputwidth + 1, x2, CreateTerm(BVMULT, inputwidth + 1, quotient, x1)); + x = _bm->CreateTerm(BVSUB, inputwidth + 1, x2, _bm->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); + max_bvgt_0 = _bm->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); + ASTNode hi = _bm->CreateBVConst(32, inputwidth - 1); + ASTNode low = _bm->CreateZeroConst(32); + inverse = _bm->CreateTerm(BVEXTRACT, inputwidth, x2, hi, low); inverse = BVConstEvaluator(inverse); UpdateMultInverseMap(d, inverse); @@ -3049,17 +2984,17 @@ ASTNode BeevMgr::SimplifyTerm_TopLevel(const ASTNode& b) } //end of MultiplicativeInverse() //returns true if the input is odd - bool BeevMgr::BVConstIsOdd(const ASTNode& c) + bool Simplifier::BVConstIsOdd(const ASTNode& c) { if (BVCONST != c.GetKind()) { FatalError("Input must be a constant", c); } - ASTNode zero = CreateZeroConst(1); - ASTNode hi = CreateZeroConst(32); + ASTNode zero = _bm->CreateZeroConst(1); + ASTNode hi = _bm->CreateZeroConst(32); ASTNode low = hi; - ASTNode lowestbit = CreateTerm(BVEXTRACT, 1, c, hi, low); + ASTNode lowestbit = _bm->CreateTerm(BVEXTRACT, 1, c, hi, low); lowestbit = BVConstEvaluator(lowestbit); if (lowestbit == zero) @@ -3071,165 +3006,42 @@ ASTNode BeevMgr::SimplifyTerm_TopLevel(const ASTNode& b) return true; } } //end of BVConstIsOdd() - - //The big substitution function - ASTNode BeevMgr::CreateSubstitutionMap(const ASTNode& a) - { - if (!wordlevel_solve_flag) - return a; - - ASTNode output = a; - //if the variable has been solved for, then simply return it - if (CheckSolverMap(a, output)) - return output; - - //traverse a and populate the SubstitutionMap - Kind k = a.GetKind(); - if (SYMBOL == k && BOOLEAN_TYPE == a.GetType()) - { - bool updated = UpdateSubstitutionMap(a, ASTTrue); - output = updated ? ASTTrue : a; - return output; - } - if (NOT == k && SYMBOL == a[0].GetKind()) - { - bool updated = UpdateSubstitutionMap(a[0], ASTFalse); - output = updated ? ASTTrue : a; - return output; - } - - if (IFF == k) - { - ASTVec c = a.GetChildren(); - SortByArith(c); - if (SYMBOL != c[0].GetKind() || VarSeenInTerm(c[0], SimplifyFormula_NoRemoveWrites(c[1], false))) - { - return a; - } - bool updated = UpdateSubstitutionMap(c[0], SimplifyFormula(c[1], false)); - output = updated ? ASTTrue : a; - return output; - } - - if (EQ == k) - { - //fill the arrayname readindices vector if e0 is a - //READ(Arr,index) and index is a BVCONST - ASTVec c = a.GetChildren(); - SortByArith(c); - FillUp_ArrReadIndex_Vec(c[0], c[1]); - - ASTNode c1 = SimplifyTerm(c[1]); - if (SYMBOL == c[0].GetKind() && VarSeenInTerm(c[0], c1)) - { - return a; - } - - if (1 == TermOrder(c[0], c[1]) && READ == c[0].GetKind() && VarSeenInTerm(c[0][1], c1)) - { - return a; - } - bool updated = UpdateSubstitutionMap(c[0], c1); - output = updated ? ASTTrue : a; - return output; - } - - if (AND == k) - { - ASTVec o; - ASTVec c = a.GetChildren(); - for (ASTVec::iterator it = c.begin(), itend = c.end(); it != itend; it++) - { - UpdateAlwaysTrueFormMap(*it); - ASTNode aaa = CreateSubstitutionMap(*it); - - if (ASTTrue != aaa) - { - if (ASTFalse == aaa) - return ASTFalse; - else - o.push_back(aaa); - } - } - if (o.size() == 0) - return ASTTrue; - - if (o.size() == 1) - return o[0]; - - return CreateNode(AND, o); - } - - //printf("I gave up on kind: %d node: %d\n", k, a.GetNodeNum()); - return output; - } //end of CreateSubstitutionMap() - - - bool BeevMgr::VarSeenInTerm(const ASTNode& var, const ASTNode& term) + + // in ext/hash_map, and tr/unordered_map, there is no provision to + // shrink down the number of buckets in a hash map. If the hash_map + // has previously held a lot of data, then it will have a lot of + // buckets. Slowing down iterators and clears() in particular. + void Simplifier::ResetSimplifyMaps() { - if (READ == term.GetKind() && WRITE == term[0].GetKind() && !Begin_RemoveWrites) - { - return false; - } - - if (READ == term.GetKind() && WRITE == term[0].GetKind() && Begin_RemoveWrites) - { - return true; - } - - ASTNodeMap::iterator it; - if ((it = TermsAlreadySeenMap.find(term)) != TermsAlreadySeenMap.end()) - { - if (it->second == var) - { - return false; - } - } - - if (var == term) - { - return true; - } - - for (ASTVec::const_iterator it = term.begin(), itend = term.end(); it != itend; it++) - { - if (VarSeenInTerm(var, *it)) - { - return true; - } - else - { - TermsAlreadySeenMap[*it] = var; - } - } - - TermsAlreadySeenMap[term] = var; - return false; - } - - // in ext/hash_map, and tr/unordered_map, there is no provision to shrink down - // the number of buckets in a hash map. If the hash_map has previously held a - // lot of data, then it will have a lot of buckets. Slowing down iterators and - // clears() in particular. - void BeevMgr::ResetSimplifyMaps() - { - // clear() is extremely expensive for hash_maps with a lot of buckets, - // in the EXT_MAP implementation it visits every bucket, checking whether - // each bucket is empty or not, if non-empty it deletes the contents. - // The destructor seems to clear everything anyway. + // clear() is extremely expensive for hash_maps with a lot of + // buckets, in the EXT_MAP implementation it visits every bucket, + // checking whether each bucket is empty or not, if non-empty it + // deletes the contents. The destructor seems to clear everything + // anyway. //SimplifyMap->clear(); delete SimplifyMap; - SimplifyMap = new ASTNodeMap(INITIAL_SIMPLIFY_MAP_SIZE); + SimplifyMap = new ASTNodeMap(); //SimplifyNegMap->clear(); delete SimplifyNegMap; - SimplifyNegMap = new ASTNodeMap(INITIAL_SIMPLIFY_MAP_SIZE); + SimplifyNegMap = new ASTNodeMap(); //ReferenceCount->clear(); delete ReferenceCount; - ReferenceCount = new ASTNodeCountMap(INITIAL_SIMPLIFY_MAP_SIZE); + ReferenceCount = new ASTNodeCountMap(); } -} -;//end of namespace +void Simplifier::printCacheStatus() +{ + cerr << SimplifyMap->size() << endl; + cerr << SimplifyNegMap->size() << endl; + cerr << ReferenceCount->size() << endl; + //cerr << TermsAlreadySeenMap.size() << endl; + + cerr << SimplifyMap->bucket_count() << endl; + cerr << SimplifyNegMap->bucket_count() << endl; + cerr << ReferenceCount->bucket_count() << endl; + //cerr << TermsAlreadySeenMap.bucket_count() << endl; +} //printCacheStatus() +};//end of namespace diff --git a/src/simplifier/simplifier.h b/src/simplifier/simplifier.h new file mode 100644 index 0000000..64d5147 --- /dev/null +++ b/src/simplifier/simplifier.h @@ -0,0 +1,247 @@ +// -*- c++ -*- +/******************************************************************** + * AUTHORS: Vijay Ganesh + * + * BEGIN DATE: November, 2005 + * + * LICENSE: Please view LICENSE file in the home dir of this Program + ********************************************************************/ + +#ifndef SIMPLIFIER_H +#define SIMPLIFIER_H + +#include "../AST/AST.h" +#include "../STPManager/STPManager.h" + +namespace BEEV +{ + class Simplifier + { + friend class counterexample; + private: + + /**************************************************************** + * Private Data and TypeDefs * + ****************************************************************/ + + // Handy defs + ASTNode ASTTrue, ASTFalse, ASTUndefined; + + // Memo table for simplifcation. Key is unsimplified node, and + // value is simplified node. + ASTNodeMap * SimplifyMap; + ASTNodeMap * SimplifyNegMap; + ASTNodeMap * SolverMap; + ASTNodeSet AlwaysTrueFormMap; + ASTNodeMap MultInverseMap; + + // 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; + + + // The number of direct parents of each node. i.e. the number + // of times the pointer is in "children". When we simplify we + // want to be careful sometimes about using the context of a + // node. For example, given ((x + 23) = 2), the obvious + // simplification is to join the constants. However, if there + // are lots of references to the plus node. Then each time we + // simplify, we'll create an additional plus. + // nextpoweroftwo064.smt is the motivating benchmark. The + // splitting increased the number of pluses from 1 to 65. + ASTNodeCountMap *ReferenceCount; + + //Ptr to STP Manager + BeevMgr * _bm; + + public: + + /**************************************************************** + * Public Member Functions * + ****************************************************************/ + Simplifier(BeevMgr * bm) : _bm(bm) + { + SimplifyMap = new ASTNodeMap(INITIAL_TABLE_SIZE); + SimplifyNegMap = new ASTNodeMap(INITIAL_TABLE_SIZE); + SolverMap = new ASTNodeMap(INITIAL_TABLE_SIZE); + ReadOverWrite_NewName_Map = new ASTNodeMap(INITIAL_TABLE_SIZE); + ReferenceCount = new ASTNodeCountMap(INITIAL_TABLE_SIZE); + + ASTTrue = bm->CreateNode(TRUE); + ASTFalse = bm->CreateNode(FALSE); + ASTUndefined = bm->CreateNode(UNDEFINED); + } + + ~Simplifier() + { + delete SimplifyMap; + delete SimplifyNegMap; + delete ReferenceCount; + } + + /**************************************************************** + * Functions to check and update various Maps * + ****************************************************************/ + + //Check the map passed to SimplifyTerm + bool CheckMap(ASTNodeMap* VarConstMap, + const ASTNode& key, ASTNode& output); + + //substitution + bool CheckSubstitutionMap(const ASTNode& a, ASTNode& output); + bool CheckSubstitutionMap(const ASTNode& a); + bool UpdateSubstitutionMap(const ASTNode& e0, const ASTNode& e1); + + //functions for checking and updating simplifcation map + bool CheckSimplifyMap(const ASTNode& key, + ASTNode& output, + bool pushNeg, ASTNodeMap* VarConstMap=NULL); + void UpdateSimplifyMap(const ASTNode& key, + const ASTNode& value, + bool pushNeg, ASTNodeMap* VarConstMap=NULL); + 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); + + void ResetSimplifyMaps(void); + + /**************************************************************** + * Simplification functions * + ****************************************************************/ + + ASTNode SimplifyFormula_TopLevel(const ASTNode& a, + bool pushNeg, + ASTNodeMap* VarConstMap=NULL); + + ASTNode SimplifyTerm_TopLevel(const ASTNode& b); + + + ASTNode SimplifyFormula(const ASTNode& a, + bool pushNeg, + ASTNodeMap* VarConstMap=NULL); + + ASTNode SimplifyTerm(const ASTNode& inputterm, + ASTNodeMap* VarConstMap=NULL); + + + ASTNode SimplifyFormula_NoRemoveWrites(const ASTNode& a, + bool pushNeg, + ASTNodeMap* VarConstMap=NULL); + + void CheckSimplifyInvariant(const ASTNode& a, + const ASTNode& output); + + void BuildReferenceCountMap(const ASTNode& b); + + ASTNode SimplifyAtomicFormula(const ASTNode& a, + bool pushNeg, + ASTNodeMap* VarConstMap=NULL); + + ASTNode CreateSimplifiedEQ(const ASTNode& t1, + const ASTNode& t2); + + ASTNode ITEOpt_InEqs(const ASTNode& in1, + ASTNodeMap* VarConstMap=NULL); + + ASTNode PullUpITE(const ASTNode& in); + + ASTNode RemoveContradictionsFromAND(const ASTNode& in); + + ASTNode CreateSimplifiedTermITE(const ASTNode& t1, + const ASTNode& t2, + const ASTNode& t3); + + ASTNode CreateSimplifiedFormulaITE(const ASTNode& in0, + const ASTNode& in1, + const ASTNode& in2); + + ASTNode CreateSimplifiedINEQ(Kind k, + const ASTNode& a0, + const ASTNode& a1, bool pushNeg); + + ASTNode SimplifyNotFormula(const ASTNode& a, + bool pushNeg, ASTNodeMap* VarConstMap=NULL); + + ASTNode SimplifyAndOrFormula(const ASTNode& a, + bool pushNeg, ASTNodeMap* VarConstMap=NULL); + + ASTNode SimplifyXorFormula(const ASTNode& a, + bool pushNeg, ASTNodeMap* VarConstMap=NULL); + + ASTNode SimplifyNandFormula(const ASTNode& a, + bool pushNeg, ASTNodeMap* VarConstMap=NULL); + + ASTNode SimplifyNorFormula(const ASTNode& a, + bool pushNeg, ASTNodeMap* VarConstMap=NULL); + + ASTNode SimplifyImpliesFormula(const ASTNode& a, + bool pushNeg, ASTNodeMap* VarConstMap=NULL); + + ASTNode SimplifyIffFormula(const ASTNode& a, + bool pushNeg, ASTNodeMap* VarConstMap=NULL); + + ASTNode SimplifyIteFormula(const ASTNode& a, + bool pushNeg, ASTNodeMap* VarConstMap=NULL); + + ASTNode SimplifyForFormula(const ASTNode& a, + bool pushNeg, ASTNodeMap* VarConstMap=NULL); + + ASTNode Flatten(const ASTNode& a); + + 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); + + //accepts constant term and simplifies it to a bvconst + ASTNode BVConstEvaluator(const ASTNode& t); + + + //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); + + //Replaces WRITE(Arr,i,val) with ITE(j=i, val, READ(Arr,j)) + ASTNode RemoveWrites_TopLevel(const ASTNode& term); + ASTNode RemoveWrites(const ASTNode& term); + ASTNode SimplifyWrites_InPlace(const ASTNode& term, + ASTNodeMap* VarConstMap=NULL); + ASTNode ReadOverWrite_To_ITE(const ASTNode& term, + ASTNodeMap* VarConstMap=NULL); + + void printCacheStatus(); + + //FIXME: Get rid of this horrible function + const ASTNodeMap * ReadOverWriteMap() + { + return ReadOverWrite_NewName_Map; + } // End of ReadOverWriteMap() + + const ASTNodeMap * Return_SolverMap() + { + return SolverMap; + } // End of SolverMap() + + };//end of class Simplifier +}; //end of namespace +#endif diff --git a/src/to-sat/CallSAT.cpp b/src/to-sat/CallSAT.cpp new file mode 100644 index 0000000..3018db8 --- /dev/null +++ b/src/to-sat/CallSAT.cpp @@ -0,0 +1,91 @@ +// -*- c++ -*- +/******************************************************************** + * AUTHORS: Vijay Ganesh + * + * BEGIN DATE: November, 2005 + * + * LICENSE: Please view LICENSE file in the home dir of this Program + ********************************************************************/ + +#include "ToSAT.h" + +namespace BEEV +{ + //Call the SAT solver, and check the result before returning. This + //can return one of 3 values, SOLVER_VALID, SOLVER_INVALID or + //SOLVER_UNDECIDED + bool ToSAT::CallSAT(MINISAT::Solver& SatSolver, + const ASTNode& modified_input, + const ASTNode& original_input) + { + bm->GetRunTimes()->start(RunTimes::BitBlasting); + BitBlaster BB(bm); + ASTNode BBFormula = BB.BBForm(modified_input); + bm->GetRunTimes()->stop(RunTimes::BitBlasting); + + CNFMgr* cm = new CNFMgr(bm); + ClauseList* cl = cm->convertToCNF(BBFormula); + if (stats_flag) + { + cerr << "Number of clauses:" << cl->size() << endl; + } + //PrintClauseList(cout, *cl); + bool sat = toSATandSolve(SatSolver, *cl); + cm->DELETE(cl); + delete cm; + return sat; + } + + //################################################## + //################################################## + + /******************************************************************* + * Helper Functions + *******************************************************************/ + + //This function prints the output of the STP solver + void ToSAT::PrintOutput(SOLVER_RETURN_TYPE ret) + { + bool true_iff_valid = (SOLVER_VALID == ret); + + if (print_output_flag) + { + if (smtlib_parser_flag) + { + if (true_iff_valid && + (input_status == TO_BE_SATISFIABLE)) + { + cerr << "Warning. Expected satisfiable, FOUND unsatisfiable" << endl; + } + else if (!true_iff_valid && + (input_status == TO_BE_UNSATISFIABLE)) + { + cerr << "Warning. Expected unsatisfiable, FOUND satisfiable" << endl; + } + } + } + + if (true_iff_valid) + { + bm->ValidFlag = true; + if (print_output_flag) + { + if (smtlib_parser_flag) + cout << "unsat\n"; + else + cout << "Valid.\n"; + } + } + else + { + bm->ValidFlag = false; + if (print_output_flag) + { + if (smtlib_parser_flag) + cout << "sat\n"; + else + cout << "Invalid.\n"; + } + } + } //end of PrintOutput() +};//end of namespace diff --git a/src/to-sat/ToCNF.cpp b/src/to-sat/ToCNF.cpp index 1770e2f..bfcb9a8 100644 --- a/src/to-sat/ToCNF.cpp +++ b/src/to-sat/ToCNF.cpp @@ -1678,7 +1678,7 @@ namespace BEEV ClauseList* CNFMgr::convertToCNF(const ASTNode& varphi) { - varphi.GetBeevMgr()->runTimes.start(RunTimes::CNFConversion); + varphi.GetBeevMgr()->GetRunTimes()->start(RunTimes::CNFConversion); scanFormula(varphi, true); ASTNode dummy_true_var = bm->CreateSymbol("*TrueDummy*"); ClauseList* defs = SINGLETON(dummy_true_var); @@ -1687,7 +1687,7 @@ namespace BEEV defs->insert(defs->begin() + 1, top->begin(), top->end()); cleanup(varphi); - varphi.GetBeevMgr()->runTimes.stop(RunTimes::CNFConversion); + varphi.GetBeevMgr()->GetRunTimes()->stop(RunTimes::CNFConversion); return defs; }//End of convertToCNF() diff --git a/src/to-sat/ToCNF.h b/src/to-sat/ToCNF.h index be1fb23..630dc74 100644 --- a/src/to-sat/ToCNF.h +++ b/src/to-sat/ToCNF.h @@ -257,7 +257,6 @@ namespace BEEV // constructor CNFMgr(BeevMgr *bmgr); - //######################################## //######################################## // destructor diff --git a/src/to-sat/ToSAT.cpp b/src/to-sat/ToSAT.cpp index 4f6618c..458581e 100644 --- a/src/to-sat/ToSAT.cpp +++ b/src/to-sat/ToSAT.cpp @@ -6,14 +6,7 @@ * * LICENSE: Please view LICENSE file in the home dir of this Program ********************************************************************/ -#include -#include "../AST/AST.h" -#include "../STPManager/STPManager.h" -#include "../simplifier/bvsolver.h" -#include "../sat/sat.h" -#include "../AST/RunTimes.h" -#include "BitBlast.h" -#include "ToCNF.h" +#include "ToSAT.h" namespace BEEV { @@ -21,7 +14,8 @@ namespace BEEV * lookup or create new MINISAT Vars from the global MAP * _ASTNode_to_SATVar. */ - MINISAT::Var BeevMgr::LookupOrCreateSATVar(MINISAT::Solver& newS, const ASTNode& n) + MINISAT::Var + ToSAT::LookupOrCreateSATVar(MINISAT::Solver& newS, const ASTNode& n) { ASTtoSATMap::iterator it; MINISAT::Var v; @@ -51,13 +45,13 @@ namespace BEEV */ // FIXME: Still need to deal with TRUE/FALSE in clauses! // - //bool BeevMgr::toSATandSolve(MINISAT::Solver& newS, + //bool ToSAT::toSATandSolve(MINISAT::Solver& newS, //ClauseList& cll, ASTNodeToIntMap& heuristic) - bool BeevMgr::toSATandSolve(MINISAT::Solver& newS, ClauseList& cll) + bool ToSAT::toSATandSolve(MINISAT::Solver& newS, ClauseList& cll) { CountersAndStats("SAT Solver"); - runTimes.start(RunTimes::SendingToSAT); + bm->GetRunTimes()->start(RunTimes::SendingToSAT); //iterate through the list (conjunction) of ASTclauses cll ClauseList::const_iterator i = cll.begin(), iend = cll.end(); @@ -109,18 +103,18 @@ namespace BEEV } else { - PrintStats(newS); - runTimes.stop(RunTimes::SendingToSAT); + bm->PrintStats(newS); + bm->GetRunTimes()->stop(RunTimes::SendingToSAT); return false; } } - runTimes.stop(RunTimes::SendingToSAT); + bm->GetRunTimes()->stop(RunTimes::SendingToSAT); // if input is UNSAT return false, else return true if (!newS.simplify()) { - PrintStats(newS); + bm->PrintStats(newS); return false; } @@ -129,13 +123,13 @@ namespace BEEV //PrintActivityLevels_Of_SATVars("Before SAT and after initial bias:",newS); //newS.solve(); - runTimes.start(RunTimes::Solving); + bm->GetRunTimes()->start(RunTimes::Solving); newS.solve(); - runTimes.stop(RunTimes::Solving); + bm->GetRunTimes()->stop(RunTimes::Solving); //PrintActivityLevels_Of_SATVars("After SAT",newS); - PrintStats(newS); + bm->PrintStats(newS); if (newS.okay()) return true; else @@ -144,7 +138,7 @@ namespace BEEV // 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) + ASTNode ToSAT::SymbolTruthValue(MINISAT::Solver &newS, ASTNode form) { MINISAT::Var satvar = _ASTNode_to_SATVar[form]; if (newS.model[satvar] == MINISAT::l_True) @@ -158,15 +152,15 @@ namespace BEEV } } - // 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) + // 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 ToSAT::CheckBBandCNF(MINISAT::Solver& newS, ASTNode form) { // Clear memo table (in case newS has changed). CheckBBandCNFMemo.clear(); @@ -174,12 +168,11 @@ namespace BEEV return CheckBBandCNF_int(newS, form); } //End of CheckBBandCNF() - // 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) + // 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 ToSAT::CheckBBandCNF_int(MINISAT::Solver& newS, ASTNode form) { - // cout << "++++++++++++++++" << endl << "CheckBBandCNF_int form = " << // form << endl; @@ -225,7 +218,7 @@ namespace BEEV { eval_children.push_back(CheckBBandCNF_int(newS, *it)); } - result = CreateSimpForm(k, eval_children); + result = bm->CreateSimpForm(k, eval_children); cout << "================" << endl << "Checking BB formula:" << form << endl; cout << "----------------" << endl << "Result:" << result << endl; @@ -244,7 +237,7 @@ namespace BEEV else { // It's (NOT sym). Get value of sym and complement. - replit_eval = CreateSimpNot(SymbolTruthValue(newS, replit[0])); + replit_eval = bm->CreateSimpNot(SymbolTruthValue(newS, replit[0])); } cout << "----------------" << endl << "Rep lit: " << replit << endl; @@ -266,935 +259,4 @@ namespace BEEV return (CheckBBandCNFMemo[form] = result); } //end of CheckBBandCNF_int() - - /*FUNCTION: constructs counterexample from MINISAT counterexample - * step1 : iterate through MINISAT counterexample and assemble the - * bits for each AST term. Store it in a map from ASTNode to vector - * of bools (bits). - * - * step2: Iterate over the map from ASTNodes->Vector-of-Bools and - * populate the CounterExampleMap data structure (ASTNode -> BVConst) - */ - void BeevMgr::ConstructCounterExample(MINISAT::Solver& newS) - { - //iterate over MINISAT counterexample and construct a map from AST - //terms to vector of bools. We need this iteration step because - //MINISAT might return the various bits of a term out of - //order. Therfore, we need to collect all the bits and assemble - //them properly - - if (!newS.okay()) - return; - if (!construct_counterexample_flag) - return; - - CopySolverMap_To_CounterExample(); - for (int i = 0; i < newS.nVars(); i++) - { - //Make sure that the MINISAT::Var is defined - if (newS.model[i] != MINISAT::l_Undef) - { - - //mapping from MINISAT::Vars to ASTNodes. We do not need to - //print MINISAT vars or CNF vars. - ASTNode s = _SATVar_to_AST[i]; - - //assemble the counterexample here - if (s.GetKind() == BVGETBIT && s[0].GetKind() == SYMBOL) - { - ASTNode symbol = s[0]; - unsigned int symbolWidth = symbol.GetValueWidth(); - - //'v' is the map from bit-index to bit-value - hash_map * v; - if (_ASTNode_to_Bitvector.find(symbol) == _ASTNode_to_Bitvector.end()) - _ASTNode_to_Bitvector[symbol] = new hash_map (symbolWidth); - - //v holds the map from bit-index to bit-value - v = _ASTNode_to_Bitvector[symbol]; - - //kk is the index of BVGETBIT - unsigned int kk = GetUnsignedConst(s[1]); - - //Collect the bits of 'symbol' and store in v. Store in reverse order. - if (newS.model[i] == MINISAT::l_True) - (*v)[(symbolWidth - 1) - kk] = true; - else - (*v)[(symbolWidth - 1) - kk] = false; - } - else - { - if (s.GetKind() == SYMBOL && s.GetType() == BOOLEAN_TYPE) - { - const char * zz = s.GetName(); - //if the variables are not cnf variables then add them to the counterexample - if (0 != strncmp("cnf", zz, 3) && 0 != strcmp("*TrueDummy*", zz)) - { - if (newS.model[i] == MINISAT::l_True) - CounterExampleMap[s] = ASTTrue; - else if (newS.model[i] == MINISAT::l_False) - CounterExampleMap[s] = ASTFalse; - else - { - int seed = 10000; - srand(seed); - CounterExampleMap[s] = (rand() > seed) ? ASTFalse : ASTTrue; - } - } - } - } - } - } - - //iterate over the ASTNode_to_Bitvector data-struct and construct - //the the aggregate value of the bitvector, and populate the - //CounterExampleMap datastructure - for (ASTtoBitvectorMap::iterator it = _ASTNode_to_Bitvector.begin(), itend = _ASTNode_to_Bitvector.end(); it != itend; it++) - { - ASTNode var = it->first; - //debugging - //cerr << var; - if (SYMBOL != var.GetKind()) - FatalError("ConstructCounterExample: error while constructing counterexample: not a variable: ", var); - - //construct the bitvector value - hash_map * w = it->second; - ASTNode value = BoolVectoBVConst(w, var.GetValueWidth()); - //debugging - //cerr << value; - - //populate the counterexample datastructure. add only scalars - //variables which were declared in the input and newly - //introduced variables for array reads - CounterExampleMap[var] = value; - } - - //In this loop, we compute the value of each array read, the - //corresponding ITE against the counterexample generated above. - for (ASTNodeMap::iterator it = _arrayread_ite.begin(), itend = _arrayread_ite.end(); it != itend; it++) - { - //the array read - ASTNode arrayread = it->first; - ASTNode value_ite = _arrayread_ite[arrayread]; - - //convert it to a constant array-read and store it in the - //counter-example. First convert the index into a constant. then - //construct the appropriate array-read and store it in the - //counterexample - ASTNode arrayread_index = TermToConstTermUsingModel(arrayread[1]); - ASTNode key = CreateTerm(READ, arrayread.GetValueWidth(), arrayread[0], arrayread_index); - - //Get the ITE corresponding to the array-read and convert it - //to a constant against the model - ASTNode value = TermToConstTermUsingModel(value_ite); - //save the result in the counter_example - if (!CheckSubstitutionMap(key)) - CounterExampleMap[key] = value; - } - } //End of ConstructCounterExample - - - // FUNCTION: accepts a non-constant term, and returns the - // corresponding constant term with respect to a model. - // - // term READ(A,i) is treated as follows: - // - //1. If (the boolean variable 'ArrayReadFlag' is true && ArrayRead - //1. has value in counterexample), then return the value of the - //1. arrayread. - // - //2. If (the boolean variable 'ArrayReadFlag' is true && ArrayRead - //2. doesn't have value in counterexample), then return the - //2. arrayread itself (normalized such that arrayread has a constant - //2. index) - // - //3. If (the boolean variable 'ArrayReadFlag' is false) && ArrayRead - //3. has a value in the counterexample then return the value of the - //3. arrayread. - // - //4. If (the boolean variable 'ArrayReadFlag' is false) && ArrayRead - //4. doesn't have a value in the counterexample then return 0 as the - //4. value of the arrayread. - ASTNode BeevMgr::TermToConstTermUsingModel(const ASTNode& t, bool ArrayReadFlag) - { - Begin_RemoveWrites = false; - SimplifyWrites_InPlace_Flag = false; - //ASTNode term = SimplifyTerm(t); - ASTNode term = t; - Kind k = term.GetKind(); - - //cerr << "Input to TermToConstTermUsingModel: " << term << endl; - if (!is_Term_kind(k)) - { - FatalError("TermToConstTermUsingModel: The input is not a term: ", term); - } - if (k == WRITE) - { - FatalError("TermToConstTermUsingModel: The input has wrong kind: WRITE : ", term); - } - if (k == SYMBOL && BOOLEAN_TYPE == term.GetType()) - { - FatalError("TermToConstTermUsingModel: The input has wrong kind: Propositional variable : ", term); - } - - ASTNodeMap::iterator it1; - if ((it1 = CounterExampleMap.find(term)) != CounterExampleMap.end()) - { - ASTNode val = it1->second; - if (BVCONST != val.GetKind()) - { - //CounterExampleMap has two maps rolled into - //one. SubstitutionMap and SolverMap. - // - //recursion is fine here. There are two maps that are checked - //here. One is the substitutionmap. We garuntee that the value - //of a key in the substitutionmap is always a constant. - // - //in the SolverMap we garuntee that "term" does not occur in - //the value part of the map - if (term == val) - { - FatalError("TermToConstTermUsingModel: The input term is stored as-is " - "in the CounterExample: Not ok: ", term); - } - return TermToConstTermUsingModel(val, ArrayReadFlag); - } - else - { - return val; - } - } - - ASTNode output; - switch (k) - { - case BVCONST: - output = term; - break; - case SYMBOL: - { - if (term.GetType() == ARRAY_TYPE) - { - return term; - } - - //when all else fails set symbol values to some constant by - //default. if the variable is queried the second time then add 1 - //to and return the new value. - ASTNode zero = CreateZeroConst(term.GetValueWidth()); - output = zero; - break; - } - case READ: - { - ASTNode arrName = term[0]; - ASTNode index = term[1]; - if (0 == arrName.GetIndexWidth()) - { - FatalError("TermToConstTermUsingModel: array has 0 index width: ", arrName); - } - - - if (WRITE == arrName.GetKind()) //READ over a WRITE - { - ASTNode wrtterm = Expand_ReadOverWrite_UsingModel(term, ArrayReadFlag); - if (wrtterm == term) - { - FatalError("TermToConstTermUsingModel: Read_Over_Write term must be expanded into an ITE", term); - } - ASTNode rtterm = TermToConstTermUsingModel(wrtterm, ArrayReadFlag); - assert(ArrayReadFlag || (BVCONST == rtterm.GetKind())); - return rtterm; - } - else if (ITE == arrName.GetKind()) //READ over an ITE - { - // The "then" and "else" branch are arrays. - ASTNode indexVal = TermToConstTermUsingModel(index, ArrayReadFlag); - - ASTNode condcompute = ComputeFormulaUsingModel(arrName[0]); // Get the truth value. - if (ASTTrue == condcompute) - { - const ASTNode & result = TermToConstTermUsingModel(CreateTerm(READ, arrName.GetValueWidth(), arrName[1], indexVal), ArrayReadFlag); - assert(ArrayReadFlag || (BVCONST == result.GetKind())); - return result; - } - else if (ASTFalse == condcompute) - { - const ASTNode & result = TermToConstTermUsingModel(CreateTerm(READ, arrName.GetValueWidth(), arrName[2], indexVal), ArrayReadFlag); - assert(ArrayReadFlag || (BVCONST == result.GetKind())); - return result; - } - else - { - cerr << "TermToConstTermUsingModel: termITE: value of conditional is wrong: " << condcompute << endl; - FatalError(" TermToConstTermUsingModel: termITE: cannot compute ITE conditional against model: ", term); - } - FatalError("bn23143 Never Here"); - } - - ASTNode modelentry; - if (CounterExampleMap.find(index) != CounterExampleMap.end()) - { - //index has a const value in the CounterExampleMap - //ASTNode indexVal = CounterExampleMap[index]; - ASTNode indexVal = TermToConstTermUsingModel(CounterExampleMap[index], ArrayReadFlag); - modelentry = CreateTerm(READ, arrName.GetValueWidth(), arrName, indexVal); - } - else - { - //index does not have a const value in the CounterExampleMap. compute it. - ASTNode indexconstval = TermToConstTermUsingModel(index, ArrayReadFlag); - //update model with value of the index - //CounterExampleMap[index] = indexconstval; - modelentry = CreateTerm(READ, arrName.GetValueWidth(), arrName, indexconstval); - } - //modelentry is now an arrayread over a constant index - BVTypeCheck(modelentry); - - //if a value exists in the CounterExampleMap then return it - if (CounterExampleMap.find(modelentry) != CounterExampleMap.end()) - { - output = TermToConstTermUsingModel(CounterExampleMap[modelentry], ArrayReadFlag); - } - else if (ArrayReadFlag) - { - //return the array read over a constantindex - output = modelentry; - } - else - { - //when all else fails set symbol values to some constant by - //default. if the variable is queried the second time then add 1 - //to and return the new value. - ASTNode zero = CreateZeroConst(modelentry.GetValueWidth()); - output = zero; - } - break; - } - case ITE: - { - ASTNode condcompute = ComputeFormulaUsingModel(term[0]); - if (ASTTrue == condcompute) - { - output = TermToConstTermUsingModel(term[1], ArrayReadFlag); - } - else if (ASTFalse == condcompute) - { - output = TermToConstTermUsingModel(term[2], ArrayReadFlag); - } - else - { - cerr << "TermToConstTermUsingModel: termITE: value of conditional is wrong: " << condcompute << endl; - FatalError(" TermToConstTermUsingModel: termITE: cannot compute ITE conditional against model: ", term); - } - break; - } - default: - { - ASTVec c = term.GetChildren(); - ASTVec o; - for (ASTVec::iterator it = c.begin(), itend = c.end(); it != itend; it++) - { - ASTNode ff = TermToConstTermUsingModel(*it, ArrayReadFlag); - o.push_back(ff); - } - output = CreateTerm(k, term.GetValueWidth(), o); - //output is a CONST expression. compute its value and store it - //in the CounterExampleMap - ASTNode oo = BVConstEvaluator(output); - //the return value - output = oo; - break; - } - } - - assert(ArrayReadFlag || (BVCONST == output.GetKind())); - - //when this flag is false, we should compute the arrayread to a - //constant. this constant is stored in the counter_example - //datastructure - if (!ArrayReadFlag) - { - CounterExampleMap[term] = output; - } - - //cerr << "Output to TermToConstTermUsingModel: " << output << endl; - return output; - } //End of TermToConstTermUsingModel - - //Expands read-over-write by evaluating (readIndex=writeIndex) for - //every writeindex until, either it evaluates to TRUE or all - //(readIndex=writeIndex) evaluate to FALSE - ASTNode BeevMgr::Expand_ReadOverWrite_UsingModel(const ASTNode& term, bool arrayread_flag) - { - if (READ != term.GetKind() && WRITE != term[0].GetKind()) - { - FatalError("RemovesWrites: Input must be a READ over a WRITE", term); - } - - ASTNode output; - ASTNodeMap::iterator it1; - if ((it1 = CounterExampleMap.find(term)) != CounterExampleMap.end()) - { - ASTNode val = it1->second; - if (BVCONST != val.GetKind()) - { - //recursion is fine here. There are two maps that are checked - //here. One is the substitutionmap. We garuntee that the value - //of a key in the substitutionmap is always a constant. - if (term == val) - { - FatalError("TermToConstTermUsingModel: The input term is stored as-is " - "in the CounterExample: Not ok: ", term); - } - return TermToConstTermUsingModel(val, arrayread_flag); - } - else - { - return val; - } - } - - unsigned int width = term.GetValueWidth(); - ASTNode writeA = ASTTrue; - ASTNode newRead = term; - ASTNode readIndex = TermToConstTermUsingModel(newRead[1], false); - //iteratively expand read-over-write, and evaluate against the - //model at every iteration - do - { - ASTNode write = newRead[0]; - writeA = write[0]; - ASTNode writeIndex = TermToConstTermUsingModel(write[1], false); - ASTNode writeVal = TermToConstTermUsingModel(write[2], false); - - ASTNode cond = - ComputeFormulaUsingModel(CreateSimplifiedEQ(writeIndex, readIndex)); - if (ASTTrue == cond) - { - //found the write-value. return it - output = writeVal; - CounterExampleMap[term] = output; - return output; - } - - newRead = CreateTerm(READ, width, writeA, readIndex); - } while (READ == newRead.GetKind() && WRITE == newRead[0].GetKind()); - - output = TermToConstTermUsingModel(newRead, arrayread_flag); - - //memoize - CounterExampleMap[term] = output; - return output; - } //Exand_ReadOverWrite_To_ITE_UsingModel() - - /* FUNCTION: accepts a non-constant formula, and checks if the - * formula is ASTTrue or ASTFalse w.r.t to a model - */ - ASTNode BeevMgr::ComputeFormulaUsingModel(const ASTNode& form) - { - ASTNode in = form; - Kind k = form.GetKind(); - if (!(is_Form_kind(k) && BOOLEAN_TYPE == form.GetType())) - { - FatalError(" ComputeConstFormUsingModel: The input is a non-formula: ", form); - } - - //cerr << "Input to ComputeFormulaUsingModel:" << form << endl; - ASTNodeMap::iterator it1; - if ((it1 = ComputeFormulaMap.find(form)) != ComputeFormulaMap.end()) - { - ASTNode res = it1->second; - if (ASTTrue == res || ASTFalse == res) - { - return res; - } - else - { - FatalError("ComputeFormulaUsingModel: The value of a formula must be TRUE or FALSE:", form); - } - } - - ASTNode t0, t1; - ASTNode output = ASTFalse; - switch (k) - { - case TRUE: - case FALSE: - output = form; - break; - case SYMBOL: - if (BOOLEAN_TYPE != form.GetType()) - FatalError(" ComputeFormulaUsingModel: Non-Boolean variables are not formulas", form); - if (CounterExampleMap.find(form) != CounterExampleMap.end()) - { - ASTNode counterexample_val = CounterExampleMap[form]; - if (!VarSeenInTerm(form, counterexample_val)) - { - output = ComputeFormulaUsingModel(counterexample_val); - } - else - { - output = counterexample_val; - } - } - else - { - CounterExampleMap[form] = ASTFalse; - output = ASTFalse; - } - break; - case EQ: - 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; - case PARAMBOOL: - output = NewBooleanVar(form[0],form[1]); - output = ComputeFormulaUsingModel(output); - break; - case FOR: - output = Check_FiniteLoop_UsingModel(form); - break; - default: - FatalError(" ComputeFormulaUsingModel: "\ - "the kind has not been implemented", ASTUndefined); - break; - } - - //cout << "ComputeFormulaUsingModel output is:" << output << endl; - ComputeFormulaMap[form] = output; - return output; - } - - void BeevMgr::CheckCounterExample(bool t) - { - // FIXME: Code is more useful if enable flags are check OUTSIDE the method. - // If I want to check a counterexample somewhere, I don't want to have to set - // the flag in order to make it actualy happen! - - printf("checking counterexample\n"); - if (!check_counterexample_flag) - { - return; - } - - //input is valid, no counterexample to check - if (ValidFlag) - return; - - //t is true if SAT solver generated a counterexample, else it is false - if (!t) - FatalError("CheckCounterExample: No CounterExample to check", ASTUndefined); - const ASTVec c = GetAsserts(); - for (ASTVec::const_iterator it = c.begin(), itend = c.end(); it != itend; it++) - if (ASTFalse == ComputeFormulaUsingModel(*it)) - FatalError("CheckCounterExample:counterexample bogus:" - "assert evaluates to FALSE under counterexample: NOT OK", *it); - - if (ASTTrue == ComputeFormulaUsingModel(_current_query)) - FatalError("CheckCounterExample:counterexample bogus:" - "query evaluates to TRUE under counterexample: NOT OK", _current_query); - } - - /* FUNCTION: 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 - - //################################################## - //################################################## - - //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 UNDECIDED - SOLVER_RETURN_TYPE BeevMgr::TopLevelSATAux(const ASTNode& inputasserts) - { - ASTNode inputToSAT = inputasserts; - ASTNode orig_input = inputToSAT; - ASTNodeStats("input asserts and query: ", inputToSAT); - - ASTNode simplified_solved_InputToSAT = inputToSAT; - //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 = new BVSolver(this); - SimplifyWrites_InPlace_Flag = false; - Begin_RemoveWrites = false; - start_abstracting = false; - TermsAlreadySeenMap.clear(); - do - { - inputToSAT = simplified_solved_InputToSAT; - - if(optimize_flag) - { - - runTimes.start(RunTimes::CreateSubstitutionMap); - simplified_solved_InputToSAT = - CreateSubstitutionMap(simplified_solved_InputToSAT); - runTimes.stop(RunTimes::CreateSubstitutionMap); - //printf("##################################################\n"); - ASTNodeStats("after pure substitution: ", simplified_solved_InputToSAT); - - - simplified_solved_InputToSAT = - SimplifyFormula_TopLevel(simplified_solved_InputToSAT, false); - - ASTNodeStats("after simplification: ", simplified_solved_InputToSAT); - } - - if(wordlevel_solve_flag) - { - simplified_solved_InputToSAT = - bvsolver->TopLevelBVSolve(simplified_solved_InputToSAT); - ASTNodeStats("after solving: ", simplified_solved_InputToSAT); - } - - } - while (inputToSAT != simplified_solved_InputToSAT); - - ASTNodeStats("Before SimplifyWrites_Inplace begins: ", - simplified_solved_InputToSAT); - - SimplifyWrites_InPlace_Flag = true; - Begin_RemoveWrites = false; - start_abstracting = false; - TermsAlreadySeenMap.clear(); - do - { - inputToSAT = simplified_solved_InputToSAT; - - if(optimize_flag) - { - runTimes.start(RunTimes::CreateSubstitutionMap); - simplified_solved_InputToSAT = - CreateSubstitutionMap(simplified_solved_InputToSAT); - runTimes.stop(RunTimes::CreateSubstitutionMap); - ASTNodeStats("after pure substitution: ", simplified_solved_InputToSAT); - - simplified_solved_InputToSAT = - SimplifyFormula_TopLevel(simplified_solved_InputToSAT, false); - ASTNodeStats("after simplification: ", simplified_solved_InputToSAT); - } - - if(wordlevel_solve_flag) - { - simplified_solved_InputToSAT = - bvsolver->TopLevelBVSolve(simplified_solved_InputToSAT); - ASTNodeStats("after solving: ", simplified_solved_InputToSAT); - } - } while (inputToSAT != simplified_solved_InputToSAT); - - ASTNodeStats("After SimplifyWrites_Inplace: ", simplified_solved_InputToSAT); - delete bvsolver; - bvsolver = NULL; - - start_abstracting = (arraywrite_refinement_flag) ? true : false; - SimplifyWrites_InPlace_Flag = false; - Begin_RemoveWrites = (start_abstracting) ? false : true; - if (start_abstracting) - { - ASTNodeStats("before abstraction round begins: ", simplified_solved_InputToSAT); - } - - TermsAlreadySeenMap.clear(); - if (start_abstracting) - { - ASTNodeStats("After abstraction: ", simplified_solved_InputToSAT); - } - start_abstracting = false; - SimplifyWrites_InPlace_Flag = false; - Begin_RemoveWrites = false; - - simplified_solved_InputToSAT = - TransformFormula_TopLevel(simplified_solved_InputToSAT); - ASTNodeStats("after transformation: ", simplified_solved_InputToSAT); - TermsAlreadySeenMap.clear(); - - SOLVER_RETURN_TYPE res; - //solver instantiated here - MINISAT::Solver newS; - //MINISAT::SimpSolver newS; - //MINISAT::UnsoundSimpSolver newS; - if (arrayread_refinement_flag) - { - counterexample_checking_during_refinement = true; - } - - res = CallSAT_ResultCheck(newS, simplified_solved_InputToSAT, orig_input); - if (SOLVER_UNDECIDED != res) - { - CountersAndStats("print_func_stats"); - return res; - } - - // res = SATBased_AllFiniteLoops_Refinement(newS, orig_input); - // if (SOLVER_UNDECIDED != res) - // { - // CountersAndStats("print_func_stats"); - // return res; - // } - - res = SATBased_ArrayReadRefinement(newS, simplified_solved_InputToSAT, orig_input); - if (SOLVER_UNDECIDED != res) - { - CountersAndStats("print_func_stats"); - return res; - } - - res = SATBased_ArrayWriteRefinement(newS, orig_input); - if (SOLVER_UNDECIDED != res) - { - CountersAndStats("print_func_stats"); - return res; - } - - res = SATBased_ArrayReadRefinement(newS, simplified_solved_InputToSAT, orig_input); - if (SOLVER_UNDECIDED != res) - { - CountersAndStats("print_func_stats"); - return res; - } - - FatalError("TopLevelSATAux: reached the end without proper conclusion:" - "either a divide by zero in the input or a bug in STP"); - //bogus return to make the compiler shut up - return SOLVER_ERROR; - } //End of TopLevelSATAux - - /******************************************************************* - * Helper Functions - *******************************************************************/ - //FUNCTION: this function accepts a boolvector and returns a BVConst - ASTNode BeevMgr::BoolVectoBVConst(hash_map * 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); - } //end of BoolVectoBVConst() - - - //Call the SAT solver, and check the result before returning. This - //can return one of 3 values, SOLVER_VALID, SOLVER_INVALID or SOLVER_UNDECIDED - SOLVER_RETURN_TYPE BeevMgr::CallSAT_ResultCheck(MINISAT::Solver& SatSolver, - const ASTNode& modified_input, - const ASTNode& original_input) - { - runTimes.start(RunTimes::BitBlasting); - BitBlaster BB(this); - ASTNode BBFormula = BB.BBForm(modified_input); - runTimes.stop(RunTimes::BitBlasting); - - CNFMgr* cm = new CNFMgr(this); - ClauseList* cl = cm->convertToCNF(BBFormula); - if (stats_flag) - { - cerr << "Number of clauses:" << cl->size() << endl; - } - //PrintClauseList(cout, *cl); - bool sat = toSATandSolve(SatSolver, *cl); - cm->DELETE(cl); - delete cm; - - if (!sat) - { - //PrintOutput(true); - return SOLVER_VALID; - } - else if (SatSolver.okay()) - { - CounterExampleMap.clear(); - ConstructCounterExample(SatSolver); - if (stats_flag && print_nodes_flag) - { - PrintSATModel(SatSolver); - } - //check if the counterexample is good or not - ComputeFormulaMap.clear(); - if (counterexample_checking_during_refinement) - bvdiv_exception_occured = false; - ASTNode orig_result = ComputeFormulaUsingModel(original_input); - if (!(ASTTrue == orig_result || ASTFalse == orig_result)) - FatalError("TopLevelSat: Original input must compute to "\ - "true or false against model"); - - // if the counterexample is indeed a good one, then return - // invalid - if (ASTTrue == orig_result) - { - //CheckCounterExample(SatSolver.okay()); - //PrintOutput(false); - PrintCounterExample(SatSolver.okay()); - PrintCounterExample_InOrder(SatSolver.okay()); - return SOLVER_INVALID; - } - // counterexample is bogus: flag it - else - { - if (stats_flag && print_nodes_flag) - { - cout << "Supposedly bogus one: \n"; - bool tmp = print_counterexample_flag; - print_counterexample_flag = true; - PrintCounterExample(true); - print_counterexample_flag = tmp; - } - - return SOLVER_UNDECIDED; - } - } - else - { - //Control should never reach here - //PrintOutput(true); - return SOLVER_ERROR; - } - } //end of CALLSAT_ResultCheck() - - SOLVER_RETURN_TYPE BeevMgr::TopLevelSAT(const ASTNode& inputasserts, - const ASTNode& query) - { - - ASTNode q = CreateNode(AND, inputasserts, CreateNode(NOT, query)); - return TopLevelSATAux(q); - } //End of TopLevelSAT() }; //end of namespace BEEV diff --git a/src/to-sat/ToSAT.h b/src/to-sat/ToSAT.h new file mode 100644 index 0000000..203eb7c --- /dev/null +++ b/src/to-sat/ToSAT.h @@ -0,0 +1,123 @@ +// -*- c++ -*- +/******************************************************************** + * AUTHORS: Vijay Ganesh + * + * BEGIN DATE: November, 2005 + * + * LICENSE: Please view LICENSE file in the home dir of this Program + ********************************************************************/ + +#ifndef TOSAT_H +#define TOSAT_H +#include + +#include "BitBlast.h" +#include "ToCNF.h" + +#include "../AST/AST.h" +#include "../sat/sat.h" +#include "../AST/RunTimes.h" +#include "../simplifier/bvsolver.h" +#include "../STPManager/STPManager.h" +#include "../simplifier/simplifier.h" + +namespace BEEV +{ + class ToSAT { + private: + /**************************************************************** + * Private Typedefs and Data * + ****************************************************************/ + + // 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; + + // MAP: This is a map from MINISAT::Vars to ASTNodes + // + // Reverse map used in building counterexamples. MINISAT returns a + // model in terms of MINISAT Vars, and this map helps us convert + // it to a model over ASTNode variables. + vector _SATVar_to_AST; + + // Ptr to STPManager + BeevMgr * bm; + + // Ptr to Simplifier + Simplifier * simp; + + // Memo table to check the functioning of bitblaster and CNF + // converter + ASTNodeMap CheckBBandCNFMemo; + + // Map from formulas to representative literals, for debugging. + ASTNodeMap RepLitMap; + + ASTNode ASTTrue, ASTFalse, ASTUndefined; + + /**************************************************************** + * Private Member Functions * + ****************************************************************/ + + //looksup a MINISAT var from the minisat-var memo-table. if none + //exists, then creates one. Treat the result as const. + MINISAT::Var LookupOrCreateSATVar(MINISAT::Solver& S, + const ASTNode& n); + + // Evaluates bitblasted formula in satisfying assignment + ASTNode CheckBBandCNF(MINISAT::Solver& newS, ASTNode form); + ASTNode CheckBBandCNF_int(MINISAT::Solver& newS, ASTNode form); + + // Looks up truth value of ASTNode SYMBOL in MINISAT satisfying + // assignment. Returns ASTTrue if true, ASTFalse if false or + // undefined. + ASTNode SymbolTruthValue(MINISAT::Solver &newS, ASTNode form); + + public: + /**************************************************************** + * Public Member Functions * + ****************************************************************/ + + // Constructor + ToSAT(BeevMgr * bm, Simplifier * s) : + bm(bm), simp(s) + { + ASTTrue = bm->CreateNode(TRUE); + ASTFalse = bm->CreateNode(FALSE); + ASTUndefined = bm->CreateNode(UNDEFINED); + } + + // Bitblasts, CNF conversion and calls toSATandSolve() + bool CallSAT(MINISAT::Solver& SatSolver, + const ASTNode& modified_input, + const ASTNode& original_input); + + // Converts the clause to SAT and calls SAT solver + bool toSATandSolve(MINISAT::Solver& S, ClauseList& cll); + + // Calls SAT simplifier, array transformer (abstraction + // refinement), bitvector solver, and SAT solver. Returns the + // answer to the input query + SOLVER_RETURN_TYPE TopLevelSATAux(const ASTNode& query); + + //print the STP solver output + void PrintOutput(SOLVER_RETURN_TYPE ret); + + ASTNode SATVar_to_ASTMap(int i) + { + return _SATVar_to_AST[i]; + } + + }; //end of class ToSAT +}; //end of namespace + +#endif -- 2.47.3