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

  Synopsis [Moves x up until either it reaches the bound (x_low) or
  the size of the ZDD heap increases too much.]

  Description [Moves x up until either it reaches the bound (x_low) or
  the size of the ZDD heap increases too much. Assumes that x is the top
  of a symmetry group.  Checks x for symmetry to the adjacent
  variables. If symmetry is found, the symmetry group of x is merged
  with the symmetry group of the other variable. Returns the set of
  moves in case of success; ZDD_MV_OOM if memory is full.]

  SideEffects [None]

  SeeAlso     []

******************************************************************************/
Function
Synopsis [Moves x up until either it reaches the bound (x_low) or
the size of the ZDD heap increases too much.]

Description [Moves x up until either it reaches the bound (x_low) or
the size of the ZDD heap increases too much. Assumes that x is the top
of a symmetry group.  Checks x for symmetry to the adjacent
variables. If symmetry is found, the symmetry group of x is merged
with the symmetry group of the other variable. Returns the set of
moves in case of success; ZDD_MV_OOM if memory is full.]




Function Synopsis [ Moves x up until either it reaches the bound ( x_low ) or the size of the ZDD heap increases too much . ] Description [ Moves x up until either it reaches the bound ( x_low ) or the size of the ZDD heap increases too much . Assumes that x is the top of a symmetry group . Checks x for symmetry to the adjacent variables . If symmetry is found the symmetry group of x is merged with the symmetry group of the other variable . Returns the set of moves in case of success ; ZDD_MV_OOM if memory is full . ]
static Move *
cuddZddSymmSifting_up(
  DdManager * table,
  int  x,
  int  x_low,
  int  initial_size)
{
    Move        *moves;
    Move        *move;
    int         y;
    int         size;
    int         limit_size = initial_size;
    int         i, gytop;
    moves = NULL;
    y = cuddZddNextLow(table, x);
    while (y >= x_low) {
        gytop = table->subtableZ[y].next;
        if (cuddZddSymmCheck(table, y, x)) {
            table->subtableZ[y].next = x;
            i = table->subtableZ[x].next;
            while (table->subtableZ[i].next != (unsigned) x)
                i = table->subtableZ[i].next;
            table->subtableZ[i].next = gytop;
        }
        else if ((table->subtableZ[x].next == (unsigned) x) &&
            (table->subtableZ[y].next == (unsigned) y)) {
            size = cuddZddSwapInPlace(table, y, x);
            if (size == 0)
                goto cuddZddSymmSifting_upOutOfMem;
            move = (Move *)cuddDynamicAllocNode(table);
            if (move == NULL)
                goto cuddZddSymmSifting_upOutOfMem;
            move->x = y;
            move->y = x;
            move->size = size;
            move->next = moves;
            moves = move;
            if ((double)size >
                (double)limit_size * table->maxGrowth)
                return(moves);
            if (size < limit_size)
                limit_size = size;
        }
        else { 
            size = zdd_group_move(table, y, x, &moves);
            if ((double)size >
                (double)limit_size * table->maxGrowth)
                return(moves);
            if (size < limit_size)
                limit_size = size;
        }
        x = gytop;
        y = cuddZddNextLow(table, x);
    }
    return(moves);
cuddZddSymmSifting_upOutOfMem:
    while (moves != NULL) {
        move = moves->next;
        cuddDeallocMove(table, moves);
        moves = move;
    }
    return(ZDD_MV_OOM);
}
static Move * cuddZddSymmSifting_up ( DdManager * table , int x , int x_low , int initial_size ) { Move * moves ; Move * move ; int y ; int size ; int limit_size = initial_size ; int i , gytop ; moves = NULL ; y = cuddZddNextLow ( table , x ) ; while ( y >= x_low ) { gytop = table -> subtableZ [ y ] . next ; if ( cuddZddSymmCheck ( table , y , x ) ) { table -> subtableZ [ y ] . next = x ; i = table -> subtableZ [ x ] . next ; while ( table -> subtableZ [ i ] . next != ( unsigned ) x ) i = table -> subtableZ [ i ] . next ; table -> subtableZ [ i ] . next = gytop ; } else if ( ( table -> subtableZ [ x ] . next == ( unsigned ) x ) && ( table -> subtableZ [ y ] . next == ( unsigned ) y ) ) { size = cuddZddSwapInPlace ( table , y , x ) ; if ( size == 0 ) goto cuddZddSymmSifting_upOutOfMem ; move = ( Move * ) cuddDynamicAllocNode ( table ) ; if ( move == NULL ) goto cuddZddSymmSifting_upOutOfMem ; move -> x = y ; move -> y = x ; move -> size = size ; move -> next = moves ; moves = move ; if ( ( double ) size > ( double ) limit_size * table -> maxGrowth ) return ( moves ) ; if ( size < limit_size ) limit_size = size ; } else { size = zdd_group_move ( table , y , x , & moves ) ; if ( ( double ) size > ( double ) limit_size * table -> maxGrowth ) return ( moves ) ; if ( size < limit_size ) limit_size = size ; } x = gytop ; y = cuddZddNextLow ( table , x ) ; } return ( moves ) ; cuddZddSymmSifting_upOutOfMem : while ( moves != NULL ) { move = moves -> next ; cuddDeallocMove ( table , moves ) ; moves = move ; } return ( ZDD_MV_OOM ) ; }
Function
Synopsis [Moves x up until either it reaches the bound (x_low) or
the size of the ZDD heap increases too much.]
Function Synopsis [ Moves x up until either it reaches the bound ( x_low ) or the size of the ZDD heap increases too much . ]
/* Symmetry found, attach symm groups */ /* x and y have self symmetry */ /* Group move */