diff --git a/current_goal.txt b/current_goal.txt index 0bcc198..81e4fc7 100644 --- a/current_goal.txt +++ b/current_goal.txt @@ -7,9 +7,14 @@ sitting in a tavern by a fireplace Comprehend the sentence "My name is ${name}" + - Figure out that we're assigning a value + - Figure out what values we're assigning - Transfer statement eval +Update parsers to use "Arguments" (currently called "NounStack"), "Predicates" (Not defined yet, but essentially verbs), and "Adjuncts" (also not defined yet, are noncritial information eg "yesterday") +Update parsers to determine valence of sentence (maybe create a dictionary to lookup?) + diff --git a/src/main/java/org/studiorailgun/conversation/evaluators/EvaluationTree.java b/src/main/java/org/studiorailgun/conversation/evaluators/EvaluationTree.java index 809bbfe..89dc4b6 100644 --- a/src/main/java/org/studiorailgun/conversation/evaluators/EvaluationTree.java +++ b/src/main/java/org/studiorailgun/conversation/evaluators/EvaluationTree.java @@ -6,6 +6,7 @@ import org.studiorailgun.conversation.evaluators.goal.GoalEval; import org.studiorailgun.conversation.evaluators.greet.GreetingEval; import org.studiorailgun.conversation.evaluators.query.QueryEval; import org.studiorailgun.conversation.evaluators.synthesis.ResponseEval; +import org.studiorailgun.conversation.evaluators.transfer.TransferEval; import org.studiorailgun.conversation.parser.NLPParser; import org.studiorailgun.conversation.tracking.Conversation; import org.studiorailgun.conversation.tracking.Quote; @@ -48,7 +49,7 @@ public class EvaluationTree { QueryEval.evaluate(conversation, quote, sentence); } break; case TRANSFER : { - + TransferEval.evaluate(conversation, quote, sentence); } break; default: { throw new UnsupportedOperationException("Unsupported quote function: " + sentence.getFunction()); diff --git a/src/main/java/org/studiorailgun/conversation/evaluators/query/NounStack.java b/src/main/java/org/studiorailgun/conversation/evaluators/query/NounStack.java index 66e033c..194829a 100644 --- a/src/main/java/org/studiorailgun/conversation/evaluators/query/NounStack.java +++ b/src/main/java/org/studiorailgun/conversation/evaluators/query/NounStack.java @@ -49,17 +49,30 @@ public class NounStack { if(children.size() > 0){ for(IndexedWord child : children){ switch(child.tag()){ + + //the child is an interrogative modifying the noun case "WDT": case "WP": case "WP$": case "WRB": { - //the child is an interrogative modifying the verb rVal.interrogative = child.originalText(); } break; + + + //the child is a possessive pronoun case "PRP$": { - //the child is a possessive pronoun rVal.possessive = child.originalText(); } break; + + + //skip children that aren't a part of the stack (ie if we're parsing the root, skip other subjects) + case "VBZ": + case ".": + case "NN" : { + continue; + } + + //complain when unhandled case found default: { System.out.println(child); System.out.println(child.tag()); diff --git a/src/main/java/org/studiorailgun/conversation/evaluators/transfer/TransferEval.java b/src/main/java/org/studiorailgun/conversation/evaluators/transfer/TransferEval.java new file mode 100644 index 0000000..a10f155 --- /dev/null +++ b/src/main/java/org/studiorailgun/conversation/evaluators/transfer/TransferEval.java @@ -0,0 +1,106 @@ +package org.studiorailgun.conversation.evaluators.transfer; + +import org.studiorailgun.conversation.evaluators.query.NounStack; +import org.studiorailgun.conversation.parser.NLPDependencies; +import org.studiorailgun.conversation.parser.PennTreebankTagSet; +import org.studiorailgun.conversation.tracking.Conversation; +import org.studiorailgun.conversation.tracking.Quote; +import org.studiorailgun.conversation.tracking.Sentence; + +import edu.stanford.nlp.ling.IndexedWord; +import edu.stanford.nlp.semgraph.SemanticGraph; +import edu.stanford.nlp.trees.GrammaticalRelation; + +/** + * Evaluates a transfer statement + */ +public class TransferEval { + + /** + * Evaluates a quote + * @param conversation The conversation + * @param quote The quote + */ + public static void evaluate(Conversation conversation, Quote quote, Sentence sentence){ + SemanticGraph semanticGraph = sentence.getGraph(); + if(semanticGraph.getRoots().size() > 1){ + String message = "Multiple roots to sentence!\n" + + "\"" + quote.getRaw() + "\"\n" + + semanticGraph; + throw new UnsupportedOperationException(message); + } + IndexedWord root = semanticGraph.getFirstRoot(); + + if(PennTreebankTagSet.isNoun(root.tag())){ + if(TransferEval.isCopularStatement(semanticGraph)){ + NounStack noun1 = NounStack.parse(semanticGraph, root); + NounStack noun2 = null; + for(IndexedWord child : semanticGraph.getChildList(root)){ + if(PennTreebankTagSet.isNoun(child.tag())){ + noun2 = NounStack.parse(semanticGraph, child); + break; + } + } + if(noun2 == null){ + throw new Error("Failed to parse second noun! " + semanticGraph); + } + TransferEval.evaluateCopularStatement(conversation, quote, sentence, noun1, null); + } else { + String message = "Unsupported root type!\n" + + "\"" + sentence.getRaw() + "\"\n" + + semanticGraph; + throw new UnsupportedOperationException(message); + } + } else { + String message = "Unsupported root type!\n" + + "\"" + sentence.getRaw() + "\"\n" + + semanticGraph; + throw new UnsupportedOperationException(message); + } + } + + /** + * Evaluates a copular statement + * @param conversation The conversation + * @param quote The quote + * @param sentence The sentence containing the copular statement + * @param noun1 The first noun stack + * @param noun2 The second noun stack + */ + private static void evaluateCopularStatement(Conversation conversation, Quote quote, Sentence sentence, NounStack noun1, NounStack noun2){ + SemanticGraph graph = sentence.getGraph(); + IndexedWord verb = NLPDependencies.getCopular(graph); + if(PennTreebankTagSet.isBe(verb.tag())){ + TransferEval.evaluateEquivalenceStatement(conversation, quote, sentence, noun1, noun2); + } else { + throw new Error("Unsupported verb type! " + graph); + } + } + + /** + * Evaluates a statement that is equating two nouns + * @param conversation The conversation + * @param quote The quote + * @param sentence The sentence + */ + private static void evaluateEquivalenceStatement(Conversation conversation, Quote quote, Sentence sentence, NounStack noun1, NounStack noun2){ + throw new UnsupportedOperationException("Need to actually perform the equivalence transforms in the knowledge web!"); + } + + /** + * Checks if this is a copular statement + * @param graph The graph + * @return true if it is a copular statement, false otherwise + */ + private static boolean isCopularStatement(SemanticGraph graph){ + IndexedWord root = graph.getFirstRoot(); + for(IndexedWord child : graph.getChildList(root)){ + GrammaticalRelation relation = graph.reln(root,child); + if(NLPDependencies.isCopular(relation.getLongName())){ + return true; + } + } + return false; + } + +} diff --git a/src/main/java/org/studiorailgun/conversation/parser/NLPDependencies.java b/src/main/java/org/studiorailgun/conversation/parser/NLPDependencies.java new file mode 100644 index 0000000..a17bea3 --- /dev/null +++ b/src/main/java/org/studiorailgun/conversation/parser/NLPDependencies.java @@ -0,0 +1,41 @@ +package org.studiorailgun.conversation.parser; + +import edu.stanford.nlp.ling.IndexedWord; +import edu.stanford.nlp.semgraph.SemanticGraph; +import edu.stanford.nlp.trees.GrammaticalRelation; + +/** + * NLP dependency functions + */ +public class NLPDependencies { + + /** + * Checks if this is a copular dependency + * @param dependency The dependency tag + * @return true if it is a copular dependency, false otherwise + */ + public static boolean isCopular(String dependency){ + return dependency.equals("copula"); + } + + /** + * Gets the copular verb of the graph + * @param graph The graph + * @param root The root + * @return The copular verb + */ + public static IndexedWord getCopular(SemanticGraph graph){ + if(graph.getRoots().size() != 1){ + throw new Error("Can't handle roots != 1\n" + graph); + } + IndexedWord root = graph.getFirstRoot(); + for(IndexedWord child : graph.getChildList(root)){ + GrammaticalRelation relation = graph.reln(root,child); + if(NLPDependencies.isCopular(relation.getLongName())){ + return child; + } + } + throw new Error("Passed in root without copular verb!\n" + graph); + } + +} diff --git a/src/main/java/org/studiorailgun/conversation/parser/PennTreebankTagSet.java b/src/main/java/org/studiorailgun/conversation/parser/PennTreebankTagSet.java index 9c47208..d8fac6e 100644 --- a/src/main/java/org/studiorailgun/conversation/parser/PennTreebankTagSet.java +++ b/src/main/java/org/studiorailgun/conversation/parser/PennTreebankTagSet.java @@ -59,4 +59,24 @@ public class PennTreebankTagSet { } } + /** + * Checks if this tag is a noun or not + * @param tag The tag + * @return true if it is a noun, false otherwise + */ + public static boolean isNoun(String tag){ + switch(tag){ + case "NN": + case "NNS": + case "NP": + case "NPS": + case "NNP": { + return true; + } + default: { + return false; + } + } + } + }