/* * Copyright 2015 S. Webber * * 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.oakgp.function.math; import static org.oakgp.Type.integerType; import java.math.BigDecimal; import java.math.BigInteger; import org.oakgp.function.AbstractFunctionTest; import org.oakgp.function.Function; public class SubtractTest extends AbstractFunctionTest { @Override protected Subtract getFunction() { return IntegerUtils.INTEGER_UTILS.getSubtract(); } @Override public void testEvaluate() { // integer evaluate("(- 3 21)").to(-18); // long evaluate("(- 3L 21L)").to(-18L); // big integer evaluate("(- 3I 21I)").to(BigInteger.valueOf(-18)); // double evaluate("(- 3.0 21.0)").to(-18d); // big decimal evaluate("(- 3D 21D)").to(BigDecimal.valueOf(-18)); } @Override public void testCanSimplify() { Object[][] assignedValues = { { 0, 0 }, { 0, 1 }, { 1, 0 }, { 1, 21 }, { 2, 14 }, { 3, -6 }, { 7, 3 }, { -1, 9 }, { -7, 0 } }; // constants get simplified to the result of subtracting the second from the first simplify("(- 8 3)").to("5").verifyAll(assignedValues); // anything minus zero is itself simplify("(- v0 0)").to("v0").verifyAll(assignedValues); // anything minus itself is zero simplify("(- v0 v0)").to("0").verifyAll(assignedValues); // simplify "zero minus ?" expressions simplify("(- 0 (- v0 v1))").to("(- v1 v0)").verifyAll(assignedValues); // convert double negatives to addition simplify("(- v0 -7)").to("(+ 7 v0)").verifyAll(assignedValues); // test when second argument is an addition expression simplify("(- 1 (+ 1 v0))").to("(- 0 v0)").verifyAll(assignedValues); simplify("(- 6 (+ 4 v0))").to("(- 2 v0)").verifyAll(assignedValues); // test when second argument is a subtraction expression simplify("(- 1 (- 7 v0))").to("(- v0 6)").verifyAll(assignedValues); simplify("(- 1 (- 1 v0))").to("v0").verifyAll(assignedValues); simplify("(- 6 (- 4 v0))").to("(+ 2 v0)").verifyAll(assignedValues); simplify("(- 1 (- 0 v0))").to("(+ 1 v0)").verifyAll(assignedValues); // test when second argument is a multiplication expression simplify("(- 0 (* -3 v0))").to("(* 3 v0)").verifyAll(assignedValues); simplify("(- 7 (* -3 v0))").to("(+ 7 (* 3 v0))").verifyAll(assignedValues); // (1 + x) - (2 + y) evaluates to -1+x-y simplify("(- (+ 1 v0) (+ 2 v1))").to("(- v0 (+ 1 v1))").verifyAll(assignedValues); simplify("(- (+ 1 v0) (+ 2 v0))").to("-1").verifyAll(assignedValues); // (1 + x) - (12 - y) evaluates to -11+x+y simplify("(- (+ 1 v0) (- 12 v1))").to("(- v0 (- 11 v1))").verifyAll(assignedValues); simplify("(- (+ 1 v0) (- 12 v0))").to("(- (* 2 v0) 11)").verifyAll(assignedValues); simplify("(- (+ 1 v0) v0)").to("1").verifyAll(assignedValues); simplify("(- (- (- (* 2 v0) 9) v1) v1)").to("(- (- (* 2 v0) 9) (* 2 v1))").verifyAll(assignedValues); simplify("(- (- (+ (* 2 v0) 9) v1) v1)").to("(- (+ 9 (* 2 v0)) (* 2 v1))").verifyAll(assignedValues); simplify("(- (- (- (* 2 v0) 9) v1) v1)").to("(- (- (* 2 v0) 9) (* 2 v1))").verifyAll(assignedValues); simplify("(- 5 (- (- (+ (* 2 v0) (* 2 v1)) 1) (- v0 2)))").to("(- 4 (+ v0 (* 2 v1)))").verifyAll(assignedValues); simplify("(- (* 2 v0) (- v1 v0))").to("(- (* 3 v0) v1)").verifyAll(assignedValues); simplify("(- (* -2 v0) (- v1 v0))").to("(- (* -1 v0) v1)").verifyAll(assignedValues); // (- (- 5 (- (- (+ (* 2 v0) (* 2 v1)) 1) (- v1 2))) (* 2 v1)) = // (5-((((2*y)+(2*x))-1)-(x-2)))-(2 * x) = // -3x+4-2y simplify("(- (- 5 (- (- (+ (* 2 v0) (* 2 v1)) 1) (- v1 2))) (* 2 v1))").to("(- (- 4 (* 2 v0)) (* 3 v1))").verifyAll(assignedValues); simplify("(- (+ 9 (- v0 (+ 9 v1))) (- 8 v1))").to("(- v0 8)").verifyAll(assignedValues); simplify("(- (+ 9 (- v0 (+ 9 v1))) (- v1 v0))").to("(- (* 2 v0) (* 2 v1))").verifyAll(assignedValues); // (- v0 (- v1 (+ (* 2 v0) (* -2 v1)))) = x-(y-((2*x)+(-2*y))) = 3x-3y = (+ (* 3 v0) (* -3 v1)) simplify("(- v0 (- v1 (+ (* 2 v0) (* -2 v1))))").to("(+ (* 3 v0) (* -3 v1))").verifyAll(assignedValues); simplify("(- v1 (- (* 2 v0) v1))").to("(- (* 2 v1) (* 2 v0))").verifyAll(assignedValues); simplify("(- v1 (- 4 (+ v1 (* 2 v0))))").to("(- (+ (* 2 v1) (* 2 v0)) 4)").verifyAll(assignedValues); simplify("(- (+ 9 (- v0 (+ 9 v1))) (- 8 v1))").to("(- v0 8)").verifyAll(assignedValues); simplify("(- (+ 9 (- v0 (+ 9 v1))) (- v1 v0))").to("(- (* 2 v0) (* 2 v1))").verifyAll(assignedValues); simplify("(- (- v0 v1) (- v1 v0))").to("(- (* 2 v0) (* 2 v1))").verifyAll(assignedValues); simplify("(- 0 (* 2 v0))").to("(* -2 v0)").verifyAll(assignedValues); simplify("(- 0 (* -162 v0))").to("(* 162 v0)").verifyAll(assignedValues); // TODO "(- (- 0 v2) (- -3 v0))" is simplified to "(- (- 3 v2) (- 0 v0))" and "(- (- 3 v2) (- 0 v0))" is simplified to "(- (- 0 v2) (- -3 v0))" // - resolve this behaviour so results are consistent and stable // simplify("(- (- 0 v2) (- -3 v0))").to("(- (- 3 v2) (- 0 v0))"); // simplify("(- (- 3 v2) (- 0 v0))").to("(- (- 0 v2) (- -3 v0))"); } @Override public void testCannotSimplify() { cannotSimplify("(- v0 1)", integerType()); cannotSimplify("(- 0 v0)", integerType()); } @Override protected Function[] getFunctionSet() { return new Function[] { getFunction(), IntegerUtils.INTEGER_UTILS.getAdd(), IntegerUtils.INTEGER_UTILS.getMultiply(), LongUtils.LONG_UTILS.getSubtract(), DoubleUtils.DOUBLE_UTILS.getSubtract(), BigIntegerUtils.BIG_INTEGER_UTILS.getSubtract(), BigDecimalUtils.BIG_DECIMAL_UTILS.getSubtract() }; } }