/** @brief Cleans clauses from failed literals/removes satisfied clauses from cs May change solver->ok to FALSE (!) */ void CompleteDetachReatacher::cleanAndAttachClauses( vector<ClOffset>& cs , bool removeStatsFirst ) { assert(!solver->drup->something_delayed()); vector<ClOffset>::iterator i = cs.begin(); vector<ClOffset>::iterator j = i; for (vector<ClOffset>::iterator end = cs.end(); i != end; i++) { Clause* cl = solver->clAllocator.getPointer(*i); //Handle stat removal if need be if (removeStatsFirst) { if (cl->red()) { solver->litStats.redLits -= cl->size(); } else { solver->litStats.irredLits -= cl->size(); } } if (cleanClause(cl)) { solver->attachClause(*cl); *j++ = *i; } else { solver->clAllocator.clauseFree(*i); } } cs.resize(cs.size() - (i-j)); }
PropResult PropEngine::handle_normal_prop_fail( Clause& c , ClOffset offset , PropBy& confl ) { confl = PropBy(offset); #ifdef VERBOSE_DEBUG_FULLPROP cout << "Conflict from "; for(size_t i = 0; i < c.size(); i++) { cout << c[i] << " , "; } cout << endl; #endif //VERBOSE_DEBUG_FULLPROP //Update stats #ifdef STATS_NEEDED c.stats.conflicts_made++; c.stats.sum_of_branch_depth_conflict += decisionLevel() + 1; #endif if (c.red()) lastConflictCausedBy = ConflCausedBy::longred; else lastConflictCausedBy = ConflCausedBy::longirred; qhead = trail.size(); return PROP_FAIL; }
void PropEngine::attachClause( const Clause& c , const bool checkAttach ) { assert(c.size() > 3); if (checkAttach) { assert(value(c[0]) == l_Undef); assert(value(c[1]) == l_Undef || value(c[1]) == l_False); } if (c.red() && red_long_cls_is_reducedb(c)) { num_red_cls_reducedb++; } #ifdef DEBUG_ATTACH for (uint32_t i = 0; i < c.size(); i++) { assert(varData[c[i].var()].removed == Removed::none); } #endif //DEBUG_ATTACH const ClOffset offset = cl_alloc.get_offset(&c); const Lit blocked_lit = find_good_blocked_lit(c); watches[c[0].toInt()].push(Watched(offset, blocked_lit)); watches[c[1].toInt()].push(Watched(offset, blocked_lit)); }
void ClauseAllocator::updateAllOffsetsAndPointers( Solver* solver , const vector<ClOffset>& offsets ) { //Must be at toplevel, otherwise propBy reset will not work //and also, detachReattacher will fail assert(solver->decisionLevel() == 0); //We are at decision level 0, so we can reset all PropBy-s for (auto& vdata: solver->varData) { vdata.reason = PropBy(); } //Detach long clauses CompleteDetachReatacher detachReattach(solver); detachReattach.detach_nonbins_nontris(); //Make sure all non-freed clauses were accessible from solver const size_t origNumClauses = solver->longIrredCls.size() + solver->longRedCls.size(); if (origNumClauses != offsets.size()) { std::cerr << "ERROR: Not all non-freed clauses are accessible from Solver" << endl << " This usually means that a clause was not freed, i.e. a mem leak" << endl << " no. clauses accessible from solver: " << origNumClauses << endl << " no. clauses non-freed: " << offsets.size() << endl; assert(origNumClauses == offsets.size()); std::exit(-1); } //Clear clauses solver->longIrredCls.clear(); solver->longRedCls.clear(); //Add back to the solver the correct red & irred clauses for(auto offset: offsets) { Clause* cl = ptr(offset); assert(!cl->freed()); //Put it in the right bucket if (cl->red()) { solver->longRedCls.push_back(offset); } else { solver->longIrredCls.push_back(offset); } } //Finally, reattach long clauses detachReattach.reattachLongs(); }
void PropEngine::update_glue(Clause& c) { if (c.red() && c.stats.glue > 2 && conf.update_glues_on_prop ) { const uint32_t new_glue = calc_glue_using_seen2(c); if (new_glue < c.stats.glue && new_glue < conf.protect_clause_if_imrpoved_glue_below_this_glue_for_one_turn ) { if (red_long_cls_is_reducedb(c)) { num_red_cls_reducedb--; } c.stats.ttl = 1; } c.stats.glue = std::min(c.stats.glue, new_glue); } }
bool DistillerLongWithImpl::remove_or_shrink_clause(Clause& cl, ClOffset& offset) { //Remove or shrink clause timeAvailable -= (long)cl.size()*10; cache_based_data.remLitCache += thisRemLitCache; cache_based_data.remLitBinTri += thisRemLitBinTri; tmpStats.shrinked++; timeAvailable -= (long)lits.size()*2 + 50; Clause* c2 = solver->add_clause_int(lits, cl.red(), cl.stats); if (c2 != NULL) { solver->detachClause(offset); solver->cl_alloc.clauseFree(offset); offset = solver->cl_alloc.get_offset(c2); return false; } //Implicit clause or non-existent after addition, remove return true; }
Clause* BVA::find_cl_for_bva( const vector<Lit>& torem , const bool red ) const { Clause* cl = NULL; for(const Lit lit: torem) { seen[lit.toInt()] = 1; } for(Watched w: solver->watches[torem[0]]) { if (!w.isClause()) continue; cl = solver->cl_alloc.ptr(w.get_offset()); if (cl->red() != red || cl->size() != torem.size() ) { continue; } #ifdef SLOW_DEBUG assert(!cl->freed()); assert(!cl->getRemoved()); #endif bool OK = true; for(const Lit lit: *cl) { if (seen[lit.toInt()] == 0) { OK = false; break; } } if (OK) break; } for(const Lit lit: torem) { seen[lit.toInt()] = 0; } assert(cl != NULL); return cl; }
/** @brief Helper function for replace_set() */ bool VarReplacer::handleUpdatedClause( Clause& c , const Lit origLit1 , const Lit origLit2 ) { bool satisfied = false; std::sort(c.begin(), c.end()); Lit p; uint32_t i, j; const uint32_t origSize = c.size(); for (i = j = 0, p = lit_Undef; i != origSize; i++) { assert(solver->varData[c[i].var()].removed == Removed::none); if (solver->value(c[i]) == l_True || c[i] == ~p) { satisfied = true; break; } else if (solver->value(c[i]) != l_False && c[i] != p) c[j++] = p = c[i]; } c.shrink(i - j); c.setChanged(); solver->detachModifiedClause(origLit1, origLit2, origSize, &c); #ifdef VERBOSE_DEBUG cout << "clause after replacing: " << c << endl; #endif if (satisfied) { (*solver->drup) << findelay; return true; } (*solver->drup) << c << fin << findelay; switch(c.size()) { case 0: solver->ok = false; return true; case 1 : solver->enqueue(c[0]); #ifdef STATS_NEEDED solver->propStats.propsUnit++; #endif solver->ok = (solver->propagate().isNULL()); runStats.removedLongLits += origSize; return true; case 2: solver->attachBinClause(c[0], c[1], c.red()); runStats.removedLongLits += origSize; return true; case 3: solver->attachTriClause(c[0], c[1], c[2], c.red()); runStats.removedLongLits += origSize; return true; default: solver->attachClause(c); runStats.removedLongLits += origSize - c.size(); return false; } assert(false); return false; }
bool DistillerLongWithImpl::subsume_clause_with_watch( const Lit lit , Watched* wit , const Clause& cl ) { //Subsumption w/ bin if (wit->isBin() && seen2[wit->lit2().toInt()] ) { //If subsuming irred with redundant, make the redundant into irred if (wit->red() && !cl.red()) { wit->setRed(false); timeAvailable -= (long)solver->watches[wit->lit2()].size()*3; findWatchedOfBin(solver->watches, wit->lit2(), lit, true).setRed(false); solver->binTri.redBins--; solver->binTri.irredBins++; } cache_based_data.subBinTri++; isSubsumed = true; return true; } //Extension w/ bin if (wit->isBin() && !wit->red() && !seen2[(~(wit->lit2())).toInt()] ) { seen2[(~(wit->lit2())).toInt()] = 1; lits2.push_back(~(wit->lit2())); } if (wit->isTri()) { assert(wit->lit2() < wit->lit3()); } //Subsumption w/ tri if (wit->isTri() && lit < wit->lit2() //Check only one instance of the TRI clause && seen2[wit->lit2().toInt()] && seen2[wit->lit3().toInt()] ) { //If subsuming irred with redundant, make the redundant into irred if (!cl.red() && wit->red()) { wit->setRed(false); timeAvailable -= (long)solver->watches[wit->lit2()].size()*3; timeAvailable -= (long)solver->watches[wit->lit3()].size()*3; findWatchedOfTri(solver->watches, wit->lit2(), lit, wit->lit3(), true).setRed(false); findWatchedOfTri(solver->watches, wit->lit3(), lit, wit->lit2(), true).setRed(false); solver->binTri.redTris--; solver->binTri.irredTris++; } cache_based_data.subBinTri++; isSubsumed = true; return true; } //Extension w/ tri (1) if (wit->isTri() && lit < wit->lit2() //Check only one instance of the TRI clause && !wit->red() && seen2[wit->lit2().toInt()] && !seen2[(~(wit->lit3())).toInt()] ) { seen2[(~(wit->lit3())).toInt()] = 1; lits2.push_back(~(wit->lit3())); } //Extension w/ tri (2) if (wit->isTri() && lit < wit->lit2() //Check only one instance of the TRI clause && !wit->red() && !seen2[(~(wit->lit2())).toInt()] && seen2[wit->lit3().toInt()] ) { seen2[(~(wit->lit2())).toInt()] = 1; lits2.push_back(~(wit->lit2())); } return false; }