package org.matheclipse.core.reflection.system;
import org.matheclipse.core.basic.Config;
import org.matheclipse.core.eval.exception.JASConversionException;
import org.matheclipse.core.eval.exception.Validate;
import org.matheclipse.core.eval.interfaces.AbstractFunctionEvaluator;
import org.matheclipse.core.expression.F;
import org.matheclipse.core.interfaces.IAST;
import org.matheclipse.core.interfaces.IExpr;
import org.matheclipse.core.interfaces.ISymbol;
import org.matheclipse.core.visit.VisitorExpr;
import org.matheclipse.parser.client.SyntaxError;
/**
*
*/
public class Together extends AbstractFunctionEvaluator {
/**
*
*/
static class TogetherVisitor extends VisitorExpr {
/**
*
*/
public TogetherVisitor() {
super();
}
@Override
public IExpr visit(IAST ast) {
IExpr temp = visitAST(ast);
IAST astTemp = ast;
if (temp != null) {
if (temp.isAST()) {
astTemp = (IAST) temp;
} else {
return temp;
}
}
if (astTemp.isPlus()) {
return visitPlus(astTemp);
} else if (astTemp.isTimes() || astTemp.isPower()) {
try {
return Cancel.cancelPowerTimes(astTemp);
} catch (JASConversionException jce) {
if (Config.DEBUG) {
jce.printStackTrace();
}
}
}
return astTemp;
}
private IExpr visitPlus(IAST plusAST) {
if (plusAST.size() <= 1) {
return plusAST;
}
IAST ni;
IExpr temp;
IAST numer = F.ast(F.Plus, plusAST.size(), false);
IAST denom = F.ast(F.Times, plusAST.size(), false);
for (int i = 1; i < plusAST.size(); i++) {
numer.add(i, F.eval(F.Numerator(plusAST.get(i))));
denom.add(i, F.eval(F.Denominator(plusAST.get(i))));
}
for (int i = 1; i < plusAST.size(); i++) {
ni = F.Times(numer.get(i));
for (int j = 1; j < plusAST.size(); j++) {
if (i == j) {
continue;
}
temp = denom.get(j);
if (!temp.equals(F.C1)) {
ni.add(temp);
}
}
numer.set(i, ni);
}
int i = 1;
while (denom.size() > i) {
if (denom.get(i).equals(F.C1)) {
denom.remove(i);
continue;
}
i++;
}
// System.out.println(numer.toString());
IExpr exprNumerator = F.evalExpandAll(numer);
if (denom.size() == 1) {
return exprNumerator;
}
IExpr exprDenominator = F.evalExpandAll(denom);
if (!exprDenominator.equals(F.C1)) {
try {
IExpr[] result = Cancel.cancelGCD(exprNumerator, exprDenominator);
if (result != null) {
return F.Times(result[0], result[1], F.Power(result[2], F.CN1));
}
} catch (JASConversionException jce) {
if (Config.DEBUG) {
jce.printStackTrace();
}
}
}
return F.Times(exprNumerator, F.Power(exprDenominator, F.CN1));
}
}
private static final TogetherVisitor VISITOR = new TogetherVisitor();
public Together() {
}
@Override
public IExpr evaluate(final IAST ast) {
Validate.checkSize(ast, 2);
if (ast.arg1().isAST()) {
IExpr expr = together((IAST) ast.arg1());
if (expr != null) {
return expr;
}
}
return ast.arg1();
}
public static IExpr together(IAST ast) {
return F.eval(ast.accept(VISITOR));
}
@Override
public void setUp(final ISymbol symbol) throws SyntaxError {
symbol.setAttributes(ISymbol.LISTABLE);
super.setUp(symbol);
}
}
Ads help maintain this website.