Skip to main content
  • Home
  • Development
  • Documentation
  • Donate
  • Operational login
  • Browse the archive

swh logo
SoftwareHeritage
Software
Heritage
Archive
Features
  • Search

  • Downloads

  • Save code now

  • Add forge now

  • Help

  • 2988e94
  • /
  • lcm.cc
Raw File Download

To reference or cite the objects present in the Software Heritage archive, permalinks based on SoftWare Hash IDentifiers (SWHIDs) must be used.
Select below a type of object currently browsed in order to display its associated SWHID and permalink.

  • content
  • directory
content badge
swh:1:cnt:67ab9d92634fcd9ba208b7e08343c02501ab68b8
directory badge
swh:1:dir:2988e946df67387fe9aa1e2daf701c46f71d6c18

This interface enables to generate software citations, provided that the root directory of browsed objects contains a citation.cff or codemeta.json file.
Select below a type of object currently browsed in order to generate citations for them.

  • content
  • directory
(requires biblatex-software package)
Generating citation ...
(requires biblatex-software package)
Generating citation ...
lcm.cc
#include "Solver.h"
#include "mtl/Sort.h"
using namespace Glucose;



// simplify All
//
CRef Solver::simplePropagate()
{
    CRef    confl = CRef_Undef;
    int     num_props = 0;
    watches.cleanAll();
    watchesBin.cleanAll();
    while (qhead < trail.size()){
        Lit            p = trail[qhead++];     // 'p' is enqueued fact to propagate.
        vec<Watcher>&  ws = watches[p];
        Watcher        *i, *j, *end;
        num_props++;

        // First, Propagate binary clauses
        vec<Watcher>&  wbin = watchesBin[p];

        for (int k = 0; k<wbin.size(); k++){

            Lit imp = wbin[k].blocker;

            if (value(imp) == l_False){
                return wbin[k].cref;
            }

            if (value(imp) == l_Undef){
                simpleUncheckEnqueue(imp, wbin[k].cref);
            }
        }
        for (i = j = (Watcher*)ws, end = i + ws.size(); i != end;){
            // Try to avoid inspecting the clause:
            Lit blocker = i->blocker;
            if (value(blocker) == l_True){
                *j++ = *i++; continue;
            }

            // Make sure the false literal is data[1]:
            CRef     cr = i->cref;
            Clause&  c = ca[cr];
            Lit      false_lit = ~p;
            if (c[0] == false_lit)
                c[0] = c[1], c[1] = false_lit;
            assert(c[1] == false_lit);
            //  i++;

            // If 0th watch is true, then clause is already satisfied.
            // However, 0th watch is not the blocker, make it blocker using a new watcher w
            // why not simply do i->blocker=first in this case?
            Lit     first = c[0];
            //  Watcher w     = Watcher(cr, first);
            if (first != blocker && value(first) == l_True){
                i->blocker = first;
                *j++ = *i++; continue;
            }

            // Look for new watch:
            if (incremental){ // ----------------- INCREMENTAL MODE
                int choosenPos = -1;
                for (int k = 2; k < c.size(); k++){
                    if (value(c[k]) != l_False){
                        if (decisionLevel()>assumptions.size()){
                            choosenPos = k;
                            break;
                        }
                        else{
                            choosenPos = k;

                            if (value(c[k]) == l_True || !isSelector(var(c[k]))) {
                                break;
                            }
                        }

                    }
                }
                if (choosenPos != -1){
                    // watcher i is abandonned using i++, because cr watches now ~c[k] instead of p
                    // the blocker is first in the watcher. However,
                    // the blocker in the corresponding watcher in ~first is not c[1]
                    Watcher w = Watcher(cr, first); i++;
                    c[1] = c[choosenPos]; c[choosenPos] = false_lit;
                    watches[~c[1]].push(w);
                    goto NextClause;
                }
            }
            else{  // ----------------- DEFAULT  MODE (NOT INCREMENTAL)
                for (int k = 2; k < c.size(); k++){

                    if (value(c[k]) != l_False){
                        // watcher i is abandonned using i++, because cr watches now ~c[k] instead of p
                        // the blocker is first in the watcher. However,
                        // the blocker in the corresponding watcher in ~first is not c[1]
                        Watcher w = Watcher(cr, first); i++;
                        c[1] = c[k]; c[k] = false_lit;
                        watches[~c[1]].push(w);
                        goto NextClause;
                    }
                }
            }

            // Did not find watch -- clause is unit under assignment:
            i->blocker = first;
            *j++ = *i++;
            if (value(first) == l_False){
                confl = cr;
                qhead = trail.size();
                // Copy the remaining watches:
                while (i < end)
                    *j++ = *i++;
            }
            else{
                simpleUncheckEnqueue(first, cr);
            }
            NextClause:;
        }
        ws.shrink(i - j);

        // unaryWatches "propagation"
        if(useUnaryWatched && confl == CRef_Undef) {
            confl = simplePropagateUnaryWatches(p);

        }
    }


    return confl;
}

CRef Solver::simplePropagateUnaryWatches(Lit p) {
    CRef confl = CRef_Undef;
    Watcher *i, *j, *end;
    vec <Watcher> &ws = unaryWatches[p];
    for(i = j = (Watcher *) ws, end = i + ws.size(); i != end;) {
        // Try to avoid inspecting the clause:
        Lit blocker = i->blocker;
        if(value(blocker) == l_True) {
            *j++ = *i++;
            continue;
        }

        // Make sure the false literal is data[1]:
        CRef cr = i->cref;
        Clause &c = ca[cr];
        assert(c.getOneWatched());
        Lit false_lit = ~p;
        assert(c[0] == false_lit); // this is unary watch... No other choice if "propagated"
        //if (c[0] == false_lit)
        //c[0] = c[1], c[1] = false_lit;
        //assert(c[1] == false_lit);
        i++;
        Watcher w = Watcher(cr, c[0]);
        for(int k = 1; k < c.size(); k++) {
            if(value(c[k]) != l_False) {
                c[0] = c[k];
                c[k] = false_lit;
                unaryWatches[~c[0]].push(w);
                goto NextClauseUnary;
            }
        }

        // Did not find watch -- clause is empty under assignment:
        *j++ = w;

        confl = cr;
        qhead = trail.size();
        // Copy the remaining watches:
        while(i < end)
            *j++ = *i++;

        NextClauseUnary:;
    }
    ws.shrink(i - j);

    return confl;
}


void Solver::simpleUncheckEnqueue(Lit p, CRef from){
    assert(value(p) == l_Undef);
    assigns[var(p)] = lbool(!sign(p)); // this makes a lbool object whose value is sign(p)
    vardata[var(p)].reason = from;
    trail.push_(p);
}

void Solver::cancelUntilTrailRecord()
{
    for (int c = trail.size() - 1; c >= trailRecord; c--)
    {
        Var x = var(trail[c]);
        assigns[x] = l_Undef;

    }
    qhead = trailRecord;
    trail.shrink(trail.size() - trailRecord);

}

void Solver::litsEnqueue(int cutP, Clause& c)
{
    for (int i = cutP; i < c.size(); i++)
    {
        simpleUncheckEnqueue(~c[i]);
    }
}

bool Solver::removed(CRef cr) {
    return ca[cr].mark() == 1;
}

void Solver::simpleAnalyze(CRef confl, vec<Lit>& out_learnt, vec<CRef>& reason_clause, bool True_confl)
{
    int pathC = 0;
    Lit p = lit_Undef;
    int index = trail.size() - 1;

    do{
        if (confl != CRef_Undef){
            reason_clause.push(confl);
            Clause& c = ca[confl];
            // Special case for binary clauses
            // The first one has to be SAT
            if (p != lit_Undef && c.size() == 2 && value(c[0]) == l_False) {

                assert(value(c[1]) == l_True);
                Lit tmp = c[0];
                c[0] = c[1], c[1] = tmp;
            }
            // if True_confl==true, then choose p begin with the 1th index of c;
            for (int j = (p == lit_Undef && True_confl == false) ? 0 : 1; j < c.size(); j++){
                Lit q = c[j];
                if (!seen[var(q)]){
                    seen[var(q)] = 1;
                    pathC++;
                }
            }
        }
        else if (confl == CRef_Undef){
            out_learnt.push(~p);
        }
        // if not break, while() will come to the index of trail blow 0, and fatal error occur;
        if (pathC == 0) break;
        // Select next clause to look at:
        while (!seen[var(trail[index--])]);
        // if the reason cr from the 0-level assigned var, we must break avoid move forth further;
        // but attention that maybe seen[x]=1 and never be clear. However makes no matter;
        if (trailRecord > index + 1) break;
        p = trail[index + 1];
        confl = reason(var(p));
        seen[var(p)] = 0;
        pathC--;

    } while (pathC >= 0);
}

void Solver::simplifyLearnt(Clause& c)
{
    stats[lcmtested]++;

    trailRecord = trail.size();// record the start pointer

    vec<Lit> falseLit;

    falseLit.clear();

    bool True_confl = false;
    int beforeSize, afterSize;
    beforeSize = c.size();
    int i, j;
    CRef confl;

    for (i = 0, j = 0; i < c.size(); i++){
        if (value(c[i]) == l_Undef){
            //printf("///@@@ uncheckedEnqueue:index = %d. l_Undef\n", i);
            simpleUncheckEnqueue(~c[i]);
            c[j++] = c[i];
            confl = simplePropagate();
            if (confl != CRef_Undef){
                break;
            }
        }
        else{
            if (value(c[i]) == l_True){
                //printf("///@@@ uncheckedEnqueue:index = %d. l_True\n", i);
                c[j++] = c[i];
                True_confl = true;
                confl = reason(var(c[i]));
                break;
            }
            else{
                falseLit.push(c[i]);
                //printf("///@@@ uncheckedEnqueue:index = %d. l_False\n", i);
            }
        }
    }
    c.shrink(c.size() - j);
    if (LCMUpdateLBD && c.lbd() > c.size()) c.setLBD(c.size());
    afterSize = c.size();

    if (confl != CRef_Undef || True_confl == true){
        simp_learnt_clause.clear();
        simp_reason_clause.clear();
        if (True_confl == true){
            simp_learnt_clause.push(c.last());
        }
        simpleAnalyze(confl, simp_learnt_clause, simp_reason_clause, True_confl);

        if (simp_learnt_clause.size() < c.size()){
            for (i = 0; i < simp_learnt_clause.size(); i++){
                c[i] = simp_learnt_clause[i];
            }
            c.shrink(c.size() - i);
            if (LCMUpdateLBD) {
                int nblevels = computeLBD(simp_learnt_clause);
                if (nblevels < c.lbd())
                    c.setLBD(nblevels);
            }
        }
    }

    cancelUntilTrailRecord();

}

bool Solver::simplifyAll()
{
    int nbGoodReduce = 0;
    int beforeSize, afterSize;
    int nbSize1 = 0, nbSize2 = 0;

    if (!ok || propagate() != CRef_Undef)
        return ok = false;

    removeSatisfied(clauses);

    int ci, cj, li, lj;
    bool sat, false_lit;
    unsigned int nblevels;
    vec<Lit> ori_c;

    if (0 && chanseokStrategy && permanentLearnts.size() > 0) {
        for (ci = 0, cj = 0; ci < permanentLearnts.size(); ci++){
            CRef cr = permanentLearnts[ci];
            Clause& c = ca[cr];

            if (!removed(cr)){
                sat = false_lit = false;
                for (int i = 0; i < c.size(); i++){
                    if (value(c[i]) == l_True){
                        sat = true;
                        break;
                    }
                    else if (value(c[i]) == l_False){
                        false_lit = true;
                    }
                }
                if (sat){
                    removeClause(cr);
                }
                else{
                    detachClause(cr, true);

                    if (false_lit){
                        for (li = lj = 0; li < c.size(); li++){
                            if (value(c[li]) != l_False){
                                c[lj++] = c[li];
                            }
                        }
                        c.shrink(li - lj);
                        if(certifiedUNSAT)
                            addToDrat(c, true);
                    }
                    ////
                    if (c.simplified() || c.lbd() > 3) {
                        attachClause(cr);
                        permanentLearntsReduced.push(cr); //[cj++] = permanentLearnts[ci];
                        // permanentLearnts[cj++] = permanentLearnts[ci];
                        continue;
                    }

                    beforeSize = c.size();
                    assert(c.size() > 1);
                    // simplify a learnt clause c
                    simplifyLearnt(c);
                    assert(c.size() > 0);
                    afterSize = c.size();

                    if (beforeSize > afterSize){
                        if (afterSize <= 3) {
                            nbGoodReduce++;
                            if (afterSize > 1) parallelExportClauseDuringSearch(c);
                            if (afterSize == 2){
                                nbSize2++;
                            }
                        }
                        if(certifiedOutput)
                            addToDrat(c, true);
                        stats[lcmreduced]++;
                    }

                    if (c.size() == 1){
                        nbSize1++;
                        // when unit clause occur, enqueue and propagate
                        uncheckedEnqueue(c[0]);
                        parallelExportUnaryClause(c[0]);
                        if (propagate() != CRef_Undef)
                        {
                            ok = false;
                            return false;
                        }
                        // delete the clause memory in logic
                        c.mark(1);
                        ca.free(cr);
                    }
                    else{
                        attachClause(cr);
                        permanentLearntsReduced.push(cr); //[cj++] = permanentLearnts[ci];
                        //permanentLearnts[cj++] = permanentLearnts[ci];
                        // TODO
                        /*nblevels = computeLBD(c);
                          if (nblevels < c.lbd()){
                          c.setLBD(nblevels);
                          }*/

                        c.setSimplified(true);
                    }
                }
            }
        }
        permanentLearnts.shrink(ci - cj);
    }

    if (!chanseokStrategy) {
        sort(learnts, reduceDB_lt(ca));

        for (ci = 0, cj = 0; ci < learnts.size(); ci++){
            CRef cr = learnts[ci];
            Clause& c = ca[cr];

            if (!removed(cr)){
                sat = false_lit = false;
                for (int i = 0; i < c.size(); i++){
                    if (value(c[i]) == l_True){
                        sat = true;
                        break;
                    }
                    else if (value(c[i]) == l_False){
                        false_lit = true;
                    }
                }
                if (sat){
                    removeClause(cr);
                }
                else{
                    detachClause(cr, true);

                    if (false_lit){
                        for (li = lj = 0; li < c.size(); li++){
                            if (value(c[li]) != l_False){
                                c[lj++] = c[li];
                            }
                        }
                        c.shrink(li - lj);
                        if(certifiedUNSAT)
                            addToDrat(c, true);
                    }
                    ////
                    if (ci < learnts.size() / 2 || c.simplified()) {
                        attachClause(cr);
                        learnts[cj++] = learnts[ci];
                        continue;
                    }

                    beforeSize = c.size();
                    assert(c.size() > 1);
                    // simplify a learnt clause c
                    simplifyLearnt(c);
                    assert(c.size() > 0);
                    afterSize = c.size();

                    if (beforeSize > afterSize){
                        if (afterSize <= 3) {
                            nbGoodReduce++;
                            if (afterSize > 1) parallelExportClauseDuringSearch(c);
                            if (afterSize == 2){
                                nbSize2++;
                            }
                        }
                        if(certifiedOutput)
                            addToDrat(c, true);
                        stats[lcmreduced]++;
                    }

                    if (c.size() == 1){
                        nbSize1++;
                        // when unit clause occur, enqueue and propagate
                        uncheckedEnqueue(c[0]);
                        parallelExportUnaryClause(c[0]);
                        if (propagate() != CRef_Undef)
                        {
                            ok = false;
                            return false;
                        }
                        // delete the clause memory in logic
                        c.mark(1);
                        ca.free(cr);
                    }
                    else{
                        attachClause(cr);
                        learnts[cj++] = learnts[ci];
                        // TODO
                        /*nblevels = computeLBD(c);
                          if (nblevels < c.lbd()){
                          c.setLBD(nblevels);
                          }*/

                        c.setSimplified(true);
                    }
                }
            }
        }
        learnts.shrink(ci - cj);
    }

    checkGarbage();

    return true;
}



back to top

Software Heritage — Copyright (C) 2015–2026, The Software Heritage developers. License: GNU AGPLv3+.
The source code of Software Heritage itself is available on our development forge.
The source code files archived by Software Heritage are available under their own copyright and licenses.
Terms of use: Archive access, API— Content policy— Contact— JavaScript license information— Web API