From 4562502b8b18d147c1d7610ce3fd4352cfcf51ca Mon Sep 17 00:00:00 2001 From: John Maxwell Date: Thu, 3 Sep 2026 07:40:28 -0700 Subject: [PATCH 1/2] Fix bug in MergeEquivalentAnalyses --- .../AnalysisStratumRule.cs | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/SIL.Machine.Morphology.HermitCrab/AnalysisStratumRule.cs b/src/SIL.Machine.Morphology.HermitCrab/AnalysisStratumRule.cs index 48bc2474..ea46aa79 100644 --- a/src/SIL.Machine.Morphology.HermitCrab/AnalysisStratumRule.cs +++ b/src/SIL.Machine.Morphology.HermitCrab/AnalysisStratumRule.cs @@ -127,11 +127,11 @@ internal IEnumerable Apply(Word input, ref int alternativeCount) _prulesRule.Apply(input); input.Freeze(); - IDictionary shapeWord = null; + IDictionary wordCache = null; // Don't merge if tracing because it messes up the tracing. bool mergeEquivalentAnalyses = _morpher.MergeEquivalentAnalyses && !_morpher.TraceManager.IsTracing; if (mergeEquivalentAnalyses) - shapeWord = new Dictionary(FreezableEqualityComparer.Default); + wordCache = new Dictionary(); // AnalysisStratumRule.Apply should cover the inverse of SynthesisStratumRule.Apply. IEnumerable mruleOutWords = ApplyTemplates(input).Concat(ApplyMorphologicalRules(input)); @@ -152,14 +152,13 @@ internal IEnumerable Apply(Word input, ref int alternativeCount) mruleOutWord.Source = origInput; if (mergeEquivalentAnalyses) { - Shape shape = mruleOutWord.Shape; - Word canonicalWord; - if (shapeWord.TryGetValue(shape, out canonicalWord)) + var key = AnalysisStateKey.PinAndKey(mruleOutWord); + if (wordCache.TryGetValue(key, out Word canonicalWord)) { canonicalWord.Alternatives.Add(mruleOutWord); continue; } - shapeWord[shape] = mruleOutWord; + wordCache[key] = mruleOutWord; } output.Add(mruleOutWord); if (_morpher.TraceManager.IsTracing) From 4d58f22ff3298e03aed01a2f1b35aa19ba2222f8 Mon Sep 17 00:00:00 2001 From: John Maxwell Date: Fri, 11 Sep 2026 11:54:44 -0700 Subject: [PATCH 2/2] Add comment about SyntacticFeatureStruct --- src/SIL.Machine.Morphology.HermitCrab/Word.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/SIL.Machine.Morphology.HermitCrab/Word.cs b/src/SIL.Machine.Morphology.HermitCrab/Word.cs index 51c3c53c..38a1bca9 100644 --- a/src/SIL.Machine.Morphology.HermitCrab/Word.cs +++ b/src/SIL.Machine.Morphology.HermitCrab/Word.cs @@ -632,6 +632,9 @@ public override bool ValueEquals(Word other) if (IsFrozen && other.IsFrozen && GetFrozenHashCode() != other.GetFrozenHashCode()) return false; + // We don't need to include SyntacticFeatureStruct because it is uniquely determined + // by the combination of _mruleApps and _realizationalFS. AffixTemplates check + // but don't change SyntacticFeatureStruct. return _shape.ValueEquals(other._shape) && _realizationalFS.ValueEquals(other._realizationalFS) && _nonHeadApps.SequenceEqual(other._nonHeadApps, FreezableEqualityComparer.Default)