use of org.matheclipse.core.interfaces.IPatternObject in project symja_android_library by axkr.
the class PatternMap method determinePatternsRecursive.
/**
* Determine all patterns (i.e. all objects of instance IPattern) in the
* given expression
*
* Increments this classes pattern counter.
*
* @param patternIndexMap
* @param lhsPatternExpr
* the (left-hand-side) expression which could contain pattern
* objects.
* @param treeLevel
* TODO
*/
private int determinePatternsRecursive(Map<IExpr, Integer> patternIndexMap, final IAST lhsPatternExpr, int treeLevel) {
final IAST ast = lhsPatternExpr;
if (lhsPatternExpr.isAST(F.Except, 2, 3)) {
fRuleWithoutPattern = false;
}
int listEvalFlags = IAST.NO_FLAG;
for (int i = 0; i < ast.size(); i++) {
IExpr temp = ast.get(i);
if (temp.isAST()) {
listEvalFlags |= determinePatternsRecursive(patternIndexMap, (IAST) temp, treeLevel + 1);
fPriority -= 11;
} else if (temp instanceof IPatternObject) {
int[] result = ((IPatternObject) temp).addPattern(this, patternIndexMap);
listEvalFlags |= result[0];
fPriority -= result[1];
} else {
fPriority -= (50 - treeLevel);
}
}
ast.setEvalFlags(listEvalFlags);
// listEvalFlags &= IAST.CONTAINS_NO_DEFAULT_PATTERN_MASK;
return listEvalFlags;
}
use of org.matheclipse.core.interfaces.IPatternObject in project symja_android_library by axkr.
the class PatternSequence method equivalent.
/**
* Check if the two left-hand-side pattern expressions are equivalent. (i.e.
* <code>f[x_,y_]</code> is equivalent to <code>f[a_,b_]</code> )
*
* @param patternExpr2
* @param pm1
* @param pm2
* @return
*/
@Override
public boolean equivalent(final IPatternObject patternExpr2, final PatternMap pm1, PatternMap pm2) {
if (this == patternExpr2) {
return true;
}
if (patternExpr2 instanceof PatternSequence) {
// test if the pattern indices are equal
final IPatternSequence p2 = (IPatternSequence) patternExpr2;
if (getIndex(pm1) != p2.getIndex(pm2)) {
return false;
}
// test if the "check" expressions are equal
final Object o1 = getCondition();
final Object o2 = p2.getCondition();
if ((o1 == null) || (o2 == null)) {
return o1 == o2;
}
return o1.equals(o2);
}
return false;
}
use of org.matheclipse.core.interfaces.IPatternObject in project symja_android_library by axkr.
the class PatternMatcher method equivalent.
/**
* Check if the two left-hand-side pattern expressions are equivalent. (i.e. <code>f[x_,y_]</code> is equivalent to
* <code>f[a_,b_]</code> )
*
* @param patternExpr1
* @param patternExpr2
* @param pm1
* @param pm2
* @return
*/
public static boolean equivalent(final IExpr patternExpr1, final IExpr patternExpr2, final PatternMap pm1, PatternMap pm2) {
if (patternExpr1 == patternExpr2) {
return true;
}
if (!patternExpr1.isPatternExpr()) {
if (!patternExpr2.isPatternExpr()) {
return patternExpr1.equals(patternExpr2);
}
return false;
}
if (patternExpr1.isAST()) {
if (patternExpr2.isAST()) {
final IAST l1 = (IAST) patternExpr1;
final IAST l2 = (IAST) patternExpr2;
if (l1.size() != l2.size()) {
return false;
}
IExpr temp1, temp2;
for (int i = 0; i < l1.size(); i++) {
temp1 = l1.get(i);
temp2 = l2.get(i);
if (temp1 == temp2) {
continue;
}
if (temp1.hashCode() != temp2.hashCode()) {
if (temp1.isPatternExpr() && temp2.isPatternExpr()) {
if (!equivalent(temp1, temp2, pm1, pm2)) {
return false;
} else {
continue;
}
}
return false;
}
if (!temp1.isPatternExpr() || !temp2.isPatternExpr()) {
if (!temp1.equals(temp2)) {
return false;
}
}
if (!equivalent(temp1, temp2, pm1, pm2)) {
return false;
}
}
return true;
}
return false;
}
if (patternExpr1 instanceof IPatternObject) {
if (patternExpr2 instanceof IPatternObject) {
return ((IPatternObject) patternExpr1).equivalent((IPatternObject) patternExpr2, pm1, pm2);
}
return false;
}
return patternExpr1.equals(patternExpr2);
}
use of org.matheclipse.core.interfaces.IPatternObject in project symja_android_library by axkr.
the class EvalEngine method evalASTArg1.
/**
* Evaluate an AST with only one argument (i.e. <code>head[arg1]</code>). The evaluation steps are
* controlled by the header attributes.
*
* @param ast
* @return
*/
private IExpr evalASTArg1(final IAST ast) {
// special case ast.isAST1()
// head == ast[0] --- arg1 == ast[1]
IExpr result = ast.head().evaluateHead(ast, this);
if (result.isPresent()) {
return result;
}
final ISymbol symbol = ast.topHead();
final int attributes = symbol.getAttributes();
if ((attributes & ISymbol.SEQUENCEHOLD) != ISymbol.SEQUENCEHOLD) {
if ((result = F.flattenSequence(ast)).isPresent()) {
return result;
}
}
if ((result = evalArgs(ast, attributes)).isPresent()) {
return result;
}
final IExpr arg1 = ast.arg1();
if (ISymbol.hasFlatAttribute(attributes)) {
if (arg1.head().equals(symbol)) {
// associative
return arg1;
}
if (arg1.isUnevaluated() && arg1.first().head().equals(symbol) && arg1.first().isAST()) {
IAST unevaluated = (IAST) arg1.first();
return unevaluated.map(symbol, x -> F.Unevaluated(x));
}
}
if ((ISymbol.LISTABLE & attributes) == ISymbol.LISTABLE) {
if (symbol.isBuiltInSymbol()) {
if (arg1.isRealVector() && ((IAST) arg1).size() > 1) {
final IEvaluator module = ((IBuiltInSymbol) symbol).getEvaluator();
if (module instanceof DoubleUnaryOperator) {
DoubleUnaryOperator oper = (DoubleUnaryOperator) module;
return ASTRealVector.map((IAST) arg1, oper);
}
} else if (arg1.isRealMatrix()) {
final IEvaluator module = ((IBuiltInSymbol) symbol).getEvaluator();
if (module instanceof DoubleUnaryOperator) {
DoubleUnaryOperator oper = (DoubleUnaryOperator) module;
return ASTRealMatrix.map((IAST) arg1, oper);
}
}
if (arg1.isList()) {
// thread over the list
return EvalAttributes.threadList(ast, S.List, ast.head(), ((IAST) arg1).argSize());
} else if (arg1.isAssociation()) {
// thread over the association
return ((IAssociation) arg1).mapThread(ast, 1);
} else if (arg1.isSparseArray()) {
return ((ISparseArray) arg1).mapThread(ast, 1);
} else if (arg1.isConditionalExpression()) {
IExpr temp = ast.extractConditionalExpression(true);
if (temp.isPresent()) {
return temp;
}
}
}
}
if ((ISymbol.NUMERICFUNCTION & attributes) == ISymbol.NUMERICFUNCTION) {
if (ast.arg1().isIndeterminate()) {
return S.Indeterminate;
}
}
if (!(arg1 instanceof IPatternObject) && arg1.isPresent()) {
ISymbol lhsSymbol = arg1.isSymbol() ? (ISymbol) arg1 : arg1.topHead();
return lhsSymbol.evalUpRules(ast, this);
}
return F.NIL;
}
use of org.matheclipse.core.interfaces.IPatternObject in project symja_android_library by axkr.
the class EvalEngine method evalSetAttributesRecursive.
private IExpr evalSetAttributesRecursive(IAST ast, boolean noEvaluation, boolean evalNumericFunction, int level) {
// final ISymbol symbol = ast.topHead();
IExpr head = ast.head();
if (!(head instanceof IPatternObject) && !noEvaluation) {
IExpr headResult = head.evaluate(this);
if (headResult.isPresent()) {
ast = ast.apply(headResult);
head = headResult;
}
}
ISymbol symbol = head.topHead();
if (head.isSymbol()) {
symbol = (ISymbol) head;
}
if (symbol.isBuiltInSymbol()) {
// call so that attributes may be set in
// AbstractFunctionEvaluator#setUp() method
((IBuiltInSymbol) symbol).getEvaluator();
}
int headID = ast.headID();
if (headID >= 0) {
if (headID == ID.Blank || headID == ID.BlankSequence || headID == ID.BlankNullSequence || headID == ID.Pattern || headID == ID.Optional || headID == ID.OptionsPattern || headID == ID.Repeated || headID == ID.RepeatedNull) {
return ((IFunctionEvaluator) ((IBuiltInSymbol) ast.head()).getEvaluator()).evaluate(ast, this);
}
}
final int attributes = symbol.getAttributes();
IASTMutable resultList = F.NIL;
if ((ISymbol.HOLDALL & attributes) != ISymbol.HOLDALL) {
final int astSize = ast.size();
if ((ISymbol.HOLDFIRST & attributes) == ISymbol.NOATTRIBUTE) {
// the HoldFirst attribute isn't set here
if (astSize > 1) {
IExpr expr = ast.arg1();
if (expr.isAST()) {
resultList = evalSetAttributeArg(ast, 1, (IAST) expr, resultList, noEvaluation, level);
} else if (!(expr instanceof IPatternObject) && !noEvaluation) {
IExpr temp = expr.evaluate(this);
if (temp.isPresent()) {
resultList = ast.setAtCopy(1, temp);
}
}
}
}
if (astSize > 2) {
if ((ISymbol.HOLDREST & attributes) == ISymbol.NOATTRIBUTE) {
// the HoldRest attribute isn't set here
for (int i = 2; i < astSize; i++) {
IExpr expr = ast.get(i);
if (expr.isAST()) {
resultList = evalSetAttributeArg(ast, i, (IAST) expr, resultList, noEvaluation, level);
} else if (!(expr instanceof IPatternObject) && !noEvaluation) {
IExpr temp = expr.evaluate(this);
if (temp.isPresent()) {
if (resultList.isPresent()) {
resultList.set(i, temp);
} else {
resultList = ast.setAtCopy(i, temp);
}
}
}
}
}
}
if (evalNumericFunction && ((ISymbol.HOLDALL & attributes) == ISymbol.NOATTRIBUTE)) {
IAST f = resultList.orElse(ast);
if (f.isNumericFunction(true)) {
IExpr temp = evalLoop(f);
if (temp.isPresent()) {
return temp;
}
}
}
}
if (resultList.isPresent()) {
if (resultList.size() > 2) {
if (ISymbol.hasFlatAttribute(attributes)) {
// associative
IASTAppendable result;
if ((result = EvalAttributes.flattenDeep(resultList)).isPresent()) {
return evalSetOrderless(result, attributes, noEvaluation, level);
}
}
IExpr expr = evalSetOrderless(resultList, attributes, noEvaluation, level);
if (expr.isPresent()) {
return expr;
}
}
return resultList;
}
if ((ast.getEvalFlags() & IAST.IS_FLATTENED_OR_SORTED_MASK) != 0x0000) {
// already flattened or sorted
return ast;
}
if (ISymbol.hasFlatAttribute(attributes)) {
// associative
IASTAppendable result;
if ((result = EvalAttributes.flattenDeep(ast)).isPresent()) {
return evalSetOrderless(result, attributes, noEvaluation, level);
}
}
return evalSetOrderless(ast, attributes, noEvaluation, level);
}
Aggregations