Skip to content
Draft
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
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,15 @@

namespace SIL.Machine.Morphology.HermitCrab
{
internal class AnalysisAffixTemplateRule : IRule<Word, ShapeNode>
internal class AnalysisAffixTemplateRule : InstrumentedRule<Word, ShapeNode>
{
private readonly Morpher _morpher;
private readonly AffixTemplate _template;
private readonly List<IRule<Word, ShapeNode>> _rules;

public AnalysisAffixTemplateRule(Morpher morpher, AffixTemplate template)
{
Name = template.Name;
_morpher = morpher;
_template = template;
_rules = new List<IRule<Word, ShapeNode>>(
Expand All @@ -29,9 +30,10 @@ public AnalysisAffixTemplateRule(Morpher morpher, AffixTemplate template)
FreezableEqualityComparer<Word>.Default
))
);
AddSubRules(_rules);
}

public IEnumerable<Word> Apply(Word input)
public override IEnumerable<Word> Apply(Word input)
{
if (!_morpher.RuleSelector(_template))
return Enumerable.Empty<Word>();
Expand All @@ -55,6 +57,8 @@ public IEnumerable<Word> Apply(Word input)

foreach (Word outWord in output)
outWord.SyntacticFeatureStruct.Add(fs);

AddRuleStats(output.Count);
return output;
}

Expand Down
10 changes: 8 additions & 2 deletions src/SIL.Machine.Morphology.HermitCrab/AnalysisLanguageRule.cs
Original file line number Diff line number Diff line change
@@ -1,26 +1,30 @@
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using SIL.Machine.Annotations;
using SIL.Machine.Rules;
using SIL.ObjectModel;

namespace SIL.Machine.Morphology.HermitCrab
{
internal class AnalysisLanguageRule : IRule<Word, ShapeNode>
internal class AnalysisLanguageRule : InstrumentedRule<Word, ShapeNode>
{
private readonly Morpher _morpher;
private readonly List<Stratum> _strata;
private readonly List<IRule<Word, ShapeNode>> _rules;

public AnalysisLanguageRule(Morpher morpher, Language language)
{
Name = "Analysis";
_morpher = morpher;
_strata = language.Strata.Reverse().ToList();
_rules = _strata.Select(stratum => stratum.CompileAnalysisRule(morpher)).ToList();
AddSubRules(_rules);
}

public IEnumerable<Word> Apply(Word input)
public override IEnumerable<Word> Apply(Word input)
{
long startTime = Stopwatch.GetTimestamp();
var inputSet = new HashSet<Word>(FreezableEqualityComparer<Word>.Default) { input };
var tempSet = new HashSet<Word>(FreezableEqualityComparer<Word>.Default);
var results = new HashSet<Word>(FreezableEqualityComparer<Word>.Default);
Expand All @@ -45,6 +49,8 @@ public IEnumerable<Word> Apply(Word input)
inputSet = outputSet;
}

AddElapsedTime(Stopwatch.GetTimestamp() - startTime);
AddRuleStats(results.Count());
return results;
}
}
Expand Down
12 changes: 10 additions & 2 deletions src/SIL.Machine.Morphology.HermitCrab/AnalysisStratumRule.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

namespace SIL.Machine.Morphology.HermitCrab
{
internal class AnalysisStratumRule : IRule<Word, ShapeNode>
internal class AnalysisStratumRule : InstrumentedRule<Word, ShapeNode>
{
private readonly IRule<Word, ShapeNode> _mrulesRule;
private readonly IRule<Word, ShapeNode> _prulesRule;
Expand All @@ -18,6 +18,7 @@ internal class AnalysisStratumRule : IRule<Word, ShapeNode>

public AnalysisStratumRule(Morpher morpher, Stratum stratum)
{
Name = stratum.Name;
_stratum = stratum;
_morpher = morpher;
_prulesRule = new LinearRuleCascade<Word, ShapeNode>(
Expand Down Expand Up @@ -61,6 +62,9 @@ public AnalysisStratumRule(Morpher morpher, Stratum stratum)
#endif
break;
}
AddSubRule(_prulesRule);
AddSubRule(_templatesRule);
AddSubRule(_mrulesRule);
}

private IRule<Word, ShapeNode> CompileAffixTemplate(AffixTemplate template, Morpher morpher)
Expand Down Expand Up @@ -99,8 +103,9 @@ private IRule<Word, ShapeNode> CompilePhonologicalRule(IPhonologicalRule prule,
}
}

public IEnumerable<Word> Apply(Word input)
public override IEnumerable<Word> Apply(Word input)
{
long startTime = Stopwatch.GetTimestamp();
if (_morpher.TraceManager.IsTracing)
_morpher.TraceManager.BeginUnapplyStratum(_stratum, input);

Expand Down Expand Up @@ -144,6 +149,9 @@ public IEnumerable<Word> Apply(Word input)
if (_morpher.MaxUnapplications > 0 && output.Count >= _morpher.MaxUnapplications)
break;
}

AddElapsedTime(Stopwatch.GetTimestamp() - startTime);
AddRuleStats(output.Count);
return output;
}

Expand Down
46 changes: 45 additions & 1 deletion src/SIL.Machine.Morphology.HermitCrab/Morpher.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ public class Morpher : IMorphologicalAnalyzer, IMorphologicalGenerator
private readonly ITraceManager _traceManager;
private readonly ReadOnlyObservableCollection<Morpheme> _morphemes;
private readonly IList<RootAllomorph> _lexicalPatterns = new List<RootAllomorph>();
private bool _enableCorpusStatistics = false;

public Morpher(ITraceManager traceManager, Language lang)
{
Expand All @@ -53,8 +54,9 @@ public Morpher(ITraceManager traceManager, Language lang)
}
_analysisRule = lang.CompileAnalysisRule(this);
_synthesisRule = lang.CompileSynthesisRule(this);
((InstrumentedRule<Word, ShapeNode>)_synthesisRule).Name = "Synthesis";
MaxStemCount = 2;
MaxUnapplications = 0;
MaxUnapplications = 1000;
MergeEquivalentAnalyses = true;
LexEntrySelector = entry => true;
RuleSelector = rule => true;
Expand Down Expand Up @@ -84,6 +86,16 @@ public ITraceManager TraceManager
/// </summary>
public bool MergeEquivalentAnalyses { get; set; }

public bool EnableCorpusStatistics
{
get { return _enableCorpusStatistics; }
set
{
_enableCorpusStatistics = value;
ClearRuleStats();
}
}

public Func<LexEntry, bool> LexEntrySelector { get; set; }
public Func<IHCRule, bool> RuleSelector { get; set; }

Expand Down Expand Up @@ -119,6 +131,10 @@ public IEnumerable<Word> ParseWord(string word, out object trace, bool guessRoot
if (_traceManager.IsTracing)
_traceManager.AnalyzeWord(_lang, input);
trace = input.CurrentTrace;
if (!EnableCorpusStatistics)
{
ClearRuleStats();
}

// Unapply rules
var analyses = new ConcurrentQueue<Word>(_analysisRule.Apply(input));
Expand Down Expand Up @@ -163,6 +179,34 @@ public IEnumerable<Word> ParseWord(string word, out object trace, bool guessRoot
return syntheses;
}

/// <summary>
/// Get the top-level rule statistics.
/// </summary>
public IEnumerable<InstrumentedRule<Word, ShapeNode>> GetRuleStats()
{
var list = new List<InstrumentedRule<Word, ShapeNode>>();
if (_analysisRule is InstrumentedRule<Word, ShapeNode>)
{
list.Add(_analysisRule as InstrumentedRule<Word, ShapeNode>);
}
if (_synthesisRule is InstrumentedRule<Word, ShapeNode>)
{
list.Add(_synthesisRule as InstrumentedRule<Word, ShapeNode>);
}
return list;
}

/// <summary>
/// Clear all rule statistics.
/// </summary>
public void ClearRuleStats()
{
foreach (InstrumentedRule<Word, ShapeNode> rule in GetRuleStats())
{
rule.ClearStats();
}
}

/// <summary>
/// Generates surface forms from the specified word synthesis information.
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,15 @@

namespace SIL.Machine.Morphology.HermitCrab.MorphologicalRules
{
public class AnalysisAffixProcessRule : IRule<Word, ShapeNode>
public class AnalysisAffixProcessRule : InstrumentedRule<Word, ShapeNode>
{
private readonly Morpher _morpher;
private readonly AffixProcessRule _rule;
private readonly List<PatternRule<Word, ShapeNode>> _rules;

public AnalysisAffixProcessRule(Morpher morpher, AffixProcessRule rule)
{
Name = rule.Name;
_morpher = morpher;
_rule = rule;

Expand All @@ -36,7 +37,7 @@ public AnalysisAffixProcessRule(Morpher morpher, AffixProcessRule rule)
}
}

public IEnumerable<Word> Apply(Word input)
public override IEnumerable<Word> Apply(Word input)
{
if (!_morpher.RuleSelector(_rule))
return Enumerable.Empty<Word>();
Expand Down Expand Up @@ -70,6 +71,8 @@ public IEnumerable<Word> Apply(Word input)
if (_morpher.TraceManager.IsTracing && !unapplied)
_morpher.TraceManager.MorphologicalRuleNotUnapplied(_rule, i, input);
}

AddRuleStats(output.Count);
return output;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,15 @@

namespace SIL.Machine.Morphology.HermitCrab.MorphologicalRules
{
public class AnalysisCompoundingRule : IRule<Word, ShapeNode>
public class AnalysisCompoundingRule : InstrumentedRule<Word, ShapeNode>
{
private readonly Morpher _morpher;
private readonly CompoundingRule _rule;
private readonly List<IRule<Word, ShapeNode>> _rules;

public AnalysisCompoundingRule(Morpher morpher, CompoundingRule rule)
{
Name = rule.Name;
_morpher = morpher;
_rule = rule;

Expand All @@ -36,7 +37,7 @@ public AnalysisCompoundingRule(Morpher morpher, CompoundingRule rule)
}
}

public IEnumerable<Word> Apply(Word input)
public override IEnumerable<Word> Apply(Word input)
{
if (!_morpher.RuleSelector(_rule))
return Enumerable.Empty<Word>();
Expand Down Expand Up @@ -143,6 +144,7 @@ RootAllomorph allo in _morpher.SearchRootAllomorphs(_rule.Stratum, outWord.Curre
_morpher.TraceManager.MorphologicalRuleNotUnapplied(_rule, i, input);
}

AddRuleStats(output.Count);
return output;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,15 @@

namespace SIL.Machine.Morphology.HermitCrab.MorphologicalRules
{
public class AnalysisRealizationalAffixProcessRule : IRule<Word, ShapeNode>
public class AnalysisRealizationalAffixProcessRule : InstrumentedRule<Word, ShapeNode>
{
private readonly Morpher _morpher;
private readonly RealizationalAffixProcessRule _rule;
private readonly List<PatternRule<Word, ShapeNode>> _rules;

public AnalysisRealizationalAffixProcessRule(Morpher morpher, RealizationalAffixProcessRule rule)
{
Name = rule.Name;
_morpher = morpher;
_rule = rule;

Expand All @@ -37,7 +38,7 @@ public AnalysisRealizationalAffixProcessRule(Morpher morpher, RealizationalAffix
}
}

public IEnumerable<Word> Apply(Word input)
public override IEnumerable<Word> Apply(Word input)
{
if (!_morpher.RuleSelector(_rule))
return Enumerable.Empty<Word>();
Expand Down Expand Up @@ -65,6 +66,8 @@ public IEnumerable<Word> Apply(Word input)
if (_morpher.TraceManager.IsTracing && !unapplied)
_morpher.TraceManager.MorphologicalRuleNotUnapplied(_rule, i, input);
}

AddRuleStats(output.Count);
return output;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,15 @@

namespace SIL.Machine.Morphology.HermitCrab.MorphologicalRules
{
public class SynthesisAffixProcessRule : IRule<Word, ShapeNode>
public class SynthesisAffixProcessRule : InstrumentedRule<Word, ShapeNode>
{
private readonly Morpher _morpher;
private readonly AffixProcessRule _rule;
private readonly List<PatternRule<Word, ShapeNode>> _rules;

public SynthesisAffixProcessRule(Morpher morpher, AffixProcessRule rule)
{
Name = rule.Name;
_morpher = morpher;
_rule = rule;
_rules = new List<PatternRule<Word, ShapeNode>>();
Expand All @@ -38,7 +39,7 @@ public SynthesisAffixProcessRule(Morpher morpher, AffixProcessRule rule)
}
}

public IEnumerable<Word> Apply(Word input)
public override IEnumerable<Word> Apply(Word input)
{
if (!input.IsMorphologicalRuleApplicable(_rule))
return Enumerable.Empty<Word>();
Expand Down Expand Up @@ -232,6 +233,7 @@ public IEnumerable<Word> Apply(Word input)
}
}

AddRuleStats(output.Count);
return output;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,15 @@

namespace SIL.Machine.Morphology.HermitCrab.MorphologicalRules
{
public class SynthesisCompoundingRule : IRule<Word, ShapeNode>
public class SynthesisCompoundingRule : InstrumentedRule<Word, ShapeNode>
{
private readonly Morpher _morpher;
private readonly CompoundingRule _rule;
private readonly List<Tuple<Matcher<Word, ShapeNode>, Matcher<Word, ShapeNode>>> _subruleMatchers;

public SynthesisCompoundingRule(Morpher morpher, CompoundingRule rule)
{
Name = rule.Name;
_morpher = morpher;
_rule = rule;
_subruleMatchers = new List<Tuple<Matcher<Word, ShapeNode>, Matcher<Word, ShapeNode>>>();
Expand All @@ -42,7 +43,7 @@ private Matcher<Word, ShapeNode> BuildMatcher(IEnumerable<Pattern<Word, ShapeNod
);
}

public IEnumerable<Word> Apply(Word input)
public override IEnumerable<Word> Apply(Word input)
{
if (!input.IsMorphologicalRuleApplicable(_rule))
return Enumerable.Empty<Word>();
Expand Down Expand Up @@ -223,6 +224,7 @@ public IEnumerable<Word> Apply(Word input)
}
}

AddRuleStats(output.Count);
return output;
}

Expand Down
Loading
Loading