/**CFile***********************************************************************

  FileName    [cuddCompose.c]

  PackageName [cudd]

  Synopsis    [Functional composition and variable permutation of DDs.]

  Description [External procedures included in this module:
                <ul>
                <li> Cudd_bddCompose()
                <li> Cudd_addCompose()
                <li> Cudd_addPermute()
                <li> Cudd_addSwapVariables()
                <li> Cudd_bddPermute()
                <li> Cudd_bddVarMap()
                <li> Cudd_SetVarMap()
                <li> Cudd_bddSwapVariables()
                <li> Cudd_bddAdjPermuteX()
                <li> Cudd_addVectorCompose()
                <li> Cudd_addGeneralVectorCompose()
                <li> Cudd_addNonSimCompose()
                <li> Cudd_bddVectorCompose()
                </ul>
               Internal procedures included in this module:
                <ul>
                <li> cuddBddComposeRecur()
                <li> cuddAddComposeRecur()
                </ul>
               Static procedures included in this module:
                <ul>
                <li> cuddAddPermuteRecur()
                <li> cuddBddPermuteRecur()
                <li> cuddBddVarMapRecur()
                <li> cuddAddVectorComposeRecur()
                <li> cuddAddGeneralVectorComposeRecur()
                <li> cuddAddNonSimComposeRecur()
                <li> cuddBddVectorComposeRecur()
                <li> ddIsIthAddVar()
                <li> ddIsIthAddVarPair()
               </ul>
  The permutation functions use a local cache because the results to
  be remembered depend on the permutation being applied.  Since the
  permutation is just an array, it cannot be stored in the global
  cache. There are different procedured for BDDs and ADDs. This is
  because bddPermuteRecur uses cuddBddIteRecur. If this were changed,
  the procedures could be merged.]

  Author      [Fabio Somenzi and Kavita Ravi]

  Copyright   [Copyright (c) 1995-2004, Regents of the University of Colorado

  All rights reserved.

  Redistribution and use in source and binary forms, with or without
  modification, are permitted provided that the following conditions
  are met:

  Redistributions of source code must retain the above copyright
  notice, this list of conditions and the following disclaimer.

  Redistributions in binary form must reproduce the above copyright
  notice, this list of conditions and the following disclaimer in the
  documentation and/or other materials provided with the distribution.

  Neither the name of the University of Colorado nor the names of its
  contributors may be used to endorse or promote products derived from
  this software without specific prior written permission.

  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  POSSIBILITY OF SUCH DAMAGE.]

******************************************************************************/

#include "misc/util/util_hack.h"
#include "cuddInt.h"

ABC_NAMESPACE_IMPL_START




/*---------------------------------------------------------------------------*/
/* Constant declarations                                                     */
/*---------------------------------------------------------------------------*/

/*---------------------------------------------------------------------------*/
/* Stucture declarations                                                     */
/*---------------------------------------------------------------------------*/

/*---------------------------------------------------------------------------*/
/* Type declarations                                                         */
/*---------------------------------------------------------------------------*/

/*---------------------------------------------------------------------------*/
/* Variable declarations                                                     */
/*---------------------------------------------------------------------------*/

#ifndef lint
static char rcsid[] DD_UNUSED = "$Id: cuddCompose.c,v 1.45 2004/08/13 18:04:47 fabio Exp $";
#endif

#ifdef DD_DEBUG
static int addPermuteRecurHits;
static int bddPermuteRecurHits;
static int bddVectorComposeHits;
static int addVectorComposeHits;

static int addGeneralVectorComposeHits;
#endif

/*---------------------------------------------------------------------------*/
/* Macro declarations                                                        */
/*---------------------------------------------------------------------------*/


/**AutomaticStart*************************************************************/

/*---------------------------------------------------------------------------*/
/* Static function prototypes                                                */
/*---------------------------------------------------------------------------*/

static DdNode * cuddAddPermuteRecur (DdManager *manager, DdHashTable *table, DdNode *node, int *permut);
static DdNode * cuddBddPermuteRecur (DdManager *manager, DdHashTable *table, DdNode *node, int *permut);
static DdNode * cuddBddVarMapRecur (DdManager *manager, DdNode *f);
static DdNode * cuddAddVectorComposeRecur (DdManager *dd, DdHashTable *table, DdNode *f, DdNode **vector, int deepest);
static DdNode * cuddAddNonSimComposeRecur (DdManager *dd, DdNode *f, DdNode **vector, DdNode *key, DdNode *cube, int lastsub);
static DdNode * cuddBddVectorComposeRecur (DdManager *dd, DdHashTable *table, DdNode *f, DdNode **vector, int deepest);
DD_INLINE static int ddIsIthAddVar (DdManager *dd, DdNode *f, unsigned int i);

static DdNode * cuddAddGeneralVectorComposeRecur (DdManager *dd, DdHashTable *table, DdNode *f, DdNode **vectorOn, DdNode **vectorOff, int deepest);
DD_INLINE static int ddIsIthAddVarPair (DdManager *dd, DdNode *f, DdNode *g, unsigned int i);

/**AutomaticEnd***************************************************************/


/*---------------------------------------------------------------------------*/
/* Definition of exported functions                                          */
/*---------------------------------------------------------------------------*/


/**Function********************************************************************

  Synopsis    [Substitutes g for x_v in the BDD for f.]

  Description [Substitutes g for x_v in the BDD for f. v is the index of the
  variable to be substituted. Cudd_bddCompose passes the corresponding
  projection function to the recursive procedure, so that the cache may
  be used.  Returns the composed BDD if successful; NULL otherwise.]

  SideEffects [None]

  SeeAlso     [Cudd_addCompose]

******************************************************************************/
DdNode *
Cudd_bddCompose(
  DdManager * dd,
  DdNode * f,
  DdNode * g,
  int  v)
{
    DdNode *proj, *res;

    /* Sanity check. */
    if (v < 0 || v >= dd->size) return(NULL);

    proj =  dd->vars[v];
    do {
        dd->reordered = 0;
        res = cuddBddComposeRecur(dd,f,g,proj);
    } while (dd->reordered == 1);
    return(res);

} /* end of Cudd_bddCompose */


/**Function********************************************************************

  Synopsis    [Substitutes g for x_v in the ADD for f.]

  Description [Substitutes g for x_v in the ADD for f. v is the index of the
  variable to be substituted. g must be a 0-1 ADD. Cudd_bddCompose passes
  the corresponding projection function to the recursive procedure, so
  that the cache may be used.  Returns the composed ADD if successful;
  NULL otherwise.]

  SideEffects [None]

  SeeAlso     [Cudd_bddCompose]

******************************************************************************/
DdNode *
Cudd_addCompose(
  DdManager * dd,
  DdNode * f,
  DdNode * g,
  int  v)
{
    DdNode *proj, *res;

    /* Sanity check. */
    if (v < 0 || v >= dd->size) return(NULL);

    proj =  dd->vars[v];
    do {
        dd->reordered = 0;
        res = cuddAddComposeRecur(dd,f,g,proj);
    } while (dd->reordered == 1);
    return(res);

} /* end of Cudd_addCompose */


/**Function********************************************************************

  Synopsis    [Permutes the variables of an ADD.]

  Description [Given a permutation in array permut, creates a new ADD
  with permuted variables. There should be an entry in array permut
  for each variable in the manager. The i-th entry of permut holds the
  index of the variable that is to substitute the i-th
  variable. Returns a pointer to the resulting ADD if successful; NULL
  otherwise.]

  SideEffects [None]

  SeeAlso     [Cudd_bddPermute Cudd_addSwapVariables]

******************************************************************************/
DdNode *
Cudd_addPermute(
  DdManager * manager,
  DdNode * node,
  int * permut)
{
    DdHashTable         *table;
    DdNode              *res;

    do {
        manager->reordered = 0;
        table = cuddHashTableInit(manager,1,2);
        if (table == NULL) return(NULL);
        /* Recursively solve the problem. */
        res = cuddAddPermuteRecur(manager,table,node,permut);
        if (res != NULL) cuddRef(res);
        /* Dispose of local cache. */
        cuddHashTableQuit(table);
    } while (manager->reordered == 1);

    if (res != NULL) cuddDeref(res);
    return(res);

} /* end of Cudd_addPermute */


/**Function********************************************************************

  Synopsis [Swaps two sets of variables of the same size (x and y) in
  the ADD f.]

  Description [Swaps two sets of variables of the same size (x and y) in
  the ADD f.  The size is given by n. The two sets of variables are
  assumed to be disjoint. Returns a pointer to the resulting ADD if
  successful; NULL otherwise.]

  SideEffects [None]

  SeeAlso     [Cudd_addPermute Cudd_bddSwapVariables]

******************************************************************************/
DdNode *
Cudd_addSwapVariables(
  DdManager * dd,
  DdNode * f,
  DdNode ** x,
  DdNode ** y,
  int  n)
{
    DdNode *swapped;
    int  i, j, k;
    int  *permut;

    permut = ABC_ALLOC(int,dd->size);
    if (permut == NULL) {
        dd->errorCode = CUDD_MEMORY_OUT;
        return(NULL);
    }
    for (i = 0; i < dd->size; i++) permut[i] = i;
    for (i = 0; i < n; i++) {
        j = x[i]->index;
        k = y[i]->index;
        permut[j] = k;
        permut[k] = j;
    }

    swapped = Cudd_addPermute(dd,f,permut);
    ABC_FREE(permut);

    return(swapped);

} /* end of Cudd_addSwapVariables */


/**Function********************************************************************

  Synopsis    [Permutes the variables of a BDD.]

  Description [Given a permutation in array permut, creates a new BDD
  with permuted variables. There should be an entry in array permut
  for each variable in the manager. The i-th entry of permut holds the
  index of the variable that is to substitute the i-th variable.
  Returns a pointer to the resulting BDD if successful; NULL
  otherwise.]

  SideEffects [None]

  SeeAlso     [Cudd_addPermute Cudd_bddSwapVariables]

******************************************************************************/
DdNode *
Cudd_bddPermute(
  DdManager * manager,
  DdNode * node,
  int * permut)
{
    DdHashTable         *table;
    DdNode              *res;

    do {
        manager->reordered = 0;
        table = cuddHashTableInit(manager,1,2);
        if (table == NULL) return(NULL);
        res = cuddBddPermuteRecur(manager,table,node,permut);
        if (res != NULL) cuddRef(res);
        /* Dispose of local cache. */
        cuddHashTableQuit(table);

    } while (manager->reordered == 1);

    if (res != NULL) cuddDeref(res);
    return(res);

} /* end of Cudd_bddPermute */


/**Function********************************************************************

  Synopsis    [Remaps the variables of a BDD using the default variable map.]

  Description [Remaps the variables of a BDD using the default
  variable map.  A typical use of this function is to swap two sets of
  variables.  The variable map must be registered with Cudd_SetVarMap.
  Returns a pointer to the resulting BDD if successful; NULL
  otherwise.]

  SideEffects [None]

  SeeAlso     [Cudd_bddPermute Cudd_bddSwapVariables Cudd_SetVarMap]

******************************************************************************/
DdNode *
Cudd_bddVarMap(
  DdManager * manager /* DD manager */,
  DdNode * f /* function in which to remap variables */)
{
    DdNode *res;

    if (manager->map == NULL) return(NULL);
    do {
        manager->reordered = 0;
        res = cuddBddVarMapRecur(manager, f);
    } while (manager->reordered == 1);

    return(res);

} /* end of Cudd_bddVarMap */


/**Function********************************************************************

  Synopsis [Registers a variable mapping with the manager.]

  Description [Registers with the manager a variable mapping described
  by two sets of variables.  This variable mapping is then used by
  functions like Cudd_bddVarMap.  This function is convenient for
  those applications that perform the same mapping several times.
  However, if several different permutations are used, it may be more
  efficient not to rely on the registered mapping, because changing
  mapping causes the cache to be cleared.  (The initial setting,
  however, does not clear the cache.) The two sets of variables (x and
  y) must have the same size (x and y).  The size is given by n. The
  two sets of variables are normally disjoint, but this restriction is
  not imposeded by the function. When new variables are created, the
  map is automatically extended (each new variable maps to
  itself). The typical use, however, is to wait until all variables
  are created, and then create the map.  Returns 1 if the mapping is
  successfully registered with the manager; 0 otherwise.]

  SideEffects [Modifies the manager. May clear the cache.]

  SeeAlso     [Cudd_bddVarMap Cudd_bddPermute Cudd_bddSwapVariables]

******************************************************************************/
int
Cudd_SetVarMap (
  DdManager *manager /* DD manager */,
  DdNode **x /* first array of variables */,
  DdNode **y /* second array of variables */,
  int n /* length of both arrays */)
{
    int i;

    if (manager->map != NULL) {
        cuddCacheFlush(manager);
    } else {
        manager->map = ABC_ALLOC(int,manager->maxSize);
        if (manager->map == NULL) {
            manager->errorCode = CUDD_MEMORY_OUT;
            return(0);
        }
        manager->memused += sizeof(int) * manager->maxSize;
    }
    /* Initialize the map to the identity. */
    for (i = 0; i < manager->size; i++) {
        manager->map[i] = i;
    }
    /* Create the map. */
    for (i = 0; i < n; i++) {
        manager->map[x[i]->index] = y[i]->index;
        manager->map[y[i]->index] = x[i]->index;
    }
    return(1);

} /* end of Cudd_SetVarMap */


/**Function********************************************************************

  Synopsis [Swaps two sets of variables of the same size (x and y) in
  the BDD f.]

  Description [Swaps two sets of variables of the same size (x and y)
  in the BDD f. The size is given by n. The two sets of variables are
  assumed to be disjoint.  Returns a pointer to the resulting BDD if
  successful; NULL otherwise.]

  SideEffects [None]

  SeeAlso     [Cudd_bddPermute Cudd_addSwapVariables]

******************************************************************************/
DdNode *
Cudd_bddSwapVariables(
  DdManager * dd,
  DdNode * f,
  DdNode ** x,
  DdNode ** y,
  int  n)
{
    DdNode *swapped;
    int  i, j, k;
    int  *permut;

    permut = ABC_ALLOC(int,dd->size);
    if (permut == NULL) {
        dd->errorCode = CUDD_MEMORY_OUT;
        return(NULL);
    }
    for (i = 0; i < dd->size; i++) permut[i] = i;
    for (i = 0; i < n; i++) {
        j = x[i]->index;
        k = y[i]->index;
        permut[j] = k;
        permut[k] = j;
    }

    swapped = Cudd_bddPermute(dd,f,permut);
    ABC_FREE(permut);

    return(swapped);

} /* end of Cudd_bddSwapVariables */


/**Function********************************************************************

  Synopsis [Rearranges a set of variables in the BDD B.]

  Description [Rearranges a set of variables in the BDD B. The size of
  the set is given by n. This procedure is intended for the
  `randomization' of the priority functions. Returns a pointer to the
  BDD if successful; NULL otherwise.]

  SideEffects [None]

  SeeAlso     [Cudd_bddPermute Cudd_bddSwapVariables
  Cudd_Dxygtdxz Cudd_Dxygtdyz Cudd_PrioritySelect]

******************************************************************************/
DdNode *
Cudd_bddAdjPermuteX(
  DdManager * dd,
  DdNode * B,
  DdNode ** x,
  int  n)
{
    DdNode *swapped;
    int  i, j, k;
    int  *permut;

    permut = ABC_ALLOC(int,dd->size);
    if (permut == NULL) {
        dd->errorCode = CUDD_MEMORY_OUT;
        return(NULL);
    }
    for (i = 0; i < dd->size; i++) permut[i] = i;
    for (i = 0; i < n-2; i += 3) {
        j = x[i]->index;
        k = x[i+1]->index;
        permut[j] = k;
        permut[k] = j;
    }

    swapped = Cudd_bddPermute(dd,B,permut);
    ABC_FREE(permut);

    return(swapped);

} /* end of Cudd_bddAdjPermuteX */


/**Function********************************************************************

  Synopsis    [Composes an ADD with a vector of 0-1 ADDs.]

  Description [Given a vector of 0-1 ADDs, creates a new ADD by
  substituting the 0-1 ADDs for the variables of the ADD f.  There
  should be an entry in vector for each variable in the manager.
  If no substitution is sought for a given variable, the corresponding
  projection function should be specified in the vector.
  This function implements simultaneous composition.
  Returns a pointer to the resulting ADD if successful; NULL
  otherwise.]

  SideEffects [None]

  SeeAlso     [Cudd_addNonSimCompose Cudd_addPermute Cudd_addCompose
  Cudd_bddVectorCompose]

******************************************************************************/
DdNode *
Cudd_addVectorCompose(
  DdManager * dd,
  DdNode * f,
  DdNode ** vector)
{
    DdHashTable         *table;
    DdNode              *res;
    int                 deepest;
    int                 i;

    do {
        dd->reordered = 0;
        /* Initialize local cache. */
        table = cuddHashTableInit(dd,1,2);
        if (table == NULL) return(NULL);

        /* Find deepest real substitution. */
        for (deepest = dd->size - 1; deepest >= 0; deepest--) {
            i = dd->invperm[deepest];
            if (!ddIsIthAddVar(dd,vector[i],i)) {
                break;
            }
        }

        /* Recursively solve the problem. */
        res = cuddAddVectorComposeRecur(dd,table,f,vector,deepest);
        if (res != NULL) cuddRef(res);

        /* Dispose of local cache. */
        cuddHashTableQuit(table);
    } while (dd->reordered == 1);

    if (res != NULL) cuddDeref(res);
    return(res);

} /* end of Cudd_addVectorCompose */


/**Function********************************************************************

  Synopsis    [Composes an ADD with a vector of ADDs.]

  Description [Given a vector of ADDs, creates a new ADD by substituting the
  ADDs for the variables of the ADD f. vectorOn contains ADDs to be substituted
  for the x_v and vectorOff the ADDs to be substituted for x_v'. There should
  be an entry in vector for each variable in the manager.  If no substitution
  is sought for a given variable, the corresponding projection function should
  be specified in the vector.  This function implements simultaneous
  composition.  Returns a pointer to the resulting ADD if successful; NULL
  otherwise.]

  SideEffects [None]

  SeeAlso [Cudd_addVectorCompose Cudd_addNonSimCompose Cudd_addPermute
  Cudd_addCompose Cudd_bddVectorCompose]

******************************************************************************/
DdNode *
Cudd_addGeneralVectorCompose(
  DdManager * dd,
  DdNode * f,
  DdNode ** vectorOn,
  DdNode ** vectorOff)
{
    DdHashTable         *table;
    DdNode              *res;
    int                 deepest;
    int                 i;

    do {
        dd->reordered = 0;
        /* Initialize local cache. */
        table = cuddHashTableInit(dd,1,2);
        if (table == NULL) return(NULL);

        /* Find deepest real substitution. */
        for (deepest = dd->size - 1; deepest >= 0; deepest--) {
            i = dd->invperm[deepest];
            if (!ddIsIthAddVarPair(dd,vectorOn[i],vectorOff[i],i)) {
                break;
            }
        }

        /* Recursively solve the problem. */
        res = cuddAddGeneralVectorComposeRecur(dd,table,f,vectorOn,
                                               vectorOff,deepest);
        if (res != NULL) cuddRef(res);

        /* Dispose of local cache. */
        cuddHashTableQuit(table);
    } while (dd->reordered == 1);

    if (res != NULL) cuddDeref(res);
    return(res);

} /* end of Cudd_addGeneralVectorCompose */


/**Function********************************************************************

  Synopsis    [Composes an ADD with a vector of 0-1 ADDs.]

  Description [Given a vector of 0-1 ADDs, creates a new ADD by
  substituting the 0-1 ADDs for the variables of the ADD f.  There
  should be an entry in vector for each variable in the manager.
  This function implements non-simultaneous composition. If any of the
  functions being composed depends on any of the variables being
  substituted, then the result depends on the order of composition,
  which in turn depends on the variable order: The variables farther from
  the roots in the order are substituted first.
  Returns a pointer to the resulting ADD if successful; NULL
  otherwise.]

  SideEffects [None]

  SeeAlso     [Cudd_addVectorCompose Cudd_addPermute Cudd_addCompose]

******************************************************************************/
DdNode *
Cudd_addNonSimCompose(
  DdManager * dd,
  DdNode * f,
  DdNode ** vector)
{
    DdNode              *cube, *key, *var, *tmp, *piece;
    DdNode              *res;
    int                 i, lastsub;

    /* The cache entry for this function is composed of three parts:
    ** f itself, the replacement relation, and the cube of the
    ** variables being substituted.
    ** The replacement relation is the product of the terms (yi EXNOR gi).
    ** This apporach allows us to use the global cache for this function,
    ** with great savings in memory with respect to using arrays for the
    ** cache entries.
    ** First we build replacement relation and cube of substituted
    ** variables from the vector specifying the desired composition.
    */
    key = DD_ONE(dd);
    cuddRef(key);
    cube = DD_ONE(dd);
    cuddRef(cube);
    for (i = (int) dd->size - 1; i >= 0; i--) {
        if (ddIsIthAddVar(dd,vector[i],(unsigned int)i)) {
            continue;
        }
        var = Cudd_addIthVar(dd,i);
        if (var == NULL) {
            Cudd_RecursiveDeref(dd,key);
            Cudd_RecursiveDeref(dd,cube);
            return(NULL);
        }
        cuddRef(var);
        /* Update cube. */
        tmp = Cudd_addApply(dd,Cudd_addTimes,var,cube);
        if (tmp == NULL) {
            Cudd_RecursiveDeref(dd,key);
            Cudd_RecursiveDeref(dd,cube);
            Cudd_RecursiveDeref(dd,var);
            return(NULL);
        }
        cuddRef(tmp);
        Cudd_RecursiveDeref(dd,cube);
        cube = tmp;
        /* Update replacement relation. */
        piece = Cudd_addApply(dd,Cudd_addXnor,var,vector[i]);
        if (piece == NULL) {
            Cudd_RecursiveDeref(dd,key);
            Cudd_RecursiveDeref(dd,var);
            return(NULL);
        }
        cuddRef(piece);
        Cudd_RecursiveDeref(dd,var);
        tmp = Cudd_addApply(dd,Cudd_addTimes,key,piece);
        if (tmp == NULL) {
            Cudd_RecursiveDeref(dd,key);
            Cudd_RecursiveDeref(dd,piece);
            return(NULL);
        }
        cuddRef(tmp);
        Cudd_RecursiveDeref(dd,key);
        Cudd_RecursiveDeref(dd,piece);
        key = tmp;
    }

    /* Now try composition, until no reordering occurs. */
    do {
        /* Find real substitution with largest index. */
        for (lastsub = dd->size - 1; lastsub >= 0; lastsub--) {
            if (!ddIsIthAddVar(dd,vector[lastsub],(unsigned int)lastsub)) {
                break;
            }
        }

        /* Recursively solve the problem. */
        dd->reordered = 0;
        res = cuddAddNonSimComposeRecur(dd,f,vector,key,cube,lastsub+1);
        if (res != NULL) cuddRef(res);

    } while (dd->reordered == 1);

    Cudd_RecursiveDeref(dd,key);
    Cudd_RecursiveDeref(dd,cube);
    if (res != NULL) cuddDeref(res);
    return(res);

} /* end of Cudd_addNonSimCompose */


/**Function********************************************************************

  Synopsis    [Composes a BDD with a vector of BDDs.]

  Description [Given a vector of BDDs, creates a new BDD by
  substituting the BDDs for the variables of the BDD f.  There
  should be an entry in vector for each variable in the manager.
  If no substitution is sought for a given variable, the corresponding
  projection function should be specified in the vector.
  This function implements simultaneous composition.
  Returns a pointer to the resulting BDD if successful; NULL
  otherwise.]

  SideEffects [None]

  SeeAlso     [Cudd_bddPermute Cudd_bddCompose Cudd_addVectorCompose]

******************************************************************************/
DdNode *
Cudd_bddVectorCompose(
  DdManager * dd,
  DdNode * f,
  DdNode ** vector)
{
    DdHashTable         *table;
    DdNode              *res;
    int                 deepest;
    int                 i;

    do {
        dd->reordered = 0;
        /* Initialize local cache. */
        table = cuddHashTableInit(dd,1,2);
        if (table == NULL) return(NULL);

        /* Find deepest real substitution. */
        for (deepest = dd->size - 1; deepest >= 0; deepest--) {
            i = dd->invperm[deepest];
            if (vector[i] != dd->vars[i]) {
                break;
            }
        }

        /* Recursively solve the problem. */
        res = cuddBddVectorComposeRecur(dd,table,f,vector, deepest);
        if (res != NULL) cuddRef(res);

        /* Dispose of local cache. */
        cuddHashTableQuit(table);
    } while (dd->reordered == 1);

    if (res != NULL) cuddDeref(res);
    return(res);

} /* end of Cudd_bddVectorCompose */


/*---------------------------------------------------------------------------*/
/* Definition of internal functions                                          */
/*---------------------------------------------------------------------------*/


/**Function********************************************************************

  Synopsis    [Performs the recursive step of Cudd_bddCompose.]

  Description [Performs the recursive step of Cudd_bddCompose.
  Exploits the fact that the composition of f' with g
  produces the complement of the composition of f with g to better
  utilize the cache.  Returns the composed BDD if successful; NULL
  otherwise.]

  SideEffects [None]

  SeeAlso     [Cudd_bddCompose]

******************************************************************************/
DdNode *
cuddBddComposeRecur(
  DdManager * dd,
  DdNode * f,
  DdNode * g,
  DdNode * proj)
{
    DdNode      *F, *G, *f1, *f0, *g1, *g0, *r, *t, *e;
    unsigned int v, topf, topg, topindex;
    int         comple;

    statLine(dd);
    v = dd->perm[proj->index];
    F = Cudd_Regular(f);
    topf = cuddI(dd,F->index);

    /* Terminal case. Subsumes the test for constant f. */
    if (topf > v) return(f);

    /* We solve the problem for a regular pointer, and then complement
    ** the result if the pointer was originally complemented.
    */
    comple = Cudd_IsComplement(f);

    /* Check cache. */
    r = cuddCacheLookup(dd,DD_BDD_COMPOSE_RECUR_TAG,F,g,proj);
    if (r != NULL) {
        return(Cudd_NotCond(r,comple));
    }

    if (topf == v) {
        /* Compose. */
        f1 = cuddT(F);
        f0 = cuddE(F);
        r = cuddBddIteRecur(dd, g, f1, f0);
        if (r == NULL) return(NULL);
    } else {
        /* Compute cofactors of f and g. Remember the index of the top
        ** variable.
        */
        G = Cudd_Regular(g);
        topg = cuddI(dd,G->index);
        if (topf > topg) {
            topindex = G->index;
            f1 = f0 = F;
        } else {
            topindex = F->index;
            f1 = cuddT(F);
            f0 = cuddE(F);
        }
        if (topg > topf) {
            g1 = g0 = g;
        } else {
            g1 = cuddT(G);
            g0 = cuddE(G);
            if (g != G) {
                g1 = Cudd_Not(g1);
                g0 = Cudd_Not(g0);
            }
        }
        /* Recursive step. */
        t = cuddBddComposeRecur(dd, f1, g1, proj);
        if (t == NULL) return(NULL);
        cuddRef(t);
        e = cuddBddComposeRecur(dd, f0, g0, proj);
        if (e == NULL) {
            Cudd_IterDerefBdd(dd, t);
            return(NULL);
        }
        cuddRef(e);

        r = cuddBddIteRecur(dd, dd->vars[topindex], t, e);
        if (r == NULL) {
            Cudd_IterDerefBdd(dd, t);
            Cudd_IterDerefBdd(dd, e);
            return(NULL);
        }
        cuddRef(r);
        Cudd_IterDerefBdd(dd, t); /* t & e not necessarily part of r */
        Cudd_IterDerefBdd(dd, e);
        cuddDeref(r);
    }

    cuddCacheInsert(dd,DD_BDD_COMPOSE_RECUR_TAG,F,g,proj,r);

    return(Cudd_NotCond(r,comple));

} /* end of cuddBddComposeRecur */


/**Function********************************************************************

  Synopsis    [Performs the recursive step of Cudd_addCompose.]

  Description [Performs the recursive step of Cudd_addCompose.
  Returns the composed BDD if successful; NULL otherwise.]

  SideEffects [None]

  SeeAlso     [Cudd_addCompose]

******************************************************************************/
DdNode *
cuddAddComposeRecur(
  DdManager * dd,
  DdNode * f,
  DdNode * g,
  DdNode * proj)
{
    DdNode *f1, *f0, *g1, *g0, *r, *t, *e;
    unsigned int v, topf, topg, topindex;

    statLine(dd);
    v = dd->perm[proj->index];
    topf = cuddI(dd,f->index);

    /* Terminal case. Subsumes the test for constant f. */
    if (topf > v) return(f);

    /* Check cache. */
    r = cuddCacheLookup(dd,DD_ADD_COMPOSE_RECUR_TAG,f,g,proj);
    if (r != NULL) {
        return(r);
    }

    if (topf == v) {
        /* Compose. */
        f1 = cuddT(f);
        f0 = cuddE(f);
        r = cuddAddIteRecur(dd, g, f1, f0);
        if (r == NULL) return(NULL);
    } else {
        /* Compute cofactors of f and g. Remember the index of the top
        ** variable.
        */
        topg = cuddI(dd,g->index);
        if (topf > topg) {
            topindex = g->index;
            f1 = f0 = f;
        } else {
            topindex = f->index;
            f1 = cuddT(f);
            f0 = cuddE(f);
        }
        if (topg > topf) {
            g1 = g0 = g;
        } else {
            g1 = cuddT(g);
            g0 = cuddE(g);
        }
        /* Recursive step. */
        t = cuddAddComposeRecur(dd, f1, g1, proj);
        if (t == NULL) return(NULL);
        cuddRef(t);
        e = cuddAddComposeRecur(dd, f0, g0, proj);
        if (e == NULL) {
            Cudd_RecursiveDeref(dd, t);
            return(NULL);
        }
        cuddRef(e);

        if (t == e) {
            r = t;
        } else {
            r = cuddUniqueInter(dd, (int) topindex, t, e);
            if (r == NULL) {
                Cudd_RecursiveDeref(dd, t);
                Cudd_RecursiveDeref(dd, e);
                return(NULL);
            }
        }
        cuddDeref(t);
        cuddDeref(e);
    }

    cuddCacheInsert(dd,DD_ADD_COMPOSE_RECUR_TAG,f,g,proj,r);

    return(r);

} /* end of cuddAddComposeRecur */


/*---------------------------------------------------------------------------*/
/* Definition of static functions                                            */
/*---------------------------------------------------------------------------*/


/**Function********************************************************************

  Synopsis    [Implements the recursive step of Cudd_addPermute.]

  Description [ Recursively puts the ADD in the order given in the
  array permut. Checks for trivial cases to terminate recursion, then
  splits on the children of this node.  Once the solutions for the
  children are obtained, it puts into the current position the node
  from the rest of the ADD that should be here. Then returns this ADD.
  The key here is that the node being visited is NOT put in its proper
  place by this instance, but rather is switched when its proper
  position is reached in the recursion tree.<p>
  The DdNode * that is returned is the same ADD as passed in as node,
  but in the new order.]

  SideEffects [None]

  SeeAlso     [Cudd_addPermute cuddBddPermuteRecur]

******************************************************************************/
static DdNode *
cuddAddPermuteRecur(
  DdManager * manager /* DD manager */,
  DdHashTable * table /* computed table */,
  DdNode * node /* ADD to be reordered */,
  int * permut /* permutation array */)
{
    DdNode      *T,*E;
    DdNode      *res,*var;
    int         index;
    
    statLine(manager);
    /* Check for terminal case of constant node. */
    if (cuddIsConstant(node)) {
        return(node);
    }

    /* If problem already solved, look up answer and return. */
    if (node->ref != 1 && (res = cuddHashTableLookup1(table,node)) != NULL) {
#ifdef DD_DEBUG
        addPermuteRecurHits++;
#endif
        return(res);
    }

    /* Split and recur on children of this node. */
    T = cuddAddPermuteRecur(manager,table,cuddT(node),permut);
    if (T == NULL) return(NULL);
    cuddRef(T);
    E = cuddAddPermuteRecur(manager,table,cuddE(node),permut);
    if (E == NULL) {
        Cudd_RecursiveDeref(manager, T);
        return(NULL);
    }
    cuddRef(E);

    /* Move variable that should be in this position to this position
    ** by creating a single var ADD for that variable, and calling
    ** cuddAddIteRecur with the T and E we just created.
    */
    index = permut[node->index];
    var = cuddUniqueInter(manager,index,DD_ONE(manager),DD_ZERO(manager));
    if (var == NULL) return(NULL);
    cuddRef(var);
    res = cuddAddIteRecur(manager,var,T,E);
    if (res == NULL) {
        Cudd_RecursiveDeref(manager,var);
        Cudd_RecursiveDeref(manager, T);
        Cudd_RecursiveDeref(manager, E);
        return(NULL);
    }
    cuddRef(res);
    Cudd_RecursiveDeref(manager,var);
    Cudd_RecursiveDeref(manager, T);
    Cudd_RecursiveDeref(manager, E);

    /* Do not keep the result if the reference count is only 1, since
    ** it will not be visited again.
    */
    if (node->ref != 1) {
        ptrint fanout = (ptrint) node->ref;
        cuddSatDec(fanout);
        if (!cuddHashTableInsert1(table,node,res,fanout)) {
            Cudd_RecursiveDeref(manager, res);
            return(NULL);
        }
    }
    cuddDeref(res);
    return(res);

} /* end of cuddAddPermuteRecur */


/**Function********************************************************************

  Synopsis    [Implements the recursive step of Cudd_bddPermute.]

  Description [ Recursively puts the BDD in the order given in the array permut.
  Checks for trivial cases to terminate recursion, then splits on the
  children of this node.  Once the solutions for the children are
  obtained, it puts into the current position the node from the rest of
  the BDD that should be here. Then returns this BDD.
  The key here is that the node being visited is NOT put in its proper
  place by this instance, but rather is switched when its proper position
  is reached in the recursion tree.<p>
  The DdNode * that is returned is the same BDD as passed in as node,
  but in the new order.]

  SideEffects [None]

  SeeAlso     [Cudd_bddPermute cuddAddPermuteRecur]

******************************************************************************/
static DdNode *
cuddBddPermuteRecur(
  DdManager * manager /* DD manager */,
  DdHashTable * table /* computed table */,
  DdNode * node /* BDD to be reordered */,
  int * permut /* permutation array */)
{
    DdNode      *N,*T,*E;
    DdNode      *res;
    int         index;

    statLine(manager);
    N = Cudd_Regular(node);

    /* Check for terminal case of constant node. */
    if (cuddIsConstant(N)) {
        return(node);
    }

    /* If problem already solved, look up answer and return. */
    if (N->ref != 1 && (res = cuddHashTableLookup1(table,N)) != NULL) {
#ifdef DD_DEBUG
        bddPermuteRecurHits++;
#endif
        return(Cudd_NotCond(res,N != node));
    }

    /* Split and recur on children of this node. */
    T = cuddBddPermuteRecur(manager,table,cuddT(N),permut);
    if (T == NULL) return(NULL);
    cuddRef(T);
    E = cuddBddPermuteRecur(manager,table,cuddE(N),permut);
    if (E == NULL) {
        Cudd_IterDerefBdd(manager, T);
        return(NULL);
    }
    cuddRef(E);

    /* Move variable that should be in this position to this position
    ** by retrieving the single var BDD for that variable, and calling
    ** cuddBddIteRecur with the T and E we just created.
    */
    index = permut[N->index];
    res = cuddBddIteRecur(manager,manager->vars[index],T,E);
    if (res == NULL) {
        Cudd_IterDerefBdd(manager, T);
        Cudd_IterDerefBdd(manager, E);
        return(NULL);
    }
    cuddRef(res);
    Cudd_IterDerefBdd(manager, T);
    Cudd_IterDerefBdd(manager, E);

    /* Do not keep the result if the reference count is only 1, since
    ** it will not be visited again.
    */
    if (N->ref != 1) {
        ptrint fanout = (ptrint) N->ref;
        cuddSatDec(fanout);
        if (!cuddHashTableInsert1(table,N,res,fanout)) {
            Cudd_IterDerefBdd(manager, res);
            return(NULL);
        }
    }
    cuddDeref(res);
    return(Cudd_NotCond(res,N != node));

} /* end of cuddBddPermuteRecur */


/**Function********************************************************************

  Synopsis    [Implements the recursive step of Cudd_bddVarMap.]

  Description [Implements the recursive step of Cudd_bddVarMap.
  Returns a pointer to the result if successful; NULL otherwise.]

  SideEffects [None]

  SeeAlso     [Cudd_bddVarMap]

******************************************************************************/
static DdNode *
cuddBddVarMapRecur(
  DdManager *manager /* DD manager */,
  DdNode *f /* BDD to be remapped */)
{
    DdNode      *F, *T, *E;
    DdNode      *res;
    int         index;

    statLine(manager);
    F = Cudd_Regular(f);

    /* Check for terminal case of constant node. */
    if (cuddIsConstant(F)) {
        return(f);
    }

    /* If problem already solved, look up answer and return. */
    if (F->ref != 1 &&
        (res = cuddCacheLookup1(manager,Cudd_bddVarMap,F)) != NULL) {
        return(Cudd_NotCond(res,F != f));
    }

    if ( manager->TimeStop && Abc_Clock() > manager->TimeStop )
        return NULL;

    /* Split and recur on children of this node. */
    T = cuddBddVarMapRecur(manager,cuddT(F));
    if (T == NULL) return(NULL);
    cuddRef(T);
    E = cuddBddVarMapRecur(manager,cuddE(F));
    if (E == NULL) {
        Cudd_IterDerefBdd(manager, T);
        return(NULL);
    }
    cuddRef(E);

    /* Move variable that should be in this position to this position
    ** by retrieving the single var BDD for that variable, and calling
    ** cuddBddIteRecur with the T and E we just created.
    */
    index = manager->map[F->index];
    res = cuddBddIteRecur(manager,manager->vars[index],T,E);
    if (res == NULL) {
        Cudd_IterDerefBdd(manager, T);
        Cudd_IterDerefBdd(manager, E);
        return(NULL);
    }
    cuddRef(res);
    Cudd_IterDerefBdd(manager, T);
    Cudd_IterDerefBdd(manager, E);

    /* Do not keep the result if the reference count is only 1, since
    ** it will not be visited again.
    */
    if (F->ref != 1) {
        cuddCacheInsert1(manager,Cudd_bddVarMap,F,res);
    }
    cuddDeref(res);
    return(Cudd_NotCond(res,F != f));

} /* end of cuddBddVarMapRecur */


/**Function********************************************************************

  Synopsis    [Performs the recursive step of Cudd_addVectorCompose.]

  Description []

  SideEffects [None]

  SeeAlso     []

******************************************************************************/
static DdNode *
cuddAddVectorComposeRecur(
  DdManager * dd /* DD manager */,
  DdHashTable * table /* computed table */,
  DdNode * f /* ADD in which to compose */,
  DdNode ** vector /* functions to substitute */,
  int  deepest /* depth of deepest substitution */)
{
    DdNode      *T,*E;
    DdNode      *res;

    statLine(dd);
    /* If we are past the deepest substitution, return f. */
    if (cuddI(dd,f->index) > deepest) {
        return(f);
    }

    if ((res = cuddHashTableLookup1(table,f)) != NULL) {
#ifdef DD_DEBUG
        addVectorComposeHits++;
#endif
        return(res);
    }

    /* Split and recur on children of this node. */
    T = cuddAddVectorComposeRecur(dd,table,cuddT(f),vector,deepest);
    if (T == NULL)  return(NULL);
    cuddRef(T);
    E = cuddAddVectorComposeRecur(dd,table,cuddE(f),vector,deepest);
    if (E == NULL) {
        Cudd_RecursiveDeref(dd, T);
        return(NULL);
    }
    cuddRef(E);

    /* Retrieve the 0-1 ADD for the current top variable and call
    ** cuddAddIteRecur with the T and E we just created.
    */
    res = cuddAddIteRecur(dd,vector[f->index],T,E);
    if (res == NULL) {
        Cudd_RecursiveDeref(dd, T);
        Cudd_RecursiveDeref(dd, E);
        return(NULL);
    }
    cuddRef(res);
    Cudd_RecursiveDeref(dd, T);
    Cudd_RecursiveDeref(dd, E);

    /* Do not keep the result if the reference count is only 1, since
    ** it will not be visited again
    */
    if (f->ref != 1) {
        ptrint fanout = (ptrint) f->ref;
        cuddSatDec(fanout);
        if (!cuddHashTableInsert1(table,f,res,fanout)) {
            Cudd_RecursiveDeref(dd, res);
            return(NULL);
        }
    }
    cuddDeref(res);
    return(res);

} /* end of cuddAddVectorComposeRecur */


/**Function********************************************************************

  Synopsis    [Performs the recursive step of Cudd_addGeneralVectorCompose.]

  Description []

  SideEffects [None]

  SeeAlso     []

******************************************************************************/
static DdNode *
cuddAddGeneralVectorComposeRecur(
  DdManager * dd /* DD manager */,
  DdHashTable * table /* computed table */,
  DdNode * f /* ADD in which to compose */,
  DdNode ** vectorOn /* functions to substitute for x_i */,
  DdNode ** vectorOff /* functions to substitute for x_i' */,
  int  deepest /* depth of deepest substitution */)
{
    DdNode      *T,*E,*t,*e;
    DdNode      *res;

    /* If we are past the deepest substitution, return f. */
    if (cuddI(dd,f->index) > deepest) {
        return(f);
    }

    if ((res = cuddHashTableLookup1(table,f)) != NULL) {
#ifdef DD_DEBUG
        addGeneralVectorComposeHits++;
#endif
        return(res);
    }

    /* Split and recur on children of this node. */
    T = cuddAddGeneralVectorComposeRecur(dd,table,cuddT(f),
                                         vectorOn,vectorOff,deepest);
    if (T == NULL)  return(NULL);
    cuddRef(T);
    E = cuddAddGeneralVectorComposeRecur(dd,table,cuddE(f),
                                         vectorOn,vectorOff,deepest);
    if (E == NULL) {
        Cudd_RecursiveDeref(dd, T);
        return(NULL);
    }
    cuddRef(E);

    /* Retrieve the compose ADDs for the current top variable and call
    ** cuddAddApplyRecur with the T and E we just created.
    */
    t = cuddAddApplyRecur(dd,Cudd_addTimes,vectorOn[f->index],T);
    if (t == NULL) {
      Cudd_RecursiveDeref(dd,T);
      Cudd_RecursiveDeref(dd,E);
      return(NULL);
    }
    cuddRef(t);
    e = cuddAddApplyRecur(dd,Cudd_addTimes,vectorOff[f->index],E);
    if (e == NULL) {
      Cudd_RecursiveDeref(dd,T);
      Cudd_RecursiveDeref(dd,E);
      Cudd_RecursiveDeref(dd,t);
      return(NULL);
    }
    cuddRef(e);
    res = cuddAddApplyRecur(dd,Cudd_addPlus,t,e);
    if (res == NULL) {
      Cudd_RecursiveDeref(dd,T);
      Cudd_RecursiveDeref(dd,E);
      Cudd_RecursiveDeref(dd,t);
      Cudd_RecursiveDeref(dd,e);
      return(NULL);
    }
    cuddRef(res);
    Cudd_RecursiveDeref(dd,T);
    Cudd_RecursiveDeref(dd,E);
    Cudd_RecursiveDeref(dd,t);
    Cudd_RecursiveDeref(dd,e);

    /* Do not keep the result if the reference count is only 1, since
    ** it will not be visited again
    */
    if (f->ref != 1) {
        ptrint fanout = (ptrint) f->ref;
        cuddSatDec(fanout);
        if (!cuddHashTableInsert1(table,f,res,fanout)) {
            Cudd_RecursiveDeref(dd, res);
            return(NULL);
        }
    }
    cuddDeref(res);
    return(res);

} /* end of cuddAddGeneralVectorComposeRecur */


/**Function********************************************************************

  Synopsis    [Performs the recursive step of Cudd_addNonSimCompose.]

  Description []

  SideEffects [None]

  SeeAlso     []

******************************************************************************/
static DdNode *
cuddAddNonSimComposeRecur(
  DdManager * dd,
  DdNode * f,
  DdNode ** vector,
  DdNode * key,
  DdNode * cube,
  int  lastsub)
{
    DdNode *f1, *f0, *key1, *key0, *cube1, *var;
    DdNode *T,*E;
    DdNode *r;
    unsigned int top, topf, topk, topc;
    unsigned int index;
    int i;
    DdNode **vect1;
    DdNode **vect0;

    statLine(dd);
    /* If we are past the deepest substitution, return f. */
    if (cube == DD_ONE(dd) || cuddIsConstant(f)) {
        return(f);
    }

    /* If problem already solved, look up answer and return. */
    r = cuddCacheLookup(dd,DD_ADD_NON_SIM_COMPOSE_TAG,f,key,cube);
    if (r != NULL) {
        return(r);
    }

    /* Find top variable. we just need to look at f, key, and cube,
    ** because all the varibles in the gi are in key.
    */
    topf = cuddI(dd,f->index);
    topk = cuddI(dd,key->index);
    top = ddMin(topf,topk);
    topc = cuddI(dd,cube->index);
    top = ddMin(top,topc);
    index = dd->invperm[top];

    /* Compute the cofactors. */
    if (topf == top) {
        f1 = cuddT(f);
        f0 = cuddE(f);
    } else {
        f1 = f0 = f;
    }
    if (topc == top) {
        cube1 = cuddT(cube);
        /* We want to eliminate vector[index] from key. Otherwise
        ** cache performance is severely affected. Hence we
        ** existentially quantify the variable with index "index" from key.
        */
        var = Cudd_addIthVar(dd, (int) index);
        if (var == NULL) {
            return(NULL);
        }
        cuddRef(var);
        key1 = cuddAddExistAbstractRecur(dd, key, var);
        if (key1 == NULL) {
            Cudd_RecursiveDeref(dd,var);
            return(NULL);
        }
        cuddRef(key1);
        Cudd_RecursiveDeref(dd,var);
        key0 = key1;
    } else {
        cube1 = cube;
        if (topk == top) {
            key1 = cuddT(key);
            key0 = cuddE(key);
        } else {
            key1 = key0 = key;
        }
        cuddRef(key1);
    }

    /* Allocate two new vectors for the cofactors of vector. */
    vect1 = ABC_ALLOC(DdNode *,lastsub);
    if (vect1 == NULL) {
        dd->errorCode = CUDD_MEMORY_OUT;
        Cudd_RecursiveDeref(dd,key1);
        return(NULL);
    }
    vect0 = ABC_ALLOC(DdNode *,lastsub);
    if (vect0 == NULL) {
        dd->errorCode = CUDD_MEMORY_OUT;
        Cudd_RecursiveDeref(dd,key1);
        ABC_FREE(vect1);
        return(NULL);
    }

    /* Cofactor the gi. Eliminate vect1[index] and vect0[index], because
    ** we do not need them.
    */
    for (i = 0; i < lastsub; i++) {
        DdNode *gi = vector[i];
        if (gi == NULL) {
            vect1[i] = vect0[i] = NULL;
        } else if (gi->index == index) {
            vect1[i] = cuddT(gi);
            vect0[i] = cuddE(gi);
        } else {
            vect1[i] = vect0[i] = gi;
        }
    }
    vect1[index] = vect0[index] = NULL;

    /* Recur on children. */
    T = cuddAddNonSimComposeRecur(dd,f1,vect1,key1,cube1,lastsub);
    ABC_FREE(vect1);
    if (T == NULL) {
        Cudd_RecursiveDeref(dd,key1);
        ABC_FREE(vect0);
        return(NULL);
    }
    cuddRef(T);
    E = cuddAddNonSimComposeRecur(dd,f0,vect0,key0,cube1,lastsub);
    ABC_FREE(vect0);
    if (E == NULL) {
        Cudd_RecursiveDeref(dd,key1);
        Cudd_RecursiveDeref(dd,T);
        return(NULL);
    }
    cuddRef(E);
    Cudd_RecursiveDeref(dd,key1);

    /* Retrieve the 0-1 ADD for the current top variable from vector,
    ** and call cuddAddIteRecur with the T and E we just created.
    */
    r = cuddAddIteRecur(dd,vector[index],T,E);
    if (r == NULL) {
        Cudd_RecursiveDeref(dd,T);
        Cudd_RecursiveDeref(dd,E);
        return(NULL);
    }
    cuddRef(r);
    Cudd_RecursiveDeref(dd,T);
    Cudd_RecursiveDeref(dd,E);
    cuddDeref(r);

    /* Store answer to trim recursion. */
    cuddCacheInsert(dd,DD_ADD_NON_SIM_COMPOSE_TAG,f,key,cube,r);

    return(r);

} /* end of cuddAddNonSimComposeRecur */


/**Function********************************************************************

  Synopsis    [Performs the recursive step of Cudd_bddVectorCompose.]

  Description []

  SideEffects [None]

  SeeAlso     []

******************************************************************************/
static DdNode *
cuddBddVectorComposeRecur(
  DdManager * dd /* DD manager */,
  DdHashTable * table /* computed table */,
  DdNode * f /* BDD in which to compose */,
  DdNode ** vector /* functions to be composed */,
  int deepest /* depth of the deepest substitution */)
{
    DdNode      *F,*T,*E;
    DdNode      *res;

    statLine(dd);
    F = Cudd_Regular(f);

    /* If we are past the deepest substitution, return f. */
    if (cuddI(dd,F->index) > deepest) {
        return(f);
    }

    /* If problem already solved, look up answer and return. */
    if ((res = cuddHashTableLookup1(table,F)) != NULL) {
#ifdef DD_DEBUG
        bddVectorComposeHits++;
#endif
        return(Cudd_NotCond(res,F != f));
    }

    /* Split and recur on children of this node. */
    T = cuddBddVectorComposeRecur(dd,table,cuddT(F),vector, deepest);
    if (T == NULL) return(NULL);
    cuddRef(T);
    E = cuddBddVectorComposeRecur(dd,table,cuddE(F),vector, deepest);
    if (E == NULL) {
        Cudd_IterDerefBdd(dd, T);
        return(NULL);
    }
    cuddRef(E);

    /* Call cuddBddIteRecur with the BDD that replaces the current top
    ** variable and the T and E we just created.
    */
    res = cuddBddIteRecur(dd,vector[F->index],T,E);
    if (res == NULL) {
        Cudd_IterDerefBdd(dd, T);
        Cudd_IterDerefBdd(dd, E);
        return(NULL);
    }
    cuddRef(res);
    Cudd_IterDerefBdd(dd, T);
    Cudd_IterDerefBdd(dd, E);   

    /* Do not keep the result if the reference count is only 1, since
    ** it will not be visited again.
    */
    if (F->ref != 1) {
        ptrint fanout = (ptrint) F->ref;
        cuddSatDec(fanout);
        if (!cuddHashTableInsert1(table,F,res,fanout)) {
            Cudd_IterDerefBdd(dd, res);
            return(NULL);
        }
    }
    cuddDeref(res);
    return(Cudd_NotCond(res,F != f));

} /* end of cuddBddVectorComposeRecur */


/**Function********************************************************************

  Synopsis    [Comparison of a function to the i-th ADD variable.]

  Description [Comparison of a function to the i-th ADD variable. Returns 1 if
  the function is the i-th ADD variable; 0 otherwise.]

  SideEffects [None]

  SeeAlso     []

******************************************************************************/
DD_INLINE
static int
ddIsIthAddVar(
  DdManager * dd,
  DdNode * f,
  unsigned int  i)
{
    return(f->index == i && cuddT(f) == DD_ONE(dd) && cuddE(f) == DD_ZERO(dd));

} /* end of ddIsIthAddVar */


/**Function********************************************************************

  Synopsis    [Comparison of a pair of functions to the i-th ADD variable.]

  Description [Comparison of a pair of functions to the i-th ADD
  variable. Returns 1 if the functions are the i-th ADD variable and its
  complement; 0 otherwise.]

  SideEffects [None]

  SeeAlso     []

******************************************************************************/
DD_INLINE
static int
ddIsIthAddVarPair(
  DdManager * dd,
  DdNode * f,
  DdNode * g,
  unsigned int  i)
{
    return(f->index == i && g->index == i && 
           cuddT(f) == DD_ONE(dd) && cuddE(f) == DD_ZERO(dd) &&
           cuddT(g) == DD_ZERO(dd) && cuddE(g) == DD_ONE(dd));

} /* end of ddIsIthAddVarPair */


ABC_NAMESPACE_IMPL_END

