Exemple #1
0
        public void MorphosyntacticRules()
        {
            var any   = FeatureStruct.New().Symbol(HCFeatureSystem.Segment).Value;
            var rule1 = new CompoundingRule {
                Name = "rule1", NonHeadRequiredSyntacticFeatureStruct = FeatureStruct.New(Language.SyntacticFeatureSystem).Symbol("V").Value
            };

            Allophonic.MorphologicalRules.Add(rule1);
            rule1.Subrules.Add(new CompoundingSubrule
            {
                HeadLhs    = { Pattern <Word, ShapeNode> .New("head").Annotation(any).OneOrMore.Value },
                NonHeadLhs = { Pattern <Word, ShapeNode> .New("nonHead").Annotation(any).OneOrMore.Value },
                Rhs        = { new CopyFromInput("head"), new InsertSegments(Table3, "+"), new CopyFromInput("nonHead") }
            });

            var         morpher = new Morpher(SpanFactory, TraceManager, Language);
            List <Word> output  = morpher.ParseWord("pʰutdat").ToList();

            AssertMorphsEqual(output, "5 9");
            AssertRootAllomorphsEquals(output, "5");
            AssertSyntacticFeatureStructsEqual(output, FeatureStruct.New(Language.SyntacticFeatureSystem).Symbol("N").Value);
            Assert.That(morpher.ParseWord("pʰutbupu"), Is.Empty);

            rule1.OutSyntacticFeatureStruct = FeatureStruct.New(Language.SyntacticFeatureSystem).Symbol("V").Value;

            morpher = new Morpher(SpanFactory, TraceManager, Language);
            output  = morpher.ParseWord("pʰutdat").ToList();
            AssertMorphsEqual(output, "5 9");
            AssertRootAllomorphsEquals(output, "5");
            AssertSyntacticFeatureStructsEqual(output, FeatureStruct.New(Language.SyntacticFeatureSystem).Symbol("V").Value);

            Allophonic.MorphologicalRules.Clear();
            Morphophonemic.MorphologicalRules.Add(rule1);
            rule1.HeadRequiredSyntacticFeatureStruct = FeatureStruct.New(Language.SyntacticFeatureSystem)
                                                       .Symbol("V")
                                                       .Feature(Head).EqualTo(head => head
                                                                              .Feature("pers").EqualTo("2")).Value;
            rule1.NonHeadRequiredSyntacticFeatureStruct = FeatureStruct.New().Value;

            morpher = new Morpher(SpanFactory, TraceManager, Language);
            output  = morpher.ParseWord("ssagabba").ToList();
            AssertMorphsEqual(output, "Perc0 39", "Perc0 40", "Perc3 39", "Perc3 40");
            AssertRootAllomorphsEquals(output, "Perc0", "Perc3");
        }
Exemple #2
0
        public void SimpleRules()
        {
            var any   = FeatureStruct.New().Symbol(HCFeatureSystem.Segment).Value;
            var rule1 = new CompoundingRule {
                Name = "rule1"
            };

            Allophonic.MorphologicalRules.Add(rule1);
            rule1.Subrules.Add(new CompoundingSubrule
            {
                HeadLhs    = { Pattern <Word, ShapeNode> .New("head").Annotation(any).OneOrMore.Value },
                NonHeadLhs = { Pattern <Word, ShapeNode> .New("nonHead").Annotation(any).OneOrMore.Value },
                Rhs        = { new CopyFromInput("head"), new InsertSegments(Table3, "+"), new CopyFromInput("nonHead") }
            });

            var         morpher = new Morpher(SpanFactory, TraceManager, Language);
            List <Word> output  = morpher.ParseWord("pʰutdat").ToList();

            AssertMorphsEqual(output, "5 8", "5 9");
            AssertRootAllomorphsEquals(output, "5");
            Assert.That(morpher.ParseWord("pʰutdas"), Is.Empty);
            Assert.That(morpher.ParseWord("pʰusdat"), Is.Empty);

            rule1.Subrules.Clear();
            rule1.Subrules.Add(new CompoundingSubrule
            {
                HeadLhs    = { Pattern <Word, ShapeNode> .New("head").Annotation(any).OneOrMore.Value },
                NonHeadLhs = { Pattern <Word, ShapeNode> .New("nonHead").Annotation(any).OneOrMore.Value },
                Rhs        = { new CopyFromInput("nonHead"), new InsertSegments(Table3, "+"), new CopyFromInput("head") }
            });

            morpher = new Morpher(SpanFactory, TraceManager, Language);
            output  = morpher.ParseWord("pʰutdat").ToList();
            AssertMorphsEqual(output, "5 8", "5 9");
            AssertRootAllomorphsEquals(output, "8", "9");
            Assert.That(morpher.ParseWord("pʰutdas"), Is.Empty);
            Assert.That(morpher.ParseWord("pʰusdat"), Is.Empty);

            var prefix = new AffixProcessRule
            {
                Name  = "prefix",
                Gloss = "PAST",
                RequiredSyntacticFeatureStruct = FeatureStruct.New(Language.SyntacticFeatureSystem).Symbol("V").Value,
                OutSyntacticFeatureStruct      = FeatureStruct.New(Language.SyntacticFeatureSystem)
                                                 .Feature(Head).EqualTo(head => head
                                                                        .Feature("tense").EqualTo("past")).Value
            };

            Allophonic.MorphologicalRules.Insert(0, prefix);
            prefix.Allomorphs.Add(new AffixProcessAllomorph
            {
                Lhs = { Pattern <Word, ShapeNode> .New("1").Annotation(any).OneOrMore.Value },
                Rhs = { new InsertSegments(Table3, "di+"), new CopyFromInput("1") }
            });

            morpher = new Morpher(SpanFactory, TraceManager, Language);
            output  = morpher.ParseWord("pʰutdidat").ToList();
            AssertMorphsEqual(output, "5 PAST 9");
            AssertRootAllomorphsEquals(output, "9");

            Allophonic.MorphologicalRules.RemoveAt(0);

            rule1.MaxApplicationCount = 2;
            rule1.Subrules.Clear();
            rule1.Subrules.Add(new CompoundingSubrule
            {
                HeadLhs    = { Pattern <Word, ShapeNode> .New("head").Annotation(any).OneOrMore.Value },
                NonHeadLhs = { Pattern <Word, ShapeNode> .New("nonHead").Annotation(any).OneOrMore.Value },
                Rhs        = { new CopyFromInput("head"), new InsertSegments(Table3, "+"), new CopyFromInput("nonHead") }
            });

            morpher = new Morpher(SpanFactory, TraceManager, Language)
            {
                MaxStemCount = 3
            };
            output = morpher.ParseWord("pʰutdatpip").ToList();
            AssertMorphsEqual(output, "5 8 41", "5 9 41");
            AssertRootAllomorphsEquals(output, "5");

            rule1.MaxApplicationCount = 1;

            var rule2 = new CompoundingRule {
                Name = "rule2"
            };

            Allophonic.MorphologicalRules.Add(rule2);
            rule2.Subrules.Add(new CompoundingSubrule
            {
                HeadLhs    = { Pattern <Word, ShapeNode> .New("head").Annotation(any).OneOrMore.Value },
                NonHeadLhs = { Pattern <Word, ShapeNode> .New("nonHead").Annotation(any).OneOrMore.Value },
                Rhs        = { new CopyFromInput("nonHead"), new InsertSegments(Table3, "+"), new CopyFromInput("head") }
            });

            morpher = new Morpher(SpanFactory, TraceManager, Language)
            {
                MaxStemCount = 3
            };
            output = morpher.ParseWord("pʰutdatpip").ToList();
            AssertMorphsEqual(output, "5 8 41", "5 9 41");
            AssertRootAllomorphsEquals(output, "8", "9");
        }
        public void NonFinalTemplate()
        {
            var any     = FeatureStruct.New().Symbol(HCFeatureSystem.Segment).Value;
            var alvStop = FeatureStruct.New(Language.PhonologicalFeatureSystem)
                          .Symbol(HCFeatureSystem.Segment)
                          .Symbol("cons+")
                          .Symbol("strident-")
                          .Symbol("del_rel-")
                          .Symbol("alveolar").Value;
            var voicelessCons = FeatureStruct.New(Language.PhonologicalFeatureSystem)
                                .Symbol(HCFeatureSystem.Segment)
                                .Symbol("cons+")
                                .Symbol("vd-").Value;

            var edSuffix = new AffixProcessRule
            {
                Name  = "ed_suffix",
                Gloss = "PAST",
            };

            edSuffix.Allomorphs.Add(new AffixProcessAllomorph
            {
                Lhs =
                {
                    Pattern <Word, ShapeNode> .New("1").Annotation(any).OneOrMore.Value,
                    Pattern <Word, ShapeNode> .New("2").Annotation(alvStop).Value
                },
                Rhs = { new CopyFromInput("1"), new CopyFromInput("2"), new InsertSegments(Table3, "ɯd") }
            });
            edSuffix.Allomorphs.Add(new AffixProcessAllomorph
            {
                Lhs = { Pattern <Word, ShapeNode> .New("1").Annotation(any).OneOrMore.Annotation(voicelessCons).Value },
                Rhs = { new CopyFromInput("1"), new InsertSegments(Table3, "t") }
            });
            edSuffix.Allomorphs.Add(new AffixProcessAllomorph
            {
                Lhs = { Pattern <Word, ShapeNode> .New("1").Annotation(any).OneOrMore.Value },
                Rhs = { new CopyFromInput("1"), new InsertSegments(Table3, "d") }
            });

            var verbTemplate = new AffixTemplate
            {
                Name = "verb",
                RequiredSyntacticFeatureStruct = FeatureStruct.New(Language.SyntacticFeatureSystem).Symbol("V").Value
            };

            verbTemplate.Slots.Add(new AffixTemplateSlot(edSuffix));
            Morphophonemic.AffixTemplates.Add(verbTemplate);

            var nominalizer = new AffixProcessRule
            {
                Name  = "nominalizer",
                Gloss = "NOM",
                RequiredSyntacticFeatureStruct = FeatureStruct.New(Language.SyntacticFeatureSystem).Symbol("V").Value,
                OutSyntacticFeatureStruct      = FeatureStruct.New(Language.SyntacticFeatureSystem).Symbol("N").Value
            };

            nominalizer.Allomorphs.Add(new AffixProcessAllomorph
            {
                Lhs = { Pattern <Word, ShapeNode> .New("1").Annotation(any).OneOrMore.Value },
                Rhs = { new CopyFromInput("1"), new InsertSegments(Table3, "v") }
            });
            Morphophonemic.MorphologicalRules.Add(nominalizer);

            var crule = new CompoundingRule
            {
                Name = "rule1",
                HeadRequiredSyntacticFeatureStruct = FeatureStruct.New(Language.SyntacticFeatureSystem)
                                                     .Symbol("V").Value,
                NonHeadRequiredSyntacticFeatureStruct = FeatureStruct.New(Language.SyntacticFeatureSystem)
                                                        .Symbol("N").Value,
                OutSyntacticFeatureStruct = FeatureStruct.New(Language.SyntacticFeatureSystem).Symbol("N").Value
            };

            crule.Subrules.Add(new CompoundingSubrule
            {
                HeadLhs    = { Pattern <Word, ShapeNode> .New("head").Annotation(any).OneOrMore.Value },
                NonHeadLhs = { Pattern <Word, ShapeNode> .New("nonHead").Annotation(any).OneOrMore.Value },
                Rhs        = { new CopyFromInput("head"), new InsertSegments(Table3, "+"), new CopyFromInput("nonHead") }
            });
            Morphophonemic.MorphologicalRules.Add(crule);

            var sSuffix = new AffixProcessRule
            {
                Name  = "s_suffix",
                Gloss = "PL",
                RequiredSyntacticFeatureStruct = FeatureStruct.New(Language.SyntacticFeatureSystem).Symbol("N").Value,
            };

            sSuffix.Allomorphs.Add(new AffixProcessAllomorph
            {
                Lhs = { Pattern <Word, ShapeNode> .New("1").Annotation(any).OneOrMore.Value },
                Rhs = { new CopyFromInput("1"), new InsertSegments(Table3, "s") }
            });

            var nounTemplate = new AffixTemplate
            {
                Name = "noun",
                RequiredSyntacticFeatureStruct = FeatureStruct.New(Language.SyntacticFeatureSystem).Symbol("N").Value
            };

            nounTemplate.Slots.Add(new AffixTemplateSlot(sSuffix)
            {
                Optional = true
            });
            Morphophonemic.AffixTemplates.Add(nounTemplate);

            var morpher = new Morpher(TraceManager, Language);

            AssertMorphsEqual(morpher.ParseWord("sagd"), "32 PAST");
            AssertMorphsEqual(morpher.ParseWord("sagdv"));
            AssertMorphsEqual(morpher.ParseWord("sagdvs"));
            AssertMorphsEqual(morpher.ParseWord("sagdmi"));
            AssertMorphsEqual(morpher.ParseWord("sagdmis"));

            verbTemplate.IsFinal = false;
            morpher = new Morpher(TraceManager, Language);
            AssertMorphsEqual(morpher.ParseWord("sagd"));
            AssertMorphsEqual(morpher.ParseWord("sagdv"), "32 PAST NOM");
            AssertMorphsEqual(morpher.ParseWord("sagdvs"), "32 PAST NOM PL");
            AssertMorphsEqual(morpher.ParseWord("sagdmi"), "32 PAST 53");
            AssertMorphsEqual(morpher.ParseWord("sagdmis"), "32 PAST 53 PL");
        }
        private bool TryLoadCompoundingRule(XElement compRuleElem, CharacterDefinitionTable defaultTable, out IMorphologicalRule mrule)
        {
            var compRuleID = (string) compRuleElem.Attribute("id");
            var compRule = new CompoundingRule
            {
                Name = (string) compRuleElem.Element("Name"),
                Blockable = (bool?) compRuleElem.Attribute("blockable") ?? true
            };
            var multApp = (string) compRuleElem.Attribute("multipleApplication");
            if (!string.IsNullOrEmpty(multApp))
                compRule.MaxApplicationCount = int.Parse(multApp);

            var fs = new FeatureStruct();
            var headRequiredPos = (string) compRuleElem.Attribute("headPartsOfSpeech");
            if (!string.IsNullOrEmpty(headRequiredPos))
                fs.AddValue(_posFeature, ParsePartsOfSpeech(headRequiredPos));
            XElement headRequiredHeadFeatElem = compRuleElem.Element("HeadRequiredHeadFeatures");
            if (headRequiredHeadFeatElem != null)
                fs.AddValue(_headFeature, LoadFeatureStruct(headRequiredHeadFeatElem, _language.SyntacticFeatureSystem));
            XElement headRequiredFootFeatElem = compRuleElem.Element("HeadRequiredFootFeatures");
            if (headRequiredFootFeatElem != null)
                fs.AddValue(_footFeature, LoadFeatureStruct(headRequiredFootFeatElem, _language.SyntacticFeatureSystem));
            fs.Freeze();
            compRule.HeadRequiredSyntacticFeatureStruct = fs;

            fs = new FeatureStruct();
            var nonHeadRequiredPos = (string) compRuleElem.Attribute("nonHeadPartsOfSpeech");
            if (!string.IsNullOrEmpty(nonHeadRequiredPos))
                fs.AddValue(_posFeature, ParsePartsOfSpeech(nonHeadRequiredPos));
            XElement nonHeadRequiredHeadFeatElem = compRuleElem.Element("NonHeadRequiredHeadFeatures");
            if (nonHeadRequiredHeadFeatElem != null)
                fs.AddValue(_headFeature, LoadFeatureStruct(nonHeadRequiredHeadFeatElem, _language.SyntacticFeatureSystem));
            XElement nonHeadRequiredFootFeatElem = compRuleElem.Element("NonHeadRequiredFootFeatures");
            if (nonHeadRequiredFootFeatElem != null)
                fs.AddValue(_footFeature, LoadFeatureStruct(nonHeadRequiredFootFeatElem, _language.SyntacticFeatureSystem));
            fs.Freeze();
            compRule.NonHeadRequiredSyntacticFeatureStruct = fs;

            fs = new FeatureStruct();
            var outPos = (string) compRuleElem.Attribute("outputPartOfSpeech");
            if (!string.IsNullOrEmpty(outPos))
                fs.AddValue(_posFeature, ParsePartsOfSpeech(outPos));
            XElement outHeadFeatElem = compRuleElem.Element("OutputHeadFeatures");
            if (outHeadFeatElem != null)
                fs.AddValue(_headFeature, LoadFeatureStruct(outHeadFeatElem, _language.SyntacticFeatureSystem));
            XElement outFootFeatElem = compRuleElem.Element("OutputFootFeatures");
            if (outFootFeatElem != null)
                fs.AddValue(_footFeature, LoadFeatureStruct(outFootFeatElem, _language.SyntacticFeatureSystem));
            fs.Freeze();
            compRule.OutSyntacticFeatureStruct = fs;

            var obligHeadIDsStr = (string) compRuleElem.Attribute("outputObligatoryFeatures");
            if (!string.IsNullOrEmpty(obligHeadIDsStr))
            {
                foreach (string obligHeadID in obligHeadIDsStr.Split(' '))
                    compRule.ObligatorySyntacticFeatures.Add(_language.SyntacticFeatureSystem.GetFeature(obligHeadID));
            }

            foreach (XElement subruleElem in compRuleElem.Elements("CompoundingSubrules").Elements("CompoundingSubrule").Where(IsActive))
            {
                try
                {
                    compRule.Subrules.Add(LoadCompoundingSubrule(subruleElem, defaultTable));
                }
                catch (Exception e)
                {
                    if (_errorHandler != null)
                        _errorHandler(e, compRuleID);
                    else
                        throw;
                }
            }

            if (compRule.Subrules.Count > 0)
            {
                mrule = compRule;
                return true;
            }

            mrule = null;
            return false;
        }