use of org.matheclipse.core.interfaces.IPatternObject in project symja_android_library by axkr.
the class PatternMatcher method removeOrderless.
/**
* Remove parts which are "free of patterns" 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[] removeOrderless(final IAST lhsPattern, final IAST lhsEval) {
int iIndex = 1;
int jIndex = -1;
while (iIndex < lhsPattern.size()) {
IExpr temp = lhsPattern.get(iIndex);
if (!(temp instanceof IPatternObject) && temp.isFreeOfPatterns()) {
jIndex = lhsEval.indexOf(temp);
if (jIndex > 0) {
break;
}
return null;
}
iIndex++;
}
if (jIndex > 0) {
IASTAppendable lhsPatternAST = lhsPattern.copyAppendable();
IASTAppendable lhsEvalAST = lhsEval.copyAppendable();
lhsPatternAST.remove(iIndex);
lhsEvalAST.remove(jIndex);
while (iIndex < lhsPatternAST.size()) {
final IExpr temp = lhsPatternAST.get(iIndex);
if (!(temp instanceof IPatternObject) && temp.isFreeOfPatterns()) {
int indx = lhsEvalAST.indexOf(temp);
if (indx > 0) {
lhsPatternAST.remove(iIndex);
lhsEvalAST.remove(indx);
continue;
}
return null;
}
iIndex++;
}
return new IAST[] { lhsPatternAST, lhsEvalAST };
}
return new IAST[] { lhsPattern, lhsEval };
}
use of org.matheclipse.core.interfaces.IPatternObject in project symja_android_library by axkr.
the class PatternMatcher method remove.
/**
* Remove parts which are "free of patterns" 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 IAST[] remove(final IAST lhsPattern, final IAST lhsEval, EvalEngine engine, StackMatcher stackMatcher) {
IASTAppendable lhsPatternAST = F.NIL;
IASTAppendable lhsEvalAST = F.NIL;
int i = 1;
int iIndex = 1;
boolean evaled = false;
boolean matched = false;
while (i < lhsPattern.size()) {
IExpr lhs = lhsPattern.get(i);
IExpr rhs = lhsEval.get(i);
i++;
if (lhs instanceof IPatternObject) {
if (lhs instanceof IPatternSequence) {
return UNEVALED;
}
IPatternObject pattern = (IPatternObject) lhs;
if (pattern.getSymbol() != null && !pattern.isPatternOptional()) {
matched = matchPattern((IPatternObject) lhs, rhs, engine, stackMatcher);
if (matched) {
if (!evaled) {
lhsPatternAST = lhsPattern.copyAppendable();
lhsEvalAST = lhsEval.copyAppendable();
}
lhsPatternAST.remove(iIndex);
lhsEvalAST.remove(iIndex);
evaled = true;
continue;
}
return null;
}
} else if (lhs.isFreeOfPatterns()) {
if (lhs.equals(rhs)) {
if (!evaled) {
lhsPatternAST = lhsPattern.copyAppendable();
lhsEvalAST = lhsEval.copyAppendable();
}
lhsPatternAST.remove(iIndex);
lhsEvalAST.remove(iIndex);
evaled = true;
continue;
}
return null;
}
iIndex++;
}
if (!evaled) {
return UNEVALED;
}
return new IAST[] { lhsPatternAST, lhsEvalAST };
}
use of org.matheclipse.core.interfaces.IPatternObject in project symja_android_library by axkr.
the class PatternMatcher 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 patternExpr1
* @param patternExpr2
* @param pm1
* @param pm2
* @return
*/
public static boolean equivalent(final IExpr patternExpr1, final IExpr patternExpr2, final IPatternMap pm1, IPatternMap pm2) {
if (!patternExpr1.isPatternExpr()) {
if (!patternExpr2.isPatternExpr()) {
return patternExpr1.equals(patternExpr2);
}
return false;
}
if (patternExpr1.isASTOrAssociation()) {
if (patternExpr2.isASTOrAssociation()) {
final IAST l1 = (IAST) patternExpr1;
final IAST l2 = (IAST) patternExpr2;
if (l1.size() != l2.size()) {
return false;
}
return l1.forAll((temp1, i) -> {
IExpr temp2 = l2.get(i);
if (temp1 == temp2) {
return true;
}
if (temp1.hashCode() != temp2.hashCode()) {
if (temp1.isPatternExpr() && temp2.isPatternExpr()) {
return equivalent(temp1, temp2, pm1, pm2);
}
return false;
}
if (!temp1.isPatternExpr() || !temp2.isPatternExpr()) {
if (!temp1.equals(temp2)) {
return false;
}
}
return equivalent(temp1, temp2, pm1, pm2);
}, 0);
}
return false;
}
if (patternExpr1 instanceof IPatternObject) {
if (patternExpr2 instanceof IPatternObject) {
return ((IPatternObject) patternExpr1).equivalent((IPatternObject) patternExpr2, pm1, pm2);
}
return false;
}
return patternExpr1.equals(patternExpr2);
}
use of org.matheclipse.core.interfaces.IPatternObject 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();
}
}
use of org.matheclipse.core.interfaces.IPatternObject in project symja_android_library by axkr.
the class PatternMap method substitutePatternOrSymbols.
/**
* Substitute all patterns and symbols in the given expression with the
* current value of the corresponding internal pattern values arrays
*
* @param lhsPatternExpr
* left-hand-side expression which may containe pattern objects
*
* @return
*/
protected IExpr substitutePatternOrSymbols(final IExpr lhsPatternExpr) {
if (fPatternValuesArray != null) {
IExpr result = lhsPatternExpr.replaceAll((IExpr input) -> {
if (input instanceof IPatternObject) {
IPatternObject patternObject = (IPatternObject) input;
ISymbol sym = patternObject.getSymbol();
if (sym != null) {
for (int i = 0; i < fSymbolsArray.length; i++) {
if (sym == fSymbolsArray[i]) {
return fPatternValuesArray[i] != null ? fPatternValuesArray[i] : F.NIL;
}
}
} else {
for (int i = 0; i < fSymbolsArray.length; i++) {
if (patternObject == fSymbolsArray[i]) {
return fPatternValuesArray[i] != null ? fPatternValuesArray[i] : F.NIL;
}
}
}
}
return F.NIL;
});
if (result != null) {
return result;
}
}
return lhsPatternExpr;
}
Aggregations