Ejemplo n.º 1
0
/**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++;
}
Ejemplo n.º 2
0
/**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;
}