$search
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 }