示例#1
0
        [CanBeNull] private string Sentence([NotNull] ElizaContext ctx)
        {
            //Split sentence into words
            var words = ctx.Input.Split(' ', StringSplitOptions.RemoveEmptyEntries);

            //Check if there are any exit words, if so immediately terminate
            if (words.Any(_script.Quit.Contains))
            {
                Finished = true;
                return(_script.Final.Random(_random));
            }

            //Get key for each word in the sentence, ordered by rank
            var keys = from word in words
                       from key in _script.GetKeys(word)
                       where key != null
                       orderby key.Rank descending
                       select key;

            //Get a reply for each key
            var replies = from key in keys
                          let reply = TryKey(key, new ElizaContext(ctx, ctx.Input.PadLeft(1).PadRight(1)))
                                      where reply != null
                                      select reply;

            //take the first non-null reply
            return(replies.FirstOrDefault());
        }
示例#2
0
 [CanBeNull] private string ProcessSentences([NotNull] ElizaContext ctx)
 {
     return((from sentence in ctx.Input.Split('.', StringSplitOptions.RemoveEmptyEntries)
             let transformed = new ElizaContext(ctx.Base, Transform(_script.Pre, sentence).Trim())
                               let r = Sentence(transformed)
                                       where r != null
                                       select r).FirstOrDefault());
 }
示例#3
0
        [NotNull] public string ProcessInput([NotNull] ICommandContext input)
        {
            var ctx = new ElizaContext(input, CleanInput(input.Message.Content));

            return(ProcessSentences(ctx)                    //Try to create a reply to one of the sentences of the input
                   ?? _mem.PopOrDefault()                   //Fall back to a reply we saved earlier
                   ?? TryKey(_xnone.Random(_random), ctx)   //Default reply
                   ?? "I am at a loss for words");          //Return default default
        }
示例#4
0
        /// <summary>Decompose a string according to the given key.</summary>
        /// <remarks>
        /// Decompose a string according to the given key. Try each decomposition
        /// rule in order. If it matches, assemble a reply and return it. If assembly
        /// fails, try another decomposition rule. If assembly is a goto rule, return
        /// null and give the key. If assembly succeeds, return the reply;
        /// </remarks>
        [CanBeNull] private string TryKey([CanBeNull] Key key, ElizaContext ctx)
        {
            if (key == null)
            {
                return(null);
            }

            //Select reassembly rules which match the input
            var decompositions = from decomp in key.Decompositions
                                 let decomposed = Patterns.Match(ctx.Input, decomp.Pattern, _script.Syns)
                                                  where decomposed != null
                                                  let rule = Task.Run(async() => await ChooseReassembly(decomp).Rule(ctx, decomposed)).Result
                                                             where !string.IsNullOrWhiteSpace(rule)
                                                             select(decomp, rule, decomposed);

            foreach (var(decomposition, rule, decomposed) in decompositions)
            {
                //If it's a goto rule follow it
                if (rule.StartsWith("goto "))
                {
                    var gotos = _script.GetKeys(rule.Substring(5));
                    return((from g in gotos
                            orderby g.Rank descending
                            let r = TryKey(g, ctx)
                                    where r != null
                                    select r).FirstOrDefault());
                }

                //Try to assemble a reply using this reassembly rule
                var rep = Assemble(rule, decomposed);
                if (rep != null)
                {
                    if (decomposition.Memorise)
                    {
                        _mem.Push(rep);
                    }
                    else
                    {
                        return(rep);
                    }
                }
            }

            return(null);
        }