VIS

src/sat/satCore.c

Go to the documentation of this file.
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 }