Java tutorial
//The MIT License // // Copyright (c) 2004 Mindswap Research Group, University of Maryland, College Park // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to // deal in the Software without restriction, including without limitation the // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or // sell copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS // IN THE SOFTWARE. package org.mindswap.swoop.renderer.entity; import java.io.IOException; import java.io.PrintWriter; import java.io.StringWriter; import java.net.URI; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.Hashtable; import java.util.Iterator; import java.util.List; import java.util.Set; import java.util.Vector; import org.apache.commons.lang.StringEscapeUtils; import org.mindswap.swoop.SwoopModel; import org.mindswap.swoop.renderer.BaseEntityRenderer; import org.mindswap.swoop.renderer.SwoopRenderingVisitor; import org.semanticweb.owl.io.ShortFormProvider; import org.semanticweb.owl.model.OWLAnd; import org.semanticweb.owl.model.OWLClass; import org.semanticweb.owl.model.OWLDataAllRestriction; import org.semanticweb.owl.model.OWLDataCardinalityRestriction; import org.semanticweb.owl.model.OWLDataEnumeration; import org.semanticweb.owl.model.OWLDataProperty; import org.semanticweb.owl.model.OWLDataPropertyInstance; import org.semanticweb.owl.model.OWLDataPropertyRangeAxiom; import org.semanticweb.owl.model.OWLDataSomeRestriction; import org.semanticweb.owl.model.OWLDataType; import org.semanticweb.owl.model.OWLDataValue; import org.semanticweb.owl.model.OWLDataValueRestriction; import org.semanticweb.owl.model.OWLDescription; import org.semanticweb.owl.model.OWLDifferentIndividualsAxiom; import org.semanticweb.owl.model.OWLDisjointClassesAxiom; import org.semanticweb.owl.model.OWLEnumeration; import org.semanticweb.owl.model.OWLEquivalentClassesAxiom; import org.semanticweb.owl.model.OWLEquivalentPropertiesAxiom; import org.semanticweb.owl.model.OWLException; import org.semanticweb.owl.model.OWLFunctionalPropertyAxiom; import org.semanticweb.owl.model.OWLIndividual; import org.semanticweb.owl.model.OWLIndividualTypeAssertion; import org.semanticweb.owl.model.OWLInverseFunctionalPropertyAxiom; import org.semanticweb.owl.model.OWLInversePropertyAxiom; import org.semanticweb.owl.model.OWLNot; import org.semanticweb.owl.model.OWLObjectAllRestriction; import org.semanticweb.owl.model.OWLObjectCardinalityRestriction; import org.semanticweb.owl.model.OWLObjectProperty; import org.semanticweb.owl.model.OWLObjectPropertyInstance; import org.semanticweb.owl.model.OWLObjectPropertyRangeAxiom; import org.semanticweb.owl.model.OWLObjectSomeRestriction; import org.semanticweb.owl.model.OWLObjectValueRestriction; import org.semanticweb.owl.model.OWLOr; import org.semanticweb.owl.model.OWLProperty; import org.semanticweb.owl.model.OWLPropertyDomainAxiom; import org.semanticweb.owl.model.OWLSameIndividualsAxiom; import org.semanticweb.owl.model.OWLSubClassAxiom; import org.semanticweb.owl.model.OWLSubPropertyAxiom; import org.semanticweb.owl.model.OWLSymmetricPropertyAxiom; import org.semanticweb.owl.model.OWLTransitivePropertyAxiom; import org.semanticweb.owl.model.helper.OWLObjectVisitorAdapter; import qtag.Tagger; public class NLVisitor extends OWLObjectVisitorAdapter implements SwoopRenderingVisitor { ShortFormProvider shortForms; StringWriter sw; PrintWriter pw; SwoopModel swoopModel; static Tagger tagger; //**** Define elements to create Natural Language Tree NLTree tree; NLNode parent; NLLink linkContext; HashMap nodeStore; Hashtable hyperlinkMap; OWLProperty linkProp; static String LINK_EQUIVALENT = "is"; // NEW CHANGE static String LINK_SUBCLASS = "is"; static String LINK_COMPLEMENT = "is not a"; static String LINK_INTERSECTION = "is"; static String LINK_UNION = "or a"; static String LINK_ALLVALUES = "that always"; static String LINK_SOMEVALUES = "that"; static String LINK_HASVALUE = "that"; static String LINK_MAXCARD = "with at most"; static String LINK_MINCARD = "with at least"; static String LINK_CARD = "with exactly"; static String LINK_ONEOF = "either"; static String LINK_BETWEEN = "with between"; //***** public NLVisitor(ShortFormProvider shortForms, SwoopModel swoopModel) { try { tagger = new Tagger("lib/qtag-eng"); } catch (IOException e) { System.out.println("Error: POS library not found!"); } this.shortForms = shortForms; this.swoopModel = swoopModel; hyperlinkMap = new Hashtable(); reset(); } /** * HTML-escape an object * @param o * @return */ private static String escape(Object o) { return StringEscapeUtils.escapeHtml(o.toString()); } public String result() { return sw.toString(); } public void reset() { sw = new StringWriter(); pw = new PrintWriter(sw); } public void resetNLTree(String entityName, String link, int type) { // set entity name as the root node of the tree NLNode root = new NLNode(entityName, type); // create a new NL tree with this root this.tree = new NLTree(root); // set current parent in NL-Visitor as root this.parent = root; // set current link (use argument passed as linktype) this.linkContext = new NLLink("", link); // used to reset parents during each iteration of a and/or/oneof nodeStore = new HashMap(); } public void resetParent() { this.parent = tree.getRoot(); } public void setLinkContext(String linkType) { linkContext.setLinkType(linkType); linkContext.setKeyword(""); } public void visit(OWLClass clazz) throws OWLException { // build NL tree String className = getShortForm(clazz.getURI()); String tokens = getEntityTokens(className); // add hyperlink hyperlinkMap.put(tokens, "<a href=\"" + clazz.getURI() + "\">" + tokens + "</a>"); NLNode target = new NLNode(tokens, 0); parent.addLink(linkContext, target); } public void visit(OWLIndividual ind) throws OWLException { // build NL tree String indName = getShortForm(ind.getURI()); String tokens = getEntityTokens(indName); // add hyperlink hyperlinkMap.put(tokens, "<a href=\"" + ind.getURI() + "\">" + tokens + "</a>"); NLNode target = new NLNode(tokens, 3); parent.addLink(linkContext, target); } // TODO this is just object properties public void visit(OWLObjectProperty prop) throws OWLException { // build NL tree String propName = getShortForm(prop.getURI()); String tokens = getEntityTokens(propName).toLowerCase(); String[] tok = getEntityTokens(propName).toLowerCase().split("( )+"); if (!tokens.startsWith("has") && !tokens.startsWith("is")) { // tagger.setInput(tokens); String[] tags = tagger.tag(tok); System.out.print(tokens + " TAG:"); for (int i = 0; i < tags.length; i++) { System.out.print(tags[i].toString() + " "); } System.out.println(); if (tok.length == 1) { // TODO: there is a problem if the word is ambiguous between a noun and a verb // for example: drives. a possible solution is to get the complete tagging and see if // such ambiguity exists, and always prefer the verb form, since plural nouns in properties // are apparently rare // To solve this problems, strips 's' from word and checks if the resulting form can be a verb if (tags[0].equals("NNS")) { String possibleVerb = tok[0].substring(0, tok[0].length() - 2); String[] testTags = tagger.tag(tok); if (testTags[0].startsWith("V")) { tok[0] = possibleVerb; tags = tagger.tag(tok); //System.out.print(tokens + " NEW TAG:" ); } } if (tags[0].startsWith("VB")) { if (tags[0].equals("VBN")) { tokens = "is " + tokens; // FOR TESTING NOW } else if (tags[0].startsWith("VBD")) { tokens = "is " + tokens; } } else if (tags[0].startsWith("N") && !tags[0].endsWith("S")) { // only singular nouns tokens = "has " + tokens; } else { //tokens = "has " + tokens; // unidentified prop type? } } else { if (tags[0].startsWith("NN")) { String possibleVerb = tok[0].substring(0, tok[0].length() - 2); String[] testTags = tagger.tag(tok); if (testTags[0].startsWith("V")) { tok[0] = possibleVerb; tags = tagger.tag(tok); } } int propClass = classifyComplexProp(tags, tok); System.err.println(propClass); // 0 = complex np (just multiple nouns) phone number // 1 = np and p child of // 2 = vp and np produces wine // 3 = vp and p located in // 4 = vp and pp (p and np) made from grape // -1 = other (unrecognized) prop12 switch (propClass) { case 0: tokens = "has " + tokens; break; case 1: tokens = "is a " + tokens; break; case 2: case 3: case 4: if (tags[0].equals("VBN")) { tokens = "is " + tokens; // FOR TESTING NOW } else if (tags[0].startsWith("VBD")) { tokens = "is " + tokens; } break; case 5: // unfortunately can't get here String newTokens = new String(tok[0] + "a "); for (int i = 1; i < tok.length; i++) { newTokens = newTokens.concat(tok[i] + " "); } tokens = newTokens; break; } } } else if (tokens.startsWith("is") && tok.length > 1) { String[] tags = tagger.tag(tok); System.out.print(tokens + " TAG:"); for (int i = 0; i < tags.length; i++) { System.out.print(tags[i].toString() + " "); } System.out.println(); int propClass = classifyComplexProp(tags, tok); if (propClass == 5) { String newTokens = new String(tok[0] + " a "); for (int i = 1; i < tok.length; i++) { newTokens = newTokens.concat(tok[i] + " "); } tokens = newTokens; } } // add hyperlink hyperlinkMap.put(tokens, "<a href=\"" + prop.getURI() + "\">" + tokens + "</a>"); linkContext.setKeyword(tokens); linkProp = prop; } // TODO dataproperty is not the same as public void visit(OWLDataProperty prop) throws OWLException { // build NL tree String propName = getShortForm(prop.getURI()); // String tokens = getEntityTokens(propName).toLowerCase(); String[] tok = getEntityTokens(propName).toLowerCase().split("( )+"); if (!tokens.startsWith("has") && !tokens.startsWith("is")) { String[] tags = tagger.tag(tok); // System.out.println(tokens+" TAG:"+tags); if (tags[0].startsWith("VB")) { tokens = "is " + tokens; // heuristic for verbs } else { tokens = "has " + tokens; // heuristic for nouns } } // add hyperlink hyperlinkMap.put(tokens, "<a href=\"" + prop.getURI() + "\">" + tokens + "</a>"); linkContext.setKeyword(tokens); linkProp = prop; } public void visit(OWLDataValue cd) throws OWLException { String dVal = " \"" + escape(cd.getValue()) + "\""; NLNode target = new NLNode(getEntityTokens(dVal), 3); parent.addLink(linkContext, target); } public void visit(OWLAnd and) throws OWLException { if (linkProp != null) prefixDomain(linkProp); // suppose object of prop restr is a intersection String saveCode = String.valueOf(this.parent.hashCode()); nodeStore.put(saveCode, parent); boolean restoreLC = linkContext.isComplement(); // restore link complement for each intersection element for (Iterator it = and.getOperands().iterator(); it.hasNext();) { linkContext.setLinkType(LINK_INTERSECTION); linkContext.setKeyword(""); linkContext.setIsComplement(restoreLC); OWLDescription desc = (OWLDescription) it.next(); desc.accept(this); this.parent = (NLNode) nodeStore.get(saveCode); // reset parent at each iteration // TESTING: // this.printTree(); // System.out.println(); } } public void visit(OWLOr or) throws OWLException { if (linkProp != null) prefixDomain(linkProp); // suppose object of prop restr is a union String saveCode = String.valueOf(this.parent.hashCode()); nodeStore.put(saveCode, parent); boolean restoreLC = linkContext.isComplement(); // restore link complement for each union element for (Iterator it = or.getOperands().iterator(); it.hasNext();) { linkContext.setLinkType(LINK_UNION); linkContext.setKeyword(""); linkContext.setIsComplement(restoreLC); OWLDescription desc = (OWLDescription) it.next(); desc.accept(this); this.parent = (NLNode) nodeStore.get(saveCode); // reset parent at each iteration } } public void visit(OWLNot not) throws OWLException { if (linkProp != null) prefixDomain(linkProp); // suppose object of prop restr is a complement linkContext.setIsComplement(true); // used to print "not" when object is a description linkContext.setLinkType(NLVisitor.LINK_COMPLEMENT); // used to print "not" when object is a class linkContext.setKeyword(""); OWLDescription desc = not.getOperand(); desc.accept(this); } public void visit(OWLEnumeration enumeration) throws OWLException { System.out.println("Visiting Enumeration"); String saveCode = String.valueOf(this.parent.hashCode()); nodeStore.put(saveCode, parent); boolean restoreLC = linkContext.isComplement(); // restore link complement for each oneof element //NLLink originalLinkContext = linkContext; String enumString = new String(); for (Iterator it = enumeration.getIndividuals().iterator(); it.hasNext();) { //linkContext.setLinkType(LINK_ONEOF); //linkContext.setIsComplement(restoreLC); OWLIndividual desc = (OWLIndividual) it.next(); //desc.accept( this ); //this.parent = (NLNode) nodeStore.get(saveCode); // reset parent at each iteration String indName = getShortForm(desc.getURI()); String tokens = getEntityTokens(indName); enumString = enumString.concat(indName + ";;;"); } NLNode enum_ = new NLNode(enumString, 4); // create dummy node ? parent.addLink(linkContext, enum_); } public void visit(OWLObjectSomeRestriction restriction) throws OWLException { prefixDomain(restriction.getObjectProperty()); linkContext.setLinkType(LINK_SOMEVALUES); restriction.getObjectProperty().accept(this); restriction.getDescription().accept(this); } public void visit(OWLObjectAllRestriction restriction) throws OWLException { prefixDomain(restriction.getObjectProperty()); linkContext.setLinkType(LINK_ALLVALUES); restriction.getObjectProperty().accept(this); restriction.getDescription().accept(this); } public void visit(OWLObjectValueRestriction restriction) throws OWLException { prefixDomain(restriction.getObjectProperty()); linkContext.setLinkType(LINK_HASVALUE); restriction.getObjectProperty().accept(this); restriction.getIndividual().accept(this); } public void visit(OWLDataSomeRestriction restriction) throws OWLException { prefixDomain(restriction.getDataProperty()); linkContext.setLinkType(LINK_SOMEVALUES); restriction.getDataProperty().accept(this); restriction.getDataType().accept(this); } public void visit(OWLDataAllRestriction restriction) throws OWLException { prefixDomain(restriction.getDataProperty()); linkContext.setLinkType(LINK_ALLVALUES); restriction.getDataProperty().accept(this); restriction.getDataType().accept(this); } public void visit(OWLObjectCardinalityRestriction restriction) throws OWLException { prefixDomain(restriction.getObjectProperty()); int ncard = -1; if (restriction.isExactly()) { linkContext.setLinkType(LINK_CARD); ncard = restriction.getAtLeast(); } else if (restriction.isAtMost()) { linkContext.setLinkType(LINK_MAXCARD); ncard = restriction.getAtMost(); } else if (restriction.isAtLeast()) { linkContext.setLinkType(LINK_MINCARD); ncard = restriction.getAtLeast(); } restriction.getObjectProperty().accept(this); NLNode cardNode = new NLNode(String.valueOf(ncard), 2); parent.addLink(linkContext, cardNode); } public void visit(OWLDataCardinalityRestriction restriction) throws OWLException { prefixDomain(restriction.getProperty()); int ncard = -1; if (restriction.isExactly()) { linkContext.setLinkType(LINK_CARD); ncard = restriction.getAtLeast(); } else if (restriction.isAtMost()) { linkContext.setLinkType(LINK_MAXCARD); ncard = restriction.getAtMost(); } else if (restriction.isAtLeast()) { linkContext.setLinkType(LINK_MINCARD); ncard = restriction.getAtLeast(); } restriction.getDataProperty().accept(this); NLNode cardNode = new NLNode(String.valueOf(ncard), 2); parent.addLink(linkContext, cardNode); } public void visit(OWLDataValueRestriction restriction) throws OWLException { prefixDomain(restriction.getDataProperty()); linkContext.setLinkType(LINK_HASVALUE); restriction.getDataProperty().accept(this); restriction.getValue().accept(this); } public void visit(OWLEquivalentClassesAxiom axiom) throws OWLException { pw.print("EquivalentClasses("); for (Iterator it = axiom.getEquivalentClasses().iterator(); it.hasNext();) { OWLDescription desc = (OWLDescription) it.next(); desc.accept(this); if (it.hasNext()) { pw.print(" "); } } pw.print(")"); } public void visit(OWLDisjointClassesAxiom axiom) throws OWLException { pw.print("("); for (Iterator it = axiom.getDisjointClasses().iterator(); it.hasNext();) { OWLDescription desc = (OWLDescription) it.next(); desc.accept(this); if (it.hasNext()) { pw.print(" " + ConciseFormat.DISJOINT + " "); } } pw.print(")"); } public void visit(OWLSubClassAxiom axiom) throws OWLException { pw.print("("); axiom.getSubClass().accept(this); pw.print(" " + ConciseFormat.SUBSET + " "); axiom.getSuperClass().accept(this); pw.print(")"); } public void visit(OWLEquivalentPropertiesAxiom axiom) throws OWLException { pw.print("("); for (Iterator it = axiom.getProperties().iterator(); it.hasNext();) { OWLProperty prop = (OWLProperty) it.next(); prop.accept(this); if (it.hasNext()) { pw.print(" = "); } } pw.print(")"); } public void visit(OWLSubPropertyAxiom axiom) throws OWLException { pw.print("("); axiom.getSubProperty().accept(this); pw.print(" " + ConciseFormat.SUBSET + " "); axiom.getSuperProperty().accept(this); pw.print(")"); } public void visit(OWLDifferentIndividualsAxiom ax) throws OWLException { pw.print("("); for (Iterator it = ax.getIndividuals().iterator(); it.hasNext();) { OWLIndividual desc = (OWLIndividual) it.next(); desc.accept(this); if (it.hasNext()) { pw.print(" " + ConciseFormat.DISJOINT + " "); } } pw.print(")"); } public void visit(OWLSameIndividualsAxiom ax) throws OWLException { pw.print("SameIndividual("); for (Iterator it = ax.getIndividuals().iterator(); it.hasNext();) { OWLIndividual desc = (OWLIndividual) it.next(); desc.accept(this); if (it.hasNext()) { pw.print(" = "); } } pw.print(")"); } public void visit(OWLDataType ocdt) throws OWLException { //pw.print( "<a href=\"" + ocdt.getURI() + "\">" + getShortForm( ocdt.getURI() ) + "</a>" ); //pw.print( getShortForm( ocdt.getURI() ) ); } public void visit(OWLDataEnumeration enumeration) throws OWLException { pw.print("{"); for (Iterator it = enumeration.getValues().iterator(); it.hasNext();) { linkContext.setLinkType(LINK_ONEOF); OWLDataValue desc = (OWLDataValue) it.next(); desc.accept(this); if (it.hasNext()) { pw.print(", "); } } pw.print("}"); } public void prefixDomain(OWLProperty prop) { System.out.print("PROP: " + prop); String domainName = ""; URI uri = null; try { for (Iterator it = swoopModel.getReasoner().domainsOf(prop).iterator(); it.hasNext();) { OWLDescription dom = (OWLDescription) it.next(); if (dom instanceof OWLClass) { uri = ((OWLClass) dom).getURI(); domainName = getShortForm(((OWLClass) dom).getURI()); break; } } } catch (Exception e) { e.printStackTrace(); } finally { if (domainName.equals("")) domainName = "Thing"; // THIS WAS CHANGED FROM thing String tokens = getEntityTokens(domainName); // add hyperlink hyperlinkMap.put(tokens, "<a href=\"" + uri + "\">" + tokens + "</a>"); NLNode target = new NLNode(tokens, 0); //NLLink isaLink = new NLLink("", this.LINK_SUBCLASS); parent = parent.addLink(linkContext, target); } System.out.println(" DOM: " + domainName); } // this is what does the splitting of prop names into tokens, here is where we add // delimiter support in the future public String getEntityTokens(String entityName) { String[] tokens = new String[10]; String strTokens = ""; int tLen = 0; int prev = 0; for (int i = 1; i < entityName.length(); i++) { if (Character.isUpperCase(entityName.charAt(i))) { //if (entityName.charAt(i) >= 'A' && entityName.charAt(i) <= 'Z') { if (i - prev > 0) { strTokens += (entityName.substring(prev, i) + " "); tokens[tLen++] = entityName.substring(prev, i); prev = i; } } if (i == (entityName.length() - 1)) { // System.out.println(i+":"+prev+":"+entityName+":"+entityName.substring(prev)); tokens[tLen] = entityName.substring(prev); strTokens += entityName.substring(prev); } } return strTokens; } public String getShortForm(URI uri) throws OWLException { String sf = shortForms.shortForm(uri); if (sf.indexOf(":") >= 0) sf = sf.substring(sf.indexOf(":") + 1, sf.length()); return sf; } public void printTree() { NLNode root = tree.getRoot(); cleanUpThingNodes(); printNode(root, true, 0); } private void putLinks(List sorted, HashMap map) { for (Iterator i = map.keySet().iterator(); i.hasNext();) { NLLink link = (NLLink) i.next(); NLNode node = (NLNode) map.get(link); sorted.add(new NLLinkNode(link, node)); } } // onlyPrefix == false means return the rest, not the whole thing private String getPart(String sentence, boolean onlyPrefix) { // remove hyperlink stuff if any if (sentence.indexOf("<a href") >= 0) { sentence = sentence.substring(sentence.indexOf("\">") + 2, sentence.indexOf("</a>")); } if (sentence.indexOf(" ") == -1) return sentence; if (onlyPrefix) { String prefix = sentence.substring(0, sentence.indexOf(" ")); return prefix; } else { String rest = sentence.substring(sentence.indexOf(" ") + 1, sentence.length()); return rest; } } /* New NLP Functions - Daniel */ // 0 = complex np (just multiple nouns) phone number // 1 = np and p child of // 2 = vp and np produces wine // 3 = vp and p located in // 4 = vp and pp (p and np) made from grape // 5 = is NP of is specific function of // -1 = other (unrecognized) prop12 private int classifyComplexProp(String[] tags, String[] tokens) { boolean containsVerb = false; boolean containsPrep = false; boolean containsNoun = false; boolean containsOf = false; boolean containsIs = false; for (int i = 0; i < tags.length; i++) { String curr = tags[i]; System.err.println(tokens[i] + " " + tags[i]); if (curr.startsWith("V")) { containsVerb = true; } else if (curr.startsWith("N")) { containsNoun = true; if (i == tags.length - 1) { if (containsVerb && containsPrep) { return 4; } else if (containsVerb && !containsPrep) { return 2; } } } else if (curr.startsWith("IN")) { containsPrep = true; System.out.println("PREP: " + tokens[i]); if (tokens[i].equals("of")) containsOf = true; if (i == tags.length - 1) { if (containsOf) { // I assume that anything with of will always have an NP if (containsIs) { // is brother of System.out.println("RETURNING 5"); return 5; } else { // brother of return 1; } } if (containsVerb) { return 3; } else if (containsNoun) { return 1; } // if ( containsNoun && !containsVerb ) { // return 1; // } else if ( containsVerb && !containsNoun ) { // return 3; // } } } else if (curr.startsWith("B")) { containsIs = true; } } if (containsOf && containsIs) return 5; if (containsNoun && !containsVerb && !containsPrep) { return 0; } return -1; } private void cleanUpThingNodes() { NLNode root = tree.getRoot(); System.out.println("BEGINNING THING REMOVAL"); printDebugTree(); reconcileThingNodes(root); printDebugTree(); //reconcileNegativeThingNodes( root ); //printDebugTree(); reconcileNonIsaThingNodes(root); printDebugTree(); System.out.println("END THING REMOVAL"); } public void printDebugTree() { printDebugNode(tree.getRoot(), 0); } private void printDebugNode(NLNode node, int indent) { System.out.println(node.keyword); HashMap links = node.getLinks(); Set keys = links.keySet(); for (Iterator iter = keys.iterator(); iter.hasNext();) { // cycle through each link NLLink link = (NLLink) iter.next(); NLNode target = (NLNode) links.get(link); for (int i = 0; i < indent; i++) System.out.print("\t"); System.out.print("(" + link.linkType + ") " + link.keyword + " "); printDebugNode(target, indent + 1); } } // TODO make this fix the problem of multiple all values on same property private void mergeAllValues(NLNode node) { } // PROPERTIES private void reconcileNonIsaThingNodes(NLNode node) { HashMap links = node.getLinks(); Set keys = links.keySet(); NLLink isaLink = new NLLink("", NLVisitor.LINK_SUBCLASS); boolean thingFound = false; Set isaLinks = new HashSet(); //Set nonIsaLinks = new HashSet(); Set nonIsaThingLinks = new HashSet(); // may be more than one, unlike is-a for (Iterator iter = new HashSet(keys).iterator(); iter.hasNext();) { // cycle through each link NLLink link = (NLLink) iter.next(); NLNode target = (NLNode) links.get(link); System.out.println("LINK: " + link.keyword + " (" + link.linkType + "), TARGET: " + target.keyword); if (!link.equals(isaLink)) { //nonIsaLinks.add( link ); if (target.getKeyword().equals("Thing") || target.getKeyword().equals("thing")) { System.out.println("NON-ISA thing found"); nonIsaThingLinks.add(link); } } } // pulling-up named classes for non-isa thing links for (Iterator nt = nonIsaThingLinks.iterator(); nt.hasNext();) { NLLink curr = (NLLink) nt.next(); NLNode thingNode = (NLNode) links.get(curr); HashMap tLinks = thingNode.getLinks(); Set tNonThingTargets = new HashSet(); Set tKeys = tLinks.keySet(); for (Iterator i = tKeys.iterator(); i.hasNext();) { NLLink tLink = (NLLink) i.next(); NLNode tTarget = (NLNode) tLinks.get(tLink); if (tLink.equals(isaLink)) { if (!tTarget.getKeyword().equals("Thing") && !tTarget.getKeyword().equals("thing")) { System.out.println("pull-up"); System.out.println(links); links.remove(curr); links.put(curr, tTarget); tTarget.links.putAll(thingNode.links); tTarget.links.remove(tLink); } } } } // Recurse keys = links.keySet(); for (Iterator iter = keys.iterator(); iter.hasNext();) { NLLink link = (NLLink) iter.next(); NLNode target = (NLNode) links.get(link); System.out.println("NEW LINK: " + link.keyword + " (" + link.linkType + "), TARGET: " + target.keyword); reconcileNonIsaThingNodes(target); } } // recursive function to squash Thing nodes - COMPLEMENT private void reconcileNegativeThingNodes(NLNode node) { HashMap links = node.getLinks(); NLLink isNotALink = new NLLink("", NLVisitor.LINK_COMPLEMENT); // first: gather all the is-a links NLLink nonThingLink = null; NLLink thingLink = null; boolean thingFound = false; Set isaLinks = new HashSet(); for (Iterator iter = links.keySet().iterator(); iter.hasNext();) { NLLink link = (NLLink) iter.next(); NLNode target = (NLNode) links.get(link); //System.out.println( "LINK: " + link.keyword + " (" + link.linkType + "), TARGET: " + target.keyword ); if (link.equals(isNotALink)) { isaLinks.add(link); if (target.getKeyword().equals("Thing") || target.getKeyword().equals("thing")) { //System.out.println( "thing found" ); thingFound = true; thingLink = link; } else { nonThingLink = link; } } } //System.out.println( "NEG-ISA's: " + isaLinks.size() + " " + thingFound); if (thingFound) { if (isaLinks.size() == 0) { // this should never happen } else if (isaLinks.size() == 1) { // there is only one node and it is a thing node, so we can safely pull its links up NLNode thingNode = (NLNode) links.get(thingLink); HashMap tLinks = thingNode.getLinks(); node.links.putAll(tLinks); links.remove(thingLink); } else { NLNode thingNode = (NLNode) links.get(thingLink); NLNode nonThingNode = (NLNode) links.get(nonThingLink); HashMap tLinks = thingNode.getLinks(); HashMap ntLinks = nonThingNode.getLinks(); ntLinks.putAll(tLinks); links.remove(thingLink); } } // Recurse for (Iterator iter = links.keySet().iterator(); iter.hasNext();) { NLLink link = (NLLink) iter.next(); NLNode target = (NLNode) links.get(link); //System.out.println( "NEW LINK: " + link.keyword + " (" + link.linkType + "), TARGET: " + target.keyword ); reconcileNegativeThingNodes(target); } } // recursive function to squash Thing nodes - ISA private void reconcileThingNodes(NLNode node) { HashMap links = node.getLinks(); Set keys = links.keySet(); NLLink isaLink = new NLLink("", NLVisitor.LINK_SUBCLASS); // first: gather all the is-a links NLLink nonThingLink = null; NLLink thingLink = null; boolean thingFound = false; Set isaLinks = new HashSet(); for (Iterator iter = new HashSet(keys).iterator(); iter.hasNext();) { // cycle through each link NLLink link = (NLLink) iter.next(); NLNode target = (NLNode) links.get(link); System.out.println("LINK: " + link.keyword + " (" + link.linkType + "), TARGET: " + target.keyword); if (link.equals(isaLink)) { isaLinks.add(link); if (target.getKeyword().equals("Thing") || target.getKeyword().equals("thing")) { System.out.println("thing found"); thingFound = true; thingLink = link; } else { nonThingLink = link; } } } System.out.println("ISA's: " + isaLinks.size() + " " + thingFound); if (thingFound) { if (isaLinks.size() == 0) { // this should never happen } else if (isaLinks.size() == 1) { // there is only one node and it is a thing node, so we can safely pull its links up NLNode thingNode = (NLNode) links.get(thingLink); HashMap tLinks = thingNode.getLinks(); node.links.putAll(tLinks); links.remove(thingLink); } else { NLNode thingNode = (NLNode) links.get(thingLink); NLNode nonThingNode = (NLNode) links.get(nonThingLink); HashMap tLinks = thingNode.getLinks(); HashMap ntLinks = nonThingNode.getLinks(); ntLinks.putAll(tLinks); links.remove(thingLink); } } // Recurse keys = links.keySet(); for (Iterator iter = keys.iterator(); iter.hasNext();) { NLLink link = (NLLink) iter.next(); NLNode target = (NLNode) links.get(link); System.out.println("NEW LINK: " + link.keyword + " (" + link.linkType + "), TARGET: " + target.keyword); reconcileThingNodes(target); } } private boolean containsNP(String propName) { if (propName.startsWith("has") || propName.startsWith("is")) return true; String[] tokens = propName.split("( )+"); String[] tags = tagger.tag(tokens); if (tokens.length > 1) { int result = classifyComplexProp(tags, tokens); if (result == 2 || result == 4) return true; } return false; } private void processAllValues(NLNode node, int indent) { HashMap links = node.getLinks(); boolean allPrinted = false; NLLink isaLink = new NLLink("", NLVisitor.LINK_SUBCLASS); for (Iterator iter = links.keySet().iterator(); iter.hasNext();) { // cycle through each link NLLink link = (NLLink) iter.next(); NLNode target = (NLNode) links.get(link); System.out.println("LINK: " + link.keyword + " (" + link.linkType + "), TARGET: " + target.keyword); if (link.equals(isaLink)) { for (Iterator ti = target.getLinks().keySet().iterator(); ti.hasNext();) { NLLink tLink = (NLLink) ti.next(); NLNode tTarget = (NLNode) target.getLinks().get(tLink); if (tLink.getLinkType().equals(NLVisitor.LINK_ALLVALUES)) { System.out.println("All Values present"); boolean simpleAll = !containsNP(tLink.getKeyword()); if (simpleAll) { pw.print("If a " + node.getKeyword() + " " + tLink.getKeyword() + " something"); pw.println(", then that thing:"); pw.print("\t- "); } else { pw.print("If a " + node.getKeyword() + " " + getPart(tLink.getKeyword(), true) + " a " + getPart(tLink.getKeyword(), false)); pw.println(", then that " + getPart(tLink.getKeyword(), false) + ":"); pw.print("\t- "); } // old part pw.print(link.getLinkType() + " "); // new part printNode(tTarget, false, indent + 1); // the all-values is already printed, so remove it ti.remove(); allPrinted = true; } if (allPrinted) pw.println(); } } else if (link.getLinkType().equals(NLVisitor.LINK_ALLVALUES)) { System.out.println("All Values present"); boolean simpleAll = !containsNP(link.getKeyword()); if (simpleAll) { pw.print("If a " + node.getKeyword() + " " + link.getKeyword() + " something"); pw.println(", then that thing:"); pw.print("\t- "); } else { pw.print("If a " + node.getKeyword() + " " + getPart(link.getKeyword(), true) + " a " + getPart(link.getKeyword(), false)); pw.println(", then that " + getPart(link.getKeyword(), false) + ":"); pw.print("\t- "); } // old part sans linkType - because we know its all values pw.print("is "); // new part printNode(target, false, indent + 1); // the all-values is already printed, so remove it iter.remove(); allPrinted = true; pw.println(); } } } /** * Recursive algorithm to print a single NL tree node * @param node - print a subtree of this node * @param basic TODO */ public void printNode(NLNode node, boolean topLevel, int indent) { System.out.println("printing node: " + node.keyword + " " + node.links + " type:" + node.nodeType); // processes and REMOVES all all-values nodes processAllValues(node, indent); if (node.nodeType == 0) { pw.print("a "); } else if (node.nodeType == 4) { String[] elements = node.getKeyword().split(";;;"); if (elements.length == 0) { System.out.println("There is a prolem: Empty Enumeration"); } else if (elements.length == 1) { pw.print(elements[0] + " "); } else if (elements.length == 2) { pw.print(elements[0] + " or " + elements[1] + " "); } else { for (int i = 0; i < elements.length; i++) { pw.print(elements[i]); if (i < elements.length - 2) { pw.print(", "); } else if (i == elements.length - 2) { pw.print(" or "); } } pw.print(" "); } return; // enumeration is always terminal } // NODE KEYWORD PRINTED pw.print(node.getKeyword() + " "); HashMap links = node.getLinks(); // get hashmap of links for current node Set keys = links.keySet(); // save the initial set of links //*********************************************** // Rule 2: sort links as follows: 1st is-a, 2nd cardinality, 3rd remaining HashMap isaLinks = new HashMap(); HashMap compLinks = new HashMap(); HashMap cardLinks = new HashMap(); HashMap allLinks = new HashMap(); HashMap remLinks = new HashMap(); NLLink isaLink = new NLLink("", NLVisitor.LINK_SUBCLASS); HashMap newIsaLinks = new HashMap(); for (Iterator iter = new HashSet(keys).iterator(); iter.hasNext();) { // cycle through each link NLLink link = (NLLink) iter.next(); NLNode target = (NLNode) links.get(link); System.out.println("LINK: " + link.keyword + " (" + link.linkType + "), TARGET: " + target.keyword); if (link.equals(isaLink)) { newIsaLinks.put(link, target); } if (link.equals(isaLink) && target.links.keySet().size() == 0) { System.out.println(target.keyword + " " + node.keyword); // simply is-a link and not a nested restriction isaLinks.put(link, target); } else if (link.getLinkType().equals(NLVisitor.LINK_COMPLEMENT)) { compLinks.put(link, target); } else if (link.getLinkType().equals(NLVisitor.LINK_CARD) || link.getLinkType().equals(NLVisitor.LINK_MAXCARD) || link.getLinkType().equals(NLVisitor.LINK_MINCARD)) { // cardinality restrictions cardLinks.put(link, target); } else if (link.getLinkType().equals(NLVisitor.LINK_ALLVALUES)) { // all values restrictions - this also never happens allLinks.put(link, target); } else { // value restrictions remLinks.put(link, target); } } List sortedLinkNodes = new ArrayList(); putLinks(sortedLinkNodes, isaLinks); putLinks(sortedLinkNodes, compLinks); putLinks(sortedLinkNodes, cardLinks); putLinks(sortedLinkNodes, remLinks); putLinks(sortedLinkNodes, allLinks); boolean bigMultiple = sortedLinkNodes.size() > 0; boolean bigComplex = false; if (bigMultiple) { for (int i = 0; i < sortedLinkNodes.size(); i++) { NLLink link = ((NLLinkNode) sortedLinkNodes.get(i)).link; // Check for just existential restriction or is_a if (!link.linkType.equals(NLVisitor.LINK_SOMEVALUES) && !link.linkType.equals(NLVisitor.LINK_HASVALUE) && !link.linkType.equals(NLVisitor.LINK_SUBCLASS)) { bigComplex = true; break; } } } boolean bigFirstTime = true; for (int i = 0; i < sortedLinkNodes.size(); i++) { if (bigComplex && bigFirstTime) { pw.print("that: \n"); pw.print("\t"); for (int j = 0; j < indent; j++) { pw.print("\t"); } pw.print("-- "); } // cycle through each sorted link NLLink link = ((NLLinkNode) sortedLinkNodes.get(i)).link; String linkProp = link.getKeyword(); List linkTargets = new ArrayList(); //*********************************************** // Rule 3: find all targets that match the same link property // and put them in a shortened list = linkTargets for (int j = 0; j < sortedLinkNodes.size(); j++) { NLLink chkLink = ((NLLinkNode) sortedLinkNodes.get(j)).link; if (keys.contains(chkLink) && chkLink.getKeyword().equals(linkProp)) { // add link target to common matrix NLNode target = ((NLLinkNode) sortedLinkNodes.get(j)).node; linkTargets.add(new NLLinkNode(chkLink, target)); keys.remove(chkLink); // successively remove to prevent duplicate printing of the exact same link } } //*********************************************** // Rule 4: combine restrictions on the same property (e.g. allValues with a cardinality, either with a someValues etc) // and change linktype text for restrictions accordingly List minLNs = filterLinks(linkTargets, NLVisitor.LINK_MINCARD, false); List maxLNs = filterLinks(linkTargets, NLVisitor.LINK_MAXCARD, false); if (minLNs.size() > 0 && maxLNs.size() > 0) { // assuming there is only one of each (can there be more?) NLLinkNode minCardLN = (NLLinkNode) minLNs.iterator().next(); NLLinkNode maxCardLN = (NLLinkNode) maxLNs.iterator().next(); // then combine both the min and max cardinalities using 'between' minCardLN.link.setLinkType(NLVisitor.LINK_BETWEEN); minCardLN.node.setKeyword(minCardLN.node.keyword + " - " + maxCardLN.node.keyword); linkTargets.remove(maxCardLN); } List cardLNs = filterLinks(linkTargets, NLVisitor.LINK_CARD, false); List someLNs = filterLinks(linkTargets, NLVisitor.LINK_SOMEVALUES, false); List allLNs = filterLinks(linkTargets, NLVisitor.LINK_ALLVALUES, false); List hasLNs = filterLinks(linkTargets, NLVisitor.LINK_HASVALUE, false); if (cardLNs.size() > 0 || minLNs.size() > 0 || maxLNs.size() > 0) { // combine cardinality with someValues for (Iterator k = someLNs.iterator(); k.hasNext();) { NLLinkNode someLN = (NLLinkNode) k.next(); someLN.link.setLinkType("at least one of which is"); } // combine cardinality with allValues - // TODO now this will never happen? for (Iterator k = allLNs.iterator(); k.hasNext();) { NLLinkNode allLN = (NLLinkNode) k.next(); allLN.link.setLinkType("each of which is"); } // combine cardinality with oneOf for (Iterator k = hasLNs.iterator(); k.hasNext();) { //System.out.println( "YOYOYO" ); NLLinkNode hasLN = (NLLinkNode) k.next(); //hasLN.link.setLinkType("that has"); hasLN.link.setLinkType("which is"); } } // combine someValues with allValues // some x, some y and always x or y if (someLNs.size() > 0 && allLNs.size() > 0) { //TODO } // START PRINTING //*********************************************** // insert either-or for hasValue for oneOfs // code below ONLY FOR ONEOFs List oneofs = filterLinks(linkTargets, NLVisitor.LINK_ONEOF, true); if (oneofs.size() > 0) { String connector1 = "", connector2 = ""; if (((NLLinkNode) oneofs.get(0)).link.isComplement) { connector1 = " neither "; connector2 = " nor "; } else { connector1 = " either "; connector2 = " or "; } // assume link.keyword starts with is/has String prefix = this.getPart(link.getKeyword(), true); pw.print(prefix + " "); if (!prefix.equals("has")) { if (oneofs.size() > 1) { //pw.print(" that"+connector1); pw.print(connector1); } pw.print(this.getPart(link.getKeyword(), false) + " "); } else { if (oneofs.size() > 1) { //pw.print(" that"+connector1); pw.print(connector1); } } Vector v = new Vector(oneofs); for (int k = 0; k < v.size(); k++) { NLNode target = ((NLLinkNode) v.get(k)).node; printNode(target, false, indent); if (v.size() > 2) { if (k < v.size() - 2) { pw.print(", "); } else if (k < v.size() - 1) { pw.print(connector2); } } else { if (k == 0) { pw.print(connector2); } } } // for (Iterator j = oneofs.iterator(); j.hasNext(); ) { // NLNode target = ((NLLinkNode) j.next()).node; // printNode( target, false, indent ); // if ( j.hasNext() ) // pw.print(connector2); // } if (prefix.equals("has")) { pw.print(this.getPart(link.getKeyword(), false) + " "); } //if (linkTargets.size()>1) pw.print(", "); //else if (linkTargets.size()==1) pw.print(" and "); } // *********************************************** // insert either-or for UNIONS List unions = filterLinks(linkTargets, NLVisitor.LINK_UNION, true); if (unions.size() > 0) { String connector1 = "", connector2 = ""; if (((NLLinkNode) unions.get(0)).link.isComplement) { connector1 = " neither "; connector2 = " nor a "; } else { connector1 = " either "; connector2 = " or a "; } if (unions.size() > 1) pw.print(" is" + connector1 + "a "); pw.print(link.getKeyword() + " "); for (Iterator j = unions.iterator(); j.hasNext();) { NLNode target = ((NLLinkNode) j.next()).node; printNode(target, false, indent); if (j.hasNext()) pw.print(connector2); } if (linkTargets.size() > 1) pw.print(", "); else if (linkTargets.size() == 1) pw.print(" and "); } //System.out.println( "Here we are!!!" ); //**************************************************************** // finally handle remaining link-nodes normally - EVERYTHING ELSE boolean firstTime = true; boolean complex = false; boolean multiple = linkTargets.size() > 0; for (int j = 0; j < linkTargets.size(); j++) { NLLink flink = ((NLLinkNode) linkTargets.get(j)).link; ; NLNode ftarget = ((NLLinkNode) linkTargets.get(j)).node; if (flink.getLinkType().equals(NLVisitor.LINK_SOMEVALUES)) { } else { complex = true; System.out.println("complex!"); } } //System.out.println( "THE CRITICAL FACTOR: " + (linkTargets.size() > 2) ); boolean cardPrinted = false; for (int j = 0; j < linkTargets.size(); j++) { NLLink flink = ((NLLinkNode) linkTargets.get(j)).link; ; NLNode ftarget = ((NLLinkNode) linkTargets.get(j)).node; System.out.println("LOOP + " + i + ": " + flink.keyword + " (" + flink.linkType + "), TARGET: " + ftarget.keyword); if (cardPrinted) { System.out.println("CARD-IN-AL-ITY"); pw.print(", "); pw.print(flink.getLinkType() + " "); printNode(ftarget, firstTime, indent); } else { if (flink.getLinkType().equals(NLVisitor.LINK_CARD) || flink.getLinkType().equals(NLVisitor.LINK_MINCARD) || flink.getLinkType().equals(NLVisitor.LINK_MAXCARD) || flink.getLinkType().equals(NLVisitor.LINK_BETWEEN)) { // change order for property and value for cardinality restriction // re-phrase cardinality clauses , // e.g., with at most 1 is made from grape -> which is made from at most 1 grape reOrderCardClause(flink, ftarget, link.getKeyword(), !firstTime, indent); cardPrinted = true; } else { if (bigFirstTime) { pw.print(flink.getLinkType() + " "); } if (complex && keys.size() > 0) { //pw.print( "\n\t- " ); } String prefix = this.getPart(link.getKeyword(), true); if (prefix.equals("has")) { // TODO replace with function isPrefixEligible() pw.print(prefix + " "); } else { pw.print(flink.getKeyword() + " "); } // make a check here for boolean properties // example is hard working "false" -> is not hard working if (ftarget.keyword.indexOf("false") == -1 && ftarget.keyword.indexOf("true") == -1) { // it is NOT a boolean property // THIS IS WHERE MOST PRINTING TAKES PLACE printNode(ftarget, firstTime, indent); // TODO NEW CHANGE - is this good? } else { // it is a boolean property if (ftarget.keyword.indexOf("false") != -1) { pw.print("not "); //TODO make negation better } } if (prefix.equals("has")) { // TODO replace with function isPrefixEligible() pw.print(this.getPart(link.getKeyword(), false) + " "); } } } // If complex sentence forming, break // Currently complex is determined as those that involve // combination of two restrictions (eg. card + all/some/has) // and all these combinations use the keyword "which" //TODO Extend and improve determination of complex //if ( flink.getLinkType().indexOf("that") != -1 && keys.size()>0 ) { if (complex && keys.size() > 0) { //pw.print( "\n\t- " ); // TODO fix this later } else if (!cardPrinted) { // else add comma or and depending on number of items left if (j < linkTargets.size() - 2) pw.print(", "); else if (j == linkTargets.size() - 2) pw.print(" and "); } firstTime = false; } // END INTERNAL LOOP if (!bigComplex && keys.size() > 0) { if (keys.size() == 1) pw.print(" and "); else pw.print(", "); } else { if (keys.size() == 0) { //pw.print( ". " ); } else { pw.print("\n\t-- "); } } bigFirstTime = false; } } // consider that only the last word of the keyword is a noun phrase private void reOrderCardClause(NLLink flink, NLNode ftarget, String strKeyword, boolean onlyonce, int indent) { //split the strings into tokens String[] tokens = strKeyword.split("( )+"); String[] tags = tagger.tag(tokens); int nounPhraseIndex = -1; //check where the NP starts, assume it starts with the first noun for (int i = 0; i < tags.length; i++) { if (tags[i].equals("NN") || tags[i].equals("NNS") || tags[i].equals("NP") || tags[i].equals("NPS")) { // noun phrase nounPhraseIndex = i; } } String strPrefix = "", strNP = ""; //case when there is no NP - select the last token as target and the rest as prefix if (nounPhraseIndex == -1) nounPhraseIndex = tokens.length - 1; for (int i = 0; i < nounPhraseIndex; i++) { strPrefix += (tokens[i] + " "); } for (int i = nounPhraseIndex; i < tokens.length; i++) { strNP += (tokens[i] + " "); } // change - removed all that's from below code if (flink.getLinkType().equals(NLVisitor.LINK_CARD)) { //with exactly pw.print(" " + strPrefix + " exactly "); } else if (flink.getLinkType().equals(NLVisitor.LINK_MINCARD)) { //with at most pw.print(" " + strPrefix + " at least "); } else if (flink.getLinkType().equals(NLVisitor.LINK_MAXCARD)) { //with at least pw.print(" " + strPrefix + " at most "); } else if (flink.getLinkType().equals(NLVisitor.LINK_BETWEEN)) { //with between pw.print(" " + strPrefix + " between "); } printNode(ftarget, false, indent); // TODO did this matter? if (!onlyonce) pw.print(strNP); } private List filterLinks(List linkTargets, String filterType, boolean doRemoveLinks) { List filter = new ArrayList(); Set remove = new HashSet(); for (int i = 0; i < linkTargets.size(); i++) { NLLink link = ((NLLinkNode) linkTargets.get(i)).link; String linkType = link.getLinkType(); if (linkType.equals(filterType)) { remove.add(linkTargets.get(i)); filter.add(((NLLinkNode) linkTargets.get(i))); } } if (doRemoveLinks) linkTargets.removeAll(remove); return filter; } protected class NLTree { // natural language tree to represent entity structure private NLNode root; public NLTree() { } public NLTree(NLNode root) { this.root = root; } public void setRoot(NLNode root) { this.root = root; } public NLNode getRoot() { return root; } } protected class NLNode { // structure of a single NL node private String keyword; private HashMap links; public int nodeType = 0; // 0 is for Class // 1 is for Cardinality Target // 2 is for Data Literal // 3 is for Individual // 4 is for dummy node for enumeration - always called **enum** public NLNode(String word, int type) { keyword = word; links = new HashMap(); nodeType = type; } public String getKeyword() { return keyword; } public void setKeyword(String word) { this.keyword = word; } public NLNode addLink(NLLink link, NLNode target) { for (Iterator iter = links.keySet().iterator(); iter.hasNext();) { NLLink key = (NLLink) iter.next(); if (key.equals(link)) { NLNode value = (NLNode) links.get(key); if (value.equals(target)) { return value; } } } NLNode newTarget = new NLNode(target.getKeyword(), target.nodeType); links.put(new NLLink(link.getKeyword(), link.getLinkType(), link.isComplement), newTarget); // also remove complement on link if present link.setIsComplement(false); return newTarget; } public HashMap getLinks() { return links; } public boolean equals(NLNode node) { if (node.getKeyword().equals(this.keyword)) return true; else return false; } } protected class NLLink { // different types of links between nodes private String linkType; private String keyword; private boolean isComplement; public NLLink(String keyword, String type) { this.keyword = keyword; this.linkType = type; this.isComplement = false; } public NLLink(String keyword, String type, boolean isComplement) { this.keyword = keyword; this.linkType = type; this.isComplement = isComplement; } public boolean isComplement() { return this.isComplement; } public void setIsComplement(boolean mode) { this.isComplement = mode; } public String getLinkType() { return linkType; } public void setLinkType(String linkType) { this.linkType = linkType; } public void setKeyword(String keyword) { this.keyword = keyword; } public String getKeyword() { return keyword; } public boolean equals(NLLink link) { if ((link.getKeyword().equals(this.keyword)) && link.getLinkType().equals(this.getLinkType()) && link.isComplement() == this.isComplement()) return true; else return false; } public void printLink() { System.out.println("LINK: (" + this.linkType + ") " + this.keyword); } } protected class NLLinkNode { NLLink link; NLNode node; public NLLinkNode(NLLink link, NLNode node) { this.link = link; this.node = node; } } /* (non-Javadoc) * @see org.semanticweb.owl.model.OWLObjectVisitor#visit(org.semanticweb.owl.model.OWLFunctionalPropertyAxiom) */ public void visit(OWLFunctionalPropertyAxiom node) throws OWLException { // TODO Auto-generated method stub } /* (non-Javadoc) * @see org.semanticweb.owl.model.OWLObjectVisitor#visit(org.semanticweb.owl.model.OWLInverseFunctionalPropertyAxiom) */ public void visit(OWLInverseFunctionalPropertyAxiom node) throws OWLException { // TODO Auto-generated method stub } /* (non-Javadoc) * @see org.semanticweb.owl.model.OWLObjectVisitor#visit(org.semanticweb.owl.model.OWLTransitivePropertyAxiom) */ public void visit(OWLTransitivePropertyAxiom node) throws OWLException { // TODO Auto-generated method stub } /* (non-Javadoc) * @see org.semanticweb.owl.model.OWLObjectVisitor#visit(org.semanticweb.owl.model.OWLSymmetricPropertyAxiom) */ public void visit(OWLSymmetricPropertyAxiom node) throws OWLException { // TODO Auto-generated method stub } /* (non-Javadoc) * @see org.semanticweb.owl.model.OWLObjectVisitor#visit(org.semanticweb.owl.model.OWLInversePropertyAxiom) */ public void visit(OWLInversePropertyAxiom node) throws OWLException { // TODO Auto-generated method stub } /* (non-Javadoc) * @see org.semanticweb.owl.model.OWLObjectVisitor#visit(org.semanticweb.owl.model.OWLPropertyDomainAxiom) */ public void visit(OWLPropertyDomainAxiom node) throws OWLException { // TODO Auto-generated method stub } /* (non-Javadoc) * @see org.semanticweb.owl.model.OWLObjectVisitor#visit(org.semanticweb.owl.model.OWLObjectPropertyRangeAxiom) */ public void visit(OWLObjectPropertyRangeAxiom node) throws OWLException { // TODO Auto-generated method stub } /* (non-Javadoc) * @see org.semanticweb.owl.model.OWLObjectVisitor#visit(org.semanticweb.owl.model.OWLDataPropertyRangeAxiom) */ public void visit(OWLDataPropertyRangeAxiom node) throws OWLException { // TODO Auto-generated method stub } /* (non-Javadoc) * @see org.semanticweb.owl.model.OWLObjectVisitor#visit(org.semanticweb.owl.model.OWLObjectPropertyInstance) */ public void visit(OWLObjectPropertyInstance node) throws OWLException { //prefixDomain(node.getProperty()); linkContext.setLinkType(LINK_SOMEVALUES); node.getProperty().accept(this); node.getObject().accept(this); } /* (non-Javadoc) * @see org.semanticweb.owl.model.OWLObjectVisitor#visit(org.semanticweb.owl.model.OWLDataPropertyInstance) */ public void visit(OWLDataPropertyInstance node) throws OWLException { // TODO Auto-generated method stub } /* (non-Javadoc) * @see org.semanticweb.owl.model.OWLObjectVisitor#visit(org.semanticweb.owl.model.OWLIndividualTypeAssertion) */ public void visit(OWLIndividualTypeAssertion node) throws OWLException { // TODO Auto-generated method stub } }