o
    8Va                     @   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   B/usr/lib/python3/dist-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   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   Z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   Z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-   r.   r/   r0   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   ZzeroZ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   r1   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
   r=   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 )z0Returns ``True`` if two domains are equivalent. )r   r8   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K1r@   K0r   r   r   from_ZZ   s   zQuotientRing.from_ZZc                 C   s   | | j |S r	   )r
   
from_sympyr?   r   r   r   rE      r,   zQuotientRing.from_sympyc                 C      | j |jS r	   )r
   to_sympyr   r?   r   r   r   rG      r   zQuotientRing.to_sympyc                 C   s   || kr|S d S r	   r   )r   r@   rC   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   Zgensr   r   r   	poly_ring      zQuotientRing.poly_ringc                 G   rI   )z)Returns a fraction field, i.e. ``K(X)``. rJ   rK   rL   r   r   r   
frac_field   rN   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   Zin_terms_of_generatorsr9   r   )r   r@   Ir   r   r   r*      s   zQuotientRing.revertc                 C   rF   r	   )r   containsr   r?   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   Zrankr   r   r   free_module   s   
	zQuotientRing.free_moduleN)r1   r2   r3   r4   Zhas_assoc_RingZhas_assoc_Fieldr   r=   r   r   r>   rA   r/   rD   Zfrom_ZZ_pythonZfrom_QQ_pythonZfrom_ZZ_gmpyZfrom_QQ_gmpyZfrom_RealFieldZfrom_GlobalPolynomialRingZfrom_FractionFieldrE   rG   rH   rM   rO   r*   r   rS   r   r   r   r   r8   \   s4    
r8   N)r4   Zsympy.polys.agca.modulesr   Zsympy.polys.domains.ringr   Zsympy.polys.polyerrorsr   r   Zsympy.utilitiesr   r   r8   r   r   r   r   <module>   s    M