package org.matheclipse.core.patternmatching;
import java.io.IOException;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.matheclipse.core.eval.EvalEngine;
import org.matheclipse.core.expression.F;
import org.matheclipse.core.interfaces.IAST;
import org.matheclipse.core.interfaces.IEvaluationEngine;
import org.matheclipse.core.interfaces.IExpr;
import org.matheclipse.core.interfaces.IPattern;
import org.matheclipse.core.interfaces.ISymbol;
import com.google.common.collect.ArrayListMultimap;
/**
* The pattern matching rules associated with a symbol.
*/
public class UpRulesData implements Serializable {
/**
*
*/
private static final long serialVersionUID = 779382003637253257L;
private transient Map fEqualUpRules;
private transient ArrayListMultimap fSimplePatternUpRules;
public UpRulesData() {
this.fEqualUpRules = null;
this.fSimplePatternUpRules = null;
}
public void clear() {
fEqualUpRules = null;
fSimplePatternUpRules = null;
}
public IExpr evalUpRule(final IEvaluationEngine ee, final IExpr expression) {
PatternMatcherEquals res;
if (fEqualUpRules != null) {
res = fEqualUpRules.get(expression);
if (res != null) {
return res.getRHS();
}
}
try {
IExpr result;
IPatternMatcher pmEvaluator;
if ((fSimplePatternUpRules != null) && (expression.isAST())) {
final Integer hash = Integer.valueOf(((IAST) expression).patternHashCode());
final List list = fSimplePatternUpRules.get(hash);
if (list != null) {
for (int i = 0; i < list.size(); i++) {
pmEvaluator = (IPatternMatcher) list.get(i).clone();
result = pmEvaluator.eval(expression);
if (result != null) {
return result;
}
}
}
}
} catch (CloneNotSupportedException cnse) {
cnse.printStackTrace();
}
return null;
}
public IPatternMatcher putUpRule(ISymbol setSymbol, final boolean equalRule, final IAST leftHandSide,
final IExpr rightHandSide, final int priority) {
if (equalRule) {
fEqualUpRules = getEqualUpRules();
PatternMatcherEquals pmEquals = new PatternMatcherEquals(setSymbol, leftHandSide, rightHandSide);
fEqualUpRules.put(leftHandSide, pmEquals);
return pmEquals;
}
final PatternMatcherAndEvaluator pmEvaluator = new PatternMatcherAndEvaluator(setSymbol, leftHandSide, rightHandSide);
if (pmEvaluator.isRuleWithoutPatterns()) {
fEqualUpRules = getEqualUpRules();
PatternMatcherEquals pmEquals = new PatternMatcherEquals(setSymbol, leftHandSide, rightHandSide);
fEqualUpRules.put(leftHandSide, pmEquals);
return pmEquals;
}
fSimplePatternUpRules = getSimplePatternUpRules();
return addSimplePatternUpRule(leftHandSide, pmEvaluator);
}
/**
* Create a pattern hash value for the left-hand-side expression and insert
* the left-hand-side as a simple pattern rule to the
* fSimplePatternRules.
*
* @param leftHandSide
* @param pmEvaluator
* @return
*/
private PatternMatcher addSimplePatternUpRule(final IExpr leftHandSide, final PatternMatcher pmEvaluator) {
final Integer hash = Integer.valueOf(((IAST) leftHandSide).patternHashCode());
if (F.isSystemInitialized && fSimplePatternUpRules.containsEntry(hash, pmEvaluator)) {
fSimplePatternUpRules.remove(hash, pmEvaluator);
}
fSimplePatternUpRules.put(hash, pmEvaluator);
return pmEvaluator;
}
private boolean isComplicatedPatternRule(final IExpr lhsExpr) {
if (lhsExpr.isAST()) {
final IAST lhsAST = ((IAST) lhsExpr);
if (lhsAST.size() > 1) {
final int attr = lhsAST.topHead().getAttributes();
if ((ISymbol.ORDERLESS & attr) == ISymbol.ORDERLESS) {
return true;
}
if (lhsAST.get(1).isAST()) {
IAST arg1 = (IAST) lhsAST.get(1);
if (arg1.isCondition()) {
return true;
}
// the left hand side is associated with the first argument
// see if the first argument is complicated
for (int i = 2; i < arg1.size(); i++) {
if (arg1.get(i).isPattern() && ((IPattern) arg1.get(i)).isDefault()) {
return true;
}
}
} else if (lhsAST.get(1).isPattern()) {
return true;
} else if (lhsAST.get(1).isPatternSequence()) {
return true;
}
for (int i = 2; i < lhsAST.size(); i++) {
if (lhsAST.get(i).isPattern() && ((IPattern) lhsAST.get(i)).isDefault()) {
return true;
}
}
}
} else if (lhsExpr.isPattern()) {
return true;
} else if (lhsExpr.isPatternSequence()) {
return true;
}
return false;
}
/**
* @return Returns the equalRules.
*/
public Map getEqualUpRules() {
if (fEqualUpRules == null) {
fEqualUpRules = new HashMap();
}
return fEqualUpRules;
}
private ArrayListMultimap getSimplePatternUpRules() {
if (fSimplePatternUpRules == null) {
fSimplePatternUpRules = ArrayListMultimap.create();
}
return fSimplePatternUpRules;
}
public List definition() {
ArrayList definitionList = new ArrayList();
Iterator iter;
IExpr key;
PatternMatcherEquals pme;
IExpr condition;
ISymbol setSymbol;
IAST ast;
PatternMatcherAndEvaluator pmEvaluator;
if (fEqualUpRules != null && fEqualUpRules.size() > 0) {
iter = fEqualUpRules.keySet().iterator();
while (iter.hasNext()) {
key = iter.next();
pme = fEqualUpRules.get(key);
setSymbol = pme.getSetSymbol();
ast = F.ast(setSymbol);
ast.add(key);
ast.add(pme.getRHS());
definitionList.add(ast);
}
}
if (fSimplePatternUpRules != null && fSimplePatternUpRules.size() > 0) {
Iterator listIter = fSimplePatternUpRules.values().iterator();
IPatternMatcher elem;
while (listIter.hasNext()) {
elem = listIter.next();
if (elem instanceof PatternMatcherAndEvaluator) {
pmEvaluator = (PatternMatcherAndEvaluator) elem;
setSymbol = pmEvaluator.getSetSymbol();
ast = F.ast(setSymbol);
ast.add(pmEvaluator.getLHS());
condition = pmEvaluator.getCondition();
if (condition != null) {
ast.add(F.Condition(pmEvaluator.getRHS(), condition));
} else {
ast.add(pmEvaluator.getRHS());
}
definitionList.add(ast);
}
// if (elem instanceof PatternMatcherAndInvoker) {
// don't show internal methods associated with a pattern
// }
}
}
return definitionList;
}
public void readSymbol(java.io.ObjectInputStream stream) throws IOException {
String astString;
IExpr key;
IExpr value;
EvalEngine engine = EvalEngine.get();
ISymbol setSymbol;
int len = stream.read();
if (len > 0) {
// fEqualRules = new HashMap>();
// for (int i = 0; i < len; i++) {
// astString = stream.readUTF();
// setSymbol = F.$s(astString);
//
// astString = stream.readUTF();
// key = engine.parse(astString);
// astString = stream.readUTF();
// value = engine.parse(astString);
// fEqualRules.put(key, new Pair(setSymbol, value));
// }
fEqualUpRules = new HashMap();
for (int i = 0; i < len; i++) {
astString = stream.readUTF();
setSymbol = F.$s(astString);
astString = stream.readUTF();
key = engine.parse(astString);
astString = stream.readUTF();
value = engine.parse(astString);
fEqualUpRules.put(key, new PatternMatcherEquals(setSymbol, key, value));
}
}
len = stream.read();
IExpr lhs;
IExpr rhs;
IExpr condition;
int listLength;
int condLength;
PatternMatcherAndEvaluator pmEvaluator;
if (len > 0) {
fSimplePatternUpRules = ArrayListMultimap.create();
for (int i = 0; i < len; i++) {
astString = stream.readUTF();
setSymbol = F.$s(astString);
astString = stream.readUTF();
lhs = engine.parse(astString);
astString = stream.readUTF();
rhs = engine.parse(astString);
pmEvaluator = new PatternMatcherAndEvaluator(setSymbol, lhs, rhs);
condLength = stream.read();
if (condLength == 0) {
condition = null;
} else {
astString = stream.readUTF();
condition = engine.parse(astString);
pmEvaluator.setCondition(condition);
}
addSimplePatternUpRule(lhs, pmEvaluator);
}
}
}
public void writeSymbol(java.io.ObjectOutputStream stream) throws java.io.IOException {
Iterator iter;
IExpr key;
IExpr condition;
PatternMatcherEquals pme;
ISymbol setSymbol;
PatternMatcherAndEvaluator pmEvaluator;
if (fEqualUpRules == null || fEqualUpRules.size() == 0) {
stream.write(0);
} else {
stream.write(fEqualUpRules.size());
iter = fEqualUpRules.keySet().iterator();
while (iter.hasNext()) {
key = iter.next();
pme = fEqualUpRules.get(key);
stream.writeUTF(pme.getLHS().toString());
stream.writeUTF(key.fullFormString());
stream.writeUTF(pme.getRHS().fullFormString());
}
}
if (fSimplePatternUpRules == null || fSimplePatternUpRules.size() == 0) {
stream.write(0);
} else {
stream.write(fSimplePatternUpRules.size());
Iterator listIter = fSimplePatternUpRules.values().iterator();
IPatternMatcher elem;
while (listIter.hasNext()) {
elem = listIter.next();
pmEvaluator = (PatternMatcherAndEvaluator) elem;
setSymbol = pmEvaluator.getSetSymbol();
stream.writeUTF(setSymbol.toString());
stream.writeUTF(pmEvaluator.getLHS().fullFormString());
stream.writeUTF(pmEvaluator.getRHS().fullFormString());
condition = pmEvaluator.getCondition();
if (condition == null) {
stream.write(0);
} else {
stream.write(1);
stream.writeUTF(condition.fullFormString());
}
}
}
}
}
Ads help maintain this website.