00001
00019 #include "fxuInt.h"
00020
00024
00025 static void Fxu_UpdateDoublePairs( Fxu_Matrix * p, Fxu_Double * pDouble, Fxu_Var * pVar );
00026 static void Fxu_UpdateMatrixDoubleCreateCubes( Fxu_Matrix * p, Fxu_Cube * pCube1, Fxu_Cube * pCube2, Fxu_Double * pDiv );
00027 static void Fxu_UpdateMatrixDoubleClean( Fxu_Matrix * p, Fxu_Cube * pCubeUse, Fxu_Cube * pCubeRem );
00028 static void Fxu_UpdateMatrixSingleClean( Fxu_Matrix * p, Fxu_Var * pVar1, Fxu_Var * pVar2, Fxu_Var * pVarNew );
00029
00030 static void Fxu_UpdateCreateNewVars( Fxu_Matrix * p, Fxu_Var ** ppVarC, Fxu_Var ** ppVarD, int nCubes );
00031 static int Fxu_UpdatePairCompare( Fxu_Pair ** ppP1, Fxu_Pair ** ppP2 );
00032 static void Fxu_UpdatePairsSort( Fxu_Matrix * p, Fxu_Double * pDouble );
00033
00034 static void Fxu_UpdateCleanOldDoubles( Fxu_Matrix * p, Fxu_Double * pDiv, Fxu_Cube * pCube );
00035 static void Fxu_UpdateAddNewDoubles( Fxu_Matrix * p, Fxu_Cube * pCube );
00036 static void Fxu_UpdateCleanOldSingles( Fxu_Matrix * p );
00037 static void Fxu_UpdateAddNewSingles( Fxu_Matrix * p, Fxu_Var * pVar );
00038
00042
00054 void Fxu_Update( Fxu_Matrix * p, Fxu_Single * pSingle, Fxu_Double * pDouble )
00055 {
00056 Fxu_Cube * pCube, * pCubeNew;
00057 Fxu_Var * pVarC, * pVarD;
00058 Fxu_Var * pVar1, * pVar2;
00059
00060
00061 if ( pSingle == NULL )
00062 {
00063 assert( pDouble->Weight == Fxu_HeapDoubleReadMaxWeight( p->pHeapDouble ) );
00064 Fxu_UpdateDouble( p );
00065 return;
00066 }
00067 if ( pDouble == NULL )
00068 {
00069 assert( pSingle->Weight == Fxu_HeapSingleReadMaxWeight( p->pHeapSingle ) );
00070 Fxu_UpdateSingle( p );
00071 return;
00072 }
00073
00074
00075 pVar1 = pSingle->pVar1;
00076 pVar2 = pSingle->pVar2;
00077
00078
00079 Fxu_HeapDoubleDelete( p->pHeapDouble, pDouble );
00080
00081 Fxu_ListTableDelDivisor( p, pDouble );
00082
00083
00084 Fxu_UpdateCreateNewVars( p, &pVarC, &pVarD, 1 );
00085
00086 pCubeNew = Fxu_MatrixAddCube( p, pVarD, 0 );
00087 pCubeNew->pFirst = pCubeNew;
00088
00089 pVarD->pFirst = pCubeNew;
00090
00091
00092 Fxu_MatrixRingCubesStart( p );
00093 Fxu_MatrixRingVarsStart( p );
00094
00095 Fxu_MatrixRingVarsAdd( p, pVar1 );
00096 Fxu_MatrixRingVarsAdd( p, pVar2 );
00097
00098
00099
00100 Fxu_UpdateMatrixSingleClean( p, pVar1, pVar2, pVarD );
00101
00102
00103 Fxu_UpdateDoublePairs( p, pDouble, pVarC );
00104
00105 Fxu_MatrixRingCubesStop( p );
00106 Fxu_MatrixRingVarsStop( p );
00107
00108
00109 assert( pVar1->iVar < pVar2->iVar );
00110 assert( Fxu_SingleCountCoincidence( p, pVar1, pVar2 ) == 0 );
00111 Fxu_MatrixAddLiteral( p, pCubeNew, pVar1 );
00112 Fxu_MatrixAddLiteral( p, pCubeNew, pVar2 );
00113
00114
00115
00116 Fxu_MatrixForEachCubeInRing( p, pCube )
00117 Fxu_UpdateAddNewDoubles( p, pCube );
00118
00119 Fxu_UpdateCleanOldSingles( p );
00120
00121
00122 Fxu_MatrixRingCubesUnmark( p );
00123 Fxu_MatrixRingVarsUnmark( p );
00124
00125
00126
00127 Fxu_UpdateAddNewSingles( p, pVarC );
00128 Fxu_UpdateAddNewSingles( p, pVarD );
00129
00130
00131 MEM_FREE_FXU( p, Fxu_Double, 1, pDouble );
00132 p->nDivs3++;
00133 }
00134
00146 void Fxu_UpdateSingle( Fxu_Matrix * p )
00147 {
00148 Fxu_Single * pSingle;
00149 Fxu_Cube * pCube, * pCubeNew;
00150 Fxu_Var * pVarC, * pVarD;
00151 Fxu_Var * pVar1, * pVar2;
00152
00153
00154 pSingle = Fxu_HeapSingleReadMax( p->pHeapSingle );
00155
00156 pVar1 = pSingle->pVar1;
00157 pVar2 = pSingle->pVar2;
00158
00159
00160 Fxu_UpdateCreateNewVars( p, &pVarC, &pVarD, 1 );
00161
00162 pCubeNew = Fxu_MatrixAddCube( p, pVarD, 0 );
00163 pCubeNew->pFirst = pCubeNew;
00164
00165 pVarD->pFirst = pCubeNew;
00166
00167
00168 Fxu_MatrixRingCubesStart( p );
00169 Fxu_MatrixRingVarsStart( p );
00170
00171 Fxu_MatrixRingVarsAdd( p, pVar1 );
00172 Fxu_MatrixRingVarsAdd( p, pVar2 );
00173
00174
00175
00176 Fxu_UpdateMatrixSingleClean( p, pVar1, pVar2, pVarD );
00177
00178 Fxu_MatrixRingCubesStop( p );
00179 Fxu_MatrixRingVarsStop( p );
00180
00181
00182 assert( pVar1->iVar < pVar2->iVar );
00183 assert( Fxu_SingleCountCoincidence( p, pVar1, pVar2 ) == 0 );
00184 Fxu_MatrixAddLiteral( p, pCubeNew, pVar1 );
00185 Fxu_MatrixAddLiteral( p, pCubeNew, pVar2 );
00186
00187
00188
00189 Fxu_MatrixForEachCubeInRing( p, pCube )
00190 Fxu_UpdateAddNewDoubles( p, pCube );
00191
00192 Fxu_UpdateCleanOldSingles( p );
00193
00194
00195
00196 Fxu_MatrixRingCubesUnmark( p );
00197 Fxu_MatrixRingVarsUnmark( p );
00198
00199
00200 Fxu_UpdateAddNewSingles( p, pVarC );
00201 Fxu_UpdateAddNewSingles( p, pVarD );
00202 p->nDivs1++;
00203 }
00204
00216 void Fxu_UpdateDouble( Fxu_Matrix * p )
00217 {
00218 Fxu_Double * pDiv;
00219 Fxu_Cube * pCube, * pCubeNew1, * pCubeNew2;
00220 Fxu_Var * pVarC, * pVarD;
00221
00222
00223 pDiv = Fxu_HeapDoubleGetMax( p->pHeapDouble );
00224
00225 Fxu_ListTableDelDivisor( p, pDiv );
00226
00227
00228 Fxu_UpdateCreateNewVars( p, &pVarC, &pVarD, 2 );
00229
00230 pCubeNew1 = Fxu_MatrixAddCube( p, pVarD, 0 );
00231 pCubeNew1->pFirst = pCubeNew1;
00232 pCubeNew2 = Fxu_MatrixAddCube( p, pVarD, 1 );
00233 pCubeNew2->pFirst = pCubeNew1;
00234
00235 pVarD->pFirst = pCubeNew1;
00236
00237
00238 Fxu_UpdateMatrixDoubleCreateCubes( p, pCubeNew1, pCubeNew2, pDiv );
00239
00240
00241 Fxu_MatrixRingCubesStart( p );
00242 Fxu_MatrixRingVarsStart( p );
00243
00244
00245 Fxu_UpdateDoublePairs( p, pDiv, pVarD );
00246
00247 Fxu_MatrixRingCubesStop( p );
00248 Fxu_MatrixRingVarsStop( p );
00249
00250
00251
00252 Fxu_MatrixForEachCubeInRing( p, pCube )
00253 Fxu_UpdateAddNewDoubles( p, pCube );
00254
00255 Fxu_UpdateCleanOldSingles( p );
00256
00257
00258 Fxu_MatrixRingCubesUnmark( p );
00259 Fxu_MatrixRingVarsUnmark( p );
00260
00261
00262
00263 Fxu_UpdateAddNewSingles( p, pVarC );
00264 Fxu_UpdateAddNewSingles( p, pVarD );
00265
00266
00267 MEM_FREE_FXU( p, Fxu_Double, 1, pDiv );
00268 p->nDivs2++;
00269 }
00270
00282 void Fxu_UpdateDoublePairs( Fxu_Matrix * p, Fxu_Double * pDouble, Fxu_Var * pVar )
00283 {
00284 Fxu_Pair * pPair;
00285 Fxu_Cube * pCubeUse, * pCubeRem;
00286 int i;
00287
00288
00289 Fxu_UpdatePairsSort( p, pDouble );
00290
00291 for ( i = 0; i < p->vPairs->nSize; i++ )
00292 {
00293
00294
00295 pPair = p->vPairs->pArray[i];
00296
00297 pCubeUse = Fxu_PairMinCube( pPair );
00298 pCubeRem = Fxu_PairMaxCube( pPair );
00299
00300 assert( pCubeUse->pOrder == NULL );
00301 Fxu_MatrixRingCubesAdd( p, pCubeUse );
00302
00303
00304 Fxu_UpdateMatrixDoubleClean( p, pCubeUse, pCubeRem );
00305
00306 Fxu_MatrixAddLiteral( p, pCubeUse, pVar );
00307
00308 assert( pCubeUse->lLits.nItems == pPair->nBase + 1 );
00309 assert( pCubeRem->lLits.nItems == 0 );
00310
00311
00312 Fxu_UpdateCleanOldDoubles( p, pDouble, pCubeUse );
00313 Fxu_UpdateCleanOldDoubles( p, pDouble, pCubeRem );
00314
00315 MEM_FREE_FXU( p, Fxu_Pair, 1, pPair );
00316 }
00317 p->vPairs->nSize = 0;
00318 }
00319
00331 void Fxu_UpdateMatrixDoubleCreateCubes( Fxu_Matrix * p, Fxu_Cube * pCube1, Fxu_Cube * pCube2, Fxu_Double * pDiv )
00332 {
00333 Fxu_Lit * pLit1, * pLit2;
00334 Fxu_Pair * pPair;
00335 int nBase, nLits1, nLits2;
00336
00337
00338 nBase = nLits1 = nLits2 = 0;
00339 pPair = pDiv->lPairs.pHead;
00340 pLit1 = pPair->pCube1->lLits.pHead;
00341 pLit2 = pPair->pCube2->lLits.pHead;
00342 while ( 1 )
00343 {
00344 if ( pLit1 && pLit2 )
00345 {
00346 if ( pLit1->iVar == pLit2->iVar )
00347 {
00348 pLit1 = pLit1->pHNext;
00349 pLit2 = pLit2->pHNext;
00350 nBase++;
00351 }
00352 else if ( pLit1->iVar < pLit2->iVar )
00353 {
00354 Fxu_MatrixAddLiteral( p, pCube1, pLit1->pVar );
00355
00356 pLit1 = pLit1->pHNext;
00357 nLits1++;
00358 }
00359 else
00360 {
00361 Fxu_MatrixAddLiteral( p, pCube2, pLit2->pVar );
00362
00363 pLit2 = pLit2->pHNext;
00364 nLits2++;
00365 }
00366 }
00367 else if ( pLit1 && !pLit2 )
00368 {
00369 Fxu_MatrixAddLiteral( p, pCube1, pLit1->pVar );
00370
00371 pLit1 = pLit1->pHNext;
00372 nLits1++;
00373 }
00374 else if ( !pLit1 && pLit2 )
00375 {
00376 Fxu_MatrixAddLiteral( p, pCube2, pLit2->pVar );
00377
00378 pLit2 = pLit2->pHNext;
00379 nLits2++;
00380 }
00381 else
00382 break;
00383 }
00384 assert( pPair->nLits1 == nLits1 );
00385 assert( pPair->nLits2 == nLits2 );
00386 assert( pPair->nBase == nBase );
00387 }
00388
00389
00401 void Fxu_UpdateMatrixDoubleClean( Fxu_Matrix * p, Fxu_Cube * pCubeUse, Fxu_Cube * pCubeRem )
00402 {
00403 Fxu_Lit * pLit1, * bLit1Next;
00404 Fxu_Lit * pLit2, * bLit2Next;
00405
00406
00407 pLit1 = pCubeUse->lLits.pHead;
00408 pLit2 = pCubeRem->lLits.pHead;
00409 bLit1Next = pLit1? pLit1->pHNext: NULL;
00410 bLit2Next = pLit2? pLit2->pHNext: NULL;
00411
00412
00413 while ( 1 )
00414 {
00415 if ( pLit1 && pLit2 )
00416 {
00417 if ( pLit1->iVar == pLit2->iVar )
00418 {
00419
00420 if ( pLit1->pVar->pOrder == NULL )
00421 Fxu_MatrixRingVarsAdd( p, pLit1->pVar );
00422
00423 Fxu_MatrixDelLiteral( p, pLit2 );
00424
00425 pLit1 = bLit1Next;
00426 pLit2 = bLit2Next;
00427 bLit1Next = pLit1? pLit1->pHNext: NULL;
00428 bLit2Next = pLit2? pLit2->pHNext: NULL;
00429 }
00430 else if ( pLit1->iVar < pLit2->iVar )
00431 {
00432
00433 if ( pLit1->pVar->pOrder == NULL )
00434 Fxu_MatrixRingVarsAdd( p, pLit1->pVar );
00435
00436 Fxu_MatrixDelLiteral( p, pLit1 );
00437
00438 pLit1 = bLit1Next;
00439 bLit1Next = pLit1? pLit1->pHNext: NULL;
00440 }
00441 else
00442 {
00443
00444 if ( pLit2->pVar->pOrder == NULL )
00445 Fxu_MatrixRingVarsAdd( p, pLit2->pVar );
00446
00447 Fxu_MatrixDelLiteral( p, pLit2 );
00448
00449 pLit2 = bLit2Next;
00450 bLit2Next = pLit2? pLit2->pHNext: NULL;
00451 }
00452 }
00453 else if ( pLit1 && !pLit2 )
00454 {
00455
00456 if ( pLit1->pVar->pOrder == NULL )
00457 Fxu_MatrixRingVarsAdd( p, pLit1->pVar );
00458
00459 Fxu_MatrixDelLiteral( p, pLit1 );
00460
00461 pLit1 = bLit1Next;
00462 bLit1Next = pLit1? pLit1->pHNext: NULL;
00463 }
00464 else if ( !pLit1 && pLit2 )
00465 {
00466
00467 if ( pLit2->pVar->pOrder == NULL )
00468 Fxu_MatrixRingVarsAdd( p, pLit2->pVar );
00469
00470 Fxu_MatrixDelLiteral( p, pLit2 );
00471
00472 pLit2 = bLit2Next;
00473 bLit2Next = pLit2? pLit2->pHNext: NULL;
00474 }
00475 else
00476 break;
00477 }
00478 }
00479
00491 void Fxu_UpdateMatrixSingleClean( Fxu_Matrix * p, Fxu_Var * pVar1, Fxu_Var * pVar2, Fxu_Var * pVarNew )
00492 {
00493 Fxu_Lit * pLit1, * bLit1Next;
00494 Fxu_Lit * pLit2, * bLit2Next;
00495
00496
00497 pLit1 = pVar1->lLits.pHead;
00498 pLit2 = pVar2->lLits.pHead;
00499 bLit1Next = pLit1? pLit1->pVNext: NULL;
00500 bLit2Next = pLit2? pLit2->pVNext: NULL;
00501 while ( 1 )
00502 {
00503 if ( pLit1 && pLit2 )
00504 {
00505 if ( pLit1->pCube->pVar->iVar == pLit2->pCube->pVar->iVar )
00506 {
00507 if ( pLit1->iCube == pLit2->iCube )
00508 {
00509
00510
00511 assert( pLit1->pCube->pOrder == NULL );
00512 Fxu_MatrixRingCubesAdd( p, pLit1->pCube );
00513
00514
00515 Fxu_MatrixAddLiteral( p, pLit1->pCube, pVarNew );
00516
00517 Fxu_UpdateCleanOldDoubles( p, NULL, pLit1->pCube );
00518
00519
00520 Fxu_MatrixDelLiteral( p, pLit1 );
00521 Fxu_MatrixDelLiteral( p, pLit2 );
00522
00523
00524 pLit1 = bLit1Next;
00525 pLit2 = bLit2Next;
00526 bLit1Next = pLit1? pLit1->pVNext: NULL;
00527 bLit2Next = pLit2? pLit2->pVNext: NULL;
00528 }
00529 else if ( pLit1->iCube < pLit2->iCube )
00530 {
00531 pLit1 = bLit1Next;
00532 bLit1Next = pLit1? pLit1->pVNext: NULL;
00533 }
00534 else
00535 {
00536 pLit2 = bLit2Next;
00537 bLit2Next = pLit2? pLit2->pVNext: NULL;
00538 }
00539 }
00540 else if ( pLit1->pCube->pVar->iVar < pLit2->pCube->pVar->iVar )
00541 {
00542 pLit1 = bLit1Next;
00543 bLit1Next = pLit1? pLit1->pVNext: NULL;
00544 }
00545 else
00546 {
00547 pLit2 = bLit2Next;
00548 bLit2Next = pLit2? pLit2->pVNext: NULL;
00549 }
00550 }
00551 else if ( pLit1 && !pLit2 )
00552 {
00553 pLit1 = bLit1Next;
00554 bLit1Next = pLit1? pLit1->pVNext: NULL;
00555 }
00556 else if ( !pLit1 && pLit2 )
00557 {
00558 pLit2 = bLit2Next;
00559 bLit2Next = pLit2? pLit2->pVNext: NULL;
00560 }
00561 else
00562 break;
00563 }
00564 }
00565
00577 void Fxu_UpdatePairsSort( Fxu_Matrix * p, Fxu_Double * pDouble )
00578 {
00579 Fxu_Pair * pPair;
00580
00581
00582 p->vPairs->nSize = 0;
00583 Fxu_DoubleForEachPair( pDouble, pPair )
00584 Vec_PtrPush( p->vPairs, pPair );
00585 if ( p->vPairs->nSize < 2 )
00586 return;
00587
00588 qsort( (void *)p->vPairs->pArray, p->vPairs->nSize, sizeof(Fxu_Pair *),
00589 (int (*)(const void *, const void *)) Fxu_UpdatePairCompare );
00590 assert( Fxu_UpdatePairCompare( (Fxu_Pair**)p->vPairs->pArray, (Fxu_Pair**)p->vPairs->pArray + p->vPairs->nSize - 1 ) < 0 );
00591 }
00592
00604 int Fxu_UpdatePairCompare( Fxu_Pair ** ppP1, Fxu_Pair ** ppP2 )
00605 {
00606 Fxu_Cube * pC1 = (*ppP1)->pCube1;
00607 Fxu_Cube * pC2 = (*ppP2)->pCube1;
00608 int iP1CubeMin, iP2CubeMin;
00609 if ( pC1->pVar->iVar < pC2->pVar->iVar )
00610 return -1;
00611 if ( pC1->pVar->iVar > pC2->pVar->iVar )
00612 return 1;
00613 iP1CubeMin = Fxu_PairMinCubeInt( *ppP1 );
00614 iP2CubeMin = Fxu_PairMinCubeInt( *ppP2 );
00615 if ( iP1CubeMin < iP2CubeMin )
00616 return -1;
00617 if ( iP1CubeMin > iP2CubeMin )
00618 return 1;
00619 assert( 0 );
00620 return 0;
00621 }
00622
00623
00635 void Fxu_UpdateCreateNewVars( Fxu_Matrix * p, Fxu_Var ** ppVarC, Fxu_Var ** ppVarD, int nCubes )
00636 {
00637 Fxu_Var * pVarC, * pVarD;
00638
00639
00640 pVarC = Fxu_MatrixAddVar( p );
00641 pVarC->nCubes = 0;
00642
00643 pVarD = Fxu_MatrixAddVar( p );
00644 pVarD->nCubes = nCubes;
00645
00646
00647
00648
00649
00650
00651 *ppVarC = pVarC;
00652 *ppVarD = pVarD;
00653 }
00654
00655
00667 void Fxu_UpdateCleanOldDoubles( Fxu_Matrix * p, Fxu_Double * pDiv, Fxu_Cube * pCube )
00668 {
00669 Fxu_Double * pDivCur;
00670 Fxu_Pair * pPair;
00671 int i;
00672
00673
00674
00675
00676 if ( pCube->pVar->ppPairs == NULL )
00677 return;
00678
00679
00680 Fxu_CubeForEachPair( pCube, pPair, i )
00681 {
00682
00683 pDivCur = pPair->pDiv;
00684
00685 if ( pDivCur == pDiv )
00686 continue;
00687
00688 Fxu_ListDoubleDelPair( pDivCur, pPair );
00689
00690 if ( pDivCur->lPairs.nItems == 0 )
00691 {
00692 assert( pDivCur->Weight == pPair->nBase - 1 );
00693 Fxu_HeapDoubleDelete( p->pHeapDouble, pDivCur );
00694 Fxu_MatrixDelDivisor( p, pDivCur );
00695 }
00696 else
00697 {
00698
00699 pDivCur->Weight -= pPair->nLits1 + pPair->nLits2 - 1 + pPair->nBase;
00700 Fxu_HeapDoubleUpdate( p->pHeapDouble, pDivCur );
00701 }
00702 MEM_FREE_FXU( p, Fxu_Pair, 1, pPair );
00703 }
00704
00705 Fxu_PairClearStorage( pCube );
00706 }
00707
00721 void Fxu_UpdateAddNewDoubles( Fxu_Matrix * p, Fxu_Cube * pCube )
00722 {
00723 Fxu_Cube * pTemp;
00724 assert( pCube->pOrder );
00725
00726
00727
00728
00729 if ( pCube->pVar->ppPairs == NULL )
00730 return;
00731
00732 for ( pTemp = pCube->pFirst; pTemp->pVar == pCube->pVar; pTemp = pTemp->pNext )
00733 {
00734
00735 if ( pTemp->lLits.nItems == 0 )
00736 continue;
00737
00738
00739 if ( pTemp->pOrder && pTemp >= pCube )
00740 continue;
00741 Fxu_MatrixAddDivisor( p, pTemp, pCube );
00742 }
00743 }
00744
00756 void Fxu_UpdateCleanOldSingles( Fxu_Matrix * p )
00757 {
00758 Fxu_Single * pSingle, * pSingle2;
00759 int WeightNew;
00760 int Counter = 0;
00761
00762 Fxu_MatrixForEachSingleSafe( p, pSingle, pSingle2 )
00763 {
00764
00765 if ( pSingle->pVar1->pOrder || pSingle->pVar2->pOrder )
00766 {
00767 Counter++;
00768
00769 WeightNew = -2 + Fxu_SingleCountCoincidence( p, pSingle->pVar1, pSingle->pVar2 );
00770 if ( WeightNew >= 0 )
00771 {
00772 pSingle->Weight = WeightNew;
00773 Fxu_HeapSingleUpdate( p->pHeapSingle, pSingle );
00774 }
00775 else
00776 {
00777 Fxu_HeapSingleDelete( p->pHeapSingle, pSingle );
00778 Fxu_ListMatrixDelSingle( p, pSingle );
00779 MEM_FREE_FXU( p, Fxu_Single, 1, pSingle );
00780 }
00781 }
00782 }
00783
00784 }
00785
00797 void Fxu_UpdateAddNewSingles( Fxu_Matrix * p, Fxu_Var * pVar )
00798 {
00799 Fxu_MatrixComputeSinglesOne( p, pVar );
00800 }
00801
00805
00806