Ticket #14141: trac_14141-review-fs.patch

File trac_14141-review-fs.patch, 59.4 KB (added by saliola, 8 years ago)
  • sage/combinat/all.py

    # HG changeset patch
    # User Franco Saliola <saliola@gmail.com>
    # Date 1368495762 14400
    # Node ID 16c3277ad4c1699b97852c96c0bc4dfc50eae2ae
    # Parent  7ef5b208a82072db11f3cdd5a13d6d4ba90a198f
    imported patch trac_14141-review-fs.patch
    
    diff --git a/sage/combinat/all.py b/sage/combinat/all.py
    a b from cyclic_sieving_phenomenon import Cy 
    134134from sidon_sets import sidon_sets
    135135
    136136# Puzzles
    137 from knutson_tao_puzzles import PuzzlePiece, PuzzlePieces, PuzzleSolver
     137from knutson_tao_puzzles import KnutsonTaoPuzzleSolver
    138138
    139139# Gelfand-Tsetlin patterns
    140140from gelfand_tsetlin_patterns import GelfandTsetlinPattern, GelfandTsetlinPatterns
  • sage/combinat/knutson_tao_puzzles.py

    diff --git a/sage/combinat/knutson_tao_puzzles.py b/sage/combinat/knutson_tao_puzzles.py
    a b  
    11r"""
    22Knutson-Tao Puzzles
    33
    4 
    5 OVERVIEW OF CURRENT USAGE
    6 =========================
    7 
    8 Here are some examples on how to use the puzzle code.
    9 
    10 Puzzle Solvers
    11 --------------
    12 
    13 Solving and plotting puzzles::
    14 
    15     sage: from sage.combinat.knutson_tao_puzzles import H_grassmannian_pieces
    16     sage: ps = PuzzleSolver(H_grassmannian_pieces())
    17     sage: solns = ps('0101', '0101')
    18     sage: sorted(solns, key=str)
    19     [{(1, 2): 1/\0  0\/1, (1, 3): 0/\0  0\/0, (3, 3): 1/1\1, (4, 4): 10/0\1, (1, 4): 1/\0  0\/1,
    20     (1, 1): 0/0\0, (2, 3): 0/\10  1\/1, (2, 2): 1/1\1, (3, 4): 0/\0  1\/10, (2, 4): 1/\1  10\/0},
    21     {(1, 2): 1/\1  10\/0, (1, 3): 0/\0  1\/10, (3, 3): 0/0\0, (4, 4): 1/1\1, (1, 4): 1/\0  0\/1,
    22     (1, 1): 0/1\10, (2, 3): 10/\1  0\/0, (2, 2): 0/0\0, (3, 4): 1/\0  0\/1, (2, 4): 1/\1  1\/1}]
    23     sage: ps.plot(solns)         # not tested
    24 
    25 Equivariant puzzles::
    26 
    27     sage: from sage.combinat.knutson_tao_puzzles import HT_grassmannian_pieces
    28     sage: ps = PuzzleSolver(HT_grassmannian_pieces())
    29     sage: solns = ps('0101', '0101')
    30     sage: sorted(solns, key=str)
    31     [{(1, 2): 1/\0  0\/1, (1, 3): 0/\0  0\/0, (3, 3): 0/0\0, (4, 4): 1/1\1, (1, 4): 1/\0  0\/1,
    32     (1, 1): 0/0\0, (2, 3): 0/\1  1\/0, (2, 2): 1/1\1, (3, 4): 1/\0  0\/1, (2, 4): 1/\1  1\/1},
    33     {(1, 2): 1/\0  0\/1, (1, 3): 0/\0  0\/0, (3, 3): 1/1\1, (4, 4): 10/0\1, (1, 4): 1/\0  0\/1,
    34     (1, 1): 0/0\0, (2, 3): 0/\10  1\/1, (2, 2): 1/1\1, (3, 4): 0/\0  1\/10, (2, 4): 1/\1  10\/0},
    35     {(1, 2): 1/\1  10\/0, (1, 3): 0/\0  1\/10, (3, 3): 0/0\0, (4, 4): 1/1\1, (1, 4): 1/\0  0\/1,
    36     (1, 1): 0/1\10, (2, 3): 10/\1  0\/0, (2, 2): 0/0\0, (3, 4): 1/\0  0\/1, (2, 4): 1/\1  1\/1}]
    37     sage: ps.plot(solns)         # not tested
    38 
    39 K-Theory puzzles::
    40 
    41     sage: from sage.combinat.knutson_tao_puzzles import K_grassmannian_pieces
    42     sage: ps = PuzzleSolver(K_grassmannian_pieces())
    43     sage: solns = ps('0101', '0101')
    44     sage: sorted(solns, key=str)
    45     [{(1, 2): 1/\0  0\/1, (1, 3): 0/\0  0\/0, (3, 3): 1/1\1, (4, 4): 10/0\1, (1, 4): 1/\0  0\/1,
    46     (1, 1): 0/0\0, (2, 3): 0/\10  1\/1, (2, 2): 1/1\1, (3, 4): 0/\0  1\/10, (2, 4): 1/\1  10\/0},
    47     {(1, 2): 1/\1  10\/0, (1, 3): 0/\0  1\/10, (3, 3): 0/0\0, (4, 4): 1/1\1, (1, 4): 1/\0  0\/1,
    48     (1, 1): 0/1\10, (2, 3): 10/\1  0\/0, (2, 2): 0/0\0, (3, 4): 1/\0  0\/1, (2, 4): 1/\1  1\/1},
    49     {(1, 2): 1/\1  10\/0, (1, 3): 0/\0  1\/K, (3, 3): 1/1\1, (4, 4): 10/0\1, (1, 4): 1/\0  0\/1,
    50     (1, 1): 0/1\10, (2, 3): K/\K  0\/1, (2, 2): 0/0\0, (3, 4): 0/\0  1\/10, (2, 4): 1/\1  K\/0}]
    51     sage: ps.plot(solns)        # not tested
    52 
    53 Two-step puzzles::
    54 
    55     sage: from sage.combinat.knutson_tao_puzzles import H_two_step_pieces
    56     sage: ps = PuzzleSolver(H_two_step_pieces())
    57     sage: solns = ps('01201', '01021')
    58     sage: sorted(solns, key=str)
    59     [{(1, 2): 1/\0  0\/1, (1, 3): 2/\0  0\/2, (3, 3): 1/1\1, (4, 5): 20/\2  1\/10,
    60     (4, 4): 1/1\1, (5, 5): 10/0\1, (1, 4): 0/\0  0\/0, (1, 1): 0/0\0, (1, 5): 1/\0  0\/1,
    61     (2, 3): 2/\2  21\/1, (2, 2): 1/2\21, (2, 5): 1/\1  10\/0, (3, 4): 21/\2  1\/1,
    62     (2, 4): 0/\10  2\/21, (3, 5): 0/\0  2\/20},
    63     {(1, 2): 1/\1  10\/0, (1, 3): 2/\1  1\/2, (3, 3): 0/0\0, (4, 5): 2(10)/\2  0\/1,
    64     (4, 4): 0/0\0, (5, 5): 1/1\1, (1, 4): 0/\0  1\/10, (1, 1): 0/1\10, (1, 5): 1/\0  0\/1,
    65     (2, 3): 2/\2  20\/0, (2, 2): 0/2\20, (2, 5): 1/\1  1\/1, (3, 4): 20/\2  0\/0,
    66     (2, 4): 10/\1  2\/20, (3, 5): 1/\0  2\/2(10)},
    67     {(1, 2): 1/\21  20\/0, (1, 3): 2/\2  21\/1, (3, 3): 1/1\1, (4, 5): 21/\2  1\/1,
    68     (4, 4): 10/0\1, (5, 5): 1/1\1, (1, 4): 0/\0  2\/20, (1, 1): 0/2\20, (1, 5): 1/\0  0\/1,
    69     (2, 3): 1/\0  0\/1, (2, 2): 0/0\0, (2, 5): 1/\1  2\/21, (3, 4): 0/\0  1\/10, (2, 4): 20/\2  0\/0,
    70     (3, 5): 21/\0  0\/21}]
    71     sage: ps.plot(solns)        # not tested
    72 
    73 Two-step equivariant puzzles::
    74 
    75     sage: from sage.combinat.knutson_tao_puzzles import HT_two_step_pieces
    76     sage: ps = PuzzleSolver(HT_two_step_pieces())
    77     sage: solns = ps('10212', '12012')
    78     sage: sorted(solns, key=str)
    79     [{(1, 2): 0/\(21)0  1\/2, (1, 3): 2/\1  (21)0\/0, (3, 3): 0/0\0, (4, 5): 1/\1  2\/21, (4, 4): 2/2\2,
    80     (5, 5): 21/1\2, (1, 4): 1/\1  1\/1, (1, 1): 1/1\1, (1, 5): 2/\1  1\/2, (2, 3): 0/\2  2\/0, (2, 2): 2/2\2,
    81     (2, 5): 2/\2  21\/1, (3, 4): 2/\0  0\/2, (2, 4): 1/\21  2\/2, (3, 5): 1/\0  0\/1},
    82     {(1, 2): 0/\(21)0  1\/2, (1, 3): 2/\1  (21)0\/0, (3, 3): 0/0\0, (4, 5): 2/\1  1\/2, (4, 4): 1/1\1,
    83     (5, 5): 2/2\2, (1, 4): 1/\1  1\/1, (1, 1): 1/1\1, (1, 5): 2/\1  1\/2, (2, 3): 0/\2  2\/0, (2, 2): 2/2\2,
    84     (2, 5): 2/\2  2\/2, (3, 4): 1/\0  0\/1, (2, 4): 1/\2  2\/1, (3, 5): 2/\0  0\/2},
    85     {(1, 2): 0/\(21)0  1\/2, (1, 3): 2/\1  (21)0\/0, (3, 3): 2/2\2, (4, 5): 1/\1  2\/21, (4, 4): 20/0\2,
    86     (5, 5): 21/1\2, (1, 4): 1/\1  1\/1, (1, 1): 1/1\1, (1, 5): 2/\1  1\/2, (2, 3): 0/\20  2\/2, (2, 2): 2/2\2,
    87     (2, 5): 2/\2  21\/1, (3, 4): 0/\0  2\/20, (2, 4): 1/\21  20\/0, (3, 5): 1/\0  0\/1},
    88     {(1, 2): 0/\1  1\/0, (1, 3): 2/\1  1\/2, (3, 3): 0/0\0, (4, 5): 1/\1  2\/21, (4, 4): 2/2\2, (5, 5): 21/1\2,
    89     (1, 4): 1/\1  1\/1, (1, 1): 1/1\1, (1, 5): 2/\1  1\/2, (2, 3): 2/\2  20\/0, (2, 2): 0/2\20,
    90     (2, 5): 2/\2  21\/1, (3, 4): 2/\0  0\/2, (2, 4): 1/\21  2\/2, (3, 5): 1/\0  0\/1},
    91     {(1, 2): 0/\1  1\/0, (1, 3): 2/\1  1\/2, (3, 3): 0/0\0, (4, 5): 2/\1  1\/2, (4, 4): 1/1\1,
    92     (5, 5): 2/2\2, (1, 4): 1/\1  1\/1, (1, 1): 1/1\1, (1, 5): 2/\1  1\/2, (2, 3): 2/\2  20\/0,
    93     (2, 2): 0/2\20, (2, 5): 2/\2  2\/2, (3, 4): 1/\0  0\/1, (2, 4): 1/\2  2\/1, (3, 5): 2/\0  0\/2},
    94     {(1, 2): 0/\10  1\/1, (1, 3): 2/\10  10\/2, (3, 3): 1/1\1, (4, 5): 10/\1  2\/20, (4, 4): 2/2\2,
    95     (5, 5): 20/0\2, (1, 4): 1/\1  10\/0, (1, 1): 1/1\1, (1, 5): 2/\1  1\/2, (2, 3): 2/\2  21\/1,
    96     (2, 2): 1/2\21, (2, 5): 2/\2  20\/0, (3, 4): 2/\1  1\/2, (2, 4): 0/\20  2\/2, (3, 5): 0/\0  1\/10},
    97     {(1, 2): 0/\10  1\/1, (1, 3): 2/\10  10\/2, (3, 3): 1/1\1, (4, 5): 2/\1  1\/2, (4, 4): 10/0\1,
    98     (5, 5): 2/2\2, (1, 4): 1/\1  10\/0, (1, 1): 1/1\1, (1, 5): 2/\1  1\/2, (2, 3): 2/\2  21\/1,
    99     (2, 2): 1/2\21, (2, 5): 2/\2  2\/2, (3, 4): 0/\0  1\/10, (2, 4): 0/\2  2\/0, (3, 5): 2/\0  0\/2},
    100     {(1, 2): 0/\20  21\/1, (1, 3): 2/\2  20\/0, (3, 3): 0/0\0, (4, 5): 2/\1  1\/2, (4, 4): 1/1\1,
    101     (5, 5): 2/2\2, (1, 4): 1/\1  2\/21, (1, 1): 1/2\21, (1, 5): 2/\1  1\/2, (2, 3): 0/\1  1\/0,
    102     (2, 2): 1/1\1, (2, 5): 2/\2  2\/2, (3, 4): 1/\0  0\/1, (2, 4): 21/\2  1\/1, (3, 5): 2/\0  0\/2},
    103     {(1, 2): 0/\20  21\/1, (1, 3): 2/\2  20\/0, (3, 3): 1/1\1, (4, 5): 2/\1  1\/2, (4, 4): 10/0\1,
    104     (5, 5): 2/2\2, (1, 4): 1/\1  2\/21, (1, 1): 1/2\21, (1, 5): 2/\1  1\/2, (2, 3): 0/\10  1\/1,
    105     (2, 2): 1/1\1, (2, 5): 2/\2  2\/2, (3, 4): 0/\0  1\/10, (2, 4): 21/\2  10\/0, (3, 5): 2/\0  0\/2},
    106     {(1, 2): 0/\21  21\/0, (1, 3): 2/\2  21\/1, (3, 3): 0/0\0, (4, 5): 2/\1  1\/2, (4, 4): 1/1\1,
    107     (5, 5): 2/2\2, (1, 4): 1/\1  2\/21, (1, 1): 1/2\21, (1, 5): 2/\1  1\/2, (2, 3): 1/\1  10\/0,
    108     (2, 2): 0/1\10, (2, 5): 2/\2  2\/2, (3, 4): 1/\0  0\/1, (2, 4): 21/\2  1\/1, (3, 5): 2/\0  0\/2}]
    109     sage: ps.plot(solns)        # not tested
    110 
    111 Structure Constants for Products
    112 --------------------------------
    113 
    114 From the puzzles we can compute the structure coefficients in the various settings.
    115 
    116 Grassmannian cohomology::
    117 
    118     sage: from sage.combinat.knutson_tao_puzzles import cohomology_product, H_grassmannian_pieces
    119     sage: cohomology_product(H_grassmannian_pieces(), '0101', '0101')
    120     {('1', '0', '0', '1'): 1, ('0', '1', '1', '0'): 1}
    121 
    122 Equivariant cohomology::
    123 
    124     sage: from sage.combinat.knutson_tao_puzzles import cohomology_product, HT_grassmannian_pieces
    125     sage: cohomology_product( HT_grassmannian_pieces(), '0101', '0101')
    126     {('0', '1', '0', '1'): y2 - y3, ('1', '0', '0', '1'): 1, ('0', '1', '1', '0'): 1}
    127 
    128 K-theory::
    129 
    130     sage: from sage.combinat.knutson_tao_puzzles import cohomology_product, K_grassmannian_pieces
    131     sage: cohomology_product(K_grassmannian_pieces(), '0101', '0101')
    132     {('1', '0', '0', '1'): 1, ('0', '1', '1', '0'): 1, ('1', '0', '1', '0'): -1}
    133 
    134 Two-step::
    135 
    136     sage: from sage.combinat.knutson_tao_puzzles import cohomology_product, H_two_step_pieces
    137     sage: cohomology_product(H_two_step_pieces(), '01122', '01122')
    138     {('0', '1', '1', '2', '2'): 1}
    139     sage: sorted(cohomology_product(H_two_step_pieces(), '01201', '01021'), key = str)
    140     [('0', '2', '1', '1', '0'),
    141     ('1', '2', '0', '0', '1'),
    142     ('2', '0', '1', '0', '1')]
    143 
    144 Two-step equivariant::
    145 
    146     sage: from sage.combinat.knutson_tao_puzzles import cohomology_product, HT_two_step_pieces
    147     sage: D = cohomology_product(HT_two_step_pieces(), list('10212'), list('12012'))
    148     sage: ds = sorted(D.keys(), key=str)
    149     sage: dict([(p,D[p]) for p in ds])
    150     {('1', '2', '1', '0', '2'): y2 - y4, ('1', '2', '0', '2', '1'): y1 - y3,
    151     ('1', '2', '0', '1', '2'): y1*y2 - y2*y3 - y1*y4 + y3*y4, ('1', '2', '1', '2', '0'): 1,
    152     ('2', '1', '0', '1', '2'): y1 - y3, ('1', '2', '2', '0', '1'): 1, ('2', '1', '1', '0', '2'): 1}
    153 
    154 Algebra
    155 -------
    156 
    157 Create the algebra and compute products::
    158 
    159     sage: from sage.combinat.knutson_tao_puzzles import SchubertCalculusAlgebra
    160     sage: WordOptions(identifier='')
    161     sage: Sc = SchubertCalculusAlgebra(QQ, (3,3))
    162     sage: x = Sc.an_element()
    163     sage: x
    164     2*Sc[000111] + 2*Sc[001011] + 3*Sc[001101]
    165     sage: x*x
    166     4*Sc[000111] + 8*Sc[001011] + 16*Sc[001101] + 12*Sc[001110] + 4*Sc[010011] + 12*Sc[010101] + 9*Sc[010110] + 9*Sc[011001]
    167 
    168 K-Theory::
    169 
    170     sage: from sage.combinat.knutson_tao_puzzles import SchubertCalculusAlgebra
    171     sage: Sc = SchubertCalculusAlgebra(QQ, (3,3), K=True)
    172     sage: x = Sc.an_element()
    173     sage: x * x
    174     4*Sc[000111] + 8*Sc[001011] + 16*Sc[001101] + 12*Sc[001110] + 4*Sc[010011] + 8*Sc[010101] + (-3)*Sc[010110] + 9*Sc[011001] + (-9)*Sc[011010]
     4This module implements a generic algorithm to solve Knutson-Tao puzzles. An
     5instance of this class will be callable: the arguments are the labels of
     6north-east and north-west sides of the puzzle boundary; the output is the list
     7of the fillings of the puzzle with the specified pieces.
    1758
    1769Acknowledgements
    17710----------------
    The code was tested afterwards by Liz Be 
    18518
    18619    - plotter will not plot edge labels higher than 2; e.g. in BK puzzles, the labels are
    18720      1,..., n and so in 3-step examples, none of the edge labels with 3 appear
     21
    18822    - we should also have a 3-step puzzle pieces constructor, taken from p22 of
    18923      {{{:arxiv:`0610538`}}}
    19024
    191     Speed ups (possible):
    192 
    193     - write a method that computes the the fillings of a 1 x k strip given the
    194       k NW labels and the single NE label; cache the results
    195     - if the method hasn't yet computed the filling, use a recursive call to
    196       fill the right-hand 1 x (k-1) strip, and for each of those look at all
    197       ways to put on one more rhombus
    198 
    19925"""
    20026#*****************************************************************************
    20127#       Copyright (C) 2013 Franco Saliola <saliola@gmail.com>,
    class PuzzlePieces(object): 
    692518    """
    693519    Construct a valid set of puzzle pieces.
    694520
    695     This class constructs the set of valid puzzle pieces. It can take
    696     a list of forbidden border labels as input. The user can add
    697     valid nabla or delta pieces and specify which rotations of these
    698     pieces are legal. For example, ``rotations=0`` does not add any
    699     additional pieces (only the piece itself), ``rotations=60`` adds
    700     six pieces (the pieces and its rotations by 60, 120, 180, 240, 300), etc..
     521    This class constructs the set of valid puzzle pieces. It can take a list of
     522    forbidden border labels as input. These labels are forbidden from appearing
     523    on the south edge of a puzzle filling. The user can add valid nabla or
     524    delta pieces and specify which rotations of these pieces are legal. For
     525    example, ``rotations=0`` does not add any additional pieces (only the piece
     526    itself), ``rotations=60`` adds six pieces (the pieces and its rotations by
     527    60, 120, 180, 240, 300), etc..
    701528
    702529    EXAMPLES::
    703530
    704         sage: from sage.combinat.knutson_tao_puzzles import NablaPiece
     531        sage: from sage.combinat.knutson_tao_puzzles import PuzzlePieces, NablaPiece
    705532        sage: forbidden_border_labels = ['10']
    706533        sage: pieces = PuzzlePieces(forbidden_border_labels)
    707534        sage: pieces.add_piece(NablaPiece('0','0','0'), rotations=60)
    class PuzzlePieces(object): 
    717544        [0/\0  0\/0, 0/\0  1\/10, 0/\10  10\/0, 0/\10  1\/1, 1/\0  0\/1,
    718545        1/\1  10\/0, 1/\1  1\/1, 10/\1  0\/0, 10/\1  1\/10]
    719546    """
    720 
    721547    def __init__(self, forbidden_border_labels=None):
    722548        """
    723549        INPUT:
    class PuzzlePieces(object): 
    726552
    727553        TESTS::
    728554
    729            sage: forbidden_border_labels = ['10']
    730            sage: pieces = PuzzlePieces(forbidden_border_labels)
    731            sage: pieces
    732            Nablas : []
    733            Deltas : []
     555            sage: from sage.combinat.knutson_tao_puzzles import PuzzlePieces
     556            sage: forbidden_border_labels = ['10']
     557            sage: pieces = PuzzlePieces(forbidden_border_labels)
     558            sage: pieces
     559            Nablas : []
     560            Deltas : []
    734561
    735            sage: PuzzlePieces('10')
    736            Traceback (most recent call last):
    737            ...
    738            TypeError: Input must be a list
     562            sage: PuzzlePieces('10')
     563            Traceback (most recent call last):
     564            ...
     565            TypeError: Input must be a list
    739566        """
    740567        self._nabla_pieces = set([])
    741568        self._delta_pieces = set([])
    class PuzzlePieces(object): 
    790617
    791618        EXAMPLES::
    792619
    793             sage: from sage.combinat.knutson_tao_puzzles import DeltaPiece
     620            sage: from sage.combinat.knutson_tao_puzzles import PuzzlePieces, DeltaPiece
    794621            sage: delta = DeltaPiece('a','b','c')
    795622            sage: pieces = PuzzlePieces()
    796623            sage: pieces
    class PuzzlePieces(object): 
    837664
    838665        EXAMPLES::
    839666
     667            sage: from sage.combinat.knutson_tao_puzzles import PuzzlePieces
    840668            sage: pieces = PuzzlePieces()
    841669            sage: pieces.add_forbidden_label('1')
    842670            sage: pieces._forbidden_border_labels
    class PuzzlePieces(object): 
    857685
    858686        EXAMPLES::
    859687
     688            sage: from sage.combinat.knutson_tao_puzzles import PuzzlePieces
    860689            sage: pieces = PuzzlePieces()
    861690            sage: pieces.add_T_piece('1','3')
    862691            sage: pieces
    class PuzzlePieces(object): 
    872701        """
    873702        TESTS::
    874703
    875             sage: from sage.combinat.knutson_tao_puzzles import DeltaPiece
     704            sage: from sage.combinat.knutson_tao_puzzles import PuzzlePieces, DeltaPiece
    876705            sage: pieces = PuzzlePieces()
    877706            sage: delta = DeltaPiece('a','b','c')
    878707            sage: pieces.add_piece(delta,rotations=60)
    class PuzzlePieces(object): 
    890719
    891720        EXAMPLES::
    892721
    893             sage: from sage.combinat.knutson_tao_puzzles import DeltaPiece
     722            sage: from sage.combinat.knutson_tao_puzzles import PuzzlePieces, DeltaPiece
    894723            sage: pieces = PuzzlePieces()
    895724            sage: delta = DeltaPiece('a','b','c')
    896725            sage: pieces.add_piece(delta,rotations=60)
    class PuzzlePieces(object): 
    905734
    906735        EXAMPLES::
    907736
    908             sage: from sage.combinat.knutson_tao_puzzles import DeltaPiece
     737            sage: from sage.combinat.knutson_tao_puzzles import PuzzlePieces, DeltaPiece
    909738            sage: pieces = PuzzlePieces()
    910739            sage: delta = DeltaPiece('a','b','c')
    911740            sage: pieces.add_piece(delta,rotations=60)
    class PuzzlePieces(object): 
    923752
    924753        EXAMPLES::
    925754
    926             sage: from sage.combinat.knutson_tao_puzzles import DeltaPiece
     755            sage: from sage.combinat.knutson_tao_puzzles import PuzzlePieces, DeltaPiece
    927756            sage: pieces = PuzzlePieces()
    928757            sage: delta = DeltaPiece('a','b','c')
    929758            sage: pieces.add_piece(delta,rotations=60)
    class PuzzlePieces(object): 
    943772
    944773        EXAMPLES::
    945774
    946             sage: from sage.combinat.knutson_tao_puzzles import DeltaPiece
     775            sage: from sage.combinat.knutson_tao_puzzles import PuzzlePieces, DeltaPiece
    947776            sage: pieces = PuzzlePieces(['a'])
    948777            sage: delta = DeltaPiece('a','b','c')
    949778            sage: pieces.add_piece(delta,rotations=60)
    def HT_two_step_pieces(): 
    1075904    return pieces
    1076905
    1077906
    1078 def BK_pieces(maxLetter):
     907def BK_pieces(max_letter):
    1079908    """
    1080909    Defines the puzzle pieces used in computing the Belkale-Kumar coefficients for any partial flag variety in type `A`.
    1081910
    1082911    INPUT:
    1083912
    1084     - ``maxLetter`` -- positive integer specifying the number of steps in the partial flag variety
     913    - ``max_letter`` -- positive integer specifying the number of steps in the partial flag variety
    1085914
    1086915    REFERENCES:
    1087916
    def BK_pieces(maxLetter): 
    1095924        Nablas : [0\0/0, 1\1/1, 2\2/2, 3\3/3]
    1096925        Deltas : [0/0\0, 1/1\1, 2/2\2, 3/3\3]
    1097926    """
    1098     maxLetter += 1
    1099     forbidden_border_labels = ['%s%s' % (i,j) for j in range(maxLetter-1) for i in range(j+1,maxLetter)]
     927    max_letter += 1
     928    forbidden_border_labels = ['%s%s' % (i,j) for j in range(max_letter-1) for i in range(j+1,max_letter)]
    1100929    pieces = PuzzlePieces(forbidden_border_labels)
    1101     for j in range(0,maxLetter):
     930    for j in range(0, max_letter):
    1102931        jstr = '%s'%j
    1103932        pieces.add_piece(DeltaPiece(jstr,jstr,jstr), rotations = 60)
    1104933
    1105     for i in range(j+1,maxLetter):
     934    for i in range(j+1, max_letter):
    1106935        istr = '%s'%i
    1107936        pieces.add_piece(DeltaPiece(istr+jstr, istr, jstr), rotations = 60)
    1108937
    1109938    return pieces
    1110939
    1111 
    1112 def cohomology_product(pieces, lamda, mu, nu=None):
    1113     r"""
    1114     Compute cohomology structure coefficients from puzzles.
    1115 
    1116     INPUT:
    1117 
    1118     - ``pieces`` -- puzzle pieces to be used
    1119     - ``lambda``, ``mu`` -- edge labels of puzzle for northwest and north east side
    1120     - ``nu`` -- (default: ``None``) If ``nu`` is not specified a dictionary is returned with
    1121       the structure coefficients corresponding to all south labels; if ``nu`` is given, only
    1122       the coefficients with the specified label is returned.
    1123 
    1124     EXAMPLES::
    1125 
    1126         sage: from sage.combinat.knutson_tao_puzzles import cohomology_product, H_grassmannian_pieces, HT_grassmannian_pieces
    1127         sage: sorted(cohomology_product(H_grassmannian_pieces(), '0101', '0101').items(), key = str)
    1128         [(('0', '1', '1', '0'), 1), (('1', '0', '0', '1'), 1)]
    1129         sage: sorted(cohomology_product(HT_grassmannian_pieces(), '0101', '0101').items(), key = str)
    1130         [(('0', '1', '0', '1'), y2 - y3),
    1131         (('0', '1', '1', '0'), 1),
    1132         (('1', '0', '0', '1'), 1)]
    1133 
    1134         sage: cohomology_product(H_grassmannian_pieces(), '001001', '001010', '010100')
    1135         1
    1136     """
    1137     ps = PuzzleSolver(pieces)
    1138     from collections import defaultdict
    1139     R = PolynomialRing(Integers(), 'y', len(lamda)+1)
    1140     z = defaultdict(R.zero)
    1141     for p in ps(list(lamda), list(mu)):
    1142         z[p.south_labels()] += p.contribution()
    1143     if nu is None:
    1144         return dict(z)
    1145     else:
    1146         return z[tuple(nu)]
    1147 
    1148 
    1149 class PartialPuzzle(object):
     940class PuzzleFilling(object):
    1150941    r"""
    1151942    Create partial puzzles and provides methods to build puzzles from them.
    1152943    """
    class PartialPuzzle(object): 
    1154945        """
    1155946        TESTS::
    1156947
    1157             sage: from sage.combinat.knutson_tao_puzzles import PartialPuzzle
    1158             sage: P = PartialPuzzle('0101','0101')
     948            sage: from sage.combinat.knutson_tao_puzzles import PuzzleFilling
     949            sage: P = PuzzleFilling('0101','0101')
    1159950            sage: P
    1160951            {}
    1161952        """
    class PartialPuzzle(object): 
    1169960        """
    1170961        TESTS::
    1171962
    1172             sage: ps = PuzzleSolver("H")
     963            sage: from sage.combinat.knutson_tao_puzzles import KnutsonTaoPuzzleSolver
     964            sage: ps = KnutsonTaoPuzzleSolver("H")
    1173965            sage: puzzle = ps('0101','1001')[0]
    1174966            sage: puzzle
    1175967            {(1, 2): 1/\1  10\/0, (1, 3): 0/\10  1\/1, (3, 3): 1/1\1, (4, 4): 10/0\1,
    class PartialPuzzle(object): 
    1189981
    1190982        EXAMPLES::
    1191983
    1192             sage: from sage.combinat.knutson_tao_puzzles import PartialPuzzle
    1193             sage: P = PartialPuzzle('0101','0101')
     984            sage: from sage.combinat.knutson_tao_puzzles import PuzzleFilling
     985            sage: P = PuzzleFilling('0101','0101')
    1194986            sage: P
    1195987            {}
    1196988            sage: P.kink_coordinates()
    class PartialPuzzle(object): 
    1204996
    1205997        EXAMPLES::
    1206998
    1207             sage: from sage.combinat.knutson_tao_puzzles import PartialPuzzle
    1208             sage: P = PartialPuzzle('0101','0101')
     999            sage: from sage.combinat.knutson_tao_puzzles import PuzzleFilling
     1000            sage: P = PuzzleFilling('0101','0101')
    12091001            sage: P.is_in_south_edge()
    12101002            False
    12111003        """
    class PartialPuzzle(object): 
    12181010
    12191011        EXAMPLES::
    12201012
    1221             sage: from sage.combinat.knutson_tao_puzzles import PartialPuzzle
    1222             sage: P = PartialPuzzle('0101','0101')
     1013            sage: from sage.combinat.knutson_tao_puzzles import PuzzleFilling
     1014            sage: P = PuzzleFilling('0101','0101')
    12231015            sage: P.north_west_label_of_kink()
    12241016            '1'
    12251017        """
    class PartialPuzzle(object): 
    12351027
    12361028        EXAMPLES::
    12371029
    1238             sage: from sage.combinat.knutson_tao_puzzles import PartialPuzzle
    1239             sage: P = PartialPuzzle('0101','0101')
     1030            sage: from sage.combinat.knutson_tao_puzzles import PuzzleFilling
     1031            sage: P = PuzzleFilling('0101','0101')
    12401032            sage: P.north_east_label_of_kink()
    12411033            '0'
    12421034        """
    class PartialPuzzle(object): 
    12521044
    12531045        EXAMPLES::
    12541046
    1255             sage: from sage.combinat.knutson_tao_puzzles import PartialPuzzle
    1256             sage: P = PartialPuzzle('0101','0101')
     1047            sage: from sage.combinat.knutson_tao_puzzles import PuzzleFilling
     1048            sage: P = PuzzleFilling('0101','0101')
    12571049            sage: P.is_completed()
    12581050            False
    12591051
    1260             sage: ps = PuzzleSolver("H")
     1052            sage: from sage.combinat.knutson_tao_puzzles import KnutsonTaoPuzzleSolver
     1053            sage: ps = KnutsonTaoPuzzleSolver("H")
    12611054            sage: puzzle = ps('0101','1001')[0]
    12621055            sage: puzzle.is_completed()
    12631056            True
    class PartialPuzzle(object): 
    12711064
    12721065        EXAMPLES::
    12731066
    1274             sage: ps = PuzzleSolver("H")
     1067            sage: from sage.combinat.knutson_tao_puzzles import KnutsonTaoPuzzleSolver
     1068            sage: ps = KnutsonTaoPuzzleSolver("H")
    12751069            sage: ps('0101','1001')[0].south_labels()
    12761070            ('1', '0', '1', '0')
    12771071        """
     1072        # TODO: return ''.join(self[i, i]['south'] for i in range(1, self._n + 1))
    12781073        return tuple([self[i,i]['south'] for i in range(1, self._n+1)])
    12791074
    12801075    def add_piece(self, piece):
    class PartialPuzzle(object): 
    12831078
    12841079        EXAMPLES::
    12851080
    1286             sage: from sage.combinat.knutson_tao_puzzles import DeltaPiece, PartialPuzzle
     1081            sage: from sage.combinat.knutson_tao_puzzles import DeltaPiece, PuzzleFilling
    12871082            sage: piece = DeltaPiece('0','1','0')
    1288             sage: P = PartialPuzzle('0101','0101'); P
     1083            sage: P = PuzzleFilling('0101','0101'); P
    12891084            {}
    12901085            sage: P.add_piece(piece); P
    12911086            {(1, 4): 1/0\0}
    class PartialPuzzle(object): 
    13091104
    13101105        EXAMPLES::
    13111106
    1312             sage: from sage.combinat.knutson_tao_puzzles import DeltaPiece, PartialPuzzle
    1313             sage: P = PartialPuzzle('0101','0101'); P
     1107            sage: from sage.combinat.knutson_tao_puzzles import DeltaPiece, PuzzleFilling
     1108            sage: P = PuzzleFilling('0101','0101'); P
    13141109            {}
    13151110            sage: piece = DeltaPiece('0','1','0')
    13161111            sage: pieces = [piece,piece]
    class PartialPuzzle(object): 
    13351130        EXAMPLES::
    13361131
    13371132
    1338             sage: from sage.combinat.knutson_tao_puzzles import DeltaPiece, PartialPuzzle
     1133            sage: from sage.combinat.knutson_tao_puzzles import DeltaPiece, PuzzleFilling
    13391134            sage: piece = DeltaPiece('0','1','0')
    1340             sage: P = PartialPuzzle('0101','0101'); P
     1135            sage: P = PuzzleFilling('0101','0101'); P
    13411136            {}
    13421137            sage: PP = P.copy()
    13431138            sage: P.add_piece(piece); P
    class PartialPuzzle(object): 
    13451140            sage: PP
    13461141            {}
    13471142        """
    1348         PP = PartialPuzzle(self._nw_labels, self._ne_labels)
     1143        PP = PuzzleFilling(self._nw_labels, self._ne_labels)
    13491144        PP._squares = self._squares.copy()
    13501145        PP._kink_coordinates = self._kink_coordinates
    13511146        PP._n = self._n
    class PartialPuzzle(object): 
    13571152
    13581153        EXAMPLES::
    13591154
    1360             sage: ps = PuzzleSolver("HT")
     1155            sage: from sage.combinat.knutson_tao_puzzles import KnutsonTaoPuzzleSolver
     1156            sage: ps = KnutsonTaoPuzzleSolver("HT")
    13611157            sage: puzzles = ps('0101','1001')
    1362             sage: sorted([p.contribution() for p in puzzles], key = str)
     1158            sage: sorted([p.contribution() for p in puzzles], key=str)
    13631159            [1, y1 - y3]
    13641160        """
    13651161        R = PolynomialRing(Integers(), 'y', self._n+1)
    class PartialPuzzle(object): 
    13771173        """
    13781174        TESTS::
    13791175
    1380             sage: from sage.combinat.knutson_tao_puzzles import H_grassmannian_pieces, PartialPuzzle
    1381             sage: P = PartialPuzzle('0101','0101'); P
     1176            sage: from sage.combinat.knutson_tao_puzzles import H_grassmannian_pieces, PuzzleFilling
     1177            sage: P = PuzzleFilling('0101','0101'); P
    13821178            {}
    13831179            sage: P.__repr__()
    13841180            '{}'
    class PartialPuzzle(object): 
    13911187
    13921188        TESTS::
    13931189
    1394             sage: ps = PuzzleSolver("H")
     1190            sage: from sage.combinat.knutson_tao_puzzles import KnutsonTaoPuzzleSolver
     1191            sage: ps = KnutsonTaoPuzzleSolver("H")
    13951192            sage: puzzle = ps('0101','1001')[0]
    13961193            sage: puzzle
    13971194            {(1, 2): 1/\1  10\/0, (1, 3): 0/\10  1\/1, (3, 3): 1/1\1, (4, 4): 10/0\1,
    class PartialPuzzle(object): 
    14191216
    14201217        EXAMPLES::
    14211218
    1422             sage: ps = PuzzleSolver("H")
     1219            sage: from sage.combinat.knutson_tao_puzzles import KnutsonTaoPuzzleSolver
     1220            sage: ps = KnutsonTaoPuzzleSolver("H")
    14231221            sage: puzzle = ps('0101','1001')[0]
    14241222            sage: puzzle.plot()  #not tested
    14251223            sage: puzzle.plot(style='fill')  #not tested
    class PartialPuzzle(object): 
    14541252            sage: latex.extra_preamble(r'''\usepackage{tikz}''')
    14551253            sage: from sage.combinat.knutson_tao_puzzles import *
    14561254
    1457             sage: ps = PuzzleSolver(H_grassmannian_pieces())
     1255            sage: ps = KnutsonTaoPuzzleSolver(H_grassmannian_pieces())
    14581256            sage: solns = ps('0101', '0101')
    14591257            sage: view(solns[0], viewer='pdf', tightpage=True)  # not tested
    14601258
    1461             sage: ps = PuzzleSolver(HT_two_step_pieces())
     1259            sage: ps = KnutsonTaoPuzzleSolver(HT_two_step_pieces())
    14621260            sage: solns = ps(list('10212'), list('12012'))
    14631261            sage: view(solns[0], viewer='pdf', tightpage=True)  # not tested
    14641262
    1465             sage: ps = PuzzleSolver(K_grassmannian_pieces())
     1263            sage: ps = KnutsonTaoPuzzleSolver(K_grassmannian_pieces())
    14661264            sage: solns = ps('0101', '0101')
    14671265            sage: view(solns[0], viewer='pdf', tightpage=True)  # not tested
    14681266
    class PartialPuzzle(object): 
    15261324
    15271325        return s
    15281326
    1529     def path_thru_puzzle(self, coord):
    1530         """
    1531         Returns the content row of the LR skew tableau corresponding to ``coord``.
    1532 
    1533         This method traces out a path from ``coord`` to its "mirror" coordinate.
    1534         If ``coord`` specifies the `i`-th 1 from the top on the north-east border
    1535         of the puzzle, then its mirror is the `i`-th 1 from the top on the north-west
    1536         border. The algorithm records the content numbers of the traced vertical rhombi.
    1537         See [Vakil03]_ and [Purbhoo07]_.
    1538 
    1539         .. WARNING::
    1540 
    1541             This method only works for the classical cohomology puzzle pieces.
    1542 
    1543         REFERENCES:
    1544 
    1545         .. [Vakil03] R. Vakil, A geometric Littlewood-Richardson rule, {{{:arXiv:`0302294`}}}
    1546 
    1547         .. [Purbhoo07] K. Purbhoo, Puzzles, Tableaux and Mosaics, {{{:arXiv:`0705.1184`}}}
    1548 
    1549         INPUT:
    1550 
    1551         - ``corrd`` -- north-east boundary position counting from the top whose label is 1
    1552 
    1553         OUTPUT: a list of numbers giving the content of one row in the LR tableau
    1554 
    1555         EXAMPLES::
    1556 
    1557             sage: ps = PuzzleSolver("H")
    1558             sage: solns = sorted(ps('0010111','0011011'), key = str)
    1559             sage: puzzle = solns[0]
    1560             sage: puzzle.path_thru_puzzle(6)
    1561             [1, 3, 3]
    1562             sage: puzzle.path_thru_puzzle(5)
    1563             Traceback (most recent call last):
    1564             ...
    1565             AssertionError: The coordinate needs to be a coordinate of a 1 on the north east boundary
    1566 
    1567             sage: puzzle = solns[1]
    1568             sage: puzzle.path_thru_puzzle(7)
    1569             [4, 4]
    1570         """
    1571         i = coord
    1572         assert self._ne_labels[coord-1] == '1', "The coordinate needs to be a coordinate of a 1 on the north east boundary"
    1573         j = self._n
    1574         k = 0
    1575         LR_list=[]
    1576         dir = "N"
    1577         while i != 0:
    1578             if i==j:
    1579                 current_piece = self[(i,j)]
    1580                 current_labels = current_piece.border()
    1581                 if current_labels == ('1', '1', '1'):
    1582                     i = i-1
    1583                     dir = "S"
    1584                     k = k+1
    1585                 elif current_labels == ('0', '10', '1'):
    1586                     i = i-1
    1587                     j = j-1
    1588             elif dir == "N":
    1589                 current_piece = self[(i,j)].north_piece()
    1590                 current_labels = current_piece.border()
    1591                 if current_labels == ('1', '1', '1'):
    1592                     i = i-1
    1593                     dir = "S"
    1594                     k = k+1
    1595                 elif current_labels == ('0', '10', '1'):
    1596                     i = i-1
    1597                     j = j-1
    1598             elif dir == "S":
    1599                 current_piece = self[(i,j)].south_piece()
    1600                 current_labels = current_piece.border()
    1601                 if current_labels == ('1', '1', '1'):
    1602                     j = j-1
    1603                     dir = "N"
    1604                 elif current_labels == ('10', '1', '0'):
    1605                     i = i-1
    1606                     LR_list.append(k)
    1607             else: #only necessary if wrong input to terminate loop!
    1608                 i = i-1
    1609         return LR_list
    1610 
    1611 
    1612     def LR_tab_from_puzzle(self):
    1613         """
    1614         Creates the skew Littlewood-Richardson tableau from the puzzle ``self``.
    1615 
    1616         EXAMPLES::
    1617 
    1618             sage: ps = PuzzleSolver("H")
    1619             sage: solns = ps('010101','010101')
    1620             sage: sorted([puzzle.LR_tab_from_puzzle() for puzzle in solns])
    1621             [[[None, None, 1], [None, 1], [1]],
    1622             [[None, None, 1], [None, 1], [2]],
    1623             [[None, None, 1], [None, 2], [1]],
    1624             [[None, None, 1], [None, 2], [3]]]
    1625         """
    1626         st = self._nw_labels
    1627         lam = partition_from_string(st)
    1628         k = 0
    1629         LRtableaux = []
    1630         for i in range(0,len(st)):
    1631             LRrow = []
    1632             if st[i] == '1':
    1633                 k=k+1
    1634                 for j in range(0,lam[k-1]):
    1635                     LRrow.append(None)
    1636                 LRrow.extend(self.path_thru_puzzle(i+1))
    1637                 LRtableaux.append(LRrow)
    1638         return SkewTableau(LRtableaux)
    1639 
    1640 
    1641 def partition_from_string(str):
    1642     """
    1643     Returns a partition from the string data of a partition.
    1644 
    1645     INPUT:
    1646 
    1647     - ``str`` -- a tuple of a string of 1's and 0's
    1648 
    1649     OUTPUT:
    1650 
    1651     - a list of weakly decreasing integers specifying the corresponding partition shape
    1652 
    1653     EXAMPLES::
    1654 
    1655         sage: from sage.combinat.knutson_tao_puzzles import partition_from_string
    1656         sage: partition_from_string(('0','1','0','1','0','1'))
    1657         [2, 1, 0]
    1658         sage: partition_from_string(('0','0','0','0','1','1'))
    1659         [0, 0]
    1660         sage: partition_from_string(('0','0','0','1','1','1'))
    1661         [0, 0, 0]
    1662         sage: partition_from_string(('1','1','1','0','0','0'))
    1663         [3, 3, 3]
    1664     """
    1665     Pt = []
    1666     n = len(str)
    1667     k=0
    1668     for i in range(0,n):
    1669         if str[n-i-1]=='1':
    1670             k=k+1
    1671             Pt.append(i+1-k)
    1672     return Pt[::-1]
    1673 
    1674 class PuzzleSolver(UniqueRepresentation):
     1327class KnutsonTaoPuzzleSolver(UniqueRepresentation):
    16751328    r"""
    16761329    Returns puzzle solver function used to create all puzzles with given boundary conditions.
    16771330    """
    16781331    def __init__(self, puzzle_pieces):
    16791332        r"""
    1680         Initialize the puzzle solver.
     1333        Knutson-Tao puzzle solver.
     1334
     1335        This class implements a generic algorithm to solve Knutson-Tao puzzles.
     1336        An instance of this class will be callable: the arguments are the
     1337        labels of north-east and north-west sides of the puzzle boundary; the
     1338        output is the list of the fillings of the puzzle with the specified
     1339        pieces.
    16811340
    16821341        INPUT:
    16831342
    1684         - ``puzzle_pieces`` -- takes either a list of puzzle pieces or a string
    1685           "H", "HT", "K", "H2step", "HT2step", "BK" to indicate the Grassmannian,
    1686           equivariant Grassmannian, K-theory, Grassmannian 2 step, equivariant
    1687           Grassmannian 2 step or Belkale-Kumar puzzle pieces.
     1343        - ``puzzle_pieces`` -- takes either a collection of puzzle pieces or
     1344          a string indicating a pre-programmed collection of puzzle pieces:
    16881345
    1689         - ``maxLetter`` -- (default: None) None or positive integer which only needs
    1690           to be specified for Belkale-Kumar puzzle pieces.
     1346          - ``H`` -- cohomology of the Grassmannian
     1347          - ``HT`` -- equivariant cohomology of the Grassmannian
     1348          - ``K`` -- K-theory
     1349          - ``H2step`` -- cohomology of the *2-step* Grassmannian
     1350          - ``HT2step`` -- equivariant cohomology of the *2-step* Grassmannian
     1351          - ``BK`` -- Belkale-Kumar puzzle pieces
    16911352
    1692         OUTPUT:
     1353        - ``max_letter`` -- (default: None) None or a positive integer. This is
     1354          only required only for Belkale-Kumar puzzles.
    16931355
    1694         - function that takes as input the outer label of two sides of the puzzle boundary
    1695            and returns the list of puzzle fillings
     1356        EXAMPLES:
    16961357
    1697         EXAMPLES::
     1358        Each puzzle piece is an edge-labelled triangle oriented in such a way
     1359        that it has a south edge (called a *delta* piece) or a north edge
     1360        (called a *nabla* piece). For example, the puzzle pieces corresponding
     1361        to the cohomology of the Grassmannian are the following::
    16981362
    16991363            sage: from sage.combinat.knutson_tao_puzzles import H_grassmannian_pieces
    1700             sage: ps = PuzzleSolver(H_grassmannian_pieces())
     1364            sage: H_grassmannian_pieces()
     1365            Nablas : [0\0/0, 0\10/1, 10\1/0, 1\0/10, 1\1/1]
     1366            Deltas : [0/0\0, 0/1\10, 1/10\0, 1/1\1, 10/0\1]
     1367
     1368        In the string representation, the nabla pieces are depicted as
     1369        ``c\a/b``, where `a` is the label of the north edge, `b` is the label
     1370        of the south-east edge, `c` is the label of the south-west edge.
     1371        A similar string representation exists for the delta pieces.
     1372
     1373        To create a puzzle solver, one specifies a collection of puzzle pieces::
     1374
     1375            sage: KnutsonTaoPuzzleSolver(H_grassmannian_pieces())
     1376            Knutson-Tao puzzle solver with pieces:
     1377            Nablas : [0\0/0, 0\10/1, 10\1/0, 1\0/10, 1\1/1]
     1378            Deltas : [0/0\0, 0/1\10, 1/10\0, 1/1\1, 10/0\1]
     1379
     1380        The following shorthand to create the above puzzle solver is also supported::
     1381
     1382            sage: KnutsonTaoPuzzleSolver('H')
     1383            Knutson-Tao puzzle solver with pieces:
     1384            Nablas : [0\0/0, 0\10/1, 10\1/0, 1\0/10, 1\1/1]
     1385            Deltas : [0/0\0, 0/1\10, 1/10\0, 1/1\1, 10/0\1]
     1386
     1387        The solver will compute all fillings of the puzzle with the given
     1388        puzzle pieces. The user specifies the labels of north-east and
     1389        north-west sides of the puzzle boundary and the output is a list of the
     1390        fillings of the puzzle with the specified pieces. For example, there is
     1391        one solution to the puzzle whose north-west and north-east edges are
     1392        both labeled '0'::
     1393
     1394            sage: ps = KnutsonTaoPuzzleSolver('H')
    17011395            sage: ps('0', '0')
    17021396            [{(1, 1): 0/0\0}]
    17031397
     1398        There are two solutions to the puzzle whose north-west and north-east
     1399        edges are both labeled '0101'::
     1400
     1401            sage: ps = KnutsonTaoPuzzleSolver('H')
     1402            sage: solns = ps('0101', '0101')
     1403            sage: len(solns)
     1404            2
     1405            sage: solns.sort(key=str)
     1406            sage: solns
     1407            [{(1, 2): 1/\0  0\/1, (1, 3): 0/\0  0\/0, (3, 3): 1/1\1, (4, 4): 10/0\1, (1, 4): 1/\0  0\/1, (1, 1): 0/0\0, (2, 3): 0/\10  1\/1, (2, 2): 1/1\1, (3, 4): 0/\0  1\/10, (2, 4): 1/\1  10\/0},
     1408             {(1, 2): 1/\1  10\/0, (1, 3): 0/\0  1\/10, (3, 3): 0/0\0, (4, 4): 1/1\1, (1, 4): 1/\0  0\/1, (1, 1): 0/1\10, (2, 3): 10/\1  0\/0, (2, 2): 0/0\0, (3, 4): 1/\0  0\/1, (2, 4): 1/\1  1\/1}]
     1409
     1410        The pieces in a puzzle filling are indexed by pairs of non-negative
     1411        integers `(i, j)` with `1 \leq i \leq j \leq n`, where `n` is the
     1412        length of the word labelling the triangle edge. The pieces indexed by
     1413        `(i, i)` are the triangles along the south edge of the puzzle. ::
     1414
     1415            sage: f = solns[0]
     1416            sage: [f[i, i] for i in range(1,5)]
     1417            [0/0\0, 1/1\1, 1/1\1, 10/0\1]
     1418
     1419        The pieces indexed by `(i, j)` for `j > i` are a pair consisting of
     1420        a delta piece and nabla piece glued together along the south edge and
     1421        north edge, respectively (these pairs are called *rhombi*). ::
     1422
     1423            sage: f = solns[0]
     1424            sage: f[1, 2]
     1425            1/\0  0\/1
     1426
     1427        Below are examples of using each of the currently supported puzzles.
     1428
     1429        Cohomology of the Grassmannian::
     1430
     1431            sage: ps = KnutsonTaoPuzzleSolver("H")
     1432            sage: solns = ps('0101', '0101')
     1433            sage: sorted(solns, key=str)
     1434            [{(1, 2): 1/\0  0\/1, (1, 3): 0/\0  0\/0, (3, 3): 1/1\1, (4, 4): 10/0\1, (1, 4): 1/\0  0\/1, (1, 1): 0/0\0, (2, 3): 0/\10  1\/1, (2, 2): 1/1\1, (3, 4): 0/\0  1\/10, (2, 4): 1/\1  10\/0},
     1435            {(1, 2): 1/\1  10\/0, (1, 3): 0/\0  1\/10, (3, 3): 0/0\0, (4, 4): 1/1\1, (1, 4): 1/\0  0\/1, (1, 1): 0/1\10, (2, 3): 10/\1  0\/0, (2, 2): 0/0\0, (3, 4): 1/\0  0\/1, (2, 4): 1/\1  1\/1}]
     1436
     1437        Equivariant puzzles::
     1438
     1439            sage: ps = KnutsonTaoPuzzleSolver("HT")
     1440            sage: solns = ps('0101', '0101')
     1441            sage: sorted(solns, key=str)
     1442            [{(1, 2): 1/\0  0\/1, (1, 3): 0/\0  0\/0, (3, 3): 0/0\0, (4, 4): 1/1\1, (1, 4): 1/\0  0\/1, (1, 1): 0/0\0, (2, 3): 0/\1  1\/0, (2, 2): 1/1\1, (3, 4): 1/\0  0\/1, (2, 4): 1/\1  1\/1},
     1443            {(1, 2): 1/\0  0\/1, (1, 3): 0/\0  0\/0, (3, 3): 1/1\1, (4, 4): 10/0\1, (1, 4): 1/\0  0\/1, (1, 1): 0/0\0, (2, 3): 0/\10  1\/1, (2, 2): 1/1\1, (3, 4): 0/\0  1\/10, (2, 4): 1/\1  10\/0},
     1444            {(1, 2): 1/\1  10\/0, (1, 3): 0/\0  1\/10, (3, 3): 0/0\0, (4, 4): 1/1\1, (1, 4): 1/\0  0\/1, (1, 1): 0/1\10, (2, 3): 10/\1  0\/0, (2, 2): 0/0\0, (3, 4): 1/\0  0\/1, (2, 4): 1/\1  1\/1}]
     1445
     1446        K-Theory puzzles::
     1447
     1448            sage: ps = KnutsonTaoPuzzleSolver("K")
     1449            sage: solns = ps('0101', '0101')
     1450            sage: sorted(solns, key=str)
     1451            [{(1, 2): 1/\0  0\/1, (1, 3): 0/\0  0\/0, (3, 3): 1/1\1, (4, 4): 10/0\1, (1, 4): 1/\0  0\/1, (1, 1): 0/0\0, (2, 3): 0/\10  1\/1, (2, 2): 1/1\1, (3, 4): 0/\0  1\/10, (2, 4): 1/\1  10\/0},
     1452            {(1, 2): 1/\1  10\/0, (1, 3): 0/\0  1\/10, (3, 3): 0/0\0, (4, 4): 1/1\1, (1, 4): 1/\0  0\/1, (1, 1): 0/1\10, (2, 3): 10/\1  0\/0, (2, 2): 0/0\0, (3, 4): 1/\0  0\/1, (2, 4): 1/\1  1\/1},
     1453            {(1, 2): 1/\1  10\/0, (1, 3): 0/\0  1\/K, (3, 3): 1/1\1, (4, 4): 10/0\1, (1, 4): 1/\0  0\/1, (1, 1): 0/1\10, (2, 3): K/\K  0\/1, (2, 2): 0/0\0, (3, 4): 0/\0  1\/10, (2, 4): 1/\1  K\/0}]
     1454
     1455        Two-step puzzles::
     1456
     1457            sage: ps = KnutsonTaoPuzzleSolver("H2step")
     1458            sage: solns = ps('01201', '01021')
     1459            sage: sorted(solns, key=str)
     1460            [{(1, 2): 1/\0  0\/1, (1, 3): 2/\0  0\/2, (3, 3): 1/1\1, (4, 5): 20/\2  1\/10, (4, 4): 1/1\1, (5, 5): 10/0\1, (1, 4): 0/\0  0\/0, (1, 1): 0/0\0, (1, 5): 1/\0  0\/1, (2, 3): 2/\2  21\/1, (2, 2): 1/2\21, (2, 5): 1/\1  10\/0, (3, 4): 21/\2  1\/1, (2, 4): 0/\10  2\/21, (3, 5): 0/\0  2\/20},
     1461            {(1, 2): 1/\1  10\/0, (1, 3): 2/\1  1\/2, (3, 3): 0/0\0, (4, 5): 2(10)/\2  0\/1, (4, 4): 0/0\0, (5, 5): 1/1\1, (1, 4): 0/\0  1\/10, (1, 1): 0/1\10, (1, 5): 1/\0  0\/1, (2, 3): 2/\2  20\/0, (2, 2): 0/2\20, (2, 5): 1/\1  1\/1, (3, 4): 20/\2  0\/0, (2, 4): 10/\1  2\/20, (3, 5): 1/\0  2\/2(10)},
     1462            {(1, 2): 1/\21  20\/0, (1, 3): 2/\2  21\/1, (3, 3): 1/1\1, (4, 5): 21/\2  1\/1, (4, 4): 10/0\1, (5, 5): 1/1\1, (1, 4): 0/\0  2\/20, (1, 1): 0/2\20, (1, 5): 1/\0  0\/1, (2, 3): 1/\0  0\/1, (2, 2): 0/0\0, (2, 5): 1/\1  2\/21, (3, 4): 0/\0  1\/10, (2, 4): 20/\2  0\/0, (3, 5): 21/\0  0\/21}]
     1463
     1464        Two-step equivariant puzzles::
     1465
     1466            sage: ps = KnutsonTaoPuzzleSolver("HT2step")
     1467            sage: solns = ps('10212', '12012')
     1468            sage: sorted(solns, key=str)
     1469            [{(1, 2): 0/\(21)0  1\/2, (1, 3): 2/\1  (21)0\/0, (3, 3): 0/0\0, (4, 5): 1/\1  2\/21, (4, 4): 2/2\2, (5, 5): 21/1\2, (1, 4): 1/\1  1\/1, (1, 1): 1/1\1, (1, 5): 2/\1  1\/2, (2, 3): 0/\2  2\/0, (2, 2): 2/2\2, (2, 5): 2/\2  21\/1, (3, 4): 2/\0  0\/2, (2, 4): 1/\21  2\/2, (3, 5): 1/\0  0\/1},
     1470            {(1, 2): 0/\(21)0  1\/2, (1, 3): 2/\1  (21)0\/0, (3, 3): 0/0\0, (4, 5): 2/\1  1\/2, (4, 4): 1/1\1, (5, 5): 2/2\2, (1, 4): 1/\1  1\/1, (1, 1): 1/1\1, (1, 5): 2/\1  1\/2, (2, 3): 0/\2  2\/0, (2, 2): 2/2\2, (2, 5): 2/\2  2\/2, (3, 4): 1/\0  0\/1, (2, 4): 1/\2  2\/1, (3, 5): 2/\0  0\/2},
     1471            {(1, 2): 0/\(21)0  1\/2, (1, 3): 2/\1  (21)0\/0, (3, 3): 2/2\2, (4, 5): 1/\1  2\/21, (4, 4): 20/0\2, (5, 5): 21/1\2, (1, 4): 1/\1  1\/1, (1, 1): 1/1\1, (1, 5): 2/\1  1\/2, (2, 3): 0/\20  2\/2, (2, 2): 2/2\2, (2, 5): 2/\2  21\/1, (3, 4): 0/\0  2\/20, (2, 4): 1/\21  20\/0, (3, 5): 1/\0  0\/1},
     1472            {(1, 2): 0/\1  1\/0, (1, 3): 2/\1  1\/2, (3, 3): 0/0\0, (4, 5): 1/\1  2\/21, (4, 4): 2/2\2, (5, 5): 21/1\2, (1, 4): 1/\1  1\/1, (1, 1): 1/1\1, (1, 5): 2/\1  1\/2, (2, 3): 2/\2  20\/0, (2, 2): 0/2\20, (2, 5): 2/\2  21\/1, (3, 4): 2/\0  0\/2, (2, 4): 1/\21  2\/2, (3, 5): 1/\0  0\/1},
     1473            {(1, 2): 0/\1  1\/0, (1, 3): 2/\1  1\/2, (3, 3): 0/0\0, (4, 5): 2/\1  1\/2, (4, 4): 1/1\1, (5, 5): 2/2\2, (1, 4): 1/\1  1\/1, (1, 1): 1/1\1, (1, 5): 2/\1  1\/2, (2, 3): 2/\2  20\/0, (2, 2): 0/2\20, (2, 5): 2/\2  2\/2, (3, 4): 1/\0  0\/1, (2, 4): 1/\2  2\/1, (3, 5): 2/\0  0\/2},
     1474            {(1, 2): 0/\10  1\/1, (1, 3): 2/\10  10\/2, (3, 3): 1/1\1, (4, 5): 10/\1  2\/20, (4, 4): 2/2\2, (5, 5): 20/0\2, (1, 4): 1/\1  10\/0, (1, 1): 1/1\1, (1, 5): 2/\1  1\/2, (2, 3): 2/\2  21\/1, (2, 2): 1/2\21, (2, 5): 2/\2  20\/0, (3, 4): 2/\1  1\/2, (2, 4): 0/\20  2\/2, (3, 5): 0/\0  1\/10},
     1475            {(1, 2): 0/\10  1\/1, (1, 3): 2/\10  10\/2, (3, 3): 1/1\1, (4, 5): 2/\1  1\/2, (4, 4): 10/0\1, (5, 5): 2/2\2, (1, 4): 1/\1  10\/0, (1, 1): 1/1\1, (1, 5): 2/\1  1\/2, (2, 3): 2/\2  21\/1, (2, 2): 1/2\21, (2, 5): 2/\2  2\/2, (3, 4): 0/\0  1\/10, (2, 4): 0/\2  2\/0, (3, 5): 2/\0  0\/2},
     1476            {(1, 2): 0/\20  21\/1, (1, 3): 2/\2  20\/0, (3, 3): 0/0\0, (4, 5): 2/\1  1\/2, (4, 4): 1/1\1, (5, 5): 2/2\2, (1, 4): 1/\1  2\/21, (1, 1): 1/2\21, (1, 5): 2/\1  1\/2, (2, 3): 0/\1  1\/0, (2, 2): 1/1\1, (2, 5): 2/\2  2\/2, (3, 4): 1/\0  0\/1, (2, 4): 21/\2  1\/1, (3, 5): 2/\0  0\/2},
     1477            {(1, 2): 0/\20  21\/1, (1, 3): 2/\2  20\/0, (3, 3): 1/1\1, (4, 5): 2/\1  1\/2, (4, 4): 10/0\1, (5, 5): 2/2\2, (1, 4): 1/\1  2\/21, (1, 1): 1/2\21, (1, 5): 2/\1  1\/2, (2, 3): 0/\10  1\/1, (2, 2): 1/1\1, (2, 5): 2/\2  2\/2, (3, 4): 0/\0  1\/10, (2, 4): 21/\2  10\/0, (3, 5): 2/\0  0\/2},
     1478            {(1, 2): 0/\21  21\/0, (1, 3): 2/\2  21\/1, (3, 3): 0/0\0, (4, 5): 2/\1  1\/2, (4, 4): 1/1\1, (5, 5): 2/2\2, (1, 4): 1/\1  2\/21, (1, 1): 1/2\21, (1, 5): 2/\1  1\/2, (2, 3): 1/\1  10\/0, (2, 2): 0/1\10, (2, 5): 2/\2  2\/2, (3, 4): 1/\0  0\/1, (2, 4): 21/\2  1\/1, (3, 5): 2/\0  0\/2}]
     1479
     1480
     1481        Belkale-Kumar puzzles::
     1482
     1483            sage: ps = KnutsonTaoPuzzleSolver("BK", 3)
     1484            sage: solns = ps('10212', '12012')
     1485            sage: sorted(solns, key=str)
     1486
    17041487        TESTS:
    17051488
    17061489        Check that UniqueRepresentation works::
    17071490
    1708             sage: from sage.combinat.knutson_tao_puzzles import H_grassmannian_pieces
    1709             sage: ps = PuzzleSolver(H_grassmannian_pieces())
    1710             sage: qs = PuzzleSolver("H")
     1491            sage: from sage.combinat.knutson_tao_puzzles import KnutsonTaoPuzzleSolver, H_grassmannian_pieces
     1492            sage: ps = KnutsonTaoPuzzleSolver(H_grassmannian_pieces())
     1493            sage: qs = KnutsonTaoPuzzleSolver("H")
    17111494            sage: ps
    17121495            Knutson-Tao puzzle solver with pieces:
    17131496            Nablas : [0\0/0, 0\10/1, 10\1/0, 1\0/10, 1\1/1]
    class PuzzleSolver(UniqueRepresentation) 
    17241507        self._bottom_deltas = tuple(puzzle_pieces.boundary_deltas())
    17251508
    17261509    @staticmethod
    1727     def __classcall_private__(cls, puzzle_pieces, maxLetter=None):
     1510    def __classcall_private__(cls, puzzle_pieces, max_letter=None):
    17281511        """
    17291512        TESTS::
    17301513
    17311514            sage: from sage.combinat.knutson_tao_puzzles import *
    1732             sage: PuzzleSolver(H_grassmannian_pieces()) == PuzzleSolver("H") # indirect doctest
     1515            sage: KnutsonTaoPuzzleSolver(H_grassmannian_pieces()) == KnutsonTaoPuzzleSolver("H") # indirect doctest
    17331516            True
    1734             sage: PuzzleSolver(HT_grassmannian_pieces()) == PuzzleSolver("HT")
     1517            sage: KnutsonTaoPuzzleSolver(HT_grassmannian_pieces()) == KnutsonTaoPuzzleSolver("HT")
    17351518            True
    1736             sage: PuzzleSolver(K_grassmannian_pieces()) == PuzzleSolver("K")
     1519            sage: KnutsonTaoPuzzleSolver(K_grassmannian_pieces()) == KnutsonTaoPuzzleSolver("K")
    17371520            True
    1738             sage: PuzzleSolver(H_two_step_pieces()) == PuzzleSolver("H2step")
     1521            sage: KnutsonTaoPuzzleSolver(H_two_step_pieces()) == KnutsonTaoPuzzleSolver("H2step")
    17391522            True
    1740             sage: PuzzleSolver(HT_two_step_pieces()) == PuzzleSolver("HT2step")
     1523            sage: KnutsonTaoPuzzleSolver(HT_two_step_pieces()) == KnutsonTaoPuzzleSolver("HT2step")
    17411524            True
    1742             sage: PuzzleSolver(BK_pieces(3)) == PuzzleSolver("BK",3)
     1525            sage: KnutsonTaoPuzzleSolver(BK_pieces(3)) == KnutsonTaoPuzzleSolver("BK",3)
    17431526            True
    17441527        """
    17451528        if isinstance(puzzle_pieces, str):
    class PuzzleSolver(UniqueRepresentation) 
    17541537            elif puzzle_pieces == "HT2step":
    17551538                puzzle_pieces = HT_two_step_pieces()
    17561539            elif puzzle_pieces == "BK":
    1757                 if maxLetter is not None:
    1758                     puzzle_pieces = BK_pieces(maxLetter)
     1540                if max_letter is not None:
     1541                    puzzle_pieces = BK_pieces(max_letter)
    17591542                else:
    1760                     raise ValueError, "maxLetter needs to be specified"
    1761         return super(PuzzleSolver, cls).__classcall__(cls, puzzle_pieces)
     1543                    raise ValueError, "max_letter needs to be specified"
     1544        return super(KnutsonTaoPuzzleSolver, cls).__classcall__(cls, puzzle_pieces)
    17621545
    17631546    def __call__(self, lamda, mu, algorithm='strips'):
    17641547        """
    17651548        TESTS::
    17661549
    1767             sage: ps = PuzzleSolver("H")
     1550            sage: from sage.combinat.knutson_tao_puzzles import KnutsonTaoPuzzleSolver
     1551            sage: ps = KnutsonTaoPuzzleSolver("H")
    17681552            sage: ps('0101','1001')
    17691553            [{(1, 2): 1/\1  10\/0, (1, 3): 0/\10  1\/1, (3, 3): 1/1\1, (4, 4): 10/0\1, (1, 4): 1/\1  10\/0,
    17701554            (1, 1): 0/1\10, (2, 3): 1/\0  0\/1, (2, 2): 0/0\0, (3, 4): 0/\0  1\/10, (2, 4): 0/\0  0\/0}]
    class PuzzleSolver(UniqueRepresentation) 
    17841568        """
    17851569        EXAMPLES::
    17861570
    1787             sage: from sage.combinat.knutson_tao_puzzles import H_grassmannian_pieces
    1788             sage: PuzzleSolver(H_grassmannian_pieces())
     1571            sage: from sage.combinat.knutson_tao_puzzles import KnutsonTaoPuzzleSolver
     1572            sage: KnutsonTaoPuzzleSolver('H')
    17891573            Knutson-Tao puzzle solver with pieces:
    17901574            Nablas : [0\0/0, 0\10/1, 10\1/0, 1\0/10, 1\1/1]
    17911575            Deltas : [0/0\0, 0/1\10, 1/10\0, 1/1\1, 10/0\1]
    class PuzzleSolver(UniqueRepresentation) 
    18071591
    18081592        EXAMPLES::
    18091593
    1810             sage: from sage.combinat.knutson_tao_puzzles import H_grassmannian_pieces
    1811             sage: ps = PuzzleSolver(H_grassmannian_pieces())
     1594            sage: from sage.combinat.knutson_tao_puzzles import KnutsonTaoPuzzleSolver
     1595            sage: ps = KnutsonTaoPuzzleSolver('H')
    18121596            sage: ps._fill_piece('0', '0', ps._bottom_deltas)
    18131597            [0/0\0]
    18141598        """
    class PuzzleSolver(UniqueRepresentation) 
    18371621
    18381622        EXAMPLES::
    18391623
    1840             sage: from sage.combinat.knutson_tao_puzzles import H_grassmannian_pieces
    1841             sage: ps = PuzzleSolver(H_grassmannian_pieces())
     1624            sage: from sage.combinat.knutson_tao_puzzles import KnutsonTaoPuzzleSolver
     1625            sage: ps = KnutsonTaoPuzzleSolver('H')
    18421626            sage: ps._fill_strip(('0',), '0', ps._rhombus_pieces, ps._bottom_deltas)
    18431627            [[0/0\0]]
    18441628            sage: ps._fill_strip(('0','0'), '0', ps._rhombus_pieces, ps._bottom_deltas)
    class PuzzleSolver(UniqueRepresentation) 
    18501634
    18511635        TESTS::
    18521636
    1853             sage: from sage.combinat.knutson_tao_puzzles import H_grassmannian_pieces
    1854             sage: ps = PuzzleSolver(H_grassmannian_pieces())
     1637            sage: from sage.combinat.knutson_tao_puzzles import KnutsonTaoPuzzleSolver
     1638            sage: ps = KnutsonTaoPuzzleSolver('H')
    18551639            sage: ps._fill_strip(('0',), 'goo', ps._rhombus_pieces)
    18561640            []
    18571641        """
    class PuzzleSolver(UniqueRepresentation) 
    18771661
    18781662        EXAMPLES::
    18791663
    1880             sage: from sage.combinat.knutson_tao_puzzles import H_grassmannian_pieces
    1881             sage: ps = PuzzleSolver(H_grassmannian_pieces())
     1664            sage: from sage.combinat.knutson_tao_puzzles import KnutsonTaoPuzzleSolver
     1665            sage: ps = KnutsonTaoPuzzleSolver('H')
    18821666            sage: list(ps._fill_puzzle_by_pieces('0', '0'))
    18831667            [{(1, 1): 0/0\0}]
    18841668        """
    1885         queue = [PartialPuzzle(lamda, mu)]
     1669        queue = [PuzzleFilling(lamda, mu)]
    18861670        while queue:
    18871671            PP = queue.pop()
    18881672            ne_label = PP.north_east_label_of_kink()
    class PuzzleSolver(UniqueRepresentation) 
    19051689
    19061690        EXAMPLES::
    19071691
    1908             sage: from sage.combinat.knutson_tao_puzzles import H_grassmannian_pieces
    1909             sage: ps = PuzzleSolver(H_grassmannian_pieces())
     1692            sage: from sage.combinat.knutson_tao_puzzles import KnutsonTaoPuzzleSolver
     1693            sage: ps = KnutsonTaoPuzzleSolver('H')
    19101694            sage: list(ps._fill_puzzle_by_strips('0', '0'))
    19111695            [{(1, 1): 0/0\0}]
    19121696            sage: list(ps._fill_puzzle_by_strips('01', '01'))
    19131697            [{(1, 2): 1/\0  0\/1, (1, 1): 0/0\0, (2, 2): 1/1\1}]
    19141698        """
    1915         queue = [PartialPuzzle(lamda, mu)]
     1699        queue = [PuzzleFilling(lamda, mu)]
    19161700        while queue:
    19171701            PP = queue.pop()
    19181702            (i, j) = PP.kink_coordinates()
    class PuzzleSolver(UniqueRepresentation) 
    19471731
    19481732        EXAMPLES::
    19491733
    1950             sage: from sage.combinat.knutson_tao_puzzles import K_grassmannian_pieces
    1951             sage: ps = PuzzleSolver(K_grassmannian_pieces())
     1734            sage: from sage.combinat.knutson_tao_puzzles import KnutsonTaoPuzzleSolver
     1735            sage: ps = KnutsonTaoPuzzleSolver('K')
    19521736            sage: solns = ps('0101', '0101')
    19531737            sage: ps.plot(solns)        # not tested
    19541738        """
    class PuzzleSolver(UniqueRepresentation) 
    19571741        m = len([gg.axes(False) for gg in g])
    19581742        return graphics_array(g, (m+3)/4, 4)
    19591743
     1744    def structure_constants(self, lamda, mu, nu=None):
     1745        r"""
     1746        Compute cohomology structure coefficients from puzzles.
    19601747
    1961 class SchubertCalculusAlgebra(CombinatorialFreeModule):
    1962     """
    1963     Schubert calculus algebra computed from puzzles.
    1964 
    1965     The Schubert calculus algebra can be used to compute products in the Schubert algebra.
    1966     It can be computed in the various settings that the puzzles exist for.
    1967 
    1968     INPUT:
    1969 
    1970     - ``R`` -- ground ring
    1971     - ``content`` -- tuple: the `i`-th entry in ``content`` specifies the number of `i`-th in the words that label the basis
    1972     - ``equivariance``, ``K``, ``BK`` -- boolean
    1973 
    1974     EXAMPLES::
    1975 
    1976         sage: from sage.combinat.knutson_tao_puzzles import SchubertCalculusAlgebra
    1977         sage: Sc = SchubertCalculusAlgebra(QQ, (2,1), equivariance = True).basis()
    1978         sage: Sc[Word('100')]
    1979         Sc[100]
    1980         sage: Sc[Word('100')]*Sc[Word('100')]
    1981         (y1^2-y1*y2-y1*y3+y2*y3)*Sc[100]
    1982 
    1983         sage: Sc = SchubertCalculusAlgebra(QQ, (2,2)).basis()
    1984         sage: Sc.an_element()
    1985         Sc[0011]
    1986         sage: Sc.an_element()*Sc.an_element()
    1987         Sc[0011]
    1988 
    1989         sage: Sc = SchubertCalculusAlgebra(QQ, (2,2), K=True).basis()
    1990         sage: Sc[Word('1010')]*Sc[Word('0101')]
    1991         Sc[1100]
    1992     """
    1993 
    1994     def __init__(self, R, content, equivariance=False, K=False, BK=False):
    1995         """
    19961748        INPUT:
    19971749
    1998         - ``R`` -- ground ring
    1999         - ``content`` -- tuple: the `i`-th entry in ``content`` specifies the number of `i`-th
    2000         - ``equivariance``, ``K``, ``BK`` -- boolean
     1750        - ``pieces`` -- puzzle pieces to be used
     1751        - ``lambda``, ``mu`` -- edge labels of puzzle for northwest and north east side
     1752        - ``nu`` -- (default: ``None``) If ``nu`` is not specified a dictionary is returned with
     1753          the structure coefficients corresponding to all south labels; if ``nu`` is given, only
     1754          the coefficients with the specified label is returned.
    20011755
    2002         EXAMPLES::
     1756        OUTPUT: dictionary
    20031757
    2004             sage: from sage.combinat.knutson_tao_puzzles import SchubertCalculusAlgebra
    2005             sage: SchubertCalculusAlgebra(QQ, (3,2))        # indirect doctest
    2006             Schubert Calculus Algebra over the Rational Field
    2007         """
    2008         from sage.misc.flatten import flatten
    2009         basis_elements = [Word()]
    2010         for i in range(len(content)):
    2011             w = [str(i)]*content[i]
    2012             basis_elements = flatten([b.shuffle(w).list() for b in basis_elements])
     1758        EXAMPLES:
    20131759
    2014         CombinatorialFreeModule.__init__(self, R, basis_elements,
    2015                                          prefix='Sc',
    2016                                          category = AlgebrasWithBasis(R))
     1760        Note: In order to standardize the output of the following examples,
     1761        we output a sorted list of items from the dictionary instead of the
     1762        dictionary itself.
    20171763
    2018         if len(content) == 2:
    2019             if equivariance:
    2020                 self._pieces = HT_grassmannian_pieces()
    2021             else:
    2022                 self._pieces = H_grassmannian_pieces()
    2023         elif len(content) == 3:
    2024             if equivariance:
    2025                 self._pieces = HT_two_step_pieces()
    2026             else:
    2027                 self._pieces = H_two_step_pieces()
     1764        Grassmannian cohomology::
    20281765
    2029         if K:
    2030             if equivariance or len(content) >= 3:
    2031                 raise NotImplementedError
    2032             else:
    2033                 self._pieces = K_grassmannian_pieces()
     1766            sage: ps = KnutsonTaoPuzzleSolver('H')
     1767            sage: cp = ps.structure_constants('0101', '0101')
     1768            sage: sorted(cp.items(), key=str)
     1769            [(('0', '1', '1', '0'), 1), (('1', '0', '0', '1'), 1)]
     1770            sage: ps.structure_constants('001001', '001010', '010100')
     1771            1
    20341772
    2035         #if BK:
    2036         #    if equivariance or K:
    2037         #        raise NotImplementedError
    2038         #else:
    2039         #    if len(content) > 4:
    2040         #        raise NotImplementedError
     1773        Equivariant cohomology::
    20411774
    2042         self._puzzle_solver = PuzzleSolver(self._pieces)
     1775            sage: ps = KnutsonTaoPuzzleSolver('HT')
     1776            sage: cp = ps.structure_constants('0101', '0101')
     1777            sage: sorted(cp.items(), key=str)
     1778            [(('0', '1', '0', '1'), y2 - y3),
     1779            (('0', '1', '1', '0'), 1),
     1780            (('1', '0', '0', '1'), 1)]
    20431781
    2044     def _repr_(self):
    2045         """
    2046         TESTS::
     1782        K-theory::
    20471783
    2048             sage: from sage.combinat.knutson_tao_puzzles import SchubertCalculusAlgebra
    2049             sage: SchubertCalculusAlgebra(QQ, (3,3))
    2050             Schubert Calculus Algebra over the Rational Field
    2051         """
    2052         return "Schubert Calculus Algebra over the %s" % self.base_ring()
     1784            sage: ps = KnutsonTaoPuzzleSolver('K')
     1785            sage: cp = ps.structure_constants('0101', '0101')
     1786            sage: sorted(cp.items(), key=str)
     1787            [(('0', '1', '1', '0'), 1), (('1', '0', '0', '1'), 1), (('1', '0', '1', '0'), -1)]
    20531788
    2054     def product_on_basis(self, w, u):
    2055         r"""
    2056         Computes product between ``w`` and ``u`` in the algebra.
     1789        Two-step::
    20571790
    2058         EXAMPLES::
     1791            sage: ps = KnutsonTaoPuzzleSolver('H2step')
     1792            sage: cp = ps.structure_constants('01122', '01122')
     1793            sage: sorted(cp.items(), key=str)
     1794            [(('0', '1', '1', '2', '2'), 1)]
     1795            sage: cp = ps.structure_constants('01201', '01021')
     1796            sage: sorted(cp.items(), key=str)
     1797            [(('0', '2', '1', '1', '0'), 1),
     1798             (('1', '2', '0', '0', '1'), 1),
     1799             (('2', '0', '1', '0', '1'), 1)]
    20591800
    2060             sage: from sage.combinat.knutson_tao_puzzles import SchubertCalculusAlgebra
    2061             sage: WordOptions(identifier='')
    2062             sage: Sc = SchubertCalculusAlgebra(QQ, (3,3)).basis()
    2063             sage: Sc[Word('001011')] * Sc[Word('010101')]               # indirect doctest
    2064             Sc[010110] + Sc[011001] + Sc[100101]
     1801        Two-step equivariant::
     1802
     1803            sage: ps = KnutsonTaoPuzzleSolver('HT2step')
     1804            sage: cp = ps.structure_constants('10212', '12012')
     1805            sage: sorted(cp.items(), key=str)
     1806            [(('1', '2', '0', '1', '2'), y1*y2 - y2*y3 - y1*y4 + y3*y4),
     1807             (('1', '2', '0', '2', '1'), y1 - y3),
     1808             (('1', '2', '1', '0', '2'), y2 - y4),
     1809             (('1', '2', '1', '2', '0'), 1),
     1810             (('1', '2', '2', '0', '1'), 1),
     1811             (('2', '1', '0', '1', '2'), y1 - y3),
     1812             (('2', '1', '1', '0', '2'), 1)]
    20651813        """
    20661814        from collections import defaultdict
    2067         z = defaultdict(int)
    2068         for p in self._puzzle_solver(w, u):
     1815        R = PolynomialRing(Integers(), 'y', len(lamda)+1)
     1816        z = defaultdict(R.zero)
     1817        for p in self(lamda, mu):
    20691818            z[p.south_labels()] += p.contribution()
    2070         return self.sum_of_terms((Word(m), c) for (m, c) in z.iteritems())
     1819        if nu is None:
     1820            return dict(z)
     1821        else:
     1822            return z[tuple(nu)]