public virtual bool Match(Context env, IParsedPhrase check) { if (IsMatch(check)) { Propogate(env, check, 1.0); env.Map[StarUtilities.NextStarName(env, name)] = check.Text; return(true); } return(false); }
public override bool Match(object check, Context context, IContinuation succ, IFailure fail) { if (!(check is IParsedPhrase)) { fail.Fail("Cannot match a " + check.GetType(), succ); return(true); } // Set up main check IParsedPhrase full = (IParsedPhrase)check; GroupPhrase sofar = context.LookupDefaulted <GroupPhrase>("$active$" + name, null); if (sofar != null) { full = sofar.AddBranch(full); } bool?isMatch = IsMatch(full); if (!isMatch.HasValue) { List <IContent> contents = new List <IContent>(); contents.Add(new Value(this)); Context tryagain = new Context(context, contents); tryagain.Map["$active$" + name] = new GroupPhrase(full); // Continue with same context succ.Continue(tryagain, fail); } else { if (isMatch.Value) { Propogate(context, full, 1.0); context.Map[StarUtilities.NextStarName(context, name)] = full.Text; succ.Continue(context.ChildRange(1), fail); } else { fail.Fail("Does not match " + full.Text, 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() { // Look through my concepts for a possible match List <IContent> contents = context.Contents; if (contents.Count == 1) { if (contents[0] is Variable) { Variable check = (Variable)contents[0]; // If we already have a concept in mind, just check its data Concept left = context.LookupDefaulted <Concept>("$knowConcept", null); if (left != null) { List <Datum> data = memory.GetData(left); foreach (Datum datum in data) { if (datum.Left == left && kinds.Contains(datum.Relation) && check.Match(context, datum.Right)) { List <Datum> completes = context.LookupAndAdd <List <Datum> >("$knowCompletes", new List <Datum>()); completes.Add(datum); succ.Continue(new Context(context, new List <IContent>()), fail); return(true); } } // Can't match anything! fail.Fail("Initial variable didn't match anything", succ); return(true); } // Does anything here match? for (int ii = 0; ii < directchecks.Count; ii++) { bool matched = kinds.Contains(directchecks[ii].Relation); if (matched) { matched = check.Match(context, directchecks[ii].Right); if (propfunc != null) // always do propfuncs, but only affect matched if failed { matched = check.Match(context, directchecks[ii].Right, propfunc, propargs) || matched; } } if (matched) { Context child = new Context(context, new List <IContent>()); child.Map["$knowConcept"] = directchecks[ii].Left; List <Datum> completes = child.LookupAndAdd <List <Datum> >("$knowCompletes", new List <Datum>()); completes.Add(directchecks[ii]); // Make a clone of ourselves, if this fails succ.Continue(child, MakeContinuingFailure(ii)); return(true); } } } else if (contents[0].Name == "*" || contents[0].Name == "_") { // If we already have a concept in mind, just check its data Concept left = context.LookupDefaulted <Concept>("$knowConcept", null); if (left != null) { List <Datum> data = memory.GetData(left); foreach (Datum datum in data) { if (datum.Left == left && kinds.Contains(datum.Relation)) { List <IContent> words = new List <IContent>(); if (!datum.Right.IsUnknown) { words.Add(new Word(datum.Right.Name)); } context.Map.Add(StarUtilities.NextStarName(context, contents[0].Name), words); List <Datum> completes = context.LookupAndAdd <List <Datum> >("$knowCompletes", new List <Datum>()); completes.Add(datum); succ.Continue(new Context(context, new List <IContent>()), fail); return(true); } } // Can't match anything! fail.Fail("Could not find a matching datum", succ); return(true); } // Does anything here match? for (int ii = 0; ii < directchecks.Count; ii++) { if (kinds.Contains(directchecks[ii].Relation)) { Context child = new Context(context, new List <IContent>()); List <IContent> words = new List <IContent>(); if (!directchecks[ii].Right.IsUnknown) { words.Add(new Word(directchecks[ii].Right.Name)); } child.Map.Add(StarUtilities.NextStarName(child, contents[0].Name), words); child.Map["$knowConcept"] = directchecks[ii].Left; List <Datum> completes = child.LookupAndAdd <List <Datum> >("$knowCompletes", new List <Datum>()); completes.Add(directchecks[ii]); succ.Continue(child, MakeContinuingFailure(ii)); return(true); } } } // Nothing matched! Expand search if (parentchecks.Count > 0) { Concept parent = parentchecks.Dequeue(); directchecks = memory.GetData(parent); Continue(new Context(context, context.Contents, context.Weight * 0.95), fail); return(true); } } // Don't fail if it's just a * if (contents.Count == 1 && contents[0].Name == "*") { Context child = new Context(context, new List <IContent>()); List <IContent> empty = new List <IContent>(); child.Map.Add(StarUtilities.NextStarName(child, contents[0].Name), empty); succ.Continue(child, fail); return(true); } fail.Fail("No data matches", succ); return(true); }