package de.unisiegen.tpml.core.bigstep ;
import java.awt.Color ;
import java.lang.reflect.InvocationTargetException ;
import de.unisiegen.tpml.core.AbstractProofRule ;
import de.unisiegen.tpml.core.ProofRuleException ;
import de.unisiegen.tpml.core.exceptions.NotOnlyFreeVariableException ;
import de.unisiegen.tpml.core.exceptions.RowSubstitutionException ;
import de.unisiegen.tpml.core.latex.DefaultLatexCommand ;
import de.unisiegen.tpml.core.latex.DefaultLatexInstruction ;
import de.unisiegen.tpml.core.latex.LatexCommandList ;
import de.unisiegen.tpml.core.latex.LatexInstructionList ;
import de.unisiegen.tpml.core.latex.LatexPackage ;
import de.unisiegen.tpml.core.latex.LatexPackageList ;
import de.unisiegen.tpml.core.latex.LatexPrintable ;
import de.unisiegen.tpml.core.latex.LatexString ;
import de.unisiegen.tpml.core.latex.LatexStringBuilder ;
import de.unisiegen.tpml.core.latex.LatexStringBuilderFactory ;
import de.unisiegen.tpml.core.prettyprinter.PrettyPrintable ;
import de.unisiegen.tpml.core.prettyprinter.PrettyString ;
import de.unisiegen.tpml.core.prettyprinter.PrettyStringBuilder ;
import de.unisiegen.tpml.core.prettyprinter.PrettyStringBuilderFactory ;
import de.unisiegen.tpml.core.typechecker.UnificationException ;
import de.unisiegen.tpml.core.util.Theme ;
/**
* Abstract base class for implementations of the <code>BigStepProofRule</code>
* interface.
*
* @author Benedikt Meurer
* @author Christian Fehler
* @version $Rev:415M $
* @see de.unisiegen.tpml.core.bigstep.BigStepProofRule
* @see de.unisiegen.tpml.core.AbstractProofRule
*/
public abstract class AbstractBigStepProofRule extends AbstractProofRule
implements BigStepProofRule
{
/**
* Returns a set of needed latex commands for this latex printable object.
*
* @return A set of needed latex commands for this latex printable object.
*/
public static LatexCommandList getLatexCommandsStatic ( )
{
LatexCommandList commands = new LatexCommandList ( ) ;
commands.add ( new DefaultLatexCommand ( LATEX_BIG_STEP_PROOF_RULE , 1 ,
"\\mbox{\\textbf{\\color{" + LATEX_COLOR_RULE + "}(#1)}}" , //$NON-NLS-1$//$NON-NLS-2$
"name" ) ) ; //$NON-NLS-1$
return commands ;
}
/**
* Returns a set of needed latex instructions for this latex printable object.
*
* @return A set of needed latex instructions for this latex printable object.
*/
public static LatexInstructionList getLatexInstructionsStatic ( )
{
LatexInstructionList instructions = new LatexInstructionList ( ) ;
Color colorRule = Theme.currentTheme ( ).getRuleColor ( ) ;
float red = ( float ) Math
.round ( ( ( float ) colorRule.getRed ( ) ) / 255 * 100 ) / 100 ;
float green = ( float ) Math
.round ( ( ( float ) colorRule.getGreen ( ) ) / 255 * 100 ) / 100 ;
float blue = ( float ) Math
.round ( ( ( float ) colorRule.getBlue ( ) ) / 255 * 100 ) / 100 ;
instructions.add ( new DefaultLatexInstruction (
"\\definecolor{" + LATEX_COLOR_RULE + "}{rgb}{" //$NON-NLS-1$ //$NON-NLS-2$
+ red + "," //$NON-NLS-1$
+ green + "," //$NON-NLS-1$
+ blue + "}" , LATEX_COLOR_RULE + ": color of proof rules" ) ) ; //$NON-NLS-1$ //$NON-NLS-2$
return instructions ;
}
/**
* Returns a set of needed latex packages for this latex printable object.
*
* @return A set of needed latex packages for this latex printable object.
*/
public static LatexPackageList getLatexPackagesStatic ( )
{
LatexPackageList packages = new LatexPackageList ( ) ;
packages.add ( LatexPackage.COLOR ) ;
return packages ;
}
/**
* Allocates a new <code>BigStepProofRule</code> with the specified
* <code>name</code>, that does nothing, meaning that
* {@link #apply(BigStepProofContext, BigStepProofNode)} and
* {@link #update(BigStepProofContext, BigStepProofNode)} are noops.
*
* @param name the name of the rule to allocate.
* @return a newly allocated <code>BigStepProofRule</code> with the
* specified <code>name</code>, that does nothing.
* @see #toExnRule(int)
*/
public static BigStepProofRule newNoopRule ( String name )
{
return new AbstractBigStepProofRule ( - 1 , name )
{
@ Override
protected void applyInternal ( @ SuppressWarnings ( "unused" )
BigStepProofContext context , @ SuppressWarnings ( "unused" )
BigStepProofNode node ) throws Exception
{
throw new IllegalArgumentException ( "Cannot apply noop rules" ) ; //$NON-NLS-1$
}
@ Override
protected void updateInternal ( @ SuppressWarnings ( "unused" )
BigStepProofContext context , @ SuppressWarnings ( "unused" )
BigStepProofNode node ) throws Exception
{
// nothing to do here...
}
} ;
}
/**
* Allocates a new <code>AbstractBigStepProofRule</code> of the specified
* <code>name</code>.
*
* @param group the group id of this big step rule, see the description of the
* {@link AbstractProofRule#getGroup()} for details.
* @param name the name of the big step proof rule to allocate.
* @throws NullPointerException if <code>name</code> is <code>null</code>.
*/
public AbstractBigStepProofRule ( int group , String name )
{
super ( group , name ) ;
}
/**
* Applies this big step proof rule to the specified <code>node</code> via
* the given <code>context</code>.
*
* @param context the big step proof context via which the application of this
* rule to the <code>node</code> should be performed.
* @param node the big step proof node to which to apply this rule.
* @throws ProofRuleException if this rule cannot be applied to the
* <code>node</code>.
* @throws NullPointerException if either <code>context</code> or
* <code>node</code> is <code>null</code>.
*/
public void apply ( BigStepProofContext context , BigStepProofNode node )
throws ProofRuleException
{
if ( node == null )
{
throw new NullPointerException ( "node is null" ) ; //$NON-NLS-1$
}
if ( context == null )
{
throw new NullPointerException ( "context is null" ) ; //$NON-NLS-1$
}
try
{
applyInternal ( context , node ) ;
}
catch ( ProofRuleException e )
{
throw e ;
}
catch ( InvocationTargetException e )
{
if ( ( e.getTargetException ( ) instanceof NotOnlyFreeVariableException )
|| ( e.getTargetException ( ) instanceof RowSubstitutionException ) )
{
throw new RuntimeException ( e.getTargetException ( ).getMessage ( ) ) ;
}
throw new ProofRuleException ( node , this , e.getTargetException ( ) ) ;
}
catch ( Exception e )
{
// check if e contains a usable error message
for ( Throwable t = e ; t != null ; t = t.getCause ( ) )
{
if ( t instanceof IllegalArgumentException
&& t instanceof UnificationException )
{
throw new ProofRuleException ( t.getMessage ( ) , node , this , e ) ;
}
}
throw new ProofRuleException ( node , this , e ) ;
}
}
/**
* Abstract internal apply method, implemented by the
* {@link AbstractBigStepProofRuleSet} class while registering new proof
* rules.
*
* @param context see {@link #apply(BigStepProofContext, BigStepProofNode)}.
* @param node see {@link #apply(BigStepProofContext, BigStepProofNode)}.
* @throws Exception if an error occurs while applying the rule to the
* <code>node</code> using the <code>context</code>.
* @see #apply(BigStepProofContext, BigStepProofNode)
*/
protected abstract void applyInternal ( BigStepProofContext context ,
BigStepProofNode node ) throws Exception ;
/**
* Returns a set of needed latex commands for this latex printable object.
*
* @return A set of needed latex commands for this latex printable object.
*/
public LatexCommandList getLatexCommands ( )
{
LatexCommandList commands = new LatexCommandList ( ) ;
commands.add ( getLatexCommandsStatic ( ) ) ;
return commands ;
}
/**
* Returns a set of needed latex instructions for this latex printable object.
*
* @return A set of needed latex instructions for this latex printable object.
*/
public LatexInstructionList getLatexInstructions ( )
{
LatexInstructionList instructions = new LatexInstructionList ( ) ;
instructions.add ( getLatexInstructionsStatic ( ) ) ;
return instructions ;
}
/**
* Returns a set of needed latex packages for this latex printable object.
*
* @return A set of needed latex packages for this latex printable object.
*/
public LatexPackageList getLatexPackages ( )
{
LatexPackageList packages = new LatexPackageList ( ) ;
packages.add ( getLatexPackagesStatic ( ) ) ;
return packages ;
}
/**
* Translates this big step proof rule to an appropriate exception rule, with
* the given sub node index <code>n</code>. For example, for <b>(APP)</b>,
* this generates <b>(APP-EXN-n)</b>.
*
* @param n the index of the sub node, starting at <code>0</code>.
* @return the new {@link BigStepProofRule} for the exception.
* @throws IllegalArgumentException if <code>n</code> is negative.
*/
BigStepProofRule toExnRule ( int n )
{
if ( n < 0 )
{
throw new IllegalArgumentException ( "n is negative" ) ; //$NON-NLS-1$
}
return newNoopRule ( getName ( ) + "-EXN-" + ( n + 1 ) ) ; //$NON-NLS-1$
}
/**
* {@inheritDoc}
*
* @see LatexPrintable#toLatexString()
*/
public final LatexString toLatexString ( )
{
return toLatexStringBuilder ( LatexStringBuilderFactory.newInstance ( ) , 0 )
.toLatexString ( ) ;
}
/**
* {@inheritDoc}
*
* @see LatexPrintable#toLatexStringBuilder(LatexStringBuilderFactory,int)
*/
public final LatexStringBuilder toLatexStringBuilder (
LatexStringBuilderFactory pLatexStringBuilderFactory , int pIndent )
{
LatexStringBuilder builder = pLatexStringBuilderFactory.newBuilder ( 0 ,
LATEX_BIG_STEP_PROOF_RULE , pIndent , this.toPrettyString ( )
.toString ( ) ) ;
builder
.addText ( "{" + this.getName ( ).replaceAll ( "_" , "\\\\_" ) + "}" ) ; //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
return builder ;
}
/**
* {@inheritDoc}
*
* @see PrettyPrintable#toPrettyString()
*/
public final PrettyString toPrettyString ( )
{
return toPrettyStringBuilder ( PrettyStringBuilderFactory.newInstance ( ) )
.toPrettyString ( ) ;
}
/**
* {@inheritDoc}
*
* @see PrettyPrintable#toPrettyStringBuilder(PrettyStringBuilderFactory)
*/
public PrettyStringBuilder toPrettyStringBuilder (
PrettyStringBuilderFactory pPrettyStringBuilderFactory )
{
PrettyStringBuilder builder = pPrettyStringBuilderFactory.newBuilder (
this , 0 ) ;
builder.addText ( PRETTY_LPAREN ) ;
builder.addText ( this.getName ( ) ) ;
builder.addText ( PRETTY_RPAREN ) ;
return builder ;
}
/**
* Returns the string representation for this proof rule. This method is
* mainly used for debugging.
*
* @return The pretty printed string representation for this proof rule.
* @see #toPrettyString()
* @see Object#toString()
*/
@ Override
public final String toString ( )
{
return toPrettyString ( ).toString ( ) ;
}
/**
* Updates the specified <code>node</code> as part of a previous rule
* application for <code>context</code>. This method is only interesting
* for non-axiom rules, like <b>(APP)</b> or <b>(LET)</b>, that need to
* update their created proof nodes even after applications of other proof
* rules to subtrees. This method is only invoked for proof nodes that are not
* already proven (see {@link de.unisiegen.tpml.core.ProofNode#isProven()}).
* If <code>node</code> is proven, this represents a bug in the big step
* proof model logic.
*
* @param context the main proof context, which was previously specified as
* parameter to an
* {@link #apply(BigStepProofContext, BigStepProofNode)} invokation
* on another proof node, possibly with another proof rule.
* @param node the {@link BigStepProofNode} that may need to be updated.
* @throws NullPointerException if <code>context</code> or <code>node</code>
* is <code>null</code>.
*/
public void update ( BigStepProofContext context , BigStepProofNode node )
{
if ( node == null )
{
throw new NullPointerException ( "node is null" ) ; //$NON-NLS-1$
}
if ( context == null )
{
throw new NullPointerException ( "context is null" ) ; //$NON-NLS-1$
}
try
{
updateInternal ( context , node ) ;
}
catch ( RuntimeException e )
{
throw e ;
}
catch ( InvocationTargetException e )
{
throw new RuntimeException ( e.getTargetException ( ).getMessage ( ) ) ;
}
catch ( Exception e )
{
throw new RuntimeException ( e ) ;
}
}
/**
* Abstract internal update method, implemented by the
* {@link AbstractBigStepProofRuleSet} class while registering new proof
* rules.
*
* @param context see {@link #update(BigStepProofContext, BigStepProofNode)}.
* @param node see {@link #update(BigStepProofContext, BigStepProofNode)}.
* @throws Exception if an error occurs while updating the <code>node</code>
* using the <code>context</code>.
*/
protected abstract void updateInternal ( BigStepProofContext context ,
BigStepProofNode node ) throws Exception ;
}