VIS
|
00001 00020 #include "satInt.h" 00021 #include "puresatInt.h" 00022 00023 static char rcsid[] UNUSED = "$Id: satCore.c,v 1.20 2009/04/12 00:14:11 fabio Exp $"; 00024 00025 /*---------------------------------------------------------------------------*/ 00026 /* Constant declarations */ 00027 /*---------------------------------------------------------------------------*/ 00028 00029 #define CONFLICT 1 00030 #define NO_CONFLICT 2 00031 00033 /*---------------------------------------------------------------------------*/ 00034 /* Static function prototypes */ 00035 /*---------------------------------------------------------------------------*/ 00036 00037 static int 00038 ScoreCompare( 00039 const void * node1, 00040 const void * node2) 00041 { 00042 int v1; 00043 int v2; 00044 int s1, s2; 00045 00046 v1 = *(int *)(node1); 00047 v2 = *(int *)(node2); 00048 s1 = *((int *)(node1) + 1); 00049 s2 = *((int *)(node2) + 1); 00050 00051 if(s1 == s2) { 00052 return(v1 > v2); 00053 } 00054 return(s1 < s2); 00055 } 00056 00060 /*---------------------------------------------------------------------------*/ 00061 00062 /* Definition of exported functions */ 00063 /*---------------------------------------------------------------------------*/ 00064 00065 00078 void 00079 sat_PrintClauseLits(satManager_t * cm, 00080 long concl) 00081 { 00082 long i, node, var_idx,*lit; 00083 00084 for(i=0, lit = (long*)SATfirstLit(concl); i<SATnumLits(concl);i++, lit++){ 00085 node = SATgetNode(*lit); 00086 var_idx = SATnodeID(node); 00087 if(SATisInverted(node)) 00088 fprintf(vis_stdout,"%ld ", -var_idx); 00089 else 00090 fprintf(vis_stdout,"%ld ",var_idx); 00091 } 00092 fprintf(vis_stdout,"0\n"); 00093 } 00094 00095 00110 void 00111 sat_PrintClauseLitsForCore(satManager_t * cm, 00112 long concl, 00113 FILE *fp) 00114 { 00115 long i, node, var_idx,*lit, cls_idx; 00116 00117 lit = (long*)SATfirstLit(concl); 00118 cls_idx = -(*(lit-1)); 00119 00120 if(fp) { 00122 cls_idx -= cm->initNumVariables * satNodeSize; 00124 cls_idx = cls_idx/satNodeSize - 1; 00125 fprintf(fp,"#clause index:%ld\n",cls_idx); 00126 for(i=0, lit = (long*)SATfirstLit(concl); i<SATnumLits(concl);i++, lit++){ 00127 node = SATgetNode(*lit); 00128 var_idx = SATnodeID(node); 00129 if(SATisInverted(node)) 00130 fprintf(fp, "%ld ", -var_idx); 00131 else 00132 fprintf(fp, "%ld ",var_idx); 00133 } 00134 fprintf(fp, "0\n"); 00135 } 00136 else { 00137 if(cm->clauseIndexInCore == 0) 00138 cm->clauseIndexInCore = sat_ArrayAlloc(1024); 00139 sat_ArrayInsert(cm->clauseIndexInCore, cls_idx); 00140 } 00141 00142 } 00143 00144 00157 void 00158 sat_GenerateCoreRecur(satManager_t * cm, 00159 long concl, 00160 FILE *fp, 00161 int * count) 00162 { 00163 int j; 00164 long tmp; 00165 satArray_t * dep; 00166 00167 if(!(SATflags(concl)&NewMask)){ 00168 SATflags(concl)|=NewMask; 00170 if(!(SATflags(concl)& IsConflictMask)){ 00171 (*count)++; 00172 sat_PrintClauseLitsForCore(cm,concl,fp); 00173 } 00175 else{ 00176 if(!st_lookup(cm->dependenceTable,(char *)concl, &dep)){ 00177 fprintf(cm->stdOut,"%ld is not in depe table\n",concl); 00178 exit(0); 00179 } 00180 else{ 00181 for(j=0;j<dep->num; j++){ 00182 tmp = dep->space[j]; 00183 sat_GenerateCoreRecur(cm, tmp, fp, count); 00184 } 00185 } 00186 } 00187 } 00188 } 00189 00190 00191 00204 void 00205 sat_GetDependence(satManager_t * cm, long concl, satArray_t* dep) 00206 { 00207 long node, *lit, ante; 00208 int i; 00209 00210 for(i=0, lit = (long*)SATfirstLit(concl); i<SATnumLits(concl);i++, lit++){ 00211 node = SATgetNode(*lit); 00212 node = SATnormalNode(node); 00213 ante = SATante(node); 00214 if(ante==0){ 00215 if(!st_lookup(cm->anteTable, (char *)node, &ante)){ 00216 fprintf(vis_stdout,"ante = 0 and is not in anteTable %ld\n",node); 00217 exit(0); 00218 } 00219 } 00220 if(!(SATflags(ante)&NewMask)){ 00221 SATflags(ante)|=NewMask; 00222 sat_ArrayInsert(dep,ante); 00223 sat_GetDependence(cm,ante,dep); 00224 } 00225 } 00226 } 00227 00240 void 00241 sat_GenerateCore(satManager_t * cm) 00242 { 00243 int j, tmp,value; 00244 long *lit, node, concl, i; 00245 satArray_t * dep; 00246 FILE *fp = cm->fp; 00247 int count, inverted; 00248 st_generator *stGen; 00249 satArray_t* tmpdep = sat_ArrayAlloc(1); 00250 satLevel_t * d; 00251 00252 cm->status = 0; 00253 count = 0; 00254 d = SATgetDecision(0); 00255 for(i=satNodeSize; i<cm->nodesArraySize; i+=satNodeSize){ 00256 node = i; 00257 if((SATflags(node)&IsCNFMask)&&(SATnumLits(node)==1)){ 00258 lit = (long*)SATfirstLit(node); 00259 tmp = SATgetNode(*lit); 00260 inverted = SATisInverted(tmp); 00261 tmp = SATnormalNode(tmp); 00262 00263 00264 value = !inverted; 00265 if(SATvalue(tmp) < 2) { 00266 if(SATvalue(tmp) == value) continue; 00267 else { 00268 cm->status = SAT_UNSAT; 00269 d->conflict = node; 00270 break; 00271 } 00272 } 00273 00274 SATvalue(tmp) = !inverted; 00275 SATmakeImplied(tmp, d); 00276 SATante(tmp) = node; 00277 if((SATflags(tmp) & InQueueMask) == 0) { 00278 sat_Enqueue(cm->queue, tmp); 00279 SATflags(tmp) |= InQueueMask; 00280 } 00282 } 00283 } 00284 00285 sat_ImplicationMain(cm, d); 00286 if(d->conflict == 0) { 00287 fprintf(vis_stderr,"There should be a conflict\n"); 00288 exit(0); 00289 } 00291 concl = d->conflict; 00292 sat_ArrayInsert(tmpdep,concl); 00293 SATflags(concl)|=NewMask; 00295 if(!(SATflags(concl)&IsConflictMask)){ 00296 count++; 00297 sat_PrintClauseLitsForCore(cm,concl,fp); 00298 } 00299 00300 sat_GetDependence(cm, concl, tmpdep); 00301 for(i=satNodeSize;i<cm->nodesArraySize;i+=satNodeSize){ 00302 SATflags(i)&=ResetNewMask; 00303 } 00304 00305 for(i=0;i<tmpdep->num;i++){ 00306 concl = tmpdep->space[i]; 00307 if(!(SATflags(concl)&NewMask)){ 00308 SATflags(concl)|=NewMask; 00310 if((SATflags(concl)&IsConflictMask)){ 00311 if(!st_lookup(cm->dependenceTable,(char *)concl,&dep)){ 00312 fprintf(cm->stdOut,"%ld is conflict but not in depe table\n",concl); 00313 exit(0); 00314 } 00315 else{ 00316 for(j=0;j<dep->num; j++){ 00317 tmp = dep->space[j]; 00318 sat_GenerateCoreRecur(cm, tmp, fp, &count); 00319 } 00320 } 00321 } 00323 else{ 00324 count++; 00325 sat_PrintClauseLitsForCore(cm,concl,fp); 00326 } 00327 } 00328 } 00330 cm->numOfClsInCore = count; 00331 00332 for(i=satNodeSize;i<cm->nodesArraySize;i+=satNodeSize){ 00333 SATflags(i)&=ResetNewMask; 00334 } 00335 st_foreach_item(cm->dependenceTable, stGen,&node, &dep) 00336 sat_ArrayFree(dep); 00337 sat_ArrayFree(tmpdep); 00338 sat_Undo(cm,d); 00339 st_free_table(cm->dependenceTable); 00340 st_free_table(cm->anteTable); 00341 cm->status = SAT_UNSAT; 00342 } 00343 00355 void 00356 sat_ImplyArrayWithAnte( 00357 satManager_t *cm, 00358 satLevel_t *d, 00359 satArray_t *arr) 00360 { 00361 int i, size; 00362 bAigEdge_t v; 00363 int inverted, value; 00364 satQueue_t *Q; 00365 00366 if(arr == 0) return; 00367 if(cm->status)return; 00368 00369 size = arr->num; 00370 Q = cm->queue; 00371 for(i=0; i<size; i++) { 00372 v = arr->space[i]; 00373 inverted = SATisInverted(v); 00374 v = SATnormalNode(v); 00375 00376 value = !inverted; 00377 if(SATvalue(v) < 2) { 00378 if(SATvalue(v) == value) continue; 00379 else { 00380 cm->status = SAT_UNSAT; 00381 d->conflict = v; 00382 return; 00383 } 00384 } 00385 00386 SATvalue(v) = value; 00387 SATmakeImplied(v, d); 00388 SATante(v) = SATnormalNode(v); 00389 00390 if((SATflags(v) & InQueueMask) == 0) { 00391 sat_Enqueue(Q, v); 00392 SATflags(v) |= InQueueMask; 00393 } 00394 } 00395 } 00396 00397 00411 void 00412 sat_ImplyUnitPureLitsWithAnte(satManager_t * cm, satLevel_t *d) 00413 { 00414 int tmp, inverted; 00415 long node, *lit, i; 00416 00417 for(i=satNodeSize; i<cm->nodesArraySize; i+=satNodeSize){ 00418 node = i; 00419 if((SATflags(node)&IsCNFMask)&&(SATnumLits(node)==1)){ 00420 int value; 00421 lit = (long*)SATfirstLit(node); 00422 tmp = SATgetNode(*lit); 00423 inverted = SATisInverted(tmp); 00424 tmp = SATnormalNode(tmp); 00425 00426 value = !inverted; 00427 if(SATvalue(tmp) < 2) { 00428 if(SATvalue(tmp) == value) continue; 00429 else { 00430 cm->status = SAT_UNSAT; 00431 d->conflict = node; 00432 break; 00433 } 00434 } 00435 00436 SATvalue(tmp) = !inverted; 00437 SATmakeImplied(tmp, d); 00438 SATante(tmp) = node; 00439 if((SATflags(tmp) & InQueueMask) == 0) { 00440 sat_Enqueue(cm->queue, tmp); 00441 SATflags(tmp) |= InQueueMask; 00442 } 00443 } 00444 } 00445 00446 if(cm->status == SAT_UNSAT) 00447 return; 00448 00449 sat_ImplyArray(cm, d, cm->pureLits); 00450 } 00451 00452 00465 void 00466 sat_BuildRT( 00467 satManager_t * cm, 00468 RTnode_t root, 00469 long *lp, 00470 long *tmpIP, 00471 int size, 00472 boolean NotCNF) 00473 { 00474 int i; 00475 long tmpnode; 00476 RTManager_t *rm = cm->rm; 00477 00478 RT_formula(root) = rm->cpos; 00479 00480 RT_fSize(root) = size; 00481 00482 00483 if(rm->maxpos<=rm->cpos+size+1){ 00484 rm->fArray = REALLOC(long,rm->fArray,rm->maxpos+FORMULA_BLOCK); 00485 rm->maxpos = rm->maxpos+FORMULA_BLOCK; 00486 } 00487 00488 for(i=0;i<size;i++,lp++){ 00489 if(NotCNF) 00490 tmpnode = *lp; 00491 else 00492 tmpnode = SATgetNode(*lp); 00493 rm->fArray[rm->cpos] = tmpnode; 00494 rm->cpos++; 00495 } 00496 } 00497 00510 bAigEdge_t sat_GenerateFwdIP(bAig_Manager_t* manager, 00511 satManager_t *cm, 00512 RTnode_t RTnode, 00513 int cut) 00514 { 00515 int i; 00516 long node, node1, left, right, result, *lp, *lp1; 00517 int IPTrue=0, local=1, first=0, second=0, allDummy=1; 00518 RTManager_t * rm = cm->rm; 00519 00520 manager->class_ = cut; 00521 if(RT_flag(RTnode)&RT_VisitedMask){ 00522 #if DBG 00523 assert(RT_IPnode(RTnode)!=-1); 00524 #endif 00525 00526 return RT_IPnode(RTnode); 00527 } 00528 #if DBG 00529 assert(RT_IPnode(RTnode)==-1); 00530 #endif 00531 RT_flag(RTnode) |= RT_VisitedMask; 00532 00533 if(RT_pivot(RTnode)==0){ /*leaf*/ 00534 00535 #if DBG 00536 assert(RT_left(RTnode)==RT_NULL&&RT_right(RTnode)==RT_NULL); 00537 #endif 00538 00539 #if DBG 00540 assert(RT_oriClsIdx(RTnode)==0); 00541 #endif 00542 if(RT_oriClsIdx(RTnode)) 00543 lp = (long*)SATfirstLit(RT_oriClsIdx(RTnode)); 00544 else 00545 00546 lp = RT_formula(RTnode) + cm->rm->fArray; 00547 lp1 = lp; 00548 for(i=0;i<RT_fSize(RTnode);i++,lp++){ 00549 if(*lp == DUMMY) 00550 continue; 00551 else{ 00552 allDummy = 0; 00553 #if DBG 00554 assert(*lp>0); 00555 #endif 00556 } 00557 if(RT_oriClsIdx(RTnode))/*is CNF*/ 00558 node = SATgetNode(*lp); 00559 else /*is AIG*/ 00560 node = *lp; 00561 00562 node = SATnormalNode(node); 00563 if(SATflags(node)&IsGlobalVarMask) 00564 continue; 00565 00566 if(SATclass(node)>cut){ 00567 IPTrue = 1; 00568 #if DBG 00569 second = 1; 00570 #else 00571 break; 00572 #endif 00573 } 00574 #if DBG 00575 else{ 00576 first = 1; 00577 } 00578 #endif 00579 } 00580 00581 #if DBG 00582 assert(!allDummy); 00583 assert(!(first&&second)); 00584 #endif 00585 00586 00587 if(IPTrue){ 00588 RT_IPnode(RTnode) = bAig_One; 00589 return bAig_One; 00590 } 00591 00592 lp = lp1; 00593 result = bAig_Zero; 00594 for(i=0;i<RT_fSize(RTnode);i++,lp++){ 00595 if(RT_oriClsIdx(RTnode))/*is CNF*/ 00596 node = SATgetNode(*lp); 00597 else /*is AIG*/ 00598 node = *lp; 00599 node1 = SATnormalNode(node); 00600 if(flags(node1)&IsGlobalVarMask){ 00601 result = PureSat_Or(manager,result,node); 00602 cm->nodesArray = manager->NodesArray; 00603 } 00604 } 00605 00606 RT_IPnode(RTnode) = result; 00607 return result; 00608 } /*leaf*/ 00609 00610 /*not leaf*/ 00611 else{ 00612 00613 #if DBG 00614 assert(RT_left(RTnode)!=RT_NULL&&RT_right(RTnode)!=RT_NULL); 00615 #endif 00616 left = sat_GenerateFwdIP(manager,cm,RT_left(RTnode),cut); 00617 right = sat_GenerateFwdIP(manager,cm,RT_right(RTnode),cut); 00618 if(RT_pivot(RTnode)<0){ 00619 int class_; 00620 class_ = RT_pivot(RTnode)-DUMMY; 00621 #if DBG 00622 assert(class_>0); 00623 #endif 00624 if(class_>cut) 00625 local=0; 00626 } 00627 else{ 00628 node = SATnormalNode(RT_pivot(RTnode)); 00629 if((SATflags(node)&IsGlobalVarMask)|| 00630 (SATclass(node)>cut)) 00631 local = 0; 00632 } 00633 if(local==0){ 00634 result = PureSat_And(manager,left,right); 00635 00636 } 00637 else{ 00638 result = PureSat_Or(manager,left,right); 00639 00640 } 00641 }/* else{ not leaf*/ 00642 00643 cm->nodesArray = manager->NodesArray; 00644 RT_IPnode(RTnode) = result; 00645 return result; 00646 00647 } 00648 00649 00663 bAigEdge_t sat_GenerateBwdIP(bAig_Manager_t* manager, 00664 satManager_t *cm, 00665 RTnode_t RTnode, 00666 int cut) 00667 { 00668 int i; 00669 long node,node1, left, right, result, *lp, *lp1; 00670 int IPTrue=0, local=1, allGV=1; 00671 RTManager_t * rm = cm->rm; 00672 00673 manager->class_ = cut; 00674 00675 if(RT_flag(RTnode)&RT_VisitedMask){ 00676 #if DBG 00677 assert(RT_IPnode(RTnode)!=-1); 00678 #endif 00679 00680 return RT_IPnode(RTnode); 00681 } 00682 #if DBG 00683 assert(RT_IPnode(RTnode)==-1); 00684 #endif 00685 RT_flag(RTnode) |= RT_VisitedMask; 00686 00687 if(RT_pivot(RTnode)==0){ /*leaf*/ 00688 00689 #if DBG 00690 assert(RT_left(RTnode)==RT_NULL&&RT_right(RTnode)==RT_NULL); 00691 assert(RT_oriClsIdx(RTnode)==0); 00692 #endif 00693 result = bAig_Zero; 00694 if(RT_oriClsIdx(RTnode)) 00695 lp = (long*)SATfirstLit(RT_oriClsIdx(RTnode)); 00696 else 00697 00698 lp = RT_formula(RTnode) + cm->rm->fArray; 00699 lp1 = lp; 00700 for(i=0;i<RT_fSize(RTnode);i++,lp++){ 00701 if(*lp == DUMMY) 00702 continue; 00703 else{ 00704 assert(*lp>0); 00705 } 00706 if(RT_oriClsIdx(RTnode))/*is CNF*/ 00707 node = SATgetNode(*lp); 00708 else /*is AIG*/ 00709 node = *lp; 00710 node = SATnormalNode(node); 00711 if(SATflags(node)&IsGlobalVarMask) 00712 continue; 00713 else 00714 allGV = 0; 00715 00716 if(SATclass(node)<=cut){ 00717 IPTrue = 1; 00718 break; 00719 } 00720 } 00721 00722 if(IPTrue||allGV){ 00723 RT_IPnode(RTnode) = bAig_One; 00724 return bAig_One; 00725 } 00726 00727 lp = lp1; 00728 for(i=0;i<RT_fSize(RTnode);i++,lp++){ 00729 if(RT_oriClsIdx(RTnode))/*is CNF*/ 00730 node = SATgetNode(*lp); 00731 else /*is AIG*/ 00732 node = *lp; 00733 node1 = SATnormalNode(node); 00734 if(SATflags(node1)&IsGlobalVarMask){ 00735 result = PureSat_Or(manager,result,node); 00736 cm->nodesArray = manager->NodesArray; 00737 } 00738 } 00739 RT_IPnode(RTnode) = result; 00740 return result; 00741 } /*leaf*/ 00742 00743 /*not leaf*/ 00744 else{ 00745 00746 #if DBG 00747 assert(RT_left(RTnode)!=RT_NULL&&RT_right(RTnode)!=RT_NULL); 00748 #endif 00749 left = sat_GenerateBwdIP(manager,cm,RT_left(RTnode),cut); 00750 right = sat_GenerateBwdIP(manager,cm,RT_right(RTnode),cut); 00751 if(RT_pivot(RTnode)<0){ 00752 int class_; 00753 class_ = RT_pivot(RTnode)-DUMMY; 00754 #if DBG 00755 assert(class_>0); 00756 #endif 00757 if(class_<=cut) 00758 local=0; 00759 } 00760 else{ 00761 node = SATnormalNode(RT_pivot(RTnode)); 00762 00763 if((SATflags(node)&IsGlobalVarMask)|| 00764 (SATclass(node)<=cut)) 00765 local = 0; 00766 } 00767 if(local==0){ 00768 result = PureSat_And(manager,left,right); 00769 00770 } 00771 else{ 00772 result = PureSat_Or(manager,left,right); 00773 00774 } 00775 }/* else{ not leaf*/ 00776 00777 cm->nodesArray = manager->NodesArray; 00778 RT_IPnode(RTnode) = result; 00779 return result; 00780 00781 } 00782 00795 void ResetRTree(RTManager_t *rm) 00796 { 00797 int i; 00798 for(i=RTnodeSize;i<=rm->aSize;i+=RTnodeSize){ 00799 RT_IPnode(i) = -1; 00800 RT_flag(i) &= RT_ResetVisitedMask; 00801 } 00802 00803 return; 00804 } 00805 00817 void 00818 RT_Free(RTManager_t *rm) 00819 { 00820 FREE(rm->nArray); 00821 FREE(rm->fArray); 00822 FREE(rm); 00823 } 00824 00836 void 00837 sat_MarkLayerProperty(satManager_t *cm, 00838 long v, 00839 int layer) 00840 { 00841 satVariable_t *var = SATgetVariable(v); 00842 00843 if((v==bAig_NULL)) 00844 return; 00845 00846 if(!(SATflags(v)&CoiMask)){ 00847 00848 return; 00849 } 00850 00851 /*already assigned score*/ 00852 if(SATflags(v)&Visited2Mask){ 00853 00854 return; 00855 } 00856 00857 var->scores[0] = SCOREUNIT*layer; 00858 var->scores[1] = SCOREUNIT*layer; 00859 SATflags(v) |= Visited2Mask; 00860 00861 00862 if((SATflags(v)&StateBitMask)&& 00863 (SATclass(v)<=cm->Length)){ 00864 00865 return; 00866 } 00867 00868 sat_MarkLayerProperty(cm,SATleftChild(v),layer); 00869 sat_MarkLayerProperty(cm,SATrightChild(v),layer); 00870 00871 } 00872 00885 void sat_MarkLayer(satManager_t *cm, 00886 long v, 00887 int layer) 00888 { 00889 satVariable_t *var = SATgetVariable(v); 00890 00891 if((v==bAig_NULL)) 00892 return; 00893 00894 if(!(SATflags(v)&CoiMask)){ 00895 00896 return; 00897 } 00898 00899 /*already assigned score*/ 00900 if(SATflags(v)&Visited2Mask){ 00901 00902 return; 00903 } 00904 00905 var->scores[0] = SCOREUNIT*layer; 00906 var->scores[1] = SCOREUNIT*layer; 00907 SATflags(v) |= Visited2Mask; 00908 00909 00910 if((SATflags(v)&StateBitMask)){ 00911 00912 return; 00913 } 00914 00915 sat_MarkLayer(cm,SATleftChild(v),layer); 00916 sat_MarkLayer(cm,SATrightChild(v),layer); 00917 00918 } 00919 00933 void sat_MarkLayerInitState(satManager_t *cm, 00934 long v, 00935 int layer) 00936 { 00937 satVariable_t *var = SATgetVariable(v); 00938 00939 if((v==bAig_NULL)) 00940 return; 00941 00942 if(!(SATflags(v)&CoiMask)){ 00943 00944 return; 00945 } 00946 00947 /*already assigned score*/ 00948 if(SATflags(v)&Visited2Mask){ 00949 00950 return; 00951 } 00952 00953 var->scores[0] = SCOREUNIT*layer; 00954 var->scores[1] = SCOREUNIT*layer; 00955 SATflags(v) |= Visited2Mask; 00956 00957 00958 /*if((SATflags(v)&StateBitMask)){ 00959 fprintf(vis_stderr,"%d ISV return\n",SATnormalNode(v)); 00960 return; 00961 }*/ 00962 00963 sat_MarkLayerInitState(cm,SATleftChild(v),layer); 00964 sat_MarkLayerInitState(cm,SATrightChild(v),layer); 00965 00966 } 00967 00980 void sat_MarkLayerLatch(satManager_t *cm, 00981 long v, 00982 int layer) 00983 { 00984 satVariable_t *var = SATgetVariable(v); 00985 00986 if((v==bAig_NULL)) 00987 return; 00988 00989 if(!(SATflags(v)&CoiMask)){ 00990 00991 return; 00992 } 00993 00994 /*not assigned score yet*/ 00995 if(!(SATflags(v)&Visited2Mask)){ 00996 var->scores[0] = SCOREUNIT*layer; 00997 var->scores[1] = SCOREUNIT*layer; 00998 SATflags(v) |= Visited2Mask; 00999 01000 } 01001 sat_MarkLayer(cm,SATleftChild(v),layer); 01002 sat_MarkLayer(cm,SATrightChild(v),layer); 01003 01004 } 01005 01018 void sat_InitLayerScore(satManager_t * cm){ 01019 int i,j,k,layer; 01020 long v; 01021 st_table *table; 01022 st_generator * stgen, *stgen1; 01023 satVariable_t *var; 01024 01025 int objExist; 01026 int inverted; 01027 long *plit, nv; 01028 int size; 01029 int count0, count1; 01030 satArray_t *ordered, *newOrdered; 01031 array_t * layerArray = array_alloc(st_table *,cm->LatchLevel+1); 01032 01033 for(k=1;k<=cm->LatchLevel;k++){ 01034 cm->assignedArray[k]=0; 01035 cm->numArray[k]=0; 01036 } 01037 01038 cm->currentLevel = cm->LatchLevel; 01039 01040 for(i=satNodeSize;i<cm->nodesArraySize;i+=satNodeSize){ 01041 SATflags(i)&=ResetVisited2Mask; 01042 } 01043 01044 01045 sat_MarkLayerInitState(cm,cm->InitState,cm->LatchLevel); 01046 01047 sat_MarkLayerProperty(cm,cm->property,cm->LatchLevel); 01048 01049 01050 st_foreach_item(cm->layerTable,stgen,&table,&layer) 01051 array_insert(st_table *,layerArray,layer,table); 01052 01053 for(i=cm->LatchLevel;i>=1;i--){ 01054 table = array_fetch(st_table*,layerArray,i); 01055 st_foreach_item(table,stgen1,&v,NIL(char*)){ 01056 sat_MarkLayerLatch(cm,v,i); 01057 01058 } 01059 } 01060 01061 array_free(layerArray); 01062 01063 for(i=bAigNodeSize;i<cm->nodesArraySize;i+=bAigNodeSize){ 01064 if(SATflags(i)&Visited2Mask){ 01065 int layer; 01066 SATflags(i)&=ResetVisited2Mask; 01067 var = SATgetVariable(i); 01068 #if DBG 01069 assert(var->scores[0]%SCOREUNIT==0); 01070 #endif 01071 layer = var->scores[0]/SCOREUNIT; 01072 cm->numArray[layer]++; 01073 } 01074 } 01075 01076 if(cm->option->verbose >= 2){ 01077 for(i=1;i<=cm->LatchLevel;i++){ 01078 fprintf(vis_stdout,"Level %d:%d\n",i,cm->numArray[i]); 01079 } 01080 } 01081 01082 01083 ordered = cm->orderedVariableArray; 01084 if(ordered == 0) 01085 ordered = sat_ArrayAlloc(cm->initNumVariables); 01086 else 01087 ordered->num = 0; 01088 cm->orderedVariableArray = ordered; 01089 01090 objExist = 0; 01091 01092 01093 for(i=satNodeSize; i<cm->nodesArraySize; i+=satNodeSize) { 01094 v = i; 01095 if((SATflags(v) & IsBDDMask)) { 01096 continue; 01097 } 01098 if((SATflags(v) & IsCNFMask)) { 01099 size = SATnumLits(v); 01100 plit = (long*)SATfirstLit(v); 01101 for(j=0; j<size; j++, plit++) { 01102 nv = SATgetNode(*plit); 01103 inverted = !(SATisInverted(nv)); 01104 nv = SATnormalNode(nv); 01105 var = SATgetVariable(nv); 01106 var->litsCount[inverted]++; 01107 } 01108 continue; 01109 } 01110 if(!(SATflags(v) & CoiMask)) continue; 01111 if(!(SATflags(v) & VisitedMask) && objExist) continue; 01112 01113 if(SATvalue(v) != 2 && SATlevel(v) == 0) continue; 01114 01115 count0 = count1 = SATnFanout(v); 01116 if(count0 == 0 && SATleftChild(v) == 2 && SATrightChild(v) == 2) { 01117 count0 = 0; 01118 count1 = 0; 01119 } 01120 else if(SATleftChild(v) != 2) { 01121 count0 += 2; 01122 count1++; 01123 } 01124 else { 01125 count0 += 3; 01126 count1 += 3; 01127 } 01128 01129 var = SATgetVariable(v); 01130 var->litsCount[0] += count0; 01131 var->litsCount[1] += count1; 01132 01133 sat_ArrayInsert(ordered, v); 01134 } 01135 01136 for(i=0; i<cm->unitLits->num; i++) { 01137 v = cm->unitLits->space[i]; 01138 v = SATnormalNode(v); 01139 SATflags(v) |= NewMask; 01140 } 01141 if(cm->assertion) { 01142 for(i=0; i<cm->assertion->num; i++) { 01143 v = cm->assertion->space[i]; 01144 v = SATnormalNode(v); 01145 SATflags(v) |= NewMask; 01146 } 01147 } 01148 01149 newOrdered = sat_ArrayAlloc((ordered->num) * 2); 01150 size = ordered->num; 01151 for(i=0; i<size; i++) { 01152 v = ordered->space[i]; 01153 var = SATgetVariable(v); 01154 var->lastLitsCount[0] = var->litsCount[0]; 01155 var->lastLitsCount[1] = var->litsCount[1]; 01156 var->scores[0] += var->lastLitsCount[0]; 01157 var->scores[1] += var->lastLitsCount[1]; 01158 01159 if(SATflags(v) & NewMask); 01160 else if(var->scores[0] == 0 && var->scores[1] == 0 && !(SATflags(v) & NewMask)) { 01161 sat_ArrayInsert(cm->pureLits, (v)); 01162 } 01163 else if(var->scores[0] == 0 && !(SATflags(v) & NewMask)) { 01164 sat_ArrayInsert(cm->pureLits, (v)); 01165 } 01166 else if(var->scores[1] == 0 && !(SATflags(v) & NewMask)) { 01167 sat_ArrayInsert(cm->pureLits, SATnot(v)); 01168 } 01169 else { 01170 sat_ArrayInsert(newOrdered, v); 01171 sat_ArrayInsert(newOrdered, (var->scores[0] > var->scores[1]) ? var->scores[0] : var->scores[1]); 01172 } 01173 } 01174 01175 for(i=0; i<cm->unitLits->num; i++) { 01176 v = cm->unitLits->space[i]; 01177 v = SATnormalNode(v); 01178 SATflags(v) &= ResetNewMask; 01179 } 01180 if(cm->assertion) { 01181 for(i=0; i<cm->assertion->num; i++) { 01182 v = cm->assertion->space[i]; 01183 v = SATnormalNode(v); 01184 SATflags(v) &= ResetNewMask; 01185 } 01186 } 01187 01188 cm->orderedVariableArray = ordered; 01189 size = newOrdered->num; 01190 qsort(newOrdered->space, size>>1, sizeof(long)*2, ScoreCompare); 01191 01192 cm->currentVarPos = 0; 01193 ordered->num = 0; 01194 for(i=0; i<size; i++) { 01195 v = newOrdered->space[i]; 01196 var = SATgetVariable(v); 01197 var->pos = (i>>1); 01198 sat_ArrayInsert(ordered, v); 01199 i++; 01200 } 01201 01202 sat_ArrayFree(newOrdered); 01203 01204 if(cm->option->verbose > 3) 01205 sat_PrintScore(cm); 01206 01207 } 01208 01221 void 01222 sat_GenerateCore_All(satManager_t * cm) 01223 { 01224 int i,j,value; 01225 long *lit, ante, node, tmp1; 01226 int count, inverted; 01227 satLevel_t * d; 01228 satArray_t *clauseArray = sat_ArrayAlloc(1); 01229 int objectFlag; 01230 01231 long conflicting, ante2; 01232 int nMarked,first; 01233 long v,left,right,result,*lp,*tmpIP; 01234 long *space,*tmp; 01235 satArray_t *implied; 01236 RTnode_t tmprt; 01237 int size = 0, *bLevel; 01238 long *fdaLit=ALLOC(long,1); 01239 boolean endnow; 01240 RTManager_t * rm = cm->rm; 01241 01242 cm->status = 0; 01243 count = 0; 01244 d = SATgetDecision(0); 01245 sat_ImplyArrayWithAnte(cm,d,cm->obj); 01246 sat_ImplyArrayWithAnte(cm,d,cm->auxObj); 01247 sat_ImplyArrayWithAnte(cm,d,cm->assertArray); 01248 01249 01250 01251 if(cm->status==0){ 01252 for(i=satNodeSize; i<cm->nodesArraySize; i+=satNodeSize){ 01253 node = i; 01254 if((SATflags(node)&IsCNFMask)&&(SATnumLits(node)==1)){ 01255 lit = (long*)SATfirstLit(node); 01256 tmp1 = SATgetNode(*lit); 01257 inverted = SATisInverted(tmp1); 01258 tmp1 = SATnormalNode(tmp1); 01259 01260 01261 value = !inverted; 01262 if(SATvalue(tmp1) < 2) { 01263 if(SATvalue(tmp1) == value) continue; 01264 else { 01265 cm->status = SAT_UNSAT; 01266 d->conflict = node; 01267 break; 01268 } 01269 } 01270 01271 SATvalue(tmp1) = !inverted; 01272 SATmakeImplied(tmp1, d); 01273 SATante(tmp1) = node; 01274 if((SATflags(tmp1) & InQueueMask) == 0) { 01275 sat_Enqueue(cm->queue, tmp1); 01276 SATflags(tmp1) |= InQueueMask; 01277 } 01278 01279 } 01280 } 01281 } 01282 01283 01284 if(cm->status==0){ 01285 sat_ImplicationMain(cm, d); 01286 } 01287 01288 if(d->conflict == 0) { 01289 fprintf(vis_stderr,"There should be a conflict\n"); 01290 exit(0); 01291 } 01292 01293 conflicting = d->conflict; 01294 nMarked = 0; 01295 01296 sat_MarkNodeInConflict( 01297 cm, d, &nMarked, &objectFlag, bLevel, clauseArray); 01298 /* Traverse implication graph backward*/ 01299 first = 1; 01300 implied = d->implied; 01301 space = implied->space+implied->num-1; 01302 01303 01304 01305 if(cm->option->coreGeneration){ 01306 /*if last conflict is CNF*/ 01307 if(SATflags(conflicting)&IsCNFMask){ 01308 /*is conflict CNF*/ 01309 if(SATflags(conflicting)&IsConflictMask){ 01310 if(!st_lookup(cm->RTreeTable,(char*)conflicting,&tmprt)){ 01311 fprintf(vis_stderr,"RTree node of conflict cnf %ld is not in RTreeTable\n",ante); 01312 exit(0); 01313 } 01314 else{ 01315 rm->root = tmprt; 01316 #if PR 01317 fprintf(vis_stdout,"Get formula for CONFLICT CLAUSE:%d\n",ante); 01318 #endif 01319 } 01320 } 01321 /*CNF but not conflict*/ 01322 else{ 01323 rm->root = RTCreateNode(rm); 01324 01325 size = SATnumLits(conflicting); 01326 RT_fSize(rm->root) = size; 01327 lp = (long*)SATfirstLit(conflicting); 01328 sat_BuildRT(cm,rm->root, lp, tmpIP,size,0); 01329 } 01330 } 01331 /*if last conflict is AIG*/ 01332 else{ 01333 rm->root = RTCreateNode(rm); 01334 node = SATnormalNode(conflicting); 01335 left = SATleftChild(node); 01336 right = SATrightChild(node); 01337 result = PureSat_IdentifyConflict(cm,left,right,conflicting); 01338 inverted = SATisInverted(left); 01339 left = SATnormalNode(left); 01340 left = inverted ? SATnot(left) : left; 01341 01342 inverted = SATisInverted(right); 01343 right = SATnormalNode(right); 01344 right = inverted ? SATnot(right) : right; 01345 01346 j = node; 01347 01348 if(result == 1){ 01349 tmp = ALLOC(long,3); 01350 tmp[0] = left; 01351 tmp[1] = SATnot(j); 01352 size = 2; 01353 } 01354 else if(result == 2){ 01355 tmp = ALLOC(long,3); 01356 tmp[0] = right; 01357 tmp[1] = SATnot(j); 01358 size = 2; 01359 } 01360 else if(result == 3){ 01361 tmp = ALLOC(long,4); 01362 tmp[0] = SATnot(left); 01363 tmp[1] = SATnot(right); 01364 tmp[2] = j; 01365 size = 3; 01366 } 01367 else{ 01368 fprintf(vis_stderr,"wrong returned result value, exit\n"); 01369 exit(0); 01370 } 01371 01372 lp = tmp; 01373 sat_BuildRT(cm,rm->root, lp, tmpIP,size,1); 01374 FREE(tmp); 01375 } 01376 } 01377 01378 01379 endnow = FALSE; 01380 for(i=implied->num-1; i>=0; i--, space--) { 01381 if(endnow) 01382 break; 01383 v = *space; 01384 if(SATflags(v) & VisitedMask) { 01385 SATflags(v) &= ResetVisitedMask; 01386 --nMarked; 01387 01388 if(nMarked == 0 && (!first || i==0)) { 01389 /*value = SATvalue(v);*/ 01390 *fdaLit = v^(!value); 01391 sat_ArrayInsert(clauseArray, *fdaLit); 01392 /*break;*/ 01393 endnow = TRUE; 01394 } 01395 01396 01397 if(cm->option->coreGeneration){ 01398 ante = SATante(v); 01399 if(ante==0){ 01400 if(!(st_lookup(cm->anteTable, (char *)SATnormalNode(v),&ante))){ 01401 fprintf(vis_stderr,"ante = 0 and is not in anteTable %ld\n",v); 01402 exit(0); 01403 } 01404 } 01405 01406 /*build non-leaf node*/ 01407 tmprt = RTCreateNode(rm); 01408 RT_pivot(tmprt) = SATnormalNode(v); 01409 RT_right(tmprt) = rm->root; 01410 rm->root = tmprt; 01411 01412 if((SATflags(ante)&IsConflictMask)&&(SATflags(ante)&IsCNFMask)){ 01413 if(!st_lookup(cm->RTreeTable,(char*)ante,&tmprt)){ 01414 fprintf(vis_stderr,"RTree node of conflict cnf %ld is not in RTreeTable\n",ante); 01415 exit(0); 01416 } 01417 else{ 01418 RT_left(rm->root) = tmprt; 01419 #if PR 01420 fprintf(vis_stdout,"Get formula for CONFLICT CLAUSE:%d\n",ante); 01421 #endif 01422 } 01423 } 01424 else{ /* if not conflict CNF*/ 01425 /*left*/ 01426 tmprt = RTCreateNode(rm); 01427 RT_left(rm->root) = tmprt; 01428 /*left is AIG*/ 01429 if(!(SATflags(ante) & IsCNFMask)){ 01430 /*generate formula for left*/ 01431 tmp = ALLOC(long,3); 01432 value = SATvalue(v); 01433 node = SATnormalNode(v); 01434 node = value==1?node:SATnot(node); 01435 tmp[0] = node; 01436 01437 size = 1; 01438 if(ante != SATnormalNode(v)){ 01439 value = SATvalue(ante); 01440 node = SATnormalNode(ante); 01441 node = value==1?SATnot(node):node; 01442 tmp[1] = node; 01443 size++; 01444 ante2 = SATante2(v); 01445 if(ante2){ 01446 value = SATvalue(ante2); 01447 node = SATnormalNode(ante2); 01448 node = value==1?SATnot(node):node; 01449 tmp[2] = node; 01450 size++; 01451 } 01452 } 01453 01454 lp = tmp; 01455 sat_BuildRT(cm,tmprt,lp,tmpIP,size,1); 01456 FREE(tmp); 01457 } 01458 /* left is CNF*/ 01459 else{ 01460 01461 lp = (long*)SATfirstLit(ante); 01462 size = SATnumLits(ante); 01463 RT_fSize(tmprt) = size; 01464 sat_BuildRT(cm,tmprt, lp, tmpIP,size,0); 01465 } 01466 } /*else{ // if not conflict CNF*/ 01467 01468 }/*if(cm->option->coreGeneration){*/ 01469 01470 sat_MarkNodeInImpliedNode( 01471 cm, d, v, &nMarked, &objectFlag, bLevel, clauseArray); 01472 }/*if(SATflags(v) & VisitedMask) {*/ 01473 first = 0; 01474 }/*for(i=implied->num-1; i>=*/ 01475 01476 01477 if(cm->option->verbose >= 2) 01478 fprintf(vis_stdout,"total # of RTree node:%ld\n",rm->aSize/RTnodeSize); 01479 01480 sat_ArrayFree(clauseArray); 01481 FREE(fdaLit); 01482 if(cm->option->arosat) 01483 AS_Undo(cm,d); 01484 else 01485 sat_Undo(cm,d); 01486 cm->status = SAT_UNSAT; 01487 } 01488 01489 01503 void sat_ASmergeLevel(satManager_t *cm) 01504 { 01505 int base; 01506 long v; 01507 satVariable_t *var; 01508 int *assignedArray = cm->assignedArray; 01509 int * numArray = cm->numArray,level=0; 01510 01511 if(cm->option->verbose >= 2) 01512 fprintf(vis_stdout,"MERGE LEVEL\n"); 01513 while(cm->LatchLevel>0){ 01514 if(cm->option->verbose >= 2) 01515 fprintf(vis_stdout,"Merge level %d and %d\n",cm->LatchLevel, cm->LatchLevel-1); 01516 level++; 01517 cm->LatchLevel--; 01518 if(cm->numArray[cm->LatchLevel]>0) 01519 break; 01520 } 01521 if(cm->option->verbose >= 2) 01522 fprintf(vis_stdout,"After Merge,Latch level:%d\n",cm->LatchLevel); 01523 #if DBG 01524 assert(cm->LatchLevel>0); 01525 #endif 01526 01527 for(v=satNodeSize;v<cm->initNodesArraySize;v+=satNodeSize){ 01528 if(!SATflags(v)&CoiMask) 01529 continue; 01530 var = SATgetVariable(v); 01531 base = var->scores[0]/SCOREUNIT; 01532 if(base==cm->LatchLevel+level){ 01533 var->scores[0] = cm->LatchLevel*SCOREUNIT + var->scores[0]%SCOREUNIT; 01534 var->scores[1] = cm->LatchLevel*SCOREUNIT + var->scores[1]%SCOREUNIT; 01535 } 01536 } 01537 assignedArray[cm->LatchLevel]+=assignedArray[cm->LatchLevel+level]; 01538 numArray[cm->LatchLevel]+=numArray[cm->LatchLevel+level]; 01539 01540 } 01541 01554 int sat_CE_CNF( 01555 satManager_t *cm, 01556 satLevel_t *d, 01557 int v, 01558 satArray_t *wl) 01559 { 01560 long size, i, *space; 01561 long lit, *plit, dir; 01562 long nv, tv, *oplit, *wlit; 01563 int isInverted, value; 01564 long inverted, clit; 01565 satStatistics_t *stats; 01566 satOption_t *option; 01567 satQueue_t *Q; 01568 01569 size = wl->num; 01570 space = wl->space; 01571 Q = cm->queue; 01572 stats = cm->each; 01573 option = cm->option; 01574 01575 for(i=0; i<size; i++) { 01576 plit = (long*)space[i]; 01577 01578 if(plit == 0 || *plit == 0) { 01579 01580 continue; 01581 } 01582 01583 lit = *plit; 01584 dir = SATgetDir(lit); 01585 oplit = plit; 01586 01587 while(1) { 01588 oplit += dir; 01589 if(*oplit <=0) { 01590 if(dir == 1) nv =- (*oplit); 01591 if(dir == SATgetDir(lit)) { 01592 oplit = plit; 01593 dir = -dir; 01594 continue; 01595 } 01596 01597 tv = SATgetNode(*wlit); 01598 isInverted = SATisInverted(tv); 01599 tv = SATnormalNode(tv); 01600 value = SATvalue(tv) ^ isInverted; 01601 if(value == 0) { /* conflict happens*/ 01602 01603 return CONFLICT; 01604 } 01605 else if(value > 1) { /* implication*/ 01606 /*implication can only be made on the other wl*/ 01607 01608 break; 01609 } 01610 01611 break; 01612 } 01613 01614 clit = *oplit; 01615 01616 tv = SATgetNode(clit); 01617 inverted = SATisInverted(tv); 01618 tv = SATnormalNode(tv); 01619 value = SATvalue(tv) ^ inverted; 01620 01621 if(SATisWL(clit)) { /* found other watched literal*/ 01622 wlit = oplit; 01623 /*a little diff from zchaff, if otherwl==1, break*/ 01624 if(value == 1) { 01625 break; 01626 } 01627 /*since it is otherwl, it can't be zero. Here it is unknow*/ 01628 continue; 01629 } 01630 01631 if(value == 0) 01632 continue; 01633 01634 /*now it is 1 or unknow*/ 01635 break; 01636 }/*while(1)*/ 01637 }/*for*/ 01638 return NO_CONFLICT; 01639 } 01640 01652 int 01653 sat_CE(satManager_t *cm, 01654 satLevel_t *d, 01655 long v, 01656 int dfs, 01657 int value) 01658 { 01659 long value1,*fan; 01660 long cur, i, size; 01661 long left, right; 01662 satVariable_t *var; 01663 satArray_t *wlArray; 01664 01665 long enforce=0; 01666 01667 v = SATnormalNode(v); 01668 01669 var = SATgetVariable(v); 01670 01671 wlArray = var->wl[value^1]; 01672 01673 /*need recovery*/ 01674 SATvalue(v) = value; 01675 01676 /* implcation on CNF*/ 01677 if(wlArray && wlArray->size) { 01678 if(sat_CE_CNF(cm, d, v, wlArray)==CONFLICT){ 01679 enforce = 1; 01680 } 01681 } 01682 01683 /*need recovery*/ 01684 SATvalue(v) = value; 01685 01686 if(enforce==0){ 01687 /* implication on AIG*/ 01688 fan = SATfanout(v); 01689 size = SATnFanout(v); 01690 for(i=0; i<size; i++, fan++) { 01691 cur = *fan; 01692 cur = cur >> 1; 01693 cur = SATnormalNode(cur); 01694 left = SATleftChild(cur); 01695 right = SATrightChild(cur); 01696 value1 = SATgetValue(left, right, cur); 01697 if(value1==1||value1==5||value1==9||value1==13||value1==17 01698 ||value1==20||value1==33||value1==49){ 01699 /*fprintf(vis_stdout,"AIG Output enforce\n");*/ 01700 enforce=1; 01701 break; 01702 } 01703 } 01704 } 01705 01706 if(enforce==0){ 01707 left = SATleftChild(v); 01708 right = SATrightChild(v); 01709 if(left!=2&&right!=2){ 01710 value1 = SATgetValue(left, right, v); 01711 if(value1==1||value1==5||value1==9||value1==13||value1==17 01712 ||value1==20||value1==33||value1==49){ 01713 /*fprintf(vis_stdout,"AIG Children enforce\n");*/ 01714 enforce=1; 01715 } 01716 } 01717 } 01718 01719 01720 SATvalue(v)=2; 01721 01722 return enforce; 01723 01724 } 01725 01739 int sat_ASDec(satManager_t *cm, 01740 satLevel_t *d, 01741 long v) 01742 { 01743 int dfs; 01744 int *numArray,*assignedArray; 01745 satVariable_t *var=SATgetVariable(v); 01746 01747 assignedArray = cm->assignedArray; 01748 numArray = cm->numArray; 01749 01750 v = SATnormalNode(v); 01751 dfs = var->scores[0]/SCOREUNIT; 01752 01753 #if DBG 01754 01755 assert(dfs==cm->LatchLevel); 01756 assert(!(SATflags(SATnormalNode(v)) & InQueueMask)); 01757 assert(SATvalue(SATnormalNode(v))==2); 01758 #endif 01759 if(!(SATflags(SATnormalNode(v))&AssignedMask)){ 01760 SATflags(SATnormalNode(v))|=AssignedMask; 01761 assignedArray[dfs]++; 01762 /* if(dfs==cm->OriLevel) 01763 // fprintf(vis_stdout,"Assign Level %d: %d dfs=%d assArray[%d]=%d\n", 01764 // d->level,v,dfs,dfs,cm->assignedArray[dfs]);*/ 01765 01766 if(cm->assignedArray[dfs]==cm->numArray[dfs]) 01767 sat_ASmergeLevel(cm); 01768 /*fprintf(vis_stdout,"Decisionlevel:%d: %d dfs=%d,assArray[%d]=%d, numArray[%d]=%d\n", 01769 // d->level,v,dfs,dfs,assignedArray[dfs],dfs,numArray[dfs]);*/ 01770 } 01771 return 0; 01772 } 01773 01785 int 01786 sat_ASImp(satManager_t *cm, 01787 satLevel_t *d, 01788 long v, 01789 int value) 01790 { 01791 int dfs; 01792 long tmpv; 01793 int *numArray,*assignedArray; 01794 satVariable_t *var=SATgetVariable(v); 01795 01796 assignedArray = cm->assignedArray; 01797 numArray = cm->numArray; 01798 01799 v = SATnormalNode(v); 01800 01801 #if DBG 01802 assert(SATvalue(v)==2); 01803 #endif 01804 dfs = var->scores[0]/SCOREUNIT; 01805 01806 01807 if(dfs==cm->LatchLevel){ 01808 if(!(SATflags(SATnormalNode(v))&AssignedMask)){ 01809 01810 SATflags(SATnormalNode(v))|=AssignedMask; 01811 assignedArray[dfs]++; 01812 01813 #if DBG 01814 assert(assignedArray[dfs]<=numArray[dfs]); 01815 #endif 01816 if(cm->assignedArray[dfs]==cm->numArray[dfs]) 01817 sat_ASmergeLevel(cm); 01818 01819 } 01820 01821 return 0; 01822 } 01823 else{ 01824 /*if conflict enforcing*/ 01825 if(sat_CE(cm,d,v,dfs,value)){ 01826 01827 if(!(SATflags(SATnormalNode(v))&AssignedMask)){ 01828 SATflags(SATnormalNode(v))|=AssignedMask; 01829 assignedArray[dfs]++; 01830 01831 #if DBG 01832 assert(assignedArray[dfs]<=numArray[dfs]); 01833 #endif 01834 01835 } 01836 01837 return 0; 01838 } 01839 /*else implication is prohibited*/ 01840 else{ 01841 01842 #if DBG 01843 assert(value==0||value==1); 01844 #endif 01845 if(value==0) 01846 tmpv = -1; 01847 else 01848 tmpv = 1; 01849 SATgetVariable(v)->RecVal = tmpv; 01850 01851 return 1; 01852 } 01853 } 01854 return 0; 01855 }