
    \h	                     2   S SK Jr  S SKJr  S SKJrJrJrJrJ	r	J
r
JrJr  S SKJr  S SKJrJr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J r J!r!  S S
K"J#r#  S SK$J%r%J&r&J'r'J(r(J)r)J*r*J+r+J,r,J-r-  S SK$J.r.  S SK/J0r0  S SK1J2r2  S SK3J4r4J5r5J6r6J7r7  S SK8J9r9  S SK:J;r;  S SK<J=r=  S SK>J?r?  S SK@JArA  S SKBJCrC  S SKDJErE  S SKFJGrG  / SSS4S jrH\2\04rIS rJS0S jrKS rLSS.S  jrMS! rNS"qOS# rPS$ rQS% rRS& rSS' rTS( rUS0S) jrV\S0S* j5       rWSS+.S, jrXS- rYS. rZS1S/ jr[g")2    )defaultdict)reduce)sympifyBasicSExprfactor_termsMulAdd	bottom_up)cacheit)	count_ops_mexpandFunctionClassexpand
expand_mul_coeff_isneg
Derivative)IInteger)igcd)_nodes)DummysymbolsWild)
SYMPY_INTS)	sincosexpcoshtanhsinhtancotcoth)atan2)HyperbolicFunction)TrigonometricFunction)Polyfactorcancelparallel_poly_from_expr)ZZ)PolificationFailed)groebner)cse)identity)greedy)iterable)debugFgrlexc                   ^^^ S mS mUUU4S jn[        S5      mU R                  [        R                  T5      n T[        R                  4/n[	        U 5      R                  5       u  px [        Xx/5      u  u  pn[        SUR                  5        U" UR                  U5      u  pn[        SU5        [        SUS[        U5      5        [        S	US[        U5      5        U(       d  U $ [        XU[        S
9n[        S[        U5      S[        U5      5        SSKJn  U(       Ga  U
R                   " [#        U5      R%                  U
R                  5      6 (       Ga  ['        X~U-   S9R(                  " U6 n/ nUR+                  5        GH  u  nn[#        [        UU/5      S   R                  5      nSnU(       a  SnU H  n['        U5      nUR-                  UR                  5      (       a  M0  UR                   " [#        UR                  5      R/                  U5      6 (       a  Mh  SnUR1                  UR3                  5       R                  5        M     U(       a  M  U Vs/ s H  nUU;   d  M  UPM     nnUR4                   Vs/ s HB  nUR                   " UR%                  UR                  5      6 (       d  M2  UR7                  5       PMD     nnUR9                  [;        [=        UU5       VVs/ s H  u  nnUU-  PM     snn6 U" UU-  UUUU[        US9R                  U5      -  5        GM     [?        U6 $ U" U [        U5      X=U-   U[        US9R                  U5      $ ! [         a    U s $ f = fs  snf s  snf s  snnf )a  
Simplify trigonometric expressions using a groebner basis algorithm.

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

This routine takes a fraction involving trigonometric or hyperbolic
expressions, and tries to simplify it. The primary metric is the
total degree. Some attempts are made to choose the simplest possible
expression of the minimal degree, but this is non-rigorous, and also
very slow (see the ``quick=True`` option).

If ``polynomial`` is set to True, instead of simplifying numerator and
denominator together, this function just brings numerator and denominator
into a canonical form. This is much faster, but has potentially worse
results. However, if the input is a polynomial, then the result is
guaranteed to be an equivalent polynomial of minimal degree.

The most important option is hints. Its entries can be any of the
following:

- a natural number
- a function
- an iterable of the form (func, var1, var2, ...)
- anything else, interpreted as a generator

A number is used to indicate that the search space should be increased.
A function is used to indicate that said function is likely to occur in a
simplified expression.
An iterable is used indicate that func(var1 + var2 + ...) is likely to
occur in a simplified .
An additional generator also indicates that it is likely to occur.
(See examples below).

This routine carries out various computationally intensive algorithms.
The option ``quick=True`` can be used to suppress one particularly slow
step (at the expense of potentially more complicated results, but never at
the expense of increased total degree).

Examples
========

>>> from sympy.abc import x, y
>>> from sympy import sin, tan, cos, sinh, cosh, tanh
>>> from sympy.simplify.trigsimp import trigsimp_groebner

Suppose you want to simplify ``sin(x)*cos(x)``. Naively, nothing happens:

>>> ex = sin(x)*cos(x)
>>> trigsimp_groebner(ex)
sin(x)*cos(x)

This is because ``trigsimp_groebner`` only looks for a simplification
involving just ``sin(x)`` and ``cos(x)``. You can tell it to also try
``2*x`` by passing ``hints=[2]``:

>>> trigsimp_groebner(ex, hints=[2])
sin(2*x)/2
>>> trigsimp_groebner(sin(x)**2 - cos(x)**2, hints=[2])
-cos(2*x)

Increasing the search space this way can quickly become expensive. A much
faster way is to give a specific expression that is likely to occur:

>>> trigsimp_groebner(ex, hints=[sin(2*x)])
sin(2*x)/2

Hyperbolic expressions are similarly supported:

>>> trigsimp_groebner(sinh(2*x)/sinh(x))
2*cosh(x)

Note how no hints had to be passed, since the expression already involved
``2*x``.

The tangent function is also supported. You can either pass ``tan`` in the
hints, to indicate that tan should be tried whenever cosine or sine are,
or you can pass a specific generator:

>>> trigsimp_groebner(sin(x)/cos(x), hints=[tan])
tan(x)
>>> trigsimp_groebner(sinh(x)/cosh(x), hints=[tanh(x)])
tanh(x)

Finally, you can use the iterable form to suggest that angle sum formulae
should be tried:

>>> ex = (tan(x) + tan(y))/(1 - tan(x)*tan(y))
>>> trigsimp_groebner(ex, hints=[(tan, x, y)])
tan(x + y)
c                    Sn/ / / pCnU  H  n[        U[        [        45      (       a  UnM"  [        U[        5      (       a  UR	                  U5        MJ  [        U5      (       at  UR	                  US   USS 45        UR                  [        USS  Vs/ s H  oeS   " U5      PM     snUS   " [        USS 6 5      /-   5      S   R                  5        M  UR	                  U5        M     XX44$ s  snf )z-Split hints into (n, funcs, iterables, gens).   r   N)

isinstancer   r   r   appendr3   extendr,   r   gens)hintsnfuncs	iterablesr<   exs          O/var/www/auris/envauris/lib/python3.13/site-packages/sympy/simplify/trigsimp.pyparse_hints&trigsimp_groebner.<locals>.parse_hints   s    !#R$A!j'233A}--Q!  !A$!"/ 3&'e,eqT!We,!S!AB%[0A/BBDDEGGKtM A  (( -s   C1c           	      z   / n[        S5      nU GH  u  pE[        [        [        [        U 5      S-  [        U 5      S-  -   S-
  /[        [
        [        [	        U 5      S-  [        U 5      S-  -
  S-
  /4 H  u  pgpUS:X  a  XFU4;   a  UR                  " U	5        M'  XH:X  a2  UR                  " U" XP-  5      U" XP-  5      -  U" XP-  5      -
  5        M^  XFU4;   d  Mg  U" XS-  5      R                  SS9R                  X05      n
UR                  " U" XP-  5      U
-
  5        M     GM     [        [        U5      5      $ )aF  
Build generators for our ideal. ``Terms`` is an iterable with elements of
the form (fn, coeff), indicating that we have a generator fn(coeff*x).

If any of the terms is trigonometric, sin(x) and cos(x) are guaranteed
to appear in terms. Similarly for hyperbolic functions. For tan(n*x),
sin(n*x) and cos(n*x) are guaranteed.
y   r8   Ttrig)r   r   r   r#   r    r"   r!   r:   r   subslistset)rB   termsr   rG   fncoeffcstrelcns              rC   build_ideal&trigsimp_groebner.<locals>.build_ideal   s    #JIB#sCFAIA	$9A$=>4tAwzDGQJ'>'BC!Ea A:"A,HHSMWHHQuwZ%'
2QuwZ?@q6\EG+++6;;AABHHR[2-.!E  CF|    c                 	  >^^ T"" U5      u  p#pE[        SX4U45        [        U 5      n U R                  U5        [        [        U5      5      n[        [        U5      5      n[        [        U 5      5      n [        [
        [        [        [        [        1nU  Vs/ s H>  nUR                  U;   d  M  UR                  S   R                  5       UR                  4PM@     nnU  Vs/ s H  owR                  U;  d  M  UPM     n	n/ n
0 nU H+  u  u  pmUR                  U/ 5      R                  UT45        M-     / nUR                  5        GH^  u  nnU Vs/ s H  nUS   PM
     nnU Vs/ s H  nUS   PM
     nn[!        ["        U5      n[%        UU5       VVs/ s H  u  nnUUU-  4PM     nnn[        UU-   5      m[
        [        [        /[        [        [        /4 HH  u  nnn['        U4S jUUU4 5       5      (       d  M&  TR)                  U5        TR)                  U5        MJ     T H+  mUR                  U4S j[+        SUS-   5       5       5        M-     / nU H  u  mnT[        :X  a.  UR                  [        U45        UR                  [
        U45        T[        [
        4;   a!  [        T;   a  UR                  [        U45        T[        :X  a.  UR                  [        U45        UR                  [        U45        T[        [        4;   d  M  [        T;   d  M  UR                  [        U45        M     UR                  U5        U[-        U6 -  nT " UU5      nUR                  U5        U
R                  U VVs1 s H  u  nnU" UU-  5      iM     snn5        GMa     U H  u  mnT[        :X  a!  UR                  [        U4[
        U4/5        M1  T[        :X  a!  UR                  [        U4[        U4/5        M\  [/        S[1        U5      -  [2        S9nT" [5        U6 5      R7                  SS	9R9                  [        [%        UU5      5      5      nUR                  T" [5        U6 5      U-
  5        M     T!U ;   a9  UR                  T!S
-  S-   5        U	R;                  T!5        U
R                  T!5        XU
4$ s  snf s  snf s  snf s  snf s  snnf s  snnf )z
Analyse the generators ``gens``, using the hints ``hints``.

The meaning of ``hints`` is described in the main docstring.
Return a new list of generators, and also the ideal we should
work with.
z1n=%s   funcs: %s   iterables: %s    extragens: %sr   r8   c              3   ,   >#    U  H	  oT;   v   M     g 7fN ).0rB   fss     rC   	<genexpr>:trigsimp_groebner.<locals>.analyse_gens.<locals>.<genexpr>6  s     2	1Bw	   c              3   ,   >#    U  H	  nTU4v   M     g 7fr[   r\   )r]   krO   s     rC   r_   r`   :  s     >ob!Wora   zd:%iclsTrI   rH   )r4   rL   r;   rM   r   r   r#   r"   r    r!   funcargsas_coeff_mul
setdefaultr:   itemsr   r   zipanyaddranger
   r   lenr   r   r   rK   remove)#r<   r=   r>   r?   r@   	extragensallfuncsg	trigtermsfreegensnewgenstrigdictrP   varreskeyvalrB   fnsgcdrO   vrN   rQ   rR   rS   extrarrg   dummysexprr^   rV   myIrD   s#                       `          @rC   analyse_gens'trigsimp_groebner.<locals>.analyse_gens   s.    *5U);&)A+	- DzI SZ Y(	CI c4t4AE ,A(* 8affQi,,.7	 ,  $>t!vvX'=At> )LU"R(//< !* (HC" "%%A1Q4C%!$%A1Q4C%s#C03C>Wb!b!C%[E>US[!B #sOdD$-?@1a2Aq	222FF1IFF1I A >eAq1uo>> EA9LL#q*LL#q*#s#r	LL#q*:LL$+LL$+$%$"*LL$+  LLCIAAu%AJJqMNN7ABqsG78Y )^ "HBSy  3+T{!;<t  4,t!=> #d)!3?3<(//T/:??SQUEV@WX

2c4j>D01 " $;JJsAvz"OOC NN3g%%W, ?0 &%>0 8s0   S	1-S	$S;SS*SSS#r   zinitial gens:zideal:z	new gens:z -- lenz
free gens:)orderr<   domainzgroebner basis:r   )ratsimpmodprime)r<   r8   TF)r   r<   quickr   
polynomial) r   rK   r   ImaginaryUnitr+   as_numer_denomr,   r.   r4   r<   ro   r/   r-   rL   sympy.simplify.ratsimpr   has_only_gensrM   intersectionr)   ejectrN   
issuperset
differenceupdateexcludepolysas_exprr:   r
   rk   r   ) r   r=   r   r   r   r   rK   numdenompnumpdenomoptidealru   r<   Gr   ry   monomrP   ourgenschangedprB   realgensrs   ourGabrV   r   rD   s                                 @@@rC   trigsimp_groebnerr      s
   f)(0d&L *C99Q__c*D!//"#D,,.JC5slC 
/388$(59ET	(E	+tYD	2	,)SY7 $r:A	
T!WiQ8
 7F((#d)*@*@*MN3(]+1148IIKLE515%.A!DIIJG GAQA"--aff55??CK,B,B7,KLL"&qyy{'7'78  ' $(84a1<4H8 *+ DAOOW%9%9!&&%AB  AIIKD DJJsc(E.BC.BdaQT.BCD&uU{D,4E"2<>>Bd4jI J5 (< Cy $q'd]z;;?4:	F{  H 9DCs0   ,M) &
M;4M;
1N ?N 4N)M87M8c                 2   ^^ S mUU4S jm[        U T5      $ )Nc                 b     U R                   S   UR                   S   :H  $ ! [         a     gf = f)Nr   F)rg   
IndexError)rB   rG   s     rC   
check_args%_trigsimp_inverse.<locals>.check_args  s4    	66!9q	)) 		s   ! 
..c                    > [        U SS 5      nUb_  [        U R                  S   U" 5       5      (       a<  [        U" 5       " S5      [        5      (       a  U R                  S   R                  S   $ [        U [        5      (       a  U R                  u  p#[        U5      (       a  T" [	        U* U5      5      * $ [        U5      (       a#  [        R                  T" [	        X#* 5      5      -
  $ T" X25      (       a  [        U[        5      (       a$  [        U[        5      (       a  UR                  S   $ [        U[        5      (       a8  [        U[        5      (       a#  [        R                  S-  UR                  S   -
  $ U $ )Ninverser   r8   rH   )
getattrr9   rg   r(   r&   r   r   Pir   r   )rvrs   rG   rB   r   fs       rC   r   _trigsimp_inverse.<locals>.f  s   B	4(MjQS9913q6#899771:??1%% b%  77DAA%A,''attaao--!a%%*Q*<*<66!9$a%%*Q*<*<44!8affQi//	rX   )r   )r   r   r   s    @@rC   _trigsimp_inverser     s    . RrX   c                 x  ^^^	 SSK Jm  [        U 5      n [        U SS5      nUb  U" S0 TD6$ TR	                  SS5      nU(       d7  TR	                  SS5        TR	                  SS5        TR	                  S	S
5      nOSnS m	UU4S jS U	U4S jU	4S jU4S jS.U   nU" U 5      nU(       a  [        U5      nU$ )av  Returns a reduced expression by using known trig identities.

Parameters
==========

inverse : bool, optional
    If ``inverse=True``, it will be assumed that a composition of inverse
    functions, such as sin and asin, can be cancelled in any order.
    For example, ``asin(sin(x))`` will yield ``x`` without checking whether
    x belongs to the set where this relation is true. The default is False.
    Default : True

method : string, optional
    Specifies the method to use. Valid choices are:

    - ``'matching'``, default
    - ``'groebner'``
    - ``'combined'``
    - ``'fu'``
    - ``'old'``

    If ``'matching'``, simplify the expression recursively by targeting
    common patterns. If ``'groebner'``, apply an experimental groebner
    basis algorithm. In this case further options are forwarded to
    ``trigsimp_groebner``, please refer to
    its docstring. If ``'combined'``, it first runs the groebner basis
    algorithm with small default parameters, then runs the ``'matching'``
    algorithm. If ``'fu'``, run the collection of trigonometric
    transformations described by Fu, et al. (see the
    :py:func:`~sympy.simplify.fu.fu` docstring). If ``'old'``, the original
    SymPy trig simplification function is run.
opts :
    Optional keyword arguments passed to the method. See each method's
    function docstring for details.

Examples
========

>>> from sympy import trigsimp, sin, cos, log
>>> from sympy.abc import x
>>> e = 2*sin(x)**2 + 2*cos(x)**2
>>> trigsimp(e)
2

Simplification occurs wherever trigonometric functions are located.

>>> trigsimp(log(e))
log(2)

Using ``method='groebner'`` (or ``method='combined'``) might lead to
greater simplification.

The old trigsimp routine can be accessed as with method ``method='old'``.

>>> from sympy import coth, tanh
>>> t = 3*tanh(x)**7 - 2/coth(x)**7
>>> trigsimp(t, method='old') == t
True
>>> trigsimp(t)
tanh(x)**7

r   )fu_eval_trigsimpNoldFdeep	recursivemethodmatchingc                 j   ^^ UU4S jmT" U 5      n[        U[        5      (       d  U$ [        U40 TD6$ )Nc                   > U R                   (       a  U $ U R                   Vs/ s H  nT" U5      PM     nnU R                  (       d  U R                  (       a  U Vs/ s H  n[	        U40 TD6PM     nnU R
                  " U6 $ s  snf s  snf r[   is_Atomrg   is_Functionis_Powr   rf   rA   rB   rg   optstraverses      rC   r   0trigsimp.<locals>.groebnersimp.<locals>.traverse  m    yy)*0AHQKD0}}>BCd)!4t4dC664=  1C   BB	)r9   r   r   )exr   newr   s    ` @rC   groebnersimptrigsimp.<locals>.groebnersimp  s5    	! rl#t$$J ---rX   c                    > T" U 40 TD6$ r[   r\   )rB   r   r   s    rC   <lambda>trigsimp.<locals>.<lambda>,  s    ArX   c                     [        U 5      $ r[   )futrigrB   s    rC   r   r   -  s    vayrX   c                    > T" U 40 TD6$ r[   r\   )rB   r   r   s    rC   r   r   .  s    |A66rX   c                 2   > [        T" U SS[        /S95      $ NTrH   )r   r=   )r   r#   )rB   r   s    rC   r   r   /  s    vl1*.q#h'@  ArX   c                    > [        U 40 TD6$ r[   )trigsimp_old)rB   r   s    rC   r   r   1  s    a040rX   )r   r   r/   combinedr   r\   )sympy.simplify.fur   r   r   popr   )
r   r   r   r   r   r   trigsimpfuncexpr_simplifiedr   r   s
     `     @@rC   trigsimpr     s    ~ %4=DT#3T:N!%%%
((5%
 Cd#(J/. '(6A0 L #4(O+O<rX   c                 n  ^ SSK JnJn  S n[        X5      nU4S jm[        UT5      nUR	                  [
        5      (       a  U" U5      u  nmT" U" U5      5      nUR	                  [        5      (       a  U" U5      nUR	                  [        5      (       a  U R	                  [        5      (       a  Un U $ )z
Simplifies exponential / trigonometric / hyperbolic functions.

Examples
========

>>> from sympy import exptrigsimp, exp, cosh, sinh
>>> from sympy.abc import z

>>> exptrigsimp(exp(z) + exp(-z))
2*cosh(z)
>>> exptrigsimp(cosh(z) - sinh(z))
exp(-z)
r   )hyper_as_trigTR2ic                     U /nU R                   " [        6 (       a$  UR                  U R                  [        5      5        UR                  U R                  [
        5      5        [        US[        06$ )Nrz   )has_trigsr:   rewriter   r   minr   )rA   choicess     rC   exp_trigexptrigsimp.<locals>.exp_trigL  sN     #55&>NN199S>*qyy~&G+++rX   c                   >^ U R                   (       d  U $ U R                  5       u  p[        U5      S:  a  T" [        U6 5      [        U6 -  $ U R	                  5       nUR                  5       n[        R                  4U4S jjmU[        R                     nU GH  nUR                  (       d  M  [        UR                  5      S:X  d  M2  UR                  S   nT" UR                  S   U-  5      u  pU	(       d  Md  X6   n
XF==   U
-  ss'   XY* U
-  S-  :X  ae  U[        R                  ==   U-  ss'   SnUS:X  a!  USU-  [        U	S-  5      -  ==   U
-  ss'   M  USU-  [        U	S-  5      -  ==   U
-  ss'   M  USU[        R                  U	-  -  -
     U
* :X  a^  USU[        R                  U	-  -  -
  	 US:X  a  XG* [        U	S-  5      -  ==   U
-  ss'   GME  XG* [        U	S-  5      -  ==   U
-  ss'   GMd  USU[        R                  U	-  -  -   ==   U
-  ss'   XG==   U
-  ss'   GM     [        U Vs/ s H	  ofXF   -  PM     sn6 $ s  snf )Nr8   c                 F  > U [         R                  L a  U[         R                  4$ [        U [        5      (       d/  U R
                  (       a+  U R                  [         R                  :X  a  XR                  4$ U[         R                  L a  T" U * [         R                  * S9$ g)N)sign)NN)r   Exp1Oner9   r   r   base)r   r   signlogs     rC   r   'exptrigsimp.<locals>.f.<locals>.signlogb  sm    qvv~QUU{"D#&&4;;499;NXX~%uAEE622!rX   rH   r   )is_Mulargs_cncro   r
   as_powers_dictcopyr   r   r   is_Addrg   r    r"   r!   )r   commutative_partnoncommutative_partrvdnewdeerc   rQ   r   rB   mr   r   s              @rC   r   exptrigsimp.<locals>.fV  s   yyI02- #$q(S*+,S2E-FFF!xxz uu 	" [AxxxCK1,FF1I!!&&)A+.F1Aa<LB&LBqyQqSac]+q0+RT$qs)^,1,!d16619n,-!3Qaffai/0qyRQqS	\*a/*RQqS	\*a/*T!&&!)^+,1,GqLG5 8 .AZ.//.s   <I)r   r   r   r   r   r'   r(   r   )r   r   r   r   newexprrA   r   s         @rC   exptrigsimpr   ;  s     6, 'G30h #G {{%&&W%1DG*{{())w- KKNN488A;;KrX   T)firstc                  ^^ U nU(       GaS  U R                   " [        6 (       d  U $ [        5       R                  " U R                  " [        6  Vs/ s H  oDR
                  PM     sn6 n[        U5      S:  a  SSKJn  U" U 5      nUR                  (       a  U" USS9=(       d    Un[        U[        5      (       aE  Sn UR                  5        H,  nUn	[        U5      nSTS'   [        U40 TD6n
X:X  a  U	n
X
-  n M.     U nO_UR                  (       aN  U HF  nU R!                  U5      u  pU(       d  M  STS'   U[        U40 TD6-   n U R                  (       a  MF    O   U nTR#                  SS5      nTR#                  S	S5      nTR#                  S
S5      nS mS UU4S jU4S jS.U   nU(       aP  [%        U 5      u  nnU" US   U5      n['        U5       H$  nUR)                  US   US   5      nU" UU5      nM&     UnOU" X5      nTR+                  SS5      (       a  [-        U5      nUU:w  a  [/        SU5        U$ s  snf )a  
Reduces expression by using known trig identities.

Notes
=====

deep:
- Apply trigsimp inside all objects with arguments

recursive:
- Use common subexpression elimination (cse()) and apply
trigsimp recursively (this is quite expensive if the
expression is large)

method:
- Determine the method to use. Valid choices are 'matching' (default),
'groebner', 'combined', 'fu' and 'futrig'. If 'matching', simplify the
expression recursively by pattern matching. If 'groebner', apply an
experimental groebner basis algorithm. In this case further options
are forwarded to ``trigsimp_groebner``, please refer to its docstring.
If 'combined', first run the groebner basis algorithm with small
default parameters, then run the 'matching' algorithm. 'fu' runs the
collection of trigonometric transformations described by Fu, et al.
(see the `fu` docstring) while `futrig` runs a subset of Fu-transforms
that mimic the behavior of `trigsimp`.

compare:
- show input and output from `trigsimp` and `futrig` when different,
but returns the `trigsimp` value.

Examples
========

>>> from sympy import trigsimp, sin, cos, log, cot
>>> from sympy.abc import x
>>> e = 2*sin(x)**2 + 2*cos(x)**2
>>> trigsimp(e, old=True)
2
>>> trigsimp(log(e), old=True)
log(2*sin(x)**2 + 2*cos(x)**2)
>>> trigsimp(log(e), deep=True, old=True)
log(2)

Using `method="groebner"` (or `"combined"`) can sometimes lead to a lot
more simplification:

>>> e = (-sin(x) + 1)/cos(x) + cos(x)/(-sin(x) + 1)
>>> trigsimp(e, old=True)
(1 - sin(x))/cos(x) + cos(x)/(1 - sin(x))
>>> trigsimp(e, method="groebner", old=True)
2/cos(x)

>>> trigsimp(1/cot(x)**2, compare=True, old=True)
      futrig: tan(x)**2
cot(x)**(-2)

r8   r   )separatevarsT)dictFr   r   r   r   r   c                 J   ^^ UU4S jmU(       a  T" U 5      n [        U 40 TD6$ )Nc                   > U R                   (       a  U $ U R                   Vs/ s H  nT" U5      PM     nnU R                  (       d  U R                  (       a  U Vs/ s H  n[	        U40 TD6PM     nnU R
                  " U6 $ s  snf s  snf r[   r   r   s      rC   r   4trigsimp_old.<locals>.groebnersimp.<locals>.traverse  r   r   )r   )r   r   r   r   s     `@rC   r   "trigsimp_old.<locals>.groebnersimp  s&    	! "B ,t,,rX   c                     [        X5      $ r[   )	_trigsimp)rB   ds     rC   r   trigsimp_old.<locals>.<lambda>  s    )A/rX   c                    > T" X40 TD6$ r[   r\   )rB   r	  r   r   s     rC   r   r
  	  s    ,q"<t"<rX   c           	      6   > [        T" U USS[        /S9U5      $ r   )r  r#   )rB   r	  r   s     rC   r   r
  
  s"    )L'(T!S-K#$#&rX   )r   r/   r   comparez	futrig:)r   r   rM   unionatomsfree_symbolsro   sympy.simplify.simplifyr  r   r9   r  valuesr   r   r   as_independentr   r0   reversedrK   getr   print)r   r   r   r   rS   trigsymsr  r	  r~   wasvnewrR   r   rA   r   r   r   r   wrs   subresultr   r   s     `                    @rC   r   r     s#   t Cxx K5;;V9L M9LA9L MNx=1<T"Axx .3!!T""AC"1A$)DM#A..Dy"LD $ 88%#22151,1DM#$x':T':#:D#';;; % & Ce,I88FE"DXXh
+F
- 2<& L 4y11t$A;Cs1vs1v&AQ%A  d)xx	5!!3K;+q!MM !Ns   Ic                    U R                   UR                   :H  =(       ai    U R                  [        5      =(       a    UR                  [        5      =(       d1    U R                  [        5      =(       a    UR                  [        5      $ )zHelper to tell whether ``a`` and ``b`` have the same sorts
of symbols in them -- no need to test hyperbolic patterns against
expressions that have no hyperbolics in them.)rf   r   r(   r'   )r   r   s     rC   _dotrigr  "  s^     66QVV A	#$E/D)E 	@	 !?aee,>&?ArX   Nc                  H   [        S[        S9u  pn[        SSS9nU [        U5      U-  -  [        U5      U-  -  U [	        U5      U-  -  [        U5      [        U5      4U [	        U5      U-  -  [        U5      U-  -  U [        U5      U-  -  [        U5      [        U5      4U [        U5      U-  -  [        U5      U-  -  U [        U5      U-  -  [        U5      [        U5      4U [	        U5      U-  -  [        U5      U-  -  U [        U5      U-  -  [        U5      [        U5      4U [        U5      U-  -  [        U5      U-  -  U [        U5      U-  -  [        U5      [        U5      4U [        U5      U-  -  [	        U5      U-  -  U [        U5      [        U5      4U [        U5      S-   U-  -  [        U5      S-
  U-  -  U [        U5      S-  * U-  -  [        U5      S-   [        U5      S-
  4U [        U5      S-   U-  -  [        U5      S-
  U-  -  U [        U5      S-  * U-  -  [        U5      S-   [        U5      S-
  4U [        U5      U-  -  [        U5      U-  -  U [        U5      U-  -  [        R                  [        R                  4U [        U5      U-  -  [        U5      U-  -  U [        U5      U-  -  [        R                  [        R                  4U [        U5      U-  -  [        U5      U-  -  U [        U5      U-  -  [        R                  [        R                  4U [        U5      U-  -  [        U5      U-  -  U [        U5      U-  -  [        R                  [        R                  4U [        U5      U-  -  [        U5      U-  -  U [        U5      U-  -  [        R                  [        R                  4U [        U5      U-  -  [        U5      U-  -  U [        R                  [        R                  4U[        U 5      [        U5      -   -  S[        U 5      [        U5      -  -   -  [        X-   5      U-  [        R                  [        R                  44nU[        U 5      -  [        U5      -  U[        U 5      -  [        U5      -  -   U-   [        X-   5      U-  U-   4U[        U 5      -  [        U5      -  U[        U 5      -  [        U5      -  -
  U-   [        X-   5      U-  U-   4U[        U 5      -  [        U5      -  U[        U 5      -  [        U5      -  -
  U-   [        X-
  5      U-  U-   4U[        U 5      -  [        U5      -  U[        U 5      -  [        U5      -  -   U-   [        X-
  5      U-  U-   4U[        U 5      -  [        U5      -  U[        U5      -  [        U 5      -  -   U-   [        X-   5      U-  U-   4U[        U 5      -  [        U5      -  U[        U 5      -  [        U5      -  -   U-   [        X-   5      U-  U-   44nU [        U5      S-  -  X [        U5      S-  -  -
  4U [	        U5      S-  -  U S[        U5      -  S-  -  U -
  4U [        U5      S-  -  U S[        U5      -  S-  -  U -
  4U [        X-   5      -  U [        U5      [        U5      -  [        U5      [        U5      -  -   -  4U [        X-   5      -  U [        U5      [        U5      -  [        U5      [        U5      -  -
  -  4U [	        X-   5      -  U [	        U5      [	        U5      -   S[	        U5      [	        U5      -  -
  -  -  4U [        U5      S-  -  U [        U5      S-  -  U -
  4U [        U5      S-  -  X S[        U5      -  S-  -  -
  4U [        U5      S-  -  X S[        U5      -  S-  -  -   4U [        X-   5      -  U [        U5      [        U5      -  [        U5      [        U5      -  -   -  4U [        X-   5      -  U [        U5      [        U5      -  [        U5      [        U5      -  -   -  4U [        X-   5      -  U [        U5      [        U5      -   S[        U5      [        U5      -  -   -  -  44nX [        U5      S-  -  -
  U-   U [        U5      S-  -  U-   [        4X S[        U5      -  S-  -  -
  U-   U * [	        U5      S-  -  U-   [        4X S[        U5      -  S-  -  -
  U-   U * [        U5      S-  -  U-   [        4X [        U5      S-  -  -
  U-   U * [        U5      S-  -  U-   [        4X S[        U5      -  S-  -  -
  U-   U [        U5      S-  -  U-   [        4X S[        U5      -  S-  -  -   U-   U [        U5      S-  -  U-   [        4X-  X-  [        U5      S-  -  -
  U-   X-  [        U5      S-  -  U-   [        4X-  X-  S[        U5      -  S-  -  -
  U-   U * U-  [	        U5      S-  -  U-   [        4X-  X-  S[        U5      -  S-  -  -
  U-   U * U-  [        U5      S-  -  U-   [        4X-  X-  [        U5      S-  -  -
  U-   U * U-  [        U5      S-  -  U-   [        4X-  X-  S[        U5      -  S-  -  -
  U-   X-  [        U5      S-  -  U-   [        4X-  X-  S[        U5      -  S-  -  -   U-   X-  [        U5      S-  -  U-   [        44nXX#XEXg4q[        $ )Nza b crd   r	  F)commutativer8   rH   )r   r   r   r   r#   r$   r"   r    r!   r   r   r%   _trigpat)r   r   rQ   r	  matchers_divisionmatchers_addmatchers_identity	artifactss           rC   	_trigpatsr&  ,  s6
   g4(GA!Se$A 
3q619SVQY	#a&!)SVSV<	
3q619SVQY	#a&!)SVSV<	
3q619SVQY	#a&!)SVSV<	
3q619SVQY	#a&!)SVSV<	
3q619SVQY	#a&!)SVSV<	
3q619SVQY	3q63q62	
CFQJ?	CFQJ?	*A	zAos1vz3q6A:	7	
CFQJ?	CFQJ?	*A	zAos1vz3q6A:	7 
47A:d1gqj	 !DGQJ,quu=	
47A:d1gqj	 !DGQJ,quu=	
47A:d1gqj	 !DGQJ,quu=	
47A:d1gqj	 !DGQJ,quu=	
47A:d1gqj	 !DGQJ,quu=	
47A:d1gqj	 !QUUAEE2	
DGd1g	DGDGO 3	4KM155!%%	)'0 
3q6#a&1SV8CF?	*Q	.AE
1q0@A	
3q6#a&1SV8CF?	*Q	.AE
1q0@A	
3q6#a&1SV8CF?	*Q	.AE
1q0@A	
3q6#a&1SV8CF?	*Q	.AE
1q0@A	
4747	QtAwYtAw.	.	2DKMA4EF	
4747	QtAwYtAw.	.	2DKMA4EFL 
3q619aCFAI+o&	
3q619a3q6Ao)*	
3q619a3q6Ao)*	
3qu:q#a&Q-#a&Q-789	
3qu:q#a&Q-#a&Q-789	
3qu:q3q6CF?QQA->?@A	
47A:qa!|a'(	
47A:qaQi!^++,	
47A:qaQi!^++,	
4;4747?T!WT!W_<=>	
4;4747?T!WT!W_<=>	
4;DGd1g-DGDGO0CDEF( 
s1vqy[1	aA	kAos3	
#a&1}_	q	 1"SVQY,"2C8	
#a&1}_	q	 1"SVQY,"2C8	
tAwz\	A	r$q'1*}q0$7	
$q'	A~		!1T!WaZ<!#3T:	
$q'	A~		!1T!WaZ<!#3T: 
qs3q619}	q	 !#c!fai-!"3S9	
qsAc!fHq= 	 1	$qbd3q619nq&8#>	
qsAc!fHq= 	 1	$qbd3q619nq&8#>	
qs47A:~		!A2a4Q
?Q#6=	
qsAd1gI>!	!A	%qs47A:~'94@	
qsAd1gI>!	!A	%qs47A:~'94@!I& a-&HOrX   c                    [        [        5      n[        [        5      n/ nU R                   H  n	U	R                  (       d  U	R                  X4;   a  U	R                  5       u  pU
R                  (       d  UR                  (       aV  U
R                  U:X  a  XjR                  S   ==   U-  ss'   M  U
R                  U:X  a  XzR                  S   ==   U-  ss'   M  UR                  U	5        M     [        U5      [        U5      -  nSnU(       aq  UR                  5       nUR                  U5      nUR                  U5      nX" U5      :X  a#  UR                  U" U5      U" U5      -  5        SnOXU'   UX~'   U(       a  Mq  U(       d  U $ U(       a5  UR                  5       u  pUR                  U" U5      U-  5        U(       a  M5  U(       a5  UR                  5       u  pUR                  U" U5      U-  5        U(       a  M5  [        U6 $ )zHelper for _match_div_rewrite.

Replace f(b_)**c_*g(b_)**(rexp(c_)) with h(b)**rexph(c) if f(b_)
and g(b_) are both positive or if c_ is an integer.
r   FT)r   intrg   r   rf   as_base_expis_positive
is_integerr:   rM   r   popitemr
   )r   r   rs   rexphrexphfargsgargsrg   rB   r   rA   commonhitrz   feges                    rC   _replace_mul_fpowxgpowr6    s    EEDYY88qvv!'==?DA}}66Q;&&)$)$VVq[&&)$)$A  Z#e*$F
C
jjlYYs^YYs^b>KK#b	)*C#JEJ & 
AcFAI % AcFAI % :rX   c                     U $ r[   r\   r   s    rC   r   r     s    rX   c                     U * $ r[   r\   r   s    rC   r   r     s    1"rX   c                 "    [         R                  $ r[   )r   r   r   s    rC   r   r     s    rX   c                 $   US:X  a&  [        U [        [        [        [        [
        5      n U $ US:X  a&  [        U [        [        [
        [        [
        5      n U $ US:X  a&  [        U [        [        [
        [        [
        5      n U $ US:X  a&  [        U [        [        [        [        [        5      n U $ US:X  a&  [        U [        [        [        [        [        5      n U $ US:X  a&  [        U [        [        [
        [        [
        5      n U $ US:X  a&  [        U [        [        [        [        [
        5      n U $ US:X  a&  [        U [        [        [
        [        [
        5      n U $ US	:X  a&  [        U [        [        [
        [        [
        5      n U $ US
:X  a&  [        U [        [        [        [        [        5      n U $ US:X  a&  [        U [        [        [        [        [        5      n U $ US:X  a&  [        U [        [        [
        [        [
        5      n U $ g)zhelper for __trigsimpr   r8   rH               	   
            N)r6  r   r   _midnr#   _idnr$   _oner"   r    r!   r%   )r   is     rC   _match_div_rewriterH    s   Av%dC3L KI 
a%dC#tF KC 
a%dC#t@ K= 
a%dC3: K7 
a%dC34 K1 
a%dC$. K) 
a%dD$4& K# 
a%dD$$  K 
b%dD$$ K 
b%dD$4  K 
b%dD$4  K 
b%dD$$ K rX   c                 L    U R                   " [        6 (       a  [        X5      $ U $ r[   )r   r   
__trigsimp)r   r   s     rC   r  r    s      xx$%%KrX   c           	      j  ^^^ SSK Jn  [        c
  [        5         [        u  mmp4pVpxU R                  (       Gay  U R
                  (       dK  U R                  5       u  p[        [        R                  " U	5      U5      [        R                  " U
5      -  n GO[        U5       GH  u  nu  pp[        X5      (       d  M  [        X5      nUb  UU :w  a  Un   OM6  U R                  U5      mT(       d  MP  TR                  US5      (       d  Mi  TU   R                  (       dH  UR!                  T5      nUR"                  (       d  M  UR!                  T5      nUR"                  (       d  M  [%        UU4S jTT   R'                  [(        [*        5       5       5      (       a  M  UR!                  T5      n   O   U R,                  (       Ga  / nU R.                   H  nUR
                  (       d?  UR                  5       u  p[        R                  " U
5      n
[        R                  " U	5      nO[0        R2                  n
[        UU5      nU H-  u  nnUR                  U5      mTc  M  UR!                  T5      n  O   UR5                  UU
-  5        M     UU R.                  :w  a   [7        U6 n [9        U [;        U 5      [<        S9n U R,                  (       a  U H  u  nn[        X5      (       d  M  U" U 5      n U R?                  [*        5      (       d  M<  U R                  U5      mTbC  TT;   a=  TT;   a7  [%        UUU4S jTU   R'                  [(        [*        5       5       5      (       a  M  UR!                  T5      n   O   U GH  u  nnn[        X5      (       d  M  [A        SU/S9nUR!                  TU5      nUR!                  TU5      nU R                  U5      nSnU(       d  Me  UU :w  d  Mm  U nUU   S:X  d&  UU   * UU   R.                  ;   d  UU   UU   -   S:X  a  M  UU;   a  UU   UU   -  UU   -   S:X  a  M  UR!                  U5      n U R                  U5      nURC                  U[0        RD                  5        U(       d  GM	  UU :w  a  M  GM     OnU R                  (       d)  U RF                  (       d  U(       aE  U R.                  (       a4  U RH                  " U R.                   Vs/ s H  n[        UU5      PM     sn6 n  U R>                  " [J        6 (       d  [L        eU R'                  [N        5      nU RQ                  [N        US	9nUU:X  a  [L        e[S        U5      nUU:w  a  [9        U[S        U5      /[<        S9nUR'                  [N        5      U-
  (       d  Un U $ s  snf ! [L         a     U $ f = f)
zrecursive helper for trigsimpr   )TR10iNc              3   L   >#    U  H  oR                   S    TT   :H  v   M     g7fr   Nrg   )r]   r  r   ry   s     rC   r_   __trigsimp.<locals>.<genexpr>  s+      H 9G166!9A. 9Gs   !$)rz   c              3   V   >#    U  H  oR                   S    TT   TT   4;   v   M      g7frN  rO  )r]   r  r   r   ry   s     rC   r_   rP  0  s7      IH@G!q	c!fc!f%55 @Gs   &)r   )r   )r   )*r   rL  r!  r&  r   is_commutativer   r  r
   
_from_args	enumerater  rH  matchr  r+  rK   r*  rl   r  r(   r'   r   rg   r   r   r:   r   r   r   r   r   r   ri   Zeror   rf   r   	TypeErrorr   r   r*   )r   r   rL  rQ   r	  r"  r#  r$  r%  comncrG  patternsimpok1ok2r   okrg   termr  r   a_tr   r  r   rA   r   fnewr   ry   s                            `   @@rC   rJ  rJ    s    (#+!Aq!!{{{""mmoGCS^^C0$7r8JJD09:K0L,,G3t--,T5&$&  jj)33771a==q6,, XXc]!~~$ XXc]!~~$  HA13E9G H H H 99S>D; 1M> {{{IID&&--/^^B'~~c*UUT4(D#4jj)?!;;s+D	 $5
 KKR   499:DtVD\y9D;;#/t--T{88.//**W-C {18SS IH?B1v||13E@GIH FH FH !!;;s+D $0$ $-GVR4)) sRD)Cll1c*G[[C(F

7#AC!tS6Q;31Q499,#10B6afQqTkAaD0A5{{1~JJw'Q' !t $-. 
t		yytyyAy!9Q-yABxx OJJsOll3Tl*!8Oc{3;sF3K(i8C		#"D K% B  Ks   &VBV$ $
V21V2)hyperc                   SSK Jn  [        U 5      n [        U [        5      (       d  U $ U R
                  (       d  U $ U n[        U [        5      n U(       a:  U R                  [        5      (       a   U" U 5      u  pU" [        U [        5      5      n X:w  aE  U R                  (       a4  U R
                  S   R                  (       a  [        U R                  5       6 n U $ )a  Return simplified ``e`` using Fu-like transformations.
This is not the "Fu" algorithm. This is called by default
from ``trigsimp``. By default, hyperbolics subexpressions
will be simplified, but this can be disabled by setting
``hyper=False``.

Examples
========

>>> from sympy import trigsimp, tan, sinh, tanh
>>> from sympy.simplify.trigsimp import futrig
>>> from sympy.abc import x
>>> trigsimp(1/tan(x)**2)
tan(x)**(-2)

>>> futrig(sinh(x)/tanh(x))
cosh(x)

r   )r   )r   r   r   r9   r   rg   r   _futrigr   r'   r   is_Rationalr
   as_coeff_Mul)rA   rb  kwargsr   r   r   s         rC   r   r   g  s    ( 0
Aa66
C!WA)**Qi7#$xAHH!6!6!"HrX   c           !      N  ^^^^^^^^^^ SSK JnJmJnJmJnJmJnJnJ	mJ
mJmJnJmJnJnJn	Jn
JmJm  U R)                  [*        5      (       d  U $ U R,                  (       a  U R/                  [*        5      u  pOSnU4S jnS m[0        UUTU4S jT[0        U4S j/TU4S jU
TUXTU4S	 jU
[0        U4S
 j/UU[0        U/[0        UU4S j/UU4S jUU4S j/UU4S jUU4S j/U[0        T/[0        UU4S j/UTT[0        UU4S j/4/n[3        XS9" U 5      n Ub  X-  n U $ )zHelper for futrig.r   )TR1TR2TR3r   TR10LrL  TR8TR6TR15TR16TR111TR5TRmorrieTR11_TR11TR14TR22TR12Nc                    > T" U 5      U R                  5       [        U 5      [        U R                  5      U R                  4$ r[   )r   r   ro   rg   r   )rB   rm  s    rC   r   _futrig.<locals>.<lambda>  s*    adAKKM6!9c!&&k188LrX   c                 ,    U R                  [        5      $ r[   )r   r(   r   s    rC   r   r{    s    aee12rX   c                 &   > [        [        U T5      $ r[   _eapplyr*   rB   trigss    rC   r   r{        '&!U+rX   c                 &   > [        [        U T5      $ r[   r  r   r  s    rC   r   r{        WXq%8rX   c                     > [        S U T5      $ )Nc                 4    [        U R                  5       5      $ r[   )r*   normal)rG  s    rC   r   +_futrig.<locals>.<lambda>.<locals>.<lambda>  s    F188:$6rX   )r  r  s    rC   r   r{    s    '65ArX   c                 &   > [        [        U T5      $ r[   r~  r  s    rC   r   r{    r  rX   c                 &   > [        [        U T5      $ r[   r  r  s    rC   r   r{    r  rX   c                     > T" T" U 5      5      $ r[   r\   )rB   rj  r   s    rC   r   r{    s    T#a&\rX   c                 2   > [        [        T" U 5      T5      $ r[   r  r   )rB   rs  r  s    rC   r   r{    s    gj#a&%8rX   c                 2   > [        [        T" U 5      T5      $ r[   r  )rB   rp  r  s    rC   r   r{    s    gDGU,rX   c                 2   > [        [        T" U 5      T5      $ r[   r  )rB   ro  r  s    rC   r   r{    s    wz3q659rX   c                 2   > [        [        T" U 5      T5      $ r[   r  )rB   rq  r  s    rC   r   r{    s    wDGU,rX   c                 2   > [        [        T" U 5      T5      $ r[   r  )rB   rx  r  s    rC   r   r{    s    WQ(rX   c                 2   > [        [        T" U 5      T5      $ r[   )r  r	   )rB   ry  r  s    rC   r   r{    s    W$q'5*rX   )	objective)r   ri  rj  rk  r   rl  rm  rL  rn  ro  rp  rq  rr  rs  rt  ru  rv  rw  rx  ry  r   r(   r   r  r1   r2   )rA   ri  rk  rl  rL  rn  rr  rt  ru  rv  rw  rP   Lopstreerm  ry  rp  rq  rj  rx  r   rs  ro  r  s                 @@@@@@@@@@rC   rd  rd    s3        
 55&''xx##$9:qLD2E+	89AS+	89	3	)*8,	-
 :,	- 		4	 ( 	)S$	 * 	+C#	
$DJ 	t$Q'AIHrX   c                     [        U [        5      (       a  [        U R                  5      $ [        U [        5      (       d  g[        S U R                   5       5      $ )z@_eapply helper to tell whether ``e`` and all its args
are Exprs.Fc              3   8   #    U  H  n[        U5      v   M     g 7fr[   )_is_Expr)r]   rG  s     rC   r_   _is_Expr.<locals>.<genexpr>  s     +Fqx{{Fs   )r9   r   r  r   r   allrg   )rA   s    rC   r  r    sE     !Z  a+AFF+++rX   c           	         [        U[        5      (       d  U$ [        U5      (       d  UR                  (       d  U " U5      $ UR                  " UR                   Vs/ s H   nUb  U" U5      (       a  [        X5      OUPM"     sn6 $ s  snf )z`Apply ``func`` to ``e`` if all args are Exprs else only
apply it to those args that *are* Exprs.)r9   r   r  rg   rf   r  )rf   rA   condeis       rC   r  r    sy     a{{!&&Aw66&&B #ld2hhR?   s   'B)Fr[   )\collectionsr   	functoolsr   
sympy.corer   r   r   r   r	   r
   r   r   sympy.core.cacher   sympy.core.functionr   r   r   r   r   r   r   sympy.core.numbersr   r   sympy.core.intfuncr   sympy.core.sortingr   sympy.core.symbolr   r   r   sympy.external.gmpyr   sympy.functionsr   r   r   r    r!   r"   r#   r$   r%   r&   %sympy.functions.elementary.hyperbolicr'   (sympy.functions.elementary.trigonometricr(   sympy.polysr)   r*   r+   r,   sympy.polys.domainsr-   sympy.polys.polyerrorsr.   sympy.polys.polytoolsr/   sympy.simplify.cse_mainr0   sympy.strategies.corer1   sympy.strategies.treer2   sympy.utilities.iterablesr3   sympy.utilities.miscr4   r   r   r   r   r   r   r  r!  r&  r6  rE  rD  rF  rH  r  rJ  r   rd  r  r  r\   rX   rC   <module>r     s   # - - - $G G G ) # % 2 2 * K K K ! D J E E " 5 * ' * ( . &"$E!&KF\  !3	4DiX[~ !% EPA Qh)X )X 	~ 	~D  (V<~,	rX   