package common; import java.util.EventListener; import javax.swing.event.TreeModelListener; import javax.swing.tree.TreeModel; import javax.swing.tree.TreeNode; import common.beans.Bean; /** * The interface defines a suitable data model for proving * various properties about an expression. It is based on * the generic {@link javax.swing.tree.TreeModel}. * * @author Benedikt Meurer * @version $Id$ * * @see common.AbstractProofModel * @see common.ProofNode */ public interface ProofModel extends Bean, TreeModel { // // Accessors // /** * Returns the list of {@link ProofRule}s that should * be displayed as possible rules in the user interface. * This is usually a subset of the list of all available * rules for the given proof. * * The user interface should query the rules everytime * the user opens the menu/list to apply rules, as the * list of rules may have changed after an operation. * * @return the {@link ProofRule}s to be displayed in the * user interface. */ public ProofRule[] getRules(); // // Undo/Redo // /** * Returns <code>true</code> if the model has * recorded undo steps that can be redone * using the {@link #redo()} operation. * * @return <code>true</code> if {@link #redo()} * is possible, <code>false</code> otherwise. * * @see #isUndoable() * @see #redo() */ public boolean isRedoable(); /** * Returns <code>true</code> if the model has * recorded proof steps that can be undone using * the {@link #undo()} operation. * * @return <code>true</code> if {@link #undo()} * is possible, <code>false</code> otherwise. * * @see #isRedoable() * @see #undo() */ public boolean isUndoable(); /** * Redoes the previously undo change to the proof model. Use * {@link #isRedoable()} to test whether there's a change to * this model that can be redone. * * @throws CannotRedoException if the redo history is empty * or the change cannot be redone * for some other reason. * * @see #undo() */ public void redo() throws CannotRedoException; /** * Undoes the previous change to the proof model. Use * {@link #isUndoable()} to test whether there's a change * to this model that can be undone. * * @throws CannotUndoException if the undo history is empty * or the change cannot be undone * for some other reason. * * @see #redo() */ public void undo() throws CannotUndoException; // // Actions // /** * Guesses the next proof step for the specified <code>node</code>. * * The <code>node</code> must not be already proven (see the * {@link ProofNode#isProven()} method for details), otherwise * an {@link IllegalStateException} is thrown. * * @param node the {@link ProofNode} for which the next proof step should * be guessed. * * @throws IllegalArgumentException if the <code>node</code> is invalid for * this model. * @throws IllegalStateException if for some reason <code>node</code> cannot * be proven. * @throws ProofGuessException if the next proof step could not be guessed. * * @see #prove(ProofRule, ProofNode) */ public void guess(ProofNode node) throws ProofGuessException; /** * Applies the given proof <code>rule</code> to the specified * proof <code>node</code>. * * The <code>node</code> must not be already proven (see the * {@link ProofNode#isProven()} method for details), otherwise * an {@link IllegalStateException} is thrown. * * @param rule the {@link ProofRule} to apply. * @param node the {@link ProofNode} to which the <code>rule</code> * should be applied. * * @throw IllegalArgumentException if either the <code>rule</code> is * not valid for the model, or the * <code>node</code> is invalid for * the model. * @throws IllegalStateException if for some reason <code>node</code> cannot * be proven. * @throw ProofRuleException if the <code>rule</code> cannot be applied * to the <code>node</code>. * * @see #guess(ProofNode) */ public void prove(ProofRule rule, ProofNode node) throws ProofRuleException; /** * Translates the outermost expression associated with the given * <code>node</code> from syntactic sugar to core syntax. * * @param node the proof node whose outermost expression should be * translated to core syntax. * * @throws IllegalArgumentException if the <code>node</code> is * invalid for this proof model, * or the <code>node</code>'s * expression does not contain * syntactic sugar. * @throws IllegalStateException if any steps were performed on * the <code>node</code> already, * * @see expressions.Expression#translateSyntacticSugar() */ public void translateToCoreSyntax(ProofNode node); // // Tree queries // /** * Returns the root of the tree. Returns <code>null</code> * only if the tree has no nodes. * * @return the root of the proof tree. * * @see javax.swing.tree.TreeModel#getRoot() */ public ProofNode getRoot(); /** * Returns the child of <code>parent</code> at index <code>index</code> in * the <code>parent</code>'s child array. <code>parent</code> must be a node * previously obtained from this data source. This should not return <code>null</code> * if <code>index</code> is a valid index for <code>parent</code> (that is * <code>index >= 0 && index < getChildCount(parent)</code>). * * @param parent a node in the tree, obtained from this data source. * @param index the child index of a child node of <code>parent</code>. * * @return the child of <code>parent</code> at index <code>index</code>. * * @see javax.swing.tree.TreeModel#getChild(java.lang.Object, int) */ public ProofNode getChild(Object parent, int index); /** * Builds the parents of node up to and including the root node, * where the original node is the last element in the returned * array. The length of the returned array gives the node's depth * in the tree. * * @param aNode the {@link TreeNode} to get the path for. * * @return the parents of <code>aNode</code> up to and including * the root node. */ public TreeNode[] getPathToRoot(TreeNode aNode); // // Events // /** * Returns an array of all the tree model listeners registered on this * model. * * @return all of this model's {@link TreeModelListener}'s or an empty * array if no tree model listeners are currently registered. * * @see javax.swing.tree.TreeModel#addTreeModelListener(TreeModelListener) * @see javax.swing.tree.TreeModel#removeTreeModelListener(TreeModelListener) */ public TreeModelListener[] getTreeModelListeners(); /** * Returns an array of all the objects currently registered as <code><em>Foo</em>Listener</code>s * upon this model. <code><em>Foo</em>Listener</code>s are registered using the * <code>add<em>Foo</em>Listener</code> method. * * You can specify the <code>listenerType</code> argument with a class literal, such as * <code><em>Foo</em>Listener.class</code>. For example, you can query a <code>ProofModel</code> * <code>m</code> for its tree model listeners with the following code: * * <pre>TreeModelListener[] tmls = (TreeModelListener[])(m.getListeners(TreeModelListener.class));</pre> * * If no such listeners exist, this method returns an empty array. * * @param listenerType the type of listeners requested; this parameter should specify an interface * that descends from {@link EventListener}. * * @return an array of all objects registered as <code><em>Foo</em>Listener</code>s on this prover, * or an empty array if no such listeners have been added. * * @throws ClassCastException if <code>listenerType</code> doesn't specify a class or interface that * implements {@link EventListener}. * * @see #getTreeModelListeners() */ public <T extends EventListener> T[] getListeners(Class<T> listenerType); }