Path: blob/master/src/sage/combinat/crystals/generalized_young_walls.py
8817 views
r"""1Crystals of Generalized Young Walls23AUTHORS:45- Lucas David-Roesler: Initial version67- Ben Salisbury: Initial version89- Travis Scrimshaw: Initial version1011Generalized Young walls are certain generalizations of Young tableaux12introduced in [KS10]_ and designed to be a realization of the crystals13`\mathcal{B}(\infty)` and `\mathcal{B}(\lambda)` in type `A_n^{(1)}`.1415REFERENCES:1617.. [KS10] J.-A. Kim and D.-U. Shin.18Generalized Young walls and crystal bases for quantum affine algebra19of type `A`.20Proc. Amer. Math. Soc. 138(11), pp. 3877--3889, 2010.2122.. [KLRS] S.-J. Kang, K.-H. Lee, H. Ryu, and B. Salisbury.23A combinatorial description of the affine Gindikin-Karpelevich formula of24type `A_n^{(1)}`.25:arXiv:`1203.1640`.26"""2728#******************************************************************************29# Copyright (C) 201330#31# Lucas David-Roesler (roesler at lvc dot edu)32# Ben Salisbury (bsalisbury at ccny dot cuny dot edu)33# Travis Scrimshaw (tscrim at ucdavis dot edu)34#35# Distributed under the terms of the GNU General Public License (GPL)36# http://www.gnu.org/licenses/37#******************************************************************************3839import re40from copy import deepcopy41from sage.combinat.root_system.cartan_type import CartanType42from sage.structure.element import Element43from sage.structure.parent import Parent44from sage.structure.unique_representation import UniqueRepresentation45from sage.combinat.combinat import CombinatorialObject46from sage.categories.regular_crystals import RegularCrystals47from sage.categories.highest_weight_crystals import HighestWeightCrystals48from sage.categories.infinite_enumerated_sets import InfiniteEnumeratedSets49from sage.combinat.root_system.root_system import RootSystem50from sage.rings.infinity import Infinity5152class GeneralizedYoungWall(CombinatorialObject, Element):53r"""54A generalized Young wall.5556For more information, see :class:`InfinityCrystalOfGeneralizedYoungWalls`.5758EXAMPLES::5960sage: Y = InfinityCrystalOfGeneralizedYoungWalls(4)61sage: mg = Y.module_generators[0]; mg.pp()62063sage: mg.f_string([1,2,0,1]).pp()641|2|650|1|66|67"""68def __init__(self,parent,data):69r"""70EXAMPLES::7172sage: Y = InfinityCrystalOfGeneralizedYoungWalls(2)73sage: mg = Y.module_generators[0]74sage: TestSuite(mg).run()75"""76i = len(data)-177while i >= 0 and len(data[i]) == 0:78data.pop()79i -= 180self.rows = len(data)81if data == []:82self.cols = 083else:84self.cols = max([len(r) for r in data])85self.data = data86CombinatorialObject.__init__(self, data)87Element.__init__(self, parent)8889def __repr__(self):90r"""91EXAMPLES::9293sage: y = InfinityCrystalOfGeneralizedYoungWalls(3)([[0],[1,0,3,2],[2,1],[3,2,1,0,3,2],[0],[],[2]])94sage: y95[[0], [1, 0, 3, 2], [2, 1], [3, 2, 1, 0, 3, 2], [0], [], [2]]96"""97return self.data.__repr__()9899def __eq__(self,other):100r"""101EXAMPLES::102103sage: GYW = InfinityCrystalOfGeneralizedYoungWalls(2)104sage: y = GYW([[],[1,0],[2,1]])105sage: x = GYW([[],[1,0],[2,1]])106sage: z = GYW([[],[1],[2]])107sage: x == y108True109sage: x == z110False111"""112if isinstance(other, GeneralizedYoungWall):113return self.data == other.data114return self.data == other115116def raw_signature(self, i):117r"""118Return the sequence from `\{+,-\}` obtained from all `i`-admissible119slots and removable `i`-boxes without canceling any `(+,-)`-pairs.120The result also notes the row and column of the sign.121122EXAMPLES::123124sage: x = InfinityCrystalOfGeneralizedYoungWalls(3)([[],[1,0,3,2],[2,1],[3,2,1,0,3,2],[],[],[2]])125sage: x.raw_signature(2)126[['-', 3, 6], ['-', 1, 4], ['-', 6, 1]]127"""128sig = []129rank = self.parent().cartan_type().rank() # n+1130for row in range(self.rows):131if self.data[row] == [] and i == ( row % rank ):132sig.append(['+', row, 0])133elif self.data[row] == []:134continue135elif self.data[row][-1] == ( (i+1) % rank ):136sig.append(['+', row, len(self.data[row])+1])137elif self.data[row][-1] == i:138sig.append(['-', row, len(self.data[row])])139return sorted(sig, key=self._sig_sort)140141def _sig_sort(self,a):142r"""143Internal command used to appropriately sort the output144from :meth:`raw_signature()`.145146INPUT:147148- `a` -- list of the form ``['s',j,k]`` where `s` is a string, `j` is an integer149and `k` is an integer150151EXAMPLES::152153sage: hw = InfinityCrystalOfGeneralizedYoungWalls(5)([])154sage: hw._sig_sort(['+',1,0])155(0, 1)156"""157return (-a[2],a[1])158159def generate_signature(self, i):160r"""161The `i`-signature of ``self`` (with whitespace where cancellation162occurs) together with the unreduced sequence from `\{+,-\}`. The163result also records to the row and column position of the sign.164165EXAMPLES::166167sage: y = InfinityCrystalOfGeneralizedYoungWalls(2)([[0],[1,0],[2,1,0,2],[],[1]])168sage: y.generate_signature(1)169([['+', 2, 5], ['-', 4, 1]], ' ')170"""171sig = []172rank = self.parent().cartan_type().classical().rank()173for row in range(self.rows):174if self.data[row] == [] and i == ( row % (rank+1) ):175sig.append(['+', row, 0])176elif self.data[row] == []:177continue178elif self.data[row][-1] == ( (i+1) % (rank+1) ):179sig.append(['+', row, len(self.data[row])+1])180elif self.data[row][-1] == i:181sig.append(['-', row, len(self.data[row])])182sig = sorted(sig, key=self._sig_sort)183strsig = ''.join( x[0] for x in sig)184reducedsig = strsig185while re.search(r"\+\s*-",reducedsig):186reducedsig = re.sub(r"\+\s*-", lambda match : str().ljust(len(match.group(int(0)))) , reducedsig)187return (sig,reducedsig)188189def signature(self, i):190r"""191Return the `i`-signature of ``self``.192193The signature is obtained by reading ``self`` in columns bottom to top starting from the left.194Then add a `-` at every `i`-box which may be removed from ``self`` and still obtain a legal195generalized Young wall, and add a `+` at each site for which an `i`-box may be added and still196obtain a valid generalized Young wall. Then successively cancel any `(+,-)`-pair to obtain a197sequence of the form `- \cdots -+ \cdots +`. This resulting sequence is the output.198199EXAMPLES::200201sage: y = InfinityCrystalOfGeneralizedYoungWalls(2)([[0],[1,0],[2,1,0,2],[],[1]])202sage: y.signature(1)203''204205sage: x = InfinityCrystalOfGeneralizedYoungWalls(3)([[],[1,0,3,2],[2,1],[3,2,1,0,3,2],[],[],[2]])206sage: x.signature(2)207'---'208"""209return self.generate_signature(i)[1].strip()210211def pp(self):212r"""213Return an ASCII drawing of ``self``.214215EXAMPLES::216217sage: y = InfinityCrystalOfGeneralizedYoungWalls(2)([[0,2,1],[1,0,2,1,0],[],[0],[1,0,2],[],[],[1]])218sage: y.pp()2191|220|221|2222|0|1|2230|224|2250|1|2|0|1|2261|2|0|227"""228for row in reversed(self.data):229wall = ''230for elem in reversed(row):231wall += str(elem)232wall += '|'233if row == []:234wall += '|'235print(wall.rjust(2*self.cols+1))236if self.data==[]:237print '0'238239def content(self):240r"""241Return total number of blocks in ``self``.242243EXAMPLES::244245sage: y = InfinityCrystalOfGeneralizedYoungWalls(2)([[0],[1,0],[2,1,0,2],[],[1]])246sage: y.content()2478248249sage: x = InfinityCrystalOfGeneralizedYoungWalls(3)([[],[1,0,3,2],[2,1],[3,2,1,0,3,2],[],[],[2]])250sage: x.content()25113252"""253return sum(len(r) for r in self.data)254255def number_of_parts(self):256r"""257Return the value of `\mathscr{N}` on ``self``.258259In [KLRS]_, the statistic `\mathscr{N}` was defined on elements in260`\mathcal{Y}(\infty)` which counts how many parts are in the261corresponding Kostant partition. Specifically, the computation of262`\mathscr{N}(Y)` is done using the following algorithm:263264- If `Y` has no rows whose right-most box is colored `n` and such that265the length of this row is a multiple of `n+1`, then `\mathscr{N}(Y)`266is the total number of distinct rows in `Y`, not counting multiplicity.267268- Otherwise, search `Y` for the longest row such that the right-most box269is colored `n` and such that the total number of boxes in the row is270`k(n+1)` for some `k\ge 1`. Replace this row by `n+1` distinct rows271of length `k`, reordering all rows, if necessary, so that the result272is a proper wall. (Note that the resulting wall may no longer be273reduced.) Repeat the search and replace process for all other rows of274the above form for each `k' < k`. Then `\mathscr{N}(Y)` is the number275of distinct rows, not counting multipicity, in the wall resulting from276this process.277278EXAMPLES::279280sage: Y = InfinityCrystalOfGeneralizedYoungWalls(3)281sage: y = Y([[0],[],[],[],[0],[],[],[],[0]])282sage: y.number_of_parts()2831284285sage: Y = InfinityCrystalOfGeneralizedYoungWalls(3)286sage: y = Y([[0,3,2],[1,0],[],[],[0,3],[1,0],[],[],[0]])287sage: y.number_of_parts()2884289290sage: Y = InfinityCrystalOfGeneralizedYoungWalls(2)291sage: y = Y([[0,2,1],[1,0],[2,1,0,2,1,0,2,1,0],[],[2,1,0,2,1,0]])292sage: y.number_of_parts()2938294"""295n = self.parent().cartan_type().rank()-1296new = self.data[:]297i = 0298while i < len(new):299r = new[i]300if r == [] or r in new[i+1:]:301new.pop(i)302elif r[0] == n and len(r)%(n+1) == 0:303for j in range(n+1):304temp = [k%(n+1) for k in range(j+len(r)/(n+1)-1,j-1,-1)]305if temp not in new:306new.insert(i+1, temp)307new.pop(i)308else:309i += 1310return len(new)311312def sum_of_weighted_row_lengths(self):313r"""314Return the value of `\mathscr{M}` on ``self``.315316Let `\mathcal{Y}_0 \subset \mathcal{Y}(\infty)` be the set of317generalized Young walls which have no rows whose right-most box is318colored `n`. For `Y \in \mathcal{Y}_0`,319320.. MATH::321322\mathscr{M}(Y) = \sum_{i=1}^n (i+1)M_i(Y),323324where `M_i(Y)` is the number of nonempty rows in `Y` whose right-most325box is colored `i-1`.326327EXAMPLES::328329sage: Y = InfinityCrystalOfGeneralizedYoungWalls(2)330sage: y = Y([[0,2,1,0,2],[1,0,2],[],[0,2],[1,0],[],[0],[1,0]])331sage: y.sum_of_weighted_row_lengths()33215333"""334n = self.parent().cartan_type().rank()-1335m = lambda i : len([r for r in self.data if r!=[] if r[0]==(i-1)%(n+1)])336for r in self.data:337if r != [] and r[0] == n:338raise ValueError('Statistic only valid for generalized Young walls in Y_0')339return sum((i+1)*m(i) for i in range(1,n+1))340341def e(self,i):342r"""343Return the application of the Kashiwara raising operator344`\widetilde{e}_i` on ``self``.345346This will remove the `i`-colored box corresponding to the347rightmost `+` in ``self.signature(i)``.348349EXAMPLES::350351sage: x=InfinityCrystalOfGeneralizedYoungWalls(3)([[],[1,0,3,2],[2,1],[3,2,1,0,3,2],[],[],[2]])352sage: x.e(2)353[[], [1, 0, 3, 2], [2, 1], [3, 2, 1, 0, 3, 2]]354sage: _.e(2)355[[], [1, 0, 3], [2, 1], [3, 2, 1, 0, 3, 2]]356sage: _.e(2)357[[], [1, 0, 3], [2, 1], [3, 2, 1, 0, 3]]358sage: _.e(2)359"""360signature = self.generate_signature(i)361raw_signature = signature[0]362lastminus = signature[1].rfind('-')363newdata = []364if lastminus > -1:365deletionrow = raw_signature[lastminus][1]366for r in range(self.rows):367if r == deletionrow:368newdata.append(list(self.data[r][:-1]))369else:370newdata.append(list(self.data[r]))371return self.__class__(self.parent(),newdata)372else:373return None374375def f(self,i):376r"""377Return the application of the Kashiwara lowering operator378`\widetilde{f}_i` on ``self``.379380This will add an `i`-colored colored box to the site corresponding381to the leftmost plus in ``self.signature(i)``.382383EXAMPLES::384385sage: hw = InfinityCrystalOfGeneralizedYoungWalls(2)([])386sage: hw.f(1)387[[], [1]]388sage: _.f(2)389[[], [1], [2]]390sage: _.f(0)391[[], [1, 0], [2]]392sage: _.f(0)393[[0], [1, 0], [2]]394"""395signature = self.generate_signature(i)396raw_signature = signature[0]397firstplus = signature[1].find('+')398newdata = deepcopy(self.data)399if firstplus > -1:400additionrow = raw_signature[firstplus][1]401newdata[additionrow].append(i)402else:403while len(newdata) % self.cartan_type().rank() != i:404newdata.append([])405newdata.append([i])406return self.__class__(self.parent(), newdata)407408def latex_large(self):409r"""410Generate LaTeX code for ``self`` but the output is larger.411Requires TikZ.412413EXAMPLES::414415sage: x = InfinityCrystalOfGeneralizedYoungWalls(3)([[],[1,0,3,2],[2,1],[3,2,1,0,3,2],[],[],[2]])416sage: x.latex_large()417'\\begin{tikzpicture}[baseline=5,scale=.45] \n \\foreach \\x [count=\\s from 0] in \n{{},{1,0,3,2},{2,1},{3,2,1,0,3,2},{},{},{2}} \n{\\foreach \\y [count=\\t from 0] in \\x { \\node[font=\\scriptsize] at (-\\t,\\s) {$\\y$}; \n \\draw (-\\t+.5,\\s+.5) to (-\\t-.5,\\s+.5); \n \\draw (-\\t+.5,\\s-.5) to (-\\t-.5,\\s-.5); \n \\draw (-\\t-.5,\\s-.5) to (-\\t-.5,\\s+.5); } \n \\draw[-,thick] (.5,\\s+1) to (.5,-.5) to (-\\t-1,-.5); } \n \\end{tikzpicture} \n'418"""419s = ""420if self.data == []:421s += "\\emptyset"422else:423s += "\\begin{tikzpicture}[baseline=5,scale=.45] \n \\foreach \\x [count=\\s from 0] in \n"424s += "{" + ','.join("{" + ','.join( str(i) for i in r ) + "}" for r in self.data ) + "} \n"425s += "{\\foreach \\y [count=\\t from 0] in \\x { \\node[font=\\scriptsize] at (-\\t,\\s) {$\\y$}; \n \draw (-\\t+.5,\\s+.5) to (-\\t-.5,\\s+.5); \n \draw (-\\t+.5,\\s-.5) to (-\\t-.5,\\s-.5); \n \draw (-\\t-.5,\\s-.5) to (-\\t-.5,\\s+.5); } \n \draw[-,thick] (.5,\\s+1) to (.5,-.5) to (-\\t-1,-.5); } \n \\end{tikzpicture} \n"426return s427428def _latex_(self):429r"""430Generate LaTeX code for ``self``. Requires TikZ.431432EXAMPLES::433434sage: x = InfinityCrystalOfGeneralizedYoungWalls(3)([[],[1,0,3,2],[2,1],[3,2,1,0,3,2],[],[],[2]])435sage: x._latex_()436'\\begin{tikzpicture}[baseline=5,scale=.25] \\foreach \\x [count=\\s from 0] in \n{{},{1,0,3,2},{2,1},{3,2,1,0,3,2},{},{},{2}} \n{\\foreach \\y [count=\\t from 0] in \\x { \\node[font=\\tiny] at (-\\t,\\s) {$\\y$}; \n \\draw (-\\t+.5,\\s+.5) to (-\\t-.5,\\s+.5); \n \\draw (-\\t+.5,\\s-.5) to (-\\t-.5,\\s-.5); \n \\draw (-\\t-.5,\\s-.5) to (-\\t-.5,\\s+.5); } \n \\draw[-] (.5,\\s+1) to (.5,-.5) to (-\\t-1,-.5); } \n \\end{tikzpicture} \n'437"""438s = ""439if self.data == []:440s += "\\emptyset"441else:442s += "\\begin{tikzpicture}[baseline=5,scale=.25] \\foreach \\x [count=\\s from 0] in \n"443s += "{" + ','.join("{" + ','.join( str(i) for i in r ) + "}" for r in self.data ) + "} \n"444s += "{\\foreach \\y [count=\\t from 0] in \\x { \\node[font=\\tiny] at (-\\t,\\s) {$\\y$}; \n \draw (-\\t+.5,\\s+.5) to (-\\t-.5,\\s+.5); \n \draw (-\\t+.5,\\s-.5) to (-\\t-.5,\\s-.5); \n \draw (-\\t-.5,\\s-.5) to (-\\t-.5,\\s+.5); } \n \draw[-] (.5,\\s+1) to (.5,-.5) to (-\\t-1,-.5); } \n \\end{tikzpicture} \n"445return s446447def weight(self):448r"""449Returns the weight of ``self`` as an element of the root lattice450`\bigoplus_{i=0}^n \ZZ \alpha_i`.451452EXAMPLES::453454sage: x=InfinityCrystalOfGeneralizedYoungWalls(3)([[],[1,0,3,2],[2,1],[3,2,1,0,3,2],[],[],[2]])455sage: x.weight()456-2*alpha[0] - 3*alpha[1] - 5*alpha[2] - 3*alpha[3]457"""458W = []459L = self.cartan_type().root_system().root_lattice()460alpha = L.simple_roots()461for r in self.data:462for i in r:463W.append(-1*alpha[i])464return L(sum(w for w in W))465466def epsilon(self, i):467r"""468Return the number of `i`-colored arrows in the `i`-string above469``self`` in the crystal graph.470471EXAMPLES::472473sage: y=InfinityCrystalOfGeneralizedYoungWalls(3)([[],[1,0,3,2],[2,1],[3,2,1,0,3,2],[],[],[2]])474sage: y.epsilon(1)4750476sage: y.epsilon(2)4773478sage: y.epsilon(0)4790480"""481if i not in self.index_set():482raise ValueError("i must in in the index set")483eps = 0484while True:485self = self.e(i)486if self is None:487break488eps = eps+1489return eps490491def Epsilon(self):492r"""493Return `\sum_{i=0}^n \varepsilon_i(Y) \Lambda_i` where `Y` is ``self``.494495EXAMPLES::496497sage: y = InfinityCrystalOfGeneralizedYoungWalls(3)([[0],[1,0,3,2],[2,1],[3,2,1,0,3,2],[0],[],[2]])498sage: y.Epsilon()499Lambda[0] + 3*Lambda[2]500"""501La = self.cartan_type().root_system().weight_lattice().fundamental_weights()502return sum(self.epsilon(i)*La[i] for i in self.index_set())503504def phi(self,i):505r"""506Return the value `\varepsilon_i(Y) + \langle h_i,507\mathrm{wt}(Y)\rangle`, where `h_i` is the `i`-th simple508coroot and `Y` is ``self``.509510EXAMPLES::511512sage: y = InfinityCrystalOfGeneralizedYoungWalls(3)([[0],[1,0,3,2],[2,1],[3,2,1,0,3,2],[0],[],[2]])513sage: y.phi(1)5143515sage: y.phi(2)516-1517"""518h = self.parent().weight_lattice_realization().simple_coroots()519return self.epsilon(i) + self.weight().scalar(h[i])520521def Phi(self):522r"""523Return `\sum_{i=0}^n \varphi_i(Y) \Lambda_i` where `Y` is ``self``.524525EXAMPLES::526527sage: y = InfinityCrystalOfGeneralizedYoungWalls(3)([[0],[1,0,3,2],[2,1],[3,2,1,0,3,2],[0],[],[2]])528sage: y.Phi()529-Lambda[0] + 3*Lambda[1] - Lambda[2] + 3*Lambda[3]530531sage: x=InfinityCrystalOfGeneralizedYoungWalls(3)([[],[1,0,3,2],[2,1],[3,2,1,0,3,2],[],[],[2]])532sage: x.Phi()5332*Lambda[0] + Lambda[1] - Lambda[2] + Lambda[3]534"""535La = self.cartan_type().root_system().weight_lattice().fundamental_weights()536return sum(self.phi(i)*La[i] for i in self.index_set())537538def column(self, k):539r"""540Return the list of boxes from the ``k``-th column of ``self``.541542EXAMPLES::543544sage: y = InfinityCrystalOfGeneralizedYoungWalls(3)([[0],[1,0,3,2],[2,1],[3,2,1,0,3,2],[0],[],[2]])545sage: y.column(2)546[None, 0, 1, 2, None, None, None]547548sage: hw = InfinityCrystalOfGeneralizedYoungWalls(5)([])549sage: hw.column(1)550[]551"""552C = []553for row in self.data:554if k-1 < len(row):555C.append(row[k-1])556else:557C.append(None)558return C559560def a(self,i,k):561r"""562Return the number `a_i(k)` of `i`-colored boxes in the ``k``-th563column of ``self``.564565EXAMPLES::566567sage: y = InfinityCrystalOfGeneralizedYoungWalls(3)([[0],[1,0,3,2],[2,1],[3,2,1,0,3,2],[0],[],[2]])568sage: y.a(1,2)5691570sage: y.a(0,2)5711572sage: y.a(3,2)5730574"""575A = []576for c in range(len(self.column(k))):577if self.column(k)[c] == i:578A.append(self.column(k)[c])579return len(A)580581def in_highest_weight_crystal(self,La):582r"""583Return a boolean indicating if the generalized Young wall element584is in the highest weight crystal cut out by the given highest weight585``La``.586587By Theorem 4.1 of [KS10]_, a generalized Young wall `Y` represents a588vertex in the highest weight crystal `Y(\lambda)`, with589`\lambda = \Lambda_{i_1} + \Lambda_{i_2} + \cdots + \Lambda_{i_\ell}`590a dominant integral weight of level `\ell > 0`, if it satisfies the591following condition. For each positive integer `k`, if there exists592`j \in I` such that `a_j(k) - a_{j-1}(k) > 0`, then for some593`p = 1, \ldots, \ell`,594595.. MATH::596597j + k \equiv i_p + 1 \bmod n+1 \text{ and } a_j(k) - a_{j-1}(k)598\le \lambda(h_{i_p}),599600where `\{h_0, h_1, \ldots, h_n\}` is the set of simple coroots attached601to `A_n^{(1)}`.602603EXAMPLES::604605sage: La = RootSystem(['A',2,1]).weight_lattice().fundamental_weights()[1]606sage: GYW = InfinityCrystalOfGeneralizedYoungWalls(2)607sage: y = GYW([[],[1,0],[2,1]])608sage: y.in_highest_weight_crystal(La)609True610sage: x = GYW([[],[1],[2],[],[],[2],[],[],[2]])611sage: x.in_highest_weight_crystal(La)612False613"""614if not La in self.parent().weight_lattice_realization():615raise TypeError("Must be an element in the weight lattice realization")616ac = self.parent().weight_lattice_realization().simple_coroots()617n = self.cartan_type().classical().rank()618for k in range(1,self.cols+1):619for j in self.index_set():620if self.a(j,k) - self.a( (j-1) % (n+1) ,k) <= 0:621continue622else:623p_not_found = True624for p in self.index_set():625if (j+k) % (n+1) == (p+1) % (n+1) and self.a(j,k) - self.a( (j-1) % (n+1) ,k) <= La.scalar(ac[p]):626p_not_found = False627continue628else:629continue630if p_not_found:631return False632return True633634635class InfinityCrystalOfGeneralizedYoungWalls(Parent,UniqueRepresentation):636r"""637The crystal `\mathcal{Y}(\infty)` of generalized Young walls of638type `A_n^{(1)}` as defined in [KS10]_.639640A generalized Young wall is a collection of boxes stacked on a fixed board,641such that color of the box at the site located in the `j`-th row from the642bottom and the `i`-th column from the right is `j-1 \bmod n+1`. There are643several growth conditions on elements in `Y \in \mathcal{Y}(\infty)`:644645- Walls grow in rows from right to left. That is, for every box `y\in Y`646that is not in the rightmost column, there must be a box immediately to647the right of `y`.648649- For all `p>q` such that `p-q \equiv 0 \bmod n+1`, the `p`-th row has650most as many boxes as the `q`-th row.651652- There does not exist a column in the wall such that if one `i`-colored653box, for every `i = 0,1,\ldots,n`, is removed from that column, then the654result satisfies the above conditions.655656There is a crystal structure on `\mathcal{Y}(\infty)` defined as follows.657Define maps658659.. MATH::660661\widetilde{e}_i,\ \widetilde{f}_i \colon \mathcal{Y}(\infty)662\longrightarrow \mathcal{Y}(\infty) \sqcup \{0\}, \qquad663\varepsilon_i,\ \varphi_i \colon \mathcal{Y}(\infty)664\longrightarrow \ZZ, \qquad665\mathrm{wt}\colon \mathcal{Y}(\infty) \longrightarrow666\bigoplus_{i=0}^n \ZZ \Lambda_i,667668by669670.. MATH::671672\mathrm{wt}(Y) = -\sum_{i=0}^n m_i(Y) \alpha_i,673674where `m_i(Y)` is the number of `i`-boxes in `Y`, `\varepsilon_i(Y)`675is the number of `-` in the `i`-signature of `Y`, and676677.. MATH::678679\varphi_i(Y) = \varepsilon_i(Y) + \langle h_i, \mathrm{wt}(Y) \rangle.680681See :meth:`GeneralizedYoungWall.e()`, :meth:`GeneralizedYoungWall.f()`,682and :meth:`GeneralizedYoungWall.signature()` for more about683`\widetilde{e}_i`, `\widetilde{f}_i`, and `i`-signatures.684685686INPUT:687688- ``n`` -- type `A_n^{(1)}`689690EXAMPLES::691692sage: Yinf = InfinityCrystalOfGeneralizedYoungWalls(3)693sage: y = Yinf([[0],[1,0,3,2],[],[3,2,1],[0],[1,0]])694sage: y.pp()6950|1|6960|6971|2|3|698|6992|3|0|1|7000|701sage: y.weight()702-4*alpha[0] - 3*alpha[1] - 2*alpha[2] - 2*alpha[3]703sage: y.f(0)704[[0], [1, 0, 3, 2], [], [3, 2, 1], [0], [1, 0], [], [], [0]]705sage: y.e(0).pp()7060|1|707|7081|2|3|709|7102|3|0|1|7110|712713To display the crystal down to depth 3::714715sage: S = Yinf.subcrystal(max_depth=3)716sage: G = Yinf.digraph(subset=S) # long time717sage: view(G, tightpage=True) # not tested718"""719720@staticmethod721def __classcall_private__(cls, n, category=None):722r"""723Normalize input to ensure a unique representation.724725INPUT:726727- ``n`` -- type `A_n^{(1)}`728729EXAMPLES::730731sage: Yinf = InfinityCrystalOfGeneralizedYoungWalls(3)732sage: Yinf2 = InfinityCrystalOfGeneralizedYoungWalls(int(3))733sage: Yinf is Yinf2734True735"""736return super(InfinityCrystalOfGeneralizedYoungWalls,cls).__classcall__(cls,n,category)737738def __init__(self, n, category):739r"""740EXAMPLES::741742sage: Yinf = InfinityCrystalOfGeneralizedYoungWalls(3)743sage: TestSuite(Yinf).run()744"""745self._cartan_type = CartanType(['A',n,1])746if category is None:747category = (HighestWeightCrystals(), InfiniteEnumeratedSets())748Parent.__init__(self, category=category)749self.module_generators = (self.element_class(self,[]),)750751Element = GeneralizedYoungWall752753def _element_constructor_(self,data):754r"""755Construct an element of ``self`` from ``data``.756757INPUT:758759- ``data`` -- a multilist760761EXAMPLES::762763sage: GYW = InfinityCrystalOfGeneralizedYoungWalls(2)764sage: y = GYW([[],[1,0],[2,1]]) # indirect doctest765sage: y766[[], [1, 0], [2, 1]]767"""768return self.element_class(self,data)769770def _repr_(self):771r"""772EXAMPLES::773774sage: Y = InfinityCrystalOfGeneralizedYoungWalls(4)775sage: Y776Crystal of generalized Young walls of type ['A', 4, 1]777"""778return "Crystal of generalized Young walls of type %s" % self._cartan_type779780def subset(self, max_depth=4):781r"""782Construct the subcrystal of ``self`` trucated at depth ``max_depth``.783784EXAMPLES::785786sage: Y = InfinityCrystalOfGeneralizedYoungWalls(2)787sage: S = Y.subset(max_depth=2)788sage: S789[[], [[], [1]], [[], [], [2]], [[0]], [[0, 2]], [[0], [1]], [[], [], [2], [], [], [2]],790[[], [1], [2]], [[0], [], [], [0]], [[0], [], [2]], [[], [], [2, 1]], [[], [1], [], [], [1]], [[], [1, 0]]]791"""792return [c for c in self.subcrystal(max_depth=max_depth, direction='lower')]793794795########################796## Highest weight GYW ##797########################798799class CrystalOfGeneralizedYoungWallsElement(GeneralizedYoungWall):800r"""801Element of the highest weight crystal of generalized Young walls.802"""803804def e(self,i):805r"""806Compute the action of `\widetilde{e}_i` restricted to the highest weight crystal.807808EXAMPLES::809810sage: La = RootSystem(['A',2,1]).weight_lattice().fundamental_weights()[1]811sage: hwy = CrystalOfGeneralizedYoungWalls(2,La)([[],[1,0],[2,1]])812sage: hwy.e(1)813[[], [1, 0], [2]]814sage: hwy.e(2)815sage: hwy.e(3)816"""817ret = GeneralizedYoungWall.e(self, i)818if ret is None:819return None820if ret.in_highest_weight_crystal(self.parent().hw):821return self.__class__(self.parent(),ret.data)822return None823824def f(self,i):825r"""826Compute the action of `\widetilde{f}_i` restricted to the highest weight crystal.827828EXAMPLES::829830sage: La = RootSystem(['A',2,1]).weight_lattice().fundamental_weights()[1]831sage: GYW = InfinityCrystalOfGeneralizedYoungWalls(2)832sage: y = GYW([[],[1,0],[2,1]])833sage: y.f(1)834[[], [1, 0], [2, 1], [], [1]]835sage: hwy = CrystalOfGeneralizedYoungWalls(2,La)([[],[1,0],[2,1]])836sage: hwy.f(1)837"""838ret = GeneralizedYoungWall.f(self, i)839if ret.in_highest_weight_crystal(self.parent().hw):840return self.__class__(self.parent(),ret.data)841return None842843def weight(self):844r"""845Return the weight of ``self`` in the highest weight crystal as an846element of the weight lattice `\bigoplus_{i=0}^n \ZZ \Lambda_i`.847848EXAMPLES::849850sage: La = RootSystem(['A',2,1]).weight_lattice().fundamental_weights()[1]851sage: hwy = CrystalOfGeneralizedYoungWalls(2,La)([[],[1,0],[2,1]])852sage: hwy.weight()853Lambda[0] - Lambda[1] + Lambda[2]854"""855return self.parent().weight_lattice_realization()(self.parent().hw + GeneralizedYoungWall.weight(self))856857858class CrystalOfGeneralizedYoungWalls(InfinityCrystalOfGeneralizedYoungWalls):859r"""860The crystal `\mathcal{Y}(\lambda)` of generalized Young walls of the given861type with highest weight `\lambda`.862863These were characterized in Theorem 4.1 of [KS10]_.864See :meth:`GeneralizedYoungWall.in_highest_weight_crystal()`.865866INPUT:867868- ``n`` -- type `A_n^{(1)}`869870- ``weight`` -- dominant integral weight871872EXAMPLES::873874sage: La = RootSystem(['A',3,1]).weight_lattice().fundamental_weights()[1]875sage: YLa = CrystalOfGeneralizedYoungWalls(3,La)876sage: y = YLa([[0],[1,0,3,2,1],[2,1,0],[3]])877sage: y.pp()8783|8790|1|2|8801|2|3|0|1|8810|882sage: y.weight()883-Lambda[0] + Lambda[2] + Lambda[3]884sage: y.in_highest_weight_crystal(La)885True886sage: y.f(1)887[[0], [1, 0, 3, 2, 1], [2, 1, 0], [3], [], [1]]888sage: y.f(1).f(1)889sage: yy = InfinityCrystalOfGeneralizedYoungWalls(3)([[0], [1, 0, 3, 2, 1], [2, 1, 0], [3], [], [1]])890sage: yy.f(1)891[[0], [1, 0, 3, 2, 1], [2, 1, 0], [3], [], [1], [], [], [], [1]]892sage: yyy = yy.f(1)893sage: yyy.in_highest_weight_crystal(La)894False895896sage: LS = CrystalOfLSPaths(['A',3,1],[1,0,0,0])897sage: C = LS.subcrystal(max_depth=4)898sage: G = LS.digraph(subset=C)899sage: P = LS.weight_lattice_realization()900sage: La = P.fundamental_weights()901sage: YW = CrystalOfGeneralizedYoungWalls(3,La[0])902sage: CW = YW.subcrystal(max_depth=4)903sage: GW = YW.digraph(subset=CW)904sage: GW.is_isomorphic(G,edge_labels=True)905True906907To display the crystal down to a specified depth::908909sage: S = YLa.subset(max_depth=4)910sage: sorted(list(S))911[[], [[], [1]], [[], [1], [2]], [[], [1], [2], [3]], [[], [1, 0]], [[], [1, 0], [2]], [[], [1, 0], [2], [3]], [[], [1, 0], [2, 1]], [[], [1, 0, 3]], [[], [1, 0, 3], [2]], [[], [1, 0, 3, 2]]]912sage: G = YLa.digraph(subset=S)913sage: view(G, tightpage=True) # not tested914"""915@staticmethod916def __classcall_private__(cls, n, La):917r"""918EXAMPLES::919920sage: La = RootSystem(['A',2,1]).weight_lattice().fundamental_weights()[2]921sage: Al = RootSystem(['A',2,1]).weight_lattice().monomial(2)922sage: Y = CrystalOfGeneralizedYoungWalls(2,La)923sage: Y1 = CrystalOfGeneralizedYoungWalls(int(2),Al)924sage: Y is Y1925True926"""927La = RootSystem(['A',n,1]).weight_lattice()(La)928return super(CrystalOfGeneralizedYoungWalls, cls).__classcall__(cls, n, La)929930def __init__(self, n, La):931r"""932EXAMPLES::933934sage: La = RootSystem(['A',2,1]).weight_lattice().fundamental_weights()[1]935sage: YLa = CrystalOfGeneralizedYoungWalls(2,La)936937We skip the two tests because they take a very long time::938939sage: TestSuite(YLa).run(skip=["_test_enumerated_set_contains","_test_stembridge_local_axioms"]) # long time940"""941InfinityCrystalOfGeneralizedYoungWalls.__init__( self, n,942category=(RegularCrystals(), HighestWeightCrystals(), InfiniteEnumeratedSets()) )943self.hw = La944945Element = CrystalOfGeneralizedYoungWallsElement946947def __repr__(self):948r"""949EXAMPLES::950951sage: La = RootSystem(['A',5,1]).weight_lattice().fundamental_weights()[2]952sage: Y = CrystalOfGeneralizedYoungWalls(5,La)953sage: Y954Highest weight crystal of generalized Young walls of Cartan type ['A', 5, 1] and highest weight Lambda[2].955"""956return "Highest weight crystal of generalized Young walls of Cartan type {1!s} and highest weight {0!s}.".format(self.hw, self._cartan_type)957958def __iter__(self):959r"""960EXAMPLES::961962sage: y = InfinityCrystalOfGeneralizedYoungWalls(3)([[0],[1,0,3,2],[2,1],[3,2,1,0,3,2],[0],[],[2]])963sage: x = y.__iter__()964sage: x.next()965[0]966"""967for c in self.subcrystal(direction='lower'):968if c.in_highest_weight_crystal(self.hw) :969yield c970971def subset(self, max_depth=4):972r"""973Return a subset of ``self`` up to ``max_depth``.974975EXAMPLES::976977sage: Y = CrystalOfGeneralizedYoungWalls(2,RootSystem(['A',2,1]).weight_lattice().fundamental_weights()[0])978sage: S = Y.subset(max_depth=3)979sage: S980[[], [[0]], [[0, 2]], [[0], [1]], [[0, 2, 1]], [[0, 2], [1]]]981"""982return [c for c in self.subcrystal(max_depth=max_depth, direction='lower')983if c.in_highest_weight_crystal(self.hw)]984985986987