//=============================================================================
// Copyright 2006-2010 Daniel W. Dyer
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//=============================================================================
package org.uncommons.watchmaker.examples.geneticprogramming;
/**
* Simple addition operator {@link Node}.
* @author Daniel Dyer
*/
public class Addition extends BinaryNode
{
/**
* Creates a node that evaluates to the sum of the values of its two
* child nodes ({@literal left} and {@literal right}).
* @param left The first operand.
* @param right The second operand.
*/
public Addition(Node left, Node right)
{
super(left, right, '+');
}
/**
* Evaluates the two sub-trees and returns the sum of these two values.
* @param programParameters Program parameters (ignored by the addition operator
* but may be used in evaluating the sub-trees).
* @return The sum of the values of both child nodes.
*/
public double evaluate(double[] programParameters)
{
return left.evaluate(programParameters) + right.evaluate(programParameters);
}
/**
* {@inheritDoc}
*/
public Node simplify()
{
Node simplifiedLeft = left.simplify();
Node simplifiedRight = right.simplify();
// Adding zero is pointless, the expression can be reduced to its other argument.
if (simplifiedRight instanceof Constant && simplifiedRight.evaluate(NO_ARGS) == 0)
{
return simplifiedLeft;
}
else if (simplifiedLeft instanceof Constant && simplifiedLeft.evaluate(NO_ARGS) == 0)
{
return simplifiedRight;
}
// If the two arguments are constants, we can simplify by calculating the result, it won't
// ever change.
else if (simplifiedLeft instanceof Constant && simplifiedRight instanceof Constant)
{
return new Constant(simplifiedLeft.evaluate(NO_ARGS) + simplifiedRight.evaluate(NO_ARGS));
}
else if (simplifiedLeft != left || simplifiedRight != right)
{
return new Addition(simplifiedLeft, simplifiedRight);
}
else
{
return this;
}
}
}