passagemath-groups 10.6.45__cp314-cp314-macosx_13_0_arm64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. passagemath_groups/.dylibs/libgap.10.dylib +0 -0
  2. passagemath_groups/.dylibs/libgmp.10.dylib +0 -0
  3. passagemath_groups/.dylibs/libreadline.8.2.dylib +0 -0
  4. passagemath_groups/.dylibs/libz.1.3.1.dylib +0 -0
  5. passagemath_groups/__init__.py +3 -0
  6. passagemath_groups-10.6.45.dist-info/METADATA +113 -0
  7. passagemath_groups-10.6.45.dist-info/RECORD +40 -0
  8. passagemath_groups-10.6.45.dist-info/WHEEL +6 -0
  9. passagemath_groups-10.6.45.dist-info/top_level.txt +3 -0
  10. sage/all__sagemath_groups.py +21 -0
  11. sage/geometry/all__sagemath_groups.py +1 -0
  12. sage/geometry/palp_normal_form.cpython-314-darwin.so +0 -0
  13. sage/geometry/palp_normal_form.pyx +401 -0
  14. sage/groups/abelian_gps/all.py +25 -0
  15. sage/groups/all.py +5 -0
  16. sage/groups/all__sagemath_groups.py +32 -0
  17. sage/groups/artin.py +1074 -0
  18. sage/groups/braid.py +3806 -0
  19. sage/groups/cactus_group.py +1001 -0
  20. sage/groups/cubic_braid.py +2052 -0
  21. sage/groups/finitely_presented.py +1896 -0
  22. sage/groups/finitely_presented_catalog.py +27 -0
  23. sage/groups/finitely_presented_named.py +592 -0
  24. sage/groups/fqf_orthogonal.py +579 -0
  25. sage/groups/free_group.py +944 -0
  26. sage/groups/group_exp.py +360 -0
  27. sage/groups/group_semidirect_product.py +504 -0
  28. sage/groups/kernel_subgroup.py +231 -0
  29. sage/groups/lie_gps/all.py +1 -0
  30. sage/groups/lie_gps/catalog.py +8 -0
  31. sage/groups/lie_gps/nilpotent_lie_group.py +945 -0
  32. sage/groups/misc_gps/all.py +1 -0
  33. sage/groups/misc_gps/misc_groups.py +11 -0
  34. sage/groups/misc_gps/misc_groups_catalog.py +33 -0
  35. sage/groups/raag.py +866 -0
  36. sage/groups/semimonomial_transformations/all.py +1 -0
  37. sage/groups/semimonomial_transformations/semimonomial_transformation.cpython-314-darwin.so +0 -0
  38. sage/groups/semimonomial_transformations/semimonomial_transformation.pxd +9 -0
  39. sage/groups/semimonomial_transformations/semimonomial_transformation.pyx +346 -0
  40. sage/groups/semimonomial_transformations/semimonomial_transformation_group.py +512 -0
sage/groups/artin.py ADDED
@@ -0,0 +1,1074 @@
1
+ # sage_setup: distribution = sagemath-groups
2
+ """
3
+ Artin Groups
4
+
5
+ Artin groups are implemented as a particular case of finitely presented
6
+ groups. For finite-type Artin groups, there is a specific left normal
7
+ form using the Garside structure associated to the lift the long element
8
+ of the corresponding Coxeter group.
9
+
10
+ AUTHORS:
11
+
12
+ - Travis Scrimshaw (2018-02-05): Initial version
13
+ - Travis Scrimshaw (2025-01-30): Allowed general construction; implemented
14
+ general Burau representation
15
+
16
+ .. TODO::
17
+
18
+ Implement affine type Artin groups with their well-known embeddings into
19
+ the classical braid group.
20
+ """
21
+
22
+ # ****************************************************************************
23
+ # Copyright (C) 2018-2025 Travis Scrimshaw <tcscrims at gmail.com>
24
+ #
25
+ # This program is free software: you can redistribute it and/or modify
26
+ # it under the terms of the GNU General Public License as published by
27
+ # the Free Software Foundation, either version 2 of the License, or
28
+ # (at your option) any later version.
29
+ # http://www.gnu.org/licenses/
30
+ # *****************************************************************************
31
+
32
+ from sage.combinat.root_system.coxeter_matrix import CoxeterMatrix
33
+ from sage.combinat.root_system.coxeter_group import CoxeterGroup
34
+ from sage.groups.free_group import FreeGroup
35
+ from sage.groups.finitely_presented import FinitelyPresentedGroup, FinitelyPresentedGroupElement
36
+ from sage.misc.cachefunc import cached_method
37
+ from sage.misc.lazy_attribute import lazy_attribute
38
+ from sage.rings.infinity import Infinity
39
+ from sage.structure.richcmp import richcmp, rich_to_bool
40
+ from sage.structure.unique_representation import UniqueRepresentation
41
+
42
+
43
+ class ArtinGroupElement(FinitelyPresentedGroupElement):
44
+ """
45
+ An element of an Artin group.
46
+
47
+ It is a particular case of element of a finitely presented group.
48
+
49
+ EXAMPLES::
50
+
51
+ sage: # needs sage.rings.number_field
52
+ sage: A.<s1,s2,s3> = ArtinGroup(['B',3])
53
+ sage: A
54
+ Artin group of type ['B', 3]
55
+ sage: s1 * s2 / s3 / s2
56
+ s1*s2*s3^-1*s2^-1
57
+ sage: A((1, 2, -3, -2))
58
+ s1*s2*s3^-1*s2^-1
59
+ """
60
+ def _latex_(self):
61
+ r"""
62
+ Return a LaTeX representation of ``self``.
63
+
64
+ OUTPUT: string; a valid LaTeX math command sequence
65
+
66
+ TESTS::
67
+
68
+ sage: A = ArtinGroup(['B', 3]) # needs sage.rings.number_field
69
+ sage: b = A([1, 2, 3, -1, 2, -3]) # needs sage.rings.number_field
70
+ sage: b._latex_() # needs sage.rings.number_field
71
+ '\\sigma_{1}\\sigma_{2}\\sigma_{3}\\sigma_{1}^{-1}\\sigma_{2}\\sigma_{3}^{-1}'
72
+
73
+ sage: # needs sage.combinat sage.graphs
74
+ sage: B = BraidGroup(4)
75
+ sage: b = B([1, 2, 3, -1, 2, -3])
76
+ sage: b._latex_()
77
+ '\\sigma_{1}\\sigma_{2}\\sigma_{3}\\sigma_{1}^{-1}\\sigma_{2}\\sigma_{3}^{-1}'
78
+ sage: B.one()._latex_()
79
+ '1'
80
+ """
81
+ word = self.Tietze()
82
+ if not word:
83
+ return '1'
84
+ return ''.join(r"\sigma_{%s}^{-1}" % (-i) if i < 0 else r"\sigma_{%s}" % i
85
+ for i in word)
86
+
87
+ def exponent_sum(self):
88
+ """
89
+ Return the exponent sum of ``self``.
90
+
91
+ OUTPUT: integer
92
+
93
+ EXAMPLES::
94
+
95
+ sage: # needs sage.rings.number_field
96
+ sage: A = ArtinGroup(['E',6])
97
+ sage: b = A([1, 4, -3, 2])
98
+ sage: b.exponent_sum()
99
+ 2
100
+ sage: b = A([])
101
+ sage: b.exponent_sum()
102
+ 0
103
+
104
+ sage: # needs sage.combinat sage.graphs
105
+ sage: B = BraidGroup(5)
106
+ sage: b = B([1, 4, -3, 2])
107
+ sage: b.exponent_sum()
108
+ 2
109
+ sage: b = B([])
110
+ sage: b.exponent_sum()
111
+ 0
112
+ """
113
+ return sum(s.sign() for s in self.Tietze())
114
+
115
+ def coxeter_group_element(self, W=None):
116
+ """
117
+ Return the corresponding Coxeter group element under the natural
118
+ projection.
119
+
120
+ INPUT:
121
+
122
+ - ``W`` -- (default: ``self.parent().coxeter_group()``) the image
123
+ Coxeter group
124
+
125
+ OUTPUT: an element of the Coxeter group ``W``
126
+
127
+ EXAMPLES::
128
+
129
+ sage: # needs sage.rings.number_field
130
+ sage: B.<s1,s2,s3> = ArtinGroup(['B',3])
131
+ sage: b = s1 * s2 / s3 / s2
132
+ sage: b1 = b.coxeter_group_element(); b1
133
+ [ 1 -1 0]
134
+ [ 2 -1 0]
135
+ [ a -a 1]
136
+ sage: b.coxeter_group_element().reduced_word()
137
+ [1, 2, 3, 2]
138
+
139
+ sage: # neeeds sage.combinat sage.rings.number_field
140
+ sage: A.<s1,s2,s3> = ArtinGroup(['A',3])
141
+ sage: c = s1 * s2 *s3
142
+ sage: c1 = c.coxeter_group_element(); c1
143
+ [4, 1, 2, 3]
144
+ sage: c1.reduced_word()
145
+ [3, 2, 1]
146
+ sage: c.coxeter_group_element(W=SymmetricGroup(4))
147
+ (1,4,3,2)
148
+
149
+ sage: # needs sage.graphs
150
+ sage: A.<s1,s2,s3> = BraidGroup(4)
151
+ sage: c = s1 * s2 * s3^-1
152
+ sage: c0 = c.coxeter_group_element(); c0
153
+ [4, 1, 2, 3]
154
+ sage: c1 = c.coxeter_group_element(W=SymmetricGroup(4)); c1
155
+ (1,4,3,2)
156
+
157
+ From an element of the Coxeter group it is possible to recover
158
+ the image by the standard section to the Artin group::
159
+
160
+ sage: # needs sage.rings.number_field
161
+ sage: B(b1)
162
+ s1*s2*s3*s2
163
+
164
+ sage: # needs sage.graphs
165
+ sage: A(c0)
166
+ s1*s2*s3
167
+ sage: A(c0) == A(c1)
168
+ True
169
+ """
170
+ if W is None:
171
+ W = self.parent().coxeter_group()
172
+ s = W.simple_reflections()
173
+ In = W.index_set()
174
+ return W.prod(s[In[abs(i) - 1]] for i in self.Tietze())
175
+
176
+ def burau_matrix(self, var='t'):
177
+ r"""
178
+ Return the Burau matrix of the Artin group element.
179
+
180
+ Following [BQ2024]_, the (generalized) Burau representation
181
+ of an Artin group is defined by deforming the reflection
182
+ representation of the corresponding Coxeter group. However,
183
+ we substitute `q \mapsto -t` from [BQ2024]_ to match one of
184
+ the unitary (reduced) Burau representations of the braid group
185
+ (see :meth:`sage.groups.braid.Braid.burau_matrix()` for details.)
186
+
187
+ More precisely, let `(m_{ij})_{i,j \in I}` be the
188
+ :meth:`Coxeter matrix<coxeter_matrix>`. Then the action is
189
+ given on the basis `(\alpha_1, \ldots \alpha_n)` (corresponding
190
+ to the reflection representation of the corresponding
191
+ :meth:`Coxeter group<coxeter_group>`) by
192
+
193
+ .. MATH::
194
+
195
+ \sigma_i(\alpha_j) = \alpha_j
196
+ - \langle \alpha_i, \alpha_j \rangle_q \alpha_i,
197
+ \qquad \text{ where }
198
+ \langle \alpha_i, \alpha_j \rangle_q := \begin{cases}
199
+ 1 + t^2 & \text{if } i = j, \\
200
+ -2 t \cos(\pi/m_{ij}) & \text{if } i \neq j.
201
+ \end{cases}.
202
+
203
+ By convention `\cos(\pi/\infty) = 1`. Note that the inverse of the
204
+ generators act by `\sigma_i^{-1}(\alpha_j) = \alpha_j - q^{-2}
205
+ \langle \alpha_j, \alpha_i \rangle_q \alpha_i`.
206
+
207
+ INPUT:
208
+
209
+ - ``var`` -- string (default: ``'t'``); the name of the
210
+ variable in the entries of the matrix
211
+
212
+ OUTPUT:
213
+
214
+ The Burau matrix of the Artin group element over the Laurent
215
+ polynomial ring in the variable ``var``.
216
+
217
+ EXAMPLES::
218
+
219
+ sage: A.<s1,s2,s3> = ArtinGroup(['B',3])
220
+ sage: B1 = s1.burau_matrix()
221
+ sage: B2 = s2.burau_matrix()
222
+ sage: B3 = s3.burau_matrix()
223
+ sage: [B1, B2, B3]
224
+ [
225
+ [-t^2 t 0] [ 1 0 0] [ 1 0 0]
226
+ [ 0 1 0] [ t -t^2 a*t] [ 0 1 0]
227
+ [ 0 0 1], [ 0 0 1], [ 0 a*t -t^2]
228
+ ]
229
+ sage: B1 * B2 * B1 == B2 * B1 * B2
230
+ True
231
+ sage: B2 * B3 * B2 * B3 == B3 * B2 * B3 * B2
232
+ True
233
+ sage: B1 * B3 == B3 * B1
234
+ True
235
+ sage: (~s1).burau_matrix() * B1 == 1
236
+ True
237
+
238
+ We verify the example in Theorem 4.1 of [BQ2024]_::
239
+
240
+ sage: A.<s1,s2,s3,s4> = ArtinGroup(['A', 3, 1])
241
+ sage: [g.burau_matrix() for g in A.gens()]
242
+ [
243
+ [-t^2 t 0 t] [ 1 0 0 0] [ 1 0 0 0]
244
+ [ 0 1 0 0] [ t -t^2 t 0] [ 0 1 0 0]
245
+ [ 0 0 1 0] [ 0 0 1 0] [ 0 t -t^2 t]
246
+ [ 0 0 0 1], [ 0 0 0 1], [ 0 0 0 1],
247
+ <BLANKLINE>
248
+ [ 1 0 0 0]
249
+ [ 0 1 0 0]
250
+ [ 0 0 1 0]
251
+ [ t 0 t -t^2]
252
+ ]
253
+ sage: a = s3^2 * s4 * s3 * s2 *s1 * ~s3 * s4 * s3 * s2 * s1^-2 * s4
254
+ sage: b = s1^2 * ~s2 * s4 * s1 * ~s3 * s2 * ~s4 * s3 * s1 * s4 * s1 * ~s2 * s4^-2 * s3
255
+ sage: alpha = a * s3 * ~a
256
+ sage: beta = b * s2 * ~b
257
+ sage: elm = alpha * beta * ~alpha * ~beta
258
+ sage: print(elm.Tietze())
259
+ (3, 3, 4, 3, 2, 1, -3, 4, 3, 2, -1, -1, 4, 3, -4, 1, 1, -2, -3,
260
+ -4, 3, -1, -2, -3, -4, -3, -3, 1, 1, -2, 4, 1, -3, 2, -4, 3, 1,
261
+ 4, 1, -2, -4, -4, 3, 2, -3, 4, 4, 2, -1, -4, -1, -3, 4, -2, 3,
262
+ -1, -4, 2, -1, -1, 3, 3, 4, 3, 2, 1, -3, 4, 3, 2, -1, -1, 4,
263
+ -3, -4, 1, 1, -2, -3, -4, 3, -1, -2, -3, -4, -3, -3, 1, 1, -2,
264
+ 4, 1, -3, 2, -4, 3, 1, 4, 1, -2, -4, -4, 3, -2, -3, 4, 4, 2,
265
+ -1, -4, -1, -3, 4, -2, 3, -1, -4, 2, -1, -1)
266
+ sage: elm.burau_matrix()
267
+ [1 0 0 0]
268
+ [0 1 0 0]
269
+ [0 0 1 0]
270
+ [0 0 0 1]
271
+
272
+ Next, we show ``elm`` is not the identity by using the embedding of
273
+ the affine braid group `\widetilde{B}_n \to B_{n+1}`::
274
+
275
+ sage: # needs sage.libs.braiding
276
+ sage: B.<t1,t2,t3,t4> = BraidGroup(5)
277
+ sage: D = t1 * t2 * t3 * t4^2
278
+ sage: t0 = D * t3 * ~D
279
+ sage: t0*t1*t0 == t1*t0*t1
280
+ True
281
+ sage: t0*t2 == t2*t0
282
+ True
283
+ sage: t0*t3*t0 == t3*t0*t3
284
+ True
285
+ sage: T = [t0, t1, t2, t3]
286
+ sage: emb = B.prod(T[i-1] if i > 0 else ~T[-i-1] for i in elm.Tietze())
287
+ sage: emb.is_one()
288
+ False
289
+
290
+ Since the Burau representation does not respect the group embedding,
291
+ the corresponding `B_5` element's Burau matrix is not the identity
292
+ (Bigelow gave an example of the representation not being faithful for
293
+ `B_5`, but it is still open for `B_4`)::
294
+
295
+ sage: emb.burau_matrix() != 1 # needs sage.libs.braiding
296
+ True
297
+
298
+ We also verify the result using the elements in [BQ2024]_ Remark 4.2::
299
+
300
+ sage: ap = s3 * s1 * s2 * s1 * ~s3 * s4 * s2 * s3 * s2 * ~s3 * s1^-2 * s4
301
+ sage: bp = s1 * ~s4 * s1^2 * s3^-2 * ~s2 * s4 * s1 * ~s3 * s2 * ~s4 * s3 * s1 * s4 * s1 * ~s2 * s4^-2 * s3
302
+ sage: alpha = ap * s3 * ~ap
303
+ sage: beta = bp * s2 * ~bp
304
+ sage: elm = alpha * beta * ~alpha * ~beta # needs sage.libs.braiding
305
+ sage: elm.burau_matrix() # needs sage.libs.braiding
306
+ [1 0 0 0]
307
+ [0 1 0 0]
308
+ [0 0 1 0]
309
+ [0 0 0 1]
310
+
311
+ REFERENCES:
312
+
313
+ - [BQ2024]_
314
+ """
315
+ gens, invs = self.parent()._burau_generators
316
+ MS = gens[0].parent()
317
+ ret = MS.prod(gens[i-1] if i > 0 else invs[-i-1] for i in self.Tietze())
318
+
319
+ if var == 't':
320
+ return ret
321
+
322
+ from sage.rings.polynomial.laurent_polynomial_ring import LaurentPolynomialRing
323
+ poly_ring = LaurentPolynomialRing(ret.base_ring().base_ring(), var)
324
+ return ret.change_ring(poly_ring)
325
+
326
+
327
+ class FiniteTypeArtinGroupElement(ArtinGroupElement):
328
+ """
329
+ An element of a finite-type Artin group.
330
+ """
331
+ def _richcmp_(self, other, op):
332
+ """
333
+ Compare ``self`` and ``other``.
334
+
335
+ TESTS::
336
+
337
+ sage: # needs sage.rings.number_field
338
+ sage: A = ArtinGroup(['B',3])
339
+ sage: x = A([1, 2, 1])
340
+ sage: y = A([2, 1, 2])
341
+ sage: x == y
342
+ True
343
+ sage: x < y^(-1)
344
+ True
345
+ sage: A([]) == A.one()
346
+ True
347
+ sage: x = A([2, 3, 2, 3])
348
+ sage: y = A([3, 2, 3, 2])
349
+ sage: x == y
350
+ True
351
+ sage: x < y^(-1)
352
+ True
353
+ """
354
+ if self.Tietze() == other.Tietze():
355
+ return rich_to_bool(op, 0)
356
+ nfself = [i.Tietze() for i in self.left_normal_form()]
357
+ nfother = [i.Tietze() for i in other.left_normal_form()]
358
+ return richcmp(nfself, nfother, op)
359
+
360
+ def __hash__(self):
361
+ r"""
362
+ Return a hash value for ``self``.
363
+
364
+ EXAMPLES::
365
+
366
+ sage: # needs sage.rings.number_field
367
+ sage: B.<s1,s2,s3> = ArtinGroup(['B',3])
368
+ sage: hash(s1*s3) == hash(s3*s1)
369
+ True
370
+ sage: hash(s1*s2) == hash(s2*s1)
371
+ False
372
+ sage: hash(s1*s2*s1) == hash(s2*s1*s2)
373
+ True
374
+ sage: hash(s2*s3*s2) == hash(s3*s2*s3)
375
+ False
376
+ sage: hash(s2*s3*s2*s3) == hash(s3*s2*s3*s2)
377
+ True
378
+ """
379
+ return hash(tuple(i.Tietze() for i in self.left_normal_form()))
380
+
381
+ @cached_method
382
+ def left_normal_form(self):
383
+ r"""
384
+ Return the left normal form of ``self``.
385
+
386
+ OUTPUT:
387
+
388
+ A tuple of simple generators in the left normal form. The first
389
+ element is a power of `\Delta`, and the rest are elements of the
390
+ natural section lift from the corresponding Coxeter group.
391
+
392
+ EXAMPLES::
393
+
394
+ sage: # needs sage.rings.number_field
395
+ sage: A = ArtinGroup(['B',3])
396
+ sage: A([1]).left_normal_form()
397
+ (1, s1)
398
+ sage: A([-1]).left_normal_form()
399
+ (s1^-1*(s2^-1*s1^-1*s3^-1)^2*s2^-1*s3^-1, s3*(s2*s3*s1)^2*s2)
400
+ sage: A([1, 2, 2, 1, 2]).left_normal_form()
401
+ (1, s1*s2*s1, s2*s1)
402
+ sage: A([3, 3, -2]).left_normal_form()
403
+ (s1^-1*(s2^-1*s1^-1*s3^-1)^2*s2^-1*s3^-1,
404
+ s3*s1*s2*s3*s2*s1, s3, s3*s2*s3)
405
+ sage: A([1, 2, 3, -1, 2, -3]).left_normal_form()
406
+ (s1^-1*(s2^-1*s1^-1*s3^-1)^2*s2^-1*s3^-1,
407
+ (s3*s1*s2)^2*s1, s1*s2*s3*s2)
408
+ sage: A([1,2,1,3,2,1,3,2,3,3,2,3,1,2,3,1,2,3,1,2]).left_normal_form()
409
+ ((s3*(s2*s3*s1)^2*s2*s1)^2, s3*s2)
410
+
411
+ sage: # needs sage.combinat
412
+ sage: B = BraidGroup(4)
413
+ sage: b = B([1, 2, 3, -1, 2, -3])
414
+ sage: b.left_normal_form() # needs sage.libs.braiding
415
+ (s0^-1*s1^-1*s0^-1*s2^-1*s1^-1*s0^-1, s0*s1*s2*s1*s0, s0*s2*s1)
416
+ sage: c = B([1])
417
+ sage: c.left_normal_form() # needs sage.libs.braiding
418
+ (1, s0)
419
+ """
420
+ lnfp = self._left_normal_form_coxeter()
421
+ P = self.parent()
422
+ return tuple([P.delta() ** lnfp[0]] +
423
+ [P._standard_lift(w) for w in lnfp[1:]])
424
+
425
+ def _left_normal_form_coxeter(self):
426
+ r"""
427
+ Return the left normal form of the element, in the `\Delta`
428
+ exponent and Coxeter group element form.
429
+
430
+ OUTPUT: tuple whose first element is the power of `\Delta`, and the
431
+ rest are the Coxeter elements corresponding to the simple factors
432
+
433
+ EXAMPLES::
434
+
435
+ sage: # needs sage.rings.number_field
436
+ sage: A = ArtinGroup(['E',6])
437
+ sage: A([2, -4, 2, 3, 1, 3, 2, 1, -2])._left_normal_form_coxeter()
438
+ (
439
+ [ 0 0 0 0 0 -1] [ 0 0 -1 1 0 0] [-1 0 1 0 0 0]
440
+ [ 0 1 0 -1 0 0] [ 0 -1 0 1 0 0] [ 0 -1 0 1 0 0]
441
+ [ 0 0 0 0 -1 0] [-1 0 0 1 0 0] [ 0 0 1 0 0 0]
442
+ [ 0 1 -1 0 -1 0] [-1 -1 0 1 1 0] [ 0 0 0 1 0 0]
443
+ [ 0 0 -1 0 0 0] [ 0 0 0 0 1 0] [ 0 0 0 0 1 0]
444
+ -1, [-1 0 0 0 0 0], [ 0 0 0 0 0 1], [ 0 0 0 0 0 1]
445
+ )
446
+ sage: A = ArtinGroup(['F',4])
447
+ sage: A([2, 3, -4, 2, 3, -2, 1, -2, 3, 4, 1, -2])._left_normal_form_coxeter()
448
+ (
449
+ [-1 0 0 0] [ -1 1 0 0] [-1 0 0 0]
450
+ [-1 -1 a -a] [ -2 3 -a 0] [-1 1 -a 0]
451
+ [-a 0 1 -2] [ -a 2*a -1 -1] [ 0 0 -1 0]
452
+ -3, [-a 0 1 -1], [ -a a 0 -1], [ 0 0 0 -1],
453
+ <BLANKLINE>
454
+ [ -1 1 0 -a] [ -1 0 a -a]
455
+ [ 0 1 0 -2*a] [ -1 1 a -2*a]
456
+ [ 0 a -1 -2] [ 0 0 2 -3]
457
+ [ 0 a -1 -1], [ 0 0 1 -1]
458
+ )
459
+ """
460
+ delta = 0
461
+ Delta = self.parent().coxeter_group().long_element()
462
+ sr = self.parent().coxeter_group().simple_reflections()
463
+ tz = self.Tietze()
464
+ if tz == ():
465
+ return (0,)
466
+ form = []
467
+ for i in tz:
468
+ if i > 0:
469
+ form.append(sr[i])
470
+ else:
471
+ delta += 1
472
+ form = [Delta * a * Delta for a in form]
473
+ form.append(Delta * sr[-i])
474
+ i = j = 0
475
+ while j < len(form):
476
+ while i < len(form) - j - 1:
477
+ e = form[i].descents(side='right')
478
+ s = form[i + 1].descents(side='left')
479
+ S = set(s).difference(set(e))
480
+ while S:
481
+ a = list(S)[0]
482
+ form[i] = form[i] * sr[a]
483
+ form[i + 1] = sr[a] * form[i+1]
484
+ e = form[i].descents(side='right')
485
+ s = form[i + 1].descents(side='left')
486
+ S = set(s).difference(set(e))
487
+ if form[i+1].length() == 0:
488
+ form.pop(i+1)
489
+ i = 0
490
+ else:
491
+ i += 1
492
+ j += 1
493
+ i = 0
494
+ form = [elt for elt in form if elt.length()]
495
+ while form and form[0] == Delta:
496
+ form.pop(0)
497
+ delta -= 1
498
+ return tuple([-delta] + form)
499
+
500
+
501
+ class ArtinGroup(UniqueRepresentation, FinitelyPresentedGroup):
502
+ r"""
503
+ An Artin group.
504
+
505
+ Fix an index set `I`. Let `M = (m_{ij})_{i,j \in I}` be a
506
+ :class:`Coxeter matrix
507
+ <sage.combinat.root_system.coxeter_matrix.CoxeterMatrix>`.
508
+ An *Artin group* is a group `A_M` that has a presentation
509
+ given by generators `\{ s_i \mid i \in I \}` and relations
510
+
511
+ .. MATH::
512
+
513
+ \underbrace{s_i s_j s_i \cdots}_{m_{ij}}
514
+ = \underbrace{s_j s_i s_j \cdots}_{\text{$m_{ji}$ factors}}
515
+
516
+ for all `i,j \in I` with the usual convention that `m_{ij} = \infty`
517
+ implies no relation between `s_i` and `s_j`. There is a natural
518
+ corresponding Coxeter group `W_M` by imposing the additional
519
+ relations `s_i^2 = 1` for all `i \in I`. Furthermore, there is
520
+ a natural section of `W_M` by sending a reduced word
521
+ `s_{i_1} \cdots s_{i_{\ell}} \mapsto s_{i_1} \cdots s_{i_{\ell}}`.
522
+
523
+ Artin groups `A_M` are classified based on the Coxeter data:
524
+
525
+ - `A_M` is of *finite type* or *spherical* if `W_M` is finite;
526
+ - `A_M` is of *affine type* if `W_M` is of affine type;
527
+ - `A_M` is of *large type* if `m_{ij} \geq 4` for all `i,j \in I`;
528
+ - `A_M` is of *extra-large type* if `m_{ij} \geq 5` for all `i,j \in I`;
529
+ - `A_M` is *right-angled* if `m_{ij} \in \{2,\infty\}` for all `i,j \in I`.
530
+
531
+ Artin groups are conjectured to have many nice properties:
532
+
533
+ - Artin groups are torsion free.
534
+ - Finite type Artin groups have `Z(A_M) = \ZZ` and infinite type
535
+ Artin groups have trivial center.
536
+ - Artin groups have solvable word problems.
537
+ - `H_{W_M} / W_M` is a `K(A_M, 1)`-space, where `H_W` is the
538
+ hyperplane complement of the Coxeter group `W` acting on `\CC^n`.
539
+
540
+ These conjectures are known when the Artin group is finite type and a
541
+ number of other cases. See, e.g., [GP2012]_ and references therein.
542
+
543
+ INPUT:
544
+
545
+ - ``coxeter_data`` -- data defining a Coxeter matrix
546
+
547
+ - ``names`` -- string or list/tuple/iterable of strings
548
+ (default: ``'s'``); the generator names or name prefix
549
+
550
+ EXAMPLES::
551
+
552
+ sage: A.<a,b,c> = ArtinGroup(['B',3]); A # needs sage.rings.number_field
553
+ Artin group of type ['B', 3]
554
+ sage: ArtinGroup(['B',3]) # needs sage.rings.number_field
555
+ Artin group of type ['B', 3]
556
+
557
+ The input must always include the Coxeter data, but the ``names``
558
+ can either be a string representing the prefix of the names or
559
+ the explicit names of the generators. Otherwise the default prefix
560
+ of ``'s'`` is used::
561
+
562
+ sage: ArtinGroup(['B',2]).generators() # needs sage.rings.number_field
563
+ (s1, s2)
564
+ sage: ArtinGroup(['B',2], 'g').generators() # needs sage.rings.number_field
565
+ (g1, g2)
566
+ sage: ArtinGroup(['B',2], 'x,y').generators() # needs sage.rings.number_field
567
+ (x, y)
568
+
569
+ REFERENCES:
570
+
571
+ - :wikipedia:`Artin_group`
572
+
573
+ .. SEEALSO::
574
+
575
+ :class:`~sage.groups.raag.RightAngledArtinGroup`
576
+ """
577
+ @staticmethod
578
+ def __classcall_private__(cls, coxeter_data, names=None):
579
+ """
580
+ Normalize input to ensure a unique representation.
581
+
582
+ TESTS::
583
+
584
+ sage: # needs sage.rings.number_field
585
+ sage: A1 = ArtinGroup(['B',3])
586
+ sage: A2 = ArtinGroup(['B',3], 's')
587
+ sage: A3 = ArtinGroup(['B',3], ['s1','s2','s3'])
588
+ sage: A1 is A2 and A2 is A3
589
+ True
590
+
591
+ sage: # needs sage.rings.number_field
592
+ sage: A1 = ArtinGroup(['B',2], 'a,b')
593
+ sage: A2 = ArtinGroup([[1,4],[4,1]], 'a,b')
594
+ sage: A3.<a,b> = ArtinGroup('B2')
595
+ sage: A1 is A2 and A2 is A3
596
+ True
597
+
598
+ sage: ArtinGroup(['A',3]) is BraidGroup(4, 's1,s2,s3') # needs sage.combinat sage.rings.number_field
599
+ True
600
+
601
+ sage: # needs sage.graphs sage.rings.number_field
602
+ sage: G = graphs.PathGraph(3)
603
+ sage: CM = CoxeterMatrix([[1,-1,2],[-1,1,-1],[2,-1,1]], index_set=G.vertices(sort=True))
604
+ sage: A = groups.misc.Artin(CM)
605
+ sage: Ap = groups.misc.RightAngledArtin(G, 's')
606
+ sage: A is Ap
607
+ True
608
+ """
609
+ coxeter_data = CoxeterMatrix(coxeter_data)
610
+ if names is None:
611
+ names = 's'
612
+ if isinstance(names, str):
613
+ if ',' in names:
614
+ names = [x.strip() for x in names.split(',')]
615
+ else:
616
+ names = [names + str(i) for i in coxeter_data.index_set()]
617
+ names = tuple(names)
618
+ if len(names) != coxeter_data.rank():
619
+ raise ValueError("the number of generators must match"
620
+ " the rank of the Coxeter type")
621
+ if all(m == Infinity for m in coxeter_data.coxeter_graph().edge_labels()):
622
+ from sage.groups.raag import RightAngledArtinGroup
623
+ return RightAngledArtinGroup(coxeter_data.coxeter_graph(), names)
624
+ if not coxeter_data.is_finite():
625
+ return super().__classcall__(cls, coxeter_data, names)
626
+ if coxeter_data.coxeter_type().cartan_type().type() == 'A':
627
+ from sage.groups.braid import BraidGroup
628
+ return BraidGroup(coxeter_data.rank() + 1, names)
629
+ return FiniteTypeArtinGroup(coxeter_data, names)
630
+
631
+ def __init__(self, coxeter_matrix, names) -> None:
632
+ """
633
+ Initialize ``self``.
634
+
635
+ TESTS::
636
+
637
+ sage: # needs sage.rings.number_field
638
+ sage: A = ArtinGroup(['D',4])
639
+ sage: TestSuite(A).run()
640
+ sage: A = ArtinGroup(['B',3], ['x','y','z'])
641
+ sage: TestSuite(A).run()
642
+ """
643
+ self._coxeter_group = CoxeterGroup(coxeter_matrix)
644
+ free_group = FreeGroup(names)
645
+ rels = []
646
+ # Generate the relations based on the Coxeter graph
647
+ I = coxeter_matrix.index_set()
648
+ gens = free_group.gens()
649
+ for ii, i in enumerate(I):
650
+ for jj, j in enumerate(I[ii + 1:], start=ii + 1):
651
+ m = coxeter_matrix[i, j]
652
+ if m == Infinity: # no relation
653
+ continue
654
+ elt = (gens[ii] * gens[jj]) ** (m // 2)
655
+ if m % 2 == 1:
656
+ elt = elt * gens[ii] * ~gens[jj]
657
+ elt = elt * (~gens[ii] * ~gens[jj]) ** (m // 2)
658
+ rels.append(elt)
659
+ FinitelyPresentedGroup.__init__(self, free_group, tuple(rels))
660
+
661
+ def _repr_(self) -> str:
662
+ """
663
+ Return a string representation of ``self``.
664
+
665
+ TESTS::
666
+
667
+ sage: ArtinGroup(['B',3]) # needs sage.rings.number_field
668
+ Artin group of type ['B', 3]
669
+ sage: ArtinGroup(['D',4], 'g') # needs sage.rings.number_field
670
+ Artin group of type ['D', 4]
671
+ """
672
+ try:
673
+ data = self.coxeter_type().cartan_type()
674
+ return "Artin group of type {}".format(data)
675
+ except AttributeError:
676
+ pass
677
+ return "Artin group with Coxeter matrix:\n{}".format(self.coxeter_matrix())
678
+
679
+ def cardinality(self):
680
+ """
681
+ Return the number of elements of ``self``.
682
+
683
+ OUTPUT: infinity
684
+
685
+ EXAMPLES::
686
+
687
+ sage: # needs sage.graphs
688
+ sage: Gamma = graphs.CycleGraph(5)
689
+ sage: G = RightAngledArtinGroup(Gamma)
690
+ sage: G.cardinality()
691
+ +Infinity
692
+
693
+ sage: A = ArtinGroup(['A',1]) # needs sage.rings.number_field
694
+ sage: A.cardinality() # needs sage.rings.number_field
695
+ +Infinity
696
+ """
697
+ from sage.rings.infinity import Infinity
698
+ return Infinity
699
+
700
+ order = cardinality
701
+
702
+ def as_permutation_group(self):
703
+ """
704
+ Return an isomorphic permutation group.
705
+
706
+ This raises a :exc:`ValueError` error since Artin groups are
707
+ infinite and have no corresponding permutation group.
708
+
709
+ EXAMPLES::
710
+
711
+ sage: # needs sage.graphs
712
+ sage: Gamma = graphs.CycleGraph(5)
713
+ sage: G = RightAngledArtinGroup(Gamma)
714
+ sage: G.as_permutation_group()
715
+ Traceback (most recent call last):
716
+ ...
717
+ ValueError: the group is infinite
718
+
719
+ sage: A = ArtinGroup(['D',4], 'g') # needs sage.rings.number_field
720
+ sage: A.as_permutation_group() # needs sage.rings.number_field
721
+ Traceback (most recent call last):
722
+ ...
723
+ ValueError: the group is infinite
724
+ """
725
+ raise ValueError("the group is infinite")
726
+
727
+ def coxeter_type(self):
728
+ """
729
+ Return the Coxeter type of ``self``.
730
+
731
+ EXAMPLES::
732
+
733
+ sage: A = ArtinGroup(['D',4]) # needs sage.rings.number_field
734
+ sage: A.coxeter_type() # needs sage.rings.number_field
735
+ Coxeter type of ['D', 4]
736
+ """
737
+ return self._coxeter_group.coxeter_type()
738
+
739
+ def coxeter_matrix(self):
740
+ """
741
+ Return the Coxeter matrix of ``self``.
742
+
743
+ EXAMPLES::
744
+
745
+ sage: A = ArtinGroup(['B',3]) # needs sage.rings.number_field
746
+ sage: A.coxeter_matrix() # needs sage.rings.number_field
747
+ [1 3 2]
748
+ [3 1 4]
749
+ [2 4 1]
750
+ """
751
+ return self._coxeter_group.coxeter_matrix()
752
+
753
+ def coxeter_group(self):
754
+ """
755
+ Return the Coxeter group of ``self``.
756
+
757
+ EXAMPLES::
758
+
759
+ sage: A = ArtinGroup(['D',4]) # needs sage.rings.number_field
760
+ sage: A.coxeter_group() # needs sage.rings.number_field
761
+ Finite Coxeter group over Integer Ring with Coxeter matrix:
762
+ [1 3 2 2]
763
+ [3 1 3 3]
764
+ [2 3 1 2]
765
+ [2 3 2 1]
766
+ """
767
+ return self._coxeter_group
768
+
769
+ def index_set(self):
770
+ """
771
+ Return the index set of ``self``.
772
+
773
+ OUTPUT: tuple
774
+
775
+ EXAMPLES::
776
+
777
+ sage: A = ArtinGroup(['E',7]) # needs sage.rings.number_field
778
+ sage: A.index_set() # needs sage.rings.number_field
779
+ (1, 2, 3, 4, 5, 6, 7)
780
+ """
781
+ return self._coxeter_group.index_set()
782
+
783
+ def _element_constructor_(self, x):
784
+ """
785
+ TESTS::
786
+
787
+ sage: A = ArtinGroup(['B',3]) # needs sage.rings.number_field
788
+ sage: A([2,1,-2,3,3,3,1]) # needs sage.rings.number_field
789
+ s2*s1*s2^-1*s3^3*s1
790
+ """
791
+ if x in self._coxeter_group:
792
+ return self._standard_lift(x)
793
+ return self.element_class(self, x)
794
+
795
+ @cached_method
796
+ def _an_element_(self):
797
+ """
798
+ Return an element of ``self``.
799
+
800
+ EXAMPLES::
801
+
802
+ sage: A = ArtinGroup(['B',2]) # needs sage.rings.number_field
803
+ sage: A.an_element() # needs sage.rings.number_field
804
+ s1
805
+ """
806
+ return self.gen(0)
807
+
808
+ def some_elements(self) -> list:
809
+ """
810
+ Return a list of some elements of ``self``.
811
+
812
+ EXAMPLES::
813
+
814
+ sage: A = ArtinGroup(['B',3]) # needs sage.rings.number_field
815
+ sage: A.some_elements() # needs sage.rings.number_field
816
+ [s1, s1*s2*s3, (s1*s2*s3)^3]
817
+ """
818
+ rank = self.coxeter_matrix().rank()
819
+ elements_list = [self.gen(0)]
820
+ elements_list.append(self.prod(self.gens()))
821
+ elements_list.append(elements_list[-1] ** min(rank, 3))
822
+ return elements_list
823
+
824
+ def _standard_lift_Tietze(self, w):
825
+ """
826
+ Return a Tietze word representing the Coxeter element ``w``
827
+ under the natural section.
828
+
829
+ INPUT:
830
+
831
+ - ``w`` -- an element of the Coxeter group of ``self``
832
+
833
+ EXAMPLES::
834
+
835
+ sage: A = ArtinGroup(['B',3]) # needs sage.rings.number_field
836
+ sage: A._standard_lift_Tietze(A.coxeter_group().long_element()) # needs sage.rings.number_field
837
+ [3, 2, 3, 1, 2, 3, 1, 2, 1]
838
+ """
839
+ return w.reduced_word()
840
+
841
+ @cached_method
842
+ def _standard_lift(self, w):
843
+ """
844
+ Return the element of ``self`` that corresponds to the given
845
+ Coxeter element ``w`` under the natural section.
846
+
847
+ INPUT:
848
+
849
+ - ``w`` -- an element of the Coxeter group of ``self``
850
+
851
+ EXAMPLES::
852
+
853
+ sage: A = ArtinGroup(['B',3]) # needs sage.combinat sage.rings.number_field
854
+ sage: A._standard_lift(A.coxeter_group().long_element()) # needs sage.combinat sage.rings.number_field
855
+ s3*(s2*s3*s1)^2*s2*s1
856
+
857
+ sage: B = BraidGroup(5)
858
+ sage: P = Permutation([5, 3, 1, 2, 4])
859
+ sage: B._standard_lift(P)
860
+ s0*s1*s2*s3*s0*s1
861
+ """
862
+ return self(self._standard_lift_Tietze(w))
863
+
864
+ @lazy_attribute
865
+ def _burau_generators(self):
866
+ """
867
+ The Burau matrices for the generators of ``self`` and their inverses.
868
+
869
+ EXAMPLES::
870
+
871
+ sage: A = ArtinGroup(['G',2])
872
+ sage: A._burau_generators
873
+ [[
874
+ [-t^2 a*t] [ 1 0]
875
+ [ 0 1], [ a*t -t^2]
876
+ ],
877
+ [
878
+ [ -t^-2 a*t^-1] [ 1 0]
879
+ [ 0 1], [a*t^-1 -t^-2]
880
+ ]]
881
+
882
+ sage: A = ArtinGroup(['H',3])
883
+ sage: A._burau_generators
884
+ [[
885
+ [-t^2 t 0] [ 1 0 0]
886
+ [ 0 1 0] [ t -t^2 (1/2*a + 1/2)*t]
887
+ [ 0 0 1], [ 0 0 1],
888
+ <BLANKLINE>
889
+ [ 1 0 0]
890
+ [ 0 1 0]
891
+ [ 0 (1/2*a + 1/2)*t -t^2]
892
+ ],
893
+ [
894
+ [-t^-2 t^-1 0]
895
+ [ 0 1 0]
896
+ [ 0 0 1],
897
+ <BLANKLINE>
898
+ [ 1 0 0]
899
+ [ t^-1 -t^-2 (1/2*a + 1/2)*t^-1]
900
+ [ 0 0 1],
901
+ <BLANKLINE>
902
+ [ 1 0 0]
903
+ [ 0 1 0]
904
+ [ 0 (1/2*a + 1/2)*t^-1 -t^-2]
905
+ ]]
906
+
907
+ sage: CM = matrix([[1,4,7], [4,1,10], [7,10,1]])
908
+ sage: A = ArtinGroup(CM)
909
+ sage: gens = A._burau_generators[0]; gens
910
+ [
911
+ [ -t^2 (E(8) - E(8)^3)*t (-E(7)^3 - E(7)^4)*t]
912
+ [ 0 1 0]
913
+ [ 0 0 1],
914
+ <BLANKLINE>
915
+ [ 1 0 0]
916
+ [ (E(8) - E(8)^3)*t -t^2 (E(20) - E(20)^9)*t]
917
+ [ 0 0 1],
918
+ <BLANKLINE>
919
+ [ 1 0 0]
920
+ [ 0 1 0]
921
+ [(-E(7)^3 - E(7)^4)*t (E(20) - E(20)^9)*t -t^2]
922
+ ]
923
+ sage: all(gens[i] * A._burau_generators[1][i] == 1 for i in range(3))
924
+ True
925
+ sage: B1, B2, B3 = gens
926
+ sage: (B1 * B2)^2 == (B2 * B1)^2
927
+ True
928
+ sage: (B2 * B3)^5 == (B3 * B2)^5
929
+ True
930
+ sage: B1 * B3 * B1 * B3 * B1 * B3 * B1 == B3 * B1 * B3 * B1 * B3 * B1 * B3
931
+ True
932
+ """
933
+ data = self.coxeter_type()
934
+ coxeter_matrix = self.coxeter_matrix()
935
+ n = coxeter_matrix.rank()
936
+
937
+ # Determine the base field
938
+ if data.is_simply_laced():
939
+ from sage.rings.integer_ring import ZZ
940
+ base_ring = ZZ
941
+ elif data.is_finite():
942
+ from sage.rings.number_field.number_field import QuadraticField
943
+ letter = data.cartan_type().type()
944
+ if letter in ['B', 'C', 'F']:
945
+ base_ring = QuadraticField(2)
946
+ elif letter == 'G':
947
+ base_ring = QuadraticField(3)
948
+ elif letter == 'H':
949
+ base_ring = QuadraticField(5)
950
+ else:
951
+ from sage.rings.universal_cyclotomic_field import UniversalCyclotomicField
952
+ base_ring = UniversalCyclotomicField()
953
+ else:
954
+ from sage.rings.universal_cyclotomic_field import UniversalCyclotomicField
955
+ base_ring = UniversalCyclotomicField()
956
+
957
+ # Construct the matrices
958
+ from sage.matrix.args import SparseEntry
959
+ from sage.matrix.matrix_space import MatrixSpace
960
+ from sage.rings.polynomial.laurent_polynomial_ring import LaurentPolynomialRing
961
+ import sage.rings.abc
962
+ poly_ring = LaurentPolynomialRing(base_ring, 't')
963
+ q = -poly_ring.gen()
964
+ MS = MatrixSpace(poly_ring, n, sparse=True)
965
+ one = MS.one()
966
+ # FIXME: Hack because there is no ZZ \cup \{ \infty \}: -1 represents \infty
967
+ if isinstance(base_ring, sage.rings.abc.UniversalCyclotomicField):
968
+ E = base_ring.gen
969
+
970
+ def val(x):
971
+ if x == -1:
972
+ return 2 * q
973
+ elif x == 1:
974
+ return 1 + q**2
975
+ else:
976
+ E2x = E(2 * x)
977
+ return q * (E2x + ~E2x)
978
+ elif isinstance(base_ring, sage.rings.abc.NumberField_quadratic):
979
+ from sage.rings.universal_cyclotomic_field import UniversalCyclotomicField
980
+ E = UniversalCyclotomicField().gen
981
+
982
+ def val(x):
983
+ if x == -1:
984
+ return 2 * q
985
+ elif x == 1:
986
+ return 1 + q**2
987
+ else:
988
+ return q * base_ring((E(2 * x) + ~E(2 * x)).to_cyclotomic_field())
989
+ else:
990
+ def val(x):
991
+ if x == -1:
992
+ return 2 * q
993
+ elif x == 1:
994
+ return 1 + q**2
995
+ elif x == 2:
996
+ return 0
997
+ elif x == 3:
998
+ return q
999
+ else:
1000
+ from sage.functions.trig import cos
1001
+ from sage.symbolic.constants import pi
1002
+ return q * base_ring(2 * cos(pi / x))
1003
+ index_set = data.index_set()
1004
+ gens = [one - MS([SparseEntry(i, j, val(coxeter_matrix[index_set[i], index_set[j]]))
1005
+ for j in range(n)])
1006
+ for i in range(n)]
1007
+ invs = [one - q**-2 * MS([SparseEntry(i, j, val(coxeter_matrix[index_set[i], index_set[j]]))
1008
+ for j in range(n)])
1009
+ for i in range(n)]
1010
+ return [gens, invs]
1011
+
1012
+ Element = ArtinGroupElement
1013
+
1014
+
1015
+ class FiniteTypeArtinGroup(ArtinGroup):
1016
+ r"""
1017
+ A finite-type Artin group.
1018
+
1019
+ An Artin group is *finite-type* or *spherical* if the corresponding
1020
+ Coxeter group is finite. Finite type Artin groups are known to be
1021
+ torsion free, have a Garside structure given by `\Delta` (see
1022
+ :meth:`delta`) and have a center generated by `\Delta`.
1023
+
1024
+ .. SEEALSO::
1025
+
1026
+ :class:`ArtinGroup`
1027
+
1028
+ EXAMPLES::
1029
+
1030
+ sage: ArtinGroup(['E',7]) # needs sage.rings.number_field
1031
+ Artin group of type ['E', 7]
1032
+
1033
+ Since the word problem for finite-type Artin groups is solvable, their
1034
+ Cayley graph can be locally obtained as follows (see :issue:`16059`)::
1035
+
1036
+ sage: def ball(group, radius):
1037
+ ....: ret = set()
1038
+ ....: ret.add(group.one())
1039
+ ....: for length in range(1, radius):
1040
+ ....: for w in Words(alphabet=group.gens(), length=length):
1041
+ ....: ret.add(prod(w))
1042
+ ....: return ret
1043
+ sage: A = ArtinGroup(['B',3]) # needs sage.rings.number_field
1044
+ sage: GA = A.cayley_graph(elements=ball(A, 4), generators=A.gens()); GA # needs sage.combinat sage.graphs sage.rings.number_field
1045
+ Digraph on 32 vertices
1046
+
1047
+ Since the Artin group has nontrivial relations, this graph contains less
1048
+ vertices than the one associated to the free group (which is a tree)::
1049
+
1050
+ sage: F = FreeGroup(3)
1051
+ sage: GF = F.cayley_graph(elements=ball(F, 4), generators=F.gens()); GF # needs sage.combinat sage.graphs sage.combinat
1052
+ Digraph on 40 vertices
1053
+ """
1054
+ def delta(self):
1055
+ r"""
1056
+ Return the `\Delta` element of ``self``.
1057
+
1058
+ EXAMPLES::
1059
+
1060
+ sage: A = ArtinGroup(['B',3]) # needs sage.rings.number_field
1061
+ sage: A.delta() # needs sage.rings.number_field
1062
+ s3*(s2*s3*s1)^2*s2*s1
1063
+
1064
+ sage: A = ArtinGroup(['G',2]) # needs sage.rings.number_field
1065
+ sage: A.delta() # needs sage.rings.number_field
1066
+ (s2*s1)^3
1067
+
1068
+ sage: B = BraidGroup(5) # needs sage.combinat
1069
+ sage: B.delta() # needs sage.combinat
1070
+ s0*s1*s2*s3*s0*s1*s2*s0*s1*s0
1071
+ """
1072
+ return self._standard_lift(self._coxeter_group.long_element())
1073
+
1074
+ Element = FiniteTypeArtinGroupElement