protected override bool IsFeatureMatch(Segment seg, VariableValues instantiatedVars, ModeType mode) { if (!base.IsFeatureMatch(seg, instantiatedVars, mode)) { return(false); } if (m_alphaVars != null) { // only one possible binding during synthesis if (Owner.IsTarget) { if (!m_alphaVars.GetBinding(m_variables, seg, instantiatedVars)) { return(false); } } else if (mode == ModeType.SYNTHESIS) { if (!m_alphaVars.GetBinding(m_variables, seg, instantiatedVars)) { // when a variable is specified in a target and environment for agreement, the environment // must specify a feature for each variable foreach (KeyValuePair <string, bool> varPolarity in m_variables) { // check each variable to see which one is not specified in the environment if (!m_alphaVars.GetBinding(varPolarity.Key, varPolarity.Value, seg, new VariableValues(m_alphaVars))) { Feature f = m_alphaVars.GetFeature(varPolarity.Key); MorphException me = new MorphException(MorphException.MorphErrorType.UNINSTANTIATED_FEATURE, m_natClass.Morpher, string.Format(HCStrings.kstidUninstEnv, f.ID)); me.Data["feature"] = f.ID; throw me; } } return(false); } } else { // during analysis, get all possible bindings, since a feature could // be uninstantiated if (!m_alphaVars.GetAllBindings(m_variables, seg, instantiatedVars)) { return(false); } } } return(true); }
void ApplyInsertion(Direction dir, IList <PhoneticShapeNode> match, VariableValues instantiatedVars) { PhoneticShapeNode cur = match[match.Count - 1]; for (PhoneticPatternNode pseqNode = m_rhs.GetFirst(dir); pseqNode != null; pseqNode = pseqNode.GetNext(dir)) { PhoneticShapeNode newNode = null; switch (pseqNode.Type) { case PhoneticPatternNode.NodeType.SIMP_CTXT: SimpleContext ctxt = pseqNode as SimpleContext; newNode = ctxt.ApplyInsertion(instantiatedVars); break; case PhoneticPatternNode.NodeType.BDRY_CTXT: newNode = new Boundary(pseqNode as BoundaryContext); break; } if (newNode != null) { try { cur.Insert(newNode, dir); } catch (InvalidOperationException ioe) { MorphException me = new MorphException(MorphException.MorphErrorType.TOO_MANY_SEGS, m_rule.Morpher, string.Format(HCStrings.kstidTooManySegs, m_rule.ID), ioe); me.Data["rule"] = m_rule.ID; throw me; } cur = newNode; } } }
public virtual void Write(MorphException me) { m_out.WriteLine("Morph Error: " + me.Message); m_out.WriteLine(); }
void ApplyInsertion(Direction dir, IList<PhoneticShapeNode> match, VariableValues instantiatedVars) { PhoneticShapeNode cur = match[match.Count - 1]; for (PhoneticPatternNode pseqNode = m_rhs.GetFirst(dir); pseqNode != null; pseqNode = pseqNode.GetNext(dir)) { PhoneticShapeNode newNode = null; switch (pseqNode.Type) { case PhoneticPatternNode.NodeType.SIMP_CTXT: SimpleContext ctxt = pseqNode as SimpleContext; newNode = ctxt.ApplyInsertion(instantiatedVars); break; case PhoneticPatternNode.NodeType.BDRY_CTXT: newNode = new Boundary(pseqNode as BoundaryContext); break; } if (newNode != null) { try { cur.Insert(newNode, dir); } catch (InvalidOperationException ioe) { MorphException me = new MorphException(MorphException.MorphErrorType.TOO_MANY_SEGS, m_rule.Morpher, string.Format(HCStrings.kstidTooManySegs, m_rule.ID), ioe); me.Data["rule"] = m_rule.ID; throw me; } cur = newNode; } } }
/// <summary> /// Does the real work of morphing the specified word. /// </summary> /// <param name="word">The word.</param> /// <param name="prev">The previous word.</param> /// <param name="next">The next word.</param> /// <param name="trace">The trace.</param> /// <returns>All valid word synthesis records.</returns> ICollection <WordSynthesis> MorphAndLookupToken(string word, string prev, string next, out WordAnalysisTrace trace, string[] selectTraceMorphs) { // convert the word to its phonetic shape PhoneticShape input = SurfaceStratum.CharacterDefinitionTable.ToPhoneticShape(word, ModeType.ANALYSIS); // if word contains invalid segments, the char def table will return null if (input == null) { MorphException me = new MorphException(MorphException.MorphErrorType.INVALID_SHAPE, this, string.Format(HCStrings.kstidInvalidWord, word, SurfaceStratum.CharacterDefinitionTable.ID)); me.Data["shape"] = word; me.Data["charDefTable"] = SurfaceStratum.CharacterDefinitionTable.ID; throw me; } // create the root of the trace tree trace = new WordAnalysisTrace(word, input.Clone()); Set <WordSynthesis> candidates = new Set <WordSynthesis>(); Set <WordAnalysis> inAnalysis = new Set <WordAnalysis>(); Set <WordAnalysis> outAnalysis = new Set <WordAnalysis>(); inAnalysis.Add(new WordAnalysis(input, SurfaceStratum, trace)); // Unapply rules for (int i = m_strata.Count - 1; i >= 0; i--) { outAnalysis.Clear(); foreach (WordAnalysis wa in inAnalysis) { if (m_traceStrataAnalysis) { // create the stratum analysis input trace record StratumAnalysisTrace stratumTrace = new StratumAnalysisTrace(m_strata[i], true, wa.Clone()); wa.CurrentTrace.AddChild(stratumTrace); } foreach (WordAnalysis outWa in m_strata[i].Unapply(wa, candidates, selectTraceMorphs)) { // promote each analysis to the next stratum if (i != 0) { outWa.Stratum = m_strata[i - 1]; } if (m_traceStrataAnalysis) { // create the stratum analysis output trace record for the output word synthesis outWa.CurrentTrace.AddChild(new StratumAnalysisTrace(m_strata[i], false, outWa.Clone())); } outAnalysis.Add(outWa); } } inAnalysis.Clear(); inAnalysis.AddMany(outAnalysis); } Set <WordSynthesis> allValidSyntheses = new Set <WordSynthesis>(); // Apply rules for each candidate entry foreach (WordSynthesis candidate in candidates) { Set <WordSynthesis> inSynthesis = new Set <WordSynthesis>(); Set <WordSynthesis> outSynthesis = new Set <WordSynthesis>(); for (int i = 0; i < m_strata.Count; i++) { // start applying at the stratum that this lex entry belongs to if (m_strata[i] == candidate.Root.Stratum) { inSynthesis.Add(candidate); } outSynthesis.Clear(); foreach (WordSynthesis cur in inSynthesis) { if (m_traceStrataSynthesis) { // create the stratum synthesis input trace record StratumSynthesisTrace stratumTrace = new StratumSynthesisTrace(m_strata[i], true, cur.Clone()); cur.CurrentTrace.AddChild(stratumTrace); } foreach (WordSynthesis outWs in m_strata[i].Apply(cur)) { // promote the word synthesis to the next stratum if (i != m_strata.Count - 1) { outWs.Stratum = m_strata[i + 1]; } if (m_traceStrataSynthesis) { // create the stratum synthesis output trace record for the output analysis outWs.CurrentTrace.AddChild(new StratumSynthesisTrace(m_strata[i], false, outWs.Clone())); } outSynthesis.Add(outWs); } } inSynthesis.Clear(); inSynthesis.AddMany(outSynthesis); } foreach (WordSynthesis ws in outSynthesis) { if (ws.IsValid) { allValidSyntheses.Add(ws); } } } Set <WordSynthesis> results = new Set <WordSynthesis>(); // sort the resulting syntheses according to the order of precedence of each allomorph in // their respective morphemes List <WordSynthesis> sortedSyntheses = new List <WordSynthesis>(allValidSyntheses); sortedSyntheses.Sort(); WordSynthesis prevValidSynthesis = null; foreach (WordSynthesis cur in sortedSyntheses) { // enforce the disjunctive property of allomorphs by ensuring that this word synthesis // has the highest order of precedence for its allomorphs while also allowing for free // fluctuation, also check that the phonetic shape matches the original input word if ((prevValidSynthesis == null || AreAllomorphsNondisjunctive(cur, prevValidSynthesis)) && SurfaceStratum.CharacterDefinitionTable.IsMatch(word, cur.Shape)) { if (m_traceSuccess) { // create the report a success output trace record for the output analysis cur.CurrentTrace.AddChild(new ReportSuccessTrace(cur)); } // do not add to the result if it has the same root, shape, and morphemes as another result bool duplicate = false; foreach (WordSynthesis ws in results) { if (cur.Duplicates(ws)) { duplicate = true; break; } } if (!duplicate) { results.Add(cur); } } prevValidSynthesis = cur; } return(results); }
public virtual void Write(MorphException me) { m_xmlWriter.WriteElementString("MorphError", me.Message); }
/// <summary> /// Does the real work of morphing the specified word. /// </summary> /// <param name="word">The word.</param> /// <param name="prev">The previous word.</param> /// <param name="next">The next word.</param> /// <param name="trace">The trace.</param> /// <param name="selectTraceMorphs"></param> /// <returns>All valid word synthesis records.</returns> ICollection<WordSynthesis> MorphAndLookupToken(string word, string prev, string next, TraceManager trace, string[] selectTraceMorphs) { PhoneticShape input; try { // convert the word to its phonetic shape; it could throw a missing phonetic shape exception input = SurfaceStratum.CharacterDefinitionTable.ToPhoneticShape(word, ModeType.ANALYSIS); } catch (MissingPhoneticShapeException mpse) { var me = new MorphException(MorphException.MorphErrorType.INVALID_SHAPE, this, string.Format(HCStrings.kstidInvalidWord, word, SurfaceStratum.CharacterDefinitionTable.ID, mpse.Position+1, word.Substring(mpse.Position), mpse.PhonemesFoundSoFar)); me.Data["shape"] = word; me.Data["charDefTable"] = SurfaceStratum.CharacterDefinitionTable.ID; me.Data["position"] = mpse.Position; me.Data["phonemesFoundSoFar"] = mpse.PhonemesFoundSoFar; throw me; } var inputAnalysis = new WordAnalysis(input, SurfaceStratum); if (trace != null) trace.BeginAnalyzeWord(word, inputAnalysis); var candidates = new Set<WordSynthesis>(); var inAnalysis = new Set<WordAnalysis>(); var outAnalysis = new Set<WordAnalysis>(); inAnalysis.Add(inputAnalysis); // Unapply rules for (int i = m_strata.Count - 1; i >= 0; i--) { outAnalysis.Clear(); foreach (WordAnalysis wa in inAnalysis) { if (trace != null) trace.BeginUnapplyStratum(m_strata[i], wa); foreach (WordAnalysis outWa in m_strata[i].Unapply(wa, trace, selectTraceMorphs, candidates)) { // promote each analysis to the next stratum if (i != 0) outWa.Stratum = m_strata[i - 1]; if (trace != null) trace.EndUnapplyStratum(m_strata[i], outWa); outAnalysis.Add(outWa); } } inAnalysis.Clear(); inAnalysis.AddMany(outAnalysis); } var allValidSyntheses = new Set<WordSynthesis>(); // Apply rules for each candidate entry foreach (WordSynthesis candidate in candidates) { var inSynthesis = new Set<WordSynthesis>(); var outSynthesis = new Set<WordSynthesis>(); for (int i = 0; i < m_strata.Count; i++) { // start applying at the stratum that this lex entry belongs to if (m_strata[i] == candidate.Root.Stratum) inSynthesis.Add(candidate); outSynthesis.Clear(); foreach (WordSynthesis cur in inSynthesis) { if (trace != null) trace.BeginApplyStratum(m_strata[i], cur); foreach (WordSynthesis outWs in m_strata[i].Apply(cur, trace)) { // promote the word synthesis to the next stratum if (i != m_strata.Count - 1) outWs.Stratum = m_strata[i + 1]; if (trace != null) trace.EndApplyStratum(m_strata[i], outWs); outSynthesis.Add(outWs); } } inSynthesis.Clear(); inSynthesis.AddMany(outSynthesis); } foreach (WordSynthesis ws in outSynthesis) { if (ws.IsValid(trace)) allValidSyntheses.Add(ws); } } var results = new Set<WordSynthesis>(); // sort the resulting syntheses according to the order of precedence of each allomorph in // their respective morphemes var sortedSyntheses = new List<WordSynthesis>(allValidSyntheses); sortedSyntheses.Sort(); WordSynthesis prevValidSynthesis = null; bool allFreeFluctuation = true; foreach (WordSynthesis cur in sortedSyntheses) { // enforce the disjunctive property of allomorphs by ensuring that this word synthesis // has the highest order of precedence for its allomorphs while also allowing for free // fluctuation if (prevValidSynthesis == null || AreAllomorphsNondisjunctive(cur, prevValidSynthesis)) { AddResult(word, results, cur, trace); allFreeFluctuation = true; } else if (allFreeFluctuation && CheckFreeFluctuation(cur, prevValidSynthesis)) { AddResult(word, results, cur, trace); } else { allFreeFluctuation = false; } prevValidSynthesis = cur; } return results; } // end MorphAndLookupToken
protected override bool IsFeatureMatch(Segment seg, VariableValues instantiatedVars, ModeType mode) { if (!base.IsFeatureMatch(seg, instantiatedVars, mode)) return false; if (m_alphaVars != null) { // only one possible binding during synthesis if (Owner.IsTarget) { if (!m_alphaVars.GetBinding(m_variables, seg, instantiatedVars)) return false; } else if (mode == ModeType.SYNTHESIS) { if (!m_alphaVars.GetBinding(m_variables, seg, instantiatedVars)) { // when a variable is specified in a target and environment for agreement, the environment // must specify a feature for each variable foreach (KeyValuePair<string, bool> varPolarity in m_variables) { // check each variable to see which one is not specified in the environment if (!m_alphaVars.GetBinding(varPolarity.Key, varPolarity.Value, seg, new VariableValues(m_alphaVars))) { Feature f = m_alphaVars.GetFeature(varPolarity.Key); MorphException me = new MorphException(MorphException.MorphErrorType.UNINSTANTIATED_FEATURE, m_natClass.Morpher, string.Format(HCStrings.kstidUninstEnv, f.ID)); me.Data["feature"] = f.ID; throw me; } } return false; } } else { // during analysis, get all possible bindings, since a feature could // be uninstantiated if (!m_alphaVars.GetAllBindings(m_variables, seg, instantiatedVars)) return false; } } return true; }
public override void Write(MorphException me) { m_xmlWriter.WriteStartElement("Error"); switch (me.ErrorType) { case MorphException.MorphErrorType.INVALID_SHAPE: string shape = me.Data["shape"] as string; m_xmlWriter.WriteString(string.Format(ParserCoreStrings.ksHCInvalidWordform, shape)); break; case MorphException.MorphErrorType.UNINSTANTIATED_FEATURE: string featId = me.Data["feature"] as string; Feature feat = me.Morpher.PhoneticFeatureSystem.GetFeature(featId); m_xmlWriter.WriteString(string.Format(ParserCoreStrings.ksHCUninstFeature, feat.Description)); break; default: m_xmlWriter.WriteString(string.Format(ParserCoreStrings.ksHCDefaultErrorMsg, me.Message)); break; } m_xmlWriter.WriteEndElement(); }
private void Write(XmlWriter writer, MorphException me) { writer.WriteStartElement("Error"); writer.WriteString(ProcessMorphException(me)); writer.WriteEndElement(); }
private string ProcessMorphException(MorphException me) { string errorMessage; switch (me.ErrorType) { case MorphException.MorphErrorType.INVALID_SHAPE: var shape = (string)me.Data["shape"]; var position = (int)me.Data["position"]; var phonemesFoundSoFar = (string)me.Data["phonemesFoundSoFar"]; string rest = shape.Substring(position); string restToUse = rest; LgGeneralCharCategory cc = m_cache.ServiceLocator.UnicodeCharProps.get_GeneralCategory(rest[0]); if (cc == LgGeneralCharCategory.kccMn) { // the first character is a diacritic, combining type of character // insert a space so it does not show on top of a single quote in the message string restToUse = " " + rest; } errorMessage = String.Format(ParserCoreStrings.ksHCInvalidWordform, shape, position + 1, restToUse, phonemesFoundSoFar); break; case MorphException.MorphErrorType.UNINSTANTIATED_FEATURE: var featId = me.Data["feature"] as string; var feat = me.Morpher.PhoneticFeatureSystem.GetFeature(featId); errorMessage = String.Format(ParserCoreStrings.ksHCUninstFeature, feat.Description); break; default: errorMessage = String.Format(ParserCoreStrings.ksHCDefaultErrorMsg, me.Message); break; } return errorMessage; }
/// <summary> /// Does the real work of morphing the specified word. /// </summary> /// <param name="word">The word.</param> /// <param name="prev">The previous word.</param> /// <param name="next">The next word.</param> /// <param name="trace">The trace.</param> /// <returns>All valid word synthesis records.</returns> ICollection<WordSynthesis> MorphAndLookupToken(string word, string prev, string next, out WordAnalysisTrace trace) { // convert the word to its phonetic shape PhoneticShape input = SurfaceStratum.CharacterDefinitionTable.ToPhoneticShape(word, ModeType.ANALYSIS); // if word contains invalid segments, the char def table will return null if (input == null) { MorphException me = new MorphException(MorphException.MorphErrorType.INVALID_SHAPE, this, string.Format(HCStrings.kstidInvalidWord, word, SurfaceStratum.CharacterDefinitionTable.ID)); me.Data["shape"] = word; me.Data["charDefTable"] = SurfaceStratum.CharacterDefinitionTable.ID; throw me; } // create the root of the trace tree trace = new WordAnalysisTrace(word, input.Clone()); Set<WordSynthesis> candidates = new Set<WordSynthesis>(); Set<WordAnalysis> inAnalysis = new Set<WordAnalysis>(); Set<WordAnalysis> outAnalysis = new Set<WordAnalysis>(); inAnalysis.Add(new WordAnalysis(input, SurfaceStratum, trace)); // Unapply rules for (int i = m_strata.Count - 1; i >= 0; i--) { outAnalysis.Clear(); foreach (WordAnalysis wa in inAnalysis) { if (m_traceStrataAnalysis) { // create the stratum analysis input trace record StratumAnalysisTrace stratumTrace = new StratumAnalysisTrace(m_strata[i], true, wa.Clone()); wa.CurrentTrace.AddChild(stratumTrace); } foreach (WordAnalysis outWa in m_strata[i].Unapply(wa, candidates)) { // promote each analysis to the next stratum if (i != 0) outWa.Stratum = m_strata[i - 1]; if (m_traceStrataAnalysis) // create the stratum analysis output trace record for the output word synthesis outWa.CurrentTrace.AddChild(new StratumAnalysisTrace(m_strata[i], false, outWa.Clone())); outAnalysis.Add(outWa); } } inAnalysis.Clear(); inAnalysis.AddMany(outAnalysis); } Set<WordSynthesis> allValidSyntheses = new Set<WordSynthesis>(); // Apply rules for each candidate entry foreach (WordSynthesis candidate in candidates) { Set<WordSynthesis> inSynthesis = new Set<WordSynthesis>(); Set<WordSynthesis> outSynthesis = new Set<WordSynthesis>(); for (int i = 0; i < m_strata.Count; i++) { // start applying at the stratum that this lex entry belongs to if (m_strata[i] == candidate.Root.Stratum) inSynthesis.Add(candidate); outSynthesis.Clear(); foreach (WordSynthesis cur in inSynthesis) { if (m_traceStrataSynthesis) { // create the stratum synthesis input trace record StratumSynthesisTrace stratumTrace = new StratumSynthesisTrace(m_strata[i], true, cur.Clone()); cur.CurrentTrace.AddChild(stratumTrace); } foreach (WordSynthesis outWs in m_strata[i].Apply(cur)) { // promote the word synthesis to the next stratum if (i != m_strata.Count - 1) outWs.Stratum = m_strata[i + 1]; if (m_traceStrataSynthesis) // create the stratum synthesis output trace record for the output analysis outWs.CurrentTrace.AddChild(new StratumSynthesisTrace(m_strata[i], false, outWs.Clone())); outSynthesis.Add(outWs); } } inSynthesis.Clear(); inSynthesis.AddMany(outSynthesis); } foreach (WordSynthesis ws in outSynthesis) { if (ws.IsValid) allValidSyntheses.Add(ws); } } Set<WordSynthesis> results = new Set<WordSynthesis>(); // sort the resulting syntheses according to the order of precedence of each allomorph in // their respective morphemes List<WordSynthesis> sortedSyntheses = new List<WordSynthesis>(allValidSyntheses); sortedSyntheses.Sort(); WordSynthesis prevValidSynthesis = null; foreach (WordSynthesis cur in sortedSyntheses) { // enforce the disjunctive property of allomorphs by ensuring that this word synthesis // has the highest order of precedence for its allomorphs, also check that the phonetic // shape matches the original input word if ((prevValidSynthesis == null || !cur.Morphs.SameMorphemes(prevValidSynthesis.Morphs)) && SurfaceStratum.CharacterDefinitionTable.IsMatch(word, cur.Shape)) { if (m_traceSuccess) // create the report a success output trace record for the output analysis cur.CurrentTrace.AddChild(new ReportSuccessTrace(cur)); // do not add to the result if it has the same root, shape, and morphemes as another result bool duplicate = false; foreach (WordSynthesis ws in results) { if (cur.Duplicates(ws)) { duplicate = true; break; } } if (!duplicate) { results.Add(cur); } } prevValidSynthesis = cur; } return results; }