Path: blob/master/src/sage/combinat/crystals/infinity_crystals.py
8817 views
r"""1`\mathcal{B}(\infty)` Crystals of Tableaux in Nonexceptional Types and `G_2`23A tableau model for `\mathcal{B}(\infty)`. For more information, see4:class:`InfinityCrystalOfTableaux`.56AUTHORS:78- Ben Salisbury: Initial version910- Travis Scrimshaw: Initial version11"""1213#*****************************************************************************14# Copyright (C) 2013 Ben Salisbury <bsalisbury1 at gmail.com>15# Travis Scrimshaw <tscrim at ucdavis.edu>16#17# Distributed under the terms of the GNU General Public License (GPL)18#19# This code is distributed in the hope that it will be useful,20# but WITHOUT ANY WARRANTY; without even the implied warranty of21# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU22# General Public License for more details.23#24# The full text of the GPL is available at:25#26# http://www.gnu.org/licenses/27#****************************************************************************2829from sage.structure.parent import Parent30from sage.categories.infinite_enumerated_sets import InfiniteEnumeratedSets31from sage.categories.highest_weight_crystals import HighestWeightCrystals32from sage.misc.cachefunc import cached_method33from sage.misc.flatten import flatten34from sage.rings.infinity import Infinity3536from sage.combinat.partition import Partition37from sage.combinat.root_system.cartan_type import CartanType38from sage.combinat.crystals.letters import CrystalOfLetters39from sage.combinat.crystals.tensor_product import CrystalOfWords, CrystalOfTableauxElement4041class InfinityCrystalOfTableaux(CrystalOfWords):42r"""43`\mathcal{B}(\infty)` crystal of tableaux.4445A tableaux model `\mathcal{T}(\infty)` for the crystal46`\mathcal{B}(\infty)` is introduced by Hong and Lee in [HL08]_. This model47is currently valid for types `A_n`, `B_n`, `C_n`, `D_n`, and `G_2`, and48builds on the tableaux model given by Kashiwara and Nakashima [KN94]_ in49types `A_n`, `B_n`, `C_n`, and `D_n`, and by Kang and Misra [KM94]_ in50type `G_2`.5152.. NOTE::5354We are using the English convention for our tableaux.5556We say a tableau `T` is *marginally large* if:5758- for each `1 \leq i \leq n`, the leftmost box in the `i`-th row59from the top in `T` is an `i`-box,6061- for each `1 \leq i \leq n`, the number of `i`-boxes in the `i`-th row62from the top in `T` is greater than the total number of boxes in the63`(i+1)`-th row by exactly one.6465We now will describe this tableaux model type-by-type.6667.. rubric:: Type `A_n`6869`\mathcal{T}(\infty)` is the set of marginally large semistandard70tableaux with exactly `n` rows over the alphabet `\{1 \prec 2 \prec71\cdots \prec n+1 \}`.7273.. rubric:: Type `B_n`7475`\mathcal{T}(\infty)` is the set of marginally large semistandard76tableaux with exactly `n` rows over the alphabet `\{1 \prec \cdots77\prec n \prec 0 \prec \overline{n} \prec \cdots \prec \overline{1} \}`78and subject to the following constraints:7980- for each `1 \le i \le n`, the contents of the boxes in the81`i`-th row are `\preceq \overline{i}`,8283- the entry `0` can appear at most once in a single row.8485.. rubric:: Type `C_n`8687`\mathcal{T}(\infty)` is the set of marginally large semistandard88tableaux with exactly `n` rows over the alphabet `\{1 \prec \cdots89\prec n \prec \overline{n} \prec \cdots \prec \overline{1} \}` and90for each `1 \leq i \leq n`, the contents of the boxes in the `i`-th91row are `\preceq \overline{i}`.9293.. rubric:: Type `D_n`9495`\mathcal{T}(\infty)` is the set of marginally large semistandard96tableaux with exactly `n-1` rows over the alphabet `\{1 \prec \cdots97\prec n, \overline{n} \prec \cdots \prec \overline{1} \}` and subject98to the following constaints:99100- for each `1 \le i \le n`, the contents of the boxes in the `i`-th101row are `\preceq \overline{i}`,102103- the entries `n` and `\overline{n}` may not appear simultaneously in104a single row.105106.. rubric:: Type `G_2`107108`\mathcal{T}(\infty)` is the set of marginally large semistandard109tableaux with exactly `2` rows over the ordered alphabet `\{1 \prec1102 \prec 3 \prec 0 \prec \overline{3} \prec \overline{2} \prec111\overline{1}\}` and subject to the following constraints:112113- the contents of the boxes in the first row are `\preceq \overline{i}`,114115- the contents of the boxes in the second row are `\preceq 3`,116117- the entry `0` can appear at most once in the first row and not at118all in the second row.119120In particular, the shape of the tableaux is not fixed in any instance of121`\mathcal{T}(\infty)`; the row lengths of a tableau can be arbitrarily long.122123REFERENCES:124125.. [BN10] D. Bump and M. Nakasuji.126Integration on `p`-adic groups and crystal bases.127Proc. Amer. Math. Soc. 138(5), pp. 1595--1605.128129.. [LS12] K.-H. Lee and B. Salisbury.130Young tableaux, canonical bases, and the Gindikin-Karpelevich formula.131:arXiv:`1205.6006`.132133.. [HL08] J. Hong and H. Lee.134Young tableaux and crystal `B(\infty)` for finite simple Lie algebras.135J. Algebra 320, pp. 3680--3693, 2008.136137.. [KM94] S.-J. Kang and K. C. Misra.138Crystal bases and tensor product decompositions of `U_q(G_2)`-modules.139J. Algebra 163, pp. 675--691, 1994.140141INPUT:142143- ``cartan_type`` -- One of ``['A',n]``, ``['B',n]``, ``['C',n]``,144``['D',n]``, or ``['G',2]``, where ``n`` is a positive integer145146EXAMPLES::147148sage: B = InfinityCrystalOfTableaux(['A',2])149sage: b = B.highest_weight_vector(); b.pp()1501 11512152sage: b.f_string([2,1,1,2,2,2]).pp()1531 1 1 1 1 2 31542 3 3 3155156sage: B = InfinityCrystalOfTableaux(['G',2])157sage: b = B(rows=[[1,1,1,1,1,2,3,3,0,-3,-1,-1,-1],[2,3,3,3]])158sage: b.e_string([2,1,1,1,1,1,1]).pp()1591 1 1 1 2 3 3 3 3 -2 -2 -21602 3 3161sage: b.e_string([2,1,1,1,1,1,1,1])162163We check that a few classical crystals embed into `\mathcal{T}(\infty)`::164165sage: def crystal_test(B, C):166....: g = {C.module_generators[0] : B.module_generators[0]}167....: f = C.crystal_morphism(g)168....: G = B.digraph(subset=[f(x) for x in C])169....: return G.is_isomorphic(C.digraph(), edge_labels=True)170sage: B = InfinityCrystalOfTableaux(['A',2])171sage: C = CrystalOfTableaux(['A',2], shape=[2,1])172sage: crystal_test(B, C)173True174sage: C = CrystalOfTableaux(['A',2], shape=[6,2])175sage: crystal_test(B, C)176True177sage: B = InfinityCrystalOfTableaux(['B',2])178sage: C = CrystalOfTableaux(['B',2], shape=[3])179sage: crystal_test(B, C)180True181sage: C = CrystalOfTableaux(['B',2], shape=[2,1])182sage: crystal_test(B, C)183True184sage: B = InfinityCrystalOfTableaux(['C',3])185sage: C = CrystalOfTableaux(['C',3], shape=[2,1])186sage: crystal_test(B, C)187True188sage: B = InfinityCrystalOfTableaux(['D',4])189sage: C = CrystalOfTableaux(['D',4], shape=[2])190sage: crystal_test(B, C)191True192sage: C = CrystalOfTableaux(['D',4], shape=[1,1,1,1])193sage: crystal_test(B, C)194True195sage: B = InfinityCrystalOfTableaux(['G',2])196sage: C = CrystalOfTableaux(['G',2], shape=[3])197sage: crystal_test(B, C)198True199"""200@staticmethod201def __classcall_private__(cls, cartan_type):202"""203Normalize input to ensure a unique representation.204205EXAMPLES::206207sage: B = InfinityCrystalOfTableaux(['A',4])208sage: B2 = InfinityCrystalOfTableaux(CartanType(['A',4]))209sage: B is B2210True211"""212cartan_type = CartanType(cartan_type)213if cartan_type.type() == 'D':214return InfinityCrystalOfTableauxTypeD(cartan_type)215return super(InfinityCrystalOfTableaux, cls).__classcall__(cls, cartan_type)216217def __init__(self, cartan_type):218"""219Initialize ``self``.220221EXAMPLES::222223sage: B = InfinityCrystalOfTableaux(['A',2])224sage: TestSuite(B).run() # long time225"""226Parent.__init__( self, category=(HighestWeightCrystals(), InfiniteEnumeratedSets()) )227self._cartan_type = cartan_type228self.letters = CrystalOfLetters(cartan_type)229self.module_generators = (self.module_generator(),)230231def _repr_(self):232"""233Return a string representation of ``self``.234235EXAMPLES::236237sage: B = InfinityCrystalOfTableaux(['A',4]); B238The infinity crystal of tableaux of type ['A', 4]239"""240return "The infinity crystal of tableaux of type %s"%self._cartan_type241242@cached_method243def module_generator(self):244"""245Return the module generator (or highest weight element) of ``self``.246247The module generator is the unique tableau of shape `(n, n-1, \ldots,2482, 1)` with weight `0`.249250EXAMPLES::251252sage: T = InfinityCrystalOfTableaux(['A',3])253sage: T.module_generator()254[[1, 1, 1], [2, 2], [3]]255"""256n = self._cartan_type.rank()257p = Partition([x for x in reversed(range(1, n+1))])258# The column canonical tableau, read by columns259module_generator = flatten([[p[j]-i for i in range(p[j])] for j in range(n)])260return self(list=[self.letters(x) for x in module_generator])261262def _element_constructor_(self, *args, **options):263"""264Construct an element of ``self`` from the input data.265266EXAMPLES::267268sage: T = CrystalOfTableaux(['A',3], shape = [2,2])269sage: T(rows=[[1,2],[3,4]])270[[1, 2], [3, 4]]271sage: T(columns=[[3,1],[4,2]])272[[1, 2], [3, 4]]273"""274return self.element_class(self, *args, **options)275276class Element(CrystalOfTableauxElement):277r"""278Elements in `\mathcal{B}(\infty)` crystal of tableaux.279"""280281def e(self,i):282r"""283Return the action of `\widetilde{e}_i` on ``self``.284285INPUT:286287- ``i`` -- An element of the index set288289EXAMPLES::290291sage: B = InfinityCrystalOfTableaux(['B',3])292sage: b = B(rows=[[1,1,1,1,1,1,1,2,0,-3,-1,-1,-1,-1],[2,2,2,2,-2,-2],[3,-3,-3]])293sage: b.e(3).pp()2941 1 1 1 1 1 1 2 0 -3 -1 -1 -1 -12952 2 2 2 -2 -22963 0 -3297sage: b.e(1).pp()2981 1 1 1 1 1 1 0 -3 -1 -1 -1 -12992 2 2 2 -2 -23003 -3 -3301"""302if i not in self.index_set():303raise ValueError('i is not in the index set.')304position = self.positions_of_unmatched_plus(i)305if position == []:306return None307k = position[0]308ret = self.set_index(k, self[k].e(i))309if k+i > len(self):310return ret311for j in reversed(range(1, i+1)):312if ret[k+i-j].value != j:313return ret314# We've found a column, so we need to remove it315for j in range(i):316ret._list.pop(k)317return ret318319def f(self, i):320r"""321Return the action of `\widetilde{f}_i` on ``self``.322323INPUT:324325- ``i`` -- An element of the index set326327EXAMPLES::328329sage: B = InfinityCrystalOfTableaux(['C',4])330sage: b = B.highest_weight_vector()331sage: b.f(1).pp()3321 1 1 1 23332 2 23343 33354336sage: b.f(3).pp()3371 1 1 1 13382 2 2 23393 3 43404341sage: b.f(3).f(4).pp()3421 1 1 1 13432 2 2 23443 3 -43454346"""347if i not in self.index_set():348raise ValueError('i is not in the index set.')349position = self.positions_of_unmatched_minus(i)350if position == []:351return None352k = position[len(position)-1]353ret = self.set_index(k, self[k].f(i))354if k+i > len(self):355return ret356for j in reversed(range(1,i+1)):357if self[k+i-j].value != j:358return ret359# We've found a full column, so we'll need to add a new column360for j in range(i):361ret._list.insert(k,self.parent().letters(j+1))362return ret363364def phi(self,i):365r"""366Return `\varphi_i` of ``self``.367368Let `T \in \mathcal{B}(\infty)` Define `\varphi_i(T) :=369\varepsilon_i(T) + \langle h_i, \mathrm{wt}(T) \rangle`, where `h_i`370is the `i`-th simple coroot and `\mathrm{wt}(T)` is the :meth:`weight`371of `T`.372373INPUT:374375- ``i`` -- An element of the index set376377EXAMPLES::378379sage: B = InfinityCrystalOfTableaux("A3")380sage: [B.highest_weight_vector().f_string([1,3,2,3,1,3,2,1]).phi(i) for i in B.index_set()]381[-3, 4, -3]382383sage: B = InfinityCrystalOfTableaux("G2")384sage: [B.highest_weight_vector().f_string([2,2,1,2,1,1,1,2]).phi(i) for i in B.index_set()]385[5, -3]386"""387P = self.parent().weight_lattice_realization()388h = P.simple_coroots()389return self.epsilon(i) + P(self.weight()).scalar(h[i])390391@cached_method392def weight(self):393r"""394Return the weight of ``self``.395396From the definition of a crystal and that the highest weight397element `b_{\infty}` of `\mathcal{B}(\infty)` is `0`, the weight of398`T \in \mathcal{B}(\infty)` can be defined as `\mathrm{wt}(T)399:= -\sum_j \alpha_{i_j}` where `\widetilde{e}_{i_1} \cdots400\widetilde{e}_{i_{\ell}} T = b_{\infty}` and `\{\alpha_i\}` is the401set of simple roots. (Note that the weight is independent of the402path chosen to get to the highest weight.)403404However we can also take advantage of the fact that405`\rho \colon R_{\lambda} \otimes \mathcal{B}(\infty) \longrightarrow406B(\lambda)`, where `\lambda` is the shape of `T`, preserves the407tableau representation of `T`. Therefore408409.. MATH::410411\mathrm{wt}(T) = \mathrm{wt}\bigl( \rho(T) \bigr) - \lambda412413where `\mathrm{wt}\bigl( \rho(T) \bigr)` is just the usual weight of414the tableau `T`.415416Let `\Lambda_i` be the `i`-th fundamental weight. In type `D`, the417height `n-1` columns corresponds to `\Lambda_{n-1} + \Lambda_n` and418the in type `B`, the height `n` columns corresponds to419`2 \Lambda_n`.420421EXAMPLES::422423sage: B = InfinityCrystalOfTableaux("C7")424sage: b = B.highest_weight_vector().f_string([1,6,4,7,4,2,4,6,2,4,6,7,1,2,4,7])425sage: b.weight()426(-2, -1, 3, -5, 5, -3, -3)427428Check that the definitions agree::429430sage: P = B.weight_lattice_realization()431sage: alpha = P.simple_roots()432sage: b.weight() == -2*alpha[1] - 3*alpha[2] - 5*alpha[4] - 3*alpha[6] - 3*alpha[7]433True434435Check that it works for type `B`::436437sage: B = InfinityCrystalOfTableaux("B2")438sage: B.highest_weight_vector().weight()439(0, 0)440sage: b = B.highest_weight_vector().f_string([1,2,2,2,1,2])441sage: P = B.weight_lattice_realization()442sage: alpha = P.simple_roots()443sage: b.weight() == -2*alpha[1] - 4*alpha[2]444True445446Check that it works for type `D`::447448sage: B = InfinityCrystalOfTableaux("D4")449sage: B.highest_weight_vector().weight()450(0, 0, 0, 0)451sage: b = B.highest_weight_vector().f_string([1,4,4,2,4,3,2,4,1,3,2,4])452sage: P = B.weight_lattice_realization()453sage: alpha = P.simple_roots()454sage: b.weight() == -2*alpha[1] - 3*alpha[2] - 2*alpha[3] - 5*alpha[4]455True456"""457P = self.parent().weight_lattice_realization()458La = P.fundamental_weights()459cur_col_len = 1460shape_wt = P.zero()461n = self.cartan_type().rank()462ty = self.cartan_type().type()463for i in range(1, len(self)):464if self[i-1] < self[i] or (self[i-1].value != 0 and self[i-1] == self[i]):465if (cur_col_len == n - 1 and ty == 'D') or \466(cur_col_len == n and ty == 'B'):467shape_wt += La[n]468shape_wt += La[cur_col_len]469cur_col_len = 1470else:471cur_col_len += 1472shape_wt += La[1] # Since we miss the last column (which is always height 1)473return CrystalOfTableauxElement.weight(self) - shape_wt474475def reduced_form(self):476r"""477Return the reduced form of ``self``.478479The reduced form of a tableaux `T \in \mathcal{T}(\infty)` is the480(not necessarily semistandard) tableaux obtained from `T` by481removing all `i`-boxes in the `i`-th row, subject to the condition482that if the row is empty, a `\ast` is put as a placeholder.483This is described in [BN10]_ and [LS12]_.484485EXAMPLES::486487sage: B = InfinityCrystalOfTableaux(['A',3])488sage: b = B.highest_weight_vector().f_string([2,2,2,3,3,3,3,3])489sage: b.pp()4901 1 1 1 1 1 1 14912 2 2 2 4 4 44923 4 4493sage: b.reduced_form().pp()494*4954 4 44964 4497"""498tab = self.to_tableau()499for i in range(len(tab)):500j=0501while j < len(tab[i]):502if tab[i][j] == i+1:503tab[i].pop(j)504if tab[i] == []:505tab[i].append('*')506else:507j += 1508return tab509510def seg(self):511r"""512Returns the statistic `\mathrm{seg}` of ``self.``513514More precisely, following [LS12]_, define a `k`-segment of a515tableau `T` in `\mathcal{B}(\infty)` to be a maximal string516of `k`-boxes in a single row of `T`. Set `\mathrm{seg}^{\prime}(T)`517to be the number of `k`-segments in `T`, as `k` varies over518all possible values. Then `\mathrm{seg}(T)` is determined519type-by-type.520521- In types `A_n` and `C_n`, define `\mathrm{seg}(T) :=522\mathrm{seg}^{\prime}(T)`.523524- In types `B_n` and `G_2`, set `e(T)` to be the number of rows in525`T` which contain both a `0`-box and an `\overline{\imath}`-box.526Define `\mathrm{seg}(T) := \mathrm{seg}^{\prime}(T) - e(T)`.527528- In type `D_n`, set `d(T)` to be the number of rows in `T` which529contain an `\overline{\imath}`-box, but no `n`-box nor530`\overline{n}`-box. Define `\mathrm{seg}(T) :=531\mathrm{seg}^{\prime}(T) + d(T)`.532533EXAMPLES::534535sage: B = InfinityCrystalOfTableaux(['A',3])536sage: b = B.highest_weight_vector().f_string([1,3,2,2,3,1,1,3])537sage: b.pp()5381 1 1 1 1 1 2 2 45392 2 2 2 35403 4 4541sage: b.seg()5424543544sage: B = InfinityCrystalOfTableaux(['D',4])545sage: b = B(rows=[[1,1,1,1,1,1,3,-2,-1],[2,2,2,4,-2],[3,3],[4]])546sage: b.pp()5471 1 1 1 1 1 3 -2 -15482 2 2 4 -25493 35504551sage: b.seg()5526553554sage: B = InfinityCrystalOfTableaux(['G',2])555sage: b = B.highest_weight_vector().f_string([2,1,1,1,2,1,2,2,1,2,2,2,1,2,2,1])556sage: b.pp()5571 1 1 1 1 1 1 1 2 3 0 -35582 3 3 3 3 3 3559sage: b.seg()5605561"""562tab = self.to_tableau()563segments = []564for r in range(len(tab)):565for c in range(len(tab[r])):566if tab[r][c] != r+1:567if [r,tab[r][c]] not in segments:568segments.append([r,tab[r][c]])569if self.parent().cartan_type().type() == 'B':570for r in range(len(tab)):571for c in range(len(tab[r])):572if tab[r][c] == 0 and tab[r][-1] == -r-1:573segments.remove([r,tab[r][c]])574if self.parent().cartan_type().type() == 'D':575n = self.parent().cartan_type().rank()576add = []577for r in range(len(tab)):578if tab[r][-1] == -1*(r+1):579for c in range(len(tab[r])):580if tab[r][c] != n and tab[r][c] != -n:581if [r,n] not in add:582add.append([r,n])583if len(add) > 0:584segments.append([r,n])585if self.parent().cartan_type().type() == 'G':586for c in range(len(tab[0])):587if tab[0][c] == 0 and tab[0][-1] == -1:588segments.remove([0,tab[0][c]])589return len(segments)590591def content(self):592r"""593Return the content of ``self``.594595The content `|T|` of `T \in \mathcal{B}(\infty)` is the number of596blocks added to the highest weight to obtain `T` with any597`\overline{\imath}`-boxes in the `i`-th row counted with598multiplicity `2` provided the underlying Cartan type is of type599`B`, `D`, or `G`.600601EXAMPLES::602603sage: B = InfinityCrystalOfTableaux("D5")604sage: b = B.highest_weight_vector().f_string([5,4,3,1,1,3,4,5,3,4,5,1,4,5,2,3,5,3,2,4])605sage: b.content()60613607608sage: B = InfinityCrystalOfTableaux("B2")609sage: b = B(rows=[[1,1,1,1,1,1,2,2,2,-2,-2],[2,0,-2,-2,-2]])610sage: b.content()61112612613sage: B = InfinityCrystalOfTableaux("C2")614sage: b = B(rows=[[1,1,1,1,1,1,2,2,2,-2,-2],[2,-2,-2,-2]])615sage: b.content()6168617"""618tab = self.to_tableau()619count = 0620ct = self.parent().cartan_type().type()621for i,row in enumerate(tab):622for entry in row:623if entry == -i-1 and ct in ('B','D','G'):624count += 2625elif entry != i+1:626count += 1627return count628629def string_parameters(self,word):630r"""631Return the string parametrization of ``self`` with respect to ``word``.632633For `w` in the Weyl group, let `R(w)` denote the set of reduced634expressions for `w`; that is, if `w = s_{i_1} s_{i_2} \cdots635s_{i_{\ell}}` is a reduced expression, then636`(i_1, i_2, \ldots, i_{\ell}) \in R(w)`. For brevity, such words637are denoted by `\mathbf{i}`.638639For `T \in \mathcal{T}(\infty)` and640`\mathbf{i} = (i_1, \ldots, i_{\ell}) \in R(w)`,641the string parametrization `(a_1, \ldots, a_{\ell})` of `T` in the642direction `\mathbf{i}` is defined recursively by `a_1 =643\varepsilon_{i_1}(T)` and `a_j = \varepsilon_{i_j}644(\widetilde{e}_{i_{j-1}}^{\, a_{j-1}} \cdots \widetilde{e}_{i_1}^{\,645a_1} T)` for `j = 2, \ldots, \ell`. If `w = w_0` is the longest646element of the Weyl group, then the path determined by the string647parametrization terminates at the highest weight vector.648649INPUT:650651- ``word`` -- A word in the alphabet of the index set652653EXAMPLES::654655sage: B = InfinityCrystalOfTableaux("A5")656sage: b = B(rows=[[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,3,6,6,6,6,6,6],[2,2,2,2,2,2,2,2,2,4,5,5,5,6],[3,3,3,3,3,3,3,5],[4,4,4,6,6,6],[5,6]])657sage: b.string_parameters([1,2,1,3,2,1,4,3,2,1,5,4,3,2,1])658[0, 1, 1, 1, 1, 0, 4, 4, 3, 0, 11, 10, 7, 7, 6]659660sage: B = InfinityCrystalOfTableaux("G2")661sage: b = B(rows=[[1,1,1,1,1,3,3,0,-3,-3,-2,-2,-1,-1,-1,-1],[2,3,3,3]])662sage: b.string_parameters([2,1,2,1,2,1])663[5, 13, 11, 15, 4, 4]664sage: b.string_parameters([1,2,1,2,1,2])665[7, 12, 15, 8, 10, 0]666"""667ret = []668for i in word:669a = 0670while self.e(i) != None:671self = self.e(i)672a += 1673ret.append(a)674return ret675676class InfinityCrystalOfTableauxTypeD(InfinityCrystalOfTableaux):677r"""678`\mathcal{B}(\infty)` crystal of tableaux for type `D_n`.679680This is the set `\mathcal{T}(\infty)` of marginally large semistandard681tableaux with exactly `n-1` rows over the alphabet `\{1 \prec \cdots682\prec n, \overline{n} \prec \cdots \prec \overline{1} \}` and subject683to the following constraints:684685- for each `1 \le i \le n`, the contents of the boxes in the `i`-th686row are `\preceq \overline{i}`,687688- the entries `n` and `\overline{n}` may not appear simultaneously in689a single row.690691For more information, see :class:`InfinityCrystalOfTableaux`.692693EXAMPLES::694695sage: B = InfinityCrystalOfTableaux("D4")696sage: b = B.highest_weight_vector().f_string([4,3,2,1,4])697sage: b.pp()6981 1 1 1 1 1 26992 2 2 2 37003 -4 -3701sage: b.weight()702(-1, 0, -2, -1)703"""704@staticmethod705def __classcall_private__(cls, cartan_type):706"""707Normalize input to ensure a unique representation.708709EXAMPLES::710711sage: B = InfinityCrystalOfTableaux(['D',4])712sage: B2 = InfinityCrystalOfTableaux(CartanType(['D',4]))713sage: B is B2714True715"""716return super(InfinityCrystalOfTableauxTypeD, cls).__classcall__(cls, CartanType(cartan_type))717718@cached_method719def module_generator(self):720"""721Return the module generator (or highest weight element) of ``self``.722723The module generator is the unique tableau of shape `(n-1, \ldots, 2,7241)` with weight `0`.725726EXAMPLES::727728sage: T = InfinityCrystalOfTableaux(['D',4])729sage: T.module_generator()730[[1, 1, 1], [2, 2], [3]]731"""732n = self._cartan_type.rank()733p = Partition([x for x in reversed(range(1, n))])734# The column canonical tableau, read by columns735module_generator = flatten([[p[j]-i for i in range(p[j])] for j in range(n-1)])736return self(list=[self.letters(x) for x in module_generator])737738class Element(InfinityCrystalOfTableaux.Element):739r"""740Elements in `\mathcal{B}(\infty)` crystal of tableaux for type `D_n`.741"""742def e(self, i):743r"""744Return the action of `\widetilde{e}_i` on ``self``.745746INPUT:747748- ``i`` -- An element of the index set749750EXAMPLES::751752sage: B = InfinityCrystalOfTableaux(['D',4])753sage: b = B.highest_weight_vector().f_string([1,4,3,1,2]); b.pp()7541 1 1 1 2 37552 2 27563 -3757sage: b.e(2).pp()7581 1 1 1 2 27592 2 27603 -3761"""762if i not in self.index_set():763raise ValueError('i is not in the index set.')764position = self.positions_of_unmatched_plus(i)765if position == []:766return None767k = position[0]768ret = self.set_index(k, self[k].e(i))769if i == self.cartan_type().rank():770i -= 1771if k+i > len(self):772return ret773for j in reversed(range(1, i+1)):774if ret[k+i-j].value != j:775return ret776# We've found a column, so we need to remove it777for j in range(i):778ret._list.pop(k)779return ret780781def f(self, i):782r"""783Return the action of `\widetilde{f}_i` on ``self``.784785INPUT:786787- ``i`` -- An element of the index set788789EXAMPLES::790791sage: B = InfinityCrystalOfTableaux(['D',5])792sage: b = B.highest_weight_vector().f_string([1,4,3,1,5]); b.pp()7931 1 1 1 1 1 2 27942 2 2 2 27953 3 3 -57964 5797sage: b.f(1).pp()7981 1 1 1 1 1 2 2 27992 2 2 2 28003 3 3 -58014 5802sage: b.f(5).pp()8031 1 1 1 1 1 2 28042 2 2 2 28053 3 3 -58064 -4807"""808ret = InfinityCrystalOfTableaux.Element.f(self, i)809if ret._list[0].value == -self.cartan_type().rank():810# Exceptional case for f_n where we need to add a new column811for j in range(i-1):812ret._list.insert(0,self.parent().letters(j+1))813return ret814815816817