initial pass at first query parsing
All checks were successful
studiorailgun/trpg/pipeline/head This commit looks good
All checks were successful
studiorailgun/trpg/pipeline/head This commit looks good
This commit is contained in:
parent
3781c73d88
commit
ee5f4eab86
@ -8,8 +8,8 @@ sitting in a tavern by a fireplace
|
||||
|
||||
|
||||
Respond to "What color is your hat?"
|
||||
- determine sentence function
|
||||
- determine what is being queried for
|
||||
- respond with the correct information
|
||||
|
||||
|
||||
|
||||
|
||||
31
data/webs/bert.json
Normal file
31
data/webs/bert.json
Normal file
@ -0,0 +1,31 @@
|
||||
{
|
||||
"tag" : "bert",
|
||||
"nodes" : {
|
||||
"0" : {
|
||||
"id" : 0,
|
||||
"name" : "Bert"
|
||||
},
|
||||
"9" : {
|
||||
"id" : 9,
|
||||
"name" : "Bert's Hat"
|
||||
}
|
||||
},
|
||||
"relations" : {
|
||||
"0" : {
|
||||
"id" : 0,
|
||||
"name" : "nameOf",
|
||||
"parent" : 0,
|
||||
"child" : 2,
|
||||
"childWeb" : "root"
|
||||
},
|
||||
"1" : {
|
||||
"id" : 1,
|
||||
"name" : "qualiaOf",
|
||||
"parent" : 1,
|
||||
"parentWeb" : "color",
|
||||
"child" : 9
|
||||
}
|
||||
},
|
||||
"children" : [
|
||||
]
|
||||
}
|
||||
24
data/webs/qualia/qualia.json
Normal file
24
data/webs/qualia/qualia.json
Normal file
@ -0,0 +1,24 @@
|
||||
{
|
||||
"tag" : "qualia",
|
||||
"nodes" : {
|
||||
"0" : {
|
||||
"id" : 0,
|
||||
"name" : "qualia"
|
||||
}
|
||||
},
|
||||
"relations" : {
|
||||
"0" : {
|
||||
"id" : 0,
|
||||
"name" : "instanceOf",
|
||||
"parent" : 0,
|
||||
"child" : 0,
|
||||
"childWeb" : "color"
|
||||
}
|
||||
},
|
||||
"anchors" : {
|
||||
"qualia" : 0
|
||||
},
|
||||
"children" : [
|
||||
"./data/webs/qualia/color.json"
|
||||
]
|
||||
}
|
||||
@ -1,11 +1,6 @@
|
||||
{
|
||||
"tag" : "root",
|
||||
"selfId": 2,
|
||||
"nodes" : {
|
||||
"0" : {
|
||||
"id" : 0,
|
||||
"name" : "Bert"
|
||||
},
|
||||
"1" : {
|
||||
"id" : 1,
|
||||
"name" : "Name"
|
||||
@ -37,53 +32,71 @@
|
||||
"8" : {
|
||||
"id" : 8,
|
||||
"name" : "Hat"
|
||||
},
|
||||
"10" : {
|
||||
"id" : 10,
|
||||
"name" : "concept"
|
||||
}
|
||||
},
|
||||
"relations" : {
|
||||
"0" : {
|
||||
"id" : 0,
|
||||
"name" : "Name",
|
||||
"parent" : 0,
|
||||
"child" : 2
|
||||
},
|
||||
"1" : {
|
||||
"id" : 1,
|
||||
"name" : "InstanceOf",
|
||||
"name" : "instanceOf",
|
||||
"parent" : 3,
|
||||
"child" : 2
|
||||
},
|
||||
"2" : {
|
||||
"id" : 2,
|
||||
"name" : "InstanceOf",
|
||||
"name" : "instanceOf",
|
||||
"parent" : 1,
|
||||
"child" : 0
|
||||
"child" : 0,
|
||||
"childWeb" : "bert"
|
||||
},
|
||||
"3" : {
|
||||
"id" : 3,
|
||||
"name" : "InstanceOf",
|
||||
"name" : "instanceOf",
|
||||
"parent" : 3,
|
||||
"child" : 4
|
||||
},
|
||||
"4" : {
|
||||
"id" : 4,
|
||||
"name" : "ParticipantOf",
|
||||
"name" : "participantOf",
|
||||
"parent" : 7,
|
||||
"child" : 4
|
||||
},
|
||||
"5" : {
|
||||
"id" : 5,
|
||||
"name" : "ParticipantOf",
|
||||
"name" : "participantOf",
|
||||
"parent" : 7,
|
||||
"child" : 2
|
||||
},
|
||||
"6" : {
|
||||
"id" : 6,
|
||||
"name" : "Possession",
|
||||
"name" : "possessionOf",
|
||||
"parent" : 2,
|
||||
"child" : 9,
|
||||
"childWeb" : "bert"
|
||||
},
|
||||
"7" : {
|
||||
"id" : 7,
|
||||
"name" : "instanceOf",
|
||||
"parent" : 8,
|
||||
"child" : 9,
|
||||
"childWeb" : "bert"
|
||||
},
|
||||
"8" : {
|
||||
"id" : 8,
|
||||
"name" : "instanceOf",
|
||||
"parent" : 10,
|
||||
"child" : 8
|
||||
}
|
||||
},
|
||||
"anchors" : {
|
||||
"self" : 2,
|
||||
"concept" : 10
|
||||
},
|
||||
"children" : [
|
||||
"./data/webs/color.json"
|
||||
"./data/webs/qualia/qualia.json",
|
||||
"./data/webs/bert.json"
|
||||
]
|
||||
}
|
||||
@ -1,6 +1,5 @@
|
||||
{
|
||||
"tag" : "root",
|
||||
"selfId": 2,
|
||||
"children" : [
|
||||
"./data/webs/root.json"
|
||||
]
|
||||
|
||||
@ -1,5 +1,7 @@
|
||||
package org.studiorailgun.conversation.evaluators.goal;
|
||||
|
||||
import org.studiorailgun.conversation.evaluators.query.QueryData;
|
||||
|
||||
/**
|
||||
* Data about the AI's goal in the conversation
|
||||
*/
|
||||
@ -21,6 +23,18 @@ public class GoalData {
|
||||
*/
|
||||
ConversationGoal goal;
|
||||
|
||||
/**
|
||||
* The query data
|
||||
*/
|
||||
QueryData queryData;
|
||||
|
||||
/**
|
||||
* The query data for the conversation
|
||||
*/
|
||||
public GoalData(){
|
||||
this.queryData = new QueryData();
|
||||
}
|
||||
|
||||
public ConversationGoal getGoal() {
|
||||
return goal;
|
||||
}
|
||||
@ -29,6 +43,8 @@ public class GoalData {
|
||||
this.goal = goal;
|
||||
}
|
||||
|
||||
|
||||
public QueryData getQueryData() {
|
||||
return queryData;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -1,5 +1,15 @@
|
||||
package org.studiorailgun.conversation.evaluators.query;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.studiorailgun.Globals;
|
||||
import org.studiorailgun.conversation.tracking.Conversation;
|
||||
import org.studiorailgun.conversation.tracking.Quote;
|
||||
import org.studiorailgun.knowledge.Node;
|
||||
import org.studiorailgun.knowledge.query.InstanceQuery;
|
||||
import org.studiorailgun.knowledge.query.QualiaQuery;
|
||||
import org.studiorailgun.knowledge.query.filter.PossessionQueryFilter;
|
||||
|
||||
/**
|
||||
* Interrogatives available
|
||||
*/
|
||||
@ -25,4 +35,60 @@ public class Interrogative {
|
||||
WHEN,
|
||||
}
|
||||
|
||||
/**
|
||||
* Evaluates a query of "which"
|
||||
* @param conversation The conversation
|
||||
* @param quote The quote
|
||||
* @param interrogative The interrogative noun
|
||||
* @param items The items noun
|
||||
* @return null
|
||||
*/
|
||||
public static void evalWhichQuery(Conversation conversation, Quote quote, NounStack interrogative, NounStack items){
|
||||
if(QualiaQuery.isQualiaClarificationQuery(interrogative)){
|
||||
Node finalQualifier = InstanceQuery.getConcept(items.indexedWord.originalText());
|
||||
|
||||
if(items.possessive != null){
|
||||
List<Node> qualifierInstances = InstanceQuery.getInstances(finalQualifier);
|
||||
finalQualifier = PossessionQueryFilter.withPossessor(qualifierInstances, Globals.web.getAnchors().getSelfNode());
|
||||
}
|
||||
|
||||
List<Node> qualiaOfInstance = QualiaQuery.getQualiaOfInstance(finalQualifier);
|
||||
|
||||
Node qualiaType = QualiaQuery.getRequestedQualiaType(interrogative);
|
||||
|
||||
conversation.addQuote(quote);
|
||||
conversation.getGoalData().getQueryData().getRecentQueries().add(quote);
|
||||
} else {
|
||||
throw new Error("Unknown query type!");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Evaluates a query of "what"
|
||||
* @param conversation The conversation
|
||||
* @param quote The quote
|
||||
* @param interrogative The interrogative noun
|
||||
* @param items The items noun
|
||||
* @return null
|
||||
*/
|
||||
public static void evalWhatQuery(Conversation conversation, Quote quote, NounStack interrogative, NounStack items){
|
||||
if(QualiaQuery.isQualiaClarificationQuery(interrogative)){
|
||||
Node finalQualifier = InstanceQuery.getConcept(items.indexedWord.originalText());
|
||||
|
||||
if(items.possessive != null){
|
||||
List<Node> qualifierInstances = InstanceQuery.getInstances(finalQualifier);
|
||||
finalQualifier = PossessionQueryFilter.withPossessor(qualifierInstances, Globals.web.getAnchors().getSelfNode());
|
||||
}
|
||||
|
||||
List<Node> qualiaOfInstance = QualiaQuery.getQualiaOfInstance(finalQualifier);
|
||||
|
||||
Node qualiaType = QualiaQuery.getRequestedQualiaType(interrogative);
|
||||
|
||||
conversation.addQuote(quote);
|
||||
conversation.getGoalData().getQueryData().getRecentQueries().add(quote);
|
||||
} else {
|
||||
throw new Error("Unknown query type!");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -77,4 +77,18 @@ public class NounStack {
|
||||
return rVal;
|
||||
}
|
||||
|
||||
public String getInterrogative() {
|
||||
return interrogative;
|
||||
}
|
||||
|
||||
public String getPossessive() {
|
||||
return possessive;
|
||||
}
|
||||
|
||||
public IndexedWord getIndexedWord() {
|
||||
return indexedWord;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@ -0,0 +1,34 @@
|
||||
package org.studiorailgun.conversation.evaluators.query;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
import org.studiorailgun.conversation.tracking.Quote;
|
||||
|
||||
/**
|
||||
* Data about recent queries in the conversation
|
||||
*/
|
||||
public class QueryData {
|
||||
|
||||
/**
|
||||
* The recent queries
|
||||
*/
|
||||
List<Quote> recentQueries = new LinkedList<Quote>();
|
||||
|
||||
/**
|
||||
* Gets the recent queries in the conversation
|
||||
* @return The recent queries
|
||||
*/
|
||||
public List<Quote> getRecentQueries(){
|
||||
return recentQueries;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the quote to the recent queries
|
||||
* @param quote The quote
|
||||
*/
|
||||
public void addQuery(Quote quote){
|
||||
recentQueries.add(quote);
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,12 +1,17 @@
|
||||
package org.studiorailgun.conversation.evaluators.query;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.studiorailgun.Globals;
|
||||
import org.studiorailgun.conversation.parser.NLPParser;
|
||||
import org.studiorailgun.conversation.parser.PennTreebankTagSet;
|
||||
import org.studiorailgun.conversation.tracking.Conversation;
|
||||
import org.studiorailgun.conversation.tracking.Quote;
|
||||
import org.studiorailgun.knowledge.Node;
|
||||
import org.studiorailgun.knowledge.query.InstanceQuery;
|
||||
import org.studiorailgun.knowledge.query.filter.PossessionQueryFilter;
|
||||
|
||||
import edu.stanford.nlp.ling.IndexedWord;
|
||||
import edu.stanford.nlp.semgraph.SemanticGraph;
|
||||
@ -57,13 +62,38 @@ public class QueryEval {
|
||||
//get the two things we're comparing
|
||||
SemanticGraph graph = quote.getGraph();
|
||||
IndexedWord root = graph.getFirstRoot();
|
||||
Set<IndexedWord> dependents = graph.descendants(root);
|
||||
Set<IndexedWord> children = graph.getChildren(root);
|
||||
Iterator<IndexedWord> iterator = children.iterator();
|
||||
IndexedWord firstItem = iterator.next();
|
||||
IndexedWord secondItem = iterator.next();
|
||||
NounStack firstNoun = NounStack.parse(graph, firstItem);
|
||||
NounStack secondNoun = NounStack.parse(graph, secondItem);
|
||||
|
||||
//interrogative error checking
|
||||
if(firstNoun.interrogative != null && secondNoun.interrogative != null){
|
||||
String message = "Comparing two interrogatives!";
|
||||
throw new Error(message);
|
||||
}
|
||||
|
||||
//handle interrogative solving
|
||||
if(firstNoun.interrogative != null || secondNoun.interrogative != null){
|
||||
NounStack interrogativeStack = firstNoun.interrogative != null ? firstNoun : secondNoun;
|
||||
NounStack qualifierStack = firstNoun.interrogative != null ? secondNoun : firstNoun;
|
||||
|
||||
switch(interrogativeStack.interrogative.toLowerCase()){
|
||||
case "which": {
|
||||
Interrogative.evalWhichQuery(conversation, quote, interrogativeStack, qualifierStack);
|
||||
} break;
|
||||
case "what": {
|
||||
Interrogative.evalWhatQuery(conversation, quote, interrogativeStack, qualifierStack);
|
||||
} break;
|
||||
default : {
|
||||
throw new Error("Unhandled interrogative type! " + interrogativeStack.interrogative.toLowerCase());
|
||||
}
|
||||
}
|
||||
|
||||
System.out.println("Turn this into a query");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -1,7 +1,11 @@
|
||||
package org.studiorailgun.conversation.tracking;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
import org.studiorailgun.conversation.evaluators.goal.GoalData;
|
||||
import org.studiorailgun.conversation.evaluators.greet.GreetingData;
|
||||
import org.studiorailgun.conversation.evaluators.query.QueryData;
|
||||
import org.studiorailgun.knowledge.KnowledgeWeb;
|
||||
import org.studiorailgun.knowledge.Node;
|
||||
|
||||
@ -35,6 +39,11 @@ public class Conversation {
|
||||
*/
|
||||
GoalData goalData;
|
||||
|
||||
/**
|
||||
* The history of the conversation
|
||||
*/
|
||||
List<Quote> history;
|
||||
|
||||
/**
|
||||
* Parses the current conversation's data from the knowledge web
|
||||
* @param web The web
|
||||
@ -44,7 +53,7 @@ public class Conversation {
|
||||
Node node = web.getNode(7);
|
||||
|
||||
//find the self
|
||||
ConvParticipant self = new ConvParticipant(web.getSelf());
|
||||
ConvParticipant self = new ConvParticipant(web.getAnchors().getSelfNode());
|
||||
|
||||
//find the other participant
|
||||
ConvParticipant other = new ConvParticipant(web.getNode(4));
|
||||
@ -65,6 +74,7 @@ public class Conversation {
|
||||
this.other = other;
|
||||
this.greetingData = new GreetingData();
|
||||
this.goalData = new GoalData();
|
||||
this.history = new LinkedList<Quote>();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -99,6 +109,22 @@ public class Conversation {
|
||||
this.goalData = goalData;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the history of the conversation
|
||||
* @return The history of the conversation
|
||||
*/
|
||||
public List<Quote> getHistory(){
|
||||
return history;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a quote to the conversation
|
||||
* @param quote The quote
|
||||
*/
|
||||
public void addQuote(Quote quote){
|
||||
this.history.add(quote);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@ -10,6 +10,7 @@ import java.util.Map.Entry;
|
||||
|
||||
import org.studiorailgun.FileUtils;
|
||||
import org.studiorailgun.Globals;
|
||||
import org.studiorailgun.knowledge.anchor.AnchorNodes;
|
||||
|
||||
/**
|
||||
* A knowledge web
|
||||
@ -38,9 +39,15 @@ public class KnowledgeWeb {
|
||||
transient Map<String,List<Integer>> typeRelationLookup;
|
||||
|
||||
/**
|
||||
* The node that represents the current ai
|
||||
* Map of node -> relations where that node is the parent
|
||||
*/
|
||||
int selfId;
|
||||
transient Map<Node,List<Relation>> parentRelations;
|
||||
|
||||
/**
|
||||
* The anchor nodes
|
||||
*/
|
||||
AnchorNodes anchors;
|
||||
|
||||
/**
|
||||
* Child webs
|
||||
*/
|
||||
@ -53,6 +60,7 @@ public class KnowledgeWeb {
|
||||
this.nodes = new HashMap<Integer,Node>();
|
||||
this.relations = new HashMap<Integer,Relation>();
|
||||
this.typeRelationLookup = new HashMap<String,List<Integer>>();
|
||||
this.parentRelations = new HashMap<Node,List<Relation>>();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -70,7 +78,12 @@ public class KnowledgeWeb {
|
||||
Globals.web = rVal;
|
||||
//fix the IDs referenced by the links
|
||||
for(Relation relation : rVal.relations.values()){
|
||||
String lookupId = "node-" + relation.webTag + relation.parent;
|
||||
String lookupId = "";
|
||||
if(relation.parentWeb != null){
|
||||
lookupId = "node-" + relation.parentWeb + relation.parent;
|
||||
} else {
|
||||
lookupId = "node-" + relation.webTag + relation.parent;
|
||||
}
|
||||
int nodeId = crossRelationLookupMap.get(lookupId);
|
||||
relation.parent = nodeId;
|
||||
|
||||
@ -85,6 +98,20 @@ public class KnowledgeWeb {
|
||||
}
|
||||
relation.child = nodeId;
|
||||
}
|
||||
//populate lookup acceleration structures
|
||||
for(Relation relation : rVal.relations.values()){
|
||||
Node parent = relation.getParent();
|
||||
if(rVal.parentRelations.containsKey(parent)){
|
||||
List<Relation> relations = rVal.parentRelations.get(parent);
|
||||
relations.add(relation);
|
||||
} else {
|
||||
List<Relation> relations = new LinkedList<Relation>();
|
||||
relations.add(relation);
|
||||
rVal.parentRelations.put(parent,relations);
|
||||
}
|
||||
}
|
||||
//error check that all anchors are defined
|
||||
Globals.web.getAnchors().errorCheck();
|
||||
return rVal;
|
||||
}
|
||||
|
||||
@ -117,6 +144,29 @@ public class KnowledgeWeb {
|
||||
Relation.idIncrementer++;
|
||||
}
|
||||
rVal.relations = newRelations;
|
||||
//make sure anchors object exists and any values are valid
|
||||
if(rVal.anchors == null){
|
||||
rVal.anchors = new AnchorNodes();
|
||||
} else {
|
||||
if(rVal.anchors.getSelf() != null){
|
||||
int oldId = rVal.anchors.getSelf();
|
||||
String lookupId = "node-" + rVal.getTag() + oldId;
|
||||
int newNodeId = crossRelationLookupMap.get(lookupId);
|
||||
rVal.anchors.setSelf(newNodeId);
|
||||
}
|
||||
if(rVal.anchors.getConcept() != null){
|
||||
int oldId = rVal.anchors.getConcept();
|
||||
String lookupId = "node-" + rVal.getTag() + oldId;
|
||||
int newNodeId = crossRelationLookupMap.get(lookupId);
|
||||
rVal.anchors.setConcept(newNodeId);
|
||||
}
|
||||
if(rVal.anchors.getQualia() != null){
|
||||
int oldId = rVal.anchors.getQualia();
|
||||
String lookupId = "node-" + rVal.getTag() + oldId;
|
||||
int newNodeId = crossRelationLookupMap.get(lookupId);
|
||||
rVal.anchors.setQualia(newNodeId);
|
||||
}
|
||||
}
|
||||
//parse children
|
||||
if(rVal.getChildren() != null && rVal.getChildren().size() > 0){
|
||||
for(String child : rVal.getChildren()){
|
||||
@ -142,6 +192,9 @@ public class KnowledgeWeb {
|
||||
for(Relation relation : child.getRelations()){
|
||||
parent.relations.put(relation.getId(),relation);
|
||||
}
|
||||
|
||||
//hoist anchors from children
|
||||
AnchorNodes.copyToParent(parent.anchors, child.anchors);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -217,14 +270,6 @@ public class KnowledgeWeb {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the node that represents the ai
|
||||
* @return The node
|
||||
*/
|
||||
public Node getSelf(){
|
||||
return this.getNode(this.selfId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the child webs of this web
|
||||
@ -238,4 +283,25 @@ public class KnowledgeWeb {
|
||||
return tag;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the relations where the provided node is the parent of the relationship
|
||||
* @param node The node
|
||||
* @return The list of relations
|
||||
*/
|
||||
public List<Relation> getRelationsOfParentNode(Node node){
|
||||
if(this.parentRelations.containsKey(node)){
|
||||
return this.parentRelations.get(node);
|
||||
} else {
|
||||
return new LinkedList<Relation>();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the anchor nodes for the web
|
||||
* @return The anchor nodes
|
||||
*/
|
||||
public AnchorNodes getAnchors(){
|
||||
return anchors;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -29,6 +29,11 @@ public class Relation {
|
||||
*/
|
||||
int parent;
|
||||
|
||||
/**
|
||||
* The web that contains the parent node
|
||||
*/
|
||||
String parentWeb;
|
||||
|
||||
/**
|
||||
* The child of the relationship
|
||||
*/
|
||||
@ -77,6 +82,14 @@ public class Relation {
|
||||
return this.childWeb;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the tag for the web the parent belongs to (can be null or empty string if the web is the same as the parent)
|
||||
* @return The tag for the web
|
||||
*/
|
||||
public String getParentWeb(){
|
||||
return this.parentWeb;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@ -0,0 +1,136 @@
|
||||
package org.studiorailgun.knowledge.anchor;
|
||||
|
||||
import org.studiorailgun.Globals;
|
||||
import org.studiorailgun.knowledge.Node;
|
||||
|
||||
/**
|
||||
* Anchor nodes for the rest of the web
|
||||
*/
|
||||
public class AnchorNodes {
|
||||
|
||||
/**
|
||||
* The node that represents the self
|
||||
*/
|
||||
Integer self;
|
||||
|
||||
/**
|
||||
* The node that represents the idea of a concept
|
||||
*/
|
||||
Integer concept;
|
||||
|
||||
/**
|
||||
* The concept of a qualia
|
||||
*/
|
||||
Integer qualia;
|
||||
|
||||
/**
|
||||
* Gets the self
|
||||
* @return The self node
|
||||
*/
|
||||
public Node getSelfNode() {
|
||||
if(self == null){
|
||||
return null;
|
||||
}
|
||||
return Globals.web.getNode(self);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the self node ID
|
||||
* @param id The self node's ID
|
||||
*/
|
||||
public void setSelf(int id) {
|
||||
this.self = id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the id for the self node
|
||||
* @return The id
|
||||
*/
|
||||
public Integer getSelf(){
|
||||
return self;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the idea of a concept
|
||||
* @return The idea of a concept
|
||||
*/
|
||||
public Node getConceptNode() {
|
||||
if(concept == null){
|
||||
return null;
|
||||
}
|
||||
return Globals.web.getNode(concept);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the concept node
|
||||
* @param id The concept node
|
||||
*/
|
||||
public void setConcept(int id){
|
||||
this.concept = id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the id for the concept node
|
||||
* @return The id for the concept node
|
||||
*/
|
||||
public Integer getConcept(){
|
||||
return concept;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the idea of a qualia
|
||||
* @return The idea of a qualia
|
||||
*/
|
||||
public Node getQualiaNode() {
|
||||
if(qualia == null){
|
||||
return null;
|
||||
}
|
||||
return Globals.web.getNode(qualia);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the qualia node
|
||||
* @param id The qualia node
|
||||
*/
|
||||
public void setQualia(int id){
|
||||
this.qualia = id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the id for the qualia node
|
||||
* @return The id for the qualia node
|
||||
*/
|
||||
public Integer getQualia(){
|
||||
return qualia;
|
||||
}
|
||||
|
||||
/**
|
||||
* Copies anchor nodes from the child to the parent
|
||||
* @param parentAnchors The parent anchors
|
||||
* @param childAnchors The child anchors
|
||||
*/
|
||||
public static void copyToParent(AnchorNodes parentAnchors, AnchorNodes childAnchors){
|
||||
if(childAnchors.getConcept() != null){
|
||||
parentAnchors.setConcept(childAnchors.getConcept());
|
||||
}
|
||||
if(childAnchors.getSelf() != null){
|
||||
parentAnchors.setSelf(childAnchors.getSelf());
|
||||
}
|
||||
if(childAnchors.getQualia() != null){
|
||||
parentAnchors.setQualia(childAnchors.getQualia());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks for errors in the anchor definitions
|
||||
*/
|
||||
public void errorCheck(){
|
||||
if(self == null){
|
||||
throw new Error("Self undefined!");
|
||||
}
|
||||
if(concept == null){
|
||||
throw new Error("Concept undefined!");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,41 @@
|
||||
package org.studiorailgun.knowledge.query;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.studiorailgun.Globals;
|
||||
import org.studiorailgun.knowledge.KnowledgeWeb;
|
||||
import org.studiorailgun.knowledge.Node;
|
||||
import org.studiorailgun.knowledge.Relation;
|
||||
import org.studiorailgun.knowledge.query.filter.NameQueryFilter;
|
||||
import org.studiorailgun.knowledge.types.RelationTypes;
|
||||
|
||||
/**
|
||||
* Queries for dealing with instances of nodes
|
||||
*/
|
||||
public class InstanceQuery {
|
||||
|
||||
/**
|
||||
* Gets the instances of a node
|
||||
* @param web The web
|
||||
* @param parent The parent node
|
||||
* @return The list of instances of that node
|
||||
*/
|
||||
public static List<Node> getInstances(Node parent){
|
||||
List<Relation> relations = Globals.web.getRelationsOfParentNode(parent);
|
||||
return relations.stream().filter(relation -> relation.getName().equals(RelationTypes.INSTANCE_OF)).map(relation -> relation.getChild()).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a concept by its name
|
||||
* @param web The web
|
||||
* @param conceptName The name of the concept
|
||||
* @return The concept
|
||||
*/
|
||||
public static Node getConcept(String conceptName){
|
||||
Node concept = Globals.web.getAnchors().getConceptNode();
|
||||
List<Node> concepts = InstanceQuery.getInstances(concept);
|
||||
return NameQueryFilter.withNodeName(concepts, conceptName);
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,24 @@
|
||||
package org.studiorailgun.knowledge.query;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.studiorailgun.Globals;
|
||||
import org.studiorailgun.knowledge.Node;
|
||||
import org.studiorailgun.knowledge.types.RelationTypes;
|
||||
|
||||
/**
|
||||
* Queries based around possession
|
||||
*/
|
||||
public class PossessionQuery {
|
||||
|
||||
/**
|
||||
* Gets all the child nodes that this node possesses
|
||||
* @param parent The parent node
|
||||
* @return The child nodes that are possessed by this node
|
||||
*/
|
||||
public static List<Node> getPossessions(Node parent){
|
||||
return Globals.web.getRelationsOfParentNode(parent).stream().filter(relation -> relation.getName().equals(RelationTypes.POSSESSION_OF)).map(relation -> relation.getChild()).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,50 @@
|
||||
package org.studiorailgun.knowledge.query;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.studiorailgun.Globals;
|
||||
import org.studiorailgun.conversation.evaluators.query.NounStack;
|
||||
import org.studiorailgun.knowledge.Node;
|
||||
import org.studiorailgun.knowledge.query.filter.NameQueryFilter;
|
||||
import org.studiorailgun.knowledge.types.RelationTypes;
|
||||
|
||||
/**
|
||||
* Performs a qualia query
|
||||
*/
|
||||
public class QualiaQuery {
|
||||
|
||||
/**
|
||||
* Checks if this noun stack is querying for a qualia
|
||||
* @param interrogativeStack The interrogative noun stack
|
||||
* @return true if it is a qualia query, false otherwise
|
||||
*/
|
||||
public static boolean isQualiaClarificationQuery(NounStack interrogativeStack){
|
||||
String originalWord = interrogativeStack.getIndexedWord().originalText();
|
||||
List<Node> nodes = InstanceQuery.getInstances(Globals.web.getAnchors().getQualiaNode());
|
||||
Node rVal = NameQueryFilter.withNodeName(nodes, originalWord);
|
||||
return rVal != null;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets the type of qualia requested by the interrogative stack
|
||||
* @param interrogativeStack The noun stack containing the qualia type
|
||||
* @return The qualia type
|
||||
*/
|
||||
public static Node getRequestedQualiaType(NounStack interrogativeStack){
|
||||
String originalWord = interrogativeStack.getIndexedWord().originalText();
|
||||
List<Node> nodes = InstanceQuery.getInstances(Globals.web.getAnchors().getQualiaNode());
|
||||
return NameQueryFilter.withNodeName(nodes, originalWord);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets all the qualia of an instance
|
||||
* @param inst The instance
|
||||
* @return The qualia
|
||||
*/
|
||||
public static List<Node> getQualiaOfInstance(Node inst){
|
||||
return Globals.web.getRelationsOfParentNode(inst).stream().filter(relation -> relation.getName().equals(RelationTypes.QUALIA_OF)).map(relation -> relation.getChild()).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,24 @@
|
||||
package org.studiorailgun.knowledge.query.filter;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.studiorailgun.knowledge.Node;
|
||||
|
||||
/**
|
||||
* Node query filters based around names
|
||||
*/
|
||||
public class NameQueryFilter {
|
||||
|
||||
/**
|
||||
* Filters a set of nodes to a singleton based on a name
|
||||
*/
|
||||
public static Node withNodeName(List<Node> nodes, String name){
|
||||
List<Node> filtered = nodes.stream().filter(node -> !node.getName().equals(name)).collect(Collectors.toList());
|
||||
if(filtered.size() != 1){
|
||||
throw new UnsupportedOperationException("TODO: handle ambiguous case");
|
||||
}
|
||||
return filtered.get(0);
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,28 @@
|
||||
package org.studiorailgun.knowledge.query.filter;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.studiorailgun.knowledge.Node;
|
||||
import org.studiorailgun.knowledge.query.PossessionQuery;
|
||||
|
||||
/**
|
||||
* Query filters based on possession relationships
|
||||
*/
|
||||
public class PossessionQueryFilter {
|
||||
|
||||
/**
|
||||
* Filters a set of nodes to a singleton based on a name
|
||||
*/
|
||||
public static Node withPossessor(List<Node> nodes, Node possessor){
|
||||
List<Node> possessions = PossessionQuery.getPossessions(possessor);
|
||||
List<Node> filtered = nodes.stream().filter(node -> {
|
||||
return possessions.contains(node);
|
||||
}).collect(Collectors.toList());
|
||||
if(filtered.size() != 1){
|
||||
throw new UnsupportedOperationException("TODO: handle ambiguous case");
|
||||
}
|
||||
return filtered.get(0);
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,24 @@
|
||||
package org.studiorailgun.knowledge.types;
|
||||
|
||||
/**
|
||||
* All relation types
|
||||
*/
|
||||
public class RelationTypes {
|
||||
|
||||
/**
|
||||
* An instance relationship
|
||||
*/
|
||||
public static final String INSTANCE_OF = "instanceOf";
|
||||
|
||||
|
||||
/**
|
||||
* A possession relationship
|
||||
*/
|
||||
public static final String POSSESSION_OF = "possessionOf";
|
||||
|
||||
/**
|
||||
* A qualia of instance relationship
|
||||
*/
|
||||
public static final String QUALIA_OF = "qualiaOf";
|
||||
|
||||
}
|
||||
@ -12,8 +12,8 @@ public class ConvLoadingTests {
|
||||
@Test
|
||||
public void testLoadConversation(){
|
||||
Globals.init("./data/webs/test/web.json");
|
||||
assertEquals(Globals.web.getSelf(), Globals.conversation.getSelf().getData());
|
||||
assertNotEquals(Globals.web.getSelf(), Globals.conversation.getOther().getData());
|
||||
assertEquals(Globals.web.getAnchors().getSelfNode(), Globals.conversation.getSelf().getData());
|
||||
assertNotEquals(Globals.web.getAnchors().getSelfNode(), Globals.conversation.getOther().getData());
|
||||
}
|
||||
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user