use of org.matheclipse.core.interfaces.IPatternSequence in project symja_android_library by axkr.
the class PatternMatcher method matchAST.
protected boolean matchAST(IAST lhsPatternAST, final IExpr lhsEvalExpr, EvalEngine engine, StackMatcher stackMatcher) {
if (lhsEvalExpr instanceof IAST) {
if (lhsPatternAST.isFreeOfPatterns() && lhsPatternAST.equals(lhsEvalExpr)) {
return stackMatcher.matchRest();
}
IAST lhsEvalAST = (IAST) lhsEvalExpr;
final ISymbol sym = lhsPatternAST.topHead();
if (lhsPatternAST.size() <= lhsEvalAST.size()) {
if (lhsPatternAST.isOrderlessAST()) {
IExpr temp = fPatternMap.substituteASTPatternOrSymbols(lhsPatternAST, false).orElse(lhsPatternAST);
if (temp.isAST(lhsPatternAST.head())) {
lhsPatternAST = (IAST) temp;
IAST[] removed = removeOrderless(lhsPatternAST, lhsEvalAST);
if (removed == null) {
return false;
}
lhsPatternAST = removed[0];
lhsEvalAST = removed[1];
}
} else if (lhsPatternAST.isFlatAST()) {
IExpr temp = fPatternMap.substituteASTPatternOrSymbols(lhsPatternAST, false).orElse(lhsPatternAST);
if (temp.isAST(lhsPatternAST.head())) {
IAST[] removed = removeFlat((IAST) temp, lhsEvalAST);
if (removed == null) {
return false;
}
lhsPatternAST = removed[0];
lhsEvalAST = removed[1];
}
}
if ((lhsPatternAST.isFlatAST()) && sym.equals(lhsEvalAST.topHead()) && !(lhsPatternAST.isOrderlessAST() && lhsPatternAST.size() == lhsEvalAST.size())) {
if (!matchHeads(lhsPatternAST, lhsEvalAST, engine)) {
return false;
}
if (lhsPatternAST.size() == 1 && lhsEvalAST.size() == 1) {
return stackMatcher.matchRest();
}
return matchFlatAndFlatOrderless(sym, lhsPatternAST, lhsEvalAST, engine, stackMatcher);
}
}
int lhsEvalSize = lhsEvalAST.size();
if (lhsPatternAST.isEvalFlagOn(IAST.CONTAINS_PATTERN_SEQUENCE)) {
if (!matchHeads(lhsPatternAST, lhsEvalAST, engine)) {
return false;
}
if (lhsPatternAST.isEmpty() && lhsEvalAST.isEmpty()) {
return stackMatcher.matchRest();
}
final int lastPosition = lhsPatternAST.argSize();
if (lastPosition == 1 && lhsPatternAST.get(lastPosition).isAST(S.PatternTest, 3)) {
if (lhsPatternAST.size() <= lhsEvalSize) {
IAST patternTest = (IAST) lhsPatternAST.get(lastPosition);
if (patternTest.arg1().isPatternSequence(false)) {
// TODO only the special case, where the last element is
// a pattern sequence, is handled here
IASTAppendable seq = F.Sequence();
seq.appendAll(lhsEvalAST, lastPosition, lhsEvalSize);
if (((IPatternSequence) patternTest.arg1()).matchPatternSequence(seq, fPatternMap, lhsPatternAST.topHead())) {
if (matchAST(lhsPatternAST.removeFromEnd(lastPosition), lhsEvalAST.removeFromEnd(lastPosition), engine, stackMatcher)) {
return fPatternMap.isPatternTest(patternTest.arg1(), patternTest.arg2(), engine);
}
return false;
}
}
}
} else if (lhsPatternAST.size() > 1 && lhsPatternAST.arg1().isPatternSequence(false)) {
IPatternSequence patternSequence = (IPatternSequence) lhsPatternAST.arg1();
return matchBlankSequence(patternSequence, lhsPatternAST, 1, lhsEvalAST, engine, stackMatcher);
} else {
if (lhsPatternAST.size() > 1 && lhsEvalSize > 1) {
if (matchExpr(lhsPatternAST.arg1(), lhsEvalAST.arg1(), engine)) {
return matchAST(lhsPatternAST.rest().addEvalFlags(IAST.CONTAINS_PATTERN_SEQUENCE), lhsEvalAST.rest(), engine, stackMatcher);
}
}
}
return false;
}
if (lhsPatternAST.size() != lhsEvalSize || !matchHeads(lhsPatternAST, lhsEvalAST, engine)) {
return false;
}
if (lhsPatternAST.isOrderlessAST() && lhsPatternAST.size() > 2) {
// only "pure Orderless" and "FlatOrderless with same size()" will be handled here:
OrderlessStepVisitor visitor = new OrderlessStepVisitor(sym, lhsPatternAST, lhsEvalAST, stackMatcher, fPatternMap, (sym.hasOneIdentityAttribute() || sym.hasFlatAttribute()) || // same size ==> use OneIdentity in pattern matching
(lhsPatternAST.size() == lhsEvalSize && !sym.hasFlatAttribute()));
MultisetPartitionsIterator iter = new MultisetPartitionsIterator(visitor, lhsPatternAST.argSize());
return !iter.execute();
}
return matchASTSequence(lhsPatternAST, lhsEvalAST, 0, engine, stackMatcher);
}
return false;
}
Aggregations