Beispiel #1
0
/**
 * @brief Basic ADD test.
 * @return 0 if successful; -1 otherwise.
 */
static int
testAdd(int verbosity)
{
    DdManager *manager;
    DdNode *f, *var, *tmp, *bg;
    int i, ret;
    CUDD_VALUE_TYPE pinf;

    manager = Cudd_Init(0, 0, CUDD_UNIQUE_SLOTS, CUDD_CACHE_SLOTS, 0);
    if (!manager) {
        if (verbosity) {
            printf("initialization failed\n");
        }
        return -1;
    }
    pinf = Cudd_V(Cudd_ReadPlusInfinity(manager));
    if (verbosity) {
        printf("Plus infinity is %g\n", pinf);
    }
    f = Cudd_addConst(manager,5);
    Cudd_Ref(f);
    for (i = 3; i >= 0; i--) {
        var = Cudd_addIthVar(manager,i);
        Cudd_Ref(var);
        tmp = Cudd_addApply(manager,Cudd_addTimes,var,f);
        Cudd_Ref(tmp);
        Cudd_RecursiveDeref(manager,f);
        Cudd_RecursiveDeref(manager,var);
        f = tmp;
    }
    if (verbosity) {
        Cudd_PrintMinterm(manager, f);
        printf("\n");
    }
    Cudd_RecursiveDeref(manager, f);
    bg = Cudd_ReadBackground(manager);
    if (verbosity) {
        printf("background (%g) minterms : ", Cudd_V(bg));
        Cudd_ApaPrintMinterm(Cudd_ReadStdout(manager), manager, bg, 0);
    }
    ret = Cudd_CheckZeroRef(manager);
    if (ret != 0 && verbosity) {
        printf("%d non-zero ADD reference counts after dereferencing\n", ret);
    }
    Cudd_Quit(manager);
    return ret != 0;
}
Beispiel #2
0
/**Function********************************************************************

  Synopsis    [Computes shortest paths in a state graph.]

  Description [Computes shortest paths in the state transition graph of
  a network.  Three methods are availabe:
  <ul>
  <li> Bellman-Ford algorithm for single-source shortest paths; the
  algorithm computes the distance (number of transitions) from the initial
  states to all states.
  <li> Floyd-Warshall algorithm for all-pair shortest paths.
  <li> Repeated squaring algorithm for all-pair shortest paths.
  </ul>
  The function returns 1 in case of success; 0 otherwise.
  ]

  SideEffects [ADD variables are created in the manager.]

  SeeAlso     []

******************************************************************************/
int
Ntr_ShortestPaths(
  DdManager * dd,
  BnetNetwork * net,
  NtrOptions * option)
{
    NtrPartTR *TR;
    DdNode *edges, *source, *res, *r, *q, *bddSource;
    DdNode **xadd, **yadd, **zadd;
    int i;
    int pr = option->verb;
    int algorithm = option->shortPath;
    int selectiveTrace = option->selectiveTrace;
    int nvars = net->nlatches;

    /* Set background to infinity for shortest paths. */
    Cudd_SetBackground(dd,Cudd_ReadPlusInfinity(dd));

    /* Build the monolithic TR. */
    TR = Ntr_buildTR(dd,net,option,NTR_IMAGE_MONO);

    /* Build the ADD variable vectors for x and y. */
    xadd = ALLOC(DdNode *, nvars);
    yadd = ALLOC(DdNode *, nvars);
    for(i = 0; i < nvars; i++) {
	q = Cudd_addIthVar(dd,TR->x[i]->index);
	Cudd_Ref(q);
	xadd[i] = q;
	q = Cudd_addIthVar(dd,TR->y[i]->index);
	Cudd_Ref(q);
	yadd[i] = q;
    }

    /* Convert the transition relation BDD into an ADD... */
    q = Cudd_BddToAdd(dd,TR->part[0]);
    Cudd_Ref(q);
    /* ...replacing zeroes with infinities... */
    r = Cudd_addIte(dd,q,Cudd_ReadOne(dd),Cudd_ReadPlusInfinity(dd));
    Cudd_Ref(r);
    Cudd_RecursiveDeref(dd,q);
    /* ...and zeroing the diagonal. */
    q = Cudd_addXeqy(dd,nvars,xadd,yadd);
    Cudd_Ref(q);
    edges = Cudd_addIte(dd,q,Cudd_ReadZero(dd),r);
    Cudd_Ref(edges);
    Cudd_RecursiveDeref(dd,r);
    Cudd_RecursiveDeref(dd,q);

    switch(algorithm) {
    case NTR_SHORT_BELLMAN:
	bddSource = Ntr_initState(dd,net,option);
	source = Cudd_BddToAdd(dd,bddSource);
	Cudd_Ref(source);
	res = ntrBellman(dd,edges,source,xadd,yadd,nvars,pr);
	if (res == NULL) return(0);
	Cudd_Ref(res);
	Cudd_RecursiveDeref(dd,source);
	Cudd_RecursiveDeref(dd,bddSource);
	if (pr >= 0) {
	    (void) fprintf(stdout,"Distance Matrix");
	    Cudd_PrintDebug(dd,res,nvars,pr);
	}
	break;
    case NTR_SHORT_FLOYD:
	res = ntrWarshall(dd,edges,xadd,yadd,nvars,pr);
	if (res == NULL) return(0);
	Cudd_Ref(res);
	if (pr >= 0) {
	    (void) fprintf(stdout,"Distance Matrix");
	    Cudd_PrintDebug(dd,res,2*nvars,pr);
	}
	break;
    case NTR_SHORT_SQUARE:
	/* Create a third set of ADD variables. */
	zadd = ALLOC(DdNode *, nvars);
	for(i = 0; i < nvars; i++) {
	    int level;
	    level = Cudd_ReadIndex(dd,TR->x[i]->index);
	    q = Cudd_addNewVarAtLevel(dd,level);
	    Cudd_Ref(q);
	    zadd[i] = q;
	}
	/* Compute the shortest paths. */
	res = ntrSquare(dd,edges,zadd,yadd,xadd,nvars,pr,selectiveTrace);
	if (res == NULL) return(0);
	Cudd_Ref(res);
	/* Dispose of the extra variables. */
	for(i = 0; i < nvars; i++) {
	    Cudd_RecursiveDeref(dd,zadd[i]);
	}
	FREE(zadd);
	if (pr >= 0) {
	    (void) fprintf(stdout,"Distance Matrix");
	    Cudd_PrintDebug(dd,res,2*nvars,pr);
	}
	break;
    default:
	(void) printf("Unrecognized method. Try again.\n");
	return(0);
    }

    /* Here we should compute the paths. */

    /* Clean up. */
    Ntr_freeTR(dd,TR);
    Cudd_RecursiveDeref(dd,edges);
    Cudd_RecursiveDeref(dd,res);
    for(i = 0; i < nvars; i++) {
	Cudd_RecursiveDeref(dd,xadd[i]);
	Cudd_RecursiveDeref(dd,yadd[i]);
    }
    FREE(xadd);
    FREE(yadd);

    if (option->autoDyn & 1) {
	(void) printf("Order after short path computation\n");
	if (!Bnet_PrintOrder(net,dd)) return(0);
    }

    return(1);

} /* end of Ntr_ShortestPaths */
Beispiel #3
0
/**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 */
Beispiel #4
0
/**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 = ALLOC(DdNode *,lastsub);
    if (vect1 == NULL) {
	dd->errorCode = CUDD_MEMORY_OUT;
	Cudd_RecursiveDeref(dd,key1);
	return(NULL);
    }
    vect0 = ALLOC(DdNode *,lastsub);
    if (vect0 == NULL) {
	dd->errorCode = CUDD_MEMORY_OUT;
	Cudd_RecursiveDeref(dd,key1);
	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);
    FREE(vect1);
    if (T == NULL) {
	Cudd_RecursiveDeref(dd,key1);
	FREE(vect0);
	return(NULL);
    }
    cuddRef(T);
    E = cuddAddNonSimComposeRecur(dd,f0,vect0,key0,cube1,lastsub);
    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 */