
    \h                        S r SSKJr  SSKJr  SSKJr  SSKJrJ	r	  SSK
Jr  SSKJr  SSKJr  SS	KJr  SS
KJrJrJr  SSKJrJr  SSKJr  SSKJr  \ " S S5      5       rS/rg)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                  D   \ rS rSr% SrSrS\S'    SrS\S'    SrS\S'    S	r	 S	r
 S	r S	r S	=rrS	=rrS	=rrS	=rrS	=rrS	=rrS	=rrS	=rrS	=rrS	=rr S	=r!r"S	=r#r$S	r%S
r&S	r'S	r(S	r)S	r* S	r+Sr,S\S'   Sr-S\S'   S r.S r/S r0S r1S r2\3S 5       r4S r5S r6S r7ShS jr8S r9S r:S r;S r<S r=S r>S r?S r@S  rAS! rBS" rCS# rDS$ rES% rFS& rGS' rHS( rIS) rJS* rKS+ rLS, rMS- rNS. rOS/ rPShS0 jrQS1 rRS2 rSS3 rTS4 rUS5 rVS6 rWS7 rX\YS8.S9 jrZ\YS8.S: jr[S; r\S< r]SS=.S> jr^SiS? jr_SjS@ jr`SA raSB rbSC rcSD rdSE reSF rfSG rgSH rhSI riSJ rjSK rkSL rlSM rmSN rnSO roSP rpSQ rqSR rrSS rsST rtSU ruSV rvSW rwSX rxSY rySZ rzS[ r{S\ r|S] r}S^ r~S_ rS` rSa rShSb jr\rSc rSd rShSe jrSf rSgrg)kDomain   a*  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             # doctest: +SKIP
<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                    [         eNNotImplementedErrorselfs    R/var/www/auris/envauris/lib/python3.13/site-packages/sympy/polys/domains/domain.py__init__Domain.__init__g  s    !!    c                    U R                   $ r   )r   r   s    r!   __str__Domain.__str__j  s    xxr$   c                    [        U 5      $ r   )strr   s    r!   __repr__Domain.__repr__m  s    4yr$   c                X    [        U R                  R                  U R                  45      $ r   )hash	__class____name__r   r   s    r!   __hash__Domain.__hash__p  s     T^^,,djj9::r$   c                     U R                   " U6 $ r   r   r    argss     r!   new
Domain.news      zz4  r$   c                    U R                   $ )z#Alias for :py:attr:`~.Domain.dtype`r3   r   s    r!   tp	Domain.tpv  s     zzr$   c                     U R                   " U6 $ )z7Construct an element of ``self`` domain from ``args``. )r6   r4   s     r!   __call__Domain.__call__{  s    xxr$   c                     U R                   " U6 $ r   r3   r4   s     r!   normalDomain.normal  r8   r$   c           
         UR                   b  SUR                   -   nOSUR                  R                  -   n[        X5      nUb  U" X5      nUb  U$ [	        SU< S[        U5      < SU< SU < 35      e)z=Convert ``element`` to ``self.dtype`` given the base domain. from_Cannot convert 	 of type z from  to )r   r.   r/   getattrr   type)r    elementbasemethod_convertresults         r!   convert_fromDomain.convert_from  sp    ::!tzz)Ft~~666F4(g,F!WVZ[bVceikopqqr$   c                X   Ub/  [        U5      (       a  [        SU-  5      eU R                  X5      $ U R                  U5      (       a  U$ [        U5      (       a  [        SU-  5      eSSKJnJnJnJn  UR                  U5      (       a  U R                  X5      $ [        U[        5      (       a  U R                  U" U5      U5      $ [        S:w  aV  [        XR                  5      (       a  U R                  X5      $ [        XR                  5      (       a  U R                  X5      $ [        U[        5      (       a  U" 5       nU R                  U" U5      U5      $ [        U[        5      (       a  U" 5       nU R                  U" U5      U5      $ [        U5      R                   S:X  a  U" 5       nU R                  U" U5      U5      $ [        U5      R                   S:X  a  U" 5       nU R                  U" U5      U5      $ [        U["        5      (       a  U R                  XR%                  5       5      $ U R&                  (       a1  [)        USS5      (       a  U R+                  UR-                  5       5      $ [        U[.        5      (       a   U R1                  U5      $ [7        U5      (       d2   [9        US	S
9n[        U[.        5      (       a  U R1                  U5      $  [        SU< S[        U5      < SU < 35      e! [2        [4        4 a     N2f = f! [2        [4        4 a     NHf = f)z'Convert ``element`` to ``self.dtype``. z%s is not in any domainr   )ZZQQ	RealFieldComplexFieldpythonmpfmpc	is_groundFT)strictrD   rE   rF   )r   r   rN   of_typesympy.polys.domainsrQ   rR   rS   rT   
isinstanceintr	   r:   floatcomplexrH   r/   r
   parentis_NumericalrG   convertLCr   
from_sympy	TypeError
ValueErrorr   r   )r    rI   rJ   rQ   rR   rS   rT   r`   s           r!   rb   Domain.convert  s    G$$$%>%HII$$W33<<  N   !:W!DEEGG::g$$W11gs##$$R["558#'55))((55'55))((55gu%%[F$$VG_f==gw''!^F$$VG_f===!!U*[F$$VG_f===!!U*!^F$$VG_f==g}--$$Wnn.>?? +u!E!E<<

--gu%%w// w''%gd;G!'511#w77 2
 WdSZm]abcc z*  ":. s$   L  //L  LLL)(L)c                ,    [        XR                  5      $ )z%Check if ``a`` is of type ``dtype``. )r\   r:   )r    rI   s     r!   rZ   Domain.of_type  s    '77++r$   c                t     [        U5      (       a  [        eU R                  U5        g! [         a     gf = f)z'Check if ``a`` belongs to this domain. FT)r   r   rb   r    as     r!   __contains__Domain.__contains__  s:    	A$$LLO   		s   '* 
77c                    [         e)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
r   rk   s     r!   to_sympyDomain.to_sympy  s    v "!r$   c                    [         e)aj  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
r   rk   s     r!   rd   Domain.from_sympyB  s
    4 "!r$   c                (    [        XR                  S9$ )N)start)sumr   r4   s     r!   rv   
Domain.sum^  s    4yy))r$   c                    gz.Convert ``ModularInteger(int)`` to ``dtype``. N K1rl   K0s      r!   from_FFDomain.from_FFa      r$   c                    gry   rz   r{   s      r!   from_FF_pythonDomain.from_FF_pythone  r   r$   c                    g)z.Convert a Python ``int`` object to ``dtype``. Nrz   r{   s      r!   from_ZZ_pythonDomain.from_ZZ_pythoni  r   r$   c                    g)z3Convert a Python ``Fraction`` object to ``dtype``. Nrz   r{   s      r!   from_QQ_pythonDomain.from_QQ_pythonm  r   r$   c                    g)z.Convert ``ModularInteger(mpz)`` to ``dtype``. Nrz   r{   s      r!   from_FF_gmpyDomain.from_FF_gmpyq  r   r$   c                    g)z,Convert a GMPY ``mpz`` object to ``dtype``. Nrz   r{   s      r!   from_ZZ_gmpyDomain.from_ZZ_gmpyu  r   r$   c                    g)z,Convert a GMPY ``mpq`` object to ``dtype``. Nrz   r{   s      r!   from_QQ_gmpyDomain.from_QQ_gmpyy  r   r$   c                    g)z,Convert a real element object to ``dtype``. Nrz   r{   s      r!   from_RealFieldDomain.from_RealField}  r   r$   c                    g)z(Convert a complex element to ``dtype``. Nrz   r{   s      r!   from_ComplexFieldDomain.from_ComplexField  r   r$   c                    g)z*Convert an algebraic number to ``dtype``. Nrz   r{   s      r!   from_AlgebraicFieldDomain.from_AlgebraicField  r   r$   c                r    UR                   (       a&  U R                  UR                  UR                  5      $ g)#Convert a polynomial to ``dtype``. N)rX   rb   rc   domr{   s      r!   from_PolynomialRingDomain.from_PolynomialRing  s'    ;;::addBFF++ r$   c                    g)z*Convert a rational function to ``dtype``. Nrz   r{   s      r!   from_FractionFieldDomain.from_FractionField  r   r$   c                N    U R                  UR                  UR                  5      $ )z.Convert an ``ExtensionElement`` to ``dtype``. )rN   r   ringr{   s      r!   from_MonogenicFiniteExtension$Domain.from_MonogenicFiniteExtension  s    quubgg..r$   c                8    U R                  UR                  5      $ z&Convert a ``EX`` object to ``dtype``. )rd   exr{   s      r!   from_ExpressionDomainDomain.from_ExpressionDomain  s    }}QTT""r$   c                $    U R                  U5      $ r   )rd   r{   s      r!   from_ExpressionRawDomainDomain.from_ExpressionRawDomain  s    }}Qr$   c                    UR                  5       S::  a*  U R                  UR                  5       UR                  5      $ g)r   r   N)degreerb   rc   r   r{   s      r!   from_GlobalPolynomialRing Domain.from_GlobalPolynomialRing  s/    88:?::addfbff-- r$   c                $    U R                  X5      $ r   )r   r{   s      r!   from_GeneralizedPolynomialRing%Domain.from_GeneralizedPolynomialRing  s    $$Q++r$   c           
     B   U R                   (       a&  [        U R                  5      [        U5      -  (       d7  UR                   (       aG  [        UR                  5      [        U5      -  (       a!  [        SU < SU< S[	        U5      < S35      eU R                  U5      $ )NCannot unify  with z, given z generators)is_Compositesetsymbolsr   tupleunify)r}   r|   r   s      r!   unify_with_symbolsDomain.unify_with_symbols  sf    OORZZ3w<!?boo[^_a_i_i[jmpqxmy[y#VXZ\^cdk^l$mnnxx|r$   c                   U R                   (       a  U R                  OU nUR                   (       a  UR                  OUnU R                   (       a  U R                  OSnUR                   (       a  UR                  OSnUR                  U5      n[	        XE5      nU R                   (       a  U R
                  OUR
                  nU R                  (       a  UR                  (       d"  UR                  (       ae  U R                  (       aT  UR                  (       a  UR                  (       d2  UR                  (       a!  UR                  (       a  UR                  5       nU R                   (       a@  UR                   (       a"  U R                  (       d  UR                  (       a  U R                  n	OUR                  n	SSKJn
  X:X  a  U	" Xg5      $ U	" XgU5      $ )z2Unify two domains where at least one is composite.rz   r   )GlobalPolynomialRing)r   r   r   r   r   orderis_FractionFieldis_PolynomialRingis_Fieldhas_assoc_Ringget_ringr.   &sympy.polys.domains.old_polynomialringr   )r}   r|   	K0_ground	K1_ground
K0_symbols
K1_symbolsdomainr   r   clsr   s              r!   unify_compositeDomain.unify_composite  s    ooBFF2	 ooBFF2	#%??RZZ
#%??RZZ
+j5OO   R%9%9  R%9%9$$I,>,>FOO&&__&F??BOOr7J7JbNbNb,,C,,C
 	P&v''6E**r$   c                (	   Ub  U R                  X5      $ X:X  a  U $ U R                  (       a  UR                  (       dF  U R                  5       UR                  5       :w  a  [        SU < SU< 35      eU R	                  U5      $ U R
                  (       a  U $ UR
                  (       a  U$ U R                  (       a  U $ UR                  (       a  U$ U R                  (       d  UR                  (       a  UR                  (       a  XpUR                  (       aN  [        [        U R                  UR                  /5      5      S   U R                  :X  a  XpUR                  U 5      $ UR                  U R                  5      nU R                  R                  U5      nU R                  U5      $ U R                   (       d  UR                   (       a  U R	                  U5      $ UR"                  (       a  XpU R"                  (       aV  UR"                  (       d  UR$                  (       a2  U R&                  UR&                  :  a  U $ SSKJn  U" UR&                  S9$ U $ UR$                  (       a  XpU R$                  (       ai  UR$                  (       a  U R&                  UR&                  :  a  U $ U$ UR,                  (       d  UR.                  (       a  SSKJn  U" U R&                  S9$ U $ UR0                  (       a  XpU R0                  (       a  UR,                  (       a  UR3                  5       nUR.                  (       a  UR5                  5       nUR0                  (       aT  U R6                  " U R8                  R                  UR8                  5      /[;        U R<                  UR<                  5      Q76 $ U $ U R.                  (       a  U $ UR.                  (       a  U$ U R,                  (       a#  UR>                  (       a  U R3                  5       n U $ UR,                  (       a#  U R>                  (       a  UR3                  5       nU$ U R>                  (       a  U $ UR>                  (       a  U$ U R@                  (       a  U $ UR@                  (       a  U$ SSK!J"n  U$ )z
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``

r   r      r   )rT   )prec)EX)#r   has_CharacteristicZerocharacteristicr   r   is_EXRAWis_EXis_FiniteExtensionlistr   modulus
set_domaindropsymbolr   r   r   is_ComplexFieldis_RealField	precision sympy.polys.domains.complexfieldrT   is_GaussianRingis_GaussianFieldis_AlgebraicField	get_fieldas_AlgebraicFieldr.   r   r   orig_extis_RationalFieldis_IntegerRingr[   r   )r}   r|   r   rT   r   s        r!   r   Domain.unify  s3   " ((558I))b.G.G  "b&7&7&99'R(LMM
 %%b))
 ;;I;;I88I88I  B$9$9$$B$$ RZZ 89:1=K}}R(( WWRYY'YY__R(}}R((??boo%%b))!!R__<<2<</IM'R\\::	????<<2<</II##r':':I#66	!!\\^""))+##||BFFLL$8a;r{{TVT_T_;`aa	II""\\^I""\\^IIIII*	r$   c                b    [        U[        5      =(       a    U R                  UR                  :H  $ )z0Returns ``True`` if two domains are equivalent. )r\   r   r   r    others     r!   __eq__Domain.__eq__N  s#     %(FTZZ5;;-FFr$   c                    X:X  + $ )z1Returns ``False`` if two domains are equivalent. rz   r   s     r!   __ne__Domain.__ne__S  s      r$   c                    / nU HQ  n[        U[        5      (       a"  UR                  U R                  U5      5        M:  UR                  U " U5      5        MS     U$ )z5Rersively apply ``self`` to all elements of ``seq``. )r\   r   appendmap)r    seqrM   elts       r!   r   
Domain.mapW  sI    C#t$$dhhsm,d3i(	  r$   c                    [        SU -  5      e)z)Returns a ring associated with ``self``. z#there is no ring associated with %sr   r   s    r!   r   Domain.get_ringc  s    ?$FGGr$   c                    [        SU -  5      e)z*Returns a field associated with ``self``. z$there is no field associated with %sr   r   s    r!   r   Domain.get_fieldg  s    @4GHHr$   c                    U $ )z2Returns an exact domain associated with ``self``. rz   r   s    r!   	get_exactDomain.get_exactk  s    r$   c                d    [        US5      (       a  U R                  " U6 $ U R                  U5      $ )z0The mathematical way to make a polynomial ring. __iter__)hasattr	poly_ringr    r   s     r!   __getitem__Domain.__getitem__o  s-    7J''>>7++>>'**r$   )r   c                    SSK Jn  U" XU5      $ z(Returns a polynomial ring, i.e. `K[X]`. r   )PolynomialRing)"sympy.polys.domains.polynomialringr  )r    r   r   r  s       r!   r  Domain.poly_ringv  s    EdU33r$   c                    SSK Jn  U" XU5      $ z'Returns a fraction field, i.e. `K(X)`. r   )FractionField)!sympy.polys.domains.fractionfieldr  )r    r   r   r  s       r!   
frac_fieldDomain.frac_field{  s    CTE22r$   c                &    SSK Jn  U" U /UQ70 UD6$ r  )r   r  )r    r   kwargsr  s       r!   old_poly_ringDomain.old_poly_ring  s    Id7W777r$   c                &    SSK Jn  U" U /UQ70 UD6$ r  )%sympy.polys.domains.old_fractionfieldr  )r    r   r  r  s       r!   old_frac_fieldDomain.old_frac_field  s    GT6G6v66r$   r   c                   [        SU -  5      e)z6Returns an algebraic field, i.e. `K(\alpha, \ldots)`. z%Cannot create algebraic field over %sr   )r    r   	extensions      r!   algebraic_fieldDomain.algebraic_field  s    ADHIIr$   c                N    SSK Jn  U" X5      n[        XRS9nU R                  XbS9$ )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alphas          r!   alg_field_from_polyDomain.alg_field_from_poly  s0    J 	4t(2##E#77r$   c                f    SSK Jn  U(       a  U[        U5      -  nU R                  U" X5      UUS9$ )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&  )sympy.polys.specialpolysr,  r)   r)  )r    nssr   genr&  r,  s          r!   cyclotomic_fieldDomain.cyclotomic_field  s<    H 	=SVOE''(?u3= ( ? 	?r$   c                    [         e)z$Inject generators into this domain. r   r  s     r!   injectDomain.inject      !!r$   c                4    U R                   (       a  U $ [        e)z"Drop generators from this domain. )	is_Simpler   r  s     r!   r   Domain.drop  s    >>K!!r$   c                    U(       + $ )zReturns True if ``a`` is zero. rz   rk   s     r!   is_zeroDomain.is_zero  s	    ur$   c                    XR                   :H  $ )zReturns True if ``a`` is one. )r   rk   s     r!   is_oneDomain.is_one  s    HH}r$   c                    US:  $ )z#Returns True if ``a`` is positive. r   rz   rk   s     r!   is_positiveDomain.is_positive      1ur$   c                    US:  $ )z#Returns True if ``a`` is negative. r   rz   rk   s     r!   is_negativeDomain.is_negative  rC  r$   c                    US:*  $ )z'Returns True if ``a`` is non-positive. r   rz   rk   s     r!   is_nonpositiveDomain.is_nonpositive      Avr$   c                    US:  $ )z'Returns True if ``a`` is non-negative. r   rz   rk   s     r!   is_nonnegativeDomain.is_nonnegative   rJ  r$   c                `    U R                  U5      (       a  U R                  * $ U R                  $ r   )rE  r   rk   s     r!   canonical_unitDomain.canonical_unit  s(    AHH988Or$   c                    [        U5      $ )z.Absolute value of ``a``, implies ``__abs__``. )absrk   s     r!   rR  
Domain.abs
  s    1vr$   c                    U* $ )z,Returns ``a`` negated, implies ``__neg__``. rz   rk   s     r!   neg
Domain.neg  	    r	r$   c                    U7$ )z-Returns ``a`` positive, implies ``__pos__``. rz   rk   s     r!   pos
Domain.pos  rW  r$   c                
    X-   $ )z.Sum of ``a`` and ``b``, implies ``__add__``.  rz   r    rl   bs      r!   add
Domain.add  	    ur$   c                
    X-
  $ )z5Difference of ``a`` and ``b``, implies ``__sub__``.  rz   r\  s      r!   sub
Domain.sub  r`  r$   c                
    X-  $ )z2Product of ``a`` and ``b``, implies ``__mul__``.  rz   r\  s      r!   mul
Domain.mul  r`  r$   c                
    X-  $ )z2Raise ``a`` to power ``b``, implies ``__pow__``.  rz   r\  s      r!   pow
Domain.pow"  	    vr$   c                    [         e)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.

r   r\  s      r!   exquoDomain.exquo&  s    r "!r$   c                    [         e)a  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``
r   r\  s      r!   quo
Domain.quo  
     "!r$   c                    [         e)a  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``
r   r\  s      r!   rem
Domain.rem  rq  r$   c                    [         e)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.

r   r\  s      r!   div
Domain.div  s    h "!r$   c                    [         e)z5Returns inversion of ``a mod b``, implies something. r   r\  s      r!   invertDomain.invert  r6  r$   c                    [         e)z!Returns ``a**(-1)`` if possible. r   rk   s     r!   revertDomain.revert  r6  r$   c                    [         e)zReturns numerator of ``a``. r   rk   s     r!   numerDomain.numer  r6  r$   c                    [         e)zReturns denominator of ``a``. r   rk   s     r!   denomDomain.denom  r6  r$   c                0    U R                  X5      u  p4nX54$ )z&Half extended GCD of ``a`` and ``b``. )gcdex)r    rl   r]  sths         r!   
half_gcdexDomain.half_gcdex  s    **Q"atr$   c                    [         e)z!Extended GCD of ``a`` and ``b``. r   r\  s      r!   r  Domain.gcdex
  r6  r$   c                p    U R                  X5      nU R                  X5      nU R                  X#5      nX4U4$ )z.Returns GCD and cofactors of ``a`` and ``b``. )gcdro  )r    rl   r]  r  cfacfbs         r!   	cofactorsDomain.cofactors  s5    hhqnhhqhhq}r$   c                    [         e)z Returns GCD of ``a`` and ``b``. r   r\  s      r!   r  
Domain.gcd  r6  r$   c                    [         e)z Returns LCM of ``a`` and ``b``. r   r\  s      r!   lcm
Domain.lcm  r6  r$   c                    [         e)z#Returns b-base logarithm of ``a``. r   r\  s      r!   log
Domain.log  r6  r$   c                    [         e)a  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
r   rk   s     r!   sqrtDomain.sqrt!  rq  r$   c                    [         e)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
r   rk   s     r!   	is_squareDomain.is_square0  s
     "!r$   c                    [         e)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
r   rk   s     r!   exsqrtDomain.exsqrt@  s
     "!r$   c                F    U R                  U5      R                  " U40 UD6$ )z*Returns numerical approximation of ``a``. )rp   evalf)r    rl   r   optionss       r!   r  Domain.evalfQ  s!    }}Q%%d6g66r$   c                    U$ r   rz   rk   s     r!   realDomain.realW  s    r$   c                    U R                   $ r   )r   rk   s     r!   imagDomain.imagZ  s    yyr$   c                
    X:H  $ )z+Check if ``a`` and ``b`` are almost equal. rz   )r    rl   r]  	tolerances       r!   almosteqDomain.almosteq]  rj  r$   c                    [        S5      e)z*Return the characteristic of this domain. zcharacteristic()r   r   s    r!   r   Domain.characteristica  s    !"455r$   rz   r   )N)FzetaNr  )r/   
__module____qualname____firstlineno____doc__r   __annotations__r   r   is_Ringr   r   has_assoc_Fieldis_FiniteFieldis_FFr   is_ZZr   is_QQr   is_ZZ_Ir   is_QQ_Ir   is_RRr   is_CCr   is_Algebraicr   is_Polyr   is_Fracis_SymbolicDomainr   is_SymbolicRawDomainr   r   is_Exactra   r8  r   is_PIDr   r   r   r"   r&   r*   r0   r6   propertyr:   r=   r@   rN   rb   rZ   rm   rp   rd   rv   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)  r1  r4  r   r;  r>  rA  rE  rH  rL  rO  rR  rU  rY  r^  rb  re  rh  rl  ro  rs  rv  ry  r|  r  r  r  r  r  r  r  r  r  r  r  r  r.  r  r  r  r   __static_attributes__rz   r$   r!   r   r      s   hT E;, D# CO G$ H" N  O  #"NU""NU$$u %%Og!&&w  L5##Oe',,"''!&&w %%&++8HLILF" #CE:";!  !r"AdF,	["z"8*,
/# .
,+BBG
!
HI+ ), 4
 *- 3
8
7
 15 J(8T(?T""Y"v""T"l""""
"""""" ""7 	A6r$   r   N)r  
__future__r   typingr   sympy.core.numbersr   
sympy.corer   r   sympy.core.sortingr   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__rz   r$   r!   <module>r     sU    / "  . % & , ; % Q Q ; " 1 P6 P6 P6f* *r$   