SetTable.java
Go to the documentation of this file.
00001 package edu.tum.cs.ias.knowrob.mod_dialog.queries;
00002 
00003 import java.io.IOException;
00004 import java.util.Arrays;
00005 import java.util.HashMap;
00006 import java.util.Vector;
00007 
00008 import edu.tum.cs.ias.knowrob.mod_dialog.DialogModule;
00009 import edu.tum.cs.logic.parser.ParseException;
00010 import edu.tum.cs.probcog.InferenceResult;
00011 import edu.tum.cs.probcog.Model;
00012 import edu.tum.cs.probcog.ModelPool;
00013 import edu.tum.cs.util.StringTool;
00014 
00015 public class SetTable extends DialogQuery {
00016 
00017         protected int participants;
00018         protected String mealType;
00019         protected String[] people;
00020         protected HashMap<Integer,String> participant2name = new HashMap<Integer,String>();
00021         protected HashMap<String,Integer> name2participant = new HashMap<String,Integer>();
00022         protected Vector<String[]> evidence = new Vector<String[]>();
00023         protected ModelPool pool;
00024         protected Model model;
00025         protected String regexUtensil, regexGood;
00026         protected HashMap<String,String> utensils = new HashMap<String,String>();
00027         protected HashMap<String,String> goods = new HashMap<String,String>();
00028 
00029         public SetTable(DialogModule mod) throws IOException, ParseException, Exception {
00030                 super(mod);             
00031                 registerStates();
00032                 pool = new ModelPool(DialogModule.findRosPackage("srldb") + "/models/models.xml");
00033                 model = pool.getModel("tableSetting_fall09");
00034                 
00035                 // build up some domain data
00036                 Vector<String[]> doms = model.getDomains();
00037                 for(String[] dom : doms) {
00038                         if(dom[0].equals("domutensilT")) {
00039                                 for(int i = 1; i < dom.length; i++)
00040                                         utensils.put(dom[i].toLowerCase(), dom[i]);
00041                                 regexUtensil = "(?:" + StringTool.join("|", utensils.keySet()) + ")";
00042                         }
00043                         if(dom[0].equals("objType_g")) {
00044                                 for(int i = 1; i < dom.length; i++)
00045                                         goods.put(dom[i].toLowerCase(), dom[i]);
00046                                 regexGood = "(?:" + StringTool.join("|", goods.keySet()) + ")";
00047                         }
00048                 }
00049                 System.out.println("consumables: " + StringTool.join("|", goods.values()));
00050                 System.out.println("usables: " + StringTool.join("|", utensils.values()));
00051         }
00052         
00053         private void registerStates() {
00054                 this.dialog_module.registerState("set_table_num_participants");
00055                 this.dialog_module.registerState("set_table_family_members");
00056                 this.dialog_module.registerState("set_table_meal_type");
00057                 this.dialog_module.registerState("hypo_meal");
00058         }
00059         
00060         public static String capitalize(String s) {
00061                 return s.substring(0, 1).toUpperCase() + s.substring(1);
00062         }
00063 
00064         @Override
00065         public String process(String q) throws IOException, ParseException, Exception {
00066                 q = q.toLowerCase().replace(".", "").replace("?", "");
00067                 
00068                 String regexPersonName = "(?:anna|bert|dorothy|emily|charly)";
00069                 String regexMealType = "(?:breakfast|lunch|dinner)";
00070                 String regexNumber = "(?:one|two|three|four)";
00071                 String regexGeneralParticipant = String.format("(?:%s|participant %s)", regexPersonName, regexNumber);
00072         
00073                 if(match("start over", q)) {
00074                         setTopLevelState();
00075                         return "OK.";
00076                 }
00077                 
00078                 if(this.haveState(DialogModule.TOP_LEVEL_STATE)) {
00079                         evidence.clear();
00080                         
00081                         // initiate table setting
00082                         if(match("(?:please )?set the table", q)) {
00083                                 setState("set_table_meal_type");
00084                                 return "OK. What kind of meal will it be?";
00085                         }
00086                         
00087                         // query food consumption preferences
00088                         if(match(String.format("what does (%s) like to have for (%s)", regexPersonName, regexMealType), q)) {
00089                                 addEvidence("takesPartIn", "P1", "M");
00090                                 String name = capitalize(matcher.group(1));
00091                                 addEvidence("name", "P1", name);
00092                                 addEvidence("mealT", "M", capitalize(matcher.group(2)));
00093                                 Vector<InferenceResult> res = query("consumesAnyIn");
00094                                 String[] phrases = new String[]{"Almost always", "Quite often", "Sometimes"};
00095                                 Double[] probs = new Double[]{0.85, 0.5, 0.00001};
00096                                 String text = "";
00097                                 for(int i = 0; i < phrases.length; i++) {
00098                                         Vector<String> v = new Vector<String>();
00099                                         for(InferenceResult r : res) {
00100                                                 double upper = i == 0 ? 1.0 : probs[i-1];
00101                                                 if(r.probability >= probs[i] && r.probability < upper) {
00102                                                         v.add(r.params[1]);
00103                                                 }                                               
00104                                         }
00105                                         if(!v.isEmpty()) {
00106                                                 if(text != "") text += " ";
00107                                                 text += phrases[i] + ", " + name + " likes to have " + StringTool.join(", ", v) + ".";                                          
00108                                         }
00109                                 }       
00110                                 return text;
00111                         }
00112                         
00113                         // initiate hypothetical reasoning
00114                         if(match("suppose there was a meal", q)) {
00115                                 setState("hypo_meal");
00116                                 participants = 0;
00117                                 return "OK. How many participants were there?";
00118                         }
00119                 }
00120                 
00121                 if(haveState("hypo_meal")) {
00122                         if(participants == 0) {
00123                                 if(match(regexNumber, q)) {
00124                                         participants = parseNumber(matcher.group());
00125                                         if(participants > 0) {
00126                                                 for(int i = 1; i <= participants; i++)
00127                                                         addEvidence("takesPartIn", "P" + i, "M");
00128                                                 return "OK. What else do we know about the meal?";
00129                                         }
00130                                         return "I don't understand. How many participants were there?";
00131                                 }
00132                                 return "I don't understand. How many participants were there?"; 
00133                         }
00134                         else {
00135                                 System.out.println("participants = " + participants);
00136                                 if(match("participant (" + regexNumber + ") was (" + regexPersonName + ")", q)) {
00137                                         int no = parseNumber(matcher.group(1));
00138                                         String name = matcher.group(2);                                                                         
00139                                         this.name2participant.put(name, no);
00140                                         name = capitalize(name);
00141                                         addEvidence("name", "P" + no, name);
00142                                         this.participant2name.put(no, name);
00143                                         return "OK. Anything else?";
00144                                 }
00145                                 else if(match("(" + regexGeneralParticipant + ") used (?:an? )?(" + regexUtensil + ")", q)) {
00146                                         Integer no = getGeneralParticipant(matcher.group(1));
00147                                         if(no == null)
00148                                                 return "I wasn't told that " + matcher.group(1) + " is one of the participants.";
00149                                         String utensil = utensils.get(matcher.group(2));
00150                                         addEvidence("usesAnyIn", "P" + no, utensil, "M");
00151                                         return "OK. Anything else?";
00152                                 }
00153                                 else if(match("(" + regexGeneralParticipant + ") consumed (?:an? )?(" + regexGood + ")", q)) {
00154                                         Integer no = getGeneralParticipant(matcher.group(1));
00155                                         if(no == null)
00156                                                 return "I wasn't told that " + matcher.group(1) + " is one of the participants.";
00157                                         String good = goods.get(matcher.group(2));
00158                                         addEvidence("consumesAnyIn", "P" + no, good, "M");
00159                                         return "OK. Anything else?";
00160                                 }
00161                                 else if(match("the type of the meal was (" + regexMealType + ")", q)) {
00162                                         String type = capitalize(matcher.group(1));
00163                                         addEvidence("mealT", "M", type);
00164                                         return "OK. Anything else?";
00165                                 }
00166                                 else if(match("what type of meal was it", q)) {
00167                                         Vector<InferenceResult> res = query("mealT");
00168                                         return this.extractResults(res, 1);
00169                                 }
00170                                 else if(match("what time was it", q)) {
00171                                         Vector<InferenceResult> res = query("timeT");
00172                                         return this.extractResults(res, 1);
00173                                 }
00174                                 else if(match("who was participant (" + regexNumber + ")", q)) {
00175                                         int no = parseNumber(matcher.group(1));
00176                                         Vector<InferenceResult> res = query("name(P" + no + ")");
00177                                         return this.extractResults(res, 1);
00178                                 }
00179                                 else if(match(String.format("what did (%s) consume", regexGeneralParticipant), q)) {
00180                                         Integer no = getGeneralParticipant(matcher.group(1));
00181                                         if(no == null)
00182                                                 return "I wasn't told that " + matcher.group(1) + " is one of the participants.";
00183                                         Vector<InferenceResult> res = query("consumesAnyIn(P" + no + ",x,M)");
00184                                         return this.extractResults(res, 1);
00185                                 }
00186                                 else if(match("what did (" + regexGeneralParticipant + ") use", q)) {
00187                                         Integer no = getGeneralParticipant(matcher.group(1));
00188                                         if(no == null)
00189                                                 return "I wasn't told that " + matcher.group(1) + " is one of the participants.";
00190                                         Vector<InferenceResult> res = query("usesAnyIn(P" + no + ",x,M)");
00191                                         return this.extractResults(res, 1);
00192                                 }
00193                                 else
00194                                         return "I don't understand. What else do we know about the meal?";
00195                         }
00196                 }
00197                 
00198                 if(haveState("set_table_meal_type")) {
00199                         if(match(regexMealType, q)) {
00200                                 regexMealType = capitalize(matcher.group());
00201                                 setState("set_table_num_participants");
00202                                 return "OK. How many people will participate?";
00203                         }
00204                 }
00205                 
00206                 if(haveState("set_table_num_participants")) {
00207                         if(match("one|two|three|four", q)) {
00208                                 participants = parseNumber(matcher.group());
00209                                 setState("set_table_family_members");
00210                                 return "OK. Anyone family members I know?";
00211                         }
00212                         else {
00213                                 return "I don't understand. How many people will participate?";
00214                         }
00215                 }
00216                 
00217                 if(haveState("set_table_family_members")) {
00218                         people = null;                  
00219                         String connect = "(?: and |,\\s?)";
00220                         if(match(String.format("(%s(?:%s%s)*)", regexPersonName, connect, regexPersonName), q)) {
00221                                 people = matcher.group(1).split(connect);
00222                                 for(int i = 0; i < people.length; i++)
00223                                         people[i] = capitalize(people[i]);
00224                         }
00225                         else if(match("no|none", q)) {
00226                                 people = null;
00227                         }
00228                         else {
00229                                 return "I don't understand. Please name the family members or say 'none' if none will participate?";
00230                         }
00231                         
00232                         setTopLevelState();                     
00233                         
00234                         return querySetTable();
00235                 }
00236                 
00237                 System.out.println("No match in SetTable");
00238                 
00239                 return null;
00240         }       
00241         
00242         protected Integer getGeneralParticipant(String s) {
00243                 if(s.startsWith("participant")) {
00244                         int no = parseNumber(s.substring("participant ".length()));
00245                         if(no == 0) {                           
00246                                 return null;
00247                         }
00248                         return no;
00249                 }
00250                 Integer no = name2participant.get(s);
00251                 if(no == null)
00252                         System.out.println("tried to retrieve '" + s + "' from " + StringTool.join(",", name2participant.keySet()));
00253                 return no;
00254         }
00255         
00256         protected String extractResults(Vector<InferenceResult> vres, int argNo) {
00257                 StringBuffer ret = new StringBuffer();
00258                 int i = 0; 
00259                 for(InferenceResult res : vres) {
00260                         if(i++ > 0)
00261                                 ret.append(", ");                       
00262                         ret.append(res.params[argNo] + " " + String.format("%.2f", res.probability));
00263                 }
00264                 return ret.toString();
00265         }
00266         
00267         protected static int parseNumber(String no) {
00268                 if(no.equals("one"))
00269                         return 1;
00270                 if(no.equals("two"))
00271                         return 2;
00272                 if(no.equals("three"))
00273                         return 3;
00274                 if(no.equals("four"))
00275                         return 4;
00276                 return 0;
00277         }
00278         
00279         protected String querySetTable() {
00280                 //participants = 2;
00281                 //people = new String[]{"Anna"};
00282                 
00283                 // build evidence
00284                 for(int i = 1; i <= this.participants; i++) {
00285                         String person = "P" + i;
00286                         addEvidence("takesPartIn", person, "M");
00287                         if(people != null && i <= people.length)
00288                                 addEvidence("name", person, people[i-1]);
00289                 }
00290                 addEvidence("mealT", "M", mealType);
00291                 
00292                 // infer
00293                 Vector<InferenceResult> res;
00294                 try {
00295                         res = query("usesAnyIn");
00296                 } 
00297                 catch (Exception e) {
00298                         e.printStackTrace();
00299                         return null;
00300                 } 
00301                 
00302                 String text = "I will provide ";
00303                 int cnt = 0;
00304                 double threshold = 0.4;
00305                 for(InferenceResult r : res) {
00306                         r.print(System.out);
00307                         if(r.probability > threshold) {
00308                                 String name;
00309                                 int i = Integer.parseInt(r.params[0].substring(1));
00310                                 if(people != null && i <= people.length)
00311                                         name = people[i-1];
00312                                 else
00313                                         name = "Participant " + i;
00314                                 String object = r.params[1];
00315                                 if(cnt++ > 0)
00316                                         text += ", ";
00317                                 text += String.format("a %s for %s", object, name);
00318                         }
00319                 }
00320                 
00321                 return text;
00322         }
00323         
00324         protected void addEvidence(String... items) {
00325                 evidence.add(items);
00326         }
00327         
00328         protected Vector<InferenceResult> query(String... queries) throws IOException, ParseException, Exception {              System.out.println("evidence: " + evidence);
00329                 Model m = this.model;
00330                 m.setEvidence(evidence); 
00331                 m.instantiate(); 
00332                 Vector<InferenceResult> res = m.infer(Arrays.asList(queries));
00333                 
00334                 return res;
00335         }
00336 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Properties Friends


mod_dialog
Author(s): Moritz Tenorth
autogenerated on Tue Apr 16 2013 00:38:37