text:
int_rules_1_1_3_4 = @theory begin

    #= ::Subsection::Closed:: =#
    #= 1.1.3.4*(e*x)^m*(a+b*x^n)^p*(c+d*x^n)^q =#
    @apply_utils Antiderivative((~(e') * ~x) ^ ~(m') * (~(b') * (~x) ^ ~n) ^ ~p * (~c + ~(d') * (~x) ^ ~n) ^ ~(q'), ~x) => ((~e) ^ ~m / (~n * (~b) ^ (Simplify((~m + 1) / ~n) - 1))) * Subst(Antiderivative((~b * ~x) ^ ((~p + Simplify((~m + 1) / ~n)) - 1) * (~c + ~d * ~x) ^ ~q, ~x), ~x, (~x) ^ ~n) <-- FreeQ([~b, ~c, ~d, ~e, ~m, ~n, ~p, ~q], ~x) && ((IntegerQ(~m) || GtQ(~e, 0)) && IntegerQ(Simplify((~m + 1) / ~n)))
    @apply_utils Antiderivative((~(e') * ~x) ^ ~(m') * (~(b') * (~x) ^ ~(n')) ^ ~p * (~c + ~(d') * (~x) ^ ~n) ^ ~(q'), ~x) => (((~e) ^ ~m * (~b) ^ IntPart(~p) * (~b * (~x) ^ ~n) ^ FracPart(~p)) / (~x) ^ (~n * FracPart(~p))) * Antiderivative((~x) ^ (~m + ~n * ~p) * (~c + ~d * (~x) ^ ~n) ^ ~q, ~x) <-- FreeQ([~b, ~c, ~d, ~e, ~m, ~n, ~p, ~q], ~x) && ((IntegerQ(~m) || GtQ(~e, 0)) && Not(IntegerQ(Simplify((~m + 1) / ~n))))
    @apply_utils Antiderivative((~e * ~x) ^ ~m * (~(b') * (~x) ^ ~(n')) ^ ~p * (~c + ~(d') * (~x) ^ ~n) ^ ~(q'), ~x) => (((~e) ^ IntPart(~m) * (~e * ~x) ^ FracPart(~m)) / (~x) ^ FracPart(~m)) * Antiderivative((~x) ^ ~m * (~b * (~x) ^ ~n) ^ ~p * (~c + ~d * (~x) ^ ~n) ^ ~q, ~x) <-- FreeQ([~b, ~c, ~d, ~e, ~m, ~n, ~p, ~q], ~x) && Not(IntegerQ(~m))
    @apply_utils Antiderivative(~x / ((~a + ~(b') * (~x) ^ 2) ^ (1 / 4) * (~c + ~(d') * (~x) ^ 2)), ~x) => (-1 / (sqrt(2) * Rt(~a, 4) * ~d)) * atan((Rt(~a, 4) ^ 2 - sqrt(~a + ~b * (~x) ^ 2)) / (sqrt(2) * Rt(~a, 4) * (~a + ~b * (~x) ^ 2) ^ (1 / 4))) - (1 / (sqrt(2) * Rt(~a, 4) * ~d)) * atanh((Rt(~a, 4) ^ 2 + sqrt(~a + ~b * (~x) ^ 2)) / (sqrt(2) * Rt(~a, 4) * (~a + ~b * (~x) ^ 2) ^ (1 / 4))) <-- FreeQ([~a, ~b, ~c, ~d], ~x) && (EqQ(~b * ~c - 2 * ~a * ~d, 0) && PosQ(~a))
    @apply_utils Antiderivative((~x) ^ ~m / ((~a + ~(b') * (~x) ^ 2) ^ (1 / 4) * (~c + ~(d') * (~x) ^ 2)), ~x) => Antiderivative(ExpandIntegrand((~x) ^ ~m / ((~a + ~b * (~x) ^ 2) ^ (1 / 4) * (~c + ~d * (~x) ^ 2)), ~x), ~x) <-- FreeQ([~a, ~b, ~c, ~d], ~x) && (EqQ(~b * ~c - 2 * ~a * ~d, 0) && (IntegerQ(~m) && (PosQ(~a) || IntegerQ(~m / 2))))
    @apply_utils Antiderivative((~x) ^ 2 / ((~a + ~(b') * (~x) ^ 2) ^ (3 / 4) * (~c + ~(d') * (~x) ^ 2)), ~x) => (-(~b) / (~a * ~d * Rt((~b) ^ 2 / ~a, 4) ^ 3)) * atan((~b + Rt((~b) ^ 2 / ~a, 4) ^ 2 * sqrt(~a + ~b * (~x) ^ 2)) / (Rt((~b) ^ 2 / ~a, 4) ^ 3 * ~x * (~a + ~b * (~x) ^ 2) ^ (1 / 4))) + (~b / (~a * ~d * Rt((~b) ^ 2 / ~a, 4) ^ 3)) * atanh((~b - Rt((~b) ^ 2 / ~a, 4) ^ 2 * sqrt(~a + ~b * (~x) ^ 2)) / (Rt((~b) ^ 2 / ~a, 4) ^ 3 * ~x * (~a + ~b * (~x) ^ 2) ^ (1 / 4))) <-- FreeQ([~a, ~b, ~c, ~d], ~x) && (EqQ(~b * ~c - 2 * ~a * ~d, 0) && PosQ((~b) ^ 2 / ~a))
    @apply_utils Antiderivative((~x) ^ 2 / ((~a + ~(b') * (~x) ^ 2) ^ (3 / 4) * (~c + ~(d') * (~x) ^ 2)), ~x) => (-(~b) / (sqrt(2) * ~a * ~d * Rt(-((~b) ^ 2) / ~a, 4) ^ 3)) * atan((Rt(-((~b) ^ 2) / ~a, 4) * ~x) / (sqrt(2) * (~a + ~b * (~x) ^ 2) ^ (1 / 4))) + (~b / (sqrt(2) * ~a * ~d * Rt(-((~b) ^ 2) / ~a, 4) ^ 3)) * atanh((Rt(-((~b) ^ 2) / ~a, 4) * ~x) / (sqrt(2) * (~a + ~b * (~x) ^ 2) ^ (1 / 4))) <-- FreeQ([~a, ~b, ~c, ~d], ~x) && (EqQ(~b * ~c - 2 * ~a * ~d, 0) && NegQ((~b) ^ 2 / ~a))
    @apply_utils Antiderivative((~x) ^ ~m / ((~a + ~(b') * (~x) ^ 2) ^ (3 / 4) * (~c + ~(d') * (~x) ^ 2)), ~x) => Antiderivative(ExpandIntegrand((~x) ^ ~m / ((~a + ~b * (~x) ^ 2) ^ (3 / 4) * (~c + ~d * (~x) ^ 2)), ~x), ~x) <-- FreeQ([~a, ~b, ~c, ~d], ~x) && (EqQ(~b * ~c - 2 * ~a * ~d, 0) && (IntegerQ(~m) && (PosQ(~a) || IntegerQ(~m / 2))))
    @apply_utils Antiderivative((~x) ^ ~(m') * (~a + ~(b') * (~x) ^ ~n) ^ ~(p') * (~c + ~(d') * (~x) ^ ~n) ^ ~(q'), ~x) => (1 / ~n) * Subst(Antiderivative((~a + ~b * ~x) ^ ~p * (~c + ~d * ~x) ^ ~q, ~x), ~x, (~x) ^ ~n) <-- FreeQ([~a, ~b, ~c, ~d, ~m, ~n, ~p, ~q], ~x) && (NeQ(~b * ~c - ~a * ~d, 0) && EqQ((~m - ~n) + 1, 0))
    @apply_utils Antiderivative((~x) ^ ~(m') * (~a + ~(b') * (~x) ^ ~n) ^ ~(p') * (~c + ~(d') * (~x) ^ ~n) ^ ~(q'), ~x) => Antiderivative((~x) ^ (~m + ~n * (~p + ~q)) * (~b + ~a * (~x) ^ -(~n)) ^ ~p * (~d + ~c * (~x) ^ -(~n)) ^ ~q, ~x) <-- FreeQ([~a, ~b, ~c, ~d, ~m, ~n], ~x) && (NeQ(~b * ~c - ~a * ~d, 0) && (IntegersQ(~p, ~q) && NegQ(~n)))
    @apply_utils Antiderivative((~x) ^ ~(m') * (~a + ~(b') * (~x) ^ ~n) ^ ~(p') * (~c + ~(d') * (~x) ^ ~n) ^ ~(q'), ~x) => (1 / ~n) * Subst(Antiderivative((~x) ^ (Simplify((~m + 1) / ~n) - 1) * (~a + ~b * ~x) ^ ~p * (~c + ~d * ~x) ^ ~q, ~x), ~x, (~x) ^ ~n) <-- FreeQ([~a, ~b, ~c, ~d, ~m, ~n, ~p, ~q], ~x) && (NeQ(~b * ~c - ~a * ~d, 0) && IntegerQ(Simplify((~m + 1) / ~n)))
    @apply_utils Antiderivative((~e * ~x) ^ ~(m') * (~a + ~(b') * (~x) ^ ~n) ^ ~(p') * (~c + ~(d') * (~x) ^ ~n) ^ ~(q'), ~x) => (((~e) ^ IntPart(~m) * (~e * ~x) ^ FracPart(~m)) / (~x) ^ FracPart(~m)) * Antiderivative((~x) ^ ~m * (~a + ~b * (~x) ^ ~n) ^ ~p * (~c + ~d * (~x) ^ ~n) ^ ~q, ~x) <-- FreeQ([~a, ~b, ~c, ~d, ~e, ~m, ~n, ~p, ~q], ~x) && (NeQ(~b * ~c - ~a * ~d, 0) && IntegerQ(Simplify((~m + 1) / ~n)))
    @apply_utils Antiderivative((~(e') * ~x) ^ ~(m') * (~a + ~(b') * (~x) ^ ~n) ^ ~(p') * (~c + ~(d') * (~x) ^ ~n) ^ ~(q'), ~x) => Antiderivative(ExpandIntegrand((~e * ~x) ^ ~m * (~a + ~b * (~x) ^ ~n) ^ ~p * (~c + ~d * (~x) ^ ~n) ^ ~q, ~x), ~x) <-- FreeQ([~a, ~b, ~c, ~d, ~e, ~m, ~n], ~x) && (NeQ(~b * ~c - ~a * ~d, 0) && (IGtQ(~p, 0) && IGtQ(~q, 0)))
    @apply_utils Antiderivative((~(e') * ~x) ^ ~(m') * (~a + ~(b') * (~x) ^ ~n) ^ ~(p') * (~c + ~(d') * (~x) ^ ~n), ~x) => (~c * (~e * ~x) ^ (~m + 1) * (~a + ~b * (~x) ^ ~n) ^ (~p + 1)) / (~a * ~e * (~m + 1)) <-- FreeQ([~a, ~b, ~c, ~d, ~e, ~m, ~n, ~p], ~x) && (NeQ(~b * ~c - ~a * ~d, 0) && (EqQ(~a * ~d * (~m + 1) - ~b * ~c * (~m + ~n * (~p + 1) + 1), 0) && NeQ(~m, -1)))
    @apply_utils Antiderivative((~(e') * ~x) ^ ~(m') * (~a1 + ~(b1') * (~x) ^ ~(non2')) ^ ~(p') * (~a2 + ~(b2') * (~x) ^ ~(non2')) ^ ~(p') * (~c + ~(d') * (~x) ^ ~n), ~x) => (~c * (~e * ~x) ^ (~m + 1) * (~a1 + ~b1 * (~x) ^ (~n / 2)) ^ (~p + 1) * (~a2 + ~b2 * (~x) ^ (~n / 2)) ^ (~p + 1)) / (~a1 * ~a2 * ~e * (~m + 1)) <-- FreeQ([~a1, ~b1, ~a2, ~b2, ~c, ~d, ~e, ~m, ~n, ~p], ~x) && (EqQ(~non2, ~n / 2) && (EqQ(~a2 * ~b1 + ~a1 * ~b2, 0) && (EqQ(~a1 * ~a2 * ~d * (~m + 1) - ~b1 * ~b2 * ~c * (~m + ~n * (~p + 1) + 1), 0) && NeQ(~m, -1))))
    @apply_utils Antiderivative((~(e') * ~x) ^ ~(m') * (~a + ~(b') * (~x) ^ ~n) ^ ~(p') * (~c + ~(d') * (~x) ^ ~n), ~x) => (~c * (~e * ~x) ^ (~m + 1) * (~a + ~b * (~x) ^ ~n) ^ (~p + 1)) / (~a * ~e * (~m + 1)) + (~d / (~e) ^ ~n) * Antiderivative((~e * ~x) ^ (~m + ~n) * (~a + ~b * (~x) ^ ~n) ^ ~p, ~x) <-- FreeQ([~a, ~b, ~c, ~d, ~e, ~m, ~n, ~p], ~x) && (NeQ(~b * ~c - ~a * ~d, 0) && (EqQ(~m + ~n * (~p + 1) + 1, 0) && ((IntegerQ(~n) || GtQ(~e, 0)) && (GtQ(~n, 0) && LtQ(~m, -1) || LtQ(~n, 0) && GtQ(~m + ~n, -1)))))
    @apply_utils Antiderivative((~(e') * ~x) ^ ~(m') * (~a + ~(b') * (~x) ^ ~n) ^ ~(p') * (~c + ~(d') * (~x) ^ ~n), ~x) => ((~b * ~c - ~a * ~d) * (~e * ~x) ^ (~m + 1) * (~a + ~b * (~x) ^ ~n) ^ (~p + 1)) / (~a * ~b * ~e * (~m + 1)) + (~d / ~b) * Antiderivative((~e * ~x) ^ ~m * (~a + ~b * (~x) ^ ~n) ^ (~p + 1), ~x) <-- FreeQ([~a, ~b, ~c, ~d, ~e, ~m, ~n, ~p], ~x) && (NeQ(~b * ~c - ~a * ~d, 0) && (EqQ(~m + ~n * (~p + 1) + 1, 0) && NeQ(~m, -1)))
    @apply_utils Antiderivative((~(e') * ~x) ^ ~(m') * (~a + ~(b') * (~x) ^ ~n) ^ ~(p') * (~c + ~(d') * (~x) ^ ~n), ~x) => (~c * (~e * ~x) ^ (~m + 1) * (~a + ~b * (~x) ^ ~n) ^ (~p + 1)) / (~a * ~e * (~m + 1)) + ((~a * ~d * (~m + 1) - ~b * ~c * (~m + ~n * (~p + 1) + 1)) / (~a * (~e) ^ ~n * (~m + 1))) * Antiderivative((~e * ~x) ^ (~m + ~n) * (~a + ~b * (~x) ^ ~n) ^ ~p, ~x) <-- FreeQ([~a, ~b, ~c, ~d, ~e, ~p], ~x) && (NeQ(~b * ~c - ~a * ~d, 0) && ((IntegerQ(~n) || GtQ(~e, 0)) && ((GtQ(~n, 0) && LtQ(~m, -1) || LtQ(~n, 0) && GtQ(~m + ~n, -1)) && Not(ILtQ(~p, -1)))))
    @apply_utils Antiderivative((~(e') * ~x) ^ ~(m') * (~a1 + ~(b1') * (~x) ^ ~(non2')) ^ ~(p') * (~a2 + ~(b2') * (~x) ^ ~(non2')) ^ ~(p') * (~c + ~(d') * (~x) ^ ~n), ~x) => (~c * (~e * ~x) ^ (~m + 1) * (~a1 + ~b1 * (~x) ^ (~n / 2)) ^ (~p + 1) * (~a2 + ~b2 * (~x) ^ (~n / 2)) ^ (~p + 1)) / (~a1 * ~a2 * ~e * (~m + 1)) + ((~a1 * ~a2 * ~d * (~m + 1) - ~b1 * ~b2 * ~c * (~m + ~n * (~p + 1) + 1)) / (~a1 * ~a2 * (~e) ^ ~n * (~m + 1))) * Antiderivative((~e * ~x) ^ (~m + ~n) * (~a1 + ~b1 * (~x) ^ (~n / 2)) ^ ~p * (~a2 + ~b2 * (~x) ^ (~n / 2)) ^ ~p, ~x) <-- FreeQ([~a1, ~b1, ~a2, ~b2, ~c, ~d, ~e, ~p], ~x) && (EqQ(~non2, ~n / 2) && (EqQ(~a2 * ~b1 + ~a1 * ~b2, 0) && ((IntegerQ(~n) || GtQ(~e, 0)) && ((GtQ(~n, 0) && LtQ(~m, -1) || LtQ(~n, 0) && GtQ(~m + ~n, -1)) && Not(ILtQ(~p, -1))))))
    @apply_utils Antiderivative((~x) ^ ~m * (~a + ~(b') * (~x) ^ 2) ^ ~p * (~c + ~(d') * (~x) ^ 2), ~x) => ((-(~a)) ^ (~m / 2 - 1) * (~b * ~c - ~a * ~d) * ~x * (~a + ~b * (~x) ^ 2) ^ (~p + 1)) / (2 * (~b) ^ (~m / 2 + 1) * (~p + 1)) + (1 / (2 * (~b) ^ (~m / 2 + 1) * (~p + 1))) * Antiderivative((~a + ~b * (~x) ^ 2) ^ (~p + 1) * ExpandToSum(2 * ~b * (~p + 1) * (~x) ^ 2 * Together(((~b) ^ (~m / 2) * (~x) ^ (~m - 2) * (~c + ~d * (~x) ^ 2) - (-(~a)) ^ (~m / 2 - 1) * (~b * ~c - ~a * ~d)) / (~a + ~b * (~x) ^ 2)) - (-(~a)) ^ (~m / 2 - 1) * (~b * ~c - ~a * ~d), ~x), ~x) <-- FreeQ([~a, ~b, ~c, ~d], ~x) && (NeQ(~b * ~c - ~a * ~d, 0) && (LtQ(~p, -1) && (IGtQ(~m / 2, 0) && (IntegerQ(~p) || EqQ(~m + 2 * ~p + 1, 0)))))
    @apply_utils Antiderivative((~x) ^ ~m * (~a + ~(b') * (~x) ^ 2) ^ ~p * (~c + ~(d') * (~x) ^ 2), ~x) => ((-(~a)) ^ (~m / 2 - 1) * (~b * ~c - ~a * ~d) * ~x * (~a + ~b * (~x) ^ 2) ^ (~p + 1)) / (2 * (~b) ^ (~m / 2 + 1) * (~p + 1)) + (1 / (2 * (~b) ^ (~m / 2 + 1) * (~p + 1))) * Antiderivative((~x) ^ ~m * (~a + ~b * (~x) ^ 2) ^ (~p + 1) * ExpandToSum(2 * ~b * (~p + 1) * Together(((~b) ^ (~m / 2) * (~c + ~d * (~x) ^ 2) - (-(~a)) ^ (~m / 2 - 1) * (~b * ~c - ~a * ~d) * (~x) ^ (-(~m) + 2)) / (~a + ~b * (~x) ^ 2)) - (-(~a)) ^ (~m / 2 - 1) * (~b * ~c - ~a * ~d) * (~x) ^ -(~m), ~x), ~x) <-- FreeQ([~a, ~b, ~c, ~d], ~x) && (NeQ(~b * ~c - ~a * ~d, 0) && (LtQ(~p, -1) && (ILtQ(~m / 2, 0) && (IntegerQ(~p) || EqQ(~m + 2 * ~p + 1, 0)))))
    @apply_utils Antiderivative((~(e') * ~x) ^ ~(m') * (~a + ~(b') * (~x) ^ ~n) ^ ~(p') * (~c + ~(d') * (~x) ^ ~n), ~x) => (-((~b * ~c - ~a * ~d)) * (~e * ~x) ^ (~m + 1) * (~a + ~b * (~x) ^ ~n) ^ (~p + 1)) / (~a * ~b * ~e * ~n * (~p + 1)) - ((~a * ~d * (~m + 1) - ~b * ~c * (~m + ~n * (~p + 1) + 1)) / (~a * ~b * ~n * (~p + 1))) * Antiderivative((~e * ~x) ^ ~m * (~a + ~b * (~x) ^ ~n) ^ (~p + 1), ~x) <-- FreeQ([~a, ~b, ~c, ~d, ~e, ~m, ~n], ~x) && (NeQ(~b * ~c - ~a * ~d, 0) && (LtQ(~p, -1) && (Not(IntegerQ(~p + 1 / 2)) && NeQ(~p, -5 / 4) || (Not(RationalQ(~m)) || IGtQ(~n, 0) && (ILtQ(~p + 1 / 2, 0) && LeQ(-1, ~m, -(~n) * (~p + 1)))))))
    @apply_utils Antiderivative((~(e') * ~x) ^ ~(m') * (~a1 + ~(b1') * (~x) ^ ~(non2')) ^ ~(p') * (~a2 + ~(b2') * (~x) ^ ~(non2')) ^ ~(p') * (~c + ~(d') * (~x) ^ ~n), ~x) => (-((~b1 * ~b2 * ~c - ~a1 * ~a2 * ~d)) * (~e * ~x) ^ (~m + 1) * (~a1 + ~b1 * (~x) ^ (~n / 2)) ^ (~p + 1) * (~a2 + ~b2 * (~x) ^ (~n / 2)) ^ (~p + 1)) / (~a1 * ~a2 * ~b1 * ~b2 * ~e * ~n * (~p + 1)) - ((~a1 * ~a2 * ~d * (~m + 1) - ~b1 * ~b2 * ~c * (~m + ~n * (~p + 1) + 1)) / (~a1 * ~a2 * ~b1 * ~b2 * ~n * (~p + 1))) * Antiderivative((~e * ~x) ^ ~m * (~a1 + ~b1 * (~x) ^ (~n / 2)) ^ (~p + 1) * (~a2 + ~b2 * (~x) ^ (~n / 2)) ^ (~p + 1), ~x) <-- FreeQ([~a1, ~b1, ~a2, ~b2, ~c, ~d, ~e, ~m, ~n], ~x) && (EqQ(~non2, ~n / 2) && (EqQ(~a2 * ~b1 + ~a1 * ~b2, 0) && (LtQ(~p, -1) && (Not(IntegerQ(~p + 1 / 2)) && NeQ(~p, -5 / 4) || (Not(RationalQ(~m)) || IGtQ(~n, 0) && (ILtQ(~p + 1 / 2, 0) && LeQ(-1, ~m, -(~n) * (~p + 1))))))))
    @apply_utils Antiderivative((~(e') * ~x) ^ ~(m') * (~a + ~(b') * (~x) ^ ~n) ^ ~(p') * (~c + ~(d') * (~x) ^ ~n), ~x) => (~d * (~e * ~x) ^ (~m + 1) * (~a + ~b * (~x) ^ ~n) ^ (~p + 1)) / (~b * ~e * (~m + ~n * (~p + 1) + 1)) - ((~a * ~d * (~m + 1) - ~b * ~c * (~m + ~n * (~p + 1) + 1)) / (~b * (~m + ~n * (~p + 1) + 1))) * Antiderivative((~e * ~x) ^ ~m * (~a + ~b * (~x) ^ ~n) ^ ~p, ~x) <-- FreeQ([~a, ~b, ~c, ~d, ~e, ~m, ~n, ~p], ~x) && (NeQ(~b * ~c - ~a * ~d, 0) && NeQ(~m + ~n * (~p + 1) + 1, 0))
    @apply_utils Antiderivative((~(e') * ~x) ^ ~(m') * (~a1 + ~(b1') * (~x) ^ ~(non2')) ^ ~(p') * (~a2 + ~(b2') * (~x) ^ ~(non2')) ^ ~(p') * (~c + ~(d') * (~x) ^ ~n), ~x) => (~d * (~e * ~x) ^ (~m + 1) * (~a1 + ~b1 * (~x) ^ (~n / 2)) ^ (~p + 1) * (~a2 + ~b2 * (~x) ^ (~n / 2)) ^ (~p + 1)) / (~b1 * ~b2 * ~e * (~m + ~n * (~p + 1) + 1)) - ((~a1 * ~a2 * ~d * (~m + 1) - ~b1 * ~b2 * ~c * (~m + ~n * (~p + 1) + 1)) / (~b1 * ~b2 * (~m + ~n * (~p + 1) + 1))) * Antiderivative((~e * ~x) ^ ~m * (~a1 + ~b1 * (~x) ^ (~n / 2)) ^ ~p * (~a2 + ~b2 * (~x) ^ (~n / 2)) ^ ~p, ~x) <-- FreeQ([~a1, ~b1, ~a2, ~b2, ~c, ~d, ~e, ~m, ~n, ~p], ~x) && (EqQ(~non2, ~n / 2) && (EqQ(~a2 * ~b1 + ~a1 * ~b2, 0) && NeQ(~m + ~n * (~p + 1) + 1, 0)))
    @apply_utils Antiderivative(((~(e') * ~x) ^ ~(m') * (~a + ~(b') * (~x) ^ ~n) ^ ~p) / (~c + ~(d') * (~x) ^ ~n), ~x) => Antiderivative(ExpandIntegrand(((~e * ~x) ^ ~m * (~a + ~b * (~x) ^ ~n) ^ ~p) / (~c + ~d * (~x) ^ ~n), ~x), ~x) <-- FreeQ([~a, ~b, ~c, ~d, ~e, ~m], ~x) && (NeQ(~b * ~c - ~a * ~d, 0) && (IGtQ(~n, 0) && (IGtQ(~p, 0) && (IntegerQ(~m) || (IGtQ(2 * (~m + 1), 0) || Not(RationalQ(~m)))))))
    @apply_utils Antiderivative((~(e') * ~x) ^ ~m * (~a + ~(b') * (~x) ^ ~n) ^ ~p * (~c + ~(d') * (~x) ^ ~n) ^ 2, ~x) => ((~c) ^ 2 * (~e * ~x) ^ (~m + 1) * (~a + ~b * (~x) ^ ~n) ^ (~p + 1)) / (~a * ~e * (~m + 1)) - (1 / (~a * (~e) ^ ~n * (~m + 1))) * Antiderivative((~e * ~x) ^ (~m + ~n) * (~a + ~b * (~x) ^ ~n) ^ ~p * Simp((~b * (~c) ^ 2 * ~n * (~p + 1) + ~c * (~b * ~c - 2 * ~a * ~d) * (~m + 1)) - ~a * (~m + 1) * (~d) ^ 2 * (~x) ^ ~n, ~x), ~x) <-- FreeQ([~a, ~b, ~c, ~d, ~e, ~p], ~x) && (NeQ(~b * ~c - ~a * ~d, 0) && (IGtQ(~n, 0) && (LtQ(~m, -1) && GtQ(~n, 0))))
    @apply_utils Antiderivative((~(e') * ~x) ^ ~(m') * (~a + ~(b') * (~x) ^ ~n) ^ ~p * (~c + ~(d') * (~x) ^ ~n) ^ 2, ~x) => (-((~b * ~c - ~a * ~d) ^ 2) * (~e * ~x) ^ (~m + 1) * (~a + ~b * (~x) ^ ~n) ^ (~p + 1)) / (~a * (~b) ^ 2 * ~e * ~n * (~p + 1)) + (1 / (~a * (~b) ^ 2 * ~n * (~p + 1))) * Antiderivative((~e * ~x) ^ ~m * (~a + ~b * (~x) ^ ~n) ^ (~p + 1) * Simp((~b * ~c - ~a * ~d) ^ 2 * (~m + 1) + (~b) ^ 2 * (~c) ^ 2 * ~n * (~p + 1) + ~a * ~b * (~d) ^ 2 * ~n * (~p + 1) * (~x) ^ ~n, ~x), ~x) <-- FreeQ([~a, ~b, ~c, ~d, ~e, ~m, ~n], ~x) && (NeQ(~b * ~c - ~a * ~d, 0) && (IGtQ(~n, 0) && LtQ(~p, -1)))
    @apply_utils Antiderivative((~(e') * ~x) ^ ~(m') * (~a + ~(b') * (~x) ^ ~n) ^ ~p * (~c + ~(d') * (~x) ^ ~n) ^ 2, ~x) => ((~d) ^ 2 * (~e * ~x) ^ (~m + ~n + 1) * (~a + ~b * (~x) ^ ~n) ^ (~p + 1)) / (~b * (~e) ^ (~n + 1) * (~m + ~n * (~p + 2) + 1)) + (1 / (~b * (~m + ~n * (~p + 2) + 1))) * Antiderivative((~e * ~x) ^ ~m * (~a + ~b * (~x) ^ ~n) ^ ~p * Simp(~b * (~c) ^ 2 * (~m + ~n * (~p + 2) + 1) + ~d * ((2 * ~b * ~c - ~a * ~d) * (~m + ~n + 1) + 2 * ~b * ~c * ~n * (~p + 1)) * (~x) ^ ~n, ~x), ~x) <-- FreeQ([~a, ~b, ~c, ~d, ~e, ~m, ~n, ~p], ~x) && (NeQ(~b * ~c - ~a * ~d, 0) && (IGtQ(~n, 0) && NeQ(~m + ~n * (~p + 2) + 1, 0)))
    @apply_utils Antiderivative((~x) ^ ~(m') * (~a + ~(b') * (~x) ^ ~n) ^ ~p * (~c + ~(d') * (~x) ^ ~n) ^ ~q, ~x) => With([k = GCD(~m + 1, ~n)], (1 / k) * Subst(Antiderivative((~x) ^ ((~m + 1) / k - 1) * (~a + ~b * (~x) ^ (~n / k)) ^ ~p * (~c + ~d * (~x) ^ (~n / k)) ^ ~q, ~x), ~x, (~x) ^ k) <-- k != 1) <-- FreeQ([~a, ~b, ~c, ~d, ~p, ~q], ~x) && (NeQ(~b * ~c - ~a * ~d, 0) && (IGtQ(~n, 0) && IntegerQ(~m)))
    @apply_utils Antiderivative((~(e') * ~x) ^ ~m * (~a + ~(b') * (~x) ^ ~n) ^ ~p * (~c + ~(d') * (~x) ^ ~n) ^ ~q, ~x) => With([k = Denominator(~m)], (k / ~e) * Subst(Antiderivative((~x) ^ (k * (~m + 1) - 1) * (~a + (~b * (~x) ^ (k * ~n)) / (~e) ^ ~n) ^ ~p * (~c + (~d * (~x) ^ (k * ~n)) / (~e) ^ ~n) ^ ~q, ~x), ~x, (~e * ~x) ^ (1 / k))) <-- FreeQ([~a, ~b, ~c, ~d, ~e, ~p, ~q], ~x) && (NeQ(~b * ~c - ~a * ~d, 0) && (IGtQ(~n, 0) && (FractionQ(~m) && IntegerQ(~p))))
    @apply_utils Antiderivative((~(e') * ~x) ^ ~(m') * (~a + ~(b') * (~x) ^ ~n) ^ ~p * (~c + ~(d') * (~x) ^ ~n) ^ ~q, ~x) => ((~e) ^ (~n - 1) * (~e * ~x) ^ ((~m - ~n) + 1) * (~a + ~b * (~x) ^ ~n) ^ (~p + 1) * (~c + ~d * (~x) ^ ~n) ^ ~q) / (~b * ~n * (~p + 1)) - ((~e) ^ ~n / (~b * ~n * (~p + 1))) * Antiderivative((~e * ~x) ^ (~m - ~n) * (~a + ~b * (~x) ^ ~n) ^ (~p + 1) * (~c + ~d * (~x) ^ ~n) ^ (~q - 1) * Simp(~c * ((~m - ~n) + 1) + ~d * (~m + ~n * (~q - 1) + 1) * (~x) ^ ~n, ~x), ~x) <-- FreeQ([~a, ~b, ~c, ~d, ~e], ~x) && (NeQ(~b * ~c - ~a * ~d, 0) && (IGtQ(~n, 0) && (LtQ(~p, -1) && (GtQ(~q, 0) && (GtQ((~m - ~n) + 1, 0) && IntBinomialQ(~a, ~b, ~c, ~d, ~e, ~m, ~n, ~p, ~q, ~x))))))
    @apply_utils Antiderivative((~(e') * ~x) ^ ~(m') * (~a + ~(b') * (~x) ^ ~n) ^ ~p * (~c + ~(d') * (~x) ^ ~n) ^ ~q, ~x) => (-((~c * ~b - ~a * ~d)) * (~e * ~x) ^ (~m + 1) * (~a + ~b * (~x) ^ ~n) ^ (~p + 1) * (~c + ~d * (~x) ^ ~n) ^ (~q - 1)) / (~a * ~b * ~e * ~n * (~p + 1)) + (1 / (~a * ~b * ~n * (~p + 1))) * Antiderivative((~e * ~x) ^ ~m * (~a + ~b * (~x) ^ ~n) ^ (~p + 1) * (~c + ~d * (~x) ^ ~n) ^ (~q - 2) * Simp(~c * (~c * ~b * ~n * (~p + 1) + (~c * ~b - ~a * ~d) * (~m + 1)) + ~d * (~c * ~b * ~n * (~p + 1) + (~c * ~b - ~a * ~d) * (~m + ~n * (~q - 1) + 1)) * (~x) ^ ~n, ~x), ~x) <-- FreeQ([~a, ~b, ~c, ~d, ~e, ~m], ~x) && (NeQ(~b * ~c - ~a * ~d, 0) && (IGtQ(~n, 0) && (LtQ(~p, -1) && (GtQ(~q, 1) && IntBinomialQ(~a, ~b, ~c, ~d, ~e, ~m, ~n, ~p, ~q, ~x)))))
    @apply_utils Antiderivative((~(e') * ~x) ^ ~(m') * (~a + ~(b') * (~x) ^ ~n) ^ ~p * (~c + ~(d') * (~x) ^ ~n) ^ ~q, ~x) => (-((~e * ~x) ^ (~m + 1)) * (~a + ~b * (~x) ^ ~n) ^ (~p + 1) * (~c + ~d * (~x) ^ ~n) ^ ~q) / (~a * ~e * ~n * (~p + 1)) + (1 / (~a * ~n * (~p + 1))) * Antiderivative((~e * ~x) ^ ~m * (~a + ~b * (~x) ^ ~n) ^ (~p + 1) * (~c + ~d * (~x) ^ ~n) ^ (~q - 1) * Simp(~c * (~m + ~n * (~p + 1) + 1) + ~d * (~m + ~n * (~p + ~q + 1) + 1) * (~x) ^ ~n, ~x), ~x) <-- FreeQ([~a, ~b, ~c, ~d, ~e, ~m], ~x) && (NeQ(~b * ~c - ~a * ~d, 0) && (IGtQ(~n, 0) && (LtQ(~p, -1) && (LtQ(0, ~q, 1) && IntBinomialQ(~a, ~b, ~c, ~d, ~e, ~m, ~n, ~p, ~q, ~x)))))
    @apply_utils Antiderivative((~(e') * ~x) ^ ~(m') * (~a + ~(b') * (~x) ^ ~n) ^ ~p * (~c + ~(d') * (~x) ^ ~n) ^ ~q, ~x) => (-(~a) * (~e) ^ (2 * ~n - 1) * (~e * ~x) ^ ((~m - 2 * ~n) + 1) * (~a + ~b * (~x) ^ ~n) ^ (~p + 1) * (~c + ~d * (~x) ^ ~n) ^ (~q + 1)) / (~b * ~n * (~b * ~c - ~a * ~d) * (~p + 1)) + ((~e) ^ (2 * ~n) / (~b * ~n * (~b * ~c - ~a * ~d) * (~p + 1))) * Antiderivative((~e * ~x) ^ (~m - 2 * ~n) * (~a + ~b * (~x) ^ ~n) ^ (~p + 1) * (~c + ~d * (~x) ^ ~n) ^ ~q * Simp(~a * ~c * ((~m - 2 * ~n) + 1) + (~a * ~d * ((~m - ~n) + ~n * ~q + 1) + ~b * ~c * ~n * (~p + 1)) * (~x) ^ ~n, ~x), ~x) <-- FreeQ([~a, ~b, ~c, ~d, ~e, ~q], ~x) && (NeQ(~b * ~c - ~a * ~d, 0) && (IGtQ(~n, 0) && (LtQ(~p, -1) && (GtQ((~m - ~n) + 1, ~n) && IntBinomialQ(~a, ~b, ~c, ~d, ~e, ~m, ~n, ~p, ~q, ~x)))))
    @apply_utils Antiderivative((~(e') * ~x) ^ ~(m') * (~a + ~(b') * (~x) ^ ~n) ^ ~p * (~c + ~(d') * (~x) ^ ~n) ^ ~q, ~x) => ((~e) ^ (~n - 1) * (~e * ~x) ^ ((~m - ~n) + 1) * (~a + ~b * (~x) ^ ~n) ^ (~p + 1) * (~c + ~d * (~x) ^ ~n) ^ (~q + 1)) / (~n * (~b * ~c - ~a * ~d) * (~p + 1)) - ((~e) ^ ~n / (~n * (~b * ~c - ~a * ~d) * (~p + 1))) * Antiderivative((~e * ~x) ^ (~m - ~n) * (~a + ~b * (~x) ^ ~n) ^ (~p + 1) * (~c + ~d * (~x) ^ ~n) ^ ~q * Simp(~c * ((~m - ~n) + 1) + ~d * (~m + ~n * (~p + ~q + 1) + 1) * (~x) ^ ~n, ~x), ~x) <-- FreeQ([~a, ~b, ~c, ~d, ~e, ~q], ~x) && (NeQ(~b * ~c - ~a * ~d, 0) && (IGtQ(~n, 0) && (LtQ(~p, -1) && (GeQ(~n, (~m - ~n) + 1) && (GtQ((~m - ~n) + 1, 0) && IntBinomialQ(~a, ~b, ~c, ~d, ~e, ~m, ~n, ~p, ~q, ~x))))))
    @apply_utils Antiderivative((~(e') * ~x) ^ ~(m') * (~a + ~(b') * (~x) ^ ~n) ^ ~p * (~c + ~(d') * (~x) ^ ~n) ^ ~q, ~x) => (-(~b) * (~e * ~x) ^ (~m + 1) * (~a + ~b * (~x) ^ ~n) ^ (~p + 1) * (~c + ~d * (~x) ^ ~n) ^ (~q + 1)) / (~a * ~e * ~n * (~b * ~c - ~a * ~d) * (~p + 1)) + (1 / (~a * ~n * (~b * ~c - ~a * ~d) * (~p + 1))) * Antiderivative((~e * ~x) ^ ~m * (~a + ~b * (~x) ^ ~n) ^ (~p + 1) * (~c + ~d * (~x) ^ ~n) ^ ~q * Simp(~c * ~b * (~m + 1) + ~n * (~b * ~c - ~a * ~d) * (~p + 1) + ~d * ~b * (~m + ~n * (~p + ~q + 2) + 1) * (~x) ^ ~n, ~x), ~x) <-- FreeQ([~a, ~b, ~c, ~d, ~e, ~m, ~q], ~x) && (NeQ(~b * ~c - ~a * ~d, 0) && (IGtQ(~n, 0) && (LtQ(~p, -1) && IntBinomialQ(~a, ~b, ~c, ~d, ~e, ~m, ~n, ~p, ~q, ~x))))
    @apply_utils Antiderivative((~(e') * ~x) ^ ~m * (~a + ~(b') * (~x) ^ ~n) ^ ~p * (~c + ~(d') * (~x) ^ ~n) ^ ~q, ~x) => ((~e * ~x) ^ (~m + 1) * (~a + ~b * (~x) ^ ~n) ^ ~p * (~c + ~d * (~x) ^ ~n) ^ ~q) / (~e * (~m + 1)) - (~n / ((~e) ^ ~n * (~m + 1))) * Antiderivative((~e * ~x) ^ (~m + ~n) * (~a + ~b * (~x) ^ ~n) ^ (~p - 1) * (~c + ~d * (~x) ^ ~n) ^ (~q - 1) * Simp(~b * ~c * ~p + ~a * ~d * ~q + ~b * ~d * (~p + ~q) * (~x) ^ ~n, ~x), ~x) <-- FreeQ([~a, ~b, ~c, ~d, ~e], ~x) && (NeQ(~b * ~c - ~a * ~d, 0) && (IGtQ(~n, 0) && (GtQ(~q, 0) && (LtQ(~m, -1) && (GtQ(~p, 0) && IntBinomialQ(~a, ~b, ~c, ~d, ~e, ~m, ~n, ~p, ~q, ~x))))))
    @apply_utils Antiderivative((~(e') * ~x) ^ ~m * (~a + ~(b') * (~x) ^ ~n) ^ ~p * (~c + ~(d') * (~x) ^ ~n) ^ ~q, ~x) => (~c * (~e * ~x) ^ (~m + 1) * (~a + ~b * (~x) ^ ~n) ^ (~p + 1) * (~c + ~d * (~x) ^ ~n) ^ (~q - 1)) / (~a * ~e * (~m + 1)) - (1 / (~a * (~e) ^ ~n * (~m + 1))) * Antiderivative((~e * ~x) ^ (~m + ~n) * (~a + ~b * (~x) ^ ~n) ^ ~p * (~c + ~d * (~x) ^ ~n) ^ (~q - 2) * Simp(~c * (~c * ~b - ~a * ~d) * (~m + 1) + ~c * ~n * (~b * ~c * (~p + 1) + ~a * ~d * (~q - 1)) + ~d * ((~c * ~b - ~a * ~d) * (~m + 1) + ~c * ~b * ~n * (~p + ~q)) * (~x) ^ ~n, ~x), ~x) <-- FreeQ([~a, ~b, ~c, ~d, ~e, ~p], ~x) && (NeQ(~b * ~c - ~a * ~d, 0) && (IGtQ(~n, 0) && (GtQ(~q, 1) && (LtQ(~m, -1) && IntBinomialQ(~a, ~b, ~c, ~d, ~e, ~m, ~n, ~p, ~q, ~x)))))
    @apply_utils Antiderivative((~(e') * ~x) ^ ~m * (~a + ~(b') * (~x) ^ ~n) ^ ~p * (~c + ~(d') * (~x) ^ ~n) ^ ~q, ~x) => ((~e * ~x) ^ (~m + 1) * (~a + ~b * (~x) ^ ~n) ^ (~p + 1) * (~c + ~d * (~x) ^ ~n) ^ ~q) / (~a * ~e * (~m + 1)) - (1 / (~a * (~e) ^ ~n * (~m + 1))) * Antiderivative((~e * ~x) ^ (~m + ~n) * (~a + ~b * (~x) ^ ~n) ^ ~p * (~c + ~d * (~x) ^ ~n) ^ (~q - 1) * Simp(~c * ~b * (~m + 1) + ~n * (~b * ~c * (~p + 1) + ~a * ~d * ~q) + ~d * (~b * (~m + 1) + ~b * ~n * (~p + ~q + 1)) * (~x) ^ ~n, ~x), ~x) <-- FreeQ([~a, ~b, ~c, ~d, ~e, ~p], ~x) && (NeQ(~b * ~c - ~a * ~d, 0) && (IGtQ(~n, 0) && (LtQ(0, ~q, 1) && (LtQ(~m, -1) && IntBinomialQ(~a, ~b, ~c, ~d, ~e, ~m, ~n, ~p, ~q, ~x)))))
    @apply_utils Antiderivative((~(e') * ~x) ^ ~(m') * (~a + ~(b') * (~x) ^ ~n) ^ ~p * (~c + ~(d') * (~x) ^ ~n) ^ ~q, ~x) => ((~e * ~x) ^ (~m + 1) * (~a + ~b * (~x) ^ ~n) ^ ~p * (~c + ~d * (~x) ^ ~n) ^ ~q) / (~e * (~m + ~n * (~p + ~q) + 1)) + (~n / (~m + ~n * (~p + ~q) + 1)) * Antiderivative((~e * ~x) ^ ~m * (~a + ~b * (~x) ^ ~n) ^ (~p - 1) * (~c + ~d * (~x) ^ ~n) ^ (~q - 1) * Simp(~a * ~c * (~p + ~q) + (~q * (~b * ~c - ~a * ~d) + ~a * ~d * (~p + ~q)) * (~x) ^ ~n, ~x), ~x) <-- FreeQ([~a, ~b, ~c, ~d, ~e, ~m], ~x) && (NeQ(~b * ~c - ~a * ~d, 0) && (IGtQ(~n, 0) && (GtQ(~q, 0) && (GtQ(~p, 0) && IntBinomialQ(~a, ~b, ~c, ~d, ~e, ~m, ~n, ~p, ~q, ~x)))))
    @apply_utils Antiderivative((~(e') * ~x) ^ ~(m') * (~a + ~(b') * (~x) ^ ~n) ^ ~p * (~c + ~(d') * (~x) ^ ~n) ^ ~q, ~x) => (~d * (~e * ~x) ^ (~m + 1) * (~a + ~b * (~x) ^ ~n) ^ (~p + 1) * (~c + ~d * (~x) ^ ~n) ^ (~q - 1)) / (~b * ~e * (~m + ~n * (~p + ~q) + 1)) + (1 / (~b * (~m + ~n * (~p + ~q) + 1))) * Antiderivative((~e * ~x) ^ ~m * (~a + ~b * (~x) ^ ~n) ^ ~p * (~c + ~d * (~x) ^ ~n) ^ (~q - 2) * Simp(~c * ((~c * ~b - ~a * ~d) * (~m + 1) + ~c * ~b * ~n * (~p + ~q)) + (~d * (~c * ~b - ~a * ~d) * (~m + 1) + ~d * ~n * (~q - 1) * (~b * ~c - ~a * ~d) + ~c * ~b * ~d * ~n * (~p + ~q)) * (~x) ^ ~n, ~x), ~x) <-- FreeQ([~a, ~b, ~c, ~d, ~e, ~m, ~p], ~x) && (NeQ(~b * ~c - ~a * ~d, 0) && (IGtQ(~n, 0) && (GtQ(~q, 1) && IntBinomialQ(~a, ~b, ~c, ~d, ~e, ~m, ~n, ~p, ~q, ~x))))
    @apply_utils Antiderivative((~(e') * ~x) ^ ~(m') * (~a + ~(b') * (~x) ^ ~n) ^ ~p * (~c + ~(d') * (~x) ^ ~n) ^ ~q, ~x) => ((~e) ^ (~n - 1) * (~e * ~x) ^ ((~m - ~n) + 1) * (~a + ~b * (~x) ^ ~n) ^ (~p + 1) * (~c + ~d * (~x) ^ ~n) ^ ~q) / (~b * (~m + ~n * (~p + ~q) + 1)) - ((~e) ^ ~n / (~b * (~m + ~n * (~p + ~q) + 1))) * Antiderivative((~e * ~x) ^ (~m - ~n) * (~a + ~b * (~x) ^ ~n) ^ ~p * (~c + ~d * (~x) ^ ~n) ^ (~q - 1) * Simp(~a * ~c * ((~m - ~n) + 1) + (~a * ~d * ((~m - ~n) + 1) - ~n * ~q * (~b * ~c - ~a * ~d)) * (~x) ^ ~n, ~x), ~x) <-- FreeQ([~a, ~b, ~c, ~d, ~e, ~p], ~x) && (NeQ(~b * ~c - ~a * ~d, 0) && (IGtQ(~n, 0) && (GtQ(~q, 0) && (GtQ((~m - ~n) + 1, 0) && IntBinomialQ(~a, ~b, ~c, ~d, ~e, ~m, ~n, ~p, ~q, ~x)))))
    @apply_utils Antiderivative((~(e') * ~x) ^ ~(m') * (~a + ~(b') * (~x) ^ ~n) ^ ~p * (~c + ~(d') * (~x) ^ ~n) ^ ~q, ~x) => ((~e) ^ (2 * ~n - 1) * (~e * ~x) ^ ((~m - 2 * ~n) + 1) * (~a + ~b * (~x) ^ ~n) ^ (~p + 1) * (~c + ~d * (~x) ^ ~n) ^ (~q + 1)) / (~b * ~d * (~m + ~n * (~p + ~q) + 1)) - ((~e) ^ (2 * ~n) / (~b * ~d * (~m + ~n * (~p + ~q) + 1))) * Antiderivative((~e * ~x) ^ (~m - 2 * ~n) * (~a + ~b * (~x) ^ ~n) ^ ~p * (~c + ~d * (~x) ^ ~n) ^ ~q * Simp(~a * ~c * ((~m - 2 * ~n) + 1) + (~a * ~d * (~m + ~n * (~q - 1) + 1) + ~b * ~c * (~m + ~n * (~p - 1) + 1)) * (~x) ^ ~n, ~x), ~x) <-- FreeQ([~a, ~b, ~c, ~d, ~e, ~p, ~q], ~x) && (NeQ(~b * ~c - ~a * ~d, 0) && (IGtQ(~n, 0) && (GtQ((~m - ~n) + 1, ~n) && IntBinomialQ(~a, ~b, ~c, ~d, ~e, ~m, ~n, ~p, ~q, ~x))))
    @apply_utils Antiderivative((~(e') * ~x) ^ ~m * (~a + ~(b') * (~x) ^ ~n) ^ ~p * (~c + ~(d') * (~x) ^ ~n) ^ ~q, ~x) => ((~e * ~x) ^ (~m + 1) * (~a + ~b * (~x) ^ ~n) ^ (~p + 1) * (~c + ~d * (~x) ^ ~n) ^ (~q + 1)) / (~a * ~c * ~e * (~m + 1)) - (1 / (~a * ~c * (~e) ^ ~n * (~m + 1))) * Antiderivative((~e * ~x) ^ (~m + ~n) * (~a + ~b * (~x) ^ ~n) ^ ~p * (~c + ~d * (~x) ^ ~n) ^ ~q * Simp((~b * ~c + ~a * ~d) * (~m + ~n + 1) + ~n * (~b * ~c * ~p + ~a * ~d * ~q) + ~b * ~d * (~m + ~n * (~p + ~q + 2) + 1) * (~x) ^ ~n, ~x), ~x) <-- FreeQ([~a, ~b, ~c, ~d, ~e, ~p, ~q], ~x) && (NeQ(~b * ~c - ~a * ~d, 0) && (IGtQ(~n, 0) && (LtQ(~m, -1) && IntBinomialQ(~a, ~b, ~c, ~d, ~e, ~m, ~n, ~p, ~q, ~x))))
    @apply_utils Antiderivative((~(e') * ~x) ^ ~(m') / ((~a + ~(b') * (~x) ^ ~n) * (~c + ~(d') * (~x) ^ ~n)), ~x) => ((-(~a) * (~e) ^ ~n) / (~b * ~c - ~a * ~d)) * Antiderivative((~e * ~x) ^ (~m - ~n) / (~a + ~b * (~x) ^ ~n), ~x) + ((~c * (~e) ^ ~n) / (~b * ~c - ~a * ~d)) * Antiderivative((~e * ~x) ^ (~m - ~n) / (~c + ~d * (~x) ^ ~n), ~x) <-- FreeQ([~a, ~b, ~c, ~d, ~e, ~m], ~x) && (NeQ(~b * ~c - ~a * ~d, 0) && (IGtQ(~n, 0) && LeQ(~n, ~m, 2 * ~n - 1)))
    @apply_utils Antiderivative((~(e') * ~x) ^ ~(m') / ((~a + ~(b') * (~x) ^ ~n) * (~c + ~(d') * (~x) ^ ~n)), ~x) => (~b / (~b * ~c - ~a * ~d)) * Antiderivative((~e * ~x) ^ ~m / (~a + ~b * (~x) ^ ~n), ~x) - (~d / (~b * ~c - ~a * ~d)) * Antiderivative((~e * ~x) ^ ~m / (~c + ~d * (~x) ^ ~n), ~x) <-- FreeQ([~a, ~b, ~c, ~d, ~e, ~m], ~x) && (NeQ(~b * ~c - ~a * ~d, 0) && IGtQ(~n, 0))
    @apply_utils Antiderivative(((~(e') * ~x) ^ ~m * (~c + ~(d') * (~x) ^ ~n) ^ ~(q')) / (~a + ~(b') * (~x) ^ ~n), ~x) => ((~e) ^ ~n / ~b) * Antiderivative((~e * ~x) ^ (~m - ~n) * (~c + ~d * (~x) ^ ~n) ^ ~q, ~x) - ((~a * (~e) ^ ~n) / ~b) * Antiderivative(((~e * ~x) ^ (~m - ~n) * (~c + ~d * (~x) ^ ~n) ^ ~q) / (~a + ~b * (~x) ^ ~n), ~x) <-- FreeQ([~a, ~b, ~c, ~d, ~e, ~m, ~q], ~x) && (NeQ(~b * ~c - ~a * ~d, 0) && (IGtQ(~n, 0) && (LeQ(~n, ~m, 2 * ~n - 1) && IntBinomialQ(~a, ~b, ~c, ~d, ~e, ~m, ~n, -1, ~q, ~x))))
    @apply_utils Antiderivative((~x * (~a + ~(b') * (~x) ^ ~n) ^ ~p) / (~c + ~(d') * (~x) ^ ~n), ~x) => (~b / ~d) * Antiderivative(~x * (~a + ~b * (~x) ^ ~n) ^ (~p - 1), ~x) - ((~b * ~c - ~a * ~d) / ~d) * Antiderivative((~x * (~a + ~b * (~x) ^ ~n) ^ (~p - 1)) / (~c + ~d * (~x) ^ ~n), ~x) <-- FreeQ([~a, ~b, ~c, ~d], ~x) && (NeQ(~b * ~c - ~a * ~d, 0) && (IGtQ(~n, 0) && (GtQ(~p, 0) && IntBinomialQ(~a, ~b, ~c, ~d, 1, 1, ~n, ~p, -1, ~x))))
    @apply_utils Antiderivative((~x * (~a + ~(b') * (~x) ^ ~n) ^ ~p) / (~c + ~(d') * (~x) ^ ~n), ~x) => (~b / (~b * ~c - ~a * ~d)) * Antiderivative(~x * (~a + ~b * (~x) ^ ~n) ^ (~p - 1), ~x) - (~d / (~b * ~c - ~a * ~d)) * Antiderivative((~x * (~a + ~b * (~x) ^ ~n) ^ (~p + 1)) / (~c + ~d * (~x) ^ ~n), ~x) <-- FreeQ([~a, ~b, ~c, ~d], ~x) && (NeQ(~b * ~c - ~a * ~d, 0) && (IGtQ(~n, 0) && (LtQ(~p, -1) && IntBinomialQ(~a, ~b, ~c, ~d, 1, 1, ~n, ~p, -1, ~x))))
    @apply_utils Antiderivative(~x / ((~a + ~(b') * (~x) ^ 3) * sqrt(~c + ~(d') * (~x) ^ 3)), ~x) => With([q = Rt(~d / ~c, 3)], (((q * atanh(sqrt(~c + ~d * (~x) ^ 3) / Rt(~c, 2))) / (9 * 2 ^ (2 / 3) * ~b * Rt(~c, 2)) + (q * atan(sqrt(~c + ~d * (~x) ^ 3) / (sqrt(3) * Rt(~c, 2)))) / (3 * 2 ^ (2 / 3) * sqrt(3) * ~b * Rt(~c, 2))) - (q * atan((sqrt(3) * Rt(~c, 2) * (1 + 2 ^ (1 / 3) * q * ~x)) / sqrt(~c + ~d * (~x) ^ 3))) / (3 * 2 ^ (2 / 3) * sqrt(3) * ~b * Rt(~c, 2))) - (q * atanh((Rt(~c, 2) * (1 - 2 ^ (1 / 3) * q * ~x)) / sqrt(~c + ~d * (~x) ^ 3))) / (3 * 2 ^ (2 / 3) * ~b * Rt(~c, 2))) <-- FreeQ([~a, ~b, ~c, ~d], ~x) && (NeQ(~b * ~c - ~a * ~d, 0) && (EqQ(4 * ~b * ~c - ~a * ~d, 0) && PosQ(~c)))
    @apply_utils Antiderivative(~x / ((~a + ~(b') * (~x) ^ 3) * sqrt(~c + ~(d') * (~x) ^ 3)), ~x) => With([q = Rt(~d / ~c, 3)], (((-q * atan(sqrt(~c + ~d * (~x) ^ 3) / Rt(-(~c), 2))) / (9 * 2 ^ (2 / 3) * ~b * Rt(-(~c), 2)) - (q * atanh(sqrt(~c + ~d * (~x) ^ 3) / (sqrt(3) * Rt(-(~c), 2)))) / (3 * 2 ^ (2 / 3) * sqrt(3) * ~b * Rt(-(~c), 2))) - (q * atanh((sqrt(3) * Rt(-(~c), 2) * (1 + 2 ^ (1 / 3) * q * ~x)) / sqrt(~c + ~d * (~x) ^ 3))) / (3 * 2 ^ (2 / 3) * sqrt(3) * ~b * Rt(-(~c), 2))) - (q * atan((Rt(-(~c), 2) * (1 - 2 ^ (1 / 3) * q * ~x)) / sqrt(~c + ~d * (~x) ^ 3))) / (3 * 2 ^ (2 / 3) * ~b * Rt(-(~c), 2))) <-- FreeQ([~a, ~b, ~c, ~d], ~x) && (NeQ(~b * ~c - ~a * ~d, 0) && (EqQ(4 * ~b * ~c - ~a * ~d, 0) && NegQ(~c)))
    @apply_utils Antiderivative(~x / ((~a + ~(b') * (~x) ^ 3) * sqrt(~c + ~(d') * (~x) ^ 3)), ~x) => With([q = Rt(~d / ~c, 3)], (((~d * q) / (4 * ~b)) * Antiderivative((~x) ^ 2 / ((8 * ~c - ~d * (~x) ^ 3) * sqrt(~c + ~d * (~x) ^ 3)), ~x) - (q ^ 2 / (12 * ~b)) * Antiderivative((1 + q * ~x) / ((2 - q * ~x) * sqrt(~c + ~d * (~x) ^ 3)), ~x)) + (1 / (12 * ~b * ~c)) * Antiderivative(((2 * ~c * q ^ 2 - 2 * ~d * ~x) - ~d * q * (~x) ^ 2) / ((4 + 2 * q * ~x + q ^ 2 * (~x) ^ 2) * sqrt(~c + ~d * (~x) ^ 3)), ~x)) <-- FreeQ([~a, ~b, ~c, ~d], ~x) && (NeQ(~b * ~c - ~a * ~d, 0) && EqQ(8 * ~b * ~c + ~a * ~d, 0))
    @apply_utils Antiderivative(~x / ((~c + ~(d') * (~x) ^ 3) * sqrt(~a + ~(b') * (~x) ^ 3)), ~x) => With([q = Rt(~b / ~a, 3), r = Simplify((~b * ~c - 10 * ~a * ~d) / (6 * ~a * ~d))], (((-q * (2 - r) * atan(((1 - r) * sqrt(~a + ~b * (~x) ^ 3)) / (sqrt(2) * Rt(~a, 2) * r ^ (3 / 2)))) / (3 * sqrt(2) * Rt(~a, 2) * ~d * r ^ (3 / 2)) - (q * (2 - r) * atan((Rt(~a, 2) * sqrt(r) * (1 + r) * (1 + q * ~x)) / (sqrt(2) * sqrt(~a + ~b * (~x) ^ 3)))) / (2 * sqrt(2) * Rt(~a, 2) * ~d * r ^ (3 / 2))) - (q * (2 - r) * atanh((Rt(~a, 2) * (1 - r) * sqrt(r) * (1 + q * ~x)) / (sqrt(2) * sqrt(~a + ~b * (~x) ^ 3)))) / (6 * sqrt(2) * Rt(~a, 2) * ~d * sqrt(r))) - (q * (2 - r) * atanh((Rt(~a, 2) * sqrt(r) * ((1 + r) - 2 * q * ~x)) / (sqrt(2) * sqrt(~a + ~b * (~x) ^ 3)))) / (3 * sqrt(2) * Rt(~a, 2) * ~d * sqrt(r))) <-- FreeQ([~a, ~b, ~c, ~d], ~x) && (NeQ(~b * ~c - ~a * ~d, 0) && (EqQ(((~b) ^ 2 * (~c) ^ 2 - 20 * ~a * ~b * ~c * ~d) - 8 * (~a) ^ 2 * (~d) ^ 2, 0) && PosQ(~a)))
    @apply_utils Antiderivative(~x / ((~c + ~(d') * (~x) ^ 3) * sqrt(~a + ~(b') * (~x) ^ 3)), ~x) => With([q = Rt(~b / ~a, 3), r = Simplify((~b * ~c - 10 * ~a * ~d) / (6 * ~a * ~d))], (((q * (2 - r) * atanh(((1 - r) * sqrt(~a + ~b * (~x) ^ 3)) / (sqrt(2) * Rt(-(~a), 2) * r ^ (3 / 2)))) / (3 * sqrt(2) * Rt(-(~a), 2) * ~d * r ^ (3 / 2)) - (q * (2 - r) * atanh((Rt(-(~a), 2) * sqrt(r) * (1 + r) * (1 + q * ~x)) / (sqrt(2) * sqrt(~a + ~b * (~x) ^ 3)))) / (2 * sqrt(2) * Rt(-(~a), 2) * ~d * r ^ (3 / 2))) - (q * (2 - r) * atan((Rt(-(~a), 2) * (1 - r) * sqrt(r) * (1 + q * ~x)) / (sqrt(2) * sqrt(~a + ~b * (~x) ^ 3)))) / (6 * sqrt(2) * Rt(-(~a), 2) * ~d * sqrt(r))) - (q * (2 - r) * atan((Rt(-(~a), 2) * sqrt(r) * ((1 + r) - 2 * q * ~x)) / (sqrt(2) * sqrt(~a + ~b * (~x) ^ 3)))) / (3 * sqrt(2) * Rt(-(~a), 2) * ~d * sqrt(r))) <-- FreeQ([~a, ~b, ~c, ~d], ~x) && (NeQ(~b * ~c - ~a * ~d, 0) && (EqQ(((~b) ^ 2 * (~c) ^ 2 - 20 * ~a * ~b * ~c * ~d) - 8 * (~a) ^ 2 * (~d) ^ 2, 0) && NegQ(~a)))
    @apply_utils Antiderivative(~x / ((~a + ~(b') * (~x) ^ 3) ^ (1 / 3) * (~c + ~(d') * (~x) ^ 3)), ~x) => With([q = Rt(~b / ~a, 3)], (-(q ^ 2) / (3 * ~d)) * Antiderivative(1 / ((1 - q * ~x) * (~a + ~b * (~x) ^ 3) ^ (1 / 3)), ~x) + (q / ~d) * Subst(Antiderivative(1 / (1 + 2 * ~a * (~x) ^ 3), ~x), ~x, (1 + q * ~x) / (~a + ~b * (~x) ^ 3) ^ (1 / 3))) <-- FreeQ([~a, ~b, ~c, ~d], ~x) && (NeQ(~b * ~c - ~a * ~d, 0) && EqQ(~b * ~c + ~a * ~d, 0))
    @apply_utils Antiderivative(~x / ((~a + ~(b') * (~x) ^ 3) ^ (2 / 3) * (~c + ~(d') * (~x) ^ 3)), ~x) => With([q = Rt((~b * ~c - ~a * ~d) / ~c, 3)], (-(atan((1 + (2 * q * ~x) / (~a + ~b * (~x) ^ 3) ^ (1 / 3)) / sqrt(3))) / (sqrt(3) * ~c * q ^ 2) + log(~c + ~d * (~x) ^ 3) / (6 * ~c * q ^ 2)) - log(q * ~x - (~a + ~b * (~x) ^ 3) ^ (1 / 3)) / (2 * ~c * q ^ 2)) <-- FreeQ([~a, ~b, ~c, ~d], ~x) && NeQ(~b * ~c - ~a * ~d, 0)
    @apply_utils Antiderivative((~x) ^ 2 / ((~a + ~(b') * (~x) ^ 4) * sqrt(~c + ~(d') * (~x) ^ 4)), ~x) => With([r = Numerator(Rt(-(~a) / ~b, 2)), s = Denominator(Rt(-(~a) / ~b, 2))], (s / (2 * ~b)) * Antiderivative(1 / ((r + s * (~x) ^ 2) * sqrt(~c + ~d * (~x) ^ 4)), ~x) - (s / (2 * ~b)) * Antiderivative(1 / ((r - s * (~x) ^ 2) * sqrt(~c + ~d * (~x) ^ 4)), ~x)) <-- FreeQ([~a, ~b, ~c, ~d], ~x) && NeQ(~b * ~c - ~a * ~d, 0)
    @apply_utils Antiderivative(((~x) ^ 2 * sqrt(~c + ~(d') * (~x) ^ 4)) / (~a + ~(b') * (~x) ^ 4), ~x) => (~d / ~b) * Antiderivative((~x) ^ 2 / sqrt(~c + ~d * (~x) ^ 4), ~x) + ((~b * ~c - ~a * ~d) / ~b) * Antiderivative((~x) ^ 2 / ((~a + ~b * (~x) ^ 4) * sqrt(~c + ~d * (~x) ^ 4)), ~x) <-- FreeQ([~a, ~b, ~c, ~d], ~x) && NeQ(~b * ~c - ~a * ~d, 0)
    @apply_utils Antiderivative((~x) ^ 2 / (sqrt(~a + ~(b') * (~x) ^ 2) * sqrt(~c + ~(d') * (~x) ^ 2)), ~x) => (~x * sqrt(~a + ~b * (~x) ^ 2)) / (~b * sqrt(~c + ~d * (~x) ^ 2)) - (~c / ~b) * Antiderivative(sqrt(~a + ~b * (~x) ^ 2) / (~c + ~d * (~x) ^ 2) ^ (3 / 2), ~x) <-- FreeQ([~a, ~b, ~c, ~d], ~x) && (NeQ(~b * ~c - ~a * ~d, 0) && (PosQ(~b / ~a) && (PosQ(~d / ~c) && Not(SimplerSqrtQ(~b / ~a, ~d / ~c)))))
    @apply_utils Antiderivative((~x) ^ ~n / (sqrt(~a + ~(b') * (~x) ^ ~n) * sqrt(~c + ~(d') * (~x) ^ ~n)), ~x) => (1 / ~b) * Antiderivative(sqrt(~a + ~b * (~x) ^ ~n) / sqrt(~c + ~d * (~x) ^ ~n), ~x) - (~a / ~b) * Antiderivative(1 / (sqrt(~a + ~b * (~x) ^ ~n) * sqrt(~c + ~d * (~x) ^ ~n)), ~x) <-- FreeQ([~a, ~b, ~c, ~d], ~x) && (NeQ(~b * ~c - ~a * ~d, 0) && ((EqQ(~n, 2) || EqQ(~n, 4)) && Not(EqQ(~n, 2) && SimplerSqrtQ(-(~b) / ~a, -(~d) / ~c))))
    @apply_utils Antiderivative((~x) ^ ~(m') * (~a + ~(b') * (~x) ^ ~n) ^ ~p * (~c + ~(d') * (~x) ^ ~n) ^ ~(q'), ~x) => With([k = Denominator(~p)], ((k * (~a) ^ (~p + (~m + 1) / ~n)) / ~n) * Subst(Antiderivative(((~x) ^ ((k * (~m + 1)) / ~n - 1) * (~c - (~b * ~c - ~a * ~d) * (~x) ^ k) ^ ~q) / (1 - ~b * (~x) ^ k) ^ (~p + ~q + (~m + 1) / ~n + 1), ~x), ~x, (~x) ^ (~n / k) / (~a + ~b * (~x) ^ ~n) ^ (1 / k))) <-- FreeQ([~a, ~b, ~c, ~d], ~x) && (IGtQ(~n, 0) && (RationalQ(~m, ~p) && (IntegersQ(~p + (~m + 1) / ~n, ~q) && LtQ(-1, ~p, 0))))
    @apply_utils Antiderivative((~x) ^ ~(m') * (~a + ~(b') * (~x) ^ ~n) ^ ~p * (~c + ~(d') * (~x) ^ ~n) ^ ~q, ~x) => -(Subst(Antiderivative(((~a + ~b * (~x) ^ -(~n)) ^ ~p * (~c + ~d * (~x) ^ -(~n)) ^ ~q) / (~x) ^ (~m + 2), ~x), ~x, 1 / ~x)) <-- FreeQ([~a, ~b, ~c, ~d, ~p, ~q], ~x) && (NeQ(~b * ~c - ~a * ~d, 0) && (ILtQ(~n, 0) && IntegerQ(~m)))
    @apply_utils Antiderivative((~(e') * ~x) ^ ~m * (~a + ~(b') * (~x) ^ ~n) ^ ~p * (~c + ~(d') * (~x) ^ ~n) ^ ~q, ~x) => With([g = Denominator(~m)], (-g / ~e) * Subst(Antiderivative(((~a + ~b * (~e) ^ -(~n) * (~x) ^ (-g * ~n)) ^ ~p * (~c + ~d * (~e) ^ -(~n) * (~x) ^ (-g * ~n)) ^ ~q) / (~x) ^ (g * (~m + 1) + 1), ~x), ~x, 1 / (~e * ~x) ^ (1 / g))) <-- FreeQ([~a, ~b, ~c, ~d, ~e, ~p, ~q], ~x) && (ILtQ(~n, 0) && FractionQ(~m))
    @apply_utils Antiderivative((~(e') * ~x) ^ ~m * (~a + ~(b') * (~x) ^ ~n) ^ ~p * (~c + ~(d') * (~x) ^ ~n) ^ ~q, ~x) => -((~e * ~x) ^ ~m) * ((~x) ^ -1) ^ ~m * Subst(Antiderivative(((~a + ~b * (~x) ^ -(~n)) ^ ~p * (~c + ~d * (~x) ^ -(~n)) ^ ~q) / (~x) ^ (~m + 2), ~x), ~x, 1 / ~x) <-- FreeQ([~a, ~b, ~c, ~d, ~e, ~m, ~p, ~q], ~x) && (NeQ(~b * ~c - ~a * ~d, 0) && (ILtQ(~n, 0) && Not(RationalQ(~m))))
    @apply_utils Antiderivative((~x) ^ ~(m') * (~a + ~(b') * (~x) ^ ~n) ^ ~p * (~c + ~(d') * (~x) ^ ~n) ^ ~q, ~x) => With([g = Denominator(~n)], g * Subst(Antiderivative((~x) ^ (g * (~m + 1) - 1) * (~a + ~b * (~x) ^ (g * ~n)) ^ ~p * (~c + ~d * (~x) ^ (g * ~n)) ^ ~q, ~x), ~x, (~x) ^ (1 / g))) <-- FreeQ([~a, ~b, ~c, ~d, ~m, ~p, ~q], ~x) && (NeQ(~b * ~c - ~a * ~d, 0) && FractionQ(~n))
    @apply_utils Antiderivative((~e * ~x) ^ ~m * (~a + ~(b') * (~x) ^ ~n) ^ ~p * (~c + ~(d') * (~x) ^ ~n) ^ ~q, ~x) => (((~e) ^ IntPart(~m) * (~e * ~x) ^ FracPart(~m)) / (~x) ^ FracPart(~m)) * Antiderivative((~x) ^ ~m * (~a + ~b * (~x) ^ ~n) ^ ~p * (~c + ~d * (~x) ^ ~n) ^ ~q, ~x) <-- FreeQ([~a, ~b, ~c, ~d, ~e, ~m, ~p, ~q], ~x) && (NeQ(~b * ~c - ~a * ~d, 0) && FractionQ(~n))
    #= Antiderivative((~x)^(~m')*((~a)+(~b')*(~x)^(~n))^(~p)*((~c)+(~d')*(~x)^(~n))^(~q),~x) :=  -1/(m+1)*Subst(Antiderivative((a+b*x^Simplify(-n/(m+1)))^p*(c+d*x^Simplify(-n/(m+ 1)))^q/x^2,x),x,x^(-(m+1))) <-- FreeQ([a,b,c,d,m,n],x) &&  NeQ(b*c-a*d,0) && NeQ(m,-1) && ILtQ(Simplify(n/(m+1)+1),0) && GeQ(p,-1) && LtQ(p,0) && GeQ(q,-1) && LtQ(q,0) && Not(IntegerQ(n)) =#
    @apply_utils Antiderivative((~x) ^ ~(m') * (~a + ~(b') * (~x) ^ ~n) ^ ~p * (~c + ~(d') * (~x) ^ ~n) ^ ~q, ~x) => (1 / (~m + 1)) * Subst(Antiderivative((~a + ~b * (~x) ^ Simplify(~n / (~m + 1))) ^ ~p * (~c + ~d * (~x) ^ Simplify(~n / (~m + 1))) ^ ~q, ~x), ~x, (~x) ^ (~m + 1)) <-- FreeQ([~a, ~b, ~c, ~d, ~m, ~n, ~p, ~q], ~x) && (NeQ(~b * ~c - ~a * ~d, 0) && (IntegerQ(Simplify(~n / (~m + 1))) && Not(IntegerQ(~n))))
    @apply_utils Antiderivative((~e * ~x) ^ ~(m') * (~a + ~(b') * (~x) ^ ~n) ^ ~p * (~c + ~(d') * (~x) ^ ~n) ^ ~q, ~x) => (((~e) ^ IntPart(~m) * (~e * ~x) ^ FracPart(~m)) / (~x) ^ FracPart(~m)) * Antiderivative((~x) ^ ~m * (~a + ~b * (~x) ^ ~n) ^ ~p * (~c + ~d * (~x) ^ ~n) ^ ~q, ~x) <-- FreeQ([~a, ~b, ~c, ~d, ~e, ~m, ~n, ~p, ~q], ~x) && (NeQ(~b * ~c - ~a * ~d, 0) && (IntegerQ(Simplify(~n / (~m + 1))) && Not(IntegerQ(~n))))
    @apply_utils Antiderivative((~(e') * ~x) ^ ~(m') * (~a + ~(b') * (~x) ^ ~n) ^ ~p * (~c + ~(d') * (~x) ^ ~n) ^ ~q, ~x) => (-((~c * ~b - ~a * ~d)) * (~e * ~x) ^ (~m + 1) * (~a + ~b * (~x) ^ ~n) ^ (~p + 1) * (~c + ~d * (~x) ^ ~n) ^ (~q - 1)) / (~a * ~b * ~e * ~n * (~p + 1)) + (1 / (~a * ~b * ~n * (~p + 1))) * Antiderivative((~e * ~x) ^ ~m * (~a + ~b * (~x) ^ ~n) ^ (~p + 1) * (~c + ~d * (~x) ^ ~n) ^ (~q - 2) * Simp(~c * (~c * ~b * ~n * (~p + 1) + (~c * ~b - ~a * ~d) * (~m + 1)) + ~d * (~c * ~b * ~n * (~p + 1) + (~c * ~b - ~a * ~d) * (~m + ~n * (~q - 1) + 1)) * (~x) ^ ~n, ~x), ~x) <-- FreeQ([~a, ~b, ~c, ~d, ~e, ~m, ~n], ~x) && (NeQ(~b * ~c - ~a * ~d, 0) && (LtQ(~p, -1) && (GtQ(~q, 1) && IntBinomialQ(~a, ~b, ~c, ~d, ~e, ~m, ~n, ~p, ~q, ~x))))
    @apply_utils Antiderivative((~(e') * ~x) ^ ~(m') * (~a + ~(b') * (~x) ^ ~n) ^ ~p * (~c + ~(d') * (~x) ^ ~n) ^ ~q, ~x) => (-((~e * ~x) ^ (~m + 1)) * (~a + ~b * (~x) ^ ~n) ^ (~p + 1) * (~c + ~d * (~x) ^ ~n) ^ ~q) / (~a * ~e * ~n * (~p + 1)) + (1 / (~a * ~n * (~p + 1))) * Antiderivative((~e * ~x) ^ ~m * (~a + ~b * (~x) ^ ~n) ^ (~p + 1) * (~c + ~d * (~x) ^ ~n) ^ (~q - 1) * Simp(~c * (~m + ~n * (~p + 1) + 1) + ~d * (~m + ~n * (~p + ~q + 1) + 1) * (~x) ^ ~n, ~x), ~x) <-- FreeQ([~a, ~b, ~c, ~d, ~e, ~m, ~n], ~x) && (NeQ(~b * ~c - ~a * ~d, 0) && (LtQ(~p, -1) && (LtQ(0, ~q, 1) && IntBinomialQ(~a, ~b, ~c, ~d, ~e, ~m, ~n, ~p, ~q, ~x))))
    @apply_utils Antiderivative((~(e') * ~x) ^ ~(m') * (~a + ~(b') * (~x) ^ ~n) ^ ~p * (~c + ~(d') * (~x) ^ ~n) ^ ~q, ~x) => (-(~b) * (~e * ~x) ^ (~m + 1) * (~a + ~b * (~x) ^ ~n) ^ (~p + 1) * (~c + ~d * (~x) ^ ~n) ^ (~q + 1)) / (~a * ~e * ~n * (~b * ~c - ~a * ~d) * (~p + 1)) + (1 / (~a * ~n * (~b * ~c - ~a * ~d) * (~p + 1))) * Antiderivative((~e * ~x) ^ ~m * (~a + ~b * (~x) ^ ~n) ^ (~p + 1) * (~c + ~d * (~x) ^ ~n) ^ ~q * Simp(~c * ~b * (~m + 1) + ~n * (~b * ~c - ~a * ~d) * (~p + 1) + ~d * ~b * (~m + ~n * (~p + ~q + 2) + 1) * (~x) ^ ~n, ~x), ~x) <-- FreeQ([~a, ~b, ~c, ~d, ~e, ~m, ~n, ~q], ~x) && (NeQ(~b * ~c - ~a * ~d, 0) && (LtQ(~p, -1) && IntBinomialQ(~a, ~b, ~c, ~d, ~e, ~m, ~n, ~p, ~q, ~x)))
    @apply_utils Antiderivative((~(e') * ~x) ^ ~(m') * (~a + ~(b') * (~x) ^ ~n) ^ ~p * (~c + ~(d') * (~x) ^ ~n) ^ ~q, ~x) => ((~e * ~x) ^ (~m + 1) * (~a + ~b * (~x) ^ ~n) ^ ~p * (~c + ~d * (~x) ^ ~n) ^ ~q) / (~e * (~m + ~n * (~p + ~q) + 1)) + (~n / (~m + ~n * (~p + ~q) + 1)) * Antiderivative((~e * ~x) ^ ~m * (~a + ~b * (~x) ^ ~n) ^ (~p - 1) * (~c + ~d * (~x) ^ ~n) ^ (~q - 1) * Simp(~a * ~c * (~p + ~q) + (~q * (~b * ~c - ~a * ~d) + ~a * ~d * (~p + ~q)) * (~x) ^ ~n, ~x), ~x) <-- FreeQ([~a, ~b, ~c, ~d, ~e, ~m, ~n], ~x) && (NeQ(~b * ~c - ~a * ~d, 0) && (GtQ(~q, 0) && (GtQ(~p, 0) && IntBinomialQ(~a, ~b, ~c, ~d, ~e, ~m, ~n, ~p, ~q, ~x))))
    @apply_utils Antiderivative((~(e') * ~x) ^ ~(m') * (~a + ~(b') * (~x) ^ ~n) ^ ~p * (~c + ~(d') * (~x) ^ ~n) ^ ~q, ~x) => (~d * (~e * ~x) ^ (~m + 1) * (~a + ~b * (~x) ^ ~n) ^ (~p + 1) * (~c + ~d * (~x) ^ ~n) ^ (~q - 1)) / (~b * ~e * (~m + ~n * (~p + ~q) + 1)) + (1 / (~b * (~m + ~n * (~p + ~q) + 1))) * Antiderivative((~e * ~x) ^ ~m * (~a + ~b * (~x) ^ ~n) ^ ~p * (~c + ~d * (~x) ^ ~n) ^ (~q - 2) * Simp(~c * ((~c * ~b - ~a * ~d) * (~m + 1) + ~c * ~b * ~n * (~p + ~q)) + (~d * (~c * ~b - ~a * ~d) * (~m + 1) + ~d * ~n * (~q - 1) * (~b * ~c - ~a * ~d) + ~c * ~b * ~d * ~n * (~p + ~q)) * (~x) ^ ~n, ~x), ~x) <-- FreeQ([~a, ~b, ~c, ~d, ~e, ~m, ~n, ~p], ~x) && (NeQ(~b * ~c - ~a * ~d, 0) && (GtQ(~q, 1) && IntBinomialQ(~a, ~b, ~c, ~d, ~e, ~m, ~n, ~p, ~q, ~x)))
    @apply_utils Antiderivative((~x) ^ ~m / ((~a + ~(b') * (~x) ^ ~n) * (~c + ~(d') * (~x) ^ ~n)), ~x) => (-(~a) / (~b * ~c - ~a * ~d)) * Antiderivative((~x) ^ (~m - ~n) / (~a + ~b * (~x) ^ ~n), ~x) + (~c / (~b * ~c - ~a * ~d)) * Antiderivative((~x) ^ (~m - ~n) / (~c + ~d * (~x) ^ ~n), ~x) <-- FreeQ([~a, ~b, ~c, ~d, ~m, ~n], ~x) && (NeQ(~b * ~c - ~a * ~d, 0) && (EqQ(~m, ~n) || EqQ(~m, 2 * ~n - 1)))
    @apply_utils Antiderivative((~(e') * ~x) ^ ~(m') / ((~a + ~(b') * (~x) ^ ~n) * (~c + ~(d') * (~x) ^ ~n)), ~x) => (~b / (~b * ~c - ~a * ~d)) * Antiderivative((~e * ~x) ^ ~m / (~a + ~b * (~x) ^ ~n), ~x) - (~d / (~b * ~c - ~a * ~d)) * Antiderivative((~e * ~x) ^ ~m / (~c + ~d * (~x) ^ ~n), ~x) <-- FreeQ([~a, ~b, ~c, ~d, ~e, ~n, ~m], ~x) && NeQ(~b * ~c - ~a * ~d, 0)
    @apply_utils Antiderivative((~(e') * ~x) ^ ~(m') * (~a + ~(b') * (~x) ^ ~n) ^ ~p * (~c + ~(d') * (~x) ^ ~n) ^ ~q, ~x) => Antiderivative(ExpandIntegrand((~e * ~x) ^ ~m * (~a + ~b * (~x) ^ ~n) ^ ~p * (~c + ~d * (~x) ^ ~n) ^ ~q, ~x), ~x) <-- FreeQ([~a, ~b, ~c, ~d, ~e, ~m], ~x) && (NeQ(~b * ~c - ~a * ~d, 0) && (IGtQ(~p, -2) && (IGtQ(~q, -2) || EqQ(~q, -3) && IntegerQ((~m - 1) / 2))))
    @apply_utils Antiderivative((~(e') * ~x) ^ ~(m') * (~a + ~(b') * (~x) ^ ~n) ^ ~p * (~c + ~(d') * (~x) ^ ~n) ^ ~q, ~x) => (((~a) ^ ~p * (~c) ^ ~q * (~e * ~x) ^ (~m + 1)) / (~e * (~m + 1))) * AppellF1((~m + 1) / ~n, -(~p), -(~q), 1 + (~m + 1) / ~n, (-(~b) * (~x) ^ ~n) / ~a, (-(~d) * (~x) ^ ~n) / ~c) <-- FreeQ([~a, ~b, ~c, ~d, ~e, ~m, ~n, ~p, ~q], ~x) && (NeQ(~b * ~c - ~a * ~d, 0) && (NeQ(~m, -1) && (NeQ(~m, ~n - 1) && ((IntegerQ(~p) || GtQ(~a, 0)) && (IntegerQ(~q) || GtQ(~c, 0))))))
    @apply_utils Antiderivative((~(e') * ~x) ^ ~(m') * (~a + ~(b') * (~x) ^ ~n) ^ ~p * (~c + ~(d') * (~x) ^ ~n) ^ ~q, ~x) => (((~a) ^ IntPart(~p) * (~a + ~b * (~x) ^ ~n) ^ FracPart(~p)) / (1 + (~b * (~x) ^ ~n) / ~a) ^ FracPart(~p)) * Antiderivative((~e * ~x) ^ ~m * (1 + (~b * (~x) ^ ~n) / ~a) ^ ~p * (~c + ~d * (~x) ^ ~n) ^ ~q, ~x) <-- FreeQ([~a, ~b, ~c, ~d, ~e, ~m, ~n, ~p, ~q], ~x) && (NeQ(~b * ~c - ~a * ~d, 0) && (NeQ(~m, -1) && (NeQ(~m, ~n - 1) && Not(IntegerQ(~p) || GtQ(~a, 0)))))
    @apply_utils Antiderivative((~x) ^ ~(m') * (~(a') + ~(b') * (~v) ^ ~n) ^ ~(p') * (~(c') + ~(d') * (~v) ^ ~n) ^ ~(q'), ~x) => (1 / Coefficient(~v, ~x, 1) ^ (~m + 1)) * Subst(Antiderivative(SimplifyIntegrand((~x - Coefficient(~v, ~x, 0)) ^ ~m * (~a + ~b * (~x) ^ ~n) ^ ~p * (~c + ~d * (~x) ^ ~n) ^ ~q, ~x), ~x), ~x, ~v) <-- FreeQ([~a, ~b, ~c, ~d, ~n, ~p, ~q], ~x) && (LinearQ(~v, ~x) && (IntegerQ(~m) && NeQ(~v, ~x)))
    @apply_utils Antiderivative((~u) ^ ~(m') * (~(a') + ~(b') * (~v) ^ ~n) ^ ~(p') * (~(c') + ~(d') * (~v) ^ ~n) ^ ~(q'), ~x) => ((~u) ^ ~m / (Coefficient(~v, ~x, 1) * (~v) ^ ~m)) * Subst(Antiderivative((~x) ^ ~m * (~a + ~b * (~x) ^ ~n) ^ ~p * (~c + ~d * (~x) ^ ~n) ^ ~q, ~x), ~x, ~v) <-- FreeQ([~a, ~b, ~c, ~d, ~m, ~n, ~p, ~q], ~x) && LinearPairQ(~u, ~v, ~x)
    @apply_utils Antiderivative((~x) ^ ~(m') * (~a + ~(b') * (~x) ^ ~(n')) ^ ~(p') * (~c + ~(d') * (~x) ^ ~(mn')) ^ ~(q'), ~x) => Antiderivative((~x) ^ (~m - ~n * ~q) * (~a + ~b * (~x) ^ ~n) ^ ~p * (~d + ~c * (~x) ^ ~n) ^ ~q, ~x) <-- FreeQ([~a, ~b, ~c, ~d, ~m, ~n, ~p], ~x) && (EqQ(~mn, -(~n)) && (IntegerQ(~q) && (PosQ(~n) || Not(IntegerQ(~p)))))
    @apply_utils Antiderivative((~x) ^ ~(m') * (~a + ~(b') * (~x) ^ ~(n')) ^ ~(p') * (~c + ~(d') * (~x) ^ ~(mn')) ^ ~q, ~x) => (((~x) ^ (~n * FracPart(~q)) * (~c + ~d * (~x) ^ -(~n)) ^ FracPart(~q)) / (~d + ~c * (~x) ^ ~n) ^ FracPart(~q)) * Antiderivative((~x) ^ (~m - ~n * ~q) * (~a + ~b * (~x) ^ ~n) ^ ~p * (~d + ~c * (~x) ^ ~n) ^ ~q, ~x) <-- FreeQ([~a, ~b, ~c, ~d, ~m, ~n, ~p, ~q], ~x) && (EqQ(~mn, -(~n)) && (Not(IntegerQ(~q)) && Not(IntegerQ(~p))))
    @apply_utils Antiderivative((~e * ~x) ^ ~m * (~(a') + ~(b') * (~x) ^ ~(n')) ^ ~(p') * (~c + ~(d') * (~x) ^ ~(mn')) ^ ~(q'), ~x) => (((~e) ^ IntPart(~m) * (~e * ~x) ^ FracPart(~m)) / (~x) ^ FracPart(~m)) * Antiderivative((~x) ^ ~m * (~a + ~b * (~x) ^ ~n) ^ ~p * (~c + ~d * (~x) ^ -(~n)) ^ ~q, ~x) <-- FreeQ([~a, ~b, ~c, ~d, ~e, ~m, ~n, ~p, ~q], ~x) && EqQ(~mn, -(~n))
    #= IntBinomialQ(a,b,c,d,e,m,n,p,q,x)*returns*True*iff  (e*x)^m*(a+b*x^n)^p*(c+d*x^n)^q*is*integrable*wrt*x*in*terms*of  non-Appell*functions. =#IntBinomialQ((~a), (~b), (~c), (~d), (~e), (~m), (~n), (~p), (~q), ~x) := IntegersQ(p, q) || IGtQ(p, 0) || IGtQ(q, 0) || EqQ(n, 2) && (IntegersQ(m, 2*p, 2*q) || IntegersQ(2*m, p, 2*q) || IntegersQ(2*m, 2*p, q)) || EqQ(n, 4) && (IntegersQ(m, p, 2*q) || IntegersQ(m, 2*p, q)) || EqQ(n, 2) && IntegersQ(m/2, p + 1/3, q) && (EqQ(b*c + 3*a*d, 0) || EqQ(b*c - 9*a*d, 0)) || EqQ(n, 2) && IntegersQ(m/2, q + 1/3, p) && (EqQ(a*d + 3*b*c, 0) || EqQ(a*d - 9*b*c, 0)) || EqQ(n, 3) && IntegersQ((m - 1)/3, q, p - 1/2) && (EqQ(b*c - 4*a*d, 0) || EqQ(b*c + 8*a*d, 0) || EqQ(b^2*c^2 - 20*a*b*c*d - 8*a^2*d^2, 0)) || EqQ(n, 3) && IntegersQ((m - 1)/3, p, q - 1/2) && (EqQ(4*b*c - a*d, 0) || EqQ(8*b*c + a*d, 0) || EqQ(8*b^2*c^2 + 20*a*b*c*d - a^2*d^2, 0)) || EqQ(n, 3) && (IntegersQ(m, q, 3*p) || IntegersQ(m, p, 3*q)) && EqQ(b*c + a*d, 0) || EqQ(n, 3) && (IntegersQ((m + 2)/3, p + 2/3, q) || IntegersQ((m + 2)/3, q + 2/3, p)) || EqQ(n, 3) && (IntegersQ(m/3, p + 1/3, q) || IntegersQ(m/3, q + 1/3, p))
    @apply_utils Antiderivative(~(u') * (~a1 + ~(b1') * (~x) ^ ~(non2')) ^ ~(p') * (~a2 + ~(b2') * (~x) ^ ~(non2')) ^ ~(p') * (~c + ~(d') * (~x) ^ ~(n')) ^ ~(q'), ~x) => Antiderivative(~u * (~a1 * ~a2 + ~b1 * ~b2 * (~x) ^ ~n) ^ ~p * (~c + ~d * (~x) ^ ~n) ^ ~q, ~x) <-- FreeQ([~a1, ~b1, ~a2, ~b2, ~c, ~d, ~n, ~p, ~q], ~x) && (EqQ(~non2, ~n / 2) && (EqQ(~a2 * ~b1 + ~a1 * ~b2, 0) && (IntegerQ(~p) || GtQ(~a1, 0) && GtQ(~a2, 0))))
    @apply_utils Antiderivative(~(u') * (~a1 + ~(b1') * (~x) ^ ~(non2')) ^ ~(p') * (~a2 + ~(b2') * (~x) ^ ~(non2')) ^ ~(p') * (~c + ~(d') * (~x) ^ ~(n') + ~(e') * (~x) ^ ~(n2')) ^ ~(q'), ~x) => Antiderivative(~u * (~a1 * ~a2 + ~b1 * ~b2 * (~x) ^ ~n) ^ ~p * (~c + ~d * (~x) ^ ~n + ~e * (~x) ^ (2 * ~n)) ^ ~q, ~x) <-- FreeQ([~a1, ~b1, ~a2, ~b2, ~c, ~d, ~e, ~n, ~p, ~q], ~x) && (EqQ(~non2, ~n / 2) && (EqQ(~n2, 2 * ~n) && (EqQ(~a2 * ~b1 + ~a1 * ~b2, 0) && (IntegerQ(~p) || GtQ(~a1, 0) && GtQ(~a2, 0)))))
    @apply_utils Antiderivative(~(u') * (~a1 + ~(b1') * (~x) ^ ~(non2')) ^ ~p * (~a2 + ~(b2') * (~x) ^ ~(non2')) ^ ~p * (~c + ~(d') * (~x) ^ ~(n')) ^ ~(q'), ~x) => (((~a1 + ~b1 * (~x) ^ (~n / 2)) ^ FracPart(~p) * (~a2 + ~b2 * (~x) ^ (~n / 2)) ^ FracPart(~p)) / (~a1 * ~a2 + ~b1 * ~b2 * (~x) ^ ~n) ^ FracPart(~p)) * Antiderivative(~u * (~a1 * ~a2 + ~b1 * ~b2 * (~x) ^ ~n) ^ ~p * (~c + ~d * (~x) ^ ~n) ^ ~q, ~x) <-- FreeQ([~a1, ~b1, ~a2, ~b2, ~c, ~d, ~n, ~p, ~q], ~x) && (EqQ(~non2, ~n / 2) && (EqQ(~a2 * ~b1 + ~a1 * ~b2, 0) && Not(EqQ(~n, 2) && IGtQ(~q, 0))))
    @apply_utils Antiderivative(~(u') * (~a1 + ~(b1') * (~x) ^ ~(non2')) ^ ~(p') * (~a2 + ~(b2') * (~x) ^ ~(non2')) ^ ~(p') * (~c + ~(d') * (~x) ^ ~(n') + ~(e') * (~x) ^ ~(n2')) ^ ~(q'), ~x) => (((~a1 + ~b1 * (~x) ^ (~n / 2)) ^ FracPart(~p) * (~a2 + ~b2 * (~x) ^ (~n / 2)) ^ FracPart(~p)) / (~a1 * ~a2 + ~b1 * ~b2 * (~x) ^ ~n) ^ FracPart(~p)) * Antiderivative(~u * (~a1 * ~a2 + ~b1 * ~b2 * (~x) ^ ~n) ^ ~p * (~c + ~d * (~x) ^ ~n + ~e * (~x) ^ (2 * ~n)) ^ ~q, ~x) <-- FreeQ([~a1, ~b1, ~a2, ~b2, ~c, ~d, ~e, ~n, ~p, ~q], ~x) && (EqQ(~non2, ~n / 2) && (EqQ(~n2, 2 * ~n) && EqQ(~a2 * ~b1 + ~a1 * ~b2, 0)))
end

max_stars_repo_path: src/rules/1 Algebraic functions/1.1 Binomial products/1.1.3 General/1.1.3.4 (e x)^m (a+b x^n)^p (c+d x^n)^q.jl


text:
"""Solves a 1OKP"""

"""
    backtrack(prob::Problem, indEndAssignment::Int, permList::Vector{Int}, iter::Int, bestSolPrim::Vector{Bool}, currentLB::Float64, poidsRestPrim::Float64, lb::Float64, ub::Float64; verbose = false)

    returns ...

    @prob : 1OKP to solve (the sub problems have the same number of variables)
    @assignment : array of assignments (of length n) (non ordered)
    @indFinAssignment : index of the last assigned variable (non ordered)
    @permList : permutation list sorting the variables. Beginning with the best ones, ending with worsts. Usage : permList[1] gives the index of the first best variable
    @revPermList : inverse permutation list allowing to get back to the original indexes of the variables
    @iter : ancient iterLastOne (ordered)
    @bestSolPrim : current best primal solution (indexed on ordered variables) : bestSolPrim[1] targets the first best variable.
    @currentLB : current lb
    @poidsRestPrim : space left in the bag
    @lb : best lower bound
    @ub : best upper bound
"""
function backtrack(prob::Problem, assignment::Vector{Int}, indEndAssignment::Int, permList::Vector{Int}, revPermList::Vector{Int}, iter::Int, bestSolPrim::Vector{Bool}, currentLB::Float64, poidsRestPrim::Float64, lb::Float64, ub::Float64; verbose = false)

    if iter == indEndAssignment || lb == ub # stopping rule, end of study or optimality
        return bestSolPrim, lb
    elseif bestSolPrim[iter] == 0 # we can't test anything here because the item is not assigned to one, we backtrack with iter-1
        return backtrack(prob, assignment, indEndAssignment, permList, revPermList, iter-1, bestSolPrim, currentLB, poidsRestPrim, lb, ub, verbose = verbose)
    elseif assignment[permList[iter]] != -1

    else
        iterLastOne = prob.nbVar # initialization of iterLastOne

        verbose && println("On tente d'améliorer en fixant x_$(permList[iter]) à 0")

        # GOAL : improve current solution by assigning the variable permList[iter] to zero.

        currentPoidsRest = poidsRestPrim + prob.constraint.weights[permList[iter]]
        currentProfit = currentLB - prob.objs[1].profits[permList[iter]]
        currentUB = Inf
        sol = falses(prob.nbVar-iter)

        iterSub = iter+1

        while iterSub <= prob.nbVar && prob.constraint.weights[permList[iterSub]] <= currentPoidsRest
            sol[iterSub - iter] = 1
            currentPoidsRest -= prob.constraint.weights[permList[iterSub]]
            currentProfit += prob.objs[1].profits[permList[iterSub]]
            iterLastOne = iterSub
            iterSub += 1
        end

        if iterSub <= prob.nbVar
            currentUB = currentProfit + (currentPoidsRest / prob.constraint.weights[permList[iterSub]]) * prob.objs[1].profits[permList[iterSub]]
        else
            currentUB = currentProfit
        end

        verbose && println("La valeur max du sous problème est : $currentUB et la meilleure solution actuelle : $lb")

        if currentUB > lb

            verbose && println("Le sous problème est peut-être améliorant ! ")

            while iterSub <= prob.nbVar && currentPoidsRest != 0
                if prob.constraint.weights[permList[iterSub]] <= currentPoidsRest
                    sol[iterSub - iter] = 1
                    currentPoidsRest -= prob.constraint.weights[permList[iterSub]]
                    currentProfit += prob.objs[1].profits[permList[iterSub]]
                    iterLastOne = iterSub
                end
                iterSub += 1
            end

            if currentProfit > lb

                verbose && println("Youpi on améliore : de $lb à $currentProfit")

                lb = currentProfit
                bestSolPrim[iter] = 0
                bestSolPrim[iter+1:end] = sol[1:end]
                iter = iterLastOne
                poidsRestPrim = currentPoidsRest

                verbose && println()
                return backtrack(prob, assignment, indEndAssignment, permList, revPermList, iter, bestSolPrim, lb, poidsRestPrim, lb, ub, verbose = verbose)
            else
                verbose && println("Coup dur, on continue le Backtrack")
                verbose && println()
                return backtrack(prob, assignment, indEndAssignment, permList, revPermList, iter-1, bestSolPrim, currentLB - prob.objs[1].profits[permList[iter]], poidsRestPrim + prob.constraint.weights[permList[iter]], lb, ub, verbose = verbose)
            end
        else
            verbose && println()
            return backtrack(prob, assignment, indEndAssignment, permList, revPermList, iter-1, bestSolPrim, currentLB - prob.objs[1].profits[permList[iter]], poidsRestPrim + prob.constraint.weights[permList[iter]], lb, ub, verbose = verbose)
        end
    end

end

"""
    solve1OKP(prob::Problem, assignment::Vector{Int} = Vector{Int}(), indEndAssignment::Int = 0, assignmentWeight::Float64 = 0., assignmentProfit::Float64 = 0.; verbose = false)

    return the unique solution of the given 1OKP

    @prob : 1OKP to solve (the sub problems have the same number of variables)
    @assignment : array of assignments (of length n) (non ordered)
    @indFinAssignment : index of the last assigned variable (non ordered)
    @assignmentWeight : the sum of the weights of the variables assigned to one
    @assignmentProfit : the sum of the profits of the variables assigned to one

    @bestSolPrim : current best primal solution (indexed on ordered variables) : bestSolPrim[1] targets the first best variable.
    @iterLastOne : index (ordered) of the last variable assigned to one in @bestSolPrim
"""
function solve1OKP(prob::Problem, assignment::Vector{Int} = Vector{Int}(), indEndAssignment::Int = 0, assignmentWeight::Float64 = 0., assignmentProfit::Float64 = 0.; verbose = false)
    @assert prob.nbObj == 1 "This problem is no 1OKP"

    # if the assignment is empty, we initialize the array at a size of nbVars in prob
    if assignment == []
        assignment  = Vector{Int}(undef, prob.nbVar)
        for iter = 1:prob.nbVar
            assignment[iter] = -1
        end
    end

    # permutation list sorting the variables. Beginning with the best ones, ending with worsts.
    # usage : permList[1] gives the index of the first best variable
    permList = sortperm(prob.objs[1].profits ./ prob.constraint.weights, rev = true)

    # inverse permutation list allowing to get back to the original indexes of the variables
    revPermList = Vector{Int}(undef, length(permList))
    # construction of the inverse permutation list
    for iter = 1:length(permList)
        revPermList[permList[iter]] = iter
    end

    # weight still available
    poidsRestPrim = prob.constraint.maxWeight - assignmentWeight

    # current best primal solution (indexed on ordered variables) : bestSolPrim[1] targets the first best variable.
    bestSolPrim = zeros(Bool, prob.nbVar)
    # construction of bestSolPrim
    iterLastOne = 0 # index (ordered) of the last variable assigned to one
    for iter = 1:prob.nbVar # iterating on variables (non ordered)
        var = permList[iter] # index of var (ordered)
        if assignment[var] != -1 # if the variable is assigned
            bestSolPrim[iter] = assignment[var] # the current sol assign this var to the same value
            if assignment[var] == 1 # the variable is assigned to one
                iterLastOne = var
            end
        end
    end

    iter = indEndAssignment + 1 # index (non ordered) of the first non assigned variable

    lb = 0. + assignmentProfit # profit we are sure to make because the solution is feasible
    ub = Inf

    """

    Construction of a good first feasible solution being our LowerBound. We compute our UpperBound by adding a portion of the next item.

    """

    # GOAL : inside bestSolPrim, we want to force to one all the first variables (ordered) that could fit in the knapsack
    # iterating on the variables after iter. We stop if we can't assign the next variable to one.
    while iter <= prob.nbVar && prob.constraint.weights[permList[iter]] <= poidsRestPrim
        bestSolPrim[iter] = 1

        verbose && println("On choisit de mettre l'objet $(permList[iter])")

        poidsRestPrim -= prob.constraint.weights[permList[iter]]
        lb += prob.objs[1].profits[permList[iter]]
        iterLastOne = iter
        iter += 1
    end

    # GOAL : check if bestSolPrim is optimal, and if not, compute a first upper bound
    if iter <= prob.nbVar # at least one object is assigned to zero
        # we can set the upper bound by adding the portion of the next item that can fit inside the knapsack
        ub = lb + (poidsRestPrim / prob.constraint.weights[permList[iter]]) * prob.objs[1].profits[permList[iter]]
    else # all the variables are assigned to one
        # bestSolPrim is optimal
        return Solution(bestSolPrim[revPermList], [lb])
    end

    verbose && println("La upperBound vaut donc : $ub")

    while iter <= prob.nbVar && poidsRestPrim != 0
        if prob.constraint.weights[permList[iter]] <= poidsRestPrim
            bestSolPrim[iter] = 1

       		verbose && println("On choisit de mettre l'objet $(permList[iter])")

            poidsRestPrim -= prob.constraint.weights[permList[iter]]
            lb += prob.objs[1].profits[permList[iter]]
            iterLastOne = iter
        end
        iter += 1
    end

    verbose && println("La lowerBound vaut donc : $lb")

    """

    Backtracking

    """

    verbose && println("On commence le Backtracking")

    return Solution(bestSolPrim[revPermList], [lb])
    exit()

    if revPermList[iterLastOne] > indEndAssignment # we'll begin the backtracking after the assignment
        sol, lb = backtrack(prob, assignment, indEndAssignment, permList, revPermList, iterLastOne, bestSolPrim, lb, poidsRestPrim, lb, ub, verbose = verbose)
        return Solution(sol[revPermList], [lb])
    else # the backtrack is useless
        return Solution(bestSolPrim[revPermList], [lb])
    end
end

"""

    JULES AREA

"""

"""
    returns the inverse permutation of the given permutation vector
"""
function revPerm(p::Vector{Int})
    revP = Vector{Int}(undef, length(p))
    for iter = 1:length(p)
        revP[p[iter]] = iter
    end
    return revP
end

"""
    construct and returns the subproblem associated with the given problem and assignment
"""
function createSubProblem(prob::Problem, assignment::Vector{Int}, assignmentWeight::Float64, indEndAssignment::Int; verbose = false)
    # verbose && println("[createSubProblem]")
    # newNbVars = prob.nbVar - indEndAssignment # new number of variables
    # newObjs = Vector{Obj}(undef, prob.nbObj) # new objectives
    # for indexObj in 1:length(prob.objs) # going through objectives
    #     obj = prob.objs[indexObj] # current objetive
    #     newObj = Vector{Float64}(undef, newNbVars) # new objective, replacing obj
    #     for indexVar in 1:newNbVars # iterating on the variables not assigned
    #         newObj[indexVar] = obj.profits[indexVar+indEndAssignment] # filling newObj
    #     end
    #     newObjs[indexObj] = Obj(newObj)
    # end
    # # result : newObjs contains the new objectives
    #
    # newWeightConstr = prob.constraint.maxWeight - assignmentWeight # new max capa
    # newWeights = Vector{Float64}(undef,newNbVars) # new vector of weights in the constraint
    # for indexVar in 1:newNbVars
    #     newWeights[indexVar] = prob.constraint.weights[indexVar+indEndAssignment]
    # end
    # newConstr = Const(newWeightConstr,newWeights)
    # # result : newConst is the new constraint for the subproblem
    #
    # # creation of the subproblem
    # subProb = Problem(prob.nbObj,newNbVars,newObjs,newConstr)
    # verbose && println("[END - createSubProblem]")
    # return subProb
    #
    # exit()

    return Problem(
        prob.nbObj,
        prob.nbVar - indEndAssignment,
        broadcast(obj->Obj(obj.profits[indEndAssignment+1:end]), prob.objs),
        Const(prob.constraint.maxWeight - assignmentWeight, prob.constraint.weights[indEndAssignment+1:end])
    )

end

"""
    returns the solution of the initial super problem, from a given solution and assignment for a subProblem
"""
function reconstructSuperSolution(solution::Solution, assignment::Vector{Int}, indEndAssignment::Int, assignmentProfit::Float64; verbose = false)
    verbose && println("[reconstructSuperSolution]")
    if indEndAssignment != 0
        nbVarsInSuperP = length(solution.x) + indEndAssignment
        newX = Vector{Bool}(undef,nbVarsInSuperP)
        # construction of newX
        for indexVar in 1:nbVarsInSuperP
            if indexVar <= indEndAssignment
                newX[indexVar] = assignment[indexVar]
            else
                newX[indexVar] = solution.x[indexVar-indEndAssignment]
            end
        end
        # result : newX is the new x
        newY = solution.y .+ [assignmentProfit]
        verbose && println("[END - reconstructSuperSolution]")
        return Solution(newX,newY)
    else
        verbose && println("[END - reconstructSuperSolution]")
        return solution
    end
end

"""
    backtrackJules(prob::Problem, p::Vector{Int}, revP::Vector{Int}, indexOnOrdered::Int, bestSolPrim::Vector{Bool}, currentLB::Float64, weightRemaining::Float64, lb::Float64, ub::Float64; verbose = false)

    returns ...

    [PARAMETERS]

    @prob : 1OKP to solve
    {
        @prob.nbObjs : always the same as the superProblem
        @prob.nbVars : number of vars of the subProblem and not the superProblem
        @prob.objs : vector of the objectives of the subProblem. Each objective is adapted to the subProblem (same number of variables)
        @prob.constraint : constraint of the subProblem, not the same as the superProblem
        {
            @prob.constraint.maxWeight : equal to maxWeight of the superP minus the assignmentWeight !
            @prob.constraint.weights : adapted to the subProblem, less variables.
        }
    }

    @p : permutation to order variables. p[1] indicate the first best variable.
    @revP : inverse permutation of p.
    @indexOnOrdered : index of the backtrack (going through the ordered vector)
    @bestSolPrim : current best primal solution (indexed on ordered variables) : bestSolPrim[1] targets the first best variable.
    @currentLB : current lb
    @weightRemaining : space left in the bag
    @lb : best lower bound
    @ub : best upper bound
"""
function backtrackJules(prob::Problem, p::Vector{Int}, revP::Vector{Int}, indexOnOrdered::Int, bestSolPrim::Vector{Bool}, currentLB::Float64, weightRemaining::Float64, lb::Float64, solLB::Vector{Bool}, ub::Float64; verbose = false)
    verbose && println("[backtrackJules] - indexOnOrdered = $indexOnOrdered, bestSolPrim = $bestSolPrim, bestSolPrim[revP] = $(bestSolPrim[revP])")

    if indexOnOrdered == 0 || lb == ub # stopping rule, end of study or optimality
    verbose && println("[END - backtrackJules]")
        return solLB, lb # returns the best solution known (which is always the optimal solution)
    elseif bestSolPrim[indexOnOrdered] == 0 # we can't test anything here because the item is not assigned to one, we backtrackJules with indexOnOrdered-1
        verbose && println("[RECURSIVE CALL - backtrackJules]")
        return backtrackJules(prob, p, revP, indexOnOrdered-1, bestSolPrim, currentLB, weightRemaining, lb, solLB, ub, verbose = verbose)
    else # we are somewhere in the oredered list and we indexOnOrdered targets a item assigned to one
        iterLastOne = prob.nbVar # initialization of iterLastOne

        verbose && println("\n- On tente d'améliorer en fixant x_$(p[indexOnOrdered]) (non ordered) à 0")

        # GOAL : improve current solution by assigning the variable p[indexOnOrdered] to zero.
        sol = falses(prob.nbVar-indexOnOrdered) # sol keep track of the current solution we are building
        currentWeightRemaining = weightRemaining + prob.constraint.weights[p[indexOnOrdered]] # because we took an item out of the bag
        currentProfit = currentLB - prob.objs[1].profits[p[indexOnOrdered]]
        currentUB = Inf

        verbose && println("\n- Forcing first variables that can fit into the bag")
        # GOAL : force the next variables (ordered). This will help us compute a new upper bound.
        # we stop when the next item can't fit in the bag
        indexBrokenOV = indexOnOrdered+1 # the item indexOnOrdered has to stay assigned to zero
        while indexBrokenOV <= prob.nbVar && prob.constraint.weights[p[indexBrokenOV]] <= currentWeightRemaining
            verbose && println("    (forcing $(p[indexBrokenOV]))")
            sol[indexBrokenOV - indexOnOrdered] = 1 # we assign the item to one
            currentWeightRemaining -= prob.constraint.weights[p[indexBrokenOV]] # the remaining weight decreases
            currentProfit += prob.objs[1].profits[p[indexBrokenOV]] # the profit increases
            iterLastOne = indexBrokenOV
            indexBrokenOV += 1
        end
        # result : indexBrokenOV targets the broken item in ordered list

        verbose && println("    -> new broken item (non ordered) = $(p[indexBrokenOV])")

        verbose && println("\n- updating currentLB")
        if indexBrokenOV <= prob.nbVar # at least the last variable (ordered) is assigned to zero, we can add a portion of the next item assigned to zero to get a UB.
            currentUB = currentProfit + (currentWeightRemaining / prob.constraint.weights[p[indexBrokenOV]]) * prob.objs[1].profits[p[indexBrokenOV]]
        else # all the next variables are assigned to one. The UB is the
            currentUB = currentProfit
        end
        # result : currentUB is the upper bound of the current sol

        verbose && println("    -> the current UB : $currentUB, best LB : $lb")

        if currentUB > lb # the new solution could be better than the old one

            verbose && println("\n- currentUB > lb -> Le sous problème est peut-être améliorant ! ")

            verbose && println("\n- Forcing the rest of the items that fit inside the bag")
            # GOAL : computing the current LowerBound by forcing the rest of the items that fit in the bag to one.
            while indexBrokenOV <= prob.nbVar && currentWeightRemaining != 0
                if prob.constraint.weights[p[indexBrokenOV]] <= currentWeightRemaining
                    verbose && println("    (forcing $(p[indexBrokenOV]))")
                    sol[indexBrokenOV - indexOnOrdered] = 1 # the item is set to one
                    currentWeightRemaining -= prob.constraint.weights[p[indexBrokenOV]] # the remaining weight decreases
                    currentProfit += prob.objs[1].profits[p[indexBrokenOV]] # the profit increases
                    iterLastOne = indexBrokenOV
                end
                indexBrokenOV += 1
            end
            # result : indexBrokenOV doesn't target a item in particular ! Could be a broken item or the end of the list.
            #        : currentProfit is the new current lb
            verbose && println("    -> currentProfit is the new current lb, currentProfit = $currentProfit")

            bestSolPrim[indexOnOrdered] = 0 # putting indexOnOrdered item to zero was a good choice, so we update bestSolPrim accordingly
            bestSolPrim[indexOnOrdered+1:end] = sol[1:end] # bestSolPrim copy the solution saved in the vector sol
            indexOnOrdered = iterLastOne
            weightRemaining = currentWeightRemaining

            if currentProfit > lb # comparing the new lower bound to the new one

                verbose && println("\n- currentProfit > lb -> YEY we have made a progress : from $lb to $currentProfit")

                verbose && println("\n- Update time(lb,bestSolPrim,indexOnOrdered,weightRemaining")
                lb = currentProfit # updating lb
                solLB = bestSolPrim[1:end] # updating the best known solution

                # we start a new backtrack, starting from the last one value
                verbose && println("[RECURSIVE CALL - backtrackJules]")
                return backtrackJules(prob, p, revP, indexOnOrdered, bestSolPrim, lb, weightRemaining, lb, solLB, ub, verbose = verbose)
            else # the new solution is not better
                verbose && println("\n- The new solution is not better, we keep backtracking\n")
                # we free the variable indexOnOrdered, so the lb and weightRemaining are updated
                verbose && println("[RECURSIVE CALL - backtrackJules]")
                return backtrackJules(prob, p, revP, indexOnOrdered, bestSolPrim, currentProfit, weightRemaining, lb, solLB, ub, verbose = verbose)
            end
        else # there is no way the new solution can be better than the old one
            verbose && println("The new solution can't be better, we keep backtracking\n")
            # we free the variable indexOnOrdered, so the lb and weightRemaining are updated
            newCurrentLB = currentLB - prob.objs[1].profits[p[indexOnOrdered]]
            newWeightRemaining = weightRemaining + prob.constraint.weights[p[indexOnOrdered]]
            verbose && println("[RECURSIVE CALL - backtrackJules]")
            return backtrackJules(prob, p, revP, indexOnOrdered-1, bestSolPrim, newCurrentLB, newWeightRemaining, lb, solLB, ub, verbose = verbose)
        end
    end
end

"""
    solve1OKPAux(prob::Problem, assignment::Vector{Int}, indEndAssignment::Int = 0, assignmentWeight::Float64 = 0., assignmentProfit::Float64 = 0.; verbose = false)

    Solve the 1OKP

    [PARAMETERS]

    @prob : 1OKP to solve
    {
        @prob.nbObjs : always the same as the superProblem
        @prob.nbVars : number of vars of the subProblem and not the superProblem
        @prob.objs : vector of the objectives of the subProblem. Each objective is adapted to the subProblem (same number of variables)
        @prob.constraint : constraint of the subProblem, not the same as the superProblem
        {
            @prob.constraint.maxWeight : equal to maxWeight of the superP minus the assignmentWeight !
            @prob.constraint.weights : adapted to the subProblem, less variables.
        }
    }
    @assignment : array of assignments (of length the original number of variables), indicating the values of the previous variables (non ordered)
    @indEndAssignment : index of the last assigned variable (non ordered)
    @assignmentWeight : the sum of the weights of the variables assigned to one
    @assignmentProfit : the sum of the profits of the variables assigned to one

    [VARIABLES]

    @p : permutation to order variables. p[1] indicate the first best variable.
    @revP : inverse permutation of p.
    @weightRemaining : weight remaining in the bag (take into account the assignment weight of course)
    @bestSolPrim : current best primal solution (indexed on ordered variables) : bestSolPrim[1] targets the first best variable.
    @iterLastOne : index (ordered) of the last variable assigned to one in @bestSolPrim
    @indexFirstNotAssignedOV : index (ordered) of the first variable not assigned
"""
function solve1OKPAux(prob::Problem; verbose = false)
    verbose && println("[solve1OKPMain]")
    # permutation list sorting the variables. Beginning with the best ones, ending with worsts.
    # usage : p[1] gives the index of the first best variable
    p = sortperm(prob.objs[1].profits ./ prob.constraint.weights, rev = true)
    # inverse permutation list allowing to get back to the original indexes of the variables
    revP = revPerm(p)

    lb = 0. # profit we are sure to make because the solution is feasible
    ub = Inf

    weightRemaining = prob.constraint.maxWeight

    """

    Construction of a good first feasible solution being our LowerBound. We compute our UpperBound by adding a portion of the next item.

    """

    bestSolPrim = zeros(Bool, prob.nbVar) # current best primal solution (indexed on ordered variables) : bestSolPrim[1] targets the first best variable.
    indexFirstNotAssignedOV = 1 # index (ordered) of the first variable not assigned
    iterLastOne = 0 # index (ordered) of the last variable assigned to one in @bestSolPrim
    # GOAL : inside bestSolPrim, we want to force to one all the first variables (ordered) that could fit in the knapsack
    # iterating on the best variables first. We stop if we can't assign the next variable to one.
    while indexFirstNotAssignedOV <= prob.nbVar && prob.constraint.weights[p[indexFirstNotAssignedOV]] <= weightRemaining
        orderedVar = p[indexFirstNotAssignedOV] # index of the variable (ordered)
        bestSolPrim[indexFirstNotAssignedOV] = 1 # we put the variable to one in the current solution
        weightRemaining -= prob.constraint.weights[orderedVar] # we substract the weight (non ordered) of the variable that we assigned to one
        lb += prob.objs[1].profits[orderedVar] # we add to the primal bound the profit of var
        iterLastOne = indexFirstNotAssignedOV # update iterLastOne
        indexFirstNotAssignedOV += 1
    end

    # GOAL : check if bestSolPrim is optimal, and if not, compute a first upper bound
    if indexFirstNotAssignedOV <= prob.nbVar # at least one object is assigned to zero
        # we can set the upper bound by adding the portion of the next item that can fit inside the knapsack
        ub = lb + (weightRemaining / prob.constraint.weights[p[indexFirstNotAssignedOV]]) * prob.objs[1].profits[p[indexFirstNotAssignedOV]]
    else # all the variables are assigned to one
        # bestSolPrim is optimal
        verbose && println("[END - solve1OKPAux]")
        return Solution(bestSolPrim[revP], [lb])
    end

    # GOAL : we finish to go through variables and try to put as many to one.
    # iterating on remaining variables (ordered), we stop if we don't have any space remaining in the bag
    while indexFirstNotAssignedOV <= prob.nbVar && weightRemaining > 0
        orderedVar = p[indexFirstNotAssignedOV] # index of the variable (non ordered)
        if prob.constraint.weights[orderedVar] <= weightRemaining # if the current var fits in the bag
            bestSolPrim[indexFirstNotAssignedOV] = 1 # assigning the var to one
            weightRemaining -= prob.constraint.weights[orderedVar] # updating the remaining space in the bag
            lb += prob.objs[1].profits[orderedVar] # updating the lower bound because we added a variable
            iterLastOne = indexFirstNotAssignedOV # updating iterLastOne
        end
        indexFirstNotAssignedOV += 1
    end

    """

    Backtracking or End

    """

    if iterLastOne >= 1 # we'll begin the backtracking after the assignment
        sol, lb = backtrackJules(prob, p, revP, iterLastOne, bestSolPrim, lb, weightRemaining, lb, bestSolPrim[1:end], ub, verbose = verbose)
        verbose && println("[END - solve1OKPAux]")
        return Solution(sol[revP], [lb])
    else # the backtrack is useless
        verbose && println("[END - solve1OKPAux]")
        return Solution(bestSolPrim[revP], [lb])
    end
end

"""
    solve1OKPMain(prob::Problem, assignment::Vector{Int} = Vector{Int}(), indEndAssignment::Int = 0, assignmentWeight::Float64 = 0., assignmentProfit::Float64 = 0.; verbose = false)

    Transform the problem into a subproblem and call solve1OKPAux on it

    @prob : 1OKP to solve (the sub problems have the same number of variables)
    @assignment : array of assignments (of length n) (not ordered)
    @indEndAssignment : index of the last assigned variable (not ordered)
    @assignmentWeight : the sum of the weights of the variables assigned to one
    @assignmentProfit : the sum of the profits of the variables assigned to one
"""
function solve1OKPMain(prob::Problem, assignment::Vector{Int} = Vector{Int}(), indEndAssignment::Int = 0, assignmentWeight::Float64 = 0., assignmentProfit::Float64 = 0.; verbose = false)
    @assert prob.nbObj == 1 "This problem is no 1OKP"
    verbose && println("[solve1OKPMain]")

    # if the assignment is empty, we initialize the array at a size of nbVars in prob
    if assignment == []
        verbose && println("[END - solve1OKPMain]")
        return solve1OKPAux(prob, verbose = verbose)
    else
        # creation of the subproblem
        subProb = createSubProblem(prob,assignment,assignmentWeight, indEndAssignment, verbose=verbose)
        verbose && println("[END - solve1OKPMain]")
        sol = solve1OKPAux(subProb, verbose=verbose)

        return reconstructSuperSolution(sol, assignment, indEndAssignment, assignmentProfit, verbose = verbose)

    end
end

ext: jl


text:
using ZygoteRules: @adjoint

@doc raw"
    einsum_grad(::EinCode{ixs, iy}, xs, size_dict, cdy, i)

return the gradient of the result of evaluating the `EinCode` w.r.t
the `i`th tensor in `xs`. `cdy` is the result of applying the `EinCode`
to the `xs`.

# example
```jldoctest; setup = :(using OMEinsum)
julia> using OMEinsum: einsum_grad, get_size_dict

julia> a, b = rand(2,2), rand(2,2);

julia> c = einsum(EinCode((('i','j'),('j','k')), ('i','k')), (a,b));

julia> sd = get_size_dict((('i','j'),('j','k')), (a,b));

julia> einsum_grad(EinCode((('i','j'),('j','k')), ('i','k')), (a,b), sd, c, 1) ≈ c * transpose(b)
true
```
"
function einsum_grad(::EinCode{ixs, iy}, xs, size_dict, cdy, i) where {ixs, iy}
    nixs = TupleTools.insertat(ixs, i, (iy,))
    nxs  = TupleTools.insertat( xs, i, (cdy,))
    niy = ixs[i]
    y = einsum(EinCode(nixs, niy), nxs, size_dict)
    try
        conj!(y)
    catch e
        y = conj(y)
    end
    typeof(y) == typeof(xs[i]) && return y
    xs[i] isa Array{<:Real} && return convert(typeof(xs[i]), real(y))
    convert(typeof(xs[i]), y)
end

@adjoint function einsum(code::EinCode{ixs, iy}, xs::NTuple{N,T where T}, size_dict::IndexSize) where {N, ixs, iy}
    y = einsum(code, xs, size_dict)
    return y, dy -> let cdy = map(conj,dy)
                (
                    nothing,
                    ntuple(i -> einsum_grad(code, xs, size_dict, cdy, i), N),
                    nothing
                )
            end
end

# @Zygote.nograd get_size_dict
@adjoint get_size_dict(arg...) = get_size_dict(arg...), Δ -> map(_->nothing, arg)


text:
# AUTO GENERATED FILE - DO NOT EDIT

export ''_home

"""
    ''_home(;kwargs...)
    ''_home(children::Any;kwargs...)
    ''_home(children_maker::Function;kwargs...)

A Home component.

Keyword arguments:
- `children` (a list of or a singular dash component, string or number; optional)
- `id` (String; optional)
- `isOpen` (Bool; optional)
"""
function ''_home(; kwargs...)
        available_props = Symbol[:children, :id, :isOpen]
        wild_props = Symbol[]
        return Component("''_home", "Home", "python_version", available_props, wild_props; kwargs...)
end

''_home(children::Any; kwargs...) = ''_home(;kwargs..., children = children)
''_home(children_maker::Function; kwargs...) = ''_home(children_maker(); kwargs...)

max_stars_repo_licenses: CNRI-Python Xnet X11

max_issues_repo_licenses: CNRI-Python Xnet X11

max_forks_repo_licenses: CNRI-Python Xnet X11


text:
@testset "Arithmetic" begin
    x = DNAMer("AA")
    @test x - 1 == x + (-1) == x - 0x01 == DNAMer("TT")
    @test x + 1 == x - (-1) == x + 0x01 == DNAMer("AC")

    x = BigDNAMer("AA")
    @test x - 1 == x + (-1) == x - 0x01 == BigDNAMer("TT")
    @test x + 1 == x - (-1) == x + 0x01 == BigDNAMer("AC")

    x = DNAMer("TT")
    @test x - 1 == x + (-1) == x - 0x01 == DNAMer("TG")
    @test x + 1 == x - (-1) == x + 0x01 == DNAMer("AA")

    x = BigDNAMer("TT")
    @test x - 1 == x + (-1) == x - 0x01 == BigDNAMer("TG")
    @test x + 1 == x - (-1) == x + 0x01 == BigDNAMer("AA")

    base = DNAMer("AAA")
    offset = 0
    nucs = "ACGT"
    for a in nucs, b in nucs, c in nucs
        @test base + offset == DNAMer(string(a, b, c))
        offset += 1
    end

    base = BigDNAMer("AAA")
    offset = 0
    nucs = "ACGT"
    for a in nucs, b in nucs, c in nucs
        @test base + offset == BigDNAMer(string(a, b, c))
        offset += 1
    end

    @testset "typemin" begin
        for k in 1:64
            if k <= 32
                @test typemin(DNAMer{k}) === DNAMer("A"^k)
                @test typemin(RNAMer{k}) === RNAMer("A"^k)
            end

            @test typemin(BigDNAMer{k}) === BigDNAMer("A"^k)
            @test typemin(BigRNAMer{k}) === BigRNAMer("A"^k)
        end
        @test_throws ArgumentError typemin(DNAMer{0})
        @test_throws ArgumentError typemin(DNAMer{33})

        @test_throws ArgumentError typemin(BigDNAMer{0})
        @test_throws ArgumentError typemin(BigDNAMer{65})
    end

    @testset "typemax" begin
        for k in 1:64
            if k <= 32
                @test typemax(DNAMer{k}) === DNAMer("T"^k)
                @test typemax(RNAMer{k}) === RNAMer("U"^k)
            end

            @test typemax(BigDNAMer{k}) === BigDNAMer("T"^k)
            @test typemax(BigRNAMer{k}) === BigRNAMer("U"^k)
        end
        @test_throws ArgumentError typemax(DNAMer{0})
        @test_throws ArgumentError typemax(DNAMer{33})

        @test_throws ArgumentError typemax(BigDNAMer{0})
        @test_throws ArgumentError typemax(BigDNAMer{65})
    end
end


text:
module TestBuilderInstall

using Test
using Scratch
using Comonicon.Configs
using Comonicon.Builder: ensure_path, entryfile_script, completion_script, detect_rcfile

@testset "ensure_path" begin
    path = tempname()
    @test ispath(path) == false
    ensure_path(path)
    @test ispath(path) == true
end

module TestInstall

using Comonicon

@cast foo(x) = 0
@cast goo(x) = 1

@main

end

@testset "entryfile_script" begin
    options = Configs.Comonicon(name = "test")
    script = entryfile_script(TestInstall, options)

    @test occursin("#!/usr/bin/env bash", script)
    @test occursin("JULIA_PROJECT=$(get_scratch!(TestInstall, "env"))", script)
    julia_exe = joinpath(Sys.BINDIR, Base.julia_exename())
    @test occursin("exec $julia_exe \\\n", script)
    @test occursin("--startup-file=no \\\n", script)
    @test occursin("--color=yes \\\n", script)
    @test occursin("--compile=yes \\\n", script)
    @test occursin("--optimize=2 \\\n", script)
    @test occursin("-- \"\${BASH_SOURCE[0]}\"", script)
    @test occursin(
        "using Main.TestBuilderInstall.TestInstall\nexit(Main.TestBuilderInstall.TestInstall.command_main())",
        script,
    )
end

@testset "test completion script" begin
    options = Configs.Comonicon(name = "test")
    withenv("SHELL" => "/bin/zsh") do
        script = completion_script(TestInstall, options, "zsh")
        @test occursin("#compdef _testinstall testinstall \n", script)
    end

    withenv("SHELL" => "/bin/fakesh") do
        @test_throws ErrorException completion_script(TestInstall, options, "/bin/fakesh")
    end
end

@testset "detect_rcfile" begin
    withenv("SHELL" => "zsh") do
        @test detect_rcfile("zsh") == joinpath(homedir(), ".zshrc")
    end

    withenv("SHELL" => "zsh", "ZDOTDIR" => "zsh_dir") do
        @test detect_rcfile("zsh") == joinpath("zsh_dir", ".zshrc")
    end
end

end # TestBuilderInstall


text:
function GNSSDate(arg0::AbsoluteDate, arg1::SatelliteSystem)
    return GNSSDate((AbsoluteDate, SatelliteSystem), arg0, arg1)
end

function GNSSDate(arg0::AbsoluteDate, arg1::SatelliteSystem, arg2::TimeScales)
    return GNSSDate((AbsoluteDate, SatelliteSystem, TimeScales), arg0, arg1, arg2)
end

function GNSSDate(arg0::jint, arg1::jdouble, arg2::SatelliteSystem)
    return GNSSDate((jint, jdouble, SatelliteSystem), arg0, arg1, arg2)
end

function GNSSDate(arg0::jint, arg1::jdouble, arg2::SatelliteSystem, arg3::TimeScales)
    return GNSSDate((jint, jdouble, SatelliteSystem, TimeScales), arg0, arg1, arg2, arg3)
end

function get_date(obj::GNSSDate)
    return jcall(obj, "getDate", AbsoluteDate, ())
end

function get_milli_in_week(obj::GNSSDate)
    return jcall(obj, "getMilliInWeek", jdouble, ())
end

function get_rollover_reference(::Type{GNSSDate})
    return jcall(GNSSDate, "getRolloverReference", DateComponents, ())
end

function get_week_number(obj::GNSSDate)
    return jcall(obj, "getWeekNumber", jint, ())
end

function set_rollover_reference(::Type{GNSSDate}, arg0::DateComponents)
    return jcall(GNSSDate, "setRolloverReference", void, (DateComponents,), arg0)
end


text:
using Base.Iterators

export all_functions, sqrt, has_sqrt, all_sqrts, random_square

# This code is for finding compositional square roots of functions.
# It is extremely inefficient!!!

"""
`all_functions(n)` returns a generator that produces all
`DiscreteFunctions` on `{1,2,...,n}`
"""
function all_functions(n::Int)
    @assert n>0 "Argument must be a positive integer"
    arg = (1:n for t=1:n)
    iter = product(arg...)
    (DiscreteFunction(collect(t)) for t in iter)
end
#
# OLD VERSION OF sqrt
#
# """
# `sqrt(f::DiscreteFunction)` returns a `DiscreteFunction`
# `g` such that `g*g==f` or throws an error if no such `g` exists.
# """
# function sqrt(f::DiscreteFunction)::DiscreteFunction
#     n = length(f)
#     gen = all_functions(n)
#     for g in gen
#         if g*g == f
#             return g
#         end
#     end
#     error("This function does not have a square root")
# end

"""
`all_sqrts(f::DiscreteFunction)` returns an array consisting
of all `g` such that `g*g==f`.
"""
function all_sqrts(f::DiscreteFunction)
    n = length(f)
    gen = all_functions(n)
    [ g for g in gen if g*g==f ]
end

"""
`all_squares(n)` returns a list of all function on `[n]` that are
perfect compositional squares.
"""
function all_squares(n::Int)
    G = all_functions(n)
    S = Set(f*f for f in G)
    collect(S)
end

"""
`random_square(n)` returns a `DiscreteFunction` on `n` elements
that has a compositional square root.
"""
function random_square(n::Int)::DiscreteFunction
    @assert n>0 "Require `n` to be positive"
    while true
        f = RandomFunction(n)
        if has_sqrt(f)
            return f
        end
    end
end


text:
using InstantiateFromURL
activate_github("QuantEcon/QuantEconLectureAllPackages", tag = "v0.9.5");

max_stars_repo_name: aderdzyan/QuantEcon-lecture-source-jl

max_issues_repo_name: aderdzyan/QuantEcon-lecture-source-jl

max_forks_repo_name: aderdzyan/QuantEcon-lecture-source-jl