diff --git a/BREAKING-CHANGES.md b/BREAKING-CHANGES.md
index 277e44c3b..954ee66b5 100644
--- a/BREAKING-CHANGES.md
+++ b/BREAKING-CHANGES.md
@@ -396,6 +396,26 @@ in Rubi's 1.1.3.4 come out shorter as well, and those that took two seconds take
| `"1/(x^8*(a + b*x^3)*(c + d*x^3))".ToEntity().Integrate("x")` | `integral(...)` | 1,217 characters |
| `"1/(x^6*(a + b*x^4)*(c + d*x^4))".ToEntity().Integrate("x")` | `integral(...)` | 795 characters |
+### A trigonometric function of `a + b/x` beside a rational function is integrated in `1/x`
+
+**Answers where there were none.** `sin(c + d/x)/(e + f x)` was declined: the substitution search reads a candidate's
+derivative but never solves the candidate for `x`. Under `x = 1/u` it is `-sin(c + d u)/(u (e u + f)) du`, which the
+partial fractions and the sine and cosine integrals answer, and `x = 1/u` is one-to-one on either side of 0. Below a
+root of a linear, the linear radical substitution gets there first
+([#718](https://github.com/asc-community/AngouriMath/issues/718)).
+
+The answers below a root are large because the sine over the linears that come out of the substitution carries
+expanded coefficients ([#1877](https://github.com/asc-community/AngouriMath/issues/1877)).
+
+| Input | Was (2.5.0) | Now |
+|---|---|---|
+| `"sin(c + d/x)/(e + f*x)".ToEntity().Integrate("x")` | `integral(...)` | 196 characters |
+| `"(a + b*sin(c + d/x))/(e + f*x)^2".ToEntity().Integrate("x")` | `integral(...)` | 470 characters |
+| `"(a + b*sin(c + d/x))^2/(e + f*x)^3".ToEntity().Integrate("x")` | `integral(...)` | 2,516 characters |
+| `"(c*e + d*e*x)^(1/3)*sin(a + b/(c + d*x)^(1/3))".ToEntity().Integrate("x")` | `integral(...)` | 1,453 characters |
+| `"sin(a + b/sqrt(c + d*x))/(e + f*x)".ToEntity().Integrate("x")` | `integral(...)` | 12,010 characters |
+| `"sin(a + b/sqrt(c + d*x))/(e + f*x)^2".ToEntity().Integrate("x")` | `integral(...)` | 32,780 characters |
+
### A power of the cosine beside a secant binomial is integrated in the cosine
**Answers where there were none.** `cos(c + d x)^2/(a + b sec(c + d x))` was declined, and so were the cosine's powers
diff --git a/Sources/AngouriMath/Functions/Continuous/Integration/IndefiniteIntegralSolver.cs b/Sources/AngouriMath/Functions/Continuous/Integration/IndefiniteIntegralSolver.cs
index dfca3fe23..7d0e7556d 100644
--- a/Sources/AngouriMath/Functions/Continuous/Integration/IndefiniteIntegralSolver.cs
+++ b/Sources/AngouriMath/Functions/Continuous/Integration/IndefiniteIntegralSolver.cs
@@ -19120,6 +19120,77 @@ Entity TakeOut(Entity node)
/// Set while asks its question.
[System.ThreadStatic] private static bool takingTheWholePowersOut;
+ ///
+ /// A rational function of x and of trigonometric functions of a + b/x, under
+ /// x = 1/u: sin(c + d/x)/(e + f x) is
+ /// -sin(c + d u)/(u (e u + f)) du, which the partial fractions and the sine and
+ /// cosine integrals answer.
+ ///
+ ///
+ /// x = 1/u is one-to-one on either side of 0, so the answer in u written back
+ /// in 1/x holds on both. Every argument of a function holding x has to be
+ /// linear in 1/x and not in x, so the integrand in u is one this rule
+ /// does not read again. Rubi's 4.1.12 (a + b sin(c + d/x))^k/(e + f x)^m were
+ /// declined: the substitution search reads a candidate's derivative but never solves
+ /// the candidate for x. https://github.com/asc-community/AngouriMath/issues/718
+ ///
+ internal static Entity? SolveByTheReciprocalOfAFunctionOfTheReciprocal(Entity expr, Entity.Variable x, bool integrateByParts)
+ {
+ var u = Variable.CreateUnique(expr, "u_rec");
+ // Each function of x, named, and written in u: its argument the linear in u it is.
+ var inU = new Dictionary();
+ var names = new Dictionary();
+ foreach (var node in expr.Nodes)
+ {
+ Entity argument;
+ switch (node)
+ {
+ case Sinf(var a): argument = a; break;
+ case Cosf(var a): argument = a; break;
+ case Tanf(var a): argument = a; break;
+ case Cotanf(var a): argument = a; break;
+ case Secantf(var a): argument = a; break;
+ case Cosecantf(var a): argument = a; break;
+ case Powf(_, Number.Integer):
+ case Sumf or Minusf or Mulf or Divf or Variable or Number:
+ continue;
+ default:
+ if (node.ContainsNode(x))
+ return null;
+ continue;
+ }
+ if (!argument.ContainsNode(x) || inU.ContainsKey(node))
+ continue;
+ if (!TreeAnalyzer.TryGetPolynomial(argument.Substitute(x, Number.Integer.One / u).InnerSimplified, u, out var read)
+ || read.Keys.Any(k => k.Sign < 0 || k.CompareTo(EInteger.One) > 0) || !read.TryGetValue(EInteger.One, out var slope))
+ return null;
+ Entity linear = read.TryGetValue(EInteger.Zero, out var constant)
+ ? constant.InnerSimplified + slope.InnerSimplified * u
+ : slope.InnerSimplified * u;
+ inU[node] = node switch
+ {
+ Sinf => MathS.Sin(linear),
+ Cosf => MathS.Cos(linear),
+ Tanf => MathS.Tan(linear),
+ Cotanf => MathS.Cotan(linear),
+ Secantf => MathS.Sec(linear),
+ Cosecantf => MathS.Cosec(linear),
+ _ => node,
+ };
+ names[node] = Variable.CreateUnique(expr, "f_rec" + names.Count);
+ }
+ if (inU.Count == 0)
+ return null;
+ // The rest one quotient, the way the rules read it: not `e + f/u` but `(e u + f)/u`.
+ var named = expr.Replace(node => names.TryGetValue(node, out var name) ? name : node);
+ var integrand = Functions.SingleQuotient.Combine(-named.Substitute(x, Number.Integer.One / u) / MathS.Sqr(u)).InnerSimplified;
+ foreach (var pair in names)
+ integrand = integrand.Substitute(pair.Value, inU[pair.Key]);
+ if (Integration.ComputeIndefiniteIntegral(integrand, u, integrateByParts) is not { } inTermsOfU)
+ return null;
+ return inTermsOfU.Substitute(u, Number.Integer.One / x);
+ }
+
///
/// A root of a product beside a root of one of its factors, the product split:
/// (P Q)^r is K P^r Q^r, where K = (P Q)^r/(P^r Q^r) is constant wherever
diff --git a/Sources/AngouriMath/Functions/Continuous/Integration/Integration.Definition.cs b/Sources/AngouriMath/Functions/Continuous/Integration/Integration.Definition.cs
index b4c2725ba..bf2c21f94 100644
--- a/Sources/AngouriMath/Functions/Continuous/Integration/Integration.Definition.cs
+++ b/Sources/AngouriMath/Functions/Continuous/Integration/Integration.Definition.cs
@@ -666,6 +666,9 @@ private static Entity Normalized(Entity expr, Entity.Variable x) =>
if ((answer = IndefiniteIntegralSolver.SolveAGaussianInAReciprocal(expr, x)) is { }) return answer;
// And a trigonometric function of the reciprocal of a linear beside a power of it, under u = 1/L.
if ((answer = IndefiniteIntegralSolver.SolveAFunctionOfTheReciprocalOfALinear(expr, x, integrateByParts)) is { }) return answer;
+ // And one of `a + b/x` beside any rational function, under `x = 1/u`:
+ // `sin(c + d/x)/(e + f x)` is `-sin(c + d u)/(u (e u + f)) du`.
+ if ((answer = IndefiniteIntegralSolver.SolveByTheReciprocalOfAFunctionOfTheReciprocal(expr, x, integrateByParts)) is { }) return answer;
// An exponential of a multiple of a logarithm is a power of the argument, which is
// how every inverse hyperbolic function under an exponential arrives.
if ((answer = IndefiniteIntegralSolver.SolveByFoldingAnExponentialOfALogarithm(expr, x, integrateByParts)) is { }) return answer;
diff --git a/Sources/Tests/UnitTests/Calculus/AFunctionOfTheReciprocalIntegralTest.cs b/Sources/Tests/UnitTests/Calculus/AFunctionOfTheReciprocalIntegralTest.cs
new file mode 100644
index 000000000..c06b1d265
--- /dev/null
+++ b/Sources/Tests/UnitTests/Calculus/AFunctionOfTheReciprocalIntegralTest.cs
@@ -0,0 +1,79 @@
+//
+// 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 trigonometric function of a + b/x beside a rational function, under x = 1/u:
+ /// sin(c + d/x)/(e + f x) is -sin(c + d u)/(u (e u + f)) du.
+ /// #718
+ ///
+ ///
+ /// Rubi's 4.1.12 (a + b sin(c + d/x))^k/(e + f x)^m were declined. Each answer is
+ /// differentiated back on both sides of 0.
+ ///
+ [Trait("Area", "Calculus")]
+ public sealed class AFunctionOfTheReciprocalIntegralTest
+ {
+ private static void DifferentiatesBack(string integrand, double[] points, params (string, double)[] pins)
+ {
+ var integral = integrand.ToEntity().Integrate("x");
+ Assert.DoesNotContain("integral(", integral.Stringize());
+ Assert.DoesNotContain("NaN", integral.Stringize());
+
+ var derivative = integral.Substitute("C", 0).Differentiate("x");
+ Entity original = integrand.ToEntity();
+ foreach (var (name, value) in pins)
+ {
+ derivative = derivative.Substitute(name, value);
+ original = original.Substitute(name, value);
+ }
+
+ var compared = 0;
+ foreach (var at in points)
+ {
+ var got = derivative.Substitute("x", at).EvalNumerical();
+ var want = original.Substitute("x", at).EvalNumerical();
+ if (got.IsNaN || want.IsNaN)
+ continue;
+ compared++;
+ var difference = Math.Abs((double)(got - want).RealPart)
+ + Math.Abs((double)(got - want).ImaginaryPart);
+ var scale = Math.Max(1.0, Math.Abs((double)want.RealPart) + Math.Abs((double)want.ImaginaryPart));
+ Assert.True(difference / scale < 1e-8,
+ $"d/dx of the antiderivative of {integrand} is {got} at x = {at}, "
+ + $"where the integrand is {want}");
+ }
+ Assert.True(compared >= 3,
+ $"only {compared} of {points.Length} points were comparable for {integrand}");
+ }
+
+ [Theory]
+ [InlineData("sin(c+d/x)/(e+f*x)")]
+ [InlineData("cos(c+d/x)/(e+f*x)^2")]
+ [InlineData("(a+b*sin(c+d/x))/(e+f*x)^3")]
+ [InlineData("(a+b*sin(c+d/x))^2/(e+f*x)")]
+ public void AFunctionOfAPlusBOverX(string integrand)
+ {
+ var points = new[] { -1.4, -0.3, 0.8, 2.25 };
+ DifferentiatesBack(integrand, points, ("a", 1.0 / 3), ("b", 2), ("c", 1.5), ("d", 1.25), ("e", 2), ("f", 3));
+ }
+
+ [Theory]
+ [InlineData("(c*e+d*e*x)^(1/3)*sin(a+b/(c+d*x)^(1/3))")]
+ [InlineData("sin(a+b/sqrt(c+d*x))/(e+f*x)")]
+ public void AFunctionOfAPlusBOverARootOfALinear(string integrand)
+ {
+ var points = new[] { -0.3, 0.8, 2.25 };
+ DifferentiatesBack(integrand, points, ("a", 1.0 / 3), ("b", 2), ("c", 1.5), ("d", 1.25), ("e", 2), ("f", 3));
+ }
+ }
+}