StackEntry.java

package edu.udel.cis.vsl.gmc.seq;

import java.util.Collection;
import java.util.Iterator;
import java.util.NoSuchElementException;

/**
 * The stack entry that is going to be pushed onto the stack during the search.
 * The stack entry also serves as the iterator of the ample set or ample set
 * complement of the source {@code state}.
 * 
 * @author Yihao Yan (yanyihao)
 *
 */
public class StackEntry<STATE, TRANSITION> implements Iterator<TRANSITION> {
	/**
	 * The search node that wraps the source state with its search information
	 * like stack position or fullyExpanded flag.
	 */
	private SequentialNode<STATE> node;

	/**
	 * This collection could be the ample set or ample set complement of the
	 * source state.
	 */
	private Collection<TRANSITION> transitions;

	/**
	 * The iterator to iterate either the ample set or the ample set complement
	 * of the {@link #sourceState}. This iterator will iterate over all the
	 * transitions after {@link #current} transition.
	 */
	private Iterator<TRANSITION> transitionIterator;

	/**
	 * The index of the current transition. This is used to write the trace file
	 * which will be used later for replay.
	 */
	private int tid = -1;

	/**
	 * The current transition.
	 */
	private TRANSITION current = null;

	/**
	 * If a successor is on stack, then it will have an index on the stack. This
	 * variable will store the minimum value among all the successors.
	 */
	private int minimumSuccessorStackIndex = Integer.MAX_VALUE;

	/**
	 * @param node
	 *            The node that wraps the source state.
	 * @param transitions
	 *            The ample set or ample set complement of the source state.
	 * @param offset
	 *            Offset should be the start index of transitions in
	 *            {@link #transitions}. When you construct a stack entry for the
	 *            candidate ample set of a state, offset should be 0, while when
	 *            you construct a stack entry for the candidate ample set
	 *            complement of a state, offset should be the size of candidate
	 *            ample set of the same state.
	 */
	public StackEntry(SequentialNode<STATE> node,
			Collection<TRANSITION> transitions, int offset) {
		this.node = node;
		this.transitions = transitions;
		this.transitionIterator = transitions.iterator();
		if (transitionIterator.hasNext()) {
			this.current = transitionIterator.next();
			tid = offset;
		}
	}

	/**
	 * @return the current transition but not move the
	 *         {@link #transitionIterator}.
	 */
	public TRANSITION peek() {
		if (current == null)
			throw new NoSuchElementException();
		return current;
	}

	/**
	 * @return the current transition and also move the
	 *         {@link #transitionIterator}.
	 */
	@Override
	public TRANSITION next() {
		TRANSITION result = current;

		if (result != null) {
			if (transitionIterator.hasNext()) {
				current = transitionIterator.next();
				tid++;
			} else
				current = null;
		} else
			throw new NoSuchElementException();
		return result;
	}

	public int getTid() {
		return tid;
	}

	public SequentialNode<STATE> getNode() {
		return node;
	}

	public Iterator<TRANSITION> getTransitionIterator() {
		return transitionIterator;
	}

	public STATE source() {
		return node.getState();
	}

	@Override
	public boolean hasNext() {
		return current != null;
	}

	public STATE getState() {
		return node.getState();
	}

	public int getMinimumSuccessorStackIndex() {
		return minimumSuccessorStackIndex;
	}

	public void setMinimumSuccessorStackIndex(int minimumSuccessorStackIndex) {
		this.minimumSuccessorStackIndex = minimumSuccessorStackIndex;
	}

	public Collection<TRANSITION> getTransitions() {
		return transitions;
	}
}