VIS

src/sat/satConflict.c

Go to the documentation of this file.
00001 
00020 #include "satInt.h"
00021 #include "puresatInt.h"
00022 
00023 static char rcsid[] UNUSED = "$Id: satConflict.c,v 1.31 2009/04/11 18:26:37 fabio Exp $";
00024 
00025 static  satManager_t *SATcm;
00026 
00027 /*---------------------------------------------------------------------------*/
00028 /* Constant declarations                                                     */
00029 /*---------------------------------------------------------------------------*/
00030 
00033 /*---------------------------------------------------------------------------*/
00034 /* Static function prototypes                                                */
00035 /*---------------------------------------------------------------------------*/
00036 
00037 static int levelCompare( const void * node1, const void * node2);
00038 
00042 /*---------------------------------------------------------------------------*/
00043 /* Definition of exported functions                                          */
00044 /*---------------------------------------------------------------------------*/
00045 
00046 
00059 int
00060 sat_ConflictAnalysis(
00061         satManager_t *cm,
00062         satLevel_t *d)
00063 {
00064 satStatistics_t *stats;
00065 satOption_t *option;
00066 satArray_t *clauseArray;
00067 int objectFlag;
00068 int bLevel;
00069 long fdaLit, conflicting;
00070 
00071 
00072   conflicting = d->conflict;
00073 
00074   if(d->level == 0) {
00076     if(cm->option->coreGeneration)
00077       sat_ConflictAnalysisForCoreGen(cm, d);
00078     cm->currentDecision--;
00079     return (-1);
00080   }
00081 
00082   stats = cm->each;
00083   option = cm->option;
00084 
00085 
00086   stats->nBacktracks++;
00087 
00088   clauseArray = cm->auxArray;
00089 
00090   bLevel = 0;
00091   fdaLit = -1;
00092   clauseArray->num = 0;
00093 
00094   /*  Find Unique Implication Point */
00095 
00096   if(option->RT)
00097     sat_FindUIPWithRT(cm, clauseArray, d, &objectFlag, &bLevel, &fdaLit);
00098   else
00099     sat_FindUIP(cm, clauseArray, d, &objectFlag, &bLevel, &fdaLit);
00100   stats->nNonchonologicalBacktracks += (d->level - bLevel);
00101 
00102 
00103   if(clauseArray->num == 0) {
00104     sat_PrintImplicationGraph(cm, d);
00105     sat_PrintNode(cm, conflicting);
00106   }
00107 
00108   /* If we could find UIP then it is critical error...
00109   * at lease the decision node has to be detected as UIP.
00110   */
00111   if(fdaLit == -1) {
00112     fprintf(cm->stdOut, "%s ERROR : Illegal unit literal\n", cm->comment);
00113     fflush(cm->stdOut);
00114     sat_PrintNode(cm, conflicting);
00115     sat_PrintImplicationGraph(cm, d);
00116     sat_PrintDotForConflict(cm, d, conflicting, 0);
00117     exit(0);
00118   }
00119 
00120   if(bLevel && cm->lowestBacktrackLevel > bLevel)
00121     cm->lowestBacktrackLevel = bLevel;
00122 
00123   bLevel = sat_AddConflictClauseAndBacktrack(
00124           cm, clauseArray, d, fdaLit, bLevel, objectFlag, 0);
00125 
00126   return(bLevel);
00127 }
00128 
00141 int
00142 sat_ConflictAnalysisForLifting(
00143         satManager_t *cm,
00144         satLevel_t *d)
00145 {
00146 satStatistics_t *stats;
00147 satOption_t *option;
00148 satArray_t *clauseArray;
00149 int objectFlag;
00150 int bLevel;
00151 long fdaLit, conflicting;
00152 
00153 
00154   conflicting = d->conflict;
00155 
00156   if(d->level == 0) {
00157     cm->currentDecision--;
00158     return (-1);
00159   }
00160 
00161   stats = cm->each;
00162   option = cm->option;
00163 
00164 
00165   stats->nBacktracks++;
00166 
00167   clauseArray = cm->auxArray;
00168 
00169   bLevel = 0;
00170   fdaLit = -1;
00171   clauseArray->num = 0;
00172 
00173   /*  Find Unique Implication Point */
00174   sat_FindUIP(cm, clauseArray, d, &objectFlag, &bLevel, &fdaLit);
00175   stats->nNonchonologicalBacktracks += (d->level - bLevel);
00176 
00177 
00178   if(clauseArray->num == 0) {
00179     sat_PrintImplicationGraph(cm, d);
00180     sat_PrintNode(cm, conflicting);
00181   }
00182 
00183   /* If we could find UIP then it is critical error...
00184   * at lease the decision node has to be detected as UIP.
00185   */
00186   if(fdaLit == -1) {
00187     fprintf(cm->stdOut, "%s ERROR : Illegal unit literal\n", cm->comment);
00188     fflush(cm->stdOut);
00189     sat_PrintNode(cm, conflicting);
00190     sat_PrintImplicationGraph(cm, d);
00191     sat_PrintDotForConflict(cm, d, conflicting, 0);
00192     exit(0);
00193   }
00194 
00195   if(bLevel && cm->lowestBacktrackLevel > bLevel)
00196     cm->lowestBacktrackLevel = bLevel;
00197 
00198   bLevel = sat_AddConflictClauseAndBacktrackForLifting(
00199           cm, clauseArray, d, fdaLit, bLevel, objectFlag, 0);
00200 
00201   return(bLevel);
00202 }
00215 int
00216 sat_ConflictAnalysisWithBlockingClause(
00217         satManager_t *cm,
00218         satLevel_t *d)
00219 {
00220 satStatistics_t *stats;
00221 satOption_t *option;
00222 satArray_t *clauseArray;
00223 int objectFlag;
00224 int bLevel;
00225 long fdaLit, conflicting;
00226 
00227 
00228   conflicting = d->conflict;
00229 
00230   if(d->level == 0) {
00231     cm->currentDecision--;
00232     return (-1);
00233   }
00234 
00235   stats = cm->each;
00236   option = cm->option;
00237 
00238 
00239   stats->nBacktracks++;
00240 
00241   clauseArray = cm->auxArray;
00242 
00243   bLevel = 0;
00244   fdaLit = -1;
00245   clauseArray->num = 0;
00246 
00247   /*  Find Unique Implication Point */
00248   sat_FindUIP(cm, clauseArray, d, &objectFlag, &bLevel, &fdaLit);
00249   stats->nNonchonologicalBacktracks += (d->level - bLevel);
00250 
00251 
00252   if(clauseArray->num == 0) {
00253     sat_PrintImplicationGraph(cm, d);
00254     sat_PrintNode(cm, conflicting);
00255   }
00256 
00257   /* If we could find UIP then it is critical error...
00258   * at lease the decision node has to be detected as UIP.
00259   */
00260   if(fdaLit == -1) {
00261     fprintf(cm->stdOut, "%s ERROR : Illegal unit literal\n", cm->comment);
00262     fflush(cm->stdOut);
00263     sat_PrintNode(cm, conflicting);
00264     sat_PrintImplicationGraph(cm, d);
00265     sat_PrintDotForConflict(cm, d, conflicting, 0);
00266     exit(0);
00267   }
00268 
00269   if(bLevel && cm->lowestBacktrackLevel > bLevel)
00270     cm->lowestBacktrackLevel = bLevel;
00271 
00272   bLevel = sat_AddConflictClauseWithNoScoreAndBacktrack(
00273           cm, clauseArray, d, fdaLit, bLevel, objectFlag, 0);
00274 
00275   return(bLevel);
00276 }
00277 
00289 int
00290 sat_StrongConflictAnalysis(
00291         satManager_t *cm,
00292         satLevel_t *d)
00293 {
00294 satStatistics_t *stats;
00295 satOption_t *option;
00296 satArray_t *clauseArray;
00297 int objectFlag;
00298 int bLevel;
00299 long fdaLit, conflicting;
00300 
00301 
00302   conflicting = d->conflict;
00303 
00304   if(d->level == 0) {
00306     if(cm->option->coreGeneration)
00307       sat_ConflictAnalysisForCoreGen(cm, d);
00308     cm->currentDecision--;
00309     return (-1);
00310   }
00311 
00312   stats = cm->each;
00313   option = cm->option;
00314 
00315 
00316   stats->nBacktracks++;
00317 
00318   if(SATflags(conflicting) & IsCNFMask) {
00319     SATnumConflict(conflicting) += 1;
00320   }
00321 
00322   clauseArray = cm->auxArray;
00323 
00324   bLevel = 0;
00325   fdaLit = -1;
00326   clauseArray->num = 0;
00327 
00328   /*  Find Unique Implication Point */
00329   sat_FindUIPAndNonUIP(cm, clauseArray, d, &objectFlag, &bLevel, &fdaLit);
00330   stats->nNonchonologicalBacktracks += (d->level - bLevel);
00331 
00332 
00333   if(clauseArray->num == 0) {
00334     sat_PrintImplicationGraph(cm, d);
00335     sat_PrintNode(cm, conflicting);
00336   }
00337 
00338   /* If we could find UIP then it is critical error...
00339   * at lease the decision node has to be detected as UIP.
00340   */
00341   if(fdaLit == -1) {
00342     fprintf(cm->stdOut, "%s ERROR : Illegal unit literal\n", cm->comment);
00343     fflush(cm->stdOut);
00344     sat_PrintNode(cm, conflicting);
00345     sat_PrintImplicationGraph(cm, d);
00346     sat_PrintDotForConflict(cm, d, conflicting, 0);
00347     exit(0);
00348   }
00349 
00350   if(bLevel && cm->lowestBacktrackLevel > bLevel)
00351     cm->lowestBacktrackLevel = bLevel;
00352 
00353   bLevel = sat_AddConflictClauseAndBacktrack(
00354           cm, clauseArray, d, fdaLit, bLevel, objectFlag, 1);
00355 
00356   return(bLevel);
00357 }
00358 
00370 int
00371 sat_AddConflictClauseAndBacktrack(
00372         satManager_t *cm,
00373         satArray_t *clauseArray,
00374         satLevel_t *d,
00375         long fdaLit,
00376         int bLevel,
00377         int objectFlag,
00378         int strongFlag)
00379 {
00380 int inverted;
00381 long conflicting, learned;
00382 satOption_t *option;
00383 satStatistics_t *stats;
00384 satArray_t *nClauseArray;
00385 
00386  RTManager_t * rm = cm->rm;
00387 
00388   option = cm->option;
00389   stats = cm->each;
00390 
00391   inverted = SATisInverted(fdaLit);
00392   fdaLit = SATnormalNode(fdaLit);
00393 
00394   conflicting = d->conflict;
00395 
00396   if(option->verbose > 2) {
00397     if(option->verbose > 4)
00398       sat_PrintNode(cm, conflicting);
00399     fprintf(cm->stdOut, "conflict at %3d on %6ld  bLevel %d UnitLit ",
00400             d->level, conflicting, bLevel);
00401     sat_PrintNodeAlone(cm, fdaLit);
00402     fprintf(cm->stdOut, "\n");
00403   }
00404 
00405   d->conflict = 0;
00406 
00407   /* unit literal conflict clause */
00408   if(clauseArray->num == 1) {
00409     learned = sat_AddUnitConflictClause(cm, clauseArray, objectFlag);
00410     stats->nUnitConflictCl++;
00411     cm->currentTopConflict = cm->literals->last-1;
00412     cm->currentTopConflictCount = 0;
00413 
00414     sat_Backtrack(cm, 0);
00415 
00416     if(SATlevel(fdaLit) == 0) {
00417       if(cm->option->coreGeneration){
00418         if(cm->option->RT){
00419           st_insert(cm->anteTable,(char*)SATnormalNode(fdaLit),(char*)learned);
00420 
00421           st_insert(cm->RTreeTable, (char *)learned, (char *)rm->root);
00422           RT_oriClsIdx(rm->root) = learned;
00423         }
00424         else{
00425           st_insert(cm->anteTable,(char*)SATnormalNode(fdaLit),(char*)learned);
00426           st_insert(cm->dependenceTable, (char *)learned, (char *)cm->dependenceArray);
00427         }
00428       }
00429       cm->currentDecision = -1;
00430       return (-1);
00431     }
00432 
00433     d = SATgetDecision(cm->currentDecision);
00434     cm->implicatedSoFar -= d->implied->num;
00435     SATante(fdaLit) = 0;
00436 
00437     SATvalue(fdaLit) = inverted;
00438     SATmakeImplied(fdaLit, d);
00439 
00440     if((SATflags(fdaLit) & InQueueMask)  == 0) {
00441       sat_Enqueue(cm->queue, fdaLit);
00442       SATflags(fdaLit) |= InQueueMask;
00443     }
00444 
00445     clauseArray->num = 0;
00446 
00447     if(option->incTraceObjective && objectFlag == 0)
00448       sat_ArrayInsert(cm->nonobjUnitLitArray, SATnot(fdaLit));
00449 
00450     if(option->incDistill && objectFlag)
00451       sat_ArrayInsert(cm->objUnitLitArray, SATnot(fdaLit));
00452 
00453     if(objectFlag)
00454       SATflags(fdaLit) |= ObjMask;
00455 
00456     /* Bing: UNSAT core generation */
00457     if(cm->option->coreGeneration){
00458       if(cm->option->RT){
00459         st_insert(cm->anteTable,(char*)SATnormalNode(fdaLit),(char*)learned);
00460 
00461         st_insert(cm->RTreeTable, (char *)learned, (char *)rm->root);
00462         RT_oriClsIdx(rm->root) = learned;
00463          }
00464       else{
00465         st_insert(cm->anteTable,(char*)SATnormalNode(fdaLit),(char*)learned);
00466         st_insert(cm->dependenceTable, (char *)learned, (char *)cm->dependenceArray);
00467       }
00468     }
00469     return(bLevel);
00470   }
00471 
00472   if(strongFlag && (SATnumConflict(conflicting) % 5) == 0 &&
00473           clauseArray->num > 4) {
00474     nClauseArray = sat_ArrayAlloc(clauseArray->num);
00475     memcpy(nClauseArray->space, clauseArray->space, sizeof(long)*clauseArray->num);
00476     nClauseArray->num = clauseArray->num;
00477     clauseArray->num = 0;
00478     bLevel = sat_ConflictAnalysisUsingAuxImplication(cm, nClauseArray);
00479     sat_ArrayFree(nClauseArray);
00480   }
00481   else {
00482     /* add conflict learned clause */
00483     learned = sat_AddConflictClause(cm, clauseArray, objectFlag);
00484     cm->currentTopConflict = cm->literals->last-1;
00485     cm->currentTopConflictCount = 0;
00486 
00487      /* Bing: UNSAT core generation */
00488     if(cm->option->coreGeneration){
00489 
00490       if(cm->option->RT){
00491         st_insert(cm->RTreeTable, (char *)learned, (char *)rm->root);
00492         RT_oriClsIdx(rm->root) = learned;
00493         }
00494       else{
00495         st_insert(cm->dependenceTable, (char *)learned, (char *)cm->dependenceArray);
00496       }
00497     }
00498 
00499     if(option->verbose > 2) {
00500       sat_PrintNode(cm, learned);
00501       fflush(cm->stdOut);
00502     }
00503 
00504 
00505     /* apply Deepest Variable Hike decision heuristic */
00506     if(option->decisionHeuristic & DVH_DECISION)
00507       sat_UpdateDVH(cm, d, clauseArray, bLevel, fdaLit);
00508 
00509     /* Backtrack and failure driven assertion */
00510     sat_Backtrack(cm, bLevel);
00511 
00512     d = SATgetDecision(bLevel);
00513     cm->implicatedSoFar -= d->implied->num;
00514 
00515     SATante(fdaLit) = learned;
00516     SATvalue(fdaLit) = inverted;
00517     SATmakeImplied(fdaLit, d);
00518 
00519     if((SATflags(fdaLit) & InQueueMask)  == 0) {
00520       sat_Enqueue(cm->queue, fdaLit);
00521       SATflags(fdaLit) |= InQueueMask;
00522     }
00523 
00524     clauseArray->num = 0;
00525     if(objectFlag)
00526       SATflags(fdaLit) |= ObjMask;
00527 
00528   }
00529 
00530   return(bLevel);
00531 }
00532 
00544 int
00545 sat_AddConflictClauseAndBacktrackForLifting(
00546         satManager_t *cm,
00547         satArray_t *clauseArray,
00548         satLevel_t *d,
00549         long fdaLit,
00550         int bLevel,
00551         int objectFlag,
00552         int strongFlag)
00553 {
00554 int inverted;
00555 long conflicting, learned;
00556 satOption_t *option;
00557 satStatistics_t *stats;
00558 satArray_t *nClauseArray;
00559 
00560   option = cm->option;
00561   stats = cm->each;
00562 
00563   inverted = SATisInverted(fdaLit);
00564   fdaLit = SATnormalNode(fdaLit);
00565 
00566   conflicting = d->conflict;
00567 
00568   if(option->verbose > 2) {
00569     if(option->verbose > 4)
00570       sat_PrintNode(cm, conflicting);
00571     fprintf(cm->stdOut, "conflict at %3d on %6ld  bLevel %d UnitLit ",
00572             d->level, conflicting, bLevel);
00573     sat_PrintNodeAlone(cm, fdaLit);
00574     fprintf(cm->stdOut, "\n");
00575   }
00576 
00577   d->conflict = 0;
00578 
00579   /* unit literal conflict clause */
00580   if(clauseArray->num == 1) {
00581     learned = sat_AddUnitConflictClause(cm, clauseArray, objectFlag);
00582     stats->nUnitConflictCl++;
00583     cm->currentTopConflict = cm->literals->last-1;
00584     cm->currentTopConflictCount = 0;
00585 
00586     sat_Backtrack(cm, 0);
00587 
00588     if(SATlevel(fdaLit) == 0) {
00589       if(cm->option->coreGeneration){
00590         st_insert(cm->anteTable,(char*)SATnormalNode(fdaLit),(char*)learned);
00591         st_insert(cm->dependenceTable, (char *)learned, (char *)cm->dependenceArray);
00592       }
00593       cm->currentDecision = -1;
00594       return (-1);
00595     }
00596 
00597     d = SATgetDecision(cm->currentDecision);
00598     cm->implicatedSoFar -= d->implied->num;
00599     SATante(fdaLit) = 0;
00600 
00601     SATvalue(fdaLit) = inverted;
00602     SATmakeImplied(fdaLit, d);
00603 
00604     if((SATflags(fdaLit) & InQueueMask)  == 0) {
00605       sat_Enqueue(cm->queue, fdaLit);
00606       SATflags(fdaLit) |= InQueueMask;
00607     }
00608 
00609     clauseArray->num = 0;
00610 
00611     if(option->incTraceObjective && objectFlag == 0)
00612       sat_ArrayInsert(cm->nonobjUnitLitArray, SATnot(fdaLit));
00613 
00614     if(option->incDistill && objectFlag)
00615       sat_ArrayInsert(cm->objUnitLitArray, SATnot(fdaLit));
00616 
00617     if(objectFlag)
00618       SATflags(fdaLit) |= ObjMask;
00619 
00620     /* Bing: UNSAT core generation */
00621     if(cm->option->coreGeneration){
00622       st_insert(cm->anteTable,(char*)SATnormalNode(fdaLit),(char*)learned);
00623       st_insert(cm->dependenceTable, (char *)learned, (char *)cm->dependenceArray);
00624     }
00625     return(0);
00626   }
00627 
00628   if(strongFlag && (SATnumConflict(conflicting) % 5) == 0 &&
00629           clauseArray->num > 4) {
00630     nClauseArray = sat_ArrayAlloc(clauseArray->num);
00631     memcpy(nClauseArray->space, clauseArray->space, sizeof(long)*clauseArray->num);
00632     nClauseArray->num = clauseArray->num;
00633     clauseArray->num = 0;
00634     bLevel = sat_ConflictAnalysisUsingAuxImplication(cm, nClauseArray);
00635     sat_ArrayFree(nClauseArray);
00636   }
00637   else {
00638     /* add conflict learned clause */
00639     learned = sat_AddConflictClause(cm, clauseArray, objectFlag);
00640     cm->currentTopConflict = cm->literals->last-1;
00641     cm->currentTopConflictCount = 0;
00642 
00643      /* Bing: UNSAT core generation */
00644     if(cm->option->coreGeneration){
00645       st_insert(cm->dependenceTable, (char *)learned, (char *)cm->dependenceArray);
00646     }
00647 
00648     if(option->verbose > 2) {
00649       sat_PrintNode(cm, learned);
00650       fflush(cm->stdOut);
00651     }
00652 
00653 
00654     /* apply Deepest Variable Hike decision heuristic */
00660     /* Backtrack and failure driven assertion */
00661     sat_Backtrack(cm, bLevel);
00662 
00663     d = SATgetDecision(bLevel);
00664     cm->implicatedSoFar -= d->implied->num;
00665 
00666     SATante(fdaLit) = learned;
00667     SATvalue(fdaLit) = inverted;
00668     SATmakeImplied(fdaLit, d);
00669 
00670     if((SATflags(fdaLit) & InQueueMask)  == 0) {
00671       sat_Enqueue(cm->queue, fdaLit);
00672       SATflags(fdaLit) |= InQueueMask;
00673     }
00674 
00675     clauseArray->num = 0;
00676     if(objectFlag)
00677       SATflags(fdaLit) |= ObjMask;
00678 
00679   }
00680 
00681   return(bLevel);
00682 }
00683 
00695 int
00696 sat_AddConflictClauseWithNoScoreAndBacktrack(
00697         satManager_t *cm,
00698         satArray_t *clauseArray,
00699         satLevel_t *d,
00700         long fdaLit,
00701         int bLevel,
00702         int objectFlag,
00703         int strongFlag)
00704 {
00705 int inverted;
00706 long conflicting, learned;
00707 satOption_t *option;
00708 satStatistics_t *stats;
00709 satArray_t *nClauseArray;
00710 
00711   option = cm->option;
00712   stats = cm->each;
00713 
00714   inverted = SATisInverted(fdaLit);
00715   fdaLit = SATnormalNode(fdaLit);
00716 
00717   conflicting = d->conflict;
00718 
00719   if(option->verbose > 2) {
00720     if(option->verbose > 4)
00721       sat_PrintNode(cm, conflicting);
00722     fprintf(cm->stdOut, "conflict at %3d on %6ld  bLevel %d UnitLit ",
00723             d->level, conflicting, bLevel);
00724     sat_PrintNodeAlone(cm, fdaLit);
00725     fprintf(cm->stdOut, "\n");
00726   }
00727 
00728   d->conflict = 0;
00729 
00730   /* unit literal conflict clause */
00731   if(clauseArray->num == 1) {
00732     learned = sat_AddUnitConflictClause(cm, clauseArray, objectFlag);
00733     stats->nUnitConflictCl++;
00734     cm->currentTopConflict = cm->literals->last-1;
00735     cm->currentTopConflictCount = 0;
00736 
00737     sat_Backtrack(cm, 0);
00738 
00739     if(SATlevel(fdaLit) == 0) {
00740       if(cm->option->coreGeneration){
00741         st_insert(cm->anteTable,(char*)SATnormalNode(fdaLit),(char*)learned);
00742         st_insert(cm->dependenceTable, (char *)learned, (char *)cm->dependenceArray);
00743       }
00744       cm->currentDecision = -1;
00745       return (-1);
00746     }
00747 
00748     d = SATgetDecision(cm->currentDecision);
00749     cm->implicatedSoFar -= d->implied->num;
00750     SATante(fdaLit) = 0;
00751 
00752     SATvalue(fdaLit) = inverted;
00753     SATmakeImplied(fdaLit, d);
00754 
00755     if((SATflags(fdaLit) & InQueueMask)  == 0) {
00756       sat_Enqueue(cm->queue, fdaLit);
00757       SATflags(fdaLit) |= InQueueMask;
00758     }
00759 
00760     clauseArray->num = 0;
00761 
00762     if(option->incTraceObjective && objectFlag == 0)
00763       sat_ArrayInsert(cm->nonobjUnitLitArray, SATnot(fdaLit));
00764 
00765     if(option->incDistill && objectFlag)
00766       sat_ArrayInsert(cm->objUnitLitArray, SATnot(fdaLit));
00767 
00768     if(objectFlag)
00769       SATflags(fdaLit) |= ObjMask;
00770 
00771     /* Bing: UNSAT core generation */
00772     if(cm->option->coreGeneration){
00773       st_insert(cm->anteTable,(char*)SATnormalNode(fdaLit),(char*)learned);
00774       st_insert(cm->dependenceTable, (char *)learned, (char *)cm->dependenceArray);
00775     }
00776     return(bLevel);
00777   }
00778 
00779   if(strongFlag && (SATnumConflict(conflicting) % 5) == 0 &&
00780           clauseArray->num > 4) {
00781     nClauseArray = sat_ArrayAlloc(clauseArray->num);
00782     memcpy(nClauseArray->space, clauseArray->space, sizeof(long)*clauseArray->num);
00783     nClauseArray->num = clauseArray->num;
00784     clauseArray->num = 0;
00785     bLevel = sat_ConflictAnalysisUsingAuxImplication(cm, nClauseArray);
00786     sat_ArrayFree(nClauseArray);
00787   }
00788   else {
00789     /* add conflict learned clause */
00790     learned = sat_AddConflictClauseNoScoreUpdate(cm, clauseArray, objectFlag);
00791     cm->currentTopConflict = cm->literals->last-1;
00792     cm->currentTopConflictCount = 0;
00793 
00794      /* Bing: UNSAT core generation */
00795     if(cm->option->coreGeneration){
00796       st_insert(cm->dependenceTable, (char *)learned, (char *)cm->dependenceArray);
00797     }
00798 
00799     if(option->verbose > 2) {
00800       sat_PrintNode(cm, learned);
00801       fflush(cm->stdOut);
00802     }
00803 
00804 
00805     /* apply Deepest Variable Hike decision heuristic */
00806     if(option->decisionHeuristic & DVH_DECISION)
00807       sat_UpdateDVH(cm, d, clauseArray, bLevel, fdaLit);
00808 
00809     /* Backtrack and failure driven assertion */
00810     sat_Backtrack(cm, bLevel);
00811 
00812     d = SATgetDecision(bLevel);
00813     cm->implicatedSoFar -= d->implied->num;
00814 
00815     SATante(fdaLit) = learned;
00816     SATvalue(fdaLit) = inverted;
00817     SATmakeImplied(fdaLit, d);
00818 
00819     if((SATflags(fdaLit) & InQueueMask)  == 0) {
00820       sat_Enqueue(cm->queue, fdaLit);
00821       SATflags(fdaLit) |= InQueueMask;
00822     }
00823 
00824     clauseArray->num = 0;
00825     if(objectFlag)
00826       SATflags(fdaLit) |= ObjMask;
00827 
00828   }
00829 
00830   return(bLevel);
00831 }
00832 
00844 int
00845 sat_ConflictAnalysisUsingAuxImplication(
00846         satManager_t *cm,
00847         satArray_t *clauseArray)
00848 {
00849 int tLevel, level, bLevel;
00850 int i, size;
00851 int value, tvalue;
00852 int minConflict, maxConflict;
00853 long v, tv, conflicting;
00854 satLevel_t *d;
00855 satArray_t *nClauseArray;
00856 double aMean, hMean, gMean;
00857 int objectFlag;
00858 long fdaLit;
00859 
00860   SATcm = cm;
00861   qsort(clauseArray->space, clauseArray->num, sizeof(int), levelCompare);
00862   tLevel = cm->currentDecision;
00863 
00864   tv = clauseArray->space[0];
00865   v = SATnormalNode(tv);
00866   level = SATlevel(v);
00867   minConflict = cm->decisionHead[level].nConflict;
00868   tv = clauseArray->space[clauseArray->num-1];
00869   v = SATnormalNode(tv);
00870   level = SATlevel(v);
00871   maxConflict = cm->decisionHead[level].nConflict;
00872 
00873   aMean = hMean = 0;
00874 
00875   for(i=0; i<clauseArray->num; i++) {
00876     tv = clauseArray->space[i];
00877     v = SATnormalNode(tv);
00878     level = SATlevel(v);
00879     if(level < tLevel) tLevel = level;
00880     aMean = aMean + (double)level;
00881     hMean = hMean + 1.0/(double)level;
00882   }
00883   aMean = aMean/(double)clauseArray->num;
00884   hMean = (double)clauseArray->num/hMean;
00885   gMean = sqrt(aMean*hMean);
00886 
00887   sat_Backtrack(cm, tLevel-1);
00888 
00889   size = clauseArray->num;
00890 
00891   for(i=0; i<size; i++) {
00892     tv = clauseArray->space[i];
00893     value = !SATisInverted(tv);
00894     v = SATnormalNode(tv);
00895     tvalue = SATvalue(v);
00896 
00897     if(tvalue != 2)     {
00904       continue;
00905     }
00906     d = sat_AllocLevel(cm);
00907 
00908     SATvalue(v) = value;
00909     SATmakeImplied(v, d);
00910     d->decisionNode = v;
00911     d->nConflict = cm->each->nConflictCl;
00912     if((SATflags(v) & InQueueMask) == 0) {
00913       sat_Enqueue(cm->queue, v);
00914       SATflags(v) |= InQueueMask;
00915     }
00916     sat_ImplicationMain(cm, d);
00917 
00918     if(d->conflict) {
00919       conflicting = d->conflict;
00920       break;
00921     }
00922   }
00923 
00924   if(d->conflict) {
00925     nClauseArray = cm->auxArray;
00926     bLevel = 0;
00927     fdaLit = -1;
00928     nClauseArray->num = 0;
00929     sat_FindUIP(cm, nClauseArray, d, &objectFlag, &bLevel, &fdaLit);
00930 
00937     bLevel = sat_AddConflictClauseAndBacktrack(
00938             cm, nClauseArray, d, fdaLit, bLevel, objectFlag, 0);
00939 
00940 
00941   }
00942   else {
00943     bLevel = cm->currentDecision;
00944   }
00945   return(bLevel);
00946 
00947 }
00948 
00949 
00961 int
00962 sat_ConflictAnalysisForCoreGen(
00963         satManager_t *cm,
00964         satLevel_t *d)
00965 {
00966 satStatistics_t *stats;
00967 satOption_t *option;
00968 satArray_t *clauseArray;
00969 int objectFlag;
00970 int bLevel;
00971 long fdaLit, learned, conflicting;
00972 int inverted;
00973 
00974 RTManager_t * rm = cm->rm;
00975 
00976   if(d->level != 0) {
00977     fprintf(stdout, "ERROR : Can't use this function at higher than level 0\n");
00978     return(0);
00979   }
00980 
00981   conflicting = d->conflict;
00982 
00983   stats = cm->each;
00984   option = cm->option;
00985 
00986   stats->nBacktracks++;
00987 
00988   clauseArray = cm->auxArray;
00989 
00990   bLevel = 0;
00991   fdaLit = -1;
00992   clauseArray->num = 0;
00993 
00994   /* Find Unique Implication Point */
00995 
00996   if(option->RT)
00997     sat_FindUIPForCoreGenWithRT(cm, clauseArray, d, &objectFlag, &bLevel,&fdaLit);
00998   else
00999     sat_FindUIPForCoreGen(cm, clauseArray, d, &objectFlag, &bLevel, &fdaLit);
01000 
01001   if(fdaLit < 0 )
01002     fprintf(stdout, "ERROR : critical\n");
01003 
01004   inverted = SATisInverted(fdaLit);
01005   fdaLit = SATnormalNode(fdaLit);
01006 
01007   d->conflict = 0;
01008 
01009   assert(clauseArray->num == 1);
01010   learned = sat_AddUnitConflictClause(cm, clauseArray, objectFlag);
01011 
01012   SATante(fdaLit) = 0;
01013 
01014   clauseArray->num = 0;
01015 
01016   /* Bing: UNSAT core generation */
01017   if(cm->option->coreGeneration){
01018     st_insert(cm->anteTable,(char*)(long)SATnormalNode(fdaLit),(char*)(long)learned);
01019     if(option->RT){
01020       st_insert(cm->RTreeTable, (char *)learned, (char *)rm->root);
01021       RT_oriClsIdx(rm->root) = learned;
01022     }
01023     else
01024       st_insert(cm->dependenceTable, (char *)(long)learned, (char *)(long)cm->dependenceArray);
01025   }
01026   return 1;
01027 }
01028 
01041 void
01042 sat_FindUIP(
01043         satManager_t *cm,
01044         satArray_t *clauseArray,
01045         satLevel_t *d,
01046         int *objectFlag,
01047         int *bLevel,
01048         long *fdaLit)
01049 {
01050 long conflicting;
01051 int nMarked, value;
01052 int first, i;
01053 long *space, v;
01054 satArray_t *implied;
01055 satOption_t *option;
01056 
01057   conflicting = d->conflict;
01058   nMarked = 0;
01059   option = cm->option;
01060   if(option->incTraceObjective) *objectFlag = 0;
01061   else                          *objectFlag = ObjMask;
01062 
01063   (*objectFlag) |= (SATflags(conflicting) & ObjMask);
01064 
01065   /* find seed from conflicting clause to find unique implication point.
01066    * */
01067   clauseArray->num = 0;
01068 
01069   if(SATflags(conflicting) & IsCNFMask)
01070     SATconflictUsage(conflicting)++;
01071 
01072   sat_MarkNodeInConflict(
01073           cm, d, &nMarked, objectFlag, bLevel, clauseArray);
01074 
01075   /* Traverse implication graph backward */
01076   first = 1;
01077   implied = d->implied;
01078   space = implied->space+implied->num-1;
01079   /* Bing:  UNSAT core generation */
01080   if(cm->option->coreGeneration){
01081     cm->dependenceArray = sat_ArrayAlloc(1);
01082     sat_ArrayInsert(cm->dependenceArray,conflicting);
01083   }
01084 
01085   for(i=implied->num-1; i>=0; i--, space--) {
01086     v = *space;
01087     if(SATflags(v) & VisitedMask) {
01088       SATflags(v) &= ResetVisitedMask;
01089       --nMarked;
01090 
01091       if(nMarked == 0 && (!first || i==0))  {
01092         value = SATvalue(v);
01093         *fdaLit = v^(!value);
01094         sat_ArrayInsert(clauseArray, *fdaLit);
01095         break;
01096       }
01097 
01098       /* Bing: UNSAT core genration */
01099       if(cm->option->coreGeneration){
01100         int ante = SATante(v);
01101         if(ante!=0 && !(SATflags(ante) & IsCNFMask)){
01102           printf("node %d is not CNF\n", ante);
01103           exit(0);
01104         }
01105         if(ante==0){
01106           if(!st_lookup(cm->anteTable, (char *)SATnormalNode(v), &ante)){
01107             printf("ante = 0 and is not in anteTable %ld\n",v);
01108             exit(0);
01109           }
01110         }
01111         sat_ArrayInsert(cm->dependenceArray,ante);
01112       }
01113 
01114       sat_MarkNodeInImpliedNode(
01115               cm, d, v, &nMarked, objectFlag, bLevel, clauseArray);
01116     }
01117     first = 0;
01118   }
01119 
01120 
01121   /* Minimize conflict clause */
01122   if(option->minimizeConflictClause)
01123     sat_MinimizeConflictClause(cm, clauseArray);
01124   else
01125     sat_ResetFlagForClauseArray(cm, clauseArray);
01126 
01127   return;
01128 }
01142 void
01143 sat_FindUIPWithRT(
01144         satManager_t *cm,
01145         satArray_t *clauseArray,
01146         satLevel_t *d,
01147         int *objectFlag,
01148         int *bLevel,
01149         long *fdaLit)
01150 {
01151 long conflicting;
01152 int nMarked, value;
01153 int first, i,j;
01154 long *space, v,left,right,inverted,result,*tmp;
01155 satArray_t *implied;
01156 satOption_t *option;
01157 RTnode_t  tmprt;
01158 int size = 0;
01159 long *lp,*tmpIP,ante,ante2,node;
01160  RTManager_t * rm = cm->rm;
01161 
01162   conflicting = d->conflict;
01163   nMarked = 0;
01164   option = cm->option;
01165   if(option->incTraceObjective) *objectFlag = 0;
01166   else                          *objectFlag = ObjMask;
01167 
01168   (*objectFlag) |= (SATflags(conflicting) & ObjMask);
01169 
01170   /* find seed from conflicting clause to find unique implication point.
01171    * */
01172   clauseArray->num = 0;
01173   sat_MarkNodeInConflict(
01174           cm, d, &nMarked, objectFlag, bLevel, clauseArray);
01175 
01176   /* Traverse implication graph backward */
01177   first = 1;
01178   implied = d->implied;
01179   space = implied->space+implied->num-1;
01180 
01181 
01182   if(cm->option->coreGeneration){
01183     /*if last conflict is CNF*/
01184     if(SATflags(conflicting)&IsCNFMask){
01185       /*is conflict CNF*/
01186       if(SATflags(conflicting)&IsConflictMask){
01187          if(!st_lookup(cm->RTreeTable,(char*)conflicting,&tmprt)){
01188             printf("RTree node of conflict cnf %ld is not in RTreeTable\n",ante);
01189             exit(0);
01190           }
01191           else{
01192             rm->root = tmprt;
01193 #if PR
01194             printf("Get formula for CONFLICT CLAUSE:%d\n",ante);
01195 #endif
01196           }
01197       }
01198       /*CNF but not conflict*/
01199       else{
01200         rm->root = RTCreateNode(rm);
01201 
01202         size = SATnumLits(conflicting);
01203         RT_fSize(rm->root) = size;
01204         lp = (long*)SATfirstLit(conflicting);
01205         sat_BuildRT(cm,rm->root, lp, tmpIP,size,0);
01206       }
01207     }
01208     /*if last conflict is AIG*/
01209     else{
01210       rm->root = RTCreateNode(rm);
01211       node = SATnormalNode(conflicting);
01212       left = SATleftChild(node);
01213       right = SATrightChild(node);
01214       result = PureSat_IdentifyConflict(cm,left,right,conflicting);
01215       inverted = SATisInverted(left);
01216       left = SATnormalNode(left);
01217       left = inverted ? SATnot(left) : left;
01218 
01219       inverted = SATisInverted(right);
01220       right = SATnormalNode(right);
01221       right = inverted ? SATnot(right) : right;
01222 
01223       j = node;
01224 
01225       if(result == 1){
01226         tmp = ALLOC(long,3);
01227         tmp[0] = left;
01228         tmp[1] = SATnot(j);
01229         size = 2;
01230       }
01231       else if(result == 2){
01232         tmp = ALLOC(long,3);
01233         tmp[0] = right;
01234         tmp[1] = SATnot(j);
01235         size = 2;
01236       }
01237       else if(result == 3){
01238         tmp = ALLOC(long,4);
01239         tmp[0] = SATnot(left);
01240         tmp[1] = SATnot(right);
01241         tmp[2] = j;
01242         size = 3;
01243       }
01244       else{
01245         printf("wrong returned result value, exit\n");
01246         exit(0);
01247       }
01248 
01249       lp = tmp;
01250       sat_BuildRT(cm,rm->root, lp, tmpIP,size,1);
01251       FREE(tmp);
01252     }
01253   }
01254 
01255 
01256   for(i=implied->num-1; i>=0; i--, space--) {
01257     v = *space;
01258     if(SATflags(v) & VisitedMask) {
01259       SATflags(v) &= ResetVisitedMask;
01260       --nMarked;
01261 
01262       if(nMarked == 0 && (!first || i==0))  {
01263         value = SATvalue(v);
01264         *fdaLit = v^(!value);
01265         sat_ArrayInsert(clauseArray, *fdaLit);
01266         break;
01267       }
01268 
01269 
01270       if(cm->option->coreGeneration){
01271         ante = SATante(v);
01272         if(ante==0){
01273           if(!(st_lookup(cm->anteTable, (char *)SATnormalNode(v),&ante))){
01274             printf("ante = 0 and is not in anteTable %ld\n",v);
01275             exit(0);
01276           }
01277         }
01278 
01279         /*build non-leaf node*/
01280         tmprt = RTCreateNode(rm);
01281         RT_pivot(tmprt) = SATnormalNode(v);
01282         RT_right(tmprt) = rm->root;
01283         rm->root = tmprt;
01284 
01285         if((SATflags(ante)&IsConflictMask)&&(SATflags(ante)&IsCNFMask)){
01286           if(!st_lookup(cm->RTreeTable,(char*)ante,&tmprt)){
01287             printf("RTree node of conflict cnf %ld is not in RTreeTable\n",ante);
01288             exit(0);
01289           }
01290           else{
01291             RT_left(rm->root) = tmprt;
01292 #if PR
01293             printf("Get formula for CONFLICT CLAUSE:%d\n",ante);
01294 #endif
01295           }
01296         }
01297         else{ /* if not conflict CNF*/
01298           /*left  */
01299           tmprt = RTCreateNode(rm);
01300           RT_left(rm->root) = tmprt;
01301           /*left is AIG*/
01302           if(!(SATflags(ante) & IsCNFMask)){
01303             /*generate formula for left*/
01304             tmp = ALLOC(long,3);
01305             value = SATvalue(v);
01306             node = SATnormalNode(v);
01307             node = value==1?node:SATnot(node);
01308             tmp[0] = node;
01309 
01310             size = 1;
01311             if(ante != SATnormalNode(v)){
01312               value = SATvalue(ante);
01313               node = SATnormalNode(ante);
01314               node = value==1?SATnot(node):node;
01315               tmp[1] = node;
01316               size++;
01317               ante2 = SATante2(v);
01318               if(ante2){
01319                 value = SATvalue(ante2);
01320                 node = SATnormalNode(ante2);
01321                 node = value==1?SATnot(node):node;
01322                 tmp[2] = node;
01323                 size++;
01324               }
01325             }
01326 
01327             lp = tmp;
01328             sat_BuildRT(cm,tmprt,lp,tmpIP,size,1);
01329             FREE(tmp);
01330           }
01331           /* left is CNF*/
01332           else{
01333 
01334             lp = (long*)SATfirstLit(ante);
01335             size = SATnumLits(ante);
01336             RT_fSize(tmprt) = size;
01337             sat_BuildRT(cm,tmprt, lp, tmpIP,size,0);
01338           }
01339         } /*else{ // if not conflict CNF*/
01340 
01341       }/*if(cm->option->coreGeneration){*/
01342 
01343 
01344       sat_MarkNodeInImpliedNode(
01345               cm, d, v, &nMarked, objectFlag, bLevel, clauseArray);
01346     }
01347     first = 0;
01348   }
01349 
01350 
01351   /* Minimize conflict clause */
01352   if(option->minimizeConflictClause)
01353     sat_MinimizeConflictClause(cm, clauseArray);
01354   else
01355     sat_ResetFlagForClauseArray(cm, clauseArray);
01356 
01357   return;
01358 }
01359 
01372 void
01373 sat_FindUIPAndNonUIP(
01374         satManager_t *cm,
01375         satArray_t *clauseArray,
01376         satLevel_t *d,
01377         int *objectFlag,
01378         int *bLevel,
01379         long *fdaLit)
01380 {
01381 long conflicting;
01382 int nMarked, value;
01383 int first, i, j;
01384 int size, oSize;
01385 int depth, maxSize;
01386 long *space, v, nv, maxV;
01387 long ante, ante2;
01388 long learned;
01389 long *plit;
01390 satArray_t *implied;
01391 satArray_t *nClauseArray;
01392 satOption_t *option;
01393 int tLevel, inverted, lBacktrace, uBacktrace;
01394 int minLimit, markLimit, tObjectFlag;
01395 int inserted;
01396 long tFdaLit;
01397 
01399   conflicting = d->conflict;
01400   nMarked = 0;
01401   option = cm->option;
01402   if(option->incTraceObjective) *objectFlag = 0;
01403   else                          *objectFlag = ObjMask;
01404 
01405   (*objectFlag) |= (SATflags(conflicting) & ObjMask);
01406 
01407   /* find seed from conflicting clause to find unique implication point.
01408    * */
01409   clauseArray->num = 0;
01410 
01411   if(SATflags(conflicting) & IsCNFMask)
01412     SATconflictUsage(conflicting)++;
01413 
01414   sat_MarkNodeInConflict(
01415           cm, d, &nMarked, objectFlag, bLevel, clauseArray);
01416 
01417   /* Traverse implication graph backward */
01418   first = 1;
01419   implied = d->implied;
01420   space = implied->space+implied->num-1;
01421   maxSize = 0;
01422   maxV = 0;
01423   /* Bing:  UNSAT core generation */
01424   if(cm->option->coreGeneration){
01425     cm->dependenceArray = sat_ArrayAlloc(1);
01426     sat_ArrayInsert(cm->dependenceArray,conflicting);
01427   }
01428 
01429   for(i=implied->num-1; i>=0; i--, space--) {
01430     v = *space;
01431     if(SATflags(v) & VisitedMask) {
01432       SATflags(v) &= ResetVisitedMask;
01433       --nMarked;
01434 
01435       depth = cm->variableArray[SATnodeID(v)].depth;
01436       if(nMarked == 0 && (!first || i==0))  {
01437         value = SATvalue(v);
01438         *fdaLit = v^(!value);
01439         sat_ArrayInsert(clauseArray, *fdaLit);
01440         break;
01441       }
01442 
01443       ante = SATante(v);
01444       /* Bing: UNSAT core genration */
01445       if(cm->option->coreGeneration){
01446         if(ante!=0 && !(SATflags(ante) & IsCNFMask)){
01447           printf("node %ld is not CNF\n", ante);
01448           exit(0);
01449         }
01450         if(ante==0){
01451           if(!st_lookup(cm->anteTable, (char *)SATnormalNode(v), &ante)){
01452             printf("ante = 0 and is not in anteTable %ld\n",v);
01453             exit(0);
01454           }
01455         }
01456         sat_ArrayInsert(cm->dependenceArray,ante);
01457       }
01458 
01464       if(SATflags(ante) & IsCNFMask) {
01465         SATconflictUsage(ante)++;
01466         size = SATnumLits(ante);
01467         oSize = clauseArray->num;
01468         for(j=0, plit=(long*)SATfirstLit(ante); j<size; j++, plit++) {
01469           nv = SATgetNode(*plit);
01470           if(SATnormalNode(nv) != v)    {
01471             sat_MarkNodeSub(cm, nv, &nMarked, bLevel, d, clauseArray);
01472             if(cm->variableArray[SATnodeID(nv)].depth <= depth) {
01473               cm->variableArray[SATnodeID(nv)].depth = depth+1;
01474             }
01475           }
01476         }
01477         oSize = clauseArray->num-oSize;
01478         if(oSize > maxSize) {
01479           maxSize = oSize;
01480           maxV = v;
01481         }
01482       }
01483       else {
01484         sat_MarkNodeSub(cm, ante, &nMarked, bLevel, d, clauseArray);
01485         ante2 = SATante2(v);
01486         if(ante2)
01487           sat_MarkNodeSub(cm, ante2, &nMarked, bLevel, d, clauseArray);
01488       }
01489 
01490     }
01491     first = 0;
01492   }
01493 
01494   /* Minimize conflict clause */
01495   if(option->minimizeConflictClause)
01496     sat_MinimizeConflictClause(cm, clauseArray);
01497   else
01498     sat_ResetFlagForClauseArray(cm, clauseArray);
01499 
01500   if(maxSize > clauseArray->num/4 && maxSize > 5) {
01501     nClauseArray = sat_ArrayAlloc(clauseArray->num);
01502 
01503     nMarked = 0;
01504     tLevel = 0;
01505     tObjectFlag |= (SATflags(conflicting) & ObjMask);
01506 
01507     sat_MarkNodeInConflict(
01508           cm, d, &nMarked, &tObjectFlag, &tLevel, nClauseArray);
01509 
01510     /* Traverse implication graph backward */
01511     first = 1;
01512     implied = d->implied;
01513     space = implied->space+implied->num-1;
01514     for(i=implied->num-1; i>=0; i--, space--) {
01515       v = *space;
01516       if(v == maxV) {
01517         if(SATflags(v) & VisitedMask) {
01518           SATflags(v) &= ResetVisitedMask;
01519           --nMarked;
01520           value = SATvalue(v);
01521           sat_ArrayInsert(nClauseArray, v^(!value));
01522         }
01523         continue;
01524       }
01525 
01526       if(SATflags(v) & VisitedMask) {
01527         SATflags(v) &= ResetVisitedMask;
01528         --nMarked;
01529 
01530         if(nMarked == 0 && (!first || i == 0))  {
01531           value = SATvalue(v);
01532           tFdaLit = v^(!value);
01533           sat_ArrayInsert(nClauseArray, tFdaLit);
01534           break;
01535         }
01536 
01537         ante= SATante(v);
01538         inverted = SATisInverted(ante);
01539         ante= SATnormalNode(ante);
01540 
01541         if(SATflags(ante) & IsCNFMask) {
01542           size = SATnumLits(ante);
01543           for(j=0, plit=(long*)SATfirstLit(ante); j<size; j++, plit++) {
01544             nv = SATgetNode(*plit);
01545             if(SATnormalNode(nv) != v)
01546               sat_MarkNodeSub(cm, nv, &nMarked, &tLevel, d, nClauseArray);
01547           }
01548         }
01549         else {
01550           sat_MarkNodeSub(cm, ante, &nMarked, &tLevel, d, nClauseArray);
01551           ante2 = SATante2(v);
01552           if(ante2)
01553             sat_MarkNodeSub(cm, ante2, &nMarked, &tLevel, d, nClauseArray);
01554         }
01555       }
01556       first = 0;
01557     }
01558     sat_MinimizeConflictClause(cm, nClauseArray);
01559 
01560     inserted = 0;
01561     if(clauseArray->num*4/5 > nClauseArray->num) {
01562       learned = sat_AddConflictClauseNoScoreUpdate(cm, nClauseArray, tObjectFlag);
01563       inserted = 1;
01564     }
01565     sat_ArrayFree(nClauseArray);
01566   }
01567   if( inserted == 0 &&
01568       depth > 20) {
01569     nClauseArray = sat_ArrayAlloc(clauseArray->num);
01570 
01571     lBacktrace = depth/3;
01572     uBacktrace = depth*2/3;
01573 
01576     markLimit = 1;
01577     minLimit = 1000;
01578     while(1){
01579       nMarked = 0;
01580       tLevel = 0;
01581       depth = 0;
01582       nClauseArray->num = 0;
01583       markLimit++;
01584       if(markLimit > 3) break;
01585       if(minLimit != 1000 && minLimit > 3)
01586         break;
01587       tObjectFlag |= (SATflags(conflicting) & ObjMask);
01588 
01589       sat_MarkNodeInConflict(
01590             cm, d, &nMarked, &tObjectFlag, &tLevel, nClauseArray);
01591 
01592       first = 1;
01593       implied = d->implied;
01594       space = implied->space+implied->num-1;
01595       for(i=implied->num-1; i>=0; i--, space--) {
01596         v = *space;
01597         if(uBacktrace < depth) {
01598           sat_ResetFlagForClauseArray(cm, nClauseArray);
01599           nClauseArray->num = 0;
01600           for(; i>=0; i--, space--) {
01601             v = *space;
01602             if(SATflags(v) & VisitedMask) {
01603               SATflags(v) &= ResetVisitedMask;
01604               --nMarked;
01605               if(nMarked == 0)
01606                 break;
01607             }
01608           }
01609           break;
01610         }
01611         if(nMarked < minLimit)
01612           minLimit = nMarked;
01613         if(depth > lBacktrace && nMarked < markLimit) {
01614           for(; i>=0; i--, space--) {
01615             v = *space;
01616             if(SATflags(v) & VisitedMask) {
01617               SATflags(v) &= ResetVisitedMask;
01618               --nMarked;
01619               value = SATvalue(v);
01620               sat_ArrayInsert(nClauseArray, v^(!value));
01621               if(nMarked == 0)
01622                 break;
01623             }
01624           }
01625         }
01626 
01627         if(SATflags(v) & VisitedMask) {
01628           depth = cm->variableArray[SATnodeID(v)].depth;
01629 
01630           SATflags(v) &= ResetVisitedMask;
01631           --nMarked;
01632 
01633           if(nMarked == 0 && (!first || i == 0))  {
01634             value = SATvalue(v);
01635             tFdaLit = v^(!value);
01636             sat_ArrayInsert(nClauseArray, tFdaLit);
01637             break;
01638           }
01639 
01640           ante= SATante(v);
01641           inverted = SATisInverted(ante);
01642           ante= SATnormalNode(ante);
01643 
01644           if(SATflags(ante) & IsCNFMask) {
01645             size = SATnumLits(ante);
01646             for(j=0, plit=(long*)SATfirstLit(ante); j<size; j++, plit++) {
01647               nv = SATgetNode(*plit);
01648               if(SATnormalNode(nv) != v)
01649                 sat_MarkNodeSub(cm, nv, &nMarked, &tLevel, d, nClauseArray);
01650             }
01651           }
01652           else {
01653             sat_MarkNodeSub(cm, ante, &nMarked, &tLevel, d, nClauseArray);
01654             ante2 = SATante2(v);
01655             if(ante2)
01656               sat_MarkNodeSub(cm, ante2, &nMarked, &tLevel, d, nClauseArray);
01657           }
01658         }
01659         first = 0;
01660       }
01661       if(nClauseArray->num == 0)
01662         continue;
01663       sat_MinimizeConflictClause(cm, nClauseArray);
01664 
01665       if(clauseArray->num*4/5 > nClauseArray->num) {
01666 
01667         learned = sat_AddConflictClauseNoScoreUpdate(cm, nClauseArray, tObjectFlag);
01668         break;
01669       }
01670     }
01671     sat_ArrayFree(nClauseArray);
01672   }
01673 
01674   return;
01675 }
01676 
01688 void
01689 sat_FindUIPForCoreGen(
01690         satManager_t *cm,
01691         satArray_t *clauseArray,
01692         satLevel_t *d,
01693         int *objectFlag,
01694         int *bLevel,
01695         long *fdaLit)
01696 {
01697 long conflicting;
01698 int nMarked, value;
01699 long v;
01700 int first, i;
01701 long *space;
01702 satArray_t *implied;
01703 satOption_t *option;
01704 
01705   conflicting = d->conflict;
01706   nMarked = 0;
01707   option = cm->option;
01708   if(option->incTraceObjective) *objectFlag = 0;
01709   else                          *objectFlag = ObjMask;
01710 
01711   (*objectFlag) |= (SATflags(conflicting) & ObjMask);
01712 
01713   /*  find seed from conflicting clause to find unique implication point. */
01714   clauseArray->num = 0;
01715   sat_MarkNodeInConflict(
01716           cm, d, &nMarked, objectFlag, bLevel, clauseArray);
01717 
01718   /* Traverse implication graph backward */
01719   first = 1;
01720   implied = d->implied;
01721   space = implied->space+implied->num-1;
01722   /* Bing: UNSAT core generation */
01723   if(cm->option->coreGeneration){
01724     cm->dependenceArray = sat_ArrayAlloc(1);
01725     sat_ArrayInsert(cm->dependenceArray,conflicting);
01726   }
01727 
01728   for(i=implied->num-1; i>=0; i--, space--) {
01729     v = *space;
01730     if(SATflags(v) & VisitedMask) {
01731       SATflags(v) &= ResetVisitedMask;
01732       --nMarked;
01733 
01734       if(nMarked == 0 && (!first || i==0))  {
01735         value = SATvalue(v);
01736         *fdaLit = v^(!value);
01737         sat_ArrayInsert(clauseArray, *fdaLit);
01738         break;
01739       }
01740 
01741 
01742        /* Bing: UNSAT core generation */
01743       if(cm->option->coreGeneration){
01744         int ante = SATante(v);
01745         if(ante!=0 && !(SATflags(ante) & IsCNFMask)){
01746           printf("node %d is not CNF\n", ante);
01747           exit(0);
01748         }
01749         if(ante==0){
01750           if(!st_lookup(cm->anteTable, (char *)SATnormalNode(v), &ante)){
01751             printf("ante = 0 and is not in anteTable %ld\n",v);
01752             exit(0);
01753           }
01754         }
01755         sat_ArrayInsert(cm->dependenceArray,ante);
01756       }
01757 
01758 
01759       sat_MarkNodeInImpliedNode(
01760               cm, d, v, &nMarked, objectFlag, bLevel, clauseArray);
01761     }
01762     first = 0;
01763   }
01764 
01765   sat_ResetFlagForClauseArray(cm, clauseArray);
01766 
01767   return;
01768 }
01769 
01783 void
01784 sat_FindUIPForCoreGenWithRT(
01785         satManager_t *cm,
01786         satArray_t *clauseArray,
01787         satLevel_t *d,
01788         int *objectFlag,
01789         int *bLevel,
01790         long *fdaLit)
01791 {
01792 long conflicting;
01793 int nMarked, value;
01794  long v,left,right,inverted,result;
01795 int first, i,size=0;
01796 long *space,*tmp;
01797 satArray_t *implied;
01798 satOption_t *option;
01799 RTnode_t tmprt;
01800 long  *lp, *tmpIP,ante,ante2,node,j;
01801  RTManager_t * rm = cm->rm;
01802 
01803   conflicting = d->conflict;
01804   nMarked = 0;
01805   option = cm->option;
01806   if(option->incTraceObjective) *objectFlag = 0;
01807   else                          *objectFlag = ObjMask;
01808 
01809   (*objectFlag) |= (SATflags(conflicting) & ObjMask);
01810 
01811   /*  find seed from conflicting clause to find unique implication point. */
01812   clauseArray->num = 0;
01813   sat_MarkNodeInConflict(
01814           cm, d, &nMarked, objectFlag, bLevel, clauseArray);
01815 
01816   /* Traverse implication graph backward */
01817   first = 1;
01818   implied = d->implied;
01819   space = implied->space+implied->num-1;
01820 
01821 
01822   if(cm->option->coreGeneration){
01823     /*if last conflict is CNF*/
01824     if(SATflags(conflicting)&IsCNFMask){
01825       /*is conflict CNF*/
01826       if(SATflags(conflicting)&IsConflictMask){
01827          if(!st_lookup(cm->RTreeTable,(char*)conflicting,&tmprt)){
01828             printf("RTree node of conflict cnf %ld is not in RTreeTable\n",ante);
01829             exit(0);
01830           }
01831           else{
01832             rm->root = tmprt;
01833 #if PR
01834             printf("Get formula for CONFLICT CLAUSE:%d\n",ante);
01835 #endif
01836           }
01837       }
01838       /*CNF but not conflict*/
01839       else{
01840         rm->root = RTCreateNode(rm);
01841 
01842         size = SATnumLits(conflicting);
01843         RT_fSize(rm->root) = size;
01844         lp = (long*)SATfirstLit(conflicting);
01845         sat_BuildRT(cm,rm->root, lp, tmpIP,size,0);
01846       }
01847     }
01848     /*if last conflict is AIG*/
01849     else{
01850       rm->root = RTCreateNode(rm);
01851       node = SATnormalNode(conflicting);
01852       left = SATleftChild(node);
01853       right = SATrightChild(node);
01854       result = PureSat_IdentifyConflict(cm,left,right,conflicting);
01855       inverted = SATisInverted(left);
01856       left = SATnormalNode(left);
01857       left = inverted ? SATnot(left) : left;
01858 
01859       inverted = SATisInverted(right);
01860       right = SATnormalNode(right);
01861       right = inverted ? SATnot(right) : right;
01862 
01863       j = node;
01864 
01865       if(result == 1){
01866         tmp = ALLOC(long,3);
01867         tmp[0] = left;
01868         tmp[1] = SATnot(j);
01869         size = 2;
01870       }
01871       else if(result == 2){
01872         tmp = ALLOC(long,3);
01873         tmp[0] = right;
01874         tmp[1] = SATnot(j);
01875         size = 2;
01876       }
01877       else if(result == 3){
01878         tmp = ALLOC(long,4);
01879         tmp[0] = SATnot(left);
01880         tmp[1] = SATnot(right);
01881         tmp[2] = j;
01882         size = 3;
01883       }
01884       else{
01885         printf("wrong returned result value, exit\n");
01886         exit(0);
01887       }
01888 
01889       lp = tmp;
01890       sat_BuildRT(cm,rm->root, lp, tmpIP,size,1);
01891       FREE(tmp);
01892     }
01893   }
01894 
01895 
01896 
01897   for(i=implied->num-1; i>=0; i--, space--) {
01898     v = *space;
01899     if(SATflags(v) & VisitedMask) {
01900       SATflags(v) &= ResetVisitedMask;
01901       --nMarked;
01902 
01903       if(nMarked == 0 && (!first || i==0))  {
01904         value = SATvalue(v);
01905         *fdaLit = v^(!value);
01906         sat_ArrayInsert(clauseArray, *fdaLit);
01907         break;
01908       }
01909 
01910 
01911       if(cm->option->coreGeneration){
01912         ante = SATante(v);
01913         if(ante==0){
01914           if(!(st_lookup(cm->anteTable, (char *)SATnormalNode(v),&ante))){
01915             printf("ante = 0 and is not in anteTable %ld\n",v);
01916             exit(0);
01917           }
01918         }
01919 
01920         /*build non-leaf node*/
01921         tmprt = RTCreateNode(rm);
01922         RT_pivot(tmprt) = SATnormalNode(v);
01923         RT_right(tmprt) = rm->root;
01924         rm->root = tmprt;
01925 
01926         if((SATflags(ante)&IsConflictMask)&&(SATflags(ante)&IsCNFMask)){
01927           if(!st_lookup(cm->RTreeTable,(char*)ante,&tmprt)){
01928             printf("RTree node of conflict cnf %ld is not in RTreeTable\n",ante);
01929             exit(0);
01930           }
01931           else{
01932             RT_left(rm->root) = tmprt;
01933 #if PR
01934             printf("Get formula for CONFLICT CLAUSE:%d\n",ante);
01935 #endif
01936           }
01937         }
01938         else{ /* if not conflict CNF*/
01939           /*left */
01940           tmprt = RTCreateNode(rm);
01941           RT_left(rm->root) = tmprt;
01942           /*left is AIG*/
01943           if(!(SATflags(ante) & IsCNFMask)){
01944             /*generate formula for left*/
01945             tmp = ALLOC(long,3);
01946             value = SATvalue(v);
01947             node = SATnormalNode(v);
01948             node = value==1?node:SATnot(node);
01949             tmp[0] = node;
01950 
01951             size = 1;
01952             if(ante != SATnormalNode(v)){
01953               value = SATvalue(ante);
01954               node = SATnormalNode(ante);
01955               node = value==1?SATnot(node):node;
01956               tmp[1] = node;
01957               size++;
01958               ante2 = SATante2(v);
01959               if(ante2){
01960                 value = SATvalue(ante2);
01961                 node = SATnormalNode(ante2);
01962                 node = value==1?SATnot(node):node;
01963                 tmp[2] = node;
01964                 size++;
01965               }
01966             }
01967 
01968             lp = tmp;
01969             sat_BuildRT(cm,tmprt,lp,tmpIP,size,1);
01970             FREE(tmp);
01971           }
01972           /* left is CNF*/
01973           else{
01974 
01975             lp = (long*)SATfirstLit(ante);
01976             size = SATnumLits(ante);
01977             RT_fSize(tmprt) = size;
01978             sat_BuildRT(cm,tmprt, lp, tmpIP,size,0);
01979           }
01980         } /*else{ // if not conflict CNF*/
01981 
01982       }/*if(cm->option->coreGeneration){*/
01983 
01984 
01985       sat_MarkNodeInImpliedNode(
01986               cm, d, v, &nMarked, objectFlag, bLevel, clauseArray);
01987     }
01988     first = 0;
01989   }
01990 
01991   sat_ResetFlagForClauseArray(cm, clauseArray);
01992 
01993   return;
01994 }
01995 
01996 
01997 
02010 void
02011 sat_MinimizeConflictClause(
02012         satManager_t *cm,
02013         satArray_t *clauseArray)
02014 {
02015 int i, j, size, all, tsize;
02016 int inverted;
02017 long v, tv;
02018 long ante, ante2;
02019 long *plit;
02020 satArray_t *newArray;
02021 satVariable_t *var;
02022 
02023   size = clauseArray->num;
02024   newArray = sat_ArrayAlloc(size);
02025   for(i=0; i<size; i++) {
02026     v = clauseArray->space[i];
02027     inverted = SATisInverted(v);
02028     v = SATnormalNode(v);
02029 
02030     ante = SATante(v);
02031     ante = SATnormalNode(ante);
02032     if(SATflags(ante) & IsCNFMask) {
02033       tsize = SATnumLits(ante);
02034       all = 1;
02035       for(j=0, plit=(long*)SATfirstLit(ante); j<tsize; j++, plit++) {
02036         tv = SATgetNode(*plit);
02037         tv = SATnormalNode(tv);
02038         if(tv == v)     continue;
02039         if(!(SATflags(tv) & NewMask)) {
02040           all = 0;
02041           break;
02042         }
02043       }
02044       if(all) {
02045         var = SATgetVariable(v);
02046         if(inverted)    (var->litsCount[1])++;
02047         else            (var->litsCount[0])++;
02048         continue;
02049       }
02050     }
02051     else {
02052       if(SATflags(ante) & NewMask) {
02053         ante2 = SATante2(v);
02054         ante2 = SATnormalNode(ante2);
02055         if((ante2==0) || (SATflags(ante2) & NewMask)) {
02056           var = SATgetVariable(v);
02057           if(inverted)  (var->litsCount[1])++;
02058           else          (var->litsCount[0])++;
02059           continue;
02060         }
02061       }
02062     }
02063     sat_ArrayInsert(newArray, v^inverted);
02064   }
02065   sat_ResetFlagForClauseArray(cm, clauseArray);
02066   memcpy(clauseArray->space, newArray->space, sizeof(long)*(newArray->num));
02067   clauseArray->num = newArray->num;
02068   sat_ArrayFree(newArray);
02069 }
02070 
02082 void
02083 sat_ResetFlagForClauseArray(
02084         satManager_t *cm,
02085         satArray_t *clauseArray)
02086 {
02087 int size, i;
02088 long v;
02089 
02090   size = clauseArray->num;
02091   for(i=0; i<size; i++) {
02092     v = clauseArray->space[i];
02093     v = SATnormalNode(v);
02094     SATflags(v) &= ResetNewVisitedMask;
02095   }
02096 }
02097 
02111 void
02112 sat_MarkNodeInConflict(
02113         satManager_t *cm,
02114         satLevel_t *d,
02115         int *nMarked,
02116         int *objectFlag,
02117         int *bLevel,
02118         satArray_t *clauseArray)
02119 {
02120 satOption_t *option;
02121 
02122   option = cm->option;
02123   if(option->incTraceObjective == 0) {
02124     sat_MarkNodeInConflictClauseNoObj(
02125         cm, d, nMarked, objectFlag, bLevel, clauseArray);
02126   }
02127   else if(option->incTraceObjective == 1) { /* conservative */
02128     sat_MarkNodeInConflictClauseObjConservative(
02129         cm, d, nMarked, objectFlag, bLevel, clauseArray);
02130   }
02131 }
02132 
02144 void
02145 sat_MarkNodeInImpliedNode(
02146         satManager_t *cm,
02147         satLevel_t *d,
02148         long v,
02149         int *nMarked,
02150         int *objectFlag,
02151         int *bLevel,
02152         satArray_t *clauseArray)
02153 {
02154 satOption_t *option;
02155 
02156   option = cm->option;
02157   if(option->incTraceObjective == 0) {
02158     sat_MarkNodeInImpliedNodeNoObj(
02159         cm, d, v, nMarked, objectFlag, bLevel, clauseArray);
02160   }
02161   else if(option->incTraceObjective == 1) { /* conservative */
02162     sat_MarkNodeInImpliedNodeObjConservative(
02163         cm, d, v, nMarked, objectFlag, bLevel, clauseArray);
02164   }
02165 }
02166 
02180 void
02181 sat_MarkNodeSub(
02182         satManager_t *cm,
02183         long v,
02184         int *nMarked,
02185         int *bLevel,
02186         satLevel_t *d,
02187         satArray_t *clauseArray)
02188 {
02189 satLevel_t *td;
02190 satOption_t *option;
02191 int value;
02192 
02193   v = SATnormalNode(v);
02194 
02195   td = SATgetDecision(SATlevel(v));
02196   if(d == td) {
02197     if(!(SATflags(v) & VisitedMask)) {
02198       (*nMarked)++;
02199       SATflags(v) |= VisitedMask;
02200     }
02201   }
02202   else if(td->level < d->level) {
02203     if(!(SATflags(v) & NewMask)) {
02204       option = cm->option;
02205       if((td->level != 0) ||
02206          (td->level == 0 && option->includeLevelZeroLiteral)) {
02207         SATflags(v) |= NewMask;
02208         value = SATvalue(v);
02209         sat_ArrayInsert(clauseArray, v^(!value));
02210         if(*bLevel < td->level)
02211           *bLevel = td->level;
02212       }
02213     }
02214   }
02215   return;
02216 }
02217 
02229 void
02230 sat_MarkNodeInImpliedNodeNoObj(
02231         satManager_t *cm,
02232         satLevel_t *d,
02233         long v,
02234         int *nMarked,
02235         int *oFlag,
02236         int *bLevel,
02237         satArray_t *clauseArray)
02238 {
02239 long ante, ante2, nv;
02240 int inverted, size, i;
02241 long *plit;
02242 satOption_t *option;
02243 
02244   ante= SATante(v);
02245   /* Bing: UNSAT core generation */
02246   if(cm->option->coreGeneration){
02247     if(ante==0){
02248       if(!(st_lookup(cm->anteTable, (char *)(long)SATnormalNode(v), &ante))){
02249         printf("ante = 0 and is not in anteTable %ld\n",v);
02250         exit(0);
02251       }
02252     }
02253   }
02254   inverted = SATisInverted(ante);
02255   ante= SATnormalNode(ante);
02256 
02257   option = cm->option;
02258   if(SATflags(ante) & IsCNFMask) {
02259     SATconflictUsage(ante)++;
02260     size = SATnumLits(ante);
02261     for(i=0, plit=(long*)SATfirstLit(ante); i<size; i++, plit++) {
02262       nv = SATgetNode(*plit);
02263       if((int)(SATnormalNode(nv)) == v) continue;
02264       sat_MarkNodeSub(cm, nv, nMarked, bLevel, d, clauseArray);
02265     }
02266   }
02267   else {
02268     /*Bing: very inmportant for level zero conflict analysis*/
02269     if(ante != SATnormalNode(v))
02270       sat_MarkNodeSub(cm, ante, nMarked, bLevel, d, clauseArray);
02271 
02272     ante2 = SATante2(v);
02273     if(ante2)
02274       sat_MarkNodeSub(cm, ante2, nMarked, bLevel, d, clauseArray);
02275   }
02276 }
02277 
02278 
02290 void
02291 sat_MarkNodeInImpliedNodeObjConservative(
02292         satManager_t *cm,
02293         satLevel_t *d,
02294         long v,
02295         int *nMarked,
02296         int *oFlag,
02297         int *bLevel,
02298         satArray_t *clauseArray)
02299 {
02300 long ante, ante2, nv;
02301 int inverted, size, i;
02302 int objectFlag;
02303 long *plit;
02304 satOption_t *option;
02305 
02306   ante= SATante(v);
02307   /* Bing: UNSAT core generation */
02308   if(cm->option->coreGeneration){
02309     if(ante==0){
02310       if(!(st_lookup(cm->anteTable, (char *)SATnormalNode(v), &ante))){
02311         printf("ante = 0 and is not in anteTable %ld\n",v);
02312         exit(0);
02313       }
02314     }
02315   }
02316   inverted = SATisInverted(ante);
02317   ante= SATnormalNode(ante);
02318 
02319   objectFlag = 0;
02320   option = cm->option;
02321   if(SATflags(ante) & IsCNFMask) {
02322     SATconflictUsage(ante)++;
02323     size = SATnumLits(ante);
02324     for(i=0, plit=(long*)SATfirstLit(ante); i<size; i++, plit++) {
02325       nv = SATgetNode(*plit);
02326       nv = SATnormalNode(nv);
02327       if(nv == v)       continue;
02328       sat_MarkNodeSub(cm, nv, nMarked, bLevel, d, clauseArray);
02329     }
02330     objectFlag |= SATflags(ante) & ObjMask;
02331   }
02332   else {
02333     /*Bing: very inmportant for level zero conflict analysis*/
02334     if(ante != SATnormalNode(v))
02335       sat_MarkNodeSub(cm, ante, nMarked, bLevel, d, clauseArray);
02336 
02337     ante2 = SATante2(v);
02338     if(ante2) {
02339       ante2 = SATnormalNode(ante2);
02340       sat_MarkNodeSub(cm, ante2, nMarked, bLevel, d, clauseArray);
02341     }
02342   }
02343   *oFlag |= objectFlag;
02344 }
02345 
02346 
02360 void
02361 sat_MarkNodeInConflictClauseNoObj(
02362         satManager_t *cm,
02363         satLevel_t *d,
02364         int *nMarked,
02365         int *oFlag,
02366         int *bLevel,
02367         satArray_t *clauseArray)
02368 {
02369 long conflict, left, right, nv;
02370 int inverted, size, value, i;
02371 long *plit;
02372 satOption_t *option;
02373 
02374   conflict = d->conflict;
02375   inverted = SATisInverted(conflict);
02376   conflict = SATnormalNode(conflict);
02377 
02378   option = cm->option;
02379   if(SATflags(conflict) & IsCNFMask) {
02380     size = SATnumLits(conflict);
02381     for(i=0, plit=(long*)SATfirstLit(conflict); i<size; i++, plit++) {
02382       nv = SATgetNode(*plit);
02383       sat_MarkNodeSub(cm, nv, nMarked, bLevel, d, clauseArray);
02384     }
02385   }
02386   else {
02387     value = SATvalue(conflict);
02388     if(value == 1) {
02389       sat_MarkNodeSub(cm, conflict, nMarked, bLevel, d, clauseArray);
02390 
02391       left = SATleftChild(conflict);
02392       inverted = SATisInverted(left);
02393       left = SATnormalNode(left);
02394       value = SATvalue(left) ^ inverted;
02395       if(value == 0) {
02396         sat_MarkNodeSub(cm, left, nMarked, bLevel, d, clauseArray);
02397         return;
02398       }
02399 
02400       right = SATrightChild(conflict);
02401       inverted = SATisInverted(right);
02402       right = SATnormalNode(right);
02403       value = SATvalue(right) ^ inverted;
02404       if(value == 0) {
02405         sat_MarkNodeSub(cm, right, nMarked, bLevel, d, clauseArray);
02406         return;
02407       }
02408     }
02409     else if(value == 0) {
02410       left = SATleftChild(conflict);
02411       right = SATrightChild(conflict);
02412       sat_MarkNodeSub(cm, conflict, nMarked, bLevel, d, clauseArray);
02413       sat_MarkNodeSub(cm, left, nMarked, bLevel, d, clauseArray);
02414       sat_MarkNodeSub(cm, right, nMarked, bLevel, d, clauseArray);
02415     }
02416   }
02417 }
02418 
02432 void
02433 sat_MarkNodeInConflictClauseObjConservative(
02434         satManager_t *cm,
02435         satLevel_t *d,
02436         int *nMarked,
02437         int *oFlag,
02438         int *bLevel,
02439         satArray_t *clauseArray)
02440 {
02441 long conflict, left, right, nv;
02442 int inverted, size, value, i;
02443 long *plit;
02444 satOption_t *option;
02445 
02446   conflict = d->conflict;
02447   inverted = SATisInverted(conflict);
02448   conflict = SATnormalNode(conflict);
02449 
02450   option = cm->option;
02451   if(SATflags(conflict) & IsCNFMask) {
02452     size = SATnumLits(conflict);
02453     for(i=0, plit=(long*)SATfirstLit(conflict); i<size; i++, plit++) {
02454       nv = SATgetNode(*plit);
02455       *oFlag |= (SATflags(nv) & ObjMask);
02456       sat_MarkNodeSub(cm, nv, nMarked, bLevel, d, clauseArray);
02457     }
02458   }
02459   else {
02460     value = SATvalue(conflict);
02461     if(value == 1) {
02462       *oFlag |= (SATflags(conflict) & ObjMask);
02463       sat_MarkNodeSub(cm, conflict, nMarked, bLevel, d, clauseArray);
02464 
02465       left = SATleftChild(conflict);
02466       inverted = SATisInverted(left);
02467       left = SATnormalNode(left);
02468       value = SATvalue(left) ^ inverted;
02469       if(value == 0) {
02470         *oFlag |= (SATflags(left) & ObjMask);
02471         sat_MarkNodeSub(cm, left, nMarked, bLevel, d, clauseArray);
02472         return;
02473       }
02474 
02475       right = SATrightChild(conflict);
02476       inverted = SATisInverted(right);
02477       right = SATnormalNode(right);
02478       value = SATvalue(right) ^ inverted;
02479       if(value == 0) {
02480         *oFlag |= (SATflags(right) & ObjMask);
02481         sat_MarkNodeSub(cm, right, nMarked, bLevel, d, clauseArray);
02482         return;
02483       }
02484     }
02485     else if(value == 0) {
02486       *oFlag |= (SATflags(conflict) & ObjMask);
02487 
02488       left = SATleftChild(conflict);
02489       inverted = SATisInverted(left);
02490       left = SATnormalNode(left);
02491       *oFlag |= (SATflags(left) & ObjMask);
02492 
02493       right = SATrightChild(conflict);
02494       inverted = SATisInverted(right);
02495       right = SATnormalNode(right);
02496       *oFlag |= (SATflags(right) & ObjMask);
02497 
02498       sat_MarkNodeSub(cm, conflict, nMarked, bLevel, d, clauseArray);
02499       sat_MarkNodeSub(cm, left, nMarked, bLevel, d, clauseArray);
02500       sat_MarkNodeSub(cm, right, nMarked, bLevel, d, clauseArray);
02501     }
02502   }
02503 }
02504 
02505 
02517 void
02518 sat_Backtrack(
02519         satManager_t *cm,
02520         int level)
02521 {
02522 satLevel_t *d;
02523 
02524 /*Bing*/
02525  if(cm->option->ForceFinish == 0)
02526    if(level < 0)        return;
02527 
02528   d = SATgetDecision(cm->currentDecision);
02529   while(1) {
02530     if(d->level <= level)
02531       break;
02532 
02533     sat_Undo(cm, d);
02534     cm->currentDecision--;
02535     if(cm->currentDecision == -1)
02536       break;
02537     d = SATgetDecision(cm->currentDecision);
02538   }
02539   return;
02540 }
02541 
02542 
02554 void
02555 sat_Undo(
02556         satManager_t *cm,
02557         satLevel_t *d)
02558 {
02559 satArray_t *implied, *satisfied;
02560 satVariable_t *var;
02561 int size, i;
02562 long *space, v;
02563 
02564   implied = d->implied;
02565   space = implied->space;
02566   size = implied->num;
02567   for(i=0; i<size; i++, space++) {
02568     v = *space;
02569 
02570     SATvalue(v) = 2;
02571     SATflags(v) &= ResetNewVisitedObjInQueueMask;
02572     var = &(cm->variableArray[SATnodeID(v)]);
02573     var->antecedent = 0;
02574     var->antecedent2 = 0;
02575     var->level = -1;
02576     var->depth = 0;
02577   }
02578 
02579   cm->implicatedSoFar -= size;
02580 
02581   if(d->satisfied) {
02582     satisfied = d->implied;
02583     space = satisfied->space;
02584     size = satisfied->num;
02585     for(i=0; i<size; i++, space++) {
02586       v = *space;
02587 
02588       SATflags(v) &= ResetBDDSatisfiedMask;
02589     }
02590     d->satisfied->num = 0;
02591   }
02592   if(d->level > 0) {
02593     if((cm->decisionHead[d->level-1]).currentVarPos < cm->currentVarPos)
02594       cm->currentVarPos = (cm->decisionHead[d->level-1]).currentVarPos;
02595   }
02596   else
02597     cm->currentVarPos = d->currentVarPos;
02598 
02599   d->implied->num = 0;
02600   d->currentVarPos = 0;
02601   d->conflict = 0;
02602 
02603 
02604 }
02605 
02618 static int
02619 levelCompare(
02620   const void * node1,
02621   const void * node2)
02622 {
02623   long v1, v2;
02624   int l1, l2;
02625 
02626   v1 = *(int *)(node1);
02627   v2 = *(int *)(node2);
02628   l1 = SATcm->variableArray[SATnodeID(v1)].level;
02629   l2 = SATcm->variableArray[SATnodeID(v2)].level;
02630 
02631   if(l1 == l2)  return(v1 > v2);
02632   return (l1 > l2);
02633 }