Beispiel #1
0
void DataSync::signalNewBinClause(Lit lit1, Lit lit2)
{
    if (!enabled()) {
        return;
    }

    if (must_rebuild_bva_map) {
        outer_to_without_bva_map = solver->build_outer_to_without_bva_map();
        must_rebuild_bva_map = false;
    }

    if (solver->varData[lit1.var()].is_bva)
        return;
    if (solver->varData[lit2.var()].is_bva)
        return;

    lit1 = solver->map_inter_to_outer(lit1);
    lit1 = map_outside_without_bva(lit1);
    lit2 = solver->map_inter_to_outer(lit2);
    lit2 = map_outside_without_bva(lit2);

    if (lit1.toInt() > lit2.toInt()) {
        std::swap(lit1, lit2);
    }
    newBinClauses.push_back(std::make_pair(lit1, lit2));
}
Beispiel #2
0
void XorSubsumer::removeWrongBins()
{
    uint32_t numRemovedHalfLearnt = 0;
    uint32_t wsLit = 0;
    for (vec<Watched> *it = solver.watches.getData(), *end = solver.watches.getDataEnd(); it != end; it++, wsLit++) {
        Lit lit = ~Lit::toLit(wsLit);
        vec<Watched>& ws = *it;

        vec<Watched>::iterator i = ws.getData();
        vec<Watched>::iterator j = i;
        for (vec<Watched>::iterator end2 = ws.getDataEnd(); i != end2; i++) {
            if (i->isBinary()
                    && i->getLearnt()
                    && (var_elimed[lit.var()] || var_elimed[i->getOtherLit().var()])
               ) {
                numRemovedHalfLearnt++;
            } else {
                assert(!i->isBinary() || (!var_elimed[lit.var()] && !var_elimed[i->getOtherLit().var()]));
                *j++ = *i;
            }
        }
        ws.shrink_(i - j);
    }

    assert(numRemovedHalfLearnt % 2 == 0);
    solver.learnts_literals -= numRemovedHalfLearnt;
    solver.numBins -= numRemovedHalfLearnt/2;
}
Beispiel #3
0
void HyperEngine::add_hyper_bin(const Lit lit1, const Lit lit2, const Lit lit3)
{
    assert(value(lit1.var()) == l_Undef);

    #ifdef VERBOSE_DEBUG_FULLPROP
    print_trail();
    cout << "Enqueing " << lit1
    << " with ancestor 3-long clause: " << lit1 << " , "
    << lit2 << " (lev:" << varData[lit2.var()].level << ") "
    << lit3 << " (lev:" << varData[lit3.var()].level << ") "
    << endl;
    #endif

    assert(value(lit2) == l_False);
    assert(value(lit3) == l_False);

    currAncestors.clear();
    if (varData[lit2.var()].level != 0) {
        currAncestors.push_back(~lit2);
    }

    if (varData[lit3.var()].level != 0)
        currAncestors.push_back(~lit3);

    add_hyper_bin(lit1);
}
Beispiel #4
0
bool TransCache::merge(
    const vector<Lit>& otherLits //Lits to add
    , const Lit extraLit //Add this, too to the list of lits
    , const bool red //The step was a redundant-dependent step?
    , const Var leaveOut //Leave this literal out
    , vector<uint16_t>& seen
) {
    //Mark every literal that is to be added in 'seen'
    for (size_t i = 0, size = otherLits.size(); i < size; i++) {
        const Lit lit = otherLits[i];
        seen[lit.toInt()] = 1;
    }

    bool taut = mergeHelper(extraLit, red, seen);

    //Whatever rests needs to be added
    for (size_t i = 0 ,size = otherLits.size(); i < size; i++) {
        const Lit lit = otherLits[i];
        if (seen[lit.toInt()]) {
            if (lit.var() != leaveOut)
                lits.push_back(LitExtra(lit, false));
            seen[lit.toInt()] = 0;
        }
    }

    //Handle extra lit
    if (extraLit != lit_Undef && seen[extraLit.toInt()]) {
        if (extraLit.var() != leaveOut)
            lits.push_back(LitExtra(extraLit, !red));
        seen[extraLit.toInt()] = 0;
    }

    return taut;
}
void SolutionExtender::addClause(const vector<Lit>& lits, const Lit blockedOn)
{
    const uint32_t blocked_on_inter = solver->map_outer_to_inter(blockedOn.var());
    assert(solver->varData[blocked_on_inter].removed == Removed::elimed);
    assert(contains_lit(lits, blockedOn));
    if (satisfied(lits))
        return;

    #ifdef VERBOSE_DEBUG_SOLUTIONEXTENDER
    for(Lit lit: lits) {
        Lit lit_inter = solver->map_outer_to_inter(lit);
        cout
        << lit << ": " << solver->model_value(lit)
        << "(elim: " << removed_type_to_string(solver->varData[lit_inter.var()].removed) << ")"
        << ", ";
    }
    cout << "blocked on: " <<  blockedOn << endl;
    #endif

    if (solver->model_value(blockedOn) != l_Undef) {
        cout << "ERROR: Model value for var " << blockedOn.unsign() << " is "
        << solver->model_value(blockedOn) << " but that doesn't satisfy a v-elim clause on the stack!"
        << endl;
    }
    assert(solver->model_value(blockedOn) == l_Undef);
    solver->model[blockedOn.var()] = blockedOn.sign() ? l_False : l_True;
    if (solver->conf.verbosity >= 10) {
        cout << "Extending VELIM cls. -- setting model for var "
        << blockedOn.unsign() << " to " << solver->model[blockedOn.var()] << endl;
    }

    assert(satisfied(lits));

    solver->varReplacer->extend_model(blockedOn.var());
}
Beispiel #6
0
/**
@brief Returns if we already know that var = lit

Also checks if var = ~lit, in which it sets solver.ok = false
*/
bool VarReplacer::alreadyIn(const Var var, const Lit lit)
{
    Lit lit2 = table[var];
    if (lit2.var() == lit.var()) {
        if (lit2.sign() != lit.sign()) {
            #ifdef VERBOSE_DEBUG
            cout << "Inverted cycle in var-replacement -> UNSAT" << endl;
            #endif
            solver.ok = false;
        }
        return true;
    }

    lit2 = table[lit.var()];
    if (lit2.var() == var) {
        if (lit2.sign() != lit.sign()) {
            #ifdef VERBOSE_DEBUG
            cout << "Inverted cycle in var-replacement -> UNSAT" << endl;
            #endif
            solver.ok = false;
        }
        return true;
    }

    return false;
}
void SolutionExtender::addClause(const vector<Lit>& lits, const Lit blockedOn)
{
    const Var blocked_on_inter = solver->map_outer_to_inter(blockedOn.var());
    assert(solver->varData[blocked_on_inter].removed == Removed::elimed);
    assert(contains_lit(lits, blockedOn));
    if (satisfied(lits))
        return;

    #ifdef VERBOSE_DEBUG_SOLUTIONEXTENDER
    for(Lit lit: lits) {
        Lit lit_inter = solver->map_outer_to_inter(lit);
        cout
        << lit << ": " << solver->model_value(lit)
        << "(elim: " << removed_type_to_string(solver->varData[lit_inter.var()].removed) << ")"
        << ", ";
    }
    cout << "blocked on: " <<  blockedOn << endl;
    #endif

    assert(solver->model_value(blockedOn) == l_Undef);
    solver->model[blockedOn.var()] = blockedOn.sign() ? l_False : l_True;
    assert(satisfied(lits));

    solver->varReplacer->extend_model(blockedOn.var());
}
bool SolutionExtender::propagateCl(
    const Clause* cl
    , const Lit blockedOn
) {
    size_t numUndef = 0;
    Lit lastUndef = lit_Undef;
    for (const Lit
        *it = cl->begin(), *end = cl->end()
        ; it != end
        ; ++it
    ) {
        if (value(*it) == l_True) return true;
        if (value(*it) == l_False) continue;

        assert(value(*it) == l_Undef);
        numUndef++;

        //Doesn't propagate anything
        if (numUndef > 1)
            break;

        lastUndef = *it;
    }

    //Must set this one value
    if (numUndef == 1) {
        #ifdef VERBOSE_DEBUG_RECONSTRUCT
        cout << "c Due to cl " << *cl << " propagate enqueueing " << lastUndef << endl;
        #endif
        enqueue(lastUndef);
    }

    if (numUndef >= 1)
        return true;

    //Must flip
    #ifdef VERBOSE_DEBUG_RECONSTRUCT
    cout
    << "Flipping lit " << blockedOn
    << " due to clause " << *cl << endl;
    #endif
    assert(blockedOn != lit_Undef);

    if (solver->varData[blockedOn.var()].level == 0) {
        cout
        << "!! Flip 0-level var:"
        << solver->map_inter_to_outer(blockedOn.var()) + 1
        << endl;
    }

    assert(
        (solver->varData[blockedOn.var()].level != 0
            //|| solver->varData[blockedOn.var()].removed == Removed::decomposed
        )
        && "We cannot flip 0-level vars"
    );
    enqueue(blockedOn);
    replaceSet(blockedOn);
    return true;
}
void CalcDefPolars::add_vote(const Lit lit, const double value)
{
    if (lit.sign()) {
        votes[lit.var()] -= value;
    } else {
        votes[lit.var()] += value;
    }
}
void SolutionExtender::enqueue(const Lit lit)
{
    assigns[lit.var()] = boolToLBool(!lit.sign());
    trail.push_back(lit);
    #ifdef VERBOSE_DEBUG_RECONSTRUCT
    cout << "c Enqueueing lit " << lit << " during solution reconstruction" << endl;
    #endif
    solver->varData[lit.var()].level = std::numeric_limits< uint32_t >::max();
}
Beispiel #11
0
const bool DataSync::shareUnitData()
{
    uint32_t thisGotUnitData = 0;
    uint32_t thisSentUnitData = 0;

    SharedData& shared = *sharedData;
    shared.value.growTo(solver.nVars(), l_Undef);
    for (uint32_t var = 0; var < solver.nVars(); var++) {
        Lit thisLit = Lit(var, false);
        thisLit = solver.varReplacer->getReplaceTable()[thisLit.var()] ^ thisLit.sign();
        const lbool thisVal = solver.value(thisLit);
        const lbool otherVal = shared.value[var];

        if (thisVal == l_Undef && otherVal == l_Undef) continue;
        if (thisVal != l_Undef && otherVal != l_Undef) {
            if (thisVal != otherVal) {
                solver.ok = false;
                return false;
            } else {
                continue;
            }
        }

        if (otherVal != l_Undef) {
            assert(thisVal == l_Undef);
            Lit litToEnqueue = thisLit ^ (otherVal == l_False);
            if (solver.subsumer->getVarElimed()[litToEnqueue.var()]
                || solver.xorSubsumer->getVarElimed()[litToEnqueue.var()]
                ) continue;

            solver.uncheckedEnqueue(litToEnqueue);
            solver.ok = solver.propagate<false>().isNULL();
            if (!solver.ok) return false;
            thisGotUnitData++;
            continue;
        }

        if (thisVal != l_Undef) {
            assert(otherVal == l_Undef);
            shared.value[var] = thisVal;
            thisSentUnitData++;
            continue;
        }
    }

    if (solver.conf.verbosity >= 3 && (thisGotUnitData > 0 || thisSentUnitData > 0)) {
        std::cout << "c got units " << std::setw(8) << thisGotUnitData
        << " sent units " << std::setw(8) << thisSentUnitData << std::endl;
    }

    recvUnitData += thisGotUnitData;
    sentUnitData += thisSentUnitData;

    return true;
}
Beispiel #12
0
//Analyze why did we fail at decision level 1
Lit HyperEngine::analyzeFail(const PropBy propBy)
{
    //Clear out the datastructs we will be usin
    currAncestors.clear();

    //First, we set the ancestors, based on the clause
    //Each literal in the clause is an ancestor. So just 'push' them inside the
    //'currAncestors' variable
    switch(propBy.getType()) {
        case tertiary_t : {
            const Lit lit = ~propBy.lit3();
            if (varData[lit.var()].level != 0)
                currAncestors.push_back(lit);
            //intentionally falling through here
            //i.e. there is no 'break' here for a reason
        }
        case binary_t: {
            const Lit lit = ~propBy.lit2();
            if (varData[lit.var()].level != 0)
                currAncestors.push_back(lit);

            if (varData[failBinLit.var()].level != 0)
                currAncestors.push_back(~failBinLit);

            break;
        }

        case clause_t: {
            const uint32_t offset = propBy.get_offset();
            const Clause& cl = *cl_alloc.ptr(offset);
            for(size_t i = 0; i < cl.size(); i++) {
                if (varData[cl[i].var()].level != 0)
                    currAncestors.push_back(~cl[i]);
            }
            break;
        }

        case xor_t: {
            //in the future, we'll have XOR clauses. Not yet.
            assert(false);
            exit(-1);
            break;
        }

        case null_clause_t:
            assert(false);
            break;
    }

    Lit foundLit = deepest_common_ancestor();

    return foundLit;
}
Beispiel #13
0
bool DataSync::syncBinFromOthers(
    const Lit lit
    , const vector<Lit>& bins
    , uint32_t& finished
    , watch_subarray ws
) {
    assert(solver->varReplacer->get_lit_replaced_with(lit) == lit);
    assert(solver->varData[lit.var()].removed == Removed::none);

    assert(toClear.empty());
    for (const Watched& w: ws) {
        if (w.isBin()) {
            toClear.push_back(w.lit2());
            assert(seen.size() > w.lit2().toInt());
            seen[w.lit2().toInt()] = true;
        }
    }

    vector<Lit> lits(2);
    for (uint32_t i = finished; i < bins.size(); i++) {
        Lit otherLit = bins[i];
        otherLit = solver->map_to_with_bva(otherLit);
        otherLit = solver->varReplacer->get_lit_replaced_with_outer(otherLit);
        otherLit = solver->map_outer_to_inter(otherLit);
        if (solver->varData[otherLit.var()].removed != Removed::none
            || solver->value(otherLit) != l_Undef
        ) {
            continue;
        }
        assert(seen.size() > otherLit.toInt());
        if (!seen[otherLit.toInt()]) {
            stats.recvBinData++;
            lits[0] = lit;
            lits[1] = otherLit;

            //Don't add DRUP: it would add to the thread data, too
            solver->add_clause_int(lits, true, ClauseStats(), true, NULL, false);
            if (!solver->ok) {
                goto end;
            }
        }
    }
    finished = bins.size();

    end:
    for (const Lit l: toClear) {
        seen[l.toInt()] = false;
    }
    toClear.clear();

    return solver->ok;
}
Beispiel #14
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;
}
Beispiel #15
0
void VarReplacer::print_equivalent_literals(std::ostream *os) const
{
    vector<Lit> tmpCl;
    for (Var var = 0; var < table.size(); var++) {
        const Lit lit = table[var];
        if (lit.var() == var)
            continue;

        tmpCl.clear();
        tmpCl.push_back(~lit);
        tmpCl.push_back(Lit(var, false));
        std::sort(tmpCl.begin(), tmpCl.end());

        *os
        << tmpCl[0] << " "
        << tmpCl[1]
        << " 0\n";

        tmpCl[0] ^= true;
        tmpCl[1] ^= true;

        *os
        << tmpCl[0] << " "
        << tmpCl[1]
        << " 0\n";
    }
}
Beispiel #16
0
/**
@brief Changes internal graph to set everything that pointed to var to point to lit
*/
void VarReplacer::setAllThatPointsHereTo(const Var var, const Lit lit)
{
    map<Var, vector<Var> >::iterator it = reverseTable.find(var);
    if (it != reverseTable.end()) {
        for(const Var var2: it->second) {
            assert(table[var2].var() == var);
            if (lit.var() != var2) {
                table[var2] = lit ^ table[var2].sign();
                reverseTable[lit.var()].push_back(var2);
            }
        }
        reverseTable.erase(it);
    }
    table[var] = lit;
    reverseTable[lit.var()].push_back(var);
}
Beispiel #17
0
void Prober::add_rest_of_lits_to_cache(Lit lit)
{
    tmp_lits.clear();
    for (int64_t c = solver->trail_size()-1
        ; c != (int64_t)solver->trail_lim[0] - 1
        ; c--
    ) {
        extraTime += 2;
        const Lit thisLit = solver->trail[c];
        tmp_lits.push_back(thisLit);
    }

    bool taut = solver->implCache[~lit].merge(
        tmp_lits
        , lit_Undef
        , true //Red step -- we don't know, so we assume
        , lit.var()
        , solver->seen
    );

    //If tautology according to cache we can
    //enqueue ~lit at toplevel since both
    //~lit V OTHER, and ~lit V ~OTHER are technically in
    if (taut) {
        toEnqueue.push_back(~lit);
        (*solver->drat) << ~lit << fin;
    }
}
Beispiel #18
0
void Prober::sortAndResetCandidates()
{
    candidates.clear();
    candidates.resize(solver->nVars());
    for(size_t i = 0; i < solver->nVars(); i++) {
        Lit lit = Lit(i, false);
        candidates[i].var = lit.var();

        //Calculate approx number of literals propagated for positive polarity
        //TODO stamping -- replace '0'
        size_t posPolar =
            std::max<size_t>(
                solver->watches[(~lit).toInt()].size()
                , 0//solver->implCache[(~lit).toInt()].lits.size()
            );

        //Calculate approx number of literals propagated for negative polarity
        //TODO stamping -- replace '0'
        size_t negPolar =
            std::max<size_t>(
                solver->watches[lit.toInt()].size()
                , 0 //solver->implCache[lit.toInt()].lits.size()
            );

        //Minimim of the two polarities
        candidates[i].minOfPolarities = std::min(posPolar, negPolar);
        //cout << "candidate size: " << candidates[i].minOfPolarities << endl;
    }

    //Sort candidates from MAX to MIN of 'minOfPolarities'
    std::sort(candidates.begin(), candidates.end());
}
void SubsumeImplicit::try_subsume_bin(
    const Lit lit
    , Watched*& i
    , Watched*& j
) {
    //Subsume bin with bin
    if (i->lit2() == lastLit2
        && lastLit3 == lit_Undef
    ) {
        //The sorting algorithm prefers irred to red, so it is
        //impossible to have irred before red
        assert(!(i->red() == false && lastRed == true));

        runStats.remBins++;
        assert(i->lit2().var() != lit.var());
        timeAvailable -= 30;
        timeAvailable -= solver->watches[i->lit2().toInt()].size();
        removeWBin(solver->watches, i->lit2(), lit, i->red());
        if (i->red()) {
            solver->binTri.redBins--;
        } else {
            solver->binTri.irredBins--;
        }
        (*solver->drup) << del << lit << i->lit2() << fin;

        return;
    } else {
        lastBin = j;
        lastLit2 = i->lit2();
        lastLit3 = lit_Undef;
        lastRed = i->red();
        *j++ = *i;
    }
}
Beispiel #20
0
bool UselessBinRemover::fillBinImpliesMinusLast(const Lit& origLit, const Lit& lit, vec<Lit>& wrong)
{
    solver.newDecisionLevel();
    solver.uncheckedEnqueueLight(lit);
    //if it's a cycle, it doesn't work, so don't propagate origLit
    failed = !onlyNonLearntBins.propagateBinExcept(origLit);
    if (failed) return false;

    assert(solver.decisionLevel() > 0);
    int c;
    extraTime += (solver.trail.size() - solver.trail_lim[0]) / EXTRATIME_DIVIDER;
    for (c = solver.trail.size()-1; c > (int)solver.trail_lim[0]; c--) {
        Lit x = solver.trail[c];
        if (toDeleteSet[x.toInt()]) {
            wrong.push(x);
            toDeleteSet[x.toInt()] = false;
        };
        solver.assigns[x.var()] = l_Undef;
    }
    solver.assigns[solver.trail[c].var()] = l_Undef;

    solver.qhead = solver.trail_lim[0];
    solver.trail.shrink_(solver.trail.size() - solver.trail_lim[0]);
    solver.trail_lim.clear();
    //solver.cancelUntil(0);

    return true;
}
Beispiel #21
0
void ImplCache::printStatsSort(const Solver* solver) const
{
    size_t numHasElems = 0;
    size_t totalElems = 0;
    size_t activeLits = 0;

    for(size_t i = 0; i < implCache.size(); i++) {
        Lit lit = Lit::toLit(i);

        if (solver->varData[lit.var()].is_decision) {
            activeLits++;
            totalElems += implCache[i].lits.size();
            numHasElems += !implCache[i].lits.empty();
        }
    }

    printStatsLine(
        "c lits having cache"
        , stats_line_percent(numHasElems, activeLits)
        , "% of decision lits"
    );

    printStatsLine(
        "c num elems in cache/lit"
        , stats_line_percent(totalElems, numHasElems)
        , "extralits"
    );
}
Beispiel #22
0
//Add binary clause to deepest common ancestor
void HyperEngine::add_hyper_bin(const Lit p)
{
    propStats.otfHyperTime += 2;

    Lit deepestAncestor = lit_Undef;
    bool hyperBinNotAdded = true;
    if (currAncestors.size() > 1) {
        deepestAncestor = deepest_common_ancestor();

        #ifdef VERBOSE_DEBUG_FULLPROP
        cout << "Adding hyper-bin clause: " << p << " , " << ~deepestAncestor << endl;
        #endif
        needToAddBinClause.insert(BinaryClause(p, ~deepestAncestor, true));
        *drat << p << (~deepestAncestor) << fin;

        hyperBinNotAdded = false;
    } else {
        //0-level propagation is NEVER made by propFull
        assert(currAncestors.size() > 0);

        #ifdef VERBOSE_DEBUG_FULLPROP
        cout
        << "Not adding hyper-bin because only ONE lit is not set at"
        << "level 0 in long clause, but that long clause needs to be cleaned"
        << endl;
        #endif
        deepestAncestor = currAncestors[0];
        hyperBinNotAdded = true;
    }

    enqueue_with_acestor_info(p, deepestAncestor, true);
    varData[p.var()].reason.setHyperbin(true);
    varData[p.var()].reason.setHyperbinNotAdded(hyperBinNotAdded);
}
Beispiel #23
0
void XorSubsumer::fillCannotEliminate()
{
    std::fill(cannot_eliminate.getData(), cannot_eliminate.getDataEnd(), false);
    for (uint32_t i = 0; i < solver.clauses.size(); i++)
        addToCannotEliminate(solver.clauses[i]);

    uint32_t wsLit = 0;
    for (const vec<Watched> *it = solver.watches.getData(), *end = solver.watches.getDataEnd(); it != end; it++, wsLit++) {
        Lit lit = ~Lit::toLit(wsLit);
        const vec<Watched>& ws = *it;
        for (vec<Watched>::const_iterator it2 = ws.getData(), end2 = ws.getDataEnd(); it2 != end2; it2++) {
            if (it2->isBinary() && !it2->getLearnt()) {
                cannot_eliminate[lit.var()] = true;
                cannot_eliminate[it2->getOtherLit().var()] = true;
            }
        }
    }

    for (Var var = 0; var < solver.nVars(); var++) {
        cannot_eliminate[var] |= solver.varReplacer->cannot_eliminate[var];
    }

#ifdef VERBOSE_DEBUG
    uint32_t tmpNum = 0;
    for (uint32_t i = 0; i < cannot_eliminate.size(); i++)
        if (cannot_eliminate[i])
            tmpNum++;
    std::cout << "Cannot eliminate num:" << tmpNum << std::endl;
#endif
}
Beispiel #24
0
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);
}
Beispiel #25
0
/**
@brief Changes internal graph to set everything that pointed to var to point to lit
*/
void VarReplacer::setAllThatPointsHereTo(const Var var, const Lit lit)
{
    map<Var, vector<Var> >::iterator it = reverseTable.find(var);
    if (it != reverseTable.end()) {
        for(vector<Var>::const_iterator it2 = it->second.begin(), end = it->second.end(); it2 != end; it2++) {
            assert(table[*it2].var() == var);
            if (lit.var() != *it2) {
                table[*it2] = lit ^ table[*it2].sign();
                reverseTable[lit.var()].push_back(*it2);
            }
        }
        reverseTable.erase(it);
    }
    table[var] = lit;
    reverseTable[lit.var()].push_back(var);
}
void CalcDefPolars::tallyVotesBinTri(const vector<vec<Watched> >& watches)
{
    size_t wsLit = 0;
    for (vector<vec<Watched> >::const_iterator
        it = watches.begin(), end = watches.end()
        ; it != end
        ; it++, wsLit++
    ) {
        Lit lit = Lit::toLit(wsLit);
        const vec<Watched>& ws = *it;
        for (vec<Watched>::const_iterator it2 = ws.begin(), end2 = ws.end(); it2 != end2; it2++) {

            //Only count bins once
            if (it2->isBinary()
                && lit < it2->lit2()
                && !it2->learnt()
            ) {

                if (lit.sign()) votes[lit.var()] += 0.5;
                else votes[lit.var()] -= 0.5;

                Lit lit2 = it2->lit2();
                if (lit2.sign()) votes[lit2.var()] += 0.5;
                else votes[lit2.var()] -= 0.5;
            }

            //Only count TRI-s once
            if (it2->isTri()
                && lit < it2->lit2()
                && it2->lit2() < it2->lit3()
                && it2->learnt()
            ) {
                if (lit.sign()) votes[lit.var()] += 0.3;
                else votes[lit.var()] -= 0.3;

                Lit lit2 = it2->lit2();
                if (lit2.sign()) votes[lit2.var()] += 0.3;
                else votes[lit2.var()] -= 0.3;

                Lit lit3 = it2->lit3();
                if (lit3.sign()) votes[lit3.var()] += 0.3;
                else votes[lit3.var()] -= 0.3;
            }
        }
    }
}
Beispiel #27
0
Lit Prober::update_lit_for_dominator(
    Lit lit
) {
    if (solver->conf.doCache) {
        if (solver->litReachable[lit.toInt()].lit != lit_Undef) {
            const Lit betterlit = solver->litReachable[lit.toInt()].lit;
            if (solver->value(betterlit.var()) == l_Undef
                && solver->varData[betterlit.var()].removed == Removed::none
            ) {
                //Update lit
                lit = betterlit;
            }
        }
    }

    return lit;
}
Beispiel #28
0
bool BVA::try_bva_on_lit(const Lit lit)
{
    assert(solver->value(lit) == l_Undef);
    assert(solver->varData[lit.var()].removed == Removed::none);

    m_cls.clear();
    m_lits.clear();
    m_lits.push_back(lit);
    *simplifier->limit_to_decrease -= solver->watches[lit].size();
    for(const Watched w: solver->watches[lit]) {
        if (!solver->redundant(w)) {
            m_cls.push_back(OccurClause(lit, w));
            if (solver->conf.verbosity >= 6 || bva_verbosity) {
                cout << "1st adding to m_cls "
                     << solver->watched_to_string(lit, w)
                     << endl;
            }
        }
    }
    remove_duplicates_from_m_cls();

    while(true) {
        potential.clear();
        fill_potential(lit);
        if (*simplifier->limit_to_decrease < 0) {
            return solver->okay();
        }

        size_t num_occur;
        const lit_pair l_max = most_occuring_lit_in_potential(num_occur);
        if (simplifies_system(num_occur)) {
            m_lits.push_back(l_max);
            m_cls.clear();
            *simplifier->limit_to_decrease -= potential.size()*3;
            for(const PotentialClause pot: potential) {
                if (pot.lits == l_max) {
                    m_cls.push_back(pot.occur_cl);
                    if (solver->conf.verbosity >= 6 || bva_verbosity) {
                        cout << "-- max is : (" << l_max.lit1 << ", " << l_max.lit2 << "), adding to m_cls "
                             << solver->watched_to_string(pot.occur_cl.lit, pot.occur_cl.ws)
                             << endl;
                    }
                    assert(pot.occur_cl.lit == lit);
                }
            }
        } else {
            break;
        }
    }

    const int simp_size = simplification_size(m_lits.size(), m_cls.size());
    if (simp_size <= 0) {
        return solver->okay();
    }

    const bool ok = bva_simplify_system();
    return ok;
}
Beispiel #29
0
void CompHandler::move_binary_clause(
    SATSolver* newSolver
    , const uint32_t comp
    ,  Watched *i
    , const Lit lit
) {
    const Lit lit2 = i->lit2();

    //Unless redundant, cannot be in 2 comps at once
    assert((compFinder->getVarComp(lit.var()) == comp
                && compFinder->getVarComp(lit2.var()) == comp
           ) || i->red()
    );

    //If it's redundant and the lits are in different comps, remove it.
    if (compFinder->getVarComp(lit.var()) != comp
        || compFinder->getVarComp(lit2.var()) != comp
    ) {
        //Can only be redundant, otherwise it would be in the same
        //component
        assert(i->red());

        //The way we go through this, it's definitely going to be
        //lit2 that's in the other component
        assert(compFinder->getVarComp(lit2.var()) != comp);

        remove_bin_except_for_lit1(lit, lit2);
        return;
    }

    //don't add the same clause twice
    if (lit < lit2) {

        //Add clause
        tmp_lits = {upd_bigsolver_to_smallsolver(lit), upd_bigsolver_to_smallsolver(lit2)};
        assert(compFinder->getVarComp(lit.var()) == comp);
        assert(compFinder->getVarComp(lit2.var()) == comp);

        //Add new clause
        if (i->red()) {
            //newSolver->addRedClause(tmp_lits);
            numRemovedHalfRed++;
        } else {
            //Save backup
            saveClause(vector<Lit>{lit, lit2});

            newSolver->add_clause(tmp_lits);
            numRemovedHalfIrred++;
        }
    } else {

        //Just remove, already added above
        if (i->red()) {
            numRemovedHalfRed++;
        } else {
            numRemovedHalfIrred++;
        }
    }
}
Beispiel #30
0
void Prober::update_cache(Lit thisLit, Lit lit, size_t numElemsSet)
{
    //Update cache, if the trail was within limits (cacheUpdateCutoff)
    const Lit ancestor = solver->varData[thisLit.var()].reason.getAncestor();
    if (solver->conf.doCache
        && thisLit != lit
        && numElemsSet <= solver->conf.cacheUpdateCutoff
        //&& cacheUpdated[(~ancestor).toInt()] == 0
    ) {
        //Update stats/markings
        //cacheUpdated[(~ancestor).toInt()]++;
        extraTime += 1;
        extraTimeCache += solver->implCache[~ancestor].lits.size()/30;
        extraTimeCache += solver->implCache[~thisLit].lits.size()/30;

        const bool redStep = solver->varData[thisLit.var()].reason.isRedStep();

        //Update the cache now
        assert(ancestor != lit_Undef);
        bool taut = solver->implCache[~ancestor].merge(
            solver->implCache[~thisLit].lits
            , thisLit
            , redStep
            , ancestor.var()
            , solver->seen
        );

        //If tautology according to cache we can
        //enqueue ~ancestor at toplevel since both
        //~ancestor V OTHER, and ~ancestor V ~OTHER are technically in
        if (taut
            && solver->varData[ancestor.var()].removed == Removed::none
        ) {
            toEnqueue.push_back(~ancestor);
            if (solver->conf.verbosity >= 10)
                cout << "c Tautology from cache indicated we can enqueue " << (~ancestor) << endl;
        }

        #ifdef VERBOSE_DEBUG_FULLPROP
        cout << "The impl cache of " << (~ancestor) << " is now: ";
        cout << solver->implCache[(~ancestor).toInt()] << endl;
        #endif
    }
}