1"""
2Utility functions for Rubi integration.
3
4See: http://www.apmaths.uwo.ca/~arich/IntegrationRules/PortableDocumentFiles/Integration%20utility%20functions.pdf
5"""
6from sympy.external import import_module
7matchpy = import_module("matchpy")
8from sympy import (Basic, E, polylog, N, Wild, WildFunction, factor, gcd, Sum,
9    S, I, Mul, Integer, Float, Dict, Symbol, Rational, Add, hyper, symbols,
10    sqf_list, sqf, Max, factorint, factorrat, Min, sign, E, Function, collect,
11    FiniteSet, nsimplify, expand_trig, expand, poly, apart, lcm, And, Pow, pi,
12    zoo, oo, Integral, UnevaluatedExpr, PolynomialError, Dummy, exp as sym_exp,
13    powdenest, PolynomialDivisionFailed, discriminant, UnificationFailed, appellf1)
14from sympy.core.exprtools import factor_terms
15from sympy.core.sympify import sympify
16from sympy.functions import (log as sym_log, sin, cos, tan, cot, csc, sec,
17                             sqrt, erf, gamma, uppergamma, polygamma, digamma,
18                             loggamma, factorial, zeta, LambertW)
19from sympy.functions.elementary.complexes import im, re, Abs
20from sympy.functions.elementary.hyperbolic import acosh, asinh, atanh, acoth, acsch, asech, cosh, sinh, tanh, coth, sech, csch
21from sympy.functions.elementary.integers import floor, frac
22from sympy.functions.elementary.trigonometric import atan, acsc, asin, acot, acos, asec, atan2
23from sympy.functions.special.elliptic_integrals import elliptic_f, elliptic_e, elliptic_pi
24from sympy.functions.special.error_functions import fresnelc, fresnels, erfc, erfi, Ei, expint, li, Si, Ci, Shi, Chi
25from sympy.functions.special.hyper import TupleArg
26from sympy.logic.boolalg import Or
27from sympy.polys.polytools import Poly, quo, rem, total_degree, degree
28from sympy.simplify.simplify import fraction, simplify, cancel, powsimp
29from sympy.utilities.decorator import doctest_depends_on
30from sympy.utilities.iterables import flatten, postorder_traversal
31from random import randint
32
33
34class rubi_unevaluated_expr(UnevaluatedExpr):
35    """
36    This is needed to convert `exp` as `Pow`.
37    sympy's UnevaluatedExpr has an issue with `is_commutative`.
38    """
39    @property
40    def is_commutative(self):
41        from sympy.core.logic import fuzzy_and
42        return fuzzy_and(a.is_commutative for a in self.args)
43
44_E = rubi_unevaluated_expr(E)
45
46
47class rubi_exp(Function):
48    """
49    sympy's exp is not identified as `Pow`. So it is not matched with `Pow`.
50    Like `a = exp(2)` is not identified as `Pow(E, 2)`. Rubi rules need it.
51    So, another exp has been created only for rubi module.
52
53    Examples
54    ========
55
56    >>> from sympy import Pow, exp as sym_exp
57    >>> isinstance(sym_exp(2), Pow)
58    False
59    >>> from sympy.integrals.rubi.utility_function import rubi_exp
60    >>> isinstance(rubi_exp(2), Pow)
61    True
62
63    """
64    @classmethod
65    def eval(cls, *args):
66        return Pow(_E, args[0])
67
68class rubi_log(Function):
69    """
70    For rule matching different `exp` has been used. So for proper results,
71    `log` is modified little only for case when it encounters rubi's `exp`.
72    For other cases it is same.
73
74    Examples
75    ========
76
77    >>> from sympy.integrals.rubi.utility_function import rubi_exp, rubi_log
78    >>> a = rubi_exp(2)
79    >>> rubi_log(a)
80    2
81
82    """
83    @classmethod
84    def eval(cls, *args):
85        if args[0].has(_E):
86            return sym_log(args[0]).doit()
87        else:
88            return sym_log(args[0])
89
90if matchpy:
91    from matchpy import Arity, Operation, CustomConstraint, Pattern, ReplacementRule, ManyToOneReplacer
92    from sympy.integrals.rubi.symbol import WC
93    from matchpy import is_match, replace_all
94
95    class UtilityOperator(Operation):
96        name = 'UtilityOperator'
97        arity = Arity.variadic
98        commutative = False
99        associative = True
100
101    Operation.register(rubi_log)
102    Operation.register(rubi_exp)
103
104    A_, B_, C_, F_, G_, a_, b_, c_, d_, e_, f_, g_, h_, i_, j_, k_, l_, m_, \
105    n_, p_, q_, r_, t_, u_, v_, s_, w_, x_, z_ = [WC(i) for i in 'ABCFGabcdefghijklmnpqrtuvswxz']
106    a, b, c, d, e = symbols('a b c d e')
107
108
109Int = Integral
110
111
112def replace_pow_exp(z):
113    """
114    This function converts back rubi's `exp` to general sympy's `exp`.
115
116    Examples
117    ========
118
119    >>> from sympy.integrals.rubi.utility_function import rubi_exp, replace_pow_exp
120    >>> expr = rubi_exp(5)
121    >>> expr
122    E**5
123    >>> replace_pow_exp(expr)
124    exp(5)
125
126    """
127    z = S(z)
128    if z.has(_E):
129        z = z.replace(_E, E)
130    return z
131
132def Simplify(expr):
133    expr = simplify(expr)
134    return expr
135
136def Set(expr, value):
137    return {expr: value}
138
139def With(subs, expr):
140    if isinstance(subs, dict):
141        k = list(subs.keys())[0]
142        expr = expr.xreplace({k: subs[k]})
143    else:
144        for i in subs:
145            k = list(i.keys())[0]
146            expr = expr.xreplace({k: i[k]})
147    return expr
148
149def Module(subs, expr):
150    return With(subs, expr)
151
152def Scan(f, expr):
153    # evaluates f applied to each element of expr in turn.
154    for i in expr:
155        yield f(i)
156
157def MapAnd(f, l, x=None):
158    # MapAnd[f,l] applies f to the elements of list l until False is returned; else returns True
159    if x:
160        for i in l:
161            if f(i, x) == False:
162                return False
163        return True
164    else:
165        for i in l:
166            if f(i) == False:
167                return False
168        return True
169
170def FalseQ(u):
171    if isinstance(u, (Dict, dict)):
172        return FalseQ(*list(u.values()))
173
174    return u == False
175
176def ZeroQ(*expr):
177    if len(expr) == 1:
178        if isinstance(expr[0], list):
179            return list(ZeroQ(i) for i in expr[0])
180        else:
181
182            return Simplify(expr[0]) == 0
183    else:
184        return all(ZeroQ(i) for i in expr)
185
186def OneQ(a):
187    if a == S(1):
188        return True
189    return False
190
191def NegativeQ(u):
192    u = Simplify(u)
193    if u in (zoo, oo):
194        return False
195    if u.is_comparable:
196        res = u < 0
197        if not res.is_Relational:
198            return res
199    return False
200
201def NonzeroQ(expr):
202    return Simplify(expr) != 0
203
204
205def FreeQ(nodes, var):
206    if isinstance(nodes, list):
207        return not any(S(expr).has(var) for expr in nodes)
208    else:
209        nodes = S(nodes)
210        return not nodes.has(var)
211
212def NFreeQ(nodes, var):
213    """ Note that in rubi 4.10.8 this function was not defined in `Integration Utility Functions.m`,
214    but was used in rules. So explicitly its returning `False`
215    """
216    return False
217    # return not FreeQ(nodes, var)
218
219def List(*var):
220    return list(var)
221
222def PositiveQ(var):
223    var = Simplify(var)
224    if var in (zoo, oo):
225        return False
226    if var.is_comparable:
227        res = var > 0
228        if not res.is_Relational:
229            return res
230    return False
231
232def PositiveIntegerQ(*args):
233    return all(var.is_Integer and PositiveQ(var) for var in args)
234
235def NegativeIntegerQ(*args):
236    return all(var.is_Integer and NegativeQ(var) for var in args)
237
238def IntegerQ(var):
239    var = Simplify(var)
240    if isinstance(var, (int, Integer)):
241        return True
242    else:
243        return var.is_Integer
244
245def IntegersQ(*var):
246    return all(IntegerQ(i) for i in var)
247
248def _ComplexNumberQ(var):
249    i = S(im(var))
250    if isinstance(i, (Integer, Float)):
251        return i != 0
252    else:
253        return False
254
255def ComplexNumberQ(*var):
256    """
257    ComplexNumberQ(m, n,...) returns True if m, n, ... are all explicit complex numbers, else it returns False.
258
259    Examples
260    ========
261
262    >>> from sympy.integrals.rubi.utility_function import ComplexNumberQ
263    >>> from sympy import I
264    >>> ComplexNumberQ(1 + I*2, I)
265    True
266    >>> ComplexNumberQ(2, I)
267    False
268
269    """
270    return all(_ComplexNumberQ(i) for i in var)
271
272def PureComplexNumberQ(*var):
273    return all((_ComplexNumberQ(i) and re(i)==0) for i in var)
274
275def RealNumericQ(u):
276    return u.is_real
277
278def PositiveOrZeroQ(u):
279    return u.is_real and u >= 0
280
281def NegativeOrZeroQ(u):
282    return u.is_real and u <= 0
283
284def FractionOrNegativeQ(u):
285    return FractionQ(u) or NegativeQ(u)
286
287def NegQ(var):
288    return Not(PosQ(var)) and NonzeroQ(var)
289
290
291def Equal(a, b):
292    return a == b
293
294def Unequal(a, b):
295    return a != b
296
297def IntPart(u):
298    # IntPart[u] returns the sum of the integer terms of u.
299    if ProductQ(u):
300        if IntegerQ(First(u)):
301            return First(u)*IntPart(Rest(u))
302    elif IntegerQ(u):
303        return u
304    elif FractionQ(u):
305        return IntegerPart(u)
306    elif SumQ(u):
307        res = 0
308        for i in u.args:
309            res += IntPart(i)
310        return res
311    return 0
312
313def FracPart(u):
314    # FracPart[u] returns the sum of the non-integer terms of u.
315    if ProductQ(u):
316        if IntegerQ(First(u)):
317            return First(u)*FracPart(Rest(u))
318
319    if IntegerQ(u):
320        return 0
321    elif FractionQ(u):
322        return FractionalPart(u)
323    elif SumQ(u):
324        res = 0
325        for i in u.args:
326            res += FracPart(i)
327        return res
328    else:
329        return u
330
331def RationalQ(*nodes):
332    return all(var.is_Rational for var in nodes)
333
334def ProductQ(expr):
335    return S(expr).is_Mul
336
337def SumQ(expr):
338    return expr.is_Add
339
340def NonsumQ(expr):
341    return not SumQ(expr)
342
343def Subst(a, x, y):
344    if None in [a, x, y]:
345        return None
346    if a.has(Function('Integrate')):
347        # substituting in `Function(Integrate)` won't take care of properties of Integral
348        a = a.replace(Function('Integrate'), Integral)
349    return a.subs(x, y)
350    # return a.xreplace({x: y})
351
352def First(expr, d=None):
353    """
354    Gives the first element if it exists, or d otherwise.
355
356    Examples
357    ========
358
359    >>> from sympy.integrals.rubi.utility_function import First
360    >>> from sympy.abc import  a, b, c
361    >>> First(a + b + c)
362    a
363    >>> First(a*b*c)
364    a
365
366    """
367    if isinstance(expr, list):
368        return expr[0]
369    if isinstance(expr, Symbol):
370        return expr
371    else:
372        if SumQ(expr) or ProductQ(expr):
373            l = Sort(expr.args)
374            return l[0]
375        else:
376            return expr.args[0]
377
378def Rest(expr):
379    """
380    Gives rest of the elements if it exists
381
382    Examples
383    ========
384
385    >>> from sympy.integrals.rubi.utility_function import Rest
386    >>> from sympy.abc import  a, b, c
387    >>> Rest(a + b + c)
388    b + c
389    >>> Rest(a*b*c)
390    b*c
391
392    """
393    if isinstance(expr, list):
394        return expr[1:]
395    else:
396        if SumQ(expr) or ProductQ(expr):
397            l = Sort(expr.args)
398            return expr.func(*l[1:])
399        else:
400            return expr.args[1]
401
402def SqrtNumberQ(expr):
403    # SqrtNumberQ[u] returns True if u^2 is a rational number; else it returns False.
404    if PowerQ(expr):
405        m = expr.base
406        n = expr.exp
407        return (IntegerQ(n) and SqrtNumberQ(m)) or (IntegerQ(n-S(1)/2) and RationalQ(m))
408    elif expr.is_Mul:
409        return all(SqrtNumberQ(i) for i in expr.args)
410    else:
411        return RationalQ(expr) or expr == I
412
413def SqrtNumberSumQ(u):
414    return SumQ(u) and SqrtNumberQ(First(u)) and SqrtNumberQ(Rest(u)) or ProductQ(u) and SqrtNumberQ(First(u)) and SqrtNumberSumQ(Rest(u))
415
416def LinearQ(expr, x):
417    """
418    LinearQ(expr, x) returns True iff u is a polynomial of degree 1.
419
420    Examples
421    ========
422
423    >>> from sympy.integrals.rubi.utility_function import LinearQ
424    >>> from sympy.abc import  x, y, a
425    >>> LinearQ(a, x)
426    False
427    >>> LinearQ(3*x + y**2, x)
428    True
429    >>> LinearQ(3*x + y**2, y)
430    False
431
432    """
433    if isinstance(expr, list):
434        return all(LinearQ(i, x) for i in expr)
435    elif expr.is_polynomial(x):
436        if degree(Poly(expr, x), gen=x) == 1:
437            return True
438    return False
439
440def Sqrt(a):
441    return sqrt(a)
442
443def ArcCosh(a):
444    return acosh(a)
445
446class Util_Coefficient(Function):
447    def doit(self):
448        if len(self.args) == 2:
449            n = 1
450        else:
451            n = Simplify(self.args[2])
452
453        if NumericQ(n):
454            expr = expand(self.args[0])
455            if isinstance(n, (int, Integer)):
456                return expr.coeff(self.args[1], n)
457            else:
458                return expr.coeff(self.args[1]**n)
459        else:
460            return self
461
462def Coefficient(expr, var, n=1):
463    """
464    Coefficient(expr, var) gives the coefficient of form in the polynomial expr.
465    Coefficient(expr, var, n) gives the coefficient of var**n in expr.
466
467    Examples
468    ========
469
470    >>> from sympy.integrals.rubi.utility_function import Coefficient
471    >>> from sympy.abc import  x, a, b, c
472    >>> Coefficient(7 + 2*x + 4*x**3, x, 1)
473    2
474    >>> Coefficient(a + b*x + c*x**3, x, 0)
475    a
476    >>> Coefficient(a + b*x + c*x**3, x, 4)
477    0
478    >>> Coefficient(b*x + c*x**3, x, 3)
479    c
480
481    """
482    if NumericQ(n):
483        if expr == 0 or n in (zoo, oo):
484            return 0
485        expr = expand(expr)
486        if isinstance(n, (int, Integer)):
487            return expr.coeff(var, n)
488        else:
489            return expr.coeff(var**n)
490
491    return Util_Coefficient(expr, var, n)
492
493def Denominator(var):
494    var = Simplify(var)
495    if isinstance(var, Pow):
496        if isinstance(var.exp, Integer):
497            if var.exp > 0:
498                return Pow(Denominator(var.base), var.exp)
499            elif var.exp < 0:
500                return Pow(Numerator(var.base), -1*var.exp)
501    elif isinstance(var, Add):
502        var = factor(var)
503    return fraction(var)[1]
504
505def Hypergeometric2F1(a, b, c, z):
506    return hyper([a, b], [c], z)
507
508def Not(var):
509    if isinstance(var, bool):
510        return not var
511    elif var.is_Relational:
512        var = False
513    return not var
514
515
516def FractionalPart(a):
517    return frac(a)
518
519def IntegerPart(a):
520    return floor(a)
521
522def AppellF1(a, b1, b2, c, x, y):
523    return appellf1(a, b1, b2, c, x, y)
524
525def EllipticPi(*args):
526    return elliptic_pi(*args)
527
528def EllipticE(*args):
529    return elliptic_e(*args)
530
531def EllipticF(Phi, m):
532    return elliptic_f(Phi, m)
533
534def ArcTan(a, b = None):
535    if b is None:
536        return atan(a)
537    else:
538        return atan2(a, b)
539
540def ArcCot(a):
541    return acot(a)
542
543def ArcCoth(a):
544    return acoth(a)
545
546def ArcTanh(a):
547    return atanh(a)
548
549def ArcSin(a):
550    return asin(a)
551
552def ArcSinh(a):
553    return asinh(a)
554
555def ArcCos(a):
556    return acos(a)
557
558def ArcCsc(a):
559    return acsc(a)
560
561def ArcSec(a):
562    return asec(a)
563
564def ArcCsch(a):
565    return acsch(a)
566
567def ArcSech(a):
568    return asech(a)
569
570def Sinh(u):
571    return sinh(u)
572
573def Tanh(u):
574    return tanh(u)
575
576def Cosh(u):
577    return cosh(u)
578
579def Sech(u):
580    return sech(u)
581
582def Csch(u):
583    return csch(u)
584
585def Coth(u):
586    return coth(u)
587
588def LessEqual(*args):
589    for i in range(0, len(args) - 1):
590        try:
591            if args[i] > args[i + 1]:
592                return False
593        except (IndexError, NotImplementedError):
594            return False
595    return True
596
597def Less(*args):
598    for i in range(0, len(args) - 1):
599        try:
600            if args[i] >= args[i + 1]:
601                return False
602        except (IndexError, NotImplementedError):
603            return False
604    return True
605
606def Greater(*args):
607    for i in range(0, len(args) - 1):
608        try:
609            if args[i] <= args[i + 1]:
610                return False
611        except (IndexError, NotImplementedError):
612            return False
613    return True
614
615def GreaterEqual(*args):
616    for i in range(0, len(args) - 1):
617        try:
618            if args[i] < args[i + 1]:
619                return False
620        except (IndexError, NotImplementedError):
621            return False
622    return True
623
624def FractionQ(*args):
625    """
626    FractionQ(m, n,...) returns True if m, n, ... are all explicit fractions, else it returns False.
627
628    Examples
629    ========
630
631    >>> from sympy import S
632    >>> from sympy.integrals.rubi.utility_function import FractionQ
633    >>> FractionQ(S('3'))
634    False
635    >>> FractionQ(S('3')/S('2'))
636    True
637
638    """
639    return all(i.is_Rational for i in args) and all(Denominator(i) != S(1) for i in args)
640
641def IntLinearcQ(a, b, c, d, m, n, x):
642    # returns True iff (a+b*x)^m*(c+d*x)^n is integrable wrt x in terms of non-hypergeometric functions.
643    return IntegerQ(m) or IntegerQ(n) or IntegersQ(S(3)*m, S(3)*n) or IntegersQ(S(4)*m, S(4)*n) or IntegersQ(S(2)*m, S(6)*n) or IntegersQ(S(6)*m, S(2)*n) or IntegerQ(m + n)
644
645Defer = UnevaluatedExpr
646
647def Expand(expr):
648    return expr.expand()
649
650def IndependentQ(u, x):
651    """
652    If u is free from x IndependentQ(u, x) returns True else False.
653
654    Examples
655    ========
656
657    >>> from sympy.integrals.rubi.utility_function import IndependentQ
658    >>> from sympy.abc import  x, a, b
659    >>> IndependentQ(a + b*x, x)
660    False
661    >>> IndependentQ(a + b, x)
662    True
663
664    """
665    return FreeQ(u, x)
666
667def PowerQ(expr):
668    return expr.is_Pow or ExpQ(expr)
669
670def IntegerPowerQ(u):
671    if isinstance(u, sym_exp): #special case for exp
672        return IntegerQ(u.args[0])
673    return PowerQ(u) and IntegerQ(u.args[1])
674
675def PositiveIntegerPowerQ(u):
676    if isinstance(u, sym_exp):
677        return IntegerQ(u.args[0]) and PositiveQ(u.args[0])
678    return PowerQ(u) and IntegerQ(u.args[1]) and PositiveQ(u.args[1])
679
680def FractionalPowerQ(u):
681    if isinstance(u, sym_exp):
682        return FractionQ(u.args[0])
683    return PowerQ(u) and FractionQ(u.args[1])
684
685def AtomQ(expr):
686    expr = sympify(expr)
687    if isinstance(expr, list):
688        return False
689    if expr in [None, True, False, _E]: # [None, True, False] are atoms in mathematica and _E is also an atom
690        return True
691    # elif isinstance(expr, list):
692    #     return all(AtomQ(i) for i in expr)
693    else:
694        return expr.is_Atom
695
696def ExpQ(u):
697    u = replace_pow_exp(u)
698    return Head(u) in (sym_exp, rubi_exp)
699
700def LogQ(u):
701    return u.func in (sym_log, Log)
702
703def Head(u):
704    return u.func
705
706def MemberQ(l, u):
707    if isinstance(l, list):
708        return u in l
709    else:
710        return u in l.args
711
712def TrigQ(u):
713    if AtomQ(u):
714        x = u
715    else:
716        x = Head(u)
717    return MemberQ([sin, cos, tan, cot, sec, csc], x)
718
719def SinQ(u):
720    return Head(u) == sin
721
722def CosQ(u):
723    return Head(u) == cos
724
725def TanQ(u):
726    return Head(u) == tan
727
728def CotQ(u):
729    return Head(u) == cot
730
731def SecQ(u):
732    return Head(u) == sec
733
734def CscQ(u):
735    return Head(u) == csc
736
737def Sin(u):
738    return sin(u)
739
740def Cos(u):
741    return cos(u)
742
743def Tan(u):
744    return tan(u)
745
746def Cot(u):
747    return cot(u)
748
749def Sec(u):
750    return sec(u)
751
752def Csc(u):
753    return csc(u)
754
755def HyperbolicQ(u):
756    if AtomQ(u):
757        x = u
758    else:
759        x = Head(u)
760    return MemberQ([sinh, cosh, tanh, coth, sech, csch], x)
761
762def SinhQ(u):
763    return Head(u) == sinh
764
765def CoshQ(u):
766    return Head(u) == cosh
767
768def TanhQ(u):
769    return Head(u) == tanh
770
771def CothQ(u):
772    return Head(u) == coth
773
774def SechQ(u):
775    return Head(u) == sech
776
777def CschQ(u):
778    return Head(u) == csch
779
780def InverseTrigQ(u):
781    if AtomQ(u):
782        x = u
783    else:
784        x = Head(u)
785    return MemberQ([asin, acos, atan, acot, asec, acsc], x)
786
787def SinCosQ(f):
788    return MemberQ([sin, cos, sec, csc], Head(f))
789
790def SinhCoshQ(f):
791    return MemberQ([sinh, cosh, sech, csch], Head(f))
792
793def LeafCount(expr):
794    return len(list(postorder_traversal(expr)))
795
796def Numerator(u):
797    u = Simplify(u)
798    if isinstance(u, Pow):
799        if isinstance(u.exp, Integer):
800            if u.exp > 0:
801                return Pow(Numerator(u.base), u.exp)
802            elif u.exp < 0:
803                return Pow(Denominator(u.base), -1*u.exp)
804    elif isinstance(u, Add):
805        u = factor(u)
806    return fraction(u)[0]
807
808def NumberQ(u):
809    if isinstance(u, (int, float)):
810        return True
811    return u.is_number
812
813def NumericQ(u):
814    return N(u).is_number
815
816def Length(expr):
817    """
818    Returns number of elements in the expression just as sympy's len.
819
820    Examples
821    ========
822
823    >>> from sympy.integrals.rubi.utility_function import Length
824    >>> from sympy.abc import  x, a, b
825    >>> from sympy import cos, sin
826    >>> Length(a + b)
827    2
828    >>> Length(sin(a)*cos(a))
829    2
830
831    """
832    if isinstance(expr, list):
833        return len(expr)
834    return len(expr.args)
835
836def ListQ(u):
837    return isinstance(u, list)
838
839def Im(u):
840    u = S(u)
841    return im(u.doit())
842
843def Re(u):
844    u = S(u)
845    return re(u.doit())
846
847def InverseHyperbolicQ(u):
848    if not u.is_Atom:
849        u = Head(u)
850    return u in [acosh, asinh, atanh, acoth, acsch, acsch]
851
852def InverseFunctionQ(u):
853    # returns True if u is a call on an inverse function; else returns False.
854    return LogQ(u) or InverseTrigQ(u) and Length(u) <= 1 or InverseHyperbolicQ(u) or u.func == polylog
855
856def TrigHyperbolicFreeQ(u, x):
857    # If u is free of trig, hyperbolic and calculus functions involving x, TrigHyperbolicFreeQ[u,x] returns true; else it returns False.
858    if AtomQ(u):
859        return True
860    else:
861        if TrigQ(u) | HyperbolicQ(u) | CalculusQ(u):
862            return FreeQ(u, x)
863        else:
864            for i in u.args:
865                if not TrigHyperbolicFreeQ(i, x):
866                    return False
867            return True
868
869def InverseFunctionFreeQ(u, x):
870    # If u is free of inverse, calculus and hypergeometric functions involving x, InverseFunctionFreeQ[u,x] returns true; else it returns False.
871    if AtomQ(u):
872        return True
873    else:
874        if InverseFunctionQ(u) or CalculusQ(u) or u.func == hyper or u.func == appellf1:
875            return FreeQ(u, x)
876        else:
877            for i in u.args:
878                if not ElementaryFunctionQ(i):
879                    return False
880            return True
881
882def RealQ(u):
883    if ListQ(u):
884        return MapAnd(RealQ, u)
885    elif NumericQ(u):
886        return ZeroQ(Im(N(u)))
887    elif PowerQ(u):
888        u = u.base
889        v = u.exp
890        return RealQ(u) & RealQ(v) & (IntegerQ(v) | PositiveOrZeroQ(u))
891    elif u.is_Mul:
892        return all(RealQ(i) for i in u.args)
893    elif u.is_Add:
894        return all(RealQ(i) for i in u.args)
895    elif u.is_Function:
896        f = u.func
897        u = u.args[0]
898        if f in [sin, cos, tan, cot, sec, csc, atan, acot, erf]:
899            return RealQ(u)
900        else:
901            if f in [asin, acos]:
902                return LE(-1, u, 1)
903            else:
904                if f == sym_log:
905                    return PositiveOrZeroQ(u)
906                else:
907                    return False
908    else:
909        return False
910
911def EqQ(u, v):
912    return ZeroQ(u - v)
913
914def FractionalPowerFreeQ(u):
915    if AtomQ(u):
916        return True
917    elif FractionalPowerQ(u):
918        return False
919
920def ComplexFreeQ(u):
921    if AtomQ(u) and Not(ComplexNumberQ(u)):
922        return True
923    else:
924         return False
925
926def PolynomialQ(u, x = None):
927    if x is None :
928        return u.is_polynomial()
929    if isinstance(x, Pow):
930        if isinstance(x.exp, Integer):
931            deg = degree(u, x.base)
932            if u.is_polynomial(x):
933                if deg % x.exp !=0 :
934                    return False
935                try:
936                    p = Poly(u, x.base)
937                except PolynomialError:
938                    return False
939
940                c_list = p.all_coeffs()
941                coeff_list = c_list[:-1:x.exp]
942                coeff_list += [c_list[-1]]
943                for i in coeff_list:
944                    if not i == 0:
945                        index = c_list.index(i)
946                        c_list[index] = 0
947
948                if all(i == 0 for i in c_list):
949                    return True
950                else:
951                    return False
952
953            else:
954                return False
955
956        elif isinstance(x.exp, (Float, Rational)): #not full - proof
957            if FreeQ(simplify(u), x.base) and Exponent(u, x.base) == 0:
958                if not all(FreeQ(u, i) for i in x.base.free_symbols):
959                    return False
960
961    if isinstance(x, Mul):
962        return all(PolynomialQ(u, i) for i in x.args)
963
964    return u.is_polynomial(x)
965
966def FactorSquareFree(u):
967    return sqf(u)
968
969def PowerOfLinearQ(expr, x):
970    u = Wild('u')
971    w = Wild('w')
972    m = Wild('m')
973    n = Wild('n')
974    Match = expr.match(u**m)
975    if PolynomialQ(Match[u], x) and FreeQ(Match[m], x):
976        if IntegerQ(Match[m]):
977            e = FactorSquareFree(Match[u]).match(w**n)
978            if FreeQ(e[n], x) and LinearQ(e[w], x):
979                return True
980            else:
981                return False
982        else:
983            return LinearQ(Match[u], x)
984    else:
985        return False
986
987def Exponent(expr, x):
988    expr = Expand(S(expr))
989    if S(expr).is_number or (not expr.has(x)):
990        return 0
991    if PolynomialQ(expr, x):
992        if isinstance(x, Rational):
993            return degree(Poly(expr, x), x)
994        return degree(expr, gen = x)
995    else:
996        return 0
997
998def ExponentList(expr, x):
999    expr = Expand(S(expr))
1000    if S(expr).is_number or (not expr.has(x)):
1001        return [0]
1002    if expr.is_Add:
1003        expr = collect(expr, x)
1004        lst = []
1005        k = 1
1006        for t in expr.args:
1007            if t.has(x):
1008                if isinstance(x, Rational):
1009                    lst += [degree(Poly(t, x), x)]
1010                else:
1011                    lst += [degree(t, gen = x)]
1012            else:
1013                if k == 1:
1014                    lst += [0]
1015                    k += 1
1016        lst.sort()
1017        return lst
1018    else:
1019        if isinstance(x, Rational):
1020            return [degree(Poly(expr, x), x)]
1021        else:
1022            return [degree(expr, gen = x)]
1023
1024def QuadraticQ(u, x):
1025    # QuadraticQ(u, x) returns True iff u is a polynomial of degree 2 and not a monomial of the form a x^2
1026    if ListQ(u):
1027        for expr in u:
1028            if Not(PolyQ(expr, x, 2) and Not(Coefficient(expr, x, 0) == 0 and Coefficient(expr, x, 1) == 0)):
1029                return False
1030        return True
1031    else:
1032        return PolyQ(u, x, 2) and Not(Coefficient(u, x, 0) == 0 and Coefficient(u, x, 1) == 0)
1033
1034def LinearPairQ(u, v, x):
1035    # LinearPairQ(u, v, x) returns True iff u and v are linear not equal x but u/v is a constant wrt x
1036    return LinearQ(u, x) and LinearQ(v, x) and NonzeroQ(u-x) and ZeroQ(Coefficient(u, x, 0)*Coefficient(v, x, 1)-Coefficient(u, x, 1)*Coefficient(v, x, 0))
1037
1038def BinomialParts(u, x):
1039    if PolynomialQ(u, x):
1040        if Exponent(u, x) > 0:
1041            lst = ExponentList(u, x)
1042            if len(lst)==1:
1043                return [0, Coefficient(u, x, Exponent(u, x)), Exponent(u, x)]
1044            elif len(lst) == 2 and lst[0] == 0:
1045                return [Coefficient(u, x, 0), Coefficient(u, x, Exponent(u, x)), Exponent(u, x)]
1046            else:
1047                return False
1048        else:
1049            return False
1050    elif PowerQ(u):
1051        if u.base == x and FreeQ(u.exp, x):
1052            return [0, 1, u.exp]
1053        else:
1054            return False
1055    elif ProductQ(u):
1056        if FreeQ(First(u), x):
1057            lst2 = BinomialParts(Rest(u), x)
1058            if AtomQ(lst2):
1059                return False
1060            else:
1061                return [First(u)*lst2[0], First(u)*lst2[1], lst2[2]]
1062        elif FreeQ(Rest(u), x):
1063            lst1 = BinomialParts(First(u), x)
1064            if AtomQ(lst1):
1065                return False
1066            else:
1067                return [Rest(u)*lst1[0], Rest(u)*lst1[1], lst1[2]]
1068        lst1 = BinomialParts(First(u), x)
1069        if AtomQ(lst1):
1070            return False
1071        lst2 = BinomialParts(Rest(u), x)
1072        if AtomQ(lst2):
1073            return False
1074        a = lst1[0]
1075        b = lst1[1]
1076        m = lst1[2]
1077        c = lst2[0]
1078        d = lst2[1]
1079        n = lst2[2]
1080        if ZeroQ(a):
1081            if ZeroQ(c):
1082                return [0, b*d, m + n]
1083            elif ZeroQ(m + n):
1084                return [b*d, b*c, m]
1085            else:
1086                return False
1087        if ZeroQ(c):
1088            if ZeroQ(m + n):
1089                return [b*d, a*d, n]
1090            else:
1091                return False
1092        if EqQ(m, n) and ZeroQ(a*d + b*c):
1093            return [a*c, b*d, 2*m]
1094        else:
1095            return False
1096    elif SumQ(u):
1097        if FreeQ(First(u),x):
1098            lst2 = BinomialParts(Rest(u), x)
1099            if AtomQ(lst2):
1100                return False
1101            else:
1102                return [First(u) + lst2[0], lst2[1], lst2[2]]
1103        elif FreeQ(Rest(u), x):
1104            lst1 = BinomialParts(First(u), x)
1105            if AtomQ(lst1):
1106                return False
1107            else:
1108                return[Rest(u) + lst1[0], lst1[1], lst1[2]]
1109        lst1 = BinomialParts(First(u), x)
1110        if AtomQ(lst1):
1111            return False
1112        lst2 = BinomialParts(Rest(u),x)
1113        if AtomQ(lst2):
1114            return False
1115        if EqQ(lst1[2], lst2[2]):
1116            return [lst1[0] + lst2[0], lst1[1] + lst2[1], lst1[2]]
1117        else:
1118            return False
1119    else:
1120        return False
1121
1122def TrinomialParts(u, x):
1123    # If u is equivalent to a trinomial of the form a + b*x^n + c*x^(2*n) where n!=0, b!=0 and c!=0, TrinomialParts[u,x] returns the list {a,b,c,n}; else it returns False.
1124    u = sympify(u)
1125    if PolynomialQ(u, x):
1126        lst = CoefficientList(u, x)
1127        if len(lst)<3 or EvenQ(sympify(len(lst))) or ZeroQ((len(lst)+1)/2):
1128            return False
1129        #Catch(
1130         #   Scan(Function(if ZeroQ(lst), Null, Throw(False), Drop(Drop(Drop(lst, [(len(lst)+1)/2]), 1), -1];
1131          #  [First(lst), lst[(len(lst)+1)/2], Last(lst), (len(lst)-1)/2]):
1132    if PowerQ(u):
1133        if EqQ(u.exp, 2):
1134            lst = BinomialParts(u.base, x)
1135            if not lst or ZeroQ(lst[0]):
1136                return False
1137            else:
1138                return [lst[0]**2, 2*lst[0]*lst[1], lst[1]**2, lst[2]]
1139        else:
1140            return False
1141    if ProductQ(u):
1142        if FreeQ(First(u), x):
1143            lst2 = TrinomialParts(Rest(u), x)
1144            if not lst2:
1145                return False
1146            else:
1147                return [First(u)*lst2[0], First(u)*lst2[1], First(u)*lst2[2], lst2[3]]
1148        if FreeQ(Rest(u), x):
1149            lst1 = TrinomialParts(First(u), x)
1150            if not lst1:
1151                return False
1152            else:
1153                return [Rest(u)*lst1[0], Rest(u)*lst1[1], Rest(u)*lst1[2], lst1[3]]
1154        lst1 = BinomialParts(First(u), x)
1155        if not lst1:
1156            return False
1157        lst2 = BinomialParts(Rest(u), x)
1158        if not lst2:
1159            return False
1160        a = lst1[0]
1161        b = lst1[1]
1162        m = lst1[2]
1163        c = lst2[0]
1164        d = lst2[1]
1165        n = lst2[2]
1166        if EqQ(m, n) and NonzeroQ(a*d+b*c):
1167            return [a*c, a*d + b*c, b*d, m]
1168        else:
1169            return False
1170    if SumQ(u):
1171        if FreeQ(First(u), x):
1172            lst2 = TrinomialParts(Rest(u), x)
1173            if not lst2:
1174                return False
1175            else:
1176                return [First(u)+lst2[0], lst2[1], lst2[2], lst2[3]]
1177        if FreeQ(Rest(u), x):
1178            lst1 = TrinomialParts(First(u), x)
1179            if not lst1:
1180                return False
1181            else:
1182                return [Rest(u)+lst1[0], lst1[1], lst1[2], lst1[3]]
1183        lst1 = TrinomialParts(First(u), x)
1184        if not lst1:
1185            lst3 = BinomialParts(First(u), x)
1186            if not lst3:
1187                return False
1188            lst2 = TrinomialParts(Rest(u), x)
1189            if not lst2:
1190                lst4 = BinomialParts(Rest(u), x)
1191                if not lst4:
1192                    return False
1193                if EqQ(lst3[2], 2*lst4[2]):
1194                    return [lst3[0]+lst4[0], lst4[1], lst3[1], lst4[2]]
1195                if EqQ(lst4[2], 2*lst3[2]):
1196                    return [lst3[0]+lst4[0], lst3[1], lst4[1], lst3[2]]
1197                else:
1198                    return False
1199            if EqQ(lst3[2], lst2[3]) and NonzeroQ(lst3[1]+lst2[1]):
1200                return [lst3[0]+lst2[0], lst3[1]+lst2[1], lst2[2], lst2[3]]
1201            if EqQ(lst3[2], 2*lst2[3]) and NonzeroQ(lst3[1]+lst2[2]):
1202                return [lst3[0]+lst2[0], lst2[1], lst3[1]+lst2[2], lst2[3]]
1203            else:
1204                return False
1205        lst2 = TrinomialParts(Rest(u), x)
1206        if AtomQ(lst2):
1207            lst4 = BinomialParts(Rest(u), x)
1208            if not lst4:
1209                return False
1210            if EqQ(lst4[2], lst1[3]) and NonzeroQ(lst1[1]+lst4[0]):
1211                return [lst1[0]+lst4[0], lst1[1]+lst4[1], lst1[2], lst1[3]]
1212            if EqQ(lst4[2], 2*lst1[3]) and NonzeroQ(lst1[2]+lst4[1]):
1213                return [lst1[0]+lst4[0], lst1[1], lst1[2]+lst4[1], lst1[3]]
1214            else:
1215                return False
1216        if EqQ(lst1[3], lst2[3]) and NonzeroQ(lst1[1]+lst2[1]) and NonzeroQ(lst1[2]+lst2[2]):
1217            return [lst1[0]+lst2[0], lst1[1]+lst2[1], lst1[2]+lst2[2], lst1[3]]
1218        else:
1219            return False
1220    else:
1221        return False
1222
1223def PolyQ(u, x, n=None):
1224    # returns True iff u is a polynomial of degree n.
1225    if ListQ(u):
1226        return all(PolyQ(i, x) for i in u)
1227
1228    if n is None:
1229        if u == x:
1230            return False
1231        elif isinstance(x, Pow):
1232            n = x.exp
1233            x_base = x.base
1234            if FreeQ(n, x_base):
1235                if PositiveIntegerQ(n):
1236                    return PolyQ(u, x_base) and (PolynomialQ(u, x) or PolynomialQ(Together(u), x))
1237                elif AtomQ(n):
1238                    return PolynomialQ(u, x) and FreeQ(CoefficientList(u, x), x_base)
1239                else:
1240                    return False
1241
1242        return PolynomialQ(u, x) or PolynomialQ(u, Together(x))
1243
1244    else:
1245        return PolynomialQ(u, x) and Coefficient(u, x, n) != 0 and Exponent(u, x) == n
1246
1247
1248def EvenQ(u):
1249    # gives True if expr is an even integer, and False otherwise.
1250    return isinstance(u, (Integer, int)) and u%2 == 0
1251
1252def OddQ(u):
1253    # gives True if expr is an odd integer, and False otherwise.
1254
1255    return isinstance(u, (Integer, int)) and u%2 == 1
1256
1257def PerfectSquareQ(u):
1258    # (* If u is a rational number whose squareroot is rational or if u is of the form u1^n1 u2^n2 ...
1259    # and n1, n2, ... are even, PerfectSquareQ[u] returns True; else it returns False. *)
1260    if RationalQ(u):
1261        return Greater(u, 0) and RationalQ(Sqrt(u))
1262    elif PowerQ(u):
1263        return EvenQ(u.exp)
1264    elif ProductQ(u):
1265        return PerfectSquareQ(First(u)) and PerfectSquareQ(Rest(u))
1266    elif SumQ(u):
1267        s = Simplify(u)
1268        if NonsumQ(s):
1269            return PerfectSquareQ(s)
1270        return False
1271    else:
1272        return False
1273
1274def NiceSqrtAuxQ(u):
1275    if RationalQ(u):
1276        return u > 0
1277    elif PowerQ(u):
1278        return EvenQ(u.exp)
1279    elif ProductQ(u):
1280        return NiceSqrtAuxQ(First(u)) and NiceSqrtAuxQ(Rest(u))
1281    elif SumQ(u):
1282        s = Simplify(u)
1283        return  NonsumQ(s) and NiceSqrtAuxQ(s)
1284    else:
1285        return False
1286
1287def NiceSqrtQ(u):
1288    return Not(NegativeQ(u)) and NiceSqrtAuxQ(u)
1289
1290def Together(u):
1291    return factor(u)
1292
1293def PosAux(u):
1294    if RationalQ(u):
1295        return u>0
1296    elif NumberQ(u):
1297        if ZeroQ(Re(u)):
1298            return Im(u) > 0
1299        else:
1300            return Re(u) > 0
1301    elif NumericQ(u):
1302        v = N(u)
1303        if ZeroQ(Re(v)):
1304            return Im(v) > 0
1305        else:
1306            return Re(v) > 0
1307    elif PowerQ(u):
1308        if OddQ(u.exp):
1309            return PosAux(u.base)
1310        else:
1311            return True
1312    elif ProductQ(u):
1313        if PosAux(First(u)):
1314            return PosAux(Rest(u))
1315        else:
1316            return not PosAux(Rest(u))
1317    elif SumQ(u):
1318        return PosAux(First(u))
1319    else:
1320        res = u > 0
1321        if res in(True, False):
1322            return res
1323        return True
1324
1325def PosQ(u):
1326    # If u is not 0 and has a positive form, PosQ[u] returns True, else it returns False.
1327    return PosAux(TogetherSimplify(u))
1328
1329def CoefficientList(u, x):
1330    if PolynomialQ(u, x):
1331        return list(reversed(Poly(u, x).all_coeffs()))
1332    else:
1333        return []
1334
1335def ReplaceAll(expr, args):
1336    if isinstance(args, list):
1337        n_args = {}
1338        for i in args:
1339            n_args.update(i)
1340        return expr.subs(n_args)
1341    return expr.subs(args)
1342
1343def ExpandLinearProduct(v, u, a, b, x):
1344    # If u is a polynomial in x, ExpandLinearProduct[v,u,a,b,x] expands v*u into a sum of terms of the form c*v*(a+b*x)^n.
1345    if FreeQ([a, b], x) and PolynomialQ(u, x):
1346        lst = CoefficientList(ReplaceAll(u, {x: (x - a)/b}), x)
1347        lst = [SimplifyTerm(i, x) for i in lst]
1348        res = 0
1349        for k in range(1, len(lst)+1):
1350            res = res + Simplify(v*lst[k-1]*(a + b*x)**(k - 1))
1351        return res
1352    return u*v
1353
1354def GCD(*args):
1355    args = S(args)
1356    if len(args) == 1:
1357        if isinstance(args[0], (int, Integer)):
1358            return args[0]
1359        else:
1360            return S(1)
1361    return gcd(*args)
1362
1363def ContentFactor(expn):
1364    return factor_terms(expn)
1365
1366def NumericFactor(u):
1367    # returns the real numeric factor of u.
1368    if NumberQ(u):
1369        if ZeroQ(Im(u)):
1370            return u
1371        elif ZeroQ(Re(u)):
1372            return Im(u)
1373        else:
1374            return S(1)
1375    elif PowerQ(u):
1376        if RationalQ(u.base) and RationalQ(u.exp):
1377            if u.exp > 0:
1378                return 1/Denominator(u.base)
1379            else:
1380                return 1/(1/Denominator(u.base))
1381        else:
1382            return S(1)
1383    elif ProductQ(u):
1384        return Mul(*[NumericFactor(i) for i in u.args])
1385    elif SumQ(u):
1386        if LeafCount(u) < 50:
1387            c = ContentFactor(u)
1388            if SumQ(c):
1389                return S(1)
1390            else:
1391                return NumericFactor(c)
1392        else:
1393            m = NumericFactor(First(u))
1394            n = NumericFactor(Rest(u))
1395            if m < 0 and n < 0:
1396                return -GCD(-m, -n)
1397            else:
1398                return GCD(m, n)
1399    return S(1)
1400
1401def NonnumericFactors(u):
1402    if NumberQ(u):
1403        if ZeroQ(Im(u)):
1404            return S(1)
1405        elif ZeroQ(Re(u)):
1406            return I
1407        return u
1408    elif PowerQ(u):
1409        if RationalQ(u.base) and FractionQ(u.exp):
1410            return u/NumericFactor(u)
1411        return u
1412    elif ProductQ(u):
1413        result = 1
1414        for i in u.args:
1415            result *= NonnumericFactors(i)
1416        return result
1417    elif SumQ(u):
1418        if LeafCount(u) < 50:
1419            i = ContentFactor(u)
1420            if SumQ(i):
1421                return u
1422            else:
1423                return NonnumericFactors(i)
1424        n = NumericFactor(u)
1425        result = 0
1426        for i in u.args:
1427            result += i/n
1428        return result
1429    return u
1430
1431def MakeAssocList(u, x, alst=None):
1432    # (* MakeAssocList[u,x,alst] returns an association list of gensymed symbols with the nonatomic
1433    # parameters of a u that are not integer powers, products or sums. *)
1434    if alst is None:
1435        alst = []
1436    u = replace_pow_exp(u)
1437    x = replace_pow_exp(x)
1438    if AtomQ(u):
1439        return alst
1440    elif IntegerPowerQ(u):
1441        return MakeAssocList(u.base, x, alst)
1442    elif ProductQ(u) or SumQ(u):
1443        return MakeAssocList(Rest(u), x, MakeAssocList(First(u), x, alst))
1444    elif FreeQ(u, x):
1445        tmp = []
1446        for i in alst:
1447            if PowerQ(i):
1448                if i.exp == u:
1449                    tmp.append(i)
1450                    break
1451            elif len(i.args) > 1: # make sure args has length > 1, else causes index error some times
1452                if i.args[1] == u:
1453                    tmp.append(i)
1454                    break
1455        if tmp == []:
1456            alst.append(u)
1457        return alst
1458    return alst
1459
1460def GensymSubst(u, x, alst=None):
1461    # (* GensymSubst[u,x,alst] returns u with the kernels in alst free of x replaced by gensymed names. *)
1462    if alst is None:
1463        alst =[]
1464    u = replace_pow_exp(u)
1465    x = replace_pow_exp(x)
1466    if AtomQ(u):
1467        return u
1468    elif IntegerPowerQ(u):
1469        return GensymSubst(u.base, x, alst)**u.exp
1470    elif ProductQ(u) or SumQ(u):
1471        return u.func(*[GensymSubst(i, x, alst) for i in u.args])
1472    elif FreeQ(u, x):
1473        tmp = []
1474        for i in alst:
1475            if PowerQ(i):
1476                if i.exp == u:
1477                    tmp.append(i)
1478                    break
1479
1480            elif len(i.args) > 1: # make sure args has length > 1, else causes index error some times
1481                if i.args[1] == u:
1482                    tmp.append(i)
1483                    break
1484        if tmp == []:
1485            return u
1486        return tmp[0][0]
1487    return u
1488
1489def KernelSubst(u, x, alst):
1490    # (* KernelSubst[u,x,alst] returns u with the gensymed names in alst replaced by kernels free of x. *)
1491    if AtomQ(u):
1492        tmp = []
1493        for i in alst:
1494            if i.args[0] == u:
1495                tmp.append(i)
1496                break
1497        if tmp == []:
1498            return u
1499        elif len(tmp[0].args) > 1: # make sure args has length > 1, else causes index error some times
1500            return tmp[0].args[1]
1501
1502    elif IntegerPowerQ(u):
1503        tmp = KernelSubst(u.base, x, alst)
1504        if u.exp < 0 and ZeroQ(tmp):
1505            return 'Indeterminate'
1506        return tmp**u.exp
1507    elif ProductQ(u) or SumQ(u):
1508        return u.func(*[KernelSubst(i, x, alst) for i in u.args])
1509    return u
1510
1511def ExpandExpression(u, x):
1512    if AlgebraicFunctionQ(u, x) and Not(RationalFunctionQ(u, x)):
1513        v = ExpandAlgebraicFunction(u, x)
1514    else:
1515        v = S(0)
1516    if SumQ(v):
1517        return ExpandCleanup(v, x)
1518    v = SmartApart(u, x)
1519    if SumQ(v):
1520        return ExpandCleanup(v, x)
1521    v = SmartApart(RationalFunctionFactors(u, x), x, x)
1522    if SumQ(v):
1523        w = NonrationalFunctionFactors(u, x)
1524        return ExpandCleanup(v.func(*[i*w for i in v.args]), x)
1525    v = Expand(u)
1526    if SumQ(v):
1527        return ExpandCleanup(v, x)
1528    v = Expand(u)
1529    if SumQ(v):
1530        return ExpandCleanup(v, x)
1531    return SimplifyTerm(u, x)
1532
1533def Apart(u, x):
1534    if RationalFunctionQ(u, x):
1535        return apart(u, x)
1536
1537    return u
1538
1539def SmartApart(*args):
1540    if len(args) == 2:
1541        u, x = args
1542        alst = MakeAssocList(u, x)
1543        tmp = KernelSubst(Apart(GensymSubst(u, x, alst), x), x, alst)
1544        if tmp == 'Indeterminate':
1545            return u
1546        return tmp
1547
1548    u, v, x = args
1549    alst = MakeAssocList(u, x)
1550    tmp = KernelSubst(Apart(GensymSubst(u, x, alst), x), x, alst)
1551    if tmp == 'Indeterminate':
1552        return u
1553    return tmp
1554
1555def MatchQ(expr, pattern, *var):
1556    # returns the matched arguments after matching pattern with expression
1557    match = expr.match(pattern)
1558    if match:
1559        return tuple(match[i] for i in var)
1560    else:
1561        return None
1562
1563def PolynomialQuotientRemainder(p, q, x):
1564    return [PolynomialQuotient(p, q, x), PolynomialRemainder(p, q, x)]
1565
1566def FreeFactors(u, x):
1567    # returns the product of the factors of u free of x.
1568    if ProductQ(u):
1569        result = 1
1570        for i in u.args:
1571            if FreeQ(i, x):
1572                result *= i
1573        return result
1574    elif FreeQ(u, x):
1575        return u
1576    else:
1577        return S(1)
1578
1579def NonfreeFactors(u, x):
1580    """
1581    Returns the product of the factors of u not free of x.
1582
1583    Examples
1584    ========
1585
1586    >>> from sympy.integrals.rubi.utility_function import NonfreeFactors
1587    >>> from sympy.abc import  x, a, b
1588    >>> NonfreeFactors(a, x)
1589    1
1590    >>> NonfreeFactors(x + a, x)
1591    a + x
1592    >>> NonfreeFactors(a*b*x, x)
1593    x
1594
1595    """
1596    if ProductQ(u):
1597        result = 1
1598        for i in u.args:
1599            if not FreeQ(i, x):
1600                result *= i
1601        return result
1602    elif FreeQ(u, x):
1603        return 1
1604    else:
1605        return u
1606
1607def RemoveContentAux(expr, x):
1608    return RemoveContentAux_replacer.replace(UtilityOperator(expr, x))
1609
1610def RemoveContent(u, x):
1611    v = NonfreeFactors(u, x)
1612    w = Together(v)
1613
1614    if EqQ(FreeFactors(w, x), 1):
1615        return RemoveContentAux(v, x)
1616    else:
1617        return RemoveContentAux(NonfreeFactors(w, x), x)
1618
1619
1620def FreeTerms(u, x):
1621    """
1622    Returns the sum of the terms of u free of x.
1623
1624    Examples
1625    ========
1626
1627    >>> from sympy.integrals.rubi.utility_function import FreeTerms
1628    >>> from sympy.abc import  x, a, b
1629    >>> FreeTerms(a, x)
1630    a
1631    >>> FreeTerms(x*a, x)
1632    0
1633    >>> FreeTerms(a*x + b, x)
1634    b
1635
1636    """
1637    if SumQ(u):
1638        result = 0
1639        for i in u.args:
1640            if FreeQ(i, x):
1641                result += i
1642        return result
1643    elif FreeQ(u, x):
1644        return u
1645    else:
1646        return 0
1647
1648def NonfreeTerms(u, x):
1649    # returns the sum of the terms of u free of x.
1650    if SumQ(u):
1651        result = S(0)
1652        for i in u.args:
1653            if not FreeQ(i, x):
1654                result += i
1655        return result
1656    elif not FreeQ(u, x):
1657        return u
1658    else:
1659        return S(0)
1660
1661def ExpandAlgebraicFunction(expr, x):
1662    if ProductQ(expr):
1663        u_ = Wild('u', exclude=[x])
1664        n_ = Wild('n', exclude=[x])
1665        v_ = Wild('v')
1666        pattern = u_*v_
1667        match = expr.match(pattern)
1668        if match:
1669            keys = [u_, v_]
1670            if len(keys) == len(match):
1671                u, v = tuple([match[i] for i in keys])
1672                if SumQ(v):
1673                    u, v = v, u
1674                if not FreeQ(u, x) and SumQ(u):
1675                    result = 0
1676                    for i in u.args:
1677                        result += i*v
1678                    return result
1679
1680        pattern = u_**n_*v_
1681        match = expr.match(pattern)
1682        if match:
1683            keys = [u_, n_, v_]
1684            if len(keys) == len(match):
1685                u, n, v = tuple([match[i] for i in keys])
1686                if PositiveIntegerQ(n) and SumQ(u):
1687                    w = Expand(u**n)
1688                    result = 0
1689                    for i in w.args:
1690                        result += i*v
1691                    return result
1692
1693    return expr
1694
1695def CollectReciprocals(expr, x):
1696    # Basis: e/(a+b x)+f/(c+d x)==(c e+a f+(d e+b f) x)/(a c+(b c+a d) x+b d x^2)
1697    if SumQ(expr):
1698        u_ = Wild('u')
1699        a_ = Wild('a', exclude=[x])
1700        b_ = Wild('b', exclude=[x])
1701        c_ = Wild('c', exclude=[x])
1702        d_ = Wild('d', exclude=[x])
1703        e_ = Wild('e', exclude=[x])
1704        f_ = Wild('f', exclude=[x])
1705        pattern = u_ + e_/(a_ + b_*x) + f_/(c_+d_*x)
1706        match = expr.match(pattern)
1707        if match:
1708            try: # .match() does not work peoperly always
1709                keys = [u_, a_, b_, c_, d_, e_, f_]
1710                u, a, b, c, d, e, f = tuple([match[i] for i in keys])
1711                if ZeroQ(b*c + a*d) & ZeroQ(d*e + b*f):
1712                    return CollectReciprocals(u + (c*e + a*f)/(a*c + b*d*x**2),x)
1713                elif ZeroQ(b*c + a*d) & ZeroQ(c*e + a*f):
1714                    return CollectReciprocals(u + (d*e + b*f)*x/(a*c + b*d*x**2),x)
1715            except:
1716                pass
1717    return expr
1718
1719def ExpandCleanup(u, x):
1720    v = CollectReciprocals(u, x)
1721    if SumQ(v):
1722        res = 0
1723        for i in v.args:
1724            res += SimplifyTerm(i, x)
1725        v = res
1726        if SumQ(v):
1727            return UnifySum(v, x)
1728        else:
1729            return v
1730    else:
1731        return v
1732
1733def AlgebraicFunctionQ(u, x, flag=False):
1734    if ListQ(u):
1735        if u == []:
1736            return True
1737        elif AlgebraicFunctionQ(First(u), x, flag):
1738            return AlgebraicFunctionQ(Rest(u), x, flag)
1739        else:
1740            return False
1741
1742    elif AtomQ(u) or FreeQ(u, x):
1743        return True
1744    elif PowerQ(u):
1745        if RationalQ(u.exp) | flag & FreeQ(u.exp, x):
1746            return AlgebraicFunctionQ(u.base, x, flag)
1747    elif ProductQ(u) | SumQ(u):
1748        for i in u.args:
1749            if not AlgebraicFunctionQ(i, x, flag):
1750                return False
1751        return True
1752
1753    return False
1754
1755def Coeff(expr, form, n=1):
1756    if n == 1:
1757        return Coefficient(Together(expr), form, n)
1758    else:
1759        coef1 = Coefficient(expr, form, n)
1760        coef2 = Coefficient(Together(expr), form, n)
1761        if Simplify(coef1 - coef2) == 0:
1762            return coef1
1763        else:
1764            return coef2
1765
1766def LeadTerm(u):
1767    if SumQ(u):
1768        return First(u)
1769    return u
1770
1771def RemainingTerms(u):
1772    if SumQ(u):
1773        return Rest(u)
1774    return u
1775
1776def LeadFactor(u):
1777    # returns the leading factor of u.
1778    if ComplexNumberQ(u) and Re(u) == 0:
1779        if Im(u) == S(1):
1780            return u
1781        else:
1782            return LeadFactor(Im(u))
1783    elif ProductQ(u):
1784            return LeadFactor(First(u))
1785    return u
1786
1787def RemainingFactors(u):
1788    # returns the remaining factors of u.
1789    if ComplexNumberQ(u) and Re(u) == 0:
1790        if Im(u) == 1:
1791            return S(1)
1792        else:
1793            return I*RemainingFactors(Im(u))
1794    elif ProductQ(u):
1795        return RemainingFactors(First(u))*Rest(u)
1796    return S(1)
1797
1798def LeadBase(u):
1799    """
1800    returns the base of the leading factor of u.
1801
1802    Examples
1803    ========
1804
1805    >>> from sympy.integrals.rubi.utility_function import LeadBase
1806    >>> from sympy.abc import  a, b, c
1807    >>> LeadBase(a**b)
1808    a
1809    >>> LeadBase(a**b*c)
1810    a
1811    """
1812    v = LeadFactor(u)
1813    if PowerQ(v):
1814        return v.base
1815    return v
1816
1817def LeadDegree(u):
1818    # returns the degree of the leading factor of u.
1819    v = LeadFactor(u)
1820    if PowerQ(v):
1821        return v.exp
1822    return v
1823
1824def Numer(expr):
1825    # returns the numerator of u.
1826    if PowerQ(expr):
1827        if expr.exp < 0:
1828            return 1
1829    if ProductQ(expr):
1830        return Mul(*[Numer(i) for i in expr.args])
1831    return Numerator(expr)
1832
1833def Denom(u):
1834    # returns the denominator of u
1835    if PowerQ(u):
1836        if u.exp < 0:
1837            return u.args[0]**(-u.args[1])
1838    elif ProductQ(u):
1839        return Mul(*[Denom(i) for i in u.args])
1840    return Denominator(u)
1841
1842def hypergeom(n, d, z):
1843    return hyper(n, d, z)
1844
1845def Expon(expr, form):
1846    return Exponent(Together(expr), form)
1847
1848def MergeMonomials(expr, x):
1849    u_ = Wild('u')
1850    p_ = Wild('p', exclude=[x, 1, 0])
1851    a_ = Wild('a', exclude=[x])
1852    b_ = Wild('b', exclude=[x, 0])
1853    c_ = Wild('c', exclude=[x])
1854    d_ = Wild('d', exclude=[x, 0])
1855    n_ = Wild('n', exclude=[x])
1856    m_ = Wild('m', exclude=[x])
1857
1858    # Basis: If  m/n\[Element]\[DoubleStruckCapitalZ], then z^m (c z^n)^p==(c z^n)^(m/n+p)/c^(m/n)
1859    pattern = u_*(a_ + b_*x)**m_*(c_*(a_ + b_*x)**n_)**p_
1860    match = expr.match(pattern)
1861    if match:
1862        keys = [u_, a_, b_, m_, c_, n_, p_]
1863        if len(keys) == len(match):
1864            u, a, b, m, c, n, p = tuple([match[i] for i in keys])
1865            if IntegerQ(m/n):
1866                if u*(c*(a + b*x)**n)**(m/n + p)/c**(m/n) is S.NaN:
1867                    return expr
1868                else:
1869                    return u*(c*(a + b*x)**n)**(m/n + p)/c**(m/n)
1870
1871
1872    # Basis: If  m\[Element]\[DoubleStruckCapitalZ] \[And] b c-a d==0, then (a+b z)^m==b^m/d^m (c+d z)^m
1873    pattern = u_*(a_ + b_*x)**m_*(c_ + d_*x)**n_
1874    match = expr.match(pattern)
1875    if match:
1876        keys = [u_, a_, b_, m_, c_, d_, n_]
1877        if len(keys) == len(match):
1878            u, a, b, m, c, d, n = tuple([match[i] for i in keys])
1879            if IntegerQ(m) and ZeroQ(b*c - a*d):
1880                if u*b**m/d**m*(c + d*x)**(m + n) is S.NaN:
1881                    return expr
1882                else:
1883                    return u*b**m/d**m*(c + d*x)**(m + n)
1884    return expr
1885
1886def PolynomialDivide(u, v, x):
1887
1888
1889    quo = PolynomialQuotient(u, v, x)
1890    rem = PolynomialRemainder(u, v, x)
1891    s = 0
1892    for i in ExponentList(quo, x):
1893        s += Simp(Together(Coefficient(quo, x, i)*x**i), x)
1894    quo = s
1895    rem = Together(rem)
1896    free = FreeFactors(rem, x)
1897    rem = NonfreeFactors(rem, x)
1898    monomial = x**Min(ExponentList(rem, x))
1899    if NegQ(Coefficient(rem, x, 0)):
1900        monomial = -monomial
1901    s = 0
1902    for i in ExponentList(rem, x):
1903        s += Simp(Together(Coefficient(rem, x, i)*x**i/monomial), x)
1904    rem = s
1905    if BinomialQ(v, x):
1906        return quo + free*monomial*rem/ExpandToSum(v, x)
1907    else:
1908        return quo + free*monomial*rem/v
1909
1910
1911
1912def BinomialQ(u, x, n=None):
1913    """
1914    If u is equivalent to an expression of the form a + b*x**n, BinomialQ(u, x, n) returns True, else it returns False.
1915
1916    Examples
1917    ========
1918
1919    >>> from sympy.integrals.rubi.utility_function import BinomialQ
1920    >>> from sympy.abc import  x
1921    >>> BinomialQ(x**9, x)
1922    True
1923    >>> BinomialQ((1 + x)**3, x)
1924    False
1925
1926    """
1927    if ListQ(u):
1928        for i in u:
1929            if Not(BinomialQ(i, x, n)):
1930                return False
1931        return True
1932    elif NumberQ(x):
1933        return False
1934    return ListQ(BinomialParts(u, x))
1935
1936def TrinomialQ(u, x):
1937    """
1938    If u is equivalent to an expression of the form a + b*x**n + c*x**(2*n) where n, b and c are not 0,
1939    TrinomialQ(u, x) returns True, else it returns False.
1940
1941    Examples
1942    ========
1943
1944    >>> from sympy.integrals.rubi.utility_function import TrinomialQ
1945    >>> from sympy.abc import x
1946    >>> TrinomialQ((7 + 2*x**6 + 3*x**12), x)
1947    True
1948    >>> TrinomialQ(x**2, x)
1949    False
1950
1951    """
1952    if ListQ(u):
1953        for i in u.args:
1954            if Not(TrinomialQ(i, x)):
1955                return False
1956        return True
1957
1958    check = False
1959    u = replace_pow_exp(u)
1960    if PowerQ(u):
1961        if u.exp == 2 and BinomialQ(u.base, x):
1962            check = True
1963
1964    return ListQ(TrinomialParts(u,x)) and Not(QuadraticQ(u, x)) and Not(check)
1965
1966def GeneralizedBinomialQ(u, x):
1967    """
1968    If u is equivalent to an expression of the form a*x**q+b*x**n where n, q and b are not 0,
1969    GeneralizedBinomialQ(u, x) returns True, else it returns False.
1970
1971    Examples
1972    ========
1973
1974    >>> from sympy.integrals.rubi.utility_function import GeneralizedBinomialQ
1975    >>> from sympy.abc import a, x, q, b, n
1976    >>> GeneralizedBinomialQ(a*x**q, x)
1977    False
1978
1979    """
1980    if ListQ(u):
1981        return all(GeneralizedBinomialQ(i, x) for i in u)
1982    return ListQ(GeneralizedBinomialParts(u, x))
1983
1984def GeneralizedTrinomialQ(u, x):
1985    """
1986    If u is equivalent to an expression of the form a*x**q+b*x**n+c*x**(2*n-q) where n, q, b and c are not 0,
1987    GeneralizedTrinomialQ(u, x) returns True, else it returns False.
1988
1989    Examples
1990    ========
1991
1992    >>> from sympy.integrals.rubi.utility_function import GeneralizedTrinomialQ
1993    >>> from sympy.abc import x
1994    >>> GeneralizedTrinomialQ(7 + 2*x**6 + 3*x**12, x)
1995    False
1996
1997    """
1998    if ListQ(u):
1999        return all(GeneralizedTrinomialQ(i, x) for i in u)
2000    return ListQ(GeneralizedTrinomialParts(u, x))
2001
2002def FactorSquareFreeList(poly):
2003    r = sqf_list(poly)
2004    result = [[1, 1]]
2005    for i in r[1]:
2006        result.append(list(i))
2007    return result
2008
2009def PerfectPowerTest(u, x):
2010    # If u (x) is equivalent to a polynomial raised to an integer power greater than 1,
2011    # PerfectPowerTest[u,x] returns u (x) as an expanded polynomial raised to the power;
2012    # else it returns False.
2013    if PolynomialQ(u, x):
2014        lst = FactorSquareFreeList(u)
2015        gcd = 0
2016        v = 1
2017        if lst[0] == [1, 1]:
2018            lst = Rest(lst)
2019        for i in lst:
2020            gcd = GCD(gcd, i[1])
2021        if gcd > 1:
2022            for i in lst:
2023                v = v*i[0]**(i[1]/gcd)
2024            return Expand(v)**gcd
2025        else:
2026            return False
2027    return False
2028
2029def SquareFreeFactorTest(u, x):
2030    # If u (x) can be square free factored, SquareFreeFactorTest[u,x] returns u (x) in
2031    # factored form; else it returns False.
2032    if PolynomialQ(u, x):
2033        v = FactorSquareFree(u)
2034        if PowerQ(v) or ProductQ(v):
2035            return v
2036        return False
2037    return False
2038
2039def RationalFunctionQ(u, x):
2040    # If u is a rational function of x, RationalFunctionQ[u,x] returns True; else it returns False.
2041    if AtomQ(u) or FreeQ(u, x):
2042        return True
2043    elif IntegerPowerQ(u):
2044        return RationalFunctionQ(u.base, x)
2045    elif ProductQ(u) or SumQ(u):
2046        for i in u.args:
2047            if Not(RationalFunctionQ(i, x)):
2048                return False
2049        return True
2050    return False
2051
2052def RationalFunctionFactors(u, x):
2053    # RationalFunctionFactors[u,x] returns the product of the factors of u that are rational functions of x.
2054    if ProductQ(u):
2055        res = 1
2056        for i in u.args:
2057            if RationalFunctionQ(i, x):
2058                res *= i
2059        return res
2060    elif RationalFunctionQ(u, x):
2061        return u
2062    return S(1)
2063
2064def NonrationalFunctionFactors(u, x):
2065    if ProductQ(u):
2066        res = 1
2067        for i in u.args:
2068            if not RationalFunctionQ(i, x):
2069                res *= i
2070        return res
2071    elif RationalFunctionQ(u, x):
2072        return S(1)
2073    return u
2074
2075def Reverse(u):
2076    if isinstance(u, list):
2077        return list(reversed(u))
2078    else:
2079        l = list(u.args)
2080        return u.func(*list(reversed(l)))
2081
2082def RationalFunctionExponents(u, x):
2083    """
2084    u is a polynomial or rational function of x.
2085    RationalFunctionExponents(u, x) returns a list of the exponent of the
2086    numerator of u and the exponent of the denominator of u.
2087
2088    Examples
2089    ========
2090    >>> from sympy.integrals.rubi.utility_function import RationalFunctionExponents
2091    >>> from sympy.abc import  x, a
2092    >>> RationalFunctionExponents(x, x)
2093    [1, 0]
2094    >>> RationalFunctionExponents(x**(-1), x)
2095    [0, 1]
2096    >>> RationalFunctionExponents(x**(-1)*a, x)
2097    [0, 1]
2098
2099    """
2100    if PolynomialQ(u, x):
2101        return [Exponent(u, x), 0]
2102    elif IntegerPowerQ(u):
2103        if PositiveQ(u.exp):
2104            return u.exp*RationalFunctionExponents(u.base, x)
2105        return  (-u.exp)*Reverse(RationalFunctionExponents(u.base, x))
2106    elif ProductQ(u):
2107        lst1 = RationalFunctionExponents(First(u), x)
2108        lst2 = RationalFunctionExponents(Rest(u), x)
2109        return [lst1[0] + lst2[0], lst1[1] + lst2[1]]
2110    elif SumQ(u):
2111        v = Together(u)
2112        if SumQ(v):
2113            lst1 = RationalFunctionExponents(First(u), x)
2114            lst2 = RationalFunctionExponents(Rest(u), x)
2115            return [Max(lst1[0] + lst2[1], lst2[0] + lst1[1]), lst1[1] + lst2[1]]
2116        else:
2117            return RationalFunctionExponents(v, x)
2118    return [0, 0]
2119
2120def RationalFunctionExpand(expr, x):
2121    # expr is a polynomial or rational function of x.
2122    # RationalFunctionExpand[u,x] returns the expansion of the factors of u that are rational functions times the other factors.
2123    def cons_f1(n):
2124        return FractionQ(n)
2125    cons1 = CustomConstraint(cons_f1)
2126
2127    def cons_f2(x, v):
2128        if not isinstance(x, Symbol):
2129            return False
2130        return UnsameQ(v, x)
2131    cons2 = CustomConstraint(cons_f2)
2132
2133    def With1(n, u, x, v):
2134        w = RationalFunctionExpand(u, x)
2135        return If(SumQ(w), Add(*[i*v**n for i in w.args]), v**n*w)
2136    pattern1 = Pattern(UtilityOperator(u_*v_**n_, x_), cons1, cons2)
2137    rule1 = ReplacementRule(pattern1, With1)
2138    def With2(u, x):
2139        v = ExpandIntegrand(u, x)
2140
2141        def _consf_u(a, b, c, d, p, m, n, x):
2142            return And(FreeQ(List(a, b, c, d, p), x), IntegersQ(m, n), Equal(m, Add(n, S(-1))))
2143        cons_u = CustomConstraint(_consf_u)
2144        pat = Pattern(UtilityOperator(x_**WC('m', S(1))*(x_*WC('d', S(1)) + c_)**p_/(x_**n_*WC('b', S(1)) + a_), x_), cons_u)
2145        result_matchq = is_match(UtilityOperator(u, x), pat)
2146        if UnsameQ(v, u) and not result_matchq:
2147            return v
2148        else:
2149            v = ExpandIntegrand(RationalFunctionFactors(u, x), x)
2150            w = NonrationalFunctionFactors(u, x)
2151            if SumQ(v):
2152                return Add(*[i*w for i in v.args])
2153            else:
2154                return v*w
2155    pattern2 = Pattern(UtilityOperator(u_, x_))
2156    rule2 = ReplacementRule(pattern2, With2)
2157    expr = expr.replace(sym_exp, rubi_exp)
2158    res = replace_all(UtilityOperator(expr, x), [rule1, rule2])
2159    return replace_pow_exp(res)
2160
2161
2162def ExpandIntegrand(expr, x, extra=None):
2163    expr = replace_pow_exp(expr)
2164    if not extra is None:
2165        extra, x = x, extra
2166        w = ExpandIntegrand(extra, x)
2167        r = NonfreeTerms(w, x)
2168        if SumQ(r):
2169            result = [expr*FreeTerms(w, x)]
2170            for i in r.args:
2171                result.append(MergeMonomials(expr*i, x))
2172            return r.func(*result)
2173        else:
2174            return expr*FreeTerms(w, x) + MergeMonomials(expr*r, x)
2175
2176    else:
2177        u_ = Wild('u', exclude=[0, 1])
2178        a_ = Wild('a', exclude=[x])
2179        b_ = Wild('b', exclude=[x, 0])
2180        F_ = Wild('F', exclude=[0])
2181        c_ = Wild('c', exclude=[x])
2182        d_ = Wild('d', exclude=[x, 0])
2183        n_ = Wild('n', exclude=[0, 1])
2184        pattern = u_*(a_ + b_*F_)**n_
2185        match = expr.match(pattern)
2186        if match:
2187            if MemberQ([asin, acos, asinh, acosh], match[F_].func):
2188                keys = [u_, a_, b_, F_, n_]
2189                if len(match) == len(keys):
2190                    u, a, b, F, n = tuple([match[i] for i in keys])
2191                    match = F.args[0].match(c_ + d_*x)
2192                    if match:
2193                        keys = c_, d_
2194                        if len(keys) == len(match):
2195                            c, d = tuple([match[i] for i in keys])
2196                            if PolynomialQ(u, x):
2197                                F = F.func
2198                                return ExpandLinearProduct((a + b*F(c + d*x))**n, u, c, d, x)
2199
2200        expr = expr.replace(sym_exp, rubi_exp)
2201        res = replace_all(UtilityOperator(expr, x), ExpandIntegrand_rules, max_count = 1)
2202        return replace_pow_exp(res)
2203
2204
2205def SimplerQ(u, v):
2206    # If u is simpler than v, SimplerQ(u, v) returns True, else it returns False.  SimplerQ(u, u) returns False
2207    if IntegerQ(u):
2208        if IntegerQ(v):
2209            if Abs(u)==Abs(v):
2210                return v<0
2211            else:
2212                return Abs(u)<Abs(v)
2213        else:
2214            return True
2215    elif IntegerQ(v):
2216        return False
2217    elif FractionQ(u):
2218        if FractionQ(v):
2219            if Denominator(u) == Denominator(v):
2220                return SimplerQ(Numerator(u), Numerator(v))
2221            else:
2222                return Denominator(u)<Denominator(v)
2223        else:
2224            return True
2225    elif FractionQ(v):
2226        return False
2227    elif (Re(u)==0 or Re(u) == 0) and (Re(v)==0 or Re(v) == 0):
2228        return SimplerQ(Im(u), Im(v))
2229    elif ComplexNumberQ(u):
2230        if ComplexNumberQ(v):
2231            if Re(u) == Re(v):
2232                return SimplerQ(Im(u), Im(v))
2233            else:
2234                return SimplerQ(Re(u),Re(v))
2235        else:
2236            return False
2237    elif NumberQ(u):
2238        if NumberQ(v):
2239            return OrderedQ([u,v])
2240        else:
2241            return True
2242    elif NumberQ(v):
2243        return False
2244    elif AtomQ(u) or (Head(u) == re) or (Head(u) == im):
2245        if AtomQ(v) or (Head(u) == re) or (Head(u) == im):
2246            return OrderedQ([u,v])
2247        else:
2248            return True
2249    elif AtomQ(v) or (Head(u) == re) or (Head(u) == im):
2250        return False
2251    elif Head(u) == Head(v):
2252        if Length(u) == Length(v):
2253            for i in range(len(u.args)):
2254                if not u.args[i] == v.args[i]:
2255                    return SimplerQ(u.args[i], v.args[i])
2256            return False
2257        return Length(u) < Length(v)
2258    elif LeafCount(u) < LeafCount(v):
2259        return True
2260    elif LeafCount(v) < LeafCount(u):
2261        return False
2262    return Not(OrderedQ([v,u]))
2263
2264def SimplerSqrtQ(u, v):
2265    # If Rt(u, 2) is simpler than Rt(v, 2), SimplerSqrtQ(u, v) returns True, else it returns False.  SimplerSqrtQ(u, u) returns False
2266    if NegativeQ(v) and Not(NegativeQ(u)):
2267        return True
2268    if NegativeQ(u) and Not(NegativeQ(v)):
2269        return False
2270    sqrtu = Rt(u, S(2))
2271    sqrtv = Rt(v, S(2))
2272    if IntegerQ(sqrtu):
2273        if IntegerQ(sqrtv):
2274            return sqrtu<sqrtv
2275        else:
2276            return True
2277    if IntegerQ(sqrtv):
2278        return False
2279    if RationalQ(sqrtu):
2280        if RationalQ(sqrtv):
2281            return sqrtu<sqrtv
2282        else:
2283            return True
2284    if RationalQ(sqrtv):
2285        return False
2286    if PosQ(u):
2287        if PosQ(v):
2288            return LeafCount(sqrtu)<LeafCount(sqrtv)
2289        else:
2290            return True
2291    if PosQ(v):
2292        return False
2293    if LeafCount(sqrtu)<LeafCount(sqrtv):
2294        return True
2295    if LeafCount(sqrtv)<LeafCount(sqrtu):
2296        return False
2297    else:
2298        return Not(OrderedQ([v, u]))
2299
2300def SumSimplerQ(u, v):
2301    """
2302    If u + v is simpler than u, SumSimplerQ(u, v) returns True, else it returns False.
2303    If for every term w of v there is a term of u equal to n*w where n<-1/2, u + v will be simpler than u.
2304
2305    Examples
2306    ========
2307
2308    >>> from sympy.integrals.rubi.utility_function import SumSimplerQ
2309    >>> from sympy.abc import x
2310    >>> from sympy import S
2311    >>> SumSimplerQ(S(4 + x),S(3 + x**3))
2312    False
2313
2314    """
2315    if RationalQ(u, v):
2316        if v == S(0):
2317            return False
2318        elif v > S(0):
2319            return u < -S(1)
2320        else:
2321            return u >= -v
2322    else:
2323        return SumSimplerAuxQ(Expand(u), Expand(v))
2324
2325def BinomialDegree(u, x):
2326    # if u is a binomial. BinomialDegree[u,x] returns the degree of x in u.
2327    bp = BinomialParts(u, x)
2328    if bp == False:
2329        return bp
2330    return bp[2]
2331
2332def TrinomialDegree(u, x):
2333    # If u is equivalent to a trinomial of the form a + b*x^n + c*x^(2*n) where n!=0, b!=0 and c!=0, TrinomialDegree[u,x] returns n
2334    t = TrinomialParts(u, x)
2335    if t:
2336        return t[3]
2337    return t
2338
2339def CancelCommonFactors(u, v):
2340    def _delete_cases(a, b):
2341        # only for CancelCommonFactors
2342        lst = []
2343        deleted = False
2344        for i in a.args:
2345            if i == b and not deleted:
2346                deleted = True
2347                continue
2348            lst.append(i)
2349        return a.func(*lst)
2350
2351    # CancelCommonFactors[u,v] returns {u',v'} are the noncommon factors of u and v respectively.
2352    if ProductQ(u):
2353        if ProductQ(v):
2354            if MemberQ(v, First(u)):
2355                return CancelCommonFactors(Rest(u), _delete_cases(v, First(u)))
2356            else:
2357                lst = CancelCommonFactors(Rest(u), v)
2358                return [First(u)*lst[0], lst[1]]
2359        else:
2360            if MemberQ(u, v):
2361                return [_delete_cases(u, v), 1]
2362            else:
2363                return[u, v]
2364    elif ProductQ(v):
2365        if MemberQ(v, u):
2366            return [1, _delete_cases(v, u)]
2367        else:
2368            return [u, v]
2369    return[u, v]
2370
2371def SimplerIntegrandQ(u, v, x):
2372    lst = CancelCommonFactors(u, v)
2373    u1 = lst[0]
2374    v1 = lst[1]
2375    if Head(u1) == Head(v1) and Length(u1) == 1 and Length(v1) == 1:
2376        return SimplerIntegrandQ(u1.args[0], v1.args[0], x)
2377    if 4*LeafCount(u1) < 3*LeafCount(v1):
2378        return True
2379    if RationalFunctionQ(u1, x):
2380        if RationalFunctionQ(v1, x):
2381            t1 = 0
2382            t2 = 0
2383            for i in RationalFunctionExponents(u1, x):
2384                t1 += i
2385            for i in RationalFunctionExponents(v1, x):
2386                t2 += i
2387            return t1 < t2
2388        else:
2389            return True
2390    else:
2391        return False
2392
2393def GeneralizedBinomialDegree(u, x):
2394    b = GeneralizedBinomialParts(u, x)
2395    if b:
2396        return b[2] - b[3]
2397
2398def GeneralizedBinomialParts(expr, x):
2399    expr = Expand(expr)
2400    if GeneralizedBinomialMatchQ(expr, x):
2401        a = Wild('a', exclude=[x])
2402        b = Wild('b', exclude=[x])
2403        n = Wild('n', exclude=[x])
2404        q = Wild('q', exclude=[x])
2405        Match = expr.match(a*x**q + b*x**n)
2406        if Match and PosQ(Match[q] - Match[n]):
2407            return [Match[b], Match[a], Match[q], Match[n]]
2408    else:
2409        return False
2410
2411def GeneralizedTrinomialDegree(u, x):
2412    t = GeneralizedTrinomialParts(u, x)
2413    if t:
2414        return t[3] - t[4]
2415
2416def GeneralizedTrinomialParts(expr, x):
2417    expr = Expand(expr)
2418    if GeneralizedTrinomialMatchQ(expr, x):
2419        a = Wild('a', exclude=[x, 0])
2420        b = Wild('b', exclude=[x, 0])
2421        c = Wild('c', exclude=[x])
2422        n = Wild('n', exclude=[x, 0])
2423        q = Wild('q', exclude=[x])
2424        Match = expr.match(a*x**q + b*x**n+c*x**(2*n-q))
2425        if Match and expr.is_Add:
2426            return [Match[c], Match[b], Match[a], Match[n], 2*Match[n]-Match[q]]
2427    else:
2428        return False
2429
2430def MonomialQ(u, x):
2431    # If u is of the form a*x^n where n!=0 and a!=0, MonomialQ[u,x] returns True; else False
2432    if isinstance(u, list):
2433        return all(MonomialQ(i, x) for i in u)
2434    else:
2435        a = Wild('a', exclude=[x])
2436        b = Wild('b', exclude=[x])
2437        re = u.match(a*x**b)
2438        if re:
2439            return True
2440    return False
2441
2442def MonomialSumQ(u, x):
2443    # if u(x) is a sum and each term is free of x or an expression of the form a*x^n, MonomialSumQ(u, x) returns True; else it returns False
2444    if SumQ(u):
2445        for i in u.args:
2446            if Not(FreeQ(i, x) or MonomialQ(i, x)):
2447                return False
2448        return True
2449
2450@doctest_depends_on(modules=('matchpy',))
2451def MinimumMonomialExponent(u, x):
2452    """
2453    u is sum whose terms are monomials.  MinimumMonomialExponent(u, x) returns the exponent of the term having the smallest exponent
2454
2455    Examples
2456    ========
2457
2458    >>> from sympy.integrals.rubi.utility_function import MinimumMonomialExponent
2459    >>> from sympy.abc import  x
2460    >>> MinimumMonomialExponent(x**2 + 5*x**2 + 3*x**5, x)
2461    2
2462    >>> MinimumMonomialExponent(x**2 + 5*x**2 + 1, x)
2463    0
2464    """
2465
2466    n =MonomialExponent(First(u), x)
2467    for i in u.args:
2468        if PosQ(n - MonomialExponent(i, x)):
2469            n = MonomialExponent(i, x)
2470
2471    return n
2472
2473def MonomialExponent(u, x):
2474    # u is a monomial. MonomialExponent(u, x) returns the exponent of x in u
2475    a = Wild('a', exclude=[x])
2476    b = Wild('b', exclude=[x])
2477    re = u.match(a*x**b)
2478    if re:
2479        return re[b]
2480
2481def LinearMatchQ(u, x):
2482    # LinearMatchQ(u, x) returns True iff u matches patterns of the form a+b*x where a and b are free of x
2483    if isinstance(u, list):
2484        return all(LinearMatchQ(i, x) for i in u)
2485    else:
2486        a = Wild('a', exclude=[x])
2487        b = Wild('b', exclude=[x])
2488        re = u.match(a + b*x)
2489        if re:
2490            return True
2491    return False
2492
2493def PowerOfLinearMatchQ(u, x):
2494    if isinstance(u, list):
2495        for i in u:
2496            if not PowerOfLinearMatchQ(i, x):
2497                return False
2498        return True
2499    else:
2500        a = Wild('a', exclude=[x])
2501        b = Wild('b', exclude=[x, 0])
2502        m = Wild('m', exclude=[x, 0])
2503        Match = u.match((a + b*x)**m)
2504        if Match:
2505            return True
2506        else:
2507            return False
2508
2509def QuadraticMatchQ(u, x):
2510    if ListQ(u):
2511        return all(QuadraticMatchQ(i, x) for i in u)
2512    pattern1 = Pattern(UtilityOperator(x_**2*WC('c', 1) + x_*WC('b', 1) + WC('a', 0), x_), CustomConstraint(lambda a, b, c, x: FreeQ([a, b, c], x)))
2513    pattern2 = Pattern(UtilityOperator(x_**2*WC('c', 1) + WC('a', 0), x_), CustomConstraint(lambda a, c, x: FreeQ([a, c], x)))
2514    u1 = UtilityOperator(u, x)
2515    return is_match(u1, pattern1) or is_match(u1, pattern2)
2516
2517def CubicMatchQ(u, x):
2518    if isinstance(u, list):
2519        return all(CubicMatchQ(i, x) for i in u)
2520    else:
2521        pattern1 = Pattern(UtilityOperator(x_**3*WC('d', 1) + x_**2*WC('c', 1) + x_*WC('b', 1) + WC('a', 0), x_), CustomConstraint(lambda a, b, c, d, x: FreeQ([a, b, c, d], x)))
2522        pattern2 = Pattern(UtilityOperator(x_**3*WC('d', 1) + x_*WC('b', 1) + WC('a', 0), x_), CustomConstraint(lambda a, b, d, x: FreeQ([a, b, d], x)))
2523        pattern3 = Pattern(UtilityOperator(x_**3*WC('d', 1) + x_**2*WC('c', 1) + WC('a', 0), x_), CustomConstraint(lambda a, c, d, x: FreeQ([a, c, d], x)))
2524        pattern4 = Pattern(UtilityOperator(x_**3*WC('d', 1) + WC('a', 0), x_), CustomConstraint(lambda a, d, x: FreeQ([a, d], x)))
2525        u1 = UtilityOperator(u, x)
2526        if is_match(u1, pattern1) or is_match(u1, pattern2) or is_match(u1, pattern3) or is_match(u1, pattern4):
2527            return True
2528        else:
2529            return False
2530
2531def BinomialMatchQ(u, x):
2532    if isinstance(u, list):
2533        return all(BinomialMatchQ(i, x) for i in u)
2534    else:
2535        pattern = Pattern(UtilityOperator(x_**WC('n', S(1))*WC('b', S(1)) + WC('a', S(0)), x_) , CustomConstraint(lambda a, b, n, x: FreeQ([a,b,n],x)))
2536        u = UtilityOperator(u, x)
2537        return is_match(u, pattern)
2538
2539def TrinomialMatchQ(u, x):
2540    if isinstance(u, list):
2541        return all(TrinomialMatchQ(i, x) for i in u)
2542    else:
2543        pattern = Pattern(UtilityOperator(x_**WC('j', S(1))*WC('c', S(1)) + x_**WC('n', S(1))*WC('b', S(1)) + WC('a', S(0)), x_) , CustomConstraint(lambda a, b, c, n, x: FreeQ([a, b, c, n], x)),  CustomConstraint(lambda j, n: ZeroQ(j-2*n) ))
2544        u = UtilityOperator(u, x)
2545        return is_match(u, pattern)
2546
2547def GeneralizedBinomialMatchQ(u, x):
2548    if isinstance(u, list):
2549        return all(GeneralizedBinomialMatchQ(i, x) for i in u)
2550    else:
2551        a = Wild('a', exclude=[x, 0])
2552        b = Wild('b', exclude=[x, 0])
2553        n = Wild('n', exclude=[x, 0])
2554        q = Wild('q', exclude=[x, 0])
2555        Match = u.match(a*x**q + b*x**n)
2556        if Match and len(Match) == 4 and Match[q] != 0 and Match[n] != 0:
2557            return True
2558        else:
2559            return False
2560
2561def GeneralizedTrinomialMatchQ(u, x):
2562    if isinstance(u, list):
2563        return all(GeneralizedTrinomialMatchQ(i, x) for i in u)
2564    else:
2565        a = Wild('a', exclude=[x, 0])
2566        b = Wild('b', exclude=[x, 0])
2567        n = Wild('n', exclude=[x, 0])
2568        c = Wild('c', exclude=[x, 0])
2569        q = Wild('q', exclude=[x, 0])
2570        Match = u.match(a*x**q + b*x**n + c*x**(2*n - q))
2571        if Match and len(Match) == 5 and 2*Match[n] - Match[q] != 0 and Match[n] != 0:
2572            return True
2573        else:
2574            return False
2575
2576def QuotientOfLinearsMatchQ(u, x):
2577    if isinstance(u, list):
2578        return all(QuotientOfLinearsMatchQ(i, x) for i in u)
2579    else:
2580        a = Wild('a', exclude=[x])
2581        b = Wild('b', exclude=[x])
2582        d = Wild('d', exclude=[x])
2583        c = Wild('c', exclude=[x])
2584        e = Wild('e')
2585        Match = u.match(e*(a + b*x)/(c + d*x))
2586        if Match and len(Match) == 5:
2587            return True
2588        else:
2589            return False
2590
2591def PolynomialTermQ(u, x):
2592    a = Wild('a', exclude=[x])
2593    n = Wild('n', exclude=[x])
2594    Match = u.match(a*x**n)
2595    if Match and IntegerQ(Match[n]) and Greater(Match[n], S(0)):
2596        return True
2597    else:
2598        return False
2599
2600def PolynomialTerms(u, x):
2601    s = 0
2602    for i in u.args:
2603        if PolynomialTermQ(i, x):
2604            s = s + i
2605    return s
2606
2607def NonpolynomialTerms(u, x):
2608    s = 0
2609    for i in u.args:
2610        if not PolynomialTermQ(i, x):
2611            s = s + i
2612    return s
2613
2614def PseudoBinomialParts(u, x):
2615    if PolynomialQ(u, x) and Greater(Expon(u, x), S(2)):
2616        n = Expon(u, x)
2617        d = Rt(Coefficient(u, x, n), n)
2618        c =  d**(-n + S(1))*Coefficient(u, x, n + S(-1))/n
2619        a = Simplify(u - (c + d*x)**n)
2620        if NonzeroQ(a) and FreeQ(a, x):
2621            return [a, S(1), c, d, n]
2622        else:
2623            return False
2624    else:
2625        return False
2626
2627def NormalizePseudoBinomial(u, x):
2628    lst = PseudoBinomialParts(u, x)
2629    if lst:
2630        return (lst[0] + lst[1]*(lst[2] + lst[3]*x)**lst[4])
2631
2632def PseudoBinomialPairQ(u, v, x):
2633    lst1 = PseudoBinomialParts(u, x)
2634    if AtomQ(lst1):
2635        return False
2636    else:
2637        lst2 = PseudoBinomialParts(v, x)
2638        if AtomQ(lst2):
2639            return False
2640        else:
2641            return Drop(lst1, 2) == Drop(lst2, 2)
2642
2643def PseudoBinomialQ(u, x):
2644    lst = PseudoBinomialParts(u, x)
2645    if lst:
2646        return True
2647    else:
2648        return False
2649
2650def PolynomialGCD(f, g):
2651    return gcd(f, g)
2652
2653def PolyGCD(u, v, x):
2654    # (* u and v are polynomials in x. *)
2655    # (* PolyGCD[u,v,x] returns the factors of the gcd of u and v dependent on x. *)
2656    return NonfreeFactors(PolynomialGCD(u, v), x)
2657
2658def AlgebraicFunctionFactors(u, x, flag=False):
2659    # (* AlgebraicFunctionFactors[u,x] returns the product of the factors of u that are algebraic functions of x. *)
2660    if ProductQ(u):
2661        result = 1
2662        for i in u.args:
2663            if AlgebraicFunctionQ(i, x, flag):
2664                result *= i
2665        return result
2666    if AlgebraicFunctionQ(u, x, flag):
2667        return u
2668    return 1
2669
2670def NonalgebraicFunctionFactors(u, x):
2671    """
2672    NonalgebraicFunctionFactors[u,x] returns the product of the factors of u that are not algebraic functions of x.
2673
2674    Examples
2675    ========
2676
2677    >>> from sympy.integrals.rubi.utility_function import NonalgebraicFunctionFactors
2678    >>> from sympy.abc import  x
2679    >>> from sympy import sin
2680    >>> NonalgebraicFunctionFactors(sin(x), x)
2681    sin(x)
2682    >>> NonalgebraicFunctionFactors(x, x)
2683    1
2684
2685    """
2686    if ProductQ(u):
2687        result = 1
2688        for i in u.args:
2689            if not AlgebraicFunctionQ(i, x):
2690                result *= i
2691        return result
2692    if AlgebraicFunctionQ(u, x):
2693        return 1
2694    return u
2695
2696def QuotientOfLinearsP(u, x):
2697    if LinearQ(u, x):
2698        return True
2699    elif SumQ(u):
2700        if FreeQ(u.args[0], x):
2701            return QuotientOfLinearsP(Rest(u), x)
2702    elif LinearQ(Numerator(u), x) and LinearQ(Denominator(u), x):
2703        return True
2704    elif ProductQ(u):
2705        if FreeQ(First(u), x):
2706            return QuotientOfLinearsP(Rest(u), x)
2707    elif Numerator(u) == 1 and PowerQ(u):
2708        return QuotientOfLinearsP(Denominator(u), x)
2709    return u == x or FreeQ(u, x)
2710
2711def QuotientOfLinearsParts(u, x):
2712    # If u is equivalent to an expression of the form (a+b*x)/(c+d*x), QuotientOfLinearsParts[u,x]
2713    #   returns the list {a, b, c, d}.
2714    if LinearQ(u, x):
2715        return [Coefficient(u, x, 0), Coefficient(u, x, 1), 1, 0]
2716    elif PowerQ(u):
2717        if Numerator(u) == 1:
2718            u = Denominator(u)
2719            r = QuotientOfLinearsParts(u, x)
2720            return [r[2], r[3], r[0], r[1]]
2721    elif SumQ(u):
2722        a = First(u)
2723        if FreeQ(a, x):
2724            u = Rest(u)
2725            r = QuotientOfLinearsParts(u, x)
2726            return [r[0] + a*r[2], r[1] + a*r[3], r[2], r[3]]
2727    elif ProductQ(u):
2728        a = First(u)
2729        if FreeQ(a, x):
2730            r = QuotientOfLinearsParts(Rest(u), x)
2731            return [a*r[0], a*r[1], r[2], r[3]]
2732        a = Numerator(u)
2733        d = Denominator(u)
2734        if LinearQ(a, x) and LinearQ(d, x):
2735            return [Coefficient(a, x, 0), Coefficient(a, x, 1), Coefficient(d, x, 0), Coefficient(d, x, 1)]
2736    elif u == x:
2737        return [0, 1, 1, 0]
2738    elif FreeQ(u, x):
2739        return [u, 0, 1, 0]
2740    return [u, 0, 1, 0]
2741
2742def QuotientOfLinearsQ(u, x):
2743    # (*QuotientOfLinearsQ[u,x] returns True iff u is equivalent to an expression of the form (a+b x)/(c+d x) where b!=0 and d!=0.*)
2744    if ListQ(u):
2745        for i in u:
2746            if not QuotientOfLinearsQ(i, x):
2747                return False
2748        return True
2749    q = QuotientOfLinearsParts(u, x)
2750    return QuotientOfLinearsP(u, x) and NonzeroQ(q[1]) and NonzeroQ(q[3])
2751
2752def Flatten(l):
2753    return flatten(l)
2754
2755def Sort(u, r=False):
2756    return sorted(u, key=lambda x: x.sort_key(), reverse=r)
2757
2758# (*Definition: A number is absurd if it is a rational number, a positive rational number raised to a fractional power, or a product of absurd numbers.*)
2759def AbsurdNumberQ(u):
2760    # (* AbsurdNumberQ[u] returns True if u is an absurd number, else it returns False. *)
2761    if PowerQ(u):
2762        v = u.exp
2763        u = u.base
2764        return RationalQ(u) and u > 0 and FractionQ(v)
2765    elif ProductQ(u):
2766        return all(AbsurdNumberQ(i) for i in u.args)
2767    return RationalQ(u)
2768
2769def AbsurdNumberFactors(u):
2770    # (* AbsurdNumberFactors[u] returns the product of the factors of u that are absurd numbers. *)
2771    if AbsurdNumberQ(u):
2772        return u
2773    elif ProductQ(u):
2774        result = S(1)
2775        for i in u.args:
2776            if AbsurdNumberQ(i):
2777                result *= i
2778        return result
2779    return NumericFactor(u)
2780
2781def NonabsurdNumberFactors(u):
2782    # (* NonabsurdNumberFactors[u] returns the product of the factors of u that are not absurd numbers. *)
2783    if AbsurdNumberQ(u):
2784        return S(1)
2785    elif ProductQ(u):
2786        result = 1
2787        for i in u.args:
2788            result *= NonabsurdNumberFactors(i)
2789        return result
2790    return NonnumericFactors(u)
2791
2792def SumSimplerAuxQ(u, v):
2793    if SumQ(v):
2794        return (RationalQ(First(v)) or SumSimplerAuxQ(u,First(v))) and (RationalQ(Rest(v)) or SumSimplerAuxQ(u,Rest(v)))
2795    elif SumQ(u):
2796        return SumSimplerAuxQ(First(u), v) or SumSimplerAuxQ(Rest(u), v)
2797    else:
2798        return v!=0 and NonnumericFactors(u)==NonnumericFactors(v) and (NumericFactor(u)/NumericFactor(v)<-1/2 or NumericFactor(u)/NumericFactor(v)==-1/2 and NumericFactor(u)<0)
2799
2800def Prepend(l1, l2):
2801    if not isinstance(l2, list):
2802        return [l2] + l1
2803    return l2 + l1
2804
2805def Drop(lst, n):
2806    if isinstance(lst, list):
2807        if isinstance(n, list):
2808            lst = lst[:(n[0]-1)] + lst[n[1]:]
2809        elif n > 0:
2810            lst = lst[n:]
2811        elif n < 0:
2812            lst = lst[:-n]
2813        else:
2814            return lst
2815        return lst
2816    return lst.func(*[i for i in Drop(list(lst.args), n)])
2817
2818def CombineExponents(lst):
2819    if Length(lst) < 2:
2820        return lst
2821    elif lst[0][0] == lst[1][0]:
2822        return CombineExponents(Prepend(Drop(lst,2),[lst[0][0], lst[0][1] + lst[1][1]]))
2823    return Prepend(CombineExponents(Rest(lst)), First(lst))
2824
2825def FactorInteger(n, l=None):
2826    if isinstance(n, (int, Integer)):
2827        return sorted(factorint(n, limit=l).items())
2828    else:
2829        return sorted(factorrat(n, limit=l).items())
2830
2831def FactorAbsurdNumber(m):
2832    # (* m must be an absurd number.  FactorAbsurdNumber[m] returns the prime factorization of m *)
2833    # (* as list of base-degree pairs where the bases are prime numbers and the degrees are rational. *)
2834    if RationalQ(m):
2835        return FactorInteger(m)
2836    elif PowerQ(m):
2837        r = FactorInteger(m.base)
2838        return [r[0], r[1]*m.exp]
2839
2840    # CombineExponents[Sort[Flatten[Map[FactorAbsurdNumber,Apply[List,m]],1], Function[i1[[1]]<i2[[1]]]]]
2841    return list((m.as_base_exp(),))
2842
2843def SubstForInverseFunction(*args):
2844    """
2845    SubstForInverseFunction(u, v, w, x) returns u with subexpressions equal to v replaced by x and x replaced by w.
2846
2847    Examples
2848    ========
2849
2850    >>> from sympy.integrals.rubi.utility_function import SubstForInverseFunction
2851    >>> from sympy.abc import  x, a, b
2852    >>> SubstForInverseFunction(a, a, b, x)
2853    a
2854    >>> SubstForInverseFunction(x**a, x**a, b, x)
2855    x
2856    >>> SubstForInverseFunction(a*x**a, a, b, x)
2857    a*b**a
2858
2859    """
2860    if len(args) == 3:
2861        u, v, x = args[0], args[1], args[2]
2862        return SubstForInverseFunction(u, v, (-Coefficient(v.args[0], x, 0) + InverseFunction(Head(v))(x))/Coefficient(v.args[0], x, 1), x)
2863    elif len(args) == 4:
2864        u, v, w, x = args[0], args[1], args[2], args[3]
2865        if AtomQ(u):
2866            if u == x:
2867                return w
2868            return u
2869        elif Head(u) == Head(v) and ZeroQ(u.args[0] - v.args[0]):
2870            return x
2871        res = [SubstForInverseFunction(i, v, w, x) for i in u.args]
2872        return u.func(*res)
2873
2874def SubstForFractionalPower(u, v, n, w, x):
2875    # (* SubstForFractionalPower[u,v,n,w,x] returns u with subexpressions equal to v^(m/n) replaced
2876    # by x^m and x replaced by w. *)
2877    if AtomQ(u):
2878        if u == x:
2879            return w
2880        return u
2881    elif FractionalPowerQ(u):
2882        if ZeroQ(u.base - v):
2883            return x**(n*u.exp)
2884    res = [SubstForFractionalPower(i, v, n, w, x) for i in u.args]
2885    return u.func(*res)
2886
2887def SubstForFractionalPowerOfQuotientOfLinears(u, x):
2888    # (* If u has a subexpression of the form ((a+b*x)/(c+d*x))^(m/n) where m and n>1 are integers,
2889    # SubstForFractionalPowerOfQuotientOfLinears[u,x] returns the list {v,n,(a+b*x)/(c+d*x),b*c-a*d} where v is u
2890    # with subexpressions of the form ((a+b*x)/(c+d*x))^(m/n) replaced by x^m and x replaced
2891    lst = FractionalPowerOfQuotientOfLinears(u, 1, False, x)
2892    if AtomQ(lst) or AtomQ(lst[1]):
2893        return False
2894    n = lst[0]
2895    tmp = lst[1]
2896    lst = QuotientOfLinearsParts(tmp, x)
2897    a, b, c, d = lst[0], lst[1], lst[2], lst[3]
2898    if ZeroQ(d):
2899        return False
2900    lst = Simplify(x**(n - 1)*SubstForFractionalPower(u, tmp, n, (-a + c*x**n)/(b - d*x**n), x)/(b - d*x**n)**2)
2901    return [NonfreeFactors(lst, x), n, tmp, FreeFactors(lst, x)*(b*c - a*d)]
2902
2903def FractionalPowerOfQuotientOfLinears(u, n, v, x):
2904    # (* If u has a subexpression of the form ((a+b*x)/(c+d*x))^(m/n),
2905    # FractionalPowerOfQuotientOfLinears[u,1,False,x] returns {n,(a+b*x)/(c+d*x)}; else it returns False. *)
2906    if AtomQ(u) or FreeQ(u, x):
2907        return [n, v]
2908    elif CalculusQ(u):
2909        return False
2910    elif FractionalPowerQ(u):
2911        if QuotientOfLinearsQ(u.base, x) and Not(LinearQ(u.base, x)) and (FalseQ(v) or ZeroQ(u.base - v)):
2912            return [LCM(Denominator(u.exp), n), u.base]
2913    lst = [n, v]
2914    for i in u.args:
2915        lst = FractionalPowerOfQuotientOfLinears(i, lst[0], lst[1],x)
2916        if AtomQ(lst):
2917            return False
2918    return lst
2919
2920def SubstForFractionalPowerQ(u, v, x):
2921    # (* If the substitution x=v^(1/n) will not complicate algebraic subexpressions of u,
2922    # SubstForFractionalPowerQ[u,v,x] returns True; else it returns False. *)
2923    if AtomQ(u) or FreeQ(u, x):
2924        return True
2925    elif FractionalPowerQ(u):
2926        return SubstForFractionalPowerAuxQ(u, v, x)
2927    return all(SubstForFractionalPowerQ(i, v, x) for i in u.args)
2928
2929def SubstForFractionalPowerAuxQ(u, v, x):
2930    if AtomQ(u):
2931        return False
2932    elif FractionalPowerQ(u):
2933        if ZeroQ(u.base - v):
2934            return True
2935    return any(SubstForFractionalPowerAuxQ(i, v, x) for i in u.args)
2936
2937def FractionalPowerOfSquareQ(u):
2938    # (* If a subexpression of u is of the form ((v+w)^2)^n where n is a fraction, *)
2939    # (* FractionalPowerOfSquareQ[u] returns (v+w)^2; else it returns False. *)
2940    if AtomQ(u):
2941        return False
2942    elif FractionalPowerQ(u):
2943        a_ = Wild('a', exclude=[0])
2944        b_ = Wild('b', exclude=[0])
2945        c_ = Wild('c', exclude=[0])
2946        match = u.base.match(a_*(b_ + c_)**(S(2)))
2947        if match:
2948            keys = [a_, b_, c_]
2949            if len(keys) == len(match):
2950                a, b, c = tuple(match[i] for i in keys)
2951                if NonsumQ(a):
2952                    return (b + c)**S(2)
2953    for i in u.args:
2954        tmp = FractionalPowerOfSquareQ(i)
2955        if Not(FalseQ(tmp)):
2956            return tmp
2957    return False
2958
2959def FractionalPowerSubexpressionQ(u, v, w):
2960    # (* If a subexpression of u is of the form w^n where n is a fraction but not equal to v, *)
2961    # (* FractionalPowerSubexpressionQ[u,v,w] returns True; else it returns False. *)
2962    if AtomQ(u):
2963        return False
2964    elif FractionalPowerQ(u):
2965        if PositiveQ(u.base/w):
2966            return Not(u.base == v) and LeafCount(w) < 3*LeafCount(v)
2967    for i in u.args:
2968        if FractionalPowerSubexpressionQ(i, v, w):
2969            return True
2970    return False
2971
2972def Apply(f, lst):
2973    return f(*lst)
2974
2975def FactorNumericGcd(u):
2976    # (* FactorNumericGcd[u] returns u with the gcd of the numeric coefficients of terms of sums factored out. *)
2977    if PowerQ(u):
2978        if RationalQ(u.exp):
2979            return FactorNumericGcd(u.base)**u.exp
2980    elif ProductQ(u):
2981        res = [FactorNumericGcd(i) for i in u.args]
2982        return Mul(*res)
2983    elif SumQ(u):
2984        g = GCD([NumericFactor(i) for i in u.args])
2985        r = Add(*[i/g for i in u.args])
2986        return g*r
2987    return u
2988
2989def MergeableFactorQ(bas, deg, v):
2990    # (* MergeableFactorQ[bas,deg,v] returns True iff bas equals the base of a factor of v or bas is a factor of every term of v. *)
2991    if bas == v:
2992        return RationalQ(deg + S(1)) and (deg + 1>=0 or RationalQ(deg) and deg>0)
2993    elif PowerQ(v):
2994        if bas == v.base:
2995            return RationalQ(deg+v.exp) and (deg+v.exp>=0 or RationalQ(deg) and deg>0)
2996        return SumQ(v.base) and IntegerQ(v.exp) and (Not(IntegerQ(deg) or IntegerQ(deg/v.exp))) and MergeableFactorQ(bas, deg/v.exp, v.base)
2997    elif ProductQ(v):
2998        return MergeableFactorQ(bas, deg, First(v)) or MergeableFactorQ(bas, deg, Rest(v))
2999    return SumQ(v) and MergeableFactorQ(bas, deg, First(v)) and MergeableFactorQ(bas, deg, Rest(v))
3000
3001def MergeFactor(bas, deg, v):
3002    # (* If MergeableFactorQ[bas,deg,v], MergeFactor[bas,deg,v] return the product of bas^deg and v,
3003    # but with bas^deg merged into the factor of v whose base equals bas. *)
3004    if bas == v:
3005        return bas**(deg + 1)
3006    elif PowerQ(v):
3007        if bas == v.base:
3008            return bas**(deg + v.exp)
3009        return MergeFactor(bas, deg/v.exp, v.base**v.exp)
3010    elif ProductQ(v):
3011        if MergeableFactorQ(bas, deg, First(v)):
3012            return MergeFactor(bas, deg, First(v))*Rest(v)
3013        return First(v)*MergeFactor(bas, deg, Rest(v))
3014    return MergeFactor(bas, deg, First(v)) + MergeFactor(bas, deg, Rest(v))
3015
3016def MergeFactors(u, v):
3017    # (* MergeFactors[u,v] returns the product of u and v, but with the mergeable factors of u merged into v. *)
3018    if ProductQ(u):
3019        return MergeFactors(Rest(u), MergeFactors(First(u), v))
3020    elif PowerQ(u):
3021        if MergeableFactorQ(u.base, u.exp, v):
3022            return MergeFactor(u.base, u.exp, v)
3023        elif RationalQ(u.exp) and u.exp < -1 and MergeableFactorQ(u.base, -S(1), v):
3024            return MergeFactors(u.base**(u.exp + 1), MergeFactor(u.base, -S(1), v))
3025        return u*v
3026    elif MergeableFactorQ(u, S(1), v):
3027        return MergeFactor(u, S(1), v)
3028    return u*v
3029
3030def TrigSimplifyQ(u):
3031    # (* TrigSimplifyQ[u] returns True if TrigSimplify[u] actually simplifies u; else False. *)
3032    return ActivateTrig(u) != TrigSimplify(u)
3033
3034def TrigSimplify(u):
3035    # (* TrigSimplify[u] returns a bottom-up trig simplification of u. *)
3036    return ActivateTrig(TrigSimplifyRecur(u))
3037
3038def TrigSimplifyRecur(u):
3039    if AtomQ(u):
3040        return u
3041    return TrigSimplifyAux(u.func(*[TrigSimplifyRecur(i) for i in u.args]))
3042
3043def Order(expr1, expr2):
3044    if expr1 == expr2:
3045        return 0
3046    elif expr1.sort_key() > expr2.sort_key():
3047        return -1
3048    return 1
3049
3050def FactorOrder(u, v):
3051    if u == 1:
3052        if v == 1:
3053            return 0
3054        return -1
3055    elif v == 1:
3056        return 1
3057    return Order(u, v)
3058
3059def Smallest(num1, num2=None):
3060    if num2 is None:
3061        lst = num1
3062        num = lst[0]
3063        for i in Rest(lst):
3064            num = Smallest(num, i)
3065        return num
3066    return Min(num1, num2)
3067
3068def OrderedQ(l):
3069    return l == Sort(l)
3070
3071def MinimumDegree(deg1, deg2):
3072    if RationalQ(deg1):
3073        if RationalQ(deg2):
3074            return Min(deg1, deg2)
3075        return deg1
3076    elif RationalQ(deg2):
3077        return deg2
3078
3079    deg = Simplify(deg1- deg2)
3080
3081    if RationalQ(deg):
3082        if deg > 0:
3083            return deg2
3084        return deg1
3085    elif OrderedQ([deg1, deg2]):
3086        return deg1
3087    return deg2
3088
3089def PositiveFactors(u):
3090    # (* PositiveFactors[u] returns the positive factors of u *)
3091    if ZeroQ(u):
3092        return S(1)
3093    elif RationalQ(u):
3094        return Abs(u)
3095    elif PositiveQ(u):
3096        return u
3097    elif ProductQ(u):
3098        res = 1
3099        for i in u.args:
3100            res *= PositiveFactors(i)
3101        return res
3102    return 1
3103
3104def Sign(u):
3105    return sign(u)
3106
3107def NonpositiveFactors(u):
3108    # (* NonpositiveFactors[u] returns the nonpositive factors of u *)
3109    if ZeroQ(u):
3110        return u
3111    elif RationalQ(u):
3112        return Sign(u)
3113    elif PositiveQ(u):
3114        return S(1)
3115    elif ProductQ(u):
3116        res = S(1)
3117        for i in u.args:
3118            res *= NonpositiveFactors(i)
3119        return res
3120    return u
3121
3122def PolynomialInAuxQ(u, v, x):
3123    if u == v:
3124        return True
3125    elif AtomQ(u):
3126        return u != x
3127    elif PowerQ(u):
3128        if PowerQ(v):
3129            if u.base == v.base:
3130                return PositiveIntegerQ(u.exp/v.exp)
3131        return PositiveIntegerQ(u.exp) and PolynomialInAuxQ(u.base, v, x)
3132    elif SumQ(u) or ProductQ(u):
3133        for i in u.args:
3134            if Not(PolynomialInAuxQ(i, v, x)):
3135                return False
3136        return True
3137    return False
3138
3139def PolynomialInQ(u, v, x):
3140    """
3141    If u is a polynomial in v(x), PolynomialInQ(u, v, x) returns True, else it returns False.
3142
3143    Examples
3144    ========
3145
3146    >>> from sympy.integrals.rubi.utility_function import PolynomialInQ
3147    >>> from sympy.abc import  x
3148    >>> from sympy import log, S
3149    >>> PolynomialInQ(S(1), log(x), x)
3150    True
3151    >>> PolynomialInQ(log(x), log(x), x)
3152    True
3153    >>> PolynomialInQ(1 + log(x)**2, log(x), x)
3154    True
3155
3156    """
3157    return PolynomialInAuxQ(u, NonfreeFactors(NonfreeTerms(v, x), x), x)
3158
3159def ExponentInAux(u, v, x):
3160    if u == v:
3161        return S(1)
3162    elif AtomQ(u):
3163        return S(0)
3164    elif PowerQ(u):
3165        if PowerQ(v):
3166            if u.base == v.base:
3167                return u.exp/v.exp
3168        return u.exp*ExponentInAux(u.base, v, x)
3169    elif ProductQ(u):
3170        return Add(*[ExponentInAux(i, v, x) for i in u.args])
3171    return Max(*[ExponentInAux(i, v, x) for i in u.args])
3172
3173def ExponentIn(u, v, x):
3174    return ExponentInAux(u, NonfreeFactors(NonfreeTerms(v, x), x), x)
3175
3176def PolynomialInSubstAux(u, v, x):
3177    if u == v:
3178        return x
3179    elif AtomQ(u):
3180        return u
3181    elif PowerQ(u):
3182        if PowerQ(v):
3183            if u.base == v.base:
3184                return x**(u.exp/v.exp)
3185        return PolynomialInSubstAux(u.base, v, x)**u.exp
3186    return u.func(*[PolynomialInSubstAux(i, v, x) for i in u.args])
3187
3188def PolynomialInSubst(u, v, x):
3189    # If u is a polynomial in v[x], PolynomialInSubst[u,v,x] returns the polynomial u in x.
3190    w = NonfreeTerms(v, x)
3191    return ReplaceAll(PolynomialInSubstAux(u, NonfreeFactors(w, x), x), {x: x - FreeTerms(v, x)/FreeFactors(w, x)})
3192
3193def Distrib(u, v):
3194    # Distrib[u,v] returns the sum of u times each term of v.
3195    if SumQ(v):
3196        return Add(*[u*i for i in v.args])
3197    return u*v
3198
3199def DistributeDegree(u, m):
3200    # DistributeDegree[u,m] returns the product of the factors of u each raised to the mth degree.
3201    if AtomQ(u):
3202        return u**m
3203    elif PowerQ(u):
3204        return u.base**(u.exp*m)
3205    elif ProductQ(u):
3206        return Mul(*[DistributeDegree(i, m) for i in u.args])
3207    return u**m
3208
3209def FunctionOfPower(*args):
3210    """
3211    FunctionOfPower[u,x] returns the gcd of the integer degrees of x in u.
3212
3213    Examples
3214    ========
3215
3216    >>> from sympy.integrals.rubi.utility_function import FunctionOfPower
3217    >>> from sympy.abc import  x
3218    >>> FunctionOfPower(x, x)
3219    1
3220    >>> FunctionOfPower(x**3, x)
3221    3
3222
3223    """
3224    if len(args) == 2:
3225        return FunctionOfPower(args[0], None, args[1])
3226
3227    u, n, x = args
3228
3229    if FreeQ(u, x):
3230        return n
3231    elif u == x:
3232        return S(1)
3233    elif PowerQ(u):
3234        if u.base == x and IntegerQ(u.exp):
3235            if n is None:
3236                return u.exp
3237            return GCD(n, u.exp)
3238    tmp = n
3239    for i in u.args:
3240        tmp = FunctionOfPower(i, tmp, x)
3241    return tmp
3242
3243def DivideDegreesOfFactors(u, n):
3244    """
3245    DivideDegreesOfFactors[u,n] returns the product of the base of the factors of u raised to the degree of the factors divided by n.
3246
3247    Examples
3248    ========
3249
3250    >>> from sympy import S
3251    >>> from sympy.integrals.rubi.utility_function import DivideDegreesOfFactors
3252    >>> from sympy.abc import a, b
3253    >>> DivideDegreesOfFactors(a**b, S(3))
3254    a**(b/3)
3255
3256    """
3257    if ProductQ(u):
3258        return Mul(*[LeadBase(i)**(LeadDegree(i)/n) for i in u.args])
3259    return LeadBase(u)**(LeadDegree(u)/n)
3260
3261def MonomialFactor(u, x):
3262    # MonomialFactor[u,x] returns the list {n,v} where x^n*v==u and n is free of x.
3263    if AtomQ(u):
3264        if u == x:
3265            return [S(1), S(1)]
3266        return [S(0), u]
3267    elif PowerQ(u):
3268        if IntegerQ(u.exp):
3269            lst = MonomialFactor(u.base, x)
3270            return [lst[0]*u.exp, lst[1]**u.exp]
3271        elif u.base == x and FreeQ(u.exp, x):
3272            return [u.exp, S(1)]
3273        return [S(0), u]
3274    elif ProductQ(u):
3275        lst1 = MonomialFactor(First(u), x)
3276        lst2 = MonomialFactor(Rest(u), x)
3277        return [lst1[0] + lst2[0], lst1[1]*lst2[1]]
3278    elif SumQ(u):
3279        lst = [MonomialFactor(i, x) for i in u.args]
3280        deg = lst[0][0]
3281        for i in Rest(lst):
3282            deg = MinimumDegree(deg, i[0])
3283        if ZeroQ(deg) or RationalQ(deg) and deg < 0:
3284            return [S(0), u]
3285        return [deg, Add(*[x**(i[0] - deg)*i[1] for i in lst])]
3286    return [S(0), u]
3287
3288def FullSimplify(expr):
3289    return Simplify(expr)
3290
3291def FunctionOfLinearSubst(u, a, b, x):
3292    if FreeQ(u, x):
3293        return u
3294    elif LinearQ(u, x):
3295        tmp = Coefficient(u, x, 1)
3296        if tmp == b:
3297            tmp = S(1)
3298        else:
3299            tmp = tmp/b
3300        return Coefficient(u, x, S(0)) - a*tmp + tmp*x
3301    elif PowerQ(u):
3302        if FreeQ(u.base, x):
3303            return E**(FullSimplify(FunctionOfLinearSubst(Log(u.base)*u.exp, a, b, x)))
3304    lst = MonomialFactor(u, x)
3305    if ProductQ(u) and NonzeroQ(lst[0]):
3306        if RationalQ(LeadFactor(lst[1])) and LeadFactor(lst[1]) < 0:
3307            return  -FunctionOfLinearSubst(DivideDegreesOfFactors(-lst[1], lst[0])*x, a, b, x)**lst[0]
3308        return FunctionOfLinearSubst(DivideDegreesOfFactors(lst[1], lst[0])*x, a, b, x)**lst[0]
3309    return u.func(*[FunctionOfLinearSubst(i, a, b, x) for i in u.args])
3310
3311
3312def FunctionOfLinear(*args):
3313    # (* If u (x) is equivalent to an expression of the form f (a+b*x) and not the case that a==0 and
3314    # b==1, FunctionOfLinear[u,x] returns the list {f (x),a,b}; else it returns False. *)
3315    if len(args) == 2:
3316        u, x = args
3317        lst = FunctionOfLinear(u, False, False, x, False)
3318        if AtomQ(lst) or FalseQ(lst[0]) or (lst[0] == 0 and lst[1] == 1):
3319            return False
3320        return [FunctionOfLinearSubst(u, lst[0], lst[1], x), lst[0], lst[1]]
3321    u, a, b, x, flag = args
3322    if FreeQ(u, x):
3323        return [a, b]
3324    elif CalculusQ(u):
3325        return False
3326    elif LinearQ(u, x):
3327        if FalseQ(a):
3328            return [Coefficient(u, x, 0), Coefficient(u, x, 1)]
3329        lst = CommonFactors([b, Coefficient(u, x, 1)])
3330        if ZeroQ(Coefficient(u, x, 0)) and Not(flag):
3331            return [0, lst[0]]
3332        elif ZeroQ(b*Coefficient(u, x, 0) - a*Coefficient(u, x, 1)):
3333            return [a/lst[1], lst[0]]
3334        return [0, 1]
3335    elif PowerQ(u):
3336        if FreeQ(u.base, x):
3337            return FunctionOfLinear(Log(u.base)*u.exp, a, b, x, False)
3338    lst = MonomialFactor(u, x)
3339    if ProductQ(u) and NonzeroQ(lst[0]):
3340        if False and IntegerQ(lst[0]) and lst[0] != -1 and FreeQ(lst[1], x):
3341            if RationalQ(LeadFactor(lst[1])) and LeadFactor(lst[1]) < 0:
3342                return FunctionOfLinear(DivideDegreesOfFactors(-lst[1], lst[0])*x, a, b, x, False)
3343            return FunctionOfLinear(DivideDegreesOfFactors(lst[1], lst[0])*x, a, b, x, False)
3344        return False
3345    lst = [a, b]
3346    for i in u.args:
3347        lst = FunctionOfLinear(i, lst[0], lst[1], x, SumQ(u))
3348        if AtomQ(lst):
3349            return False
3350    return lst
3351
3352def NormalizeIntegrand(u, x):
3353    v = NormalizeLeadTermSigns(NormalizeIntegrandAux(u, x))
3354    if v == NormalizeLeadTermSigns(u):
3355        return u
3356    else:
3357        return v
3358
3359def NormalizeIntegrandAux(u, x):
3360    if SumQ(u):
3361        l = 0
3362        for i in u.args:
3363            l += NormalizeIntegrandAux(i, x)
3364        return l
3365    if ProductQ(MergeMonomials(u, x)):
3366        l = 1
3367        for i in MergeMonomials(u, x).args:
3368            l *= NormalizeIntegrandFactor(i, x)
3369        return l
3370    else:
3371        return NormalizeIntegrandFactor(MergeMonomials(u, x), x)
3372
3373def NormalizeIntegrandFactor(u, x):
3374    if PowerQ(u):
3375        if FreeQ(u.exp, x):
3376            bas = NormalizeIntegrandFactorBase(u.base, x)
3377            deg = u.exp
3378            if IntegerQ(deg) and SumQ(bas):
3379                if all(MonomialQ(i, x) for i in bas.args):
3380                    mi = MinimumMonomialExponent(bas, x)
3381                    q = 0
3382                    for i in bas.args:
3383                        q += Simplify(i/x**mi)
3384                    return x**(mi*deg)*q**deg
3385                else:
3386                    return bas**deg
3387            else:
3388                return bas**deg
3389    if PowerQ(u):
3390        if FreeQ(u.base, x):
3391            return u.base**NormalizeIntegrandFactorBase(u.exp, x)
3392    bas = NormalizeIntegrandFactorBase(u, x)
3393    if SumQ(bas):
3394        if all(MonomialQ(i, x) for i in bas.args):
3395            mi = MinimumMonomialExponent(bas, x)
3396            z = 0
3397            for j in bas.args:
3398                z += j/x**mi
3399            return x**mi*z
3400        else:
3401            return bas
3402    else:
3403        return bas
3404
3405def NormalizeIntegrandFactorBase(expr, x):
3406    m = Wild('m', exclude=[x])
3407    u = Wild('u')
3408    match = expr.match(x**m*u)
3409    if match and SumQ(u):
3410        l = 0
3411        for i in u.args:
3412            l += NormalizeIntegrandFactorBase((x**m*i), x)
3413        return l
3414    if BinomialQ(expr, x):
3415        if BinomialMatchQ(expr, x):
3416            return expr
3417        else:
3418            return ExpandToSum(expr, x)
3419    elif TrinomialQ(expr, x):
3420        if TrinomialMatchQ(expr, x):
3421            return expr
3422        else:
3423            return ExpandToSum(expr, x)
3424    elif ProductQ(expr):
3425        l = 1
3426        for i in expr.args:
3427            l *= NormalizeIntegrandFactor(i, x)
3428        return l
3429    elif PolynomialQ(expr, x) and Exponent(expr, x) <= 4:
3430        return ExpandToSum(expr, x)
3431    elif SumQ(expr):
3432        w = Wild('w')
3433        m = Wild('m', exclude=[x])
3434        v = TogetherSimplify(expr)
3435        if SumQ(v) or v.match(x**m*w) and SumQ(w) or LeafCount(v) > LeafCount(expr) + 2:
3436            return UnifySum(expr, x)
3437        else:
3438            return NormalizeIntegrandFactorBase(v, x)
3439    else:
3440        return expr
3441
3442def NormalizeTogether(u):
3443    return NormalizeLeadTermSigns(Together(u))
3444
3445def NormalizeLeadTermSigns(u):
3446    if ProductQ(u):
3447        t = 1
3448        for i in u.args:
3449            lst = SignOfFactor(i)
3450            if lst[0] == 1:
3451                t *= lst[1]
3452            else:
3453                t *= AbsorbMinusSign(lst[1])
3454        return t
3455    else:
3456        lst = SignOfFactor(u)
3457    if lst[0] == 1:
3458        return lst[1]
3459    else:
3460        return AbsorbMinusSign(lst[1])
3461
3462def AbsorbMinusSign(expr, *x):
3463    m = Wild('m', exclude=[x])
3464    u = Wild('u')
3465    v = Wild('v')
3466    match = expr.match(u*v**m)
3467    if match:
3468        if len(match) == 3:
3469            if SumQ(match[v]) and OddQ(match[m]):
3470                return match[u]*(-match[v])**match[m]
3471
3472    return -expr
3473
3474def NormalizeSumFactors(u):
3475    if AtomQ(u):
3476        return u
3477    elif ProductQ(u):
3478        k = 1
3479        for i in u.args:
3480            k *= NormalizeSumFactors(i)
3481        return SignOfFactor(k)[0]*SignOfFactor(k)[1]
3482    elif SumQ(u):
3483        k = 0
3484        for i in u.args:
3485            k += NormalizeSumFactors(i)
3486        return k
3487    else:
3488        return u
3489
3490def SignOfFactor(u):
3491    if RationalQ(u) and u < 0 or SumQ(u) and NumericFactor(First(u)) < 0:
3492        return [-1, -u]
3493    elif IntegerPowerQ(u):
3494        if SumQ(u.base) and NumericFactor(First(u.base)) < 0:
3495            return [(-1)**u.exp, (-u.base)**u.exp]
3496    elif ProductQ(u):
3497        k = 1
3498        h = 1
3499        for i in u.args:
3500            k *= SignOfFactor(i)[0]
3501            h *= SignOfFactor(i)[1]
3502        return [k, h]
3503    return [1, u]
3504
3505def NormalizePowerOfLinear(u, x):
3506    v = FactorSquareFree(u)
3507    if PowerQ(v):
3508        if LinearQ(v.base, x) and FreeQ(v.exp, x):
3509            return ExpandToSum(v.base, x)**v.exp
3510
3511    return ExpandToSum(v, x)
3512
3513def SimplifyIntegrand(u, x):
3514    v = NormalizeLeadTermSigns(NormalizeIntegrandAux(Simplify(u), x))
3515    if 5*LeafCount(v) < 4*LeafCount(u):
3516        return v
3517    if v != NormalizeLeadTermSigns(u):
3518        return v
3519    else:
3520        return u
3521
3522def SimplifyTerm(u, x):
3523    v = Simplify(u)
3524    w = Together(v)
3525    if LeafCount(v) < LeafCount(w):
3526        return NormalizeIntegrand(v, x)
3527    else:
3528        return NormalizeIntegrand(w, x)
3529
3530def TogetherSimplify(u):
3531    v = Together(Simplify(Together(u)))
3532    return FixSimplify(v)
3533
3534def SmartSimplify(u):
3535    v = Simplify(u)
3536    w = factor(v)
3537    if LeafCount(w) < LeafCount(v):
3538        v = w
3539    if Not(FalseQ(w == FractionalPowerOfSquareQ(v))) and FractionalPowerSubexpressionQ(u, w, Expand(w)):
3540        v = SubstForExpn(v, w, Expand(w))
3541    else:
3542        v = FactorNumericGcd(v)
3543    return FixSimplify(v)
3544
3545def SubstForExpn(u, v, w):
3546    if u == v:
3547        return w
3548    if AtomQ(u):
3549        return u
3550    else:
3551        k = 0
3552        for i in u.args:
3553            k +=  SubstForExpn(i, v, w)
3554        return k
3555
3556def ExpandToSum(u, *x):
3557    if len(x) == 1:
3558        x = x[0]
3559        expr = 0
3560        if PolyQ(S(u), x):
3561            for t in ExponentList(u, x):
3562                expr += Coeff(u, x, t)*x**t
3563            return expr
3564        if BinomialQ(u, x):
3565            i = BinomialParts(u, x)
3566            expr += i[0] + i[1]*x**i[2]
3567            return expr
3568        if TrinomialQ(u, x):
3569            i = TrinomialParts(u, x)
3570            expr += i[0] + i[1]*x**i[3] + i[2]*x**(2*i[3])
3571            return expr
3572        if GeneralizedBinomialMatchQ(u, x):
3573            i = GeneralizedBinomialParts(u, x)
3574            expr += i[0]*x**i[3] + i[1]*x**i[2]
3575            return expr
3576        if GeneralizedTrinomialMatchQ(u, x):
3577            i = GeneralizedTrinomialParts(u, x)
3578            expr += i[0]*x**i[4] + i[1]*x**i[3] + i[2]*x**(2*i[3]-i[4])
3579            return expr
3580        else:
3581            return Expand(u)
3582    else:
3583        v = x[0]
3584        x = x[1]
3585        w = ExpandToSum(v, x)
3586        r = NonfreeTerms(w, x)
3587        if SumQ(r):
3588            k = u*FreeTerms(w, x)
3589            for i in r.args:
3590                k += MergeMonomials(u*i, x)
3591            return k
3592        else:
3593            return u*FreeTerms(w, x) + MergeMonomials(u*r, x)
3594
3595def UnifySum(u, x):
3596    if SumQ(u):
3597        t = 0
3598        lst = []
3599        for i in u.args:
3600            lst += [i]
3601        for j in UnifyTerms(lst, x):
3602            t += j
3603        return t
3604    else:
3605        return SimplifyTerm(u, x)
3606
3607def UnifyTerms(lst, x):
3608    if lst==[]:
3609        return lst
3610    else:
3611        return UnifyTerm(First(lst), UnifyTerms(Rest(lst), x), x)
3612
3613def UnifyTerm(term, lst, x):
3614    if lst==[]:
3615        return [term]
3616    tmp = Simplify(First(lst)/term)
3617    if FreeQ(tmp, x):
3618        return Prepend(Rest(lst), [(1+tmp)*term])
3619    else:
3620        return Prepend(UnifyTerm(term, Rest(lst), x), [First(lst)])
3621
3622def CalculusQ(u):
3623    return False
3624
3625def FunctionOfInverseLinear(*args):
3626    # (* If u is a function of an inverse linear binomial of the form 1/(a+b*x),
3627    # FunctionOfInverseLinear[u,x] returns the list {a,b}; else it returns False. *)
3628    if len(args) == 2:
3629        u, x = args
3630        return FunctionOfInverseLinear(u, None, x)
3631    u, lst, x = args
3632
3633    if FreeQ(u, x):
3634        return lst
3635    elif u == x:
3636        return False
3637    elif QuotientOfLinearsQ(u, x):
3638        tmp = Drop(QuotientOfLinearsParts(u, x), 2)
3639        if tmp[1] == 0:
3640            return False
3641        elif lst is None:
3642            return tmp
3643        elif ZeroQ(lst[0]*tmp[1] - lst[1]*tmp[0]):
3644            return lst
3645        return False
3646    elif CalculusQ(u):
3647        return False
3648    tmp = lst
3649    for i in u.args:
3650        tmp = FunctionOfInverseLinear(i, tmp, x)
3651        if AtomQ(tmp):
3652            return False
3653    return tmp
3654
3655def PureFunctionOfSinhQ(u, v, x):
3656    # (* If u is a pure function of Sinh[v] and/or Csch[v], PureFunctionOfSinhQ[u,v,x] returns True;
3657    # else it returns False. *)
3658    if AtomQ(u):
3659        return u != x
3660    elif CalculusQ(u):
3661        return False
3662    elif HyperbolicQ(u) and ZeroQ(u.args[0] - v):
3663        return SinhQ(u) or CschQ(u)
3664    for i in u.args:
3665        if Not(PureFunctionOfSinhQ(i, v, x)):
3666            return False
3667    return True
3668
3669def PureFunctionOfTanhQ(u, v , x):
3670    # (* If u is a pure function of Tanh[v] and/or Coth[v], PureFunctionOfTanhQ[u,v,x] returns True;
3671    # else it returns False. *)
3672    if AtomQ(u):
3673        return u != x
3674    elif CalculusQ(u):
3675        return False
3676    elif HyperbolicQ(u) and ZeroQ(u.args[0] - v):
3677        return TanhQ(u) or CothQ(u)
3678    for i in u.args:
3679        if Not(PureFunctionOfTanhQ(i, v, x)):
3680            return False
3681    return True
3682
3683def PureFunctionOfCoshQ(u, v, x):
3684    # (* If u is a pure function of Cosh[v] and/or Sech[v], PureFunctionOfCoshQ[u,v,x] returns True;
3685    # else it returns False. *)
3686    if AtomQ(u):
3687        return u != x
3688    elif CalculusQ(u):
3689        return False
3690    elif HyperbolicQ(u) and ZeroQ(u.args[0] - v):
3691        return CoshQ(u) or SechQ(u)
3692    for i in u.args:
3693        if Not(PureFunctionOfCoshQ(i, v, x)):
3694            return False
3695    return True
3696
3697def IntegerQuotientQ(u, v):
3698    # (* If u/v is an integer, IntegerQuotientQ[u,v] returns True; else it returns False. *)
3699    return IntegerQ(Simplify(u/v))
3700
3701def OddQuotientQ(u, v):
3702    # (* If u/v is odd, OddQuotientQ[u,v] returns True; else it returns False. *)
3703    return OddQ(Simplify(u/v))
3704
3705def EvenQuotientQ(u, v):
3706    # (* If u/v is even, EvenQuotientQ[u,v] returns True; else it returns False. *)
3707    return EvenQ(Simplify(u/v))
3708
3709def FindTrigFactor(func1, func2, u, v, flag):
3710    # (* If func[w]^m is a factor of u where m is odd and w is an integer multiple of v,
3711    # FindTrigFactor[func1,func2,u,v,True] returns the list {w,u/func[w]^n}; else it returns False. *)
3712    # (* If func[w]^m is a factor of u where m is odd and w is an integer multiple of v not equal to v,
3713    # FindTrigFactor[func1,func2,u,v,False] returns the list {w,u/func[w]^n}; else it returns False. *)
3714    if u == 1:
3715        return False
3716    elif (Head(LeadBase(u)) == func1 or Head(LeadBase(u)) == func2) and OddQ(LeadDegree(u)) and IntegerQuotientQ(LeadBase(u).args[0], v) and (flag or NonzeroQ(LeadBase(u).args[0] - v)):
3717        return [LeadBase[u].args[0], RemainingFactors(u)]
3718    lst = FindTrigFactor(func1, func2, RemainingFactors(u), v, flag)
3719    if AtomQ(lst):
3720        return False
3721    return [lst[0], LeadFactor(u)*lst[1]]
3722
3723def FunctionOfSinhQ(u, v, x):
3724    # (* If u is a function of Sinh[v], FunctionOfSinhQ[u,v,x] returns True; else it returns False. *)
3725    if AtomQ(u):
3726        return u != x
3727    elif CalculusQ(u):
3728        return False
3729    elif HyperbolicQ(u) and IntegerQuotientQ(u.args[0], v):
3730        if OddQuotientQ(u.args[0], v):
3731            # (* Basis: If m odd, Sinh[m*v]^n is a function of Sinh[v]. *)
3732            return SinhQ(u) or CschQ(u)
3733        # (* Basis: If m even, Cos[m*v]^n is a function of Sinh[v]. *)
3734        return CoshQ(u) or SechQ(u)
3735    elif IntegerPowerQ(u):
3736        if HyperbolicQ(u.base) and IntegerQuotientQ(u.base.args[0], v):
3737            if EvenQ(u.exp):
3738                # (* Basis: If m integer and n even, Hyper[m*v]^n is a function of Sinh[v]. *)
3739                return True
3740            return FunctionOfSinhQ(u.base, v, x)
3741    elif ProductQ(u):
3742        if CoshQ(u.args[0]) and SinhQ(u.args[1]) and ZeroQ(u.args[0].args[0] - v/2) and ZeroQ(u.args[1].args[0] - v/2):
3743            return FunctionOfSinhQ(Drop(u, 2), v, x)
3744        lst = FindTrigFactor(Sinh, Csch, u, v, False)
3745        if ListQ(lst) and EvenQuotientQ(lst[0], v):
3746            # (* Basis: If m even and n odd, Sinh[m*v]^n == Cosh[v]*u where u is a function of Sinh[v]. *)
3747            return FunctionOfSinhQ(Cosh(v)*lst[1], v, x)
3748        lst = FindTrigFactor(Cosh, Sech, u, v, False)
3749        if ListQ(lst) and OddQuotientQ(lst[0], v):
3750            # (* Basis: If m odd and n odd, Cosh[m*v]^n == Cosh[v]*u where u is a function of Sinh[v]. *)
3751            return FunctionOfSinhQ(Cosh(v)*lst[1], v, x)
3752        lst = FindTrigFactor(Tanh, Coth, u, v, True)
3753        if ListQ(lst):
3754            # (* Basis: If m integer and n odd, Tanh[m*v]^n == Cosh[v]*u where u is a function of Sinh[v]. *)
3755            return FunctionOfSinhQ(Cosh(v)*lst[1], v, x)
3756        return all(FunctionOfSinhQ(i, v, x) for i in u.args)
3757    return all(FunctionOfSinhQ(i, v, x) for i in u.args)
3758
3759def FunctionOfCoshQ(u, v, x):
3760    #(* If u is a function of Cosh[v], FunctionOfCoshQ[u,v,x] returns True; else it returns False. *)
3761    if AtomQ(u):
3762        return u != x
3763    elif CalculusQ(u):
3764        return False
3765    elif HyperbolicQ(u) and IntegerQuotientQ(u.args[0], v):
3766        # (* Basis: If m integer, Cosh[m*v]^n is a function of Cosh[v]. *)
3767        return CoshQ(u) or SechQ(u)
3768    elif IntegerPowerQ(u):
3769        if HyperbolicQ(u.base) and IntegerQuotientQ(u.base.args[0], v):
3770            if EvenQ(u.exp):
3771                # (* Basis: If m integer and n even, Hyper[m*v]^n is a function of Cosh[v]. *)
3772                return True
3773            return FunctionOfCoshQ(u.base, v, x)
3774    elif ProductQ(u):
3775        lst = FindTrigFactor(Sinh, Csch, u, v, False)
3776        if ListQ(lst):
3777            # (* Basis: If m integer and n odd, Sinh[m*v]^n == Sinh[v]*u where u is a function of Cosh[v]. *)
3778            return FunctionOfCoshQ(Sinh(v)*lst[1], v, x)
3779        lst = FindTrigFactor(Tanh, Coth, u, v, True)
3780        if ListQ(lst):
3781            # (* Basis: If m integer and n odd, Tanh[m*v]^n == Sinh[v]*u where u is a function of Cosh[v]. *)
3782            return FunctionOfCoshQ(Sinh(v)*lst[1], v, x)
3783        return all(FunctionOfCoshQ(i, v, x) for i in u.args)
3784    return all(FunctionOfCoshQ(i, v, x) for i in u.args)
3785
3786def OddHyperbolicPowerQ(u, v, x):
3787    if SinhQ(u) or CoshQ(u) or SechQ(u) or CschQ(u):
3788        return OddQuotientQ(u.args[0], v)
3789    if PowerQ(u):
3790        return OddQ(u.exp) and OddHyperbolicPowerQ(u.base, v, x)
3791    if ProductQ(u):
3792        if Not(EqQ(FreeFactors(u, x), 1)):
3793            return OddHyperbolicPowerQ(NonfreeFactors(u, x), v, x)
3794        lst = []
3795        for i in u.args:
3796            if Not(FunctionOfTanhQ(i, v, x)):
3797                lst.append(i)
3798        if lst == []:
3799            return True
3800        return Length(lst)==1 and OddHyperbolicPowerQ(lst[0], v, x)
3801    if SumQ(u):
3802        return all(OddHyperbolicPowerQ(i, v, x) for i in u.args)
3803    return False
3804
3805def FunctionOfTanhQ(u, v, x):
3806    #(* If u is a function of the form f[Tanh[v],Coth[v]] where f is independent of x,
3807    # FunctionOfTanhQ[u,v,x] returns True; else it returns False. *)
3808    if AtomQ(u):
3809        return u != x
3810    elif CalculusQ(u):
3811        return False
3812    elif HyperbolicQ(u) and IntegerQuotientQ(u.args[0], v):
3813        return TanhQ(u) or CothQ(u) or EvenQuotientQ(u.args[0], v)
3814    elif PowerQ(u):
3815        if EvenQ(u.exp) and HyperbolicQ(u.base) and IntegerQuotientQ(u.base.args[0], v):
3816            return True
3817        elif EvenQ(u.args[1]) and SumQ(u.args[0]):
3818            return FunctionOfTanhQ(Expand(u.args[0]**2, v, x))
3819    if ProductQ(u):
3820        lst = []
3821        for i in u.args:
3822            if Not(FunctionOfTanhQ(i, v, x)):
3823                lst.append(i)
3824        if lst == []:
3825            return True
3826        return Length(lst)==2 and OddHyperbolicPowerQ(lst[0], v, x) and OddHyperbolicPowerQ(lst[1], v, x)
3827    return all(FunctionOfTanhQ(i, v, x) for i in u.args)
3828
3829def FunctionOfTanhWeight(u, v, x):
3830    """
3831    u is a function of the form f(tanh(v), coth(v)) where f is independent of x.
3832    FunctionOfTanhWeight(u, v, x) returns a nonnegative number if u is best considered a function of tanh(v), else it returns a negative number.
3833
3834    Examples
3835    ========
3836
3837    >>> from sympy import sinh, log, tanh
3838    >>> from sympy.abc import x
3839    >>> from sympy.integrals.rubi.utility_function import FunctionOfTanhWeight
3840    >>> FunctionOfTanhWeight(x, log(x), x)
3841    0
3842    >>> FunctionOfTanhWeight(sinh(log(x)), log(x), x)
3843    0
3844    >>> FunctionOfTanhWeight(tanh(log(x)), log(x), x)
3845    1
3846
3847    """
3848    if AtomQ(u):
3849        return S(0)
3850    elif CalculusQ(u):
3851        return S(0)
3852    elif HyperbolicQ(u) and IntegerQuotientQ(u.args[0], v):
3853        if TanhQ(u) and ZeroQ(u.args[0] - v):
3854            return S(1)
3855        elif CothQ(u) and ZeroQ(u.args[0] - v):
3856            return S(-1)
3857        return S(0)
3858    elif PowerQ(u):
3859        if EvenQ(u.exp) and HyperbolicQ(u.base) and IntegerQuotientQ(u.base.args[0], v):
3860            if TanhQ(u.base) or CoshQ(u.base) or SechQ(u.base):
3861                return S(1)
3862            return S(-1)
3863    if ProductQ(u):
3864        if all(FunctionOfTanhQ(i, v, x) for i in u.args):
3865            return Add(*[FunctionOfTanhWeight(i, v, x) for i in u.args])
3866        return S(0)
3867    return Add(*[FunctionOfTanhWeight(i, v, x) for i in u.args])
3868
3869def FunctionOfHyperbolicQ(u, v, x):
3870    # (* If u (x) is equivalent to a function of the form f (Sinh[v],Cosh[v],Tanh[v],Coth[v],Sech[v],Csch[v])
3871    # where f is independent of x, FunctionOfHyperbolicQ[u,v,x] returns True; else it returns False. *)
3872    if AtomQ(u):
3873        return u != x
3874    elif CalculusQ(u):
3875        return False
3876    elif HyperbolicQ(u) and IntegerQuotientQ(u.args[0], v):
3877        return True
3878    return all(FunctionOfHyperbolicQ(i, v, x) for i in u.args)
3879
3880def SmartNumerator(expr):
3881    if PowerQ(expr):
3882        n = expr.exp
3883        u = expr.base
3884        if RationalQ(n) and n < 0:
3885            return SmartDenominator(u**(-n))
3886    elif ProductQ(expr):
3887        return Mul(*[SmartNumerator(i) for i in expr.args])
3888    return Numerator(expr)
3889
3890def SmartDenominator(expr):
3891    if PowerQ(expr):
3892        u = expr.base
3893        n = expr.exp
3894        if RationalQ(n) and n < 0:
3895            return SmartNumerator(u**(-n))
3896    elif ProductQ(expr):
3897        return Mul(*[SmartDenominator(i) for i in expr.args])
3898    return Denominator(expr)
3899
3900def ActivateTrig(u):
3901    return u
3902
3903def ExpandTrig(*args):
3904    if len(args) == 2:
3905        u, x = args
3906        return ActivateTrig(ExpandIntegrand(u, x))
3907    u, v, x = args
3908    w = ExpandTrig(v, x)
3909    z = ActivateTrig(u)
3910    if SumQ(w):
3911        return w.func(*[z*i for i in w.args])
3912    return z*w
3913
3914def TrigExpand(u):
3915    return expand_trig(u)
3916
3917# SubstForTrig[u_,sin_,cos_,v_,x_] :=
3918#   If[AtomQ[u],
3919#     u,
3920#   If[TrigQ[u] && IntegerQuotientQ[u[[1]],v],
3921#     If[u[[1]]===v || ZeroQ[u[[1]]-v],
3922#       If[SinQ[u],
3923#         sin,
3924#       If[CosQ[u],
3925#         cos,
3926#       If[TanQ[u],
3927#         sin/cos,
3928#       If[CotQ[u],
3929#         cos/sin,
3930#       If[SecQ[u],
3931#         1/cos,
3932#       1/sin]]]]],
3933#     Map[Function[SubstForTrig[#,sin,cos,v,x]],
3934#             ReplaceAll[TrigExpand[Head[u][Simplify[u[[1]]/v]*x]],x->v]]],
3935#   If[ProductQ[u] && CosQ[u[[1]]] && SinQ[u[[2]]] && ZeroQ[u[[1,1]]-v/2] && ZeroQ[u[[2,1]]-v/2],
3936#     sin/2*SubstForTrig[Drop[u,2],sin,cos,v,x],
3937#   Map[Function[SubstForTrig[#,sin,cos,v,x]],u]]]]
3938
3939
3940def SubstForTrig(u, sin_ , cos_, v, x):
3941    # (* u (v) is an expression of the form f (Sin[v],Cos[v],Tan[v],Cot[v],Sec[v],Csc[v]). *)
3942    # (* SubstForTrig[u,sin,cos,v,x] returns the expression f (sin,cos,sin/cos,cos/sin,1/cos,1/sin). *)
3943    if AtomQ(u):
3944        return u
3945    elif TrigQ(u) and IntegerQuotientQ(u.args[0], v):
3946        if u.args[0] == v or ZeroQ(u.args[0] - v):
3947            if SinQ(u):
3948                return sin_
3949            elif CosQ(u):
3950                return cos_
3951            elif TanQ(u):
3952                return sin_/cos_
3953            elif CotQ(u):
3954                return cos_/sin_
3955            elif SecQ(u):
3956                return 1/cos_
3957            return 1/sin_
3958        r = ReplaceAll(TrigExpand(Head(u)(Simplify(u.args[0]/v*x))), {x: v})
3959        return r.func(*[SubstForTrig(i, sin_, cos_, v, x) for i in r.args])
3960    if ProductQ(u) and CosQ(u.args[0]) and SinQ(u.args[1]) and ZeroQ(u.args[0].args[0] - v/2) and ZeroQ(u.args[1].args[0] - v/2):
3961        return sin(x)/2*SubstForTrig(Drop(u, 2), sin_, cos_, v, x)
3962    return u.func(*[SubstForTrig(i, sin_, cos_, v, x) for i in u.args])
3963
3964def SubstForHyperbolic(u, sinh_, cosh_, v, x):
3965    # (* u (v) is an expression of the form f (Sinh[v],Cosh[v],Tanh[v],Coth[v],Sech[v],Csch[v]). *)
3966    # (* SubstForHyperbolic[u,sinh,cosh,v,x] returns the expression
3967    # f (sinh,cosh,sinh/cosh,cosh/sinh,1/cosh,1/sinh). *)
3968    if AtomQ(u):
3969        return u
3970    elif HyperbolicQ(u) and IntegerQuotientQ(u.args[0], v):
3971        if u.args[0] == v or ZeroQ(u.args[0] - v):
3972            if SinhQ(u):
3973                return sinh_
3974            elif CoshQ(u):
3975                return cosh_
3976            elif TanhQ(u):
3977                return sinh_/cosh_
3978            elif CothQ(u):
3979                return cosh_/sinh_
3980            if SechQ(u):
3981                return 1/cosh_
3982            return 1/sinh_
3983        r = ReplaceAll(TrigExpand(Head(u)(Simplify(u.args[0]/v)*x)), {x: v})
3984        return r.func(*[SubstForHyperbolic(i, sinh_, cosh_, v, x) for i in r.args])
3985    elif ProductQ(u) and CoshQ(u.args[0]) and SinhQ(u.args[1]) and ZeroQ(u.args[0].args[0] - v/2) and ZeroQ(u.args[1].args[0] - v/2):
3986        return sinh(x)/2*SubstForHyperbolic(Drop(u, 2), sinh_, cosh_, v, x)
3987    return u.func(*[SubstForHyperbolic(i, sinh_, cosh_, v, x) for i in u.args])
3988
3989def InertTrigFreeQ(u):
3990    return FreeQ(u, sin) and FreeQ(u, cos) and FreeQ(u, tan) and FreeQ(u, cot) and FreeQ(u, sec) and FreeQ(u, csc)
3991
3992def LCM(a, b):
3993    return lcm(a, b)
3994
3995def SubstForFractionalPowerOfLinear(u, x):
3996    # (* If u has a subexpression of the form (a+b*x)^(m/n) where m and n>1 are integers,
3997    # SubstForFractionalPowerOfLinear[u,x] returns the list {v,n,a+b*x,1/b} where v is u
3998    # with subexpressions of the form (a+b*x)^(m/n) replaced by x^m and x replaced
3999    # by -a/b+x^n/b, and all times x^(n-1); else it returns False. *)
4000    lst = FractionalPowerOfLinear(u, S(1), False, x)
4001    if AtomQ(lst) or FalseQ(lst[1]):
4002        return False
4003    n = lst[0]
4004    a = Coefficient(lst[1], x, 0)
4005    b = Coefficient(lst[1], x, 1)
4006    tmp = Simplify(x**(n-1)*SubstForFractionalPower(u, lst[1], n, -a/b + x**n/b, x))
4007    return [NonfreeFactors(tmp, x), n, lst[1], FreeFactors(tmp, x)/b]
4008
4009def FractionalPowerOfLinear(u, n, v, x):
4010    # If u has a subexpression of the form (a + b*x)**(m/n), FractionalPowerOfLinear(u, 1, False, x) returns [n, a + b*x], else it returns False.
4011    if AtomQ(u) or FreeQ(u, x):
4012        return [n, v]
4013    elif CalculusQ(u):
4014        return False
4015    elif FractionalPowerQ(u):
4016        if LinearQ(u.base, x) and (FalseQ(v) or ZeroQ(u.base - v)):
4017            return [LCM(Denominator(u.exp), n), u.base]
4018    lst = [n, v]
4019    for i in u.args:
4020        lst = FractionalPowerOfLinear(i, lst[0], lst[1], x)
4021        if AtomQ(lst):
4022            return False
4023    return lst
4024
4025def InverseFunctionOfLinear(u, x):
4026    # (* If u has a subexpression of the form g[a+b*x] where g is an inverse function,
4027    # InverseFunctionOfLinear[u,x] returns g[a+b*x]; else it returns False. *)
4028    if AtomQ(u) or CalculusQ(u) or FreeQ(u, x):
4029        return False
4030    elif InverseFunctionQ(u) and LinearQ(u.args[0], x):
4031        return u
4032    for i in u.args:
4033        tmp = InverseFunctionOfLinear(i, x)
4034        if Not(AtomQ(tmp)):
4035            return tmp
4036    return False
4037
4038def InertTrigQ(*args):
4039    if len(args) == 1:
4040        f = args[0]
4041        l = [sin,cos,tan,cot,sec,csc]
4042        return any(Head(f) == i for i in l)
4043    elif len(args) == 2:
4044        f, g = args
4045        if f == g:
4046            return InertTrigQ(f)
4047        return InertReciprocalQ(f, g) or InertReciprocalQ(g, f)
4048    else:
4049        f, g, h = args
4050        return InertTrigQ(g, f) and InertTrigQ(g, h)
4051
4052def InertReciprocalQ(f, g):
4053    return (f.func == sin and g.func == csc) or (f.func == cos and g.func == sec) or (f.func == tan and g.func == cot)
4054
4055def DeactivateTrig(u, x):
4056    # (* u is a function of trig functions of a linear function of x. *)
4057    # (* DeactivateTrig[u,x] returns u with the trig functions replaced with inert trig functions. *)
4058    return FixInertTrigFunction(DeactivateTrigAux(u, x), x)
4059
4060def FixInertTrigFunction(u, x):
4061    return u
4062
4063def DeactivateTrigAux(u, x):
4064    if AtomQ(u):
4065        return u
4066    elif TrigQ(u) and LinearQ(u.args[0], x):
4067        v = ExpandToSum(u.args[0], x)
4068        if SinQ(u):
4069            return sin(v)
4070        elif CosQ(u):
4071            return cos(v)
4072        elif TanQ(u):
4073            return tan(u)
4074        elif CotQ(u):
4075            return cot(v)
4076        elif SecQ(u):
4077            return sec(v)
4078        return csc(v)
4079    elif HyperbolicQ(u) and LinearQ(u.args[0], x):
4080        v = ExpandToSum(I*u.args[0], x)
4081        if SinhQ(u):
4082            return -I*sin(v)
4083        elif CoshQ(u):
4084            return cos(v)
4085        elif TanhQ(u):
4086            return -I*tan(v)
4087        elif CothQ(u):
4088            I*cot(v)
4089        elif SechQ(u):
4090            return sec(v)
4091        return I*csc(v)
4092    return u.func(*[DeactivateTrigAux(i, x) for i in u.args])
4093
4094def PowerOfInertTrigSumQ(u, func, x):
4095    p_ = Wild('p', exclude=[x])
4096    q_ = Wild('q', exclude=[x])
4097    a_ = Wild('a', exclude=[x])
4098    b_ = Wild('b', exclude=[x])
4099    c_ = Wild('c', exclude=[x])
4100    d_ = Wild('d', exclude=[x])
4101    n_ = Wild('n', exclude=[x])
4102    w_ = Wild('w')
4103
4104    pattern = (a_ + b_*(c_*func(w_))**p_)**n_
4105    match = u.match(pattern)
4106    if match:
4107        keys = [a_, b_, c_, n_, p_, w_]
4108        if len(keys) == len(match):
4109            return True
4110
4111    pattern = (a_ + b_*(d_*func(w_))**p_ + c_*(d_*func(w_))**q_)**n_
4112    match = u.match(pattern)
4113    if match:
4114        keys = [a_, b_, c_, d_, n_, p_, q_, w_]
4115        if len(keys) == len(match):
4116            return True
4117    return False
4118
4119def PiecewiseLinearQ(*args):
4120    # (* If the derivative of u wrt x is a constant wrt x, PiecewiseLinearQ[u,x] returns True;
4121    # else it returns False. *)
4122    if len(args) == 3:
4123        u, v, x = args
4124        return PiecewiseLinearQ(u, x) and PiecewiseLinearQ(v, x)
4125
4126    u, x = args
4127    if LinearQ(u, x):
4128        return True
4129
4130    c_ = Wild('c', exclude=[x])
4131    F_ = Wild('F', exclude=[x])
4132    v_ = Wild('v')
4133    match = u.match(Log(c_*F_**v_))
4134    if match:
4135        if len(match) == 3:
4136            if LinearQ(match[v_], x):
4137                return True
4138    try:
4139        F = type(u)
4140        G = type(u.args[0])
4141        v = u.args[0].args[0]
4142        if LinearQ(v, x):
4143            if MemberQ([[atanh, tanh], [atanh, coth], [acoth, coth], [acoth, tanh], [atan, tan], [atan, cot], [acot, cot], [acot, tan]], [F, G]):
4144                return True
4145    except:
4146        pass
4147    return False
4148
4149def KnownTrigIntegrandQ(lst, u, x):
4150    if u == 1:
4151        return True
4152    a_ = Wild('a', exclude=[x])
4153    b_ = Wild('b', exclude=[x, 0])
4154    func_ = WildFunction('func')
4155    m_ = Wild('m', exclude=[x])
4156    A_ = Wild('A', exclude=[x])
4157    B_ = Wild('B', exclude=[x, 0])
4158    C_ = Wild('C', exclude=[x, 0])
4159
4160    match = u.match((a_ + b_*func_)**m_)
4161    if match:
4162        func = match[func_]
4163        if LinearQ(func.args[0], x) and MemberQ(lst, func.func):
4164            return True
4165
4166    match = u.match((a_ + b_*func_)**m_*(A_ + B_*func_))
4167    if match:
4168        func = match[func_]
4169        if LinearQ(func.args[0], x) and MemberQ(lst, func.func):
4170            return True
4171
4172    match = u.match(A_ + C_*func_**2)
4173    if match:
4174        func = match[func_]
4175        if LinearQ(func.args[0], x) and MemberQ(lst, func.func):
4176            return True
4177
4178    match = u.match(A_ + B_*func_ + C_*func_**2)
4179    if match:
4180        func = match[func_]
4181        if LinearQ(func.args[0], x) and MemberQ(lst, func.func):
4182            return True
4183
4184    match = u.match((a_ + b_*func_)**m_*(A_ + C_*func_**2))
4185    if match:
4186        func = match[func_]
4187        if LinearQ(func.args[0], x) and MemberQ(lst, func.func):
4188            return True
4189
4190    match = u.match((a_ + b_*func_)**m_*(A_ + B_*func_ + C_*func_**2))
4191    if match:
4192        func = match[func_]
4193        if LinearQ(func.args[0], x) and MemberQ(lst, func.func):
4194            return True
4195
4196    return False
4197
4198def KnownSineIntegrandQ(u, x):
4199    return KnownTrigIntegrandQ([sin, cos], u, x)
4200
4201def KnownTangentIntegrandQ(u, x):
4202    return KnownTrigIntegrandQ([tan], u, x)
4203
4204def KnownCotangentIntegrandQ(u, x):
4205    return KnownTrigIntegrandQ([cot], u, x)
4206
4207def KnownSecantIntegrandQ(u, x):
4208    return KnownTrigIntegrandQ([sec, csc], u, x)
4209
4210def TryPureTanSubst(u, x):
4211    a_ = Wild('a', exclude=[x])
4212    b_ = Wild('b', exclude=[x])
4213    c_ = Wild('c', exclude=[x])
4214    G_ = Wild('G')
4215
4216    F = u.func
4217    try:
4218        if MemberQ([atan, acot, atanh, acoth], F):
4219            match = u.args[0].match(c_*(a_ + b_*G_))
4220            if match:
4221                if len(match) == 4:
4222                    G = match[G_]
4223                    if MemberQ([tan, cot, tanh, coth], G.func):
4224                        if LinearQ(G.args[0], x):
4225                            return True
4226    except:
4227        pass
4228
4229    return False
4230
4231def TryTanhSubst(u, x):
4232    if LogQ(u):
4233        return False
4234    elif not FalseQ(FunctionOfLinear(u, x)):
4235        return False
4236
4237    a_ = Wild('a', exclude=[x])
4238    m_ = Wild('m', exclude=[x])
4239    p_ = Wild('p', exclude=[x])
4240    r_, s_, t_, n_, b_, f_, g_ = map(Wild, 'rstnbfg')
4241
4242    match = u.match(r_*(s_ + t_)**n_)
4243    if match:
4244        if len(match) == 4:
4245            r, s, t, n = [match[i] for i in [r_, s_, t_, n_]]
4246            if IntegerQ(n) and PositiveQ(n):
4247                return False
4248
4249    match = u.match(1/(a_ + b_*f_**n_))
4250    if match:
4251        if len(match) == 4:
4252            a, b, f, n = [match[i] for i in [a_, b_, f_, n_]]
4253            if SinhCoshQ(f) and IntegerQ(n) and n > 2:
4254                return False
4255
4256    match = u.match(f_*g_)
4257    if match:
4258        if len(match) == 2:
4259            f, g = match[f_], match[g_]
4260            if SinhCoshQ(f) and SinhCoshQ(g):
4261                if IntegersQ(f.args[0]/x, g.args[0]/x):
4262                    return False
4263
4264    match = u.match(r_*(a_*s_**m_)**p_)
4265    if match:
4266        if len(match) == 5:
4267            r, a, s, m, p = [match[i] for i in [r_, a_, s_, m_, p_]]
4268            if Not(m==2 and (s == Sech(x) or s == Csch(x))):
4269                return False
4270
4271    if u != ExpandIntegrand(u, x):
4272        return False
4273
4274    return True
4275
4276def TryPureTanhSubst(u, x):
4277    F = u.func
4278    a_ = Wild('a', exclude=[x])
4279    G_ = Wild('G')
4280
4281    if F == sym_log:
4282        return False
4283
4284    match = u.args[0].match(a_*G_)
4285    if match and len(match) == 2:
4286        G = match[G_].func
4287        if MemberQ([atanh, acoth], F) and MemberQ([tanh, coth], G):
4288            return False
4289
4290    if u != ExpandIntegrand(u, x):
4291        return False
4292
4293    return True
4294
4295def AbsurdNumberGCD(*seq):
4296    # (* m, n, ... must be absurd numbers.  AbsurdNumberGCD[m,n,...] returns the gcd of m, n, ... *)
4297    lst = list(seq)
4298    if Length(lst) == 1:
4299        return First(lst)
4300    return AbsurdNumberGCDList(FactorAbsurdNumber(First(lst)), FactorAbsurdNumber(AbsurdNumberGCD(*Rest(lst))))
4301
4302def AbsurdNumberGCDList(lst1, lst2):
4303    # (* lst1 and lst2 must be absurd number prime factorization lists. *)
4304    # (* AbsurdNumberGCDList[lst1,lst2] returns the gcd of the absurd numbers represented by lst1 and lst2. *)
4305    if lst1 == []:
4306        return Mul(*[i[0]**Min(i[1],0) for i in lst2])
4307    elif lst2 == []:
4308        return Mul(*[i[0]**Min(i[1],0) for i in lst1])
4309    elif lst1[0][0] == lst2[0][0]:
4310        if lst1[0][1] <= lst2[0][1]:
4311            return lst1[0][0]**lst1[0][1]*AbsurdNumberGCDList(Rest(lst1), Rest(lst2))
4312        return lst1[0][0]**lst2[0][1]*AbsurdNumberGCDList(Rest(lst1), Rest(lst2))
4313    elif lst1[0][0] < lst2[0][0]:
4314        if lst1[0][1] < 0:
4315            return lst1[0][0]**lst1[0][1]*AbsurdNumberGCDList(Rest(lst1), lst2)
4316        return AbsurdNumberGCDList(Rest(lst1), lst2)
4317    elif lst2[0][1] < 0:
4318        return lst2[0][0]**lst2[0][1]*AbsurdNumberGCDList(lst1, Rest(lst2))
4319    return AbsurdNumberGCDList(lst1, Rest(lst2))
4320
4321def ExpandTrigExpand(u, F, v, m, n, x):
4322    w = Expand(TrigExpand(F.xreplace({x: n*x}))**m).xreplace({x: v})
4323    if SumQ(w):
4324        t = 0
4325        for i in w.args:
4326            t += u*i
4327        return t
4328    else:
4329        return u*w
4330
4331def ExpandTrigReduce(*args):
4332    if len(args) == 3:
4333        u = args[0]
4334        v = args[1]
4335        x = args[2]
4336        w = ExpandTrigReduce(v, x)
4337        if SumQ(w):
4338            t = 0
4339            for i in w.args:
4340                t += u*i
4341            return t
4342        else:
4343            return u*w
4344    else:
4345        u = args[0]
4346        x = args[1]
4347        return ExpandTrigReduceAux(u, x)
4348
4349def ExpandTrigReduceAux(u, x):
4350    v = TrigReduce(u).expand()
4351    if SumQ(v):
4352        t = 0
4353        for i in v.args:
4354            t += NormalizeTrig(i, x)
4355        return t
4356    return NormalizeTrig(v, x)
4357
4358def NormalizeTrig(v, x):
4359    a = Wild('a', exclude=[x])
4360    n = Wild('n', exclude=[x, 0])
4361    F = Wild('F')
4362    expr = a*F**n
4363    M = v.match(expr)
4364    if M and len(M[F].args) == 1 and PolynomialQ(M[F].args[0], x) and Exponent(M[F].args[0], x) > 0:
4365        u = M[F].args[0]
4366        return M[a]*M[F].xreplace({u: ExpandToSum(u, x)})**M[n]
4367    else:
4368        return v
4369#=================================
4370def TrigToExp(expr):
4371    ex = expr.rewrite(sin, sym_exp).rewrite(cos, sym_exp).rewrite(tan, sym_exp).rewrite(sec, sym_exp).rewrite(csc, sym_exp).rewrite(cot, sym_exp)
4372    return ex.replace(sym_exp, rubi_exp)
4373
4374def ExpandTrigToExp(u, *args):
4375    if len(args) == 1:
4376        x = args[0]
4377        return ExpandTrigToExp(1, u, x)
4378    else:
4379        v = args[0]
4380        x = args[1]
4381        w = TrigToExp(v)
4382        k = 0
4383        if SumQ(w):
4384            for i in w.args:
4385                k += SimplifyIntegrand(u*i, x)
4386            w = k
4387        else:
4388            w = SimplifyIntegrand(u*w, x)
4389        return ExpandIntegrand(FreeFactors(w, x), NonfreeFactors(w, x),x)
4390#======================================
4391def TrigReduce(i):
4392    """
4393    TrigReduce(expr) rewrites products and powers of trigonometric functions in expr in terms of trigonometric functions with combined arguments.
4394
4395    Examples
4396    ========
4397
4398    >>> from sympy import sin, cos
4399    >>> from sympy.integrals.rubi.utility_function import TrigReduce
4400    >>> from sympy.abc import x
4401    >>> TrigReduce(cos(x)**2)
4402    cos(2*x)/2 + 1/2
4403    >>> TrigReduce(cos(x)**2*sin(x))
4404    sin(x)/4 + sin(3*x)/4
4405    >>> TrigReduce(cos(x)**2+sin(x))
4406    sin(x) + cos(2*x)/2 + 1/2
4407
4408    """
4409    if SumQ(i):
4410        t = 0
4411        for k in i.args:
4412            t += TrigReduce(k)
4413        return t
4414    if ProductQ(i):
4415        if any(PowerQ(k) for k in i.args):
4416            if (i.rewrite((sin, sinh), sym_exp).rewrite((cos, cosh), sym_exp).expand().rewrite(sym_exp, sin)).has(I, cosh, sinh):
4417                return i.rewrite((sin, sinh), sym_exp).rewrite((cos, cosh), sym_exp).expand().rewrite(sym_exp, sin).simplify()
4418            else:
4419                return i.rewrite((sin, sinh), sym_exp).rewrite((cos, cosh), sym_exp).expand().rewrite(sym_exp, sin)
4420        else:
4421            a = Wild('a')
4422            b = Wild('b')
4423            v = Wild('v')
4424            Match = i.match(v*sin(a)*cos(b))
4425            if Match:
4426                a = Match[a]
4427                b = Match[b]
4428                v = Match[v]
4429                return i.subs(v*sin(a)*cos(b), v*S(1)/2*(sin(a + b) + sin(a - b)))
4430            Match = i.match(v*sin(a)*sin(b))
4431            if Match:
4432                a = Match[a]
4433                b = Match[b]
4434                v = Match[v]
4435                return i.subs(v*sin(a)*sin(b), v*S(1)/2*cos(a - b) - cos(a + b))
4436            Match = i.match(v*cos(a)*cos(b))
4437            if Match:
4438                a = Match[a]
4439                b = Match[b]
4440                v = Match[v]
4441                return i.subs(v*cos(a)*cos(b), v*S(1)/2*cos(a + b) + cos(a - b))
4442            Match = i.match(v*sinh(a)*cosh(b))
4443            if Match:
4444                a = Match[a]
4445                b = Match[b]
4446                v = Match[v]
4447                return i.subs(v*sinh(a)*cosh(b), v*S(1)/2*(sinh(a + b) + sinh(a - b)))
4448            Match = i.match(v*sinh(a)*sinh(b))
4449            if Match:
4450                a = Match[a]
4451                b = Match[b]
4452                v = Match[v]
4453                return i.subs(v*sinh(a)*sinh(b), v*S(1)/2*cosh(a - b) - cosh(a + b))
4454            Match = i.match(v*cosh(a)*cosh(b))
4455            if Match:
4456                a = Match[a]
4457                b = Match[b]
4458                v = Match[v]
4459                return i.subs(v*cosh(a)*cosh(b), v*S(1)/2*cosh(a + b) + cosh(a - b))
4460
4461    if PowerQ(i):
4462        if i.has(sin, sinh):
4463            if (i.rewrite((sin, sinh), sym_exp).expand().rewrite(sym_exp, sin)).has(I, cosh, sinh):
4464                return i.rewrite((sin, sinh), sym_exp).expand().rewrite(sym_exp, sin).simplify()
4465            else:
4466                return i.rewrite((sin, sinh), sym_exp).expand().rewrite(sym_exp, sin)
4467        if i.has(cos, cosh):
4468            if (i.rewrite((cos, cosh), sym_exp).expand().rewrite(sym_exp, cos)).has(I, cosh, sinh):
4469                return i.rewrite((cos, cosh), sym_exp).expand().rewrite(sym_exp, cos).simplify()
4470            else:
4471                return i.rewrite((cos, cosh), sym_exp).expand().rewrite(sym_exp, cos)
4472    return i
4473
4474def FunctionOfTrig(u, *args):
4475    # If u is a function of trig functions of v where v is a linear function of x,
4476    # FunctionOfTrig[u,x] returns v; else it returns False.
4477    if len(args) == 1:
4478        x = args[0]
4479        v = FunctionOfTrig(u, None, x)
4480        if v:
4481            return v
4482        else:
4483            return False
4484    else:
4485        v, x = args
4486        if AtomQ(u):
4487            if u == x:
4488                return False
4489            else:
4490                return v
4491        if TrigQ(u) and LinearQ(u.args[0], x):
4492            if v is None:
4493                return u.args[0]
4494            else:
4495                a = Coefficient(v, x, 0)
4496                b = Coefficient(v, x, 1)
4497                c = Coefficient(u.args[0], x, 0)
4498                d = Coefficient(u.args[0], x, 1)
4499                if ZeroQ(a*d - b*c) and RationalQ(b/d):
4500                    return a/Numerator(b/d) + b*x/Numerator(b/d)
4501                else:
4502                    return False
4503        if HyperbolicQ(u) and LinearQ(u.args[0], x):
4504            if v is None:
4505                return I*u.args[0]
4506            a = Coefficient(v, x, 0)
4507            b = Coefficient(v, x, 1)
4508            c = I*Coefficient(u.args[0], x, 0)
4509            d = I*Coefficient(u.args[0], x, 1)
4510            if ZeroQ(a*d - b*c) and RationalQ(b/d):
4511                return a/Numerator(b/d) + b*x/Numerator(b/d)
4512            else:
4513                return False
4514        if CalculusQ(u):
4515            return False
4516        else:
4517            w = v
4518            for i in u.args:
4519                w = FunctionOfTrig(i, w, x)
4520                if FalseQ(w):
4521                    return False
4522            return w
4523
4524def AlgebraicTrigFunctionQ(u, x):
4525    # If u is algebraic function of trig functions, AlgebraicTrigFunctionQ(u,x) returns True; else it returns False.
4526    if AtomQ(u):
4527        return True
4528    elif TrigQ(u) and LinearQ(u.args[0], x):
4529        return True
4530    elif HyperbolicQ(u) and LinearQ(u.args[0], x):
4531        return True
4532    elif PowerQ(u):
4533        if FreeQ(u.exp, x):
4534            return AlgebraicTrigFunctionQ(u.base, x)
4535    elif ProductQ(u) or SumQ(u):
4536        for i in u.args:
4537            if not AlgebraicTrigFunctionQ(i, x):
4538                return False
4539        return True
4540
4541    return False
4542
4543def FunctionOfHyperbolic(u, *x):
4544    # If u is a function of hyperbolic trig functions of v where v is linear in x,
4545    # FunctionOfHyperbolic(u,x) returns v; else it returns False.
4546    if len(x) == 1:
4547        x = x[0]
4548        v = FunctionOfHyperbolic(u, None, x)
4549        if v is None:
4550            return False
4551        else:
4552            return v
4553    else:
4554        v = x[0]
4555        x = x[1]
4556        if AtomQ(u):
4557            if u == x:
4558                return False
4559            return v
4560        if HyperbolicQ(u) and LinearQ(u.args[0], x):
4561            if v is None:
4562                return u.args[0]
4563            a = Coefficient(v, x, 0)
4564            b = Coefficient(v, x, 1)
4565            c = Coefficient(u.args[0], x, 0)
4566            d = Coefficient(u.args[0], x, 1)
4567            if ZeroQ(a*d - b*c) and RationalQ(b/d):
4568                return a/Numerator(b/d) + b*x/Numerator(b/d)
4569            else:
4570                return False
4571        if CalculusQ(u):
4572            return False
4573        w = v
4574        for i in u.args:
4575            if w == FunctionOfHyperbolic(i, w, x):
4576                return False
4577        return w
4578
4579def FunctionOfQ(v, u, x, PureFlag=False):
4580    # v is a function of x. If u is a function of v,  FunctionOfQ(v, u, x) returns True; else it returns False. *)
4581    if FreeQ(u, x):
4582        return False
4583    elif AtomQ(v):
4584        return True
4585    elif ProductQ(v) and Not(EqQ(FreeFactors(v, x), 1)):
4586        return FunctionOfQ(NonfreeFactors(v, x), u, x, PureFlag)
4587    elif PureFlag:
4588        if SinQ(v) or CscQ(v):
4589            return PureFunctionOfSinQ(u, v.args[0], x)
4590        elif CosQ(v) or SecQ(v):
4591            return PureFunctionOfCosQ(u, v.args[0], x)
4592        elif TanQ(v):
4593            return PureFunctionOfTanQ(u, v.args[0], x)
4594        elif CotQ(v):
4595            return PureFunctionOfCotQ(u, v.args[0], x)
4596        elif SinhQ(v) or CschQ(v):
4597            return PureFunctionOfSinhQ(u, v.args[0], x)
4598        elif CoshQ(v) or SechQ(v):
4599            return PureFunctionOfCoshQ(u, v.args[0], x)
4600        elif TanhQ(v):
4601            return PureFunctionOfTanhQ(u, v.args[0], x)
4602        elif CothQ(v):
4603            return PureFunctionOfCothQ(u, v.args[0], x)
4604        else:
4605            return FunctionOfExpnQ(u, v, x) != False
4606    elif SinQ(v) or CscQ(v):
4607        return FunctionOfSinQ(u, v.args[0], x)
4608    elif CosQ(v) or SecQ(v):
4609        return FunctionOfCosQ(u, v.args[0], x)
4610    elif TanQ(v) or CotQ(v):
4611        FunctionOfTanQ(u, v.args[0], x)
4612    elif SinhQ(v) or CschQ(v):
4613        return FunctionOfSinhQ(u, v.args[0], x)
4614    elif CoshQ(v) or SechQ(v):
4615        return FunctionOfCoshQ(u, v.args[0], x)
4616    elif TanhQ(v) or CothQ(v):
4617        return FunctionOfTanhQ(u, v.args[0], x)
4618    return FunctionOfExpnQ(u, v, x) != False
4619
4620
4621
4622def FunctionOfExpnQ(u, v, x):
4623    if u == v:
4624        return 1
4625    if AtomQ(u):
4626        if u == x:
4627            return False
4628        else:
4629            return 0
4630    if CalculusQ(u):
4631        return False
4632    if PowerQ(u):
4633        if FreeQ(u.exp, x):
4634            if ZeroQ(u.base - v):
4635                if IntegerQ(u.exp):
4636                    return u.exp
4637                else:
4638                    return 1
4639            if PowerQ(v):
4640                if FreeQ(v.exp, x) and ZeroQ(u.base-v.base):
4641                    if RationalQ(v.exp):
4642                        if RationalQ(u.exp) and IntegerQ(u.exp/v.exp) and (v.exp>0 or u.exp<0):
4643                            return u.exp/v.exp
4644                        else:
4645                            return False
4646                    if IntegerQ(Simplify(u.exp/v.exp)):
4647                        return Simplify(u.exp/v.exp)
4648                    else:
4649                        return False
4650            return FunctionOfExpnQ(u.base, v, x)
4651    if ProductQ(u) and Not(EqQ(FreeFactors(u, x), 1)):
4652        return FunctionOfExpnQ(NonfreeFactors(u, x), v, x)
4653    if ProductQ(u) and ProductQ(v):
4654        deg1 = FunctionOfExpnQ(First(u), First(v), x)
4655        if deg1==False:
4656            return False
4657        deg2 = FunctionOfExpnQ(Rest(u), Rest(v), x);
4658        if deg1==deg2 and FreeQ(Simplify(u/v^deg1), x):
4659            return deg1
4660        else:
4661            return False
4662    lst = []
4663    for i in u.args:
4664        if FunctionOfExpnQ(i, v, x) is False:
4665            return False
4666        lst.append(FunctionOfExpnQ(i, v, x))
4667    return Apply(GCD, lst)
4668
4669def PureFunctionOfSinQ(u, v, x):
4670    # If u is a pure function of Sin(v) and/or Csc(v), PureFunctionOfSinQ(u, v, x) returns True; else it returns False.
4671    if AtomQ(u):
4672        return u!=x
4673    if CalculusQ(u):
4674        return False
4675    if TrigQ(u) and ZeroQ(u.args[0]-v):
4676        return SinQ(u) or CscQ(u)
4677    for i in u.args:
4678        if Not(PureFunctionOfSinQ(i, v, x)):
4679            return False
4680    return True
4681
4682def PureFunctionOfCosQ(u, v, x):
4683    # If u is a pure function of Cos(v) and/or Sec(v), PureFunctionOfCosQ(u, v, x) returns True; else it returns False.
4684    if AtomQ(u):
4685        return u!=x
4686    if CalculusQ(u):
4687        return False
4688    if TrigQ(u) and ZeroQ(u.args[0]-v):
4689        return CosQ(u) or SecQ(u)
4690    for i in u.args:
4691        if Not(PureFunctionOfCosQ(i, v, x)):
4692            return False
4693    return True
4694
4695def PureFunctionOfTanQ(u, v, x):
4696    # If u is a pure function of Tan(v) and/or Cot(v), PureFunctionOfTanQ(u, v, x) returns True; else it returns False.
4697    if AtomQ(u):
4698        return u!=x
4699    if CalculusQ(u):
4700        return False
4701    if TrigQ(u) and ZeroQ(u.args[0]-v):
4702        return TanQ(u) or CotQ(u)
4703    for i in u.args:
4704        if Not(PureFunctionOfTanQ(i, v, x)):
4705            return False
4706    return True
4707
4708def PureFunctionOfCotQ(u, v, x):
4709    # If u is a pure function of Cot(v), PureFunctionOfCotQ(u, v, x) returns True; else it returns False.
4710    if AtomQ(u):
4711        return u!=x
4712    if CalculusQ(u):
4713        return False
4714    if TrigQ(u) and ZeroQ(u.args[0]-v):
4715        return CotQ(u)
4716    for i in u.args:
4717        if Not(PureFunctionOfCotQ(i, v, x)):
4718            return False
4719    return True
4720
4721def FunctionOfCosQ(u, v, x):
4722    # If u is a function of Cos[v], FunctionOfCosQ[u,v,x] returns True; else it returns False.
4723    if AtomQ(u):
4724        return u != x
4725    elif CalculusQ(u):
4726        return False
4727    elif TrigQ(u) and IntegerQuotientQ(u.args[0], v):
4728        # Basis: If m integer, Cos[m*v]^n is a function of Cos[v]. *)
4729        return CosQ(u) or SecQ(u)
4730    elif IntegerPowerQ(u):
4731        if TrigQ(u.base) and IntegerQuotientQ(u.base.args[0], v):
4732            if EvenQ(u.exp):
4733                # Basis: If m integer and n even, Trig[m*v]^n is a function of Cos[v]. *)
4734                return True
4735            return FunctionOfCosQ(u.base, v, x)
4736    elif ProductQ(u):
4737        lst = FindTrigFactor(sin, csc, u, v, False)
4738        if ListQ(lst):
4739            # (* Basis: If m integer and n odd, Sin[m*v]^n == Sin[v]*u where u is a function of Cos[v]. *)
4740            return FunctionOfCosQ(Sin(v)*lst[1], v, x)
4741        lst = FindTrigFactor(tan, cot, u, v, True)
4742        if ListQ(lst):
4743            # (* Basis: If m integer and n odd, Tan[m*v]^n == Sin[v]*u where u is a function of Cos[v]. *)
4744            return FunctionOfCosQ(Sin(v)*lst[1], v, x)
4745        return all(FunctionOfCosQ(i, v, x) for i in u.args)
4746    return all(FunctionOfCosQ(i, v, x) for i in u.args)
4747
4748def FunctionOfSinQ(u, v, x):
4749    # If u is a function of Sin[v], FunctionOfSinQ[u,v,x] returns True; else it returns False.
4750    if AtomQ(u):
4751        return u != x
4752    elif CalculusQ(u):
4753        return False
4754    elif TrigQ(u) and IntegerQuotientQ(u.args[0], v):
4755        if OddQuotientQ(u.args[0], v):
4756            # Basis: If m odd, Sin[m*v]^n is a function of Sin[v].
4757            return SinQ(u) or CscQ(u)
4758        # Basis: If m even, Cos[m*v]^n is a function of Sin[v].
4759        return CosQ(u) or SecQ(u)
4760    elif IntegerPowerQ(u):
4761        if TrigQ(u.base) and IntegerQuotientQ(u.base.args[0], v):
4762            if EvenQ(u.exp):
4763                # Basis: If m integer and n even, Hyper[m*v]^n is a function of Sin[v].
4764                return True
4765            return FunctionOfSinQ(u.base, v, x)
4766    elif ProductQ(u):
4767        if CosQ(u.args[0]) and SinQ(u.args[1]) and ZeroQ(u.args[0].args[0] - v/2) and ZeroQ(u.args[1].args[0] - v/2):
4768            return FunctionOfSinQ(Drop(u, 2), v, x)
4769        lst = FindTrigFactor(sin, csch, u, v, False)
4770        if ListQ(lst) and EvenQuotientQ(lst[0], v):
4771            # Basis: If m even and n odd, Sin[m*v]^n == Cos[v]*u where u is a function of Sin[v].
4772            return FunctionOfSinQ(Cos(v)*lst[1], v, x)
4773        lst = FindTrigFactor(cos, sec, u, v, False)
4774        if ListQ(lst) and OddQuotientQ(lst[0], v):
4775            # Basis: If m odd and n odd, Cos[m*v]^n == Cos[v]*u where u is a function of Sin[v].
4776            return FunctionOfSinQ(Cos(v)*lst[1], v, x)
4777        lst = FindTrigFactor(tan, cot, u, v, True)
4778        if ListQ(lst):
4779            # Basis: If m integer and n odd, Tan[m*v]^n == Cos[v]*u where u is a function of Sin[v].
4780            return FunctionOfSinQ(Cos(v)*lst[1], v, x)
4781        return all(FunctionOfSinQ(i, v, x) for i in u.args)
4782    return all(FunctionOfSinQ(i, v, x) for i in u.args)
4783
4784def OddTrigPowerQ(u, v, x):
4785    if SinQ(u) or CosQ(u) or SecQ(u) or CscQ(u):
4786        return OddQuotientQ(u.args[0], v)
4787    if PowerQ(u):
4788        return OddQ(u.exp) and OddTrigPowerQ(u.base, v, x)
4789    if ProductQ(u):
4790        if not FreeFactors(u, x) == 1:
4791            return OddTrigPowerQ(NonfreeFactors(u, x), v, x)
4792        lst = []
4793        for i in u.args:
4794            if Not(FunctionOfTanQ(i, v, x)):
4795                lst.append(i)
4796        if lst == []:
4797            return True
4798        return Length(lst)==1 and OddTrigPowerQ(lst[0], v, x)
4799    if SumQ(u):
4800        return all(OddTrigPowerQ(i, v, x) for i in u.args)
4801    return False
4802
4803def FunctionOfTanQ(u, v, x):
4804    # If u is a function of the form f[Tan[v],Cot[v]] where f is independent of x,
4805    # FunctionOfTanQ[u,v,x] returns True; else it returns False.
4806    if AtomQ(u):
4807        return u != x
4808    elif CalculusQ(u):
4809        return False
4810    elif TrigQ(u) and IntegerQuotientQ(u.args[0], v):
4811        return TanQ(u) or CotQ(u) or EvenQuotientQ(u.args[0], v)
4812    elif PowerQ(u):
4813        if EvenQ(u.exp) and TrigQ(u.base) and IntegerQuotientQ(u.base.args[0], v):
4814            return True
4815        elif EvenQ(u.exp) and SumQ(u.base):
4816            return FunctionOfTanQ(Expand(u.base**2, v, x))
4817    if ProductQ(u):
4818        lst = []
4819        for i in u.args:
4820            if Not(FunctionOfTanQ(i, v, x)):
4821                lst.append(i)
4822        if lst == []:
4823            return True
4824        return Length(lst)==2 and OddTrigPowerQ(lst[0], v, x) and OddTrigPowerQ(lst[1], v, x)
4825    return all(FunctionOfTanQ(i, v, x) for i in u.args)
4826
4827def FunctionOfTanWeight(u, v, x):
4828    # (* u is a function of the form f[Tan[v],Cot[v]] where f is independent of x.
4829    # FunctionOfTanWeight[u,v,x] returns a nonnegative number if u is best considered a function
4830    # of Tan[v]; else it returns a negative number. *)
4831    if AtomQ(u):
4832        return S(0)
4833    elif CalculusQ(u):
4834        return S(0)
4835    elif TrigQ(u) and IntegerQuotientQ(u.args[0], v):
4836        if TanQ(u) and ZeroQ(u.args[0] - v):
4837            return S(1)
4838        elif CotQ(u) and ZeroQ(u.args[0] - v):
4839            return S(-1)
4840        return S(0)
4841    elif PowerQ(u):
4842        if EvenQ(u.exp) and TrigQ(u.base) and IntegerQuotientQ(u.base.args[0], v):
4843            if TanQ(u.base) or CosQ(u.base) or SecQ(u.base):
4844                return S(1)
4845            return S(-1)
4846    if ProductQ(u):
4847        if all(FunctionOfTanQ(i, v, x) for i in u.args):
4848            return Add(*[FunctionOfTanWeight(i, v, x) for i in u.args])
4849        return S(0)
4850    return Add(*[FunctionOfTanWeight(i, v, x) for i in u.args])
4851
4852def FunctionOfTrigQ(u, v, x):
4853    # If u (x) is equivalent to a function of the form f (Sin[v],Cos[v],Tan[v],Cot[v],Sec[v],Csc[v]) where f is independent of x, FunctionOfTrigQ[u,v,x] returns True; else it returns False.
4854    if AtomQ(u):
4855        return u != x
4856    elif CalculusQ(u):
4857        return False
4858    elif TrigQ(u) and IntegerQuotientQ(u.args[0], v):
4859        return True
4860    return all(FunctionOfTrigQ(i, v, x) for i in u.args)
4861
4862def FunctionOfDensePolynomialsQ(u, x):
4863    # If all occurrences of x in u (x) are in dense polynomials, FunctionOfDensePolynomialsQ[u,x] returns True; else it returns False.
4864    if FreeQ(u, x):
4865        return True
4866    if PolynomialQ(u, x):
4867        return Length(ExponentList(u, x)) > 1
4868    return all(FunctionOfDensePolynomialsQ(i, x) for i in u.args)
4869
4870def FunctionOfLog(u, *args):
4871    # If u (x) is equivalent to an expression of the form f (Log[a*x^n]), FunctionOfLog[u,x] returns
4872    # the list {f (x),a*x^n,n}; else it returns False.
4873    if len(args) == 1:
4874        x = args[0]
4875        lst = FunctionOfLog(u, False, False, x)
4876        if AtomQ(lst) or FalseQ(lst[1]) or not isinstance(x, Symbol):
4877            return False
4878        else:
4879            return lst
4880    else:
4881        v = args[0]
4882        n = args[1]
4883        x = args[2]
4884        if AtomQ(u):
4885            if u==x:
4886                return False
4887            else:
4888                return [u, v, n]
4889        if CalculusQ(u):
4890            return False
4891        lst = BinomialParts(u.args[0], x)
4892        if LogQ(u) and ListQ(lst) and ZeroQ(lst[0]):
4893            if FalseQ(v) or u.args[0] == v:
4894                return [x, u.args[0], lst[2]]
4895            else:
4896                return False
4897        lst = [0, v, n]
4898        l = []
4899        for i in u.args:
4900                lst = FunctionOfLog(i, lst[1], lst[2], x)
4901                if AtomQ(lst):
4902                    return False
4903                else:
4904                    l.append(lst[0])
4905
4906        return [u.func(*l), lst[1], lst[2]]
4907
4908def PowerVariableExpn(u, m, x):
4909    # If m is an integer, u is an expression of the form f((c*x)**n) and g=GCD(m,n)>1,
4910    # PowerVariableExpn(u,m,x) returns the list {x**(m/g)*f((c*x)**(n/g)),g,c}; else it returns False.
4911    if IntegerQ(m):
4912        lst = PowerVariableDegree(u, m, 1, x)
4913        if not lst:
4914            return False
4915        else:
4916            return [x**(m/lst[0])*PowerVariableSubst(u, lst[0], x), lst[0], lst[1]]
4917    else:
4918        return False
4919
4920def PowerVariableDegree(u, m, c, x):
4921    if FreeQ(u, x):
4922        return [m, c]
4923    if AtomQ(u) or CalculusQ(u):
4924        return False
4925    if PowerQ(u):
4926        if FreeQ(u.base/x, x):
4927            if ZeroQ(m) or m == u.exp and c == u.base/x:
4928                return [u.exp, u.base/x]
4929            if IntegerQ(u.exp) and IntegerQ(m) and GCD(m, u.exp)>1 and c==u.base/x:
4930                return [GCD(m, u.exp), c]
4931            else:
4932                return False
4933    lst = [m, c]
4934    for i in u.args:
4935        if PowerVariableDegree(i, lst[0], lst[1], x) == False:
4936            return False
4937        lst1 = PowerVariableDegree(i, lst[0], lst[1], x)
4938    if not lst1:
4939        return False
4940    else:
4941        return lst1
4942
4943def PowerVariableSubst(u, m, x):
4944    if FreeQ(u, x) or AtomQ(u) or CalculusQ(u):
4945        return u
4946    if PowerQ(u):
4947        if FreeQ(u.base/x, x):
4948            return x**(u.exp/m)
4949    if ProductQ(u):
4950        l = 1
4951        for i in u.args:
4952            l *= (PowerVariableSubst(i, m, x))
4953        return l
4954    if SumQ(u):
4955        l = 0
4956        for i in u.args:
4957            l += (PowerVariableSubst(i, m, x))
4958        return l
4959    return u
4960
4961def EulerIntegrandQ(expr, x):
4962    a = Wild('a', exclude=[x])
4963    b = Wild('b', exclude=[x])
4964    n = Wild('n', exclude=[x, 0])
4965    m = Wild('m', exclude=[x, 0])
4966    p = Wild('p', exclude=[x, 0])
4967    u = Wild('u')
4968    v = Wild('v')
4969    # Pattern 1
4970    M = expr.match((a*x + b*u**n)**p)
4971    if M:
4972        if len(M) == 5 and FreeQ([M[a], M[b]], x) and IntegerQ(M[n] + 1/2) and QuadraticQ(M[u], x) and Not(RationalQ(M[p])) or NegativeIntegerQ(M[p]) and Not(BinomialQ(M[u], x)):
4973            return True
4974    # Pattern 2
4975    M = expr.match(v**m*(a*x + b*u**n)**p)
4976    if M:
4977        if len(M) == 6 and FreeQ([M[a], M[b]], x) and ZeroQ(M[u] - M[v]) and IntegersQ(2*M[m], M[n] + 1/2) and QuadraticQ(M[u], x) and Not(RationalQ(M[p])) or NegativeIntegerQ(M[p]) and Not(BinomialQ(M[u], x)):
4978            return True
4979    # Pattern 3
4980    M = expr.match(u**n*v**p)
4981    if M:
4982        if len(M) == 3 and NegativeIntegerQ(M[p]) and IntegerQ(M[n] + 1/2) and QuadraticQ(M[u], x) and QuadraticQ(M[v], x) and Not(BinomialQ(M[v], x)):
4983            return True
4984    else:
4985        return False
4986
4987def FunctionOfSquareRootOfQuadratic(u, *args):
4988    if len(args) == 1:
4989        x = args[0]
4990        pattern = Pattern(UtilityOperator(x_**WC('m', 1)*(a_ + x**WC('n', 1)*WC('b', 1))**p_, x), CustomConstraint(lambda a, b, m, n, p, x: FreeQ([a, b, m, n, p], x)))
4991        M = is_match(UtilityOperator(u, args[0]), pattern)
4992        if M:
4993            return False
4994        tmp = FunctionOfSquareRootOfQuadratic(u, False, x)
4995        if AtomQ(tmp) or FalseQ(tmp[0]):
4996            return False
4997        tmp = tmp[0]
4998        a = Coefficient(tmp, x, 0)
4999        b = Coefficient(tmp, x, 1)
5000        c = Coefficient(tmp, x, 2)
5001        if ZeroQ(a) and ZeroQ(b) or ZeroQ(b**2-4*a*c):
5002            return False
5003        if PosQ(c):
5004            sqrt = Rt(c, S(2));
5005            q = a*sqrt + b*x + sqrt*x**2
5006            r = b + 2*sqrt*x
5007            return [Simplify(SquareRootOfQuadraticSubst(u, q/r, (-a+x**2)/r, x)*q/r**2), Simplify(sqrt*x + Sqrt(tmp)), 2]
5008        if PosQ(a):
5009            sqrt = Rt(a, S(2))
5010            q = c*sqrt - b*x + sqrt*x**2
5011            r = c - x**2
5012            return [Simplify(SquareRootOfQuadraticSubst(u, q/r, (-b+2*sqrt*x)/r, x)*q/r**2), Simplify((-sqrt+Sqrt(tmp))/x), 1]
5013        sqrt = Rt(b**2 - 4*a*c, S(2))
5014        r = c - x**2
5015        return[Simplify(-sqrt*SquareRootOfQuadraticSubst(u, -sqrt*x/r, -(b*c+c*sqrt+(-b+sqrt)*x**2)/(2*c*r), x)*x/r**2), FullSimplify(2*c*Sqrt(tmp)/(b-sqrt+2*c*x)), 3]
5016    else:
5017        v = args[0]
5018        x = args[1]
5019        if AtomQ(u) or FreeQ(u, x):
5020            return [v]
5021        if PowerQ(u):
5022            if FreeQ(u.exp, x):
5023                if FractionQ(u.exp) and Denominator(u.exp) == 2 and PolynomialQ(u.base, x) and Exponent(u.base, x) == 2:
5024                    if FalseQ(v) or u.base == v:
5025                        return [u.base]
5026                    else:
5027                        return False
5028                return FunctionOfSquareRootOfQuadratic(u.base, v, x)
5029        if ProductQ(u) or SumQ(u):
5030            lst = [v]
5031            lst1 = []
5032            for i in u.args:
5033                if FunctionOfSquareRootOfQuadratic(i, lst[0], x) == False:
5034                    return False
5035                lst1 = FunctionOfSquareRootOfQuadratic(i, lst[0], x)
5036            return lst1
5037        else:
5038            return False
5039
5040def SquareRootOfQuadraticSubst(u, vv, xx, x):
5041    # SquareRootOfQuadraticSubst(u, vv, xx, x) returns u with fractional powers replaced by vv raised to the power and x replaced by xx.
5042    if AtomQ(u) or FreeQ(u, x):
5043        if u==x:
5044            return xx
5045        return u
5046    if PowerQ(u):
5047        if FreeQ(u.exp, x):
5048            if FractionQ(u.exp) and Denominator(u.exp)==2 and PolynomialQ(u.base, x) and Exponent(u.base, x)==2:
5049                return vv**Numerator(u.exp)
5050            return SquareRootOfQuadraticSubst(u.base, vv, xx, x)**u.exp
5051    elif SumQ(u):
5052        t = 0
5053        for i in u.args:
5054            t += SquareRootOfQuadraticSubst(i, vv, xx, x)
5055        return t
5056    elif ProductQ(u):
5057        t = 1
5058        for i in u.args:
5059            t *= SquareRootOfQuadraticSubst(i, vv, xx, x)
5060        return t
5061
5062def Divides(y, u, x):
5063    # If u divided by y is free of x, Divides[y,u,x] returns the quotient; else it returns False.
5064    v = Simplify(u/y)
5065    if FreeQ(v, x):
5066        return v
5067    else:
5068        return False
5069
5070def DerivativeDivides(y, u, x):
5071    """
5072    If y not equal to x, y is easy to differentiate wrt x, and u divided by the derivative of y
5073    is free of x, DerivativeDivides[y,u,x] returns the quotient; else it returns False.
5074    """
5075    from matchpy import is_match
5076    pattern0 = Pattern(Mul(a , b_), CustomConstraint(lambda a, b : FreeQ(a, b)))
5077    def f1(y, u, x):
5078        if PolynomialQ(y, x):
5079            return PolynomialQ(u, x) and Exponent(u, x) == Exponent(y, x) - 1
5080        else:
5081            return EasyDQ(y, x)
5082
5083    if is_match(y, pattern0):
5084        return False
5085
5086    elif f1(y, u, x):
5087        v = D(y ,x)
5088        if EqQ(v, 0):
5089            return False
5090        else:
5091            v = Simplify(u/v)
5092            if FreeQ(v, x):
5093                return v
5094            else:
5095                return False
5096    else:
5097        return False
5098
5099
5100def EasyDQ(expr, x):
5101    # If u is easy to differentiate wrt x,  EasyDQ(u, x) returns True; else it returns False *)
5102    u = Wild('u',exclude=[1])
5103    m = Wild('m',exclude=[x, 0])
5104    M = expr.match(u*x**m)
5105    if M:
5106        return EasyDQ(M[u], x)
5107    if AtomQ(expr) or FreeQ(expr, x) or Length(expr)==0:
5108        return True
5109    elif CalculusQ(expr):
5110        return False
5111    elif Length(expr)==1:
5112        return EasyDQ(expr.args[0], x)
5113    elif BinomialQ(expr, x) or ProductOfLinearPowersQ(expr, x):
5114        return True
5115    elif RationalFunctionQ(expr, x) and RationalFunctionExponents(expr, x)==[1, 1]:
5116        return True
5117    elif ProductQ(expr):
5118        if FreeQ(First(expr), x):
5119            return EasyDQ(Rest(expr), x)
5120        elif FreeQ(Rest(expr), x):
5121            return EasyDQ(First(expr), x)
5122        else:
5123            return False
5124    elif SumQ(expr):
5125        return EasyDQ(First(expr), x) and EasyDQ(Rest(expr), x)
5126    elif Length(expr)==2:
5127        if FreeQ(expr.args[0], x):
5128            EasyDQ(expr.args[1], x)
5129        elif FreeQ(expr.args[1], x):
5130            return EasyDQ(expr.args[0], x)
5131        else:
5132            return False
5133    return False
5134
5135def ProductOfLinearPowersQ(u, x):
5136    # ProductOfLinearPowersQ(u, x) returns True iff u is a product of factors of the form v^n where v is linear in x
5137    v = Wild('v')
5138    n = Wild('n', exclude=[x])
5139    M = u.match(v**n)
5140    return FreeQ(u, x) or M and LinearQ(M[v], x) or ProductQ(u) and ProductOfLinearPowersQ(First(u), x) and ProductOfLinearPowersQ(Rest(u), x)
5141
5142def Rt(u, n):
5143    return RtAux(TogetherSimplify(u), n)
5144
5145def NthRoot(u, n):
5146    return nsimplify(u**(S(1)/n))
5147
5148def AtomBaseQ(u):
5149    # If u is an atom or an atom raised to an odd degree,  AtomBaseQ(u) returns True; else it returns False
5150    return AtomQ(u) or PowerQ(u) and OddQ(u.args[1]) and AtomBaseQ(u.args[0])
5151
5152def SumBaseQ(u):
5153    # If u is a sum or a sum raised to an odd degree,  SumBaseQ(u) returns True; else it returns False
5154    return SumQ(u) or PowerQ(u) and OddQ(u.args[1]) and SumBaseQ(u.args[0])
5155
5156def NegSumBaseQ(u):
5157    # If u is a sum or a sum raised to an odd degree whose lead term has a negative form,  NegSumBaseQ(u) returns True; else it returns False
5158    return SumQ(u) and NegQ(First(u)) or PowerQ(u) and OddQ(u.args[1]) and NegSumBaseQ(u.args[0])
5159
5160def AllNegTermQ(u):
5161    # If all terms of u have a negative form, AllNegTermQ(u) returns True; else it returns False
5162    if PowerQ(u):
5163        if OddQ(u.exp):
5164            return AllNegTermQ(u.base)
5165    if SumQ(u):
5166        return NegQ(First(u)) and AllNegTermQ(Rest(u))
5167    return NegQ(u)
5168
5169def SomeNegTermQ(u):
5170    # If some term of u has a negative form,  SomeNegTermQ(u) returns True; else it returns False
5171    if PowerQ(u):
5172        if OddQ(u.exp):
5173            return SomeNegTermQ(u.base)
5174    if SumQ(u):
5175        return NegQ(First(u)) or SomeNegTermQ(Rest(u))
5176    return NegQ(u)
5177
5178def TrigSquareQ(u):
5179    # If u is an expression of the form Sin(z)^2 or Cos(z)^2,  TrigSquareQ(u) returns True,  else it returns False
5180    return PowerQ(u) and EqQ(u.args[1], 2) and MemberQ([sin, cos], Head(u.args[0]))
5181
5182def RtAux(u, n):
5183    if PowerQ(u):
5184        return u.base**(u.exp/n)
5185    if ComplexNumberQ(u):
5186        a = Re(u)
5187        b = Im(u)
5188        if Not(IntegerQ(a) and IntegerQ(b)) and IntegerQ(a/(a**2 + b**2)) and IntegerQ(b/(a**2 + b**2)):
5189            # Basis: a+b*I==1/(a/(a^2+b^2)-b/(a^2+b^2)*I)
5190            return S(1)/RtAux(a/(a**2 + b**2) - b/(a**2 + b**2)*I, n)
5191        else:
5192            return NthRoot(u, n)
5193    if ProductQ(u):
5194        lst = SplitProduct(PositiveQ, u)
5195        if ListQ(lst):
5196            return RtAux(lst[0], n)*RtAux(lst[1], n)
5197        lst = SplitProduct(NegativeQ, u)
5198        if ListQ(lst):
5199            if EqQ(lst[0], -1):
5200                v = lst[1]
5201                if PowerQ(v):
5202                    if NegativeQ(v.exp):
5203                        return 1/RtAux(-v.base**(-v.exp), n)
5204                if ProductQ(v):
5205                    if ListQ(SplitProduct(SumBaseQ, v)):
5206                        lst = SplitProduct(AllNegTermQ, v)
5207                        if ListQ(lst):
5208                            return RtAux(-lst[0], n)*RtAux(lst[1], n)
5209                        lst = SplitProduct(NegSumBaseQ, v)
5210                        if ListQ(lst):
5211                            return RtAux(-lst[0], n)*RtAux(lst[1], n)
5212                        lst = SplitProduct(SomeNegTermQ, v)
5213                        if ListQ(lst):
5214                            return RtAux(-lst[0], n)*RtAux(lst[1], n)
5215                        lst = SplitProduct(SumBaseQ, v)
5216                        return RtAux(-lst[0], n)*RtAux(lst[1], n)
5217                    lst = SplitProduct(AtomBaseQ, v)
5218                    if ListQ(lst):
5219                        return RtAux(-lst[0], n)*RtAux(lst[1], n)
5220                    else:
5221                        return RtAux(-First(v), n)*RtAux(Rest(v), n)
5222                if OddQ(n):
5223                    return -RtAux(v, n)
5224                else:
5225                    return NthRoot(u, n)
5226            else:
5227                return RtAux(-lst[0], n)*RtAux(-lst[1], n)
5228        lst = SplitProduct(AllNegTermQ, u)
5229        if ListQ(lst) and ListQ(SplitProduct(SumBaseQ, lst[1])):
5230            return RtAux(-lst[0], n)*RtAux(-lst[1], n)
5231        lst = SplitProduct(NegSumBaseQ, u)
5232        if ListQ(lst) and ListQ(SplitProduct(NegSumBaseQ, lst[1])):
5233            return RtAux(-lst[0], n)*RtAux(-lst[1], n)
5234        return u.func(*[RtAux(i, n) for i in u.args])
5235    v = TrigSquare(u)
5236    if Not(AtomQ(v)):
5237        return RtAux(v, n)
5238    if OddQ(n) and NegativeQ(u):
5239        return -RtAux(-u, n)
5240    if OddQ(n) and NegQ(u) and PosQ(-u):
5241        return -RtAux(-u, n)
5242    else:
5243        return NthRoot(u, n)
5244
5245def TrigSquare(u):
5246    # If u is an expression of the form a-a*Sin(z)^2 or a-a*Cos(z)^2, TrigSquare(u) returns Cos(z)^2 or Sin(z)^2 respectively,
5247    # else it returns False.
5248    if SumQ(u):
5249        for i in u.args:
5250            v = SplitProduct(TrigSquareQ, i)
5251            if v == False or SplitSum(v, u) == False:
5252                return False
5253            lst = SplitSum(SplitProduct(TrigSquareQ, i))
5254        if lst and ZeroQ(lst[1][2] + lst[1]):
5255            if Head(lst[0][0].args[0]) == sin:
5256                return lst[1]*cos(lst[1][1][1][1])**2
5257            return lst[1]*sin(lst[1][1][1][1])**2
5258        else:
5259            return False
5260    else:
5261        return False
5262
5263def IntSum(u, x):
5264    # If u is free of x or of the form c*(a+b*x)^m, IntSum[u,x] returns the antiderivative of u wrt x;
5265    # else it returns d*Int[v,x] where d*v=u and d is free of x.
5266    return Add(*[Integral(i, x) for i in u.args])
5267
5268def IntTerm(expr, x):
5269    # If u is of the form c*(a+b*x)**m, IntTerm(u,x) returns the antiderivative of u wrt x;
5270    # else it returns d*Int(v,x) where d*v=u and d is free of x.
5271    c = Wild('c', exclude=[x])
5272    m = Wild('m', exclude=[x, 0])
5273    v = Wild('v')
5274    M = expr.match(c/v)
5275    if M and len(M) == 2 and FreeQ(M[c], x) and LinearQ(M[v], x):
5276        return Simp(M[c]*Log(RemoveContent(M[v], x))/Coefficient(M[v], x, 1), x)
5277    M = expr.match(c*v**m)
5278    if M and len(M) == 3 and NonzeroQ(M[m] + 1) and LinearQ(M[v], x):
5279        return Simp(M[c]*M[v]**(M[m] + 1)/(Coefficient(M[v], x, 1)*(M[m] + 1)), x)
5280    if SumQ(expr):
5281        t = 0
5282        for i in expr.args:
5283            t += IntTerm(i, x)
5284        return t
5285    else:
5286        u = expr
5287        return Dist(FreeFactors(u,x), Integral(NonfreeFactors(u, x), x), x)
5288
5289def Map2(f, lst1, lst2):
5290    result = []
5291    for i in range(0, len(lst1)):
5292        result.append(f(lst1[i], lst2[i]))
5293    return result
5294
5295def ConstantFactor(u, x):
5296    # (* ConstantFactor[u,x] returns a 2-element list of the factors of u[x] free of x and the
5297    # factors not free of u[x].  Common constant factors of the terms of sums are also collected. *)
5298    if FreeQ(u, x):
5299        return [u, S(1)]
5300    elif AtomQ(u):
5301        return [S(1), u]
5302    elif PowerQ(u):
5303        if FreeQ(u.exp, x):
5304            lst = ConstantFactor(u.base, x)
5305            if IntegerQ(u.exp):
5306                return [lst[0]**u.exp, lst[1]**u.exp]
5307            tmp = PositiveFactors(lst[0])
5308            if tmp == 1:
5309                return [S(1), u]
5310            return [tmp**u.exp, (NonpositiveFactors(lst[0])*lst[1])**u.exp]
5311    elif ProductQ(u):
5312        lst = [ConstantFactor(i, x) for i in u.args]
5313        return [Mul(*[First(i) for i in lst]), Mul(*[i[1] for i in lst])]
5314    elif SumQ(u):
5315        lst1 = [ConstantFactor(i, x) for i in u.args]
5316        if SameQ(*[i[1] for i in lst1]):
5317            return [Add(*[i[0] for i in lst]), lst1[0][1]]
5318        lst2 = CommonFactors([First(i) for i in lst1])
5319        return [First(lst2), Add(*Map2(Mul, Rest(lst2), [i[1] for i in lst1]))]
5320    return [S(1), u]
5321
5322def SameQ(*args):
5323    for i in range(0, len(args) - 1):
5324        if args[i] != args[i+1]:
5325            return False
5326    return True
5327
5328def ReplacePart(lst, a, b):
5329    lst[b] = a
5330    return lst
5331
5332def CommonFactors(lst):
5333    # (* If lst is a list of n terms, CommonFactors[lst] returns a n+1-element list whose first
5334    # element is the product of the factors common to all terms of lst, and whose remaining
5335    # elements are quotients of each term divided by the common factor. *)
5336    lst1 = [NonabsurdNumberFactors(i) for i in lst]
5337    lst2 = [AbsurdNumberFactors(i) for i in lst]
5338    num = AbsurdNumberGCD(*lst2)
5339    common = num
5340    lst2 = [i/num for i in lst2]
5341    while (True):
5342        lst3 = [LeadFactor(i) for i in lst1]
5343
5344        if SameQ(*lst3):
5345            common = common*lst3[0]
5346            lst1 = [RemainingFactors(i) for i in lst1]
5347        elif (all((LogQ(i) and IntegerQ(First(i)) and First(i) > 0) for i in lst3) and
5348            all(RationalQ(i) for i in [FullSimplify(j/First(lst3)) for j in lst3])):
5349            lst4 = [FullSimplify(j/First(lst3)) for j in lst3]
5350            num = GCD(*lst4)
5351            common = common*Log((First(lst3)[0])**num)
5352            lst2 = [lst2[i]*lst4[i]/num for i in range(0, len(lst2))]
5353            lst1 = [RemainingFactors(i) for i in lst1]
5354        lst4 = [LeadDegree(i) for i in lst1]
5355        if SameQ(*[LeadBase(i) for i in lst1]) and RationalQ(*lst4):
5356            num = Smallest(lst4)
5357            base = LeadBase(lst1[0])
5358            if num != 0:
5359                common = common*base**num
5360            lst2 = [lst2[i]*base**(lst4[i] - num) for i in range(0, len(lst2))]
5361            lst1 = [RemainingFactors(i) for i in lst1]
5362        elif (Length(lst1) == 2 and ZeroQ(LeadBase(lst1[0]) + LeadBase(lst1[1])) and
5363            NonzeroQ(lst1[0] - 1) and IntegerQ(lst4[0]) and FractionQ(lst4[1])):
5364            num = Min(lst4)
5365            base = LeadBase(lst1[1])
5366            if num != 0:
5367                common = common*base**num
5368            lst2 = [lst2[0]*(-1)**lst4[0], lst2[1]]
5369            lst2 = [lst2[i]*base**(lst4[i] - num) for i in range(0, len(lst2))]
5370            lst1 = [RemainingFactors(i) for i in lst1]
5371        elif (Length(lst1) == 2 and ZeroQ(lst1[0] + LeadBase(lst1[1])) and
5372            NonzeroQ(lst1[1] - 1) and IntegerQ(lst1[1]) and FractionQ(lst4[0])):
5373            num = Min(lst4)
5374            base = LeadBase(lst1[0])
5375            if num != 0:
5376                common = common*base**num
5377            lst2 = [lst2[0], lst2[1]*(-1)**lst4[1]]
5378            lst2 = [lst2[i]*base**(lst4[i] - num) for i in range(0, len(lst2))]
5379            lst1 = [RemainingFactors(i) for i in lst1]
5380        else:
5381            num = MostMainFactorPosition(lst3)
5382            lst2 = ReplacePart(lst2, lst3[num]*lst2[num], num)
5383            lst1 = ReplacePart(lst1, RemainingFactors(lst1[num]), num)
5384        if all(i==1 for i in lst1):
5385            return Prepend(lst2, common)
5386
5387def MostMainFactorPosition(lst):
5388    factor = S(1)
5389    num = 0
5390    for i in range(0, Length(lst)):
5391        if FactorOrder(lst[i], factor) > 0:
5392            factor = lst[i]
5393            num = i
5394    return num
5395
5396SbaseS, SexponS = None, None
5397SexponFlagS = False
5398def FunctionOfExponentialQ(u, x):
5399    # (* FunctionOfExponentialQ[u,x] returns True iff u is a function of F^v where F is a constant and v is linear in x, *)
5400    # (* and such an exponential explicitly occurs in u (i.e. not just implicitly in hyperbolic functions). *)
5401    global SbaseS, SexponS, SexponFlagS
5402    SbaseS, SexponS = None, None
5403    SexponFlagS = False
5404    res = FunctionOfExponentialTest(u, x)
5405    return res and SexponFlagS
5406
5407def FunctionOfExponential(u, x):
5408    global SbaseS, SexponS, SexponFlagS
5409    # (* u is a function of F^v where v is linear in x.  FunctionOfExponential[u,x] returns F^v. *)
5410    SbaseS, SexponS = None, None
5411    SexponFlagS = False
5412    FunctionOfExponentialTest(u, x)
5413    return SbaseS**SexponS
5414
5415def FunctionOfExponentialFunction(u, x):
5416    global SbaseS, SexponS, SexponFlagS
5417    # (* u is a function of F^v where v is linear in x.  FunctionOfExponentialFunction[u,x] returns u with F^v replaced by x. *)
5418    SbaseS, SexponS = None, None
5419    SexponFlagS = False
5420    FunctionOfExponentialTest(u, x)
5421    return SimplifyIntegrand(FunctionOfExponentialFunctionAux(u, x), x)
5422
5423def FunctionOfExponentialFunctionAux(u, x):
5424    # (* u is a function of F^v where v is linear in x, and the fluid variables $base$=F and $expon$=v. *)
5425    # (* FunctionOfExponentialFunctionAux[u,x] returns u with F^v replaced by x. *)
5426    global SbaseS, SexponS, SexponFlagS
5427    if AtomQ(u):
5428        return u
5429    elif PowerQ(u):
5430        if FreeQ(u.base, x) and LinearQ(u.exp, x):
5431            if ZeroQ(Coefficient(SexponS, x, 0)):
5432                return u.base**Coefficient(u.exp, x, 0)*x**FullSimplify(Log(u.base)*Coefficient(u.exp, x, 1)/(Log(SbaseS)*Coefficient(SexponS, x, 1)))
5433            return x**FullSimplify(Log(u.base)*Coefficient(u.exp, x, 1)/(Log(SbaseS)*Coefficient(SexponS, x, 1)))
5434    elif HyperbolicQ(u) and LinearQ(u.args[0], x):
5435        tmp = x**FullSimplify(Coefficient(u.args[0], x, 1)/(Log(SbaseS)*Coefficient(SexponS, x, 1)))
5436        if SinhQ(u):
5437            return tmp/2 - 1/(2*tmp)
5438        elif CoshQ(u):
5439            return tmp/2 + 1/(2*tmp)
5440        elif TanhQ(u):
5441            return (tmp - 1/tmp)/(tmp + 1/tmp)
5442        elif CothQ(u):
5443            return (tmp + 1/tmp)/(tmp - 1/tmp)
5444        elif SechQ(u):
5445            return 2/(tmp + 1/tmp)
5446        return 2/(tmp - 1/tmp)
5447    if PowerQ(u):
5448        if FreeQ(u.base, x) and SumQ(u.exp):
5449            return FunctionOfExponentialFunctionAux(u.base**First(u.exp), x)*FunctionOfExponentialFunctionAux(u.base**Rest(u.exp), x)
5450    return u.func(*[FunctionOfExponentialFunctionAux(i, x) for i in u.args])
5451
5452def FunctionOfExponentialTest(u, x):
5453    # (* FunctionOfExponentialTest[u,x] returns True iff u is a function of F^v where F is a constant and v is linear in x. *)
5454    # (* Before it is called, the fluid variables $base$ and $expon$ should be set to Null and $exponFlag$ to False. *)
5455    # (* If u is a function of F^v, $base$ and $expon$ are set to F and v, respectively. *)
5456    # (* If an explicit exponential occurs in u, $exponFlag$ is set to True. *)
5457    global SbaseS, SexponS, SexponFlagS
5458    if FreeQ(u, x):
5459        return True
5460    elif u == x or CalculusQ(u):
5461        return False
5462    elif PowerQ(u):
5463        if FreeQ(u.base, x) and LinearQ(u.exp, x):
5464            SexponFlagS = True
5465            return FunctionOfExponentialTestAux(u.base, u.exp, x)
5466    elif HyperbolicQ(u) and LinearQ(u.args[0], x):
5467        return FunctionOfExponentialTestAux(E, u.args[0], x)
5468    if PowerQ(u):
5469        if FreeQ(u.base, x) and SumQ(u.exp):
5470            return FunctionOfExponentialTest(u.base**First(u.exp), x) and FunctionOfExponentialTest(u.base**Rest(u.exp), x)
5471    return all(FunctionOfExponentialTest(i, x) for i in u.args)
5472
5473def FunctionOfExponentialTestAux(base, expon, x):
5474    global SbaseS, SexponS, SexponFlagS
5475    if SbaseS is None:
5476        SbaseS = base
5477        SexponS = expon
5478        return True
5479    tmp = FullSimplify(Log(base)*Coefficient(expon, x, 1)/(Log(SbaseS)*Coefficient(SexponS, x, 1)))
5480    if Not(RationalQ(tmp)):
5481        return False
5482    elif ZeroQ(Coefficient(SexponS, x, 0)) or NonzeroQ(tmp - FullSimplify(Log(base)*Coefficient(expon, x, 0)/(Log(SbaseS)*Coefficient(SexponS, x, 0)))):
5483        if PositiveIntegerQ(base, SbaseS) and base < SbaseS:
5484            SbaseS = base
5485            SexponS = expon
5486            tmp = 1/tmp
5487        SexponS = Coefficient(SexponS, x, 1)*x/Denominator(tmp)
5488        if tmp < 0 and NegQ(Coefficient(SexponS, x, 1)):
5489            SexponS = -SexponS
5490        return True
5491    SexponS = SexponS/Denominator(tmp)
5492    if tmp < 0 and NegQ(Coefficient(SexponS, x, 1)):
5493        SexponS = -SexponS
5494    return True
5495
5496def stdev(lst):
5497    """Calculates the standard deviation for a list of numbers."""
5498    num_items = len(lst)
5499    mean = sum(lst) / num_items
5500    differences = [x - mean for x in lst]
5501    sq_differences = [d ** 2 for d in differences]
5502    ssd = sum(sq_differences)
5503    variance = ssd / num_items
5504    sd = sqrt(variance)
5505
5506    return sd
5507
5508def rubi_test(expr, x, optimal_output, expand=False, _hyper_check=False, _diff=False, _numerical=False):
5509    #Returns True if (expr - optimal_output) is equal to 0 or a constant
5510    #expr: integrated expression
5511    #x: integration variable
5512    #expand=True equates `expr` with `optimal_output` in expanded form
5513    #_hyper_check=True evaluates numerically
5514    #_diff=True differentiates the expressions before equating
5515    #_numerical=True equates the expressions at random `x`. Normally used for large expressions.
5516    from sympy import nsimplify
5517    if not expr.has(csc, sec, cot, csch, sech, coth):
5518        optimal_output = process_trig(optimal_output)
5519    if expr == optimal_output:
5520        return True
5521    if simplify(expr) == simplify(optimal_output):
5522        return True
5523
5524    if nsimplify(expr) == nsimplify(optimal_output):
5525        return True
5526
5527    if expr.has(sym_exp):
5528        expr = powsimp(powdenest(expr), force=True)
5529        if simplify(expr) == simplify(powsimp(optimal_output, force=True)):
5530            return True
5531    res = expr - optimal_output
5532    if _numerical:
5533        args = res.free_symbols
5534        rand_val = []
5535        try:
5536            for i in range(0, 5): # check at 5 random points
5537                rand_x = randint(1, 40)
5538                substitutions = {s: rand_x for s in args}
5539                rand_val.append(float(abs(res.subs(substitutions).n())))
5540
5541            if stdev(rand_val) < Pow(10, -3):
5542                return True
5543        except:
5544            pass
5545            # return False
5546
5547    dres = res.diff(x)
5548    if _numerical:
5549        args = dres.free_symbols
5550        rand_val = []
5551        try:
5552            for i in range(0, 5): # check at 5 random points
5553                rand_x = randint(1, 40)
5554                substitutions = {s: rand_x for s in args}
5555                rand_val.append(float(abs(dres.subs(substitutions).n())))
5556            if stdev(rand_val) < Pow(10, -3):
5557                return True
5558            # return False
5559        except:
5560            pass
5561            # return False
5562
5563
5564
5565    r = Simplify(nsimplify(res))
5566    if r == 0 or (not r.has(x)):
5567        return True
5568
5569    if _diff:
5570        if dres == 0:
5571            return True
5572        elif Simplify(dres) == 0:
5573            return True
5574
5575    if expand: # expands the expression and equates
5576        e = res.expand()
5577        if Simplify(e) == 0 or (not e.has(x)):
5578            return True
5579
5580
5581    return False
5582
5583
5584def If(cond, t, f):
5585    # returns t if condition is true else f
5586    if cond:
5587        return t
5588    return f
5589
5590def IntQuadraticQ(a, b, c, d, e, m, p, x):
5591    # (* IntQuadraticQ[a,b,c,d,e,m,p,x] returns True iff (d+e*x)^m*(a+b*x+c*x^2)^p is integrable wrt x in terms of non-Appell functions. *)
5592    return IntegerQ(p) or PositiveIntegerQ(m) or IntegersQ(2*m, 2*p) or IntegersQ(m, 4*p) or IntegersQ(m, p + S(1)/3) and (ZeroQ(c**2*d**2 - b*c*d*e + b**2*e**2 - 3*a*c*e**2) or ZeroQ(c**2*d**2 - b*c*d*e - 2*b**2*e**2 + 9*a*c*e**2))
5593
5594def IntBinomialQ(*args):
5595    #(* IntBinomialQ(a,b,c,n,m,p,x) returns True iff (c*x)^m*(a+b*x^n)^p is integrable wrt x in terms of non-hypergeometric functions. *)
5596    if len(args) == 8:
5597        a, b, c, d, n, p, q, x = args
5598        return IntegersQ(p,q) or PositiveIntegerQ(p) or PositiveIntegerQ(q) or (ZeroQ(n-2) or ZeroQ(n-4)) and (IntegersQ(p,4*q) or IntegersQ(4*p,q)) or ZeroQ(n-2) and (IntegersQ(2*p,2*q) or IntegersQ(3*p,q) and ZeroQ(b*c+3*a*d) or IntegersQ(p,3*q) and ZeroQ(3*b*c+a*d))
5599    elif len(args) == 7:
5600        a, b, c, n, m, p, x = args
5601        return IntegerQ(2*p) or IntegerQ((m+1)/n + p) or (ZeroQ(n - 2) or ZeroQ(n - 4)) and IntegersQ(2*m, 4*p) or ZeroQ(n - 2) and IntegerQ(6*p) and (IntegerQ(m) or IntegerQ(m - p))
5602    elif len(args) == 10:
5603        a, b, c, d, e, m, n, p, q, x = args
5604        return IntegersQ(p,q) or PositiveIntegerQ(p) or PositiveIntegerQ(q) or ZeroQ(n-2) and IntegerQ(m) and IntegersQ(2*p,2*q) or ZeroQ(n-4) and (IntegersQ(m,p,2*q) or IntegersQ(m,2*p,q))
5605
5606def RectifyTangent(*args):
5607    # (* RectifyTangent(u,a,b,r,x) returns an expression whose derivative equals the derivative of r*ArcTan(a+b*Tan(u)) wrt x. *)
5608    if len(args) == 5:
5609        u, a, b, r, x = args
5610        t1 = Together(a)
5611        t2 = Together(b)
5612        if (PureComplexNumberQ(t1) or (ProductQ(t1) and any(PureComplexNumberQ(i) for i in t1.args))) and (PureComplexNumberQ(t2) or ProductQ(t2) and any(PureComplexNumberQ(i) for i in t2.args)):
5613            c = a/I
5614            d = b/I
5615            if NegativeQ(d):
5616                return RectifyTangent(u, -a, -b, -r, x)
5617            e = SmartDenominator(Together(c + d*x))
5618            c = c*e
5619            d = d*e
5620            if EvenQ(Denominator(NumericFactor(Together(u)))):
5621                return I*r*Log(RemoveContent(Simplify((c+e)**2+d**2)+Simplify((c+e)**2-d**2)*Cos(2*u)+Simplify(2*(c+e)*d)*Sin(2*u),x))/4 - I*r*Log(RemoveContent(Simplify((c-e)**2+d**2)+Simplify((c-e)**2-d**2)*Cos(2*u)+Simplify(2*(c-e)*d)*Sin(2*u),x))/4
5622            return I*r*Log(RemoveContent(Simplify((c+e)**2)+Simplify(2*(c+e)*d)*Cos(u)*Sin(u)-Simplify((c+e)**2-d**2)*Sin(u)**2,x))/4 - I*r*Log(RemoveContent(Simplify((c-e)**2)+Simplify(2*(c-e)*d)*Cos(u)*Sin(u)-Simplify((c-e)**2-d**2)*Sin(u)**2,x))/4
5623        elif NegativeQ(b):
5624            return RectifyTangent(u, -a, -b, -r, x)
5625        elif EvenQ(Denominator(NumericFactor(Together(u)))):
5626            return r*SimplifyAntiderivative(u,x) + r*ArcTan(Simplify((2*a*b*Cos(2*u)-(1+a**2-b**2)*Sin(2*u))/(a**2+(1+b)**2+(1+a**2-b**2)*Cos(2*u)+2*a*b*Sin(2*u))))
5627        return r*SimplifyAntiderivative(u,x) - r*ArcTan(ActivateTrig(Simplify((a*b-2*a*b*cos(u)**2+(1+a**2-b**2)*cos(u)*sin(u))/(b*(1+b)+(1+a**2-b**2)*cos(u)**2+2*a*b*cos(u)*sin(u)))))
5628
5629    u, a, b, x = args
5630    t = Together(a)
5631    if PureComplexNumberQ(t) or (ProductQ(t) and any(PureComplexNumberQ(i) for i in t.args)):
5632        c = a/I
5633        if NegativeQ(c):
5634            return RectifyTangent(u, -a, -b, x)
5635        if ZeroQ(c - 1):
5636            if EvenQ(Denominator(NumericFactor(Together(u)))):
5637                return I*b*ArcTanh(Sin(2*u))/2
5638            return I*b*ArcTanh(2*cos(u)*sin(u))/2
5639        e = SmartDenominator(c)
5640        c = c*e
5641        return I*b*Log(RemoveContent(e*Cos(u)+c*Sin(u),x))/2 - I*b*Log(RemoveContent(e*Cos(u)-c*Sin(u),x))/2
5642    elif NegativeQ(a):
5643        return RectifyTangent(u, -a, -b, x)
5644    elif ZeroQ(a - 1):
5645        return b*SimplifyAntiderivative(u, x)
5646    elif EvenQ(Denominator(NumericFactor(Together(u)))):
5647        c =  Simplify((1 + a)/(1 - a))
5648        numr = SmartNumerator(c)
5649        denr = SmartDenominator(c)
5650        return b*SimplifyAntiderivative(u,x) - b*ArcTan(NormalizeLeadTermSigns(denr*Sin(2*u)/(numr+denr*Cos(2*u)))),
5651    elif PositiveQ(a - 1):
5652        c = Simplify(1/(a - 1))
5653        numr = SmartNumerator(c)
5654        denr = SmartDenominator(c)
5655        return b*SimplifyAntiderivative(u,x) + b*ArcTan(NormalizeLeadTermSigns(denr*Cos(u)*Sin(u)/(numr+denr*Sin(u)**2))),
5656    c = Simplify(a/(1 - a))
5657    numr = SmartNumerator(c)
5658    denr = SmartDenominator(c)
5659    return b*SimplifyAntiderivative(u,x) - b*ArcTan(NormalizeLeadTermSigns(denr*Cos(u)*Sin(u)/(numr+denr*Cos(u)**2)))
5660
5661def RectifyCotangent(*args):
5662    #(* RectifyCotangent[u,a,b,r,x] returns an expression whose derivative equals the derivative of r*ArcTan[a+b*Cot[u]] wrt x. *)
5663    if len(args) == 5:
5664        u, a, b, r, x = args
5665        t1 = Together(a)
5666        t2 = Together(b)
5667        if (PureComplexNumberQ(t1) or (ProductQ(t1) and any(PureComplexNumberQ(i) for i in t1.args))) and (PureComplexNumberQ(t2) or ProductQ(t2) and any(PureComplexNumberQ(i) for i in t2.args)):
5668            c = a/I
5669            d = b/I
5670            if NegativeQ(d):
5671                return RectifyTangent(u,-a,-b,-r,x)
5672            e = SmartDenominator(Together(c + d*x))
5673            c = c*e
5674            d = d*e
5675            if EvenQ(Denominator(NumericFactor(Together(u)))):
5676                return  I*r*Log(RemoveContent(Simplify((c+e)**2+d**2)-Simplify((c+e)**2-d**2)*Cos(2*u)+Simplify(2*(c+e)*d)*Sin(2*u),x))/4 - I*r*Log(RemoveContent(Simplify((c-e)**2+d**2)-Simplify((c-e)**2-d**2)*Cos(2*u)+Simplify(2*(c-e)*d)*Sin(2*u),x))/4
5677            return I*r*Log(RemoveContent(Simplify((c+e)**2)-Simplify((c+e)**2-d**2)*Cos(u)**2+Simplify(2*(c+e)*d)*Cos(u)*Sin(u),x))/4 - I*r*Log(RemoveContent(Simplify((c-e)**2)-Simplify((c-e)**2-d**2)*Cos(u)**2+Simplify(2*(c-e)*d)*Cos(u)*Sin(u),x))/4
5678        elif NegativeQ(b):
5679            return RectifyCotangent(u,-a,-b,-r,x)
5680        elif EvenQ(Denominator(NumericFactor(Together(u)))):
5681            return -r*SimplifyAntiderivative(u,x) - r*ArcTan(Simplify((2*a*b*Cos(2*u)+(1+a**2-b**2)*Sin(2*u))/(a**2+(1+b)**2-(1+a**2-b**2)*Cos(2*u)+2*a*b*Sin(2*u))))
5682        return -r*SimplifyAntiderivative(u,x) - r*ArcTan(ActivateTrig(Simplify((a*b-2*a*b*sin(u)**2+(1+a**2-b**2)*cos(u)*sin(u))/(b*(1+b)+(1+a**2-b**2)*sin(u)**2+2*a*b*cos(u)*sin(u)))))
5683
5684    u, a, b, x = args
5685    t = Together(a)
5686    if PureComplexNumberQ(t) or (ProductQ(t) and any(PureComplexNumberQ(i) for i in t.args)):
5687        c = a/I
5688        if NegativeQ(c):
5689            return RectifyCotangent(u,-a,-b,x)
5690        elif ZeroQ(c - 1):
5691            if EvenQ(Denominator(NumericFactor(Together(u)))):
5692                return -I*b*ArcTanh(Sin(2*u))/2
5693            return -I*b*ArcTanh(2*Cos(u)*Sin(u))/2
5694        e = SmartDenominator(c)
5695        c = c*e
5696        return -I*b*Log(RemoveContent(c*Cos(u)+e*Sin(u),x))/2 + I*b*Log(RemoveContent(c*Cos(u)-e*Sin(u),x))/2
5697    elif NegativeQ(a):
5698        return RectifyCotangent(u,-a,-b,x)
5699    elif ZeroQ(a-1):
5700        return b*SimplifyAntiderivative(u,x)
5701    elif EvenQ(Denominator(NumericFactor(Together(u)))):
5702        c = Simplify(a - 1)
5703        numr = SmartNumerator(c)
5704        denr = SmartDenominator(c)
5705        return b*SimplifyAntiderivative(u,x) - b*ArcTan(NormalizeLeadTermSigns(denr*Cos(u)*Sin(u)/(numr+denr*Cos(u)**2)))
5706    c = Simplify(a/(1-a))
5707    numr = SmartNumerator(c)
5708    denr = SmartDenominator(c)
5709    return b*SimplifyAntiderivative(u,x) + b*ArcTan(NormalizeLeadTermSigns(denr*Cos(u)*Sin(u)/(numr+denr*Sin(u)**2)))
5710
5711def Inequality(*args):
5712    f = args[1::2]
5713    e = args[0::2]
5714    r = []
5715    for i in range(0, len(f)):
5716        r.append(f[i](e[i], e[i + 1]))
5717    return all(r)
5718
5719def Condition(r, c):
5720    # returns r if c is True
5721    if c:
5722        return r
5723    else:
5724        raise NotImplementedError('In Condition()')
5725
5726def Simp(u, x):
5727    u = replace_pow_exp(u)
5728    return NormalizeSumFactors(SimpHelp(u, x))
5729
5730def SimpHelp(u, x):
5731    if AtomQ(u):
5732        return u
5733    elif FreeQ(u, x):
5734        v = SmartSimplify(u)
5735        if LeafCount(v) <= LeafCount(u):
5736            return v
5737        return u
5738    elif ProductQ(u):
5739        #m = MatchQ[Rest[u],a_.+n_*Pi+b_.*v_ /; FreeQ[{a,b},x] && Not[FreeQ[v,x]] && EqQ[n^2,1/4]]
5740        #if EqQ(First(u), S(1)/2) and m:
5741        #    if
5742        #If[EqQ[First[u],1/2] && MatchQ[Rest[u],a_.+n_*Pi+b_.*v_ /; FreeQ[{a,b},x] && Not[FreeQ[v,x]] && EqQ[n^2,1/4]],
5743        #  If[MatchQ[Rest[u],n_*Pi+b_.*v_ /; FreeQ[b,x] && Not[FreeQ[v,x]] && EqQ[n^2,1/4]],
5744        #    Map[Function[1/2*#],Rest[u]],
5745        #  If[MatchQ[Rest[u],m_*a_.+n_*Pi+p_*b_.*v_ /; FreeQ[{a,b},x] && Not[FreeQ[v,x]] && IntegersQ[m/2,p/2]],
5746        #    Map[Function[1/2*#],Rest[u]],
5747        #  u]],
5748
5749        v = FreeFactors(u, x)
5750        w = NonfreeFactors(u, x)
5751        v = NumericFactor(v)*SmartSimplify(NonnumericFactors(v)*x**2)/x**2
5752        if ProductQ(w):
5753            w = Mul(*[SimpHelp(i,x) for i in w.args])
5754        else:
5755            w = SimpHelp(w, x)
5756        w = FactorNumericGcd(w)
5757        v = MergeFactors(v, w)
5758        if ProductQ(v):
5759            return Mul(*[SimpFixFactor(i, x) for i in v.args])
5760        return v
5761    elif SumQ(u):
5762        Pi = pi
5763        a_ = Wild('a', exclude=[x])
5764        b_ = Wild('b', exclude=[x, 0])
5765        n_ = Wild('n', exclude=[x, 0, 0])
5766        pattern = a_ + n_*Pi + b_*x
5767        match = u.match(pattern)
5768        m = False
5769        if match:
5770            if EqQ(match[n_]**3, S(1)/16):
5771                m = True
5772        if m:
5773            return u
5774        elif PolynomialQ(u, x) and Exponent(u, x) <= 0:
5775            return SimpHelp(Coefficient(u, x, 0), x)
5776        elif PolynomialQ(u, x) and Exponent(u, x) == 1 and Coefficient(u, x, 0) == 0:
5777            return SimpHelp(Coefficient(u, x, 1), x)*x
5778
5779        v = 0
5780        w = 0
5781        for i in u.args:
5782            if FreeQ(i, x):
5783                v = i + v
5784            else:
5785                w = i + w
5786        v = SmartSimplify(v)
5787        if SumQ(w):
5788            w = Add(*[SimpHelp(i, x) for i in w.args])
5789        else:
5790            w = SimpHelp(w, x)
5791        return v + w
5792    return u.func(*[SimpHelp(i, x) for i in u.args])
5793
5794def SplitProduct(func, u):
5795    #(* If func[v] is True for a factor v of u, SplitProduct[func,u] returns {v, u/v} where v is the first such factor; else it returns False. *)
5796    if ProductQ(u):
5797        if func(First(u)):
5798            return [First(u), Rest(u)]
5799        lst = SplitProduct(func, Rest(u))
5800        if AtomQ(lst):
5801            return False
5802        return [lst[0], First(u)*lst[1]]
5803    if func(u):
5804        return [u, 1]
5805    return False
5806
5807def SplitSum(func, u):
5808    # (* If func[v] is nonatomic for a term v of u, SplitSum[func,u] returns {func[v], u-v} where v is the first such term; else it returns False. *)
5809    if SumQ(u):
5810        if Not(AtomQ(func(First(u)))):
5811            return [func(First(u)), Rest(u)]
5812        lst = SplitSum(func, Rest(u))
5813        if AtomQ(lst):
5814            return False
5815        return [lst[0], First(u) + lst[1]]
5816    elif Not(AtomQ(func(u))):
5817        return [func(u), 0]
5818    return False
5819
5820def SubstFor(*args):
5821    if len(args) == 4:
5822        w, v, u, x = args
5823        # u is a function of v. SubstFor(w,v,u,x) returns w times u with v replaced by x.
5824        return SimplifyIntegrand(w*SubstFor(v, u, x), x)
5825    v, u, x = args
5826    # u is a function of v. SubstFor(v, u, x) returns u with v replaced by x.
5827    if AtomQ(v):
5828        return Subst(u, v, x)
5829    elif Not(EqQ(FreeFactors(v, x), 1)):
5830        return SubstFor(NonfreeFactors(v, x), u, x/FreeFactors(v, x))
5831    elif SinQ(v):
5832        return SubstForTrig(u, x, Sqrt(1 - x**2), v.args[0], x)
5833    elif CosQ(v):
5834        return SubstForTrig(u, Sqrt(1 - x**2), x, v.args[0], x)
5835    elif TanQ(v):
5836        return SubstForTrig(u, x/Sqrt(1 + x**2), 1/Sqrt(1 + x**2), v.args[0], x)
5837    elif CotQ(v):
5838        return SubstForTrig(u, 1/Sqrt(1 + x**2), x/Sqrt(1 + x**2), v.args[0], x)
5839    elif SecQ(v):
5840        return SubstForTrig(u, 1/Sqrt(1 - x**2), 1/x, v.args[0], x)
5841    elif CscQ(v):
5842        return SubstForTrig(u, 1/x, 1/Sqrt(1 - x**2), v.args[0], x)
5843    elif SinhQ(v):
5844        return SubstForHyperbolic(u, x, Sqrt(1 + x**2), v.args[0], x)
5845    elif CoshQ(v):
5846        return SubstForHyperbolic(u, Sqrt( - 1 + x**2), x, v.args[0], x)
5847    elif TanhQ(v):
5848        return SubstForHyperbolic(u, x/Sqrt(1 - x**2), 1/Sqrt(1 - x**2), v.args[0], x)
5849    elif CothQ(v):
5850        return SubstForHyperbolic(u, 1/Sqrt( - 1 + x**2), x/Sqrt( - 1 + x**2), v.args[0], x)
5851    elif SechQ(v):
5852        return SubstForHyperbolic(u, 1/Sqrt( - 1 + x**2), 1/x, v.args[0], x)
5853    elif CschQ(v):
5854        return SubstForHyperbolic(u, 1/x, 1/Sqrt(1 + x**2), v.args[0], x)
5855    else:
5856        return SubstForAux(u, v, x)
5857
5858def SubstForAux(u, v, x):
5859    # u is a function of v. SubstForAux(u, v, x) returns u with v replaced by x.
5860    if u==v:
5861        return x
5862    elif AtomQ(u):
5863        if PowerQ(v):
5864            if FreeQ(v.exp, x) and ZeroQ(u - v.base):
5865                return x**Simplify(1/v.exp)
5866        return u
5867    elif PowerQ(u):
5868        if FreeQ(u.exp, x):
5869            if ZeroQ(u.base - v):
5870                return x**u.exp
5871            if PowerQ(v):
5872                if FreeQ(v.exp, x) and ZeroQ(u.base - v.base):
5873                    return x**Simplify(u.exp/v.exp)
5874            return SubstForAux(u.base, v, x)**u.exp
5875    elif ProductQ(u) and Not(EqQ(FreeFactors(u, x), 1)):
5876        return FreeFactors(u, x)*SubstForAux(NonfreeFactors(u, x), v, x)
5877    elif ProductQ(u) and ProductQ(v):
5878        return SubstForAux(First(u), First(v), x)
5879
5880    return u.func(*[SubstForAux(i, v, x) for i in u.args])
5881
5882def FresnelS(x):
5883    return fresnels(x)
5884
5885def FresnelC(x):
5886    return fresnelc(x)
5887
5888def Erf(x):
5889    return erf(x)
5890
5891def Erfc(x):
5892    return erfc(x)
5893
5894def Erfi(x):
5895    return erfi(x)
5896
5897class Gamma(Function):
5898    @classmethod
5899    def eval(cls,*args):
5900        a = args[0]
5901        if len(args) == 1:
5902            return gamma(a)
5903        else:
5904            b = args[1]
5905            if (NumericQ(a) and NumericQ(b)) or a == 1:
5906                return uppergamma(a, b)
5907
5908def FunctionOfTrigOfLinearQ(u, x):
5909    # If u is an algebraic function of trig functions of a linear function of x,
5910    # FunctionOfTrigOfLinearQ[u,x] returns True; else it returns False.
5911    if FunctionOfTrig(u, None, x) and AlgebraicTrigFunctionQ(u, x) and FunctionOfLinear(FunctionOfTrig(u, None, x), x):
5912        return True
5913    else:
5914        return False
5915
5916def ElementaryFunctionQ(u):
5917    # ElementaryExpressionQ[u] returns True if u is a sum, product, or power and all the operands
5918    # are elementary expressions; or if u is a call on a trig, hyperbolic, or inverse function
5919    # and all the arguments are elementary expressions; else it returns False.
5920    if AtomQ(u):
5921        return True
5922    elif SumQ(u) or ProductQ(u) or PowerQ(u) or TrigQ(u) or HyperbolicQ(u) or InverseFunctionQ(u):
5923        for i in u.args:
5924            if not ElementaryFunctionQ(i):
5925                return False
5926        return True
5927    return False
5928
5929def Complex(a, b):
5930    return a + I*b
5931
5932def UnsameQ(a, b):
5933    return a != b
5934
5935@doctest_depends_on(modules=('matchpy',))
5936def _SimpFixFactor():
5937    replacer = ManyToOneReplacer()
5938
5939    pattern1 = Pattern(UtilityOperator(Pow(Add(Mul(Complex(S(0), c_), WC('a', S(1))), Mul(Complex(S(0), d_), WC('b', S(1)))), WC('p', S(1))), x_), CustomConstraint(lambda p: IntegerQ(p)))
5940    rule1 = ReplacementRule(pattern1, lambda b, c, x, a, p, d : Mul(Pow(I, p), SimpFixFactor(Pow(Add(Mul(a, c), Mul(b, d)), p), x)))
5941    replacer.add(rule1)
5942
5943    pattern2 = Pattern(UtilityOperator(Pow(Add(Mul(Complex(S(0), d_), WC('a', S(1))), Mul(Complex(S(0), e_), WC('b', S(1))), Mul(Complex(S(0), f_), WC('c', S(1)))), WC('p', S(1))), x_), CustomConstraint(lambda p: IntegerQ(p)))
5944    rule2 = ReplacementRule(pattern2, lambda b, c, x, f, a, p, e, d : Mul(Pow(I, p), SimpFixFactor(Pow(Add(Mul(a, d), Mul(b, e), Mul(c, f)), p), x)))
5945    replacer.add(rule2)
5946
5947    pattern3 = Pattern(UtilityOperator(Pow(Add(Mul(WC('a', S(1)), Pow(c_, r_)), Mul(WC('b', S(1)), Pow(x_, WC('n', S(1))))), WC('p', S(1))), x_), CustomConstraint(lambda a, x: FreeQ(a, x)), CustomConstraint(lambda b, x: FreeQ(b, x)), CustomConstraint(lambda c, x: FreeQ(c, x)), CustomConstraint(lambda n, p: IntegersQ(n, p)), CustomConstraint(lambda c: AtomQ(c)), CustomConstraint(lambda r: RationalQ(r)), CustomConstraint(lambda r: Less(r, S(0))))
5948    rule3 = ReplacementRule(pattern3, lambda b, c, r, n, x, a, p : Mul(Pow(c, Mul(r, p)), SimpFixFactor(Pow(Add(a, Mul(Mul(b, Pow(Pow(c, r), S(-1))), Pow(x, n))), p), x)))
5949    replacer.add(rule3)
5950
5951    pattern4 = Pattern(UtilityOperator(Pow(Add(WC('a', S(0)), Mul(WC('b', S(1)), Pow(c_, r_), Pow(x_, WC('n', S(1))))), WC('p', S(1))), x_), CustomConstraint(lambda a, x: FreeQ(a, x)), CustomConstraint(lambda b, x: FreeQ(b, x)), CustomConstraint(lambda c, x: FreeQ(c, x)), CustomConstraint(lambda n, p: IntegersQ(n, p)), CustomConstraint(lambda c: AtomQ(c)), CustomConstraint(lambda r: RationalQ(r)), CustomConstraint(lambda r: Less(r, S(0))))
5952    rule4 = ReplacementRule(pattern4, lambda b, c, r, n, x, a, p : Mul(Pow(c, Mul(r, p)), SimpFixFactor(Pow(Add(Mul(a, Pow(Pow(c, r), S(-1))), Mul(b, Pow(x, n))), p), x)))
5953    replacer.add(rule4)
5954
5955    pattern5 = Pattern(UtilityOperator(Pow(Add(Mul(WC('a', S(1)), Pow(c_, WC('s', S(1)))), Mul(WC('b', S(1)), Pow(c_, WC('r', S(1))), Pow(x_, WC('n', S(1))))), WC('p', S(1))), x_), CustomConstraint(lambda a, x: FreeQ(a, x)), CustomConstraint(lambda b, x: FreeQ(b, x)), CustomConstraint(lambda c, x: FreeQ(c, x)), CustomConstraint(lambda n, p: IntegersQ(n, p)), CustomConstraint(lambda r, s: RationalQ(s, r)), CustomConstraint(lambda r, s: Inequality(S(0), Less, s, LessEqual, r)), CustomConstraint(lambda p, c, s: UnsameQ(Pow(c, Mul(s, p)), S(-1))))
5956    rule5 = ReplacementRule(pattern5, lambda b, c, r, n, x, a, p, s : Mul(Pow(c, Mul(s, p)), SimpFixFactor(Pow(Add(a, Mul(b, Pow(c, Add(r, Mul(S(-1), s))), Pow(x, n))), p), x)))
5957    replacer.add(rule5)
5958
5959    pattern6 = Pattern(UtilityOperator(Pow(Add(Mul(WC('a', S(1)), Pow(c_, WC('s', S(1)))), Mul(WC('b', S(1)), Pow(c_, WC('r', S(1))), Pow(x_, WC('n', S(1))))), WC('p', S(1))), x_), CustomConstraint(lambda a, x: FreeQ(a, x)), CustomConstraint(lambda b, x: FreeQ(b, x)), CustomConstraint(lambda c, x: FreeQ(c, x)), CustomConstraint(lambda n, p: IntegersQ(n, p)), CustomConstraint(lambda r, s: RationalQ(s, r)), CustomConstraint(lambda s, r: Less(S(0), r, s)), CustomConstraint(lambda p, c, r: UnsameQ(Pow(c, Mul(r, p)), S(-1))))
5960    rule6 = ReplacementRule(pattern6, lambda b, c, r, n, x, a, p, s : Mul(Pow(c, Mul(r, p)), SimpFixFactor(Pow(Add(Mul(a, Pow(c, Add(s, Mul(S(-1), r)))), Mul(b, Pow(x, n))), p), x)))
5961    replacer.add(rule6)
5962
5963    return replacer
5964
5965@doctest_depends_on(modules=('matchpy',))
5966def SimpFixFactor(expr, x):
5967    r = SimpFixFactor_replacer.replace(UtilityOperator(expr, x))
5968    if isinstance(r, UtilityOperator):
5969        return expr
5970    return r
5971
5972@doctest_depends_on(modules=('matchpy',))
5973def _FixSimplify():
5974    Plus = Add
5975    def cons_f1(n):
5976        return OddQ(n)
5977    cons1 = CustomConstraint(cons_f1)
5978
5979    def cons_f2(m):
5980        return RationalQ(m)
5981    cons2 = CustomConstraint(cons_f2)
5982
5983    def cons_f3(n):
5984        return FractionQ(n)
5985    cons3 = CustomConstraint(cons_f3)
5986
5987    def cons_f4(u):
5988        return SqrtNumberSumQ(u)
5989    cons4 = CustomConstraint(cons_f4)
5990
5991    def cons_f5(v):
5992        return SqrtNumberSumQ(v)
5993    cons5 = CustomConstraint(cons_f5)
5994
5995    def cons_f6(u):
5996        return PositiveQ(u)
5997    cons6 = CustomConstraint(cons_f6)
5998
5999    def cons_f7(v):
6000        return PositiveQ(v)
6001    cons7 = CustomConstraint(cons_f7)
6002
6003    def cons_f8(v):
6004        return SqrtNumberSumQ(S(1)/v)
6005    cons8 = CustomConstraint(cons_f8)
6006
6007    def cons_f9(m):
6008        return IntegerQ(m)
6009    cons9 = CustomConstraint(cons_f9)
6010
6011    def cons_f10(u):
6012        return NegativeQ(u)
6013    cons10 = CustomConstraint(cons_f10)
6014
6015    def cons_f11(n, m, a, b):
6016        return RationalQ(a, b, m, n)
6017    cons11 = CustomConstraint(cons_f11)
6018
6019    def cons_f12(a):
6020        return Greater(a, S(0))
6021    cons12 = CustomConstraint(cons_f12)
6022
6023    def cons_f13(b):
6024        return Greater(b, S(0))
6025    cons13 = CustomConstraint(cons_f13)
6026
6027    def cons_f14(p):
6028        return PositiveIntegerQ(p)
6029    cons14 = CustomConstraint(cons_f14)
6030
6031    def cons_f15(p):
6032        return IntegerQ(p)
6033    cons15 = CustomConstraint(cons_f15)
6034
6035    def cons_f16(p, n):
6036        return Greater(-n + p, S(0))
6037    cons16 = CustomConstraint(cons_f16)
6038
6039    def cons_f17(a, b):
6040        return SameQ(a + b, S(0))
6041    cons17 = CustomConstraint(cons_f17)
6042
6043    def cons_f18(n):
6044        return Not(IntegerQ(n))
6045    cons18 = CustomConstraint(cons_f18)
6046
6047    def cons_f19(c, a, b, d):
6048        return ZeroQ(-a*d + b*c)
6049    cons19 = CustomConstraint(cons_f19)
6050
6051    def cons_f20(a):
6052        return Not(RationalQ(a))
6053    cons20 = CustomConstraint(cons_f20)
6054
6055    def cons_f21(t):
6056        return IntegerQ(t)
6057    cons21 = CustomConstraint(cons_f21)
6058
6059    def cons_f22(n, m):
6060        return RationalQ(m, n)
6061    cons22 = CustomConstraint(cons_f22)
6062
6063    def cons_f23(n, m):
6064        return Inequality(S(0), Less, m, LessEqual, n)
6065    cons23 = CustomConstraint(cons_f23)
6066
6067    def cons_f24(p, n, m):
6068        return RationalQ(m, n, p)
6069    cons24 = CustomConstraint(cons_f24)
6070
6071    def cons_f25(p, n, m):
6072        return Inequality(S(0), Less, m, LessEqual, n, LessEqual, p)
6073    cons25 = CustomConstraint(cons_f25)
6074
6075    def cons_f26(p, n, m, q):
6076        return Inequality(S(0), Less, m, LessEqual, n, LessEqual, p, LessEqual, q)
6077    cons26 = CustomConstraint(cons_f26)
6078
6079    def cons_f27(w):
6080        return Not(RationalQ(w))
6081    cons27 = CustomConstraint(cons_f27)
6082
6083    def cons_f28(n):
6084        return Less(n, S(0))
6085    cons28 = CustomConstraint(cons_f28)
6086
6087    def cons_f29(n, w, v):
6088        return ZeroQ(v + w**(-n))
6089    cons29 = CustomConstraint(cons_f29)
6090
6091    def cons_f30(n):
6092        return IntegerQ(n)
6093    cons30 = CustomConstraint(cons_f30)
6094
6095    def cons_f31(w, v):
6096        return ZeroQ(v + w)
6097    cons31 = CustomConstraint(cons_f31)
6098
6099    def cons_f32(p, n):
6100        return IntegerQ(n/p)
6101    cons32 = CustomConstraint(cons_f32)
6102
6103    def cons_f33(w, v):
6104        return ZeroQ(v - w)
6105    cons33 = CustomConstraint(cons_f33)
6106
6107    def cons_f34(p, n):
6108        return IntegersQ(n, n/p)
6109    cons34 = CustomConstraint(cons_f34)
6110
6111    def cons_f35(a):
6112        return AtomQ(a)
6113    cons35 = CustomConstraint(cons_f35)
6114
6115    def cons_f36(b):
6116        return AtomQ(b)
6117    cons36 = CustomConstraint(cons_f36)
6118
6119    pattern1 = Pattern(UtilityOperator((w_ + Complex(S(0), b_)*WC('v', S(1)))**WC('n', S(1))*Complex(S(0), a_)*WC('u', S(1))), cons1)
6120    def replacement1(n, u, w, v, a, b):
6121        return (S(-1))**(n/S(2) + S(1)/2)*a*u*FixSimplify((b*v - w*Complex(S(0), S(1)))**n)
6122    rule1 = ReplacementRule(pattern1, replacement1)
6123    def With2(m, n, u, w, v):
6124        z = u**(m/GCD(m, n))*v**(n/GCD(m, n))
6125        if Or(AbsurdNumberQ(z), SqrtNumberSumQ(z)):
6126            return True
6127        return False
6128    pattern2 = Pattern(UtilityOperator(u_**WC('m', S(1))*v_**n_*WC('w', S(1))), cons2, cons3, cons4, cons5, cons6, cons7, CustomConstraint(With2))
6129    def replacement2(m, n, u, w, v):
6130        z = u**(m/GCD(m, n))*v**(n/GCD(m, n))
6131        return FixSimplify(w*z**GCD(m, n))
6132    rule2 = ReplacementRule(pattern2, replacement2)
6133    def With3(m, n, u, w, v):
6134        z = u**(m/GCD(m, -n))*v**(n/GCD(m, -n))
6135        if Or(AbsurdNumberQ(z), SqrtNumberSumQ(z)):
6136            return True
6137        return False
6138    pattern3 = Pattern(UtilityOperator(u_**WC('m', S(1))*v_**n_*WC('w', S(1))), cons2, cons3, cons4, cons8, cons6, cons7, CustomConstraint(With3))
6139    def replacement3(m, n, u, w, v):
6140        z = u**(m/GCD(m, -n))*v**(n/GCD(m, -n))
6141        return FixSimplify(w*z**GCD(m, -n))
6142    rule3 = ReplacementRule(pattern3, replacement3)
6143    def With4(m, n, u, w, v):
6144        z = v**(n/GCD(m, n))*(-u)**(m/GCD(m, n))
6145        if Or(AbsurdNumberQ(z), SqrtNumberSumQ(z)):
6146            return True
6147        return False
6148    pattern4 = Pattern(UtilityOperator(u_**WC('m', S(1))*v_**n_*WC('w', S(1))), cons9, cons3, cons4, cons5, cons10, cons7, CustomConstraint(With4))
6149    def replacement4(m, n, u, w, v):
6150        z = v**(n/GCD(m, n))*(-u)**(m/GCD(m, n))
6151        return FixSimplify(-w*z**GCD(m, n))
6152    rule4 = ReplacementRule(pattern4, replacement4)
6153    def With5(m, n, u, w, v):
6154        z = v**(n/GCD(m, -n))*(-u)**(m/GCD(m, -n))
6155        if Or(AbsurdNumberQ(z), SqrtNumberSumQ(z)):
6156            return True
6157        return False
6158    pattern5 = Pattern(UtilityOperator(u_**WC('m', S(1))*v_**n_*WC('w', S(1))), cons9, cons3, cons4, cons8, cons10, cons7, CustomConstraint(With5))
6159    def replacement5(m, n, u, w, v):
6160        z = v**(n/GCD(m, -n))*(-u)**(m/GCD(m, -n))
6161        return FixSimplify(-w*z**GCD(m, -n))
6162    rule5 = ReplacementRule(pattern5, replacement5)
6163    def With6(p, m, n, u, w, v, a, b):
6164        c = a**(m/p)*b**n
6165        if RationalQ(c):
6166            return True
6167        return False
6168    pattern6 = Pattern(UtilityOperator(a_**m_*(b_**n_*WC('v', S(1)) + u_)**WC('p', S(1))*WC('w', S(1))), cons11, cons12, cons13, cons14, CustomConstraint(With6))
6169    def replacement6(p, m, n, u, w, v, a, b):
6170        c = a**(m/p)*b**n
6171        return FixSimplify(w*(a**(m/p)*u + c*v)**p)
6172    rule6 = ReplacementRule(pattern6, replacement6)
6173    pattern7 = Pattern(UtilityOperator(a_**WC('m', S(1))*(a_**n_*WC('u', S(1)) + b_**WC('p', S(1))*WC('v', S(1)))*WC('w', S(1))), cons2, cons3, cons15, cons16, cons17)
6174    def replacement7(p, m, n, u, w, v, a, b):
6175        return FixSimplify(a**(m + n)*w*((S(-1))**p*a**(-n + p)*v + u))
6176    rule7 = ReplacementRule(pattern7, replacement7)
6177    def With8(m, d, n, w, c, a, b):
6178        q = b/d
6179        if FreeQ(q, Plus):
6180            return True
6181        return False
6182    pattern8 = Pattern(UtilityOperator((a_ + b_)**WC('m', S(1))*(c_ + d_)**n_*WC('w', S(1))), cons9, cons18, cons19, CustomConstraint(With8))
6183    def replacement8(m, d, n, w, c, a, b):
6184        q = b/d
6185        return FixSimplify(q**m*w*(c + d)**(m + n))
6186    rule8 = ReplacementRule(pattern8, replacement8)
6187    pattern9 = Pattern(UtilityOperator((a_**WC('m', S(1))*WC('u', S(1)) + a_**WC('n', S(1))*WC('v', S(1)))**WC('t', S(1))*WC('w', S(1))), cons20, cons21, cons22, cons23)
6188    def replacement9(m, n, u, w, v, a, t):
6189        return FixSimplify(a**(m*t)*w*(a**(-m + n)*v + u)**t)
6190    rule9 = ReplacementRule(pattern9, replacement9)
6191    pattern10 = Pattern(UtilityOperator((a_**WC('m', S(1))*WC('u', S(1)) + a_**WC('n', S(1))*WC('v', S(1)) + a_**WC('p', S(1))*WC('z', S(1)))**WC('t', S(1))*WC('w', S(1))), cons20, cons21, cons24, cons25)
6192    def replacement10(p, m, n, u, w, v, a, z, t):
6193        return FixSimplify(a**(m*t)*w*(a**(-m + n)*v + a**(-m + p)*z + u)**t)
6194    rule10 = ReplacementRule(pattern10, replacement10)
6195    pattern11 = Pattern(UtilityOperator((a_**WC('m', S(1))*WC('u', S(1)) + a_**WC('n', S(1))*WC('v', S(1)) + a_**WC('p', S(1))*WC('z', S(1)) + a_**WC('q', S(1))*WC('y', S(1)))**WC('t', S(1))*WC('w', S(1))), cons20, cons21, cons24, cons26)
6196    def replacement11(p, m, n, u, q, w, v, a, z, y, t):
6197        return FixSimplify(a**(m*t)*w*(a**(-m + n)*v + a**(-m + p)*z + a**(-m + q)*y + u)**t)
6198    rule11 = ReplacementRule(pattern11, replacement11)
6199    pattern12 = Pattern(UtilityOperator((sqrt(v_)*WC('b', S(1)) + sqrt(v_)*WC('c', S(1)) + sqrt(v_)*WC('d', S(1)) + sqrt(v_)*WC('a', S(1)) + WC('u', S(0)))*WC('w', S(1))))
6200    def replacement12(d, u, w, v, c, a, b):
6201        return FixSimplify(w*(u + sqrt(v)*FixSimplify(a + b + c + d)))
6202    rule12 = ReplacementRule(pattern12, replacement12)
6203    pattern13 = Pattern(UtilityOperator((sqrt(v_)*WC('b', S(1)) + sqrt(v_)*WC('c', S(1)) + sqrt(v_)*WC('a', S(1)) + WC('u', S(0)))*WC('w', S(1))))
6204    def replacement13(u, w, v, c, a, b):
6205        return FixSimplify(w*(u + sqrt(v)*FixSimplify(a + b + c)))
6206    rule13 = ReplacementRule(pattern13, replacement13)
6207    pattern14 = Pattern(UtilityOperator((sqrt(v_)*WC('b', S(1)) + sqrt(v_)*WC('a', S(1)) + WC('u', S(0)))*WC('w', S(1))))
6208    def replacement14(u, w, v, a, b):
6209        return FixSimplify(w*(u + sqrt(v)*FixSimplify(a + b)))
6210    rule14 = ReplacementRule(pattern14, replacement14)
6211    pattern15 = Pattern(UtilityOperator(v_**m_*w_**n_*WC('u', S(1))), cons2, cons27, cons3, cons28, cons29)
6212    def replacement15(m, n, u, w, v):
6213        return -FixSimplify(u*v**(m + S(-1)))
6214    rule15 = ReplacementRule(pattern15, replacement15)
6215    pattern16 = Pattern(UtilityOperator(v_**m_*w_**WC('n', S(1))*WC('u', S(1))), cons2, cons27, cons30, cons31)
6216    def replacement16(m, n, u, w, v):
6217        return (S(-1))**n*FixSimplify(u*v**(m + n))
6218    rule16 = ReplacementRule(pattern16, replacement16)
6219    pattern17 = Pattern(UtilityOperator(w_**WC('n', S(1))*(-v_**WC('p', S(1)))**m_*WC('u', S(1))), cons2, cons27, cons32, cons33)
6220    def replacement17(p, m, n, u, w, v):
6221        return (S(-1))**(n/p)*FixSimplify(u*(-v**p)**(m + n/p))
6222    rule17 = ReplacementRule(pattern17, replacement17)
6223    pattern18 = Pattern(UtilityOperator(w_**WC('n', S(1))*(-v_**WC('p', S(1)))**m_*WC('u', S(1))), cons2, cons27, cons34, cons31)
6224    def replacement18(p, m, n, u, w, v):
6225        return (S(-1))**(n + n/p)*FixSimplify(u*(-v**p)**(m + n/p))
6226    rule18 = ReplacementRule(pattern18, replacement18)
6227    pattern19 = Pattern(UtilityOperator((a_ - b_)**WC('m', S(1))*(a_ + b_)**WC('m', S(1))*WC('u', S(1))), cons9, cons35, cons36)
6228    def replacement19(m, u, a, b):
6229        return u*(a**S(2) - b**S(2))**m
6230    rule19 = ReplacementRule(pattern19, replacement19)
6231    pattern20 = Pattern(UtilityOperator((S(729)*c - e*(-S(20)*e + S(540)))**WC('m', S(1))*WC('u', S(1))), cons2)
6232    def replacement20(m, u):
6233        return u*(a*e**S(2) - b*d*e + c*d**S(2))**m
6234    rule20 = ReplacementRule(pattern20, replacement20)
6235    pattern21 = Pattern(UtilityOperator((S(729)*c + e*(S(20)*e + S(-540)))**WC('m', S(1))*WC('u', S(1))), cons2)
6236    def replacement21(m, u):
6237        return u*(a*e**S(2) - b*d*e + c*d**S(2))**m
6238    rule21 = ReplacementRule(pattern21, replacement21)
6239    pattern22 = Pattern(UtilityOperator(u_))
6240    def replacement22(u):
6241        return u
6242    rule22 = ReplacementRule(pattern22, replacement22)
6243    return [rule1, rule2, rule3, rule4, rule5, rule6, rule7, rule8, rule9, rule10, rule11, rule12, rule13, rule14, rule15, rule16, rule17, rule18, rule19, rule20, rule21, rule22, ]
6244
6245@doctest_depends_on(modules=('matchpy',))
6246def FixSimplify(expr):
6247    if isinstance(expr, (list, tuple, TupleArg)):
6248        return [replace_all(UtilityOperator(i), FixSimplify_rules) for i in expr]
6249    return replace_all(UtilityOperator(expr), FixSimplify_rules)
6250
6251@doctest_depends_on(modules=('matchpy',))
6252def _SimplifyAntiderivativeSum():
6253    replacer = ManyToOneReplacer()
6254
6255    pattern1 = Pattern(UtilityOperator(Add(Mul(Log(Add(a_, Mul(WC('b', S(1)), Pow(Tan(u_), WC('n', S(1)))))), WC('A', S(1))), Mul(Log(Cos(u_)), WC('B', S(1))), WC('v', S(0))), x_), CustomConstraint(lambda a, x: FreeQ(a, x)), CustomConstraint(lambda b, x: FreeQ(b, x)), CustomConstraint(lambda A, x: FreeQ(A, x)), CustomConstraint(lambda B, x: FreeQ(B, x)), CustomConstraint(lambda n: IntegerQ(n)), CustomConstraint(lambda B, A, n: ZeroQ(Add(Mul(n, A), Mul(S(1), B)))))
6256    rule1 = ReplacementRule(pattern1, lambda n, x, v, b, B, A, u, a : Add(SimplifyAntiderivativeSum(v, x), Mul(A, Log(RemoveContent(Add(Mul(a, Pow(Cos(u), n)), Mul(b, Pow(Sin(u), n))), x)))))
6257    replacer.add(rule1)
6258
6259    pattern2 = Pattern(UtilityOperator(Add(Mul(Log(Add(Mul(Pow(Cot(u_), WC('n', S(1))), WC('b', S(1))), a_)), WC('A', S(1))), Mul(Log(Sin(u_)), WC('B', S(1))), WC('v', S(0))), x_), CustomConstraint(lambda a, x: FreeQ(a, x)), CustomConstraint(lambda b, x: FreeQ(b, x)), CustomConstraint(lambda A, x: FreeQ(A, x)), CustomConstraint(lambda B, x: FreeQ(B, x)), CustomConstraint(lambda n: IntegerQ(n)), CustomConstraint(lambda B, A, n: ZeroQ(Add(Mul(n, A), Mul(S(1), B)))))
6260    rule2 = ReplacementRule(pattern2, lambda n, x, v, b, B, A, a, u : Add(SimplifyAntiderivativeSum(v, x), Mul(A, Log(RemoveContent(Add(Mul(a, Pow(Sin(u), n)), Mul(b, Pow(Cos(u), n))), x)))))
6261    replacer.add(rule2)
6262
6263    pattern3 = Pattern(UtilityOperator(Add(Mul(Log(Add(a_, Mul(WC('b', S(1)), Pow(Tan(u_), WC('n', S(1)))))), WC('A', S(1))), Mul(Log(Add(c_, Mul(WC('d', S(1)), Pow(Tan(u_), WC('n', S(1)))))), WC('B', S(1))), WC('v', S(0))), x_), CustomConstraint(lambda a, x: FreeQ(a, x)), CustomConstraint(lambda b, x: FreeQ(b, x)), CustomConstraint(lambda c, x: FreeQ(c, x)), CustomConstraint(lambda d, x: FreeQ(d, x)), CustomConstraint(lambda A, x: FreeQ(A, x)), CustomConstraint(lambda B, x: FreeQ(B, x)), CustomConstraint(lambda n: IntegerQ(n)), CustomConstraint(lambda B, A: ZeroQ(Add(A, B))))
6264    rule3 = ReplacementRule(pattern3, lambda n, x, v, b, A, B, u, c, d, a : Add(SimplifyAntiderivativeSum(v, x), Mul(A, Log(RemoveContent(Add(Mul(a, Pow(Cos(u), n)), Mul(b, Pow(Sin(u), n))), x))), Mul(B, Log(RemoveContent(Add(Mul(c, Pow(Cos(u), n)), Mul(d, Pow(Sin(u), n))), x)))))
6265    replacer.add(rule3)
6266
6267    pattern4 = Pattern(UtilityOperator(Add(Mul(Log(Add(Mul(Pow(Cot(u_), WC('n', S(1))), WC('b', S(1))), a_)), WC('A', S(1))), Mul(Log(Add(Mul(Pow(Cot(u_), WC('n', S(1))), WC('d', S(1))), c_)), WC('B', S(1))), WC('v', S(0))), x_), CustomConstraint(lambda a, x: FreeQ(a, x)), CustomConstraint(lambda b, x: FreeQ(b, x)), CustomConstraint(lambda c, x: FreeQ(c, x)), CustomConstraint(lambda d, x: FreeQ(d, x)), CustomConstraint(lambda A, x: FreeQ(A, x)), CustomConstraint(lambda B, x: FreeQ(B, x)), CustomConstraint(lambda n: IntegerQ(n)), CustomConstraint(lambda B, A: ZeroQ(Add(A, B))))
6268    rule4 = ReplacementRule(pattern4, lambda n, x, v, b, A, B, c, a, d, u : Add(SimplifyAntiderivativeSum(v, x), Mul(A, Log(RemoveContent(Add(Mul(b, Pow(Cos(u), n)), Mul(a, Pow(Sin(u), n))), x))), Mul(B, Log(RemoveContent(Add(Mul(d, Pow(Cos(u), n)), Mul(c, Pow(Sin(u), n))), x)))))
6269    replacer.add(rule4)
6270
6271    pattern5 = Pattern(UtilityOperator(Add(Mul(Log(Add(a_, Mul(WC('b', S(1)), Pow(Tan(u_), WC('n', S(1)))))), WC('A', S(1))), Mul(Log(Add(c_, Mul(WC('d', S(1)), Pow(Tan(u_), WC('n', S(1)))))), WC('B', S(1))), Mul(Log(Add(e_, Mul(WC('f', S(1)), Pow(Tan(u_), WC('n', S(1)))))), WC('C', S(1))), WC('v', S(0))), x_), CustomConstraint(lambda a, x: FreeQ(a, x)), CustomConstraint(lambda b, x: FreeQ(b, x)), CustomConstraint(lambda c, x: FreeQ(c, x)), CustomConstraint(lambda d, x: FreeQ(d, x)), CustomConstraint(lambda e, x: FreeQ(e, x)), CustomConstraint(lambda f, x: FreeQ(f, x)), CustomConstraint(lambda A, x: FreeQ(A, x)), CustomConstraint(lambda B, x: FreeQ(B, x)), CustomConstraint(lambda C, x: FreeQ(C, x)), CustomConstraint(lambda n: IntegerQ(n)), CustomConstraint(lambda B, A, C: ZeroQ(Add(A, B, C))))
6272    rule5 = ReplacementRule(pattern5, lambda n, e, x, v, b, A, B, u, c, f, d, a, C : Add(SimplifyAntiderivativeSum(v, x), Mul(A, Log(RemoveContent(Add(Mul(a, Pow(Cos(u), n)), Mul(b, Pow(Sin(u), n))), x))), Mul(B, Log(RemoveContent(Add(Mul(c, Pow(Cos(u), n)), Mul(d, Pow(Sin(u), n))), x))), Mul(C, Log(RemoveContent(Add(Mul(e, Pow(Cos(u), n)), Mul(f, Pow(Sin(u), n))), x)))))
6273    replacer.add(rule5)
6274
6275    pattern6 = Pattern(UtilityOperator(Add(Mul(Log(Add(Mul(Pow(Cot(u_), WC('n', S(1))), WC('b', S(1))), a_)), WC('A', S(1))), Mul(Log(Add(Mul(Pow(Cot(u_), WC('n', S(1))), WC('d', S(1))), c_)), WC('B', S(1))), Mul(Log(Add(Mul(Pow(Cot(u_), WC('n', S(1))), WC('f', S(1))), e_)), WC('C', S(1))), WC('v', S(0))), x_), CustomConstraint(lambda a, x: FreeQ(a, x)), CustomConstraint(lambda b, x: FreeQ(b, x)), CustomConstraint(lambda c, x: FreeQ(c, x)), CustomConstraint(lambda d, x: FreeQ(d, x)), CustomConstraint(lambda e, x: FreeQ(e, x)), CustomConstraint(lambda f, x: FreeQ(f, x)), CustomConstraint(lambda A, x: FreeQ(A, x)), CustomConstraint(lambda B, x: FreeQ(B, x)), CustomConstraint(lambda C, x: FreeQ(C, x)), CustomConstraint(lambda n: IntegerQ(n)), CustomConstraint(lambda B, A, C: ZeroQ(Add(A, B, C))))
6276    rule6 = ReplacementRule(pattern6, lambda n, e, x, v, b, A, B, c, a, f, d, u, C : Add(SimplifyAntiderivativeSum(v, x), Mul(A, Log(RemoveContent(Add(Mul(b, Pow(Cos(u), n)), Mul(a, Pow(Sin(u), n))), x))), Mul(B, Log(RemoveContent(Add(Mul(d, Pow(Cos(u), n)), Mul(c, Pow(Sin(u), n))), x))), Mul(C, Log(RemoveContent(Add(Mul(f, Pow(Cos(u), n)), Mul(e, Pow(Sin(u), n))), x)))))
6277    replacer.add(rule6)
6278
6279    return replacer
6280
6281@doctest_depends_on(modules=('matchpy',))
6282def SimplifyAntiderivativeSum(expr, x):
6283    r = SimplifyAntiderivativeSum_replacer.replace(UtilityOperator(expr, x))
6284    if isinstance(r, UtilityOperator):
6285        return expr
6286    return r
6287
6288@doctest_depends_on(modules=('matchpy',))
6289def _SimplifyAntiderivative():
6290    replacer = ManyToOneReplacer()
6291
6292    pattern2 = Pattern(UtilityOperator(Log(Mul(c_, u_)), x_), CustomConstraint(lambda c, x: FreeQ(c, x)))
6293    rule2 = ReplacementRule(pattern2, lambda x, c, u : SimplifyAntiderivative(Log(u), x))
6294    replacer.add(rule2)
6295
6296    pattern3 = Pattern(UtilityOperator(Log(Pow(u_, n_)), x_), CustomConstraint(lambda n, x: FreeQ(n, x)))
6297    rule3 = ReplacementRule(pattern3, lambda x, n, u : Mul(n, SimplifyAntiderivative(Log(u), x)))
6298    replacer.add(rule3)
6299
6300    pattern7 = Pattern(UtilityOperator(Log(Pow(f_, u_)), x_), CustomConstraint(lambda f, x: FreeQ(f, x)))
6301    rule7 = ReplacementRule(pattern7, lambda x, f, u : Mul(Log(f), SimplifyAntiderivative(u, x)))
6302    replacer.add(rule7)
6303
6304    pattern8 = Pattern(UtilityOperator(Log(Add(a_, Mul(WC('b', S(1)), Tan(u_)))), x_), CustomConstraint(lambda a, x: FreeQ(a, x)), CustomConstraint(lambda b, x: FreeQ(b, x)), CustomConstraint(lambda b, a: ZeroQ(Add(Pow(a, S(2)), Pow(b, S(2))))))
6305    rule8 = ReplacementRule(pattern8, lambda x, b, u, a : Add(Mul(Mul(b, Pow(a, S(1))), SimplifyAntiderivative(u, x)), Mul(S(1), SimplifyAntiderivative(Log(Cos(u)), x))))
6306    replacer.add(rule8)
6307
6308    pattern9 = Pattern(UtilityOperator(Log(Add(Mul(Cot(u_), WC('b', S(1))), a_)), x_), CustomConstraint(lambda a, x: FreeQ(a, x)), CustomConstraint(lambda b, x: FreeQ(b, x)), CustomConstraint(lambda b, a: ZeroQ(Add(Pow(a, S(2)), Pow(b, S(2))))))
6309    rule9 = ReplacementRule(pattern9, lambda x, b, u, a : Add(Mul(Mul(Mul(S(1), b), Pow(a, S(1))), SimplifyAntiderivative(u, x)), Mul(S(1), SimplifyAntiderivative(Log(Sin(u)), x))))
6310    replacer.add(rule9)
6311
6312    pattern10 = Pattern(UtilityOperator(ArcTan(Mul(WC('a', S(1)), Tan(u_))), x_), CustomConstraint(lambda a, x: FreeQ(a, x)), CustomConstraint(lambda a: PositiveQ(Pow(a, S(2)))), CustomConstraint(lambda u: ComplexFreeQ(u)))
6313    rule10 = ReplacementRule(pattern10, lambda x, u, a : RectifyTangent(u, a, S(1), x))
6314    replacer.add(rule10)
6315
6316    pattern11 = Pattern(UtilityOperator(ArcCot(Mul(WC('a', S(1)), Tan(u_))), x_), CustomConstraint(lambda a, x: FreeQ(a, x)), CustomConstraint(lambda a: PositiveQ(Pow(a, S(2)))), CustomConstraint(lambda u: ComplexFreeQ(u)))
6317    rule11 = ReplacementRule(pattern11, lambda x, u, a : RectifyTangent(u, a, S(1), x))
6318    replacer.add(rule11)
6319
6320    pattern12 = Pattern(UtilityOperator(ArcCot(Mul(WC('a', S(1)), Tanh(u_))), x_), CustomConstraint(lambda a, x: FreeQ(a, x)), CustomConstraint(lambda u: ComplexFreeQ(u)))
6321    rule12 = ReplacementRule(pattern12, lambda x, u, a : Mul(S(1), SimplifyAntiderivative(ArcTan(Mul(a, Tanh(u))), x)))
6322    replacer.add(rule12)
6323
6324    pattern13 = Pattern(UtilityOperator(ArcTanh(Mul(WC('a', S(1)), Tan(u_))), x_), CustomConstraint(lambda a, x: FreeQ(a, x)), CustomConstraint(lambda a: PositiveQ(Pow(a, S(2)))), CustomConstraint(lambda u: ComplexFreeQ(u)))
6325    rule13 = ReplacementRule(pattern13, lambda x, u, a : RectifyTangent(u, Mul(I, a), Mul(S(1), I), x))
6326    replacer.add(rule13)
6327
6328    pattern14 = Pattern(UtilityOperator(ArcCoth(Mul(WC('a', S(1)), Tan(u_))), x_), CustomConstraint(lambda a, x: FreeQ(a, x)), CustomConstraint(lambda a: PositiveQ(Pow(a, S(2)))), CustomConstraint(lambda u: ComplexFreeQ(u)))
6329    rule14 = ReplacementRule(pattern14, lambda x, u, a : RectifyTangent(u, Mul(I, a), Mul(S(1), I), x))
6330    replacer.add(rule14)
6331
6332    pattern15 = Pattern(UtilityOperator(ArcTanh(Tanh(u_)), x_))
6333    rule15 = ReplacementRule(pattern15, lambda x, u : SimplifyAntiderivative(u, x))
6334    replacer.add(rule15)
6335
6336    pattern16 = Pattern(UtilityOperator(ArcCoth(Tanh(u_)), x_))
6337    rule16 = ReplacementRule(pattern16, lambda x, u : SimplifyAntiderivative(u, x))
6338    replacer.add(rule16)
6339
6340    pattern17 = Pattern(UtilityOperator(ArcCot(Mul(Cot(u_), WC('a', S(1)))), x_), CustomConstraint(lambda a, x: FreeQ(a, x)), CustomConstraint(lambda a: PositiveQ(Pow(a, S(2)))), CustomConstraint(lambda u: ComplexFreeQ(u)))
6341    rule17 = ReplacementRule(pattern17, lambda x, u, a : RectifyCotangent(u, a, S(1), x))
6342    replacer.add(rule17)
6343
6344    pattern18 = Pattern(UtilityOperator(ArcTan(Mul(Cot(u_), WC('a', S(1)))), x_), CustomConstraint(lambda a, x: FreeQ(a, x)), CustomConstraint(lambda a: PositiveQ(Pow(a, S(2)))), CustomConstraint(lambda u: ComplexFreeQ(u)))
6345    rule18 = ReplacementRule(pattern18, lambda x, u, a : RectifyCotangent(u, a, S(1), x))
6346    replacer.add(rule18)
6347
6348    pattern19 = Pattern(UtilityOperator(ArcTan(Mul(Coth(u_), WC('a', S(1)))), x_), CustomConstraint(lambda a, x: FreeQ(a, x)), CustomConstraint(lambda u: ComplexFreeQ(u)))
6349    rule19 = ReplacementRule(pattern19, lambda x, u, a : Mul(S(1), SimplifyAntiderivative(ArcTan(Mul(Tanh(u), Pow(a, S(1)))), x)))
6350    replacer.add(rule19)
6351
6352    pattern20 = Pattern(UtilityOperator(ArcCoth(Mul(Cot(u_), WC('a', S(1)))), x_), CustomConstraint(lambda a, x: FreeQ(a, x)), CustomConstraint(lambda a: PositiveQ(Pow(a, S(2)))), CustomConstraint(lambda u: ComplexFreeQ(u)))
6353    rule20 = ReplacementRule(pattern20, lambda x, u, a : RectifyCotangent(u, Mul(I, a), I, x))
6354    replacer.add(rule20)
6355
6356    pattern21 = Pattern(UtilityOperator(ArcTanh(Mul(Cot(u_), WC('a', S(1)))), x_), CustomConstraint(lambda a, x: FreeQ(a, x)), CustomConstraint(lambda a: PositiveQ(Pow(a, S(2)))), CustomConstraint(lambda u: ComplexFreeQ(u)))
6357    rule21 = ReplacementRule(pattern21, lambda x, u, a : RectifyCotangent(u, Mul(I, a), I, x))
6358    replacer.add(rule21)
6359
6360    pattern22 = Pattern(UtilityOperator(ArcCoth(Coth(u_)), x_))
6361    rule22 = ReplacementRule(pattern22, lambda x, u : SimplifyAntiderivative(u, x))
6362    replacer.add(rule22)
6363
6364    pattern23 = Pattern(UtilityOperator(ArcTanh(Mul(Coth(u_), WC('a', S(1)))), x_), CustomConstraint(lambda a, x: FreeQ(a, x)), CustomConstraint(lambda u: ComplexFreeQ(u)))
6365    rule23 = ReplacementRule(pattern23, lambda x, u, a : SimplifyAntiderivative(ArcTanh(Mul(Tanh(u), Pow(a, S(1)))), x))
6366    replacer.add(rule23)
6367
6368    pattern24 = Pattern(UtilityOperator(ArcTanh(Coth(u_)), x_))
6369    rule24 = ReplacementRule(pattern24, lambda x, u : SimplifyAntiderivative(u, x))
6370    replacer.add(rule24)
6371
6372    pattern25 = Pattern(UtilityOperator(ArcTan(Mul(WC('c', S(1)), Add(a_, Mul(WC('b', S(1)), Tan(u_))))), x_), CustomConstraint(lambda a, x: FreeQ(a, x)), CustomConstraint(lambda b, x: FreeQ(b, x)), CustomConstraint(lambda c, x: FreeQ(c, x)), CustomConstraint(lambda c, a: PositiveQ(Mul(Pow(a, S(2)), Pow(c, S(2))))), CustomConstraint(lambda c, b: PositiveQ(Mul(Pow(b, S(2)), Pow(c, S(2))))), CustomConstraint(lambda u: ComplexFreeQ(u)))
6373    rule25 = ReplacementRule(pattern25, lambda x, a, b, u, c : RectifyTangent(u, Mul(a, c), Mul(b, c), S(1), x))
6374    replacer.add(rule25)
6375
6376    pattern26 = Pattern(UtilityOperator(ArcTanh(Mul(WC('c', S(1)), Add(a_, Mul(WC('b', S(1)), Tan(u_))))), x_), CustomConstraint(lambda a, x: FreeQ(a, x)), CustomConstraint(lambda b, x: FreeQ(b, x)), CustomConstraint(lambda c, x: FreeQ(c, x)), CustomConstraint(lambda c, a: PositiveQ(Mul(Pow(a, S(2)), Pow(c, S(2))))), CustomConstraint(lambda c, b: PositiveQ(Mul(Pow(b, S(2)), Pow(c, S(2))))), CustomConstraint(lambda u: ComplexFreeQ(u)))
6377    rule26 = ReplacementRule(pattern26, lambda x, a, b, u, c : RectifyTangent(u, Mul(I, a, c), Mul(I, b, c), Mul(S(1), I), x))
6378    replacer.add(rule26)
6379
6380    pattern27 = Pattern(UtilityOperator(ArcTan(Mul(WC('c', S(1)), Add(Mul(Cot(u_), WC('b', S(1))), a_))), x_), CustomConstraint(lambda a, x: FreeQ(a, x)), CustomConstraint(lambda b, x: FreeQ(b, x)), CustomConstraint(lambda c, x: FreeQ(c, x)), CustomConstraint(lambda c, a: PositiveQ(Mul(Pow(a, S(2)), Pow(c, S(2))))), CustomConstraint(lambda c, b: PositiveQ(Mul(Pow(b, S(2)), Pow(c, S(2))))), CustomConstraint(lambda u: ComplexFreeQ(u)))
6381    rule27 = ReplacementRule(pattern27, lambda x, a, b, u, c : RectifyCotangent(u, Mul(a, c), Mul(b, c), S(1), x))
6382    replacer.add(rule27)
6383
6384    pattern28 = Pattern(UtilityOperator(ArcTanh(Mul(WC('c', S(1)), Add(Mul(Cot(u_), WC('b', S(1))), a_))), x_), CustomConstraint(lambda a, x: FreeQ(a, x)), CustomConstraint(lambda b, x: FreeQ(b, x)), CustomConstraint(lambda c, x: FreeQ(c, x)), CustomConstraint(lambda c, a: PositiveQ(Mul(Pow(a, S(2)), Pow(c, S(2))))), CustomConstraint(lambda c, b: PositiveQ(Mul(Pow(b, S(2)), Pow(c, S(2))))), CustomConstraint(lambda u: ComplexFreeQ(u)))
6385    rule28 = ReplacementRule(pattern28, lambda x, a, b, u, c : RectifyCotangent(u, Mul(I, a, c), Mul(I, b, c), Mul(S(1), I), x))
6386    replacer.add(rule28)
6387
6388    pattern29 = Pattern(UtilityOperator(ArcTan(Add(WC('a', S(0)), Mul(WC('b', S(1)), Tan(u_)), Mul(WC('c', S(1)), Pow(Tan(u_), S(2))))), x_), CustomConstraint(lambda a, x: FreeQ(a, x)), CustomConstraint(lambda b, x: FreeQ(b, x)), CustomConstraint(lambda c, x: FreeQ(c, x)), CustomConstraint(lambda u: ComplexFreeQ(u)))
6389    rule29 = ReplacementRule(pattern29, lambda x, a, b, u, c : If(EvenQ(Denominator(NumericFactor(Together(u)))), ArcTan(NormalizeTogether(Mul(Add(a, c, S(1), Mul(Add(a, Mul(S(1), c), S(1)), Cos(Mul(S(2), u))), Mul(b, Sin(Mul(S(2), u)))), Pow(Add(a, c, S(1), Mul(Add(a, Mul(S(1), c), S(1)), Cos(Mul(S(2), u))), Mul(b, Sin(Mul(S(2), u)))), S(1))))), ArcTan(NormalizeTogether(Mul(Add(c, Mul(Add(a, Mul(S(1), c), S(1)), Pow(Cos(u), S(2))), Mul(b, Cos(u), Sin(u))), Pow(Add(c, Mul(Add(a, Mul(S(1), c), S(1)), Pow(Cos(u), S(2))), Mul(b, Cos(u), Sin(u))), S(1)))))))
6390    replacer.add(rule29)
6391
6392    pattern30 = Pattern(UtilityOperator(ArcTan(Add(WC('a', S(0)), Mul(WC('b', S(1)), Add(WC('d', S(0)), Mul(WC('e', S(1)), Tan(u_)))), Mul(WC('c', S(1)), Pow(Add(WC('f', S(0)), Mul(WC('g', S(1)), Tan(u_))), S(2))))), x_), CustomConstraint(lambda a, x: FreeQ(a, x)), CustomConstraint(lambda b, x: FreeQ(b, x)), CustomConstraint(lambda c, x: FreeQ(c, x)), CustomConstraint(lambda u: ComplexFreeQ(u)))
6393    rule30 = ReplacementRule(pattern30, lambda x, d, a, e, f, b, u, c, g : SimplifyAntiderivative(ArcTan(Add(a, Mul(b, d), Mul(c, Pow(f, S(2))), Mul(Add(Mul(b, e), Mul(S(2), c, f, g)), Tan(u)), Mul(c, Pow(g, S(2)), Pow(Tan(u), S(2))))), x))
6394    replacer.add(rule30)
6395
6396    pattern31 = Pattern(UtilityOperator(ArcTan(Add(WC('a', S(0)), Mul(WC('c', S(1)), Pow(Tan(u_), S(2))))), x_), CustomConstraint(lambda a, x: FreeQ(a, x)), CustomConstraint(lambda c, x: FreeQ(c, x)), CustomConstraint(lambda u: ComplexFreeQ(u)))
6397    rule31 = ReplacementRule(pattern31, lambda x, c, u, a : If(EvenQ(Denominator(NumericFactor(Together(u)))), ArcTan(NormalizeTogether(Mul(Add(a, c, S(1), Mul(Add(a, Mul(S(1), c), S(1)), Cos(Mul(S(2), u)))), Pow(Add(a, c, S(1), Mul(Add(a, Mul(S(1), c), S(1)), Cos(Mul(S(2), u)))), S(1))))), ArcTan(NormalizeTogether(Mul(Add(c, Mul(Add(a, Mul(S(1), c), S(1)), Pow(Cos(u), S(2)))), Pow(Add(c, Mul(Add(a, Mul(S(1), c), S(1)), Pow(Cos(u), S(2)))), S(1)))))))
6398    replacer.add(rule31)
6399
6400    pattern32 = Pattern(UtilityOperator(ArcTan(Add(WC('a', S(0)), Mul(WC('c', S(1)), Pow(Add(WC('f', S(0)), Mul(WC('g', S(1)), Tan(u_))), S(2))))), x_), CustomConstraint(lambda a, x: FreeQ(a, x)), CustomConstraint(lambda c, x: FreeQ(c, x)), CustomConstraint(lambda u: ComplexFreeQ(u)))
6401    rule32 = ReplacementRule(pattern32, lambda x, a, f, u, c, g : SimplifyAntiderivative(ArcTan(Add(a, Mul(c, Pow(f, S(2))), Mul(Mul(S(2), c, f, g), Tan(u)), Mul(c, Pow(g, S(2)), Pow(Tan(u), S(2))))), x))
6402    replacer.add(rule32)
6403
6404    return replacer
6405
6406@doctest_depends_on(modules=('matchpy',))
6407def SimplifyAntiderivative(expr, x):
6408    r = SimplifyAntiderivative_replacer.replace(UtilityOperator(expr, x))
6409    if isinstance(r, UtilityOperator):
6410        if ProductQ(expr):
6411            u, c = S(1), S(1)
6412            for i in expr.args:
6413                if FreeQ(i, x):
6414                    c *= i
6415                else:
6416                    u *= i
6417            if FreeQ(c, x) and c != S(1):
6418                v = SimplifyAntiderivative(u, x)
6419                if SumQ(v) and NonsumQ(u):
6420                    return Add(*[c*i for i in v.args])
6421                return c*v
6422        elif LogQ(expr):
6423            F = expr.args[0]
6424            if MemberQ([cot, sec, csc, coth, sech, csch], Head(F)):
6425                return -SimplifyAntiderivative(Log(1/F), x)
6426        if MemberQ([Log, atan, acot], Head(expr)):
6427            F = Head(expr)
6428            G = expr.args[0]
6429            if MemberQ([cot, sec, csc, coth, sech, csch], Head(G)):
6430                return -SimplifyAntiderivative(F(1/G), x)
6431        if MemberQ([atanh, acoth], Head(expr)):
6432            F = Head(expr)
6433            G = expr.args[0]
6434            if MemberQ([cot, sec, csc, coth, sech, csch], Head(G)):
6435                return SimplifyAntiderivative(F(1/G), x)
6436        u = expr
6437        if FreeQ(u, x):
6438            return S(0)
6439        elif LogQ(u):
6440            return Log(RemoveContent(u.args[0], x))
6441        elif SumQ(u):
6442            return SimplifyAntiderivativeSum(Add(*[SimplifyAntiderivative(i, x) for i in u.args]), x)
6443        return u
6444    else:
6445        return r
6446
6447@doctest_depends_on(modules=('matchpy',))
6448def _TrigSimplifyAux():
6449    replacer = ManyToOneReplacer()
6450
6451    pattern1 = Pattern(UtilityOperator(Mul(WC('u', S(1)), Pow(Add(Mul(WC('a', S(1)), Pow(v_, WC('m', S(1)))), Mul(WC('b', S(1)), Pow(v_, WC('n', S(1))))), p_))), CustomConstraint(lambda v: InertTrigQ(v)), CustomConstraint(lambda p: IntegerQ(p)), CustomConstraint(lambda n, m: RationalQ(m, n)), CustomConstraint(lambda n, m: Less(m, n)))
6452    rule1 = ReplacementRule(pattern1, lambda n, a, p, m, u, v, b : Mul(u, Pow(v, Mul(m, p)), Pow(TrigSimplifyAux(Add(a, Mul(b, Pow(v, Add(n, Mul(S(-1), m)))))), p)))
6453    replacer.add(rule1)
6454
6455    pattern2 = Pattern(UtilityOperator(Add(Mul(Pow(cos(u_), S('2')), WC('a', S(1))), WC('v', S(0)), Mul(WC('b', S(1)), Pow(sin(u_), S('2'))))), CustomConstraint(lambda b, a: SameQ(a, b)))
6456    rule2 = ReplacementRule(pattern2, lambda u, v, b, a : Add(a, v))
6457    replacer.add(rule2)
6458
6459    pattern3 = Pattern(UtilityOperator(Add(WC('v', S(0)), Mul(WC('a', S(1)), Pow(sec(u_), S('2'))), Mul(WC('b', S(1)), Pow(tan(u_), S('2'))))), CustomConstraint(lambda b, a: SameQ(a, Mul(S(-1), b))))
6460    rule3 = ReplacementRule(pattern3, lambda u, v, b, a : Add(a, v))
6461    replacer.add(rule3)
6462
6463    pattern4 = Pattern(UtilityOperator(Add(Mul(Pow(csc(u_), S('2')), WC('a', S(1))), Mul(Pow(cot(u_), S('2')), WC('b', S(1))), WC('v', S(0)))), CustomConstraint(lambda b, a: SameQ(a, Mul(S(-1), b))))
6464    rule4 = ReplacementRule(pattern4, lambda u, v, b, a : Add(a, v))
6465    replacer.add(rule4)
6466
6467    pattern5 = Pattern(UtilityOperator(Pow(Add(Mul(Pow(cos(u_), S('2')), WC('a', S(1))), WC('v', S(0)), Mul(WC('b', S(1)), Pow(sin(u_), S('2')))), n_)))
6468    rule5 = ReplacementRule(pattern5, lambda n, a, u, v, b : Pow(Add(Mul(Add(b, Mul(S(-1), a)), Pow(Sin(u), S('2'))), a, v), n))
6469    replacer.add(rule5)
6470
6471    pattern6 = Pattern(UtilityOperator(Add(WC('w', S(0)), u_, Mul(WC('v', S(1)), Pow(sin(z_), S('2'))))), CustomConstraint(lambda u, v: SameQ(u, Mul(S(-1), v))))
6472    rule6 = ReplacementRule(pattern6, lambda u, w, z, v : Add(Mul(u, Pow(Cos(z), S('2'))), w))
6473    replacer.add(rule6)
6474
6475    pattern7 = Pattern(UtilityOperator(Add(Mul(Pow(cos(z_), S('2')), WC('v', S(1))), WC('w', S(0)), u_)), CustomConstraint(lambda u, v: SameQ(u, Mul(S(-1), v))))
6476    rule7 = ReplacementRule(pattern7, lambda z, w, v, u : Add(Mul(u, Pow(Sin(z), S('2'))), w))
6477    replacer.add(rule7)
6478
6479    pattern8 = Pattern(UtilityOperator(Add(WC('w', S(0)), u_, Mul(WC('v', S(1)), Pow(tan(z_), S('2'))))), CustomConstraint(lambda u, v: SameQ(u, v)))
6480    rule8 = ReplacementRule(pattern8, lambda u, w, z, v : Add(Mul(u, Pow(Sec(z), S('2'))), w))
6481    replacer.add(rule8)
6482
6483    pattern9 = Pattern(UtilityOperator(Add(Mul(Pow(cot(z_), S('2')), WC('v', S(1))), WC('w', S(0)), u_)), CustomConstraint(lambda u, v: SameQ(u, v)))
6484    rule9 = ReplacementRule(pattern9, lambda z, w, v, u : Add(Mul(u, Pow(Csc(z), S('2'))), w))
6485    replacer.add(rule9)
6486
6487    pattern10 = Pattern(UtilityOperator(Add(WC('w', S(0)), u_, Mul(WC('v', S(1)), Pow(sec(z_), S('2'))))), CustomConstraint(lambda u, v: SameQ(u, Mul(S(-1), v))))
6488    rule10 = ReplacementRule(pattern10, lambda u, w, z, v : Add(Mul(v, Pow(Tan(z), S('2'))), w))
6489    replacer.add(rule10)
6490
6491    pattern11 = Pattern(UtilityOperator(Add(Mul(Pow(csc(z_), S('2')), WC('v', S(1))), WC('w', S(0)), u_)), CustomConstraint(lambda u, v: SameQ(u, Mul(S(-1), v))))
6492    rule11 = ReplacementRule(pattern11, lambda z, w, v, u : Add(Mul(v, Pow(Cot(z), S('2'))), w))
6493    replacer.add(rule11)
6494
6495    pattern12 = Pattern(UtilityOperator(Mul(WC('u', S(1)), Pow(Add(Mul(cos(v_), WC('b', S(1))), a_), S(-1)), Pow(sin(v_), S('2')))), CustomConstraint(lambda b, a: ZeroQ(Add(Pow(a, S('2')), Mul(S(-1), Pow(b, S('2')))))))
6496    rule12 = ReplacementRule(pattern12, lambda u, v, b, a : Mul(u, Add(Mul(S(1), Pow(a, S(-1))), Mul(S(-1), Mul(Cos(v), Pow(b, S(-1)))))))
6497    replacer.add(rule12)
6498
6499    pattern13 = Pattern(UtilityOperator(Mul(Pow(cos(v_), S('2')), WC('u', S(1)), Pow(Add(a_, Mul(WC('b', S(1)), sin(v_))), S(-1)))), CustomConstraint(lambda b, a: ZeroQ(Add(Pow(a, S('2')), Mul(S(-1), Pow(b, S('2')))))))
6500    rule13 = ReplacementRule(pattern13, lambda u, v, b, a : Mul(u, Add(Mul(S(1), Pow(a, S(-1))), Mul(S(-1), Mul(Sin(v), Pow(b, S(-1)))))))
6501    replacer.add(rule13)
6502
6503    pattern14 = Pattern(UtilityOperator(Mul(WC('u', S(1)), Pow(tan(v_), WC('n', S(1))), Pow(Add(a_, Mul(WC('b', S(1)), Pow(tan(v_), WC('n', S(1))))), S(-1)))), CustomConstraint(lambda n: PositiveIntegerQ(n)), CustomConstraint(lambda a: NonsumQ(a)))
6504    rule14 = ReplacementRule(pattern14, lambda n, a, u, v, b : Mul(u, Pow(Add(b, Mul(a, Pow(Cot(v), n))), S(-1))))
6505    replacer.add(rule14)
6506
6507    pattern15 = Pattern(UtilityOperator(Mul(Pow(cot(v_), WC('n', S(1))), WC('u', S(1)), Pow(Add(Mul(Pow(cot(v_), WC('n', S(1))), WC('b', S(1))), a_), S(-1)))), CustomConstraint(lambda n: PositiveIntegerQ(n)), CustomConstraint(lambda a: NonsumQ(a)))
6508    rule15 = ReplacementRule(pattern15, lambda n, a, u, v, b : Mul(u, Pow(Add(b, Mul(a, Pow(Tan(v), n))), S(-1))))
6509    replacer.add(rule15)
6510
6511    pattern16 = Pattern(UtilityOperator(Mul(WC('u', S(1)), Pow(sec(v_), WC('n', S(1))), Pow(Add(a_, Mul(WC('b', S(1)), Pow(sec(v_), WC('n', S(1))))), S(-1)))), CustomConstraint(lambda n: PositiveIntegerQ(n)), CustomConstraint(lambda a: NonsumQ(a)))
6512    rule16 = ReplacementRule(pattern16, lambda n, a, u, v, b : Mul(u, Pow(Add(b, Mul(a, Pow(Cos(v), n))), S(-1))))
6513    replacer.add(rule16)
6514
6515    pattern17 = Pattern(UtilityOperator(Mul(Pow(csc(v_), WC('n', S(1))), WC('u', S(1)), Pow(Add(Mul(Pow(csc(v_), WC('n', S(1))), WC('b', S(1))), a_), S(-1)))), CustomConstraint(lambda n: PositiveIntegerQ(n)), CustomConstraint(lambda a: NonsumQ(a)))
6516    rule17 = ReplacementRule(pattern17, lambda n, a, u, v, b : Mul(u, Pow(Add(b, Mul(a, Pow(Sin(v), n))), S(-1))))
6517    replacer.add(rule17)
6518
6519    pattern18 = Pattern(UtilityOperator(Mul(WC('u', S(1)), Pow(Add(a_, Mul(WC('b', S(1)), Pow(sec(v_), WC('n', S(1))))), S(-1)), Pow(tan(v_), WC('n', S(1))))), CustomConstraint(lambda n: PositiveIntegerQ(n)), CustomConstraint(lambda a: NonsumQ(a)))
6520    rule18 = ReplacementRule(pattern18, lambda n, a, u, v, b : Mul(u, Mul(Pow(Sin(v), n), Pow(Add(b, Mul(a, Pow(Cos(v), n))), S(-1)))))
6521    replacer.add(rule18)
6522
6523    pattern19 = Pattern(UtilityOperator(Mul(Pow(cot(v_), WC('n', S(1))), WC('u', S(1)), Pow(Add(Mul(Pow(csc(v_), WC('n', S(1))), WC('b', S(1))), a_), S(-1)))), CustomConstraint(lambda n: PositiveIntegerQ(n)), CustomConstraint(lambda a: NonsumQ(a)))
6524    rule19 = ReplacementRule(pattern19, lambda n, a, u, v, b : Mul(u, Mul(Pow(Cos(v), n), Pow(Add(b, Mul(a, Pow(Sin(v), n))), S(-1)))))
6525    replacer.add(rule19)
6526
6527    pattern20 = Pattern(UtilityOperator(Mul(WC('u', S(1)), Pow(Add(Mul(WC('a', S(1)), Pow(sec(v_), WC('n', S(1)))), Mul(WC('b', S(1)), Pow(tan(v_), WC('n', S(1))))), WC('p', S(1))))), CustomConstraint(lambda n, p: IntegersQ(n, p)))
6528    rule20 = ReplacementRule(pattern20, lambda n, a, p, u, v, b : Mul(u, Pow(Sec(v), Mul(n, p)), Pow(Add(a, Mul(b, Pow(Sin(v), n))), p)))
6529    replacer.add(rule20)
6530
6531    pattern21 = Pattern(UtilityOperator(Mul(Pow(Add(Mul(Pow(csc(v_), WC('n', S(1))), WC('a', S(1))), Mul(Pow(cot(v_), WC('n', S(1))), WC('b', S(1)))), WC('p', S(1))), WC('u', S(1)))), CustomConstraint(lambda n, p: IntegersQ(n, p)))
6532    rule21 = ReplacementRule(pattern21, lambda n, a, p, u, v, b : Mul(u, Pow(Csc(v), Mul(n, p)), Pow(Add(a, Mul(b, Pow(Cos(v), n))), p)))
6533    replacer.add(rule21)
6534
6535    pattern22 = Pattern(UtilityOperator(Mul(WC('u', S(1)), Pow(Add(Mul(WC('b', S(1)), Pow(sin(v_), WC('n', S(1)))), Mul(WC('a', S(1)), Pow(tan(v_), WC('n', S(1))))), WC('p', S(1))))), CustomConstraint(lambda n, p: IntegersQ(n, p)))
6536    rule22 = ReplacementRule(pattern22, lambda n, a, p, u, v, b : Mul(u, Pow(Tan(v), Mul(n, p)), Pow(Add(a, Mul(b, Pow(Cos(v), n))), p)))
6537    replacer.add(rule22)
6538
6539    pattern23 = Pattern(UtilityOperator(Mul(Pow(Add(Mul(Pow(cot(v_), WC('n', S(1))), WC('a', S(1))), Mul(Pow(cos(v_), WC('n', S(1))), WC('b', S(1)))), WC('p', S(1))), WC('u', S(1)))), CustomConstraint(lambda n, p: IntegersQ(n, p)))
6540    rule23 = ReplacementRule(pattern23, lambda n, a, p, u, v, b : Mul(u, Pow(Cot(v), Mul(n, p)), Pow(Add(a, Mul(b, Pow(Sin(v), n))), p)))
6541    replacer.add(rule23)
6542
6543    pattern24 = Pattern(UtilityOperator(Mul(Pow(cos(v_), WC('m', S(1))), WC('u', S(1)), Pow(Add(WC('a', S(0)), Mul(WC('c', S(1)), Pow(sec(v_), WC('n', S(1)))), Mul(WC('b', S(1)), Pow(tan(v_), WC('n', S(1))))), WC('p', S(1))))), CustomConstraint(lambda n, p, m: IntegersQ(m, n, p)))
6544    rule24 = ReplacementRule(pattern24, lambda n, a, c, p, m, u, v, b : Mul(u, Pow(Cos(v), Add(m, Mul(S(-1), Mul(n, p)))), Pow(Add(c, Mul(b, Pow(Sin(v), n)), Mul(a, Pow(Cos(v), n))), p)))
6545    replacer.add(rule24)
6546
6547    pattern25 = Pattern(UtilityOperator(Mul(WC('u', S(1)), Pow(sec(v_), WC('m', S(1))), Pow(Add(WC('a', S(0)), Mul(WC('c', S(1)), Pow(sec(v_), WC('n', S(1)))), Mul(WC('b', S(1)), Pow(tan(v_), WC('n', S(1))))), WC('p', S(1))))), CustomConstraint(lambda n, p, m: IntegersQ(m, n, p)))
6548    rule25 = ReplacementRule(pattern25, lambda n, a, c, p, m, u, v, b : Mul(u, Pow(Sec(v), Add(m, Mul(n, p))), Pow(Add(c, Mul(b, Pow(Sin(v), n)), Mul(a, Pow(Cos(v), n))), p)))
6549    replacer.add(rule25)
6550
6551    pattern26 = Pattern(UtilityOperator(Mul(Pow(Add(WC('a', S(0)), Mul(Pow(cot(v_), WC('n', S(1))), WC('b', S(1))), Mul(Pow(csc(v_), WC('n', S(1))), WC('c', S(1)))), WC('p', S(1))), WC('u', S(1)), Pow(sin(v_), WC('m', S(1))))), CustomConstraint(lambda n, p, m: IntegersQ(m, n, p)))
6552    rule26 = ReplacementRule(pattern26, lambda n, a, c, p, m, u, v, b : Mul(u, Pow(Sin(v), Add(m, Mul(S(-1), Mul(n, p)))), Pow(Add(c, Mul(b, Pow(Cos(v), n)), Mul(a, Pow(Sin(v), n))), p)))
6553    replacer.add(rule26)
6554
6555    pattern27 = Pattern(UtilityOperator(Mul(Pow(csc(v_), WC('m', S(1))), Pow(Add(WC('a', S(0)), Mul(Pow(cot(v_), WC('n', S(1))), WC('b', S(1))), Mul(Pow(csc(v_), WC('n', S(1))), WC('c', S(1)))), WC('p', S(1))), WC('u', S(1)))), CustomConstraint(lambda n, p, m: IntegersQ(m, n, p)))
6556    rule27 = ReplacementRule(pattern27, lambda n, a, c, p, m, u, v, b : Mul(u, Pow(Csc(v), Add(m, Mul(n, p))), Pow(Add(c, Mul(b, Pow(Cos(v), n)), Mul(a, Pow(Sin(v), n))), p)))
6557    replacer.add(rule27)
6558
6559    pattern28 = Pattern(UtilityOperator(Mul(WC('u', S(1)), Pow(Add(Mul(Pow(csc(v_), WC('m', S(1))), WC('a', S(1))), Mul(WC('b', S(1)), Pow(sin(v_), WC('n', S(1))))), WC('p', S(1))))), CustomConstraint(lambda n, m: IntegersQ(m, n)))
6560    rule28 = ReplacementRule(pattern28, lambda n, a, p, m, u, v, b : If(And(ZeroQ(Add(m, n, S(-2))), ZeroQ(Add(a, b))), Mul(u, Pow(Mul(a, Mul(Pow(Cos(v), S('2')), Pow(Pow(Sin(v), m), S(-1)))), p)), Mul(u, Pow(Mul(Add(a, Mul(b, Pow(Sin(v), Add(m, n)))), Pow(Pow(Sin(v), m), S(-1))), p))))
6561    replacer.add(rule28)
6562
6563    pattern29 = Pattern(UtilityOperator(Mul(WC('u', S(1)), Pow(Add(Mul(Pow(cos(v_), WC('n', S(1))), WC('b', S(1))), Mul(WC('a', S(1)), Pow(sec(v_), WC('m', S(1))))), WC('p', S(1))))), CustomConstraint(lambda n, m: IntegersQ(m, n)))
6564    rule29 = ReplacementRule(pattern29, lambda n, a, p, m, u, v, b : If(And(ZeroQ(Add(m, n, S(-2))), ZeroQ(Add(a, b))), Mul(u, Pow(Mul(a, Mul(Pow(Sin(v), S('2')), Pow(Pow(Cos(v), m), S(-1)))), p)), Mul(u, Pow(Mul(Add(a, Mul(b, Pow(Cos(v), Add(m, n)))), Pow(Pow(Cos(v), m), S(-1))), p))))
6565    replacer.add(rule29)
6566
6567    pattern30 = Pattern(UtilityOperator(u_))
6568    rule30 = ReplacementRule(pattern30, lambda u : u)
6569    replacer.add(rule30)
6570
6571    return replacer
6572
6573@doctest_depends_on(modules=('matchpy',))
6574def TrigSimplifyAux(expr):
6575    return TrigSimplifyAux_replacer.replace(UtilityOperator(expr))
6576
6577def Cancel(expr):
6578    return cancel(expr)
6579
6580class Util_Part(Function):
6581    def doit(self):
6582        i = Simplify(self.args[0])
6583        if len(self.args) > 2 :
6584            lst = list(self.args[1:])
6585        else:
6586            lst = self.args[1]
6587        if isinstance(i, (int, Integer)):
6588            if isinstance(lst, list):
6589                return lst[i - 1]
6590            elif AtomQ(lst):
6591                return lst
6592            return lst.args[i - 1]
6593        else:
6594            return self
6595
6596def Part(lst, i): #see i = -1
6597    if isinstance(lst, list):
6598        return Util_Part(i, *lst).doit()
6599    return Util_Part(i, lst).doit()
6600
6601def PolyLog(n, p, z=None):
6602    return polylog(n, p)
6603
6604def D(f, x):
6605    try:
6606        return f.diff(x)
6607    except ValueError:
6608        return Function('D')(f, x)
6609
6610def IntegralFreeQ(u):
6611    return FreeQ(u, Integral)
6612
6613def Dist(u, v, x):
6614    #Dist(u,v) returns the sum of u times each term of v, provided v is free of Int
6615    u = replace_pow_exp(u) # to replace back to sympy's exp
6616    v = replace_pow_exp(v)
6617    w = Simp(u*x**2, x)/x**2
6618    if u == 1:
6619        return v
6620    elif u == 0:
6621        return 0
6622    elif NumericFactor(u) < 0 and NumericFactor(-u) > 0:
6623        return -Dist(-u, v, x)
6624    elif SumQ(v):
6625        return Add(*[Dist(u, i, x) for i in v.args])
6626    elif IntegralFreeQ(v):
6627        return Simp(u*v, x)
6628    elif w != u and FreeQ(w, x) and w == Simp(w, x) and w == Simp(w*x**2, x)/x**2:
6629        return Dist(w, v, x)
6630    else:
6631        return Simp(u*v, x)
6632
6633def PureFunctionOfCothQ(u, v, x):
6634    # If u is a pure function of Coth[v], PureFunctionOfCothQ[u,v,x] returns True;
6635    if AtomQ(u):
6636        return u != x
6637    elif CalculusQ(u):
6638        return False
6639    elif HyperbolicQ(u) and ZeroQ(u.args[0] - v):
6640        return CothQ(u)
6641    return all(PureFunctionOfCothQ(i, v, x) for i in u.args)
6642
6643def LogIntegral(z):
6644    return li(z)
6645
6646def ExpIntegralEi(z):
6647    return Ei(z)
6648
6649def ExpIntegralE(a, b):
6650    return expint(a, b).evalf()
6651
6652def SinIntegral(z):
6653    return Si(z)
6654
6655def CosIntegral(z):
6656    return Ci(z)
6657
6658def SinhIntegral(z):
6659    return Shi(z)
6660
6661def CoshIntegral(z):
6662    return Chi(z)
6663
6664class PolyGamma(Function):
6665    @classmethod
6666    def eval(cls, *args):
6667        if len(args) == 2:
6668            return polygamma(args[0], args[1])
6669        return digamma(args[0])
6670
6671def LogGamma(z):
6672    return loggamma(z)
6673
6674class ProductLog(Function):
6675    @classmethod
6676    def eval(cls, *args):
6677        if len(args) == 2:
6678            return LambertW(args[1], args[0]).evalf()
6679        return LambertW(args[0]).evalf()
6680
6681def Factorial(a):
6682    return factorial(a)
6683
6684def Zeta(*args):
6685    return zeta(*args)
6686
6687def HypergeometricPFQ(a, b, c):
6688    return hyper(a, b, c)
6689
6690def Sum_doit(exp, args):
6691    """
6692    This function perform summation using sympy's `Sum`.
6693
6694    Examples
6695    ========
6696
6697    >>> from sympy.integrals.rubi.utility_function import Sum_doit
6698    >>> from sympy.abc import x
6699    >>> Sum_doit(2*x + 2, [x, 0, 1.7])
6700    6
6701
6702    """
6703    exp = replace_pow_exp(exp)
6704    if not isinstance(args[2], (int, Integer)):
6705        new_args = [args[0], args[1], Floor(args[2])]
6706        return Sum(exp, new_args).doit()
6707
6708    return Sum(exp, args).doit()
6709
6710def PolynomialQuotient(p, q, x):
6711    try:
6712        p = poly(p, x)
6713        q = poly(q, x)
6714
6715    except:
6716        p = poly(p)
6717        q = poly(q)
6718    try:
6719        return quo(p, q).as_expr()
6720    except (PolynomialDivisionFailed, UnificationFailed):
6721        return p/q
6722
6723def PolynomialRemainder(p, q, x):
6724    try:
6725        p = poly(p, x)
6726        q = poly(q, x)
6727
6728    except:
6729        p = poly(p)
6730        q = poly(q)
6731    try:
6732        return rem(p, q).as_expr()
6733    except (PolynomialDivisionFailed, UnificationFailed):
6734        return S(0)
6735
6736def Floor(x, a = None):
6737    if a is None:
6738        return floor(x)
6739    return a*floor(x/a)
6740
6741def Factor(var):
6742    return factor(var)
6743
6744def Rule(a, b):
6745    return {a: b}
6746
6747def Distribute(expr, *args):
6748    if len(args) == 1:
6749        if isinstance(expr, args[0]):
6750            return expr
6751        else:
6752            return expr.expand()
6753    if len(args) == 2:
6754        if isinstance(expr, args[1]):
6755            return expr.expand()
6756        else:
6757            return expr
6758    return expr.expand()
6759
6760def CoprimeQ(*args):
6761    args = S(args)
6762    g = gcd(*args)
6763    if g == 1:
6764        return True
6765    return False
6766
6767def Discriminant(a, b):
6768    try:
6769        return discriminant(a, b)
6770    except PolynomialError:
6771        return Function('Discriminant')(a, b)
6772
6773def Negative(x):
6774    return x < S(0)
6775
6776def Quotient(m, n):
6777    return Floor(m/n)
6778
6779def process_trig(expr):
6780    """
6781    This function processes trigonometric expressions such that all `cot` is
6782    rewritten in terms of `tan`, `sec` in terms of `cos`, `csc` in terms of `sin` and
6783    similarly for `coth`, `sech` and `csch`.
6784
6785    Examples
6786    ========
6787
6788    >>> from sympy.integrals.rubi.utility_function import process_trig
6789    >>> from sympy.abc import x
6790    >>> from sympy import coth, cot, csc
6791    >>> process_trig(x*cot(x))
6792    x/tan(x)
6793    >>> process_trig(coth(x)*csc(x))
6794    1/(sin(x)*tanh(x))
6795
6796    """
6797    expr = expr.replace(lambda x: isinstance(x, cot), lambda x: 1/tan(x.args[0]))
6798    expr = expr.replace(lambda x: isinstance(x, sec), lambda x: 1/cos(x.args[0]))
6799    expr = expr.replace(lambda x: isinstance(x, csc), lambda x: 1/sin(x.args[0]))
6800    expr = expr.replace(lambda x: isinstance(x, coth), lambda x: 1/tanh(x.args[0]))
6801    expr = expr.replace(lambda x: isinstance(x, sech), lambda x: 1/cosh(x.args[0]))
6802    expr = expr.replace(lambda x: isinstance(x, csch), lambda x: 1/sinh(x.args[0]))
6803    return expr
6804
6805def _ExpandIntegrand():
6806    Plus = Add
6807    Times = Mul
6808    def cons_f1(m):
6809        return PositiveIntegerQ(m)
6810
6811    cons1 = CustomConstraint(cons_f1)
6812    def cons_f2(d, c, b, a):
6813        return ZeroQ(-a*d + b*c)
6814
6815    cons2 = CustomConstraint(cons_f2)
6816    def cons_f3(a, x):
6817        return FreeQ(a, x)
6818
6819    cons3 = CustomConstraint(cons_f3)
6820    def cons_f4(b, x):
6821        return FreeQ(b, x)
6822
6823    cons4 = CustomConstraint(cons_f4)
6824    def cons_f5(c, x):
6825        return FreeQ(c, x)
6826
6827    cons5 = CustomConstraint(cons_f5)
6828    def cons_f6(d, x):
6829        return FreeQ(d, x)
6830
6831    cons6 = CustomConstraint(cons_f6)
6832    def cons_f7(e, x):
6833        return FreeQ(e, x)
6834
6835    cons7 = CustomConstraint(cons_f7)
6836    def cons_f8(f, x):
6837        return FreeQ(f, x)
6838
6839    cons8 = CustomConstraint(cons_f8)
6840    def cons_f9(g, x):
6841        return FreeQ(g, x)
6842
6843    cons9 = CustomConstraint(cons_f9)
6844    def cons_f10(h, x):
6845        return FreeQ(h, x)
6846
6847    cons10 = CustomConstraint(cons_f10)
6848    def cons_f11(e, b, c, f, n, p, F, x, d, m):
6849        if not isinstance(x, Symbol):
6850            return False
6851        return FreeQ(List(F, b, c, d, e, f, m, n, p), x)
6852
6853    cons11 = CustomConstraint(cons_f11)
6854    def cons_f12(F, x):
6855        return FreeQ(F, x)
6856
6857    cons12 = CustomConstraint(cons_f12)
6858    def cons_f13(m, x):
6859        return FreeQ(m, x)
6860
6861    cons13 = CustomConstraint(cons_f13)
6862    def cons_f14(n, x):
6863        return FreeQ(n, x)
6864
6865    cons14 = CustomConstraint(cons_f14)
6866    def cons_f15(p, x):
6867        return FreeQ(p, x)
6868
6869    cons15 = CustomConstraint(cons_f15)
6870    def cons_f16(e, b, c, f, n, a, p, F, x, d, m):
6871        if not isinstance(x, Symbol):
6872            return False
6873        return FreeQ(List(F, a, b, c, d, e, f, m, n, p), x)
6874
6875    cons16 = CustomConstraint(cons_f16)
6876    def cons_f17(n, m):
6877        return IntegersQ(m, n)
6878
6879    cons17 = CustomConstraint(cons_f17)
6880    def cons_f18(n):
6881        return Less(n, S(0))
6882
6883    cons18 = CustomConstraint(cons_f18)
6884    def cons_f19(x, u):
6885        if not isinstance(x, Symbol):
6886            return False
6887        return PolynomialQ(u, x)
6888
6889    cons19 = CustomConstraint(cons_f19)
6890    def cons_f20(G, F, u):
6891        return SameQ(F(u)*G(u), S(1))
6892
6893    cons20 = CustomConstraint(cons_f20)
6894    def cons_f21(q, x):
6895        return FreeQ(q, x)
6896
6897    cons21 = CustomConstraint(cons_f21)
6898    def cons_f22(F):
6899        return MemberQ(List(ArcSin, ArcCos, ArcSinh, ArcCosh), F)
6900
6901    cons22 = CustomConstraint(cons_f22)
6902    def cons_f23(j, n):
6903        return ZeroQ(j - S(2)*n)
6904
6905    cons23 = CustomConstraint(cons_f23)
6906    def cons_f24(A, x):
6907        return FreeQ(A, x)
6908
6909    cons24 = CustomConstraint(cons_f24)
6910    def cons_f25(B, x):
6911        return FreeQ(B, x)
6912
6913    cons25 = CustomConstraint(cons_f25)
6914    def cons_f26(m, u, x):
6915        if not isinstance(x, Symbol):
6916            return False
6917        def _cons_f_u(d, w, c, p, x):
6918            return And(FreeQ(List(c, d), x), IntegerQ(p), Greater(p, m))
6919        cons_u = CustomConstraint(_cons_f_u)
6920        pat = Pattern(UtilityOperator((c_ + x_*WC('d', S(1)))**p_*WC('w', S(1)), x_), cons_u)
6921        result_matchq = is_match(UtilityOperator(u, x), pat)
6922        return Not(And(PositiveIntegerQ(m), result_matchq))
6923
6924    cons26 = CustomConstraint(cons_f26)
6925    def cons_f27(b, v, n, a, x, u, m):
6926        if not isinstance(x, Symbol):
6927            return False
6928        return And(FreeQ(List(a, b, m), x), NegativeIntegerQ(n), Not(IntegerQ(m)), PolynomialQ(u, x), PolynomialQ(v, x),\
6929            RationalQ(m), Less(m, -1), GreaterEqual(Exponent(u, x), (-n - IntegerPart(m))*Exponent(v, x)))
6930    cons27 = CustomConstraint(cons_f27)
6931    def cons_f28(v, n, x, u, m):
6932        if not isinstance(x, Symbol):
6933            return False
6934        return And(FreeQ(List(a, b, m), x), NegativeIntegerQ(n), Not(IntegerQ(m)), PolynomialQ(u, x),\
6935            PolynomialQ(v, x), GreaterEqual(Exponent(u, x), -n*Exponent(v, x)))
6936    cons28 = CustomConstraint(cons_f28)
6937    def cons_f29(n):
6938        return PositiveIntegerQ(n/S(4))
6939
6940    cons29 = CustomConstraint(cons_f29)
6941    def cons_f30(n):
6942        return IntegerQ(n)
6943
6944    cons30 = CustomConstraint(cons_f30)
6945    def cons_f31(n):
6946        return Greater(n, S(1))
6947
6948    cons31 = CustomConstraint(cons_f31)
6949    def cons_f32(n, m):
6950        return Less(S(0), m, n)
6951
6952    cons32 = CustomConstraint(cons_f32)
6953    def cons_f33(n, m):
6954        return OddQ(n/GCD(m, n))
6955
6956    cons33 = CustomConstraint(cons_f33)
6957    def cons_f34(a, b):
6958        return PosQ(a/b)
6959
6960    cons34 = CustomConstraint(cons_f34)
6961    def cons_f35(n, m, p):
6962        return IntegersQ(m, n, p)
6963
6964    cons35 = CustomConstraint(cons_f35)
6965    def cons_f36(n, m, p):
6966        return Less(S(0), m, p, n)
6967
6968    cons36 = CustomConstraint(cons_f36)
6969    def cons_f37(q, n, m, p):
6970        return IntegersQ(m, n, p, q)
6971
6972    cons37 = CustomConstraint(cons_f37)
6973    def cons_f38(n, q, m, p):
6974        return Less(S(0), m, p, q, n)
6975
6976    cons38 = CustomConstraint(cons_f38)
6977    def cons_f39(n):
6978        return IntegerQ(n/S(2))
6979
6980    cons39 = CustomConstraint(cons_f39)
6981    def cons_f40(p):
6982        return NegativeIntegerQ(p)
6983
6984    cons40 = CustomConstraint(cons_f40)
6985    def cons_f41(n, m):
6986        return IntegersQ(m, n/S(2))
6987
6988    cons41 = CustomConstraint(cons_f41)
6989    def cons_f42(n, m):
6990        return Unequal(m, n/S(2))
6991
6992    cons42 = CustomConstraint(cons_f42)
6993    def cons_f43(c, b, a):
6994        return NonzeroQ(-S(4)*a*c + b**S(2))
6995
6996    cons43 = CustomConstraint(cons_f43)
6997    def cons_f44(j, n, m):
6998        return IntegersQ(m, n, j)
6999
7000    cons44 = CustomConstraint(cons_f44)
7001    def cons_f45(n, m):
7002        return Less(S(0), m, S(2)*n)
7003
7004    cons45 = CustomConstraint(cons_f45)
7005    def cons_f46(n, m, p):
7006        return Not(And(Equal(m, n), Equal(p, S(-1))))
7007
7008    cons46 = CustomConstraint(cons_f46)
7009    def cons_f47(v, x):
7010        if not isinstance(x, Symbol):
7011            return False
7012        return PolynomialQ(v, x)
7013
7014    cons47 = CustomConstraint(cons_f47)
7015    def cons_f48(v, x):
7016        if not isinstance(x, Symbol):
7017            return False
7018        return BinomialQ(v, x)
7019
7020    cons48 = CustomConstraint(cons_f48)
7021    def cons_f49(v, x, u):
7022        if not isinstance(x, Symbol):
7023            return False
7024        return Inequality(Exponent(u, x), Equal, Exponent(v, x) + S(-1), GreaterEqual, S(2))
7025
7026    cons49 = CustomConstraint(cons_f49)
7027    def cons_f50(v, x, u):
7028        if not isinstance(x, Symbol):
7029            return False
7030        return GreaterEqual(Exponent(u, x), Exponent(v, x))
7031
7032    cons50 = CustomConstraint(cons_f50)
7033    def cons_f51(p):
7034        return Not(IntegerQ(p))
7035
7036    cons51 = CustomConstraint(cons_f51)
7037
7038    def With2(e, b, c, f, n, a, g, h, x, d, m):
7039        tmp = a*h - b*g
7040        k = Symbol('k')
7041        return f**(e*(c + d*x)**n)*SimplifyTerm(h**(-m)*tmp**m, x)/(g + h*x) + Sum_doit(f**(e*(c + d*x)**n)*(a + b*x)**(-k + m)*SimplifyTerm(b*h**(-k)*tmp**(k - 1), x), List(k, 1, m))
7042    pattern2 = Pattern(UtilityOperator(f_**((x_*WC('d', S(1)) + WC('c', S(0)))**WC('n', S(1))*WC('e', S(1)))*(x_*WC('b', S(1)) + WC('a', S(0)))**WC('m', S(1))/(x_*WC('h', S(1)) + WC('g', S(0))), x_), cons3, cons4, cons5, cons6, cons7, cons8, cons9, cons10, cons1, cons2)
7043    rule2 = ReplacementRule(pattern2, With2)
7044    pattern3 = Pattern(UtilityOperator(F_**((x_*WC('d', S(1)) + WC('c', S(0)))**WC('n', S(1))*WC('b', S(1)))*x_**WC('m', S(1))*(e_ + x_*WC('f', S(1)))**WC('p', S(1)), x_), cons12, cons4, cons5, cons6, cons7, cons8, cons13, cons14, cons15, cons11)
7045    def replacement3(e, b, c, f, n, p, F, x, d, m):
7046        return If(And(PositiveIntegerQ(m, p), LessEqual(m, p), Or(EqQ(n, S(1)), ZeroQ(-c*f + d*e))), ExpandLinearProduct(F**(b*(c + d*x)**n)*(e + f*x)**p, x**m, e, f, x), If(PositiveIntegerQ(p), Distribute(F**(b*(c + d*x)**n)*x**m*(e + f*x)**p, Plus, Times), ExpandIntegrand(F**(b*(c + d*x)**n), x**m*(e + f*x)**p, x)))
7047    rule3 = ReplacementRule(pattern3, replacement3)
7048    pattern4 = Pattern(UtilityOperator(F_**((x_*WC('d', S(1)) + WC('c', S(0)))**WC('n', S(1))*WC('b', S(1)) + WC('a', S(0)))*x_**WC('m', S(1))*(e_ + x_*WC('f', S(1)))**WC('p', S(1)), x_), cons12, cons3, cons4, cons5, cons6, cons7, cons8, cons13, cons14, cons15, cons16)
7049    def replacement4(e, b, c, f, n, a, p, F, x, d, m):
7050        return If(And(PositiveIntegerQ(m, p), LessEqual(m, p), Or(EqQ(n, S(1)), ZeroQ(-c*f + d*e))), ExpandLinearProduct(F**(a + b*(c + d*x)**n)*(e + f*x)**p, x**m, e, f, x), If(PositiveIntegerQ(p), Distribute(F**(a + b*(c + d*x)**n)*x**m*(e + f*x)**p, Plus, Times), ExpandIntegrand(F**(a + b*(c + d*x)**n), x**m*(e + f*x)**p, x)))
7051    rule4 = ReplacementRule(pattern4, replacement4)
7052    def With5(b, v, c, n, a, F, u, x, d, m):
7053        if not isinstance(x, Symbol) or not (FreeQ([F, a, b, c, d], x) and IntegersQ(m, n) and n < 0):
7054            return False
7055        w = ExpandIntegrand((a + b*x)**m*(c + d*x)**n, x)
7056        w = ReplaceAll(w, Rule(x, F**v))
7057        if SumQ(w):
7058            return True
7059        return False
7060    pattern5 = Pattern(UtilityOperator((F_**v_*WC('b', S(1)) + a_)**WC('m', S(1))*(F_**v_*WC('d', S(1)) + c_)**n_*WC('u', S(1)), x_), cons12, cons3, cons4, cons5, cons6, cons17, cons18, CustomConstraint(With5))
7061    def replacement5(b, v, c, n, a, F, u, x, d, m):
7062        w = ReplaceAll(ExpandIntegrand((a + b*x)**m*(c + d*x)**n, x), Rule(x, F**v))
7063        return w.func(*[u*i for i in w.args])
7064    rule5 = ReplacementRule(pattern5, replacement5)
7065    def With6(e, b, c, f, n, a, x, u, d, m):
7066        if not isinstance(x, Symbol) or not (FreeQ([a, b, c, d, e, f, m, n], x) and PolynomialQ(u,x)):
7067            return False
7068        v = ExpandIntegrand(u*(a + b*x)**m, x)
7069        if SumQ(v):
7070            return True
7071        return False
7072    pattern6 = Pattern(UtilityOperator(f_**((x_*WC('d', S(1)) + WC('c', S(0)))**WC('n', S(1))*WC('e', S(1)))*u_*(x_*WC('b', S(1)) + WC('a', S(0)))**WC('m', S(1)), x_), cons3, cons4, cons5, cons6, cons7, cons8, cons13, cons14, cons19, CustomConstraint(With6))
7073    def replacement6(e, b, c, f, n, a, x, u, d, m):
7074        v = ExpandIntegrand(u*(a + b*x)**m, x)
7075        return Distribute(f**(e*(c + d*x)**n)*v, Plus, Times)
7076    rule6 = ReplacementRule(pattern6, replacement6)
7077    pattern7 = Pattern(UtilityOperator(u_*(x_*WC('b', S(1)) + WC('a', S(0)))**WC('m', S(1))*Log((x_**WC('n', S(1))*WC('e', S(1)) + WC('d', S(0)))**WC('p', S(1))*WC('c', S(1))), x_), cons3, cons4, cons5, cons6, cons7, cons13, cons14, cons15, cons19)
7078    def replacement7(e, b, c, n, a, p, x, u, d, m):
7079        return ExpandIntegrand(Log(c*(d + e*x**n)**p), u*(a + b*x)**m, x)
7080    rule7 = ReplacementRule(pattern7, replacement7)
7081    pattern8 = Pattern(UtilityOperator(f_**((x_*WC('d', S(1)) + WC('c', S(0)))**WC('n', S(1))*WC('e', S(1)))*u_, x_), cons5, cons6, cons7, cons8, cons14, cons19)
7082    def replacement8(e, c, f, n, x, u, d):
7083        return If(EqQ(n, S(1)), ExpandIntegrand(f**(e*(c + d*x)**n), u, x), ExpandLinearProduct(f**(e*(c + d*x)**n), u, c, d, x))
7084    rule8 = ReplacementRule(pattern8, replacement8)
7085    # pattern9 = Pattern(UtilityOperator(F_**u_*(G_*u_*WC('b', S(1)) + a_)**WC('n', S(1)), x_), cons3, cons4, cons17, cons20)
7086    # def replacement9(b, G, n, a, F, u, x, m):
7087    #     return ReplaceAll(ExpandIntegrand(x**(-m)*(a + b*x)**n, x), Rule(x, G(u)))
7088    # rule9 = ReplacementRule(pattern9, replacement9)
7089    pattern10 = Pattern(UtilityOperator(u_*(WC('a', S(0)) + WC('b', S(1))*Log(((x_*WC('f', S(1)) + WC('e', S(0)))**WC('p', S(1))*WC('d', S(1)))**WC('q', S(1))*WC('c', S(1))))**n_, x_), cons3, cons4, cons5, cons6, cons7, cons8, cons14, cons15, cons21, cons19)
7090    def replacement10(e, b, c, f, n, a, p, x, u, d, q):
7091        return ExpandLinearProduct((a + b*Log(c*(d*(e + f*x)**p)**q))**n, u, e, f, x)
7092    rule10 = ReplacementRule(pattern10, replacement10)
7093    # pattern11 = Pattern(UtilityOperator(u_*(F_*(x_*WC('d', S(1)) + WC('c', S(0)))*WC('b', S(1)) + WC('a', S(0)))**n_, x_), cons3, cons4, cons5, cons6, cons14, cons19, cons22)
7094    # def replacement11(b, c, n, a, F, u, x, d):
7095    #     return ExpandLinearProduct((a + b*F(c + d*x))**n, u, c, d, x)
7096    # rule11 = ReplacementRule(pattern11, replacement11)
7097    pattern12 = Pattern(UtilityOperator(WC('u', S(1))/(x_**n_*WC('a', S(1)) + sqrt(c_ + x_**j_*WC('d', S(1)))*WC('b', S(1))), x_), cons3, cons4, cons5, cons6, cons14, cons23)
7098    def replacement12(b, c, n, a, x, u, d, j):
7099        return ExpandIntegrand(u*(a*x**n - b*sqrt(c + d*x**(S(2)*n)))/(-b**S(2)*c + x**(S(2)*n)*(a**S(2) - b**S(2)*d)), x)
7100    rule12 = ReplacementRule(pattern12, replacement12)
7101    pattern13 = Pattern(UtilityOperator((a_ + x_*WC('b', S(1)))**m_/(c_ + x_*WC('d', S(1))), x_), cons3, cons4, cons5, cons6, cons1)
7102    def replacement13(b, c, a, x, d, m):
7103        if RationalQ(a, b, c, d):
7104            return ExpandExpression((a + b*x)**m/(c + d*x), x)
7105        else:
7106            tmp = a*d - b*c
7107            k = Symbol("k")
7108            return Sum_doit((a + b*x)**(-k + m)*SimplifyTerm(b*d**(-k)*tmp**(k + S(-1)), x), List(k, S(1), m)) + SimplifyTerm(d**(-m)*tmp**m, x)/(c + d*x)
7109
7110    rule13 = ReplacementRule(pattern13, replacement13)
7111    pattern14 = Pattern(UtilityOperator((A_ + x_*WC('B', S(1)))*(a_ + x_*WC('b', S(1)))**WC('m', S(1))/(c_ + x_*WC('d', S(1))), x_), cons3, cons4, cons5, cons6, cons24, cons25, cons1)
7112    def replacement14(b, B, A, c, a, x, d, m):
7113        if RationalQ(a, b, c, d, A, B):
7114            return ExpandExpression((A + B*x)*(a + b*x)**m/(c + d*x), x)
7115        else:
7116            tmp1 = (A*d - B*c)/d
7117            tmp2 = ExpandIntegrand((a + b*x)**m/(c + d*x), x)
7118            tmp2 = If(SumQ(tmp2), tmp2.func(*[SimplifyTerm(tmp1*i, x) for i in tmp2.args]), SimplifyTerm(tmp1*tmp2, x))
7119            return SimplifyTerm(B/d, x)*(a + b*x)**m + tmp2
7120    rule14 = ReplacementRule(pattern14, replacement14)
7121
7122    def With15(b, a, x, u, m):
7123        tmp1 = ExpandLinearProduct((a + b*x)**m, u, a, b, x)
7124        if not IntegerQ(m):
7125            return tmp1
7126        else:
7127            tmp2 = ExpandExpression(u*(a + b*x)**m, x)
7128            if SumQ(tmp2) and LessEqual(LeafCount(tmp2), LeafCount(tmp1) + S(2)):
7129                return tmp2
7130            else:
7131                return tmp1
7132    pattern15 = Pattern(UtilityOperator(u_*(a_ + x_*WC('b', S(1)))**m_, x_), cons3, cons4, cons13, cons19, cons26)
7133    rule15 = ReplacementRule(pattern15, With15)
7134    pattern16 = Pattern(UtilityOperator(u_*v_**n_*(a_ + x_*WC('b', S(1)))**m_, x_), cons27)
7135    def replacement16(b, v, n, a, x, u, m):
7136        s = PolynomialQuotientRemainder(u, v**(-n)*(a+b*x)**(-IntegerPart(m)), x)
7137        return ExpandIntegrand((a + b*x)**FractionalPart(m)*s[0], x) + ExpandIntegrand(v**n*(a + b*x)**m*s[1], x)
7138    rule16 = ReplacementRule(pattern16, replacement16)
7139
7140    pattern17 = Pattern(UtilityOperator(u_*v_**n_*(a_ + x_*WC('b', S(1)))**m_, x_), cons28)
7141    def replacement17(b, v, n, a, x, u, m):
7142        s = PolynomialQuotientRemainder(u, v**(-n),x)
7143        return ExpandIntegrand((a + b*x)**(m)*s[0], x) + ExpandIntegrand(v**n*(a + b*x)**m*s[1], x)
7144    rule17 = ReplacementRule(pattern17, replacement17)
7145
7146    def With18(b, n, a, x, u):
7147        r = Numerator(Rt(-a/b, S(2)))
7148        s = Denominator(Rt(-a/b, S(2)))
7149        return r/(S(2)*a*(r + s*u**(n/S(2)))) + r/(S(2)*a*(r - s*u**(n/S(2))))
7150    pattern18 = Pattern(UtilityOperator(S(1)/(a_ + u_**n_*WC('b', S(1))), x_), cons3, cons4, cons29)
7151    rule18 = ReplacementRule(pattern18, With18)
7152    def With19(b, n, a, x, u):
7153        k = Symbol("k")
7154        r = Numerator(Rt(-a/b, n))
7155        s = Denominator(Rt(-a/b, n))
7156        return Sum_doit(r/(a*n*(-(-1)**(2*k/n)*s*u + r)), List(k, 1, n))
7157    pattern19 = Pattern(UtilityOperator(S(1)/(a_ + u_**n_*WC('b', S(1))), x_), cons3, cons4, cons30, cons31)
7158    rule19 = ReplacementRule(pattern19, With19)
7159    def With20(b, n, a, x, u, m):
7160        k = Symbol("k")
7161        g = GCD(m, n)
7162        r = Numerator(Rt(a/b, n/GCD(m, n)))
7163        s = Denominator(Rt(a/b, n/GCD(m, n)))
7164        return If(CoprimeQ(g + m, n), Sum_doit((-1)**(-2*k*m/n)*r*(-r/s)**(m/g)/(a*n*((-1)**(2*g*k/n)*s*u**g + r)), List(k, 1, n/g)), Sum_doit((-1)**(2*k*(g + m)/n)*r*(-r/s)**(m/g)/(a*n*((-1)**(2*g*k/n)*r + s*u**g)), List(k, 1, n/g)))
7165    pattern20 = Pattern(UtilityOperator(u_**WC('m', S(1))/(a_ + u_**n_*WC('b', S(1))), x_), cons3, cons4, cons17, cons32, cons33, cons34)
7166    rule20 = ReplacementRule(pattern20, With20)
7167    def With21(b, n, a, x, u, m):
7168        k = Symbol("k")
7169        g = GCD(m, n)
7170        r = Numerator(Rt(-a/b, n/GCD(m, n)))
7171        s = Denominator(Rt(-a/b, n/GCD(m, n)))
7172        return If(Equal(n/g, S(2)), s/(S(2)*b*(r + s*u**g)) - s/(S(2)*b*(r - s*u**g)), If(CoprimeQ(g + m, n), Sum_doit((S(-1))**(-S(2)*k*m/n)*r*(r/s)**(m/g)/(a*n*(-(S(-1))**(S(2)*g*k/n)*s*u**g + r)), List(k, S(1), n/g)), Sum_doit((S(-1))**(S(2)*k*(g + m)/n)*r*(r/s)**(m/g)/(a*n*((S(-1))**(S(2)*g*k/n)*r - s*u**g)), List(k, S(1), n/g))))
7173    pattern21 = Pattern(UtilityOperator(u_**WC('m', S(1))/(a_ + u_**n_*WC('b', S(1))), x_), cons3, cons4, cons17, cons32)
7174    rule21 = ReplacementRule(pattern21, With21)
7175    def With22(b, c, n, a, x, u, d, m):
7176        k = Symbol("k")
7177        r = Numerator(Rt(-a/b, n))
7178        s = Denominator(Rt(-a/b, n))
7179        return Sum_doit((c*r + (-1)**(-2*k*m/n)*d*r*(r/s)**m)/(a*n*(-(-1)**(2*k/n)*s*u + r)), List(k, 1, n))
7180    pattern22 = Pattern(UtilityOperator((c_ + u_**WC('m', S(1))*WC('d', S(1)))/(a_ + u_**n_*WC('b', S(1))), x_), cons3, cons4, cons5, cons6, cons17, cons32)
7181    rule22 = ReplacementRule(pattern22, With22)
7182    def With23(e, b, c, n, a, p, x, u, d, m):
7183        k = Symbol("k")
7184        r = Numerator(Rt(-a/b, n))
7185        s = Denominator(Rt(-a/b, n))
7186        return Sum_doit((c*r + (-1)**(-2*k*p/n)*e*r*(r/s)**p + (-1)**(-2*k*m/n)*d*r*(r/s)**m)/(a*n*(-(-1)**(2*k/n)*s*u + r)), List(k, 1, n))
7187    pattern23 = Pattern(UtilityOperator((u_**p_*WC('e', S(1)) + u_**WC('m', S(1))*WC('d', S(1)) + WC('c', S(0)))/(a_ + u_**n_*WC('b', S(1))), x_), cons3, cons4, cons5, cons6, cons7, cons35, cons36)
7188    rule23 = ReplacementRule(pattern23, With23)
7189    def With24(e, b, c, f, n, a, p, x, u, d, q, m):
7190        k = Symbol("k")
7191        r = Numerator(Rt(-a/b, n))
7192        s = Denominator(Rt(-a/b, n))
7193        return Sum_doit((c*r + (-1)**(-2*k*q/n)*f*r*(r/s)**q + (-1)**(-2*k*p/n)*e*r*(r/s)**p + (-1)**(-2*k*m/n)*d*r*(r/s)**m)/(a*n*(-(-1)**(2*k/n)*s*u + r)), List(k, 1, n))
7194    pattern24 = Pattern(UtilityOperator((u_**p_*WC('e', S(1)) + u_**q_*WC('f', S(1)) + u_**WC('m', S(1))*WC('d', S(1)) + WC('c', S(0)))/(a_ + u_**n_*WC('b', S(1))), x_), cons3, cons4, cons5, cons6, cons7, cons8, cons37, cons38)
7195    rule24 = ReplacementRule(pattern24, With24)
7196    def With25(c, n, a, p, x, u):
7197        q = Symbol('q')
7198        return ReplaceAll(ExpandIntegrand(c**(-p), (c*x - q)**p*(c*x + q)**p, x), List(Rule(q, Rt(-a*c, S(2))), Rule(x, u**(n/S(2)))))
7199    pattern25 = Pattern(UtilityOperator((a_ + u_**WC('n', S(1))*WC('c', S(1)))**p_, x_), cons3, cons5, cons39, cons40)
7200    rule25 = ReplacementRule(pattern25, With25)
7201    def With26(c, n, a, p, x, u, m):
7202        q = Symbol('q')
7203        return ReplaceAll(ExpandIntegrand(c**(-p), x**m*(c*x**(n/S(2)) - q)**p*(c*x**(n/S(2)) + q)**p, x), List(Rule(q, Rt(-a*c, S(2))), Rule(x, u)))
7204    pattern26 = Pattern(UtilityOperator(u_**WC('m', S(1))*(u_**WC('n', S(1))*WC('c', S(1)) + WC('a', S(0)))**p_, x_), cons3, cons5, cons41, cons40, cons32, cons42)
7205    rule26 = ReplacementRule(pattern26, With26)
7206    def With27(b, c, n, a, p, x, u, j):
7207        q = Symbol('q')
7208        return ReplaceAll(ExpandIntegrand(S(4)**(-p)*c**(-p), (b + S(2)*c*x - q)**p*(b + S(2)*c*x + q)**p, x), List(Rule(q, Rt(-S(4)*a*c + b**S(2), S(2))), Rule(x, u**n)))
7209    pattern27 = Pattern(UtilityOperator((u_**WC('j', S(1))*WC('c', S(1)) + u_**WC('n', S(1))*WC('b', S(1)) + WC('a', S(0)))**p_, x_), cons3, cons4, cons5, cons30, cons23, cons40, cons43)
7210    rule27 = ReplacementRule(pattern27, With27)
7211    def With28(b, c, n, a, p, x, u, j, m):
7212        q = Symbol('q')
7213        return ReplaceAll(ExpandIntegrand(S(4)**(-p)*c**(-p), x**m*(b + S(2)*c*x**n - q)**p*(b + S(2)*c*x**n + q)**p, x), List(Rule(q, Rt(-S(4)*a*c + b**S(2), S(2))), Rule(x, u)))
7214    pattern28 = Pattern(UtilityOperator(u_**WC('m', S(1))*(u_**WC('j', S(1))*WC('c', S(1)) + u_**WC('n', S(1))*WC('b', S(1)) + WC('a', S(0)))**p_, x_), cons3, cons4, cons5, cons44, cons23, cons40, cons45, cons46, cons43)
7215    rule28 = ReplacementRule(pattern28, With28)
7216    def With29(b, c, n, a, x, u, d, j):
7217        q = Rt(-a/b, S(2))
7218        return -(c - d*q)/(S(2)*b*q*(q + u**n)) - (c + d*q)/(S(2)*b*q*(q - u**n))
7219    pattern29 = Pattern(UtilityOperator((u_**WC('n', S(1))*WC('d', S(1)) + WC('c', S(0)))/(a_ + u_**WC('j', S(1))*WC('b', S(1))), x_), cons3, cons4, cons5, cons6, cons14, cons23)
7220    rule29 = ReplacementRule(pattern29, With29)
7221    def With30(e, b, c, f, n, a, g, x, u, d, j):
7222        q = Rt(-S(4)*a*c + b**S(2), S(2))
7223        r = TogetherSimplify((-b*e*g + S(2)*c*(d + e*f))/q)
7224        return (e*g - r)/(b + 2*c*u**n + q) + (e*g + r)/(b + 2*c*u**n - q)
7225    pattern30 = Pattern(UtilityOperator(((u_**WC('n', S(1))*WC('g', S(1)) + WC('f', S(0)))*WC('e', S(1)) + WC('d', S(0)))/(u_**WC('j', S(1))*WC('c', S(1)) + u_**WC('n', S(1))*WC('b', S(1)) + WC('a', S(0))), x_), cons3, cons4, cons5, cons6, cons7, cons8, cons9, cons14, cons23, cons43)
7226    rule30 = ReplacementRule(pattern30, With30)
7227    def With31(v, x, u):
7228        lst = CoefficientList(u, x)
7229        i = Symbol('i')
7230        return x**Exponent(u, x)*lst[-1]/v + Sum_doit(x**(i - 1)*Part(lst, i), List(i, 1, Exponent(u, x)))/v
7231    pattern31 = Pattern(UtilityOperator(u_/v_, x_), cons19, cons47, cons48, cons49)
7232    rule31 = ReplacementRule(pattern31, With31)
7233    pattern32 = Pattern(UtilityOperator(u_/v_, x_), cons19, cons47, cons50)
7234    def replacement32(v, x, u):
7235        return PolynomialDivide(u, v, x)
7236    rule32 = ReplacementRule(pattern32, replacement32)
7237    pattern33 = Pattern(UtilityOperator(u_*(x_*WC('a', S(1)))**p_, x_), cons51, cons19)
7238    def replacement33(x, a, u, p):
7239        return ExpandToSum((a*x)**p, u, x)
7240    rule33 = ReplacementRule(pattern33, replacement33)
7241    pattern34 = Pattern(UtilityOperator(v_**p_*WC('u', S(1)), x_), cons51)
7242    def replacement34(v, x, u, p):
7243        return ExpandIntegrand(NormalizeIntegrand(v**p, x), u, x)
7244    rule34 = ReplacementRule(pattern34, replacement34)
7245    pattern35 = Pattern(UtilityOperator(u_, x_))
7246    def replacement35(x, u):
7247        return ExpandExpression(u, x)
7248    rule35 = ReplacementRule(pattern35, replacement35)
7249    return [ rule2,rule3, rule4, rule5, rule6, rule7, rule8, rule10, rule12, rule13, rule14, rule15, rule16, rule17, rule18, rule19, rule20, rule21, rule22, rule23, rule24, rule25, rule26, rule27, rule28, rule29, rule30, rule31, rule32, rule33, rule34, rule35]
7250
7251def _RemoveContentAux():
7252    def cons_f1(b, a):
7253        return IntegersQ(a, b)
7254
7255    cons1 = CustomConstraint(cons_f1)
7256
7257    def cons_f2(b, a):
7258        return Equal(a + b, S(0))
7259
7260    cons2 = CustomConstraint(cons_f2)
7261
7262    def cons_f3(m):
7263        return RationalQ(m)
7264
7265    cons3 = CustomConstraint(cons_f3)
7266
7267    def cons_f4(m, n):
7268        return RationalQ(m, n)
7269
7270    cons4 = CustomConstraint(cons_f4)
7271
7272    def cons_f5(m, n):
7273        return GreaterEqual(-m + n, S(0))
7274
7275    cons5 = CustomConstraint(cons_f5)
7276
7277    def cons_f6(a, x):
7278        return FreeQ(a, x)
7279
7280    cons6 = CustomConstraint(cons_f6)
7281
7282    def cons_f7(m, n, p):
7283        return RationalQ(m, n, p)
7284
7285    cons7 = CustomConstraint(cons_f7)
7286
7287    def cons_f8(m, p):
7288        return GreaterEqual(-m + p, S(0))
7289
7290    cons8 = CustomConstraint(cons_f8)
7291
7292    pattern1 = Pattern(UtilityOperator(a_**m_*WC('u', S(1)) + b_*WC('v', S(1)), x_), cons1, cons2, cons3)
7293    def replacement1(v, x, a, u, m, b):
7294        return If(Greater(m, S(1)), RemoveContentAux(a**(m + S(-1))*u - v, x), RemoveContentAux(-a**(-m + S(1))*v + u, x))
7295    rule1 = ReplacementRule(pattern1, replacement1)
7296    pattern2 = Pattern(UtilityOperator(a_**WC('m', S(1))*WC('u', S(1)) + a_**WC('n', S(1))*WC('v', S(1)), x_), cons6, cons4, cons5)
7297    def replacement2(n, v, x, u, m, a):
7298        return RemoveContentAux(a**(-m + n)*v + u, x)
7299    rule2 = ReplacementRule(pattern2, replacement2)
7300    pattern3 = Pattern(UtilityOperator(a_**WC('m', S(1))*WC('u', S(1)) + a_**WC('n', S(1))*WC('v', S(1)) + a_**WC('p', S(1))*WC('w', S(1)), x_), cons6, cons7, cons5, cons8)
7301    def replacement3(n, v, x, p, u, w, m, a):
7302        return RemoveContentAux(a**(-m + n)*v + a**(-m + p)*w + u, x)
7303    rule3 = ReplacementRule(pattern3, replacement3)
7304    pattern4 = Pattern(UtilityOperator(u_, x_))
7305    def replacement4(u, x):
7306        return If(And(SumQ(u), NegQ(First(u))), -u, u)
7307    rule4 = ReplacementRule(pattern4, replacement4)
7308    return [rule1, rule2, rule3, rule4, ]
7309
7310IntHide = Int
7311Log = rubi_log
7312Null = None
7313if matchpy:
7314    RemoveContentAux_replacer = ManyToOneReplacer(* _RemoveContentAux())
7315    ExpandIntegrand_rules = _ExpandIntegrand()
7316    TrigSimplifyAux_replacer = _TrigSimplifyAux()
7317    SimplifyAntiderivative_replacer = _SimplifyAntiderivative()
7318    SimplifyAntiderivativeSum_replacer = _SimplifyAntiderivativeSum()
7319    FixSimplify_rules = _FixSimplify()
7320    SimpFixFactor_replacer = _SimpFixFactor()
7321