package ec.gp.syntactic.simplification.numeric;

import ec.EvolutionState;
import ec.app.semanticGP.func.IConstant;
import ec.app.semanticGP.func.numeric.Cos;
import ec.app.semanticGP.func.numeric.Mul;
import ec.app.semanticGP.func.numeric.Sin;
import ec.app.semanticGP.func.numeric.Sub;
import ec.gp.GPNode;
import ec.gp.syntactic.simplification.IRule;
import ec.util.Parameter;

class OneSinSqRule implements IRule {

	@Override
	public void setup(EvolutionState state, Parameter base) {
		// TODO Auto-generated method stub

	}

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

		if (!(subtree.children[0] instanceof IConstant && ((IConstant<Double>) subtree.children[0]).getConstant() == 1.0))
			return false;

		if (!(subtree.children[1] instanceof Mul))
			return false;

		if (!(subtree.children[1].children[0] instanceof Sin && subtree.children[1].children[1] instanceof Sin))
			return false;

		return subtree.children[1].children[0].children[0]
				.rootedTreeEquals(subtree.children[1].children[1].children[0]);
	}

	@Override
	public GPNode replace(GPNode subtree) {
		assert match(subtree) : "The given tree is not of form 1-sin^2(p)";

		Cos cos1 = new Cos();
		cos1.children = new GPNode[] { subtree.children[1].children[0].children[0] };

		Cos cos2 = new Cos();
		cos2.children = new GPNode[] { subtree.children[1].children[1].children[0] };

		Mul mul = new Mul();
		mul.children = new GPNode[] { cos1, cos2 };

		return mul;
	}

}
