package ec.gp.syntactic.simplification.numeric;

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

class SumSumSameRule 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 this.version(subtree) != -1;
	}

	private int version(GPNode subtree) {
		for (int i = 0; i < 2; ++i) {
			if (!(subtree.children[i] instanceof Sum))
				continue;

			GPNode p1 = subtree.children[i].children[0];
			GPNode p2 = subtree.children[i].children[1];
			GPNode p3 = subtree.children[1 - i];

			if (p1.rootedTreeEquals(p2) && p1.rootedTreeEquals(p3))
				return i;
		}

		return -1;
	}

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

		int v = this.version(subtree);
		if (v == -1)
			throw new UnsupportedOperationException("The given tree is not (p + p) + p");

		Constant c = new Constant(3.0);
		Mul mul = new Mul();
		mul.children = new GPNode[] { c, subtree.children[1 - v] };

		return mul;
	}

}
