
    gP                     L   d Z ddlmZ ddlZddlmZmZ ddlmZ ddl	m
Z
 ddlmZ ddlmZ dd	lmZ dd
lmZmZ ddlmZmZmZmZ ddlmZ ddlmZmZmZmZ ddl m!Z! ddl"m#Z#  G d de          Z$	 	 d dZ%d Z&d!dZ'd!dZ(d!dZ)d!dZ*d!dZ+d!dZ,e#ddddd            Z-dS )"z
Compute Galois groups of polynomials.

We use algorithms from [1], with some modifications to use lookup tables for
resolvents.

References
==========

.. [1] Cohen, H. *A Course in Computational Algebraic Number Theory*.

    )defaultdictN)Dummysymbols)	is_squareZZ)
dup_random)dup_eval)dup_discriminant)dup_factor_listdup_irreducible_p)GaloisGroupExceptionget_resolvent_by_lookupdefine_resolvents	Resolvent)coeff_search)Polypoly_from_exprPolificationFailedComputationFailed)	dup_sqf_p)publicc                       e Zd ZdS )MaxTriesExceptionN)__name__
__module____qualname__     a/var/www/html/ai-engine/env/lib/python3.11/site-packages/sympy/polys/numberfields/galoisgroups.pyr   r   #   s        Cr   r   
      Tc                 ~   t          d          }|                                 }|t                      }|                    | j                   |ri d}d}fd}	t          |          D ]K}
|r |	|          }t          |          }t          d |D                       }||z   |k    r0|dk    r|dz  }|dz
  }n|dz  } |	|          }t          |          }t          d          gd |D             z   }nFt          |
d	z  dz   |          }t          j        d|dz
            }t          || |t                    }t          || j                  }t          |                     ||z
            |          }|j        |vr2t!          |j                                        t                    r||fc S Mt$          )
a  
    Given a univariate, monic, irreducible polynomial over the integers, find
    another such polynomial defining the same number field.

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

    See Alg 6.3.4 of [1].

    Parameters
    ==========

    T : Poly
        The given polynomial
    max_coeff : int
        When choosing a transformation as part of the process,
        keep the coeffs between plus and minus this.
    max_tries : int
        Consider at most this many transformations.
    history : set, None, optional (default=None)
        Pass a set of ``Poly.rep``'s in order to prevent any of these
        polynomials from being returned as the polynomial ``U`` i.e. the
        transformation of the given polynomial *T*. The given poly *T* will
        automatically be added to this set, before we try to find a new one.
    fixed_order : bool, default True
        If ``True``, work through candidate transformations A(x) in a fixed
        order, from small coeffs to large, resulting in deterministic behavior.
        If ``False``, the A(x) are chosen randomly, while still working our way
        up from small coefficients to larger ones.

    Returns
    =======

    Pair ``(A, U)``

        ``A`` and ``U`` are ``Poly``, ``A`` is the
        transformation, and ``U`` is the transformed polynomial that defines
        the same number field as *T*. The polynomial ``A`` maps the roots of
        *T* to the roots of ``U``.

    Raises
    ======

    MaxTriesException
        if could not find a polynomial before exceeding *max_tries*.

    XN      c                 Z                         | t          | d                    }|| <   |S )N   )getr   )degreegencoeff_generatorss     r    get_coeff_generatorz9tschirnhausen_transformation.<locals>.get_coeff_generatorc   s2    ""6<+B+BCC#& 
r   c              3   4   K   | ]}t          |          V  d S )N)abs.0cs     r    	<genexpr>z/tschirnhausen_transformation.<locals>.<genexpr>x   s(      ++qCFF++++++r   r(   c                 ,    g | ]}t          |          S r   r   r0   s     r    
<listcomp>z0tschirnhausen_transformation.<locals>.<listcomp>   s    111Q2a55111r      )r   r*   setaddreprangenextmaxr   minrandomrandintr	   r   r+   	resultantr   to_listr   )T	max_coeff	max_trieshistoryfixed_orderr$   ndeg_coeff_sumcurrent_degreer-   ir+   coeffsmaCdAUr,   s                      @r    tschirnhausen_transformationrR   '   s   b 	c

A	

A%%KK     
 9 & &  	) &%n55C#YYF++F+++++A!M11!Q&&!Q&M%2Q%6NN"a'N)).99cA11&1111AA AqD1Hi((Aq!a%((A1qb!R((AAENNQU##Q''5Iaemmoor$B$Ba4KKK
r   c                     t          | t                    r|                                 nt          | t                    }t          |          S )z?Convenience to check if a Poly or dup has square discriminant. )
isinstancer   discriminantr   r   r   )rB   rO   s     r    has_square_discrV      s<    &q$//L5Ea5L5LAQ<<r   Fc                 P    ddl m} t          |           r	|j        dfn|j        dfS )z~
    Compute the Galois group of a polynomial of degree 3.

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

    Uses Prop 6.3.5 of [1].

    r   )S3TransitiveSubgroupsTF)sympy.combinatorics.galoisrX   rV   A3S3)rB   rD   	randomizerX   s       r    _galois_group_degree_3r]      sE     A@@@@@0?0B0B 3"%t,,'*E24r   c           	         ddl m} ddlm} t	          d          }|d         |d         z  |d         |d         z  z   } |d            |d          dd            |d          dd          g}t          |||          }|d         |d         dz  z  |d         |d         dz  z  z   |d         |d         dz  z  z   |d         |d         dz  z  z   }	 |d            |d          dd          g}
t                      }t          |          D ]3}|dk    rt          | |||           \  }} |	                    | d	
          \  }}}t          |t                    sQt          |           }||r	|j        d	fn|j        dfc S |r|j        d	fc S ||         |	                    t#          | |                    d	          }fd|
D             }t          |||          }|	                    |           \  }}}t%          |t                    }|dk    rt'          |          r|j        dfc S |j        dfc S t,          )z
    Compute the Galois group of a polynomial of degree 4.

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

    Follows Alg 6.3.7 of [1], using a pure root approximation approach.

    r   PermutationS4TransitiveSubgroupszX0 X1 X2 X3r&   r(   r%   rD   rE   rF   T)find_integer_rootNFsimultaneousc                      g | ]
}|z  z  S r   r   r1   tausigmas     r    r5   z6_galois_group_degree_4_root_approx.<locals>.<listcomp>   !    000#eCio000r   ) sympy.combinatorics.permutationsr`   rY   rb   r   r   r7   r:   rR   eval_for_polyr   r   rV   A4S4Vsubszipr   r   C4D4r   )rB   rD   r\   r`   rb   r$   F1s1R1F2_pres2_prerE   rJ   _R_dupi0sq_discF2s2R2rO   rj   s                        @r    "_galois_group_degree_4_root_approxr      s    =<<<<<@@@@@@A
 
1adQqT!A$Y	BAAq!Aq!
B
 
2q"		B
 qT!A$'\AaD1qL(1Q4!a<7!A$qtQw,FFAAq!F
 eeG9 .5 .5q55/Y8?@IMK K KDAq ''T'BBq"## 	 "!$$: 9@ ;*-t44/2E:< < <  	3)+T2222 2 [[Qa))[==0000000r1b!!&&q))q!UB''66Q<< 	5),e4444),e4444
r   c                    ddl m} t                      }t          |          D ]@}t	          | d          }t          |t                    r nt          | |||           \  }} At          t          |t                    }t          t          d |d         D             g                     }	|	dgk    r!t          |           r	|j        dfn|j        dfS |	g d	k    r	|j        dfS |	g d
k    r	|j        dfS |	ddgk    sJ |j        dfS )z
    Compute the Galois group of a polynomial of degree 4.

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

    Based on Alg 6.3.6 of [1], but uses resolvent coeff lookup.

    r   ra   rc   c                 @    g | ]\  }}t          |          d z
  g|z  S )r(   len)r1   res      r    r5   z1_galois_group_degree_4_lookup.<locals>.<listcomp>  s:       !QQ!q  r   r(      TFr(   r(      )r&   r&   r&   r&   r   )rY   rb   r7   r:   r   r   r   rR   r   r   sortedsumrV   rn   ro   rs   rp   rt   )
rB   rD   r\   rb   rE   rJ   r{   rz   flLs
             r    _galois_group_degree_4_lookupr      so    A@@@@@eeG9    '1--UB 	E+A4;<EG G G11   
	#	#Bs  %'U  	  	 	A 	QCxx4CA4F4F 3&)400'*E2	4 	III~~%(%00III~~%'..A;;;;!$e,,r   c           	      ,   ddl m} ddlm} t	          d          }t                      }|d         \  }}}	 |j        | }t          |||	          }
t                      }d}t          |          D ]}|dk    rt          | |||           \  }} t          | d          }t          |t                    sF|sGt          |           }t          |t                    r|r	|j        d	fn|j        dfc S |s|j        dfc S d	}|
                    |           }|                                D ]\  }}t+          ||t                    s n|}|d         |d         d
z  z  |d         |d
         d
z  z  z   |d
         |d         d
z  z  z   |d         |d         d
z  z  z   |d         |d         d
z  z  z   } |d             |d          dd          d
d          g}|}|	|         |                    t/          | |                    d	          }fd|D             }t          |||          }|                    |           \  }}}t3          |t                    }|dk    rt5          |          r|j        d	fc S |j        d	fc S t:          )z
    Compute the Galois group of a polynomial of degree 5.

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

    Based on Alg 6.3.9 of [1], but uses a hybrid approach, combining resolvent
    coeff lookup, with root approximation.

    r   S5TransitiveSubgroupsr_   zX0,X1,X2,X3,X4)r6   r(   Frc   r(   Tr&   r%   r   re   c                      g | ]
}|z  z  S r   r   rh   s     r    r5   z1_galois_group_degree_5_hybrid.<locals>.<listcomp>k  rk   r   )rY   r   rl   r`   r   r   as_exprr   r7   r:   rR   r   r   r   rV   r   A5S5M20 round_roots_to_integers_for_polyitemsr
   rq   rr   rm   r   r   C5D5r   )rB   rD   r\   r   r`   X5resF51rz   s51R51rE   reached_second_stagerJ   R51_dupr}   rounded_rootspermutation_indexcandidate_rootr$   rx   ry   r|   r~   r   r   r{   rO   rj   s                               @r    _galois_group_degree_5_hybridr   )  sA    A@@@@@<<<<<<	!	"	"B


Cf+KCC
#+r
C
CS
!
!CeeG 9 64 64q55/Y8?@IMK K KDAq *!Q//"%% 	
 $ 	:%a((G "-- @<C ?.148836>@ @ @  :-159999  $ <<Q?? 2?1D1D1F1F 	 	-~G^R88  1adAg!QqT1W,qtAaD!G|;ad1Q47lJQqTRSTURVXYRY\YKNN NKKNN1a  A&&

 B[[Qa))[==0000000r1b!!&&q))q!UB''66Q<< 	4),d3333),d3333
r   c                 "   ddl m} | }t                      }t          |          D ]@}t	          | d          }t          |t                    r nt          | |||           \  }} At          t          |           }	t          |t                    r|	r	|j        dfn|j        dfS |	s	|j        dfS t          |t          j        |                                                    d         }
t#          |
          dk    r	|j        dfS |j        dfS )	z
    Compute the Galois group of a polynomial of degree 5.

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

    Based on Alg 6.3.9 of [1], but uses resolvent coeff lookup, plus
    factorization over an algebraic extension.

    r   r   r(   rc   TF)domainr6   )rY   r   r7   r:   r   r   r   rR   r   rV   r   r   r   r   r   alg_field_from_polyfactor_listr   r   r   )rB   rD   r\   r   _TrE   rJ   r{   rz   r}   r   s              r    (_galois_group_degree_5_lookup_ext_factorr   z  sK    A@@@@@	
BeeG9    '1--UB 	E+A4;<EG G G11  a  G## 84; 7&)400+.6	8  2%)511
 
b/33	4	4	4	@	@	B	B1	EB
2ww!||%($//%($//r   c                    ddl m} t                      }t          |          D ]@}t	          | d          }t          |t                    r nt          | |||           \  }} At          t          |t                    }t          t                    }	|d         D ]0\  }
}|	t          |
          dz
                               |
           1t          t          d |	                                D             g                     }t#          |           }|g dk    r/|	d         d         }t#          |          r	|j        dfn|j        dfS |ddgk    r=|	d         \  }}t#          |          pt#          |          }|r	|j        dfn|j        dfS |d	d
gk    r:|r	|j        dfS |	d
         d         }t#          |          r	|j        dfn|j        dfS |g dk    r|r	|j        dfn|j        dfS |ddgk    r|r	|j        dfn|j        dfS |g dk    r	|j        dfS |dgk    sJ t                      }t          |          D ]@}t	          | d	          }t          |t                    r nt          | |||           \  }} At          t#          |           }t=          |t                    r|r	|j        dfn|j         dfS |r	|j!        dfn|j"        dfS )z
    Compute the Galois group of a polynomial of degree 6.

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

    Based on Alg 6.3.10 of [1], but uses resolvent coeff lookup.

    r   )S6TransitiveSubgroupsr(   rc   c                 :    g | ]\  }}|gt          |          z  S r   r   )r1   rO   ffs      r    r5   z1_galois_group_degree_6_lookup.<locals>.<listcomp>  s5       !Rc"gg  r   )r(   r&   r%   r%   Fr&   r   Tr   r6   )r(   r(   r(   r%   r   )#rY   r   r7   r:   r   r   r   rR   r   r   r   listr   appendr   r   r   rV   C6D6G18G36mS4pA4xC2S4xC2rn   S4mPSL2F5PGL2F5r[   r   A6S6G36pG72)rB   rD   r\   r   rE   rJ   r{   rz   r   factors_by_degr   r   T_has_sq_discf1f2
any_squares                   r    _galois_group_degree_6_lookupr     s    A@@@@@ eeG9    '1--UB 	E+A4;<EG G G11  		#	#B !&&N1 - -1s1vvz"))!,,,,s  #1#7#7#9#9  	  	 	A $A&&MIII~~Aq!5DR5H5H 7&)511+.6	8 
q!f"B$R((?OB,?,?
6@ 9&*E22+0%8	: 
q!f 	?)-t44"1%B<KB<O<O >*0%88/5u=? 
iii4A 8&)400+/7	9 
q!f8E ;&-t44+2E:	< 
lll		%(%008888 eeG9    '1--UB 	E+A4;<EG G G11  #A&&M## 94A 7&)400+.6	8 7D 8&+T22+/7	9r   by_namerD   r\   c                    |pg }|pi }	 t          | g|R i |\  }}n## t          $ r}t          dd|          d}~ww xY w|                    |||          S )a  
    Compute the Galois group for polynomials *f* up to degree 6.

    Examples
    ========

    >>> from sympy import galois_group
    >>> from sympy.abc import x
    >>> f = x**4 + 1
    >>> G, alt = galois_group(f)
    >>> print(G)
    PermutationGroup([
    (0 1)(2 3),
    (0 2)(1 3)])

    The group is returned along with a boolean, indicating whether it is
    contained in the alternating group $A_n$, where $n$ is the degree of *T*.
    Along with other group properties, this can help determine which group it
    is:

    >>> alt
    True
    >>> G.order()
    4

    Alternatively, the group can be returned by name:

    >>> G_name, _ = galois_group(f, by_name=True)
    >>> print(G_name)
    S4TransitiveSubgroups.V

    The group itself can then be obtained by calling the name's
    ``get_perm_group()`` method:

    >>> G_name.get_perm_group()
    PermutationGroup([
    (0 1)(2 3),
    (0 2)(1 3)])

    Group names are values of the enum classes
    :py:class:`sympy.combinatorics.galois.S1TransitiveSubgroups`,
    :py:class:`sympy.combinatorics.galois.S2TransitiveSubgroups`,
    etc.

    Parameters
    ==========

    f : Expr
        Irreducible polynomial over :ref:`ZZ` or :ref:`QQ`, whose Galois group
        is to be determined.
    gens : optional list of symbols
        For converting *f* to Poly, and will be passed on to the
        :py:func:`~.poly_from_expr` function.
    by_name : bool, default False
        If ``True``, the Galois group will be returned by name.
        Otherwise it will be returned as a :py:class:`~.PermutationGroup`.
    max_tries : int, default 30
        Make at most this many attempts in those steps that involve
        generating Tschirnhausen transformations.
    randomize : bool, default False
        If ``True``, then use random coefficients when generating Tschirnhausen
        transformations. Otherwise try transformations in a fixed order. Both
        approaches start with small coefficients and degrees and work upward.
    args : optional
        For converting *f* to Poly, and will be passed on to the
        :py:func:`~.poly_from_expr` function.

    Returns
    =======

    Pair ``(G, alt)``
        The first element ``G`` indicates the Galois group. It is an instance
        of one of the :py:class:`sympy.combinatorics.galois.S1TransitiveSubgroups`
        :py:class:`sympy.combinatorics.galois.S2TransitiveSubgroups`, etc. enum
        classes if *by_name* was ``True``, and a :py:class:`~.PermutationGroup`
        if ``False``.

        The second element is a boolean, saying whether the group is contained
        in the alternating group $A_n$ ($n$ the degree of *T*).

    Raises
    ======

    ValueError
        if *f* is of an unsupported degree.

    MaxTriesException
        if could not complete before exceeding *max_tries* in those steps
        that involve generating Tschirnhausen transformations.

    See Also
    ========

    .Poly.galois_group

    galois_groupr(   Nr   )r   r   r   r   )	fr   rD   r\   gensargsFoptexcs	            r    r   r     s    D :2D:2D81D111D1133 8 8 837778 >>'Y$-  / / /s    
>9>)r!   r"   NT)r"   F).__doc__collectionsr   r>   sympy.core.symbolr   r   sympy.ntheory.primetestr   sympy.polys.domainsr   sympy.polys.densebasicr	   sympy.polys.densetoolsr
   sympy.polys.euclidtoolsr   sympy.polys.factortoolsr   r   *sympy.polys.numberfields.galois_resolventsr   r   r   r   "sympy.polys.numberfields.utilitiesr   sympy.polys.polytoolsr   r   r   r   sympy.polys.sqfreetoolsr   sympy.utilitiesr   r   rR   rV   r]   r   r   r   r   r   r   r   r   r    <module>r      s    $ # # # # #  , , , , , , , , - - - - - - " " " " " " - - - - - - + + + + + + 4 4 4 4 4 4 F F F F F F F F            < ; ; ; ; ;J J J J J J J J J J J J - - - - - - " " " " " "    ,    IM-1h h h hV  4 4 4 4T T T Tn(- (- (- (-VN N N Nb*0 *0 *0 *0ZZ9 Z9 Z9 Z9z #(B% j/ j/ j/ j/ j/ j/ j/r   