package org.matheclipse.core.patternmatching;
import org.matheclipse.combinatoric.AbstractListStepVisitor;
import org.matheclipse.combinatoric.NumberPartitionsIterator;
import org.matheclipse.core.expression.F;
import org.matheclipse.core.interfaces.IAST;
import org.matheclipse.core.interfaces.IExpr;
import org.matheclipse.core.interfaces.ISymbol;
import org.matheclipse.core.patternmatching.PatternMatcher.StackMatcher;
/**
* This visitor is used in an NumberPartitionsIterator to match
* flat expressions in pattern matching.
*
* @see PatternMatcher
* @see NumberPartitionsIterator
*/
public class FlatStepVisitor extends AbstractListStepVisitor {
protected ISymbol fSymbol;
protected StackMatcher stackMatcher;
protected PatternMap fPatternMap;
protected IExpr[] patternValues;
protected IAST fLhsPatternAST;
protected boolean fOneIdentity;
public FlatStepVisitor(final ISymbol sym, IAST lhsPatternAST, IAST lhsEvalAST, StackMatcher stackMatcher, PatternMap patternMap) {
super(lhsEvalAST, 1, lhsEvalAST.size());
this.fSymbol = sym;
this.stackMatcher = stackMatcher;
this.fPatternMap = patternMap;
// copy pattern values to local variable
this.patternValues = patternMap.copyPattern();
this.fLhsPatternAST = lhsPatternAST;
this.fOneIdentity = (sym.getAttributes() & ISymbol.ONEIDENTITY) == ISymbol.ONEIDENTITY;
}
/**
* {@inheritDoc}
*
* @see org.matheclipse.combinatoric.IStepVisitor#visit(int[][])
*/
public boolean visit(int[][] result) {
if (matchSinglePartition(result, stackMatcher)) {
return false; // stop iterating and calling this visitor
}
// reset pattern values:
fPatternMap.resetPattern(patternValues);
return true;
}
/**
* Match a single partition combination
*
* @param result
* @param stackMatcher
* @return
*/
protected boolean matchSinglePartition(int[][] result, StackMatcher stackMatcher) {
IAST partitionElement;
// if (Config.SHOW_STACKTRACE == true) {
// }
int lastStackSize = stackMatcher.size();
boolean matched = true;
try {
for (int j = 0; j < result.length; j++) {
final int n = result[j].length;
if (n == 1 && fOneIdentity) {
// OneIdentity here
if (!stackMatcher.push(fLhsPatternAST.get(j + 1), (IExpr) array[result[j][0]])) {
matched = false;
return false;
}
} else {
partitionElement = F.ast(fSymbol, n, false);
for (int i = 0; i < n; i++) {
partitionElement.add((IExpr) array[result[j][i]]);
}
if (!stackMatcher.push(fLhsPatternAST.get(j + 1), partitionElement)) {
matched = false;
return false;
}
}
}
if (!stackMatcher.matchRest()) {
matched = false;
return false;
}
return true;
} finally {
if (!matched) {
stackMatcher.removeFrom(lastStackSize);
}
}
}
}
Ads help maintain this website.