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); }
void CoreSMTSolver::printTrail( ) { for (int i = 0; i < trail.size(); i++) { printLit( trail[i] ); // cerr << " | "; // printSMTLit( cerr, trail[i] ); cerr << endl; } }
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); }
// 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); } }
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); }
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"); }
/*_________________________________________________________________________________________________ | | 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); } } }
/*_________________________________________________________________________________________________ | | 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; }
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(); } } }
/*_________________________________________________________________________________________________ | | 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 } }