o
    8VaK                     @   s  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 d dl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 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$ dd Z%dd Z&G dd deZ'G dd de'Z(dS )    )Add)is_sequenceTuple)Expr)Mul)Equality
Relational)S)SymbolDummy)sympify)piecewise_fold	Piecewise)BooleanFunction)Idx)Interval)Range)flatten)sift)SymPyDeprecationWarningc                 O   s  t |}t|trAt| \}}|rtdd |D s$tddddd  |j}|j}t| |g|R i || |g|R i |S |t	j
u rIt	j
S |rut| \}}t|D ]\}}	t|	dkrs||	d	 |	d
 }t|	dd
  ||< qUn|j}
t|
dkrtd| dd |
D d}}| t|krt|j| }|j}| t|ksi }dd |D }|tD ]}|j| st ||< q||}t|}|dd | D }|||fS )zReturn either a special return value or the tuple,
    (function, limits, orientation). This code is common to
    both ExprWithLimits and AddWithLimits.c                 s   s    | ]	}t |d kV  qdS    Nlen).0limit r   A/usr/lib/python3/dist-packages/sympy/concrete/expr_with_limits.py	<genexpr>   s    z_common_new.<locals>.<genexpr>zIntegral(Eq(x, y))z"Eq(Integral(x, z), Integral(y, z))iF  g?)ZfeatureZ
useinsteadZissueZdeprecated_since_version   r   N   zspecify dummy variables for %sc                 S   s   g | ]}t |qS r   r   )r   sr   r   r   
<listcomp>;       z_common_new.<locals>.<listcomp>c                 S   s   h | ]}|d  qS r   r   r   ir   r   r   	<setcomp>F   r%   z_common_new.<locals>.<setcomp>c                 S   s   i | ]\}}||qS r   r   )r   kvr   r   r   
<dictcomp>O   s    z_common_new.<locals>.<dictcomp>)r   
isinstancer   _process_limitsallr   warnlhsrhsr
   ZNaN	enumerater   subsr   free_symbols
ValueErrortypelistlimitsfunctionatomsr   hasr   Zxreplacer   items)clsr:   symbolsassumptionsr9   orientationr1   r2   r(   ZlifreeZrepsZsymbols_of_integrationpr   r   r   _common_new   s\   





rD   c            	   	   G   s.  g }d}| D ]}t |ttfr|t }|| f}t |ts(t|ddrSt |trK|j	du s7|j
du r?|t| n|t||j	|j
 n|t| qt|trt|dkrt |d tr|d j}|d j}t|d j}|d gd|| | ||d  | g }tt|}t |d ttfst|d ddr|d }t|dkrt |d tr|d j|d jg|dd< n$t|dkr|d du r|d dur|d9 }|gd	d
 |dd D  }t |trt|dkrt|dkr|t|  qt|dkr\t |trT|j	|j
}}z|dur)t|d |ks)tdW n
 ty4   Y nw z|durHt|d |ksHtdW n
 tyS   Y nw |t|  qt|dksqt|dkry|d du ry|t| qt|dkr|t||d  qtdt|  ||fS )a  Process the list of symbols and convert them to canonical limits,
    storing them as Tuple(symbol, lower, upper). The orientation of
    the function is also returned when the upper limit is missing
    so (x, 1, None) becomes (x, None, 1) and the orientation is changed.
    r"   	_diff_wrtFN   r   r   r!   c                 S   s   g | ]}|d ur|qS Nr   r'   r   r   r   r$   z       z#_process_limits.<locals>.<listcomp>r    z%Summation will set Idx value too low.z&Summation will set Idx value too high.zInvalid limits given: %s)r-   r	   r   r;   r   popZas_setgetattrr   lowerupperappendr   r   r   r   infsupabsstepr   r   r   startendboolr6   	TypeErrorstr)	r?   r9   rA   VvariablelohiZdxZ	newsymbolr   r   r   r.   T   sv   



($*r.   c                   @   s   e Zd ZdZ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dd Zdd Zedd Zedd ZdS )ExprWithLimits)is_commutativec           	      O   s   t | |g|R i |}t|tu r|\}}}n|S tdd |D r'tdtj| fi |}|g}|| t||_|j	|_	|S )Nc                 s   s$    | ]}t |d kpd|v V  qdS r   r   r   lr   r   r   r      s   " z)ExprWithLimits.__new__.<locals>.<genexpr>z:ExprWithLimits requires values for lower and upper bounds.)
rD   r7   tupleanyr6   r   __new__extend_argsr\   )	r>   r:   r?   r@   prer9   _objarglistr   r   r   ra      s   

zExprWithLimits.__new__c                 C   s
   | j d S )a%  Return the function applied across limits.

        Examples
        ========

        >>> from sympy import Integral
        >>> from sympy.abc import x
        >>> Integral(x**2, (x,)).function
        x**2

        See Also
        ========

        limits, variables, free_symbols
        r   rc   selfr   r   r   r:      s   
zExprWithLimits.functionc                 C   s   | j jS rG   )r:   kindri   r   r   r   rk      s   zExprWithLimits.kindc                 C   s   | j dd S )a+  Return the limits of expression.

        Examples
        ========

        >>> from sympy import Integral
        >>> from sympy.abc import x, i
        >>> Integral(x**i, (i, 1, 3)).limits
        ((i, 1, 3),)

        See Also
        ========

        function, variables, free_symbols
        r"   Nrh   ri   r   r   r   r9      s   zExprWithLimits.limitsc                 C      dd | j D S )a  Return a list of the limit variables.

        >>> from sympy import Sum
        >>> from sympy.abc import x, i
        >>> Sum(x**i, (i, 1, 3)).variables
        [i]

        See Also
        ========

        function, limits, free_symbols
        as_dummy : Rename dummy variables
        sympy.integrals.integrals.Integral.transform : Perform mapping on the dummy variable
        c                 S   s   g | ]}|d  qS r&   r   r]   r   r   r   r$      r%   z,ExprWithLimits.variables.<locals>.<listcomp>r9   ri   r   r   r   	variables   s   zExprWithLimits.variablesc                 C   rl   )a  Return only variables that are dummy variables.

        Examples
        ========

        >>> from sympy import Integral
        >>> from sympy.abc import x, i, j, k
        >>> Integral(x**i, (i, 1, 3), (j, 2), k).bound_symbols
        [i, j]

        See Also
        ========

        function, limits, free_symbols
        as_dummy : Rename dummy variables
        sympy.integrals.integrals.Integral.transform : Perform mapping on the dummy variable
        c                 S   s    g | ]}t |d kr|d qS )r"   r   r   r]   r   r   r   r$          z0ExprWithLimits.bound_symbols.<locals>.<listcomp>rm   ri   r   r   r   bound_symbols   s   zExprWithLimits.bound_symbolsc                 C   sv   | j | j}}|j}|D ],}t|dkr||d  q|d |v r)||d  |dd D ]}||j q/q|S )a4  
        This method returns the symbols in the object, excluding those
        that take on a specific value (i.e. the dummy symbols).

        Examples
        ========

        >>> from sympy import Sum
        >>> from sympy.abc import x, y
        >>> Sum(x, (x, y, 1)).free_symbols
        {y}
        r"   r   N)r:   r9   r5   r   addremoveupdate)rj   r:   r9   Zisymsxabr(   r   r   r   r5   	  s   zExprWithLimits.free_symbolsc                 C   s   | j  S )z7Return True if the Sum has no free symbols, else False.)r5   ri   r   r   r   	is_number(  s   zExprWithLimits.is_numberc                    s0    fdd| j D }| j}| j|g|R  S )Nc                    s&   g | ]}|d  kr|n fqS r&   r   r'   abxr   r   r$   .  s   & z1ExprWithLimits._eval_interval.<locals>.<listcomp>)r9   r:   func)rj   ry   rw   rx   r9   Z	integrandr   rv   r   _eval_interval-  s   zExprWithLimits._eval_intervalc                    s  ddl m}m} | jt| j}}|  ttr!j	
| j	rd}t|D ]D\}}	dt|	krB|	d krB jr> f}	nf}	t|	d g fdd|	dd D R  ||< t|	d j	
j	dkrkd} nq't|svt|rt| j
t t}
t| j
tj}|
|std	d}|r| }n/t|D ]*\}}	t|	d
krt|	d g fdd|	dd D R  ||< |	d kr nqt|D ]\}}	t|	dkr|	d |	d  jrt|	d ||< q|  | j|g|R  S )a  
        Perform substitutions over non-dummy variables
        of an expression with limits.  Also, can be used
        to specify point-evaluation of an abstract antiderivative.

        Examples
        ========

        >>> from sympy import Sum, oo
        >>> from sympy.abc import s, n
        >>> Sum(1/n**s, (n, 1, oo)).subs(s, 2)
        Sum(n**(-2), (n, 1, oo))

        >>> from sympy import Integral
        >>> from sympy.abc import x, a
        >>> Integral(a*x**2, x).subs(x, 4)
        Integral(a*x**2, (x, 4))

        See Also
        ========

        variables : Lists the integration variables
        transform : Perform mapping on the dummy variable for integrals
        change_index : Perform mapping on the sum and product dummy variables

        r   )AppliedUndefUndefinedFunctionTr"   c                       g | ]}|  qS r   Z_subsr]   newoldr   r   r$   d  rH   z-ExprWithLimits._eval_subs.<locals>.<listcomp>NFz.substitution can not create dummy dependenciesr   c                    r~   r   r   r]   r   r   r   r$   u  rH   rF   )Zsympy.core.functionr|   r}   r:   r8   r9   reverser-   r   r5   intersectionr3   r   rE   r   setrn   r;   argsissubsetr6   r4   Zis_zerorz   )rj   r   r   r|   r}   rz   r9   Zsub_into_funcr(   rt   Zsy2Zsy1r   r   r   
_eval_subs2  sP   
0
0zExprWithLimits._eval_subsc                 C   s   d}| j D ]8}t|dkr4tdd |dd D r dS tdd |dd D r3|d jdu r3d	}q|d jdu r=d	}q|rBdS d	S )
a#  
        Returns True if the limits are known to be finite, either by the
        explicit bounds, assumptions on the bounds, or assumptions on the
        variables.  False if known to be infinite, based on the bounds.
        None if not enough information is available to determine.

        Examples
        ========

        >>> from sympy import Sum, Integral, Product, oo, Symbol
        >>> x = Symbol('x')
        >>> Sum(x, (x, 1, 8)).has_finite_limits
        True

        >>> Integral(x, (x, 1, oo)).has_finite_limits
        False

        >>> M = Symbol('M')
        >>> Sum(x, (x, 1, M)).has_finite_limits

        >>> N = Symbol('N', integer=True)
        >>> Product(x, (x, 1, N)).has_finite_limits
        True

        See Also
        ========

        has_reversed_limits

        Fr   c                 s   s    | ]}|j V  qd S rG   is_infiniter]   r   r   r   r     s    z3ExprWithLimits.has_finite_limits.<locals>.<genexpr>r"   Nc                 s   s    | ]}|j d u V  qd S rG   r   r]   r   r   r   r     s    r   T)r9   r   r`   r   )rj   ret_Nonelimr   r   r   has_finite_limits  s   !
z ExprWithLimits.has_finite_limitsc                 C   sX   d}| j D ] }t|dkr#|\}}}|| }|jr dS |jr qd}q dS |r*dS dS )a  
        Returns True if the limits are known to be in reversed order, either
        by the explicit bounds, assumptions on the bounds, or assumptions on the
        variables.  False if known to be in normal order, based on the bounds.
        None if not enough information is available to determine.

        Examples
        ========

        >>> from sympy import Sum, Integral, Product, oo, Symbol
        >>> x = Symbol('x')
        >>> Sum(x, (x, 8, 1)).has_reversed_limits
        True

        >>> Sum(x, (x, 1, oo)).has_reversed_limits
        False

        >>> M = Symbol('M')
        >>> Integral(x, (x, 1, M)).has_reversed_limits

        >>> N = Symbol('N', integer=True, positive=True)
        >>> Sum(x, (x, 1, N)).has_reversed_limits
        False

        >>> Product(x, (x, 2, N)).has_reversed_limits

        >>> Product(x, (x, 2, N)).subs(N, N + 2).has_reversed_limits
        False

        See Also
        ========

        sympy.concrete.expr_with_intlimits.ExprWithIntLimits.has_empty_sequence

        Fr   TN)r9   r   Zis_extended_negativeZis_extended_nonnegative)rj   r   r   varrw   rx   Zdifr   r   r   has_reversed_limits  s   %

z"ExprWithLimits.has_reversed_limitsN)__name__
__module____qualname__	__slots__ra   propertyr:   rk   r9   rn   rp   r5   ru   r{   r   r   r   r   r   r   r   r[      s.    






P
2r[   c                   @   s@   e Zd ZdZdd Zdd Zdd Zdd	 Zd
d Zdd Z	dS )AddWithLimitszZRepresents unevaluated oriented additions.
        Parent class for Integral and Sum.
    c           	      O   sp   t | |g|R i |}t|tu r|\}}}n|S tj| fi |}|| g}|| t||_|j|_|S rG   )rD   r7   r_   r   ra   rb   rc   r\   )	r>   r:   r?   r@   rd   r9   rA   rf   rg   r   r   r   ra     s   


zAddWithLimits.__new__c                 C   6   t dd t| jD r| j| j g| jR  S d S )Nc                 S      g | ]}|j qS r   Zis_realr   ry   r   r   r   r$         z/AddWithLimits._eval_adjoint.<locals>.<listcomp>)r/   r   r9   rz   r:   Zadjointri   r   r   r   _eval_adjoint      zAddWithLimits._eval_adjointc                 C   r   )Nc                 S   r   r   r   r   r   r   r   r$     r   z1AddWithLimits._eval_conjugate.<locals>.<listcomp>)r/   r   r9   rz   r:   	conjugateri   r   r   r   _eval_conjugate  r   zAddWithLimits._eval_conjugatec                 C   r   )Nc                 S   r   r   r   r   r   r   r   r$     r   z1AddWithLimits._eval_transpose.<locals>.<listcomp>)r/   r   r9   rz   r:   Z	transposeri   r   r   r   _eval_transpose
  r   zAddWithLimits._eval_transposec                    s   dt  jkr3 jjdi |}|jr1t|j fdd}t|d   jt|d  g jR   S  S  j jg jdd R   }|	 j
d sZ d jd g | S t|trj | jd  S  S )	Nr"   c                    s   | j ot j| j@  S rG   )r\   r   rn   r5   )wri   r   r   <lambda>  s    z,AddWithLimits._eval_factor.<locals>.<lambda>TFr   r!   r   )r   r9   r:   ZfactorZis_Mulr   r   r   rz   r<   rn   Zdoitr-   )rj   hintssummandoutr   ri   r   _eval_factor  s   
"
zAddWithLimits._eval_factorc                    s   ddl m}  jjdi |}|jr!|jr!t fdd|jD  S t||r/|	 fddS | jkr> j
|g jR  S  S )Nr   )
MatrixBasec                    s    g | ]} j |g jR  qS r   rz   r9   r'   ri   r   r   r$   $  ro   z4AddWithLimits._eval_expand_basic.<locals>.<listcomp>c                    s    j | g jR  S rG   r   )ry   ri   r   r   r   &  r%   z2AddWithLimits._eval_expand_basic.<locals>.<lambda>r   )Zsympy.matrices.matricesr   r:   expandZis_Addr\   r   r   r-   Z	applyfuncrz   r9   )rj   r   r   r   r   ri   r   _eval_expand_basic  s   

z AddWithLimits._eval_expand_basicN)
r   r   r   __doc__ra   r   r   r   r   r   r   r   r   r   r     s    r   N))Zsympy.core.addr   Zsympy.core.compatibilityr   Zsympy.core.containersr   Zsympy.core.exprr   Zsympy.core.mulr   Zsympy.core.relationalr   r	   Zsympy.core.singletonr
   Zsympy.core.symbolr   r   Zsympy.core.sympifyr   Z$sympy.functions.elementary.piecewiser   r   Zsympy.logic.boolalgr   Zsympy.tensor.indexedr   Zsympy.sets.setsr   Zsympy.sets.fancysetsr   Zsympy.utilitiesr   Zsympy.utilities.iterablesr   Zsympy.utilities.exceptionsr   rD   r.   r[   r   r   r   r   r   <module>   s.    ?M  M