コード例 #1
0
ファイル: bddem.c プロジェクト: gokhansolak/yap-6.3
static YAP_Bool ret_prob(void) {
  YAP_Term arg1, arg2, out;
  DdNode *node;

  arg1 = YAP_ARG1;
  arg2 = YAP_ARG2;
  node = (DdNode *)YAP_IntOfTerm(arg1);

  if (!Cudd_IsConstant(node)) {
    table = init_table(boolVars_ex[ex]);
    out = YAP_MkFloatTerm(Prob(node, 0));
    destroy_table(table, boolVars_ex[ex]);
  } else {
    if (node == Cudd_ReadOne(mgr_ex[ex]))
      out = YAP_MkFloatTerm(1.0);
    else
      out = YAP_MkFloatTerm(0.0);
  }

  return (YAP_Unify(out, arg2));
}
コード例 #2
0
ファイル: BddBuilder.cpp プロジェクト: HosukChoi/ECO
BddBuilder::BddBuilder(){
	__pddWireHead = __pddWireTail = NULL;
	__pddOutputWireHead = __pddOutputWireTail = NULL;
	__pddOutputNodes = NULL;
	__pddGateHead = __pddGateTail = NULL;
	__pddInputNodes = NULL;

	__pddManager = Cudd_Init(0, 0,CUDD_UNIQUE_SLOTS,CUDD_CACHE_SLOTS , 0);
	Cudd_ReduceHeap(__pddManager,CUDD_REORDER_RANDOM_PIVOT,0);
	Cudd_AutodynEnable(__pddManager,CUDD_REORDER_RANDOM_PIVOT);
	__Vcc = Cudd_ReadOne(__pddManager);
	__GND = Cudd_ReadLogicZero(__pddManager);
	
	char * name_vcc = new char[4];
	char * name_gnd = new char[4];

	sprintf(name_vcc, "Vcc");
	sprintf(name_gnd, "GND");

	__VccWire = new DdWire(__pddManager, name_vcc, 0, 0);
	__GNDWire = new DdWire(__pddManager, name_gnd, 0, 0);
	__VccWire->setDdNode(__Vcc);
	__GNDWire->setDdNode(__GND);

	Cudd_Ref(__Vcc);
	Cudd_Ref(__GND);

	if(__pddManager == NULL){
		perror("DdManager initializing error.");
	}

	//__inputWireCnt = 2; // Vcc & GND
	__inputWireCnt = -1;
	__outputWireCnt = -1;

	__pddInputWireHead = __VccWire;
	__VccWire->setInputListNext(__GNDWire);
	__pddInputWireTail = __GNDWire;
}
コード例 #3
0
ファイル: bdd.c プロジェクト: dkudrow/cs267
/* encode the program counter in an array of boolean variables */
DdNode* bdd_encode_pc(DdManager* m, DdNode* node, int** pc_array, int pc_size,
                      int proc, int pc) {
    int i;
    DdNode* tmp, *var;
    DdNode* ret = Cudd_ReadOne(m);
    Cudd_Ref(ret);
    for (i=0; i<pc_size; i++) {          /* iterate for each bit in pc_size */
        var = Cudd_bddIthVar(m, pc_array[proc][i]);
        if (pc % 2)                        /* encode true bit */
            tmp = Cudd_bddAnd(m, var, ret);
        else                               /* encode false bit */
            tmp = Cudd_bddAnd(m, Cudd_Not(var), ret);
        Cudd_Ref(tmp);
        Cudd_RecursiveDeref(m, ret);       /* release the old bdd each time a new */
        ret = tmp;                         /* one is made */
        pc /= 2;
    }
    tmp = Cudd_bddAnd(m, ret, node);     /* add encoding to existing edge */
    Cudd_Ref(tmp);
    Cudd_RecursiveDeref(m, ret);
    Cudd_RecursiveDeref(m, node);
    return tmp;                          /* return updated edge */
}
コード例 #4
0
/**Function*************************************************************

  Synopsis    [Transforms the AIG into nodes.]

  Description [Threhold is the max number of nodes duplicated at a node.]
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
void Abc_NtkMultiInt( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkNew )
{
    ProgressBar * pProgress;
    Abc_Obj_t * pNode, * pConst1, * pNodeNew;
    int i;

    // set the constant node
    pConst1 = Abc_AigConst1(pNtk);
    if ( Abc_ObjFanoutNum(pConst1) > 0 )
    {
        pNodeNew = Abc_NtkCreateNode( pNtkNew );  
        pNodeNew->pData = Cudd_ReadOne( pNtkNew->pManFunc );   Cudd_Ref( pNodeNew->pData );
        pConst1->pCopy = pNodeNew;
    }

    // perform renoding for POs
    pProgress = Extra_ProgressBarStart( stdout, Abc_NtkCoNum(pNtk) );
    Abc_NtkForEachCo( pNtk, pNode, i )
    {
        Extra_ProgressBarUpdate( pProgress, i, NULL );
        if ( Abc_ObjIsCi(Abc_ObjFanin0(pNode)) )
            continue;
        Abc_NtkMulti_rec( pNtkNew, Abc_ObjFanin0(pNode) );
    }
コード例 #5
0
ファイル: bdd.c プロジェクト: dkudrow/cs267
DdNode* compute_EX(DdManager* m, pos* postab, DdNode* R, DdNode* p) {
    DdNode* tmp;
    /* rename variables */
    int perm[2*(postab->num_procs*postab->pc_size+postab->num_vars)];
    int i, j, k;
    for (i=0; i<postab->num_vars; i++) {
        perm[i] = i+postab->num_vars;
        perm[i+postab->num_vars] = i;
    }
    for (j=0; j<postab->num_procs; j++) {
        for (k=0; k<postab->pc_size; k++) {
            perm[postab->num_vars+i] = postab->pc_[j][k];
            perm[postab->num_vars+postab->num_procs*postab->pc_size+i++] = postab->pc[j][k];
        }
    }
    p = Cudd_bddPermute(m, p, perm);
    /* construct cube of next state variables */
    DdNode* cube = Cudd_ReadOne(m);
    for (i=0; i<postab->num_vars; i++) {
        tmp = Cudd_bddAnd(m, cube, Cudd_bddIthVar(m, postab->num_vars+i));
        Cudd_Ref(tmp);
        Cudd_RecursiveDeref(m, cube);
        cube = tmp;
    }
    for (i=0; i<postab->num_procs*postab->pc_size; i++) {
        tmp = Cudd_bddAnd(m, cube, Cudd_bddIthVar(m, 2*postab->num_vars+postab->num_procs*postab->pc_size+i));
        Cudd_Ref(tmp);
        Cudd_RecursiveDeref(m, cube);
        cube = tmp;
    }
    DdNode* EX_p = Cudd_bddAndAbstract(m, R, p, cube);
    Cudd_Ref(EX_p);
    Cudd_RecursiveDeref(m, p);
    Cudd_RecursiveDeref(m, cube);
    return EX_p;
}
コード例 #6
0
/**Function*************************************************************

  Synopsis    []

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
void Abc_MvRead( Mv_Man_t * p )
{
    FILE * pFile;
    char Buffer[1000], * pLine;
    DdNode * bCube, * bTemp, * bProd, * bVar0, * bVar1, * bCubeSum;
    int i, v;

    // start the cube
    bCubeSum = Cudd_ReadLogicZero(p->dd);  Cudd_Ref( bCubeSum );

    // start the values
    for ( i = 0; i < 15; i++ )
    for ( v = 0; v < 4; v++ )
    {
        p->bValues[i][v]   = Cudd_ReadLogicZero(p->dd);  Cudd_Ref( p->bValues[i][v] );
        p->bValueDcs[i][v] = Cudd_ReadLogicZero(p->dd);  Cudd_Ref( p->bValueDcs[i][v] );
    }

    // read the file
    pFile = fopen( "input.pla", "r" );
    while ( fgets( Buffer, 1000, pFile ) )
    {
        if ( Buffer[0] == '#' )
            continue;
        if ( Buffer[0] == '.' )
        {
            if ( Buffer[1] == 'e' )
                break;
            continue;
        }

        // get the cube 
        bCube = Abc_MvReadCube( p->dd, Buffer, 18 );  Cudd_Ref( bCube );

        // add it to the values of the output functions
        pLine = Buffer + 19;
        for ( i = 0; i < 15; i++ )
        {
            if ( pLine[2*i] == '-' && pLine[2*i+1] == '-' )
            {
                for ( v = 0; v < 4; v++ )
                {
                    p->bValueDcs[i][v] = Cudd_bddOr( p->dd, bTemp = p->bValueDcs[i][v], bCube );  Cudd_Ref( p->bValueDcs[i][v] );
                    Cudd_RecursiveDeref( p->dd, bTemp );
                }
                continue;
            }
            else if ( pLine[2*i] == '0' && pLine[2*i+1] == '0' ) // 0
                v = 0;
            else if ( pLine[2*i] == '1' && pLine[2*i+1] == '0' ) // 1
                v = 1;
            else if ( pLine[2*i] == '0' && pLine[2*i+1] == '1' ) // 2
                v = 2;
            else if ( pLine[2*i] == '1' && pLine[2*i+1] == '1' ) // 3
                v = 3;
            else assert( 0 );
            // add the value
            p->bValues[i][v] = Cudd_bddOr( p->dd, bTemp = p->bValues[i][v], bCube );  Cudd_Ref( p->bValues[i][v] );
            Cudd_RecursiveDeref( p->dd, bTemp );
        }

        // add the cube
        bCubeSum = Cudd_bddOr( p->dd, bTemp = bCubeSum, bCube );  Cudd_Ref( bCubeSum );
        Cudd_RecursiveDeref( p->dd, bTemp );
        Cudd_RecursiveDeref( p->dd, bCube );
    }

    // add the complement of the domain to all values
    for ( i = 0; i < 15; i++ )
        for ( v = 0; v < 4; v++ )
        {
            if ( p->bValues[i][v] == Cudd_Not(Cudd_ReadOne(p->dd)) )
                continue;
            p->bValues[i][v] = Cudd_bddOr( p->dd, bTemp = p->bValues[i][v], p->bValueDcs[i][v] );  Cudd_Ref( p->bValues[i][v] );
            Cudd_RecursiveDeref( p->dd, bTemp );
            p->bValues[i][v] = Cudd_bddOr( p->dd, bTemp = p->bValues[i][v], Cudd_Not(bCubeSum) );  Cudd_Ref( p->bValues[i][v] );
            Cudd_RecursiveDeref( p->dd, bTemp );
        }
    printf( "Domain = %5.2f %%.\n", 100.0*Cudd_CountMinterm(p->dd, bCubeSum, 32)/Cudd_CountMinterm(p->dd, Cudd_ReadOne(p->dd), 32) ); 
    Cudd_RecursiveDeref( p->dd, bCubeSum );

    // create each output function
    for ( i = 0; i < 15; i++ )
    {
        p->bFuncs[i] = Cudd_ReadLogicZero(p->dd);  Cudd_Ref( p->bFuncs[i] );
        for ( v = 0; v < 4; v++ )
        {
            bVar0 = Cudd_NotCond( Cudd_bddIthVar(p->dd, 30), ((v & 1) == 0) );
            bVar1 = Cudd_NotCond( Cudd_bddIthVar(p->dd, 31), ((v & 2) == 0) );
            bCube = Cudd_bddAnd( p->dd, bVar0, bVar1 );             Cudd_Ref( bCube );
            bProd = Cudd_bddAnd( p->dd, p->bValues[i][v], bCube );  Cudd_Ref( bProd );
            Cudd_RecursiveDeref( p->dd, bCube );
            // add the value
            p->bFuncs[i] = Cudd_bddOr( p->dd, bTemp = p->bFuncs[i], bProd );  Cudd_Ref( p->bFuncs[i] );
            Cudd_RecursiveDeref( p->dd, bTemp );
            Cudd_RecursiveDeref( p->dd, bProd );
        }
    }
}
コード例 #7
0
ファイル: ntrShort.c プロジェクト: Oliii/MTBDD
/**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 */
コード例 #8
0
ファイル: solve.c プロジェクト: tulip-control/gr1c
anode_t *synthesize( DdManager *manager,  unsigned char init_flags,
                     unsigned char verbose )
{
    anode_t *strategy = NULL;
    anode_t *this_node_stack = NULL;
    anode_t *node, *new_node;
    bool initial;
    vartype *state;
    vartype **env_moves;
    int emoves_len;

    ptree_t *var_separator;
    DdNode *W;
    DdNode *strans_into_W;

    DdNode *einit, *sinit, *etrans, *strans, **egoals, **sgoals;

    DdNode *ddval;  /* Store result of evaluating a BDD */
    DdNode ***Y = NULL;
    DdNode *Y_i_primed;
    int *num_sublevels;
    DdNode ****X_ijr = NULL;

    DdNode *tmp, *tmp2;
    int i, j, r, k;  /* Generic counters */
    int offset;
    bool env_nogoal_flag = False;  /* Indicate environment has no goals */
    int loop_mode;
    int next_mode;

    int num_env, num_sys;
    int *cube;  /* length will be twice total number of variables (to
                   account for both variables and their primes). */

    /* Variables used during CUDD generation (state enumeration). */
    DdGen *gen;
    CUDD_VALUE_TYPE gvalue;
    int *gcube;

    /* Set environment goal to True (i.e., any state) if none was
       given. This simplifies the implementation below. */
    if (spc.num_egoals == 0) {
        env_nogoal_flag = True;
        spc.num_egoals = 1;
        spc.env_goals = malloc( sizeof(ptree_t *) );
        *spc.env_goals = init_ptree( PT_CONSTANT, NULL, 1 );
    }

    num_env = tree_size( spc.evar_list );
    num_sys = tree_size( spc.svar_list );

    /* State vector (i.e., valuation of the variables) */
    state = malloc( sizeof(vartype)*(num_env+num_sys) );
    if (state == NULL) {
        perror( __FILE__ ",  malloc" );
        exit(-1);
    }

    /* Allocate cube array, used later for quantifying over variables. */
    cube = (int *)malloc( sizeof(int)*2*(num_env+num_sys) );
    if (cube == NULL) {
        perror( __FILE__ ",  malloc" );
        exit(-1);
    }

    /* Chain together environment and system variable lists for
       working with BDD library. */
    if (spc.evar_list == NULL) {
        var_separator = NULL;
        spc.evar_list = spc.svar_list;  /* that this is the deterministic case
                                           is indicated by var_separator = NULL. */
    } else {
        var_separator = get_list_item( spc.evar_list, -1 );
        if (var_separator == NULL) {
            fprintf( stderr,
                     "Error: get_list_item failed on environment variables"
                     " list.\n" );
            free( state );
            free( cube );
            return NULL;
        }
        var_separator->left = spc.svar_list;
    }

    /* Generate BDDs for the various parse trees from the problem spec. */
    if (spc.env_init != NULL) {
        einit = ptree_BDD( spc.env_init, spc.evar_list, manager );
    } else {
        einit = Cudd_ReadOne( manager );
        Cudd_Ref( einit );
    }
    if (spc.sys_init != NULL) {
        sinit = ptree_BDD( spc.sys_init, spc.evar_list, manager );
    } else {
        sinit = Cudd_ReadOne( manager );
        Cudd_Ref( sinit );
    }
    if (verbose > 1)
        logprint( "Building environment transition BDD..." );
    etrans = ptree_BDD( spc.env_trans, spc.evar_list, manager );
    if (verbose > 1) {
        logprint( "Done." );
        logprint( "Building system transition BDD..." );
    }
    strans = ptree_BDD( spc.sys_trans, spc.evar_list, manager );
    if (verbose > 1)
        logprint( "Done." );

    /* Build goal BDDs, if present. */
    if (spc.num_egoals > 0) {
        egoals = malloc( spc.num_egoals*sizeof(DdNode *) );
        for (i = 0; i < spc.num_egoals; i++)
            *(egoals+i) = ptree_BDD( *(spc.env_goals+i), spc.evar_list, manager );
    } else {
        egoals = NULL;
    }
    if (spc.num_sgoals > 0) {
        sgoals = malloc( spc.num_sgoals*sizeof(DdNode *) );
        for (i = 0; i < spc.num_sgoals; i++)
            *(sgoals+i) = ptree_BDD( *(spc.sys_goals+i), spc.evar_list, manager );
    } else {
        sgoals = NULL;
    }

    if (var_separator == NULL) {
        spc.evar_list = NULL;
    } else {
        var_separator->left = NULL;
    }

    W = compute_winning_set_BDD( manager, etrans, strans, egoals, sgoals,
                                 verbose );
    if (W == NULL) {
        fprintf( stderr,
                 "Error synthesize: failed to construct winning set.\n" );
        free( state );
        free( cube );
        return NULL;
    }
    Y = compute_sublevel_sets( manager, W, etrans, strans,
                               egoals, spc.num_egoals,
                               sgoals, spc.num_sgoals,
                               &num_sublevels, &X_ijr, verbose );
    if (Y == NULL) {
        fprintf( stderr,
                 "Error synthesize: failed to construct sublevel sets.\n" );
        free( state );
        free( cube );
        return NULL;
    }

    /* The sublevel sets are exactly as resulting from the vanilla
       fixed point formula.  Thus for each system goal i, Y_0 = \emptyset,
       and Y_1 is a union of i-goal states and environment-blocking states.

       For the purpose of synthesis, it is enough to delete Y_0 and
       replace Y_1 with the intersection of i-goal states and the
       winning set, and then shift the indices down (so that Y_1 is
       now called Y_0, Y_2 is now called Y_1, etc.) */
    for (i = 0; i < spc.num_sgoals; i++) {
        Cudd_RecursiveDeref( manager, *(*(Y+i)) );
        Cudd_RecursiveDeref( manager, *(*(Y+i)+1) );
        for (r = 0; r < spc.num_egoals; r++)
            Cudd_RecursiveDeref( manager, *(*(*(X_ijr+i))+r) );
        free( *(*(X_ijr+i)) );

        *(*(Y+i)+1) = Cudd_bddAnd( manager, *(sgoals+i), W );
        Cudd_Ref( *(*(Y+i)+1) );

        (*(num_sublevels+i))--;
        for (j = 0; j < *(num_sublevels+i); j++) {
            *(*(Y+i)+j) = *(*(Y+i)+j+1);
            *(*(X_ijr+i)+j) = *(*(X_ijr+i)+j+1);
        }

        assert( *(num_sublevels+i) > 0 );
        *(Y+i) = realloc( *(Y+i), (*(num_sublevels+i))*sizeof(DdNode *) );
        *(X_ijr+i) = realloc( *(X_ijr+i),
                              (*(num_sublevels+i))*sizeof(DdNode **) );
        if (*(Y+i) == NULL || *(X_ijr+i) == NULL) {
            perror( __FILE__ ",  realloc" );
            exit(-1);
        }
    }

    /* Make primed form of W and take conjunction with system
       transition (safety) formula, for use while stepping down Y_i
       sets.  Note that we assume the variable map has been
       appropriately defined in the CUDD manager, after the call to
       compute_winning_set_BDD above. */
    tmp = Cudd_bddVarMap( manager, W );
    if (tmp == NULL) {
        fprintf( stderr,
                 "Error synthesize: Error in swapping variables with primed"
                 " forms.\n" );
        free( state );
        free( cube );
        return NULL;
    }
    Cudd_Ref( tmp );
    strans_into_W = Cudd_bddAnd( manager, strans, tmp );
    Cudd_Ref( strans_into_W );
    Cudd_RecursiveDeref( manager, tmp );

    /* From each initial state, build strategy by propagating forward
       toward the next goal (current target goal specified by "mode"
       of a state), and iterating until every reached state and mode
       combination has already been encountered (whence the
       strategy already built). */
    if (init_flags == ALL_INIT
        || (init_flags == ONE_SIDE_INIT && spc.sys_init == NULL)) {
        if (init_flags == ALL_INIT) {
            if (verbose > 1)
                logprint( "Enumerating initial states, given init_flags ="
                          " ALL_INIT" );
            tmp = Cudd_bddAnd( manager, einit, sinit );
        } else {
            if (verbose > 1)
                logprint( "Enumerating initial states, given init_flags ="
                          " ONE_SIDE_INIT and empty SYSINIT" );
            tmp = einit;
            Cudd_Ref( tmp );
        }
        Cudd_Ref( tmp );
        Cudd_AutodynDisable( manager );
        Cudd_ForeachCube( manager, tmp, gen, gcube, gvalue ) {
            initialize_cube( state, gcube, num_env+num_sys );
            while (!saturated_cube( state, gcube, num_env+num_sys )) {
                this_node_stack = insert_anode( this_node_stack, 0, -1, False,
                                                state, num_env+num_sys );
                if (this_node_stack == NULL) {
                    fprintf( stderr,
                             "Error synthesize: building list of initial"
                             " states.\n" );
                    return NULL;
                }
                increment_cube( state, gcube, num_env+num_sys );
            }
            this_node_stack = insert_anode( this_node_stack, 0, -1, False,
                                            state, num_env+num_sys );
            if (this_node_stack == NULL) {
                fprintf( stderr,
                         "Error synthesize: building list of initial"
                         " states.\n" );
                return NULL;
            }
        }
        Cudd_AutodynEnable( manager, CUDD_REORDER_SAME );
        Cudd_RecursiveDeref( manager, tmp );

    } else if (init_flags == ALL_ENV_EXIST_SYS_INIT) {
コード例 #9
0
ファイル: testextra.c プロジェクト: cjdrake/cudd
/**
 * @brief Basic test of timeout handler.
 *
 * @details Sets a short timeout and then tries to build a function
 * with a large BDD.  Strives to avoid leaking nodes.
 *
 * @return 0 if successful; -1 otherwise.
 */
static int
testTimeout(int verbosity)
{
    DdManager *dd;
    /* Declare these "volatile" to prevent clobbering by longjmp. */
    DdNode * volatile f;
    DdNode * volatile clause = NULL;
    DdNode * var1, * var2;
    int i, ret, count;
    int const N = 20; /* half the number of variables in f */
    unsigned long timeout = 100UL; /* in milliseconds */
    jmp_buf timeoutEnv;

    dd = Cudd_Init(0, 0, CUDD_UNIQUE_SLOTS, CUDD_CACHE_SLOTS, 0);
    if (!dd) {
        if (verbosity) {
            printf("initialization failed\n");
        }
        return -1;
    }

    /* Set up timeout handling. */
    if (setjmp(timeoutEnv) > 0) {
        if (verbosity) {
            printf("caught timeout\n");
        }
        /* The nodes of clause may be leaked if the timeout was
         * detected while conjoining the clause to f.  We set
         * clause to NULL when it's not in use to be able to
         * detect this case.
         */
        if (clause)
            Cudd_RecursiveDeref(dd, clause);
        goto finally;
    }
    (void) Cudd_RegisterTimeoutHandler(dd, timeoutHandler, (void *) &timeoutEnv);
    (void) Cudd_SetTimeLimit(dd, timeout);

    /* Try to build function.  This is expected to run out of time. */
    f = Cudd_ReadOne(dd);
    Cudd_Ref(f);
    for (i = 0; i < N; i++) {
        DdNode * tmp;
        var1 = Cudd_bddIthVar(dd, i);
        if (!var1) {
            if (verbosity) {
                printf("computation failed\n");
                return -1;
            }
        }
        var2 = Cudd_bddIthVar(dd, i+N);
        if (!var2) {
            if (verbosity) {
                printf("computation failed\n");
                return -1;
            }
        }
        clause = Cudd_bddOr(dd, var1, var2);
        if (!clause) {
            if (verbosity) {
                printf("computation failed\n");
            }
            return -1;
        }
        Cudd_Ref(clause);
        tmp = Cudd_bddAnd(dd, f, clause);
        if (!tmp) {
            if (verbosity) {
                printf("computation failed\n");
            }
            return -1;
        }
        Cudd_Ref(tmp);
        Cudd_RecursiveDeref(dd, clause);
        clause = NULL;
        Cudd_RecursiveDeref(dd, f);
        f = tmp;
    }
    if (verbosity > 1) {
        Cudd_bddPrintCover(dd, f, f);
    }

finally:
    if (verbosity) {
        printf("so far");
        Cudd_PrintSummary(dd, f, 2*N, 0);
    }
    count = 0;
    for (i = 0; i < N-1; i += 2) {
        var1 = Cudd_bddIthVar(dd, i);
        if (!var1) {
            printf("computation failed\n");
            return -1;
        }
        var2 = Cudd_bddIthVar(dd, i+1);
        if (!var2) {
            printf("computation failed\n");
            return -1;
        }
        clause = Cudd_bddOr(dd, var1, var2);
        if (!clause) {
            printf("computation failed\n");
            return -1;
        }
        Cudd_Ref(clause);
        if (Cudd_bddLeq(dd, f, clause)) {
            count++;
        }
        Cudd_RecursiveDeref(dd, clause);
    }
    if (verbosity) {
        printf("f implies %d clauses\n", count);
    }
    Cudd_RecursiveDeref(dd, f);
    ret = Cudd_CheckZeroRef(dd);
    if (verbosity) {
        Cudd_PrintInfo(dd, stdout);
        if (ret != 0) {
            printf("%d non-zero references\n", ret);
        }
    }
    Cudd_Quit(dd);
    return 0;
}
コード例 #10
0
ファイル: testextra.c プロジェクト: cjdrake/cudd
/**
 * @brief Basic test of long double and EPD minterm computation.
 * @return 0 if successful; -1 otherwise.
 */
static int
testLdbl(int verbosity)
{
    DdManager *dd;
    DdNode *f, *g;
    int i, ret;
    int const N = 12; /* half the number of variables */
    long double cnt;

    dd = Cudd_Init(2*N, 0, CUDD_UNIQUE_SLOTS, CUDD_CACHE_SLOTS, 0);
    if (!dd) {
        if (verbosity) {
            printf("initialization failed\n");
        }
        return -1;
    }
    f = g = Cudd_ReadOne(dd);
    Cudd_Ref(f);
    Cudd_Ref(g);
    for (i = 0; i < N; i++) {
        DdNode *var1, *var2, *clause, *tmp;
        var1 = Cudd_bddIthVar(dd, i);
        var2 = Cudd_bddIthVar(dd, i+N);
        clause = Cudd_bddOr(dd, var1, var2);
        if (!clause) {
            Cudd_Quit(dd);
            return -1;
        }
        Cudd_Ref(clause);
        tmp = Cudd_bddAnd(dd, f, clause);
        if (!tmp) {
            Cudd_Quit(dd);
            return -1;
        }
        Cudd_Ref(tmp);
        Cudd_RecursiveDeref(dd, clause);
        Cudd_RecursiveDeref(dd, f);
        f = tmp;
        clause = Cudd_bddOr(dd, Cudd_Not(var1), Cudd_Not(var2));
        if (!clause) {
            Cudd_Quit(dd);
            return -1;
        }
        Cudd_Ref(clause);
        tmp = Cudd_bddAnd(dd, g, clause);
        if (!tmp) {
            Cudd_Quit(dd);
            return -1;
        }
        Cudd_Ref(tmp);
        Cudd_RecursiveDeref(dd, clause);
        Cudd_RecursiveDeref(dd, g);
        g = tmp;
    }
    if (verbosity) {
        printf("f");
        Cudd_PrintSummary(dd, f, 2*N, 0);
    }
    cnt = Cudd_LdblCountMinterm(dd, f, 2*N);
    if (verbosity) {
        printf("f has %Lg minterms\n", cnt);
    }
    if (verbosity) {
        printf("EPD count for f = ");
        ret = Cudd_EpdPrintMinterm(dd, f, 2*N);
        printf("\n");
        if (!ret) {
            printf("problem with EPD\n");
        }
    }
    Cudd_RecursiveDeref(dd, f);
    if (verbosity) {
        printf("g");
        Cudd_PrintSummary(dd, g, 2*N, 0);
    }
    cnt = Cudd_LdblCountMinterm(dd, g, 2*N);
    if (verbosity) {
        printf("g has %Lg minterms\n", cnt);
    }
    if (verbosity) {
        printf("EPD count for g = ");
        ret = Cudd_EpdPrintMinterm(dd, g, 2*N);
        printf("\n");
        if (!ret) {
            printf("problem with EPD\n");
        }
    }
    Cudd_RecursiveDeref(dd, g);
    ret = Cudd_CheckZeroRef(dd);
    if (verbosity && ret != 0) {
        printf("%d non-zero references\n", ret);
    }
    Cudd_Quit(dd);
    return 0;
}
コード例 #11
0
void
I_BDD_new_mutex_domain (DdManager *dd, DdNode *node[], unsigned int size)
{
  unsigned int shbuf, vars, ctr;
  DdNode **ddVar, *one, *newnode, *oldnode, *bitnode;
  int i,j, extra;

  /* base cases */

  if (size == 0)
    {
      return;
    }

  one = Cudd_ReadOne(dd);

  if (size == 1)
    {
      node[0] = one;
      Cudd_Ref (node[0]);
      return;
    }

  for(shbuf = size - 1, vars = 0; shbuf != 0; shbuf >>= 1, vars++);

  extra = (1 << vars) - size;

  ddVar = malloc(vars * sizeof(DdNode *));

  for (j = 0; j < vars; j++)
    {
      ddVar[j] = bitnode = Cudd_bddNewVar (dd);
      Cudd_Ref (bitnode);
    }

  ctr = 0;

  for (i = 0; i < size; i++, ctr++)
    {
      newnode = one;
      Cudd_Ref (newnode);

#ifdef I_BDD_MUTEX_DEBUG
      printf("i%d:", i);
#endif

      for (j = (extra > 0); j < vars; j++)
	{
	  bitnode = (ctr & (1 << j)) ? ddVar[j] : Cudd_Not(ddVar[j]);

	  newnode = Cudd_bddAnd (dd, bitnode, oldnode = newnode);
	  Cudd_Ref (newnode);
	  Cudd_RecursiveDeref (dd, oldnode);

#ifdef I_BDD_MUTEX_DEBUG
	  if (ctr & (1 << j))
	    printf("+ v%d ", j);
	  else
	    printf("+ !v%d ", j);
#endif
	}

#ifdef I_BDD_MUTEX_DEBUG
      printf ("\n");
#endif

      node[i] = newnode;

      if (extra > 0)
	{
	  extra--;
	  ctr++;
	}
    }

#ifdef I_BDD_MUTEX_TEST
  {
    DdNode *test, *old_test;
    int i;
    test = Cudd_ReadLogicZero(dd);
    Cudd_Ref (test);
    for (i = 0; i < size; i++)
      {
	if (Cudd_bddIte (dd, test, node[i], zero) != zero)
	  I_punt("I_BDD_new_mutex_complex: not mutex!");

	test = Cudd_bddIte(dd, node[i], one, old_test = test);
	Cudd_Ref (test);
	Cudd_RecursiveDeref (dd, old_test);
      }
    if (test != one)
      I_punt("I_BDD_new_mutex_complex: not exhaustive!");

    Cudd_RecursiveDeref (dd, test);
    }
#endif

  for (j = 0; j < vars; j++)
    Cudd_RecursiveDeref (dd, ddVar[j]);

  free (ddVar);
  return;
}
コード例 #12
0
ファイル: solve_operators.c プロジェクト: tulip-control/gr1c
DdNode *compute_winning_set_BDD( DdManager *manager,
                                 DdNode *etrans, DdNode *strans,
                                 DdNode **egoals, DdNode **sgoals,
                                 unsigned char verbose )
{
    DdNode *X = NULL, *X_prev = NULL;
    DdNode *Y = NULL, *Y_exmod = NULL, *Y_prev = NULL;
    DdNode **Z = NULL, **Z_prev = NULL;
    bool Z_changed;  /* Use to detect occurrence of fixpoint for all Z_i */

    /* Fixpoint iteration counters */
    int num_it_Z, num_it_Y, num_it_X;

    DdNode *tmp, *tmp2;
    int i, j;  /* Generic counters */

    DdNode **vars, **pvars;
    int num_env, num_sys;
    int *cube;  /* length will be twice total number of variables (to
                   account for both variables and their primes). */

    num_env = tree_size( spc.evar_list );
    num_sys = tree_size( spc.svar_list );

    /* Allocate cube array, used later for quantifying over variables. */
    cube = (int *)malloc( sizeof(int)*2*(num_env+num_sys) );
    if (cube == NULL) {
        perror( __FILE__ ",  malloc" );
        exit(-1);
    }

    /* Define a map in the manager to easily swap variables with their
       primed selves. */
    vars = malloc( (num_env+num_sys)*sizeof(DdNode *) );
    pvars = malloc( (num_env+num_sys)*sizeof(DdNode *) );
    for (i = 0; i < num_env+num_sys; i++) {
        *(vars+i) = Cudd_bddIthVar( manager, i );
        *(pvars+i) = Cudd_bddIthVar( manager, i+num_env+num_sys );
    }
    if (!Cudd_SetVarMap( manager, vars, pvars, num_env+num_sys )) {
        fprintf( stderr,
                 "Error: failed to define variable map in CUDD manager.\n" );
        free( cube );
        return NULL;
    }
    free( vars );
    free( pvars );

    if (spc.num_sgoals > 0) {
        Z = malloc( spc.num_sgoals*sizeof(DdNode *) );
        Z_prev = malloc( spc.num_sgoals*sizeof(DdNode *) );
        for (i = 0; i < spc.num_sgoals; i++) {
            *(Z+i) = NULL;
            *(Z_prev+i) = NULL;
        }
    }

    /* Initialize */
    for (i = 0; i < spc.num_sgoals; i++) {
        *(Z+i) = Cudd_ReadOne( manager );
        Cudd_Ref( *(Z+i) );
    }

    num_it_Z = 0;
    do {
        num_it_Z++;
        if (verbose > 1) {
            logprint( "Z iteration %d", num_it_Z );
            logprint( "Cudd_ReadMemoryInUse (bytes): %d",
                      Cudd_ReadMemoryInUse( manager ) );
        }

        for (i = 0; i < spc.num_sgoals; i++) {
            if (*(Z_prev+i) != NULL)
                Cudd_RecursiveDeref( manager, *(Z_prev+i) );
            *(Z_prev+i) = *(Z+i);
        }

        for (i = 0; i < spc.num_sgoals; i++) {
            if (i == spc.num_sgoals-1) {
                *(Z+i) = compute_existsmodal( manager, *Z_prev, etrans, strans,
                                              num_env, num_sys, cube );
            } else {
                *(Z+i) = compute_existsmodal( manager, *(Z_prev+i+1),
                                              etrans, strans, num_env, num_sys,
                                              cube );
            }
            if (*(Z+i) == NULL) {
                /* fatal error */
                return NULL;
            }

            /* (Re)initialize Y */
            if (Y != NULL)
                Cudd_RecursiveDeref( manager, Y );
            Y = Cudd_Not( Cudd_ReadOne( manager ) );
            Cudd_Ref( Y );

            num_it_Y = 0;
            do {
                num_it_Y++;
                if (verbose > 1) {
                    logprint( "\tY iteration %d", num_it_Y );
                    logprint( "\tCudd_ReadMemoryInUse (bytes): %d",
                              Cudd_ReadMemoryInUse( manager ) );
                }

                if (Y_prev != NULL)
                    Cudd_RecursiveDeref( manager, Y_prev );
                Y_prev = Y;
                if (Y_exmod != NULL)
                    Cudd_RecursiveDeref( manager, Y_exmod );
                Y_exmod = compute_existsmodal( manager, Y_prev, etrans, strans,
                                               num_env, num_sys, cube );
                if (Y_exmod == NULL) {
                    /* fatal error */
                    return NULL;
                }

                Y = Cudd_Not( Cudd_ReadOne( manager ) );
                Cudd_Ref( Y );
                for (j = 0; j < spc.num_egoals; j++) {

                    /* (Re)initialize X */
                    if (X != NULL)
                        Cudd_RecursiveDeref( manager, X );
                    X = Cudd_ReadOne( manager );
                    Cudd_Ref( X );

                    /* Greatest fixpoint for X, for this env goal */
                    num_it_X = 0;
                    do {
                        num_it_X++;
                        if (verbose > 1) {
                            logprint( "\t\tX iteration %d", num_it_X );
                            logprint( "\t\tCudd_ReadMemoryInUse (bytes): %d",
                                      Cudd_ReadMemoryInUse( manager ) );
                        }

                        if (X_prev != NULL)
                            Cudd_RecursiveDeref( manager, X_prev );
                        X_prev = X;
                        X = compute_existsmodal( manager, X_prev,
                                                 etrans, strans,
                                                 num_env, num_sys, cube );
                        if (X == NULL) {
                            /* fatal error */
                            return NULL;
                        }

                        tmp = Cudd_bddAnd( manager, *(sgoals+i), *(Z+i) );
                        Cudd_Ref( tmp );
                        tmp2 = Cudd_bddOr( manager, tmp, Y_exmod );
                        Cudd_Ref( tmp2 );
                        Cudd_RecursiveDeref( manager, tmp );

                        tmp = Cudd_bddAnd( manager,
                                           X, Cudd_Not( *(egoals+j) ) );
                        Cudd_Ref( tmp );
                        Cudd_RecursiveDeref( manager, X );

                        X = Cudd_bddOr( manager, tmp2, tmp );
                        Cudd_Ref( X );
                        Cudd_RecursiveDeref( manager, tmp );
                        Cudd_RecursiveDeref( manager, tmp2 );

                        tmp = X;
                        X = Cudd_bddAnd( manager, X, X_prev );
                        Cudd_Ref( X );
                        Cudd_RecursiveDeref( manager, tmp );

                    } while (!Cudd_bddLeq( manager, X, X_prev )
                             || !Cudd_bddLeq( manager, X_prev, X ));

                    tmp = Y;
                    Y = Cudd_bddOr( manager, Y, X );
                    Cudd_Ref( Y );
                    Cudd_RecursiveDeref( manager, tmp );

                    Cudd_RecursiveDeref( manager, X );
                    X = NULL;
                    Cudd_RecursiveDeref( manager, X_prev );
                    X_prev = NULL;
                }

                tmp2 = Y;
                Y = Cudd_bddOr( manager, Y, Y_prev );
                Cudd_Ref( Y );
                Cudd_RecursiveDeref( manager, tmp2 );

            } while (!Cudd_bddLeq( manager, Y, Y_prev )
                     || !Cudd_bddLeq( manager, Y_prev, Y ));

            Cudd_RecursiveDeref( manager, *(Z+i) );
            *(Z+i) = Cudd_bddAnd( manager, Y, *(Z_prev+i) );
            Cudd_Ref( *(Z+i) );

            Cudd_RecursiveDeref( manager, Y );
            Y = NULL;
            Cudd_RecursiveDeref( manager, Y_prev );
            Y_prev = NULL;
            Cudd_RecursiveDeref( manager, Y_exmod );
            Y_exmod = NULL;

        }

        Z_changed = False;
        for (i = 0; i < spc.num_sgoals; i++) {
            if (!Cudd_bddLeq( manager, *(Z+i), *(Z_prev+i) )
                || !Cudd_bddLeq( manager, *(Z_prev+i), *(Z+i) )) {
                Z_changed = True;
                break;
            }
        }
    } while (Z_changed);

    /* Pre-exit clean-up */
    tmp = *Z;
    Cudd_RecursiveDeref( manager, *Z_prev );
    for (i = 1; i < spc.num_sgoals; i++) {
        Cudd_RecursiveDeref( manager, *(Z+i) );
        Cudd_RecursiveDeref( manager, *(Z_prev+i) );
    }
    free( Z );
    free( Z_prev );
    free( cube );

    return tmp;
}
コード例 #13
0
ファイル: expr.cpp プロジェクト: cambridgehackers/atomicc
static DdNode *tree2BDD(DdManager *mgr, ACCExpr *expr, VarMap &varMap)
{
    std::string op = expr->value;
    DdNode *ret = nullptr;
    if (op == "&&")
        op = "&";
    else if (op == "||")
        op = "|";
    if (checkInteger(expr, "1"))
        ret = Cudd_ReadOne(mgr);
    else if (checkInteger(expr, "0"))
        ret = Cudd_ReadLogicZero(mgr);
    else if (op == "!")
        return Cudd_Not(tree2BDD(mgr, expr->operands.front(), varMap)); // Not passes through ref count
    else if (op != "&" && op != "|" && op != "^") {
        if ((op == "!=" || op == "==")) {
            ACCExpr *lhs = getRHS(expr, 0);
            if (boolPossible(lhs) && boolPossible(getRHS(expr,1)))
                goto next; // we can analyze relops on booleans
            if (trace_bool)
                printf("[%s:%d] boolnot %d %d = %s\n", __FUNCTION__, __LINE__, boolPossible(getRHS(expr,0)), boolPossible(getRHS(expr,1)), tree2str(expr).c_str());
            if (isIdChar(lhs->value[0])) {
                if (trace_bool)
                    printf("[%s:%d] name %s type %s\n", __FUNCTION__, __LINE__, lhs->value.c_str(), refList[lhs->value].type.c_str());
            }
        }
        if (op == "!=")    // normalize comparison strings
            expr->value = "==";
        std::string name = "( " + tree2str(expr) + " )";
        if (!varMap[name]) {
            varMap[name] = new MapItem;
            varMap[name]->index = varMap.size();
            varMap[name]->node = Cudd_bddIthVar(mgr, varMap[name]->index);
        }
        ret = varMap[name]->node;
        if (op == "!=") {   // normalize comparison strings
            expr->value = op; // restore
            ret = Cudd_Not(ret);
        }
    }
    if (ret) {
        Cudd_Ref(ret);
        return ret;
    }
next:;
    for (auto item: expr->operands) {
         DdNode *operand = tree2BDD(mgr, item, varMap), *next;
         if (!ret)
             ret = operand;
         else {
             if (op == "&")
                 next = Cudd_bddAnd(mgr, ret, operand);
             else if (op == "|")
                 next = Cudd_bddOr(mgr, ret, operand);
             else if (op == "^" || op == "!=")
                 next = Cudd_bddXor(mgr, ret, operand);
             else if (op == "==")
                 next = Cudd_bddXnor(mgr, ret, operand);
             else {
                 printf("[%s:%d] unknown operator\n", __FUNCTION__, __LINE__);
                 exit(-1);
             }
             Cudd_Ref(next);
             Cudd_RecursiveDeref(mgr, operand);
             Cudd_RecursiveDeref(mgr, ret);
             ret = next;
         }
    }
    return ret;
}
コード例 #14
0
/**Function********************************************************************

  Synopsis    [Main program for ntr.]

  Description [Main program for ntr. Performs initialization. Reads command
  line options and network(s). Builds BDDs with reordering, and optionally
  does reachability analysis. Prints stats.]

  SideEffects [None]

  SeeAlso     []

******************************************************************************/
int
main(
  int  argc,
  char ** argv)
{
    NtrOptions	*option;	/* options */
    FILE	*fp1;		/* first network file pointer */
    BnetNetwork	*net1 = NULL;	/* first network */
    FILE	*fp2;		/* second network file pointer */
    BnetNetwork	*net2 = NULL;	/* second network */
    DdManager	*dd;		/* pointer to DD manager */
    int		exitval;	/* return value of Cudd_CheckZeroRef */
    int		ok;		/* overall return value from main() */
    int		result;		/* stores the return value of functions */
    BnetNode	*node;		/* auxiliary pointer to network node */
    int		i;		/* loop index */
    int		j;		/* loop index */
    double	*signatures;	/* array of signatures */
    int		pr;		/* verbosity level */
    int		reencoded;	/* linear transformations attempted */

    /* Initialize. */
    option = mainInit();
    ntrReadOptions(argc,argv,option);
    pr = option->verb;
    reencoded = option->reordering == CUDD_REORDER_LINEAR ||
		option->reordering == CUDD_REORDER_LINEAR_CONVERGE ||
		option->autoMethod == CUDD_REORDER_LINEAR ||
		option->autoMethod == CUDD_REORDER_LINEAR_CONVERGE;
    /* Currently traversal requires global BDDs. Override whatever
    ** was specified for locGlob.
    */
    if (option->traverse == TRUE || option->envelope == TRUE ||
	option->scc == TRUE) {
	option->locGlob = BNET_GLOBAL_DD;
    }

    /* Read the first network... */
    fp1 = open_file(option->file1, "r");
    net1 = Bnet_ReadNetwork(fp1,pr);
    (void) fclose(fp1);
    if (net1 == NULL) {
	(void) fprintf(stderr,"Syntax error in %s.\n",option->file1);
	exit(2);
    }
    /* ... and optionally echo it to the standard output. */
    if (pr > 2) {
	Bnet_PrintNetwork(net1);
    }

    /* Read the second network... */
    if (option->verify == TRUE || option->second == TRUE ||
	option->clip > 0.0 || option->dontcares) {
	fp2 = open_file(option->file2, "r");
	net2 = Bnet_ReadNetwork(fp2,pr);
	(void) fclose(fp2);
	if (net2 == NULL) {
	    (void) fprintf(stderr,"Syntax error in %s.\n",option->file2);
	    exit(2);
	}
	/* ... and optionally echo it to the standard output. */
	if (pr > 2) {
	    Bnet_PrintNetwork(net2);
	}
    }

    /* Initialize manager. We start with 0 variables, because
    ** Ntr_buildDDs will create new variables rather than using
    ** whatever already exists.
    */
    dd = startCudd(option,net1->ninputs);
    if (dd == NULL) { exit(2); }

    /* Build the BDDs for the nodes of the first network. */
    result = Ntr_buildDDs(net1,dd,option,NULL);
    if (result == 0) { exit(2); }

    /* Build the BDDs for the nodes of the second network if requested. */
    if (option->verify == TRUE || option->second == TRUE ||
	option->clip > 0.0 || option->dontcares == TRUE) {
	char *nodesave = option->node;
	option->node = NULL;
	result = Ntr_buildDDs(net2,dd,option,net1);
	option->node = nodesave;
	if (result == 0) { exit(2); }
    }

    if (option->noBuild == TRUE) {
	Bnet_FreeNetwork(net1);
	if (option->verify == TRUE || option->second == TRUE ||
	    option->clip > 0.0) {
	    Bnet_FreeNetwork(net2);
	}
	freeOption(option);
	exit(0);
    }
    if (option->locGlob != BNET_LOCAL_DD) {
	/* Print the order before the final reordering. */
	(void) printf("Order before final reordering\n");
	result = Bnet_PrintOrder(net1,dd);
	if (result == 0) exit(2);
    }

    /* Perform final reordering */
    if (option->zddtest == FALSE) {
	result = reorder(net1,dd,option);
	if (result == 0) exit(2);

	/* Print final order. */
	if ((option->reordering != CUDD_REORDER_NONE || option->gaOnOff) &&
	    option->locGlob != BNET_LOCAL_DD) {
	    (void) printf("New order\n");
	    result = Bnet_PrintOrder(net1,dd);
	    if (result == 0) exit(2);
	}

	/* Print the re-encoded inputs. */
	if (pr >= 1 && reencoded == 1) {
	    for (i = 0; i < net1->npis; i++) {
		if (!st_lookup(net1->hash,net1->inputs[i],&node)) {
		    exit(2);
		}
		(void) fprintf(stdout,"%s:",node->name);
		Cudd_PrintDebug(dd,node->dd,Cudd_ReadSize(dd),pr);
	    }
	    for (i = 0; i < net1->nlatches; i++) {
		if (!st_lookup(net1->hash,net1->latches[i][1],&node)) {
		    exit(2);
		}
		(void) fprintf(stdout,"%s:",node->name);
		Cudd_PrintDebug(dd,node->dd,Cudd_ReadSize(dd),pr);
	    }
	    if (pr >= 3) {
		result = Cudd_PrintLinear(dd);
		if (result == 0) exit(2);
	    }
	}
    }

    /* Verify (combinational) equivalence. */
    if (option->verify == TRUE) {
	result = Ntr_VerifyEquivalence(dd,net1,net2,option);
	if (result == 0) {
	    (void) printf("Verification abnormally terminated\n");
	    exit(2);
	} else if (result == -1) {
	    (void) printf("Combinational verification failed\n");
	} else {
	    (void) printf("Verification succeeded\n");
	}
    }

    /* Traverse if requested and if the circuit is sequential. */
    result = Ntr_Trav(dd,net1,option);
    if (result == 0) exit(2);

    /* Traverse with trasitive closure. */
    result = Ntr_ClosureTrav(dd,net1,option);
    if (result == 0) exit(2);

    /* Compute outer envelope if requested and if the circuit is sequential. */
    if (option->envelope == TRUE && net1->nlatches > 0) {
	NtrPartTR *T;
	T = Ntr_buildTR(dd,net1,option,option->image);
	result = Ntr_Envelope(dd,T,NULL,option);
	Ntr_freeTR(dd,T);
    }

    /* Compute SCCs if requested and if the circuit is sequential. */
    result = Ntr_SCC(dd,net1,option);
    if (result == 0) exit(2);

    /* Test Constrain Decomposition. */
    if (option->partition == TRUE && net1->nlatches > 0) {
	NtrPartTR *T;
	DdNode *product;
	DdNode **decomp;
	int sharingSize;
	T = Ntr_buildTR(dd,net1,option,NTR_IMAGE_MONO);
	decomp = Cudd_bddConstrainDecomp(dd,T->part[0]);
	if (decomp == NULL) exit(2);
	sharingSize = Cudd_SharingSize(decomp, Cudd_ReadSize(dd));
	(void) fprintf(stdout, "Decomposition Size: %d components %d nodes\n",
		       Cudd_ReadSize(dd), sharingSize);
	product = Cudd_ReadOne(dd);
	Cudd_Ref(product);
	for (i = 0; i < Cudd_ReadSize(dd); i++) {
	    DdNode *intermediate = Cudd_bddAnd(dd, product, decomp[i]);
	    if (intermediate == NULL) {
		exit(2);
	    }
	    Cudd_Ref(intermediate);
	    Cudd_IterDerefBdd(dd, product);
	    product = intermediate;
	}
	if (product != T->part[0])
	    exit(2);
	Cudd_IterDerefBdd(dd, product);
	for (i = 0; i < Cudd_ReadSize(dd); i++) {
	    Cudd_IterDerefBdd(dd, decomp[i]);
	}
	FREE(decomp);
	Ntr_freeTR(dd,T);
    }

    /* Test char-to-vect conversion. */
    result = Ntr_TestCharToVect(dd,net1,option);
    if (result == 0) exit(2);

    /* Test extraction of two-literal clauses. */
    result = Ntr_TestTwoLiteralClauses(dd,net1,option);
    if (result == 0) exit(2);

    /* Test BDD minimization functions. */
    result = Ntr_TestMinimization(dd,net1,net2,option);
    if (result == 0) exit(2);

    /* Test density-related functions. */
    result = Ntr_TestDensity(dd,net1,option);
    if (result == 0) exit(2);

    /* Test decomposition functions. */
    result = Ntr_TestDecomp(dd,net1,option);
    if (result == 0) exit(2);

    /* Test cofactor estimation functions. */
    result = Ntr_TestCofactorEstimate(dd,net1,option);
    if (result == 0) exit(2);

    /* Test BDD clipping functions. */
    result = Ntr_TestClipping(dd,net1,net2,option);
    if (result == 0) exit(2);

    /* Test BDD equivalence and containment under DC functions. */
    result = Ntr_TestEquivAndContain(dd,net1,net2,option);
    if (result == 0) exit(2);

    /* Test BDD Cudd_bddClosestCube. */
    result = Ntr_TestClosestCube(dd,net1,option);
    if (result == 0) exit(2);

    /* Test ZDDs if requested. */
    if (option->stateOnly == FALSE && option->zddtest == TRUE) {
	result = Ntr_testZDD(dd,net1,option);
	if (result == 0)
	    (void) fprintf(stdout,"ZDD test failed.\n");
	result = Ntr_testISOP(dd,net1,option);
	if (result == 0)
	    (void) fprintf(stdout,"ISOP test failed.\n");
    }

    /* Compute maximum flow if requested and if the circuit is sequential. */
    if (option->maxflow == TRUE && net1->nlatches > 0) {
	result = Ntr_maxflow(dd,net1,option);
	if (result == 0)
	    (void) fprintf(stdout,"Maxflow computation failed.\n");
    }

    /* Compute shortest paths if requested and if the circuit is sequential. */
    if (option->shortPath != NTR_SHORT_NONE && net1->nlatches > 0) {
	result = Ntr_ShortestPaths(dd,net1,option);
	if (result == 0)
	    (void) fprintf(stdout,"Shortest paths computation failed.\n");
    }

    /* Compute output signatures if so requested. */
    if (option->signatures) {
	(void) printf("Positive cofactor measures\n");
	for (i = 0; i < net1->noutputs; i++) {
	    if (!st_lookup(net1->hash,net1->outputs[i],&node)) {
		exit(2);
	    }
	    signatures = Cudd_CofMinterm(dd, node->dd);
	    if (signatures) {
		(void) printf("%s:\n", node->name);
		for (j = 0; j < Cudd_ReadSize(dd); j++) {
		    if((j%5 == 0)&&i) (void) printf("\n");
		    (void) printf("%5d: %-#8.4g ", j, signatures[j]);
		}
		(void) printf("\n");
		FREE(signatures);
	    } else {
		(void) printf("Signature computation failed.\n");
	    }
	}
    }

    /* Dump BDDs if so requested. */
    if (option->bdddump && option->second == FALSE &&
	option->density == FALSE && option->decomp == FALSE &&
	option->cofest == FALSE && option->clip < 0.0 &&
	option->scc == FALSE) {
	(void) printf("Dumping BDDs to %s\n", option->dumpfile);
	if (option->node != NULL) {
	    if (!st_lookup(net1->hash,option->node,&node)) {
		exit(2);
	    }
	    result = Bnet_bddArrayDump(dd,net1,option->dumpfile,&(node->dd),
				       &(node->name),1,option->dumpFmt);
	} else {
	    result = Bnet_bddDump(dd, net1, option->dumpfile,
				  option->dumpFmt, reencoded);
	}
	if (result != 1) {
	    (void) printf("BDD dump failed.\n");
	}
    }

    /* Print stats and clean up. */
    if (pr >= 0) {
	result = Cudd_PrintInfo(dd,stdout);
	if (result != 1) {
	    (void) printf("Cudd_PrintInfo failed.\n");
	}
    }

#if defined(DD_DEBUG) && !defined(DD_NO_DEATH_ROW)
    (void) fprintf(dd->err,"%d empty slots in death row\n",
    cuddTimesInDeathRow(dd,NULL));
#endif
    (void) printf("Final size: %ld\n", Cudd_ReadNodeCount(dd));

    /* Dispose of node BDDs. */
    node = net1->nodes;
    while (node != NULL) {
	if (node->dd != NULL &&
	node->type != BNET_INPUT_NODE &&
	node->type != BNET_PRESENT_STATE_NODE) {
	    Cudd_IterDerefBdd(dd,node->dd);
	}
	node = node->next;
    }
    /* Dispose of network. */
    Bnet_FreeNetwork(net1);
    /* Do the same cleanup for the second network if it was created. */
    if (option->verify == TRUE || option->second == TRUE ||
	option->clip > 0.0 || option->dontcares == TRUE) {
	node = net2->nodes;
	while (node != NULL) {
	    if (node->dd != NULL &&
		node->type != BNET_INPUT_NODE &&
		node->type != BNET_PRESENT_STATE_NODE) {
		Cudd_IterDerefBdd(dd,node->dd);
	    }
	    node = node->next;
	}
	Bnet_FreeNetwork(net2);
    }

    /* Check reference counts: At this point we should have dereferenced
    ** everything we had, except in the case of re-encoding.
    */
    exitval = Cudd_CheckZeroRef(dd);
    ok = exitval != 0;  /* ok == 0 means O.K. */
    if (exitval != 0) {
	(void) fflush(stdout);
	(void) fprintf(stderr,
	    "%d non-zero DD reference counts after dereferencing\n", exitval);
    }

#ifdef DD_DEBUG
    Cudd_CheckKeys(dd);
#endif

    Cudd_Quit(dd);

    if (pr >= 0) (void) printf("total time = %s\n",
	    util_print_time(util_cpu_time() - option->initialTime));
    freeOption(option);
    if (pr >= 0) util_print_cpu_stats(stdout);

#ifdef MNEMOSYNE
    mnem_writestats();
#endif

    exit(ok);
    /* NOTREACHED */

} /* end of main */