EvaluatedFunctionExpression.java
package edu.udel.cis.vsl.tass.symbolic.function;
import java.util.Arrays;
import edu.udel.cis.vsl.tass.symbolic.BooleanPrimitive;
import edu.udel.cis.vsl.tass.symbolic.NumericPrimitive;
import edu.udel.cis.vsl.tass.symbolic.IF.tree.TreeExpressionIF;
import edu.udel.cis.vsl.tass.symbolic.IF.type.SymbolicFunctionTypeIF;
import edu.udel.cis.vsl.tass.symbolic.IF.type.SymbolicTypeIF;
import edu.udel.cis.vsl.tass.symbolic.expression.SymbolicExpression;
/**
* An object of this class represents an expression of the form
* f(x_{0},...,x_{n-1}), i.e., the application of a function f to a list of n
* arguments.
*/
public class EvaluatedFunctionExpression extends SymbolicExpression implements
NumericPrimitive, BooleanPrimitive {
/** The function f */
private TreeExpressionIF function;
/** The list of arguments. */
private TreeExpressionIF[] arguments;
/**
* Constructs new evaluated function expression using the given given
* function and arguments array. The type of function must be an instance of
* SymbolicFunctionTypeIF. The type of this expression is the output type of
* the function. The array arguments may not be null, but it may have length
* 0. The types of the arguments must correspond (by equals) to the inputs
* types of the function.
*/
EvaluatedFunctionExpression(TreeExpressionIF function,
TreeExpressionIF[] arguments) {
super(((SymbolicFunctionTypeIF) function.type()).outputType());
assert arguments != null;
int numArgs = arguments.length;
SymbolicFunctionTypeIF functionType = (SymbolicFunctionTypeIF) function
.type();
this.function = function;
if (numArgs != functionType.numInputs()) {
throw new IllegalArgumentException("Wrong number of arguments to "
+ function + ": saw " + numArgs + ", expected "
+ functionType.numInputs());
}
for (int i = 0; i < numArgs; i++) {
SymbolicTypeIF argumentType = arguments[i].type();
SymbolicTypeIF expectedType = functionType.inputType(i);
if (!argumentType.equals(expectedType)) {
throw new IllegalArgumentException(
"Error in application of function " + function
+ " argument " + i + ": expected type "
+ expectedType + ", saw type " + argumentType);
}
}
this.arguments = arguments;
}
/** Returns the function f. */
public TreeExpressionIF function() {
return function;
}
/** Returns the i-th argument, counting from 0. */
public TreeExpressionIF functionArgument(int index) {
return arguments[index];
}
/** Returns the array of arguments. Don't modify this array. */
public TreeExpressionIF[] arguments() {
return arguments;
}
public String atomString() {
String result = function.atomString() + "(";
int numArgs = arguments.length;
for (int i = 0; i < numArgs; i++) {
if (i > 0)
result += ", ";
result += arguments[i].toString();
}
result += ")";
return result;
}
public String toString() {
return atomString();
}
protected int intrinsicHashCode() {
return function.hashCode() + Arrays.hashCode(arguments);
}
protected boolean intrinsicEquals(SymbolicExpression thatExpression) {
if (thatExpression instanceof EvaluatedFunctionExpression) {
EvaluatedFunctionExpression that = (EvaluatedFunctionExpression) thatExpression;
return function.equals(that.function)
&& Arrays.equals(arguments, that.arguments);
}
return false;
}
public NumericPrimitiveKind numericPrimitiveKind() {
return NumericPrimitiveKind.APPLY;
}
public BooleanPrimitiveKind booleanPrimitiveKind() {
return BooleanPrimitiveKind.APPLY;
}
public TreeExpressionIF argument(int index) {
if (index == 0) {
return function;
} else {
return arguments[index - 1];
}
}
public SymbolicKind kind() {
return SymbolicKind.APPLY;
}
public int numArguments() {
return arguments.length + 1;
}
}