Instructions for Implementation, Glossary of Terms, Back to Thesis

 

APPENDIX A:

Instructions for Implementing a New Parameter Type

Introduction:

To add an additional parameter type to the Structured Matcher program the following classes must be constructed and added to the Structured Matcher directory.

Each of the objects will be described as well as the methods needed to be implemented. This appendix closes with the actual code used to add the decimal range parameter type to Structured Matcher. The decimal range parameter type provided a type that could be answered with a value between 1 and 10 inclusively.

In the following objects foo will be used to represent the name of the new parameter type. When new parameters are created replace foo with the respective name, for example the a QstnFactory for the decimal range parameter was created foo was replace with decimal as in, DecimalQstnFactory.

  To add a new parameter type to the Structured Matcher program, an instance of the QstnFactory must be added to the JComboBox in QuestionDefineDialog. An example of the code is shown in Figure 44.

Figure 44. Example code to add an new parameter type

This code is part of the constructor method in QuestionDefineDialog.

Overview of the Objects:

FooQstnFactory   implements QuestionFactortyIF

Purpose: This class is used by the QuestionDefineDialog to create an instance of the proper Question, or to select the correct item by its creation type

 

Methods:

public Question makeQuestion( String ref, String body )

Creates an new instance of FooQuestion and sets the strategy variable to FooQstnAskStrategy

public boolean isCreatorOfType( Class cls )

  Checks to see if cls is the class of Question this factory creates

public String toString( )

  Returns the String to be used in the JComboBox
as can be seen in the drop-down menu below

 

code

Figure 45: Example of DecimalQstnFactory

 


FooQstn     extends Question

Purpose: Return the proper cell editor for FooCEle

 

Methods:

public FooQstn( String name, String body ) // Constructor

Call the constructor for Question and pass on the name and body Strings, but also include the FooQstn.class variable that will be used for the questions type.

public TableCellEditor getCellEditor( )

Return the proper cell editor for FooCEle

FooQstn is part of the model, and does not have a visual representation

 

code


FooCEle  implements CellElementIF

Purpose: Manage (create, edit, evaluate) a matching constraint for the parameter type

 

Methods:

public boolean evaluate(Object colId, Hashtable caseRef)

           throws UserCanceledException;

Resolve whether the value(answer) matches the matching constraint held in this cell element.

colId: is the ColumnIdentifier for the column ( ie the Question or SimpleMatcher)

caseRef: the case hashtable. If the question has been resolved before, the answer will be recorded here. If the question has not be answered, then ask the question and record the answer

public String toString( )

used to return a String representation of the cell element to be displayed in the table

 

code

Figure 46. Example of DecimalCEle in use

The reader may note that here the author used DecimalRelCEle for the title of this class, which deviates somewhat from the pattern

His explanation: "There is a difference; with the Boolean question type I used BooleanCEle because there weren't any relationship operators displayed in the cell element where with the Likelihood and Decimal question type there is a relationship operator that is also displayed, and so that is the reason for the difference in names."

 


FooQstnAskStrategy    implements QuestionAskStrategyIF

Purpose: To provide a JPanel with window widgets for getting an answer for a question of this parameter type.

 

Methods:

public Object getAnswer( )

Get the answer selected from the widgets in the JPanel returned by getOptionPanel

public JPanel getOptionPanel( )

Provide a JPanel with window widgets for getting an answer for a question of this parameter type.

code

Figure 47.Example of DecimalQstnAskStrategy
JPanel returned and managed by the QstnAskStrategy

 


FooCellEditor  implements TableCellEditor

CellEditor object is only needed if something is needed beyond what is provided by DefaultCellEditor that is part of the Swing package. DecimalCellEditor uses a dialog to get the information so it is more complicated, so a sequence diagram is provided below to show how the methods are called

code

 

Figure 48. Example of DecimalCellEditor

 


DecimalQstnFactory Example
gui

 

package edu.csuchico.aitools.sm; class DecimalQstnFactory implements QuestionFactoryIF { public Question makeQuestion( String ref, String body ) { Question decimalQstn = new DecimalQstn( ref, body ); decimalQstn.setStrategy( new DecimalQstnAskStrategy() ); return decimalQstn; } public boolean isCreatorOfType ( Class cls ) { if ( cls == DecimalQstn.class ) return true; else return false; } public String toString() { return "1-10 range" ; } } // end DecimalQstnFactory

 

DecimalQstn Example
back to specs

 

package edu.csuchico.aitools.sm; import javax.swing.table.*; class DecimalQstn extends Question { private transient static TableCellEditor decimalCellEditor = new DecimalCellEditor( new DummyFrame() ); public DecimalQstn( String ref, String body ) { super ( ref, DecimalQstn.class, body ); } public TableCellEditor getCellEditor() { return decimalCellEditor; } // end getCellEditor method } // end DecimalQstn

 

DecimalRelCEle Example
gui

 

package edu.csuchico.aitools.sm; import java.io.*; import java.util.*; public class DecimalRelCEle implements CellElementIF, Cloneable, Serializable { Integer value; int relationship; public static final Class TYPE = LikelihoodRelCEle.class; static final int GREATERTHAN = 1; static final int GREATERTHAN_EQUAL = 2; static final int EQUAL = 3; static final int LESSTHAN = 4; static final int LESSTHAN_EQUAL = 5; static final int NOT_EQUAL = 6; public DecimalRelCEle( Integer value, int relationship ) { int intValue = value.intValue(); if ( intValue > 10 || intValue < 1 ) throw new IllegalArgumentException("Not a valid value for DecimalCEle"); this.value = value; this.relationship = relationship; } public DecimalRelCEle( ) { value = new Integer( 1 ); relationship = EQUAL; } // used by DecimalCellEditor to select the proper value public Integer getValue() { return value; } // used by DecimalCellEditor to select the proper relationship public int getRelationship() { return relationship; } // used by DecimalCellEditor to set the proper relationship public void setRelationship ( int rel ) { relationship = rel; } // used by DecimalCellEditor to set the proper value public void setValue( Integer integer ) { int intValue = integer.intValue(); if ( intValue > 10 || intValue < 1 ) throw new IllegalArgumentException("Not a valid value for DecimalCEle"); this.value = integer; } public Object clone() { return new DecimalRelCEle( value, relationship ); } // used by JTable to get the String to represent the matching constraint public String toString() { String str = ""; if ( value == null ) { str = " ? - Don't Care"; } else { switch ( relationship ) { case GREATERTHAN: str = " > "; break; case GREATERTHAN_EQUAL: str = " >= "; break; case EQUAL: str = " = "; break; case LESSTHAN: str = " < "; break; case LESSTHAN_EQUAL: str = " <= "; break; case NOT_EQUAL: str = " ~= "; break; } str += (" " + value + " "); } // end else return str; } // end toString() boolean compare( Integer result ) { if ( result == null ) { System.err.println("In Compare: passed in value is null "); return false; } else { switch ( relationship ) { case GREATERTHAN: if ( result.intValue() > ((Integer)value).intValue() ) return true; break; case GREATERTHAN_EQUAL: if ( result.intValue() >= ((Integer)value).intValue() ) return true; break; case EQUAL: if ( result.intValue() == ((Integer)value).intValue() ) return true; break; case LESSTHAN: if ( result.intValue() < ((Integer)value).intValue() ) return true; break; case LESSTHAN_EQUAL: if ( result.intValue() <= ((Integer)value).intValue() ) return true; break; case NOT_EQUAL: if ( result.intValue() != ((Integer)value).intValue() ) return true; break; } return false; } // end else from null check } // end compare method // meets CellElementIF public boolean evaluate(Object colId, Hashtable caseRef) throws UserCanceledException { CaseElement tmpCaseElem; Question question = (Question)colId; String qstnName = question.getRef(); if (( tmpCaseElem = (CaseElement)caseRef.get(qstnName)) != null ) { // Question has been asked already return compare ( (Integer) tmpCaseElem.getAnswer() ); } else { // Question hasn't been asked yet Integer answer = null; try { answer = (Integer) QuestionAskDialog.ask( question ); } catch( UserCanceledException e ) { } if (answer == null ) { throw new RuntimeException("Question " + question + " was not answered" ); } else { caseRef.put( qstnName, new CaseElement( qstnName, question.getType(), answer)); return compare( answer ); } // end else } // end question hasn't been asked yet } // end evaluate method } // end DecimalRelCEle class

 

DecimalQstnAskStrategy Example
gui

 

package edu.csuchico.aitools.sm; import javax.swing.*; import java.awt.*; import java.io.*; class DecimalQstnAskStrategy implements QstnAskStrategyIF, Serializable { DecimalComboBox decimalChoice = new DecimalComboBox(); public JPanel getOptionPanel( ) { JPanel panel = new JPanel( false ); panel.add(new JLabel( "Choose one of the following:" ) ); decimalChoice.setMaximumRowCount( decimalChoice.getItemCount() + 1 ); panel.add(decimalChoice); decimalChoice.setSelectedIndex( 0 ); // select first value ( ie 1 ) panel.setLayout( new FlowLayout( FlowLayout.LEFT ) ); return panel; } public Object getAnswer( ) { return decimalChoice.getSelectedItem(); } } // end of DecimalQstnAskStrategy

 

DecimalComboBox Example
used for DecimalQstnAskStrategy

 

package edu.csuchico.aitools.sm; import javax.swing.JComboBox; class DecimalComboBox extends JComboBox { public DecimalComboBox() { addItem(new Integer(1)); addItem(new Integer(2)); addItem(new Integer(3)); addItem(new Integer(4)); addItem(new Integer(5)); addItem(new Integer(6)); addItem(new Integer(7)); addItem(new Integer(8)); addItem(new Integer(9)); addItem(new Integer(10)); setSelectedIndex( 0 ); } }

 

DecimalCellEditor Example
gui

 

package edu.csuchico.aitools.sm; import java.awt.event.*; import javax.swing.*; import javax.swing.event.*; import javax.swing.border.*; import javax.swing.table.TableCellEditor; import java.awt.*; import java.util.*; import java.io.*; public class DecimalCellEditor extends JDialog implements TableCellEditor, Serializable { JTable table; int colIndex; int rowInd; Object value; DecimalRelCEle newValue; Vector listeners = new Vector( 5, 5 ); JList relationshipList; JList decimalList; JButton okButton; JButton cancelButton; JButton dontCareButton; JButton helpButton; Container contentPane; Point screenLoc; public DecimalCellEditor(Frame parent) { super(parent,"Decimal Relationship Editor",false); setResizable(false); setSize( 300, 300 ); setModal( false ); addWindowListener( new WindowAdapter() { public void windowClosing( WindowEvent e ) { cancelCellEditing(); } } ); contentPane = getContentPane(); String[] data = { " > ", " >= ", " = " , " < ", " <= ", " ~= " }; relationshipList = new JList( data ); relationshipList.setBackground( Color.white ); relationshipList.setBorder( new BevelBorder( BevelBorder.LOWERED ) ); String[] decData = { " 1 ", " 2 ", " 3 ", " 4 ", " 5 ", " 6 ", " 7 ", " 8 ", " 9 ", " 10 " }; decimalList = new JList( decData ); decimalList.setBackground( Color.white ); decimalList.setBorder( new BevelBorder( BevelBorder.LOWERED )); SMListCellRenderer relationshipListCellRenderer = new SMListCellRenderer(); SMListCellRenderer decimalListCellRenderer = new SMListCellRenderer(); relationshipListCellRenderer.setFont(new Font("Dialog",Font.PLAIN,18)); decimalListCellRenderer.setFont(new Font("Dialog",Font.PLAIN,16)); relationshipList.setCellRenderer(relationshipListCellRenderer); decimalList.setCellRenderer(decimalListCellRenderer); JPanel southPanel = new JPanel(); JPanel centerPanel = new JPanel(); centerPanel.setLayout( new FlowLayout( FlowLayout.CENTER, 50, 5 ) ); centerPanel.add( relationshipList ); centerPanel.add( decimalList ); contentPane.add( "Center", centerPanel ); okButton = new JButton( "Ok" ); okButton.addActionListener( new ActionListener() { public void actionPerformed( ActionEvent e ) { stopCellEditing(); } } ); southPanel.add( okButton ); cancelButton = new JButton( "Cancel" ); cancelButton.addActionListener( new ActionListener() { public void actionPerformed( ActionEvent e ) { cancelCellEditing(); } } ); southPanel.add(cancelButton); dontCareButton = new JButton( "Don't Care" ); dontCareButton.addActionListener( new ActionListener() { public void actionPerformed( ActionEvent e ) { decimalList.clearSelection(); relationshipList.clearSelection(); stopCellEditing(); } } ); southPanel.add(dontCareButton); helpButton = new JButton( "Help" ); helpButton.addActionListener( new ActionListener() { public void actionPerformed( ActionEvent e ) { // help stuff goes here..... } } ); southPanel.add(helpButton); contentPane.add( "South", southPanel ); } public void addCellEditorListener(CellEditorListener listener ) { listeners.addElement( listener ); } public void removeCellEditorListener(CellEditorListener listener ) { listeners.removeElement( listener ); } public Object getCellEditorValue() { return value; } public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int column, int rowIndex) { this.table = table; colIndex = column; rowInd = rowIndex; if(value.getClass() == DecimalRelCEle.class) { this.value = ((DecimalRelCEle)value).clone(); } else { this.value = value; } return new JLabel( value.toString() ); } public boolean isCellEditable(EventObject anEvent ) { MouseEvent e = (MouseEvent) anEvent; if(SwingUtilities.isLeftMouseButton( e ) && e.getClickCount() == 2 ) { return true; } else { return false; } } public boolean shouldSelectCell(EventObject anEvent) { newValue = new DecimalRelCEle(); if(value instanceof DontCare) { relationshipList.clearSelection(); decimalList.clearSelection(); } else { relationshipList.setSelectedIndex( ((DecimalRelCEle)value).getRelationship() - 1); decimalList.setSelectedIndex( ((((DecimalRelCEle)value).getValue() ).intValue()) - 1 ); } // starts dialog in center of scree if ( screenLoc == null ) { Dimension screen = Toolkit.getDefaultToolkit().getScreenSize(); setLocation(( screen.width - getPreferredSize().width ) / 2, ( screen.height - getPreferredSize().height ) / 2 ); } setVisible(true); return true; } public boolean stopCellEditing() { int relIndex, likeIndex; likeIndex = decimalList.getSelectedIndex(); relIndex = relationshipList.getSelectedIndex(); if( likeIndex == -1 ^ relIndex == -1 ) { // one list selected // leave Cell editor visible requestFocus(); return false; } // no list selected else if ( likeIndex == -1 && relIndex == -1 ) { value = DontCare.INSTANCE; } else { // both list selected newValue.setValue( new Integer( decimalList.getSelectedIndex() + 1) ); newValue.setRelationship( relationshipList.getSelectedIndex() + 1); value = newValue; } for (Enumeration e = listeners.elements() ; e.hasMoreElements() ;) { ((CellEditorListener)e.nextElement()).editingStopped(new ChangeEvent(DecimalCellEditor.this)); } screenLoc = getLocationOnScreen(); setVisible(false); return true; } public void cancelCellEditing() { if ( isShowing() ) { screenLoc = getLocationOnScreen(); setVisible( false ); } for (Enumeration e = listeners.elements() ; e.hasMoreElements() ;) { ((CellEditorListener)e.nextElement()).editingCanceled(new ChangeEvent(DecimalCellEditor.this)); } } } // end DecimalCellEditor class

 


 

APPENDIX C

Definition of Terms

Cell: A location within a truth table that holds a matching constraint for a parameter ( question or simple matcher).

 

Expert: A person who has knowledge in a particular field, and will use the Structured Matcher program to construct an environment ( combination of parameters and matching constraints) where a hypothesis can be tested.

 

Matching Constraint: A set of values, defined by the expert, used in comparison with the answer, given by the non-expert, for a parameter to evaluate whether a cell is considered to be a match ( true ). If the non-expert’s answer falls within the set of values defined by the expert, a cell will be considered to have matched.

 

Non-expert: A person who will supply the values to a predefined environment defined by an expert resulting in a confidence level of the hypothesis being tested.

 

Parameter: Elements that are pertinent in the determination of a hypothesis. A parameter will have a set number of valid values. Often a parameter takes the form of a question.

 

Simple Matcher: Another name for a truth table.

 

Structured Matcher: A software program that provides the artificial intelligence technique of Structured Matching.

 

Structured Matching: A tree like hierarchy of truth tables used to provide hypothesis testing. The tree structure provides a way to transform complex decisions into a simpler forms by breaking a decision into sub-decisions. In the tree structure, the branches would represent the sub-decisions and the root of the tree would represent the overall decision.

 

Truth Table: A logical structure used to establish a relationship between parameters and matching conditions in a way that a confidence level can be given for a hypothesis based the configuration of the matching conditions for the parameters. The columns of the table will represent the parameters pertinent to the hypothesis. The rows of the table will represent different possible hypothesis resolutions based on varying matching constraints.

 

Value: An answer given in response to a parameter or question in a truth table. This answer will be compared to the matching constraints set up in the cells of the column of the truth table representing the particular parameter.