VIS

src/sat/satInc.c

Go to the documentation of this file.
00001 
00019 #include "satInt.h"
00020 
00021 static char rcsid[] UNUSED = "$Id: satInc.c,v 1.16 2009/04/11 18:26:37 fabio Exp $";
00022 static satManager_t *SatCm;
00023 
00024 /*---------------------------------------------------------------------------*/
00025 /* Constant declarations                                                     */
00026 /*---------------------------------------------------------------------------*/
00027 
00030 /*---------------------------------------------------------------------------*/
00031 /* Static function prototypes                                                */
00032 /*---------------------------------------------------------------------------*/
00033 
00034 static int ScoreDistillCompare(const void *x, const void *y);
00035 
00039 /*---------------------------------------------------------------------------*/
00040 /* Definition of exported functions                                          */
00041 /*---------------------------------------------------------------------------*/
00042 
00043 
00057 void
00058 sat_IncrementalUsingDistill(satManager_t *cm)
00059 {
00060   sat_TrieBasedImplication(cm, cm->trieArray, 1);
00061   sat_FreeTrie(cm, cm->trieArray);
00062   cm->trieArray = 0;
00063   fprintf(cm->stdOut, "%s %d conflicts are forwarded from distillation,\n",
00064           cm->comment,
00065           cm->each->nDistillObjConflictCl + cm->each->nDistillNonobjConflictCl);
00066 }
00067 
00079 satLevel_t *
00080 sat_DecisionBasedOnTrie(
00081         satManager_t *cm,
00082         long v,
00083         int value)
00084 {
00085 satLevel_t *d;
00086 
00087   d = sat_AllocLevel(cm);
00088   d->decisionNode = v;
00089 
00090   SATvalue(v) = value;
00091   SATmakeImplied(v, d);
00092 
00093   sat_Enqueue(cm->queue, v);
00094   SATflags(v) |= InQueueMask;
00095 
00096   return(d);
00097 }
00098 
00110 void
00111 sat_TrieBasedImplication(
00112         satManager_t *cm,
00113         satArray_t *trieArray,
00114         int depth)
00115 {
00116 int i;
00117 satTrie_t *t;
00118 satLevel_t *d;
00119 satArray_t *tArray;
00120 
00121   if(trieArray == 0)    return;
00122 
00123   for(i=0; i<trieArray->num; i++) {
00124     t = (satTrie_t *)(trieArray->space[i]);
00125     if(SATvalue(t->id) < 2)     continue;
00126 
00127     tArray = t->child[0];
00128     if(tArray) {
00129       d = sat_DecisionBasedOnTrie(cm, t->id, 0);
00130       sat_ImplicationMain(cm, d);
00131       if(d->conflict) {
00132         sat_ConflictAnalysisOnTrie(cm, d);
00133       }
00134       else if(cm->status == 0) {
00135         sat_TrieBasedImplication(cm, tArray, depth+1);
00136       }
00137       sat_Backtrack(cm, depth-1);
00138     }
00139 
00140     tArray = t->child[1];
00141     if(tArray && cm->status == 0) {
00142       d = sat_DecisionBasedOnTrie(cm, t->id, 1);
00143       sat_ImplicationMain(cm, d);
00144       if(d->conflict) {
00145         sat_ConflictAnalysisOnTrie(cm, d);
00146       }
00147       else if(cm->status == 0) {
00148         sat_TrieBasedImplication(cm, tArray, depth+1);
00149       }
00150       sat_Backtrack(cm, depth-1);
00151     }
00152 
00153     if(cm->status == SAT_BACKTRACK && depth == 1) {
00154       cm->status = 0;
00155       d = SATgetDecision(0);
00156       sat_ImplyArray(cm, d, cm->nonobjUnitLitArray);
00157       sat_ImplyArray(cm, d, cm->objUnitLitArray);
00158       sat_MarkObjectiveFlagToArray(cm, cm->objUnitLitArray);
00159       sat_ImplicationMain(cm, d);
00160       if(d->conflict) {
00161         cm->status = SAT_UNSAT;
00162         return;
00163       }
00164       i--;
00165     }
00166   }
00167 }
00168 
00180 void
00181 sat_ConflictAnalysisOnTrie(
00182         satManager_t *cm,
00183         satLevel_t *d)
00184 {
00185 int bLevel;
00186 long v, learned, unitLit;
00187 int objectFlag;
00188 satArray_t *clauseArray;
00189 satStatistics_t *stats;
00190 
00191   bLevel = 0;
00192   unitLit = -1;
00193   clauseArray = cm->auxArray;
00194   sat_FindUIP(cm, clauseArray, d, &objectFlag, &bLevel, &unitLit);
00195 
00196   if(clauseArray->num > (int)(cm->currentDecision*2)) {
00197     sat_GetConflictAsConflictClause(cm, clauseArray);
00198   }
00199 
00200   if(clauseArray->num == 1) {
00201     cm->status = SAT_BACKTRACK;
00202     v = clauseArray->space[0];
00203     if(objectFlag)
00204       sat_ArrayInsert(cm->objUnitLitArray, SATnot(v));
00205     else
00206       sat_ArrayInsert(cm->nonobjUnitLitArray, SATnot(v));
00207   }
00208   else {
00209     learned = sat_AddClauseIncremental(cm, clauseArray, objectFlag, 1);
00210   }
00211 
00212   stats = cm->each;
00213   if(objectFlag) {
00214     stats->nInitObjConflictCl++;
00215     stats->nInitObjConflictLit += clauseArray->num;
00216     stats->nObjConflictCl++;
00217     stats->nObjConflictLit += clauseArray->num;
00218     stats->nDistillObjConflictCl++;
00219     stats->nDistillObjConflictLit += clauseArray->num;
00220   }
00221   else {
00222     stats->nInitNonobjConflictCl++;
00223     stats->nInitNonobjConflictLit += clauseArray->num;
00224     stats->nObjConflictCl++;
00225     stats->nObjConflictLit += clauseArray->num;
00226     stats->nDistillNonobjConflictCl++;
00227     stats->nDistillNonobjConflictLit += clauseArray->num;
00228   }
00229   stats->nConflictCl++;
00230   stats->nConflictLit += clauseArray->num;
00231 }
00232 
00246 void
00247 sat_GetConflictAsConflictClause(
00248         satManager_t *cm,
00249         satArray_t *clauseArray)
00250 {
00251 int i;
00252 satLevel_t *d;
00253 
00254   clauseArray->num = 0;
00255   for(i=1; i<=cm->currentDecision; i++) {
00256     d = SATgetDecision(i);
00257     sat_ArrayInsert(clauseArray,
00258             (d->decisionNode)^(!(SATvalue(d->decisionNode))));
00259   }
00260 }
00261 
00273 void
00274 sat_RestoreForwardedClauses(satManager_t *cm, int objectFlag)
00275 {
00276 int i, size;
00277 int total;
00278 long *space, c, *start;
00279 satArray_t *saved;
00280 satArray_t *clause;
00281 //Bing
00282  int NotCoi = 0, ct=0;
00283 
00284 
00285   if(cm->option->checkNonobjForwarding) {
00286     sat_CheckForwardedClauses(cm);
00287   }
00288 
00289   saved = cm->savedConflictClauses;
00290   if(saved == 0)
00291     return;
00292 
00293   clause = sat_ArrayAlloc(50);
00294 
00295   total = 0;
00296   for(i=0, space=saved->space; i<saved->num; i++, space++){
00297     if(*space < 0) {
00298       space++;
00299       i++;
00300       start = space;
00301       size = 0;
00302       clause->num = 0;
00303       //Bing:
00304       NotCoi = 0;
00305       while(*space > 0) {
00306         sat_ArrayInsert(clause, SATnot((*space)));
00307         //Bing:
00308         if(!(SATflags(*space)&CoiMask)){
00309           NotCoi = 1;
00310         }
00311         size++;
00312         i++;
00313         space++;
00314       }
00315 
00316 
00317       //Bing:
00318       if(cm->option->AbRf){
00319         if(!NotCoi){
00320           c = sat_AddClauseIncremental(cm, clause, objectFlag, 0);
00321           total++;
00322         }
00323         else
00324           ct++;
00325       }
00326       else{
00327         c = sat_AddClauseIncremental(cm, clause, objectFlag, 0);
00328         total++;
00329       }
00330     }
00331   }
00332   sat_ArrayFree(clause);
00333   sat_ArrayFree(saved);
00334   cm->savedConflictClauses = 0;
00335 
00338 }
00339 
00351 void
00352 sat_CheckForwardedClauses(satManager_t *cm)
00353 {
00354 long *space, *start;
00355 long nv;
00356 int size, i;
00357 int total;
00358 int conflictFlag, inverted;
00359 int j, value, level;
00360 satLevel_t *d;
00361 satArray_t *saved;
00362 satArray_t *clause;
00363 
00364   d = 0;
00365   saved = cm->savedConflictClauses;
00366   if(saved == 0)
00367     return;
00368 
00369   clause = sat_ArrayAlloc(50);
00370 
00371   total = 0;
00372   for(i=0, space=saved->space; i<saved->num; i++, space++){
00373     if(*space < 0) {
00374       start = space;
00375       space++;
00376       i++;
00377       size = 0;
00378       clause->num = 0;
00379       conflictFlag = 0;
00380       while(*space > 0) {
00381         sat_ArrayInsert(clause, SATnot((*space)));
00382         if(conflictFlag == 0) {
00383           nv = *space;
00384           inverted = (SATisInverted(nv));
00385           nv = SATnormalNode(nv);
00386 
00387           d = sat_AllocLevel(cm);
00388           d->decisionNode = nv;
00389           SATvalue(nv) = inverted;
00390           SATmakeImplied(nv, d);
00391 
00392           sat_Enqueue(cm->queue, nv);
00393           SATflags(nv) |= InQueueMask;
00394 
00395           sat_ImplicationMain(cm, d);
00396           if(d->conflict)       conflictFlag = 1;
00397         }
00398         size++;
00399         i++;
00400         space++;
00401       }
00402 
00403       if(d->conflict == 0) {
00404         fprintf(cm->stdOut, "%s ERROR : %ld does not result in conflict\n",
00405             cm->comment, *start);
00406         for(j=0; j<clause->num; j++) {
00407           nv = clause->space[j];
00408           inverted = SATisInverted(nv);
00409           nv = SATnormalNode(nv);
00410           value = SATvalue(nv);
00411           level = value>1 ? -1 : SATlevel(nv);
00412           fprintf(cm->stdOut, "%6ld%c@%d=%c%c ",
00413                   nv, inverted ? '\'' : ' ', level, SATgetValueChar(value),
00414                   ' ');
00415         }
00416         fprintf(cm->stdOut, "\n");
00417       }
00418       sat_Backtrack(cm, -1);
00419 
00420       total++;
00421     }
00422   }
00423   sat_ArrayFree(clause);
00424 }
00425 
00439 void
00440 sat_SaveNonobjClauses(satManager_t *cm)
00441 {
00442 int limit, total, passed;
00443 int size, j;
00444 long *plit, nv, v, i;
00445 satArray_t *savedArray;
00446 
00447   savedArray = sat_ArrayAlloc(1024);
00448 
00449   total = passed = 0;
00450   limit = cm->option->incNumNonobjLitsLimit;
00451   for(i=cm->beginConflict; i<cm->nodesArraySize; i+= satNodeSize) {
00452     if(SATreadInUse(i) == 0)            continue;
00453     if(!(SATflags(i) & NonobjMask))     {
00454       continue;
00455     }
00456     size = SATnumLits(i);
00457     if(size > limit) {
00458       total++;
00459     }
00460     else {
00461       total++;
00462       passed++;
00463       plit = (long*)SATfirstLit(i);
00464       nv = (*(plit-1));
00465       sat_ArrayInsert(savedArray, nv);
00466       for(j=0; j<size; j++, plit++) {
00467         v = SATgetNode(*plit);
00468         sat_ArrayInsert(savedArray, v);
00469       }
00470       sat_ArrayInsert(savedArray, nv);
00471     }
00472   }
00473   if(cm->option->verbose > 1) {
00474     fprintf(cm->stdOut, "%s %d NonObjective Clauses forwarded out of %d\n",
00475             cm->comment, passed, total);
00476   }
00477   cm->savedConflictClauses = savedArray;
00478 }
00479 
00493 void
00494 sat_SaveAllClauses(satManager_t *cm)
00495 {
00496 int limit, total, passed;
00497 int size, j;
00498 long *plit, nv, v, i;
00499 satArray_t *savedArray;
00500 
00501   savedArray = sat_ArrayAlloc(1024);
00502 
00503   total = passed = 0;
00504   limit = cm->option->incNumNonobjLitsLimit;
00505   for(i=cm->beginConflict; i<cm->nodesArraySize; i+= satNodeSize) {
00506     if(SATreadInUse(i) == 0)            continue;
00507     size = SATnumLits(i);
00508     total++;
00509     plit = (long*)SATfirstLit(i);
00510     nv = (*(plit-1));
00511     sat_ArrayInsert(savedArray, nv);
00512     for(j=0; j<size; j++, plit++) {
00513       v = SATgetNode(*plit);
00514       sat_ArrayInsert(savedArray, v);
00515     }
00516     sat_ArrayInsert(savedArray, nv);
00517   }
00524   cm->savedConflictClauses = savedArray;
00525 }
00526 
00539 void
00540 sat_BuildTrieForDistill(satManager_t *cm)
00541 {
00542 int limit, nCl, nLit;
00543 int j, n;
00544 int size, inverted;
00545 long v, *plit, i;
00546 int findFlag;
00547 satVariable_t *var;
00548 satArray_t *trieArray;
00549 satArray_t *unitArray;
00550 satTrie_t *t;
00551 
00552   size = cm->initNumVariables * satNodeSize;
00553   for(i=satNodeSize; i<size; i+= satNodeSize) {
00554     var = SATgetVariable(i);
00555     var->scores[0] = 0;
00556     var->scores[1] = 0;
00557   }
00558 
00559   nCl = nLit = 0;
00560   limit = cm->option->incNumObjLitsLimit;
00561   for(i=cm->beginConflict; i<cm->nodesArraySize; i+= satNodeSize) {
00562     if(SATreadInUse(i) == 0)            continue;
00563     if(SATflags(i) & NonobjMask)        continue;
00564 
00565     size = SATnumLits(i);
00566     if(size > limit)    continue;
00567     n = 0;
00568     for(j=0, plit = (long*)SATfirstLit(i); j<size; j++, plit++) {
00569       v = SATgetNode(*plit);
00570       inverted = SATisInverted(v);
00571       v = SATnormalNode(v);
00572       var = SATgetVariable(v);
00573       var->scores[inverted] += 1;
00574       if(SATvalue(v) < 2)       continue;
00575       n++;
00576     }
00577     if(n > 0) {
00578       nCl++;
00579       nLit += n;
00580     }
00581   }
00582   if(cm->option->verbose > 1) {
00583     fprintf(cm->stdOut, "%s Candidates for Distill %d clauses %d literals\n",
00584             cm->comment, nCl, nLit);
00585   }
00586 
00587   trieArray = sat_ArrayAlloc(64);
00588   cm->trieArray = trieArray;
00589   unitArray = cm->objUnitLitArray;
00590   if(unitArray) {
00591     for(i=0; i<unitArray->num; i++) {
00592       v = unitArray->space[i];
00593       inverted = SATisInverted(v);
00594       v = SATnormalNode(v);
00595 
00596       findFlag = 0;
00597       for(j=0;  j<trieArray->num; j++) {
00598         t = (satTrie_t *)(trieArray->space[j]);
00599         if(t->id == v) {
00600           if(t->child[inverted] == 0)
00601             t->child[inverted] = sat_ArrayAlloc(2);
00602           findFlag = 1;
00603         }
00604       }
00605 
00606       if(findFlag == 0) {
00607         t = ALLOC(satTrie_t, 1);
00608         memset(t, 0, sizeof(satTrie_t));
00609         t->id = v;
00610         if(t->child[inverted] == 0)
00611           t->child[inverted] = sat_ArrayAlloc(2);
00612         sat_ArrayInsert(trieArray, (long)t);
00613       }
00614     }
00615   }
00616 
00617   for(i=cm->beginConflict; i<cm->nodesArraySize; i+=satNodeSize) {
00618     if(SATreadInUse(i) == 0)            continue;
00619     if(SATflags(i) & NonobjMask)        continue;
00620 
00621     size = SATnumLits(i);
00622     if(size > limit)    continue;
00623 
00624     plit = (long*)SATfirstLit(i);
00625     SatCm = cm;
00626     qsort(plit, size, sizeof(long), ScoreDistillCompare);
00627     sat_BuildTrie(cm, trieArray, plit, 1);
00628   }
00629 }
00630 
00643 void
00644 sat_BuildTrie(
00645         satManager_t *cm,
00646         satArray_t *trieArray,
00647         long *plit,
00648         int depth)
00649 {
00650 int i, inverted;
00651 long v;
00652 satTrie_t *t;
00653 
00654   while(1) {
00655     if(*plit <= 0)      return;
00656     v = SATgetNode(*plit);
00657     inverted = SATisInverted(v);
00658     v = SATnormalNode(v);
00659     if(SATvalue(v) < 2)plit++;
00660     else                break;
00661   }
00662 
00663   for(i=0; i<trieArray->num; i++) {
00664     t = (satTrie_t *)(trieArray->space[i]);
00665     if(t->id == v) {
00666       if(t->child[inverted] == 0)
00667         t->child[inverted] = sat_ArrayAlloc(2);
00668       plit++;
00669       sat_BuildTrie(cm, t->child[inverted], plit, depth+1);
00670       return;
00671     }
00672   }
00673 
00674   t = ALLOC(satTrie_t, 1);
00675   memset(t, 0, sizeof(satTrie_t));
00676   t->id = v;
00677   t->depth = depth;
00678   sat_ArrayInsert(trieArray, (long)t);
00679 
00680   if(t->child[inverted] == 0)
00681     t->child[inverted] = sat_ArrayAlloc(2);
00682   plit++;
00683   sat_BuildTrie(cm, t->child[inverted], plit, depth+1);
00684 }
00685 
00686 
00687 
00699 void
00700 sat_FreeTrie(satManager_t *cm, satArray_t *arr)
00701 {
00702 int i;
00703 satTrie_t *t;
00704 
00705   if(arr == 0)  return;
00706 
00707   for(i=0; i<arr->num; i++) {
00708     t = (satTrie_t *)(arr->space[i]);
00709     if(t->child[0]) {
00710       sat_FreeTrie(cm, t->child[0]);
00711       sat_ArrayFree(t->child[0]);
00712     }
00713     if(t->child[1]) {
00714       sat_FreeTrie(cm, t->child[1]);
00715       sat_ArrayFree(t->child[1]);
00716     }
00717     free(t);
00718   }
00719 
00720 }
00732 static int
00733 ScoreDistillCompare(const void *x, const void *y)
00734 {
00735 int n1, n2;
00736 int i1, i2;
00737 satVariable_t  v1, v2;
00738 
00739   n1 = *(int *)x;
00740   n2 = *(int *)y;
00741   n1 >>= 2;
00742   n2 >>= 2;
00743   i1 = SATisInverted(n1);
00744   n1 = SATnormalNode(n1);
00745   i2 = SATisInverted(n2);
00746   n2 = SATnormalNode(n2);
00747   v1 = SatCm->variableArray[SATnodeID(n1)];
00748   v2 = SatCm->variableArray[SATnodeID(n2)];
00749 
00750   if(v1.scores[i1] == v2.scores[i2]) {
00751     return(n1 > n2);
00752   }
00753   return(v1.scores[i1] < v2.scores[i2]);
00754 }