Beispiel #1
0
void Solver::uncheckedEnqueue(Lit p, Clause* from)
{
#ifdef __PRINT  
  if (from) {
    printClause(*from);
  }
  
  printf("--> ");
  printLit(p);
  printf("\n");

  if (decisionLevel() == 0) {
    printf("Zl: ");
    printLit(p);
    printf("\n");

  }
#endif
    

  assigns [var(p)] = toInt(lbool(!sign(p)));  // <<== abstract but not uttermost effecient
  level   [var(p)] = decisionLevel();
  reason  [var(p)] = from;
  trail.push(p);
}
Beispiel #2
0
void CoreSMTSolver::printTrail( )
{
  for (int i = 0; i < trail.size(); i++)
  {
    printLit( trail[i] );
    // cerr << " | ";
    // printSMTLit( cerr, trail[i] );
    cerr << endl;
  }
}
Beispiel #3
0
void Solver::uncheckedEnqueue(Lit p, Clause* from)
{
    #ifdef RESTORE
    if (backup.stage == 0) {
        printf("setting lit "); printLit(p); printf(" decLevel: %d flag: %d detachedClause: %p\n", decisionLevel(), backup.stage, backup.detachedClause);
    }
    #endif

    assert(value(p) == l_Undef);
    assigns [var(p)] = toInt(lbool(!sign(p)));  // <<== abstract but not uttermost effecient
    level   [var(p)] = decisionLevel();
    reason  [var(p)] = from;
    polarity[var(p)] = sign(p);
    trail.push(p);
}
Beispiel #4
0
// Revert to the state at given level (keeping all assignment at 'level' but not beyond).
//
void Solver::cancelUntil(int level) {
    #ifdef RESTORE
    printf("------------    Canceling until level %d\n", level);
    #endif
  if (decisionLevel() > level){
    for (int c = trail.size()-1; c >= trail_lim[level]; c--){
      Var     x  = var(trail[c]);
      assigns[x] = toInt(l_Undef);
      insertVarOrder(x);
      #ifdef RESTORE
      printf("Canceling lit ");printLit(trail[c]); printf("\n");
      #endif
    }
    qhead = trail_lim[level];
    trail.shrink(trail.size() - trail_lim[level]);
    trail_lim.shrink(trail_lim.size() - level);
  }
}
Beispiel #5
0
Lit Solver::pickBranchLit(int polarity_mode, double random_var_freq)
{
    Var next = var_Undef;
    /*if (backup.stage == 0) {
        assert(order_heap.heapProperty());
        for(int i = 0; i < std::min(order_heap.size(), 10); i++) {
            printf("order_heap %d has var %d, has activity %lf\n", i, order_heap[i], activity[order_heap[i]]);
        }
    }*/

    // Random decision:
    if (drand(random_seed) < random_var_freq
        && !order_heap.empty()
    ){
        next = order_heap[irand(random_seed,order_heap.size())];
        if (toLbool(assigns[next]) == l_Undef && decision_var[next])
            rnd_decisions++;
    }

    // Activity based decision:
    while (next == var_Undef || toLbool(assigns[next]) != l_Undef || !decision_var[next])
      if (order_heap.empty()){
            next = var_Undef;
            break;
        }else
            next = order_heap.removeMin();

    bool sign = false;
    switch (polarity_mode){
    case polarity_true:  sign = false; break;
    case polarity_false: sign = true;  break;
    case polarity_user:  if(next!=var_Undef) sign = polarity[next]; break;
    case polarity_rnd:   sign = irand(random_seed, 2); break;
    default: assert(false); }

    #ifdef RESTORE
    if (backup.stage == 0) {
        printf("--> Picking decision lit "); printLit(Lit(next, sign)); printf(" at decision level: %d, sublevel: %d\n", decisionLevel(), trail.size());
    }
    #endif

    return next == var_Undef ? lit_Undef : Lit(next, sign);
}
Beispiel #6
0
void Solver::liftModel2() {
  vec<lbool> completeModel;

  //printf ("Copy Model\n");
  //completeModel.clear();
  model.copyTo(completeModel);
  model.clear();
  model.growTo(completeModel.size(), l_Undef);
  //printf ("Copy done\n");

  // Foreach variable v
  for (int i=0; i<nVars(); i++)
    if (reason[i])
      model[i]=completeModel[i];

  printf ("Trail: \n");
  for (int i=0; i<trail.size(); i++) {
    printLit (trail[i]);
    printf (" ");
  }
  printf ("0\n");
}
Beispiel #7
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 #8
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 #9
0
void GroundProgramBuilder::add()
{
	switch(stack_->type)
	{
		case LIT:
		{
			stack_->lits.push_back(Lit::create(stack_->type, stack_->vals.size() - stack_->n - 1, stack_->n));
			break;
		}
		case TERM:
		{
			if(stack_->n > 0)
			{
				ValVec vals;
				std::copy(stack_->vals.end() - stack_->n, stack_->vals.end(), std::back_inserter(vals));
				stack_->vals.resize(stack_->vals.size() - stack_->n);
				uint32_t name = stack_->vals.back().index;
				stack_->vals.back()  = Val::func(storage()->index(Func(storage(), name, vals)));
			}
			break;
		}
		case AGGR_SUM:
		case AGGR_COUNT:
		case AGGR_AVG:
		case AGGR_MIN:
		case AGGR_MAX:
		case AGGR_EVEN:
		case AGGR_EVEN_SET:
		case AGGR_ODD:
		case AGGR_ODD_SET:
		case AGGR_DISJUNCTION:
		{
			assert(stack_->type != AGGR_DISJUNCTION || stack_->n > 0);
			std::copy(stack_->lits.end() - stack_->n, stack_->lits.end(), std::back_inserter(stack_->aggrLits));
			stack_->lits.resize(stack_->lits.size() - stack_->n);
			stack_->lits.push_back(Lit::create(stack_->type, stack_->n ? stack_->aggrLits.size() - stack_->n : stack_->vals.size() - 2, stack_->n));
			break;
		}
		case STM_RULE:
		case STM_CONSTRAINT:
		{
			Rule::Printer *printer = output_->printer<Rule::Printer>();
			printer->begin();
			if(stack_->type == STM_RULE)             { printLit(printer, stack_->lits.size() - stack_->n - 1, true); }
			printer->endHead();
			for(uint32_t i = stack_->n; i >= 1; i--) { printLit(printer, stack_->lits.size() - i, false); }
			printer->end();
			pop(stack_->n + (stack_->type == STM_RULE));
			break;
		}
		case STM_SHOW:
		case STM_HIDE:
		{
			Display::Printer *printer = output_->printer<Display::Printer>();
			printLit(printer, stack_->lits.size() - 1, stack_->type == STM_SHOW);
			pop(1);
			break;
		}
		case STM_EXTERNAL:
		{
			External::Printer *printer = output_->printer<External::Printer>();
			printLit(printer, stack_->lits.size() - 1, true);
			pop(1);
			break;
		}
		#pragma message "reimplement this"
		/*
		case STM_MINIMIZE:
		case STM_MAXIMIZE:
		case STM_MINIMIZE_SET:
		case STM_MAXIMIZE_SET:
		{
			Optimize::Printer *printer = output_->printer<Optimize::Printer>();
			bool maximize = (stack_->type == STM_MAXIMIZE || stack_->type == STM_MAXIMIZE_SET);
			bool set = (stack_->type == STM_MINIMIZE_SET || stack_->type == STM_MAXIMIZE_SET);
			printer->begin(maximize, set);
			for(uint32_t i = stack_->n; i >= 1; i--)
			{

				Lit &a     = stack_->lits[stack_->lits.size() - i];
				Val prio   = stack_->vals[a.offset + a.n + 2];
				Val weight = stack_->vals[a.offset + a.n + 1];
				printer->print(predLitRep(a), weight.num, prio.num);
			}
			printer->end();
			pop(stack_->n);
			break;
		}
		*/
		case STM_COMPUTE:
		{
			Compute::Printer *printer = output_->printer<Compute::Printer>();
			for(uint32_t i = stack_->n; i >= 1; i--)
			{
				Lit &a = stack_->lits[stack_->lits.size() - i];
				printer->print(predLitRep(a));
			}
			pop(stack_->n);
			break;
		}
#pragma message "reimplement me!"
		//case META_SHOW:
		//case META_HIDE:
//		case META_EXTERNAL:
//		{
//			Val num = stack_->vals.back();
//			stack_->vals.pop_back();
//			Val id  = stack_->vals.back();
//			stack_->vals.pop_back();
//			assert(id.type == Val::ID);
//			assert(num.type == Val::NUM);
//			storage()->newDomain(id.index, num.num);
//			if(stack_->type == META_EXTERNAL) { output_->external(id.index, num.num); }
//			//else { output_->show(id.index, num.num, stack_->type == META_SHOW); }
//			break;
//		}
#pragma message "reimplement me!"
		//case META_GLOBALSHOW:
		case META_GLOBALHIDE:
		{
			output_->hideAll();
			break;
		}
		default: {
			doAdd();
		}
	}
}
Beispiel #10
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
  }
}