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

  Synopsis    [Checks for symmetry of x and y.]

  Description [Checks for symmetry of x and y. Ignores projection
  functions, unless they are isolated. Returns 1 in case of symmetry; 0
  otherwise.]

  SideEffects [None]

******************************************************************************/
Function
Synopsis    [Checks for symmetry of x and y.]

Description [Checks for symmetry of x and y. Ignores projection
functions, unless they are isolated. Returns 1 in case of symmetry; 0
otherwise.]


Function Synopsis [ Checks for symmetry of x and y . ] Description [ Checks for symmetry of x and y . Ignores projection functions unless they are isolated . Returns 1 in case of symmetry ; 0 otherwise . ]
int
cuddSymmCheck(
  DdManager * table,
  int  x,
  int  y)
{
    DdNode *f,*f0,*f1,*f01,*f00,*f11,*f10;
    int comple;         
    int xsymmy;         
    int xsymmyp;        
    int arccount;       
    int TotalRefCount;  
    int yindex;
    int i;
    DdNodePtr *list;
    int slots;
    DdNode *sentinel = &(table->sentinel);
#ifdef DD_DEBUG
    int xindex;
#endif
    if (table->subtables[x].keys == 1) {
        return(0);
    }
    yindex = table->invperm[y];
    if (table->subtables[y].keys == 1) {
        if (table->vars[yindex]->ref == 1)
            return(0);
    }
    xsymmy = xsymmyp = 1;
    arccount = 0;
    slots = table->subtables[x].slots;
    list = table->subtables[x].nodelist;
    for (i = 0; i < slots; i++) {
        f = list[i];
        while (f != sentinel) {
            f1 = cuddT(f);
            f0 = Cudd_Regular(cuddE(f));
            comple = Cudd_IsComplement(cuddE(f));
            if ((int) f1->index == yindex) {
                arccount++;
                f11 = cuddT(f1); f10 = cuddE(f1);
            } else {
                if ((int) f0->index != yindex) {
                    if (f1 != DD_ONE(table) || f0 != DD_ONE(table) || f->ref != 1)
                        return(0); 
                }
                f11 = f10 = f1;
            }
            if ((int) f0->index == yindex) {
                arccount++;
                f01 = cuddT(f0); f00 = cuddE(f0);
            } else {
                f01 = f00 = f0;
            }
            if (comple) {
                f01 = Cudd_Not(f01);
                f00 = Cudd_Not(f00);
            }
            if (f1 != DD_ONE(table) || f0 != DD_ONE(table) || f->ref != 1) {
                xsymmy &= f01 == f10;
                xsymmyp &= f11 == f00;
                if ((xsymmy == 0) && (xsymmyp == 0))
                    return(0);
            }
            f = f->next;
        } 
    } 
    TotalRefCount = -1; 
    slots = table->subtables[y].slots;
    list = table->subtables[y].nodelist;
    for (i = 0; i < slots; i++) {
        f = list[i];
        while (f != sentinel) {
            TotalRefCount += f->ref;
            f = f->next;
        }
    }
#if defined(DD_DEBUG) && defined(DD_VERBOSE)
    if (arccount == TotalRefCount) {
        xindex = table->invperm[x];
        (void) fprintf(table->out,
                       "Found symmetry! x =%d\ty = %d\tPos(%d,%d)\n",
                       xindex,yindex,x,y);
    }
#endif
    return(arccount == TotalRefCount);
}
int cuddSymmCheck ( DdManager * table , int x , int y ) { DdNode * f , * f0 , * f1 , * f01 , * f00 , * f11 , * f10 ; int comple ; int xsymmy ; int xsymmyp ; int arccount ; int TotalRefCount ; int yindex ; int i ; DdNodePtr * list ; int slots ; DdNode * sentinel = & ( table -> sentinel ) ; #ifdef DD_DEBUG int xindex ; #endif if ( table -> subtables [ x ] . keys == 1 ) { return ( 0 ) ; } yindex = table -> invperm [ y ] ; if ( table -> subtables [ y ] . keys == 1 ) { if ( table -> vars [ yindex ] -> ref == 1 ) return ( 0 ) ; } xsymmy = xsymmyp = 1 ; arccount = 0 ; slots = table -> subtables [ x ] . slots ; list = table -> subtables [ x ] . nodelist ; for ( i = 0 ; i < slots ; i ++ ) { f = list [ i ] ; while ( f != sentinel ) { f1 = cuddT ( f ) ; f0 = Cudd_Regular ( cuddE ( f ) ) ; comple = Cudd_IsComplement ( cuddE ( f ) ) ; if ( ( int ) f1 -> index == yindex ) { arccount ++ ; f11 = cuddT ( f1 ) ; f10 = cuddE ( f1 ) ; } else { if ( ( int ) f0 -> index != yindex ) { if ( f1 != DD_ONE ( table ) || f0 != DD_ONE ( table ) || f -> ref != 1 ) return ( 0 ) ; } f11 = f10 = f1 ; } if ( ( int ) f0 -> index == yindex ) { arccount ++ ; f01 = cuddT ( f0 ) ; f00 = cuddE ( f0 ) ; } else { f01 = f00 = f0 ; } if ( comple ) { f01 = Cudd_Not ( f01 ) ; f00 = Cudd_Not ( f00 ) ; } if ( f1 != DD_ONE ( table ) || f0 != DD_ONE ( table ) || f -> ref != 1 ) { xsymmy &= f01 == f10 ; xsymmyp &= f11 == f00 ; if ( ( xsymmy == 0 ) && ( xsymmyp == 0 ) ) return ( 0 ) ; } f = f -> next ; } } TotalRefCount = -1 ; slots = table -> subtables [ y ] . slots ; list = table -> subtables [ y ] . nodelist ; for ( i = 0 ; i < slots ; i ++ ) { f = list [ i ] ; while ( f != sentinel ) { TotalRefCount += f -> ref ; f = f -> next ; } } #if defined ( DD_DEBUG ) && defined ( DD_VERBOSE ) if ( arccount == TotalRefCount ) { xindex = table -> invperm [ x ] ; ( void ) fprintf ( table -> out , " \t \t \n " , xindex , yindex , x , y ) ; } #endif return ( arccount == TotalRefCount ) ; }
Function
Synopsis    [Checks for symmetry of x and y.]
Function Synopsis [ Checks for symmetry of x and y . ]
/* f0 is complemented */ /* x and y may be positively symmetric */ /* x and y may be negatively symmetric */ /* number of arcs from layer x to layer y */ /* total reference count of layer y minus 1 */ /* Checks that x and y are not the projection functions.
    ** For x it is sufficient to check whether there is only one
    ** node; indeed, if there is one node, it is the projection function
    ** and it cannot point to y. Hence, if y isn't just the projection
    ** function, it has one arc coming from a layer different from x.
    */ /* Find f1, f0, f11, f10, f01, f00. */ /* If f is an isolated projection function it is
                    ** allowed to bypass layer y.
                    */ /* f bypasses layer y */ /* while */ /* for */ /* Calculate the total reference counts of y */ /* -1 for projection function */