Skip to content

Commit

Permalink
Avoid duplicate matches
Browse files Browse the repository at this point in the history
  • Loading branch information
jtmaxwell3 committed Sep 18, 2024
1 parent a2a3c94 commit 2fa12a0
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 0 deletions.
13 changes: 13 additions & 0 deletions src/SIL.Machine.Morphology.HermitCrab/Morpher.cs
Original file line number Diff line number Diff line change
Expand Up @@ -359,12 +359,16 @@ LexEntry entry in SearchRootAllomorphs(input.Stratum, input.Shape)
}
}

/// <summary>
/// Match the input against lexical patterns and return matches.
/// </summary>
private IEnumerable<Word> LexicalGuess(Word input)
{
if (_traceManager.IsTracing)
_traceManager.LexicalLookup(input.Stratum, input);
CharacterDefinitionTable table = input.Stratum.CharacterDefinitionTable;
IEnumerable<ShapeNode> shapeNodes = input.Shape.GetNodes(input.Range);
HashSet<string> shapeSet = new HashSet<string>();
foreach (RootAllomorph lexicalPattern in _lexicalPatterns)
{
IEnumerable<ShapeNode> shapePattern = lexicalPattern.Segments.Shape.GetNodes(
Expand All @@ -374,6 +378,10 @@ private IEnumerable<Word> LexicalGuess(Word input)
{
// Create a root allomorph for the guess.
string shapeString = match.ToString(table, false);
if (shapeSet.Contains(shapeString))
// Avoid duplicates caused by multiple paths through pattern (e.g. ([Seg])([Seg])).
continue;
shapeSet.Add(shapeString);
var root = new RootAllomorph(new Segments(table, shapeString)) { Guessed = true };
// Create a lexical entry to hold the root allomorph.
// (The root's Morpheme will point to the lexical entry.)
Expand Down Expand Up @@ -402,6 +410,11 @@ private IEnumerable<Word> LexicalGuess(Word input)
}
}

/// <summary>
/// Match the shape nodes against the shape pattern.
/// This can produce multiple outputs if there is more than one path.
/// The outputs can be different because it unifies the nodes.
/// </summary>
public IEnumerable<List<ShapeNode>> MatchNodesWithPattern(
IList<ShapeNode> nodes,
IList<ShapeNode> pattern,
Expand Down
15 changes: 15 additions & 0 deletions tests/SIL.Machine.Morphology.HermitCrab.Tests/MorpherTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,21 @@ public void TestMatchNodesWithPattern()
);
Assert.That(morpher.MatchNodesWithPattern(twoNodes, optionalPattern), Is.Empty);

// Test ambiguity.
// (It is up to the caller to eliminate duplicates.)
IList<ShapeNode> optionalPattern2 = GetNodes("([Any])([Any])");
Assert.That(
morpher.MatchNodesWithPattern(noNodes, optionalPattern2),
Is.EquivalentTo(new List<IList<ShapeNode>> { noNodes })
);
Assert.That(
morpher.MatchNodesWithPattern(oneNode, optionalPattern2),
Is.EquivalentTo(new List<IList<ShapeNode>> { oneNode, oneNode })
);
Assert.That(morpher.MatchNodesWithPattern(twoNodes, optionalPattern2),
Is.EquivalentTo(new List<IList<ShapeNode>> { twoNodes }));
Assert.That(morpher.MatchNodesWithPattern(threeNodes, optionalPattern2), Is.Empty);

// Test Kleene star.
IList<ShapeNode> starPattern = GetNodes("[Any]*");
Assert.That(
Expand Down

0 comments on commit 2fa12a0

Please sign in to comment.