use of org.matheclipse.core.combinatoric.MultisetPartitionsIterator in project symja_android_library by axkr.
the class CombinatoricTestCase method testRosenIterator.
public void testRosenIterator() {
IAST lhsPatternAST = F.Plus(F.x_, F.y_, F.z_);
IAST lhsEvalAST = F.Plus(F.a, F.b, F.c, F.d);
PatternMatcher patternMatcher = new PatternMatcher(lhsPatternAST);
IPatternMap patternMap = patternMatcher.createPatternMap();
// StackMatcher stackMatcher = patternMatcher.new StackMatcher(EvalEngine.get());
FlatOrderlessStepVisitor visitor = new FlatOrderlessStepVisitor(F.Plus, lhsPatternAST, lhsEvalAST, patternMatcher, patternMap);
MultisetPartitionsIterator iter = new MultisetPartitionsIterator(visitor, lhsPatternAST.argSize());
boolean b = false;
while (!b) {
b = iter.execute();
if (!b) {
System.out.println(iter.toString());
iter.initPatternMap();
}
}
assertEquals(true, b);
}
use of org.matheclipse.core.combinatoric.MultisetPartitionsIterator in project symja_android_library by axkr.
the class PatternMatcher method matchFlatOrderless.
/**
* Match <code>Flat</code> and <code>Orderless</code> LHS pattern expressions. It's assumed that
* the headers of the expressions already matched.
*
* @param sym
* @param lhsPattern
* @param lhsEval
* @param engine
* @param stackMatcher
* @return
*/
private boolean matchFlatOrderless(final ISymbol sym, IAST lhsPattern, IAST lhsEval, EvalEngine engine, StackMatcher stackMatcher) {
if (lhsPattern.isAST1()) {
return matchExpr(lhsPattern.arg1(), lhsEval, engine, stackMatcher);
}
IAST lhsPatternAST = lhsPattern;
IAST lhsEvalAST = lhsEval;
// removeOrderless already called a level up
boolean matched = false;
IExpr[] patternValues = fPatternMap.copyPattern();
if (lhsPatternAST.size() <= 2) {
try {
if (lhsPatternAST.isAST1()) {
matched = matchExpr(lhsPatternAST.arg1(), lhsEvalAST, engine, stackMatcher);
return matched;
}
if (lhsPatternAST.isEmpty() && lhsEvalAST.size() > 1) {
matched = false;
return matched;
}
matched = stackMatcher.matchRest();
return matched;
} finally {
if (!matched) {
fPatternMap.resetPattern(patternValues);
}
}
}
lhsPattern = lhsPatternAST;
lhsEval = lhsEvalAST;
final IAST lhsPatternFinal = lhsPattern;
final IAST lhsEvalFinal = lhsEval;
for (int i = 1; i < lhsPatternFinal.size(); i++) {
IExpr patternArg = lhsPatternFinal.get(i);
if (!(patternArg instanceof IPatternObject)) {
final int index = i;
IAST reduced = lhsPatternFinal.splice(index);
boolean evaled = false;
for (int k = 1; k < lhsEvalFinal.size(); k++) {
try {
IExpr evalArg = lhsEvalFinal.get(k);
if (!(patternArg.head() instanceof IPatternObject)) {
if (patternArg.isASTOrAssociation()) {
if ((((IAST) patternArg).getEvalFlags() & IAST.CONTAINS_DEFAULT_PATTERN) == IAST.CONTAINS_DEFAULT_PATTERN) {
continue;
}
}
if (patternArg.head().equals(evalArg.head()) && patternArg.isFree(x -> x.isOrderlessAST(), true)) {
evaled = true;
matched = matchExpr(patternArg, evalArg, engine, stackMatcher);
}
if (matched) {
matched = matchFlatAndFlatOrderless(sym, reduced, lhsEvalFinal.removeAtCopy(k), engine, stackMatcher);
if (matched) {
return true;
}
}
}
} finally {
if (!matched) {
fPatternMap.resetPattern(patternValues);
}
}
}
if (evaled) {
return false;
}
}
}
FlatOrderlessStepVisitor visitor = new FlatOrderlessStepVisitor(sym, lhsPatternFinal, lhsEvalFinal, stackMatcher, fPatternMap, sym.hasFlatAttribute());
MultisetPartitionsIterator iter = new MultisetPartitionsIterator(visitor, lhsPattern.argSize());
return !iter.execute();
}
use of org.matheclipse.core.combinatoric.MultisetPartitionsIterator 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