use of org.matheclipse.core.interfaces.IPatternObject in project symja_android_library by axkr.
the class PatternMatcher method removeFlat.
/**
* Remove parts which are "free of patterns" at the start or the end positions in <code>lhsPattern
* </code> and <code>lhsEval</code>.
*
* @param lhsPattern the expression which can contain pattern-matching objects
* @param lhsEval the expression which can contain no patterns
* @return <code>null</code> if the matching isn't possible.
*/
private static IAST[] removeFlat(final IAST lhsPattern, final IAST lhsEval) {
IASTAppendable lhsPatternAST = lhsPattern.copyAppendable();
IASTAppendable lhsEvalAST = lhsEval.copyAppendable();
// start from the beginning
int iIndex = 1;
while (iIndex < lhsPatternAST.size()) {
IExpr temp = lhsPatternAST.get(iIndex);
if (!(temp instanceof IPatternObject) && temp.isFreeOfPatterns()) {
if (iIndex < lhsEvalAST.size()) {
if (lhsEvalAST.get(iIndex).equals(temp)) {
lhsPatternAST.remove(iIndex);
lhsEvalAST.remove(iIndex);
continue;
}
}
return null;
}
break;
}
// now start from the end
iIndex = lhsPatternAST.size() - 1;
int jIndex = lhsEvalAST.size() - 1;
while (iIndex > 0) {
IExpr temp = lhsPatternAST.get(iIndex);
if (!(temp instanceof IPatternObject) && temp.isFreeOfPatterns()) {
if (jIndex < lhsEvalAST.size()) {
if (lhsEvalAST.get(jIndex).equals(temp)) {
lhsPatternAST.remove(iIndex--);
lhsEvalAST.remove(jIndex--);
continue;
}
}
return null;
}
break;
}
return new IASTAppendable[] { lhsPatternAST, lhsEvalAST };
}
use of org.matheclipse.core.interfaces.IPatternObject in project symja_android_library by axkr.
the class PatternMatcher method matchASTSpecialBuiltIn.
/**
* Test first if <code>functionID = lhsPatternAST.headID()</code> is a special pattern-matching
* construct (i.e. <code>
* Association, HoldPattern, Literal, Condition, Alternatives, Except, Complex, Rational, Optional, PatternTest, Verbatim
* </code>). If <code>true</code> evaluate the special pattern-matching construct otherwise
* continue with <code>lhsPatternAST</code> pattern matching.
*
* @param lhsPatternAST left-hand-side pattern AST
* @param lhsEvalExpr left-hand-side expression which should be matched by the pattern expression
* @param engine the evaluation engine
* @param stackMatcher a stack matcher
* @return
*/
private boolean matchASTSpecialBuiltIn(IAST lhsPatternAST, final IExpr lhsEvalExpr, EvalEngine engine, StackMatcher stackMatcher) {
int functionID = lhsPatternAST.headID();
if (functionID >= ID.Association && functionID <= ID.Verbatim) {
boolean matched = false;
if (lhsPatternAST.size() == 2) {
final IExpr[] patternValues;
switch(functionID) {
case ID.Association:
patternValues = fPatternMap.copyPattern();
try {
if (lhsEvalExpr.isAssociation()) {
IAST lhsPatternAssociation = lhsPatternAST;
// TODO set/determine pattern matching flags?
IASTMutable lhsPatternList = (IASTMutable) lhsPatternAssociation.normal(false);
lhsPatternList.set(0, S.Association);
IAssociation lhsEvalAssociation = (IAssociation) lhsEvalExpr;
IASTMutable lhsEvalList = lhsEvalAssociation.normal(false);
lhsEvalList.set(0, S.Association);
matched = matchExpr(lhsPatternList, lhsEvalList, engine, stackMatcher);
return matched;
}
matched = matchASTExpr(lhsPatternAST, lhsEvalExpr, engine, stackMatcher);
} finally {
if (!matched) {
fPatternMap.resetPattern(patternValues);
}
}
return matched;
case ID.Except:
patternValues = fPatternMap.copyPattern();
try {
matched = !matchExpr(lhsPatternAST.arg1(), lhsEvalExpr, engine, stackMatcher);
} finally {
if (!matched) {
fPatternMap.resetPattern(patternValues);
}
}
return matched;
case ID.HoldPattern:
case ID.Literal:
patternValues = fPatternMap.copyPattern();
try {
matched = matchExpr(lhsPatternAST.arg1(), lhsEvalExpr, engine, stackMatcher);
} finally {
if (!matched) {
fPatternMap.resetPattern(patternValues);
}
}
return matched;
case ID.Optional:
return matchOptional(lhsPatternAST, lhsEvalExpr, engine, stackMatcher);
case ID.Verbatim:
return lhsPatternAST.arg1().equals(lhsEvalExpr);
default:
}
} else if (lhsPatternAST.size() == 3) {
if (functionID >= ID.Complex && functionID <= ID.Rational) {
final IExpr[] patternValues;
switch(functionID) {
case ID.Complex:
patternValues = fPatternMap.copyPattern();
try {
if (lhsEvalExpr.isNumber()) {
INumber number = (INumber) lhsEvalExpr;
matched = matchExpr(lhsPatternAST.arg1(), number.re(), engine, stackMatcher) && matchExpr(lhsPatternAST.arg2(), number.im(), engine, stackMatcher);
return matched;
}
matched = matchASTExpr(lhsPatternAST, lhsEvalExpr, engine, stackMatcher);
} finally {
if (!matched) {
fPatternMap.resetPattern(patternValues);
}
}
return matched;
case ID.Condition:
return matchCondition(lhsPatternAST, lhsEvalExpr, engine, stackMatcher);
case ID.Except:
patternValues = fPatternMap.copyPattern();
try {
matched = !matchExpr(lhsPatternAST.arg1(), lhsEvalExpr, engine, stackMatcher) && matchExpr(lhsPatternAST.arg2(), lhsEvalExpr, engine, stackMatcher);
} finally {
if (!matched) {
fPatternMap.resetPattern(patternValues);
}
}
return matched;
case ID.Optional:
return matchOptional(lhsPatternAST, lhsEvalExpr, engine, stackMatcher);
case ID.PatternTest:
patternValues = fPatternMap.copyPattern();
try {
final IExpr lhsPatternExpr = lhsPatternAST.arg1();
final IExpr patternTest = lhsPatternAST.arg2();
if (lhsPatternExpr instanceof IPatternObject && patternTest.isFreeOfPatterns()) {
// other pattern symbol
if (matchPattern((IPatternObject) lhsPatternExpr, lhsEvalExpr, engine, stackMatcher)) {
if (fPatternMap.isPatternTest(lhsPatternExpr, patternTest, engine)) {
matched = stackMatcher.matchRest();
}
}
} else if (matchExpr(lhsPatternExpr, lhsEvalExpr, engine, stackMatcher)) {
matched = fPatternMap.isPatternTest(lhsPatternExpr, patternTest, engine);
}
} finally {
if (!matched) {
fPatternMap.resetPattern(patternValues);
}
}
return matched;
case ID.Rational:
patternValues = fPatternMap.copyPattern();
try {
// check for fractions (and no integers) here to be compatible with MMA
if (lhsEvalExpr.isFraction()) {
IFraction rational = (IFraction) lhsEvalExpr;
matched = matchExpr(lhsPatternAST.arg1(), rational.numerator(), engine, stackMatcher) && matchExpr(lhsPatternAST.arg2(), rational.denominator(), engine, stackMatcher);
return matched;
}
matched = matchASTExpr(lhsPatternAST, lhsEvalExpr, engine, stackMatcher);
return matched;
} finally {
if (!matched) {
fPatternMap.resetPattern(patternValues);
}
}
default:
}
}
}
} else {
if (lhsPatternAST.isAlternatives()) {
return matchAlternatives(lhsPatternAST, lhsEvalExpr, engine);
}
}
return matchASTExpr(lhsPatternAST, lhsEvalExpr, engine, stackMatcher);
}
Aggregations