package de.unisiegen.tpml.core ; import java.util.Iterator ; import java.util.LinkedList ; import java.util.List ; import java.util.NoSuchElementException ; import de.unisiegen.tpml.core.languages.Language ; /** * Abstract base class for classes implementing the <code>ProofRuleSet</code> * interface. * * @author Benedikt Meurer * @version $Rev$ * @see de.unisiegen.tpml.core.ProofRule * @see de.unisiegen.tpml.core.ProofRuleSet */ public abstract class AbstractProofRuleSet implements ProofRuleSet { // // Constants // /** * An empty array of <code>ProofRule</code>s, used for the * {@link #getRules()} implementation. * * @see #getRules() */ private static final ProofRule [ ] EMPTY_ARRAY = new ProofRule [ 0 ] ; // // Attributes // /** * The {@link Language} to which the proof rule set belongs. * * @see #getLanguage() */ private Language language ; /** * The set of {@link ProofRule}s in this rule set. * * @see #getRules() */ protected List < AbstractProofRule > rules = new LinkedList < AbstractProofRule > ( ) ; // // Constructor (protected) // /** * Allocates a new <code>AbstractProofRuleSet</code> with the specified * <code>language</code>. * * @param pLanguage the {@link Language} to which the rules in this proof rule * set belong. * @throws NullPointerException if <code>language</code> is * <code>null</code>. */ protected AbstractProofRuleSet ( Language pLanguage ) { if ( pLanguage == null ) { throw new NullPointerException ( "language is null" ) ; //$NON-NLS-1$ } this.language = pLanguage ; } // // Accessors // /** * {@inheritDoc} * * @see de.unisiegen.tpml.core.ProofRuleSet#getLanguage() */ public Language getLanguage ( ) { return this.language ; } /** * {@inheritDoc} * * @see de.unisiegen.tpml.core.ProofRuleSet#getRules() */ public ProofRule [ ] getRules ( ) { return this.rules.toArray ( EMPTY_ARRAY ) ; } /** * Looks up the previously registered {@link ProofRule} with the specified * <code>name</code>. * * @param name the name of the rule to look up. * @return the previously registered proof rule of the given <code>name</code>. * @throws NoSuchElementException if no rule of the given <code>name</code> * is found. * @throws NullPointerException if <code>name</code> is <code>null</code>. * @see ProofRule */ protected AbstractProofRule getRuleByName ( String name ) throws NoSuchElementException { if ( name == null ) { throw new NullPointerException ( "name is null" ) ; //$NON-NLS-1$ } for ( AbstractProofRule rule : this.rules ) { if ( rule.getName ( ).equals ( name ) ) { return rule ; } } throw new NoSuchElementException ( "No such rule of name " + name ) ; //$NON-NLS-1$ } // // Primitives // /** * {@inheritDoc} * * @see de.unisiegen.tpml.core.ProofRuleSet#contains(de.unisiegen.tpml.core.ProofRule) */ public boolean contains ( ProofRule rule ) { return this.rules.contains ( rule ) ; } /** * {@inheritDoc} * * @see java.lang.Iterable#iterator() */ public final Iterator < ProofRule > iterator ( ) { return new Iterator < ProofRule > ( ) { private Iterator < AbstractProofRule > iterator = AbstractProofRuleSet.this.rules .iterator ( ) ; public boolean hasNext ( ) { return this.iterator.hasNext ( ) ; } public ProofRule next ( ) { return this.iterator.next ( ) ; } public void remove ( ) { throw new UnsupportedOperationException ( ) ; } } ; } // // Rule registration // /** * Registers the <code>rule</code> in the proof rule set. If a rule with the * same name was already added to the proof rule set, the previous rule is * unregistered first. The <code>rule</code> is prepended to the list, which * is important for guessing, as the last registered proof rule will be used * first when guessing. So, for example, for the big step interpreter, the * <b>(APP)</b> must be registered first. * * @param rule the proof rule to register. * @throws NullPointerException if <code>rule</code> is <code>null</code>. * @see #unregister(AbstractProofRule) */ protected void register ( AbstractProofRule rule ) { if ( rule == null ) { throw new NullPointerException ( "rule is null" ) ; //$NON-NLS-1$ } // unregister any previous rule with the same name this.rules.remove ( rule ) ; // register the new rule this.rules.add ( 0 , rule ) ; } /** * Unregisters the <code>rule</code> from the proof rule set. * * @param rule the proof rule to unregister. * @throws NullPointerException if <code>rule</code> is <code>null</code>. * @see #register(AbstractProofRule) */ protected void unregister ( AbstractProofRule rule ) { if ( rule == null ) { throw new NullPointerException ( "rule is null" ) ; //$NON-NLS-1$ } // unregister the rule this.rules.remove ( rule ) ; } }