package bigstep; import bigstep.rules.AndFalseRule; import bigstep.rules.AndTrueRule; import bigstep.rules.AppRule; import bigstep.rules.AssignRule; import bigstep.rules.BetaValueRule; import bigstep.rules.BopRule; import bigstep.rules.CondFalseRule; import bigstep.rules.CondTrueRule; import bigstep.rules.ConsRule; import bigstep.rules.DerefRule; import bigstep.rules.HdRule; import bigstep.rules.IsEmptyFalseRule; import bigstep.rules.IsEmptyTrueRule; import bigstep.rules.LetRule; import bigstep.rules.ListRule; import bigstep.rules.OrFalseRule; import bigstep.rules.OrTrueRule; import bigstep.rules.ProjRule; import bigstep.rules.RefRule; import bigstep.rules.SeqRule; import bigstep.rules.TlRule; import bigstep.rules.TupleRule; import bigstep.rules.UnfoldRule; import bigstep.rules.UopRule; import bigstep.rules.ValRule; import bigstep.rules.WhileRule; import common.ProofGuessException; import common.ProofNode; import common.ProofRule; import common.ProofRuleException; import common.ProofStep; import common.interpreters.AbstractInterpreterProofModel; import common.interpreters.Store; import expressions.Expression; /** * TODO Add documentation here. * * @author Benedikt Meurer * @version $Id$ */ public final class BigStepProofModel extends AbstractInterpreterProofModel { // // Constructor (package) // /** * Allocates a new <code>BigStepProofModel</code> to * prove the specified <code>expression</code>. * * @param expression the {@link Expression} to prove. */ BigStepProofModel(Expression expression) { super(new DefaultBigStepProofNode(expression)); // tell the view that stores should be displayed // if the supplied expression contains any refe- // rences or memory locations setMemoryEnabled(expression.containsReferences()); } // // Accessors // /** * {@inheritDoc} * * @see common.AbstractProofModel#getRules() */ @Override public ProofRule[] getRules() { return new BigStepProofRule[] { new ValRule(), new ConsRule(), new IsEmptyFalseRule(), new IsEmptyTrueRule(), new HdRule(), new TlRule(), new ProjRule(), new BetaValueRule(), new AssignRule(), new BopRule(), new UopRule(), new RefRule(), new DerefRule(), new AppRule(), new CondFalseRule(), new CondTrueRule(), new LetRule(), new UnfoldRule(), new SeqRule(), new ListRule(), new TupleRule(), new AndFalseRule(), new AndTrueRule(), new OrFalseRule(), new OrTrueRule(), new WhileRule(), }; } // // Actions // /** * {@inheritDoc} * * @see common.AbstractProofModel#guess(common.ProofNode) */ @Override public void guess(ProofNode node) throws ProofGuessException { // verify that the node is valid for the model if (!this.root.isNodeRelated(node)) { throw new IllegalArgumentException("The node is invalid for the model"); } // verify that we did not already applied a rule to that node if (node.getSteps().length > 0) { throw new IllegalArgumentException("The node is already completed"); } // try to guess the next rule for the next for (ProofRule rule : getRules()) { try { // try to apply the rule to the specified node apply((BigStepProofRule)rule, (DefaultBigStepProofNode)node); // yep, we did it return; } catch (ProofRuleException e) { // next one, please continue; } } // unable to guess next step throw new ProofGuessException(node); } /** * {@inheritDoc} * * @see common.AbstractProofModel#prove(common.ProofRule, common.ProofNode) */ @Override public void prove(ProofRule rule, ProofNode node) throws ProofRuleException { // verify that the rule is a big step rule if (!(rule instanceof BigStepProofRule)) { throw new IllegalArgumentException("The rule must be a big step proof rule"); } // verify that the node is valid for the model if (!this.root.isNodeRelated(node)) { throw new IllegalArgumentException("The node is invalid for the model"); } // verify that we did not already applied a rule to that node if (node.getSteps().length > 0) { throw new IllegalArgumentException("The node is already completed"); } // try to apply the rule to the specified node apply((BigStepProofRule)rule, (DefaultBigStepProofNode)node); } // // Rule application // /** * TODO Add documentation here. */ private void apply(final BigStepProofRule rule, final DefaultBigStepProofNode node) throws ProofRuleException { // allocate a new big step proof context DefaultBigStepProofContext context = new DefaultBigStepProofContext(this); try { // try to apply the rule to the node context.apply(rule, node); // determine the redo and undo actions from the context final Runnable redoActions = context.getRedoActions(); final Runnable undoActions = context.getUndoActions(); // record the undo edit action for this proof step addUndoableTreeEdit(new UndoableTreeEdit() { public void redo() { redoActions.run(); } public void undo() { undoActions.run(); } }); } catch (ProofRuleException e) { // revert the actions performed so far context.revert(); // re-throw the exception throw e; } } // // Proof context support // /** * TODO Add documentation here. */ void contextAddProofNode(DefaultBigStepProofContext context, final DefaultBigStepProofNode node, final Expression expression, Store store) { final DefaultBigStepProofNode child = new DefaultBigStepProofNode(expression, store); context.addRedoAction(new Runnable() { public void run() { node.add(child); nodesWereInserted(node, new int[] { node.getIndex(child) }); } }); context.addUndoAction(new Runnable() { public void run() { int index = node.getIndex(child); node.remove(index); nodesWereRemoved(node, new int[] { index }, new Object[] { child }); } }); } /** * TODO Add documentation here. */ void contextSetProofNodeResult(DefaultBigStepProofContext context, final DefaultBigStepProofNode node, final BigStepProofResult result) { final BigStepProofResult oldResult = node.getResult(); context.addRedoAction(new Runnable() { public void run() { node.setResult(result); nodeChanged(node); } }); context.addUndoAction(new Runnable() { public void run() { node.setResult(oldResult); nodeChanged(node); } }); } /** * TODO Add documentation here. */ void contextSetProofNodeRule(DefaultBigStepProofContext context, final DefaultBigStepProofNode node, final BigStepProofRule rule) { final ProofStep[] oldSteps = node.getSteps(); context.addRedoAction(new Runnable() { public void run() { node.setSteps(new ProofStep[] { new ProofStep(node.getExpression(), rule) }); nodeChanged(node); } }); context.addUndoAction(new Runnable() { public void run() { node.setSteps(oldSteps); nodeChanged(node); } }); } }