120 #define MODULUS1 2147483563
124 #define MODULUS2 2147483399
129 #define STAB_DIV (1 + (MODULUS1 - 1) / STAB_SIZE)
145 static char rcsid[]
DD_UNUSED =
"$Id: cuddUtil.c,v 1.81 2009/03/08 02:49:02 fabio Exp $";
159 #define bang(f) ((Cudd_IsComplement(f)) ? '!' : ' ')
229 for (i = 0; i < manager->
size; i++) list[i] = 2;
266 if (array == NULL)
return(0);
274 DdNode *implicant, *prime, *tmp;
277 if (implicant == NULL) {
309 for (q = 0; q < dd->
size; q++) {
312 (void) fprintf(dd->
out,
"0");
315 (void) fprintf(dd->
out,
"1");
318 (void) fprintf(dd->
out,
"-");
321 (void) fprintf(dd->
out,
"?");
324 (void) fprintf(dd->
out,
" 1\n");
340 (void) fprintf(dd->
out,
"\n");
395 (void) fprintf(dd->
out,
": is the NULL DD\n");
396 (void) fflush(dd->
out);
401 if ((f == azero || f == bzero) && pr > 0){
402 (void) fprintf(dd->
out,
": is the zero DD\n");
403 (void) fflush(dd->
out);
413 (void) fprintf(dd->
out,
": %d nodes %d leaves %g minterms\n",
414 nodes, leaves, minterms);
416 if (!
cuddP(dd, f)) retval = 0;
418 if (pr == 2 || pr > 3) {
420 (void) fprintf(dd->
out,
"\n");
422 (void) fflush(dd->
out);
551 for (j = 0; j < n; j++) {
554 for (j = 0; j < n; j++) {
591 max = pow(2.0,(
double)nvars);
752 if (support == NULL) {
756 for (i = 0; i <
size; i++) {
769 for (j = size - 1; j >= 0; j--) {
771 if (support[i] == 1) {
826 if (support == NULL) {
830 for (i = 0; i <
size; i++) {
869 if (support == NULL) {
873 for (i = 0; i <
size; i++) {
883 for (i = 0; i <
size; i++) {
884 if (support[i] == 1) count++;
921 if (support == NULL) {
925 for (i = 0; i <
size; i++) {
930 for (i = 0; i < n; i++) {
933 for (i = 0; i < n; i++) {
940 for (j = size - 1; j >= 0; j--) {
942 if (support[i] == 1) {
992 if (support == NULL) {
996 for (i = 0; i <
size; i++) {
1001 for (i = 0; i < n; i++) {
1004 for (i = 0; i < n; i++) {
1041 if (support == NULL) {
1045 for (i = 0; i <
size; i++) {
1050 for (i = 0; i < n; i++) {
1053 for (i = 0; i < n; i++) {
1059 for (i = 0; i <
size; i++) {
1060 if (support[i] == 1) count++;
1093 int *supportF, *supportG;
1101 if (supportF == NULL) {
1106 if (supportG == NULL) {
1111 for (i = 0; i <
size; i++) {
1123 *common = *onlyF = *onlyG =
DD_ONE(dd);
1125 for (j = size - 1; j >= 0; j--) {
1127 if (supportF[i] == 0 && supportG[i] == 0)
continue;
1130 if (supportG[i] == 0) {
1143 }
else if (supportF[i] == 0) {
1231 if (
string == NULL || node == NULL)
return(0);
1236 if (node == bzero)
return(0);
1238 for (i = 0; i < ddm->
size; i++)
string[i] = 2;
1242 if (node == one)
break;
1251 string[N->
index] = 0;
1253 }
else if (E == bzero) {
1254 string[N->
index] = 1;
1258 string[N->
index] = dir;
1305 if (
string == NULL) {
1310 if (indices == NULL) {
1316 for (i = 0; i < n; i++) {
1317 indices[i] = vars[i]->
index;
1328 for (i = 0; i < n; i++) {
1329 if (
string[indices[i]] == 2)
1330 string[indices[i]] = (char) ((
Cudd_Random() & 0x20) >> 5);
1337 for (i = n-1; i >= 0; i--) {
1407 int saveFlag, savePoint = -1, isSame;
1410 if ((
double)k > minterms) {
1416 if (
string == NULL) {
1420 for (i = 0; i < k; i++) {
1422 if (
string[i] == NULL) {
1423 for (j = 0; j < i; j++)
1429 for (j = 0; j <
size; j++)
string[i][j] =
'2';
1430 string[i][
size] =
'\0';
1433 if (indices == NULL) {
1435 for (i = 0; i < k; i++)
1441 for (i = 0; i < n; i++) {
1442 indices[i] = vars[i]->
index;
1447 for (i = 0; i < k; i++)
1457 for (i = 0; i < k; i++)
1464 if (saveString == NULL) {
1466 for (i = 0; i < k; i++)
1476 for (i = 0; i < k; i++) {
1479 for (j = i + 1; j < k; j++) {
1480 if (
strcmp(
string[i],
string[j]) == 0) {
1482 strcpy(saveString,
string[i]);
1488 if (
strcmp(
string[i], saveString) == 0) {
1492 for (j = i + 1; j < k; j++) {
1493 if (
strcmp(
string[i],
string[j]) == 0) {
1495 strcpy(saveString,
string[i]);
1503 for (j = 0; j < n; j++) {
1504 if (
string[i][indices[j]] ==
'2')
1505 string[i][indices[j]] =
1511 for (j = savePoint; j < i; j++) {
1512 if (
strcmp(
string[i],
string[j]) == 0) {
1518 strcpy(
string[i], saveString);
1520 for (j = 0; j < n; j++) {
1521 if (
string[i][indices[j]] ==
'2')
1522 string[i][indices[j]] =
1531 for (j = 0; j < n; j++) {
1532 if (
string[i][indices[j]] ==
'0') {
1539 for (l = 0; l < k; l++)
1543 for (l = 0; l <= i; l++)
1556 for (l = 0; l < k; l++)
1560 for (l = 0; l <= i; l++)
1568 for (i = 0; i < k; i++) {
1613 int *indices, *mask;
1627 if (weight == NULL) {
1631 for (i = 0; i <
size; i++) {
1634 for (i = 0; i < mvars; i++) {
1647 if (
string == NULL) {
1659 for (i = 0; i <
size; i++) {
1663 string[
size] =
'\0';
1665 if (indices == NULL) {
1672 for (i = 0; i < nvars; i++) {
1673 indices[i] = vars[i]->
index;
1688 for (i = 0; i < nvars; i++) {
1689 if (
string[indices[i]] ==
'0') {
1691 }
else if (
string[indices[i]] ==
'1') {
1695 if (newCube == NULL) {
1709 for (i = 0; i < mvars; i++) {
1710 mask[maskVars[i]->
index] = 1;
1712 for (i = 0; i < nvars; i++) {
1713 if (mask[indices[i]]) {
1714 if (
string[indices[i]] ==
'2') {
1715 if (weight[indices[i]] >= 0.0)
1716 string[indices[i]] =
'1';
1718 string[indices[i]] =
'0';
1721 string[indices[i]] =
'2';
1730 for (i = 0; i < nvars; i++) {
1731 if (
string[indices[i]] ==
'0') {
1733 }
else if (
string[indices[i]] ==
'1') {
1737 if (newCube == NULL) {
1805 DdNode *top, *treg, *next, *nreg, *prev, *preg;
1810 if (dd == NULL || f == NULL)
return(NULL);
1825 gen->
stack.stack = NULL;
1835 for (i = 0; i < nvars; i++) gen->
gen.
cubes.cube[i] = 2;
1842 if (gen->
stack.stack == NULL) {
1848 for (i = 0; i <= nvars; i++) gen->
stack.stack[i] = NULL;
1860 if (top != treg) next =
Cudd_Not(next);
1865 if (gen->
stack.sp == 1) {
1874 if (prev != preg) {next =
Cudd_Not(nreg);}
else {next = nreg;}
1922 DdNode *top, *treg, *next, *nreg, *prev, *preg;
1927 if (gen->
stack.sp == 1) {
1938 if (prev != preg) {next =
Cudd_Not(nreg);}
else {next = nreg;}
1956 if (top != treg) next =
Cudd_Not(next);
1961 if (gen->
stack.sp == 1) {
1970 if (prev != preg) {next =
Cudd_Not(nreg);}
else {next = nreg;}
2035 DdNode *implicant, *prime, *tmp;
2039 if (dd == NULL || l == NULL || u == NULL)
return(NULL);
2054 gen->
stack.stack = NULL;
2069 if (implicant == NULL) {
2077 if (prime == NULL) {
2134 DdNode *implicant, *prime, *tmp;
2142 if (implicant == NULL) {
2148 if (prime == NULL) {
2209 for (i = n - 1; i >= 0; i--) {
2210 if (phase == NULL || phase[i] != 0) {
2260 for (i = n - 1; i >= 0; i--) {
2261 if (phase == NULL || phase[i] != 0) {
2308 for (i = size - 1; i >= 0; i--) {
2309 if ((array[i] & ~1) == 0) {
2356 for (i = size-1; i >= 0; i--) {
2366 }
else if (e == zero) {
2409 if (dd == NULL || f == NULL)
return(NULL);
2426 if (gen->
stack.stack == NULL) {
2494 if (gen == NULL)
return(0);
2495 switch (gen->
type) {
2534 if (gen == NULL)
return(1);
2563 for (i = n - 1; i >= 0; i--) {
2617 double tetotal, nexttotal;
2618 double tesubtotal, nextsubtotal;
2619 double temeasured, nextmeasured;
2628 if (nvars == 0)
return(0.0);
2637 for (i = 0; i < nvars; i++) {
2642 for (j = 0; j < slots; j++) {
2644 while (scan != sentinel) {
2645 diff = (long) scan - (
long)
cuddT(scan);
2646 tesubtotal += (double)
ddAbs(diff);
2648 tesubtotal += (double)
ddAbs(diff);
2650 if (scan->
next != sentinel) {
2651 diff = (long) scan - (
long) scan->
next;
2652 nextsubtotal += (double)
ddAbs(diff);
2653 nextmeasured += 1.0;
2658 tetotal += tesubtotal;
2659 nexttotal += nextsubtotal;
2666 for (j = 0; j < slots; j++) {
2668 while (scan != NULL) {
2669 if (scan->
next != NULL) {
2670 diff = (long) scan - (
long) scan->
next;
2671 nextsubtotal += (double)
ddAbs(diff);
2672 nextmeasured += 1.0;
2677 nexttotal += nextsubtotal;
2679 return((tetotal + nexttotal) / (temeasured + nextmeasured));
2811 if (nvars == 0) nvars = dd->
size;
2815 density = minterms / (double) nodes;
2840 (void) fflush(stdout);
2841 (void) fprintf(stderr,
"\nunable to allocate %ld bytes\n", size);
2873 if (table == NULL)
return(0);
2875 retval =
dp2(dd,f,table);
2877 (void) fputc(
'\n',dd->
out);
2902 d = (
double *)value;
2955 if (retval != 1)
return(retval);
2988 if (table == NULL) {
3031 #if SIZEOF_VOID_P == 8
3032 (void) fprintf(dd->
out,
"ID = %c0x%lx\tvalue = %-9g\n",
bang(f),
3035 (void) fprintf(dd->
out,
"ID = %c0x%x\tvalue = %-9g\n",
bang(f),
3046 #if SIZEOF_VOID_P == 8
3047 (void) fprintf(dd->
out,
"ID = %c0x%lx\tindex = %d\tr = %d\t",
bang(f),
3050 (void) fprintf(dd->
out,
"ID = %c0x%x\tindex = %d\tr = %d\t",
bang(f),
3054 #if SIZEOF_VOID_P == 8
3055 (void) fprintf(dd->
out,
"ID = %c0x%lx\tindex = %u\t",
bang(f),
3058 (void) fprintf(dd->
out,
"ID = %c0x%x\tindex = %hu\t",
bang(f),
3064 (void) fprintf(dd->
out,
"T = %-9g\t",
cuddV(n));
3067 #if SIZEOF_VOID_P == 8
3078 (void) fprintf(dd->
out,
"E = %c%-9g\n",
bang(n),
cuddV(N));
3081 #if SIZEOF_VOID_P == 8
3089 if (
dp2(dd,N,t) == 0)
3126 if (node != background && node != zero) {
3127 for (i = 0; i < dd->
size; i++) {
3129 if (v == 0) (void) fprintf(dd->
out,
"0");
3130 else if (v == 1) (void) fprintf(dd->
out,
"1");
3131 else (
void) fprintf(dd->
out,
"-");
3133 (void) fprintf(dd->
out,
" % g\n",
cuddV(node));
3179 return(1 + tval + eval);
3248 int tval, eval, val;
3252 if (!
st__lookup(table,(
char *)node,(
char **)ptr)) {
3267 if ((
int) node->
index == i) {
3275 if (node->
ref > 1) {
3286 if (node->
ref > 1) {
3291 val = 1 + tval + eval;
3301 if (node->
ref > 1) {
3306 }
else if ((ptrT !=
cuddT(node) || ptrE !=
cuddE(node)) &&
3311 val = 1 + tval + eval;
3313 if (node->
ref > 1) {
3320 val = 1 + tval + eval;
3352 if (index >= unique->
size) {
3356 level = unique->
perm[index];
3366 looking = nodelist[posn];
3368 while (T <
cuddT(looking)) {
3371 while (T ==
cuddT(looking) && E <
cuddE(looking)) {
3374 if (
cuddT(looking) == T &&
cuddE(looking) == E) {
3413 if ((
int) node->
index == i)
return(tval);
3415 return(1 + tval + eval);
3445 double min, minT, minE;
3451 if (node == background || node == zero) {
3459 if (res->
ref == 0) {
3475 if (minE == (
double)CUDD_OUT_OF_MEM)
return((
double)CUDD_OUT_OF_MEM);
3485 return((
double)CUDD_OUT_OF_MEM);
3518 double paths, *ppaths, paths1, paths2;
3525 if (
st__lookup(table, (
const char *)node, (
char **)&dummy)) {
3533 if (paths1 == (
double)
CUDD_OUT_OF_MEM)
return((
double)CUDD_OUT_OF_MEM);
3535 if (paths2 == (
double)CUDD_OUT_OF_MEM)
return((
double)CUDD_OUT_OF_MEM);
3536 paths = paths1 + paths2;
3539 if (ppaths == NULL) {
3540 return((
double)CUDD_OUT_OF_MEM);
3547 return((
double)CUDD_OUT_OF_MEM);
3586 if (node == background || node == zero) {
3593 if (node->
ref != 1 &&
st__lookup(table, (
const char *)node, (
char **)&res)) {
3612 if (node->
ref > 1) {
3651 double paths, *ppaths, paths1, paths2;
3658 if (
st__lookup(table, (
const char *)N, (
char **)&dummy)) {
3669 if (paths1 == (
double)
CUDD_OUT_OF_MEM)
return((
double)CUDD_OUT_OF_MEM);
3671 if (paths2 == (
double)CUDD_OUT_OF_MEM)
return((
double)CUDD_OUT_OF_MEM);
3672 paths = paths1 + paths2;
3675 if (ppaths == NULL) {
3676 return((
double)CUDD_OUT_OF_MEM);
3683 return((
double)CUDD_OUT_OF_MEM);
3712 support[f->
index] = 1;
3780 return(tval + eval);
3810 if (
string == NULL || node == NULL)
return(0);
3815 if (nminterms == 0 || node == bzero)
return(1);
3829 if (min2 == (
double)CUDD_OUT_OF_MEM)
return(0);
3831 t = (int)((
double)nminterms * min1 / (min1 + min2) + 0.5);
3832 for (i = 0; i < t; i++)
3833 string[i][N->
index] =
'1';
3834 for (i = t; i < nminterms; i++)
3835 string[i][N->
index] =
'0';
3868 if (
string == NULL || node == NULL)
return(0);
3873 if (node == bzero)
return(0);
3875 if (node ==
DD_ONE(dd))
return(1);
3887 if (weight[N->
index] >= 0.0) {
3890 string[N->
index] =
'0';
3893 string[N->
index] =
'1';
3898 string[N->
index] =
'1';
3901 string[N->
index] =
'0';
DdNode * Cudd_bddPickOneMinterm(DdManager *dd, DdNode *f, DdNode **vars, int n)
void st__free_table(st__table *table)
static double ddCountPathsToNonZero(DdNode *N, st__table *table)
DdGen * Cudd_FirstPrime(DdManager *dd, DdNode *l, DdNode *u, int **cube)
DdNode * Cudd_SubsetWithMaskVars(DdManager *dd, DdNode *f, DdNode **vars, int nvars, DdNode **maskVars, int mvars)
int Cudd_NextNode(DdGen *gen, DdNode **node)
DdNode ** Cudd_bddPickArbitraryMinterms(DdManager *dd, DdNode *f, DdNode **vars, int n, int k)
static int cuddEstimateCofactor(DdManager *dd, st__table *table, DdNode *node, int i, int phase, DdNode **ptr)
int Cudd_SupportSize(DdManager *dd, DdNode *f)
int EpdCmp(const char *key1, const char *key2)
double Cudd_Density(DdManager *dd, DdNode *f, int nvars)
void Cudd_RecursiveDeref(DdManager *table, DdNode *n)
void Cudd_Srandom(long seed)
void Cudd_PrintVersion(FILE *fp)
#define CUDD_GEN_ZDD_PATHS
struct DdGen::@30::@32 cubes
void EpdCopy(EpDouble *from, EpDouble *to)
int st__insert(st__table *table, const char *key, char *value)
DdNode * Cudd_bddComputeCube(DdManager *dd, DdNode **vars, int *phase, int n)
DdNode * cuddUniqueConst(DdManager *unique, CUDD_VALUE_TYPE value)
static int ddPickArbitraryMinterms(DdManager *dd, DdNode *node, int nvars, int nminterms, char **string)
static int cuddEstimateCofactorSimple(DdNode *node, int i)
#define Cudd_IsConstant(node)
static int dp2(DdManager *dd, DdNode *f, st__table *t)
int Cudd_PrintDebug(DdManager *dd, DdNode *f, int n, int pr)
DdNode * Cudd_ReadLogicZero(DdManager *dd)
#define Cudd_Regular(node)
enum st__retval cuddStCountfree(char *key, char *value, char *arg)
static enum st__retval ddEpdFree(char *key, char *value, char *arg)
int st__ptrcmp(const char *, const char *)
int Cudd_EstimateCofactor(DdManager *dd, DdNode *f, int i, int phase)
void Cudd_OutOfMem(long size)
static DdNode * cuddUniqueLookup(DdManager *unique, int index, DdNode *T, DdNode *E)
int Cudd_DagSize(DdNode *node)
void cuddGetBranches(DdNode *g, DdNode **g1, DdNode **g0)
#define ABC_ALLOC(type, num)
DdGen * Cudd_FirstCube(DdManager *dd, DdNode *f, int **cube, CUDD_VALUE_TYPE *value)
DdNode * Cudd_bddIte(DdManager *dd, DdNode *f, DdNode *g, DdNode *h)
DdNode * Cudd_addComputeCube(DdManager *dd, DdNode **vars, int *phase, int n)
#define st__is_member(table, key)
DdGen * Cudd_FirstNode(DdManager *dd, DdNode *f, DdNode **node)
static DdNode * background
static int ddPickRepresentativeCube(DdManager *dd, DdNode *node, double *weight, char *string)
int Cudd_NextCube(DdGen *gen, int **cube, CUDD_VALUE_TYPE *value)
void EpdPow2(int n, EpDouble *epd)
for(p=first;p->value< newval;p=p->next)
DdNode * cuddHashTableLookup1(DdHashTable *hash, DdNode *f)
void EpdSubtract3(EpDouble *epd1, EpDouble *epd2, EpDouble *epd3)
int Cudd_ReadSize(DdManager *dd)
int Cudd_SharingSize(DdNode **nodeArray, int n)
double Cudd_CountPathsToNonZero(DdNode *node)
#define CUDD_GEN_NONEMPTY
DdNode * Cudd_LargestCube(DdManager *manager, DdNode *f, int *length)
static long shuffleSelect
double Cudd_CountMinterm(DdManager *manager, DdNode *node, int nvars)
st__table * st__init_table(st__compare_func_type compare, st__hash_func_type hash)
static long shuffleTable[STAB_SIZE]
double Cudd_AverageDistance(DdManager *dd)
int Cudd_bddPrintCover(DdManager *dd, DdNode *l, DdNode *u)
#define Cudd_IsComplement(node)
static char rcsid[] DD_UNUSED
void Cudd_SetEpsilon(DdManager *dd, CUDD_VALUE_TYPE ep)
DdNode * Cudd_bddMakePrime(DdManager *dd, DdNode *cube, DdNode *f)
void EpdAdd3(EpDouble *epd1, EpDouble *epd2, EpDouble *epd3)
int Cudd_BddToCubeArray(DdManager *dd, DdNode *cube, int *array)
DdNode * Cudd_Cofactor(DdManager *dd, DdNode *f, DdNode *g)
DdNode * Cudd_IndicesToCube(DdManager *dd, int *array, int n)
int Cudd_NextPrime(DdGen *gen, int **cube)
int Cudd_GenFree(DdGen *gen)
int Cudd_PrintMinterm(DdManager *manager, DdNode *node)
DdNode * Cudd_VectorSupport(DdManager *dd, DdNode **F, int n)
static void ddSupportStep(DdNode *f, int *support)
int Cudd_CountLeaves(DdNode *node)
double Cudd_CountPath(DdNode *node)
static void ddPrintMintermAux(DdManager *dd, DdNode *node, int *list)
#define ABC_NAMESPACE_IMPL_END
#define cuddIsConstant(node)
void EpdMakeZero(EpDouble *epd, int sign)
int Cudd_EpdCountMinterm(DdManager *manager, DdNode *node, int nvars, EpDouble *epd)
static double ddCountPathAux(DdNode *node, st__table *table)
int cuddP(DdManager *dd, DdNode *f)
ABC_NAMESPACE_IMPL_START EpDouble * EpdAlloc(void)
DdNodePtr * cuddNodeArray(DdNode *f, int *n)
static int ddDagInt(DdNode *n)
int st__foreach(st__table *table, enum st__retval(*func)(char *, char *, char *), char *arg)
void cuddHashTableQuit(DdHashTable *hash)
int Cudd_IsGenEmpty(DdGen *gen)
DdNode * Cudd_bddOr(DdManager *dd, DdNode *f, DdNode *g)
#define ABC_NAMESPACE_IMPL_START
DdNode * Cudd_ReadOne(DdManager *dd)
int Cudd_bddLeq(DdManager *dd, DdNode *f, DdNode *g)
int st__lookup(st__table *table, const char *key, char **value)
DdNode * Cudd_addIte(DdManager *dd, DdNode *f, DdNode *g, DdNode *h)
static int ddLeavesInt(DdNode *n)
int Cudd_bddPickOneCube(DdManager *ddm, DdNode *node, char *string)
int cuddHashTableInsert1(DdHashTable *hash, DdNode *f, DdNode *value, ptrint count)
DdNode * Cudd_CubeArrayToBdd(DdManager *dd, int *array)
struct DdGen::@30::@33 primes
DdNode * Cudd_bddIthVar(DdManager *dd, int i)
int * Cudd_VectorSupportIndex(DdManager *dd, DdNode **F, int n)
int st__add_direct(st__table *table, char *key, char *value)
#define Cudd_NotCond(node, c)
void EpdMultiply(EpDouble *epd1, double value)
DdNode * Cudd_bddAnd(DdManager *dd, DdNode *f, DdNode *g)
int cuddCollectNodes(DdNode *f, st__table *visited)
static void ddClearFlag(DdNode *f)
static double ddCountMintermAux(DdNode *node, double max, DdHashTable *table)
struct DdGen::@30::@34 nodes
DdHashTable * cuddHashTableInit(DdManager *manager, unsigned int keySize, unsigned int initSize)
void EpdFree(EpDouble *epd)
int Cudd_EstimateCofactorSimple(DdNode *node, int i)
int Cudd_VectorSupportSize(DdManager *dd, DdNode **F, int n)
int * Cudd_SupportIndex(DdManager *dd, DdNode *f)
static int ddEpdCountMintermAux(DdNode *node, EpDouble *max, EpDouble *epd, st__table *table)
int Cudd_ClassifySupport(DdManager *dd, DdNode *f, DdNode *g, DdNode **common, DdNode **onlyF, DdNode **onlyG)
DdNode * Cudd_Support(DdManager *dd, DdNode *f)
DdNode * cuddBddAndRecur(DdManager *manager, DdNode *f, DdNode *g)
int st__ptrhash(const char *, int)
DdNode * cuddUniqueInter(DdManager *unique, int index, DdNode *T, DdNode *E)
CUDD_VALUE_TYPE Cudd_ReadEpsilon(DdManager *dd)
static int cuddNodeArrayRecur(DdNode *f, DdNodePtr *table, int index)