public void GenerateWords_CanGenerate_ReturnsCorrectWord() { var any = FeatureStruct.New().Symbol(HCFeatureSystem.Segment).Value; var siPrefix = new AffixProcessRule { Id = "3SG", Name = "si_prefix", Gloss = "3SG", RequiredSyntacticFeatureStruct = FeatureStruct.New(Language.SyntacticFeatureSystem).Symbol("V").Value }; siPrefix.Allomorphs.Add(new AffixProcessAllomorph { Lhs = { Pattern <Word, ShapeNode> .New("1").Annotation(any).OneOrMore.Value }, Rhs = { new InsertSegments(Table3, "si+"), new CopyFromInput("1") } }); Morphophonemic.MorphologicalRules.Add(siPrefix); var edSuffix = new AffixProcessRule { Id = "PAST", Name = "ed_suffix", Gloss = "PAST", RequiredSyntacticFeatureStruct = FeatureStruct.New(Language.SyntacticFeatureSystem).Symbol("V").Value }; edSuffix.Allomorphs.Add(new AffixProcessAllomorph { Lhs = { Pattern <Word, ShapeNode> .New("1").Annotation(any).OneOrMore.Value }, Rhs = { new CopyFromInput("1"), new InsertSegments(Table3, "+ɯd") } }); Morphophonemic.MorphologicalRules.Add(edSuffix); var morpher = new Morpher(TraceManager, Language); var analysis = new WordAnalysis(new IMorpheme[] { siPrefix, Entries["33"], edSuffix }, 1, "V"); string[] words = morpher.GenerateWords(analysis).ToArray(); Assert.That(words, Is.EquivalentTo(new[] { "sisasɯd" })); }
internal override bool IsWordValid(Morpher morpher, Word word) { if (!base.IsWordValid(morpher, word)) { return(false); } if (IsBound && word.Allomorphs.Count == 1) { if (morpher.TraceManager.IsTracing) { morpher.TraceManager.Failed(morpher.Language, word, FailureReason.BoundRoot, this, null); } return(false); } if (StemName != null && !StemName.IsRequiredMatch(word.SyntacticFeatureStruct)) { if (morpher.TraceManager.IsTracing) { morpher.TraceManager.Failed(morpher.Language, word, FailureReason.RequiredStemName, this, StemName); } return(false); } foreach (RootAllomorph otherAllo in ((LexEntry)Morpheme).Allomorphs.Where(a => a != this && a.StemName != null)) { if (!otherAllo.StemName.IsExcludedMatch(word.SyntacticFeatureStruct, StemName)) { if (morpher.TraceManager.IsTracing) { morpher.TraceManager.Failed(morpher.Language, word, FailureReason.ExcludedStemName, this, otherAllo.StemName); } return(false); } } return(true); }
public void FreeFluctuation() { var any = FeatureStruct.New().Symbol(HCFeatureSystem.Segment).Value; var d = FeatureStruct.New(Language.PhonologicalFeatureSystem) .Symbol(HCFeatureSystem.Segment) .Symbol("cons+") .Symbol("strident-") .Symbol("del_rel-") .Symbol("alveolar") .Symbol("nasal-") .Symbol("vd+").Value; var edSuffix = new AffixProcessRule { Name = "ed_suffix", Gloss = "PAST", RequiredSyntacticFeatureStruct = FeatureStruct.New(Language.SyntacticFeatureSystem).Symbol("V").Value }; edSuffix.Allomorphs.Add(new AffixProcessAllomorph { Lhs = { Pattern <Word, ShapeNode> .New("1").Annotation(any).OneOrMore.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, "+"), new InsertSimpleContext(d) } }); Morphophonemic.MorphologicalRules.Add(edSuffix); var morpher = new Morpher(TraceManager, Language); AssertMorphsEqual(morpher.ParseWord("tazd"), "free PAST"); AssertMorphsEqual(morpher.ParseWord("tast"), "free PAST"); AssertMorphsEqual(morpher.ParseWord("tazt"), "free PAST"); AssertMorphsEqual(morpher.ParseWord("tasd"), "free PAST"); }
public void BoundRootAllomorph() { var any = FeatureStruct.New().Symbol(HCFeatureSystem.Segment).Value; var edSuffix = new AffixProcessRule { Name = "ed_suffix", Gloss = "PAST", RequiredSyntacticFeatureStruct = FeatureStruct.New(Language.SyntacticFeatureSystem).Symbol("V").Value }; Morphophonemic.MorphologicalRules.Add(edSuffix); edSuffix.Allomorphs.Add(new AffixProcessAllomorph { Lhs = { Pattern <Word, ShapeNode> .New("1").Annotation(any).OneOrMore.Value }, Rhs = { new CopyFromInput("1"), new InsertSegments(Table3, "+ɯd") } }); var morpher = new Morpher(TraceManager, Language); Assert.That(morpher.ParseWord("dag"), Is.Empty); AssertMorphsEqual(morpher.ParseWord("dagɯd"), "bound PAST"); }
public void AnalyzeWord_CannotAnalyze_ReturnsEmptyEnumerable() { var any = FeatureStruct.New().Symbol(HCFeatureSystem.Segment).Value; var edSuffix = new AffixProcessRule { Id = "PAST", Name = "ed_suffix", Gloss = "PAST", RequiredSyntacticFeatureStruct = FeatureStruct.New(Language.SyntacticFeatureSystem).Symbol("V").Value }; edSuffix.Allomorphs.Add(new AffixProcessAllomorph { Lhs = { Pattern <Word, ShapeNode> .New("1").Annotation(any).OneOrMore.Value }, Rhs = { new CopyFromInput("1"), new InsertSegments(Table3, "+d") } }); Morphophonemic.MorphologicalRules.Add(edSuffix); var morpher = new Morpher(TraceManager, Language); Assert.That(morpher.AnalyzeWord("sagt"), Is.Empty); }
internal virtual bool IsWordValid(Morpher morpher, Word word) { AllomorphEnvironment env = Environments.FirstOrDefault(e => !e.IsWordValid(word)); if (env != null) { if (morpher.TraceManager.IsTracing) { morpher.TraceManager.Failed(morpher.Language, word, FailureReason.Environments, this, env); } return(false); } AllomorphCoOccurrenceRule alloRule = AllomorphCoOccurrenceRules.FirstOrDefault(r => !r.IsWordValid(word)); if (alloRule != null) { if (morpher.TraceManager.IsTracing) { morpher.TraceManager.Failed(morpher.Language, word, FailureReason.AllomorphCoOccurrenceRules, this, alloRule); } return(false); } MorphemeCoOccurrenceRule morphemeRule = Morpheme.MorphemeCoOccurrenceRules.FirstOrDefault(r => !r.IsWordValid(word)); if (morphemeRule != null) { if (morpher.TraceManager.IsTracing) { morpher.TraceManager.Failed(morpher.Language, word, FailureReason.MorphemeCoOccurrenceRules, this, morphemeRule); } return(false); } return(true); }
public SynthesisStratumRule(Morpher morpher, Stratum stratum) { _templatesRule = new SynthesisAffixTemplatesRule(morpher, stratum); _mrulesRule = null; IEnumerable <IRule <Word, ShapeNode> > mrules = stratum.MorphologicalRules .Select(mrule => mrule.CompileSynthesisRule(morpher)); switch (stratum.MorphologicalRuleOrder) { case MorphologicalRuleOrder.Linear: _mrulesRule = new LinearRuleCascade <Word, ShapeNode>(mrules, true, FreezableEqualityComparer <Word> .Default); break; case MorphologicalRuleOrder.Unordered: _mrulesRule = new CombinationRuleCascade <Word, ShapeNode>(mrules, true, FreezableEqualityComparer <Word> .Default); break; } _prulesRule = new LinearRuleCascade <Word, ShapeNode>( stratum.PhonologicalRules.Select(prule => prule.CompileSynthesisRule(morpher))); _stratum = stratum; _morpher = morpher; }
public override IRule <Word, ShapeNode> CompileSynthesisRule(Morpher morpher) { return(new SynthesisStratumRule(morpher, this)); }
public void Compile() { _morpher = new Morpher(new TraceManager(), _language); }
public void StemNames() { var any = FeatureStruct.New().Symbol(HCFeatureSystem.Segment).Value; var edSuffix = new AffixProcessRule { Name = "ed_suffix", Gloss = "1", RequiredSyntacticFeatureStruct = FeatureStruct.New(Language.SyntacticFeatureSystem).Symbol("V").Value, OutSyntacticFeatureStruct = FeatureStruct.New(Language.SyntacticFeatureSystem) .Feature(Head).EqualTo(head => head .Feature("pers").EqualTo("1")).Value }; edSuffix.Allomorphs.Add(new AffixProcessAllomorph { Lhs = { Pattern <Word, ShapeNode> .New("1").Annotation(any).OneOrMore.Value }, Rhs = { new CopyFromInput("1"), new InsertSegments(Table3, "+ɯd") } }); Morphophonemic.MorphologicalRules.Add(edSuffix); var tSuffix = new AffixProcessRule { Name = "t_suffix", Gloss = "2", RequiredSyntacticFeatureStruct = FeatureStruct.New(Language.SyntacticFeatureSystem).Symbol("V").Value, OutSyntacticFeatureStruct = FeatureStruct.New(Language.SyntacticFeatureSystem) .Feature(Head).EqualTo(head => head .Feature("pers").EqualTo("2")).Value }; tSuffix.Allomorphs.Add(new AffixProcessAllomorph { Lhs = { Pattern <Word, ShapeNode> .New("1").Annotation(any).OneOrMore.Value }, Rhs = { new CopyFromInput("1"), new InsertSegments(Table3, "+t") } }); Morphophonemic.MorphologicalRules.Add(tSuffix); var sSuffix = new AffixProcessRule { Name = "s_suffix", Gloss = "3", RequiredSyntacticFeatureStruct = FeatureStruct.New(Language.SyntacticFeatureSystem).Symbol("V").Value, OutSyntacticFeatureStruct = FeatureStruct.New(Language.SyntacticFeatureSystem) .Feature(Head).EqualTo(head => head .Feature("pers").EqualTo("3")).Value }; sSuffix.Allomorphs.Add(new AffixProcessAllomorph { Lhs = { Pattern <Word, ShapeNode> .New("1").Annotation(any).OneOrMore.Value }, Rhs = { new CopyFromInput("1"), new InsertSegments(Table3, "+s") } }); Morphophonemic.MorphologicalRules.Add(sSuffix); var morpher = new Morpher(TraceManager, Language); AssertMorphsEqual(morpher.ParseWord("sanɯd")); AssertMorphsEqual(morpher.ParseWord("sant")); AssertMorphsEqual(morpher.ParseWord("sans")); AssertMorphsEqual(morpher.ParseWord("san"), "stemname"); AssertMorphsEqual(morpher.ParseWord("sadɯd"), "stemname 1"); AssertMorphsEqual(morpher.ParseWord("sadt"), "stemname 2"); AssertMorphsEqual(morpher.ParseWord("sads")); AssertMorphsEqual(morpher.ParseWord("sad")); AssertMorphsEqual(morpher.ParseWord("sapɯd"), "stemname 1"); AssertMorphsEqual(morpher.ParseWord("sapt")); AssertMorphsEqual(morpher.ParseWord("saps"), "stemname 3"); AssertMorphsEqual(morpher.ParseWord("sap")); }
public abstract IRule <Word, ShapeNode> CompileSynthesisRule(Morpher morpher);
public abstract IRule <Word, ShapeNode> CompileAnalysisRule(Morpher morpher);
public void RealizationalRule() { 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 labiodental = FeatureStruct.New(Language.PhonologicalFeatureSystem) .Symbol(HCFeatureSystem.Segment) .Symbol("cons+") .Symbol("labiodental").Value; var voiced = FeatureStruct.New(Language.PhonologicalFeatureSystem) .Symbol(HCFeatureSystem.Segment) .Symbol("vd+").Value; var strident = FeatureStruct.New(Language.PhonologicalFeatureSystem) .Symbol(HCFeatureSystem.Segment) .Symbol("cons+") .Symbol("strident+").Value; var edSuffix = new RealizationalAffixProcessRule { Name = "ed_suffix", RealizationalFeatureStruct = FeatureStruct.New(Language.SyntacticFeatureSystem) .Feature(Head).EqualTo(head => head .Feature("tense").EqualTo("past")).Value, 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 sSuffix = new RealizationalAffixProcessRule { Name = "s_suffix", RealizationalFeatureStruct = FeatureStruct.New(Language.SyntacticFeatureSystem) .Feature(Head).EqualTo(head => head .Feature("pers").EqualTo("3") .Feature("tense").EqualTo("pres")).Value, Gloss = "3SG" }; sSuffix.Allomorphs.Add(new AffixProcessAllomorph { Lhs = { Pattern <Word, ShapeNode> .New("1").Annotation(any).OneOrMore.Value, Pattern <Word, ShapeNode> .New("2").Annotation(labiodental).Value }, Rhs = { new CopyFromInput("1"), new ModifyFromInput("2", voiced), new InsertSegments(Table3, "z") } }); sSuffix.Allomorphs.Add(new AffixProcessAllomorph { Lhs = { Pattern <Word, ShapeNode> .New("1").Annotation(any).OneOrMore.Annotation(strident).Value }, Rhs = { new CopyFromInput("1"), new InsertSegments(Table3, "ɯz") } }); sSuffix.Allomorphs.Add(new AffixProcessAllomorph { Lhs = { Pattern <Word, ShapeNode> .New("1").Annotation(any).OneOrMore.Value, Pattern <Word, ShapeNode> .New("2").Annotation(voicelessCons).Value }, Rhs = { new CopyFromInput("1"), new CopyFromInput("2"), new InsertSegments(Table3, "s") } }); sSuffix.Allomorphs.Add(new AffixProcessAllomorph { Lhs = { Pattern <Word, ShapeNode> .New("1").Annotation(any).OneOrMore.Value }, Rhs = { new CopyFromInput("1"), new InsertSegments(Table3, "z") } }); var evidential = new RealizationalAffixProcessRule { Name = "evidential", RealizationalFeatureStruct = FeatureStruct.New(Language.SyntacticFeatureSystem) .Feature(Head).EqualTo(head => head .Feature("evidential").EqualTo("witnessed")).Value, Gloss = "WIT" }; evidential.Allomorphs.Add(new AffixProcessAllomorph { Lhs = { Pattern <Word, ShapeNode> .New("1").Annotation(any).OneOrMore.Value }, Rhs = { new CopyFromInput("1"), new InsertSegments(Table3, "v") } }); var verbTemplate = new AffixTemplate { Name = "verb", RequiredSyntacticFeatureStruct = FeatureStruct.New(Language.SyntacticFeatureSystem).Symbol("V").Value }; verbTemplate.Slots.Add(new AffixTemplateSlot(sSuffix, edSuffix) { Optional = true }); verbTemplate.Slots.Add(new AffixTemplateSlot(evidential) { Optional = true }); Morphophonemic.AffixTemplates.Add(verbTemplate); var morpher = new Morpher(TraceManager, Language); Word[] output = morpher.ParseWord("sagd").ToArray(); AssertMorphsEqual(output, "32 PAST"); AssertSyntacticFeatureStructsEqual(output, FeatureStruct.New(Language.SyntacticFeatureSystem) .Symbol("V") .Feature(Head).EqualTo(head => head .Feature("tense").EqualTo("past")).Value); output = morpher.ParseWord("sagdv").ToArray(); AssertMorphsEqual(output, "32 PAST WIT"); AssertSyntacticFeatureStructsEqual(output, FeatureStruct.New(Language.SyntacticFeatureSystem) .Symbol("V") .Feature(Head).EqualTo(head => head .Feature("tense").EqualTo("past") .Feature("evidential").EqualTo("witnessed")).Value); Assert.That(morpher.ParseWord("sid"), Is.Empty); output = morpher.ParseWord("sau").ToArray(); AssertMorphsEqual(output, "bl2"); AssertSyntacticFeatureStructsEqual(output, FeatureStruct.New(Language.SyntacticFeatureSystem) .Symbol("V") .Feature(Head).EqualTo(head => head .Feature("tense").EqualTo("past")).Value); evidential.RealizationalFeatureStruct = FeatureStruct.New(Language.SyntacticFeatureSystem) .Feature(Head).EqualTo(head => head .Feature("evidential").EqualTo("witnessed") .Feature("tense").EqualTo("pres")).Value; morpher = new Morpher(TraceManager, Language); output = morpher.ParseWord("sagzv").ToArray(); AssertMorphsEqual(output, "32 3SG WIT"); AssertSyntacticFeatureStructsEqual(output, FeatureStruct.New(Language.SyntacticFeatureSystem) .Symbol("V") .Feature(Head).EqualTo(head => head .Feature("pers").EqualTo("3") .Feature("tense").EqualTo("pres") .Feature("evidential").EqualTo("witnessed")).Value); }
public override IRule <Word, ShapeNode> CompileSynthesisRule(Morpher morpher) { return(new PipelineRuleCascade <Word, ShapeNode>( _strata.Select(stratum => stratum.CompileSynthesisRule(morpher)), FreezableEqualityComparer <Word> .Default)); }
public override IRule <Word, ShapeNode> CompileAnalysisRule(Morpher morpher) { return(new AnalysisLanguageRule(morpher, this)); }
public AnalysisLanguageRule(Morpher morpher, Language language) { _morpher = morpher; _strata = language.Strata.Reverse().ToList(); _rules = _strata.Select(stratum => stratum.CompileAnalysisRule(morpher)).ToList(); }
public override IRule <Word, ShapeNode> CompileSynthesisRule(Morpher morpher) { return(new SynthesisAffixTemplateRule(morpher, this)); }
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"); }