ó
    Š*£hNz  ã                   ó˜  • S r SSKJr  SSKJrJrJrJrJr  SSK	J
r
Jr  SSKJr  SSKJr  SSKJr  SSKJrJr  SS	KJrJrJrJrJr  SS
KJrJrJrJrJ r J!r!  SSK"J#r#  SSK$J%r%  SSK&J'r'J(r(J)r)J*r*  SSK+J,r,  \,RZ                  \,R\                  4\S4/r/S r0S r1S r2S r3S r4 " S S5      r5 " S S5      r6S r7SS jr8S S jr9  S!S jr:S r;g)"z2Tools for doing common subexpression elimination.
é    )Údefaultdict)ÚBasicÚMulÚAddÚPowÚsympify)ÚTupleÚ
OrderedSet)Úfactor_terms)ÚS)Úordered)ÚsymbolsÚSymbol)Ú
MatrixBaseÚMatrixÚImmutableMatrixÚSparseMatrixÚImmutableSparseMatrix)Ú
MatrixExprÚMatrixSymbolÚMatMulÚMatAddÚMatPowÚInverse)ÚMatrixElement)ÚRootOf)Únumbered_symbolsÚsiftÚtopological_sortÚiterableé   )Úcse_optsNc                 ó,  • [        U 5      n / n[        U 5       HB  u  nu  p4[        U 5       H+  u  nu  pgX7R                  ;   d  M  UR                  X%45        M-     MD     [	        [        [        U 5      5      U45       Vs/ s H  o€U   PM	     sn$ s  snf )aì  Sort replacements ``r`` so (k1, v1) appears before (k2, v2)
if k2 is in v1's free symbols. This orders items in the
way that cse returns its results (hence, in order to use the
replacements in a substitution option it would make sense
to reverse the order).

Examples
========

>>> from sympy.simplify.cse_main import reps_toposort
>>> from sympy.abc import x, y
>>> from sympy import Eq
>>> for l, r in reps_toposort([(x, y + 1), (y, 2)]):
...     print(Eq(l, r))
...
Eq(y, 2)
Eq(x, y + 1)

)r   Ú	enumerateÚfree_symbolsÚappendr   ÚrangeÚlen)	ÚrÚEÚc1Úk1Úv1Úc2Úk2Úv2Úis	            ÚT/home/mande/repo/quber/.venv/lib/python3.13/site-packages/sympy/simplify/cse_main.pyÚreps_toposortr3   +   s‚   € ô( 	�‹
€AØ
€AÜ! !ž‰ˆ‰HˆRÜ% ažL‰LˆB‘�Ø—_‘_Õ$Ø—‘˜"˜Ö"ó )ñ %ô +¬E´#°a³&«M¸1Ð+=Ô>Ó?Ò>�QˆaŒDÑ>Ñ?Ð?ùÒ?s   Â Bc                 óŒ   • [        US 5      nXS    Vs/ s H  o3R                  PM     sn-   n US   n[        U 5      U/$ s  snf )ao  Move expressions that are in the form (symbol, expr) out of the
expressions and sort them into the replacements using the reps_toposort.

Examples
========

>>> from sympy.simplify.cse_main import cse_separate
>>> from sympy.abc import x, y, z
>>> from sympy import cos, exp, cse, Eq, symbols
>>> x0, x1 = symbols('x:2')
>>> eq = (x + 1 + exp((x + 1)/(y + 1)) + cos(y + 1))
>>> cse([eq, Eq(x, z + 1), z - 2], postprocess=cse_separate) in [
... [[(x0, y + 1), (x, z + 1), (x1, x + 1)],
...  [x1 + exp(x1/x0) + cos(x0), z - 2]],
... [[(x1, y + 1), (x, z + 1), (x0, x + 1)],
...  [x0 + exp(x0/x1) + cos(x1), z - 2]]]
...
True
c                 óT   • U R                   =(       a    U R                  R                  $ ©N)Úis_EqualityÚlhsÚ	is_Symbol)Úws    r2   Ú<lambda>Úcse_separate.<locals>.<lambda>\   s   € ˜!Ÿ-™-×;¨A¯E©E¯O©OÐ;ó    TF)r   Úargsr3   )r)   ÚeÚdr:   s       r2   Úcse_separaterA   H   sL   € ô( 	ˆQÑ;Ó<€AØ	˜tšWÓ%šW˜�VŒV™WÑ%Ñ%€AØ	ˆ%‰€AÜ˜!Ó˜aÐ Ð ùò &s   •Ac                 ó  ^^	^
• U (       d  X4$ [        U 6 u  mm
[        S[        U5      -  5      n[        U5      n[        T5      m[	        T5      m	[        T
5      m
[        [        U5      5       Vs/ s H  oAU   X4   4PM     nn[        [        UU	U
U4S jS96 u  p[        U5      nT
U-  m
/ n[        T
5      S-
  nUS:¼  a®  T
R                  5       nT	UR                  -  nU(       a/  UR                  [        U[        S9 Vs/ s H  oˆS4PM     sn5        U[        U 5      :¼  a"  UR                  UR                  5       U45        OUR                  TU   U45        T	U-  m	US-  nUS:¼  a  M®  UR                  5         XR4$ s  snf s  snf )a  
Return tuples giving ``(a, b)`` where ``a`` is a symbol and ``b`` is
either an expression or None. The value of None is used when a
symbol is no longer needed for subsequent expressions.

Use of such output can reduce the memory footprint of lambdified
expressions that contain large, repeated subexpressions.

Examples
========

>>> from sympy import cse
>>> from sympy.simplify.cse_main import cse_release_variables
>>> from sympy.abc import x, y
>>> eqs = [(x + y - 1)**2, x, x + y, (x + y)/(2*x + 1) + (x + y - 1)**2, (2*x + 1)**(x + y)]
>>> defs, rvs = cse_release_variables(*cse(eqs))
>>> for i in defs:
...   print(i)
...
(x0, x + y)
(x1, (x0 - 1)**2)
(x2, 2*x + 1)
(_3, x0/x2 + x1)
(_4, x2**x0)
(x2, None)
(_0, x1)
(x1, None)
(_2, x0)
(x0, None)
(_1, x)
>>> print(rvs)
(_0, _1, _2, _3, _4)
z_:%dc                 óR   >• [        UU4S jU S   R                  T-   5       5      * $ )Nc              3   óh   >#   • U  H'  nTTR                  U5         R                  5       v •  M)     g 7fr6   )ÚindexÚ	count_ops)Ú.0r1   ÚpÚss     €€r2   Ú	<genexpr>Ú:cse_release_variables.<locals>.<lambda>.<locals>.<genexpr>�   s0   øé € ð -Ú+ˆAð ˜QŸW™W Q›Z™=×2Ñ2×4Ð4Ú+ùs   ƒ/2r   )Úsumr%   )ÚxÚin_userH   rI   s    €€€r2   r;   Ú'cse_release_variables.<locals>.<lambda>�   s+   ø€ ”sõ -Ø�1‘×"Ñ" VÒ+ó-ó -ñ -r=   ©Úkeyr!   r   N)Úzipr   r(   ÚlistÚsetr'   ÚsortedÚpopr%   ÚextendÚstrr&   Úreverse)r)   r?   ÚesymsÚsymsr1   ÚrvÚ_pÚcrI   rN   rH   s           `@@r2   Úcse_release_variablesr_   b   sn  ú€ öD Øˆtˆä�ˆ7�D€A€qÜ�FœS ›V‘OÓ$€EÜ�‹;€DÜˆQ‹€AÜ�‹V€FÜˆQ‹€Aä"'¬¨A«¤-Ó0¢-˜QˆA‰$�‘‹¡-€AÐ0Ü”6˜!ö-ñ.ð /�G€Aô �‹:€DØˆ�F€AØ	€BÜˆA‹�‰
€AØ
ˆq‹&Ø�U‰U‹WˆØ�R—_‘_Ñ$ˆÞØ�I‰I¬&°¼Ò*<Ó=Ò*< Q˜4“yÑ*<Ñ=Ô>Ø”�A“‹;Ø�I‰I�t—x‘x“z 2Ð&Õ'à�I‰I�q˜‘t˜R�jÔ!Ø�!‰ˆØ	ˆQ‰ˆð ˆq�&ð ‡J�J„LØˆ9Ðùò) 	1ùò >s   Á2FÄF
c                 ó6   • U H  u  p#Uc  M
  U" U 5      n M     U $ )aL  Preprocess an expression to optimize for common subexpression
elimination.

Parameters
==========

expr : SymPy expression
    The target expression to optimize.
optimizations : list of (callable, callable) pairs
    The (preprocessor, postprocessor) pairs.

Returns
=======

expr : SymPy expression
    The transformed expression.
© ©ÚexprÚoptimizationsÚpreÚposts       r2   Úpreprocess_for_cserg   ¨   s%   € ó$ #‰	ˆØ‹?Ù�t“9ŠDñ #ð €Kr=   c                 óH   • [        U5       H  u  p#Uc  M
  U" U 5      n M     U $ )añ  Postprocess an expression after common subexpression elimination to
return the expression to canonical SymPy form.

Parameters
==========

expr : SymPy expression
    The target expression to transform.
optimizations : list of (callable, callable) pairs, optional
    The (preprocessor, postprocessor) pairs.  The postprocessors will be
    applied in reversed order to undo the effects of the preprocessors
    correctly.

Returns
=======

expr : SymPy expression
    The transformed expression.
)Úreversedrb   s       r2   Úpostprocess_for_cserj   À   s+   € ô( ˜mÖ,‰	ˆØÓÙ˜“:ŠDñ -ð €Kr=   c                   óJ   • \ rS rSrSrS rS rS rS rSS jr	SS	 jr
S
 rSrg)ÚFuncArgTrackeréÚ   zq
A class which manages a mapping from functions to arguments and an inverse
mapping from arguments to functions.
c                 óT  • 0 U l         / U l        / U l        / U l        [	        U5       H}  u  p#[        5       nUR                   HC  nU R                  U5      nUR                  U5        U R                  U   R                  U5        ME     U R                  R                  U5        M     g r6   )
Úvalue_numbersÚvalue_number_to_valueÚarg_to_funcsetÚfunc_to_argsetr$   r
   r>   Úget_or_add_value_numberÚaddr&   )ÚselfÚfuncsÚfunc_iÚfuncÚfunc_argsetÚfunc_argÚ
arg_numbers          r2   Ú__init__ÚFuncArgTracker.__init__à   s—   € ð  ˆÔØ%'ˆÔ"ð !ˆÔØ ˆÔä% eÖ,‰LˆFÜ$›,ˆKà ŸIœI�Ø!×9Ñ9¸(ÓC�
Ø—‘ 
Ô+Ø×#Ñ# JÑ/×3Ñ3°FÖ;ñ &ð
 ×Ñ×&Ñ& {Ö3ò -r=   c                 ó\   • [        U5       Vs/ s H  o R                  U   PM     sn$ s  snf )zP
Return the list of arguments in sorted order according to their value
numbers.
)rU   rp   )ru   ÚargsetÚargns      r2   Úget_args_in_value_orderÚ&FuncArgTracker.get_args_in_value_orderô   s*   € ô
 >DÀF¼^ÓLº^°T×*Ñ*¨4Ô0¹^ÑLÐLùÒLs   Ž)c                 óì   • [        U R                  5      nU R                  R                  X5      nX2:X  a>  U R                  R	                  U5        U R
                  R	                  [        5       5        U$ )z1
Return the value number for the given argument.
)r(   ro   Ú
setdefaultrp   r&   rq   r
   )ru   ÚvalueÚnvaluesÚvalue_numbers       r2   rs   Ú&FuncArgTracker.get_or_add_value_numberû   s`   € ô �d×(Ñ(Ó)ˆØ×)Ñ)×4Ñ4°UÓDˆØÓ"Ø×&Ñ&×-Ñ-¨eÔ4Ø×Ñ×&Ñ&¤z£|Ô4ØÐr=   c                 ól   • U R                   U    H!  nU R                  U   R                  U5        M#     g)zC
Remove the function func_i from the argument to function mapping.
N)rr   rq   Úremove)ru   rw   Úargs      r2   Ústop_arg_trackingÚ FuncArgTracker.stop_arg_tracking  s2   € ð ×&Ñ& vÔ.ˆCØ×Ñ Ñ$×+Ñ+¨FÖ3ò /r=   c                 óº  • [        S 5      nU(       d  U$ U Vs/ s H  o@R                  U   PM     nn[        U[        S9nU H%  nXgL a  M	  U H  nX‚:¼  d  M
  X8==   S-  ss'   M     M'     [	        Xc/[        S9u  n	n
U	 H   nX8   S:  a  M  XŠ;   d  M  X8==   S-  ss'   M"     UR                  5        VVs0 s H  u  p¼US:¼  d  M  X¼_M     snn$ s  snf s  snnf )zçReturn a dict whose keys are function numbers. The entries of the dict are
the number of arguments said function has in common with
``argset``. Entries have at least 2 items in common.  All keys have
value at least ``min_func_i``.
c                  ó   • g)Nr   ra   ra   r=   r2   r;   Ú:FuncArgTracker.get_common_arg_candidates.<locals>.<lambda>  s   € ¨r=   rP   r!   é   )r   rq   Úmaxr(   rU   Úitems)ru   r   Ú
min_func_iÚ	count_mapr‹   ÚfuncsetsÚlargest_funcsetÚfuncsetrw   Úsmaller_funcs_containerÚlarger_funcs_containerÚkÚvs                r2   Úget_common_arg_candidatesÚ(FuncArgTracker.get_common_arg_candidates  sø   € ô  ¡	Ó*ˆ	ÞØÐá8>Ó?º°×'Ñ'¨Ô,¹ˆÐ?ô ˜h¬CÑ0ˆãˆGØÒ)ÙÛ!�ØÕ'ØÓ%¨Ñ*Õ%ó "ñ  ô $*Ø!Ð-Üñ$ñ	!Ð	 Ø	ó .ˆFð Ñ  1Ó$ÙàÕ/ØÓ! QÑ&Õ!ñ .ð "+§¡Ô!2Ô=Ò!2™˜°a¸1±f“�’Ñ!2Ò=Ð=ùò9 @ùó8 >s   šCÂ8CÃCNc                 ó®   • [        U5      n[        S U R                  [        U5          5       5      nUb  XB-  nU H  nX@R                  U   -  nM     U$ )zœ
Return a set of functions each of which whose argument list contains
``argset``, optionally filtered only to contain functions in
``restrict_to_funcset``.
c              3   ó$   #   • U  H  ov •  M     g 7fr6   ra   )rG   Úfis     r2   rJ   Ú7FuncArgTracker.get_subset_candidates.<locals>.<genexpr>>  s   é € ð :Ú8�2ŒBÒ8ùs   ‚)Úiterr
   rq   Únext)ru   r   Úrestrict_to_funcsetÚiargÚindicesr‹   s         r2   Úget_subset_candidatesÚ$FuncArgTracker.get_subset_candidates6  sg   € ô �F‹|ˆäñ :Ø×,Ñ,¬T°$«ZÒ8ó:ó :ˆð Ñ*ØÑ*ˆGãˆCØ×*Ñ*¨3Ñ/Ñ/ŠGñ ð ˆr=   c                 óR  • [        U5      nU R                  U   nXC-
   H!  nU R                  U   R                  U5        M#     X4-
   H!  nU R                  U   R	                  U5        M#     U R                  U   R                  5         U R                  U   R                  U5        g)z0
Update a function with a new set of arguments.
N)r
   rr   rq   rŠ   rt   ÚclearÚupdate)ru   rw   Ú
new_argsetÚnew_argsÚold_argsÚdeleted_argÚ	added_args          r2   Úupdate_func_argsetÚ!FuncArgTracker.update_func_argsetI  sœ   € ô ˜jÓ)ˆØ×&Ñ& vÑ.ˆà#Ô.ˆKØ×Ñ Ñ,×3Ñ3°FÖ;ñ /à!Ô,ˆIØ×Ñ 	Ñ*×.Ñ.¨vÖ6ñ -ð 	×Ñ˜FÑ#×)Ñ)Ô+Ø×Ñ˜FÑ#×*Ñ*¨8Õ4r=   )rq   rr   rp   ro   )r   r6   )Ú__name__Ú
__module__Ú__qualname__Ú__firstlineno__Ú__doc__r|   r�   rs   rŒ   r�   r¨   r²   Ú__static_attributes__ra   r=   r2   rl   rl   Ú   s,   † ñò
4ò(Mò	ò4ô&>ôPõ&5r=   rl   c                   ó:   • \ rS rSrS rS rS r\S 5       r\r	Sr
g)ÚUnevaluatediY  c                 ó   • Xl         X l        g r6   ©rx   r>   )ru   rx   r>   s      r2   r|   ÚUnevaluated.__init__[  s   € ØŒ	Ø�	r=   c                 óz   • SR                  U R                  SR                  S U R                   5       5      5      $ )NzUneval<{}>({})z, c              3   ó8   #   • U  H  n[        U5      v •  M     g 7fr6   )rX   )rG   Úas     r2   rJ   Ú&Unevaluated.__str__.<locals>.<genexpr>a  s   é € Ð$?²Y°¤S¨§V V²Yùs   ‚)Úformatrx   Újoinr>   ©ru   s    r2   Ú__str__ÚUnevaluated.__str___  s3   € Ø×&Ñ&Ø—	‘	˜4Ÿ9™9Ñ$?°T·Y²YÓ$?Ó?óAð 	Ar=   c                 ó:   • U R                   " U R                  SS06$ )NÚevaluateFr½   rÅ   s    r2   Úas_unevaluated_basicÚ Unevaluated.as_unevaluated_basicc  s   € Ø�yŠy˜$Ÿ)™)Ð4¨eÑ4Ð4r=   c                 ó‚   • [        5       R                  " U R                   Vs/ s H  oR                  PM     sn6 $ s  snf r6   )rT   Úunionr>   r%   )ru   rÁ   s     r2   r%   ÚUnevaluated.free_symbolsf  s+   € ä‹u�{Š{°T·Y²YÓ?²Y°Ÿ^œ^±YÑ?Ð@Ð@ùÒ?s   £<)r>   rx   N)r´   rµ   r¶   r·   r|   rÆ   rÊ   Úpropertyr%   Ú__repr__r¹   ra   r=   r2   r»   r»   Y  s/   † òòAò5ð ñAó ðAð ƒHr=   r»   c           	      óÔ  ^• [        US S9n[        U5      n[        5       n[        [	        U5      5       GH.  nUR                  UR                  U   US-   S9m[        [        TR                  5       U4S jS95      nU(       Gaš  UR                  SS9nUR                  U   R                  UR                  U   5      n[	        U5      S::  a  MS  UR                  U   R                  U5      n	U	(       a[  [        XR                  U5      5      n
UR                  U
5      nUR                  XY[        U/5      -  5        UR                  U5        OUR                  X   5      nUR                  U   R                  U5      nUR                  X|[        U/5      -  5        UR                  U5        UR!                  X†5       HP  nUR                  U   R                  U5      nUR                  XÞ[        U/5      -  5        UR                  U5        MR     U(       a  GMš  XT;   a-  [        U UR                  UR                  U   5      5      X!U   '   UR#                  U5        GM1     g)	a/  
Recognize and extract common subexpressions of function arguments within a
set of function calls. For instance, for the following function calls::

    x + z + y
    sin(x + y)

this will extract a common subexpression of `x + y`::

    w = x + y
    w + z
    sin(w)

The function we work with is assumed to be associative and commutative.

Parameters
==========

func_class: class
    The function class (e.g. Add, Mul)
funcs: list of functions
    A list of function calls.
opt_subs: dict
    A dictionary of substitutions which this function may update.
c                 ó,   • [        U R                  5      $ r6   )r(   r>   )Úfs    r2   r;   Ú#match_common_args.<locals>.<lambda>Š  s   € ¬¨A¯F©F¬r=   rP   r!   )r”   c                 ó   >• TU    U 4$ r6   ra   )r›   Úcommon_arg_candidates_countss    €r2   r;   rÔ   —  s   ø€ Ð;¸AÑ>ÀÑBr=   F)ÚlastN)rU   rl   r
   r'   r(   r�   rr   ÚkeysrV   ÚintersectionÚ
differencer»   r�   rs   r²   rt   r¨   rŒ   )Ú
func_classrv   Úopt_subsÚarg_trackerÚchangedr1   Úcommon_arg_candidatesÚjÚcom_argsÚdiff_iÚcom_funcÚcom_func_numberÚdiff_jr›   Údiff_krÖ   s                  @r2   Úmatch_common_argsrç   m  sG  ø€ ô: �5Ñ3Ñ4€EÜ  Ó'€Kä‹l€Gä”3�u“:×ˆØ'2×'LÑ'LØ×*Ñ*¨1Ñ-¸!¸a¹%ð (Mð (AÐ$ô
 !+¬6Ø,×1Ñ1Ó3ÜBñ,Dó !EÐ÷ $Ø%×)Ñ)¨uÐ)Ð5ˆAà"×1Ñ1°!Ñ4×AÑAØ×.Ñ.¨qÑ1ó3ˆHô �8‹} Ó!ñ ð
 !×/Ñ/°Ñ2×=Ñ=¸hÓGˆFÞä&Ø"×$GÑ$GÈÓ$QóS�à"-×"EÑ"EÀhÓ"O�Ø×.Ñ.¨q¼:ÀÐFWÓ;XÑ2XÔYØ—‘˜A•ð #.×"EÑ"EÀeÁhÓ"O�à ×/Ñ/°Ñ2×=Ñ=¸hÓGˆFØ×*Ñ*¨1´zÀ?ÐBSÓ7TÑ.TÔUØ�K‰K˜ŒNà ×6Ñ6Øö5�à$×3Ñ3°AÑ6×AÑAÀ(ÓK�Ø×.Ñ.¨q¼:ÀÐFWÓ;XÑ2XÔYØ—‘˜A–ñ	5÷K $Ñ#ðV ‹<Ü!,¨ZØ×3Ñ3°K×4NÑ4NÈqÑ4QÓRó"TˆH˜1‘XÑð 	×%Ñ% a×(òs r=   c                 óº  ^^^^^^• 0 m[        5       m[        5       m[        5       m[        5       mUUUUUU4S jmU  H(  n[        U[        [        45      (       d  M   T" U5        M*     T Vs/ s H(  nUR
                  S   T;   d  M  X3R
                  S   4PM*     nn[        [        TU45      5       H2  nTR                  UR
                  S   UR
                  S   5      TU'   M4     [        5       nT H¹  nUR                  SS9u  pxU(       d  M  UR                  " U6 n	U(       ad  U	S:X  a  UR                  " U6 n
OI[        U[        5      (       a  UR                  " U	/UQ7SS06n
OUR                  X–R                  " U6 SS9n
U
TU'   [        U5      S:”  d  M¨  UR                  U	5        M»     [        [        TT5        [        [         UT5        T$ s  snf )aé  Find optimization opportunities in Adds, Muls, Pows and negative
coefficient Muls.

Parameters
==========

exprs : list of SymPy expressions
    The expressions to optimize.
order : string, 'none' or 'canonical'
    The order by which Mul and Add arguments are processed. For large
    expressions where speed is a concern, use the setting order='none'.

Returns
=======

opt_subs : dictionary of expression substitutions
    The expression substitutions which can be useful to optimize CSE.

Examples
========

>>> from sympy.simplify.cse_main import opt_cse
>>> from sympy.abc import x
>>> opt_subs = opt_cse([x**-2])
>>> k, v = list(opt_subs.keys())[0], list(opt_subs.values())[0]
>>> print((k, v.as_unevaluated_basic()))
(x**(-2), 1/(x**2))
c                 óâ  >• [        U [        [        45      (       d  g U R                  (       d  U R                  (       a  g [        U 5      (       a  [        [        TU 5      5        g U T	;   a  U $ T	R                  U 5        [        [        TU R                  5      5        [        U [        5      (       dŽ  U R                  5       (       ay  [        U [        5      (       a  [        S U R                   5       6 nOU * nUR                  (       d6  [        [        [        R                  U45      TU '   T	R                  U5        Un [        U [        [         45      (       a=  [#        U R                  5      S:X  a  TR                  U 5        g TR                  U 5        g [        U [        [$        45      (       a=  [#        U R                  5      S:X  a  TR                  U 5        g TR                  U 5        g [        U [&        5      (       a  g [        U [(        [*        45      (       aM  U R,                  U R.                  p2UR                  5       (       a   [        [(        [)        X#* 5      S45      TU '   g g g )Nc              3   ó&   #   • U  H  o* v •  M	     g 7fr6   ra   )rG   r1   s     r2   rJ   Ú.opt_cse.<locals>._find_opts.<locals>.<genexpr>  s   é € Ð 7ªY¨¥ªYùs   ‚r!   éÿÿÿÿ)Ú
isinstancer   r»   Úis_AtomÚis_Orderr    rS   Úmaprt   r>   r   Úcould_extract_minus_signr   r   r   ÚNegativeOner   r(   r   r   r   r   ÚbaseÚexp)
rc   Úneg_exprró   rô   Ú
_find_optsÚaddsÚcollapsible_subexpÚmulsrÜ   Úseen_subexps
       €€€€€€r2   rö   Úopt_cse.<locals>._find_optsð  s¿  ø€ ä˜$¤¬Ð 4×5Ñ5Øà�<�<˜4Ÿ=Ÿ=Øä�D�>‰>Ü”�Z Ó&Ô'Øà�;ÓØˆKØ�‰˜ÔäŒS�˜TŸY™YÓ'Ô(ä˜$¤
×+Ñ+°×0MÑ0M×0OÑ0Oô ˜$¤×$Ñ$ÜÑ 7¨T¯YªYÓ 7Ð8‘à ˜5�à×#×#Ü!,¬S´1·=±=À(Ð2KÓ!L�˜‘Ø—‘ Ô)Ø�ä�dœS¤&˜M×*Ñ*Ü�4—9‘9‹~ Ó"Ø"×&Ñ& tÕ,à—‘˜•ä˜œs¤F˜m×,Ñ,Ü�4—9‘9‹~ Ó"Ø"×&Ñ& tÕ,à—‘˜•ä˜œg×&Ñ&àä˜œs¤F˜m×,Ñ,ØŸ	™	 4§8¡8�#Ø×+Ñ+×-Ñ-Ü!,¬S´3°t¸T³?ÀBÐ2GÓ!H�˜’ð .ð -r=   r   F)Úcsetr!   rÉ   )rÉ   )r
   rT   rí   r   r»   r>   ri   r   ÚgetÚargs_cncrx   r   r(   rt   rç   r   r   )ÚexprsÚorderr?   rI   ÚedgesÚcommutative_mulsÚmr^   ÚncÚc_mulÚnew_objrö   r÷   rø   rù   rÜ   rú   s              @@@@@@r2   Úopt_cser  Ë  sª  ý€ ð: €Hä‹<€DÜ‹<€Dä“%€KÜ›Ð÷3Iò 3Iój ˆÜ�aœ%¤Ð-×.Ó.Ù�qŽMñ ñ
 &8ó 1Ò%7 Ø—‘�q‘	Ð/Ñ/ó ˆa—‘˜‘‹^Ñ%7€Eð 1äÔ&Ð(:¸EÐ'BÓCÖDˆØ—l‘l 1§6¡6¨!¡9¨a¯f©f°Q©iÓ8ˆ�‹ñ Eô "“|ÐÛˆØ—
‘
 �
Ð&‰ˆßˆ1Ø—F’F˜A�JˆEÞØ˜A“:ØŸfšf b˜k‘Gä! !¤V×,Ñ,Ø"#§&¢&¨Ð"D°Ò"D¸eÑ"D™à"#§&¡&¨·²¸°Àe &Ð"L˜Ø%�˜‘Ü�1‹v˜�zØ ×$Ñ$ UÖ+ñ ô  ”c˜4 Ô*Ü”cÐ+¨XÔ6à€Oùò51s   Á.GÂ	Gc                 ó|  ^^^^^^	^
^^^^• Tc  0 m[        5       m[        5       m[        5       m
UU
UUUU4S jmU  H"  n[        U[        5      (       d  M  T" U5        M$     U
4S jT 5       m/ m0 mU	UUUUUU4S jm	/ nU  H4  n[        U[        5      (       a	  T	" U5      nOUnUR                  U5        M6     TU4$ )a·  Perform raw CSE on expression tree, taking opt_subs into account.

Parameters
==========

exprs : list of SymPy expressions
    The expressions to reduce.
symbols : infinite iterator yielding unique Symbols
    The symbols used to label the common subexpressions which are pulled
    out.
opt_subs : dictionary of expression substitutions
    The expressions to be substituted before any CSE action is performed.
order : string, 'none' or 'canonical'
    The order by which Mul and Add arguments are processed. For large
    expressions where speed is a concern, use the setting order='none'.
ignore : iterable of Symbols
    Substitutions containing any Symbol from ``ignore`` will be ignored.
c                 ól  >• [        U [        [        45      (       d  g [        U [        5      (       a  g [        U [        5      (       aj  U R                  (       d,  U R
                  (       d  [        U [        [        45      (       a-  U R                  (       a  TR                  U R                  5        g [        U 5      (       a  U nOZU T;   a,  T H  nX R                  ;   d  M    O   TR                  U 5        g TR                  U 5        U T;   a  TU    n U R                  n[        [        TU5      5        g r6   )rí   r   r»   r   rî   rï   r   r   r9   rt   Únamer    r%   r>   rS   rð   )	rc   r>   ÚignÚ_find_repeatedÚexcluded_symbolsÚignorerÜ   rú   Úto_eliminates	      €€€€€€r2   r  Ú tree_cse.<locals>._find_repeatedd  sê   ø€ Ü˜$¤¬Ð 4×5Ñ5Øä�dœF×#Ñ#Øä�dœE×"Ñ"Ø——Ø——Ü˜4¤,´Ð!>×?Ñ?Ø�~�~Ø ×$Ñ$ T§Y¡YÔ/Øä�D�>‰>Ø‰Dð �{Ó"Û!�CØ×/Ñ/Õ/Ùñ "ð !×$Ñ$ TÔ*Øà�O‰O˜DÔ!à�xÓØ ‘~�à—9‘9ˆDäŒS� Ó&Õ'r=   c              3   óJ   >#   • U  H  oR                   T;  d  M  Uv •  M     g 7fr6   )r
  )rG   Ú_r  s     €r2   rJ   Útree_cse.<locals>.<genexpr>�  s   øé € ÐDš'�Q§V¡VÐ3CÑ%C�q‰qš'ùs   ƒ#š	#c                 óþ  >• [        U [        [        45      (       d  U $ U R                  (       d  U $ [	        U 5      (       a1  U R                   Vs/ s H  nT	" U5      PM     nnU R
                  " U6 $ U T;   a  TU    $ U nU T
;   a  T
U    n TS:w  a–  [        U [        [        45      (       a4  U R                  5       u  pEUS/:X  a  UnOk[        [        U5      5      U-   nOS[        U [        [        45      (       a  [        [        U R                  5      5      nOU R                  nOU R                  n[        [        T	U5      5      n[        U [        5      (       d  X&:w  a  U R
                  " U6 nOU nUT;   ae   [        T5      n[        U["        5      (       a+  [%        UR&                  UR(                  UR*                  5      nUTU'   TR-                  X‡45        U$ U$ s  snf ! [         a    [!        S5      ef = f)NÚnoner!   z$Symbols iterator ran out of symbols.)rí   r   r»   r>   r    rx   r   r   rþ   rS   r   r   r   rð   r¤   ÚStopIterationÚ
ValueErrorr   r   r
  ÚrowsÚcolsr&   )rc   r‹   r®   Ú	orig_exprr^   r  r>   Únew_exprÚsymÚ_rebuildrÜ   r   ÚreplacementsÚsubsr   r  s            €€€€€€€r2   r  Útree_cse.<locals>._rebuild•  sÅ  ø€ Ü˜$¤¬Ð 4×5Ñ5ØˆKà�y�yØˆKä�D�>‰>Ø15·²Ó;²¨#™ ž±ˆHÐ;Ø—9’9˜hÐ'Ð'à�4‹<Ø˜‘:Ðàˆ	Ø�8ÓØ˜D‘>ˆDð �F‹?Ü˜$¤¤f ×.Ñ.ØŸ™›‘�Ø˜˜“8Ø‘Dä¤¨£
Ó+¨bÑ0‘DÜ˜D¤3¬ -×0Ñ0ÜœG D§I¡IÓ.Ó/‘à—y‘y‘à—9‘9ˆDäœ˜H dÓ+Ó,ˆÜ�dœK×(Ñ(¨HÓ,<Ø—y’y (Ð+‰HàˆHà˜Ó$ðIÜ˜7“m�ô ˜)¤Z×0Ñ0Ü" 3§8¡8¨Y¯^©^Ø—N‘Nó$�ð "ˆD�‰OØ×Ñ  Ô0ØˆJð ˆOùò_ <øôF !ó IÜ Ð!GÓHÐHðIús   ÁG!Å;G& Ç&G<)rT   rí   r   r&   )rÿ   r   rÜ   r   r  r?   Úreduced_exprsÚ	reduced_er  r  r  r  rú   r  r  s    ````   @@@@@@@r2   Útree_cser#  G  s¾   ÿú€ ð& ÑØˆô “5€Lä“%€KÜ“uÐ÷"(ò "(óH ˆÜ�aœ×ÓÙ˜1Öñ ô E™'ÓD€Gà€Là€D÷7ó 7ðr €MÛˆÜ�aœ×ÑÙ  ›‰IàˆIØ×Ñ˜YÖ'ñ ð ˜Ð&Ð&r=   c           	      óŠ  • U(       d  [        U XX4US9$ [        U [        [        45      (       a  [	        U 5      n [        U [
        [        45      (       a  U /n U n/ nU  H¦  n	[        U	[        [        45      (       a'  UR                  [        U	R                  5       6 5        ME  [        U	[        [        45      (       a5  UR                  [        U	R                  5       R                  5       6 5        M•  UR                  U	5        M¨     Un AUc  / nOUS:X  a  [         nU  V	s/ s H  n	[#        X’5      PM     n
n	Uc  [%        [&        S9nO[)        U5      n[+        X¤5      n[-        X¡UXE5      u  pÊUn U VVs/ s H  u  pÞU[/        Xâ5      4PM     nnnU
 V	s/ s H  n	[/        X’5      PM     n
n	[1        U 5       Hì  u  pù[        U	[        [        45      (       aR  [        U	R2                  U	R4                  X¯   5      X¯'   [        U	[        5      (       a  X¯   R7                  5       X¯'   Mp  Mr  [        U	[        [        45      (       d  M�  [        U	R2                  U	R4                  0 5      nX¯    H  u  nnUUU'   M     [        U	[        5      (       a  UR7                  5       nUX¯'   Mî     Uc  XÊ4$ U" XÊ5      $ s  sn	f s  snnf s  sn	f )az  Perform common subexpression elimination on an expression.

Parameters
==========

exprs : list of SymPy expressions, or a single SymPy expression
    The expressions to reduce.
symbols : infinite iterator yielding unique Symbols
    The symbols used to label the common subexpressions which are pulled
    out. The ``numbered_symbols`` generator is useful. The default is a
    stream of symbols of the form "x0", "x1", etc. This must be an
    infinite iterator.
optimizations : list of (callable, callable) pairs
    The (preprocessor, postprocessor) pairs of external optimization
    functions. Optionally 'basic' can be passed for a set of predefined
    basic optimizations. Such 'basic' optimizations were used by default
    in old implementation, however they can be really slow on larger
    expressions. Now, no pre or post optimizations are made by default.
postprocess : a function which accepts the two return values of cse and
    returns the desired form of output from cse, e.g. if you want the
    replacements reversed the function might be the following lambda:
    lambda r, e: return reversed(r), e
order : string, 'none' or 'canonical'
    The order by which Mul and Add arguments are processed. If set to
    'canonical', arguments will be canonically ordered. If set to 'none',
    ordering will be faster but dependent on expressions hashes, thus
    machine dependent and variable. For large expressions where speed is a
    concern, use the setting order='none'.
ignore : iterable of Symbols
    Substitutions containing any Symbol from ``ignore`` will be ignored.
list : bool, (default True)
    Returns expression in list or else with same type as input (when False).

Returns
=======

replacements : list of (Symbol, expression) pairs
    All of the common subexpressions that were replaced. Subexpressions
    earlier in this list might show up in subexpressions later in this
    list.
reduced_exprs : list of SymPy expressions
    The reduced expressions with all of the replacements above.

Examples
========

>>> from sympy import cse, SparseMatrix
>>> from sympy.abc import x, y, z, w
>>> cse(((w + x + y + z)*(w + y + z))/(w + x)**3)
([(x0, y + z), (x1, w + x)], [(w + x0)*(x0 + x1)/x1**3])


List of expressions with recursive substitutions:

>>> m = SparseMatrix([x + y, x + y + z])
>>> cse([(x+y)**2, x + y + z, y + z, x + z + y, m])
([(x0, x + y), (x1, x0 + z)], [x0**2, x1, y + z, x1, Matrix([
[x0],
[x1]])])

Note: the type and mutability of input matrices is retained.

>>> isinstance(_[1][-1], SparseMatrix)
True

The user may disallow substitutions containing certain symbols:

>>> cse([y**2*(x + 1), 3*y**2*(x + 1)], ignore=(y,))
([(x0, x + 1)], [x0*y**2, 3*x0*y**2])

The default return value for the reduced expression(s) is a list, even if there is only
one expression. The `list` flag preserves the type of the input in the output:

>>> cse(x)
([], [x])
>>> cse(x, list=False)
([], x)
)r   rd   Úpostprocessr   r  Úbasic)Úcls)Ú_cse_homogeneousrí   ÚintÚfloatr   r   r   r   r   r&   r	   Úflatr   r   Útodokr“   Úbasic_optimizationsrg   r   r   r£   r  r#  rj   r$   r  r  Úas_immutable)rÿ   r   rd   r%  r   r  rS   ÚcopyÚtempr?   r!  rÜ   r  r  Úsubtreer1   r  r›   rœ   s                      r2   Úcser2  Ø  s¡  € ö` Ü ØØ#¸ñAð 	Aô �%œ#œu˜×&Ñ&Ü˜“ˆô �%œ%¤Ð,×-Ñ-Ø�ˆà€DØ€DÛˆÜ�aœ&¤/Ð2×3Ñ3Ø�K‰Kœ˜qŸv™v›xÐ(Ö)Ü˜œLÔ*?Ð@×AÑAØ�K‰Kœ˜qŸw™w›yŸ™Ó0Ð1Ö2à�K‰K˜ŽNñ ð €EØàÑØ‰Ø	˜'Ó	!Ü+ˆñ DIÓIÂ5¸aÔ'¨Ö9Á5€MÐIà�Ü"¤vÑ.‰ô �w“-ˆô �}Ó,€Hô #+¨=À8Ø+0ó#:Ñ€Lð €Eá(4ô6Ú(4™˜ð Ô-¨gÓEÓFÙ(4ð ñ 6ñ ,ó-Ú+˜ô )¨Ö:Ù+ð ð -ô ˜%Ö ‰ˆÜ�aœ&¤/Ð2×3Ñ3Ü% a§f¡f¨a¯f©f°mÑ6FÓGˆMÑÜ˜!œ_×-Ñ-Ø#0Ñ#3×#@Ñ#@Ó#B�Ó ñ .ä˜œLÔ*?Ð@×AÓAÜ˜QŸV™V Q§V¡V¨RÓ0ˆAØ%Ô(‘��1Ø��!“ñ )ä˜!Ô2×3Ñ3Ø—N‘NÓ$�Ø ˆMÓñ !ð ÑØÐ*Ð*á�|Ó3Ð3ùòQ Jùó$6ùò-s   Ä!J5Å5J:ÆK c                 ó  • [        U [        5      (       a$  [        [        U 5      40 UD6u  p#U[	        U5      4$ [        U [
        [        [        45      (       a!  [        U 40 UD6u  p#U[        U 5      " U5      4$ [        U [        5      (       aQ  [        U R                  5       5      n[        U Vs/ s H  oPU   PM	     sn40 UD6u  p&[        [        XF5      5      nX#4$  [        U 40 UD6u  nu  nX#4$ s  snf ! [         a    / U 4s $ f = f)aµ  
Same as ``cse`` but the ``reduced_exprs`` are returned
with the same type as ``exprs`` or a sympified version of the same.

Parameters
==========

exprs : an Expr, iterable of Expr or dictionary with Expr values
    the expressions in which repeated subexpressions will be identified
kwargs : additional arguments for the ``cse`` function

Returns
=======

replacements : list of (Symbol, expression) pairs
    All of the common subexpressions that were replaced. Subexpressions
    earlier in this list might show up in subexpressions later in this
    list.
reduced_exprs : list of SymPy expressions
    The reduced expressions with all of the replacements above.

Examples
========

>>> from sympy.simplify.cse_main import cse
>>> from sympy import cos, Tuple, Matrix
>>> from sympy.abc import x
>>> output = lambda x: type(cse(x, list=False)[1])
>>> output(1)
<class 'sympy.core.numbers.One'>
>>> output('cos(x)')
<class 'str'>
>>> output(cos(x))
cos
>>> output(Tuple(1, x))
<class 'sympy.core.containers.Tuple'>
>>> output(Matrix([[1,0], [0,1]]))
<class 'sympy.matrices.dense.MutableDenseMatrix'>
>>> output([1, x])
<class 'list'>
>>> output((1, x))
<class 'tuple'>
>>> output({1, x})
<class 'set'>
)rí   rX   r(  r   ÚreprrS   ÚtuplerT   r2  ÚtypeÚdictrØ   rR   Ú	TypeError)rÿ   Úkwargsr  r!  rØ   r›   Úvaluess          r2   r(  r(  q  s  € ô\ �%œ×ÑÜ&6Ü�E‹Nñ'&Ø$ñ'&Ñ#ˆàœT -Ó0Ð0Ð0Ü�%œ$¤¤sÐ+×,Ñ,Ü&)¨%Ñ&:°6Ñ&:Ñ#ˆØœT %œ[¨Ó7Ð7Ð7Ü�%œ×ÑÜ�E—J‘J“LÓ!ˆÜ"±dÓ#;²d°¨!¤H±dÑ#;ÑF¸vÑFÑˆÜœS Ó.Ó/ˆØÐ*Ð*ð+Ü),¨UÑ)=°fÑ)=Ñ&ˆÑ&�}ð Ð*Ð*ùò $<øô ó Ø�5ˆyÒðús   Â2C6Ã"C; Ã;DÄD)Ú	canonical)Nr;  ra   )NNNr;  ra   T)<r¸   Úcollectionsr   Ú
sympy.corer   r   r   r   r   Úsympy.core.containersr	   r
   Úsympy.core.exprtoolsr   Úsympy.core.singletonr   Úsympy.core.sortingr   Úsympy.core.symbolr   r   Úsympy.matricesr   r   r   r   r   Úsympy.matrices.expressionsr   r   r   r   r   r   Ú"sympy.matrices.expressions.matexprr   Úsympy.polys.rootoftoolsr   Úsympy.utilities.iterablesr   r   r   r    Ú r"   Úsub_preÚsub_postr-  r3   rA   r_   rg   rj   rl   r»   rç   r  r#  r2  r(  ra   r=   r2   Ú<module>rK     sÓ   ðñå #ç 4Õ 4ß 3Ý -Ý "Ý &ß -÷Aõ A÷A÷ Aå <Ý *÷#ó #õ ð !×(Ñ(¨(×*;Ñ*;Ð<Ø$ dÐ+ð-Ð ò@ò:!ò4@òLò0÷4|5ñ |5÷~ñ ò([)ô|yôxN'ðb >BØ+/ôV4ór@+r=   