use of org.matheclipse.core.interfaces.IPatternSequence in project symja_android_library by axkr.
the class PatternSequence method equivalent.
/**
* Check if the two left-hand-side pattern expressions are equivalent. (i.e.
* <code>f[x_,y_]</code> is equivalent to <code>f[a_,b_]</code> )
*
* @param patternExpr2
* @param pm1
* @param pm2
* @return
*/
@Override
public boolean equivalent(final IPatternObject patternExpr2, final PatternMap pm1, PatternMap pm2) {
if (this == patternExpr2) {
return true;
}
if (patternExpr2 instanceof PatternSequence) {
// test if the pattern indices are equal
final IPatternSequence p2 = (IPatternSequence) patternExpr2;
if (getIndex(pm1) != p2.getIndex(pm2)) {
return false;
}
// test if the "check" expressions are equal
final Object o1 = getCondition();
final Object o2 = p2.getCondition();
if ((o1 == null) || (o2 == null)) {
return o1 == o2;
}
return o1.equals(o2);
}
return false;
}
use of org.matheclipse.core.interfaces.IPatternSequence in project symja_android_library by axkr.
the class F method initPredefinedPatternSequence.
public static IPatternSequence initPredefinedPatternSequence(@Nonnull final ISymbol symbol) {
PatternSequence temp = PatternSequence.valueOf(symbol);
PREDEFINED_PATTERNSEQUENCE_MAP.put(symbol.toString(), temp);
return temp;
}
use of org.matheclipse.core.interfaces.IPatternSequence 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;
}
use of org.matheclipse.core.interfaces.IPatternSequence in project symja_android_library by axkr.
the class PatternSequence method equivalent.
/**
* Check if the two left-hand-side pattern expressions are equivalent. (i.e. <code>f[x_,y_]</code>
* is equivalent to <code>f[a_,b_]</code> )
*
* @param patternExpr2
* @param pm1
* @param pm2
* @return
*/
@Override
public boolean equivalent(final IPatternObject patternExpr2, final IPatternMap pm1, IPatternMap pm2) {
if (this == patternExpr2) {
return true;
}
if (patternExpr2 instanceof PatternSequence) {
// test if the pattern indices are equal
final IPatternSequence p2 = (IPatternSequence) patternExpr2;
if (getIndex(pm1) != p2.getIndex(pm2)) {
return false;
}
// test if the "check" expressions are equal
final Object o1 = getHeadTest();
final Object o2 = p2.getHeadTest();
if ((o1 == null) || (o2 == null)) {
return o1 == o2;
}
return o1.equals(o2);
}
return false;
}
use of org.matheclipse.core.interfaces.IPatternSequence in project symja_android_library by axkr.
the class Predicates method toFreeQ.
/**
* Convert the pattern into a pattern-matching predicate used in {@link F#FreeQ(IExpr, IExpr)}.
* FreeQ does test for subsequences (MemberQ does not test for subsequences).
*
* @param pattern
* @return
* @see IExpr#isFree(Predicate, boolean)
*/
public static Predicate<IExpr> toFreeQ(IExpr pattern) {
if (pattern.isSymbol() || pattern.isNumber() || pattern.isString()) {
return x -> x.equals(pattern);
}
final IPatternMatcher matcher;
if (pattern.isOrderlessAST() && pattern.isFreeOfPatterns()) {
// append a BlankNullSequence[] to match the parts of an Orderless expression
IPatternSequence blankNullRest = F.$ps(null, true);
IASTAppendable newPattern = ((IAST) pattern).copyAppendable();
newPattern.append(blankNullRest);
matcher = new PatternMatcher(newPattern);
} else {
matcher = new PatternMatcher(pattern);
}
return matcher;
}
Aggregations