U
    ZÊ¹j€ž  ã                   @  sÀ   d 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 ddlmZ dd	lmZ dd
lmZmZmZ ddlmZmZ ddlmZ ddlmZ eG dd„ dƒƒZdgZdS )z)Implementation of :class:`Domain` class. é    )Úannotations)ÚAny)ÚAlgebraicNumber)ÚBasicÚsympify)Úordered)ÚGROUND_TYPES)ÚDomainElement)Úlex)ÚUnificationFailedÚCoercionFailedÚDomainError)Ú_unify_gensÚ_not_a_coeff)Úpublic)Úis_sequencec                   @  s¸  e Zd ZU dZdZded< dZded< dZded< dZdZ	dZ
dZd ZZd ZZd ZZd ZZd ZZd ZZd ZZd ZZd ZZd ZZd Z Z!d Z"Z#dZ$d	Z%dZ&dZ'dZ(dZ)dZ*dZ+d
ed< dZ,d
ed< dd„ Z-dd„ Z.dd„ Z/dd„ Z0dd„ Z1e2dd„ ƒZ3dd„ Z4dd„ Z5dd„ Z6d¿dd „Z7d!d"„ Z8d#d$„ Z9d%d&„ Z:d'd(„ Z;d)d*„ Z<d+d,„ Z=d-d.„ Z>d/d0„ Z?d1d2„ Z@d3d4„ ZAd5d6„ ZBd7d8„ ZCd9d:„ ZDd;d<„ ZEd=d>„ ZFd?d@„ ZGdAdB„ ZHdCdD„ ZIdEdF„ ZJdGdH„ ZKdIdJ„ ZLdKdL„ ZMdMdN„ ZNdOdP„ ZOdÀdQdR„ZPdSdT„ ZQdUdV„ ZRdWdX„ ZSdYdZ„ ZTd[d\„ ZUd]d^„ ZVd_d`„ ZWeXdaœdbdc„ZYeXdaœddde„ZZdfdg„ Z[dhdi„ Z\ddjœdkdl„Z]dÁdndo„Z^dÂdqdr„Z_dsdt„ Z`dudv„ Zadwdx„ Zbdydz„ Zcd{d|„ Zdd}d~„ Zedd€„ Zfd�d‚„ Zgdƒd„„ Zhd…d†„ Zid‡dˆ„ Zjd‰dŠ„ Zkd‹dŒ„ Zld�dŽ„ Zmd�d�„ Znd‘d’„ Zod“d”„ Zpd•d–„ Zqd—d˜„ Zrd™dš„ Zsd›dœ„ Ztd�dž„ ZudŸd „ Zvd¡d¢„ Zwd£d¤„ Zxd¥d¦„ Zyd§d¨„ Zzd©dª„ Z{d«d¬„ Z|d­d®„ Z}d¯d°„ Z~d±d²„ Zd³d´„ Z€dÃdµd¶„Z�e�Z‚d·d¸„ Zƒd¹dº„ Z„dÄd»d¼„Z…d½d¾„ Z†dS )ÅÚDomainay  Superclass for all domains in the polys domains system.

    See :ref:`polys-domainsintro` for an introductory explanation of the
    domains system.

    The :py:class:`~.Domain` class is an abstract base class for all of the
    concrete domain types. There are many different :py:class:`~.Domain`
    subclasses each of which has an associated ``dtype`` which is a class
    representing the elements of the domain. The coefficients of a
    :py:class:`~.Poly` are elements of a domain which must be a subclass of
    :py:class:`~.Domain`.

    Examples
    ========

    The most common example domains are the integers :ref:`ZZ` and the
    rationals :ref:`QQ`.

    >>> from sympy import Poly, symbols, Domain
    >>> x, y = symbols('x, y')
    >>> p = Poly(x**2 + y)
    >>> p
    Poly(x**2 + y, x, y, domain='ZZ')
    >>> p.domain
    ZZ
    >>> isinstance(p.domain, Domain)
    True
    >>> Poly(x**2 + y/2)
    Poly(x**2 + 1/2*y, x, y, domain='QQ')

    The domains can be used directly in which case the domain object e.g.
    (:ref:`ZZ` or :ref:`QQ`) can be used as a constructor for elements of
    ``dtype``.

    >>> from sympy import ZZ, QQ
    >>> ZZ(2)
    2
    >>> ZZ.dtype  # doctest: +SKIP
    <class 'int'>
    >>> type(ZZ(2))  # doctest: +SKIP
    <class 'int'>
    >>> QQ(1, 2)
    1/2
    >>> type(QQ(1, 2))  # doctest: +SKIP
    <class 'sympy.polys.domains.pythonrational.PythonRational'>

    The corresponding domain elements can be used with the arithmetic
    operations ``+,-,*,**`` and depending on the domain some combination of
    ``/,//,%`` might be usable. For example in :ref:`ZZ` both ``//`` (floor
    division) and ``%`` (modulo division) can be used but ``/`` (true
    division) cannot. Since :ref:`QQ` is a :py:class:`~.Field` its elements
    can be used with ``/`` but ``//`` and ``%`` should not be used. Some
    domains have a :py:meth:`~.Domain.gcd` method.

    >>> ZZ(2) + ZZ(3)
    5
    >>> ZZ(5) // ZZ(2)
    2
    >>> ZZ(5) % ZZ(2)
    1
    >>> QQ(1, 2) / QQ(2, 3)
    3/4
    >>> ZZ.gcd(ZZ(4), ZZ(2))
    2
    >>> QQ.gcd(QQ(2,7), QQ(5,3))
    1/21
    >>> ZZ.is_Field
    False
    >>> QQ.is_Field
    True

    There are also many other domains including:

        1. :ref:`GF(p)` for finite fields of prime order.
        2. :ref:`RR` for real (floating point) numbers.
        3. :ref:`CC` for complex (floating point) numbers.
        4. :ref:`QQ(a)` for algebraic number fields.
        5. :ref:`K[x]` for polynomial rings.
        6. :ref:`K(x)` for rational function fields.
        7. :ref:`EX` for arbitrary expressions.

    Each domain is represented by a domain object and also an implementation
    class (``dtype``) for the elements of the domain. For example the
    :ref:`K[x]` domains are represented by a domain object which is an
    instance of :py:class:`~.PolynomialRing` and the elements are always
    instances of :py:class:`~.PolyElement`. The implementation class
    represents particular types of mathematical expressions in a way that is
    more efficient than a normal SymPy expression which is of type
    :py:class:`~.Expr`. The domain methods :py:meth:`~.Domain.from_sympy` and
    :py:meth:`~.Domain.to_sympy` are used to convert from :py:class:`~.Expr`
    to a domain element and vice versa.

    >>> from sympy import Symbol, ZZ, Expr
    >>> x = Symbol('x')
    >>> K = ZZ[x]           # polynomial ring domain
    >>> K
    ZZ[x]
    >>> type(K)             # class of the domain
    <class 'sympy.polys.domains.polynomialring.PolynomialRing'>
    >>> K.dtype             # class of the elements
    <class 'sympy.polys.rings.PolyElement'>
    >>> p_expr = x**2 + 1   # Expr
    >>> p_expr
    x**2 + 1
    >>> type(p_expr)
    <class 'sympy.core.add.Add'>
    >>> isinstance(p_expr, Expr)
    True
    >>> p_domain = K.from_sympy(p_expr)
    >>> p_domain            # domain element
    x**2 + 1
    >>> type(p_domain)
    <class 'sympy.polys.rings.PolyElement'>
    >>> K.to_sympy(p_domain) == p_expr
    True

    The :py:meth:`~.Domain.convert_from` method is used to convert domain
    elements from one domain to another.

    >>> from sympy import ZZ, QQ
    >>> ez = ZZ(2)
    >>> eq = QQ.convert_from(ez, ZZ)
    >>> type(ez)  # doctest: +SKIP
    <class 'int'>
    >>> type(eq)  # doctest: +SKIP
    <class 'sympy.polys.domains.pythonrational.PythonRational'>

    Elements from different domains should not be mixed in arithmetic or other
    operations: they should be converted to a common domain first.  The domain
    method :py:meth:`~.Domain.unify` is used to find a domain that can
    represent all the elements of two given domains.

    >>> from sympy import ZZ, QQ, symbols
    >>> x, y = symbols('x, y')
    >>> ZZ.unify(QQ)
    QQ
    >>> ZZ[x].unify(QQ)
    QQ[x]
    >>> ZZ[x].unify(QQ[y])
    QQ[x,y]

    If a domain is a :py:class:`~.Ring` then is might have an associated
    :py:class:`~.Field` and vice versa. The :py:meth:`~.Domain.get_field` and
    :py:meth:`~.Domain.get_ring` methods will find or create the associated
    domain.

    >>> from sympy import ZZ, QQ, Symbol
    >>> x = Symbol('x')
    >>> ZZ.has_assoc_Field
    True
    >>> ZZ.get_field()
    QQ
    >>> QQ.has_assoc_Ring
    True
    >>> QQ.get_ring()
    ZZ
    >>> K = QQ[x]
    >>> K
    QQ[x]
    >>> K.get_field()
    QQ(x)

    See also
    ========

    DomainElement: abstract base class for domain elements
    construct_domain: construct a minimal domain for some expressions

    Nztype | NoneÚdtyper   ÚzeroÚoneFTz
str | NoneÚrepÚaliasc                 C  s   t ‚d S ©N©ÚNotImplementedError©Úself© r   úY/var/www/html/bwave/python/venv/lib/python3.8/site-packages/sympy/polys/domains/domain.pyÚ__init__g  s    zDomain.__init__c                 C  s   | j S r   )r   r   r   r   r   Ú__str__j  s    zDomain.__str__c                 C  s   t | ƒS r   )Ústrr   r   r   r   Ú__repr__m  s    zDomain.__repr__c                 C  s   t | jj| jfƒS r   )ÚhashÚ	__class__Ú__name__r   r   r   r   r   Ú__hash__p  s    zDomain.__hash__c                 G  s
   | j |Ž S r   ©r   ©r   Úargsr   r   r   Únews  s    z
Domain.newc                 C  s   | j S )z#Alias for :py:attr:`~.Domain.dtype`r'   r   r   r   r   Útpv  s    z	Domain.tpc                 G  s
   | j |Ž S )z7Construct an element of ``self`` domain from ``args``. )r*   r(   r   r   r   Ú__call__{  s    zDomain.__call__c                 G  s
   | j |Ž S r   r'   r(   r   r   r   Únormal  s    zDomain.normalc                 C  sf   |j dk	rd|j  }nd|jj }t| |ƒ}|dk	rJ|||ƒ}|dk	rJ|S td|t|ƒ|| f ƒ‚dS )z=Convert ``element`` to ``self.dtype`` given the base domain. NZfrom_z*Cannot convert %s of type %s from %s to %s)r   r$   r%   Úgetattrr   Útype)r   ÚelementÚbaseÚmethodÚ_convertÚresultr   r   r   Úconvert_from‚  s    


zDomain.convert_fromc              	   C  sò  |dk	r(t |ƒrtd| ƒ‚|  ||¡S |  |¡r6|S t |ƒrJtd| ƒ‚ddlm}m}m}m} | |¡rx|  ||¡S t	|t
ƒr’|  ||ƒ|¡S tdkrÊt	||jƒr²|  ||¡S t	||jƒrÊ|  ||¡S t	|tƒrî|dd�}|  ||ƒ|¡S t	|tƒ�r|dd�}|  ||ƒ|¡S t	|tƒ�r0|  || ¡ ¡S | j�rTt|ddƒ�rT|  | ¡ ¡S t	|tƒ�rŠz|  |¡W S  ttfk
�r†   Y nX nNt|ƒ�sØz(t|d	d
�}t	|tƒ�rº|  |¡W S W n ttfk
�rÖ   Y nX td|t|ƒ| f ƒ‚dS )z'Convert ``element`` to ``self.dtype``. Nz%s is not in any domainr   )ÚZZÚQQÚ	RealFieldÚComplexFieldÚpythonF)ÚtolÚ	is_groundT)Ústrictz"Cannot convert %s of type %s to %s)r   r   r5   Úof_typeÚsympy.polys.domainsr6   r7   r8   r9   Ú
isinstanceÚintr   r+   ÚfloatÚcomplexr	   ÚparentÚis_Numericalr.   ÚconvertÚLCr   Ú
from_sympyÚ	TypeErrorÚ
ValueErrorr   r   r/   )r   r0   r1   r6   r7   r8   r9   rD   r   r   r   rF   “  sR    






zDomain.convertc                 C  s   t || jƒS )z%Check if ``a`` is of type ``dtype``. )r@   r+   )r   r0   r   r   r   r>   Î  s    zDomain.of_typec                 C  s6   zt |ƒrt‚|  |¡ W n tk
r0   Y dS X dS )z'Check if ``a`` belongs to this domain. FT)r   r   rF   ©r   Úar   r   r   Ú__contains__Ò  s    zDomain.__contains__c                 C  s   t ‚dS )aö	  Convert domain element *a* to a SymPy expression (Expr).

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

        Convert a :py:class:`~.Domain` element *a* to :py:class:`~.Expr`. Most
        public SymPy functions work with objects of type :py:class:`~.Expr`.
        The elements of a :py:class:`~.Domain` have a different internal
        representation. It is not possible to mix domain elements with
        :py:class:`~.Expr` so each domain has :py:meth:`~.Domain.to_sympy` and
        :py:meth:`~.Domain.from_sympy` methods to convert its domain elements
        to and from :py:class:`~.Expr`.

        Parameters
        ==========

        a: domain element
            An element of this :py:class:`~.Domain`.

        Returns
        =======

        expr: Expr
            A normal SymPy expression of type :py:class:`~.Expr`.

        Examples
        ========

        Construct an element of the :ref:`QQ` domain and then convert it to
        :py:class:`~.Expr`.

        >>> from sympy import QQ, Expr
        >>> q_domain = QQ(2)
        >>> q_domain
        2
        >>> q_expr = QQ.to_sympy(q_domain)
        >>> q_expr
        2

        Although the printed forms look similar these objects are not of the
        same type.

        >>> isinstance(q_domain, Expr)
        False
        >>> isinstance(q_expr, Expr)
        True

        Construct an element of :ref:`K[x]` and convert to
        :py:class:`~.Expr`.

        >>> from sympy import Symbol
        >>> x = Symbol('x')
        >>> K = QQ[x]
        >>> x_domain = K.gens[0]  # generator x as a domain element
        >>> p_domain = x_domain**2/3 + 1
        >>> p_domain
        1/3*x**2 + 1
        >>> p_expr = K.to_sympy(p_domain)
        >>> p_expr
        x**2/3 + 1

        The :py:meth:`~.Domain.from_sympy` method is used for the opposite
        conversion from a normal SymPy expression to a domain element.

        >>> p_domain == p_expr
        False
        >>> K.from_sympy(p_expr) == p_domain
        True
        >>> K.to_sympy(p_domain) == p_expr
        True
        >>> K.from_sympy(K.to_sympy(p_domain)) == p_domain
        True
        >>> K.to_sympy(K.from_sympy(p_expr)) == p_expr
        True

        The :py:meth:`~.Domain.from_sympy` method makes it easier to construct
        domain elements interactively.

        >>> from sympy import Symbol
        >>> x = Symbol('x')
        >>> K = QQ[x]
        >>> K.from_sympy(x**2/3 + 1)
        1/3*x**2 + 1

        See also
        ========

        from_sympy
        convert_from
        Nr   rK   r   r   r   Úto_sympyÝ  s    [zDomain.to_sympyc                 C  s   t ‚dS )aê  Convert a SymPy expression to an element of this domain.

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

        See :py:meth:`~.Domain.to_sympy` for explanation and examples.

        Parameters
        ==========

        expr: Expr
            A normal SymPy expression of type :py:class:`~.Expr`.

        Returns
        =======

        a: domain element
            An element of this :py:class:`~.Domain`.

        See also
        ========

        to_sympy
        convert_from
        Nr   rK   r   r   r   rH   :  s    zDomain.from_sympyc                 C  s   t || jd�S )N)Ústart)Úsumr   r(   r   r   r   rP   V  s    z
Domain.sumc                 C  s   dS ©z.Convert ``ModularInteger(int)`` to ``dtype``. Nr   ©ÚK1rL   ÚK0r   r   r   Úfrom_FFY  s    zDomain.from_FFc                 C  s   dS rQ   r   rR   r   r   r   Úfrom_FF_python]  s    zDomain.from_FF_pythonc                 C  s   dS )z.Convert a Python ``int`` object to ``dtype``. Nr   rR   r   r   r   Úfrom_ZZ_pythona  s    zDomain.from_ZZ_pythonc                 C  s   dS )z3Convert a Python ``Fraction`` object to ``dtype``. Nr   rR   r   r   r   Úfrom_QQ_pythone  s    zDomain.from_QQ_pythonc                 C  s   dS )z.Convert ``ModularInteger(mpz)`` to ``dtype``. Nr   rR   r   r   r   Úfrom_FF_gmpyi  s    zDomain.from_FF_gmpyc                 C  s   dS )z,Convert a GMPY ``mpz`` object to ``dtype``. Nr   rR   r   r   r   Úfrom_ZZ_gmpym  s    zDomain.from_ZZ_gmpyc                 C  s   dS )z,Convert a GMPY ``mpq`` object to ``dtype``. Nr   rR   r   r   r   Úfrom_QQ_gmpyq  s    zDomain.from_QQ_gmpyc                 C  s   dS )z,Convert a real element object to ``dtype``. Nr   rR   r   r   r   Úfrom_RealFieldu  s    zDomain.from_RealFieldc                 C  s   dS )z(Convert a complex element to ``dtype``. Nr   rR   r   r   r   Úfrom_ComplexFieldy  s    zDomain.from_ComplexFieldc                 C  s   dS )z*Convert an algebraic number to ``dtype``. Nr   rR   r   r   r   Úfrom_AlgebraicField}  s    zDomain.from_AlgebraicFieldc                 C  s   |j r|  |j|j¡S dS )ú#Convert a polynomial to ``dtype``. N)r<   rF   rG   ÚdomrR   r   r   r   Úfrom_PolynomialRing�  s    zDomain.from_PolynomialRingc                 C  s   dS )z*Convert a rational function to ``dtype``. Nr   rR   r   r   r   Úfrom_FractionField†  s    zDomain.from_FractionFieldc                 C  s   |   |j|j¡S )z.Convert an ``ExtensionElement`` to ``dtype``. )r5   r   ÚringrR   r   r   r   Úfrom_MonogenicFiniteExtensionŠ  s    z$Domain.from_MonogenicFiniteExtensionc                 C  s   |   |j¡S ©z&Convert a ``EX`` object to ``dtype``. )rH   ÚexrR   r   r   r   Úfrom_ExpressionDomainŽ  s    zDomain.from_ExpressionDomainc                 C  s
   |   |¡S re   )rH   rR   r   r   r   Úfrom_ExpressionRawDomain’  s    zDomain.from_ExpressionRawDomainc                 C  s"   |  ¡ dkr|  | ¡ |j¡S dS )r_   r   N)ZdegreerF   rG   r`   rR   r   r   r   Úfrom_GlobalPolynomialRing–  s    z Domain.from_GlobalPolynomialRingc                 C  s   |   ||¡S r   )rb   rR   r   r   r   Úfrom_GeneralizedPolynomialRing›  s    z%Domain.from_GeneralizedPolynomialRingc                 C  sP   | j rt| jƒt|ƒ@ s0|j rFt|jƒt|ƒ@ rFtd| |t|ƒf ƒ‚|  |¡S )Nz,Cannot unify %s with %s, given %s generators)Úis_CompositeÚsetÚsymbolsr   ÚtupleÚunify)rT   rS   rm   r   r   r   Úunify_with_symbolsž  s    0zDomain.unify_with_symbolsc                 C  sî   | j r| jn| }|j r|jn|}| j r,| jnd}|j r<|jnd}| |¡}t||ƒ}| j r`| jn|j}| jrr|js~|jrž| jrž|jrŠ|jsž|jrž|j	rž| 
¡ }| j r¾|j r¶| js¶|jr¾| j}	n|j}	ddlm}
 |	|
krâ|	||ƒS |	|||ƒS )z2Unify two domains where at least one is composite.r   r   )ÚGlobalPolynomialRing)rk   r`   rm   ro   r   ÚorderÚis_FractionFieldÚis_PolynomialRingÚis_FieldÚhas_assoc_RingÚget_ringr$   Ú&sympy.polys.domains.old_polynomialringrq   )rT   rS   Z	K0_groundZ	K1_groundZ
K0_symbolsZ
K1_symbolsÚdomainrm   rr   Úclsrq   r   r   r   Úunify_composite¤  s8    

ÿÿþþþý
zDomain.unify_compositec                 C  s¬  |dk	r|   ||¡S | |kr | S | jr,|jsV|  ¡ | ¡ krLtd| |f ƒ‚|  |¡S | jr`| S |jrj|S | jrt| S |jr~|S | jsŠ|jrô|jrš||  } }|jrÒtt	| j
|j
gƒƒd | j
krÈ||  } }| | ¡S | | j¡}| j |¡}|  |¡S | j�s|j�r|  |¡S dd„ }|j�r(||  } }| j�rR|j�s@|j�rN|| j| |ƒS | S |j�rd||  } }| j�r²|j�r‚|| j| |ƒS |j�s’|j�r®ddlm} || j| jd�S | S |j�rÄ||  } }| j�r|j�rÜ| ¡ }|j�rì| ¡ }|j�r| j| j |j¡ft| j|jƒžŽ S | S | j�r(| S |j�r4|S | j�rP|j �rL|  ¡ } | S |j�rl| j �rh| ¡ }|S | j �rx| S |j �r„|S | j!�r�| S |j!�rœ|S dd	l"m#} |S )
aZ  
        Construct a minimal domain that contains elements of ``K0`` and ``K1``.

        Known domains (from smallest to largest):

        - ``GF(p)``
        - ``ZZ``
        - ``QQ``
        - ``RR(prec, tol)``
        - ``CC(prec, tol)``
        - ``ALG(a, b, c)``
        - ``K[x, y, z]``
        - ``K(x, y, z)``
        - ``EX``

        NzCannot unify %s with %sé   c                 S  s(   t |j|jƒ}t |j|jƒ}| ||d�S )N©Úprecr;   )ÚmaxÚ	precisionÚ	tolerance)rz   rT   rS   r~   r;   r   r   r   Ú	mkinexact  s    zDomain.unify.<locals>.mkinexactr   )r9   r}   )ÚEX)$rp   Úhas_CharacteristicZeroÚcharacteristicr   r{   Úis_EXRAWÚis_EXÚis_FiniteExtensionÚlistr   ÚmodulusZ
set_domainÚdropÚsymbolry   ro   rk   Úis_ComplexFieldÚis_RealFieldr$   Úis_GaussianRingÚis_GaussianFieldZ sympy.polys.domains.complexfieldr9   r€   r�   Úis_AlgebraicFieldÚ	get_fieldZas_AlgebraicFieldr`   r   Zorig_extÚis_RationalFieldÚis_IntegerRingr?   rƒ   )rT   rS   rm   r‚   r9   rƒ   r   r   r   ro   Å  s˜    








$zDomain.unifyc                 C  s   t |tƒo| j|jkS )z0Returns ``True`` if two domains are equivalent. )r@   r   r   ©r   Úotherr   r   r   Ú__eq__D  s    zDomain.__eq__c                 C  s
   | |k S )z1Returns ``False`` if two domains are equivalent. r   r•   r   r   r   Ú__ne__I  s    zDomain.__ne__c                 C  s<   g }|D ].}t |tƒr(| |  |¡¡ q| | |ƒ¡ q|S )z5Rersively apply ``self`` to all elements of ``seq``. )r@   r‰   ÚappendÚmap)r   Úseqr4   Úeltr   r   r   rš   M  s    
z
Domain.mapc                 C  s   t d|  ƒ‚dS )z)Returns a ring associated with ``self``. z#there is no ring associated with %sN©r   r   r   r   r   rw   Y  s    zDomain.get_ringc                 C  s   t d|  ƒ‚dS )z*Returns a field associated with ``self``. z$there is no field associated with %sNr�   r   r   r   r   r’   ]  s    zDomain.get_fieldc                 C  s   | S )z2Returns an exact domain associated with ``self``. r   r   r   r   r   Ú	get_exacta  s    zDomain.get_exactc                 C  s"   t |dƒr| j|Ž S |  |¡S dS )z0The mathematical way to make a polynomial ring. Ú__iter__N)ÚhasattrÚ	poly_ring©r   rm   r   r   r   Ú__getitem__e  s    

zDomain.__getitem__)rr   c                G  s   ddl m} || ||ƒS ©z(Returns a polynomial ring, i.e. `K[X]`. r   )ÚPolynomialRing)Z"sympy.polys.domains.polynomialringr¥   )r   rr   rm   r¥   r   r   r   r¡   l  s    zDomain.poly_ringc                G  s   ddl m} || ||ƒS ©z'Returns a fraction field, i.e. `K(X)`. r   )ÚFractionField)Z!sympy.polys.domains.fractionfieldr§   )r   rr   rm   r§   r   r   r   Ú
frac_fieldq  s    zDomain.frac_fieldc                 O  s   ddl m} || f|ž|ŽS r¤   )rx   r¥   )r   rm   Úkwargsr¥   r   r   r   Úold_poly_ringv  s    zDomain.old_poly_ringc                 O  s   ddl m} || f|ž|ŽS r¦   )Z%sympy.polys.domains.old_fractionfieldr§   )r   rm   r©   r§   r   r   r   Úold_frac_field{  s    zDomain.old_frac_field©r   c                G  s   t d|  ƒ‚dS )z6Returns an algebraic field, i.e. `K(\alpha, \ldots)`. z%Cannot create algebraic field over %sNr�   )r   r   Ú	extensionr   r   r   Úalgebraic_field€  s    zDomain.algebraic_fieldéÿÿÿÿc                 C  s0   ddl m} |||ƒ}t||d�}| j||d�S )aï  
        Convenience method to construct an algebraic extension on a root of a
        polynomial, chosen by root index.

        Parameters
        ==========

        poly : :py:class:`~.Poly`
            The polynomial whose root generates the extension.
        alias : str, optional (default=None)
            Symbol name for the generator of the extension.
            E.g. "alpha" or "theta".
        root_index : int, optional (default=-1)
            Specifies which root of the polynomial is desired. The ordering is
            as defined by the :py:class:`~.ComplexRootOf` class. The default of
            ``-1`` selects the most natural choice in the common cases of
            quadratic and cyclotomic fields (the square root on the positive
            real or imaginary axis, resp. $\mathrm{e}^{2\pi i/n}$).

        Examples
        ========

        >>> from sympy import QQ, Poly
        >>> from sympy.abc import x
        >>> f = Poly(x**2 - 2)
        >>> K = QQ.alg_field_from_poly(f)
        >>> K.ext.minpoly == f
        True
        >>> g = Poly(8*x**3 - 6*x - 1)
        >>> L = QQ.alg_field_from_poly(g, "alpha")
        >>> L.ext.minpoly == g
        True
        >>> L.to_sympy(L([1, 1, 1]))
        alpha**2 + alpha + 1

        r   )ÚCRootOfr¬   )Zsympy.polys.rootoftoolsr°   r   r®   )r   Zpolyr   Ú
root_indexr°   ÚrootÚalphar   r   r   Úalg_field_from_poly„  s    %
zDomain.alg_field_from_polyÚzetac                 C  s2   ddl m} |r|t|ƒ7 }| j|||ƒ||d�S )a¢  
        Convenience method to construct a cyclotomic field.

        Parameters
        ==========

        n : int
            Construct the nth cyclotomic field.
        ss : boolean, optional (default=False)
            If True, append *n* as a subscript on the alias string.
        alias : str, optional (default="zeta")
            Symbol name for the generator.
        gen : :py:class:`~.Symbol`, optional (default=None)
            Desired variable for the cyclotomic polynomial that defines the
            field. If ``None``, a dummy variable will be used.
        root_index : int, optional (default=-1)
            Specifies which root of the polynomial is desired. The ordering is
            as defined by the :py:class:`~.ComplexRootOf` class. The default of
            ``-1`` selects the root $\mathrm{e}^{2\pi i/n}$.

        Examples
        ========

        >>> from sympy import QQ, latex
        >>> K = QQ.cyclotomic_field(5)
        >>> K.to_sympy(K([-1, 1]))
        1 - zeta
        >>> L = QQ.cyclotomic_field(7, True)
        >>> a = L.to_sympy(L([-1, 1]))
        >>> print(a)
        1 - zeta7
        >>> print(latex(a))
        1 - \zeta_{7}

        r   )Úcyclotomic_poly)r   r±   )Zsympy.polys.specialpolysr¶   r!   r´   )r   ÚnÚssr   Úgenr±   r¶   r   r   r   Úcyclotomic_field®  s    $ÿzDomain.cyclotomic_fieldc                 G  s   t ‚dS )z$Inject generators into this domain. Nr   r¢   r   r   r   ÚinjectØ  s    zDomain.injectc                 G  s   | j r
| S t‚dS )z"Drop generators from this domain. N)Ú	is_Simpler   r¢   r   r   r   r‹   Ü  s    zDomain.dropc                 C  s   | S )zReturns True if ``a`` is zero. r   rK   r   r   r   Úis_zeroâ  s    zDomain.is_zeroc                 C  s
   || j kS )zReturns True if ``a`` is one. )r   rK   r   r   r   Úis_oneæ  s    zDomain.is_onec                 C  s   |dkS )z#Returns True if ``a`` is positive. r   r   rK   r   r   r   Úis_positiveê  s    zDomain.is_positivec                 C  s   |dk S )z#Returns True if ``a`` is negative. r   r   rK   r   r   r   Úis_negativeî  s    zDomain.is_negativec                 C  s   |dkS )z'Returns True if ``a`` is non-positive. r   r   rK   r   r   r   Úis_nonpositiveò  s    zDomain.is_nonpositivec                 C  s   |dkS )z'Returns True if ``a`` is non-negative. r   r   rK   r   r   r   Úis_nonnegativeö  s    zDomain.is_nonnegativec                 C  s   |   |¡r| j S | jS d S r   )rÀ   r   rK   r   r   r   Úcanonical_unitú  s    
zDomain.canonical_unitc                 C  s   t |ƒS )z.Absolute value of ``a``, implies ``__abs__``. )ÚabsrK   r   r   r   rÄ      s    z
Domain.absc                 C  s   | S )z,Returns ``a`` negated, implies ``__neg__``. r   rK   r   r   r   Úneg  s    z
Domain.negc                 C  s   |
 S )z-Returns ``a`` positive, implies ``__pos__``. r   rK   r   r   r   Úpos  s    z
Domain.posc                 C  s   || S )z.Sum of ``a`` and ``b``, implies ``__add__``.  r   ©r   rL   Úbr   r   r   Úadd  s    z
Domain.addc                 C  s   || S )z5Difference of ``a`` and ``b``, implies ``__sub__``.  r   rÇ   r   r   r   Úsub  s    z
Domain.subc                 C  s   || S )z2Product of ``a`` and ``b``, implies ``__mul__``.  r   rÇ   r   r   r   Úmul  s    z
Domain.mulc                 C  s   || S )z2Raise ``a`` to power ``b``, implies ``__pow__``.  r   rÇ   r   r   r   Úpow  s    z
Domain.powc                 C  s   t ‚dS )a
  Exact quotient of *a* and *b*. Analogue of ``a / b``.

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

        This is essentially the same as ``a / b`` except that an error will be
        raised if the division is inexact (if there is any remainder) and the
        result will always be a domain element. When working in a
        :py:class:`~.Domain` that is not a :py:class:`~.Field` (e.g. :ref:`ZZ`
        or :ref:`K[x]`) ``exquo`` should be used instead of ``/``.

        The key invariant is that if ``q = K.exquo(a, b)`` (and ``exquo`` does
        not raise an exception) then ``a == b*q``.

        Examples
        ========

        We can use ``K.exquo`` instead of ``/`` for exact division.

        >>> from sympy import ZZ
        >>> ZZ.exquo(ZZ(4), ZZ(2))
        2
        >>> ZZ.exquo(ZZ(5), ZZ(2))
        Traceback (most recent call last):
            ...
        ExactQuotientFailed: 2 does not divide 5 in ZZ

        Over a :py:class:`~.Field` such as :ref:`QQ`, division (with nonzero
        divisor) is always exact so in that case ``/`` can be used instead of
        :py:meth:`~.Domain.exquo`.

        >>> from sympy import QQ
        >>> QQ.exquo(QQ(5), QQ(2))
        5/2
        >>> QQ(5) / QQ(2)
        5/2

        Parameters
        ==========

        a: domain element
            The dividend
        b: domain element
            The divisor

        Returns
        =======

        q: domain element
            The exact quotient

        Raises
        ======

        ExactQuotientFailed: if exact division is not possible.
        ZeroDivisionError: when the divisor is zero.

        See also
        ========

        quo: Analogue of ``a // b``
        rem: Analogue of ``a % b``
        div: Analogue of ``divmod(a, b)``

        Notes
        =====

        Since the default :py:attr:`~.Domain.dtype` for :ref:`ZZ` is ``int``
        (or ``mpz``) division as ``a / b`` should not be used as it would give
        a ``float`` which is not a domain element.

        >>> ZZ(4) / ZZ(2) # doctest: +SKIP
        2.0
        >>> ZZ(5) / ZZ(2) # doctest: +SKIP
        2.5

        On the other hand with `SYMPY_GROUND_TYPES=flint` elements of :ref:`ZZ`
        are ``flint.fmpz`` and division would raise an exception:

        >>> ZZ(4) / ZZ(2) # doctest: +SKIP
        Traceback (most recent call last):
        ...
        TypeError: unsupported operand type(s) for /: 'fmpz' and 'fmpz'

        Using ``/`` with :ref:`ZZ` will lead to incorrect results so
        :py:meth:`~.Domain.exquo` should be used instead.

        Nr   rÇ   r   r   r   Úexquo  s    YzDomain.exquoc                 C  s   t ‚dS )aG  Quotient of *a* and *b*. Analogue of ``a // b``.

        ``K.quo(a, b)`` is equivalent to ``K.div(a, b)[0]``. See
        :py:meth:`~.Domain.div` for more explanation.

        See also
        ========

        rem: Analogue of ``a % b``
        div: Analogue of ``divmod(a, b)``
        exquo: Analogue of ``a / b``
        Nr   rÇ   r   r   r   Úquow  s    z
Domain.quoc                 C  s   t ‚dS )aN  Modulo division of *a* and *b*. Analogue of ``a % b``.

        ``K.rem(a, b)`` is equivalent to ``K.div(a, b)[1]``. See
        :py:meth:`~.Domain.div` for more explanation.

        See also
        ========

        quo: Analogue of ``a // b``
        div: Analogue of ``divmod(a, b)``
        exquo: Analogue of ``a / b``
        Nr   rÇ   r   r   r   Úrem†  s    z
Domain.remc                 C  s   t ‚dS )a[	  Quotient and remainder for *a* and *b*. Analogue of ``divmod(a, b)``

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

        This is essentially the same as ``divmod(a, b)`` except that is more
        consistent when working over some :py:class:`~.Field` domains such as
        :ref:`QQ`. When working over an arbitrary :py:class:`~.Domain` the
        :py:meth:`~.Domain.div` method should be used instead of ``divmod``.

        The key invariant is that if ``q, r = K.div(a, b)`` then
        ``a == b*q + r``.

        The result of ``K.div(a, b)`` is the same as the tuple
        ``(K.quo(a, b), K.rem(a, b))`` except that if both quotient and
        remainder are needed then it is more efficient to use
        :py:meth:`~.Domain.div`.

        Examples
        ========

        We can use ``K.div`` instead of ``divmod`` for floor division and
        remainder.

        >>> from sympy import ZZ, QQ
        >>> ZZ.div(ZZ(5), ZZ(2))
        (2, 1)

        If ``K`` is a :py:class:`~.Field` then the division is always exact
        with a remainder of :py:attr:`~.Domain.zero`.

        >>> QQ.div(QQ(5), QQ(2))
        (5/2, 0)

        Parameters
        ==========

        a: domain element
            The dividend
        b: domain element
            The divisor

        Returns
        =======

        (q, r): tuple of domain elements
            The quotient and remainder

        Raises
        ======

        ZeroDivisionError: when the divisor is zero.

        See also
        ========

        quo: Analogue of ``a // b``
        rem: Analogue of ``a % b``
        exquo: Analogue of ``a / b``

        Notes
        =====

        If ``gmpy`` is installed then the ``gmpy.mpq`` type will be used as
        the :py:attr:`~.Domain.dtype` for :ref:`QQ`. The ``gmpy.mpq`` type
        defines ``divmod`` in a way that is undesirable so
        :py:meth:`~.Domain.div` should be used instead of ``divmod``.

        >>> a = QQ(1)
        >>> b = QQ(3, 2)
        >>> a               # doctest: +SKIP
        mpq(1,1)
        >>> b               # doctest: +SKIP
        mpq(3,2)
        >>> divmod(a, b)    # doctest: +SKIP
        (mpz(0), mpq(1,1))
        >>> QQ.div(a, b)    # doctest: +SKIP
        (mpq(2,3), mpq(0,1))

        Using ``//`` or ``%`` with :ref:`QQ` will lead to incorrect results so
        :py:meth:`~.Domain.div` should be used instead.

        Nr   rÇ   r   r   r   Údiv•  s    Tz
Domain.divc                 C  s   t ‚dS )z5Returns inversion of ``a mod b``, implies something. Nr   rÇ   r   r   r   Úinvertë  s    zDomain.invertc                 C  s   t ‚dS )z!Returns ``a**(-1)`` if possible. Nr   rK   r   r   r   Úrevertï  s    zDomain.revertc                 C  s   t ‚dS )zReturns numerator of ``a``. Nr   rK   r   r   r   Únumeró  s    zDomain.numerc                 C  s   t ‚dS )zReturns denominator of ``a``. Nr   rK   r   r   r   Údenom÷  s    zDomain.denomc                 C  s   |   ||¡\}}}||fS )z&Half extended GCD of ``a`` and ``b``. )Úgcdex)r   rL   rÈ   ÚsÚtÚhr   r   r   Ú
half_gcdexû  s    zDomain.half_gcdexc                 C  s   t ‚dS )z!Extended GCD of ``a`` and ``b``. Nr   rÇ   r   r   r   rÕ      s    zDomain.gcdexc                 C  s.   |   ||¡}|  ||¡}|  ||¡}|||fS )z.Returns GCD and cofactors of ``a`` and ``b``. )ÚgcdrÎ   )r   rL   rÈ   rÚ   ZcfaZcfbr   r   r   Ú	cofactors  s    zDomain.cofactorsc                 C  s   t ‚dS )z Returns GCD of ``a`` and ``b``. Nr   rÇ   r   r   r   rÚ     s    z
Domain.gcdc                 C  s   t ‚dS )z Returns LCM of ``a`` and ``b``. Nr   rÇ   r   r   r   Úlcm  s    z
Domain.lcmc                 C  s   t ‚dS )z#Returns b-base logarithm of ``a``. Nr   rÇ   r   r   r   Úlog  s    z
Domain.logc                 C  s   t ‚dS )aJ  Returns a (possibly inexact) square root of ``a``.

        Explanation
        ===========
        There is no universal definition of "inexact square root" for all
        domains. It is not recommended to implement this method for domains
        other then :ref:`ZZ`.

        See also
        ========
        exsqrt
        Nr   rK   r   r   r   Úsqrt  s    zDomain.sqrtc                 C  s   t ‚dS )aŽ  Returns whether ``a`` is a square in the domain.

        Explanation
        ===========
        Returns ``True`` if there is an element ``b`` in the domain such that
        ``b * b == a``, otherwise returns ``False``. For inexact domains like
        :ref:`RR` and :ref:`CC`, a tiny difference in this equality can be
        tolerated.

        See also
        ========
        exsqrt
        Nr   rK   r   r   r   Ú	is_square&  s    zDomain.is_squarec                 C  s   t ‚dS )a'  Principal square root of a within the domain if ``a`` is square.

        Explanation
        ===========
        The implementation of this method should return an element ``b`` in the
        domain such that ``b * b == a``, or ``None`` if there is no such ``b``.
        For inexact domains like :ref:`RR` and :ref:`CC`, a tiny difference in
        this equality can be tolerated. The choice of a "principal" square root
        should follow a consistent rule whenever possible.

        See also
        ========
        sqrt, is_square
        Nr   rK   r   r   r   Úexsqrt6  s    zDomain.exsqrtc                 K  s   |   |¡j|f|ŽS )z*Returns numerical approximation of ``a``. )rN   Úevalf)r   rL   r~   Úoptionsr   r   r   rá   G  s    zDomain.evalfc                 C  s   |S r   r   rK   r   r   r   ÚrealM  s    zDomain.realc                 C  s   | j S r   )r   rK   r   r   r   ÚimagP  s    zDomain.imagc                 C  s   ||kS )z+Check if ``a`` and ``b`` are almost equal. r   )r   rL   rÈ   r�   r   r   r   ÚalmosteqS  s    zDomain.almosteqc                 C  s   t dƒ‚dS )z*Return the characteristic of this domain. zcharacteristic()Nr   r   r   r   r   r…   W  s    zDomain.characteristic)N)N)Nr¯   )Frµ   Nr¯   )N)N)‡r%   Ú
__module__Ú__qualname__Ú__doc__r   Ú__annotations__r   r   Zis_Ringru   rv   Zhas_assoc_FieldZis_FiniteFieldZis_FFr”   Zis_ZZr“   Zis_QQr�   Zis_ZZ_Ir�   Zis_QQ_IrŽ   Zis_RRr�   Zis_CCr‘   Zis_Algebraicrt   Zis_Polyrs   Zis_FracZis_SymbolicDomainr‡   Zis_SymbolicRawDomainr†   rˆ   Zis_ExactrE   r¼   rk   Zis_PIDr„   r   r   r   r    r"   r&   r*   Úpropertyr+   r,   r-   r5   rF   r>   rM   rN   rH   rP   rU   rV   rW   rX   rY   rZ   r[   r\   r]   r^   ra   rb   rd   rg   rh   ri   rj   rp   r{   ro   r—   r˜   rš   rw   r’   rž   r£   r
   r¡   r¨   rª   r«   r®   r´   rº   r»   r‹   r½   r¾   r¿   rÀ   rÁ   rÂ   rÃ   rÄ   rÅ   rÆ   rÉ   rÊ   rË   rÌ   rÍ   rÎ   rÏ   rÐ   rÑ   rÒ   rÓ   rÔ   rÙ   rÕ   rÛ   rÚ   rÜ   rÝ   rÞ   rß   rà   rá   r·   rã   rä   rå   r…   r   r   r   r   r      sî   
 +

;]!

*
*[V

r   N)rè   Ú
__future__r   Útypingr   Zsympy.core.numbersr   Z
sympy.corer   r   Zsympy.core.sortingr   Zsympy.external.gmpyr   Z!sympy.polys.domains.domainelementr	   Zsympy.polys.orderingsr
   Zsympy.polys.polyerrorsr   r   r   Zsympy.polys.polyutilsr   r   Zsympy.utilitiesr   Zsympy.utilities.iterablesr   r   Ú__all__r   r   r   r   Ú<module>   s2             S