VIS
|
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 }