
    sgA+                     L    d Z ddlmZ ddlmZ  G d de      Z G d de      Zy)	z-Computations with ideals of polynomial rings.    )CoercionFailed)IntegerPowerablec                       e Zd ZdZd Zd Zd Zd Zd Zd Z	d Z
d	 Zd
 Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd ZeZd ZeZ d Z!d Z"d Z#d  Z$y!)"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                     t         )z&Implementation of element containment.NotImplementedErrorselfxs     J/var/www/html/venv/lib/python3.12/site-packages/sympy/polys/agca/ideals.py_contains_elemzIdeal._contains_elem*       !!    c                     t         )z$Implementation of ideal containment.r   )r   Is     r   _contains_idealzIdeal._contains_ideal.   r   r   c                     t         )z!Implementation of ideal quotient.r   r   Js     r   	_quotientzIdeal._quotient2   r   r   c                     t         )z%Implementation of ideal intersection.r   r   s     r   
_intersectzIdeal._intersect6   r   r   c                     t         )z*Return True if ``self`` is the whole ring.r   r   s    r   is_whole_ringzIdeal.is_whole_ring:   r   r   c                     t         )z*Return True if ``self`` is the zero ideal.r   r   s    r   is_zerozIdeal.is_zero>   r   r   c                 J    | j                  |      xr |j                  |       S )z!Implementation of ideal equality.)r   r   s     r   _equalszIdeal._equalsB   s#    ##A&B1+<+<T+BBr   c                     t         )z)Return True if ``self`` is a prime ideal.r   r   s    r   is_primezIdeal.is_primeF   r   r   c                     t         )z+Return True if ``self`` is a maximal ideal.r   r   s    r   
is_maximalzIdeal.is_maximalJ   r   r   c                     t         )z+Return True if ``self`` is a radical ideal.r   r   s    r   
is_radicalzIdeal.is_radicalN   r   r   c                     t         )z+Return True if ``self`` is a primary ideal.r   r   s    r   
is_primaryzIdeal.is_primaryR   r   r   c                     t         )z-Return True if ``self`` is a principal ideal.r   r   s    r   is_principalzIdeal.is_principalV   r   r   c                     t         )z Compute the radical of ``self``.r   r   s    r   radicalzIdeal.radicalZ   r   r   c                     t         )zCompute the depth of ``self``.r   r   s    r   depthzIdeal.depth^   r   r   c                     t         )zCompute the height of ``self``.r   r   s    r   heightzIdeal.heightb   r   r   c                     || _         y N)ring)r   r3   s     r   __init__zIdeal.__init__j   s	    	r   c                     t        |t              r|j                  | j                  k7  rt        d| j                  d|      y)z.Helper to check ``J`` is an ideal of our ring.zJ must be an ideal of z, got N)
isinstancer   r3   
ValueErrorr   s     r   _check_idealzIdeal._check_idealm   s;    !U#qvv':6:iiCE E (;r   c                 V    | j                  | j                  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   r3   convert)r   elems     r   containszIdeal.containss   s$     ""499#4#4T#:;;r   c                 n     t        |t              r j                  |      S t         f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   @   K   | ]  }j                  |        y wr2   )r   ).0r   r   s     r   	<genexpr>zIdeal.subset.<locals>.<genexpr>   s     9a4&&q)9s   )r6   r   r   all)r   others   ` r   subsetzIdeal.subset   s1    & eU#''..95999r   c                 J    | j                  |        | 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>
        )r8   r   r   r   optss      r   quotientzIdeal.quotient   s(      	!t~~a(4((r   c                 F    | j                  |       | j                  |      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>
        )r8   r   r   s     r   	intersectzIdeal.intersect   s!     	!q!!r   c                     t         )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   s     r   saturatezIdeal.saturate   s
     "!r   c                 F    | j                  |       | j                  |      S )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
        )r8   _unionr   s     r   unionzIdeal.union   s      	!{{1~r   c                 F    | j                  |       | j                  |      S )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>
        )r8   _productr   s     r   productzIdeal.product   s!     	!}}Qr   c                     |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
   s     r   reduce_elementzIdeal.reduce_element   s	     r   c                 >   t        |t              sl| j                  j                  |       }t        ||j                        r|S t        ||j                  j                        r ||      S |j                  |      S | j                  |       | j                  |      S r2   )r6   r   r3   quotient_ringdtyper:   r8   rN   )r   eRs      r   __add__zIdeal.__add__   sx    !U#		''-A!QWW%!QVV\\*t99Q<!zz!}r   c                     t        |t              s	 | j                  j                  |      }| j                  |       | j                  |      S # t        $ r	 t
        cY S w xY wr2   )r6   r   r3   idealr   NotImplementedr8   rQ   r   rX   s     r   __mul__zIdeal.__mul__   sX    !U#&IIOOA& 	!||A " &%%&s   A A! A!c                 8    | j                   j                  d      S N   )r3   r\   r   s    r   _zeroth_powerzIdeal._zeroth_power	  s    yyq!!r   c                     | dz  S ra   rS   r   s    r   _first_powerzIdeal._first_power  s     axr   c                 x    t        |t              r|j                  | j                  k7  ry| j                  |      S )NF)r6   r   r3   r    r^   s     r   __eq__zIdeal.__eq__  s,    !U#qvv':||Ar   c                     | |k(   S r2   rS   r^   s     r   __ne__zIdeal.__ne__  s    AIr   N)%__name__
__module____qualname____doc__r   r   r   r   r   r   r    r"   r$   r&   r(   r*   r,   r.   r0   r4   r8   r<   rC   rG   rI   rK   rN   rQ   rT   rZ   __radd__r_   __rmul__rc   re   rg   ri   rS   r   r   r   r      s     D""""""C""""""""E< :.)&" " $	 H H"

r   r   c                   h    e Zd ZdZd Zd Zd Zd Zd Zd Z	e
d        Zd	 Zd
 Zd Zd Zd Zd Zy)ModuleImplementedIdealzs
    Ideal implementation relying on the modules code.

    Attributes:

    - _module - the underlying module
    c                 >    t         j                  | |       || _        y r2   )r   r4   _module)r   r3   modules      r   r4   zModuleImplementedIdeal.__init__#  s    tT"r   c                 :    | j                   j                  |g      S r2   )rs   r<   r
   s     r   r   z%ModuleImplementedIdeal._contains_elem'  s    ||$$aS))r   c                 x    t        |t              st        | j                  j	                  |j                        S r2   )r6   rq   r	   rs   is_submoduler   s     r   r   z&ModuleImplementedIdeal._contains_ideal*  s,    !34%%||((33r   c                     t        |t              st        | j                  | j                  | j
                  j                  |j
                              S r2   )r6   rq   r	   	__class__r3   rs   rI   r   s     r   r   z!ModuleImplementedIdeal._intersect/  s;    !34%%~~dii)?)?		)JKKr   c                 |    t        |t              st         | j                  j                  |j                  fi |S r2   )r6   rq   r	   rs   module_quotientrE   s      r   r   z ModuleImplementedIdeal._quotient4  s3    !34%%+t||++AII>>>r   c                     t        |t              st        | j                  | j                  | j
                  j                  |j
                              S r2   )r6   rq   r	   ry   r3   rs   rN   r   s     r   rM   zModuleImplementedIdeal._union9  s;    !34%%~~dii););AII)FGGr   c                 <    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              3   &   K   | ]	  }|d      yw)r   NrS   )r?   r   s     r   r@   z.ModuleImplementedIdeal.gens.<locals>.<genexpr>K  s     0!0s   )rs   gensr   s    r   r   zModuleImplementedIdeal.gens>  s     1dll//00r   c                 6    | j                   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   s    r   r   zModuleImplementedIdeal.is_zeroM  s     ||##%%r   c                 6    | j                   j                         S )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   s    r   r   z$ModuleImplementedIdeal.is_whole_ring]  s      ||**,,r   c                     ddl m | j                  j                  D cg c]  \  }| j                  j                  |      ! }}ddj                  fd|D              z   dz   S c c}w )Nr   )sstr<,c              3   .   K   | ]  } |        y wr2   rS   )r?   gr   s     r   r@   z2ModuleImplementedIdeal.__repr__.<locals>.<genexpr>r  s     4!d1g4s   >)sympy.printing.strr   rs   r   r3   to_sympyjoin)r   r   r   r   s      @r   __repr__zModuleImplementedIdeal.__repr__o  sY    +151B1BC#1		""1%CCSXX4t444s:: Ds   $A&c                 .   t        |t              st        | j                  | j                   | j
                  j                  | j
                  j                  D cg c]'  \  }|j
                  j                  D ]
  \  }||z  g ) c}}       S c c}}w r2   )r6   rq   r	   ry   r3   rs   	submoduler   )r   r   r   ys       r   rP   zModuleImplementedIdeal._productu  sz    !34%%~~dii)?)?)?#||00KAIINNKSaqseKeK*M N 	NKs   ,Bc                 :    | j                   j                  |g      S )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_generatorsr^   s     r   r   z-ModuleImplementedIdeal.in_terms_of_generators{  s     ||22A377r   c                 D     | j                   j                  |gfi |d   S )Nr   )rs   rT   )r   r   optionss      r   rT   z%ModuleImplementedIdeal.reduce_element  s%    *t||**A3:':1==r   N)rj   rk   rl   rm   r4   r   r   r   r   rM   propertyr   r   r   r   rP   r   rT   rS   r   r   rq   rq     sZ    *4
L
?
H
 1 1& -$;N8>r   rq   N)rm   sympy.polys.polyerrorsr   sympy.polys.polyutilsr   r   rq   rS   r   r   <module>r      s,    3 1 2P Pfq>U q>r   