@Override public IExpr evaluate(final IAST ast) { Validate.checkRange(ast, 3); if (ast.size() == 3 && ast.get(2).isList() && ((IAST) ast.get(2)).size() == 4) { IAST list = (IAST) ast.get(2); if (ast.get(1).isPlus()) { return ((IAST) ast.get(1)).map(Functors.replace1st(F.Sum(F.Null, ast.get(2)))); } if (list.get(1).isSymbol() && list.get(2).isInteger() && list.get(3).isSymbol()) { final ISymbol var = (ISymbol) list.get(1); final IInteger from = (IInteger) list.get(2); final ISymbol to = (ISymbol) list.get(3); if (ast.get(1).isFree(var, true) && ast.get(1).isFree(to, true)) { if (from.equals(F.C1)) { return F.Times(to, ast.get(1)); } if (from.equals(F.C0)) { return F.Times(Plus(to, C1), ast.get(1)); } } else { if (ast.get(1).isTimes()) { // Sum[ Times[a,b,c,...], {var, from, to} ] IAST filterCollector = F.Times(); IAST restCollector = F.Times(); ((IAST) ast.get(1)) .filter( filterCollector, restCollector, new Predicate<IExpr>() { @Override public boolean apply(IExpr input) { return input.isFree(var, true) && input.isFree(to, true); } }); if (filterCollector.size() > 1) { if (restCollector.size() == 2) { filterCollector.add(F.Sum(restCollector.get(1), ast.get(2))); } else { filterCollector.add(F.Sum(restCollector, ast.get(2))); } return filterCollector; } } if (from.equals(F.C0)) { IExpr repl = ast.get(1).replaceAll(F.List(F.Rule(var, F.Slot(F.C1)), F.Rule(to, F.Slot(F.C2)))); if (repl != null) { IExpr temp = MAP_0_N.get(repl); if (temp != null) { return temp.replaceAll(F.Rule(F.Slot(F.C1), to)); } } } } if (from.isPositive()) { return F.Subtract( F.Sum(ast.get(1), F.List(var, C0, to)), F.Sum(ast.get(1), F.List(var, C0, from.minus(F.C1)))); } } } IAST resultList = Plus(); IExpr temp = evaluateTable(ast, resultList, C0); if (temp.equals(resultList)) { return null; } return temp; }
@Override public void setUp(final ISymbol symbol) throws SyntaxError { symbol.setAttributes(ISymbol.LISTABLE); REPLACE_RULES = Functors.rules(REPLACE_STRINGS); super.setUp(symbol); }