VIS

src/sat/satUtil.c

Go to the documentation of this file.
00001 
00019 #include "satInt.h"
00020 
00021 static char rcsid[] UNUSED = "$Id: satUtil.c,v 1.37 2009/04/11 18:26:37 fabio Exp $";
00022 
00023 /*---------------------------------------------------------------------------*/
00024 /* Constant declarations                                                     */
00025 /*---------------------------------------------------------------------------*/
00026 
00029 /*---------------------------------------------------------------------------*/
00030 /* Static function prototypes                                                */
00031 /*---------------------------------------------------------------------------*/
00032 
00033 static int NodeIndexCompare(const void *x, const void *y);
00034 
00038 /*---------------------------------------------------------------------------*/
00039 /* Definition of exported functions                                          */
00040 /*---------------------------------------------------------------------------*/
00041 
00042 
00054 long
00055 sat_AddConflictClause(
00056         satManager_t *cm,
00057         satArray_t *clauseArray,
00058         int objectFlag)
00059 {
00060 satStatistics_t *stats;
00061 satLiteralDB_t *literals;
00062 satVariable_t *var;
00063 long v, c;
00064 int inverted;
00065 long *last;
00066 long *space;
00067 int i, size;
00068 int maxLevel, maxIndex;
00069 int value, level;
00070 int otherWLIndex;
00071 
00072   literals = cm->literals;
00073 
00074   while(literals->last + clauseArray->num + 2 >= literals->end) {
00075     if(!sat_EnlargeLiteralDB(cm)) {
00076       fprintf(cm->stdErr, "%s ERROR : Cannot alloc memory for LiteralDB\n",
00077               cm->comment);
00078       exit(0);
00079     }
00080   }
00081 
00082   c = 0;
00083   if(cm->unusedAigQueue)
00084     c = sat_Dequeue(cm->unusedAigQueue);
00085   if(c == 0)
00086     c = sat_CreateNode(cm, 2, 2);
00087 
00088 
00089   last = literals->last;
00090   *(last) = (-c);
00091   last++;
00092 
00096   (cm->nodesArray[c+satFirstLit]) = (long)last;
00097   SATnumLits(c) = clauseArray->num;
00098   SATflags(c) |= IsCNFMask;
00099   SATsetInUse(c);
00100   SATnumConflict(c) = 0;
00101 
00102   size = clauseArray->num;
00103   space = clauseArray->space;
00104   for(i=0; i<size; i++, space++) {
00105     v = *space;
00106     inverted = !SATisInverted(v);
00107     v = SATnormalNode(v);
00108 
00109     *(last) = ((v^inverted) << 2);
00110     last++;
00111 
00112     var = SATgetVariable(v);
00113 
00114     if(inverted){
00115       (var->litsCount[0])++;
00116       (var->conflictLits[0])++;
00117     }
00118     else        {
00119       (var->litsCount[1])++;
00120       (var->conflictLits[1])++;
00121     }
00122   }
00123   *(last) = (-c);
00124   last++;
00125 
00126   literals->last = last;
00127 
00128   maxLevel = -1;
00129   maxIndex = -1;
00130   otherWLIndex = -1;
00131   space = clauseArray->space;
00132   for(i=0; i<size; i++, space++) {
00133     v = *space;
00134     inverted = SATisInverted(v);
00135     v = SATnormalNode(v);
00136     value = SATvalue(v);
00137     if(value == 2) {
00138       sat_AddWL(cm, c, i, 1);
00139       otherWLIndex = i;
00140       break;
00141     }
00142     else {
00143       level = SATlevel(v);
00144       if(level > maxLevel) {
00145         maxLevel = level;
00146         maxIndex = i;
00147       }
00148     }
00149   }
00150   if(i >= size) {
00151     sat_AddWL(cm, c, maxIndex, 1);
00152     otherWLIndex = maxIndex;
00153   }
00154 
00155   maxLevel = -1;
00156   maxIndex = -1;
00157   space = clauseArray->space+size-1;
00158   for(i=size-1; i>=0; i--, space--) {
00159     v = *space;
00160     inverted = SATisInverted(v);
00161     v = SATnormalNode(v);
00162     value = SATvalue(v);
00163     if(i != otherWLIndex) {
00164       if(value == 2) {
00165         sat_AddWL(cm, c, i, -1);
00166         break;
00167       }
00168       else {
00169         level = SATlevel(v);
00170         if(level > maxLevel) {
00171           maxLevel = level;
00172           maxIndex = i;
00173         }
00174       }
00175     }
00176   }
00177   if(i < 0)
00178     sat_AddWL(cm, c, maxIndex, -1);
00179 
00180 
00181   SATflags(c) |= IsConflictMask;
00182 
00183   stats = cm->each;
00184   stats->nConflictCl++;
00185   stats->nConflictLit += clauseArray->num;
00186   if(objectFlag) {
00187     stats->nObjConflictCl++;
00188     stats->nObjConflictLit += clauseArray->num;
00189     SATflags(c) |= ObjMask;
00190   }
00191   else {
00192     stats->nNonobjConflictCl++;
00193     stats->nNonobjConflictLit += clauseArray->num;
00194     SATflags(c) |= NonobjMask;
00195   }
00196 
00197 
00198   return(c);
00199 }
00200 
00212 long
00213 sat_AddConflictClauseNoScoreUpdate(
00214         satManager_t *cm,
00215         satArray_t *clauseArray,
00216         int objectFlag)
00217 {
00218 satStatistics_t *stats;
00219 satLiteralDB_t *literals;
00220 satVariable_t *var;
00221 long v, c;
00222 int inverted;
00223 long *last;
00224 long *space;
00225 int i, size;
00226 int maxLevel, maxIndex;
00227 int value, level;
00228 int otherWLIndex;
00229 
00230   literals = cm->literals;
00231 
00232   while(literals->last + clauseArray->num + 2 >= literals->end) {
00233     if(!sat_EnlargeLiteralDB(cm)) {
00234       fprintf(cm->stdErr, "%s ERROR : Cannot alloc memory for LiteralDB\n",
00235               cm->comment);
00236       exit(0);
00237     }
00238   }
00239 
00240   c = 0;
00241   if(cm->unusedAigQueue)
00242     c = sat_Dequeue(cm->unusedAigQueue);
00243   if(c == 0)
00244     c = sat_CreateNode(cm, 2, 2);
00245 
00246 
00247   last = literals->last;
00248   *(last) = (-c);
00249   last++;
00250 
00254   (cm->nodesArray[c+satFirstLit]) = (long)last;
00255   SATnumLits(c) = clauseArray->num;
00256   SATflags(c) |= IsCNFMask;
00257   SATsetInUse(c);
00258   SATnumConflict(c) = 0;
00259 
00260   size = clauseArray->num;
00261   space = clauseArray->space;
00262   for(i=0; i<size; i++, space++) {
00263     v = *space;
00264     inverted = !SATisInverted(v);
00265     v = SATnormalNode(v);
00266 
00267     *(last) = ((v^inverted) << 2);
00268     last++;
00269 
00270     var = SATgetVariable(v);
00271 
00272     if(inverted){
00273       (var->litsCount[0])++;
00274       (var->conflictLits[0])++;
00275     }
00276     else        {
00277       (var->litsCount[1])++;
00278       (var->conflictLits[1])++;
00279     }
00280   }
00281   *(last) = (-c);
00282   last++;
00283 
00284   literals->last = last;
00285 
00286   maxLevel = -1;
00287   maxIndex = -1;
00288   otherWLIndex = -1;
00289   space = clauseArray->space;
00290   for(i=0; i<size; i++, space++) {
00291     v = *space;
00292     inverted = SATisInverted(v);
00293     v = SATnormalNode(v);
00294     value = SATvalue(v);
00295     if(value == 2) {
00296       sat_AddWL(cm, c, i, 1);
00297       otherWLIndex = i;
00298       break;
00299     }
00300     else {
00301       level = SATlevel(v);
00302       if(level > maxLevel) {
00303         maxLevel = level;
00304         maxIndex = i;
00305       }
00306     }
00307   }
00308   if(i >= size) {
00309     sat_AddWL(cm, c, maxIndex, 1);
00310     otherWLIndex = maxIndex;
00311   }
00312 
00313   maxLevel = -1;
00314   maxIndex = -1;
00315   space = clauseArray->space+size-1;
00316   for(i=size-1; i>=0; i--, space--) {
00317     v = *space;
00318     inverted = SATisInverted(v);
00319     v = SATnormalNode(v);
00320     value = SATvalue(v);
00321     if(i != otherWLIndex) {
00322       if(value == 2) {
00323         sat_AddWL(cm, c, i, -1);
00324         break;
00325       }
00326       else {
00327         level = SATlevel(v);
00328         if(level > maxLevel) {
00329           maxLevel = level;
00330           maxIndex = i;
00331         }
00332       }
00333     }
00334   }
00335   if(i < 0)
00336     sat_AddWL(cm, c, maxIndex, -1);
00337 
00338 
00339   SATflags(c) |= IsConflictMask;
00340 
00341   stats = cm->each;
00342   stats->nConflictCl++;
00343   stats->nConflictLit += clauseArray->num;
00344   if(objectFlag) {
00345     stats->nObjConflictCl++;
00346     stats->nObjConflictLit += clauseArray->num;
00347     SATflags(c) |= ObjMask;
00348   }
00349   else {
00350     stats->nNonobjConflictCl++;
00351     stats->nNonobjConflictLit += clauseArray->num;
00352     SATflags(c) |= NonobjMask;
00353   }
00354 
00355 
00356   return(c);
00357 }
00369 long
00370 sat_AddUnitConflictClause(
00371         satManager_t *cm,
00372         satArray_t *clauseArray,
00373         int objectFlag)
00374 {
00375 satLiteralDB_t *literals;
00376 satStatistics_t *stats;
00377 long c, v;
00378 int inverted;
00379 long *last, *space;
00380 int i, size;
00381 
00382   literals = cm->literals;
00383 
00384   while(literals->last + clauseArray->num + 2 >= literals->end) {
00385     if(!sat_EnlargeLiteralDB(cm)) {
00386       fprintf(cm->stdErr, "%s ERROR : Cannot alloc memory for LiteralDB\n",
00387               cm->comment);
00388       exit(0);
00389     }
00390   }
00391 
00392   c = 0;
00393   if(cm->unusedAigQueue)
00394     c = sat_Dequeue(cm->unusedAigQueue);
00395   if(c == 0)
00396     c = sat_CreateNode(cm, 2, 2);
00397 
00398 
00399   last = literals->last;
00400   *(last) = (-c);
00401   last++;
00402 
00406   (cm->nodesArray[c+satFirstLit]) = (long)last;
00407   SATnumLits(c) = clauseArray->num;
00408   SATflags(c) |= IsCNFMask;
00409   SATsetInUse(c);
00410   SATnumConflict(c) = 0;
00411 
00412   size = clauseArray->num;
00413   space = clauseArray->space;
00414   for(i=0; i<size; i++, space++) {
00415     v = *space;
00416     inverted = !SATisInverted(v);
00417     v = SATnormalNode(v);
00418 
00419     *(last) = ((v^inverted) << 2);
00420     last++;
00421   }
00422   *(last) = (-c);
00423   last++;
00424 
00425   literals->last = last;
00426 
00427   SATflags(c) |= IsConflictMask;
00428   stats = cm->each;
00429   stats->nConflictCl++;
00430   stats->nConflictLit += clauseArray->num;
00431   if(objectFlag) {
00432     stats->nObjConflictCl++;
00433     stats->nObjConflictLit += clauseArray->num;
00434     SATflags(c) |= ObjMask;
00435   }
00436   else {
00437     stats->nNonobjConflictCl++;
00438     stats->nNonobjConflictLit += clauseArray->num;
00439     SATflags(c) |= NonobjMask;
00440   }
00441 
00442   return(c);
00443 }
00455 long
00456 sat_AddUnitBlockingClause(
00457         satManager_t *cm,
00458         satArray_t *clauseArray)
00459 {
00460 satLiteralDB_t *literals;
00461 satStatistics_t *stats;
00462 long c, v;
00463 int inverted;
00464 long *last, *space;
00465 int i, size;
00466 
00467   literals = cm->literals;
00468   stats = cm->each;
00469 
00470   while(literals->last + clauseArray->num + 2 >= literals->end) {
00471     if(!sat_EnlargeLiteralDB(cm)) {
00472       fprintf(cm->stdErr, "%s ERROR : Cannot alloc memory for LiteralDB\n",
00473               cm->comment);
00474       exit(0);
00475     }
00476   }
00477 
00478   c = 0;
00479   if(cm->unusedAigQueue)
00480     c = sat_Dequeue(cm->unusedAigQueue);
00481   if(c == 0)
00482     c = sat_CreateNode(cm, 2, 2);
00483 
00484 
00485   last = literals->last;
00486   *(last) = (-c);
00487   last++;
00488 
00492   (cm->nodesArray[c+satFirstLit]) = (long)last;
00493   SATnumLits(c) = clauseArray->num;
00494   SATflags(c) |= IsCNFMask;
00495   SATsetInUse(c);
00496   SATnumConflict(c) = 0;
00497 
00498   size = clauseArray->num;
00499   space = clauseArray->space;
00500   for(i=0; i<size; i++, space++) {
00501     v = *space;
00502     inverted = !SATisInverted(v);
00503     v = SATnormalNode(v);
00504 
00505     *(last) = ((v^inverted) << 2);
00506     last++;
00507   }
00508   *(last) = (-c);
00509   last++;
00510 
00511   literals->last = last;
00512 
00513   SATflags(c) |= IsBlockingMask;
00514 
00515   stats = cm->each;
00516   stats->nBlockingCl++;
00517   stats->nBlockingLit += clauseArray->num;
00518   return(c);
00519 }
00520 
00521 
00533 long
00534 sat_AddUnitClause(
00535         satManager_t *cm,
00536         satArray_t *clauseArray)
00537 {
00538 satLiteralDB_t *literals;
00539 long c = 0, v;
00540 int inverted;
00541 long *last, *space;
00542 int i, size;
00543 
00544   literals = cm->literals;
00545 
00546   while(literals->last + clauseArray->num + 2 >= literals->end) {
00547     if(!sat_EnlargeLiteralDB(cm)) {
00548       fprintf(cm->stdErr, "%s ERROR : Cannot alloc memory for LiteralDB\n",
00549               cm->comment);
00550       exit(0);
00551     }
00552   }
00553 
00554 
00555   c = 0;
00556   if(cm->unusedAigQueue)
00557     c = sat_Dequeue(cm->unusedAigQueue);
00558   if(c == 0)
00559     c = sat_CreateNode(cm, 2, 2);
00560 
00561 
00562   last = literals->last;
00563   *(last) = (-c);
00564   last++;
00565 
00569   (cm->nodesArray[c+satFirstLit]) = (long)last;
00570   SATnumLits(c) = clauseArray->num;
00571   SATflags(c) |= IsCNFMask;
00572   SATsetInUse(c);
00573   SATnumConflict(c) = 0;
00574 
00575   size = clauseArray->num;
00576   space = clauseArray->space;
00577   for(i=0; i<size; i++, space++) {
00578     v = *space;
00579     inverted = !SATisInverted(v);
00580     v = SATnormalNode(v);
00581 
00582     *(last) = ((v^inverted) << 2);
00583     last++;
00584   }
00585   *(last) = (-c);
00586   last++;
00587 
00588   literals->last = last;
00589 
00590   return(c);
00591 }
00592 
00604 long
00605 sat_AddClauseIncremental(
00606         satManager_t *cm,
00607         satArray_t *clauseArray,
00608         int objectFlag,
00609         int fromDistill)
00610 {
00611 satLiteralDB_t *literals;
00612 satStatistics_t *stats;
00613 satVariable_t *var;
00614 long c, v;
00615 int inverted;
00616 long *last, *space;
00617 int i, size;
00618 int maxLevel, maxIndex;
00619 int value, level;
00620 int otherWLIndex;
00621 
00622   literals = cm->literals;
00623   stats = cm->each;
00624 
00625   while(literals->last + clauseArray->num + 2 >= literals->end) {
00626     if(!sat_EnlargeLiteralDB(cm)) {
00627       fprintf(cm->stdErr, "%s ERROR : Cannot alloc memory for LiteralDB\n",
00628               cm->comment);
00629       exit(0);
00630     }
00631   }
00632 
00633   c = 0;
00634   if(cm->unusedAigQueue)
00635     c = sat_Dequeue(cm->unusedAigQueue);
00636   if(c == 0)
00637     c = sat_CreateNode(cm, 2, 2);
00638 
00639   last = literals->last;
00640   *(last) = (-c);
00641   last++;
00642 
00643 
00647   (cm->nodesArray[c+satFirstLit]) = (long)last;
00648   SATnumLits(c) = clauseArray->num;
00649   SATflags(c) |= IsCNFMask;
00650   SATsetInUse(c);
00651   SATnumConflict(c) = 0;
00652 
00653   size = clauseArray->num;
00654   space = clauseArray->space;
00655   for(i=0; i<size; i++, space++) {
00656     v = *space;
00657     inverted = !SATisInverted(v);
00658     v = SATnormalNode(v);
00659 
00660     *(last) = ((v^inverted) << 2);
00661     last++;
00662 
00663     var = SATgetVariable(v);
00664     if(inverted){
00665       if(fromDistill)
00666         (var->litsCount[0])++;
00667       (var->conflictLits[0])++;
00668     }
00669     else        {
00670       if(fromDistill)
00671         (var->litsCount[1])++;
00672       (var->conflictLits[1])++;
00673     }
00674   }
00675   *(last) = (-c);
00676   last++;
00677 
00678   literals->last = last;
00679 
00680 
00681   /* Bing: UNSAT core generation */
00682  if(clauseArray->num>1){
00683   maxLevel = -1;
00684   maxIndex = -1;
00685   otherWLIndex = -1;
00686   space = clauseArray->space;
00687   for(i=0; i<size; i++, space++) {
00688     v = *space;
00689     inverted = SATisInverted(v);
00690     v = SATnormalNode(v);
00691     value = SATvalue(v);
00692     if(value == 2) {
00693       sat_AddWL(cm, c, i, 1);
00694       otherWLIndex = i;
00695       break;
00696     }
00697     else {
00698       level = SATlevel(v);
00699       if(level > maxLevel) {
00700         maxLevel = level;
00701         maxIndex = i;
00702       }
00703     }
00704   }
00705   if(i >= size) {
00706     sat_AddWL(cm, c, maxIndex, 1);
00707     otherWLIndex = maxIndex;
00708   }
00709 
00710   maxLevel = -1;
00711   maxIndex = -1;
00712   space = clauseArray->space+size-1;
00713   for(i=size-1; i>=0; i--, space--) {
00714     v = *space;
00715     inverted = SATisInverted(v);
00716     v = SATnormalNode(v);
00717     value = SATvalue(v);
00718     if(i != otherWLIndex) {
00719       if(value == 2) {
00720         sat_AddWL(cm, c, i, -1);
00721         break;
00722       }
00723       else {
00724         level = SATlevel(v);
00725         if(level > maxLevel) {
00726           maxLevel = level;
00727           maxIndex = i;
00728         }
00729       }
00730     }
00731   }
00732   if(i < 0)
00733     sat_AddWL(cm, c, maxIndex, -1);
00734  }
00735 
00736   if(objectFlag)SATflags(c) |= ObjMask;
00737   else          SATflags(c) |= NonobjMask;
00738   /*SATflags(c) |= IsConflictMask;*/
00739   //Bing:change??
00740   if(!cm->option->coreGeneration)
00741     SATflags(c) |= IsConflictMask;
00742 
00743   if(objectFlag) {
00744     stats->nInitObjConflictCl++;
00745     stats->nInitObjConflictLit += clauseArray->num;
00746     stats->nObjConflictCl++;
00747     stats->nObjConflictLit += clauseArray->num;
00748   }
00749   else {
00750     stats->nInitNonobjConflictCl++;
00751     stats->nInitNonobjConflictLit += clauseArray->num;
00752     stats->nObjConflictCl++;
00753     stats->nObjConflictLit += clauseArray->num;
00754   }
00755   stats->nConflictCl++;
00756   stats->nConflictLit += clauseArray->num;
00757 
00758   return(c);
00759 }
00760 
00772 long
00773 sat_AddClause(
00774         satManager_t *cm,
00775         satArray_t *clauseArray)
00776 {
00777 satLiteralDB_t *literals;
00778 long c, v;
00779 int inverted;
00780 long *last, *space;
00781 int i, size;
00782 int maxLevel, maxIndex;
00783 int value, level;
00784 int otherWLIndex;
00785 
00786   literals = cm->literals;
00787 
00788   while(literals->last + clauseArray->num + 2 >= literals->end) {
00789     if(!sat_EnlargeLiteralDB(cm)) {
00790       fprintf(cm->stdErr, "%s ERROR : Cannot alloc memory for LiteralDB\n",
00791               cm->comment);
00792       exit(0);
00793     }
00794   }
00795   c = 0;
00796   if(cm->unusedAigQueue)
00797     c = sat_Dequeue(cm->unusedAigQueue);
00798   if(c == 0)
00799     c = sat_CreateNode(cm, 2, 2);
00800 
00801   last = literals->last;
00802   *(last) = (-c);
00803   last++;
00804 
00808   (cm->nodesArray[c+satFirstLit]) = (long)last;
00809   SATnumLits(c) = clauseArray->num;
00810   SATflags(c) |= IsCNFMask;
00811   SATsetInUse(c);
00812   SATnumConflict(c) = 0;
00813 
00814   size = clauseArray->num;
00815   space = clauseArray->space;
00816   for(i=0; i<size; i++, space++) {
00817     v = *space;
00818     inverted = !SATisInverted(v);
00819     v = SATnormalNode(v);
00820 
00821     *(last) = ((v^inverted) << 2);
00822     last++;
00823   }
00824   *(last) = (-c);
00825   last++;
00826 
00827   literals->last = last;
00828 
00829   maxLevel = -1;
00830   maxIndex = -1;
00831   otherWLIndex = -1;
00832   space = clauseArray->space;
00833   for(i=0; i<size; i++, space++) {
00834     v = *space;
00835     inverted = SATisInverted(v);
00836     v = SATnormalNode(v);
00837     value = SATvalue(v);
00838     if(value == 2) {
00839       sat_AddWL(cm, c, i, 1);
00840       otherWLIndex = i;
00841       break;
00842     }
00843     else {
00844       level = SATlevel(v);
00845       if(level > maxLevel) {
00846         maxLevel = level;
00847         maxIndex = i;
00848       }
00849     }
00850   }
00851   if(i >= size) {
00852     sat_AddWL(cm, c, maxIndex, 1);
00853     otherWLIndex = maxIndex;
00854   }
00855 
00856   maxLevel = -1;
00857   maxIndex = -1;
00858   space = clauseArray->space+size-1;
00859   for(i=size-1; i>=0; i--, space--) {
00860     v = *space;
00861     inverted = SATisInverted(v);
00862     v = SATnormalNode(v);
00863     value = SATvalue(v);
00864     if(i != otherWLIndex) {
00865       if(value == 2) {
00866         sat_AddWL(cm, c, i, -1);
00867         break;
00868       }
00869       else {
00870         level = SATlevel(v);
00871         if(level > maxLevel) {
00872           maxLevel = level;
00873           maxIndex = i;
00874         }
00875       }
00876     }
00877   }
00878   if(i < 0)
00879     sat_AddWL(cm, c, maxIndex, -1);
00880 
00881 
00882   return(c);
00883 }
00884 
00896 long
00897 sat_AddBlockingClause(
00898         satManager_t *cm,
00899         satArray_t *clauseArray)
00900 {
00901 satLiteralDB_t *literals;
00902 satStatistics_t *stats;
00903 long c, v;
00904 int inverted;
00905 long *last, *space;
00906 int i, size;
00907 int maxLevel, maxIndex;
00908 int value, level;
00909 int otherWLIndex;
00910 
00911   literals = cm->literals;
00912   stats = cm->each;
00913 
00914   while(literals->last + clauseArray->num + 2 >= literals->end) {
00915     if(!sat_EnlargeLiteralDB(cm)) {
00916       fprintf(cm->stdErr, "%s ERROR : Cannot alloc memory for LiteralDB\n",
00917               cm->comment);
00918       exit(0);
00919     }
00920   }
00921 
00922   if(clauseArray->num == 1)
00923     return(sat_AddUnitBlockingClause(cm, clauseArray));
00924 
00925   c = 0;
00926   if(cm->unusedAigQueue)
00927     c = sat_Dequeue(cm->unusedAigQueue);
00928   if(c == 0)
00929     c = sat_CreateNode(cm, 2, 2);
00930 
00931   last = literals->last;
00932   *(last) = (-c);
00933   last++;
00934 
00938   (cm->nodesArray[c+satFirstLit]) = (long)last;
00939   SATnumLits(c) = clauseArray->num;
00940   SATflags(c) |= IsCNFMask;
00941   SATsetInUse(c);
00942   SATnumConflict(c) = 0;
00943 
00944   size = clauseArray->num;
00945   space = clauseArray->space;
00946   for(i=0; i<size; i++, space++) {
00947     v = *space;
00948     inverted = !SATisInverted(v);
00949     v = SATnormalNode(v);
00950 
00951     *(last) = ((v^inverted) << 2);
00952     last++;
00953   }
00954   *(last) = (-c);
00955   last++;
00956 
00957   literals->last = last;
00958 
00959   maxLevel = -1;
00960   maxIndex = -1;
00961   otherWLIndex = -1;
00962   space = clauseArray->space;
00963   for(i=0; i<size; i++, space++) {
00964     v = *space;
00965     inverted = SATisInverted(v);
00966     v = SATnormalNode(v);
00967     value = SATvalue(v);
00968     if(value == 2) {
00969       sat_AddWL(cm, c, i, 1);
00970       otherWLIndex = i;
00971       break;
00972     }
00973     else {
00974       level = SATlevel(v);
00975       if(level > maxLevel) {
00976         maxLevel = level;
00977         maxIndex = i;
00978       }
00979     }
00980   }
00981   if(i >= size) {
00982     sat_AddWL(cm, c, maxIndex, 1);
00983     otherWLIndex = maxIndex;
00984   }
00985 
00986   maxLevel = -1;
00987   maxIndex = -1;
00988   space = clauseArray->space+size-1;
00989   for(i=size-1; i>=0; i--, space--) {
00990     v = *space;
00991     inverted = SATisInverted(v);
00992     v = SATnormalNode(v);
00993     value = SATvalue(v);
00994     if(i != otherWLIndex) {
00995       if(value == 2) {
00996         sat_AddWL(cm, c, i, -1);
00997         break;
00998       }
00999       else {
01000         level = SATlevel(v);
01001         if(level > maxLevel) {
01002           maxLevel = level;
01003           maxIndex = i;
01004         }
01005       }
01006     }
01007   }
01008   if(i < 0)
01009     sat_AddWL(cm, c, maxIndex, -1);
01010 
01011   SATflags(c) |= IsBlockingMask;
01012 
01013   stats = cm->each;
01014   stats->nBlockingCl++;
01015   stats->nBlockingLit += clauseArray->num;
01016 
01017   return(c);
01018 }
01019 
01020 
01032 void
01033 sat_AddWL(
01034         satManager_t *cm,
01035         long c,
01036         int index,
01037         int dir)
01038 {
01039 long *plit, v;
01040 int inverted;
01041 satVariable_t *var;
01042 
01043   plit = (long*)SATfirstLit(c) + index;
01044   v = SATgetNode(*plit);
01045   inverted = !SATisInverted(v);
01046   v = SATnormalNode(v);
01047   var = SATgetVariable(v);
01048 
01049   if(var->wl[inverted] == 0)
01050     var->wl[inverted] = sat_ArrayAlloc(4);
01051   sat_ArrayInsert(var->wl[inverted], (long)plit);
01052   SATsetWL(plit, dir);
01053 }
01054 
01055 
01067 satArray_t *
01068 sat_ArrayAlloc(long number)
01069 {
01070 satArray_t *array;
01071 
01072   array = ALLOC(satArray_t, 1);
01073   if (array) {
01074     array->num = 0;
01075     array->size = number;
01076     array->space = ALLOC(long, number);
01077     if (array->space) {
01078       return array;
01079     }
01080   }
01081   //Bing: To avoid segmentation fault
01082   if(array==0 || (number>0&&array->space==0)){
01083     printf("can't alloc mem, exit\n");
01084     exit(0);
01085   }
01086   return 0;
01087 }
01088 
01100 satArray_t *
01101 sat_ArrayDuplicate(satArray_t *old)
01102 {
01103 satArray_t *array;
01104 
01105   array = (satArray_t *)malloc(sizeof(satArray_t));
01106   if (array) {
01107     array->num = old->num;
01108     array->size = old->num;
01109     array->space = (long *)malloc(sizeof(long) * old->num);
01110     memcpy(array->space, old->space, sizeof(long)*old->num);
01111     if (array->space) {
01112       return array;
01113     }
01114   }
01115   return 0;
01116 }
01117 
01129 void
01130 sat_ArrayInsert(satArray_t *array, long datum)
01131 {
01132   if(array->num < array->size) {
01133     array->space[array->num++] = datum;
01134   }
01135   else {
01136     array->size <<= 1;
01137     array->space = REALLOC(long, array->space, array->size);
01138     if(array->space == 0) {
01139       fprintf(stdout, "ERROR : Can't allocate memory in sat_ArrayInsert\n");
01140       exit(0);
01141     }
01142     array->space[array->num++] = datum;
01143   }
01144 }
01145 
01157 void
01158 sat_ArrayFree(satArray_t *array)
01159 {
01160   free(array->space);
01161   free(array);
01162 }
01163 
01164 
01176 satQueue_t *
01177 sat_CreateQueue( long MaxElements )
01178 {
01179 satQueue_t *Q;
01180 
01181   Q = ALLOC(satQueue_t, 1);
01182   if( Q == NULL )
01183     fprintf(stderr, "Out of space!!!\n" );
01184 
01185   Q->array = ALLOC(long, MaxElements );
01186   if( Q->array == NULL )
01187     fprintf(stderr, "Out of space!!!\n" );
01188   Q->max = MaxElements;
01189   Q->size = 0;
01190   Q->front = 1;
01191   Q->rear = 0;
01192   return Q;
01193 }
01194 
01206 void
01207 sat_FreeQueue( satQueue_t *Q )
01208 {
01209   if( Q != NULL ) {
01210     free( Q->array );
01211     free( Q );
01212   }
01213 }
01214 
01215 
01227 void
01228 sat_Enqueue(satQueue_t *Q, long v)
01229 {
01230   long *arr, *oarr;
01231   long rear;
01232 
01233   if(Q->size < Q->max) {
01234     Q->size++;
01235     rear = Q->rear;
01236     rear = (++(rear) == Q->max) ? 0 : rear;
01237     Q->array[rear] = v;
01238     Q->rear = rear;
01239   }
01240   else {
01241     arr = ALLOC(long, Q->size * 2 );
01242     if(arr == NULL )
01243        fprintf(stderr, "Out of space!!!\n" );
01244     oarr = Q->array;
01245     if(Q->front > Q->rear) {
01246        memcpy(&(arr[1]), &(oarr[Q->front]),
01247                sizeof(long) *(Q->max-Q->front));
01248        memcpy(&(arr[Q->size-Q->front+1]), &(oarr[0]),
01249                sizeof(long) *(Q->rear+1));
01250     }
01251     else if(Q->front < Q->rear) {
01252        memcpy(&(arr[1]), &(oarr[Q->front]), sizeof(long) *(Q->size));
01253     }
01254     free(oarr);
01255     Q->array = arr;
01256     Q->front = 1;
01257     Q->rear = Q->size;
01258     Q->max *= 2;
01259 
01260     Q->size++;
01261     rear = Q->rear;
01262     rear = (++(rear) == Q->max) ? 0 : rear;
01263     Q->array[rear] = v;
01264     Q->rear = rear;
01265   }
01266 }
01267 
01268 
01280 long
01281 sat_Dequeue( satQueue_t * Q )
01282 {
01283   long front;
01284   long v;
01285 
01286   if(Q->size > 0) {
01287     Q->size--;
01288     front = Q->front;
01289     v = Q->array[front];
01290     Q->front = (++(front) == Q->max) ? 0 : front;
01291     return v;
01292   }
01293   else
01294     return(0);
01295 }
01296 
01297 
01309 satLevel_t *
01310 sat_AllocLevel(
01311         satManager_t *cm)
01312 {
01313 satStatistics_t *stats;
01314 satLevel_t *d;
01315 satArray_t *implied;
01316 int size;
01317 
01318   if(cm->decisionHeadSize == 0) {
01319     size = cm->currentDecision+2;
01320     cm->decisionHeadSize = size;
01321     cm->decisionHead = REALLOC(satLevel_t, cm->decisionHead, size);
01322     memset(cm->decisionHead, 0, sizeof(satLevel_t) * size);
01323   }
01324 
01325   if(cm->currentDecision+1 >= cm->decisionHeadSize) {
01326     size = cm->decisionHeadSize;
01327     cm->decisionHeadSize <<=1;
01328     cm->decisionHead = REALLOC(satLevel_t, cm->decisionHead,
01329                                cm->decisionHeadSize);
01330     memset(cm->decisionHead+size, 0, sizeof(satLevel_t) * size);
01331   }
01332 
01333   cm->currentDecision++;
01334   d = &(cm->decisionHead[cm->currentDecision]);
01335   implied = d->implied;
01336   memset(d, 0, sizeof(satLevel_t));
01337   d->implied = implied;
01338   if(d->implied == 0){
01339     d->implied = sat_ArrayAlloc(64);
01340     //Bing: avoid seg fault
01341     if(d->implied == 0){
01342       printf("out of mem, exit\n");
01343       exit(0);
01344     }
01345   }
01346 
01347   d->level = cm->currentDecision;
01348   d->conflict = 0;
01349 
01350   stats = cm->each;
01351   if(stats->maxDecisionLevel < d->level)
01352     stats->maxDecisionLevel = d->level;
01353 
01354   return(d);
01355 
01356 }
01357 
01369 void
01370 sat_CleanLevel(
01371         satLevel_t *d)
01372 {
01373   if(d->implied)
01374     d->implied->num = 0;
01375   if(d->satisfied)
01376     d->satisfied->num = 0;
01377   d->currentVarPos = 0;
01378 }
01379 
01391 void
01392 sat_ClauseDeletion(satManager_t *cm)
01393 {
01394 satLiteralDB_t *literals;
01395 satOption_t *option;
01396 long v, *plit, nv, lit;
01397 int size, n0, n1x, deleteFlag;
01398 int unrelevance;
01399 int inverted, i;
01400 int value;
01401 double ratio;
01402 
01409   option = cm->option;
01410   if(option->clauseDeletionHeuristic == 0)      return;
01411 
01412   literals = cm->literals;
01413   for(v=cm->beginConflict; v<cm->nodesArraySize; v+=satNodeSize) {
01414     if(!(SATflags(v) & IsCNFMask))      continue;
01415     if(SATreadInUse(v) == 0)            continue;
01416 
01417     if(option->incPreserveNonobjective && (SATflags(v) & NonobjMask))
01418       continue;
01419 
01420     size = SATnumLits(v);
01421     if(size < option->minLitsLimit)     continue;
01422 
01423     plit = (long*)SATfirstLit(v);
01424 
01425     unrelevance = option->unrelevance;
01426     if(option->clauseDeletionHeuristic & SIMPLE_LATEST_DELETION) {
01427       ratio = (double)(plit-literals->initialSize)/
01428           (double)(literals->last-literals->initialSize);
01429       if(ratio > 0.8)   unrelevance <<= 3;
01430     }
01431     if(!(option->clauseDeletionHeuristic & MAX_UNRELEVANCE_DELETION)) {
01432       unrelevance = MAXINT;
01433     }
01434 
01435     n0 = n1x = 0;
01436     deleteFlag = 0;
01437     for(i=0; i<size; i++, plit++) {
01438       lit = *plit;
01439       nv = SATgetNode(lit);
01440       inverted = SATisInverted(nv);
01441       nv = SATnormalNode(nv);
01442       value = SATvalue(nv) ^ inverted;
01443 
01444       if(value == 0)    n0++;
01445       else if(value == 1) {
01446         n1x++;
01447         if(SATlevel(nv) == 0 && cm->option->coreGeneration == 0)
01448           deleteFlag = 1;
01449       }
01450       else      n1x++;
01451 
01452       if(deleteFlag) {
01453         sat_DeleteClause(cm, v);
01454         sat_Enqueue(cm->unusedAigQueue, v);
01455         break;
01456       }
01457       if((size > option->maxLitsLimit) && (n1x > 1)) {
01458         sat_DeleteClause(cm, v);
01459         sat_Enqueue(cm->unusedAigQueue, v);
01460         break;
01461       }
01462       if(n1x > unrelevance) {
01463         sat_DeleteClause(cm, v);
01464         sat_Enqueue(cm->unusedAigQueue, v);
01465         break;
01466       }
01467     }
01468 
01469   }
01470 }
01471 
01483 void
01484 sat_DeleteClause(
01485         satManager_t *cm,
01486         long v)
01487 {
01488 satStatistics_t *stats;
01489 int size, i;
01490 long nv, *plit;
01491 
01492   stats = cm->each;
01493   size = SATnumLits(v);
01494   stats->nDeletedCl++;
01495   stats->nDeletedLit += size;
01496 
01498   SATflags(v) = 0;
01499   SATflags(v) |= IsCNFMask;
01500 
01501   for(i=0, plit=(long*)SATfirstLit(v); i<size; i++, plit++) {
01502     nv = SATgetNode(*plit);
01503     *plit = 0;
01504   }
01505 }
01506 
01518 void
01519 sat_CompactClauses(satManager_t *cm)
01520 {
01521 satLiteralDB_t *literals;
01522 long *plit, v, lit;
01523 int i, size, index;
01524 int inverted;
01525 satVariable_t *var;
01526 
01527   literals = cm->literals;
01528   size = literals->last - literals->begin;
01529 
01530   plit = literals->begin;
01531   index = literals->initialSize-literals->begin;
01532   for(i=literals->initialSize-literals->begin; i<size; i++) {
01533     if(i < 2) {
01534       plit[index] = plit[i];
01535       index++;
01536       continue;
01537     }
01538 
01539     if(plit[i-1] == 0 && plit[i] < 0)   continue;
01540     else if(plit[i-1] == 0 && plit[i] == 0)     continue;
01541     else if(plit[i-1] < 0 && plit[i] == 0)      continue;
01542     else if(plit[i-1] < 0 && plit[i] < 0 && plit[i+1] == 0)     continue;
01543     else {
01544       plit[index] = plit[i];
01545       index++;
01546     }
01547   }
01548 
01549   literals->last = literals->begin + index;
01550   for(v=satNodeSize; v<cm->beginConflict; v+=satNodeSize) {
01551     if(SATflags(v) & IsCNFMask) continue;
01552     var = SATgetVariable(v);
01553     if(var->wl[0]) var->wl[0]->num = 0;
01554     if(var->wl[1]) var->wl[1]->num = 0;
01555   }
01556 
01557   size = literals->last - literals->begin;
01558   plit = literals->begin;
01559   for(i=0; i<size; i++) {
01560     lit = plit[i];
01561     if(lit > 0 && SATisWL(lit)) {
01562       v = SATgetNode(lit);
01563       inverted = !(SATisInverted(v));
01564       v = SATnormalNode(v);
01565       var = SATgetVariable(v);
01566       if(var->wl[inverted] == 0)
01567         var->wl[inverted] = sat_ArrayAlloc(4);
01568       sat_ArrayInsert(var->wl[inverted], (long)(&(plit[i])));
01569     }
01570 
01571     if(lit <= 0) {
01572       v = -lit;
01576       (cm->nodesArray[v+satFirstLit]) = (long)(&(plit[i]) - SATnumLits(v));
01577     }
01578   }
01579 
01580   plit = literals->last - 1;
01581   cm->currentTopConflict = plit;
01582   cm->currentTopConflictCount = 0;
01583 
01584 }
01585 
01597 int
01598 sat_EnlargeLiteralDB(satManager_t *cm)
01599 {
01600 satLiteralDB_t *literals;
01601 int nLiveConflictCl, nLiveConflictLit;
01602 double ratio, growRatio;
01603 double memUsage;
01604 long *oldBegin, *oldEnd;
01605 long newSize, oldSize;
01606 int offset, index, size;
01607 int i, j, nodesSize;
01608 long tv;
01609 int arrSize;
01610 satVariable_t *var;
01611 satArray_t *wl;
01612 satStatistics_t *stats;
01613 satOption_t *option;
01614 
01615 
01616   literals = cm->literals;
01617   option = cm->option;
01618   stats = cm->each;
01619 
01620   size = literals->last - literals->begin;
01621   nLiveConflictCl = cm->initNumClauses + stats->nConflictCl + stats->nBlockingCl - stats->nDeletedCl;
01622   nLiveConflictLit = cm->initNumLiterals + stats->nBlockingLit +
01623                      stats->nConflictLit - stats->nDeletedLit ;
01624   ratio = (double)(nLiveConflictLit + (nLiveConflictCl << 1)) /
01625           (double)(size);
01626 
01627   if(ratio < 0.8) {
01628     sat_CompactClauses(cm);
01629     return(1);
01630   }
01631 
01632   memUsage = (double)sat_MemUsage(cm);
01633   growRatio = 1.0;
01634   if(memUsage < (double)option->memoryLimit/4.0)        growRatio = 2.0;
01635   else if(memUsage < (double)option->memoryLimit/2.0)   growRatio = 1.5;
01636   else if(memUsage < (double)option->memoryLimit*0.8)   growRatio = 1.2;
01637 
01638   if(growRatio < 1.5) {
01639     if(ratio < 0.9) {
01640       sat_CompactClauses(cm);
01641       return(1);
01642     }
01643   }
01644 
01645   oldBegin = literals->begin;
01646   oldEnd = literals->end;
01647   oldSize = literals->last - literals->begin;
01648   newSize = oldSize * (int)growRatio;
01649 
01650   literals->begin = REALLOC(long, oldBegin, newSize);
01651   literals->last = literals->begin + oldSize;
01652   literals->end = literals->begin + newSize;
01653 
01654   offset = literals->begin - oldBegin;
01655   nodesSize = cm->nodesArraySize;
01656   for(i=satNodeSize; i<nodesSize; i+= satNodeSize) {
01657     tv = i;
01658     if(SATflags(tv) & IsCNFMask) {
01659       if(SATreadInUse(tv))
01660         (cm->nodesArray[tv+satFirstLit]) = (long)((long*)(SATfirstLit(tv)) + offset);
01664     }
01665     else if(SATflags(tv) & IsBDDMask) {
01666       (cm->nodesArray[tv+satFirstLit]) = (long)((long*)(SATfirstLit(tv)) + offset);
01670     }
01671     else {
01672       var = SATgetVariable(tv);
01673       wl = var->wl[0];
01674       if(wl) {
01675         arrSize = wl->num;
01676         for(j=0, index=0; j<arrSize; j++) {
01677           if(wl->space[j] == 0) continue;
01678           wl->space[j] = (long)(((long*)(wl->space[j])) + offset);
01679         }
01680       }
01681       wl = var->wl[1];
01682       if(wl) {
01683         arrSize = wl->num;
01684         for(j=0, index=0; j<arrSize; j++) {
01685           if(wl->space[j] == 0) continue;
01686           wl->space[j] = (long)(((long*)(wl->space[j])) + offset);
01687         }
01688       }
01689     }
01690   }
01691   literals->initialSize = literals->initialSize + offset;
01692   cm->currentTopConflict += offset;
01693 
01694   return(1);
01695 }
01696 
01708 void
01709 sat_AllocLiteralsDB(satManager_t *cm)
01710 {
01711 satLiteralDB_t *literals;
01712 int size;
01713 
01714   literals = cm->literals;
01715   if(literals)  return;
01716 
01717   literals = ALLOC(satLiteralDB_t, 1);
01718   cm->literals = literals;
01719 
01720   size = 1024 * 1024;
01721   literals->begin = ALLOC(long, size);
01722   *(literals->begin) = 0;
01723   literals->last = literals->begin + 1;
01724   literals->end = literals->begin + size;
01726   literals->initialSize = literals->last;
01727 
01728 }
01729 
01730 
01742 void
01743 sat_FreeLiteralsDB(satLiteralDB_t *literals)
01744 {
01745 
01746   if(literals == 0)     return;
01747   free(literals->begin);
01748   literals->begin = 0;
01749   free(literals);
01750 }
01751 
01763 void
01764 sat_CleanDatabase(satManager_t *cm)
01765 {
01766 long v, i;
01767 
01768   for(i=satNodeSize; i<cm->nodesArraySize; i+=satNodeSize) {
01769     v = i;
01770     SATvalue(v) = 2;
01771     SATflags(v) &= PreserveMask;
01772   }
01773 }
01774 
01786 void
01787 sat_CompactFanout(satManager_t *cm)
01788 {
01789 int bufSize, bufIndex;
01790 long *buf, *fan;
01791 long i, v, cur;
01792 int j, size, tsize;
01793 
01794   bufSize = 1024;
01795   bufIndex = 0;
01796   buf = ALLOC(long, bufSize);
01797   for(i=satNodeSize; i<cm->nodesArraySize; i+=satNodeSize) {
01798     v = i;
01799 
01800     if(!(SATflags(v) & CoiMask))
01801       continue;
01802 
01803     size = SATnFanout(v);
01804     if(size >= bufSize) {
01805       bufSize <<= 1;
01806       if(size >= bufSize)
01807         bufSize = size + 1;
01808       buf = REALLOC(long, buf, bufSize);
01809     }
01810 
01811     bufIndex = 0;
01812     for(j=0, fan = SATfanout(v); j<size; j++) {
01813       cur = fan[j];
01814       cur >>= 1;
01815       cur = SATnormalNode(cur);
01816       if(!(SATflags(cur) & CoiMask))
01817         continue;
01818       buf[bufIndex++] = fan[j];
01819     }
01820 
01821     if(bufIndex > 0) {
01822       tsize = bufIndex;
01823       for(j=0, fan=SATfanout(v); j<size; j++) {
01824         cur = fan[j];
01825         cur >>= 1;
01826         cur = SATnormalNode(cur);
01827         if(!(SATflags(cur) & CoiMask))  {
01828           buf[bufIndex++] = fan[j];
01829           continue;
01830         }
01831       }
01832       buf[bufIndex] = 0;
01833       memcpy(fan, buf, sizeof(long)*(size+1));
01834       SATnFanout(v) = tsize;
01835     }
01836     else {
01837       SATnFanout(v) = 0;
01838     }
01839   }
01840 
01841   free(buf);
01842 
01843   for(i=satNodeSize; i<cm->nodesArraySize; i+=satNodeSize) {
01844     v = i;
01845     if(!(SATflags(v) & CoiMask))
01846       continue;
01847     fan = SATfanout(v);
01848     size = SATnFanout(v);
01849     qsort(fan, size, sizeof(long), NodeIndexCompare);
01850   }
01851 }
01852 
01853 
01854 
01866 void
01867 sat_RestoreFanout(satManager_t *cm)
01868 {
01869 long i, v;
01870 
01871   for(i=satNodeSize; i<cm->nodesArraySize; i+=satNodeSize) {
01872     v = i;
01873     if((SATflags(v) & IsCNFMask))
01874       continue;
01875     SATnFanout(v) = sat_GetFanoutSize(cm, v);
01876   }
01877 }
01878 
01890 int
01891 sat_GetFanoutSize(
01892         satManager_t *cm,
01893         long v)
01894 {
01895 long *fan;
01896 int i;
01897 
01898   fan = SATfanout(v);
01899   if(fan == 0)  return(0);
01900 
01901   for(i=0; fan[i]!=0; i++);
01902   return(i);
01903 }
01904 
01916 void
01917 sat_MarkTransitiveFaninForArray(
01918         satManager_t *cm,
01919         satArray_t *arr,
01920         unsigned int mask)
01921 {
01922 long v;
01923 int i, size;
01924 
01925   if(arr == 0)  return;
01926   size = arr->num;
01927 
01928   for(i=0; i<size; i++) {
01929     v = arr->space[i];
01930     sat_MarkTransitiveFaninForNode(cm, v, mask);
01931   }
01932 }
01933 
01945 void
01946 sat_MarkTransitiveFaninForNode(
01947         satManager_t *cm,
01948         long v,
01949         unsigned int mask)
01950 {
01951   if(v == 2)    return;
01952 
01953   v = SATnormalNode(v);
01954 
01955   if(SATflags(v) & mask)        return;
01956 
01957   SATflags(v) |= mask;
01958 
01959   sat_MarkTransitiveFaninForNode(cm, SATleftChild(v), mask);
01960   sat_MarkTransitiveFaninForNode(cm, SATrightChild(v), mask);
01961 }
01962 
01974 void
01975 sat_UnmarkTransitiveFaninForArray(
01976         satManager_t *cm,
01977         satArray_t *arr,
01978         unsigned int mask,
01979         unsigned int resetMask)
01980 {
01981 long v;
01982 int i, size;
01983 
01984   size = arr->num;
01985 
01986   for(i=0; i<size; i++) {
01987     v = arr->space[i];
01988     sat_UnmarkTransitiveFaninForNode(cm, v, mask, resetMask);
01989   }
01990 }
01991 
02003 void
02004 sat_UnmarkTransitiveFaninForNode(
02005         satManager_t *cm,
02006         long v,
02007         unsigned int mask,
02008         unsigned int resetMask)
02009 {
02010   if(v == 2)    return;
02011 
02012   v = SATnormalNode(v);
02013 
02014   if(!(SATflags(v) & mask))     return;
02015 
02016   SATflags(v) &= resetMask;
02017   sat_UnmarkTransitiveFaninForNode(cm, SATleftChild(v), mask, resetMask);
02018   sat_UnmarkTransitiveFaninForNode(cm, SATrightChild(v), mask, resetMask);
02019 }
02020 
02021 
02034 void
02035 sat_SetConeOfInfluence(satManager_t *cm)
02036 {
02037   sat_MarkTransitiveFaninForArray(cm, cm->assertion, CoiMask);
02038   sat_MarkTransitiveFaninForArray(cm, cm->auxObj, CoiMask);
02039   sat_MarkTransitiveFaninForArray(cm, cm->obj, CoiMask);
02040   //Bing:
02041   sat_MarkTransitiveFaninForArray(cm, cm->assertArray, CoiMask);
02042 }
02043 
02044 
02056 satManager_t *
02057 sat_InitManager(satInterface_t *interface)
02058 {
02059 satManager_t *cm;
02060 
02061   cm = ALLOC(satManager_t, 1);
02062   memset(cm, 0, sizeof(satManager_t));
02063 
02064   if(interface) {
02065     cm->total = interface->total;
02066     cm->nonobjUnitLitArray = interface->nonobjUnitLitArray;
02067     cm->savedConflictClauses = interface->savedConflictClauses;
02068     cm->trieArray = interface->trieArray;
02069     cm->objUnitLitArray = sat_ArrayAlloc(8);
02070   }
02071   else {
02072     cm->total = sat_InitStatistics();
02073     cm->objUnitLitArray = sat_ArrayAlloc(8);
02074     cm->nonobjUnitLitArray = sat_ArrayAlloc(8);
02075   }
02076 
02077   return(cm);
02078 }
02079 
02091 void
02092 sat_FreeManager(satManager_t *cm)
02093 {
02094 satVariable_t *var;
02095 satLevel_t *d;
02096 int i;
02097 
02098   if(cm->option)        sat_FreeOption(cm->option);
02099   if(cm->total)         sat_FreeStatistics(cm->total);
02100   if(cm->each)          sat_FreeStatistics(cm->each);
02101 
02102   if(cm->literals)      sat_FreeLiteralsDB(cm->literals);
02103 
02104   if(cm->decisionHead) {
02105     for(i=0; i<cm->decisionHeadSize; i++) {
02106       d = &(cm->decisionHead[i]);
02107       if(d->implied)
02108         sat_ArrayFree(d->implied);
02109       if(d->satisfied)
02110         sat_ArrayFree(d->satisfied);
02111     }
02112     free(cm->decisionHead);
02113     cm->decisionHead = 0;
02114     cm->decisionHeadSize = 0;
02115   }
02116 
02117   if(cm->queue)         sat_FreeQueue(cm->queue);
02118   if(cm->BDDQueue)      sat_FreeQueue(cm->BDDQueue);
02119   if(cm->unusedAigQueue)sat_FreeQueue(cm->unusedAigQueue);
02120   cm->queue = 0;
02121   cm->BDDQueue = 0;
02122   cm->unusedAigQueue = 0;
02123 
02124   if(cm->auxObj)               sat_ArrayFree(cm->auxObj);
02125   if(cm->obj)                  sat_ArrayFree(cm->obj);
02126   if(cm->unitLits)             sat_ArrayFree(cm->unitLits);
02127   if(cm->pureLits)             sat_ArrayFree(cm->pureLits);
02128   if(cm->assertion)            sat_ArrayFree(cm->assertion);
02129   if(cm->auxArray)             sat_ArrayFree(cm->auxArray);
02130   if(cm->nonobjUnitLitArray)   sat_ArrayFree(cm->nonobjUnitLitArray);
02131   if(cm->objUnitLitArray)      sat_ArrayFree(cm->objUnitLitArray);
02132   if(cm->orderedVariableArray) sat_ArrayFree(cm->orderedVariableArray);
02133   if(cm->clauseIndexInCore)    sat_ArrayFree(cm->clauseIndexInCore);
02134   cm->auxObj = 0;
02135   cm->obj = 0;
02136   cm->unitLits = 0;
02137   cm->pureLits = 0;
02138   cm->assertion = 0;
02139   cm->auxArray = 0;
02140   cm->nonobjUnitLitArray = 0;
02141   cm->objUnitLitArray = 0;
02142   cm->orderedVariableArray = 0;
02143 
02144   if(cm->variableArray) {
02145     for(i=0; i<=cm->initNumVariables; i++) {
02146       var = &(cm->variableArray[i]);
02147       if(var->wl[0]) {
02148         sat_ArrayFree(var->wl[0]);
02149         var->wl[0] = 0;
02150       }
02151       if(var->wl[1]) {
02152         sat_ArrayFree(var->wl[1]);
02153         var->wl[1] = 0;
02154       }
02155     }
02156     free(cm->variableArray);
02157     cm->variableArray = 0;
02158   }
02159 
02160 
02161   if(cm->comment)       free(cm->comment);
02162 
02163   if(cm->nodesArray)    free(cm->nodesArray);
02164   free(cm);
02165 }
02166 
02178 void
02179 sat_FreeOption(satOption_t * option)
02180 {
02181   if(option)
02182     free(option);
02183 }
02184 
02196 void
02197 sat_FreeStatistics(satStatistics_t * stats)
02198 {
02199   if(stats)
02200     free(stats);
02201 }
02202 
02203 
02215 satOption_t *
02216 sat_InitOption()
02217 {
02218 satOption_t *option;
02219 
02220   option = ALLOC(satOption_t, 1);
02221   memset(option, 0, sizeof(satOption_t));
02222 
02223   option->decisionHeuristic |= LATEST_CONFLICT_DECISION;
02227   option->decisionAgeInterval = 0xff;
02228   option->decisionAgeRestart = 1;
02229   option->minConflictForDecision = 50;
02230   option->maxConflictForDecision = 10000;
02231   option->skipSatisfiedClauseForDecision = 0;
02232 
02233 
02238   option->clauseDeletionHeuristic |= LATEST_ACTIVITY_DELETION;
02239   option->clauseDeletionInterval = 2500;
02240   option->nextClauseDeletion = option->clauseDeletionInterval*5;
02241   option->unrelevance = 20;
02242   option->minLitsLimit = 20;
02243   option->maxLitsLimit = 1000;
02244 
02245   option->latestUnrelevance = 45;
02246   option->obsoleteUnrelevance = 20;//6
02247   option->latestUsage = 100;
02248   option->obsoleteUsage = 2;
02249   option->latestRate = 16;
02250 
02251   option->incNumObjLitsLimit = 20; 
02252   option->incNumNonobjLitsLimit = 50;
02253 
02254   option->incPreserveNonobjective = 1;
02255   option->minimizeConflictClause = 1;
02256 
02257 
02258   option->BDDMonolithic = 0;
02259   option->BDDDPLL = 0;
02260   option->maxLimitOfVariablesForMonolithicBDD = 2000;
02261   option->maxLimitOfClausesForMonolithicBDD = 20000;
02262   option->maxLimitOfCutSizeForMonolithicBDD = 2000;
02263 
02264   option->maxLimitOfVariablesForBDDDPLL = 200;
02265   option->maxLimitOfClausesForBDDDPLL = 2000;
02266   option->maxLimitOfCutSizeForBDDDPLL = 500;
02267 
02268   option->maxLimitOfVariablesForBDD = 50;
02269 
02270   option->memoryLimit = 1024 * 1024 * 1024;
02271 
02272   return(option);
02273 }
02274 
02286 void
02287 sat_ReportStatistics(
02288         satManager_t *cm,
02289         satStatistics_t *stats)
02290 {
02291 satOption_t *option;
02292 
02293   option = cm->option;
02294   fprintf(cm->stdOut, "%s Number of decisions %d\n",
02295               cm->comment, stats->nDecisions);
02296   if(option->decisionHeuristic & DVH_DECISION) {
02297     fprintf(cm->stdOut, "%s Number of DVH decisions %d\n",
02298               cm->comment, stats->nDVHDecisions);
02299   }
02300   if(option->decisionHeuristic & LATEST_CONFLICT_DECISION) {
02301     fprintf(cm->stdOut, "%s Number of latest conflict decisions %d\n",
02302               cm->comment, stats->nLatestConflictDecisions);
02303   }
02304   fprintf(cm->stdOut, "%s Number of backtracks %d\n",
02305               cm->comment, stats->nBacktracks);
02306 
02307   fprintf(cm->stdOut, "%s Number of CNF implications %d\n",
02308               cm->comment, stats->nCNFImplications);
02309   fprintf(cm->stdOut, "%s Number of Aig implications %d\n",
02310               cm->comment, stats->nAigImplications);
02311   fprintf(cm->stdOut, "%s Number of BDD implications %d\n",
02312               cm->comment, stats->nBDDImplications);
02313 
02314   fprintf(cm->stdOut, "%s Number of unit conflict clauses %d\n",
02315               cm->comment, stats->nUnitConflictCl);
02316   fprintf(cm->stdOut, "%s Number of conflict clauses %d\n",
02317               cm->comment, stats->nConflictCl);
02318   fprintf(cm->stdOut, "%s Number of conflict literals %d\n",
02319               cm->comment, stats->nConflictLit);
02320   fprintf(cm->stdOut, "%s Number of deleted clauses %d\n",
02321               cm->comment, stats->nDeletedCl);
02322   fprintf(cm->stdOut, "%s Number of deleted literals %d\n",
02323               cm->comment, stats->nDeletedLit);
02324 
02325   if(option->incTraceObjective + option->incDistill) {
02326     fprintf(cm->stdOut, "%s Number of init object conflict clauses %d\n",
02327               cm->comment, stats->nInitObjConflictCl);
02328     fprintf(cm->stdOut, "%s Number of init object conflict literals %d\n",
02329               cm->comment, stats->nInitObjConflictLit);
02330     fprintf(cm->stdOut, "%s Number of init non-object conflict clauses %d\n",
02331               cm->comment, stats->nInitNonobjConflictCl);
02332     fprintf(cm->stdOut, "%s Number of init non-object conflict literals %d\n",
02333               cm->comment, stats->nInitNonobjConflictLit);
02334     fprintf(cm->stdOut, "%s Number of object conflict clauses %d\n",
02335               cm->comment, stats->nObjConflictCl);
02336     fprintf(cm->stdOut, "%s Number of object conflict literals %d\n",
02337               cm->comment, stats->nObjConflictLit);
02338     fprintf(cm->stdOut, "%s Number of non-object conflict clauses %d\n",
02339               cm->comment, stats->nNonobjConflictCl);
02340     fprintf(cm->stdOut, "%s Number of non-object conflict literals %d\n",
02341               cm->comment, stats->nNonobjConflictLit);
02342   }
02343   if(option->incDistill) {
02344     fprintf(cm->stdOut, "%s Number of distill object conflict clauses %d\n",
02345               cm->comment, stats->nDistillObjConflictCl);
02346     fprintf(cm->stdOut, "%s Number of distill object conflict literals %d\n",
02347               cm->comment, stats->nDistillObjConflictLit);
02348     fprintf(cm->stdOut, "%s Number of distill non-object conflict clauses %d\n",
02349               cm->comment, stats->nDistillNonobjConflictCl);
02350     fprintf(cm->stdOut, "%s Number of distill non-object conflict literals %d\n",
02351               cm->comment, stats->nDistillNonobjConflictLit);
02352   }
02353   if(option->allSatMode) {
02354     fprintf(cm->stdOut, "%s Number of blocking clauses %d\n",
02355               cm->comment, stats->nBlockingCl);
02356     fprintf(cm->stdOut, "%s Number of blocking literals %d\n",
02357               cm->comment, stats->nBlockingLit);
02358   }
02359 
02360   fprintf(cm->stdOut, "%s Maximum decision level %d\n",
02361               cm->comment, stats->maxDecisionLevel);
02362   fprintf(cm->stdOut, "%s Number of low score decisions %d\n",
02363               cm->comment, stats->nLowScoreDecisions);
02364   fprintf(cm->stdOut, "%s Total nonchronological backtracks %d\n",
02365               cm->comment, stats->nNonchonologicalBacktracks);
02366   fprintf(cm->stdOut, "%s Total run time %10g\n", cm->comment, stats->satTime);
02367   fflush(cm->stdOut);
02368 
02369 }
02370 
02382 satStatistics_t *
02383 sat_InitStatistics(void)
02384 {
02385 satStatistics_t *stats;
02386 
02387   stats = ALLOC(satStatistics_t, 1);
02388   memset(stats, 0, sizeof(satStatistics_t));
02389 
02390   return(stats);
02391 }
02392 
02393 
02405 void
02406 sat_SetIncrementalOption(satOption_t *option, int incFlag)
02407 {
02408   if(incFlag == 0) return;
02409 
02410   if(incFlag == 1)  { /* TraceObjective */
02411     option->incTraceObjective = 1;
02412   }
02413   else if(incFlag == 2)  { /* Distill */
02414     option->incDistill = 1;
02415   }
02416   else if(incFlag == 3)  { /* TraceObjective & Distill */
02417     option->incTraceObjective = 1;
02418     option->incDistill = 1;
02419   }
02420 
02421 }
02422 
02434 void
02435 sat_RestoreBlockingClauses(satManager_t *cm)
02436 {
02437 long *space, *start;
02438 long c, v;
02439 int i;
02440 satArray_t *reached;
02441 satArray_t *clause;
02442 satArray_t *unitLits;
02443 
02444   reached = cm->reached;
02445   if(reached == 0)
02446     return;
02447 
02448   unitLits = cm->unitLits;
02449   if(unitLits == 0)
02450     unitLits = cm->unitLits = sat_ArrayAlloc(16);
02451 
02452   clause = sat_ArrayAlloc(50);
02453 
02454   for(i=0, space=reached->space; i<reached->num; i++, space++){
02455     if(*space <= 0) {
02456       space++;
02457       i++;
02458       if(i>=reached->num)
02459         break;
02460       start = space;
02461       clause->num = 0;
02462       while(*space > 0) {
02463         v = (*space);
02464         sat_ArrayInsert(clause, SATnot(v));
02465         i++;
02466         space++;
02467       }
02468 
02469       c = sat_AddBlockingClause(cm, clause);
02470 
02476       if(clause->num == 1)
02477         sat_ArrayInsert(unitLits, (v));
02478       i--;
02479       space--;
02480     }
02481   }
02482   sat_ArrayFree(clause);
02483 }
02484 
02496 void
02497 sat_RestoreFrontierClauses(satManager_t *cm)
02498 {
02499 long *space, *start;
02500 long c, v;
02501 int i;
02502 satArray_t *frontier;
02503 satArray_t *clause;
02504 satArray_t *unitLits;
02505 
02506   frontier = cm->frontier;
02507   cm->frontierNodesEnd = cm->nodesArraySize;
02508   if(frontier == 0)
02509     return;
02510 
02511   unitLits = cm->unitLits;
02512   if(unitLits == 0)
02513     unitLits = cm->unitLits = sat_ArrayAlloc(16);
02514 
02515   clause = sat_ArrayAlloc(50);
02516 
02517   for(i=0, space=frontier->space; i<frontier->num; i++, space++){
02518     if(*space <= 0) {
02519       space++;
02520       i++;
02521       if(i>=frontier->num)
02522         break;
02523       start = space;
02524       clause->num = 0;
02525       while(*space > 0) {
02526         v = (*space);
02527         sat_ArrayInsert(clause, SATnot(v));
02528         i++;
02529         space++;
02530       }
02531 
02532       c = sat_AddClause(cm, clause);
02533 
02538       cm->initNumClauses++;
02539       cm->initNumLiterals += clause->num;
02540       if(clause->num == 1)
02541         sat_ArrayInsert(unitLits, (v));
02542 
02543       i--;
02544       space--;
02545     }
02546   }
02547   sat_ArrayFree(clause);
02548   cm->frontierNodesEnd = cm->nodesArraySize;
02549 }
02550 
02562 void
02563 sat_RestoreClauses(satManager_t *cm, satArray_t *cnfArray)
02564 {
02565 long *space, *start;
02566 long c, v;
02567 int i;
02568 satArray_t *clause;
02569 satArray_t *unitLits;
02570 
02571 
02572   unitLits = cm->unitLits;
02573   if(unitLits == 0)
02574     unitLits = cm->unitLits = sat_ArrayAlloc(16);
02575 
02576   clause = sat_ArrayAlloc(50);
02577 
02578   for(i=0, space=cnfArray->space; i<cnfArray->num; i++, space++){
02579     if(*space <= 0) {
02580       space++;
02581       i++;
02582       if(i>=cnfArray->num)
02583         break;
02584       start = space;
02585       clause->num = 0;
02586       while(*space > 0) {
02587         v = (*space);
02588         sat_ArrayInsert(clause, SATnot(v));
02589         i++;
02590         space++;
02591       }
02592 
02593       if(clause->num == 1) {
02594         sat_ArrayInsert(unitLits, (v));
02595       }
02596       else {
02597         c = sat_AddClause(cm, clause);
02598       }
02599 
02600       cm->initNumClauses++;
02601       cm->initNumLiterals += clause->num;
02602 
02603       i--;
02604       space--;
02605     }
02606   }
02607   sat_ArrayFree(clause);
02608 }
02609 
02621 void
02622 sat_CollectBlockingClause(satManager_t *cm)
02623 {
02624 satArray_t *reached, *frontier;
02625 long i, v, tv, *plit;
02626 int j, size;
02627 int inverted, num;
02628 int nReachs, nFrontiers;
02629 
02630   if(cm->reached == 0)  cm->reached = sat_ArrayAlloc(1024);
02631   if(cm->frontier == 0) cm->frontier = sat_ArrayAlloc(1024);
02632 
02633   frontier = cm->frontier;
02634   reached = cm->reached;
02635 
02636   frontier->num = 0;
02637   reached->num = 0;
02638   sat_ArrayInsert(frontier, 0);
02639   sat_ArrayInsert(reached, 0);
02640   nReachs = nFrontiers = 0;
02641 
02642   for(i=cm->beginConflict; i<cm->nodesArraySize; i+=satNodeSize) {
02643     if(!(SATflags(i) & IsBlockingMask))
02644       continue;
02645 
02646     if(SATreadInUse(i) == 0)            continue;
02647 
02648     if((SATflags(i) & IsFrontierMask)) {
02649 
02654       plit = (long*)SATfirstLit(i);
02655       size = SATnumLits(i);
02656       num = frontier->num;
02657       for(j=0; j<size; j++, plit++) {
02658         v = SATgetNode(*plit);
02659         inverted = SATisInverted(v);
02660         tv = SATnormalNode(v);
02661         sat_ArrayInsert(frontier, v);
02662       }
02663       nFrontiers++;
02664       sat_ArrayInsert(frontier, 0);
02665     }
02666 
02667     plit = (long*)SATfirstLit(i);
02668     size = SATnumLits(i);
02669     for(j=0; j<size; j++, plit++) {
02670       v = SATgetNode(*plit);
02671       sat_ArrayInsert(reached, v);
02672     }
02673     sat_ArrayInsert(reached, 0);
02674     nReachs ++;
02675   }
02676 
02677 
02678 
02679   cm->frontier = frontier;
02680   cm->reached = reached;
02681   fprintf(stdout, "NOTICE : %d frontier are collected\n", nFrontiers);
02682   fprintf(stdout, "NOTICE : %d blocking clauses are collected\n", nReachs);
02683 }
02684 
02685 
02697 void
02698 sat_FreeInterface(satInterface_t *interface)
02699 {
02700   if(interface == 0)    return;
02701 
02702   if(interface->total)
02703     free(interface->total);
02704   if(interface->nonobjUnitLitArray)
02705     sat_ArrayFree(interface->nonobjUnitLitArray);
02706   if(interface->objUnitLitArray)
02707     sat_ArrayFree(interface->objUnitLitArray);
02708   if(interface->savedConflictClauses)
02709     free(interface->savedConflictClauses);
02710   free(interface);
02711 }
02712 
02726 long
02727 sat_CreateNode(
02728         satManager_t *cm,
02729         long left,
02730         long right)
02731 {
02732 long newNode;
02733 
02734   newNode = cm->nodesArraySize;
02735   //Bing: to deal with the case that cm->maxNodesArraySize is not multiple of
02736   // satNodeSize
02737   cm->nodesArraySize += satNodeSize;
02738 
02739   if(cm->nodesArraySize >= cm->maxNodesArraySize) {
02740     cm->maxNodesArraySize = 2* cm->maxNodesArraySize;
02741     cm->nodesArray = REALLOC(long, cm->nodesArray, cm->maxNodesArraySize);
02742   }
02743   cm->nodesArray[newNode + satRight] = right;
02744   cm->nodesArray[newNode + satLeft] = left;
02745 
02746   //cm->nodesArraySize += satNodeSize;
02747 
02748   SATflags(newNode) = 0;
02749   SATnext(newNode) = 2;
02750   SATnFanout(newNode) = 0;
02754   (cm->nodesArray[newNode+satFanout]) = 0;
02755   //Bing:
02756   SATvalue(newNode) = 2;
02757 
02758   return(newNode);
02759 }
02760 
02772 int
02773 sat_MemUsage(satManager_t *cm)
02774 {
02775 satLiteralDB_t *literals;
02776 satStatistics_t *stats;
02777 int aigSize, cnfSize, watchedSize;
02778 
02779   literals = cm->literals;
02780   stats = cm->each;
02781   aigSize = sizeof(int) * cm->maxNodesArraySize;
02782   cnfSize = sizeof(int) * (literals->end - literals->begin);
02783   watchedSize = sizeof(int) * 2 *
02784                  (stats->nConflictCl - stats->nDeletedCl);
02785   return(aigSize + cnfSize + watchedSize);
02786 }
02787 
02788 
02789 
02801 long
02802 sat_GetCanonical(satManager_t *cm, long v)
02803 {
02804 long nv;
02805 int inverted;
02806 
02807   if(v == 2)    return(2);
02808 
02809   while(!(SATflags(SATnormalNode(v))) & CanonicalBitMask) {
02810     inverted = SATisInverted(v);
02811     v = SATnormalNode(v);
02812     nv = SATcanonical(v);
02813     if(inverted)
02814       nv = SATnot(nv);
02815     v = nv;
02816   }
02817   return(v);
02818 }
02819 
02820 
02832 void
02833 sat_CombineStatistics(satManager_t *cm)
02834 {
02835     /* CONSIDER ... */
02836 }
02837 
02850 int
02851 sat_GetNumberOfInitialClauses(satManager_t *cm)
02852 {
02853   return(cm->initNumClauses);
02854 }
02855 
02868 int
02869 sat_GetNumberOfInitialVariables(satManager_t *cm)
02870 {
02871   return(cm->initNumVariables);
02872 }
02873 
02885 satArray_t *
02886 sat_ReadForcedAssignment(
02887         char *filename)
02888 {
02889 FILE *fin;
02890 char line[102400], word[1024];
02891 char *lp;
02892 satArray_t *arr;
02893 long v;
02894 
02895   if(!(fin = fopen(filename, "r"))) {
02896     fprintf(stdout, "ERROR : Can't open file %s\n", filename);
02897     return(0);
02898   }
02899 
02900   arr = sat_ArrayAlloc(64);
02901   while(fgets(line, 102400, fin)) {
02902     lp = sat_RemoveSpace(line);
02903     if(lp[0] == '\n')   continue;
02904     while(1) {
02905       lp = sat_RemoveSpace(lp);
02906       lp = sat_CopyWord(lp, word);
02907       if(strlen(word)) {
02908         v = atoi(word);
02909         v *= satNodeSize;
02910         if(v < 0)       v = SATnot(-v);
02911         sat_ArrayInsert(arr, v);
02912       }
02913       else {
02914         break;
02915       }
02916     }
02917   }
02918   fclose(fin);
02919 
02920   return(arr);
02921 }
02922 
02934 int
02935 sat_ApplyForcedAssigment(
02936         satManager_t *cm,
02937         satArray_t *arr,
02938         satLevel_t *d)
02939 {
02940 long v;
02941 int i, inverted, errorFlag;
02942 
02943   errorFlag = 0;
02944   for(i=0; i<arr->num; i++) {
02945     v = arr->space[i];
02946     inverted = SATisInverted(v);
02947     v = SATnormalNode(v);
02948 
02949     SATvalue(v) = !inverted;
02950     SATmakeImplied(v, d);
02951     sat_Enqueue(cm->queue, v);
02952     SATflags(v) |= InQueueMask;
02953     sat_ImplicationMain(cm, d);
02954     if(d->conflict) {
02955       fprintf(cm->stdOut,
02956               "%s WARNING : conflict happens at level %d while applying forced assignments\n", cm->comment, d->level);
02957       errorFlag = 1;
02958       break;
02959     }
02960   }
02961   if(errorFlag)
02962     return(SAT_UNSAT);
02963   else
02964     return(0);
02965 }
02966 
02978 void
02979 sat_ApplyForcedAssignmentMain(
02980         satManager_t *cm,
02981         satLevel_t *d)
02982 {
02983 satArray_t *forcedArr;
02984 int flag;
02985 
02986   forcedArr = cm->option->forcedAssignArr;
02987   flag = 0;
02988   if(forcedArr) {
02989     flag = sat_ApplyForcedAssigment(cm, forcedArr, d);
02990   }
02991 
02992   if(flag == SAT_UNSAT) {
02993     cm->status = SAT_UNSAT;
02994     return;
02995   }
02996 }
02997 
03009 void
03010 sat_PutAssignmentValueMain(
03011         satManager_t *cm,
03012         satLevel_t *d,
03013         satArray_t *arr)
03014 {
03015 long v;
03016 int i;
03017 int inverted;
03018 
03019   if(arr == 0)  return;
03020 
03021   if(cm->variableArray == 0) {
03022     cm->variableArray = ALLOC(satVariable_t, cm->initNumVariables+1);
03023     memset(cm->variableArray, 0,
03024             sizeof(satVariable_t) * (cm->initNumVariables+1));
03025   }
03026 
03027   for(i=0; i<arr->num; i++) {
03028     v = arr->space[i];
03029     inverted = SATisInverted(v);
03030     v = SATnormalNode(v);
03031 
03032     SATvalue(v) = !inverted;
03033   }
03034 }
03035 
03047 void
03048 sat_ClauseDeletionLatestActivity(satManager_t *cm)
03049 {
03050 satLiteralDB_t *literals;
03051 satOption_t *option;
03052 long nv, v, *plit, *clit;
03053 long usage, totalConflictCl;
03054 long index, lit;
03055 
03056 int size, n0, n1x, deleteFlag;
03057 int unrelevance;
03058 int usedLimit;
03059 int inverted, i;
03060 int value;
03061 int nLatestCl;
03062 int nDeletedCl;
03063 double ratio;
03064 
03071   option = cm->option;
03072   if(option->clauseDeletionHeuristic == 0)      return;
03073 
03074   totalConflictCl = (cm->nodesArraySize - cm->beginConflict)/satNodeSize;
03075   nDeletedCl = cm->each->nDeletedCl;
03076   nLatestCl = totalConflictCl/option->latestRate;
03077   literals = cm->literals;
03078   index = 0;
03079   for(clit = literals->last-1; clit > literals->begin; clit--){
03080     if(*clit == 0)
03081       continue;
03082     if(index >= totalConflictCl)
03083       break;
03084     v = -(*clit);
03085 
03086     plit = (long*)SATfirstLit(v);
03087     clit = plit - 1;
03088     index++;
03089 
03090     if(nLatestCl > 0) {
03091       nLatestCl--;
03092       unrelevance = option->latestUnrelevance;
03093     }
03094     else {
03095       unrelevance = option->obsoleteUnrelevance;
03096     }
03097 
03098     if(!(SATflags(v) & IsConflictMask)) continue;
03099     if((SATflags(v) & IsFrontierMask))  continue;
03100 
03101     if(option->incPreserveNonobjective && (SATflags(v) & NonobjMask))
03102       continue;
03103 
03104     usage = SATconflictUsage(v);
03105     SATconflictUsage(v) = usage/2;
03106     size = SATnumLits(v);
03107 //    if(size < option->minLitsLimit)   continue;
03108     if(size < unrelevance)
03109       continue;
03110 
03111     usedLimit = option->obsoleteUsage +
03112         (option->latestUsage-option->obsoleteUsage)*index/totalConflictCl;
03113     if(usage > usedLimit)
03114       continue;
03115 
03116 
03117     n0 = n1x = 0;
03118     deleteFlag = 0;
03119     for(i=0; i<size; i++, plit++) {
03120       lit = *plit;
03121       nv = SATgetNode(lit);
03122       inverted = SATisInverted(nv);
03123       nv = SATnormalNode(nv);
03124       value = SATvalue(nv) ^ inverted;
03125 
03126       if(value == 0)    n0++;
03127       else if(value == 1) {
03128         n1x++;
03129         if(SATlevel(nv) == 0)   deleteFlag = 1;
03130       }
03131       else      n1x++;
03132 
03133       if(deleteFlag) {
03134         sat_DeleteClause(cm, v);
03135         sat_Enqueue(cm->unusedAigQueue, v);
03136         break;
03137       }
03138       if((size > option->maxLitsLimit) && (n1x > 1)) {
03139         sat_DeleteClause(cm, v);
03140         sat_Enqueue(cm->unusedAigQueue, v);
03141         break;
03142       }
03143       if(n1x > unrelevance) {
03144         sat_DeleteClause(cm, v);
03145         sat_Enqueue(cm->unusedAigQueue, v);
03146         break;
03147       }
03148     }
03149 
03150   }
03151 
03152   cm->each->nDeletedButUncompacted += cm->each->nDeletedCl - nDeletedCl;
03153   ratio = (double)cm->each->nDeletedButUncompacted/
03154           (double)(cm->each->nConflictCl-cm->each->nDeletedCl);
03155 
03156   if(ratio> 0.2) {
03157     sat_CompactClauses(cm);
03158     cm->each->nDeletedButUncompacted = 0;
03159   }
03160 
03161 }
03162 
03163 
03175 long
03176 sat_GetClauseFromLit(
03177         satManager_t *cm,
03178         long *lit)
03179 {
03180   while(*lit > 0) {
03181     lit++;
03182   }
03183   return(-(*lit));
03184 }
03196 static int
03197 NodeIndexCompare(const void *x, const void *y)
03198 {
03199 long n1, n2;
03200 
03201   n1 = *(long *)x;
03202   n2 = *(long *)y;
03203   return(n1 > n2);
03204 }