o
    8Va.                  	   @   s   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
 d dlmZmZ d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eeeeeeeedZdS )    )DictCallable)SAddExprBasicMul)Boolean)askQTc                    s   t | ts| S | js fdd| jD }| j| } t| dr)|  }|dur)|S | jj}t	
|d}|du r9| S ||  }|du sF| |krH| S t |tsO|S t| S )a#  
    Simplify an expression using assumptions.

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

    Unlike :func:`~.simplify()` which performs structural simplification
    without any assumption, this function transforms the expression into
    the form which is only valid under certain assumptions. Note that
    ``simplify()`` is generally not done in refining process.

    Refining boolean expression involves reducing it to ``S.true`` or
    ``S.false``. Unlike :func:`~.ask()`, the expression will not be reduced
    if the truth value cannot be determined.

    Examples
    ========

    >>> from sympy import refine, sqrt, Q
    >>> from sympy.abc import x
    >>> refine(sqrt(x**2), Q.real(x))
    Abs(x)
    >>> refine(sqrt(x**2), Q.positive(x))
    x

    >>> refine(Q.real(x), Q.positive(x))
    True
    >>> refine(Q.positive(x), Q.real(x))
    Q.positive(x)

    See Also
    ========

    sympy.simplify.simplify.simplify : Structural simplification without assumptions.
    sympy.assumptions.ask.ask : Query for boolean expressions using assumptions.
    c                    s   g | ]}t | qS  )refine).0argassumptionsr   :/usr/lib/python3/dist-packages/sympy/assumptions/refine.py
<listcomp>2   s    zrefine.<locals>.<listcomp>_eval_refineN)
isinstancer   Zis_Atomargsfunchasattrr   	__class____name__handlers_dictgetr   r   )exprr   r   Zref_exprnameZhandlerZnew_exprr   r   r   r   	   s&   
%





r   c           	         s   ddl m} ddlm} | jd }tt| r%|tt| r%|S tt| r0| S t	|t
re fdd|jD }g }g }|D ]}t	||rU||jd  qE|| qEt
| |t
|  S dS )aF  
    Handler for the absolute value.

    Examples
    ========

    >>> from sympy import Q, Abs
    >>> from sympy.assumptions.refine import refine_abs
    >>> from sympy.abc import x
    >>> refine_abs(Abs(x), Q.real(x))
    >>> refine_abs(Abs(x), Q.positive(x))
    x
    >>> refine_abs(Abs(x), Q.negative(x))
    -x

    r   )	fuzzy_notAbsc                    s   g | ]	}t t| qS r   )r   abs)r   ar   r   r   r   a   s    zrefine_abs.<locals>.<listcomp>N)Zsympy.core.logicr   Zsympyr!   r   r
   r   realnegativer   r   append)	r   r   r   r!   r   rZnon_absZin_absir   r   r   
refine_absE   s&   


r)   c                 C   s  ddl m}m} ddlm} ddlm} t| j|r8t	t
| jjd |r8t	t
| j|r8| jjd | j S t	t
| j|rj| jjrmt	t
| j|rWt| j| j S t	t
| j|rm|| jt| j| j  S t| j|rt| j|u rt| jj| jj| j  S | jtju rl| jjrn| }| j \}}t|}t }	t }
t|}|D ]}t	t
||r|	| qt	t
||r|
| q||	8 }t|
d r||
8 }|tj d }n||
8 }|d }||kst||k r|| | jt|  } d| j }t	t
||r| r|| j9 }|jrc| \}}|jrc|jtju rct	t
|j|rc|d d }t	t
||rJ| j|j S t	t
||r[| j|jd  S | j|j|  S || krp| S dS dS dS dS )as  
    Handler for instances of Pow.

    Examples
    ========

    >>> from sympy import Q
    >>> from sympy.assumptions.refine import refine_Pow
    >>> from sympy.abc import x,y,z
    >>> refine_Pow((-1)**x, Q.real(x))
    >>> refine_Pow((-1)**x, Q.even(x))
    1
    >>> refine_Pow((-1)**x, Q.odd(x))
    -1

    For powers of -1, even parts of the exponent can be simplified:

    >>> refine_Pow((-1)**(x+y), Q.even(x))
    (-1)**y
    >>> refine_Pow((-1)**(x+y+z), Q.odd(x) & Q.odd(z))
    (-1)**y
    >>> refine_Pow((-1)**(x+y+2), Q.odd(x))
    (-1)**(y + 1)
    >>> refine_Pow((-1)**(x+3), True)
    (-1)**(x + 1)

    r   )PowRationalr    )sign      N) 
sympy.corer*   r+   Z$sympy.functions.elementary.complexesr!   Zsympy.functionsr,   r   baser
   r   r$   r   ZevenZexpZ	is_numberr"   Zoddtyper   NegativeOneZis_AddZas_coeff_addsetlenaddOner   could_extract_minus_signZas_two_termsZis_PowZinteger)r   r   r*   r+   r!   r,   oldZcoeffZtermsZ
even_termsZ	odd_termsZinitial_number_of_termstZ	new_coeffZe2r(   pr   r   r   
refine_Powl   sx   







3r;   c                 C   s.  ddl m} ddlm} | j\}}tt|t|@ |r$||| S tt	|t	|@ |r:||| |j
 S tt|t	|@ |rP||| |j
 S tt|t	|@ |r`|j
S tt|t|@ |rr|j
d S tt	|t|@ |r|j
 d S tt|t|@ |r|jS | S )a  
    Handler for the atan2 function.

    Examples
    ========

    >>> from sympy import Q, atan2
    >>> from sympy.assumptions.refine import refine_atan2
    >>> from sympy.abc import x, y
    >>> refine_atan2(atan2(y,x), Q.real(y) & Q.positive(x))
    atan(y/x)
    >>> refine_atan2(atan2(y,x), Q.negative(y) & Q.negative(x))
    atan(y/x) - pi
    >>> refine_atan2(atan2(y,x), Q.positive(y) & Q.negative(x))
    atan(y/x) + pi
    >>> refine_atan2(atan2(y,x), Q.zero(y) & Q.negative(x))
    pi
    >>> refine_atan2(atan2(y,x), Q.positive(y) & Q.zero(x))
    pi/2
    >>> refine_atan2(atan2(y,x), Q.negative(y) & Q.zero(x))
    -pi/2
    >>> refine_atan2(atan2(y,x), Q.zero(y) & Q.zero(x))
    nan
    r   )atan)r   r-   )Z(sympy.functions.elementary.trigonometricr<   r/   r   r   r
   r   r$   positiver%   PizeroZNaN)r   r   r<   r   yxr   r   r   refine_atan2   s$   

rB   c                 C   s>   | j d }tt||r|S tt||rtjS t| |S )a  
    Handler for real part.

    Examples
    ========

    >>> from sympy.assumptions.refine import refine_re
    >>> from sympy import Q, re
    >>> from sympy.abc import x
    >>> refine_re(re(x), Q.real(x))
    x
    >>> refine_re(re(x), Q.imaginary(x))
    0
    r   )r   r
   r   r$   	imaginaryr   Zero_refine_reimr   r   r   r   r   r   	refine_re   s   

rG   c                 C   sF   | j d }tt||rtjS tt||rtj | S t| |S )a  
    Handler for imaginary part.

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

    >>> from sympy.assumptions.refine import refine_im
    >>> from sympy import Q, im
    >>> from sympy.abc import x
    >>> refine_im(im(x), Q.real(x))
    0
    >>> refine_im(im(x), Q.imaginary(x))
    -I*x
    r   )	r   r
   r   r$   r   rD   rC   ImaginaryUnitrE   rF   r   r   r   	refine_im  s   

rI   c                 C   s:   | j d }tt||rtjS tt||rtjS dS )a"  
    Handler for complex argument

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

    >>> from sympy.assumptions.refine import refine_arg
    >>> from sympy import Q, arg
    >>> from sympy.abc import x
    >>> refine_arg(arg(x), Q.positive(x))
    0
    >>> refine_arg(arg(x), Q.negative(x))
    pi
    r   N)r   r
   r   r=   r   rD   r%   r>   )r   r   Zrgr   r   r   
refine_arg,  s   
rJ   c                 C   s.   | j dd}|| krt||}||kr|S d S )NT)complex)expandr   )r   r   ZexpandedZrefinedr   r   r   rE   C  s   
rE   c                 C   s   | j d }tt||rtjS tt|r-tt||r"tjS tt	||r-tj
S tt|rQ| \}}tt||rEtjS tt	||rQtj S | S )a*  
    Handler for sign.

    Examples
    ========

    >>> from sympy.assumptions.refine import refine_sign
    >>> from sympy import Symbol, Q, sign, im
    >>> x = Symbol('x', real = True)
    >>> expr = sign(x)
    >>> refine_sign(expr, Q.positive(x) & Q.nonzero(x))
    1
    >>> refine_sign(expr, Q.negative(x) & Q.nonzero(x))
    -1
    >>> refine_sign(expr, Q.zero(x))
    0
    >>> y = Symbol('y', imaginary = True)
    >>> expr = sign(y)
    >>> refine_sign(expr, Q.positive(im(y)))
    I
    >>> refine_sign(expr, Q.negative(im(y)))
    -I
    r   )r   r
   r   r?   r   rD   r$   r=   r6   r%   r2   rC   Zas_real_imagrH   )r   r   r   Zarg_reZarg_imr   r   r   refine_signN  s   
rM   c                 C   sH   ddl m} | j\}}}tt||r"||  r| S ||||S dS )a  
    Handler for symmetric part.

    Examples
    ========

    >>> from sympy.assumptions.refine import refine_matrixelement
    >>> from sympy import Q
    >>> from sympy.matrices.expressions.matexpr import MatrixSymbol
    >>> X = MatrixSymbol('X', 3, 3)
    >>> refine_matrixelement(X[0, 1], Q.symmetric(X))
    X[0, 1]
    >>> refine_matrixelement(X[1, 0], Q.symmetric(X))
    X[0, 1]
    r   )MatrixElementN)Z"sympy.matrices.expressions.matexprrN   r   r
   r   Z	symmetricr7   )r   r   rN   Zmatrixr(   jr   r   r   refine_matrixelementw  s   rP   )r!   r*   Zatan2reZimr   r,   rN   N)T)typingr   r   r/   r   r   r   r   r   Zsympy.logic.boolalgr	   Zsympy.assumptionsr
   r   r   r)   r;   rB   rG   rI   rJ   rE   rM   rP   r   r   r   r   r   <module>   s.    
<'e.)
