package org.matheclipse.core.builtin.function;
import java.util.IdentityHashMap;
import java.util.Map;
import org.matheclipse.core.basic.Config;
import org.matheclipse.core.eval.EvalEngine;
import org.matheclipse.core.eval.exception.Validate;
import org.matheclipse.core.eval.interfaces.AbstractCoreFunctionEvaluator;
import org.matheclipse.core.expression.F;
import org.matheclipse.core.generic.Functors;
import org.matheclipse.core.interfaces.IAST;
import org.matheclipse.core.interfaces.IExpr;
import org.matheclipse.core.interfaces.ISymbol;
import org.matheclipse.parser.client.math.MathException;
public class Module extends AbstractCoreFunctionEvaluator {
public Module() {
}
/**
*
*/
@Override
public IExpr evaluate(final IAST ast) {
Validate.checkSize(ast, 3);
if (ast.arg1().isList()) {
IAST lst = (IAST) ast.arg1();
IExpr arg2 = ast.get(2);
final EvalEngine engine = EvalEngine.get();
return evalModule(lst, arg2, engine);
}
return null;
}
/**
* Check the (possible nested) module condition in pattern matcher without evaluating a result.
*
* @param arg1
* @param arg2
* @param engine
* @return
*/
public static boolean checkModuleCondition(IExpr arg1, IExpr arg2, final EvalEngine engine) {
if (arg1.isList()) {
IAST intializerList = (IAST) arg1;
final int moduleCounter = engine.incModuleCounter();
final String varAppend = "$" + moduleCounter;
// final IAST lst = (IAST) ast.arg1();
final java.util.Map moduleVariables = new IdentityHashMap();
try {
rememberVariables(intializerList, engine, varAppend, moduleVariables);
IExpr result = F.subst(arg2, Functors.rules(moduleVariables));
if (result.isCondition()) {
return Condition.checkCondition(result.getAt(1), result.getAt(2), engine);
} else if (result.isModule()) {
return checkModuleCondition(result.getAt(1), result.getAt(2), engine);
}
} finally {
engine.removeUserVariables(moduleVariables);
}
}
return true;
}
/**
* Module[{variablesList}, rhs ]
*
* @param intializerList
* @param arg2
* @param engine
* @return
*/
private static IExpr evalModule(IAST intializerList, IExpr arg2, final EvalEngine engine) {
final int moduleCounter = engine.incModuleCounter();
final String varAppend = "$" + moduleCounter;
final java.util.Map moduleVariables = new IdentityHashMap();
try {
rememberVariables(intializerList, engine, varAppend, moduleVariables);
IExpr temp = engine.evaluate(F.subst(arg2, Functors.rules(moduleVariables)));
return temp;
} finally {
engine.removeUserVariables(moduleVariables);
}
}
private static void rememberVariables(IAST variablesList, final EvalEngine engine, final String varAppend,
final java.util.Map variables) {
ISymbol oldSymbol;
ISymbol newSymbol;
// remember which local variables we use:
for (int i = 1; i < variablesList.size(); i++) {
if (variablesList.get(i).isSymbol()) {
oldSymbol = (ISymbol) variablesList.get(i);
newSymbol = F.$s(oldSymbol.toString() + varAppend);
variables.put(oldSymbol, newSymbol);
newSymbol.pushLocalVariable();
} else {
if (variablesList.get(i).isAST(F.Set, 3)) {
final IAST setFun = (IAST) variablesList.get(i);
if (setFun.arg1().isSymbol()) {
oldSymbol = (ISymbol) setFun.arg1();
newSymbol = F.$s(oldSymbol.toString() + varAppend);
variables.put(oldSymbol, newSymbol);
IExpr rightHandSide = setFun.arg2();
try {
rightHandSide = engine.evaluate(rightHandSide);
} catch (MathException me) {
if (Config.DEBUG) {
me.printStackTrace();
}
}
newSymbol.pushLocalVariable(rightHandSide);
}
}
}
}
}
@Override
public void setUp(ISymbol symbol) {
symbol.setAttributes(ISymbol.HOLDALL);
}
}
Ads help maintain this website.