U
    9%ez2                    @   sR  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
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 ddlmZ ddlmZ d dl m!Z! G dd dZ"eej#Z$dd Z%dd Z&G dd deeZ'edZ(d&ddZ)d'dd Z*d!d" Z+dd#l,m-Z- dd$l.m/Z/ dd%l0m1Z1m2Z2 dS )(    )Tuple)defaultdict)
cmp_to_keyreduce)productN   )sympify)Basic)S)AssocOpAssocOpDispatcher)cacheit)	fuzzy_not_fuzzy_group)Expr)global_parameters)KindDispatcher	bottom_up)siftc                   @   s    e Zd ZdZdZdZdZdZdS )	NC_MarkerFN)__name__
__module____qualname__is_Orderis_Mul	is_NumberZis_Polyis_commutative r   r   M/var/www/html/Darija-Ai-API/env/lib/python3.8/site-packages/sympy/core/mul.pyr      s
   r   c                 C   s   | j td d S )Nkey)sort_args_sortkeyargsr   r   r   _mulsort!   s    r&   c                  G   s   t | } g }g }tj}| rp|  }|jrT| \}}| | |rn|t	| q|j
rd||9 }q|| qt| |tjk	r|d| |r|t	| t	|S )a   Return a well-formed unevaluated Mul: Numbers are collected and
    put in slot 0, any arguments that are Muls will be flattened, and args
    are sorted. Use this when args have changed but you still want to return
    an unevaluated Mul.

    Examples
    ========

    >>> from sympy.core.mul import _unevaluated_Mul as uMul
    >>> from sympy import S, sqrt, Mul
    >>> from sympy.abc import x
    >>> a = uMul(*[S(3.0), x, S(2)])
    >>> a.args[0]
    6.00000000000000
    >>> a.args[1]
    x

    Two unevaluated Muls with the same arguments will
    always compare as equal during testing:

    >>> m = uMul(sqrt(2), sqrt(3))
    >>> m == uMul(sqrt(3), sqrt(2))
    True
    >>> u = Mul(sqrt(3), sqrt(2), evaluate=False)
    >>> m == uMul(u)
    True
    >>> m == Mul(*m.args)
    False

    r   )listr
   Onepopr   args_cncextendappendMul
_from_argsr   r&   insert)r%   ZnewargsZncargscoacncr   r   r   _unevaluated_Mul&   s(    


r4   c                       s  e Zd ZU dZdZee ed< dZeZ	e
dddZedd Zd	d
 Zdd Zedd Zdd Zedd Zdd Zedd Zedd ZeddddZdddZddd Zed!d" Zd#d$ Zed%d& Ze fd'd(Zd)d* Z d+d, Z!dd.d/Z"ed0d1 Z#edd2d3Z$ed4d5 Z%ed6d7 Z&ed8d9 Z'ed:d; Z(ed<d= Z)d>d? Z*d@dA Z+dBdC Z,dDdE Z-dFdG Z.dHdI Z/dJdK Z0dLdM Z1dNdO Z2dPdQ Z3dRdS Z4dTdU Z5dVdW Z6dXdY Z7dZd[ Z8d\d] Z9d^d_ Z:d`da Z;dbdc Z<ddde Z=dfdg Z>dhdi Z?djdk Z@dldm ZAdndo ZBdpdq ZCdrds ZDdtdu ZEdvdw ZFdxdy ZGdd{d|ZHdd}d~ZIdd ZJdd ZKdd ZLdddZMdddZNedd ZO  ZPS )r-   aB  
    Expression representing multiplication operation for algebraic field.

    .. deprecated:: 1.7

       Using arguments that aren't subclasses of :class:`~.Expr` in core
       operators (:class:`~.Mul`, :class:`~.Add`, and :class:`~.Pow`) is
       deprecated. See :ref:`non-expr-args-deprecated` for details.

    Every argument of ``Mul()`` must be ``Expr``. Infix operator ``*``
    on most scalar objects in SymPy calls this class.

    Another use of ``Mul()`` is to represent the structure of abstract
    multiplication so that its arguments can be substituted to return
    different class. Refer to examples section for this.

    ``Mul()`` evaluates the argument unless ``evaluate=False`` is passed.
    The evaluation logic includes:

    1. Flattening
        ``Mul(x, Mul(y, z))`` -> ``Mul(x, y, z)``

    2. Identity removing
        ``Mul(x, 1, y)`` -> ``Mul(x, y)``

    3. Exponent collecting by ``.as_base_exp()``
        ``Mul(x, x**2)`` -> ``Pow(x, 3)``

    4. Term sorting
        ``Mul(y, x, 2)`` -> ``Mul(2, x, y)``

    Since multiplication can be vector space operation, arguments may
    have the different :obj:`sympy.core.kind.Kind()`. Kind of the
    resulting object is automatically inferred.

    Examples
    ========

    >>> from sympy import Mul
    >>> from sympy.abc import x, y
    >>> Mul(x, 1)
    x
    >>> Mul(x, x)
    x**2

    If ``evaluate=False`` is passed, result is not evaluated.

    >>> Mul(1, 2, evaluate=False)
    1*2
    >>> Mul(x, x, evaluate=False)
    x*x

    ``Mul()`` also represents the general structure of multiplication
    operation.

    >>> from sympy import MatrixSymbol
    >>> A = MatrixSymbol('A', 2,2)
    >>> expr = Mul(x,y).subs({y:A})
    >>> expr
    x*A
    >>> type(expr)
    <class 'sympy.matrices.expressions.matmul.MatMul'>

    See Also
    ========

    MatMul

    r   r%   TZMul_kind_dispatcher)Zcommutativec                 C   s   dd | j D }| j| S )Nc                 s   s   | ]}|j V  qd S N)kind.0r1   r   r   r   	<genexpr>   s     zMul.kind.<locals>.<genexpr>)r%   _kind_dispatcher)selfZ	arg_kindsr   r   r   r6      s    zMul.kindc                 C   s$   | |  krdS | j d }|jo"|jS )NFr   )r%   r   is_extended_negative)r;   r2   r   r   r   could_extract_minus_sign   s    

zMul.could_extract_minus_signc                 C   s   |   \}}|d tjk	r | }|tjk	rr|d jrht|}|tjkrV|d  |d< qr|d  |9  < n
|f| }| || jS Nr   )	as_coeff_mulr
   ComplexInfinityr(   r   r'   NegativeOner.   r   )r;   r2   r%   r   r   r   __neg__   s    



zMul.__neg__c           1         sH
  ddl m} ddlm  d}t|dkr|\jrH g}tjk	sVtj	sjr
 \}jr|tjk	r| }|tjkr}n| | dd}|gg df}n0tjrjrtfdd	jD  }|gg df}|r|S g }g }	g }
tjg }g }tj}i }d}|D ]}|jr6||\}}|jr|jrT||j n6|jD ]$}|jrr|| n
|
| qZ|t qq|jr|tjkstjkr|j	rtjgg df  S jst|r|9 tjkrtjgg df  S qqt||r,|qq|tjkr^sPtjgg df  S tjqq|tjkr||tj7 }qq|jrN| \}|j r>jr>|jr|j!rĈt"|9 qn4|j#r|t"| qnj#r||7 } tjk	r|$g | qn"j%s,|j&r>||f q||f n|tk	rb|
| |
r|
'd}|	s|	| qb|	' }| \}}| \}}|| }||kr|js|| }|jr|| qbn|
(d| n|	||g qbqd
d }||}||}t)dD ]*}g }d}|D ]\}|j	rjsVjr6t*fddtjtj+tj,fD r6tjgg df    S q6|tjkrjr9 q6}|tjk	rt"|}|j rj s}| \}|krd}|| ||f q6|rHtdd |D t|krHg }||}n qRq$i } |D ]\}| $|g  qZ| - D ]\}|  | |< q|dd	 | - D  i }!|- D ] \}|!$t| g  q~g }"|!- D ]x\}|  |j.dkrt"|9 q|j/|j.krTt0|j/|j.\}#}$t"|#9 t1|$|j.}|"|f q~!t2t3}%d}|t|"k r|"| \}}&g }'t)|d t|"D ]}(|"|( \})}*|4|)}+|+tjk	r|&|* }|j.dkrt"|+|9 nH|j/|j.kr(t0|j/|j.\}#}$t"|+|#9 t1|$|j.}|'|+|f |)|+ |*f|"|(< ||+ }|tjkr qdq|tjk	rt"||&},|,jr|,9 nHt56|,D ]<},|,jr|,9 n$|,j st|,j\}}&|%|& | q|"|' |d7 }qt|%- D ]\}|  |%|< q|r|7 \}}t0||\}-}|-d r: |dkrR|tj n\|rt1||}|%- D ],\}||krjj%rj |%|<  qqj|t"tj8|dd |dd	 |%- D  tj+tj,fk	rdd }.|.|d\}}/|.|	|/\}	}/|/9 tjk	r.dd	 |D }dd	 |	D }	nZj		rt* fdd|	D 	rZg|	|fS t*dd |D 	r|tjgg |fS gg |fS g }0|D ]"}|j	r|9 n
|0| 	q|0}t9| tjk		r|(d tj
r>|	
s>t|dk
r>|d j
r>|d j:
r>|d j
r>|d tfdd	|d jD  g}||	|fS )a.  Return commutative, noncommutative and order arguments by
        combining related terms.

        Notes
        =====
            * In an expression like ``a*b*c``, Python process this through SymPy
              as ``Mul(Mul(a, b), c)``. This can have undesirable consequences.

              -  Sometimes terms are not combined as one would like:
                 {c.f. https://github.com/sympy/sympy/issues/4596}

                >>> from sympy import Mul, sqrt
                >>> from sympy.abc import x, y, z
                >>> 2*(x + 1) # this is the 2-arg Mul behavior
                2*x + 2
                >>> y*(x + 1)*2
                2*y*(x + 1)
                >>> 2*(x + 1)*y # 2-arg result will be obtained first
                y*(2*x + 2)
                >>> Mul(2, x + 1, y) # all 3 args simultaneously processed
                2*y*(x + 1)
                >>> 2*((x + 1)*y) # parentheses can control this behavior
                2*y*(x + 1)

                Powers with compound bases may not find a single base to
                combine with unless all arguments are processed at once.
                Post-processing may be necessary in such cases.
                {c.f. https://github.com/sympy/sympy/issues/5728}

                >>> a = sqrt(x*sqrt(y))
                >>> a**3
                (x*sqrt(y))**(3/2)
                >>> Mul(a,a,a)
                (x*sqrt(y))**(3/2)
                >>> a*a*a
                x*sqrt(y)*sqrt(x*sqrt(y))
                >>> _.subs(a.base, z).subs(z, a.base)
                (x*sqrt(y))**(3/2)

              -  If more than two terms are being multiplied then all the
                 previous terms will be re-processed for each new argument.
                 So if each of ``a``, ``b`` and ``c`` were :class:`Mul`
                 expression, then ``a*b*c`` (or building up the product
                 with ``*=``) will process all the arguments of ``a`` and
                 ``b`` twice: once when ``a*b`` is computed and again when
                 ``c`` is multiplied.

                 Using ``Mul(a, b, c)`` will process all arguments once.

            * The results of Mul are cached according to arguments, so flatten
              will only be called once for ``Mul(a, b, c)``. If you can
              structure a calculation so the arguments are most likely to be
              repeats then this can save time in computing the answer. For
              example, say you had a Mul, M, that you wished to divide by ``d[i]``
              and multiply by ``n[i]`` and you suspect there are many repeats
              in ``n``. It would be better to compute ``M*n[i]/d[i]`` rather
              than ``M/d[i]*n[i]`` since every time n[i] is a repeat, the
              product, ``M*n[i]`` will be returned without flattening -- the
              cached value will be returned. If you divide by the ``d[i]``
              first (and those are more unique than the ``n[i]``) then that will
              create a new Mul, ``M/d[i]`` the args of which will be traversed
              again when it is multiplied by ``n[i]``.

              {c.f. https://github.com/sympy/sympy/issues/5706}

              This consideration is moot if the cache is turned off.

            NB
            --
              The validity of the above notes depends on the implementation
              details of Mul and flatten which may change at any time. Therefore,
              you should only consider them when your code is highly performance
              sensitive.

              Removal of 1 from the sequence is already handled by AssocOp.__new__.
        r   )AccumBounds
MatrixExprN   Fevaluatec                    s   g | ]}t  |qS r   _keep_coeff)r8   bi)r1   r   r   
<listcomp>)  s     zMul.flatten.<locals>.<listcomp>c                    s   i }| D ]2\ }|  }| i |d g |d  q| D ]&\ }| D ]\}}t| ||< qTqDg }| D ]$\ }| fdd| D  qx|S )Nr   r   c                    s   g | ]\}} || fqS r   r   )r8   tr2   br   r   rL     s     z0Mul.flatten.<locals>._gather.<locals>.<listcomp>)as_coeff_Mul
setdefaultr,   itemsAddr+   )c_powersZcommon_ber0   dZdiZlinew_c_powersr   rN   r   _gather  s      zMul.flatten.<locals>._gatherc                 3   s   | ]}| j kV  qd S r5   r$   )r8   ZinftyrN   r   r   r9     s   zMul.flatten.<locals>.<genexpr>Tc                 S   s   h | ]\}}|qS r   r   )r8   rO   rU   r   r   r   	<setcomp>  s    zMul.flatten.<locals>.<setcomp>c                 S   s   g | ]\}}|rt ||qS r   Powr8   rU   rO   r   r   r   rL   +  s      r   c                 S   s   g | ]\}}t ||qS r   rZ   r\   r   r   r   rL     s     c                 S   s8   g }| D ]&}|j rq|jr$|d9 }q|| q||fS N)is_extended_positiver<   r,   )c_part
coeff_signZ
new_c_partrM   r   r   r   _handle_for_oo  s    z#Mul.flatten.<locals>._handle_for_ooc                 S   s$   g | ]}t |jr|jd k	s|qS r5   r   is_zerois_extended_realr8   r2   r   r   r   rL     s     

c                 S   s$   g | ]}t |jr|jd k	s|qS r5   rc   rf   r   r   r   rL     s     

c                 3   s   | ]}t | V  qd S r5   )
isinstancerf   rD   r   r   r9     s     c                 s   s   | ]}|j d kV  qdS FN	is_finiterf   r   r   r   r9     s     c                    s   g | ]} | qS r   r   r8   fcoeffr   r   rL     s     );Z!sympy.calculus.accumulationboundsrC   Zsympy.matrices.expressionsrE   lenis_Rationalr
   r(   AssertionErrorrd   rP   is_Addr   Z
distributer   rS   r%   Zeror   Zas_expr_variablesr   r+   r,   r   r   NaNr@   rg   __mul__ImaginaryUnitHalfas_base_expis_Pow
is_Integerr[   is_negativerQ   is_positive
is_integerr)   r/   rangeanyInfinityNegativeInfinityrR   qpdivmodRationalr   r'   gcdr-   	make_argsas_numer_denomrA   r&   rj   )1clsseqrC   rvrarZarbZnewbr`   Znc_partZnc_seqrT   Znum_expZneg1eZpnum_ratZorder_symbolsor   rU   Zo1b1e1b2e2Znew_expZo12rX   irW   changedr   rK   Zinv_exp_dictZcomb_eZnum_ratZe_iepZpneweiZgrowjZbjZejgobjnrb   ra   _newr   )rE   r1   rO   rn   r   flatten   s   O





 


























zMul.flattenc                    s  | j dd\}} jr@t fdd|D  tt| dd S  jr jdkr| jr|  d }|jrddl	m
} t|d  \}}||d\}}|r||d\}}|rd	d
lm}	 t|| }
t|
 j d|	|tj   j S t|  dd} js jr| S |S )NF)Zsplit_1c                    s   g | ]}t | d dqS )FrG   rZ   r8   rO   rU   r   r   rL     s     z#Mul._eval_power.<locals>.<listcomp>rG   rF   r   )integer_nthrootr   sign)r*   rz   r-   r[   r.   rp   r   is_imaginaryas_real_imagpowerr   absr   $sympy.functions.elementary.complexesr   r   r4   r   r
   rv   is_FloatZ_eval_expand_power_base)r;   rU   Zcargsr3   r1   r   r   rV   rM   r   r   r   r   r   r   _eval_power  s,    $zMul._eval_powerc                 C   s   dd| j fS )N   r   )r   r   r   r   r   	class_key  s    zMul.class_keyc                 C   sh   |   \}}|tjkrJ|jr,t|| }qV||}|d k	rB|}| }nt| |}|jrd| S |S r5   )rP   r
   rA   r   r   _eval_evalf	is_numberexpand)r;   precr2   mr   Zmnewr   r   r   r     s    

zMul._eval_evalfc                 C   s>   ddl m} |  \}}|tjk	r*td|dj||jfS )z;
        Convert self to an mpmath mpc if possible
        r   )Floatz7Cannot convert Mul to mpc. Must be of the form Number*Ir   )numbersr   rP   r
   rv   AttributeErrorZ_mpf_)r;   r   Zim_partZ	imag_unitr   r   r   _mpc_  s
    
z	Mul._mpc_c                 C   sJ   | j }t|dkrtj| fS t|dkr,|S |d | j|dd  fS dS )ao  Return head and tail of self.

        This is the most efficient way to get the head and tail of an
        expression.

        - if you want only the head, use self.args[0];
        - if you want to process the arguments of the tail then use
          self.as_coef_mul() which gives the head and a tuple containing
          the arguments of the tail when treated as a Mul.
        - if you want the coefficient when self is treated as an Add
          then use self.as_coeff_add()[0]

        Examples
        ========

        >>> from sympy.abc import x, y
        >>> (3*x*y).as_two_terms()
        (3, x*y)
        r   rF   r   N)r%   ro   r
   r(   _new_rawargs)r;   r%   r   r   r   as_two_terms  s    
zMul.as_two_terms)rationalc                   s    r2t | j fdddd\}}| j| t|fS | j}|d jr|rP|d jrd|d |dd  fS |d jrtj|d  f|dd   fS tj	|fS )Nc                    s
   | j   S r5   )hasxdepsr   r   <lambda>0      z"Mul.as_coeff_mul.<locals>.<lambda>T)binaryr   r   )
r   r%   r   tupler   rp   r<   r
   rA   r(   )r;   r   r   kwargsl1l2r%   r   r   r   r?   -  s    

zMul.as_coeff_mulFc                 C   sz   | j d | j dd  }}|jrp|r*|jrRt|dkrB||d fS || j| fS n|jrptj| j| f|  fS tj| fS )zC
        Efficiently extract the coefficient of a product.
        r   r   N)	r%   r   rp   ro   r   r<   r
   rA   r(   )r;   r   rn   r%   r   r   r   rP   :  s    
zMul.as_coeff_Mulc                 K   s   ddl m}m}m} g }g }g }tj}	| jD ]}
|
 \}}|jrN|	| q,|jrf|	|tj
  q,|
jr|rx|
 nd }t|D ],\}}||kr|	||d  ||=  qq|
jr|	|
9 }	q|	|
 q,|	|
 q,| j| }|d|krd S t|d r||d}ntj}| j||  }||| |||  }}|	dkr|dkrv|jrh|tjfS tj|| fS |tjkr||fS | | || fS ddlm} ||	dd \}}|tjkr|| ||  || ||  fS | | ||  }}|| ||  || ||  fS d S )	Nr   )AbsimrerF   ignorer   )
expand_mulF)deep)r   r   r   r   r
   r(   r%   r   rd   r,   rv   r   	conjugate	enumeraterr   funcgetro   r)   rs   functionr   )r;   r   hintsr   r   r   otherZcoeffrZcoeffiZaddtermsr1   r   r   Zaconjr   r   ZimcoZrecor   ZaddreZaddimr   r   r   r   J  sX    





 zMul.as_real_imagc                    sn   t | }|dkr| d jS g }t| d|d  }t| |d d   fdd|D }t| }t|S )zk
        Helper function for _eval_expand_mul.

        sums must be a list of instances of Basic.
        r   r   NrF   c                    s    g | ]} D ]}t ||qqS r   )r-   )r8   r1   rO   rightr   r   rL     s       z#Mul._expandsums.<locals>.<listcomp>)ro   r%   r-   _expandsumsrS   r   )sumsLtermsleftaddedr   r   r   r     s    
zMul._expandsumsc                    s0  ddl m} | }||\}}|jr< fdd||fD \}}|| }|jsN|S g g d  }}}|jD ]:}	|	jr~||	 d}qd|	jr||	 qd|t|	 qd|s|S | j| }|r( 	dd}
| j
|}g }|D ]F}| ||}|jrtdd	 |jD r|
r| }|| qt| S |S d S )
Nr   fractionc                    s"   g | ]}|j r|jf  n|qS r   )r   _eval_expand_mulr8   r   r   r   r   rL     s   z(Mul._eval_expand_mul.<locals>.<listcomp>FTr   c                 s   s   | ]}|j V  qd S r5   )rr   r7   r   r   r   r9     s     z'Mul._eval_expand_mul.<locals>.<genexpr>)sympy.simplify.radsimpr   r   r%   rr   r,   r   r	   r   r   r   r   r   rS   )r;   r   r   exprr   rV   plainr   Zrewritefactorr   r   r%   termrM   r   r   r   r     s@    




$zMul._eval_expand_mulc              	   C   sr   t | j}g }tt|D ]L}|| |}|r|tdd |d | |g ||d d   tj qt	
|S )Nc                 S   s   | | S r5   r   )r   yr   r   r   r     r   z&Mul._eval_derivative.<locals>.<lambda>r   )r'   r%   r~   ro   diffr,   r   r
   r(   rS   Zfromiter)r;   sr%   r   r   rV   r   r   r   _eval_derivative  s    
8zMul._eval_derivativec                    sx  ddl m} ddlm}m}m} t||fs<t S ddl	m
} | j t }tt|frg }	ddlm}
 |
|D ]2\}tfddt D  }|	||  q~t|	 S dd	lm} dd
lm} ddlm} |d| |dt }|}|tt| || t fddt|d D    d |d|f fddD  }}||f| S )Nr   )AppliedUndef)SymbolsymbolsDummy)Integerr   )!multinomial_coefficients_iteratorc                    s   g | ]\}}|  |fqS r   r   )r8   karg)r   r   r   rL     s     z0Mul._eval_derivative_n_times.<locals>.<listcomp>)Sum)	factorial)Maxzk1:%ir   c                    s"   g | ]} |  | fqS r   r   r8   rM   )r%   kvalsr   r   r   rL     s     r^   c                    s   g | ]}|d  fqS r   r   )r8   r   )r   r   r   rL     s     )r   r   symbolr   r   r   rg   super_eval_derivative_n_timesr   r   r%   ro   intZsympy.ntheory.multinomialr   r-   zipr,   rS   Zsympy.concrete.summationsr   Z(sympy.functions.combinatorial.factorialsr   Z(sympy.functions.elementary.miscellaneousr   sumprodmapr~   r   )r;   r   r   r   r   r   r   r   r   r   r   r2   r   r   r   r   ZklastZnfactrU   l	__class__)r%   r   r   r   r   r     s8     zMul._eval_derivative_n_timesc                 C   sT   ddl m} | jd }t| jdd   }|||| |||| |||||  S )Nr   )difference_deltar   )Zsympy.series.limitseqr  r%   r-   subs)r;   r   stepddZarg0restr   r   r   _eval_difference_delta  s    
$zMul._eval_difference_deltac                 C   sD   |   \}}t|}t|dkr@| j||}|d ||S d S )Nr   r   )rP   r-   r   ro   r   _combine_inversematches)r;   r   	repl_dictrn   r   Znewexprr   r   r   _matches_simple  s    
zMul._matches_simpleNc           
      C   s   t |}| jr"|jr"| |||S | j|jk	r2d S |  \}}| \}}dd ||fD \}}t| }t| }	||	||}|s||krd S t|}t|}t|||}|pd S )Nc                 S   s   g | ]}|pd gqS r   r   rf   r   r   r   rL     s     zMul.matches.<locals>.<listcomp>)r   r   Z_matches_commutativer*   r-   r  _matches_expand_pows_matches_noncomm)
r;   r   r	  oldc1Znc1c2Znc2Zcomm_mul_selfZcomm_mul_exprr   r   r   r    s"    

zMul.matchesc                 C   sB   g }| D ]4}|j r2|jdkr2||jg|j  q|| q|S r>   )ry   expr+   baser,   )arg_listnew_argsr   r   r   r   r    s    zMul._matches_expand_powsc                 C   s   |dkri }n|  }g }d}|\}}i }|t|k r|t| k r| | }|jr\t|| t||| |}	|	r|	\}
}||
 |r|D ]}|| ||< q|sdS | }|\}}q*|S )zNon-commutative multiplication matcher.

        `nodes` is a list of symbols within the matcher multiplication
        expression, while `targets` is a list of arguments in the
        multiplication expression being matched against.
        N)r   r   )copyro   is_Wildr-   _matches_add_wildcard_matches_new_statesr+   r)   )nodestargetsr	  Zagendastatenode_ind
target_indZwildcard_dictnodeZstates_matchesZ
new_statesZnew_matchesmatchr   r   r   r  $  s4     

zMul._matches_noncommc                 C   s:   |\}}|| kr*| | \}}||f| |< n||f| |< d S r5   r   )
dictionaryr  r  r  beginendr   r   r   r  O  s
    zMul._matches_add_wildcardc                 C   s  |\}}|| }|| }|t |d kr<|t |d k r<d S |jrt| |||}|rt| ||}	|	D ]`}
| |
 \}}| | \}}|||d  }|||d  }t||D ]\}}||kr  d S qql||d fg}|t |d k r||d |d f ||fS nr|t |d kr6|t |d k r6d S ||}|r\|d |d fg|fS ||kr||d |d fgd fS d S d S )Nr   )ro   r  r-   _matches_match_wilds_matches_get_other_nodesr   r,   r  )r   r  r  r  r  r  r  targetZmatch_attemptZother_node_indsindZother_beginZ	other_endZ
curr_beginZcurr_endZother_targetsZcurrent_targetscurrr   	new_stater   r   r   r  X  sF       
$

zMul._matches_new_statesc           	      C   sJ   || }| | \}}|||d  }t |dkr8t| n|d }||S )z@Determine matches of a wildcard with sub-expression in `target`.r   r   )ro   r-   r  )	r   Zwildcard_indr  r  Zwildcardr!  r"  r   multr   r   r   r#    s
    zMul._matches_match_wildsc                    s   |   fdd| D S )z8Find other wildcards that may have already been matched.c                    s   g | ]}|  kr|qS r   r   )r8   r&  Zind_noder  r   r   rL     s      z0Mul._matches_get_other_nodes.<locals>.<listcomp>r   )r   r  r  r   r*  r   r$    s    zMul._matches_get_other_nodesc                 C   sH  ddl m} ddlm} | |kr&tjS dd }|| |sB||| rHtjS tdd | |fD r(|d	}tj|i}|tji}| |	 }||	 }	t
|	}
t|	 D ]4}||kr||  |	|8  < || s|| qt
|	|
kr(td
d | D  |} tdd |	 D  |}| | }||}|jrD|S |S )z
        Returns lhs/rhs, but treats arguments like symbols, so things
        like oo/oo return 1 (instead of a nan) and ``I`` behaves like
        a symbol instead of sqrt(-1).
        r   )signsimpr   )r   c                 S   s(   | j r$|jr$| d| dkS dS )Nr   F)r   Zis_comparable__add__Zevalf)r   r   r   r   r   check  s    z#Mul._combine_inverse.<locals>.checkc                 s   s   | ]}|j p|jV  qd S r5   )ry   r   r   r   r   r   r9     s     z'Mul._combine_inverse.<locals>.<genexpr>Ic                 S   s   g | ]\}}|| qS r   r   r8   r   vr   r   r   rL     s     z(Mul._combine_inverse.<locals>.<listcomp>c                 S   s   g | ]\}}|| qS r   r   r/  r   r   r   rL     s     )Zsympy.simplify.simplifyr+  r   r   r
   r(   r   rv   Zxreplaceas_powers_dictro   r   keysr)   r-   rR   r   )lhsrhsr+  r   r-  rV   Z_iZi_r1   rO   blenrK   r   Zsrvr   r   r   r    s2    

zMul._combine_inversec                 C   s>   t t}| jD ]*}|  D ]\}}||  |7  < qq|S r5   )r   r   r%   r1  rR   )r;   rV   r   rO   rU   r   r   r   r1    s
    
zMul.as_powers_dictc                 C   s0   t tdd | jD  \}}| j| | j| fS )Nc                 S   s   g | ]}|  qS r   )r   rk   r   r   r   rL     s     z&Mul.as_numer_denom.<locals>.<listcomp>)r'   r   r%   r   )r;   ZnumersZdenomsr   r   r   r     s    zMul.as_numer_denomc                 C   sv   d }g }d}| j D ]T}| \}}|js0|d7 }|d kr>|}n||ksN|dkr\| tjf  S || q| j| |fS )Nr   r   )r%   rx   r   r
   r(   r,   r   )r;   r   basesr3   r   rO   rU   r   r   r   rx     s    
zMul.as_base_expc                    s   t  fdd| jD S )Nc                 3   s   | ]}|  V  qd S r5   )_eval_is_polynomialr8   r   symsr   r   r9     s     z*Mul._eval_is_polynomial.<locals>.<genexpr>allr%   r;   r:  r   r9  r   r7    s    zMul._eval_is_polynomialc                    s   t  fdd| jD S )Nc                 3   s   | ]}|  V  qd S r5   )_eval_is_rational_functionr8  r9  r   r   r9     s     z1Mul._eval_is_rational_function.<locals>.<genexpr>r;  r=  r   r9  r   r>    s    zMul._eval_is_rational_functionc                    s   t  fdd| jD ddS )Nc                 3   s   | ]}|  V  qd S r5   )Zis_meromorphicr8   r   r1   r   r   r   r9     s     z+Mul._eval_is_meromorphic.<locals>.<genexpr>TZ
quick_exitr   r%   )r;   r   r1   r   r@  r   _eval_is_meromorphic  s    zMul._eval_is_meromorphicc                    s   t  fdd| jD S )Nc                 3   s   | ]}|  V  qd S r5   )_eval_is_algebraic_exprr8  r9  r   r   r9     s     z.Mul._eval_is_algebraic_expr.<locals>.<genexpr>r;  r=  r   r9  r   rD    s    zMul._eval_is_algebraic_exprc                 C   s   t dd | jD S )Nc                 s   s   | ]}|j V  qd S r5   )r   r7   r   r   r   r9     s    zMul.<lambda>.<locals>.<genexpr>rB  r;   r   r   r   r     s   zMul.<lambda>c                 C   sP   t dd | jD }|dkrLtdd | jD rLtdd | jD rHd S dS |S )Nc                 s   s   | ]}|j V  qd S r5   )
is_complexr7   r   r   r   r9     s     z'Mul._eval_is_complex.<locals>.<genexpr>Fc                 s   s   | ]}|j V  qd S r5   )is_infiniter7   r   r   r   r9     s     c                 s   s   | ]}|j d k	V  qdS rh   rd   r7   r   r   r   r9     s     )r   r%   r   )r;   compr   r   r   _eval_is_complex  s    zMul._eval_is_complexc                 C   s   d }}| j D ]}|jr,|dk	r& dS d}q|jrF|dk	r@ dS d}q|dkrj|jd krj|dk	rf dS d }|dkr|jd kr|dk	r dS d }q||fS )NF)NNT)r%   rd   rG  )r;   	seen_zeroseen_infiniter1   r   r   r   _eval_is_zero_infinite_helper  s&    ,
z!Mul._eval_is_zero_infinite_helperc                 C   s4   |   \}}|dkrdS |dkr,|dkr,dS d S d S NFTrM  r;   rK  rL  r   r   r   _eval_is_zero@  s    zMul._eval_is_zeroc                 C   s4   |   \}}|dkr |dkr dS |dkr,dS d S d S )NTFrO  rP  r   r   r   _eval_is_infiniteL  s    zMul._eval_is_infinitec                 C   sD   t dd | jD dd}|r |S |dkr@tdd | jD r@dS d S )Nc                 s   s   | ]}|j V  qd S r5   )is_rationalr7   r   r   r   r9   \  s     z(Mul._eval_is_rational.<locals>.<genexpr>TrA  Fc                 s   s   | ]}|j d kV  qdS rh   rH  r7   r   r   r   r9   a  s     r   r%   r<  r;   r   r   r   r   _eval_is_rational[  s    zMul._eval_is_rationalc                 C   sD   t dd | jD dd}|r |S |dkr@tdd | jD r@dS d S )Nc                 s   s   | ]}|j V  qd S r5   )Zis_algebraicr7   r   r   r   r9   e  s     z)Mul._eval_is_algebraic.<locals>.<genexpr>TrA  Fc                 s   s   | ]}|j d kV  qdS rh   rH  r7   r   r   r   r9   j  s     rT  rU  r   r   r   _eval_is_algebraicd  s    zMul._eval_is_algebraicc                    sz  ddl m} |  }|dkr dS g }g }d}| jD ]}d}|jrZt|tjk	rX|| q2|j	r|
 \}}	t|tjk	r|| |	tjk	r||	 q2|jr| \}
}|
jr|jsd }}|jr||tjkrdn
t|tj n(|s|jrt|jrt d S  d S q2 d S q2|s,|s,dS dd }dd }d	d }d
dlm  |sx|rxt fdd|D rxdS |rd S ||r||rdS ||r|dgkrdS ||r||rt|ddid
 jrdS t|d
kr,|d }	|	jr,|	jr,tdd |D  ||	j jr,dS t|d
krv|d }|jrv|jrvtdd |D  ||j jrvdS d S )Nr   trailingFTrF   c                 S   s   t dd | D S )Nc                 s   s   | ]}|j V  qd S r5   )is_oddr   r   r   r   r9     s     9Mul._eval_is_integer.<locals>.<lambda>.<locals>.<genexpr>r<  r   r   r   r   r     r   z&Mul._eval_is_integer.<locals>.<lambda>c                 S   s   t dd | D S )Nc                 s   s   | ]}|j V  qd S r5   is_evenr   r   r   r   r9     s     r[  r\  r   r   r   r   r     r   c                 S   s   t dd | D S )Nc                 s   s   | ]}|j V  qd S r5   r]  r   r   r   r   r9     s     r[  )r   r   r   r   r   r     r   r   is_gtc                 3   s   | ]} |t jV  qd S r5   )r
   r(   )r8   _r_  r   r   r9     s    z'Mul._eval_is_integer.<locals>.<genexpr>rH   c                 S   s   g | ]}|j r| d  qS r  r^  rx   r   r   r   r   rL     s    z(Mul._eval_is_integer.<locals>.<listcomp>c                 S   s   g | ]}|j r| d  qS r  rb  r   r   r   r   rL     s    )sympy.ntheory.factor_rY  rV  r%   r}   r   r
   r(   r,   rp   r   ry   rx   r{   rw   r[   rA   r|   rq   rd   Z
relationalr`  r<  r-   ro   rz   r^  rS   r   is_nonnegative)r;   rY  rS  Z
numeratorsZdenominatorsunknownr1   hitr   rV   rO   rU   ZalloddZallevenZanyevenr   r_  r   _eval_is_integerp  s    





zMul._eval_is_integerc                 C   s,   t dd | jD }|o*tdd | jD S )Nc                 s   s   | ]}|j V  qd S r5   )is_polarr?  r   r   r   r9     s     z%Mul._eval_is_polar.<locals>.<genexpr>c                 s   s   | ]}|j p|jV  qd S r5   )rh  r|   r?  r   r   r   r9     s     )r   r%   r<  )r;   Z	has_polarr   r   r   _eval_is_polar  s    zMul._eval_is_polarc                 C   s
   |  dS NT)_eval_real_imagrE  r   r   r   _eval_is_extended_real  s    zMul._eval_is_extended_realc                 C   s  d}d }| j D ]}|jp|jdkr2|jdkr2 dS |jr@| }q|jr|s|j}|sb|dkrb|}q|rtdd | j D r dS  d S q|jdkr|r d S |}q|jdkr|r d S |}q d S q|r|jdkr|r|S |jdkr|s|S n|dkr|S |r|S d S )NFc                 s   s   | ]}|j V  qd S r5   ri   r7   r   r   r   r9     s     z&Mul._eval_real_imag.<locals>.<genexpr>T)r%   rF  rG  re   r   rd   r<  )r;   realzeroZt_not_re_imrM   zr   r   r   rk    sH    




zMul._eval_real_imagc                 C   s"   t dd | jD r| dS d S )Nc                 s   s   | ]}|j d ko|jV  qdS rh   )rd   rj   r7   r   r   r   r9     s     z)Mul._eval_is_imaginary.<locals>.<genexpr>F)r<  r%   rk  rE  r   r   r   _eval_is_imaginary  s    zMul._eval_is_imaginaryc                 C   s
   |  dS rj  _eval_herm_antihermrE  r   r   r   _eval_is_hermitian  s    zMul._eval_is_hermitianc                 C   s
   |  dS )NFrq  rE  r   r   r   _eval_is_antihermitian  s    zMul._eval_is_antihermitianc                 C   sp   | j D ]<}|jd ks|jd kr$ d S |jr.qq|jr<| }q d S q|dk	rP|S |  }|r`dS |dkrl|S d S rN  )r%   Zis_hermitianZis_antihermitianrQ  )r;   ZhermrM   rd   r   r   r   rr    s    
zMul._eval_herm_antihermc                 C   sr   | j D ]N}|j}|rFt| j }|| tdd |D r@ dS  d S |d kr d S qtdd | j D rndS d S )Nc                 s   s"   | ]}|j ot|jd kV  qdS )TN)rS  r   rd   r8   r   r   r   r   r9     s     z*Mul._eval_is_irrational.<locals>.<genexpr>Tc                 s   s   | ]}|j V  qd S r5   )Zis_realru  r   r   r   r9     s     F)r%   Zis_irrationalr'   remover<  )r;   rM   r1   Zothersr   r   r   _eval_is_irrational  s    


zMul._eval_is_irrationalc                 C   s
   |  dS )a  Return True if self is positive, False if not, and None if it
        cannot be determined.

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

        This algorithm is non-recursive and works by keeping track of the
        sign which changes when a negative or nonpositive is encountered.
        Whether a nonpositive or nonnegative is seen is also tracked since
        the presence of these makes it impossible to return True, but
        possible to return False if the end result is nonpositive. e.g.

            pos * neg * nonpositive -> pos or zero -> None is returned
            pos * neg * nonnegative -> neg or zero -> False is returned
        r   _eval_pos_negrE  r   r   r   _eval_is_extended_positive  s    zMul._eval_is_extended_positivec                 C   s   d }}| j D ]}|jrqq|jr*| }q|jrPtdd | j D rJ dS  d S |jrb| }d}q|jrnd}q|jdkr| }|r d S d}q|jdkr|r d S d}q d S q|dkr|dkr|dkrdS |dk rdS d S )NFc                 s   s   | ]}|j V  qd S r5   ri   r7   r   r   r   r9   7  s     z$Mul._eval_pos_neg.<locals>.<genexpr>Tr   r   )	r%   r_   r<   rd   r<  Zis_extended_nonpositiveZis_extended_nonnegativer|   r{   )r;   r   Zsaw_NONZsaw_NOTrM   r   r   r   ry  /  s:    


zMul._eval_pos_negc                 C   s
   |  dS r]   rx  rE  r   r   r   _eval_is_extended_negativeR  s    zMul._eval_is_extended_negativec           	      C   s   |   }|dk	r|S ddlm} || \}}|jrp|jrpddlm} tdd t	|D  ||j
 jrldS d S d\}}| jD ]T}t|tjkrq~|jr dS |dkrn&|d	kr|| jrd}n|jd krd }|}q~|S )
NTr   r   rX  c                 S   s   g | ]}|j r| d  qS r  rb  r   r   r   r   rL   `  s    z$Mul._eval_is_odd.<locals>.<listcomp>F)Tr   r   )rg  r   r   rz   r^  rc  rY  rS   r-   r   r   r|   r%   r   r
   r(   rZ  )	r;   r}   r   r   rV   rY  r   accrM   r   r   r   _eval_is_oddU  s8    

zMul._eval_is_oddc                 C   s\   ddl m} || \}}|jrX|jrXddlm} tdd t|D  ||j	 j
rXdS d S )Nr   r   rX  c                 S   s   g | ]}|j r| d  qS r  rb  r   r   r   r   rL   |  s    z%Mul._eval_is_even.<locals>.<listcomp>F)r   r   rz   r^  rc  rY  rS   r-   r   r   rd  )r;   r   r   rV   rY  r   r   r   _eval_is_event  s    zMul._eval_is_evenc                 C   sD   d}| j D ](}|jr|js  dS |d jr
|d7 }q
|dkr@dS dS )z
        Here we count the number of arguments that have a minimum value
        greater than two.
        If there are more than one of such a symbol then the result is composite.
        Else, the result cannot be determined.
        r   Nr   T)r%   r}   r|   )r;   Znumber_of_argsr   r   r   r   _eval_is_composite  s    


zMul._eval_is_compositec           (         sp  ddl m ddlm} ddlm ddlm} |js:d S |j	d j
r|j	d dk r| j	d j
r| j	d dk r~| | | S d S dd   fdd	} fd
d}dd }d }|| \}	}
| }|
tjk	r|	|||
|| }|js|||S || kr|}|j	d }|j	d }d }|jrB|jrB||krN||}n|jrN|S ||\}||\}|r|jrt|dkrt|t||}| |kr|  |7  < n||< |||  }nd}d}t|t|krd}nxttkrd}n`dd |D dd |D r.d}n:ttrHd}n tfddD rhd}|sr|S s~d }nJg } D ]4\}}| }|||| |d s|  S qt|}|sd }tt|D ]}|||  ||< qސnd}t|}|ptj}g }d}|rt|| t|krtd}g }t|D ]}|||  d || d krl qXn|dkr|||||  d || d  nd||d kr|||||  d || d  n0|||  d || d kr qXn
|d |d7 }qBt|} | rX|dkrn|r4t|| } t|| ||| d || d | |d d    ||< nd} ||| d || d | |d d   }!|}"|| d }#||# d ||# d | |d d   f}$|$d r.|| t|k r
|!|" |$g|||| < n"||$ }$|!|" |$ g|||| < n|!|" g|||| < || 8 }|| 7 }d}|sh|| |d7 }q|s~|S |t|t| |D ]}|||  ||||< q|d kr|}%n|d kr|}%n
t||}%g }&D ]R}|kr| | |%  }'|&|||' n|&|||||  q|rX|sXt||g|& }&||j|&  |j|  S )Nr   r   )multiplicity)	powdenestr   c                 S   s.   ddl m} | jst| |r$|  S | tjfS )Nr   )r  )Z&sympy.functions.elementary.exponentialr  ry   rg   rx   r
   r(   )r1   r  r   r   r   base_exp  s    z Mul._eval_subs.<locals>.base_expc                    s   t tg  }}t| D ]f}|} |\}}|tjk	rX| \}}t||| }|}|jrp||  |7  < q|	||g q||fS )zbreak up powers of eq when treated as a Mul:
                   b**(Rational*e) -> b**e, Rational
                commutatives come back as a dictionary {b**e: Rational}
                noncommutatives come back as a list [(b**e, Rational)]
            )
r   r   r-   r   r
   r(   r?   r[   r   r,   )eqr2   r3   r1   rO   rU   r0   ra  )r  r  r   r   breakup  s    
zMul._eval_subs.<locals>.breakupc                    s    | \} }t | || S )z
            Put rational back with exponent; in general this is not ok, but
            since we took it from the exponent for analysis, it's ok to put
            it back.
            rZ   )rO   r0   rU   )r  r   r   rejoin  s    zMul._eval_subs.<locals>.rejoinc                 S   s(   |j | j  r| j |j  s$t| | S dS )zif b divides a in an extractive way (like 1/4 divides 1/2
            but not vice versa, and 2/5 does not divide 1/3) then return
            the integer number of times it divides, else return 0.
            r   )r   r   )r1   rO   r   r   r   ndiv  s    zMul._eval_subs.<locals>.ndivr   TFc                 S   s   h | ]}|d  qS r   r   r   r   r   r   rY     s     z!Mul._eval_subs.<locals>.<setcomp>c                 3   s&   | ]} | | kV  qd S r5   r   r   )r2   old_cr   r   r   r9     s     z!Mul._eval_subs.<locals>.<genexpr>r^   )r   r   rc  r  sympy.simplify.powsimpr  r   r   r   r%   r   _subsr
   r(   rp   Zextract_multiplicativelyr   r)   ro   
differencesetr   rR   r,   minr~   r   r[   r+   r  r   )(r;   r  newr  r   r  r  r  r   r   rV   Zself2Zco_selfZco_oldZco_xmulr3   Zold_ncr)  Zco_residualokZcdidratrO   Zold_eZc_eZncdidr   Ztakelimitfailedrf  r   Zndor   midZirr   domargsrU   r   )r  r2   r  r  r   r   
_eval_subs  s   	






 

&&










 zMul._eval_subsr   c                    s  ddl m} ddlm ddlm} dd g }z| jD ]0}|\}	}
|	sd|	||
f q8t
q8tdd	 |D g }|D ]b\}} |jr|nd }|j| d
}| }|d k	r||k r܈|| 8 |	| qW n t
ttt|fk
r   ttdd	 |D jr*tj fdd| jD }ddlm} || j|  ddd}||r|| 7 }| Y S X tj}dd |D }t| D ]N}fdd|D }t| \}}t|}| jr|t| |  7 }qfdd| rddlm } ddl!m"} z<| ksX|| ||krj|| 7 }W n |k
r   Y nX |S || kr| | #dtjkrԈdkr| j$ d}|tjkr|S || 7 }|S )Nr   )	PoleErrorr   )ceiling)Orderc                 S   sJ   |  |}|d |rFz| |}W n tk
rD   | tjf Y S X |S r>   )Zas_coeff_exponentr   leadterm
ValueErrorr
   rs   )r   r   ltr   r   r   	coeff_exp  s    
z$Mul._eval_nseries.<locals>.coeff_expc                 s   s    | ]}|d  j r|d  V  qdS r   Nr   r   r   r   r   r9     s     
 z$Mul._eval_nseries.<locals>.<genexpr>r   logxcdirc                 s   s    | ]}|d  j r|d  V  qdS r  r  r   r   r   r   r9     s     
 c                    s&   g | ]}|j   d qS )r  )nseriesr   )r  r  r  r   n0r   r   r   rL     s     z%Mul._eval_nseries.<locals>.<listcomp>)powsimpr  T)combiner   c                 S   s   g | ]}t |qS r   )rS   r   )r8   r   r   r   r   rL     s     c                    s   g | ]} |qS r   r   r8  )r  r   r   r   rL     s     c                    sx   |  krt jS | jrt jS | jr:t fdd| jD S | jrZt fdd| jD  S | j	rr| j
 | j S t jS )Nc                 3   s   | ]} |V  qd S r5   r   r7   
max_degreer   r   r   r9     s     z8Mul._eval_nseries.<locals>.max_degree.<locals>.<genexpr>c                    s   g | ]} |qS r   r   r7   r  r   r   rL     s     z9Mul._eval_nseries.<locals>.max_degree.<locals>.<listcomp>)r
   r(   Zis_Atomrs   rr   maxr%   r   rS   ry   r  r  )rU   r   )r  r   r   r    s    z%Mul._eval_nseries.<locals>.max_degree)PolynomialError)degreer  r  )%r   r  Z#sympy.functions.elementary.integersr  Zsympy.series.orderr  r%   r  r   r,   r  r   r   r  ZgetnNotImplementedError	TypeErrorr   r   rd  r
   rs   r  r  r   r   r   r   r{   r-   Zis_polynomialZsympy.polys.polyerrorsr  Zsympy.polys.polytoolsr  r  _eval_as_leading_term)r;   r   r   r  r  r  r  ZordsrM   rn   r  Zfacsr   Zn1r   nsr  resZords2ZfacZords3ZcoeffsZpowersr   r  r  r  r   )r  r  r  r  r  r   r  r   r   _eval_nseries  sp    	


&
"zMul._eval_nseriesc                    s   | j  fdd| jD  S )Nc                    s   g | ]}|j  d qS )r  )Zas_leading_termr   r  r  r   r   r   rL     s     z-Mul._eval_as_leading_term.<locals>.<listcomp>r   r%   )r;   r   r  r  r   r  r   r    s    zMul._eval_as_leading_termc                 C   s   | j dd | jD  S )Nc                 S   s   g | ]}|  qS r   )r   r   r   r   r   rL     s     z'Mul._eval_conjugate.<locals>.<listcomp>r  rE  r   r   r   _eval_conjugate  s    zMul._eval_conjugatec                 C   s    | j dd | jd d d D  S )Nc                 S   s   g | ]}|  qS r   )Z	transposer   r   r   r   rL     s     z'Mul._eval_transpose.<locals>.<listcomp>r^   r  rE  r   r   r   _eval_transpose  s    zMul._eval_transposec                 C   s    | j dd | jd d d D  S )Nc                 S   s   g | ]}|  qS r   )Zadjointr   r   r   r   rL     s     z%Mul._eval_adjoint.<locals>.<listcomp>r^   r  rE  r   r   r   _eval_adjoint  s    zMul._eval_adjointc                 C   sR   t j}g }| jD ]2}|j||d\}}||9 }|t jk	r|| q|| j| fS )aU  Return the tuple (R, self/R) where R is the positive Rational
        extracted from self.

        Examples
        ========

        >>> from sympy import sqrt
        >>> (-3*sqrt(2)*(2 - 2*sqrt(2))).as_content_primitive()
        (6, -sqrt(2)*(1 - sqrt(2)))

        See docstring of Expr.as_content_primitive for more examples.
        )radicalclear)r
   r(   r%   as_content_primitiver,   r   )r;   r  r  Zcoefr%   r1   r2   r   r   r   r   r    s    

zMul.as_content_primitivec                    s(   |   \}}|j fddd || S )a  Transform an expression into an ordered list of factors.

        Examples
        ========

        >>> from sympy import sin, cos
        >>> from sympy.abc import x, y

        >>> (2*x*y*sin(x)*cos(x)).as_ordered_factors()
        [2, x, y, sin(x), cos(x)]

        c                    s   | j  dS )Norder)sort_key)r   r  r   r   r   &  r   z(Mul.as_ordered_factors.<locals>.<lambda>r    )r*   r"   )r;   r  ZcpartZncpartr   r  r   as_ordered_factors  s    zMul.as_ordered_factorsc                 C   s   t |  S r5   )r   r  rE  r   r   r   _sorted_args)  s    zMul._sorted_args)F)T)NF)N)r   )Nr   )FT)N)Qr   r   r   __doc__	__slots__tTupler   __annotations__r   Z
_args_typer   r:   propertyr6   r=   rB   classmethodr   r   r   r   r   r   r   r?   rP   r   staticmethodr   r   r   r   r  r
  r  r  r  r  r  r#  r$  r  r1  r   rx   r7  r>  rC  rD  Z_eval_is_commutativerJ  rM  rQ  rR  rV  rW  rg  ri  rl  rk  rp  rs  rt  rr  rw  rz  ry  r{  r}  r~  r  r  r  r  r  r  r  r  r  r  __classcell__r   r   r   r   r-   \   s   
E

    




7
*
	
 
	*

4
	

)	C	O*#  

X


r-   mulc                 C   s   t tj| |S )a  Return product of elements of a. Start with int 1 so if only
       ints are included then an int result is returned.

    Examples
    ========

    >>> from sympy import prod, S
    >>> prod(range(3))
    0
    >>> type(_) is int
    True
    >>> prod([S(2), 3])
    6
    >>> _.is_Integer
    True

    You can start the product at something other than 1:

    >>> prod([1, 2], 3)
    6

    )r   operatorr  )r1   startr   r   r   r   0  s    r   TFc                    sL   j s |j r | } n | S |tjkr. S  tjkr<|S  tjkrP|sP| S |jr|s jr jdkrdd |jD } fdd|D }tdd |D rt	
dd |D S t |dd	S |jrt|j}|d
 j r|d
   9  < |d
 dkr|d
 n|d
  t
|S  | }|j rD|j sDt
 |f}|S dS )a  Return ``coeff*factors`` unevaluated if necessary.

    If ``clear`` is False, do not keep the coefficient as a factor
    if it can be distributed on a single factor such that one or
    more terms will still have integer coefficients.

    If ``sign`` is True, allow a coefficient of -1 to remain factored out.

    Examples
    ========

    >>> from sympy.core.mul import _keep_coeff
    >>> from sympy.abc import x, y
    >>> from sympy import S

    >>> _keep_coeff(S.Half, x + 2)
    (x + 2)/2
    >>> _keep_coeff(S.Half, x + 2, clear=False)
    x/2 + 1
    >>> _keep_coeff(S.Half, (x + 2)*y, clear=False)
    y*(x + 2)/2
    >>> _keep_coeff(S(-1), x + y)
    -x - y
    >>> _keep_coeff(S(-1), x + y, sign=True)
    -(x + y)
    r   c                 S   s   g | ]}|  qS r   )rP   r   r   r   r   rL   r  s     z_keep_coeff.<locals>.<listcomp>c                    s   g | ]\}}t | |fqS r   rI   )r8   r2   r   rm   r   r   rL   s  s     c                 s   s   | ]\}}|j V  qd S r5   )rz   )r8   r2   ra  r   r   r   r9   t  s     z_keep_coeff.<locals>.<genexpr>c                 S   s.   g | ]&}t |d  dkr$|dd n|qS )r   r   N)r-   r.   r   r   r   r   rL   u  s   FrG   r   N)r   r
   r(   rA   rr   rp   r   r%   r   rS   r.   r-   r   r'   r)   r/   )rn   Zfactorsr  r   r%   r  r   r   rm   r   rJ   J  s>    




rJ   c                 C   s   dd }t | |S )Nc                    s:   | j r6|  \ } jr6|jr6t fdd|jD  S | S )Nc                    s   g | ]} | qS r   r   )r8   rir2   r   r   rL     s     z+expand_2arg.<locals>.do.<locals>.<listcomp>)r   rP   r   rr   _unevaluated_Addr%   )rU   r   r   r  r   r    s
    zexpand_2arg.<locals>.dor   )rU   r  r   r   r   expand_2arg  s    r  )r   rZ   )rS   r  )r   )TF)3typingr   r  collectionsr   	functoolsr   r   	itertoolsr   r  r   basicr	   Z	singletonr
   
operationsr   r   cacher   Zlogicr   r   r   r   
parametersr   r6   r   Z	traversalr   Zsympy.utilities.iterablesr   r   comparer#   r&   r4   r-   r  r   rJ   r  r   r   r   r[   addrS   r  r   r   r   r   <module>   sT   

6               `

=
