a
    RG5d                     @   s   d Z ddlmZ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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.     )AnyOptionalType)AlgebraicNumber)Basicsympify)default_sort_keyordered)HAS_GMPY)DomainElement)lex)UnificationFailedCoercionFailedDomainError)_unify_gens_not_a_coeff)public)is_sequencec                   @   sv  e Zd ZdZdZdZdZ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Z+dd Z,dd Z-d	d
 Z.dd Z/dd Z0e1dd Z2dd Z3dd Z4dd Z5dddZ6dd Z7dd Z8dd Z9dd  Z:d!d" Z;d#d$ Z<d%d& Z=d'd( Z>d)d* Z?d+d, Z@d-d. ZAd/d0 ZBd1d2 ZCd3d4 ZDd5d6 ZEd7d8 ZFd9d: ZGd;d< ZHd=d> ZId?d@ ZJdAdB ZKdCdD ZLdEdF ZMddGdHZNdIdJ ZOdKdL ZPdMdN ZQdOdP ZRdQdR ZSdSdT ZTdUdV ZUeVdWdXdYZWeVdWdZd[ZXd\d] ZYd^d_ ZZdd`dadbZ[ddddeZ\ddgdhZ]didj Z^dkdl Z_dmdn Z`dodp Zadqdr Zbdsdt Zcdudv Zddwdx Zedydz Zfd{d| Zgd}d~ Zhdd Zidd Zjdd Zkdd Zldd Zmdd Zndd Zodd Zpdd Zqdd Zrdd Zsdd Ztdd Zudd Zvdd Zwdd Zxdd Zydd Zzdd Z{dd Z|dddZ}e}Z~dd Zdd ZdddZdd Zd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

    NFTc                 C   s   t d S NNotImplementedErrorself r   V/var/www/html/django/DPS/env/lib/python3.9/site-packages/sympy/polys/domains/domain.py__init__g  s    zDomain.__init__c                 C   s   | j S r   )repr   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__dtyper   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urd|j  }nd|jj }t| |}|durJ|||}|durJ|S td|t||| f dS )z=Convert ``element`` to ``self.dtype`` given the base domain. Nfrom_z*Cannot convert %s of type %s from %s to %s)aliasr"   r#   getattrr   type)r   elementbasemethod_convertresultr   r   r   convert_from  s    


zDomain.convert_fromc           
   	   C   s  |du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r|}t	||jr| ||S |}t	||jr| ||S t	|tr|dd}	| |	||	S t	|tr|dd}	| |	||	S t	|tr4| || S | jrXt|ddrX| | S t	|trz| |W S  ttfy   Y n0 nLt|sz(t|dd	}t	|tr| |W S W n ttfy   Y n0 td
|t|| f dS )z'Convert ``element`` to ``self.dtype``. Nz%s is not in any domainr   )ZZQQ	RealFieldComplexFieldF)tol	is_groundT)strictz"Cannot convert %s of type %s to %s)r   r   r6   of_typesympy.polys.domainsr7   r8   r9   r:   
isinstanceintr
   r*   floatcomplexr   parentis_Numericalr/   convertLCr   
from_sympy	TypeError
ValueErrorr   r   r0   )
r   r1   r2   r7   r8   r9   r:   integers	rationalsrD   r   r   r   rF     sV    






zDomain.convertc                 C   s   t || jS )z%Check if ``a`` is of type ``dtype``. )r@   r*   )r   r1   r   r   r   r>     s    zDomain.of_typec                 C   s4   zt |rt| | W n ty.   Y dS 0 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   rM   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   rM   r   r   r   rH   =  s    zDomain.from_sympyc                 C   s   t |S r   )sumr'   r   r   r   rQ   Y  s    z
Domain.sumc                 C   s   dS z.Convert ``ModularInteger(int)`` to ``dtype``. Nr   K1rN   K0r   r   r   from_FF\  s    zDomain.from_FFc                 C   s   dS rR   r   rS   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   rS   r   r   r   from_ZZ_pythond  s    zDomain.from_ZZ_pythonc                 C   s   dS )z3Convert a Python ``Fraction`` object to ``dtype``. Nr   rS   r   r   r   from_QQ_pythonh  s    zDomain.from_QQ_pythonc                 C   s   dS )z.Convert ``ModularInteger(mpz)`` to ``dtype``. Nr   rS   r   r   r   from_FF_gmpyl  s    zDomain.from_FF_gmpyc                 C   s   dS )z,Convert a GMPY ``mpz`` object to ``dtype``. Nr   rS   r   r   r   from_ZZ_gmpyp  s    zDomain.from_ZZ_gmpyc                 C   s   dS )z,Convert a GMPY ``mpq`` object to ``dtype``. Nr   rS   r   r   r   from_QQ_gmpyt  s    zDomain.from_QQ_gmpyc                 C   s   dS )z,Convert a real element object to ``dtype``. Nr   rS   r   r   r   from_RealFieldx  s    zDomain.from_RealFieldc                 C   s   dS )z(Convert a complex element to ``dtype``. Nr   rS   r   r   r   from_ComplexField|  s    zDomain.from_ComplexFieldc                 C   s   dS )z*Convert an algebraic number to ``dtype``. Nr   rS   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   domrS   r   r   r   from_PolynomialRing  s    zDomain.from_PolynomialRingc                 C   s   dS )z*Convert a rational function to ``dtype``. Nr   rS   r   r   r   from_FractionField  s    zDomain.from_FractionFieldc                 C   s   |  |j|jS )z.Convert an ``ExtensionElement`` to ``dtype``. )r6   r   ringrS   r   r   r   from_MonogenicFiniteExtension  s    z$Domain.from_MonogenicFiniteExtensionc                 C   s   |  |jS z&Convert a ``EX`` object to ``dtype``. )rH   exrS   r   r   r   from_ExpressionDomain  s    zDomain.from_ExpressionDomainc                 C   s
   |  |S rf   )rH   rS   r   r   r   from_ExpressionRawDomain  s    zDomain.from_ExpressionRawDomainc                 C   s"   |  dkr| | |jS dS )r`   r   N)degreerF   rG   ra   rS   r   r   r   from_GlobalPolynomialRing  s    z Domain.from_GlobalPolynomialRingc                 C   s   |  ||S r   )rc   rS   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)rU   rT   ro   r   r   r   unify_with_symbols  s    0zDomain.unify_with_symbolsc                 C   s  |dur|  ||S | |kr | S | jr*| S |jr4|S | jr>| S |jrH|S | jsT|jr|jrd||  } }|jrtt| j|jgd | jkr||  } }|| S || j	}| j
|}| |S | js|jr| jr| jn| }|jr|jn|}| jr| jnd}|jr
|jnd}||}t||}| jr0| jn|j}| jrF|jsV|jr~| jr~|jrf|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 dd }|jr||  } }| jr|js
|jr|| j| |S | S |jr.||  } }| jr||jrL|| j| |S |js\|jrxddlm} || j| j d	S | S |j!r||  } }| j!r|jr|" }|jr|# }|j!r| j| j|jgt| j$|j$R  S | S | jr| S |jr |S | jr|j%r| " } | S |jr8| j%r4|" }|S | j%rD| S |j%rP|S | j&r\| S |j&rh|S | j'r|j'r| t(| j)|j)t*d
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``

        N   r   r   )GlobalPolynomialRingc                 S   s(   t |j|j}t |j|j}| ||dS )Nprecr;   )max	precision	tolerance)clsrU   rT   rv   r;   r   r   r   	mkinexact  s    zDomain.unify.<locals>.mkinexact)r:   ru   )key)EX)-rr   is_EXRAWis_EXis_FiniteExtensionlistr	   modulus
set_domaindropsymboldomainrq   rm   ra   ro   r   orderis_FractionFieldis_PolynomialRingis_Fieldhas_assoc_Ringget_ringr"   &sympy.polys.domains.old_polynomialringrt   is_ComplexFieldis_RealFieldis_GaussianRingis_GaussianField sympy.polys.domains.complexfieldr:   rx   ry   is_AlgebraicField	get_fieldZas_AlgebraicFieldZorig_extis_RationalFieldis_IntegerRingis_FiniteFieldrw   modr   r?   r}   )rU   rT   ro   Z	K0_groundZ	K1_groundZ
K0_symbolsZ
K1_symbolsr   r   rz   rt   r{   r:   r}   r   r   r   rq     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__5  s    zDomain.__eq__c                 C   s
   | |k S )z1Returns ``False`` if two domains are equivalent. r   r   r   r   r   __ne__9  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   seqr5   eltr   r   r   r   =  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   r   I  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   M  s    zDomain.get_fieldc                 C   s   | S )z2Returns an exact domain associated with ``self``. r   r   r   r   r   	get_exactQ  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   ro   r   r   r   __getitem__U  s    

zDomain.__getitem__)r   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   r   ro   r   r   r   r   r   \  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   r   ro   r   r   r   r   
frac_fielda  s    zDomain.frac_fieldc                 O   s"   ddl m} || g|R i |S r   )r   r   )r   ro   kwargsr   r   r   r   old_poly_ringf  s    zDomain.old_poly_ringc                 O   s"   ddl m} || g|R i |S r   )Z%sympy.polys.domains.old_fractionfieldr   )r   ro   r   r   r   r   r   old_frac_fieldk  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_fieldp  s    zDomain.algebraic_fieldc                 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   )sympy.polys.rootoftoolsr   r   r   )r   polyr.   
root_indexr   rootalphar   r   r   alg_field_from_polyt  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   rM   r   r   r   is_zero  s    zDomain.is_zeroc                 C   s
   || j kS )zReturns True if ``a`` is one. )onerM   r   r   r   is_one  s    zDomain.is_onec                 C   s   |dkS )z#Returns True if ``a`` is positive. r   r   rM   r   r   r   is_positive  s    zDomain.is_positivec                 C   s   |dk S )z#Returns True if ``a`` is negative. r   r   rM   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   rM   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   rM   r   r   r   is_nonnegative  s    zDomain.is_nonnegativec                 C   s   |  |r| j S | jS d S r   )r   r   rM   r   r   r   canonical_unit  s    
zDomain.canonical_unitc                 C   s   t |S )z.Absolute value of ``a``, implies ``__abs__``. )absrM   r   r   r   r     s    z
Domain.absc                 C   s   | S )z,Returns ``a`` negated, implies ``__neg__``. r   rM   r   r   r   neg  s    z
Domain.negc                 C   s   |
 S )z-Returns ``a`` positive, implies ``__pos__``. r   rM   r   r   r   pos  s    z
Domain.posc                 C   s   || S )z.Sum of ``a`` and ``b``, implies ``__add__``.  r   r   rN   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``.

        >>> ZZ(4) / ZZ(2)
        2.0
        >>> ZZ(5) / ZZ(2)
        2.5

        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    Qz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   quo_  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   remn  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   rM   r   r   r   revert  s    zDomain.revertc                 C   s   t dS )zReturns numerator of ``a``. Nr   rM   r   r   r   numer  s    zDomain.numerc                 C   s   t dS )zReturns denominator of ``a``. Nr   rM   r   r   r   denom  s    zDomain.denomc                 C   s   |  ||\}}}||fS )z&Half extended GCD of ``a`` and ``b``. )gcdex)r   rN   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   rN   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 )zReturns square root of ``a``. Nr   rM   r   r   r   sqrt  s    zDomain.sqrtc                 K   s   |  |j|fi |S )z*Returns numerical approximation of ``a``. )rP   evalf)r   rN   rv   optionsr   r   r   r     s    zDomain.evalfc                 C   s   |S r   r   rM   r   r   r   real	  s    zDomain.realc                 C   s   | j S r   )zerorM   r   r   r   imag  s    zDomain.imagc                 C   s   ||kS )z+Check if ``a`` and ``b`` are almost equal. r   )r   rN   r   ry   r   r   r   almosteq  s    zDomain.almosteqc                 C   s   t ddS )z*Return the characteristic of this domain. zcharacteristic()Nr   r   r   r   r   characteristic  s    zDomain.characteristic)N)N)Nr   )Fr   Nr   )N)N)r#   
__module____qualname____doc__r$   r   r   is_Ringr   r   Zhas_assoc_Fieldr   Zis_FFr   Zis_ZZr   Zis_QQr   Zis_ZZ_Ir   Zis_QQ_Ir   Zis_RRr   Zis_CCr   Zis_Algebraicr   is_Polyr   Zis_FracZis_SymbolicDomainr   Zis_SymbolicRawDomainr~   r   is_ExactrE   r   rm   Zis_PIDZhas_CharacteristicZeror   r.   r   r   r    r%   r)   propertyr*   r+   r,   r6   rF   r>   rO   rP   rH   rQ   rV   rW   rX   rY   rZ   r[   r\   r]   r^   r_   rb   rc   re   rh   ri   rk   rl   rr   rq   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   r   r      s    +

>]
 
*
*SV

r   N) r   typingr   r   r   sympy.core.numbersr   
sympy.corer   r   sympy.core.sortingr   r	   sympy.external.gmpyr
   !sympy.polys.domains.domainelementr   sympy.polys.orderingsr   sympy.polys.polyerrorsr   r   r   sympy.polys.polyutilsr   r   sympy.utilitiesr   sympy.utilities.iterablesr   r   __all__r   r   r   r   <module>   s0             