K iEDdZddlmZddlmZddlZddlmZmZm Z m Z m Z m Z ddl mZddlmZGdd eZGd d eZGd d eZGddeZGddeZGddeZdZdZdZdZdZdZdZdZdZdZ dZ!dZ"d Z#d!Z$d"d#d$Z%y)%aS Construct transitive subgroups of symmetric groups, useful in Galois theory. Besides constructing instances of the :py:class:`~.PermutationGroup` class to represent the transitive subgroups of $S_n$ for small $n$, this module provides *names* for these groups. In some applications, it may be preferable to know the name of a group, rather than receive an instance of the :py:class:`~.PermutationGroup` class, and then have to do extra work to determine which group it is, by checking various properties. Names are instances of ``Enum`` classes defined in this module. With a name in hand, the name's ``get_perm_group`` method can then be used to retrieve a :py:class:`~.PermutationGroup`. The names used for groups in this module are taken from [1]. References ========== .. [1] Cohen, H. *A Course in Computational Algebraic Number Theory*. ) defaultdict)EnumN)SymmetricGroupAlternatingGroup CyclicGroup DihedralGroupset_symmetric_group_properties set_alternating_group_properties)PermutationGroup) PermutationceZdZdZdZdZy)S1TransitiveSubgroupsz3 Names for the transitive subgroups of S1. S1ctdS)Nrselfs `/mnt/ssd/data/python-lab/Trading/venv/lib/python3.12/site-packages/sympy/combinatorics/galois.pyget_perm_groupz$S1TransitiveSubgroups.get_perm_group, a  N)__name__ __module__ __qualname____doc__rrrrrr& B!rrceZdZdZdZdZy)S2TransitiveSubgroupsz3 Names for the transitive subgroups of S2. S2ctdS)Nrrs rrz$S2TransitiveSubgroups.get_perm_group6rrN)rrrrr!rrrrr r 0rrr ceZdZdZdZdZdZy)S3TransitiveSubgroupsz3 Names for the transitive subgroups of S3. A3S3c||tjk(r tdS|tjk(r t dSy)N)r%r&rr'rrs rrz$S3TransitiveSubgroups.get_perm_groupAs; (++ +#A& & *-- -!!$ $.rN)rrrrr&r'rrrrr%r%:s B B%rr%c*eZdZdZdZdZdZdZdZdZ y) S4TransitiveSubgroupsz3 Names for the transitive subgroups of S4. C4VD4A4S4c.|tjk(r tdS|tjk(r t S|tj k(r t dS|tjk(r tdS|tjk(r tdSy)N) r+r,rr- four_groupr.rr/rr0rrs rrz$S4TransitiveSubgroups.get_perm_groupRs (++ +q> ! *,, ,<  *-- - # # *-- -#A& & *-- -!!$ $.rN) rrrrr,r-r.r/r0rrrrr+r+Hs' B A B B B %rr+c*eZdZdZdZdZdZdZdZdZ y) S5TransitiveSubgroupsz3 Names for the transitive subgroups of S5. C5D5M20A5S5c.|tjk(r tdS|tjk(r t dS|tj k(r t S|tj k(r tdS|tjk(r tdSy)N) r5r6rr7rr8r9rr:rrs rrz$S5TransitiveSubgroups.get_perm_groupis (++ +q> ! *-- - # # *.. .5L *-- -#A& & *-- -!!$ $.rN) rrrrr6r7r8r9r:rrrrr5r5_s' B B C B B %rr5cVeZdZdZdZdZdZdZdZdZ dZ d Z d Z d Z d Zd ZdZdZdZdZdZy)S6TransitiveSubgroupsz3 Names for the transitive subgroups of S6. C6r'D6r/G18zA4 x C2zS4-zS4+zG36-zG36+zS4 x C2zPSL2(F5)G72zPGL2(F5)A6S6c|tjk(r tdS|tjk(r t S|tj k(r t dS|tjk(r tS|tjk(r tS|tjk(r tS|tjk(r tS|tjk(r tS|tjk(r tS|tjk(r tS|tjk(r tS|tj k(r t!S|tj"k(r t#S|tj$k(r t%S|tj&k(r t)dS|tj*k(r t-dSy)N)r>r?rr'S3_in_S6r@rr/A4_in_S6rAA4xC2S4mS4pG36mG36pS4xC2PSL2F5rBPGL2F5rCrrDrrs rrz$S6TransitiveSubgroups.get_perm_groupsx (++ +q> ! *-- -:  *-- - # # *-- -:  *.. .5L *00 07N *.. .5L *.. .5L *// /6M *// /6M *00 07N *11 18O *.. .5L *11 18O *-- -#A& & *-- -!!$ $.rN)rrrrr?r'r@r/rArIrJrKrLrMrNrOrBrPrCrDrrrrr>r>vs^ B B B B C E C C D D E F C F B B %rr>c^ttddddtddddS)z] Return a representation of the Klein four-group as a transitive subgroup of S4. rrr#r)r r rrrr3r3s7  Aq!Q Aq!Q rc ttdddddtdddd}d|_d|_d|_d |_d |_d |_d |_|S) z Return a representation of the metacyclic group M20, a transitive subgroup of S5 that is one of the possible Galois groups for polys of degree 5. Notes ===== See [1], Page 323. rrr#r)r2r<TF) r r _degree_order_is_transitive_is_sym_is_alt _is_cyclic _is_dihedralGs rr8r8s_ Q1a3[Aq!5LMAAIAHAAIAIALAN Hrc ttddddddtdddddd}t|dd|S)z Return a representation of S3 as a transitive subgroup of S6. Notes ===== The representation is found by viewing the group as the symmetries of a triangular prism. rrr#r)r2r<rFr r r r\s rrGrGsS -Q1-aA68O8I Aq8I!Q8OPQST8UVA"1a+ Hrc ttddddddtdddddd}t|dd|S)z Return a representation of A4 as a transitive subgroup of S6. Notes ===== This was computed using :py:func:`~.find_transitive_subgroups_of_S6`. rr2r<rr)r#rFr r r r\s rrHrHsM -Q1-aA68L Aq!8LQPQST8UVA$Q1- Hrc ttddddtdddddd}t|dd|S)z Return a representation of the S4- transitive subgroup of S6. Notes ===== This was computed using :py:func:`~.find_transitive_subgroups_of_S6`. rr2r<r)rr#rFr_r\s rrJrJsG Q1a02I2C+a2CAq2I!Q2OPA"1a+ Hrc ttddddddtdddd}t|dd|S)z Return a representation of the S4+ transitive subgroup of S6. Notes ===== This was computed using :py:func:`~.find_transitive_subgroups_of_S6`. rr#r2rr)r<rFr_r\s rrKrKsG 0Q1a0A68I Aq8I!Q8OPA"1a+ Hrc ttddddddtddddddtdddS)z Return a representation of the (A4 x C2) transitive subgroup of S6. Notes ===== This was computed using :py:func:`~.find_transitive_subgroups_of_S6`. rr2r<rr)r#rRrrrrIrI sO  Aq!Q1%';{1a';Aq!'D Aq! rc ttddddtddddddtddddS)z Return a representation of the (S4 x C2) transitive subgroup of S6. Notes ===== This was computed using :py:func:`~.find_transitive_subgroups_of_S6`. rr2r<r)rr#rRrrrrNrNsO Aq!Q!8!2Q!21a!8A!> Aq!Q !!rc ttddddtdddtddddddS)z Return a representation of the group G18, a transitive subgroup of S6 isomorphic to the semidirect product of C3^2 with C2. Notes ===== This was computed using :py:func:`~.find_transitive_subgroups_of_S6`. r<rrr#r)r2rRrrrrArA*sK  Aq!QQ1!5 Aq!Q1% ''rc ttddddtdddtddddtddddddS)z Return a representation of the group G36-, a transitive subgroup of S6 isomorphic to the semidirect product of C3^2 with C2^2. Notes ===== This was computed using :py:func:`~.find_transitive_subgroups_of_S6`. r<rrr#r)r2rRrrrrLrL:s`  Aq!QQ1!5 Aq!Q!8!2Q!21a!8A!> @@rc zttddddtdddtddddddS)z Return a representation of the group G36+, a transitive subgroup of S6 isomorphic to the semidirect product of C3^2 with C4. Notes ===== This was computed using :py:func:`~.find_transitive_subgroups_of_S6`. r<rrr#r)r2rRrrrrMrMJsE  Aq!QQ1!5 Aq!Q1% ''rc ttddddtddddddtddddddS)z Return a representation of the group G72, a transitive subgroup of S6 isomorphic to the semidirect product of C3^2 with D4. Notes ===== See [1], Page 325. r<rrr#r2r)rRrrrrBrBZsY  Aq!Q Aq!Q1%'>'8{1a'8A'>q!'D FFrc xttddddddtddddd}t|dd|S)z Return a representation of the group $PSL_2(\mathbb{F}_5)$, as a transitive subgroup of S6, isomorphic to $A_5$. Notes ===== This was computed using :py:func:`~.find_transitive_subgroups_of_S6`. rr2r<rr)r#rFrar\s rrOrOjsF  Aq!Q1%{1aAq'A CA$Q1- Hrc ttdddddtdddddd}t|dd|S)z Return a representation of the group $PGL_2(\mathbb{F}_5)$, as a transitive subgroup of S6, isomorphic to $S_5$. Notes ===== See [1], Page 325. rrr#r)r2r<rFr_r\s rrPrP{sM Aq!Q"$;$5K1$5a$;Aq$A CA"1a+ HrF) print_reportc Vddfd td}td|dfd dfd }ifd}tj|vstj|vr(|td}|tj|tj |vstj |vr*|tdd }|tj |tj|vr*|tdd }|tj|tj|vr=jd gd td }|tj|tj |vr,jd gd} |tj | tdddd tddddg} tj|vr"| d gd} |tj| tj|vr%| d d gdd } |tj| tj|vr$| dgdd } |tj| tj|vr#| dd gd}|tj|tj|vr(|td}|tj|tj|vr(|td}|tj|tj |vr(|t#d}|tj |tj$|vr(|td}|tj$|tj&|vr(|t)d}|tj&|tj*|vr||tj*tj,|vr||}|tj,|S)a Search for certain transitive subgroups of $S_6$. The symmetric group $S_6$ has 16 different transitive subgroups, up to conjugacy. Some are more easily constructed than others. For example, the dihedral group $D_6$ is immediately found, but it is not at all obvious how to realize $S_4$ or $S_5$ *transitively* within $S_6$. In some cases there are well-known constructions that can be used. For example, $S_5$ is isomorphic to $PGL_2(\mathbb{F}_5)$, which acts in a natural way on the projective line $P^1(\mathbb{F}_5)$, a set of order 6. In absence of such special constructions however, we can simply search for generators. For example, transitive instances of $A_4$ and $S_4$ can be found within $S_6$ in this way. Once we are engaged in such searches, it may then be easier (if less elegant) to find even those groups like $S_5$ that do have special constructions, by mere search. This function locates generators for transitive instances in $S_6$ of the following subgroups: * $A_4$ * $S_4^-$ ($S_4$ not contained within $A_6$) * $S_4^+$ ($S_4$ contained within $A_6$) * $A_4 \times C_2$ * $S_4 \times C_2$ * $G_{18} = C_3^2 \rtimes C_2$ * $G_{36}^- = C_3^2 \rtimes C_2^2$ * $G_{36}^+ = C_3^2 \rtimes C_4$ * $G_{72} = C_3^2 \rtimes D_4$ * $A_5$ * $S_5$ Note: Each of these groups also has a dedicated function in this module that returns the group immediately, using generators that were found by this search procedure. The search procedure serves as a record of how these generators were found. Also, due to randomness in the generation of the elements of permutation groups, it can be called again, in order to (probably) get different generators for the same groups. Parameters ========== targets : list of :py:class:`~.S6TransitiveSubgroups` values The groups you want to find. print_report : bool (default False) If True, print to stdout the generators found for each group. Returns ======= dict mapping each name in *targets* to the :py:class:`~.PermutationGroup` that was found References ========== .. [2] https://en.wikipedia.org/wiki/Projective_linear_group#Exceptional_isomorphisms .. [3] https://en.wikipedia.org/wiki/Automorphisms_of_the_symmetric_and_alternating_groups#PGL%282,5%29 ctt}|jD]$}||jj |&|S)z-Sort the elements of a group by their order. )rlistelementsorderappend)r]eltsgs r elts_by_orderz6find_transitive_subgroups_of_S6..elts_by_orders<4  &A O " "1 % & rc |}|jDcic]\}}|t|c}}|r@t|ddjfdt j DzScc}}w)z8Determine how many elements a group has, of each order. z:  c3DK|]}t|d|yw)@N)len).0rprofiles r zIfind_transitive_subgroups_of_S6..order_profile..s%(baC O+.order_profilesmQ(, 511SV85  TF"+(b6RYR^R^R`Ka(b bb c6sA<rFctj|Dcgc]} | c}D]}tt|t|kr$t |t |z}|j |k(sO|js`||j |k7rw|r  ||k7r|r  ||k(r|cSycc}w)a Find a transitive subgroup of S6. Parameters ========== existing_gens : list of Permutation Optionally empty list of generators that must be in the group. needed_gen_orders : list of positive int Nonempty list of the orders of the additional generators that are to be found. order: int The order of the group being sought. alt: bool, None If True, require the group to be contained in A6. If False, require the group not to be contained in A6. profile : dict If given, the group's order profile must equal this. anti_profile : dict If given, the group's order profile must *not* equal this. N) itertoolsproductrzsetr rorq is_transitive is_subgroup) existing_gensneeded_gen_ordersrqaltr} anti_profilengensr]rC S6_by_orderrs rsearchz/find_transitive_subgroups_of_S6..searchs8%%@Q'R1 A'RS D3t9~D ) d!;c |jDcgc]}|j}}g||j||Scc}w)N)rr}) generatorsrq)r]rrtneededrrs rmatch_known_groupz:find_transitive_subgroups_of_S6..match_known_group sC%&\\2!'')22b&!'')mA>NOO3sA cr||<r/tdt|dt|jyy)Nz(========================================:)rr)rr]foundrls r finish_upz2find_transitive_subgroups_of_S6..finish_ups5d  (O TF!*  !,,  rr2F)rTr#)r0r<rrr)$H)N)NNN)rrr>r/rIrJrNrKrr rArLrMrBrOrPr?rr'r@rrCrD)rltargetsrDrrrH S4m_in_S6 S4p_in_S6 A4xC2_in_S6 S4xC2_in_S6N_gens G18_in_S6 G36m_in_S6 G36p_in_S6 G72_in_S6 PSL2F5_in_S6 PGL2F5_in_S6r?r'r@rCrrurrrs` @@@@@@rfind_transitive_subgroups_of_S6rsH  B ! B#K'RP E 7*.C.I.IW.T$%5a%89'**H5  G+/D/J/Jg/U%nQ&7UC '++Y7  G+%nQ&7TB '++Y7""g-X001#r VdefVgHhi '--{;""g-Y11A3; '--{;k!nQ1%~{1~aA'> ?F  G+6A3+ '++Y7!!W,FQFBE: ',,j9!!W,FQC6 ',,j9  G+6Aq62. '++Y7##w.()9!)<= '.. =##w.():; '.. = 7* {1~ .'**B/7* ~a0 1'**B/7* }Q/ 0'**B/7* r "'**B/7* r "'**B/ Lr)&r collectionsrenumrr sympy.combinatorics.named_groupsrrrrr r sympy.combinatorics.perm_groupsr sympy.combinatorics.permutationsr rr r%r+r5r>r3r8rGrHrJrKrIrNrArLrMrBrOrPrrrrrs2$=8!D!!D! %D %%D%.%D%.5%D5%p ,         ! ' @ ' F  " "