package ec.app.semanticGP.func.numeric;

import ec.gp.semantic.DoubleSemantics;
import ec.gp.semantic.ISemantics;
import ec.gp.semantic.func.BinaryNode;

public final class Div extends BinaryNode<Double> {

	private static final String DIV = "/";

	@Override
	public String toString() {
		return DIV;
	}

	@Override
	public boolean isSymmetric() {
		return false;
	}

	@Override
	protected ISemantics execute(ISemantics... arguments) {
		double[] arg0 = (double[]) arguments[0].getValue();
		double[] arg1 = (double[]) arguments[1].getValue();
		double[] semantics = new double[arg0.length];

		for (int i = 0; i < semantics.length; ++i) {
			if (arg1[i] != 0.0 && !Double.isInfinite(arg1[i]) && !Double.isNaN(arg1[i]))
				semantics[i] = arg0[i] / arg1[i];
		}

		return new DoubleSemantics(semantics);
	}

	@Override
	public Double[] invert(Double output, int missingArgIdx, Double... restOfArguments) {
		switch (missingArgIdx) {
			case 0:
				if (!Double.isInfinite(restOfArguments[0]))
					return new Double[]{output * restOfArguments[0]};
				else if (output == 0.0)
					return Inversions.DONT_CARE; // don't care
				else
					return Inversions.INCONSISTENT; // inconsistent
			case 1:
			default:
				if (restOfArguments[0] != 0.0)
					return new Double[]{restOfArguments[0] / output};
				else if (output == 0.0)
					return Inversions.DONT_CARE; // don't care
				else
					return Inversions.INCONSISTENT; // inconsistent
		}
	}
}
