180 lines
4.6 KiB
C
180 lines
4.6 KiB
C
|
#include <stdio.h>
|
||
|
#include <string.h>
|
||
|
#include <sys/stat.h>
|
||
|
|
||
|
#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, *level;
|
||
|
node_t *graph;
|
||
|
int *left, *right;
|
||
|
int *left_invariant, *right_invariant;
|
||
|
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
|
||
|
infile = fopen(argv[1], "rb");
|
||
|
|
||
|
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));
|
||
|
left_invariant = (int*)malloc(rank*sizeof(int));
|
||
|
right_invariant = (int*)malloc(rank*sizeof(int));
|
||
|
seen = (int*)malloc(order*sizeof(int));
|
||
|
generators = (int*)malloc(order*sizeof(int));
|
||
|
level = (int*)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
|
||
|
|
||
|
while(fread(level, sizeof(int), order, infile) == order) {
|
||
|
|
||
|
for(int j = 0; j < rank; j++) {
|
||
|
left_invariant[j] = 1;
|
||
|
right_invariant[j] = 1;
|
||
|
}
|
||
|
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[k] = 0;
|
||
|
if(level[j] == 0 && level[graph[j].right[k]] != 0 || level[j] != 0 && level[graph[j].right[k]] == 0)
|
||
|
right_invariant[k] = 0;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
ngens = 0;
|
||
|
memset(generators, 0, order*sizeof(int));
|
||
|
for(int j = 0; j < order; j++) {
|
||
|
if(level[j] == -1 && 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[k])
|
||
|
queue_put(&queue, graph[current].left[k]);
|
||
|
if(right_invariant[k])
|
||
|
queue_put(&queue, graph[current].right[k]);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
printf("left: ");
|
||
|
for(int j = 0; j < rank; j++)
|
||
|
printf("%c", left_invariant[j] ? alphabet[j] : ' ');
|
||
|
printf(" right: ");
|
||
|
for(int j = 0; j < rank; j++)
|
||
|
printf("%c", right_invariant[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(right_invariant);
|
||
|
free(left_invariant);
|
||
|
free(seen);
|
||
|
free(generators);
|
||
|
free(type.factors);
|
||
|
|
||
|
return 0;
|
||
|
}
|