o
    *ήc                     @   s^   d 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Z
G dd	 d	eZd
S )z.Implementation of :class:`QuotientRing` class.    FreeModuleQuotientRing)Ring)NotReversibleCoercionFailed)publicc                   @   s   e Zd ZdZdd Zdd Ze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dd 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   G/tmp/pip-target-vg8gfxp4/lib/python/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 + )sympy.printing.strr   r   strr
   
base_ideal)r   r   r   r   r   __str__   s   zQuotientRingElement.__str__c                 C   s   | j |  S r	   )r
   is_zeror   r   r   r   __bool__#      zQuotientRingElement.__bool__c              	   C   sV   t || jr|j| jkr"z| j|}W n ttfy!   t Y S w | | j|j S r	   
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__0      zQuotientRingElement.__neg__c                 C   s   |  | S r	   r!   r   r   r   r   __sub__3      zQuotientRingElement.__sub__c                 C   s   |   |S r	   r%   r   r   r   r   __rsub__6   r'   zQuotientRingElement.__rsub__c              	   C   sJ   t || jsz| j|}W n ttfy   t Y S w | | j|j S r	   r   r   or   r   r   __mul__9   s   zQuotientRingElement.__mul__c                 C   s   | j | | S r	   )r
   revertr)   r   r   r   __rtruediv__C      z QuotientRingElement.__rtruediv__c              	   C   sH   t || jsz| j|}W n ttfy   t Y S w | j||  S r	   )r   r   r
   r   r   r   r   r,   r)   r   r   r   __truediv__F   s   zQuotientRingElement.__truediv__c                 C   s*   |dk r| j | |  S |  | j| S )Nr   )r
   r,   r   )r   othr   r   r   __pow__N   s   zQuotientRingElement.__pow__c                 C   s,   t || jr|j| jkrdS | j| | S )NF)r   r   r
   r   r   r   r   r   __eq__S   s   zQuotientRingElement.__eq__c                 C   s
   | |k S r	   r   r   r   r   r   __ne__X   s   
zQuotientRingElement.__ne__N)__name__
__module____qualname____doc__r   r   __repr__r   r!   __radd__r#   r&   r(   r+   __rmul__r-   r/   r1   r2   r3   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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   zeroone)r   r
   idealr   r   r   r   {   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 r	   )hashr   r4   dtyper
   r   r   r   r   r   __hash__   r$   zQuotientRing.__hash__c                 C   s,   t || jjs| |}| | | j|S )z4Construct an element of ``self`` domain from ``a``. )r   r
   rB   r   reduce_elementr   ar   r   r   new   s   
zQuotientRing.newc                 C   s"   t |to| j|jko| j|jkS )z0Returns ``True`` if two domains are equivalent. )r   r;   r
   r   )r   otherr   r   r   r2      s
   


zQuotientRing.__eq__c                 C   s   | | j ||S )z.Convert a Python ``int`` object to ``dtype``. )r
   r   )K1rF   K0r   r   r   from_ZZ   s   zQuotientRing.from_ZZc                 C   s   | | j |S r	   )r
   
from_sympyrE   r   r   r   rL      r.   zQuotientRing.from_sympyc                 C      | j |jS r	   )r
   to_sympyr   rE   r   r   r   rN      r   zQuotientRing.to_sympyc                 C   s   || kr|S d S r	   r   )r   rF   rJ   r   r   r   from_QuotientRing   s   zQuotientRing.from_QuotientRingc                 G      t d)z*Returns a polynomial ring, i.e. ``K[X]``. nested domains not allowedr   r   gensr   r   r   	poly_ring      zQuotientRing.poly_ringc                 G   rP   )z)Returns a fraction field, i.e. ``K(X)``. rQ   rR   rS   r   r   r   
frac_field   rV   zQuotientRing.frac_fieldc                 C   sH   | j |j| j }z
| |dd W S  ty#   td|| f w )z/
        Compute a**(-1), if possible.
           r   z%s not a unit in %r)r
   r?   r   r   in_terms_of_generatorsr<   r   )r   rF   Ir   r   r   r,      s   zQuotientRing.revertc                 C   rM   r	   )r   containsr   rE   r   r   r   r      r   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   rankr   r   r   free_module   s   
	zQuotientRing.free_moduleN)r4   r5   r6   r7   has_assoc_Ringhas_assoc_Fieldr   rB   r   r   rC   rG   r2   rK   from_ZZ_pythonfrom_QQ_pythonfrom_ZZ_gmpyfrom_QQ_gmpyfrom_RealFieldfrom_GlobalPolynomialRingfrom_FractionFieldrL   rN   rO   rU   rW   r,   r   r]   r   r   r   r   r;   \   s4    
r;   N)r7   sympy.polys.agca.modulesr   sympy.polys.domains.ringr   sympy.polys.polyerrorsr   r   sympy.utilitiesr   r   r;   r   r   r   r   <module>   s    M