using System;
|
using System.Collections.Generic;
|
using System.Linq;
|
using System.Text;
|
using Jace.Operations;
|
using Jace.Execution;
|
|
namespace Jace
|
{
|
public class Optimizer
|
{
|
private readonly IExecutor executor;
|
|
public Optimizer(IExecutor executor)
|
{
|
this.executor = executor;
|
}
|
|
public Operation Optimize(Operation operation, IFunctionRegistry functionRegistry, IConstantRegistry constantRegistry)
|
{
|
if (!operation.DependsOnVariables && operation.IsIdempotent && operation.GetType() != typeof(IntegerConstant)
|
&& operation.GetType() != typeof(FloatingPointConstant))
|
{
|
double result = executor.Execute(operation, functionRegistry, constantRegistry);
|
return new FloatingPointConstant(result);
|
}
|
else
|
{
|
if (operation.GetType() == typeof(Addition))
|
{
|
Addition addition = (Addition)operation;
|
addition.Argument1 = Optimize(addition.Argument1, functionRegistry, constantRegistry);
|
addition.Argument2 = Optimize(addition.Argument2, functionRegistry, constantRegistry);
|
}
|
else if (operation.GetType() == typeof(Subtraction))
|
{
|
Subtraction substraction = (Subtraction)operation;
|
substraction.Argument1 = Optimize(substraction.Argument1, functionRegistry, constantRegistry);
|
substraction.Argument2 = Optimize(substraction.Argument2, functionRegistry, constantRegistry);
|
}
|
else if (operation.GetType() == typeof(Multiplication))
|
{
|
Multiplication multiplication = (Multiplication)operation;
|
multiplication.Argument1 = Optimize(multiplication.Argument1, functionRegistry, constantRegistry);
|
multiplication.Argument2 = Optimize(multiplication.Argument2, functionRegistry, constantRegistry);
|
|
if ((multiplication.Argument1.GetType() == typeof(FloatingPointConstant) && ((FloatingPointConstant)multiplication.Argument1).Value == 0.0)
|
|| (multiplication.Argument2.GetType() == typeof(FloatingPointConstant) && ((FloatingPointConstant)multiplication.Argument2).Value == 0.0))
|
{
|
return new FloatingPointConstant(0.0);
|
}
|
}
|
else if (operation.GetType() == typeof(Division))
|
{
|
Division division = (Division)operation;
|
division.Dividend = Optimize(division.Dividend, functionRegistry, constantRegistry);
|
division.Divisor = Optimize(division.Divisor, functionRegistry, constantRegistry);
|
}
|
else if (operation.GetType() == typeof(Exponentiation))
|
{
|
Exponentiation division = (Exponentiation)operation;
|
division.Base = Optimize(division.Base, functionRegistry, constantRegistry);
|
division.Exponent = Optimize(division.Exponent, functionRegistry, constantRegistry);
|
}
|
else if(operation.GetType() == typeof(Function))
|
{
|
Function function = (Function)operation;
|
IList<Operation> arguments = function.Arguments.Select(a => Optimize(a, functionRegistry, constantRegistry)).ToList();
|
function.Arguments = arguments;
|
}
|
|
return operation;
|
}
|
}
|
}
|
}
|