// Take first sentence and return remainder as second element of tuple public TwoTuple <List <IContent>, IContinuation> SplitArguments(Context context, IContinuation succ) { // Construct a %sentence for the first segment List <IContent> sentence = new List <IContent>(); sentence.Add(new Special("%sentence")); int index = 0; while (index < context.Contents.Count && context.Contents[index].Name != "/") { sentence.Add(context.Contents[index]); index++; } List <IContent> remains = new List <IContent>(); if (index < context.Contents.Count) { index++; while (index < context.Contents.Count) { remains.Add(context.Contents[index]); index++; } } IContinuation mysucc = succ; if (remains.Count > 0) { mysucc = new ContinueAgentWrapper(NextSentence, succ); mysucc = new ContextAppender(salience, new Context(context, remains), null, mysucc); } return(new TwoTuple <List <IContent>, IContinuation>(sentence, mysucc)); }
public override bool Evaluate() { List<IContent> contents = context.Contents; if (contents.Count == 0) { Unilog.Notice(this, "Ran out of template before input"); fail.Fail("Ran out of tokens before matched all input", succ); return true; } // Does our first element match the whole thing? IContent first = contents[0]; //Console.WriteLine("Match " + first.Name + " against " + input.Text + " + " + unmatched.Count); // always consider dropping interjections IFailure myfail = fail; if (input.Part == "UH") { IFailure skipfail; if (unmatched.Count == 0) { // then fail becomes success! skipfail = new ContinueCodelet(salience, context, succ, fail); } else { Matcher matchskip = new Matcher(salience, unmatched[0], unmatched.GetRange(1, unmatched.Count - 1), succ); skipfail = new ContinueCodelet(salience, context, matchskip, fail); } myfail = skipfail; } if (first.Name == "*") { // Failure state has the first POS eaten by the star StarEater eater = new StarEater(coderack, salience, this, StarUtilities.NextStarName(context, "*"), true); if (context.Contents.Count == 1) { // We ran out elements, but we still have some unmatched coderack.AddCodelet(eater, "Evaluate *"); return true; } else { MatchAgainst(salience, context.ChildRange(1), input, unmatched, succ, eater); return true; } } else if (first.Name == "_") { StarEater eater = new StarEater(coderack, salience, this, StarUtilities.NextStarName(context, "_"), true); coderack.AddCodelet(eater, "Evaluate _"); return true; } else if (first.Name == "%opt") { // Try with, and if that fails, do without int end = context.Contents.IndexOf(Special.EndDelimSpecial); if (end == -1) { // It's all optional-- but on fail return to match to ensure blank Context without = new Context(context, new List<IContent>()); Evaluator evalfail = MakeMatcherContinue(salience, without, input, unmatched, succ); IFailure withoutfail = new ContinueCodelet(salience, without, evalfail, myfail); Context with = new Context(context, context.Contents.GetRange(1, context.Contents.Count - 1)); Matcher.MatchAgainst(salience, with, input, unmatched, succ, withoutfail); } else { Context without = new Context(context, context.Contents.GetRange(end + 1, context.Contents.Count - (end + 1))); Evaluator evalfail = MakeMatcherContinue(salience, without, input, unmatched, succ); IFailure withoutfail = new ContinueCodelet(salience, without, evalfail, myfail); Context with = new Context(context, context.Contents.GetRange(1, end - 1)); with.Contents.AddRange(without.Contents); Matcher.MatchAgainst(salience, with, input, unmatched, succ, withoutfail); } return true; } else if (first is Variable) { if (((Variable)first).Match(context, input)) { ContinueNextUnmatched(context.ChildRange(1)); return true; } else if (input.IsLeaf) { // we didn't match-- fail! Unilog.Notice(this, first.Name + " does not match " + input.Text); fail.Fail("Initial variable didn't match", succ); return true; } else { GroupPhrase groupPhrase = new GroupPhrase(input); unmatched.InsertRange(0, groupPhrase.GetRange(1)); // Call again with the same evaluated first argument Matcher matchrest = new Matcher(salience, groupPhrase.GetBranch(0), unmatched, succ); matchrest.Continue(context, myfail); return true; } } else if (first is Value && ((Value) first).Data is MatchProduceAgent) { IContinuation mysucc = succ; // Check if we have values to match later if (unmatched.Count != 0) mysucc = MakeNextUnmatchedContinue(mysucc); ContextAppender appender = new ContextAppender(salience, context, -1, mysucc); MatchProduceAgent agent = (MatchProduceAgent)((Value) first).Data; context.Map["$check"] = input; ContinueToCallAgent codelet = new ContinueToCallAgent(agent, appender); IFailure deepenfail = myfail; if (!input.IsLeaf) { // Continue to deeper GroupPhrase groupPhrase = new GroupPhrase(input); unmatched.InsertRange(0, groupPhrase.GetRange(1)); // Call again with the same evaluated first argument Matcher matchrest = new Matcher(salience, groupPhrase.GetBranch(0), unmatched, succ); deepenfail = new FailToContinue(context, matchrest, myfail); } codelet.Continue(context, deepenfail); return true; } if (first is Word && input.IsLeaf) { WordComparer comparer = (WordComparer) context.LookupSimple("$Compare"); if (comparer.Match(input.Text, first.Name)) { ContinueNextUnmatched(context.ChildRange(1)); return true; } else { // failure! fail.Fail(string.Format("Pattern [{0}] does not match [{1}]", first.Name, input.Text), succ); return true; } } else if (first is Word) { GroupPhrase groupPhrase = new GroupPhrase(input); unmatched.InsertRange(0, groupPhrase.GetRange(1)); Matcher matchcont = new Matcher(salience, groupPhrase.GetBranch(0), unmatched, succ); matchcont.Continue(context, myfail); return true; } // We can't handle this! fail fail.Fail("Unknown first element", succ); return true; }
public override bool Evaluate() { List <IContent> contents = context.Contents; if (contents.Count == 0) { Unilog.Notice(this, "Ran out of template before input"); fail.Fail("Ran out of tokens before matched all input", succ); return(true); } // Does our first element match the whole thing? IContent first = contents[0]; //Console.WriteLine("Match " + first.Name + " against " + input.Text + " + " + unmatched.Count); // always consider dropping interjections IFailure myfail = fail; if (input.Part == "UH") { IFailure skipfail; if (unmatched.Count == 0) { // then fail becomes success! skipfail = new ContinueCodelet(salience, context, succ, fail); } else { Matcher matchskip = new Matcher(salience, unmatched[0], unmatched.GetRange(1, unmatched.Count - 1), succ); skipfail = new ContinueCodelet(salience, context, matchskip, fail); } myfail = skipfail; } if (first.Name == "*") { // Failure state has the first POS eaten by the star StarEater eater = new StarEater(coderack, salience, this, StarUtilities.NextStarName(context, "*"), true); if (context.Contents.Count == 1) { // We ran out elements, but we still have some unmatched coderack.AddCodelet(eater, "Evaluate *"); return(true); } else { MatchAgainst(salience, context.ChildRange(1), input, unmatched, succ, eater); return(true); } } else if (first.Name == "_") { StarEater eater = new StarEater(coderack, salience, this, StarUtilities.NextStarName(context, "_"), true); coderack.AddCodelet(eater, "Evaluate _"); return(true); } else if (first.Name == "%opt") { // Try with, and if that fails, do without int end = context.Contents.IndexOf(Special.EndDelimSpecial); if (end == -1) { // It's all optional-- but on fail return to match to ensure blank Context without = new Context(context, new List <IContent>()); Evaluator evalfail = MakeMatcherContinue(salience, without, input, unmatched, succ); IFailure withoutfail = new ContinueCodelet(salience, without, evalfail, myfail); Context with = new Context(context, context.Contents.GetRange(1, context.Contents.Count - 1)); Matcher.MatchAgainst(salience, with, input, unmatched, succ, withoutfail); } else { Context without = new Context(context, context.Contents.GetRange(end + 1, context.Contents.Count - (end + 1))); Evaluator evalfail = MakeMatcherContinue(salience, without, input, unmatched, succ); IFailure withoutfail = new ContinueCodelet(salience, without, evalfail, myfail); Context with = new Context(context, context.Contents.GetRange(1, end - 1)); with.Contents.AddRange(without.Contents); Matcher.MatchAgainst(salience, with, input, unmatched, succ, withoutfail); } return(true); } else if (first is Variable) { if (((Variable)first).Match(context, input)) { ContinueNextUnmatched(context.ChildRange(1)); return(true); } else if (input.IsLeaf) { // we didn't match-- fail! Unilog.Notice(this, first.Name + " does not match " + input.Text); fail.Fail("Initial variable didn't match", succ); return(true); } else { GroupPhrase groupPhrase = new GroupPhrase(input); unmatched.InsertRange(0, groupPhrase.GetRange(1)); // Call again with the same evaluated first argument Matcher matchrest = new Matcher(salience, groupPhrase.GetBranch(0), unmatched, succ); matchrest.Continue(context, myfail); return(true); } } else if (first is Value && ((Value)first).Data is MatchProduceAgent) { IContinuation mysucc = succ; // Check if we have values to match later if (unmatched.Count != 0) { mysucc = MakeNextUnmatchedContinue(mysucc); } ContextAppender appender = new ContextAppender(salience, context, -1, mysucc); MatchProduceAgent agent = (MatchProduceAgent)((Value)first).Data; context.Map["$check"] = input; ContinueToCallAgent codelet = new ContinueToCallAgent(agent, appender); IFailure deepenfail = myfail; if (!input.IsLeaf) { // Continue to deeper GroupPhrase groupPhrase = new GroupPhrase(input); unmatched.InsertRange(0, groupPhrase.GetRange(1)); // Call again with the same evaluated first argument Matcher matchrest = new Matcher(salience, groupPhrase.GetBranch(0), unmatched, succ); deepenfail = new FailToContinue(context, matchrest, myfail); } codelet.Continue(context, deepenfail); return(true); } if (first is Word && input.IsLeaf) { WordComparer comparer = (WordComparer)context.LookupSimple("$Compare"); if (comparer.Match(input.Text, first.Name)) { ContinueNextUnmatched(context.ChildRange(1)); return(true); } else { // failure! fail.Fail(string.Format("Pattern [{0}] does not match [{1}]", first.Name, input.Text), succ); return(true); } } else if (first is Word) { GroupPhrase groupPhrase = new GroupPhrase(input); unmatched.InsertRange(0, groupPhrase.GetRange(1)); Matcher matchcont = new Matcher(salience, groupPhrase.GetBranch(0), unmatched, succ); matchcont.Continue(context, myfail); return(true); } // We can't handle this! fail fail.Fail("Unknown first element", succ); return(true); }
public override bool Evaluate() { List<IContent> contents = context.Contents; if (contents.Count == 0) { // nothing to do! succ.Continue(context, fail); aftersucc.Continue(new Context(context, null), fail); return true; } // Look ahead until first recursion int ii; for (ii = 0; ii < contents.Count; ii++) if ((contents[ii] is Special) && !(contents[ii].Name.StartsWith("*") || contents[ii].Name.StartsWith("_"))) break; if (ii > 0 && argumentMode == ArgumentMode.SingleArgument) { succ.Continue(new Context(context, contents.GetRange(0, 1)), fail); aftersucc.Continue(context.ChildRange(1), fail); return true; } if (ii == contents.Count) { // everything was done succ.Continue(context, fail); aftersucc.Continue(new Context(context, null), fail); return true; } if (contents[ii] == Special.EndDelimSpecial) { // everything to the # is done Context value = new Context(context, contents.GetRange(0, ii)); Context after = new Context(context, contents.GetRange(ii + 1, contents.Count - ii - 1)); succ.Continue(value, fail); aftersucc.Continue(after, fail); return true; } IContent content = contents[ii]; object element = null; try { element = context.Lookup(content.Name); } catch (Exception ex) { if (isUserInput) throw new UserException("The variable '" + content.Name + "' is unknown", ex); else throw ex; } if (element is CallAgent) { IContinuation mysucc = succ; if (ii > 0) mysucc = new ContextAppender(salience, context, ii, succ); List<IContent> sublst = context.Contents.GetRange(ii + 1, context.Contents.Count - ii - 1); if (((CallAgent)element).ArgumentOptions == ArgumentMode.NoArugments) { if (argumentMode == ArgumentMode.SingleArgument) { ContinueToCallAgent.Instantiate((CallAgent)element, new Context(context, null), mysucc, fail); aftersucc.Continue(new Context(context, sublst), fail); return true; } else { ContinuationAppender evalappend = new ContinuationAppender(context, mysucc); ContinueToCallAgent.Instantiate((CallAgent)element, new Context(context, null), evalappend.AsIndex(0), fail); Evaluator eval = new Evaluator(salience, ArgumentMode.ManyArguments, evalappend.AsIndex(1), aftersucc, isUserInput); eval.Continue(new Context(context, sublst), fail); return true; } } else if (((CallAgent)element).ArgumentOptions == ArgumentMode.RemainderUnevaluated) { ContinueToCallAgent.Instantiate((CallAgent) element, new Context(context, sublst), mysucc, fail); aftersucc.Continue(new Context(context, new List<IContent>()), fail); return true; } else if (((CallAgent)element).ArgumentOptions == ArgumentMode.DelimitedUnevaluated) { int jj; for (jj = 0; jj < contents.Count; jj++) if (contents[jj] == Special.EndDelimSpecial) break; List<IContent> before = context.Contents.GetRange(ii + 1, jj - 1); List<IContent> after; if (jj < context.Contents.Count - 1) after = context.Contents.GetRange(jj + 1, context.Contents.Count - jj - 1); else after = new List<IContent>(); ContinuationAppender evalappend = new ContinuationAppender(context, mysucc); ContinueToCallAgent.Instantiate((CallAgent) element, new Context(context, before), evalappend.AsIndex(0), fail); Evaluator aftereval = new Evaluator(salience, ArgumentMode.ManyArguments, evalappend.AsIndex(1), aftersucc, isUserInput); aftereval.Continue(new Context(context, after), fail); return true; } else { if (argumentMode == ArgumentMode.SingleArgument) { ContinueToCallAgent callagent = new ContinueToCallAgent((CallAgent)element, mysucc); Evaluator eval = new Evaluator(salience, ((CallAgent) element).ArgumentOptions, callagent, aftersucc, isUserInput); eval.Continue(new Context(context, sublst), fail); return true; } else { ContinuationAppender evalappend = new ContinuationAppender(context, mysucc); ContinueToCallAgent callagent = new ContinueToCallAgent((CallAgent)element, evalappend.AsIndex(0)); Evaluator aftereval = new Evaluator(salience, ArgumentMode.ManyArguments, evalappend.AsIndex(1), aftersucc, isUserInput); Evaluator eval = new Evaluator(salience, ((CallAgent) element).ArgumentOptions, callagent, aftereval, isUserInput); eval.Continue(new Context(context, sublst), fail); return true; } } } else if (element is Codelet) { IContinuation mysucc = succ; if (ii > 0) mysucc = new ContextAppender(salience, context, ii, succ); List<IContent> sublst = context.Contents.GetRange(ii + 1, context.Contents.Count - ii - 1); coderack.AddCodelet((Codelet) element, "Codelet in content"); Evaluator eval = new Evaluator(salience, argumentMode, mysucc, aftersucc, isUserInput); eval.Continue(new Context(context, sublst), fail); return true; } else { Context result = new Context(context, new List<IContent>(context.Contents.GetRange(0, ii))); if (element is IContent) result.Contents.Add((IContent) element); else if (element is List<IContent>) result.Contents.AddRange((List<IContent>) element); else result.Contents.Add(new Value(element)); if (argumentMode == ArgumentMode.SingleArgument) { succ.Continue(result, fail); aftersucc.Continue(context.ChildRange(1), fail); return true; } else { IContinuation appender = new ContextAppender(salience, result, result.Contents.Count, succ); List<IContent> sublst = context.Contents.GetRange(ii + 1, context.Contents.Count - ii - 1); Evaluator eval = new Evaluator(salience, argumentMode, appender, aftersucc, isUserInput); eval.Continue(new Context(context, sublst), fail); return true; } } }
// Take first sentence and return remainder as second element of tuple public TwoTuple<List<IContent>, IContinuation> SplitArguments(Context context, IContinuation succ) { // Construct a %sentence for the first segment List<IContent> sentence = new List<IContent>(); sentence.Add(new Special("%sentence")); int index = 0; while (index < context.Contents.Count && context.Contents[index].Name != "/") { sentence.Add(context.Contents[index]); index++; } List<IContent> remains = new List<IContent>(); if (index < context.Contents.Count) { index++; while (index < context.Contents.Count) { remains.Add(context.Contents[index]); index++; } } IContinuation mysucc = succ; if (remains.Count > 0) { mysucc = new ContinueAgentWrapper(NextSentence, succ); mysucc = new ContextAppender(salience, new Context(context, remains), null, mysucc); } return new TwoTuple<List<IContent>, IContinuation>(sentence, mysucc); }