示例#1
0
/*_________________________________________________________________________________________________
|
|  search : (nof_conflicts : int) (nof_learnts : int) (params : const SearchParams&)  ->  [lbool]
|  
|  Description:
|    Search for a model the specified number of conflicts, keeping the number of learnt clauses
|    below the provided limit. NOTE! Use negative value for 'nof_conflicts' or 'nof_learnts' to
|    indicate infinity.
|  
|  Output:
|    'l_True' if a partial assigment that is consistent with respect to the clauseset is found. If
|    all variables are decision variables, this means that the clause set is satisfiable. 'l_False'
|    if the clause set is unsatisfiable. 'l_Undef' if the bound on number of conflicts is reached.
|________________________________________________________________________________________________@*/
lbool Solver::search(int nof_conflicts, int nof_learnts)
{

    assert(ok);
    int         backtrack_level;
    int         conflictC = 0;
    vec<Lit>    learnt_clause;

    starts++;
    for (;;){

#ifdef _DEBUGSEARCH
      for(int k=0; k<decisionLevel(); ++k) 
	std::cout << "  ";
      std::cout << "propagate" << std::endl;
#endif
      
        Clause* confl = propagate();
        if (confl != NULL){
            // CONFLICT
            conflicts++; conflictC++;
            if (decisionLevel() <= init_level) {

#ifdef _DEBUGSEARCH
	      std::cout << "infeasible" << std::endl;
#endif

	      return l_False;
	    }

            learnt_clause.clear();
            analyze(confl, learnt_clause, backtrack_level);
            cancelUntil(backtrack_level);

#ifdef _DEBUGSEARCH
	    for(int k=0; k<decisionLevel(); ++k) 
	      std::cout << "  ";
	    std::cout << "backtrack to " << decisionLevel() << std::endl;
#endif

            assert(value(learnt_clause[0]) == l_Undef);

            if (learnt_clause.size() == 1){
                uncheckedEnqueue(learnt_clause[0]);

#ifdef _DEBUGSEARCH
		for(int k=0; k<decisionLevel(); ++k) 
		  std::cout << "  ";
		std::cout << "deduce " ;
		printLit(learnt_clause[0]);
		std::cout << std::endl;
#endif

            }else{
                Clause* c = Clause_new(learnt_clause, true);

#ifdef _DEBUGSEARCH
		for(int k=0; k<decisionLevel(); ++k) 
		  std::cout << "  ";
		std::cout << "deduce ";
		printClause(*c);
		std::cout << std::endl;
#endif

                learnts.push(c);
                attachClause(*c);
                claBumpActivity(*c);
                uncheckedEnqueue(learnt_clause[0], c);
            }

            varDecayActivity();
            claDecayActivity();

        }else{
            // NO CONFLICT

            if (nof_conflicts >= 0 && conflictC >= nof_conflicts){
                // Reached bound on number of conflicts:
                progress_estimate = progressEstimate();
                cancelUntil(0);
                return l_Undef; }

            // Simplify the set of problem clauses:
            if (decisionLevel() == 0 && !simplify())
                return l_False;

            if (nof_learnts >= 0 && learnts.size()-nAssigns() >= nof_learnts)
                // Reduce the set of learnt clauses:
                reduceDB();

            Lit next = lit_Undef;
            while (decisionLevel() < assumptions.size()){

                // Perform user provided assumption:
                Lit p = assumptions[decisionLevel()];
                if (value(p) == l_True){
                    // Dummy decision level:
                    newDecisionLevel();
                }else if (value(p) == l_False){
                    analyzeFinal(~p, conflict);
                    return l_False;
                }else{
                    next = p;
                    break;
                }
            }

            if (next == lit_Undef){
                // New variable decision:
                decisions++;
                next = pickBranchLit(polarity_mode, random_var_freq);

                if (next == lit_Undef)
                    // Model found:
                    return l_True;
            }

#ifdef _DEBUGSEARCH
	    for(int k=0; k<decisionLevel(); ++k) 
	      std::cout << "  ";
	    std::cout << "branch on " ;
	    printLit(next);
	    std::cout << std::endl;
#endif

            // Increase decision level and enqueue 'next'
            assert(value(next) == l_Undef);
            newDecisionLevel();
            uncheckedEnqueue(next);
        }
    }
}
示例#2
0
/*_________________________________________________________________________________________________
|
|  newClause : (ps : const vec<Lit>&) (learnt : bool)  ->  [void]
|  
|  Description:
|    Allocate and add a new clause to the SAT solvers clause database. If a conflict is detected,
|    the 'ok' flag is cleared and the solver is in an unusable state (must be disposed).
|  
|  Input:
|    ps     - The new clause as a vector of literals.
|    learnt - Is the clause a learnt clause? For learnt clauses, 'ps[0]' is assumed to be the
|             asserting literal. An appropriate 'enqueue()' operation will be performed on this
|             literal. One of the watches will always be on this literal, the other will be set to
|             the literal with the highest decision level.
|  
|  Effect:
|    Activity heuristics are updated.
|________________________________________________________________________________________________@*/
void Solver::newClause(const vec<Lit>& ps_, bool learnt)
{
    if (!ok) return;

    vec<Lit>    qs;
    if (!learnt){
        assert(decisionLevel() == 0);
        ps_.copyTo(qs);             // Make a copy of the input vector.

        // Remove duplicates:
        sortUnique(qs);

        // Check if clause is satisfied:
        for (int i = 0; i < qs.size()-1; i++){
            if (qs[i] == ~qs[i+1])
                return; }
        for (int i = 0; i < qs.size(); i++){
            if (value(qs[i]) == l_True)
                return; }

        // Remove false literals:
        int     i, j;
        for (i = j = 0; i < qs.size(); i++)
            if (value(qs[i]) != l_False)
                qs[j++] = qs[i];
        qs.shrink(i - j);
    }
    const vec<Lit>& ps = learnt ? ps_ : qs;     // 'ps' is now the (possibly) reduced vector of literals.

    if (ps.size() == 0){
        ok = false;

    }else if (ps.size() == 1){
        // NOTE: If enqueue takes place at root level, the assignment will be lost in incremental use (it doesn't seem to hurt much though).
        if (!enqueue(ps[0]))
            ok = false;

    }else if (ps.size() == 2){
        // Create special binary clause watch:
        watches[index(~ps[0])].push(GClause_new(ps[1]));
        watches[index(~ps[1])].push(GClause_new(ps[0]));

        if (learnt){
            check(enqueue(ps[0], GClause_new(~ps[1])));
            stats.learnts_literals += ps.size();
        }else
            stats.clauses_literals += ps.size();
        n_bin_clauses++;

    }else{
        // Allocate clause:
        Clause* c   = Clause_new(learnt, ps);

        if (learnt){
            // Put the second watch on the literal with highest decision level:
            int     max_i = 1;
            int     max   = level[var(ps[1])];
            for (int i = 2; i < ps.size(); i++)
                if (level[var(ps[i])] > max)
                    max   = level[var(ps[i])],
                    max_i = i;
            (*c)[1]     = ps[max_i];
            (*c)[max_i] = ps[1];

            // Bump, enqueue, store clause:
            claBumpActivity(c);         // (newly learnt clauses should be considered active)
            check(enqueue((*c)[0], GClause_new(c)));
            learnts.push(c);
            stats.learnts_literals += c->size();
        }else{
            // Store clause:
            clauses.push(c);
            stats.clauses_literals += c->size();
        }
        // Watch clause:
        watches[index(~(*c)[0])].push(GClause_new(c));
        watches[index(~(*c)[1])].push(GClause_new(c));
    }
}
示例#3
0
/*_________________________________________________________________________________________________
|
|  analyze : (confl : Clause*) (out_learnt : vec<Lit>&) (out_btlevel : int&)  ->  [void]
|  
|  Description:
|    Analyze conflict and produce a reason clause.
|  
|    Pre-conditions:
|      * 'out_learnt' is assumed to be cleared.
|      * Current decision level must be greater than root level.
|  
|    Post-conditions:
|      * 'out_learnt[0]' is the asserting literal at level 'out_btlevel'.
|  
|  Effect:
|    Will undo part of the trail, upto but not beyond the assumption of the current decision level.
|________________________________________________________________________________________________@*/
void Solver::analyze(Clause* confl, vec<Lit>& out_learnt, int& out_btlevel)
{
    int pathC = 0;
    Lit p     = lit_Undef;

    // Generate conflict clause:
    //
    out_learnt.push();      // (leave room for the asserting literal)
    int index   = trail.size() - 1;
    out_btlevel = 0;

    do{
        assert(confl != NULL);          // (otherwise should be UIP)
        Clause& c = *confl;

        if (c.learnt())
            claBumpActivity(c);

        for (int j = (p == lit_Undef) ? 0 : 1; j < c.size(); j++){
            Lit q = c[j];

            if (!seen[var(q)] && level[var(q)] > 0){
                varBumpActivity(var(q));
                seen[var(q)] = 1;
                if (level[var(q)] >= decisionLevel())
                    pathC++;
                else{
                    out_learnt.push(q);
                    if (level[var(q)] > out_btlevel)
                        out_btlevel = level[var(q)];
                }
            }
        }

        // Select next clause to look at:
        while (!seen[var(trail[index--])]);
        p     = trail[index+1];
        confl = reason[var(p)];
        seen[var(p)] = 0;
        pathC--;

    }while (pathC > 0);
    out_learnt[0] = ~p;

    // Simplify conflict clause:
    //
    int i, j;
    if (expensive_ccmin){
        uint32_t abstract_level = 0;
        for (i = 1; i < out_learnt.size(); i++)
            abstract_level |= abstractLevel(var(out_learnt[i])); // (maintain an abstraction of levels involved in conflict)

        out_learnt.copyTo(analyze_toclear);
        for (i = j = 1; i < out_learnt.size(); i++)
            if (reason[var(out_learnt[i])] == NULL || !litRedundant(out_learnt[i], abstract_level))
                out_learnt[j++] = out_learnt[i];
    }else{
        out_learnt.copyTo(analyze_toclear);
        for (i = j = 1; i < out_learnt.size(); i++){
            Clause& c = *reason[var(out_learnt[i])];
            for (int k = 1; k < c.size(); k++)
                if (!seen[var(c[k])] && level[var(c[k])] > 0){
                    out_learnt[j++] = out_learnt[i];
                    break; }
        }
    }
    max_literals += out_learnt.size();
    out_learnt.shrink(i - j);
    tot_literals += out_learnt.size();

    // Find correct backtrack level:
    //
    if (out_learnt.size() == 1)
      out_btlevel = init_level;
    else{
        int max_i = 1;
        for (int i = 2; i < out_learnt.size(); i++)
            if (level[var(out_learnt[i])] > level[var(out_learnt[max_i])])
                max_i = i;
        Lit p             = out_learnt[max_i];
        out_learnt[max_i] = out_learnt[1];
        out_learnt[1]     = p;
        out_btlevel       = level[var(p)];
    }


    for (int j = 0; j < analyze_toclear.size(); j++) seen[var(analyze_toclear[j])] = 0;    // ('seen[]' is now cleared)
}
示例#4
0
lbool Solver::search(int nof_conflicts, int nof_learnts)
{
    assert(ok);
    int         backtrack_level;
    int         conflictsC = 0;
    vec<Lit>    learnt_clause;
    int nblevels=0,nbCC=0,merged=0;
    starts++;
    bool first = true;

    for (;;){

        Clause* confl = propagate();
        if (confl != NULL){
            // CONFLICT
	  conflicts++; conflictsC++;cons++;nbCC++;
            if (decisionLevel() == 0) return l_False;

            first = false;

            learnt_clause.clear();
            analyze(confl, learnt_clause, backtrack_level,nblevels,merged);


	    conf4Stats++;
	    nbDecisionLevelHistory.push(nblevels);
	    totalSumOfDecisionLevel += nblevels;
	    
	    cancelUntil(backtrack_level);
	    assert(value(learnt_clause[0]) == l_Undef);
	    
	    if (learnt_clause.size() == 1){
	      uncheckedEnqueue(learnt_clause[0]);
	      nbUn++;
            }else{
	      Clause* c = Clause_new(learnt_clause, true);
	      learnts.push(c);
	      c->setActivity(nblevels); // LS
	      if(nblevels<=2) nbDL2++;
	      if(c->size()==2) nbBin++;
	      attachClause(*c);
	      claBumpActivity(*c);
	      uncheckedEnqueue(learnt_clause[0], c);
            }
	      varDecayActivity();
	      claDecayActivity();
        }else{
	  if (
	      ( nbDecisionLevelHistory.isvalid() && 
		((nbDecisionLevelHistory.getavg()*0.7) > (totalSumOfDecisionLevel / conf4Stats)))) {
	      nbDecisionLevelHistory.fastclear();
	      progress_estimate = progressEstimate();
	      cancelUntil(0);
	      return l_Undef; }


            // Simplify the set of problem clauses:
            if (decisionLevel() == 0 && !simplify())
                return l_False;
	    //

            Lit next = lit_Undef;


	    if(cons-curRestart* nbclausesbeforereduce>=0) 
	      {
		curRestart = (conflicts/ nbclausesbeforereduce)+1;
		reduceDB();
		nbclausesbeforereduce += 500;
	      }


            if (next == lit_Undef){
                // New variable decision:
                decisions++;
                next = pickBranchLit(polarity_mode, random_var_freq);

                if (next == lit_Undef)
                    // Model found:
                    return l_True;
            }

            // Increase decision level and enqueue 'next'
            assert(value(next) == l_Undef);
            newDecisionLevel();
            uncheckedEnqueue(next);
        }
    }
}
示例#5
0
/*_________________________________________________________________________________________________
|
|  search : (nof_conflicts : int) (nof_learnts : int) (params : const SearchParams&)  ->  [lbool]
|  
|  Description:
|    Search for a model the specified number of conflicts, keeping the number of learnt clauses
|    below the provided limit. NOTE! Use negative value for 'nof_conflicts' or 'nof_learnts' to
|    indicate infinity.
|  
|  Output:
|    'l_True' if a partial assigment that is consistent with respect to the clauseset is found. If
|    all variables are decision variables, this means that the clause set is satisfiable. 'l_False'
|    if the clause set is unsatisfiable. 'l_Undef' if the bound on number of conflicts is reached.
|________________________________________________________________________________________________@*/
lbool MiniSATP::search(int nof_conflicts, int nof_learnts)
{
    assert(ok);
    int         backtrack_level;
    int         conflictC = 0;
    vec<Lit>    learnt_clause;

    starts++;

    bool first = true;

    for (;;){
        Clause* confl = propagate();
        if (confl != NULL){
            // CONFLICT
            conflicts++; conflictC++;

            if (decisionLevel() == 0) 
	    {
	      // Added Lines
	      fillExplanation(confl);
	      return l_False;
	    }

            first = false;

            learnt_clause.clear();
            analyze(confl, learnt_clause, backtrack_level);
            cancelUntil(backtrack_level);
            assert(value(learnt_clause[0]) == l_Undef);

            if (learnt_clause.size() == 1){
                uncheckedEnqueue(learnt_clause[0]);
            }else{
                Clause* c = Clause_new(learnt_clause, true);
                learnts.push(c);
                attachClause(*c);
		
                claBumpActivity(*c);
                uncheckedEnqueue(learnt_clause[0], c);
            }

            varDecayActivity();
            claDecayActivity();

        }else{
            // NO CONFLICT

            if (nof_conflicts >= 0 && conflictC >= nof_conflicts){
                // Reached bound on number of conflicts:
                progress_estimate = progressEstimate();
                cancelUntil(0);
                return l_Undef; }

            // Simplify the set of problem clauses:
            if (decisionLevel() == 0 && !simplify())
	    {
                return l_False;
	    }

            if (nof_learnts >= 0 && learnts.size()-nAssigns() >= nof_learnts)
                // Reduce the set of learnt clauses:
                reduceDB();

            Lit next = lit_Undef;
            while (decisionLevel() < assumptions.size()){
                // Perform user provided assumption:
                Lit p = assumptions[decisionLevel()];
                if (value(p) == l_True){
                    // Dummy decision level:
                    newDecisionLevel();
                }else if (value(p) == l_False){
                    analyzeFinal(~p, conflict);
                    return l_False;
                }else{
                    next = p;
                    break;
                }
            }

            if (next == lit_Undef){
                // New variable decision:
                decisions++;
                next = pickBranchLit(polarity_mode, random_var_freq);

                if (next == lit_Undef)
		{
		    // Added Line
		    // Clear explanation vector if satisfiable
		    explanation.clear( );

                    // Model found:
                    return l_True;
		}
            }

            // Increase decision level and enqueue 'next'
            assert(value(next) == l_Undef);
            newDecisionLevel();
            uncheckedEnqueue(next);
        }
    }
}
示例#6
0
/*_________________________________________________________________________________________________
|
|  analyze : (confl : Clause*) (out_learnt : vec<Lit>&) (out_btlevel : int&)  ->  [void]
|  
|  Description:
|    Analyze conflict and produce a reason clause.
|  
|    Pre-conditions:
|      * 'out_learnt' is assumed to be cleared.
|      * Current decision level must be greater than root level.
|  
|    Post-conditions:
|      * 'out_learnt[0]' is the asserting literal at level 'out_btlevel'.
|  
|  Effect:
|    Will undo part of the trail, upto but not beyond the assumption of the current decision level.
|________________________________________________________________________________________________@*/
void Solver::analyze(Clause* confl, vec<Lit>& out_learnt, int& out_btlevel,int &nbl,int &mer)
{
    int pathC = 0;
    Lit p     = lit_Undef;

	
    out_learnt.push();      // (leave room for the asserting literal)
    int index   = trail.size() - 1;
    out_btlevel = 0;

    do{
      assert(confl != NULL);          // (otherwise should be UIP)
      Clause& c = *confl;
      
      // 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 (c.learnt())
	claBumpActivity(c);
      
      for (int j = (p == lit_Undef) ? 0 : 1; j < c.size(); j++){
	Lit q = c[j];
	
            if (!seen[var(q)] && level[var(q)] > 0){
	      
                varBumpActivity(var(q));

                seen[var(q)] = 1;
                if (level[var(q)] >= decisionLevel()){
                    pathC++;
#ifdef UPDATEVARACTIVITY
		    if((reason[var(q)]!=NULL)  && (reason[var(q)]->learnt())) 
		      lastDecisionLevel.push(q);
#endif
		}
                else{
                    out_learnt.push(q);
                    if (level[var(q)] > out_btlevel)
                        out_btlevel = level[var(q)];
                }
            }
        }
        // Select next clause to look at:
        while (!seen[var(trail[index--])]);
        p     = trail[index+1];
        confl = reason[var(p)];
        seen[var(p)] = 0;
        pathC--;

    }while (pathC > 0);
    out_learnt[0] = ~p;

	
    // Simplify conflict clause:
    //
    int i, j;
    if (expensive_ccmin){
      uint32_t abstract_level = 0;
      for (i = 1; i < out_learnt.size(); i++)
	abstract_level |= abstractLevel(var(out_learnt[i])); // (maintain an abstraction of levels involved in conflict)
      
      out_learnt.copyTo(analyze_toclear);
      for (i = j = 1; i < out_learnt.size(); i++)
	if (reason[var(out_learnt[i])] == NULL || !litRedundant(out_learnt[i], abstract_level))
	  out_learnt[j++] = out_learnt[i];
    }else{
      out_learnt.copyTo(analyze_toclear);
      for (i = j = 1; i < out_learnt.size(); i++){
	Clause& c = *reason[var(out_learnt[i])];
	if(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;
	}
	
	for (int k = 1; k < c.size(); k++)
	  if (!seen[var(c[k])] && level[var(c[k])] > 0){
	    out_learnt[j++] = out_learnt[i];
	    break; }
      }
    }
    max_literals += out_learnt.size();
    out_learnt.shrink(i - j);
    tot_literals += out_learnt.size();

    



    // Find correct backtrack level:
    //
    if (out_learnt.size() == 1)
        out_btlevel = 0;
    else{
        int max_i = 1;
        for (int i = 2; i < out_learnt.size(); i++)
            if (level[var(out_learnt[i])] > level[var(out_learnt[max_i])])
                max_i = i;
        Lit p             = out_learnt[max_i];
        out_learnt[max_i] = out_learnt[1];
        out_learnt[1]     = p;
        out_btlevel       = level[var(p)];
    }


    nbl = 0;mer = 0;
    MYFLAG++;
    for(int i=0;i<out_learnt.size();i++) {
      
      int l = level[var(out_learnt[i])];
      if (permDiff[l] != MYFLAG) {
		  permDiff[l] = MYFLAG;
		  nbl++;
		  mer +=nbPropagated(l);
      }
    }
    
	
#ifdef UPDATEVARACTIVITY
    if(lastDecisionLevel.size()>0) {
      for(int i = 0;i<lastDecisionLevel.size();i++) {
	if(reason[var(lastDecisionLevel[i])]->activity()<nbl)
	  varBumpActivity(var(lastDecisionLevel[i]));
      }
      lastDecisionLevel.clear();
    } 
#endif	    
    



    for (int j = 0; j < analyze_toclear.size(); j++) seen[var(analyze_toclear[j])] = 0;    // ('seen[]' is now cleared)
}
示例#7
0
/*_________________________________________________________________________________________________
|
|  analyze : (confl : Clause*) (out_learnt : vec<Lit>&) (out_btlevel : int&)  ->  [void]
|  
|  Description:
|    Analyze conflict and produce a reason clause.
|  
|    Pre-conditions:
|      * 'out_learnt' is assumed to be cleared.
|      * Current decision level must be greater than root level.
|  
|    Post-conditions:
|      * 'out_learnt[0]' is the asserting literal at level 'out_btlevel'.
|  
|  Effect:
|    Will undo part of the trail, upto but not beyond the assumption of the current decision level.
|________________________________________________________________________________________________@*/
void Solver::analyze(Clause* _confl, vec<Lit>& out_learnt, int& out_btlevel)
{
    GClause confl = GClause_new(_confl);
    vec<char>&     seen  = analyze_seen;
    int            pathC = 0;
    Lit            p     = lit_Undef;

    // Generate conflict clause:
    //
    out_learnt.push();      // (leave room for the asserting literal)
    out_btlevel = 0;
    int index = trail.size()-1;
    do{
        assert(confl != GClause_NULL);          // (otherwise should be UIP)

        Clause& c = confl.isLit() ? ((*analyze_tmpbin)[1] = confl.lit(), *analyze_tmpbin)
                                  : *confl.clause();
        if (c.learnt())
            claBumpActivity(&c);

        for (int j = (p == lit_Undef) ? 0 : 1; j < c.size(); j++){
            Lit q = c[j];
            if (!seen[var(q)] && level[var(q)] > 0){
                varBumpActivity(q);
                seen[var(q)] = 1;
                if (level[var(q)] == decisionLevel())
                    pathC++;
                else{
                    out_learnt.push(q);
                    out_btlevel = max(out_btlevel, level[var(q)]);
                }
            }
        }

        // Select next clause to look at:
        while (!seen[var(trail[index--])]);
        p     = trail[index+1];
        confl = reason[var(p)];
        seen[var(p)] = 0;
        pathC--;

    }while (pathC > 0);
    out_learnt[0] = ~p;

    int     i, j;
    if (expensive_ccmin){
        // Simplify conflict clause (a lot):
        //
        unsigned int    min_level = 0;
        for (i = 1; i < out_learnt.size(); i++)
            min_level |= 1 << (level[var(out_learnt[i])] & 31);         // (maintain an abstraction of levels involved in conflict)

        out_learnt.copyTo(analyze_toclear);
        for (i = j = 1; i < out_learnt.size(); i++)
            if (reason[var(out_learnt[i])] == GClause_NULL || !analyze_removable(out_learnt[i], min_level))
                out_learnt[j++] = out_learnt[i];
    }else{
        // Simplify conflict clause (a little):
        //
        out_learnt.copyTo(analyze_toclear);
        for (i = j = 1; i < out_learnt.size(); i++){
            GClause r = reason[var(out_learnt[i])];
            if (r == GClause_NULL)
                out_learnt[j++] = out_learnt[i];
            else if (r.isLit()){
                Lit q = r.lit();
                if (!seen[var(q)] && level[var(q)] != 0)
                    out_learnt[j++] = out_learnt[i];
            }else{
                Clause& c = *r.clause();
                for (int k = 1; k < c.size(); k++)
                    if (!seen[var(c[k])] && level[var(c[k])] != 0){
                        out_learnt[j++] = out_learnt[i];
                        break; }
            }
        }
    }

    stats.max_literals += out_learnt.size();
    out_learnt.shrink(i - j);
    stats.tot_literals += out_learnt.size();

    for (int j = 0; j < analyze_toclear.size(); j++) seen[var(analyze_toclear[j])] = 0;    // ('seen[]' is now cleared)
}
示例#8
0
/*_________________________________________________________________________________________________
|
|  search : (nof_conflicts : int) (nof_learnts : int) (params : const SearchParams&)  ->  [lbool]
|  
|  Description:
|    Search for a model the specified number of conflicts, keeping the number of learnt clauses
|    below the provided limit. NOTE! Use negative value for 'nof_conflicts' or 'nof_learnts' to
|    indicate infinity.
|  
|  Output:
|    'l_True' if a partial assigment that is consistent with respect to the clauseset is found. If
|    all variables are decision variables, this means that the clause set is satisfiable. 'l_False'
|    if the clause set is unsatisfiable. 'l_Undef' if the bound on number of conflicts is reached.
|________________________________________________________________________________________________@*/
lbool Solver::search(int nof_conflicts, int nof_learnts)
{
  int         backtrack_level;
  int         conflictC = 0;
  vec<Lit>    learnt_clause;

  starts++;

  // bool first = true;

  for (;;){
    Clause* confl = propagate();


    if (confl != NULL){
      // CONFLICT
      conflicts++; conflictC++;

      if (decisionLevel() == 0) return l_False;
      
      // first = false;

      learnt_clause.clear();
      analyze(confl, learnt_clause, backtrack_level);
      cancelUntil(backtrack_level);

#ifdef __PRINT
      char c1 = sign(learnt_clause[0]) ? '-' : '+';
      char c2 = polarity[var(learnt_clause[0])] == 0 ? '-' : '+'; 
      if (decisionLevel() < minDecisionLevel && 
	  original_activity[var(learnt_clause[0])] > 0) {
	printf("Conflict record: ");
	printLit(learnt_clause[0]);
	printf(" .%d.\t.%d. %c .%c .%g\n", decisionLevel(), trail.size(), 
	       c1, c2, original_activity[var(learnt_clause[0])]);
	if (decisionLevel() == 0) {
	  minDecisionLevel = (unsigned)(-1);
	} else {
	  minDecisionLevel = decisionLevel();
	}
      }
#endif

      if (learnt_clause.size() == 1){
	uncheckedEnqueue(learnt_clause[0]);
      }else{
	Clause* c = Clause::Clause_new(learnt_clause, true);
	learnts.push(c);
	attachClause(*c);
	claBumpActivity(*c);
	uncheckedEnqueue(learnt_clause[0], c);
      }

      #ifdef _MINISAT_DEFAULT_VSS
      varDecayActivity();
      #endif
      claDecayActivity();

    }else{

      // NO CONFLICT

      if (nof_conflicts >= 0 && conflictC >= nof_conflicts){
	// Reached bound on number of conflicts:
	progress_estimate = progressEstimate();
	// cancelUntil(0);
	return l_Undef; }

      // Simplify the set of problem clauses:
      if (decisionLevel() == 0 && !simplify())
	return l_False;

      if (nof_learnts >= 0 && learnts.size()-nAssigns() >= nof_learnts)
	// Reduce the set of learnt clauses:
	reduceDB();

      Lit next = lit_Undef;
      while (decisionLevel() < assumptions.size()){
	// Perform user provided assumption:
	Lit p = assumptions[decisionLevel()];
	if (value(p) == l_True){
	  // Dummy decision level:
	  newDecisionLevel();
	}else if (value(p) == l_False){
	  analyzeFinal(~p, conflict);
	  return l_False;
	}else{
	  next = p;
	  break;
	}
      }




      if (next == lit_Undef){
	// New variable decision:
	decisions++;
	next = pickBranchLit(polarity_mode, random_var_freq);

	if (next == lit_Undef)
	  // Model found:
	  return l_True;

#ifdef __PRINT
	printf("Decision: ");
	printLit(next);
	printf("\t.%f.\t.%d.\t.%d.", activity[var(next)], decisionLevel(), trail.size());
	printf("\n");
#endif
		

      }

      // Increase decision level and enqueue 'next'
      newDecisionLevel();
      uncheckedEnqueue(next);
    }

    //#ifdef __PRINT
    //    printTrail();
    //#endif
  }
}
示例#9
0
/*_________________________________________________________________________________________________
|
|  analyze : (confl : Clause*) (out_learnt : vec<Lit>&) (out_btlevel : int&)  ->  [void]
|  
|  Description:
|    Analyze conflict and produce a reason clause.
|  
|    Pre-conditions:
|      * 'out_learnt' is assumed to be cleared.
|      * Current decision level must be greater than root level.
|  
|    Post-conditions:
|      * 'out_learnt[0]' is the asserting literal at level 'out_btlevel'.
|  
|  Effect:
|    Will undo part of the trail, upto but not beyond the assumption of the current decision level.
|________________________________________________________________________________________________@*/
void Solver::analyze(Clause* confl, vec<Lit>& out_learnt, int& out_btlevel)
{
  int pathC = 0;
  Lit p     = lit_Undef;

  // Generate conflict clause:
  //
  out_learnt.push();      // (leave room for the asserting literal)
  int index   = trail.size() - 1;
  out_btlevel = 0;

  do{
    Clause& c = *confl;

    #ifdef __PRINT
    printf("Explain: ");
    printClause(c);
    printf("\n");
    #endif

      if (c.learnt())
	claBumpActivity(c);

      for (int j = (p == lit_Undef) ? 0 : 1; j < c.size(); j++){
	Lit q = c[j];

	if (!seen[var(q)] && level[var(q)] > 0){
	  #ifdef _MINISAT_DEFAULT_VSS
	  varBumpActivity(var(q));
	  #endif
	  seen[var(q)] = 1;
	  if (level[var(q)] >= decisionLevel()) {
	    pathC++;
	  }else{
	    out_learnt.push(q);
	    if (level[var(q)] > out_btlevel)
	      out_btlevel = level[var(q)];
	  }
	}
      }

      // Select next clause to look at:
      while (!seen[var(trail[index--])]);
      p     = trail[index+1];
      confl = reason[var(p)];
      seen[var(p)] = 0;
      pathC--;
  } while (pathC > 0);
  out_learnt[0] = ~p;

  // Simplify conflict clause:
  //
  int i, j;
  if (expensive_ccmin){
    uint32_t abstract_level = 0;
    for (i = 1; i < out_learnt.size(); i++)
      abstract_level |= abstractLevel(var(out_learnt[i])); // (maintain an abstraction of levels involved in conflict)

    out_learnt.copyTo(analyze_toclear);
    for (i = j = 1; i < out_learnt.size(); i++)
      if (reason[var(out_learnt[i])] == NULL || !litRedundant(out_learnt[i], abstract_level))
	out_learnt[j++] = out_learnt[i];
  }else{
    out_learnt.copyTo(analyze_toclear);
    for (i = j = 1; i < out_learnt.size(); i++){
      Clause& c = *reason[var(out_learnt[i])];
      for (int k = 1; k < c.size(); k++)
	if (!seen[var(c[k])] && level[var(c[k])] > 0){
	  out_learnt[j++] = out_learnt[i];
	  break; }
    }
  }
  max_literals += out_learnt.size();
  out_learnt.shrink(i - j);
  tot_literals += out_learnt.size();

  // Find correct backtrack level:
  //
  if (out_learnt.size() == 1)
    out_btlevel = 0;
  else{
    int max_i = 1;
    for (int i = 2; i < out_learnt.size(); i++)
      if (level[var(out_learnt[i])] > level[var(out_learnt[max_i])])
	max_i = i;
    Lit p             = out_learnt[max_i];
    out_learnt[max_i] = out_learnt[1];
    out_learnt[1]     = p;
    out_btlevel       = level[var(p)];
  }

#ifdef __PRINT
  printf("Learnt: ");
  for (int i = 0; i < out_learnt.size(); i++) {
    printf("%s%d ", sign(out_learnt[i]) ? "-" : "", var(out_learnt[i]));
    if (value(out_learnt[i]) != l_False)
      exit(1);
  }
  printf("\n");
#endif

  for (int j = 0; j < analyze_toclear.size(); j++) seen[var(analyze_toclear[j])] = 0;    // ('seen[]' is now cleared)

  
}
示例#10
0
void Solver::addConflictingClause(vec<Lit>& lits) {
  if (lits.size() == 1) {
    if (value(lits[0]) == l_True)
      return;
    
    if (value(lits[0]) == l_False) {
      if (level[var(lits[0])] == 0) {
	ok = false;
	return;
      }
      cancelUntil(level[var(lits[0])] - 1);
    }
    uncheckedEnqueue(~lits[0]);
  } else {
    vec<Lit>    learnt_clause;
    int backtrack_level;

    for (int i = 1; i < lits.size(); i++) {
      if (value(lits[0]) == l_False) {
	if (value(lits[i]) != l_False){
	  Lit tmp = lits[0];
	  lits[0] = lits[i];
	  lits[i] = tmp;
	}
      } else if (value(lits[1]) == l_False) {
	if (value(lits[i]) != l_False){
	  Lit tmp = lits[1];
	  lits[1] = lits[i];
	  lits[i] = tmp;
	  break;
	}
      }
    }

    if (value(lits[0]) == l_False) {
      for (int i = 1; i < lits.size(); i++) {
	if (level[var(lits[i])] > level[var(lits[0])]) {
	  Lit tmp = lits[0];
	  lits[0] = lits[i];
	  lits[i] = tmp;
	}
      }
    }

    if (value(lits[1]) == l_False) {
      for (int i = 2; i < lits.size(); i++) {
	if (level[var(lits[i])] > level[var(lits[1])]) {
	  Lit tmp = lits[1];
	  lits[1] = lits[i];
	  lits[i] = tmp;
	}
      }
    }

    Clause* confl = Clause::Clause_new(lits, true);
    clauses.push(confl);
    attachClause(*confl);


    
    if (value(lits[0]) != l_False) {
      if (value(lits[1]) == l_False) {
	uncheckedEnqueue(lits[0], confl);
      }
      return;
    }

    int maxLevel = level[var(lits[0])];
    cancelUntil(maxLevel);
    if (maxLevel == 0) {
      ok = false;
      return;
    }

    learnt_clause.clear();
    analyze(confl, learnt_clause, backtrack_level);
    cancelUntil(backtrack_level);
    
    if (learnt_clause.size() == 1){
      uncheckedEnqueue(learnt_clause[0]);
    } else {
      Clause* c = Clause::Clause_new(learnt_clause, true);
      learnts.push(c);
      attachClause(*c);
      claBumpActivity(*c);
      uncheckedEnqueue(learnt_clause[0], c);
    }

#ifdef _MINISAT_DEFAULT_VSS
    varDecayActivity();
#endif
    claDecayActivity();
  }
}