static sl_object_t* allocate_class(sl_vm_t* vm) { sl_class_t* klass = sl_alloc(vm->arena, sizeof(sl_class_t)); klass->base.primitive_type = SL_T_CLASS; klass->constants = st_init_table(vm->arena, &sl_string_hash_type); klass->class_variables = st_init_table(vm->arena, &sl_string_hash_type); klass->instance_methods = st_init_table(vm->arena, &sl_string_hash_type); klass->super = vm->lib.Object; klass->name = vm->lib.nil; klass->in = vm->lib.Object; return (sl_object_t*)klass; }
/**Function******************************************************************** Synopsis [Check that minterm counts have not changed.] Description [Counts the minterms in the global functions of the primary outputs of the network passed as argument. When it is calld with the second argument set to NULL, it allocates a symbol table and stores, for each output, the minterm count. If an output does not have a BDD, it stores a NULL pointer for it. If it is called with a non-null second argument, it assumes that the symbol table contains the minterm counts measured previously and it compares the new counts to the old ones. Finally, it frees the symbol table. check_minterms is designed so that it can be called twice: once before reordering, and once after reordering. Returns a pointer to the symbol table on the first invocation and NULL on the second invocation.] SideEffects [None] SeeAlso [] ******************************************************************************/ st_table * checkMinterms( BnetNetwork * net, DdManager * dd, st_table * previous) { BnetNode *po; int numPi; char *name; double *count, newcount, *oldcount; int flag,err,i; numPi = net->ninputs; if (previous == NULL) { previous = st_init_table(strcmp,st_strhash); if (previous == NULL) { (void) printf("checkMinterms out-of-memory\n"); return(NULL); } for (i = 0; i < net->noutputs; i++) { if (!st_lookup(net->hash,net->outputs[i],&po)) { exit(2); } name = net->outputs[i]; if (po->dd != NULL) { count = ALLOC(double,1); *count = Cudd_CountMinterm(dd,po->dd,numPi); err = st_insert(previous, name, (char *) count); } else {
static void init_compile_state(sl_compile_state_t* cs, sl_vm_t* vm, sl_compile_state_t* parent, size_t init_registers) { size_t i; cs->vm = vm; cs->vars = st_init_table(vm->arena, &sl_string_hash_type); cs->parent = parent; cs->last_line = 0; cs->section = sl_alloc(vm->arena, sizeof(sl_vm_section_t)); if(parent) { cs->section->filename = parent->section->filename; } cs->section->max_registers = init_registers; cs->section->req_registers = 0; cs->section->arg_registers = 0; cs->section->insns_cap = 4; cs->section->insns_count = 0; cs->section->insns = sl_alloc(vm->arena, sizeof(sl_vm_insn_t) * cs->section->insns_cap); cs->section->can_stack_alloc_frame = 1; cs->section->opt_skip = NULL; cs->registers = sl_alloc(vm->arena, cs->section->max_registers); for(i = 0; i < init_registers; i++) { cs->registers[i] = 1; } cs->next_last_frames = NULL; }
static int DddmpCuddDdArrayStorePrefixBody ( DdManager *ddMgr /* IN: Manager */, int n /* IN: Number of output nodes to be dumped */, DdNode **f /* IN: Array of output nodes to be dumped */, char **inputNames /* IN: Array of input names (or NULL) */, char **outputNames /* IN: Array of output names (or NULL) */, FILE *fp /* IN: Pointer to the dump file */ ) { st_table *visited = NULL; int retValue; int i; /* Initialize symbol table for visited nodes. */ visited = st_init_table(st_ptrcmp, st_ptrhash); Dddmp_CheckAndGotoLabel (visited==NULL, "Error if function st_init_table.", failure); /* Call the function that really gets the job done. */ for (i = 0; i < n; i++) { retValue = DddmpCuddDdArrayStorePrefixStep (ddMgr, Cudd_Regular(f[i]), fp, visited, inputNames); Dddmp_CheckAndGotoLabel (retValue==0, "Error if function DddmpCuddDdArrayStorePrefixStep.", failure); } /* To account for the possible complement on the root, ** we put either a buffer or an inverter at the output of ** the multiplexer representing the top node. */ for (i=0; i<n; i++) { if (outputNames == NULL) { retValue = fprintf (fp, "(BUF outNode%d ", i); } else { retValue = fprintf (fp, "(BUF %s ", outputNames[i]); } Dddmp_CheckAndGotoLabel (retValue==EOF, "Error during file store.", failure); if (Cudd_IsComplement(f[i])) { retValue = fprintf (fp, "(NOT node%" PRIxPTR "))\n", (ptruint) f[i] / sizeof(DdNode)); } else { retValue = fprintf (fp, "node%" PRIxPTR ")\n", (ptruint) f[i] / sizeof(DdNode)); } Dddmp_CheckAndGotoLabel (retValue==EOF, "Error during file store.", failure); } st_free_table (visited); return(1); failure: if (visited != NULL) st_free_table(visited); return(0); }
void sl_pre_init_class(sl_vm_t* vm) { sl_class_t* obj = sl_alloc(vm->arena, sizeof(sl_class_t)); vm->lib.Class = sl_make_ptr((sl_object_t*)obj); obj->name = vm->lib.nil; obj->super = vm->lib.Object; obj->in = vm->lib.Object; obj->constants = st_init_table(vm->arena, &sl_string_hash_type); obj->class_variables = st_init_table(vm->arena, &sl_string_hash_type); obj->instance_methods = st_init_table(vm->arena, &sl_string_hash_type); obj->allocator = allocate_class; obj->base.klass = vm->lib.Class; obj->base.primitive_type = SL_T_CLASS; obj->base.instance_variables = st_init_table(vm->arena, &sl_string_hash_type); }
/**Function************************************************************* Synopsis [] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ st_table * Map_CreateTableGate2Super( Map_Man_t * pMan ) { Map_Super_t * pSuper; st_table * tTable; int i, nInputs, v; tTable = st_init_table(strcmp, st_strhash); for ( i = 0; i < pMan->pSuperLib->nSupersAll; i++ ) { pSuper = pMan->pSuperLib->ppSupers[i]; if ( pSuper->nGates == 1 ) { // skip different versions of the same root gate nInputs = Mio_GateReadInputs(pSuper->pRoot); for ( v = 0; v < nInputs; v++ ) if ( pSuper->pFanins[v]->Num != nInputs - 1 - v ) break; if ( v != nInputs ) continue; // printf( "%s\n", Mio_GateReadName(pSuper->pRoot) ); if ( st_insert( tTable, (char *)pSuper->pRoot, (char *)pSuper ) ) { assert( 0 ); } } } return tTable; }
mfgptr mf_alloc_graph() { mfgptr graph; if (!(graph = MF_ALLOC(1, mf_graph_t))) mf_error("Memory allocation failure", "mf_alloc_graph"); graph->node_table = st_init_table(strcmp, st_strhash); return(graph); }/* end of mf_alloc_graph */
/**Function************************************************************* Synopsis [Start AIG recording.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void Cudd2_Init( unsigned int numVars, unsigned int numVarsZ, unsigned int numSlots, unsigned int cacheSize, unsigned long maxMemory, void * pCudd ) { int v; // start the BDD-to-AIG manager when the first BDD manager is allocated if ( s_pCuddMan != NULL ) return; s_pCuddMan = ALLOC( Aig_CuddMan_t, 1 ); s_pCuddMan->pAig = Aig_ManStart(); s_pCuddMan->pTable = st_init_table( st_ptrcmp, st_ptrhash ); for ( v = 0; v < (int)numVars; v++ ) Aig_ObjCreatePi( s_pCuddMan->pAig ); }
static VALUE rhash_alloc(VALUE klass, SEL sel) { assert(klass != 0); assert(rb_klass_is_rhash(klass)); NEWOBJ(hash, rb_hash_t); hash->basic.flags = 0; hash->basic.klass = klass; GC_WB(&hash->tbl, st_init_table(&objhash)); hash->ifnone = Qnil; hash->has_proc_default = false; return (VALUE)hash; }
/**Function******************************************************************** Synopsis [List of nodes below some level reachable from a root node.] Description [List of nodes below some level reachable from a root node. if max>0, the list is at most of size max (partial list). Given a BDD/ADD f and a variable level level the function performs a depth-first search of the graph rooted at $f$ and select the first nodes encountered such that their variable level is equal or below the level level. If level==CUDD_MAXINDEX, then the functions collects only constant nodes. The background node is not returned in the result if take_background==0. Returns the list of nodes, the index of which has its level equal or below level, and the size of the list in *psize, if successful; NULL otherwise. Nodes in the list are NOT referenced.] SideEffects [None] SeeAlso [] ******************************************************************************/ cuddaux_list_t* Cuddaux_NodesBelowLevel(DdManager* manager, DdNode* f, int level, size_t max, size_t* psize, bool take_background) { cuddaux_list_t* res = 0; st_table* visited; visited = st_init_table(st_ptrcmp,st_ptrhash); if (visited==NULL) return NULL; *psize = 0; cuddauxNodesBelowLevelRecur(manager, Cudd_Regular(f), level, &res, visited, max, psize, take_background); if (res==NULL) *psize=0; assert (max>0 ? *psize<=max : 1); st_free_table(visited); return(res); }
static struct traceobj_arg * get_traceobj_arg(void) { if (tmp_trace_arg == 0) { tmp_trace_arg = ALLOC_N(struct traceobj_arg, 1); MEMZERO(tmp_trace_arg, struct traceobj_arg, 1); tmp_trace_arg->running = 0; tmp_trace_arg->keys = 0; tmp_trace_arg->vals = VAL_COUNT | VAL_OLDCOUNT | VAL_TOTAL_AGE | VAL_MAX_AGE | VAL_MIN_AGE | VAL_MEMSIZE; tmp_trace_arg->aggregate_table = st_init_table(&memcmp_hash_type); tmp_trace_arg->object_table = st_init_numtable(); tmp_trace_arg->str_table = st_init_strtable(); tmp_trace_arg->freed_allocation_info = NULL; tmp_trace_arg->lifetime_table = NULL; }
/**Function******************************************************************** Synopsis [Prints a ZDD to the standard output. One line per node is printed.] Description [Prints a ZDD to the standard output. One line per node is printed. Returns 1 if successful; 0 otherwise.] SideEffects [None] SeeAlso [Cudd_zddPrintDebug] ******************************************************************************/ int cuddZddP( DdManager * zdd, DdNode * f) { int retval; st_table *table = st_init_table(st_ptrcmp, st_ptrhash); if (table == NULL) return(0); retval = zp2(zdd, f, table); st_free_table(table); (void) fputc('\n', zdd->out); return(retval); } /* end of cuddZddP */
void ace_bdd_get_literals(Abc_Ntk_t * ntk, st_table ** lit_st_table, Vec_Ptr_t ** literals) { Abc_Obj_t * obj; int i; *literals = Vec_PtrAlloc(0); *lit_st_table = st_init_table(st_ptrcmp, st_ptrhash); Abc_NtkForEachObj(ntk, obj, i) { if (Abc_ObjIsCi(obj)) { st_insert(*lit_st_table, (char*) obj, (char*) Vec_PtrSize(*literals)); Vec_PtrPush(*literals, obj); } } }
/**Function******************************************************************** Synopsis [Computes the fraction of minterms in the on-set of all the positive cofactors of a BDD or ADD.] Description [Computes the fraction of minterms in the on-set of all the positive cofactors of DD. Returns the pointer to an array of doubles if successful; NULL otherwise. The array hs as many positions as there are BDD variables in the manager plus one. The last position of the array contains the fraction of the minterms in the ON-set of the function represented by the BDD or ADD. The other positions of the array hold the variable signatures.] SideEffects [None] ******************************************************************************/ double * Cudd_CofMinterm( DdManager * dd, DdNode * node) { st_table *table; double *values; double *result = NULL; int i, firstLevel; #ifdef DD_STATS long startTime; startTime = util_cpu_time(); num_calls = 0; table_mem = sizeof(st_table); #endif table = st_init_table(st_ptrcmp, st_ptrhash); if (table == NULL) { (void) fprintf(stdout,"out-of-memory, couldn't measure DD cofactors.\n"); return(NULL); } size = dd->size; values = ddCofMintermAux(dd, node, table); if (values != NULL) { result = ALLOC(double,size + 1); if (result != NULL) { #ifdef DD_STATS table_mem += (size + 1) * sizeof(double); #endif if (Cudd_IsConstant(node)) firstLevel = 1; else firstLevel = cuddI(dd,Cudd_Regular(node)->index); for (i = 0; i < size; i++) { if (i >= cuddI(dd,Cudd_Regular(node)->index)) { result[dd->invperm[i]] = values[i - firstLevel]; } else { result[dd->invperm[i]] = values[size - firstLevel]; } } result[size] = values[size - firstLevel]; } else { dd->errorCode = CUDD_MEMORY_OUT; } }
/**Function******************************************************************** Synopsis [Convert a BDD from a manager to another one.] Description [Convert a BDD from a manager to another one. Returns a pointer to the BDD in the destination manager if successful; NULL otherwise.] SideEffects [None] SeeAlso [Extra_TransferPermute] ******************************************************************************/ DdNode * extraTransferPermuteTime( DdManager * ddS, DdManager * ddD, DdNode * f, int * Permute, int TimeOut ) { DdNode *res; st_table *table = NULL; st_generator *gen = NULL; DdNode *key, *value; table = st_init_table( st_ptrcmp, st_ptrhash ); if ( table == NULL ) goto failure; res = extraTransferPermuteRecurTime( ddS, ddD, f, table, Permute, TimeOut ); if ( res != NULL ) cuddRef( res ); /* Dereference all elements in the table and dispose of the table. ** This must be done also if res is NULL to avoid leaks in case of ** reordering. */ gen = st_init_gen( table ); if ( gen == NULL ) goto failure; while ( st_gen( gen, ( const char ** ) &key, ( char ** ) &value ) ) { Cudd_RecursiveDeref( ddD, value ); } st_free_gen( gen ); gen = NULL; st_free_table( table ); table = NULL; if ( res != NULL ) cuddDeref( res ); return ( res ); failure: if ( table != NULL ) st_free_table( table ); if ( gen != NULL ) st_free_gen( gen ); return ( NULL ); } /* end of extraTransferPermuteTime */
/** @brief Computes the correlation of f and g. @details If f == g, their correlation is 1. If f == g', their correlation is 0. @return the fraction of minterms in the ON-set of the EXNOR of f and g. If it runs out of memory, returns (double)CUDD_OUT_OF_MEM. @sideeffect None @see Cudd_bddCorrelationWeights */ double Cudd_bddCorrelation( DdManager * manager, DdNode * f, DdNode * g) { st_table *table; double correlation; #ifdef CORREL_STATS num_calls = 0; #endif table = st_init_table(CorrelCompare,CorrelHash); if (table == NULL) return((double)CUDD_OUT_OF_MEM); correlation = bddCorrelationAux(manager,f,g,table); st_foreach(table, CorrelCleanUp, NIL(void)); st_free_table(table); return(correlation); } /* end of Cudd_bddCorrelation */
/**Function******************************************************************** Synopsis [Convert a BDD from a manager to another one.] Description [Convert a BDD from a manager to another one. Returns a pointer to the BDD in the destination manager if successful; NULL otherwise.] SideEffects [None] SeeAlso [Cudd_bddTransfer] ******************************************************************************/ DdNode * cuddBddTransfer( DdManager * ddS, DdManager * ddD, DdNode * f) { DdNode *res; st_table *table = NULL; st_generator *gen = NULL; DdNode *key, *value; /* NuSMV: begin add */ abort(); /* NOT USED BY NUSMV */ /* NuSMV: begin end */ table = st_init_table(st_ptrcmp,st_ptrhash); if (table == NULL) goto failure; res = cuddBddTransferRecur(ddS, ddD, f, table); if (res != NULL) cuddRef(res); /* Dereference all elements in the table and dispose of the table. ** This must be done also if res is NULL to avoid leaks in case of ** reordering. */ gen = st_init_gen(table); if (gen == NULL) goto failure; while (st_gen(gen, &key, &value)) { Cudd_RecursiveDeref(ddD, value); } st_free_gen(gen); gen = NULL; st_free_table(table); table = NULL; if (res != NULL) cuddDeref(res); return(res); failure: if (table != NULL) st_free_table(table); if (gen != NULL) st_free_gen(gen); return(NULL); } /* end of cuddBddTransfer */
/**Function******************************************************************** Synopsis [Counts the number of minterms of a ZDD.] Description [Counts the number of minterms of a ZDD. The result is returned as a double. If the procedure runs out of memory, it returns (double) CUDD_OUT_OF_MEM. This procedure is used in Cudd_zddCountMinterm.] SideEffects [None] SeeAlso [Cudd_zddCountMinterm Cudd_zddCount] ******************************************************************************/ double Cudd_zddCountDouble( DdManager * zdd, DdNode * P) { st_table *table; double res; DdNode *base, *empty; base = DD_TRUE(zdd); empty = DD_FALSE(zdd); table = st_init_table(st_ptrcmp, st_ptrhash); if (table == NULL) return((double)CUDD_OUT_OF_MEM); res = cuddZddCountDoubleStep(P, table, base, empty); if (res == (double)CUDD_OUT_OF_MEM) { zdd->errorCode = CUDD_MEMORY_OUT; } st_foreach(table, st_zdd_count_dbl_free, NIL(char)); st_free_table(table); return(res); } /* end of Cudd_zddCountDouble */
/**Function******************************************************************** Synopsis [Counts the number of minterms in a ZDD.] Description [Returns an integer representing the number of minterms in a ZDD.] SideEffects [None] SeeAlso [Cudd_zddCountDouble] ******************************************************************************/ int Cudd_zddCount( DdManager * zdd, DdNode * P) { st_table *table; int res; DdNode *base, *empty; base = DD_ONE(zdd); empty = DD_ZERO(zdd); table = st_init_table(st_ptrcmp, st_ptrhash); if (table == NULL) return(CUDD_OUT_OF_MEM); res = cuddZddCountStep(P, table, base, empty); if (res == CUDD_OUT_OF_MEM) { zdd->errorCode = CUDD_MEMORY_OUT; } st_foreach(table, st_zdd_countfree, NIL(char)); st_free_table(table); return(res); } /* end of Cudd_zddCount */
/**Function******************************************************************** Synopsis [Writes a blif body representing the argument BDDs.] Description [Writes a blif body representing the argument BDDs as a network of multiplexers. No header (.model, .inputs, and .outputs) and footer (.end) are produced by this function. One multiplexer is written for each BDD node. It returns 1 in case of success; 0 otherwise (e.g., out-of-memory, file system full, or an ADD with constants different from 0 and 1). Cudd_DumpBlifBody does not close the file: This is the caller responsibility. Cudd_DumpBlifBody uses a minimal unique subset of the hexadecimal address of a node as name for it. If the argument inames is non-null, it is assumed to hold the pointers to the names of the inputs. Similarly for onames. This function prints out only .names part.] SideEffects [None] SeeAlso [Cudd_DumpBlif Cudd_DumpDot Cudd_PrintDebug Cudd_DumpDDcal Cudd_DumpDaVinci Cudd_DumpFactoredForm] ******************************************************************************/ int Cudd_DumpBlifBody( DdManager * dd /* manager */, int n /* number of output nodes to be dumped */, DdNode ** f /* array of output nodes to be dumped */, char ** inames /* array of input names (or NULL) */, char ** onames /* array of output names (or NULL) */, FILE * fp /* pointer to the dump file */, int mv /* 0: blif, 1: blif-MV */) { st_table *visited = NULL; int retval; int i; /* Initialize symbol table for visited nodes. */ visited = st_init_table(st_ptrcmp, st_ptrhash); if (visited == NULL) goto failure; /* Call the function that really gets the job done. */ for (i = 0; i < n; i++) { retval = ddDoDumpBlif(dd,Cudd_Regular(f[i]),fp,visited,inames,mv); if (retval == 0) goto failure; } /* To account for the possible complement on the root, ** we put either a buffer or an inverter at the output of ** the multiplexer representing the top node. */ for (i = 0; i < n; i++) { if (onames == NULL) { retval = fprintf(fp, #if SIZEOF_VOID_P == 8 ".names %lx f%d\n", (ptruint) f[i] / (ptruint) sizeof(DdNode), i); #else ".names %x f%d\n", (ptruint) f[i] / (ptruint) sizeof(DdNode), i); #endif } else {
/* ================ Call Info =================*/ static st_table * call_info_table_create() { return st_init_table(&type_method_hash); }
/**Function******************************************************************** Synopsis [Returns m minterms from a BDD.] Description [Returns <code>m</code> minterms from a BDD whose support has <code>n</code> variables at most. The procedure tries to create as few extra nodes as possible. The function represented by <code>S</code> depends on at most <code>n</code> of the variables in <code>xVars</code>. Returns a BDD with <code>m</code> minterms of the on-set of S if successful; NULL otherwise.] SideEffects [None] SeeAlso [] ******************************************************************************/ DdNode * Cudd_SplitSet( DdManager * manager, DdNode * S, DdNode ** xVars, int n, double m) { DdNode *result; DdNode *zero, *one; double max, num; st_table *mtable; int *varSeen; int i,index, size; size = manager->size; one = DD_ONE(manager); zero = Cudd_Not(one); /* Trivial cases. */ if (m == 0.0) { return(zero); } if (S == zero) { return(NULL); } max = pow(2.0,(double)n); if (m > max) return(NULL); do { manager->reordered = 0; /* varSeen is used to mark the variables that are encountered ** while traversing the BDD S. */ varSeen = ALLOC(int, size); if (varSeen == NULL) { manager->errorCode = CUDD_MEMORY_OUT; return(NULL); } for (i = 0; i < size; i++) { varSeen[i] = -1; } for (i = 0; i < n; i++) { index = (xVars[i])->index; varSeen[manager->invperm[index]] = 0; } if (S == one) { if (m == max) { FREE(varSeen); return(S); } result = selectMintermsFromUniverse(manager,varSeen,m); if (result) cuddRef(result); FREE(varSeen); } else { mtable = st_init_table(st_ptrcmp,st_ptrhash); if (mtable == NULL) { (void) fprintf(manager->out, "Cudd_SplitSet: out-of-memory.\n"); FREE(varSeen); manager->errorCode = CUDD_MEMORY_OUT; return(NULL); } /* The nodes of BDD S are annotated by the number of minterms ** in their onset. The node and the number of minterms in its ** onset are stored in mtable. */ num = bddAnnotateMintermCount(manager,S,max,mtable); if (m == num) { st_foreach(mtable,cuddStCountfree,NIL(char)); st_free_table(mtable); FREE(varSeen); return(S); } result = cuddSplitSetRecur(manager,mtable,varSeen,S,m,max,0); if (result) cuddRef(result); st_foreach(mtable,cuddStCountfree,NULL); st_free_table(mtable); FREE(varSeen); } } while (manager->reordered == 1); cuddDeref(result); return(result); } /* end of Cudd_SplitSet */
/**Function************************************************************* Synopsis [Returns the local function of the DSD node. ] Description [The local function is computed using the global function of the node and the global functions of the formal inputs. The resulting local function is mapped using the topmost N variables of the manager. The number of variables N is equal to the number of formal inputs.] SideEffects [] SeeAlso [] ***********************************************************************/ DdNode * Dsd_TreeGetPrimeFunction( DdManager * dd, Dsd_Node_t * pNode ) { int * pForm2Var; // the mapping of each formal input into its first var int * pVar2Form; // the mapping of each var into its formal inputs int i, iVar, iLev, * pPermute; DdNode ** pbCube0, ** pbCube1; DdNode * bFunc, * bRes, * bTemp; st_table * pCache; pPermute = ALLOC( int, dd->size ); pVar2Form = ALLOC( int, dd->size ); pForm2Var = ALLOC( int, dd->size ); pbCube0 = ALLOC( DdNode *, dd->size ); pbCube1 = ALLOC( DdNode *, dd->size ); // remap the global function in such a way that // the support variables of each formal input are adjacent iLev = 0; for ( i = 0; i < pNode->nDecs; i++ ) { pForm2Var[i] = dd->invperm[i]; for ( bTemp = pNode->pDecs[i]->S; bTemp != b1; bTemp = cuddT(bTemp) ) { iVar = dd->invperm[iLev]; pPermute[bTemp->index] = iVar; pVar2Form[iVar] = i; iLev++; } // collect the cubes representing each assignment pbCube0[i] = Extra_bddGetOneCube( dd, Cudd_Not(pNode->pDecs[i]->G) ); Cudd_Ref( pbCube0[i] ); pbCube1[i] = Extra_bddGetOneCube( dd, pNode->pDecs[i]->G ); Cudd_Ref( pbCube1[i] ); } // remap the function bFunc = Cudd_bddPermute( dd, pNode->G, pPermute ); Cudd_Ref( bFunc ); // remap the cube for ( i = 0; i < pNode->nDecs; i++ ) { pbCube0[i] = Cudd_bddPermute( dd, bTemp = pbCube0[i], pPermute ); Cudd_Ref( pbCube0[i] ); Cudd_RecursiveDeref( dd, bTemp ); pbCube1[i] = Cudd_bddPermute( dd, bTemp = pbCube1[i], pPermute ); Cudd_Ref( pbCube1[i] ); Cudd_RecursiveDeref( dd, bTemp ); } // remap the function pCache = st_init_table(st_ptrcmp,st_ptrhash); bRes = Extra_dsdRemap( dd, bFunc, pCache, pVar2Form, pForm2Var, pbCube0, pbCube1 ); Cudd_Ref( bRes ); st_free_table( pCache ); Cudd_RecursiveDeref( dd, bFunc ); for ( i = 0; i < pNode->nDecs; i++ ) { Cudd_RecursiveDeref( dd, pbCube0[i] ); Cudd_RecursiveDeref( dd, pbCube1[i] ); } /* //////////// // permute the function once again // in such a way that i-th var stood for i-th formal input for ( i = 0; i < dd->size; i++ ) pPermute[i] = -1; for ( i = 0; i < pNode->nDecs; i++ ) pPermute[dd->invperm[i]] = i; bRes = Cudd_bddPermute( dd, bTemp = bRes, pPermute ); Cudd_Ref( bRes ); Cudd_RecursiveDeref( dd, bTemp ); //////////// */ FREE(pPermute); FREE(pVar2Form); FREE(pForm2Var); FREE(pbCube0); FREE(pbCube1); Cudd_Deref( bRes ); return bRes; }
/**Function******************************************************************** Synopsis [Writes a dot file representing the argument ZDDs.] Description [Writes a file representing the argument ZDDs in a format suitable for the graph drawing program dot. It returns 1 in case of success; 0 otherwise (e.g., out-of-memory, file system full). Cudd_zddDumpDot does not close the file: This is the caller responsibility. Cudd_zddDumpDot uses a minimal unique subset of the hexadecimal address of a node as name for it. If the argument inames is non-null, it is assumed to hold the pointers to the names of the inputs. Similarly for onames. Cudd_zddDumpDot uses the following convention to draw arcs: <ul> <li> solid line: THEN arcs; <li> dashed line: ELSE arcs. </ul> The dot options are chosen so that the drawing fits on a letter-size sheet. ] SideEffects [None] SeeAlso [Cudd_DumpDot Cudd_zddPrintDebug] ******************************************************************************/ int Cudd_zddDumpDot( DdManager * dd /* manager */, int n /* number of output nodes to be dumped */, DdNode ** f /* array of output nodes to be dumped */, char ** inames /* array of input names (or NULL) */, char ** onames /* array of output names (or NULL) */, FILE * fp /* pointer to the dump file */) { DdNode *support = NULL; DdNode *scan; int *sorted = NULL; int nvars = dd->sizeZ; st_table *visited = NULL; st_generator *gen; int retval; int i, j; int slots; DdNodePtr *nodelist; long refAddr, diff, mask; /* Build a bit array with the support of f. */ sorted = ALLOC(int,nvars); if (sorted == NULL) { dd->errorCode = CUDD_MEMORY_OUT; goto failure; } for (i = 0; i < nvars; i++) sorted[i] = 0; /* Take the union of the supports of each output function. */ for (i = 0; i < n; i++) { support = Cudd_Support(dd,f[i]); if (support == NULL) goto failure; cuddRef(support); scan = support; while (!cuddIsConstant(scan)) { sorted[scan->index] = 1; scan = cuddT(scan); } Cudd_RecursiveDeref(dd,support); } support = NULL; /* so that we do not try to free it in case of failure */ /* Initialize symbol table for visited nodes. */ visited = st_init_table(st_ptrcmp, st_ptrhash); if (visited == NULL) goto failure; /* Collect all the nodes of this DD in the symbol table. */ for (i = 0; i < n; i++) { retval = cuddCollectNodes(f[i],visited); if (retval == 0) goto failure; } /* Find how many most significant hex digits are identical ** in the addresses of all the nodes. Build a mask based ** on this knowledge, so that digits that carry no information ** will not be printed. This is done in two steps. ** 1. We scan the symbol table to find the bits that differ ** in at least 2 addresses. ** 2. We choose one of the possible masks. There are 8 possible ** masks for 32-bit integer, and 16 possible masks for 64-bit ** integers. */ /* Find the bits that are different. */ refAddr = (long) f[0]; diff = 0; gen = st_init_gen(visited); while (st_gen(gen, (char **) &scan, NULL)) { diff |= refAddr ^ (long) scan; } st_free_gen(gen); /* Choose the mask. */ for (i = 0; (unsigned) i < 8 * sizeof(long); i += 4) { mask = (1 << i) - 1; if (diff <= mask) break; } /* Write the header and the global attributes. */ retval = fprintf(fp,"digraph \"ZDD\" {\n"); if (retval == EOF) return(0); retval = fprintf(fp, "size = \"7.5,10\"\ncenter = true;\nedge [dir = none];\n"); if (retval == EOF) return(0); /* Write the input name subgraph by scanning the support array. */ retval = fprintf(fp,"{ node [shape = plaintext];\n"); if (retval == EOF) goto failure; retval = fprintf(fp," edge [style = invis];\n"); if (retval == EOF) goto failure; /* We use a name ("CONST NODES") with an embedded blank, because ** it is unlikely to appear as an input name. */ retval = fprintf(fp," \"CONST NODES\" [style = invis];\n"); if (retval == EOF) goto failure; for (i = 0; i < nvars; i++) { if (sorted[dd->invpermZ[i]]) { if (inames == NULL) { retval = fprintf(fp,"\" %d \" -> ", dd->invpermZ[i]); } else { retval = fprintf(fp,"\" %s \" -> ", inames[dd->invpermZ[i]]); } if (retval == EOF) goto failure; } } retval = fprintf(fp,"\"CONST NODES\"; \n}\n"); if (retval == EOF) goto failure; /* Write the output node subgraph. */ retval = fprintf(fp,"{ rank = same; node [shape = box]; edge [style = invis];\n"); if (retval == EOF) goto failure; for (i = 0; i < n; i++) { if (onames == NULL) { retval = fprintf(fp,"\"F%d\"", i); } else { retval = fprintf(fp,"\" %s \"", onames[i]); } if (retval == EOF) goto failure; if (i == n - 1) { retval = fprintf(fp,"; }\n"); } else { retval = fprintf(fp," -> "); } if (retval == EOF) goto failure; } /* Write rank info: All nodes with the same index have the same rank. */ for (i = 0; i < nvars; i++) { if (sorted[dd->invpermZ[i]]) { retval = fprintf(fp,"{ rank = same; "); if (retval == EOF) goto failure; if (inames == NULL) { retval = fprintf(fp,"\" %d \";\n", dd->invpermZ[i]); } else { retval = fprintf(fp,"\" %s \";\n", inames[dd->invpermZ[i]]); } if (retval == EOF) goto failure; nodelist = dd->subtableZ[i].nodelist; slots = dd->subtableZ[i].slots; for (j = 0; j < slots; j++) { scan = nodelist[j]; while (scan != NULL) { if (st_is_member(visited,(char *) scan)) { retval = fprintf(fp,"\"%lx\";\n", (mask & (long) scan) / sizeof(DdNode)); if (retval == EOF) goto failure; } scan = scan->next; } } retval = fprintf(fp,"}\n"); if (retval == EOF) goto failure; } } /* All constants have the same rank. */ retval = fprintf(fp, "{ rank = same; \"CONST NODES\";\n{ node [shape = box]; "); if (retval == EOF) goto failure; nodelist = dd->constants.nodelist; slots = dd->constants.slots; for (j = 0; j < slots; j++) { scan = nodelist[j]; while (scan != NULL) { if (st_is_member(visited,(char *) scan)) { retval = fprintf(fp,"\"%lx\";\n", (mask & (long) scan) / sizeof(DdNode)); if (retval == EOF) goto failure; } scan = scan->next; } } retval = fprintf(fp,"}\n}\n"); if (retval == EOF) goto failure; /* Write edge info. */ /* Edges from the output nodes. */ for (i = 0; i < n; i++) { if (onames == NULL) { retval = fprintf(fp,"\"F%d\"", i); } else { retval = fprintf(fp,"\" %s \"", onames[i]); } if (retval == EOF) goto failure; retval = fprintf(fp," -> \"%lx\" [style = solid];\n", (mask & (long) f[i]) / sizeof(DdNode)); if (retval == EOF) goto failure; } /* Edges from internal nodes. */ for (i = 0; i < nvars; i++) { if (sorted[dd->invpermZ[i]]) { nodelist = dd->subtableZ[i].nodelist; slots = dd->subtableZ[i].slots; for (j = 0; j < slots; j++) { scan = nodelist[j]; while (scan != NULL) { if (st_is_member(visited,(char *) scan)) { retval = fprintf(fp, "\"%lx\" -> \"%lx\";\n", (mask & (long) scan) / sizeof(DdNode), (mask & (long) cuddT(scan)) / sizeof(DdNode)); if (retval == EOF) goto failure; retval = fprintf(fp, "\"%lx\" -> \"%lx\" [style = dashed];\n", (mask & (long) scan) / sizeof(DdNode), (mask & (long) cuddE(scan)) / sizeof(DdNode)); if (retval == EOF) goto failure; } scan = scan->next; } } } } /* Write constant labels. */ nodelist = dd->constants.nodelist; slots = dd->constants.slots; for (j = 0; j < slots; j++) { scan = nodelist[j]; while (scan != NULL) { if (st_is_member(visited,(char *) scan)) { retval = fprintf(fp,"\"%lx\" [label = \"%g\"];\n", (mask & (long) scan) / sizeof(DdNode), cuddV(scan)); if (retval == EOF) goto failure; } scan = scan->next; } } /* Write trailer and return. */ retval = fprintf(fp,"}\n"); if (retval == EOF) goto failure; st_free_table(visited); FREE(sorted); return(1); failure: if (sorted != NULL) FREE(sorted); if (support != NULL) Cudd_RecursiveDeref(dd,support); if (visited != NULL) st_free_table(visited); return(0); } /* end of Cudd_zddDumpBlif */
/**Function******************************************************************** Synopsis [Genetic algorithm for DD reordering.] Description [Genetic algorithm for DD reordering. The two children of a crossover will be stored in storedd[popsize] and storedd[popsize+1] --- the last two slots in the storedd array. (This will make comparisons and replacement easy.) Returns 1 in case of success; 0 otherwise.] SideEffects [None] SeeAlso [] ******************************************************************************/ int cuddGa( DdManager * table /* manager */, int lower /* lowest level to be reordered */, int upper /* highest level to be reorderded */) { int i,n,m; /* dummy/loop vars */ int index; #ifdef DD_STATS double average_fitness; #endif int small; /* index of smallest DD in population */ /* Do an initial sifting to produce at least one reasonable individual. */ if (!cuddSifting(table,lower,upper)) return(0); /* Get the initial values. */ numvars = upper - lower + 1; /* number of variables to be reordered */ if (table->populationSize == 0) { popsize = 3 * numvars; /* population size is 3 times # of vars */ if (popsize > 120) { popsize = 120; /* Maximum population size is 120 */ } } else { popsize = table->populationSize; /* user specified value */ } if (popsize < 4) popsize = 4; /* enforce minimum population size */ /* Allocate population table. */ storedd = ALLOC(int,(popsize+2)*(numvars+1)); if (storedd == NULL) { table->errorCode = CUDD_MEMORY_OUT; return(0); } /* Initialize the computed table. This table is made up of two data ** structures: A hash table with the key given by the order, which says ** if a given order is present in the population; and the repeat ** vector, which says how many copies of a given order are stored in ** the population table. If there are multiple copies of an order, only ** one has a repeat count greater than 1. This copy is the one pointed ** by the computed table. */ repeat = ALLOC(int,popsize); if (repeat == NULL) { table->errorCode = CUDD_MEMORY_OUT; FREE(storedd); return(0); } for (i = 0; i < popsize; i++) { repeat[i] = 0; } computed = st_init_table(array_compare,array_hash); if (computed == NULL) { table->errorCode = CUDD_MEMORY_OUT; FREE(storedd); FREE(repeat); return(0); } /* Copy the current DD and its size to the population table. */ for (i = 0; i < numvars; i++) { STOREDD(0,i) = table->invperm[i+lower]; /* order of initial DD */ } STOREDD(0,numvars) = table->keys - table->isolated; /* size of initial DD */ /* Store the initial order in the computed table. */ if (st_insert(computed,(char *)storedd,(char *) 0) == ST_OUT_OF_MEM) { FREE(storedd); FREE(repeat); st_free_table(computed); return(0); } repeat[0]++; /* Insert the reverse order as second element of the population. */ for (i = 0; i < numvars; i++) { STOREDD(1,numvars-1-i) = table->invperm[i+lower]; /* reverse order */ } /* Now create the random orders. make_random fills the population ** table with random permutations. The successive loop builds and sifts ** the DDs for the reverse order and each random permutation, and stores ** the results in the computed table. */ if (!make_random(table,lower)) { table->errorCode = CUDD_MEMORY_OUT; FREE(storedd); FREE(repeat); st_free_table(computed); return(0); } for (i = 1; i < popsize; i++) { result = build_dd(table,i,lower,upper); /* build and sift order */ if (!result) { FREE(storedd); FREE(repeat); st_free_table(computed); return(0); } if (st_lookup_int(computed,(char *)&STOREDD(i,0),&index)) { repeat[index]++; } else { if (st_insert(computed,(char *)&STOREDD(i,0),(char *)(long)i) == ST_OUT_OF_MEM) { FREE(storedd); FREE(repeat); st_free_table(computed); return(0); } repeat[i]++; } } #if 0 #ifdef DD_STATS /* Print the initial population. */ (void) fprintf(table->out,"Initial population after sifting\n"); for (m = 0; m < popsize; m++) { for (i = 0; i < numvars; i++) { (void) fprintf(table->out," %2d",STOREDD(m,i)); } (void) fprintf(table->out," : %3d (%d)\n", STOREDD(m,numvars),repeat[m]); } #endif #endif small = find_best(); #ifdef DD_STATS average_fitness = find_average_fitness(); (void) fprintf(table->out,"\nInitial population: best fitness = %d, average fitness %8.3f",STOREDD(small,numvars),average_fitness); #endif /* Decide how many crossovers should be tried. */ if (table->numberXovers == 0) { cross = 3*numvars; if (cross > 60) { /* do a maximum of 50 crossovers */ cross = 60; } } else { cross = table->numberXovers; /* use user specified value */ } /* Perform the crossovers to get the best order. */ for (m = 0; m < cross; m++) { if (!PMX(table->size)) { /* perform one crossover */ table->errorCode = CUDD_MEMORY_OUT; FREE(storedd); FREE(repeat); st_free_table(computed); return(0); } /* The offsprings are left in the last two entries of the ** population table. These are now considered in turn. */ for (i = popsize; i <= popsize+1; i++) { result = build_dd(table,i,lower,upper); /* build and sift child */ if (!result) { FREE(storedd); FREE(repeat); st_free_table(computed); return(0); } large = largest(); /* find the largest DD in population */ /* If the new child is smaller than the largest DD in the current ** population, enter it into the population in place of the ** largest DD. */ if (STOREDD(i,numvars) < STOREDD(large,numvars)) { /* Look up the largest DD in the computed table. ** Decrease its repetition count. If the repetition count ** goes to 0, remove the largest DD from the computed table. */ result = st_lookup_int(computed,(char *)&STOREDD(large,0), &index); if (!result) { FREE(storedd); FREE(repeat); st_free_table(computed); return(0); } repeat[index]--; if (repeat[index] == 0) { int *pointer = &STOREDD(index,0); result = st_delete(computed, (char **)&pointer,NULL); if (!result) { FREE(storedd); FREE(repeat); st_free_table(computed); return(0); } } /* Copy the new individual to the entry of the ** population table just made available and update the ** computed table. */ for (n = 0; n <= numvars; n++) { STOREDD(large,n) = STOREDD(i,n); } if (st_lookup_int(computed,(char *)&STOREDD(large,0), &index)) { repeat[index]++; } else { if (st_insert(computed,(char *)&STOREDD(large,0), (char *)(long)large) == ST_OUT_OF_MEM) { FREE(storedd); FREE(repeat); st_free_table(computed); return(0); } repeat[large]++; } } } } /* Find the smallest DD in the population and build it; ** that will be the result. */ small = find_best(); /* Print stats on the final population. */ #ifdef DD_STATS average_fitness = find_average_fitness(); (void) fprintf(table->out,"\nFinal population: best fitness = %d, average fitness %8.3f",STOREDD(small,numvars),average_fitness); #endif /* Clean up, build the result DD, and return. */ st_free_table(computed); computed = NULL; result = build_dd(table,small,lower,upper); FREE(storedd); FREE(repeat); return(result); } /* end of cuddGa */
st_table* st_init_strtable(void) { return st_init_table(&type_strhash); }
st_table* st_init_numtable(void) { return st_init_table(&type_numhash); }
void avro_memoize_init(avro_memoize_t *mem) { memset(mem, 0, sizeof(avro_memoize_t)); mem->cache = st_init_table(&avro_memoize_hash_type); }
st_table* st_init_strcasetable(void) { return st_init_table(&type_strcasehash); }
st_table* js_st_table_new() { return st_init_table(&js_string_st_type); }