From 7c39f25fcfc49f9c46933c17fce490fca04fd85a Mon Sep 17 00:00:00 2001 From: axexlck Date: Mon, 24 Feb 2020 00:15:42 +0100 Subject: [PATCH] Fuzz tests: fix some bugs --- .../org/matheclipse/core/builtin/Algebra.java | 106 +++++++++---- .../core/builtin/BooleanFunctions.java | 75 +++++----- .../core/builtin/Combinatoric.java | 57 +++---- .../core/builtin/EllipticIntegrals.java | 5 + .../matheclipse/core/builtin/IOFunctions.java | 1 + .../core/builtin/LinearAlgebra.java | 19 ++- .../core/builtin/ListFunctions.java | 80 +++++++--- .../core/builtin/NumberTheory.java | 5 +- .../core/builtin/PatternMatching.java | 40 +++-- .../core/builtin/PolynomialFunctions.java | 36 +++-- .../matheclipse/core/builtin/PredicateQ.java | 3 + .../matheclipse/core/builtin/Programming.java | 8 +- .../core/builtin/RandomFunctions.java | 5 +- .../core/builtin/StatisticsFunctions.java | 13 +- .../matheclipse/core/builtin/Structure.java | 67 +++++---- .../core/builtin/TensorFunctions.java | 48 +++--- .../core/eval/exception/Validate.java | 26 ++++ .../matheclipse/core/eval/util/Iterator.java | 22 ++- .../core/eval/util/LevelSpecification.java | 46 +++--- .../core/form/mathml/MathMLFormFactory.java | 35 +++-- .../core/form/tex/TeXFormFactory.java | 32 ++-- .../core/numbertheory/Primality.java | 3 + .../core/reflection/system/Product.java | 140 +++++++++--------- .../core/reflection/system/Sum.java | 37 +++-- .../core/visit/VisitorLevelSpecification.java | 56 +++---- .../core/fuzz/ExprEvaluatorTests.java | 77 +++++----- .../core/system/LowercaseTestCase.java | 46 +++++- 27 files changed, 675 insertions(+), 413 deletions(-) diff --git a/symja_android_library/matheclipse-core/src/main/java/org/matheclipse/core/builtin/Algebra.java b/symja_android_library/matheclipse-core/src/main/java/org/matheclipse/core/builtin/Algebra.java index 584921ad60..0e7efe6786 100644 --- a/symja_android_library/matheclipse-core/src/main/java/org/matheclipse/core/builtin/Algebra.java +++ b/symja_android_library/matheclipse-core/src/main/java/org/matheclipse/core/builtin/Algebra.java @@ -2273,6 +2273,12 @@ public int[] expectedArgSize() { private static IExpr factorList(IExpr expr, List varList, boolean factorSquareFree) throws JASConversionException { + if (!expr.isAST()) { + if (expr.isNumber()) { + return F.List(F.List(expr, F.C1)); + } + return F.List(F.List(F.C1, F.C1), F.List(expr, F.C1)); + } JASConvert jas = new JASConvert(varList, BigRational.ZERO); GenPolynomial polyRat = jas.expr2JAS(expr, false); Object[] objects = jas.factorTerms(polyRat); @@ -3185,7 +3191,15 @@ private static class PolynomialQuotient extends PolynomialQuotientRemainder { public IExpr evaluate(final IAST ast, EvalEngine engine) { if (ast.size() == 4 || ast.size() == 5) { - IExpr variable = ast.arg3(); + IExpr variable; + if (ast.arg3().isAST()) { + variable = ast.arg3(); + } else { + variable = Validate.checkSymbolType(ast, 3, engine); + if (!variable.isPresent()) { + return F.NIL; + } + } IExpr arg1 = F.evalExpandAll(ast.arg1(), engine); IExpr arg2 = F.evalExpandAll(ast.arg2(), engine); @@ -3290,29 +3304,43 @@ public IExpr evaluate(final IAST ast, EvalEngine engine) { if (temp != null) { return temp; } - IExpr variable = ast.arg3(); + IExpr variable; + if (ast.arg3().isAST()) { + variable = ast.arg3(); + } else { + variable = Validate.checkSymbolType(ast, 3, engine); + if (!variable.isPresent()) { + return F.NIL; + } + } IExpr arg1 = F.evalExpandAll(ast.arg1(), engine); IExpr arg2 = F.evalExpandAll(ast.arg2(), engine); - - IExpr result = F.NIL; - if (ast.size() == 5) { - final OptionArgs options = new OptionArgs(ast.topHead(), ast, 4, engine); - IExpr option = options.getOption(F.Modulus); - if (option.isInteger() && !option.isZero()) { - IExpr[] quotientRemainderModInteger = quotientRemainderModInteger(arg1, arg2, variable, option); - if (quotientRemainderModInteger != null) { - result = F.List(quotientRemainderModInteger[0], quotientRemainderModInteger[1]); + try { + IExpr result = F.NIL; + if (ast.size() == 5) { + final OptionArgs options = new OptionArgs(ast.topHead(), ast, 4, engine); + IExpr option = options.getOption(F.Modulus); + if (option.isInteger() && !option.isZero()) { + IExpr[] quotientRemainderModInteger = quotientRemainderModInteger(arg1, arg2, variable, option); + if (quotientRemainderModInteger != null) { + result = F.List(quotientRemainderModInteger[0], quotientRemainderModInteger[1]); + } } + F.REMEMBER_AST_CACHE.put(ast, result); + return result; + } + IExpr[] quotientRemainder = quotientRemainder(arg1, arg2, variable); + if (quotientRemainder != null) { + result = F.List(quotientRemainder[0], quotientRemainder[1]); } F.REMEMBER_AST_CACHE.put(ast, result); return result; + } catch (RuntimeException rex) { + if (Config.SHOW_STACKTRACE) { + rex.printStackTrace(); + } + return F.NIL; } - IExpr[] quotientRemainder = quotientRemainder(arg1, arg2, variable); - if (quotientRemainder != null) { - result = F.List(quotientRemainder[0], quotientRemainder[1]); - } - F.REMEMBER_AST_CACHE.put(ast, result); - return result; } public int[] expectedArgSize() { @@ -3376,27 +3404,41 @@ private static class PolynomialRemainder extends PolynomialQuotientRemainder { @Override public IExpr evaluate(final IAST ast, EvalEngine engine) { - IExpr variable = ast.arg3(); + IExpr variable; + if (ast.arg3().isAST()) { + variable = ast.arg3(); + } else { + variable = Validate.checkSymbolType(ast, 3, engine); + if (!variable.isPresent()) { + return F.NIL; + } + } IExpr arg1 = F.evalExpandAll(ast.arg1(), engine); IExpr arg2 = F.evalExpandAll(ast.arg2(), engine); - - if (ast.size() == 5) { - final OptionArgs options = new OptionArgs(ast.topHead(), ast, 4, engine); - IExpr option = options.getOption(F.Modulus); - if (option.isInteger() && !option.isZero()) { - IExpr[] result = quotientRemainderModInteger(arg1, arg2, variable, option); - if (result == null) { - return F.NIL; + try { + if (ast.size() == 5) { + final OptionArgs options = new OptionArgs(ast.topHead(), ast, 4, engine); + IExpr option = options.getOption(F.Modulus); + if (option.isInteger() && !option.isZero()) { + IExpr[] result = quotientRemainderModInteger(arg1, arg2, variable, option); + if (result == null) { + return F.NIL; + } + return result[1]; } - return result[1]; + return F.NIL; + } + IExpr[] result = quotientRemainder(arg1, arg2, variable); + if (result == null) { + return F.NIL; + } + return result[1]; + } catch (RuntimeException rex) { + if (Config.SHOW_STACKTRACE) { + rex.printStackTrace(); } return F.NIL; } - IExpr[] result = quotientRemainder(arg1, arg2, variable); - if (result == null) { - return F.NIL; - } - return result[1]; } public int[] expectedArgSize() { diff --git a/symja_android_library/matheclipse-core/src/main/java/org/matheclipse/core/builtin/BooleanFunctions.java b/symja_android_library/matheclipse-core/src/main/java/org/matheclipse/core/builtin/BooleanFunctions.java index e65dd02ed2..db62123666 100644 --- a/symja_android_library/matheclipse-core/src/main/java/org/matheclipse/core/builtin/BooleanFunctions.java +++ b/symja_android_library/matheclipse-core/src/main/java/org/matheclipse/core/builtin/BooleanFunctions.java @@ -888,47 +888,52 @@ private static class BooleanMinimize extends AbstractFunctionEvaluator { @Override public IExpr evaluate(final IAST ast, EvalEngine engine) { - FormulaFactory factory = new FormulaFactory(); - LogicFormula lf = new LogicFormula(factory); - Formula formula = lf.expr2BooleanFunction(ast.arg1()); - // only DNF form can be used in QuineMcCluskeyAlgorithm at the moment - formula = formula.transform(new DNFFactorization()); - IExpr ex = lf.booleanFunction2Expr(formula); - IASTAppendable vars = F.Or(); - if (ex.isOr()) { - IAST orAST = (IAST) ex; - IASTAppendable rest = F.Or(); - for (int i = 1; i < orAST.size(); i++) { - IExpr temp = orAST.get(i); - if (temp.isAnd()) { - rest.append(temp); + try { + FormulaFactory factory = new FormulaFactory(); + LogicFormula lf = new LogicFormula(factory); + Formula formula = lf.expr2BooleanFunction(ast.arg1()); + // only DNF form can be used in QuineMcCluskeyAlgorithm at the moment + formula = formula.transform(new DNFFactorization()); + IExpr ex = lf.booleanFunction2Expr(formula); + IASTAppendable vars = F.Or(); + if (ex.isOr()) { + IAST orAST = (IAST) ex; + IASTAppendable rest = F.Or(); + for (int i = 1; i < orAST.size(); i++) { + IExpr temp = orAST.get(i); + if (temp.isAnd()) { + rest.append(temp); + } else { + vars.append(temp); + } + } + if (rest.size() == 1) { + vars = F.Or(); } else { - vars.append(temp); + formula = lf.expr2BooleanFunction(rest); } } - if (rest.size() == 1) { - vars = F.Or(); + + formula = QuineMcCluskeyAlgorithm.compute(formula); + // System.out.println(formula.toString()); + IExpr result = lf.booleanFunction2Expr(formula); + if (result.isOr()) { + vars.appendArgs((IAST) result); + EvalAttributes.sort(vars); + result = vars; } else { - formula = lf.expr2BooleanFunction(rest); + vars.append(result); + EvalAttributes.sort(vars); + result = vars; } - } + return result; + // TODO CNF form after minimizing blows up the formula. + // FormulaTransformation transformation = BooleanConvert.transformation(ast, engine); + // return lf.booleanFunction2Expr(formula.transform(transformation)); + } catch (RuntimeException rex) { - formula = QuineMcCluskeyAlgorithm.compute(formula); - // System.out.println(formula.toString()); - IExpr result = lf.booleanFunction2Expr(formula); - if (result.isOr()) { - vars.appendArgs((IAST) result); - EvalAttributes.sort(vars); - result = vars; - } else { - vars.append(result); - EvalAttributes.sort(vars); - result = vars; } - return result; - // TODO CNF form after minimizing blows up the formula. - // FormulaTransformation transformation = BooleanConvert.transformation(ast, engine); - // return lf.booleanFunction2Expr(formula.transform(transformation)); + return ast.arg1(); } public int[] expectedArgSize() { @@ -2461,7 +2466,7 @@ private IExpr maximum(IAST list, boolean flattenedList) { if (!evaled) { evaled = flattenedList; } - + if (list.size() == 1) { return F.CNInfinity; } diff --git a/symja_android_library/matheclipse-core/src/main/java/org/matheclipse/core/builtin/Combinatoric.java b/symja_android_library/matheclipse-core/src/main/java/org/matheclipse/core/builtin/Combinatoric.java index c93f00027e..40f472f0b6 100644 --- a/symja_android_library/matheclipse-core/src/main/java/org/matheclipse/core/builtin/Combinatoric.java +++ b/symja_android_library/matheclipse-core/src/main/java/org/matheclipse/core/builtin/Combinatoric.java @@ -6,6 +6,7 @@ import org.matheclipse.core.combinatoric.KSubsets; import org.matheclipse.core.eval.EvalEngine; +import org.matheclipse.core.eval.exception.ArgumentTypeException; import org.matheclipse.core.eval.exception.Validate; import org.matheclipse.core.eval.interfaces.AbstractEvaluator; import org.matheclipse.core.eval.interfaces.AbstractFunctionEvaluator; @@ -1467,40 +1468,44 @@ public IExpr evaluate(final IAST ast, EvalEngine engine) { return F.NIL; } if (ast.arg1().isAST()) { - final IAST f = (IAST) ast.arg1(); - int n = f.argSize(); - final LevelSpecification level; - if (ast.isAST2()) { - if (ast.arg2().isInteger()) { - n = ((IInteger) ast.arg2()).toIntDefault(Integer.MIN_VALUE); - if (n > Integer.MIN_VALUE) { - level = new LevelSpecification(0, n); + try { + final IAST f = (IAST) ast.arg1(); + int n = f.argSize(); + final LevelSpecification level; + if (ast.isAST2()) { + if (ast.arg2().isInteger()) { + n = ((IInteger) ast.arg2()).toIntDefault(Integer.MIN_VALUE); + if (n > Integer.MIN_VALUE) { + level = new LevelSpecification(0, n); + } else { + return F.NIL; + } } else { - return F.NIL; + level = new LevelSpecification(ast.arg2(), false); } } else { - level = new LevelSpecification(ast.arg2(), false); + level = new LevelSpecification(0, n); } - } else { - level = new LevelSpecification(0, n); - } - int k; - final IASTAppendable result = F.ast(f.head()); - level.setFromLevelAsCurrent(); - while (level.isInRange()) { - k = level.getCurrentLevel(); - final KSubsetsList iter = createKSubsets(f, k, F.ast(F.List), 1); - for (IAST part : iter) { - if (part == null) { - break; + int k; + final IASTAppendable result = F.ast(f.head()); + level.setFromLevelAsCurrent(); + while (level.isInRange()) { + k = level.getCurrentLevel(); + final KSubsetsList iter = createKSubsets(f, k, F.ast(F.List), 1); + for (IAST part : iter) { + if (part == null) { + break; + } + result.append(part); } - result.append(part); + level.incCurrentLevel(); } - level.incCurrentLevel(); - } - return result; + return result; + } catch (ArgumentTypeException ate) { + // see LevelSpecification + } } return F.NIL; } diff --git a/symja_android_library/matheclipse-core/src/main/java/org/matheclipse/core/builtin/EllipticIntegrals.java b/symja_android_library/matheclipse-core/src/main/java/org/matheclipse/core/builtin/EllipticIntegrals.java index d5ef4393b1..df64f8a963 100644 --- a/symja_android_library/matheclipse-core/src/main/java/org/matheclipse/core/builtin/EllipticIntegrals.java +++ b/symja_android_library/matheclipse-core/src/main/java/org/matheclipse/core/builtin/EllipticIntegrals.java @@ -862,6 +862,11 @@ public IExpr evaluate(IAST ast, EvalEngine engine) { return F.NIL; } + @Override + public int[] expectedArgSize() { + return IOFunctions.ARGS_2_2; + } + @Override public void setUp(final ISymbol newSymbol) { newSymbol.setAttributes(ISymbol.LISTABLE | ISymbol.NUMERICFUNCTION); diff --git a/symja_android_library/matheclipse-core/src/main/java/org/matheclipse/core/builtin/IOFunctions.java b/symja_android_library/matheclipse-core/src/main/java/org/matheclipse/core/builtin/IOFunctions.java index 02daed597c..40a1a53694 100644 --- a/symja_android_library/matheclipse-core/src/main/java/org/matheclipse/core/builtin/IOFunctions.java +++ b/symja_android_library/matheclipse-core/src/main/java/org/matheclipse/core/builtin/IOFunctions.java @@ -662,6 +662,7 @@ public int[] expectedArgSize() { "intnm", "Non-negative machine-sized integer expected at position `2` in `1`.", // "intpm", "Positive integer (less equal 2147483647) expected at position `2` in `1`.", // "iterb", "Iterator does not have appropriate bounds.", // + "itform", "Argument `1` at position `2` does not have the correct form for an iterator.", // "ivar", "`1` is not a valid variable.", // "level", "Level specification `1` is not of the form n, {n}, or {m, n}.", // "list", "List expected at position `1` in `2`.", // diff --git a/symja_android_library/matheclipse-core/src/main/java/org/matheclipse/core/builtin/LinearAlgebra.java b/symja_android_library/matheclipse-core/src/main/java/org/matheclipse/core/builtin/LinearAlgebra.java index 341d953fea..59e4a5f385 100644 --- a/symja_android_library/matheclipse-core/src/main/java/org/matheclipse/core/builtin/LinearAlgebra.java +++ b/symja_android_library/matheclipse-core/src/main/java/org/matheclipse/core/builtin/LinearAlgebra.java @@ -1388,6 +1388,12 @@ public IExpr evaluateAST1(final IAST ast, EvalEngine engine) { @Override public IExpr e2ObjArg(IAST ast, final IExpr arg1, final IExpr arg2) { + if (arg1.size() == 1 && arg2.size() == 1) { + if (arg1.isList() && arg2.isList()) { + return F.C0; + } + return F.NIL; + } IExpr temp = numericalDot(arg1, arg2); if (temp.isPresent()) { return temp; @@ -1452,7 +1458,7 @@ public IExpr e2ObjArg(IAST ast, final IExpr arg1, final IExpr arg2) { // e.printStackTrace(); // } } catch (final RuntimeException e) { - engine.printMessage(ast.topHead() + ": " + e.getMessage()); + engine.printMessage(ast.topHead() + ": " + e.toString()); if (Config.SHOW_STACKTRACE) { e.printStackTrace(); } @@ -1829,7 +1835,7 @@ private static IExpr unit(IExpr arg) { public IExpr evaluate(final IAST ast, EvalEngine engine) { if (ast.arg1().isInteger()) { final int m = ast.arg1().toIntDefault(Integer.MIN_VALUE); - if (m < 0) { + if (m <= 0) { // Positive integer (less equal 2147483647) expected at position `2` in `1`. return IOFunctions.printMessage(F.FourierMatrix, "intpm", F.List(ast, F.C1), engine); } @@ -3431,6 +3437,9 @@ public IExpr evaluate(final IAST ast, EvalEngine engine) { return v.times(dotProduct(head, u, v, engine).divide(dotProduct(head, v, v, engine))); } if (dim1 >= 0 && dim1 == dim2) { + if (dim1 == 0) { + return F.CEmptyList; + } FieldVector u = Convert.list2Vector((IAST) ast.arg1()); FieldVector v = Convert.list2Vector((IAST) ast.arg2()); FieldVector vConjugate = v.copy(); @@ -4199,13 +4208,15 @@ public IExpr evaluate(final IAST ast, EvalEngine engine) { if (ast.isAST2()) { int n = ast.arg1().toIntDefault(Integer.MIN_VALUE); if (n < 0) { + return F.NIL; // Positive integer (less equal 2147483647) expected at position `2` in `1`. - return IOFunctions.printMessage(F.UnitVector, "intpm", F.List(ast, F.C1), engine); + // return IOFunctions.printMessage(F.UnitVector, "intpm", F.List(ast, F.C1), engine); } int k = ast.arg2().toIntDefault(Integer.MIN_VALUE); if (k < 0) { + return F.NIL; // Positive integer (less equal 2147483647) expected at position `2` in `1`. - return IOFunctions.printMessage(F.UnitVector, "intpm", F.List(ast, F.C2), engine); + // return IOFunctions.printMessage(F.UnitVector, "intpm", F.List(ast, F.C2), engine); } if (k <= n) { diff --git a/symja_android_library/matheclipse-core/src/main/java/org/matheclipse/core/builtin/ListFunctions.java b/symja_android_library/matheclipse-core/src/main/java/org/matheclipse/core/builtin/ListFunctions.java index 0e76e5af7e..d2fab8c63d 100644 --- a/symja_android_library/matheclipse-core/src/main/java/org/matheclipse/core/builtin/ListFunctions.java +++ b/symja_android_library/matheclipse-core/src/main/java/org/matheclipse/core/builtin/ListFunctions.java @@ -25,6 +25,7 @@ import org.matheclipse.core.convert.VariablesSet; import org.matheclipse.core.eval.EvalAttributes; import org.matheclipse.core.eval.EvalEngine; +import org.matheclipse.core.eval.exception.ArgumentTypeException; import org.matheclipse.core.eval.exception.FlowControlException; import org.matheclipse.core.eval.exception.IllegalArgument; import org.matheclipse.core.eval.exception.NoEvalException; @@ -1126,7 +1127,8 @@ public IExpr evaluate(IAST ast, EvalEngine engine) { VisitorLevelSpecification level = new VisitorLevelSpecification(crf, arg3, false, engine); arg1.accept(level); - + } catch (ArgumentTypeException ate) { + return F.NIL; } catch (StopException se) { // reached maximum number of results } @@ -1140,6 +1142,8 @@ public IExpr evaluate(IAST ast, EvalEngine engine) { VisitorLevelSpecification level = new VisitorLevelSpecification(cpmf, arg3, false, engine); arg1.accept(level); + } catch (ArgumentTypeException ate) { + return F.NIL; } catch (StopException se) { // reached maximum number of results } @@ -1505,6 +1509,9 @@ public static IExpr evaluateArray(final IAST ast, IAST resultList) { indx1 = Validate.checkIntType(dimensions, i); dim[i - 1] = indx1; } + if (dim.length == 0) { + return F.CEmptyList; + } return constantExpr.constantArray(F.List, 0, dim); } else if (ast.size() >= 4) { if (ast.arg2().isInteger() && ast.arg3().isInteger()) { @@ -1540,6 +1547,11 @@ public static IExpr evaluateArray(final IAST ast, IAST resultList) { return F.NIL; } + @Override + public int[] expectedArgSize() { + return IOFunctions.ARGS_2_2; + } + @Override public void setUp(final ISymbol newSymbol) { newSymbol.setAttributes(ISymbol.HOLDALL); @@ -1617,10 +1629,9 @@ public IExpr evaluate(final IAST ast, EvalEngine engine) { } arg1.accept(level); return F.ZZ(mf.getCounter()); - } catch (final RuntimeException rex) { - // ArgumentTypeException from VisitorLevelSpecification level specification checks - return engine.printMessage("Count: " + rex.getMessage()); + } catch (ArgumentTypeException ate) { } + return F.NIL; } @Override @@ -1845,9 +1856,11 @@ public IExpr evaluate(final IAST ast, EvalEngine engine) { return arg1RemoveClone; } catch (VisitorRemoveLevelSpecification.StopException se) { // reached maximum number of results - } catch (final RuntimeException rex) { - // ArgumentTypeException from VisitorLevelSpecification level specification checks - return engine.printMessage("DeleteCases: " + rex.getMessage()); + } catch (final ArgumentTypeException ate) { + return F.NIL; + // } catch (final RuntimeException rex) { + // // ArgumentTypeException from VisitorLevelSpecification level specification checks + // return engine.printMessage("DeleteCases: " + rex.getMessage()); } return arg1RemoveClone; @@ -3089,9 +3102,8 @@ public IExpr evaluate(final IAST ast, EvalEngine engine) { return resultList; } return F.List(); - } catch (final RuntimeException rex) { - // ArgumentTypeException from VisitorLevelSpecification level specification checks - return engine.printMessage("Level: " + rex.getMessage()); + } catch (ArgumentTypeException ate) { + return F.NIL; } } @@ -3714,9 +3726,13 @@ public IExpr evaluate(IAST ast, EvalEngine engine) { } return F.NIL; } - final IExpr arg3 = engine.evaluate(ast.arg3()); - final LevelSpec level = new LevelSpecification(arg3, true); - return position((IAST) arg1, arg2, level, maxResults, engine); + try { + final IExpr arg3 = engine.evaluate(ast.arg3()); + final LevelSpec level = new LevelSpecification(arg3, true); + return position((IAST) arg1, arg2, level, maxResults, engine); + } catch (ArgumentTypeException ate) { + // see LevelSpecification + } } } return F.NIL; @@ -3968,6 +3984,9 @@ public IExpr evaluate(final ISymbol[] variables, final IExpr[] index) { @Override public IExpr evaluate(final IAST ast, EvalEngine engine) { + if (ast.arg1().isAST(F.List, 1)) { + return ast.arg1(); + } if (ast.isAST1() && ast.arg1().isReal()) { int size = ast.arg1().toIntDefault(Integer.MIN_VALUE); if (size != Integer.MIN_VALUE) { @@ -4026,6 +4045,11 @@ public IExpr evaluateTable(final IAST ast, final IAST resultList, EvalEngine eng return F.NIL; } + @Override + public int[] expectedArgSize() { + return IOFunctions.ARGS_1_3; + } + @Override public void setUp(final ISymbol newSymbol) { newSymbol.setAttributes(ISymbol.HOLDALL); @@ -4877,9 +4901,12 @@ private final static class RotateLeft extends AbstractCoreFunctionEvaluator { public IExpr evaluate(final IAST ast, EvalEngine engine) { IExpr arg1 = engine.evaluate(ast.arg1()); if (arg1.isAST()) { + final int argSize = arg1.argSize(); + if (argSize == 0) { + return arg1; + } final IASTAppendable result = F.ast(arg1.head()); if (ast.isAST1()) { - // ASTRange range = ((IAST) arg1).args(); ((IAST) arg1).rotateLeft(result, 1); // Rotating.rotateLeft((IAST) list.arg1(), result, 2, 1); return result; @@ -4890,7 +4917,7 @@ public IExpr evaluate(final IAST ast, EvalEngine engine) { if (n == Integer.MIN_VALUE) { return F.NIL; } - // ASTRange range = ((IAST) arg1).args(); + n = n % argSize; ((IAST) arg1).rotateLeft(result, n); return result; } @@ -4945,6 +4972,10 @@ private final static class RotateRight extends AbstractCoreFunctionEvaluator { public IExpr evaluate(final IAST ast, EvalEngine engine) { IExpr arg1 = engine.evaluate(ast.arg1()); if (arg1.isAST()) { + final int argSize = arg1.argSize(); + if (argSize == 0) { + return arg1; + } final IASTAppendable result = F.ast(arg1.head()); if (ast.isAST1()) { // ASTRange range = ((IAST) arg1).args(); @@ -4958,6 +4989,7 @@ public IExpr evaluate(final IAST ast, EvalEngine engine) { if (n == Integer.MIN_VALUE) { return F.NIL; } + n = n % argSize; // ASTRange range = ((IAST) arg1).args(); ((IAST) arg1).rotateRight(result, n); return result; @@ -5377,9 +5409,9 @@ protected static IExpr evaluateTable(final IAST ast, final IAST resultList, IExp final List> iterList = new ArrayList>(); for (int i = 2; i < ast.size(); i++) { if (ast.get(i).isList()) { - iterList.add(Iterator.create((IAST) ast.get(i), engine)); + iterList.add(Iterator.create((IAST) ast.get(i), i, engine)); } else { - iterList.add(Iterator.create(F.List(ast.get(i)), engine)); + iterList.add(Iterator.create(F.List(ast.get(i)), i, engine)); } } @@ -5387,6 +5419,7 @@ protected static IExpr evaluateTable(final IAST ast, final IAST resultList, IExp new TableFunction(engine, ast.arg1()), defaultValue); return generator.table(); } + } catch (final ArgumentTypeException e) { } catch (final NoEvalException e) { } catch (final ClassCastException e) { // the iterators are generated only from IASTs @@ -5402,9 +5435,9 @@ protected static IExpr evaluateTableThrow(final IAST ast, final IAST resultList, final List> iterList = new ArrayList>(); for (int i = 2; i < ast.size(); i++) { if (ast.get(i).isList()) { - iterList.add(Iterator.create((IAST) ast.get(i), engine)); + iterList.add(Iterator.create((IAST) ast.get(i), i, engine)); } else { - iterList.add(Iterator.create(F.List(ast.get(i)), engine)); + iterList.add(Iterator.create(F.List(ast.get(i)), i, engine)); } } @@ -5412,6 +5445,7 @@ protected static IExpr evaluateTableThrow(final IAST ast, final IAST resultList, new TableFunction(engine, ast.arg1()), defaultValue); return generator.tableThrow(); } + } catch (final ArgumentTypeException e) { } catch (final NoEvalException e) { } catch (final ClassCastException e) { // the iterators are generated only from IASTs @@ -5979,9 +6013,11 @@ public IExpr evaluate(final IAST ast, EvalEngine engine) { } } } - } catch (final RuntimeException rex) { - // ArgumentTypeException from VisitorLevelSpecification level specification checks - return engine.printMessage("Total: " + rex.getMessage()); + } catch (ArgumentTypeException ate) { + return F.NIL; + // } catch (final RuntimeException rex) { + // // ArgumentTypeException from VisitorLevelSpecification level specification checks + // return engine.printMessage("Total: " + rex.getMessage()); } return F.NIL; } diff --git a/symja_android_library/matheclipse-core/src/main/java/org/matheclipse/core/builtin/NumberTheory.java b/symja_android_library/matheclipse-core/src/main/java/org/matheclipse/core/builtin/NumberTheory.java index 0ed98bbb82..5027ed3670 100644 --- a/symja_android_library/matheclipse-core/src/main/java/org/matheclipse/core/builtin/NumberTheory.java +++ b/symja_android_library/matheclipse-core/src/main/java/org/matheclipse/core/builtin/NumberTheory.java @@ -707,6 +707,9 @@ public IExpr evaluate(final IAST ast, EvalEngine engine) { if (a.length != n.length) { return F.NIL; } + if (a.length == 0) { + return F.NIL; + } try { return F.ZZ(chineseRemainders(n, a)); } catch (ArithmeticException ae) { @@ -2212,7 +2215,7 @@ private static class FrobeniusNumber extends AbstractFunctionEvaluator { @Override public IExpr evaluate(final IAST ast, EvalEngine engine) { BigInteger[] array = Validate.checkListOfBigIntegers(ast, ast.arg1(), true, engine); - if (array != null) { + if (array != null && array.length > 0) { BigInteger result = org.matheclipse.core.frobenius.FrobeniusNumber.frobeniusNumber(array); return F.ZZ(result); } diff --git a/symja_android_library/matheclipse-core/src/main/java/org/matheclipse/core/builtin/PatternMatching.java b/symja_android_library/matheclipse-core/src/main/java/org/matheclipse/core/builtin/PatternMatching.java index 0f17d6a6eb..1ac903470f 100644 --- a/symja_android_library/matheclipse-core/src/main/java/org/matheclipse/core/builtin/PatternMatching.java +++ b/symja_android_library/matheclipse-core/src/main/java/org/matheclipse/core/builtin/PatternMatching.java @@ -17,6 +17,7 @@ import org.matheclipse.core.basic.Config; import org.matheclipse.core.convert.AST2Expr; import org.matheclipse.core.eval.EvalEngine; +import org.matheclipse.core.eval.exception.ArgumentTypeException; import org.matheclipse.core.eval.exception.ConditionException; import org.matheclipse.core.eval.exception.FailedException; import org.matheclipse.core.eval.exception.ReturnException; @@ -107,7 +108,7 @@ public IExpr evaluate(final IAST ast, EvalEngine engine) { // completeContextName = packageName.substring(0, packageName.length() - 1) + contextName; // } Context context = engine.begin(contextName, pack); - return F.stringx(context.completeContextName()); + return F.stringx(context.completeContextName()); } @Override @@ -1904,20 +1905,25 @@ private final static class UpSet extends AbstractCoreFunctionEvaluator { public IExpr evaluate(final IAST ast, EvalEngine engine) { final IExpr leftHandSide = ast.arg1(); IExpr rightHandSide = ast.arg2(); - if (leftHandSide.isList()) { - // thread over lists - try { - rightHandSide = engine.evaluate(rightHandSide); - } catch (final ReturnException e) { - rightHandSide = e.getValue(); - } - IExpr temp = engine.threadASTListArgs((IASTMutable) F.UpSet(leftHandSide, rightHandSide)); - if (temp.isPresent()) { - return engine.evaluate(temp); + try { + if (leftHandSide.isList()) { + // thread over lists + try { + rightHandSide = engine.evaluate(rightHandSide); + } catch (final ReturnException e) { + rightHandSide = e.getValue(); + } + IExpr temp = engine.threadASTListArgs((IASTMutable) F.UpSet(leftHandSide, rightHandSide)); + if (temp.isPresent()) { + return engine.evaluate(temp); + } } + Object[] result = createPatternMatcher(leftHandSide, rightHandSide, false, engine); + return (IExpr) result[1]; + } catch (ArgumentTypeException ate) { + } - Object[] result = createPatternMatcher(leftHandSide, rightHandSide, false, engine); - return (IExpr) result[1]; + return F.NIL; } @Override @@ -1973,10 +1979,14 @@ private final static class UpSetDelayed extends AbstractCoreFunctionEvaluator { public IExpr evaluate(final IAST ast, EvalEngine engine) { final IExpr leftHandSide = ast.arg1(); final IExpr rightHandSide = ast.arg2(); + try { + createPatternMatcher(leftHandSide, rightHandSide, false, engine); - createPatternMatcher(leftHandSide, rightHandSide, false, engine); + return F.Null; + } catch (ArgumentTypeException ate) { - return F.Null; + } + return F.NIL; } @Override diff --git a/symja_android_library/matheclipse-core/src/main/java/org/matheclipse/core/builtin/PolynomialFunctions.java b/symja_android_library/matheclipse-core/src/main/java/org/matheclipse/core/builtin/PolynomialFunctions.java index 6cec38cf6c..709713fe1c 100644 --- a/symja_android_library/matheclipse-core/src/main/java/org/matheclipse/core/builtin/PolynomialFunctions.java +++ b/symja_android_library/matheclipse-core/src/main/java/org/matheclipse/core/builtin/PolynomialFunctions.java @@ -1155,7 +1155,13 @@ public IExpr evaluate(final IAST ast, EvalEngine engine) { } variables = eVar.getVarList(); } else { - variables = ast.arg2().orNewList(); + variables = Validate.checkSymbolOrSymbolList(ast, 2, engine); + if (!variables.isPresent()) { + return F.NIL; + } + } + if (variables.size() <= 1) { + return F.NIL; } IExpr temp = roots(ast.arg1(), variables, engine); if (!temp.isList()) { @@ -1626,18 +1632,22 @@ final private static class BellY extends AbstractFunctionEvaluator { @Override public IExpr evaluate(final IAST ast, EvalEngine engine) { - - int[] dim = ast.arg1().isMatrix(); - if (ast.isAST1() && dim != null) { - IAST matrixArg1 = (IAST) ast.arg1(); - - if (dim[0] == 1) { - if (dim[1] == 1) { - IAST row = (IAST) matrixArg1.arg1(); - return row.arg1(); - } else if (dim[1] >= 2) { - IAST row = (IAST) matrixArg1.arg1(); - return row.apply(F.Times); + if (ast.isAST1()) { + int[] dim = ast.arg1().isMatrix(); + if (dim != null) { + if (dim[0] == 0 && dim[1] == 0) { + return F.C0; + } + IAST matrixArg1 = (IAST) ast.arg1(); + + if (dim[0] == 1) { + if (dim[1] == 1) { + IAST row = (IAST) matrixArg1.arg1(); + return row.arg1(); + } else if (dim[1] >= 2) { + IAST row = (IAST) matrixArg1.arg1(); + return row.apply(F.Times); + } } } return F.NIL; diff --git a/symja_android_library/matheclipse-core/src/main/java/org/matheclipse/core/builtin/PredicateQ.java b/symja_android_library/matheclipse-core/src/main/java/org/matheclipse/core/builtin/PredicateQ.java index 3e685d425c..06edfa214c 100644 --- a/symja_android_library/matheclipse-core/src/main/java/org/matheclipse/core/builtin/PredicateQ.java +++ b/symja_android_library/matheclipse-core/src/main/java/org/matheclipse/core/builtin/PredicateQ.java @@ -200,6 +200,9 @@ private static int determineDepth(final IExpr expr, int depth, Predicate if (expr.isList()) { IAST ast = (IAST) expr; int size = ast.size(); + if (size==1) { + return depth; + } IExpr arg1AST = ast.arg1(); boolean isList = arg1AST.isList(); int arg1Size = 0; diff --git a/symja_android_library/matheclipse-core/src/main/java/org/matheclipse/core/builtin/Programming.java b/symja_android_library/matheclipse-core/src/main/java/org/matheclipse/core/builtin/Programming.java index b30d45d6da..344b6f9c38 100644 --- a/symja_android_library/matheclipse-core/src/main/java/org/matheclipse/core/builtin/Programming.java +++ b/symja_android_library/matheclipse-core/src/main/java/org/matheclipse/core/builtin/Programming.java @@ -18,6 +18,7 @@ import org.matheclipse.core.eval.EvalEngine; import org.matheclipse.core.eval.exception.ASTElementLimitExceeded; import org.matheclipse.core.eval.exception.AbortException; +import org.matheclipse.core.eval.exception.ArgumentTypeException; import org.matheclipse.core.eval.exception.BreakException; import org.matheclipse.core.eval.exception.ConditionException; import org.matheclipse.core.eval.exception.ContinueException; @@ -641,7 +642,7 @@ public IExpr doIt(IExpr input) { public IExpr evaluate(final IAST ast, EvalEngine engine) { try { final java.util.List> iterList = new ArrayList>(); - ast.forEach(2, ast.size(), x -> iterList.add(Iterator.create((IAST) x, engine))); + ast.forEach(2, ast.size(), (x, i) -> iterList.add(Iterator.create((IAST) x, i, engine))); final DoIterator generator = new DoIterator(iterList, engine); return generator.doIt(ast.arg1()); } catch (final NoEvalException e) { @@ -846,7 +847,7 @@ public IExpr evaluate(final IAST ast, EvalEngine engine) { } else if (ast.arg3().isNegativeInfinity()) { iterations = Integer.MIN_VALUE; } else { - iterations = Validate.checkIntType(ast, 3, Integer.MIN_VALUE); + iterations = Validate.checkNonNegativeIntType(ast, 3); } } if (iterations < 0) { @@ -864,7 +865,8 @@ public IExpr evaluate(final IAST ast, EvalEngine engine) { } while ((!current.isSame(last)) && (--iterations > 0)); } return list; - + } catch (ArgumentTypeException ate) { + return F.NIL; } finally { engine.setNumericMode(numericMode); } diff --git a/symja_android_library/matheclipse-core/src/main/java/org/matheclipse/core/builtin/RandomFunctions.java b/symja_android_library/matheclipse-core/src/main/java/org/matheclipse/core/builtin/RandomFunctions.java index 73ae16d5fe..b0ef9e8dd3 100644 --- a/symja_android_library/matheclipse-core/src/main/java/org/matheclipse/core/builtin/RandomFunctions.java +++ b/symja_android_library/matheclipse-core/src/main/java/org/matheclipse/core/builtin/RandomFunctions.java @@ -58,6 +58,9 @@ public IExpr evaluate(final IAST ast, EvalEngine engine) { IAST list = (IAST) ast.arg1(); ThreadLocalRandom random = ThreadLocalRandom.current(); int listSize = list.argSize(); + if (listSize == 0) { + return F.NIL; + } int randomIndex = random.nextInt(listSize); if (ast.size() == 2) { return list.get(randomIndex + 1); @@ -79,7 +82,7 @@ public IExpr evaluate(final IAST ast, EvalEngine engine) { } } - + /** *
 	 * RandomInteger(n)
diff --git a/symja_android_library/matheclipse-core/src/main/java/org/matheclipse/core/builtin/StatisticsFunctions.java b/symja_android_library/matheclipse-core/src/main/java/org/matheclipse/core/builtin/StatisticsFunctions.java
index ed09ca1ec8..a27ce84dfa 100644
--- a/symja_android_library/matheclipse-core/src/main/java/org/matheclipse/core/builtin/StatisticsFunctions.java
+++ b/symja_android_library/matheclipse-core/src/main/java/org/matheclipse/core/builtin/StatisticsFunctions.java
@@ -2584,7 +2584,7 @@ public IExpr evaluate(final IAST ast, EvalEngine engine) {
 				return super.evaluate(ast, engine);
 			}
 
-			if (ast.size() == 3) {
+			if (ast.size() == 3 && ast.arg1().isAST() && ast.arg2().isAST()) {
 				final IAST arg1 = (IAST) ast.arg1();
 				final IAST arg2 = (IAST) ast.arg2();
 				return evaluateArg2(arg1, arg2, engine);
@@ -3249,11 +3249,12 @@ public IExpr evaluate(final IAST ast, EvalEngine engine) {
 			if (ast.isAST1()) {
 				// KolmogorovSmirnovTest(data1)
 				double[] data1 = ast.arg1().toDoubleVector();
-				org.hipparchus.stat.inference.KolmogorovSmirnovTest test = new org.hipparchus.stat.inference.KolmogorovSmirnovTest();
-				double d = test.kolmogorovSmirnovTest(new org.hipparchus.distribution.continuous.NormalDistribution(),
-						data1, false);
-				return F.num(d);
-
+				if (data1 != null && data1.length > 0) {
+					org.hipparchus.stat.inference.KolmogorovSmirnovTest test = new org.hipparchus.stat.inference.KolmogorovSmirnovTest();
+					double d = test.kolmogorovSmirnovTest(
+							new org.hipparchus.distribution.continuous.NormalDistribution(), data1, false);
+					return F.num(d);
+				}
 			} else if (ast.size() == 3 || ast.size() == 4) {
 				int property = 0;
 				if (ast.size() == 4) {
diff --git a/symja_android_library/matheclipse-core/src/main/java/org/matheclipse/core/builtin/Structure.java b/symja_android_library/matheclipse-core/src/main/java/org/matheclipse/core/builtin/Structure.java
index 1c1eb38fc6..c0e72509de 100644
--- a/symja_android_library/matheclipse-core/src/main/java/org/matheclipse/core/builtin/Structure.java
+++ b/symja_android_library/matheclipse-core/src/main/java/org/matheclipse/core/builtin/Structure.java
@@ -10,6 +10,7 @@
 import org.matheclipse.core.basic.Config;
 import org.matheclipse.core.eval.EvalAttributes;
 import org.matheclipse.core.eval.EvalEngine;
+import org.matheclipse.core.eval.exception.ArgumentTypeException;
 import org.matheclipse.core.eval.exception.ReturnException;
 import org.matheclipse.core.eval.exception.Validate;
 import org.matheclipse.core.eval.interfaces.AbstractCoreFunctionEvaluator;
@@ -228,9 +229,10 @@ public static IExpr evalApply(IExpr f, IExpr expr, IAST evaledAST, int lastIndex
 						return expr;
 					}
 				}
-			} catch (final RuntimeException rex) {
-				// ArgumentTypeException from VisitorLevelSpecification level specification checks
-				return engine.printMessage("Apply: " + rex.getMessage());
+			} catch (final ArgumentTypeException ate) {
+				// } catch (final RuntimeException rex) {
+				// // ArgumentTypeException from VisitorLevelSpecification level specification checks
+				// return engine.printMessage("Apply: " + rex.getMessage());
 			}
 			return F.NIL;
 		}
@@ -476,34 +478,38 @@ public IExpr evaluate(final IAST ast, EvalEngine engine) {
 			IExpr arg1 = engine.evaluate(ast.arg1());
 			if (arg1.isAST()) {
 				IAST arg1AST = (IAST) arg1;
-				if (ast.isAST1()) {
-					IAST resultList = EvalAttributes.flattenDeep(arg1AST.topHead(), (IAST) arg1);
-					if (resultList.isPresent()) {
-						return resultList;
-					}
-					return arg1AST;
-				} else if (ast.isAST2()) {
-					IExpr arg2 = engine.evaluate(ast.arg2());
-
-					int level = Validate.checkIntLevelType(arg2);
-					if (level > 0) {
-						IASTAppendable resultList = F.ast(arg1AST.topHead());
-						if (EvalAttributes.flatten(arg1AST.topHead(), (IAST) arg1, resultList, 0, level)) {
+				try {
+					if (ast.isAST1()) {
+						IAST resultList = EvalAttributes.flattenDeep(arg1AST.topHead(), (IAST) arg1);
+						if (resultList.isPresent()) {
 							return resultList;
 						}
-					}
-					return arg1;
-				} else if (ast.isAST3() && ast.arg3().isSymbol()) {
-					IExpr arg2 = engine.evaluate(ast.arg2());
-
-					int level = Validate.checkIntLevelType(arg2);
-					if (level > 0) {
-						IASTAppendable resultList = F.ast(arg1AST.topHead());
-						if (EvalAttributes.flatten((ISymbol) ast.arg3(), (IAST) arg1, resultList, 0, level)) {
-							return resultList;
+						return arg1AST;
+					} else if (ast.isAST2()) {
+						IExpr arg2 = engine.evaluate(ast.arg2());
+
+						int level = Validate.checkIntLevelType(arg2);
+						if (level > 0) {
+							IASTAppendable resultList = F.ast(arg1AST.topHead());
+							if (EvalAttributes.flatten(arg1AST.topHead(), (IAST) arg1, resultList, 0, level)) {
+								return resultList;
+							}
 						}
+						return arg1;
+					} else if (ast.isAST3() && ast.arg3().isSymbol()) {
+						IExpr arg2 = engine.evaluate(ast.arg2());
+
+						int level = Validate.checkIntLevelType(arg2);
+						if (level > 0) {
+							IASTAppendable resultList = F.ast(arg1AST.topHead());
+							if (EvalAttributes.flatten((ISymbol) ast.arg3(), (IAST) arg1, resultList, 0, level)) {
+								return resultList;
+							}
+						}
+						return arg1;
 					}
-					return arg1;
+				} catch (ArgumentTypeException ate) {
+
 				}
 			}
 			return F.NIL;
@@ -927,8 +933,10 @@ public IExpr evaluate(IAST ast, EvalEngine engine) {
 					level = new VisitorLevelSpecification(x -> F.unaryAST1(arg1, x), 1, heads);
 				}
 				return arg2.accept(level).orElse(arg2);
-			} catch (final RuntimeException e) {
-				return engine.printMessage("Map: " + e.getMessage());
+			} catch (final ArgumentTypeException ate) {
+				return F.NIL;
+				// } catch (final RuntimeException e) {
+				// return engine.printMessage("Map: " + e.getMessage());
 			}
 		}
 
@@ -1582,6 +1590,7 @@ public IExpr evaluate(IAST ast, EvalEngine engine) {
 						}
 					}
 					return F.Null;
+				} catch (final ArgumentTypeException ate) {
 				} catch (final ReturnException e) {
 					return e.getValue();
 					// don't catch Throw[] here !
diff --git a/symja_android_library/matheclipse-core/src/main/java/org/matheclipse/core/builtin/TensorFunctions.java b/symja_android_library/matheclipse-core/src/main/java/org/matheclipse/core/builtin/TensorFunctions.java
index 8e6218ec27..d3f3909601 100644
--- a/symja_android_library/matheclipse-core/src/main/java/org/matheclipse/core/builtin/TensorFunctions.java
+++ b/symja_android_library/matheclipse-core/src/main/java/org/matheclipse/core/builtin/TensorFunctions.java
@@ -127,6 +127,14 @@ public IExpr evaluate(final IAST ast, EvalEngine engine) {
 			if (ast.arg1().isList() && ast.arg2().isList()) {
 				IAST list = (IAST) ast.arg1();
 				IAST dims = (IAST) ast.arg2();
+				if (dims.size() == 1) {
+					if (list.size() == 1) {
+						return F.C0;
+					}
+					if (list.size() > 1) {
+						return list.arg1();
+					}
+				}
 				int[] dimension = Validate.checkListOfInts(ast, dims, 1, Integer.MAX_VALUE, engine);
 				if (dimension == null) {
 					return F.NIL;
@@ -172,15 +180,17 @@ private static class ListConvolve extends AbstractEvaluator {
 		 */
 		@Override
 		public IExpr evaluate(final IAST ast, EvalEngine engine) {
-
-			if (ast.arg1().isAST() && ast.arg2().isAST()) {
-				IAST kernel = (IAST) ast.arg1();
-				IAST tensor = (IAST) ast.arg2();
-
-				int kernelSize = kernel.size();
-				int tensorSize = tensor.size();
-				if (kernelSize <= tensorSize) {
-					return ListCorrelate.listCorrelate(ListFunctions.reverse(kernel), kernelSize, tensor, tensorSize);
+			if (ast.isAST2()) {
+				if (ast.arg1().isAST() && ast.arg2().isAST()) {
+					IAST kernel = (IAST) ast.arg1();
+					IAST tensor = (IAST) ast.arg2();
+
+					int kernelSize = kernel.size();
+					int tensorSize = tensor.size();
+					if (kernelSize <= tensorSize) {
+						return ListCorrelate.listCorrelate(ListFunctions.reverse(kernel), kernelSize, tensor,
+								tensorSize);
+					}
 				}
 			}
 			return F.NIL;
@@ -188,7 +198,7 @@ public IExpr evaluate(final IAST ast, EvalEngine engine) {
 
 		@Override
 		public int[] expectedArgSize() {
-			return IOFunctions.ARGS_1_2;
+			return IOFunctions.ARGS_2_2;
 		}
 	}
 
@@ -218,13 +228,15 @@ private static class ListCorrelate extends AbstractEvaluator {
 		 */
 		@Override
 		public IExpr evaluate(final IAST ast, EvalEngine engine) {
-			if (ast.arg1().isAST() && ast.arg2().isAST()) {
-				IAST kernel = (IAST) ast.arg1();
-				IAST tensor = (IAST) ast.arg2();
-				int kernelSize = kernel.size();
-				int tensorSize = tensor.size();
-				if (kernelSize <= tensorSize) {
-					return listCorrelate(kernel, kernelSize, tensor, tensorSize);
+			if (ast.isAST2()) {
+				if (ast.arg1().isAST() && ast.arg2().isAST()) {
+					IAST kernel = (IAST) ast.arg1();
+					IAST tensor = (IAST) ast.arg2();
+					int kernelSize = kernel.size();
+					int tensorSize = tensor.size();
+					if (kernelSize <= tensorSize) {
+						return listCorrelate(kernel, kernelSize, tensor, tensorSize);
+					}
 				}
 			}
 			return F.NIL;
@@ -232,7 +244,7 @@ public IExpr evaluate(final IAST ast, EvalEngine engine) {
 
 		@Override
 		public int[] expectedArgSize() {
-			return IOFunctions.ARGS_1_2;
+			return IOFunctions.ARGS_2_2;
 		}
 
 		public static IExpr listCorrelate(IAST kernel, int kernelSize, IAST tensor, int tensorSize) {
diff --git a/symja_android_library/matheclipse-core/src/main/java/org/matheclipse/core/eval/exception/Validate.java b/symja_android_library/matheclipse-core/src/main/java/org/matheclipse/core/eval/exception/Validate.java
index d8c0063e5f..62fa4fdbdc 100644
--- a/symja_android_library/matheclipse-core/src/main/java/org/matheclipse/core/eval/exception/Validate.java
+++ b/symja_android_library/matheclipse-core/src/main/java/org/matheclipse/core/eval/exception/Validate.java
@@ -215,6 +215,32 @@ public static int checkIntType(IAST ast, int pos, int startValue) {
 		throw new ArgumentTypeException(str);
 	}
 
+	public static int checkNonNegativeIntType(IAST ast, int pos ) {
+		if (ast.get(pos) instanceof IntegerSym) {
+			// IntegerSym always fits into an int number
+			int result = ((IntegerSym) ast.get(pos)).toInt();
+			if (0 > result) {
+				// Non-negative machine-sized integer expected at position `2` in `1`.
+				String str = IOFunctions.getMessage("intnm", F.List(ast, F.ZZ(pos)),
+						EvalEngine.get());
+				throw new ArgumentTypeException(str);
+			}
+			return result;
+		}
+		if (ast.get(pos).isReal()) {
+			int result = ast.get(pos).toIntDefault();
+			if (result == Integer.MIN_VALUE || 0 > result) {
+				// Non-negative machine-sized integer expected at position `2` in `1`.
+				String str = IOFunctions.getMessage("intnm", F.List(ast, F.ZZ(pos)),
+						EvalEngine.get());
+				throw new ArgumentTypeException(str);
+			}
+			return result;
+		}
+		// Non-negative machine-sized integer expected at position `2` in `1`.
+		String str = IOFunctions.getMessage("intnm", F.List(ast, F.ZZ(pos)), EvalEngine.get());
+		throw new ArgumentTypeException(str);
+	}
 	/**
 	 * Check the expression, if it's a Java {@code int} value in the range [0 , Integer.MAX_VALUE]
 	 * 
diff --git a/symja_android_library/matheclipse-core/src/main/java/org/matheclipse/core/eval/util/Iterator.java b/symja_android_library/matheclipse-core/src/main/java/org/matheclipse/core/eval/util/Iterator.java
index 1fb37b4814..f81c9a2e1a 100644
--- a/symja_android_library/matheclipse-core/src/main/java/org/matheclipse/core/eval/util/Iterator.java
+++ b/symja_android_library/matheclipse-core/src/main/java/org/matheclipse/core/eval/util/Iterator.java
@@ -4,8 +4,10 @@
 import static org.matheclipse.core.expression.F.Less;
 import static org.matheclipse.core.expression.F.Subtract;
 
+import org.matheclipse.core.builtin.IOFunctions;
 import org.matheclipse.core.builtin.QuantityFunctions;
 import org.matheclipse.core.eval.EvalEngine;
+import org.matheclipse.core.eval.exception.ArgumentTypeException;
 import org.matheclipse.core.eval.exception.NoEvalException;
 import org.matheclipse.core.eval.exception.WrongArgumentType;
 import org.matheclipse.core.expression.F;
@@ -1029,7 +1031,7 @@ public void tearDown() {
 	 *            the evaluation engine
 	 * @return the iterator
 	 */
-	public static IIterator create(final IAST list, final EvalEngine engine) {
+	public static IIterator create(final IAST list, int position, final EvalEngine engine) {
 
 		EvalEngine evalEngine = engine;
 		IExpr lowerLimit;
@@ -1183,16 +1185,22 @@ public static IIterator create(final IAST list, final EvalEngine engine)
 				}
 
 				break;
-			default:
-				lowerLimit = null;
-				upperLimit = null;
-				step = null;
-				variable = null;
+			default: 
+					// Argument `1` at position `2` does not have the correct form for an iterator.
+					String str = IOFunctions.getMessage("itform", F.List(list, F.ZZ(position)), EvalEngine.get());
+					throw new ArgumentTypeException(str);
+				 
+				// lowerLimit = null;
+				// upperLimit = null;
+				// step = null;
+				// variable = null;
 			}
 
 			return new ExprIterator(variable, evalEngine, lowerLimit, upperLimit, step, fNumericMode);
 		} catch (RuntimeException rex) {
-			throw new ClassCastException();
+			// Argument `1` at position `2` does not have the correct form for an iterator.
+			String str = IOFunctions.getMessage("itform", F.List(list, F.ZZ(position)), EvalEngine.get());
+			throw new ArgumentTypeException(str);
 		} finally {
 			evalEngine.setNumericMode(localNumericMode);
 		}
diff --git a/symja_android_library/matheclipse-core/src/main/java/org/matheclipse/core/eval/util/LevelSpecification.java b/symja_android_library/matheclipse-core/src/main/java/org/matheclipse/core/eval/util/LevelSpecification.java
index 8920b2fd25..c030110cbb 100644
--- a/symja_android_library/matheclipse-core/src/main/java/org/matheclipse/core/eval/util/LevelSpecification.java
+++ b/symja_android_library/matheclipse-core/src/main/java/org/matheclipse/core/eval/util/LevelSpecification.java
@@ -1,10 +1,12 @@
 package org.matheclipse.core.eval.util;
 
+import org.matheclipse.core.builtin.IOFunctions;
+import org.matheclipse.core.eval.EvalEngine;
+import org.matheclipse.core.eval.exception.ArgumentTypeException;
 import org.matheclipse.core.expression.F;
 import org.matheclipse.core.interfaces.IAST;
 import org.matheclipse.core.interfaces.IExpr;
 import org.matheclipse.core.interfaces.IInteger;
-import org.matheclipse.parser.client.math.MathException;
 
 /**
  * Level specification for expression trees
@@ -27,17 +29,15 @@ public LevelSpecification() {
 	 * Create a LevelSpecification from an IInteger or IAST list-object.
*
* - * If expr is a non-negative IInteger iValue set Level - * {1,iValue};
+ * If expr is a non-negative IInteger iValue set Level {1,iValue};
* If expr is a negative IInteger iValue set Level {iValue, 0};
- * If expr is a List {i0Value, i1Value} set Level {i0Value, - * i1Value};
+ * If expr is a List {i0Value, i1Value} set Level {i0Value, i1Value};
* * @param expr * @param includeHeads - * TODO + * TODO * @throws MathException - * if the expr is not a level specification + * if the expr is not a level specification * @see */ public LevelSpecification(final IExpr expr, boolean includeHeads) { @@ -65,7 +65,7 @@ public LevelSpecification(final IExpr expr, boolean includeHeads) { if (lst.isAST1()) { if (lst.arg1() instanceof IInteger) { - final IInteger i = (IInteger) lst.arg1() ; + final IInteger i = (IInteger) lst.arg1(); if (i.isNegative()) { fFromDepth = i.toBigNumerator().intValue(); @@ -73,7 +73,9 @@ public LevelSpecification(final IExpr expr, boolean includeHeads) { fFromLevel = 0; fToLevel = Integer.MAX_VALUE; if (fToDepth < fFromDepth) { - throw new MathException("Invalid Level specification: " + expr.toString()); + String str = IOFunctions.getMessage("level", F.List(expr), EvalEngine.get()); + throw new ArgumentTypeException(str); + // throw new MathException("Invalid Level specification: " + expr.toString()); } } else { fToLevel = i.toBigNumerator().intValue(); @@ -81,23 +83,27 @@ public LevelSpecification(final IExpr expr, boolean includeHeads) { fFromDepth = Integer.MIN_VALUE; fToDepth = -1; if (fToLevel < fFromLevel) { - throw new MathException("Invalid Level specification: " + expr.toString()); + String str = IOFunctions.getMessage("level", F.List(expr), EvalEngine.get()); + throw new ArgumentTypeException(str); + // throw new MathException("Invalid Level specification: " + expr.toString()); } } return; } } else { if ((lst.isAST2())) { - if ((lst.arg1() instanceof IInteger) && (lst.arg2() instanceof IInteger)) { - final IInteger i0 = (IInteger) lst.arg1() ; - final IInteger i1 = (IInteger) lst.arg2() ; + if ((lst.arg1() instanceof IInteger) && (lst.arg2() instanceof IInteger)) { + final IInteger i0 = (IInteger) lst.arg1(); + final IInteger i1 = (IInteger) lst.arg2(); if (i0.isNegative() && i1.isNegative()) { fFromDepth = i0.toBigNumerator().intValue(); fToDepth = i1.toBigNumerator().intValue(); fFromLevel = 0; fToLevel = Integer.MAX_VALUE; } else if (i0.isNegative()) { - throw new MathException("Invalid Level specification: " + expr.toString()); + String str = IOFunctions.getMessage("level", F.List(expr), EvalEngine.get()); + throw new ArgumentTypeException(str); + // throw new MathException("Invalid Level specification: " + expr.toString()); } else if (i1.isNegative()) { fFromDepth = Integer.MIN_VALUE; fToDepth = i1.toBigNumerator().intValue(); @@ -110,10 +116,12 @@ public LevelSpecification(final IExpr expr, boolean includeHeads) { fToLevel = i1.toBigNumerator().intValue(); } return; - } else if ((lst.arg1() instanceof IInteger) && (lst.arg2() .isInfinity())) { - final IInteger i0 = (IInteger) lst.arg1() ; + } else if ((lst.arg1() instanceof IInteger) && (lst.arg2().isInfinity())) { + final IInteger i0 = (IInteger) lst.arg1(); if (i0.isNegative()) { - throw new MathException("Invalid Level specification: " + expr.toString()); + String str = IOFunctions.getMessage("level", F.List(expr), EvalEngine.get()); + throw new ArgumentTypeException(str); + // throw new MathException("Invalid Level specification: " + expr.toString()); } else { fFromDepth = Integer.MIN_VALUE; fToDepth = -1; @@ -132,7 +140,9 @@ public LevelSpecification(final IExpr expr, boolean includeHeads) { fToDepth = -1; return; } - throw new MathException("Invalid Level specification: " + expr.toString()); + String str = IOFunctions.getMessage("level", F.List(expr), EvalEngine.get()); + throw new ArgumentTypeException(str); + // throw new MathException("Invalid Level specification: " + expr.toString()); } /** diff --git a/symja_android_library/matheclipse-core/src/main/java/org/matheclipse/core/form/mathml/MathMLFormFactory.java b/symja_android_library/matheclipse-core/src/main/java/org/matheclipse/core/form/mathml/MathMLFormFactory.java index cfb2df55fe..5e5cb47817 100644 --- a/symja_android_library/matheclipse-core/src/main/java/org/matheclipse/core/form/mathml/MathMLFormFactory.java +++ b/symja_android_library/matheclipse-core/src/main/java/org/matheclipse/core/form/mathml/MathMLFormFactory.java @@ -13,6 +13,7 @@ import org.matheclipse.core.convert.AST2Expr; import org.matheclipse.core.eval.EvalAttributes; import org.matheclipse.core.eval.EvalEngine; +import org.matheclipse.core.eval.exception.ArgumentTypeException; import org.matheclipse.core.eval.util.Iterator; import org.matheclipse.core.expression.ASTRealMatrix; import org.matheclipse.core.expression.ASTRealVector; @@ -852,23 +853,27 @@ public boolean iteratorStep(final StringBuilder buf, final String mathSymbol, fi } fFactory.tagStart(buf, "mrow"); if (f.get(i).isList()) { - IIterator iterator = Iterator.create((IAST) f.get(i), EvalEngine.get()); - if (iterator.isValidVariable() && iterator.getStep().isOne()) { - fFactory.tagStart(buf, "munderover"); - fFactory.tag(buf, "mo", mathSymbol); + try { + IIterator iterator = Iterator.create((IAST) f.get(i), i, EvalEngine.get()); + if (iterator.isValidVariable() && iterator.getStep().isOne()) { + fFactory.tagStart(buf, "munderover"); + fFactory.tag(buf, "mo", mathSymbol); - fFactory.tagStart(buf, "mrow"); - fFactory.convertSymbol(buf, iterator.getVariable()); - fFactory.tag(buf, "mo", "="); - fFactory.convertInternal(buf, iterator.getLowerLimit(), Integer.MIN_VALUE, false); - fFactory.tagEnd(buf, "mrow"); - fFactory.convertInternal(buf, iterator.getUpperLimit(), Integer.MIN_VALUE, false); - fFactory.tagEnd(buf, "munderover"); - if (!iteratorStep(buf, mathSymbol, f, i + 1)) { - return false; + fFactory.tagStart(buf, "mrow"); + fFactory.convertSymbol(buf, iterator.getVariable()); + fFactory.tag(buf, "mo", "="); + fFactory.convertInternal(buf, iterator.getLowerLimit(), Integer.MIN_VALUE, false); + fFactory.tagEnd(buf, "mrow"); + fFactory.convertInternal(buf, iterator.getUpperLimit(), Integer.MIN_VALUE, false); + fFactory.tagEnd(buf, "munderover"); + if (!iteratorStep(buf, mathSymbol, f, i + 1)) { + return false; + } + fFactory.tagEnd(buf, "mrow"); + return true; } - fFactory.tagEnd(buf, "mrow"); - return true; + } catch (final ArgumentTypeException e) { + return false; } } else if (f.get(i).isSymbol()) { ISymbol symbol = (ISymbol) f.get(i); diff --git a/symja_android_library/matheclipse-core/src/main/java/org/matheclipse/core/form/tex/TeXFormFactory.java b/symja_android_library/matheclipse-core/src/main/java/org/matheclipse/core/form/tex/TeXFormFactory.java index 13e532285e..d6b5705097 100644 --- a/symja_android_library/matheclipse-core/src/main/java/org/matheclipse/core/form/tex/TeXFormFactory.java +++ b/symja_android_library/matheclipse-core/src/main/java/org/matheclipse/core/form/tex/TeXFormFactory.java @@ -10,6 +10,7 @@ import org.matheclipse.core.builtin.Algebra; import org.matheclipse.core.convert.AST2Expr; import org.matheclipse.core.eval.EvalEngine; +import org.matheclipse.core.eval.exception.ArgumentTypeException; import org.matheclipse.core.eval.util.Iterator; import org.matheclipse.core.expression.ASTRealMatrix; import org.matheclipse.core.expression.ApcomplexNum; @@ -861,21 +862,26 @@ public boolean iteratorStep(final StringBuilder buf, final String mathSymbol, fi return true; } if (f.get(i).isList()) { - IIterator iterator = Iterator.create((IAST) f.get(i), EvalEngine.get()); - if (iterator.isValidVariable() && iterator.getStep().isOne()) { - buf.append(mathSymbol); - buf.append("_{"); - fFactory.convertSubExpr(buf, iterator.getVariable(), 0); - buf.append(" = "); - fFactory.convertSubExpr(buf, iterator.getLowerLimit(), 0); - buf.append("}^{"); - fFactory.convertInternal(buf, iterator.getUpperLimit(), 0); - buf.append('}'); - if (!iteratorStep(buf, mathSymbol, f, i + 1)) { - return false; + try { + IIterator iterator = Iterator.create((IAST) f.get(i), i, EvalEngine.get()); + if (iterator.isValidVariable() && iterator.getStep().isOne()) { + buf.append(mathSymbol); + buf.append("_{"); + fFactory.convertSubExpr(buf, iterator.getVariable(), 0); + buf.append(" = "); + fFactory.convertSubExpr(buf, iterator.getLowerLimit(), 0); + buf.append("}^{"); + fFactory.convertInternal(buf, iterator.getUpperLimit(), 0); + buf.append('}'); + if (!iteratorStep(buf, mathSymbol, f, i + 1)) { + return false; + } + return true; } - return true; + } catch (ArgumentTypeException ate) { + // see Ietrator definition } + return false; } else if (f.get(i).isSymbol()) { ISymbol symbol = (ISymbol) f.get(i); buf.append(mathSymbol); diff --git a/symja_android_library/matheclipse-core/src/main/java/org/matheclipse/core/numbertheory/Primality.java b/symja_android_library/matheclipse-core/src/main/java/org/matheclipse/core/numbertheory/Primality.java index 21eeb48ccb..6ccfa53f68 100644 --- a/symja_android_library/matheclipse-core/src/main/java/org/matheclipse/core/numbertheory/Primality.java +++ b/symja_android_library/matheclipse-core/src/main/java/org/matheclipse/core/numbertheory/Primality.java @@ -1052,6 +1052,9 @@ public static boolean isPrimePower(BigInteger value) { if (value.compareTo(BigInteger.ZERO) < 0) { value = value.negate(); } + if (value.equals(BigInteger.ZERO)) { + return false; + } try { SortedMap map = new PrimePowerTreedMap(); factorInteger(value, map); diff --git a/symja_android_library/matheclipse-core/src/main/java/org/matheclipse/core/reflection/system/Product.java b/symja_android_library/matheclipse-core/src/main/java/org/matheclipse/core/reflection/system/Product.java index 6b414ee2a1..1d28891f91 100644 --- a/symja_android_library/matheclipse-core/src/main/java/org/matheclipse/core/reflection/system/Product.java +++ b/symja_android_library/matheclipse-core/src/main/java/org/matheclipse/core/reflection/system/Product.java @@ -8,6 +8,7 @@ import org.matheclipse.core.builtin.IOFunctions; import org.matheclipse.core.builtin.ListFunctions; import org.matheclipse.core.eval.EvalEngine; +import org.matheclipse.core.eval.exception.ArgumentTypeException; import org.matheclipse.core.eval.exception.RecursionLimitExceeded; import org.matheclipse.core.eval.exception.Validate; import org.matheclipse.core.eval.util.Iterator; @@ -129,7 +130,7 @@ public IExpr evaluate(final IAST ast, EvalEngine engine) { boolean flag = true; // Prod( i^a, {i,from,to},... ) for (int i = 2; i < ast.size(); i++) { - IIterator iterator = Iterator.create((IAST) ast.get(i), engine); + IIterator iterator = Iterator.create((IAST) ast.get(i), i, engine); if (iterator.isValidVariable() && exponent.isFree(iterator.getVariable())) { continue; } @@ -144,90 +145,91 @@ public IExpr evaluate(final IAST ast, EvalEngine engine) { } IExpr argN = ast.last(); if (ast.size() >= 3 && argN.isList()) { - if (arg1.isZero()) { - // Product(0, {k, n, m}) - return F.C0; - } - IIterator iterator = Iterator.create((IAST) argN, engine); - if (iterator.isValidVariable() && iterator.getUpperLimit().isInfinity()) { - if (arg1.isOne()) { - // Product(1, {k, a, Infinity}) - return F.C1; + try { + if (arg1.isZero()) { + // Product(0, {k, n, m}) + return F.C0; } - if (arg1.isPositiveResult() && arg1.isIntegerResult()) { - // Product(n, {k, a, Infinity}) ;n is positive integer - return F.CInfinity; + IIterator iterator = Iterator.create((IAST) argN, ast.argSize(), engine); + if (iterator.isValidVariable() && iterator.getUpperLimit().isInfinity()) { + if (arg1.isOne()) { + // Product(1, {k, a, Infinity}) + return F.C1; + } + if (arg1.isPositiveResult() && arg1.isIntegerResult()) { + // Product(n, {k, a, Infinity}) ;n is positive integer + return F.CInfinity; + } } - } - if (iterator.isValidVariable() && !iterator.isNumericFunction()) { - // if (iterator.getLowerLimit().isInteger() && iterator.getUpperLimit().isSymbol() - // && iterator.getStep().isOne()) { - if (iterator.getUpperLimit().isSymbol() && iterator.getStep().isOne()) { - final ISymbol var = iterator.getVariable(); - final IExpr from = iterator.getLowerLimit(); - final ISymbol to = (ISymbol) iterator.getUpperLimit(); - if (arg1.isPower()) { - IExpr base = arg1.base(); - if (base.isFree(var)) { - if (iterator.getLowerLimit().isOne()) { - IExpr exponent = arg1.exponent(); - if (exponent.equals(var)) { - // Prod( a^i, ..., {i,from,to} ) - if (ast.isAST2()) { - return F.Power(base, Times(C1D2, to, Plus(C1, to))); + if (iterator.isValidVariable() && !iterator.isNumericFunction()) { + // if (iterator.getLowerLimit().isInteger() && iterator.getUpperLimit().isSymbol() + // && iterator.getStep().isOne()) { + if (iterator.getUpperLimit().isSymbol() && iterator.getStep().isOne()) { + final ISymbol var = iterator.getVariable(); + final IExpr from = iterator.getLowerLimit(); + final ISymbol to = (ISymbol) iterator.getUpperLimit(); + if (arg1.isPower()) { + IExpr base = arg1.base(); + if (base.isFree(var)) { + if (iterator.getLowerLimit().isOne()) { + IExpr exponent = arg1.exponent(); + if (exponent.equals(var)) { + // Prod( a^i, ..., {i,from,to} ) + if (ast.isAST2()) { + return F.Power(base, Times(C1D2, to, Plus(C1, to))); + } + IASTAppendable result = ast.removeAtClone(ast.argSize()); + // result.remove(ast.argSize()); + result.set(1, F.Power(base, Times(C1D2, to, Plus(C1, to)))); + return result; } - IASTAppendable result = ast.removeAtClone(ast.argSize()); - // result.remove(ast.argSize()); - result.set(1, F.Power(base, Times(C1D2, to, Plus(C1, to)))); - return result; } } } - } - if (arg1.isFree(var)) { + if (arg1.isFree(var)) { - if (ast.isAST2()) { - if (from.isOne()) { - return F.Power(ast.arg1(), to); - } - if (from.isZero()) { - return F.Power(ast.arg1(), Plus(to, C1)); - } - if (from.isSymbol()) { - // 2^(1-from+to) - return F.Power(arg1, F.Plus(F.C1, from.negate(), to)); - } - } else { - IASTAppendable result = ast.removeAtClone(ast.argSize()); - // result.remove(ast.argSize()); - if (from.isOne()) { - result.set(1, F.Power(ast.arg1(), to)); - return result; - } - if (from.isZero()) { - result.set(1, F.Power(ast.arg1(), Plus(to, C1))); - return result; - } - if (from.isSymbol()) { - // 2^(1-from+to) - result.set(1, F.Power(arg1, F.Plus(F.C1, from.negate(), to))); - return result; - } + if (ast.isAST2()) { + if (from.isOne()) { + return F.Power(ast.arg1(), to); + } + if (from.isZero()) { + return F.Power(ast.arg1(), Plus(to, C1)); + } + if (from.isSymbol()) { + // 2^(1-from+to) + return F.Power(arg1, F.Plus(F.C1, from.negate(), to)); + } + } else { + IASTAppendable result = ast.removeAtClone(ast.argSize()); + // result.remove(ast.argSize()); + if (from.isOne()) { + result.set(1, F.Power(ast.arg1(), to)); + return result; + } + if (from.isZero()) { + result.set(1, F.Power(ast.arg1(), Plus(to, C1))); + return result; + } + if (from.isSymbol()) { + // 2^(1-from+to) + result.set(1, F.Power(arg1, F.Plus(F.C1, from.negate(), to))); + return result; + } + } } - } + } } - } - - try { + temp = F.NIL; IAST resultList = Times(); temp = evaluateLast(ast.arg1(), iterator, resultList, F.C1); if (!temp.isPresent() || temp.equals(resultList)) { return F.NIL; } + } catch (final ArgumentTypeException e) { } catch (RecursionLimitExceeded rle) { return engine.printMessage("Product: Recursionlimit exceeded"); } @@ -243,11 +245,11 @@ public IExpr evaluate(final IAST ast, EvalEngine engine) { } return F.NIL; } - + public int[] expectedArgSize() { return IOFunctions.ARGS_2_INFINITY; } - + @Override public IExpr numericEval(final IAST functionList, EvalEngine engine) { return evaluate(functionList, engine); diff --git a/symja_android_library/matheclipse-core/src/main/java/org/matheclipse/core/reflection/system/Sum.java b/symja_android_library/matheclipse-core/src/main/java/org/matheclipse/core/reflection/system/Sum.java index 4b94c8371f..757ea5f27d 100644 --- a/symja_android_library/matheclipse-core/src/main/java/org/matheclipse/core/reflection/system/Sum.java +++ b/symja_android_library/matheclipse-core/src/main/java/org/matheclipse/core/reflection/system/Sum.java @@ -24,6 +24,7 @@ import org.matheclipse.core.builtin.ListFunctions.TableGenerator; import org.matheclipse.core.convert.VariablesSet; import org.matheclipse.core.eval.EvalEngine; +import org.matheclipse.core.eval.exception.ArgumentTypeException; import org.matheclipse.core.eval.exception.RecursionLimitExceeded; import org.matheclipse.core.eval.exception.Validate; import org.matheclipse.core.eval.interfaces.IArrayFunction; @@ -168,22 +169,26 @@ public IExpr evaluate(final IAST ast, EvalEngine engine) { IIterator iterator = null; if (argN.isList()) { - argN = evalBlockWithoutReap(argN, varList); - iterator = Iterator.create((IAST) argN, engine); - // if (iterator.isSetIterator() || iterator.isNumericFunction()) { - // IAST resultList = Plus(); - // temp = evaluateLast(ast.arg1(), iterator, resultList, C0); - // if (temp.isPresent() && !temp.equals(resultList)) { - // if (ast.isAST2()) { - // return temp; - // } else { - // IAST result = ast.clone(); - // result.remove(ast.argSize()); - // result.set(1, temp); - // return result; - // } - // } - // } + try { + argN = evalBlockWithoutReap(argN, varList); + iterator = Iterator.create((IAST) argN, ast.argSize(), engine); + // if (iterator.isSetIterator() || iterator.isNumericFunction()) { + // IAST resultList = Plus(); + // temp = evaluateLast(ast.arg1(), iterator, resultList, C0); + // if (temp.isPresent() && !temp.equals(resultList)) { + // if (ast.isAST2()) { + // return temp; + // } else { + // IAST result = ast.clone(); + // result.remove(ast.argSize()); + // result.set(1, temp); + // return result; + // } + // } + // } + } catch (ArgumentTypeException ate) { + return F.NIL; + } } // arg1 = evalBlockExpandWithoutReap(ast.arg1(), varList); diff --git a/symja_android_library/matheclipse-core/src/main/java/org/matheclipse/core/visit/VisitorLevelSpecification.java b/symja_android_library/matheclipse-core/src/main/java/org/matheclipse/core/visit/VisitorLevelSpecification.java index 9029104819..332591b613 100644 --- a/symja_android_library/matheclipse-core/src/main/java/org/matheclipse/core/visit/VisitorLevelSpecification.java +++ b/symja_android_library/matheclipse-core/src/main/java/org/matheclipse/core/visit/VisitorLevelSpecification.java @@ -2,12 +2,13 @@ import java.util.function.Function; +import org.matheclipse.core.builtin.IOFunctions; import org.matheclipse.core.eval.EvalEngine; +import org.matheclipse.core.eval.exception.ArgumentTypeException; import org.matheclipse.core.eval.exception.Validate; import org.matheclipse.core.expression.F; import org.matheclipse.core.interfaces.IAST; import org.matheclipse.core.interfaces.IASTMutable; -import org.matheclipse.core.interfaces.IBuiltInSymbol; import org.matheclipse.core.interfaces.IComplex; import org.matheclipse.core.interfaces.IComplexNum; import org.matheclipse.core.interfaces.IExpr; @@ -18,7 +19,6 @@ import org.matheclipse.core.interfaces.IPatternSequence; import org.matheclipse.core.interfaces.IStringX; import org.matheclipse.core.interfaces.ISymbol; -import org.matheclipse.parser.client.math.MathException; /** * A level specification visitor for levels in abstract syntax trees (AST). @@ -73,11 +73,11 @@ public VisitorLevelSpecification(final Function function, final IE if (value.isNegative()) { fFromDepth = Integer.MIN_VALUE; - fToDepth = Validate.throwIntType(value,Integer.MIN_VALUE, engine); + fToDepth = Validate.throwIntType(value, Integer.MIN_VALUE, engine); fFromLevel = 1; fToLevel = Integer.MAX_VALUE; } else { - fToLevel = Validate.throwIntType(value,Integer.MIN_VALUE, engine); + fToLevel = Validate.throwIntType(value, Integer.MIN_VALUE, engine); fFromLevel = 1; fFromDepth = Integer.MIN_VALUE; fToDepth = -1; @@ -91,7 +91,7 @@ public VisitorLevelSpecification(final Function function, final IE if (lst.arg1() instanceof IInteger) { final IInteger i = (IInteger) lst.arg1(); - final int level = Validate.throwIntType(i,Integer.MIN_VALUE, engine); + final int level = Validate.throwIntType(i, Integer.MIN_VALUE, engine); if (i.isNegative()) { fFromDepth = level; fToDepth = level; @@ -111,37 +111,40 @@ public VisitorLevelSpecification(final Function function, final IE final IInteger i0 = (IInteger) lst.arg1(); final IInteger i1 = (IInteger) lst.arg2(); if (i0.isNegative() && i1.isNegative()) { - fFromDepth = Validate.throwIntType(i0,Integer.MIN_VALUE, engine); - fToDepth = Validate.throwIntType(i1,Integer.MIN_VALUE, engine); + fFromDepth = Validate.throwIntType(i0, Integer.MIN_VALUE, engine); + fToDepth = Validate.throwIntType(i1, Integer.MIN_VALUE, engine); fFromLevel = 0; fToLevel = Integer.MAX_VALUE; } else if (i0.isNegative()) { // all subexpressions at levels i0 or above with a depth of -i1 or less. - fFromDepth = Validate.throwIntType(i0,Integer.MIN_VALUE, engine); + fFromDepth = Validate.throwIntType(i0, Integer.MIN_VALUE, engine); fToDepth = -1; fFromLevel = 0; - fToLevel = Validate.throwIntType(i1,Integer.MIN_VALUE, engine); + fToLevel = Validate.throwIntType(i1, Integer.MIN_VALUE, engine); } else if (i1.isNegative()) { // all subexpressions at any level greater equal i0 that have a depth of -i1 or greater. fFromDepth = Integer.MIN_VALUE; - fToDepth = Validate.throwIntType(i1,Integer.MIN_VALUE, engine); - fFromLevel = Validate.throwIntType(i0,Integer.MIN_VALUE, engine); + fToDepth = Validate.throwIntType(i1, Integer.MIN_VALUE, engine); + fFromLevel = Validate.throwIntType(i0, Integer.MIN_VALUE, engine); fToLevel = Integer.MAX_VALUE; } else { fFromDepth = Integer.MIN_VALUE; fToDepth = -1; - fFromLevel = Validate.throwIntType(i0,Integer.MIN_VALUE, engine); - fToLevel = Validate.throwIntType(i1,Integer.MIN_VALUE, engine); + fFromLevel = Validate.throwIntType(i0, Integer.MIN_VALUE, engine); + fToLevel = Validate.throwIntType(i1, Integer.MIN_VALUE, engine); } return; } else if ((lst.arg1() instanceof IInteger) && (lst.arg2().isInfinity())) { final IInteger i0 = (IInteger) lst.arg1(); if (i0.isNegative()) { - throw new MathException("Invalid Level specification: " + levelExpr.toString()); + // Level specification `1` is not of the form n, {n}, or {m, n}. + String str = IOFunctions.getMessage("level", F.List(levelExpr), EvalEngine.get()); + throw new ArgumentTypeException(str); + // throw new MathException("Invalid Level specification: " + levelExpr.toString()); } else { fFromDepth = Integer.MIN_VALUE; fToDepth = -1; - fFromLevel = Validate.throwIntType(i0,Integer.MIN_VALUE, engine); + fFromLevel = Validate.throwIntType(i0, Integer.MIN_VALUE, engine); fToLevel = Integer.MAX_VALUE; } return; @@ -164,7 +167,10 @@ public VisitorLevelSpecification(final Function function, final IE fToDepth = -1; return; } - throw new MathException("Invalid Level specification: " + levelExpr.toString()); + // Level specification `1` is not of the form n, {n}, or {m, n}. + String str = IOFunctions.getMessage("level", F.List(levelExpr), EvalEngine.get()); + throw new ArgumentTypeException(str); + // throw new MathException("Invalid Level specification: " + levelExpr.toString()); } /** @@ -235,7 +241,7 @@ public boolean isInRange(int level, int depth) { */ @Override public IExpr visit(IInteger element) { - return visitAtom( element); + return visitAtom(element); } /** @@ -243,7 +249,7 @@ public IExpr visit(IInteger element) { */ @Override public IExpr visit(IFraction element) { - return visitAtom( element); + return visitAtom(element); } /** @@ -251,7 +257,7 @@ public IExpr visit(IFraction element) { */ @Override public IExpr visit(IComplex element) { - return visitAtom( element); + return visitAtom(element); } /** @@ -259,7 +265,7 @@ public IExpr visit(IComplex element) { */ @Override public IExpr visit(INum element) { - return visitAtom( element); + return visitAtom(element); } /** @@ -267,7 +273,7 @@ public IExpr visit(INum element) { */ @Override public IExpr visit(IComplexNum element) { - return visitAtom( element); + return visitAtom(element); } /** @@ -275,7 +281,7 @@ public IExpr visit(IComplexNum element) { */ @Override public IExpr visit(ISymbol element) { - return visitAtom( element); + return visitAtom(element); } /** @@ -283,7 +289,7 @@ public IExpr visit(ISymbol element) { */ @Override public IExpr visit(IPattern element) { - return visitAtom( element); + return visitAtom(element); } /** @@ -291,7 +297,7 @@ public IExpr visit(IPattern element) { */ @Override public IExpr visit(IPatternSequence element) { - return visitAtom( element); + return visitAtom(element); } /** @@ -299,7 +305,7 @@ public IExpr visit(IPatternSequence element) { */ @Override public IExpr visit(IStringX element) { - return visitAtom( element); + return visitAtom(element); } protected final IExpr visitAtom(IExpr element) { diff --git a/symja_android_library/matheclipse-core/src/test/java/org/matheclipse/core/fuzz/ExprEvaluatorTests.java b/symja_android_library/matheclipse-core/src/test/java/org/matheclipse/core/fuzz/ExprEvaluatorTests.java index 7aabaf628c..3b611fead4 100644 --- a/symja_android_library/matheclipse-core/src/test/java/org/matheclipse/core/fuzz/ExprEvaluatorTests.java +++ b/symja_android_library/matheclipse-core/src/test/java/org/matheclipse/core/fuzz/ExprEvaluatorTests.java @@ -5,9 +5,12 @@ import org.matheclipse.core.eval.ExprEvaluator; import org.matheclipse.core.eval.interfaces.IFunctionEvaluator; import org.matheclipse.core.expression.F; +import org.matheclipse.core.interfaces.IAST; import org.matheclipse.core.interfaces.IASTAppendable; import org.matheclipse.core.interfaces.IBuiltInSymbol; import org.matheclipse.core.interfaces.IEvaluator; +import org.matheclipse.core.interfaces.IExpr; +import org.matheclipse.core.interfaces.ISymbol; import org.matheclipse.parser.client.math.MathException; import junit.framework.TestCase; @@ -34,48 +37,48 @@ public void testFuzz001() { if (evaluator instanceof IFunctionEvaluator) { int[] argSize = ((IFunctionEvaluator) evaluator).expectedArgSize(); if (argSize != null) { - if (argSize[1] <= 10) { -// System.out.println(sym.toString() + "[" + argSize[0] + "," + argSize[1] + "]"); - IASTAppendable ast = F.ast(sym); - for (int j = 0; j < argSize[0]; j++) { - ast.append(F.Null); - } - eval = new ExprEvaluator(engine, true, 20); - try { - System.out.println(ast.toString()); - eval.eval(ast); - } catch (MathException mex) { - mex.printStackTrace(); - } catch (RuntimeException rex) { - System.out.println(ast.toString()); - rex.printStackTrace(); - fail(); - } - for (int j = argSize[0]; j < argSize[1]; j++) { - eval = new ExprEvaluator(engine, true, 20); - ast.append(F.Null); - try { - System.out.println(ast.toString()); - eval.eval(ast); - } catch (MathException mex) { - mex.printStackTrace(); - } catch (RuntimeException rex) { - System.out.println(ast.toString()); - rex.printStackTrace(); - fail(); - } - } + int end = argSize[1]; + if (end <= 10) { + int start = argSize[0]; + generateASTs(sym, start, end, F.C0, engine); + generateASTs(sym, start, end, F.Null, engine); + generateASTs(sym, start, end, F.List(), engine); + continue; } } } + generateASTs(sym, 1, 5, F.C0, engine); + generateASTs(sym, 1, 5, F.Null, engine); + generateASTs(sym, 1, 5, F.List(), engine); + } + } + + private void generateASTs(IBuiltInSymbol sym, int start, int end, IExpr arg, EvalEngine engine) { + ExprEvaluator eval; + for (int j = start; j <= end; j++) { + eval = new ExprEvaluator(engine, true, 20); + IAST ast = generate(sym, j,arg); + try { + System.out.println(ast.toString()); + eval.eval(ast); + } catch (MathException mex) { + System.out.println(ast.toString()); + mex.printStackTrace(); + System.out.println(); + } catch (RuntimeException rex) { + System.out.println(ast.toString()); + rex.printStackTrace(); + fail(); + } + } + } + private IAST generate(ISymbol sym, int numberOfArgs, IExpr arg) { + IASTAppendable ast = F.ast(sym); + for (int j = 0; j < numberOfArgs; j++) { + ast.append(arg); } - // String str = "sin(x)"; - // IExpr e = eval.eval(str); - // int i = 100; - // eval.defineVariable("x", (double) i); - // double result = e.evalDouble(); - // assertEquals(-0.5063656411097588, result, 0E-10); + return ast; } } diff --git a/symja_android_library/matheclipse-core/src/test/java/org/matheclipse/core/system/LowercaseTestCase.java b/symja_android_library/matheclipse-core/src/test/java/org/matheclipse/core/system/LowercaseTestCase.java index 95bc4cf870..ffceff685e 100644 --- a/symja_android_library/matheclipse-core/src/test/java/org/matheclipse/core/system/LowercaseTestCase.java +++ b/symja_android_library/matheclipse-core/src/test/java/org/matheclipse/core/system/LowercaseTestCase.java @@ -991,6 +991,8 @@ public void testArrayDepth() { } public void testArrayQ() { + check("ArrayQ({ })", // + "True"); check("ArrayQ({1, 2, 3, 4})", // "True"); check("ArrayQ({1, 2, {3}, 4})", // @@ -1018,6 +1020,12 @@ public void testArrayQ() { } public void testArrayReshape() { + check("ArrayReshape({}, {})", // + "0"); + check("ArrayReshape({a,b,c}, { })", // + "a"); + check("ArrayReshape({}, {1,2,3})", // + "{{{0,0,0},{0,0,0}}}"); check("ArrayReshape(Range(1000), {3, 2, 2})", // "{{{1,2},{3,4}},{{5,6},{7,8}},{{9,10},{11,12}}}"); check("ArrayReshape({a, b, c, d, e, f}, {2, 3})", // @@ -1961,6 +1969,8 @@ public void testBooleanConvert() { } public void testBooleanMinimize() { + check("BooleanMinimize(f(x))", // + "f(x)"); check("BooleanMinimize(Or(z,a, z))", // "a||z"); check("BooleanMinimize((a&&b&&!c)||(a&&!b&&c)||(a&&!c&&d)||(!a&&b&&c)||(b&&c&&!d)||(b&&!c&&d)||(!b&&c&&d))", // @@ -3290,6 +3300,8 @@ public void testConstant() { } public void testConstantArray() { + check("ConstantArray({},{})", // + "{}"); check("ConstantArray(a, 3)", // "{a,a,a}"); check("ConstantArray(a, {2, 3})", // @@ -6959,6 +6971,10 @@ public void testFactorSquareFree() { } public void testFactorSquareFreeList() { + check("FactorSquareFreeList(42)", // + "{{42,1}}"); + check("FactorSquareFreeList(x)", // + "{{1,1},{x,1}}"); check("FactorSquareFreeList(x^5 - x^3 - x^2 + 1)", // "{{-1+x,2},{1+2*x+2*x^2+x^3,1}}"); check("FactorSquareFreeList(x^8 + 11*x^7 + 43*x^6 + 59*x^5 - 35*x^4 - 151*x^3 - 63*x^2 + 81*x + 54)", // @@ -7458,8 +7474,8 @@ public void testFiveNum() { } public void testFixedPoint() { -// check("FixedPoint(Null, Null)", // -// "Recursion limit 256 exceeded at: Null"); + // check("FixedPoint(Null, Null)", // + // "Recursion limit 256 exceeded at: Null"); check("FixedPoint(Cos, 1.0)", // "0.739085"); check("FixedPoint(#+1 &, 1, 20)", // @@ -10483,11 +10499,11 @@ public void testJavaForm() { } public void testJSForm() { -// check("JSForm(Ramp(x))", // -// "((x>=0) ? x : ( 0 ))"); + // check("JSForm(Ramp(x))", // + // "((x>=0) ? x : ( 0 ))"); check("Piecewise({{x, 0 < x < 1}, {x^3, 1 < x < 2}}) // JSForm", // "((0=0&&y>=0&&z>=0},0})"); - + check("PiecewiseExpand(Ramp(x))", // "Piecewise({{x,x>=0},0})"); } @@ -16368,9 +16384,13 @@ public void testPrimeOmega() { } public void testPrimePowerQ() { + check("PrimePowerQ(0)", // + "False"); check("PrimePowerQ(1)", // "False"); - + check("PrimePowerQ(-1)", // + "False"); + check("13^9", // "10604499373"); check("PrimePowerQ(10604499373)", // @@ -16673,6 +16693,8 @@ public void testProductLog() { } public void testProjection() { + check("Projection({},{})", // + "{}"); check("Projection({5, 6, 7}, {1, 0, 0})", // "{5,0,0}"); check("Projection({5, 6, 7}, {1, 1, 1})", // @@ -18148,6 +18170,10 @@ public void testRoots() { } public void testRotateLeft() { + check("RotateLeft({})", // + "{}"); + check("RotateLeft({a,b,c}, 5)", // + "{c,a,b}"); check("RotateLeft({1, 2, 3})", // "{2,3,1}"); check("RotateLeft(Range(10),3)", // @@ -18161,6 +18187,10 @@ public void testRotateLeft() { } public void testRotateRight() { + check("RotateRight({})", // + "{}"); + check("RotateRight({a,b,c}, 5)", // + "{b,c,a}"); check("RotateRight({1, 2, 3})", // "{3,1,2}"); check("RotateRight(Range(10),3)", //