o
    h                     @   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   V/var/www/html/ai/venv/lib/python3.10/site-packages/sympy/polys/domains/quotientring.py__init__   s   
zQuotientRingElement.__init__c                 C   s4   ddl m} | jj| j}||d t| jj S )Nr   )sstrz + )sympy.printing.strr   r
   to_sympyr   str
base_ideal)r   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__1      zQuotientRingElement.__neg__c                 C   s   |  | S r	   r"   r    r   r   r   __sub__4      zQuotientRingElement.__sub__c                 C   s   |   |S r	   r&   r    r   r   r   __rsub__7   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__:   s   zQuotientRingElement.__mul__c                 C   s   | j | | S r	   )r
   revertr*   r   r   r   __rtruediv__D      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__G   s   zQuotientRingElement.__truediv__c                 C   s*   |dk r| j | |  S |  | j| S )Nr   )r
   r-   r   )r   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
   r   r    r   r   r   __eq__T   s   zQuotientRingElement.__eq__c                 C   s
   | |k S r	   r   r    r   r   r   __ne__Y   s   
zQuotientRingElement.__ne__N)__name__
__module____qualname____doc__r   r   __repr__r   r"   __radd__r$   r'   r)   r,   __rmul__r.   r0   r2   r3   r4   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   r5   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
   rC   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   r3      s
   


zQuotientRing.__eq__c                 C   s   | | j ||S )z.Convert a Python ``int`` object to ``dtype``. )r
   r   )K1rG   K0r   r   r   from_ZZ   s   zQuotientRing.from_ZZc                 C   s   | | j |S r	   )r
   
from_sympyrF   r   r   r   rM      r/   zQuotientRing.from_sympyc                 C      | j |jS r	   )r
   r   r   rF   r   r   r   r      r   zQuotientRing.to_sympyc                 C   s   || kr|S d S r	   r   )r   rG   rK   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   rG   Ir   r   r   r-      s   zQuotientRing.revertc                 C   rN   r	   )r   containsr   rF   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)r5   r6   r7   r8   has_assoc_Ringhas_assoc_Fieldr   rC   r   r   rD   rH   r3   rL   from_ZZ_pythonfrom_QQ_pythonfrom_ZZ_gmpyfrom_QQ_gmpyfrom_RealFieldfrom_GlobalPolynomialRingfrom_FractionFieldrM   r   rO   rU   rW   r-   r   r]   r   r   r   r   r<   ]   s4    
r<   N)r8   sympy.polys.agca.modulesr   sympy.polys.domains.ringr   sympy.polys.polyerrorsr   r   sympy.utilitiesr   r   r<   r   r   r   r   <module>   s    N