
    \hI                         S SK r S SKJrJrJr  S SKJr  S SKJr  S SK	J
r
  S SKJr  S SKJr   " S S	5      rSS
 jrS rS rS rSS jrS rg)    N)FpGroup
FpSubgroupsimplify_presentation)	FreeGroup)PermutationGroup)igcd)totient)Sc                   r    \ rS rSrSrS rS rS rS rS r	S r
S	 rS
 rS rS rS rS rS rS rS rSrg)GroupHomomorphism	   z
A class representing group homomorphisms. Instantiate using `homomorphism()`.

References
==========

.. [1] Holt, D., Eick, B. and O'Brien, E. (2005). Handbook of computational group theory.

c                 R    Xl         X l        X0l        S U l        S U l        S U l        g N)domaincodomainimages	_inverses_kernel_image)selfr   r   r   s       Y/var/www/auris/envauris/lib/python3.13/site-packages/sympy/combinatorics/homomorphisms.py__init__GroupHomomorphism.__init__   s&         c                 t   U R                  5       n0 n[        U R                  R                  5       5       H0  nU R                  U   nXB;   a  M  UR                  (       a  M,  X2U'   M2     [        U R                  [        5      (       a  UR                  nOUR                  nU H  nXb;   d  UR                  (       a  M  U R                  R                  n[        U R                  [        5      (       a  UR                  U   SSS2   nOUnU H  n	X;   a	  XrU	   -  nM  XrU	S-     S-  -  nM      XrU'   M     U$ )z
Return a dictionary with `{gen: inverse}` where `gen` is a rewriting
generator of `codomain` (e.g. strong generator for permutation groups)
and `inverse` is an element of its preimage

N)imagelistr   keysis_identity
isinstancer   r   strong_gens
generatorsr   identity_strong_gens_slp)
r   r   inverseskvgensgwpartsss
             r   _invsGroupHomomorphism._invs   s    

dkk&&()AAAM}}}	 *
 dmm%566$$D##DA}$$A$--)9::..q1$B$7=1+A1b5/2--A	 
 QK  r   c                    SSK Jn  SSKJn  [	        XU45      (       Ga(  [	        U R
                  [        5      (       a  U R
                  R                  U5      nU R                  c  U R                  5       U l        U R                  5       nU R                  R                  n[	        U R
                  [        5      (       a  UR                  U5      SSS2   nOUn[        [!        U5      5       HS  nXg   nUR"                  (       a  M  XR                  ;   a  XPR                  U   -  nM<  XPR                  US-     S-  -  nMU     U$ [	        U[$        5      (       a!  U V	s/ s H  oR'                  U	5      PM     sn	$ gs  sn	f )a  
Return an element of the preimage of ``g`` or of each element
of ``g`` if ``g`` is a list.

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

If the codomain is an FpGroup, the inverse for equal
elements might not always be the same unless the FpGroup's
rewriting system is confluent. However, making a system
confluent can be time-consuming. If it's important, try
`self.codomain.make_confluent()` first.

r   Permutation)FreeGroupElementNr   )sympy.combinatoricsr2   sympy.combinatorics.free_groupsr3   r!   r   r   reducer   r.   r   r   r$   r   generator_productrangelenr    r   invert)
r   r*   r2   r3   r   r+   r)   ir-   es
             r   r:   GroupHomomorphism.invert?   s3    	4Da'7899$--11MM((+~~%!%JJLE$$A$--)9::..q1$B$7 3t9%G==&..++A..B/33A & H4  ,-.AqKKNA.. !.s   !E?c                 ^    U R                   c  U R                  5       U l         U R                   $ )z 
Compute the kernel of `self`.

)r   _compute_kernelr   s    r   kernelGroupHomomorphism.kernelm   s(    
 <<//1DL||r   c                 ^   U R                   nUR                  5       nU[        R                  L a  [	        S5      e/ n[        U[        5      (       a  [        UR                  5      nO
[        XSS9nU R                  5       R                  5       nUR                  5       U-  U:w  a  UR                  5       nX`R                  U " U5      5      S-  -  nXt;  a<  UR                  U5        [        U[        5      (       a  [        U5      nO
[        XSS9nUR                  5       U-  U:w  a  M  U$ )Nz9Kernel computation is not implemented for infinite groupsT)normalr   )r   orderr
   InfinityNotImplementedErrorr!   r   r$   r   r   randomr:   append)r   GG_orderr)   Kr;   rr'   s           r   r?   !GroupHomomorphism._compute_kernelv   s    KK'')ajj %KM Ma)** ,A140AJJL ggikW$
A++d1g&**AzAa!122(.A"148A ggikW$ r   c                 X   U R                   c  [        [        U R                  R	                  5       5      5      n[        U R                  [        5      (       a,  U R                  R                  U5      U l         U R                   $ [        U R                  U5      U l         U R                   $ )z
Compute the image of `self`.

)
r   r   setr   valuesr!   r   r   subgroupr   )r   rQ   s     r   r   GroupHomomorphism.image   s|    
 ;;#dkk00234F$--)9::"mm44V< {{ )?{{r   c                    XR                   ;  aG  [        U[        [        45      (       a!  U Vs/ s H  o R	                  U5      PM     sn$ [        S5      eUR                  (       a  U R                  R                  $ U R                  nU R                  R                  n[        U R                   [        5      (       aJ  U R                   R                  USS9nU H(  nX`R                  ;   a	  X6   U-  nM  X6S-     S-  U-  nM*     U$ SnUR                   H/  u  pU	S:  a  X   S-  nOX   nXCU   U	-  -  nU[        U	5      -  nM1     U$ s  snf )z
Apply `self` to `elem`.

z2The supplied element does not belong to the domainT)originalr   r   )r   r!   r   tuple_apply
ValueErrorr    r   r$   r   r   r7   
array_formabs)
r   elemr<   r   valuer)   r*   r;   _ps
             r   rW   GroupHomomorphism._apply   s6   
 {{"$u..0451A55QRR==)))[[FMM**E$++'788{{44TD4IAKK' &	% &"ur 1% 7	    OODA1u GRK G!)Q,.EQKA , / 6s   Ec                 $    U R                  U5      $ r   )rW   )r   r[   s     r   __call__GroupHomomorphism.__call__   s    {{4  r   c                 D    U R                  5       R                  5       S:H  $ )z)
Check if the homomorphism is injective

   )rA   rE   r@   s    r   is_injectiveGroupHomomorphism.is_injective   s    
 {{}""$))r   c                     U R                  5       R                  5       nU R                  R                  5       nU[        R                  L a  U[        R                  L a  gX:H  $ )z*
Check if the homomorphism is surjective

N)r   rE   r   r
   rF   )r   imoths      r   is_surjectiveGroupHomomorphism.is_surjective   sL    
 ZZ\!mm!!#qzz 19r   c                 P    U R                  5       =(       a    U R                  5       $ )z%
Check if `self` is an isomorphism.

)re   rj   r@   s    r   is_isomorphism GroupHomomorphism.is_isomorphism   s!    
   ";t'9'9';;r   c                 D    U R                  5       R                  5       S:H  $ )z[
Check is `self` is a trivial homomorphism, i.e. all elements
are mapped to the identity.

rd   )r   rE   r@   s    r   
is_trivialGroupHomomorphism.is_trivial   s     zz|!!#q((r   c           	         UR                  5       R                  U R                  5      (       d  [        S5      eUR                   Vs0 s H  o"U " U" U5      5      _M     nn[        UR                  U R                  U5      $ s  snf )z
Return the composition of `self` and `other`, i.e.
the homomorphism phi such that for all g in the domain
of `other`, phi(g) = self(other(g))

z?The image of `other` must be a subgroup of the domain of `self`)r   is_subgroupr   rX   r   r   r   )r   otherr*   r   s       r   composeGroupHomomorphism.compose   sp     {{}((55 + , ,-2\\:\T%(^#\: t}}fEE ;s   Bc                     [        U[        5      (       a   UR                  U R                  5      (       d  [	        S5      eUnUR
                   Vs0 s H  o3U " U5      _M     nn[        X R                  U5      $ s  snf )zP
Return the restriction of the homomorphism to the subgroup `H`
of the domain.

z'Given H is not a subgroup of the domain)r!   r   rs   r   rX   r#   r   r   )r   Hr   r*   r   s        r   restrict_toGroupHomomorphism.restrict_to   si     !-..ammDKK6P6PFGG&'ll3lT!W*l3 ?? 4s   A;c                    UR                  U R                  5       5      (       d  [        S5      e/ n[        U R                  5       R                  5      nUR
                   H~  nU R                  U5      nXS;  a  UR                  U5        [        U5      nU R                  5       R
                   H+  nXe-  U;  d  M  UR                  Xe-  5        [        U5      nM-     M     U$ )zn
Return the subgroup of the domain that is the inverse image
of the subgroup ``H`` of the homomorphism image

z&Given H is not a subgroup of the image)	rs   r   rX   r   r$   r#   r:   rI   rA   )r   rx   r)   Phh_ir'   s          r   invert_subgroup!GroupHomomorphism.invert_subgroup   s     }}TZZ\**EFFTZZ\223A++a.C|C $T*[[]--5>KK&(.A .  r   )r   r   r   r   r   r   N)__name__
__module____qualname____firstlineno____doc__r   r.   r:   rA   r?   r   rW   ra   re   rj   rm   rp   ru   ry   r   __static_attributes__ r   r   r   r   	   sW    !F,/\.@!*
<)F
@r   r   c                 ,  ^^ [        U [        [        [        45      (       d  [	        S5      e[        T[        [        [        45      (       d  [	        S5      eU R
                  m[        U4S jU 5       5      (       d  [        S5      e[        U4S jU 5       5      (       d  [        S5      eU(       a#  [        U5      [        U5      :w  a  [        S5      e[        U5      n[        U5      nUR                  TR                  /[        T5      [        U5      -
  -  5        UR                  T Vs/ s H  oUU;  d  M
  UPM     sn5        [        [        X#5      5      nU(       a  [        U TU5      (       d  [        S5      e[        U TU5      $ s  snf )	a^  
Create (if possible) a group homomorphism from the group ``domain``
to the group ``codomain`` defined by the images of the domain's
generators ``gens``. ``gens`` and ``images`` can be either lists or tuples
of equal sizes. If ``gens`` is a proper subset of the group's generators,
the unspecified generators will be mapped to the identity. If the
images are not specified, a trivial homomorphism will be created.

If the given images of the generators do not define a homomorphism,
an exception is raised.

If ``check`` is ``False``, do not check whether the given images actually
define a homomorphism.

zThe domain must be a groupzThe codomain must be a groupc              3   ,   >#    U  H	  oT;   v   M     g 7fr   r   ).0r*   r#   s     r   	<genexpr>homomorphism.<locals>.<genexpr>#  s     -1J   zCThe supplied generators must be a subset of the domain's generatorsc              3   ,   >#    U  H	  oT;   v   M     g 7fr   r   )r   r*   r   s     r   r   r   %  s     -fH}fr   z+The images must be elements of the codomainz>The number of images must be equal to the number of generatorsz-The given images do not define a homomorphism)r!   r   r   r   	TypeErrorr#   allrX   r9   r   extendr$   dictzip_check_homomorphismr   )r   r   r)   r   checkr*   r#   s    `    @r   homomorphismr     sC     f/)DEE455h!17I FGG677""J----^__-f---FGG#f+T*YZZ:D&\F
MM8$$%s:s6{'BCDKKJ8Jq4-J89#d"#F(6BBHIIVXv66 9s   2	F?Fc                 N  ^^^ [        U S5      (       a  U OU R                  5       nUR                  nUR                  nU Vs/ s H  ofR                  S   PM     nn[        [        XpR                  5      5      mUR                  mUUU4S jnU H  n	[        U[        5      (       aY  UR                  U" U	5      T5      n
U
c=  UR                  5       nUR                  U" U	5      T5      n
U
c  U(       d  [        S5      eOU" U	5      R                  n
U
(       a  M    g   gs  snf )a9  
Check that a given mapping of generators to images defines a homomorphism.

Parameters
==========
domain : PermutationGroup, FpGroup, FreeGroup
codomain : PermutationGroup, FpGroup, FreeGroup
images : dict
    The set of keys must be equal to domain.generators.
    The values must be elements of the codomain.

relatorsr   c                 V   > TnU R                    H  u  p#TU   nUTU   U-  -  nM     U$ r   )rY   )rM   r+   symbolpowerr*   r$   r   symbols_to_domain_generatorss        r   r   #_check_homomorphism.<locals>._imageJ  s<    \\MF,V4AE!!A * r   zCan't determine if the images define a homomorphism. Try increasing the maximum number of rewriting rules (group._rewriting_system.set_max(new_value); the current value is stored in group._rewriting_system.maxeqns)FT)hasattrpresentationr   r#   ext_repr   r   r$   r!   r   equalsmake_confluentRuntimeErrorr    )r   r   r   presrelsr)   r*   symbolsr   rM   r-   successr$   r   s     `         @@r   r   r   6  s    VZ006f6I6I6KD==D??D%)*Tyy|TG*#'G5F5F(G#H   H h((q	84Ay #113OOF1Ix89W& (+ , , q	%%Aq' ( ? +s   D"c                     SSK Jn  SSKJn  U" [	        U5      5      nUR
                  n[        U5      nU R                   VVs0 s H.  ofXR" U Vs/ s H  oqR                  Xv-  5      PM     sn5      -  _M0     nnnU R                  US9  [        XU5      n	[	        U R                  5      [	        U5      :  a  U R                  [	        U5         U	l        U	$ [        U R
                  /5      U	l        U	$ s  snf s  snnf )z
Return the homomorphism induced by the action of the permutation
group ``group`` on the set ``omega`` that is closed under the action.

r   r1   SymmetricGroup)base)r4   r2    sympy.combinatorics.named_groupsr   r9   r$   r   r#   index_schreier_simsr   basic_stabilizersr   r   )
groupomegar2   r   r   r$   r*   or   rx   s
             r   orbit_homomorphismr   g  s     0?c%j)H  HKERWRbRbcRbQ+&GA{{13'7&GHHHRbFc	e$%62A
5""#c%j0++CJ7	 H %enn%56	H 'Hcs   C:C5,C:5C:c                    SSK Jn  SSKJn  [	        U5      nSn/ nS/U-  n[        U5       H'  nX   U:X  d  M  UR                  U5        XWU'   US-  nM)     [        U5       H  nXqU      Xx'   M     U" U5      n	[        U5      n
U R                   VVs0 s H#  oU" U
 Vs/ s H  oXh   U-     PM     sn5      _M%     nnn[        X	U5      nU$ s  snf s  snnf )aJ  
Return the homomorphism induced by the action of the permutation
group ``group`` on the block system ``blocks``. The latter should be
of the same form as returned by the ``minimal_block`` method for
permutation groups, namely a list of length ``group.degree`` where
the i-th entry is a representative of the block i belongs to.

r   r1   r   Nrd   )	r4   r2   r   r   r9   r8   rI   r#   r   )r   blocksr2   r   nmr^   br;   r   r$   r*   r   rx   s                 r   block_homomorphismr   {  s     0?FA 	
A
A	qA1X9>HHQKaDFA	 
 1X|  a HQxHEJEUEUVEU:AQi:;;EUFV%62AH ;Vs   C!C4CCc           	         [        U [        [        45      (       d  [        S5      e[        U[        [        45      (       d  [        S5      e[        U [        5      (       a  [        U[        5      (       a  [	        U 5      n [	        U5      nU R
                  UR
                  :X  aa  U R                  R                  5       UR                  R                  5       :X  a+  U(       d  gS[        XU R
                  UR
                  5      4$ UnU R                  5       nUR                  5       nU[        R                  L a  [        S5      e[        U[        5      (       a0  U[        R                  L a  [        S5      eUR                  5       u  p6XE:w  d  U R                  UR                  :w  a	  U(       d  ggU(       d  Un[        U[!        U5      5      S:X  a  g[#        U R
                  5      n[$        R&                  " U[)        U5      5       H  n	[#        U	5      n
U
R+                  UR,                  /[)        U R
                  5      [)        U
5      -
  -  5        [/        [1        X5      5      n[3        XU5      (       d  Ms  [        U[        5      (       a  WR5                  U
5      n
[        XU R
                  U
SS9nUR7                  5       (       d  M  U(       d    gSU4s  $    U(       d  gg)a  
Compute an isomorphism between 2 given groups.

Parameters
==========

G : A finite ``FpGroup`` or a ``PermutationGroup``.
    First group.

H : A finite ``FpGroup`` or a ``PermutationGroup``
    Second group.

isomorphism : bool
    This is used to avoid the computation of homomorphism
    when the user only wants to check if there exists
    an isomorphism between the groups.

Returns
=======

If isomorphism = False -- Returns a boolean.
If isomorphism = True  -- Returns a boolean and an isomorphism between `G` and `H`.

Examples
========

>>> from sympy.combinatorics import free_group, Permutation
>>> from sympy.combinatorics.perm_groups import PermutationGroup
>>> from sympy.combinatorics.fp_groups import FpGroup
>>> from sympy.combinatorics.homomorphisms import group_isomorphism
>>> from sympy.combinatorics.named_groups import DihedralGroup, AlternatingGroup

>>> D = DihedralGroup(8)
>>> p = Permutation(0, 1, 2, 3, 4, 5, 6, 7)
>>> P = PermutationGroup(p)
>>> group_isomorphism(D, P)
(False, None)

>>> F, a, b = free_group("a, b")
>>> G = FpGroup(F, [a**3, b**3, (a*b)**2])
>>> H = AlternatingGroup(4)
>>> (check, T) = group_isomorphism(G, H)
>>> check
True
>>> T(b*a*b**-1*a**-1*b**-1)
(0 2 3)

Notes
=====

Uses the approach suggested by Robert Tarjan to compute the isomorphism between two groups.
First, the generators of ``G`` are mapped to the elements of ``H`` and
we check if the mapping induces an isomorphism.

z2The group must be a PermutationGroup or an FpGroupTz<Isomorphism methods are not implemented for infinite groups.F)FNrd   )r   )r!   r   r   r   r   r#   r   sortr   rE   r
   rF   rG   _to_perm_group
is_abelianr   r	   r   	itertoolspermutationsr9   r   r$   r   r   r   r:   rm   )rJ   rx   isomorphism_Hg_orderh_orderh_isomorphismr   r)   subsetr   _imagesTs                r   group_isomorphismr     sB   p a*G455LMMa*G455LMM!W*Q"8"8!!$!!$ <<1<<'QZZ,=,=,?AJJCTCTCV,V,qQ\\1<<HII 
BggiGggiG!**!"`aa!Wajj %&dee,,. < GAJA% D((SY7fr{{mS%6s6{%BCDs4'(qg..!W%%&--f5aALL&FA!!"ay  8 r   c                     [        XSS9$ )z
Check if the groups are isomorphic to each other

Parameters
==========

G : A finite ``FpGroup`` or a ``PermutationGroup``
    First group.

H : A finite ``FpGroup`` or a ``PermutationGroup``
    Second group.

Returns
=======

boolean
F)r   )r   )rJ   rx   s     r   is_isomorphicr     s    $ Qu55r   )r   T)T)r   sympy.combinatorics.fp_groupsr   r   r   r5   r   sympy.combinatorics.perm_groupsr   sympy.core.intfuncr   %sympy.functions.combinatorial.numbersr	   sympy.core.singletonr
   r   r   r   r   r   r   r   r   r   r   <module>r      sM     T T 5 < # 9 "B BH'7R/b("Hrh6r   