Path: blob/master/sage/combinat/crystals/alcove_path.py
4096 views
r"""1Crystals of alcove paths2"""34#*****************************************************************************5# Copyright (C) 2008 Brant Jones <brant at math.ucdavis.edu>6#7# Distributed under the terms of the GNU General Public License (GPL)8# http://www.gnu.org/licenses/9#****************************************************************************1011from sage.structure.unique_representation import UniqueRepresentation12from sage.structure.parent import Parent13from sage.categories.classical_crystals import ClassicalCrystals14from sage.combinat.crystals.letters import Letter15from sage.combinat.root_system.cartan_type import CartanType16from sage.rings.integer import Integer17from sage.misc.misc import math,ellipsis_range18from sage.combinat.partition import Partitions19from sage.combinat.crystals.all import CrystalOfTableaux20from sage.combinat.root_system.root_system import RootSystem21from sage.graphs.graph import DiGraph22import copy2324#####################################################################25# Crystal (parent) class.26#####################################################################2728class ClassicalCrystalOfAlcovePaths(UniqueRepresentation, Parent):29r"""30Implementation of crystal of alcove paths of the given classical type with31given highest weight, based on the Lenart--Postnikov model [LP2008].3233These are highest weight crystals for classical types `A_n`, `B_n`, `C_n`,34`D_n` and the exceptional types `F_4`, `G_2`, `E_6`, `E_7`, `E_8`.3536INPUT:3738- ``cartan_type`` is the Cartan type of a classical Dynkin diagram39- ``highest_weight`` is a dominant weight as a list of coefficients of40the fundamental weights `Lambda_i`4142In this model, a chain of roots is associated to the given highest_weight,43and then the elements of the crystal are indexed by "admissible subsets"44which indicate "folding positions" along the chain of roots. See [LP2008]45for details.4647TODO:4849- Resolve speed issues; `E_6(\Lambda_1)` takes just under 4 minutes to list().50To construct the highest-weight node takes 15 sec for `E_6(\Lambda_4)`.51The initial chain has 42 roots.5253TESTS:5455The following example appears in Figure 2 of [LP2008]::5657sage: C = ClassicalCrystalOfAlcovePaths(['G',2],[0,1]);58sage: G = C.digraph()59sage: GG= DiGraph({60... () : {(0) : 2 },61... (0) : {(0,8) : 1 },62... (0,1) : {(0,1,7) : 2 },63... (0,1,2) : {(0,1,2,9) : 1 },64... (0,1,2,3) : {(0,1,2,3,4) : 2 },65... (0,1,2,6) : {(0,1,2,3) : 1 },66... (0,1,2,9) : {(0,1,2,6) : 1 },67... (0,1,7) : {(0,1,2) : 2 },68... (0,1,7,9) : {(0,1,2,9) : 2 },69... (0,5) : {(0,1) : 1, (0,5,7) : 2 },70... (0,5,7) : {(0,5,7,9) : 1 },71... (0,5,7,9) : {(0,1,7,9) : 1 },72... (0,8) : {(0,5) : 1 },73... })74sage: G.is_isomorphic(GG)75True7677sage: for edge in sorted([(u.value, v.value, i) for (u,v,i) in G.edges()]):78... print edge79([], [0], 2)80([0], [0, 8], 1)81([0, 1], [0, 1, 7], 2)82([0, 1, 2], [0, 1, 2, 9], 1)83([0, 1, 2, 3], [0, 1, 2, 3, 4], 2)84([0, 1, 2, 6], [0, 1, 2, 3], 1)85([0, 1, 2, 9], [0, 1, 2, 6], 1)86([0, 1, 7], [0, 1, 2], 2)87([0, 1, 7, 9], [0, 1, 2, 9], 2)88([0, 5], [0, 1], 1)89([0, 5], [0, 5, 7], 2)90([0, 5, 7], [0, 5, 7, 9], 1)91([0, 5, 7, 9], [0, 1, 7, 9], 1)92([0, 8], [0, 5], 1)9394REFERENCES:9596.. [LP2008] C. Lenart and A. Postnikov. A combinatorial model for crystals of Kac-Moody algebras. Trans. Amer. Math. Soc. 360 (2008), 4349-4381.97"""9899@staticmethod100def __classcall__(cls, cartan_type, highest_weight):101"""102cartan_type and heighest_weight are lists, which are mutable, this103causes a problem for class UniqueRepresentation, the following code104fixes this problem.105106EXAMPLES::107sage: ClassicalCrystalOfAlcovePaths.__classcall__(ClassicalCrystalOfAlcovePaths,['A',3],[0,1,0])108<class 'sage.combinat.crystals.alcove_path.ClassicalCrystalOfAlcovePaths_with_category'>109"""110cartan_type = CartanType(cartan_type)111highest_weight = tuple(highest_weight)112return super(ClassicalCrystalOfAlcovePaths, cls).__classcall__(cls, cartan_type, highest_weight)113114def __init__(self, cartan_type, highest_weight):115"""116EXAMPLES::117118sage: C = ClassicalCrystalOfAlcovePaths(['A',3],[1,0,0])119sage: C.list()120[[], [0], [0, 1], [0, 1, 2]]121sage: TestSuite(C).run()122"""123Parent.__init__(self, category = ClassicalCrystals())124self._cartan_type = CartanType(cartan_type)125self._name = "The crystal of alcove paths for type %s"%cartan_type126self.chain_cache = {}127self.endweight_cache = {}128129self.R = RootSystem(cartan_type)130alpha = self.R.root_space().simple_roots()131Lambda = self.R.weight_space().basis()132133self.positive_roots = sorted(self.R.root_space().positive_roots());134135self.weight = Lambda[Integer(1)] - Lambda[Integer(1)]136offset = self.R.index_set()[Integer(0)]137for j in self.R.index_set():138self.weight = self.weight + highest_weight[j-offset]*Lambda[j]139140self.initial_element = self([])141142self.initial_element.chain = self.get_initial_chain(self.weight)143rho = (Integer(1)/Integer(2))*sum(self.positive_roots)144self.initial_element.endweight = rho145146self.chain_cache[ str([]) ] = self.initial_element.chain147self.endweight_cache[ str([]) ] = self.initial_element.endweight148149self.module_generators = [self.initial_element]150151self._list = super(ClassicalCrystalOfAlcovePaths, self).list()152self._digraph = super(ClassicalCrystalOfAlcovePaths, self).digraph()153self._digraph_closure = self.digraph().transitive_closure()154155def get_initial_chain(self, highest_weight):156"""157Called internally by __init__() to construct the chain of roots158associated to the highest weight element.159160EXAMPLES::161sage: C = ClassicalCrystalOfAlcovePaths(['A',3],[0,1,0])162sage: C.get_initial_chain(RootSystem(['A',3]).weight_space().basis()[1])163[[alpha[1], alpha[1]], [alpha[1] + alpha[2], alpha[1] + alpha[2]], [alpha[1] + alpha[2] + alpha[3], alpha[1] + alpha[2] + alpha[3]]]164"""165pos_roots = self.positive_roots166tis = self.R.index_set()167tis.reverse()168cv_to_pos_root = {}169to_sort = []170for r in pos_roots:171j = highest_weight.scalar( r.associated_coroot() )172if (int(math.floor(j)) - j == Integer(0)):173j = j - Integer(1)174j = int(math.floor(j))175for k in (ellipsis_range(Integer(0),Ellipsis,j)):176cv = []177cv.append((Integer(1)/highest_weight.scalar(r.associated_coroot()))*k)178for i in tis:179cv.append((Integer(1)/highest_weight.scalar(r.associated_coroot()))*r.associated_coroot().coefficient(i))180cv_to_pos_root[ str(cv) ] = r181to_sort.append( cv )182183to_sort.sort() # Note: Python sorts nested lists lexicographically by default.184lambda_chain = []185for t in to_sort:186lambda_chain.append( [ cv_to_pos_root[str(t)], cv_to_pos_root[str(t)] ] )187return lambda_chain188189def _element_constructor_(self, value):190"""191Coerces value into self.192193EXAMPLES::194195sage: C = ClassicalCrystalOfAlcovePaths(['A',3],[1,0,0])196sage: C.module_generators197[[]]198sage: C([]).e(1)199sage: C([]).f(1)200[0]201"""202return self.element_class(self, value)203204def list(self):205"""206Returns a list of the elements of self.207208.. warning::209210This can be slow!211212EXAMPLES::213214sage: C = ClassicalCrystalOfAlcovePaths(['A',3],[0,1,0])215sage: C.list()216[[], [0], [0, 1], [0, 2], [0, 1, 2], [0, 1, 2, 3]]217"""218return self._list219220def digraph(self):221"""222Returns the directed graph associated to self.223224EXAMPLES::225226sage: C = ClassicalCrystalOfAlcovePaths(['A',3],[0,1,0])227sage: C.digraph().vertices()228[[], [0], [0, 1], [0, 2], [0, 1, 2], [0, 1, 2, 3]]229sage: C.digraph().edges()230[([], [0], 2), ([0], [0, 1], 1), ([0], [0, 2], 3), ([0, 1], [0, 1, 2], 3), ([0, 2], [0, 1, 2], 1), ([0, 1, 2], [0, 1, 2, 3], 2)]231"""232return self._digraph233234def lt_elements(self, x, y):235r"""236Returns True if and only if there is a path237from x to y in the crystal graph.238239Because the crystal graph is classical, it is a directed240acyclic graph which can be interpreted as a poset. This241function implements the comparison function of this poset.242243EXAMPLES::244245sage: C = ClassicalCrystalOfAlcovePaths(['A',3],[0,1,0])246sage: x = C([])247sage: y = C([0,2])248sage: C.lt_elements(x,y)249True250sage: C.lt_elements(y,x)251False252sage: C.lt_elements(x,x)253False254"""255assert x.parent() == self and y.parent() == self256if self._digraph_closure.has_edge(x,y):257return True258return False259260#####################################################################261# Element class.262#####################################################################263264class ClassicalCrystalOfAlcovePathsElement(Letter):265r"""266Crystal of alcove paths element267268These elements are indexed by "admissible subsets" which indicate "folding positions"269along the chain of roots. Not every subset corresponds to an element.270271TESTS::272273sage: C = ClassicalCrystalOfAlcovePaths(['A',3],[0,1,0])274sage: C.list()275[[], [0], [0, 1], [0, 2], [0, 1, 2], [0, 1, 2, 3]]276sage: [ [ x < y for y in C ] for x in C ]277[[False, True, True, True, True, True], [False, False, True, True, True, True], [False, False, False, False, True, True], [False, False, False, False, True, True], [False, False, False, False, False, True], [False, False, False, False, False, False]]278sage: C([]).parent()279<class 'sage.combinat.crystals.alcove_path.ClassicalCrystalOfAlcovePaths_with_category'>280sage: C([])281[]282sage: C([]) == C([0])283False284sage: C([]) == C([])285True286sage: C([]) < C([0])287True288sage: C([0,1]) < C([0,2])289False290sage: C([0,1]) < C([0,1,2,3])291True292sage: TestSuite(C).run()293"""294295def __init__(self, parent, value):296"""297INPUT:298299- ``value`` is an admissible subset, stored as a list.300301chain is a chain of roots. This is computed from value, using302get_chain_from_subset(). We do this lazily because it can be303expensive.304305endweight is the weight that lies at the end of the chain of roots.306307chain and endweight are cached (in the parent), and they are only308computed when required by E(), F() or weight().309310The weight of the element can be theoretically be computed from311endweight, although this is not yet implemented.312313EXAMPLES::314315sage: C = ClassicalCrystalOfAlcovePaths(['A',3],[0,1,0])316sage: C.list()317[[], [0], [0, 1], [0, 2], [0, 1, 2], [0, 1, 2, 3]]318sage: c = C([0,1])319sage: TestSuite(c).run()320"""321Letter.__init__(self, parent, value)322if (str(value) in parent.chain_cache.keys()):323self.chain = parent.chain_cache[ str(value) ]324self.endweight = parent.endweight_cache[ str(value) ]325else:326self.chain = None327self.endweight = None328329def get_chain_from_subset(self, verbose = False):330r"""331Returns a list of pairs of roots, from an admissible subset of332an initial chain of pairs of roots. Called internally by333__init__().334335EXAMPLES::336337sage: C = ClassicalCrystalOfAlcovePaths(['A',3],[0,1,0])338sage: C([]).get_chain_from_subset()339([[alpha[2], alpha[2]], [alpha[1] + alpha[2], alpha[1] + alpha[2]], [alpha[2] + alpha[3], alpha[2] + alpha[3]], [alpha[1] + alpha[2] + alpha[3], alpha[1] + alpha[2] + alpha[3]]], 3/2*alpha[1] + 2*alpha[2] + 3/2*alpha[3])340"""341rchain = []342# NT: Is a deep copy required?343rchain = copy.deepcopy(self.parent().initial_element.chain)344rend = copy.deepcopy(self.parent().initial_element.endweight)345J = sorted(copy.deepcopy(self.value))346J.reverse()347348if verbose == True:349print "**** get_chain_from_subset(): initial weight at infinity ", rend350for i in J:351(rchain, rend) = self.fold(i, rchain, rend)352if verbose == True:353print "**** get_chain_from_subset() after fold ", i, ": weight at infinity ", rend354return (rchain, rend)355356def fold(self, i, chain, endweight):357r"""358Returns a new chain that results from folding at position i.359Called internally by __init__().360361TESTS::362363sage: C = ClassicalCrystalOfAlcovePaths(['A',3],[0,1,0])364sage: C([0]).get_chain_from_subset()365([[alpha[2], -alpha[2]], [alpha[1], alpha[1]], [alpha[3], alpha[3]], [alpha[1] + alpha[2] + alpha[3], alpha[1] + alpha[2] + alpha[3]]], 3/2*alpha[1] + alpha[2] + 3/2*alpha[3])366"""367s = self.parent().R.root_space().reflection(chain[i][Integer(0)])368chain[i][Integer(1)] = s(chain[i][Integer(1)])369for j in (ellipsis_range((i+Integer(1)),Ellipsis,len(chain)-Integer(1))):370pair = chain[j]371pair[Integer(0)] = s(pair[Integer(0)])372pair[Integer(1)] = s(pair[Integer(1)])373return (chain, s(endweight))374375def __hash__(self):376"""377Return hash value.378379EXAMPLES::380381sage: C = ClassicalCrystalOfAlcovePaths(['A',3],[0,1,0])382sage: C([0]).__hash__() == C([]).f(2).__hash__()383True384"""385return hash(tuple(self.value))386387def e(self, i, verbose=False):388r"""389Returns the action of `e_i` on self.390391EXAMPLES::392393sage: C = ClassicalCrystalOfAlcovePaths(['E',6],[1,0,0,0,0,0]) # long time (20s on sage.math, 2011)394sage: C.module_generators # long time395[[]]396sage: C([]).f(1) # long time397[0]398sage: C([]).f(1).e(1) # long time399[]400"""401assert i in self.index_set()402403# Construct the chain associated to the subset self.value404if self.chain is None:405if (str(self.value) in self.parent().chain_cache.keys()):406self.chain = self.parent().chain_cache[ str(self.value) ]407self.endweight = self.parent().endweight_cache[ str(self.value) ]408else:409(self.chain, self.endweight) = self.get_chain_from_subset()410self.parent().chain_cache[str(self.value)] = copy.deepcopy(self.chain)411self.parent().endweight_cache[str(self.value)] = copy.deepcopy(self.endweight)412413ai = self.parent().R.root_space().simple_root(i)414415if verbose == True:416print "( self.value, i = ", self.value, i, " ) "417print "( chain = ", self.chain, " ) "418IJp = filter( lambda j: self.chain[j][Integer(0)] == ai or self.chain[j][Integer(0)] == (-Integer(1))*ai, (ellipsis_range(Integer(0) ,Ellipsis, len(self.chain)-Integer(1))) )419if verbose == True:420print "( IJp = ", IJp, ") "421SJp = []422for j in IJp:423pair = self.chain[j]424if ( pair[Integer(0)].coefficients()[Integer(0)] < Integer(0) ):425SJp.append( -Integer(1) )426else:427SJp.append( Integer(1) )428if ( pair[Integer(1)].coefficients()[Integer(0)] < Integer(0) ):429SJp.append( -Integer(1) )430else:431SJp.append( Integer(1) )432433if (self.endweight.scalar( ai.associated_coroot() ) < Integer(0)):434SJp.append( -Integer(1) )435else:436SJp.append( Integer(1) )437438if verbose == True:439print "( SJp = ", SJp, ") "440441LJp = []442t = Integer(0)-(Integer(1)/Integer(2))443for j in (ellipsis_range(Integer(0),Ellipsis,len(SJp)-Integer(1))):444if SJp[j] == Integer(1):445t = t+(Integer(1)/Integer(2))446elif SJp[j] == -Integer(1):447t = t-(Integer(1)/Integer(2))448if ((j % Integer(2)) == Integer(0)):449LJp.append(t)450451if verbose == True:452print "( LJp = ", LJp, " ) "453454MJp = max(LJp)455if verbose == True:456print "( MJp = ", MJp, " ) "457458if (MJp <= LJp[ len(LJp)-1 ]):459return None460461rLJp = copy.deepcopy(LJp)462rLJp.reverse()463k = rLJp.index(MJp)464k = (len(LJp)-1) - k465m = k + 1466467rsubseq = []468rsubseq.extend(self.value)469rsubseq.remove(IJp[k])470if (m < len(IJp)):471rsubseq.append(IJp[m])472rsubseq.sort()473474return self.parent()(rsubseq)475476def f(self, i, verbose=False):477r"""478Returns the action of `f_i` on self.479480EXAMPLES::481482sage: C = ClassicalCrystalOfAlcovePaths(['E',6],[1,0,0,0,0,0]) # long time (21s on sage.math, 2011)483sage: C.module_generators # long time484[[]]485sage: C([]).f(1) # long time486[0]487sage: C([]).f(1).f(3) # long time488[0, 1]489sage: C([]).f(1).f(3).f(4) # long time490[0, 1, 2]491sage: C([]).f(1).f(3).f(4).f(5) # long time492[0, 1, 2, 4]493sage: C([]).f(1).f(3).f(4).f(2) # long time494[0, 1, 2, 3]495"""496assert i in self.index_set()497498# Construct the chain associated to the subset self.value499if self.chain is None:500if (str(self.value) in self.parent().chain_cache.keys()):501self.chain = self.parent().chain_cache[ str(self.value) ]502self.endweight = self.parent().endweight_cache[ str(self.value) ]503else:504(self.chain, self.endweight) = self.get_chain_from_subset()505self.parent().chain_cache[str(self.value)] = copy.deepcopy(self.chain)506self.parent().endweight_cache[str(self.value)] = copy.deepcopy(self.endweight)507508ai = self.parent().R.root_space().simple_root(i)509510if verbose == True:511print "( self.value, i = ", self.value, i, " ) "512print "( chain = ", self.chain, " ) "513IJp = filter( lambda j: self.chain[j][Integer(0)] == ai or self.chain[j][Integer(0)] == (-Integer(1))*ai, (ellipsis_range(Integer(0) ,Ellipsis, len(self.chain)-Integer(1))) )514if verbose == True:515print "( IJp = ", IJp, ") "516SJp = []517for j in IJp:518pair = self.chain[j]519if ( pair[Integer(0)].coefficients()[Integer(0)] < Integer(0) ):520SJp.append( -Integer(1) )521else:522SJp.append( Integer(1) )523if ( pair[Integer(1)].coefficients()[Integer(0)] < Integer(0) ):524SJp.append( -Integer(1) )525else:526SJp.append( Integer(1) )527528# Incidentally, the vector at infinity in LJp is <mu(J), a_p^check>.529# This gives an alternative way to calculate the last SJp/LJp entries.530if (self.endweight.scalar( ai.associated_coroot() ) < Integer(0)):531SJp.append( -Integer(1) )532else:533SJp.append( Integer(1) )534535if verbose == True:536print "( SJp = ", SJp, ") "537538LJp = []539t = Integer(0)-(Integer(1)/Integer(2))540for j in (ellipsis_range(Integer(0),Ellipsis,len(SJp)-Integer(1))):541if SJp[j] == Integer(1):542t = t+(Integer(1)/Integer(2))543elif SJp[j] == -Integer(1):544t = t-(Integer(1)/Integer(2))545if ((j % Integer(2)) == Integer(0)):546LJp.append(t)547548if verbose == True:549print "( LJp = ", LJp, " ) "550551MJp = max(LJp)552if verbose == True:553print "( MJp = ", MJp, " ) "554555if (MJp <= Integer(0)):556return None557558m = LJp.index(MJp)559k = m - Integer(1)560561rsubseq = []562rsubseq.extend(self.value)563if (m < len(IJp)):564rsubseq.remove(IJp[m])565rsubseq.append(IJp[k])566rsubseq.sort()567568return self.parent()(rsubseq)569570ClassicalCrystalOfAlcovePaths.Element = ClassicalCrystalOfAlcovePathsElement571572#####################################################################573# Code to test by comparing with existing crystal implementations.574#####################################################################575576def compare_graphs(g1, g2, node1, node2):577r"""578Returns two edge-labeled DiGraphs obtained from Crystal.digraph(), starting579from the root nodes of each graph.580581EXAMPLES:582sage: G1 = sage.combinat.crystals.all.CrystalOfTableaux(['A',3], shape = [1,1]).digraph()583sage: G2 = ClassicalCrystalOfAlcovePaths(['A',3],[0,1,0]).digraph()584sage: sage.combinat.crystals.alcove_path.compare_graphs(G1, G2, G1.vertices()[0], G2.vertices()[0])585True586"""587for out_edge in g1.outgoing_edges( node1 ):588matched = False589for o2 in g2.outgoing_edges( node2 ):590if o2[2] == out_edge[2]:591if matched == True:592print "ERROR: Two edges with the same label for ", out_edge, " exist."593return False594matched = True595result = compare_graphs(g1, g2, out_edge[1], o2[1])596if result == False:597return False598if matched == False:599print "ERROR: No matching edge for ", out_edge, "."600return False601return True602603def test_against_tableaux(R, N, k):604r"""605Tests our ClassicalCrystalOfAlcovePaths against all of the tableaux crystals606of type R in rank N with highest weight given by a partition of k.607608EXAMPLES::609610sage: sage.combinat.crystals.alcove_path.test_against_tableaux(['A',3], 3, 2)611** Shape [2]612T has 10 nodes.613C weight [2, 0, 0]614C has 10 nodes.615Compare graphs: True616** Shape [1, 1]617T has 6 nodes.618C weight [0, 1, 0]619C has 6 nodes.620Compare graphs: True621"""622shapes = Partitions(k).list()623for shape in shapes:624print "** Shape ", shape625T = CrystalOfTableaux(R, shape = shape)626ct = len(T.list())627print " T has ", ct, " nodes."628#T.digraph().show(edge_labels=True)629H = T.digraph()630weight = T.module_generators[0].weight()631w = [ weight.scalar(RootSystem(R).ambient_space().simple_coroot(i)) for i in range(1,N+1) ]632print " C weight ", w633634C = ClassicalCrystalOfAlcovePaths(R , w)635636cc = len(C.list())637#C.digraph().show(edge_labels=True)638G = C.digraph()639print " C has ", cc, " nodes."640if cc != ct:641print "FAIL: number of nodes differ.", cc, ct642return643print " Compare graphs: ", compare_graphs(G, H, G.vertices()[0], H.vertices()[0])644645646647def test_some_specific_examples():648r"""649Tests our ClassicalCrystalOfAlcovePaths against some specific examples.650651EXAMPLES::652653sage: sage.combinat.crystals.alcove_path.test_some_specific_examples() # long time (12s on sage.math, 2011)654G2 example passed.655C3 example passed.656B3 example 1 passed.657B3 example 2 passed.658True659"""660661# This appears in Lenart.662C = ClassicalCrystalOfAlcovePaths(['G',2],[0,1]);663G = C.digraph();664665GT = DiGraph({666() : {(0) : 2 },667(0) : {(0,8) : 1 },668(0,1) : {(0,1,7) : 2 },669(0,1,2) : {(0,1,2,9) : 1 },670(0,1,2,3) : {(0,1,2,3,4) : 2 },671(0,1,2,6) : {(0,1,2,3) : 1 },672(0,1,2,9) : {(0,1,2,6) : 1 },673(0,1,7) : {(0,1,2) : 2 },674(0,1,7,9) : {(0,1,2,9) : 2 },675(0,5) : {(0,1) : 1, (0,5,7) : 2 },676(0,5,7) : {(0,5,7,9) : 1 },677(0,5,7,9) : {(0,1,7,9) : 1 },678(0,8) : {(0,5) : 1 }679})680681682if (G.is_isomorphic(GT) != True):683return False;684else:685print "G2 example passed."686687# Some examples from Hong--Kang:688689# type C, ex. 8.3.5, pg. 189690C = ClassicalCrystalOfAlcovePaths(['C',3],[0,0,1]);691G = C.digraph();692GT = DiGraph({693():{ (0): 3},694(0):{ (0, 6): 2},695(0, 1):{ (0, 1, 3): 3, (0, 1, 7): 1},696(0, 1, 2):{ (0, 1, 2, 3): 3},697(0, 1, 2, 3):{ (0, 1, 2, 3, 8): 2},698(0, 1, 2, 3, 4):{ (0, 1, 2, 3, 4, 5): 3},699(0, 1, 2, 3, 8):{ (0, 1, 2, 3, 4): 2},700(0, 1, 3):{ (0, 1, 3, 7): 1},701(0, 1, 3, 7):{ (0, 1, 2, 3): 1, (0, 1, 3, 7, 8): 2},702(0, 1, 3, 7, 8):{ (0, 1, 2, 3, 8): 1},703(0, 1, 7):{ (0, 1, 2): 1, (0, 1, 3, 7): 3},704(0, 6):{ (0, 1): 2, (0, 6, 7): 1},705(0, 6, 7):{ (0, 1, 7): 2}706})707708if (G.is_isomorphic(GT) != True):709return False;710else:711print "C3 example passed."712713# type B, fig. 8.1 pg. 172714C = ClassicalCrystalOfAlcovePaths(['B',3],[2,0,0]);715G = C.digraph();716717GT = DiGraph({718():{ (6): 1},719(0):{ (0, 7): 2},720(0, 1):{ (0, 1, 11): 3},721(0, 1, 2):{ (0, 1, 2, 9): 2},722(0, 1, 2, 3):{ (0, 1, 2, 3, 10): 1},723(0, 1, 2, 3, 10):{ (0, 1, 2, 3, 4): 1},724(0, 1, 2, 9):{ (0, 1, 2, 3): 2, (0, 1, 2, 9, 10): 1},725(0, 1, 2, 9, 10):{ (0, 1, 2, 3, 10): 2},726(0, 1, 5):{ (0, 1, 2): 3, (0, 1, 5, 9): 2},727(0, 1, 5, 9):{ (0, 1, 2, 9): 3, (0, 1, 5, 9, 10): 1},728(0, 1, 5, 9, 10):{ (0, 1, 2, 9, 10): 3},729(0, 1, 8):{ (0, 1, 5): 3},730(0, 1, 8, 9):{ (0, 1, 5, 9): 3, (0, 1, 8, 9, 10): 1},731(0, 1, 8, 9, 10):{ (0, 1, 5, 9, 10): 3},732(0, 1, 11):{ (0, 1, 8): 3},733(0, 7):{ (0, 1): 2, (0, 7, 11): 3},734(0, 7, 8):{ (0, 7, 8, 9): 2},735(0, 7, 8, 9):{ (0, 1, 8, 9): 2},736(0, 7, 8, 9, 10):{ (0, 1, 8, 9, 10): 2},737(0, 7, 11):{ (0, 1, 11): 2, (0, 7, 8): 3},738(6):{ (0): 1, (6, 7): 2},739(6, 7):{ (0, 7): 1, (6, 7, 11): 3},740(6, 7, 8):{ (0, 7, 8): 1, (6, 7, 8, 9): 2},741(6, 7, 8, 9):{ (6, 7, 8, 9, 10): 1},742(6, 7, 8, 9, 10):{ (0, 7, 8, 9, 10): 1},743(6, 7, 11):{ (0, 7, 11): 1, (6, 7, 8): 3}744})745746if (G.is_isomorphic(GT) != True):747return False;748else:749print "B3 example 1 passed."750751C = ClassicalCrystalOfAlcovePaths(['B',3],[0,1,0]);752G = C.digraph();753754GT = DiGraph({755():{ (0): 2},756(0):{ (0, 1): 1, (0, 7): 3},757(0, 1):{ (0, 1, 7): 3},758(0, 1, 2):{ (0, 1, 2, 8): 2},759(0, 1, 2, 3):{ (0, 1, 2, 3, 5): 1, (0, 1, 2, 3, 9): 3},760(0, 1, 2, 3, 4):{ (0, 1, 2, 3, 4, 5): 1},761(0, 1, 2, 3, 4, 5):{ (0, 1, 2, 3, 4, 5, 6): 2},762(0, 1, 2, 3, 5):{ (0, 1, 2, 3, 5, 9): 3},763(0, 1, 2, 3, 5, 9):{ (0, 1, 2, 3, 4, 5): 3},764(0, 1, 2, 3, 9):{ (0, 1, 2, 3, 4): 3, (0, 1, 2, 3, 5, 9): 1},765(0, 1, 2, 5):{ (0, 1, 2, 3, 5): 2},766(0, 1, 2, 8):{ (0, 1, 2, 3): 2},767(0, 1, 2, 8, 9):{ (0, 1, 2, 3, 9): 2},768(0, 1, 7):{ (0, 1, 2): 3, (0, 1, 7, 8): 2},769(0, 1, 7, 8):{ (0, 1, 7, 8, 9): 3},770(0, 1, 7, 8, 9):{ (0, 1, 2, 8, 9): 3},771(0, 2):{ (0, 1, 2): 1, (0, 2, 5): 2},772(0, 2, 5):{ (0, 2, 5, 8): 1},773(0, 2, 5, 8):{ (0, 1, 2, 5): 1},774(0, 7):{ (0, 1, 7): 1, (0, 2): 3}775})776777if (G.is_isomorphic(GT) != True):778return False;779else:780print "B3 example 2 passed."781782# type B, fig. 8.3 pg. 174783784return True;785786787788