Ejemplo n.º 1
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;
}
Ejemplo n.º 2
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));
}
void DistillerLongWithImpl::strengthen_clause_with_watch(
    const Lit lit
    , const Watched* wit
) {
    //Strengthening w/ bin
    if (wit->isBin()
        && seen[lit.toInt()] //We haven't yet removed it
    ) {
        if (seen[(~wit->lit2()).toInt()]) {
            thisRemLitBinTri++;
            seen[(~wit->lit2()).toInt()] = 0;
        }
    }

    //Strengthening w/ tri
    if (wit->isTri()
        && seen[lit.toInt()] //We haven't yet removed it
    ) {
        if (seen[(wit->lit2()).toInt()]) {
            if (seen[(~wit->lit3()).toInt()]) {
                thisRemLitBinTri++;
                seen[(~wit->lit3()).toInt()] = 0;
            }
        } else if (seen[wit->lit3().toInt()]) {
            if (seen[(~wit->lit2()).toInt()]) {
                thisRemLitBinTri++;
                seen[(~wit->lit2()).toInt()] = 0;
            }
        }
    }
}
Ejemplo n.º 4
0
void GateFinder::set_seen2_tri(
    const OrGate& gate
    , const bool only_irred
) {
    assert(seen2Set.empty());
    watch_subarray_const csOther = solver->watches[~(gate.lit2)];
    *simplifier->limit_to_decrease -= csOther.size();
    for (const Watched ws: csOther) {
        if (!ws.isTri())
            continue;

        if (ws.red() && only_irred)
            continue;

        //We might be contracting 2 irred clauses based on a learnt gate
        //would lead to UNSAT->SAT
        if (!ws.red() && gate.red)
            continue;

        const Lit lits[2] = {ws.lit2(), ws.lit3()};
        for (size_t i = 0; i < 2; i++) {
            const Lit lit = lits[i];
            if (!seen2[lit.toInt()]) {
                seen2[lit.toInt()] = 1;
                seen2Set.push_back(lit.toInt());
            }
        }
    }
}
Ejemplo n.º 5
0
void OnlyNonLearntBins::removeBin(Lit lit1, Lit lit2)
{
    uint32_t index0 = lit1.toInt();
    uint32_t index1 = lit2.toInt();
    if (index1 > index0) std::swap(index0, index1);
    uint64_t final = index0;
    final |= ((uint64_t)index1) << 32;
Ejemplo n.º 6
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;
}
Ejemplo n.º 7
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.toInt()].size();
    for(const Watched w: solver->watches[lit.toInt()]) {
        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;
}
Ejemplo n.º 8
0
void DataSync::addOneBinToOthers(const Lit lit1, const Lit lit2)
{
    assert(lit1.toInt() < lit2.toInt());

    vector<Lit>& bins = sharedData->bins[(~lit1).toInt()];
    for (vector<Lit>::const_iterator it = bins.begin(), end = bins.end(); it != end; it++) {
        if (*it == lit2) return;
    }

    bins.push_back(lit2);
    sentBinData++;
}
Ejemplo n.º 9
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;
}
Ejemplo n.º 10
0
void PropEngine::detach_bin_clause(
    const Lit lit1
    , const Lit lit2
    , const bool red
    , const bool allow_empty_watch
) {
    if (!(allow_empty_watch && watches[lit1.toInt()].empty())) {
        removeWBin(watches, lit1, lit2, red);
    }
    if (!(allow_empty_watch && watches[lit2.toInt()].empty())) {
        removeWBin(watches, lit2, lit1, red);
    }
}
Ejemplo n.º 11
0
/**
@brief Detaches a (potentially) modified clause

The first two literals might have chaned through modification, so they are
passed along as arguments -- they are needed to find the correct place where
the clause is
*/
void PropEngine::detach_modified_clause(
    const Lit lit1
    , const Lit lit2
    , const uint32_t origSize
    , const Clause* address
) {
    assert(origSize > 3);
    if (address->red() && red_long_cls_is_reducedb(*address)) {
        num_red_cls_reducedb--;
    }

    ClOffset offset = cl_alloc.get_offset(address);
    removeWCl(watches[lit1.toInt()], offset);
    removeWCl(watches[lit2.toInt()], offset);
}
Ejemplo n.º 12
0
void DataSync::addOneBinToOthers(Lit lit1, Lit lit2)
{
    assert(lit1 < lit2);
    if (sharedData->bins[lit1.toInt()].data == NULL) {
        return;
    }

    vector<Lit>& bins = *sharedData->bins[lit1.toInt()].data;
    for (const Lit lit : bins) {
        if (lit == lit2)
            return;
    }

    bins.push_back(lit2);
    stats.sentBinData++;
}
bool DistillerLongWithImpl::str_and_sub_clause_with_cache(const Lit lit, const bool alsoStrengthen)
{
    if (solver->conf.doCache
        && seen[lit.toInt()] //We haven't yet removed this literal from the clause
     ) {
        timeAvailable -= (1+(int)alsoStrengthen)*(long)solver->implCache[lit].lits.size();
        for (const LitExtra elit: solver->implCache[lit].lits) {
             if (alsoStrengthen
                && seen[(~(elit.getLit())).toInt()]
            ) {
                seen[(~(elit.getLit())).toInt()] = 0;
                thisRemLitCache++;
             }

             if (seen2[elit.getLit().toInt()]
                 && elit.getOnlyIrredBin()
             ) {
                 isSubsumed = true;
                 cache_based_data.subCache++;
                 return true;
             }
         }

         return false;
     }

     return false;
}
Ejemplo n.º 14
0
bool TransCache::mergeHelper(
    const Lit extraLit //Add this, too to the list of lits
    , const bool red //The step was a redundant-dependent step?
    , vector<uint16_t>& seen
) {
    bool taut = false;

    //Handle extra lit
    if (extraLit != lit_Undef)
        seen[extraLit.toInt()] = 1 + (int)!red;

    //Everything that's already in the cache, set seen[] to zero
    //Also, if seen[] is 2, but it's marked redundant in the cache
    //mark it as irred
    for (size_t i = 0, size = lits.size(); i < size; i++) {
        if (!red
            && !lits[i].getOnlyIrredBin()
            && seen[lits[i].getLit().toInt()] == 2
        ) {
            lits[i].setOnlyIrredBin();
        }

        seen[lits[i].getLit().toInt()] = 0;

        //Both L and ~L are in, the ancestor is a tautology
        if (seen[(~(lits[i].getLit())).toInt()]) {
            taut = true;
        }
    }

    return taut;
}
Ejemplo n.º 15
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());
}
Ejemplo n.º 16
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;
}
Ejemplo n.º 17
0
void BVA::update_touched_lits_in_bva()
{
    const vector<uint32_t>& touched_list = touched.getTouchedList();
    for(const uint32_t lit_uint: touched_list) {
        const Lit lit = Lit::toLit(lit_uint);
        if (var_bva_order.in_heap(lit.toInt())) {
            watch_irred_sizes[lit.toInt()] = calc_watch_irred_size(lit);
            var_bva_order.update_if_inside(lit.toInt());
        }

        if (var_bva_order.in_heap((~lit).toInt())) {
            watch_irred_sizes[(~lit).toInt()] = calc_watch_irred_size(~lit);
            var_bva_order.update_if_inside((~lit).toInt());
        }
    }
    touched.clear();
}
Ejemplo n.º 18
0
void FeaturesCalc::for_all_clauses(Function func_each_cl, Function2 func_each_lit) const
{
    for (size_t i = 0; i < solver->nVars() * 2; i++) {
        Lit lit = Lit::toLit(i);
        for (const Watched & w : solver->watches[lit.toInt()]) {
            for_one_clause(w, lit, func_each_cl, func_each_lit);
        }
    }
}
Ejemplo n.º 19
0
void GateFinder::find_or_gates_in_sweep_mode(const Lit lit)
{
    assert(toClear.empty());
    watch_subarray_const ws = solver->watches[lit.toInt()];
    *simplifier->limit_to_decrease -= ws.size();
    for(const Watched w: ws) {
        if (w.isBinary() && !w.red()) {
            seen[(~w.lit2()).toInt()] = 1;
            toClear.push_back(~w.lit2());
        }
    }

    if (solver->conf.doCache && solver->conf.otfHyperbin) {
        const vector<LitExtra>& cache = solver->implCache[lit.toInt()].lits;
        *simplifier->limit_to_decrease -= cache.size();
        for(const LitExtra l: cache) {
             if (l.getOnlyIrredBin()) {
                seen[(~l.getLit()).toInt()] = 1;
                toClear.push_back(~l.getLit());
            }
        }
    }

    watch_subarray_const ws2 = solver->watches[(~lit).toInt()];
    *simplifier->limit_to_decrease -= ws2.size();
    for(const Watched w: ws2) {
        if (w.isTri()
            && !w.red()
            && (seen[w.lit2().toInt()]
                || (solver->conf.doStamp && solver->conf.otfHyperbin && solver->find_with_stamp_a_or_b(~w.lit2(), lit)))
            && (seen[w.lit3().toInt()]
                || (solver->conf.doStamp && solver->conf.otfHyperbin && solver->find_with_stamp_a_or_b(~w.lit3(), lit)))
        ) {
            add_gate_if_not_already_inside(lit, w.lit2(), w.lit3());
        }
    }

    *simplifier->limit_to_decrease -= toClear.size();
    for(const Lit toclear: toClear) {
        seen[toclear.toInt()] = 0;
    }
    toClear.clear();
}
Ejemplo n.º 20
0
void PropEngine::attach_bin_clause(
    const Lit lit1
    , const Lit lit2
    , const bool red
    , const bool checkUnassignedFirst
) {
    #ifdef DEBUG_ATTACH
    assert(lit1.var() != lit2.var());
    if (checkUnassignedFirst) {
        assert(value(lit1.var()) == l_Undef);
        assert(value(lit2) == l_Undef || value(lit2) == l_False);
    }

    assert(varData[lit1.var()].removed == Removed::none);
    assert(varData[lit2.var()].removed == Removed::none);
    #endif //DEBUG_ATTACH

    watches[lit1.toInt()].push(Watched(lit2, red));
    watches[lit2.toInt()].push(Watched(lit1, red));
}
Ejemplo n.º 21
0
bool UselessBinRemover::removeUselessBinaries(const Lit& lit)
{
    solver.newDecisionLevel();
    solver.uncheckedEnqueueLight(lit);
    failed = !onlyNonLearntBins.propagateBinOneLevel();
    if (failed) return false;
    bool ret = true;

    oneHopAway.clear();
    assert(solver.decisionLevel() > 0);
    int c;
    if (solver.trail.size()-solver.trail_lim[0] == 0) {
        solver.cancelUntil(0);
        goto end;
    }
    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];
        toDeleteSet[x.toInt()] = true;
        oneHopAway.push(x);
        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);

    wrong.clear();
    for(uint32_t i = 0; i < oneHopAway.size(); i++) {
        //no need to visit it if it already queued for removal
        //basically, we check if it's in 'wrong'
        if (toDeleteSet[oneHopAway[i].toInt()]) {
            if (!fillBinImpliesMinusLast(lit, oneHopAway[i], wrong)) {
                ret = false;
                goto end;
            }
        }
    }

    for (uint32_t i = 0; i < wrong.size(); i++) {
        removeBin(~lit, wrong[i]);
    }

    end:
    for(uint32_t i = 0; i < oneHopAway.size(); i++) {
        toDeleteSet[oneHopAway[i].toInt()] = false;
    }

    return ret;
}
Ejemplo n.º 22
0
void RestartTypeChooser::addDegreesBin(vector<uint32_t>& degrees) const
{
    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() && lit.toInt() < it2->getOtherLit().toInt()) {
                degrees[lit.var()]++;
                degrees[it2->getOtherLit().var()]++;
            }
        }
    }
}
Ejemplo n.º 23
0
void VarReplacer::updateBin(
    watch_subarray::iterator& i
    , watch_subarray::iterator& j
    , const Lit origLit1
    , const Lit origLit2
    , Lit lit1
    , Lit lit2
) {
    bool remove = false;

    //Two lits are the same in BIN
    if (lit1 == lit2) {
        delayedEnqueue.push_back(lit2);
        (*solver->drup) << lit2 << fin;
        remove = true;
    }

    //Tautology
    if (lit1 == ~lit2)
        remove = true;

    if (remove) {
        impl_tmp_stats.remove(*i);

        //Drup -- Delete only once
        if (origLit1 < origLit2) {
            (*solver->drup) << del << origLit1 << origLit2 << fin;
        }

        return;
    }

    //Drup
    if (//Changed
        (lit1 != origLit1
            || lit2 != origLit2)
        //Delete&attach only once
        && (origLit1 < origLit2)
    ) {
        (*solver->drup)
        << lit1 << lit2 << fin
        << del << origLit1 << origLit2 << fin;
    }

    if (lit1 != origLit1) {
        solver->watches[lit1.toInt()].push(*i);
    } else {
        *j++ = *i;
    }
}
Ejemplo n.º 24
0
void PropEngine::attach_tri_clause(
    Lit lit1
    , Lit lit2
    , Lit lit3
    , const bool red
) {
    #ifdef DEBUG_ATTACH
    assert(lit1.var() != lit2.var());
    assert(value(lit1.var()) == l_Undef);
    assert(value(lit2) == l_Undef || value(lit2) == l_False);

    assert(varData[lit1.var()].removed == Removed::none);
    assert(varData[lit2.var()].removed == Removed::none);
    #endif //DEBUG_ATTACH

    //Order them
    orderLits(lit1, lit2, lit3);

    //And now they are attached, ordered
    watches[lit1.toInt()].push(Watched(lit2, lit3, red));
    watches[lit2.toInt()].push(Watched(lit1, lit3, red));
    watches[lit3.toInt()].push(Watched(lit1, lit2, red));
}
Ejemplo n.º 25
0
bool GateFinder::check_seen_and_gate_against_lit(
    const Lit lit
    , const OrGate& gate
) {
    //If some weird variable is inside, skip
    if (   lit.var() == gate.lit2.var()
        || lit.var() == gate.rhs.var()
        //A lit is inside this clause isn't inside the others
        || !seen2[lit.toInt()]
    ) {
        return false;
    }

    return true;
}
Ejemplo n.º 26
0
size_t BVA::calc_watch_irred_size(const Lit lit) const
{
    size_t num = 0;
    watch_subarray_const ws = solver->watches[lit.toInt()];
    for(const Watched w: ws) {
        if (w.isBinary() || w.isTri()) {
            num += !w.red();
            continue;
        }

        assert(w.isClause());
        const Clause& cl = *solver->cl_alloc.ptr(w.get_offset());
        num += !cl.red();
    }

    return num;
}
Ejemplo n.º 27
0
/**
@brief Propagate recursively on non-learnt binaries
*/
bool OnlyNonLearntBins::propagate()
{
    while (solver.qhead < solver.trail.size()) {
        Lit p = solver.trail[solver.qhead++];
        vec<WatchedBin> & wbin = binwatches[p.toInt()];
        solver.propagations += wbin.size()/2 + 2;
        for(WatchedBin *k = wbin.getData(), *end = wbin.getDataEnd(); k != end; k++) {
            lbool val = solver.value(k->impliedLit);
            if (val.isUndef()) {
                solver.uncheckedEnqueueLight(k->impliedLit);
            } else if (val == l_False) {
                return false;
            }
        }
    }

    return true;
}
Ejemplo n.º 28
0
void PropEngine::printWatchList(const Lit lit) const
{
    watch_subarray_const ws = watches[lit.toInt()];
    for (watch_subarray_const::const_iterator
        it2 = ws.begin(), end2 = ws.end()
        ; it2 != end2
        ; it2++
    ) {
        if (it2->isBinary()) {
            cout << "bin: " << lit << " , " << it2->lit2() << " red : " <<  (it2->red()) << endl;
        } else if (it2->isTri()) {
            cout << "tri: " << lit << " , " << it2->lit2() << " , " <<  (it2->lit3()) << endl;
        } else if (it2->isClause()) {
            cout << "cla:" << it2->get_offset() << endl;
        } else {
            assert(false);
        }
    }
}
Ejemplo n.º 29
0
Lit HyperEngine::propagate_dfs(
    const StampType stampType
    , const uint64_t timeout
) {
    timedOutPropagateFull = false;
    propStats.otfHyperPropCalled++;
    #ifdef VERBOSE_DEBUG_FULLPROP
    cout << "Prop full 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);
    }

    //Set up stacks
    toPropBin.clear();
    toPropRedBin.clear();
    toPropNorm.clear();

    Lit root = trail.back();
    toPropBin.push(root);
    toPropNorm.push(root);
    if (stampType == STAMP_RED)
        toPropRedBin.push(root);

    //Setup
    needToAddBinClause.clear();
    stamp.stampingTime++;
    stamp.tstamp[root.toInt()].start[stampType] = stamp.stampingTime;

    #ifdef DEBUG_STAMPING
    cout
    << "Top-enqueued << " << trail.back()
    << " for stamp.stampingTime " << stamp.stampingTime
    << endl;
    #endif

    while(true) {
        propStats.bogoProps += 3;
        if (need_early_abort_dfs(stampType, timeout))
            return lit_Undef;

        //Propagate binary irred
        bool restart = false;
        while (!toPropBin.empty()) {
            Lit ret = prop_irred_bin_dfs(stampType, confl, root, restart);
            if (ret != lit_Undef)
                return ret;
            if (restart)
                break;
        }
        if (restart)
            continue;

        if (stampType == STAMP_IRRED) {
            while (!toPropRedBin.empty()) {
                Lit ret = prop_red_bin_dfs(stampType, confl, root, restart);
                if (ret != lit_Undef)
                    return ret;
                if (restart)
                    break;
            }
        }
        if (restart)
            continue;

        while (!toPropNorm.empty()) {
            Lit ret = prop_larger_than_bin_cl_dfs(stampType, confl, root, restart);
            if (ret != lit_Undef)
                return ret;
            if (restart)
                break;

            qhead++;
        }
        if (restart)
            continue;

        //Nothing more to propagate
        break;
    }

    return lit_Undef;
}
Ejemplo n.º 30
0
Lit HyperEngine::prop_irred_bin_dfs(
    StampType stampType
    , PropBy& confl
    , const Lit //root
    , bool& restart
) {
    const Lit p = toPropBin.top();
    watch_subarray_const ws = watches[~p];
    size_t done = 0;
    for(watch_subarray::const_iterator
        k = ws.begin(), end = ws.end()
        ; k != end
        ; k++, done++
    ) {
        propStats.bogoProps += 1;
        //Pre-fetch long clause
        if (k->isClause()) {
            if (value(k->getBlockedLit()) != l_True) {
                const ClOffset offset = k->get_offset();
                __builtin_prefetch(cl_alloc.ptr(offset));
            }

            continue;
        } //end CLAUSE

        //If something other than binary, skip
        if (!k->isBin())
            continue;

        //If stamping only irred, go over red binaries
        if (stampType == STAMP_IRRED
            && k->red()
        ) {
            continue;
        }

        PropResult ret = prop_bin_with_ancestor_info(p, k, confl);
        switch(ret) {
            case PROP_FAIL:
                close_all_timestamps(stampType);
                return analyzeFail(confl);

            case PROP_SOMETHING:
                propStats.bogoProps += 8;
                stamp.stampingTime++;
                stamp.tstamp[trail.back().toInt()].start[stampType] = stamp.stampingTime;
                #ifdef DEBUG_STAMPING
                cout
                << "From " << p << " enqueued " << trail.back()
                << " for stamp.stampingTime " << stamp.stampingTime
                << endl;
                #endif

                toPropNorm.push(trail.back());
                toPropBin.push(trail.back());
                if (stampType == STAMP_IRRED) toPropRedBin.push(trail.back());
                propStats.bogoProps += done*4;
                restart = true;
                return lit_Undef;

            case PROP_NOTHING:
                break;
            default:
                assert(false);
                break;
        }
    }

    //Finished with this literal
    propStats.bogoProps += ws.size()*4;
    toPropBin.pop();
    stamp.stampingTime++;
    stamp.tstamp[p.toInt()].end[stampType] = stamp.stampingTime;
    #ifdef DEBUG_STAMPING
    cout
    << "End time for " << p
    << " is " << stamp.stampingTime
    << endl;
    #endif

    return lit_Undef;
}