From 621628d7821ddb04e775b5d0bd8853483c20fa6c Mon Sep 17 00:00:00 2001 From: Rafael Vuijk Date: Sat, 8 Aug 2026 00:33:19 +0000 Subject: [PATCH] Pin three accepted proposals that are already implemented (#246, #214, #185) Each of these asks for behaviour the library already has, and each is pinned by the example the proposal itself gives, so that closing it rests on a test rather than on a reading. #246 a logarithmic solver, converting logarithms to a polynomial where possible log(2, x) + log(2, x - 1) = 1 -> { 2 } ln(x)^2 - 3*ln(x) + 2 = 0 -> { e, e^2 } #214 a ^ f(x) + b ^ g(x) + ... = 0 2^x + 4^x = 6 -> { 1 } 3^(2x) - 4*3^x + 3 = 0 -> { 0, 1 } #185 collecting unlike terms by treating each as an unknown e^x + sin(x) + 2e^x + 2sin(x) -> 3*(sin(x) + e^x) Every root is substituted back into its equation. A solver that answers the right root alongside a wrong one is not solving the equation, and the printed set does not say which it has done -- which is the whole reason #115 and #272 were defects rather than gaps. Grouped into one commit rather than three, against the usual habit of a branch per issue, because there is no behaviour change to bisect: it is one test file recording a measurement about three issues. Test-only; 8 pass. Co-Authored-By: Claude Opus 5 (1M context) --- ...AcceptedProposalsAlreadyImplementedTest.cs | 96 +++++++++++++++++++ 1 file changed, 96 insertions(+) create mode 100644 Sources/Tests/UnitTests/Algebra/AcceptedProposalsAlreadyImplementedTest.cs diff --git a/Sources/Tests/UnitTests/Algebra/AcceptedProposalsAlreadyImplementedTest.cs b/Sources/Tests/UnitTests/Algebra/AcceptedProposalsAlreadyImplementedTest.cs new file mode 100644 index 000000000..a0c6c55bd --- /dev/null +++ b/Sources/Tests/UnitTests/Algebra/AcceptedProposalsAlreadyImplementedTest.cs @@ -0,0 +1,96 @@ +// +// Copyright (c) 2019-2022 Angouri. +// AngouriMath is licensed under MIT. +// Details: https://github.com/asc-community/AngouriMath/blob/master/LICENSE.md. +// Website: https://am.angouri.org. +// + +using AngouriMath; +using AngouriMath.Extensions; +using Xunit; + +namespace AngouriMath.Tests.Algebra +{ + /// + /// Three accepted proposals that ask for behaviour the library already has. Each is + /// pinned here by the example the proposal itself gives, so that closing it rests on a + /// test rather than on a reading. + /// + [Trait("Area", "Algebra")] + public sealed class AcceptedProposalsAlreadyImplementedTest + { + /// + /// "we need a logarithmic solver which converts equation with logarithms to + /// polynomial, if possible". + /// https://github.com/asc-community/AngouriMath/issues/246 + /// + [Theory] + [InlineData("log(2, x) + log(2, x - 1) = 1", "2")] + [InlineData("log(3, x) = 2", "9")] + [InlineData("ln(x) + ln(x + 1) = ln(6)", "2")] + public void ALogarithmicEquationIsSolved(string equation, string root) + { + var roots = Assert.IsType(equation.ToEntity().Solve("x").InnerSimplified); + Assert.Contains(root.ToEntity(), roots); + foreach (var found in roots) + AssertSatisfies(equation, found); + } + + /// + /// The quadratic-in-a-logarithm case, which is the "converts to polynomial" half. + /// + [Fact] + public void AQuadraticInALogarithmIsSolved() + { + var roots = Assert.IsType( + "ln(x) ^ 2 - 3 * ln(x) + 2 = 0".ToEntity().Solve("x").InnerSimplified); + Assert.Contains(MathS.e, roots); + Assert.Contains(MathS.e.Pow(2).InnerSimplified, roots); + } + + /// + /// "So that a ^ f(x) + b ^ g(x) + ... = 0 could be solved." + /// https://github.com/asc-community/AngouriMath/issues/214 + /// + [Theory] + [InlineData("2 ^ x + 4 ^ x = 6", "1")] + [InlineData("3 ^ (2 * x) - 4 * 3 ^ x + 3 = 0", "1")] + [InlineData("2 ^ x = 8", "3")] + public void AnExponentialEquationIsSolved(string equation, string root) + { + var roots = Assert.IsType(equation.ToEntity().Solve("x").InnerSimplified); + Assert.Contains(root.ToEntity(), roots); + foreach (var found in roots) + AssertSatisfies(equation, found); + } + + /// + /// The proposal's own worked example: e^x + sin(x) + 2e^x + 2sin(x) should + /// collect to 3e^x + 3sin(x), by treating each distinct non-polynomial term + /// as an unknown of its own. + /// https://github.com/asc-community/AngouriMath/issues/185 + /// + [Fact] + public void UnlikeTermsAreCollectedByTreatingEachAsAnUnknown() + { + var difference = ("e^x + sin(x) + 2*e^x + 2*sin(x)".ToEntity() + - "3*e^x + 3*sin(x)".ToEntity()).Simplify(); + Assert.Equal(Entity.Number.Integer.Create(0), difference); + } + + /// + /// Every root is substituted back. A solver that answers the right root alongside a + /// wrong one is not solving the equation, and the printed set does not say which it + /// has done. + /// + private static void AssertSatisfies(string equation, Entity root) + { + var residual = equation.ToEntity() is Entity.Equalsf(var lhs, var rhs) + ? lhs - rhs + : equation.ToEntity(); + var at = residual.Substitute("x", root).Simplify(); + while (at is Entity.Providedf(var inner, _)) at = inner; + Assert.Equal(Entity.Number.Integer.Create(0), at); + } + } +}