diff --git a/BREAKING-CHANGES.md b/BREAKING-CHANGES.md
index f82ee966a..c8ea6e633 100644
--- a/BREAKING-CHANGES.md
+++ b/BREAKING-CHANGES.md
@@ -527,6 +527,20 @@ interval without a case for each. Only where nothing else answers the integrand
| `"acoth(x)^2/(1-x^2)^2".ToEntity().Integrate("x")` | `integral(...)` | 1,304 characters, with `(ln((x + 1)/(x - 1)) - ln((1 + x)/(1 - x)))/2` for `K` |
| `"acoth(c*x)^2/(1-c^2*x^2)^2".ToEntity().Integrate("x")` | `integral(...)` | 1,681 characters |
+### A power of a sum of exponentials that is one exponential is written as it
+
+**Answers where there were none, and a shorter one.** The parser writes `cosh(u) + sinh(u)` as
+`(e^u + e^(-u))/2 + (e^u - e^(-u))/2`, and nothing collected it. Rubi's 6.7.1 `F^(a + b x) (cosh(c + d x) + sinh(c + d x))^n`
+and its twin with the difference were declined. A power of such a sum is now written as the one exponential it is,
+`c^n e^(p n u)` for a sum that is `c e^(p u)`, which holds for a real `u` since `e^(p u)` is positive
+([#233](https://github.com/asc-community/AngouriMath/issues/233)).
+
+| Input | Was (2.5.0) | Now |
+|---|---|---|
+| `"F^(a+b*x)*(cosh(c+d*x)+sinh(c+d*x))^n".ToEntity().Integrate("x")` | `integral(...)` | 160 characters |
+| `"F^(a+b*x)*(cosh(c+d*x)-sinh(c+d*x))^n".ToEntity().Integrate("x")` | `integral(...)` | 165 characters |
+| `"(cosh(x)+sinh(x))^3".ToEntity().Integrate("x")` | 787 characters | `e^(3 x)/3`, 19 characters |
+
### A function of the hyperbolic tangent alone is integrated under `u = tanh`
**Answers where there were none.** `tanh(x)/sqrt(a + b tanh(x)^2 + c tanh(x)^4)` was declined, and so were 35 more of
diff --git a/Sources/AngouriMath/Functions/Continuous/Integration/IndefiniteIntegralSolver.cs b/Sources/AngouriMath/Functions/Continuous/Integration/IndefiniteIntegralSolver.cs
index 37e3c6c9d..beb4e0234 100644
--- a/Sources/AngouriMath/Functions/Continuous/Integration/IndefiniteIntegralSolver.cs
+++ b/Sources/AngouriMath/Functions/Continuous/Integration/IndefiniteIntegralSolver.cs
@@ -41968,6 +41968,60 @@ Entity Times(Entity term)
/// Set while asks its question.
[System.ThreadStatic] private static bool clearingANegativeExponential;
+ ///
+ /// A power of a sum of exponentials of x that is one exponential, written as it: Rubi's
+ /// F^(a + b x) (cosh(c + d x) + sinh(c + d x))^n is F^(a + b x) e^(n (c + d x)).
+ /// https://github.com/asc-community/AngouriMath/issues/233
+ ///
+ ///
+ /// The parser writes the hyperbolic functions as exponentials, and the sum is
+ /// (e^u + e^(-u))/2 + (e^u - e^(-u))/2 as written, which nothing collects: beside
+ /// F^(a + b x) it was declined. With each exponential a whole power of the first,
+ /// w, the base is a Laurent polynomial in w, and where one coefficient is left it
+ /// is c w^p; (c w^p)^n is c^n w^(p n) for a positive w, which e to a
+ /// real power is. At the question asked.
+ ///
+ internal static Entity? SolveByFoldingASumOfExponentialsIntoOne(Entity expr, Entity.Variable x, bool integrateByParts)
+ {
+ if (!Integration.AnsweringTheQuestionAsked)
+ return null;
+ static bool IsAnExponential(Entity node, Entity.Variable x) => node is Powf(var @base, var exponent) && @base == MathS.e && exponent.ContainsNode(x);
+ var folded = expr.Replace(node =>
+ {
+ if (node is not Powf(Sumf or Minusf, var power) raised || power.ContainsNode(x) || power == Number.Integer.One)
+ return node;
+ var sum = raised.Base;
+ var exponentials = sum.Nodes.Where(inner => IsAnExponential(inner, x)).Distinct().ToList();
+ if (exponentials.Count < 2
+ || sum.Replace(inner => IsAnExponential(inner, x) ? Number.Integer.One : inner).ContainsNode(x))
+ return node;
+ // Each a whole power of the first, e^(m + k x).
+ var first = ((Powf)exponentials[0]).Exponent;
+ var powers = new Dictionary();
+ foreach (var exponential in exponentials)
+ if (Functions.PartialFractions.Bare((((Powf)exponential).Exponent / first).Simplify()) is Number.Integer { EInteger: var whole } && whole.CanFitInInt32())
+ powers[exponential] = whole.ToInt32Unchecked();
+ else
+ return node;
+ var w = Variable.CreateUnique(expr, "w_fold");
+ var inW = sum.Replace(inner => powers.TryGetValue(inner, out var k) ? MathS.Pow(w, Number.Integer.Create(k)) : inner);
+ // Expanded, `(w + 1/w)/2 + (w - 1/w)/2` is `w provided not w = 0`, and w is never 0.
+ if (!TreeAnalyzer.TryGetPolynomial(Functions.PartialFractions.Bare(inW.Expand()), w, out var read))
+ return node;
+ var left = read.Where(pair => !Functions.PartialFractions.IsZeroAsAValue(pair.Value)).ToList();
+ if (left.Count != 1 || !left[0].Key.CanFitInInt32())
+ return node;
+ var (degree, coefficient) = (left[0].Key.ToInt32Unchecked(), Functions.PartialFractions.Bare(left[0].Value.InnerSimplified));
+ var exponentialOfThePower = MathS.Pow(MathS.e, (power * degree * first).InnerSimplified);
+ return coefficient == Number.Integer.One ? exponentialOfThePower : MathS.Pow(coefficient, power) * exponentialOfThePower;
+ });
+ if (folded == expr)
+ return null;
+ // Inner-simplified, which takes the `ln(e)` the rule for `F^u` writes for the base to 1.
+ var answer = Integration.ComputeAsTheSameQuestion(folded.InnerSimplified, x, integrateByParts)?.InnerSimplified;
+ return answer is not null && Functions.PartialFractions.DerivativeHoldsAtSampledPoints(answer, expr, x) ? answer : null;
+ }
+
///
/// A squared sine and a squared cosine of one argument in a sum, written as the one they
/// add up to: Rubi's e^(cos(x)^2 + sin(x)^2) is e x.
diff --git a/Sources/AngouriMath/Functions/Continuous/Integration/Integration.Definition.cs b/Sources/AngouriMath/Functions/Continuous/Integration/Integration.Definition.cs
index 110f98822..803834f4e 100644
--- a/Sources/AngouriMath/Functions/Continuous/Integration/Integration.Definition.cs
+++ b/Sources/AngouriMath/Functions/Continuous/Integration/Integration.Definition.cs
@@ -695,6 +695,8 @@ internal static bool ASumOverRootsWouldAnswer
// And a squared sine beside the squared cosine of its argument, the one they add up to:
// `e^(cos(x)^2 + sin(x)^2)` was declined, written with an x its value does not hold.
if ((answer = IndefiniteIntegralSolver.SolveByFoldingAPythagoreanPair(expr, x, integrateByParts)) is { }) return answer;
+ // And a power of a sum of exponentials that is one exponential, the hyperbolic `cosh(u) + sinh(u)`.
+ if ((answer = IndefiniteIntegralSolver.SolveByFoldingASumOfExponentialsIntoOne(expr, x, integrateByParts)) is { }) return answer;
// An arctangent over a power of d (1 +- i c x), under x = tan(u)/c, where 1 + i tan(u) is
// e^(i u)/cos(u): the rules below ran out of time on `(a + b atan(c x))^2/(d + i c d x)^2`.
if ((answer = IndefiniteIntegralSolver.SolveAnArctangentOverAPowerOfOnePlusICXUnderTheTangent(expr, x, integrateByParts)) is { }) return answer;
diff --git a/Sources/Tests/UnitTests/Calculus/APowerOfASumOfExponentialsThatIsOneIntegralTest.cs b/Sources/Tests/UnitTests/Calculus/APowerOfASumOfExponentialsThatIsOneIntegralTest.cs
new file mode 100644
index 000000000..a7f34ec90
--- /dev/null
+++ b/Sources/Tests/UnitTests/Calculus/APowerOfASumOfExponentialsThatIsOneIntegralTest.cs
@@ -0,0 +1,49 @@
+//
+// Copyright (c) 2019-2026 Angouri.
+// AngouriMath is licensed under MIT.
+// Details: https://github.com/asc-community/AngouriMath/blob/master/LICENSE.md.
+// Website: https://am.angouri.org.
+//
+
+using System;
+using AngouriMath.Extensions;
+using Xunit;
+
+namespace AngouriMath.Tests.Calculus
+{
+ ///
+ /// A power of a sum of exponentials that is one exponential, written as it: the parser writes
+ /// cosh(u) + sinh(u) as (e^u + e^(-u))/2 + (e^u - e^(-u))/2, which nothing collected, and
+ /// Rubi's 6.7.1 F^(a + b x) (cosh(c + d x) + sinh(c + d x))^n was declined.
+ /// #233
+ ///
+ [Trait("Area", "Calculus")]
+ public sealed class APowerOfASumOfExponentialsThatIsOneIntegralTest
+ {
+ [Theory]
+ [InlineData("F^(a + b*x)*(cosh(c + d*x) + sinh(c + d*x))^n", 400)]
+ [InlineData("F^(a + b*x)*(cosh(c + d*x) - sinh(c + d*x))^n", 400)]
+ [InlineData("(cosh(x) + sinh(x))^3", 40)]
+ [InlineData("x*(cosh(x) - sinh(x))^(5/2)", 120)]
+ public void IsOneExponential(string integrand, int characters)
+ {
+ var integral = integrand.ToEntity().Integrate("x");
+ var text = integral.Stringize();
+ Assert.DoesNotContain("integral(", text);
+ Assert.True(text.Length < characters, $"the antiderivative of {integrand} is {text.Length} characters: {text}");
+ Entity Pinned(Entity e) => e.Substitute("F", 1.7).Substitute("a", 1.3).Substitute("b", 0.7).Substitute("c", 0.4)
+ .Substitute("d", 0.9).Substitute("n", 0.6);
+ var derivative = Pinned(integral.Substitute("C", 0)).Differentiate("x");
+ var original = Pinned(integrand.ToEntity());
+ foreach (var at in new[] { -1.7, -0.6, 0.4, 1.3, 2.2 })
+ {
+ var want = original.Substitute("x", at).EvalNumerical();
+ var got = derivative.Substitute("x", at).EvalNumerical();
+ Assert.False(got.IsNaN, $"d/dx of the antiderivative of {integrand} has no value at x = {at}, where the integrand is {want}");
+ Assert.True(Math.Abs((double)(got - want).RealPart) + Math.Abs((double)(got - want).ImaginaryPart)
+ < 1e-9 * Math.Max(1, Math.Abs((double)want.RealPart) + Math.Abs((double)want.ImaginaryPart)),
+ $"d/dx of the antiderivative of {integrand} is {got} at x = {at}, where the integrand is {want}");
+ }
+ }
+ }
+}