Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sagemath
GitHub Repository: sagemath/sagelib
Path: blob/master/sage/combinat/crystals/affine.py
4079 views
1
r"""
2
Affine Crystals
3
"""
4
#*****************************************************************************
5
# Copyright (C) 2008 Brant Jones <brant at math.ucdavis.edu>
6
# Anne Schilling <anne at math.ucdavis.edu>
7
#
8
# Distributed under the terms of the GNU General Public License (GPL)
9
# http://www.gnu.org/licenses/
10
#****************************************************************************
11
# Acknowledgment: most of the design and implementation of this
12
# library is heavily inspired from MuPAD-Combinat.
13
#****************************************************************************
14
15
from sage.misc.abstract_method import abstract_method
16
from sage.categories.finite_crystals import FiniteCrystals
17
from sage.structure.parent import Parent
18
from sage.structure.unique_representation import UniqueRepresentation
19
from sage.structure.element_wrapper import ElementWrapper
20
from sage.combinat.root_system.cartan_type import CartanType
21
22
class AffineCrystalFromClassical(UniqueRepresentation, Parent):
23
r"""
24
This abstract class can be used for affine crystals that are constructed from a classical crystal.
25
The zero arrows can be implemented using different methods (for example using a Dynkin diagram
26
automorphisms or virtual crystals).
27
28
This is a helper class, mostly used to implement Kirillov-Reshetikhin crystals
29
(see: :func:`sage.combinat.crystals.kirillov_reshetikhin.KirillovReshetikhin`).
30
31
For general information about crystals see :mod:`sage.combinat.crystals`.
32
33
INPUT:
34
35
- ``cartan_type`` - The Cartan type of the resulting affine crystal
36
37
- ``classical_crystal`` - instance of a classical crystal.
38
39
EXAMPLES::
40
41
sage: n=2
42
sage: C=CrystalOfTableaux(['A',n],shape=[1])
43
sage: pr = attrcall("promotion")
44
sage: pr_inverse = attrcall("promotion_inverse")
45
sage: A=AffineCrystalFromClassicalAndPromotion(['A',n,1],C,pr,pr_inverse,1)
46
sage: A.list()
47
[[[1]], [[2]], [[3]]]
48
sage: A.cartan_type()
49
['A', 2, 1]
50
sage: A.index_set()
51
[0, 1, 2]
52
sage: b=A(rows=[[1]])
53
sage: b.weight()
54
-Lambda[0] + Lambda[1]
55
sage: b.classical_weight()
56
(1, 0, 0)
57
sage: [x.s(0) for x in A.list()]
58
[[[3]], [[2]], [[1]]]
59
sage: [x.s(1) for x in A.list()]
60
[[[2]], [[1]], [[3]]]
61
"""
62
63
@staticmethod
64
def __classcall__(cls, cartan_type, *args, **options):
65
"""
66
TESTS::
67
68
sage: n = 1
69
sage: C = CrystalOfTableaux(['A',n],shape=[1])
70
sage: pr = attrcall("promotion")
71
sage: pr_inverse = attrcall("promotion_inverse")
72
sage: A = AffineCrystalFromClassicalAndPromotion(['A',n,1],C,pr,pr_inverse,1) # indirect doctest
73
sage: B = AffineCrystalFromClassicalAndPromotion(['A',n,1],C,pr,pr_inverse,1) # indirect doctest
74
sage: A is B
75
True
76
"""
77
ct = CartanType(cartan_type)
78
return super(AffineCrystalFromClassical, cls).__classcall__(cls, ct, *args, **options)
79
80
def __init__(self, cartan_type, classical_crystal, category = None):
81
"""
82
Input is an affine Cartan type 'cartan_type', a classical crystal 'classical_crystal', and automorphism and its
83
inverse 'automorphism' and 'inverse_automorphism', and the Dynkin node 'dynkin_node'
84
85
EXAMPLES::
86
87
sage: n = 1
88
sage: C = CrystalOfTableaux(['A',n],shape=[1])
89
sage: pr = attrcall("promotion")
90
sage: pr_inverse = attrcall("promotion_inverse")
91
sage: A = AffineCrystalFromClassicalAndPromotion(['A',n,1],C,pr,pr_inverse,1) # indirect doctest
92
sage: A.list()
93
[[[1]], [[2]]]
94
sage: A.cartan_type()
95
['A', 1, 1]
96
sage: A.index_set()
97
[0, 1]
98
99
Note: AffineCrystalFromClassical is an abstract class, so we
100
can't test it directly.
101
102
TESTS::
103
104
sage: TestSuite(A).run()
105
"""
106
if category is None:
107
category = FiniteCrystals()
108
self._cartan_type = cartan_type
109
Parent.__init__(self, category = category)
110
self.classical_crystal = classical_crystal;
111
self.module_generators = map( self.retract, self.classical_crystal.module_generators )
112
self.element_class._latex_ = lambda x: x.lift()._latex_()
113
114
def _repr_(self):
115
"""
116
EXAMPLES::
117
118
sage: n=1
119
sage: C=CrystalOfTableaux(['A',n],shape=[1])
120
sage: pr = attrcall("promotion")
121
sage: pr_inverse = attrcall("promotion_inverse")
122
sage: AffineCrystalFromClassicalAndPromotion(['A',n,1],C,pr,pr_inverse,1) # indirect doctest
123
An affine crystal for type ['A', 1, 1]
124
"""
125
return "An affine crystal for type %s"%self.cartan_type()
126
127
128
def __iter__(self):
129
r"""
130
Construct the iterator from the underlying classical crystal.
131
132
TESTS::
133
134
sage: n=1
135
sage: C=CrystalOfTableaux(['A',n],shape=[1])
136
sage: pr = attrcall("promotion")
137
sage: pr_inverse = attrcall("promotion_inverse")
138
sage: A=AffineCrystalFromClassicalAndPromotion(['A',n,1],C,pr,pr_inverse,1) # indirect doctest
139
sage: A.list() # indirect doctest
140
[[[1]], [[2]]]
141
"""
142
for x in self.classical_crystal:
143
yield self.retract(x)
144
145
# should be removed once crystal defines __iter__ instead of list
146
def list(self):
147
"""
148
Returns the list of all crystal elements using the underlying classical crystal
149
150
EXAMPLES::
151
152
sage: n=2
153
sage: C=CrystalOfTableaux(['A',n],shape=[1])
154
sage: pr = attrcall("promotion")
155
sage: pr_inverse = attrcall("promotion_inverse")
156
sage: A=AffineCrystalFromClassicalAndPromotion(['A',n,1],C,pr,pr_inverse,1)
157
sage: A.list()
158
[[[1]], [[2]], [[3]]]
159
"""
160
return map( self.retract, self.classical_crystal.list() )
161
162
def lift(self, affine_elt):
163
"""
164
Lifts an affine crystal element to the corresponding classical crystal element
165
166
EXAMPLES::
167
168
sage: n=2
169
sage: C=CrystalOfTableaux(['A',n],shape=[1])
170
sage: pr = attrcall("promotion")
171
sage: pr_inverse = attrcall("promotion_inverse")
172
sage: A=AffineCrystalFromClassicalAndPromotion(['A',n,1],C,pr,pr_inverse,1)
173
sage: b=A.list()[0]
174
sage: A.lift(b)
175
[[1]]
176
sage: A.lift(b).parent()
177
The crystal of tableaux of type ['A', 2] and shape(s) [[1]]
178
"""
179
return affine_elt.lift()
180
181
def retract(self, classical_elt):
182
"""
183
Transforms a classical crystal element to the corresponding affine crystal element
184
185
EXAMPLES::
186
187
sage: n=2
188
sage: C=CrystalOfTableaux(['A',n],shape=[1])
189
sage: pr = attrcall("promotion")
190
sage: pr_inverse = attrcall("promotion_inverse")
191
sage: A=AffineCrystalFromClassicalAndPromotion(['A',n,1],C,pr,pr_inverse,1)
192
sage: t=C(rows=[[1]])
193
sage: t.parent()
194
The crystal of tableaux of type ['A', 2] and shape(s) [[1]]
195
sage: A.retract(t)
196
[[1]]
197
sage: A.retract(t).parent() is A
198
True
199
"""
200
return self.element_class(classical_elt, parent = self)
201
202
def __call__(self, *value, **options):
203
r"""
204
Coerces value into self.
205
206
EXAMPLES:
207
208
sage: n=2
209
sage: C=CrystalOfTableaux(['A',n],shape=[1])
210
sage: pr = attrcall("promotion")
211
sage: pr_inverse = attrcall("promotion_inverse")
212
sage: A=AffineCrystalFromClassicalAndPromotion(['A',n,1],C,pr,pr_inverse,1)
213
sage: b=A(rows=[[1]])
214
sage: b
215
[[1]]
216
sage: b.parent()
217
An affine crystal for type ['A', 2, 1]
218
sage: A(b) is b
219
True
220
"""
221
if len(value) == 1 and isinstance(value[0], self.element_class) and value[0].parent() == self:
222
return value[0]
223
else: # Should do sanity checks! (Including check for inconsistent parent.)
224
return self.retract(self.classical_crystal(*value, **options))
225
226
def __contains__(self, x):
227
r"""
228
Checks whether x is an element of self.
229
230
EXAMPLES:
231
232
sage: n=2
233
sage: C=CrystalOfTableaux(['A',n],shape=[1])
234
sage: pr = attrcall("promotion")
235
sage: pr_inverse = attrcall("promotion_inverse")
236
sage: A=AffineCrystalFromClassicalAndPromotion(['A',n,1],C,pr,pr_inverse,1)
237
sage: b=A(rows=[[1]])
238
sage: A.__contains__(b)
239
True
240
"""
241
return x.parent() is self
242
243
244
class AffineCrystalFromClassicalElement(ElementWrapper):
245
r"""
246
Elements of crystals that are constructed from a classical crystal.
247
The elements inherit many of their methods from the classical crystal
248
using lift and retract.
249
250
This class is not instantiated directly but rather __call__ed from
251
AffineCrystalFromClassical. The syntax of this is governed by the
252
(classical) CrystalOfTableaux.
253
254
EXAMPLES::
255
256
sage: n=2
257
sage: C=CrystalOfTableaux(['A',n],shape=[1])
258
sage: pr = attrcall("promotion")
259
sage: pr_inverse = attrcall("promotion_inverse")
260
sage: A=AffineCrystalFromClassicalAndPromotion(['A',n,1],C,pr,pr_inverse,1)
261
sage: b=A(rows=[[1]])
262
sage: b._repr_()
263
'[[1]]'
264
"""
265
266
def classical_weight(self):
267
"""
268
Returns the classical weight corresponding to self.
269
270
EXAMPLES::
271
272
sage: n=2
273
sage: C=CrystalOfTableaux(['A',n],shape=[1])
274
sage: pr = attrcall("promotion")
275
sage: pr_inverse = attrcall("promotion_inverse")
276
sage: A=AffineCrystalFromClassicalAndPromotion(['A',n,1],C,pr,pr_inverse,1)
277
sage: b=A(rows=[[1]])
278
sage: b.classical_weight()
279
(1, 0, 0)
280
"""
281
return self.lift().weight()
282
283
def lift(self):
284
"""
285
Lifts an affine crystal element to the corresponding classical crystal element
286
287
EXAMPLES::
288
289
sage: n=2
290
sage: C=CrystalOfTableaux(['A',n],shape=[1])
291
sage: pr = attrcall("promotion")
292
sage: pr_inverse = attrcall("promotion_inverse")
293
sage: A=AffineCrystalFromClassicalAndPromotion(['A',n,1],C,pr,pr_inverse,1)
294
sage: b=A.list()[0]
295
sage: b.lift()
296
[[1]]
297
sage: b.lift().parent()
298
The crystal of tableaux of type ['A', 2] and shape(s) [[1]]
299
"""
300
return self.value
301
302
def pp(self):
303
"""
304
Method for pretty printing
305
306
EXAMPLES::
307
308
sage: K = KirillovReshetikhinCrystal(['D',3,2],1,1)
309
sage: t=K(rows=[[1]])
310
sage: t.pp()
311
1
312
"""
313
return self.lift().pp()
314
315
@abstract_method
316
def e0(self):
317
r"""
318
Assumes that `e_0` is implemented separately.
319
"""
320
321
@abstract_method
322
def f0(self):
323
r"""
324
Assumes that `f_0` is implemented separately.
325
"""
326
327
def e(self, i):
328
r"""
329
Returns the action of `e_i` on self.
330
331
EXAMPLES::
332
333
sage: n=2
334
sage: C=CrystalOfTableaux(['A',n],shape=[1])
335
sage: pr = attrcall("promotion")
336
sage: pr_inverse = attrcall("promotion_inverse")
337
sage: A=AffineCrystalFromClassicalAndPromotion(['A',n,1],C,pr,pr_inverse,1)
338
sage: b=A(rows=[[1]])
339
sage: b.e(0)
340
[[3]]
341
sage: b.e(1)
342
"""
343
if i == 0:
344
return self.e0()
345
else:
346
x = self.lift().e(i)
347
if (x == None):
348
return None
349
else:
350
return self.parent().retract(x)
351
352
def f(self, i):
353
r"""
354
Returns the action of `f_i` on self.
355
356
EXAMPLES::
357
358
sage: n=2
359
sage: C=CrystalOfTableaux(['A',n],shape=[1])
360
sage: pr = attrcall("promotion")
361
sage: pr_inverse = attrcall("promotion_inverse")
362
sage: A=AffineCrystalFromClassicalAndPromotion(['A',n,1],C,pr,pr_inverse,1)
363
sage: b=A(rows=[[3]])
364
sage: b.f(0)
365
[[1]]
366
sage: b.f(2)
367
"""
368
if i == 0:
369
return self.f0()
370
else:
371
x = self.lift().f(i)
372
if (x == None):
373
return None
374
else:
375
return self.parent().retract(x)
376
377
def epsilon0(self):
378
r"""
379
Uses `epsilon_0` from the super class, but should be implemented if a faster implementation exists.
380
"""
381
return super(AffineCrystalFromClassicalElement, self).epsilon(0)
382
383
def epsilon(self, i):
384
"""
385
Returns the maximal time the crystal operator `e_i` can be applied to self.
386
387
EXAMPLES::
388
389
sage: n=2
390
sage: C=CrystalOfTableaux(['A',n],shape=[1])
391
sage: pr = attrcall("promotion")
392
sage: pr_inverse = attrcall("promotion_inverse")
393
sage: A=AffineCrystalFromClassicalAndPromotion(['A',n,1],C,pr,pr_inverse,1)
394
sage: [x.epsilon(0) for x in A.list()]
395
[1, 0, 0]
396
sage: [x.epsilon(1) for x in A.list()]
397
[0, 1, 0]
398
"""
399
if i == 0:
400
return self.epsilon0()
401
else:
402
return self.lift().epsilon(i)
403
404
def phi0(self):
405
r"""
406
Uses `phi_0` from the super class, but should be implemented if a faster implementation exists.
407
"""
408
return super(AffineCrystalFromClassicalElement, self).phi(0)
409
410
def phi(self, i):
411
r"""
412
Returns the maximal time the crystal operator `f_i` can be applied to self.
413
414
EXAMPLES::
415
416
sage: n=2
417
sage: C=CrystalOfTableaux(['A',n],shape=[1])
418
sage: pr = attrcall("promotion")
419
sage: pr_inverse = attrcall("promotion_inverse")
420
sage: A=AffineCrystalFromClassicalAndPromotion(['A',n,1],C,pr,pr_inverse,1)
421
sage: [x.phi(0) for x in A.list()]
422
[0, 0, 1]
423
sage: [x.phi(1) for x in A.list()]
424
[1, 0, 0]
425
"""
426
if i == 0:
427
return self.phi0()
428
else:
429
return self.lift().phi(i)
430
431
def __lt__(self, other):
432
"""
433
Non elements of the crystal are incomparable with elements of the crystal
434
(or should it return NotImplemented?). Elements of this crystal are compared
435
using the comparison in the underlying classical crystal.
436
437
EXAMPLES::
438
439
sage: K = KirillovReshetikhinCrystal(['A',2,1],1,1)
440
sage: b = K(rows=[[1]])
441
sage: c = K(rows=[[2]])
442
sage: c<b
443
False
444
sage: b<b
445
False
446
sage: b<c
447
True
448
"""
449
if self.parent() is not other.parent():
450
return False
451
return self.lift() < other.lift()
452
453
AffineCrystalFromClassical.Element = AffineCrystalFromClassicalElement
454
455
456
class AffineCrystalFromClassicalAndPromotion(AffineCrystalFromClassical):
457
r"""
458
Crystals that are constructed from a classical crystal and a
459
Dynkin diagram automorphism `\sigma`. In type `A_n`, the Dynkin
460
diagram automorphism is `i \to i+1 \pmod n+1` and the
461
corresponding map on the crystal is the promotion operation
462
`\mathrm{pr}` on tableaux. The affine crystal operators are given
463
by `f_0= \mathrm{pr}^{-1} f_{\sigma(0)} \mathrm{pr}`.
464
465
INPUT:
466
467
- ``cartan_type`` - The Cartan type of the resulting affine crystal
468
469
- ``classical_crystal`` - instance of a classical crystal.
470
471
- ``automorphism, inverse_automorphism`` - A function on the
472
elements of the classical_crystal
473
474
- ``dynkin_node`` - Integer specifying the classical node in the
475
image of the zero node under the automorphism sigma.
476
477
EXAMPLES::
478
479
sage: n=2
480
sage: C=CrystalOfTableaux(['A',n],shape=[1])
481
sage: pr = attrcall("promotion")
482
sage: pr_inverse = attrcall("promotion_inverse")
483
sage: A=AffineCrystalFromClassicalAndPromotion(['A',n,1],C,pr,pr_inverse,1)
484
sage: A.list()
485
[[[1]], [[2]], [[3]]]
486
sage: A.cartan_type()
487
['A', 2, 1]
488
sage: A.index_set()
489
[0, 1, 2]
490
sage: b=A(rows=[[1]])
491
sage: b.weight()
492
-Lambda[0] + Lambda[1]
493
sage: b.classical_weight()
494
(1, 0, 0)
495
sage: [x.s(0) for x in A.list()]
496
[[[3]], [[2]], [[1]]]
497
sage: [x.s(1) for x in A.list()]
498
[[[2]], [[1]], [[3]]]
499
"""
500
501
def __init__(self, cartan_type, classical_crystal, p_automorphism, p_inverse_automorphism, dynkin_node):
502
"""
503
Input is an affine Cartan type 'cartan_type', a classical crystal 'classical_crystal', and automorphism and its
504
inverse 'automorphism' and 'inverse_automorphism', and the Dynkin node 'dynkin_node'
505
506
EXAMPLES::
507
508
sage: n=1
509
sage: C=CrystalOfTableaux(['A',n],shape=[1])
510
sage: pr = attrcall("promotion")
511
sage: pr_inverse = attrcall("promotion_inverse")
512
sage: A=AffineCrystalFromClassicalAndPromotion(['A',n,1],C,pr,pr_inverse,1)
513
sage: A.list()
514
[[[1]], [[2]]]
515
sage: A.cartan_type()
516
['A', 1, 1]
517
sage: A.index_set()
518
[0, 1]
519
520
TESTS::
521
522
sage: TestSuite(A).run()
523
"""
524
AffineCrystalFromClassical.__init__(self, cartan_type, classical_crystal)
525
self.p_automorphism = p_automorphism
526
self.p_inverse_automorphism = p_inverse_automorphism
527
self.dynkin_node = dynkin_node
528
529
def automorphism(self, x):
530
"""
531
Gives the analogue of the affine Dynkin diagram automorphism on the level of crystals
532
533
EXAMPLES::
534
535
sage: n=2
536
sage: C=CrystalOfTableaux(['A',n],shape=[1])
537
sage: pr = attrcall("promotion")
538
sage: pr_inverse = attrcall("promotion_inverse")
539
sage: A=AffineCrystalFromClassicalAndPromotion(['A',n,1],C,pr,pr_inverse,1)
540
sage: b=A.list()[0]
541
sage: A.automorphism(b)
542
[[2]]
543
"""
544
return self.retract( self.p_automorphism( x.lift() ) )
545
546
def inverse_automorphism(self, x):
547
"""
548
Gives the analogue of the inverse of the affine Dynkin diagram automorphism on the level of crystals
549
550
EXAMPLES::
551
552
sage: n=2
553
sage: C=CrystalOfTableaux(['A',n],shape=[1])
554
sage: pr = attrcall("promotion")
555
sage: pr_inverse = attrcall("promotion_inverse")
556
sage: A=AffineCrystalFromClassicalAndPromotion(['A',n,1],C,pr,pr_inverse,1)
557
sage: b=A.list()[0]
558
sage: A.inverse_automorphism(b)
559
[[3]]
560
"""
561
return self.retract( self.p_inverse_automorphism( x.lift() ) )
562
563
class AffineCrystalFromClassicalAndPromotionElement(AffineCrystalFromClassicalElement):
564
r"""
565
Elements of crystals that are constructed from a classical crystal
566
and a Dynkin diagram automorphism. In type A, the automorphism is
567
the promotion operation on tableaux.
568
569
This class is not instantiated directly but rather __call__ed from
570
AffineCrystalFromClassicalAndPromotion. The syntax of this is governed by the
571
(classical) CrystalOfTableaux.
572
573
Since this class inherits from AffineClassicalFromClassicalElement, the methods
574
that need to be implemented are e0, f0 and possibly epsilon0 and phi0 if more efficient
575
algorithms exist.
576
577
EXAMPLES::
578
579
sage: n=2
580
sage: C=CrystalOfTableaux(['A',n],shape=[1])
581
sage: pr = attrcall("promotion")
582
sage: pr_inverse = attrcall("promotion_inverse")
583
sage: A=AffineCrystalFromClassicalAndPromotion(['A',n,1],C,pr,pr_inverse,1)
584
sage: b=A(rows=[[1]])
585
sage: b._repr_()
586
'[[1]]'
587
"""
588
589
def e0(self):
590
r"""
591
Implements `e_0` using the automorphism as
592
`e_0 = \operatorname{pr}^{-1} e_{dynkin_node} \operatorname{pr}`
593
594
EXAMPLES::
595
596
sage: n=2
597
sage: C=CrystalOfTableaux(['A',n],shape=[1])
598
sage: pr = attrcall("promotion")
599
sage: pr_inverse = attrcall("promotion_inverse")
600
sage: A=AffineCrystalFromClassicalAndPromotion(['A',n,1],C,pr,pr_inverse,1)
601
sage: b=A(rows=[[1]])
602
sage: b.e0()
603
[[3]]
604
"""
605
x = self.parent().automorphism(self).e(self.parent().dynkin_node)
606
if (x == None):
607
return None
608
else:
609
return self.parent().inverse_automorphism(x)
610
611
def f0(self):
612
r"""
613
Implements `f_0` using the automorphism as
614
`f_0 = \operatorname{pr}^{-1} f_{dynkin_node} \operatorname{pr}`
615
616
EXAMPLES::
617
618
sage: n=2
619
sage: C=CrystalOfTableaux(['A',n],shape=[1])
620
sage: pr = attrcall("promotion")
621
sage: pr_inverse = attrcall("promotion_inverse")
622
sage: A=AffineCrystalFromClassicalAndPromotion(['A',n,1],C,pr,pr_inverse,1)
623
sage: b=A(rows=[[3]])
624
sage: b.f0()
625
[[1]]
626
"""
627
x = self.parent().automorphism(self).f(self.parent().dynkin_node)
628
if (x == None):
629
return None
630
else:
631
return self.parent().inverse_automorphism(x)
632
633
def epsilon0(self):
634
r"""
635
Implements `epsilon_0` using the automorphism.
636
637
EXAMPLES::
638
639
sage: n=2
640
sage: C=CrystalOfTableaux(['A',n],shape=[1])
641
sage: pr = attrcall("promotion")
642
sage: pr_inverse = attrcall("promotion_inverse")
643
sage: A=AffineCrystalFromClassicalAndPromotion(['A',n,1],C,pr,pr_inverse,1)
644
sage: [x.epsilon0() for x in A.list()]
645
[1, 0, 0]
646
"""
647
x = self.parent().automorphism(self)
648
return x.lift().epsilon(self.parent().dynkin_node)
649
650
def phi0(self):
651
r"""
652
Implements `phi_0` using the automorphism.
653
654
EXAMPLES::
655
656
sage: n=2
657
sage: C=CrystalOfTableaux(['A',n],shape=[1])
658
sage: pr = attrcall("promotion")
659
sage: pr_inverse = attrcall("promotion_inverse")
660
sage: A=AffineCrystalFromClassicalAndPromotion(['A',n,1],C,pr,pr_inverse,1)
661
sage: [x.phi0() for x in A.list()]
662
[0, 0, 1]
663
"""
664
x = self.parent().automorphism(self)
665
return x.lift().phi(self.parent().dynkin_node)
666
667
AffineCrystalFromClassicalAndPromotion.Element = AffineCrystalFromClassicalAndPromotionElement
668
669