public static ICollection <string> SortAtOnce(ICollection <string> unsorted)
        {
            var bucket = new Inheritance();

            bucket.Fill(unsorted);
            return(bucket.Dump());
        }
Esempio n. 2
0
        /// <summary>
        /// Sort the %Previous buffer.
        /// </summary>
        public void sortPrevious()
        {
            // Keep track if ANYTHING has a %Previous.
            _hasPrevious = false;

            // Find all the triggers that have a %Previous. This hash maps a %Previous
            // label to the list of triggers that are associated with it.
            var prev2trig = new Dictionary <string, ICollection <string> >();

            // Loop through the triggers to find those with a %Previous.
            var triggers = listTriggers(true);

            for (int i = 0; i < triggers.Length; i++)
            {
                var pattern = triggers[i];
                if (pattern.IndexOf("{previous}") > -1)
                {
                    // This one has it.
                    _hasPrevious = true;

                    var parts    = pattern.SplitRegex("\\{previous\\}", 2);
                    var previous = parts[1];

                    // Keep it under the %Previous.
                    if (false == prev2trig.ContainsKey(previous))
                    {
                        prev2trig.Add(previous, new List <String>());
                    }
                    prev2trig[previous].Add(parts[0]);
                }
            }

            // Loop over keys
            // TODO: Can do better to solve this, its is not best performance options
            // NOTE: ToArray is necessary to clone key list and avoid error on interation
            foreach (var key in prev2trig.Keys.ToArray())
            {
                prev2trig[key] = Inheritance.SortAtOnce(prev2trig[key]);
            }


            this.previous = prev2trig;
        }
Esempio n. 3
0
        /// <summary>
        /// (Re)create the internal sort cache for this topic's triggers.
        /// </summary>
        /// <param name="alltrigs"></param>
        public void sortTriggers(string[] alltrigs)
        {
            // Get our list of triggers.
            var sorted = new List <string>();

            // Do multiple sorts, one for each inheritence level.
            var heritage = new Dictionary <int, ICollection <string> >();

            heritage.Add(-1, new List <string>());
            var highest = -1;


            var reInherit = new Regex("\\{inherits=(\\d+)\\}");

            for (int i = 0; i < alltrigs.Length; i++)
            {
                int inherits = -1; // Default, when no {inherits} tag.

                // Does it have an inherit level?
                if (alltrigs[i].IndexOf("{inherits=") > -1)
                {
                    var mc = reInherit.Matches(alltrigs[i]);
                    foreach (Match m in mc)
                    {
                        inherits = int.Parse(m.Groups[1].Value);
                        if (inherits > highest)
                        {
                            highest = inherits;
                        }
                        break;
                    }
                }

                alltrigs[i] = Regex.Replace(alltrigs[i], "\\{inherits=\\d+\\}", "");

                // Initialize this inherit group?
                if (false == heritage.ContainsKey(inherits))
                {
                    heritage.Add(inherits, new List <string>());
                }

                // Add it.
                heritage[inherits].Add(alltrigs[i]);
            }

            // Go on and sort each heritage level. We want to loop from level 0 up,
            // and then do level -1 last.
            for (int h = -1; h <= highest; h++)
            {
                if (false == heritage.ContainsKey(h))
                {
                    continue;
                }

                int inherits = h;
                say("Sorting triggers by heritage level " + inherits);
                var triggers = heritage[inherits].ToArray();

                // Sort-priority maps.
                var prior = new Dictionary <int, ICollection <string> >();

                // Assign each trigger to its priority level.
                say("BEGIN sortTriggers in topic " + this.name);

                var rePrior = new Regex("\\{weight=(\\d+?)\\}");
                for (int i = 0; i < triggers.Length; i++)
                {
                    int priority = 0;

                    // See if this trigger has a {weight}.
                    if (triggers[i].IndexOf("{weight") > -1)
                    {
                        //NOTE: I thnk this can do user only Match
                        var mc = rePrior.Matches(triggers[i]);
                        foreach (Match m in mc)
                        {
                            priority = int.Parse(m.Groups[1].Value);
                        }
                    }

                    // Initialize its priority group?
                    if (false == prior.ContainsKey(priority))
                    {
                        // Create it.
                        prior.Add(priority, new List <String>());
                    }

                    // Add it.
                    prior[priority].Add(triggers[i]);
                }

                /*
                 *  Keep in mind here that there is a difference between includes and
                 *  inherits -- topics that inherit other topics are able to OVERRIDE
                 *  triggers that appear in the inherited topic. This means that if the
                 *  top topic has a trigger of simply *, then NO triggers are capable of
                 *  matching in ANY inherited topic, because even though * has the lowest
                 *  sorting priority, it has an automatic priority over all inherited
                 *  topics.
                 *
                 *  The topicTriggers in TopicManager takes this into account. All topics
                 *  that inherit other topics will have their local triggers prefixed
                 *  with a fictional {inherits} tag, which will start at {inherits=0}
                 *  and increment if the topic tree has other inheriting topics. So
                 *  we can use this tag to make sure topics that inherit things will
                 *  have their triggers always be on the top of the stack, from
                 *  inherits=0 to inherits=n.
                 */

                // Sort the priority lists numerically from highest to lowest.
                var prior_sorted = Util.SortKeysDesc(prior);
                for (int p = 0; p < prior_sorted.Length; p++)
                {
                    say("Sorting triggers w/ priority " + prior_sorted[p]);
                    var p_list = prior[prior_sorted[p]];

                    /*
                     *  So, some of these triggers may include {inherits} tags, if
                     *  they came from a topic which inherits another topic. Lower
                     *  inherits values mean higher priority on the stack. Keep this
                     *  in mind when keeping track of how to sort these things.
                     */

                    var highest_inherits = inherits; // highest {inherits} we've seen

                    // Initialize a sort bucket that will keep inheritance levels'
                    // triggers in separate places.
                    //com.rivescript.InheritanceManager bucket = new com.rivescript.InheritanceManager();
                    var bucket = new Inheritance();

                    // Loop through the triggers and sort them into their buckets.
                    foreach (var e in p_list)
                    {
                        var trigger = e.ToString(); //Copy the element

                        // Count the number of whole words it has.
                        //Javacode: String[] words = trigger.split("[ |\\*|\\#|\\_]");
                        var words = Regex.Split(trigger, "[ |\\*|\\#|_]");
                        int wc    = 0;
                        for (int w = 0; w < words.Length; w++)
                        {
                            if (words[w].Length > 0)
                            {
                                wc++;
                            }
                        }

                        say("On trigger: " + trigger + " (it has " + wc + " words) - inherit level: " + inherits);

                        // Profile it.
                        if (trigger.IndexOf("_") > -1)
                        {
                            // It has the alpha wildcard, _.
                            if (wc > 0)
                            {
                                bucket.addAlpha(wc, trigger);
                            }
                            else
                            {
                                bucket.addUnder(trigger);
                            }
                        }
                        else if (trigger.IndexOf("#") > -1)
                        {
                            // It has the numeric wildcard, #.
                            if (wc > 0)
                            {
                                bucket.addNumber(wc, trigger);
                            }
                            else
                            {
                                bucket.addPound(trigger);
                            }
                        }
                        else if (trigger.IndexOf("*") > -1)
                        {
                            // It has the global wildcard, *.
                            if (wc > 0)
                            {
                                bucket.addWild(wc, trigger);
                            }
                            else
                            {
                                bucket.addStar(trigger);
                            }
                        }
                        else if (trigger.IndexOf("[") > -1)
                        {
                            // It has optional parts.
                            bucket.addOption(wc, trigger);
                        }
                        else
                        {
                            // Totally atomic.
                            bucket.addAtomic(wc, trigger);
                        }
                    }

                    // Sort each inheritence level individually.
                    say("Dumping sort bucket !");
                    var subsort = bucket.Dump(new List <string>());
                    foreach (var item in subsort)
                    {
                        say("ADD TO SORT: " + item);
                        sorted.Add(item);
                    }
                }
            }

            // Turn the running sort buffer into a string array and store it.
            this.sorted = sorted.ToArray();
        }
Esempio n. 4
0
        /// <summary>
        /// (Re)create the internal sort cache for this topic's triggers.
        /// </summary>
        /// <param name="alltrigs"></param>
        public void sortTriggers(string[] alltrigs)
        {
            // Get our list of triggers.
            var sorted = new List <string>();

            // Do multiple sorts, one for each inheritence level.
            var heritage = new Dictionary <int, ICollection <string> >();

            heritage.Add(-1, new List <string>());
            var highest = -1;


            var reInherit = new Regex("\\{inherits=(\\d+)\\}");

            for (int i = 0; i < alltrigs.Length; i++)
            {
                int inherits = -1; // Default, when no {inherits} tag.

                // Does it have an inherit level?
                if (alltrigs[i].IndexOf("{inherits=") > -1)
                {
                    var mc = reInherit.Matches(alltrigs[i]);
                    foreach (Match m in mc)
                    {
                        inherits = int.Parse(m.Groups[1].Value);
                        if (inherits > highest)
                        {
                            highest = inherits;
                        }
                        break;
                    }
                }

                alltrigs[i] = Regex.Replace(alltrigs[i], "\\{inherits=\\d+\\}", "");

                // Initialize this inherit group?
                if (false == heritage.ContainsKey(inherits))
                {
                    heritage.Add(inherits, new List <string>());
                }

                // Add it.
                heritage[inherits].Add(alltrigs[i]);
            }

            // Move the no-{inherits} triggers to the bottom of the stack.
            heritage.Add(highest + 1, heritage[-1]);
            heritage.Remove(-1);


            // Go on and sort each heritage level. We want to loop from level 0 up,
            for (int h = 0; h <= highest + 1; h++)
            {
                if (false == heritage.ContainsKey(h))
                {
                    continue;
                }

                int inherits = h;
                say("Sorting triggers by heritage level " + inherits);
                var triggers = heritage[inherits].ToArray();

                // Sort-priority maps.
                var prior = new Dictionary <int, ICollection <string> >();

                // Assign each trigger to its priority level.
                say("BEGIN sortTriggers in topic " + this.name);

                var rePrior = new Regex("\\{weight=(\\d+?)\\}");
                for (int i = 0; i < triggers.Length; i++)
                {
                    int priority = 0;

                    // See if this trigger has a {weight}.
                    if (triggers[i].IndexOf("{weight") > -1)
                    {
                        //NOTE: I thnk this can do user only Match
                        var mc = rePrior.Matches(triggers[i]);
                        foreach (Match m in mc)
                        {
                            priority = int.Parse(m.Groups[1].Value);
                        }
                    }

                    // Initialize its priority group?
                    if (false == prior.ContainsKey(priority))
                    {
                        // Create it.
                        prior.Add(priority, new List <String>());
                    }

                    // Add it.
                    prior[priority].Add(triggers[i]);
                }

                /*
                 *  Keep in mind here that there is a difference between includes and
                 *  inherits -- topics that inherit other topics are able to OVERRIDE
                 *  triggers that appear in the inherited topic. This means that if the
                 *  top topic has a trigger of simply *, then NO triggers are capable of
                 *  matching in ANY inherited topic, because even though * has the lowest
                 *  sorting priority, it has an automatic priority over all inherited
                 *  topics.
                 *
                 *  The topicTriggers in TopicManager takes this into account. All topics
                 *  that inherit other topics will have their local triggers prefixed
                 *  with a fictional {inherits} tag, which will start at {inherits=0}
                 *  and increment if the topic tree has other inheriting topics. So
                 *  we can use this tag to make sure topics that inherit things will
                 *  have their triggers always be on the top of the stack, from
                 *  inherits=0 to inherits=n.
                 */

                // Sort the priority lists numerically from highest to lowest.
                var prior_sorted = Util.SortKeysDesc(prior);
                for (int p = 0; p < prior_sorted.Length; p++)
                {
                    say("Sorting triggers w/ priority " + prior_sorted[p]);
                    var p_list = prior[prior_sorted[p]];

                    /*
                     *  So, some of these triggers may include {inherits} tags, if
                     *  they came from a topic which inherits another topic. Lower
                     *  inherits values mean higher priority on the stack. Keep this
                     *  in mind when keeping track of how to sort these things.
                     */

                    // Initialize a sort bucket that will keep inheritance levels'
                    // triggers in separate places.
                    //com.rivescript.InheritanceManager bucket = new com.rivescript.InheritanceManager();
                    var bucket = new Inheritance();

                    // Loop through the triggers and sort them into their buckets.
                    bucket.Fill(p_list);

                    // Sort each inheritence level individually.
                    say("Dumping sort bucket !");
                    var subsort = bucket.Dump();
                    foreach (var item in subsort)
                    {
                        say("ADD TO SORT: " + item);
                        sorted.Add(item);
                    }
                }
            }

            // Turn the running sort buffer into a string array and store it.
            this.sorted = sorted.ToArray();
        }