package de.unisiegen.tpml.core.bigstep ; import javax.swing.tree.TreeNode ; import de.unisiegen.tpml.core.ProofStep ; import de.unisiegen.tpml.core.expressions.Expression ; import de.unisiegen.tpml.core.interpreters.AbstractInterpreterProofNode ; import de.unisiegen.tpml.core.interpreters.DefaultStore ; import de.unisiegen.tpml.core.interpreters.Store ; 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 ; /** * Default implementation of the <code>BigStepProofNode</code> interface. The * class for nodes in a {@link de.unisiegen.tpml.core.bigstep.BigStepProofModel}. * * @author Benedikt Meurer * @version $Rev$ * @see de.unisiegen.tpml.core.bigstep.BigStepProofNode * @see de.unisiegen.tpml.core.interpreters.AbstractInterpreterProofNode */ public final class DefaultBigStepProofNode extends AbstractInterpreterProofNode implements BigStepProofNode { /** * 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_BYRULE , 1 , "\\hspace{-5mm}\\mbox{\\scriptsize\\ #1}" , "rule" ) ) ; //$NON-NLS-1$ //$NON-NLS-2$ commands .add ( new DefaultLatexCommand ( LATEX_BIG_STEP_PROOF_NODE , 7 , LATEX_LINE_BREAK_NEW_COMMAND + "\\ifarrows" //$NON-NLS-1$ + LATEX_LINE_BREAK_NEW_COMMAND + "\\else \\refstepcounter{node}" //$NON-NLS-1$ + LATEX_LINE_BREAK_NEW_COMMAND + "\\noindent\\hspace{\\treeindent}\\hspace{#2\\nodeindent}" //$NON-NLS-1$ + LATEX_LINE_BREAK_NEW_COMMAND + "\\rnode{\\thetree.#1}{\\makebox[6mm]{(\\thenode)}}\\label{\\thetree.#1}" //$NON-NLS-1$ + LATEX_LINE_BREAK_NEW_COMMAND + "$\\begin{tabular}[t]{p{#7}}$" //$NON-NLS-1$ + LATEX_LINE_BREAK_NEW_COMMAND_INDENT1 + "\\ifthenelse{\\equal{#4}{}}" //$NON-NLS-1$ + LATEX_LINE_BREAK_NEW_COMMAND_INDENT2 // begin of the node variables + "{#3\\ \\color{" + LATEX_COLOR_NONE + "}{\\Downarrow}\\ #5}" //$NON-NLS-1$ //$NON-NLS-2$ + LATEX_LINE_BREAK_NEW_COMMAND_INDENT2 + "{\\color{" //$NON-NLS-1$ + LATEX_COLOR_NONE + "}{(}#3\\ \\ #4\\color{" //$NON-NLS-1$ + LATEX_COLOR_NONE + "}{)}\\ \\color{" + LATEX_COLOR_NONE //$NON-NLS-1$ + "}{\\Downarrow}\\ #5}" + LATEX_LINE_BREAK_NEW_COMMAND //$NON-NLS-1$ + "$\\\\$" + LATEX_LINE_BREAK_NEW_COMMAND_INDENT1 //$NON-NLS-1$ + "\\byrule{#6}" //$NON-NLS-1$ // end of the node variables + LATEX_LINE_BREAK_NEW_COMMAND + "$\\end{tabular}$" //$NON-NLS-1$ + LATEX_LINE_BREAK_NEW_COMMAND + "\\vspace{\\nodesep}" //$NON-NLS-1$ + LATEX_LINE_BREAK_NEW_COMMAND + "\\fi" , "depth" , "id" , "e" , //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ "store" , "result" , "proofrule" , "space" ) ) ; //$NON-NLS-1$ //$NON-NLS-2$//$NON-NLS-3$ //$NON-NLS-4$ 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 ( ) ; instructions.add ( new DefaultLatexInstruction ( "\\newcounter{tree}" ) ) ; //$NON-NLS-1$ instructions .add ( new DefaultLatexInstruction ( "\\newcounter{node}[tree]" ) ) ; //$NON-NLS-1$ instructions.add ( new DefaultLatexInstruction ( "\\newlength{\\treeindent}" ) ) ; //$NON-NLS-1$ instructions.add ( new DefaultLatexInstruction ( "\\newlength{\\nodeindent}" ) ) ; //$NON-NLS-1$ instructions .add ( new DefaultLatexInstruction ( "\\newlength{\\nodesep}" ) ) ; //$NON-NLS-1$ instructions.add ( new DefaultLatexInstruction ( "\\newif\\ifarrows" + LATEX_LINE_BREAK_SOURCE_CODE //$NON-NLS-1$ + "\\arrowsfalse" ) ) ; //$NON-NLS-1$ instructions.add ( new DefaultLatexInstruction ( "\\definecolor{" //$NON-NLS-1$ + LATEX_COLOR_NONE + "}{rgb}{0.0,0.0,0.0}" , //$NON-NLS-1$ LATEX_COLOR_NONE + ": color of normal text" ) ) ; //$NON-NLS-1$ 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.AMSMATH ) ; packages.add ( LatexPackage.AMSTEXT ) ; packages.add ( LatexPackage.COLOR ) ; packages.add ( LatexPackage.IFTHEN ) ; packages.add ( LatexPackage.PSTNODE ) ; packages.add ( LatexPackage.PSTRICKS ) ; return packages ; } /** * The result of the evaluation of the expression at this node. May be either * <code>null</code> if the node is not yet proven, or a value (see * {@link Expression#isValue()}) or an exception (see * {@link Expression#isException()}) with a store. * * @see #getResult() * @see #setResult(BigStepProofResult) */ private BigStepProofResult result ; /** * Convenience wrapper for {@link #DefaultBigStepProofNode(Expression, Store)}, * which passes an empty {@link Store} for the <code>store</code> parameter. * * @param pExpression the {@link Expression} for this node. * @throws NullPointerException if <code>expression</code> is * <code>null</code>. */ public DefaultBigStepProofNode ( Expression pExpression ) { this ( pExpression , new DefaultStore ( ) ) ; } /** * Allocates a new <code>DefaultBigStepProofNode</code> with the specified * <code>expression</code> and <code>store</code>. * * @param pExpression the {@link Expression} for this node. * @param store the {@link Store} for this node. * @throws NullPointerException if either <code>expression</code> or * <code>store</code> is <code>null</code>. */ public DefaultBigStepProofNode ( Expression pExpression , Store store ) { super ( pExpression , store ) ; } /** * {@inheritDoc} * * @see de.unisiegen.tpml.core.AbstractProofNode#getChildAfter(javax.swing.tree.TreeNode) */ @ Override public DefaultBigStepProofNode getChildAfter ( TreeNode aChild ) { return ( DefaultBigStepProofNode ) super.getChildAfter ( aChild ) ; } /** * {@inheritDoc} * * @see de.unisiegen.tpml.core.AbstractProofNode#getChildAt(int) */ @ Override public DefaultBigStepProofNode getChildAt ( int childIndex ) { return ( DefaultBigStepProofNode ) super.getChildAt ( childIndex ) ; } /** * {@inheritDoc} * * @see de.unisiegen.tpml.core.AbstractProofNode#getChildBefore(javax.swing.tree.TreeNode) */ @ Override public DefaultBigStepProofNode getChildBefore ( TreeNode aChild ) { return ( DefaultBigStepProofNode ) super.getChildBefore ( aChild ) ; } /** * {@inheritDoc} * * @see de.unisiegen.tpml.core.AbstractProofNode#getFirstChild() */ @ Override public DefaultBigStepProofNode getFirstChild ( ) { return ( DefaultBigStepProofNode ) super.getFirstChild ( ) ; } /** * {@inheritDoc} * * @see de.unisiegen.tpml.core.AbstractProofNode#getFirstLeaf() */ @ Override public DefaultBigStepProofNode getFirstLeaf ( ) { return ( DefaultBigStepProofNode ) super.getFirstLeaf ( ) ; } /** * {@inheritDoc} * * @see de.unisiegen.tpml.core.AbstractProofNode#getLastChild() */ @ Override public DefaultBigStepProofNode getLastChild ( ) { return ( DefaultBigStepProofNode ) super.getLastChild ( ) ; } /** * {@inheritDoc} * * @see de.unisiegen.tpml.core.AbstractProofNode#getLastLeaf() */ @ Override public DefaultBigStepProofNode getLastLeaf ( ) { return ( DefaultBigStepProofNode ) super.getLastLeaf ( ) ; } /** * 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 ( ) ) ; commands.add ( this.expression ) ; commands.add ( getStore ( ) ) ; commands.add ( this.result ) ; commands.add ( getRule ( ) ) ; 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 ( ) ) ; instructions.add ( this.expression ) ; instructions.add ( this.getStore ( ) ) ; instructions.add ( this.result ) ; instructions.add ( getRule ( ) ) ; 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 ( ) ) ; packages.add ( this.expression ) ; packages.add ( this.getStore ( ) ) ; packages.add ( this.result ) ; packages.add ( getRule ( ) ) ; return packages ; } /** * {@inheritDoc} * * @see de.unisiegen.tpml.core.AbstractProofNode#getParent() */ @ Override public DefaultBigStepProofNode getParent ( ) { return ( DefaultBigStepProofNode ) super.getParent ( ) ; } /** * {@inheritDoc} * * @see de.unisiegen.tpml.core.bigstep.BigStepProofNode#getResult() */ public BigStepProofResult getResult ( ) { return this.result ; } /** * {@inheritDoc} * * @see de.unisiegen.tpml.core.AbstractProofNode#getRoot() */ @ Override public DefaultBigStepProofNode getRoot ( ) { return ( DefaultBigStepProofNode ) super.getRoot ( ) ; } /** * {@inheritDoc} * * @see de.unisiegen.tpml.core.bigstep.BigStepProofNode#getRule() */ public BigStepProofRule getRule ( ) { ProofStep [ ] steps = getSteps ( ) ; if ( steps.length > 0 ) { return ( BigStepProofRule ) steps [ 0 ].getRule ( ) ; } return null ; } /** * {@inheritDoc} * * @see de.unisiegen.tpml.core.bigstep.BigStepProofNode#isFinished() */ public boolean isFinished ( ) { if ( ! isProven ( ) ) { return false ; } for ( int n = 0 ; n < getChildCount ( ) ; ++ n ) { if ( ! getChildAt ( n ).isFinished ( ) ) { return false ; } } return true ; } /** * {@inheritDoc} A big step proof node is proven if the {@link #result} is * non-<code>null</code>. * * @see de.unisiegen.tpml.core.ProofNode#isProven() */ public boolean isProven ( ) { return ( this.result != null ) ; } /** * Sets the result for the expression at this node. The <code>result</code> * must be either <code>null</code> or a {@link BigStepProofResult} with a * valid store and a value or an exception (according to the semantics of the * big step interpreter), otherwise an {@link IllegalArgumentException} will * be thrown. * * @param pResult the new result for this node, or <code>null</code> to * reset the result. * @throws IllegalArgumentException if <code>result</code> is invalid. * @see #getResult() */ public void setResult ( BigStepProofResult pResult ) { if ( pResult != null && ! pResult.getValue ( ).isException ( ) && ! pResult.getValue ( ).isValue ( ) ) { throw new IllegalArgumentException ( "result is invalid" ) ; //$NON-NLS-1$ } this.result = pResult ; } /** * {@inheritDoc} * * @see LatexPrintable#toLatexString() */ public LatexString toLatexString ( ) { return toLatexStringBuilder ( LatexStringBuilderFactory.newInstance ( ) , 0 ) .toLatexString ( ) ; } /** * {@inheritDoc} * * @see LatexPrintable#toLatexStringBuilder(LatexStringBuilderFactory,int) */ public LatexStringBuilder toLatexStringBuilder ( LatexStringBuilderFactory pLatexStringBuilderFactory , int pIndent ) { int depth = 0 ; BigStepProofNode myParent = this.getParent ( ) ; while ( myParent != null ) { depth ++ ; myParent = myParent.getParent ( ) ; } LatexStringBuilder builder = pLatexStringBuilderFactory.newBuilder ( 0 , LATEX_BIG_STEP_PROOF_NODE , pIndent , this.toPrettyString ( ) .toString ( ) , this.expression.toPrettyString ( ).toString ( ) , this.expression.containsMemoryOperations ( ) ? this.getStore ( ) .toPrettyString ( ).toString ( ) : LATEX_NO_STORE , this.result == null ? LATEX_NO_RESULT : this.result.toPrettyString ( ) .toString ( ) , this.getRule ( ) == null ? LATEX_NO_RULE : this .getRule ( ).toPrettyString ( ).toString ( ) ) ; builder.addText ( "{" + String.valueOf ( this.getId ( ) ) + "}" ) ; //$NON-NLS-1$//$NON-NLS-2$ builder.addText ( "{" + String.valueOf ( depth ) + "}" ) ; //$NON-NLS-1$//$NON-NLS-2$ builder.addBuilder ( this.expression.toLatexStringBuilder ( pLatexStringBuilderFactory , pIndent + LATEX_INDENT ) , 0 ) ; if ( this.expression.containsMemoryOperations ( ) ) { builder.addBuilder ( getStore ( ).toLatexStringBuilder ( pLatexStringBuilderFactory , pIndent + LATEX_INDENT ) , 0 ) ; } else { builder.addEmptyBuilder ( ) ; } if ( this.result != null ) { builder.addBuilder ( this.result.toLatexStringBuilder ( pLatexStringBuilderFactory , pIndent + LATEX_INDENT ) , 0 ) ; } else { builder.addEmptyBuilder ( ) ; } if ( this.getRule ( ) != null ) { builder.addBuilder ( this.getRule ( ).toLatexStringBuilder ( pLatexStringBuilderFactory , pIndent + LATEX_INDENT ) , 0 ) ; } else { builder.addEmptyBuilder ( ) ; } int indent = 245 - depth * 7 ; builder.addSourceCodeBreak ( 0 ) ; builder.addComment ( "width of the table" ) ; //$NON-NLS-1$ builder.addText ( "{" + indent + "mm}" ) ; //$NON-NLS-1$//$NON-NLS-2$ 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 ) ; boolean memoryEnabled = getExpression ( ).containsMemoryOperations ( ) ; if ( memoryEnabled ) { builder.addText ( PRETTY_LPAREN ) ; } builder.addBuilder ( this.getExpression ( ).toPrettyStringBuilder ( pPrettyStringBuilderFactory ) , 0 ) ; if ( memoryEnabled ) { builder.addText ( PRETTY_SPACE ) ; builder.addText ( PRETTY_SPACE ) ; builder.addBuilder ( this.getStore ( ).toPrettyStringBuilder ( pPrettyStringBuilderFactory ) , 0 ) ; builder.addText ( PRETTY_RPAREN ) ; } builder.addText ( " \u21d3 " ) ; //$NON-NLS-1$ if ( this.result != null ) { builder.addBuilder ( this.result .toPrettyStringBuilder ( pPrettyStringBuilderFactory ) , 0 ) ; } return builder ; } /** * {@inheritDoc} * * @see java.lang.Object#toString() */ @ Override public String toString ( ) { StringBuilder builder = new StringBuilder ( ) ; boolean memoryEnabled = getExpression ( ).containsMemoryOperations ( ) ; if ( memoryEnabled ) { builder.append ( '(' ) ; } builder.append ( getExpression ( ) ) ; if ( memoryEnabled ) { builder.append ( ", " ) ; //$NON-NLS-1$ builder.append ( getStore ( ) ) ; builder.append ( ')' ) ; } builder.append ( " \u21d3 " ) ; //$NON-NLS-1$ if ( this.result != null ) { if ( memoryEnabled ) { builder.append ( '(' ) ; } builder.append ( this.result.getValue ( ) ) ; if ( memoryEnabled ) { builder.append ( ", " ) ; //$NON-NLS-1$ builder.append ( this.result.getStore ( ) ) ; builder.append ( ')' ) ; } } return builder.toString ( ) ; } }