text: """
  Root system data for type B
  """
  #*****************************************************************************
  #       Copyright (C) 2008-2009 Daniel Bump
  #       Copyright (C) 2008-2009 Justin Walker
  #       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 __future__ import print_function
  from __future__ import absolute_import
  
  from . import ambient_space
  
  class  AmbientSpace(ambient_space.AmbientSpace):
      def dimension(self):
          """
          EXAMPLES::
  
              sage: e = RootSystem(['B',3]).ambient_space()
              sage: e.dimension()
              3
          """
          return self.root_system.cartan_type().rank()
  
      def root(self, i, j):
          """
          Note that indexing starts at 0.
  
          EXAMPLES::
  
              sage: e = RootSystem(['B',3]).ambient_space()
              sage: e.root(0,1)
              (1, -1, 0)
  
          """
          return self.monomial(i) - self.monomial(j)
  
      def simple_root(self, i):
          """
          EXAMPLES::
  
              sage: e = RootSystem(['B',4]).ambient_space()
              sage: e.simple_roots()
              Finite family {1: (1, -1, 0, 0), 2: (0, 1, -1, 0), 3: (0, 0, 1, -1), 4: (0, 0, 0, 1)}
              sage: e.positive_roots()
              [(1, -1, 0, 0),
              (1, 1, 0, 0),
              (1, 0, -1, 0),
              (1, 0, 1, 0),
              (1, 0, 0, -1),
              (1, 0, 0, 1),
              (0, 1, -1, 0),
              (0, 1, 1, 0),
              (0, 1, 0, -1),
              (0, 1, 0, 1),
              (0, 0, 1, -1),
              (0, 0, 1, 1),
              (1, 0, 0, 0),
              (0, 1, 0, 0),
              (0, 0, 1, 0),
              (0, 0, 0, 1)]
              sage: e.fundamental_weights()
              Finite family {1: (1, 0, 0, 0), 2: (1, 1, 0, 0), 3: (1, 1, 1, 0), 4: (1/2, 1/2, 1/2, 1/2)}
          """
          if i not in self.index_set():
              raise ValueError("{} is not in the index set".format(i))
          return self.root(i-1,i) if i < self.n else self.monomial(self.n-1)
  
      def negative_roots(self):
          """
          EXAMPLES::
  
              sage: RootSystem(['B',3]).ambient_space().negative_roots()
              [(-1, 1, 0),
               (-1, -1, 0),
               (-1, 0, 1),
               (-1, 0, -1),
               (0, -1, 1),
               (0, -1, -1),
               (-1, 0, 0),
               (0, -1, 0),
               (0, 0, -1)]
  
          """
          return [ -a for a in self.positive_roots()]
  
  
      def positive_roots(self):
          """
          EXAMPLES::
  
              sage: RootSystem(['B',3]).ambient_space().positive_roots()
              [(1, -1, 0),
               (1, 1, 0),
               (1, 0, -1),
               (1, 0, 1),
               (0, 1, -1),
               (0, 1, 1),
               (1, 0, 0),
               (0, 1, 0),
               (0, 0, 1)]
  
          """
          res = []
          for i in range(self.n-1):
              for j in range(i+1,self.n):
                  res.append(self.monomial(i) - self.monomial(j))
                  res.append(self.monomial(i) + self.monomial(j))
          for i in range(self.n):
              res.append(self.monomial(i))
          return res
  
      def fundamental_weight(self, i):
          """
          EXAMPLES::
  
              sage: RootSystem(['B',3]).ambient_space().fundamental_weights()
              Finite family {1: (1, 0, 0), 2: (1, 1, 0), 3: (1/2, 1/2, 1/2)}
          """
          if i not in self.index_set():
              raise ValueError("{} is not in the index set".format(i))
          n = self.dimension()
          if i == n:
              return self.sum( self.monomial(j) for j in range(n) ) / 2
          else:
              return self.sum(self.monomial(j) for j in range(i))
  
  from .cartan_type import CartanType_standard_finite, CartanType_simple, CartanType_crystallographic, CartanType_simply_laced
  class CartanType(CartanType_standard_finite, CartanType_simple, CartanType_crystallographic):
      def __init__(self, n):
          """
          EXAMPLES::
  
              sage: ct = CartanType(['B',4])
              sage: ct
              ['B', 4]
              sage: ct._repr_(compact = True)
              'B4'
  
              sage: ct.is_irreducible()
              True
              sage: ct.is_finite()
              True
              sage: ct.is_affine()
              False
              sage: ct.is_crystallographic()
              True
              sage: ct.is_simply_laced()
              False
              sage: ct.affine()
              ['B', 4, 1]
              sage: ct.dual()
              ['C', 4]
  
              sage: ct = CartanType(['B',1])
              sage: ct.is_simply_laced()
              True
              sage: ct.affine()
              ['B', 1, 1]
  
          TESTS::
  
              sage: TestSuite(ct).run()
          """
          assert n >= 1
          CartanType_standard_finite.__init__(self, "B", n)
          if n == 1:
              self._add_abstract_superclass(CartanType_simply_laced)
  
      def _latex_(self):
          """
          Return a latex representation of ``self``.
  
          EXAMPLES::
  
              sage: latex(CartanType(['B',4]))
              B_{4}
          """
          return "B_{%s}"%self.n
  
      AmbientSpace = AmbientSpace
  
      def coxeter_number(self):
          """
          Return the Coxeter number associated with ``self``.
  
          EXAMPLES::
  
              sage: CartanType(['B',4]).coxeter_number()
              8
          """
          return 2*self.n
  
      def dual_coxeter_number(self):
          """
          Return the dual Coxeter number associated with ``self``.
  
          EXAMPLES::
  
              sage: CartanType(['B',4]).dual_coxeter_number()
              7
          """
          return 2*self.n - 1
  
      def dual(self):
          """
          Types B and C are in duality:
  
          EXAMPLES::
  
              sage: CartanType(["C", 3]).dual()
              ['B', 3]
          """
          from . import cartan_type
          return cartan_type.CartanType(["C", self.n])
  
      def dynkin_diagram(self):
          """
          Returns a Dynkin diagram for type B.
  
          EXAMPLES::
  
               sage: b = CartanType(['B',3]).dynkin_diagram()
               sage: b
               O---O=>=O
               1   2   3
               B3
               sage: sorted(b.edges())
               [(1, 2, 1), (2, 1, 1), (2, 3, 2), (3, 2, 1)]
  
               sage: b = CartanType(['B',1]).dynkin_diagram()
               sage: b
               O
               1
               B1
               sage: sorted(b.edges())
               []
          """
          from .dynkin_diagram import DynkinDiagram_class
          n = self.n
          g = DynkinDiagram_class(self)
          for i in range(1, n):
              g.add_edge(i, i+1)
          if n >= 2:
              g.set_edge_label(n-1, n, 2)
          return g
  
      def ascii_art(self, label=lambda i: i, node=None):
          """
          Return an ascii art representation of the Dynkin diagram.
  
          EXAMPLES::
  
              sage: print(CartanType(['B',1]).ascii_art())
              O
              1
              sage: print(CartanType(['B',2]).ascii_art())
              O=>=O
              1   2
              sage: print(CartanType(['B',5]).ascii_art(label = lambda x: x+2))
              O---O---O---O=>=O
              3   4   5   6   7
          """
          if node is None:
              node = self._ascii_art_node
          n = self.n
          if n == 1:
              ret = node(label(1)) + "\n"
          else:
              ret  = "---".join(node(label(i)) for i in range(1,n)) + "=>=" + node(label(n)) + '\n'
          ret += "".join("{!s:4}".format(label(i)) for i in range(1,n+1))
          return ret
  
      def _latex_dynkin_diagram(self, label=lambda i: i, node=None, node_dist=2, dual=False):
          r"""
          Return a latex representation of the Dynkin diagram.
  
          EXAMPLES::
  
              sage: print(CartanType(['B',4])._latex_dynkin_diagram())
              \draw (0 cm,0) -- (4 cm,0);
              \draw (4 cm, 0.1 cm) -- +(2 cm,0);
              \draw (4 cm, -0.1 cm) -- +(2 cm,0);
              \draw[shift={(5.2, 0)}, rotate=0] (135 : 0.45cm) -- (0,0) -- (-135 : 0.45cm);
              \draw[fill=white] (0 cm, 0 cm) circle (.25cm) node[below=4pt]{$1$};
              \draw[fill=white] (2 cm, 0 cm) circle (.25cm) node[below=4pt]{$2$};
              \draw[fill=white] (4 cm, 0 cm) circle (.25cm) node[below=4pt]{$3$};
              \draw[fill=white] (6 cm, 0 cm) circle (.25cm) node[below=4pt]{$4$};
              <BLANKLINE>
  
          When ``dual=True``, the Dynkin diagram for the dual Cartan
          type `C_n` is returned::
  
              sage: print(CartanType(['B',4])._latex_dynkin_diagram(dual=True))
              \draw (0 cm,0) -- (4 cm,0);
              \draw (4 cm, 0.1 cm) -- +(2 cm,0);
              \draw (4 cm, -0.1 cm) -- +(2 cm,0);
              \draw[shift={(4.8, 0)}, rotate=180] (135 : 0.45cm) -- (0,0) -- (-135 : 0.45cm);
              \draw[fill=white] (0 cm, 0 cm) circle (.25cm) node[below=4pt]{$1$};
              \draw[fill=white] (2 cm, 0 cm) circle (.25cm) node[below=4pt]{$2$};
              \draw[fill=white] (4 cm, 0 cm) circle (.25cm) node[below=4pt]{$3$};
              \draw[fill=white] (6 cm, 0 cm) circle (.25cm) node[below=4pt]{$4$};
              <BLANKLINE>
  
          .. SEEALSO::
  
              - :meth:`sage.combinat.root_system.type_C.CartanType._latex_dynkin_diagram`
              - :meth:`sage.combinat.root_system.type_BC_affine.CartanType._latex_dynkin_diagram`
          """
          if node is None:
              node = self._latex_draw_node
          if self.n == 1:
              return node(0, 0, label(1))
          n = self.n
          ret = "\\draw (0 cm,0) -- (%s cm,0);\n"%((n-2)*node_dist)
          ret += "\\draw (%s cm, 0.1 cm) -- +(%s cm,0);\n"%((n-2)*node_dist, node_dist)
          ret += "\\draw (%s cm, -0.1 cm) -- +(%s cm,0);\n"%((n-2)*node_dist, node_dist)
          if dual:
              ret += self._latex_draw_arrow_tip((n-1.5)*node_dist-0.2, 0, 180)
          else:
              ret += self._latex_draw_arrow_tip((n-1.5)*node_dist+0.2, 0, 0)
          for i in range(self.n):
              ret += node(i*node_dist, 0, label(i+1))
          return ret
  
      def _default_folded_cartan_type(self):
          """
          Return the default folded Cartan type.
  
          EXAMPLES::
  
              sage: CartanType(['B', 3])._default_folded_cartan_type()
              ['B', 3] as a folding of ['D', 4]
          """
          from sage.combinat.root_system.type_folded import CartanTypeFolded
          n = self.n
          return CartanTypeFolded(self, ['D', n+1],
              [[i] for i in range(1, n)] + [[n, n+1]])
  
  # For unpickling backward compatibility (Sage <= 4.1)
  from sage.structure.sage_object import register_unpickle_override
  register_unpickle_override('sage.combinat.root_system.type_B', 'ambient_space',  AmbientSpace)
  
  