text: r"""
  Examples of finite Weyl groups
  """
  #*****************************************************************************
  #  Copyright (C) 2008-2009 Nicolas M. Thiery <nthiery at users.sf.net>
  #
  #  Distributed under the terms of the GNU General Public License (GPL)
  #                  http://www.gnu.org/licenses/
  #******************************************************************************
  from six.moves import range
  
  from sage.misc.cachefunc import cached_method
  from sage.structure.parent import Parent
  from sage.structure.element_wrapper import ElementWrapper
  from sage.categories.all import FiniteWeylGroups
  from sage.structure.unique_representation import UniqueRepresentation
  
  class SymmetricGroup(UniqueRepresentation, Parent):
      r"""
      An example of finite Weyl group: the symmetric group, with
      elements in list notation.
  
      The purpose of this class is to provide a minimal template for
      implementing finite Weyl groups. See
      :class:`~sage.groups.perm_gps.permgroup_named.SymmetricGroup` for
      a full featured and optimized implementation.
  
      EXAMPLES::
  
          sage: S = FiniteWeylGroups().example()
          sage: S
          The symmetric group on {0, ..., 3}
          sage: S.category()
          Category of finite weyl groups
  
      The elements of this group are permutations of the set `\{0,\ldots,3\}`::
  
          sage: S.one()
          (0, 1, 2, 3)
          sage: S.an_element()
          (1, 2, 3, 0)
  
      The group itself is generated by the elementary transpositions::
  
          sage: S.simple_reflections()
          Finite family {0: (1, 0, 2, 3), 1: (0, 2, 1, 3), 2: (0, 1, 3, 2)}
  
      Only the following basic operations are implemented:
  
      - :meth:`.one`
      - :meth:`.product`
      - :meth:`.simple_reflection`
      - :meth:`.cartan_type`
      - :meth:`.Element.has_right_descent`.
  
      All the other usual Weyl group operations are inherited from the
      categories::
  
          sage: S.cardinality()
          24
          sage: S.long_element()
          (3, 2, 1, 0)
          sage: S.cayley_graph(side = "left").plot()
          Graphics object consisting of 120 graphics primitives
  
      Alternatively, one could have implemented
      :meth:`sage.categories.coxeter_groups.CoxeterGroups.ElementMethods.apply_simple_reflection`
      instead of :meth:`.simple_reflection` and :meth:`.product`. See
      ``CoxeterGroups().example()``.
  
      TESTS::
  
          sage: TestSuite(S).run()
      """
  
      def __init__(self, n = 4):
          """
          EXAMPLES::
  
              sage: S = sage.categories.examples.finite_weyl_groups.SymmetricGroup(4)
              sage: S == FiniteWeylGroups().example(4)
              True
          """
          Parent.__init__(self, category = FiniteWeylGroups())
          self.n = n
  
      def _repr_(self):
          """
          EXAMPLES::
  
              sage: FiniteWeylGroups().example()
              The symmetric group on {0, ..., 3}
  
          """
          return "The symmetric group on {0, ..., %s}"%(self.n-1)
  
      @cached_method
      def one(self):
          """
          Implements :meth:`Monoids.ParentMethods.one`.
  
          EXAMPLES::
  
              sage: FiniteWeylGroups().example().one()
              (0, 1, 2, 3)
          """
          return self(tuple(range(self.n)))
  
      def index_set(self):
          """
          Implements :meth:`CoxeterGroups.ParentMethods.index_set`.
  
          EXAMPLES::
  
              sage: FiniteWeylGroups().example().index_set()
              [0, 1, 2]
          """
          return list(range(self.n - 1))
  
      def simple_reflection(self, i):
          """
          Implement :meth:`CoxeterGroups.ParentMethods.simple_reflection`
          by returning the transposition `(i, i+1)`.
  
          EXAMPLES::
  
              sage: FiniteWeylGroups().example().simple_reflection(2)
              (0, 1, 3, 2)
          """
          assert i in self.index_set()
          return self(tuple(range(i)) + (i + 1, i) + tuple(range(i + 2, self.n)))
  
      def cartan_type(self):
          """
          Return the Cartan type of ``self``.
  
          EXAMPLES::
  
              sage: FiniteWeylGroups().example().cartan_type()
              ['A', 3] relabelled by {1: 0, 2: 1, 3: 2}
          """
          from sage.combinat.root_system.cartan_type import CartanType
          C = CartanType(['A',self.n-1])
          C = C.relabel(lambda i:i-1)
          return C
  
      def product(self, x, y):
          """
          Implements :meth:`Semigroups.ParentMethods.product`.
  
          EXAMPLES::
  
              sage: s = FiniteWeylGroups().example().simple_reflections()
              sage: s[1] * s[2]
              (0, 2, 3, 1)
              """
          assert x in self
          assert y in self
          return self(tuple(x.value[i] for i in y.value))
  
      def degrees(self):
          """
          Return the degrees of ``self``.
  
          EXAMPLES::
  
              sage: W = FiniteWeylGroups().example()
              sage: W.degrees()
              (2, 3, 4)
          """
          from sage.rings.integer_ring import ZZ
          return tuple(ZZ(i) for i in range(2, self.n + 1))
  
      class Element(ElementWrapper):
  
          def has_right_descent(self, i):
              """
              Implements :meth:`CoxeterGroups.ElementMethods.has_right_descent`.
  
              EXAMPLES::
  
                  sage: S = FiniteWeylGroups().example()
                  sage: s = S.simple_reflections()
                  sage: (s[1] * s[2]).has_descent(2)
                  True
                  sage: S._test_has_descent()
              """
              return (self.value[i] > self.value[i+1])
  
  
  Example = SymmetricGroup
  