/****************************************************************************** * * Copyright 2014 Paphus Solutions Inc. * * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/legal/epl-v10.html * * 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.botlibre.tool; import java.math.BigDecimal; import java.math.BigInteger; import org.botlibre.api.knowledge.Vertex; import org.botlibre.knowledge.Primitive; import org.botlibre.sense.BasicTool; /** * Does math. */ public class Calculator extends BasicTool { public Calculator() { } public Vertex plus(Vertex source, Vertex left, Vertex right) { return add(source, left, right); } public Vertex minus(Vertex source, Vertex left, Vertex right) { return subtract(source, left, right); } public Vertex add(Vertex source, Vertex left, Vertex right) { Object result = null; if ((left.getData() instanceof BigInteger) && (right.getData() instanceof BigInteger)) { BigInteger leftNumber = (BigInteger)left.getData(); BigInteger rightNumber = (BigInteger)right.getData(); result = leftNumber.add(rightNumber); } else if ((left.getData() instanceof BigDecimal) || (right.getData() instanceof BigDecimal)) { BigDecimal leftNumber = null; BigDecimal rightNumber = null; if (left.getData() instanceof BigInteger) { leftNumber = new BigDecimal((BigInteger)left.getData()); } else if (left.getData() instanceof BigDecimal) { leftNumber = (BigDecimal)left.getData(); } if (right.getData() instanceof BigInteger) { rightNumber = new BigDecimal((BigInteger)right.getData()); } else if (right.getData() instanceof BigDecimal) { rightNumber = (BigDecimal)right.getData(); } if ((rightNumber != null) && (leftNumber != null)) { result = leftNumber.add(rightNumber); } } if (left.is(Primitive.UNDEFINED)) { return left; } if (right.is(Primitive.UNDEFINED)) { return right; } if (left.is(Primitive.INFINITY) || left.is(Primitive.NINFINITY)) { return left; } if (right.is(Primitive.INFINITY) || left.is(Primitive.NINFINITY)) { return right; } return left.getNetwork().createVertex(checkInteger(result)); } public Vertex subtract(Vertex source, Vertex left, Vertex right) { Object result = null; if ((left.getData() instanceof BigInteger) && (right.getData() instanceof BigInteger)) { BigInteger leftNumber = (BigInteger)left.getData(); BigInteger rightNumber = (BigInteger)right.getData(); result = leftNumber.subtract(rightNumber); } else if ((left.getData() instanceof BigDecimal) || (right.getData() instanceof BigDecimal)) { BigDecimal leftNumber = null; BigDecimal rightNumber = null; if (left.getData() instanceof BigInteger) { leftNumber = new BigDecimal((BigInteger)left.getData()); } else if (left.getData() instanceof BigDecimal) { leftNumber = (BigDecimal)left.getData(); } if (right.getData() instanceof BigInteger) { rightNumber = new BigDecimal((BigInteger)right.getData()); } else if (right.getData() instanceof BigDecimal) { rightNumber = (BigDecimal)right.getData(); } if ((rightNumber != null) && (leftNumber != null)) { result = leftNumber.subtract(rightNumber); } } if (left.is(Primitive.UNDEFINED)) { return left; } if (right.is(Primitive.UNDEFINED)) { return right; } if (left.is(Primitive.INFINITY) || left.is(Primitive.NINFINITY)) { return left; } if (right.is(Primitive.INFINITY)) { return left.getNetwork().createVertex(Primitive.NINFINITY); } if (right.is(Primitive.NINFINITY)) { return left.getNetwork().createVertex(Primitive.INFINITY); } return left.getNetwork().createVertex(checkInteger(result)); } public Vertex multiply(Vertex source, Vertex left, Vertex right) { Object result = null; if ((left.getData() instanceof BigInteger) && (right.getData() instanceof BigInteger)) { BigInteger leftNumber = (BigInteger)left.getData(); BigInteger rightNumber = (BigInteger)right.getData(); result = leftNumber.multiply(rightNumber); } else if ((left.getData() instanceof BigDecimal) || (right.getData() instanceof BigDecimal)) { BigDecimal leftNumber = null; BigDecimal rightNumber = null; if (left.getData() instanceof BigInteger) { leftNumber = new BigDecimal((BigInteger)left.getData()); } else if (left.getData() instanceof BigDecimal) { leftNumber = (BigDecimal)left.getData(); } if (right.getData() instanceof BigInteger) { rightNumber = new BigDecimal((BigInteger)right.getData()); } else if (right.getData() instanceof BigDecimal) { rightNumber = (BigDecimal)right.getData(); } if ((rightNumber != null) && (leftNumber != null)) { result = leftNumber.multiply(rightNumber); } } if (left.is(Primitive.UNDEFINED)) { return left; } if (right.is(Primitive.UNDEFINED)) { return right; } if (left.is(Primitive.INFINITY) || left.is(Primitive.NINFINITY)) { return left; } if (right.is(Primitive.INFINITY) || left.is(Primitive.NINFINITY)) { return right; } return left.getNetwork().createVertex(checkInteger(result)); } public Vertex divide(Vertex source, Vertex left, Vertex right) { Object result = null; if ((left.getData() instanceof BigInteger) && (right.getData() instanceof BigInteger)) { BigInteger leftNumber = (BigInteger)left.getData(); BigInteger rightNumber = (BigInteger)right.getData(); if (rightNumber.signum() == 0) { if (leftNumber.signum() == 0) { return left.getNetwork().createVertex(Primitive.UNDEFINED); } else if (leftNumber.signum() < 0) { return left.getNetwork().createVertex(Primitive.NINFINITY); } return left.getNetwork().createVertex(Primitive.INFINITY); } try { BigInteger[] remainder = leftNumber.divideAndRemainder(rightNumber); if (remainder[1].signum() == 0) { result = remainder[0]; } } catch (Exception failedAgain) { return left.getNetwork().createVertex(Primitive.INFINITY); } } if (left.is(Primitive.UNDEFINED)) { return left; } if (right.is(Primitive.UNDEFINED)) { return right; } if (left.is(Primitive.INFINITY) || left.is(Primitive.NINFINITY)) { return left; } if (right.is(Primitive.INFINITY) || right.is(Primitive.NINFINITY)) { return left.getNetwork().createVertex(BigInteger.valueOf(0)); } if (result == null) { BigDecimal leftNumber = null; BigDecimal rightNumber = null; if (left.getData() instanceof BigInteger) { leftNumber = new BigDecimal((BigInteger)left.getData()); } else if (left.getData() instanceof BigDecimal) { leftNumber = (BigDecimal)left.getData(); } if (right.getData() instanceof BigInteger) { rightNumber = new BigDecimal((BigInteger)right.getData()); } else if (right.getData() instanceof BigDecimal) { rightNumber = (BigDecimal)right.getData(); } if ((rightNumber != null) && (leftNumber != null)) { if (rightNumber.signum() == 0) { if (leftNumber.signum() == 0) { return left.getNetwork().createVertex(Primitive.UNDEFINED); } else if (leftNumber.signum() < 0) { return left.getNetwork().createVertex(Primitive.NINFINITY); } return left.getNetwork().createVertex(Primitive.INFINITY); } try { result = leftNumber.divide(rightNumber); } catch (Exception failed) { try { result = leftNumber.divide(rightNumber, 10, BigDecimal.ROUND_UP); } catch (Exception failedAgain) { return left.getNetwork().createVertex(Primitive.INFINITY); } } } } return left.getNetwork().createVertex(checkInteger(result)); } public Vertex power(Vertex source, Vertex left, Vertex right) { if ((left.getData() instanceof Number) && (right.getData() instanceof Number)) { try { double result = java.lang.Math.pow(((Number)left.getData()).doubleValue(), ((Number)right.getData()).doubleValue()); if (Double.isInfinite(result)) { return left.getNetwork().createVertex(Primitive.INFINITY); } BigDecimal decimal = BigDecimal.valueOf(result); return left.getNetwork().createVertex(checkInteger(decimal)); } catch (Exception failed) { return left.getNetwork().createVertex(Primitive.UNDEFINED); } } if (left.is(Primitive.UNDEFINED)) { return left; } if (left.is(Primitive.INFINITY) || left.is(Primitive.NINFINITY)) { return left; } if (right.is(Primitive.INFINITY) || right.is(Primitive.NINFINITY)) { return right; } return left.getNetwork().createVertex(Primitive.NULL); } public Vertex sqrt(Vertex source, Vertex left) { if ((left.getData() instanceof Number)) { try { double result = java.lang.Math.sqrt((((Number)left.getData()).doubleValue())); if (Double.isInfinite(result)) { return left.getNetwork().createVertex(Primitive.INFINITY); } BigDecimal decimal = BigDecimal.valueOf(result); return left.getNetwork().createVertex(checkInteger(decimal)); } catch (Exception failed) { return left.getNetwork().createVertex(Primitive.UNDEFINED); } } if (left.is(Primitive.UNDEFINED)) { return left; } if (left.is(Primitive.INFINITY) || left.is(Primitive.NINFINITY)) { return left; } return left.getNetwork().createVertex(Primitive.NULL); } public Vertex ln(Vertex source, Vertex left) { if ((left.getData() instanceof Number)) { try { double result = java.lang.Math.log((((Number)left.getData()).doubleValue())); if (Double.isInfinite(result)) { return left.getNetwork().createVertex(Primitive.INFINITY); } BigDecimal decimal = BigDecimal.valueOf(result); return left.getNetwork().createVertex(checkInteger(decimal)); } catch (Exception failed) { return left.getNetwork().createVertex(Primitive.UNDEFINED); } } if (left.is(Primitive.UNDEFINED)) { return left; } if (left.is(Primitive.INFINITY) || left.is(Primitive.NINFINITY)) { return left.getNetwork().createVertex(Primitive.INFINITY); } return left.getNetwork().createVertex(Primitive.NULL); } public Vertex log(Vertex source, Vertex left) { if ((left.getData() instanceof Number)) { try { double result = java.lang.Math.log10((((Number)left.getData()).doubleValue())); if (Double.isInfinite(result)) { return left.getNetwork().createVertex(Primitive.INFINITY); } BigDecimal decimal = BigDecimal.valueOf(result); return left.getNetwork().createVertex(checkInteger(decimal)); } catch (Exception failed) { return left.getNetwork().createVertex(Primitive.UNDEFINED); } } if (left.is(Primitive.UNDEFINED)) { return left; } if (left.is(Primitive.INFINITY) || left.is(Primitive.NINFINITY)) { return left.getNetwork().createVertex(Primitive.INFINITY); } return left.getNetwork().createVertex(Primitive.NULL); } public Vertex round(Vertex source, Vertex left) { if ((left.getData() instanceof Number)) { try { double result = java.lang.Math.round((((Number)left.getData()).doubleValue())); if (Double.isInfinite(result)) { return left.getNetwork().createVertex(Primitive.INFINITY); } BigDecimal decimal = BigDecimal.valueOf(result); return left.getNetwork().createVertex(checkInteger(decimal)); } catch (Exception failed) { return left.getNetwork().createVertex(Primitive.UNDEFINED); } } if (left.is(Primitive.UNDEFINED)) { return left; } if (left.is(Primitive.INFINITY) || left.is(Primitive.NINFINITY)) { return left.getNetwork().createVertex(Primitive.INFINITY); } return left.getNetwork().createVertex(Primitive.NULL); } public Vertex floor(Vertex source, Vertex left) { if ((left.getData() instanceof Number)) { try { double result = java.lang.Math.floor((((Number)left.getData()).doubleValue())); if (Double.isInfinite(result)) { return left.getNetwork().createVertex(Primitive.INFINITY); } BigDecimal decimal = BigDecimal.valueOf(result); return left.getNetwork().createVertex(checkInteger(decimal)); } catch (Exception failed) { return left.getNetwork().createVertex(Primitive.UNDEFINED); } } if (left.is(Primitive.UNDEFINED)) { return left; } if (left.is(Primitive.INFINITY) || left.is(Primitive.NINFINITY)) { return left.getNetwork().createVertex(Primitive.INFINITY); } return left.getNetwork().createVertex(Primitive.NULL); } public Vertex ceil(Vertex source, Vertex left) { if ((left.getData() instanceof Number)) { try { double result = java.lang.Math.ceil((((Number)left.getData()).doubleValue())); if (Double.isInfinite(result)) { return left.getNetwork().createVertex(Primitive.INFINITY); } BigDecimal decimal = BigDecimal.valueOf(result); return left.getNetwork().createVertex(checkInteger(decimal)); } catch (Exception failed) { return left.getNetwork().createVertex(Primitive.UNDEFINED); } } if (left.is(Primitive.UNDEFINED)) { return left; } if (left.is(Primitive.INFINITY) || left.is(Primitive.NINFINITY)) { return left.getNetwork().createVertex(Primitive.INFINITY); } return left.getNetwork().createVertex(Primitive.NULL); } public Vertex abs(Vertex source, Vertex left) { if ((left.getData() instanceof Number)) { try { double result = java.lang.Math.abs((((Number)left.getData()).doubleValue())); if (Double.isInfinite(result)) { return left.getNetwork().createVertex(Primitive.INFINITY); } BigDecimal decimal = BigDecimal.valueOf(result); return left.getNetwork().createVertex(checkInteger(decimal)); } catch (Exception failed) { return left.getNetwork().createVertex(Primitive.UNDEFINED); } } if (left.is(Primitive.UNDEFINED)) { return left; } if (left.is(Primitive.INFINITY) || left.is(Primitive.NINFINITY)) { return left.getNetwork().createVertex(Primitive.INFINITY); } return left.getNetwork().createVertex(Primitive.NULL); } public Vertex sin(Vertex source, Vertex left) { if ((left.getData() instanceof Number)) { try { double result = java.lang.Math.sin((((Number)left.getData()).doubleValue())); if (Double.isInfinite(result)) { return left.getNetwork().createVertex(Primitive.INFINITY); } BigDecimal decimal = BigDecimal.valueOf(result); return left.getNetwork().createVertex(checkInteger(decimal)); } catch (Exception failed) { return left.getNetwork().createVertex(Primitive.UNDEFINED); } } if (left.is(Primitive.UNDEFINED)) { return left; } if (left.is(Primitive.INFINITY) || left.is(Primitive.NINFINITY)) { return left.getNetwork().createVertex(BigInteger.valueOf(0)); } return left.getNetwork().createVertex(Primitive.NULL); } public Vertex cos(Vertex source, Vertex left) { if ((left.getData() instanceof Number)) { try { double result = java.lang.Math.cos((((Number)left.getData()).doubleValue())); if (Double.isInfinite(result)) { return left.getNetwork().createVertex(Primitive.INFINITY); } BigDecimal decimal = BigDecimal.valueOf(result); return left.getNetwork().createVertex(checkInteger(decimal)); } catch (Exception failed) { return left.getNetwork().createVertex(Primitive.UNDEFINED); } } if (left.is(Primitive.UNDEFINED)) { return left; } if (left.is(Primitive.INFINITY) || left.is(Primitive.NINFINITY)) { return left.getNetwork().createVertex(Primitive.UNDEFINED); } return left.getNetwork().createVertex(Primitive.NULL); } public Vertex tan(Vertex source, Vertex left) { if ((left.getData() instanceof Number)) { try { double result = java.lang.Math.tan((((Number)left.getData()).doubleValue())); if (Double.isInfinite(result)) { return left.getNetwork().createVertex(Primitive.INFINITY); } BigDecimal decimal = BigDecimal.valueOf(result); return left.getNetwork().createVertex(checkInteger(decimal)); } catch (Exception failed) { return left.getNetwork().createVertex(Primitive.UNDEFINED); } } if (left.is(Primitive.UNDEFINED)) { return left; } if (left.is(Primitive.INFINITY) || left.is(Primitive.NINFINITY)) { return left.getNetwork().createVertex(Primitive.UNDEFINED); } return left.getNetwork().createVertex(Primitive.NULL); } public Vertex atan(Vertex source, Vertex left) { if ((left.getData() instanceof Number)) { try { double result = java.lang.Math.atan((((Number)left.getData()).doubleValue())); if (Double.isInfinite(result)) { return left.getNetwork().createVertex(Primitive.INFINITY); } BigDecimal decimal = BigDecimal.valueOf(result); return left.getNetwork().createVertex(checkInteger(decimal)); } catch (Exception failed) { return left.getNetwork().createVertex(Primitive.UNDEFINED); } } if (left.is(Primitive.UNDEFINED)) { return left; } if (left.is(Primitive.INFINITY) || left.is(Primitive.NINFINITY)) { return left.getNetwork().createVertex(Primitive.UNDEFINED); } return left.getNetwork().createVertex(Primitive.NULL); } public Vertex asin(Vertex source, Vertex left) { if ((left.getData() instanceof Number)) { try { double result = java.lang.Math.asin((((Number)left.getData()).doubleValue())); if (Double.isInfinite(result)) { return left.getNetwork().createVertex(Primitive.INFINITY); } BigDecimal decimal = BigDecimal.valueOf(result); return left.getNetwork().createVertex(checkInteger(decimal)); } catch (Exception failed) { return left.getNetwork().createVertex(Primitive.UNDEFINED); } } if (left.is(Primitive.UNDEFINED)) { return left; } if (left.is(Primitive.INFINITY) || left.is(Primitive.NINFINITY)) { return left.getNetwork().createVertex(BigInteger.valueOf(0)); } return left.getNetwork().createVertex(Primitive.NULL); } public Vertex acos(Vertex source, Vertex left) { if ((left.getData() instanceof Number)) { try { double result = java.lang.Math.acos((((Number)left.getData()).doubleValue())); if (Double.isInfinite(result)) { return left.getNetwork().createVertex(Primitive.INFINITY); } BigDecimal decimal = BigDecimal.valueOf(result); return left.getNetwork().createVertex(checkInteger(decimal)); } catch (Exception failed) { return left.getNetwork().createVertex(Primitive.UNDEFINED); } } if (left.is(Primitive.UNDEFINED)) { return left; } if (left.is(Primitive.INFINITY) || left.is(Primitive.NINFINITY)) { return left.getNetwork().createVertex(Primitive.UNDEFINED); } return left.getNetwork().createVertex(Primitive.NULL); } public Vertex sinh(Vertex source, Vertex left) { if ((left.getData() instanceof Number)) { try { double result = java.lang.Math.sinh((((Number)left.getData()).doubleValue())); if (Double.isInfinite(result)) { return left.getNetwork().createVertex(Primitive.INFINITY); } BigDecimal decimal = BigDecimal.valueOf(result); return left.getNetwork().createVertex(checkInteger(decimal)); } catch (Exception failed) { return left.getNetwork().createVertex(Primitive.UNDEFINED); } } if (left.is(Primitive.UNDEFINED)) { return left; } if (left.is(Primitive.INFINITY) || left.is(Primitive.NINFINITY)) { return left.getNetwork().createVertex(BigInteger.valueOf(0)); } return left.getNetwork().createVertex(Primitive.NULL); } public Vertex cosh(Vertex source, Vertex left) { if ((left.getData() instanceof Number)) { try { double result = java.lang.Math.cosh((((Number)left.getData()).doubleValue())); if (Double.isInfinite(result)) { return left.getNetwork().createVertex(Primitive.INFINITY); } BigDecimal decimal = BigDecimal.valueOf(result); return left.getNetwork().createVertex(checkInteger(decimal)); } catch (Exception failed) { return left.getNetwork().createVertex(Primitive.UNDEFINED); } } if (left.is(Primitive.UNDEFINED)) { return left; } if (left.is(Primitive.INFINITY) || left.is(Primitive.NINFINITY)) { return left.getNetwork().createVertex(Primitive.UNDEFINED); } return left.getNetwork().createVertex(Primitive.NULL); } public Vertex tanh(Vertex source, Vertex left) { if ((left.getData() instanceof Number)) { try { double result = java.lang.Math.tanh((((Number)left.getData()).doubleValue())); if (Double.isInfinite(result)) { return left.getNetwork().createVertex(Primitive.INFINITY); } BigDecimal decimal = BigDecimal.valueOf(result); return left.getNetwork().createVertex(checkInteger(decimal)); } catch (Exception failed) { return left.getNetwork().createVertex(Primitive.UNDEFINED); } } if (left.is(Primitive.UNDEFINED)) { return left; } if (left.is(Primitive.INFINITY) || left.is(Primitive.NINFINITY)) { return left.getNetwork().createVertex(Primitive.UNDEFINED); } return left.getNetwork().createVertex(Primitive.NULL); } public Object checkInteger(Object result) { if (result == null) { return Primitive.NULL; } if (result instanceof BigDecimal) { BigDecimal decimal = (BigDecimal)result; decimal = decimal.stripTrailingZeros(); if (decimal.signum() == 0 || decimal.scale() <= 0) { result = decimal.toBigInteger(); } else { result = decimal; } } return result; } }