Beispiel #1
0
bool Solver::addClause(vec<Lit>& ps)
{
    assert(decisionLevel() == 0);

    if (!ok)
        return false;
    else{
        // Check if clause is satisfied and remove false/duplicate literals:
        sort(ps);
        Lit p; int i, j;
        for (i = j = 0, p = lit_Undef; i < ps.size(); i++)
            if (value(ps[i]) == l_True || ps[i] == ~p)
                return true;
            else if (value(ps[i]) != l_False && ps[i] != p)
                ps[j++] = p = ps[i];
        ps.shrink(i - j);
    }

    if (ps.size() == 0)
        return ok = false;
    else if (ps.size() == 1){
        assert(value(ps[0]) == l_Undef);
        uncheckedEnqueue(ps[0]);
        return ok = (propagate() == NULL);
    }else{
        Clause* c = Clause_new(ps, false);
        clauses.push(c);
        attachClause(*c);
    }

    return true;
}
Beispiel #2
0
bool SimpSMTSolver::asymm(Var v, Clause& c)
{
  assert(decisionLevel() == 0);

  if (c.mark() || satisfied(c)) return true;

  trail_lim.push(trail.size());
  Lit l = lit_Undef;
  for (int i = 0; i < c.size(); i++)
    if (var(c[i]) != v && value(c[i]) != l_False)
    {
      uncheckedEnqueue(~c[i]);
    }
    else
      l = c[i];

  if (propagate() != NULL){
    cancelUntil(0);
    asymm_lits++;
    if (!strengthenClause(c, l))
      return false;
  }else
    cancelUntil(0);

  return true;
}
Beispiel #3
0
/*_________________________________________________________________________________________________
|
|  propagate : [void]  ->  [Clause*]
|  
|  Description:
|    Propagates all enqueued facts. If a conflict arises, the conflicting clause is returned,
|    otherwise NULL.
|  
|    Post-conditions:
|      * the propagation queue is empty, even if there was a conflict.
|________________________________________________________________________________________________@*/
Clause* Solver::propagate()
{
    Clause* confl     = NULL;
    int     num_props = 0;

    while (qhead < trail.size()){
        Lit            p   = trail[qhead++];     // 'p' is enqueued fact to propagate.

        vec<Clause*>&  ws  = watches[toInt(p)];
        Clause         **i, **j, **end;
        num_props++;

        for (i = j = (Clause**)ws, end = i + ws.size();  i != end;){
            Clause& c = **i++;

            // Make sure the false literal is data[1]:
            Lit false_lit = ~p;
            if (c[0] == false_lit)
                c[0] = c[1], c[1] = false_lit;

            assert(c[1] == false_lit);

            // If 0th watch is true, then clause is already satisfied.
            Lit first = c[0];
            if (value(first) == l_True){
                *j++ = &c;
            }else{
                // Look for new watch:
                for (int k = 2; k < c.size(); k++)
                    if (value(c[k]) != l_False){
                        c[1] = c[k]; c[k] = false_lit;
                        watches[toInt(~c[1])].push(&c);
                        goto FoundWatch; }

                // Did not find watch -- clause is unit under assignment:
                *j++ = &c;
                if (value(first) == l_False){
                    confl = &c;
                    qhead = trail.size();
                    // Copy the remaining watches:
                    while (i < end)
                        *j++ = *i++;
                }else
                    uncheckedEnqueue(first, &c);
            }
        FoundWatch:;
        }
        ws.shrink(i - j);
    }
    propagations += num_props;
    simpDB_props -= num_props;

    return confl;
}
bool SimpSolver::implied(const vec<Lit>& c)
{
    assert(decisionLevel() == 0);

    trail_lim.push(trail.size());
    for (int i = 0; i < c.size(); i++)
        if (value(c[i]) == l_True){
            cancelUntil(0);
            return false;
        }else if (value(c[i]) != l_False){
            assert(value(c[i]) == l_Undef);
            uncheckedEnqueue(~c[i]);
        }

    bool result = propagate() != NULL;
    cancelUntil(0);
    return result;
}
Beispiel #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 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);
        }
    }
}
Beispiel #6
0
/*_________________________________________________________________________________________________
|
|  propagate : [void]  ->  [Clause*]
|
|  Description:
|    Propagates all enqueued facts. If a conflict arises, the conflicting clause is returned,
|    otherwise NULL.
|
|    Post-conditions:
|      * the propagation queue is empty, even if there was a conflict.
|________________________________________________________________________________________________@*/
Clause* Solver::propagate() {
  Clause* confl     = NULL;
  int     num_props = 0;

  while (qhead < trail.size()){
    const Lit      p   = trail[qhead++];     // 'p' is enqueued fact to propagate.
    vec<Watched>&  ws  = watches[toInt(p)];
    Watched         *i, *j, *end;
    num_props++;

    #ifdef RESTORE
    printf("Propagating lit "); printLit(p); printf(" number: %d\n", toInt(p));
    #endif

    const vec<Binaire> & wbin = watchesBin[toInt(p)];

    bogoProps += wbin.size();
    for(int k = 0;k<wbin.size();k++) {
      Lit imp = wbin[k].implied;
      if(value(imp) == l_False) {
        if (handleConflict(*wbin[k].clause, num_props))
            return wbin[k].clause;
      }

      if(value(imp) == l_Undef) {
        uncheckedEnqueue(imp,wbin[k].clause);
      }
    }

    if (backup.running
        && watchBackup.flags[toInt(p)] == false
    ) {
        watchBackup.ws[toInt(p)] = watches[toInt(p)];
        watchBackup.flags[toInt(p)] = true;
        watchBackup.changed.push(toInt(p));
    }

    bogoProps += ws.size();
    for (i = j = (Watched*)ws, end = i + ws.size();  i != end;){
      if(value(i->blocked)==l_True) { // Clause is sat
        *j++ = *i++;
        continue;
      }
      Lit bl = i->blocked;
      Clause& c = *(i->wcl);
      i++;
      bogoProps += 5;

      if (backup.running
          && backup.touchedClauses.find(&c) == backup.touchedClauses.end()
      ) {
          backup.touchedClauses.insert(&c);
          c.saveLiterals();
      }

      // Make sure the false literal is data[1]:
      Lit false_lit = ~p;
      if (c[0] == false_lit)
        c[0] = c[1], c[1] = false_lit;

      assert(c[1] == false_lit);

      // If 0th watch is true, then clause is already satisfied.
      Lit first = c[0];
      if (value(first) == l_True){
        j->wcl = &c;
        j->blocked = first;
        j++;
      }else{
        // Look for new watch:
        for (int k = 2; k < c.size(); k++)
          if (value(c[k]) != l_False){
            c[1] = c[k]; c[k] = false_lit;

            const int wsNum = toInt(~c[1]);
            //Save ws before changing it
            if (backup.running
                && watchBackup.flags[wsNum] == false
            ) {
                watchBackup.ws[wsNum] = watches[wsNum];
                watchBackup.flags[wsNum] = true;
                watchBackup.changed.push(wsNum);
            }

            watches[wsNum].push();
            watches[wsNum].last().wcl = &c;
            watches[wsNum].last().blocked = c[0];
            goto FoundWatch; }

        // Did not find watch -- clause is unit under assignment:
        j->wcl = &c;
        j->blocked = bl;
        j++;

        if (value(first) == l_False){
            if (handleConflict(c, num_props)) {
                confl = &c;
                qhead = trail.size();
                // Copy the remaining watches:
                while (i < end)
                    *j++ = *i++;
            } else {
                goto FoundWatch;
            }
        } else {
            uncheckedEnqueue(first, &c);
            #ifdef DYNAMICNBLEVEL
            if(backup.stage == 0
                && c.learnt()
                && c.activity()>2
            ) {
                MYFLAG++;
                int nblevels =0;
                for(int i=0;i<c.size();i++) {
                    int l = level[var(c[i])];
                    if (permDiff[l] != MYFLAG) {
                        permDiff[l] = MYFLAG;
                        nblevels++;
                    }
                }
                if(nblevels+1<c.activity()) {
                    c.setActivity(nblevels);
                }
           }
            #endif
        }
      }
      FoundWatch:;
    }
    ws.shrink(i - j);
  }
  propagations+=num_props;
  simpDB_props-=num_props;

  return confl;
}
Beispiel #7
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();

        //Conflict at a later stage.
        if (backup.running
            && confl != NULL
            && backup.stage == 1
        ) {
            #ifdef RESTORE_FULL
            printf("Somebody else (maybe bin clause) did the conflict -- stage is one, going 2\n");
            #endif
            fullCancelUntil(backup.level, backup.sublevel);
            backup.stage = 2;
            continue;
        }

        if (confl != NULL){
            assert(backup.stage == 0);

            // 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){
              assert(decisionLevel() == 0);
              uncheckedEnqueue(learnt_clause[0]);
              nbUn++;
            }else{
              Clause* c = Clause_new(learnt_clause, clIndex++, conflicts, true);
              dumpFile << "INSERT INTO clausedata(runID, idx, timeofcreation, size) VALUES("
              << runID << ","
              << c->getIndex() << ","
              << c->getTimeOfCreation() << ","
              << c->size()
              << ");" << std::endl;

              learnts.push(c);
              c->setActivity(nblevels); // LS
              if(nblevels<=2) nbDL2++;
              if(c->size()==2) nbBin++;
              attachClause(*c);

              uncheckedEnqueue(learnt_clause[0], c);

              if (backup.running
                  && backup.stage == 0
              ) {
                  saveState();
                  #ifdef RESTORE
                  printf("Saving state after conflict at dec level: %d, sublevel: %d\n", decisionLevel(), trail.size());
                  #endif
              }
            }
              varDecayActivity();
        }else{
            if (backup.stage == 0
              && 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 (backup.stage == 0
                && decisionLevel() == 0 && !simplify()
            ) {
                return l_False;
            }

            Lit next = lit_Undef;

            if (backup.stage == 0
                && ((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);

            if (backup.running
                && backup.stage == 0
            ) {
                saveState();
                #ifdef RESTORE
                printf("Saving state after pickbranch at dec level: %d, sublevel: %d\n", decisionLevel(), trail.size());
                printf("sublevel: %d, level: %d, qhead:%d\n", trail.size(), decisionLevel(), qhead);
                #endif
            }
        }
    }
}
Beispiel #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 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);
        }
    }
}
Beispiel #9
0
/*_________________________________________________________________________________________________
|
|  propagate : [void]  ->  [Clause*]
|  
|  Description:
|    Propagates all enqueued facts. If a conflict arises, the conflicting clause is returned,
|    otherwise NULL.
|  
|    Post-conditions:
|      * the propagation queue is empty, even if there was a conflict.
|________________________________________________________________________________________________@*/
Clause* MiniSATP::propagate(const bool deduce)
{
    Clause* confl     = NULL;
    int     num_props = 0;

    while (qhead < trail.size()){
        Lit             p   = trail[qhead++];     // 'p' is enqueued fact to propagate.
        vec<Clause*>&  ws  = watches[toInt(p)];
        Clause         **i, **j, **end;
        num_props++;

        for (i = j = (Clause**)ws, end = i + ws.size();  i != end;){
            Clause& c = **i++;

            // Make sure the false literal is data[1]:
            Lit false_lit = ~p;
            if (c[0] == false_lit)
                c[0] = c[1], c[1] = false_lit;

            assert(c[1] == false_lit);

            // If 0th watch is true, then clause is already satisfied.
            Lit first = c[0];
            if (value(first) == l_True){
                *j++ = &c;
            }else{
                // Look for new watch:
                for (int k = 2; k < c.size(); k++)
                    if (value(c[k]) != l_False){
                        c[1] = c[k]; c[k] = false_lit;
                        watches[toInt(~c[1])].push(&c);
                        goto FoundWatch; }

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

//=================================================================================================
// Added Code

		  assert( (int)var_to_enode.size( ) > var( first ) );
		  if ( deduce && var_to_enode[ var( first ) ] != NULL )
		  {
		    Enode * e = var_to_enode[ var( first ) ];
		    if ( !e->hasPolarity( ) && !e->isDeduced( ) )
		    {
		      e->setDeduced( sign( first ), solver_id );
		      deductions.push_back( e );
		    }
		  }

// Added Code
//=================================================================================================

		}
            }
        FoundWatch:;
        }
        ws.shrink(i - j);
    }
    propagations += num_props;
    simpDB_props -= num_props;

    return confl;
}
Beispiel #10
0
// Modified line
// bool MiniSATP::addClause(vec<Lit>& ps, Enode * e)
bool MiniSATP::addClause(vec<Lit>& psin, Enode * e)
{
    assert( decisionLevel() == 0 );
    assert( ok );

    // Added Lines
    vec< Lit > ps;
    psin.copyTo( ps );

    if (!ok)
      return false;

    // Check if clause is satisfied and remove false/duplicate literals:
    sort(ps);
    Lit p; int i, j;
    for (i = j = 0, p = lit_Undef; i < ps.size(); i++)
    {
      if (value(ps[i]) == l_True || ps[i] == ~p)
	return true;
      else if (value(ps[i]) != l_False && ps[i] != p)
	ps[j++] = p = ps[i];
    }
    ps.shrink(i - j);

//=================================================================================================
// Modified Code

    assert( psin.size( ) == 1 || ps.size() > 0 );

    //
    // This case happens only when deductions are enabled
    //
    if (ps.size() == 0)
    {
      Clause * confl = Clause_new( psin );
      if ( confl == NULL ) return ok = true;
      initExpDup( );
      explanation.push_back( e );
      storeExpDup( e );
      fillExplanation( confl );
      doneExpDup( );
      assert( !explanation.empty( ) );
      return ok = false;
    }

    if (ps.size() == 1)
    {
      assert(value(ps[0]) == l_Undef);
      uncheckedEnqueue(ps[0]);
      /*
      const Var v = var(ps[0]);
      if ( var_to_enode.size( ) <= v )
	var_to_enode.resize( v + 1, NULL );
      var_to_enode[ v ] = e;
      */
      /*
      if ( e != NULL && seen_in_conflict.insert( e->getId( ) ).second )
	explanation.push_back( e );
      */
      // undo_stack_oper.push_back( NEWUNIT );
      // undo_stack_elem.push_back( (void *)v );

#define LAZY_PROPAGATION 0
#if LAZY_PROPAGATION
#else
      // Modified Line
      // return ok = (propagate() == NULL);
#if LIMIT_DEDUCTIONS
      deductions_done_in_call = 0;
#endif
      Clause * confl = propagate( theory_prop );
      if ( confl == NULL ) return ok = true;
      initExpDup( );
      fillExplanation( confl );
      doneExpDup( );
      assert( !explanation.empty( ) );
      return ok = false;
#endif

// Modified Code
//=================================================================================================

    }
    else
    {
      Clause* c = Clause_new(ps, false);
      clauses.push(c);
      attachClause(*c);

      // Added Lines
      undo_stack_oper.push_back( NEWCLAUSE );
      undo_stack_elem.push_back( (void *)c );
    }

    return true;
}
Beispiel #11
0
// NOTE: enqueue does not set the ok flag! (only public methods do)
inline bool Solver::enqueue(Lit p, CRef from) {
	return value(p) != l_Undef ? value(p) != l_False : (uncheckedEnqueue(p, from), true);
}
Beispiel #12
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);
        }
    }
}
Beispiel #13
0
/*_________________________________________________________________________________________________
|
|  propagate : [void]  ->  [Clause*]
|  
|  Description:
|    Propagates all enqueued facts. If a conflict arises, the conflicting clause is returned,
|    otherwise NULL.
|  
|    Post-conditions:
|      * the propagation queue is empty, even if there was a conflict.
|________________________________________________________________________________________________@*/
Clause* Solver::propagate()
{
  Clause* confl     = NULL;
  int     num_props = 0;
  
  while (qhead < trail.size()){
    Lit            p   = trail[qhead++];     // 'p' is enqueued fact to propagate.
    vec<Watched>&  ws  = watches[toInt(p)];
    Watched         *i, *j, *end;
    num_props++;
    
    vec<Binaire> & wbin = watchesBin[toInt(p)];
    
    for(int k = 0;k<wbin.size();k++) {
      Lit imp = wbin[k].implied;
      if(value(imp) == l_False) {
	return wbin[k].clause;
      }
      
      if(value(imp) == l_Undef) {
	uncheckedEnqueue(imp,wbin[k].clause);
      }
    }
      

    for (i = j = (Watched*)ws, end = i + ws.size();  i != end;){
      if(value(i->blocked)==l_True) { // Clause is sat
	*j++ = *i++;
	continue;
      }
      Lit bl = i->blocked;
      Clause& c = *(i->wcl);
      i++;
      
      
      // Make sure the false literal is data[1]:
      Lit false_lit = ~p;
      if (c[0] == false_lit)
	c[0] = c[1], c[1] = false_lit;
      
      assert(c[1] == false_lit);
      
      // If 0th watch is true, then clause is already satisfied.
      Lit first = c[0];
      if (value(first) == l_True){
	j->wcl = &c;
	j->blocked = first;
	j++;
      }else{
	// Look for new watch:
	for (int k = 2; k < c.size(); k++)
	  if (value(c[k]) != l_False){
	    c[1] = c[k]; c[k] = false_lit;
	    watches[toInt(~c[1])].push();
	    watches[toInt(~c[1])].last().wcl = &c;
	    watches[toInt(~c[1])].last().blocked = c[0];
	    goto FoundWatch; }
	
	// Did not find watch -- clause is unit under assignment:
	j->wcl = &c;
	j->blocked = bl;
	j++;
	
	if (value(first) == l_False){
	  confl = &c;
	  qhead = trail.size();
	  // Copy the remaining watches:
	  while (i < end) 
	    *j++ = *i++;
	}else {
	  uncheckedEnqueue(first, &c);
	  
#ifdef DYNAMICNBLEVEL		    
	  if(c.learnt()  && c.activity()>2) { // GA
	    MYFLAG++;
	    int nblevels =0;
		      for(int i=0;i<c.size();i++) {
			int l = level[var(c[i])];
			if (permDiff[l] != MYFLAG) {
			  permDiff[l] = MYFLAG;
			  nblevels++;
			}
			
			
		      }
		      if(nblevels+1<c.activity()) {
			c.setActivity(nblevels);
		      } else {
		      }
		    }
#endif
	      }
            }
        FoundWatch:;
        }
        ws.shrink(i - j);
    }
    propagations += num_props;
    simpDB_props -= num_props;

    return confl;
}
Beispiel #14
0
bool Solver::addClause(vec<Lit>& ps)
{
#ifdef __PRINT
  for (int i = 0; i < ps.size(); i++) {
    if (_literal_count.find(ps[i]) == _literal_count.end())
      _literal_count[ps[i]] = 1;
    else
      _literal_count[ps[i]]++;
  }
#endif

  if (!ok)
    return false;

  // Check if clause is satisfied and remove false/duplicate literals:
  // Special attention is put on single and double literal clauses
  if (ps.size() == 1 || 
      (ps.size() == 2 && ps[0] == ps[1])) {
    // Unary or Binary with a duplicate literal
    if (value(ps[0]) == l_True) {
#ifdef __PRINT
      printf("---satisfied---\n");
#endif
      return true;
    } else if (value(ps[0]) == l_False) {
#ifdef __PRINT
      printf("Clause empty after simplification\n");
#endif
      return ok = false;
    } else {
      uncheckedEnqueue(ps[0]);
      return ok = (propagate() == NULL);
    }
  } else if (ps.size() == 2) {
    // Real Binary clauses
    if (value(ps[0]) == l_True ||
	value(ps[1]) == l_True ||
	ps[0] == ~ps[1]) {
#ifdef __PRINT
      printf("---satisfied---\n");
#endif
      return true;
    } else if (value(ps[0]) == l_False) {
      if (value(ps[1]) == l_False) {
#ifdef __PRINT
	printf("Clause empty after simplification\n");
#endif
	return ok = false;
      } else {
	uncheckedEnqueue(ps[1]);
	return ok = (propagate() == NULL);
      }
    } else {
      if (value(ps[1]) == l_False) {
	uncheckedEnqueue(ps[0]);
	return ok = (propagate() == NULL);
      } else {
	Clause* c = Clause::Clause_new(ps, false);
	clauses.push(c);
	attachClause(*c);
      }
    }
  } else {
    sort(ps);
    Lit p; int i, j;
    for (i = j = 0, p = lit_Undef; i < ps.size(); i++)
      if (value(ps[i]) == l_True || ps[i] == ~p) {
#ifdef __PRINT
	printf("---satisfied---\n");
#endif
	return true;
      }
      else if (value(ps[i]) != l_False && ps[i] != p)
	ps[j++] = p = ps[i];
    ps.shrink(i - j);

    if (ps.size() == 0) {
#ifdef __PRINT
      printf("Clause empty after simplification\n");
#endif
      return ok = false;
    }
    else if (ps.size() == 1){
      uncheckedEnqueue(ps[0]);
      return ok = (propagate() == NULL);
    }else{
      Clause* c = Clause::Clause_new(ps, false);

      clauses.push(c);
      attachClause(*c);

#ifdef __PRINT
      //      printf("Simplified: ");
      //      printClause(*c);
      //      printf("\n");
#endif      
    }
  }
  return true;
}
Beispiel #15
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
  }
}
Beispiel #16
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();
  }
}