
    wg                         d dl mZ d dlmZmZmZ d dlmZ d dlm	Z	m
Z
mZmZmZ d dlmZmZ d dlmZmZ d dlmZmZ d Zd	d
ddZy)    )combinations_with_replacement)symbolsAddDummy)Rational)cancelComputationFailedparallel_poly_from_exprreducedPoly)Monomialmonomial_div)DomainErrorPolificationFailed)debugdebugfc                     t        |       j                         \  }}	 t        ||gdd      \  }}t	        | t        ||z        z   S # t        $ r ||z  cY S w xY w)z
    Put an expression over a common denominator, cancel and reduce.

    Examples
    ========

    >>> from sympy import ratsimp
    >>> from sympy.abc import x, y
    >>> ratsimp(1/x + 1/y)
    (x + y)/(x*y)
    TF)fieldexpand)r   as_numer_denomr   r	   r   )exprfgQrs        [/home/mcse/projects/flask/flask-venv/lib/python3.12/site-packages/sympy/simplify/ratsimp.pyratsimpr   	   sh     $<&&(DAqq1#T%81 7VAaC[    s
s   A AATF)quick
polynomialc                   ddl m t        d|        t        |       j	                         \  }}	 t        ||gz   g|i |\  }j                  }	|	j                  r|	j                         _        nt        d|	z        |dd D 
cg c]  }
|
j                  j                         c}
t               fddfd	t        |j                  j                  	      d
   }t        |j                  j                  	      d
   }|r||z  j                         S  t!        |j                  j                        t!        |j                  j                        g       \  }}}ss|rqt#        dt%        |             g }|D ]D  \  }}}} ||dd      }|j'                  |j)                  |      |j)                  |      f       F t+        |d       \  }}|	j,                  s7|j/                  d      \  }}|j/                  d      \  }}t1        ||      }nt1        d
      }||j2                  z  ||j4                  z  z  S # t        $ r | cY S w xY wc c}
w )a  
    Simplifies a rational expression ``expr`` modulo the prime ideal
    generated by ``G``.  ``G`` should be a Groebner basis of the
    ideal.

    Examples
    ========

    >>> from sympy.simplify.ratsimp import ratsimpmodprime
    >>> from sympy.abc import x, y
    >>> eq = (x + y**5 + y)/(x - y)
    >>> ratsimpmodprime(eq, [x*y**5 - x - y], x, y, order='lex')
    (-x**2 - x*y - x - y)/(-x**2 + x*y)

    If ``polynomial`` is ``False``, the algorithm computes a rational
    simplification which minimizes the sum of the total degrees of
    the numerator and the denominator.

    If ``polynomial`` is ``True``, this function just brings numerator and
    denominator into a canonical form. This is much faster, but has
    potentially worse results.

    References
    ==========

    .. [1] M. Monagan, R. Pearce, Rational Simplification Modulo a Polynomial
        Ideal, https://dl.acm.org/doi/pdf/10.1145/1145768.1145809
        (specifically, the second algorithm)
    r   )solveratsimpmodprimez.Cannot compute rational simplification over %s   Nc                    | dk(  rdgS g }t        t        t        j                              |       D ]U  }dgt        j                        z  |D ]  }|xx   dz  cc<    t	        fdD              sE|j                         W |D cg c]$  } t        |      j                  j                   & c} | dz
        z   S c c}w )z
        Compute all monomials with degree less than ``n`` that are
        not divisible by any element of ``leading_monomials``.
        r      c              3   :   K   | ]  }t        |      d u   y wN)r   ).0lmgms     r   	<genexpr>z5ratsimpmodprime.<locals>.staircase.<locals>.<genexpr>b   s!      &C<3'4/ &s   )r   rangelengensallappendr   as_expr)	nSmiisr*   leading_monomialsopt	staircases	        @r   r9   z"ratsimpmodprime.<locals>.staircaseV   s    
 63J/c#((m0DaH 	BCM!A !	 &$& &	 9::1###SXX.:Yq1u=MMM:s   )C	c                 B   | |}}d}| j                         |j                         z   }r|dz
  }	n|}	||z   |	k  r||fv rnj                  ||f        |       |      t        d||f       t        dt	              z  t
              t        dt	              z  t
              z   }
t        t        fdt        t	                    D              j                  |
z         }t        t        fdt        t	                    D              j                  |
z         }t        | |z  ||z  z
  j                  |
z   j                  d	
      d   }t        |j                        j                         } |z   d	d	      }|r8t        d |j                         D              s|j                  |      }|j                  |      }|j                  t!        t#        t%        z   dgt	              t	              z   z                          }|j                  t!        t#        t%        z   dgt	              t	              z   z                          }t        |j                        }t        |j                        }|dk(  rt'        d      |j)                  |||z   f       ||z   |k7  r|d   g}n|dz  }|dz  }|dz  }||z   |	k  r|dkD  r& ||||||z
        \  }}} |||||z
  |      \  }}}|||fS )ak  
        Computes a rational simplification of ``a/b`` which minimizes
        the sum of the total degrees of the numerator and the denominator.

        Explanation
        ===========

        The algorithm proceeds by looking at ``a * d - b * c`` modulo
        the ideal generated by ``G`` for some ``c`` and ``d`` with degree
        less than ``a`` and ``b`` respectively.
        The coefficients of ``c`` and ``d`` are indeterminates and thus
        the coefficients of the normalform of ``a * d - b * c`` are
        linear polynomials in these indeterminates.
        If these linear polynomials, considered as system of
        equations, have a nontrivial solution, then `\frac{a}{b}
        \equiv \frac{c}{d}` modulo the ideal generated by ``G``. So,
        by construction, the degree of ``c`` and ``d`` is less than
        the degree of ``a`` and ``b``, so a simpler representation
        has been found.
        After a simpler representation has been found, the algorithm
        tries to reduce the degree of the numerator and denominator
        and returns the result afterwards.

        As an extension, if quick=False, we look at all possible degrees such
        that the total degree is less than *or equal to* the best current
        solution. We retain a list of all solutions of minimal degree, and try
        to find the best one at the end.
        r   r%   z%s / %s: %s, %szc:%d)clszd:%dc              3   4   K   | ]  }|   |   z    y wr'    )r(   r5   CsM1s     r   r+   z<ratsimpmodprime.<locals>._ratsimpmodprime.<locals>.<genexpr>        :aBqEBqEM:   c              3   4   K   | ]  }|   |   z    y wr'   r=   )r(   r5   DsM2s     r   r+   z<ratsimpmodprime.<locals>._ratsimpmodprime.<locals>.<genexpr>   r@   rA   T)orderpolys)r.   
particularr   c              3   &   K   | ]	  }|d k(    yw)r   Nr=   )r(   r6   s     r   r+   z<ratsimpmodprime.<locals>._ratsimpmodprime.<locals>.<genexpr>   s     <!qAv<s   zIdeal not prime?)total_degreeaddr   r   r-   r   r   sumr,   r.   r   rE   coeffsr/   valuessubsdictlistzip
ValueErrorr0   )aballsolNDcdstepsmaxdegboundngc_hatd_hatr   r3   solr>   rC   r?   rD   G_ratsimpmodprimer8   r   r!   r9   testeds                   @@@@r   rd   z)ratsimpmodprime.<locals>._ratsimpmodprimeh   s   : !1!ANN$44QJEE!eun1vJJ1v1B1B$q!Rn5#b')u5B#b')u5BbB:5R>::CHHrMKE:5R>::CHHrMKE E	AI-q#((R-!iit5568A QSXX&--/A27t4@C3<szz|<<JJsOJJsO
 FF4Sb1#R3r79J2K%L MNOFF4Sb1#R3r79J2K%L MNOCHH%CHH%6$%788ueQR89q5F?$Rj\FQJEFAFA_ !eunb 19+Aq&!QYGLAq&+Aq&!e)QGLAq&!V|    )rE   r%   )domainz*Looking for best minimal solution. Got: %sTFrG   c                 t    t        | d   j                               t        | d   j                               z   S )Nr   r%   )r-   terms)xs    r   <lambda>z!ratsimpmodprime.<locals>.<lambda>   s)    QqTZZ\):S1=N)N rf   )key)convert)r   r   )sympy.solvers.solversr!   r   r   r   r
   r   rg   has_assoc_Field	get_fieldr   LMrE   setr   r.   r   r   r-   r0   rP   minis_Fieldclear_denomsr   qp)r   rc   r   r   r.   argsnumdenomrF   rg   r   rZ   r[   rW   newsolr`   ra   r3   r_   rb   cndnr   rd   r7   r8   r!   r9   re   s    ``                    @@@@@@r   r"   r"      sF   < ,	
T" ,,.JC,c5\A-=MMM
s ZZF%%'
<vEG 	G 38)<Qcii<UFN$Z Z| #q#((#))
4Q
7CE1chhcii8;EE	!!###S#((3::.UCHHSZZ0XZ\^LAq&V;S[I#) 	>E5!R2$e<CMM5::c?EJJsO<=	> 6NO1??t,At,ARQKaccEAaccE?o   =s   I% "I6%I32I3N)	itertoolsr   
sympy.corer   r   r   sympy.core.numbersr   sympy.polysr   r	   r
   r   r   sympy.polys.monomialsr   r   sympy.polys.polyerrorsr   r   sympy.utilities.miscr   r   r   r"   r=   rf   r   <module>r      s2    3 * * ' Y Y 8 B .!, +/5 rf   