/* ----------------------------------------------------------------------- Given a list of balanced functions, try to build VARS-bit permutations out of them. This does hillclimbing: it replaces one variable at a time, always trying to build a bigger list of variables that work together. Eventually it has VARS variables that all work together, and every replacement forms a new complete permutation. ----------------------------------------------------------------------- */ #include #include #include typedef unsigned long int u4; typedef struct ranctx { u4 a; u4 b; u4 c; u4 d; } ranctx; #define rot(x,k) ((x<>(32-k))) u4 ranval( ranctx *x ) { u4 e = x->a - rot(x->b, 27); x->a = x->b ^ rot(x->c, 17); x->b = x->c + x->d; x->c = x->d + e; x->d = e + x->a; return e; } /* set a bit in a bitarray */ static void bits(char *x, int off) { x[off/8] |= (1 << (off & 7)); } /* clear a bit in a bitarray */ static void bitc(char *x, int off) { x[off/8] &= (~(unsigned char)(1 << (off & 7))); } /* read a bit in a bitarray */ static int bit(char *x, int off) { return ((x[off/8] & (1 << (off & 7))) != 0); } static bitclear(char *x, int length) { int i; for (i=0; i>1 ) & 0x55555555); c = (c & 0x33333333) + ((c>>2 ) & 0x33333333); c = (c & 0x0f0f0f0f) + ((c>>4 ) & 0x0f0f0f0f); c = (c & 0x00ff00ff) + ((c>>8 ) & 0x00ff00ff); c = (c & 0x0000ffff) + ((c>>16) & 0x0000ffff); return (int)c; } /* one of all possible balanced functions */ typedef struct balance { int loglen; /* loglen of truth table, number of variables in function */ char *truth; /* truth table for this function */ } balance; #define VARS 8 #define VALUES (1<source->loglen); /* number of inputs */ for (j=0; jsource->loglen; ++j) { if (j != 0) printf(","); printf("%2d", map[i]->offset[j]); } printf(" %.*s", (1 << map[i]->source->loglen), map[i]->source->truth); printf("\n"); } printf("\n"); } /* * Given a source balanced function and a mapping of source bits to * slice bits, fill in the fields of a slice. */ void fillslice(slice *s, int mapping) { char *x = s->source->truth; int loglen = s->source->loglen; int i, j; /* fill in the offsets */ for (i=0, j=0; ioffset[j++] = i; } } /* fill in the truth table */ bitclear(s->truth, VALUES); for (i=0; i < VALUES; ++i) { int k; for (j=0, k=0; joffset[j])) { k |= (1<source->truth[k] == '1') { bits(s->truth, i); } } } /* * Return 1 if the map so far is balanced, 0 otherwise */ int testslice(slice *map[VARS], int slices) { int count[VALUES]; int len = VALUES; int values = (1 << slices); int limit = len / values; int i; for (i=0; itruth, i)) { q |= (1< limit) { return 0; } } return 1; } /* * Generate permutations from balanced functions */ int driver( balance **array, size_t arraylen, slice *map[VARS], int *count, ranctx *rctx) { int offset = ranval(rctx)%arraylen; int i; /* set up a new trial slice */ map[*count]->source = array[offset]; i=((1<loglen)-1); /* iterate over all ways of using this truth table */ while (i < VALUES) { int replace = ranval(rctx) % *count; /* old slice to replace */ slice *tempslice; int j, k; fillslice(map[*count], i); /* fill in the slice */ /* use the new slice */ tempslice = map[replace]; map[replace] = map[*count]; map[*count] = tempslice; /* test if the map is still balanced */ if (testslice(map, *count)) { if (*count < VARS && testslice(map, *count+1)) { ++*count; printf("count is now %d\n", *count); } if (*count == VARS) { /* we found a permutation, print it out */ showperm(map); } /* This slice is at least as good as the old one, keep it */ return; } /* restore the old slice */ tempslice = map[replace]; map[replace] = map[*count]; map[*count] = tempslice; /* increment i */ for (j=0; j= VALUES) { return; } i += (1<loglen = loglen; array[i]->truth = (char *)malloc(len); memcpy(array[i]->truth, &buf[5], len); ++i; } } fclose(f); f = (FILE *)0; printf("read everything in\n"); /* recursively build all permutations */ count = 1; map[0]->source = array[0]; fillslice(map[0], (1<source->loglen)-1); for (;;) { driver(array, arraylen, map, &count, &rctx); } }