void solver_reducedb(solver* s) { int i, j; double extra_lim = s->cla_inc / vecp_size(&s->learnts); /* Remove any clause below this activity */ clause** learnts = (clause**)vecp_begin(&s->learnts); clause** reasons = s->reasons; sort(vecp_begin(&s->learnts), vecp_size(&s->learnts), clause_cmp); for (i = j = 0; i < vecp_size(&s->learnts) / 2; i++){ if (clause_size(learnts[i]) > 2 && reasons[lit_var(*clause_begin(learnts[i]))] != learnts[i]) clause_remove(s,learnts[i]); else learnts[j++] = learnts[i]; } for (; i < vecp_size(&s->learnts); i++){ if (clause_size(learnts[i]) > 2 && reasons[lit_var(*clause_begin(learnts[i]))] != learnts[i] && clause_activity(learnts[i]) < extra_lim) clause_remove(s,learnts[i]); else learnts[j++] = learnts[i]; } /* printf("reducedb deleted %d\n", vecp_size(&s->learnts) - j); */ vecp_resize(&s->learnts,j); }
static inline void act_clause_rescale(solver* s) { clause** cs = (clause**)vecp_begin(&s->learnts); int i; for (i = 0; i < vecp_size(&s->learnts); i++){ float a = clause_activity(cs[i]); clause_setactivity(cs[i], a * (float)1e-20); } s->cla_inc *= (float)1e-20; }
static inline void vecp_remove(vecp* v, void* e) { void** ws = vecp_begin(v); int j = 0; for (; ws[j] != e ; j++); assert(j < vecp_size(v)); for (; j < vecp_size(v)-1; j++) ws[j] = ws[j+1]; vecp_resize(v,vecp_size(v)-1); }
// returns false if there is a conflict due to this decision bool propagate_decision(solver* s, lit decision, bool new_level){ bool no_conflict = true; int i,j,false_count; clause* c; if(new_level){ s->cur_level++; s->level_choice[s->cur_level] = decision; s->decisions[decision] = true; // only change 'decisions' on level decisions. } s->levels[decision] = s->cur_level; s->assigns[decision] = l_True; s->assigns[lit_neg(decision)] = l_False; for(i = 0; i < s->tail; i++){ c = vecp_begin(&s->clauses)[i]; for(j = 0; j < clause_size(c); j++){ if(j == 0) false_count = 0; if(s->assigns[c->lits[j]] == l_False) { false_count++; } else if(s->assigns[c->lits[j]] == l_True) { c->level_sat = s->cur_level; if(s->tail == 1) { s->tail--; s->satisfied = true; return true; } vecp_begin(&s->clauses)[i] = vecp_begin(&s->clauses)[--s->tail]; vecp_begin(&s->clauses)[s->tail] = c; i = i--; // be sure to check the current i again - it isn't the same one it was! break; } if(false_count == clause_size(c)) { no_conflict = false; //Conflict found! } } } return no_conflict; }
void printclauses(solver* s) { int i; clause* c; printf("Printing clauses:\n"); for(i = 0; i < vecp_size(&s->clauses); i++){ c = vecp_begin(&s->clauses)[i]; printf("Clause %d:\t\t",i); printvalues(c->lits,c->lits + c->size); printf("\t\tsize: %d\tlevel_sat: %d\n",c->size,c->level_sat); } }
void solver_delete(solver* s) { int i; for (i = 0; i < vecp_size(&s->clauses); i++) free(vecp_begin(&s->clauses)[i]); for (i = 0; i < vecp_size(&s->learnts); i++) free(vecp_begin(&s->learnts)[i]); /* delete vectors */ vecp_delete(&s->clauses); vecp_delete(&s->learnts); veci_delete(&s->order); veci_delete(&s->trail_lim); veci_delete(&s->tagged); veci_delete(&s->stack); veci_delete(&s->model); free(s->binary); /* delete arrays */ if (s->wlists != 0){ int i; for (i = 0; i < s->size*2; i++) vecp_delete(&s->wlists[i]); /* if one is different from null, all are */ free(s->wlists); free(s->activity ); free(s->assigns ); free(s->orderpos ); free(s->reasons ); free(s->levels ); free(s->trail ); free(s->tags ); } free(s); }
// finds a unit clause if there is one. Returns true if so, where unit_lit is the literal in that clause. bool find_unit(solver* s, lit* unit_lit){ int i,j, false_count; clause* c; for(i = 0; i < s->tail; i++){ c = vecp_begin(&s->clauses)[i]; for(j = 0; j < clause_size(c); j++){ if(j == 0) false_count = 0; assert(s->assigns[c->lits[j]] != l_True); if(s->assigns[c->lits[j]] == l_False) false_count++; else *unit_lit = c->lits[j]; // If this is a unit clause, this will be the unit lit. if(j == clause_size(c) - 1 && false_count == clause_size(c) - 1) { return true; //UNIT CLAUSE! } } } return false; // NO UNIT CLAUSES }
bool update_counts(solver* s) { int i,j; clause* c; // reset all counts to 0 initially for(i = 0; i < s->size*2; i++) { s->counts[i] = 0; } // now recount for(i = 0; i < s->tail;i++) { c = vecp_begin(&s->clauses)[i]; for(j = 0; j < clause_size(c); j++) { // A true literal should not be in the working set of clauses! if(s->assigns[c->lits[j]] == l_True) return false; else if(s->assigns[c->lits[j]] == l_Undef) // Only count if not False s->counts[c->lits[j]]++; } } return true; }
// returns the level_choice of the level backtracked to lit backtrack_once(solver* s){ int i; clause* c; for(i = 0; i < s->size*2; i++){ if(s->levels[i] == s->cur_level){ s->assigns[i] = l_Undef; s->assigns[lit_neg(i)] = l_Undef; s->levels[i] = -1; } } for(i = s->tail; i < vecp_size(&s->clauses); i++){ c = vecp_begin(&s->clauses)[i]; if(c->level_sat == s->cur_level){ c->level_sat = -1; s->tail++; } else break; } return s->level_choice[s->cur_level--]; }
void solver_delete(solver* s) { int i; for (i = 0; i < vecp_size(&s->clauses); i++) // free all clauses free(vecp_begin(&s->clauses)[i]); // delete vectors vecp_delete(&s->clauses); // delete arrays if (s->decisions != 0){ // if one is different from null, all are free(s->decisions); free(s->level_choice); free(s->assigns ); free(s->levels ); free(s->counts ); } free(s); }
bool solver_simplify(solver* s) { clause** reasons; int type; assert(solver_dlevel(s) == 0); if (solver_propagate(s) != 0) return false; if (s->qhead == s->simpdb_assigns || s->simpdb_props > 0) return true; reasons = s->reasons; for (type = 0; type < 2; type++){ vecp* cs = type ? &s->learnts : &s->clauses; clause** cls = (clause**)vecp_begin(cs); int i, j; for (j = i = 0; i < vecp_size(cs); i++){ if (reasons[lit_var(*clause_begin(cls[i]))] != cls[i] && clause_simplify(s,cls[i]) == l_True) clause_remove(s,cls[i]); else cls[j++] = cls[i]; } vecp_resize(cs,j); } s->simpdb_assigns = s->qhead; /* (shouldn't depend on 'stats' really, but it will do for now) */ s->simpdb_props = (int)(s->stats.clauses_literals + s->stats.learnts_literals); return true; }
clause* solver_propagate(solver* s) { lbool* values = s->assigns; clause* confl = (clause*)0; lit* lits; /* printf("solver_propagate\n"); */ while (confl == 0 && s->qtail - s->qhead > 0){ lit p = s->trail[s->qhead++]; vecp* ws = solver_read_wlist(s,p); clause **begin = (clause**)vecp_begin(ws); clause **end = begin + vecp_size(ws); clause **i, **j; s->stats.propagations++; s->simpdb_props--; /* printf("checking lit %d: "L_LIT"\n", veci_size(ws), L_lit(p)); */ for (i = j = begin; i < end; ){ if (clause_is_lit(*i)){ *j++ = *i; if (!enqueue(s,clause_read_lit(*i),clause_from_lit(p))){ confl = s->binary; (clause_begin(confl))[1] = lit_neg(p); (clause_begin(confl))[0] = clause_read_lit(*i++); /* Copy the remaining watches: */ while (i < end) *j++ = *i++; } }else{ lit false_lit; lbool sig; lits = clause_begin(*i); /* Make sure the false literal is data[1]: */ false_lit = lit_neg(p); if (lits[0] == false_lit){ lits[0] = lits[1]; lits[1] = false_lit; } assert(lits[1] == false_lit); /* printf("checking clause: "); printlits(lits, lits+clause_size(*i)); printf("\n"); */ /* If 0th watch is true, then clause is already satisfied. */ sig = !lit_sign(lits[0]); sig += sig - 1; if (values[lit_var(lits[0])] == sig){ *j++ = *i; }else{ /* Look for new watch: */ lit* stop = lits + clause_size(*i); lit* k; for (k = lits + 2; k < stop; k++){ lbool sig = lit_sign(*k); sig += sig - 1; if (values[lit_var(*k)] != sig){ lits[1] = *k; *k = false_lit; vecp_push(solver_read_wlist(s, lit_neg(lits[1])),*i); goto next; } } *j++ = *i; /* Clause is unit under assignment: */ if (!enqueue(s,lits[0], *i)){ confl = *i++; /* Copy the remaining watches: */ while (i < end) *j++ = *i++; } } } next: i++; } s->stats.inspects += j - (clause**)vecp_begin(ws); vecp_resize(ws,j - (clause**)vecp_begin(ws)); } return confl; }