-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcoxeter_todd.py
252 lines (177 loc) · 7.04 KB
/
coxeter_todd.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
debug = False
gens = ["a","b", "c",'d']
rels = [
['d','d'],
['a','a'],
['b','b'],
['c','c'],
['b','c','b','c','b','c'],
['b','d','b','d'],
['a','d','a','d'],
['a','c','a','c'],
['c','d','c','d','c','d'],
['a','b','a','b','a','b','a','b']
]
#rels = [ ['b', 'b'], ['b', 'c', 'b', 'c', 'b', 'c'],['a', 'c', 'a', 'c'], ['c', 'c'],['a', 'b', 'a', 'b', 'a', 'b', 'a', 'b','a','b'],['a', 'a']]
def compute_graph(gens, rels, coset):
def scan_index(index):
print("computed cosets: ", index)
coincidences = []
for rel in rels:
if debug:
print("---------------")
print(" ", index)
i = index
j = 1
for letter in rel:
if i in graphs[letter]:
if j == len(rel):
if graphs[letter][i] != index:
coincidences.append((graphs[letter][i], index))
if debug:
print("coincidence", index, graphs[letter][i])
graphs[letter][i] = index
if debug:
print(letter, index)
print("relator established!")
else:
i = graphs[letter][i]
if debug:
print(letter, i)
else:
if j == len(rel):
graphs[letter][i] = index
if debug:
print(letter, index)
print("relator established!")
else:
next = len(indices) + 1
graphs[letter][i] = next
i = next
indices.append(i)
if debug:
print(letter, i)
j += 1
if debug:
print(graphs)
for coincidence in coincidences:
process_coincidence(coincidence)
a = search_for_left_coincidence()
while a != None:
process_coincidence(a)
a= search_for_left_coincidence()
done = True
next = None
reached = {}
for gen in gens:
reached[gen] = set()
for i in indices:
for g in gens:
if i not in graphs[g]:
done = False
next = i
scan_index(next)
break
else:
reached[g].add(graphs[g][i])
for g in gens:
for i in indices:
if i not in reached[g]:
next = i
done = False
scan_index(next)
break
if done:
print('done!')
return
def substitute_index(b,a):
"""this function replaces all instances of b with a in the index set, as well as the graphs"""
print("replacing",b,a)
def process_coincidence(coincidence):
if debug:
print(indices, "before")
i,j = coincidence
x = min(i,j)
y = max(i,j)
#need to find a way to get rid of the coincidence/collapse the graph
#substitute_index(y,x)
for gen in gens:
#first, we replace all instances of {i:y} with {i:x}
for key in graphs[gen]:
if graphs[gen][key] == y:
graphs[gen][key] = x
#next, we simply remove all instances of {y:i}, because we already have these with {x:i} as these are left coincidences
if y in graphs[gen]: #it may already have been removed
graphs[gen].pop(y)
# Let y be the larger coincident index. After removing y, for all indices larger than y we must make the substitution i |-> i-1
#this substitution must also replace eery instance in the graphs.
indices.remove(y)
#after removing y, we have n-1 elements. However, those elements after y are labeled as i +1
#after relabeling, we should still have exactly n-1 elements
copy = indices[:]
index = 1
for a in copy:
if a > y:
for gen in gens:
for key in graphs[gen]:
if graphs[gen][key] == a:
graphs[gen][key] = a-1
if a in graphs[gen]:
graphs[gen][a-1] = graphs[gen][a]
graphs[gen].pop(a)
indices[index - 1] = index
if debug:
print("replaced",index , a-1)
index += 1
indices[0] = 1
def search_for_left_coincidence():
#this algorithm could be made more efficient, could be optimized with a co_graph
for gen in gens:
for key1 in graphs[gen]:
for key2 in graphs[gen]:
if key1 != key2 and graphs[gen][key1] == graphs[gen][key2]:
if debug:
print("coincidence found: ", (key1, key2))
return (key1, key2)
return None #if we return false, it means we have not found any coincidences
indices = [1]
graphs = {}
co_graphs = {}
for gen in gens:
graphs[gen] = {}
co_graphs[gen] = {}
for gen in coset:
graphs[gen][1] = 1
co_graphs[gen][1] = 1
scan_index(1)
print(indices)
return graphs,indices
def compute_words(graphs,indices,generators, shorten = True):
"""this function takes the graphs and creates a dictionary of indices to letters"""
indices_to_letters = {}
indices_to_letters[1] = "1"
def trace_graph(i, word):
que = {}
for g in generators:
que[graphs[g][i]] = g
for q in que:
if q not in indices_to_letters:
indices_to_letters[q] = que[q] + word
trace_graph(q, que[q] + word)
trace_graph(indices[0], "")
return indices_to_letters
def word_to_index(word, graphs, indices, generators):
"""word: should be a string of generators and 1
graphs: this is the dictionary of graphs
indices: this is the indices as an array
generators: these are the generators of the group.
All of these must be consistent in order for this to work
"""
pass
def test_run():
graphs, indices = compute_graph(gens, rels, [])
words = compute_words(graphs, indices, gens)
for i in words:
print(i,words[i])
if __name__ == "__main__":
test_run()