public IEnumerable <Word> Apply(Word input)
        {
            if (!_morpher.RuleSelector(_rule))
            {
                return(Enumerable.Empty <Word>());
            }

            if (!_rule.RealizationalFeatureStruct.Subsumes(input.RealizationalFeatureStruct))
            {
                return(Enumerable.Empty <Word>());
            }

            if (!_rule.RealizationalFeatureStruct.IsEmpty && IsBlocked(_rule.RealizationalFeatureStruct, input.SyntacticFeatureStruct, new HashSet <Tuple <FeatureStruct, FeatureStruct> >()))
            {
                return(Enumerable.Empty <Word>());
            }

            FeatureStruct syntacticFS;

            if (!_rule.RequiredSyntacticFeatureStruct.Unify(input.SyntacticFeatureStruct, true, out syntacticFS))
            {
                if (_morpher.TraceManager.IsTracing)
                {
                    _morpher.TraceManager.MorphologicalRuleNotApplied(_rule, -1, input, FailureReason.RequiredSyntacticFeatureStruct, _rule.RequiredSyntacticFeatureStruct);
                }
                return(Enumerable.Empty <Word>());
            }

            var output = new List <Word>();

            for (int i = 0; i < _rules.Count; i++)
            {
                AffixProcessAllomorph allo = _rule.Allomorphs[i];
                MprFeatureGroup       group;
                if (allo.RequiredMprFeatures.Count > 0 && !allo.RequiredMprFeatures.IsMatchRequired(input.MprFeatures, out group))
                {
                    if (_morpher.TraceManager.IsTracing)
                    {
                        _morpher.TraceManager.MorphologicalRuleNotApplied(_rule, i, input, FailureReason.RequiredMprFeatures, group);
                    }
                    continue;
                }
                if (allo.ExcludedMprFeatures.Count > 0 && !allo.ExcludedMprFeatures.IsMatchExcluded(input.MprFeatures, out group))
                {
                    if (_morpher.TraceManager.IsTracing)
                    {
                        _morpher.TraceManager.MorphologicalRuleNotApplied(_rule, i, input, FailureReason.ExcludedMprFeatures, group);
                    }
                    continue;
                }

                Word outWord = _rules[i].Apply(input).SingleOrDefault();
                if (outWord != null)
                {
                    outWord.SyntacticFeatureStruct = syntacticFS;
                    outWord.SyntacticFeatureStruct.PriorityUnion(_rule.RealizationalFeatureStruct);
                    outWord.MorphologicalRuleApplied(_rule);

                    Word newWord;
                    if (_rule.Blockable && outWord.CheckBlocking(out newWord))
                    {
                        if (_morpher.TraceManager.IsTracing)
                        {
                            _morpher.TraceManager.ParseBlocked(_rule, newWord);
                        }
                        outWord = newWord;
                    }
                    else
                    {
                        outWord.Freeze();
                    }

                    if (_morpher.TraceManager.IsTracing)
                    {
                        _morpher.TraceManager.MorphologicalRuleApplied(_rule, i, input, outWord);
                    }

                    output.Add(outWord);

                    // 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 != _rule.Allomorphs.Count - 1 && !allo.FreeFluctuatesWith(_rule.Allomorphs[i + 1])) &&
                        allo.Environments.Count == 0 && allo.RequiredSyntacticFeatureStruct.IsEmpty)
                    {
                        break;
                    }
                }
                else if (_morpher.TraceManager.IsTracing)
                {
                    _morpher.TraceManager.MorphologicalRuleNotApplied(_rule, i, input, FailureReason.Pattern, null);
                }
            }

            return(output);
        }
예제 #2
0
        public IEnumerable <Word> Apply(Word input)
        {
            if (input.CurrentMorphologicalRule != _rule)
            {
                return(Enumerable.Empty <Word>());
            }

            if (input.GetApplicationCount(_rule) >= _rule.MaxApplicationCount)
            {
                if (_morpher.TraceManager.IsTracing)
                {
                    _morpher.TraceManager.MorphologicalRuleNotApplied(_rule, -1, input, FailureReason.MaxApplicationCount, _rule.MaxApplicationCount);
                }
                return(Enumerable.Empty <Word>());
            }

            // if a final template was last applied, do not allow a non-partial rule to apply unless the input is partial
            if (!_rule.IsTemplateRule && (input.IsLastAppliedRuleFinal ?? false) && !input.IsPartial && !_rule.IsPartial)
            {
                if (_morpher.TraceManager.IsTracing)
                {
                    _morpher.TraceManager.MorphologicalRuleNotApplied(_rule, -1, input, FailureReason.NonPartialRuleProhibitedAfterFinalTemplate, null);
                }
                return(Enumerable.Empty <Word>());
            }

            // if a non-final template was last applied, only allow a non-partial rule to apply unless the input is partial
            if (!_rule.IsTemplateRule && input.IsLastAppliedRuleFinal.HasValue && !input.IsLastAppliedRuleFinal.Value && !input.IsPartial && _rule.IsPartial)
            {
                if (_morpher.TraceManager.IsTracing)
                {
                    _morpher.TraceManager.MorphologicalRuleNotApplied(_rule, -1, input, FailureReason.NonPartialRuleRequiredAfterNonFinalTemplate, null);
                }
                return(Enumerable.Empty <Word>());
            }

            if (_rule.RequiredStemName != null && _rule.RequiredStemName != input.RootAllomorph.StemName)
            {
                if (_morpher.TraceManager.IsTracing)
                {
                    _morpher.TraceManager.MorphologicalRuleNotApplied(_rule, -1, input, FailureReason.RequiredStemName, _rule.RequiredStemName);
                }
                return(Enumerable.Empty <Word>());
            }

            FeatureStruct syntacticFS;

            if (!_rule.RequiredSyntacticFeatureStruct.Unify(input.SyntacticFeatureStruct, true, out syntacticFS))
            {
                if (_morpher.TraceManager.IsTracing)
                {
                    _morpher.TraceManager.MorphologicalRuleNotApplied(_rule, -1, input, FailureReason.RequiredSyntacticFeatureStruct, _rule.RequiredSyntacticFeatureStruct);
                }
                return(Enumerable.Empty <Word>());
            }

            var output = new List <Word>();

            for (int i = 0; i < _rules.Count; i++)
            {
                AffixProcessAllomorph allo = _rule.Allomorphs[i];
                MprFeatureGroup       group;
                if (allo.RequiredMprFeatures.Count > 0 && !allo.RequiredMprFeatures.IsMatchRequired(input.MprFeatures, out group))
                {
                    if (_morpher.TraceManager.IsTracing)
                    {
                        _morpher.TraceManager.MorphologicalRuleNotApplied(_rule, i, input, FailureReason.RequiredMprFeatures, group);
                    }
                    continue;
                }
                if (allo.ExcludedMprFeatures.Count > 0 && !allo.ExcludedMprFeatures.IsMatchExcluded(input.MprFeatures, out group))
                {
                    if (_morpher.TraceManager.IsTracing)
                    {
                        _morpher.TraceManager.MorphologicalRuleNotApplied(_rule, i, input, FailureReason.ExcludedMprFeatures, group);
                    }
                    continue;
                }

                Word outWord = _rules[i].Apply(input).SingleOrDefault();
                if (outWord != null)
                {
                    outWord.SyntacticFeatureStruct = syntacticFS;
                    outWord.SyntacticFeatureStruct.PriorityUnion(_rule.OutSyntacticFeatureStruct);

                    foreach (Feature obligFeature in _rule.ObligatorySyntacticFeatures)
                    {
                        outWord.ObligatorySyntacticFeatures.Add(obligFeature);
                    }

                    if (!_rule.IsTemplateRule)
                    {
                        if (_rule.IsPartial)
                        {
                            outWord.IsPartial = true;
                        }
                        else
                        {
                            outWord.IsLastAppliedRuleFinal = null;
                        }
                    }

                    outWord.CurrentMorphologicalRuleApplied();

                    Word newWord;
                    if (_rule.Blockable && outWord.CheckBlocking(out newWord))
                    {
                        if (_morpher.TraceManager.IsTracing)
                        {
                            _morpher.TraceManager.ParseBlocked(_rule, newWord);
                        }
                        outWord = newWord;
                    }
                    else
                    {
                        outWord.Freeze();
                    }

                    if (_morpher.TraceManager.IsTracing)
                    {
                        _morpher.TraceManager.MorphologicalRuleApplied(_rule, i, input, outWord);
                    }
                    output.Add(outWord);

                    // 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 != _rule.Allomorphs.Count - 1 && !allo.FreeFluctuatesWith(_rule.Allomorphs[i + 1])) &&
                        allo.Environments.Count == 0 && allo.RequiredSyntacticFeatureStruct.IsEmpty)
                    {
                        break;
                    }
                }
                else if (_morpher.TraceManager.IsTracing)
                {
                    _morpher.TraceManager.MorphologicalRuleNotApplied(_rule, i, input, FailureReason.Pattern, null);
                }
            }

            return(output);
        }