package de.gaalop.api.dfg;
import de.gaalop.dfg.Addition;
import de.gaalop.dfg.BaseVector;
import de.gaalop.dfg.Division;
import de.gaalop.dfg.Equality;
import de.gaalop.dfg.Exponentiation;
import de.gaalop.dfg.Expression;
import de.gaalop.dfg.ExpressionVisitor;
import de.gaalop.dfg.FloatConstant;
import de.gaalop.dfg.FunctionArgument;
import de.gaalop.dfg.Inequality;
import de.gaalop.dfg.InnerProduct;
import de.gaalop.dfg.LogicalAnd;
import de.gaalop.dfg.LogicalNegation;
import de.gaalop.dfg.LogicalOr;
import de.gaalop.dfg.MacroCall;
import de.gaalop.dfg.MathFunctionCall;
import de.gaalop.dfg.Multiplication;
import de.gaalop.dfg.MultivectorComponent;
import de.gaalop.dfg.Negation;
import de.gaalop.dfg.OuterProduct;
import de.gaalop.dfg.Relation;
import de.gaalop.dfg.Reverse;
import de.gaalop.dfg.Subtraction;
import de.gaalop.dfg.Variable;
/**
* Implements an expression visitor, which rounds float constants
* @author Christian Steinmetz
*/
public class RoundingDFGVisitor implements ExpressionVisitor {
private Expression result;
private int numberOfDigits;
/**
* Facade method for rounding float constants in this expression tree.
* @param expressionToRound The expression to be rounded
* @param numberOfDigits The number of significant digits to round to
* @return The rounded expression
*/
public static Expression round(Expression expressionToRound, int numberOfDigits) {
RoundingDFGVisitor visitor = new RoundingDFGVisitor(numberOfDigits);
if (expressionToRound != null)
expressionToRound.accept(visitor);
if (visitor.result != null)
return visitor.result;
else
return expressionToRound;
}
public RoundingDFGVisitor(int numberOfDigits) {
result = null;
this.numberOfDigits = numberOfDigits;
}
@Override
public void visit(Subtraction node) {
result = null;
node.getLeft().accept(this);
Expression leftResult = result;
node.getRight().accept(this);
Expression rightResult = result;
if (leftResult != null || rightResult != null)
result = new Subtraction(leftResult, rightResult);
}
@Override
public void visit(Addition node) {
result = null;
node.getLeft().accept(this);
Expression leftResult = result;
node.getRight().accept(this);
Expression rightResult = result;
if (leftResult != null || rightResult != null)
result = new Addition(leftResult, rightResult);
}
@Override
public void visit(Division node) {
result = null;
node.getLeft().accept(this);
Expression leftResult = result;
node.getRight().accept(this);
Expression rightResult = result;
if (leftResult != null || rightResult != null)
result = new Division(leftResult, rightResult);
}
@Override
public void visit(InnerProduct node) {
result = null;
node.getLeft().accept(this);
Expression leftResult = result;
node.getRight().accept(this);
Expression rightResult = result;
if (leftResult != null || rightResult != null)
result = new InnerProduct(leftResult, rightResult);
}
@Override
public void visit(Multiplication node) {
result = null;
node.getLeft().accept(this);
Expression leftResult = result;
node.getRight().accept(this);
Expression rightResult = result;
if (leftResult != null || rightResult != null)
result = new Multiplication(leftResult, rightResult);
}
@Override
public void visit(MathFunctionCall node) {
result = null;
node.getOperand().accept(this);
if (result != null)
result = new MathFunctionCall(result, node.getFunction());
}
@Override
public void visit(Variable node) {
result = null;
}
@Override
public void visit(MultivectorComponent node) {
result = null;
}
@Override
public void visit(Exponentiation node) {
result = null;
node.getLeft().accept(this);
Expression leftResult = result;
node.getRight().accept(this);
Expression rightResult = result;
if (leftResult != null || rightResult != null)
result = new Exponentiation(leftResult, rightResult);
}
@Override
public void visit(FloatConstant node) {
result = null;
double multiplicator = Math.pow(10, numberOfDigits);
result = new FloatConstant(Math.round(node.getValue() * multiplicator) / multiplicator);
}
@Override
public void visit(OuterProduct node) {
result = null;
node.getLeft().accept(this);
Expression leftResult = result;
node.getRight().accept(this);
Expression rightResult = result;
if (leftResult != null || rightResult != null)
result = new OuterProduct(leftResult, rightResult);
}
@Override
public void visit(BaseVector node) {
result = null;
}
@Override
public void visit(Negation node) {
result = null;
node.getOperand().accept(this);
if (result != null)
result = new Negation(result);
}
@Override
public void visit(Reverse node) {
result = null;
node.getOperand().accept(this);
if (result != null)
result = new Reverse(result);
}
@Override
public void visit(LogicalOr node) {
result = null;
node.getLeft().accept(this);
Expression leftResult = result;
node.getRight().accept(this);
Expression rightResult = result;
if (leftResult != null || rightResult != null)
result = new LogicalOr(leftResult, rightResult);
}
@Override
public void visit(LogicalAnd node) {
result = null;
node.getLeft().accept(this);
Expression leftResult = result;
node.getRight().accept(this);
Expression rightResult = result;
if (leftResult != null || rightResult != null)
result = new LogicalAnd(leftResult, rightResult);
}
@Override
public void visit(LogicalNegation node) {
result = null;
node.getOperand().accept(this);
if (result != null)
result = new LogicalNegation(result);
}
@Override
public void visit(Equality node) {
result = null;
node.getLeft().accept(this);
Expression leftResult = result;
node.getRight().accept(this);
Expression rightResult = result;
if (leftResult != null || rightResult != null)
result = new Equality(leftResult, rightResult);
}
@Override
public void visit(Inequality node) {
result = null;
node.getLeft().accept(this);
Expression leftResult = result;
node.getRight().accept(this);
Expression rightResult = result;
if (leftResult != null || rightResult != null)
result = new Inequality(leftResult, rightResult);
}
@Override
public void visit(Relation relation) {
result = null;
relation.getLeft().accept(this);
Expression leftResult = result;
relation.getRight().accept(this);
Expression rightResult = result;
if (leftResult != null || rightResult != null)
result = new Relation(leftResult, rightResult, relation.getType());
}
@Override
public void visit(FunctionArgument node) {
result = null;
}
@Override
public void visit(MacroCall node) {
result = null;
}
}