ASTNode NodeFactory::CreateTerm(Kind kind, unsigned int width, const ASTNode& child0, const ASTVec &children) { ASTVec child; child.reserve(children.size() + 1); child.push_back(child0); child.insert(child.end(), children.begin(), children.end()); return CreateTerm(kind, width, child); }
void checkChildrenAreBV(const ASTVec& v, const ASTNode&n) { 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); } }
ASTNode NodeFactory::CreateNode(Kind kind, const ASTNode& child0, const ASTVec & back_children) { ASTVec front_children; front_children.reserve(1 + back_children.size()); front_children.push_back(child0); front_children.insert(front_children.end(), back_children.begin(), back_children.end()); return CreateNode(kind, front_children); }
void STPMgr::printAssertsToStream(ostream& os) { ASTVec v = GetAsserts(); for (ASTVec::iterator i = v.begin(), iend = v.end(); i != iend; i++) { ASTNode q = *i; os << "ASSERT( "; q.PL_Print(os, this); os << ");" << endl; } }
void STPMgr::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; ASTNode q = *i; //Begin_RemoveWrites = false; os << "ASSERT( "; q.PL_Print(os); os << ");" << endl; } }
void FlattenKind(const Kind k, const ASTVec &children, ASTVec & flat_children) { ASTVec::const_iterator ch_end = children.end(); for (ASTVec::const_iterator it = children.begin(); it != ch_end; it++) { Kind ck = it->GetKind(); if (k == ck) { FlattenKind(k,it->GetChildren(), flat_children); } else { flat_children.push_back(*it); } } }
void print_STPInput_Back(const ASTNode& query) { // Determine the symbols in the query and asserts. ASTNodeSet visited; ASTNodeSet symbols; buildListOfSymbols(query, visited, symbols); ASTVec v = (BEEV::GlobalSTP->bm)->GetAsserts(); for(ASTVec::iterator i=v.begin(),iend=v.end();i!=iend;i++) buildListOfSymbols(*i, visited, symbols); (BEEV::GlobalSTP->bm)->printVarDeclsToStream(cout, symbols); (BEEV::GlobalSTP->bm)->printAssertsToStream(cout,0); cout << "QUERY("; query.PL_Print(cout); cout << ");\n"; } //end of print_STPInput_Back()
void Dot_Print1(ostream &os, const ASTNode n, hash_set<int> *alreadyOutput) { // check if this node has already been printed. If so return. if (alreadyOutput->find(n.GetNodeNum()) != alreadyOutput->end()) return; alreadyOutput->insert(n.GetNodeNum()); os << "n" << n.GetNodeNum() << "[label =\""; switch (n.GetKind()) { case SYMBOL: n.nodeprint(os); break; case BITVECTOR: case BVCONST: outputBitVec(n, os); break; default: os << _kind_names[n.GetKind()]; } os << "\"];" << endl; // print the edges to each child. ASTVec ch = n.GetChildren(); ASTVec::iterator itend = ch.end(); int i = 0; for (ASTVec::iterator it = ch.begin(); it < itend; it++) { os << "n" << n.GetNodeNum() << " -> " << "n" << it->GetNodeNum() << "[label=" << i++ << "];" << endl; } // print each of the children. for (ASTVec::iterator it = ch.begin(); it < itend; it++) { Dot_Print1(os, *it, alreadyOutput); } }
/* Maintains a set of nodes that have already been seen. So that deeply shared * AND,OR operations are not * flattened multiple times. */ void FlattenKindNoDuplicates(const Kind k, const ASTVec& children, ASTVec& flat_children, ASTNodeSet& alreadyFlattened) { const ASTVec::const_iterator ch_end = children.end(); for (ASTVec::const_iterator it = children.begin(); it != ch_end; it++) { const Kind ck = it->GetKind(); if (k == ck) { if (alreadyFlattened.find(*it) == alreadyFlattened.end()) { alreadyFlattened.insert(*it); FlattenKindNoDuplicates(k, it->GetChildren(), flat_children, alreadyFlattened); } } else { flat_children.push_back(*it); } } }
// Flatten (k ... (k ci cj) ...) to (k ... ci cj ...) // This is local to this file. ASTVec FlattenKind(Kind k, const ASTVec &children) { ASTVec flat_children; ASTVec::const_iterator ch_end = children.end(); for (ASTVec::const_iterator it = children.begin(); it != ch_end; it++) { Kind ck = it->GetKind(); const ASTVec &gchildren = it->GetChildren(); if (k == ck) { // append grandchildren to children flat_children.insert(flat_children.end(), gchildren.begin(), gchildren.end()); } else { flat_children.push_back(*it); } } return flat_children; }
//FIXME: Ideally I would like the ASTNodes to be able to operate on //themselves (add, sub, concat, etc.) rather than doing a //GetBVConst() and then do the operation externally. For now, //this is the fastest path to completion. ASTNode BeevMgr::BVConstEvaluator(const ASTNode& t) { //cerr << "inside begin bcconstevaluator: " << t << endl; ASTNode OutputNode; if(CheckSolverMap(t,OutputNode)) return OutputNode; OutputNode = ASTUndefined; Kind k = t.GetKind(); unsigned long long int output = 0; unsigned inputwidth = t.GetValueWidth(); ASTNode t0 = ASTUndefined; ASTNode t1 = ASTUndefined; if(2 == t.Degree()) { t0 = BVConstEvaluator(t[0]); t1 = BVConstEvaluator(t[1]); } switch(k) { case READ: case UNDEFINED: case WRITE: case SYMBOL: cerr << t; FatalError("BVConstEvaluator: term is not a constant-term",t); break; case BVCONST: return t; break; case BVNEG: //compute bitwise negation in C output = ~(BVConstEvaluator(t[0]).GetBVConst()); break; case BVSX: output = SXBVConst64(BVConstEvaluator(t[0])); break; case BVAND: output = t0.GetBVConst() & t1.GetBVConst(); break; case BVOR: output = t0.GetBVConst() | t1.GetBVConst(); break; case BVXOR: output = t0.GetBVConst() ^ t1.GetBVConst(); break; case BVSUB: output = t0.GetBVConst() - t1.GetBVConst(); break; case BVUMINUS: output = ~(BVConstEvaluator(t[0]).GetBVConst()) + 1; break; case BVEXTRACT: { unsigned long long int val = BVConstEvaluator(t[0]).GetBVConst(); unsigned int hi = GetUnsignedConst(BVConstEvaluator(t[1])); unsigned int low = GetUnsignedConst(BVConstEvaluator(t[2])); if(!(0 <= hi <= 64)) FatalError("ConstantEvaluator: hi bit in BVEXTRACT is > 32bits",t); if(!(0 <= low <= hi <= 64)) FatalError("ConstantEvaluator: low bit in BVEXTRACT is > 32bits or hi",t); //64 bit mask. unsigned long long int mask1 = 0xffffffffffffffffLL; mask1 >>= 64-(hi+1); //extract val[hi:0] val &= mask1; //extract val[hi:low] val >>= low; output = val; break; } case BVCONCAT: { unsigned long long int q = BVConstEvaluator(t0).GetBVConst(); unsigned long long int r = BVConstEvaluator(t1).GetBVConst(); unsigned int qlen = t[0].GetValueWidth(); unsigned int rlen = t[1].GetValueWidth(); unsigned int slen = t.GetValueWidth(); if(!(0 < qlen + rlen <= 64)) FatalError("BVConstEvaluator:" "lengths of childnodes of BVCONCAT are > 64:",t); //64 bit mask for q unsigned long long int qmask = 0xffffffffffffffffLL; qmask >>= 64-qlen; //zero the useless bits of q q &= qmask; //64 bit mask for r unsigned long long int rmask = 0xffffffffffffffffLL; rmask >>= 64-rlen; //zero the useless bits of r r &= rmask; //concatenate q <<= rlen; q |= r; //64 bit mask for output s unsigned long long int smask = 0xffffffffffffffffLL; smask >>= 64-slen; //currently q has the output output = q; output &= smask; break; } case BVMULT: { output = t0.GetBVConst() * t1.GetBVConst(); //64 bit mask unsigned long long int mask = 0xffffffffffffffffLL; mask = mask >> (64 - inputwidth); output &= mask; break; } case BVPLUS: { ASTVec c = t.GetChildren(); for(ASTVec::iterator it=c.begin(),itend=c.end();it!=itend;it++) output += BVConstEvaluator(*it).GetBVConst(); //64 bit mask unsigned long long int mask = 0xffffffffffffffffLL; mask = mask >> (64 -inputwidth); output &= mask; break; } case SBVDIV: case SBVMOD: { output = BVConstEvaluator(TranslateSignedDivMod(t)).GetBVConst(); break; } case BVDIV: { if(0 == t1.GetBVConst()) { //if denominator is 0 then // (if refinement is ON then output is set to 0) // (else produce a fatal error) if(counterexample_checking_during_refinement) { output = 0; bvdiv_exception_occured = true; break; } else { FatalError("BVConstEvaluator: divide by zero not allowed:",t); } } output = t0.GetBVConst() / t1.GetBVConst(); //64 bit mask unsigned long long int mask = 0xffffffffffffffffLL; mask = mask >> (64 - inputwidth); output &= mask; break; } case BVMOD: { if(0 == t1.GetBVConst()) { //if denominator is 0 then // (if refinement is ON then output is set to 0) // (else produce a fatal error) if(counterexample_checking_during_refinement) { output = 0; bvdiv_exception_occured = true; break; } else { FatalError("BVConstEvaluator: divide by zero not allowed:",t); } } output = t0.GetBVConst() % t1.GetBVConst(); //64 bit mask unsigned long long int mask = 0xffffffffffffffffLL; mask = mask >> (64 - inputwidth); output &= mask; break; } case ITE: if(ASTTrue == t[0]) OutputNode = BVConstEvaluator(t[1]); else if(ASTFalse == t[0]) OutputNode = BVConstEvaluator(t[2]); else FatalError("BVConstEvaluator:" "ITE condiional must be either TRUE or FALSE:",t); break; case EQ: if(t0.GetBVConst() == t1.GetBVConst()) OutputNode = ASTTrue; else OutputNode = ASTFalse; break; case NEQ: if(t0.GetBVConst() != t1.GetBVConst()) OutputNode = ASTTrue; else OutputNode = ASTFalse; break; break; case BVLT: { unsigned long long n0 = t0.GetBVConst(); unsigned long long n1 = t1.GetBVConst(); if(n0 < n1) OutputNode = ASTTrue; else OutputNode = ASTFalse; break; } case BVLE: if(t0.GetBVConst() <= t1.GetBVConst()) OutputNode = ASTTrue; else OutputNode = ASTFalse; break; case BVGT: if(t0.GetBVConst() > t1.GetBVConst()) OutputNode = ASTTrue; else OutputNode = ASTFalse; break; case BVGE: if(t0.GetBVConst() >= t1.GetBVConst()) OutputNode = ASTTrue; else OutputNode = ASTFalse; break; case BVSLT: { signed long long int n0 = SXBVConst64(t0); signed long long int n1 = SXBVConst64(t1); if(n0 < n1) OutputNode = ASTTrue; else OutputNode = ASTFalse; break; } case BVSLE: { signed long long int n0 = SXBVConst64(t0); signed long long int n1 = SXBVConst64(t1); if(n0 <= n1) OutputNode = ASTTrue; else OutputNode = ASTFalse; break; } case BVSGT: { signed long long int n0 = SXBVConst64(t0); signed long long int n1 = SXBVConst64(t1); if(n0 > n1) OutputNode = ASTTrue; else OutputNode = ASTFalse; break; } case BVSGE: { signed long long int n0 = SXBVConst64(t0); signed long long int n1 = SXBVConst64(t1); if(n0 >= n1) OutputNode = ASTTrue; else OutputNode = ASTFalse; break; } default: FatalError("BVConstEvaluator: The input kind is not supported yet:",t); break; } if(ASTTrue != OutputNode && ASTFalse != OutputNode) OutputNode = CreateBVConst(inputwidth, output); UpdateSolverMap(t,OutputNode); //UpdateSimplifyMap(t,OutputNode,false); return OutputNode; } //End of BVConstEvaluator
void GDL_Print1(ostream& os, const ASTNode& n, hash_set<int>* alreadyOutput, string (*annotate)(const ASTNode&)) { // check if this node has already been printed. If so return. if (alreadyOutput->find(n.GetNodeNum()) != alreadyOutput->end()) return; alreadyOutput->insert(n.GetNodeNum()); os << "node: { title:\"n" << n.GetNodeNum() << "\" label: \""; switch (n.GetKind()) { case SYMBOL: n.nodeprint(os); break; case BITVECTOR: case BVCONST: outputBitVec(n, os); break; default: os << _kind_names[n.GetKind()]; } os << annotate(n); os << "\"}" << endl; // print the edges to each child. const ASTVec ch = n.GetChildren(); const ASTVec::const_iterator itend = ch.end(); // If a node has the child 'TRUE' twice, we only want to output one TRUE node. ASTNodeSet constantOutput; int i = 0; for (ASTVec::const_iterator it = ch.begin(); it < itend; it++) { std::stringstream label; if (!isCommutative(n.GetKind())) label << " label:\"" << i << "\""; if (it->isConstant()) { std::stringstream ss; ss << n.GetNodeNum() << "_" << it->GetNodeNum(); if (constantOutput.end() == constantOutput.find(*it)) { os << "node: { title:\"n"; os << ss.str() << "\" label: \""; if (it->GetType() == BEEV::BOOLEAN_TYPE) os << _kind_names[it->GetKind()]; else outputBitVec(*it, os); os << "\"}" << endl; constantOutput.insert(*it); } os << "edge: { source:\"n" << n.GetNodeNum() << "\" target: \"" << "n" << ss.str() << "\"" << label.str() << "}" << endl; } else os << "edge: { source:\"n" << n.GetNodeNum() << "\" target: \"" << "n" << it->GetNodeNum() << "\"" << label.str() << "}" << endl; i++; } // print each of the children. for (ASTVec::const_iterator it = ch.begin(); it < itend; it++) { if (!it->isConstant()) GDL_Print1(os, *it, alreadyOutput, annotate); } }
//UserGuided abstraction refinement SOLVER_RETURN_TYPE STP:: UserGuided_AbsRefine(SATSolver& NewSolver, const ASTNode& original_input) { ASTVec v = bm->GetAsserts_WithKey(0); if(v.empty()) { FatalError("UserGuided_AbsRefine: Something is seriously wrong."\ "The input set is empty"); } ASTNode sureAddInput = (v.size() == 1) ? v[0] : bm->CreateNode(AND, v); SOLVER_RETURN_TYPE res = SOLVER_UNDECIDED; res = TopLevelSTPAux(NewSolver, sureAddInput, original_input); if(SOLVER_UNDECIDED != res) { return res; } //Do refinement here if(AND != original_input.GetKind()) { FatalError("UserGuided_AbsRefine: The input must be an AND"); } ASTVec RefineFormulasVec; ASTVec RemainingFormulasVec; ASTNode asttrue = bm->CreateNode(TRUE); ASTNode astfalse = bm->CreateNode(FALSE); for(int count=0; count < bm->UserFlags.num_absrefine; count++) { RemainingFormulasVec.clear(); RemainingFormulasVec.push_back(asttrue); RefineFormulasVec.clear(); RefineFormulasVec.push_back(asttrue); ASTVec InputKids = original_input.GetChildren(); for(ASTVec::iterator it = InputKids.begin(), itend = InputKids.end(); it!=itend;it++) { Ctr_Example->ClearComputeFormulaMap(); if(astfalse == Ctr_Example->ComputeFormulaUsingModel(*it)) { RefineFormulasVec.push_back(*it); } else { RemainingFormulasVec.push_back(*it); } } ASTNode RefineFormulas = (RefineFormulasVec.size() == 1) ? RefineFormulasVec[0] : bm->CreateNode(AND, RefineFormulasVec); res = TopLevelSTPAux(NewSolver, RefineFormulas, original_input); if(SOLVER_UNDECIDED != res) { return res; } } ASTNode RemainingFormulas = (RemainingFormulasVec.size() == 1) ? RemainingFormulasVec[0] : bm->CreateNode(AND, RemainingFormulasVec); res = TopLevelSTPAux(NewSolver, RemainingFormulas, original_input); if(SOLVER_UNDECIDED != res) { return res; } FatalError("TopLevelSTPAux: reached the end without proper conclusion:" "either a divide by zero in the input or a bug in STP"); return SOLVER_ERROR; } //End of UserGuided_AbsRefine()
// Constant children are accumulated in "accumconst". ASTNode STPMgr::CreateSimpXor(ASTVec &children) { if (_trace_simpbool) { cout << "========" << endl << "CreateSimpXor "; lpvec(children); cout << endl; } ASTVec flat_children; // empty vector ASTVec::const_iterator it_end = children.end(); if (UserFlags.xor_flatten_flag) { flat_children = FlattenKind(XOR, children); } else { flat_children = children; } // sort so that identical nodes occur in sequential runs, followed by // their negations. SortByExprNum(flat_children); ASTNode retval; // This is the C Boolean value of all constant args seen. It is initially // 0. TRUE children cause it to change value. bool accumconst = 0; ASTVec new_children; it_end = flat_children.end(); ASTVec::iterator next_it; for (ASTVec::iterator it = flat_children.begin(); it != it_end; it++) { next_it = it + 1; bool nextexists = (next_it < it_end); if (ASTTrue == *it) { accumconst = !accumconst; } else if (ASTFalse == *it) { // Ignore it } else if (nextexists && (*next_it == *it)) { // x XOR x = FALSE. Skip current, write "false" into next_it // so that it gets tossed, too. *next_it = ASTFalse; } else if (nextexists && (next_it->GetKind() == NOT) && ((*next_it)[0] == *it)) { // x XOR NOT x = TRUE. Skip current, write "true" into next_it // so that it gets tossed, too. *next_it = ASTTrue; } else if (NOT == it->GetKind()) { // If child is (NOT alpha), we can flip accumconst and use alpha. // This is ok because (NOT alpha) == TRUE XOR alpha accumconst = !accumconst; // CreateSimpNot just takes child of not. new_children.push_back(CreateSimpNot(*it)); } else { new_children.push_back(*it); } } // Children should be non-constant. if (new_children.size() < 2) { if (0 == new_children.size()) { // XOR(TRUE, FALSE) -- accumconst will be 1. if (accumconst) { retval = ASTTrue; } else { retval = ASTFalse; } } else { // there is just one child // XOR(x, TRUE) -- accumconst will be 1. if (accumconst) { retval = CreateSimpNot(new_children[0]); } else { retval = new_children[0]; } } } else { // negate first child if accumconst == 1 if (accumconst) { new_children[0] = CreateSimpNot(new_children[0]); } retval = CreateNode(XOR, new_children); } if (_trace_simpbool) { cout << "returns " << retval << endl; } return retval; }
ASTNode BeevMgr::BVConstEvaluator(const ASTNode& t) { ASTNode OutputNode; Kind k = t.GetKind(); if(CheckSolverMap(t,OutputNode)) return OutputNode; OutputNode = t; unsigned int inputwidth = t.GetValueWidth(); unsigned int outputwidth = inputwidth; CBV output = NULL; CBV tmp0 = NULL; CBV tmp1 = NULL; //saving some typing. BVPLUS does not use these variables. if the //input BVPLUS has two nodes, then we want to avoid setting these //variables. if(1 == t.Degree() ){ tmp0 = BVConstEvaluator(t[0]).GetBVConst(); }else if(2 == t.Degree() && k != BVPLUS ) { tmp0 = BVConstEvaluator(t[0]).GetBVConst(); tmp1 = BVConstEvaluator(t[1]).GetBVConst(); } switch(k) { case UNDEFINED: case READ: case WRITE: case SYMBOL: FatalError("BVConstEvaluator: term is not a constant-term",t); break; case BVCONST: //FIXME Handle this special case better OutputNode = t; break; case BVNEG:{ output = CONSTANTBV::BitVector_Create(inputwidth,true); CONSTANTBV::Set_Complement(output,tmp0); OutputNode = CreateBVConst(output,outputwidth); break; } case BVSX: { output = CONSTANTBV::BitVector_Create(inputwidth,true); //unsigned * out0 = BVConstEvaluator(t[0]).GetBVConst(); unsigned t0_width = t[0].GetValueWidth(); if(inputwidth == t0_width) { CONSTANTBV::BitVector_Copy(output, tmp0); OutputNode = CreateBVConst(output, outputwidth); } else { bool topbit_sign = (CONSTANTBV::BitVector_Sign(tmp0) < 0 ); if(topbit_sign){ CONSTANTBV::BitVector_Fill(output); } CONSTANTBV::BitVector_Interval_Copy(output, tmp0, 0, 0, t0_width); OutputNode = CreateBVConst(output, outputwidth); } break; } case BVAND: { output = CONSTANTBV::BitVector_Create(inputwidth,true); CONSTANTBV::Set_Intersection(output,tmp0,tmp1); OutputNode = CreateBVConst(output, outputwidth); break; } case BVOR: { output = CONSTANTBV::BitVector_Create(inputwidth,true); CONSTANTBV::Set_Union(output,tmp0,tmp1); OutputNode = CreateBVConst(output, outputwidth); break; } case BVXOR: { output = CONSTANTBV::BitVector_Create(inputwidth,true); CONSTANTBV::Set_ExclusiveOr(output,tmp0,tmp1); OutputNode = CreateBVConst(output, outputwidth); break; } case BVSUB: { output = CONSTANTBV::BitVector_Create(inputwidth,true); bool carry = false; CONSTANTBV::BitVector_sub(output,tmp0,tmp1,&carry); OutputNode = CreateBVConst(output, outputwidth); break; } case BVUMINUS: { output = CONSTANTBV::BitVector_Create(inputwidth,true); CONSTANTBV::BitVector_Negate(output, tmp0); OutputNode = CreateBVConst(output, outputwidth); break; } case BVEXTRACT: { output = CONSTANTBV::BitVector_Create(inputwidth,true); tmp0 = BVConstEvaluator(t[0]).GetBVConst(); unsigned int hi = GetUnsignedConst(BVConstEvaluator(t[1])); unsigned int low = GetUnsignedConst(BVConstEvaluator(t[2])); unsigned int len = hi-low+1; CONSTANTBV::BitVector_Destroy(output); output = CONSTANTBV::BitVector_Create(len, false); CONSTANTBV::BitVector_Interval_Copy(output, tmp0, 0, low, len); outputwidth = len; OutputNode = CreateBVConst(output, outputwidth); break; } //FIXME Only 2 inputs? case BVCONCAT: { output = CONSTANTBV::BitVector_Create(inputwidth,true); unsigned t0_width = t[0].GetValueWidth(); unsigned t1_width = t[1].GetValueWidth(); CONSTANTBV::BitVector_Destroy(output); output = CONSTANTBV::BitVector_Concat(tmp0, tmp1); outputwidth = t0_width + t1_width; OutputNode = CreateBVConst(output, outputwidth); break; } case BVMULT: { output = CONSTANTBV::BitVector_Create(inputwidth,true); CBV tmp = CONSTANTBV::BitVector_Create(2*inputwidth,true); CONSTANTBV::ErrCode e = CONSTANTBV::BitVector_Multiply(tmp,tmp0,tmp1); if(0 != e) { BVConstEvaluatorError(e,t); } //FIXME WHAT IS MY OUTPUT???? THE SECOND HALF of tmp? //CONSTANTBV::BitVector_Interval_Copy(output, tmp, 0, inputwidth, inputwidth); CONSTANTBV::BitVector_Interval_Copy(output, tmp, 0, 0, inputwidth); OutputNode = CreateBVConst(output, outputwidth); CONSTANTBV::BitVector_Destroy(tmp); break; } case BVPLUS: { output = CONSTANTBV::BitVector_Create(inputwidth,true); bool carry = false; ASTVec c = t.GetChildren(); for(ASTVec::iterator it=c.begin(),itend=c.end();it!=itend;it++) { CBV kk = BVConstEvaluator(*it).GetBVConst(); CONSTANTBV::BitVector_add(output,output,kk,&carry); carry = false; //CONSTANTBV::BitVector_Destroy(kk); } OutputNode = CreateBVConst(output, outputwidth); break; } //FIXME ANOTHER SPECIAL CASE case SBVDIV: case SBVMOD:{ OutputNode = BVConstEvaluator(TranslateSignedDivMod(t)); break; } case BVDIV: case BVMOD: { CBV quotient = CONSTANTBV::BitVector_Create(inputwidth,true); CBV remainder = CONSTANTBV::BitVector_Create(inputwidth,true); // tmp0 is dividend, tmp1 is the divisor //All parameters to BitVector_Div_Pos must be distinct unlike BitVector_Divide //FIXME the contents of the second parameter to Div_Pos is destroyed //As tmp0 is currently the same as the copy belonging to an ASTNode t[0] //this must be copied. tmp0 = CONSTANTBV::BitVector_Clone(tmp0); CONSTANTBV::ErrCode e= CONSTANTBV::BitVector_Div_Pos(quotient,tmp0,tmp1,remainder); CONSTANTBV::BitVector_Destroy(tmp0); if(0 != e) { //error printing if(counterexample_checking_during_refinement) { output = CONSTANTBV::BitVector_Create(inputwidth,true); OutputNode = CreateBVConst(output, outputwidth); bvdiv_exception_occured = true; // CONSTANTBV::BitVector_Destroy(output); break; } else { BVConstEvaluatorError(e,t); } } //end of error printing //FIXME Not very standard in the current scheme if(BVDIV == k){ OutputNode = CreateBVConst(quotient, outputwidth); CONSTANTBV::BitVector_Destroy(remainder); }else{ OutputNode = CreateBVConst(remainder, outputwidth); CONSTANTBV::BitVector_Destroy(quotient); } break; } case ITE: if(ASTTrue == t[0]) OutputNode = BVConstEvaluator(t[1]); else if(ASTFalse == t[0]) OutputNode = BVConstEvaluator(t[2]); else FatalError("BVConstEvaluator: ITE condiional must be either TRUE or FALSE:",t); break; case EQ: if(CONSTANTBV::BitVector_equal(tmp0,tmp1)) OutputNode = ASTTrue; else OutputNode = ASTFalse; break; case NEQ: if(!CONSTANTBV::BitVector_equal(tmp0,tmp1)) OutputNode = ASTTrue; else OutputNode = ASTFalse; break; case BVLT: if(-1 == CONSTANTBV::BitVector_Lexicompare(tmp0,tmp1)) OutputNode = ASTTrue; else OutputNode = ASTFalse; break; case BVLE: { int comp = CONSTANTBV::BitVector_Lexicompare(tmp0,tmp1); if(comp <= 0) OutputNode = ASTTrue; else OutputNode = ASTFalse; break; } case BVGT: if(1 == CONSTANTBV::BitVector_Lexicompare(tmp0,tmp1)) OutputNode = ASTTrue; else OutputNode = ASTFalse; break; case BVGE: { int comp = CONSTANTBV::BitVector_Lexicompare(tmp0,tmp1); if(comp >= 0) OutputNode = ASTTrue; else OutputNode = ASTFalse; break; } case BVSLT: if(-1 == CONSTANTBV::BitVector_Compare(tmp0,tmp1)) OutputNode = ASTTrue; else OutputNode = ASTFalse; break; case BVSLE: { signed int comp = CONSTANTBV::BitVector_Compare(tmp0,tmp1); if(comp <= 0) OutputNode = ASTTrue; else OutputNode = ASTFalse; break; } case BVSGT: if(1 == CONSTANTBV::BitVector_Compare(tmp0,tmp1)) OutputNode = ASTTrue; else OutputNode = ASTFalse; break; case BVSGE: { int comp = CONSTANTBV::BitVector_Compare(tmp0,tmp1); if(comp >= 0) OutputNode = ASTTrue; else OutputNode = ASTFalse; break; } default: FatalError("BVConstEvaluator: The input kind is not supported yet:",t); break; } /* if(BVCONST != k){ cerr<<inputwidth<<endl; cerr<<"------------------------"<<endl; t.LispPrint(cerr); cerr<<endl; OutputNode.LispPrint(cerr); cerr<<endl<<"------------------------"<<endl; } */ UpdateSolverMap(t,OutputNode); //UpdateSimplifyMap(t,OutputNode,false); return OutputNode; }
void SortByArith(ASTVec& v) { sort(v.begin(), v.end(), arithless); }
void SortByExprNum(ASTVec& v) { sort(v.begin(), v.end(), exprless); }