bool GateFinder::find_pair_for_and_gate_reduction_tri( const Watched& ws , const OrGate& gate , const bool only_irred , Watched& found_pair ) { //Only long clauses if (!ws.isTri()) return false; if (ws.red() && only_irred) { //cout << "Not even possible, this clause cannot match any other" << endl; return false; } //Check that we are not removing irred info based on learnt gate if (!ws.red() && gate.red) return false; if (!check_seen_and_gate_against_lit(ws.lit2(), gate) || !check_seen_and_gate_against_lit(ws.lit3(), gate)) { return false; } seen[ws.lit2().toInt()] = 1; seen[ws.lit3().toInt()] = 1; const bool ret = findAndGateOtherCl_tri( solver->watches[~(gate.lit2)] , gate.red , only_irred , found_pair ); seen[ws.lit2().toInt()] = 0; seen[ws.lit3().toInt()] = 0; return ret; }
bool PropEngine::propagate_tri_clause_occur(const Watched& ws) { const lbool val2 = value(ws.lit2()); const lbool val3 = value(ws.lit3()); if (val2 == l_True || val3 == l_True ) { return true; } if (val2 == l_Undef && val3 == l_Undef ) { return true; } if (val2 == l_False && val3 == l_False ) { ok = false; return false; } #ifdef STATS_NEEDED if (ws.red()) propStats.propsTriRed++; else propStats.propsTriIrred++; #endif if (val2 == l_Undef) { enqueue(ws.lit2()); } else { enqueue(ws.lit3()); } return true; }
string CNF::watched_to_string(Lit otherLit, const Watched& ws) const { std::stringstream ss; switch(ws.getType()) { case watch_binary_t: ss << otherLit << ", " << ws.lit2(); if (ws.red()) { ss << "(red)"; } break; case CMSat::watch_tertiary_t: ss << otherLit << ", " << ws.lit2() << ", " << ws.lit3(); if (ws.red()) { ss << "(red)"; } break; case watch_clause_t: { const Clause* cl = cl_alloc.ptr(ws.get_offset()); for(size_t i = 0; i < cl->size(); i++) { ss << (*cl)[i]; if (i + 1 < cl->size()) ss << ", "; } if (cl->red()) { ss << "(red)"; } break; } default: assert(false); break; } return ss.str(); }
void FeaturesCalc::for_one_clause( const Watched& cl , const Lit lit , Function func_each_cl , Function2 func_each_lit ) const { unsigned neg_vars = 0; unsigned pos_vars = 0; unsigned size = 0; switch (cl.getType()) { case CMSat::watch_binary_t: { if (cl.red()) { //only irred cls break; } if (lit > cl.lit2()) { //only count once break; } pos_vars += !lit.sign(); pos_vars += !cl.lit2().sign(); size = 2; neg_vars = size - pos_vars; func_each_cl(size, pos_vars, neg_vars); func_each_lit(lit, size, pos_vars, neg_vars); func_each_lit(cl.lit2(), size, pos_vars, neg_vars); break; } case CMSat::watch_tertiary_t: { if (cl.red()) { //only irred cls break; } if (lit > cl.lit2()) { //only count once break; } assert(cl.lit2() < cl.lit3()); pos_vars += !lit.sign(); pos_vars += !cl.lit2().sign(); pos_vars += !cl.lit3().sign(); size = 3; neg_vars = size - pos_vars; func_each_cl(size, pos_vars, neg_vars); func_each_lit(lit, size, pos_vars, neg_vars); func_each_lit(cl.lit2(), size, pos_vars, neg_vars); func_each_lit(cl.lit3(), size, pos_vars, neg_vars); break; } case CMSat::watch_clause_t: { const Clause& clause = *solver->cl_alloc.ptr(cl.get_offset()); if (clause.red()) { //only irred cls break; } if (clause[0] < clause[1]) { //only count once break; } for (const Lit cl_lit : clause) { pos_vars += !cl_lit.sign(); } size = clause.size(); neg_vars = size - pos_vars; func_each_cl(size, pos_vars, neg_vars); for (const Lit cl_lit : clause) { func_each_lit(cl_lit, size, pos_vars, neg_vars); } break; } case CMSat::watch_idx_t: { // This should never be here assert(false); exit(-1); break; } } }
void CompHandler::moveClausesImplicit( SATSolver* newSolver , const uint32_t comp , const vector<uint32_t>& vars ) { numRemovedHalfIrred = 0; numRemovedHalfRed = 0; numRemovedThirdIrred = 0; numRemovedThirdRed = 0; for(const uint32_t var: vars) { for(unsigned sign = 0; sign < 2; ++sign) { const Lit lit = Lit(var, sign); watch_subarray ws = solver->watches[lit]; //If empty, nothing to to, skip if (ws.empty()) { continue; } Watched *i = ws.begin(); Watched *j = i; for (Watched *end2 = ws.end() ; i != end2 ; ++i ) { //At least one variable inside comp if (i->isBin() && (compFinder->getVarComp(lit.var()) == comp || compFinder->getVarComp(i->lit2().var()) == comp ) ) { move_binary_clause(newSolver, comp, i, lit); continue; } if (i->isTri() && (compFinder->getVarComp(lit.var()) == comp || compFinder->getVarComp(i->lit2().var()) == comp || compFinder->getVarComp(i->lit3().var()) == comp ) ) { move_tri_clause(newSolver, comp, i, lit); continue; } *j++ = *i; } ws.shrink_(i-j); }} assert(numRemovedHalfIrred % 2 == 0); solver->binTri.irredBins -= numRemovedHalfIrred/2; assert(numRemovedThirdIrred % 3 == 0); solver->binTri.irredTris -= numRemovedThirdIrred/3; assert(numRemovedHalfRed % 2 == 0); solver->binTri.redBins -= numRemovedHalfRed/2; assert(numRemovedThirdRed % 3 == 0); solver->binTri.redTris -= numRemovedThirdRed/3; }
bool Distiller::distill_tri_irred_cls() { if (solver->conf.verbosity >= 6) { cout << "c Doing distill for tri irred clauses" << endl; } //solver->watches.size()-1 would overflow if (solver->watches.size() == 0) { return solver->ok; } uint64_t origShorten = runStats.numClShorten; uint64_t origLitRem = runStats.numLitsRem; const double myTime = cpuTime(); uint64_t maxNumProps = 2LL*1000LL*solver->conf.distill_time_limitM *solver->conf.global_timeout_multiplier; uint64_t oldBogoProps = solver->propStats.bogoProps; size_t origTrailSize = solver->trail_size(); //Randomize start in the watchlist size_t upI; upI = solver->mtrand.randInt(solver->watches.size()-1); size_t numDone = 0; for (; numDone < solver->watches.size() ; upI = (upI +1) % solver->watches.size(), numDone++ ) { if (solver->propStats.bogoProps-oldBogoProps + extraTime > maxNumProps || solver->must_interrupt_asap() ) { break; } Lit lit = Lit::toLit(upI); for (size_t i = 0; i < solver->watches[upI].size(); i++) { if (solver->propStats.bogoProps-oldBogoProps + extraTime > maxNumProps) { break; } Watched ws = solver->watches[upI][i]; //Only irred TRI and each TRI only once if (ws.isTri() && !ws.red() && lit < ws.lit2() && ws.lit2() < ws.lit3() ) { uselessLits.clear(); lits.resize(3); lits[0] = lit; lits[1] = ws.lit2(); lits[2] = ws.lit3(); try_distill_clause_and_return_new( CL_OFFSET_MAX , ws.red() , 2 ); //We could have modified the watchlist, better exit now break; } } if (!solver->okay()) { break; } } int64_t diff_bogoprops = (int64_t)solver->propStats.bogoProps-(int64_t)oldBogoProps; const bool time_out = diff_bogoprops + extraTime > maxNumProps; const double time_used = cpuTime() - myTime; const double time_remain = 1.0 - float_div(diff_bogoprops + extraTime, maxNumProps); if (solver->conf.verbosity >= 3) { cout << "c [distill] tri irred" << " shorten: " << runStats.numClShorten - origShorten << " lit-rem: " << runStats.numLitsRem - origLitRem << " 0-depth ass: " << solver->trail_size() - origTrailSize << solver->conf.print_times(time_used, time_out, time_remain) << endl; } if (solver->sqlStats) { solver->sqlStats->time_passed( solver , "distill tri irred" , time_used , time_out , time_remain ); } runStats.zeroDepthAssigns = solver->trail_size() - origTrailSize; return solver->ok; }