o
    oh]                     @   s  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 ddlmZ dd	lmZ d
dlmZmZ d
dlmZ d
dlmZmZ d
dlmZmZ dd ZG dd deZdd Zedd Zd$ddZ dd Z!dd Z"dd Z#d d! Z$ed%d"d#Z%dS )&zPrime ideals in number fields.     )Poly)FF)QQ)ZZ)DomainMatrix)CoercionFailed)IntegerPowerable)public   )	round_twonilradical_mod_p)StructureError)ModuleEndomorphismfind_min_poly)coeff_searchsupplement_a_subspacec                 C   sH   d}d}|   sd}n|  sd}n|  sd}|dur"t|| dS )a  
    Several functions in this module accept an argument which is to be a
    :py:class:`~.Submodule` representing the maximal order in a number field,
    such as returned by the :py:func:`~sympy.polys.numberfields.basis.round_two`
    algorithm.

    We do not attempt to check that the given ``Submodule`` actually represents
    a maximal order, but we do check a basic set of formal conditions that the
    ``Submodule`` must satisfy, at a minimum. The purpose is to catch an
    obviously ill-formed argument.
    z4The submodule representing the maximal order should Nz'be a direct submodule of a power basis.zhave 1 as its first generator.z<have square matrix, of maximal rank, in Hermite Normal Form.)is_power_basis_submodulestarts_with_unityis_sq_maxrank_HNFr   )	submoduleprefixcond r   s/var/www/html/construction_image-detection-poc/venv/lib/python3.10/site-packages/sympy/polys/numberfields/primes.py*_check_formal_conditions_for_maximal_order   s   r   c                   @   s   e Zd ZdZd$ddZdd Zedd Zd%d
dZdd Z	dd Z
dd Zdd ZeZdd ZeZdd Zdd Zdd Zdd Zdd Zd d! Zd"d# ZdS )&
PrimeIdealz8
    A prime ideal in a ring of algebraic integers.
    Nc                 C   sL   t | || _|| _|| _|| _d| _|dur|| _dS | || | _dS )a  
        Parameters
        ==========

        ZK : :py:class:`~.Submodule`
            The maximal order where this ideal lives.
        p : int
            The rational prime this ideal divides.
        alpha : :py:class:`~.PowerBasisElement`
            Such that the ideal is equal to ``p*ZK + alpha*ZK``.
        f : int
            The inertia degree.
        e : int, ``None``, optional
            The ramification index, if already known. If ``None``, we will
            compute it here.

        N)r   ZKpalphaf_test_factor	valuatione)selfr   r   r   r   r"   r   r   r   __init__.   s   &zPrimeIdeal.__init__c                 C   s.   | j r
d| j dS d| j d| j  dS )N(), )is_inertr   r   as_exprr#   r   r   r   __str__H   s   zPrimeIdeal.__str__c                 C   s   | j | jjkS )zv
        Say whether the rational prime we divide is inert, i.e. stays prime in
        our ring of integers.
        )r   r   nr*   r   r   r   r(   M   s   zPrimeIdeal.is_inertFc           	      C   s   |p| j jjj}| j| j| j| jf\}}}}t|j	|d
 }|jdkr.d| d|j }d| d| d}|r;|S d| d| d	| d
S )a  
        Print a representation of this prime ideal.

        Examples
        ========

        >>> from sympy import cyclotomic_poly, QQ
        >>> from sympy.abc import x, zeta
        >>> T = cyclotomic_poly(7, x)
        >>> K = QQ.algebraic_field((T, zeta))
        >>> P = K.primes_above(11)
        >>> print(P[0].repr())
        [ (11, x**3 + 5*x**2 + 4*x - 1) e=1, f=3 ]
        >>> print(P[0].repr(field_gen=zeta))
        [ (11, zeta**3 + 5*zeta**2 + 4*zeta - 1) e=1, f=3 ]
        >>> print(P[0].repr(field_gen=zeta, just_gens=True))
        (11, zeta**3 + 5*zeta**2 + 4*zeta - 1)

        Parameters
        ==========

        field_gen : :py:class:`~.Symbol`, ``None``, optional (default=None)
            The symbol to use for the generator of the field. This will appear
            in our representation of ``self.alpha``. If ``None``, we use the
            variable of the defining polynomial of ``self.ZK``.
        just_gens : bool, optional (default=False)
            If ``True``, just print the "(p, alpha)" part, showing "just the
            generators" of the prime ideal. Otherwise, print a string of the
            form "[ (p, alpha) e=..., f=... ]", giving the ramification index
            and inertia degree, along with the generators.

        xr
   r%   z)/r'   r&   z[ z e=z, f=z ])r   parentTgenr   r   r"   r   str	numeratorr)   denom)	r#   	field_gen	just_gensr   r   r"   r   	alpha_repgensr   r   r   reprU   s   !
zPrimeIdeal.reprc                 C   s   |   S N)r9   r*   r   r   r   __repr__   s   zPrimeIdeal.__repr__c                 C   s(   | j | j | j| j  }d|_d|_|S )a  
        Represent this prime ideal as a :py:class:`~.Submodule`.

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

        The :py:class:`~.PrimeIdeal` class serves to bundle information about
        a prime ideal, such as its inertia degree, ramification index, and
        two-generator representation, as well as to offer helpful methods like
        :py:meth:`~.PrimeIdeal.valuation` and
        :py:meth:`~.PrimeIdeal.test_factor`.

        However, in order to be added and multiplied by other ideals or
        rational numbers, it must first be converted into a
        :py:class:`~.Submodule`, which is a class that supports these
        operations.

        In many cases, the user need not perform this conversion deliberately,
        since it is automatically performed by the arithmetic operator methods
        :py:meth:`~.PrimeIdeal.__add__` and :py:meth:`~.PrimeIdeal.__mul__`.

        Raising a :py:class:`~.PrimeIdeal` to a non-negative integer power is
        also supported.

        Examples
        ========

        >>> from sympy import Poly, cyclotomic_poly, prime_decomp
        >>> T = Poly(cyclotomic_poly(7))
        >>> P0 = prime_decomp(7, T)[0]
        >>> print(P0**6 == 7*P0.ZK)
        True

        Note that, on both sides of the equation above, we had a
        :py:class:`~.Submodule`. In the next equation we recall that adding
        ideals yields their GCD. This time, we need a deliberate conversion
        to :py:class:`~.Submodule` on the right:

        >>> print(P0 + 7*P0.ZK == P0.as_submodule())
        True

        Returns
        =======

        :py:class:`~.Submodule`
            Will be equal to ``self.p * self.ZK + self.alpha * self.ZK``.

        See Also
        ========

        __add__
        __mul__

        FT)r   r   r   _starts_with_unity_is_sq_maxrank_HNF)r#   Mr   r   r   as_submodule   s   7zPrimeIdeal.as_submodulec                 C   s   t |tr|  | kS tS r:   )
isinstancer   r?   NotImplementedr#   otherr   r   r   __eq__   s   
zPrimeIdeal.__eq__c                 C   s   |   | S )z
        Convert to a :py:class:`~.Submodule` and add to another
        :py:class:`~.Submodule`.

        See Also
        ========

        as_submodule

        r?   rB   r   r   r   __add__      zPrimeIdeal.__add__c                 C   s   |   | S )z
        Convert to a :py:class:`~.Submodule` and multiply by another
        :py:class:`~.Submodule` or a rational number.

        See Also
        ========

        as_submodule

        rE   rB   r   r   r   __mul__   rG   zPrimeIdeal.__mul__c                 C   s   | j S r:   )r   r*   r   r   r   _zeroth_power   s   zPrimeIdeal._zeroth_powerc                 C   s   | S r:   r   r*   r   r   r   _first_power   s   zPrimeIdeal._first_powerc                 C   s&   | j du rt| j| jg| j| _ | j S )aO  
        Compute a test factor for this prime ideal.

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

        Write $\mathfrak{p}$ for this prime ideal, $p$ for the rational prime
        it divides. Then, for computing $\mathfrak{p}$-adic valuations it is
        useful to have a number $\beta \in \mathbb{Z}_K$ such that
        $p/\mathfrak{p} = p \mathbb{Z}_K + \beta \mathbb{Z}_K$.

        Essentially, this is the same as the number $\Psi$ (or the "reagent")
        from Kummer's 1847 paper (*Ueber die Zerlegung...*, Crelle vol. 35) in
        which ideal divisors were invented.
        N)r    _compute_test_factorr   r   r   r*   r   r   r   test_factor   s   
zPrimeIdeal.test_factorc                 C   s
   t || S )z
        Compute the $\mathfrak{p}$-adic valuation of integral ideal I at this
        prime ideal.

        Parameters
        ==========

        I : :py:class:`~.Submodule`

        See Also
        ========

        prime_valuation

        )prime_valuation)r#   Ir   r   r   r!      s   
zPrimeIdeal.valuationc                 C   s   |   |S )a  
        Reduce a :py:class:`~.PowerBasisElement` to a "small representative"
        modulo this prime ideal.

        Parameters
        ==========

        elt : :py:class:`~.PowerBasisElement`
            The element to be reduced.

        Returns
        =======

        :py:class:`~.PowerBasisElement`
            The reduced element.

        See Also
        ========

        reduce_ANP
        reduce_alg_num
        .Submodule.reduce_element

        )r?   reduce_element)r#   eltr   r   r   rO     s   zPrimeIdeal.reduce_elementc                 C   s    | j j|}| |}| S )a  
        Reduce an :py:class:`~.ANP` to a "small representative" modulo this
        prime ideal.

        Parameters
        ==========

        elt : :py:class:`~.ANP`
            The element to be reduced.

        Returns
        =======

        :py:class:`~.ANP`
            The reduced element.

        See Also
        ========

        reduce_element
        reduce_alg_num
        .Submodule.reduce_element

        )r   r/   element_from_ANPrO   to_ANPr#   arP   redr   r   r   
reduce_ANP*  s   
zPrimeIdeal.reduce_ANPc                 C   s0   | j j|}| |}|tt|j S )a  
        Reduce an :py:class:`~.AlgebraicNumber` to a "small representative"
        modulo this prime ideal.

        Parameters
        ==========

        elt : :py:class:`~.AlgebraicNumber`
            The element to be reduced.

        Returns
        =======

        :py:class:`~.AlgebraicNumber`
            The reduced element.

        See Also
        ========

        reduce_element
        reduce_ANP
        .Submodule.reduce_element

        )	r   r/   element_from_alg_numrO   field_elementlistreversedQQ_colflatrS   r   r   r   reduce_alg_numG  s   
zPrimeIdeal.reduce_alg_numr:   )NF)__name__
__module____qualname____doc__r$   r+   propertyr(   r9   r;   r?   rD   rF   __radd__rH   __rmul__rI   rJ   rL   r!   rO   rV   r]   r   r   r   r   r   )   s*    


+=r   c                    sx   t | |   fdd|D }td|jftj| }| dddf  }|j	|j
|t |jd}|S )a  
    Compute the test factor for a :py:class:`~.PrimeIdeal` $\mathfrak{p}$.

    Parameters
    ==========

    p : int
        The rational prime $\mathfrak{p}$ divides

    gens : list of :py:class:`PowerBasisElement`
        A complete set of generators for $\mathfrak{p}$ over *ZK*, EXCEPT that
        an element equivalent to rational *p* can and should be omitted (since
        it has no effect except to waste time).

    ZK : :py:class:`~.Submodule`
        The maximal order where the prime ideal $\mathfrak{p}$ lives.

    Returns
    =======

    :py:class:`~.PowerBasisElement`

    References
    ==========

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

    c                    s   g | ]}  |jd qS )modulus)inner_endomorphismmatrix.0gEr   r   r   
<listcomp>  s    z(_compute_test_factor.<locals>.<listcomp>r   Nr4   )r   endomorphism_ringr   zerosr,   r   vstack	nullspace	transposer/   rh   
convert_tor   r4   )r   r8   r   matricesBr.   betar   rl   r   rK   e  s   rK   c                 C   sZ  |j |j}}|j|j|j}}}|t | j | | j }|t}|	 }|| dkr2dS |
 }	|| |	  }
|
| dk}d}	 || }t|D ])}|j|dd|f |d}||	9 }|| }t|D ]
}|| |||f< qmqO||d |d f j| dkr	 |S || }|rz|t}W n ty   Y |S w |t}|d7 }qG)a  
    Compute the *P*-adic valuation for an integral ideal *I*.

    Examples
    ========

    >>> from sympy import QQ
    >>> from sympy.polys.numberfields import prime_valuation
    >>> K = QQ.cyclotomic_field(5)
    >>> P = K.primes_above(5)
    >>> ZK = K.maximal_order()
    >>> print(prime_valuation(25*ZK, P[0]))
    8

    Parameters
    ==========

    I : :py:class:`~.Submodule`
        An integral ideal whose valuation is desired.

    P : :py:class:`~.PrimeIdeal`
        The prime at which to compute the valuation.

    Returns
    =======

    int

    See Also
    ========

    .PrimeIdeal.valuation

    References
    ==========

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

    r   TNro   r
   )r   r   r,   rh   r4   ru   r   invr   detrL   ranger/   	representr\   elementr   )rN   Pr   r   r,   WdADrx   r   need_complete_testvjcir   r   r   rM     sD   *

rM   Nc                    s   t | |j}|j}t fdd| D r| S |du r0|dur& | }n
t|| j }|	 } fdd|dd D }|| 7 }t
t|d}	|	D ]!}
tdd t|
|D }||| }|  dkro|    S qNdS )	a  
    Given a set of *ZK*-generators of a prime ideal, compute a set of just two
    *ZK*-generators for the same ideal, one of which is *p* itself.

    Parameters
    ==========

    gens : list of :py:class:`PowerBasisElement`
        Generators for the prime ideal over *ZK*, the ring of integers of the
        field $K$.

    ZK : :py:class:`~.Submodule`
        The maximal order in $K$.

    p : int
        The rational prime divided by the prime ideal.

    f : int, optional
        The inertia degree of the prime ideal, if known.

    Np : int, optional
        The norm $p^f$ of the prime ideal, if known.
        NOTE: There is no reason to supply both *f* and *Np*. Either one will
        save us from having to compute the norm *Np* ourselves. If both are known,
        *Np* is preferred since it saves one exponentiation.

    Returns
    =======

    :py:class:`~.PowerBasisElement` representing a single algebraic integer
    alpha such that the prime ideal is equal to ``p*ZK + alpha*ZK``.

    References
    ==========

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

    c                 3   s    | ]
}|   d V  qdS )r   N)equivri   r   r   r   	<genexpr>  s    z_two_elt_rep.<locals>.<genexpr>Nc                    s   g | ]} | qS r   r   rj   omr   r   r   rn   #  s    z _two_elt_rep.<locals>.<listcomp>r
   c                 s   s    | ]	\}}|| V  qd S r:   r   )rj   cibetair   r   r   r   '  s    r   )r   r/   r0   allzeroabssubmodule_from_gensrh   rz   basis_element_pullbacksr   lensumzipnorm)r8   r   r   r   Nppbr0   omegarx   searchr   r   r,   r   r   r   _two_elt_rep  s(   (
r   c                    sj    j j}t|d}| \}}t|dkr+|d d dkr+t  j   jdgS  fdd|D S )a?  
    Compute the decomposition of rational prime *p* in the ring of integers
    *ZK* (given as a :py:class:`~.Submodule`), in the "easy case", i.e. the
    case where *p* does not divide the index of $\theta$ in *ZK*, where
    $\theta$ is the generator of the ``PowerBasis`` of which *ZK* is a
    ``Submodule``.
    re   r
   r   c                    s4   g | ]\}}t   jt|td | |qS domain)r   r/   element_from_polyr   r   degree)rj   tr"   r   r   r   r   rn   >  s    z+_prime_decomp_easy_case.<locals>.<listcomp>)r/   r0   r   factor_listr   r   r   r,   )r   r   r0   T_barlcflr   r   r   _prime_decomp_easy_case1  s   r   c           
         s   | j }|j\}}|dkr||t}n|||tdddf }|jd |k r5t|t t}||}|	  |
|}t| fdd}|j d}	|	 sXJ |	|fS )a+  
    Parameters
    ==========

    I : :py:class:`~.Module`
        An ideal of ``ZK/pZK``.
    p : int
        The rational prime being factored.
    ZK : :py:class:`~.Submodule`
        The maximal order.

    Returns
    =======

    Pair ``(N, G)``, where:

        ``N`` is a :py:class:`~.Module` representing the kernel of the map
        ``a |--> a**p - a`` on ``(O/pO)/I``, guaranteed to be a module with
        unity.

        ``G`` is a :py:class:`~.Module` representing a basis for the separable
        algebra ``A = O/I`` (see Cohen).

    r   Nr
   c                    s   |   |  S r:   r   r-   r   r   r   <lambda>s  s    z._prime_decomp_compute_kernel.<locals>.<lambda>re   )rh   shapeeyer   hstackr   ru   r   submodule_from_matrixcompute_mult_tabdiscard_beforer   kernelr   )
rN   r   r   r   r,   rrw   GphiNr   r   r   _prime_decomp_compute_kernelD  s   


r   c                    s\   | j j\}}|| }j | j    fddt jd D }t|||d}t|||S )a  
    We have reached the case where we have a maximal (hence prime) ideal *I*,
    which we know because the quotient ``O/I`` is a field.

    Parameters
    ==========

    I : :py:class:`~.Module`
        An ideal of ``O/pO``.
    p : int
        The rational prime being factored.
    ZK : :py:class:`~.Submodule`
        The maximal order.

    Returns
    =======

    :py:class:`~.PrimeIdeal` instance representing this prime

    c                    s(   g | ]}j  d d |f jdqS )Nro   )r/   r4   )rj   r   r   r   r   r   rn     s   ( z/_prime_decomp_maximal_ideal.<locals>.<listcomp>r
   )r   )rh   r   r{   r   r   )rN   r   r   mr,   r   r8   r   r   r   r   _prime_decomp_maximal_idealy  s   r   c                    sR  | j |kr|j |u r|j |u sJ |d }|j|u sJ g t|td}| \}}|d d }	||	}
|	|
\}}}|dksHJ tt	t
||	 tdj  t fddtt D }d| }||g}g }|D ]3}| j|u sJ | jtjfdd| D  }| t}||}|| qs|S )	z
    Perform the step in the prime decomposition algorithm where we have determined
    the quotient ``ZK/I`` is _not_ a field, and we want to perform a non-trivial
    factorization of *I* by locating an idempotent element of ``ZK/I``.
    r
   )powersr   r   c                 3   s     | ]} | |  V  qd S r:   r   )rj   r   )rm   alpha_powersr   r   r     s    z,_prime_decomp_split_ideal.<locals>.<genexpr>c                    s    g | ]} | j td qS r   )columnr   r   )r"   r   r   r   rn     s    z-_prime_decomp_split_ideal.<locals>.<listcomp>)r/   	to_parentmoduler   r   r   quogcdexrY   rZ   r   r   repto_listr   r{   r   rh   ru   r   basis_elementscolumnspacer   append)rN   r   r   r   r   r   r   r   r   m1m2UVrk   eps1eps2idempsfactorsepsr   r   Hr   )rm   r   r"   r   r   _prime_decomp_split_ideal  s2   "
 
r   c                 C   s  |du r|du rt d|durt| |du r|jj}i }|du s&|du r.t||d\}}| }|| }||  dkrAt| |S |pL|| pLt|| }|g}g }	|r|	 }
t
|
| |\}}|jdkrqt|
| |}|	| nt|
| |||\}}|||g |sT|	S )a  
    Compute the decomposition of rational prime *p* in a number field.

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

    Ordinarily this should be accessed through the
    :py:meth:`~.AlgebraicField.primes_above` method of an
    :py:class:`~.AlgebraicField`.

    Examples
    ========

    >>> from sympy import Poly, QQ
    >>> from sympy.abc import x, theta
    >>> T = Poly(x ** 3 + x ** 2 - 2 * x + 8)
    >>> K = QQ.algebraic_field((T, theta))
    >>> print(K.primes_above(2))
    [[ (2, x**2 + 1) e=1, f=1 ], [ (2, (x**2 + 3*x + 2)/2) e=1, f=1 ],
     [ (2, (3*x**2 + 3*x)/2) e=1, f=1 ]]

    Parameters
    ==========

    p : int
        The rational prime whose decomposition is desired.

    T : :py:class:`~.Poly`, optional
        Monic irreducible polynomial defining the number field $K$ in which to
        factor. NOTE: at least one of *T* or *ZK* must be provided.

    ZK : :py:class:`~.Submodule`, optional
        The maximal order for $K$, if already known.
        NOTE: at least one of *T* or *ZK* must be provided.

    dK : int, optional
        The discriminant of the field $K$, if already known.

    radical : :py:class:`~.Submodule`, optional
        The nilradical mod *p* in the integers of $K$, if already known.

    Returns
    =======

    List of :py:class:`~.PrimeIdeal` instances.

    References
    ==========

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

    Nz)At least one of T or ZK must be provided.)radicalsr   r
   )
ValueErrorr   r/   r0   r   discriminantr   getr   popr   r,   r   r   r   extend)r   r0   r   dKradicalr   dT	f_squaredstackprimesrN   r   r   r~   I1I2r   r   r   prime_decomp  s4   7

	r   )NN)NNNN)&ra   sympy.polys.polytoolsr   sympy.polys.domains.finitefieldr   !sympy.polys.domains.rationalfieldr   sympy.polys.domains.integerringr   !sympy.polys.matrices.domainmatrixr   sympy.polys.polyerrorsr   sympy.polys.polyutilsr   sympy.utilities.decoratorr	   basisr   r   
exceptionsr   modulesr   r   	utilitiesr   r   r   r   rK   rM   r   r   r   r   r   r   r   r   r   r   <module>   s6      >.

XE5*