public override bool Match(object check, Context context, IContinuation succ, IFailure fail) { if (check is IParsedPhrase) { IParsedPhrase phrase = (IParsedPhrase)check; if (phrase.Part == "=P") { // Match against each element foreach (IParsedPhrase constituent in phrase.Branches) { Context child = new Context(context, context.Contents); child.Map["$check"] = constituent; ContinueToCallAgent.Instantiate(new ClauseVariable(salience, tagger, parser), child, succ, fail); } } else if (phrase.Part == "FRAG" || phrase.Part == "S" || phrase.Part == "SBARQ") { GroupPhrase groupPhrase = new GroupPhrase(phrase); IParsedPhrase last = groupPhrase.GetBranch(groupPhrase.Count - 1); if (last.Part == "." || last.Part == "?" || last.Part == "!" || last.Part == ";") { phrase = new GroupPhrase("?", groupPhrase.GetRange(0)); } // Set up propogate-on-clear ContinueToCallAgent cont = CallAgentWrapper.MakeContinuation(PropogateOnClear, succ, 100.0, 4, 10, "%clause", phrase); // Do a match using my contents Matcher.MatchAgainst(salience, context, phrase, new List <IParsedPhrase>(), cont, fail); } } return(true); }
public override bool CallRescue(Coderack coderack, IParsedPhrase input, PatternTemplateSource patternTemplateSource, string reason, IContinuation skip, IContinuation succ, IFailure fail) { List <string> words = GroupPhrase.PhraseToTexts(input); bool changed = false; List <string> corrected = new List <string>(); foreach (string word in words) { string correct = comparer.GetCorrects(word)[0]; if (correct.ToLower() != word.ToLower()) { changed = true; } corrected.Add(correct); } if (changed) { IParsedPhrase correct = parser.Parse(StringUtilities.JoinWords(corrected)); IFailure fallfail = fallback.MakeFailure(input, patternTemplateSource, succ, fail, coderack); patternTemplateSource.Generate(coderack, correct, succ, fallfail, weight); return(true); } else { return(fallback.CallRescue(coderack, input, patternTemplateSource, reason, skip, succ, fail)); } }
public override string ToString() { GroupPhrase groupPhrase = new GroupPhrase("FRAG", unmatched); StringBuilder code = new StringBuilder(); foreach (IContent content in context.Contents) { code.Append(content.Name + " "); } return(string.Format("[Matcher: Contents={0}, Input={1}, Unmatched={2}]", code.ToString(), input.Text, groupPhrase.Text)); }
public static bool KnowPhrase(IParsedPhrase phrase, Context context, Memory memory) { GroupPhrase groupPhrase = new GroupPhrase(phrase); IParsedPhrase datetime = groupPhrase.GetBranch(1); Datum datum = new Datum(null, Relations.Relation.AtTime, memory.NewConcept(datetime), context.Weight); context.LookupAndAdd <List <Datum> >("$knowPartials", new List <Datum>()).Add(datum); return(true); }
public Concept NewConcept(IParsedPhrase phrase) { if (phrase.IsLeaf) { if (phrase.Part.StartsWith("VB")) { return(NewConcept(phrase.Text, Concept.Kind.Event)); } else if (phrase.Part == "JJ" || phrase.Part == "RB") { return(NewConcept(phrase.Text, Concept.Kind.Attribute)); } else { return(NewConcept(phrase.Text, Concept.Kind.Entity)); } } GroupPhrase groupPhrase = new GroupPhrase(phrase); List <IParsedPhrase> constituents = new List <IParsedPhrase>(phrase.Branches); // 1. Strip parentheticals IParsedPhrase parenthetical = groupPhrase.FindBranch("PRN"); if (parenthetical != null) { constituents.Remove(parenthetical); } // 2. Preposition to contexts, back to front /* XXX: Works for "the road of Rome" but not "the city of Rome" * while (constituents[constituents.Count - 1] is PrepositionalPhrase) * { * context = GetConcept(constituents[constituents.Count - 1], context); * constituents.RemoveAt(constituents.Count - 1); * }*/ IParsedPhrase remain = new GroupPhrase("", constituents); if (phrase.Part == "PP") { return(NewConcept(remain.Text, Concept.Kind.Attribute)); } else if (phrase.Part == "VB") { return(NewConcept(remain.Text, Concept.Kind.Event)); } else { return(NewConcept(remain.Text, Concept.Kind.Entity)); } }
public bool ConstructSentence(Context context, IContinuation succ, IFailure fail, params object[] args) { // Need to produce all my contents! IParsedPhrase phrase = StarUtilities.ProducedPhrase(context, tagger, parser); if (phrase == null) { // oops, we failed to produce fail.Fail("Context could not be produced", succ); return(true); } if (!(phrase.Part == "=P")) { if (phrase.Part == "FRAG" || phrase.Part == "S" || phrase.Part == "SBARQ") { if (final != null) { GroupPhrase groupPhrase = new GroupPhrase(phrase); IParsedPhrase last = groupPhrase.GetBranch(groupPhrase.Count - 1); if (!(last.Part == "." || last.Part == "!" || last.Part == "?")) { List <IParsedPhrase> branches = new List <IParsedPhrase>(); branches.AddRange(phrase.Branches); branches.Add((IParsedPhrase)final.Clone()); phrase = new GroupPhrase(phrase.Part, branches); } } } else { List <IParsedPhrase> branches = new List <IParsedPhrase>(); branches.Add(phrase); if (final != null) { branches.Add((IParsedPhrase)final.Clone()); } phrase = new GroupPhrase("FRAG", branches); } } List <IContent> contents = new List <IContent>(); contents.Add(new Word(phrase.Text)); Context child = new Context(context, contents); succ.Continue(child, fail); return(true); }
public void NextSentence(Context context, IContinuation succ, IFailure fail, params object[] args) { int?sentenceStart = context.LookupDefaulted <int?>("$sentences.index", null); TwoTuple <List <IContent>, IContinuation> parts = SplitArguments(context, succ); List <IContent> chunk = parts.one; Context first = new Context(context, chunk); first.Map["$sentences.index"] = sentenceStart + 1; GroupPhrase groupPhrase = new GroupPhrase((IParsedPhrase)context.Lookup("$sentences.check")); Matcher.MatchAgainst(salience, first, groupPhrase.GetBranch(sentenceStart.Value), new List <IParsedPhrase>(), parts.two, fail); }
public override bool IsMatch(IParsedPhrase check) { if (check.Part == "PP") { GroupPhrase groupPhrase = new GroupPhrase(check); // Take everything except the preposition string datetime = groupPhrase.GetBranch(1).Text; ProbableStrength time = ValidateUtilities.SeemsTime(datetime); return(time.IsLikely(0.5)); } else { return(ValidateUtilities.SeemsSingleDay(check.Text).IsLikely(0.5)); } }
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); }
protected bool MatchNextTemplate() { if (remainingDicta.Count == 0) { return(false); } PatternTemplateSource dictum = remainingDicta.Dequeue(); if (dictum.Pattern.Contents[0].Name == "%sentence") { IFailure fail = tryToRescueMatch.MakeFailure(inputs[inputIndex], dictum, this, this, coderack); dictum.Generate(coderack, inputs[inputIndex], this, fail, weight); return(true); } else if (dictum.Pattern.Contents[0].Name == "%sentences") { int count = 1; foreach (IContent content in dictum.Pattern.Contents) { if (content.Name == "/") { count++; } } GroupPhrase groupPhrase = new GroupPhrase("=P", inputs.GetRange(inputIndex, count)); IFailure fail = tryToRescueMatch.MakeFailure(groupPhrase, dictum, this, this, coderack); dictum.Generate(coderack, groupPhrase, this, fail, weight); return(true); } else { receiver.Receive(String.Format("Template starting with {0} not available in serial mode.", dictum.Pattern.Contents[0].Name), dictum); return(MatchNextTemplate()); } }
public static List <IContent> Produced(Context context, POSTagger tagger, GrammarParser parser) { List <IContent> result = new List <IContent>(); foreach (IContent content in context.Contents) { if (content is Word) { result.Add(content); } else if (content is Special && (content.Name.StartsWith("*") || content.Name.StartsWith("_"))) { List <IContent> words = GetStarValue(context, content.Name); result.AddRange(words); } else if (content is Variable) { IParsedPhrase phrase = ((Variable)content).Produce(context, tagger, parser); if (phrase == null) { return(null); // we failed! don't use it! } List <string> words = GroupPhrase.PhraseToTexts(phrase); foreach (string word in words) { result.Add(new Word(word)); } } else { result.Add(content); } } return(result); }
public override bool Evaluate() { // Drill down to a single POSPhrase List <IParsedPhrase> unmatched = new List <IParsedPhrase>(matcher.Unmatched); IParsedPhrase input = matcher.Input; while (!input.IsLeaf) { GroupPhrase groupPhrase = new GroupPhrase(input); unmatched.InsertRange(0, groupPhrase.GetRange(1)); input = groupPhrase.GetBranch(0); } List <IContent> elements = matcher.Context.LookupDefaulted <List <IContent> >(name, new List <IContent>()); elements.Add(new Word(input.Text)); Context eaten; if (needRemoval) { eaten = new Context(matcher.Context, matcher.Context.Contents.GetRange(1, matcher.Context.Contents.Count - 1)); } else { eaten = new Context(matcher.Context, matcher.Context.Contents); } eaten.Map.Add(name, elements); // Continue matcher if (unmatched.Count == 0) { if (eaten.Contents.Count == 0 || Matcher.IsRemainderOptional(eaten.Contents)) { matcher.Success.Continue(eaten, matcher.Failure); } else { matcher.Failure.Fail("Ran out of input after *.", matcher.Success); } } else { // This matcher is for StarEater to eat another Matcher clone = (Matcher)matcher.Clone(); clone.Context = eaten; clone.Input = unmatched[0]; clone.Unmatched = unmatched.GetRange(1, unmatched.Count - 1); StarEater eater = new StarEater(coderack, salience, clone, name, false); if (eaten.Contents.Count == 0) { // Just add ourselves again coderack.AddCodelet(eater, "Evaluate empty"); } else { Matcher.MatchAgainst(salience, eaten, clone.Input, clone.Unmatched, matcher.Success, eater); } } return(true); }
private void ParseGroupPhrase(GroupPhrase phrase) { }
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?IsMatch(IParsedPhrase check) { string verb; if (check.IsLeaf || !check.Text.Contains(" ")) { verb = check.Text; if (Verbs.IsToHave(verb)) { if (bases.Contains("have")) { return(true); } else { return(null); } } if (Verbs.IsToBe(verb)) { if (bases.Contains("be")) { return(true); } else { return(null); } } if (Verbs.IsToDo(verb)) { if (bases.Contains("do")) { return(true); } else { return(null); } } if (verb == "will" || verb == "shall") { return(null); // not sure yet } } else { GroupPhrase groupPhrase = new GroupPhrase(check); if (groupPhrase.Count > 2) { return(false); } string helper = groupPhrase.GetBranch(0).Text.ToLower(); verb = groupPhrase.GetBranch(1).Text.ToLower(); if (!Verbs.IsToHave(helper) && !Verbs.IsToBe(helper) && !Verbs.IsToDo(helper) && helper != "will" && helper != "shall") { return(false); } } string baseverb = verbs.InputToBase(verb); return(comparer.MatchAny(verb, options) || comparer.MatchAny(verb, bases) || comparer.MatchAny(baseverb, bases)); }