ó
¡¼™\c           @  s<  d  d l  m Z m Z d  d l m Z d  d l m Z m Z m Z d  d l	 m
 Z
 d  d l m Z m Z d  d l m Z d  d l m Z d  d l m Z d  d	 l m Z d  d
 l m Z e d „  ƒ Z e d „  ƒ Z e d „  ƒ Z d „  Z i  Z d e f d „  ƒ  YZ d e e e f d „  ƒ  YZ  d „  Z! d „  Z" d S(   iÿÿÿÿ(   t   print_functiont   division(   t   S(   t   is_sequencet   as_intt   string_types(   t   Expr(   t   Symbolt   symbols(   t   CantSympify(   t   DefaultPrinting(   t   public(   t   flatten(   t   pollutec         C  s    t  |  ƒ } | f t | j ƒ S(   sì  Construct a free group returning ``(FreeGroup, (f_0, f_1, ..., f_(n-1))``.

    Parameters
    ==========

    symbols : str, Symbol/Expr or sequence of str, Symbol/Expr (may be empty)

    Examples
    ========

    >>> from sympy.combinatorics.free_groups import free_group
    >>> F, x, y, z = free_group("x, y, z")
    >>> F
    <free group on the generators (x, y, z)>
    >>> x**2*y**-1
    x**2*y**-1
    >>> type(_)
    <class 'sympy.combinatorics.free_groups.FreeGroupElement'>

    (   t	   FreeGroupt   tuplet
   generators(   R   t   _free_group(    (    s>   lib/python2.7/site-packages/sympy/combinatorics/free_groups.pyt
   free_group   s    c         C  s   t  |  ƒ } | | j f S(   sý  Construct a free group returning ``(FreeGroup, (f_0, f_1, ..., f_(n-1)))``.

    Parameters
    ==========

    symbols : str, Symbol/Expr or sequence of str, Symbol/Expr (may be empty)

    Examples
    ========

    >>> from sympy.combinatorics.free_groups import xfree_group
    >>> F, (x, y, z) = xfree_group("x, y, z")
    >>> F
    <free group on the generators (x, y, z)>
    >>> y**2*x**-2*z**-1
    y**2*x**-2*z**-1
    >>> type(_)
    <class 'sympy.combinatorics.free_groups.FreeGroupElement'>

    (   R   R   (   R   R   (    (    s>   lib/python2.7/site-packages/sympy/combinatorics/free_groups.pyt   xfree_group(   s    c         C  s9   t  |  ƒ } t g  | j D] } | j ^ q | j ƒ | S(   s÷  Construct a free group and inject ``f_0, f_1, ..., f_(n-1)`` as symbols
    into the global namespace.

    Parameters
    ==========

    symbols : str, Symbol/Expr or sequence of str, Symbol/Expr (may be empty)

    Examples
    ========

    >>> from sympy.combinatorics.free_groups import vfree_group
    >>> vfree_group("x, y, z")
    <free group on the generators (x, y, z)>
    >>> x**2*y**-2*z
    x**2*y**-2*z
    >>> type(_)
    <class 'sympy.combinatorics.free_groups.FreeGroupElement'>

    (   R   R   R   t   nameR   (   R   R   t   sym(    (    s>   lib/python2.7/site-packages/sympy/combinatorics/free_groups.pyt   vfree_groupA   s    )c         C  s¡   |  s t  ƒ  St |  t ƒ r, t |  d t ƒSt |  t p; t ƒ rH |  f St |  ƒ r‘ t d „  |  Dƒ ƒ rt t |  ƒ St d „  |  Dƒ ƒ r‘ |  Sn  t	 d ƒ ‚ d  S(   Nt   seqc         s  s   |  ] } t  | t ƒ Vq d  S(   N(   t
   isinstanceR   (   t   .0t   s(    (    s>   lib/python2.7/site-packages/sympy/combinatorics/free_groups.pys	   <genexpr>d   s    c         s  s   |  ] } t  | t ƒ Vq d  S(   N(   R   R   (   R   R   (    (    s>   lib/python2.7/site-packages/sympy/combinatorics/free_groups.pys	   <genexpr>f   s    sj   The type of `symbols` must be one of the following: a str, Symbol/Expr or a sequence of one of these types(
   R   R   R   t   _symbolst   TrueR   t   FreeGroupElementR   t   allt
   ValueError(   R   (    (    s>   lib/python2.7/site-packages/sympy/combinatorics/free_groups.pyt   _parse_symbols\   s    
R   c           B  sé   e  Z d  Z e Z e Z e Z e Z e	 ƒ  Z
 d „  Z d „  Z d d „ Z d „  Z d „  Z d „  Z d „  Z e Z d „  Z d	 „  Z d
 „  Z d „  Z e d „  ƒ Z e d „  ƒ Z e d „  ƒ Z e d „  ƒ Z d „  Z d „  Z RS(   s  
    Free group with finite or infinite number of generators. Its input API
    is that of a str, Symbol/Expr or a sequence of one of
    these types (which may be empty)

    See Also
    ========

    sympy.polys.rings.PolyRing

    References
    ==========

    .. [1] http://www.gap-system.org/Manuals/doc/ref/chap37.html

    .. [2] https://en.wikipedia.org/wiki/Free_group

    c         C  s/  t  t | ƒ ƒ } t | ƒ } t |  j | | f ƒ } t j | ƒ } | d  k r+t j	 |  ƒ } | | _
 | | _ t d t f i | d 6ƒ | _ | | _ | j ƒ  | _ t | j ƒ | _ x` t | j | j ƒ D]I \ } } t | t ƒ rÑ | j } t | | ƒ rt | | | ƒ qqÑ qÑ W| t | <n  | S(   NR   t   group(   R   R    t   lent   hasht   __name__t   _free_group_cachet   gett   Nonet   objectt   __new__t   _hasht   _rankt   typeR   t   dtypeR   t   _generatorsR   t   sett	   _gens_sett   zipR   R   R   t   hasattrt   setattr(   t   clsR   t   rankR*   t   objt   symbolt	   generatorR   (    (    s>   lib/python2.7/site-packages/sympy/combinatorics/free_groups.pyR)   Œ   s&    			"	c         C  sI   g  } x6 |  j  D]+ } | d f f } | j |  j | ƒ ƒ q Wt | ƒ S(   só   Returns the generators of the FreeGroup.

        Examples
        ========

        >>> from sympy.combinatorics.free_groups import free_group
        >>> F, x, y, z = free_group("x, y, z")
        >>> F.generators
        (x, y, z)

        i   (   R   t   appendR-   R   (   R!   t   gensR   t   elm(    (    s>   lib/python2.7/site-packages/sympy/combinatorics/free_groups.pyR.   ¥   s
    c         C  s   |  j  | p |  j ƒ S(   N(   t	   __class__R   (   t   selfR   (    (    s>   lib/python2.7/site-packages/sympy/combinatorics/free_groups.pyt   clone·   s    c         C  s&   t  | t ƒ s t S| j } |  | k S(   s/   Return True if ``i`` is contained in FreeGroup.(   R   R   t   FalseR!   (   R=   t   iR!   (    (    s>   lib/python2.7/site-packages/sympy/combinatorics/free_groups.pyt   __contains__º   s    	c         C  s   |  j  S(   N(   R*   (   R=   (    (    s>   lib/python2.7/site-packages/sympy/combinatorics/free_groups.pyt   __hash__Á   s    c         C  s   |  j  S(   N(   R5   (   R=   (    (    s>   lib/python2.7/site-packages/sympy/combinatorics/free_groups.pyt   __len__Ä   s    c         C  sF   |  j  d k r d |  j  } n# d } |  j } | t | ƒ d 7} | S(   Ni   s   <free group with %s generators>s   <free group on the generators t   >(   R5   R   t   str(   R=   t   str_formR:   (    (    s>   lib/python2.7/site-packages/sympy/combinatorics/free_groups.pyt   __str__Ç   s    	c         C  s   |  j  | } |  j d | ƒ S(   NR   (   R   R>   (   R=   t   indexR   (    (    s>   lib/python2.7/site-packages/sympy/combinatorics/free_groups.pyt   __getitem__Ò   s    c         C  s
   |  | k S(   s@   No ``FreeGroup`` is equal to any "other" ``FreeGroup``.
        (    (   R=   t   other(    (    s>   lib/python2.7/site-packages/sympy/combinatorics/free_groups.pyt   __eq__Ö   s    c         C  s<   t  | |  j ƒ r" |  j j | ƒ St d |  | f ƒ ‚ d S(   s!  Return the index of the generator `gen` from ``(f_0, ..., f_(n-1))``.

        Examples
        ========

        >>> from sympy.combinatorics.free_groups import free_group
        >>> F, x, y = free_group("x, y")
        >>> F.index(y)
        1
        >>> F.index(x)
        0

        s-   expected a generator of Free Group %s, got %sN(   R   R-   R   RH   R   (   R=   t   gen(    (    s>   lib/python2.7/site-packages/sympy/combinatorics/free_groups.pyRH   Û   s    c         C  s   |  j  d k r d St j Sd S(   s  Return the order of the free group.

        Examples
        ========

        >>> from sympy.combinatorics.free_groups import free_group
        >>> F, x, y = free_group("x, y")
        >>> F.order()
        oo

        >>> free_group("")[0].order()
        1

        i    i   N(   R5   R   t   Infinity(   R=   (    (    s>   lib/python2.7/site-packages/sympy/combinatorics/free_groups.pyt   orderî   s    c         C  s)   |  j  d k r |  j h St d ƒ ‚ d S(   sî   
        Return the elements of the free group.

        Examples
        ========

        >>> from sympy.combinatorics.free_groups import free_group
        >>> (z,) = free_group("")
        >>> z.elements
        {<identity>}

        i    sC   Group contains infinitely many elements, hence can't be representedN(   R5   t   identityR   (   R=   (    (    s>   lib/python2.7/site-packages/sympy/combinatorics/free_groups.pyt   elements  s    
c         C  s   |  j  S(   s  
        In group theory, the `rank` of a group `G`, denoted `G.rank`,
        can refer to the smallest cardinality of a generating set
        for G, that is

        \operatorname{rank}(G)=\min\{ |X|: X\subseteq G, \left\langle X\right\rangle =G\}.

        (   R+   (   R=   (    (    s>   lib/python2.7/site-packages/sympy/combinatorics/free_groups.pyR5     s    
c         C  s*   |  j  d k s |  j  d k r" t St Sd S(   så   Returns if the group is Abelian.

        Examples
        ========

        >>> from sympy.combinatorics.free_groups import free_group
        >>> f, x, y, z = free_group("x y z")
        >>> f.is_abelian
        False

        i    i   N(   R5   R   R?   (   R=   (    (    s>   lib/python2.7/site-packages/sympy/combinatorics/free_groups.pyt
   is_abelian#  s    c         C  s
   |  j  ƒ  S(   s+   Returns the identity element of free group.(   R-   (   R=   (    (    s>   lib/python2.7/site-packages/sympy/combinatorics/free_groups.pyRO   5  s    c         C  s.   t  | t ƒ s t S|  | j k r& t St Sd S(   su  Tests if Free Group element ``g`` belong to self, ``G``.

        In mathematical terms any linear combination of generators
        of a Free Group is contained in it.

        Examples
        ========

        >>> from sympy.combinatorics.free_groups import free_group
        >>> f, x, y, z = free_group("x y z")
        >>> f.contains(x**3*y**2)
        True

        N(   R   R   R?   R!   R   (   R=   t   g(    (    s>   lib/python2.7/site-packages/sympy/combinatorics/free_groups.pyt   contains:  s
    c         C  s
   |  j  h S(   s,   Returns the center of the free group `self`.(   RO   (   R=   (    (    s>   lib/python2.7/site-packages/sympy/combinatorics/free_groups.pyt   centerP  s    N(   R$   t
   __module__t   __doc__R   t   is_associativet   is_groupt   is_FreeGroupR?   t   is_PermutationGroupR   t   relatorsR)   R.   R'   R>   RA   RB   RC   RG   t   __repr__RI   RK   RH   RN   t   propertyRP   R5   RQ   RO   RS   RT   (    (    (    s>   lib/python2.7/site-packages/sympy/combinatorics/free_groups.pyR   s   s0   													R   c           B  s	  e  Z d  Z e Z d „  Z d1 Z d „  Z d „  Z	 e
 d „  ƒ Z e
 d „  ƒ Z e
 d „  ƒ Z d „  Z d „  Z e
 d	 „  ƒ Z e
 d
 „  ƒ Z d „  Z d „  Z e Z d „  Z d „  Z d „  Z d „  Z e Z e Z d „  Z d „  Z d „  Z d „  Z e e d „ Z  d1 e e d „ Z! d „  Z" d „  Z# d „  Z$ d „  Z% d „  Z& d „  Z' d „  Z( d „  Z) e d „ Z* d  d! „ Z+ d" „  Z, d# „  Z- d$ „  Z. d% „  Z/ d& „  Z0 d' „  Z1 d( „  Z2 d) „  Z3 d* „  Z4 d+ „  Z5 d, „  Z6 d- „  Z7 d. „  Z8 e d/ „ Z9 d0 „  Z: RS(2   s¬   Used to create elements of FreeGroup. It can not be used directly to
    create a free group element. It is called by the `dtype` method of the
    `FreeGroup` class.

    c         C  s   |  j  | ƒ S(   N(   R<   (   R=   t   init(    (    s>   lib/python2.7/site-packages/sympy/combinatorics/free_groups.pyt   newb  s    c         C  sD   |  j  } | d  k r@ t |  j t t |  ƒ ƒ f ƒ |  _  } n  | S(   N(   R*   R'   R#   R!   t	   frozensetR   (   R=   R*   (    (    s>   lib/python2.7/site-packages/sympy/combinatorics/free_groups.pyRB   g  s    	+c         C  s   |  j  |  ƒ S(   N(   R_   (   R=   (    (    s>   lib/python2.7/site-packages/sympy/combinatorics/free_groups.pyt   copym  s    c         C  s   |  j  t ƒ  k r t St Sd  S(   N(   t
   array_formR   R   R?   (   R=   (    (    s>   lib/python2.7/site-packages/sympy/combinatorics/free_groups.pyt   is_identityp  s    c         C  s
   t  |  ƒ S(   sÿ  
        SymPy provides two different internal kinds of representation
        of associative words. The first one is called the `array_form`
        which is a tuple containing `tuples` as its elements, where the
        size of each tuple is two. At the first position the tuple
        contains the `symbol-generator`, while at the second position
        of tuple contains the exponent of that generator at the position.
        Since elements (i.e. words) don't commute, the indexing of tuple
        makes that property to stay.

        The structure in ``array_form`` of ``FreeGroupElement`` is of form:

        ``( ( symbol_of_gen , exponent ), ( , ), ... ( , ) )``

        Examples
        ========

        >>> from sympy.combinatorics.free_groups import free_group
        >>> f, x, y, z = free_group("x y z")
        >>> (x*z).array_form
        ((x, 1), (z, 1))
        >>> (x**2*z*y*x**2).array_form
        ((x, 2), (z, 1), (y, 1), (x, 2))

        See Also
        ========

        letter_repr

        (   R   (   R=   (    (    s>   lib/python2.7/site-packages/sympy/combinatorics/free_groups.pyRb   w  s     c         C  sN   t  t g  |  j D]4 \ } } | d k r5 | f | n | f | ^ q ƒ ƒ S(   s™  
        The letter representation of a ``FreeGroupElement`` is a tuple
        of generator symbols, with each entry corresponding to a group
        generator. Inverses of the generators are represented by
        negative generator symbols.

        Examples
        ========

        >>> from sympy.combinatorics.free_groups import free_group
        >>> f, a, b, c, d = free_group("a b c d")
        >>> (a**3).letter_form
        (a, a, a)
        >>> (a**2*d**-2*a*b**-4).letter_form
        (a, a, -d, -d, a, -b, -b, -b, -b)
        >>> (a**-2*b**3*d).letter_form
        (-a, -a, b, b, b, d)

        See Also
        ========

        array_form

        i    (   R   R   Rb   (   R=   R@   t   j(    (    s>   lib/python2.7/site-packages/sympy/combinatorics/free_groups.pyt   letter_form™  s    	c         C  sP   |  j  } |  j | } | j r5 | j | d f f ƒ S| j | d f f ƒ Sd  S(   Ni   iÿÿÿÿ(   R!   Re   t	   is_SymbolR-   (   R=   R@   R!   t   r(    (    s>   lib/python2.7/site-packages/sympy/combinatorics/free_groups.pyRI   ¶  s
    		c         C  s5   t  | ƒ d k r t ƒ  ‚ n  |  j j | j d ƒ S(   Ni   i    (   R"   R   Re   RH   (   R=   RL   (    (    s>   lib/python2.7/site-packages/sympy/combinatorics/free_groups.pyRH   ¾  s    c         C  s]   |  j  } |  j } g  | D]@ } | j r@ | j | d f f ƒ n | j | d f f ƒ ^ q S(   s	   
        i   iÿÿÿÿ(   R!   Re   Rf   R-   (   R=   R!   Rg   R;   (    (    s>   lib/python2.7/site-packages/sympy/combinatorics/free_groups.pyt   letter_form_elmÃ  s    		c         C  s   t  t |  j ƒ ƒ S(   sK   This is called the External Representation of ``FreeGroupElement``
        (   R   R   Rb   (   R=   (    (    s>   lib/python2.7/site-packages/sympy/combinatorics/free_groups.pyt   ext_repÌ  s    c         C  s5   | j  d d t g  |  j  D] } | d ^ q ƒ k S(   Ni    (   Rb   R   (   R=   RL   Rg   (    (    s>   lib/python2.7/site-packages/sympy/combinatorics/free_groups.pyRA   Ò  s    c         C  s  |  j  r d Sd } |  j } xõ t t | ƒ ƒ D]á } | t | ƒ d k r« | | d d k rz | t | | d ƒ 7} q| t | | d ƒ d t | | d ƒ 7} q/ | | d d k rÞ | t | | d ƒ d 7} q/ | t | | d ƒ d t | | d ƒ d 7} q/ W| S(   Ns
   <identity>t    i   i    s   **t   *(   Rc   Rb   t   rangeR"   RE   (   R=   RF   Rb   R@   (    (    s>   lib/python2.7/site-packages/sympy/combinatorics/free_groups.pyRG   Õ  s    		.3c         C  sx   t  | ƒ } |  j } | d k r( | j S| d k  rI | } |  j ƒ  | S|  } x" t | d ƒ D] } | |  } q` W| S(   Ni    i   (   R   R!   RO   t   inverseRl   (   R=   t   nR!   t   resultR@   (    (    s>   lib/python2.7/site-packages/sympy/combinatorics/free_groups.pyt   __pow__ì  s    	c         C  s‡   |  j  } t | | j ƒ s* t d ƒ ‚ n  |  j r7 | S| j rD |  St |  j | j ƒ } t | t |  j ƒ d ƒ | j t	 | ƒ ƒ S(   sa  Returns the product of elements belonging to the same ``FreeGroup``.

        Examples
        ========

        >>> from sympy.combinatorics.free_groups import free_group
        >>> f, x, y, z = free_group("x y z")
        >>> x*y**2*y**-4
        x*y**-2
        >>> z*y**-2
        z*y**-2
        >>> x**2*y*y**-1*x**-2
        <identity>

        s;   only FreeGroup elements of same FreeGroup can be multipliedi   (
   R!   R   R-   t	   TypeErrorRc   t   listRb   t   zero_mul_simpR"   R   (   R=   RJ   R!   Rg   (    (    s>   lib/python2.7/site-packages/sympy/combinatorics/free_groups.pyt   __mul__ý  s    			c         C  s8   |  j  } t | | j ƒ s* t d ƒ ‚ n  |  | j ƒ  S(   Ns;   only FreeGroup elements of same FreeGroup can be multiplied(   R!   R   R-   Rq   Rm   (   R=   RJ   R!   (    (    s>   lib/python2.7/site-packages/sympy/combinatorics/free_groups.pyt   __div__  s    	c         C  s8   |  j  } t | | j ƒ s* t d ƒ ‚ n  | |  j ƒ  S(   Ns;   only FreeGroup elements of same FreeGroup can be multiplied(   R!   R   R-   Rq   Rm   (   R=   RJ   R!   (    (    s>   lib/python2.7/site-packages/sympy/combinatorics/free_groups.pyt   __rdiv__   s    	c         C  s   t  S(   N(   t   NotImplemented(   R=   RJ   (    (    s>   lib/python2.7/site-packages/sympy/combinatorics/free_groups.pyt   __add__+  s    c         C  sR   |  j  } t g  |  j d d d … D] \ } } | | f ^ q# ƒ } | j | ƒ S(   s2  
        Returns the inverse of a ``FreeGroupElement`` element

        Examples
        ========

        >>> from sympy.combinatorics.free_groups import free_group
        >>> f, x, y, z = free_group("x y z")
        >>> x.inverse()
        x**-1
        >>> (x*y).inverse()
        y**-1*x**-1

        Niÿÿÿÿ(   R!   R   Rb   R-   (   R=   R!   R@   Rd   Rg   (    (    s>   lib/python2.7/site-packages/sympy/combinatorics/free_groups.pyRm   .  s    	<c         C  s   |  j  r d St j Sd S(   sõ   Find the order of a ``FreeGroupElement``.

        Examples
        ========

        >>> from sympy.combinatorics.free_groups import free_group
        >>> f, x, y = free_group("x y")
        >>> (x**2*y*y**-1*x**-2).order()
        1

        i   N(   Rc   R   RM   (   R=   (    (    s>   lib/python2.7/site-packages/sympy/combinatorics/free_groups.pyRN   A  s    	c         C  sJ   |  j  } t | | j ƒ s* t d ƒ ‚ n |  j ƒ  | j ƒ  |  | Sd S(   sO   
        Return the commutator of `self` and `x`: ``~x*~self*x*self``

        s@   commutator of only FreeGroupElement of the same FreeGroup existsN(   R!   R   R-   R   Rm   (   R=   RJ   R!   (    (    s>   lib/python2.7/site-packages/sympy/combinatorics/free_groups.pyt
   commutatorR  s    	c         C  sÝ   t  } |  } t | t ƒ r x» | r{ t } xK | D]C } | } | j | | | d | d | ƒ} | | k r1 t  } q1 q1 Wq WnZ xW | rØ t } xD | D]< } | } | j | d | d | ƒ} | | k r• t  } q• q• Wq‚ W| S(   s•   
        Replace each subword from the dictionary `words` by words[subword].
        If words is a list, replace the words by the identity.

        t   _allRm   (   R   R   t   dictR?   t   eliminate_word(   R=   t   wordsRz   Rm   t   againR_   t   subt   prev(    (    s>   lib/python2.7/site-packages/sympy/combinatorics/free_groups.pyt   eliminate_words^  s$    	"	c   	      C  sH  | d k r |  j j } n  |  j | ƒ s6 | | k r: |  S| |  k rJ | S| d | k rc t } n  |  } t | ƒ } y | j | ƒ } d } WnM t k
 rÝ | s¨ | Sy | j | d ƒ } d } WqÞ t k
 rÙ | SXn X| j d | ƒ | | | j | | t | ƒ ƒ j	 | | ƒ } | r@| j	 | | d t
 d | ƒS| Sd S(   sÐ  
        For an associative word `self`, a subword `gen`, and an associative
        word `by` (identity by default), return the associative word obtained by
        replacing each occurrence of `gen` in `self` by `by`. If `_all = True`,
        the occurrences of `gen` that may appear after the first substitution will
        also be replaced and so on until no occurrences are found. This might not
        always terminate (e.g. `(x).eliminate_word(x, x**2, _all=True)`).

        Examples
        ========

        >>> from sympy.combinatorics.free_groups import free_group
        >>> f, x, y = free_group("x y")
        >>> w = x**5*y*x**2*y**-4*x
        >>> w.eliminate_word( x, x**2 )
        x**10*y*x**4*y**-4*x**2
        >>> w.eliminate_word( x, y**-1 )
        y**-11
        >>> w.eliminate_word(x**5)
        y*x**2*y**-4*x
        >>> w.eliminate_word(x*y, y)
        x**4*y*x**2*y**-4*x

        See Also
        ========
        substituted_word

        iÿÿÿÿi   i    Rz   Rm   N(   R'   R!   RO   t   is_independentR?   R"   t   subword_indexR   t   subwordR|   R   (	   R=   RL   t   byRz   Rm   t   wordt   lR@   t   k(    (    s>   lib/python2.7/site-packages/sympy/combinatorics/free_groups.pyR|   x  s2    	

	@c         C  s   t  d „  |  Dƒ ƒ S(   sj  
        For an associative word `self`, returns the number of letters in it.

        Examples
        ========

        >>> from sympy.combinatorics.free_groups import free_group
        >>> f, a, b = free_group("a b")
        >>> w = a**5*b*a**2*b**-4*a
        >>> len(w)
        13
        >>> len(a**17)
        17
        >>> len(w**0)
        0

        c         s  s!   |  ] \ } } t  | ƒ Vq d  S(   N(   t   abs(   R   R@   Rd   (    (    s>   lib/python2.7/site-packages/sympy/combinatorics/free_groups.pys	   <genexpr>Å  s    (   t   sum(   R=   (    (    s>   lib/python2.7/site-packages/sympy/combinatorics/free_groups.pyRC   ³  s    c         C  s/   |  j  } t | | j ƒ s t St j |  | ƒ S(   s»  
        Two  associative words are equal if they are words over the
        same alphabet and if they are sequences of the same letters.
        This is equivalent to saying that the external representations
        of the words are equal.
        There is no "universal" empty word, every alphabet has its own
        empty word.

        Examples
        ========

        >>> from sympy.combinatorics.free_groups import free_group
        >>> f, swapnil0, swapnil1 = free_group("swapnil0 swapnil1")
        >>> f
        <free group on the generators (swapnil0, swapnil1)>
        >>> g, swap0, swap1 = free_group("swap0 swap1")
        >>> g
        <free group on the generators (swap0, swap1)>

        >>> swapnil0 == swapnil1
        False
        >>> swapnil0*swapnil1 == swapnil1/swapnil1*swapnil0*swapnil1
        True
        >>> swapnil0*swapnil1 == swapnil1*swapnil0
        False
        >>> swapnil1**0 == swap0**0
        False

        (   R!   R   R-   R?   R   RK   (   R=   RJ   R!   (    (    s>   lib/python2.7/site-packages/sympy/combinatorics/free_groups.pyRK   Ç  s    	c   
      C  s  |  j  } t | | j ƒ s* t d ƒ ‚ n  t |  ƒ } t | ƒ } | | k  rR t S| | k rb t Sx² t | ƒ D]¤ } |  | j d } | | j d } | j	 j
 | d ƒ } | j	 j
 | d ƒ }	 | |	 k  rÓ t S| |	 k rã t S| d | d k  rû t S| d | d k ro t Sqo Wt S(   s8  
        The  ordering  of  associative  words is defined by length and
        lexicography (this ordering is called short-lex ordering), that
        is, shorter words are smaller than longer words, and words of the
        same length are compared w.r.t. the lexicographical ordering induced
        by the ordering of generators. Generators  are  sorted  according
        to the order in which they were created. If the generators are
        invertible then each generator `g` is larger than its inverse `g^{-1}`,
        and `g^{-1}` is larger than every generator that is smaller than `g`.

        Examples
        ========

        >>> from sympy.combinatorics.free_groups import free_group
        >>> f, a, b = free_group("a b")
        >>> b < a
        False
        >>> a < a.inverse()
        False

        s9   only FreeGroup elements of same FreeGroup can be comparedi    i   (   R!   R   R-   Rq   R"   R   R?   Rl   Rb   R   RH   (
   R=   RJ   R!   R‡   t   mR@   t   at   bt   pt   q(    (    s>   lib/python2.7/site-packages/sympy/combinatorics/free_groups.pyt   __lt__ê  s.    	c         C  s   |  | k p |  | k  S(   N(    (   R=   RJ   (    (    s>   lib/python2.7/site-packages/sympy/combinatorics/free_groups.pyt   __le__  s    c         C  s5   |  j  } t | | j ƒ s* t d ƒ ‚ n  |  | k S(   s  

        Examples
        ========

        >>> from sympy.combinatorics.free_groups import free_group
        >>> f, x, y, z = free_group("x y z")
        >>> y**2 > x**2
        True
        >>> y*z > z*y
        False
        >>> x > x.inverse()
        True

        s9   only FreeGroup elements of same FreeGroup can be compared(   R!   R   R-   Rq   (   R=   RJ   R!   (    (    s>   lib/python2.7/site-packages/sympy/combinatorics/free_groups.pyt   __gt__  s    	c         C  s   |  | k  S(   N(    (   R=   RJ   (    (    s>   lib/python2.7/site-packages/sympy/combinatorics/free_groups.pyt   __ge__3  s    c         C  sn   t  | ƒ d k r! t d ƒ ‚ n  | j d } | d t g  |  j D]$ } | d | d k rB | d ^ qB ƒ S(   s¿  
        For an associative word `self` and a generator or inverse of generator
        `gen`, ``exponent_sum`` returns the number of times `gen` appears in
        `self` minus the number of times its inverse appears in `self`. If
        neither `gen` nor its inverse occur in `self` then 0 is returned.

        Examples
        ========

        >>> from sympy.combinatorics.free_groups import free_group
        >>> F, x, y = free_group("x, y")
        >>> w = x**2*y**3
        >>> w.exponent_sum(x)
        2
        >>> w.exponent_sum(x**-1)
        -2
        >>> w = x**2*y**4*x**-3
        >>> w.exponent_sum(x)
        -1

        See Also
        ========

        generator_count

        i   s1   gen must be a generator or inverse of a generatori    (   R"   R   Rb   RŠ   (   R=   RL   R   R@   (    (    s>   lib/python2.7/site-packages/sympy/combinatorics/free_groups.pyt   exponent_sum6  s    c         C  s‹   t  | ƒ d k s) | j d d d k  r8 t d ƒ ‚ n  | j d } | d t g  |  j D]* } | d | d k rY t | d ƒ ^ qY ƒ S(   sü  
        For an associative word `self` and a generator `gen`,
        ``generator_count`` returns the multiplicity of generator
        `gen` in `self`.

        Examples
        ========

        >>> from sympy.combinatorics.free_groups import free_group
        >>> F, x, y = free_group("x, y")
        >>> w = x**2*y**3
        >>> w.generator_count(x)
        2
        >>> w = x**2*y**4*x**-3
        >>> w.generator_count(x)
        5

        See Also
        ========

        exponent_sum

        i   i    s   gen must be a generator(   R"   Rb   R   RŠ   R‰   (   R=   RL   R   R@   (    (    s>   lib/python2.7/site-packages/sympy/combinatorics/free_groups.pyt   generator_countV  s    )c         C  s¦   |  j  } | s6 t | d ƒ } t t |  ƒ | ƒ } n  | d k  sT | t |  ƒ k rc t d ƒ ‚ n  | | k rv | j S|  j | | !} t | | ƒ } | j | ƒ Sd S(   sÏ  
        For an associative word `self` and two positive integers `from_i` and
        `to_j`, `subword` returns the subword of `self` that begins at position
        `from_i` and ends at `to_j - 1`, indexing is done with origin 0.

        Examples
        ========

        >>> from sympy.combinatorics.free_groups import free_group
        >>> f, a, b = free_group("a b")
        >>> w = a**5*b*a**2*b**-4*a
        >>> w.subword(2, 6)
        a**3*b

        i    sT   `from_i`, `to_j` must be positive and no greater than the length of associative wordN(	   R!   t   maxt   minR"   R   RO   Re   t   letter_form_to_array_formR-   (   R=   t   from_it   to_jt   strictR!   Re   Rb   (    (    s>   lib/python2.7/site-packages/sympy/combinatorics/free_groups.pyR„   s  s    	i    c         C  s   t  | ƒ } |  j } | j } d } xF t | t  | ƒ | d ƒ D]' } | | | | !| k rB | } PqB qB W| d k	 r} | St d ƒ ‚ d S(   s  
        Find the index of `word` in `self`.

        Examples
        ========

        >>> from sympy.combinatorics.free_groups import free_group
        >>> f, a, b = free_group("a b")
        >>> w = a**2*b*a*b**3
        >>> w.subword_index(a*b*a*b)
        1

        i   s'   The given word is not a subword of selfN(   R"   Re   R'   Rl   R   (   R=   R†   t   startR‡   t   self_lft   word_lfRH   R@   (    (    s>   lib/python2.7/site-packages/sympy/combinatorics/free_groups.pyRƒ   ‘  s    		$c         C  s_   y |  j  | ƒ d k	 SWn t k
 r* n Xy |  j  | d ƒ d k	 SWn t k
 rZ t SXd S(   s¿  
        Examples
        ========

        >>> from sympy.combinatorics.free_groups import free_group
        >>> F, x, y = free_group("x, y")
        >>> (x**4*y**-3).is_dependent(x**4*y**-2)
        True
        >>> (x**2*y**-1).is_dependent(x*y)
        False
        >>> (x*y**2*x*y**2).is_dependent(x*y**2)
        True
        >>> (x**12).is_dependent(x**-4)
        True

        See Also
        ========

        is_independent

        iÿÿÿÿN(   Rƒ   R'   R   R?   (   R=   R†   (    (    s>   lib/python2.7/site-packages/sympy/combinatorics/free_groups.pyt   is_dependent¬  s    c         C  s   |  j  | ƒ S(   sC   

        See Also
        ========

        is_dependent

        (   RŸ   (   R=   R†   (    (    s>   lib/python2.7/site-packages/sympy/combinatorics/free_groups.pyR‚   Ë  s    	c         C  sS   |  j  } t ƒ  } x4 |  j D]) } | j | j | d d f f ƒ ƒ q Wt | ƒ S(   s  
        Examples
        ========

        >>> from sympy.combinatorics.free_groups import free_group
        >>> F, x, y, z = free_group("x, y, z")
        >>> (x**2*y**-1).contains_generators()
        {x, y}
        >>> (x**3*z).contains_generators()
        {x, z}

        i    i   (   R!   R/   Rb   t   addR-   (   R=   R!   R:   t   syllable(    (    s>   lib/python2.7/site-packages/sympy/combinatorics/free_groups.pyt   contains_generatorsÖ  s
    		'c   
      C  sÆ   |  j  } t |  ƒ } |  j } t | | ƒ } | | k rY | | | 8} | | | 8} n  | | } | | | !} t | | ƒ d }	 | | |	 | | | | | |	  7} t | | ƒ } | j | ƒ S(   Ni   (   R!   R"   Re   t   intR˜   R-   (
   R=   R™   Rš   R!   R‡   Re   t   period1t   diffR†   t   period2(    (    s>   lib/python2.7/site-packages/sympy/combinatorics/free_groups.pyt   cyclic_subwordé  s    		
&c           s    ‡  f d †  t  t ˆ  ƒ ƒ Dƒ S(   s  Returns a words which are cyclic to the word `self`.

        Examples
        ========

        >>> from sympy.combinatorics.free_groups import free_group
        >>> F, x, y = free_group("x, y")
        >>> w = x*y*x*y*x
        >>> w.cyclic_conjugates()
        {x*y*x**2*y, x**2*y*x*y, y*x*y*x**2, y*x**2*y*x, x*y*x*y*x}
        >>> s = x*y*x**2*y*x
        >>> s.cyclic_conjugates()
        {x**2*y*x**2*y, y*x**2*y*x**2, x*y*x**2*y*x}

        References
        ==========

        http://planetmath.org/cyclicpermutation

        c           s,   h  |  ]" } ˆ  j  | | t ˆ  ƒ ƒ ’ q S(    (   R§   R"   (   R   R@   (   R=   (    s>   lib/python2.7/site-packages/sympy/combinatorics/free_groups.pys	   <setcomp>  s   	 (   Rl   R"   (   R=   (    (   R=   s>   lib/python2.7/site-packages/sympy/combinatorics/free_groups.pyt   cyclic_conjugatesø  s    c   
      C  s°   t  |  ƒ } t  | ƒ } | | k r( t S|  j ƒ  } | j ƒ  } | j } | j } d j t t | ƒ ƒ } d j t t | ƒ ƒ }	 t  | ƒ t  |	 ƒ k rž t S| |	 d |	 k S(   sž  
        Checks whether words ``self``, ``w`` are cyclic conjugates.

        Examples
        ========

        >>> from sympy.combinatorics.free_groups import free_group
        >>> F, x, y = free_group("x, y")
        >>> w1 = x**2*y**5
        >>> w2 = x*y**5*x
        >>> w1.is_cyclic_conjugate(w2)
        True
        >>> w3 = x**-1*y**5*x**-1
        >>> w3.is_cyclic_conjugate(w2)
        False

        t    (   R"   R?   t   identity_cyclic_reductionRe   t   joint   mapRE   (
   R=   t   wt   l1t   l2t   w1t   w2t   letter1t   letter2t   str1t   str2(    (    s>   lib/python2.7/site-packages/sympy/combinatorics/free_groups.pyt   is_cyclic_conjugate  s    		c         C  s   t  |  j ƒ S(   sA  Returns the number of syllables of the associative word `self`.

        Examples
        ========

        >>> from sympy.combinatorics.free_groups import free_group
        >>> f, swapnil0, swapnil1 = free_group("swapnil0 swapnil1")
        >>> (swapnil1**3*swapnil0*swapnil1**-1).number_syllables()
        3

        (   R"   Rb   (   R=   (    (    s>   lib/python2.7/site-packages/sympy/combinatorics/free_groups.pyt   number_syllables0  s    c         C  s   |  j  | d S(   sH  
        Returns the exponent of the `i`-th syllable of the associative word
        `self`.

        Examples
        ========

        >>> from sympy.combinatorics.free_groups import free_group
        >>> f, a, b = free_group("a b")
        >>> w = a**5*b*a**2*b**-4*a
        >>> w.exponent_syllable( 2 )
        2

        i   (   Rb   (   R=   R@   (    (    s>   lib/python2.7/site-packages/sympy/combinatorics/free_groups.pyt   exponent_syllable>  s    c         C  s   |  j  | d S(   sg  
        Returns the symbol of the generator that is involved in the
        i-th syllable of the associative word `self`.

        Examples
        ========

        >>> from sympy.combinatorics.free_groups import free_group
        >>> f, a, b = free_group("a b")
        >>> w = a**5*b*a**2*b**-4*a
        >>> w.generator_syllable( 3 )
        b

        i    (   Rb   (   R=   R@   (    (    s>   lib/python2.7/site-packages/sympy/combinatorics/free_groups.pyt   generator_syllableO  s    c         C  sr   t  | t ƒ s  t  | t ƒ r/ t d ƒ ‚ n  |  j } | | k rK | j St |  j | | !ƒ } | j | ƒ Sd S(   s  
        `sub_syllables` returns the subword of the associative word `self` that
        consists of syllables from positions `from_to` to `to_j`, where
        `from_to` and `to_j` must be positive integers and indexing is done
        with origin 0.

        Examples
        ========

        >>> from sympy.combinatorics.free_groups import free_group
        >>> f, a, b = free_group("a, b")
        >>> w = a**5*b*a**2*b**-4*a
        >>> w.sub_syllables(1, 2)
        b
        >>> w.sub_syllables(3, 3)
        <identity>

        s!   both arguments should be integersN(   R   R£   R   R!   RO   R   Rb   R-   (   R=   R™   Rš   R!   Rg   (    (    s>   lib/python2.7/site-packages/sympy/combinatorics/free_groups.pyt   sub_syllables`  s     	c         C  sÃ   t  |  ƒ } | | k s0 | | k s0 | | k r? t d ƒ ‚ n  | d k r[ | | k r[ | S| d k r{ | |  j | | ƒ S| | k r› |  j d | ƒ | S|  j d | ƒ | |  j | | ƒ Sd S(   s  
        Returns the associative word obtained by replacing the subword of
        `self` that begins at position `from_i` and ends at position `to_j - 1`
        by the associative word `by`. `from_i` and `to_j` must be positive
        integers, indexing is done with origin 0. In other words,
        `w.substituted_word(w, from_i, to_j, by)` is the product of the three
        words: `w.subword(0, from_i)`, `by`, and
        `w.subword(to_j len(w))`.

        See Also
        ========

        eliminate_word

        s   values should be within boundsi    N(   R"   R   R„   (   R=   R™   Rš   R…   t   lw(    (    s>   lib/python2.7/site-packages/sympy/combinatorics/free_groups.pyt   substituted_word|  s    $c         C  s    |  s
 t  S|  d |  d d k S(   s  Returns whether the word is cyclically reduced or not.
        A word is cyclically reduced if by forming the cycle of the
        word, the word is not reduced, i.e a word w = `a_1 ... a_n`
        is called cyclically reduced if `a_1 \ne a_n^{âˆ’1}`.

        Examples
        ========

        >>> from sympy.combinatorics.free_groups import free_group
        >>> F, x, y = free_group("x, y")
        >>> (x**2*y**-1*x**-1).is_cyclically_reduced()
        False
        >>> (y*x**2*y**2).is_cyclically_reduced()
        True

        i    iÿÿÿÿ(   R   (   R=   (    (    s>   lib/python2.7/site-packages/sympy/combinatorics/free_groups.pyt   is_cyclically_reducedœ  s    c         C  sÀ   |  j  ƒ  } |  j } x¤ | j ƒ  s» | j d ƒ } | j d ƒ } | | } | d k ru | j d | j ƒ  d !} n4 | j d ƒ | | f f | j d | j ƒ  d !} | j | ƒ } q W| S(   sÀ  Return a unique cyclically reduced version of the word.

        Examples
        ========

        >>> from sympy.combinatorics.free_groups import free_group
        >>> F, x, y = free_group("x, y")
        >>> (x**2*y**2*x**-1).identity_cyclic_reduction()
        x*y**2
        >>> (x**-3*y**-1*x**5).identity_cyclic_reduction()
        x**2*y**-1

        References
        ==========

        http://planetmath.org/cyclicallyreduced

        i    iÿÿÿÿi   (   Ra   R!   R½   R¸   Rb   R·   R¹   R-   (   R=   R†   R!   t   exp1t   exp2Rg   t   rep(    (    s>   lib/python2.7/site-packages/sympy/combinatorics/free_groups.pyRª   ±  s    	
c   	      C  sÀ   |  j  ƒ  } |  j j } x‘ | j ƒ  s« t | j d ƒ ƒ } t | j d ƒ ƒ } t | | ƒ } | d t | ƒ } | d t | ƒ } | d | | d } | | } q W| r¼ | | f S| S(   s;  Return a cyclically reduced version of the word. Unlike
        `identity_cyclic_reduction`, this will not cyclically permute
        the reduced word - just remove the "unreduced" bits on either
        side of it. Compare the examples with those of
        `identity_cyclic_reduction`.

        When `removed` is `True`, return a tuple `(word, r)` where
        self `r` is such that before the reduction the word was either
        `r*word*r**-1`.

        Examples
        ========

        >>> from sympy.combinatorics.free_groups import free_group
        >>> F, x, y = free_group("x, y")
        >>> (x**2*y**2*x**-1).cyclic_reduction()
        x*y**2
        >>> (x**-3*y**-1*x**5).cyclic_reduction()
        y**-1*x**2
        >>> (x**-3*y**-1*x**5).cyclic_reduction(removed=True)
        (y**-1*x**2, x**-3)

        i    iÿÿÿÿ(   Ra   R!   RO   R½   R‰   R¸   R—   (	   R=   t   removedR†   RR   R¾   R¿   t   expRœ   t   end(    (    s>   lib/python2.7/site-packages/sympy/combinatorics/free_groups.pyt   cyclic_reductionÒ  s    
c   
      C  s6  |  j  r t St | ƒ } | d k rc |  j ƒ  } | | k pJ | d | k } t | ƒ d k ob | S|  j d t ƒ \ } } | j  s¹ | j d t ƒ \ } } | | k rµ | j | ƒ St St |  ƒ | k  sÛ t |  ƒ | rß t S|  j d | ƒ } | | k s| d | k r2|  j | t |  ƒ ƒ }	 |	 j | ƒ St S(   sG  
        Check if `self == other**n` for some integer n.

        Examples
        ========

        >>> from sympy.combinatorics.free_groups import free_group
        >>> F, x, y = free_group("x, y")
        >>> ((x*y)**2).power_of(x*y)
        True
        >>> (x**-3*y**-2*x**3).power_of(x**-3*y*x**3)
        True

        i   iÿÿÿÿRÁ   i    (   Rc   R   R"   R¢   RÄ   t   power_ofR?   R„   (
   R=   RJ   R‡   R:   R   t   reducedt   r1t   r2t   prefixt   rest(    (    s>   lib/python2.7/site-packages/sympy/combinatorics/free_groups.pyRÅ   ø  s(    		"N(;   R$   RU   RV   R   t   is_assoc_wordR_   R'   R*   RB   Ra   R]   Rc   Rb   Re   RI   RH   Rh   Ri   RA   RG   R\   Rp   Rt   Ru   Rv   t   __truediv__t   __rtruediv__Rx   Rm   RN   Ry   R?   R   R|   RC   RK   R   R‘   R’   R“   R”   R•   R„   Rƒ   RŸ   R‚   R¢   R§   R¨   R¶   R·   R¸   R¹   Rº   R¼   R½   Rª   RÄ   RÅ   (    (    (    s>   lib/python2.7/site-packages/sympy/combinatorics/free_groups.pyR   Z  sj   			"													;		#	0				 							!					 		!&c         C  sn  t  |  ƒ } g  } d } | j } xEt t | ƒ ƒ D]1} | t | ƒ d k r÷ | | | | d k r° | | | k r– | j | | | f ƒ qó | j | | | f ƒ nC | | | k rÜ | j | | d f ƒ n | j | | d f ƒ | S| | | | d k r| d 7} q5 | | | k rI| j | | | f ƒ n | j | | | f ƒ d } q5 Wd S(   s`  
    This method converts a list given with possible repetitions of elements in
    it. It returns a new list such that repetitions of consecutive elements is
    removed and replace with a tuple element of size two such that the first
    index contains `value` and the second index contains the number of
    consecutive repetitions of `value`.

    i   iÿÿÿÿN(   Rr   R   Rl   R"   R9   (   Rb   R!   RŒ   t	   new_arrayRn   R   R@   (    (    s>   lib/python2.7/site-packages/sympy/combinatorics/free_groups.pyR˜   %  s(    		c         C  s¼   xµ | d k r· | t  |  ƒ d k  r· |  | d |  | d d k r· |  | d |  | d d } |  | d } | | f |  | <|  | d =|  | d d k r |  | =| d 8} q q Wd S(   s"   Used to combine two reduced words.i    i   N(   R"   (   R‡   RH   RÂ   t   base(    (    s>   lib/python2.7/site-packages/sympy/combinatorics/free_groups.pyRs   I  s    EN(#   t
   __future__R    R   t
   sympy.coreR   t   sympy.core.compatibilityR   R   R   t   sympy.core.exprR   t   sympy.core.symbolR   R   R   t   sympy.core.sympifyR	   t   sympy.printing.defaultsR
   t   sympy.utilitiesR   t   sympy.utilities.iterablesR   t   sympy.utilities.magicR   R   R   R   R    R%   R   R   R   R˜   Rs   (    (    (    s>   lib/python2.7/site-packages/sympy/combinatorics/free_groups.pyt   <module>   s*   	çÿ ÿ ÿ Î	$