package org.matheclipse.core.eval.util;
import org.matheclipse.core.expression.F;
import org.matheclipse.core.interfaces.IAST;
import org.matheclipse.core.interfaces.IExpr;
import org.matheclipse.core.interfaces.IInteger;
import org.matheclipse.parser.client.math.MathException;
/**
* Level specification for expression trees
*/
public class LevelSpecification extends LevelSpec {
/**
* Create a LevelSpecification with level from 0 to Integer.MAX_VALUE
*
*/
public LevelSpecification() {
super();
fFromLevel = 0;
fToLevel = Integer.MAX_VALUE;
fFromDepth = Integer.MIN_VALUE;
fToDepth = -1;
}
/**
* Create a LevelSpecification from an IInteger or IAST list-object.
*
*
* If expr is a non-negative IInteger iValue set Level
* {1,iValue};
* If expr is a negative IInteger iValue set Level {iValue, 0};
* If expr is a List {i0Value, i1Value} set Level {i0Value,
* i1Value};
*
* @param expr
* @param includeHeads
* TODO
* @throws MathException
* if the expr is not a level specification
* @see
*/
public LevelSpecification(final IExpr expr, boolean includeHeads) {
super(0, includeHeads);
fFromLevel = fToLevel = -1;
fFromDepth = fToDepth = 0;
if (expr instanceof IInteger) {
final IInteger value = (IInteger) expr;
if (value.isNegative()) {
fFromDepth = Integer.MIN_VALUE;
fToDepth = value.getBigNumerator().intValue();
fFromLevel = 1;
fToLevel = Integer.MAX_VALUE;
} else {
fToLevel = value.getBigNumerator().intValue();
fFromLevel = 1;
fFromDepth = Integer.MIN_VALUE;
fToDepth = -1;
}
return;
}
if (expr.isList()) {
final IAST lst = (IAST) expr;
if (lst.size() == 2) {
if (lst.get(1) instanceof IInteger) {
final IInteger i = (IInteger) lst.get(1);
if (i.isNegative()) {
fFromDepth = i.getBigNumerator().intValue();
fToDepth = i.getBigNumerator().intValue();
fFromLevel = 0;
fToLevel = Integer.MAX_VALUE;
if (fToDepth < fFromDepth) {
throw new MathException("Invalid Level specification: " + expr.toString());
}
} else {
fToLevel = i.getBigNumerator().intValue();
fFromLevel = i.getBigNumerator().intValue();
fFromDepth = Integer.MIN_VALUE;
fToDepth = -1;
if (fToLevel < fFromLevel) {
throw new MathException("Invalid Level specification: " + expr.toString());
}
}
return;
}
} else {
if ((lst.size() == 3)) {
if ((lst.get(1) instanceof IInteger) && (lst.get(2) instanceof IInteger)) {
final IInteger i0 = (IInteger) lst.get(1);
final IInteger i1 = (IInteger) lst.get(2);
if (i0.isNegative() && i1.isNegative()) {
fFromDepth = i0.getBigNumerator().intValue();
fToDepth = i1.getBigNumerator().intValue();
fFromLevel = 0;
fToLevel = Integer.MAX_VALUE;
} else if (i0.isNegative()) {
throw new MathException("Invalid Level specification: " + expr.toString());
} else if (i1.isNegative()) {
fFromDepth = Integer.MIN_VALUE;
fToDepth = i1.getBigNumerator().intValue();
fFromLevel = i0.getBigNumerator().intValue();
fToLevel = Integer.MAX_VALUE;
} else {
fFromDepth = Integer.MIN_VALUE;
fToDepth = -1;
fFromLevel = i0.getBigNumerator().intValue();
fToLevel = i1.getBigNumerator().intValue();
}
return;
} else if ((lst.get(1) instanceof IInteger) && (lst.get(2).isInfinity())) {
final IInteger i0 = (IInteger) lst.get(1);
if (i0.isNegative()) {
throw new MathException("Invalid Level specification: " + expr.toString());
} else {
fFromDepth = Integer.MIN_VALUE;
fToDepth = -1;
fFromLevel = i0.getBigNumerator().intValue();
fToLevel = Integer.MAX_VALUE;
}
return;
}
}
}
}
if (expr.equals(F.CInfinity)) {
fToLevel = Integer.MAX_VALUE;
fFromLevel = 1;
fFromDepth = Integer.MIN_VALUE;
fToDepth = -1;
return;
}
throw new MathException("Invalid Level specification: " + expr.toString());
}
/**
* Create a LevelSpecification with only the given level
*
*/
public LevelSpecification(final int level) {
this(level, level);
}
/**
* Create a LevelSpecification with the given level range
*
*/
public LevelSpecification(final int levelFrom, final int levelTo) {
super();
fFromLevel = levelFrom;
fToLevel = levelTo;
fFromDepth = Integer.MIN_VALUE;
fToDepth = -1;
}
/**
* Get the low level-limit
*
* @return the from value of the level instance
*/
public int getFrom() {
return fFromLevel;
}
/**
* Get the high level-limit.
*
* @return the to value of the level instance
*/
public int getTo() {
return fToLevel;
}
public final boolean includesDepth(int i) {
i *= -1;
return ((fFromDepth <= i) && (fToDepth >= i));
}
public final boolean includesLevel(final int i) {
return ((fFromLevel <= i) && (fToLevel >= i));
}
public final int compareDepth(int i) {
i *= -1;
if (fFromDepth > i) {
return -1;
}
if (fToDepth < i) {
return 1;
}
return 0;
}
public final int compareLevel() {
return compareLevel(fCurrentLevel);
}
public final int compareLevel(final int i) {
if (fFromLevel > i) {
return -1;
}
if (fToLevel < i) {
return 1;
}
return 0;
}
/**
* @param i
*/
public void setFrom(final int i) {
fFromLevel = i;
}
/**
* @param i
*/
public void setTo(final int i) {
fToLevel = i;
}
}
Ads help maintain this website.