Example #1
0
void ClauseCleaner::cleanClauses(vec<Clause*>& cs, ClauseSetType type, const uint32_t limit)
{
    assert(solver.decisionLevel() == 0);
    assert(solver.qhead == solver.trail.size());

    if (lastNumUnitaryClean[type] + limit >= solver.get_unitary_learnts_num())
        return;

    #ifdef VERBOSE_DEBUG
    std::cout << "Cleaning " << (type==binaryClauses ? "binaryClauses" : "normal clauses" ) << std::endl;
    #endif //VERBOSE_DEBUG

    Clause **s, **ss, **end;
    for (s = ss = cs.getData(), end = s + cs.size();  s != end; s++) {
        if (s+1 != end) __builtin_prefetch(*(s+1));

        if (cleanClause(*s)) {
            solver.clauseAllocator.clauseFree(*s);
        } else {
            *ss++ = *s;
        }
    }
    cs.shrink(s-ss);

    lastNumUnitaryClean[type] = solver.get_unitary_learnts_num();

    #ifdef VERBOSE_DEBUG
    cout << "cleanClauses(Clause) useful ?? Removed: " << s-ss << endl;
    #endif
}
Example #2
0
void ClauseCleaner::cleanClausesBewareNULL(vec<ClauseSimp>& cs,
                                           ClauseCleaner::ClauseSetType type,
                                           Subsumer& subs, const unsigned limit)
{
  assert(solver.decisionLevel() == 0);
  assert(solver.qhead == solver.trail.size());

  if (lastNumUnitaryClean[type] + limit >= solver.get_unitary_learnts_num())
    return;

  ClauseSimp* s, *end;
  for (s = cs.getData(), end = s + cs.size(); s != end; s++)
  {
    if (s + 1 != end)
      __builtin_prefetch((s + 1)->clause, 1, 0);
    if (s->clause == NULL)
      continue;

    if (cleanClauseBewareNULL(*s, subs))
    {
      continue;
    }
    else if (s->clause->size() == 2)
      solver.becameBinary++;
  }

  lastNumUnitaryClean[type] = solver.get_unitary_learnts_num();
}
Example #3
0
void ClauseAllocator::updatePointers(vec<T*>& toUpdate, const map<Clause*, Clause*>& oldToNewPointer)
{
    for (T **it = toUpdate.getData(), **end = toUpdate.getDataEnd(); it != end; it++) {
        if (!(*it)->wasBin()) {
            //assert(oldToNewPointer.find((TT*)*it) != oldToNewPointer.end());
            map<Clause*, Clause*>::const_iterator it2 = oldToNewPointer.find((Clause*)*it);
            *it = (T*)it2->second;
        }
    }
}
Example #4
0
bool PartHandler::checkOnlyThisPart(const vec<T*>& cs, const uint32_t part, const PartFinder& partFinder) const
{
    for(T * const*it = cs.getData(), * const*end = it + cs.size(); it != end; it++) {
        const T& c = **it;
        for(const Lit *l = c.getData(), *end2 = l + c.size(); l != end2; l++) {
            if (partFinder.getVarPart(l->var()) != part) return false;
        }
    }

    return true;
}
Example #5
0
void RestartTypeChooser::addDegrees(const vec<T*>& cs, vector<uint32_t>& degrees) const
{
    for (T * const*c = cs.getData(), * const*end = c + cs.size(); c != end; c++) {
        T& cl = **c;
        if (cl.learnt()) continue;

        for (const Lit *l = cl.getData(), *end2 = l + cl.size(); l != end2; l++) {
            degrees[l->var()]++;
        }
    }
}
Example #6
0
void PartFinder::calcIn(const vec<T*>& cs, vector<uint>& numClauseInPart, vector<uint>& sumLitsInPart)
{
    for (T*const* c = cs.getData(), *const*end = c + cs.size(); c != end; c++) {
        if ((*c)->learnt()) continue;
        T& x = **c;
        const uint part = table[x[0].var()];
        assert(part < part_no);
        
        //for stats
        numClauseInPart[part]++;
        sumLitsInPart[part] += x.size();
    }
}
Example #7
0
void XorSubsumer::addFromSolver(vec<XorClause*>& cs)
{
    clauseID = 0;
    clauses.clear();
    XorClause **i = cs.getData();
    for (XorClause **end = i + cs.size(); i !=  end; i++) {
        if (i+1 != end) __builtin_prefetch(*(i+1));

        linkInClause(**i);
    }
    cs.clear();
    cs.push(NULL); //HACK --to force xor-propagation
}
Example #8
0
/**
@brief Replaces vars in xorclauses
*/
bool VarReplacer::replace_set(vec<XorClause*>& cs)
{
    XorClause **a = cs.getData();
    XorClause **r = a;
    for (XorClause **end = a + cs.size(); r != end; r++) {
        XorClause& c = **r;

        bool changed = false;
        Var origVar1 = c[0].var();
        Var origVar2 = c[1].var();

        for (Lit *l = &c[0], *end2 = l + c.size(); l != end2; l++) {
            Lit newlit = table[l->var()];
            if (newlit.var() != l->var()) {
                changed = true;
                *l = Lit(newlit.var(), false);
                c.invert(newlit.sign());
                replacedLits++;
            }
        }

        if (changed && handleUpdatedClause(c, origVar1, origVar2)) {
            if (!solver.ok) {
                #ifdef VERBOSE_DEBUG
                cout << "contradiction while replacing lits in xor clause" << std::endl;
                #endif
                for(;r != end; r++) solver.clauseAllocator.clauseFree(*r);
                cs.shrink(r-a);
                return false;
            }
            //solver.clauseAllocator.clauseFree(&c);
            c.setRemoved();
            solver.freeLater.push(&c);
        } else {
            #ifdef SILENT_DEBUG
            uint32_t numUndef = 0;
            for (uint32_t i = 0; i < c.size(); i++) {
                if (solver.value(c[i]) == l_Undef) numUndef++;
            }
            assert(numUndef >= 2 || numUndef == 0);
            #endif
            *a++ = *r;
        }
    }
    cs.shrink(r-a);

    return solver.ok;
}
Example #9
0
void XorSubsumer::addFromSolver(vec<XorClause*>& cs)
{
    clauseID = 0;
    clauses.clear();
    XorClause **i = cs.getData();
    for (XorClause **end = i + cs.size(); i !=  end; i++) {
        if (i+1 != end)
            __builtin_prefetch(*(i+1), 1, 1);

        linkInClause(**i);
        if ((*i)->getVarChanged() || (*i)->getStrenghtened())
            (*i)->calcXorAbstraction();
    }
    cs.clear();
    cs.push(NULL); //HACK --to force xor-propagation
}
Example #10
0
void ClauseCleaner::cleanClauses(vec<XorClause*>& cs, ClauseSetType type,
                                 const unsigned limit)
{
  assert(solver.decisionLevel() == 0);
  assert(solver.qhead == solver.trail.size());

  if (lastNumUnitaryClean[type] + limit >= solver.get_unitary_learnts_num())
    return;

  XorClause** s, **ss, **end;
  for (s = ss = cs.getData(), end = s + cs.size(); s != end; s++)
  {
    if (s + 1 != end)
      __builtin_prefetch(*(s + 1), 1, 0);

#ifdef DEBUG_ATTACH
    assert(find(solver.xorwatches[(**s)[0].var()], *s));
    assert(find(solver.xorwatches[(**s)[1].var()], *s));
    if (solver.assigns[(**s)[0].var()] != l_Undef ||
        solver.assigns[(**s)[1].var()] != l_Undef)
    {
      satisfied(**s);
    }
#endif // DEBUG_ATTACH

    if (cleanClause(**s))
    {
      solver.freeLater.push(*s);
      (*s)->setRemoved();
    }
    else
    {
#ifdef DEBUG_ATTACH
      assert(find(solver.xorwatches[(**s)[0].var()], *s));
      assert(find(solver.xorwatches[(**s)[1].var()], *s));
#endif // DEBUG_ATTACH
      *ss++ = *s;
    }
  }
  cs.shrink(s - ss);

  lastNumUnitaryClean[type] = solver.get_unitary_learnts_num();

#ifdef VERBOSE_DEBUG
  cout << "cleanClauses(XorClause) useful: ?? Removed: " << s - ss << endl;
#endif
}
Example #11
0
/**
@brief Initialises datastructures for 2-long xor finding by shortening longer xors
 */
void FailedLitSearcher::addFromSolver(const vec< XorClause* >& cs) {
    xorClauseSizes.clear();
    xorClauseSizes.growTo(cs.size());
    occur.resize(solver.nVars());
    for (Var var = 0; var < solver.nVars(); var++) {
        occur[var].clear();
    }

    uint32_t i = 0;
    for (XorClause * const*it = cs.getData(), * const*end = it + cs.size(); it != end; it++, i++) {
        if (it + 1 != end) __builtin_prefetch(*(it + 1));

        const XorClause& cl = **it;
        xorClauseSizes[i] = cl.size();
        for (const Lit *l = cl.getData(), *end2 = l + cl.size(); l != end2; l++) {
            occur[l->var()].push_back(i);
        }
    }
}
Example #12
0
void PartHandler::moveLearntClauses(vec<Clause*>& cs, Solver& newSolver, const uint32_t part, PartFinder& partFinder)
{
    Clause **i, **j, **end;
    for (i = j = cs.getData(), end = i + cs.size() ; i != end; i++) {
        if (!(**i).learnt()) {
            *j++ = *i;
            continue;
        }

        Clause& c = **i;
        assert(c.size() > 0);
        uint32_t clause_part = partFinder.getVarPart(c[0].var());
        bool removed = false;
        for (const Lit* l = c.getData(), *end = l + c.size(); l != end; l++) {
            if (partFinder.getVarPart(l->var()) != clause_part) {
                #ifdef VERBOSE_DEBUG
                std::cout << "Learnt clause in both parts:"; c.plainPrint();
                #endif

                removed = true;
                solver.removeClause(c);
                break;
            }
        }
        if (removed) continue;
        if (clause_part == part) {
            #ifdef VERBOSE_DEBUG
            //std::cout << "Learnt clause in this part:"; c.plainPrint();
            #endif

            solver.detachClause(c);
            newSolver.addLearntClause(c, c.getGroup(), c.activity());
            solver.clauseAllocator.clauseFree(&c);
        } else {
            #ifdef VERBOSE_DEBUG
            std::cout << "Learnt clause in other part:"; c.plainPrint();
            #endif

            *j++ = *i;
        }
    }
    cs.shrink(i-j);
}
Example #13
0
const bool DataSync::syncBinFromOthers(const Lit lit, const vector<Lit>& bins, uint32_t& finished, vec<Watched>& ws)
{
    assert(solver.varReplacer->getReplaceTable()[lit.var()].var() == lit.var());
    assert(solver.subsumer->getVarElimed()[lit.var()] == false);
    assert(solver.xorSubsumer->getVarElimed()[lit.var()] == false);

    vec<Lit> addedToSeen;
    for (vec<Watched>::iterator it = ws.getData(), end = ws.getDataEnd(); it != end; it++) {
        if (it->isBinary()) {
            addedToSeen.push(it->getOtherLit());
            seen[it->getOtherLit().toInt()] = true;
        }
    }

    vec<Lit> lits(2);
    for (uint32_t i = finished; i < bins.size(); i++) {
        if (!seen[bins[i].toInt()]) {
            Lit otherLit = bins[i];
            otherLit = solver.varReplacer->getReplaceTable()[otherLit.var()] ^ otherLit.sign();
            if (solver.subsumer->getVarElimed()[otherLit.var()]
                || solver.xorSubsumer->getVarElimed()[otherLit.var()]
                || solver.value(otherLit.var()) != l_Undef
                ) continue;

            recvBinData++;
            lits[0] = lit;
            lits[1] = otherLit;
            solver.addClauseInt(lits, 0, true, 2, 0, true);
            lits.clear();
            lits.growTo(2);
            if (!solver.ok) goto end;
        }
    }
    finished = bins.size();

    end:
    for (uint32_t i = 0; i < addedToSeen.size(); i++)
        seen[addedToSeen[i].toInt()] = false;

    return solver.ok;
}
Example #14
0
/**
@brief Replaces variables in normal clauses
*/
const bool VarReplacer::replace_set(vec<Clause*>& cs, const bool binClauses)
{
    Clause **a = cs.getData();
    Clause **r = a;
    for (Clause **end = a + cs.size(); r != end; r++) {
        Clause& c = **r;
        bool changed = false;
        Lit origLit1 = c[0];
        Lit origLit2 = c[1];
        Lit origLit3 = (c.size() == 3) ? c[2] : lit_Undef;
        for (Lit *l = c.getData(), *end2 = l + c.size();  l != end2; l++) {
            if (table[l->var()].var() != l->var()) {
                changed = true;
                *l = table[l->var()] ^ l->sign();
                replacedLits++;
            }
        }

        if (changed && handleUpdatedClause(c, origLit1, origLit2, origLit3)) {
            if (!solver.ok) {
                for(;r != end; r++) solver.clauseAllocator.clauseFree(*r);
                cs.shrink(r-a);
                return false;
            }
        } else {
            if (!binClauses && c.size() == 2) {
                solver.detachClause(c);
                Clause *c2 = solver.clauseAllocator.Clause_new(c);
                solver.clauseAllocator.clauseFree(&c);
                solver.attachClause(*c2);
                solver.becameBinary++;
                solver.binaryClauses.push(c2);
            } else
                *a++ = *r;
        }
    }
    cs.shrink(r-a);

    return solver.ok;
}
Example #15
0
void ClauseCleaner::removeSatisfied(vec<Clause*>& cs, ClauseSetType type, const uint limit)
{
    #ifdef DEBUG_CLEAN
    assert(solver.decisionLevel() == 0);
    #endif

    if (lastNumUnitarySat[type] + limit >= solver.get_unitary_learnts_num())
        return;

    Clause **i,**j, **end;
    for (i = j = cs.getData(), end = i + cs.size(); i != end; i++) {
        if (i+1 != end)
            __builtin_prefetch(*(i+1), 0, 0);
        if (satisfied(**i))
            solver.removeClause(**i);
        else
            *j++ = *i;
    }
    cs.shrink(i - j);

    lastNumUnitarySat[type] = solver.get_unitary_learnts_num();
}
Example #16
0
void PartHandler::moveClauses(vec<XorClause*>& cs, Solver& newSolver, const uint32_t part, PartFinder& partFinder)
{
    XorClause **i, **j, **end;
    for (i = j = cs.getData(), end = i + cs.size(); i != end; i++) {
        if (partFinder.getVarPart((**i)[0].var()) != part) {
            *j++ = *i;
            continue;
        }
        solver.detachClause(**i);
        #ifdef VERBOSE_DEBUG
        std::cout << "xor clause in this part:"; (**i).plainPrint();
        #endif

        XorClause& c = **i;
        vec<Lit> tmp(c.size());
        std::copy(c.getData(), c.getDataEnd(), tmp.getData());
        newSolver.addXorClause(tmp, c.xor_clause_inverted(), c.getGroup());
        //NOTE: we need the CS because otherwise, the addXorClause could have changed **i, which we need to re-add later!
        xorClausesRemoved.push(*i);
    }
    cs.shrink(i-j);
}
Example #17
0
/**
@brief Replaces vars in xorclauses
*/
const bool VarReplacer::replace_set(vec<XorClause*>& cs)
{
    XorClause **a = cs.getData();
    XorClause **r = a;
    for (XorClause **end = a + cs.size(); r != end; r++) {
        XorClause& c = **r;

        bool changed = false;
        Var origVar1 = c[0].var();
        Var origVar2 = c[1].var();

        for (Lit *l = &c[0], *end2 = l + c.size(); l != end2; l++) {
            Lit newlit = table[l->var()];
            if (newlit.var() != l->var()) {
                changed = true;
                *l = Lit(newlit.var(), false);
                c.invert(newlit.sign());
                replacedLits++;
            }
        }

        if (changed && handleUpdatedClause(c, origVar1, origVar2)) {
            if (!solver.ok) {
                for(;r != end; r++) solver.clauseAllocator.clauseFree(*r);
                cs.shrink(r-a);
                return false;
            }
            c.setRemoved();
            solver.freeLater.push(&c);
        } else {
            *a++ = *r;
        }
    }
    cs.shrink(r-a);

    return solver.ok;
}
Example #18
0
void PartFinder::addToPart(const vec<T*>& cs)
{
    set<uint> tomerge;
    vector<Var> newSet;
    for (T* const* c = cs.getData(), * const*end = c + cs.size(); c != end; c++) {
        if ((*c)->learnt()) continue;
        tomerge.clear();
        newSet.clear();
        for (const Lit *l = (*c)->getData(), *end2 = l + (*c)->size(); l != end2; l++) {
            if (table[l->var()] != std::numeric_limits<uint32_t>::max())
                tomerge.insert(table[l->var()]);
            else
                newSet.push_back(l->var());
        }
        if (tomerge.size() == 1) {
            //no trees to merge, only merge the clause into one tree
            
            const uint into = *tomerge.begin();
            map<uint, vector<Var> >::iterator intoReverse = reverseTable.find(into);
            for (uint i = 0; i < newSet.size(); i++) {
                intoReverse->second.push_back(newSet[i]);
                table[newSet[i]] = into;
            }
            continue;
        }
        
        for (set<uint>::iterator it = tomerge.begin(); it != tomerge.end(); it++) {
            newSet.insert(newSet.end(), reverseTable[*it].begin(), reverseTable[*it].end());
            reverseTable.erase(*it);
        }
        
        for (uint i = 0; i < newSet.size(); i++)
            table[newSet[i]] = part_no;
        reverseTable[part_no] = newSet;
        part_no++;
    }
}
Example #19
0
/**
@brief Replaces variables in normal clauses
*/
bool VarReplacer::replace_set(vec<Clause*>& cs)
{
    Clause **a = cs.getData();
    Clause **r = a;
    for (Clause **end = a + cs.size(); r != end; r++) {
        Clause& c = **r;
        assert(c.size() > 2);
        bool changed = false;
        Lit origLit1 = c[0];
        Lit origLit2 = c[1];
        Lit origLit3 = (c.size() == 3) ? c[2] : lit_Undef;
        for (Lit *l = c.getData(), *end2 = l + c.size();  l != end2; l++) {
            if (table[l->var()].var() != l->var()) {
                changed = true;
                *l = table[l->var()] ^ l->sign();
                replacedLits++;
            }
        }

        if (changed && handleUpdatedClause(c, origLit1, origLit2, origLit3)) {
            if (!solver.ok) {
                #ifdef VERBOSE_DEBUG
                cout << "contradiction while replacing lits in normal clause" << std::endl;
                #endif
                for(;r != end; r++) solver.clauseAllocator.clauseFree(*r);
                cs.shrink(r-a);
                return false;
            }
        } else {
            *a++ = *r;
        }
    }
    cs.shrink(r-a);

    return solver.ok;
}
Example #20
0
void XorSubsumer::removeWrong(vec<Clause*>& cs)
{
    Clause **i = cs.getData();
    Clause **j = i;
    for (Clause **end =  i + cs.size(); i != end; i++) {
        Clause& c = **i;
        if (!c.learnt())  {
            *j++ = *i;
            continue;
        }
        bool remove = false;
        for (Lit *l = c.getData(), *end2 = l+c.size(); l != end2; l++) {
            if (var_elimed[l->var()]) {
                remove = true;
                solver.detachClause(c);
                solver.clauseAllocator.clauseFree(&c);
                break;
            }
        }
        if (!remove)
            *j++ = *i;
    }
    cs.shrink(i-j);
}
Example #21
0
bool ClauseVivifier::vivifyClauses2(vec<Clause*>& clauses) {
    assert(solver.ok);

    vec<char> seen;
    seen.growTo(solver.nVars()*2, 0);
    vec<char> seen_subs;
    seen_subs.growTo(solver.nVars()*2, 0);

    uint32_t litsRem = 0;
    uint32_t clShrinked = 0;
    uint64_t countTime = 0;
    uint64_t maxCountTime = 800 * 1000 * 1000;
    maxCountTime *= 6;
    if (solver.clauses_literals + solver.learnts_literals < 500000)
        maxCountTime *= 2;
    uint32_t clTried = 0;
    vec<Lit> lits;
    bool needToFinish = false;
    double myTime = cpuTime();
    uint32_t subsumed_tri_num = 0;
    uint32_t subsumed_bin_num = 0;

    Clause** i = clauses.getData();
    Clause** j = i;
    for (Clause** end = clauses.getDataEnd(); i != end; i++) {
        if (needToFinish) {
            *j++ = *i;
            continue;
        }
        if (countTime > maxCountTime)
            needToFinish = true;

        Clause& cl = **i;
        countTime += cl.size()*2;
        clTried++;

        bool subsumed = false;
        const bool learnt = cl.learnt();
        for (uint32_t i2 = 0; i2 < cl.size(); i2++) {
            seen[cl[i2].toInt()] = 1; //for strengthening
            seen_subs[cl[i2].toInt()] = 1; //for subsumption
        }

        for (const Lit *l = cl.getData(), *end = cl.getDataEnd(); l != end; l++) {
            const Lit *l_other = l;
            l_other++;
            if (l_other != end)
                __builtin_prefetch(solver.watches[(~*l_other).toInt()].getData());

            const vec<Watched>& ws = solver.watches[(~*l).toInt()];
            countTime += ws.size()*2;
            for (vec<Watched>::const_iterator it = ws.getData(), end = ws.getDataEnd(); it != end; it++) {
                //Handle tri clause
                if (it->isTriClause() && cl.size() > 3) {
                    if (learnt //we cannot decide if TRI is learnt or not
                            && seen_subs[it->getOtherLit().toInt()]
                            && seen_subs[it->getOtherLit2().toInt()]
                            ) {
                        subsumed_tri_num++;
                        subsumed = true;
                    }

                    if (seen[l->toInt()]) { //we may have removed it already
                        //one way
                        if (seen[(it->getOtherLit2()).toInt()])
                            seen[(~it->getOtherLit()).toInt()] = 0;

                        //other way
                        if (seen[(it->getOtherLit()).toInt()])
                            seen[(~it->getOtherLit2()).toInt()] = 0;
                    }
                }

                //Handle Binary clause
                if (it->isBinary()) {
                    if (seen_subs[it->getOtherLit().toInt()]) {
                        if (!learnt && it->getLearnt())
                            makeNonLearntBin(*l, it->getOtherLit(), it->getLearnt());
                        subsumed_bin_num++;
                        subsumed = true;
                    }

                    if (seen[l->toInt()]) //we may have removed it already
                        seen[(~it->getOtherLit()).toInt()] = 0;

                }
            }

            if (seen[l->toInt()] == 0)
                continue;

            countTime += solver.transOTFCache[l->toInt()].lits.size();
            for (vector<Lit>::const_iterator it2 = solver.transOTFCache[l->toInt()].lits.begin()
                    , end2 = solver.transOTFCache[l->toInt()].lits.end(); it2 != end2; it2++) {
                seen[(~(*it2)).toInt()] = 0;
            }
        }

        lits.clear();
        for (const Lit *it2 = cl.getData(), *end2 = cl.getDataEnd(); it2 != end2; it2++) {
            if (seen[it2->toInt()]) lits.push(*it2);
            else litsRem++;
            seen[it2->toInt()] = 0;
            seen_subs[it2->toInt()] = 0;
        }

        if (subsumed) {
            solver.removeClause(cl);
        } else if (lits.size() < cl.size()) {
            solver.detachClause(cl);
            clShrinked++;
            Clause* c2 = solver.addClauseInt(lits, cl.learnt(), cl.getGlue(), cl.getMiniSatAct());
            solver.clauseAllocator.clauseFree(&cl);

            if (c2 != NULL) *j++ = c2;
            if (!solver.ok) needToFinish = true;
        } else {
            *j++ = *i;
        }
    }

    clauses.shrink(i - j);

    if (solver.conf.verbosity >= 1) {
        std::cout << "c vivif2 -- "
                << " cl tried " << std::setw(8) << clTried
                << " cl rem " << std::setw(8) << (subsumed_bin_num + subsumed_tri_num)
                << " cl shrink " << std::setw(8) << clShrinked
                << " lits rem " << std::setw(10) << litsRem
                << " time: " << cpuTime() - myTime
                << std::endl;
    }

    return solver.ok;
}