ModelStateFactory.java

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

import java.util.Collection;
import java.util.HashMap;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Vector;

import edu.udel.cis.vsl.tass.dynamic.IF.DynamicException;
import edu.udel.cis.vsl.tass.dynamic.IF.DynamicFactoryIF;
import edu.udel.cis.vsl.tass.dynamic.IF.ValueSubstituterIF;
import edu.udel.cis.vsl.tass.dynamic.IF.simplify.DynamicSimplifierIF;
import edu.udel.cis.vsl.tass.dynamic.IF.simplify.MorphicSimplifierCacheIF;
import edu.udel.cis.vsl.tass.dynamic.IF.value.MessageIF;
import edu.udel.cis.vsl.tass.dynamic.IF.value.ValueIF;
import edu.udel.cis.vsl.tass.model.IF.ModelIF;
import edu.udel.cis.vsl.tass.model.IF.ProcessIF;
import edu.udel.cis.vsl.tass.model.IF.location.LocationIF;
import edu.udel.cis.vsl.tass.model.IF.scope.ScopeIF;
import edu.udel.cis.vsl.tass.morph.MorphicArray;
import edu.udel.cis.vsl.tass.morph.MorphicArrayFactory;
import edu.udel.cis.vsl.tass.morph.MorphicFactory;
import edu.udel.cis.vsl.tass.morph.MorphicFactoryIF;
import edu.udel.cis.vsl.tass.morph.MorphicVector;
import edu.udel.cis.vsl.tass.morph.MorphicVectorFactory;
import edu.udel.cis.vsl.tass.semantics.IF.ExecutionProblem;
import edu.udel.cis.vsl.tass.semantics.IF.ExecutionProblem.Certainty;
import edu.udel.cis.vsl.tass.state.IF.FrameIF;
import edu.udel.cis.vsl.tass.state.IF.ModelStateFactoryIF;
import edu.udel.cis.vsl.tass.state.IF.ModelStateIF;
import edu.udel.cis.vsl.tass.state.IF.ProcessStateIF;
import edu.udel.cis.vsl.tass.state.IF.ScopeStateIF;

public class ModelStateFactory extends MorphicFactory<ModelStateIF> implements
		ModelStateFactoryIF {

	private DynamicFactoryIF dynamicFactory;

	private ScopeStateFactory scopeStateFactory;

	private FrameFactory frameFactory;

	private MorphicVectorFactory<ValueIF> valueVectorFactory;

	private MorphicVectorFactory<FrameIF> stackFactory;

	private ProcessStateFactory processStateFactory;

	private MorphicArrayFactory<ProcessStateIF> processStateArrayFactory;

	private MorphicArrayFactory<ValueIF> valueArrayFactory;

	private MorphicVectorFactory<MessageIF> bufferFactory;

	/** Number of instantiations of ModelState objects. */
	private int modelStateCounter = 0;

	/** Cached models, indexed by model IDs */
	private Vector<ModelIF> modelVector = new Vector<ModelIF>();

	/**
	 * Cached empty model states, indexed by model IDs. For each i, either null
	 * or the empty state (canonic) for the model with ID i.
	 */
	private Vector<ModelStateIF> emptyStateVector = new Vector<ModelStateIF>();

	/**
	 * For each heap substitution map, the corresponding simplifier.
	 */
	private Map<Map<ValueIF, ValueIF>, DynamicSimplifierIF> heapCacheMap = new HashMap<Map<ValueIF, ValueIF>, DynamicSimplifierIF>();

	public ModelStateFactory(ProcessStateFactory processStateFactory) {
		MorphicFactoryIF<MessageIF> messageFactory;

		this.processStateFactory = processStateFactory;
		this.dynamicFactory = processStateFactory.dynamicFactory();
		this.valueArrayFactory = dynamicFactory.valueArrayFactory();
		this.valueVectorFactory = dynamicFactory.valueVectorFactory();
		this.frameFactory = processStateFactory.frameFactory();
		this.scopeStateFactory = frameFactory.scopeStateFactory();
		this.stackFactory = processStateFactory.stackFactory();
		this.processStateArrayFactory = new MorphicArrayFactory<ProcessStateIF>(
				processStateFactory);
		messageFactory = dynamicFactory.messageFactory();
		this.bufferFactory = new MorphicVectorFactory<MessageIF>(messageFactory);
	}

	@Override
	public ProcessStateFactory processStateFactory() {
		return processStateFactory;
	}

	@Override
	public MorphicArrayFactory<ProcessStateIF> processStateArrayFactory() {
		return processStateArrayFactory;
	}

	@Override
	public DynamicFactoryIF dynamicFactory() {
		return dynamicFactory;
	}

	public FrameFactory frameFactory() {
		return frameFactory;
	}

	public MorphicVectorFactory<ValueIF> valueVectorFactory() {
		return valueVectorFactory;
	}

	public MorphicVectorFactory<FrameIF> stackFactory() {
		return stackFactory;
	}

	public MorphicArrayFactory<ValueIF> valueArrayFactory() {
		return valueArrayFactory;
	}

	public MorphicVectorFactory<MessageIF> bufferFactory() {
		return bufferFactory;
	}

	@Override
	public ScopeState newScopeState(ScopeIF scope, MorphicArray<ValueIF> values) {
		return scopeStateFactory.scopeState(scope, values);
	}

	@Override
	public Frame newFrame(LocationIF location,
			MorphicVector<ScopeStateIF> scopeStates) {
		return frameFactory.frame(location, scopeStates);
	}

	@Override
	public ProcessState newProcessState(MorphicArray<ValueIF> globalValues,
			MorphicVector<ValueIF> heap, MorphicVector<FrameIF> stack) {
		return processStateFactory.processState(globalValues, heap, stack);
	}

	@Override
	public ModelState newState(MorphicArray<ProcessStateIF> processStates,
			MorphicArray<ValueIF> sharedValues, MorphicVector<MessageIF> buffer) {
		ModelState newState = new ModelState(modelStateCounter, processStates,
				sharedValues, buffer);

		modelStateCounter++;
		return newState;
	}

	@Override
	public FrameIF canonic(FrameIF frame) {
		return frameFactory.canonic(frame);
	}

	@Override
	public ProcessStateIF canonic(ProcessStateIF processState) {
		return processStateFactory.canonic(processState);
	}

	@Override
	public ModelState canonic(ModelStateIF modelState) {
		ModelState result = (ModelState) super.canonic(modelState);

		if (result.canonicalId() < 0) {
			result.setCanonicalId(numStored() - 1);
		}
		return result;
	}

	@Override
	public ProcessStateIF emptyProcessState(ProcessIF process) {
		ModelIF model = process.model();
		ModelStateIF modelState = emptyState(model);

		return modelState.processState(process.pid());
	}

	@Override
	public ModelStateIF emptyState(ModelIF model) {
		int modelID = model.id();
		int vectorSize = modelVector.size();

		if (modelID >= vectorSize) {
			modelVector.setSize(modelID + 1);
			emptyStateVector.setSize(modelID + 1);
		}

		ModelStateIF emptyState = emptyStateVector.elementAt(modelID);

		if (emptyState != null)
			return emptyState;

		int numProcs = model.numProcs();
		MorphicArray<ProcessStateIF> emptyProcessStates = processStateArrayFactory
				.newArray(numProcs);

		for (int i = 0; i < numProcs; i++) {
			ProcessIF process = model.process(i);
			ProcessStateIF emptyProcessState = processStateFactory
					.processState(valueArrayFactory.newArray(process.scope()
							.numVariables()), valueVectorFactory.newVector(),
							stackFactory.newVector());

			emptyProcessStates.set(i, emptyProcessState);
		}
		emptyProcessStates = processStateArrayFactory
				.canonic(emptyProcessStates);
		emptyState = newState(emptyProcessStates,
				valueArrayFactory.newArray(model.scope().numVariables()),
				bufferFactory.newVector());
		emptyState = canonic(emptyState);
		modelVector.set(modelID, model);
		emptyStateVector.set(modelID, emptyState);
		return emptyState;
	}

	public Collection<ValueIF> values(ModelStateIF modelState) {
		Collection<ValueIF> result = new LinkedHashSet<ValueIF>();

		for (ValueIF value : modelState.sharedValues())
			if (value != null)
				result.add(value);
		for (ProcessStateIF processState : modelState.processStates())
			result.addAll(values(processState));
		for (MessageIF message : modelState.buffer()) {
			result.add(message.tag());
			result.add(message.data());
		}
		return result;
	}

	public Collection<ValueIF> values(ProcessStateIF processState) {
		Collection<ValueIF> result = new LinkedHashSet<ValueIF>();

		for (ValueIF value : processState.globalValues())
			if (value != null)
				result.add(value);
		for (ValueIF value : processState.heap())
			if (value != null)
				result.add(value);
		for (FrameIF frame : ((ProcessState) processState).stack())
			for (ScopeStateIF scopeState : frame.scopeStates())
				for (ValueIF value : scopeState.values())
					if (value != null)
						result.add(value);
		return result;
	}

	@Override
	public void canonicalizeChildren(ModelStateIF state) {
		((ModelState) state).canonicalizeChildren(valueArrayFactory,
				processStateArrayFactory, bufferFactory);
	}

	@Override
	public ModelStateSimplifier simplifier() {
		return new ModelStateSimplifier(this);
	}

	DynamicSimplifierIF heapReferenceSimplifier(
			Map<ValueIF, ValueIF> substitutionMap) throws ExecutionProblem {
		DynamicSimplifierIF result = heapCacheMap.get(substitutionMap);

		if (result == null) {
			MorphicSimplifierCacheIF heapCache = dynamicFactory
					.newSimpleCache();
			ValueSubstituterIF valueSubstituter;

			try {
				valueSubstituter = dynamicFactory
						.valueSubstituter(substitutionMap);
			} catch (DynamicException error) {
				throw new ExecutionProblem(error, Certainty.NONE);
			}
			result = dynamicFactory.referenceSimplifier(valueSubstituter,
					heapCache);
			heapCacheMap.put(substitutionMap, result);
		}
		return result;
	}

}