package ec.gp.syntactic.simplification.numeric;

import ec.EvolutionState;
import ec.app.semanticGP.func.IConstant;
import ec.app.semanticGP.func.numeric.Constant;
import ec.app.semanticGP.func.numeric.Sub;
import ec.app.semanticGP.func.numeric.Sum;
import ec.gp.GPNode;
import ec.gp.syntactic.simplification.IRule;
import ec.util.Parameter;

class SumNegativeRule implements IRule {

	private EvolutionState state;

	@Override
	public void setup(EvolutionState state, Parameter base) {
		this.state = state;
	}

	@Override
	public boolean match(GPNode subtree) {
		if (!(subtree instanceof Sum))
			return false;

		return (subtree.children[0] instanceof IConstant && ((IConstant<Double>) subtree.children[0]).getConstant() < 0.0)
				||
				(subtree.children[1] instanceof IConstant && ((IConstant<Double>) subtree.children[1]).getConstant() < 0.0);
	}

	@Override
	public GPNode replace(GPNode subtree) {
		assert subtree instanceof Sum : "The given tree is not a sum.";

		if (subtree.children[0] instanceof IConstant && ((IConstant<Double>) subtree.children[0]).getConstant() < 0.0) {
			Constant _const = new Constant(-((IConstant<Double>) subtree.children[0]).getConstant());
			Sub sub = new Sub();
			sub.children = new GPNode[] { subtree.children[1], _const };
			return sub;
		} else if (subtree.children[1] instanceof IConstant
				&& ((IConstant<Double>) subtree.children[1]).getConstant() < 0.0) {
			Constant _const = new Constant(-((IConstant<Double>) subtree.children[1]).getConstant());
			Sub sub = new Sub();
			sub.children = new GPNode[] { subtree.children[0], _const };
			return sub;
		}

		throw new UnsupportedOperationException("The given tree is not a sum of negative value and other subtree.");
	}

}
