VIS
|
00001 00019 #include "satInt.h" 00020 00021 static char rcsid[] UNUSED = "$Id: satDecision.c,v 1.28 2009/04/11 18:26:37 fabio Exp $"; 00022 static satManager_t *SatCm; 00023 00024 /*---------------------------------------------------------------------------*/ 00025 /* Constant declarations */ 00026 /*---------------------------------------------------------------------------*/ 00027 00030 /*---------------------------------------------------------------------------*/ 00031 /* Static function prototypes */ 00032 /*---------------------------------------------------------------------------*/ 00033 00034 static int ScoreCompare(const void * node1, const void * node2); 00035 00039 /*---------------------------------------------------------------------------*/ 00040 /* Definition of exported functions */ 00041 /*---------------------------------------------------------------------------*/ 00042 00043 00055 satLevel_t * 00056 sat_MakeDecision(satManager_t *cm) 00057 { 00058 satLevel_t *d; 00059 int value; 00060 long v; 00061 satStatistics_t *stats; 00062 00063 d = SATgetDecision(cm->currentDecision); 00064 00065 if(cm->queue->size) 00066 return(d); 00067 00068 d = sat_AllocLevel(cm); 00069 00070 v = 0; 00071 v = sat_DecisionBasedOnBDD(cm, d); 00072 00073 if(v == 0) 00074 v = sat_DecisionBasedOnLatestConflict(cm, d); 00075 00076 if(v == 0) 00077 v = sat_DecisionBasedOnScore(cm, d); 00078 00079 if(v == 0) 00080 return(0); 00081 00082 00083 stats = cm->each; 00084 00085 stats->nDecisions++; 00086 00087 value = !(SATisInverted(v)); 00088 v = SATnormalNode(v); 00089 d->decisionNode = v; 00090 d->nConflict = cm->each->nConflictCl; 00091 00092 SATvalue(v) = value; 00102 SATmakeImplied(v, d); 00103 00104 sat_Enqueue(cm->queue, v); 00105 SATflags(v) |= InQueueMask; 00106 00107 return(d); 00108 } 00109 00110 00122 long 00123 sat_DecisionBasedOnLatestConflict( 00124 satManager_t *cm, 00125 satLevel_t *d) 00126 { 00127 satOption_t *option; 00128 satStatistics_t *stats; 00129 satLiteralDB_t *literals; 00130 satVariable_t *var; 00131 int size, limit; 00132 long *plit, *tplit; 00133 long v, lit, tv, maxV; 00134 int tsize, count; 00135 int inverted, value; 00136 int i, j, satisfied; 00137 int tmpScore, maxScore; 00138 00139 option = cm->option; 00140 stats = cm->each; 00141 00142 if(!(option->decisionHeuristic & LATEST_CONFLICT_DECISION)) 00143 return(0); 00144 00152 if(cm->currentTopConflict == 0) 00153 return(0); 00154 00155 literals = cm->literals; 00156 size = literals->last - literals->begin; 00157 00158 limit = MAXINT; 00159 if(option->maxConflictForDecision > 0) 00160 limit = option->maxConflictForDecision; 00161 00162 count = cm->currentTopConflictCount; 00163 tv = -(*(cm->currentTopConflict)); 00164 tsize = SATnumLits(tv); 00165 tplit = (long*)SATfirstLit(tv); 00166 plit = tplit + tsize; 00167 00168 for(i=plit-literals->begin; i>=0; i--, plit--) { 00170 if(count > limit) break; 00171 00172 lit = *plit; 00173 if(lit < 0) { 00174 tv = -lit; 00175 00176 if(!(SATflags(tv) & IsConflictMask)) 00177 return(0); 00178 00179 if(plit < (long*)SATfirstLit(tv)) 00180 continue; 00181 00182 count++; 00183 00184 if(option->skipSatisfiedClauseForDecision) { 00185 tsize = SATnumLits(tv); 00186 tplit = (long *)SATfirstLit(tv); 00187 satisfied = 0; 00188 maxScore = -1; 00189 maxV = 0; 00190 for(j=0; j<tsize; j++, tplit++) { 00191 v = SATgetNode(*tplit); 00192 inverted = SATisInverted(v); 00193 v = SATnormalNode(v); 00194 value = SATvalue(v) ^ inverted; 00195 if(value == 1) { 00196 satisfied = 1; 00197 break; 00198 } 00199 else if(value == 0) { 00200 continue; 00201 } 00202 var = SATgetVariable(v); 00203 tmpScore = (var->scores[0] >= var->scores[1]) ? var->scores[0] : var->scores[1]; 00204 if(tmpScore > maxScore) { 00205 maxScore = tmpScore; 00206 maxV = v; 00207 } 00208 } 00209 if(satisfied) { 00210 i = i - tsize - 1; 00211 plit = plit - tsize -1; 00212 } 00213 else { 00214 var = SATgetVariable(maxV); 00215 value = (var->scores[0] >= var->scores[1]) ? 0 : 1; 00216 00217 cm->currentTopConflict = (long*)SATfirstLit(tv) + SATnumLits(tv); 00218 cm->currentTopConflictCount = count; 00219 00220 stats = cm->each; 00221 stats->nLatestConflictDecisions++; 00222 return(maxV ^ !value); 00223 } 00224 } 00225 continue; 00226 } 00227 else if(lit == 0) 00228 continue; 00229 00230 v = SATgetNode(lit); 00231 inverted = SATisInverted(v); 00232 v = SATnormalNode(v); 00233 value = SATvalue(v) ^ inverted; 00234 00235 if(value >= 2) { 00236 var = SATgetVariable(v); 00237 value = (var->conflictLits[0] >= var->conflictLits[1]) ? 0 : 1; 00238 00239 cm->currentTopConflict = (long*)SATfirstLit(tv) + SATnumLits(tv); 00240 cm->currentTopConflictCount = count; 00241 00242 stats = cm->each; 00243 stats->nLatestConflictDecisions++; 00244 return(v ^ !value); 00245 } 00246 } 00247 return(0); 00248 } 00249 00265 void 00266 sat_CheckDecisonVariableArray( 00267 satManager_t *cm) 00268 { 00269 satArray_t *orderedVariableArray; 00270 int size, i; 00271 long v; 00272 00273 orderedVariableArray = cm->orderedVariableArray; 00274 size = orderedVariableArray->num; 00275 for(i=0; i<cm->currentVarPos; i++) { 00276 v = orderedVariableArray->space[i]; 00277 if(SATvalue(v) > 1) { 00278 fprintf(stdout, " ERROR : wrong current variable pos %d at %d\n", 00279 cm->currentVarPos, i); 00280 } 00281 } 00282 } 00283 00295 long 00296 sat_DecisionBasedOnScore( 00297 satManager_t *cm, 00298 satLevel_t *d) 00299 { 00300 int size, i; 00301 long v; 00302 int value; 00303 satVariable_t *var; 00304 satArray_t *orderedVariableArray; 00305 satStatistics_t *stats; 00306 satOption_t *option; 00307 00308 00309 option = cm->option; 00310 orderedVariableArray = cm->orderedVariableArray; 00311 size = orderedVariableArray->num; 00312 00313 for(i=cm->currentVarPos; i<size; i++) { 00314 v = orderedVariableArray->space[i]; 00315 if(SATvalue(v) < 2) continue; 00316 00317 var = SATgetVariable(v); 00318 value = (var->scores[0] >= var->scores[1]) ? 0 : 1; 00319 00320 stats = cm->each; 00321 if((var->scores[0]+var->scores[1]) < 1) { 00322 stats->nLowScoreDecisions++; 00323 } 00324 00325 00326 if((option->decisionHeuristic & DVH_DECISION)) 00327 stats->nDVHDecisions++; 00328 else 00329 stats->nVSIDSDecisions++; 00330 00331 cm->currentVarPos = i; 00332 d->currentVarPos = i; 00333 00334 return(v ^ !value); 00335 } 00336 00337 return(0); 00338 } 00339 00351 long 00352 sat_DecisionBasedOnBDD( 00353 satManager_t *cm, 00354 satLevel_t *d) 00355 { 00356 satArray_t *arr; 00357 long nv, v; 00358 00359 if(cm->assignByBDD == 0) 00360 return(0); 00361 00362 arr = cm->assignByBDD; 00363 if(arr->num == 0) 00364 return(0); 00365 00375 while(arr->num) { 00376 v = arr->space[arr->num-1]; 00377 nv = SATnormalNode(v); 00378 arr->num--; 00379 if(SATvalue(nv) > 1) 00380 return(v); 00381 } 00382 return(0); 00383 } 00384 00385 00386 long 00387 sat_DecisionBasedOnShrink( 00388 satManager_t *cm) 00389 { 00390 satArray_t *arr; 00391 long nv, v; 00392 00393 if(cm->shrinkArray == 0) 00394 return(0); 00395 00396 arr = cm->shrinkArray; 00397 if(arr->num == 0) 00398 return(0); 00399 00400 while(arr->num) { 00401 v = arr->space[arr->num-1]; 00402 nv = SATnormalNode(v); 00403 arr->num--; 00404 if(SATvalue(nv) > 1) 00405 return(v); 00406 } 00407 return(0); 00408 } 00409 00410 00422 void 00423 sat_UpdateScore( 00424 satManager_t *cm) 00425 { 00426 satArray_t *one, *tmp; 00427 satArray_t *ordered; 00428 satVariable_t *var; 00429 int size, i; 00430 long v; 00431 int value; 00432 00433 ordered = cm->orderedVariableArray; 00434 00435 one = sat_ArrayAlloc(ordered->num); 00436 tmp = sat_ArrayAlloc(ordered->num); 00437 00438 size = ordered->num; 00439 for(i=0; i<size; i++) { 00440 v = ordered->space[i]; 00441 00442 if(SATvalue(v) < 2 && SATlevel(v) == 0) 00443 continue; 00444 00445 var = SATgetVariable(v); 00446 var->scores[0] = (var->scores[0]>>1) + var->litsCount[0] - var->lastLitsCount[0]; 00447 var->scores[1] = (var->scores[1]>>1) + var->litsCount[1] - var->lastLitsCount[1]; 00448 var->lastLitsCount[0] = var->litsCount[0]; 00449 var->lastLitsCount[1] = var->litsCount[1]; 00450 00451 00452 if((var->scores[0] + var->scores[1]) < 1) { 00453 sat_ArrayInsert(one, v); 00454 } 00455 else { 00456 value = (var->scores[0] > var->scores[1]) ? var->scores[0] : var->scores[1]; 00457 sat_ArrayInsert(tmp, v); 00458 sat_ArrayInsert(tmp, value); 00459 } 00460 } 00461 00462 SatCm = cm; 00463 qsort(tmp->space, (tmp->num)>>1, sizeof(long)*2, ScoreCompare); 00464 00465 ordered->num = 0; 00466 size = tmp->num; 00467 for(i=0; i<size; i++) { 00468 v = tmp->space[i]; 00469 sat_ArrayInsert(ordered, v); 00470 var = SATgetVariable(v); 00471 var->pos = (i>>1); 00472 i++; 00473 } 00474 00475 size = one->num; 00476 for(i=0; i<size; i++) { 00477 v = one->space[i]; 00478 var = SATgetVariable(v); 00479 var->pos = ordered->num; 00480 sat_ArrayInsert(ordered, v); 00481 } 00482 00483 sat_ArrayFree(one); 00484 sat_ArrayFree(tmp); 00485 00486 cm->orderedVariableArray = ordered; 00487 cm->currentVarPos = 0; 00488 00489 for(i=1; i<cm->currentDecision; i++) { 00490 cm->decisionHead[i].currentVarPos = 0; 00491 } 00492 00493 if(cm->option->verbose > 3) 00494 sat_PrintScore(cm); 00495 00496 } 00497 00498 00510 void 00511 sat_UpdateDVH( 00512 satManager_t *cm, 00513 satLevel_t *d, 00514 satArray_t *clauseArray, 00515 int bLevel, 00516 long unitLit) 00517 { 00518 satArray_t *ordered; 00519 satLevel_t *td; 00520 satVariable_t *var, *tvar, *ttvar; 00521 int score, tscore, ttscore; 00522 int value; 00523 long v; 00524 int gap, i, insert; 00525 00526 00527 ordered = cm->orderedVariableArray; 00528 00529 unitLit = SATnormalNode(unitLit); 00530 gap = cm->currentDecision - bLevel; 00531 td = SATgetDecision(bLevel+1); 00532 00533 if(gap <= 1) { 00535 } 00536 var = SATgetVariable(unitLit); 00537 tvar = SATgetVariable(td->decisionNode); 00538 00539 score = (var->scores[1] > var->scores[0]) ? var->scores[1] : var->scores[0]; 00540 tscore = (tvar->scores[1] > tvar->scores[0]) ? tvar->scores[1] : tvar->scores[0]; 00541 00542 if(score >= tscore) { 00543 return; 00544 } 00545 00546 tscore += 1; 00547 00548 value = SATvalue(unitLit); 00549 if(value == 0)var->scores[1] = tscore; 00550 else var->scores[0] = tscore; 00551 00552 ordered = cm->orderedVariableArray; 00553 insert = 0; 00554 for(i=var->pos; i>=1; i--) { 00555 v = ordered->space[i-1]; 00556 ttvar = SATgetVariable(v); 00557 ttscore = (ttvar->scores[1] > ttvar->scores[0]) ? ttvar->scores[1] : ttvar->scores[0]; 00558 if(tscore > ttscore && i>1) { 00559 ttvar->pos = i; 00560 ordered->space[i] = v; 00561 continue; 00562 } 00563 00564 var->pos = i; 00565 ordered->space[i] = unitLit; 00566 insert = 1; 00567 break; 00568 } 00569 00570 if(insert == 0) { 00571 var->pos = i; 00572 ordered->space[0] = unitLit; 00573 } 00574 00575 for(i=d->level; i>0; i--) { 00576 td = SATgetDecision(i); 00577 if(td->currentVarPos < var->pos) 00578 break; 00579 td->currentVarPos = var->pos; 00580 } 00581 cm->currentVarPos = td->currentVarPos; 00582 00583 } 00584 00596 void 00597 sat_CheckOrderedVariableArray(satManager_t *cm) 00598 { 00599 satArray_t *ordered; 00600 satVariable_t *var; 00601 int i; 00602 long v; 00603 00604 ordered = cm->orderedVariableArray; 00605 for(i=0; i<ordered->num; i++) { 00606 v = ordered->space[i]; 00607 var = SATgetVariable(v); 00608 if(i != var->pos) { 00609 fprintf(cm->stdOut, "Error : wrong variable position %d %d in ordered array\n", i, var->pos); 00610 00611 } 00612 } 00613 } 00614 00626 void 00627 sat_InitScore(satManager_t *cm) 00628 { 00629 int objExist; 00630 int j, inverted; 00631 long *plit, v, nv, i; 00632 int size; 00633 int count0, count1; 00634 satArray_t *ordered, *newOrdered; 00635 satVariable_t *var; 00636 00637 ordered = cm->orderedVariableArray; 00638 if(ordered == 0) 00639 ordered = sat_ArrayAlloc(cm->initNumVariables); 00640 else 00641 ordered->num = 0; 00642 cm->orderedVariableArray = ordered; 00643 00644 objExist = 0; 00653 for(i=satNodeSize; i<cm->nodesArraySize; i+=satNodeSize) { 00654 v = i; 00655 if((SATflags(v) & IsBDDMask)) { 00656 continue; 00657 } 00658 if((SATflags(v) & IsCNFMask)) { 00659 size = SATnumLits(v); 00660 plit = (long*)SATfirstLit(v); 00661 for(j=0; j<size; j++, plit++) { 00662 nv = SATgetNode(*plit); 00663 inverted = !(SATisInverted(nv)); 00664 nv = SATnormalNode(nv); 00665 var = SATgetVariable(nv); 00666 var->litsCount[inverted]++; 00667 } 00668 continue; 00669 } 00670 if(!(SATflags(v) & CoiMask)) continue; 00671 if(!(SATflags(v) & VisitedMask) && objExist) continue; 00672 00673 if(SATvalue(v) != 2 && SATlevel(v) == 0) continue; 00674 00675 count0 = count1 = SATnFanout(v); 00676 if(count0 == 0 && SATleftChild(v) == 2 && SATrightChild(v) == 2) { 00677 count0 = 0; 00678 count1 = 0; 00679 } 00680 else if(SATleftChild(v) != 2) { 00681 count0 += 2; 00682 count1++; 00683 } 00684 else { 00685 count0 += 3; 00686 count1 += 3; 00687 } 00688 00689 var = SATgetVariable(v); 00690 var->litsCount[0] += count0; 00691 var->litsCount[1] += count1; 00692 00693 sat_ArrayInsert(ordered, v); 00694 } 00695 00696 //Bing: 00697 if(cm->unitLits){ 00698 for(i=0; i<cm->unitLits->num; i++) { 00699 v = cm->unitLits->space[i]; 00700 v = SATnormalNode(v); 00701 SATflags(v) |= NewMask; 00702 } 00703 } 00704 00705 if(cm->assertion) { 00706 for(i=0; i<cm->assertion->num; i++) { 00707 v = cm->assertion->space[i]; 00708 v = SATnormalNode(v); 00709 SATflags(v) |= NewMask; 00710 } 00711 } 00712 00713 newOrdered = sat_ArrayAlloc((ordered->num) * 2); 00714 size = ordered->num; 00715 for(i=0; i<size; i++) { 00716 v = ordered->space[i]; 00717 var = SATgetVariable(v); 00718 var->scores[0] = var->lastLitsCount[0] = var->litsCount[0]; 00719 var->scores[1] = var->lastLitsCount[1] = var->litsCount[1]; 00720 00721 if(SATflags(v) & NewMask); 00722 else if(var->scores[0] == 0 && var->scores[1] == 0 && !(SATflags(v) & NewMask)) { 00723 sat_ArrayInsert(cm->pureLits, (v)); 00724 } 00725 else if(var->scores[0] == 0 && !(SATflags(v) & NewMask)) { 00726 sat_ArrayInsert(cm->pureLits, (v)); 00727 } 00728 else if(var->scores[1] == 0 && !(SATflags(v) & NewMask)) { 00729 sat_ArrayInsert(cm->pureLits, SATnot(v)); 00730 } 00731 else { 00732 sat_ArrayInsert(newOrdered, v); 00733 sat_ArrayInsert(newOrdered, (var->scores[0] > var->scores[1]) ? var->scores[0] : var->scores[1]); 00734 } 00735 } 00736 00737 //Bing: 00738 if(cm->unitLits){ 00739 for(i=0; i<cm->unitLits->num; i++) { 00740 v = cm->unitLits->space[i]; 00741 v = SATnormalNode(v); 00742 SATflags(v) &= ResetNewMask; 00743 } 00744 } 00745 00746 if(cm->assertion) { 00747 for(i=0; i<cm->assertion->num; i++) { 00748 v = cm->assertion->space[i]; 00749 v = SATnormalNode(v); 00750 SATflags(v) &= ResetNewMask; 00751 } 00752 } 00753 00754 cm->orderedVariableArray = ordered; 00755 size = newOrdered->num; 00756 qsort(newOrdered->space, size>>1, sizeof(long)*2, ScoreCompare); 00757 00758 cm->currentVarPos = 0; 00759 ordered->num = 0; 00760 for(i=0; i<size; i++) { 00761 v = newOrdered->space[i]; 00762 var = SATgetVariable(v); 00763 var->pos = (i>>1); 00764 sat_ArrayInsert(ordered, v); 00765 i++; 00766 } 00767 00768 sat_ArrayFree(newOrdered); 00769 00777 if(cm->option->verbose > 3) 00778 sat_PrintScore(cm); 00779 } 00780 00792 void 00793 sat_InitScoreForMixed(satManager_t *cm) 00794 { 00795 int j, inverted; 00796 long *plit, v, nv, i; 00797 int size; 00798 int count0, count1; 00799 satArray_t *ordered, *newOrdered; 00800 satVariable_t *var; 00801 00802 ordered = cm->orderedVariableArray; 00803 if(ordered == 0) 00804 ordered = sat_ArrayAlloc(cm->initNumVariables); 00805 else 00806 ordered->num = 0; 00807 cm->orderedVariableArray = ordered; 00808 00818 for(i=satNodeSize; i<cm->nodesArraySize; i+=satNodeSize) { 00819 v = i; 00820 if((SATflags(v) & IsBDDMask)) { 00821 continue; 00822 } 00823 if((SATflags(v) & IsCNFMask)) { 00824 size = SATnumLits(v); 00825 plit =(long*) SATfirstLit(v); 00826 for(j=0; j<size; j++, plit++) { 00827 nv = SATgetNode(*plit); 00828 inverted = !(SATisInverted(nv)); 00829 nv = SATnormalNode(nv); 00830 var = SATgetVariable(nv); 00831 var->litsCount[inverted]++; 00832 } 00833 continue; 00834 } 00835 if(!(SATflags(v) & CoiMask)) continue; 00840 if(SATvalue(v) != 2 && SATlevel(v) == 0) continue; 00841 00842 count0 = count1 = SATnFanout(v); 00843 if(count0 == 0 && SATleftChild(v) == 2 && SATrightChild(v) == 2) { 00844 count0 = 0; 00845 count1 = 0; 00846 } 00847 else if(SATleftChild(v) != 2) { 00848 count0 += 2; 00849 count1++; 00850 } 00851 else { 00852 count0 += 3; 00853 count1 += 3; 00854 } 00855 00856 var = SATgetVariable(v); 00857 var->litsCount[0] += count0; 00858 var->litsCount[1] += count1; 00859 00860 sat_ArrayInsert(ordered, v); 00861 } 00862 00863 for(i=0; i<cm->unitLits->num; i++) { 00864 v = cm->unitLits->space[i]; 00865 v = SATnormalNode(v); 00866 SATflags(v) |= NewMask; 00867 } 00868 if(cm->assertion) { 00869 for(i=0; i<cm->assertion->num; i++) { 00870 v = cm->assertion->space[i]; 00871 v = SATnormalNode(v); 00872 SATflags(v) |= NewMask; 00873 } 00874 } 00875 00876 newOrdered = sat_ArrayAlloc((ordered->num) * 2); 00877 size = ordered->num; 00878 for(i=0; i<size; i++) { 00879 v = ordered->space[i]; 00880 var = SATgetVariable(v); 00881 var->scores[0] = var->lastLitsCount[0] = var->litsCount[0]; 00882 var->scores[1] = var->lastLitsCount[1] = var->litsCount[1]; 00883 00884 if(SATflags(v) & NewMask); 00885 else if(var->scores[0] == 0 && var->scores[1] == 0 && !(SATflags(v) & NewMask)) { 00886 sat_ArrayInsert(cm->pureLits, (v)); 00887 } 00888 else if(var->scores[0] == 0 && !(SATflags(v) & NewMask)) { 00889 sat_ArrayInsert(cm->pureLits, (v)); 00890 } 00891 else if(var->scores[1] == 0 && !(SATflags(v) & NewMask)) { 00892 sat_ArrayInsert(cm->pureLits, SATnot(v)); 00893 } 00894 else { 00895 sat_ArrayInsert(newOrdered, v); 00896 sat_ArrayInsert(newOrdered, (var->scores[0] > var->scores[1]) ? var->scores[0] : var->scores[1]); 00897 } 00898 } 00899 00900 for(i=0; i<cm->unitLits->num; i++) { 00901 v = cm->unitLits->space[i]; 00902 v = SATnormalNode(v); 00903 SATflags(v) &= ResetNewMask; 00904 } 00905 if(cm->assertion) { 00906 for(i=0; i<cm->assertion->num; i++) { 00907 v = cm->assertion->space[i]; 00908 v = SATnormalNode(v); 00909 SATflags(v) &= ResetNewMask; 00910 } 00911 } 00912 00913 cm->orderedVariableArray = ordered; 00914 size = newOrdered->num; 00915 qsort(newOrdered->space, size>>1, sizeof(long)*2, ScoreCompare); 00916 00917 cm->currentVarPos = 0; 00918 ordered->num = 0; 00919 for(i=0; i<size; i++) { 00920 v = newOrdered->space[i]; 00921 var = SATgetVariable(v); 00922 var->pos = (i>>1); 00923 sat_ArrayInsert(ordered, v); 00924 i++; 00925 } 00926 00927 sat_ArrayFree(newOrdered); 00928 00936 if(cm->option->verbose > 3) 00937 sat_PrintScore(cm); 00938 00939 } 00951 static int 00952 ScoreCompare( 00953 const void * node1, 00954 const void * node2) 00955 { 00956 int v1; 00957 int v2; 00958 int s1, s2; 00959 00960 v1 = *(int *)(node1); 00961 v2 = *(int *)(node2); 00962 s1 = *((int *)(node1) + 1); 00963 s2 = *((int *)(node2) + 1); 00970 if(s1 == s2) { 00971 return(v1 > v2); 00972 } 00973 return(s1 < s2); 00974 }