package org.matheclipse.core.eval.util;

import static org.matheclipse.core.expression.F.Less;
import static org.matheclipse.core.expression.F.LessEqual;
import static org.matheclipse.core.expression.F.Plus;

import org.matheclipse.core.eval.EvalEngine;
import org.matheclipse.core.expression.F;
import org.matheclipse.core.expression.Symbol;
import org.matheclipse.core.generic.Predicates;
import org.matheclipse.core.generic.interfaces.IIterator;
import org.matheclipse.core.interfaces.IAST;
import org.matheclipse.core.interfaces.IExpr;
import org.matheclipse.core.interfaces.ISignedNumber;

/**
 * Iterator for functions like Product[] or Sum[]
 * 
 * @see org.matheclipse.core.reflection.system.Product
 * @see org.matheclipse.core.reflection.system.Sum
 */
public class Iterator implements IIterator {
	IExpr count;

	// boolean illegalIterator;
	final boolean fNumericMode;

	EvalEngine evalEngine;

	final IExpr maxCount;

	IExpr start;

	final IExpr step;

	final Symbol variable;

	public Iterator(final IAST lst, final EvalEngine sess) {
		// illegalIterator = false;
		evalEngine = sess;
		fNumericMode = evalEngine.isNumericMode() || lst.isMember(Predicates.isNumeric(), false);
		switch (lst.size()) {

		case 2:
			start = F.C1;
			maxCount = evalEngine.evalWithoutNumericReset(lst.get(1));
			step = F.C1;
			variable = null;

			break;
		case 3:
			start = F.C1;
			maxCount = evalEngine.evalWithoutNumericReset(lst.get(2));
			step = F.C1;

			if (lst.get(1) instanceof Symbol) {
				variable = (Symbol) lst.get(1);
			} else {
				variable = null;
			}

			break;
		case 4:
			start = evalEngine.evalWithoutNumericReset(lst.get(2));
			maxCount = evalEngine.evalWithoutNumericReset(lst.get(3));
			step = F.C1;

			// if (evalEngine.evaluate(LessEqual(start, maxCount)) != F.True) {
			// illegalIterator = true;
			// }
			if (lst.get(1) instanceof Symbol) {
				variable = (Symbol) lst.get(1);
			} else {
				variable = null;
			}

			break;
		case 5:
			start = evalEngine.evalWithoutNumericReset(lst.get(2));
			maxCount = evalEngine.evalWithoutNumericReset(lst.get(3));
			step = evalEngine.evalWithoutNumericReset(lst.get(4));
			// if (!(step instanceof ISignedNumber)) {
			// illegalIterator = true;
			// }
			// if (((ISignedNumber) step).isNegative()) {
			// if ((evalEngine.evaluate(Less(maxCount, start)) != F.True)) {
			// illegalIterator = true;
			// }
			// } else {
			// if ((evalEngine.evaluate(LessEqual(start, maxCount)) != F.True)) {
			// illegalIterator = true;
			// }
			// }
			if (lst.get(1) instanceof Symbol) {
				variable = (Symbol) lst.get(1);
			} else {
				variable = null;
			}

			break;
		default:
			maxCount = null;
			step = null;
			variable = null;

			// throw new NoIteratorException();

		}
	}

	public Iterator(final IAST lst, final Symbol symbol, final EvalEngine sess) {
		// illegalIterator = false;
		evalEngine = sess;
		fNumericMode = evalEngine.isNumericMode();
		switch (lst.size()) {

		case 2:
			start = F.C1;
			maxCount = evalEngine.evalWithoutNumericReset(lst.get(1));
			step = F.C1;
			variable = symbol;
			break;
		case 3:
			start = evalEngine.evalWithoutNumericReset(lst.get(1));
			maxCount = evalEngine.evalWithoutNumericReset(lst.get(2));
			step = F.C1;
			variable = symbol;
			// if (evalEngine.evaluate(LessEqual(start, maxCount)) != F.True) {
			// illegalIterator = true;
			// }
			break;
		case 4:
			start = evalEngine.evalWithoutNumericReset(lst.get(1));
			maxCount = evalEngine.evalWithoutNumericReset(lst.get(2));
			step = evalEngine.evalWithoutNumericReset(lst.get(3));
			variable = symbol;
			// if (!(step instanceof ISignedNumber)) {
			// illegalIterator = true;
			// }
			// if (((ISignedNumber) step).isNegative()) {
			// if ((evalEngine.evaluate(Less(maxCount, start)) != F.True)) {
			// illegalIterator = true;
			// }
			// } else {
			// if ((evalEngine.evaluate(LessEqual(start, maxCount)) != F.True)) {
			// illegalIterator = true;
			// }
			// }

			break;
		default:
			maxCount = null;
			step = null;
			variable = null;

			// throw new NoIteratorException();

		}
	}

	/**
	 * Tests if this enumeration contains more elements.
	 * 
	 * @return true if this enumeration contains more elements;
	 *         false otherwise.
	 */
	public boolean hasNext() {
		if ((maxCount == null)) {// || (illegalIterator)) {
			return false;
		}
		if (!(step instanceof ISignedNumber)) {
			return false;
		}
		if (((ISignedNumber) step).isNegative()) {
			if (evalEngine.evaluate(LessEqual(maxCount, count)) == F.True) {
				return true;
			}
		} else {
			if (evalEngine.evaluate(LessEqual(count, maxCount)) == F.True) {
				return true;
			}
		}

		return false;
	}

	/**
	 * Returns the next element of this enumeration.
	 * 
	 * @return the next element of this enumeration.
	 */
	public IExpr next() {
		if (variable != null) {
			variable.set(count);
			// variable.putDownRule(session, HRule.SET, variable, count);
		}
		final IExpr temp = count;
		count = evalEngine.evaluate(Plus(count, step));

		return temp;
	}

	public boolean setUp() {

		if (!(step instanceof ISignedNumber)) {
			return false;
		}
		if (((ISignedNumber) step).isNegative()) {
			if (evalEngine.evaluate(Less(start, maxCount)) == F.True) {
				return false;
			}
		} else {
			if (evalEngine.evaluate(Less(maxCount, start)) == F.True) {
				return false;
			}
		}
		count = start;
		if (variable != null) {
			variable.pushLocalVariable(count);
		}
		return true;
	}

	/**
	 * Method Declaration.
	 * 
	 * @see
	 */
	public void tearDown() {
		if (variable != null) {
			variable.popLocalVariable();
			// variable.clearSymbolRule(session, variable);
		}
		EvalEngine.get().setNumericMode(fNumericMode);
	}

	/**
	 * Helper method for functions like Product, Sum
	 * 
	 * @param ast
	 *          ast with Iterator specifications
	 * @param index
	 *          start index for iterstor specifications
	 * @param baseList
	 *          basic ast where the iterator elements are appended
	 * @return
	 */
	// public static IExpr iteratorLoop(IAST ast, int index, IAST baseList) {
	// EvalEngine evalEngine = EvalEngine.get();
	// if (index < ast.argsSize()) {
	// if (((IExpr) ast.getArg(index)).isList()) {
	// Iterator iter = null;
	// try {
	// iter = new Iterator((AST) ast.getArg(index), evalEngine);
	//
	// index++;
	// IAST lst = (IAST) baseList.clone();
	// IExpr temp;
	//
	// while (iter.hasNext()) {
	// temp = iteratorLoop(ast, index, baseList);
	//
	// if (temp != null) {
	// lst.add(temp);
	// }
	//
	// iter.next();
	// }
	// return lst;
	// } finally {
	// if (iter != null) {
	// iter.tearDown();
	// }
	// }
	// }
	// } else {
	// return evalEngine.evaluate(ast.get(1));
	// }
	//
	// return null;
	// }
	/**
	 * Not implemented; throws UnsupportedOperationException
	 * 
	 */
	public void remove() throws UnsupportedOperationException {
		throw new UnsupportedOperationException();
	}
}

 

Ads help maintain this website.