예제 #1
0
파일: sat.c 프로젝트: geoffchu/chuffed
void SAT::reduceDB() {
  int i, j;

	std::sort((Clause**) learnts, (Clause**) learnts + learnts.size(), activity_lt());
  double minAct = learnts[0]->activity();
  for(i = 0 ; i < receiveds.size() ; i++){
    if(receiveds[i]->received && receiveds[i]->age != 0){
      receiveds[i]->age--;
    }
  }
  for (i = j = 0; i < learnts.size()/2; i++) {
		if (!locked(*learnts[i])) removeClause(*learnts[i]);
		else learnts[j++] = learnts[i];
  }
  for (; i < learnts.size(); i++) {
		learnts[j++] = learnts[i];
  }
  learnts.resize(j);
  int nbLearntsRemoved = i-j;
  for(i = j = 0 ; i < receiveds.size() ; i++){
    if(receiveds[i]->activity() <= minAct && !locked(*receiveds[i]) && receiveds[j]->age == 0){
      removeClause(*receiveds[i]);
    }
    else
      receiveds[j++]=receiveds[i];
  }
  receiveds.resize(j);
  
    if (so.verbosity >= 1) {
      fprintf(stderr, "Pruned %d learnt and %d received clauses\n", nbLearntsRemoved, i-j);
      
      fprintf(stderr, "Slave %d, received.size()=%d\n", so.thread_no, receiveds.size());
      }
}
예제 #2
0
파일: sat.c 프로젝트: geoffchu/chuffed
void SAT::simplifyDB() {
	int i, j;
	for (i = j = 0; i < learnts.size(); i++) {
		if (simplify(*learnts[i])) removeClause(*learnts[i]);
		else learnts[j++] = learnts[i];
	}
  learnts.resize(j);
  
        for (i = j = 0; i < receiveds.size(); i++) {
                if (simplify(*receiveds[i])) removeClause(*receiveds[i]);
                else receiveds[j++] = receiveds[i];
        }
  receiveds.resize(j);
	next_simp_db = propagations + clauses_literals + learnts_literals;
}
예제 #3
0
// Backward subsumption + backward subsumption resolution
bool SimpSolver::backwardSubsumptionCheck(bool verbose)
{
    int cnt = 0;
    int subsumed = 0;
    int deleted_literals = 0;
    assert(decisionLevel() == 0);

    while (subsumption_queue.size() > 0 || bwdsub_assigns < trail.size()){

        // Check top-level assignments by creating a dummy clause and placing it in the queue:
        if (subsumption_queue.size() == 0 && bwdsub_assigns < trail.size()){
            Lit l = trail[bwdsub_assigns++];
            (*bwdsub_tmpunit)[0] = l;
            bwdsub_tmpunit->calcAbstraction();
            assert(bwdsub_tmpunit->mark() == 0);
            subsumption_queue.insert(bwdsub_tmpunit); }

        Clause&  c = *subsumption_queue.peek(); subsumption_queue.pop();

        if (c.mark()) continue;

        if (verbose && verbosity >= 2 && cnt++ % 1000 == 0)
            reportf("subsumption left: %10d (%10d subsumed, %10d deleted literals)\r", subsumption_queue.size(), subsumed, deleted_literals);

        assert(c.size() > 1 || value(c[0]) == l_True);    // Unit-clauses should have been propagated before this point.

        // Find best variable to scan:
        Var best = var(c[0]);
        for (int i = 1; i < c.size(); i++)
            if (occurs[var(c[i])].size() < occurs[best].size())
                best = var(c[i]);

        // Search all candidates:
        vec<Clause*>& _cs = getOccurs(best);
        Clause**       cs = (Clause**)_cs;

        for (int j = 0; j < _cs.size(); j++)
            if (c.mark())
                break;
            else if (!cs[j]->mark() && cs[j] != &c){
                Lit l = c.subsumes(*cs[j]);

                if (l == lit_Undef)
                    subsumed++, removeClause(*cs[j]);
                else if (l != lit_Error){
                    deleted_literals++;

                    if (!strengthenClause(*cs[j], ~l))
                        return false;

                    // Did current candidate get deleted from cs? Then check candidate at index j again:
                    if (var(l) == best)
                        j--;
                }
            }
    }

    return true;
}
예제 #4
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();
}
예제 #5
0
파일: Solver.C 프로젝트: lokdlok/Numberjack
void Solver::removeSatisfied(vec<Clause*>& cs)
{
    int i,j;
    for (i = j = 0; i < cs.size(); i++){
        if (satisfied(*cs[i]))
            removeClause(*cs[i]);
        else
            cs[j++] = cs[i];
    }
    cs.shrink(i - j);
}
예제 #6
0
파일: Solver.C 프로젝트: lokdlok/Numberjack
void Solver::reduceDB()
{
    int     i, j;
    double  extra_lim = cla_inc / learnts.size();    // Remove any clause below this activity

    sort(learnts, reduceDB_lt());
    for (i = j = 0; i < learnts.size() / 2; i++){
        if (learnts[i]->size() > 2 && !locked(*learnts[i]))
            removeClause(*learnts[i]);
        else
            learnts[j++] = learnts[i];
    }
    for (; i < learnts.size(); i++){
        if (learnts[i]->size() > 2 && !locked(*learnts[i]) && learnts[i]->activity() < extra_lim)
            removeClause(*learnts[i]);
        else
            learnts[j++] = learnts[i];
    }
    learnts.shrink(i - j);
}
예제 #7
0
파일: sat.c 프로젝트: cmears/chuffed
void SAT::reduceDB() {
  int i, j;

	std::sort((Clause**) learnts, (Clause**) learnts + learnts.size(), activity_lt());

  for (i = j = 0; i < learnts.size()/2; i++) {
		if (!locked(*learnts[i])) removeClause(*learnts[i]);
		else learnts[j++] = learnts[i];
  }
  for (; i < learnts.size(); i++) {
		learnts[j++] = learnts[i];
  }
  learnts.resize(j);

	if (so.verbosity >= 1) printf("Pruned %d learnt clauses\n", i-j);
}
예제 #8
0
bool SimpSolver::strengthenClause(Clause& c, Lit l)
{
    assert(decisionLevel() == 0);
    assert(c.mark() == 0);
    assert(!c.learnt());
    assert(find(watches[toInt(~c[0])], &c));
    assert(find(watches[toInt(~c[1])], &c));

    // FIX: this is too inefficient but would be nice to have (properly implemented)
    // if (!find(subsumption_queue, &c))
    subsumption_queue.insert(&c);

    // If l is watched, delete it from watcher list and watch a new literal
    if (c[0] == l || c[1] == l){
        Lit other = c[0] == l ? c[1] : c[0];
        if (c.size() == 2){
            removeClause(c);
            c.strengthen(l);
        }else{
            c.strengthen(l);
            remove(watches[toInt(~l)], &c);

            // Add a watch for the correct literal
            watches[toInt(~(c[1] == other ? c[0] : c[1]))].push(&c);

            // !! this version assumes that remove does not change the order !!
            //watches[toInt(~c[1])].push(&c);
            clauses_literals -= 1;
        }
    }
    else{
        c.strengthen(l);
        clauses_literals -= 1;
    }

    // if subsumption-indexing is active perform the necessary updates
    if (use_simplification){
        remove(occurs[var(l)], &c);
        n_occ[toInt(l)]--;
        updateElimHeap(var(l));
    }

    return c.size() == 1 ? enqueue(c[0]) && propagate() == NULL : true;
}
예제 #9
0
void Solver::reduceDB()
{
  int     i, j;
  
	
    nbReduceDB++;
    sort(learnts, reduceDB_lt());
    
    for (i = j = 0; i < learnts.size() / RATIOREMOVECLAUSES; i++){
	if (learnts[i]->size() > 2 && !locked(*learnts[i]) && learnts[i]->activity()>2){
	  removeClause(*learnts[i]);
	}
        else
	  learnts[j++] = learnts[i];
      }
      for (; i < learnts.size(); i++){
	learnts[j++] = learnts[i];
    }
      learnts.shrink(i - j);
      nof_learnts   *= learntsize_inc;
}
/* ----------- formula preprocessing --------------- */
void formule::preprocessing() {
	//la détection des clauses unitaires se fait via la function assignUniqueLitt() de deduce.cpp
	//élimination des doublons (vivants) et des clauses tautologiques (non satisfaites)
	vector<pair<int,int> > variables (v_var.size(), std::make_pair(0,0));
	//vector contenant pour chaque variable une paire (nb_fois_vue_niée,nb_fois_vue_non_niée)
	bool isTauto;
	bool li_need_back;
	litt* li_prev;
	clause* cl_prev = nullptr;
	bool cl_need_back = false;
	for (clause* cl=this->f_ClauseUnsatisfied;cl != nullptr || cl_need_back;cl=cl->next_clause) {
        if (cl_need_back){
			cl=cl_prev;
			cl_prev=nullptr;
			cl_need_back = false;
		}
		li_need_back = false;
		li_prev = nullptr;
		for (litt* li = cl->f_ElementAlive;li != nullptr || li_need_back;li = li->next_litt) {
			if (li_need_back){
				li=li_prev;
				li_prev=nullptr;
				li_need_back = false;
			}
			if (li->neg){
				if (variables[li->variable->id].first > 0){//si on a un doublon dans la clause, on l'élimine
					removeLitt(&cl->f_ElementAlive,&cl->l_ElementAlive,li,li_prev);
					delete li;
					if (li_prev != nullptr)
						li = li_prev;//On évite de casser la chaîne de parcours de la boucle for...
					else if (cl->f_ElementAlive != nullptr){
						li = cl->f_ElementAlive;
						li_need_back = true;
					} else//there is nothing left
						break;
				} else { 
					variables[li->variable->id].first++;
				}
			} else {
				if (variables[li->variable->id].second > 0){//si on a un doublon dans la clause, on l'élimine
					removeLitt(&cl->f_ElementAlive,&cl->l_ElementAlive,li,li_prev);
					delete li;
					if (li_prev != nullptr)
						li = li_prev;//On évite de casser la chaîne de parcours de la boucle for...
					else if (cl->f_ElementAlive != nullptr){
						li = cl->f_ElementAlive;
						li_need_back = true;
					} else//there is nothing left
						break;
				} else { 
					variables[li->variable->id].second++;
				}
			}
			li_prev = li;
		}
		isTauto = false;
		for (auto& v:variables){
			if (v.first != 0 and v.second != 0){//la clause est tautologique
				isTauto = true;
			}
			v.first = 0;
			v.second = 0;
		}
		if (isTauto) {
			removeClause(&this->f_ClauseUnsatisfied,&this->l_ClauseUnsatisfied,cl,cl_prev);
			for (litt* li = cl->f_ElementAlive;li != nullptr;li = li->next_litt){//supprimer la clause cl des clauseInto
				li->variable->clauseInto.erase(std::remove(li->variable->clauseInto.begin(), li->variable->clauseInto.end(), cl), li->variable->clauseInto.end());
			}
			cl->free_clause();
			if (cl_prev != nullptr)
				cl = cl_prev;//On évite de casser la chaîne de parcours de la boucle for...
			else if (this->f_ClauseUnsatisfied != nullptr){
				cl = this->f_ClauseUnsatisfied;
				cl_need_back = true;
			} else//there is nothing left
				break;
		}
		cl_prev = cl;
	}
	//supprimer les doublons de clauseInto
	for (auto& v:v_var){
		if (v != nullptr){
			sort(v->clauseInto.begin(), v->clauseInto.end());
			v->clauseInto.erase(std::unique(v->clauseInto.begin(), v->clauseInto.end()), v->clauseInto.end());
		}
	}
}
예제 #11
0
void
MiniSATP::popBacktrackPoint ( ) 
{ 
  //
  // Force restart, but retain assumptions
  //
  cancelUntil(0);
  //
  // Shrink back trail
  //
  int new_trail_size = undo_trail_size.back( );
  undo_trail_size.pop_back( );
  for ( int i = trail.size( ) - 1 ; i >= new_trail_size ; i -- )
  {
    Var     x  = var(trail[i]);
    assigns[x] = toInt(l_Undef);
    reason [x] = NULL;
    insertVarOrder(x);
  }  
  trail.shrink(trail.size( ) - new_trail_size);
  assert( trail_lim.size( ) == 0 );
  qhead = trail.size( );
  //
  // Undo operations
  //
  size_t new_stack_size = undo_stack_size.back( );
  undo_stack_size.pop_back( );
  while ( undo_stack_oper.size( ) > new_stack_size )
  {
    const oper_t op = undo_stack_oper.back( );

    if ( op == NEWVAR )
    {
#ifdef BUILD_64
      long xl = reinterpret_cast< long >( undo_stack_elem.back( ) );
      const Var x = static_cast< Var >( xl );
#else
      const Var x = reinterpret_cast< int >( undo_stack_elem.back( ) );
#endif

      // Undoes insertVarOrder( )
      assert( order_heap.inHeap(x) );
      order_heap  .remove(x);
      // Undoes decision_var ... watches
      decision_var.pop();
      polarity    .pop();
      seen        .pop();
      activity    .pop();
      level       .pop();
      assigns     .pop();
      reason      .pop();
      watches     .pop();
      watches     .pop();
    }
    else if ( op == NEWUNIT )
    {
    }
    else if ( op == NEWCLAUSE )
    {
      Clause * c = (Clause *)undo_stack_elem.back( );
      assert( clauses.last( ) == c );
      // assert( c->id + 1 == (int)clause_id_to_enode.size( ) );
      clauses.pop( );
      removeClause( *c );
      // clause_id_to_enode.pop_back( );
    }
    else
    {
      opensmt_error2( "unknown undo operation in BitBlaster", op );
    }

    undo_stack_oper.pop_back( );
    undo_stack_elem.pop_back( );
  }

  while( learnts.size( ) > 0 )
  {
    Clause * c = learnts.last( );
    learnts.pop( );
    removeClause( *c );
  }

  while( removed.size( ) > 0 )
  {
    Clause * c = removed.last( );
    removed.pop( );
    free( c ); 
  }
    
  assert( undo_stack_elem.size( ) == undo_stack_oper.size( ) );
  assert( learnts.size( ) == 0 );
  assert( removed.size( ) == 0 );
}