o
    jgA+                     @   s@   d Z ddlmZ ddlmZ G dd deZG dd deZdS )	z-Computations with ideals of polynomial rings.    )CoercionFailed)IntegerPowerablec                   @   s  e Zd Zd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d 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$d% Zd&d' Zd(d) Zd*d+ Zd,d- Zd.d/ Zd0d1 Zd2d3 Zd4d5 ZeZd6d7 ZeZ d8d9 Z!d:d; Z"d<d= Z#d>d? Z$d@S )AIdeala  
    Abstract base class for ideals.

    Do not instantiate - use explicit constructors in the ring class instead:

    >>> from sympy import QQ
    >>> from sympy.abc import x
    >>> QQ.old_poly_ring(x).ideal(x+1)
    <x + 1>

    Attributes

    - ring - the ring this ideal belongs to

    Non-implemented methods:

    - _contains_elem
    - _contains_ideal
    - _quotient
    - _intersect
    - _union
    - _product
    - is_whole_ring
    - is_zero
    - is_prime, is_maximal, is_primary, is_radical
    - is_principal
    - height, depth
    - radical

    Methods that likely should be overridden in subclasses:

    - reduce_element
    c                 C      t )z&Implementation of element containment.NotImplementedErrorselfx r   O/var/www/html/zoom/venv/lib/python3.10/site-packages/sympy/polys/agca/ideals.py_contains_elem*      zIdeal._contains_elemc                 C   r   )z$Implementation of ideal containment.r   )r	   Ir   r   r   _contains_ideal.   r   zIdeal._contains_idealc                 C   r   )z!Implementation of ideal quotient.r   r	   Jr   r   r   	_quotient2   r   zIdeal._quotientc                 C   r   )z%Implementation of ideal intersection.r   r   r   r   r   
_intersect6   r   zIdeal._intersectc                 C   r   )z*Return True if ``self`` is the whole ring.r   r	   r   r   r   is_whole_ring:   r   zIdeal.is_whole_ringc                 C   r   )z*Return True if ``self`` is the zero ideal.r   r   r   r   r   is_zero>   r   zIdeal.is_zeroc                 C   s   |  |o	| | S )z!Implementation of ideal equality.)r   r   r   r   r   _equalsB   s   zIdeal._equalsc                 C   r   )z)Return True if ``self`` is a prime ideal.r   r   r   r   r   is_primeF   r   zIdeal.is_primec                 C   r   )z+Return True if ``self`` is a maximal ideal.r   r   r   r   r   
is_maximalJ   r   zIdeal.is_maximalc                 C   r   )z+Return True if ``self`` is a radical ideal.r   r   r   r   r   
is_radicalN   r   zIdeal.is_radicalc                 C   r   )z+Return True if ``self`` is a primary ideal.r   r   r   r   r   
is_primaryR   r   zIdeal.is_primaryc                 C   r   )z-Return True if ``self`` is a principal ideal.r   r   r   r   r   is_principalV   r   zIdeal.is_principalc                 C   r   )z Compute the radical of ``self``.r   r   r   r   r   radicalZ   r   zIdeal.radicalc                 C   r   )zCompute the depth of ``self``.r   r   r   r   r   depth^   r   zIdeal.depthc                 C   r   )zCompute the height of ``self``.r   r   r   r   r   heightb   r   zIdeal.heightc                 C   s
   || _ d S N)ring)r	   r"   r   r   r   __init__j      
zIdeal.__init__c                 C   s,   t |tr|j| jkrtd| j|f dS )z.Helper to check ``J`` is an ideal of our ring.z J must be an ideal of %s, got %sN)
isinstancer   r"   
ValueErrorr   r   r   r   _check_idealm   s
   zIdeal._check_idealc                 C   s   |  | j|S )aD  
        Return True if ``elem`` is an element of this ideal.

        Examples
        ========

        >>> from sympy.abc import x
        >>> from sympy import QQ
        >>> QQ.old_poly_ring(x).ideal(x+1, x-1).contains(3)
        True
        >>> QQ.old_poly_ring(x).ideal(x**2, x**3).contains(x)
        False
        )r   r"   convert)r	   elemr   r   r   containss   s   zIdeal.containsc                    s*   t |tr
 |S t fdd|D S )a  
        Returns True if ``other`` is is a subset of ``self``.

        Here ``other`` may be an ideal.

        Examples
        ========

        >>> from sympy.abc import x
        >>> from sympy import QQ
        >>> I = QQ.old_poly_ring(x).ideal(x+1)
        >>> I.subset([x**2 - 1, x**2 + 2*x + 1])
        True
        >>> I.subset([x**2 + 1, x + 1])
        False
        >>> I.subset(QQ.old_poly_ring(x).ideal(x**2 - 1))
        True
        c                 3   s    | ]}  |V  qd S r!   )r   .0r
   r   r   r   	<genexpr>   s    zIdeal.subset.<locals>.<genexpr>)r%   r   r   all)r	   otherr   r   r   subset   s   

zIdeal.subsetc                 K   s   |  | | j|fi |S )a~  
        Compute the ideal quotient of ``self`` by ``J``.

        That is, if ``self`` is the ideal `I`, compute the set
        `I : J = \{x \in R | xJ \subset I \}`.

        Examples
        ========

        >>> from sympy.abc import x, y
        >>> from sympy import QQ
        >>> R = QQ.old_poly_ring(x, y)
        >>> R.ideal(x*y).quotient(R.ideal(x))
        <y>
        )r'   r   r	   r   optsr   r   r   quotient   s   
zIdeal.quotientc                 C      |  | | |S )a  
        Compute the intersection of self with ideal J.

        Examples
        ========

        >>> from sympy.abc import x, y
        >>> from sympy import QQ
        >>> R = QQ.old_poly_ring(x, y)
        >>> R.ideal(x).intersect(R.ideal(y))
        <x*y>
        )r'   r   r   r   r   r   	intersect   s   

zIdeal.intersectc                 C   r   )z
        Compute the ideal saturation of ``self`` by ``J``.

        That is, if ``self`` is the ideal `I`, compute the set
        `I : J^\infty = \{x \in R | xJ^n \subset I \text{ for some } n\}`.
        r   r   r   r   r   saturate      zIdeal.saturatec                 C   r4   )aD  
        Compute the ideal generated by the union of ``self`` and ``J``.

        Examples
        ========

        >>> from sympy.abc import x
        >>> from sympy import QQ
        >>> QQ.old_poly_ring(x).ideal(x**2 - 1).union(QQ.old_poly_ring(x).ideal((x+1)**2)) == QQ.old_poly_ring(x).ideal(x+1)
        True
        )r'   _unionr   r   r   r   union   s   

zIdeal.unionc                 C   r4   )a  
        Compute the ideal product of ``self`` and ``J``.

        That is, compute the ideal generated by products `xy`, for `x` an element
        of ``self`` and `y \in J`.

        Examples
        ========

        >>> from sympy.abc import x, y
        >>> from sympy import QQ
        >>> QQ.old_poly_ring(x, y).ideal(x).product(QQ.old_poly_ring(x, y).ideal(y))
        <x*y>
        )r'   _productr   r   r   r   product   s   

zIdeal.productc                 C   s   |S )z
        Reduce the element ``x`` of our ring modulo the ideal ``self``.

        Here "reduce" has no specific meaning: it could return a unique normal
        form, simplify the expression a bit, or just do nothing.
        r   r   r   r   r   reduce_element   r7   zIdeal.reduce_elementc                 C   sZ   t |ts#| j| }t ||jr|S t ||jjr||S ||S | | | |S r!   )r%   r   r"   quotient_ringdtyper(   r'   r9   )r	   eRr   r   r   __add__   s   



zIdeal.__add__c                 C   sF   t |tsz| j|}W n ty   t Y S w | | | |S r!   )r%   r   r"   idealr   NotImplementedr'   r;   r	   r?   r   r   r   __mul__   s   


zIdeal.__mul__c                 C   s   | j dS N   )r"   rB   r   r   r   r   _zeroth_power	  s   zIdeal._zeroth_powerc                 C   s   | d S rF   r   r   r   r   r   _first_power  s   zIdeal._first_powerc                 C   s$   t |tr|j| jkrdS | |S )NF)r%   r   r"   r   rD   r   r   r   __eq__  s   
zIdeal.__eq__c                 C   s
   | |k S r!   r   rD   r   r   r   __ne__  r$   zIdeal.__ne__N)%__name__
__module____qualname____doc__r   r   r   r   r   r   r   r   r   r   r   r   r   r   r    r#   r'   r*   r0   r3   r5   r6   r9   r;   r<   rA   __radd__rE   __rmul__rH   rI   rJ   rK   r   r   r   r   r      sF    "
		r   c                   @   s|   e Zd ZdZ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 Zdd Zdd Zdd Zdd ZdS )ModuleImplementedIdealzs
    Ideal implementation relying on the modules code.

    Attributes:

    - _module - the underlying module
    c                 C   s   t | | || _d S r!   )r   r#   _module)r	   r"   moduler   r   r   r#   #  s   
zModuleImplementedIdeal.__init__c                 C      | j |gS r!   )rS   r*   r   r   r   r   r   '  s   z%ModuleImplementedIdeal._contains_elemc                 C   s   t |tst| j|jS r!   )r%   rR   r   rS   is_submoduler   r   r   r   r   *  s   
z&ModuleImplementedIdeal._contains_idealc                 C   &   t |tst| | j| j|jS r!   )r%   rR   r   	__class__r"   rS   r5   r   r   r   r   r   /     
z!ModuleImplementedIdeal._intersectc                 K   s$   t |tst| jj|jfi |S r!   )r%   rR   r   rS   module_quotientr1   r   r   r   r   4  s   
z ModuleImplementedIdeal._quotientc                 C   rW   r!   )r%   rR   r   rX   r"   rS   r9   r   r   r   r   r8   9  rY   zModuleImplementedIdeal._unionc                 C   s   dd | j jD S )aB  
        Return generators for ``self``.

        Examples
        ========

        >>> from sympy import QQ
        >>> from sympy.abc import x, y
        >>> list(QQ.old_poly_ring(x, y).ideal(x, y, x**2 + y).gens)
        [DMP_Python([[1], []], QQ), DMP_Python([[1, 0]], QQ), DMP_Python([[1], [], [1, 0]], QQ)]
        c                 s   s    | ]}|d  V  qdS )r   Nr   r+   r   r   r   r-   K      z.ModuleImplementedIdeal.gens.<locals>.<genexpr>rS   gensr   r   r   r   r]   >  s   zModuleImplementedIdeal.gensc                 C   
   | j  S )a%  
        Return True if ``self`` is the zero ideal.

        Examples
        ========

        >>> from sympy.abc import x
        >>> from sympy import QQ
        >>> QQ.old_poly_ring(x).ideal(x).is_zero()
        False
        >>> QQ.old_poly_ring(x).ideal().is_zero()
        True
        )rS   r   r   r   r   r   r   M  s   
zModuleImplementedIdeal.is_zeroc                 C   r^   )a  
        Return True if ``self`` is the whole ring, i.e. one generator is a unit.

        Examples
        ========

        >>> from sympy.abc import x
        >>> from sympy import QQ, ilex
        >>> QQ.old_poly_ring(x).ideal(x).is_whole_ring()
        False
        >>> QQ.old_poly_ring(x).ideal(3).is_whole_ring()
        True
        >>> QQ.old_poly_ring(x, order=ilex).ideal(2 + x).is_whole_ring()
        True
        )rS   is_full_moduler   r   r   r   r   ]  s   
z$ModuleImplementedIdeal.is_whole_ringc                    sB   ddl m  fdd jjD }ddfdd|D  d	 S )
Nr   sstrc                    s   g | ]	\} j |qS r   )r"   to_sympyr+   r   r   r   
<listcomp>q  s    z3ModuleImplementedIdeal.__repr__.<locals>.<listcomp><,c                 3   s    | ]} |V  qd S r!   r   )r,   gr`   r   r   r-   r  r[   z2ModuleImplementedIdeal.__repr__.<locals>.<genexpr>>)sympy.printing.strra   rS   r]   join)r	   r]   r   )r	   ra   r   __repr__o  s    zModuleImplementedIdeal.__repr__c                    s6   t  tst| | j| jj fdd| jjD  S )Nc                    s(   g | ]\} j jD ]\}|| gq	qS r   r\   )r,   r
   yr   r   r   rc   y  s   ( z3ModuleImplementedIdeal._product.<locals>.<listcomp>)r%   rR   r   rX   r"   rS   	submoduler]   r   r   rl   r   r:   u  s
   
zModuleImplementedIdeal._productc                 C   rU   )aX  
        Express ``e`` in terms of the generators of ``self``.

        Examples
        ========

        >>> from sympy.abc import x
        >>> from sympy import QQ
        >>> I = QQ.old_poly_ring(x).ideal(x**2 + 1, x)
        >>> I.in_terms_of_generators(1)  # doctest: +SKIP
        [DMP_Python([1], QQ), DMP_Python([-1, 0], QQ)]
        )rS   in_terms_of_generatorsrD   r   r   r   rn   {  s   z-ModuleImplementedIdeal.in_terms_of_generatorsc                 K   s   | j j|gfi |d S )Nr   )rS   r<   )r	   r
   optionsr   r   r   r<     s   z%ModuleImplementedIdeal.reduce_elementN)rL   rM   rN   rO   r#   r   r   r   r   r8   propertyr]   r   r   rj   r:   rn   r<   r   r   r   r   rR     s     
rR   N)rO   sympy.polys.polyerrorsr   sympy.polys.polyutilsr   r   rR   r   r   r   r   <module>   s      