Search in sources :

Example 21 with IPatternObject

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 };
}
Also used : IASTAppendable(org.matheclipse.core.interfaces.IASTAppendable) IPatternObject(org.matheclipse.core.interfaces.IPatternObject) IExpr(org.matheclipse.core.interfaces.IExpr)

Example 22 with IPatternObject

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);
}
Also used : IFraction(org.matheclipse.core.interfaces.IFraction) IAssociation(org.matheclipse.core.interfaces.IAssociation) INumber(org.matheclipse.core.interfaces.INumber) IPatternObject(org.matheclipse.core.interfaces.IPatternObject) IExpr(org.matheclipse.core.interfaces.IExpr) IAST(org.matheclipse.core.interfaces.IAST) IASTMutable(org.matheclipse.core.interfaces.IASTMutable)

Aggregations

IPatternObject (org.matheclipse.core.interfaces.IPatternObject)22 IExpr (org.matheclipse.core.interfaces.IExpr)17 IAST (org.matheclipse.core.interfaces.IAST)16 ISymbol (org.matheclipse.core.interfaces.ISymbol)8 IPatternSequence (org.matheclipse.core.interfaces.IPatternSequence)6 IASTAppendable (org.matheclipse.core.interfaces.IASTAppendable)5 IASTMutable (org.matheclipse.core.interfaces.IASTMutable)4 PatternNested (org.matheclipse.core.expression.PatternNested)3 IAssociation (org.matheclipse.core.interfaces.IAssociation)3 INumber (org.matheclipse.core.interfaces.INumber)3 ISignedNumber (org.matheclipse.core.interfaces.ISignedNumber)3 OptionsPattern (org.matheclipse.core.expression.OptionsPattern)2 Pattern (org.matheclipse.core.expression.Pattern)2 IBuiltInSymbol (org.matheclipse.core.interfaces.IBuiltInSymbol)2 IComplex (org.matheclipse.core.interfaces.IComplex)2 IComplexNum (org.matheclipse.core.interfaces.IComplexNum)2 IFraction (org.matheclipse.core.interfaces.IFraction)2 InfixOperator (org.matheclipse.parser.client.operator.InfixOperator)2 Operator (org.matheclipse.parser.client.operator.Operator)2 PostfixOperator (org.matheclipse.parser.client.operator.PostfixOperator)2