abc/src/bdd/cudd/cuddApa.c
/**Function********************************************************************

  Synopsis    [Performs the recursive step of Cudd_ApaCountMinterm.]

  Description [Performs the recursive step of Cudd_ApaCountMinterm.
  It is based on the following identity. Let |f| be the
  number of minterms of f. Then:
  <xmp>
    |f| = (|f0|+|f1|)/2
  </xmp>
  where f0 and f1 are the two cofactors of f.
  Uses the identity <code>|f'| = max - |f|</code>.
  The procedure expects the argument "node" to be a regular pointer, and
  guarantees this condition is met in the recursive calls.
  For efficiency, the result of a call is cached only if the node has
  a reference count greater than 1.
  Returns the number of minterms of the function rooted at node.]

  SideEffects [None]

******************************************************************************/
Function
Synopsis    [Performs the recursive step of Cudd_ApaCountMinterm.]

Description [Performs the recursive step of Cudd_ApaCountMinterm.
It is based on the following identity. Let |f| be the
number of minterms of f.


Function Synopsis [ Performs the recursive step of Cudd_ApaCountMinterm . ] Description [ Performs the recursive step of Cudd_ApaCountMinterm . It is based on the following identity . Let |f| be the number of minterms of f .
static DdApaNumber
cuddApaCountMintermAux(
  DdNode * node,
  int  digits,
  DdApaNumber  max,
  DdApaNumber  min,
  st__table * table)
{
    DdNode      *Nt, *Ne;
    DdApaNumber mint, mint1, mint2;
    DdApaDigit  carryout;
    if (cuddIsConstant(node)) {
        if (node == background || node == zero) {
            return(min);
        } else {
            return(max);
        }
    }
    if (node->ref > 1 && st__lookup(table, (const char *)node, (char **)&mint)) {
        return(mint);
    }
    Nt = cuddT(node); Ne = cuddE(node);
    mint1 = cuddApaCountMintermAux(Nt,  digits, max, min, table);
    if (mint1 == NULL) return(NULL);
    mint2 = cuddApaCountMintermAux(Cudd_Regular(Ne), digits, max, min, table);
    if (mint2 == NULL) {
        if (Nt->ref == 1) ABC_FREE(mint1);
        return(NULL);
    }
    mint = Cudd_NewApaNumber(digits);
    if (mint == NULL) {
        if (Nt->ref == 1) ABC_FREE(mint1);
        if (Cudd_Regular(Ne)->ref == 1) ABC_FREE(mint2);
        return(NULL);
    }
    if (Cudd_IsComplement(Ne)) {
        (void) Cudd_ApaSubtract(digits,max,mint2,mint);
        carryout = Cudd_ApaAdd(digits,mint1,mint,mint);
    } else {
        carryout = Cudd_ApaAdd(digits,mint1,mint2,mint);
    }
    Cudd_ApaShiftRight(digits,carryout,mint,mint);
    if (Nt->ref == 1) ABC_FREE(mint1);
    if (Cudd_Regular(Ne)->ref == 1) ABC_FREE(mint2);
    if (node->ref > 1) {
        if ( st__insert(table, (char *)node, (char *)mint) == st__OUT_OF_MEM) {
            ABC_FREE(mint);
            return(NULL);
        }
    }
    return(mint);
}
static DdApaNumber cuddApaCountMintermAux ( DdNode * node , int digits , DdApaNumber max , DdApaNumber min , st__table * table ) { DdNode * Nt , * Ne ; DdApaNumber mint , mint1 , mint2 ; DdApaDigit carryout ; if ( cuddIsConstant ( node ) ) { if ( node == background || node == zero ) { return ( min ) ; } else { return ( max ) ; } } if ( node -> ref > 1 && st__lookup ( table , ( const char * ) node , ( char * * ) & mint ) ) { return ( mint ) ; } Nt = cuddT ( node ) ; Ne = cuddE ( node ) ; mint1 = cuddApaCountMintermAux ( Nt , digits , max , min , table ) ; if ( mint1 == NULL ) return ( NULL ) ; mint2 = cuddApaCountMintermAux ( Cudd_Regular ( Ne ) , digits , max , min , table ) ; if ( mint2 == NULL ) { if ( Nt -> ref == 1 ) ABC_FREE ( mint1 ) ; return ( NULL ) ; } mint = Cudd_NewApaNumber ( digits ) ; if ( mint == NULL ) { if ( Nt -> ref == 1 ) ABC_FREE ( mint1 ) ; if ( Cudd_Regular ( Ne ) -> ref == 1 ) ABC_FREE ( mint2 ) ; return ( NULL ) ; } if ( Cudd_IsComplement ( Ne ) ) { ( void ) Cudd_ApaSubtract ( digits , max , mint2 , mint ) ; carryout = Cudd_ApaAdd ( digits , mint1 , mint , mint ) ; } else { carryout = Cudd_ApaAdd ( digits , mint1 , mint2 , mint ) ; } Cudd_ApaShiftRight ( digits , carryout , mint , mint ) ; if ( Nt -> ref == 1 ) ABC_FREE ( mint1 ) ; if ( Cudd_Regular ( Ne ) -> ref == 1 ) ABC_FREE ( mint2 ) ; if ( node -> ref > 1 ) { if ( st__insert ( table , ( char * ) node , ( char * ) mint ) == st__OUT_OF_MEM ) { ABC_FREE ( mint ) ; return ( NULL ) ; } } return ( mint ) ; }
Function
Synopsis    [Performs the recursive step of Cudd_ApaCountMinterm.]
Function Synopsis [ Performs the recursive step of Cudd_ApaCountMinterm . ]
/* If the refernce count of a child is 1, its minterm count
    ** hasn't been stored in table.  Therefore, it must be explicitly
    ** freed here. */