void applyAxiomToSAT(SATSolver & SatSolver, AxiomToBe& toBe, ToSATBase::ASTNodeToSATVar & satVar) { Minisat::Var a = getEquals(SatSolver, toBe.index0, toBe.index1, satVar, LEFT_ONLY); Minisat::Var b = getEquals(SatSolver, toBe.value0, toBe.value1, satVar, RIGHT_ONLY); SATSolver::vec_literals satSolverClause; satSolverClause.push(SATSolver::mkLit(a, true)); satSolverClause.push(SATSolver::mkLit(b, false)); SatSolver.addClause(satSolverClause); }
void ToSATAIG::add_cnf_to_solver(SATSolver& satSolver, Cnf_Dat_t* cnfData) { bm->GetRunTimes()->start(RunTimes::SendingToSAT); // Create a new sat variable for each of the variables in the CNF. int satV = satSolver.nVars(); for (int i = 0; i < cnfData->nVars - satV; i++) satSolver.newVar(); SATSolver::vec_literals satSolverClause; for (int i = 0; i < cnfData->nClauses; i++) { satSolverClause.clear(); for (int* pLit = cnfData->pClauses[i], *pStop = cnfData->pClauses[i + 1]; pLit < pStop; pLit++) { uint32_t var = (*pLit) >> 1; assert((var < satSolver.nVars())); Minisat::Lit l = SATSolver::mkLit(var, (*pLit) & 1); satSolverClause.push(l); } satSolver.addClause(satSolverClause); if (!satSolver.okay()) break; } bm->GetRunTimes()->stop(RunTimes::SendingToSAT); }
// 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); } }