a
    SG5d                     @   s   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 dd	 Zd
ddddZdS )    )combinations_with_replacement)symbolsAddDummy)Rational)cancelComputationFailedparallel_poly_from_exprreducedPoly)Monomialmonomial_div)DomainErrorPolificationFailed)debugc                 C   sZ   t |  \}}zt||gddd\}}W n tyD   ||  Y S 0 t| t ||  S )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r r   R/var/www/html/django/DPS/env/lib/python3.9/site-packages/sympy/simplify/ratsimp.pyratsimp	   s    r   TF)quick
polynomialc                   s  ddl m td|  t|  \}}z&t||g  g|R i |\}W n tyb   |  Y S 0 j}	|	jr||		 _nt
d|	 fdd|dd D t fd	d
d fdd	t| jjdd }t| jjdd }|r||  S t|jjdt|jjdg \}
}}s|rtdt|  g }|D ]8\}}}}||ddd}|||||f qft|dd d\}
}|	js|
jdd\}}
|jdd\}}t||}ntd}|
|j ||j  S )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, http://citeseer.ist.psu.edu/viewdoc/summary?doi=10.1.1.163.6984
        (specifically, the second algorithm)
    r   )solveratsimpmodprimez.Cannot compute rational simplification over %sc                    s   g | ]}|  jqS r   )LMorder).0r   optr   r   
<listcomp>S       z#ratsimpmodprime.<locals>.<listcomp>   Nc                    s   | dkrdgS g }t ttj| D ]N}dgtj  |D ]} |  d7  < q>t fddD r&|  q&fdd|D | d  S )z
        Compute all monomials with degree less than ``n`` that are
        not divisible by any element of ``leading_monomials``.
        r      c                 3   s   | ]}t  |d u V  qd S )N)r   )r"   lmgmr   r   	<genexpr>b   r&   z5ratsimpmodprime.<locals>.staircase.<locals>.<genexpr>c                    s   g | ]}t |j j qS r   )r   as_exprgensr"   sr#   r   r   r%   f   r&   z6ratsimpmodprime.<locals>.staircase.<locals>.<listcomp>)r   rangelenr.   allappend)nSmii)leading_monomialsr$   	staircaser*   r   r:   V   s    z"ratsimpmodprime.<locals>.staircasec              
      s  | | }}d}|   |   }r,|d }	n|}	|| |	kr\||f
v rNq\
||f 	|	|td||f  tdt td tdt td  }
tt fddttD j	|
 }ttfd	dttD j	|
 }t
| | ||  j	|
 jd
dd }t|j	d }|  d
d
d}|rBtdd | D sB||}||}|ttt  dgt t  }|ttt  dgt t  }t|j	}t|j	}|dkrtd||||  f || |kr\|d g}q\|d7 }|d7 }|d7 }q0|dkr|||||| \}}}||||| |\}}}|||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                    s   g | ]} | |  qS r   r   r"   r8   )CsM1r   r   r%      r&   z=ratsimpmodprime.<locals>._ratsimpmodprime.<locals>.<listcomp>c                    s   g | ]} | |  qS r   r   r<   )DsM2r   r   r%      r&   T)r!   polys)r.   
particularr   c                 s   s   | ]}|d kV  qdS )r   Nr   r/   r   r   r   r,      r&   z<ratsimpmodprime.<locals>._ratsimpmodprime.<locals>.<genexpr>zIdeal not prime?)total_degreeaddr   r   r2   r   r   sumr1   r.   r
   r!   coeffsr3   valuessubsdictlistzip
ValueErrorr4   )aballsolNDcdstepsZmaxdegboundngc_hatd_hatr   r6   sol)G_ratsimpmodprimer$   r   r   r:   tested)r=   r?   r>   r@   r   r]   h   sb    

&&

..



z)ratsimpmodprime.<locals>._ratsimpmodprime)r!   r(   )domainz*Looking for best minimal solution. Got: %sTFrB   c                 S   s    t | d  t | d   S )Nr   r(   )r2   terms)xr   r   r   <lambda>   r&   z!ratsimpmodprime.<locals>.<lambda>)key)convert)r   r   )sympy.solvers.solversr   r   r   r   r	   r   r_   has_assoc_Field	get_fieldr   setr
   r.   r!   r   r2   r4   rJ   minis_Fieldclear_denomsr   qp)r   r\   r   r   r.   argsnumdenomrA   r_   rT   rU   rQ   ZnewsolrY   rZ   r6   rX   r[   cndnr   r   )r\   r]   r9   r$   r   r   r:   r^   r   r      sJ    
&
^"
r   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   r   r   <module>   s   