Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix another bug with MorphologicalRuleOrder.Linear #280

Merged
merged 2 commits into from
Jan 13, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion src/SIL.Machine.Morphology.HermitCrab/AnalysisStratumRule.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,11 @@ public AnalysisStratumRule(Morpher morpher, Stratum stratum)
switch (stratum.MorphologicalRuleOrder)
{
case MorphologicalRuleOrder.Linear:
_mrulesRule = new LinearRuleCascade<Word, ShapeNode>(
// Use PermutationRuleCascade instead of LinearRuleCascade
// because morphological rules should be considered optional
// during unapplication (they are obligatory during application,
// but we don't know they have been applied during unapplication).
_mrulesRule = new PermutationRuleCascade<Word, ShapeNode>(
mrules,
true,
FreezableEqualityComparer<Word>.Default
Expand Down
54 changes: 54 additions & 0 deletions tests/SIL.Machine.Morphology.HermitCrab.Tests/MorpherTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using SIL.Machine.FeatureModel;
using SIL.Machine.Matching;
using SIL.Machine.Morphology.HermitCrab.MorphologicalRules;
using SIL.Machine.Morphology.HermitCrab.PhonologicalRules;

namespace SIL.Machine.Morphology.HermitCrab;

Expand Down Expand Up @@ -36,8 +37,61 @@ public void AnalyzeWord_CanAnalyze_ReturnsCorrectAnalysis()
morpher.AnalyzeWord("sagd"),
Is.EquivalentTo(new[] { new WordAnalysis(new IMorpheme[] { Entries["32"], edSuffix }, 0, "V") })
);
}

[Test]
public void AnalyzeWord_CanAnalyzeLinear_ReturnsCorrectAnalysis()
{
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);

// Adding rules shouldn't block sagd analysis when Linear.
var tSuffix = new AffixProcessRule
{
Id = "PLURAL",
Name = "t_suffix",
Gloss = "PLURAL",
RequiredSyntacticFeatureStruct = FeatureStruct.New(Language.SyntacticFeatureSystem).Symbol("N").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);

// Add a phonological rule so that "sagd" becomes "sag[dt]" during unapplication.
// This is to verify that unapplication works correctly.
var rule1 = new RewriteRule
{
Name = "rule1",
Lhs = Pattern<Word, ShapeNode>.New().Annotation(Character(Table1, "t")).Value
};
rule1.Subrules.Add(
new RewriteSubrule { Rhs = Pattern<Word, ShapeNode>.New().Annotation(Character(Table1, "d")).Value }
);
Morphophonemic.PhonologicalRules.Add(rule1);

SetRuleOrder(MorphologicalRuleOrder.Linear);
var morpher = new Morpher(TraceManager, Language);

Assert.That(
morpher.AnalyzeWord("sagd"),
Is.EquivalentTo(new[] { new WordAnalysis(new IMorpheme[] { Entries["32"], edSuffix }, 0, "V") })
Expand Down
Loading