ValueExplorer.java
package edu.udel.cis.vsl.tass.dynamic.impl.value;
import java.util.Collection;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.Set;
import edu.udel.cis.vsl.tass.dynamic.IF.type.ArrayValueTypeIF;
import edu.udel.cis.vsl.tass.dynamic.IF.type.FunctionValueTypeIF;
import edu.udel.cis.vsl.tass.dynamic.IF.type.PrimitiveValueTypeIF;
import edu.udel.cis.vsl.tass.dynamic.IF.type.RecordValueTypeIF;
import edu.udel.cis.vsl.tass.dynamic.IF.type.ReferenceValueTypeIF;
import edu.udel.cis.vsl.tass.dynamic.IF.type.ValueTypeIF;
import edu.udel.cis.vsl.tass.dynamic.IF.type.VectorValueTypeIF;
import edu.udel.cis.vsl.tass.dynamic.IF.value.ValueIF;
import edu.udel.cis.vsl.tass.morph.MorphicVector;
import edu.udel.cis.vsl.tass.symbolic.IF.SymbolicConstantIF;
import edu.udel.cis.vsl.tass.symbolic.IF.SymbolicExpressionIF;
import edu.udel.cis.vsl.tass.symbolic.IF.SymbolicUniverseIF;
import edu.udel.cis.vsl.tass.symbolic.IF.tree.SymbolicConstantExpressionIF;
import edu.udel.cis.vsl.tass.symbolic.IF.tree.TreeExpressionIF;
public class ValueExplorer {
private SymbolicUniverseIF universe;
private Set<ValueIF> seenValues = null;
private Set<ValueTypeIF> seenTypes = null;
public ValueExplorer(SymbolicUniverseIF universe) {
this.universe = universe;
}
/**
* Returns the set of all symbolic constants referenced within the value or
* the type of the value.
*/
public Collection<SymbolicConstantIF> symbolicConstants(
Collection<ValueIF> valueSet) {
Collection<SymbolicConstantIF> result = new LinkedHashSet<SymbolicConstantIF>();
seenValues = new HashSet<ValueIF>();
seenTypes = new HashSet<ValueTypeIF>();
for (ValueIF value : valueSet)
findSymbolicConstants(value, result);
seenValues = null;
seenTypes = null;
return result;
}
private void findSymbolicConstants(ValueIF value,
Collection<SymbolicConstantIF> set) {
assert value != null;
if (seenValues.add(value)) {
if (value instanceof SymbolicValue) {
findSymbolicConstants((SymbolicValue) value, set);
} else if (value instanceof ArrayValue) {
findSymbolicConstants((ArrayValue) value, set);
} else if (value instanceof RecordValue) {
findSymbolicConstants((RecordValue) value, set);
} else if (value instanceof ReferenceValue) {
findSymbolicConstants((ReferenceValue) value, set);
} else if (value instanceof VectorValue) {
findSymbolicConstants((VectorValue) value, set);
} else if (value instanceof UndefinedValue) {
} else {
throw new RuntimeException("Unknown kind of value: " + value);
}
findSymbolicConstants(value.valueType(), set);
}
}
private void findSymbolicConstants(SymbolicValue value,
Collection<SymbolicConstantIF> set) {
TreeExpressionIF tree = universe.tree(value.getSymbolicExpression());
findSymbolicConstants(tree, set);
}
private void findSymbolicConstants(TreeExpressionIF tree,
Collection<SymbolicConstantIF> set) {
if (tree instanceof SymbolicConstantExpressionIF) {
set.add(((SymbolicConstantExpressionIF) tree).symbolicConstant());
} else {
int numArgs = tree.numArguments();
for (int i = 0; i < numArgs; i++)
findSymbolicConstants(tree.argument(i), set);
}
}
private void findSymbolicConstants(ArrayValue array,
Collection<SymbolicConstantIF> set) {
SymbolicExpressionIF origin = array.origin();
TreeExpressionIF originTree = universe.tree(origin);
MorphicVector<ValueIF> elements = array.elements();
findSymbolicConstants(originTree, set);
for (ValueIF element : elements) {
if (element != null)
findSymbolicConstants(element, set);
}
}
private void findSymbolicConstants(VectorValue vector,
Collection<SymbolicConstantIF> set) {
for (ValueIF element : vector) {
if (element != null)
findSymbolicConstants(element, set);
}
}
private void findSymbolicConstants(RecordValue record,
Collection<SymbolicConstantIF> set) {
RecordValueTypeIF valueType = record.valueType();
int numElements = valueType.type().numFields();
for (int i = 0; i < numElements; i++)
findSymbolicConstants(record.element(i), set);
}
private void findSymbolicConstants(ReferenceValue reference,
Collection<SymbolicConstantIF> set) {
if (reference.isNull()) {
} else {
ReferenceValue parent = (ReferenceValue) reference.parent();
if (parent != null)
findSymbolicConstants(parent, set);
if (reference instanceof VariableReferenceValue) {
} else if (reference instanceof ArrayElementReferenceValue) {
ArrayElementReferenceValue arrayElementReference = (ArrayElementReferenceValue) reference;
findSymbolicConstants(arrayElementReference.index(), set);
} else if (reference instanceof RecordElementReferenceValue) {
} else if (reference instanceof VectorElementReferenceValue) {
} else {
throw new RuntimeException("Unknown reference type: "
+ reference);
}
}
}
private void findSymbolicConstants(ValueTypeIF type,
Collection<SymbolicConstantIF> set) {
if (seenTypes.add(type)) {
if (type instanceof PrimitiveValueTypeIF) {
} else if (type instanceof ArrayValueTypeIF) {
ArrayValueTypeIF arrayType = (ArrayValueTypeIF) type;
findSymbolicConstants(arrayType.baseType(), set);
findSymbolicConstants(arrayType.lengthVector(), set);
} else if (type instanceof VectorValueTypeIF) {
findSymbolicConstants(((VectorValueTypeIF) type).elementType(),
set);
} else if (type instanceof FunctionValueTypeIF) {
FunctionValueTypeIF functionType = (FunctionValueTypeIF) type;
int numArgs = functionType.numArguments();
findSymbolicConstants(functionType.returnType(), set);
for (int i = 0; i < numArgs; i++) {
findSymbolicConstants(functionType.argumentType(i), set);
}
} else if (type instanceof RecordValueTypeIF) {
RecordValueTypeIF recordValueType = (RecordValueTypeIF) type;
int numFields = recordValueType.type().numFields();
for (int i = 0; i < numFields; i++)
findSymbolicConstants(recordValueType.fieldType(i), set);
} else if (type instanceof ReferenceValueTypeIF) {
ValueTypeIF baseType = ((ReferenceValueTypeIF) type).baseType();
if (baseType != null)
findSymbolicConstants(baseType, set);
} else {
throw new RuntimeException("Unknown type: " + type);
}
}
}
}