Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
r""" Representations of the Symmetric Group
.. TODO::
- construct the product of two irreducible representations.
- implement Induction/Restriction of representations.
.. WARNING::
This code uses a different convention than in Sagan's book "The Symmetric Group"
""" #***************************************************************************** # Copyright (C) 2009 Franco Saliola <saliola@gmail.com> # # Distributed under the terms of the GNU General Public License (GPL) # # This code is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # The full text of the GPL is available at: # # http://www.gnu.org/licenses/ #***************************************************************************** from __future__ import print_function import six from six.moves import range
from sage.symbolic.ring import SR from sage.functions.all import sqrt from sage.combinat.combinat import CombinatorialClass from sage.combinat.partition import Partition, Partitions from sage.combinat.permutation import Permutation, Permutations from sage.combinat.tableau import StandardTableaux, Tableau from sage.combinat.yang_baxter_graph import YangBaxterGraph_partition from sage.groups.perm_gps.permgroup_element import PermutationGroupElement from sage.matrix.constructor import matrix from sage.misc.cachefunc import cached_method from sage.misc.lazy_attribute import lazy_attribute from sage.rings.integer_ring import ZZ from sage.rings.rational_field import QQ from sage.structure.sage_object import SageObject
##### Constructor function ################################################
def SymmetricGroupRepresentation(partition, implementation="specht", ring=None, cache_matrices=True): r""" The irreducible representation of the symmetric group corresponding to ``partition``.
INPUT:
- ``partition`` -- a partition of a positive integer
- ``implementation`` -- string (default: ``"specht"``), one of: - ``"seminormal"`` - for Young's seminormal representation - ``"orthogonal"`` - for Young's orthogonal representation - ``"specht"`` - for Specht's representation
- ``ring`` -- the ring over which the representation is defined.
- ``cache_matrices`` -- boolean (default: ``True``) if ``True``, then any representation matrices that are computed are cached.
EXAMPLES:
Young's orthogonal representation: the matrices are orthogonal.
::
sage: orth = SymmetricGroupRepresentation([2,1], "orthogonal"); orth Orthogonal representation of the symmetric group corresponding to [2, 1] sage: all(a*a.transpose() == a.parent().identity_matrix() for a in orth) True
::
sage: orth = SymmetricGroupRepresentation([3,2], "orthogonal"); orth Orthogonal representation of the symmetric group corresponding to [3, 2] sage: orth([2,1,3,4,5]) [ 1 0 0 0 0] [ 0 1 0 0 0] [ 0 0 -1 0 0] [ 0 0 0 1 0] [ 0 0 0 0 -1] sage: orth([1,3,2,4,5]) [ 1 0 0 0 0] [ 0 -1/2 1/2*sqrt(3) 0 0] [ 0 1/2*sqrt(3) 1/2 0 0] [ 0 0 0 -1/2 1/2*sqrt(3)] [ 0 0 0 1/2*sqrt(3) 1/2] sage: orth([1,2,4,3,5]) [ -1/3 2/3*sqrt(2) 0 0 0] [2/3*sqrt(2) 1/3 0 0 0] [ 0 0 1 0 0] [ 0 0 0 1 0] [ 0 0 0 0 -1]
The Specht Representation::
sage: spc = SymmetricGroupRepresentation([3,2], "specht") sage: spc.scalar_product_matrix(Permutation([1,2,3,4,5])) [ 1 0 0 0 0] [ 0 -1 0 0 0] [ 0 0 1 0 0] [ 0 0 0 1 0] [-1 0 0 0 -1] sage: spc.scalar_product_matrix(Permutation([5,4,3,2,1])) [ 1 -1 0 1 0] [ 0 0 1 0 -1] [ 0 0 0 -1 1] [ 0 1 -1 -1 1] [-1 0 0 0 -1] sage: spc([5,4,3,2,1]) [ 1 -1 0 1 0] [ 0 0 -1 0 1] [ 0 0 0 -1 1] [ 0 1 -1 -1 1] [ 0 1 0 -1 1] sage: spc.verify_representation() True
By default, any representation matrices that are computed are cached::
sage: spc = SymmetricGroupRepresentation([3,2], "specht") sage: spc([5,4,3,2,1]) [ 1 -1 0 1 0] [ 0 0 -1 0 1] [ 0 0 0 -1 1] [ 0 1 -1 -1 1] [ 0 1 0 -1 1] sage: spc._cache__representation_matrix {(([5, 4, 3, 2, 1],), ()): [ 1 -1 0 1 0] [ 0 0 -1 0 1] [ 0 0 0 -1 1] [ 0 1 -1 -1 1] [ 0 1 0 -1 1]}
This can be turned off with the keyword cache_matrices::
sage: spc = SymmetricGroupRepresentation([3,2], "specht", cache_matrices=False) sage: spc([5,4,3,2,1]) [ 1 -1 0 1 0] [ 0 0 -1 0 1] [ 0 0 0 -1 1] [ 0 1 -1 -1 1] [ 0 1 0 -1 1] sage: hasattr(spc, '_cache__representation_matrix') False
.. NOTE::
The implementation is based on the paper [Las]_.
REFERENCES:
.. [Las] Alain Lascoux, 'Young representations of the symmetric group.' http://phalanstere.univ-mlv.fr/~al/ARTICLES/ProcCrac.ps.gz
AUTHORS:
- Franco Saliola (2009-04-23) """ cache_matrices=cache_matrices) cache_matrices=cache_matrices) cache_matrices=cache_matrices) else: raise NotImplementedError("only seminormal, orthogonal and specht are implemented")
def SymmetricGroupRepresentations(n, implementation="specht", ring=None, cache_matrices=True): r""" Irreducible representations of the symmetric group.
INPUT:
- ``n`` -- positive integer
- ``implementation`` -- string (default: ``"specht"``), one of: - ``"seminormal"`` - for Young's seminormal representation - ``"orthogonal"`` - for Young's orthogonal representation - ``"specht"`` - for Specht's representation
- ``ring`` -- the ring over which the representation is defined.
- ``cache_matrices`` -- boolean (default: ``True``) if ``True``, then any representation matrices that are computed are cached.
EXAMPLES:
Young's orthogonal representation: the matrices are orthogonal.
::
sage: orth = SymmetricGroupRepresentations(3, "orthogonal"); orth Orthogonal representations of the symmetric group of order 3! over Symbolic Ring sage: orth.list() [Orthogonal representation of the symmetric group corresponding to [3], Orthogonal representation of the symmetric group corresponding to [2, 1], Orthogonal representation of the symmetric group corresponding to [1, 1, 1]] sage: orth([2,1])([1,2,3]) [1 0] [0 1]
Young's seminormal representation.
::
sage: snorm = SymmetricGroupRepresentations(3, "seminormal"); snorm Seminormal representations of the symmetric group of order 3! over Rational Field sage: sgn = snorm([1,1,1]); sgn Seminormal representation of the symmetric group corresponding to [1, 1, 1] sage: list(map(sgn, Permutations(3))) [[1], [-1], [-1], [1], [1], [-1]]
The Specht Representation.
::
sage: spc = SymmetricGroupRepresentations(5, "specht"); spc Specht representations of the symmetric group of order 5! over Integer Ring sage: spc([3,2])([5,4,3,2,1]) [ 1 -1 0 1 0] [ 0 0 -1 0 1] [ 0 0 0 -1 1] [ 0 1 -1 -1 1] [ 0 1 0 -1 1]
.. NOTE::
The implementation is based on the paper [Las]_.
AUTHORS:
- Franco Saliola (2009-04-23) """ else: raise NotImplementedError("only seminormal, orthogonal and specht are implemented")
##### Generic classes for symmetric group representations #################
class SymmetricGroupRepresentation_generic_class(SageObject): r""" Generic methods for a representation of the symmetric group. """ _default_ring = None
def __init__(self, partition, ring=None, cache_matrices=True): r""" An irreducible representation of the symmetric group corresponding to ``partition``.
For more information, see the documentation for :func:`SymmetricGroupRepresentation`.
EXAMPLES::
sage: spc = SymmetricGroupRepresentation([3]) sage: spc([3,2,1]) [1] sage: spc == loads(dumps(spc)) True
sage: spc = SymmetricGroupRepresentation([3], cache_matrices=False) sage: spc([3,2,1]) [1] sage: spc == loads(dumps(spc)) True """
def __hash__(self): r""" TESTS::
sage: spc1 = SymmetricGroupRepresentation([3], cache_matrices=True) sage: hash(spc1) -1137003014 # 32-bit 3430541866490 # 64-bit """
def __eq__(self, other): r""" Test for equality.
EXAMPLES::
sage: spc1 = SymmetricGroupRepresentation([3], cache_matrices=True) sage: spc1([3,1,2]) [1] sage: spc2 = loads(dumps(spc1)) sage: spc1 == spc2 True
::
sage: spc3 = SymmetricGroupRepresentation([3], cache_matrices=False) sage: spc3([3,1,2]) [1] sage: spc4 = loads(dumps(spc3)) sage: spc3 == spc4 True
TESTS:
The following tests against some bug that was fixed in :trac:`8611`::
sage: spc = SymmetricGroupRepresentation([3]) sage: spc.important_info = 'Sage rules' sage: spc == SymmetricGroupRepresentation([3]) True
""" return False
def __call__(self, permutation): r""" Return the image of ``permutation`` in the representation.
EXAMPLES::
sage: spc = SymmetricGroupRepresentation([2,1]) sage: spc([1,3,2]) [ 1 0] [ 1 -1] """
def __iter__(self): r""" Iterate over the matrices representing the elements of the symmetric group.
EXAMPLES::
sage: spc = SymmetricGroupRepresentation([1,1,1]) sage: list(spc) [[1], [-1], [-1], [1], [1], [-1]] """
def verify_representation(self): r""" Verify the representation: tests that the images of the simple transpositions are involutions and tests that the braid relations hold.
EXAMPLES::
sage: spc = SymmetricGroupRepresentation([1,1,1]) sage: spc.verify_representation() True sage: spc = SymmetricGroupRepresentation([4,2,1]) sage: spc.verify_representation() True """ return False, "si si != 1 for i = %s" % (i,) return False, "si sj != sj si for (i,j) =(%s,%s)" % (i,j) else: return False, "si sj si != sj si sj for (i,j) = (%s,%s)" % (i,j)
def to_character(self): r""" Return the character of the representation.
EXAMPLES:
The trivial character::
sage: rho = SymmetricGroupRepresentation([3]) sage: chi = rho.to_character(); chi Character of Symmetric group of order 3! as a permutation group sage: chi.values() [1, 1, 1] sage: all(chi(g) == 1 for g in SymmetricGroup(3)) True
The sign character::
sage: rho = SymmetricGroupRepresentation([1,1,1]) sage: chi = rho.to_character(); chi Character of Symmetric group of order 3! as a permutation group sage: chi.values() [1, -1, 1] sage: all(chi(g) == g.sign() for g in SymmetricGroup(3)) True
The defining representation::
sage: triv = SymmetricGroupRepresentation([4]) sage: hook = SymmetricGroupRepresentation([3,1]) sage: def_rep = lambda p : triv(p).block_sum(hook(p)).trace() sage: list(map(def_rep, Permutations(4))) [4, 2, 2, 1, 1, 2, 2, 0, 1, 0, 0, 1, 1, 0, 2, 1, 0, 0, 0, 1, 1, 2, 0, 0] sage: [p.to_matrix().trace() for p in Permutations(4)] [4, 2, 2, 1, 1, 2, 2, 0, 1, 0, 0, 1, 1, 0, 2, 1, 0, 0, 0, 1, 1, 2, 0, 0]
"""
class SymmetricGroupRepresentations_class(CombinatorialClass): r""" Generic methods for the CombinatorialClass of irreducible representations of the symmetric group. """ def __init__(self, n, ring=None, cache_matrices=True): r""" Irreducible representations of the symmetric group.
See the documentation for :func:`SymmetricGroupRepresentations` for more information.
EXAMPLES::
sage: snorm = SymmetricGroupRepresentations(3, "seminormal") sage: snorm == loads(dumps(snorm)) True """
def __call__(self, partition): r""" Return the irreducible representation corresponding to partition.
EXAMPLES::
sage: sp = SymmetricGroupRepresentations(3, "specht") sage: sp([1,1,1]) Specht representation of the symmetric group corresponding to [1, 1, 1]
sage: snorm = SymmetricGroupRepresentations(3, "seminormal") sage: snorm([2,1]) Seminormal representation of the symmetric group corresponding to [2, 1] """ raise TypeError("not a partition of %s" % self._n) cache_matrices=self._cache_matrices)
def __iter__(self): r""" Iterate through all the irreducible representations of the symmetric group.
EXAMPLES::
sage: orth = SymmetricGroupRepresentations(3, "orthogonal") sage: for x in orth: print(x) Orthogonal representation of the symmetric group corresponding to [3] Orthogonal representation of the symmetric group corresponding to [2, 1] Orthogonal representation of the symmetric group corresponding to [1, 1, 1] """ cache_matrices=self._cache_matrices)
##### Young's Seminormal Representation ###################################
class YoungRepresentation_generic(SymmetricGroupRepresentation_generic_class): r""" Generic methods for Young's representations of the symmetric group. """ @lazy_attribute def _yang_baxter_graph(self): r""" Return the Yang-Baxter graph associated with the representation, with vertices labelled by the vector of contents of the partition.
EXAMPLES::
sage: orth = SymmetricGroupRepresentation([3,2], "orthogonal") sage: orth._yang_baxter_graph Yang-Baxter graph of [3, 2], with top vertex (0, -1, 2, 1, 0) """ # relabel vertices with "vector of contents" partition_to_vector_of_contents(self._partition, reverse=True)) # relabel edges with "differences"
@lazy_attribute def _tableau_dict(self): r""" A dictionary pairing the vertices of the underlying Yang-Baxter graph with standard tableau.
EXAMPLES::
sage: orth = SymmetricGroupRepresentation([3,2], "orthogonal") sage: orth._tableau_dict {(0, -1, 2, 1, 0): [[1, 2, 3], [4, 5]], (0, 2, -1, 1, 0): [[1, 2, 4], [3, 5]], (0, 2, 1, -1, 0): [[1, 3, 4], [2, 5]], (2, 0, -1, 1, 0): [[1, 2, 5], [3, 4]], (2, 0, 1, -1, 0): [[1, 3, 5], [2, 4]]} """ # construct a dictionary pairing vertices with tableau # TODO: improve the following
@lazy_attribute def _word_dict(self): r""" A dictionary pairing the vertices of the underlying Yang-Baxter graph with words readings of standard tableau.
EXAMPLES::
sage: orth = SymmetricGroupRepresentation([3,2], "orthogonal") sage: orth._word_dict {(0, -1, 2, 1, 0): (4, 5, 1, 2, 3), (0, 2, -1, 1, 0): (3, 5, 1, 2, 4), (0, 2, 1, -1, 0): (2, 5, 1, 3, 4), (2, 0, -1, 1, 0): (3, 4, 1, 2, 5), (2, 0, 1, -1, 0): (2, 4, 1, 3, 5)} """
@cached_method def representation_matrix_for_simple_transposition(self, i): r""" Return the matrix representing the transposition that swaps ``i`` and ``i+1``.
EXAMPLES::
sage: orth = SymmetricGroupRepresentation([2,1], "orthogonal") sage: orth.representation_matrix_for_simple_transposition(1) [ 1 0] [ 0 -1] sage: orth.representation_matrix_for_simple_transposition(2) [ -1/2 1/2*sqrt(3)] [1/2*sqrt(3) 1/2]
sage: norm = SymmetricGroupRepresentation([2,1], "seminormal") sage: norm.representation_matrix_for_simple_transposition(1) [ 1 0] [ 0 -1] sage: norm.representation_matrix_for_simple_transposition(2) [-1/2 3/2] [ 1/2 1/2] """ raise TypeError in digraph.edges() if j != i) else: self._2x2_matrix_entries(beta)
def _representation_matrix_uncached(self, permutation): r""" Return the matrix representing ``permutation``.
EXAMPLES::
sage: orth = SymmetricGroupRepresentation([2,1], "orthogonal") sage: orth._representation_matrix_uncached(Permutation([2,1,3])) [ 1 0] [ 0 -1] sage: orth._representation_matrix_uncached(Permutation([1,3,2])) [ -1/2 1/2*sqrt(3)] [1/2*sqrt(3) 1/2]
::
sage: norm = SymmetricGroupRepresentation([2,1], "seminormal") sage: p = PermutationGroupElement([2,1,3]) sage: norm._representation_matrix_uncached(p) [ 1 0] [ 0 -1] sage: p = PermutationGroupElement([1,3,2]) sage: norm._representation_matrix_uncached(p) [-1/2 3/2] [ 1/2 1/2] """
@cached_method def representation_matrix(self, permutation): r""" Return the matrix representing ``permutation``.
EXAMPLES::
sage: orth = SymmetricGroupRepresentation([2,1], "orthogonal") sage: orth.representation_matrix(Permutation([2,1,3])) [ 1 0] [ 0 -1] sage: orth.representation_matrix(Permutation([1,3,2])) [ -1/2 1/2*sqrt(3)] [1/2*sqrt(3) 1/2]
::
sage: norm = SymmetricGroupRepresentation([2,1], "seminormal") sage: p = PermutationGroupElement([2,1,3]) sage: norm.representation_matrix(p) [ 1 0] [ 0 -1] sage: p = PermutationGroupElement([1,3,2]) sage: norm.representation_matrix(p) [-1/2 3/2] [ 1/2 1/2] """
class YoungRepresentation_Seminormal(YoungRepresentation_generic): _default_ring = QQ
def __repr__(self): r""" String representation of ``self``.
EXAMPLES::
sage: from sage.combinat.symmetric_group_representations import YoungRepresentation_Seminormal sage: YoungRepresentation_Seminormal([2,1]).__repr__() 'Seminormal representation of the symmetric group corresponding to [2, 1]' """
def _2x2_matrix_entries(self, beta): r""" Young's representations are constructed by combining `2\times2`-matrices that depend on ``beta``. For the seminormal representation, this is the following matrix.:
``[ -beta 1+beta ]`` ``[ 1-beta beta ]``
EXAMPLES::
sage: from sage.combinat.symmetric_group_representations import YoungRepresentation_Seminormal sage: snorm = YoungRepresentation_Seminormal([2,1]) sage: snorm._2x2_matrix_entries(1/2) (-1/2, 3/2, 1/2, 1/2) """
class YoungRepresentations_Seminormal(SymmetricGroupRepresentations_class): _default_ring = QQ
object_class = YoungRepresentation_Seminormal
def __repr__(self): r""" String representation of self.
EXAMPLES::
sage: from sage.combinat.symmetric_group_representations import YoungRepresentations_Seminormal sage: YoungRepresentations_Seminormal(3).__repr__() 'Seminormal representations of the symmetric group of order 3! over Rational Field' """
##### Young's Orthogonal Representation ###################################
class YoungRepresentation_Orthogonal(YoungRepresentation_generic): _default_ring = SR
def __repr__(self): r""" String representation of self.
EXAMPLES::
sage: from sage.combinat.symmetric_group_representations import YoungRepresentation_Orthogonal sage: YoungRepresentation_Orthogonal([2,1]).__repr__() 'Orthogonal representation of the symmetric group corresponding to [2, 1]' """
def _2x2_matrix_entries(self, beta): r""" Young's representations are constructed by combining `2\times2`-matrices that depend on ``beta`` For the orthogonal representation, this is the following matrix::
``[ -beta sqrt(1-beta^2) ]`` ``[ sqrt(1-beta^2) beta ]``
EXAMPLES::
sage: from sage.combinat.symmetric_group_representations import YoungRepresentation_Orthogonal sage: orth = YoungRepresentation_Orthogonal([2,1]) sage: orth._2x2_matrix_entries(1/2) (-1/2, 1/2*sqrt(3), 1/2*sqrt(3), 1/2) """
class YoungRepresentations_Orthogonal(SymmetricGroupRepresentations_class): _default_ring = SR
object_class = YoungRepresentation_Orthogonal
def __repr__(self): r""" String representation of ``self``.
EXAMPLES::
sage: from sage.combinat.symmetric_group_representations import YoungRepresentations_Orthogonal sage: YoungRepresentations_Orthogonal(3).__repr__() 'Orthogonal representations of the symmetric group of order 3! over Symbolic Ring' """
##### Specht Representation ###############################################
class SpechtRepresentation(SymmetricGroupRepresentation_generic_class): def __repr__(self): r""" String representation of ``self``.
EXAMPLES::
sage: from sage.combinat.symmetric_group_representations import SpechtRepresentation sage: SpechtRepresentation([2,1]).__repr__() 'Specht representation of the symmetric group corresponding to [2, 1]' """
_default_ring = ZZ
@lazy_attribute def _yang_baxter_graph(self): r""" Construct and cache the underlying Yang-Baxter graph.
EXAMPLES::
sage: rho = SymmetricGroupRepresentation([3,2], 'specht') sage: rho._yang_baxter_graph Yang-Baxter graph of [3, 2], with top vertex (1, 0, 2, 1, 0) """
@lazy_attribute def _dual_vertices(self): r""" Return a list of the dual vertices of the vertices of the underlying Yang-Baxter graph.
EXAMPLES::
sage: spc = SymmetricGroupRepresentation([3,2], 'specht') sage: spc._dual_vertices [(3, 3, 0, 0, 0), (3, 0, 3, 0, 0), (3, 0, 0, 3, 0), (0, 3, 3, 0, 0), (0, 3, 0, 3, 0)] """
@cached_method def scalar_product(self, u, v): r""" Return ``0`` if ``u+v`` is not a permutation, and the signature of the permutation otherwise.
This is the scalar product of a vertex ``u`` of the underlying Yang-Baxter graph with the vertex ``v`` in the 'dual' Yang-Baxter graph.
EXAMPLES::
sage: spc = SymmetricGroupRepresentation([3,2], 'specht') sage: spc.scalar_product((1,0,2,1,0),(0,3,0,3,0)) -1 sage: spc.scalar_product((1,0,2,1,0),(3,0,0,3,0)) 0 """ else:
def scalar_product_matrix(self, permutation=None): r""" Return the scalar product matrix corresponding to ``permutation``.
The entries are given by the scalar products of ``u`` and ``permutation.action(v)``, where ``u`` is a vertex in the underlying Yang-Baxter graph and ``v`` is a vertex in the dual graph.
EXAMPLES::
sage: spc = SymmetricGroupRepresentation([3,1], 'specht') sage: spc.scalar_product_matrix() [ 1 0 0] [ 0 -1 0] [ 0 0 1] """
@lazy_attribute def _scalar_product_matrix_inverse(self): r""" Compute and store the inverse of the scalar product matrix.
EXAMPLES::
sage: spc = SymmetricGroupRepresentation([3,1], 'specht') sage: spc._scalar_product_matrix_inverse [ 1 0 0] [ 0 -1 0] [ 0 0 1] """
@cached_method def representation_matrix(self, permutation): r""" Returns the matrix representing the ``permutation`` in this irreducible representation.
.. NOTE::
This method caches the results.
EXAMPLES::
sage: spc = SymmetricGroupRepresentation([3,1], 'specht') sage: spc.representation_matrix(Permutation([2,1,3,4])) [ 0 -1 0] [-1 0 0] [ 0 0 1] sage: spc.representation_matrix(Permutation([3,2,1,4])) [0 0 1] [0 1 0] [1 0 0] """
def _representation_matrix_uncached(self, permutation): r""" Returns the matrix representing the ``permutation`` in this irreducible representation.
EXAMPLES::
sage: spc = SymmetricGroupRepresentation([3,1], 'specht') sage: spc._representation_matrix_uncached(Permutation([2,1,3,4])) [ 0 -1 0] [-1 0 0] [ 0 0 1] sage: spc._representation_matrix_uncached(Permutation([3,2,1,4])) [0 0 1] [0 1 0] [1 0 0] """
class SpechtRepresentations(SymmetricGroupRepresentations_class): object_class = SpechtRepresentation
_default_ring = ZZ
def __repr__(self): r""" String representation of ``self``.
EXAMPLES::
sage: spc = SymmetricGroupRepresentations(4) sage: spc.__repr__() 'Specht representations of the symmetric group of order 4! over Integer Ring' """
###### Miscellaneous functions ############################################
def partition_to_vector_of_contents(partition, reverse=False): r""" Returns the "vector of contents" associated to ``partition``.
EXAMPLES::
sage: from sage.combinat.symmetric_group_representations import partition_to_vector_of_contents sage: partition_to_vector_of_contents([3,2]) (0, 1, 2, -1, 0) """ |