blob: b48961e1b8bc4711e046772afb89de6f65c8d47e [file] [log] [blame]
/**CFile****************************************************************
FileName [fxuUpdate.c]
PackageName [MVSIS 2.0: Multi-valued logic synthesis system.]
Synopsis [Updating the sparse matrix when divisors are accepted.]
Author [MVSIS Group]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - February 1, 2003.]
Revision [$Id: fxuUpdate.c,v 1.0 2003/02/01 00:00:00 alanmi Exp $]
***********************************************************************/
#include "fxuInt.h"
ABC_NAMESPACE_IMPL_START
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
static void Fxu_UpdateDoublePairs( Fxu_Matrix * p, Fxu_Double * pDouble, Fxu_Var * pVar );
static void Fxu_UpdateMatrixDoubleCreateCubes( Fxu_Matrix * p, Fxu_Cube * pCube1, Fxu_Cube * pCube2, Fxu_Double * pDiv );
static void Fxu_UpdateMatrixDoubleClean( Fxu_Matrix * p, Fxu_Cube * pCubeUse, Fxu_Cube * pCubeRem );
static void Fxu_UpdateMatrixSingleClean( Fxu_Matrix * p, Fxu_Var * pVar1, Fxu_Var * pVar2, Fxu_Var * pVarNew );
static void Fxu_UpdateCreateNewVars( Fxu_Matrix * p, Fxu_Var ** ppVarC, Fxu_Var ** ppVarD, int nCubes );
static int Fxu_UpdatePairCompare( Fxu_Pair ** ppP1, Fxu_Pair ** ppP2 );
static void Fxu_UpdatePairsSort( Fxu_Matrix * p, Fxu_Double * pDouble );
static void Fxu_UpdateCleanOldDoubles( Fxu_Matrix * p, Fxu_Double * pDiv, Fxu_Cube * pCube );
static void Fxu_UpdateAddNewDoubles( Fxu_Matrix * p, Fxu_Cube * pCube );
static void Fxu_UpdateCleanOldSingles( Fxu_Matrix * p );
static void Fxu_UpdateAddNewSingles( Fxu_Matrix * p, Fxu_Var * pVar );
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**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 [Updates after accepting single cube divisor.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Fxu_UpdateSingle( Fxu_Matrix * p )
{
Fxu_Single * pSingle;
Fxu_Cube * pCube, * pCubeNew;
Fxu_Var * pVarC, * pVarD;
Fxu_Var * pVar1, * pVar2;
// read the best divisor from the heap
pSingle = Fxu_HeapSingleReadMax( p->pHeapSingle );
// get the variables of this single-cube divisor
pVar1 = pSingle->pVar1;
pVar2 = pSingle->pVar2;
// 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
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 );
// 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 );
// we should undo the rings before creating new singles
// unmark the cubes
Fxu_MatrixRingCubesUnmark( p );
Fxu_MatrixRingVarsUnmark( p );
// create new singles
Fxu_UpdateAddNewSingles( p, pVarC );
Fxu_UpdateAddNewSingles( p, pVarD );
p->nDivs1++;
}
/**Function*************************************************************
Synopsis [Updates the matrix after accepting a double cube divisor.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Fxu_UpdateDouble( Fxu_Matrix * p )
{
Fxu_Double * pDiv;
Fxu_Cube * pCube, * pCubeNew1, * pCubeNew2;
Fxu_Var * pVarC, * pVarD;
// remove the best divisor from the heap
pDiv = Fxu_HeapDoubleGetMax( p->pHeapDouble );
// remove the best divisor from the table
Fxu_ListTableDelDivisor( p, pDiv );
// create two new columns (vars)
Fxu_UpdateCreateNewVars( p, &pVarC, &pVarD, 2 );
// create two new rows (cubes)
pCubeNew1 = Fxu_MatrixAddCube( p, pVarD, 0 );
pCubeNew1->pFirst = pCubeNew1;
pCubeNew2 = Fxu_MatrixAddCube( p, pVarD, 1 );
pCubeNew2->pFirst = pCubeNew1;
// set the first cube
pVarD->pFirst = pCubeNew1;
// add the literals to the new cubes
Fxu_UpdateMatrixDoubleCreateCubes( p, pCubeNew1, pCubeNew2, pDiv );
// start collecting the affected cubes and vars
Fxu_MatrixRingCubesStart( p );
Fxu_MatrixRingVarsStart( p );
// replace each two cubes of the pair by one new cube
// the new cube contains the base and the new literal
Fxu_UpdateDoublePairs( p, pDiv, pVarD );
// stop collecting the affected cubes and vars
Fxu_MatrixRingCubesStop( p );
Fxu_MatrixRingVarsStop( p );
// 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, pDiv );
p->nDivs2++;
}
/**Function*************************************************************
Synopsis [Update the pairs.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Fxu_UpdateDoublePairs( Fxu_Matrix * p, Fxu_Double * pDouble, Fxu_Var * pVar )
{
Fxu_Pair * pPair;
Fxu_Cube * pCubeUse, * pCubeRem;
int i;
// collect and sort the pairs
Fxu_UpdatePairsSort( p, pDouble );
// for ( i = 0; i < p->nPairsTemp; i++ )
for ( i = 0; i < p->vPairs->nSize; i++ )
{
// get the pair
// pPair = p->pPairsTemp[i];
pPair = (Fxu_Pair *)p->vPairs->pArray[i];
// out of the two cubes, select the one which comes earlier
pCubeUse = Fxu_PairMinCube( pPair );
pCubeRem = Fxu_PairMaxCube( pPair );
// collect the affected cube
assert( pCubeUse->pOrder == NULL );
Fxu_MatrixRingCubesAdd( p, pCubeUse );
// remove some literals from pCubeUse and all literals from pCubeRem
Fxu_UpdateMatrixDoubleClean( p, pCubeUse, pCubeRem );
// add a literal that depends on the new variable
Fxu_MatrixAddLiteral( p, pCubeUse, pVar );
// check the literal count
assert( pCubeUse->lLits.nItems == pPair->nBase + 1 );
assert( pCubeRem->lLits.nItems == 0 );
// update the divisors by removing useless pairs
Fxu_UpdateCleanOldDoubles( p, pDouble, pCubeUse );
Fxu_UpdateCleanOldDoubles( p, pDouble, pCubeRem );
// remove the pair
MEM_FREE_FXU( p, Fxu_Pair, 1, pPair );
}
p->vPairs->nSize = 0;
}
/**Function*************************************************************
Synopsis [Add two cubes corresponding to the given double-cube divisor.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Fxu_UpdateMatrixDoubleCreateCubes( Fxu_Matrix * p, Fxu_Cube * pCube1, Fxu_Cube * pCube2, Fxu_Double * pDiv )
{
Fxu_Lit * pLit1, * pLit2;
Fxu_Pair * pPair;
int nBase, nLits1, nLits2;
// fill in the SOP and copy the fanins
nBase = nLits1 = nLits2 = 0;
pPair = pDiv->lPairs.pHead;
pLit1 = pPair->pCube1->lLits.pHead;
pLit2 = pPair->pCube2->lLits.pHead;
while ( 1 )
{
if ( pLit1 && pLit2 )
{
if ( pLit1->iVar == pLit2->iVar )
{ // skip the cube free part
pLit1 = pLit1->pHNext;
pLit2 = pLit2->pHNext;
nBase++;
}
else if ( pLit1->iVar < pLit2->iVar )
{ // add literal to the first cube
Fxu_MatrixAddLiteral( p, pCube1, pLit1->pVar );
// move to the next literal in this cube
pLit1 = pLit1->pHNext;
nLits1++;
}
else
{ // add literal to the second cube
Fxu_MatrixAddLiteral( p, pCube2, pLit2->pVar );
// move to the next literal in this cube
pLit2 = pLit2->pHNext;
nLits2++;
}
}
else if ( pLit1 && !pLit2 )
{ // add literal to the first cube
Fxu_MatrixAddLiteral( p, pCube1, pLit1->pVar );
// move to the next literal in this cube
pLit1 = pLit1->pHNext;
nLits1++;
}
else if ( !pLit1 && pLit2 )
{ // add literal to the second cube
Fxu_MatrixAddLiteral( p, pCube2, pLit2->pVar );
// move to the next literal in this cube
pLit2 = pLit2->pHNext;
nLits2++;
}
else
break;
}
assert( pPair->nLits1 == nLits1 );
assert( pPair->nLits2 == nLits2 );
assert( pPair->nBase == nBase );
}
/**Function*************************************************************
Synopsis [Create the node equal to double-cube divisor.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Fxu_UpdateMatrixDoubleClean( Fxu_Matrix * p, Fxu_Cube * pCubeUse, Fxu_Cube * pCubeRem )
{
Fxu_Lit * pLit1, * bLit1Next;
Fxu_Lit * pLit2, * bLit2Next;
// initialize the starting literals
pLit1 = pCubeUse->lLits.pHead;
pLit2 = pCubeRem->lLits.pHead;
bLit1Next = pLit1? pLit1->pHNext: NULL;
bLit2Next = pLit2? pLit2->pHNext: NULL;
// go through the pair and remove the literals in the base
// from the first cube and all literals from the second cube
while ( 1 )
{
if ( pLit1 && pLit2 )
{
if ( pLit1->iVar == pLit2->iVar )
{ // this literal is present in both cubes - it belongs to the base
// mark the affected var
if ( pLit1->pVar->pOrder == NULL )
Fxu_MatrixRingVarsAdd( p, pLit1->pVar );
// leave the base in pCubeUse; delete it from pCubeRem
Fxu_MatrixDelLiteral( p, pLit2 );
// step to the next literals
pLit1 = bLit1Next;
pLit2 = bLit2Next;
bLit1Next = pLit1? pLit1->pHNext: NULL;
bLit2Next = pLit2? pLit2->pHNext: NULL;
}
else if ( pLit1->iVar < pLit2->iVar )
{ // this literal is present in pCubeUse - remove it
// mark the affected var
if ( pLit1->pVar->pOrder == NULL )
Fxu_MatrixRingVarsAdd( p, pLit1->pVar );
// delete this literal
Fxu_MatrixDelLiteral( p, pLit1 );
// step to the next literals
pLit1 = bLit1Next;
bLit1Next = pLit1? pLit1->pHNext: NULL;
}
else
{ // this literal is present in pCubeRem - remove it
// mark the affected var
if ( pLit2->pVar->pOrder == NULL )
Fxu_MatrixRingVarsAdd( p, pLit2->pVar );
// delete this literal
Fxu_MatrixDelLiteral( p, pLit2 );
// step to the next literals
pLit2 = bLit2Next;
bLit2Next = pLit2? pLit2->pHNext: NULL;
}
}
else if ( pLit1 && !pLit2 )
{ // this literal is present in pCubeUse - leave it
// mark the affected var
if ( pLit1->pVar->pOrder == NULL )
Fxu_MatrixRingVarsAdd( p, pLit1->pVar );
// delete this literal
Fxu_MatrixDelLiteral( p, pLit1 );
// step to the next literals
pLit1 = bLit1Next;
bLit1Next = pLit1? pLit1->pHNext: NULL;
}
else if ( !pLit1 && pLit2 )
{ // this literal is present in pCubeRem - remove it
// mark the affected var
if ( pLit2->pVar->pOrder == NULL )
Fxu_MatrixRingVarsAdd( p, pLit2->pVar );
// delete this literal
Fxu_MatrixDelLiteral( p, pLit2 );
// step to the next literals
pLit2 = bLit2Next;
bLit2Next = pLit2? pLit2->pHNext: NULL;
}
else
break;
}
}
/**Function*************************************************************
Synopsis [Updates the matrix after selecting a single cube divisor.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Fxu_UpdateMatrixSingleClean( Fxu_Matrix * p, Fxu_Var * pVar1, Fxu_Var * pVar2, Fxu_Var * pVarNew )
{
Fxu_Lit * pLit1, * bLit1Next;
Fxu_Lit * pLit2, * bLit2Next;
// initialize the starting literals
pLit1 = pVar1->lLits.pHead;
pLit2 = pVar2->lLits.pHead;
bLit1Next = pLit1? pLit1->pVNext: NULL;
bLit2Next = pLit2? pLit2->pVNext: NULL;
while ( 1 )
{
if ( pLit1 && pLit2 )
{
if ( pLit1->pCube->pVar->iVar == pLit2->pCube->pVar->iVar )
{ // these literals coincide
if ( pLit1->iCube == pLit2->iCube )
{ // these literals coincide
// collect the affected cube
assert( pLit1->pCube->pOrder == NULL );
Fxu_MatrixRingCubesAdd( p, pLit1->pCube );
// add the literal to this cube corresponding to the new column
Fxu_MatrixAddLiteral( p, pLit1->pCube, pVarNew );
// clean the old cubes
Fxu_UpdateCleanOldDoubles( p, NULL, pLit1->pCube );
// remove the literals
Fxu_MatrixDelLiteral( p, pLit1 );
Fxu_MatrixDelLiteral( p, pLit2 );
// go to the next literals
pLit1 = bLit1Next;
pLit2 = bLit2Next;
bLit1Next = pLit1? pLit1->pVNext: NULL;
bLit2Next = pLit2? pLit2->pVNext: NULL;
}
else if ( pLit1->iCube < pLit2->iCube )
{
pLit1 = bLit1Next;
bLit1Next = pLit1? pLit1->pVNext: NULL;
}
else
{
pLit2 = bLit2Next;
bLit2Next = pLit2? pLit2->pVNext: NULL;
}
}
else if ( pLit1->pCube->pVar->iVar < pLit2->pCube->pVar->iVar )
{
pLit1 = bLit1Next;
bLit1Next = pLit1? pLit1->pVNext: NULL;
}
else
{
pLit2 = bLit2Next;
bLit2Next = pLit2? pLit2->pVNext: NULL;
}
}
else if ( pLit1 && !pLit2 )
{
pLit1 = bLit1Next;
bLit1Next = pLit1? pLit1->pVNext: NULL;
}
else if ( !pLit1 && pLit2 )
{
pLit2 = bLit2Next;
bLit2Next = pLit2? pLit2->pVNext: NULL;
}
else
break;
}
}
/**Function*************************************************************
Synopsis [Sort the pairs.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Fxu_UpdatePairsSort( Fxu_Matrix * p, Fxu_Double * pDouble )
{
Fxu_Pair * pPair;
// order the pairs by the first cube to ensure that new literals are added
// to the matrix from top to bottom - collect pairs into the array
p->vPairs->nSize = 0;
Fxu_DoubleForEachPair( pDouble, pPair )
Vec_PtrPush( p->vPairs, pPair );
if ( p->vPairs->nSize < 2 )
return;
// sort
qsort( (void *)p->vPairs->pArray, p->vPairs->nSize, sizeof(Fxu_Pair *),
(int (*)(const void *, const void *)) Fxu_UpdatePairCompare );
assert( Fxu_UpdatePairCompare( (Fxu_Pair**)p->vPairs->pArray, (Fxu_Pair**)p->vPairs->pArray + p->vPairs->nSize - 1 ) < 0 );
}
/**Function*************************************************************
Synopsis [Compares the vars by their number.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Fxu_UpdatePairCompare( Fxu_Pair ** ppP1, Fxu_Pair ** ppP2 )
{
Fxu_Cube * pC1 = (*ppP1)->pCube1;
Fxu_Cube * pC2 = (*ppP2)->pCube1;
int iP1CubeMin, iP2CubeMin;
if ( pC1->pVar->iVar < pC2->pVar->iVar )
return -1;
if ( pC1->pVar->iVar > pC2->pVar->iVar )
return 1;
iP1CubeMin = Fxu_PairMinCubeInt( *ppP1 );
iP2CubeMin = Fxu_PairMinCubeInt( *ppP2 );
if ( iP1CubeMin < iP2CubeMin )
return -1;
if ( iP1CubeMin > iP2CubeMin )
return 1;
assert( 0 );
return 0;
}
/**Function*************************************************************
Synopsis [Create new variables.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Fxu_UpdateCreateNewVars( Fxu_Matrix * p, Fxu_Var ** ppVarC, Fxu_Var ** ppVarD, int nCubes )
{
Fxu_Var * pVarC, * pVarD;
// add a new column for the complement
pVarC = Fxu_MatrixAddVar( p );
pVarC->nCubes = 0;
// add a new column for the divisor
pVarD = Fxu_MatrixAddVar( p );
pVarD->nCubes = nCubes;
// mark this entry in the Value2Node array
// assert( p->pValue2Node[pVarC->iVar] > 0 );
// p->pValue2Node[pVarD->iVar ] = p->pValue2Node[pVarC->iVar];
// p->pValue2Node[pVarD->iVar+1] = p->pValue2Node[pVarC->iVar]+1;
*ppVarC = pVarC;
*ppVarD = pVarD;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Fxu_UpdateCleanOldDoubles( Fxu_Matrix * p, Fxu_Double * pDiv, Fxu_Cube * pCube )
{
Fxu_Double * pDivCur;
Fxu_Pair * pPair;
int i;
// if the cube is a recently introduced one
// it does not have pairs allocated
// in this case, there is nothing to update
if ( pCube->pVar->ppPairs == NULL )
return;
// go through all the pairs of this cube
Fxu_CubeForEachPair( pCube, pPair, i )
{
// get the divisor of this pair
pDivCur = pPair->pDiv;
// skip the current divisor
if ( pDivCur == pDiv )
continue;
// remove this pair
Fxu_ListDoubleDelPair( pDivCur, pPair );
// the divisor may have become useless by now
if ( pDivCur->lPairs.nItems == 0 )
{
assert( pDivCur->Weight == pPair->nBase - 1 );
Fxu_HeapDoubleDelete( p->pHeapDouble, pDivCur );
Fxu_MatrixDelDivisor( p, pDivCur );
}
else
{
// update the divisor's weight
pDivCur->Weight -= pPair->nLits1 + pPair->nLits2 - 1 + pPair->nBase;
Fxu_HeapDoubleUpdate( p->pHeapDouble, pDivCur );
}
MEM_FREE_FXU( p, Fxu_Pair, 1, pPair );
}
// finally erase all the pair info associated with this cube
Fxu_PairClearStorage( pCube );
}
/**Function*************************************************************
Synopsis [Adds the new divisors that depend on the cube.]
Description [Go through all the non-empty cubes of this cover
(except the given cube) and, for each of them, add the new divisor
with the given cube.]
SideEffects []
SeeAlso []
***********************************************************************/
void Fxu_UpdateAddNewDoubles( Fxu_Matrix * p, Fxu_Cube * pCube )
{
Fxu_Cube * pTemp;
assert( pCube->pOrder );
// if the cube is a recently introduced one
// it does not have pairs allocated
// in this case, there is nothing to update
if ( pCube->pVar->ppPairs == NULL )
return;
for ( pTemp = pCube->pFirst; pTemp->pVar == pCube->pVar; pTemp = pTemp->pNext )
{
// do not add pairs with the empty cubes
if ( pTemp->lLits.nItems == 0 )
continue;
// to prevent adding duplicated pairs of the new cubes
// do not add the pair, if the current cube is marked
if ( pTemp->pOrder && pTemp->iCube >= pCube->iCube )
continue;
Fxu_MatrixAddDivisor( p, pTemp, pCube );
}
}
/**Function*************************************************************
Synopsis [Removes old single cube divisors.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Fxu_UpdateCleanOldSingles( Fxu_Matrix * p )
{
Fxu_Single * pSingle, * pSingle2;
int WeightNew;
int Counter = 0;
Fxu_MatrixForEachSingleSafe( p, pSingle, pSingle2 )
{
// if at least one of the variables is marked, recalculate
if ( pSingle->pVar1->pOrder || pSingle->pVar2->pOrder )
{
Counter++;
// get the new weight
WeightNew = -2 + Fxu_SingleCountCoincidence( p, pSingle->pVar1, pSingle->pVar2 );
if ( WeightNew >= 0 )
{
pSingle->Weight = WeightNew;
Fxu_HeapSingleUpdate( p->pHeapSingle, pSingle );
}
else
{
Fxu_HeapSingleDelete( p->pHeapSingle, pSingle );
Fxu_ListMatrixDelSingle( p, pSingle );
MEM_FREE_FXU( p, Fxu_Single, 1, pSingle );
}
}
}
// printf( "Called procedure %d times.\n", Counter );
}
/**Function*************************************************************
Synopsis [Updates the single cube divisors.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Fxu_UpdateAddNewSingles( Fxu_Matrix * p, Fxu_Var * pVar )
{
Fxu_MatrixComputeSinglesOne( p, pVar );
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
ABC_NAMESPACE_IMPL_END