diff --git a/automaton.py b/automaton.py index afb4e9f..ad8e62f 100755 --- a/automaton.py +++ b/automaton.py @@ -1,9 +1,9 @@ #!/usr/bin/python # 0 is infinity -coxeter_matrix = [[1, 2, 3], - [2, 1, 0], - [3, 0, 1]] +coxeter_matrix = [[1, 5, 5], + [5, 1, 5], + [5, 5, 1]] import math from copy import copy @@ -26,6 +26,18 @@ class Root: def __copy__(self): return Root(self.id, self.rank, self.depth, self.v.copy(), self.neighbors.copy()) +class Groupelement: + def __init__(self, id, rank, word): + self.id = id + self.rank = rank + self.word = word + self.length = len(word) + self.left = [None]*rank + self.right = [None]*rank + self.node = None + self.lex_node = None + self.inverse = None + # compute where alpha_k is one of the simple roots and beta any root def form_gen_root(form, k, root): rank = len(form) @@ -152,71 +164,84 @@ def generate_automaton(small_roots, lex_reduced = False): id += 1 edges.append((nodes[node], nodes[newnode], k)) - return (nodes, levels, edges) + graph = [[None for i in range(rank)] for j in range(len(nodes))] + for (fr,to,gen) in edges: + graph[fr][gen] = to + return graph # main program form = [[-math.cos(math.pi/m) if m > 0 else -1 for m in row] for row in coxeter_matrix] rank = len(coxeter_matrix) small_roots = find_small_roots(form) -nodes, levels, edges = generate_automaton(small_roots, lex_reduced = False) -nodes_lex, levels_lex, edges_lex = generate_automaton(small_roots, lex_reduced = True) +graph = generate_automaton(small_roots, lex_reduced = False) +graph_lex = generate_automaton(small_roots, lex_reduced = True) -#for r in small_roots: -# print((r.id,r.v,[n.id if n else -1 for n in r.neighbors])) +group = [Groupelement(0, rank, tuple())] +group[0].inverse = group[0] +group[0].node = group[0].lex_node = 0 -revedges = sorted(edges, key = lambda x:x[1]) - -adjlist = {} -revadjlist = {} -for efrom, eto, egen in edges: - if not efrom in adjlist: - adjlist[efrom] = [-1]*rank - adjlist[efrom][egen] = eto - if not eto in revadjlist: - revadjlist[eto] = [-1]*rank - revadjlist[eto][egen] = efrom - -words = [([], 0)] -depth = 0 i = 0 -while len(words[i][0]) < 10: - curword = words[i][0] - curnode = words[i][1] - for gen, nextnode in enumerate(adjlist[curnode]): - if nextnode < 0: - continue - nextword = curword.copy() - nextword.append(gen) - words.append((nextword, nextnode)) - i += 1 +size = 1 +while True: + current = group[i] + i+=1 -#print(sorted([x[1] for x in words])) -#print(["".join([chr(ord('a')+x) for x in w[0]]) for w in words]) + if current.length >= 10: + break -levelnodes = [] -for n,id in nodes.items(): - level = levels[n] - if level >= len(levelnodes): - levelnodes.append([]) - levelnodes[level].append(id) + for gen, new_lex_node in enumerate(graph_lex[current.lex_node]): + if new_lex_node: + new_element = Groupelement(size, rank, current.word + (gen,)) + new_element.lex_node = new_lex_node + new_element.node = graph[current.node][gen] + group.append(new_element) + size += 1 -print("digraph test123 {") -print('rankdir="TB"') + # w = w_1 t, w s = w_1 + # right multiplication (and left in case it does the same as a right mult) + for k in range(rank): -for (level,ns) in enumerate(levelnodes): - print('{rank = "same";', end = ' ') - for n in ns: - print("{id:d};".format(id=n), end = ' ') - print('}') + # if right multiplication by k decreases length + if not graph[new_element.node][k]: + word = list(new_element.word) + longer_suffix = group[0] + while len(word) > 0: + letter = word.pop() + shorter_suffix = longer_suffix + longer_suffix = shorter_suffix.left[letter] + # w = w_1 t w_2, w_2 s_k = t w_2 + # in the case word = [] longer_suffix could be None + # found it + if len(word) == 0 or shorter_suffix.right[k] == longer_suffix: + # finish word + while len(word) > 0: + shorter_suffix = shorter_suffix.left[word.pop()] + new_element.right[k] = shorter_suffix + shorter_suffix.right[k] = new_element -colors = ['red', 'darkgreen', 'blue', 'orange'] + # find inverse and left multiply + inverse = group[0] + word = list(new_element.word) + while len(word) > 0: + inverse = inverse.right[word.pop()] + if not inverse: + break + if inverse: + new_element.inverse = inverse + inverse.inverse = new_element + for k in range(rank): + if inverse.right[k]: + other = inverse.right[k].inverse + new_element.left[k] = other + other.left[k] = new_element + if new_element.right[k]: + other = new_element.right[k].inverse + inverse.left[k] = other + other.left[k] = inverse -for e in edges: - print("{fr:d} -> {to:d} [color={color}];".format( - fr = e[0], - to = e[1], - color = colors[e[2]])) - -print("}") +length = 0 +for i in range(1,len(group)+1): + if i == len(group) or group[i].length > group[i-1].length: + print("{number:d} elements up to length {length:d}".format(number = i, length = group[i-1].length))