VIS
|
00001 00019 #include "satInt.h" 00020 #ifdef BDDcu 00021 #include "cuddInt.h" 00022 #endif 00023 00024 static char rcsid[] UNUSED = "$Id: satBDD.c,v 1.30 2009/04/11 18:26:37 fabio Exp $"; 00025 00026 /*---------------------------------------------------------------------------*/ 00027 /* Constant declarations */ 00028 /*---------------------------------------------------------------------------*/ 00029 00030 #ifdef BDDcu 00031 00033 /*---------------------------------------------------------------------------*/ 00034 /* Static function prototypes */ 00035 /*---------------------------------------------------------------------------*/ 00036 00037 static int heapCostCompare(const void *c1, const void *c2); 00038 static int sat_ConvertCNF2BDD(satManager_t *cm, DdManager *mgr, int conflictFlag); 00039 static void sat_FreeLinearHead(satLinearHead_t *head); 00040 static int linearVarCompare(const void * node1, const void * node2); 00041 static int linearElemCompare(const void * node1, const void * node2); 00042 static void sat_GetArrangementByForce(satManager_t *cm, satLinearHead_t *head); 00043 static int sat_PrintCutProfile(satManager_t *cm, satLinearHead_t *head, char *baseName, int printFlag); 00044 static int sat_ClusteringElementMain(satManager_t *cm, satLinearHead_t *head); 00045 static void sat_ComputeVariableRange(satManager_t *cm, satLinearHead_t *head); 00046 static void sat_InitClusteringElement(satManager_t *cm, satLinearHead_t *head); 00047 static void sat_PrintSupportVariable(satLinearHead_t *head, satLinearElem_t *e1); 00048 static void sat_ClusteringGetCandidate(satManager_t *cm, satLinearHead_t *head); 00049 static DdNode *sat_SmoothWithDeadVariable(DdManager *mgr, satArray_t *deadArray, DdNode *bdd1, DdNode *bdd2, int bddAndLimit); 00050 static int sat_ClusteringElement(satManager_t *cm, satLinearHead_t *head); 00051 static void sat_FreeCluster(DdManager *mgr, satLinearCluster_t *clu); 00052 static void sat_CheckDeadNode(satLinearHead_t *head, satLinearCluster_t *clu); 00053 00055 #endif 00056 00057 00058 /*---------------------------------------------------------------------------*/ 00059 /* Definition of exported functions */ 00060 /*---------------------------------------------------------------------------*/ 00061 00062 #ifdef BDDcu 00063 00077 void 00078 sat_TryToBuildMonolithicBDD(satManager_t *cm) 00079 { 00080 DdManager *mgr; 00081 int nVariables, flag; 00082 00083 nVariables = cm->initNumVariables - cm->implicatedSoFar; 00084 00085 if(nVariables 00086 > cm->option->maxLimitOfVariablesForMonolithicBDD) return; 00087 00088 mgr = Cudd_Init((unsigned int)(nVariables+1), 0, CUDD_UNIQUE_SLOTS, 00089 CUDD_CACHE_SLOTS, getSoftDataLimit() / 10 * 9); 00090 cm->mgr = mgr; 00091 flag = sat_ConvertCNF2BDD(cm, mgr, 0); 00092 00093 Cudd_Quit(mgr); 00094 cm->mgr = 0; 00095 00096 if(flag == SAT_BDD_UNSAT) 00097 cm->status = SAT_UNSAT; 00098 00099 return; 00100 } 00101 00102 00114 DdNode * 00115 sat_CofactorBDDArray( 00116 satLinearHead_t *head, 00117 DdManager *mgr, 00118 DdNode *l1, 00119 satArray_t *satArr) 00120 { 00121 int i, vid, inverted; 00122 long v; 00123 DdNode *bdd, *result, *nresult; 00124 satLinearVar_t *var; 00125 00126 result = l1; 00127 cuddRef(result); 00128 for(i=0; i<satArr->num; i++) { 00129 v = satArr->space[i]; 00130 inverted = SATisInverted(v); 00131 v = SATnormalNode(v); 00132 vid = head->edge2vid[SATnodeID(v)]; 00133 var = &(head->varHead[vid]); 00134 bdd = inverted ? Cudd_Not(var->bdd) : var->bdd; 00135 00136 nresult = Cudd_bddConstrain(mgr, result, bdd); 00137 cuddRef(nresult); 00138 Cudd_RecursiveDeref(mgr, result); 00139 result = nresult; 00140 } 00141 return(result); 00142 } 00143 00157 void 00158 sat_ExtractAssignmentFromBDD( 00159 satLinearHead_t *head, 00160 DdManager *mgr, 00161 satArray_t *arr, 00162 DdNode *cube) 00163 { 00164 DdNode *C, *T, *E, *zero; 00165 00166 C = Cudd_Regular(cube); 00167 zero = Cudd_Not(DD_ONE(mgr)); 00168 if (!cuddIsConstant(C)) { 00169 while (!cuddIsConstant(C)) { 00170 T = cuddT(C); 00171 E = cuddE(C); 00172 if (Cudd_IsComplement(cube)) { 00173 T = Cudd_Not(T); 00174 E = Cudd_Not(E); 00175 } 00176 if (T == zero) { 00177 sat_ArrayInsert(arr, ((head->id2edge[C->index]) + 1)); 00178 cube = E; 00179 } 00180 else { 00181 sat_ArrayInsert(arr, (head->id2edge[C->index])); 00182 cube = T; 00183 } 00184 C = Cudd_Regular(cube); 00185 } 00186 } 00187 return; 00188 } 00189 00190 00202 satLinearHead_t * 00203 sat_CreateLinearHead( 00204 satManager_t *cm, 00205 int conflictFlag) 00206 { 00207 satLinearHead_t *head; 00208 satLinearElem_t *elem; 00209 satLinearVar_t *lvar; 00210 satArray_t *cArray, *vArray; 00211 int nVars, nCls, varId; 00212 int j, size, satisfied, inverted; 00213 int value; 00214 long v, *plit, i; 00215 int elemIndex, varIndex; 00216 int clauseLimit; 00217 00218 nVars = 0; 00219 nCls = 0; 00220 cArray = sat_ArrayAlloc(1024); 00221 vArray = sat_ArrayAlloc(1024); 00222 for(i=satNodeSize; i<cm->initNodesArraySize; i+=satNodeSize) { 00223 if(!(SATflags(i) & IsCNFMask)) continue; 00224 if(SATreadInUse(i) == 0) continue; 00226 size = SATnumLits(i); 00227 satisfied = 0; 00228 plit = (long *)SATfirstLit(i); 00229 for(j=0; j<size; j++, plit++) { 00230 v = SATgetNode(*plit); 00231 inverted = SATisInverted(v); 00232 v = SATnormalNode(v); 00233 value = SATvalue(v) ^ inverted; 00234 if(value == 1) { 00235 satisfied = 1; 00236 break; 00237 } 00238 } 00239 if(satisfied) continue; 00240 00241 nCls++; 00242 SATflags(i) |= VisitedMask; 00243 sat_ArrayInsert(cArray, i); 00244 00245 plit = (long *)SATfirstLit(i); 00246 for(j=0; j<size; j++, plit++) { 00247 v = SATgetNode(*plit); 00248 v = SATnormalNode(v); 00249 if(SATvalue(v) < 2) continue; 00250 if(!(SATflags(v) & VisitedMask)) { 00251 nVars++; 00252 SATflags(v) |= VisitedMask; 00253 sat_ArrayInsert(vArray, v); 00254 } 00255 } 00256 } 00257 00258 if(conflictFlag) 00259 clauseLimit = cm->option->maxLimitOfClausesForBDDDPLL; 00260 else 00261 clauseLimit = cm->option->maxLimitOfClausesForMonolithicBDD; 00262 00263 if(nCls > clauseLimit) { 00264 if(nVars > 100) { 00265 for(i=0; i<cArray->num; i++) { 00266 v = cArray->space[i]; 00267 SATflags(v) &= ResetVisitedMask; 00268 } 00269 sat_ArrayFree(cArray); 00270 for(i=0; i<vArray->num; i++) { 00271 v = vArray->space[i]; 00272 SATflags(v) &= ResetVisitedMask; 00273 } 00274 sat_ArrayFree(vArray); 00275 return(0); 00276 } 00277 } 00278 00279 if(cm->option->verbose > 1) { 00280 fprintf(cm->stdOut, "NOTICE : Apply BDD based method at level %d with %d vars %d cls\n", cm->currentDecision, nVars, nCls); 00281 fflush(cm->stdOut); 00282 } 00283 head = ALLOC(satLinearHead_t, 1); 00284 memset(head, 0, sizeof(satLinearHead_t)); 00285 head->clausesArray = cArray; 00286 head->variablesArray = vArray; 00287 head->reordering = 1; 00288 head->nVars = nVars; 00289 head->nCls = nCls; 00290 head->bddLimit = 5000; 00291 head->bddAndLimit = 10000; 00292 00293 head->elemHead = ALLOC(satLinearElem_t, nCls); 00294 memset(head->elemHead, 0, sizeof(satLinearElem_t)*nCls); 00295 head->varHead = ALLOC(satLinearVar_t, nVars); 00296 memset(head->varHead, 0, sizeof(satLinearVar_t)*nVars); 00297 00298 head->elemArray = sat_ArrayAlloc(nCls); 00299 head->varArray = sat_ArrayAlloc(nVars); 00300 head->latestClusterArray = sat_ArrayAlloc(32); 00301 head->deadArray = sat_ArrayAlloc(nVars); 00302 00303 head->id2edge = ALLOC(long, nVars+1); 00304 head->edge2id = ALLOC(int, cm->initNumVariables+1); 00305 head->edge2vid = ALLOC(int, cm->initNumVariables+1); 00306 00307 varIndex = 0; 00308 for(i=0; i<vArray->num; i++) { 00309 v = vArray->space[i]; 00310 SATflags(v) &= ResetVisitedMask; 00311 lvar = &(head->varHead[varIndex]); 00312 head->edge2vid[SATnodeID(v)] = varIndex; 00313 sat_ArrayInsert(head->varArray, (long)lvar); 00314 lvar->order = varIndex++; 00315 lvar->node = v; 00316 lvar->bQuantified = 1; 00317 lvar->clauses = sat_ArrayAlloc(4); 00318 } 00319 00320 elemIndex = 0; 00321 for(i=0; i<cArray->num; i++) { 00322 v = cArray->space[i]; 00323 SATflags(v) &= ResetVisitedMask; 00324 elem = &(head->elemHead[elemIndex]); 00325 sat_ArrayInsert(head->elemArray, (long)elem); 00326 elem->node = v; 00327 elem->order = elemIndex++; 00328 00329 size = SATnumLits(v); 00330 elem->support = sat_ArrayAlloc(size); 00331 plit = (long *)SATfirstLit(v); 00332 for(j=0; j<size; j++, plit++) { 00333 v = SATgetNode(*plit); 00334 inverted = SATisInverted(v); 00335 v = SATnormalNode(v); 00336 value = SATvalue(v) ^ inverted; 00337 if(value == 0) { 00338 continue; 00339 } 00340 varId = head->edge2vid[SATnodeID(v)]; 00341 lvar = &(head->varHead[varId]); 00342 00343 sat_ArrayInsert(lvar->clauses, (long)elem); 00344 if(inverted) lvar = (satLinearVar_t *)SATnot((unsigned long)lvar); 00345 sat_ArrayInsert(elem->support, (long)lvar); 00346 } 00347 } 00348 return(head); 00349 } 00350 00351 00363 satLinearCluster_t * 00364 sat_CreateCluster( 00365 satLinearHead_t *head, 00366 satLinearElem_t *e1, 00367 satLinearElem_t *e2, 00368 int flagIndex, 00369 int *idArr) 00370 { 00371 satLinearCluster_t *clu; 00372 satLinearVar_t *var; 00373 satArray_t *support, *deadArray; 00374 int from, to, nDead; 00375 int nv, bddid; 00376 int overlap, bddsize, j; 00377 00378 memset(idArr, 0, sizeof(int)*(head->nVars)); 00379 clu = ALLOC(satLinearCluster_t, 1); 00380 clu->elem1 = e1; 00381 clu->elem2 = e2; 00382 clu->deadArray = 0; 00383 from = e1->order; 00384 to = e2->order; 00385 nDead = 0; 00386 support = e1->support; 00387 for(j=0; j<support->num; j++) { 00388 var = (satLinearVar_t *)support->space[j]; 00389 var = (satLinearVar_t *)SATnormalNode((unsigned long)var); 00390 nv = var->node; 00391 bddid = head->edge2id[SATnodeID(nv)]; 00392 idArr[bddid] = 1; 00393 00394 if(var->bQuantified && from <= var->from && var->to <= to) { 00395 nDead++; 00396 if(clu->deadArray == 0) { 00397 deadArray = sat_ArrayAlloc(2); 00398 clu->deadArray = deadArray; 00399 } 00400 else 00401 deadArray = clu->deadArray; 00402 sat_ArrayInsert(deadArray, (long)var); 00403 } 00404 } 00405 00406 overlap = 0; 00407 support = e2->support; 00408 for(j=0; j<support->num; j++) { 00409 var = (satLinearVar_t *)support->space[j]; 00410 var = (satLinearVar_t *)SATnormalNode((unsigned long)var); 00411 nv = var->node; 00412 bddid = head->edge2id[SATnodeID(nv)]; 00413 if(idArr[bddid]) { 00414 if(from <= var->from && var->to <= to); 00415 else 00416 overlap++; 00417 } 00418 else { 00419 if(var->bQuantified && from <= var->from && var->to <= to) { 00420 nDead++; 00421 if(clu->deadArray == 0) { 00422 deadArray = sat_ArrayAlloc(2); 00423 clu->deadArray = deadArray; 00424 } 00425 else 00426 deadArray = clu->deadArray; 00427 sat_ArrayInsert(deadArray, (long)var); 00428 } 00429 } 00430 } 00431 00432 bddsize = Cudd_DagSize(e1->bdd) + Cudd_DagSize(e2->bdd); 00433 clu->overlap = overlap; 00434 clu->cost = (nDead<<7) + (overlap*(1024/bddsize)) + 10000/bddsize; 00435 clu->flag = flagIndex; 00436 00437 return(clu); 00438 } 00439 00451 static void 00452 sat_PrintSupportVariable( 00453 satLinearHead_t *head, 00454 satLinearElem_t *e1) 00455 { 00456 satArray_t *support; 00457 satLinearVar_t *var; 00458 int j; 00459 long nv; 00460 00461 00462 support = e1->support; 00463 for(j=0; j<support->num; j++) { 00464 var = (satLinearVar_t *)support->space[j]; 00465 var = (satLinearVar_t *)SATnormalNode((unsigned long)var); 00466 nv = var->node; 00468 fprintf(stdout, " %ld", nv); 00469 } 00470 fprintf(stdout, "\n"); 00471 } 00472 00484 static int 00485 heapCostCompare(const void *c1, const void *c2) 00486 { 00487 satLinearCluster_t *clu1, *clu2; 00488 00489 clu1 = (satLinearCluster_t *)c1; 00490 clu2 = (satLinearCluster_t *)c2; 00491 return(clu1->cost < clu2->cost); 00492 } 00493 00505 static void 00506 sat_ClusteringGetCandidate( 00507 satManager_t *cm, 00508 satLinearHead_t *head) 00509 { 00510 int i, *idArr; 00511 satArray_t *eArr; 00512 satLinearElem_t *e1, *e2; 00513 satLinearCluster_t *clu; 00514 00515 eArr = head->elemArray; 00516 head->heap = Heap_HeapInitCompare(eArr->num+2, heapCostCompare); 00517 00518 idArr = ALLOC(int, head->nVars); 00519 for(i=0; i<eArr->num; i++) { 00520 00521 e1 = (satLinearElem_t *)eArr->space[i]; 00522 if(i == eArr->num-1) 00523 continue; 00524 else 00525 e2 = (satLinearElem_t *)eArr->space[i+1]; 00526 00527 e1->flag = 1; 00528 e2->flag = 1; 00529 clu = sat_CreateCluster(head, e1, e2, 1, idArr); 00530 00531 Heap_HeapInsertCompare(head->heap, (void *)clu, (long)clu); 00532 } 00533 00534 free(idArr); 00535 00536 } 00537 00549 static DdNode * 00550 sat_SmoothWithDeadVariable( 00551 DdManager *mgr, 00552 satArray_t *deadArray, 00553 DdNode *bdd1, 00554 DdNode *bdd2, 00555 int bddAndLimit) 00556 { 00557 satLinearVar_t *var; 00558 DdNode *cube, *ncube; 00559 DdNode *result; 00560 int i; 00561 00562 00563 cube = DD_ONE(mgr); 00564 cuddRef(cube); 00565 for(i=0; i<deadArray->num; i++) { 00566 var = (satLinearVar_t *)deadArray->space[i]; 00567 ncube = Cudd_bddAnd(mgr,cube,var->bdd); 00568 if(ncube == NULL) { 00569 Cudd_RecursiveDeref(mgr, cube); 00570 return(NULL); 00571 } 00572 cuddRef(ncube); 00573 Cudd_RecursiveDeref(mgr, cube); 00574 cube = ncube; 00575 } 00576 00577 00578 result = Cudd_bddAndAbstractLimit( 00579 mgr,bdd1,bdd2,cube,bddAndLimit); 00580 if(result == NULL) { 00581 Cudd_RecursiveDeref(mgr, cube); 00582 return(NULL); 00583 } 00584 cuddRef(result); 00585 Cudd_RecursiveDeref(mgr, cube); 00586 cuddDeref(result); 00587 00588 return(result); 00589 } 00590 00602 static int 00603 sat_ClusteringElement( 00604 satManager_t *cm, 00605 satLinearHead_t *head) 00606 { 00607 int modified, total, size; 00608 int found, i, vid, index; 00609 long v; 00610 int *idArr, *idSupport; 00611 int limit, nElem; 00612 satLinearElem_t *e1, *e2; 00613 satLinearVar_t *lvar; 00614 satLinearCluster_t *clu, *tclu; 00615 satArray_t *support, *deadArray; 00616 satArray_t *neArr, *eArr; 00617 DdManager *mgr; 00618 DdNode *result, *zero; 00619 Heap_t *heap; 00620 long dummy; 00621 00622 heap = head->heap; 00623 modified = 0; 00624 00625 idArr = ALLOC(int, head->nVars); 00626 00627 mgr = head->mgr; 00628 eArr = head->elemArray; 00634 zero = Cudd_Not(DD_ONE(mgr)); 00635 limit = ((eArr->num)>>1); 00636 nElem = eArr->num; 00637 00638 if(cm->option->verbose > 3) 00639 fprintf(cm->stdOut, " ------- %d element\n", nElem); 00640 00641 while(Heap_HeapExtractMin(heap, &clu, &dummy)) { 00642 if(modified > limit) { 00643 sat_FreeCluster(mgr, clu); 00644 continue; 00645 } 00646 e1 = clu->elem1; 00647 e2 = clu->elem2; 00648 if(e1->flag == 0 || e2->flag == 0) { 00649 sat_FreeCluster(mgr, clu); 00650 continue; 00651 } 00652 if(e1->flag > clu->flag || e2->flag > clu->flag) { 00653 sat_FreeCluster(mgr, clu); 00654 continue; 00655 } 00656 deadArray = clu->deadArray; 00657 if(deadArray) { 00658 cuddRef(e1->bdd); 00659 cuddRef(e2->bdd); 00660 result = sat_SmoothWithDeadVariable( 00661 mgr, deadArray, e1->bdd, e2->bdd, head->bddAndLimit); 00662 if(result) 00663 cuddRef(result); 00664 Cudd_RecursiveDeref(mgr, e1->bdd); 00665 Cudd_RecursiveDeref(mgr, e2->bdd); 00666 for(i=0; i<deadArray->num; i++) { 00667 lvar = (satLinearVar_t *)deadArray->space[i]; 00668 sat_ArrayInsert(head->deadArray, (long)lvar); 00669 } 00670 } 00671 else { 00672 result = Cudd_bddAndLimit(mgr,e1->bdd,e2->bdd,head->bddAndLimit); 00673 if(result) 00674 cuddRef(result); 00675 } 00676 00677 total = Cudd_ReadKeys(mgr) - Cudd_ReadDead(mgr); 00678 if(total > 100000 && head->reordering) { 00679 head->reordering = 0; 00680 Cudd_AutodynDisable(mgr); 00681 } 00682 00683 if(result) { 00685 nElem--; 00686 if(cm->option->verbose > 3) { 00687 fprintf(cm->stdOut, " (%4d %4d) %4d(%3d, %3ld): %d X %d = %d\n", 00688 e1->order, e2->order, 00689 clu->cost, clu->overlap, deadArray ? deadArray->num : 0, 00690 Cudd_DagSize(e1->bdd), Cudd_DagSize(e2->bdd), 00691 Cudd_DagSize(result)); 00692 sat_PrintSupportVariable(head, e1); 00693 sat_PrintSupportVariable(head, e2); 00694 if(deadArray) { 00695 for(i=0; i<deadArray->num; i++) { 00696 lvar = (satLinearVar_t *)deadArray->space[i]; 00697 fprintf(cm->stdOut, "%ld ", lvar->node); 00698 } 00699 } 00700 fprintf(cm->stdOut, "\n"); 00701 } 00702 modified++; 00703 e1->flag += 1; 00704 e2->flag = 0; 00705 00706 if(nElem < 50) { 00707 sat_ArrayInsert(head->latestClusterArray, (long)(e1->bdd)); 00708 cuddRef(e1->bdd); 00709 sat_ArrayInsert(head->latestClusterArray, (long)(e2->bdd)); 00710 cuddRef(e2->bdd); 00711 } 00712 00713 Cudd_RecursiveDeref(mgr, e1->bdd); 00714 Cudd_RecursiveDeref(mgr, e2->bdd); 00715 e1->bdd = result; 00716 e2->bdd = 0; 00717 sat_ArrayFree(e1->support); 00718 e1->support = 0; 00719 support = e2->support; 00720 for(i=0; i<support->num; i++) { 00721 lvar = (satLinearVar_t *)support->space[i]; 00722 if(lvar->to == e2->order) 00723 lvar->to = e1->order; 00724 if(lvar->from == e2->order) 00725 lvar->from = e1->order; 00726 } 00727 sat_ArrayFree(e2->support); 00728 e2->support = 0; 00729 00730 size = (unsigned int)Cudd_ReadSize(mgr); 00731 idSupport = Cudd_SupportIndex(mgr,result); 00732 e1->support = support = sat_ArrayAlloc(10); 00733 for (i = 0; i < size; i++) { 00734 if(idSupport[i]) { 00735 v = head->id2edge[i]; 00736 vid = head->edge2vid[SATnodeID(v)]; 00737 lvar = &(head->varHead[vid]); 00738 sat_ArrayInsert(support, (long)lvar); 00745 } 00746 } 00747 free(idSupport); 00748 00749 found = 0; 00750 for(i=e1->order-1; i>=0; i--) { 00751 e2 = (satLinearElem_t *)eArr->space[i]; 00752 if(e2->flag) { 00753 found = 1; 00754 break; 00755 } 00756 } 00757 if(found) { 00758 tclu = sat_CreateCluster(head, e2, e1, e1->flag, idArr); 00759 Heap_HeapInsertCompare(head->heap, (void *)tclu, (long)tclu); 00760 } 00761 00762 found = 0; 00763 for(i=e1->order+1; i<eArr->num; i++) { 00764 e2 = (satLinearElem_t *)eArr->space[i]; 00765 if(e2->flag) { 00766 found = 1; 00767 break; 00768 } 00769 } 00770 if(found) { 00771 tclu = sat_CreateCluster(head, e1, e2, e1->flag, idArr); 00772 Heap_HeapInsertCompare(head->heap, (void *)tclu, (long)tclu); 00773 } 00774 } 00775 sat_FreeCluster(mgr, clu); 00776 } 00777 00778 Heap_HeapFree(heap); 00779 head->heap = 0; 00780 00781 free(idArr); 00782 00783 if(modified) { 00784 eArr = head->elemArray; 00785 neArr = sat_ArrayAlloc(eArr->num); 00786 index = 0; 00787 for(i=0; i<eArr->num; i++) { 00788 e1 = (satLinearElem_t *)eArr->space[i]; 00789 if(e1->flag == 0) continue; 00790 00791 e1->order = index++; 00792 sat_ArrayInsert(neArr, (long)e1); 00793 } 00794 sat_ArrayFree(eArr); 00795 head->elemArray = neArr; 00796 } 00797 00798 if(head->elemArray->num == 1) 00799 modified = 0; 00800 00801 return(modified); 00802 } 00803 00804 00816 static void 00817 sat_FreeCluster(DdManager *mgr, satLinearCluster_t *clu) 00818 { 00819 satArray_t *deadArray; 00820 00821 deadArray = clu->deadArray; 00822 if(deadArray) { 00823 sat_ArrayFree(deadArray); 00824 } 00825 free(clu); 00826 } 00827 00828 00840 static void 00841 sat_CheckDeadNode( 00842 satLinearHead_t *head, 00843 satLinearCluster_t *clu) 00844 { 00845 satArray_t *deadArray, *eArr; 00846 satArray_t *support; 00847 satLinearVar_t *var, *tvar; 00848 satLinearElem_t *elem; 00849 int i, j, k; 00850 00851 00852 if(clu->deadArray) { 00853 deadArray = clu->deadArray; 00854 for(i=0; i<deadArray->num; i++) { 00855 var = (satLinearVar_t *)deadArray->space[i]; 00856 eArr = head->elemArray; 00857 for(j=0; j<var->from; j++) { 00858 elem = (satLinearElem_t *)eArr->space[j]; 00859 if(elem->flag == 0) continue; 00860 support = elem->support; 00861 for(k=0; k<support->num; k++) { 00862 tvar = (satLinearVar_t *)support->space[k]; 00863 tvar = (satLinearVar_t *)SATnormalNode((unsigned long)tvar); 00864 if(var == tvar) { 00865 fprintf(stdout, "Error : wrong variable range\n"); 00866 } 00867 } 00868 } 00869 for(j=var->to+1; j<eArr->num; j++) { 00870 elem = (satLinearElem_t *)eArr->space[j]; 00871 if(elem->flag == 0) continue; 00872 support = elem->support; 00873 for(k=0; k<support->num; k++) { 00874 tvar = (satLinearVar_t *)support->space[k]; 00875 tvar = (satLinearVar_t *)SATnormalNode((unsigned long)tvar); 00876 if(var == tvar) { 00877 fprintf(stdout, "Error : wrong variable range\n"); 00878 } 00879 } 00880 } 00881 } 00882 } 00883 } 00884 00899 static int 00900 sat_ConvertCNF2BDD( 00901 satManager_t *cm, 00902 DdManager *mgr, 00903 int conflictFlag) 00904 { 00905 satLinearHead_t *head; 00906 DdNode *result, *cube; 00907 DdNode *l1, *l2; 00908 DdNode *nl1, *nl2; 00909 satArray_t *satArr, *arr; 00910 int limitCut; 00911 int flag, length; 00912 int cut, i; 00913 00914 head = sat_CreateLinearHead(cm, conflictFlag); 00915 00916 if(head == 0) return(0); 00917 00918 head->mgr = mgr; 00919 00920 sat_GetArrangementByForce(cm, head); 00921 00922 if(cm->option->verbose > 3) 00923 cut = sat_PrintCutProfile(cm, head, "final", 1); 00924 else 00925 cut = sat_PrintCutProfile(cm, head, "final", 0); 00926 00927 if(conflictFlag) 00928 limitCut = cm->option->maxLimitOfCutSizeForBDDDPLL; 00929 else 00930 limitCut = cm->option->maxLimitOfCutSizeForMonolithicBDD; 00931 if(cut > limitCut) { 00932 sat_FreeLinearHead(head); 00933 return(SAT_BDD_BACKTRACK); 00934 } 00935 00936 flag = sat_ClusteringElementMain(cm, head); 00937 00938 if(flag == SAT_BDD_SAT) { 00939 arr = head->latestClusterArray; 00940 satArr = sat_ArrayAlloc(16); 00941 for(i=arr->num-1; i>=0; i--) { 00942 l1 = (DdNode *)arr->space[i]; 00943 i--; 00944 l2 = (DdNode *)arr->space[i]; 00945 nl1 = sat_CofactorBDDArray(head, mgr, l1, satArr); 00946 nl2 = sat_CofactorBDDArray(head, mgr, l2, satArr); 00947 result = Cudd_bddAndLimit(mgr, nl1, nl2, head->bddAndLimit); 00948 cuddRef(result); 00949 Cudd_RecursiveDeref(mgr, nl1); 00950 Cudd_RecursiveDeref(mgr, nl2); 00951 cube = Cudd_LargestCube(mgr, result, &length); 00952 cuddRef(cube); 00953 sat_ExtractAssignmentFromBDD(head, mgr, satArr, cube); 00954 Cudd_RecursiveDeref(mgr, cube); 00955 Cudd_RecursiveDeref(mgr, result); 00956 } 00957 cm->assignByBDD = satArr; 00958 } 00959 sat_FreeLinearHead(head); 00960 00961 return(flag); 00962 } 00963 00975 static void 00976 sat_FreeLinearHead(satLinearHead_t *head) 00977 { 00978 satLinearElem_t *elem; 00979 satLinearVar_t *var; 00980 satArray_t *eArr, *vArr, *arr; 00981 satArray_t *support, *clauses; 00982 DdNode *bdd; 00983 int i; 00984 00985 eArr = head->elemArray; 00986 if(eArr) { 00987 for(i=0; i<eArr->num; i++) { 00988 elem = (satLinearElem_t *)(eArr->space[i]); 00989 support = elem->support; 00990 if(support) 00991 sat_ArrayFree(support); 00992 if(elem->bdd) 00993 Cudd_RecursiveDeref(head->mgr, elem->bdd); 00994 } 00995 } 00996 vArr = head->varArray; 00997 if(vArr) { 00998 for(i=0; i<vArr->num; i++) { 00999 var = (satLinearVar_t *)vArr->space[i]; 01000 clauses = var->clauses; 01001 if(clauses) 01002 sat_ArrayFree(clauses); 01003 if(var->bdd) 01004 Cudd_RecursiveDeref(head->mgr, var->bdd); 01005 } 01006 } 01007 01008 if(head->variablesArray) 01009 sat_ArrayFree(head->variablesArray); 01010 if(head->clausesArray) 01011 sat_ArrayFree(head->clausesArray); 01012 01013 if(head->elemHead) 01014 free(head->elemHead); 01015 if(head->varHead) 01016 free(head->varHead); 01017 if(head->id2edge) 01018 free(head->id2edge); 01019 if(head->edge2id) 01020 free(head->edge2id); 01021 if(head->edge2vid) 01022 free(head->edge2vid); 01023 01024 if(head->latestClusterArray) { 01025 arr = head->latestClusterArray; 01026 for(i=0; i<arr->num; i++) { 01027 bdd = (DdNode *)arr->space[i]; 01028 Cudd_RecursiveDeref(head->mgr, bdd); 01029 } 01030 sat_ArrayFree(arr); 01031 head->latestClusterArray = 0; 01032 } 01033 01034 if(head->deadArray) 01035 free(head->deadArray); 01036 free(head); 01037 } 01038 01039 01051 static int 01052 linearVarCompare( 01053 const void * node1, 01054 const void * node2) 01055 { 01056 satLinearVar_t *d1; 01057 satLinearVar_t *d2; 01058 01059 d1 = *(satLinearVar_t **)(node1); 01060 d2 = *(satLinearVar_t **)(node2); 01061 01062 return (d1->pos > d2->pos); 01063 } 01064 01076 static int 01077 linearElemCompare( 01078 const void * node1, 01079 const void * node2) 01080 { 01081 satLinearElem_t *d1; 01082 satLinearElem_t *d2; 01083 01084 d1 = *(satLinearElem_t **)(node1); 01085 d2 = *(satLinearElem_t **)(node2); 01086 01087 return (d1->pos > d2->pos); 01088 } 01089 01101 static void 01102 sat_GetArrangementByForce( 01103 satManager_t *cm, 01104 satLinearHead_t *head) 01105 { 01106 int iteration; 01107 double prespan, span; 01108 int from, to, sum; 01109 int i, j, inverted; 01110 satLinearElem_t *elem; 01111 satLinearVar_t *var; 01112 satArray_t *eArr, *vArr; 01113 satArray_t *support, *clauses; 01114 01115 iteration = 0; 01116 prespan = MAXINT; 01117 eArr = head->elemArray; 01118 vArr = head->varArray; 01119 while(1) { 01120 iteration++; 01121 if(iteration > 200) break; 01122 01123 span = 0; 01124 for(i=0; i<eArr->num; i++) { 01125 elem = (satLinearElem_t *)(eArr->space[i]); 01126 support = elem->support; 01127 sum = 0; 01128 from = MAXINT; 01129 to = -1; 01130 for(j=0; j<support->num; j++) { 01131 var = (satLinearVar_t *)(support->space[j]); 01132 inverted = SATisInverted((unsigned long)var); 01133 var = (satLinearVar_t *)SATnormalNode((unsigned long)var); 01134 sum += var->order; 01135 if(var->order < from) from = var->order; 01136 if(to < var->order) to = var->order; 01137 } 01138 if(from != MAXINT && to != -1) 01139 span += (double)(to - from); 01140 elem->pos = sum / (double)(support->num); 01141 } 01142 01143 if(iteration > 2 && (prespan * 0.9999) < span) 01144 break; 01145 prespan = span; 01146 01147 qsort(eArr->space, eArr->num, sizeof(satLinearElem_t *), linearElemCompare); 01148 for(i=0; i<eArr->num; i++) { 01149 elem = (satLinearElem_t *)eArr->space[i]; 01150 elem->order = i; 01151 } 01152 01153 for(i=0; i<vArr->num; i++) { 01154 var = (satLinearVar_t *)vArr->space[i]; 01155 clauses = var->clauses; 01156 sum = 0; 01157 for(j=0; j<clauses->num; j++) { 01158 elem = (satLinearElem_t *)clauses->space[j]; 01159 sum += elem->order; 01160 } 01161 var->pos = sum / (double)(clauses->num); 01162 } 01163 01164 qsort(vArr->space, vArr->num, sizeof(satLinearVar_t *), linearVarCompare); 01165 for(i=0; i<vArr->num; i++) { 01166 var = (satLinearVar_t *)vArr->space[i]; 01167 var->order = i; 01168 } 01169 } 01170 if(cm->option->verbose > 3) 01171 fprintf(cm->stdOut, "NOTICE : %d iteration for force based arrangement\n", iteration); 01172 } 01173 01185 static int 01186 sat_PrintCutProfile( 01187 satManager_t *cm, 01188 satLinearHead_t *head, 01189 char *baseName, 01190 int printFlag) 01191 { 01192 st_table *cutTable; 01193 st_generator *gen; 01194 FILE *fout = NIL(FILE); 01195 int i, j, cut, sum; 01196 int to, from; 01197 char filename[1024]; 01198 satArray_t *support, *clauses, *eArr, *vArr; 01199 satLinearElem_t *elem; 01200 satLinearVar_t *var; 01201 double span; 01202 01203 eArr = head->elemArray; 01204 span = 0; 01205 for(i=0; i<eArr->num; i++) { 01206 elem = (satLinearElem_t *)eArr->space[i]; 01207 support = elem->support; 01208 sum = 0; 01209 to = -1; 01210 from = MAXINT; 01211 for(j=0; j<support->num; j++) { 01212 var = (satLinearVar_t *)support->space[j]; 01213 var = (satLinearVar_t *)SATnormalNode((unsigned long)var); 01214 sum += var->order; 01215 if(to < var->order) to = var->order; 01216 if(var->order < from) from = var->order; 01217 } 01218 elem->to = to; 01219 if(from != MAXINT && to != -1) 01220 span += (double)(to - from); 01221 } 01222 01223 cut = 0; 01224 if(printFlag) { 01225 sprintf(filename, "%s.data", baseName); 01226 fout = fopen(filename, "w"); 01227 } 01228 cutTable = st_init_table(st_ptrcmp, st_ptrhash); 01229 vArr = head->varArray; 01230 for(i=0; i<vArr->num; i++) { 01231 var = (satLinearVar_t *)vArr->space[i]; 01232 clauses = var->clauses; 01233 for(j=0; j<clauses->num; j++) { 01234 elem = (satLinearElem_t *)clauses->space[j]; 01235 st_insert(cutTable, (char *)elem, (char *)elem); 01236 } 01237 st_foreach_item(cutTable, gen, &elem, &elem) { 01238 if(elem->to <= i) 01239 st_delete(cutTable, &elem, NIL(char *)); 01240 } 01241 if(cut < cutTable->num_entries) 01242 cut = cutTable->num_entries; 01243 if(printFlag) 01244 fprintf(fout, "%d %d\n", i, cutTable->num_entries); 01245 } 01246 st_free_table(cutTable); 01247 01248 if(printFlag) { 01249 fclose(fout); 01250 sprintf(filename, "%s.gnu", baseName); 01251 fout = fopen(filename, "w"); 01252 fprintf(fout, "set terminal postscript \n"); 01253 fprintf(fout, "set output \"%s.ps\"\n", baseName); 01254 fprintf(fout, "set title \"profile of live variable span %f cut %d\"\n", 01255 span, cut); 01256 fprintf(fout, "plot \"%s.data\" using 1:2 title \"%s\" with lines\n", baseName, "cut"); 01257 fclose(fout); 01258 } 01259 01260 return cut; 01261 01262 } 01263 01275 static int 01276 sat_ClusteringElementMain( 01277 satManager_t *cm, 01278 satLinearHead_t *head) 01279 { 01280 int modified; 01281 satLinearElem_t *elem; 01282 DdNode *one; 01283 01284 Cudd_AutodynEnable(head->mgr, CUDD_REORDER_SIFT); 01285 01286 sat_InitClusteringElement(cm, head); 01287 01288 while(1) { 01289 sat_ComputeVariableRange(cm, head); 01290 sat_ClusteringGetCandidate(cm, head); 01291 modified = sat_ClusteringElement(cm, head); 01292 if(modified == 0) break; 01293 } 01294 01295 if(head->elemArray->num == 1) { 01296 one = DD_ONE(head->mgr); 01297 elem = (satLinearElem_t *)(head->elemArray->space[0]); 01298 if(elem->bdd == one) return(SAT_BDD_SAT); 01299 else if(elem->bdd == Cudd_Not(one)) return(SAT_BDD_UNSAT); 01300 else return(SAT_BDD_BACKTRACK); 01301 } 01302 else { 01303 return(SAT_BDD_BACKTRACK); 01304 } 01305 } 01306 01318 static void 01319 sat_ComputeVariableRange( 01320 satManager_t *cm, 01321 satLinearHead_t *head) 01322 { 01323 satArray_t *support, *vArr, *eArr; 01324 satLinearElem_t *elem; 01325 satLinearVar_t *var; 01326 int i, j; 01327 01328 vArr = head->varArray; 01329 eArr = head->elemArray; 01330 01331 for(i=0; i<vArr->num; i++) { 01332 var = (satLinearVar_t *)vArr->space[i]; 01333 var->from = MAXINT; 01334 var->to = -1; 01335 } 01336 01337 for(i=0; i<eArr->num; i++) { 01338 elem = (satLinearElem_t *)eArr->space[i]; 01339 support = elem->support; 01340 for(j=0; j<support->num; j++) { 01341 var = (satLinearVar_t *)support->space[j]; 01342 var = (satLinearVar_t *)SATnormalNode((unsigned long)var); 01343 if(elem->order < var->from) var->from = elem->order; 01344 if(var->to < elem->order) var->to = elem->order; 01345 } 01346 } 01347 } 01348 01360 static void 01361 sat_InitClusteringElement( 01362 satManager_t *cm, 01363 satLinearHead_t *head) 01364 { 01365 DdNode *sum, *nsum, *one; 01366 DdManager *mgr; 01367 satLinearElem_t *elem; 01368 satLinearVar_t *var; 01369 satArray_t *support, *vArr, *eArr; 01370 int i, j, index; 01371 long nv; 01372 int inverted; 01373 01374 mgr = head->mgr; 01375 vArr = head->varArray; 01376 eArr = head->elemArray; 01377 index = 0; 01378 one = DD_ONE(mgr); 01379 01380 for(i=0; i<vArr->num; i++) { 01381 var = (satLinearVar_t *)vArr->space[i]; 01382 nv = var->node; 01383 head->id2edge[index] = nv; 01384 head->edge2id[SATnodeID(nv)] = index; 01385 var->bdd = cuddUniqueInter(mgr,index,one,Cudd_Not(one)); 01386 cuddRef(var->bdd); 01387 index++; 01388 } 01389 01390 for(i=0; i<eArr->num; i++) { 01391 elem = (satLinearElem_t *)eArr->space[i]; 01392 support = elem->support; 01393 sum = Cudd_Not(one); 01394 cuddRef(sum); 01395 for(j=0; j<support->num; j++) { 01396 var = (satLinearVar_t *)support->space[j]; 01397 inverted = SATisInverted((unsigned long)var); 01398 var = (satLinearVar_t *)SATnormalNode((unsigned long)var); 01399 nsum = Cudd_bddAnd(mgr,Cudd_Not(sum), 01400 (inverted ? var->bdd : Cudd_Not(var->bdd))); 01401 nsum = Cudd_Not(nsum); 01402 cuddRef(nsum); 01403 01404 Cudd_RecursiveDeref(mgr,sum); 01405 sum = nsum; 01406 } 01407 elem->bdd = sum; 01408 } 01409 } 01410 01411 #endif 01412 #ifndef BDDcu 01413 01426 void 01427 sat_TryToBuildMonolithicBDD(satManager_t *cm) 01428 { 01429 fprintf(stderr, "Warning : This feature is only availabe with CUDD package\n"); 01430 return; 01431 } 01432 #endif