コード例 #1
0
        public InputRecognizer(string text, string ruleId, string inputId, string condition, Dictionary <string, Synonym> synonyms, List <InputReplacement> alInputReplacements)
        {
            this.inputReplacements = alInputReplacements;

            System.Text.RegularExpressions.Regex regexVarsEq = new Regex(@"\[.+?=.+?\]");
            System.Text.RegularExpressions.Regex regexVars   = new Regex(@"\[.*?\]");
            System.Text.RegularExpressions.Regex regexSyns   = new Regex(@"\(.*?\)");
            string textReplaced = regexVarsEq.Replace(text, "xx");

            textReplaced = regexVars.Replace(textReplaced, "x");
            textReplaced = regexSyns.Replace(textReplaced, "x");
            textReplaced = textReplaced.Replace("*", "");
            this.length  = textReplaced.Length;

            text = TextToolbox.ReplaceSynonyms(text, synonyms);
            //do this last because replacements haven't been applied to synonyms
            text = TextToolbox.ReplaceOnInput(text, alInputReplacements, out this.bIsCapture);

            string pattern = TextToolbox.TextToPattern(text);

            this.regex = new Regex(pattern, /*RegexOptions.Compiled | */ RegexOptions.ExplicitCapture | RegexOptions.IgnoreCase);           //TODO: Does the IgnoreCase Work?

            //regex.IsMatch("x");
            this.ruleId    = ruleId;
            this.inputId   = inputId;
            this.condition = condition;

            if (InputRecognizer.random == null)
            {
                InputRecognizer.random = new Random();
            }
        }
コード例 #2
0
        }//ReplaceOnInput(string text, List<InputReplacement> replacements)

        public static string ReplaceSynonyms(string input, Dictionary <string, Synonym> synonyms)
        {
            int start = input.IndexOf("(");
            int end;

            while (start != -1)
            {
                end = TextToolbox.FindNextMatchingChar(input, start);
                if (end != -1)
                {
                    string synonymName = input.Substring(start + 1, end - start - 1).Trim().ToLower();
                    if (synonyms.ContainsKey(synonymName))
                    {
                        input = input.Substring(0, start + 1) + ((Synonym)synonyms[synonymName]).GetPhrases() + input.Substring(end);
                    }
                    else
                    {
                        input = input.Substring(0, start) + "(" + synonymName + ")" + input.Substring(end + 1);
                    }
                    start = input.IndexOf("(", start + 1);
                }
                else                //there's an error with this input, it won't compile
                {
                    //TODO: log an error somewhere?
                    return("");
                }
            }
            return(input);
        }//replaceSynonyms(string input, Dictionary<string, Synonym> synonymGroups)
コード例 #3
0
        }//replaceSynonyms(string input, Dictionary<string, Synonym> synonymGroups)

        public static string ReplaceOutputSynonyms(string text, Dictionary <string, Synonym> synonyms)
        {
            int start = text.IndexOf("(");
            int end;

            while (start != -1)
            {
                if (!TextToolbox.IsEscaped(text, start))
                {
                    end = TextToolbox.FindNextMatchingChar(text, start);
                    if (end != -1)
                    {
                        string synonymName = text.Substring(start + 1, end - start - 1).Trim().ToLower();
                        if (synonyms.ContainsKey(synonymName) && !TextToolbox.IsInCommand(text, start, end - start))
                        {
                            Synonym syn = ((Synonym)synonyms[synonymName]);
                            if (syn.Phrases.Count > 0)
                            {
                                Random rand = new Random();
                                int    pick = rand.Next(syn.Phrases.Count);
                                if (end == text.Length - 1)                               //the end is the end
                                {
                                    text = text.Substring(0, start) + ((Phrase)syn.Phrases[pick]).Text;
                                }
                                else
                                {
                                    text = text.Substring(0, start) + ((Phrase)syn.Phrases[pick]).Text + text.Substring(end + 1);
                                }
                            }
                            else
                            {
                                text = text.Substring(0, start + 1) + synonymName + text.Substring(end);
                            }
                        }
                        start = text.IndexOf("(", start + 1);
                    }
                    else
                    {
                        //TODO: log an error somewhere?
                        return(text);
                    }
                }
                else                 //it's escaped \(..
                {
                    //remove the '\'
                    text = text.Remove(start - 1, 1);
                    //find the next start
                    if (start >= text.Length - 1)                   //the old start is now at the end
                    {
                        start = -1;
                    }
                    else
                    {
                        start = text.IndexOf("(", start);
                    }
                }
            }            //while
            return(text);
        }//replaceSynonyms(string input, Dictionary<string, Synonym> synonymGroups)
コード例 #4
0
        /// <summary>
        /// Uses given InputReplacements to change text
        /// </summary>
        /// <param name="text">change text</param>
        /// <param name="inputReplacements">list of Replacements</param>
        /// <returns>resulting replaced text</returns>
        public static string ReplaceOnInput(string text, List <InputReplacement> replacements, out bool bIsCapture)
        {
            StringBuilder sb = new StringBuilder();

            if (text.IndexOf("[") == -1)
            {
                bIsCapture = false;
                if (replacements.Count > 0)
                {
                    int depth = 0;
                    for (int i = 0; i < text.Length; i++)
                    {
                        bool replaced = false;
                        if (text[i] == '[')
                        {
                            depth++;
                        }
                        else if (text[i] == ']')
                        {
                            depth--;
                        }
                        else if (depth == 0)
                        {
                            foreach (InputReplacement ir in replacements)
                            {
                                if (i < text.Length - ir.TextToFind.Length + 1 &&
                                    ir.TextToFind == text.Substring(i, ir.TextToFind.Length))
                                {
                                    replaced = true;
                                    sb.Append(ir.TextToInput);
                                    i += ir.TextToFind.Length - 1;
                                    break;               //can only replace with one thing
                                }
                            }                            //foreach(InputReplacement repl in inputReplacements)
                        }
                        if (!replaced)
                        {
                            sb.Append(text[i]);
                        }
                    }               //for(int i = 0; i < text.Length; i++)
                }
                else                //if we don't have any input replacements, just do the default (remove accents)
                {
                    //TODO: add if(prefs.useDefaultInputReplacements)
                    sb.Append(TextToolbox.ApplyDefaultInputReplacements(text));
                }
            }
            else
            {
                bIsCapture = true;
                sb.Append(text);                //if it is a capture, we won't replace anything
            }

            return(sb.ToString());
        }//ReplaceOnInput(string text, List<InputReplacement> replacements)
コード例 #5
0
 public static int FindNextUnescapedChar(string text, char ch, int start)
 {
     for (int i = start; i < text.Length; i++)
     {
         if (text[i] == ch && !TextToolbox.IsEscaped(text, i))
         {
             return(i);
         }
     }
     return(-1);
 }
コード例 #6
0
        public static string ApplyDefaultInputReplacements(string text)
        {
            //ÀÁÂÃÄÅàáâãäåÆæÇçÈÉÊËèéêëÌÍÎÏìíîïÑñÒÓÔÕÖòóôõöÙÚÛÜùúûüÝýÿ.!?,"':;
            StringBuilder           sb = new StringBuilder(text);
            List <InputReplacement> alDefaultInputReplacements = TextToolbox.GetDefaultInputReplacements();

            foreach (InputReplacement ir in alDefaultInputReplacements)
            {
                sb.Replace(ir.TextToFind, ir.TextToInput);
            }

            return(sb.ToString());
        }        //ApplyDefaultInputReplacements(string text)
コード例 #7
0
        }        //doTextReplacements(string text)

        public string DoAgentTextReplacements(string text)
        {
            foreach (Replacement r in this.replacements)
            {
                if (r.TextToFind != null && r.TextToFind != "")
                {
                    int pos = text.IndexOf(r.TextToFind);
                    while (pos != -1)
                    {
                        if (!TextToolbox.IsInCommand(text, pos, r.TextToFind.Length))
                        {
                            if (pos + r.TextToFind.Length < text.Length - 1)
                            {
                                text = text.Substring(0, pos)
                                       + r.TextForAgent
                                       + text.Substring(pos + r.TextToFind.Length);
                            }
                            else
                            {
                                text = text.Substring(0, pos)
                                       + r.TextForAgent;
                            }
                        }
                        if (pos < text.Length - 1)
                        {
                            pos = text.IndexOf(r.TextToFind, pos + 1);
                        }
                        else
                        {
                            pos = -1;
                        }
                    }    //while
                }        //if
            }            //foreach

            return(text);
        }        //doAgentTextReplacements(string text)
コード例 #8
0
        /*
         * Accessor Methods
         */

        public string GetNewSynoymId()
        {
            return(TextToolbox.GetNewId());
        }
コード例 #9
0
        /*
         * Accessor Methods
         */

        public string GetNewPhraseId()
        {
            return(TextToolbox.GetNewId());
        }
コード例 #10
0
        }        //ApplyDefaultInputReplacements(string text)

        public static int FindNextUnexcapedChar(string text, char ch)
        {
            return(TextToolbox.FindNextUnescapedChar(text, ch, 0));
        }
コード例 #11
0
        }//replaceSynonyms(string input, Dictionary<string, Synonym> synonymGroups)

        public static string ReplaceVars(string text, Hashtable vars)
        {
            int start = text.IndexOf("[");
            int end;

            while (start != -1)
            {
                if (!TextToolbox.IsEscaped(text, start))
                {
                    end = TextToolbox.FindNextMatchingChar(text, start);
                    if (end != -1)
                    {
                        string varName         = TextToolbox.ReplaceVars(text.Substring(start + 1, end - start - 1), vars);
                        string varDefaultValue = "";
                        if (varName.IndexOf(':') != -1)
                        {
                            varDefaultValue = varName.Substring(varName.IndexOf(':') + 1).Trim();
                            varName         = varName.Substring(0, varName.IndexOf(':')).Trim();
                        }
                        varName = varName.Replace(" ", "_");
                        string varValue = (string)vars[varName.ToLower()];
                        if (varValue == null)
                        {
                            varValue = varDefaultValue;
                        }

                        if (end == text.Length - 1)                       //var runs to the end
                        {
                            text  = text.Substring(0, start) + varValue;
                            start = -1;
                        }
                        else
                        {
                            text  = text.Substring(0, start) + varValue + text.Substring(end + 1);
                            start = text.IndexOf("[", start + varValue.Length);
                        }
                    }
                    else                    //there's an error with this input, it won't compile
                    {
                        //TODO: log an error somewhere?
                        return("");
                    }
                }
                else                // [ is escaped
                {
                    //remove the '\'
                    text = text.Remove(start - 1, 1);
                    //find the next start
                    if (start >= text.Length - 1)                   //the old start is now at the end
                    {
                        start = -1;
                    }
                    else
                    {
                        start = text.IndexOf("[", start);
                    }
                }
            }            //while we have more [vars]

            string embCmd = "<mem.get ";

            start = text.IndexOf(embCmd);
            while (start != -1)
            {
                if (!TextToolbox.IsEscaped(text, start))
                {
                    end = TextToolbox.FindNextMatchingChar(text, start);
                    if (end != -1)
                    {
                        string name = text.Substring(start + embCmd.Length, end - start - embCmd.Length);
                        string left = "";
                        if (start > 0)
                        {
                            left = text.Substring(0, start);
                        }
                        string right = "";
                        if (end + 1 != text.Length)
                        {
                            right = text.Substring(end + 1);
                        }
                        text = left + vars[name.ToLower()] + right;
                    }
                    start = text.IndexOf(embCmd);
                }
                else                // < is escaped
                {
                    //remove the '\'
                    text = text.Remove(start - 1, 1);
                    //find the next start
                    if (start >= text.Length - 1)                   //the old start is now at the end
                    {
                        start = -1;
                    }
                    else
                    {
                        start = text.IndexOf(embCmd, start);
                    }
                }
            }            //while we have more <mem.get name>s

            embCmd = "<mem.set ";
            start  = text.IndexOf(embCmd);
            while (start != -1)
            {
                if (!TextToolbox.IsEscaped(text, start))
                {
                    end = TextToolbox.FindNextMatchingChar(text, start);
                    if (end != -1)
                    {
                        string   nameValue = text.Substring(start + embCmd.Length, end - start - embCmd.Length);
                        string   left      = "";
                        string   right     = "";
                        string[] cmdArgs   = TextToolbox.splitOnFirstUnquotedSpace(nameValue);

                        if (cmdArgs.Length > 1)
                        {
                            string name = cmdArgs[0];
                            //remove quotes if they are there
                            if (name.Length > 1 && name[0] == '"')
                            {
                                name = name.Substring(1);
                            }
                            if (name.Length > 2 && name[name.Length - 1] == '"')
                            {
                                name = name.Substring(0, name.Length - 1);
                            }
                            string val = cmdArgs[1];
                            vars[name.ToLower()] = val;
                        }

                        if (start > 0)
                        {
                            left = text.Substring(0, start);
                        }
                        if (end + 1 != text.Length)
                        {
                            right = text.Substring(end + 1);
                        }
                        text = left + right;
                    }
                    start = text.IndexOf(embCmd);
                }
                else                // < is escaped
                {
                    //remove the '\'
                    text = text.Remove(start - 1, 1);
                    //find the next start
                    if (start >= text.Length - 1)                   //the old start is now at the end
                    {
                        start = -1;
                    }
                    else
                    {
                        start = text.IndexOf(embCmd, start);
                    }
                }
            }            //while we have more <mem.set name>s

            embCmd = "<mem.del ";
            start  = text.IndexOf(embCmd);
            while (start != -1)
            {
                if (!TextToolbox.IsEscaped(text, start))
                {
                    end = TextToolbox.FindNextMatchingChar(text, start);
                    if (end != -1)
                    {
                        string name = text.Substring(start + embCmd.Length, end - start - embCmd.Length);
                        vars.Remove(name.Trim().ToLower());
                        string left  = "";
                        string right = "";
                        if (start > 0)
                        {
                            left = text.Substring(0, start);
                        }
                        if (end + 1 != text.Length)
                        {
                            right = text.Substring(end + 1);
                        }
                        text = left + right;
                    }
                    start = text.IndexOf(embCmd);
                }
                else                // < is escaped
                {
                    //remove the '\'
                    text = text.Remove(start - 1, 1);
                    //find the next start
                    if (start >= text.Length - 1)                   //the old start is now at the end
                    {
                        start = -1;
                    }
                    else
                    {
                        start = text.IndexOf(embCmd, start);
                    }
                }
            }    //while we have more <mem.set name>s
            return(text);
        }        //ReplaceVars(string text, Hashtable vars)
コード例 #12
0
        }                                              //outputs2Class()

        private string outputToCode(string text)
        {
            if (text == null)
            {
                return("");
            }

            StringBuilder sb     = new StringBuilder();
            string        uncode = "";
            string        code   = "";

            //break the text apart into text and code sections
            //test needs to be written to Console.Out
            //and code needs to be written as is
            while (text != "")
            {
                int openTagPos = text.IndexOf(this.openTag);
                while (openTagPos != -1 && TextToolbox.IsEscaped(text, openTagPos))
                {
                    text       = text.Remove(openTagPos - 1, 1);
                    openTagPos = text.IndexOf(this.openTag, openTagPos);
                }

                if (openTagPos != 0)               //we have uncode to process
                {
                    if (openTagPos == -1)          //it's all uncode
                    {
                        uncode = text;
                        text   = "";
                    }
                    else                    //it's uncode + code
                    {
                        uncode = text.Substring(0, openTagPos);
                        text   = text.Substring(openTagPos);
                    }

                    sb.Append("Console.Write(\"");
                    sb.Append(this.escape(uncode));
                    sb.Append("\");\r\n");
                }
                else                //we have code to process (open is at the beginning)
                {
                    int closeTagPos = text.IndexOf(this.closeTag);
                    while (closeTagPos != -1 && TextToolbox.IsEscaped(text, closeTagPos))
                    {
                        text        = text.Remove(closeTagPos - 1, 1);
                        closeTagPos = text.IndexOf(this.closeTag, closeTagPos);
                    }
                    if (closeTagPos == -1)
                    {
                        closeTagPos = text.Length;
                    }
                    code = text.Substring(this.openTag.Length, closeTagPos - this.openTag.Length).Trim();
                    if (code != "")
                    {
                        sb.Append(code);
                    }
                    if (closeTagPos + this.closeTag.Length < text.Length)
                    {
                        text = text.Substring(closeTagPos + this.closeTag.Length);
                    }
                    else
                    {
                        text = "";
                    }
                }
            }            //while(text != "")

            return(sb.ToString());
        }        //outputToCode(string text)
コード例 #13
0
 public string GetNewOutputId()
 {
     return(TextToolbox.GetNewId());
 }
コード例 #14
0
 public string GetNewRuleId()
 {
     return(TextToolbox.GetNewId());
 }
コード例 #15
0
        }//compileRules(string parentId, List<Rule> rules)

        public Reply GetReply(string input, string lastfired, Hashtable vars, string prependOutput)
        {
            List <Match> matches = new List <Match>();
            //do replacements, strip áccents is done in ReplaceOnInput if there are no input replacements
            string inputReplaced = TextToolbox.ReplaceOnInput(input, this.inputReplacements);

            //search the children and virtual children (links) of lastfired rule
            if (this.inputs.ContainsKey(lastfired))
            {
                foreach (InputRecognizer ir in this.inputs[lastfired])
                {
                    //if the input recognizer is a capture, use the original input
                    Match match = ir.Matches((ir.IsCapture ? input : inputReplaced), vars, this.csToolbox);

                    if (match.ConfidenceFactor != 0.0)
                    {
                        //copy shortTermMemory vars to inputVars
                        Hashtable inputVars = new Hashtable();
                        foreach (object key in vars.Keys)
                        {
                            inputVars[key] = vars[key];
                        }
                        //captures the variables and adds them to the inputVars object
                        ir.CaptureVars(input, inputVars);
                        matches.Add(match);
                    }
                }
            }

            if (matches.Count == 0 && this.inputs.ContainsKey("_root"))
            {
                //search all of the primaries
                foreach (InputRecognizer ir in this.inputs["_root"])
                {
                    //if the input recognizer is a capture, use the original input
                    Match match = ir.Matches((ir.IsCapture ? input : inputReplaced), vars, this.csToolbox);
                    if (match.ConfidenceFactor != 0.0)
                    {
                        //copy shortTermMemory vars to inputVars
                        Hashtable inputVars = new Hashtable();
                        foreach (object key in vars.Keys)
                        {
                            inputVars[key] = vars[key];
                        }
                        //captures the variables and adds them to the inputVars object
                        ir.CaptureVars(input, inputVars);
                        matches.Add(match);
                    }
                }
            }

            if (matches.Count == 0)
            {
                return(null);
            }

            matches.Sort();
            Match matchBest = (Match)matches[0];

            //use the matching vars, but maintain the original object so that it persists
            vars.Clone();
            foreach (object key in matchBest.Vars.Keys)
            {
                vars[key] = matchBest.Vars[key];
            }
            //increment the usage count on the chosed InputRecognizer
            matchBest.InputRecognizer.IncUsageCount();

            string ruleId = matchBest.InputRecognizer.RuleId;

            if (!this.outputs.ContainsKey(ruleId) || this.outputs[ruleId].Count == 0)
            {
                Reply noOutputFoundReply = new Reply("Rule contains no outputs.", "", "", ruleId, 0, this.knowledgeBaseItem);

                if (this.csToolbox.StandardNoOutputFoundDefined)
                {
                    string noOutputFoundText = this.csToolbox.ExecuteOnNoOutputFound(vars, noOutputFoundReply);
                    noOutputFoundReply.Text      += this.DoTextReplacements(noOutputFoundText);
                    noOutputFoundReply.AgentText += this.DoAgentTextReplacements(noOutputFoundText);
                }

                return(noOutputFoundReply);
            }

            List <Output> alOutputs = new List <Output>();

            if (this.outputs.ContainsKey(ruleId))
            {
                alOutputs = new List <Output>(this.outputs[ruleId]);
            }

            bool trueNonEmptyOutputConditionFound = false;

            //filter out outputs with false conditions
            for (int i = 0; i < alOutputs.Count; i++)
            {
                Output o = (Output)alOutputs[i];
                if (!this.csToolbox.ExecuteCondition(o.Id, vars))
                {
                    alOutputs.RemoveAt(i);
                    i--;
                }
                else if (o.Condition != null && o.Condition != "")
                {
                    trueNonEmptyOutputConditionFound = true;
                }
            }
            if (alOutputs.Count == 0)//all outputs were removed
            {
                Reply noOutputFoundReply = new Reply("No true output found.", "", "", ruleId, 0, this.knowledgeBaseItem);

                if (this.csToolbox.StandardNoOutputFoundDefined)
                {
                    string noOutputFoundText = this.csToolbox.ExecuteOnNoOutputFound(vars, noOutputFoundReply);
                    noOutputFoundReply.Text      += this.DoTextReplacements(noOutputFoundText);
                    noOutputFoundReply.AgentText += this.DoAgentTextReplacements(noOutputFoundText);
                }

                return(noOutputFoundReply);
            }

            //filter out outputs with no conditions if there is an output which has a true condition
            if (trueNonEmptyOutputConditionFound)
            {
                for (int i = 0; i < alOutputs.Count; i++)
                {
                    Output o = (Output)alOutputs[i];
                    if (o.Condition == null || o.Condition == "")
                    {
                        alOutputs.RemoveAt(i);
                        i--;
                    }
                }
            }

            //choose an output at random
            Output outputChosen = null;

            for (int i = 0; i < alOutputs.Count; i++)           //the try again loop
            {
                outputChosen = ((Output)alOutputs[random.Next(alOutputs.Count)]);
                if (!this.recentOutputsByRule.ContainsKey(ruleId) || !this.recentOutputsByRule[ruleId].Contains(outputChosen.Id))
                {
                    break;
                }
            }

            //update the recent list for this rule
            if (alOutputs.Count > 1)
            {
                if (!this.recentOutputsByRule.ContainsKey(ruleId))
                {
                    this.recentOutputsByRule[ruleId] = new List <string>(alOutputs.Count - 1);
                }
                List <string> recent = this.recentOutputsByRule[ruleId];
                int           index  = recent.IndexOf(outputChosen.Id);
                if (index != -1)
                {
                    recent.RemoveAt(index);
                }
                else if (recent.Count == alOutputs.Count - 1)
                {
                    recent.RemoveAt(0);
                }
                recent.Add(outputChosen.Id);
            }
            //replace vars and output synonyms
            string outputChosenText = prependOutput + outputChosen.Text;

            if (this.csToolbox.OutputExists(outputChosen.Id))
            {
                outputChosenText = this.csToolbox.ExecuteOutput(outputChosen.Id, vars);
            }
            outputChosenText = TextToolbox.ReplaceVars(outputChosenText, vars);
            outputChosenText = TextToolbox.ReplaceOutputSynonyms(outputChosenText, this.synonyms);
            //execute c# code in the command field
            string outputChosenCmd = outputChosen.Cmd;

            if (this.csToolbox.OutputExists(outputChosen.Id + "_cmd"))
            {
                outputChosenCmd = this.csToolbox.ExecuteOutput(outputChosen.Id + "_cmd", vars);
            }

            string outputText = this.DoTextReplacements(outputChosenText);
            string agentText  = this.DoAgentTextReplacements(outputChosenText);
            string outputCmd  = TextToolbox.ReplaceVars(outputChosenCmd, vars);

            return(new Reply(outputText, agentText, outputCmd, matchBest.InputRecognizer.RuleId, matchBest.ConfidenceFactor, this.knowledgeBaseItem));
        }        //GetReply(string input, string lastfired)