B
    [YA                 @   s   d Z ddlmZmZ ddlmZ ddlmZmZ ddl	m
Z
mZmZ ddlmZmZmZ ddlmZ ddlmZ dd	lmZmZ dd
lmZ eG dd deZdS )z)Implementation of :class:`Domain` class.     )print_functiondivision)DomainElement)Basicsympify)HAS_GMPYinteger_typesis_sequence)UnificationFailedCoercionFailedDomainError)lex)_unify_gens)default_sort_keypublic)
deprecatedc               @   s8  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dZdZdZ dZ!dZ"dZ#dZ$e%e&ddddd	d
 Z'e%e&dddddd Z(dd Z)dd Z*dd Z+dd Z,dd Z-e%dd Z.dd Z/dd Z0dd Z1dd d!Z2d"d# Z3d$d% Z4d&d' Z5d(d) Z6d*d+ Z7d,d- Z8d.d/ Z9d0d1 Z:d2d3 Z;d4d5 Z<d6d7 Z=d8d9 Z>d:d; Z?d<d= Z@d>d? ZAd@dA ZBdBdC ZCdDdE ZDdFdG ZEddHdIZFdJdK ZGdLdM ZHdNdO ZIdPdQ ZJdRdS ZKdTdU ZLdVdW ZMdXdY ZNdZd[ ZOd\d] ZPd^d_ ZQd`da ZRdbdc ZSddde ZTdfdg ZUdhdi ZVdjdk ZWdldm ZXdndo ZYdpdq ZZdrds Z[dtdu Z\dvdw Z]dxdy Z^dzd{ Z_d|d} Z`d~d Zadd Zbdd Zcdd Zddd Zedd Zfdd Zgdd Zhdd Zidd Zjdd Zkdd Zldd Zmdd Zndd ZodddZpepZqdd Zrdd ZsdddZtdd ZudS )DomainzRepresents an abstract domain. NFTis_Fieldi1  z1.1)Z
useinsteadZissueZdeprecated_since_versionc             C   s   | j S )N)r   )self r   9lib/python3.7/site-packages/sympy/polys/domains/domain.py	has_Field5   s    zDomain.has_Fieldis_Ringc             C   s   | j S )N)r   )r   r   r   r   has_Ring:   s    zDomain.has_Ringc             C   s   t d S )N)NotImplementedError)r   r   r   r   __init__?   s    zDomain.__init__c             C   s   | j S )N)rep)r   r   r   r   __str__B   s    zDomain.__str__c             C   s   t | S )N)str)r   r   r   r   __repr__E   s    zDomain.__repr__c             C   s   t | jj| jfS )N)hash	__class____name__dtype)r   r   r   r   __hash__H   s    zDomain.__hash__c             G   s
   | j | S )N)r#   )r   argsr   r   r   newK   s    z
Domain.newc             C   s   | j S )N)r#   )r   r   r   r   tpN   s    z	Domain.tpc             G   s
   | j | S )z7Construct an element of ``self`` domain from ``args``. )r&   )r   r%   r   r   r   __call__R   s    zDomain.__call__c             G   s
   | j | S )N)r#   )r   r%   r   r   r   normalV   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)can't convert %s of type %s from %s to %s)aliasr!   r"   getattrr   type)r   elementbasemethod_convertresultr   r   r   convert_fromY   s    


zDomain.convert_fromc          	   C   s  |dk	r|  ||S | |r"|S ddlm}m}m}m}m} t|t	rV|  || S t
r| }t||jrx|  ||S | }	t||	jr|  ||	S t|tr|dd}
|  |
||
S t|tr|dd}
|  |
||
S t|tr|  || S | jrt|ddr| | S t|trPy
| |S  ttfk
rL   Y nX nHt|sy"t|}t|trz| |S W n ttfk
r   Y nX td|t|| f dS )z'Convert ``element`` to ``self.dtype``. Nr   )PythonIntegerRingGMPYIntegerRingGMPYRationalField	RealFieldComplexFieldF)tol	is_groundz!can't convert %s of type %s to %s)r2   of_typesympy.polys.domainsr3   r4   r5   r6   r7   
isinstancer   r   r'   floatcomplexr   parentis_Numericalr+   convertLCr   
from_sympy	TypeError
ValueErrorr	   r   r   r,   )r   r-   r.   r3   r4   r5   r6   r7   ZintegersZ	rationalsr?   r   r   r   rA   j   sJ    








zDomain.convertc             C   s   t || jS )z%Check if ``a`` is of type ``dtype``. )r<   r'   )r   r-   r   r   r   r:      s    zDomain.of_typec             C   s(   y|  | W n tk
r"   dS X dS )z'Check if ``a`` belongs to this domain. FT)rA   r   )r   ar   r   r   __contains__   s
    zDomain.__contains__c             C   s   t dS )z!Convert ``a`` to a SymPy object. N)r   )r   rF   r   r   r   to_sympy   s    zDomain.to_sympyc             C   s   t dS )z%Convert a SymPy object to ``dtype``. N)r   )r   rF   r   r   r   rC      s    zDomain.from_sympyc             C   s   dS )z.Convert ``ModularInteger(int)`` to ``dtype``. Nr   )K1rF   K0r   r   r   from_FF_python   s    zDomain.from_FF_pythonc             C   s   dS )z.Convert a Python ``int`` object to ``dtype``. Nr   )rI   rF   rJ   r   r   r   from_ZZ_python   s    zDomain.from_ZZ_pythonc             C   s   dS )z3Convert a Python ``Fraction`` object to ``dtype``. Nr   )rI   rF   rJ   r   r   r   from_QQ_python   s    zDomain.from_QQ_pythonc             C   s   dS )z.Convert ``ModularInteger(mpz)`` to ``dtype``. Nr   )rI   rF   rJ   r   r   r   from_FF_gmpy   s    zDomain.from_FF_gmpyc             C   s   dS )z,Convert a GMPY ``mpz`` object to ``dtype``. Nr   )rI   rF   rJ   r   r   r   from_ZZ_gmpy   s    zDomain.from_ZZ_gmpyc             C   s   dS )z,Convert a GMPY ``mpq`` object to ``dtype``. Nr   )rI   rF   rJ   r   r   r   from_QQ_gmpy   s    zDomain.from_QQ_gmpyc             C   s   dS )z,Convert a real element object to ``dtype``. Nr   )rI   rF   rJ   r   r   r   from_RealField   s    zDomain.from_RealFieldc             C   s   dS )z(Convert a complex element to ``dtype``. Nr   )rI   rF   rJ   r   r   r   from_ComplexField   s    zDomain.from_ComplexFieldc             C   s   dS )z*Convert an algebraic number to ``dtype``. Nr   )rI   rF   rJ   r   r   r   from_AlgebraicField   s    zDomain.from_AlgebraicFieldc             C   s   |j r| |j|jS dS )z#Convert a polynomial to ``dtype``. N)r9   rA   rB   dom)rI   rF   rJ   r   r   r   from_PolynomialRing   s    zDomain.from_PolynomialRingc             C   s   dS )z*Convert a rational function to ``dtype``. Nr   )rI   rF   rJ   r   r   r   from_FractionField   s    zDomain.from_FractionFieldc             C   s   |  |jS )z&Convert a ``EX`` object to ``dtype``. )rC   ex)rI   rF   rJ   r   r   r   from_ExpressionDomain   s    zDomain.from_ExpressionDomainc             C   s"   |  dkr| | |jS dS )z#Convert a polynomial to ``dtype``. r   N)ZdegreerA   rB   rT   )rI   rF   rJ   r   r   r   from_GlobalPolynomialRing   s    z Domain.from_GlobalPolynomialRingc             C   s   |  ||S )N)rV   )rI   rF   rJ   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+can't unify %s with %s, given %s generators)is_Compositesetsymbolsr
   tupleunify)rJ   rI   r]   r   r   r   unify_with_symbols   s    0zDomain.unify_with_symbolsc             C   s  |dk	r|  ||S | |kr | S | jr*| S |jr4|S | jsB|jr,| jrN| jn| }|jr^|jn|}| jrn| jnd}|jr~|jnd}||}t||}| jr| jn|j}| jr|j	s|jr| j	r|j
r|j
s|j
r| }| jr|jr| js|j	r| j}	n|j}	ddlm}
 |	|
kr |	||S |	|||S dd }| jrR|jrR|| j| |S | jrp|jrp|| j| |S | jr|jr||j|| S | jr|jr|| j| |S | js| jr| S |js|jr|S | jr|jr| j| j|jft| j|j S | jr| S |jr |S | jr,| S |jr8|S | jrD| S |jrP|S | jrx|jrx| 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``

        Nr   r   )GlobalPolynomialRingc             S   s(   t |j|j}t |j|j}| ||dS )N)precr8   )maxZ	precision	tolerance)clsrJ   rI   rb   r8   r   r   r   	mkinexact+  s    zDomain.unify.<locals>.mkinexact)key)EX)r`   is_EXr[   rT   r]   r_   r   orderis_FractionFieldis_PolynomialRingr   get_ringr!   &sympy.polys.domains.old_polynomialringra   is_ComplexFieldis_RealFieldis_AlgebraicFieldZorig_extis_RationalFieldis_IntegerRingis_FiniteFieldrc   modr   r;   rh   )rJ   rI   r]   Z	K0_groundZ	K1_groundZ
K0_symbolsZ
K1_symbolsZdomainrj   re   ra   rf   rh   r   r   r   r_      st    



$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__T  s    zDomain.__eq__c             C   s
   | |k S )z1Returns ``False`` if two domains are equivalent. r   )r   rv   r   r   r   __ne__X  s    zDomain.__ne__c             C   s@   g }x6|D ].}t |tr*|| | q
|| | q
W |S )z5Rersively apply ``self`` to all elements of ``seq``. )r<   listappendmap)r   seqr1   Z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   rm   h  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 %sN)r   )r   r   r   r   	get_fieldl  s    zDomain.get_fieldc             C   s   | S )z2Returns an exact domain associated with ``self``. r   )r   r   r   r   	get_exactp  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   r]   r   r   r   __getitem__t  s    

zDomain.__getitem__c             O   s    ddl m} || ||dtS )z(Returns a polynomial ring, i.e. `K[X]`. r   )PolynomialRingrj   )Z"sympy.polys.domains.polynomialringr   getr   )r   r]   kwargsr   r   r   r   r   {  s    zDomain.poly_ringc             O   s    ddl m} || ||dtS )z'Returns a fraction field, i.e. `K(X)`. r   )FractionFieldrj   )Z!sympy.polys.domains.fractionfieldr   r   r   )r   r]   r   r   r   r   r   
frac_field  s    zDomain.frac_fieldc             O   s   ddl m} || f||S )z(Returns a polynomial ring, i.e. `K[X]`. r   )r   )rn   r   )r   r]   r   r   r   r   r   old_poly_ring  s    zDomain.old_poly_ringc             O   s   ddl m} || f||S )z'Returns a fraction field, i.e. `K(X)`. r   )r   )Z%sympy.polys.domains.old_fractionfieldr   )r   r]   r   r   r   r   r   old_frac_field  s    zDomain.old_frac_fieldc             G   s   t d|  dS )z6Returns an algebraic field, i.e. `K(\alpha, \ldots)`. z$can't create algebraic field over %sN)r   )r   	extensionr   r   r   algebraic_field  s    zDomain.algebraic_fieldc             G   s   t dS )z$Inject generators into this domain. N)r   )r   r]   r   r   r   inject  s    zDomain.injectc             C   s   | S )zReturns True if ``a`` is zero. r   )r   rF   r   r   r   is_zero  s    zDomain.is_zeroc             C   s
   || j kS )zReturns True if ``a`` is one. )one)r   rF   r   r   r   is_one  s    zDomain.is_onec             C   s   |dkS )z#Returns True if ``a`` is positive. r   r   )r   rF   r   r   r   is_positive  s    zDomain.is_positivec             C   s   |dk S )z#Returns True if ``a`` is negative. r   r   )r   rF   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   )r   rF   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   )r   rF   r   r   r   is_nonnegative  s    zDomain.is_nonnegativec             C   s   t |S )z.Absolute value of ``a``, implies ``__abs__``. )abs)r   rF   r   r   r   r     s    z
Domain.absc             C   s   | S )z,Returns ``a`` negated, implies ``__neg__``. r   )r   rF   r   r   r   neg  s    z
Domain.negc             C   s   |
 S )z-Returns ``a`` positive, implies ``__pos__``. r   )r   rF   r   r   r   pos  s    z
Domain.posc             C   s   || S )z.Sum of ``a`` and ``b``, implies ``__add__``.  r   )r   rF   br   r   r   add  s    z
Domain.addc             C   s   || S )z5Difference of ``a`` and ``b``, implies ``__sub__``.  r   )r   rF   r   r   r   r   sub  s    z
Domain.subc             C   s   || S )z2Product of ``a`` and ``b``, implies ``__mul__``.  r   )r   rF   r   r   r   r   mul  s    z
Domain.mulc             C   s   || S )z2Raise ``a`` to power ``b``, implies ``__pow__``.  r   )r   rF   r   r   r   r   pow  s    z
Domain.powc             C   s   t dS )z6Exact quotient of ``a`` and ``b``, implies something. N)r   )r   rF   r   r   r   r   exquo  s    zDomain.exquoc             C   s   t dS )z1Quotient of ``a`` and ``b``, implies something.  N)r   )r   rF   r   r   r   r   quo  s    z
Domain.quoc             C   s   t dS )z4Remainder of ``a`` and ``b``, implies ``__mod__``.  N)r   )r   rF   r   r   r   r   rem  s    z
Domain.remc             C   s   t dS )z0Division of ``a`` and ``b``, implies something. N)r   )r   rF   r   r   r   r   div  s    z
Domain.divc             C   s   t dS )z5Returns inversion of ``a mod b``, implies something. N)r   )r   rF   r   r   r   r   invert  s    zDomain.invertc             C   s   t dS )z!Returns ``a**(-1)`` if possible. N)r   )r   rF   r   r   r   revert  s    zDomain.revertc             C   s   t dS )zReturns numerator of ``a``. N)r   )r   rF   r   r   r   numer  s    zDomain.numerc             C   s   t dS )zReturns denominator of ``a``. N)r   )r   rF   r   r   r   denom  s    zDomain.denomc             C   s   |  ||\}}}||fS )z&Half extended GCD of ``a`` and ``b``. )gcdex)r   rF   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``. N)r   )r   rF   r   r   r   r   r     s    zDomain.gcdexc             C   s.   |  ||}| ||}| ||}|||fS )z.Returns GCD and cofactors of ``a`` and ``b``. )gcdr   )r   rF   r   r   ZcfaZcfbr   r   r   	cofactors  s    zDomain.cofactorsc             C   s   t dS )z Returns GCD of ``a`` and ``b``. N)r   )r   rF   r   r   r   r   r     s    z
Domain.gcdc             C   s   t dS )z Returns LCM of ``a`` and ``b``. N)r   )r   rF   r   r   r   r   lcm  s    z
Domain.lcmc             C   s   t dS )z#Returns b-base logarithm of ``a``. N)r   )r   rF   r   r   r   r   log  s    z
Domain.logc             C   s   t dS )zReturns square root of ``a``. N)r   )r   rF   r   r   r   sqrt  s    zDomain.sqrtc             K   s   |  |j|f|S )z*Returns numerical approximation of ``a``. )rH   evalf)r   rF   rb   Zoptionsr   r   r   r     s    zDomain.evalfc             C   s   |S )Nr   )r   rF   r   r   r   real  s    zDomain.realc             C   s   | j S )N)zero)r   rF   r   r   r   imag  s    zDomain.imagc             C   s   ||kS )z+Check if ``a`` and ``b`` are almost equal. r   )r   rF   r   rd   r   r   r   almosteq  s    zDomain.almosteqc             C   s   t ddS )z*Return the characteristic of this domain. zcharacteristic()N)r   )r   r   r   r   characteristic  s    zDomain.characteristic)N)N)N)N)vr"   
__module____qualname____doc__r#   r   r   r   r   Zhas_assoc_RingZhas_assoc_Fieldrt   Zis_FFrs   Zis_ZZrr   Zis_QQrp   Zis_RRro   Zis_CCrq   Zis_Algebraicrl   Zis_Polyrk   Zis_FracZis_SymbolicDomainri   Zis_Exactr@   Z	is_Simpler[   Zis_PIDZhas_CharacteristicZeror   r*   propertyr   r   r   r   r   r   r$   r&   r'   r(   r)   r2   rA   r:   rG   rH   rC   rK   rL   rM   rN   rO   rP   rQ   rR   rS   rU   rV   rX   rY   rZ   r`   r_   rw   rx   r{   rm   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   nr   r   r   r   r   r   r   r   r      s   
6	
`

r   N)r   Z
__future__r   r   Z!sympy.polys.domains.domainelementr   Z
sympy.corer   r   Zsympy.core.compatibilityr   r   r	   Zsympy.polys.polyerrorsr
   r   r   Zsympy.polys.orderingsr   Zsympy.polys.polyutilsr   Zsympy.utilitiesr   r   Zsympy.core.decoratorsr   objectr   r   r   r   r   <module>   s   