package de.unisiegen.tpml.core.bigstep ; import java.awt.BorderLayout ; import java.awt.Component ; import java.awt.FlowLayout ; import java.awt.event.ActionEvent ; import java.awt.event.ActionListener ; import java.awt.event.WindowAdapter ; import java.awt.event.WindowEvent ; import java.beans.PropertyChangeEvent ; import java.beans.PropertyChangeListener ; import java.io.StringReader ; import java.util.LinkedList ; import javax.swing.BorderFactory ; import javax.swing.JButton ; import javax.swing.JFrame ; import javax.swing.JOptionPane ; import javax.swing.JPanel ; import javax.swing.JTree ; import javax.swing.tree.DefaultTreeCellRenderer ; import javax.swing.tree.TreePath ; import de.unisiegen.tpml.core.ExpressionProofNode ; import de.unisiegen.tpml.core.ProofNode ; import de.unisiegen.tpml.core.expressions.Expression ; import de.unisiegen.tpml.core.languages.Language ; import de.unisiegen.tpml.core.languages.LanguageFactory ; /** * Test class for the {@link de.unisiegen.tpml.core.bigstep.BigStepProofModel} * class. * * @author Benedikt Meurer * @version $Id$ * @see de.unisiegen.tpml.core.bigstep.BigStepProofModel */ @ SuppressWarnings ( "all" ) public final class BigStepProofModelTest extends JFrame { /** * Simple test expression. */ private static final String SIMPLE = "let rec fact x = if x = 0 then 1 else x * fact x in fact 10" ; // // Renderer // /** * The tree renderer. */ class Renderer extends DefaultTreeCellRenderer { /** * {@inheritDoc} * * @see javax.swing.tree.DefaultTreeCellRenderer#getTreeCellRendererComponent(javax.swing.JTree, * java.lang.Object, boolean, boolean, boolean, int, boolean) */ @ Override public Component getTreeCellRendererComponent ( JTree tree , Object value , boolean sel , boolean expanded , boolean leaf , int row , boolean hasFocus ) { super.getTreeCellRendererComponent ( tree , value , sel , expanded , leaf , row , hasFocus ) ; BigStepProofNode node = ( BigStepProofNode ) value ; StringBuilder builder = new StringBuilder ( ) ; boolean memoryEnabled = ( ( BigStepProofModel ) tree.getModel ( ) ) .isMemoryEnabled ( ) ; builder.append ( '[' ) ; for ( int n = 0 ; n < node.getSteps ( ).length ; ++ n ) { if ( n > 0 ) builder.append ( ", " ) ; builder.append ( node.getSteps ( ) [ n ].getRule ( ).getName ( ) ) ; } builder.append ( "] -> " ) ; if ( memoryEnabled ) { builder.append ( '(' ) ; } builder.append ( node.getExpression ( ) ) ; if ( memoryEnabled ) { builder.append ( ", " ) ; builder.append ( node.getStore ( ) ) ; builder.append ( ')' ) ; } builder.append ( " \u21d3 " ) ; if ( node.getResult ( ) != null ) { if ( memoryEnabled ) { builder.append ( '(' ) ; } builder.append ( node.getResult ( ).getValue ( ) ) ; if ( memoryEnabled ) { builder.append ( ", " ) ; builder.append ( node.getResult ( ).getStore ( ) ) ; builder.append ( ')' ) ; } } setText ( builder.toString ( ) ) ; return this ; } } // // Constructor // /** * Default constructor. */ public BigStepProofModelTest ( final BigStepProofModel model ) { // setup the frame setLayout ( new BorderLayout ( ) ) ; setSize ( 630 , 580 ) ; setTitle ( "BigStepProofModel Test" ) ; // setup the tree panel JPanel treePanel = new JPanel ( new BorderLayout ( ) ) ; treePanel.setBorder ( BorderFactory.createEtchedBorder ( ) ) ; add ( treePanel , BorderLayout.CENTER ) ; // setup the tree final JTree tree = new JTree ( model ) ; tree.setCellRenderer ( new Renderer ( ) ) ; treePanel.add ( tree , BorderLayout.CENTER ) ; // setup the button panel JPanel buttons = new JPanel ( new FlowLayout ( ) ) ; add ( buttons , BorderLayout.SOUTH ) ; // setup the guess button JButton guessButton = new JButton ( "Guess" ) ; guessButton.addActionListener ( new ActionListener ( ) { public void actionPerformed ( ActionEvent event ) { try { // guess the last node model.guess ( nextNode ( model ) ) ; // expand to the all nodes for ( int n = 0 ; n < tree.getRowCount ( ) ; ++ n ) { tree.expandRow ( n ) ; } } catch ( Exception e ) { e.printStackTrace ( ) ; JOptionPane.showMessageDialog ( BigStepProofModelTest.this , e .getMessage ( ) , "Error" , JOptionPane.ERROR_MESSAGE ) ; } } } ) ; buttons.add ( guessButton ) ; // setup the complete button JButton completeButton = new JButton ( "Complete" ) ; completeButton.addActionListener ( new ActionListener ( ) { public void actionPerformed ( ActionEvent event ) { try { // guess the last node model.complete ( ( ProofNode ) tree.getSelectionPath ( ) .getLastPathComponent ( ) ) ; // expand to the all nodes for ( int n = 0 ; n < tree.getRowCount ( ) ; ++ n ) { tree.expandRow ( n ) ; } } catch ( Exception e ) { e.printStackTrace ( ) ; JOptionPane.showMessageDialog ( BigStepProofModelTest.this , e .getMessage ( ) , "Error" , JOptionPane.ERROR_MESSAGE ) ; } } } ) ; buttons.add ( completeButton ) ; // setup the undo button final JButton undoButton = new JButton ( "Undo" ) ; undoButton.setEnabled ( false ) ; undoButton.addActionListener ( new ActionListener ( ) { public void actionPerformed ( ActionEvent event ) { try { // undo the last change model.undo ( ) ; } catch ( Exception e ) { e.printStackTrace ( ) ; JOptionPane.showMessageDialog ( BigStepProofModelTest.this , e .getMessage ( ) , "Error" , JOptionPane.ERROR_MESSAGE ) ; } } } ) ; model.addPropertyChangeListener ( "undoable" , new PropertyChangeListener ( ) { public void propertyChange ( PropertyChangeEvent event ) { undoButton.setEnabled ( model.isUndoable ( ) ) ; } } ) ; buttons.add ( undoButton ) ; // setup the redo button final JButton redoButton = new JButton ( "Redo" ) ; redoButton.setEnabled ( false ) ; redoButton.addActionListener ( new ActionListener ( ) { public void actionPerformed ( ActionEvent event ) { try { // redo the last undone change model.redo ( ) ; // expand to the last node for ( int n = 0 ; n < tree.getRowCount ( ) ; ++ n ) { tree.expandRow ( n ) ; } } catch ( Exception e ) { e.printStackTrace ( ) ; JOptionPane.showMessageDialog ( BigStepProofModelTest.this , e .getMessage ( ) , "Error" , JOptionPane.ERROR_MESSAGE ) ; } } } ) ; model.addPropertyChangeListener ( "redoable" , new PropertyChangeListener ( ) { public void propertyChange ( PropertyChangeEvent event ) { redoButton.setEnabled ( model.isRedoable ( ) ) ; } } ) ; buttons.add ( redoButton ) ; // setup the translate button JButton translateButton = new JButton ( "Translate" ) ; translateButton.addActionListener ( new ActionListener ( ) { public void actionPerformed ( ActionEvent event ) { try { // translate the last node TreePath path = tree.getSelectionPath ( ) ; if ( path != null ) { model.translateToCoreSyntax ( ( ExpressionProofNode ) path .getLastPathComponent ( ) , false ) ; } } catch ( Exception e ) { e.printStackTrace ( ) ; JOptionPane.showMessageDialog ( BigStepProofModelTest.this , e .getMessage ( ) , "Error" , JOptionPane.ERROR_MESSAGE ) ; } } } ) ; buttons.add ( translateButton ) ; // setup the close button JButton closeButton = new JButton ( "Close" ) ; closeButton.addActionListener ( new ActionListener ( ) { public void actionPerformed ( ActionEvent event ) { System.exit ( 0 ) ; } } ) ; buttons.add ( closeButton ) ; } private static ProofNode nextNode ( BigStepProofModel model ) { LinkedList < ProofNode > nodes = new LinkedList < ProofNode > ( ) ; nodes.add ( model.getRoot ( ) ) ; while ( ! nodes.isEmpty ( ) ) { ProofNode node = nodes.poll ( ) ; if ( node.getRules ( ).length == 0 ) { return node ; } for ( int n = 0 ; n < node.getChildCount ( ) ; ++ n ) { nodes.add ( node.getChildAt ( n ) ) ; } } throw new IllegalStateException ( "Unable to find next node" ) ; } // // Program entry point // /** * Runs the small step interpreter test. * * @param args the command line arguments. */ public static void main ( String [ ] args ) { try { // parse the program (using L4) LanguageFactory factory = LanguageFactory.newInstance ( ) ; Language language = factory.getLanguageById ( "l4" ) ; Expression expression = language.newParser ( new StringReader ( SIMPLE ) ) .parse ( ) ; BigStepProofModel model = language.newBigStepProofModel ( expression ) ; // evaluate the resulting small step expression BigStepProofModelTest window = new BigStepProofModelTest ( model ) ; window.addWindowListener ( new WindowAdapter ( ) { @ Override public void windowClosing ( WindowEvent e ) { System.exit ( 0 ) ; } } ) ; window.setVisible ( true ) ; } catch ( Exception e ) { e.printStackTrace ( ) ; } } }