ProcessState.java

package edu.udel.cis.vsl.tass.state.impl;

import edu.udel.cis.vsl.tass.dynamic.IF.value.ValueIF;
import edu.udel.cis.vsl.tass.morph.MorphicObject;
import edu.udel.cis.vsl.tass.morph.MorphicArray;
import edu.udel.cis.vsl.tass.morph.MorphicArrayFactory;
import edu.udel.cis.vsl.tass.morph.Morphic;
import edu.udel.cis.vsl.tass.morph.MorphicVector;
import edu.udel.cis.vsl.tass.morph.MorphicVectorFactory;
import edu.udel.cis.vsl.tass.state.IF.FrameIF;
import edu.udel.cis.vsl.tass.state.IF.ProcessStateIF;

/** A process state represents the state of one process in a TASS model. */
public class ProcessState extends MorphicObject implements ProcessStateIF {

	/**
	 * The values of process global variables, also known as
	 * "process variables".
	 */
	private MorphicArray<ValueIF> globalValues;

	/**
	 * The values of the heap for this process. The heap is a finite sequence of
	 * values.
	 */
	private MorphicVector<ValueIF> heap;

	/**
	 * The state of the call stack for this process. The call stack is a finite
	 * array of stack frames. The oldest frame (at the bottom of the stack) is
	 * at index 0.
	 */
	private MorphicVector<FrameIF> stack;

	private int canonicalId = -1;

	private int instanceId;

	ProcessState(int instanceId, MorphicArray<ValueIF> globalValues,
			MorphicVector<ValueIF> heap, MorphicVector<FrameIF> stack) {
		this.instanceId = instanceId;
		this.globalValues = globalValues;
		this.heap = heap;
		this.stack = stack;
	}

	@Override
	public int canonicalId() {
		return canonicalId;
	}

	@Override
	public int instanceId() {
		return instanceId;
	}

	void setCanonicalId(int id) {
		canonicalId = id;
	}

	@Override
	public MorphicArray<ValueIF> globalValues() {
		return globalValues;
	}

	@Override
	public ValueIF globalValue(int i) {
		return globalValues.get(i);
	}

	public void setGlobalValues(MorphicArray<ValueIF> globalValues) {
		assert !isCommitted();
		this.globalValues = globalValues;
	}

	public void setGlobalValue(int index, ValueIF value) {
		globalValues.set(index, value);
	}

	@Override
	public MorphicVector<ValueIF> heap() {
		return heap;
	}

	@Override
	public ValueIF heapValue(int i) {
		return heap.get(i);
	}

	public void setHeap(MorphicVector<ValueIF> heap) {
		assert !isCommitted();
		this.heap = heap;
	}

	public void setHeapValue(int index, ValueIF value) {
		heap.set(index, value);
	}

	@Override
	public MorphicVector<FrameIF> stack() {
		return stack;
	}

	@Override
	public FrameIF frame(int i) {
		return stack.get(i);
	}

	@Override
	public FrameIF peekStack() {
		return stack.peek();
	}

	public void pushStack(FrameIF frame) {
		assert !isCommitted();
		stack.push(frame);
	}

	@Override
	public int stackSize() {
		return stack.size();
	}

	public void setStack(MorphicVector<FrameIF> stack) {
		assert !isCommitted();
		this.stack = stack;
	}

	public void setStackFrame(int index, FrameIF frame) {
		stack.set(index, frame);
	}

	public void popStack() {
		stack.pop();
	}

	@Override
	public String toString() {
		return "Process State " + instanceId() + " " + descriptor();
	}

	@Override
	protected boolean computeEquals(Morphic component) {
		if (component instanceof ProcessState) {
			ProcessState that = (ProcessState) component;

			return globalValues.equals(that.globalValues)
					&& heap.equals(that.heap) && stack.equals(that.stack);
		}
		return false;
	}

	@Override
	protected int computeHashCode() {
		return globalValues.hashCode() + heap.hashCode() + stack.hashCode();
	}

	@Override
	protected void commitChildren() {
		globalValues.commit();
		stack.commit();
		heap.commit();
	}

	void canonicalizeChildren(MorphicArrayFactory<ValueIF> globalFactory,
			MorphicVectorFactory<ValueIF> heapFactory,
			MorphicVectorFactory<FrameIF> stackFactory) {
		globalValues = globalFactory.canonic(globalValues);
		heap = heapFactory.canonic(heap);
		stack = stackFactory.canonic(stack);
	}

	@Override
	public String descriptor() {
		if (!isCommitted())
			return "";
		if (!isCanonic()) {
			return "(committed)";
		}
		return "(canonicID = " + canonicalId() + ")";
	}
}