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