string bvconstToString(const ASTNode& n) { assert (n.GetKind() == BVCONST); std::stringstream output; output << *n.GetBVConst(); return output.str(); }
void outputBitVecSMTLIB2(const ASTNode n, ostream& os) { const Kind k = n.GetKind(); const ASTVec &c = n.GetChildren(); ASTNode op; if (BITVECTOR == k) { op = c[0]; } else if (BVCONST == k) { op = n; } else FatalError("nsadfsdaf"); // CONSTANTBV::BitVector_to_Dec returns a signed representation by default. // Prepend with zero to convert to unsigned. os << "(_ bv"; CBV unsign = CONSTANTBV::BitVector_Concat( n.GetSTPMgr()->CreateZeroConst(1).GetBVConst(), op.GetBVConst()); unsigned char * str = CONSTANTBV::BitVector_to_Dec(unsign); CONSTANTBV::BitVector_Destroy(unsign); os << str << " " << op.GetValueWidth() << ")"; CONSTANTBV::BitVector_Dispose(str); }
//accepts 64 bit BVConst and sign extends it static unsigned long long int SXBVConst64(const ASTNode& t) { unsigned long long int c = t.GetBVConst(); unsigned int len = t.GetValueWidth(); unsigned long long int mask = 1; mask = mask << len-1; bool TopBit = (c & mask) ? true : false; if(!TopBit) return c; unsigned long long int sign = 0xffffffffffffffffLL; sign = sign << len-1; return (c | sign); }
// This function adds the clauses to constrain that "a" and "b" equal a fresh // variable // (which it returns). // Because it's used to create array axionms (a=b)-> (c=d), it can be // used to only add one of the two polarities. Minisat::Var getEquals(SATSolver& SatSolver, const ASTNode& a, const ASTNode& b, ToSATBase::ASTNodeToSATVar& satVar, Polarity polary = BOTH) { const unsigned width = a.GetValueWidth(); assert(width == b.GetValueWidth()); assert(!a.isConstant() || !b.isConstant()); vector<unsigned> v_a; vector<unsigned> v_b; getSatVariables(a, v_a, SatSolver, satVar); getSatVariables(b, v_b, SatSolver, satVar); // The only time v_a or v_b will be empty is if "a" resp. "b" is a constant. if (v_a.size() == width && v_b.size() == width) { SATSolver::vec_literals all; const int result = SatSolver.newVar(); for (unsigned i = 0; i < width; i++) { SATSolver::vec_literals s; if (polary != RIGHT_ONLY) { int nv0 = SatSolver.newVar(); s.push(SATSolver::mkLit(v_a[i], true)); s.push(SATSolver::mkLit(v_b[i], true)); s.push(SATSolver::mkLit(nv0, false)); SatSolver.addClause(s); s.clear(); s.push(SATSolver::mkLit(v_a[i], false)); s.push(SATSolver::mkLit(v_b[i], false)); s.push(SATSolver::mkLit(nv0, false)); SatSolver.addClause(s); s.clear(); all.push(SATSolver::mkLit(nv0, true)); } if (polary != LEFT_ONLY) { s.push(SATSolver::mkLit(v_a[i], true)); s.push(SATSolver::mkLit(v_b[i], false)); s.push(SATSolver::mkLit(result, true)); SatSolver.addClause(s); s.clear(); s.push(SATSolver::mkLit(v_a[i], false)); s.push(SATSolver::mkLit(v_b[i], true)); s.push(SATSolver::mkLit(result, true)); SatSolver.addClause(s); s.clear(); } } if (all.size() > 0) { all.push(SATSolver::mkLit(result, false)); SatSolver.addClause(all); } return result; } else if ((v_a.size() == 0) ^ (v_b.size() == 0)) { ASTNode constant = a.isConstant() ? a : b; vector<unsigned> vec = v_a.size() == 0 ? v_b : v_a; assert(constant.isConstant()); assert(vec.size() == width); SATSolver::vec_literals all; const int result = SatSolver.newVar(); all.push(SATSolver::mkLit(result, false)); CBV v = constant.GetBVConst(); for (unsigned i = 0; i < width; i++) { if (polary != RIGHT_ONLY) { if (CONSTANTBV::BitVector_bit_test(v, i)) all.push(SATSolver::mkLit(vec[i], true)); else all.push(SATSolver::mkLit(vec[i], false)); } if (polary != LEFT_ONLY) { SATSolver::vec_literals p; p.push(SATSolver::mkLit(result, true)); if (CONSTANTBV::BitVector_bit_test(v, i)) p.push(SATSolver::mkLit(vec[i], false)); else p.push(SATSolver::mkLit(vec[i], true)); SatSolver.addClause(p); } } if (all.size() > 1) SatSolver.addClause(all); return result; } else { FatalError("Unexpected, both must be constants.."); exit(-1); } }