$(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/
$(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
$(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/
$(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
#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"
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,
ASTNode,
ASTNode::ASTNodeHasher,
ASTNode::ASTNodeEqual> ASTNodeMultiSet;
-
+
+ typedef hash_map<
+ ASTNode,
+ ASTVec,
+ ASTNode::ASTNodeHasher,
+ ASTNode::ASTNodeEqual> ASTNodeToVecMap;
+
// Datatype for clauses
typedef vector<const ASTNode*>* ClausePtr;
********************************************************************/
#include "AST.h"
-#include "../STPManager/STPManager.h"
+#include "../STPManager/STP.h"
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()
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
//CBV is actually an unsigned*. The bitvector constant is
//represented using an external library in extlib-bvconst.
CBV _bvconst;
-
+
/****************************************************************
* Class ASTBVConstHasher: *
* *
public:
size_t operator()(const ASTBVConst * bvc) const;
}; //End of class ASTBVConstHahser
-
+
/****************************************************************
* Class ASTBVConstEqual: *
* *
bool operator()(const ASTBVConst * bvc1,
const ASTBVConst * bvc2) const;
}; //End of class ASTBVConstEqual
-
+
/****************************************************************
* Private Functions (virtual defs and friends) *
****************************************************************/
// Return the bvconst. It is a const-value
CBV GetBVConst() const;
- }; //End of ASTBVConst
+ }; //End of ASTBVConst
};//end of namespace
#endif
********************************************************************/
#include "AST.h"
-#include "../STPManager/STPManager.h"
+#include "../STPManager/STP.h"
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()
********************************************************************/
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 <class E, class T>
+ struct enumeration
+ {
+ typedef T type;
+ typedef E enum_type;
+
+ enumeration() : e_(E())
+ {}
+
+ enumeration(E e) : e_(static_cast<T>(e))
+ {}
+
+ operator E() const
+ { return static_cast<E>(e_); }
+
+ private:
+ T e_;
+ }; //end of Enumeration struct
+
/******************************************************************
* Class ASTInternal: *
* *
********************************************************************/
#include "AST.h"
-#include "../STPManager/STPManager.h"
+#include "../STPManager/STP.h"
+
/********************************************************************
* This file gives the class definitions of the ASTNode class *
********************************************************************/
_int_node_ptr(in)
{
if (in)
- in->IncRef();
+ {
+ in->IncRef();
+ }
} //End of Constructor
// Copy constructor. Maintain _ref_count
BeevMgr* ASTNode::GetBeevMgr() const
{
- return GlobalBeevMgr;
+ return GlobalSTP->bm;
} //End of GetBeevMgr()
// Checks if the node has alreadybeen printed or not
return (n1._int_node_ptr == n2._int_node_ptr);
}
}; //End of ASTNodeEqual
+
}; //End of Class ASTNode
}; //end of namespace
#endif
********************************************************************/
#include "AST.h"
-#include "../STPManager/STPManager.h"
+#include "../STPManager/STP.h"
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<string> h;
-#else
- hash<char*> 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
#ifndef ASTSYMBOL_H
#define ASTSYMBOL_H
+
namespace BEEV
{
+ unsigned long hash(unsigned char *str);
+
/******************************************************************
* Class ASTSymbol: *
* *
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<string> h;
+#else
+ //hash<char *> 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
/****************************************************************
{
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)
{
****************************************************************/
// Default constructor
- ASTSymbol() : ASTInternal(), _name(NULL)
+ ASTSymbol() :
+ ASTInternal(), _name(NULL)
{
}
ASTSymbol(const char * const name) :
ASTInternal(SYMBOL), _name(name)
{
+ //printf("inside ASTSymbol constructor %s\n", _name);
}
// Destructor (does nothing, but is declared virtual here.
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
--- /dev/null
+// -*- 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
* 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 <cstdlib>
-#include <cstdio>
-#include <cassert>
-#include <iostream>
-#include <sstream>
-#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);
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];
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);
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.
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())
{
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);
}//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();
}
}//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();
{
ASTNode term1 = TransformTerm(simpleForm[0]);
ASTNode term2 = TransformTerm(simpleForm[1]);
- result = bm->CreateSimplifiedEQ(term1, term2);
+ result = simp->CreateSimplifiedEQ(term1, term2);
break;
}
case AND:
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;
}
//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
{
} //End of TransformFormula
- ASTNode TransformTerm(const ASTNode& inputterm)
+ ASTNode ArrayTransformer::TransformTerm(const ASTNode& inputterm)
{
assert(TransformMap != NULL);
FatalError("TransformTerm: this kind is not supported", term);
break;
case READ:
- result = bm->TransformArray(term);
+ result = TransformArray(term);
break;
case ITE:
{
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;
}
* ITE(i=j,v1,v2)
*
*/
- ASTNode BeevMgr::TransformArray(const ASTNode& term)
+ ASTNode ArrayTransformer::TransformArray(const ASTNode& term)
{
assert(TransformMap != NULL);
*/
// 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;
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;
}
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)
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:
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);
}
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;
}
(*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
--- /dev/null
+// -*- 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 <cstdlib>
+#include <cstdio>
+#include <cassert>
+#include <iostream>
+#include <sstream>
+#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
.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) > $@
+// -*- 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
class RunTimes
{
public:
- enum Category
- {
- Transforming = 0, SimplifyTopLevel, Parsing, CNFConversion, BitBlasting, Solving, BVSolver, CreateSubstitutionMap, SendingToSAT
- };
-
- static std::string CategoryNames[];
-
- typedef std::pair<Category, long> Element;
-
-private:
- RunTimes& operator =(const RunTimes&);
- RunTimes(const RunTimes& other);
-
- std::map<Category, int> counts;
- std::map<Category, long> times;
- std::stack<Element> 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<Category, long> Element;
+
+ private:
+ RunTimes& operator =(const RunTimes&);
+ RunTimes(const RunTimes& other);
+
+ std::map<Category, int> counts;
+ std::map<Category, long> times;
+ std::stack<Element> 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
#include <algorithm>
#include <assert.h>
+#define INITIAL_TABLE_SIZE 100
+
#ifdef EXT_HASH_MAP
#include <ext/hash_set>
#include <ext/hash_map>
#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 <class E, class T>
- struct enumeration
- {
- typedef T type;
- typedef E enum_type;
-
- enumeration() : e_(E())
- {}
-
- enumeration(E e) : e_(static_cast<T>(e))
- {}
-
- operator E() const
- { return static_cast<E>(e_); }
-
- private:
- T e_;
- }; //end of Enumeration struct
-
/******************************************************************
* Important classes declared as part of AST datastructures *
* *
******************************************************************/
typedef vector<ASTNode> ASTVec;
typedef unsigned int * CBV;
-#define HASHMAP hash_map;
-#define HASHSET hash_set;
extern ASTVec _empty_ASTVec;
-
}; //end of namespace
#endif
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:
depend: $(SRCS)
@$(CXX) -MM $(CXXFLAGS) $(SRCS) > $@
-#-include depend
+#-include depend
\ No newline at end of file
--- /dev/null
+// -*- 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
--- /dev/null
+// -*- 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
* 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 <inttypes.h>
+#include <cmath>
+#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);
{
n_ptr->SetNodeNum(NewNodeNum());
}
- pair<ASTInteriorSet::const_iterator, bool> p = _interior_unique_table.insert(n_ptr);
+ pair<ASTInteriorSet::const_iterator, bool> p =
+ _interior_unique_table.insert(n_ptr);
return *(p.first);
}
else
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);
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);
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;
// 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);
////////////////////////////////////////////////////////////////
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<ASTSymbolSet::const_iterator, bool> 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;
}
}
- // 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<ASTSymbolSet::const_iterator, bool> p = _symbol_unique_table.insert(s_ptr1);
- return *p.first;
- }
- else
- // return symbol found in table.
- return *it;
- }
-
- bool BeevMgr::LookupSymbol(ASTSymbol& s)
- {
- ASTSymbol* s_ptr = &s; // it's a temporary key.
-
- if (_symbol_unique_table.find(s_ptr) == _symbol_unique_table.end())
- return false;
- else
- return true;
- }
-
// Create and return an ASTNode for a term
ASTNode BeevMgr::CreateTerm(Kind kind,
unsigned int width,
FatalError("CreateTerm: Illegal kind to CreateTerm:", ASTUndefined, kind);
ASTNode n = CreateNode(kind, child0, children);
n.SetValueWidth(width);
+ BVTypeCheck(n);
return n;
}
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)
{
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)
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<ASTVec *>::iterator it=_asserts.begin(),
- // itend=_asserts.end();it!=itend;it++) {
- // (*it)->clear();
- // }
- _asserts.clear();
- for (ASTNodeToVecMap::iterator iset = _arrayname_readindices.begin(), iset_end = _arrayname_readindices.end(); iset != iset_end; iset++)
- {
- iset->second.clear();
- }
-
- _arrayname_readindices.clear();
- _interior_unique_table.clear();
- _symbol_unique_table.clear();
- _bvconst_unique_table.clear();
+// //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
--- /dev/null
+// -*- 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<ASTVec *> _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<pair<ASTNode, ASTNode> > NodeLetVarVec;
+
+ // A partial Map from ASTNodes to LetVars. Needed in order to
+ // correctly print shared subterms inside the LET itself
+ ASTNodeMap NodeLetVarMap1;
+
+ //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
--- /dev/null
+// -*- 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<unsigned int, bool> *,
+ 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<unsigned, bool> * 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
--- /dev/null
+// -*- c++ -*-
+/********************************************************************
+ * AUTHORS: Vijay Ganesh
+ *
+ * BEGIN DATE: November, 2005
+ *
+ * LICENSE: Please view LICENSE file in the home dir of this Program
+ ********************************************************************/
+
+#include <assert.h>
+#include <math.h>
+#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
--- /dev/null
+// -*- 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<unsigned, bool> * v;
+ if (_ASTNode_to_Bitvector.find(symbol) == _ASTNode_to_Bitvector.end())
+ _ASTNode_to_Bitvector[symbol] =
+ new hash_map<unsigned, bool> (symbolWidth);
+
+ //v holds the map from bit-index to bit-value
+ v = _ASTNode_to_Bitvector[symbol];
+
+ //kk is the index of BVGETBIT
+ unsigned int kk = GetUnsignedConst(s[1]);
+
+ //Collect the bits of 'symbol' and store in v. Store in reverse order.
+ if (newS.model[i] == MINISAT::l_True)
+ (*v)[(symbolWidth - 1) - kk] = true;
+ else
+ (*v)[(symbolWidth - 1) - kk] = false;
+ }
+ else
+ {
+ if (s.GetKind() == SYMBOL && s.GetType() == BOOLEAN_TYPE)
+ {
+ const char * zz = s.GetName();
+ //if the variables are not cnf variables then add them to the counterexample
+ if (0 != strncmp("cnf", zz, 3) && 0 != strcmp("*TrueDummy*", zz))
+ {
+ if (newS.model[i] == MINISAT::l_True)
+ CounterExampleMap[s] = ASTTrue;
+ else if (newS.model[i] == MINISAT::l_False)
+ CounterExampleMap[s] = ASTFalse;
+ else
+ {
+ int seed = 10000;
+ srand(seed);
+ CounterExampleMap[s] = (rand() > seed) ? ASTFalse : ASTTrue;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ //iterate over the ASTNode_to_Bitvector data-struct and construct
+ //the the aggregate value of the bitvector, and populate the
+ //CounterExampleMap datastructure
+ for (ASTtoBitvectorMap::iterator it = _ASTNode_to_Bitvector.begin(),
+ itend = _ASTNode_to_Bitvector.end(); it != itend; it++)
+ {
+ ASTNode var = it->first;
+ //debugging
+ //cerr << var;
+ if (SYMBOL != var.GetKind())
+ FatalError("ConstructCounterExample: error while constructing counterexample: not a variable: ", var);
+
+ //construct the bitvector value
+ hash_map<unsigned, bool> * w = it->second;
+ ASTNode value = BoolVectoBVConst(w, var.GetValueWidth());
+ //debugging
+ //cerr << value;
+
+ //populate the counterexample datastructure. add only scalars
+ //variables which were declared in the input and newly
+ //introduced variables for array reads
+ CounterExampleMap[var] = value;
+ }
+
+ //In this loop, we compute the value of each array read, the
+ //corresponding ITE against the counterexample generated above.
+ for (ASTNodeMap::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<int> 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<unsigned, bool> * w, unsigned int l)
+ {
+ unsigned len = w->size();
+ if (l < len)
+ FatalError("BoolVectorBVConst : "
+ "length of bitvector does not match hash_map size:", ASTUndefined, l);
+ std::string cc;
+ for (unsigned int jj = 0; jj < l; jj++)
+ {
+ if ((*w)[jj] == true)
+ cc += '1';
+ else if ((*w)[jj] == false)
+ cc += '0';
+ else
+ cc += '0';
+ }
+ return 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()
+};
SRCS = $(wildcard *.cpp)
OBJS = $(SRCS:.cpp=.o)
+CFLAGS += -I../sat/mtl -I../sat/simp -I../sat/core
libabstractionrefinement.a: $(OBJS) depend
$(AR) rc $@ $(OBJS)
+++ /dev/null
-// -*- c++ -*-
-/********************************************************************
- * AUTHORS: Vijay Ganesh
- *
- * BEGIN DATE: November, 2005
- *
- * LICENSE: Please view LICENSE file in the home dir of this Program
- ********************************************************************/
-
-#include <assert.h>
-#include <math.h>
-#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
SRCS = $(wildcard *.cpp)
OBJS = $(SRCS:.cpp=.o)
+CFLAGS += -I../sat/mtl -I../sat/simp -I../sat/core
libcinterface.a: $(OBJS) depend
$(AR) rc $@ $(OBJS)
#include <stdlib.h>
#include <assert.h>
#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<BEEV::ASTNode *> created_exprs;
bool cinterface_exprdelete_on_flag = false;
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
// 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;
}
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);
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;
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;
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
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);
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);
/////////////////////////////////////////////////////////////////////////////
//! 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;
//! 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);
// //! 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);
/*! 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);
}
* 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();
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();
// }
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";
}
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;
/*! 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);
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);
}
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);
}
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);
//! 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);
}
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);
// 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);
}
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);
}
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);
}
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);
}
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;
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);
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;
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);
}
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;
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);
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
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);
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;
// 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:",
}
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;
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;
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;
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;
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;
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;
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;
// 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;
// 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;
// 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;
}
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
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;
}
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;
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
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;
//! 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())
//! 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())
//! 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())
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;
#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";
BEEV::FatalError("");
}
- BEEV::GlobalBeevMgr = b;
+ //BEEV::GlobalSTP = (stpstar)vc;
CONSTANTBV::ErrCode c = CONSTANTBV::BitVector_Boot();
if(0 != c) {
cout << CONSTANTBV::BitVector_Error(c) << endl;
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);
}
void vc_Destroy(VC vc) {
- bmstar b = (bmstar)vc;
+ bmstar b = (bmstar)(((stpstar)vc)->bm);
// for(std::vector<BEEV::ASTNode *>::iterator it=created_exprs.begin(),
// itend=created_exprs.end();it!=itend;it++) {
// BEEV::ASTNode * aaa = *it;
void vc_DeleteExpr(Expr e) {
nodestar input = (nodestar)e;
- //bmstar b = (bmstar)vc;
+ //bmstar b = (bmstar)(((stpstar)vc)->bm);
delete input;
}
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";
}
--- /dev/null
+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
// -*- 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
// 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
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
extern bool division_by_zero_returns_one;
+ extern bool quick_statistics_flag;
+
enum inputStatus
{
NOT_DECLARED =0, // Not included in the input file / stream
//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<ASTNode> _empty_ASTVec;
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
#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;
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";
}
}
+ //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);
{
cvcparse((void*)AssertsQuery);
}
- GlobalBeevMgr->runTimes.stop(RunTimes::Parsing);
+ bm->GetRunTimes()->stop(RunTimes::Parsing);
ASTNode asserts = (*(ASTVec*)AssertsQuery)[0];
ASTNode query = (*(ASTVec*)AssertsQuery)[1];
{
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
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
#include "parseCVC_defs.h"
using namespace std;
- using namespace BEEV;
-
+ using namespace BEEV;
extern char *yytext;
extern int cvcerror (const char *msg);
%}
[\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;}
"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;
using namespace std;
using namespace BEEV;
-
+
// Suppress the bogus warning suppression in bison (it generates
// compile error)
#undef __GNUC_MINOR__
#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 {
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;
/* push : PUSH_TOK */
/* { */
-/* GlobalBeevMgr->Push(); */
+/* ParserBM->Push(); */
/* } */
/* | */
/* ; */
/* pop : POP_TOK */
/* { */
-/* GlobalBeevMgr->Pop(); */
+/* ParserBM->Pop(); */
/* } */
/* | */
/* ; */
{
$$ = 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;
}
Assert : ASSERT_TOK Formula ';' { $$ = $2; }
;
-Query : QUERY_TOK Formula ';' { GlobalBeevMgr->AddQuery(*$2); $$ = $2;}
+Query : QUERY_TOK Formula ';' { ParserBM->AddQuery(*$2); $$ = $2;}
;
_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())
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())
i->SetValueWidth($5->GetValueWidth());
i->SetIndexWidth($5->GetIndexWidth());
- GlobalBeevMgr->GetLetMgr()->LetExprMgr(*i,*$5);
+ ParserBM->GetLetMgr()->LetExprMgr(*i,*$5);
delete $5;
}
}
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;
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;
}
| 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;
}
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;
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;
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;
}
| 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;
| 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);
}
{
$$ = $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;
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;
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;
{
// 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;
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;
}
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;
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;
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;
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;
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;
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;
//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;
}
| 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;
}
| 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;
| 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;
}
| 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;
}
| 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;
}
| 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;
}
| 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;
{
$$ = $4;
//Cleanup the LetIDToExprMap
- //GlobalBeevMgr->CleanupLetIDMap();
+ //ParserBM->CleanupLetIDMap();
}
;
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;
}
LetDecl : FORMID_TOK '=' Expr
{
//Expr must typecheck
- GlobalBeevMgr->BVTypeCheck(*$3);
+ BVTypeCheck(*$3);
//set the valuewidth of the identifier
$1->SetValueWidth($3->GetValueWidth());
//
//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: ");
$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: ");
$1->SetIndexWidth($5->GetIndexWidth());
//Do LET-expr management
- GlobalBeevMgr->GetLetMgr()->LetExprMgr(*$1,*$5);
+ ParserBM->GetLetMgr()->LetExprMgr(*$1,*$5);
delete $1;
delete $5;
}
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) $@
@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 .#*
--- /dev/null
+// -*- 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
#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
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) {
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;
};
"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;
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;
ASTNode assumptions;
if($1 == NULL)
{
- assumptions = GlobalBeevMgr->CreateNode(TRUE);
+ assumptions = ParserBM->CreateNode(TRUE);
}
else
{
if(query.IsNull())
{
- query = GlobalBeevMgr->CreateNode(FALSE);
+ query = ParserBM->CreateNode(FALSE);
}
((ASTVec*)AssertsQuery)->push_back(assumptions);
{
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;
$$ = new ASTVec;
if ($1 != NULL) {
$$->push_back(*$1);
- GlobalBeevMgr->AddAssert(*$1);
+ ParserBM->AddAssert(*$1);
delete $1;
}
}
{
if ($1 != NULL && $2 != NULL) {
$1->push_back(*$2);
- GlobalBeevMgr->AddAssert(*$2);
+ ParserBM->AddAssert(*$2);
$$ = $1;
delete $2;
}
$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
{
$2->SetIndexWidth(0);
$2->SetValueWidth(0);
if(print_STPinput_back_flag)
- GlobalBeevMgr->ListOfDeclaredVars.push_back(*$2);
+ ParserBM->ListOfDeclaredVars.push_back(*$2);
}
;
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);
}
| 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;
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);
}
$$ = (forms.size() == 1) ?
new ASTNode(forms[0]) :
- new ASTNode(GlobalBeevMgr->CreateNode(AND, forms));
+ new ASTNode(ParserBM->CreateNode(AND, forms));
delete $3;
}
| 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;
| 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;
| 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;
| 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;
| 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;
| 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;
| 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;
| 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;
}
| 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;
}
{
$$ = $2;
//Cleanup the LetIDToExprMap
- GlobalBeevMgr->GetLetMgr()->CleanupLetIDMap();
+ ParserBM->GetLetMgr()->CleanupLetIDMap();
}
;
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());
//
//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;
}
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
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
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;
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;
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;
}
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;
| 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;
{
//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;
}
{
//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;
}
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
{
// 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;
}
{
// 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;
}
{
// 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();
}
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
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();
}
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
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;
}
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
}
| FORMID_TOK
{
- $$ = new ASTNode(GlobalBeevMgr->GetLetMgr()->ResolveID(*$1));
+ $$ = new ASTNode(ParserBM->GetLetMgr()->ResolveID(*$1));
delete $1;
}
;
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<int> 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++) {
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;
}
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";
--- /dev/null
+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
+
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);
}
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.
#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 );
}
#include <cstdio>
-#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"
--- /dev/null
+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
#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
#include <ctime>
#include <cstdio>
-#include "Queue.h"
-#include "Solver.h"
+#include "../mtl/Queue.h"
+#include "../core/Solver.h"
namespace MINISAT {
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
#include <cstdio>
-#include "Queue.h"
-#include "Solver.h"
+#include "../mtl/Queue.h"
+#include "../core/Solver.h"
namespace MINISAT {
--- /dev/null
+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
//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);
}
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()
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))
{
//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;
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;
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;
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.
}
}
- 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()
//
//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 ...)
{
//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;
}
//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);
// }
DoNotSolve_TheseVars.insert(lhs);
- if (!_bm->UpdateSolverMap(lhs, rhs))
+ if (!_simp->UpdateSolverMap(lhs, rhs))
{
return eq;
}
// else
// {
// DoNotSolve_TheseVars.insert(lhs);
- // if (!_bm->UpdateSolverMap(lhs, rhs))
+ // if (!_simp->UpdateSolverMap(lhs, rhs))
// {
// return eq;
// }
{
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;
}
//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;
}
//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);
//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;
}
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;
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
return output;
}
- _bm->runTimes.start(RunTimes::BVSolver);
+ _bm->GetRunTimes()->start(RunTimes::BVSolver);
ASTVec o;
ASTVec c;
if (EQ == k)
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);
{
//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);
}
output = _bm->CreateNode(AND, output, evens);
UpdateAlreadySolvedMap(input, output);
- _bm->runTimes.stop(RunTimes::BVSolver);
+ _bm->GetRunTimes()->stop(RunTimes::BVSolver);
return output;
} //end of TopLevelBVSolve()
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
//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;
{
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
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;
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;
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
********************************************************************/
// -*- 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
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;
//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
//
//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);
//equation to be solved, solves them,
ASTNode TopLevelBVSolve(const ASTNode& a);
}; //end of class bvsolver
-}
-;//end of namespace BEEV
+};//end of namespace BEEV
+#endif
********************************************************************/
#include <cassert>
-#include "../AST/AST.h"
-#include "../STPManager/STPManager.h"
-
+#include "simplifier.h"
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();
{
output = CONSTANTBV::BitVector_Create(inputwidth, true);
CONSTANTBV::Set_Complement(output, tmp0);
- OutputNode = CreateBVConst(output, outputwidth);
+ OutputNode = _bm->CreateBVConst(output, outputwidth);
break;
}
case BVSX:
if (inputwidth == t0_width)
{
CONSTANTBV::BitVector_Copy(output, tmp0);
- OutputNode = CreateBVConst(output, outputwidth);
+ OutputNode = _bm->CreateBVConst(output, outputwidth);
}
else
{
CONSTANTBV::BitVector_Fill(output);
}
CONSTANTBV::BitVector_Interval_Copy(output, tmp0, 0, 0, t0_width);
- OutputNode = CreateBVConst(output, outputwidth);
+ OutputNode = _bm->CreateBVConst(output, outputwidth);
}
break;
}
}
}
- OutputNode = CreateBVConst(output, outputwidth);
+ OutputNode = _bm->CreateBVConst(output, outputwidth);
CONSTANTBV::BitVector_Destroy(width);
break;
{
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:
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:
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;
}
output = CONSTANTBV::BitVector_Concat(tmp0, tmp1);
outputwidth = t0_width + t1_width;
- OutputNode = CreateBVConst(output, outputwidth);
+ OutputNode = _bm->CreateBVConst(output, outputwidth);
break;
}
//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;
}
carry = false;
//CONSTANTBV::BitVector_Destroy(kk);
}
- OutputNode = CreateBVConst(output, outputwidth);
+ OutputNode = _bm->CreateBVConst(output, outputwidth);
break;
}
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
{
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);
}
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
cerr << "Error code was:" << e << endl;
assert(e == CONSTANTBV::ErrCode_Ok);
}
- OutputNode = CreateBVConst(remainder, outputwidth);
+ OutputNode = _bm->CreateBVConst(remainder, outputwidth);
}
else if (isNegativeS && !isNegativeT)
{
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);
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);
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);
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);
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;
//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);
}
}
#include <cassert>
#include <cmath>
-#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)
}
- bool BeevMgr::CheckSimplifyMap(const ASTNode& key,
+ bool Simplifier::CheckSimplifyMap(const ASTNode& key,
ASTNode& output,
bool pushNeg, ASTNodeMap* VarConstMap)
{
(ASTFalse == it->second) ?
ASTTrue :
(ASTTrue == it->second) ?
- ASTFalse : CreateNode(NOT, it->second);
+ ASTFalse : _bm->CreateNode(NOT, it->second);
CountersAndStats("2nd_Successful_CheckSimplifyMap");
return true;
}
}
// 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)
{
// 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);
(*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;
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)
assert((e1.GetKind() == TRUE) ||
(e1.GetKind() == FALSE) ||
(e1.GetKind() == BVCONST));
- SolverMap[e0] = e1;
+ (*SolverMap)[e0] = e1;
return true;
}
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())
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();
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;
// 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)
isAtomic(kind)))
{
SortByArith(ca);
- a = CreateNode(kind, ca);
+ a = _bm->CreateNode(kind, ca);
}
ASTNode output;
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;
}
}
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
}
ASTNode
- BeevMgr::SimplifyAtomicFormula(const ASTNode& a,
+ Simplifier::SimplifyAtomicFormula(const ASTNode& a,
bool pushNeg, ASTNodeMap* VarConstMap)
{
// if (!optimize_flag)
{
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;
}
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:
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;
}
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:
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:
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:
{
output =
pushNeg ?
- CreateNode(BVLE, left, right) :
- CreateNode(BVLT, right, left);
+ _bm->CreateNode(BVLE, left, right) :
+ _bm->CreateNode(BVLT, right, left);
}
break;
case BVGE:
{
output =
pushNeg ?
- CreateNode(BVLT, left, right) :
- CreateNode(BVLE, right, left);
+ _bm->CreateNode(BVLT, left, right) :
+ _bm->CreateNode(BVLE, right, left);
}
break;
case BVSLT:
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:
//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();
// 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;
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());
}
//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");
}
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 &&
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);
//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();
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)
{
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)
{
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;
{
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;
{
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;
}
ASTNode
- BeevMgr::SimplifyNotFormula(const ASTNode& a,
+ Simplifier::SimplifyNotFormula(const ASTNode& a,
bool pushNeg, ASTNodeMap* VarConstMap)
{
ASTNode output;
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))
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())
{
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))
{
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
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))
{
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
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))
{
c0 = SimplifyFormula(a[0], false, VarConstMap);
c1 = SimplifyFormula(a[1], true, VarConstMap);
- output = CreateNode(AND, c0, c1);
+ output = _bm->CreateNode(AND, c0, c1);
}
else
{
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
//(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);
}
}
}
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))
{
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
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;
}
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
}
//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
}
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;
//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.
// return inputterm;
// }
- ASTNode output;
+ ASTNode output = inputterm;
assert(BVTypeCheck(inputterm));
//########################################
}
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:
}
}
- 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
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);
}
{
//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
{
{
//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);
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);
}
}
}
{
ASTVec d = output.GetChildren();
SortByArith(d);
- output = CreateTerm(output.GetKind(), output.GetValueWidth(), d);
+ output = _bm->CreateTerm(output.GetKind(), output.GetValueWidth(), d);
}
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;
}
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:
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
{
// 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;
}
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;
}
}
//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);
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:
//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;
}
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;
}
// (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:{
// "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;
}
}
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;
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:
{
}
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;
}
//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;
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;
break;
default:
SortByArith(o);
- output = CreateTerm(k, inputValueWidth, o);
+ output = _bm->CreateTerm(k, inputValueWidth, o);
if (constant)
{
output = BVConstEvaluator(output);
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])
{
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;
}
{
// 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)
{
{
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
}
}
else
- output = CreateTerm(k, width, a, b);
+ output = _bm->CreateTerm(k, width, a, b);
}
break;
}
o.push_back(aaa);
}
- output = CreateTerm(k, inputValueWidth, o);
+ output = _bm->CreateTerm(k, inputValueWidth, o);
if (constant)
output = BVConstEvaluator(output);
break;
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);
//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
ASTNode aaa = SimplifyTerm(*it, VarConstMap);
o.push_back(aaa);
}
- output = CreateTerm(k, inputValueWidth, o);
+ output = _bm->CreateTerm(k, inputValueWidth, o);
break;
}
case WRITE:
return inputterm;
break;
}
- assert(NULL != output);
+ assert(!output.IsNull());
//memoize
UpdateSimplifyMap(inputterm, output, false, VarConstMap);
//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);
}
}
//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;
//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
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())
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);
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);
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
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)
{
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);
if (outputvec.size() > 1)
{
- output = CreateTerm(BVPLUS, len, outputvec);
+ output = _bm->CreateTerm(BVPLUS, len, outputvec);
}
else if (outputvec.size() == 1)
{
//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())
}
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
{
{
ASTVec outv = output.GetChildren();
SortByArith(outv);
- output = CreateTerm(BVPLUS, len, outv);
+ output = _bm->CreateTerm(BVPLUS, len, outv);
}
//memoize
// (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;
//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];
//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];
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
{
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);
}
}
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);
}
}
//compute output here
if (outputvec.size() > 1)
{
- output = CombineLikeTerms(CreateTerm(BVPLUS, len, outputvec));
+ output = CombineLikeTerms(_bm->CreateTerm(BVPLUS, len, outputvec));
output = SimplifyTerm(output);
}
else
//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;
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);
} //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);
}
} //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;
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()
//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())
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
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;
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))
{
} //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())
//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);
} //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)
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
--- /dev/null
+// -*- 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
--- /dev/null
+// -*- 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
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);
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()
// constructor
CNFMgr(BeevMgr *bmgr);
-
//########################################
//########################################
// destructor
*
* LICENSE: Please view LICENSE file in the home dir of this Program
********************************************************************/
-#include <cmath>
-#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
{
* 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;
*/
// 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();
}
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;
}
//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
// 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)
}
}
- // 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();
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;
{
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;
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;
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<unsigned, bool> * v;
- if (_ASTNode_to_Bitvector.find(symbol) == _ASTNode_to_Bitvector.end())
- _ASTNode_to_Bitvector[symbol] = new hash_map<unsigned, bool> (symbolWidth);
-
- //v holds the map from bit-index to bit-value
- v = _ASTNode_to_Bitvector[symbol];
-
- //kk is the index of BVGETBIT
- unsigned int kk = GetUnsignedConst(s[1]);
-
- //Collect the bits of 'symbol' and store in v. Store in reverse order.
- if (newS.model[i] == MINISAT::l_True)
- (*v)[(symbolWidth - 1) - kk] = true;
- else
- (*v)[(symbolWidth - 1) - kk] = false;
- }
- else
- {
- if (s.GetKind() == SYMBOL && s.GetType() == BOOLEAN_TYPE)
- {
- const char * zz = s.GetName();
- //if the variables are not cnf variables then add them to the counterexample
- if (0 != strncmp("cnf", zz, 3) && 0 != strcmp("*TrueDummy*", zz))
- {
- if (newS.model[i] == MINISAT::l_True)
- CounterExampleMap[s] = ASTTrue;
- else if (newS.model[i] == MINISAT::l_False)
- CounterExampleMap[s] = ASTFalse;
- else
- {
- int seed = 10000;
- srand(seed);
- CounterExampleMap[s] = (rand() > seed) ? ASTFalse : ASTTrue;
- }
- }
- }
- }
- }
- }
-
- //iterate over the ASTNode_to_Bitvector data-struct and construct
- //the the aggregate value of the bitvector, and populate the
- //CounterExampleMap datastructure
- for (ASTtoBitvectorMap::iterator it = _ASTNode_to_Bitvector.begin(), itend = _ASTNode_to_Bitvector.end(); it != itend; it++)
- {
- ASTNode var = it->first;
- //debugging
- //cerr << var;
- if (SYMBOL != var.GetKind())
- FatalError("ConstructCounterExample: error while constructing counterexample: not a variable: ", var);
-
- //construct the bitvector value
- hash_map<unsigned, bool> * w = it->second;
- ASTNode value = BoolVectoBVConst(w, var.GetValueWidth());
- //debugging
- //cerr << value;
-
- //populate the counterexample datastructure. add only scalars
- //variables which were declared in the input and newly
- //introduced variables for array reads
- CounterExampleMap[var] = value;
- }
-
- //In this loop, we compute the value of each array read, the
- //corresponding ITE against the counterexample generated above.
- for (ASTNodeMap::iterator it = _arrayread_ite.begin(), itend = _arrayread_ite.end(); it != itend; it++)
- {
- //the array read
- ASTNode arrayread = it->first;
- ASTNode value_ite = _arrayread_ite[arrayread];
-
- //convert it to a constant array-read and store it in the
- //counter-example. First convert the index into a constant. then
- //construct the appropriate array-read and store it in the
- //counterexample
- ASTNode arrayread_index = TermToConstTermUsingModel(arrayread[1]);
- ASTNode key = CreateTerm(READ, arrayread.GetValueWidth(), arrayread[0], arrayread_index);
-
- //Get the ITE corresponding to the array-read and convert it
- //to a constant against the model
- ASTNode value = TermToConstTermUsingModel(value_ite);
- //save the result in the counter_example
- if (!CheckSubstitutionMap(key))
- CounterExampleMap[key] = value;
- }
- } //End of ConstructCounterExample
-
-
- // FUNCTION: accepts a non-constant term, and returns the
- // corresponding constant term with respect to a model.
- //
- // term READ(A,i) is treated as follows:
- //
- //1. If (the boolean variable 'ArrayReadFlag' is true && ArrayRead
- //1. has value in counterexample), then return the value of the
- //1. arrayread.
- //
- //2. If (the boolean variable 'ArrayReadFlag' is true && ArrayRead
- //2. doesn't have value in counterexample), then return the
- //2. arrayread itself (normalized such that arrayread has a constant
- //2. index)
- //
- //3. If (the boolean variable 'ArrayReadFlag' is false) && ArrayRead
- //3. has a value in the counterexample then return the value of the
- //3. arrayread.
- //
- //4. If (the boolean variable 'ArrayReadFlag' is false) && ArrayRead
- //4. doesn't have a value in the counterexample then return 0 as the
- //4. value of the arrayread.
- ASTNode BeevMgr::TermToConstTermUsingModel(const ASTNode& t, bool ArrayReadFlag)
- {
- Begin_RemoveWrites = false;
- SimplifyWrites_InPlace_Flag = false;
- //ASTNode term = SimplifyTerm(t);
- ASTNode term = t;
- Kind k = term.GetKind();
-
- //cerr << "Input to TermToConstTermUsingModel: " << term << endl;
- if (!is_Term_kind(k))
- {
- FatalError("TermToConstTermUsingModel: The input is not a term: ", term);
- }
- if (k == WRITE)
- {
- FatalError("TermToConstTermUsingModel: The input has wrong kind: WRITE : ", term);
- }
- if (k == SYMBOL && BOOLEAN_TYPE == term.GetType())
- {
- FatalError("TermToConstTermUsingModel: The input has wrong kind: Propositional variable : ", term);
- }
-
- ASTNodeMap::iterator it1;
- if ((it1 = CounterExampleMap.find(term)) != CounterExampleMap.end())
- {
- ASTNode val = it1->second;
- if (BVCONST != val.GetKind())
- {
- //CounterExampleMap has two maps rolled into
- //one. SubstitutionMap and SolverMap.
- //
- //recursion is fine here. There are two maps that are checked
- //here. One is the substitutionmap. We garuntee that the value
- //of a key in the substitutionmap is always a constant.
- //
- //in the SolverMap we garuntee that "term" does not occur in
- //the value part of the map
- if (term == val)
- {
- FatalError("TermToConstTermUsingModel: The input term is stored as-is "
- "in the CounterExample: Not ok: ", term);
- }
- return TermToConstTermUsingModel(val, ArrayReadFlag);
- }
- else
- {
- return val;
- }
- }
-
- ASTNode output;
- switch (k)
- {
- case BVCONST:
- output = term;
- break;
- case SYMBOL:
- {
- if (term.GetType() == ARRAY_TYPE)
- {
- return term;
- }
-
- //when all else fails set symbol values to some constant by
- //default. if the variable is queried the second time then add 1
- //to and return the new value.
- ASTNode zero = CreateZeroConst(term.GetValueWidth());
- output = zero;
- break;
- }
- case READ:
- {
- ASTNode arrName = term[0];
- ASTNode index = term[1];
- if (0 == arrName.GetIndexWidth())
- {
- FatalError("TermToConstTermUsingModel: array has 0 index width: ", arrName);
- }
-
-
- if (WRITE == arrName.GetKind()) //READ over a WRITE
- {
- ASTNode wrtterm = Expand_ReadOverWrite_UsingModel(term, ArrayReadFlag);
- if (wrtterm == term)
- {
- FatalError("TermToConstTermUsingModel: Read_Over_Write term must be expanded into an ITE", term);
- }
- ASTNode rtterm = TermToConstTermUsingModel(wrtterm, ArrayReadFlag);
- assert(ArrayReadFlag || (BVCONST == rtterm.GetKind()));
- return rtterm;
- }
- else if (ITE == arrName.GetKind()) //READ over an ITE
- {
- // The "then" and "else" branch are arrays.
- ASTNode indexVal = TermToConstTermUsingModel(index, ArrayReadFlag);
-
- ASTNode condcompute = ComputeFormulaUsingModel(arrName[0]); // Get the truth value.
- if (ASTTrue == condcompute)
- {
- const ASTNode & result = TermToConstTermUsingModel(CreateTerm(READ, arrName.GetValueWidth(), arrName[1], indexVal), ArrayReadFlag);
- assert(ArrayReadFlag || (BVCONST == result.GetKind()));
- return result;
- }
- else if (ASTFalse == condcompute)
- {
- const ASTNode & result = TermToConstTermUsingModel(CreateTerm(READ, arrName.GetValueWidth(), arrName[2], indexVal), ArrayReadFlag);
- assert(ArrayReadFlag || (BVCONST == result.GetKind()));
- return result;
- }
- else
- {
- cerr << "TermToConstTermUsingModel: termITE: value of conditional is wrong: " << condcompute << endl;
- FatalError(" TermToConstTermUsingModel: termITE: cannot compute ITE conditional against model: ", term);
- }
- FatalError("bn23143 Never Here");
- }
-
- ASTNode modelentry;
- if (CounterExampleMap.find(index) != CounterExampleMap.end())
- {
- //index has a const value in the CounterExampleMap
- //ASTNode indexVal = CounterExampleMap[index];
- ASTNode indexVal = TermToConstTermUsingModel(CounterExampleMap[index], ArrayReadFlag);
- modelentry = CreateTerm(READ, arrName.GetValueWidth(), arrName, indexVal);
- }
- else
- {
- //index does not have a const value in the CounterExampleMap. compute it.
- ASTNode indexconstval = TermToConstTermUsingModel(index, ArrayReadFlag);
- //update model with value of the index
- //CounterExampleMap[index] = indexconstval;
- modelentry = CreateTerm(READ, arrName.GetValueWidth(), arrName, indexconstval);
- }
- //modelentry is now an arrayread over a constant index
- BVTypeCheck(modelentry);
-
- //if a value exists in the CounterExampleMap then return it
- if (CounterExampleMap.find(modelentry) != CounterExampleMap.end())
- {
- output = TermToConstTermUsingModel(CounterExampleMap[modelentry], ArrayReadFlag);
- }
- else if (ArrayReadFlag)
- {
- //return the array read over a constantindex
- output = modelentry;
- }
- else
- {
- //when all else fails set symbol values to some constant by
- //default. if the variable is queried the second time then add 1
- //to and return the new value.
- ASTNode zero = CreateZeroConst(modelentry.GetValueWidth());
- output = zero;
- }
- break;
- }
- case ITE:
- {
- ASTNode condcompute = ComputeFormulaUsingModel(term[0]);
- if (ASTTrue == condcompute)
- {
- output = TermToConstTermUsingModel(term[1], ArrayReadFlag);
- }
- else if (ASTFalse == condcompute)
- {
- output = TermToConstTermUsingModel(term[2], ArrayReadFlag);
- }
- else
- {
- cerr << "TermToConstTermUsingModel: termITE: value of conditional is wrong: " << condcompute << endl;
- FatalError(" TermToConstTermUsingModel: termITE: cannot compute ITE conditional against model: ", term);
- }
- break;
- }
- default:
- {
- ASTVec c = term.GetChildren();
- ASTVec o;
- for (ASTVec::iterator it = c.begin(), itend = c.end(); it != itend; it++)
- {
- ASTNode ff = TermToConstTermUsingModel(*it, ArrayReadFlag);
- o.push_back(ff);
- }
- output = CreateTerm(k, term.GetValueWidth(), o);
- //output is a CONST expression. compute its value and store it
- //in the CounterExampleMap
- ASTNode oo = BVConstEvaluator(output);
- //the return value
- output = oo;
- break;
- }
- }
-
- assert(ArrayReadFlag || (BVCONST == output.GetKind()));
-
- //when this flag is false, we should compute the arrayread to a
- //constant. this constant is stored in the counter_example
- //datastructure
- if (!ArrayReadFlag)
- {
- CounterExampleMap[term] = output;
- }
-
- //cerr << "Output to TermToConstTermUsingModel: " << output << endl;
- return output;
- } //End of TermToConstTermUsingModel
-
- //Expands read-over-write by evaluating (readIndex=writeIndex) for
- //every writeindex until, either it evaluates to TRUE or all
- //(readIndex=writeIndex) evaluate to FALSE
- ASTNode BeevMgr::Expand_ReadOverWrite_UsingModel(const ASTNode& term, bool arrayread_flag)
- {
- if (READ != term.GetKind() && WRITE != term[0].GetKind())
- {
- FatalError("RemovesWrites: Input must be a READ over a WRITE", term);
- }
-
- ASTNode output;
- ASTNodeMap::iterator it1;
- if ((it1 = CounterExampleMap.find(term)) != CounterExampleMap.end())
- {
- ASTNode val = it1->second;
- if (BVCONST != val.GetKind())
- {
- //recursion is fine here. There are two maps that are checked
- //here. One is the substitutionmap. We garuntee that the value
- //of a key in the substitutionmap is always a constant.
- if (term == val)
- {
- FatalError("TermToConstTermUsingModel: The input term is stored as-is "
- "in the CounterExample: Not ok: ", term);
- }
- return TermToConstTermUsingModel(val, arrayread_flag);
- }
- else
- {
- return val;
- }
- }
-
- unsigned int width = term.GetValueWidth();
- ASTNode writeA = ASTTrue;
- ASTNode newRead = term;
- ASTNode readIndex = TermToConstTermUsingModel(newRead[1], false);
- //iteratively expand read-over-write, and evaluate against the
- //model at every iteration
- do
- {
- ASTNode write = newRead[0];
- writeA = write[0];
- ASTNode writeIndex = TermToConstTermUsingModel(write[1], false);
- ASTNode writeVal = TermToConstTermUsingModel(write[2], false);
-
- ASTNode cond =
- ComputeFormulaUsingModel(CreateSimplifiedEQ(writeIndex, readIndex));
- if (ASTTrue == cond)
- {
- //found the write-value. return it
- output = writeVal;
- CounterExampleMap[term] = output;
- return output;
- }
-
- newRead = CreateTerm(READ, width, writeA, readIndex);
- } while (READ == newRead.GetKind() && WRITE == newRead[0].GetKind());
-
- output = TermToConstTermUsingModel(newRead, arrayread_flag);
-
- //memoize
- CounterExampleMap[term] = output;
- return output;
- } //Exand_ReadOverWrite_To_ITE_UsingModel()
-
- /* FUNCTION: accepts a non-constant formula, and checks if the
- * formula is ASTTrue or ASTFalse w.r.t to a model
- */
- ASTNode BeevMgr::ComputeFormulaUsingModel(const ASTNode& form)
- {
- ASTNode in = form;
- Kind k = form.GetKind();
- if (!(is_Form_kind(k) && BOOLEAN_TYPE == form.GetType()))
- {
- FatalError(" ComputeConstFormUsingModel: The input is a non-formula: ", form);
- }
-
- //cerr << "Input to ComputeFormulaUsingModel:" << form << endl;
- ASTNodeMap::iterator it1;
- if ((it1 = ComputeFormulaMap.find(form)) != ComputeFormulaMap.end())
- {
- ASTNode res = it1->second;
- if (ASTTrue == res || ASTFalse == res)
- {
- return res;
- }
- else
- {
- FatalError("ComputeFormulaUsingModel: The value of a formula must be TRUE or FALSE:", form);
- }
- }
-
- ASTNode t0, t1;
- ASTNode output = ASTFalse;
- switch (k)
- {
- case TRUE:
- case FALSE:
- output = form;
- break;
- case SYMBOL:
- if (BOOLEAN_TYPE != form.GetType())
- FatalError(" ComputeFormulaUsingModel: Non-Boolean variables are not formulas", form);
- if (CounterExampleMap.find(form) != CounterExampleMap.end())
- {
- ASTNode counterexample_val = CounterExampleMap[form];
- if (!VarSeenInTerm(form, counterexample_val))
- {
- output = ComputeFormulaUsingModel(counterexample_val);
- }
- else
- {
- output = counterexample_val;
- }
- }
- else
- {
- 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<unsigned, bool> * w, unsigned int l)
- {
- unsigned len = w->size();
- if (l < len)
- FatalError("BoolVectorBVConst : "
- "length of bitvector does not match hash_map size:", ASTUndefined, l);
- std::string cc;
- for (unsigned int jj = 0; jj < l; jj++)
- {
- if ((*w)[jj] == true)
- cc += '1';
- else if ((*w)[jj] == false)
- cc += '0';
- else
- cc += '0';
- }
- return CreateBVConst(cc.c_str(), 2);
- } //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
--- /dev/null
+// -*- 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 <cmath>
+
+#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<ASTNode> _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