/// <summary> /// Unapplies all of the rules to the specified input word analysis. All matching lexical /// entries are added to the <c>candidates</c> parameter. /// </summary> /// <param name="input">The input word analysis.</param> /// <param name="candidates">The set of candidate word synthesis records.</param> /// <returns>All word analyses that result from the unapplication of rules.</returns> public IEnumerable <WordAnalysis> Unapply(WordAnalysis input, ICollection <WordSynthesis> candidates) { if (m_isCyclic) { throw new NotImplementedException(HCStrings.kstidCyclicStratumNotSupported); } if (m_pruleOrder == PRuleOrder.SIMULTANEOUS) { throw new NotImplementedException(HCStrings.kstidSimultOrderNotSupported); } WordAnalysis wa = input.Clone(); UnapplyPhonologicalRules(wa); LexicalLookup(wa, candidates); Set <WordAnalysis> tempOutput = new Set <WordAnalysis>(); tempOutput.Add(wa); UnapplyTemplates(wa, tempOutput, candidates); Set <WordAnalysis> output = new Set <WordAnalysis>(); // TODO: handle cyclicity foreach (WordAnalysis analysis in tempOutput) { UnapplyMorphologicalRules(analysis, m_mrules.Count - 1, 0, candidates, output); } return(output); }
/// <summary> /// Unapplies this affix template to specified input word analysis. /// </summary> /// <param name="input">The input word analysis.</param> /// <param name="output">The output word analyses.</param> /// <returns>The resulting word analyses.</returns> public bool Unapply(WordAnalysis input, out IEnumerable <WordAnalysis> output, string[] selectTraceMorphs) { Set <WordAnalysis> results = new Set <WordAnalysis>(); if (Morpher.TraceTemplatesAnalysis) { // create the template analysis trace input record TemplateAnalysisTrace tempTrace = new TemplateAnalysisTrace(this, true, input.Clone()); input.CurrentTrace.AddChild(tempTrace); } UnapplySlots(input.Clone(), m_slots.Count - 1, results, selectTraceMorphs); foreach (WordAnalysis wa in results) { foreach (PartOfSpeech pos in m_requiredPOSs) { wa.AddPOS(pos); } } if (results.Count > 0) { output = results; return(true); } else { output = null; return(false); } }
public override void EndUnapplyPhonologicalRule(PhonologicalRule rule, WordAnalysis output) { if (m_currentAnalysisPruleTrace != null) { m_currentAnalysisPruleTrace.Output = output.Clone(); m_currentAnalysisPruleTrace = null; } }
/// <summary> /// Performs any post-processing required after the unapplication of a word analysis. This must /// be called after a successful <c>BeginUnapplication</c> call and any <c>Unapply</c> calls. /// </summary> /// <param name="input">The input word analysis.</param> /// <param name="unapplied">if set to <c>true</c> if the input word analysis was successfully unapplied.</param> public override void EndUnapplication(WordAnalysis input, bool unapplied) { if (TraceAnalysis && !unapplied) { // create the morphological rule analysis trace record for a rule that did not succesfully unapply input.CurrentTrace.AddChild(new MorphologicalRuleAnalysisTrace(this, input.Clone())); } }
public override void BeginUnapplyPhonologicalRule(PhonologicalRule rule, WordAnalysis input) { if (IsAnalysisTracingEnabled(rule.ID)) { m_currentAnalysisPruleTrace = new PhonologicalRuleAnalysisTrace(rule, input.Clone()); ((Trace) input.CurrentTraceObject).AddChild(m_currentAnalysisPruleTrace); } }
/// <summary> /// Unapplies this subrule to the input word analysis. /// </summary> /// <param name="input">The input word analysis.</param> /// <param name="output">The output word analyses.</param> /// <returns><c>true</c> if the subrule was successfully unapplied, otherwise <c>false</c></returns> public bool Unapply(WordAnalysis input, out ICollection <WordAnalysis> output) { VariableValues instantiatedVars = new VariableValues(m_alphaVars); IList <Match> matches; m_transform.RHSTemplate.IsMatch(input.Shape.First, Direction.RIGHT, ModeType.ANALYSIS, instantiatedVars, out matches); List <WordAnalysis> outputList = new List <WordAnalysis>(); output = outputList; foreach (Match match in matches) { PhoneticShape headShape; PhoneticShape nonHeadShape; UnapplyRHS(match, out headShape, out nonHeadShape); // for computational complexity reasons, we ensure that the non-head is a root, otherwise we assume it is not // a valid analysis and throw it away foreach (LexEntry.RootAllomorph allo in Morpheme.Stratum.SearchEntries(nonHeadShape)) { // check to see if this is a duplicate of another output analysis, this is not strictly necessary, but // it helps to reduce the search space bool add = true; for (int i = 0; i < output.Count; i++) { if (headShape.Duplicates(outputList[i].Shape) && allo == outputList[i].NonHead.RootAllomorph) { if (headShape.Count > outputList[i].Shape.Count) { // if this is a duplicate and it is longer, then use this analysis and remove the previous one outputList.RemoveAt(i); } else { // if it is shorter, then do not add it to the output list add = false; } break; } } if (add) { WordAnalysis wa = input.Clone(); wa.Shape = headShape; wa.NonHead = new WordAnalysis(nonHeadShape, wa.Stratum, null); wa.NonHead.RootAllomorph = allo; output.Add(wa); } } } return(outputList.Count > 0); }
public override void MorphologicalRuleUnapplied(MorphologicalRule rule, WordAnalysis input, WordAnalysis output, Allomorph allomorph) { if (IsAnalysisTracingEnabled(rule.ID)) { // create the morphological rule analysis trace record for each output analysis var trace = new MorphologicalRuleAnalysisTrace(rule, input.Clone()) {RuleAllomorph = allomorph, Output = output.Clone()}; ((Trace) output.CurrentTraceObject).AddChild(trace); // set current trace record to the morphological rule trace record for each // output analysis output.CurrentTraceObject = trace; } }
/// <summary> /// Unapplies the rule to the specified word analysis. /// </summary> /// <param name="input">The input word analysis.</param> public override void Unapply(WordAnalysis input) { PhonologicalRuleAnalysisTrace trace = null; if (TraceAnalysis) { // create phonological rule analysis trace record trace = new PhonologicalRuleAnalysisTrace(this, input.Clone()); input.CurrentTrace.AddChild(trace); } foreach (Subrule sr in m_subrules) { sr.Unapply(input.Shape); } if (trace != null) { // add output to trace record trace.Output = input.Clone(); } }
/// <summary> /// Unapplies this subrule to the input word analysis. /// </summary> /// <param name="input">The input word analysis.</param> /// <param name="output">The output word analyses.</param> /// <returns><c>true</c> if the subrule was successfully unapplied, otherwise <c>false</c></returns> public bool Unapply(WordAnalysis input, out ICollection <WordAnalysis> output) { VariableValues instantiatedVars = new VariableValues(m_alphaVars); IList <Match> matches; m_transform.RHSTemplate.IsMatch(input.Shape.First, Direction.RIGHT, ModeType.ANALYSIS, instantiatedVars, out matches); List <WordAnalysis> outputList = new List <WordAnalysis>(); output = outputList; foreach (Match match in matches) { PhoneticShape shape = UnapplyRHS(match); if (shape.Count > 2) { // check to see if this is a duplicate of another output analysis, this is not strictly necessary, but // it helps to reduce the search space bool add = true; for (int i = 0; i < output.Count; i++) { if (shape.Duplicates(outputList[i].Shape)) { if (shape.Count > outputList[i].Shape.Count) { // if this is a duplicate and it is longer, then use this analysis and remove the previous one outputList.RemoveAt(i); } else { // if it is shorter, then do not add it to the output list add = false; } break; } } if (add) { WordAnalysis wa = input.Clone(); wa.Shape = shape; output.Add(wa); } } } return(outputList.Count > 0); }
void UnapplySlots(WordAnalysis input, int sIndex, Set <WordAnalysis> output, string[] selectTraceMorphs) { for (int i = sIndex; i >= 0; i--) { foreach (MorphologicalRule rule in m_slots[i].MorphologicalRules) { if (rule.BeginUnapplication(input)) { bool ruleUnapplied = false; for (int j = 0; j < rule.SubruleCount; j++) { ICollection <WordAnalysis> analyses; if (rule.Unapply(input, j, out analyses, selectTraceMorphs)) { ruleUnapplied = true; foreach (WordAnalysis wa in analyses) { if (wa.Shape.Count > 2) { UnapplySlots(wa, i - 1, output, selectTraceMorphs); } } } } rule.EndUnapplication(input, ruleUnapplied); } } // we can skip this slot if it is optional if (!m_slots[i].IsOptional) { if (Morpher.TraceTemplatesAnalysis) { input.CurrentTrace.AddChild(new TemplateAnalysisTrace(this, false, null)); } return; } } if (Morpher.TraceTemplatesAnalysis) { input.CurrentTrace.AddChild(new TemplateAnalysisTrace(this, false, input.Clone())); } output.Add(input); }
void LexicalLookup(WordAnalysis input, ICollection <WordSynthesis> candidates, string[] selectTraceMorphs) { LexLookupTrace lookupTrace = null; if (Morpher.TraceLexLookup) { // create lexical lookup trace record lookupTrace = new LexLookupTrace(this, input.Shape.Clone()); input.CurrentTrace.AddChild(lookupTrace); } foreach (SegmentDefinitionTrie <LexEntry.RootAllomorph> .Match match in m_entryTrie.Search(input.Shape)) { // don't allow a compound where both roots are the same if (input.NonHead == null || input.NonHead.RootAllomorph.Morpheme != match.Value.Morpheme) { LexEntry entry = (LexEntry)match.Value.Morpheme; if (IgnoreEntry(entry, selectTraceMorphs)) { continue; } foreach (LexEntry.RootAllomorph allomorph in entry.Allomorphs) { WordAnalysis wa = input.Clone(); wa.RootAllomorph = allomorph; if (Morpher.TraceLexLookup) { // successful lookup, so create word synthesis trace record WordSynthesisTrace wsTrace = new WordSynthesisTrace(wa.RootAllomorph, wa.UnappliedMorphologicalRules, wa.RealizationalFeatures.Clone()); lookupTrace.AddChild(wsTrace); wa.CurrentTrace = wsTrace; } candidates.Add(new WordSynthesis(wa)); } } } }
/// <summary> /// Unapplies all of the rules to the specified input word analysis. All matching lexical /// entries are added to the <c>candidates</c> parameter. /// </summary> /// <param name="input">The input word analysis.</param> /// <param name="candidates">The set of candidate word synthesis records.</param> /// <returns>All word analyses that result from the unapplication of rules.</returns> public IEnumerable <WordAnalysis> Unapply(WordAnalysis input, ICollection <WordSynthesis> candidates, string[] selectTraceMorphs) { if (m_isCyclic) { throw new NotImplementedException(HCStrings.kstidCyclicStratumNotSupported); } if (m_pruleOrder == PRuleOrder.SIMULTANEOUS) { throw new NotImplementedException(HCStrings.kstidSimultOrderNotSupported); } WordAnalysis wa = input.Clone(); UnapplyPhonologicalRules(wa); LexicalLookup(wa, candidates, selectTraceMorphs); Set <WordAnalysis> output = new Set <WordAnalysis>(); UnapplyMorphologicalRulesAndTemplates(wa, output, candidates, selectTraceMorphs); return(output); }
/// <summary> /// Unapplies the specified subrule to the specified word analysis. /// </summary> /// <param name="input">The input word analysis.</param> /// <param name="srIndex">Index of the subrule.</param> /// <param name="output">All resulting word analyses.</param> /// <returns> /// <c>true</c> if the subrule was successfully unapplied, otherwise <c>false</c> /// </returns> public override bool Unapply(WordAnalysis input, int srIndex, out ICollection <WordAnalysis> output) { if (m_subrules[srIndex].Unapply(input, out output)) { foreach (WordAnalysis wa in output) { if (m_headRequiredPOSs != null && m_headRequiredPOSs.Count > 0) { foreach (PartOfSpeech pos in m_headRequiredPOSs) { wa.AddPOS(pos); } } else if (m_outPOS == null) { wa.UninstantiatePOS(); } if (m_nonHeadRequiredPOSs != null) { foreach (PartOfSpeech pos in m_nonHeadRequiredPOSs) { wa.NonHead.AddPOS(pos); } } wa.MorphologicalRuleUnapplied(this); if (TraceAnalysis) { // create the morphological rule analysis trace record for each output analysis MorphologicalRuleAnalysisTrace trace = new MorphologicalRuleAnalysisTrace(this, input.Clone()); trace.RuleAllomorph = m_subrules[srIndex]; trace.Output = wa.Clone(); wa.CurrentTrace.AddChild(trace); // set current trace record to the morphological rule trace record for each // output analysis wa.CurrentTrace = trace; } } return(true); } output = null; return(false); }
/// <summary> /// Unapplies this affix template to specified input word analysis. /// </summary> /// <param name="input">The input word analysis.</param> /// <param name="selectTraceMorphs"></param> /// <param name="output">The output word analyses.</param> /// <param name="trace"></param> /// <returns>The resulting word analyses.</returns> public bool Unapply(WordAnalysis input, TraceManager trace, string[] selectTraceMorphs, out IEnumerable<WordAnalysis> output) { var results = new Set<WordAnalysis>(); if (trace != null) trace.BeginUnapplyTemplate(this, input); UnapplySlots(input.Clone(), m_slots.Count - 1, trace, selectTraceMorphs, results); foreach (WordAnalysis wa in results) { foreach (PartOfSpeech pos in m_requiredPOSs) wa.AddPOS(pos); } if (results.Count > 0) { output = results; return true; } output = null; return false; }
/// <summary> /// Unapplies this affix template to specified input word analysis. /// </summary> /// <param name="input">The input word analysis.</param> /// <param name="output">The output word analyses.</param> /// <returns>The resulting word analyses.</returns> public bool Unapply(WordAnalysis input, out IEnumerable<WordAnalysis> output) { Set<WordAnalysis> results = new Set<WordAnalysis>(); if (Morpher.TraceTemplatesAnalysis) { // create the template analysis trace input record TemplateAnalysisTrace tempTrace = new TemplateAnalysisTrace(this, true, input.Clone()); input.CurrentTrace.AddChild(tempTrace); } UnapplySlots(input.Clone(), m_slots.Count - 1, results); foreach (WordAnalysis wa in results) { foreach (PartOfSpeech pos in m_requiredPOSs) wa.AddPOS(pos); } if (results.Count > 0) { output = results; return true; } else { output = null; return false; } }
public override void MorphologicalRuleNotUnapplied(MorphologicalRule rule, WordAnalysis input) { if (IsAnalysisTracingEnabled(rule.ID)) { // create the morphological rule analysis trace record for a rule that did not succesfully unapply ((Trace) input.CurrentTraceObject).AddChild(new MorphologicalRuleAnalysisTrace(rule, input.Clone())); } }
public override void EndUnapplyTemplate(AffixTemplate template, WordAnalysis output, bool unapplied) { if (TraceTemplatesAnalysis) ((Trace) output.CurrentTraceObject).AddChild(new TemplateAnalysisTrace(template, false, unapplied ? output.Clone() : null)); }
/// <summary> /// Unapplies the rule to the specified word analysis. /// </summary> /// <param name="input">The input word analysis.</param> public override void Unapply(WordAnalysis input) { PhonologicalRuleAnalysisTrace trace = null; if (TraceAnalysis) { // create phonological rule analysis trace record trace = new PhonologicalRuleAnalysisTrace(this, input.Clone()); input.CurrentTrace.AddChild(trace); } foreach (Subrule sr in m_subrules) sr.Unapply(input.Shape); if (trace != null) // add output to trace record trace.Output = input.Clone(); }
public override void BeginUnapplyStratum(Stratum stratum, WordAnalysis input) { if (TraceStrataAnalysis) ((Trace) input.CurrentTraceObject).AddChild(new StratumAnalysisTrace(stratum, true, input.Clone())); }
public override void EndUnapplyStratum(Stratum stratum, WordAnalysis output) { if (TraceStrataAnalysis) ((Trace) output.CurrentTraceObject).AddChild(new StratumAnalysisTrace(stratum, false, output.Clone())); }
/// <summary> /// Unapplies this subrule to the input word analysis. /// </summary> /// <param name="input">The input word analysis.</param> /// <param name="output">The output word analyses.</param> /// <returns><c>true</c> if the subrule was successfully unapplied, otherwise <c>false</c></returns> public bool Unapply(WordAnalysis input, out ICollection<WordAnalysis> output) { VariableValues instantiatedVars = new VariableValues(m_alphaVars); IList<Match> matches; m_transform.RHSTemplate.IsMatch(input.Shape.First, Direction.RIGHT, ModeType.ANALYSIS, instantiatedVars, out matches); List<WordAnalysis> outputList = new List<WordAnalysis>(); output = outputList; foreach (Match match in matches) { PhoneticShape shape = UnapplyRHS(match); if (shape.Count > 2) { // check to see if this is a duplicate of another output analysis, this is not strictly necessary, but // it helps to reduce the search space bool add = true; for (int i = 0; i < output.Count; i++) { if (shape.Duplicates(outputList[i].Shape)) { if (shape.Count > outputList[i].Shape.Count) // if this is a duplicate and it is longer, then use this analysis and remove the previous one outputList.RemoveAt(i); else // if it is shorter, then do not add it to the output list add = false; break; } } if (add) { WordAnalysis wa = input.Clone(); wa.Shape = shape; output.Add(wa); } } } return outputList.Count > 0; }
/// <summary> /// Unapplies the specified subrule to the specified word analysis. /// </summary> /// <param name="input">The input word analysis.</param> /// <param name="srIndex">Index of the subrule.</param> /// <param name="output">All resulting word analyses.</param> /// <returns> /// <c>true</c> if the subrule was successfully unapplied, otherwise <c>false</c> /// </returns> public override bool Unapply(WordAnalysis input, int srIndex, out ICollection<WordAnalysis> output) { if (m_subrules[srIndex].Unapply(input, out output)) { foreach (WordAnalysis wa in output) { if (m_headRequiredPOSs != null && m_headRequiredPOSs.Count > 0) { foreach (PartOfSpeech pos in m_headRequiredPOSs) wa.AddPOS(pos); } else if (m_outPOS == null) { wa.UninstantiatePOS(); } if (m_nonHeadRequiredPOSs != null) { foreach (PartOfSpeech pos in m_nonHeadRequiredPOSs) wa.NonHead.AddPOS(pos); } wa.MorphologicalRuleUnapplied(this); if (TraceAnalysis) { // create the morphological rule analysis trace record for each output analysis MorphologicalRuleAnalysisTrace trace = new MorphologicalRuleAnalysisTrace(this, input.Clone()); trace.RuleAllomorph = m_subrules[srIndex]; trace.Output = wa.Clone(); wa.CurrentTrace.AddChild(trace); // set current trace record to the morphological rule trace record for each // output analysis wa.CurrentTrace = trace; } } return true; } output = null; return false; }
/// <summary> /// Unapplies this subrule to the input word analysis. /// </summary> /// <param name="input">The input word analysis.</param> /// <param name="output">The output word analyses.</param> /// <returns><c>true</c> if the subrule was successfully unapplied, otherwise <c>false</c></returns> public bool Unapply(WordAnalysis input, out ICollection<WordAnalysis> output) { VariableValues instantiatedVars = new VariableValues(m_alphaVars); IList<Match> matches; m_transform.RHSTemplate.IsMatch(input.Shape.First, Direction.RIGHT, ModeType.ANALYSIS, instantiatedVars, out matches); List<WordAnalysis> outputList = new List<WordAnalysis>(); output = outputList; foreach (Match match in matches) { PhoneticShape headShape; PhoneticShape nonHeadShape; UnapplyRHS(match, out headShape, out nonHeadShape); // for computational complexity reasons, we ensure that the non-head is a root, otherwise we assume it is not // a valid analysis and throw it away foreach (LexEntry.RootAllomorph allo in Morpheme.Stratum.SearchEntries(nonHeadShape)) { // check to see if this is a duplicate of another output analysis, this is not strictly necessary, but // it helps to reduce the search space bool add = true; for (int i = 0; i < output.Count; i++) { if (headShape.Duplicates(outputList[i].Shape) && allo == outputList[i].NonHead.RootAllomorph) { if (headShape.Count > outputList[i].Shape.Count) // if this is a duplicate and it is longer, then use this analysis and remove the previous one outputList.RemoveAt(i); else // if it is shorter, then do not add it to the output list add = false; break; } } if (add) { WordAnalysis wa = input.Clone(); wa.Shape = headShape; wa.NonHead = new WordAnalysis(nonHeadShape, wa.Stratum, null); wa.NonHead.RootAllomorph = allo; output.Add(wa); } } } return outputList.Count > 0; }
void UnapplySlots(WordAnalysis input, int sIndex, Set<WordAnalysis> output) { for (int i = sIndex; i >= 0; i--) { foreach (MorphologicalRule rule in m_slots[i].MorphologicalRules) { if (rule.BeginUnapplication(input)) { bool ruleUnapplied = false; for (int j = 0; j < rule.SubruleCount; j++) { ICollection<WordAnalysis> analyses; if (rule.Unapply(input, j, out analyses)) { ruleUnapplied = true; foreach (WordAnalysis wa in analyses) { if (wa.Shape.Count > 2) UnapplySlots(wa, i - 1, output); } } } rule.EndUnapplication(input, ruleUnapplied); } } // we can skip this slot if it is optional if (!m_slots[i].IsOptional) { if (Morpher.TraceTemplatesAnalysis) input.CurrentTrace.AddChild(new TemplateAnalysisTrace(this, false, null)); return; } } if (Morpher.TraceTemplatesAnalysis) input.CurrentTrace.AddChild(new TemplateAnalysisTrace(this, false, input.Clone())); output.Add(input); }
/// <summary> /// Performs any post-processing required after the unapplication of a word analysis. This must /// be called after a successful <c>BeginUnapplication</c> call and any <c>Unapply</c> calls. /// </summary> /// <param name="input">The input word analysis.</param> /// <param name="unapplied">if set to <c>true</c> if the input word analysis was successfully unapplied.</param> public override void EndUnapplication(WordAnalysis input, bool unapplied) { if (TraceAnalysis && !unapplied) // create the morphological rule analysis trace record for a rule that did not succesfully unapply input.CurrentTrace.AddChild(new MorphologicalRuleAnalysisTrace(this, input.Clone())); }
public override void BeginUnapplyTemplate(AffixTemplate template, WordAnalysis input) { if (TraceTemplatesAnalysis) ((Trace) input.CurrentTraceObject).AddChild(new TemplateAnalysisTrace(template, true, input.Clone())); }