#include #include #include #include "thickenings.h" #include "coxeter.h" #include "queue.h" #define SWAP(t, a, b) do {t tmp = a; a = b; b = tmp;} while(0) char *stringify_SLn1_permutation(int *word, int wordlength, int rank, char *str) { for(int i = 0; i <= rank; i++) str[i] = '1' + i; str[rank+1] = 0; for(int i = 0; i < wordlength; i++) { char tmp = str[word[i]]; str[word[i]] = str[word[i]+1]; str[word[i]+1] = tmp; } return str; } char *stringify_Onn1_permutation(int *word, int wordlength, int rank, char *str) { for(int i = 0; i <= rank*2; i++) str[i] = '1' + i; str[2*rank+1] = 0; for(int i = 0; i < wordlength; i++) { if(word[i] == 0) SWAP(char, str[rank-1], str[rank+1]); else { SWAP(char, str[rank-word[i]], str[rank-word[i]-1]); SWAP(char, str[rank+word[i]], str[rank+word[i]+1]); } } return str; } int main(int argc, const char *argv[]) { FILE *infile; struct stat st; int rank, order; semisimple_type_t type; int n; int *thickenings; signed char *level; node_t *graph; int *left, *right; int left_invariant, right_invariant; int left_invariant_wanted = 0, right_invariant_wanted = 0; edgelist_t *edgelists; int *words; queue_t queue; int current; int *seen; int *generators; int ngens; char string_buffer1[1000]; const char *alphabet = "abcdefghijklmnopqrstuvwxyz"; // parse arguments if(argc < 2) infile = stdin; else { if(strcmp(argv[1], "-") == 0) infile = stdin; else infile = fopen(argv[1], "rb"); if(argc >= 4) { if(strcmp(argv[2], "-") != 0) for(int i = 0; i < strlen(argv[2]); i++) left_invariant_wanted |= (1 << (argv[2][i] - 'a')); if(strcmp(argv[3], "-") != 0) for(int i = 0; i < strlen(argv[3]); i++) right_invariant_wanted |= (1 << (argv[3][i] - 'a')); } } fread(&type.n, sizeof(int), 1, infile); // we completely trust the input data type.factors = malloc(type.n * sizeof(simple_type_t)); fread(type.factors, sizeof(simple_type_t), type.n, infile); // get graph rank = coxeter_rank(type); order = coxeter_order(type); ERROR(strlen(alphabet) < rank, "The alphabet has too few letters\n"); graph = (node_t*)malloc(order*sizeof(node_t)); left = (int*)malloc(order*rank*sizeof(int)); right = (int*)malloc(order*rank*sizeof(int)); seen = (int*)malloc(order*sizeof(int)); generators = (int*)malloc(order*sizeof(int)); level = (signed char*)malloc(order*sizeof(int)); for(int i = 0; i < order; i++) { graph[i].left = &left[i*rank]; graph[i].right = &right[i*rank]; } prepare_graph(type, graph, &edgelists, &words); // finally do stuff int counter = 0; while(fread(level, sizeof(signed char), order, infile) == order) { /* if((counter++) % 100000 == 0) print_thickening(rank, order, level, 0, 0, 0, alphabet, stdout); continue; */ left_invariant = right_invariant = -1; // all 1s for(int j = 0; j < order; j++) { for(int k = 0; k < rank; k++) { if(level[j] > 0 && level[graph[j].left[k]] < 0 || level[j] < 0 && level[graph[j].left[k]] > 0) { left_invariant &= ~(1 << k); } if(level[j] > 0 && level[graph[j].right[k]] < 0 || level[j] < 0 && level[graph[j].right[k]] > 0) { right_invariant &= ~(1 << k); } } } if((~left_invariant & left_invariant_wanted) == 0 && (~right_invariant & right_invariant_wanted) == 0) { ngens = 0; memset(generators, 0, order*sizeof(int)); for(int j = 0; j < order; j++) { if(level[j] == HEAD_MARKER && generators[j] == 0) { // ignore the generator, if it is equivalent to one already seen ngens++; queue_init(&queue); queue_put(&queue, j); while((current = queue_get(&queue)) != -1) { if(generators[current] == 0) { // visit everyone only once generators[current] = ngens; for(int k = 0; k < rank; k++) { if(left_invariant & (1 << k)) queue_put(&queue, graph[current].left[k]); if(right_invariant & (1 << k)) queue_put(&queue, graph[current].right[k]); } } } } } printf("left: "); for(int j = 0; j < rank; j++) printf("%c", left_invariant & (1 << j) ? alphabet[j] : ' '); printf(" right: "); for(int j = 0; j < rank; j++) printf("%c", right_invariant & (1 << j) ? alphabet[j] : ' '); printf(" generators: "); memset(seen, 0, order*sizeof(int)); for(int i = 0; i < order; i++) { if(generators[i] != 0 && seen[generators[i]-1] == 0) { seen[generators[i]-1] = 1; // if(type.n == 1 && type.factors[0].series == 'A') // printf("%s ", stringify_SLn1_permutation(graph[i].word, graph[i].wordlength, rank, string_buffer1)); // else if(type.n == 1 && (type.factors[0].series == 'B' || type.factors[0].series == 'C')) // printf("%s ", stringify_Onn1_permutation(graph[i].word, graph[i].wordlength, rank, string_buffer1)); // else if(i == 0) printf("1 "); else printf("%s ", alphabetize(graph[i].word, graph[i].wordlength, alphabet, string_buffer1)); } } printf("\n"); } } if(infile != stdin) fclose(infile); // cleanup free(thickenings); free(edgelists); free(words); free(graph); free(left); free(right); free(seen); free(generators); free(type.factors); return 0; }