B
    ˜‘[)  ã               @   sP   d Z ddlmZm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.é    )Úprint_functionÚdivision)ÚCoercionFailed)Úreducec               @   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>S )?Ú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   s   t ‚dS )z&Implementation of element containment.N)ÚNotImplementedError)ÚselfÚx© r
   ú6lib/python3.7/site-packages/sympy/polys/agca/ideals.pyÚ_contains_elem-   s    zIdeal._contains_elemc             C   s   t ‚dS )z$Implementation of ideal containment.N)r   )r   ÚIr
   r
   r   Ú_contains_ideal1   s    zIdeal._contains_idealc             C   s   t ‚dS )z!Implementation of ideal quotient.N)r   )r   ÚJr
   r
   r   Ú	_quotient5   s    zIdeal._quotientc             C   s   t ‚dS )z%Implementation of ideal intersection.N)r   )r   r   r
   r
   r   Ú
_intersect9   s    zIdeal._intersectc             C   s   t ‚dS )z*Return True if ``self`` is the whole ring.N)r   )r   r
   r
   r   Úis_whole_ring=   s    zIdeal.is_whole_ringc             C   s   t ‚dS )z*Return True if ``self`` is the zero ideal.N)r   )r   r
   r
   r   Úis_zeroA   s    zIdeal.is_zeroc             C   s   |   |¡o|  | ¡S )z!Implementation of ideal equality.)r   )r   r   r
   r
   r   Ú_equalsE   s    zIdeal._equalsc             C   s   t ‚dS )z)Return True if ``self`` is a prime ideal.N)r   )r   r
   r
   r   Úis_primeI   s    zIdeal.is_primec             C   s   t ‚dS )z+Return True if ``self`` is a maximal ideal.N)r   )r   r
   r
   r   Ú
is_maximalM   s    zIdeal.is_maximalc             C   s   t ‚dS )z+Return True if ``self`` is a radical ideal.N)r   )r   r
   r
   r   Ú
is_radicalQ   s    zIdeal.is_radicalc             C   s   t ‚dS )z+Return True if ``self`` is a primary ideal.N)r   )r   r
   r
   r   Ú
is_primaryU   s    zIdeal.is_primaryc             C   s   t ‚dS )z-Return True if ``self`` is a principal ideal.N)r   )r   r
   r
   r   Úis_principalY   s    zIdeal.is_principalc             C   s   t ‚dS )z Compute the radical of ``self``.N)r   )r   r
   r
   r   Úradical]   s    zIdeal.radicalc             C   s   t ‚dS )zCompute the depth of ``self``.N)r   )r   r
   r
   r   Údeptha   s    zIdeal.depthc             C   s   t ‚dS )zCompute the height of ``self``.N)r   )r   r
   r
   r   Úheighte   s    zIdeal.heightc             C   s
   || _ d S )N)Úring)r   r   r
   r
   r   Ú__init__m   s    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   Ú
ValueError)r   r   r
   r
   r   Ú_check_idealp   s    zIdeal._check_idealc             C   s   |   | j |¡¡S )a!  
        Return True if ``elem`` is an element of this ideal.

        >>> 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   Úcontainsv   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.

        >>> 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 )N)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|Ž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 \}`.

        >>> 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   |   |¡ |  |¡S )zë
        Compute the intersection of self with ideal J.

        >>> 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
   r   Ú	intersect§   s    

zIdeal.intersectc             C   s   t ‚dS )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\}`.
        N)r   )r   r   r
   r
   r   Úsaturate´   s    zIdeal.saturatec             C   s   |   |¡ |  |¡S )a!  
        Compute the ideal generated by the union of ``self`` and ``J``.

        >>> 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!   Ú_union)r   r   r
   r
   r   Úunion¾   s    	
zIdeal.unionc             C   s   |   |¡ |  |¡S )ad  
        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`.

        >>> 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!   Ú_product)r   r   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
   r   Úreduce_elementÙ   s    zIdeal.reduce_elementc             C   sZ   t |tƒsF| j | ¡}t ||jƒr&|S t ||jjƒr<||ƒS | |¡S |  |¡ |  |¡S )N)r   r   r   Zquotient_ringZdtyper"   r!   r/   )r   ÚeÚRr
   r
   r   Ú__add__â   s    


zIdeal.__add__c             C   sD   t |tƒs0y| j |¡}W n tk
r.   tS X |  |¡ |  |¡S )N)r   r   r   Úidealr   ÚNotImplementedr!   r1   )r   r3   r
   r
   r   Ú__mul__ï   s    

zIdeal.__mul__c             C   s*   |dk rt ‚tdd„ | g| | j d¡ƒS )Nr   c             S   s   | | S )Nr
   )r	   Úyr
   r
   r   Ú<lambda>þ   s    zIdeal.__pow__.<locals>.<lambda>é   )r   r   r   r6   )r   Zexpr
   r
   r   Ú__pow__ú   s    zIdeal.__pow__c             C   s$   t |tƒr|j| jkrdS |  |¡S )NF)r   r   r   r   )r   r3   r
   r
   r   Ú__eq__   s    zIdeal.__eq__c             C   s
   | |k S )Nr
   )r   r3   r
   r
   r   Ú__ne__  s    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$   r)   r+   r,   r-   r/   r1   r2   r5   Ú__radd__r8   Ú__rmul__r<   r=   r>   r
   r
   r
   r   r   
   sB   !
		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 )N)r   r   Ú_module)r   r   Úmoduler
   r
   r   r     s    zModuleImplementedIdeal.__init__c             C   s   | j  |g¡S )N)rF   r$   )r   r	   r
   r
   r   r     s    z%ModuleImplementedIdeal._contains_elemc             C   s   t |tƒst‚| j |j¡S )N)r   rE   r   rF   Zis_submodule)r   r   r
   r
   r   r     s    
z&ModuleImplementedIdeal._contains_idealc             C   s&   t |tƒst‚|  | j| j |j¡¡S )N)r   rE   r   Ú	__class__r   rF   r,   )r   r   r
   r
   r   r     s    
z!ModuleImplementedIdeal._intersectc             K   s    t |tƒst‚| jj|jf|ŽS )N)r   rE   r   rF   Zmodule_quotient)r   r   r*   r
   r
   r   r   #  s    
z ModuleImplementedIdeal._quotientc             C   s&   t |tƒst‚|  | j| j |j¡¡S )N)r   rE   r   rH   r   rF   r/   )r   r   r
   r
   r   r.   (  s    
zModuleImplementedIdeal._unionc             C   s   dd„ | j jD ƒS )z×
        Return generators for ``self``.

        >>> from sympy import QQ
        >>> from sympy.abc import x, y
        >>> list(QQ.old_poly_ring(x, y).ideal(x, y, x**2 + y).gens)
        [x, y, x**2 + y]
        c             s   s   | ]}|d  V  qdS )r   Nr
   )r%   r	   r
   r
   r   r&   7  s    z.ModuleImplementedIdeal.gens.<locals>.<genexpr>)rF   Úgens)r   r
   r
   r   rI   -  s    
zModuleImplementedIdeal.gensc             C   s
   | j  ¡ S )a  
        Return True if ``self`` is the zero ideal.

        >>> 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
        )rF   r   )r   r
   r
   r   r   9  s    zModuleImplementedIdeal.is_zeroc             C   s
   | j  ¡ S )a‰  
        Return True if ``self`` is the whole ring, i.e. one generator is a unit.

        >>> 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
        )rF   Zis_full_module)r   r
   r
   r   r   F  s    z$ModuleImplementedIdeal.is_whole_ringc                s0   ddl m‰  dd ‡ fdd„| jjD ƒ¡ d S )Nr   )Ússtrú<ú,c             3   s   | ]\}ˆ |ƒV  qd S )Nr
   )r%   r	   )rJ   r
   r   r&   W  s    z2ModuleImplementedIdeal.__repr__.<locals>.<genexpr>ú>)ZsympyrJ   ÚjoinrF   rI   )r   r
   )rJ   r   Ú__repr__U  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
   )rF   rI   )r%   r	   r9   )r   r
   r   ú
<listcomp>^  s    z3ModuleImplementedIdeal._product.<locals>.<listcomp>)r   rE   r   rH   r   rF   Z	submodulerI   )r   r   r
   )r   r   r0   Z  s    
zModuleImplementedIdeal._productc             C   s   | j  |g¡S )zü
        Express ``e`` in terms of the generators of ``self``.

        >>> 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)
        [1, -x]
        )rF   Úin_terms_of_generators)r   r3   r
   r
   r   rQ   `  s    
z-ModuleImplementedIdeal.in_terms_of_generatorsc             K   s   | j j|gf|Žd S )Nr   )rF   r2   )r   r	   Zoptionsr
   r
   r   r2   l  s    z%ModuleImplementedIdeal.reduce_elementN)r?   r@   rA   rB   r   r   r   r   r   r.   ÚpropertyrI   r   r   rO   r0   rQ   r2   r
   r
   r
   r   rE   	  s   rE   N)rB   Z
__future__r   r   Zsympy.polys.polyerrorsr   Zsympy.core.compatibilityr   Úobjectr   rE   r
   r
   r
   r   Ú<module>   s     