o
    jg  ã                   @   s®   d Z ddlmZmZ ddlmZ ddlmZmZm	Z	m
Z
mZmZ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ZeG dd„ deeeƒƒZeƒ Zd
S )z.Implementation of :class:`IntegerRing` class. é    )ÚMPZÚGROUND_TYPES)Ú
int_valued)ÚSymPyIntegerÚ	factorialÚgcdexÚgcdÚlcmÚsqrtÚ	is_squareÚsqrtrem)ÚCharacteristicZero)ÚRing)ÚSimpleDomain)ÚCoercionFailed)ÚpublicNc                   @   s2  e Zd ZdZdZdZeZedƒZedƒZ	e
e	ƒZd ZZdZdZdZdZdd„ Zdd	„ Zd
d„ Zdd„ Zdd„ Zdd„ Zddœdd„Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zd d!„ Zd"d#„ Zd$d%„ Z d&d'„ Z!d(d)„ Z"d*d+„ Z#d,d-„ Z$d.d/„ Z%d0d1„ Z&d2d3„ Z'd4d5„ Z(d6d7„ Z)d8d9„ Z*d:d;„ Z+d<d=„ Z,d>d?„ Z-dS )@ÚIntegerRingaÌ  The domain ``ZZ`` representing the integers `\mathbb{Z}`.

    The :py:class:`IntegerRing` class represents the ring of integers as a
    :py:class:`~.Domain` in the domain system. :py:class:`IntegerRing` is a
    super class of :py:class:`PythonIntegerRing` and
    :py:class:`GMPYIntegerRing` one of which will be the implementation for
    :ref:`ZZ` depending on whether or not ``gmpy`` or ``gmpy2`` is installed.

    See also
    ========

    Domain
    ÚZZr   é   Tc                 C   s   dS )z$Allow instantiation of this domain. N© ©Úselfr   r   úW/var/www/html/zoom/venv/lib/python3.10/site-packages/sympy/polys/domains/integerring.pyÚ__init__3   s    zIntegerRing.__init__c                 C   s   t |tƒrdS tS )z0Returns ``True`` if two domains are equivalent. T)Ú
isinstancer   ÚNotImplemented)r   Úotherr   r   r   Ú__eq__6   s   
zIntegerRing.__eq__c                 C   s   t dƒS )z&Compute a hash value for this domain. r   )Úhashr   r   r   r   Ú__hash__=   ó   zIntegerRing.__hash__c                 C   s   t t|ƒƒS )z!Convert ``a`` to a SymPy object. )r   Úint©r   Úar   r   r   Úto_sympyA   s   zIntegerRing.to_sympyc                 C   s0   |j rt|jƒS t|ƒrtt|ƒƒS td| ƒ‚)z&Convert SymPy's Integer to ``dtype``. zexpected an integer, got %s)Ú
is_Integerr   Úpr   r!   r   r"   r   r   r   Ú
from_sympyE   s
   
zIntegerRing.from_sympyc                 C   s   ddl m} |S )as  Return the associated field of fractions :ref:`QQ`

        Returns
        =======

        :ref:`QQ`:
            The associated field of fractions :ref:`QQ`, a
            :py:class:`~.Domain` representing the rational numbers
            `\mathbb{Q}`.

        Examples
        ========

        >>> from sympy import ZZ
        >>> ZZ.get_field()
        QQ
        r   )ÚQQ)Úsympy.polys.domainsr(   )r   r(   r   r   r   Ú	get_fieldN   s   zIntegerRing.get_fieldN)Úaliasc                G   s   |   ¡ j|d|iŽS )a  Returns an algebraic field, i.e. `\mathbb{Q}(\alpha, \ldots)`.

        Parameters
        ==========

        *extension : One or more :py:class:`~.Expr`.
            Generators of the extension. These should be expressions that are
            algebraic over `\mathbb{Q}`.

        alias : str, :py:class:`~.Symbol`, None, optional (default=None)
            If provided, this will be used as the alias symbol for the
            primitive element of the returned :py:class:`~.AlgebraicField`.

        Returns
        =======

        :py:class:`~.AlgebraicField`
            A :py:class:`~.Domain` representing the algebraic field extension.

        Examples
        ========

        >>> from sympy import ZZ, sqrt
        >>> ZZ.algebraic_field(sqrt(2))
        QQ<sqrt(2)>
        r+   )r*   Úalgebraic_field)r   r+   Ú	extensionr   r   r   r,   c   s   zIntegerRing.algebraic_fieldc                 C   s   |j r|  | ¡ |j¡S dS )zcConvert a :py:class:`~.ANP` object to :ref:`ZZ`.

        See :py:meth:`~.Domain.convert`.
        N)Ú	is_groundÚconvertÚLCÚdom©ÚK1r#   ÚK0r   r   r   Úfrom_AlgebraicField€   s   ÿzIntegerRing.from_AlgebraicFieldc                 C   s   |   tt t|ƒ|¡ƒ¡S )a*  Logarithm of *a* to the base *b*.

        Parameters
        ==========

        a: number
        b: number

        Returns
        =======

        $\\lfloor\log(a, b)\\rfloor$:
            Floor of the logarithm of *a* to the base *b*

        Examples
        ========

        >>> from sympy import ZZ
        >>> ZZ.log(ZZ(8), ZZ(2))
        3
        >>> ZZ.log(ZZ(9), ZZ(2))
        3

        Notes
        =====

        This function uses ``math.log`` which is based on ``float`` so it will
        fail for large integer arguments.
        )Údtyper!   ÚmathÚlog©r   r#   Úbr   r   r   r8   ˆ   s   zIntegerRing.logc                 C   ó   t | |¡ƒS ©z3Convert ``ModularInteger(int)`` to GMPY's ``mpz``. ©r   Úto_intr2   r   r   r   Úfrom_FF¨   ó   zIntegerRing.from_FFc                 C   r;   r<   r=   r2   r   r   r   Úfrom_FF_python¬   r@   zIntegerRing.from_FF_pythonc                 C   ó   t |ƒS ©z,Convert Python's ``int`` to GMPY's ``mpz``. ©r   r2   r   r   r   Úfrom_ZZ°   r    zIntegerRing.from_ZZc                 C   rB   rC   rD   r2   r   r   r   Úfrom_ZZ_python´   r    zIntegerRing.from_ZZ_pythonc                 C   ó   |j dkr
t|jƒS dS ©z1Convert Python's ``Fraction`` to GMPY's ``mpz``. r   N©Údenominatorr   Ú	numeratorr2   r   r   r   Úfrom_QQ¸   ó   

ÿzIntegerRing.from_QQc                 C   rG   rH   rI   r2   r   r   r   Úfrom_QQ_python½   rM   zIntegerRing.from_QQ_pythonc                 C   r;   )z3Convert ``ModularInteger(mpz)`` to GMPY's ``mpz``. r=   r2   r   r   r   Úfrom_FF_gmpyÂ   r@   zIntegerRing.from_FF_gmpyc                 C   s   |S )z*Convert GMPY's ``mpz`` to GMPY's ``mpz``. r   r2   r   r   r   Úfrom_ZZ_gmpyÆ   s   zIntegerRing.from_ZZ_gmpyc                 C   s   |j dkr|jS dS )z(Convert GMPY ``mpq`` to GMPY's ``mpz``. r   N)rJ   rK   r2   r   r   r   Úfrom_QQ_gmpyÊ   s   
ÿzIntegerRing.from_QQ_gmpyc                 C   s&   |  |¡\}}|dkrtt|ƒƒS dS )z,Convert mpmath's ``mpf`` to GMPY's ``mpz``. r   N)Úto_rationalr   r!   )r3   r#   r4   r&   Úqr   r   r   Úfrom_RealFieldÏ   s   üzIntegerRing.from_RealFieldc                 C   s   |j dkr|jS d S )Nr   )ÚyÚxr2   r   r   r   Úfrom_GaussianIntegerRingÙ   s   
ÿz$IntegerRing.from_GaussianIntegerRingc                 C   s   |j r|  |¡S dS )z*Convert ``Expression`` to GMPY's ``mpz``. N)r%   r'   r2   r   r   r   Úfrom_EXÝ   s   
ÿzIntegerRing.from_EXc                 C   s,   t ||ƒ\}}}tdkr|||fS |||fS )z)Compute extended GCD of ``a`` and ``b``. Úgmpy)r   r   )r   r#   r:   ÚhÚsÚtr   r   r   r   â   s   

zIntegerRing.gcdexc                 C   ó
   t ||ƒS )z Compute GCD of ``a`` and ``b``. )r   r9   r   r   r   r   ë   ó   
zIntegerRing.gcdc                 C   r]   )z Compute LCM of ``a`` and ``b``. )r	   r9   r   r   r   r	   ï   r^   zIntegerRing.lcmc                 C   rB   )zCompute square root of ``a``. )r
   r"   r   r   r   r
   ó   r    zIntegerRing.sqrtc                 C   rB   )zÅReturn ``True`` if ``a`` is a square.

        Explanation
        ===========
        An integer is a square if and only if there exists an integer
        ``b`` such that ``b * b == a``.
        )r   r"   r   r   r   r   ÷   s   zIntegerRing.is_squarec                 C   s(   |dk rdS t |ƒ\}}|dkrdS |S )zuNon-negative square root of ``a`` if ``a`` is a square.

        See also
        ========
        is_square
        r   N)r   )r   r#   ÚrootÚremr   r   r   Úexsqrt  s   zIntegerRing.exsqrtc                 C   rB   )zCompute factorial of ``a``. )r   r"   r   r   r   r     r    zIntegerRing.factorial).Ú__name__Ú
__module__Ú__qualname__Ú__doc__Úrepr+   r   r6   ÚzeroÚoneÚtypeÚtpÚis_IntegerRingÚis_ZZÚis_NumericalÚis_PIDÚhas_assoc_RingÚhas_assoc_Fieldr   r   r   r$   r'   r*   r,   r5   r8   r?   rA   rE   rF   rL   rN   rO   rP   rQ   rT   rW   rX   r   r   r	   r
   r   ra   r   r   r   r   r   r      sR    	 
	
r   )re   Úsympy.external.gmpyr   r   Úsympy.core.numbersr   Úsympy.polys.domains.groundtypesr   r   r   r   r	   r
   r   r   Ú&sympy.polys.domains.characteristiczeror   Úsympy.polys.domains.ringr   Ú sympy.polys.domains.simpledomainr   Úsympy.polys.polyerrorsr   Úsympy.utilitiesr   r7   r   r   r   r   r   r   Ú<module>   s    (  
