§
    OŠtjE   ã                   ó’   — d 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mZ dd	lmZ d
„ Zdd„Zd„ Ze
dd„¦   «         ZdS )z,Computing integral bases for number fields. é    )ÚPoly)ÚAlgebraicField)ÚZZ)ÚQQ)Úpublicé   )ÚModuleEndomorphismÚModuleHomomorphismÚ
PowerBasis)Ú extract_fundamental_discriminantc                 ó¾  — | j         }t          | |¬¦  «        }|                     ¦   «         \  }}|dk    sJ ‚t          d||¬¦  «        }|D ]
\  }}||z  }Œ||z  }	t          |t          ¬¦  «        }
t          |	t          ¬¦  «        }|
|z  | z
  |z  }t          ||¬¦  «        }|}||	fD ]}|                     |¦  «        }Œ||z  }|                     ¦   «         }||fS )zz
    Apply the "Dedekind criterion" to test whether the order needs to be
    enlarged relative to a given prime *p*.
    ©Úmodulusr   ©Údomain)Úgenr   Úfactor_listr   ÚgcdÚdegree)ÚTÚpÚxÚT_barÚlcÚflÚg_barÚti_barÚ_Úh_barÚgÚhÚfÚf_barÚZ_barÚbÚU_barÚms                     ú\/var/www/html/CA-Chatbot/venv/lib/python3.11/site-packages/sympy/polys/numberfields/basis.pyÚ_apply_Dedekind_criterionr)      s
  € ð
 	
Œ€AÝ�˜AÐÑÔ€EØ×ÒÑ Ô �F€BˆØ�Š7ˆ7ˆ7ˆ7Ý��A˜qÐ!Ñ!Ô!€EØð ð ‰	ˆ�Ø�‰ˆˆØ�U‰N€EÝˆU�2ÐÑÔ€AÝˆU�2ÐÑÔ€AØ	
ˆQ‰�‰�qÑ€AÝ�˜AÐÑÔ€EØ€EØ�Uˆ^ð ð ˆØ—	’	˜!‘”ˆˆØ�U‰N€EØ�Š‰Œ€AØ�!ˆ8€Oó    Nc                 óŽ   ‡— | j         }‰€|Š‰|k     r‰|z  Š‰|k     °t          | ˆfd„¦  «        }|                     |¬¦  «        S )aþ  
    Compute the nilradical mod *p* for a given order *H*, and prime *p*.

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

    This is the ideal $I$ in $H/pH$ consisting of all elements some positive
    power of which is zero in this quotient ring, i.e. is a multiple of *p*.

    Parameters
    ==========

    H : :py:class:`~.Submodule`
        The given order.
    p : int
        The rational prime.
    q : int, optional
        If known, the smallest power of *p* that is $>=$ the dimension of *H*.
        If not provided, we compute it here.

    Returns
    =======

    :py:class:`~.Module` representing the nilradical mod *p* in *H*.

    References
    ==========

    .. [1] Cohen, H. *A Course in Computational Algebraic Number Theory*.
    (See Lemma 6.1.6.)

    Nc                 ó   •— | ‰z  S ©N© )r   Úqs    €r(   ú<lambda>z"nilradical_mod_p.<locals>.<lambda>K   s   ø€ ¨!¨Q©$€ r*   r   )Únr	   Úkernel)ÚHr   r/   r1   Úphis     `  r(   Únilradical_mod_pr5   %   s]   ø€ ðB 	
Œ€AØ€yØˆØ�!ŠeˆeØ�‰FˆAð �!Šeˆeå
˜Q    Ñ
/Ô
/€CØ�:Š:˜aˆ:Ñ Ô Ð r*   c                 ó„  ‡
— t          | ||¬¦  «        }| j                             | j        |j        z  | j        ¬¦  «        }||| z  z   }|                     ¦   «         Š
t          | ‰
ˆ
fd„¦  «        }|                     |¬¦  «        }| j                             | j        |j        z  | j        |z  ¬¦  «        }|| z   }	|	|fS )zD
    Perform the second enlargement in the Round Two algorithm.
    )r/   )Údenomc                 ó.   •— ‰                      | ¦  «        S r-   )Úinner_endomorphism)r   ÚEs    €r(   r0   z%_second_enlargement.<locals>.<lambda>W   s   ø€ ¨Q×-AÒ-AÀ!Ñ-DÔ-D€ r*   r   )r5   ÚparentÚsubmodule_from_matrixÚmatrixr7   Úendomorphism_ringr
   r2   )r3   r   r/   ÚIpÚBÚCr4   ÚgammaÚGÚH1r:   s             @r(   Ú_second_enlargementrE   O   sÆ   ø€ õ 
˜!˜Q !Ð	$Ñ	$Ô	$€BØ	Œ×&Ò& q¤x°"´)Ñ';À1Ä7Ð&ÑKÔK€AØ	ˆAˆa‰C‰€AØ	×ÒÑÔ€AÝ
˜Q Ð#DÐ#DÐ#DÐ#DÑ
EÔ
E€CØ�JŠJ˜qˆJÑ!Ô!€EØ	Œ×&Ò& q¤x°%´,Ñ'>ÀaÄgÐPQÁkÐ&ÑRÔR€AØ	
ˆQ‰€BØˆrˆ6€Mr*   c                 óL  — d}t          | t          ¦  «        r| | j                             ¦   «         } }| j        r| j        r| j        t          t          fvrt          d¦  «        ‚|  
                    ¦   «         \  } }|                      ¦   «         }|                      ¦   «         }t          j        t          |¦  «        ¦  «        }t          |¦  «        \  }}t!          |p| ¦  «        }|                     ¦   «         }	d}
|rÉ|                     ¦   «         \  }}t'          | |¦  «        \  }}|dk    rŒ3|                     t+          |t          ¬¦  «        ¦  «        }|	                     ||z  |	z  |¬¦  «        }	||k    rŒ€|}||k     r||z  }||k     °t/          |	||¦  «        \  }}
||	k    r|}	t/          |	||¦  «        \  }}
||	k    °|°É|
�t          |t0          ¦  «        r|
||<   |	}d|_        d|_        ||j                             ¦   «         dz  z  |j        d|z  z  z  }||fS )a  
    Zassenhaus's "Round 2" algorithm.

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

    Carry out Zassenhaus's "Round 2" algorithm on an irreducible polynomial
    *T* over :ref:`ZZ` or :ref:`QQ`. This computes an integral basis and the
    discriminant for the field $K = \mathbb{Q}[x]/(T(x))$.

    Alternatively, you may pass an :py:class:`~.AlgebraicField` instance, in
    place of the polynomial *T*, in which case the algorithm is applied to the
    minimal polynomial for the field's primitive element.

    Ordinarily this function need not be called directly, as one can instead
    access the :py:meth:`~.AlgebraicField.maximal_order`,
    :py:meth:`~.AlgebraicField.integral_basis`, and
    :py:meth:`~.AlgebraicField.discriminant` methods of an
    :py:class:`~.AlgebraicField`.

    Examples
    ========

    Working through an AlgebraicField:

    >>> from sympy import Poly, QQ
    >>> from sympy.abc import x
    >>> T = Poly(x ** 3 + x ** 2 - 2 * x + 8)
    >>> K = QQ.alg_field_from_poly(T, "theta")
    >>> print(K.maximal_order())
    Submodule[[2, 0, 0], [0, 2, 0], [0, 1, 1]]/2
    >>> print(K.discriminant())
    -503
    >>> print(K.integral_basis(fmt='sympy'))
    [1, theta, theta/2 + theta**2/2]

    Calling directly:

    >>> from sympy import Poly
    >>> from sympy.abc import x
    >>> from sympy.polys.numberfields.basis import round_two
    >>> T = Poly(x ** 3 + x ** 2 - 2 * x + 8)
    >>> print(round_two(T))
    (Submodule[[2, 0, 0], [0, 2, 0], [0, 1, 1]]/2, -503)

    The nilradicals mod $p$ that are sometimes computed during the Round Two
    algorithm may be useful in further calculations. Pass a dictionary under
    `radicals` to receive these:

    >>> T = Poly(x**3 + 3*x**2 + 5)
    >>> rad = {}
    >>> ZK, dK = round_two(T, radicals=rad)
    >>> print(rad)
    {3: Submodule[[-1, 1, 0], [-1, 0, 1]]}

    Parameters
    ==========

    T : :py:class:`~.Poly`, :py:class:`~.AlgebraicField`
        Either (1) the irreducible polynomial over :ref:`ZZ` or :ref:`QQ`
        defining the number field, or (2) an :py:class:`~.AlgebraicField`
        representing the number field itself.

    radicals : dict, optional
        This is a way for any $p$-radicals (if computed) to be returned by
        reference. If desired, pass an empty dictionary. If the algorithm
        reaches the point where it computes the nilradical mod $p$ of the ring
        of integers $Z_K$, then an $\mathbb{F}_p$-basis for this ideal will be
        stored in this dictionary under the key ``p``. This can be useful for
        other algorithms, such as prime decomposition.

    Returns
    =======

    Pair ``(ZK, dK)``, where:

        ``ZK`` is a :py:class:`~sympy.polys.numberfields.modules.Submodule`
        representing the maximal order.

        ``dK`` is the discriminant of the field $K = \mathbb{Q}[x]/(T(x))$.

    See Also
    ========

    .AlgebraicField.maximal_order
    .AlgebraicField.integral_basis
    .AlgebraicField.discriminant

    References
    ==========

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

    NzDRound 2 requires an irreducible univariate polynomial over ZZ or QQ.r   r   )Úhnf_modulusTé   )Ú
isinstancer   ÚextÚminpoly_of_elementÚis_univariateÚis_irreducibler   r   r   Ú
ValueErrorÚ)make_monic_over_integers_by_scaling_rootsr   ÚdiscriminantÚ
from_sympyÚabsr   r   Úwhole_submoduleÚpopitemr)   Úelement_from_polyr   ÚaddrE   ÚdictÚ_starts_with_unityÚ_is_sq_maxrank_HNFr=   Údetr7   )r   ÚradicalsÚKr   r1   ÚDÚ	D_modulusÚFÚZthetar3   Únilradr   Úer&   r'   ÚUr/   rD   ÚZKÚdKs                       r(   Ú	round_tworf   ^   sH  € ð@ 	€AÝ�!•^Ñ$Ô$ð -Ø�!”%×*Ò*Ñ,Ô,ˆ1ˆØŒð aØÔðaàŒ8�B¥˜8Ð#Ð#ÝÐ_Ñ`Ô`Ð`Ø×6Ò6Ñ8Ô8�D€A€qØ	�Š‰
Œ
€AØ	�ŠÑÔ€AÝ”�c !™fœfÑ%Ô%€Iõ ,¨AÑ.Ô.�D€A€qÝ˜˜˜QÑÔ€FØ×ÒÑ Ô €AØ€FØ
ð 6à�yŠy‰{Œ{‰ˆˆ1Ý,¨Q°Ñ2Ô2‰ˆˆqØ�Š6ˆ6Øð ×$Ò$¥T¨%½Ð%;Ñ%;Ô%;Ñ<Ô<ˆð
 �EŠE�!�q‘&˜1‘*¨)ˆEÑ4Ô4ˆØ�Š6ˆ6Øð ˆØ�!ŠeˆeØ�‰FˆAð �!Šeˆeå(¨¨A¨qÑ1Ô1‰
ˆˆFØ�AŠgˆgØˆAÝ,¨Q°°1Ñ5Ô5‰JˆB�ð �AŠgˆgð- ð 6ð@ Ð�j¨µ4Ñ8Ô8ÐØˆ�‰Ø	
€Bà €BÔØ €BÔØ
ˆbŒi�mŠm‰oŒo Ñ"Ñ
" r¤x°A¸±EÑ':Ñ	:€BØˆrˆ6€Mr*   r-   )Ú__doc__Úsympy.polys.polytoolsr   Ú"sympy.polys.domains.algebraicfieldr   Úsympy.polys.domains.integerringr   Ú!sympy.polys.domains.rationalfieldr   Úsympy.utilities.decoratorr   Úmodulesr	   r
   r   Ú	utilitiesr   r)   r5   rE   rf   r.   r*   r(   ú<module>ro      sø   ðØ 2Ð 2à &Ð &Ð &Ð &Ð &Ð &Ø =Ð =Ð =Ð =Ð =Ð =Ø .Ð .Ð .Ð .Ð .Ð .Ø 0Ð 0Ð 0Ð 0Ð 0Ð 0Ø ,Ð ,Ð ,Ð ,Ð ,Ð ,Ø GÐ GÐ GÐ GÐ GÐ GÐ GÐ GÐ GÐ GØ 7Ð 7Ð 7Ð 7Ð 7Ð 7ðð ð ð2'!ð '!ð '!ð '!ðTð ð ð ðWð Wð Wñ „ðWð Wð Wr*   