void Manager::View::cleanClause(Clause & clause) { exprView.sort(clause.begin(), clause.end()); for (Clause::iterator it = clause.begin(); it != clause.end(); ) { if (*it == exprView.btrue()) // [true lit] throw Trivial(true); else if (*it == exprView.bfalse()) // [false lit] clause.erase(it); else if (it+1 != clause.end()) { if (*it == *(it+1)) { // [repetition of lit] clause.erase(it); } else if (*it == exprView.apply(Expr::Not, *(it+1))) // [var with both phases] // Relies on how Expr handles negation, so possibly a hack. // However, I meant for this property to be usable, so it // will be maintained. throw Trivial(true); else it++; } else it++; } if (clause.size() == 0) // empty clause throw Trivial(false); }
void HyperEngine::add_hyper_bin(const Lit p, const Clause& cl) { assert(value(p.var()) == l_Undef); #ifdef VERBOSE_DEBUG_FULLPROP cout << "Enqueing " << p << " with ancestor clause: " << cl << endl; #endif currAncestors.clear(); size_t i = 0; for (Clause::const_iterator it = cl.begin(), end = cl.end() ; it != end ; ++it, i++ ) { if (*it != p) { assert(value(*it) == l_False); if (varData[it->var()].level != 0) currAncestors.push_back(~*it); } } add_hyper_bin(p); }
void BacktrackEnumerator::undoLevel(Solver& s) { while (!nogoods_.empty() && nogoods_.back().second >= s.decisionLevel()) { Clause* c = (Clause*)nogoods_.back().first; nogoods_.pop_back(); *c->end() = posLit(0); c->removeWatches(s); c->destroy(); } }
PropResult PropEngine::prop_normal_helper( Clause& c , ClOffset offset , watch_subarray::iterator &j , const Lit p ) { #ifdef STATS_NEEDED c.stats.clause_looked_at++; c.stats.visited_literals++; #endif // Make sure the false literal is data[1]: if (c[0] == ~p) { std::swap(c[0], c[1]); } assert(c[1] == ~p); // If 0th watch is true, then clause is already satisfied. if (value(c[0]) == l_True) { *j = Watched(offset, c[0]); j++; return PROP_NOTHING; } // Look for new watch: #ifdef STATS_NEEDED uint32_t numLitVisited = 0; #endif for (Lit *k = c.begin() + 2, *end2 = c.end() ; k != end2 ; k++ #ifdef STATS_NEEDED , numLitVisited++ #endif ) { //Literal is either unset or satisfied, attach to other watchlist if (value(*k) != l_False) { c[1] = *k; #ifdef STATS_NEEDED //propStats.bogoProps += numLitVisited/10; c.stats.visited_literals+= numLitVisited; #endif *k = ~p; watches[c[1].toInt()].push(Watched(offset, c[0])); return PROP_NOTHING; } } #ifdef STATS_NEEDED //propStats.bogoProps += numLitVisited/10; c.stats.visited_literals+= numLitVisited; #endif return PROP_TODO; }
Requirement& Requirement::operator&=(DualClause rhs) { // Treat "falsity" like an empty clause if ( rhs == DualClause::falsity ) { return *this &= Clause(); } // Now we can go through the dualclause like a // list. (DualClause::truth is just an empty DualClause) while ( rhs.size() != 0 ) { // Carefully preserve (steal) the allocated memory for *rhs.begin(). Clause unitClause; unitClause.splice(unitClause.end(), rhs, rhs.begin()); // DualClauses are stored with their elements negated. Fix it. *unitClause.begin() = ~*unitClause.begin(); // Add to the requirement *this &= move(unitClause); } return *this; }
void DistillerLongWithImpl::strsub_with_cache_and_watch( bool alsoStrengthen , Clause& cl ) { //Go through each literal and subsume/strengthen with it Lit *lit2 = cl.begin(); lit2++; for (const Lit *lit = cl.begin(), *end = cl.end() ; lit != end && !isSubsumed ; lit++, lit2++ ) { if (lit2 < end) { solver->watches.prefetch(lit2->toInt()); } bool subsumed = str_and_sub_clause_with_cache(*lit, alsoStrengthen); if (subsumed) break; str_and_sub_using_watch(cl, *lit, alsoStrengthen); } assert(lits2.size() > 1); }
/** @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; }