package typing;
import expressions.Expression;
/**
* A type judgement is the atomic item of the typing proof, it
* consists of the expression, for which the type should be
* determined, the type environment within which the type
* of the expression should be determined, and the type of
* the expression (may be a type variable of no concrete
* type is known).
*
* @author Benedikt Meurer
* @version $Id$
*/
public final class Judgement {
/**
* Allocates a new type {@link Judgement} with the given
* <code>environment</code>, <code>expression</code> and
* <code>type</code>.
*
* @param environment the type {@link Environment} in which to
* determine the type of expression.
* @param expression the {@link Expression} for which a type
* should be determined.
* @param type the {@link MonoType} for this judgement, which may be
* a {@link TypeVariable} if no concrete type is known
* yet.
*/
Judgement(Environment environment, Expression expression, MonoType type) {
this.environment = environment;
this.expression = expression;
this.type = type;
}
/**
* Returns the type environment for this type judgement,
* that is, the environment in which the type of the
* expression was determined.
*
* @return the type environment for this type judgement.
*/
public Environment getEnvironment() {
return this.environment;
}
/**
* Returns the expression for this type judgement.
*
* @return the expression for this type judgement.
*/
public Expression getExpression() {
return this.expression;
}
/**
* Return the type for this type judgement, which is
* either a type variable or a concrete type.
*
* @return the monomorphic type for this judgement.
*/
public MonoType getType() {
return this.type;
}
/**
* Applies the <code>substitution</code> to the environment
* and the type of this judgement.
*
* @param substitution the {@link Substitution} to apply.
* @param typeVariableAllocator the {@link TypeVariableAllocator} for the
* {@link Environment#substitute(Substitution, TypeVariableAllocator)}.
*
* @return the new judgement.
*
* @see Environment#substitute(Substitution, TypeVariableAllocator)
*/
Judgement substitute(Substitution substitution, TypeVariableAllocator typeVariableAllocator) {
// apply the substitution to the environment
Environment environment = this.environment.substitute(substitution, typeVariableAllocator);
// apply the substitution to the type
MonoType type = this.type.substitute(substitution);
// check if anything changed
if (environment != this.environment || type != this.type)
return new Judgement(environment, this.expression, type);
else
return this;
}
/**
* Returns <code>true</code> if <code>obj</code> is a
* {@link Judgement} and is equal to this type judgement.
*
* @param obj another object.
*
* @return <code>true</code> if the <code>obj</code> is
* equal to this judgement.
*
* @see java.lang.Object#equals(java.lang.Object)
*/
@Override
public boolean equals(Object obj) {
if (obj == this) {
return true;
}
else if (obj instanceof Judgement) {
Judgement judgement = (Judgement)obj;
return (this.environment.equals(judgement.environment)
&& this.expression.equals(judgement.expression)
&& this.type.equals(judgement.type));
}
else {
return false;
}
}
/**
* Returns a string representation of the type judgement,
* which is primarly useful for debugging purposes.
*
* @return the string represention of the type judgement.
*
* @see java.lang.Object#toString()
*/
@Override
public String toString() {
return this.environment + " > " + this.expression + " :: " + this.type;
}
// member attributes
private Environment environment;
private Expression expression;
private MonoType type;
}