# HG changeset patch
# User Anne Schilling <anne@math.ucdavis.edu>
# Date 1239260129 25200
# Node ID d65d5b2798ad1cc45fca517cb68dba809dee3808
# Parent  7820ee1d34570f493e1b0310d050076cc22cbe75
* * *
* * *
* * *
Update the affine* patches to use Sphinx syntax.

diff -r 7820ee1d3457 -r d65d5b2798ad sage/combinat/crystals/crystals.py
--- a/sage/combinat/crystals/crystals.py	Wed Apr 08 11:02:42 2009 -0700
+++ b/sage/combinat/crystals/crystals.py	Wed Apr 08 23:55:29 2009 -0700
@@ -73,7 +73,7 @@
     sage: Tens = TensorProductOfCrystals(C, C)
     sage: Spin = CrystalOfSpins(['B', 3])
     sage: Tab  = CrystalOfTableaux(['A', 3], shape = [2,1,1])
-    sage: Fast  = FastCrystal(['B', 2], shape = [3/2, 1/2])
+    sage: Fast = FastCrystal(['B', 2], shape = [3/2, 1/2])
 
 One can get (currently) crude plotting via::
 
@@ -158,8 +158,7 @@
     r"""
     The abstract class of crystals
     
-    instances of this class should have the following attributes:
-    
+    Instances of this class should have the following methods:
     
     -  cartan_type
     
@@ -183,6 +182,17 @@
             Ambient space of the Root system of type ['A', 5]
         """
         return self.cartan_type.root_system().ambient_space()
+  
+    def index_set(self):
+	"""
+	Returns the index set of the Dynkin diagram underlying the given crystal
+
+	EXAMPLES:
+	    sage: C = CrystalOfLetters(['A', 5])
+	    sage: C.index_set()
+	    [1, 2, 3, 4, 5]
+        """
+	return self.cartan_type.index_set()
 
     def Lambda(self):
         """
@@ -209,7 +219,6 @@
         
         -  Should check Stembridge's rules, etc.
         
-        
         EXAMPLES::
         
             sage: C = CrystalOfLetters(['A', 5])
@@ -250,7 +259,7 @@
         todo = result.copy()
         while len(todo) > 0:
             x = todo.pop()
-            for i in self.index_set:
+            for i in self.index_set():
                 y = x.f(i)
                 if y == None or y in result:
                     continue
@@ -272,7 +281,7 @@
         d = {}
         for x in self:
             d[x] = {}
-            for i in self.index_set:
+            for i in self.index_set():
                 child = x.f(i)
                 if child is None:
                     continue
@@ -580,7 +589,7 @@
         for x in self:
             result += "  " + vertex_key(x) + " [ label = \" \", texlbl = \"$"+quoted_latex(x)+"$\" ];\n"
         for x in self:
-            for i in self.index_set:
+            for i in self.index_set():
                 child = x.f(i)
                 if child is None:
                     continue
@@ -623,7 +632,7 @@
             sage: C(1).index_set()
             [1, 2, 3, 4, 5]
         """
-        return self._parent.index_set
+        return self._parent.index_set()
 
     def weight(self):
         """
@@ -843,7 +852,7 @@
             return
 
         # Run through the children y of x
-        for i in self._crystal.index_set: 
+        for i in self._crystal.index_set(): 
             y = x.f(i)
             if y is None:
                 continue
@@ -985,9 +994,3 @@
         return sum(self.weight_lattice_realization().weyl_dimension(x.weight())
                    for x in self.highest_weight_vectors())
 
-
-class AffineCrystal(Crystal):
-    r"""
-    The abstract class of affine crystals
-    """
-    pass
diff -r 7820ee1d3457 -r d65d5b2798ad sage/combinat/crystals/fast_crystals.py
--- a/sage/combinat/crystals/fast_crystals.py	Wed Apr 08 11:02:42 2009 -0700
+++ b/sage/combinat/crystals/fast_crystals.py	Wed Apr 08 23:55:29 2009 -0700
@@ -140,7 +140,6 @@
             l1_str = "%d/2"%int(2*l1)
             l2_str = "%d/2"%int(2*l2)
         self._name = "The fast crystal for %s2 with shape [%s,%s]"%(ct[0],l1_str,l2_str)
-        self.index_set = self.cartan_type.index_set()
         self.module_generators = [self(0)]
         self._list = ClassicalCrystal.list(self)
         self._digraph = ClassicalCrystal.digraph(self)
diff -r 7820ee1d3457 -r d65d5b2798ad sage/combinat/crystals/letters.py
--- a/sage/combinat/crystals/letters.py	Wed Apr 08 11:02:42 2009 -0700
+++ b/sage/combinat/crystals/letters.py	Wed Apr 08 23:55:29 2009 -0700
@@ -101,7 +101,6 @@
         """
         self.cartan_type = CartanType(cartan_type)
         self._name = "The crystal of letters for type %s"%cartan_type
-        self.index_set = self.cartan_type.index_set()
         self.element_class = element_class
         self.module_generators = [self(1)]
         self._list = ClassicalCrystal.list(self)
@@ -127,7 +126,6 @@
         else: # Should do sanity checks!
             return self.element_class(self, value)
 
-
     def list(self):
         """
         Returns a list of the elements of self.
@@ -164,10 +162,10 @@
         """
         return x in self._list
 
-    def cmp_elements(self, x, y):
+    def lt_elements(self, x, y):
         r"""
         Returns True if and only if there is a path from x to y in the
-        crystal graph.
+        crystal graph, when x is not equal to y.
         
         Because the crystal graph is classical, it is a directed acyclic
         graph which can be interpreted as a poset. This function implements
@@ -178,22 +176,22 @@
             sage: C = CrystalOfLetters(['A', 5])
             sage: x = C(1)
             sage: y = C(2)
-            sage: C.cmp_elements(x,y)
-            -1
-            sage: C.cmp_elements(y,x)
-            1
-            sage: C.cmp_elements(x,x)
-            0
+            sage: C.lt_elements(x,y)
+            True
+            sage: C.lt_elements(y,x)
+            False
+            sage: C.lt_elements(x,x)
+            False
+	    sage: C = CrystalOfLetters(['D', 4])
+	    sage: C.lt_elements(C(4),C(-4))
+	    False
+	    sage: C.lt_elements(C(-4),C(4))
+	    False
         """
         assert x.parent() == self and y.parent() == self
         if self._digraph_closure.has_edge(x,y):
-            return -1
-        elif self._digraph_closure.has_edge(y,x):
-            return 1
-        else:
-            return 0
- 
-    # TODO: cmp, in, ...
+            return True
+	return False
 
 # Utility. Note: much of this class should be factored out at some point!
 class Letter(Element):
@@ -257,25 +255,95 @@
                self.parent() == other.parent() and \
                self.value == other.value
 
-    def __cmp__(self, other):
+    def __ne__(self, other):
+	"""
+	EXAMPLES::
+
+	    sage: C = CrystalOfLetters(['B', 3])
+	    sage: C(0) <> C(0)
+	    False
+	    sage: C(1) <> C(-1)
+	    True
         """
-        EXAMPLES::
-        
-            sage: C = CrystalOfLetters(['A', 5])
-            sage: C(1) < C(2)
-            True
-            sage: C(2) < C(1)
-            False
-            sage: C(2) > C(1)
-            True
-            sage: C(1) <= C(1)
-            True
+	return not self == other
+    
+    def __lt__(self, other):
+	"""
+	EXAMPLES::
+
+	    sage: C = CrystalOfLetters(['D', 4])
+	    sage: C(-4) < C(4)
+	    False
+	    sage: C(4) < C(-3)
+	    True
+	    sage: C(4) < C(4)
+	    False
         """
-        if type(self) is not type(other):
-            return cmp(type(self), type(other))
-        if self.parent() != other.parent():
-            return cmp(self.parent(), other.parent())
-        return self.parent().cmp_elements(self, other)
+	return self.parent().lt_elements(self, other)
+
+    def __gt__(self, other):
+	"""
+	EXAMPLES::
+
+	    sage: C = CrystalOfLetters(['D', 4])
+	    sage: C(-4) > C(4)
+	    False
+	    sage: C(4) > C(-3)
+	    False
+	    sage: C(4) < C(4)
+	    False
+	    sage: C(-1) > C(1)
+	    True
+        """
+	return other.__lt__(self)
+
+    def __le__(self, other):
+	"""
+	EXAMPLES::
+	    
+	    sage: C = CrystalOfLetters(['D', 4])
+	    sage: C(-4) <= C(4)
+	    False
+	    sage: C(4) <= C(-3)
+	    True
+	    sage: C(4) <= C(4)
+	    True
+        """
+	return self.__lt__(other) or self == other
+
+    def __ge__(self, other):
+	"""
+	EXAMPLES::
+	    
+	    sage: C = CrystalOfLetters(['D', 4])
+	    sage: C(-4) >= C(4)
+	    False
+	    sage: C(4) >= C(-3)
+	    False
+	    sage: C(4) >= C(4)
+	    True
+        """
+	return other.__le__(self)
+
+#    def __cmp__(self, other):
+#        """
+#        EXAMPLES::
+#        
+#            sage: C = CrystalOfLetters(['A', 5])
+#            sage: C(1) < C(2)
+#            True
+#            sage: C(2) < C(1)
+#            False
+#            sage: C(2) > C(1)
+#            True
+#            sage: C(1) <= C(1)
+#            True
+#        """
+#        if type(self) is not type(other):
+#            return cmp(type(self), type(other))
+#        if self.parent() != other.parent():
+#            return cmp(self.parent(), other.parent())
+#        return self.parent().cmp_elements(self, other)
 
 #########################
 # Type A
@@ -326,7 +394,7 @@
         EXAMPLES::
         
             sage: C = CrystalOfLetters(['A',4])
-            sage: [[c,i,c.e(i)] for i in C.index_set for c in C if c.e(i) is not None]
+            sage: [[c,i,c.e(i)] for i in C.index_set() for c in C if c.e(i) is not None]
             [[2, 1, 1], [3, 2, 2], [4, 3, 3], [5, 4, 4]]
         """
         assert i in self.index_set()
@@ -342,7 +410,7 @@
         EXAMPLES::
         
             sage: C = CrystalOfLetters(['A',4])
-            sage: [[c,i,c.f(i)] for i in C.index_set for c in C if c.f(i) is not None]
+            sage: [[c,i,c.f(i)] for i in C.index_set() for c in C if c.f(i) is not None]
             [[1, 1, 2], [2, 2, 3], [3, 3, 4], [4, 4, 5]]
         """
         assert i in self.index_set()
@@ -395,7 +463,7 @@
         EXAMPLES::
         
             sage: C = CrystalOfLetters(['B',4])
-            sage: [[c,i,c.e(i)] for i in C.index_set for c in C if c.e(i) is not None]
+            sage: [[c,i,c.e(i)] for i in C.index_set() for c in C if c.e(i) is not None]
             [[2, 1, 1],
              [-1, 1, -2],
              [3, 2, 2],
@@ -425,7 +493,7 @@
         EXAMPLES::
         
             sage: C = CrystalOfLetters(['B',4])
-            sage: [[c,i,c.f(i)] for i in C.index_set for c in C if c.f(i) is not None]
+            sage: [[c,i,c.f(i)] for i in C.index_set() for c in C if c.f(i) is not None]
             [[1, 1, 2],
              [-2, 1, -1],
              [2, 2, 3],
@@ -495,7 +563,7 @@
         EXAMPLES::
         
             sage: C = CrystalOfLetters(['C',4])
-            sage: [[c,i,c.e(i)] for i in C.index_set for c in C if c.e(i) is not None]
+            sage: [[c,i,c.e(i)] for i in C.index_set() for c in C if c.e(i) is not None]
             [[2, 1, 1],
              [-1, 1, -2],
              [3, 2, 2],
@@ -519,7 +587,7 @@
         EXAMPLES::
         
             sage: C = CrystalOfLetters(['C',4])
-            sage: [[c,i,c.f(i)] for i in C.index_set for c in C if c.f(i) is not None]
+            sage: [[c,i,c.f(i)] for i in C.index_set() for c in C if c.f(i) is not None]
             [[1, 1, 2],
              [-2, 1, -1],
              [2, 2, 3],
@@ -583,7 +651,7 @@
         EXAMPLES::
         
             sage: C = CrystalOfLetters(['D',5])
-            sage: [[c,i,c.e(i)] for i in C.index_set for c in C if c.e(i) is not None]
+            sage: [[c,i,c.e(i)] for i in C.index_set() for c in C if c.e(i) is not None]
             [[2, 1, 1],
              [-1, 1, -2],
              [3, 2, 2],
@@ -617,7 +685,7 @@
         EXAMPLES::
         
             sage: C = CrystalOfLetters(['D',5])
-            sage: [[c,i,c.f(i)] for i in C.index_set for c in C if c.f(i) is not None]
+            sage: [[c,i,c.f(i)] for i in C.index_set() for c in C if c.f(i) is not None]
             [[1, 1, 2],
              [-2, 1, -1],
              [2, 2, 3],
@@ -692,7 +760,7 @@
         EXAMPLES::
         
             sage: C = CrystalOfLetters(['G',2])
-            sage: [[c,i,c.e(i)] for i in C.index_set for c in C if c.e(i) is not None]
+            sage: [[c,i,c.e(i)] for i in C.index_set() for c in C if c.e(i) is not None]
             [[2, 1, 1],
              [0, 1, 3],
              [-3, 1, 0],
@@ -727,7 +795,7 @@
         EXAMPLES::
         
             sage: C = CrystalOfLetters(['G',2])
-            sage: [[c,i,c.f(i)] for i in C.index_set for c in C if c.f(i) is not None]
+            sage: [[c,i,c.f(i)] for i in C.index_set() for c in C if c.f(i) is not None]
             [[1, 1, 2],
              [3, 1, 0],
              [0, 1, -3],
diff -r 7820ee1d3457 -r d65d5b2798ad sage/combinat/crystals/spins.py
--- a/sage/combinat/crystals/spins.py	Wed Apr 08 11:02:42 2009 -0700
+++ b/sage/combinat/crystals/spins.py	Wed Apr 08 23:55:29 2009 -0700
@@ -196,7 +196,6 @@
         else:
             self._name = "The minus crystal of spins for type %s"%ct
             
-        self.index_set = self.cartan_type.index_set()
         self.element_class = element_class
         if case == "minus":
             generator = [1]*(ct[1]-1)
diff -r 7820ee1d3457 -r d65d5b2798ad sage/combinat/crystals/tensor_product.py
--- a/sage/combinat/crystals/tensor_product.py	Wed Apr 08 11:02:42 2009 -0700
+++ b/sage/combinat/crystals/tensor_product.py	Wed Apr 08 23:55:29 2009 -0700
@@ -18,12 +18,14 @@
 #****************************************************************************
 
 from sage.misc.latex import latex
+from sage.misc.cachefunc import cached_method
 from sage.structure.element import Element
 from sage.combinat.root_system.cartan_type import CartanType
 from sage.combinat.cartesian_product import CartesianProduct
 from sage.combinat.combinat import CombinatorialObject
-from sage.combinat.partition import Partition
+from sage.combinat.partition import Partition, Partitions
 from sage.combinat.tableau import Tableau
+from sage.combinat.tableau import Tableau_class
 from crystals import CrystalElement, ClassicalCrystal, Crystal
 from letters import CrystalOfLetters
 from sage.misc.flatten import flatten
@@ -169,88 +171,89 @@
 
 def TensorProductOfCrystals(*crystals, **options):
     r"""
-Tensor product of crystals.
+    Tensor product of crystals.
 
-Given two crystals `B` and `B'` of the same type,
-one can form the tensor product `B \otimes B'`. As a set
-`B \otimes B'` is the Cartesian product
-`B \times B'`. The crystal operators `f_i` and
-`e_i` act on `b \otimes b' \in B \otimes B'` as
-follows:
+    Given two crystals `B` and `B'` of the same type,
+    one can form the tensor product `B \otimes B'`. As a set
+    `B \otimes B'` is the Cartesian product
+    `B \times B'`. The crystal operators `f_i` and
+    `e_i` act on `b \otimes b' \in B \otimes B'` as
+    follows:
 
-.. math::
+    .. math::
 
     f_i(b \otimes b') = \begin{cases}
     f_i(b) \otimes b' & \text{if $\varepsilon_i(b) \ge \varphi_i(b')$}\\
     b \otimes f_i(b') & \text{otherwise}
     \end{cases}
 
-and
+    and
 
-.. math::
+    .. math::
 
     e_i(b \otimes b') = \begin{cases}
     b \otimes e_i(b') & \text{if $\varepsilon_i(b) \le \varphi_i(b')$}\\
     e_i(b) \otimes b' & \text{otherwise.}
     \end{cases}
 
-Note that this is the opposite of Kashiwara's convention for tensor
-products of crystals.
+    Note that this is the opposite of Kashiwara's convention for tensor
+    products of crystals.
 
-EXAMPLES: We construct the type `A_2`-crystal generated by
-`2 \otimes 1 \otimes 1`::
+    EXAMPLES: 
 
-    sage: C = CrystalOfLetters(['A',2])
-    sage: T = TensorProductOfCrystals(C,C,C,generators=[[C(2),C(1),C(1)]])
+    We construct the type `A_2`-crystal generated by `2 \otimes 1 \otimes 1`::
 
-It has `8` elements
+        sage: C = CrystalOfLetters(['A',2])
+        sage: T = TensorProductOfCrystals(C,C,C,generators=[[C(2),C(1),C(1)]])
 
-::
+    It has `8` elements
 
-    sage: T.list()
-    [[2, 1, 1], [2, 1, 2], [2, 1, 3], [3, 1, 3], [3, 2, 3], [3, 1, 1], [3, 1, 2], [3, 2, 2]]
+    ::
 
-::
+        sage: T.list()
+	[[2, 1, 1], [2, 1, 2], [2, 1, 3], [3, 1, 3], [3, 2, 3], [3, 1, 1], [3, 1, 2], [3, 2, 2]]
 
-    sage: C = CrystalOfTableaux(['A',3], shape=[1,1,0])
-    sage: D = CrystalOfTableaux(['A',3], shape=[1,0,0])
-    sage: T = TensorProductOfCrystals(C,D, generators=[[C(rows=[[1], [2]]), D(rows=[[1]])], [C(rows=[[2], [3]]), D(rows=[[1]])]])
-    sage: T.cardinality()
-    24
-    sage: T.check()
-    True
-    sage: T.module_generators
-    [[[[1], [2]], [[1]]], [[[2], [3]], [[1]]]]
-    sage: [x.weight() for x in T.module_generators]
-    [(2, 1, 0, 0), (1, 1, 1, 0)]
+    ::
 
-If no module generators are specified, we obtain the full tensor
-product::
+        sage: C = CrystalOfTableaux(['A',3], shape=[1,1,0])
+	sage: D = CrystalOfTableaux(['A',3], shape=[1,0,0])
+	sage: T = TensorProductOfCrystals(C,D, generators=[[C(rows=[[1], [2]]), D(rows=[[1]])], [C(rows=[[2], [3]]), D(rows=[[1]])]])
+	sage: T.cardinality()
+	24
+	sage: T.check()
+	True
+	sage: T.module_generators
+	[[[[1], [2]], [[1]]], [[[2], [3]], [[1]]]]
+	sage: [x.weight() for x in T.module_generators]
+	[(2, 1, 0, 0), (1, 1, 1, 0)]
 
-    sage: C=CrystalOfLetters(['A',2])
-    sage: T=TensorProductOfCrystals(C,C)
-    sage: T.list()
-    [[1, 1], [1, 2], [1, 3], [2, 1], [2, 2], [2, 3], [3, 1], [3, 2], [3, 3]]
-    sage: T.cardinality()
-    9
+    If no module generators are specified, we obtain the full tensor
+    product::
 
-For a tensor product of crystals without module generators, the
-default implementation of module_generators contains all elements
-in the tensor product of the crystals. If there is a subset of
-elements in the tensor product that still generates the crystal,
-this needs to be implemented for the specific crystal separately::
+        sage: C=CrystalOfLetters(['A',2])
+	sage: T=TensorProductOfCrystals(C,C)
+	sage: T.list()
+	[[1, 1], [1, 2], [1, 3], [2, 1], [2, 2], [2, 3], [3, 1], [3, 2], [3, 3]]
+	sage: T.cardinality()
+	9
 
-    sage: T.module_generators.list()
-    [[1, 1], [1, 2], [1, 3], [2, 1], [2, 2], [2, 3], [3, 1], [3, 2], [3, 3]]
+    For a tensor product of crystals without module generators, the
+    default implementation of module_generators contains all elements
+    in the tensor product of the crystals. If there is a subset of
+    elements in the tensor product that still generates the crystal,
+    this needs to be implemented for the specific crystal separately::
 
-For classical highest weight crystals, it is also possible to list
-all highest weight elements::
+        sage: T.module_generators.list()
+	[[1, 1], [1, 2], [1, 3], [2, 1], [2, 2], [2, 3], [3, 1], [3, 2], [3, 3]]
 
-    sage: C = CrystalOfLetters(['A',2])
-    sage: T = TensorProductOfCrystals(C,C,C,generators=[[C(2),C(1),C(1)],[C(1),C(2),C(1)]])
-    sage: T.highest_weight_vectors()
-    [[2, 1, 1], [1, 2, 1]]
-"""
+    For classical highest weight crystals, it is also possible to list
+    all highest weight elements::
+
+        sage: C = CrystalOfLetters(['A',2])
+	sage: T = TensorProductOfCrystals(C,C,C,generators=[[C(2),C(1),C(1)],[C(1),C(2),C(1)]])
+	sage: T.highest_weight_vectors()
+	[[2, 1, 1], [1, 2, 1]]
+    """
     if options.has_key('generators'):
         if all(isinstance(crystal,ClassicalCrystal) for crystal in crystals):
             return TensorProductOfClassicalCrystalsWithGenerators(generators=options['generators'], *crystals)
@@ -262,7 +265,32 @@
         else: 
             return FullTensorProductOfCrystals(*crystals)
 
-class TensorProductOfCrystalsWithGenerators(Crystal):
+
+class CrystalOfWords(Crystal):
+    """
+    Auxiliary class to provide a call method to create tensor product elements.
+    This class is shared with several tensor product classes and is also used in CrystalOfTableaux to allow
+    tableaux of different tensor product structures in column-reading (and hence different shapes)
+    to be considered elements in the same crystal.
+    """
+    def __call__(self, *crystalElements):
+        """
+        EXAMPLES::
+        
+            sage: C = CrystalOfLetters(['A',2])
+            sage: T = TensorProductOfCrystals(C,C)
+            sage: T(1,1)
+            [1, 1]
+            sage: _.parent()
+            Full tensor product of the crystals [The crystal of letters for type ['A', 2], The crystal of letters for type ['A', 2]]
+            sage: T = TensorProductOfCrystals(C,C,C,generators=[[C(2),C(1),C(1)]])
+            sage: T(C(2), C(1), C(1))
+            [2, 1, 1]
+        """
+        return TensorProductOfCrystalsElement(self, list(crystalElements))
+
+
+class TensorProductOfCrystalsWithGenerators(CrystalOfWords):
     def __init__(self, *crystals, **options):
         """
         EXAMPLES::
@@ -272,7 +300,7 @@
             sage: T == loads(dumps(T))
             True
         """
-        crystals = [ crystal for crystal in crystals]
+	crystals = [ crystal for crystal in crystals]
         self._name = "The tensor product of the crystals %s"%crystals
         self.crystals = crystals
         if options.has_key('cartan_type'):
@@ -282,25 +310,14 @@
                 raise ValueError, "you need to specify the Cartan type if the tensor product list is empty"
             else:
                 self.cartan_type = crystals[0].cartan_type
-        self.index_set = self.cartan_type.index_set()
+#        self.index_set = self.cartan_type.index_set()
         self.module_generators = [ self(*x) for x in options['generators']]
 
-    def __call__(self, *args):
-        """
-        EXAMPLES::
-        
-            sage: C = CrystalOfLetters(['A',2])
-            sage: T = TensorProductOfCrystals(C,C,C,generators=[[C(2),C(1),C(1)]])
-            sage: T(C(2), C(1), C(1))
-            [2, 1, 1]
-        """
-        return TensorProductOfCrystalsElement(self,
-                                              [crystalElement for crystalElement in args])
 
 class TensorProductOfClassicalCrystalsWithGenerators(TensorProductOfCrystalsWithGenerators, ClassicalCrystal):
     pass
 
-class FullTensorProductOfCrystals(Crystal):
+class FullTensorProductOfCrystals(CrystalOfWords):
     def __init__(self, *crystals, **options):
         """
         TESTS::
@@ -323,7 +340,6 @@
                 raise ValueError, "you need to specify the Cartan type if the tensor product list is empty"
             else:
                 self.cartan_type = crystals[0].cartan_type
-            self.index_set = self.cartan_type.index_set()
         self.cartesian_product = CartesianProduct(*self.crystals)
         self.module_generators = self
 
@@ -354,19 +370,6 @@
         """
         return self.cartesian_product.cardinality()
 
-    def __call__(self, *crystalElements):
-        """
-        EXAMPLES::
-        
-            sage: C = CrystalOfLetters(['A',2])
-            sage: T = TensorProductOfCrystals(C,C)
-            sage: T(1,1)
-            [1, 1]
-            sage: _.parent()
-            Full tensor product of the crystals [The crystal of letters for type ['A', 2], The crystal of letters for type ['A', 2]]
-        """
-        return TensorProductOfCrystalsElement(self, list(crystalElements))
-
 
 class FullTensorProductOfClassicalCrystals(FullTensorProductOfCrystals, ClassicalCrystal):
     pass
@@ -434,9 +437,7 @@
 
     def phi(self, i):
         """
-        EXAMPLES
-        
-        ::
+        EXAMPLES::
         
             sage: C = CrystalOfLetters(['A',5])
             sage: T = TensorProductOfCrystals(C,C)
@@ -460,9 +461,7 @@
     
     def epsilon(self, i):
         """
-        EXAMPLES
-        
-        ::
+        EXAMPLES::
         
             sage: C = CrystalOfLetters(['A',5])
             sage: T = TensorProductOfCrystals(C,C)
@@ -533,7 +532,7 @@
         l.reverse()
         return [len(self)-1-l[j] for j in range(len(l))]
 	
-class CrystalOfTableaux(TensorProductOfCrystalsWithGenerators, ClassicalCrystal):
+class CrystalOfTableaux(CrystalOfWords, ClassicalCrystal):
     r"""
     Crystals of tableaux. Input: a Cartan Type type and "shape", a
     partition of length <= type[1]. Produces a classical crystal with
@@ -558,13 +557,11 @@
     convention, the tensor product of crystals is the same as the
     monoid operation on tableaux and hence the plactic monoid.
     
-    EXAMPLES:
+    EXAMPLES::
     
     We create the crystal of tableaux for type `A_2`, with
     highest weight given by the partition [2,1,1].
     
-    ::
-    
         sage: Tab = CrystalOfTableaux(['A',3], shape = [2,1,1])
     
     Here is the list of its elements::
@@ -616,14 +613,23 @@
     
     Base cases::
     
-        sage: Tab = CrystalOfTableaux(['A',2], shape = [])
-        sage: Tab.list()
+        sage: T = CrystalOfTableaux(['A',2], shape = [])
+        sage: T.list()
         [[]]
-        sage: Tab = CrystalOfTableaux(['C',2], shape = [1])
-        sage: Tab.check()
+        sage: T = CrystalOfTableaux(['C',2], shape = [1])
+        sage: T.check()
         True
-        sage: Tab.list()
+        sage: T.list()
         [[[1]], [[2]], [[-2]], [[-1]]]
+	sage: T = CrystalOfTableaux(['A',2], shapes = [[],[1],[2]])
+	sage: T.list()
+	[[], [[1]], [[2]], [[3]], [[1, 1]], [[1, 2]], [[2, 2]], [[1, 3]], [[2, 3]], [[3, 3]]]
+	sage: T.module_generators
+	([], [[1]], [[1, 1]])
+	sage: T = CrystalOfTableaux(['B',2],shape=[3]) 
+	sage: T(rows=[[1,1,0]])
+	[[1, 1, 0]]
+
     
     Input tests::
     
@@ -650,8 +656,18 @@
         35
         sage: C.check()
         True
+
+    The next example checks whether a given tableau is in fact a valid type C tableau or not:
+
+        sage: T = CrystalOfTableaux(['C',3], shape = [2,2,2])
+	sage: t = T(rows=[[1,3],[2,-3],[3,-1]]) 
+	sage: t in T.list()
+	True
+	sage: t = T(rows=[[2,3],[3,-3],[-3,-2]]) 
+	sage: t in T.list()
+	False
     """
-    def __init__(self, type, shape):
+    def __init__(self, type, shape = None, shapes = None):
         """
         EXAMPLES::
         
@@ -660,30 +676,45 @@
             True
         """
         self.letters = CrystalOfLetters(type)
-        if type[0] == 'D' and len(shape) == type[1] and shape[type[1]-1] < 0:
-            invert = True
-            shape[type[1]-1]=-shape[type[1]-1]
-        else:
-            invert = False
-        shape = Partition(shape)
-        if not all(shape[i] <= shape[i-1] for i in range(1,len(shape))):
-            raise ValueError, "shape must be a partition"
-        p = shape.conjugate()
-        # The column canonical tableau, read by columns
-        module_generator = flatten([[p[j]-i for i in range(p[j])] for j in range(len(p))])
-        if invert:
-            for i in range(type[1]):
-                if module_generator[i] == type[1]:
-                    module_generator[i] = -type[1]
-        module_generator=[self.letters(x) for x in module_generator]
-        TensorProductOfCrystalsWithGenerators.__init__(self, *[self.letters]*shape.size(), 
-						       **{'generators':[module_generator],'cartan_type':type})
-        self._name = "The crystal of tableaux of type %s and shape %s"%(type, str(shape))
-        self.shape = shape
+	self.cartan_type = self.letters.cartan_type
+	if shape is not None:
+	    assert shapes is None
+	    shapes = (shape,)
+	assert shapes is not None
+	CrystalOfWords.__init__(self)
+	module_generators = tuple(self.module_generator(la) for la in shapes)
+        self.module_generators = module_generators
+        self._name = "The crystal of tableaux of type %s and shape(s) %s"%(type, str(shapes))
+
+    def module_generator(self, shape):
+	"""
+	This yields the module generator (or highest weight element) of a classical
+	crystal of given shape. The module generator is the unique tableau with equal
+	shape and content.
+	
+	EXAMPLE:
+	    sage: T = CrystalOfTableaux(['D',3], shape = [1,1])
+	    sage: T.module_generator([1,1])
+	    [[1], [2]]
+	"""
+	type = self.cartan_type
+	if type[0] == 'D' and len(shape) == type[1] and shape[type[1]-1] < 0:
+	    invert = True
+	    shape[type[1]-1]=-shape[type[1]-1]
+	else:
+	    invert = False
+	p = Partition(shape).conjugate()
+	# The column canonical tableau, read by columns
+	module_generator = flatten([[p[j]-i for i in range(p[j])] for j in range(len(p))])
+	if invert:
+	    for i in range(type[1]):
+		if module_generator[i] == type[1]:
+		    module_generator[i] = -type[1]
+	return self(*[self.letters(x) for x in module_generator])
 
     def __call__(self, *args, **options):
         """
-        Returns a CrystalofTableauxElement
+        Returns a CrystalOfTableauxElement
         
         EXAMPLES::
         
@@ -705,16 +736,24 @@
             sage: t == loads(dumps(t))
             True
         """
-        if len(args) == 1 and isinstance(args[0], CrystalOfTableauxElement):
-            if args[0].parent() == parent:
-                return args[0]
-            else:
-                raise ValueError, "Inconsistent parent"
-        if options.has_key('list'):
-            list = options['list']
+        if len(args) == 1:
+	    if isinstance(args[0], CrystalOfTableauxElement):
+		if args[0].parent() == parent:
+		    return args[0]
+		else:
+		    raise ValueError, "Inconsistent parent"
+	    elif isinstance(args[0], Tableau_class):
+		options['rows'] = args[0] 
+	if options.has_key('list'):
+	    list = options['list']
         elif options.has_key('rows'):
             rows=options['rows']
-            list=Tableau(rows).to_word_by_column()
+#            list=Tableau(rows).to_word_by_column()
+	    rows=Tableau(rows).conjugate()
+	    list=[]
+	    for col in rows:
+		col.reverse()
+		list+=col
         elif options.has_key('columns'):
             columns=options['columns']
             list=[]
@@ -756,6 +795,7 @@
         """
         return latex(self.to_tableau())
 
+    @cached_method
     def to_tableau(self):
         """
         Returns the Tableau object corresponding to self.
@@ -769,21 +809,21 @@
             <class 'sage.combinat.tableau.Tableau_class'>
             sage: type(t[0][0])
             <type 'sage.rings.integer.Integer'>
+	    sage: T = CrystalOfTableaux(['D',3], shape = [1,1])
+	    sage: t=T(rows=[[-3],[3]]).to_tableau(); t
+	    [[-3], [3]]
+	    sage: t=T(rows=[[3],[-3]]).to_tableau(); t
+	    [[3], [-3]]
         """
-        try:
-            return self._tableau
-        except AttributeError:
-            pass
-        
-        shape = self.parent().shape.conjugate()
-        tab = []
-        s = 0
-        for i in range(len(shape)):
-            col = [ self[s+k].value for k in range(shape[i]) ]
-            col.reverse()
-            s += shape[i]
-            tab.append(col)
-        tab = Tableau(tab)
-        self._tableau = tab.conjugate()
-        return self._tableau
-
+	if self._list == []:
+	    return Tableau([])
+	tab = [ [self[0].value] ]
+	for i in range(1,len(self)):
+	    if self[i-1] <= self[i]:
+		tab.append([self[i].value])
+	    else:
+		l = len(tab)-1
+		tab[l].append(self[i].value)
+	for x in tab:
+	    x.reverse()
+	return Tableau(tab).conjugate()
diff -r 7820ee1d3457 -r d65d5b2798ad sage/combinat/partition.py
--- a/sage/combinat/partition.py	Wed Apr 08 11:02:42 2009 -0700
+++ b/sage/combinat/partition.py	Wed Apr 08 23:55:29 2009 -0700
@@ -1393,8 +1393,12 @@
             [[0, 2], [2, 0]]
             sage: Partition([6,3,3,1,1,1]).outside_corners() 
             [[0, 6], [1, 3], [3, 1], [6, 0]]
-        """
-        p = self
+	    sage: Partition([]).outside_corners()
+	    [[0, 0]]
+        """
+        p = self
+	if p == Partition([]):
+	    return [[0,0]]
         res = [ [0, p[0]] ]        
         for i in range(1, len(p)):
             if p[i-1] != p[i]:
