/// <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 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, 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 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; 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, trace); if (trace != null) trace.MorphologicalRuleApplied(this, input, ws, sr); 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; }