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
- 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
Parse the sentence "I am John"

View File

@ -30,6 +30,7 @@
</build>
<properties>
<maven.compiler.target>17</maven.compiler.target>
<corenlp.version>4.5.6</corenlp.version>
<maven.compiler.source>17</maven.compiler.source>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<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.knowledge.Node;
import org.studiorailgun.ai.knowledge.cleaning.CollapseRelations;
import org.studiorailgun.ai.linguistics.NameQuery;
import edu.stanford.nlp.ling.IndexedWord;
import edu.stanford.nlp.semgraph.SemanticGraph;
@ -93,12 +94,12 @@ public class TransferEval {
//if there is no node with this name already, create one
System.out.println(sentence.getGraph());
Node subjectNode = ArgumentQuery.getArgument(quote, subjectArg);
Node subjectNode = ArgumentQuery.getArgument(conversation, quote, subjectArg);
if(subjectNode == null){
throw new Error("Error querying subject!");
}
Node objectNode = ArgumentQuery.getArgument(quote, objectArg);
Node objectNode = ArgumentQuery.getArgument(conversation, quote, objectArg);
if(objectNode == null){
throw new Error("Error querying object!");
}
@ -107,6 +108,11 @@ public class TransferEval {
MetaQuery.equate(subjectNode, objectNode);
CollapseRelations.collapse(subjectNode);
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 {
String message = "Information already stored?\n" +
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.ai.conversation.parser.PennTreebankTagSet;
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.knowledge.Node;
import org.studiorailgun.ai.knowledge.Relation;
import org.studiorailgun.ai.knowledge.query.InstanceQuery;
import org.studiorailgun.ai.knowledge.query.PossessionQuery;
import org.studiorailgun.ai.knowledge.types.RelationTypes;
import org.studiorailgun.ai.linguistics.PronounQuery;
import org.studiorailgun.ai.linguistics.ProperNounQuery;
import org.studiorailgun.ai.philosophy.ConceptQuery;
@ -22,11 +24,12 @@ public class ArgumentQuery {
/**
* 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 argument The argument
* @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 argumentTag = argument.getRoot().tag();
@ -42,6 +45,8 @@ public class ArgumentQuery {
}
} else if(PennTreebankTagSet.isProperNoun(argumentTag)){
rootNode = ProperNounQuery.getProperNoun(argumentRoot);
} else if(PennTreebankTagSet.isPronoun(argumentTag)){
rootNode = PronounQuery.getPronoun(conversation, quote, argumentRoot);
} else {
throw new Error("Undefined case! " + argumentTag);
}

View File

@ -53,29 +53,32 @@ public class NameCollapse {
* @param node The 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 equalToName = false;
boolean isPossession = false;
for(Relation childRelation : Globals.web.getRelationsOfChildNode(node)){
switch(childRelation.getName()){
case RelationTypes.INSTANCE_OF: {
case RelationTypes.EQUALS: {
if(NameQuery.isName(childRelation.getParent())){
equalToName = true;
}
} break;
case RelationTypes.POSSESSION_OF: {
isPossession = true;
} break;
default: {
} break;
}
}
/**
* Collapse names
* person(inst) <--possessionOf-- name(inst) --equals--> "John"
* collapses to
* person(inst) <-- nameOf -- "John"
*/
if(childRelation.getParent().equals(nameConcept)){
if(equalToName && isPossession){
shouldAttemptPossessionSubstitution = true;
}
} break;
default: {
} break;
}
}
if(shouldAttemptPossessionSubstitution){
Node properNoun = 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.Relation;
import org.studiorailgun.ai.knowledge.types.RelationTypes;
import org.studiorailgun.ai.philosophy.ConceptQuery;
/**
* Queries related to the linguistic concept of a name
@ -30,4 +31,20 @@ public class NameQuery {
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.ai.knowledge.Node;
import org.studiorailgun.ai.knowledge.query.InstanceQuery;
import org.studiorailgun.ai.philosophy.ConceptQuery;
/**
* Queries related to proper nouns
@ -22,6 +24,9 @@ public class ProperNounQuery {
if(nodes.size() < 1){
//create a name node to represent this name
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){
rVal = nodes.get(0);
} else {

View File

@ -34,4 +34,20 @@ public class TransferEvaluationTests {
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");
}
@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");
}
}