bool CNF::redundant(const Watched& ws) const { return ( (ws.isBinary() && ws.red()) || (ws.isTri() && ws.red()) || (ws.isClause() && clAllocator.getPointer(ws.getOffset())->red() ) ); }
bool CNF::redundant(const Watched& ws) const { return ( (ws.isBin() && ws.red()) || (ws.isTri() && ws.red()) || (ws.isClause() && cl_alloc.ptr(ws.get_offset())->red() ) ); }
bool CNF::redundant_or_removed(const Watched& ws) const { if (ws.isBin() || ws.isTri()) { return ws.red(); } assert(ws.isClause()); const Clause* cl = cl_alloc.ptr(ws.get_offset()); return cl->red() || cl->getRemoved(); }
bool CNF::redundant_or_removed(const Watched& ws) const { if (ws.isBinary() || ws.isTri()) { return ws.red(); } assert(ws.isClause()); const Clause* cl = clAllocator.getPointer(ws.getOffset()); return cl->red() || cl->getRemoved(); }
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; }
Lit HyperEngine::prop_larger_than_bin_cl_dfs( StampType stampType , PropBy& confl , Lit& root , bool& restart ) { PropResult ret = PROP_NOTHING; const Lit p = toPropNorm.top(); watch_subarray ws = watches[~p]; propStats.bogoProps += 1; Watched* i = ws.begin(); Watched* j = ws.begin(); Watched* end = ws.end(); for(; i != end; i++) { propStats.bogoProps += 1; if (i->isBin()) { *j++ = *i; continue; } if (i->isTri()) { *j++ = *i; ret = prop_tri_clause_with_acestor_info(i, p, confl); if (ret == PROP_SOMETHING || ret == PROP_FAIL) { i++; break; } else { assert(ret == PROP_NOTHING); continue; } } if (i->isClause()) { ret = prop_normal_cl_with_ancestor_info(i, j, p, confl); if (ret == PROP_SOMETHING || ret == PROP_FAIL) { i++; break; } else { assert(ret == PROP_NOTHING); continue; } } } while(i != end) *j++ = *i++; ws.shrink_(end-j); switch(ret) { case PROP_FAIL: close_all_timestamps(stampType); return analyzeFail(confl); case PROP_SOMETHING: propStats.bogoProps += 8; stamp.stampingTime++; #ifdef DEBUG_STAMPING cout << "From (long-reduced) " << p << " enqueued << " << trail.back() << " for stamp.stampingTime " << stamp.stampingTime << endl; #endif stamp.tstamp[trail.back().toInt()].start[stampType] = stamp.stampingTime; if (stampType == STAMP_IRRED) { //Root for literals propagated afterwards will be this literal root = trail.back(); toPropRedBin.push(trail.back()); } toPropNorm.push(trail.back()); toPropBin.push(trail.back()); propStats.bogoProps += ws.size()*8; restart = true; return lit_Undef; case PROP_NOTHING: break; default: assert(false); break; } //Finished with this literal propStats.bogoProps += ws.size()*8; toPropNorm.pop(); return lit_Undef; }
Lit HyperEngine::propagate_bfs(const uint64_t timeout) { timedOutPropagateFull = false; propStats.otfHyperPropCalled++; #ifdef VERBOSE_DEBUG_FULLPROP cout << "Prop full BFS started" << endl; #endif PropBy confl; //Assert startup: only 1 enqueued, uselessBin is empty assert(uselessBin.empty()); //assert(decisionLevel() == 1); //The toplevel decision has to be set specifically //If we came here as part of a backtrack to decision level 1, then //this is already set, and there is no need to set it if (trail.size() - trail_lim.back() == 1) { //Set up root node Lit root = trail[qhead]; varData[root.var()].reason = PropBy(~lit_Undef, false, false, false); } uint32_t nlBinQHead = qhead; uint32_t lBinQHead = qhead; needToAddBinClause.clear(); PropResult ret = PROP_NOTHING; start: //Early-abort if too much time was used (from prober) if (propStats.otfHyperTime + propStats.bogoProps > timeout) { timedOutPropagateFull = true; return lit_Undef; } //Propagate binary irred while (nlBinQHead < trail.size()) { const Lit p = trail[nlBinQHead++]; watch_subarray_const ws = watches[~p]; propStats.bogoProps += 1; for(const Watched *k = ws.begin(), *end = ws.end() ; k != end ; k++ ) { //If something other than irred binary, skip if (!k->isBin() || k->red()) continue; ret = prop_bin_with_ancestor_info(p, k, confl); if (ret == PROP_FAIL) return analyzeFail(confl); } propStats.bogoProps += ws.size()*4; } //Propagate binary redundant ret = PROP_NOTHING; while (lBinQHead < trail.size()) { const Lit p = trail[lBinQHead]; watch_subarray_const ws = watches[~p]; propStats.bogoProps += 1; size_t done = 0; for(const Watched *k = ws.begin(), *end = ws.end(); k != end; k++, done++) { //If something other than redundant binary, skip if (!k->isBin() || !k->red()) continue; ret = prop_bin_with_ancestor_info(p, k, confl); if (ret == PROP_FAIL) { return analyzeFail(confl); } else if (ret == PROP_SOMETHING) { propStats.bogoProps += done*4; goto start; } else { assert(ret == PROP_NOTHING); } } lBinQHead++; propStats.bogoProps += done*4; } ret = PROP_NOTHING; while (qhead < trail.size()) { const Lit p = trail[qhead]; watch_subarray ws = watches[~p]; propStats.bogoProps += 1; Watched* i = ws.begin(); Watched* j = ws.begin(); Watched* end = ws.end(); for(; i != end; i++) { if (i->isBin()) { *j++ = *i; continue; } if (i->isTri()) { *j++ = *i; ret = prop_tri_clause_with_acestor_info(i, p, confl); if (ret == PROP_SOMETHING || ret == PROP_FAIL) { i++; break; } else { assert(ret == PROP_NOTHING); continue; } } if (i->isClause()) { ret = prop_normal_cl_with_ancestor_info(i, j, p, confl); if (ret == PROP_SOMETHING || ret == PROP_FAIL) { i++; break; } else { assert(ret == PROP_NOTHING); continue; } } } propStats.bogoProps += ws.size()*4; while(i != end) *j++ = *i++; ws.shrink_(end-j); if (ret == PROP_FAIL) { return analyzeFail(confl); } else if (ret == PROP_SOMETHING) { propStats.bogoProps += ws.size()*4; goto start; } qhead++; propStats.bogoProps += ws.size()*4; } return lit_Undef; }
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; }