00001 
00019 #include "reo.h"
00020 
00024 
00025 #define AddToLinkedList( ppList, pLink )   (((pLink)->Next = *(ppList)), (*(ppList) = (pLink)))
00026 
00030 
00043 double reoReorderSwapAdjacentVars( reo_man * p, int lev0, int fMovingUp )
00044 {
00045         
00046         int lev1 = lev0 + 1, lev2 = lev0 + 2;
00047         
00048         reo_unit * pLoop, * pUnit;
00049         
00050         reo_unit * pNewPlane20, * pNewPlane21, * pNewPlane20R;
00051         reo_unit * pUnitE, * pUnitER, * pUnitT;
00052         
00053         reo_unit * pNew1E, * pNew1T, * pNew2E, * pNew2T;
00054         reo_unit * pNew1ER, * pNew2ER;
00055         
00056         reo_unit * pListOld0 = p->pPlanes[lev0].pHead;
00057         reo_unit * pListOld1 = p->pPlanes[lev1].pHead;
00058         
00059         reo_unit * pListNew0 = NULL, ** ppListNew0 = &pListNew0;
00060         reo_unit * pListNew1 = NULL, ** ppListNew1 = &pListNew1; 
00061         reo_unit * pListTemp = NULL, ** ppListTemp = &pListTemp; 
00062         
00063         int fComp, fCompT, fFound, nWidthCofs, HKey, fInteract, temp, c;
00064         
00065         int nNodesUpMovedDown  = 0;
00066         int nNodesDownMovedUp  = 0;
00067         int nNodesUnrefRemoved = 0;
00068         int nNodesUnrefAdded   = 0;
00069         int nWidthReduction    = 0;
00070         double AplWeightTotalLev0;
00071         double AplWeightTotalLev1;
00072         double AplWeightHalf;
00073         double AplWeightPrev;
00074         double AplWeightAfter;
00075         double nCostGain;     
00076 
00077         
00078         assert( lev0 >= 0 && lev1 < p->nSupp );
00079         pListOld0 = p->pPlanes[lev0].pHead;
00080         pListOld1 = p->pPlanes[lev1].pHead;
00081 
00082         
00083         assert( p->pPlanes[lev0].statsNodes && p->pPlanes[lev1].statsNodes );
00084         assert( pListOld0 && pListOld1 );
00085 
00086         if ( p->fMinWidth )
00087         {
00088                 
00089                 reoProfileWidthVerifyLevel( p->pPlanes + lev0, lev0 );
00090                 reoProfileWidthVerifyLevel( p->pPlanes + lev1, lev1 );
00091                 
00092                 nWidthCofs = 0;
00093         }
00094         else if ( p->fMinApl )
00095         {
00096                 AplWeightPrev      = p->nAplCur;
00097                 AplWeightAfter     = p->nAplCur;
00098                 AplWeightTotalLev0 = 0.0;
00099                 AplWeightTotalLev1 = 0.0;
00100         }
00101 
00102         
00103         fInteract = 0; 
00104         for ( pUnit = pListOld0; pUnit; pUnit = pUnit->Next )
00105         {
00106                 if ( pUnit->pT->lev == lev1 || Unit_Regular(pUnit->pE)->lev == lev1 )
00107                 {
00108                         fInteract = 1;
00109                         break;
00110                 }
00111                 
00112                 pUnit->lev = lev1;
00113         }
00114 
00115         
00116         p->nSwaps++;
00117         if ( !fInteract )
00118 
00119         {
00120                 
00121                 p->nNISwaps++;
00122 
00123                 
00124                 if ( p->fMinWidth )
00125                 {
00126                         
00127                         for ( pUnit = pListOld1; pUnit; pUnit = pUnit->Next )
00128                         {
00129                                 pUnit->lev = lev0;
00130 
00131                                 pUnitER = Unit_Regular(pUnit->pE);
00132                                 if ( pUnitER->TopRef > lev0 )
00133                                 {
00134                                         if ( pUnitER->Sign != p->nSwaps )
00135                                         {
00136                                                 if ( pUnitER->TopRef == lev2 )
00137                                                 {
00138                                                         pUnitER->TopRef = lev1;
00139                                                         nWidthReduction--;
00140                                                 }
00141                                                 else
00142                                                 {
00143                                                         assert( pUnitER->TopRef == lev1 );
00144                                                 }
00145                                                 pUnitER->Sign   = p->nSwaps;
00146                                         }
00147                                 }
00148 
00149                                 pUnitT  = pUnit->pT;
00150                                 if ( pUnitT->TopRef > lev0 )
00151                                 {
00152                                         if ( pUnitT->Sign != p->nSwaps )
00153                                         {
00154                                                 if ( pUnitT->TopRef == lev2 )
00155                                                 {
00156                                                         pUnitT->TopRef = lev1;
00157                                                         nWidthReduction--;
00158                                                 }
00159                                                 else
00160                                                 {
00161                                                         assert( pUnitT->TopRef == lev1 );
00162                                                 }
00163                                                 pUnitT->Sign   = p->nSwaps;
00164                                         }
00165                                 }
00166 
00167                         }
00168 
00169                         
00170                         for ( pUnit = pListOld0; pUnit; pUnit = pUnit->Next )
00171                         {
00172                                 pUnit->lev = lev1;
00173 
00174                                 pUnitER = Unit_Regular(pUnit->pE);
00175                                 if ( pUnitER->TopRef > lev0 )
00176                                 {
00177                                         if ( pUnitER->Sign != p->nSwaps )
00178                                         {
00179                                                 assert( pUnitER->TopRef == lev1 );
00180                                                 pUnitER->TopRef = lev2;
00181                                                 pUnitER->Sign   = p->nSwaps;
00182                                                 nWidthReduction++;
00183                                         }
00184                                 }
00185 
00186                                 pUnitT  = pUnit->pT;
00187                                 if ( pUnitT->TopRef > lev0 )
00188                                 {
00189                                         if ( pUnitT->Sign != p->nSwaps )
00190                                         {
00191                                                 assert( pUnitT->TopRef == lev1 );
00192                                                 pUnitT->TopRef = lev2;
00193                                                 pUnitT->Sign   = p->nSwaps;
00194                                                 nWidthReduction++;
00195                                         }
00196                                 }
00197                         }
00198                 }
00199                 else
00200                 {
00201 
00202 
00203                         for ( pUnit = pListOld1; pUnit; pUnit = pUnit->Next )
00204                                 pUnit->lev = lev0;
00205                 }
00206 
00207                 
00208                 pListNew0 = pListOld1;
00209                 pListNew1 = pListOld0;
00210 
00211                 if ( p->fMinApl )
00212                 {
00213                         AplWeightTotalLev0 = p->pPlanes[lev1].statsCost;
00214                         AplWeightTotalLev1 = p->pPlanes[lev0].statsCost;
00215                 }
00216                 
00217                 
00218                 nNodesUpMovedDown = p->pPlanes[lev0].statsNodes; 
00219                 nNodesDownMovedUp = p->pPlanes[lev1].statsNodes; 
00220                 goto finish;
00221         }
00222         p->Signature++;
00223 
00224 
00225         
00226         
00227         
00228 
00229         
00230         
00231         
00232         
00233         
00234         
00235 
00236         
00237         
00238         for ( pLoop = pListOld0; pLoop; )
00239         {
00240                 pUnit = pLoop;
00241                 pLoop = pLoop->Next;
00242 
00243                 pUnitE  = pUnit->pE;
00244                 pUnitER = Unit_Regular(pUnitE);
00245                 pUnitT  = pUnit->pT;
00246 
00247                 if ( pUnitER->lev != lev1 && pUnitT->lev != lev1 )
00248                 {
00249                         
00250                         
00251                         
00252                         
00253                         
00254                         
00255                         
00256                         
00257                         
00258                         
00259                         
00260 
00261                         
00262                         
00263                         pUnit->lev = lev1;
00264                         AddToLinkedList( ppListNew1, pUnit );
00265                         if ( p->fMinApl )
00266                                 AplWeightTotalLev1 += pUnit->Weight;
00267 
00268                         
00269                         for (  HKey = hashKey3(p->Signature, pUnitE, pUnitT, p->nTableSize);
00270                                p->HTable[HKey].Sign == p->Signature;
00271                                    HKey = (HKey+1) % p->nTableSize );
00272                         assert( p->HTable[HKey].Sign != p->Signature );
00273                         p->HTable[HKey].Sign = p->Signature;
00274                         p->HTable[HKey].Arg1 = pUnitE;
00275                         p->HTable[HKey].Arg2 = pUnitT;
00276                         p->HTable[HKey].Arg3 = pUnit;
00277 
00278                         nNodesUpMovedDown++;
00279 
00280                         if ( p->fMinWidth )
00281                         {
00282                                 
00283                                 if ( pUnitER->TopRef > lev0 ) 
00284                                 {
00285                                         assert( pUnitER->TopRef == lev1 );
00286                                         pUnitER->TopRefNew = lev2;
00287                                         if ( pUnitER->Sign != p->nSwaps )
00288                                         {
00289                                                 pUnitER->Sign      = p->nSwaps;  
00290                                                 p->pWidthCofs[ nWidthCofs++ ] = pUnitER;
00291                                         }
00292                                 }
00293                                 if ( pUnitT->TopRef > lev0 ) 
00294                                 {
00295                                         assert( pUnitT->TopRef == lev1 );
00296                                         pUnitT->TopRefNew = lev2;
00297                                         if ( pUnitT->Sign != p->nSwaps )
00298                                         {
00299                                                 pUnitT->Sign      = p->nSwaps;  
00300                                                 p->pWidthCofs[ nWidthCofs++ ] = pUnitT;
00301                                         }
00302                                 }
00303                         }
00304                 }
00305                 else
00306                 {
00307                         
00308                         AddToLinkedList( ppListTemp, pUnit );
00309                 }
00310         }
00311 
00312 
00313         
00314         
00315         for ( pLoop = pListTemp; pLoop; )
00316         {
00317                 pUnit = pLoop;
00318                 pLoop = pLoop->Next;
00319 
00320                 pUnitE  = pUnit->pE;
00321                 pUnitER = Unit_Regular(pUnitE);
00322                 pUnitT  = pUnit->pT;
00323                 fComp   = (int)(pUnitER != pUnitE);
00324 
00325                 
00326                 if ( p->fMinApl )
00327                         AplWeightHalf = 0.5 * pUnit->Weight;
00328 
00329                 
00330                 if ( pUnitER->lev == lev1 && pUnitT->lev == lev1 )
00331                 {
00332                         if ( fComp == 0 )
00333                         {
00334                                 
00335                                 
00336                                 
00337                                 
00338                                 
00339                                 
00340                                 
00341                                 
00342                                 
00343                                 
00344                                 
00345                                 
00346                                 
00347                                 pNew1E = pUnitE->pE;   
00348                                 pNew1T = pUnitT->pE;   
00349 
00350                                 pNew2E = pUnitE->pT;   
00351                                 pNew2T = pUnitT->pT;   
00352                         }
00353                         else
00354                         {
00355                                 
00356                                 
00357                                 
00358                                 
00359                                 
00360                                 
00361                                 
00362                                 
00363                                 
00364                                 
00365                                 
00366                                 
00367                                 
00368                                 pNew1E = Unit_Not(pUnitER->pE);  
00369                                 pNew1T =          pUnitT->pE;    
00370 
00371                                 pNew2E = Unit_Not(pUnitER->pT);  
00372                                 pNew2T =          pUnitT->pT;    
00373                         }
00374                         
00375                         pUnitER->n--;
00376                         pUnitT->n--;
00377 
00378                         
00379                         if ( p->fMinApl )
00380                         {
00381                                 pUnitER->Weight -= AplWeightHalf;
00382                                 pUnitT->Weight  -= AplWeightHalf;
00383                                 AplWeightAfter  -= pUnit->Weight;
00384                         }
00385                 }
00386                 else if ( pUnitER->lev == lev1 )
00387                 {
00388                         if ( fComp == 0 )
00389                         {
00390                                 
00391                                 
00392                                 
00393                                 
00394                                 
00395                                 
00396                                 
00397                                 
00398                                 
00399                                 
00400                                 
00401                                 
00402                                 
00403                                 pNew1E = pUnitER->pE;     
00404                                 pNew1T = pUnitT;          
00405 
00406                                 pNew2E = pUnitER->pT;     
00407                                 pNew2T = pUnitT;          
00408                         }
00409                         else
00410                         {
00411                                 
00412                                 
00413                                 
00414                                 
00415                                 
00416                                 
00417                                 
00418                                 
00419                                 
00420                                 
00421                                 
00422                                 
00423                                 
00424                                 pNew1E = Unit_Not(pUnitER->pE);  
00425                                 pNew1T =          pUnitT;        
00426 
00427                                 pNew2E = Unit_Not(pUnitER->pT);  
00428                                 pNew2T =          pUnitT;        
00429                         }
00430                         
00431                         pUnitER->n--;
00432                         
00433                         pUnitT->n--;  
00434 
00435                         
00436                         if ( p->fMinApl )
00437                         {
00438                                 pUnitER->Weight -= AplWeightHalf;
00439                                 AplWeightAfter  -= AplWeightHalf;
00440                         }
00441                 }
00442                 else if ( pUnitT->lev == lev1 )
00443                 {
00444                         
00445                         
00446                         
00447                         
00448                         
00449                         
00450                         
00451                         
00452                         
00453                         
00454                         
00455                         
00456                         
00457                         pNew1E =     pUnitE;    
00458                         pNew1T = pUnitT->pE;    
00459 
00460                         pNew2E =     pUnitE;    
00461                         pNew2T = pUnitT->pT;    
00462 
00463                         
00464                         pUnitT->n--;
00465                         
00466                         pUnitER->n--;  
00467 
00468                         
00469                         if ( p->fMinApl )
00470                         {
00471                                 pUnitT->Weight  -= AplWeightHalf;
00472                                 AplWeightAfter  -= AplWeightHalf;
00473                         }
00474                 }
00475                 else 
00476                 {
00477                         assert( 0 ); 
00478                 }
00479 
00480 
00481                 
00482                 if ( pNew1E == pNew1T )
00483                 {
00484                         pNewPlane20 = pNew1T;
00485                         
00486                         if ( p->fMinWidth )
00487                         {
00488                                 
00489                                 if ( pNew1T->TopRef > lev0 ) 
00490                                 {
00491                                         pNew1T->TopRefNew = lev1;
00492                                         if ( pNew1T->Sign  != p->nSwaps )
00493                                         {
00494                                                 pNew1T->Sign      = p->nSwaps;  
00495                                                 p->pWidthCofs[ nWidthCofs++ ] = pNew1T;
00496                                         }
00497                                 }
00498                         }
00499                 }
00500                 else
00501                 {
00502                         
00503                         fCompT = Cudd_IsComplement(pNew1T);
00504                         if ( fCompT )
00505                         {
00506                                 pNew1E = Unit_Not(pNew1E);
00507                                 pNew1T = Unit_Not(pNew1T);
00508                         }
00509 
00510                         
00511                         fFound = 0;
00512                         for (  HKey = hashKey3(p->Signature, pNew1E, pNew1T, p->nTableSize);
00513                                p->HTable[HKey].Sign == p->Signature;
00514                                    HKey = (HKey+1) % p->nTableSize )
00515                         if ( p->HTable[HKey].Arg1 == pNew1E && p->HTable[HKey].Arg2 == pNew1T )
00516                         { 
00517                                 
00518                                 pNewPlane20 = p->HTable[HKey].Arg3;
00519                                 assert( pNewPlane20->lev == lev1 );
00520                                 fFound = 1;
00521                                 p->HashSuccess++;
00522                                 break;
00523                         }
00524 
00525                         if ( !fFound )
00526                         { 
00527                                 pNewPlane20 = reoUnitsGetNextUnit( p ); 
00528                                 pNewPlane20->pE  = pNew1E;
00529                                 pNewPlane20->pT  = pNew1T;
00530                                 pNewPlane20->n   = 0;       
00531                                 pNewPlane20->lev = lev1; 
00532                                 if ( p->fMinWidth )
00533                                 {
00534                                         pNewPlane20->TopRef = lev1;
00535                                         pNewPlane20->Sign   = 0;
00536                                 }
00537                                 
00538                                 if ( p->fMinApl )
00539                                         pNewPlane20->Weight = 0.0;
00540 
00541                                 
00542                                 pNew1ER = Unit_Regular(pNew1E);
00543                                 pNew1ER->n++;  
00544                                 pNew1T->n++;   
00545 
00546                                 
00547                                 AddToLinkedList( ppListNew1, pNewPlane20 );
00548 
00549                                 
00550                                 assert( p->HTable[HKey].Sign != p->Signature );
00551                                 p->HTable[HKey].Sign = p->Signature;
00552                                 p->HTable[HKey].Arg1 = pNew1E;
00553                                 p->HTable[HKey].Arg2 = pNew1T;
00554                                 p->HTable[HKey].Arg3 = pNewPlane20;
00555 
00556                                 nNodesUnrefAdded++;
00557                                                 
00558                                 if ( p->fMinWidth )
00559                                 {
00560                                         
00561                                         if ( pNew1ER->TopRef > lev0 ) 
00562                                         {
00563                                                 if ( pNew1ER->Sign != p->nSwaps )
00564                                                 {
00565                                                         pNew1ER->TopRefNew = lev2;
00566                                                         if ( pNew1ER->Sign != p->nSwaps )
00567                                                         {
00568                                                                 pNew1ER->Sign      = p->nSwaps;  
00569                                                                 p->pWidthCofs[ nWidthCofs++ ] = pNew1ER;
00570                                                         }
00571                                                 }
00572                                                 
00573                                                 else
00574                                                 {
00575                                                         assert( pNew1ER->TopRefNew == lev1 || pNew1ER->TopRefNew == lev2 );
00576                                                 }
00577                                         }
00578                                         
00579                                         if ( pNew1T->TopRef > lev0 ) 
00580                                         {
00581                                                 if ( pNew1T->Sign != p->nSwaps )
00582                                                 {
00583                                                         pNew1T->TopRefNew = lev2;
00584                                                         if ( pNew1T->Sign  != p->nSwaps )
00585                                                         {
00586                                                                 pNew1T->Sign      = p->nSwaps;  
00587                                                                 p->pWidthCofs[ nWidthCofs++ ] = pNew1T;
00588                                                         }
00589                                                 }
00590                                                 
00591                                                 else
00592                                                 {
00593                                                         assert( pNew1T->TopRefNew == lev1 || pNew1T->TopRefNew == lev2 );
00594                                                 }
00595                                         }
00596                                 }
00597                         }
00598 
00599                         if ( p->fMinApl )
00600                         {
00601                                 
00602                                 pNewPlane20->Weight += AplWeightHalf;
00603                                 
00604                                 AplWeightAfter      += AplWeightHalf;
00605                                 
00606                                 AplWeightTotalLev1  += AplWeightHalf;
00607                         }
00608 
00609                         if ( fCompT )
00610                                 pNewPlane20 = Unit_Not(pNewPlane20);
00611                 }
00612 
00613                 if ( pNew2E == pNew2T )
00614                 {
00615                         pNewPlane21 = pNew2T;
00616                         
00617                         if ( p->fMinWidth )
00618                         {
00619                                 
00620                                 if ( pNew2T->TopRef > lev0 ) 
00621                                 {
00622                                         pNew2T->TopRefNew = lev1;
00623                                         if ( pNew2T->Sign != p->nSwaps )
00624                                         {
00625                                                 pNew2T->Sign      = p->nSwaps;  
00626                                                 p->pWidthCofs[ nWidthCofs++ ] = pNew2T;
00627                                         }
00628                                 }
00629                         }
00630                 }
00631                 else
00632                 {
00633                         assert( !Cudd_IsComplement(pNew2T) );
00634 
00635                         
00636                         fFound = 0;
00637                         for (  HKey = hashKey3(p->Signature, pNew2E, pNew2T, p->nTableSize);
00638                                    p->HTable[HKey].Sign == p->Signature;
00639                                    HKey = (HKey+1) % p->nTableSize )
00640                         if ( p->HTable[HKey].Arg1 == pNew2E && p->HTable[HKey].Arg2 == pNew2T )
00641                         { 
00642                                 
00643                                 pNewPlane21 = p->HTable[HKey].Arg3;
00644                                 assert( pNewPlane21->lev == lev1 );
00645                                 fFound = 1;
00646                                 p->HashSuccess++;
00647                                 break;
00648                         }
00649 
00650                         if ( !fFound )
00651                         { 
00652                                 pNewPlane21 = reoUnitsGetNextUnit( p ); 
00653                                 pNewPlane21->pE  = pNew2E;
00654                                 pNewPlane21->pT  = pNew2T;
00655                                 pNewPlane21->n   = 0;       
00656                                 pNewPlane21->lev = lev1; 
00657                                 if ( p->fMinWidth )
00658                                 {
00659                                         pNewPlane21->TopRef = lev1;
00660                                         pNewPlane21->Sign   = 0;
00661                                 }
00662                                 
00663                                 if ( p->fMinApl )
00664                                         pNewPlane21->Weight = 0.0;
00665 
00666                                 
00667                                 pNew2ER = Unit_Regular(pNew2E);
00668                                 pNew2ER->n++; 
00669                                 pNew2T->n++;  
00670 
00671                                 
00672 
00673                                 AddToLinkedList( ppListNew1, pNewPlane21 );
00674 
00675                                 
00676                                 assert( p->HTable[HKey].Sign != p->Signature );
00677                                 p->HTable[HKey].Sign = p->Signature;
00678                                 p->HTable[HKey].Arg1 = pNew2E;
00679                                 p->HTable[HKey].Arg2 = pNew2T;
00680                                 p->HTable[HKey].Arg3 = pNewPlane21;
00681 
00682                                 nNodesUnrefAdded++;
00683 
00684                                                 
00685                                 if ( p->fMinWidth )
00686                                 {
00687                                         
00688                                         if ( pNew2ER->TopRef > lev0 ) 
00689                                         {
00690                                                 if ( pNew2ER->Sign != p->nSwaps )
00691                                                 {
00692                                                         pNew2ER->TopRefNew = lev2;
00693                                                         if ( pNew2ER->Sign != p->nSwaps )
00694                                                         {
00695                                                                 pNew2ER->Sign      = p->nSwaps;  
00696                                                                 p->pWidthCofs[ nWidthCofs++ ] = pNew2ER;
00697                                                         }
00698                                                 }
00699                                                 
00700                                                 else
00701                                                 {
00702                                                         assert( pNew2ER->TopRefNew == lev1 || pNew2ER->TopRefNew == lev2 );
00703                                                 }
00704                                         }
00705                                         
00706                                         if ( pNew2T->TopRef > lev0 ) 
00707                                         {
00708                                                 if ( pNew2T->Sign != p->nSwaps )
00709                                                 {
00710                                                         pNew2T->TopRefNew = lev2;
00711                                                         if ( pNew2T->Sign != p->nSwaps )
00712                                                         {
00713                                                                 pNew2T->Sign      = p->nSwaps;  
00714                                                                 p->pWidthCofs[ nWidthCofs++ ] = pNew2T;
00715                                                         }
00716                                                 }
00717                                                 
00718                                                 else
00719                                                 {
00720                                                         assert( pNew2T->TopRefNew == lev1 || pNew2T->TopRefNew == lev2 );
00721                                                 }
00722                                         }
00723                                 }
00724                         }
00725 
00726                         if ( p->fMinApl )
00727                         {
00728                                 
00729                                 pNewPlane21->Weight += AplWeightHalf;
00730                                 
00731                                 AplWeightAfter      += AplWeightHalf;
00732                                 
00733                                 AplWeightTotalLev1  += AplWeightHalf;
00734                         }
00735                 }
00736                 
00737                 
00738                 
00739 
00740                 assert( !Cudd_IsComplement(pNewPlane21) );
00741                 
00742 
00743                 pUnit->pE  = pNewPlane20;
00744                 pUnit->pT  = pNewPlane21;
00745                 assert( pUnit->lev == lev0 ); 
00746                 
00747 
00748                 
00749                 pNewPlane20R = Unit_Regular(pNewPlane20);
00750                 pNewPlane20R->n++; 
00751                 pNewPlane21->n++;  
00752 
00753                 
00754                 AddToLinkedList( ppListNew0, pUnit );
00755                 if ( p->fMinApl )
00756                         AplWeightTotalLev0 += pUnit->Weight;
00757         }
00758 
00759         
00760         
00761         for ( pLoop = pListOld1; pLoop; )
00762         {
00763                 pUnit = pLoop;
00764                 pLoop = pLoop->Next;
00765                 if ( pUnit->n )
00766                 { 
00767                         assert( !p->fMinApl || pUnit->Weight > 0.0 );
00768                         
00769                         
00770                         pUnit->lev = lev0;
00771                         AddToLinkedList( ppListNew0, pUnit );
00772                         if ( p->fMinApl )
00773                                 AplWeightTotalLev0 += pUnit->Weight;
00774 
00775                         nNodesDownMovedUp++;
00776 
00777                         if ( p->fMinWidth )
00778                         {
00779                                 pUnitER = Unit_Regular(pUnit->pE);
00780                                 pUnitT  = pUnit->pT;
00781 
00782                                 
00783                                 if ( pUnitER->TopRef > lev0 ) 
00784                                 {
00785                                         pUnitER->TopRefNew = lev1;
00786                                         if ( pUnitER->Sign != p->nSwaps )
00787                                         {
00788                                                 pUnitER->Sign      = p->nSwaps;  
00789                                                 p->pWidthCofs[ nWidthCofs++ ] = pUnitER;
00790                                         }
00791                                 }
00792                                 if ( pUnitT->TopRef > lev0 ) 
00793                                 {
00794                                         pUnitT->TopRefNew = lev1;
00795                                         if ( pUnitT->Sign != p->nSwaps )
00796                                         {
00797                                                 pUnitT->Sign      = p->nSwaps;  
00798                                                 p->pWidthCofs[ nWidthCofs++ ] = pUnitT;
00799                                         }
00800                                 }
00801                         }
00802                 }
00803                 else
00804                 {
00805                         assert( !p->fMinApl || pUnit->Weight == 0.0 );
00806                         
00807                         pUnitER = Unit_Regular(pUnit->pE);
00808                         pUnitT  = pUnit->pT;
00809                         pUnitER->n--;  
00810                         pUnitT->n--;   
00811                         
00812                         reoUnitsRecycleUnit( p, pUnit );
00813                         nNodesUnrefRemoved++;
00814                 }
00815         }
00816 
00817 finish:
00818 
00819         
00820         p->pPlanes[lev0].pHead = pListNew0;
00821         p->pPlanes[lev1].pHead = pListNew1;
00822 
00823         
00824         temp                     = p->pPlanes[lev0].fSifted;
00825         p->pPlanes[lev0].fSifted = p->pPlanes[lev1].fSifted;
00826         p->pPlanes[lev1].fSifted = temp;
00827 
00828         
00829         if ( p->pOrderInt )
00830         {
00831                 temp               = p->pOrderInt[lev0];
00832                 p->pOrderInt[lev0] = p->pOrderInt[lev1];
00833                 p->pOrderInt[lev1] = temp;
00834         }
00835 
00836         
00837         p->pPlanes[lev0].statsNodes  -= (nNodesUpMovedDown - nNodesDownMovedUp);
00838         p->pPlanes[lev1].statsNodes  -= (nNodesDownMovedUp - nNodesUpMovedDown) + nNodesUnrefRemoved - nNodesUnrefAdded;
00839         p->nNodesCur                 -=  nNodesUnrefRemoved - nNodesUnrefAdded;
00840 
00841         
00842         if ( p->fMinWidth )
00843         {
00844                 for ( c = 0; c < nWidthCofs; c++ )
00845                 {
00846                         if ( p->pWidthCofs[c]->TopRefNew < p->pWidthCofs[c]->TopRef )
00847                         {
00848                                 p->pWidthCofs[c]->TopRef = p->pWidthCofs[c]->TopRefNew;
00849                                 nWidthReduction--;
00850                         }
00851                         else if ( p->pWidthCofs[c]->TopRefNew > p->pWidthCofs[c]->TopRef )
00852                         {
00853                                 p->pWidthCofs[c]->TopRef = p->pWidthCofs[c]->TopRefNew;
00854                                 nWidthReduction++;
00855                         }
00856                 }
00857                 
00858                 reoProfileWidthVerifyLevel( p->pPlanes + lev0, lev0 );
00859                 reoProfileWidthVerifyLevel( p->pPlanes + lev1, lev1 );
00860 
00861                 
00862                 nCostGain = (nNodesDownMovedUp - nNodesUpMovedDown + nNodesUnrefRemoved - nNodesUnrefAdded) + nWidthReduction;
00863                 
00864                 p->pPlanes[lev1].statsWidth -= (int)nCostGain; 
00865                 
00866                 p->pPlanes[lev1].statsCost   = p->pPlanes[lev1].statsWidth;
00867         }
00868         else if ( p->fMinApl )
00869         {
00870                 
00871                 nCostGain = AplWeightPrev - AplWeightAfter;
00872                 
00873 
00874 
00875                 
00876                 p->pPlanes[lev0].statsApl  = AplWeightTotalLev0;
00877                 p->pPlanes[lev1].statsApl  = AplWeightTotalLev1;
00878                 
00879                 p->pPlanes[lev0].statsCost = p->pPlanes[lev0].statsApl;
00880                 p->pPlanes[lev1].statsCost = p->pPlanes[lev1].statsApl;
00881         }
00882         else
00883         {
00884                 
00885                 nCostGain = nNodesUnrefRemoved - nNodesUnrefAdded;
00886                 
00887                 
00888                 p->pPlanes[lev0].statsCost   = p->pPlanes[lev0].statsNodes;
00889                 p->pPlanes[lev1].statsCost   = p->pPlanes[lev1].statsNodes;
00890         }
00891 
00892         return nCostGain;
00893 }
00894 
00898