B
    [                 @   s   d dl mZmZ 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 d dlmZ d	d
 Zdd ZdS )    )print_functiondivision)combinations_with_replacement)symbolsAddDummy)Rational)cancelComputationFailedparallel_poly_from_exprreducedPoly)Monomialmonomial_div)PolificationFailed)debugc             C   sX   t |  \}}yt||gddd\}}W n tk
rB   || S X 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)Zfieldexpand)r	   as_numer_denomr   r
   r   )exprfgQr r   5lib/python3.7/site-packages/sympy/simplify/ratsimp.pyratsimp   s    
r   c                s  ddl m |dd|dd}td|  t|  \}}y t||g  f||\}W n tk
rr   | S X 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 }x@|D ]8\}}}}||ddd}|||||f qxW t|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.

    >>> 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
    ==========

    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quickT
polynomialFratsimpmodprimez-can't compute rational simplification over %sc                s   g | ]}|  jqS r   )ZLMorder).0r   )optr   r   
<listcomp>U   s    z#ratsimpmodprime.<locals>.<listcomp>   Nc                s   | dkrdgS g }xjt ttj| D ]R}dgtj  x|D ]} |  d7  < qBW t fddD r(|  q(W 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                s   g | ]}t  |d kqS )N)r   )r!   Zlmg)mr   r   r#   d   s    z6ratsimpmodprime.<locals>.staircase.<locals>.<listcomp>c                s   g | ]}t |j j qS r   )r   Zas_exprgens)r!   s)r"   r   r   r#   h   s    )r   rangelenr'   allappend)nSZmii)leading_monomialsr"   	staircase)r&   r   r1   X   s    

z"ratsimpmodprime.<locals>.staircasec          
      s  | | }}d}|   |   }r,|d }	n|}	x*|| |	kr\||f
krPP 
||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}P |d7 }|d7 }|d7 }q4W |dkr|||||| \}}}||||| |\}}}|||fS )aB  
        Computes a rational simplification of ``a/b`` which minimizes
        the sum of the total degrees of the numerator and the denominator.

        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!   r/   )CsM1r   r   r#      s    z=ratsimpmodprime.<locals>._ratsimpmodprime.<locals>.<listcomp>c                s   g | ]} | |  qS r   r   )r!   r/   )DsM2r   r   r#      s    T)r    polys)r'   )
particularr   c             S   s   g | ]}|d kqS )r   r   )r!   r(   r   r   r   r#      s    zIdeal not prime?)Ztotal_degreeaddr   r   r*   r   r   sumr)   r'   r   r    Zcoeffsr+   valuessubsdictlistzip
ValueErrorr,   )aballsolNDcdZstepsZmaxdegZboundngc_hatd_hatr   r.   sol)G_ratsimpmodprimer"   r   r   r1   tested)r3   r5   r4   r6   r   rN   j   sX    

**

..


z)ratsimpmodprime.<locals>._ratsimpmodprime)r    r%   )domainz*Looking for best minimal solution. Got: %s)r8   r   c             S   s    t | d  t | d   S )Nr   r%   )r*   Zterms)xr   r   r   <lambda>   s    z!ratsimpmodprime.<locals>.<lambda>)key)Zconvert)r   r   )Zsympyr   popr   r	   r   r   r   rP   Zhas_assoc_FieldZ	get_fieldZDomainErrorsetr   r'   r    r   r*   r,   r=   minZis_FieldZclear_denomsr   qp)r   rM   r'   argsr   ZnumZdenomr7   rP   rG   rH   rD   ZnewsolrJ   rK   r.   rI   rL   ZcnZdnr   r   )rM   rN   r0   r"   r   r   r1   rO   r   r   !   sJ    
 
[, r   N)Z
__future__r   r   	itertoolsr   Z
sympy.corer   r   r   Zsympy.core.numbersr   Zsympy.polysr	   r
   r   r   r   Zsympy.polys.monomialsr   r   Zsympy.polys.polyerrorsr   Zsympy.utilities.miscr   r   r   r   r   r   r   <module>   s   