Пример #1
0
void Slave::splitJob() {
        vec<int> message;
        int num_splits;
        //fprintf(stderr, "%d: Split job called, assumptions.size()=%d, DL=%d!\n", thread_no, engine.assumptions.size(), engine.decisionLevel());
        profile_start();

        MPI_Recv(&num_splits, 1, MPI_INT, 0, STEAL_TAG, MPI_COMM_WORLD, &s);

        int max_splits = engine.decisionLevel() - engine.assumptions.size() - 1;
        if (num_splits > max_splits) num_splits = max_splits;
        if (num_splits < 0) num_splits = 0;
        
        if (FULL_DEBUG) fprintf(stderr, "%d: Splitting %d jobs\n", thread_no, num_splits);

        for (int i = 0; i < num_splits; i++) {
                engine.assumptions.push(toInt(sat.decLit(engine.assumptions.size()+1)));
                sat.incVarUse(engine.assumptions.last()/2);
        }
        assert(num_splits == 0 || engine.decisionLevel() > engine.assumptions.size());

        vec<Lit> ps;
        for (int i = 0; i < engine.assumptions.size(); i++) ps.push(toLit(engine.assumptions[i]));
        Clause *c = Clause_new(ps);
        
        sat.convertToSClause(*c);
        free(c);
        message.push(num_splits);
        sat.temp_sc->pushInVec(message);

        MPI_Bsend((int*) message, message.size(), MPI_INT, 0, SPLIT_TAG, MPI_COMM_WORLD);

        profile_end("send split job", message.size());

        if (FULL_DEBUG) fprintf(stderr, "%d: Sent %d split job to master\n", thread_no, message[0]);
}
Пример #2
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;
}
Пример #3
0
bool Master::createNewJob(int thread_no, bool random){
  if(NULL == engine.opt_var)
    return false;
  int lb = engine.opt_var->getMin() + (engine.opt_type ? 1 : 0);
  int ub = engine.opt_var->getMax() - (engine.opt_type ? 1 : 0);
  // val must be in (lb, ub). 
  int val; 
  if(lb == ub)
    val = lb;
  else 
    val = random? (lb + (rand() % (ub - lb))) 
        : (lb + (ub - lb) * ((double) (thread_no+1) / (num_threads+1)));
  
  if(PAR_DEBUG) fprintf(stderr, "Creating new job for %d, bound=%d from (%d, %d)\n", thread_no, val, lb, ub);
  if(lb + 1 >= ub)
    return false;
  Lit l = engine.opt_type ?  engine.opt_var->operator>=(val)
          : engine.opt_var->operator<=(val);
  vec<Lit> ls;
  ls.push(l);
  assert(sat.value(l) == l_Undef);
  Clause * c = Clause_new(ls, false);
  sat.convertToSClause(*c);
  job_queue.push(sat.temp_sc->copy());
  return true;
}
Пример #4
0
void Slave::exportBounds(){
   int lb = engine.opt_var->getMin();
   int ub = engine.opt_var->getMax();
   Lit p =  engine.opt_var->getLit(lb, 2);
   Lit p2 = engine.opt_var->getLit(ub, 3);
                vec<Lit> ps;
                ps.push(p);
                Clause *c = Clause_new(ps, true);
                shareClause(*c);
                ps.clear();
                ps.push(p2);
                Clause *c2 = Clause_new(ps, true);
                shareClause(*c2);
                unitFound=true;
                free(c);
                free(c2);
}
Пример #5
0
bool SimpSMTSolver::eliminateVar(Var v, bool fail)
{
  if (!fail && asymm_mode && !asymmVar(v))    return false;

  const vec<Clause*>& cls = getOccurs(v);

  //  if (value(v) != l_Undef || cls.size() == 0) return true;
  if (value(v) != l_Undef) return true;

  // Split the occurrences into positive and negative:
  vec<Clause*>  pos, neg;
  for (int i = 0; i < cls.size(); i++)
    (find(*cls[i], Lit(v)) ? pos : neg).push(cls[i]);

  // Check if number of clauses decreases:
  int cnt = 0;
  for (int i = 0; i < pos.size(); i++)
    for (int j = 0; j < neg.size(); j++)
      if (merge(*pos[i], *neg[j], v) && ++cnt > cls.size() + grow)
	return true;
#ifdef PEDANTIC_DEBUG
  cerr << "XXY gonna-remove" << endl;
#endif
  // Delete and store old clauses:
  setDecisionVar(v, false);
  elimtable[v].order = elimorder++;
  assert(elimtable[v].eliminated.size() == 0);
  for (int i = 0; i < cls.size(); i++)
  {
    elimtable[v].eliminated.push(Clause_new(*cls[i]));
    removeClause(*cls[i]);
  }

  // Produce clauses in cross product:
  int top = clauses.size();
  vec<Lit> resolvent;
  for (int i = 0; i < pos.size(); i++)
    for (int j = 0; j < neg.size(); j++)
      if (merge(*pos[i], *neg[j], v, resolvent) && !addClause(resolvent))
	return false;

  // DEBUG: For checking that a clause set is saturated with respect to variable elimination.
  //        If the clause set is expected to be saturated at this point, this constitutes an
  //        error.
  if (fail){
    reportf("eliminated var %d, %d <= %d\n", v+1, cnt, cls.size());
    reportf("previous clauses:\n");
    for (int i = 0; i < cls.size(); i++){
      printClause(*cls[i]); reportf("\n"); }
    reportf("new clauses:\n");
    for (int i = top; i < clauses.size(); i++){
      printClause(*clauses[i]); reportf("\n"); }
    assert(0); }

    return backwardSubsumptionCheck();
}
Пример #6
0
void SAT::addClause(vec<Lit>& ps, bool one_watch) {
	int i, j;
	for (i = j = 0; i < ps.size(); i++) {
		if (value(ps[i]) == l_True) return;
		if (value(ps[i]) == l_Undef) ps[j++] = ps[i];
	}
	ps.resize(j);
	if (ps.size() == 0) {
		assert(false);
		TL_FAIL();
	}
	addClause(*Clause_new(ps), one_watch);
}
Пример #7
0
void MIP::unboundedFailure() {
//	NOT_SUPPORTED;
//	if (MIP_DEBUG) 
//		simplex.unboundedDebug();

	assert(simplex.row[0] == 0);

	vec<Lit> ps;
	for (int i = 1; i < vars.size(); i++) {
		ps.push(simplex.shift[i] == 0 ? vars[i]->getMinLit() : vars[i]->getMaxLit());
	}
	Clause *m_r = Clause_new(ps);
	m_r->temp_expl = 1;
	sat.rtrail.last().push(m_r);
	sat.confl = m_r;
}
Пример #8
0
SimpSolver::SimpSolver() :
  Solver()
  , grow               (0)
  , asymm_mode         (false)
  , redundancy_check   (false)
  , merges             (0)
  , asymm_lits         (0)
  , remembered_clauses (0)
  , elimorder          (1)
  , use_simplification (true)
  , elim_heap          (ElimLt(n_occ))
  , bwdsub_assigns     (0)
{
    vec<Lit> dummy(1,lit_Undef);
    bwdsub_tmpunit   = Clause_new(dummy);
    remove_satisfied = false;
}
Пример #9
0
bool MIP::propagateBound(int i, long double s) {
	if (s > 4e9) return true;
	IntView<T> v(vars[i]);
	int64_t max = v.getMin() + (int64_t) floor(s);
//	fprintf(stderr, "%.3Lf %lld %lld %lld\n", s, v.getMin(), v.getMax(), max);
	if (v.setMaxNotR(max)) {
		Clause *m_r = NULL;
		if (so.lazy) {
			m_r = Clause_new(ps);
			(*m_r)[place[i]] = (*m_r)[0];
			m_r->temp_expl = 1;
			sat.rtrail.last().push(m_r);
		}
		if (!v.setMax(max, m_r)) return false;
	}
	return true;
}
Пример #10
0
// Record a clause and drive backtracking. 'clause[0]' must contain the asserting literal.
//
void Solver::record(const vec<Lit>& clause, Deriv* deriv)
{
    assert(clause.size() != 0);
    Clause* c;
    check(Clause_new(*this, clause, true, c, 0, doDeriv, deriv));
    check(ok);
    if (c != NULL) {
		learnts.push(c);
		check(enqueue(clause[0], c));
	}
	else {
		assert(clause.size() == 1);
		if (doDeriv) {
			assert(var_deriv[var(clause[0])] == deriv);
			//var_deriv[var(clause[0])]->addDeriv(deriv);
		}
	}
}
Пример #11
0
inline bool Engine::constrain() {
	best_sol = opt_var->getVal();
	opt_time = wallClockTime() - start_time - init_time;

	sat.btToLevel(0);

	if (so.parallel) {
		Lit p = opt_type ? opt_var->getLit(best_sol+1, 2) : opt_var->getLit(best_sol-1, 3);
		vec<Lit> ps;
		ps.push(p);
		Clause *c = Clause_new(ps, true);
		slave.shareClause(*c);
		free(c);
	}

//	printf("opt_var = %d, opt_type = %d, best_sol = %d\n", opt_var->var_id, opt_type, best_sol);
//	printf("%% opt_var min = %d, opt_var max = %d\n", opt_var->getMin(), opt_var->getMax());

	if (so.mip) mip->setObjective(best_sol);

	return (opt_type ? opt_var->setMin(best_sol+1) : opt_var->setMax(best_sol-1));
}
Пример #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);
        }
    }
}
Пример #13
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);
        }
    }
}
Пример #14
0
bool SimpSMTSolver::addClause( vec<Lit> & ps
#ifdef PRODUCE_PROOF
                             , const ipartitions_t & in 
#endif
			     )
{
  //=================================================================================================
  // Added code

  if ( !use_simplification )
#ifdef PRODUCE_PROOF
    return CoreSMTSolver::addClause( ps, in );
#else
    return CoreSMTSolver::addClause( ps );
#endif

  // Added code
  //=================================================================================================

  for (int i = 0; i < ps.size(); i++)
    if (isEliminated(var(ps[i])))
      remember(var(ps[i]));

  int nclauses = clauses.size();

  if (redundancy_check && implied(ps))
    return true;

  //=================================================================================================
  // Added code

  //
  // Hack to consider clauses of size 1 that
  // wouldn't otherwise be considered by
  // MiniSAT
  //
  if ( config.sat_preprocess_theory != 0
      && ps.size( ) == 1   // Consider unit clauses
      && var(ps[0]) >= 2 ) // Don't consider true/false
  {
    Var v = var( ps[0] );
    Enode * e = theory_handler->varToEnode( v );
    if ( e->isTAtom( ) )
    {
      Clause * uc = Clause_new(ps, false);
      unary_to_remove.push_back( uc );
      Clause &c = *(unary_to_remove.back( ));
      Enode * x, * y;
      getDLVars( e, sign(ps[0]), &x, &y );
      assert( x->isVar( ) );
      assert( y->isVar( ) );
      t_pos[ x->getId( ) ].push_back( &c );
      t_neg[ y->getId( ) ].push_back( &c );
      t_var[ x ].insert( y->getId( ) );
      t_var[ y ].insert( x->getId( ) );
    }
  }

  // Added code
  //=================================================================================================

  if (!CoreSMTSolver::addClause(ps))
    return false;

  if (use_simplification && clauses.size() == nclauses + 1)
  {
    Clause& c = *clauses.last();

    subsumption_queue.insert(&c);

    for (int i = 0; i < c.size(); i++)
    {
      assert(occurs.size() > var(c[i]));
      assert(!find(occurs[var(c[i])], &c));

      occurs[var(c[i])].push(&c);
      n_occ[toInt(c[i])]++;
      touched[var(c[i])] = 1;
      assert(elimtable[var(c[i])].order == 0);
      if (elim_heap.inHeap(var(c[i])))
	elim_heap.increase_(var(c[i]));

    }
  }

  return true;
}
Пример #15
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
            }
        }
    }
}
Пример #16
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));
    }
}
Пример #17
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;
}
Пример #18
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);
        }
    }
}