package de.gaalop.dfg; /** * This class contains factory methods for additional convenience. */ public final class ExpressionFactory { private ExpressionFactory() { } /** * This class is the base class for creators of binary operations. This class uses the template method/factory * method pattern to decide which operation should be created. * * @param <T> The created type. */ private static abstract class BinaryCreator<T extends BinaryOperation> { protected abstract T create(Expression left, Expression right); /** * Creates a tree of concatenated binary expressions that operate on the given array of operands. * * @param operands The operations to operate on. * @return The root expression of the created expression tree. */ public T createBinary(Expression... operands) { if (operands.length < 2) { throw new IllegalArgumentException("At least two arguments are required."); } int i = operands.length - 2; Expression lastOperand = operands[operands.length - 1]; T result; do { lastOperand = result = create(operands[i], lastOperand); } while (--i >= 0); return result; } } /** * This is a class that creates Addition nodes. */ private static final class AdditionCreator extends BinaryCreator<Addition> { @Override protected Addition create(Expression left, Expression right) { return new Addition(left, right); } } /** * Constructs an expression tree that models the sum of all given operands. * * @param operands The operands for the sum. A deep copy of each expression will be created. At least two operands * are required. * @return A new Addition expression that represents the sum of the operands. */ public static Addition sum(Expression... operands) { return new AdditionCreator().createBinary(operands); } /** * This is a class that creates Subtraction nodes. */ private static final class SubtractionCreator extends BinaryCreator<Subtraction> { @Override protected Subtraction create(Expression left, Expression right) { return new Subtraction(left, right); } } /** * Constructs an expression tree that models the subtraction of all given operands. * * @param operands The operands for the subtraction. A deep copy of each expression will be created. At least two * operands are required. * @return A new Addition expression that represents the subtraction of the operands. */ public static Subtraction subtract(Expression... operands) { return new SubtractionCreator().createBinary(operands); } /** * This is a creator class for multiplication expressions. */ private static final class MultiplicationCreator extends BinaryCreator<Multiplication> { @Override protected Multiplication create(Expression left, Expression right) { return new Multiplication(left, right); } } /** * Constructs an expression that represents the multiplication of all given factors. * * @param factors The factors of the product. At least two have to be present. A deep copy of each operand is * created. * @return A Multiplication object that represents the product of all factors. */ public static Multiplication product(Expression... factors) { return new MultiplicationCreator().createBinary(factors); } /** * This is a creator class for division expressions. */ private static final class DivisionCreator extends BinaryCreator<Division> { @Override protected Division create(Expression left, Expression right) { return new Division(left, right); } } /** * Constructs an expression that represents the division of all given factors. * * @param factors The factors of the product. At least two have to be present. A deep copy of each operand is * created. * @return A Division object that represents the division of all factors. */ public static Division divide(Expression... factors) { return new DivisionCreator().createBinary(factors); } /** * An creator for outer products. */ private static final class OuterProductCreator extends BinaryCreator<OuterProduct> { @Override public OuterProduct create(Expression left, Expression right) { return new OuterProduct(left, right); } } /** * Constructs an expression that represents the outer product of all given factors in the order they are given. * * @param factors The factors of the resulting outer product. At least two have to be present. A deep copy of each * is created. * @return An OuterProduct object representing the outer product of all given factors. */ public static OuterProduct wedge(Expression... factors) { return new OuterProductCreator().createBinary(factors); } /** * Creates an exponentation node that squares the given expression. * * @param base The expression that should be squared. A deep copy will be created. * @return An exponentation object that exponentiates the given base with a float constant of 2.0. */ public static Multiplication square(Expression base) { return new Multiplication(base, base.copy()); } /** * Creates an expression node that negates the given expression. * * @param value The expression that should be negated. A deep copy will be created. * @return A Negation object that negates the given expression. */ public static Negation negate(Expression value) { return new Negation(value.copy()); } /** * A creator for logical and statements. */ private static final class LogicalAndCreator extends BinaryCreator<LogicalAnd> { @Override protected LogicalAnd create(Expression left, Expression right) { return new LogicalAnd(left, right); } } /** * Constructs an expression that represents the logical and of all given elements in the order they are given. * * @param booleanValues The values of the resulting conjunction. At least two have to be present. A deep copy of * each is created. * @return A LogicalAnd object representing the conjunction of all given boolean values. */ public static LogicalAnd and(Expression... booleanValues) { return new LogicalAndCreator().createBinary(booleanValues); } /** * Creates a negated version of the given logical expression. * * @param expression logical expression to be negated * @return negated logical expression */ public static LogicalNegation logicalNegation(Expression expression) { return new LogicalNegation(expression); } }