/**Function************************************************************* Synopsis [Updates the matrix after selecting two divisors.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void Fxu_Update( Fxu_Matrix * p, Fxu_Single * pSingle, Fxu_Double * pDouble ) { Fxu_Cube * pCube, * pCubeNew; Fxu_Var * pVarC, * pVarD; Fxu_Var * pVar1, * pVar2; // consider trivial cases if ( pSingle == NULL ) { assert( pDouble->Weight == Fxu_HeapDoubleReadMaxWeight( p->pHeapDouble ) ); Fxu_UpdateDouble( p ); return; } if ( pDouble == NULL ) { assert( pSingle->Weight == Fxu_HeapSingleReadMaxWeight( p->pHeapSingle ) ); Fxu_UpdateSingle( p ); return; } // get the variables of the single pVar1 = pSingle->pVar1; pVar2 = pSingle->pVar2; // remove the best double from the heap Fxu_HeapDoubleDelete( p->pHeapDouble, pDouble ); // remove the best divisor from the table Fxu_ListTableDelDivisor( p, pDouble ); // create two new columns (vars) Fxu_UpdateCreateNewVars( p, &pVarC, &pVarD, 1 ); // create one new row (cube) pCubeNew = Fxu_MatrixAddCube( p, pVarD, 0 ); pCubeNew->pFirst = pCubeNew; // set the first cube of the positive var pVarD->pFirst = pCubeNew; // start collecting the affected vars and cubes Fxu_MatrixRingCubesStart( p ); Fxu_MatrixRingVarsStart( p ); // add the vars Fxu_MatrixRingVarsAdd( p, pVar1 ); Fxu_MatrixRingVarsAdd( p, pVar2 ); // remove the literals and collect the affected cubes // remove the divisors associated with this cube // add to the affected cube the literal corresponding to the new column Fxu_UpdateMatrixSingleClean( p, pVar1, pVar2, pVarD ); // replace each two cubes of the pair by one new cube // the new cube contains the base and the new literal Fxu_UpdateDoublePairs( p, pDouble, pVarC ); // stop collecting the affected vars and cubes Fxu_MatrixRingCubesStop( p ); Fxu_MatrixRingVarsStop( p ); // add the literals to the new cube assert( pVar1->iVar < pVar2->iVar ); assert( Fxu_SingleCountCoincidence( p, pVar1, pVar2 ) == 0 ); Fxu_MatrixAddLiteral( p, pCubeNew, pVar1 ); Fxu_MatrixAddLiteral( p, pCubeNew, pVar2 ); // create new doubles; we cannot add them in the same loop // because we first have to create *all* new cubes for each node Fxu_MatrixForEachCubeInRing( p, pCube ) Fxu_UpdateAddNewDoubles( p, pCube ); // update the singles after removing some literals Fxu_UpdateCleanOldSingles( p ); // undo the temporary rings with cubes and vars Fxu_MatrixRingCubesUnmark( p ); Fxu_MatrixRingVarsUnmark( p ); // we should undo the rings before creating new singles // create new singles Fxu_UpdateAddNewSingles( p, pVarC ); Fxu_UpdateAddNewSingles( p, pVarD ); // recycle the divisor MEM_FREE_FXU( p, Fxu_Double, 1, pDouble ); p->nDivs3++; }
/**Function************************************************************* Synopsis [Performs fast_extract on a set of covers.] Description [All the covers are given in the array p->vSops. The resulting covers are returned in the array p->vSopsNew. The entries in these arrays correspond to objects in the network. The entries corresponding to the PI and objects with trivial covers are NULL. The number of extracted covers (not exceeding p->nNodesExt) is returned. Two other things are important for the correct operation of this procedure: (1) The input covers do not have duplicated fanins and are SCC-ABC_FREE. (2) The fanins array contains the numbers of the fanin objects.] SideEffects [] SeeAlso [] ***********************************************************************/ int Fxu_FastExtract( Fxu_Data_t * pData ) { Fxu_Matrix * p; Fxu_Single * pSingle; Fxu_Double * pDouble; int Weight1, Weight2, Weight3; int Counter = 0; s_MemoryTotal = 0; s_MemoryPeak = 0; // create the matrix p = Fxu_CreateMatrix( pData ); if ( p == NULL ) return -1; // if ( pData->fVerbose ) // printf( "Memory usage after construction: Total = %d. Peak = %d.\n", s_MemoryTotal, s_MemoryPeak ); //Fxu_MatrixPrint( NULL, p ); if ( pData->fOnlyS ) { pData->nNodesNew = 0; do { Weight1 = Fxu_HeapSingleReadMaxWeight( p->pHeapSingle ); if ( pData->fVerbose ) printf( "Div %5d : Best single = %5d.\r", Counter++, Weight1 ); if ( Weight1 > 0 || (Weight1 == 0 && pData->fUse0) ) Fxu_UpdateSingle( p ); else break; } while ( ++pData->nNodesNew < pData->nNodesExt ); } else if ( pData->fOnlyD ) { pData->nNodesNew = 0; do { Weight2 = Fxu_HeapDoubleReadMaxWeight( p->pHeapDouble ); if ( pData->fVerbose ) printf( "Div %5d : Best double = %5d.\r", Counter++, Weight2 ); if ( Weight2 > 0 || (Weight2 == 0 && pData->fUse0) ) Fxu_UpdateDouble( p ); else break; } while ( ++pData->nNodesNew < pData->nNodesExt ); } else if ( !pData->fUseCompl ) { pData->nNodesNew = 0; do { Weight1 = Fxu_HeapSingleReadMaxWeight( p->pHeapSingle ); Weight2 = Fxu_HeapDoubleReadMaxWeight( p->pHeapDouble ); if ( pData->fVerbose ) printf( "Div %5d : Best double = %5d. Best single = %5d.\r", Counter++, Weight2, Weight1 ); //Fxu_Select( p, &pSingle, &pDouble ); if ( Weight1 >= Weight2 ) { if ( Weight1 > 0 || (Weight1 == 0 && pData->fUse0) ) Fxu_UpdateSingle( p ); else break; } else { if ( Weight2 > 0 || (Weight2 == 0 && pData->fUse0) ) Fxu_UpdateDouble( p ); else break; } } while ( ++pData->nNodesNew < pData->nNodesExt ); } else { // use the complement pData->nNodesNew = 0; do { Weight1 = Fxu_HeapSingleReadMaxWeight( p->pHeapSingle ); Weight2 = Fxu_HeapDoubleReadMaxWeight( p->pHeapDouble ); // select the best single and double Weight3 = Fxu_Select( p, &pSingle, &pDouble ); if ( pData->fVerbose ) printf( "Div %5d : Best double = %5d. Best single = %5d. Best complement = %5d.\r", Counter++, Weight2, Weight1, Weight3 ); if ( Weight3 > 0 || (Weight3 == 0 && pData->fUse0) ) Fxu_Update( p, pSingle, pDouble ); else break; } while ( ++pData->nNodesNew < pData->nNodesExt ); } if ( pData->fVerbose ) printf( "Total single = %3d. Total double = %3d. Total compl = %3d. \n", p->nDivs1, p->nDivs2, p->nDivs3 ); // create the new covers if ( pData->nNodesNew ) Fxu_CreateCovers( p, pData ); Fxu_MatrixDelete( p ); // printf( "Memory usage after deallocation: Total = %d. Peak = %d.\n", s_MemoryTotal, s_MemoryPeak ); if ( pData->nNodesNew == pData->nNodesExt ) printf( "Warning: The limit on the number of extracted divisors has been reached.\n" ); return pData->nNodesNew; }