/**
@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));
}
Example #2
0
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;
}
Example #3
0
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();
}
Example #5
0
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;
}
Example #7
0
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;
}
Example #8
0
/**
@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;
}