public virtual void Write(WordSynthesis ws, bool prettyPrint) { if (prettyPrint) PrettyPrintWordSynthesis(ws); else m_out.WriteLine(ws.ToString()); m_out.WriteLine(); }
public override bool ApplySlotAffix(WordSynthesis input, FeatureValues origHeadFeatures, out ICollection<WordSynthesis> output) { output = null; if (IsBlockedSlotAffix(origHeadFeatures)) return false; return base.ApplySlotAffix(input, origHeadFeatures, out output); }
void PrettyPrintWordSynthesis(WordSynthesis ws) { var sb = new StringBuilder(); sb.Append("ID: "); sb.AppendLine(ws.Root.ID); sb.Append("POS: "); sb.AppendLine(ws.POS.Description); sb.Append("Morphs: "); bool firstItem = true; foreach (Morph morph in ws.Morphs) { string gl = morph.Allomorph.Morpheme.Gloss == null ? "?" : morph.Allomorph.Morpheme.Gloss.Description; string shapeStr = ws.Stratum.CharacterDefinitionTable.ToString(morph.Shape, ModeType.SYNTHESIS, false); int len = Math.Max(shapeStr.Length, gl.Length); if (len > 0) { if (!firstItem) sb.Append(' '); sb.Append(shapeStr.PadRight(len)); firstItem = false; } } sb.AppendLine(); sb.Append("Gloss: "); firstItem = true; foreach (Morph morph in ws.Morphs) { string gl = morph.Allomorph.Morpheme.Gloss == null ? "?" : morph.Allomorph.Morpheme.Gloss.Description; string shapeStr = ws.Stratum.CharacterDefinitionTable.ToString(morph.Shape, ModeType.SYNTHESIS, false); int len = Math.Max(shapeStr.Length, gl.Length); if (len > 0) { if (!firstItem) sb.Append(' '); sb.Append(gl.PadRight(len)); firstItem = false; } } sb.AppendLine(); sb.Append("MPR Features: "); sb.AppendLine(ws.MPRFeatures.ToString()); sb.Append("Head Features: "); sb.AppendLine(ws.HeadFeatures.ToString()); sb.Append("Foot Features: "); sb.Append(ws.FootFeatures); m_out.WriteLine(sb.ToString()); }
public virtual void Write(WordSynthesis ws, bool prettyPrint) { m_xmlWriter.WriteStartElement("Result"); Write("Root", ws.Root); m_xmlWriter.WriteElementString("POS", ws.POS.Description); m_xmlWriter.WriteStartElement("Morphs"); foreach (Morph morph in ws.Morphs) Write("Allomorph", morph.Allomorph); m_xmlWriter.WriteEndElement(); m_xmlWriter.WriteElementString("MPRFeatures", ws.MPRFeatures.ToString()); m_xmlWriter.WriteElementString("HeadFeatures", ws.HeadFeatures.ToString()); m_xmlWriter.WriteElementString("FootFeatures", ws.FootFeatures.ToString()); m_xmlWriter.WriteEndElement(); }
/// <summary> /// Applies the rule to the specified word synthesis. /// </summary> /// <param name="input">The word synthesis.</param> public override void Apply(WordSynthesis input) { PhonologicalRuleSynthesisTrace trace = null; if (TraceSynthesis) { // create phonological rule synthesis trace record trace = new PhonologicalRuleSynthesisTrace(this, input.Clone()); input.CurrentTrace.AddChild(trace); } // only try to apply applicable subrules List<Subrule> subrules = new List<Subrule>(); foreach (Subrule sr in m_subrules) { if (sr.IsApplicable(input)) subrules.Add(sr); } if (subrules.Count > 0) { // set all segments to clean PhoneticShape pshape = input.Shape; foreach (PhoneticShapeNode node in pshape) { if (node.Type == PhoneticShapeNode.NodeType.SEGMENT) (node as Segment).IsClean = true; } switch (m_multApplication) { case MultAppOrder.SIMULTANEOUS: ApplySimultaneous(input.Shape, subrules); break; case MultAppOrder.LR_ITERATIVE: ApplyIterative(input.Shape, Direction.RIGHT, subrules); break; case MultAppOrder.RL_ITERATIVE: ApplyIterative(input.Shape, Direction.LEFT, subrules); break; } } // add output to phonological rule trace record if (trace != null) trace.Output = input.Clone(); }
public override void PhonologicalRuleNotApplicableMPRFeatures(MPRFeaturesType type, WordSynthesis input, MPRFeatureSet mprFeatures) { if (m_currentSynthesisPruleTrace != null) m_currentSynthesisPruleTrace.AddChild(new PhonologicalRuleSynthesisMPRFeaturesTrace(type, input.MPRFeatures, mprFeatures)); }
public override void BeginApplyPhonologicalRule(PhonologicalRule rule, WordSynthesis input) { if (IsSynthesisTracingEnabled(rule.ID)) { m_currentSynthesisPruleTrace = new PhonologicalRuleSynthesisTrace(rule, input.Clone()); ((Trace) input.CurrentTraceObject).AddChild(m_currentSynthesisPruleTrace); } }
/// <summary> /// Applies the rule to the specified word analysis. /// </summary> /// <param name="input">The input word synthesis.</param> /// <param name="output">The output word syntheses.</param> /// <returns> /// <c>true</c> if the rule was successfully applied, otherwise <c>false</c> /// </returns> public override bool Apply(WordSynthesis input, out ICollection<WordSynthesis> output) { output = null; // these should probably be moved to IsApplicable, but we will leave it here for // now so we don't have to call it again to set the features for the output word // synthesis record // check head features FeatureValues headHeadFeatures; if (!m_headRequiredHeadFeatures.UnifyDefaults(input.HeadFeatures, out headHeadFeatures)) return false; FeatureValues nonHeadHeadFeatures; if (!m_nonHeadRequiredHeadFeatures.UnifyDefaults(input.NonHead.HeadFeatures, out nonHeadHeadFeatures)) return false; // check foot features FeatureValues headFootFeatures; if (!m_headRequiredFootFeatures.UnifyDefaults(input.FootFeatures, out headFootFeatures)) return false; FeatureValues nonHeadFootFeatures; if (!m_nonHeadRequiredFootFeatures.UnifyDefaults(input.NonHead.FootFeatures, out nonHeadFootFeatures)) return false; MorphologicalRuleSynthesisTrace trace = null; if (TraceSynthesis) { // create morphological rule synthesis trace record trace = new MorphologicalRuleSynthesisTrace(this, input.Clone()); input.CurrentTrace.AddChild(trace); } output = new List<WordSynthesis>(); foreach (Subrule sr in m_subrules) { WordSynthesis ws; if (sr.Apply(input, out ws)) { if (m_outPOS != null) ws.POS = m_outPOS; if (m_outHeadFeatures != null) ws.HeadFeatures = m_outHeadFeatures.Clone(); ws.HeadFeatures.Add(headHeadFeatures); if (m_outFootFeatures != null) ws.FootFeatures = m_outFootFeatures.Clone(); ws.FootFeatures.Add(headFootFeatures); if (m_obligHeadFeatures != null) { foreach (Feature feature in m_obligHeadFeatures) ws.AddObligatoryHeadFeature(feature); } ws.MorphologicalRuleApplied(this); ws = CheckBlocking(ws); if (trace != null) { // set current trace record to the morphological rule trace record for each // output analysis ws.CurrentTrace = trace; // add output to morphological rule trace record trace.RuleAllomorph = sr; trace.Output = ws.Clone(); } output.Add(ws); // return all word syntheses that match subrules that are constrained by environments, // HC violates the disjunctive property of allomorphs here because it cannot check the // environmental constraints until it has a surface form, we will enforce the disjunctive // property of allomorphs at that time if (sr.RequiredEnvironments == null && sr.ExcludedEnvironments == null) { break; } } } return output.Count > 0; }
void ApplyRHS(Match headMatch, Match nonHeadMatch, WordSynthesis input, WordSynthesis output) { output.Shape.Clear(); output.Morphs.Clear(); output.Shape.Add(new Margin(Direction.LEFT)); foreach (MorphologicalOutput outputMember in m_transform.RHS) { Match curMatch; WordSynthesis curInput; if (outputMember.Partition < m_firstNonHeadPartition) { curMatch = headMatch; curInput = input; } else { curMatch = nonHeadMatch; curInput = input.NonHead; } outputMember.Apply(curMatch, curInput, output, m_morpheme.Gloss != null ? this : null); } output.Shape.Add(new Margin(Direction.RIGHT)); }
/// <summary> /// Initializes a new instance of the <see cref="TemplateSynthesisTrace"/> class. /// </summary> /// <param name="template">The template.</param> /// <param name="input">if <c>true</c> this is an input record, if <c>false</c> this is an output record.</param> /// <param name="synthesis">The input or output word synthesis.</param> internal TemplateSynthesisTrace(AffixTemplate template, bool input, WordSynthesis synthesis) : base(template, input) { m_synthesis = synthesis; }
/// <summary> /// Initializes a new instance of the <see cref="StratumSynthesisTrace"/> class. /// </summary> /// <param name="stratum">The stratum.</param> /// <param name="input">if <c>true</c> this is an input record, if <c>false</c> this is an output record.</param> /// <param name="synthesis">The input or output word synthesis.</param> internal StratumSynthesisTrace(Stratum stratum, bool input, WordSynthesis synthesis) : base(stratum, input) { m_synthesis = synthesis; }
public override void Blocking(BlockType blockingType, WordSynthesis input, LexEntry blockingEntry) { if (TraceBlocking) // create blocking trace record, should this become the current trace? ((Trace) input.CurrentTraceObject).AddChild(new BlockingTrace(BlockingTrace.BlockType.TEMPLATE, blockingEntry)); }
public override void MorphCooccurrenceRuleFailed(MorphCoOccurrence cooccurrence, string usage, WordSynthesis input) { if (TraceTemplatesSynthesis) { var trace = new MorphCoOccurrenceTrace(cooccurrence, usage); ((Trace)input.CurrentTraceObject).AddChild(trace); } }
public override void MorphologicalRuleNotApplied(MorphologicalRule rule, WordSynthesis input) { if (IsSynthesisTracingEnabled(rule.ID)) ((Trace) input.CurrentTraceObject).AddChild(new MorphologicalRuleSynthesisTrace(rule, input.Clone())); }
public override void MorphologicalRuleApplied(MorphologicalRule rule, WordSynthesis input, WordSynthesis output, Allomorph allomorph) { if (IsSynthesisTracingEnabled(rule.ID)) { var trace = new MorphologicalRuleSynthesisTrace(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; } }
public override void EndApplyTemplate(AffixTemplate template, WordSynthesis output, bool applied) { if (TraceTemplatesSynthesis) ((Trace) output.CurrentTraceObject).AddChild(new TemplateSynthesisTrace(template, false, applied ? output.Clone() : null)); }
public override void BeginApplyTemplate(AffixTemplate template, WordSynthesis input) { if (TraceTemplatesSynthesis) ((Trace) input.CurrentTraceObject).AddChild(new TemplateSynthesisTrace(template, true, input.Clone())); }
public override void EndApplyPhonologicalRule(PhonologicalRule rule, WordSynthesis output) { if (m_currentSynthesisPruleTrace != null) { m_currentSynthesisPruleTrace.Output = output.Clone(); m_currentSynthesisPruleTrace = null; } }
/// <summary> /// Initializes a new instance of the <see cref="MorphologicalRuleSynthesisTrace"/> class. /// </summary> /// <param name="rule">The rule.</param> /// <param name="input">The input.</param> internal MorphologicalRuleSynthesisTrace(MorphologicalRule rule, WordSynthesis input) : base(rule) { m_input = input; }
/// <summary> /// Initializes a new instance of the <see cref="ReportSuccessTrace"/> class. /// </summary> internal ReportSuccessTrace(WordSynthesis output) { m_output = output; }
public override void ReportSuccess(WordSynthesis output) { if (TraceSuccess) ((Trace) output.CurrentTraceObject).AddChild(new ReportSuccessTrace(output)); }
/// <summary> /// Initializes a new instance of the <see cref="PhonologicalRuleSynthesisTrace"/> class. /// </summary> /// <param name="rule">The rule.</param> /// <param name="input">The input.</param> internal PhonologicalRuleSynthesisTrace(PhonologicalRule rule, WordSynthesis input) : base(rule) { m_input = input; }
static IEnumerable <PcPatrMorph> GetMorphs(WordSynthesis ws) { var ppMorphs = new Dictionary <string, PcPatrMorph>(); var result = new List <PcPatrMorph>(); foreach (Morph morph in ws.Morphs) { string[] formIds = morph.Allomorph.GetProperty("FormID").Split(' '); string[] wordTypes = morph.Allomorph.GetProperty("WordCategory").Split(' '); string form = ws.Stratum.CharacterDefinitionTable.ToString(morph.Shape, ModeType.SYNTHESIS, false); PcPatrMorph ppMorph; if (!ppMorphs.TryGetValue(morph.Allomorph.Morpheme.ID, out ppMorph)) { ppMorph = new PcPatrMorph { formIndex = 0, formId = formIds[0], form = form, wordType = wordTypes[0] }; } else if (formIds.Length == 1) { ppMorph.form += form; continue; } else { PcPatrMorph oldMorph = ppMorph; ppMorph = new PcPatrMorph { formIndex = oldMorph.formIndex + 1, formId = formIds[oldMorph.formIndex + 1], form = form, wordType = wordTypes[oldMorph.formIndex + 1] }; } ppMorph.msaId = morph.Allomorph.GetProperty("MsaID"); ppMorph.featureDescriptors = morph.Allomorph.GetProperty("FeatureDescriptors"); ppMorph.gloss = morph.Allomorph.Morpheme.Gloss.Description; ppMorphs[morph.Allomorph.Morpheme.ID] = ppMorph; string morphType = morph.Allomorph.GetProperty("MorphType"); switch (morphType) { case MoMorphTypeTags.kMorphInfix: case MoMorphTypeTags.kMorphInfixingInterfix: if (result.Count == 0) { result.Add(ppMorph); } else { result.Insert(result.Count - 1, ppMorph); } break; default: result.Add(ppMorph); break; } } return(result); }
/// <summary> /// Applies this subrule to the specified word synthesis. /// </summary> /// <param name="input">The input word synthesis.</param> /// <param name="output">The output word synthesis.</param> /// <returns><c>true</c> if the subrule was successfully applied, otherwise <c>false</c></returns> public bool Apply(WordSynthesis input, out WordSynthesis output) { output = null; // check MPR features if ((m_requiredMPRFeatures != null && m_requiredMPRFeatures.Count > 0 && !m_requiredMPRFeatures.IsMatch(input.MPRFeatures)) || (m_excludedMPRFeatures != null && m_excludedMPRFeatures.Count > 0 && m_excludedMPRFeatures.IsMatch(input.MPRFeatures))) return false; VariableValues instantiatedVars = new VariableValues(m_alphaVars); IList<Match> headMatches, nonHeadMatches; if (m_headLhsTemp.IsMatch(input.Shape.First, Direction.RIGHT, ModeType.SYNTHESIS, instantiatedVars, out headMatches) && m_nonHeadLhsTemp.IsMatch(input.NonHead.Shape.First, Direction.RIGHT, ModeType.SYNTHESIS, instantiatedVars, out nonHeadMatches)) { output = input.Clone(); ApplyRHS(headMatches[0], nonHeadMatches[0], input, output); if (m_outputMPRFeatures != null) output.MPRFeatures.AddOutput(m_outputMPRFeatures); return true; } return false; }
/// <summary> /// Applies the rule to the specified word synthesis. /// </summary> /// <param name="input">The word synthesis.</param> public override void Apply(WordSynthesis input) { // I don't think there is any difference between iterative and // simultaneous application Direction dir = Direction.RIGHT; switch (m_multApplication) { case MultAppOrder.LR_ITERATIVE: case MultAppOrder.SIMULTANEOUS: dir = Direction.RIGHT; break; case MultAppOrder.RL_ITERATIVE: dir = Direction.LEFT; break; } ProcessIterative(input.Shape, dir, m_lhsTemp, ModeType.SYNTHESIS); }
/// <summary> /// Determines whether this rule is applicable to the specified word synthesis. /// </summary> /// <param name="input">The input word synthesis.</param> /// <returns> /// <c>true</c> if the rule is applicable, otherwise <c>false</c>. /// </returns> public override bool IsApplicable(WordSynthesis input) { // TODO: check subcats. // check required parts of speech return input.NextRule == this && input.GetNumAppliesForMorphologicalRule(this) < m_maxNumApps && (m_headRequiredPOSs == null || m_headRequiredPOSs.Count == 0 || m_headRequiredPOSs.Contains(input.POS)) && input.NonHead != null && (m_nonHeadRequiredPOSs == null || m_nonHeadRequiredPOSs.Count == 0 || m_nonHeadRequiredPOSs.Contains(input.NonHead.POS)); }
/// <summary> /// Applies the rule to the specified word synthesis. /// </summary> /// <param name="input">The input word synthesis.</param> /// <param name="output">The output word syntheses.</param> /// <returns> /// <c>true</c> if the rule was successfully applied, otherwise <c>false</c> /// </returns> public override bool Apply(WordSynthesis input, TraceManager trace, out ICollection<WordSynthesis> output) { output = null; // these should probably be moved to IsApplicable, but we will leave it here for // now so we don't have to call it again to set the features for the output word // synthesis record // check head features FeatureValues headFeatures; if (!m_requiredHeadFeatures.UnifyDefaults(input.HeadFeatures, out headFeatures)) return false; // check foot features FeatureValues footFeatures; if (!m_requiredFootFeatures.UnifyDefaults(input.FootFeatures, out footFeatures)) return false; output = new List<WordSynthesis>(); for (int i = 0; i < m_subrules.Count; i++) { WordSynthesis ws; if (m_subrules[i].Apply(input, out ws)) { if (m_outPOS != null) ws.POS = m_outPOS; if (m_outHeadFeatures != null) ws.HeadFeatures = m_outHeadFeatures.Clone(); ws.HeadFeatures.Add(headFeatures); if (m_outFootFeatures != null) ws.FootFeatures = m_outFootFeatures.Clone(); ws.FootFeatures.Add(footFeatures); if (m_obligHeadFeatures != null) { foreach (Feature feature in m_obligHeadFeatures) ws.AddObligatoryHeadFeature(feature); } ws.MorphologicalRuleApplied(this); ws = CheckBlocking(ws, trace); if (trace != null) trace.MorphologicalRuleApplied(this, input, ws, m_subrules[i]); output.Add(ws); // return all word syntheses that match subrules that are constrained by environments, // HC violates the disjunctive property of allomorphs here because it cannot check the // environmental constraints until it has a surface form, we will enforce the disjunctive // property of allomorphs at that time // HC also checks for free fluctuation, if the next subrule has the same constraints, we // do not treat them as disjunctive if ((i != m_subrules.Count - 1 && !m_subrules[i].ConstraintsEqual(m_subrules[i + 1])) && m_subrules[i].RequiredEnvironments == null && m_subrules[i].ExcludedEnvironments == null) { break; } } } if (trace != null && output.Count == 0) trace.MorphologicalRuleNotApplied(this, input); return output.Count > 0; }
/// <summary> /// Applies the rule to the specified word synthesis. This method is used by affix templates. /// </summary> /// <param name="input">The input word synthesis.</param> /// <param name="origHeadFeatures">The original head features before template application.</param> /// <param name="output">The output word syntheses.</param> /// <returns> /// <c>true</c> if the rule was successfully applied, otherwise <c>false</c> /// </returns> public override bool ApplySlotAffix(WordSynthesis input, FeatureValues origHeadFeatures, out ICollection<WordSynthesis> output) { return Apply(input, out output); }
/// <summary> /// Determines whether this subrule is applicable to the specified word analysis. /// </summary> /// <param name="input">The word analysis.</param> /// <returns> /// <c>true</c> if this subrule is applicable, otherwise <c>false</c>. /// </returns> public bool IsApplicable(WordSynthesis input) { // check part of speech and MPR features return ((m_requiredPOSs == null || m_requiredPOSs.Count == 0 || m_requiredPOSs.Contains(input.POS)) && (m_requiredMPRFeatures == null || m_requiredMPRFeatures.Count == 0 || m_requiredMPRFeatures.IsMatch(input.MPRFeatures)) && (m_excludedMPRFeatures == null || m_excludedMPRFeatures.Count == 0 || !m_excludedMPRFeatures.IsMatch(input.MPRFeatures))); }
void ApplyRHS(Match match, WordSynthesis input, WordSynthesis output) { output.Shape.Clear(); output.Morphs.Clear(); output.Shape.Add(new Margin(Direction.LEFT)); foreach (MorphologicalOutput outputMember in m_transform.RHS) outputMember.Apply(match, input, output, this); output.Shape.Add(new Margin(Direction.RIGHT)); }
public override void PhonologicalRuleNotApplicablePOS(WordSynthesis input, HCObjectSet<PartOfSpeech> requiredPOSs) { if (m_currentSynthesisPruleTrace != null) m_currentSynthesisPruleTrace.AddChild(new PhonologicalRuleSynthesisRequiredPOSTrace(input.POS, requiredPOSs)); }