
    \h<                       % S SK Jr  S SKJr  S SKJr  S SKJrJr	  S SK
Jr  S SKJr  S SKJr  S SKJrJr  S S	KJr  S S
KJr  \S 5       r\S 5       r\S 5       rS r0 rS\S'    " S S\5      r " S S\\\5      rS r S r!g)    )annotations)S)Expr)Symbolsymbols)CantSympify)DefaultPrinting)public)flattenis_sequence)pollute)as_intc                J    [        U 5      nU4[        UR                  5      -   $ )a  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 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'>

)	FreeGrouptuple
generatorsr   _free_groups     W/var/www/auris/envauris/lib/python3.13/site-packages/sympy/combinatorics/free_groups.py
free_groupr      s&    , G$K>E+"8"8999    c                2    [        U 5      nXR                  4$ )a  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   s     r   xfree_groupr   '   s    , G$K//00r   c                    [        U 5      n[        UR                   Vs/ s H  o"R                  PM     snUR                  5        U$ s  snf )a  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 # noqa: F821
x**2*y**-2*z
>>> type(_)
<class 'sympy.combinatorics.free_groups.FreeGroupElement'>

)r   r   r   namer   )r   r   syms      r   vfree_groupr   @   sB    , G$K!4!45!4#XX!45{7M7MN 6s   Ac                8   U (       d  g[        U [        5      (       a
  [        U SS9$ [        U [        [        45      (       a  U 4$ [        U 5      (       a;  [        S U  5       5      (       a  [        U 5      $ [        S U  5       5      (       a  U $ [        S5      e)N T)seqc              3  B   #    U  H  n[        U[        5      v   M     g 7fN)
isinstancestr.0ss     r   	<genexpr>!_parse_symbols.<locals>.<genexpr>c   s     37az!S!!7   c              3  B   #    U  H  n[        U[        5      v   M     g 7fr"   )r#   r   r%   s     r   r(   r)   e   s     6gAt$$gr*   zjThe type of `symbols` must be one of the following: a str, Symbol/Expr or a sequence of one of these types)r#   r$   _symbolsr   FreeGroupElementr   all
ValueErrorr   s    r   _parse_symbolsr1   [   s    '3T**	Gd$45	6	6z	W		37333G$$6g666N
 * + +r   zdict[int, FreeGroup]_free_group_cachec                      \ rS rSr% SrSrSrSrSr/ r	S\
S'   S rS rS	 rS
 rSS jrS rS rS rS r\rS rS rS rS r\S 5       r\S 5       r\S 5       r\S 5       rS rS rSr g)r   r   aV  
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] https://www.gap-system.org/Manuals/doc/ref/chap37.html

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

TFz
list[Expr]relatorsc                f   [        [        U5      5      n[        U5      n[        U R                  X45      n[
        R                  U5      nUc  [        R                  U 5      nX4l	        X$l
        [        S[        4SU05      Ul        Xl        UR                  5       Ul        [#        UR                   5      Ul        ['        UR                  UR                   5       HF  u  pV[)        U[*        5      (       d  M  UR,                  n[/        XG5      (       d  M:  [1        XGU5        MH     U[
        U'   U$ )Nr-   group)r   r1   lenhash__name__r2   getobject__new___hash_ranktyper-   dtyper   _generatorsr   set	_gens_setzipr#   r   r   hasattrsetattr)clsr   rankr>   objsymbol	generatorr   s           r   r=   FreeGroup.__new__   s    w/07|cllG23##E*;..%CII/2B1DwPSnUCI!K __.CN/CM%(cnn%E!ff--!;;Ds))95	 &F (+e$
r   c                    U R                   4$ )zdReturn a tuple of arguments that must be passed to __new__ in order to support pickling this object.r0   selfs    r   __getnewargs__FreeGroup.__getnewargs__   s    r   c                    g r"   r   rO   s    r   __getstate__FreeGroup.__getstate__   s    r   c                    / nU R                    H(  nUS44nUR                  U R                  U5      5        M*     [        U5      $ )zReturns the generators of the FreeGroup.

Examples
========

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

   )r   appendrA   r   )r7   gensr   elms       r   rB   FreeGroup._generators   sC     ==C8+CKKC() ! T{r   Nc                J    U R                  U=(       d    U R                  5      $ r"   )	__class__r   )rP   r   s     r   cloneFreeGroup.clone   s    ~~g566r   c                N    [        U[        5      (       d  gUR                  nX:H  $ )z/Return True if ``i`` is contained in FreeGroup.Fr#   r-   r7   )rP   ir7   s      r   __contains__FreeGroup.__contains__   s$    !-..}r   c                    U R                   $ r"   r>   rO   s    r   __hash__FreeGroup.__hash__   s    zzr   c                    U R                   $ r"   rI   rO   s    r   __len__FreeGroup.__len__   s    yyr   c                    U R                   S:  a  SU R                   -  nU$ SnU R                  nU[        U5      S-   -  nU$ )N   z<free group with %s generators>z<free group on the generators >)rI   r   r$   )rP   str_formrY   s      r   __str__FreeGroup.__str__   sI    99r>8499DH
  8H??DD	C'Hr   c                >    U R                   U   nU R                  US9$ )Nr0   )r   r^   )rP   indexr   s      r   __getitem__FreeGroup.__getitem__   s!    ,,u%zz'z**r   c                    XL $ )z@No ``FreeGroup`` is equal to any "other" ``FreeGroup``.
        r   rP   others     r   __eq__FreeGroup.__eq__   s     }r   c                    [        XR                  5      (       a  U R                  R                  U5      $ [	        SU < SU< 35      e)zReturn the index of the generator `gen` from ``(f_0, ..., f_(n-1))``.

Examples
========

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

z#expected a generator of Free Group z, got )r#   rA   r   rt   r/   rP   gens     r   rt   FreeGroup.index   s:     c::&&??((--PTVYZ[[r   c                b    U R                   S:X  a  [        R                  $ [        R                  $ )zReturn the order of the free group.

Examples
========

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

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

r   )rI   r   OneInfinityrO   s    r   orderFreeGroup.order   s"     99>55L::r   c                R    U R                   S:X  a  U R                  1$ [        S5      e)z
Return the elements of the free group.

Examples
========

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

r   zDGroup contains infinitely many elements, hence cannot be represented)rI   identityr/   rO   s    r   elementsFreeGroup.elements	  s-     99>MM?" < = =r   c                    U R                   $ )z
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?   rO   s    r   rI   FreeGroup.rank  s     zzr   c                     U R                   S;   $ )zReturns if the group is Abelian.

Examples
========

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

)r   rW   rj   rO   s    r   
is_abelianFreeGroup.is_abelian*  s     yyF""r   c                "    U R                  5       $ )z+Returns the identity element of free group.)rA   rO   s    r   r   FreeGroup.identity9  s     zz|r   c                P    [        U[        5      (       d  gXR                  :w  a  gg)a!  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 import free_group
>>> f, x, y, z = free_group("x y z")
>>> f.contains(x**3*y**2)
True

FTra   )rP   gs     r   containsFreeGroup.contains>  s$     !-..WW_r   c                    U R                   1$ )z,Returns the center of the free group `self`.)r   rO   s    r   centerFreeGroup.centerT  s    r   r   r"   )!r:   
__module____qualname____firstlineno____doc__is_associativeis_groupis_FreeGroupis_PermutationGroupr5   __annotations__r=   rQ   rT   rB   r^   rc   rg   rk   rq   __repr__ru   rz   rt   r   propertyr   rI   r   r   r   r   __static_attributes__r   r   r   r   r   r   s    $ NHLHj2$7 H+
\&( = =( 	 	 # #  ,r   r   c                     \ rS rSrSrSrSrS rSrS r	S r
\S	 5       r\S
 5       r\S 5       rS rS r\S 5       r\S 5       rS rS r\rS rS rS rS rS rS rS rS rS6S jrS7S jrS r S r!S r"S r#S  r$S! r%S" r&S# r'S8S$ jr(S9S% jr)S& r*S' r+S( r,S) r-S* r.S+ r/S, r0S- r1S. r2S/ r3S0 r4S1 r5S2 r6S:S3 jr7S4 r8S5r9g);r-   i^  zUsed to create elements of FreeGroup. It cannot be used directly to
create a free group element. It is called by the `dtype` method of the
`FreeGroup` class.

r   Tc                $    U R                  U5      $ r"   )r]   )rP   inits     r   newFreeGroupElement.newg  s    ~~d##r   Nc                    U R                   nUc0  [        U R                  [        [	        U 5      5      45      =U l         nU$ r"   )r>   r9   r7   	frozensetr   )rP   r>   s     r   rg   FreeGroupElement.__hash__l  s8    

=!%tzz9U4[3I&J!KKDJr   c                $    U R                  U 5      $ r"   )r   rO   s    r   copyFreeGroupElement.copyr  s    xx~r   c                $    U R                   (       + $ r"   
array_formrO   s    r   is_identityFreeGroupElement.is_identityu  s    ??""r   c                    [        U 5      $ )aC  
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) do not 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 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   rO   s    r   r   FreeGroupElement.array_formy  s    @ T{r   c           
         [        [        U R                   VVs/ s H  u  pUS:  a  U4U-  OU* 4U* -  PM     snn5      5      $ s  snnf )a  
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 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

r   r   r   r   )rP   rb   js      r   letter_formFreeGroupElement.letter_form  sY    4 W $1 / )*Aqd1fQB51":= /1 2 3 	3 1s    Ac                    U R                   nU R                  U   nUR                  (       a  UR                  US445      $ UR                  U* S445      $ )NrW   r7   r   	is_SymbolrA   )rP   rb   r7   rs       r   ru   FreeGroupElement.__getitem__  sN    

Q;;;;Ay));;!R{++r   c                    [        U5      S:w  a
  [        5       eU R                  R                  UR                  S   5      $ )NrW   r   )r8   r/   r   rt   r}   s     r   rt   FreeGroupElement.index  s5    s8q=,  ''(:;;r   c                    U R                   nU R                  nU Vs/ s H=  nUR                  (       a  UR                  US445      OUR                  U* S445      PM?     sn$ s  snf )z	
        rW   r   r   )rP   r7   r   rZ   s       r   letter_form_elm FreeGroupElement.letter_form_elm  sk     

:;=:;3 ,/==c!WJ'[[C4)./:;= 	= =s   AA$c                >    [        [        U R                  5      5      $ )zKThis is called the External Representation of ``FreeGroupElement``
        r   rO   s    r   ext_repFreeGroupElement.ext_rep  s     WT__-..r   c                    UR                   S   S   [        U R                    Vs/ s H  o"S   PM	     sn5      ;   $ s  snf )Nr   )r   r   )rP   r~   r   s      r   rc   FreeGroupElement.__contains__  s8    ~~a #uDOO-LOqdO-L'MMM-Ls   <
c                   U R                   (       a  gSnU R                  n[        [        U5      5       H  nU[        U5      S-
  :X  aI  X#   S   S:X  a  U[	        X#   S   5      -  nM5  U[	        X#   S   5      S-   [	        X#   S   5      -   -  nM^  X#   S   S:X  a  U[	        X#   S   5      S-   -  nM  U[	        X#   S   5      S-   [	        X#   S   5      -   S-   -  nM     U$ )Nz
<identity> rW   r   z***)r   r   ranger8   r$   )rP   rp   r   rb   s       r   rq   FreeGroupElement.__str__  s   __
s:'AC
Oa''=#q(JM!$4 55HJM!$4 5$(!)+.z}Q/?+@!A AH =#q(JM!$4 5 ;;HJM!$4 5$(!)+.z}Q/?+@!ACF!G GH ( r   c                    [        U5      nU R                  R                  nUS:X  a  U$ US:  a  U* nU R                  5       nOU n US-  (       a  X#-  nUS-  nU(       d   U$ X3-  nM#  )Nr      rW   )r   r7   r   inverse)rP   nresultxs       r   __pow__FreeGroupElement.__pow__  sw    1I$$6Mq5AAA1u!GA FA r   c                l   U R                   n[        XR                  5      (       d  [        S5      eU R                  (       a  U$ UR                  (       a  U $ [        U R                  UR                  -   5      n[        U[        U R                  5      S-
  5        UR                  [        U5      5      $ )zReturns the product of elements belonging to the same ``FreeGroup``.

Examples
========

>>> from sympy.combinatorics 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>

;only FreeGroup elements of same FreeGroup can be multipliedrW   )
r7   r#   rA   	TypeErrorr   listr   zero_mul_simpr8   r   )rP   ry   r7   r   s       r   __mul__FreeGroupElement.__mul__  s      

%-- $ % %LK5#3#334aT__-12{{58$$r   c                    U R                   n[        XR                  5      (       d  [        S5      eXR	                  5       -  $ Nr   r7   r#   rA   r   r   rP   ry   r7   s      r   __truediv__FreeGroupElement.__truediv__  s;    

%-- $ % %]]_%%r   c                    U R                   n[        XR                  5      (       d  [        S5      eXR	                  5       -  $ r   r   r   s      r   __rtruediv__FreeGroupElement.__rtruediv__$  s;    

%-- $ % %lln%%r   c                    [         $ r"   )NotImplementedrx   s     r   __add__FreeGroupElement.__add__+  s    r   c                    U R                   n[        U R                  SSS2    VVs/ s H	  u  p#X#* 4PM     snn5      nUR                  U5      $ s  snnf )z
Returns the inverse of a ``FreeGroupElement`` element

Examples
========

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

Nr   )r7   r   r   rA   )rP   r7   rb   r   r   s        r   r   FreeGroupElement.inverse.  sN     

ttt'<='<tqAr7'<=>{{1~ >s   A
c                d    U R                   (       a  [        R                  $ [        R                  $ )zFind the order of a ``FreeGroupElement``.

Examples
========

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

)r   r   r   r   rO   s    r   r   FreeGroupElement.orderA  s      55L::r   c                    U R                   n[        XR                  5      (       d  [        S5      eU R	                  5       UR	                  5       -  U -  U-  $ )z?
Return the commutator of `self` and `x`: ``~x*~self*x*self``

z@commutator of only FreeGroupElement of the same FreeGroup exists)r7   r#   rA   r/   r   r   s      r   
commutatorFreeGroupElement.commutatorR  sQ    
 

%-- ' ( ( <<>%--/1$6u<<r   c                   SnU n[        U[        5      (       a;  U(       a2  SnU H!  nUnUR                  XaU   X#S9nXW:w  d  M  SnM#     U(       a  M2  U$ U(       a/  SnU H  nUnUR                  XbUS9nXW:w  d  M  SnM      U(       a  M/  U$ )z}
Replace each subword from the dictionary `words` by words[subword].
If words is a list, replace the words by the identity.

TF_allr   )r#   dicteliminate_word)rP   wordsr   r   againr   subprevs           r   eliminate_words FreeGroupElement.eliminate_words^  s     eT"" CD,,S*4,YC{ $	 ! % 
  CD,,SW,MC{ $	 ! % 
r   c                   Uc  U R                   R                  nU R                  U5      (       d  X:X  a  U $ X:X  a  U$ US-  U:X  a  SnU n[        U5      n UR	                  U5      nSnUR                  SU5      X(-  -  UR                  Xv-   [        U5      5      R                  X5      -  nU(       a  UR                  XSUS9$ U$ ! [
         a9    U(       d  Us $  UR	                  US-  5      nSn N! [
         a    Us s $ f = ff = f)a  
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 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

r   FrW   r   Tr   )r7   r   is_independentr8   subword_indexr/   subwordr   )	rP   r~   byr   r   wordlrb   ks	            r   r   FreeGroupElement.eliminate_wordx  s   : :$$Bs##syK;I7b=DH
	""3'AA ||Aq!"%'QS#d)(D(S(STW(\\&&sT7&KKK  	&&sBw/ 	s*   C DC66DDDDc                &    [        S U  5       5      $ )z
For an associative word `self`, returns the number of letters in it.

Examples
========

>>> from sympy.combinatorics 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              3  <   #    U  H  u  p[        U5      v   M     g 7fr"   abs)r&   rb   r   s      r   r(   +FreeGroupElement.__len__.<locals>.<genexpr>  s     -fq3q66s   )sumrO   s    r   rk   FreeGroupElement.__len__  s    $ ----r   c                z    U R                   n[        XR                  5      (       d  g[        R	                  X5      $ )a  
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 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

F)r7   r#   rA   r   rz   r   s      r   rz   FreeGroupElement.__eq__  s.    < 

%--||D((r   c                   U R                   n[        XR                  5      (       d  [        S5      e[	        U 5      n[	        U5      nX4:  a  gX4:  a  g[        U5       H  nX   R                  S   nX   R                  S   nUR                  R                  US   5      nUR                  R                  US   5      n	X:  a    gX:  a    gUS   US   :  a    gUS   US   :  d  M    g   g)a  
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 import free_group
>>> f, a, b = free_group("a b")
>>> b < a
False
>>> a < a.inverse()
False

9only FreeGroup elements of same FreeGroup can be comparedTFr   rW   )	r7   r#   rA   r   r8   r   r   r   rt   )
rP   ry   r7   r  mrb   abpqs
             r   __lt__FreeGroupElement.__lt__  s    , 

%-- + , ,IJ5UqA""1%A##A&A##AaD)A##AaD)Au1!1!  r   c                     X:H  =(       d    X:  $ r"   r   rx   s     r   __le__FreeGroupElement.__le__  s    -.r   c                n    U R                   n[        XR                  5      (       d  [        S5      eX::  + $ )z

Examples
========

>>> from sympy.combinatorics 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

r  )r7   r#   rA   r   r   s      r   __gt__FreeGroupElement.__gt__  s7      

%-- + , ,  r   c                    X:  + $ r"   r   rx   s     r   __ge__FreeGroupElement.__ge__3  s    r   c                   ^ [        U5      S:w  a  [        S5      eUR                  S   mTS   [        U4S jU R                   5       5      -  $ )a  
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 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

rW   z1gen must be a generator or inverse of a generatorr   c              3  H   >#    U  H  oS    TS    :X  d  M  US   v   M     g7fr   rW   Nr   r&   rb   r'   s     r   r(   0FreeGroupElement.exponent_sum.<locals>.<genexpr>T  s#     Fo11!os   "")r8   r/   r   r  rP   r~   r'   s     @r   exponent_sumFreeGroupElement.exponent_sum6  sH    6 s8q=PQQNN1tCFdooFFFFr   c                   ^ [        U5      S:w  d  UR                  S   S   S:  a  [        S5      eUR                  S   mTS   [        U4S jU R                   5       5      -  $ )ah  
For an associative word `self` and a generator `gen`,
``generator_count`` returns the multiplicity of generator
`gen` in `self`.

Examples
========

>>> from sympy.combinatorics 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

rW   r   zgen must be a generatorc              3  Z   >#    U  H   oS    TS    :X  d  M  [        US   5      v   M"     g7fr#  r  r$  s     r   r(   3FreeGroupElement.generator_count.<locals>.<genexpr>q  s)     K?adadl	AaD		?s   ++)r8   r   r/   r  r&  s     @r   generator_count FreeGroupElement.generator_countV  s]    0 s8q=CNN1-a014677NN1tCK4??KKKKr   c                    U R                   nU(       d!  [        US5      n[        [        U 5      U5      nUS:  d  U[        U 5      :  a  [	        S5      eX!::  a  UR
                  $ U R                  X n[        XT5      nUR                  U5      $ )ak  
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 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

r   zT`from_i`, `to_j` must be positive and no greater than the length of associative word)	r7   maxminr8   r/   r   r   letter_form_to_array_formrA   )rP   from_ito_jstrictr7   r   r   s          r   r   FreeGroupElement.subwords  s      

^Fs4y$'DA:D	) 5 6 6>>>!**68K2;FJ;;z**r   c                    [        U5      nU R                  nUR                  nSn[        U[        U5      U-
  S-   5       H  nXGXs-    U:X  d  M  Un  O   Ub  U$ [        S5      e)z
Find the index of `word` in `self`.

Examples
========

>>> from sympy.combinatorics 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

NrW   z'The given word is not a subword of self)r8   r   r   r/   )rP   r  startr  self_lfword_lfrt   rb   s           r   r   FreeGroupElement.subword_index  su     I""""uS\!^A-.A~( / LFGGr   c                     U R                  U5      SL$ ! [         a     Of = f U R                  US-  5      SL$ ! [         a     gf = f)a3  
Examples
========

>>> from sympy.combinatorics 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

Nr   F)r   r/   rP   r  s     r   is_dependentFreeGroupElement.is_dependent  s`    ,	%%d+477 			%%dBh/t;; 		s    
""< 
A	A	c                .    U R                  U5      (       + $ )z#

See Also
========

is_dependent

)r=  r<  s     r   r   FreeGroupElement.is_independent  s     $$T***r   c                    U R                   nU R                   Vs1 s H  o!R                  US   S445      iM     nnU$ s  snf )z
Examples
========

>>> from sympy.combinatorics 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}

r   rW   )r7   r   rA   )rP   r7   syllablerY   s       r   contains_generators$FreeGroupElement.contains_generators  sC     

AEQXhqk1-/0Q Rs    ?c                   U R                   n[        U 5      nU R                  n[        X-  5      nX:  a  XU-  -  nX$U-  -  nX!-
  nXQU n[        X$-  5      S-
  n	XU	-  US Xt-
  U-   XI-  -
   -   -  n[	        X5      nUR                  U5      $ )NrW   )r7   r8   r   intr1  rA   )
rP   r2  r3  r7   r  r   period1diffr  period2s
             r   cyclic_subwordFreeGroupElement.cyclic_subword  s    

I&&fh-;iFgID}4(df+/G#k2J46&=3J&KKK(5{{4  r   c           
         [        [        U 5      5       Vs1 s H  oR                  X[        U 5      -   5      iM!     sn$ s  snf )a  Returns a words which are cyclic to the word `self`.

Examples
========

>>> from sympy.combinatorics 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
==========

.. [1] https://planetmath.org/cyclicpermutation

)r   r8   rJ  rP   rb   s     r   cyclic_conjugates"FreeGroupElement.cyclic_conjugates  s9    * >C3t9=MN=M##AT{3=MNNNs   &A c                l   [        U 5      n[        U5      nX#:w  a  gU R                  5       nUR                  5       nUR                  nUR                  nSR                  [	        [
        U5      5      nSR                  [	        [
        U5      5      n	[        U5      [        U	5      :w  a  gXS-   U	-   ;   $ )a*  
Checks whether words ``self``, ``w`` are cyclic conjugates.

Examples
========

>>> from sympy.combinatorics 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

F )r8   identity_cyclic_reductionr   joinmapr$   )
rP   wl1l2w1w2letter1letter2str1str2s
             r   is_cyclic_conjugate$FreeGroupElement.is_cyclic_conjugate  s    $ YV8++-((*....xxC)*xxC)*t9D	!czD(((r   c                ,    [        U R                  5      $ )zReturns the number of syllables of the associative word `self`.

Examples
========

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

)r8   r   rO   s    r   number_syllables!FreeGroupElement.number_syllables.  s     4??##r   c                &    U R                   U   S   $ )z
Returns the exponent of the `i`-th syllable of the associative word
`self`.

Examples
========

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

rW   r   rM  s     r   exponent_syllable"FreeGroupElement.exponent_syllable<       q!!$$r   c                &    U R                   U   S   $ )a  
Returns the symbol of the generator that is involved in the
i-th syllable of the associative word `self`.

Examples
========

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

r   r   rM  s     r   generator_syllable#FreeGroupElement.generator_syllableM  rf  r   c                    [        U[        5      (       a  [        U[        5      (       d  [        S5      eU R                  nX!::  a  UR                  $ [        U R                  X 5      nUR                  U5      $ )a  
`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 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>

z!both arguments should be integers)r#   rF  r/   r7   r   r   r   rA   )rP   r2  r3  r7   r   s        r   sub_syllablesFreeGroupElement.sub_syllables^  sb    & &#&&js.C.C@AA

>>>!doof34A;;q>!r   c                   [        U 5      nX:  d
  X:  d  X$:  a  [        S5      eUS:X  a  X$:X  a  U$ US:X  a  X0R                  X$5      -  $ X$:X  a  U R                  SU5      U-  $ U R                  SU5      U-  U R                  X$5      -  $ )a  
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

zvalues should be within boundsr   )r8   r/   r   )rP   r2  r3  r  lws        r   substituted_word!FreeGroupElement.substituted_wordz  s      Y>V[DI=>>
 Q;4:Iq[ll4,,,Z<<6*2--<<6*2-dll4.DDDr   c                .    U (       d  gU S   U S   S-  :g  $ )a  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 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

Tr   r   r   rO   s    r   is_cyclically_reduced&FreeGroupElement.is_cyclically_reduced  s!    " Aw$r(B,&&r   c                   U R                  5       nU R                  nUR                  5       (       d  UR                  S5      nUR                  S5      nX4-   nUS:X  a!  UR                  SUR                  5       S-
   nO7UR                  S5      X4-   44UR                  SUR                  5       S-
   -   nUR                  U5      nUR                  5       (       d  M  U$ )a\  Return a unique cyclically reduced version of the word.

Examples
========

>>> from sympy.combinatorics 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
==========

.. [1] https://planetmath.org/cyclicallyreduced

r   r   rW   )r   r7   rr  rd  r   ra  rh  rA   )rP   r  r7   exp1exp2r   reps          r   rR  *FreeGroupElement.identity_cyclic_reduction  s    & yy{

,,..))!,D))"-DAAvooa)>)>)@1)DE//2DK@B4+@+@+BQ+FGH;;s#D ,,.. r   c                   U R                  5       nU R                  R                  nUR                  5       (       d  [	        UR                  S5      5      n[	        UR                  S5      5      n[        XE5      nUS   [	        U5      -  nUS   [	        U5      -  nUS-  U-  US-  -  nX7-  nUR                  5       (       d  M  U(       a  X#4$ U$ )a  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 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)

r   r   )r   r7   r   rr  r	  rd  r0  )	rP   removedr  r   ru  rv  expr7  ends	            r   cyclic_reduction!FreeGroupElement.cyclic_reduction  s    0 yy{JJ,,..t--a01Dt--b12Dd/CGSX%Er(CH$C"9T>#r')DA ,,.. 7Nr   c                0   U R                   (       a  g[        U5      nUS:X  a:  U R                  5       nX;   =(       d    US-  U;   n[        U5      S:H  =(       a    U$ U R                  SS9u  pVUR                   (       d(  UR                  SS9u  pXg:X  a  UR	                  U5      $ g[        U 5      U:  d  [        U 5      U-  (       a  gU R                  SU5      nX:X  d	  US-  U:X  a,  U R                  U[        U 5      5      n	U	R	                  U5      $ g)z
Check if `self == other**n` for some integer n.

Examples
========

>>> from sympy.combinatorics 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

TrW   r   )rz  Fr   )r   r8   rC  r}  power_ofr   )
rP   ry   r  rY   r'   reducedr1r2prefixrests
             r   r  FreeGroupElement.power_of  s     J6++-D2d!2At9>'a'
 ++D+9~~..t.<IEx''..t9q=CIMa#?fbjE1<<3t9-D==''r   rf   )FT)NFT)T)r   )F):r:   r   r   r   r   	__slots__is_assoc_wordr   r>   rg   r   r   r   r   r   ru   rt   r   r   rc   rq   r   r   r   r   r   r   r   r   r   r   r   rk   rz   r  r  r  r  r'  r,  r   r   r=  r   rC  rJ  rN  r^  ra  rd  rh  rk  ro  rr  rR  r}  r  r   r   r   r   r-   r-   ^  sf   
 IM$ E # #  B 3 38,<
 = = / /
N* H&%8&&&"
=49v.(!)F.`/!, G@L:+<H6>	+"!O.)B$%"%""8E@'*B$L*r   r-   c                @   [        U SS 5      n/ nSnUR                  n[        [        U5      5       H  nU[        U5      S-
  :X  a  X&   X&S-
     :X  a>  X&   * U;   a  UR	                  X&   * U* 45        Us  $ UR	                  X&   U45         Us  $ X&   * U;   a  UR	                  X&   * S45        Us  $ UR	                  X&   S45        Us  $ X&   X&S-      :X  a  US-  nM  X&   * U;   a  UR	                  X&   * U* 45        OUR	                  X&   U45        SnM     g)aH  
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`.

NrW   r   )r   r   r   r8   rX   )r   r7   r  	new_arrayr   r   rb   s          r   r1  r1  #  s>    	Z]AI	AmmG3q6]A
?tqQxTEg%$$qteaR[1  $$adAY/ 	 TEg%$$qteR[1  $$adAY/TQ1uXFA'!  14%!-  !$+A) r   c                (   US:  a  U[        U 5      S-
  :  ay  X   S   XS-      S   :X  ae  X   S   XS-      S   -   nX   S   nX24X'   XS-   	 X   S   S:X  a  X	 US-  nUS:  a)  U[        U 5      S-
  :  a  X   S   XS-      S   :X  a  Mb  gggggg)z"Used to combine two reduced words.r   rW   N)r8   )r  rt   r{  bases       r   r   r   G  s    
!)A
*qx{a	l1o/MhqkAaiLO+x{;aiL8A;!QJE !)A
*qx{a	l1o/M*)/M*)r   N)"
__future__r   
sympy.corer   sympy.core.exprr   sympy.core.symbolr   r   r,   sympy.core.sympifyr   sympy.printing.defaultsr	   sympy.utilitiesr
   sympy.utilities.iterablesr   r   sympy.utilities.magicr   sympy.utilities.miscr   r   r   r   r1   r2   r   r   r   r-   r1  r   r   r   r   <module>r     s    "    9 * 3 " : ) ' : :0 1 10  4+* +- ' ,d dXB{OU BJ!H	r   