+
    iS                     b    ^ RI Ht ^ RIHt ^ RIHt ^ RIHt  ! R R]4      t ! R R]4      t	R	# )
    isprime)PermutationGroup)DefaultPrinting)
free_groupc                   >   a  ] tR t^t o RtRtRR ltR tR tRt	V t
R# )PolycyclicGroupTNc                    Wn         W n        W0n        V'       g   \        V P                   W#4      V n        R# TV n        R# )a  

Parameters
==========

pc_sequence : list
    A sequence of elements whose classes generate the cyclic factor
    groups of pc_series.
pc_series : list
    A subnormal sequence of subgroups where each factor group is cyclic.
relative_order : list
    The orders of factor groups of pc_series.
collector : Collector
    By default, it is None. Collector class provides the
    polycyclic presentation with various other functionalities.

N)pcgs	pc_seriesrelative_order	Collector	collector)selfpc_sequencer   r   r   s   &&&&&[/var/www/html/photoedit/myenv/lib/python3.14/site-packages/sympy/combinatorics/pc_groups.py__init__PolycyclicGroup.__init__   s/    $  	",PY499iH_h    c                    \         ;QJ d&    R  V P                   4       F  '       d   K   R# 	  R# ! R  V P                   4       4      # )c              3   8   "   T F  p\        V4      x  K  	  R # 5iNr   ).0orders   & r   	<genexpr>1PolycyclicGroup.is_prime_order.<locals>.<genexpr>$   s     C/Be75>>/Bs   FT)allr   r   s   &r   is_prime_orderPolycyclicGroup.is_prime_order#   s7    sCt/B/BCssCsCsCt/B/BCCCr   c                ,    \        V P                  4      # r   )lenr   r   s   &r   lengthPolycyclicGroup.length&   s    499~r   )r   r   r   r   r   )__name__
__module____qualname____firstlineno__is_groupis_solvabler   r   r#   __static_attributes____classdictcell____classdict__s   @r   r	   r	      s%     HKi.D r   r	   c                   v   a  ] tR t^*t o RtRR ltR tR tR tR t	R t
R	 tR
 tR tR tR tR tR tRtV tR# )r   z
References
==========

.. [1] Holt, D., Eick, B., O'Brien, E.
       "Handbook of Computational Group Theory"
       Section 8.1.3
Nc                B   Wn         W n        W0n        V'       g+   \        RP	                  \        V4      4      4      ^ ,          MTV n        \        V P                  P                  4       UUu/ uF  w  rgWvbK	  	  uppV n        V P                  4       V n
        R# u uppi )a  

Most of the parameters for the Collector class are the same as for PolycyclicGroup.
Others are described below.

Parameters
==========

free_group_ : tuple
    free_group_ provides the mapping of polycyclic generating
    sequence with the free group elements.
pc_presentation : dict
    Provides the presentation of polycyclic groups with the
    help of power and conjugate relators.

See Also
========

PolycyclicGroup

zx:{}N)r   r   r   r   formatr"   	enumeratesymbolsindexpc_relatorspc_presentation)r   r   r   r   free_group_r6   iss   &&&&&&  r   r   Collector.__init__5   sy    , 	",IT*V]]3t9%=>qAZe'01H1H'IJ'Itqad'IJ
#//1 Ks   .Bc                   V'       g   R# VP                   pV P                  pV P                  p\        \	        V4      4       FK  pW%,          w  rgW4V,          ,          '       g   K$  V^ 8  g   WsWF,          ,          ^,
          8  g   KG  Wg33u # 	  \        \	        V4      ^,
          4       FD  pW%,          w  rgW%^,           ,          w  rWF,          WH,          8  g   K3  V	^ 8  d   ^MRp
Wg3W33u # 	  R# )a  
Returns the minimal uncollected subwords.

Explanation
===========

A word ``v`` defined on generators in ``X`` is a minimal
uncollected subword of the word ``w`` if ``v`` is a subword
of ``w`` and it has one of the following form

* `v = {x_{i+1}}^{a_j}x_i`

* `v = {x_{i+1}}^{a_j}{x_i}^{-1}`

* `v = {x_i}^{a_j}`

for `a_j` not in `\{1, \ldots, s-1\}`. Where, ``s`` is the power
exponent of the corresponding generator.

Examples
========

>>> from sympy.combinatorics.named_groups import SymmetricGroup
>>> from sympy.combinatorics import free_group
>>> G = SymmetricGroup(4)
>>> PcGroup = G.polycyclic_group()
>>> collector = PcGroup.collector
>>> F, x1, x2 = free_group("x1, x2")
>>> word = x2**2*x1**7
>>> collector.minimal_uncollected_subword(word)
((x2, 2),)

N)
array_formr   r4   ranger"   )r   wordarrayrer4   r8   s1e1s2e2es   &&         r   minimal_uncollected_subword%Collector.minimal_uncollected_subwordR   s    F   

s5z"AXFB)}}"q&BEIq,@|#	 # s5z!|$AXFBQ3ZFBy59$aAR2'** % r   c                    / p/ pV P                   P                  4        F)  w  r4\        VP                  4      ^8X  d   WAV&   K%  WBV&   K+  	  W3# )a	  
Separates the given relators of pc presentation in power and
conjugate relations.

Returns
=======

(power_rel, conj_rel)
    Separates pc presentation into power and conjugate relations.

Examples
========

>>> from sympy.combinatorics.named_groups import SymmetricGroup
>>> G = SymmetricGroup(3)
>>> PcGroup = G.polycyclic_group()
>>> collector = PcGroup.collector
>>> power_rel, conj_rel = collector.relations()
>>> power_rel
{x0**2: (), x1**3: ()}
>>> conj_rel
{x0**-1*x1*x0: x1**2}

See Also
========

pc_relators

)r6   itemsr"   r=   )r   power_relatorsconjugate_relatorskeyvalues   &    r   	relationsCollector.relations   sV    < ..446JC3>>"a'&+s#*/3'	 7
 11r   c                    RpRp\        \        V4      \        V4      ,
          ^,           4       FA  pVP                  WU\        V4      ,           4      V8X  g   K+  TpV\        V4      ,           p W43# 	  W43# )a|  
Returns the start and ending index of a given
subword in a word.

Parameters
==========

word : FreeGroupElement
    word defined on free group elements for a
    polycyclic group.
w : FreeGroupElement
    subword of a given word, whose starting and
    ending index to be computed.

Returns
=======

(i, j)
    A tuple containing starting and ending index of ``w``
    in the given word. If not exists, (-1,-1) is returned.

Examples
========

>>> from sympy.combinatorics.named_groups import SymmetricGroup
>>> from sympy.combinatorics import free_group
>>> G = SymmetricGroup(4)
>>> PcGroup = G.polycyclic_group()
>>> collector = PcGroup.collector
>>> F, x1, x2 = free_group("x1, x2")
>>> word = x2**2*x1**7
>>> w = x2**2*x1
>>> collector.subword_index(word, w)
(0, 3)
>>> w = x1**7
>>> collector.subword_index(word, w)
(2, 9)
>>> w = x1**8
>>> collector.subword_index(word, w)
(-1, -1)

r<   )r>   r"   subword)r   r?   wlowhighr8   s   &&&   r   subword_indexCollector.subword_index   sp    V s4yQ')*A||AQx(A-Qxy +
 yr   c                    VP                   pV^ ,          ^ ,          pV^,          ^ ,          pVR3V^3V^33pV P                  P                  V4      pV P                  V,          # )aW  
Return a conjugate relation.

Explanation
===========

Given a word formed by two free group elements, the
corresponding conjugate relation with those free
group elements is formed and mapped with the collected
word in the polycyclic presentation.

Examples
========

>>> from sympy.combinatorics.named_groups import SymmetricGroup
>>> from sympy.combinatorics import free_group
>>> G = SymmetricGroup(3)
>>> PcGroup = G.polycyclic_group()
>>> collector = PcGroup.collector
>>> F, x0, x1 = free_group("x0, x1")
>>> w = x1*x0
>>> collector.map_relation(w)
x1**2

See Also
========

pc_presentation

r<   )r=   r   dtyper6   )r   rS   r@   rB   rD   rM   s   &&    r   map_relationCollector.map_relation   sd    > 1Xa[1Xa[Bx"a2q'*oo##C(##C((r   c                   V P                   p V P                  V4      pV'       g    V# V P                  WP                  ! V4      4      w  rEVR8X  d   KI  V^ ,          w  rg\	        V4      ^8X  Ed"   V P
                  V P                  V,          ,          pWx,          p	WyV,          ,
          p
V^ ,          ^ ,          V33pVP                  ! V4      pV P                  V,          '       dX   V P                  V,          P                  pV^ ,          w  rV^ ,          ^ ,          V
3WV,          33pVP                  ! V4      pM/V
^ 8w  d'   V^ ,          ^ ,          V
33pVP                  ! V4      pMRpVP                  VP                  ! V4      V4      p\	        V4      ^8X  d   V^,          ^,          ^ 8  d{   V^,          w  ppV^33pVP                  ! V4      pV P                  VP                  ! V4      4      pVW,          ,          pVP                  ! V4      pVP                  WEV4      pEK%  \	        V4      ^8X  g   EK8  V^,          ^,          ^ 8  g   EKP  V^,          w  ppV^33pVP                  ! V4      pV P                  VP                  ! V4      4      pVR,          W,          ,          pVP                  ! V4      pVP                  WEV4      pEK  )a  
Return the collected form of a word.

Explanation
===========

A word ``w`` is called collected, if `w = {x_{i_1}}^{a_1} * \ldots *
{x_{i_r}}^{a_r}` with `i_1 < i_2< \ldots < i_r` and `a_j` is in
`\{1, \ldots, {s_j}-1\}`.

Otherwise w is uncollected.

Parameters
==========

word : FreeGroupElement
    An uncollected word.

Returns
=======

word
    A collected word of form `w = {x_{i_1}}^{a_1}, \ldots,
    {x_{i_r}}^{a_r}` with `i_1, i_2, \ldots, i_r` and `a_j \in
    \{1, \ldots, {s_j}-1\}`.

Examples
========

>>> from sympy.combinatorics.named_groups import SymmetricGroup
>>> from sympy.combinatorics.perm_groups import PermutationGroup
>>> from sympy.combinatorics import free_group
>>> G = SymmetricGroup(4)
>>> PcGroup = G.polycyclic_group()
>>> collector = PcGroup.collector
>>> F, x0, x1, x2, x3 = free_group("x0, x1, x2, x3")
>>> word = x3*x2*x1*x0
>>> collected_word = collector.collected_word(word)
>>> free_to_perm = {}
>>> free_group = collector.free_group
>>> for sym, gen in zip(free_group.symbols, collector.pcgs):
...     free_to_perm[sym] = gen
>>> G1 = PermutationGroup()
>>> for w in word:
...     sym = w[0]
...     perm = free_to_perm[sym]
...     G1 = PermutationGroup([perm] + G1.generators)
>>> G2 = PermutationGroup()
>>> for w in collected_word:
...     sym = w[0]
...     perm = free_to_perm[sym]
...     G2 = PermutationGroup([perm] + G2.generators)

The two are not identical, but they are equivalent:

>>> G1.equals(G2), G1 == G2
(True, False)

See Also
========

minimal_uncollected_subword

Nr<   )r   rG   rV   rY   r"   r   r4   r6   r=   eliminate_wordrZ   substituted_word)r   r?   r   rS   rT   rU   rB   rC   rA   qrrM   presentationsymexpword_rD   rE   s   &&                r   collected_wordCollector.collected_word  s   B __
006AZ W **41A1A!1DEICbyqTFB1v{((B8HtG!Q}' &&s+'',,#'#7#7#<#G#GL+AHCd1gq\C3<8E&,,U3EAv"#A$q'1 0 * 0 0 7 $**:+;+;A+>F1v{qtAw{1B1g[%%b)))**:*:1*=>59"((/,,S>Q11a11B1g[%%b)))**:*:1*=>Buy("((/,,S>r   c                   V P                   pV P                  p/ p/ pV P                  p\        WQP                  4       F  w  rgVR,          WFR,          &   WtV&   K  	  VRRR1,          pV P
                  RRR1,          pVRRR1,          p. p	\        V4       EF  w  rW*,          pWF,          V,          pW,          pVP                  Wk,          RR7      pVP                  4        VP                  pV F  pWV,          ,          pK  	  V P                  V4      pV'       d   TMRW<&   W0n        V	P                  V4       \        V	4      ^8  g   K  V	\        V	4      ^,
          ,          pVV,          p\        \        V	4      ^,
          4       F  pWIV,          ,          pVR,          V,          V,          pVR,          V	V,          ,          V,          pVP                  VRR7      pVP                  4        VP                  pV F  pWV,          ,          pK  	  V P                  V4      pV'       d   TMRW<&   W0n        K  	  EK  	  V# )a  
Return the polycyclic presentation.

Explanation
===========

There are two types of relations used in polycyclic
presentation.

* Power relations : Power relators are of the form `x_i^{re_i}`,
  where `i \in \{0, \ldots, \mathrm{len(pcgs)}\}`, ``x`` represents polycyclic
  generator and ``re`` is the corresponding relative order.

* Conjugate relations : Conjugate relators are of the form `x_j^-1x_ix_j`,
  where `j < i \in \{0, \ldots, \mathrm{len(pcgs)}\}`.

Returns
=======

A dictionary with power and conjugate relations as key and
their collected form as corresponding values.

Notes
=====

Identity Permutation is mapped with empty ``()``.

Examples
========

>>> from sympy.combinatorics.named_groups import SymmetricGroup
>>> from sympy.combinatorics.permutations import Permutation
>>> S = SymmetricGroup(49).sylow_subgroup(7)
>>> der = S.derived_series()
>>> G = der[len(der)-2]
>>> PcGroup = G.polycyclic_group()
>>> collector = PcGroup.collector
>>> pcgs = PcGroup.pcgs
>>> len(pcgs)
6
>>> free_group = collector.free_group
>>> pc_resentation = collector.pc_presentation
>>> free_to_perm = {}
>>> for s, g in zip(free_group.symbols, pcgs):
...     free_to_perm[s] = g

>>> for k, v in pc_resentation.items():
...     k_array = k.array_form
...     if v != ():
...        v_array = v.array_form
...     lhs = Permutation()
...     for gen in k_array:
...         s = gen[0]
...         e = gen[1]
...         lhs = lhs*free_to_perm[s]**e
...     if v == ():
...         assert lhs.is_identity
...         continue
...     rhs = Permutation()
...     for gen in v_array:
...         s = gen[0]
...         e = gen[1]
...         rhs = rhs*free_to_perm[s]**e
...     assert lhs == rhs

NToriginalr<    )r   r   r   zip
generatorsr   r2   generator_productreverseidentityre   r6   appendr"   r>   )r   r   	rel_orderr5   perm_to_freer   genr9   seriescollected_gensr8   rA   relationGlr?   gconj
conjugatorj
conjugatedgenss   &                     r   r5   Collector.pc_relators  s   F __
''	yy$ 5 56FC$%rELb! ! 7 DbDz"%ddO	oFAB#(",H	A##CG#=AIIK&&DO+  &&t,D,0DbK!#. !!#&>"Q&%c.&9!&;<)$/
s>2145A!-Q.?!@J)2~j8CH8N1$55d:D++DT+BAIIK%..D#O3   ..t4D48DbK)+6( 6+ &J r   c                ^   V P                   p\        4       pV P                   F   p\        V.VP                  ,           4      pK"  	  VP	                  VRR7      pVP                  4        / p\        VP                  V P                  4       F  w  rtVR,          WdR,          &   WvV&   K  	  VP                  pV F  pWV,          ,          pK  	  V P                  V4      p	V P                  p
^ .\        V4      ,          pV	P                  p	V	 F  pV^,          WV^ ,          ,          &   K  	  V# )a:  
Return the exponent vector of length equal to the
length of polycyclic generating sequence.

Explanation
===========

For a given generator/element ``g`` of the polycyclic group,
it can be represented as `g = {x_1}^{e_1}, \ldots, {x_n}^{e_n}`,
where `x_i` represents polycyclic generators and ``n`` is
the number of generators in the free_group equal to the length
of pcgs.

Parameters
==========

element : Permutation
    Generator of a polycyclic group.

Examples
========

>>> from sympy.combinatorics.named_groups import SymmetricGroup
>>> from sympy.combinatorics.permutations import Permutation
>>> G = SymmetricGroup(4)
>>> PcGroup = G.polycyclic_group()
>>> collector = PcGroup.collector
>>> pcgs = PcGroup.pcgs
>>> collector.exponent_vector(G[0])
[1, 0, 0, 0]
>>> exp = collector.exponent_vector(G[1])
>>> g = Permutation()
>>> for i in range(len(exp)):
...     g = g*pcgs[i]**exp[i] if exp[i] else g
>>> assert g == G[1]

References
==========

.. [1] Holt, D., Eick, B., O'Brien, E.
       "Handbook of Computational Group Theory"
       Section 8.1.1, Definition 8.4

Trh   r<   )r   r   r   rl   rm   rn   rk   ro   re   r4   r"   r=   )r   elementr   rw   ry   r~   rr   rb   rS   r?   r4   
exp_vectorts   &&           r   exponent_vectorCollector.exponent_vector  s   Z __
A !q||!34A ""7t"<*//;FC"%r'LB!O < Aq/!A  ""1%

SZ(
A&'dJQqT{# r   c                    V P                  V4      p\        R \        V4       4       \        V P                  4      ^,           4      # )ai  
Return the depth of a given element.

Explanation
===========

The depth of a given element ``g`` is defined by
`\mathrm{dep}[g] = i` if `e_1 = e_2 = \ldots = e_{i-1} = 0`
and `e_i != 0`, where ``e`` represents the exponent-vector.

Examples
========

>>> from sympy.combinatorics.named_groups import SymmetricGroup
>>> G = SymmetricGroup(3)
>>> PcGroup = G.polycyclic_group()
>>> collector = PcGroup.collector
>>> collector.depth(G[0])
2
>>> collector.depth(G[1])
1

References
==========

.. [1] Holt, D., Eick, B., O'Brien, E.
       "Handbook of Computational Group Theory"
       Section 8.1.1, Definition 8.5

c              3   L   "   T F  w  rV'       g   K  V^,           x  K  	  R# 5i)   Nrj   )r   r8   xs   &  r   r   "Collector.depth.<locals>.<genexpr>a  s     @%:TQaSQqSS%:s   $$)r   nextr2   r"   r   )r   r   r   s   && r   depthCollector.depthA  s:    > ))'2
@Yz%:@#dii.QRBRSSr   c                    V P                  V4      pV P                  V4      pV\        V P                  4      ^,           8w  d   W#^,
          ,          # R# )a  
Return the leading non-zero exponent.

Explanation
===========

The leading exponent for a given element `g` is defined
by `\mathrm{leading\_exponent}[g]` `= e_i`, if `\mathrm{depth}[g] = i`.

Examples
========

>>> from sympy.combinatorics.named_groups import SymmetricGroup
>>> G = SymmetricGroup(3)
>>> PcGroup = G.polycyclic_group()
>>> collector = PcGroup.collector
>>> collector.leading_exponent(G[1])
1

N)r   r   r"   r   )r   r   r   r   s   &&  r   leading_exponentCollector.leading_exponentc  sG    * ))'2


7#C		N1$$Ag&&r   c                   TpV P                  V4      pV\        V P                  4      8  d   W^,
          ,          ^8w  d   W^,
          ,          pV P                  V4      V P                  V4      R,          ,          pW`P                  V^,
          ,          ,          pWV) ,          V,          pV P                  V4      pK  V# )r   r<   )r   r"   r   r   r   )r   zry   hdkrF   s   &&&    r   _siftCollector._sift~  s    JJqM#dii. QsVq[A#A%%a($*?*?*BR)GGA''!,,A2aA

1Ar   c                   ^.\        V P                  4      ,          pTpV'       d   VP                  ^ 4      pV P                  W$4      pV P	                  V4      pV\        V P                  4      8  g   KW  V F@  pV^8w  g   K  VP                  VR,          VR,          ,          V,          V,          4       KB  	  WRV^,
          &   K  V Uu. uF  qw^8w  g   K  VNK  	  ppV# u upi )ax  

Parameters
==========

gens : list
    A list of generators on which polycyclic subgroup
    is to be defined.

Examples
========

>>> from sympy.combinatorics.named_groups import SymmetricGroup
>>> S = SymmetricGroup(8)
>>> G = S.sylow_subgroup(2)
>>> PcGroup = G.polycyclic_group()
>>> collector = PcGroup.collector
>>> gens = [G[0], G[1]]
>>> ipcgs = collector.induced_pcgs(gens)
>>> [gen.order() for gen in ipcgs]
[2, 2, 2]
>>> G = S.sylow_subgroup(3)
>>> PcGroup = G.polycyclic_group()
>>> collector = PcGroup.collector
>>> gens = [G[0], G[1]]
>>> ipcgs = collector.induced_pcgs(gens)
>>> [gen.order() for gen in ipcgs]
[3]

r<   )r"   r   popr   r   rp   )r   r~   r   rw   ry   r   r   rs   s   &&      r   induced_pcgsCollector.induced_pcgs  s    > CDIIaA

1 A

1A3tyy>!CaxBsBwq!45  !A#*ASSSA* +s   C%C%c                   ^ .\        V4      ,          pTpV P                  V4      p\        V4       F  w  rgV P                  V4      V8X  g   K  V P                  V4      V P                  V4      ,          pWP                  V^,
          ,          ,          pWx) ,          V,          pWV&   V P                  V4      pK  	  V^8X  d   V# R# )z.
Return the exponent vector for induced pcgs.
F)r"   r   r2   r   r   )	r   ipcgsry   rF   r   r   r8   rs   fs	   &&&      r   constructive_membership_test&Collector.constructive_membership_test  s     CE
NJJqM&FA**S/Q&))!,T-B-B3-GG++AaC00"IaK!JJqM ' 6Hr   )r   r4   r6   r   r   r   )NN)r%   r&   r'   r(   __doc__r   rG   rO   rV   rZ   re   r5   r   r   r   r   r   r   r+   r,   r-   s   @r   r   r   *   s]     2:8t%2N2h$)NrjwrCJ TD6	+Z r   r   N)
sympy.ntheory.primetestr   sympy.combinatorics.perm_groupsr   sympy.printing.defaultsr   sympy.combinatorics.free_groupsr   r	   r   rj   r   r   <module>r      s,    + < 3 6 o  F\
 \
r   