B
    [~                 @   sp   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
 ddlmZ eG dd deZG d	d
 d
eZdS )z.Implementation of :class:`QuotientRing` class.    )print_functiondivision)Ring)NotReversibleCoercionFailed)FreeModuleQuotientRing)publicc               @   s   e Zd ZdZdd Zdd Zdd ZeZdd	 Zd
d Z	dd Z
dd ZeZdd ZeZdd ZeZdd Zdd Zdd ZdS )QuotientRingElementz
    Class representing elements of (commutative) quotient rings.

    Attributes:

    - ring - containing ring
    - data - element of ring.ring (i.e. base ring) representing self
    c             C   s   || _ || _d S )N)ringdata)selfr
   r    r   ?lib/python3.7/site-packages/sympy/polys/domains/quotientring.py__init__   s    zQuotientRingElement.__init__c             C   s&   ddl m} || jd t| jj S )Nr   )sstrz + )Zsympyr   r   strr
   
base_ideal)r   r   r   r   r   __str__   s    zQuotientRingElement.__str__c          	   C   sT   t || jr|j| jkrBy| j|}W n ttfk
r@   tS X | | j|j S )N)
isinstance	__class__r
   convertNotImplementedErrorr   NotImplementedr   )r   omr   r   r   __add__#   s    zQuotientRingElement.__add__c             C   s   |  | j| j j d S )N)r
   r   r   )r   r   r   r   __neg__-   s    zQuotientRingElement.__neg__c             C   s   |  | S )N)r   )r   r   r   r   r   __sub__0   s    zQuotientRingElement.__sub__c             C   s   |   |S )N)r   )r   r   r   r   r   __rsub__3   s    zQuotientRingElement.__rsub__c          	   C   sH   t || js6y| j|}W n ttfk
r4   tS X | | j|j S )N)r   r   r
   r   r   r   r   r   )r   or   r   r   __mul__6   s    zQuotientRingElement.__mul__c             C   s   | j | | S )N)r
   revert)r   r   r   r   r   __rdiv__@   s    zQuotientRingElement.__rdiv__c          	   C   sF   t || js6y| j|}W n ttfk
r4   tS X | j||  S )N)r   r   r
   r   r   r   r   r!   )r   r   r   r   r   __div__E   s    zQuotientRingElement.__div__c             C   s   |  | j| S )N)r
   r   )r   Zothr   r   r   __pow__O   s    zQuotientRingElement.__pow__c             C   s,   t || jr|j| jkrdS | j| | S )NF)r   r   r
   is_zero)r   r   r   r   r   __eq__R   s    zQuotientRingElement.__eq__c             C   s
   | |k S )Nr   )r   r   r   r   r   __ne__W   s    zQuotientRingElement.__ne__N)__name__
__module____qualname____doc__r   r   r   __radd__r   r   r   r    __rmul__r"   __rtruediv__r#   __truediv__r$   r&   r'   r   r   r   r   r	      s"   	r	   c               @   s   e Zd ZdZdZdZeZdd Zdd Z	dd	 Z
d
d Zdd Zdd ZeZeZeZeZeZeZdd Zdd Zdd Zdd Zdd Zdd Zdd Zdd Zd S )!QuotientRingaa  
    Class representing (commutative) quotient rings.

    You should not usually instantiate this by hand, instead use the constructor
    from the base ring in the construction.

    >>> from sympy.abc import x
    >>> from sympy import QQ
    >>> I = QQ.old_poly_ring(x).ideal(x**3 + 1)
    >>> QQ.old_poly_ring(x).quotient_ring(I)
    QQ[x]/<x**3 + 1>

    Shorter versions are possible:

    >>> QQ.old_poly_ring(x)/I
    QQ[x]/<x**3 + 1>

    >>> QQ.old_poly_ring(x)/[x**3 + 1]
    QQ[x]/<x**3 + 1>

    Attributes:

    - ring - the base ring
    - base_ideal - the ideal used to form the quotient
    TFc             C   sF   |j |kstd||f || _ || _| | j j| _| | j j| _d S )NzIdeal must belong to %s, got %s)r
   
ValueErrorr   ZzeroZone)r   r
   idealr   r   r   r   z   s    
zQuotientRing.__init__c             C   s   t | jd t | j S )N/)r   r
   r   )r   r   r   r   r      s    zQuotientRing.__str__c             C   s   t | jj| j| j| jfS )N)hashr   r(   dtyper
   r   )r   r   r   r   __hash__   s    zQuotientRing.__hash__c             C   s,   t || jjs| |}| | | j|S )z0Construct an element of `self` domain from `a`. )r   r
   r5   r   Zreduce_element)r   ar   r   r   new   s    
zQuotientRing.newc             C   s"   t |to | j|jko | j|jkS )z.Returns `True` if two domains are equivalent. )r   r0   r
   r   )r   otherr   r   r   r&      s    
zQuotientRing.__eq__c             C   s   | | j ||S )z*Convert a Python `int` object to `dtype`. )r
   r   )ZK1r7   K0r   r   r   from_ZZ_python   s    zQuotientRing.from_ZZ_pythonc             C   s   | | j |S )N)r
   
from_sympy)r   r7   r   r   r   r<      s    zQuotientRing.from_sympyc             C   s   | j |jS )N)r
   to_sympyr   )r   r7   r   r   r   r=      s    zQuotientRing.to_sympyc             C   s   || kr|S d S )Nr   )r   r7   r:   r   r   r   from_QuotientRing   s    zQuotientRing.from_QuotientRingc             G   s   t ddS )z(Returns a polynomial ring, i.e. `K[X]`. znested domains not allowedN)r   )r   gensr   r   r   	poly_ring   s    zQuotientRing.poly_ringc             G   s   t ddS )z'Returns a fraction field, i.e. `K(X)`. znested domains not allowedN)r   )r   r?   r   r   r   
frac_field   s    zQuotientRing.frac_fieldc             C   sP   | j |j| j }y| |dd S  tk
rJ   td|| f Y nX dS )z/
        Compute a**(-1), if possible.
           r   z%s not a unit in %rN)r
   r2   r   r   Zin_terms_of_generatorsr1   r   )r   r7   Ir   r   r   r!      s
    zQuotientRing.revertc             C   s   | j |jS )N)r   containsr   )r   r7   r   r   r   r%      s    zQuotientRing.is_zeroc             C   s
   t | |S )z
        Generate a free module of rank ``rank`` over ``self``.

        >>> from sympy.abc import x
        >>> from sympy import QQ
        >>> (QQ.old_poly_ring(x)/[x**2 + 1]).free_module(2)
        (QQ[x]/<x**2 + 1>)**2
        )r   )r   Zrankr   r   r   free_module   s    	zQuotientRing.free_moduleN)r(   r)   r*   r+   Zhas_assoc_RingZhas_assoc_Fieldr	   r5   r   r   r6   r8   r&   r;   Zfrom_QQ_pythonZfrom_ZZ_gmpyZfrom_QQ_gmpyZfrom_RealFieldZfrom_GlobalPolynomialRingZfrom_FractionFieldr<   r=   r>   r@   rA   r!   r%   rE   r   r   r   r   r0   [   s0   
r0   N)r+   Z
__future__r   r   Zsympy.polys.domains.ringr   Zsympy.polys.polyerrorsr   r   Zsympy.polys.agca.modulesr   Zsympy.utilitiesr   objectr	   r0   r   r   r   r   <module>   s   J