/// <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(); } }
/// <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 all of the rules to the specified word synthesis. /// </summary> /// <param name="input">The input word synthesis.</param> /// <returns>All word synthesis records that result from the application of rules.</returns> public IEnumerable <WordSynthesis> Apply(WordSynthesis input) { if (m_isCyclic) { throw new NotImplementedException(HCStrings.kstidCyclicStratumNotSupported); } if (m_pruleOrder == PRuleOrder.SIMULTANEOUS) { throw new NotImplementedException(HCStrings.kstidSimultOrderNotSupported); } // TODO: handle cyclicity Set <WordSynthesis> output = new Set <WordSynthesis>(); ApplyMorphologicalRules(input.Clone(), 0, output); foreach (WordSynthesis cur in output) { ApplyPhonologicalRules(cur); } return(output); }
void ApplySlots(WordSynthesis input, int sIndex, FeatureValues origHeadFeatures, Set <WordSynthesis> output) { for (int i = sIndex; i < m_slots.Count; i++) { foreach (MorphologicalRule rule in m_slots[i].MorphologicalRules) { if (rule.IsApplicable(input)) { // this is the slot affix that realizes the features ICollection <WordSynthesis> syntheses; if (rule.ApplySlotAffix(input, origHeadFeatures, out syntheses)) { foreach (WordSynthesis ws in syntheses) { ApplySlots(ws, i + 1, origHeadFeatures, output); } } } } if (!m_slots[i].IsOptional) { if (Morpher.TraceTemplatesSynthesis) { input.CurrentTrace.AddChild(new TemplateSynthesisTrace(this, false, null)); } return; } } if (Morpher.TraceTemplatesSynthesis) { input.CurrentTrace.AddChild(new TemplateSynthesisTrace(this, false, input.Clone())); } output.Add(input); }
/// <summary> /// Applies this affix template to the specified input 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 affix template applied, otherwise <c>false</c>.</returns> public bool Apply(WordSynthesis input, out IEnumerable <WordSynthesis> output) { FeatureValues headFeatures = input.HeadFeatures.Clone(); Set <WordSynthesis> results = new Set <WordSynthesis>(); if (Morpher.TraceTemplatesSynthesis) { // create the template synthesis input trace record TemplateSynthesisTrace tempTrace = new TemplateSynthesisTrace(this, true, input.Clone()); input.CurrentTrace.AddChild(tempTrace); } ApplySlots(input.Clone(), 0, headFeatures, results); if (results.Count > 0) { output = results; return(true); } else { output = null; return(false); } }
/// <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); }
/// <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, 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); if (TraceSynthesis) { MorphologicalRuleSynthesisTrace trace = new MorphologicalRuleSynthesisTrace(this, input.Clone()); // add output to morphological rule trace record trace.RuleAllomorph = m_subrules[i]; trace.Output = ws.Clone(); ws.CurrentTrace.AddChild(trace); // set current trace record to the morphological rule trace record for each // output analysis ws.CurrentTrace = trace; } 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 (TraceSynthesis && output.Count == 0) { input.CurrentTrace.AddChild(new MorphologicalRuleSynthesisTrace(this, input.Clone())); } return(output.Count > 0); }