public class Config implements Configuration {
    /**
     * This variable specifies the default output format that is produced when
     * toString() calls are made on Term and DefiniteClause Objects. If this is
     * true then output is in POSL syntax, otherwise RuleML syntax is produced.
     */
    public static boolean PRPRINT = false;

    /**
     * This variable controls how Variables are printed. If true then the
     * variable name is combined with the variable id in the output, otherwise
     * only the variable name is printed. This is useful as after unification it
     * is possible to have two different variable with the same base name, but
     * the option to disable is there so that the parsing and output libraries
     * can be used to translate from POSL syntax to RuleML 0.88 syntax without
     * changing the variable names.
     */
    public static boolean PRINTVARID = true;

    /**
     * This variable controls how generated symbols (skolem constants) are
     * printed. If this is set to true, then the generated symbol is output as a
     * regular constant (eg. <Ind>$gensym10000</Ind> or $gensym10000; in RuleML
     * and POSL respectively). If this is set to false then the generated symbol
     * is output the same as it was input (e.g. <Skolem /> or _; in RuleML and
     * POSL respectively).
     */
    public static boolean PRINTGENSYMS = false;

    /**
     * This variable controls how system generated oids are printed. If this is
     * set to true, then the generated symbol is output; with the generated
     * symbol printed as determined by PRINTGENSYMS. If it is set to false then
     * generated oids are completely omitted. This variable does not effect the
     * RuleML output, only POSL; in RuleML the oids are always printed, but
     * generated oids are printed based upon the PRINTGENSYMS variable.
     */
    public static boolean PRINTGENOIDS = true;

    /**
     * This variable controls how anonymous variables are printed. If this is
     * set to false (the default), then anonymous variables are printed as they
     * are input (<Var /> or ?; for RuleML and POSL respectively). If it is set
     * to true then the generated variable name is output (e.g.
     * <Var>$anonvar1</Var> or ?$ANON1; for RuleML and POSL respectively).
     */
    public static boolean PRINTANONVARNAMES = false;

    private Preferences preferences;
    
    private int uiPreferenceChanges;

    public Config(Class clazz) {
        preferences = Preferences.userNodeForPackage(clazz);
        uiPreferenceChanges = 1;
    }
    
    public void addPreferenceChangeListener(PreferenceChangeListener listener) {
        preferences.addPreferenceChangeListener(listener);
    }
    
    public int getUiPreferenceChangeCount() {
        return uiPreferenceChanges;
    }
    
    public void decreaseUiPreferenceChangeCount() {
        uiPreferenceChanges--;
    }

    public int getTextAreaFontSize() {
        return preferences.getInt("TextAreaFontSize", 12);
    }

    public void setTextAreaFontSize(int newSize) {
        int oldSize = getTextAreaFontSize();
        if (oldSize != newSize) {
            preferences.putInt("TextAreaFontSize", newSize);
            uiPreferenceChanges++;
        }
    }

    public int getUIFontSize() {
        return preferences.getInt("UIFontSize", 12);
    }

    public void setUIFontSize(int newSize) {
        int oldSize = getUIFontSize();
        if (oldSize != newSize) {
            preferences.putInt("UIFontSize", newSize);
            uiPreferenceChanges++;
        }
    }

    public boolean getDebugConsoleVisible() {
        return preferences.getBoolean("DebugConsoleVisible", false);
    }

    public void setDebugConsoleVisible(boolean visible) {
        if (getDebugConsoleVisible() != visible) {
            preferences.putBoolean("DebugConsoleVisible", visible);
        }
    }

    public String getLookAndFeel() {
        String defaultLookAndFeelName = UIManager.getSystemLookAndFeelClassName();
        return preferences.get("LookAndFeel", defaultLookAndFeelName);
    }

    public void setLookAndFeel(String lafClassName) {
        if (!getLookAndFeel().equals(lafClassName)) {
            preferences.put("LookAndFeel", lafClassName);
            uiPreferenceChanges++;
        }
    }

    public RuleMLFormat getRuleMLFormat() {
        String defaultRuleMLFormat = RuleMLFormat.RuleML100.getVersionName();
        String configuredRuleMLVersion = preferences.get("RuleMLFormat", defaultRuleMLFormat);
        return RuleMLFormat.fromString(configuredRuleMLVersion);
    }

    public void setSelectedRuleMLFormat(RuleMLFormat rmlFormat) {
        if (getRuleMLFormat() != rmlFormat) {
            preferences.put("RuleMLFormat", rmlFormat.getVersionName());
        }
    }

    public boolean getLinkFontSizes() {
        return preferences.getBoolean("LinkFontSizes", false);
    }

    public void setLinkFontSizes(boolean linkFontSizes) {
        if (getLinkFontSizes() != linkFontSizes) {
            preferences.putBoolean("LinkFontSizes", linkFontSizes);
        }
    }

    public Level getLogLevel() {
        Level defaultLogLevel = Level.ERROR;
        int logLevel = preferences.getInt("LogLevel", defaultLogLevel.toInt());
        return Level.toLevel(logLevel);
    }

    public void setLogLevel(Level logLevel) {
        if (getLogLevel() != logLevel) {
            preferences.putInt("LogLevel", logLevel.toInt());
        }
    }

    public int getHttpConnectionTimeout() {
        int defaultTimeoutInMilliseconds = 7000;
        return preferences.getInt("HttpConnectionTimeout", defaultTimeoutInMilliseconds);
    }

    public void setHttpConnectionTimeout(int timeoutInMilliseconds) {
        if (getHttpConnectionTimeout() != timeoutInMilliseconds) {
            preferences.putInt("HttpConnectionTimeout", timeoutInMilliseconds);
        }
    }
} public interface Configuration {
    
    void addPreferenceChangeListener(PreferenceChangeListener listener);
    
    public int getUiPreferenceChangeCount();
    public void decreaseUiPreferenceChangeCount();
    
    public int getTextAreaFontSize();
    public void setTextAreaFontSize(int newSize);

    public int getUIFontSize();
    public void setUIFontSize(int newSize);

    public boolean getLinkFontSizes();
    public void setLinkFontSizes(boolean linkFontSizes);

    public String getLookAndFeel();
    public void setLookAndFeel(String lafClassName);

    public RuleMLFormat getRuleMLFormat();
    public void setSelectedRuleMLFormat(RuleMLFormat rmlFormat);
    
    public int getHttpConnectionTimeout();
    public void setHttpConnectionTimeout(int timeoutInMilliseconds);

    public Level getLogLevel();
    public void setLogLevel(Level logLevel);
}
 public enum SyntaxFormat {
	RDFS,
	RULEML,
	POSL
} public abstract class AbstractUIApp implements UISettingsController, PreferenceChangeListener {

    protected Configuration config;
    protected UI ui;
    protected PreferenceDialogUI preferenceDialogUI;
    protected DebugConsole debugConsole;
    protected PreferenceManager preferenceManager;
    protected Logger logger;

    protected POSLParser poslParser;
    protected RuleMLParser rmlParser;
    
    protected RDFSParser rdfsParser;
    protected SubsumesParser subsumesParser;

    protected Reasoner reasoner;

    protected AbstractUIApp(Configuration config, PreferenceManager preferenceManager,
            PreferenceDialogUI preferenceDialogUI, UI ui, Logger logger, DebugConsole debugConsole,
            RDFSParser rdfsParser, POSLParser poslParser, RuleMLParser rmlParser,
            SubsumesParser subsumesParser, Reasoner reasoner) {
        this.config = config;
        this.preferenceManager = preferenceManager;
        this.ui = ui;
        this.preferenceDialogUI = preferenceDialogUI;
        this.debugConsole = debugConsole;
        this.logger = logger;
        this.rdfsParser = rdfsParser;
        this.poslParser = poslParser;
        this.rmlParser = rmlParser;
        this.subsumesParser = subsumesParser;
        this.reasoner = reasoner;
        
        TextPaneAppender tpa = new TextPaneAppender(new PatternLayout("%-5p %d [%t]:  %m%n"), "Debug");
        tpa.setTextPane(debugConsole.getTextPane());
        logger.addAppender(tpa);

        ui.setController(this);
        preferenceDialogUI.setSettingsController(this);
        config.addPreferenceChangeListener(this);
        preferenceChange(null);
    }

    public void syncUIWithSettings() {
        preferenceDialogUI.setSpinnerTextAreaFontSizeValue(config.getTextAreaFontSize());
        preferenceDialogUI.setSpinnerUIFontSizeValue(config.getUIFontSize());
        preferenceDialogUI.setLinkFontSizes(config.getLinkFontSizes());
        preferenceDialogUI.setLookAndFeel(config.getLookAndFeel());
        preferenceDialogUI.setRuleMLFormat(config.getRuleMLFormat());
        preferenceDialogUI.setLoggingLevel(config.getLogLevel());
    }

    public void applySettingsFromUI() {
        config.setTextAreaFontSize(preferenceDialogUI.getSpinnerTextAreaFontSizeValue());
        config.setUIFontSize(preferenceDialogUI.getSpinnerUIFontSizeValue());
        config.setLinkFontSizes(preferenceDialogUI.getLinkFontSizes());
        config.setLookAndFeel(preferenceDialogUI.getSelectedLookAndFeel());
        config.setSelectedRuleMLFormat(preferenceDialogUI.getRuleMLFormat());
        config.setLogLevel(preferenceDialogUI.getLoggingLevel());
    }

    public void showDebugConsole() {
        debugConsole.setVisible(true);
    }

    public void showPreferenceDialog() {
        preferenceDialogUI.setVisible(true);
    }

    public void preferenceChange(PreferenceChangeEvent evt) {
        int uiPreferenceChanges = config.getUiPreferenceChangeCount();
        if (uiPreferenceChanges > 0) {
            if (uiPreferenceChanges == 1) {
                preferenceDialogUI.updateUI();
                ui.updateUI();
                debugConsole.updateUI();
            }
            config.decreaseUiPreferenceChangeCount();
        } else {
            logger.setLevel(config.getLogLevel());
        }
    }

    private boolean showOpenForAppendDialog() {
        return 0 == JOptionPane.showConfirmDialog(ui.getFrmOoJdrew(), "Append content?",
                "Append or replace?", JOptionPane.YES_NO_OPTION);
    }

    private void setTextOfCurrentEditingTab(String text, boolean append) {
        if (text == null) {
            return;
        }

        if (append) {
            ui.appendToCurrentEditingTab(text);
        } else {
            ui.setTextForCurrentEditingTab(text);
        }
    }

    /**
     * Shows open URI dialog and reads from URL to editing tab
     */
    public void openURI() {
        boolean append = showOpenForAppendDialog();
        String uri = JOptionPane.showInputDialog("Please enter an URI");

        if (uri != null) {
            int httpConnectionTimeout = config.getHttpConnectionTimeout();
            String pageContent;
            try {
                pageContent = Util.readFromURIWithTimeout(uri, httpConnectionTimeout);
            } catch (IOException e) {
                defaultExceptionHandler(e);
                return;
            }

            setTextOfCurrentEditingTab(pageContent, append);
        }
    }

    public void openFile() {
        boolean append = showOpenForAppendDialog();
        Component parent = ui.getFrmOoJdrew();

        String fileContent;
        try {
            fileContent = Util.selectAndReadFile(parent);
        } catch (IOException e) {
            defaultExceptionHandler(e);
            return;
        }

        setTextOfCurrentEditingTab(fileContent, append);
    }

    public void saveFileAs() {
        String content = ui.getTextForCurrentEditingTab();
        Component parent = ui.getFrmOoJdrew();

        try {
            Util.selectAndSaveToFile(content, parent);
        } catch (IOException e) {
            defaultExceptionHandler(e);
        }
    }

    public void parseTypeInformation() {
        String typeInformation = ui.getTypeDefinitionTextAreaText();
        SyntaxFormat format = ui.getTypeInformationInputFormat();

        // Reset the type system
        Types.reset();

        if (format == SyntaxFormat.RDFS) {
            parseRDFSTypes(typeInformation);
        } else {
            parsePOSLTypes(typeInformation);
        }

        // Type information may have changed, time to parse the knowledge base
        // again.
        parseKnowledgeBase();
    }

    private void parseRDFSTypes(String typeInformation) {
        try {
            RDFSParser.parseRDFSString(typeInformation);
        } catch (Exception e) {
            defaultExceptionHandler(e);
            return;
        }
    }

    private void parsePOSLTypes(String typeInformation) {
        try {
            subsumesParser.parseSubsumes(typeInformation);
        } catch (Exception e) {
            defaultExceptionHandler(e);
            return;
        }
    }

    public void parseKnowledgeBase() {
        SyntaxFormat knowledgeBaseFormat = ui.getKnowledgeBaseInputFormat();
        String knowledgeBase = ui.getKnowledgeBaseTextAreaText();

        if (!knowledgeBase.isEmpty()) {
            if (knowledgeBaseFormat == SyntaxFormat.RULEML) {
                parseRuleMLKnowledeBase(knowledgeBase);
            } else {
                parsePOSLKnowledgeBase(knowledgeBase);
            }
        }
    }

    protected void parseRuleMLKnowledeBase(String knowledgeBase) {
        rmlParser.clear();

        try {
            rmlParser.parseRuleMLString(knowledgeBase);
            reasoner.loadClauses(rmlParser.iterator());
        } catch (Exception e) {
            defaultExceptionHandler(e);
            return;
        }
    }

    protected void parsePOSLKnowledgeBase(String knowledgeBase) {
        poslParser.reset();

        try {
            poslParser.parseDefiniteClauses(knowledgeBase);
            reasoner.loadClauses(poslParser.iterator());
        } catch (Exception e) {
            defaultExceptionHandler(e);
            return;
        }
    }

    protected void defaultExceptionHandler(Exception e) {
        String msg;
        if (e.getMessage() != null) {
            msg = e.getMessage();
        } else if (e.getCause() != null && e.getCause().getMessage() != null) {
            msg = e.getCause().getMessage();
        } else {
            msg = String.format("Unknown error occured (%s)", e.getClass().getName());
        }

        JOptionPane.showMessageDialog(ui.getFrmOoJdrew(), msg, "Error", JOptionPane.ERROR_MESSAGE);
        logger.error(msg);
    }

    protected void showInformationDialog(String title, String message) {
        JOptionPane.showMessageDialog(ui.getFrmOoJdrew(), message, title, JOptionPane.INFORMATION_MESSAGE);
    }

    protected void validateRuleMLDocument() {
        String content = ui.getKnowledgeBaseTextAreaText();
        RuleMLValidator validator = new RuleMLValidator();
        try {
            validator.validateRuleMLDocument(content);
            showInformationDialog("Successfully validated document.", "Validation successful");
        } catch (Exception e) {
            defaultExceptionHandler(e);
        }
    }

    protected void normalizeRuleMLDocument() {
        RuleMLFormat rmlFormat = config.getRuleMLFormat();
        String input = ui.getTextForCurrentEditingTab();

        RuleMLNormalizer normalizer = new RuleMLNormalizer();
        try {
            String normalizedRuleML = normalizer.normalize(input, rmlFormat);
            ui.setTextForCurrentEditingTab(normalizedRuleML);
        } catch (Exception e) {
            defaultExceptionHandler(e);
        }
    }
}
 public class DebugConsole extends JFrame {

    private JScrollPane scrollPaneDebugText;
    private JTextPane textPane;
    
    private JPopupMenu contextMenu;
    
    /** Creates new form DebugConsole */
    public DebugConsole() {
        super();
        initComponents();
    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    private void initComponents() {
        setTitle("DebugConsole");
        setName("debugFrame");
        
        scrollPaneDebugText = new JScrollPane();
        textPane = new JTextPane();
        
        scrollPaneDebugText.setViewportView(textPane);
        scrollPaneDebugText.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
        scrollPaneDebugText.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
        getContentPane().add(scrollPaneDebugText, java.awt.BorderLayout.CENTER);

        contextMenu = new JPopupMenu("Edit");
        contextMenu.add(new ClearAction(textPane));
       
        textPane.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseReleased(MouseEvent e) {
                requestFocus();
                processMouseClick(e);
            }
        });
        
        pack();
        this.setBounds(1, 1, 600, 800);
    }

    public JTextPane getTextPane() {
        return textPane;
    }
    
    public void updateUI() {
        SwingUtilities.updateComponentTreeUI(getTextPane());
    }
    
    protected void processMouseClick(MouseEvent e) {
        // Only interested in the right button
        if (SwingUtilities.isRightMouseButton(e)) {
            // Display the menu
            Point pt = SwingUtilities.convertPoint(e.getComponent(),
                    e.getPoint(), this);
            contextMenu.show(this, pt.x, pt.y);
        }
    }
    
    class ClearAction extends AbstractAction {
        private final JTextPane textPane;

        public ClearAction(final JTextPane textPane) {
            super("Clear console");
            this.textPane = textPane;
        }

        public void actionPerformed(ActionEvent e) {
            textPane.setText("");
        }

        public boolean isEnabled() {
            if (textPane.isEnabled()) {
                return true;
            } else {
                return false;
            }
        }
    }
}
 public class PreferenceDialogUI extends JDialog {

    private final JPanel contentPanel = new JPanel();
    private JSpinner spinnerTextFontSize;
    private UISettingsController settingsController;
    private JSpinner spinnerUIFontSize;
    private JCheckBox chkBxLinkFontSizes;
    private JComboBox cbBoxLookAndFeel;
    private JComboBox cbBoxRuleMLVersion;
    private JComboBox cbBoxLoggingLevel;

    /**
     * Launch the application.
     */
    public static void main(String[] args) {
        try {
            PreferenceDialogUI dialog = new PreferenceDialogUI();
            dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
            dialog.setVisible(true);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    protected JRootPane createRootPane() {
        ActionListener actionListener = new ActionListener() {
            public void actionPerformed(ActionEvent actionEvent) {
                setVisible(false);
            }
        };

        KeyStroke stroke = KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0);
        JRootPane rootPane = new JRootPane();
        rootPane.registerKeyboardAction(actionListener, stroke,
                JComponent.WHEN_IN_FOCUSED_WINDOW);
        return rootPane;
    }

    /**
     * Create the dialog.
     */
    public PreferenceDialogUI() {
        setTitle("Preferences");
        addWindowListener(new WindowAdapter() {
            @Override
            public void windowOpened(WindowEvent arg0) {
                settingsController.syncUIWithSettings();
            }
        });
        setBounds(100, 100, 300, 235);
        getContentPane().setLayout(new BorderLayout());
        contentPanel.setBorder(new EmptyBorder(5, 5, 5, 5));
        getContentPane().add(contentPanel, BorderLayout.CENTER);

        JButton btnCancel = new JButton("Cancel");
        btnCancel.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent arg0) {
                setVisible(false);
            }
        });

        JButton btnOk = new JButton("Ok");
        btnOk.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                settingsController.applySettingsFromUI();
                setVisible(false);
            }
        });

        JLabel lblTextFont = new JLabel("Text panel font size");
        spinnerTextFontSize = new JSpinner();
        spinnerTextFontSize.setModel(new SpinnerNumberModel(12, 8, 72, 1));

        JLabel lblMainUiFont = new JLabel("Main UI font size");
        spinnerUIFontSize = new JSpinner();
        spinnerUIFontSize.addChangeListener(new ChangeListener() {
            public void stateChanged(ChangeEvent e) {
                if (chkBxLinkFontSizes.isSelected()) {
                    spinnerTextFontSize.setValue(spinnerUIFontSize.getValue());
                }
            }
        });
        spinnerUIFontSize.setModel(new SpinnerNumberModel(12, 8, 72, 1));

        chkBxLinkFontSizes = new JCheckBox("Link font sizes");
        chkBxLinkFontSizes.addChangeListener(new ChangeListener() {
            public void stateChanged(ChangeEvent e) {
                if (chkBxLinkFontSizes.isSelected()) {
                    spinnerTextFontSize.setValue(spinnerUIFontSize.getValue());
                    spinnerTextFontSize.setEnabled(false);
                } else {
                    spinnerTextFontSize.setEnabled(true);
                }
            }
        });
        chkBxLinkFontSizes.setHorizontalAlignment(SwingConstants.RIGHT);
        chkBxLinkFontSizes.setHorizontalTextPosition(SwingConstants.LEFT);

        JLabel lblLookAndFeel = new JLabel("Look and feel");
        cbBoxLookAndFeel = new JComboBox();

        JLabel lblRuleMLVersion = new JLabel("RuleML version");
        cbBoxRuleMLVersion = new JComboBox();

        JLabel lblLoggingLevel = new JLabel("Logging level");
        cbBoxLoggingLevel = new JComboBox();

        GroupLayout gl_contentPanel = new GroupLayout(contentPanel);
        gl_contentPanel.setHorizontalGroup(
                gl_contentPanel.createParallelGroup(Alignment.LEADING)
                .addGroup(Alignment.TRAILING, gl_contentPanel.createSequentialGroup()
                        .addContainerGap()
                        .addGroup(gl_contentPanel.createParallelGroup(Alignment.TRAILING)
                                .addComponent(chkBxLinkFontSizes, Alignment.TRAILING, GroupLayout.DEFAULT_SIZE, 247, Short.MAX_VALUE)
                                .addGroup(gl_contentPanel.createSequentialGroup()
                                        .addGroup(gl_contentPanel.createParallelGroup(Alignment.LEADING)
                                                .addComponent(lblTextFont)
                                                .addComponent(lblMainUiFont)
                                                .addComponent(lblLookAndFeel)
                                                .addComponent(lblRuleMLVersion)
                                                .addComponent(lblLoggingLevel))
                                                .addGap(12)
                                                .addGroup(gl_contentPanel.createParallelGroup(Alignment.TRAILING)
                                                        .addComponent(spinnerUIFontSize, GroupLayout.DEFAULT_SIZE, 140, Short.MAX_VALUE)
                                                        .addComponent(spinnerTextFontSize, GroupLayout.DEFAULT_SIZE, 140, Short.MAX_VALUE)
                                                        .addComponent(cbBoxLookAndFeel, 0, 140, Short.MAX_VALUE)
                                                        .addComponent(cbBoxRuleMLVersion, 0, 140, Short.MAX_VALUE)
                                                        .addComponent(cbBoxLoggingLevel, 0, 140, Short.MAX_VALUE)
                                                        .addGroup(gl_contentPanel.createSequentialGroup()
                                                                .addComponent(btnOk)
                                                                .addPreferredGap(ComponentPlacement.UNRELATED)
                                                                .addComponent(btnCancel)))))
                                                                .addGap(77))
                );
        gl_contentPanel.setVerticalGroup(
                gl_contentPanel.createParallelGroup(Alignment.LEADING)
                .addGroup(gl_contentPanel.createSequentialGroup()
                        .addContainerGap()
                        .addGroup(gl_contentPanel.createParallelGroup(Alignment.BASELINE)
                                .addComponent(lblMainUiFont)
                                .addComponent(spinnerUIFontSize, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))
                                .addPreferredGap(ComponentPlacement.RELATED)
                                .addGroup(gl_contentPanel.createParallelGroup(Alignment.BASELINE)
                                        .addComponent(lblTextFont)
                                        .addComponent(spinnerTextFontSize, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))
                                        .addPreferredGap(ComponentPlacement.RELATED)
                                        .addComponent(chkBxLinkFontSizes)
                                        .addPreferredGap(ComponentPlacement.RELATED)
                                        .addGroup(gl_contentPanel.createParallelGroup(Alignment.BASELINE)
                                                .addComponent(cbBoxLookAndFeel, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
                                                .addComponent(lblLookAndFeel))
                                                .addPreferredGap(ComponentPlacement.RELATED)
                                                .addGroup(gl_contentPanel.createParallelGroup(Alignment.BASELINE)
                                                        .addComponent(cbBoxRuleMLVersion, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
                                                        .addComponent(lblRuleMLVersion))
                                                        .addPreferredGap(ComponentPlacement.RELATED)
                                                        .addGroup(gl_contentPanel.createParallelGroup(Alignment.BASELINE)
                                                                .addComponent(cbBoxLoggingLevel, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
                                                                .addComponent(lblLoggingLevel))
                                                                .addPreferredGap(ComponentPlacement.RELATED, 23, Short.MAX_VALUE)
                                                                .addGroup(gl_contentPanel.createParallelGroup(Alignment.BASELINE)
                                                                        .addComponent(btnOk)
                                                                        .addComponent(btnCancel))
                                                                        .addContainerGap())
                );
        gl_contentPanel.linkSize(SwingConstants.HORIZONTAL, new Component[] {btnCancel, btnOk});
        contentPanel.setLayout(gl_contentPanel);

        populateComboBoxes();
    }

    private void populateComboBoxes() {
        for (LookAndFeelInfo lafInfo : UIManager.getInstalledLookAndFeels()) {
            cbBoxLookAndFeel.addItem(lafInfo.getName());
        }

        cbBoxRuleMLVersion.setModel(new DefaultComboBoxModel(RuleMLFormat
                .getVersionNames()));

        for (Level loggingLevel : getAvailableLoggingLevels()) {
            cbBoxLoggingLevel.addItem(loggingLevel.toString());
        }
    }

    private Level[] getAvailableLoggingLevels() {
        Level[] loggingLevels = new Level[] { Level.OFF, Level.ERROR,
                Level.WARN, Level.DEBUG, Level.INFO };

        return loggingLevels;
    }

    private SpinnerModel getSpinnerTextAreaFontSizeModel() {
        return spinnerTextFontSize.getModel();
    }

    public int getSpinnerTextAreaFontSizeValue() {
        return (Integer) getSpinnerTextAreaFontSizeModel().getValue();
    }

    public void setSpinnerTextAreaFontSizeValue(int newSize) {
        getSpinnerTextAreaFontSizeModel().setValue(newSize);
    }

    public void setSettingsController(UISettingsController newController) {
        settingsController = newController;
    }

    private SpinnerModel getSpinnerUIFontSizeModel() {
        return spinnerUIFontSize.getModel();
    }

    public int getSpinnerUIFontSizeValue() {
        return (Integer) getSpinnerUIFontSizeModel().getValue();
    }

    public void setSpinnerUIFontSizeValue(int newSize) {
        getSpinnerUIFontSizeModel().setValue(newSize);
    }

    public boolean getLinkFontSizes() {
        return chkBxLinkFontSizes.isSelected();
    }

    public void setLinkFontSizes(boolean linkFontSizes) {
        chkBxLinkFontSizes.setSelected(linkFontSizes);
    }

    public String getSelectedLookAndFeel() {
        String lafName = cbBoxLookAndFeel.getSelectedItem().toString();
        for (LookAndFeelInfo lafInfo : UIManager.getInstalledLookAndFeels()) {
            if (lafInfo.getName().equals(lafName)) {
                return lafInfo.getClassName();
            }
        }
        return UIManager.getSystemLookAndFeelClassName();
    }

    public void setLookAndFeel(String lafClassName) {
        for (LookAndFeelInfo lafInfo : UIManager.getInstalledLookAndFeels()) {
            if (lafInfo.getClassName().equals(lafClassName)) {
                cbBoxLookAndFeel.setSelectedItem(lafInfo.getName());
                break;
            }
        }
    }

    public RuleMLFormat getRuleMLFormat() {
        String selectedRuleMLFormat = cbBoxRuleMLVersion.getSelectedItem()
                .toString();
        return RuleMLFormat.fromString(selectedRuleMLFormat);
    }

    public void setRuleMLFormat(RuleMLFormat rmlFormat) {
        String ruleMLVersionName = rmlFormat.getVersionName();
        cbBoxRuleMLVersion.setSelectedItem(ruleMLVersionName);
    }

    public Level getLoggingLevel() {
        String loggingLevel = cbBoxLoggingLevel.getSelectedItem().toString();
        return Level.toLevel(loggingLevel);
    }

    public void setLoggingLevel(Level loggingLevel) {
        cbBoxLoggingLevel.setSelectedItem(loggingLevel.toString());
    }

    public void updateUI() {
        SwingUtilities.updateComponentTreeUI(this);
        this.pack();
    }
}
 public class PreferenceManager implements PreferenceChangeListener {
    private Configuration config;

    public PreferenceManager(Configuration config) {
        this.config = config;
        config.addPreferenceChangeListener(this);
        preferenceChange(null);
    }

    public void preferenceChange(PreferenceChangeEvent evt) {
        float newUIFontSize = config.getUIFontSize();
        float newTextAreaFontSize = config.getTextAreaFontSize();

        Enumeration<Object> keys = UIManager.getDefaults().keys();
        while (keys.hasMoreElements()) {
            Object key = keys.nextElement();
            Object value = UIManager.get(key);

            if (value instanceof javax.swing.plaf.FontUIResource) {
                javax.swing.plaf.FontUIResource font = (javax.swing.plaf.FontUIResource) value;
                FontUIResource newFont;

                if (key.toString().equals("TextArea.font")) {
                    newFont = new FontUIResource(
                            font.deriveFont(newTextAreaFontSize));
                } else {
                    newFont = new FontUIResource(font.deriveFont(newUIFontSize));
                }

                UIManager.put(key, newFont);
            }
        }

        try {
            UIManager.setLookAndFeel(config.getLookAndFeel());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
} public class TopDownUI implements UI {

	private final JFrame frmOoJdrew = new JFrame();
	private final DefaultReasonerMenu menuBar = new DefaultReasonerMenu();
	private final ButtonGroup typeDefinitionButtonGroup = new ButtonGroup();
	private final ButtonGroup knowledgeBaseButtonGroup = new ButtonGroup();
	private final ButtonGroup queryButtonGroup = new ButtonGroup();
	private JTable variableBindingsTable;
	private UndoRedoTextArea typeDefinitionTextArea;
	private UndoRedoTextArea knowledgeBaseTextArea;
	private UndoRedoTextArea queryTextArea;
	private JPanel typeDefinitonTab;
	private JPanel knowledgeBaseTab;
	private JSplitPane queryTab;
	private JTabbedPane tabbedPane;
	private JRadioButton typeDefinitionFormatRDFS;
	private JButton btnNextSolution;
	private JRadioButton knowledgeBaseInputFormatRuleML;
	private JRadioButton queryFormatRuleML;
	private JCheckBox typeQueryCheckbox;
	private JTree solutionTree;
	private UndoRedoTextArea solutionTextArea;
	private JScrollPane solutionTreeScrollPane;
	
	// UI controller class
	private TopDownApp controller;

	/**
	 * Launch the application.
	 */
	public static void main(String[] args) {
		EventQueue.invokeLater(new Runnable() {
			public void run() {
				try {
					TopDownUI window = new TopDownUI();
					window.frmOoJdrew.setVisible(true);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		});
	}

	/**
	 * Create the application.
	 */
	public TopDownUI() {
		initialize();
        updateUI();
	}

	/**
	 * Initialize the contents of the frame.
	 */
	private void initialize() {
		frmOoJdrew.setTitle("OO jDREW");
		frmOoJdrew.setBounds(100, 100, 700, 650);
		frmOoJdrew.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		
		frmOoJdrew.setJMenuBar(menuBar);
		
		frmOoJdrew.getContentPane().setLayout(new BorderLayout(0, 0));
		
		tabbedPane = new JTabbedPane(JTabbedPane.TOP);
		tabbedPane.setBorder(new EmptyBorder(5, 5, 5, 5));
		frmOoJdrew.getContentPane().add(tabbedPane, BorderLayout.CENTER);
		
		typeDefinitonTab = new JPanel();
		tabbedPane.addTab("Type definition", null, typeDefinitonTab, null);
		
		JButton btnLoadTypeInformation = new JButton("Load type information");
		btnLoadTypeInformation.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				controller.parseTypeInformation();
			}
		});
		
		JLabel typeDefinitionFormatLabel = new JLabel("Input format:");
		
		typeDefinitionFormatRDFS = new JRadioButton("RDFS");
		typeDefinitionButtonGroup.add(typeDefinitionFormatRDFS);
		
		JRadioButton typeDefinitionFormatPOSL = new JRadioButton("POSL");
		typeDefinitionFormatPOSL.setSelected(true);
		typeDefinitionButtonGroup.add(typeDefinitionFormatPOSL);
		
		JScrollPane typeDefinitionScrollPane = new JScrollPane();
		GroupLayout gl_typeDefinitonTab = new GroupLayout(typeDefinitonTab);
		gl_typeDefinitonTab.setHorizontalGroup(
			gl_typeDefinitonTab.createParallelGroup(Alignment.LEADING)
				.addGroup(gl_typeDefinitonTab.createSequentialGroup()
					.addContainerGap()
					.addGroup(gl_typeDefinitonTab.createParallelGroup(Alignment.LEADING)
						.addComponent(typeDefinitionScrollPane, GroupLayout.DEFAULT_SIZE, 599, Short.MAX_VALUE)
						.addGroup(gl_typeDefinitonTab.createSequentialGroup()
							.addComponent(typeDefinitionFormatLabel)
							.addPreferredGap(ComponentPlacement.UNRELATED)
							.addComponent(typeDefinitionFormatRDFS)
							.addPreferredGap(ComponentPlacement.RELATED)
							.addComponent(typeDefinitionFormatPOSL)
							.addPreferredGap(ComponentPlacement.RELATED, 231, Short.MAX_VALUE)
							.addComponent(btnLoadTypeInformation)))
					.addContainerGap())
		);
		gl_typeDefinitonTab.setVerticalGroup(
			gl_typeDefinitonTab.createParallelGroup(Alignment.LEADING)
				.addGroup(Alignment.TRAILING, gl_typeDefinitonTab.createSequentialGroup()
					.addContainerGap()
					.addComponent(typeDefinitionScrollPane, GroupLayout.DEFAULT_SIZE, 552, Short.MAX_VALUE)
					.addPreferredGap(ComponentPlacement.RELATED)
					.addGroup(gl_typeDefinitonTab.createParallelGroup(Alignment.BASELINE)
						.addComponent(btnLoadTypeInformation)
						.addComponent(typeDefinitionFormatLabel)
						.addComponent(typeDefinitionFormatRDFS)
						.addComponent(typeDefinitionFormatPOSL))
					.addContainerGap())
		);
		
		typeDefinitionTextArea = new UndoRedoTextArea("");
		typeDefinitionScrollPane.setViewportView(typeDefinitionTextArea);
		typeDefinitonTab.setLayout(gl_typeDefinitonTab);
		
		knowledgeBaseTab = new JPanel();
		tabbedPane.addTab("Knowledge base", null, knowledgeBaseTab, null);
		
		JButton btnParseKnowledgeBase = new JButton("Parse knowledge base");
		btnParseKnowledgeBase.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				controller.parseKnowledgeBase();
			}
		});
		
		JLabel knowledgeBaseInputFormatLabel = new JLabel("Input format:");
		
		knowledgeBaseInputFormatRuleML = new JRadioButton("RuleML");
		knowledgeBaseButtonGroup.add(knowledgeBaseInputFormatRuleML);
		
		JRadioButton knowledgeBaseInputFormatPOSL = new JRadioButton("POSL");
		knowledgeBaseInputFormatPOSL.setSelected(true);
		knowledgeBaseButtonGroup.add(knowledgeBaseInputFormatPOSL);
		
		JScrollPane knowledgeBaseScrollPane = new JScrollPane();
		GroupLayout gl_knowledgeBaseTab = new GroupLayout(knowledgeBaseTab);
		gl_knowledgeBaseTab.setHorizontalGroup(
			gl_knowledgeBaseTab.createParallelGroup(Alignment.LEADING)
				.addGroup(gl_knowledgeBaseTab.createSequentialGroup()
					.addContainerGap()
					.addGroup(gl_knowledgeBaseTab.createParallelGroup(Alignment.LEADING)
						.addComponent(knowledgeBaseScrollPane, GroupLayout.DEFAULT_SIZE, 599, Short.MAX_VALUE)
						.addGroup(gl_knowledgeBaseTab.createSequentialGroup()
							.addComponent(knowledgeBaseInputFormatLabel)
							.addPreferredGap(ComponentPlacement.UNRELATED)
							.addComponent(knowledgeBaseInputFormatRuleML)
							.addPreferredGap(ComponentPlacement.RELATED)
							.addComponent(knowledgeBaseInputFormatPOSL)
							.addPreferredGap(ComponentPlacement.RELATED, 221, Short.MAX_VALUE)
							.addComponent(btnParseKnowledgeBase)))
					.addContainerGap())
		);
		gl_knowledgeBaseTab.setVerticalGroup(
			gl_knowledgeBaseTab.createParallelGroup(Alignment.LEADING)
				.addGroup(Alignment.TRAILING, gl_knowledgeBaseTab.createSequentialGroup()
					.addContainerGap()
					.addComponent(knowledgeBaseScrollPane, GroupLayout.DEFAULT_SIZE, 552, Short.MAX_VALUE)
					.addPreferredGap(ComponentPlacement.RELATED)
					.addGroup(gl_knowledgeBaseTab.createParallelGroup(Alignment.BASELINE)
						.addComponent(btnParseKnowledgeBase)
						.addComponent(knowledgeBaseInputFormatLabel)
						.addComponent(knowledgeBaseInputFormatRuleML)
						.addComponent(knowledgeBaseInputFormatPOSL))
					.addContainerGap())
		);
		
		knowledgeBaseTextArea = new UndoRedoTextArea("");

		knowledgeBaseScrollPane.setViewportView(knowledgeBaseTextArea);
		knowledgeBaseTab.setLayout(gl_knowledgeBaseTab);
		
		queryTab = new JSplitPane();
		queryTab.setOrientation(JSplitPane.VERTICAL_SPLIT);
		tabbedPane.addTab("Query", null, queryTab, null);
		
		JPanel queryTopPanel = new JPanel();
		queryTopPanel.setPreferredSize(new Dimension(10, 150));
		queryTopPanel.setBorder(null);
		queryTab.setLeftComponent(queryTopPanel);
		
		JScrollPane queryScrollPane = new JScrollPane();
		
		btnNextSolution = new JButton("Next solution");
		btnNextSolution.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				controller.nextSolution();
			}
		});
		btnNextSolution.setEnabled(false);
		
		JButton btnIssueQuery = new JButton("Issue query");
		btnIssueQuery.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				controller.issueQuery();
			}
		});
		
		JLabel queryLabel = new JLabel("Query:");
		
		JLabel queryInputFormatLabel = new JLabel("Input format:");
		
		queryFormatRuleML = new JRadioButton("RuleML");
		queryButtonGroup.add(queryFormatRuleML);
		
		JRadioButton queryFormatPOSL = new JRadioButton("POSL");
		queryFormatPOSL.setSelected(true);
		queryButtonGroup.add(queryFormatPOSL);
		
		typeQueryCheckbox = new JCheckBox("Type query");
		typeQueryCheckbox.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				if(getTypeQueryCheckboxSelected())
				{
					getSolutionTreeScrollPane().setViewportView(solutionTextArea);
				}
				else
				{
					getSolutionTreeScrollPane().setViewportView(solutionTree);
				}
			}
		});
		GroupLayout gl_queryTopPanel = new GroupLayout(queryTopPanel);
		gl_queryTopPanel.setHorizontalGroup(
			gl_queryTopPanel.createParallelGroup(Alignment.TRAILING)
				.addGroup(gl_queryTopPanel.createSequentialGroup()
					.addContainerGap()
					.addGroup(gl_queryTopPanel.createParallelGroup(Alignment.LEADING)
						.addComponent(queryLabel)
						.addComponent(queryInputFormatLabel))
					.addPreferredGap(ComponentPlacement.UNRELATED)
					.addGroup(gl_queryTopPanel.createParallelGroup(Alignment.TRAILING)
						.addGroup(gl_queryTopPanel.createSequentialGroup()
							.addComponent(queryFormatRuleML)
							.addPreferredGap(ComponentPlacement.RELATED)
							.addComponent(queryFormatPOSL)
							.addPreferredGap(ComponentPlacement.RELATED)
							.addComponent(typeQueryCheckbox)
							.addPreferredGap(ComponentPlacement.RELATED, 129, Short.MAX_VALUE)
							.addComponent(btnIssueQuery)
							.addPreferredGap(ComponentPlacement.RELATED)
							.addComponent(btnNextSolution))
						.addComponent(queryScrollPane, GroupLayout.DEFAULT_SIZE, 526, Short.MAX_VALUE))
					.addContainerGap())
		);
		gl_queryTopPanel.setVerticalGroup(
			gl_queryTopPanel.createParallelGroup(Alignment.TRAILING)
				.addGroup(gl_queryTopPanel.createSequentialGroup()
					.addContainerGap()
					.addGroup(gl_queryTopPanel.createParallelGroup(Alignment.BASELINE)
						.addComponent(queryScrollPane)
						.addComponent(queryLabel))
					.addPreferredGap(ComponentPlacement.RELATED)
					.addGroup(gl_queryTopPanel.createParallelGroup(Alignment.BASELINE)
						.addComponent(btnNextSolution)
						.addComponent(btnIssueQuery)
						.addComponent(queryInputFormatLabel)
						.addComponent(queryFormatRuleML)
						.addComponent(queryFormatPOSL)
						.addComponent(typeQueryCheckbox))
					.addContainerGap())
		);
		
		queryTextArea = new UndoRedoTextArea("");
		queryScrollPane.setViewportView(queryTextArea);
		queryTopPanel.setLayout(gl_queryTopPanel);
		
		MySplitPane queryBottomPanel = new MySplitPane();
		queryBottomPanel.setResizeWeight(0.5);
		queryTab.setRightComponent(queryBottomPanel);
		
		JPanel queryLeftPanel = new JPanel();
		queryLeftPanel.setBorder(new EmptyBorder(5, 5, 5, 5));
		queryBottomPanel.setLeftComponent(queryLeftPanel);
		queryLeftPanel.setLayout(new BorderLayout(5, 5));
		
		JLabel lblSolution = new JLabel("Solution:");
		queryLeftPanel.add(lblSolution, BorderLayout.NORTH);
		
		solutionTreeScrollPane = new JScrollPane();
		queryLeftPanel.add(solutionTreeScrollPane, BorderLayout.CENTER);
		
		solutionTree = new JTree();
		solutionTree.setModel(new DefaultTreeModel(
			new DefaultMutableTreeNode("unknown") {
			}
		));		
		solutionTextArea = new UndoRedoTextArea("");
		solutionTextArea.setEditable(false);
		solutionTreeScrollPane.setViewportView(solutionTree);
		
		JPanel queryRightPanel = new JPanel();
		queryRightPanel.setBorder(new EmptyBorder(5, 5, 5, 5));
		queryBottomPanel.setRightComponent(queryRightPanel);
		queryRightPanel.setLayout(new BorderLayout(5, 5));
		
		JLabel lblVariableBindings = new JLabel("Variable bindings:");
		queryRightPanel.add(lblVariableBindings, BorderLayout.NORTH);
		
		JScrollPane variableBindingsScrollPane = new JScrollPane();
		queryRightPanel.add(variableBindingsScrollPane, BorderLayout.CENTER);
		
		variableBindingsTable = new JTable();
		variableBindingsScrollPane.setViewportView(variableBindingsTable);
		
		tabbedPane.setSelectedIndex(1);
	}

	public boolean getFrameVisible() {
		return frmOoJdrew.isVisible();
	}
	
	public void setFrameVisible(boolean visible) {
		frmOoJdrew.setVisible(visible);
	}
	
	public void setController(AbstractUIApp controller)
	{
	    menuBar.setController(controller);
		this.controller = (TopDownApp) controller;
		this.controller.syncUIWithSettings();
	}

	public void updateUI() {
		knowledgeBaseTextArea.updateUI();
		queryTextArea.updateUI();
		typeDefinitionTextArea.updateUI();
		solutionTextArea.updateUI();
		
		SwingUtilities.updateComponentTreeUI(getFrmOoJdrew());
		getFrmOoJdrew().pack();
	}
	
	public JFrame getFrmOoJdrew() {
		return frmOoJdrew;
	}
	
	private EditingTab currentEditingTab()
	{
		switch(getTabbedPaneSelectedIndex())
		{
		case 0:
			return EditingTab.EditingTabTypeDefinition;
			
		case 1:
			return EditingTab.EditingTabKnowledgeBase;
			
		case 2:
			return EditingTab.EditingTabQuery;
			
		default:
			throw new RuntimeException("Unknown tab selected.");
		}
	}
	
	private void clearCurrentEditingTab()
	{
		switch(currentEditingTab())
		{
		case EditingTabTypeDefinition:
			setTypeDefinitionTextAreaText("");
			break;
			
		case EditingTabKnowledgeBase:
			setKnowledgeBaseTextAreaText("");
			break;
			
		case EditingTabQuery:
			setQueryTextAreaText("");
			break;
		}
	}
	
	public void appendToCurrentEditingTab(String content)
	{
		StringBuilder stringBuilder = new StringBuilder();
		
		switch(currentEditingTab())
		{
		case EditingTabTypeDefinition:
			stringBuilder.append(getTypeDefinitionTextAreaText());
			stringBuilder.append(content);
			setTypeDefinitionTextAreaText(stringBuilder.toString());
			break;
			
		case EditingTabKnowledgeBase:
			stringBuilder.append(getKnowledgeBaseTextAreaText());
			stringBuilder.append(content);
			setKnowledgeBaseTextAreaText(stringBuilder.toString());
			break;
			
		case EditingTabQuery:
			stringBuilder.append(getQueryTextAreaText());
			stringBuilder.append(content);
			setQueryTextAreaText(stringBuilder.toString());
			break;
		}		
	}
	
	public void setTextForCurrentEditingTab(String content)
	{
		clearCurrentEditingTab();
		appendToCurrentEditingTab(content);
	}
	
	public String getTextForCurrentEditingTab()
	{
		String text = "";
		switch(currentEditingTab())
		{
		case EditingTabTypeDefinition:
			text = getTypeDefinitionTextAreaText();
			break;
			
		case EditingTabKnowledgeBase:
			text = getKnowledgeBaseTextAreaText();
			break;
			
		case EditingTabQuery:
			text = getQueryTextAreaText();
			break;
		}
		return text;
	}
	
	public String getTypeDefinitionTextAreaText() {
		return typeDefinitionTextArea.getText();
	}
	
	private void setTypeDefinitionTextAreaText(String text) {
		typeDefinitionTextArea.setText(text);
	}
	
	public String getKnowledgeBaseTextAreaText() {
		return knowledgeBaseTextArea.getText();
	}
	
	private void setKnowledgeBaseTextAreaText(String text_1) {
		knowledgeBaseTextArea.setText(text_1);
	}
	
	public String getQueryTextAreaText() {
		return queryTextArea.getText();
	}
	
	private void setQueryTextAreaText(String text_2) {
		queryTextArea.setText(text_2);
	}
	
	public void setSolutionTextAreaText(String text)
	{
		solutionTextArea.setText(text);
	}
	
	private int getTabbedPaneSelectedIndex() {
		return tabbedPane.getSelectedIndex();
	}
	
	public SyntaxFormat getTypeInformationInputFormat()
	{
		if(getTypeDefinitionFormatRDFSSelected())
		{
			return SyntaxFormat.RDFS;
		}
		
		return SyntaxFormat.POSL;
	}
	
	private boolean getTypeDefinitionFormatRDFSSelected() {
		return typeDefinitionFormatRDFS.isSelected();
	}
	
	public void setBtnNextSolutionEnabled(boolean enabled) {
		btnNextSolution.setEnabled(enabled);
	}
	
	private boolean getKnowledgeBaseInputFormatRuleMLSelected() {
		return knowledgeBaseInputFormatRuleML.isSelected();
	}
	
	public SyntaxFormat getKnowledgeBaseInputFormat()
	{
		if(getKnowledgeBaseInputFormatRuleMLSelected())
		{
			return SyntaxFormat.RULEML;
		}
		
		return SyntaxFormat.POSL;
	}
	
	private boolean getQueryFormatRuleMLSelected() {
		return queryFormatRuleML.isSelected();
	}
	
	public SyntaxFormat getQueryInputFormat()
	{
		if(getQueryFormatRuleMLSelected())
		{
			return SyntaxFormat.RULEML;
		}
		
		return SyntaxFormat.POSL;
	}
	
	public boolean getTypeQueryCheckboxSelected() {
		return typeQueryCheckbox.isSelected();
	}
	
	public TreeModel getSolutionTreeModel() {
		return solutionTree.getModel();
	}
	
	public void setSolutionTreeModel(TreeModel model) {
		solutionTree.setModel(model);
		solutionTree.updateUI();
	}
	
	public TableModel getVariableBindingsTableModel() {
		return variableBindingsTable.getModel();
	}
	
	public void setVariableBindingsTableModel(TableModel model_1) {
		variableBindingsTable.setModel(model_1);
		variableBindingsTable.updateUI();
	}
	
	private JScrollPane getSolutionTreeScrollPane() {
		return solutionTreeScrollPane;
	}
}
 public class POSLParser {
    Vector clauses = new Vector();

    public POSLParser() {
    }

    /**
     * Returns an interator over the clauses that are stored in the parsers
     * internal buffer; the buffer is not automatically cleared after a call
     * to iterator(). To clear the buffer a call to reset() must be invoked.
     * @return Iterator
     */
    public Iterator iterator() {
        return clauses.iterator();
    }

    /**
     * Clears the parsers internal clause buffer.
     */
    public void reset() {
        clauses = new Vector();
    }

    /**
     * This method is used to parse a single definite clause, stored in a
     * String. The DefiniteClause object that represents the parsed clause is
     * returned directly to the user and not added to the internal clause
     * buffer.
     *
     * @param clause String A string containing the clause to be parsed. If the
     * string contains multiple clauses only the first clause will be parsed.
     *
     * @return DefiniteClause The DefiniteClause object that represents the
     * parsed clause.
     *
     * @throws RecognitionException
     * @throws TokenStreamException
     */
    public DefiniteClause parseDefiniteClause(String clause) throws RecognitionException, TokenStreamException{
        StringReader sr = new StringReader(clause);
        POSLLexer lex = new POSLLexer(sr);
        org.ruleml.oojdrew.parsing.generated.POSLParser pp = new org.ruleml.oojdrew.parsing.generated.POSLParser(lex);
        return pp.clause(true);
    }

    /**
     * This method is used to parse a query - stored in a String. The
     * DefiniteClause object that represents the parsed query is returned
     * directly to the user and not added to the internal clause buffer.
     *
     * @param query String A string containing the query to be parsed. If the
     * string contains multiple queries only the first query will be parsed.
     *
     * @return DefiniteClause The DefiniteClause object that represents the
     * parsed query.
     *
     * @throws RecognitionException
     * @throws TokenStreamException
     */
    public DefiniteClause parseQueryString(String query) throws RecognitionException, TokenStreamException{
        return parseDefiniteClause("$top():-" + query + ".");
    }
	//used for parsing a Type Query String
 	public DefiniteClause parseQueryStringT(String query) throws RecognitionException, TokenStreamException{
        return parseDefiniteClause(query + ".");
    }

    /**
     * This method is used to parse a group of clauses, stored in a String. The
     * parsed clauses (DefiniteClause objects) are added to the internal clause
     * buffer and not returned directly to the caller. The an iterator over the
     * clauses can be retrieved by invoking the iterator() method.
     *
     * @param clauses String A string containing one or more clauses.
     *
     * @throws RecognitionException
     * @throws TokenStreamException
     */
    public void parseDefiniteClauses(String clauses) throws RecognitionException, TokenStreamException{
        StringReader sr = new StringReader(clauses);
        parseReader(sr);
    }

    /**
     * This method is used to parse a group of clauses stored in a local file.
     * The full path to the filename should be used. A FileReader object is
     * created using the filename as the path; then the reader is passed to
     * the parseReader(Reader) method.
     *
     * @param filename String A string containing the complete path to the file.
     *
     * @throws FileNotFoundException
     * @throws RecognitionException
     * @throws TokenStreamException
     */
    public void parseDCFile(String filename) throws FileNotFoundException, RecognitionException, TokenStreamException{
        FileReader fr = new FileReader(filename);
        parseReader(fr);
    }

    /**
     * This method is used to parse a group of clauses read from an InputStream
     * (keyboard, socket, etc.). A InputStreamReader is created using the
     * InputStream and passed to the parseReader(Reader) method. Clauses are
     * parsed until a End of File (EOF) character is reached (Typically CTRL-D
     * on Unix-like systems and CTRL-Z on Windows).
     *
     * @param is InputStream The input stream to read clauses from.
     *
     * @throws RecognitionException
     * @throws TokenStreamException
     */
    public void parseInputStream(InputStream is) throws RecognitionException, TokenStreamException {
        InputStreamReader isr = new InputStreamReader(is);
        parseReader(isr);
    }

    /**
     * This method is used by parseInputStream(), parseDCFile() and
     * parseDefiniteClauses() to perform the parsing, using the reader that is
     * created in each of those methods.
     *
     * This method creates a POSLLexer (Lexcographical Analyzer) object on the
     * Reader. Once this is done a org.ruleml.oojdrew.util.parsing.POSLParser object
     * created on the lexer and the rulebase(Vector) method is invoked to parse
     * the rulebase that is read from the reader.
     *
     * @param r Reader The reader to read the input from.
     *
     * @throws RecognitionException
     * @throws TokenStreamException
     */
    private void parseReader(Reader r) throws RecognitionException, TokenStreamException {
        POSLLexer lex = new POSLLexer(r);
        org.ruleml.oojdrew.parsing.generated.POSLParser pp = new org.ruleml.oojdrew.parsing.generated.POSLParser(lex);
        pp.rulebase(this.clauses);
    }
}
 public class RDFSParser {
    private static String rdfsuri;
    private static String rdfuri;

    private static final String RDF = "rdf";
    private static final String RDFS = "rdfs";
    private static final String RDFSCLASS = "rdfs:Class";
    private static final String RDFDESCRIPTION = "rdf:Description";
    private static final String RDFID = "rdf:ID";
    private static final String RDFABOUT = "rdf:about";
    private static final String RDFRESOURCE = "rdf:resource";
    private static final String RDFSSUBCLASSOF = "rdfs:subClassOf";
    private static final String RDFTYPE = "rdf:type";

    private static final String CLASS = "Class";
    private static final String DESCRIPTION = "Description";
    private static final String ID = "ID";
    private static final String ABOUT = "about";
    private static final String RESOURCE = "resource";
    private static final String SUBCLASSOF = "subClassOf";
    private static final String TYPE = "type";

    private static final String CLASSRES =
            "http://www.w3.org/2000/01/rdf-schema#Class";

   // private static Logger logger = Logger.getLogger("jdrew.oo.util.RDFSParser");

    /**
     * Method to parse an RDFS file and load the type information in the RDFS
     * into the engines type sorts.
     *
     * This method parses the file into a XOM tree and passes the XOM
     * Document object to the parseDocument(Document doc) method.
     *
     * @param filename String A string containing the complete path to the RDFS
     * file.
     *
     * @throws ParsingException Thrown if there is an error in the RDFS file
     * that causes parsing to fail.
     *
     * @throws ValidityException Thrown if the XML document is not wellformed
     * or does not conform to the RDFS DTD.
     *
     * @throws IOException Thrown if there is an error reading the file from
     * disk.
     */
    public static void parseRDFS(String filename) throws ParsingException,
        ValidityException, IOException {
        Builder b = new Builder();
        File f = new File(filename);
        Document doc = b.build(f);
        parseDocument(doc);
    }

    public static void parseRDFSFile(File f) throws ParsingException, ValidityException, IOException {
    	Builder b = new Builder();	
    	Document doc = b.build(f);
    	parseDocument(doc);
    }

    /**
     * Method that parses an RDFS document contained in a string and load the
     * type information in the RDFS into the engines type sorts.
     *
     * This method parses the string to an XOM document and passes the Document
     * object to the parseDocument(Document doc) method.
     *
     * @param contents String
     *
     * @throws ParseException Thrown if there is an error in the RDFS document
     * that causes parsing to fail.
     *
     * @throws ParsingException Thrown if there is an error parsing at an XML
     * level.
     *
     * @throws ValidityException Thrown if the XML document is not wellformed
     * or does not conform to the RDFS DTD.
     *
     * @throws IOException Thrown if there is an error reading the string -
     * this should not occur.
     */
    public static void parseRDFSString(String contents) throws ParseException,
            ParsingException, ValidityException, IOException {
        Builder bl = new Builder();

        StringReader sr = new StringReader(contents);
        Document doc = bl.build(sr);
        
        //System.out.println(doc.toXML());
        parseDocument(doc);
    }

    /**
     * Parses the XOM document object that should represent an RDFS document;
     * containing types that will be added to the type sorts.
     *
     * @param doc Document The XOM document object to parse.
     */
    private static void parseDocument(Document doc) {
        Element root = doc.getRootElement();
        rdfsuri = root.getNamespaceURI("rdfs");
        rdfuri = root.getNamespaceURI("rdf");

        //logger.debug("RDFS Uri: " + rdfsuri);
        //logger.debug("RDF Uri: " + rdfuri);

        Elements els = root.getChildElements();
        for (int i = 0; i < els.size(); i++) {
            Element el = els.get(i);
            //logger.debug("Parsing element: " + el.getQualifiedName());
            if (el.getQualifiedName().equals(RDFSCLASS)) {
                parseClass(el);
            } else if (el.getQualifiedName().equals(RDFDESCRIPTION)) {
                parseDescription(el);
            } else {
                //logger.debug(
                //        "Unrecognized element in RDFS file. Element being ignored.");
            }
            
        }
// should put new type parser here
        Types.makeTypes();
        
    }

    /**
     * This method parses a rdfs:Class element and loads the information
     * contained into the Type system.
     *
     * @param cls Element The XOM element that contains the rdfs:Class object.
     */
    private static void parseClass(Element cls) {
        String typename = cls.getAttributeValue(ID, rdfuri);
        if (typename == null) {
          //  logger.debug(
           //         "rdfs:Class element does not have rdf:ID attribute - trying rdf:about");
            typename = cls.getAttributeValue(ABOUT, rdfuri);
            if (typename == null) {
                //logger.warn("rdfs:Class element does not have and rdf:about or rdf:ID attribute - no typename - type creation failure.");
                return;
            }
        }

        if (typename.indexOf("#") > 0) {
            typename = typename.substring(typename.indexOf("#") + 1);
        }

        Vector v = new Vector();
        Elements els = cls.getChildElements();
        for (int i = 0; i < els.size(); i++) {
            Element el = els.get(i);
            if (el.getQualifiedName().equals(RDFSSUBCLASSOF)) {
                String parentname = el.getAttributeValue(RESOURCE, rdfuri);
                if (parentname.indexOf("#") >= 0) {
                    parentname = parentname.substring(parentname.indexOf("#") +
                            1);
                }
                v.add(parentname);
            }
        }

        String[] parents = new String[v.size()];
        String parentstr = "";
        for (int i = 0; i < parents.length; i++) {
            parents[i] = v.get(i).toString();
            parentstr += v.get(i).toString() + " ";
        }

        //logger.info("Creating Type: " + typename + " parents: " + parentstr);
       // System.out.println("Dies before createType");
        
        Types.storeTempTypes(typename, parents);
       // Types.createDAGNode(typename);
       // Types.createDAGEdges(typename, parents);



}

    /**
     * Parses a rdf:description element and loads the type information into the
     * type sorts.
     *
     * @param desc Element The XOM element object representing the
     * rdf:description element.
     */
    private static void parseDescription(Element desc) {
        String typename = desc.getAttributeValue(ID, rdfuri);
        if (typename == null) {
           // logger.debug(
           //         "rdf:Description element does not have rdf:ID attribute - trying rdf:about");
            typename = desc.getAttributeValue(ABOUT, rdfuri);
            if (typename == null) {
               // logger.warn("rdf:Description element does not have an rdf:about or rdf:ID attribute - no typename - type creation failure.");
                return;
            }
        }

        if (typename.indexOf("#") > 0) {
            typename = typename.substring(typename.indexOf("#") + 1);
        }

        Element type = desc.getFirstChildElement(TYPE, rdfuri);
        if (type == null ||
            !type.getAttributeValue(RESOURCE, rdfuri).equals(CLASSRES)) {
           // logger.warn(
           //         "rdf:Description element has not rdf:type child element, or is not of type " +
            //        CLASSRES + " - ignoring rdf:Description element.");
            return;
        }

        if (typename.indexOf("#") >= 0) {
            typename = typename.substring(typename.indexOf("#") + 1);
        }

        Vector v = new Vector();
        Elements els = desc.getChildElements();
        for (int i = 0; i < els.size(); i++) {
            Element el = els.get(i);
            if (el.getQualifiedName().equals(RDFSSUBCLASSOF)) {
                String parentname = el.getAttributeValue(RESOURCE, rdfuri);
                if (parentname.indexOf("#") >= 0) {
                    parentname = parentname.substring(parentname.indexOf("#") +
                            1);
                }
                v.add(parentname);
            }
        }

        String[] parents = new String[v.size()];
        String parentstr = "";
        for (int i = 0; i < parents.length; i++) {
            parents[i] = v.get(i).toString();
            parentstr += v.get(i).toString() + " ";
        }

        //logger.info("Creating Type: " + typename + " parents: " + parentstr);

        //Types.createType(typename, parents);
        
        Types.storeTempTypes(typename, parents);
        
       // Types.createDAGNode(typename);
       // Types.createDAGEdges(typename, parents);
    }


}
 public class RuleMLParser implements PreferenceChangeListener {

    /**
     * A buffer that stores clauses that have already been parsed.
     */
    private Vector<DefiniteClause> clauses;
    private Configuration config;
    
    private RuleMLFormat rmlFormat;

    private Level logLevel;

    /**
     * Constructs a new parser object.
     * 
     * @param config
     *            The configuration instance which should be used
     */
    public RuleMLParser(Configuration config) {
        clauses = new Vector<DefiniteClause>();
        this.config = config;
        config.addPreferenceChangeListener(this);
        preferenceChange(null);
    }

    /**
     * Gets an iterator over all clauses that are stored in the internal clause
     * buffer. This method does not automatically clear items from the buffer.
     * 
     * @return Iterator An iterator over all clauses in the buffer.
     */
    public Iterator<DefiniteClause> iterator() {
        return clauses.iterator();
    }

    /**
     * Clears the internal buffer; and forces a garbage collection cycle. This
     * allows the easy reuse of a parser object.
     */
    public void clear() {
        clauses = new Vector<DefiniteClause>();
        System.gc();
    }

    /**
     * @see jdrew.oo.parsing.RuleMLParser#parseDocument
     */
    public void parseFile(String filename) throws ParseException, ParsingException, IOException {
        File file = new File(filename);
        parseFile(file);
    }

    /**
     * @see jdrew.oo.parsing.RuleMLParser#parseDocument
     */
    public void parseFile(File file) throws ParseException, ParsingException, IOException {
        Builder bl = new Builder();
        Document doc = bl.build(file);
        parseDocument(doc);
    }

    /**
     * @see jdrew.oo.parsing.RuleMLParser#parseDocument
     */
    public void parseRuleMLString(String contents) throws ParseException, ParsingException, IOException {
        Builder bl = new Builder();
        StringReader sr = new StringReader(contents);
        Document doc = bl.build(sr);
        parseDocument(doc);
    }

    /**
     * Parses a document containing a knowledge base that is in the indicated
     * format. If additional backed parsers are created then additional formats
     * will be added.
     * 
     * NOTE: It may be a good idea to add format auto detection based upon the
     * XSD and/or DTD that is referenced by the document.
     * 
     * @param format
     *            RuleMLVersion The RuleML version for the back-end parser
     * 
     * @param doc
     *            The document which should be parsed
     * 
     * @throws ParseException
     *             A ParseException is thrown if there is an error in the
     *             document that causes parsing to fail.
     * 
     * @throws ParsingException
     *             A ParsingException is thrown if there is an error in parsing
     *             the document at an XML level or a ValidityException
     *             (subclass) is thrown if the XML document is not well * formed
     *             or does not conform to the DTD specified.
     */
    public void parseDocument(Document doc) throws ParseException, ParsingException {
        RuleMLDocumentParser parser = new RuleMLDocumentParser(rmlFormat, clauses);
        parser.setLogLevel(logLevel);

        parser.parseRuleMLDocument(doc);
    }

    /**
     * Parses a RuleML query
     * 
     * @param contents
     *            The document content
     * 
     * @return A DefiniteClause containing the parsed document
     * 
     * @throws ParseException
     * @throws ParsingException
     * @throws IOException
     */
    public DefiniteClause parseRuleMLQuery(String contents)
            throws ParseException, ParsingException, IOException {

        contents = ensureQueryTag(contents);
        contents = buildFakeImplication(contents);

        parseRuleMLString(contents);

        return (DefiniteClause) clauses.lastElement();
    }

    /**
     * Builds a fake implication which is needed to satisfy the reasoning
     * engine.
     * 
     * @param query
     *            An input query
     * 
     * @return Input query as a RuleML implication
     */
    private String buildFakeImplication(String query) {
        Builder builder = new Builder();
        StringReader stringReader = new StringReader(query);
        Document document;

        try {
            document = builder.build(stringReader);
        } catch (Exception e) {
            // Cannot happen
            e.printStackTrace();
            return "";
        }

        Element queryElement = document.getRootElement();

        RuleMLTagNames rmlTags = new RuleMLTagNames(rmlFormat);

        Element rel = new Element(rmlTags.REL);
        rel.insertChild("$top", 0);

        Element topAtom = new Element(rmlTags.ATOM);
        topAtom.appendChild(rel);

        Nodes atoms = queryElement.removeChildren();

        Element implies = new Element(rmlTags.IMPLIES);

        for (int i = 0; i < atoms.size(); ++i) {
            implies.appendChild(atoms.get(i));
        }

        implies.appendChild(topAtom);

        queryElement.appendChild(implies);

        return document.toXML();
    }

    /**
     * Manually add <Query> wrapper if not exists
     * 
     * @param query
     *            An input query
     * 
     * @return Input query encapsulated with a <Query> tag
     */
    private String ensureQueryTag(String query) {
        // Evil hack: encapsulate the query contents in a pair of <Query> tags
        RuleMLTagNames rmlTags = new RuleMLTagNames(rmlFormat);
        query = query.trim();
        String queryTagOpen = String.format("<%s>", rmlTags.QUERY);
        String queryTagClose = String.format("</%s>", rmlTags.QUERY);

        if (!query.contains(queryTagOpen)) {
            query = String.format("%s%s%s", queryTagOpen, query, queryTagClose);
        }

        return query;
    }

    /**
     * Updates parser configuration when preferences have changed
     */
    public void preferenceChange(PreferenceChangeEvent evt) {
        rmlFormat = config.getRuleMLFormat();
        logLevel = config.getLogLevel();
    }
}
 public class SubsumesParser {
	
	String parseString;
	/** A Vector of the subsumes Objects in the system after parsing. */
	Vector subsumeObjects = new Vector();
	
	/** A Vector of Strings that contain all the classes in the type system after parsing. */
	Vector allClasses = new Vector();
	
	/** A Vector of RDFObjects in the type system after parsing. */
	Vector RDFObjects = new Vector();
	String finalRDFSString = "";
	/** 
	 * This is the constructor for the subsumes parser.  All it needs is a string to be
	 * parsed.
	 *   
	 * @param String - parseString this is the POSL representation of the type system to be
	 * parsed
	 */
	public SubsumesParser(String parseString){
		
		this.parseString = parseString;
	}
	
	public SubsumesParser()
	{
		this.parseString = "";
	}
	
	/**
	 * This method will parse the given String when the SubsumesParser was created. 
	 *
	 * @throws SubsumesException - a Exception that could occur depending on invalid formatting
	 * @throws IOException 
	 * @throws ParsingException 
	 * @throws ParseException 
	 * @throws ValidityException 
	 */
	
	public void parseSubsumes() throws SubsumesException, ValidityException, ParseException, ParsingException, IOException{
		this.buildSubsumeObjects();
		this.buildRDFObjects();
		RDFSParser.parseRDFSString(finalRDFSString);
		//this.buildTypes();
	}
	
	public void parseSubsumes(String parseString) throws SubsumesException, ValidityException, ParseException, ParsingException, IOException
	{
		this.parseString = parseString;
		parseSubsumes();
	}
	
	/**
	 * This method will parse through all the given subsumes relations and create
	 * objects for them.  The objects contain a 2 strings one for the super class and one 
	 * for the sub class.
	 * 
	 * @throws SubsumesException a Exception that could occur depending on invalid formatting
	 */
	public void buildSubsumeObjects() throws SubsumesException{
		
		 Vector rdfsObjects = new Vector();
	 	 //Parsing the POSL String given
		 POSLParser pp = new POSLParser();
		 try{
		 pp.parseDefiniteClauses(parseString);
		 }catch(Exception e){
			 throw new SubsumesException("Incorrect POSL syntax");
		 }
		 //Obtaining the Parsed subsume objects	 
		 Iterator it = pp.iterator();
		 
		 //Iterating through all of the clauses to make sure they are of valid syntax
		 //Once they have been validated then a subsumes Object is created to 
		 //store the parameters of the subsumes objects
		 while (it.hasNext()) {
		    DefiniteClause dc = (DefiniteClause) it.next();
		    
		    Term[] atoms = dc.atoms;
	    	if(atoms.length != 1){
	    		throw new SubsumesException("Types cannot contain a rule.");
	       	}
	    	Term t1 = atoms[0];
	    	String predicate = t1.getSymbolString();
	    	if(!predicate.equals("subsumes")){
	    		throw new SubsumesException("Only subsumes facts can be in type definition.");	
	    	}
	    	Term[] terms = t1.getSubTerms();
	    	
    		if(terms.length != 3){
    			throw new SubsumesException("Subsumes facts can only have 2 arguments.");
    		}
    		String[] varnames = dc.variableNames;
    		String term1 = terms[1].toPOSLString(varnames,true);
    		String term2 = terms[2].toPOSLString(varnames,true);
    		//System.out.println(term1 + " " + term2);
    	    boolean t1Var = false;
    	    boolean t2Var = false;
    		
    	    String term1Sub = term1.substring(0,1);
    	    String term2Sub = term2.substring(0,1);
    	    
    	    if(term1Sub.equals("?")){
    	    	throw new SubsumesException("Subsumes facts cannot contain variables in type definitions");
    	    	
    	    }
    	    if(term2Sub.equals("?")){
    	    	throw new SubsumesException("Subsumes facts cannot contain variables in type definitions");
    	    	
    	    }
    	    
    	    SubsumesObject so = new SubsumesObject(term1,term2);
    	    
    	    subsumeObjects.add(so);	 
		 }
		 
	}
	/**
	 * Iterating through all of the subsume objects to create RDF Objects
	 * RDF objects contain the the parent class and all of its sub classes.
	 */
	public void buildRDFObjects(){
		String allRDFSObjects = "";
		
		Iterator it = subsumeObjects.iterator();
		String superClass;
		String subClass;
		String compare;
		boolean firstPass = true;
		boolean superDuplicate = false;
		boolean subDuplicate = false;
		
		//Looping through the subsume Objects to determine all of the classes in the
		//Type System duplicates must be removed.
		
		while(it.hasNext()){
			superDuplicate = false;
			subDuplicate = false;
			
			Object b = it.next();
			SubsumesObject so = (SubsumesObject) b;
			
			superClass = so.getSuperClass();
			subClass = so.getSubClass() ;

			if(firstPass){
				//System.out.println("First pass");
				firstPass = false;
				allClasses.add(superClass);
			}
			int classSize = allClasses.size();
			
			Iterator allClassIt = allClasses.iterator();
			//checking for duplicates
			while(allClassIt.hasNext()){
				
				Object comp = allClassIt.next();
				compare = comp.toString();
				
				if(superClass.equals(compare)){
					//System.out.println("Found duplicate super");
					superDuplicate = true;
				}
				
				if(subClass.equals(compare)){
					//System.out.println("Found duplicate sub");
					subDuplicate = true;
				}
			}	
			if(!superDuplicate){
				allClasses.add(superClass);
			}
			if(!subDuplicate){
				allClasses.add(subClass);			
			}
		}
						
		
		Iterator secondPass = allClasses.iterator();
		//make all RDF objects for each class
		//This iteration will create all of the RDF Objects needed
		//We need to find all of the subClasses of every class collected in the
		//allClasses Vector.
		while(secondPass.hasNext()){

			Object sup = secondPass.next();
			String mainClass = sup.toString();
			
			Iterator subObjects = subsumeObjects.iterator();
			//find all parents of each rdf object
			Vector allParents = new Vector();
			while(subObjects.hasNext()){	
				Object subObject = subObjects.next();
				SubsumesObject so = (SubsumesObject)subObject;
				String superC = so.getSuperClass();
				String subC   = so.getSubClass();
				
				if(mainClass.equals(subC)){
					allParents.add(superC);
				}
			
			}
			int size = allParents.size();
			String[] parents = new String[size];
			
			for(int i = 0 ; i < size; i++){
				Object parOb = allParents.elementAt(i);
				parents[i] = parOb.toString();
			}

			RDFObject ro = new RDFObject(mainClass,parents);	
			
			String rdfStringSingle = "<rdf:Description rdf:ID=\""+ro.getName()+"\">" +"\n" + 
			"<rdf:type rdf:resource=\"http://www.w3.org/2000/01/rdf-schema#Class\"/>\n";
			
			String[] parentz = ro.getParents();
			
			for(int i = 0; i <parentz.length; i++){
				rdfStringSingle = rdfStringSingle + "<rdfs:subClassOf rdf:resource=\"#" + parentz[i]+ "\"/>\n";			
			}
			rdfStringSingle = "\n" + rdfStringSingle + "</rdf:Description>\n";
			allRDFSObjects = allRDFSObjects + rdfStringSingle;		
			RDFObjects.add(ro);
		}	

		
		  finalRDFSString =
		  "<rdf:RDF\n" + 	 
		  "xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\"\n" +
		  "xmlns:rdfs=\"http://www.w3.org/2000/01/rdf-schema#\"\n" + 
		  "xml:base=\"http://example.org/schemas/vehicles\">\n" +
		  allRDFSObjects + "\n" +
		  "</rdf:RDF>";

	}
	/**
	 * This method will create the RDFS Types.  Once the RDF Objects have been created
	 * all that is left to do is define them in the Type Graph.
	 */
	public void buildTypes(){
		
		Iterator it = RDFObjects.iterator();
		
		while(it.hasNext()){
			
			Object ob = it.next();
			RDFObject rdfsOb = (RDFObject)ob;
			
			String name = rdfsOb.getName();
			String[] parents = rdfsOb.getParents();

			Types.createType(name, parents);
			
		}
	}
	
}//SubsumesParser Class
 public class TypeQueryParserPOSL {

	private String queryContents;
	private boolean validPredicate;
	private String[] varnames;
	
	
	//defining the valid predicates for type querying
	public final static String LUB =  "lub";
	public final static String GLB =  "glb";
	public final static String SUBSUMES = "subsumes";
	public final static String SUBSUMESPLUS = "subsumesPlus";
	
	//predicate used for querying
	private String predicate = "";
	
	/**
	 * Constructor for a TypeQueryParserPOSL
	 * 
	 * @param contents - the query to be parsed
	 */
	public TypeQueryParserPOSL(String contents){
	
		queryContents = contents;
	
	}
	
	/**
	 * Access Method to get the predicate name
	 * 
	 * @return the predicate name
	 */
	public String getPredicate(){
		return predicate;
	}
	
	/**
	 * Access method to see if a predicate is valid or not
	 * 
	 * @return true if the predicate is valid false otherwise
	 */
	public boolean getValidPredicate(){
		return validPredicate;
	}
	
	/**
	 * This method will parse the Query and determine if the predicate is valid or not
	 * 	
	 * @return Term[] - the terms of the predicate that need to be further parsed
	 * @throws RuleMLTypeQueryException
	 * @throws ParseException
	 * @throws ParsingException
	 * @throws ValidityException
	 * @throws IOException
	 */
	public Term[] parseForPredicate()  throws Exception, POSLTypeQueryException, ParseException, ParsingException, ValidityException, IOException{
					
		//dc will contain the query
		DefiniteClause dc = null;
		//parsing the giving query
      	POSLParser pp = new POSLParser();
        dc = pp.parseQueryStringT(queryContents); 
    	//Determining if the Query is valid
       	//I.E no rules are allowed in a query
    	Term[] atoms = dc.atoms;
    	if(atoms.length != 1){
    		throw new POSLTypeQueryException("Rules cannot be used for type Queries");
       	}
    	//Determining what the predicate is
    	//Valid Predicates are GLB(Greater Lower Bound) LUB(Least Upper Bound)
    	//Subsumes(direct subclass of) subsumesPlus(transitive closure).
    	Term t1 = atoms[0];
    	predicate = t1.getSymbolString();

    	if(predicate.equalsIgnoreCase(LUB)  ||
  	 			predicate.equalsIgnoreCase(GLB) ||
  	 			predicate.equalsIgnoreCase(SUBSUMES) ||
  	 			predicate.equalsIgnoreCase(SUBSUMESPLUS)){
  	 	
  	 	   validPredicate = true;
  	 		
  	 	} else{
  	 		
  	 		validPredicate = false;
  	 		throw new POSLTypeQueryException("Only LUB, GLB, Subsumes, and SubsumesPlus are valid predcates");
  	 	}
    	
    	Term[] terms = t1.getSubTerms();
    	varnames = dc.variableNames;
  	 	return terms;
 	 	
	}
	
	/**
	 * This method will determine the structure of the subsumes Query
	 * 
	 * @param terms[] - the terms that need to be parsed into a subsumes structure
	 * @return subsumesStructure - structure used to query a subsumes or subsumesPlus predicate
	 * @throws RuleMLTypeQueryException
	 */
	public SubsumesStructure parseElementsSubsumesAndSubsumesPlus(Term[] terms) throws POSLTypeQueryException{
		
		if(terms.length != 3){
			throw new POSLTypeQueryException("Subsumes and Subsumes plus must have 2 arguments");
		}
		
		String superName = terms[1].toPOSLString(varnames,true);
		String subName = terms[2].toPOSLString(varnames,true);
		boolean superVar = false;
		boolean subVar = false;
		
		if(superName.length() == 1 || subName.length() == 1){
			throw new POSLTypeQueryException("Anonymous are not allowed");
		}
	
		
		String term1Sub = superName.substring(0,1);
    	String term2Sub = subName.substring(0,1);
    	    
    	if(term1Sub.equals("?"))
    	   	superVar = true;
    	if(term2Sub.equals("?"))
    	   	subVar = true;
		
    	String superVarName = superName;
    	String subVarName = subName;
    	
    	if(superVar){
    		superVarName = superName.substring(1,superName.length()-2);
    	}
    	   	   	   	
    	if(subVar){
    		subVarName = subName.substring(1,subName.length()-2);
    	 }
    	
		if(superVar && subVar && superName.equalsIgnoreCase(subName)){
			throw new POSLTypeQueryException("Cannot have duplicate variable names in subsumes or subsumesPlus");
		}
    	
		return new SubsumesStructure(superVarName, subVarName,  superVar, subVar);
	}
	
	/**
	 * This method will determine the structure of the LUB or GLB Query
	 * 
	 * @param terms - the terms that need to be parsed into a LUB or GLB structure
	 * @return LUBGLBStructure - structure used to query a LUB or GLB predicate
	 * @throws RuleMLTypeQueryException
	 */
	public LUBGLBStructure parseElementsGLBandLUB(Term[] terms) throws POSLTypeQueryException{

		ArrayList<String> classes = new ArrayList<String>();
		boolean resultVarUsed = false;

		String resultVarName  = terms[1].toPOSLString(varnames,true);
        String term1Sub = resultVarName.substring(0,1);

        if(term1Sub.equals("?"))
        	resultVarUsed = true;

        if(resultVarUsed)
        	resultVarName = resultVarName.substring(1,resultVarName.length()-2);


        if(resultVarUsed){
			
			for(int i = 2; i < terms.length;i++)
				classes.add(terms[i].toPOSLString(varnames,true));
			
		}else {
			
			for(int i = 1; i < terms.length;i++)
				classes.add(terms[i].toPOSLString(varnames,true));
		}
		
		return new LUBGLBStructure(classes, resultVarUsed, resultVarName);
	}		
} public class TypeQueryParserRuleML {

	private String queryContents;
	private boolean validPredicate;

	//defining the valid predicates for type querying
	public final static String LUB =  "LUB";
	public final static String GLB =  "GLB";
	public final static String SUBSUMES = "Subsumes";
	public final static String SUBSUMESPLUS = "SubsumesPlus";
	
	//valid RuleML tags
	private final static String REL = "Rel";
	private final static String VAR = "Var";
	
	//predicate used for querying
	private String predicate = "";
	

	/**
	 * Constructor for a TypeQueryParserRuleML
	 * 
	 * @param contents - the query to be parsed
	 */
	public TypeQueryParserRuleML(String contents){
	
		queryContents = contents;
	
	}
	
	public TypeQueryParserRuleML(){
	
	}
	
	/**
	 * Access Method to get the predicate name
	 * 
	 * @return the predicate name
	 */
	public String getPredicate(){
		return predicate;
	}
	
	/**
	 * Access method to see if a predicate is valid or not
	 * 
	 * @return true if the predicate is valid false otherwise
	 */
	public boolean getValidPredicate(){
		return validPredicate;
	}
	
	/**
	 * This method will parse the Query and determine if the predicate is valid or not
	 * 	
	 * @return Elements - the elements of the predicate that need to be further parsed
	 * @throws RuleMLTypeQueryException
	 * @throws ParseException
	 * @throws ParsingException
	 * @throws ValidityException
	 * @throws IOException
	 */
	public Elements parseForPredicate()  throws RuleMLTypeQueryException, ParseException, ParsingException, ValidityException, IOException{
					
	    Builder bl = new Builder();
   		StringReader sr = new StringReader(queryContents);
  	 	Document doc = bl.build(sr);
		
  	 	//get predicate element
  	 	Element root = doc.getRootElement();
     	
  	 	predicate = root.getLocalName();
  	 	
  	 	if(predicate.equalsIgnoreCase(LUB)  ||
  	 			predicate.equalsIgnoreCase(GLB) ||
  	 			predicate.equalsIgnoreCase(SUBSUMES) ||
  	 			predicate.equalsIgnoreCase(SUBSUMESPLUS)){
  	 	
  	 	   validPredicate = true;
  	 		
  	 	} else{
  	 		
  	 		validPredicate = false;
  	 		throw new RuleMLTypeQueryException("Only LUB, GLB, Subsumes, and SubsumesPlus are valid predcates");
  	 	}

  	 	//get all the roots the predicate
  	 	return root.getChildElements();
 	 	
	}
	
	/**
	 * This method will determine the structure of the subsumes Query
	 * 
	 * @param elements - the elements that need to be parsed into a subsumes structure
	 * @return subsumesStructure - structure used to query a subsumes or subsumesPlus predicate
	 * @throws RuleMLTypeQueryException
	 */
	public SubsumesStructure parseElementsSubsumesAndSubsumesPlus(Elements elements) throws RuleMLTypeQueryException{
		
		if(elements.size() != 2){
			throw new RuleMLTypeQueryException("Subsumes and Subsumes plus must have 2 arguments");
		}
		
		Element superClass = elements.get(0); 
		Element subClass = elements.get(1);
		
		String superName = superClass.getValue();
		String subName = subClass.getValue();
		boolean superVar = false;
		boolean subVar = false;
		
		if(superClass.getLocalName().equalsIgnoreCase(REL)){
			superVar = false;
		}else if(superClass.getLocalName().equalsIgnoreCase(VAR)){
			superVar = true;
		}else{
			throw new RuleMLTypeQueryException("Only Rel and Var tags can be used inside of Subsumes or SubsumesPlus");
		}
		
		if(subClass.getLocalName().equalsIgnoreCase(REL)){
			subVar = false;
		}else if(subClass.getLocalName().equalsIgnoreCase(VAR)){
			subVar = true;
		}else{
			throw new RuleMLTypeQueryException("Only Rel and Var tags can be used inside of Subsumes or SubsumesPlus");
		}

		if(superVar && subVar && superName.equalsIgnoreCase(subName)){
			throw new RuleMLTypeQueryException("Cannot have duplicate variable names in subsumes");
		}
		
		return new SubsumesStructure(superName, subName,  superVar, subVar);
	}
	
	/**
	 * This method will determine the structure of the LUB or GLB Query
	 * 
	 * @param elements - the elements that need to be parsed into a LUB or GLB structure
	 * @return LUBGLBStructure - structure used to query a LUB or GLB predicate
	 * @throws RuleMLTypeQueryException
	 */
	public LUBGLBStructure parseElementsGLBandLUB(Elements elements) throws RuleMLTypeQueryException{
		
		Element firstTerm = elements.get(0);
		
		
		ArrayList<String> terms = new ArrayList<String>();
		boolean resultVarUsed = false;
		String resultVarName = firstTerm.getValue(); 
					 
		if(firstTerm.getLocalName().equalsIgnoreCase(VAR)){
			resultVarUsed = true;
		}else if(!firstTerm.getLocalName().equalsIgnoreCase(REL)){
			throw new RuleMLTypeQueryException("Only Rel and Var tags can be used as the first term inside of a GLB or LUB");
		}
				
		int index = 0;
		//if the first term in the LUB / GLB function is a VAR we need the index to be set to 1
		if(resultVarUsed){
			index = 1;
		}else {
			index = 0;
		}

		//loop through children , add them to array list, skip first child if needed
		
		for(int i = index; i < elements.size(); i++){
			Element e = elements.get(i);
			if(!e.getLocalName().equalsIgnoreCase(REL)){
				throw new RuleMLTypeQueryException("Only Rel tags can be used for the second terms and on inside of a GLB or LUB");
			}
			System.out.println(e.getValue());
			terms.add(e.getValue());
		}

		return new LUBGLBStructure(terms, resultVarUsed, resultVarName);
	}
}
 public class DefiniteClause {

    /**
     * Contains the Term objects that represent the Atoms of the clause. The
     * term at index 0 is the head of the clause. The atoms at indices 1 .. n-1
     * are the Atoms of the body of the clause if they exist.
     */
    public Term[] atoms;

    /**
     * Contains the variable names for this clause. Since OO jDREW uses local
     * shallow binding the variables have a local scope and are stored with the
     * clause instead of in the global symbol table.
     */
    public String[] variableNames;

    /**
     * Creates a new clause representation using the a Vector of atoms and a
     * Vector of variable names. This constructor assumes that the types for a
     * variable are correct (i.e. a variable doesn't have a type that doesn't
     * exist and a variable doesn't have two different types at two places in
     * the clause).
     * 
     * A definite Clause Needs A Vector Of Term Objects that represent The atoms
     * of the clause to be constructed. The first object(Index 0) is the head of
     * the clause, while any remaining objects are the body atoms
     * (conjunctively)joined The VariableNames vector contains the names for the
     * variable names for the clause to be constructed.
     * 
     * @param atoms
     *            Vector A vector of Term objects that represent the Atoms of
     *            the clause to be constructed. The first object (index 0) is
     *            the head of the clause, while any remaining objects are the
     *            body atoms (conjunctively) joined.
     * 
     * @param variableNames
     *            Vector A vector containing the variable names for the clause
     *            to be constructed.
     */
    public DefiniteClause(Vector atoms, Vector variableNames) {
        this.atoms = new Term[atoms.size()];
        for (int i = 0; i < this.atoms.length; i++) {
            this.atoms[i] = (Term) atoms.get(i);
        }

        this.variableNames = new String[variableNames.size()];
        for (int i = 0; i < this.variableNames.length; i++) {
            this.variableNames[i] = (String) variableNames.get(i);
        }
    }

    /**
     * Creates and returns a string representation of the clause in either POSL
     * or RuleML format. The format is determined by the
     * org.ruleml.oojdrew.Config.PRPRINT variable. If PRPRINT is true - then the
     * POSL format is used for output, otherwise RuleML (0.88 +) is used.
     * 
     * @return The string representation of the clause.
     */
    public String toString() {
        if (org.ruleml.oojdrew.Config.PRPRINT) {
            return toPOSLString();
        } else {
            // TODO remove constant version
            return toRuleMLString(RuleMLFormat.RuleML88); 
        }
    }

    /**
     * Creates and returns a string representation of the clause in either POSL
     * or RuleML format. The format is determined by the
     * org.ruleml.oojdrew.Config.PRPRINT variable. If PRPRINT is true - then the
     * POSL format is used for output, otherwise RuleML (0.88 + rests or 0.91)
     * is used.
     * 
     * @param rmlFormat
     *            RuleMLFormat, to determine which RuleML version to use.
     * 
     * @return The string representation of the clause.
     */
    public String toString(RuleMLFormat version) {
        if (org.ruleml.oojdrew.Config.PRPRINT) {
            return toPOSLString();
        } else {
            return toRuleMLString(version);
        }
    }

    /**
     * Builds and returns a POSL string representation of the clause. This is
     * used by the toString() method if the org.ruleml.oojdrew.Config.PRPRINT
     * variable is true, and can also be called directly by the user code.
     * 
     * @return The POSL representation of the clause stored in a Java String
     *         object.
     */
    public String toPOSLString() {
        String s = "";
        s += atoms[0].toPOSLString(variableNames, true);

        if (atoms.length > 1) {
            s += " :- ";
            for (int i = 1; i < atoms.length; i++) {
                s += atoms[i].toPOSLString(variableNames, false) + ", ";
            }

            s = s.substring(0, s.length() - 2);
        }
        s += ".";

        return s;
    }

    /**
     * Builds and returns a RuleML (0.88 + rests or 0.91) string representation
     * of the object. The output is "pretty printed" with indentation set to 3
     * spaces and new-lines enabled. "\n" is used for newlines, therefore the
     * output may not appear properly on MS Windows based operating systems.
     * 
     * This method is called by the toString() method if
     * org.ruleml.oojdrew.Config.PRPRINT is false, and can be called by user
     * code.
     * 
     * @param rmlFormat
     *            RuleMLFormat, to determine which RuleML version to use.
     * 
     * @return The RuleML representation stored in a Java String object.
     */
    public String toRuleMLString(RuleMLFormat rmlFormat) {
        Element rmlElement = this.toRuleML(rmlFormat);
        return XmlUtils.elementToString(rmlElement);
    }

    /**
     * Builds and returns a RuleML (0.88 + rests or 0.91) representation of the
     * object as a XOM tree. Users can then manipulate this object using regular
     * calls to the XOM library routines.
     * 
     * This method is called by the toRuleMLString() method, and can be called
     * by user code.
     * 
     * @param rmlFormat
     *            RuleMLFormat, to determine which RuleML version to use.
     * 
     * @return The RuleML representation of the clause stored as a XOM tree.
     */
    public Element toRuleML(RuleMLFormat rmlFormat) {
        RuleMLTagNames rmlTagNames = new RuleMLTagNames(rmlFormat);

        Element element;
        if (atoms.length == 1) {
            element = atoms[0].toRuleML(variableNames, true, rmlFormat);
        } else {
            element = new Element(rmlTagNames.IMPLIES);
            if (atoms.length > 2) {
                Element el2 = new Element(rmlTagNames.AND);
                for (int i = 1; i < atoms.length; i++) {

                    el2.appendChild(atoms[i].toRuleML(variableNames, false,
                            rmlFormat));
                }
                element.appendChild(el2);
            } else {
                element.appendChild(atoms[1].toRuleML(variableNames, false,
                        rmlFormat));
            }

            element.appendChild(atoms[0].toRuleML(variableNames, true,
                    rmlFormat));
        }

        return element;
    }

    /**
     * Tests to see if the clause represented by this clause is a fact - this is
     * determined by checking to see if the clause only has one atom (the head).
     * 
     * @return Returns true if the clause represents a fact, otherwise false.
     */
    public boolean isFact() {
        return (atoms.length == 1);
    }
}
  public class LUBGLBStructure{
	
	//all the names of the objects to compute a GLB or LUB on
	private ArrayList<String> terms;
	//need to know if a result variable is used or not
	private boolean resultVarUsed;
	//Name of the result variable if one is sued
	private String resultVarName; 		
	
	/**
	 * Constructor for a LUBGLBStructure
	 * 
	 * @param terms - The different classes to compute a LUB or GLB with
	 * @param resultVarUsed - Whether or not a result variable is used or not in the query
	 * @param resultVarName - Name of the result variable for the query
	 */
	public LUBGLBStructure(ArrayList<String> terms, boolean resultVarUsed,String resultVarName){
	
		this.terms = terms;
		this.resultVarUsed = resultVarUsed;
		this.resultVarName = resultVarName;
	}
	
	/**
	 * Access Method for terms
	 *  
	 * @return ArrayList<String> of classes for the LUB or GLB Query
	 */
	public ArrayList<String> getTerms(){
		return terms;
	}
	
	/**
	 * Access Method Result Variable
	 * 
	 * @return true if a result variable is used false otherwise
	 */
	public boolean getResultVar(){
		return resultVarUsed;
	}
	/**
	 * Access Method for the name of the result variable
	 * 
	 * @return String the name of the result variable
	 */
	public String getResultVarName(){
		return resultVarName;
	}
	
}
 public class QueryTypes {
	
	private Vector typeVector;
	
	public QueryTypes(){
		
		this.typeVector = Types.types;
	}
	
	/**
	 * This method will determine if a class is a subClass of another class during Querying
	 *
	 * This method uses transitive closure and not direct subClass.
	 *
	 * @param String - subClass this is the class that we are going to test if it is a sub class of the super class
	 * @param String - superClass this is the class that is going to be tested if it is a super class of the sub class
	 * @return boolean - true if the subClass is a sub class of the super class, false otherwise
	 */
	public boolean isSubClass(String subClass, String superClass) throws EngineException{
		
		return Types.isSubClass(superClass,subClass);
	}
	
	/**
	 * This method will determine is a class is a super class of another class during Querying
	 *
	 * This method uses transitive closure and not direct super Class.
	 *
	 *@param String - superClass this is the class that is going to be tested if it is a super class of the sub class
	 *@param String - subClass this is the class that is going to be tested if it a sub class of the super class
	 *@return boolean - true if the superClass is a super class of the sub class, false otherwise
	 */
	public boolean isSuperClass(String superClass, String subClass) throws EngineException {
		
		return Types.isSuperClass(superClass,subClass);
	}
	
	
	/**
	 * This method will determine if a class is a subClass of another class during Querying
	 *
	 * This method uses transitive closure and not direct subClass.
	 *
	 * @param String - subClass this is the class that we are going to test if it is a sub class of the super class
	 * @param String - superClass this is the class that is going to be tested if it is a super class of the sub class
	 * @return boolean - true if the subClass is a sub class of the super class, false otherwise
	 */
	public boolean isDirectSubClass(String subClass, String superClass) throws EngineException{
	
		return Types.edgeExist(superClass,subClass);
	}
	
	/**
	 * This method will determine is a class is a super class of another class during Querying
	 *
	 * @param String - superClass this is the class that is going to be tested if it is a super class of the sub class
	 * @param String - subClass this is the class that is going to be tested if it a sub class of the super class
	 * @return boolean - true if the superClass is a super class of the sub class, false otherwise
	 */
	public boolean isDirectSuperClass(String superClass, String subClass) throws EngineException {
		
		return Types.edgeExist(superClass,subClass);
	}

	/**
	 * This method will determine the greaterLowerBound of an Array of classes(Strings)
	 * @param String[] classes - this array contains all the classes that the user wants to test the greater lower bound for
	 * @return String - The class that is the greatest lower bound of the array of given classes
	 */
	public String greatestLowerBound(String[] classes) throws EngineException{
		
		return Types.greatestLowerBound(classes);
	}

	/**
	 * This method will determine the least upper bound of an array of classes
	 * @param String[] classes - this array contains all of the classes that the user wants to test the least upper bound for 
	 * @return String - the class that is the least upper bound of the array of given classes
	 */
	public String leastUpperBound(String[] classes) throws EngineException{
		
		return Types.leastUpperBound(classes);

	}	

	/**
	 * This method will find all the direct sub classes for a given class
	 *  
	 * @param String classString - this String contains the class name that all the sub classes will be found for
	 * @return String[] - all the strings in an array that are subclasses of the given class
	 */	
	public String[] getDirectSubClasses(String superClass){
		
		Iterator typeIt = typeVector.iterator();	
		Vector subClasses = new Vector();
		
		while(typeIt.hasNext()){
			Object b = typeIt.next();
			String compare = b.toString();
			if(Types.edgeExist(superClass,compare)){
					subClasses.addElement(compare);
			}	
		}
		
		int size = subClasses.size();
		
		String[] subClassesStr = new String[size];
		
		Iterator subIt = subClasses.iterator();
		
		int i = 0;
		while(subIt.hasNext()){
			String str = subIt.next().toString();
			subClassesStr[i] = str;
			i++;
		}
	
		return subClassesStr;	
	}
	
	/**
	 * This method will find all the direct super Classes for a given class
	 *  
	 * @param String classString - this String contains the class name that all the sub classes will be found for
	 * @return String[] - all the strings in an array that are subclasses of the given class
	 */	
	public String[] getDirectSuperClasses(String subClass){
		
		Iterator typeIt = typeVector.iterator();	
		Vector superClasses = new Vector();
		
		while(typeIt.hasNext()){
			Object b = typeIt.next();
			String compare = b.toString();
			if(Types.edgeExist(compare,subClass)){
				if(!compare.equals("Thing")){
					superClasses.addElement(compare);
				}
			}	
		}
		
		int size = superClasses.size();
		
		String[] superClassesStr = new String[size];
		
		Iterator subIt = superClasses.iterator();
		
		int i = 0;
		while(subIt.hasNext()){
			String str = subIt.next().toString();
			superClassesStr[i] = str;
			i++;
		}
		
		return superClassesStr;	
	}
	
	/**
	 * This method will find all the subClasses for a given class
	 * 
	 * This method uses transitive closure and not direct subClass.
	 * 
	 * @param String classString - this String contains the class name that all the sub classes will be found for
	 * @return String[] - all the strings in an array that are subclasses of the given class
	 */		
	public String[] findAllSubClasses(String classString) throws EngineException{
	
		Iterator typeIt = typeVector.iterator();	
		Vector subClasses = new Vector();
		
		while(typeIt.hasNext()){
			Object b = typeIt.next();
			String compare = b.toString();
			if(Types.isSubClass(compare,classString)){
				if(!compare.equals("Thing")){
					if(!compare.equals(classString)){
					subClasses.addElement(compare);
					}
				}
			}
		}
		
		int size = subClasses.size();
		
		String[] subClassesStr = new String[size];
		
		Iterator subIt = subClasses.iterator();
		
		int i = 0;
		while(subIt.hasNext()){
			String str = subIt.next().toString();
			subClassesStr[i] = str;
			i++;
		}
		
		return subClassesStr;	
	}

	/**
	 * This method will find all the super classes for a given class
	 * 
	 * This method uses transitive closure and not direct superClass.
	 * 
	 * @param String classString - this String contains the class name that all the super classes will be found for
	 * @return String[] - all the strings in an array that are super classes of the given class
	 */	
	public String[] findAllSuperClasses(String classString) throws EngineException{
		
		Iterator typeIt = typeVector.iterator();	
		Vector superClasses = new Vector();
		
		while(typeIt.hasNext()){
			Object b = typeIt.next();
			String compare = b.toString();
			if(Types.isSuperClass(compare,classString)){
				if(!compare.equals("Thing")){
					if(!compare.equals(classString)){
					superClasses.addElement(compare);
					}
				}
			}
		}
		
		int size = superClasses.size();
		
		String[] superClassesStr = new String[size];
		
		Iterator superIt = superClasses.iterator();
		
		int i = 0;
		while(superIt.hasNext()){
			String str = superIt.next().toString();
			superClassesStr[i] = str;
			i++;
		}
		
		return superClassesStr;	
	}

	/**
	 * This method will find all the super classes relations in the current type system.
	 * 
	 * This method uses transitive closure and not direct superClass.
	 * 
	 * @return Vector - the vector contains a set strings in the order of 
	 * superClass, subClass pairs it should be a 
	 * subsumes Object Vector(may be implemented later)
	 */
	
	public Vector findAllSuperClassesOfEverything() throws EngineException{
		Vector allSup = new Vector();
		Iterator typeIt = typeVector.iterator();
			while(typeIt.hasNext()){
				Object b = typeIt.next();
				
				String classStr = b.toString();
				
					if(!classStr.equals("Thing") &&
						!classStr.equals("Numeric") &&
						!classStr.equals("Integer") &&
						!classStr.equals("Real") &&
						!classStr.equals("String"))	{

						String[] allSupers = this.findAllSuperClasses(classStr);				
								
						for(int i = 0; i < allSupers.length;i++){
							allSup.add(allSupers[i]);
							allSup.add(classStr);
						}
					}	
			}
		
		return allSup;
	}
	
	/**
	 * This method will find all the sub classes relations in the current type system.
	 * 
	 * This method uses transitive closure and not direct sub Class.
	 * 
	 * @return Vector - the vector contains a set strings in the order of 
	 * superClass, subClass pairs it should be a 
	 * subsumes Object Vector(may be implemented later)
	 */
     public Vector findAllSubClassesOfEverything() throws EngineException{
		Vector allSubs = new Vector();
		Iterator typeIt = typeVector.iterator();
			while(typeIt.hasNext()){
				Object b = typeIt.next();
				String classStr = b.toString();
				
				//System.out.println("Class String: " + classStr);
				//System.out.println("All Subs of: " + classStr);
				if(!classStr.equals("Thing") &&
					   !classStr.equals("Numeric") &&
					   !classStr.equals("Integer") &&
					   !classStr.equals("Real") &&
					   !classStr.equals("String")){
						
						String[] allSubClasses = this.findAllSubClasses(classStr);				
										   					
					for(int i = 0; i < allSubClasses.length;i++){
							allSubs.add(classStr);
							allSubs.add(allSubClasses[i]);
					}
				}
			}	
		return allSubs;
	}
		
 	/**
 	 * This method will find all the direct super class relations in the current type system.
     *
 	 * @return Vector - the vector contains a set strings in the order of 
 	 * superClass, subClass pairs it should be a 
 	 * subsumes Object Vector(may be implemented later)
 	 */
	public Vector findAllDirectSuperClassesOfEverything() throws EngineException{
			Vector allSup = new Vector();
			Iterator typeIt = typeVector.iterator();
				while(typeIt.hasNext()){
					Object b = typeIt.next();
					
					String classStr = b.toString();

						if(!classStr.equals("Thing") &&
							!classStr.equals("Numeric") &&
							!classStr.equals("Integer") &&
							!classStr.equals("Real") &&
							!classStr.equals("String"))	{

							String[] allSupers = this.getDirectSuperClasses(classStr);				
									
							for(int i = 0; i < allSupers.length;i++){
								allSup.add(allSupers[i]);
								allSup.add(classStr);
							}
						}	
				}
			
			return allSup;
		}
	
 	/**
 	 * This method will find all the super classes in the current type system.
     *
 	 * @return Vector - the vector contains a set strings in the order of 
 	 * superClass, subClass pairs it should be a 
 	 * subsumes Object Vector(may be implemented later)
 	 */
	public Vector findAllDirectSubClassesOfEverything() throws EngineException{
			Vector allSubs = new Vector();
			Iterator typeIt = typeVector.iterator();
				while(typeIt.hasNext()){
					Object b = typeIt.next();
					String classStr = b.toString();

					if(!classStr.equals("Thing") &&
						   !classStr.equals("Numeric") &&
						   !classStr.equals("Integer") &&
						   !classStr.equals("Real") &&
						   !classStr.equals("String")){
							
							String[] allSubClasses = this.getDirectSubClasses(classStr);				
											   					
						for(int i = 0; i < allSubClasses.length;i++){
								allSubs.add(classStr);
								allSubs.add(allSubClasses[i]);
						}
					}
				}	
			return allSubs;
		}
} public class SubsumesStructure{
	
	private String superName;
	private String subName;
	private boolean superIsVar;
	private boolean subIsVar;
	
	/**
	 * Constructor for a SusbsumesStructure
	 * 
	 * @param superName - name of the super class
	 * @param subName - name of the sub class
	 * @param superIsVar - whether or not the super class is a variable or not
	 * @param subIsVar - whether or not the sub class is a variable or not
	 */
	public SubsumesStructure(String superName, String subName, boolean superIsVar, boolean subIsVar){
		
		this.superName = superName;
		this.subName = subName;
		this.superIsVar = superIsVar;
		this.subIsVar = subIsVar;
	}
	
	/**
	 * Access Method for superName
	 *  
	 * @return name of the super class
	 */
	public String getSuperName(){
		return superName;
	}
	
	/**
	 * Access Method for subName
	 *  
	 * @return name of the sub class
	 */
	public String getSubName(){
		return subName;
	}
	
	/**
	 * Access Method for superIsVar
	 *  
	 * @return true if the super class is a variable false otherwise
	 */
	public boolean getSuperVar(){
		return superIsVar;
	}
	
	/**
	 * Access Method for subIsVar
	 *  
	 * @return true if the sub class is a variable false otherwise
	 */
	public boolean getSubVar(){
		return subIsVar;
	}
}
 public class SymbolTable {

    /**
     * This vector stores all known symbols. The index of the symbol within
     * this vector is the integer code that is used to represent this symbol.
     */
    public static Vector symbols = new Vector();

    /**
     * This vector stores all known roles. The index of the role within this
     * vector is the integer code that is used to represent this role.
     */
    public static Vector roles = new Vector();

    /**
     * This is used to generate new Skolem constants; ensuring uniqueness of
     * all generated constants.
     */
    public static int genid = 100000;

    /**
     * This integer stores the integer code that is used for the system oid
     * role.
     */
    public static final int IOID = internRole("$oid$");

    /**
     * This integer stores the integer code that is used for the role of
     * positional parameters.
     */
    public static final int INOROLE = internRole("");

    /**
     * This integer stores the integer code that is used for the role of
     * positional rest parameters.
     */
    public static final int IPREST = internRole("|");

    /**
     * This integer stores the integer code that is used for the role of
     * slotted rest parameters. This is set equal to Integer.MAX_VALUE to
     * ensure that it will always be the final parameter in the normalized
     * parameter lists.
     */
    public static final int IREST = Integer.MAX_VALUE;

    /**
     * This symbol takes up the first slot in the symbol table - as we ensure
     * that the integer code 0 is never used. This is not else where.
     */
    public static final int INOSYM = internSymbol("");

    /**
     * This integer stores the code for a NAF term.
     */
    public static final int INAF = internSymbol("naf");

    /**
     * This integer stores the code for the "constructor" of a plex term.
     */
    public static final int IPLEX = internSymbol("$PLEX");

    /**
     * This integer stores the code for an assert term.
     */
    public static final int IASSERT = internSymbol("assert");

    /**
     *
     */
    public static final int IINCONSISTENT = internSymbol("$inconsistent");

    /**
     *
     */
    public static final int INEG = internSymbol("neg");

    /**
     * This method is used to reset the symbol table. Data structures that
     * were created previous to this should no longer be used.
     */
    public static void reset() {
        symbols = new Vector();
        roles = new Vector();
        internRole("$oid$");
        internRole("");
        internRole("|");
        internSymbol("");
        internSymbol("naf");
        internSymbol("$PLEX");
        internSymbol("assert");
        internSymbol("$inconsistent");
        internSymbol("neg");
    }

    /**
     * This method is used to initalize a symbol and assign it an integer code
     * if it has not been used before; or retrieve the integer code of a symbol
     * if it already has been encountered.
     *
     * @param sym String A string containing the symbol.
     *
     * @return int The integer code of the symbol.
     */
     
    public static int internSymbol(String sym) {
        if (symbols.contains(sym)) {
            return symbols.indexOf(sym);
        } else {
            int id = symbols.size();
            symbols.add(sym);
            return id;
        }
    }

    /**
     * This method is used to initalize a role and assign it an integer code if
     * it has not been used before; or retrieve the integer code of a role if
     * it already has been encountered.
     *
     * @param role String A string containing the role name.
     *
     * @return int The integer code of the role.
     */
    public static int internRole(String role) {
        if (roles.contains(role)) {
            return roles.indexOf(role);
        } else {
            int id = roles.size();
            roles.add(role);
            return id;
        }
    }

    /**
     * This method gets the string representation of a symbol for the integer
     * code. This is commonly used by output routines.
     *
     * @param idx int The integer code to get the symbol string for.
     *
     * @return String The symbol string.
     */
    public static String symbol(int idx) {
        if (idx < 0 || idx >= symbols.size()) {
            return null;
        } else {
            return (String) symbols.get(idx);
        }
    }

    /**
     * This method gets the string representation of a role for the integer
     * code. This is commonly used by output routines.
     *
     * @param idx int The integer code to get the role string for.
     *
     * @return String The role string.
     */
    public static String role(int idx) {
        if (idx < 0 || idx >= roles.size()) {
            return null;
        } else {
            return (String) roles.get(idx);
        }
    }
}
 public class Term implements Comparable {

    /**
     * This is a regular expression to test against to see if a symbol needs to
     * be quoted when producing POSL format output.
     */
    public static final String regex = "^(-)?[a-zA-Z0-9\\$][a-zA-Z0-9_\\$\\.]*$";

    /**
     * The symbol code to be used for this term, for a variable this is a
     * negative number - and the variable name is stored in the variableNames
     * array of the DefiniteClause object, for a ind this is a positive number
     * and the symbol text is stored in the SymbolTable.
     */

    public int symbol;

    /**
     * The role name code to be used for this term, for a positional argument
     * this is equal to the INOROLE member of the SymbolTable. For slotted
     * arguments the name of the role is stored in the SymbolTable.
     */
    public int role;

    /**
     * The type code to be used for this term, the types for the engine are
     * defined by an RDFS file, and are parsed by the RDFSParser object into the
     * Types system.
     */
    public int type;

    /**
     * The symbol code for the URI for this term; The actual URI is stored in
     * the SymbolTable.
     */
    public int href = -1;

    /**
     * subTerms Term[] An array containing the terms that will be the parameters
     * of this atom, cterm or plex that is being created.
     */
    public Term[] subTerms = null;

    /**
     * This is used to tell if the Term is an atom or not.
     */
    public boolean atom = false;

    /**
     * -1 is assigned as the rest if this is a simple term or a complex term
     * with no slotted rest parameter.
     */
    public int rest = -1;

    /**
     * -1 is assigned as the positional rest if this is a simple term or a
     * complex term with no positional slotted rest parameter.
     */
    public int prest = -1;

    /**
     * Used by the unification process to check what clause a term belongs to
     * when doing unification. This is not used elsewhere.
     */
    int side;

    /**
     * This is used to distinguish between Data and Ind
     */
    private boolean isData = false;

    /**
     * This is used to distinguish between Data and Ind, when using slots
     */
    private boolean dataSlot = false;

    /**
     * Creates a new simple term (variable or ind).
     * 
     * @param symbol
     *            The symbol code to be used for this term, for a variable this
     *            is a negative number - and the variable name is stored in the
     *            variableNames array of the DefiniteClause object, for a ind
     *            this is a positive number and the symbol text is stored in the
     *            SymbolTable.
     * 
     * @param role
     *            The role name code to be used for this term, for a positional
     *            argument this is equal to the INOROLE member of the
     *            SymbolTable. For slotted arguments the name of the role is
     *            stored in the SymbolTable.
     * 
     * @param type
     *            The type code to be used for this term, the types for the
     *            engine are defined by an RDFS file, and are parsed by the
     *            RDFSParser object into the Types system.
     */
    public Term(int symbol, int role, int type) {
        this.symbol = symbol;
        this.role = role;
        this.type = type;
    }

    /**
     * Create a new simple term with a URI reference or label (must be ind)
     * 
     * @param symbol
     *            The symbol code to be used for this term, for a variable this
     *            is a negative number - and the variable name is stored in the
     *            variableNames array of the DefiniteClause object, for a ind
     *            this is a positive number and the symbol text is stored in the
     *            SymbolTable.
     * 
     * @param role
     *            The role name code to be used for this term, for a positional
     *            argument this is equal to the INOROLE member of the
     *            SymbolTable. For a slotted parameter the role name is stored
     *            in the SymbolTable.
     * 
     * @param type
     *            The type code to be used for this term, the types for the
     *            engine are defined by an RDFS file, and are parsed by the
     *            RDFSParser object into the Types system.
     * 
     * @param href
     *            The symbol code for the URI for this term; The actual URI is
     *            stored in the SymbolTable.
     */
    public Term(int symbol, int role, int type, int href) {
        this.symbol = symbol;
        this.role = role;
        this.type = type;
        this.href = href;
    }

    /**
     * Creates a new complex term (atom, expr, plex).
     * 
     * @param symbol
     *            The symbol code to be used for the relation or constructor of
     *            this term, this is always a positive number and the symbol
     *            text is stored in the SymbolTable.
     * 
     * @param role
     *            The role name code to be used for this term, for a positional
     *            argument this is equal to the INOROLE member of the
     *            SymbolTable. For a slotted parameter the role name is stored
     *            in the SymbolTable.
     * 
     * @param type
     *            The type code to be used for this term, the types for the
     *            engine are defined by an RDFS file, and are parsed by the
     *            RDFSParser object into the Types system.
     * 
     * @param subTerms
     *            An array containing the terms that will be the parameters of
     *            this atom, expr or plex that is being created.
     */
    public Term(int symbol, int role, int type, Term[] subTerms) {
        this(symbol, role, type);
        Vector st = this.sort(subTerms);
        this.subTerms = new Term[st.size()];
        for (int i = 0; i < st.size(); i++) {
            this.subTerms[i] = (Term) st.get(i);
            if (this.subTerms[i].getRole() == SymbolTable.IREST) {
                rest = i;
            }
            if (this.subTerms[i].getRole() == SymbolTable.IPREST) {
                prest = i;
            }
        }
    }

    /**
     * Creates a new complex term (atom, expr, plex).
     * 
     * @param symbol
     *            The symbol code to be used for the relation or constructor of
     *            this term, this is always a positive number and the symbol
     *            text is stored in the SymbolTable.
     * 
     * @param role
     *            The role name code to be used for this term, for a positional
     *            argument this is equal to the INOROLE member of the
     *            SymbolTable. For a slotted parameter the role name is stored
     *            in the SymbolTable.
     * 
     * @param type
     *            The type code to be used for this term, the types for the
     *            engine are defined by an RDFS file, and are parsed by the
     *            RDFSParser object into the Types system.
     * 
     * @param subTerms
     *            Vector value An array containing the terms that will be the
     *            parameters of this atom, expr or plex that is being created.
     */
    public Term(int symbol, int role, int type, Vector subTerms) {
        this(symbol, role, type);
        Vector st = this.sort(subTerms);
        this.subTerms = new Term[st.size()];
        for (int i = 0; i < st.size(); i++) {
            this.subTerms[i] = (Term) st.get(i);
            if (this.subTerms[i].getRole() == SymbolTable.IREST) {
                rest = i;
            }
            if (this.subTerms[i].getRole() == SymbolTable.IPREST) {
                prest = i;
            }
        }
    }

    /**
     * A method to get the symbol for a role within a complex term. If the r
     * value is "" this will return the first positional argument. Also if there
     * is more than one value of a role name this will return the first one.
     * 
     * @param r
     *            String A string containing the name of the role to retrieve
     *            the symbol for.
     * 
     * @return A string containing the symbol associated with the passed role.
     *         If this is a variable it will be returned as ?Varx, were x is the
     *         variable id, for for complex term this will contain the
     *         constructor symbol. Values are not enclosed within " even if this
     *         would be required for POSL Syntax.
     * 
     */
    public String getSymbolForRole(String r) {
        int role = SymbolTable.internRole(r);
        for (int i = 0; i < this.subTerms.length; i++) {
            if (subTerms[i].getRole() == role) {
                return subTerms[i].getSymbolString();
            }
        }
        return null;
    }

    /**
     * Gets the symbol code for this term. If it is a complex term this gives
     * the symbol code for the predicate/constructor. If this value is a
     * negative number then this term is a variable.
     * 
     * @return The symbol code for this term.
     */
    public int getSymbol() {
        return symbol;
    }

    /**
     * Sets the symbol code for this term.
     * 
     * @param symbol
     *            The value to set symbol to.
     */
    public void setSymbol(int symbol) {
        this.symbol = symbol;
    }

    /**
     * Gets the symbol for this term. If it is a complex term this gives the
     * symbol for the predicate/constructor. If it is a variable then the symbol
     * is prefixed with a ?.
     * 
     * @return The symbol for this term.
     */
    public String getSymbolString() {
        if (symbol > 0) {
            return SymbolTable.symbol(symbol);
        } else {
            return "?Var" + (-(symbol + 1));
        }
    }

    /**
     * Gets the role name code for this term. If this is a rest paramater it
     * will be equal to the IREST member of the associated SymbolTable. If this
     * is a positional argument it will be equal to the INOROLE member of the
     * associated SymbolTable.
     * 
     * @return The role code for this term.
     */
    public int getRole() {
        return role;
    }

    /**
     * Sets the role code for this term.
     * 
     * @param role
     *            The value to set role to.
     */
    public void setRole(int role) {
        this.role = role;
    }

    /**
     * Gets the role name for this term. If this is a positional argument this
     * will be an empty string, for a rest parameter it will be '$REST',
     * otherwise it is the name of the role.
     * 
     * @return The role name for this term.
     */
    public String getRoleString() {
        return SymbolTable.role(role);
    }

    /**
     * Gets the type code for this term. For an untyped term this will be equal
     * to the IOBJECT member of the TypeHierarchy associated with the clause.
     * 
     * @return The type code for this term.
     */
    public int getType() {
        return type;
    }

    /**
     * Sets the type code for this term.
     * 
     * @param type
     *            The value to set type to.
     */
    public void setType(int type) {
        this.type = type;
    }

    /**
     * Gets the value of the side member variable - this is used by the
     * unification process to keep track of terms.
     * 
     * @return The current value of the side member.
     */
    public int getSide() {
        return side;
    }

    /**
     * Sets the value of the side member variable.
     * 
     * @param side
     *            The value to set side to.
     */
    public void setSide(int side) {
        this.side = side;
    }

    /**
     * Gets the index of the slotted rest parameter.
     * 
     * @return The index of the slotted rest parameter within this term, or -1
     *         if this is a simple term or a complex term with no slotted rest
     *         parameter.
     */
    public int getRest() {
        return rest;
    }

    /**
     * Gets the index of the positional rest parameter.
     * 
     * @return The index of the position rest parameter within this term, or -1
     *         if this is a simple term or a complex term with no positional
     *         rest parameter.
     */
    public int getPosRest() {
        return prest;
    }

    /**
     * Gets an array of the arguments for this term.
     * 
     * @return A Term[] array of the parameters for this term. Returns null if
     *         this is a simple term (variable or ind).
     */
    public Term[] getSubTerms() {
        return subTerms;
    }

    /**
     * Tests if a term is a complex term.
     * 
     * @return True if this term is a complex term (atom, expr, tup) false
     *         otherwise.
     */
    public boolean isExpr() {
        return (subTerms != null);
    }

    /**
     * Test if this term is an atom.
     * 
     * @return boolean value - true if this term is an atom, false otherwise.
     *         This is used only by the output routines, for other things Expr
     *         and Atoms can be treated the same.
     */
    public boolean isAtom() {
        return (subTerms != null && atom);
    }

    /**
     * Sets the boolean atom flag to the passed value, if the atom member
     * variable is set to true and it is not a complex term (subTerms array is
     * set to null) isAtom() will still return false.
     * 
     * @param atom
     *            The value that the atom member should be set to.
     */
    public void setAtom(boolean atom) {
        this.atom = atom;
    }

    /**
     * Sets the isData flag to the passed value, if isData variable is set to
     * true then it is a data element if not it is a Ind
     * 
     * @param data
     *            The value that the isData member should be set to.
     */
    public void setData(boolean data) {
        isData = data;
    }

    /**
     * Gets the isData vaule
     * 
     * @return The value of the isData member
     */
    public boolean getData() {
        return isData;
    }

    /**
     * Sets the isDataSlot flag to the passed value, if isDataSlot variable is
     * set to true then it is a data element if not it is a Ind inside the slot.
     * 
     * @param data
     *            The value that the isDataSlot member should be set to.
     */
    public void setDataSlot(boolean data) {
        dataSlot = data;
    }

    /**
     * Gets the isDataSlot value
     * 
     * @return The value that the isDataSlot member
     */
    public boolean getDataSlot() {
        return dataSlot;
    }

    /**
     * Returns a string representation of this term. The format of this string
     * is determined by the value of the PRPRINT static variable in the
     * org.ruleml.oojdrew.Config class. If this is true, this will produce a
     * string in POSL syntax, otherwise it will produce a string in OO RuleML
     * XML syntax.
     * 
     * This method is used when you do not have access to the variable names;
     * variables are output as ?Varx - where x is the variable id.
     * 
     * @param rmlFormat
     *            RuleMLFormat, to determine which RuleML version to use.
     * 
     * @return The String representation of this term.
     */
    public String toString(RuleMLFormat rmlFormat) {
        if (Config.PRPRINT) {
            return this.toPOSLString(true);
        } else {

            return this.toRuleMLString(rmlFormat);
        }
    }

    /**
     * Returns a string representation of this term. The format of this string
     * is determined by the value of the PRPRINT static variable in the
     * org.ruleml.oojdrew.Config class. If this is true, this will produce a
     * string in POSL syntax, otherwise it will produce a string in OO RuleML
     * XML syntax.
     * 
     * @param rmlFormat
     *            RuleMLFormat, to determine which RuleML version to use.
     * 
     * @param varNames
     *            String array containing the variable names
     * 
     * @return The String representation of this term.
     */
    public String toString(String[] varNames, RuleMLFormat rmlFormat) {
        if (Config.PRPRINT) {
            return this.toPOSLString(varNames, true);
        } else {

            return this.toRuleMLString(varNames, rmlFormat);

        }
    }

    /**
     * Returns a string representation of this term in POSL syntax. This method
     * is used in cases where you do not have access to the variable names
     * associated with the clause - variable names will be output as ?Varx where
     * x is the variable id.
     * 
     * @return The POSL syntax representation of this term.
     */

    public String toPOSLString(boolean head) {
        String s = "";

        if (this.role != SymbolTable.INOROLE && this.role != SymbolTable.IREST
                && this.role != SymbolTable.IPREST) {
            String rs = SymbolTable.role(this.role);
            if (!rs.matches(regex)) {
                rs = "\"" + rs + "\"";
            }
            s += rs + "->";
        }

        if (this.symbol < 0) {
            s += "?Var" + (-(symbol + 1));
        } else {
            if (this.symbol != SymbolTable.INAF
                    && this.symbol != SymbolTable.IPLEX
                    && this.symbol != SymbolTable.IASSERT) {
                String sym = SymbolTable.symbol(this.symbol);

                if (sym.startsWith("$gensym")
                        && !org.ruleml.oojdrew.Config.PRINTGENSYMS) {
                    int idx = sym.indexOf("$", 7);
                    if (idx > -1) {
                        String skoname = sym.substring(idx + 1);
                        if (!sym.matches(regex)) {
                            skoname = "\"" + skoname + "\"";
                        }
                        sym = "_" + skoname;
                    } else
                        sym = "_";
                } else if (!sym.matches(regex)) {
                    sym = "\"" + sym + "\"";
                }
                s += sym;
            }
        }

        if (this.isAtom() && this.symbol == SymbolTable.INAF) {
            s += "naf(";
            for (int i = 0; i < this.subTerms.length; i++) {
                s += this.subTerms[i].toPOSLString(head);
                if ((i + 1) < this.subTerms.length) {
                    s += ",";
                }
            }
            s += ")";
        } else if (this.isAtom() && this.symbol == SymbolTable.IASSERT) {
            s += "assert( ";
            s += this.subTerms[0].toPOSLString(true);
            if (this.subTerms.length > 1) {
                s += " :- ";
                for (int i = 1; i < this.subTerms.length; i++) {
                    s += this.subTerms[i].toPOSLString(false);
                    if (i + 1 < this.subTerms.length) {
                        s += ", ";
                    }
                }
            }
            s += ". )";
        } else if (this.isExpr()) {
            String sb;
            String eb;
            if (this.isAtom()) {
                sb = "(";
                eb = ")";
            } else {
                sb = "[";
                eb = "]";
            }

            s += sb;
            for (int i = 0; i < this.subTerms.length; i++) {
                if (this.subTerms[i].role == SymbolTable.IREST) {
                    s += " !"; // handle printout if term is a slotted rest term
                } else if (this.subTerms[i].role == SymbolTable.IPREST) {
                    s += " |"; // handle printout if term is a positional rest
                               // term
                }

                if (this.subTerms[i].role == SymbolTable.IOID
                        && !org.ruleml.oojdrew.Config.PRINTGENOIDS && head) {
                    if (this.subTerms[i].getSymbolString()
                            .startsWith("$gensym"))
                        continue;
                }
                // get rid of blank oid here
                s += this.subTerms[i].toPOSLString(head);
                if (this.subTerms[i].role == SymbolTable.IOID) {
                    s += "^ ";
                }

                if ((i + 1) < this.subTerms.length) {

                    if (this.subTerms[i].role != SymbolTable.IOID
                            && this.subTerms[i + 1].role == SymbolTable.INOROLE) {
                        s += ", ";
                    } else if (this.subTerms[i + 1].role == SymbolTable.IREST) {
                    } else if (this.subTerms[i + 1].role == SymbolTable.IPREST) {
                    } else if (this.subTerms[i].role != SymbolTable.IOID) {
                        s += "; ";
                    }
                }
            }
            s += eb;
        }

        if (this.type != Types.IOBJECT) {
            String ts = Types.typeName(this.type);
            if (!ts.matches(regex)) {
                ts = "\"" + ts + "\"";
            }
            s += " : " + ts;
        }
        return s;
    }

    /**
     * Returns a string representation of this term in POSL syntax.
     * 
     * @param varNames
     *            A string array containing the variable names to use when
     *            outputting the string. These are stored in the DefiniteClause
     *            that the term is part of.
     * 
     * @return The POSL syntax representation of the term.
     */
    public String toPOSLString(String[] varNames) {
        return toPOSLString(varNames, false, true);
    }

    public String toPOSLString(String[] varNames, boolean head) {
        return toPOSLString(varNames, false, head);
    }

    /**
     * Returns a string representation of this term in POSL syntax, with the
     * option of omitting the role name. This is used by the mechanism for
     * saving variable bindings.
     * 
     * @param varNames
     *            A string array containing the variable names to use when
     *            outputting the string. These are stored in the DefiniteClause
     *            that the term is part of.
     * 
     * @param skiprole
     *            If true then the role name is omitted from the string output,
     *            otherwise the role name is included.
     * 
     * @param head
     *            If true then the atom is the head of a rule.
     * 
     * @return String The POSL syntax representation of the term.
     */
    public String toPOSLString(String[] varNames, boolean skiprole, boolean head) {
        String s = "";

        if (!skiprole) {
            if (this.role != SymbolTable.INOROLE
                    && this.role != SymbolTable.IREST
                    && this.role != SymbolTable.IPREST
                    && this.role != SymbolTable.IOID) {
                String rs = SymbolTable.role(this.role);
                if (!rs.matches(regex)) {
                    rs = "\"" + rs + "\"";
                }
                s += rs + "->";
            }
        }

        if (this.symbol < 0) {
            if (varNames[-(symbol + 1)].startsWith("$ANON")
                    && !org.ruleml.oojdrew.Config.PRINTANONVARNAMES) {
                s += "?";
            } else {
                s += "?" + varNames[-(symbol + 1)];
                if (org.ruleml.oojdrew.Config.PRINTVARID) {
                    s += "_" + (-(symbol + 1));
                }
            }
        } else {
            if (this.symbol != SymbolTable.INAF
                    && this.symbol != SymbolTable.IPLEX
                    && this.symbol != SymbolTable.IASSERT) {
                String sym = SymbolTable.symbol(this.symbol);

                if (sym.startsWith("$gensym")
                        && !org.ruleml.oojdrew.Config.PRINTGENSYMS) {
                    int idx = sym.indexOf("$", 7);
                    if (idx > -1) {
                        String skoname = sym.substring(idx + 1);
                        if (!sym.matches(regex)) {
                            skoname = "\"" + skoname + "\"";
                        }
                        sym = "_" + skoname;
                    } else
                        sym = "_";
                } else if (!sym.matches(regex)) {
                    sym = "\"" + sym + "\"";
                }

                s += sym;
            }
        }

        if (this.isAtom() && this.symbol == SymbolTable.INAF) {
            s += "naf( ";
            for (int i = 0; i < this.subTerms.length; i++) {
                s += this.subTerms[i].toPOSLString(varNames, head);
                if ((i + 1) < this.subTerms.length) {
                    s += ",";
                }
            }
            s += " )";
        } else if (this.isAtom() && this.symbol == SymbolTable.IASSERT) {
            s += "assert( ";
            s += this.subTerms[0].toPOSLString(varNames, true);
            if (this.subTerms.length > 1) {
                s += " :- ";
                for (int i = 1; i < this.subTerms.length; i++) {
                    s += this.subTerms[i].toPOSLString(varNames, false);
                    if (i + 1 < this.subTerms.length) {
                        s += ", ";
                    }
                }
            }
            s += ". )";
        } else if (this.isExpr()) {
            String sb;
            String eb;
            if (this.isAtom()) {
                sb = "(";
                eb = ")";
            } else {
                sb = "[";
                eb = "]";
            }

            s += sb;
            for (int i = 0; i < this.subTerms.length; i++) {
                if (this.subTerms[i].role == SymbolTable.IREST) {
                    s += "!"; // handle printout if first term is a slotted rest
                              // term
                } else if (this.subTerms[i].role == SymbolTable.IPREST) {
                    s += "|"; // handle printout if first term is a positional
                              // rest term
                }

                if (this.subTerms[i].role == SymbolTable.IOID
                        && !org.ruleml.oojdrew.Config.PRINTGENOIDS) {
                    if (this.subTerms[i].symbol > 0
                            && this.subTerms[i].getSymbolString().startsWith(
                                    "$gensym") && head)
                        continue;
                    if (this.subTerms[i].symbol < 0
                            && varNames[-(this.subTerms[i].symbol + 1)]
                                    .startsWith("$ANON") && !head)
                        continue;
                }

                s += this.subTerms[i].toPOSLString(varNames, head);
                if (this.subTerms[i].role == SymbolTable.IOID) {
                    s += "^ ";
                }

                if ((i + 1) < this.subTerms.length) {
                    if (this.subTerms[i].role != SymbolTable.IOID
                            && this.subTerms[i + 1].role == SymbolTable.INOROLE) {
                        s += ", ";
                    } else if (this.subTerms[i + 1].role == SymbolTable.IREST) {
                    } else if (this.subTerms[i + 1].role == SymbolTable.IPREST) {
                    } else if (this.subTerms[i].role != SymbolTable.IOID) {
                        s += "; ";
                    }
                }
            }
            s += eb;
        }

        if (this.type != Types.IOBJECT) {
            String ts = Types.typeName(this.type);
            if (!ts.matches(regex)) {
                ts = "\"" + ts + "\"";
            }
            s += " : " + ts;
        }
        return s;
    }

    // String solution to print instantiated facts
    public String toPOSLStringAll(String[] varNames, boolean skiprole,
            boolean head) {

        String s = "";

        if (!skiprole) {
            if (this.role != SymbolTable.INOROLE
                    && this.role != SymbolTable.IREST
                    && this.role != SymbolTable.IPREST
                    && this.role != SymbolTable.IOID) {
                String rs = SymbolTable.role(this.role);
                if (!rs.matches(regex)) {
                    rs = "\"" + rs + "\"";
                }
                s += rs + "->";
            }
        }

        if (this.symbol < 0) {
            if (varNames[-(symbol + 1)].startsWith("$ANON")
                    && !org.ruleml.oojdrew.Config.PRINTANONVARNAMES) {
                s += "?";
            } else {
                s += "?" + varNames[-(symbol + 1)];
                if (org.ruleml.oojdrew.Config.PRINTVARID) {
                    s += "" + (-(symbol + 1));
                }
            }
        } else {
            if (this.symbol != SymbolTable.INAF
                    && this.symbol != SymbolTable.IPLEX
                    && this.symbol != SymbolTable.IASSERT) {
                String sym = SymbolTable.symbol(this.symbol);

                if (sym.startsWith("$gensym")
                        && !org.ruleml.oojdrew.Config.PRINTGENSYMS) {
                    int idx = sym.indexOf("$", 7);
                    if (idx > -1) {
                        String skoname = sym.substring(idx + 1);
                        if (!sym.matches(regex)) {
                            skoname = "\"" + skoname + "\"";
                        }
                        sym = "" + skoname;
                    } else
                        sym = "";
                } else if (!sym.matches(regex)) {
                    sym = "\"" + sym + "\"";
                }

                s += sym;
            }
        }

        if (this.isAtom() && this.symbol == SymbolTable.INAF) {
            s += "naf( ";
            for (int i = 0; i < this.subTerms.length; i++) {
                s += this.subTerms[i].toPOSLString(varNames, head);
                if ((i + 1) < this.subTerms.length) {
                    s += ",";
                }
            }
            s += " )";
        } else if (this.isAtom() && this.symbol == SymbolTable.IASSERT) {
            s += "assert( ";
            s += this.subTerms[0].toPOSLString(varNames, true);
            if (this.subTerms.length > 1) {
                s += " :- ";
                for (int i = 1; i < this.subTerms.length; i++) {
                    s += this.subTerms[i].toPOSLString(varNames, false);
                    if (i + 1 < this.subTerms.length) {
                        s += ", ";
                    }
                }
            }
            s += ". )";
        } else if (this.isExpr()) {
            String sb;
            String eb;
            if (this.isAtom()) {
                sb = "(";
                eb = ")";
            } else {
                sb = "[";
                eb = "]";
            }

            s += sb;
            for (int i = 0; i < this.subTerms.length; i++) {
                if (this.subTerms[i].role == SymbolTable.IREST) {
                    s += "!"; // handle printout if first term is a slotted rest
                              // term
                } else if (this.subTerms[i].role == SymbolTable.IPREST) {
                    s += "|"; // handle printout if first term is a positional
                              // rest term
                }

                if (this.subTerms[i].role == SymbolTable.IOID
                        && !org.ruleml.oojdrew.Config.PRINTGENOIDS) {
                    if (this.subTerms[i].symbol > 0
                            && this.subTerms[i].getSymbolString().startsWith(
                                    "$gensym") && head)
                        continue;
                    if (this.subTerms[i].symbol < 0
                            && varNames[-(this.subTerms[i].symbol + 1)]
                                    .startsWith("$ANON") && !head)
                        continue;
                }

                // get rid of blank oid here

                String s2 = "";

                s2 = this.subTerms[i].toPOSLString(varNames, head);

                if (s2.compareTo("_") != 0) {

                    s += s2;
                }

                if (this.subTerms[i].role == SymbolTable.IOID) {
                    // s += "^ ";
                }

                if ((i + 1) < this.subTerms.length) {
                    if (this.subTerms[i].role != SymbolTable.IOID
                            && this.subTerms[i + 1].role == SymbolTable.INOROLE) {
                        s += ", ";
                    } else if (this.subTerms[i + 1].role == SymbolTable.IREST) {
                    } else if (this.subTerms[i + 1].role == SymbolTable.IPREST) {
                    } else if (this.subTerms[i].role != SymbolTable.IOID) {
                        s += "; ";
                    }
                }
            }
            s += eb;
        }

        if (this.type != Types.IOBJECT) {
            String ts = Types.typeName(this.type);
            if (!ts.matches(regex)) {
                ts = "\"" + ts + "\"";
            }
            s += " : " + ts;
        }
        return s;
    }

    /**
     * Produces an OO RuleML XML syntax representation of this term, stored in a
     * string.
     * 
     * This version is for the case where you do not have access to the variable
     * names for the term.
     * 
     * @param rmlFormat
     *            RuleMLFormat, to determine which RuleML version to use.
     * 
     * @return The OO RuleML syntax representation of this, stored as a
     *         "pretty printed" string.
     */
    public String toRuleMLString(RuleMLFormat rmlFormat) {

        Element rml = this.toRuleML(true, rmlFormat);
        ByteArrayOutputStream os = new ByteArrayOutputStream();
        nu.xom.Serializer sl = new nu.xom.Serializer(os);
        sl.setIndent(3);
        sl.setLineSeparator("\n");
        try {
            Document doc = new Document(rml);
            sl.write(doc);
        } catch (java.io.IOException e) {
            System.err.println(e.getMessage());
        }
        return os.toString();
    }

    /**
     * Produces an OO RuleML XML syntax representation of this term, stored in a
     * string.
     * 
     * @param varNames
     *            A string array containing the variable names to use when
     *            outputting - these are stored in the DefiniteClause object
     *            associated with the term.
     * 
     * @param rmlFormat
     *            RuleMLFormat, to determine which RuleML version to use.
     * 
     * @return A string containing the OO RuleML XML representation of this
     *         term.
     */
    public String toRuleMLString(String[] varNames, RuleMLFormat version) {

        Element rml = this.toRuleML(varNames, true, version);
        ByteArrayOutputStream os = new ByteArrayOutputStream();
        nu.xom.Serializer sl = new nu.xom.Serializer(os);
        sl.setIndent(3);
        sl.setLineSeparator("\n");
        try {
            Document doc = new Document(rml);
            sl.write(doc);
        } catch (java.io.IOException e) {
            System.err.println(e.getMessage());
        }
        return os.toString();
    }

    /**
     * Produces an OO RuleML XML syntax representation of this term, stored in a
     * nu.xom.Element object.
     * 
     * This version is for when you do not have access to the variable names.
     * 
     * @see toRuleML(String[] varNames, boolean head, RuleMLFormat rmlFormat)
     */
    public Element toRuleML(boolean head, RuleMLFormat rmlFormat) {
        return toRuleML(null, head, rmlFormat);
    }

    /**
     * Produces an OO RuleML XML syntax representation of this term, stored in a
     * nu.xom.Element object.
     * 
     * @param varNames
     *            The variable names associated with the term; these are stored
     *            in the DefiniteClause object associated with the term.
     * 
     * @param rmlFormat
     *            RuleMLFormat, to determine which RuleML version to use.
     * 
     * @return The OO RuleML syntax representation of this, as an Element value.
     */
    public Element toRuleML(String[] varNames, boolean head, RuleMLFormat rmlFormat) {

        RuleMLTagNames rmlTagNames = new RuleMLTagNames(rmlFormat);

        // Printing the Clauses in RuleML Format
        Element el = null;
        boolean dst = false;
        if (this.isExpr()) {
            if (this.isAtom() && this.symbol == SymbolTable.INAF) {
                el = new Element(rmlTagNames.NAF);
            } else if (this.isAtom() && this.symbol == SymbolTable.IASSERT) {
                el = new Element(rmlTagNames.ASSERT);
                if (this.subTerms.length == 1) {
                    el.insertChild(subTerms[0].toRuleML(varNames, true, rmlFormat), 0);
                } else {
                    Element implies = new Element(rmlTagNames.IMPLIES);
                    if (this.subTerms.length > 2) {
                        Element and = new Element(rmlTagNames.AND);
                        for (int i = 1; i < this.subTerms.length; i++) {
                            and.appendChild(this.subTerms[i].toRuleML(varNames, false, rmlFormat));
                        }
                        implies.appendChild(and);
                    } else {
                        implies.appendChild(this.subTerms[1].toRuleML(varNames, false, rmlFormat));
                    }
                    implies.appendChild(this.subTerms[0].toRuleML(varNames, true, rmlFormat));
                    el.appendChild(implies);
                }
                dst = true;
            } else if (this.isAtom()) {
                el = new Element(rmlTagNames.ATOM);

                Element rel = new Element(rmlTagNames.REL);
                el.insertChild(rel, el.getChildCount());
                rel.insertChild(SymbolTable.symbol(this.symbol), 0);
            } else if (this.symbol == SymbolTable.IPLEX) {
                el = new Element(rmlTagNames.PLEX);
            } else {
                el = new Element(rmlTagNames.EXPR);

                Element fun = new Element(rmlTagNames.FUN);
                el.insertChild(fun, el.getChildCount());
                fun.insertChild(SymbolTable.symbol(this.symbol), 0);
            }

            Element subElement;
            for (int i = 0; i < this.subTerms.length && !dst; i++) {
                subElement = this.subTerms[i].toRuleML(varNames, head, rmlFormat);
                if (subElement != null) {
                    el.insertChild(subElement, el.getChildCount());
                }
            }
        } else {
            if (this.role == SymbolTable.IOID
                    && !org.ruleml.oojdrew.Config.PRINTGENOIDS) {
                if (this.symbol > 0
                        && this.getSymbolString().startsWith("$gensym") && head)
                    return null;
                else if (varNames != null && this.symbol < 0
                        && varNames[-(this.symbol + 1)].startsWith("$ANON")
                        && !head)
                    return null;
            }

            if (this.symbol < 0) {
                el = new Element(rmlTagNames.VAR);
                if (varNames != null
                        && (!varNames[-(symbol + 1)].startsWith("$ANON") || org.ruleml.oojdrew.Config.PRINTANONVARNAMES)) {
                    String varName = varNames[-(symbol + 1)];
                    if (org.ruleml.oojdrew.Config.PRINTVARID) {
                        varName += -(symbol + 1);
                    }
                    el.insertChild(varName, 0);
                } else {
                    el.insertChild(rmlTagNames.VAR + (-(symbol + 1)), 0);
                }
            } else {
                String sym = SymbolTable.symbol(this.symbol);
                if (sym.startsWith("$gensym")
                        && !org.ruleml.oojdrew.Config.PRINTGENSYMS) {
                    el = new Element(rmlTagNames.SKOLEM);
                    int idx = sym.indexOf("$", 7);
                    if (idx > -1) {
                        String skoname = sym.substring(idx + 1);
                        el.appendChild(skoname);
                    }
                } else {
                    if (isData) {
                        el = new Element(rmlTagNames.DATA);
                        el.insertChild(sym, 0);
                    }

                    if (!isData) {
                        el = new Element(rmlTagNames.IND);
                        el.insertChild(sym, 0);
                    }
                }
            }
        }

        if (this.type != Types.IOBJECT) {
            Attribute typeAttribute = new Attribute(rmlTagNames.TYPE, Types.typeName(type));
            el.addAttribute(typeAttribute);
        }

        if (this.role == SymbolTable.IREST) {
            Element resl = new Element(rmlTagNames.RESL);
            resl.insertChild(el, 0);
            return resl;
        } else if (this.role == SymbolTable.IPREST) {
            Element repo = new Element(rmlTagNames.REPO);
            repo.insertChild(el, 0);
            return repo;
        } else if (this.role == SymbolTable.IOID) {
            Element oid = new Element(rmlTagNames.OID);
            oid.insertChild(el, 0);
            return oid;
        } else if (this.role == SymbolTable.INOROLE) {
            return el;
        } else {
            Element slot = new Element(rmlTagNames.SLOT);
            Element child = null;

            // If isData is true then change it here
            if (dataSlot) {
                child = new Element(rmlTagNames.DATA);
            } else {
                child = new Element(rmlTagNames.IND);
            }
            child.appendChild(SymbolTable.role(this.role));

            slot.appendChild(child);
            slot.appendChild(el);
            return slot;
        }
    }

    /**
     * Make an identical deep (recursive) copy of this term. This is used when
     * unifying to avoid making changes to the original data structures that
     * represent clauses.
     * 
     * @return A full copy of this term.
     */
    public Term deepCopy() {
        // False indicates not to change the original side values
        return deepCopy(0, false);
    }

    /**
     * Produces a deep (recursive) copy of this term, with the side member set
     * to the specified value. This is used when Unifying to avoid making
     * changes to the original data structures that represent clauses.
     * 
     * @param pside
     *            The side value that should be stored in the copy.
     * 
     * @return A full copy of this term.
     */
    public Term deepCopy(int pside) {
        // True indicates to change the original side values to pside
        return deepCopy(pside, true);
    }

    /**
     * @see deepCopy()
     * @see deepCopy(int pside)
     */
    private Term deepCopy(int newSideValue, boolean useNewSide) {
        Term term;
        if (this.subTerms != null) {
            Term[] sterms = new Term[this.subTerms.length];
            for (int i = 0; i < this.subTerms.length; i++) {
                sterms[i] = this.subTerms[i].deepCopy(newSideValue, useNewSide);
            }
            term = new Term(this.symbol, this.role, this.type, sterms);
            term.atom = this.atom;
        } else {
            term = new Term(this.symbol, this.role, this.type);
        }

        term.side = useNewSide ? newSideValue : this.side;

        if (isData) {
            term.setData(true);
        }
        return term;
    }

    /**
     * Sorts a Vector of term objects by the role code.
     * 
     * @param toSort
     *            A Vector containing only Term objects - to be sorted by the
     *            role name code.
     * 
     * @return Vector A Vector containing the sorted terms.
     */
    public static Vector sort(Vector toSort) {
        Vector sorted = new Vector();

        for (int i = 0; i < toSort.size(); i++) {
            Term c = (Term) toSort.get(i);

            int j = 0;
            while (j < sorted.size()) {
                Term chk = (Term) sorted.get(j);
                if (c.getRole() >= chk.getRole()) {
                    j++;
                } else {
                    break;
                }
            }
            sorted.add(j, c);
        }
        return sorted;
    }

    /**
     * Sorts an array of org.ruleml.oojdrew.util.Term values by the role code.
     * 
     * @param toSort
     *            An array of Term objects to be sorted by the role name code.
     * 
     * @return A Vector containing the sorted terms.
     */
    public static Vector sort(Term[] toSort) {
        Vector ts = new Vector();
        for (int i = 0; i < toSort.length; i++) {
            ts.add(toSort[i]);
        }
        return sort(ts);
    }

    /**
     * Compares one term to another object. If this object is a Term object, it
     * will compare first by the symbol code, then the role name code, the
     * number of parameters, and finally by the actual parameters themselves. If
     * the other object is not a Term, then this always returns 1.
     * 
     * @param toCompare
     *            The object to compare this term to.
     * 
     * @return The result of the comparison 1 if the other term is "less than",
     *         0 if they are equal, or -1 if the other term is "greater than".
     */
    public int compareTo(Object toCompare) {
        if (this.getClass() != toCompare.getClass()) {
            return 1;
        }

        Term o = (Term) toCompare;
        if (this.symbol < o.symbol) {
            return 1;
        } else if (this.symbol > o.symbol) {
            return -1;
        } else {
            if (this.role < o.role) {
                return 1;
            } else if (this.role > o.role) {
                return -1;
            } else {
                if (this.subTerms == null) {
                    return 0;
                }
                if (this.subTerms.length < o.subTerms.length) {
                    return 1;
                } else if (this.subTerms.length > o.subTerms.length) {
                    return -1;
                } else {
                    for (int i = 0; i < this.subTerms.length; i++) {
                        int cmp = this.subTerms[i].compareTo(o.subTerms[i]);
                        if (cmp != 0) {
                            return cmp;
                        }
                    }
                    return 0;
                }
            }
        }
    }
}

import java.awt.EventQueue;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.Vector;
import javax.swing.JOptionPane;
import javax.swing.UIManager;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;
import nu.xom.Elements;
import org.apache.log4j.BasicConfigurator;
import org.apache.log4j.Logger;
import org.ruleml.oojdrew.Config;
import org.ruleml.oojdrew.Configuration;
import org.ruleml.oojdrew.SyntaxFormat;
import org.ruleml.oojdrew.GUI.AbstractUIApp;
import org.ruleml.oojdrew.GUI.DebugConsole;
import org.ruleml.oojdrew.GUI.PreferenceDialogUI;
import org.ruleml.oojdrew.GUI.PreferenceManager;
import org.ruleml.oojdrew.GUI.TopDownUI;
import org.ruleml.oojdrew.parsing.POSLParser;
import org.ruleml.oojdrew.parsing.RDFSParser;
import org.ruleml.oojdrew.parsing.RuleMLParser;
import org.ruleml.oojdrew.parsing.SubsumesParser;
import org.ruleml.oojdrew.parsing.TypeQueryParserPOSL;
import org.ruleml.oojdrew.parsing.TypeQueryParserRuleML;
import org.ruleml.oojdrew.util.DefiniteClause;
import org.ruleml.oojdrew.util.LUBGLBStructure;
import org.ruleml.oojdrew.util.QueryTypes;
import org.ruleml.oojdrew.util.SubsumesStructure;
import org.ruleml.oojdrew.util.SymbolTable;
import org.ruleml.oojdrew.util.Term;

// OO jDREW - An Object Oriented extension of the Java Deductive Reasoning Engine for the Web
// Copyright (C) 2008 Ben Craig
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA

package org.ruleml.oojdrew.TopDown;





public class TopDownApp extends AbstractUIApp {

    // TODO: Rewrite all code that uses the following variables
    // These variables were copied from the old UI
    private Iterator queryResultIterator;
    private Iterator typeQueryResultIterator;
    private boolean t1Var;
    private boolean t2Var;
    private String term1VarName;
    private String term2VarName;
    private SubsumesStructure subPlus;
    private SubsumesStructure sub;
    private LUBGLBStructure lub;
    private LUBGLBStructure glb;

    public static void main(String[] args) {
        // The look and feel must be set before any UI objects are constructed
        try {
            UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
        } catch (Exception e) {
            e.printStackTrace();
        }

        // Create a TopDownApp using the factory method...
        TopDownApp app = TopDownApp.getTopDownApp();

        // ... and start it's event loop
        app.run();
    }

    public void run() {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                logger.debug("Entering event loop");
                getUI().setFrameVisible(true);
            }
        });
    }

    public static TopDownApp getTopDownApp() {
        // Construct dependencies
        Configuration config = new Config(TopDownApp.class);
        PreferenceManager preferenceManager = new PreferenceManager(config);
        TopDownUI topDownUI = new TopDownUI();
        PreferenceDialogUI preferenceDialogUI = new PreferenceDialogUI();

        // Create DebugConsole and logger
        DebugConsole debugConsole = new DebugConsole();

        BasicConfigurator.configure();
        Logger logger = Logger.getRootLogger();

        // Create the parsers
        RDFSParser rdfsParser = new RDFSParser();
        POSLParser poslParser = new POSLParser();
        RuleMLParser rmlParser = new RuleMLParser(config);

        SubsumesParser subsumesParser = new SubsumesParser();
