-
-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
#224 - Introduce simplification rules
- Loading branch information
Showing
71 changed files
with
1,433 additions
and
8 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
namespace xFunc.Maths.Analyzers2; | ||
|
||
internal class ChainRuleBuilder<TExpression> : | ||
IInitialChainRuleBuilder<TExpression>, | ||
IChainRuleBuilder<TExpression> | ||
where TExpression : IExpression | ||
{ | ||
private ChainRule initialRule; | ||
private ChainRule currentRule; | ||
|
||
public IChainRuleBuilder<TExpression> WithRule(IRule<TExpression> rule) | ||
{ | ||
initialRule = currentRule = new ChainRule(rule); | ||
|
||
return this; | ||
} | ||
|
||
public IChainRuleBuilder<TExpression> WithNext(IRule<TExpression> next) | ||
{ | ||
var chain = new ChainRule(next); | ||
currentRule.SetNext(chain); | ||
currentRule = chain; | ||
|
||
return this; | ||
} | ||
|
||
public IRule GetRule() | ||
=> initialRule.UnwrapIfEmpty(); | ||
|
||
private sealed class ChainRule : IRule<TExpression> | ||
{ | ||
private readonly IRule<TExpression> current; | ||
private IRule<TExpression>? next; | ||
|
||
public ChainRule(IRule<TExpression> rule) | ||
=> current = rule ?? throw new ArgumentNullException(nameof(rule)); | ||
|
||
public void SetNext(IRule<TExpression> rule) | ||
=> next = rule ?? throw new ArgumentNullException(nameof(rule)); | ||
|
||
public IRule UnwrapIfEmpty() | ||
=> next is null ? current : this; | ||
|
||
public Result Execute(IExpression expression, RuleContext context) | ||
{ | ||
var result = current.Execute(expression, context); | ||
if (result.IsHandled() || result.IsReAnalyze()) | ||
return result; | ||
|
||
if (result.IsContinue()) | ||
expression = result.Value; | ||
|
||
if (next is not null) | ||
return next.Execute(expression, context); | ||
|
||
return Result.NotHandled(); | ||
} | ||
|
||
public Result Execute(TExpression expression, RuleContext context) | ||
=> Execute(expression as IExpression, context); | ||
|
||
public string Name => "Chain Rule"; | ||
|
||
public string Description => "This is a chain of rules."; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
namespace xFunc.Maths.Analyzers2; | ||
|
||
public readonly struct ExecutionStep | ||
{ | ||
public ExecutionStep(IRule rule, IExpression before, IExpression after) | ||
{ | ||
Name = rule.Name; | ||
Description = rule.Description; | ||
Before = before; | ||
After = after; | ||
} | ||
|
||
public string Name { get; } | ||
|
||
public string Description { get; } | ||
|
||
public IExpression Before { get; } | ||
|
||
public IExpression After { get; } | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
namespace xFunc.Maths.Analyzers2; | ||
|
||
public interface IAnalyzer2 | ||
{ | ||
IExpression Analyze(IExpression expression); | ||
|
||
IExpression Analyze(IExpression expression, RuleContext context); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
namespace xFunc.Maths.Analyzers2; | ||
|
||
internal interface IChainRuleBuilder<out TExpression> | ||
where TExpression : IExpression | ||
{ | ||
IChainRuleBuilder<TExpression> WithNext(IRule<TExpression> next); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
namespace xFunc.Maths.Analyzers2; | ||
|
||
internal interface IInitialChainRuleBuilder<out TExpression> | ||
where TExpression : IExpression | ||
{ | ||
IChainRuleBuilder<TExpression> WithRule(IRule<TExpression> rule); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
namespace xFunc.Maths.Analyzers2; | ||
|
||
public interface IRule | ||
{ | ||
Result Execute(IExpression expression, RuleContext context); | ||
|
||
string Name { get; } | ||
|
||
string Description { get; } | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
namespace xFunc.Maths.Analyzers2; | ||
|
||
public interface IRule<in TExpression> : IRule | ||
{ | ||
Result Execute(TExpression expression, RuleContext context); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
namespace xFunc.Maths.Analyzers2; | ||
|
||
public readonly struct Result | ||
{ | ||
private readonly ResultKind kind; | ||
|
||
private Result(ResultKind kind, IExpression? value) | ||
{ | ||
this.kind = kind; | ||
Value = value; | ||
} | ||
|
||
public static Result NotHandled() | ||
=> new Result(ResultKind.NotHandled, default); | ||
|
||
public static Result Handled(IExpression value) | ||
=> new Result(ResultKind.Handled, value); | ||
|
||
public static Result Continue(IExpression value) | ||
=> new Result(ResultKind.Continue, value); | ||
|
||
public static Result ReAnalyze(IExpression value) | ||
=> new Result(ResultKind.ReAnalyze, value); | ||
|
||
private bool IsKind(ResultKind kind) | ||
=> this.kind == kind; | ||
|
||
public bool IsNotHandled() | ||
=> IsKind(ResultKind.NotHandled); | ||
|
||
public bool IsHandled() | ||
=> IsKind(ResultKind.Handled); | ||
|
||
public bool IsContinue() | ||
=> IsKind(ResultKind.Continue); | ||
|
||
public bool IsReAnalyze() | ||
=> IsKind(ResultKind.ReAnalyze); | ||
|
||
public IExpression? Value { get; } | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
namespace xFunc.Maths.Analyzers2; | ||
|
||
public enum ResultKind | ||
{ | ||
NotHandled, | ||
Handled, | ||
Continue, | ||
ReAnalyze, | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
namespace xFunc.Maths.Analyzers2; | ||
|
||
public abstract class Rule<TExpression> : IRule<TExpression> | ||
where TExpression : IExpression | ||
{ | ||
Result IRule.Execute(IExpression expression, RuleContext context) | ||
=> Execute((TExpression)expression, context); | ||
|
||
public Result Execute(TExpression expression, RuleContext context) | ||
{ | ||
var result = ExecuteInternal(expression, context); | ||
if (result.IsHandled() || result.IsContinue() || result.IsReAnalyze()) | ||
context.AddStep(this, expression, result.Value); | ||
|
||
return result; | ||
} | ||
|
||
protected abstract Result ExecuteInternal(TExpression expression, RuleContext context); | ||
|
||
protected static Result Handled(IExpression value) | ||
=> Result.Handled(value); | ||
|
||
protected static Result Continue(IExpression value) | ||
=> Result.Continue(value); | ||
|
||
protected static Result ReAnalyze(IExpression value) | ||
=> Result.ReAnalyze(value); | ||
|
||
protected static Result NotHandled() | ||
=> Result.NotHandled(); | ||
|
||
public virtual string Name => GetType().Name; | ||
|
||
public abstract string Description { get; } | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
namespace xFunc.Maths.Analyzers2; | ||
|
||
public class RuleContext | ||
{ | ||
private readonly IAnalyzer2 analyzer; | ||
private readonly List<ExecutionStep> steps; | ||
|
||
public RuleContext(IAnalyzer2 analyzer) | ||
{ | ||
this.analyzer = analyzer; | ||
this.steps = new List<ExecutionStep>(); | ||
} | ||
|
||
public IExpression Analyze(IExpression expression) | ||
=> analyzer.Analyze(expression, this); | ||
|
||
public void AddStep(IRule rule, IExpression before, IExpression after) | ||
=> steps.Add(new ExecutionStep(rule, before, after)); | ||
|
||
public IEnumerable<ExecutionStep> Steps => steps; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
namespace xFunc.Maths.Analyzers2; | ||
|
||
internal class RuleStorage | ||
{ | ||
private readonly IDictionary<Type, IRule> rules; | ||
|
||
public RuleStorage(IDictionary<Type, IRule> rules) | ||
=> this.rules = rules; | ||
|
||
public IRule? GetRule(Type type) | ||
{ | ||
rules.TryGetValue(type, out var rule); | ||
|
||
return rule; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
namespace xFunc.Maths.Analyzers2; | ||
|
||
internal class RuleStorageBuilder | ||
{ | ||
private readonly IDictionary<Type, IRule> rules = new Dictionary<Type, IRule>(); | ||
|
||
public RuleStorageBuilder WithRule<TExpression>(IRule<TExpression> rule) | ||
where TExpression : IExpression | ||
{ | ||
rules[typeof(TExpression)] = rule; | ||
|
||
return this; | ||
} | ||
|
||
public RuleStorageBuilder WithChain<TExpression>( | ||
Action<IInitialChainRuleBuilder<TExpression>> builder) | ||
where TExpression : IExpression | ||
{ | ||
var ruleBuilder = new ChainRuleBuilder<TExpression>(); | ||
builder(ruleBuilder); | ||
var rule = ruleBuilder.GetRule(); | ||
rules[typeof(TExpression)] = rule; | ||
|
||
return this; | ||
} | ||
|
||
public RuleStorage Build() | ||
=> new RuleStorage(rules); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
namespace xFunc.Maths.Analyzers2.Rules.AbsRules; | ||
|
||
public class AbsNestedRule : Rule<Abs> | ||
{ | ||
protected override Result ExecuteInternal(Abs expression, RuleContext context) | ||
=> expression.Argument switch | ||
{ | ||
Abs abs => Handled(abs), | ||
_ => NotHandled(), | ||
}; | ||
|
||
public override string Name => "Abs Nested Rule"; | ||
|
||
public override string Description => ""; | ||
} |
15 changes: 15 additions & 0 deletions
15
xFunc.Maths/Analyzers2/Rules/AbsRules/AbsUnaryMinusRule.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
namespace xFunc.Maths.Analyzers2.Rules.AbsRules; | ||
|
||
public class AbsUnaryMinusRule : Rule<Abs> | ||
{ | ||
protected override Result ExecuteInternal(Abs expression, RuleContext context) | ||
=> expression.Argument switch | ||
{ | ||
UnaryMinus minus => Handled(minus.Argument), | ||
_ => NotHandled(), | ||
}; | ||
|
||
public override string Name => "Abs Unary Minus"; | ||
|
||
public override string Description => ""; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
namespace xFunc.Maths.Analyzers2.Rules.AbsRules; | ||
|
||
public class AbsUnaryRule : UnaryRule<Abs> | ||
{ | ||
protected override Abs Create(IExpression argument) | ||
=> new Abs(argument); | ||
|
||
public override string Name => "Abs Unary Rule"; | ||
|
||
public override string Description => ""; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
namespace xFunc.Maths.Analyzers2.Rules.AddRules; | ||
|
||
public class AddBinaryRule : BinaryRule<Add> | ||
{ | ||
protected override Add Create(IExpression left, IExpression right) | ||
=> new Add(left, right); | ||
|
||
public override string Name => "Add Binary Rule"; | ||
|
||
public override string Description => ""; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
namespace xFunc.Maths.Analyzers2.Rules.AddRules; | ||
|
||
public class AddConstAngle : Rule<Add> | ||
{ | ||
protected override Result ExecuteInternal(Add expression, RuleContext context) | ||
=> expression switch | ||
{ | ||
(Number left, Angle right) | ||
=> Handled((left.Value + right.Value).AsExpression()), | ||
(Angle left, Number right) | ||
=> Handled((left.Value + right.Value).AsExpression()), | ||
(Angle left, Angle right) | ||
=> Handled((left.Value + right.Value).AsExpression()), | ||
|
||
_ => NotHandled(), | ||
}; | ||
|
||
public override string Name => "Add Angle Constants"; | ||
|
||
public override string Description => ""; | ||
} |
Oops, something went wrong.