Search in sources :

Example 1 with MultisetPartitionsIterator

use of org.matheclipse.combinatoric.MultisetPartitionsIterator in project symja_android_library by axkr.

the class PatternMatcher method matchAST.

protected boolean matchAST(final IAST lhsPatternAST, final IExpr lhsEvalExpr, StackMatcher stackMatcher) {
    // "+lhsEvalExpr.toString());
    if (lhsPatternAST.isAST(F.PatternTest, 3)) {
        if (matchExpr(lhsPatternAST.arg1(), lhsEvalExpr, stackMatcher)) {
            return fPatternMap.isPatternTest(lhsPatternAST.arg1(), lhsPatternAST.arg2());
        }
        return false;
    }
    if (lhsPatternAST.isAST(F.Except, 2, 3)) {
        if (lhsPatternAST.isAST2()) {
            return !matchExpr(lhsPatternAST.arg1(), lhsEvalExpr, stackMatcher) && matchExpr(lhsPatternAST.arg2(), lhsEvalExpr, stackMatcher);
        } else {
            return !matchExpr(lhsPatternAST.arg1(), lhsEvalExpr, stackMatcher);
        }
    }
    if (lhsEvalExpr instanceof IAST) {
        if (!lhsPatternAST.isPatternExpr() && lhsPatternAST.equals(lhsEvalExpr)) {
            return stackMatcher.matchRest();
        }
        final IAST lhsEvalAST = (IAST) lhsEvalExpr;
        final ISymbol sym = lhsPatternAST.topHead();
        if (lhsPatternAST.size() <= lhsEvalAST.size()) {
            if ((lhsPatternAST.isFlatAST()) && sym.equals(lhsEvalAST.topHead()) && !(lhsPatternAST.isOrderlessAST() && lhsPatternAST.size() == lhsEvalAST.size())) {
                if (!matchExpr(lhsPatternAST.head(), lhsEvalAST.head())) {
                    return false;
                }
                return matchFlatAndFlatOrderlessAST(sym, lhsPatternAST, lhsEvalAST, stackMatcher);
            }
            if (lhsPatternAST.size() < lhsEvalAST.size()) {
                if (lhsPatternAST.isEvalFlagOn(IAST.CONTAINS_PATTERN_SEQUENCE)) {
                    if (!matchExpr(lhsPatternAST.head(), lhsEvalAST.head())) {
                        return false;
                    }
                    int lastPosition = lhsPatternAST.size() - 1;
                    if (lhsPatternAST.get(lastPosition).isAST(F.PatternTest, 3)) {
                        IAST patternTest = (IAST) lhsPatternAST.get(lastPosition);
                        if (patternTest.arg1().isPatternSequence()) {
                            // TODO only the special case, where the last
                            // element is
                            // a pattern sequence, is handled here
                            IAST seq = F.Sequence();
                            seq.appendAll(lhsEvalAST, lastPosition, lhsEvalAST.size());
                            if (((IPatternSequence) patternTest.arg1()).matchPatternSequence(seq, fPatternMap)) {
                                if (matchAST(lhsPatternAST.copyUntil(lastPosition), lhsEvalAST.copyUntil(lastPosition), stackMatcher)) {
                                    return fPatternMap.isPatternTest(patternTest.arg1(), patternTest.arg2());
                                }
                                return false;
                            }
                        }
                    }
                    if (lhsPatternAST.get(lastPosition).isPatternSequence()) {
                        // TODO only the special case, where the last
                        // element is
                        // a pattern sequence, is handled here
                        IAST seq = F.Sequence();
                        seq.appendAll(lhsEvalAST.range(), lastPosition, lhsEvalAST.size());
                        if (((IPatternSequence) lhsPatternAST.get(lastPosition)).matchPatternSequence(seq, fPatternMap)) {
                            return matchAST(lhsPatternAST.copyUntil(lastPosition), lhsEvalAST.copyUntil(lastPosition), stackMatcher);
                        }
                    }
                }
                return false;
            }
        }
        if (lhsPatternAST.size() != lhsEvalAST.size()) {
            return false;
        }
        IExpr e1 = lhsPatternAST.head();
        IExpr e2 = lhsEvalAST.head();
        if (e1.isSymbol() && e2.isSymbol()) {
            if (!e1.equals(e2)) {
                return false;
            }
        } else {
            // TODO create correct stack-matcher for the following call:
            if (!matchExpr(lhsPatternAST.head(), lhsEvalAST.head())) {
                return false;
            }
        }
        if (lhsPatternAST.isOrderlessAST()) {
            // only "pure Orderless" and "FlatOrderless with same size()"
            // will be handled here:
            OrderlessStepVisitor visitor = new OrderlessStepVisitor(sym, lhsPatternAST, lhsEvalAST, stackMatcher, fPatternMap, (sym.hasOneIdentityAttribute()) || // matching
            (lhsPatternAST.size() == lhsEvalAST.size() && !sym.hasFlatAttribute()));
            MultisetPartitionsIterator iter = new MultisetPartitionsIterator(visitor, lhsPatternAST.size() - 1);
            return !iter.execute();
        }
        return matchASTSequence(lhsPatternAST, lhsEvalAST, 0, stackMatcher);
    }
    if (lhsPatternAST.isAST(F.Rational, 3) && lhsEvalExpr.isRational()) {
        IRational numer = ((IRational) lhsEvalExpr).getNumerator();
        IRational denom = ((IRational) lhsEvalExpr).getDenominator();
        if (matchExpr(lhsPatternAST.arg1(), numer) && matchExpr(lhsPatternAST.arg2(), denom)) {
            return true;
        }
    } else if (lhsPatternAST.isAST(F.Complex, 3) && lhsEvalExpr.isNumber()) {
        ISignedNumber re = ((INumber) lhsEvalExpr).re();
        ISignedNumber im = ((INumber) lhsEvalExpr).im();
        if (matchExpr(lhsPatternAST.arg1(), re) && matchExpr(lhsPatternAST.arg2(), im)) {
            return true;
        }
    }
    return false;
}
Also used : ISymbol(org.matheclipse.core.interfaces.ISymbol) ISignedNumber(org.matheclipse.core.interfaces.ISignedNumber) MultisetPartitionsIterator(org.matheclipse.combinatoric.MultisetPartitionsIterator) IRational(org.matheclipse.core.interfaces.IRational) IPatternSequence(org.matheclipse.core.interfaces.IPatternSequence) IAST(org.matheclipse.core.interfaces.IAST) IExpr(org.matheclipse.core.interfaces.IExpr)

Example 2 with MultisetPartitionsIterator

use of org.matheclipse.combinatoric.MultisetPartitionsIterator in project symja_android_library by axkr.

the class PatternMatcher method matchFlatAndFlatOrderlessAST.

private boolean matchFlatAndFlatOrderlessAST(final ISymbol sym, final IAST lhsPatternAST, final IAST lhsEvalAST, StackMatcher stackMatcher) {
    if ((sym.getAttributes() & ISymbol.ORDERLESS) == ISymbol.ORDERLESS) {
        if (lhsPatternAST.isAST1()) {
            // TODO check for OneIdentity?
            return matchExpr(lhsPatternAST.arg1(), lhsEvalAST, stackMatcher);
        }
        for (int i = 1; i < lhsPatternAST.size(); i++) {
            if (!(lhsPatternAST.get(i) instanceof IPatternObject)) {
                // try to find a matchin sub-expression
                for (int j = 1; j < lhsEvalAST.size(); j++) {
                    if (matchExpr(lhsPatternAST.get(i), lhsEvalAST.get(j))) {
                        if (matchFlatAndFlatOrderlessAST(sym, lhsPatternAST.removeAtClone(i), lhsEvalAST.removeAtClone(j), stackMatcher)) {
                            return true;
                        }
                    }
                }
                return false;
            }
        }
        FlatOrderlessStepVisitor visitor = new FlatOrderlessStepVisitor(sym, lhsPatternAST, lhsEvalAST, stackMatcher, fPatternMap);
        MultisetPartitionsIterator iter = new MultisetPartitionsIterator(visitor, lhsPatternAST.size() - 1);
        return !iter.execute();
    } else {
        if (lhsPatternAST.isAST1()) {
            if (lhsPatternAST.arg1().isPatternSequence()) {
                // TODO only the special case, where the last element is
                // a pattern sequence, is handled here
                IAST seq = F.Sequence();
                seq.appendAll(lhsEvalAST, 1, lhsEvalAST.size());
                if (((IPatternSequence) lhsPatternAST.arg1()).matchPatternSequence(seq, fPatternMap)) {
                    // }
                    return true;
                }
            }
            if (lhsPatternAST.size() == lhsEvalAST.size()) {
                return matchASTSequence(lhsPatternAST, lhsEvalAST, 0, stackMatcher);
            }
            return false;
        }
        FlatStepVisitor visitor = new FlatStepVisitor(sym, lhsPatternAST, lhsEvalAST, stackMatcher, fPatternMap);
        NumberPartitionsIterator iter = new NumberPartitionsIterator(visitor, lhsEvalAST.size() - 1, lhsPatternAST.size() - 1);
        return !iter.execute();
    }
}
Also used : NumberPartitionsIterator(org.matheclipse.combinatoric.NumberPartitionsIterator) MultisetPartitionsIterator(org.matheclipse.combinatoric.MultisetPartitionsIterator) IPatternObject(org.matheclipse.core.interfaces.IPatternObject) IPatternSequence(org.matheclipse.core.interfaces.IPatternSequence) IAST(org.matheclipse.core.interfaces.IAST)

Aggregations

MultisetPartitionsIterator (org.matheclipse.combinatoric.MultisetPartitionsIterator)2 IAST (org.matheclipse.core.interfaces.IAST)2 IPatternSequence (org.matheclipse.core.interfaces.IPatternSequence)2 NumberPartitionsIterator (org.matheclipse.combinatoric.NumberPartitionsIterator)1 IExpr (org.matheclipse.core.interfaces.IExpr)1 IPatternObject (org.matheclipse.core.interfaces.IPatternObject)1 IRational (org.matheclipse.core.interfaces.IRational)1 ISignedNumber (org.matheclipse.core.interfaces.ISignedNumber)1 ISymbol (org.matheclipse.core.interfaces.ISymbol)1