U
    L?h                     @   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   Q/var/www/html/venv/lib/python3.8/site-packages/sympy/polys/domains/integerring.py__init__3   s    zIntegerRing.__init__c                 C   s   t |trdS tS dS )z0Returns ``True`` if two domains are equivalent. TN)
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__=   s    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   s4   |j rt|jS t|r$tt|S td| dS )z&Convert SymPy's Integer to ``dtype``. zexpected an integer, got %sN)
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)Z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)Z	is_groundconvertZ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   r4      s    zIntegerRing.logc                 C   s   t ||S z3Convert ``ModularInteger(int)`` to GMPY's ``mpz``. r   Zto_intr.   r   r   r   from_FF   s    zIntegerRing.from_FFc                 C   s   t ||S r7   r8   r.   r   r   r   from_FF_python   s    zIntegerRing.from_FF_pythonc                 C   s   t |S z,Convert Python's ``int`` to GMPY's ``mpz``. r   r.   r   r   r   from_ZZ   s    zIntegerRing.from_ZZc                 C   s   t |S r;   r<   r.   r   r   r   from_ZZ_python   s    zIntegerRing.from_ZZ_pythonc                 C   s   |j dkrt|jS dS z1Convert Python's ``Fraction`` to GMPY's ``mpz``. r   Ndenominatorr   	numeratorr.   r   r   r   from_QQ   s    
zIntegerRing.from_QQc                 C   s   |j dkrt|jS dS r?   r@   r.   r   r   r   from_QQ_python   s    
zIntegerRing.from_QQ_pythonc                 C   s   t ||S )z3Convert ``ModularInteger(mpz)`` to GMPY's ``mpz``. r8   r.   r   r   r   from_FF_gmpy   s    zIntegerRing.from_FF_gmpyc                 C   s   |S )z*Convert GMPY's ``mpz`` to GMPY's ``mpz``. r   r.   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)rA   rB   r.   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)Zto_rationalr   r    )r/   r"   r0   r%   qr   r   r   from_RealField   s    zIntegerRing.from_RealFieldc                 C   s   |j dkr|jS d S )Nr   )yxr.   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&   r.   r   r   r   from_EX   s    zIntegerRing.from_EXc                 C   s0   t ||\}}}tdkr"|||fS |||fS dS )z)Compute extended GCD of ``a`` and ``b``. ZgmpyN)r   r   )r   r"   r6   hstr   r   r   r      s    
zIntegerRing.gcdexc                 C   s
   t ||S )z Compute GCD of ``a`` and ``b``. )r   r5   r   r   r   r      s    zIntegerRing.gcdc                 C   s
   t ||S )z Compute LCM of ``a`` and ``b``. )r	   r5   r   r   r   r	      s    zIntegerRing.lcmc                 C   s   t |S )zCompute square root of ``a``. )r
   r!   r   r   r   r
      s    zIntegerRing.sqrtc                 C   s   t |S )zReturn ``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   s   t |S )zCompute factorial of ``a``. )r   r!   r   r   r   r     s    zIntegerRing.factorial).__name__
__module____qualname____doc__repr)   r   r2   zeroonetypetpZis_IntegerRingZis_ZZZis_NumericalZis_PIDZhas_assoc_RingZhas_assoc_Fieldr   r   r   r#   r&   r(   r*   r1   r4   r9   r:   r=   r>   rC   rD   rE   rF   rG   rI   rL   rM   r   r   r	   r
   r   rS   r   r   r   r   r   r      sP   	 
	
r   )rW   Zsympy.external.gmpyr   r   Zsympy.core.numbersr   Zsympy.polys.domains.groundtypesr   r   r   r   r	   r
   r   r   Z&sympy.polys.domains.characteristiczeror   Zsympy.polys.domains.ringr   Z sympy.polys.domains.simpledomainr   Zsympy.polys.polyerrorsr   Zsympy.utilitiesr   r3   r   r   r   r   r   r   <module>   s   (  