o
    jgn>                     @   s   d Z ddlmZ ddlmZ ddlmZ ddlmZ ddl	m
Z
mZ ddlmZmZ ddlmZmZmZmZmZ dd	lmZmZmZ dd
lmZ ddlmZ eG dd deeZdd ZeG dd deZG dd deZ edd Z!dS )z1Implementation of :class:`PolynomialRing` class.     FreeModulePolyRing)CompositeDomain)FractionField)Ring)monomial_keybuild_product_order)DMPDMF)GeneratorsNeededPolynomialErrorCoercionFailedExactQuotientFailedNotReversible)dict_from_basicbasic_from_dict_dict_reorder)public)iterablec                   @   s  e Zd ZdZd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d0d1 Zd2d3 Zd4d5 Zd6d7 Z d8d9 Z!d:d; Z"d<d= Z#d>d? Z$d@S )APolynomialRingBasez
    Base class for generalized polynomial rings.

    This base class should be used for uniform access to generalized polynomial
    rings. Subclasses only supply information about the element storage etc.

    Do not instantiate.
    Tgrevlexc                 O   sr   |st dt|d }t|| _| j||| _| j||| _| | _| _| | _| _	|
dt| j| _d S )Nzgenerators not specified   order)r   lenngensdtypezeroonedomaindomsymbolsgensgetr   default_orderr   )selfr   r!   optslev r'   ^/var/www/html/zoom/venv/lib/python3.10/site-packages/sympy/polys/domains/old_polynomialring.py__init__!   s   
zPolynomialRingBase.__init__c                 C   s   | j |g| jR d| jiS )z0Return a new polynomial ring with given domain. r   )	__class__r!   r   )r$   r   r'   r'   r(   
set_domain0   s   zPolynomialRingBase.set_domainc                 C   s   |  || jt| jd S Nr   )r   r   r   r!   r$   elementr'   r'   r(   new4      zPolynomialRingBase.newc                 C   s   | j |S N)r   
ground_newr-   r'   r'   r(   _ground_new7   s   zPolynomialRingBase._ground_newc                 C   s   t |t| jd | jS r,   )r	   	from_dictr   r!   r   r-   r'   r'   r(   
_from_dict:   r0   zPolynomialRingBase._from_dictc                 C   sH   t | j}|| jkrd| nd}t | jd dtt | j | d S )Nz order= [,])strr   r#   r   joinmapr!   )r$   s_orderorderstrr'   r'   r(   __str__=   s   
(zPolynomialRingBase.__str__c                 C   s   t | jj| j| j| j| jfS r1   )hashr*   __name__r   r   r!   r   r$   r'   r'   r(   __hash__C   s   zPolynomialRingBase.__hash__c                 C   s:   t |to| j|jko| j|jko| j|jko| j|jkS )z0Returns ``True`` if two domains are equivalent. )
isinstancer   r   r   r!   r   )r$   otherr'   r'   r(   __eq__G   s   




zPolynomialRingBase.__eq__c                 C      |  | j||S z.Convert a Python ``int`` object to ``dtype``. r3   r   convertK1aK0r'   r'   r(   from_ZZM      zPolynomialRingBase.from_ZZc                 C   rG   rH   rI   rK   r'   r'   r(   from_ZZ_pythonQ   rP   z!PolynomialRingBase.from_ZZ_pythonc                 C   rG   z3Convert a Python ``Fraction`` object to ``dtype``. rI   rK   r'   r'   r(   from_QQU   rP   zPolynomialRingBase.from_QQc                 C   rG   rR   rI   rK   r'   r'   r(   from_QQ_pythonY   rP   z!PolynomialRingBase.from_QQ_pythonc                 C   rG   )z,Convert a GMPY ``mpz`` object to ``dtype``. rI   rK   r'   r'   r(   from_ZZ_gmpy]   rP   zPolynomialRingBase.from_ZZ_gmpyc                 C   rG   )z,Convert a GMPY ``mpq`` object to ``dtype``. rI   rK   r'   r'   r(   from_QQ_gmpya   rP   zPolynomialRingBase.from_QQ_gmpyc                 C   rG   )z.Convert a mpmath ``mpf`` object to ``dtype``. rI   rK   r'   r'   r(   from_RealFielde   rP   z!PolynomialRingBase.from_RealFieldc                 C   s   | j |kr
| |S dS )z'Convert a ``ANP`` object to ``dtype``. N)r   r3   rK   r'   r'   r(   from_AlgebraicFieldi   s   

z&PolynomialRingBase.from_AlgebraicFieldc                    s   j  jkr'j jkrt|S  fddfdd| D S t|  jj \}}j jkrC fdd|D }tt||S )z/Convert a ``PolyElement`` object to ``dtype``. c                    s   j |  j S r1   )r   convert_from)crN   rL   r'   r(   <lambda>t       z8PolynomialRingBase.from_PolynomialRing.<locals>.<lambda>c                    s   i | ]	\}}| |qS r'   r'   ).0mrZ   )convert_domr'   r(   
<dictcomp>u   s    z:PolynomialRingBase.from_PolynomialRing.<locals>.<dictcomp>c                       g | ]
}j | j qS r'   r   rJ   r^   rZ   r[   r'   r(   
<listcomp>z       z:PolynomialRingBase.from_PolynomialRing.<locals>.<listcomp>)	r!   r    r   dictr5   itemsr   to_dictziprL   rM   rN   monomscoeffsr'   )rN   rL   r`   r(   from_PolynomialRingn   s   z&PolynomialRingBase.from_PolynomialRingc                    sz   j  j krj jkr|j}| S t|  j j \}}j jkr4 fdd|D }tt||S )z'Convert a ``DMP`` object to ``dtype``. c                    rb   r'   rc   rd   r[   r'   r(   re      rf   z@PolynomialRingBase.from_GlobalPolynomialRing.<locals>.<listcomp>)r!   r   rJ   to_listr   ri   rg   rj   rk   r'   r[   r(   from_GlobalPolynomialRing~   s   z,PolynomialRingBase.from_GlobalPolynomialRingc                 C   s   t | jg| jR  S )z*Returns a field associated with ``self``. )r   r   r!   rB   r'   r'   r(   	get_field   rP   zPolynomialRingBase.get_fieldc                 G      t d)z*Returns a polynomial ring, i.e. ``K[X]``. nested domains not allowedNotImplementedErrorr$   r!   r'   r'   r(   	poly_ring      zPolynomialRingBase.poly_ringc                 G   rr   )z)Returns a fraction field, i.e. ``K(X)``. rs   rt   rv   r'   r'   r(   
frac_field   rx   zPolynomialRingBase.frac_fieldc              	   C   s0   z|  | j|W S  ttfy   td| w )Nz%s is not a unit)exquor   r   ZeroDivisionErrorr   r$   rM   r'   r'   r(   revert   s
   zPolynomialRingBase.revertc                 C   
   | |S )z!Extended GCD of ``a`` and ``b``. )gcdexr$   rM   br'   r'   r(   r         
zPolynomialRingBase.gcdexc                 C   r~   )z Returns GCD of ``a`` and ``b``. )gcdr   r'   r'   r(   r      r   zPolynomialRingBase.gcdc                 C   r~   )z Returns LCM of ``a`` and ``b``. )lcmr   r'   r'   r(   r      r   zPolynomialRingBase.lcmc                 C   s   |  | j|S )zReturns factorial of ``a``. )r   r   	factorialr|   r'   r'   r(   r      s   zPolynomialRingBase.factorialc                 C   s   t )z
        For internal use by the modules class.

        Convert an iterable of elements of this ring into a sparse distributed
        module element.
        rt   r$   vr   r'   r'   r(   _vector_to_sdm   s   z!PolynomialRingBase._vector_to_sdmc                 C   sT   ddl m} ||}dd t|D }| D ]\}}|||d  |dd < q|S )zHelper for _sdm_to_vector.r   )sdm_to_dictc                 S   s   g | ]}i qS r'   r'   )r^   _r'   r'   r(   re      r]   z3PolynomialRingBase._sdm_to_dics.<locals>.<listcomp>r   N)sympy.polys.distributedmodulesr   rangerh   )r$   snr   dicreskr   r'   r'   r(   _sdm_to_dics   s   zPolynomialRingBase._sdm_to_dicsc                    s     ||} fdd|D S )a  
        For internal use by the modules class.

        Convert a sparse distributed module into a list of length ``n``.

        Examples
        ========

        >>> from sympy import QQ, ilex
        >>> from sympy.abc import x, y
        >>> R = QQ.old_poly_ring(x, y, order=ilex)
        >>> L = [((1, 1, 1), QQ(1)), ((0, 1, 0), QQ(1)), ((0, 0, 1), QQ(2))]
        >>> R._sdm_to_vector(L, 2)
        [DMF([[1], [2, 0]], [[1]], QQ), DMF([[1, 0], []], [[1]], QQ)]
        c                    s   g | ]} |qS r'   r'   r^   xrB   r'   r(   re      s    z5PolynomialRingBase._sdm_to_vector.<locals>.<listcomp>)r   )r$   r   r   dicsr'   rB   r(   _sdm_to_vector   s   z!PolynomialRingBase._sdm_to_vectorc                 C   s
   t | |S )z
        Generate a free module of rank ``rank`` over ``self``.

        Examples
        ========

        >>> from sympy.abc import x
        >>> from sympy import QQ
        >>> QQ.old_poly_ring(x).free_module(2)
        QQ[x]**2
        r   )r$   rankr'   r'   r(   free_module   s   
zPolynomialRingBase.free_moduleN)%rA   
__module____qualname____doc__has_assoc_Ringhas_assoc_Fieldr#   r)   r+   r/   r3   r5   r?   rC   rF   rO   rQ   rS   rT   rU   rV   rW   rX   rn   rp   rq   rw   ry   r}   r   r   r   r   r   r   r   r   r'   r'   r'   r(   r      sF    			r   c                 C   sP   ddl m} i }t| D ]\}}|  D ]\}}|||f| < qq|||S )z=Helper method for common code in Global and Local poly rings.r   )sdm_from_dict)r   r   	enumerateri   rh   )r   r   r   diekeyvaluer'   r'   r(   _vector_to_sdm_helper   s   
r   c                   @   sd   e Zd ZdZd Z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d ZdS )GlobalPolynomialRingz*A true polynomial ring, with objects DMP. Tc                 C   sZ   t |trt|t| jd | jS || jv r | | j|S | 	|| jt| jd S r,   )
rD   rg   r	   r4   r   r!   r   r3   rJ   r   r-   r'   r'   r(   r/      s
   

zGlobalPolynomialRing.newc                 C   s   |  jr| | |S dS )a  
        Convert a ``DMF`` object to ``DMP``.

        Examples
        ========

        >>> from sympy.polys.polyclasses import DMP, DMF
        >>> from sympy.polys.domains import ZZ
        >>> from sympy.abc import x

        >>> f = DMF(([ZZ(1), ZZ(1)], [ZZ(1)]), ZZ)
        >>> K = ZZ.old_frac_field(x)

        >>> F = ZZ.old_poly_ring(x).from_FractionField(f, K)

        >>> F == DMP([ZZ(1), ZZ(1)], ZZ)
        True
        >>> type(F)  # doctest: +SKIP
        <class 'sympy.polys.polyclasses.DMP_Python'>

        N)denomis_onerp   numerrK   r'   r'   r(   from_FractionField   s   
z'GlobalPolynomialRing.from_FractionFieldc                 C   s   t | g| jR  S z!Convert ``a`` to a SymPy object. )r   to_sympy_dictr!   r|   r'   r'   r(   to_sympy  s   zGlobalPolynomialRing.to_sympyc                 C   sn   zt || jd\}}W n ty   td|| f w | D ]\}}| j|||< qt|| j	d | jS ))Convert SymPy's expression to ``dtype``. r!   zCannot convert %s to type %sr   )
r   r!   r   r   rh   r   
from_sympyr	   r4   r   )r$   rM   repr   r   r   r'   r'   r(   r     s   zGlobalPolynomialRing.from_sympyc                 C      | j | S )z'Returns True if ``LC(a)`` is positive. )r   is_positiveLCr|   r'   r'   r(   r   %     z GlobalPolynomialRing.is_positivec                 C   r   )z'Returns True if ``LC(a)`` is negative. )r   is_negativer   r|   r'   r'   r(   r   )  r   z GlobalPolynomialRing.is_negativec                 C   r   )z+Returns True if ``LC(a)`` is non-positive. )r   is_nonpositiver   r|   r'   r'   r(   r   -  r   z#GlobalPolynomialRing.is_nonpositivec                 C   r   )z+Returns True if ``LC(a)`` is non-negative. )r   is_nonnegativer   r|   r'   r'   r(   r   1  r   z#GlobalPolynomialRing.is_nonnegativec                 C   s
   t ||S )aG  
        Examples
        ========

        >>> from sympy import lex, QQ
        >>> from sympy.abc import x, y
        >>> R = QQ.old_poly_ring(x, y)
        >>> f = R.convert(x + 2*y)
        >>> g = R.convert(x * y)
        >>> R._vector_to_sdm([f, g], lex)
        [((1, 1, 1), 1), ((0, 1, 0), 1), ((0, 0, 1), 2)]
        )r   r   r'   r'   r(   r   5  s   
z#GlobalPolynomialRing._vector_to_sdmN)rA   r   r   r   is_PolynomialRingis_Polyr	   r   r/   r   r   r   r   r   r   r   r   r'   r'   r'   r(   r      s    r   c                   @   sL   e 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dd ZdS )GeneralizedPolynomialRingz1A generalized polynomial ring, with objects DMF. c                 C   sf   |  || jt| jd }| j| jdd d dt| j kr1ddlm} t	d||| f |S )z4Construct an element of ``self`` domain from ``a``. r   r   r   r   )sstrz denominator %s not allowed in %s)
r   r   r   r!   r   termsr   sympy.printing.strr   r   )r$   rM   r   r   r'   r'   r(   r/   J  s   (
zGeneralizedPolynomialRing.newc                 C   sL   z|  |}W n
 ty   Y dS w | j| jdd d dt| j kS )NFr   r   r   )rJ   r   r   r   r   r   r!   r|   r'   r'   r(   __contains__U  s   (z&GeneralizedPolynomialRing.__contains__c                 C   s4   t |  g| jR  t |  g| jR   S r   )r   r   r   r!   r   r|   r'   r'   r(   r   \  s   z"GeneralizedPolynomialRing.to_sympyc           	      C   s   |  \}}t|| jd\}}t|| jd\}}| D ]\}}| j|||< q| D ]\}}| j|||< q-| ||f S )r   r   )as_numer_denomr   r!   rh   r   r   cancel)	r$   rM   pqnumr   denr   r   r'   r'   r(   r   a  s   z$GeneralizedPolynomialRing.from_sympyc                 C   s<   || }z|  |j|jf}W |S  ty   t||| w )z#Exact quotient of ``a`` and ``b``. )r/   r   r   r   r   )r$   rM   r   rr'   r'   r(   rz   p  s   zGeneralizedPolynomialRing.exquoc                 C   s    |   ||}| |j|jfS r1   )rq   r   r   r   )rL   rM   rN   dmfr'   r'   r(   r   }  s   z,GeneralizedPolynomialRing.from_FractionFieldc                    s8   | j   |D ]} | 9  qt fdd|D |S )a  
        Turn an iterable into a sparse distributed module.

        Note that the vector is multiplied by a unit first to make all entries
        polynomials.

        Examples
        ========

        >>> from sympy import ilex, QQ
        >>> from sympy.abc import x, y
        >>> R = QQ.old_poly_ring(x, y, order=ilex)
        >>> f = R.convert((x + 2*y) / (1 + x))
        >>> g = R.convert(x * y)
        >>> R._vector_to_sdm([f, g], ilex)
        [((0, 0, 1), 2), ((0, 1, 0), 1), ((1, 1, 1), 1), ((1,
          2, 1), 1)]
        c                    s    g | ]}|    |  qS r'   )r   r   r   ur'   r(   re     s     z<GeneralizedPolynomialRing._vector_to_sdm.<locals>.<listcomp>)r   r   r   r   )r$   r   r   r   r'   r   r(   r     s   
z(GeneralizedPolynomialRing._vector_to_sdmN)rA   r   r   r   r
   r   r/   r   r   r   rz   r   r   r'   r'   r'   r(   r   E  s    r   c                 O   sb   | dtj}t|rt||}t|}||d< |jr&t| g|R i |S t| g|R i |S )ay  
    Create a generalized multivariate polynomial ring.

    A generalized polynomial ring is defined by a ground field `K`, a set
    of generators (typically `x_1, \ldots, x_n`) and a monomial order `<`.
    The monomial order can be global, local or mixed. In any case it induces
    a total ordering on the monomials, and there exists for every (non-zero)
    polynomial `f \in K[x_1, \ldots, x_n]` a well-defined "leading monomial"
    `LM(f) = LM(f, >)`. One can then define a multiplicative subset
    `S = S_> = \{f \in K[x_1, \ldots, x_n] | LM(f) = 1\}`. The generalized
    polynomial ring corresponding to the monomial order is
    `R = S^{-1}K[x_1, \ldots, x_n]`.

    If `>` is a so-called global order, that is `1` is the smallest monomial,
    then we just have `S = K` and `R = K[x_1, \ldots, x_n]`.

    Examples
    ========

    A few examples may make this clearer.

    >>> from sympy.abc import x, y
    >>> from sympy import QQ

    Our first ring uses global lexicographic order.

    >>> R1 = QQ.old_poly_ring(x, y, order=(("lex", x, y),))

    The second ring uses local lexicographic order. Note that when using a
    single (non-product) order, you can just specify the name and omit the
    variables:

    >>> R2 = QQ.old_poly_ring(x, y, order="ilex")

    The third and fourth rings use a mixed orders:

    >>> o1 = (("ilex", x), ("lex", y))
    >>> o2 = (("lex", x), ("ilex", y))
    >>> R3 = QQ.old_poly_ring(x, y, order=o1)
    >>> R4 = QQ.old_poly_ring(x, y, order=o2)

    We will investigate what elements of `K(x, y)` are contained in the various
    rings.

    >>> L = [x, 1/x, y/(1 + x), 1/(1 + y), 1/(1 + x*y)]
    >>> test = lambda R: [f in R for f in L]

    The first ring is just `K[x, y]`:

    >>> test(R1)
    [True, False, False, False, False]

    The second ring is R1 localised at the maximal ideal (x, y):

    >>> test(R2)
    [True, False, True, True, True]

    The third ring is R1 localised at the prime ideal (x):

    >>> test(R3)
    [True, False, True, False, True]

    Finally the fourth ring is R1 localised at `S = K[x, y] \setminus yK[y]`:

    >>> test(R4)
    [True, False, False, True, False]
    r   )r"   r   r#   r   r   r   	is_globalr   )r   r!   r%   r   r'   r'   r(   PolynomialRing  s   F
r   N)"r   sympy.polys.agca.modulesr   #sympy.polys.domains.compositedomainr   %sympy.polys.domains.old_fractionfieldr   sympy.polys.domains.ringr   sympy.polys.orderingsr   r   sympy.polys.polyclassesr	   r
   sympy.polys.polyerrorsr   r   r   r   r   sympy.polys.polyutilsr   r   r   sympy.utilitiesr   sympy.utilities.iterablesr   r   r   r   r   r   r'   r'   r'   r(   <module>   s(     R
WV