Skip to content

Commit cf823f0

Browse files
authored
#364 - Add more simplification rules (#407)
1 parent 04d7051 commit cf823f0

File tree

5 files changed

+102
-15
lines changed

5 files changed

+102
-15
lines changed

xFunc.Maths/Analyzers/Analyzer{TResult,TContext}.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ namespace xFunc.Maths.Analyzers
3434
/// <typeparam name="TContext">The type of additional parameter for analyzer.</typeparam>
3535
/// <seealso cref="IAnalyzer{TResult,TContext}" />
3636
[ExcludeFromCodeCoverage]
37-
public class Analyzer<TResult, TContext> : IAnalyzer<TResult, TContext>
37+
public abstract class Analyzer<TResult, TContext> : IAnalyzer<TResult, TContext>
3838
{
3939
/// <inheritdoc />
4040
/// <exception cref="NotSupportedException">Always.</exception>

xFunc.Maths/Analyzers/Simplifier.cs

+9-14
Original file line numberDiff line numberDiff line change
@@ -242,23 +242,22 @@ public override IExpression Analyze(Add exp)
242242
(Sub(var left, Number right), Number number)
243243
=> Analyze(new Add(new Number(number.Value - right.Value), left)),
244244

245-
// TODO: nested complex 'x'
246-
247245
// ax + x
248246
// xa + x
249247
// x + bx
250248
// x + xb
251-
(Mul(Number a, Variable x1), Variable x2) when x1.Equals(x2)
249+
(Mul(Number a, var x1), var x2) when x1.Equals(x2)
252250
=> Analyze(new Mul(new Number(a.Value + 1), x1)),
253251

254252
// ax + bx
255253
// ax + xb
256254
// xa + bx
257255
// xa + xb
258-
(Mul(Number a, Variable x1), Mul(Number b, Variable x2)) when x1.Equals(x2)
256+
(Mul(Number a, var x1), Mul(Number b, var x2)) when x1.Equals(x2)
259257
=> Analyze(new Mul(new Number(a.Value + b.Value), x1)),
260258

261-
var (left, right) when IsChanged(exp, left, right) => new Add(left, right),
259+
var (left, right) when IsChanged(exp, left, right)
260+
=> new Add(left, right),
262261

263262
_ => exp,
264263
};
@@ -535,20 +534,18 @@ public override IExpression Analyze(Mul exp)
535534
(Div(var left, Number right), Number number)
536535
=> Analyze(new Mul(new Number(number.Value / right.Value), left)),
537536

538-
// TODO: nested complex 'x'
539-
540537
// ax * x
541538
// xa * x
542539
// x * bx
543540
// x * xb
544-
(Mul(Number a, Variable x1), Variable x2) when x1.Equals(x2)
541+
(Mul(Number a, var x1), var x2) when x1.Equals(x2)
545542
=> Analyze(new Mul(a, new Pow(x1, Number.Two))),
546543

547544
// ax + bx
548545
// ax + xb
549546
// xa + bx
550547
// xa + xb
551-
(Mul(Number a, Variable x1), Mul(Number b, Variable x2)) when x1.Equals(x2)
548+
(Mul(Number a, var x1), Mul(Number b, var x2)) when x1.Equals(x2)
552549
=> Analyze(new Mul(new Number(a.Value * b.Value), new Pow(x1, Number.Two))),
553550

554551
// x * (1 / x)
@@ -766,23 +763,21 @@ public override IExpression Analyze(Sub exp)
766763
(Number number, Sub(var left, Number right))
767764
=> Analyze(new Sub(new Number(number.Value + right.Value), left)),
768765

769-
// TODO: nested complex 'x'
770-
771766
// x - bx
772767
// x - xb
773-
(Variable x1, Mul(Number b, Variable x2)) when x1.Equals(x2)
768+
(var x1, Mul(Number b, var x2)) when x1.Equals(x2)
774769
=> Analyze(new Mul(new Number(1 - b.Value), x1)),
775770

776771
// ax - x
777772
// xa - x
778-
(Mul(Number a, Variable x1), Variable x2) when x1.Equals(x2)
773+
(Mul(Number a, var x1), var x2) when x1.Equals(x2)
779774
=> Analyze(new Mul(new Number(a.Value - 1), x1)),
780775

781776
// ax - bx
782777
// ax - xb
783778
// xa - bx
784779
// xa - xb
785-
(Mul(Number a, Variable x1), Mul(Number b, Variable x2)) when x1.Equals(x2)
780+
(Mul(Number a, var x1), Mul(Number b, var x2)) when x1.Equals(x2)
786781
=> Analyze(new Mul(new Number(a.Value - b.Value), x1)),
787782

788783
var (left, right) when IsChanged(exp, left, right)

xFunc.Tests/Analyzers/SimplifierTests/AddSimplifierTest.cs

+26
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,17 @@ public void AddSaveVars2()
201201
SimplifyTest(exp, expected);
202202
}
203203

204+
[Fact(DisplayName = "2 * (x + y) + (x + y)")]
205+
public void AddComplexX()
206+
{
207+
var exp = new Add(
208+
new Mul(Number.Two, new Add(Variable.X, new Variable("Y"))),
209+
new Add(Variable.X, new Variable("Y")));
210+
var expected = new Mul(new Number(3), new Add(Variable.X, new Variable("Y")));
211+
212+
SimplifyTest(exp, expected);
213+
}
214+
204215
[Fact(DisplayName = "x + 2x")]
205216
public void AddSaveVars3()
206217
{
@@ -231,6 +242,21 @@ public void AddSaveVars5()
231242
SimplifyTest(exp, expected);
232243
}
233244

245+
[Fact(DisplayName = "2 * (x + y) + 3 * (x + y)")]
246+
public void AddComplexX2()
247+
{
248+
var exp = new Add(
249+
new Mul(Number.Two, new Add(Variable.X, new Variable("y"))),
250+
new Mul(new Number(3), new Add(Variable.X, new Variable("y")))
251+
);
252+
var expected = new Mul(
253+
new Number(5),
254+
new Add(Variable.X, new Variable("y"))
255+
);
256+
257+
SimplifyTest(exp, expected);
258+
}
259+
234260
[Fact(DisplayName = "-x + x")]
235261
public void AddSaveVars6()
236262
{

xFunc.Tests/Analyzers/SimplifierTests/MulSimplifierTest.cs

+30
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,21 @@ public void MulSameVar2()
220220
SimplifyTest(mul, expected);
221221
}
222222

223+
[Fact(DisplayName = "2 * (x + y) * (x + y)")]
224+
public void MulComplexX()
225+
{
226+
var mul = new Mul(
227+
new Mul(Number.Two, new Add(Variable.X, new Variable("y"))),
228+
new Add(Variable.X, new Variable("y"))
229+
);
230+
var expected = new Mul(
231+
Number.Two,
232+
new Pow(new Add(Variable.X, new Variable("y")), Number.Two)
233+
);
234+
235+
SimplifyTest(mul, expected);
236+
}
237+
223238
[Fact(DisplayName = "2x * 3x")]
224239
public void MulSameVar3()
225240
{
@@ -232,6 +247,21 @@ public void MulSameVar3()
232247
SimplifyTest(mul, expected);
233248
}
234249

250+
[Fact(DisplayName = "2 * (x + y) * 3 * (x + y)")]
251+
public void MulComplexX2()
252+
{
253+
var mul = new Mul(
254+
new Mul(Number.Two, new Add(Variable.X, new Variable("y"))),
255+
new Mul(new Number(3), new Add(Variable.X, new Variable("y")))
256+
);
257+
var expected = new Mul(
258+
new Number(6),
259+
new Pow(new Add(Variable.X, new Variable("y")), Number.Two)
260+
);
261+
262+
SimplifyTest(mul, expected);
263+
}
264+
235265
[Fact(DisplayName = "x * 2x")]
236266
public void MulSameVar4()
237267
{

xFunc.Tests/Analyzers/SimplifierTests/SubSimplifierTest.cs

+36
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,18 @@ public void SubSameVars4()
201201
SimplifyTest(sub, expected);
202202
}
203203

204+
[Fact(DisplayName = "(x + y) - 2 * (x + y)")]
205+
public void SubComplexX()
206+
{
207+
var sub = new Sub(
208+
new Add(Variable.X, new Variable("y")),
209+
new Mul(Number.Two, new Add(Variable.X, new Variable("y")))
210+
);
211+
var expected = new UnaryMinus(new Add(Variable.X, new Variable("y")));
212+
213+
SimplifyTest(sub, expected);
214+
}
215+
204216
[Fact(DisplayName = "x - (x * 2)")]
205217
public void SubSameVars5()
206218
{
@@ -210,6 +222,18 @@ public void SubSameVars5()
210222
SimplifyTest(sub, expected);
211223
}
212224

225+
[Fact(DisplayName = "2 * (x + y) - (x + y)")]
226+
public void SubComplexX2()
227+
{
228+
var sub = new Sub(
229+
new Mul(Number.Two, new Add(Variable.X, new Variable("y"))),
230+
new Add(Variable.X, new Variable("y"))
231+
);
232+
var expected = new Add(Variable.X, new Variable("y"));
233+
234+
SimplifyTest(sub, expected);
235+
}
236+
213237
[Fact(DisplayName = "2x - x")]
214238
public void SubSameVars6()
215239
{
@@ -240,6 +264,18 @@ public void SubSameVars8()
240264
SimplifyTest(sub, expected);
241265
}
242266

267+
[Fact(DisplayName = "3 * (x + y) - 2 * (x + y)")]
268+
public void SubComplexX3()
269+
{
270+
var sub = new Sub(
271+
new Mul(new Number(3), new Add(Variable.X, new Variable("y"))),
272+
new Mul(Number.Two, new Add(Variable.X, new Variable("y")))
273+
);
274+
var expected = new Add(Variable.X, new Variable("y"));
275+
276+
SimplifyTest(sub, expected);
277+
}
278+
243279
[Fact(DisplayName = "(x * 3) - (x * 2)")]
244280
public void SubSameVars9()
245281
{

0 commit comments

Comments
 (0)