/** * Produces a response to an "internal" input sentence -- i.e., an input that has been * produced by a <code>srai</code>. * * <p>The main differences between this and {@link * #getResponse(String,String,TemplateParser,boolean,Responder)} are that this method takes an * already-existing <code>TemplateParser</code>, <i>doesn't</i> take a <code>Responder</code>, and * assumes that the inputs have already been normalized. * * @see {@link #getResponse(String,String,TemplateParser,boolean,Responder)} * @param input the input sentence * @param userid the userid requesting the response * @param botid the botid from which to get the response * @param parser the parser object to update when generating the response */ public static String getInternalResponse( String input, String userid, String botid, TemplateParser parser) { // Get the requested bot. Bot bot = Bots.getBot(botid); // Ready the that and topic predicates for constructing the match path. ArrayList thatSentences = bot.sentenceSplit(PredicateMaster.get(THAT, 1, userid, botid)); String that = InputNormalizer.patternFitIgnoreCase((String) thatSentences.get(thatSentences.size() - 1)); if (that.equals(EMPTY_STRING) || that.equals(PREDICATE_EMPTY_DEFAULT)) { that = ASTERISK; } String topic = InputNormalizer.patternFitIgnoreCase(PredicateMaster.get(TOPIC, userid, botid)); if (topic.equals(EMPTY_STRING) || topic.equals(PREDICATE_EMPTY_DEFAULT)) { topic = ASTERISK; } return getMatchResult(input, that, topic, userid, botid, parser); }
/** * Gets the match result from the Graphmaster. * * @param input * @param that * @param topic * @param userid * @param botid * @param parser * @param timeout whether to control the match attempt with a timeout thread */ private static String getMatchResult( String input, String that, String topic, String userid, String botid, TemplateParser parser) { // Always show the input path (in any case, if match trace is on). if (SHOW_MATCH_TRACE) { Trace.userinfo( PredicateMaster.get(Globals.getClientNamePredicate(), userid, botid) + '>' + SPACE + input + SPACE + Graphmaster.PATH_SEPARATOR + SPACE + that + SPACE + Graphmaster.PATH_SEPARATOR + SPACE + topic + SPACE + Graphmaster.PATH_SEPARATOR + SPACE + botid); } // Create a case-insensitive pattern-fitted version of the input. String inputIgnoreCase = InputNormalizer.patternFitIgnoreCase(input); Match match = null; try { match = Graphmaster.match(InputNormalizer.patternFitIgnoreCase(input), that, topic, botid); } catch (NoMatchException e) { Log.userinfo(e.getMessage(), Log.CHAT); return EMPTY_STRING; } if (match == null) { Log.userinfo("No match found for input \"" + input + "\".", Log.CHAT); return EMPTY_STRING; } if (SHOW_MATCH_TRACE) { Trace.userinfo(LABEL_MATCH + match.getPath()); Trace.userinfo(LABEL_FILENAME + QUOTE_MARK + match.getFileName() + QUOTE_MARK); } ArrayList stars = match.getInputStars(); if (stars.size() > 0) { parser.setInputStars(stars); } stars = match.getThatStars(); if (stars.size() > 0) { parser.setThatStars(stars); } stars = match.getTopicStars(); if (stars.size() > 0) { parser.setTopicStars(stars); } String template = match.getTemplate(); String reply = null; try { reply = parser.processResponse(template); } catch (ProcessorException e) { // Log the error message. Log.userinfo(e.getMessage(), Log.ERROR); // Set response to empty string. return EMPTY_STRING; } // Record activation, if targeting is in use. // Needs review in light of multi-bot update if (USE_TARGETING) { Nodemapper matchNodemapper = match.getNodemapper(); if (matchNodemapper == null) { Trace.devinfo("Match nodemapper is null!"); } else { Set activations = (Set) matchNodemapper.get(Graphmaster.ACTIVATIONS); if (activations == null) { activations = new HashSet(); } String path = match.getPath() + SPACE + Graphmaster.PATH_SEPARATOR + SPACE + inputIgnoreCase + SPACE + Graphmaster.PATH_SEPARATOR + SPACE + that + SPACE + Graphmaster.PATH_SEPARATOR + SPACE + topic + SPACE + Graphmaster.PATH_SEPARATOR + SPACE + botid + SPACE + Graphmaster.PATH_SEPARATOR + SPACE + reply; if (!activations.contains(path)) { activations.add(path); match.getNodemapper().put(Graphmaster.ACTIVATIONS, activations); Graphmaster.activatedNode(match.getNodemapper()); } } } return reply; }
/** * Gets the list of replies to some input sentences. Assumes that the sentences have already had * all necessary pre-processing and substitutions performed. * * @param sentenceList the input sentences * @param userid the userid requesting the replies * @param botid * @return the list of replies to the input sentences */ private static ArrayList getReplies(ArrayList sentenceList, String userid, String botid) { // All replies will be assembled in this ArrayList. ArrayList replies = new ArrayList(sentenceList.size()); // Get the requested bot. Bot bot = Bots.getBot(botid); // Ready the that and topic predicates for constructing the match path. ArrayList thatSentences = bot.sentenceSplit(PredicateMaster.get(THAT, 1, userid, botid)); String that = InputNormalizer.patternFitIgnoreCase((String) thatSentences.get(thatSentences.size() - 1)); if (that.equals(EMPTY_STRING) || that.equals(PREDICATE_EMPTY_DEFAULT)) { that = ASTERISK; } String topic = InputNormalizer.patternFitIgnoreCase(PredicateMaster.get(TOPIC, userid, botid)); if (topic.equals(EMPTY_STRING) || topic.equals(PREDICATE_EMPTY_DEFAULT)) { topic = ASTERISK; } Iterator sentences = sentenceList.iterator(); // We might use this to track matching statistics. long time = 0; // If match trace info is on, mark the time just before matching starts. if (SHOW_MATCH_TRACE) { time = System.currentTimeMillis(); } // Get a reply for each sentence. while (sentences.hasNext()) { replies.add(getReply((String) sentences.next(), that, topic, userid, botid)); } // Increment the (static) response count. responseCount++; ; // If match trace info is on, produce statistics about the response time. if (SHOW_MATCH_TRACE) { // Mark the time that processing is finished. time = System.currentTimeMillis() - time; // Calculate the average response time. totalTime += time; avgResponseTime = (float) totalTime / (float) responseCount; Trace.userinfo( RESPONSE_SPACE + responseCount + SPACE_IN_SPACE + time + MS_AVERAGE + avgResponseTime + MS); } // Invoke targeting if appropriate. if (responseCount % TARGET_SKIP == 0) { if (USE_TARGETING) { Graphmaster.checkpoint(); } } // If no replies, return an empty string. if (replies.size() == 0) { replies.add(EMPTY_STRING); } return replies; }