package OT; import java.awt.*; import java.applet.*; import java.net.*; import java.util.*; /** * Applet to compute and display single output from single constraint hierarchy. * @version 1998-03-10 * @author Andrea Heiberg, University of Arizona */ public class Single extends Applet { //general objects public static Debug debug; public Hierarchy constraintHierarchy; public Representation input; private RepresentationSet candidates; private String stat; public LanguageFeatureTypeSet languageFeatureTypeSet; private static URL inputURL; private static URL hierarchyURL; private static URL featureURL; //applet-only objects private boolean drawInert = true; private boolean drawColor = true; private boolean drawTokens = false; private boolean drawHeads = false; private Button computeButton = new Button(); private Button firstCandidateButton; private Button firstHierarchyButton; private Button lastCandidateButton; private Button lastHierarchyButton; private Button nextCandidateButton; private Button nextHierarchyButton; private Button previousCandidateButton; private Button previousHierarchyButton; private Button optimalButton; private Checkbox drawColorCheckbox = new Checkbox("Draw with color"); private Checkbox drawInertCheckbox = new Checkbox("Draw inert features"); private Checkbox drawHeadsCheckbox = new Checkbox("Draw heads"); private Checkbox drawTokensCheckbox = new Checkbox("Draw token names"); private Choice candidateChoice; private Choice hierarchyChoice; private Choice inputChoice = new Choice(); private Image rootImage; private Image moraImage; private Image syllImage; private int optimal; private Label statusLabel = new Label(); private Panel candidateCardPanel; private Panel hierarchyCardPanel; private Panel leftPanel = null; private Panel rightPanel = null; private Panel uiPanel = new Panel(); private String inputPath; private String featurePath = "data/features/"; private String inputFileName; private String constraintFileName; private String featureFileName; private URL base; public static void main (String argv[]) { //called when run as an application try { inputURL = new URL("file:" + argv[0]); hierarchyURL = new URL("file:" + argv[1]); featureURL = new URL("file:" + argv[2]); debug = new Debug(false, argv[3]); Single t = new Single(); t.getData(); t.process(); } catch (Exception ex) { String s = "main:"+ex.toString(); System.out.println(s); } //end try } //end main public void init() { //called when run as an applet debug = new Debug(true, ""); base = getDocumentBase(); //load images rootImage = getImage(base, "images/greek/Ogr.gif"); //root graphic moraImage = getImage(base, "images/greek/Mgr.gif"); //mora graphic syllImage = getImage(base, "images/greek/Sgr.gif"); //syllable graphic setBackground(Color.white); setLayout(new BorderLayout(0,0)); uiPanel.setLayout(new BorderLayout(0,0)); uiPanel.setBackground(Color.yellow); add("North", uiPanel); try { //get URL to file containing list of input files inputPath = getParameter("inputDir") + "/"; URL inputListURL = new URL(base, inputPath + "list.txt"); //test that we can read it inputListURL.openStream(); //parse the file DataFile inputList = new DataFile(inputListURL); Vector inputListVector = inputList.createVectors(); //get constraint file name constraintFileName = getParameter("constraintFile"); //get feature file name featureFileName = getParameter("featureFile"); //create the list of inputs for (Enumeration e1=inputListVector.elements(); e1.hasMoreElements();) { Vector v = (Vector)e1.nextElement(); for (Enumeration e2=v.elements(); e2.hasMoreElements();) { String s = (String)e2.nextElement(); inputChoice.addItem(s); } //end for } //end for Panel listPanel = new Panel(); listPanel.setLayout(new FlowLayout(FlowLayout.LEFT, 5, 2)); Label l = new Label("Select an input:"); l.setFont(new Font(getFont().getName(), Font.BOLD, getFont().getSize())); listPanel.add(l); listPanel.add(inputChoice); computeButton.setLabel("Compute optimal output"); listPanel.add(computeButton); //make sure label allocates enough space to see all the message. There must be a better way to do this! statusLabel.setText(" "); listPanel.add(statusLabel); uiPanel.add("South", listPanel); Panel drawingParametersPanel = new Panel(); drawingParametersPanel.setLayout(new FlowLayout(FlowLayout.LEFT, 2, 2)); drawColorCheckbox.setState(drawColor); drawInertCheckbox.setState(drawInert); drawHeadsCheckbox.setState(drawHeads); drawTokensCheckbox.setState(drawTokens); drawingParametersPanel.add(drawColorCheckbox); drawingParametersPanel.add(drawInertCheckbox); drawingParametersPanel.add(drawHeadsCheckbox); drawingParametersPanel.add(drawTokensCheckbox); uiPanel.add("North", drawingParametersPanel); inputListURL=null; //clean up inputList=null; //clean up } catch (Exception ex) { String s = "init:"+ex.toString(); message(s); System.out.println(s); } //end try } //end init private void appletCleanup () { message("Cleaning up"); if (leftPanel!=null) { remove(leftPanel); } //end if if (rightPanel!=null) { remove(rightPanel); } //end if validate(); cleanup(); } //end appletCleanup private void cleanup() { //clean up after one input before processing another one candidates=null; constraintHierarchy=null; featureURL=null; hierarchyURL=null; input=null; inputURL=null; languageFeatureTypeSet=null; stat=null; } //end cleanup public void message(String s) { statusLabel.setText(s); uiPanel.validate(); } //end message public Representation getInput(URL url) { message("Getting input"); DataFile dataFile = new DataFile(url); Vector rawDataVectors = dataFile.createVectors(); //parse file into vectors Representation r = new Representation(debug, languageFeatureTypeSet); r.parseRawData(rawDataVectors); //parse vectors into input return r; } //end getInput public Hierarchy getHierarchy(URL url) { message("Getting constraint hierarchy"); DataFile dataFile = new DataFile(url); Vector rawDataVectors = dataFile.createVectors(); //parse file into vectors Hierarchy h = new Hierarchy(languageFeatureTypeSet); h.parseRawData(rawDataVectors); //parse vectors into constraintHierarchy return h; } //end getHierarchy public LanguageFeatureTypeSet getLanguageFeatures(URL url) { message("Getting language features"); DataFile dataFile = new DataFile(url); Vector rawDataVectors = dataFile.createVectors(); //parse file into vectors LanguageFeatureTypeSet u = new LanguageFeatureTypeSet(); u.parseRawData(rawDataVectors); //parse vectors into languageFeatureTypeSet return u; } //end getLanguageFeatures private void getData() { DataFile dataFile; Vector rawDataVectors; try { languageFeatureTypeSet = getLanguageFeatures(featureURL); try { input = getInput(inputURL); try { constraintHierarchy = getHierarchy(hierarchyURL); } catch (Exception ex) { String s = "getData: exception on getHierarchy "+ex.toString(); message(s); System.out.println(s); } //end try } catch (Exception ex) { String s = "getData: exception on getInput "+ex.toString(); message(s); System.out.println(s); } //end try } catch (Exception ex) { String s = "getData: exception on getLanguageFeatures "+ex.toString(); message(s); System.out.println(s); } //end try } //end getData public void process() { message("Constructing GEN operations"); Gen gen = new Gen(input, languageFeatureTypeSet, debug); gen.constructOperations(); //GEN info boolean ordered = false; long count = 1; long numCandidates = 1; StringBuffer ftB = new StringBuffer(); StringBuffer sb = new StringBuffer(); //ordered features for (Enumeration e=languageFeatureTypeSet.elements(); e.hasMoreElements();) { FeatureType featureType = (FeatureType)e.nextElement(); FeatureTokenSet features = input.getFeatureNodes(featureType); if (features!=null) { for (Enumeration z=features.elements(); z.hasMoreElements();) { Feature f = (Feature)z.nextElement(); if ((!f.featureType.inert) && f.ordered) { ordered = true; long r = input.getAnchors(f.featureType.anchor).size(); //(2^r + 1) long sub = 1; for (int x=1; x<=r; x++) { sub = sub * 2; } //end for sub = sub + 1; ftB.append("r" + count + " = " + r + " (anchors for ordered " + f.toString() + "), 2^" + r + " + 1" + " = " + sub + "\n"); numCandidates = numCandidates * sub; count++; } //end if } //end for } //end if } //end for if (!ordered) { for (Enumeration e=languageFeatureTypeSet.elements(); e.hasMoreElements();) { FeatureType featureType = (FeatureType)e.nextElement(); if (!featureType.inert) { long r = input.getAnchors(featureType.anchor).size(); //(2^r + 1) long sub = 1; for (int x=1; x<=r; x++) { sub = sub * 2; } //end for sub = sub + 1; ftB.append("r" + count + " = " + r + " (anchors for " + featureType.toString() + "), 2^" + r + " + 1 = " + sub + "\n"); numCandidates = numCandidates * sub; count++; } //end if } //end for } //end if stat = "c = # of possible candidates=(2^r1 + 1)*(2^r2 + 1)*... = " + numCandidates + "\n" + ftB.toString(); sb.append(stat); ftB = null; //clean up int genCounter = 1; sb.append("GEN operations for this input:\n"); for (Enumeration e = gen.elements(); e.hasMoreElements();) { Operation op = (Operation)e.nextElement(); sb.append(" " + genCounter + ": " + op.toString() + "\n"); genCounter++; } //end for long t = 1; /* int g = gen.size(); for (int x=1; x<=g; x++) { t = t * 2; } //end for sb.append("g = # of GEN operations = " + g + "\n"); sb.append("t = # of candidates to try = 2^g = 2^" + g + " = " + t + "\n\n"); */ debug.write(sb.toString() + "\n"); sb=null; //clean up message("Doing GEN-EVAL loop"); GenEval genEval = new GenEval(debug, gen, constraintHierarchy, input, this); candidates = genEval.eval(numCandidates, t); gen=null; //clean up genEval=null; //clean up languageFeatureTypeSet=null; //clean up } //end process private void display() { message("Displaying results"); //constraint hierarchy flipper hierarchyCardPanel = new Panel(); hierarchyCardPanel.setLayout(new CardLayout()); hierarchyChoice = new Choice(); int i=1; for (Enumeration e=constraintHierarchy.elements(); e.hasMoreElements();) { Constraint cons = (Constraint)e.nextElement(); Panel constraintPanel = new Panel(); constraintPanel.add(new Label(cons.toString())); String constraintNumber = new Integer(i++).toString(); hierarchyCardPanel.add(constraintNumber, constraintPanel); hierarchyChoice.addItem(constraintNumber); } //end for Panel hierarchyButtonPanel = new Panel(); hierarchyButtonPanel.add(hierarchyChoice); firstHierarchyButton = new Button("first"); nextHierarchyButton = new Button("next"); previousHierarchyButton = new Button("previous"); lastHierarchyButton = new Button("last"); hierarchyButtonPanel.add(firstHierarchyButton); hierarchyButtonPanel.add(nextHierarchyButton); hierarchyButtonPanel.add(previousHierarchyButton); hierarchyButtonPanel.add(lastHierarchyButton); Panel hierarchyPanel = new Panel(); hierarchyPanel.setLayout(new BorderLayout(0,0)); Label hierarchyTitle = new Label("Constraint Hierarchy", Label.CENTER); hierarchyTitle.setFont(new Font(getFont().getName(), Font.BOLD, getFont().getSize())); hierarchyPanel.add("North", hierarchyTitle); hierarchyPanel.add("South", hierarchyButtonPanel); hierarchyPanel.add("Center", hierarchyCardPanel); //end constraint flipper //candidate flipper candidateCardPanel = new Panel(); candidateCardPanel.setLayout(new CardLayout()); candidateChoice = new Choice(); int sorted[] = candidates.sort(); for (int j = 0; j <= sorted.length-1; j++) { Integer key = new Integer(sorted[j]); Representation candidate = (Representation)candidates.get(key); RepPanel repPanel = new RepPanel(candidate, rootImage, moraImage, syllImage, drawInert, drawColor, drawTokens, drawHeads); String name = key.toString(); candidateCardPanel.add(name, repPanel); candidateChoice.addItem(name); if (candidate.isOptimal) { optimal = key.intValue() - 1; } //end if } //end for Panel candidateButtonPanel = new Panel(); firstCandidateButton = new Button("input"); optimalButton = new Button("optimal"); nextCandidateButton = new Button("next"); previousCandidateButton = new Button("previous"); lastCandidateButton = new Button("last"); candidateButtonPanel.add(firstCandidateButton); candidateButtonPanel.add(optimalButton); candidateButtonPanel.add(candidateChoice); candidateButtonPanel.add(nextCandidateButton); candidateButtonPanel.add(previousCandidateButton); //candidateButtonPanel.add(lastCandidateButton); Panel candidatePanel = new Panel(); candidatePanel.setLayout(new BorderLayout(0,0)); Label candidateTitle = new Label("Candidates", Label.CENTER); candidateTitle.setFont(new Font(getFont().getName(), Font.BOLD, getFont().getSize())); Panel candidateControlPanel = new Panel(); candidateControlPanel.setLayout(new BorderLayout(0,0)); candidateControlPanel.add("North", candidateTitle); candidateControlPanel.add("South", candidateButtonPanel); candidatePanel.add("North", candidateControlPanel); candidatePanel.add("Center", candidateCardPanel); //end candidate flipper rightPanel = new Panel(); rightPanel.setLayout(new BorderLayout(0,0)); rightPanel.add("South", hierarchyPanel); rightPanel.add("Center", candidatePanel); TableauPanel tableauPanel = new TableauPanel(candidates, constraintHierarchy); Panel statsPanel = new Panel(); statsPanel.setLayout(new BorderLayout(0,0)); Label statsTitle = new Label("Number of Candidates", Label.CENTER); statsTitle.setFont(new Font(getFont().getName(), Font.BOLD, getFont().getSize())); statsPanel.add("North", statsTitle); TextArea statsTextArea = new TextArea(4,40); statsTextArea.appendText(stat + "\n"); statsPanel.add("South", statsTextArea); leftPanel = new Panel(); leftPanel.setLayout(new BorderLayout(0,0)); Label tableauTitle = new Label("Tableau", Label.CENTER); tableauTitle.setFont(new Font(getFont().getName(), Font.BOLD, getFont().getSize())); leftPanel.add("North", tableauTitle); leftPanel.add("Center", tableauPanel); leftPanel.add("South", statsPanel); add("West", leftPanel); add("Center", rightPanel); message("Done. # of candidates produced=" + candidates.size()); validate(); } //end display public boolean action(Event e, Object arg) { if (e.target instanceof Checkbox) { if (e.target.equals(drawInertCheckbox)) { drawInert = drawInertCheckbox.getState(); } else if (e.target.equals(drawColorCheckbox)) { drawColor = drawColorCheckbox.getState(); } else if (e.target.equals(drawTokensCheckbox)) { drawTokens = drawTokensCheckbox.getState(); } else if (e.target.equals(drawHeadsCheckbox)) { drawHeads = drawHeadsCheckbox.getState(); } //end if } else { int newIndex = 0; int lastIndex = 0; String s = (String)arg; if (e.target.equals(computeButton)) { inputFileName = new String(inputPath + inputChoice.getSelectedItem() + ".txt"); try { appletCleanup(); inputURL = new URL(base, inputFileName); //get URL to data file inputURL.openStream(); //test featureURL = new URL(base, featureFileName); //get URL to language feature type file featureURL.openStream(); //test hierarchyURL = new URL(base, constraintFileName); //get URL to constraint file hierarchyURL.openStream(); //test getData(); process(); display(); } catch (Exception ex) { String st = "action:"+ex.toString(); message(st); System.out.println(st); } //end try } else if (e.target instanceof Choice) { if (e.target.equals(candidateChoice)) { ((CardLayout)candidateCardPanel.getLayout()).show(candidateCardPanel,s); } else if (e.target.equals(hierarchyChoice)) { ((CardLayout)hierarchyCardPanel.getLayout()).show(hierarchyCardPanel,s); } //end if } else { if (e.target.equals(optimalButton)) { s = candidateChoice.getItem(optimal); ((CardLayout)candidateCardPanel.getLayout()).show(candidateCardPanel,s); candidateChoice.select(s); } else if (e.target.equals(firstCandidateButton)) { s = candidateChoice.getItem(0); ((CardLayout)candidateCardPanel.getLayout()).first(candidateCardPanel); candidateChoice.select(s); } else if (e.target.equals(nextCandidateButton)) { lastIndex = candidateChoice.countItems()-1; newIndex = candidateChoice.getSelectedIndex()+1; if (newIndex > lastIndex) { s = candidateChoice.getItem(0); } else { s = candidateChoice.getItem(newIndex); } //end if ((CardLayout)candidateCardPanel.getLayout()).next(candidateCardPanel); candidateChoice.select(s); } else if (e.target.equals(previousCandidateButton)) { lastIndex = candidateChoice.countItems()-1; newIndex = candidateChoice.getSelectedIndex()-1; if (newIndex < 0) { s = candidateChoice.getItem(lastIndex); } else { s = candidateChoice.getItem(newIndex); } //end if ((CardLayout)candidateCardPanel.getLayout()).previous(candidateCardPanel); candidateChoice.select(s); } else if (e.target.equals(lastCandidateButton)) { lastIndex = candidateChoice.countItems()-1; s = candidateChoice.getItem(lastIndex); ((CardLayout)candidateCardPanel.getLayout()).last(candidateCardPanel); candidateChoice.select(s); } else if (e.target.equals(firstHierarchyButton)) { s = hierarchyChoice.getItem(0); ((CardLayout)hierarchyCardPanel.getLayout()).first(hierarchyCardPanel); hierarchyChoice.select(s); } else if (e.target.equals(nextHierarchyButton)) { lastIndex = hierarchyChoice.countItems()-1; newIndex = hierarchyChoice.getSelectedIndex()+1; if (newIndex > lastIndex) { s = hierarchyChoice.getItem(0); } else { s = hierarchyChoice.getItem(newIndex); } //end if ((CardLayout)hierarchyCardPanel.getLayout()).next(hierarchyCardPanel); hierarchyChoice.select(s); } else if (e.target.equals(previousHierarchyButton)) { lastIndex = hierarchyChoice.countItems()-1; newIndex = hierarchyChoice.getSelectedIndex()-1; if (newIndex < 0) { s = hierarchyChoice.getItem(lastIndex); } else { s = hierarchyChoice.getItem(newIndex); } //end if ((CardLayout)hierarchyCardPanel.getLayout()).previous(hierarchyCardPanel); hierarchyChoice.select(s); } else if (e.target.equals(lastHierarchyButton)) { lastIndex = hierarchyChoice.countItems()-1; s = hierarchyChoice.getItem(lastIndex); ((CardLayout)hierarchyCardPanel.getLayout()).last(hierarchyCardPanel); hierarchyChoice.select(s); } //end if } //end if } //end if return true; } //end action }