Skip to content

Commit 14eceeb

Browse files
Merge remote-tracking branch 'origin/investigate_alignment_deuterocanonical_books' into investigate_alignment_deuterocanonical_books
2 parents 686114c + 2e54631 commit 14eceeb

File tree

3 files changed

+76
-12
lines changed

3 files changed

+76
-12
lines changed

src/SIL.Machine.Morphology.HermitCrab/AnalysisStratumRule.cs

Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,11 @@ public AnalysisStratumRule(Morpher morpher, Stratum stratum)
3434
switch (stratum.MorphologicalRuleOrder)
3535
{
3636
case MorphologicalRuleOrder.Linear:
37-
_mrulesRule = new LinearRuleCascade<Word, ShapeNode>(
37+
// Use PermutationRuleCascade instead of LinearRuleCascade
38+
// because morphological rules should be considered optional
39+
// during unapplication (they are obligatory during application,
40+
// but we don't know they have been applied during unapplication).
41+
_mrulesRule = new PermutationRuleCascade<Word, ShapeNode>(
3842
mrules,
3943
true,
4044
FreezableEqualityComparer<Word>.Default
@@ -69,17 +73,8 @@ public IEnumerable<Word> Apply(Word input)
6973
_prulesRule.Apply(input);
7074
input.Freeze();
7175

72-
IEnumerable<Word> mruleOutWords = null;
73-
switch (_stratum.MorphologicalRuleOrder)
74-
{
75-
case MorphologicalRuleOrder.Linear:
76-
mruleOutWords = ApplyTemplates(input);
77-
break;
78-
79-
case MorphologicalRuleOrder.Unordered:
80-
mruleOutWords = ApplyTemplates(input).Concat(ApplyMorphologicalRules(input));
81-
break;
82-
}
76+
// AnalysisStratumRule.Apply should cover the inverse of SynthesisStratumRule.Apply.
77+
IEnumerable<Word> mruleOutWords = ApplyTemplates(input).Concat(ApplyMorphologicalRules(input));
8378
Debug.Assert(mruleOutWords != null);
8479

8580
var output = new HashSet<Word>(FreezableEqualityComparer<Word>.Default) { input };

tests/SIL.Machine.Morphology.HermitCrab.Tests/HermitCrabTestBase.cs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -813,6 +813,15 @@ public void TestCleanup()
813813
stratum.MorphologicalRules.Clear();
814814
stratum.AffixTemplates.Clear();
815815
}
816+
SetRuleOrder(MorphologicalRuleOrder.Unordered);
817+
}
818+
819+
protected void SetRuleOrder(MorphologicalRuleOrder ruleOrder)
820+
{
821+
foreach (Stratum stratum in Language.Strata)
822+
{
823+
stratum.MorphologicalRuleOrder = ruleOrder;
824+
}
816825
}
817826

818827
public LexEntry AddEntry(string gloss, FeatureStruct syntacticFS, Stratum stratum, params string[] forms)

tests/SIL.Machine.Morphology.HermitCrab.Tests/MorpherTests.cs

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
using SIL.Machine.FeatureModel;
44
using SIL.Machine.Matching;
55
using SIL.Machine.Morphology.HermitCrab.MorphologicalRules;
6+
using SIL.Machine.Morphology.HermitCrab.PhonologicalRules;
67

78
namespace SIL.Machine.Morphology.HermitCrab;
89

@@ -38,6 +39,65 @@ public void AnalyzeWord_CanAnalyze_ReturnsCorrectAnalysis()
3839
);
3940
}
4041

42+
[Test]
43+
public void AnalyzeWord_CanAnalyzeLinear_ReturnsCorrectAnalysis()
44+
{
45+
var any = FeatureStruct.New().Symbol(HCFeatureSystem.Segment).Value;
46+
47+
var edSuffix = new AffixProcessRule
48+
{
49+
Id = "PAST",
50+
Name = "ed_suffix",
51+
Gloss = "PAST",
52+
RequiredSyntacticFeatureStruct = FeatureStruct.New(Language.SyntacticFeatureSystem).Symbol("V").Value
53+
};
54+
edSuffix.Allomorphs.Add(
55+
new AffixProcessAllomorph
56+
{
57+
Lhs = { Pattern<Word, ShapeNode>.New("1").Annotation(any).OneOrMore.Value },
58+
Rhs = { new CopyFromInput("1"), new InsertSegments(Table3, "+d") }
59+
}
60+
);
61+
Morphophonemic.MorphologicalRules.Add(edSuffix);
62+
63+
// Adding rules shouldn't block sagd analysis when Linear.
64+
var tSuffix = new AffixProcessRule
65+
{
66+
Id = "PLURAL",
67+
Name = "t_suffix",
68+
Gloss = "PLURAL",
69+
RequiredSyntacticFeatureStruct = FeatureStruct.New(Language.SyntacticFeatureSystem).Symbol("N").Value
70+
};
71+
tSuffix.Allomorphs.Add(
72+
new AffixProcessAllomorph
73+
{
74+
Lhs = { Pattern<Word, ShapeNode>.New("1").Annotation(any).OneOrMore.Value },
75+
Rhs = { new CopyFromInput("1"), new InsertSegments(Table3, "+t") }
76+
}
77+
);
78+
Morphophonemic.MorphologicalRules.Add(tSuffix);
79+
80+
// Add a phonological rule so that "sagd" becomes "sag[dt]" during unapplication.
81+
// This is to verify that unapplication works correctly.
82+
var rule1 = new RewriteRule
83+
{
84+
Name = "rule1",
85+
Lhs = Pattern<Word, ShapeNode>.New().Annotation(Character(Table1, "t")).Value
86+
};
87+
rule1.Subrules.Add(
88+
new RewriteSubrule { Rhs = Pattern<Word, ShapeNode>.New().Annotation(Character(Table1, "d")).Value }
89+
);
90+
Morphophonemic.PhonologicalRules.Add(rule1);
91+
92+
SetRuleOrder(MorphologicalRuleOrder.Linear);
93+
var morpher = new Morpher(TraceManager, Language);
94+
95+
Assert.That(
96+
morpher.AnalyzeWord("sagd"),
97+
Is.EquivalentTo(new[] { new WordAnalysis(new IMorpheme[] { Entries["32"], edSuffix }, 0, "V") })
98+
);
99+
}
100+
41101
[Test]
42102
public void AnalyzeWord_CannotAnalyze_ReturnsEmptyEnumerable()
43103
{

0 commit comments

Comments
 (0)