B
    [+S                 @   s   d Z ddl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lmZmZ ddlmZ G dd	 d	eZG d
d deZG dd deZG dd deZG dd deZG dd deZG dd deZG dd deZG dd deZG dd deZdS )zL
Handlers for predicates related to set membership: integer, rational, etc.
    )print_functiondivision)Qask)CommonHandlertest_closed_group)pi)explog)Ic               @   s   e Zd ZdZedd Zedd Zedd Zedd	 ZeZ	ee
jgd
 \ZZee
jgd \ZZZZZZZedd Zedd Zedd Ze ZZdS )AskIntegerHandlerzc
    Handler for Q.integer
    Test that an expression belongs to the field of integer numbers
    c             C   s   | j S )N)
is_integer)exprassumptions r   >lib/python3.7/site-packages/sympy/assumptions/handlers/sets.pyExpr   s    zAskIntegerHandler.Exprc             C   s<   y"t |  }| | ds tdS  tk
r6   dS X d S )Nr   TF)introundZequals	TypeError)r   r   ir   r   r   _number   s    zAskIntegerHandler._numberc             C   s    | j rt| |S t| |tjS )z
        Integer + Integer       -> Integer
        Integer + !Integer      -> !Integer
        !Integer + !Integer -> ?
        )	is_numberr   r   r   r   integer)r   r   r   r   r   Add"   s    zAskIntegerHandler.Addc             C   s   | j rt| |S d}x|| jD ]n}tt||s|jrh|jdkrVtt	d|  |S |jd@  rdS qtt
||r|rd}qdS qdS qW |S dS )z
        Integer*Integer      -> Integer
        Integer*Irrational   -> !Integer
        Odd/Even             -> !Integer
        Integer*Rational     -> ?
        T      NF)r   r   r   argsr   r   r   is_RationalqevenZ
irrational)r   r   Z_outputargr   r   r   Mul-   s     
zAskIntegerHandler.Mulr      c             C   s   dS )NFr   )r   r   r   r   r   RationalP   s    zAskIntegerHandler.Rationalc             C   s   t t| jd |S )Nr   )r   r   r   r   )r   r   r   r   r   AbsV   s    zAskIntegerHandler.Absc             C   s   t t| jd |S )Nr   )r   r   Zinteger_elementsr   )r   r   r   r   r   MatrixElementZ   s    zAskIntegerHandler.MatrixElementN)__name__
__module____qualname____doc__staticmethodr   r   r   r"   Powr   
AlwaysTruer   ZIntegerAlwaysFalsePiExp1GoldenRatioTribonacciConstantInfinityNegativeInfinityImaginaryUnitr$   r%   r&   DeterminantTracer   r   r   r   r      s   r   c               @   s   e Zd ZdZedd Zedd ZeZedd Zee	j
Zee	jZee	jgd \ZZZZZZZed	d
 Zedd Zedd Zegd \ZZZZZee ZZdS )AskRationalHandlerze
    Handler for Q.rational
    Test that an expression belongs to the field of rational numbers
    c             C   s   | j S )N)Zis_rational)r   r   r   r   r   r   h   s    zAskRationalHandler.Exprc             C   s$   | j r|  d rdS t| |tjS )z
        Rational + Rational     -> Rational
        Rational + !Rational    -> !Rational
        !Rational + !Rational   -> ?
        r   F)r   as_real_imagr   r   rational)r   r   r   r   r   r   l   s    zAskRationalHandler.Addc             C   sP   t t| j|r$t t| j|S t t| j|rLt t| j|rLdS dS )z
        Rational ** Integer      -> Rational
        Irrational ** Rational   -> Irrational
        Rational ** Irrational   -> ?
        FN)r   r   r   r	   r:   baseZprime)r   r   r   r   r   r,   z   s
    zAskRationalHandler.Powr#   c             C   s0   | j d }tt||r,tt| |S d S )Nr   )r   r   r   r:   nonzero)r   r   xr   r   r   r	      s    
zAskRationalHandler.expc             C   s"   | j d }tt||rdS d S )Nr   F)r   r   r   r:   )r   r   r=   r   r   r   cot   s    
zAskRationalHandler.cotc             C   s4   | j d }tt||r0tt|d  |S d S )Nr   r   )r   r   r   r:   r<   )r   r   r=   r   r   r   r
      s    
zAskRationalHandler.log   N) r'   r(   r)   r*   r+   r   r   r"   r,   r   r-   r$   Z
AlwaysNoneFloatr.   r5   r3   r4   r/   r0   r1   r2   r	   r>   r
   sincostanasinatanacosacotr   r   r   r   r8   a   s   

r8   c               @   s$   e Zd Zedd Zedd ZdS )AskIrrationalHandlerc             C   s   | j S )N)Zis_irrational)r   r   r   r   r   r      s    zAskIrrationalHandler.Exprc             C   s>   t t| |}|r6t t| |}|d kr0d S | S |S d S )N)r   r   realr:   )r   r   Z_realZ	_rationalr   r   r   Basic   s    zAskIrrationalHandler.BasicN)r'   r(   r)   r+   r   rJ   r   r   r   r   rH      s   rH   c            	   @   s   e Zd ZdZedd Zedd Zedd Zedd	 Zed
d Z	ee
jgd \	ZZZZZZZZZee
jgd \ZZZedd ZeZedd Zedd Zedd Ze ZZdS )AskRealHandlerz]
    Handler for Q.real
    Test that an expression belongs to the field of real numbers
    c             C   s   | j S )N)Zis_real)r   r   r   r   r   r      s    zAskRealHandler.Exprc             C   s&   |   d d}|jdkr"| S d S )Nr   r   )r9   evalf_prec)r   r   r   r   r   r   r      s    
zAskRealHandler._numberc             C   s    | j rt| |S t| |tjS )z\
        Real + Real              -> Real
        Real + (Complex & !Real) -> !Real
        )r   rK   r   r   r   rI   )r   r   r   r   r   r      s    zAskRealHandler.Addc             C   s\   | j rt| |S d}x@| jD ]2}tt||r4qtt||rN|dA }qP qW |S dS )z
        Real*Real               -> Real
        Real*Imaginary          -> !Real
        Imaginary*Imaginary     -> Real
        TN)r   rK   r   r   r   r   rI   	imaginary)r   r   resultr!   r   r   r   r"      s    
zAskRealHandler.Mulc             C   s  | j rt| |S | jjtkrtt| jj	d |rLtt| j|rLdS | jj	d t
 t }ttd| |rttd| | j |S dS tt| j|rtt| j|rtt| j|}|dk	r| S dS tt| j|rttt| j|}|dk	r|S tt| j|rtt| j|r| jjrltt| jj|rltt| j|S tt| j|rdS tt| j|rdS tt| j|rdS dS )a]  
        Real**Integer              -> Real
        Positive**Real             -> Real
        Real**(Integer/Even)       -> Real if base is nonnegative
        Real**(Integer/Odd)        -> Real
        Imaginary**(Integer/Even)  -> Real
        Imaginary**(Integer/Odd)   -> not Real
        Imaginary**Real            -> ? since Real could be 0 (giving real) or 1 (giving imaginary)
        b**Imaginary               -> Real if log(b) is imaginary and b != 0 and exponent != integer multiple of I*pi/log(b)
        Real**Real                 -> ? e.g. sqrt(-1) is imaginary and sqrt(2) is not
        r   Tr   NF)r   rK   r   r;   funcr	   r   r   rN   r   r   r   r   rI   oddr
   r   r    r   positivenegative)r   r   r   rR   imlogr   r   r   r,      s>    

zAskRealHandler.Pow	      c             C   s   t t| jd |rdS d S )Nr   T)r   r   rI   r   )r   r   r   r   r   rA   '  s    zAskRealHandler.sinc             C   s.   t t| jd t t t| jd B |S )Nr   )r   r   r   r   r   r   rI   )r   r   r   r   r   r	   .  s    zAskRealHandler.expc             C   s   t t| jd |S )Nr   )r   r   rS   r   )r   r   r   r   r   r
   2  s    zAskRealHandler.logc             C   s   t t| jd |S )Nr   )r   r   Zreal_elementsr   )r   r   r   r   r   r&   6  s    zAskRealHandler.MatrixElementN) r'   r(   r)   r*   r+   r   r   r   r"   r,   r   r-   r$   r@   r/   r0   r1   r2   r%   reimr.   r5   r3   r4   rA   rB   r	   r
   r&   r6   r7   r   r   r   r   rK      s   

8"rK   c               @   s>   e Zd ZdZedd Zegd \ZZeej	gd \Z
ZdS )AskExtendedRealHandlerz
    Handler for Q.extended_real
    Test that an expression belongs to the field of extended real numbers,
    that is real numbers union {Infinity, -Infinity}
    c             C   s   t | |tjS )N)r   r   Zextended_real)r   r   r   r   r   r   D  s    zAskExtendedRealHandler.Addr   N)r'   r(   r)   r*   r+   r   r"   r,   r   r-   r3   r4   r   r   r   r   rZ   =  s   rZ   c               @   sN   e Zd ZdZedd Zedd Zedd Zedd	 Zegd
 \Z	Z
dS )AskHermitianHandlerzi
    Handler for Q.hermitian
    Test that an expression belongs to the field of Hermitian operators
    c             C   s    | j rt| |S t| |tjS )zb
        Hermitian + Hermitian  -> Hermitian
        Hermitian + !Hermitian -> !Hermitian
        )r   rK   r   r   r   	hermitian)r   r   r   r   r   r   S  s    zAskHermitianHandler.Addc             C   s   | j rt| |S d}d}xb| jD ]T}tt||r@|dA }ntt||sRP tt| |r"|d7 }|dkr"P q"W |S dS )z
        As long as there is at most only one noncommutative term:
        Hermitian*Hermitian         -> Hermitian
        Hermitian*Antihermitian     -> !Hermitian
        Antihermitian*Antihermitian -> Hermitian
        r   Tr   N)	r   rK   r   r   r   r   antihermitianr\   commutative)r   r   nccountrO   r!   r   r   r   r"   ]  s    
zAskHermitianHandler.Mulc             C   s>   | j rt| |S tt| j|r:tt| j|r:dS dS )z1
        Hermitian**Integer -> Hermitian
        TN)	r   rK   r   r   r   r\   r;   r   r	   )r   r   r   r   r   r,   u  s
    zAskHermitianHandler.Powc             C   s   t t| jd |rdS d S )Nr   T)r   r   r\   r   )r   r   r   r   r   rA     s    zAskHermitianHandler.sinr   N)r'   r(   r)   r*   r+   r   r"   r,   rA   rB   r	   r   r   r   r   r[   M  s   
r[   c            
   @   s   e Zd ZdZedd Zedd Zegd \ZZee	j
gd \
ZZZZZZZZZZee	jgd \ZZedd	 Ze ZZd
S )AskComplexHandlerzc
    Handler for Q.complex
    Test that an expression belongs to the field of complex numbers
    c             C   s   | j S )N)Z
is_complex)r   r   r   r   r   r     s    zAskComplexHandler.Exprc             C   s   t | |tjS )N)r   r   complex)r   r   r   r   r   r     s    zAskComplexHandler.Addr   
   c             C   s   t t| jd |S )Nr   )r   r   Zcomplex_elementsr   )r   r   r   r   r   r&     s    zAskComplexHandler.MatrixElementN)r'   r(   r)   r*   r+   r   r   r"   r,   r   r-   NumberrA   rB   r
   r	   rX   rY   NumberSymbolr%   r5   r.   r3   r4   r&   r6   r7   r   r   r   r   r`     s   $r`   c               @   s~   e Zd ZdZedd Zedd Zedd Zedd	 Zed
d Z	edd Z
edd Zedd ZeZeejZdS )AskImaginaryHandlerz
    Handler for Q.imaginary
    Test that an expression belongs to the field of imaginary numbers,
    that is, numbers in the form x*I, where x is real
    c             C   s   | j S )N)Zis_imaginary)r   r   r   r   r   r     s    zAskImaginaryHandler.Exprc             C   s&   |   d d}|jdkr"| S d S )Nr   r   r   )r9   rL   rM   )r   r   rr   r   r   r     s    
zAskImaginaryHandler._numberc             C   s~   | j rt| |S d}xb| jD ]2}tt||r4qtt||rN|d7 }qP qW |dkr`dS |dksvt| j|krzdS dS )z
        Imaginary + Imaginary -> Imaginary
        Imaginary + Complex   -> ?
        Imaginary + Real      -> !Imaginary
        r   r   TFN)	r   re   r   r   r   r   rN   rI   len)r   r   realsr!   r   r   r   r     s    
zAskImaginaryHandler.Addc             C   sp   | j rt| |S d}d}xP| jD ]0}tt||r@|dA }q"tt||s"P q"W |t| jkrhdS |S dS )zV
        Real*Imaginary      -> Imaginary
        Imaginary*Imaginary -> Real
        Fr   TN)	r   re   r   r   r   r   rN   rI   rg   )r   r   rO   rh   r!   r   r   r   r"     s    
zAskImaginaryHandler.Mulc             C   s  | j rt| |S | jjtkrtt| jj	d |rtt| j|rLdS | jj	d t
 t }ttd| |rttd| | j |S tt| j|rtt| j|rtt| j|}|dk	r|S dS tt| j|rttt| j|}|dk	rdS tt| jt| j@ |rtt| j|rDdS tt| j|}|s`|S tt| j|rxdS ttd| j |}|rtt| j|S |S dS )a  
        Imaginary**Odd        -> Imaginary
        Imaginary**Even       -> Real
        b**Imaginary          -> !Imaginary if exponent is an integer multiple of I*pi/log(b)
        Imaginary**Real       -> ?
        Positive**Real        -> Real
        Negative**Integer     -> Real
        Negative**(Integer/2) -> Imaginary
        Negative**Real        -> not Imaginary if exponent is not Rational
        r   Fr   rP   N)r   re   r   r;   rQ   r	   r   r   rN   r   r   r   r   rR   r
   rI   rS   r:   rT   )r   r   r   rR   rU   ZratZhalfr   r   r   r,     s>    
 zAskImaginaryHandler.Powc             C   s   t t| jd |r4t t| jd |r0dS d S | jd jtkrb| jd jd tt gkrbdS t t| jd |}|dkrdS d S )Nr   FT)	r   r   rI   r   rS   rQ   r	   r   rN   )r   r   rY   r   r   r   r
     s    zAskImaginaryHandler.logc             C   s2   | j d t t }ttd| t| @ |S )Nr   r   )r   r   r   r   r   r   )r   r   ar   r   r   r	   *  s    zAskImaginaryHandler.expc             C   s   |   d dk S )Nr   r   )r9   )r   r   r   r   r   rc   /  s    zAskImaginaryHandler.NumberN)r'   r(   r)   r*   r+   r   r   r   r"   r,   r
   r	   rc   rd   r   r-   r5   r   r   r   r   re     s   
3re   c               @   s4   e Zd ZdZedd Zedd Zedd ZdS )	AskAntiHermitianHandlerz
    Handler for Q.antihermitian
    Test that an expression belongs to the field of anti-Hermitian operators,
    that is, operators in the form x*I, where x is Hermitian
    c             C   s    | j rt| |S t| |tjS )zz
        Antihermitian + Antihermitian  -> Antihermitian
        Antihermitian + !Antihermitian -> !Antihermitian
        )r   re   r   r   r   r]   )r   r   r   r   r   r   ?  s    zAskAntiHermitianHandler.Addc             C   s   | j rt| |S d}d}xb| jD ]T}tt||r@|dA }ntt||sRP tt| |r"|d7 }|dkr"P q"W |S dS )z
        As long as there is at most only one noncommutative term:
        Hermitian*Hermitian         -> !Antihermitian
        Hermitian*Antihermitian     -> Antihermitian
        Antihermitian*Antihermitian -> !Antihermitian
        r   FTr   N)	r   re   r   r   r   r   r]   r\   r^   )r   r   r_   rO   r!   r   r   r   r"   I  s    
zAskAntiHermitianHandler.Mulc             C   s~   | j rt| |S tt| j|r<tt| j|rzdS n>tt	| j|rztt
| j|rddS tt| j|rzdS dS )z
        Hermitian**Integer  -> !Antihermitian
        Antihermitian**Even -> !Antihermitian
        Antihermitian**Odd  -> Antihermitian
        FTN)r   re   r   r   r   r\   r;   r   r	   r]   r    rR   )r   r   r   r   r   r,   a  s    zAskAntiHermitianHandler.PowN)r'   r(   r)   r*   r+   r   r"   r,   r   r   r   r   rj   8  s   
rj   c               @   s   e Zd ZdZedd Zedd Zedd Zedd	 Zee	j
gd
 \ZZZZZee	jgd
 \ZZZZZedd Zedd Zedd Zegd
 \ZZZZZee ZZdS )AskAlgebraicHandlerzHandler for Q.algebraic key. c             C   s   t | |tjS )N)r   r   	algebraic)r   r   r   r   r   r   w  s    zAskAlgebraicHandler.Addc             C   s   t | |tjS )N)r   r   rl   )r   r   r   r   r   r"   {  s    zAskAlgebraicHandler.Mulc             C   s   | j jott| j|S )N)r	   r   r   r   rl   r;   )r   r   r   r   r   r,     s    
zAskAlgebraicHandler.Powc             C   s
   | j dkS )Nr   )r   )r   r   r   r   r   r$     s    zAskAlgebraicHandler.Rationalr?   c             C   s0   | j d }tt||r,tt| |S d S )Nr   )r   r   r   rl   r<   )r   r   r=   r   r   r   r	     s    
zAskAlgebraicHandler.expc             C   s"   | j d }tt||rdS d S )Nr   F)r   r   r   rl   )r   r   r=   r   r   r   r>     s    
zAskAlgebraicHandler.cotc             C   s4   | j d }tt||r0tt|d  |S d S )Nr   r   )r   r   r   rl   r<   )r   r   r=   r   r   r   r
     s    
zAskAlgebraicHandler.logN) r'   r(   r)   r*   r+   r   r"   r,   r$   r   r-   r@   r1   r2   r5   ZAlgebraicNumberr.   r3   r4   ZComplexInfinityr/   r0   r	   r>   r
   rA   rB   rC   rD   rE   rF   rG   r   r   r   r   rk   t  s   rk   N)r*   Z
__future__r   r   Zsympy.assumptionsr   r   Zsympy.assumptions.handlersr   r   Zsympy.core.numbersr   Z&sympy.functions.elementary.exponentialr	   r
   Zsympyr   r   r8   rH   rK   rZ   r[   r`   re   rj   rk   r   r   r   r   <module>   s$   TD ; <