[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()); }
[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()); }
[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 }
/// <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); }