package org.matheclipse.core.eval;
import java.io.Writer;
import org.matheclipse.core.basic.Config;
import org.matheclipse.core.convert.AST2Expr;
import org.matheclipse.core.interfaces.IAST;
import org.matheclipse.core.interfaces.IExpr;
import org.matheclipse.parser.client.Parser;
import org.matheclipse.parser.client.SyntaxError;
import org.matheclipse.parser.client.ast.ASTNode;
import org.matheclipse.parser.client.math.MathException;
import com.google.common.base.Predicate;
/**
* Utility to evaluate math expressions.
*
*/
public class EvalUtilities extends MathMLUtilities {
/**
* Constructor for an object which evaluates an expression. By default the internal EvalEngine didn't create a
* history list for the Out[] function.
*
* @param evalEngine
* @param mathMTagPrefix
* if set to true use "m:" as tag prefix for the MathML output.
* @param relaxedSyntax
*/
public EvalUtilities() {
this(new EvalEngine(), false, false);
}
/**
* Constructor for an object which evaluates an expression.
*
* @param mathMTagPrefix
* if set to true use "m:" as tag prefix for the MathML output.
* @param relaxedSyntax
* if set to true use "(...)" instead of "[...]" for function arguments (i.e.
* sin(...) instead of sin[...]).
*/
public EvalUtilities(final boolean mathMTagPrefix, final boolean relaxedSyntax) {
this(new EvalEngine(relaxedSyntax), mathMTagPrefix, relaxedSyntax);
}
/**
* Constructor for an object which evaluates an expression.
*
* @param evalEngine
* @param mathMTagPrefix
* if set to true use "m:" as tag prefix for the MathML output.
* @param relaxedSyntax
* if set to true use "(...)" instead of "[...]" for function arguments (i.e.
* sin(...) instead of sin[...]).
*/
public EvalUtilities(final EvalEngine evalEngine, final boolean mathMTagPrefix, final boolean relaxedSyntax) {
super(evalEngine, mathMTagPrefix, relaxedSyntax);
}
/**
* Evaluate the inputExpression and return the resulting expression.
*
* @param inputExpression
* the expression which should be evaluated.
* @return null, if the inputExpression is null
*
*/
public IExpr evaluate(final String inputExpression) throws MathException {
if (inputExpression != null) {
startRequest();
fEvalEngine.reset();
IExpr parsedExpression = fEvalEngine.parse(inputExpression);
if (parsedExpression != null) {
fEvalEngine.reset();
IExpr temp = fEvalEngine.evaluate(parsedExpression);
fEvalEngine.addOut(temp);
return temp;
}
}
return null;
}
/**
* Evaluate the inputExpression and return the resulting expression.
* The parser first tries (independently from the settings in the evalEngine) to parse the expression in the
* "relaxed mode" (i.e. "common math expression syntax" with parentheses for function arguments) and if that
* results in a SyntaxError exception it tries to parse in the "stronger mode" (i.e. with square brackets
* for function arguments).
* Note that after the second parser step this method may also throw a SyntaxError exception.
*
* @param inputExpression
* the expression which should be evaluated.
* @param evalEngine
* the evaluation engine which should be used
* @return null, if the inputExpression is null
* @throw org.matheclipse.parser.client.SyntaxError
* @throw org.matheclipse.parser.client.math.MathException
*/
public static IExpr eval(final String inputExpression, final EvalEngine evalEngine) throws MathException {
if (inputExpression != null) {
EvalEngine.set(evalEngine);
boolean SIMPLE_SYNTAX = true;
ASTNode node = null;
try {
Parser parser = new Parser(SIMPLE_SYNTAX);
node = parser.parse(inputExpression);
} catch (SyntaxError se1) {
try {
SIMPLE_SYNTAX = false;
Parser parser = new Parser(SIMPLE_SYNTAX);
node = parser.parse(inputExpression);
} catch (SyntaxError se2) {
throw se1;
}
}
if (node != null) {
IExpr parsedExpression = AST2Expr.CONST.convert(node);
if (parsedExpression != null) {
evalEngine.reset();
IExpr temp = evalEngine.evaluate(parsedExpression);
evalEngine.addOut(temp);
return temp;
}
}
}
return null;
};
/**
* Evaluate the parsedExpression and return the resulting expression.
*
* @param parsedExpression
* the expression which should be evaluated.
* @return
*/
public IExpr evaluate(final IExpr parsedExpression) throws MathException {
if (parsedExpression != null) {
startRequest();
fEvalEngine.reset();
IExpr temp = fEvalEngine.evaluate(parsedExpression);
fEvalEngine.addOut(temp);
return temp;
}
return null;
}
/**
* Converts the inputExpression string into a MathML expression and writes the result to the given Writer
*
* @param inputExpression
* @param out
*/
public String toJavaForm(final String inputExpression) throws MathException {
IExpr parsedExpression = null;
ASTNode node;
if (inputExpression != null) {
node = fEvalEngine.parseNode(inputExpression);
parsedExpression = AST2Expr.CONST.convert(node);
return parsedExpression.internalFormString(false, 0);
}
return "";
}
/**
* Evaluate the inputExpression and return the Trace[inputExpression] (i.e. all (sub-)expressions
* needed to calculate the result).
*
* @param inputExpression
* the expression which should be evaluated.
* @param matcher
* a filter which determines the expressions which should be traced, If the matcher is set to null, all
* expressions are traced.
* @param list
* an IAST object which will be cloned for containing the traced expressions. Typically a F.List() will
* be used.
* @return
*/
public IAST evalTrace(final String inputExpression, Predicate matcher, IAST list) throws MathException {
IExpr parsedExpression = null;
if (inputExpression != null) {
// try {
startRequest();
fEvalEngine.reset();
parsedExpression = fEvalEngine.parse(inputExpression);
if (parsedExpression != null) {
fEvalEngine.reset();
IAST temp = fEvalEngine.evalTrace(parsedExpression, matcher, list);
fEvalEngine.addOut(temp);
return temp;
}
}
return null;
}
/**
* Evaluate the parsedExpression and return the Trace[parsedExpression] (i.e. all (sub-)expressions
* needed to calculate the result).
*
* @param parsedExpression
* the expression which should be evaluated.
* @param matcher
* a filter which determines the expressions which should be traced, If the matcher is set to null, all
* expressions are traced.
* @param list
* an IAST object which will be cloned for containing the traced expressions. Typically a F.List() will
* be used.
* @return
*/
public IAST evalTrace(final IExpr parsedExpression, Predicate matcher, IAST list) throws RuntimeException {
if (parsedExpression != null) {
startRequest();
fEvalEngine.reset();
IAST temp = fEvalEngine.evalTrace(parsedExpression, matcher, list);
return temp;
}
return null;
}
/** {@inheritDoc} */
@Override
synchronized public void toMathML(final String inputExpression, final Writer out) {
try {
final IExpr result = evaluate(inputExpression);
if (result != null) {
toMathML(result, out);
}
} catch (final Throwable e) {
if (Config.SHOW_STACKTRACE) {
e.printStackTrace();
}
}
}
}
Ads help maintain this website.