00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include <stdio.h>
00023 #include <assert.h>
00024 #include <string.h>
00025 #include <math.h>
00026
00027 #include "satSolver.h"
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037 #define L_IND "%-*d"
00038 #define L_ind sat_solver_dlevel(s)*3+3,sat_solver_dlevel(s)
00039 #define L_LIT "%sx%d"
00040 #define L_lit(p) lit_sign(p)?"~":"", (lit_var(p))
00041
00042
00043 static inline void check(int expr) { assert(expr); }
00044
00045 static void printlits(lit* begin, lit* end)
00046 {
00047 int i;
00048 for (i = 0; i < end - begin; i++)
00049 printf(L_LIT" ",L_lit(begin[i]));
00050 }
00051
00052
00053
00054
00055
00056
00057 static inline double drand(double* seed) {
00058 int q;
00059 *seed *= 1389796;
00060 q = (int)(*seed / 2147483647);
00061 *seed -= (double)q * 2147483647;
00062 return *seed / 2147483647; }
00063
00064
00065
00066 static inline int irand(double* seed, int size) {
00067 return (int)(drand(seed) * size); }
00068
00069
00070
00071
00072
00073 static void sat_solver_sort(void** array, int size, int(*comp)(const void *, const void *));
00074
00075
00076
00077
00078 struct clause_t
00079 {
00080 int size_learnt;
00081 lit lits[0];
00082 };
00083
00084 static inline int clause_size (clause* c) { return c->size_learnt >> 1; }
00085 static inline lit* clause_begin (clause* c) { return c->lits; }
00086 static inline int clause_learnt (clause* c) { return c->size_learnt & 1; }
00087 static inline float clause_activity (clause* c) { return *((float*)&c->lits[c->size_learnt>>1]); }
00088 static inline void clause_setactivity(clause* c, float a) { *((float*)&c->lits[c->size_learnt>>1]) = a; }
00089
00090
00091
00092
00093 static inline clause* clause_from_lit (lit l) { return (clause*)((unsigned long)l + (unsigned long)l + 1); }
00094 static inline bool clause_is_lit (clause* c) { return ((unsigned long)c & 1); }
00095 static inline lit clause_read_lit (clause* c) { return (lit)((unsigned long)c >> 1); }
00096
00097
00098
00099
00100 static inline int sat_solver_dlevel(sat_solver* s) { return veci_size(&s->trail_lim); }
00101 static inline vecp* sat_solver_read_wlist(sat_solver* s, lit l) { return &s->wlists[l]; }
00102 static inline void vecp_remove(vecp* v, void* e)
00103 {
00104 void** ws = vecp_begin(v);
00105 int j = 0;
00106 for (; ws[j] != e ; j++);
00107 assert(j < vecp_size(v));
00108 for (; j < vecp_size(v)-1; j++) ws[j] = ws[j+1];
00109 vecp_resize(v,vecp_size(v)-1);
00110 }
00111
00112
00113
00114
00115 static inline void order_update(sat_solver* s, int v)
00116 {
00117 int* orderpos = s->orderpos;
00118 double* activity = s->activity;
00119 int* heap = veci_begin(&s->order);
00120 int i = orderpos[v];
00121 int x = heap[i];
00122 int parent = (i - 1) / 2;
00123
00124 assert(s->orderpos[v] != -1);
00125
00126 while (i != 0 && activity[x] > activity[heap[parent]]){
00127 heap[i] = heap[parent];
00128 orderpos[heap[i]] = i;
00129 i = parent;
00130 parent = (i - 1) / 2;
00131 }
00132 heap[i] = x;
00133 orderpos[x] = i;
00134 }
00135
00136 static inline void order_assigned(sat_solver* s, int v)
00137 {
00138 }
00139
00140 static inline void order_unassigned(sat_solver* s, int v)
00141 {
00142 int* orderpos = s->orderpos;
00143 if (orderpos[v] == -1){
00144 orderpos[v] = veci_size(&s->order);
00145 veci_push(&s->order,v);
00146 order_update(s,v);
00147
00148 }
00149 }
00150
00151 static inline int order_select(sat_solver* s, float random_var_freq)
00152 {
00153 int* heap;
00154 double* activity;
00155 int* orderpos;
00156
00157 lbool* values = s->assigns;
00158
00159
00160 if (drand(&s->random_seed) < random_var_freq){
00161 int next = irand(&s->random_seed,s->size);
00162 assert(next >= 0 && next < s->size);
00163 if (values[next] == l_Undef)
00164 return next;
00165 }
00166
00167
00168
00169 heap = veci_begin(&s->order);
00170 activity = s->activity;
00171 orderpos = s->orderpos;
00172
00173
00174 while (veci_size(&s->order) > 0){
00175 int next = heap[0];
00176 int size = veci_size(&s->order)-1;
00177 int x = heap[size];
00178
00179 veci_resize(&s->order,size);
00180
00181 orderpos[next] = -1;
00182
00183 if (size > 0){
00184 double act = activity[x];
00185
00186 int i = 0;
00187 int child = 1;
00188
00189
00190 while (child < size){
00191 if (child+1 < size && activity[heap[child]] < activity[heap[child+1]])
00192 child++;
00193
00194 assert(child < size);
00195
00196 if (act >= activity[heap[child]])
00197 break;
00198
00199 heap[i] = heap[child];
00200 orderpos[heap[i]] = i;
00201 i = child;
00202 child = 2 * child + 1;
00203 }
00204 heap[i] = x;
00205 orderpos[heap[i]] = i;
00206 }
00207
00208
00209 if (values[next] == l_Undef)
00210 return next;
00211 }
00212
00213 return var_Undef;
00214 }
00215
00216
00217
00218
00219 static inline void act_var_rescale(sat_solver* s) {
00220 double* activity = s->activity;
00221 int i;
00222 for (i = 0; i < s->size; i++)
00223 activity[i] *= 1e-100;
00224 s->var_inc *= 1e-100;
00225 }
00226
00227 static inline void act_var_bump(sat_solver* s, int v) {
00228 s->activity[v] += s->var_inc;
00229 if (s->activity[v] > 1e100)
00230 act_var_rescale(s);
00231
00232 if (s->orderpos[v] != -1)
00233 order_update(s,v);
00234 }
00235
00236 static inline void act_var_bump_factor(sat_solver* s, int v) {
00237 s->activity[v] += (s->var_inc * s->factors[v]);
00238 if (s->activity[v] > 1e100)
00239 act_var_rescale(s);
00240
00241 if (s->orderpos[v] != -1)
00242 order_update(s,v);
00243 }
00244
00245 static inline void act_var_decay(sat_solver* s) { s->var_inc *= s->var_decay; }
00246
00247 static inline void act_clause_rescale(sat_solver* s) {
00248 clause** cs = (clause**)vecp_begin(&s->learnts);
00249 int i;
00250 for (i = 0; i < vecp_size(&s->learnts); i++){
00251 float a = clause_activity(cs[i]);
00252 clause_setactivity(cs[i], a * (float)1e-20);
00253 }
00254 s->cla_inc *= (float)1e-20;
00255 }
00256
00257
00258 static inline void act_clause_bump(sat_solver* s, clause *c) {
00259 float a = clause_activity(c) + s->cla_inc;
00260 clause_setactivity(c,a);
00261 if (a > 1e20) act_clause_rescale(s);
00262 }
00263
00264 static inline void act_clause_decay(sat_solver* s) { s->cla_inc *= s->cla_decay; }
00265
00266
00267
00268
00269
00270
00271 static clause* clause_new(sat_solver* s, lit* begin, lit* end, int learnt)
00272 {
00273 int size;
00274 clause* c;
00275 int i;
00276
00277 assert(end - begin > 1);
00278 assert(learnt >= 0 && learnt < 2);
00279 size = end - begin;
00280
00281 #ifdef SAT_USE_SYSTEM_MEMORY_MANAGEMENT
00282 c = (clause*)malloc(sizeof(clause) + sizeof(lit) * size + learnt * sizeof(float));
00283 #else
00284 c = (clause*)Sat_MmStepEntryFetch( s->pMem, sizeof(clause) + sizeof(lit) * size + learnt * sizeof(float) );
00285 #endif
00286
00287 c->size_learnt = (size << 1) | learnt;
00288 assert(((unsigned int)c & 1) == 0);
00289
00290 for (i = 0; i < size; i++)
00291 c->lits[i] = begin[i];
00292
00293 if (learnt)
00294 *((float*)&c->lits[size]) = 0.0;
00295
00296 assert(begin[0] >= 0);
00297 assert(begin[0] < s->size*2);
00298 assert(begin[1] >= 0);
00299 assert(begin[1] < s->size*2);
00300
00301 assert(lit_neg(begin[0]) < s->size*2);
00302 assert(lit_neg(begin[1]) < s->size*2);
00303
00304
00305
00306
00307 vecp_push(sat_solver_read_wlist(s,lit_neg(begin[0])),(void*)(size > 2 ? c : clause_from_lit(begin[1])));
00308 vecp_push(sat_solver_read_wlist(s,lit_neg(begin[1])),(void*)(size > 2 ? c : clause_from_lit(begin[0])));
00309
00310 return c;
00311 }
00312
00313
00314 static void clause_remove(sat_solver* s, clause* c)
00315 {
00316 lit* lits = clause_begin(c);
00317 assert(lit_neg(lits[0]) < s->size*2);
00318 assert(lit_neg(lits[1]) < s->size*2);
00319
00320
00321
00322
00323 assert(lits[0] < s->size*2);
00324 vecp_remove(sat_solver_read_wlist(s,lit_neg(lits[0])),(void*)(clause_size(c) > 2 ? c : clause_from_lit(lits[1])));
00325 vecp_remove(sat_solver_read_wlist(s,lit_neg(lits[1])),(void*)(clause_size(c) > 2 ? c : clause_from_lit(lits[0])));
00326
00327 if (clause_learnt(c)){
00328 s->stats.learnts--;
00329 s->stats.learnts_literals -= clause_size(c);
00330 }else{
00331 s->stats.clauses--;
00332 s->stats.clauses_literals -= clause_size(c);
00333 }
00334
00335 #ifdef SAT_USE_SYSTEM_MEMORY_MANAGEMENT
00336 free(c);
00337 #else
00338 Sat_MmStepEntryRecycle( s->pMem, (char *)c, sizeof(clause) + sizeof(lit) * clause_size(c) + clause_learnt(c) * sizeof(float) );
00339 #endif
00340 }
00341
00342
00343 static lbool clause_simplify(sat_solver* s, clause* c)
00344 {
00345 lit* lits = clause_begin(c);
00346 lbool* values = s->assigns;
00347 int i;
00348
00349 assert(sat_solver_dlevel(s) == 0);
00350
00351 for (i = 0; i < clause_size(c); i++){
00352 lbool sig = !lit_sign(lits[i]); sig += sig - 1;
00353 if (values[lit_var(lits[i])] == sig)
00354 return l_True;
00355 }
00356 return l_False;
00357 }
00358
00359
00360
00361
00362 void sat_solver_setnvars(sat_solver* s,int n)
00363 {
00364 int var;
00365
00366 if (s->cap < n){
00367
00368 while (s->cap < n) s->cap = s->cap*2+1;
00369
00370 s->wlists = (vecp*) realloc(s->wlists, sizeof(vecp)*s->cap*2);
00371 s->activity = (double*) realloc(s->activity, sizeof(double)*s->cap);
00372 s->factors = (double*) realloc(s->factors, sizeof(double)*s->cap);
00373 s->assigns = (lbool*) realloc(s->assigns, sizeof(lbool)*s->cap);
00374 s->orderpos = (int*) realloc(s->orderpos, sizeof(int)*s->cap);
00375 s->reasons = (clause**)realloc(s->reasons, sizeof(clause*)*s->cap);
00376 s->levels = (int*) realloc(s->levels, sizeof(int)*s->cap);
00377 s->tags = (lbool*) realloc(s->tags, sizeof(lbool)*s->cap);
00378 s->trail = (lit*) realloc(s->trail, sizeof(lit)*s->cap);
00379 }
00380
00381 for (var = s->size; var < n; var++){
00382 vecp_new(&s->wlists[2*var]);
00383 vecp_new(&s->wlists[2*var+1]);
00384 s->activity [var] = 0;
00385 s->factors [var] = 0;
00386 s->assigns [var] = l_Undef;
00387 s->orderpos [var] = veci_size(&s->order);
00388 s->reasons [var] = (clause*)0;
00389 s->levels [var] = 0;
00390 s->tags [var] = l_Undef;
00391
00392
00393
00394
00395 veci_push(&s->order,var);
00396 order_update(s, var);
00397 }
00398
00399 s->size = n > s->size ? n : s->size;
00400 }
00401
00402
00403 static inline bool enqueue(sat_solver* s, lit l, clause* from)
00404 {
00405 lbool* values = s->assigns;
00406 int v = lit_var(l);
00407 lbool val = values[v];
00408 #ifdef VERBOSEDEBUG
00409 printf(L_IND"enqueue("L_LIT")\n", L_ind, L_lit(l));
00410 #endif
00411
00412 lbool sig = !lit_sign(l); sig += sig - 1;
00413 if (val != l_Undef){
00414 return val == sig;
00415 }else{
00416
00417 #ifdef VERBOSEDEBUG
00418 printf(L_IND"bind("L_LIT")\n", L_ind, L_lit(l));
00419 #endif
00420 int* levels = s->levels;
00421 clause** reasons = s->reasons;
00422
00423 values [v] = sig;
00424 levels [v] = sat_solver_dlevel(s);
00425 reasons[v] = from;
00426 s->trail[s->qtail++] = l;
00427
00428 order_assigned(s, v);
00429 return true;
00430 }
00431 }
00432
00433
00434 static inline void assume(sat_solver* s, lit l){
00435 assert(s->qtail == s->qhead);
00436 assert(s->assigns[lit_var(l)] == l_Undef);
00437 #ifdef VERBOSEDEBUG
00438 printf(L_IND"assume("L_LIT")\n", L_ind, L_lit(l));
00439 #endif
00440 veci_push(&s->trail_lim,s->qtail);
00441 enqueue(s,l,(clause*)0);
00442 }
00443
00444
00445 static void sat_solver_canceluntil(sat_solver* s, int level) {
00446 lit* trail;
00447 lbool* values;
00448 clause** reasons;
00449 int bound;
00450 int c;
00451
00452 if (sat_solver_dlevel(s) <= level)
00453 return;
00454
00455 trail = s->trail;
00456 values = s->assigns;
00457 reasons = s->reasons;
00458 bound = (veci_begin(&s->trail_lim))[level];
00459
00461
00462
00463
00465
00466 for (c = s->qtail-1; c >= bound; c--) {
00467 int x = lit_var(trail[c]);
00468 values [x] = l_Undef;
00469 reasons[x] = (clause*)0;
00470 }
00471
00472 for (c = s->qhead-1; c >= bound; c--)
00473 order_unassigned(s,lit_var(trail[c]));
00474
00475 s->qhead = s->qtail = bound;
00476 veci_resize(&s->trail_lim,level);
00477 }
00478
00479 static void sat_solver_record(sat_solver* s, veci* cls)
00480 {
00481 lit* begin = veci_begin(cls);
00482 lit* end = begin + veci_size(cls);
00483 clause* c = (veci_size(cls) > 1) ? clause_new(s,begin,end,1) : (clause*)0;
00484 enqueue(s,*begin,c);
00485
00487
00488 if ( s->pStore )
00489 {
00490 extern int Sto_ManAddClause( void * p, lit * pBeg, lit * pEnd );
00491 int RetValue = Sto_ManAddClause( s->pStore, begin, end );
00492 assert( RetValue );
00493 }
00495
00496 assert(veci_size(cls) > 0);
00497
00498 if (c != 0) {
00499 vecp_push(&s->learnts,c);
00500 act_clause_bump(s,c);
00501 s->stats.learnts++;
00502 s->stats.learnts_literals += veci_size(cls);
00503 }
00504 }
00505
00506
00507 static double sat_solver_progress(sat_solver* s)
00508 {
00509 lbool* values = s->assigns;
00510 int* levels = s->levels;
00511 int i;
00512
00513 double progress = 0;
00514 double F = 1.0 / s->size;
00515 for (i = 0; i < s->size; i++)
00516 if (values[i] != l_Undef)
00517 progress += pow(F, levels[i]);
00518 return progress / s->size;
00519 }
00520
00521
00522
00523
00524 static bool sat_solver_lit_removable(sat_solver* s, lit l, int minl)
00525 {
00526 lbool* tags = s->tags;
00527 clause** reasons = s->reasons;
00528 int* levels = s->levels;
00529 int top = veci_size(&s->tagged);
00530
00531 assert(lit_var(l) >= 0 && lit_var(l) < s->size);
00532 assert(reasons[lit_var(l)] != 0);
00533 veci_resize(&s->stack,0);
00534 veci_push(&s->stack,lit_var(l));
00535
00536 while (veci_size(&s->stack) > 0){
00537 clause* c;
00538 int v = veci_begin(&s->stack)[veci_size(&s->stack)-1];
00539 assert(v >= 0 && v < s->size);
00540 veci_resize(&s->stack,veci_size(&s->stack)-1);
00541 assert(reasons[v] != 0);
00542 c = reasons[v];
00543
00544 if (clause_is_lit(c)){
00545 int v = lit_var(clause_read_lit(c));
00546 if (tags[v] == l_Undef && levels[v] != 0){
00547 if (reasons[v] != 0 && ((1 << (levels[v] & 31)) & minl)){
00548 veci_push(&s->stack,v);
00549 tags[v] = l_True;
00550 veci_push(&s->tagged,v);
00551 }else{
00552 int* tagged = veci_begin(&s->tagged);
00553 int j;
00554 for (j = top; j < veci_size(&s->tagged); j++)
00555 tags[tagged[j]] = l_Undef;
00556 veci_resize(&s->tagged,top);
00557 return false;
00558 }
00559 }
00560 }else{
00561 lit* lits = clause_begin(c);
00562 int i, j;
00563
00564 for (i = 1; i < clause_size(c); i++){
00565 int v = lit_var(lits[i]);
00566 if (tags[v] == l_Undef && levels[v] != 0){
00567 if (reasons[v] != 0 && ((1 << (levels[v] & 31)) & minl)){
00568
00569 veci_push(&s->stack,lit_var(lits[i]));
00570 tags[v] = l_True;
00571 veci_push(&s->tagged,v);
00572 }else{
00573 int* tagged = veci_begin(&s->tagged);
00574 for (j = top; j < veci_size(&s->tagged); j++)
00575 tags[tagged[j]] = l_Undef;
00576 veci_resize(&s->tagged,top);
00577 return false;
00578 }
00579 }
00580 }
00581 }
00582 }
00583
00584 return true;
00585 }
00586
00587 static void sat_solver_analyze(sat_solver* s, clause* c, veci* learnt)
00588 {
00589 lit* trail = s->trail;
00590 lbool* tags = s->tags;
00591 clause** reasons = s->reasons;
00592 int* levels = s->levels;
00593 int cnt = 0;
00594 lit p = lit_Undef;
00595 int ind = s->qtail-1;
00596 lit* lits;
00597 int i, j, minl;
00598 int* tagged;
00599
00600 veci_push(learnt,lit_Undef);
00601
00602 do{
00603 assert(c != 0);
00604
00605 if (clause_is_lit(c)){
00606 lit q = clause_read_lit(c);
00607 assert(lit_var(q) >= 0 && lit_var(q) < s->size);
00608 if (tags[lit_var(q)] == l_Undef && levels[lit_var(q)] > 0){
00609 tags[lit_var(q)] = l_True;
00610 veci_push(&s->tagged,lit_var(q));
00611 act_var_bump(s,lit_var(q));
00612 if (levels[lit_var(q)] == sat_solver_dlevel(s))
00613 cnt++;
00614 else
00615 veci_push(learnt,q);
00616 }
00617 }else{
00618
00619 if (clause_learnt(c))
00620 act_clause_bump(s,c);
00621
00622 lits = clause_begin(c);
00623
00624 for (j = (p == lit_Undef ? 0 : 1); j < clause_size(c); j++){
00625 lit q = lits[j];
00626 assert(lit_var(q) >= 0 && lit_var(q) < s->size);
00627 if (tags[lit_var(q)] == l_Undef && levels[lit_var(q)] > 0){
00628 tags[lit_var(q)] = l_True;
00629 veci_push(&s->tagged,lit_var(q));
00630 act_var_bump(s,lit_var(q));
00631 if (levels[lit_var(q)] == sat_solver_dlevel(s))
00632 cnt++;
00633 else
00634 veci_push(learnt,q);
00635 }
00636 }
00637 }
00638
00639 while (tags[lit_var(trail[ind--])] == l_Undef);
00640
00641 p = trail[ind+1];
00642 c = reasons[lit_var(p)];
00643 cnt--;
00644
00645 }while (cnt > 0);
00646
00647 *veci_begin(learnt) = lit_neg(p);
00648
00649 lits = veci_begin(learnt);
00650 minl = 0;
00651 for (i = 1; i < veci_size(learnt); i++){
00652 int lev = levels[lit_var(lits[i])];
00653 minl |= 1 << (lev & 31);
00654 }
00655
00656
00657 for (i = j = 1; i < veci_size(learnt); i++){
00658 if (reasons[lit_var(lits[i])] == 0 || !sat_solver_lit_removable(s,lits[i],minl))
00659 lits[j++] = lits[i];
00660 }
00661
00662
00663 s->stats.max_literals += veci_size(learnt);
00664 veci_resize(learnt,j);
00665 s->stats.tot_literals += j;
00666
00667
00668 tagged = veci_begin(&s->tagged);
00669 for (i = 0; i < veci_size(&s->tagged); i++)
00670 tags[tagged[i]] = l_Undef;
00671 veci_resize(&s->tagged,0);
00672
00673 #ifdef DEBUG
00674 for (i = 0; i < s->size; i++)
00675 assert(tags[i] == l_Undef);
00676 #endif
00677
00678 #ifdef VERBOSEDEBUG
00679 printf(L_IND"Learnt {", L_ind);
00680 for (i = 0; i < veci_size(learnt); i++) printf(" "L_LIT, L_lit(lits[i]));
00681 #endif
00682 if (veci_size(learnt) > 1){
00683 int max_i = 1;
00684 int max = levels[lit_var(lits[1])];
00685 lit tmp;
00686
00687 for (i = 2; i < veci_size(learnt); i++)
00688 if (levels[lit_var(lits[i])] > max){
00689 max = levels[lit_var(lits[i])];
00690 max_i = i;
00691 }
00692
00693 tmp = lits[1];
00694 lits[1] = lits[max_i];
00695 lits[max_i] = tmp;
00696 }
00697 #ifdef VERBOSEDEBUG
00698 {
00699 int lev = veci_size(learnt) > 1 ? levels[lit_var(lits[1])] : 0;
00700 printf(" } at level %d\n", lev);
00701 }
00702 #endif
00703 }
00704
00705
00706 clause* sat_solver_propagate(sat_solver* s)
00707 {
00708 lbool* values = s->assigns;
00709 clause* confl = (clause*)0;
00710 lit* lits;
00711
00712
00713 while (confl == 0 && s->qtail - s->qhead > 0){
00714 lit p = s->trail[s->qhead++];
00715 vecp* ws = sat_solver_read_wlist(s,p);
00716 clause **begin = (clause**)vecp_begin(ws);
00717 clause **end = begin + vecp_size(ws);
00718 clause **i, **j;
00719
00720 s->stats.propagations++;
00721 s->simpdb_props--;
00722
00723
00724 for (i = j = begin; i < end; ){
00725 if (clause_is_lit(*i)){
00726
00727 *j++ = *i;
00728 if (!enqueue(s,clause_read_lit(*i),clause_from_lit(p))){
00729 confl = s->binary;
00730 (clause_begin(confl))[1] = lit_neg(p);
00731 (clause_begin(confl))[0] = clause_read_lit(*i++);
00732
00733
00734 while (i < end)
00735 *j++ = *i++;
00736 }
00737 }else{
00738 lit false_lit;
00739 lbool sig;
00740
00741 lits = clause_begin(*i);
00742
00743
00744 false_lit = lit_neg(p);
00745 if (lits[0] == false_lit){
00746 lits[0] = lits[1];
00747 lits[1] = false_lit;
00748 }
00749 assert(lits[1] == false_lit);
00750
00751
00752
00753 sig = !lit_sign(lits[0]); sig += sig - 1;
00754 if (values[lit_var(lits[0])] == sig){
00755 *j++ = *i;
00756 }else{
00757
00758 lit* stop = lits + clause_size(*i);
00759 lit* k;
00760 for (k = lits + 2; k < stop; k++){
00761 lbool sig = lit_sign(*k); sig += sig - 1;
00762 if (values[lit_var(*k)] != sig){
00763 lits[1] = *k;
00764 *k = false_lit;
00765 vecp_push(sat_solver_read_wlist(s,lit_neg(lits[1])),*i);
00766 goto next; }
00767 }
00768
00769 *j++ = *i;
00770
00771 if (!enqueue(s,lits[0], *i)){
00772 confl = *i++;
00773
00774
00775 while (i < end)
00776 *j++ = *i++;
00777 }
00778 }
00779 }
00780 next:
00781 i++;
00782 }
00783
00784 s->stats.inspects += j - (clause**)vecp_begin(ws);
00785 vecp_resize(ws,j - (clause**)vecp_begin(ws));
00786 }
00787
00788 return confl;
00789 }
00790
00791 static inline int clause_cmp (const void* x, const void* y) {
00792 return clause_size((clause*)x) > 2 && (clause_size((clause*)y) == 2 || clause_activity((clause*)x) < clause_activity((clause*)y)) ? -1 : 1; }
00793
00794 void sat_solver_reducedb(sat_solver* s)
00795 {
00796 int i, j;
00797 double extra_lim = s->cla_inc / vecp_size(&s->learnts);
00798 clause** learnts = (clause**)vecp_begin(&s->learnts);
00799 clause** reasons = s->reasons;
00800
00801 sat_solver_sort(vecp_begin(&s->learnts), vecp_size(&s->learnts), &clause_cmp);
00802
00803 for (i = j = 0; i < vecp_size(&s->learnts) / 2; i++){
00804 if (clause_size(learnts[i]) > 2 && reasons[lit_var(*clause_begin(learnts[i]))] != learnts[i])
00805 clause_remove(s,learnts[i]);
00806 else
00807 learnts[j++] = learnts[i];
00808 }
00809 for (; i < vecp_size(&s->learnts); i++){
00810 if (clause_size(learnts[i]) > 2 && reasons[lit_var(*clause_begin(learnts[i]))] != learnts[i] && clause_activity(learnts[i]) < extra_lim)
00811 clause_remove(s,learnts[i]);
00812 else
00813 learnts[j++] = learnts[i];
00814 }
00815
00816
00817
00818
00819 vecp_resize(&s->learnts,j);
00820 }
00821
00822 static lbool sat_solver_search(sat_solver* s, sint64 nof_conflicts, sint64 nof_learnts)
00823 {
00824 int* levels = s->levels;
00825 double var_decay = 0.95;
00826 double clause_decay = 0.999;
00827 double random_var_freq = 0.02;
00828
00829 sint64 conflictC = 0;
00830 veci learnt_clause;
00831 int i;
00832
00833 assert(s->root_level == sat_solver_dlevel(s));
00834
00835 s->nRestarts++;
00836 s->stats.starts++;
00837 s->var_decay = (float)(1 / var_decay );
00838 s->cla_decay = (float)(1 / clause_decay);
00839 veci_resize(&s->model,0);
00840 veci_new(&learnt_clause);
00841
00842
00843 if ( (s->nRestarts & 1) && veci_size(&s->act_vars) > 0 )
00844 for ( i = 0; i < s->act_vars.size; i++ )
00845 act_var_bump_factor(s, s->act_vars.ptr[i]);
00846
00847 for (;;){
00848 clause* confl = sat_solver_propagate(s);
00849 if (confl != 0){
00850
00851 int blevel;
00852
00853 #ifdef VERBOSEDEBUG
00854 printf(L_IND"**CONFLICT**\n", L_ind);
00855 #endif
00856 s->stats.conflicts++; conflictC++;
00857 if (sat_solver_dlevel(s) == s->root_level){
00858 veci_delete(&learnt_clause);
00859 return l_False;
00860 }
00861
00862 veci_resize(&learnt_clause,0);
00863 sat_solver_analyze(s, confl, &learnt_clause);
00864 blevel = veci_size(&learnt_clause) > 1 ? levels[lit_var(veci_begin(&learnt_clause)[1])] : s->root_level;
00865 blevel = s->root_level > blevel ? s->root_level : blevel;
00866 sat_solver_canceluntil(s,blevel);
00867 sat_solver_record(s,&learnt_clause);
00868 act_var_decay(s);
00869 act_clause_decay(s);
00870
00871 }else{
00872
00873 int next;
00874
00875 if (nof_conflicts >= 0 && conflictC >= nof_conflicts){
00876
00877 s->progress_estimate = sat_solver_progress(s);
00878 sat_solver_canceluntil(s,s->root_level);
00879 veci_delete(&learnt_clause);
00880 return l_Undef; }
00881
00882 if ( s->nConfLimit && s->stats.conflicts > s->nConfLimit ||
00883 s->nInsLimit && s->stats.inspects > s->nInsLimit )
00884 {
00885
00886 s->progress_estimate = sat_solver_progress(s);
00887 sat_solver_canceluntil(s,s->root_level);
00888 veci_delete(&learnt_clause);
00889 return l_Undef;
00890 }
00891
00892 if (sat_solver_dlevel(s) == 0 && !s->fSkipSimplify)
00893
00894 sat_solver_simplify(s);
00895
00896 if (nof_learnts >= 0 && vecp_size(&s->learnts) - s->qtail >= nof_learnts)
00897
00898 sat_solver_reducedb(s);
00899
00900
00901 s->stats.decisions++;
00902 next = order_select(s,(float)random_var_freq);
00903
00904 if (next == var_Undef){
00905
00906 lbool* values = s->assigns;
00907 int i;
00908 veci_resize(&s->model, 0);
00909 for (i = 0; i < s->size; i++)
00910 veci_push(&s->model,(int)values[i]);
00911 sat_solver_canceluntil(s,s->root_level);
00912 veci_delete(&learnt_clause);
00913
00914
00915
00916
00917
00918
00919
00920
00921
00922 return l_True;
00923 }
00924
00925 assume(s,lit_neg(toLit(next)));
00926 }
00927 }
00928
00929 return l_Undef;
00930 }
00931
00932
00933
00934
00935 sat_solver* sat_solver_new(void)
00936 {
00937 sat_solver* s = (sat_solver*)malloc(sizeof(sat_solver));
00938 memset( s, 0, sizeof(sat_solver) );
00939
00940
00941 vecp_new(&s->clauses);
00942 vecp_new(&s->learnts);
00943 veci_new(&s->order);
00944 veci_new(&s->trail_lim);
00945 veci_new(&s->tagged);
00946 veci_new(&s->stack);
00947 veci_new(&s->model);
00948 veci_new(&s->act_vars);
00949
00950
00951 s->wlists = 0;
00952 s->activity = 0;
00953 s->factors = 0;
00954 s->assigns = 0;
00955 s->orderpos = 0;
00956 s->reasons = 0;
00957 s->levels = 0;
00958 s->tags = 0;
00959 s->trail = 0;
00960
00961
00962
00963 s->size = 0;
00964 s->cap = 0;
00965 s->qhead = 0;
00966 s->qtail = 0;
00967 s->cla_inc = 1;
00968 s->cla_decay = 1;
00969 s->var_inc = 1;
00970 s->var_decay = 1;
00971 s->root_level = 0;
00972 s->simpdb_assigns = 0;
00973 s->simpdb_props = 0;
00974 s->random_seed = 91648253;
00975 s->progress_estimate = 0;
00976 s->binary = (clause*)malloc(sizeof(clause) + sizeof(lit)*2);
00977 s->binary->size_learnt = (2 << 1);
00978 s->verbosity = 0;
00979
00980 s->stats.starts = 0;
00981 s->stats.decisions = 0;
00982 s->stats.propagations = 0;
00983 s->stats.inspects = 0;
00984 s->stats.conflicts = 0;
00985 s->stats.clauses = 0;
00986 s->stats.clauses_literals = 0;
00987 s->stats.learnts = 0;
00988 s->stats.learnts_literals = 0;
00989 s->stats.max_literals = 0;
00990 s->stats.tot_literals = 0;
00991
00992 #ifdef SAT_USE_SYSTEM_MEMORY_MANAGEMENT
00993 s->pMem = NULL;
00994 #else
00995 s->pMem = Sat_MmStepStart( 10 );
00996 #endif
00997 return s;
00998 }
00999
01000
01001 void sat_solver_delete(sat_solver* s)
01002 {
01003
01004 #ifdef SAT_USE_SYSTEM_MEMORY_MANAGEMENT
01005 int i;
01006 for (i = 0; i < vecp_size(&s->clauses); i++)
01007 free(vecp_begin(&s->clauses)[i]);
01008 for (i = 0; i < vecp_size(&s->learnts); i++)
01009 free(vecp_begin(&s->learnts)[i]);
01010 #else
01011 Sat_MmStepStop( s->pMem, 0 );
01012 #endif
01013
01014
01015 vecp_delete(&s->clauses);
01016 vecp_delete(&s->learnts);
01017 veci_delete(&s->order);
01018 veci_delete(&s->trail_lim);
01019 veci_delete(&s->tagged);
01020 veci_delete(&s->stack);
01021 veci_delete(&s->model);
01022 veci_delete(&s->act_vars);
01023 free(s->binary);
01024
01025
01026 if (s->wlists != 0){
01027 int i;
01028 for (i = 0; i < s->size*2; i++)
01029 vecp_delete(&s->wlists[i]);
01030
01031
01032 free(s->wlists );
01033 free(s->activity );
01034 free(s->factors );
01035 free(s->assigns );
01036 free(s->orderpos );
01037 free(s->reasons );
01038 free(s->levels );
01039 free(s->trail );
01040 free(s->tags );
01041 }
01042
01043 sat_solver_store_free(s);
01044 free(s);
01045 }
01046
01047
01048 bool sat_solver_addclause(sat_solver* s, lit* begin, lit* end)
01049 {
01050 lit *i,*j;
01051 int maxvar;
01052 lbool* values;
01053 lit last;
01054
01055 if (begin == end) return false;
01056
01057
01058
01059 maxvar = lit_var(*begin);
01060 for (i = begin + 1; i < end; i++){
01061 lit l = *i;
01062 maxvar = lit_var(l) > maxvar ? lit_var(l) : maxvar;
01063 for (j = i; j > begin && *(j-1) > l; j--)
01064 *j = *(j-1);
01065 *j = l;
01066 }
01067 sat_solver_setnvars(s,maxvar+1);
01068
01069
01070
01071 values = s->assigns;
01072
01073
01074 last = lit_Undef;
01075 for (i = j = begin; i < end; i++){
01076
01077 lbool sig = !lit_sign(*i); sig += sig - 1;
01078 if (*i == lit_neg(last) || sig == values[lit_var(*i)])
01079 return true;
01080 else if (*i != last && values[lit_var(*i)] == l_Undef)
01081 last = *j++ = *i;
01082 }
01083
01084
01085
01086 if (j == begin)
01087 return false;
01088
01090
01091 if ( s->pStore )
01092 {
01093 extern int Sto_ManAddClause( void * p, lit * pBeg, lit * pEnd );
01094 int RetValue = Sto_ManAddClause( s->pStore, begin, j );
01095 assert( RetValue );
01096 }
01098
01099 if (j - begin == 1)
01100 return enqueue(s,*begin,(clause*)0);
01101
01102
01103 vecp_push(&s->clauses,clause_new(s,begin,j,0));
01104
01105
01106 s->stats.clauses++;
01107 s->stats.clauses_literals += j - begin;
01108
01109 return true;
01110 }
01111
01112
01113 bool sat_solver_simplify(sat_solver* s)
01114 {
01115 clause** reasons;
01116 int type;
01117
01118 assert(sat_solver_dlevel(s) == 0);
01119
01120 if (sat_solver_propagate(s) != 0)
01121 return false;
01122
01123 if (s->qhead == s->simpdb_assigns || s->simpdb_props > 0)
01124 return true;
01125
01126 reasons = s->reasons;
01127 for (type = 0; type < 2; type++){
01128 vecp* cs = type ? &s->learnts : &s->clauses;
01129 clause** cls = (clause**)vecp_begin(cs);
01130
01131 int i, j;
01132 for (j = i = 0; i < vecp_size(cs); i++){
01133 if (reasons[lit_var(*clause_begin(cls[i]))] != cls[i] &&
01134 clause_simplify(s,cls[i]) == l_True)
01135 clause_remove(s,cls[i]);
01136 else
01137 cls[j++] = cls[i];
01138 }
01139 vecp_resize(cs,j);
01140 }
01141
01142 s->simpdb_assigns = s->qhead;
01143
01144 s->simpdb_props = (int)(s->stats.clauses_literals + s->stats.learnts_literals);
01145
01146 return true;
01147 }
01148
01149
01150 int sat_solver_solve(sat_solver* s, lit* begin, lit* end, sint64 nConfLimit, sint64 nInsLimit, sint64 nConfLimitGlobal, sint64 nInsLimitGlobal)
01151 {
01152 sint64 nof_conflicts = 100;
01153 sint64 nof_learnts = sat_solver_nclauses(s) / 3;
01154 lbool status = l_Undef;
01155 lbool* values = s->assigns;
01156 lit* i;
01157
01158
01159 s->nCalls++;
01160 s->nRestarts = 0;
01161 s->nConfLimit = 0;
01162 s->nInsLimit = 0;
01163 if ( nConfLimit )
01164 s->nConfLimit = s->stats.conflicts + nConfLimit;
01165 if ( nInsLimit )
01166 s->nInsLimit = s->stats.inspects + nInsLimit;
01167 if ( nConfLimitGlobal && (s->nConfLimit == 0 || s->nConfLimit > nConfLimitGlobal) )
01168 s->nConfLimit = nConfLimitGlobal;
01169 if ( nInsLimitGlobal && (s->nInsLimit == 0 || s->nInsLimit > nInsLimitGlobal) )
01170 s->nInsLimit = nInsLimitGlobal;
01171
01172
01173 for (i = begin; i < end; i++){
01174 switch (lit_sign(*i) ? -values[lit_var(*i)] : values[lit_var(*i)]){
01175 case 1:
01176 break;
01177 case 0:
01178 assume(s, *i);
01179 if (sat_solver_propagate(s) == NULL)
01180 break;
01181
01182 case -1:
01183 sat_solver_canceluntil(s, 0);
01184 return l_False;
01185 }
01186 }
01187 s->nCalls2++;
01188
01189 s->root_level = sat_solver_dlevel(s);
01190
01191 if (s->verbosity >= 1){
01192 printf("==================================[MINISAT]===================================\n");
01193 printf("| Conflicts | ORIGINAL | LEARNT | Progress |\n");
01194 printf("| | Clauses Literals | Limit Clauses Literals Lit/Cl | |\n");
01195 printf("==============================================================================\n");
01196 }
01197
01198 while (status == l_Undef){
01199 double Ratio = (s->stats.learnts == 0)? 0.0 :
01200 s->stats.learnts_literals / (double)s->stats.learnts;
01201
01202 if (s->verbosity >= 1)
01203 {
01204 printf("| %9.0f | %7.0f %8.0f | %7.0f %7.0f %8.0f %7.1f | %6.3f %% |\n",
01205 (double)s->stats.conflicts,
01206 (double)s->stats.clauses,
01207 (double)s->stats.clauses_literals,
01208 (double)nof_learnts,
01209 (double)s->stats.learnts,
01210 (double)s->stats.learnts_literals,
01211 Ratio,
01212 s->progress_estimate*100);
01213 fflush(stdout);
01214 }
01215 status = sat_solver_search(s, nof_conflicts, nof_learnts);
01216 nof_conflicts = nof_conflicts * 3 / 2;
01217 nof_learnts = nof_learnts * 11 / 10;
01218
01219
01220 if ( s->nConfLimit && s->stats.conflicts > s->nConfLimit )
01221 {
01222
01223 break;
01224 }
01225 if ( s->nInsLimit && s->stats.inspects > s->nInsLimit )
01226 {
01227
01228 break;
01229 }
01230 }
01231 if (s->verbosity >= 1)
01232 printf("==============================================================================\n");
01233
01234 sat_solver_canceluntil(s,0);
01235
01237 if ( status == l_False && s->pStore )
01238 {
01239 extern int Sto_ManAddClause( void * p, lit * pBeg, lit * pEnd );
01240 int RetValue = Sto_ManAddClause( s->pStore, NULL, NULL );
01241 assert( RetValue );
01242 }
01244 return status;
01245 }
01246
01247
01248 int sat_solver_nvars(sat_solver* s)
01249 {
01250 return s->size;
01251 }
01252
01253
01254 int sat_solver_nclauses(sat_solver* s)
01255 {
01256 return vecp_size(&s->clauses);
01257 }
01258
01259
01260 int sat_solver_nconflicts(sat_solver* s)
01261 {
01262 return (int)s->stats.conflicts;
01263 }
01264
01265
01266
01267
01268 void sat_solver_store_alloc( sat_solver * s )
01269 {
01270 extern void * Sto_ManAlloc();
01271 assert( s->pStore == NULL );
01272 s->pStore = Sto_ManAlloc();
01273 }
01274
01275 void sat_solver_store_write( sat_solver * s, char * pFileName )
01276 {
01277 extern void Sto_ManDumpClauses( void * p, char * pFileName );
01278 if ( s->pStore ) Sto_ManDumpClauses( s->pStore, pFileName );
01279 }
01280
01281 void sat_solver_store_free( sat_solver * s )
01282 {
01283 extern void Sto_ManFree( void * p );
01284 if ( s->pStore ) Sto_ManFree( s->pStore );
01285 s->pStore = NULL;
01286 }
01287
01288 void sat_solver_store_mark_roots( sat_solver * s )
01289 {
01290 extern void Sto_ManMarkRoots( void * p );
01291 if ( s->pStore ) Sto_ManMarkRoots( s->pStore );
01292 }
01293
01294 void sat_solver_store_mark_clauses_a( sat_solver * s )
01295 {
01296 extern void Sto_ManMarkClausesA( void * p );
01297 if ( s->pStore ) Sto_ManMarkClausesA( s->pStore );
01298 }
01299
01300 void * sat_solver_store_release( sat_solver * s )
01301 {
01302 void * pTemp;
01303 if ( s->pStore == NULL )
01304 return NULL;
01305 pTemp = s->pStore;
01306 s->pStore = NULL;
01307 return pTemp;
01308 }
01309
01310
01311
01312
01313 static inline void selectionsort(void** array, int size, int(*comp)(const void *, const void *))
01314 {
01315 int i, j, best_i;
01316 void* tmp;
01317
01318 for (i = 0; i < size-1; i++){
01319 best_i = i;
01320 for (j = i+1; j < size; j++){
01321 if (comp(array[j], array[best_i]) < 0)
01322 best_i = j;
01323 }
01324 tmp = array[i]; array[i] = array[best_i]; array[best_i] = tmp;
01325 }
01326 }
01327
01328
01329 static void sortrnd(void** array, int size, int(*comp)(const void *, const void *), double* seed)
01330 {
01331 if (size <= 15)
01332 selectionsort(array, size, comp);
01333
01334 else{
01335 void* pivot = array[irand(seed, size)];
01336 void* tmp;
01337 int i = -1;
01338 int j = size;
01339
01340 for(;;){
01341 do i++; while(comp(array[i], pivot)<0);
01342 do j--; while(comp(pivot, array[j])<0);
01343
01344 if (i >= j) break;
01345
01346 tmp = array[i]; array[i] = array[j]; array[j] = tmp;
01347 }
01348
01349 sortrnd(array , i , comp, seed);
01350 sortrnd(&array[i], size-i, comp, seed);
01351 }
01352 }
01353
01354 void sat_solver_sort(void** array, int size, int(*comp)(const void *, const void *))
01355 {
01356 double seed = 91648253;
01357 sortrnd(array,size,comp,&seed);
01358 }