package bigstep.rules;
import bigstep.BigStepProofContext;
import bigstep.BigStepProofNode;
import bigstep.BigStepProofRule;
import common.ProofRuleException;
import common.interpreters.MutableStore;
import expressions.Application;
import expressions.Expression;
import expressions.UnaryOperator;
import expressions.UnaryOperatorException;
/**
* Abstract base class for all big step proof rules that handle
* unary operators.
*
* @author Benedikt Meurer
* @version $Id$
*
* @see bigstep.rules.AbstractBinaryOperatorRule
*/
abstract class AbstractUnaryOperatorRule extends BigStepProofRule {
//
// Constructor (protected)
//
/**
* Allocates a new <code>AbstractUnaryOperatorRule</code>
* with the specified <code>name</code>.
*
* @param name the name of the rule.
*/
protected AbstractUnaryOperatorRule(String name) {
super(true, name);
}
//
// Primitives
//
/**
* {@inheritDoc}
*
* @see bigstep.BigStepProofRule#apply(bigstep.BigStepProofContext, bigstep.BigStepProofNode)
*/
@Override
public final void apply(BigStepProofContext context, BigStepProofNode node) throws ProofRuleException, ClassCastException {
try {
// can only be applied to Applications
Application application = (Application)node.getExpression();
// verify that e1 and e2 are values
Expression e1 = application.getE1();
Expression e2 = application.getE2();
if (!e1.isValue() || !e2.isValue()) {
throw new ProofRuleException(node, this);
}
// allocate a new store and perform the application
MutableStore store = new MutableStore(node.getStore());
Expression value = applyTo(store, (UnaryOperator)e1, e2);
context.setProofNodeResult(node, value, store);
}
catch (UnaryOperatorException e) {
throw new ProofRuleException(node, this, e);
}
}
/**
* This method must be implemented by derived classes to handle the actual
* application of the operator <code>e1</code> to the expression <code>e2</code>,
* which is generated to be a value.
*
* Memory operators may modify the <code>store</code> as needed.
*
* @param store the {@link MutableStore} required for memory operators like <code>ref</code>.
* @param e1 the unary operator to apply to <code>e2</code>.
* @param e2 the operand, which is garantied to be a value.
*
* @return the resulting value of the operator application.
*
* @throws ClassCastException if either <code>e1</code> or <code>e2</code> is invalid
* for the operator.
* @throws UnaryOperatorException if the operator cannot be applied to <code>e2</code>.
*/
public abstract Expression applyTo(MutableStore store, UnaryOperator e1, Expression e2) throws ClassCastException, UnaryOperatorException;
}