// OO jDREW - An Object Oriented extension of the Java Deductive Reasoning Engine for the Web // Copyright (C) 2011 // // 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.BottomUp; import java.awt.EventQueue; 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 nu.xom.Attribute; import nu.xom.Element; 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.BottomUpUI; import org.ruleml.oojdrew.GUI.DebugConsole; import org.ruleml.oojdrew.GUI.PreferenceDialogUI; import org.ruleml.oojdrew.GUI.PreferenceManager; import org.ruleml.oojdrew.parsing.POSLParser; import org.ruleml.oojdrew.parsing.RDFSParser; import org.ruleml.oojdrew.parsing.RuleMLFormat; import org.ruleml.oojdrew.parsing.RuleMLParser; import org.ruleml.oojdrew.parsing.RuleMLTagNames; import org.ruleml.oojdrew.parsing.SubsumesParser; import org.ruleml.oojdrew.util.DefiniteClause; import org.ruleml.oojdrew.util.SymbolTable; import org.ruleml.oojdrew.util.Util; import org.ruleml.oojdrew.xml.XmlUtils; public class BottomUpApp extends AbstractUIApp { 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 BottomUp application using the factory method BottomUpApp app = BottomUpApp.getBottomUpApp(); // Start it's event loop app.run(); } private BottomUpApp(Configuration config, PreferenceManager preferenceManager, PreferenceDialogUI preferenceDialogUI, BottomUpUI bottomUpUI, Logger logger, DebugConsole debugConsole, RDFSParser rdfsParser, POSLParser poslParser, RuleMLParser rmlParser, SubsumesParser subsumesParser, ForwardReasoner forwardReasoner) { super(config, preferenceManager, preferenceDialogUI, bottomUpUI, logger, debugConsole, rdfsParser, poslParser, rmlParser, subsumesParser, forwardReasoner); } private void run() { EventQueue.invokeLater(new Runnable() { public void run() { logger.debug("Entering event loop"); ui.setFrameVisible(true); } }); } private static BottomUpApp getBottomUpApp() { // Construct dependencies Configuration config = new Config(BottomUpApp.class); PreferenceManager preferenceManager = new PreferenceManager(config); BottomUpUI bottomUpUI = new BottomUpUI(); 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(); // Create a forward reasoning engine ForwardReasoner forwardReasoner = new ForwardReasoner(); // Set global configuration variables org.ruleml.oojdrew.Config.PRINTGENOIDS = false; // Create a BottomUp application BottomUpApp bottomUpApp = new BottomUpApp(config, preferenceManager, preferenceDialogUI, bottomUpUI, logger, debugConsole, rdfsParser, poslParser, rmlParser, subsumesParser, forwardReasoner); return bottomUpApp; } private BottomUpUI getUI() { return (BottomUpUI) ui; } private ForwardReasoner getReasoner() { return (ForwardReasoner) reasoner; } private void setReasoner(ForwardReasoner reasoner) { this.reasoner = reasoner; } private boolean updateReasonerLoopCounter() { boolean successful = false; try { String loopCounter = getUI().getInputLoopCount(); getReasoner().setLoopCounter(loopCounter); successful = true; } catch (Exception ex1) { JOptionPane.showMessageDialog(ui.getFrmOoJdrew(), ex1.getMessage(), "Invalid Number Input", JOptionPane.ERROR_MESSAGE); } return successful; } public void checkKnowledgeBaseForStratificiation() { boolean strat = getReasoner().isStratifiable(); // Data base is not stratifiable if (!strat) { // Allowing the user to see the details on why stratification failed int dlgResult = JOptionPane.showConfirmDialog(ui.getFrmOoJdrew(), "Knowledge base is not stratifiable. \nWould you like to see more detials?\n", "Non-Stratfiable", JOptionPane.YES_NO_OPTION); // If the user wants to see the details, he can if (dlgResult == JOptionPane.YES_OPTION) { Vector msg = getReasoner().getMessage(); Iterator msgIterator = msg.iterator(); String message = ""; int count = 1; while (msgIterator.hasNext()) { message = message + count + ")" + (String) msgIterator.next() + "\n"; count++; } showInformationDialog("Stratification Violations", message); } } // Tells the user that the knowledge base is stratifiable if (strat) { showInformationDialog("Stratfiable", "Knowledge base is stratifiable."); } } @Override public void parseKnowledgeBase() { SymbolTable.reset(); setReasoner(new ForwardReasoner()); super.parseKnowledgeBase(); } public void runForwardReasoner() { if (!updateReasonerLoopCounter()) { return; } SyntaxFormat outputFormat = getUI().getOutputFormat(); RuleMLFormat rmlFormat = config.getRuleMLFormat(); boolean separateFacts = getUI().getSeparateFactsEnabled(); boolean printRules = getUI().getPrintRulesEnabled(); // Run reasoner getReasoner().runForwardReasoner(); System.out.println("Ran Reasoner"); Hashtable oldFacts = getReasoner().getOldFacts(); if (oldFacts.containsKey(SymbolTable.IINCONSISTENT)) { Vector v = (Vector) oldFacts.get(SymbolTable.IINCONSISTENT); if (v.size() > 0) { logger.warn("Knowledge base is inconsistent."); JOptionPane.showMessageDialog(ui.getFrmOoJdrew(), "Knowledge base is inconsistent", "Consistency Check", JOptionPane.WARNING_MESSAGE); } } Hashtable rules = getReasoner().getRules(); if (separateFacts) { StringBuilder stringBuilder = new StringBuilder(); String facts = getReasoner().printClauses(outputFormat, rmlFormat); stringBuilder.append(facts); if (printRules) { stringBuilder.append(Util.NEWLINE); stringBuilder.append("% Rules:"); stringBuilder.append(Util.NEWLINE); appendString(outputFormat, rmlFormat, rules.elements(), stringBuilder); } getUI().setOutputTextAreaText(stringBuilder.toString()); } else if (outputFormat == SyntaxFormat.POSL) { StringBuilder stringBuilder = new StringBuilder(); stringBuilder.append(Util.NEWLINE); stringBuilder.append("% Derived Facts:"); stringBuilder.append(Util.NEWLINE);; appendString(outputFormat, rmlFormat, oldFacts.elements(), stringBuilder); // Add the option to print rules or not if (printRules) { stringBuilder.append(Util.NEWLINE); stringBuilder.append("% Rules:"); stringBuilder.append(Util.NEWLINE); appendString(outputFormat, rmlFormat, rules.elements(), stringBuilder); } getUI().setOutputTextAreaText(stringBuilder.toString()); } else { RuleMLTagNames rmlTags = new RuleMLTagNames(rmlFormat); // Can add here to change the current parser so that // you can exchange between RuleML versions Element assertElement = new Element(rmlTags.ASSERT); Element assertChild = null; if (rmlFormat == RuleMLFormat.RuleML88) { assertChild = new Element(rmlTags.AND); } else { assertChild = new Element(rmlTags.RULEBASE); } Attribute a = new Attribute(rmlTags.MAPCLOSURE, rmlTags.UNIVERSAL); assertChild.addAttribute(a); assertElement.appendChild(assertChild); appendRuleML(assertChild, oldFacts.elements(), rmlFormat); // Add the option to print rules or not if (printRules) { appendRuleML(assertChild, rules.elements(), rmlFormat); } String rmlString = XmlUtils.elementToString(assertElement); getUI().setOutputTextAreaText(rmlString); } } private void appendString(SyntaxFormat outputFormat, RuleMLFormat rmlFormat, Enumeration enumeration, StringBuilder stringBuilder) { while (enumeration.hasMoreElements()) { Vector children = (Vector) enumeration.nextElement(); Iterator it = children.iterator(); while (it.hasNext()) { DefiniteClause dc = (DefiniteClause) it.next(); if (outputFormat == SyntaxFormat.POSL) { stringBuilder.append(dc.toPOSLString()); } else { stringBuilder.append(dc.toRuleMLString(rmlFormat)); } stringBuilder.append("\n"); } } } private void appendRuleML(Element element, Enumeration enumeration, RuleMLFormat rmlFormat) { while (enumeration.hasMoreElements()) { Vector children = (Vector) enumeration.nextElement(); Iterator it = children.iterator(); while (it.hasNext()) { DefiniteClause dc = (DefiniteClause) it.next(); if (dc.atoms[0].symbol == SymbolTable.IINCONSISTENT) { continue; } element.appendChild(dc.toRuleML(rmlFormat)); } } } }