B
    [                 @   sb  d Z ddlmZmZ ddlmZmZmZ ddl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 ddlmZmZmZm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" ddl#m$Z$m%Z%m&Z& ddl'm(Z( ddl)m*Z* ddl+m,Z, dd Z-dd Z.dd Z/d+ddZ0dd Z1dd Z2dej3dfd d!Z4d"d# Z5d,d$d%Z6d&d' Z7g fd(d)Z8d*S )-z<Tools for solving inequalities and systems of inequalities.     )print_functiondivision)SymbolDummysympify)iterable)factor_terms)
RelationalEqGeLtNe)Interval)	FiniteSetUnionEmptySetIntersection)ImageSet)S)
expand_mul)Abs)And)PolyPolynomialErrorparallel_poly_from_expr)_nsort)sift)
filldedentc          	   C   s<  t | tstd| jrXt|  d|}|tjkr:tjgS |tj	krLtj
gS td| | jddg  }}|dkrx$|D ]\}}t||}|| qxW n|dkrtj}x8|tjdfg D ]$\}	}t||	d	d	}|| |	}qW nP|  dk rd}
nd
}
d\}}|dkrd}nD|dkr(d
}n4|dkr<d\}}n |dkrPd\}}ntd| tjd	 }	}xt|D ]\}}|d r|
|kr|dt||	| | |
 ||   }
}	}nT|
|kr|s|dt||	d	| |d	 }	}n"|
|krr|rr|dt|| qrW |
|kr8|dttj|	d	| |S )a@  Solve a polynomial inequality with rational coefficients.

    Examples
    ========

    >>> from sympy import Poly
    >>> from sympy.abc import x
    >>> from sympy.solvers.inequalities import solve_poly_inequality

    >>> solve_poly_inequality(Poly(x, x, domain='ZZ'), '==')
    [{0}]

    >>> solve_poly_inequality(Poly(x**2 - 1, x, domain='ZZ'), '!=')
    [Interval.open(-oo, -1), Interval.open(-1, 1), Interval.open(1, oo)]

    >>> solve_poly_inequality(Poly(x**2 - 1, x, domain='ZZ'), '==')
    [{-1}, {1}]

    See Also
    ========
    solve_poly_inequalities
    z8For efficiency reasons, `poly` should be a Poly instancer   z%could not determine truth value of %sF)Zmultiplez==z!=   T)NF><z>=)r   Tz<=)r   Tz'%s' is not a valid relation   )
isinstancer   
ValueError	is_numberr	   as_exprr   trueRealsfalser   NotImplementedErrorZ
real_rootsr   appendNegativeInfinityInfinityZLCreversedinsert)Zpolyreltreals	intervalsroot_intervalleftrightZsignZeq_signZequalZ
right_openZmultiplicity r9   9lib/python3.7/site-packages/sympy/solvers/inequalities.pysolve_poly_inequality   sh    














r;   c             C   s   ddl m} |dd | D  S )a  Solve polynomial inequalities with rational coefficients.

    Examples
    ========

    >>> from sympy.solvers.inequalities import solve_poly_inequalities
    >>> from sympy.polys import Poly
    >>> from sympy.abc import x
    >>> solve_poly_inequalities(((
    ... Poly(x**2 - 3), ">"), (
    ... Poly(-x**2 + 1), ">")))
    Union(Interval.open(-oo, -sqrt(3)), Interval.open(-1, 1), Interval.open(sqrt(3), oo))
    r   )r   c             S   s   g | ]}t | qS r9   )r;   ).0pr9   r9   r:   
<listcomp>   s    z+solve_poly_inequalities.<locals>.<listcomp>)sympyr   )Zpolysr   r9   r9   r:   solve_poly_inequalitiesr   s    r@   c             C   s   t j}x| D ]}|sqtt jt jg}x|D ]\\}}}t|| |}t|d}g }	x8|D ]0}
x*|D ]"}|
|}|t jk	rd|	| qdW qZW |	}g }	x6|D ].}x|D ]}||8 }qW |t jk	r|	| qW |	}|s,P q,W x|D ]}||}qW qW |S )aa  Solve a system of rational inequalities with rational coefficients.

    Examples
    ========

    >>> from sympy.abc import x
    >>> from sympy import Poly
    >>> from sympy.solvers.inequalities import solve_rational_inequalities

    >>> solve_rational_inequalities([[
    ... ((Poly(-x + 1), Poly(1, x)), '>='),
    ... ((Poly(-x + 1), Poly(1, x)), '<=')]])
    {1}

    >>> solve_rational_inequalities([[
    ... ((Poly(x), Poly(1, x)), '!='),
    ... ((Poly(-x + 1), Poly(1, x)), '>=')]])
    Union(Interval.open(-oo, 0), Interval.Lopen(0, 1))

    See Also
    ========
    solve_poly_inequality
    z==)	r   r   r   r,   r-   r;   	intersectr+   union)eqsresult_eqsZglobal_intervalsnumerdenomr0   Znumer_intervalsZdenom_intervalsr3   Znumer_intervalZglobal_intervalr6   Zdenom_intervalr9   r9   r:   solve_rational_inequalities   s6    









rH   Tc          
      s  d}g }| rt jnt j}xp| D ]f}g }xL|D ]B}t|trL|\}}	n&|jrh|j|j |j }}	n
|d }}	|t j	krt j
t jd  }
}}	n0|t jkrt jt jd  }
}}	n|  \}
}yt|
|f \\}
}}W n" tk
 r   ttdY nX |jjs"|
 | d  }
}}|j }|jsd|jsd|
| }t|d|	}|t| ddM }q2||
|f|	f q2W |r || q W |r|t|M }t fdd|D g}||8 }|s|r| }|r| }|S )	a$  Reduce a system of rational inequalities with rational coefficients.

    Examples
    ========

    >>> from sympy import Poly, Symbol
    >>> from sympy.solvers.inequalities import reduce_rational_inequalities

    >>> x = Symbol('x', real=True)

    >>> reduce_rational_inequalities([[x**2 <= 0]], x)
    Eq(x, 0)

    >>> reduce_rational_inequalities([[x + 2 > 0]], x)
    (-2 < x) & (x < oo)
    >>> reduce_rational_inequalities([[(x + 2, ">")]], x)
    (-2 < x) & (x < oo)
    >>> reduce_rational_inequalities([[x + 2]], x)
    Eq(x, -2)
    Tz==z
                    only polynomials and rational functions are
                    supported in this context.
                    Fr   )
relationalc                s6   g | ].}|D ]$\\}}}|  r||jfd fqqS )z==)hasZone)r<   indr5   )genr9   r:   r>     s   z0reduce_rational_inequalities.<locals>.<listcomp>)r   r(   r   r#   tupleZis_Relationallhsrhsrel_opr'   ZeroOner)   Ztogetheras_numer_denomr   r   r   domainZis_ExactZto_exactZ	get_exactZis_ZZZis_QQr	   solve_univariate_inequalityr+   rH   Zevalfas_relational)exprsrN   rI   exactrC   Zsolution_exprsrE   exprr0   rF   rG   ZoptrV   Zexcluder9   )rN   r:   reduce_rational_inequalities   sT    







r]   c                s   |j dkrttd fdd  | }ddd}g }xL|D ]D\} }|| kr`t| d|} nt|  d|| } || g|  q>W t||S )	a  Reduce an inequality with nested absolute values.

    Examples
    ========

    >>> from sympy import Abs, Symbol
    >>> from sympy.solvers.inequalities import reduce_abs_inequality
    >>> x = Symbol('x', real=True)

    >>> reduce_abs_inequality(Abs(x - 5) - 3, '<', x)
    (2 < x) & (x < 8)

    >>> reduce_abs_inequality(Abs(x + 2)*3 - 13, '<', x)
    (-19/3 < x) & (x < 7/3)

    See Also
    ========

    reduce_abs_inequalities
    Fzr
            can't solve inequalities with absolute values containing
            non-real variables.
            c       
         s:  g }| j s| jr~| j}xd| jD ]Z} |}|s4|}qg }x:|D ]2\} }x(|D ] \}}||| ||| f qLW q>W |}qW n| jr| j}	|	jstd | j	}x|D ]\} }|| |	 |f qW nnt
| tr, | jd }xR|D ]>\} }|| |t| dg f ||  |t| dg f qW n
| g fg}|S )Nz'Only Integer Powers are allowed on Abs.r   )Zis_AddZis_Mulfuncargsr+   is_Powexp
is_Integerr$   baser#   r   r   r   )
r\   rY   opargr[   r_   condsZ_exprZ_condsrL   )_bottom_up_scanr9   r:   rg   4  s4     

"
z.reduce_abs_inequality.<locals>._bottom_up_scanr    z>=)r!   z<=r   )is_real	TypeErrorr   keysr	   r+   r]   )r\   r0   rN   rY   mappinginequalitiesrf   r9   )rg   r:   reduce_abs_inequality  s    
'
rm   c                s   t  fdd| D  S )aU  Reduce a system of inequalities with nested absolute values.

    Examples
    ========

    >>> from sympy import Abs, Symbol
    >>> from sympy.abc import x
    >>> from sympy.solvers.inequalities import reduce_abs_inequalities
    >>> x = Symbol('x', real=True)

    >>> reduce_abs_inequalities([(Abs(3*x - 5) - 7, '<'),
    ... (Abs(x + 25) - 13, '>')], x)
    (-2/3 < x) & (x < 4) & (((-oo < x) & (x < -38)) | ((-12 < x) & (x < oo)))

    >>> reduce_abs_inequalities([(Abs(x - 4) + Abs(3*x - 5) - 7, '<')], x)
    (1/2 < x) & (x < 4)

    See Also
    ========

    reduce_abs_inequality
    c                s   g | ]\}}t || qS r9   )rm   )r<   r\   r0   )rN   r9   r:   r>     s   z+reduce_abs_inequalities.<locals>.<listcomp>)r   )rY   rN   r9   )rN   r:   reduce_abs_inequalitiesk  s    rn   Fc       1         s  ddl m} ddlm}m}m} ddlm}	 ddlm	}
m
}m} ddlm} }|}jdkrvtj}|sl|S ||S jdkrtd	d
dy|iW n  tk
r   ttdY nX d}tjkr|}ntjkrtj}njj }||}|tjkrFt|}|d}|tjkr2|}n|tjkrtj}n|dk	r|||}j}|dksv|dkr|jdr|}n|jdstj}n@|dks|dkr|jdr|}n|jdstj}|j|j }}|| tjkrt d|dd
}|dkr|! \}}y>|j"krHt#|j"dkrHt$|||}|dkrbt$W n6 t$t%fk
r   t%td&t'd Y nX t|  fdd}g }x&|	D ]}|(||| qW |s| |}djkojdk}yt)|j*t+|j|j }t+|| t,|  -t |j|j|j|k|j|k}t.dd |D r|t/|d
dd } n^t0|dd }!|!d rt%y&|!d
 } t#| dkrt,t1| } W n tk
r   t%Y nX W n t%k
r   t%dY nX tj2}"| tjkrd
}#t+ }$y@|| |}%t3|%t svx6|%D ].}&|&|krB||&rB|&jrB|$t+|&7 }$qBW n|%j|%j }'}(xt/|t+|( D ]}&||'})|'|(kr6||&}*t4|'|&}+|+|kr6|+jr6||+r6|)r|*r|$t |'|&7 }$n@|)r|$t 5|'|&7 }$n(|*r&|$t 6|'|&7 }$n|$t 7|'|&7 }$|&}'qW x|D ]},|$t+|,8 }$qFW W n  tk
r~   tj2}$d}#Y nX t3|$trt$td&||f |"8|$}"tjg }-}.|j}'||'r|'j9r|.:t+|' x| D ]~}/|/}(|t4|'|(r|.:t |'|(d
d
 |/|kr,|;|/ n6|/|krJ|;|/ ||/}0n|}0|0rb|.:t+|/ |(}'qW |j}(||(r|(j9r|.:t+|( |t4|'|(r|.:t 7|'|( | tjkr|#r|"8|}nt<t=|. |"|&|}|s|S ||S )a0  Solves a real univariate inequality.

    Parameters
    ==========

    expr : Relational
        The target inequality
    gen : Symbol
        The variable for which the inequality is solved
    relational : bool
        A Relational type output is expected or not
    domain : Set
        The domain over which the equation is solved
    continuous: bool
        True if expr is known to be continuous over the given domain
        (and so continuous_domain() doesn't need to be called on it)

    Raises
    ======

    NotImplementedError
        The solution of the inequality cannot be determined due to limitation
        in `solvify`.

    Notes
    =====

    Currently, we cannot solve all the inequalities due to limitations in
    `solvify`. Also, the solution returned for trigonometric inequalities
    are restricted in its periodic interval.

    See Also
    ========

    solvify: solver returning solveset solutions with solve's output API

    Examples
    ========

    >>> from sympy.solvers.inequalities import solve_univariate_inequality
    >>> from sympy import Symbol, sin, Interval, S
    >>> x = Symbol('x')

    >>> solve_univariate_inequality(x**2 >= 4, x)
    ((2 <= x) & (x < oo)) | ((x <= -2) & (-oo < x))

    >>> solve_univariate_inequality(x**2 >= 4, x, relational=False)
    Union(Interval(-oo, -2), Interval(2, oo))

    >>> domain = Interval(0, S.Infinity)
    >>> solve_univariate_inequality(x**2 >= 4, x, False, domain)
    Interval(2, oo)

    >>> solve_univariate_inequality(sin(x) > 0, x, relational=False)
    Interval.open(0, pi)

    r   )im)continuous_domainperiodicityfunction_range)denoms)solveset_realsolvifysolveset)solveFNrN   T)realz
                When gen is real, the relational has a complex part
                which leads to an invalid comparison like I < 0.
                r!   z<=r    z>=r   z
                    The inequality, %s, cannot be solved using
                    solve_univariate_inequality.
                    xc                s     t| }y|d}W n tk
r:   tj}Y nX |tjtjfkrP|S |jdkr`tjS |d}|j	r||dS t
d| d S )Nr   Fr"   z!relationship did not evaluate: %s)subsr   r^   ri   r   r)   r'   rh   rL   Zis_comparabler*   )ry   vr)
expanded_er\   rN   r9   r:   valid  s    


z*solve_univariate_inequality.<locals>.valid=z!=c             s   s   | ]}|j V  qd S )N)r%   )r<   r|   r9   r9   r:   	<genexpr>>  s    z.solve_univariate_inequality.<locals>.<genexpr>)Z	separatedc             S   s   | j S )N)rh   )ry   r9   r9   r:   <lambda>A  s    z-solve_univariate_inequality.<locals>.<lambda>z'sorting of these roots is not supportedz
                        %s contains imaginary parts which cannot be
                        made 0 for any value of %s satisfying the
                        inequality, leading to relations like I < 0.
                        )>r?   ro   Zsympy.calculus.utilrp   rq   rr   sympy.solvers.solversrs   Zsympy.solvers.solvesetrt   ru   rv   rw   rh   r   r   rX   r   xreplaceri   r   r'   r)   rP   rQ   rS   r   r^   rR   supinfr-   r   rU   free_symbolslenr$   r*   rz   r   extendsetboundaryr   listintersectionallr   r   sortedr(   r#   _ptZRopenZLopenopenrA   Z	is_finiter+   remover   r   )1r\   rN   rI   rV   Z
continuousro   rp   rq   rr   rs   rt   ru   rv   rw   Z_genZ_domainrveZperiodZconstZfranger0   r   r   rL   rM   Zsolnsr~   ZsingularitiesZ	include_xZdiscontinuitiesZcritical_pointsr2   ZsiftedZ	make_realZcheckZim_solazstartendZvalid_startZvalid_zptsemptyZsol_setsry   Z_validr9   )r}   r\   rN   r:   rW     s&   :

























rW   c             C   s   | j s|j s| | d }n| j r.|j r.tj}n| j r>| jdksN|j rV|jdkrVtd|j rb|jsn| j rx| jrx||  } }|j r| jr| d }q| jr| tj }q| d }n0| j r|jr|tj }n|jr|d }n|d }|S )z$Return a point between start and endr"   Nz,cannot proceed with unsigned infinite valuesr   )Zis_infiniter   rS   is_positiver$   is_negativeZHalf)r   r   r   r9   r9   r:   r     s.    



r   c             C   s  ddl m} || jkr| S | j|kr*| j} | j|krD|| jjkrD| S dd }d}tj}| j| j }yBt||}|	 dkr| 
| d}n|s|	 dkrtW n0 ttfk
r   |syt| gg|}W n tk
r   t| |}Y nX || ||}	|	tjkr.||||tjkr.|||k d}|| || }
|
tjkr|||| tjkr|| |k d}||| kd}|tjkr|	tjkr||kn||k }|
tjk	rt| |k |}nt|}Y nX g }|dkrv| }d}|j|dd\}}||8 }||8 }t|}|j|d	d\}}|jd	ksd|j|j  krTdkrnn n| jd
krn|}tj}|| }|jr| 
||}n| j
||}|| j|| jB }||}x`|| D ]T}tt|d||d}t|tr|j|kr||||jtjkr||  qW x\| |fD ]N}||||tjkr$|| ||tjk	r$|||krf||k n||k  q$W || t| S )a  Return the inequality with s isolated on the left, if possible.
    If the relationship is non-linear, a solution involving And or Or
    may be returned. False or True are returned if the relationship
    is never True or always True, respectively.

    If `linear` is True (default is False) an `s`-dependent expression
    will be isoloated on the left, if possible
    but it will not be solved for `s` unless the expression is linear
    in `s`. Furthermore, only "safe" operations which don't change the
    sense of the relationship are applied: no division by an unsigned
    value is attempted unless the relationship involves Eq or Ne and
    no division by a value not known to be nonzero is ever attempted.

    Examples
    ========

    >>> from sympy import Eq, Symbol
    >>> from sympy.solvers.inequalities import _solve_inequality as f
    >>> from sympy.abc import x, y

    For linear expressions, the symbol can be isolated:

    >>> f(x - 2 < 0, x)
    x < 2
    >>> f(-x - 6 < x, x)
    x > -3

    Sometimes nonlinear relationships will be False

    >>> f(x**2 + 4 < 0, x)
    False

    Or they may involve more than one region of values:

    >>> f(x**2 - 4 < 0, x)
    (-2 < x) & (x < 2)

    To restrict the solution to a relational, set linear=True
    and only the x-dependent portion will be isolated on the left:

    >>> f(x**2 - 4 < 0, x, linear=True)
    x**2 < 4

    Division of only nonzero quantities is allowed, so x cannot
    be isolated by dividing by y:

    >>> y.is_nonzero is None  # it is unknown whether it is 0 or not
    True
    >>> f(x*y < 1, x)
    x*y < 1

    And while an equality (or unequality) still holds after dividing by a
    non-zero quantity

    >>> nz = Symbol('nz', nonzero=True)
    >>> f(Eq(x*nz, 1), x)
    Eq(x, 1/nz)

    the sign must be known for other inequalities involving > or <:

    >>> f(x*nz <= 1, x)
    nz*x <= 1
    >>> p = Symbol('p', positive=True)
    >>> f(x*p <= 1, x)
    x <= 1/p

    When there are denominators in the original expression that
    are removed by expansion, conditions for them will be returned
    as part of the result:

    >>> f(x < x*(2/x - 1), x)
    (x < 1) & Ne(x, 0)
    r   )rs   c             S   sF   y*|  ||}|tjkr|S |dkr(d S |S  tk
r@   tjS X d S )N)TF)rz   r   ZNaNri   )ier   rK   r{   r9   r9   r:   classify  s    
z#_solve_inequality.<locals>.classifyNr   T)Zas_AddF)z!=z==)linear)r   rs   r   rQ   r.   rP   r   r-   r   Zdegreer^   r&   r*   r   r]   rW   r'   r)   rz   r   Zas_independentr   Zis_zeror   r   rR   rT   _solve_inequalityr
   r#   r+   )r   r   r   rs   r   r   Zoor\   r=   ZokooZoknoorf   r   rQ   bZaxZefr   Zbeginning_denomsZcurrent_denomsrM   crK   r9   r9   r:   r     s    J



 
&
r   c                st  i i  }}g }x| D ]}|j |j }}|t}t|dkrF|  nF|j|@ }	t|	dkr|	  |tt	|d|  qnt
td| r| g ||f q| fdd}
|
rtdd |
D r| g ||f q|tt	|d|  qW g }g }x(| D ]\ }|t|g  qW x&| D ]\ }|t|  qFW t|| |  S )Nr   r   zZ
                    inequality has more than one symbol of interest.
                    c                s    |   o| jp| jo| jj S )N)rJ   Zis_Functionr`   ra   rb   )u)rN   r9   r:   r     s    
z&_reduce_inequalities.<locals>.<lambda>c             s   s   | ]}t |tV  qd S )N)r#   r   )r<   rK   r9   r9   r:   r     s    z'_reduce_inequalities.<locals>.<genexpr>)rP   rR   Zatomsr   r   popr   r+   r   r	   r*   r   Zis_polynomial
setdefaultfindr   itemsr]   rn   r   )rl   symbolsZ	poly_partZabs_partotherZ
inequalityr\   r0   genscommonZ
componentsZpoly_reducedZabs_reducedrY   r9   )rN   r:   _reduce_inequalitiesq  s6    





r   c                sT  t | s| g} dd | D } t jdd | D  }t |s@|g}t|pJ||@ }tdd |D rnttdtdd |D   fdd| D }  fd	d
|D }g }x| D ]z}t|tr|	|j
 |j  d}n|dkrt|d}|dkrqn|dkrtjS |j
jrtd| || qW |} ~t| |}|dd   D S )a  Reduce a system of inequalities with rational coefficients.

    Examples
    ========

    >>> from sympy import sympify as S, Symbol
    >>> from sympy.abc import x, y
    >>> from sympy.solvers.inequalities import reduce_inequalities

    >>> reduce_inequalities(0 <= x + 3, [])
    (-3 <= x) & (x < oo)

    >>> reduce_inequalities(0 <= x + y*2 - 1, [x])
    (x < oo) & (x >= -2*y + 1)
    c             S   s   g | ]}t |qS r9   )r   )r<   rK   r9   r9   r:   r>     s    z'reduce_inequalities.<locals>.<listcomp>c             S   s   g | ]
}|j qS r9   )r   )r<   rK   r9   r9   r:   r>     s    c             s   s   | ]}|j d kV  qdS )FN)rh   )r<   rK   r9   r9   r:   r     s    z&reduce_inequalities.<locals>.<genexpr>zP
            inequalities cannot contain symbols that are not real.
            c             S   s(   g | ] }|j d kr|t|jddfqS )NT)rx   )rh   r   name)r<   rK   r9   r9   r:   r>     s   c                s   g | ]}|  qS r9   )r   )r<   rK   )recastr9   r:   r>     s    c                s   h | ]}|  qS r9   )r   )r<   rK   )r   r9   r:   	<setcomp>  s    z&reduce_inequalities.<locals>.<setcomp>r   )TFTFz%could not determine truth value of %sc             S   s   i | ]\}}||qS r9   r9   )r<   kr{   r9   r9   r:   
<dictcomp>  s    z'reduce_inequalities.<locals>.<dictcomp>)r   r   rB   anyri   r   dictr#   r	   r^   rP   r&   rQ   r
   r   r)   r%   r*   r+   r   r   r   )rl   r   r   ZkeeprK   r   r9   )r   r:   reduce_inequalities  s@    







r   N)T)F)9__doc__Z
__future__r   r   Z
sympy.corer   r   r   Zsympy.core.compatibilityr   Zsympy.core.exprtoolsr   Zsympy.core.relationalr	   r
   r   r   r   Z
sympy.setsr   Zsympy.sets.setsr   r   r   r   Zsympy.sets.fancysetsr   Zsympy.core.singletonr   Zsympy.core.functionr   Zsympy.functionsr   Zsympy.logicr   Zsympy.polysr   r   r   Zsympy.polys.polyutilsr   Zsympy.utilities.iterablesr   Zsympy.utilities.miscr   r;   r@   rH   r]   rm   rn   r(   rW   r   r   r   r   r9   r9   r9   r:   <module>   s<   \C
RR   !
 -3