second name transmit sentence

This commit is contained in:
austin 2024-12-31 19:40:31 -05:00
parent 723a2ac8db
commit ede82384de
11 changed files with 136 additions and 26 deletions

View File

@ -5,14 +5,7 @@ sitting in a tavern by a fireplace
Use arguments from clause parsing to perform queries when answering question Parse the sentence "I am John"
- use subject to find some node
- use interrogative argument to apply filters to the lookup
Comprehend the sentence "My name is ${name}"
- Transfer statement eval

View File

@ -30,6 +30,7 @@
</build> </build>
<properties> <properties>
<maven.compiler.target>17</maven.compiler.target> <maven.compiler.target>17</maven.compiler.target>
<corenlp.version>4.5.6</corenlp.version>
<maven.compiler.source>17</maven.compiler.source> <maven.compiler.source>17</maven.compiler.source>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<dl4j-master.version>1.0.0-M2</dl4j-master.version> <dl4j-master.version>1.0.0-M2</dl4j-master.version>

View File

@ -12,6 +12,7 @@ import org.studiorailgun.ai.conversation.web.ArgumentQuery;
import org.studiorailgun.ai.conversation.web.MetaQuery; import org.studiorailgun.ai.conversation.web.MetaQuery;
import org.studiorailgun.ai.knowledge.Node; import org.studiorailgun.ai.knowledge.Node;
import org.studiorailgun.ai.knowledge.cleaning.CollapseRelations; import org.studiorailgun.ai.knowledge.cleaning.CollapseRelations;
import org.studiorailgun.ai.linguistics.NameQuery;
import edu.stanford.nlp.ling.IndexedWord; import edu.stanford.nlp.ling.IndexedWord;
import edu.stanford.nlp.semgraph.SemanticGraph; import edu.stanford.nlp.semgraph.SemanticGraph;
@ -93,12 +94,12 @@ public class TransferEval {
//if there is no node with this name already, create one //if there is no node with this name already, create one
System.out.println(sentence.getGraph()); System.out.println(sentence.getGraph());
Node subjectNode = ArgumentQuery.getArgument(quote, subjectArg); Node subjectNode = ArgumentQuery.getArgument(conversation, quote, subjectArg);
if(subjectNode == null){ if(subjectNode == null){
throw new Error("Error querying subject!"); throw new Error("Error querying subject!");
} }
Node objectNode = ArgumentQuery.getArgument(quote, objectArg); Node objectNode = ArgumentQuery.getArgument(conversation, quote, objectArg);
if(objectNode == null){ if(objectNode == null){
throw new Error("Error querying object!"); throw new Error("Error querying object!");
} }
@ -107,6 +108,11 @@ public class TransferEval {
MetaQuery.equate(subjectNode, objectNode); MetaQuery.equate(subjectNode, objectNode);
CollapseRelations.collapse(subjectNode); CollapseRelations.collapse(subjectNode);
CollapseRelations.collapse(objectNode); CollapseRelations.collapse(objectNode);
} else if(NameQuery.isName(objectNode)) {
//because this is to-be verb, can explicitly check if the object is a name and assign name relation accordingly
NameQuery.attachName(objectNode, subjectNode);
CollapseRelations.collapse(subjectNode);
CollapseRelations.collapse(objectNode);
} else { } else {
String message = "Information already stored?\n" + String message = "Information already stored?\n" +
sentence.getGraph(); sentence.getGraph();

View File

@ -114,4 +114,21 @@ public class PennTreebankTagSet {
} }
} }
/**
* Checks if this tag is a pronoun or not
* @param tag The tag
* @return true if it is a pronoun, false otherwise
*/
public static boolean isPronoun(String tag){
switch(tag){
case "PRP":
case "PRP$": {
return true;
}
default: {
return false;
}
}
}
} }

View File

@ -6,12 +6,14 @@ import java.util.stream.Collectors;
import org.studiorailgun.Globals; import org.studiorailgun.Globals;
import org.studiorailgun.ai.conversation.parser.PennTreebankTagSet; import org.studiorailgun.ai.conversation.parser.PennTreebankTagSet;
import org.studiorailgun.ai.conversation.parser.depend.Argument; import org.studiorailgun.ai.conversation.parser.depend.Argument;
import org.studiorailgun.ai.conversation.tracking.Conversation;
import org.studiorailgun.ai.conversation.tracking.Quote; import org.studiorailgun.ai.conversation.tracking.Quote;
import org.studiorailgun.ai.knowledge.Node; import org.studiorailgun.ai.knowledge.Node;
import org.studiorailgun.ai.knowledge.Relation; import org.studiorailgun.ai.knowledge.Relation;
import org.studiorailgun.ai.knowledge.query.InstanceQuery; import org.studiorailgun.ai.knowledge.query.InstanceQuery;
import org.studiorailgun.ai.knowledge.query.PossessionQuery; import org.studiorailgun.ai.knowledge.query.PossessionQuery;
import org.studiorailgun.ai.knowledge.types.RelationTypes; import org.studiorailgun.ai.knowledge.types.RelationTypes;
import org.studiorailgun.ai.linguistics.PronounQuery;
import org.studiorailgun.ai.linguistics.ProperNounQuery; import org.studiorailgun.ai.linguistics.ProperNounQuery;
import org.studiorailgun.ai.philosophy.ConceptQuery; import org.studiorailgun.ai.philosophy.ConceptQuery;
@ -22,11 +24,12 @@ public class ArgumentQuery {
/** /**
* Gets the node representing a linguistic argument * Gets the node representing a linguistic argument
* @param conversation The conversation the quote is in context of
* @param quote The quote the argument is originating from -- used for some lookups (ie possession) * @param quote The quote the argument is originating from -- used for some lookups (ie possession)
* @param argument The argument * @param argument The argument
* @return The node * @return The node
*/ */
public static Node getArgument(Quote quote, Argument argument){ public static Node getArgument(Conversation conversation, Quote quote, Argument argument){
String argumentRoot = argument.getRoot().originalText(); String argumentRoot = argument.getRoot().originalText();
String argumentTag = argument.getRoot().tag(); String argumentTag = argument.getRoot().tag();
@ -40,8 +43,10 @@ public class ArgumentQuery {
if(argument.getPossessiveModifier() != null){ if(argument.getPossessiveModifier() != null){
rootNode = ArgumentQuery.getPossessionModified(quote, rootNode, argument); rootNode = ArgumentQuery.getPossessionModified(quote, rootNode, argument);
} }
} else if(PennTreebankTagSet.isProperNoun(argumentTag)) { } else if(PennTreebankTagSet.isProperNoun(argumentTag)){
rootNode = ProperNounQuery.getProperNoun(argumentRoot); rootNode = ProperNounQuery.getProperNoun(argumentRoot);
} else if(PennTreebankTagSet.isPronoun(argumentTag)){
rootNode = PronounQuery.getPronoun(conversation, quote, argumentRoot);
} else { } else {
throw new Error("Undefined case! " + argumentTag); throw new Error("Undefined case! " + argumentTag);
} }

View File

@ -53,29 +53,32 @@ public class NameCollapse {
* @param node The node * @param node The node
*/ */
private static void attemptPossessionSubstitution(Node node){ private static void attemptPossessionSubstitution(Node node){
Node nameConcept = ConceptQuery.getConcept("name");
if(nameConcept == null){
throw new Error("Name concept undefined!");
}
boolean shouldAttemptPossessionSubstitution = false; boolean shouldAttemptPossessionSubstitution = false;
boolean equalToName = false;
boolean isPossession = false;
for(Relation childRelation : Globals.web.getRelationsOfChildNode(node)){ for(Relation childRelation : Globals.web.getRelationsOfChildNode(node)){
switch(childRelation.getName()){ switch(childRelation.getName()){
case RelationTypes.INSTANCE_OF: { case RelationTypes.EQUALS: {
/** if(NameQuery.isName(childRelation.getParent())){
* Collapse names equalToName = true;
* person(inst) <--possessionOf-- name(inst) --equals--> "John"
* collapses to
* person(inst) <-- nameOf -- "John"
*/
if(childRelation.getParent().equals(nameConcept)){
shouldAttemptPossessionSubstitution = true;
} }
} break; } break;
case RelationTypes.POSSESSION_OF: {
isPossession = true;
} break;
default: { default: {
} break; } break;
} }
} }
/**
* Collapse names
* person(inst) <--possessionOf-- name(inst) --equals--> "John"
* collapses to
* person(inst) <-- nameOf -- "John"
*/
if(equalToName && isPossession){
shouldAttemptPossessionSubstitution = true;
}
if(shouldAttemptPossessionSubstitution){ if(shouldAttemptPossessionSubstitution){
Node properNoun = null; Node properNoun = null;
Node possessor = null; Node possessor = null;

View File

@ -7,6 +7,7 @@ import org.studiorailgun.Globals;
import org.studiorailgun.ai.knowledge.Node; import org.studiorailgun.ai.knowledge.Node;
import org.studiorailgun.ai.knowledge.Relation; import org.studiorailgun.ai.knowledge.Relation;
import org.studiorailgun.ai.knowledge.types.RelationTypes; import org.studiorailgun.ai.knowledge.types.RelationTypes;
import org.studiorailgun.ai.philosophy.ConceptQuery;
/** /**
* Queries related to the linguistic concept of a name * Queries related to the linguistic concept of a name
@ -30,4 +31,20 @@ public class NameQuery {
Globals.web.createRelation(RelationTypes.NAME_OF, properNoun, child); Globals.web.createRelation(RelationTypes.NAME_OF, properNoun, child);
} }
/**
* Checks if this node is a name or not
* @param node The node
* @return true if it is a name, false otherwise
*/
public static boolean isName(Node node){
Node nameConcept = ConceptQuery.getConcept("name");
List<Relation> childRelations = Globals.web.getRelationsOfChildNode(node);
List<Node> nameSearch = childRelations.stream()
.filter(relation -> relation.getName().equals(RelationTypes.INSTANCE_OF))
.map(relation -> relation.getParent())
.filter(instParent -> instParent.equals(nameConcept))
.collect(Collectors.toList());
return nameSearch.size() > 0;
}
} }

View File

@ -0,0 +1,33 @@
package org.studiorailgun.ai.linguistics;
import org.studiorailgun.ai.conversation.tracking.Conversation;
import org.studiorailgun.ai.conversation.tracking.Quote;
import org.studiorailgun.ai.conversation.web.QuoteQuery;
import org.studiorailgun.ai.knowledge.Node;
/**
* Queries related to pronouns
*/
public class PronounQuery {
/**
* Tries to locate a pronoun
* @param conversation The conversation
* @param quote The quote
* @param pronounText The pronoun text itself
* @return The node representing the pronoun
*/
public static Node getPronoun(Conversation conversation, Quote quote, String pronounText){
Node rVal = null;
switch(pronounText){
case "I": {
rVal = QuoteQuery.getSpeaker(quote.getNode());
} break;
default: {
throw new Error("Unhandled pronoun type " + pronounText);
}
}
return rVal;
}
}

View File

@ -5,6 +5,8 @@ import java.util.stream.Collectors;
import org.studiorailgun.Globals; import org.studiorailgun.Globals;
import org.studiorailgun.ai.knowledge.Node; import org.studiorailgun.ai.knowledge.Node;
import org.studiorailgun.ai.knowledge.query.InstanceQuery;
import org.studiorailgun.ai.philosophy.ConceptQuery;
/** /**
* Queries related to proper nouns * Queries related to proper nouns
@ -22,6 +24,9 @@ public class ProperNounQuery {
if(nodes.size() < 1){ if(nodes.size() < 1){
//create a name node to represent this name //create a name node to represent this name
rVal = Globals.web.createNode(properNoun); rVal = Globals.web.createNode(properNoun);
//make this an instance of a name (it is a proper noun, by definition it is a name)
Node nameConcept = ConceptQuery.getConcept("name");
InstanceQuery.setInstance(nameConcept, rVal);
} else if(nodes.size() == 1){ } else if(nodes.size() == 1){
rVal = nodes.get(0); rVal = nodes.get(0);
} else { } else {

View File

@ -34,4 +34,20 @@ public class TransferEvaluationTests {
assertEquals(names.get(0).getName(),"John"); assertEquals(names.get(0).getName(),"John");
} }
@Test
public void testEval2(){
Globals.init("./data/webs/test/web.json");
Quote input = new Quote("I am John.");
NLPParser.parse(input);
Globals.conversation.addQuote(ConversationQuery.getOtherParticipant(), input);
TransferEval.evaluate(Globals.conversation, input, input.getSentences().get(0));
//search for the name being assigned in the knowledge web
Node otherParticipant = ConversationQuery.getOtherParticipant();
List<Node> names = NameQuery.getNames(otherParticipant);
assertEquals(names.get(0).getName(),"John");
}
} }

View File

@ -29,4 +29,18 @@ public class TransferParsingTests {
assertEquals(mainClause.getSubject().getPossessiveModifier().originalText(), "My"); assertEquals(mainClause.getSubject().getPossessiveModifier().originalText(), "My");
} }
@Test
public void testParse2(){
Globals.init("./data/webs/test/web.json");
Quote input = new Quote("I am John.");
NLPParser.parse(input);
Sentence sentence = input.getSentences().get(0);
Clause mainClause = sentence.getMainClause();
//has a copular verb
assertEquals(mainClause.getPredicate().getRoot().originalText(),"John");
assertEquals(mainClause.getPredicate().getCopular().originalText(),"am");
assertEquals(mainClause.getSubject().getRoot().originalText(), "I");
}
} }