internal FeatureStructBuilder(FeatureSystem featSys, FeatureStruct fs, IDictionary<int, FeatureValue> ids, bool mutable) { _featSys = featSys; _fs = fs; _ids = ids; _mutable = mutable; }
public override PatternNode<ComplexConcParagraphData, ShapeNode> GeneratePattern(FeatureSystem featSys) { var fs = new FeatureStruct(); var typeFeat = featSys.GetFeature<SymbolicFeature>("type"); fs.AddValue(typeFeat, typeFeat.PossibleSymbols["word"]); AddStringValue(featSys, fs, Form, "form"); AddStringValue(featSys, fs, Gloss, "gloss"); if (Category != null) { var catFeat = featSys.GetFeature<SymbolicFeature>("cat"); IEnumerable<FeatureSymbol> symbols = Category.ReallyReallyAllPossibilities.Concat(Category).Select(pos => catFeat.PossibleSymbols[pos.Hvo.ToString(CultureInfo.InvariantCulture)]); if (NegateCategory) symbols = catFeat.PossibleSymbols.Except(symbols); fs.AddValue(catFeat, symbols); } if (m_inflFeatures.Count > 0) { var inflFeat = featSys.GetFeature<ComplexFeature>("infl"); fs.AddValue(inflFeat, GetFeatureStruct(featSys, m_inflFeatures)); } var wordBdryFS = FeatureStruct.New(featSys).Symbol("bdry").Symbol("wordBdry").Value; var group = new Group<ComplexConcParagraphData, ShapeNode>(); group.Children.Add(new Quantifier<ComplexConcParagraphData, ShapeNode>(0, 1, new Constraint<ComplexConcParagraphData, ShapeNode>(wordBdryFS)) {IsGreedy = false}); group.Children.Add(new Constraint<ComplexConcParagraphData, ShapeNode>(fs)); group.Children.Add(new Quantifier<ComplexConcParagraphData, ShapeNode>(0, 1, new Constraint<ComplexConcParagraphData, ShapeNode>(wordBdryFS)) {IsGreedy = false}); return AddQuantifier(group); }
public NaturalClass(FeatureStruct fs) { if (!fs.IsFrozen) { fs.AddValue(HCFeatureSystem.Type, HCFeatureSystem.Segment); fs.Freeze(); } FeatureStruct = fs; }
public SimpleContext(NaturalClass nc, IEnumerable<SymbolicFeatureValue> variables) { _nc = nc; _variables = new ReadOnlyCollection<SymbolicFeatureValue>(variables.ToArray()); _fs = _nc.FeatureStruct.DeepClone(); foreach (SymbolicFeatureValue var in _variables) _fs.AddValue(var.Feature, var); _fs.Freeze(); }
public override PatternNode<ComplexConcParagraphData, ShapeNode> GeneratePattern(FeatureSystem featSys) { var fs = new FeatureStruct(); var typeFeat = featSys.GetFeature<SymbolicFeature>("type"); fs.AddValue(typeFeat, typeFeat.PossibleSymbols["ttag"]); if (Tag != null) { var tagFeat = featSys.GetFeature<SymbolicFeature>("tag"); fs.AddValue(tagFeat, tagFeat.PossibleSymbols[Tag.Hvo.ToString(CultureInfo.InvariantCulture)]); } return AddQuantifier(new Constraint<ComplexConcParagraphData, ShapeNode>(fs)); }
public SegmentNaturalClass(IEnumerable<CharacterDefinition> segments) { _segments = new ReadOnlyCollection<CharacterDefinition>(segments.ToArray()); FeatureStruct fs = null; foreach (CharacterDefinition segment in _segments) { if (fs == null) fs = segment.FeatureStruct.DeepClone(); else fs.Union(segment.FeatureStruct); } if (fs == null) fs = new FeatureStruct(); fs.Freeze(); FeatureStruct = fs; }
private bool AddCapturedPartNodes(string partName, int index, Match<Word, ShapeNode> match, FeatureStruct modifyFromFS, Shape output) { GroupCapture<ShapeNode> inputGroup = match.GroupCaptures[GetGroupName(partName, index)]; if (inputGroup.Success) { Span<ShapeNode> outputSpan = match.Input.Shape.CopyTo(inputGroup.Span, output); if (modifyFromFS != null) { foreach (ShapeNode node in output.GetNodes(outputSpan)) { if ((FeatureSymbol) modifyFromFS.GetValue(HCFeatureSystem.Type) == node.Annotation.Type()) node.Annotation.FeatureStruct.Add(modifyFromFS, match.VariableBindings); } } return true; } return false; }
static HCFeatureSystem() { Anchor = new FeatureSymbol(Guid.NewGuid().ToString()) { Description = "anchor" }; Segment = new FeatureSymbol(Guid.NewGuid().ToString()) { Description = "segment" }; Boundary = new FeatureSymbol(Guid.NewGuid().ToString()) { Description = "boundary" }; Morph = new FeatureSymbol(Guid.NewGuid().ToString()) { Description = "morph" }; Type = new SymbolicFeature(Guid.NewGuid().ToString(), Anchor, Segment, Boundary, Morph) { Description = "Type" }; Dirty = new FeatureSymbol(Guid.NewGuid().ToString()) { Description = "Dirty" }; Clean = new FeatureSymbol(Guid.NewGuid().ToString()) { Description = "Clean" }; Modified = new SymbolicFeature(Guid.NewGuid().ToString(), Dirty, Clean) { Description = "Modified", DefaultValue = new SymbolicFeatureValue(Clean) }; Deleted = new FeatureSymbol(Guid.NewGuid().ToString()) {Description = "Deleted"}; NotDeleted = new FeatureSymbol(Guid.NewGuid().ToString()) {Description = "NotDeleted"}; Deletion = new SymbolicFeature(Guid.NewGuid().ToString(), Deleted, NotDeleted) { Description = "Deletion", DefaultValue = new SymbolicFeatureValue(NotDeleted) }; LeftSide = new FeatureSymbol(Guid.NewGuid().ToString()) { Description = "LeftSide" }; RightSide = new FeatureSymbol(Guid.NewGuid().ToString()) { Description = "RightSide" }; AnchorType = new SymbolicFeature(Guid.NewGuid().ToString(), LeftSide, RightSide) { Description = "AnchorType" }; StrRep = new StringFeature(Guid.NewGuid().ToString()) {Description = "StrRep"}; Allomorph = new StringFeature(Guid.NewGuid().ToString()) {Description = "Allomorph"}; Instance = new HCFeatureSystem(); LeftSideAnchor = FeatureStruct.New().Symbol(Anchor).Symbol(LeftSide).Value; RightSideAnchor = FeatureStruct.New().Symbol(Anchor).Symbol(RightSide).Value; }
public override PatternNode<ComplexConcParagraphData, ShapeNode> GeneratePattern(FeatureSystem featSys) { var fs = new FeatureStruct(); var typeFeat = featSys.GetFeature<SymbolicFeature>("type"); fs.AddValue(typeFeat, typeFeat.PossibleSymbols["morph"]); AddStringValue(featSys, fs, Form, "form"); AddStringValue(featSys, fs, Gloss, "gloss"); AddStringValue(featSys, fs, Entry, "entry"); if (Category != null) { var catFeat = featSys.GetFeature<SymbolicFeature>("cat"); IEnumerable<FeatureSymbol> symbols = Category.ReallyReallyAllPossibilities.Concat(Category).Select(pos => catFeat.PossibleSymbols[pos.Hvo.ToString(CultureInfo.InvariantCulture)]); if (NegateCategory) symbols = catFeat.PossibleSymbols.Except(symbols); fs.AddValue(catFeat, symbols); } if (m_inflFeatures.Count > 0) { var inflFeat = featSys.GetFeature<ComplexFeature>("infl"); fs.AddValue(inflFeat, GetFeatureStruct(featSys, m_inflFeatures)); } return AddQuantifier(new Constraint<ComplexConcParagraphData, ShapeNode>(fs)); }
public NaturalClass(string name, FeatureStruct fs) : base(name) { _fs = fs; _fs.Freeze(); }
public bool IsRequiredMatch(FeatureStruct fs) { return _regions.Any(r => r.Subsumes(fs)); }
public override int Delta(FeatureStruct fs1, FeatureStruct fs2) { return _scorer.Delta(fs1, fs2); }
public Annotation <TOffset> Add(TOffset offset, FeatureStruct fs, bool optional) { return(Add(Range <TOffset> .Create(offset), fs, optional)); }
public void Compile() { m_featSys = new FeatureSystem { new SymbolicFeature("type", new FeatureSymbol("bdry", "Boundary"), new FeatureSymbol("word", "Word"), new FeatureSymbol("morph", "Morph"), new FeatureSymbol("ttag", "Text Tag")) { Description = "Type" }, new SymbolicFeature("anchorType", new FeatureSymbol("paraBdry", "Paragraph"), new FeatureSymbol("segBdry", "Segment"), new FeatureSymbol("wordBdry", "Word")) }; foreach (IWritingSystem ws in m_cache.ServiceLocator.WritingSystems.CurrentVernacularWritingSystems) { m_featSys.Add(new StringFeature(string.Format("entry-{0}", ws.Handle)) { Description = string.Format("Entry-{0}", ws.Abbreviation) }); m_featSys.Add(new StringFeature(string.Format("form-{0}", ws.Handle)) { Description = string.Format("Form-{0}", ws.Abbreviation) }); } foreach (IWritingSystem ws in m_cache.ServiceLocator.WritingSystems.CurrentAnalysisWritingSystems) { m_featSys.Add(new StringFeature(string.Format("gloss-{0}", ws.Handle)) { Description = string.Format("Gloss-{0}", ws.Abbreviation) }); } m_featSys.Add(new SymbolicFeature("cat", m_cache.ServiceLocator.GetInstance <IPartOfSpeechRepository>().AllInstances() .Select(pos => new FeatureSymbol(pos.Hvo.ToString(CultureInfo.InvariantCulture), pos.Abbreviation.BestAnalysisAlternative.Text))) { Description = "Category" }); m_featSys.Add(new SymbolicFeature("tag", m_cache.LangProject.TextMarkupTagsOA.PossibilitiesOS .SelectMany(poss => poss.SubPossibilitiesOS, (category, tag) => new FeatureSymbol(tag.Hvo.ToString(CultureInfo.InvariantCulture), tag.Abbreviation.BestAnalysisAlternative.Text))) { Description = "Tag" }); m_featSys.Add(new ComplexFeature("infl") { Description = "Infl", DefaultValue = FeatureStruct.New().Value }); foreach (IFsFeatDefn feature in m_cache.LangProject.MsFeatureSystemOA.FeaturesOC) { var complexFeat = feature as IFsComplexFeature; if (complexFeat != null) { m_featSys.Add(new ComplexFeature(complexFeat.Hvo.ToString(CultureInfo.InvariantCulture)) { Description = complexFeat.Abbreviation.BestAnalysisAlternative.Text, DefaultValue = FeatureStruct.New().Value }); } else { var closedFeat = (IFsClosedFeature)feature; m_featSys.Add(new SymbolicFeature(closedFeat.Hvo.ToString(CultureInfo.InvariantCulture), closedFeat.ValuesOC.Select(sym => new FeatureSymbol(sym.Hvo.ToString(CultureInfo.InvariantCulture), sym.Abbreviation.BestAnalysisAlternative.Text)) .Concat(new FeatureSymbol(closedFeat.Hvo.ToString(CultureInfo.InvariantCulture) + "_us", "unspecified"))) { Description = closedFeat.Abbreviation.BestAnalysisAlternative.Text, DefaultSymbolID = closedFeat.Hvo.ToString(CultureInfo.InvariantCulture) + "_us" }); } } var pattern = new Pattern <ComplexConcParagraphData, ShapeNode>(); pattern.Children.Add(m_root.GeneratePattern(m_featSys)); m_matcher = new Matcher <ComplexConcParagraphData, ShapeNode>(m_spanFactory, pattern, new MatcherSettings <ShapeNode> { UseDefaults = true }); }
internal static FeatureStruct AntiFeatureStruct(this FeatureStruct fs) { // TODO: handle reentrancy properly var result = new FeatureStruct(); foreach (Feature feature in fs.Features) { FeatureValue value = fs.GetValue(feature); var childFS = value as FeatureStruct; FeatureValue newValue; if (childFS != null) { newValue = HCFeatureSystem.Instance.ContainsFeature(feature) ? childFS.DeepClone() : childFS.AntiFeatureStruct(); } else { var childSfv = (SimpleFeatureValue) value; newValue = HCFeatureSystem.Instance.ContainsFeature(feature) ? childSfv.DeepClone() : childSfv.Negation(); } result.AddValue(feature, newValue); } return result; }
public Annotation <TOffset> Add(TOffset offset, FeatureStruct fs, bool optional) { return(Add(_spanFactory.Create(offset), fs, optional)); }
protected FeatureStruct GetFeatureStruct(FeatureSystem featSys, IDictionary<IFsFeatDefn, object> values) { var fs = new FeatureStruct(); foreach (KeyValuePair<IFsFeatDefn, object> kvp in values) { if (kvp.Key is IFsComplexFeature) { var childValues = (IDictionary<IFsFeatDefn, object>) kvp.Value; fs.AddValue(featSys.GetFeature(kvp.Key.Hvo.ToString(CultureInfo.InvariantCulture)), GetFeatureStruct(featSys, childValues)); } else if (kvp.Key is IFsClosedFeature) { var value = (ClosedFeatureValue) kvp.Value; var symFeat = featSys.GetFeature<SymbolicFeature>(kvp.Key.Hvo.ToString(CultureInfo.InvariantCulture)); FeatureSymbol symbol = symFeat.PossibleSymbols[value.Symbol.Hvo.ToString(CultureInfo.InvariantCulture)]; fs.AddValue(symFeat, value.Negate ? new SymbolicFeatureValue(symFeat.PossibleSymbols.Except(symbol.ToEnumerable())) : new SymbolicFeatureValue(symbol)); } } return fs; }
public IQuantifierPatternSyntax <TData, TOffset> Annotation(FeatureStruct fs) { AddAnnotation(fs); return(this); }
public Annotation <TOffset> Add(TOffset start, TOffset end, FeatureStruct fs, bool optional) { return(Add(_spanFactory.Create(start, end), fs, optional)); }
internal CharacterDefinition(IList<string> representations, FeatureStruct fs) { _representations = new ReadOnlyCollection<string>(representations); _fs = fs; }
public void Batch() { var pattern = Pattern <AnnotatedStringData, int> .New() .Group("leftEnv", leftEnv => leftEnv .Annotation(FeatureStruct.New(PhoneticFeatSys) .Symbol(Seg) .Symbol("cons+") .Feature("voice").EqualToVariable("a").Value)) .Group("target", target => target .Annotation(FeatureStruct.New(PhoneticFeatSys) .Symbol(Seg) .Symbol("cons-") .Symbol("low+").Value)) .Group("rightEnv", rightEnv => rightEnv .Annotation(FeatureStruct.New(PhoneticFeatSys) .Symbol(Seg) .Symbol("cons+") .Feature("voice").Not.EqualToVariable("a").Value)).Value; var ruleSpec1 = new DefaultPatternRuleSpec <AnnotatedStringData, int>(pattern, (r, match) => { GroupCapture <int> target = match.GroupCaptures["target"]; foreach (Annotation <int> ann in match.Input.Annotations.GetNodes(target.Span)) { ann.FeatureStruct.PriorityUnion(FeatureStruct.New(PhoneticFeatSys) .Symbol("low-") .Symbol("mid-").Value); } return(match.Input); }, input => input.Annotations.Single(ann => ((FeatureSymbol)ann.FeatureStruct.GetValue(Type)) == Word) .FeatureStruct.IsUnifiable(FeatureStruct.New(WordFeatSys).Symbol("verb").Value)); var ruleSpec2 = new DefaultPatternRuleSpec <AnnotatedStringData, int>(pattern, (r, match) => { GroupCapture <int> target = match.GroupCaptures["target"]; foreach (Annotation <int> ann in match.Input.Annotations.GetNodes(target.Span)) { ann.FeatureStruct.PriorityUnion(FeatureStruct.New(PhoneticFeatSys) .Symbol("low-") .Symbol("mid+").Value); } return(match.Input); }); var batchSpec = new BatchPatternRuleSpec <AnnotatedStringData, int>(new[] { ruleSpec1, ruleSpec2 }); var rule = new PatternRule <AnnotatedStringData, int>(SpanFactory, batchSpec); AnnotatedStringData inputWord = CreateStringData("fazk"); inputWord.Annotations.Add(inputWord.Span, FeatureStruct.New(WordFeatSys).Symbol(Word).Symbol("noun").Value); Assert.IsTrue(rule.Apply(inputWord).Any()); }
public Annotation <TOffset> Add(Range <TOffset> range, FeatureStruct fs) { return(Add(range, fs, false)); }
public Symbol(string strRep, FeatureStruct fs, bool overwrite) { _strRep = strRep.ToLowerInvariant(); _fs = fs; _overwrite = overwrite; }
public Annotation <TOffset> Add(Span <TOffset> span, FeatureStruct fs) { return(Add(span, fs, false)); }
private void ProcessSyllableWithMaximalOnset(ShapeNode startNode, ShapeNode endNode, Shape newShape) { ShapeNode node = startNode; ShapeNode onsetStart = node; while (node.Type() == CogFeatureSystem.ConsonantType && node != endNode.Next) { node = node.Next; } ShapeNode onsetEnd = node.Prev; if (onsetStart != node && onsetStart != onsetEnd) { ShapeNode n = onsetStart; if (onsetStart != onsetEnd.List.First) { for (; n != onsetEnd.Next; n = n.Next) { string onsetStr = n.GetNodes(onsetEnd).StrRep(); if (_initialOnsets.Value.Contains(onsetStr)) { break; } } // TODO: ambiguous onset, what should we do? For now, we just assume maximal onset if (n == onsetEnd.Next) { n = onsetStart; } } if (n != onsetStart) { if (onsetStart.Prev.Type() == CogFeatureSystem.ConsonantType) { CombineWith(newShape.GetLast(nd => nd.Type() == CogFeatureSystem.ConsonantType), onsetStart, n.Prev); } else { Combine(CogFeatureSystem.Coda, newShape, onsetStart, n.Prev); Annotation <ShapeNode> prevSyllableAnn = newShape.Annotations.Last(ann => ann.Type() == CogFeatureSystem.SyllableType); prevSyllableAnn.Remove(); newShape.Annotations.Add(prevSyllableAnn.Span.Start, newShape.Last, FeatureStruct.New().Symbol(CogFeatureSystem.SyllableType).Value); } startNode = n; } } ProcessSyllable(startNode, endNode, newShape); }
public Annotation <TOffset> Add(TOffset start, TOffset end, FeatureStruct fs) { return(Add(start, end, fs, false)); }
internal ModifyFromInput(string partName, FeatureStruct fs, params SymbolicFeatureValue[] variables) : this(partName, new SimpleContext(new NaturalClass(fs), variables)) { }
public bool Equals(PriorityUnionOutput <TData, TOffset> other) { return(other != null && FeatureStruct.ValueEquals(other.FeatureStruct)); }
private LexEntry AddEntry(string gloss, FeatureStruct syntacticFS, Stratum stratum, params string[] forms) { var entry = new LexEntry { SyntacticFeatureStruct = syntacticFS, Gloss = gloss, IsPartial = syntacticFS.IsEmpty }; foreach (string form in forms) entry.Allomorphs.Add(new RootAllomorph(new Segments(stratum.CharacterDefinitionTable, form))); stratum.Entries.Add(entry); Entries[gloss] = entry; return entry; }
public override int GetHashCode() { return(FeatureStruct.GetFrozenHashCode()); }
internal InsertSimpleContext(FeatureStruct fs, params SymbolicFeatureValue[] variables) : this(new SimpleContext(new NaturalClass(fs), variables)) { }
internal PriorityUnionOutput(FeatureStruct fs) : base(fs) { }
private void NewNaturalClass() { var vm = new EditNaturalClassViewModel(_projectService.Project.FeatureSystem, _soundClasses.Select(nc => nc.DomainSoundClass)); if (_dialogService.ShowModalDialog(this, vm) == true) { var fs = new FeatureStruct(); fs.AddValue(CogFeatureSystem.Type, vm.Type == SoundType.Consonant ? CogFeatureSystem.ConsonantType : CogFeatureSystem.VowelType); foreach (FeatureViewModel feature in vm.ActiveFeatures) fs.AddValue(feature.DomainFeature, feature.SelectedValue.DomainSymbol); var newNaturalClass = new SoundClassViewModel(new NaturalClass(vm.Name, fs), _displaySonority ? 0 : -1); IsChanged = true; _soundClasses.Add(newNaturalClass); SelectedSoundClass = newNaturalClass; } }
private void StemWords(Direction dir, IEnumerable <Word> words, IEnumerable <Affix> affixes) { var ruleSpec = new BatchPatternRuleSpec <Word, ShapeNode>(); foreach (Affix affix in affixes) { var pattern = new Pattern <Word, ShapeNode> { Acceptable = CheckStemWholeWord }; if (dir == Direction.LeftToRight) { pattern.Children.Add(new Constraint <Word, ShapeNode>(FeatureStruct.New().Symbol(CogFeatureSystem.AnchorType).Value)); } foreach (ShapeNode node in affix.Shape) { pattern.Children.Add(new Quantifier <Word, ShapeNode>(0, 1, new Constraint <Word, ShapeNode>(FeatureStruct.New().Symbol(CogFeatureSystem.BoundaryType).Value))); pattern.Children.Add(new Constraint <Word, ShapeNode>(node.Annotation.FeatureStruct.DeepClone())); pattern.Children.Add(new Quantifier <Word, ShapeNode>(0, 1, new Constraint <Word, ShapeNode>(FeatureStruct.New().Symbol(CogFeatureSystem.ToneLetterType).Value))); } if (dir == Direction.RightToLeft) { pattern.Children.Add(new Constraint <Word, ShapeNode>(FeatureStruct.New().Symbol(CogFeatureSystem.AnchorType).Value)); } string category = affix.Category; ruleSpec.RuleSpecs.Add(new DefaultPatternRuleSpec <Word, ShapeNode>(pattern, MarkStem, word => category == null || word.Meaning.Category == category)); } var matcherSettings = new MatcherSettings <ShapeNode> { Direction = dir, Filter = ann => ann.Type().IsOneOf(CogFeatureSystem.ConsonantType, CogFeatureSystem.VowelType, CogFeatureSystem.AnchorType, CogFeatureSystem.ToneLetterType, CogFeatureSystem.BoundaryType) }; var rule = new PatternRule <Word, ShapeNode>(_spanFactory, ruleSpec, matcherSettings); foreach (Word word in words.Where(w => w.Shape.Count > 0)) { rule.Apply(word); } }
protected Output(FeatureStruct fs) { _fs = fs; }
public void IsDeterminizable() { var featSys = new FeatureSystem { new StringFeature("A"), new StringFeature("B"), new StringFeature("C"), new StringFeature("D"), new StringFeature("E"), new StringFeature("F") }; var fst = new Fst <StringData, int>(_operations); fst.StartState = fst.CreateState(); State <StringData, int> s1 = fst.StartState.Arcs.Add(FeatureStruct.New(featSys).Feature("A").EqualTo("true").Value, FeatureStruct.New(featSys).Feature("E").EqualTo("true").Value, fst.CreateState()); State <StringData, int> s2 = fst.StartState.Arcs.Add(FeatureStruct.New(featSys).Feature("A").EqualTo("true").Value, FeatureStruct.New(featSys).Feature("F").EqualTo("true").Value, fst.CreateState()); State <StringData, int> s3 = s1.Arcs.Add(FeatureStruct.New(featSys).Feature("B").EqualTo("true").Value, FeatureStruct.New(featSys).Feature("D").EqualTo("true").Value, fst.CreateState()); s2.Arcs.Add(FeatureStruct.New(featSys).Feature("C").EqualTo("true").Value, FeatureStruct.New(featSys).Feature("D").EqualTo("true").Value, s3); State <StringData, int> s4 = s3.Arcs.Add(FeatureStruct.New(featSys).Feature("A").EqualTo("true").Value, FeatureStruct.New(featSys).Feature("A").EqualTo("true").Value, fst.CreateAcceptingState()); Assert.That(fst.IsDeterminizable, Is.True); s4.Arcs.Add(FeatureStruct.New(featSys).Feature("A").EqualTo("true").Value, FeatureStruct.New(featSys).Feature("A").EqualTo("true").Value, s4); var writer = new System.IO.StreamWriter(string.Format("c:\\ltor-nfst.dot")); fst.ToGraphViz(writer); writer.Close(); Assert.That(fst.IsDeterminizable, Is.False); }
public bool IsExcludedMatch(FeatureStruct fs, StemName stemName) { return _regions.Except(stemName == null ? Enumerable.Empty<FeatureStruct>() : stemName.Regions, FreezableEqualityComparer<FeatureStruct>.Default).All(r => !r.Subsumes(fs)); }
public void Determinize() { var featSys = new FeatureSystem { new StringFeature("A"), new StringFeature("B"), new StringFeature("C"), new StringFeature("D"), new StringFeature("E"), new StringFeature("F") }; var nfst = new Fst <StringData, int>(_operations); nfst.StartState = nfst.CreateState(); State <StringData, int> s1 = nfst.StartState.Arcs.Add(FeatureStruct.New(featSys).Feature("A").EqualTo("true").Value, FeatureStruct.New(featSys).Feature("C").EqualTo("true").Value, nfst.CreateState()); State <StringData, int> sa = s1.Arcs.Add(FeatureStruct.New(featSys).Feature("D").EqualTo("true").Value, FeatureStruct.New(featSys).Feature("E").EqualTo("true").Value, nfst.CreateAcceptingState()); State <StringData, int> s2 = nfst.StartState.Arcs.Add(FeatureStruct.New(featSys).Feature("A").EqualTo("true").Value, FeatureStruct.New(featSys).Feature("B").EqualTo("true").Value, nfst.CreateState()); State <StringData, int> s3 = s2.Arcs.Add(FeatureStruct.New(featSys).Value, FeatureStruct.New(featSys).Value, nfst.CreateState()); s3.Arcs.Add(FeatureStruct.New(featSys).Feature("B").EqualTo("true").Value, FeatureStruct.New(featSys).Feature("B").EqualTo("true").Value, sa); var writer = new System.IO.StreamWriter(string.Format("c:\\ltor-nfst.dot")); nfst.ToGraphViz(writer); writer.Close(); Fst <StringData, int> dfst; Assert.That(nfst.TryDeterminize(out dfst), Is.True); writer = new System.IO.StreamWriter(string.Format("c:\\ltor-dfst.dot")); dfst.ToGraphViz(writer); writer.Close(); }
public Symbol(string strRep, FeatureStruct fs) : this(strRep, fs, false) { }
public void Compose() { var featSys = new FeatureSystem { new StringFeature("value") }; var fst1 = new Fst <StringData, int>(_operations); fst1.StartState = fst1.CreateState(); State <StringData, int> s1 = fst1.StartState.Arcs.Add(FeatureStruct.New(featSys).Feature("value").EqualTo("a").Value, FeatureStruct.New(featSys).Feature("value").EqualTo("x").Value, fst1.CreateAcceptingState()); s1.Arcs.Add(FeatureStruct.New(featSys).Feature("value").EqualTo("b").Value, FeatureStruct.New(featSys).Feature("value").EqualTo("y").Value, s1); var fst2 = new Fst <StringData, int>(_operations); fst2.StartState = fst2.CreateAcceptingState(); fst2.StartState.Arcs.Add(FeatureStruct.New(featSys).Feature("value").EqualTo("x").Value, null, fst2.StartState); fst2.StartState.Arcs.Add(FeatureStruct.New(featSys).Feature("value").EqualTo("y").Value, FeatureStruct.New(featSys).Feature("value").EqualTo("z").Value, fst2.StartState); Fst <StringData, int> composedFsa = fst1.Compose(fst2); var writer = new System.IO.StreamWriter(string.Format("c:\\ltor-composed-nfst.dot")); composedFsa.ToGraphViz(writer); writer.Close(); }
private bool ContainsFeature(FeatureStruct fs, Feature feature, ISet<FeatureStruct> visited) { if (visited.Contains(fs)) return false; if (fs.ContainsFeature(feature)) return true; if (fs.Features.OfType<ComplexFeature>().Any(cf => ContainsFeature(fs.GetValue(cf), feature, visited))) return true; return false; }
protected void AddAnnotation(FeatureStruct fs) { CheckEndAlternation(); AddNode(new Constraint <TData, TOffset>(fs)); }
private bool TryMultipleBaseCharacterSymbol(Match match, SymbolCollection bases, out string strRep, out FeatureStruct fs) { Group joinerGroup = match.Groups["joiner"]; Group modGroup = match.Groups["mod"]; Group consBaseGroup = match.Groups["consBase"]; Symbol symbol; if (joinerGroup.Success && (!modGroup.Success || modGroup.Index >= consBaseGroup.Index + consBaseGroup.Length) && bases.TryGetValue(string.Concat(consBaseGroup.Captures.Cast<Capture>().Select(cap => cap.Value)), out symbol)) { var sb = new StringBuilder(); sb.Append(symbol.StrRep); fs = symbol.FeatureStruct != null ? symbol.FeatureStruct.DeepClone() : new FeatureStruct(); ApplyModifiers(match.Groups["mod"].Captures.Cast<Capture>(), sb, fs); strRep = sb.ToString(); return true; } strRep = null; fs = null; return false; }
public void Migrate_NewProjectSspSyllabifier_SspSyllabifierUpdated() { var pm = new ProjectMigration4(); pm.Migrate(_segmentPool, _project); var syllabifier = (SspSyllabifier)_project.VarietyProcessors[ComponentIdentifiers.Syllabifier]; SonorityClass[] scale = syllabifier.SonorityScale.ToArray(); Assert.That(scale.Length, Is.EqualTo(17)); Assert.That(scale[0].SoundClass.Name, Is.EqualTo("Prenasal")); Assert.That(((UnnaturalClass)scale[8].SoundClass).IgnoreModifiers, Is.True); Assert.That(((NaturalClass)scale[16].SoundClass).FeatureStruct.ValueEquals(FeatureStruct.New(_project.FeatureSystem) .Symbol(CogFeatureSystem.VowelType).Symbol("syllabic+").Symbol("open").Value), Is.True); }
protected void AddStringValue(FeatureSystem featSys, FeatureStruct fs, ITsString tss, string id) { if (tss != null) { var feat = featSys.GetFeature<StringFeature>(string.Format("{0}-{1}", id, tss.get_WritingSystemAt(0).ToString(CultureInfo.InvariantCulture))); fs.AddValue(feat, tss.Text); } }
private void ApplyModifiers(IEnumerable<Capture> modifiers, StringBuilder sb, FeatureStruct fs) { var modStrs = new List<string>(); foreach (Capture modifier in modifiers) { string modStr = modifier.Value; Symbol modInfo = _modifiers[modStr]; if (modInfo.FeatureStruct != null && !modInfo.FeatureStruct.IsEmpty) { if (modInfo.Overwrite) fs.PriorityUnion(modInfo.FeatureStruct); else fs.Add(modInfo.FeatureStruct); if (modStr.Length == 1 && IsStackingDiacritic(modStr[0])) sb.Append(modStr); else modStrs.Add(modStr); } } modStrs.OrderBy(str => str).Aggregate(sb, (s, modStr) => s.Append(modStr)); }
public void SetUp() { _featSys = new FeatureSystem { new SymbolicFeature("place", new FeatureSymbol("bilabial"), new FeatureSymbol("labiodental"), new FeatureSymbol("dental"), new FeatureSymbol("alveolar"), new FeatureSymbol("retroflex"), new FeatureSymbol("palato-alveolar"), new FeatureSymbol("palatal"), new FeatureSymbol("velar"), new FeatureSymbol("uvular"), new FeatureSymbol("pharyngeal"), new FeatureSymbol("glottal")), new SymbolicFeature("manner", new FeatureSymbol("stop"), new FeatureSymbol("affricate"), new FeatureSymbol("fricative"), new FeatureSymbol("approximant"), new FeatureSymbol("trill"), new FeatureSymbol("flap"), new FeatureSymbol("close-vowel"), new FeatureSymbol("mid-vowel"), new FeatureSymbol("open-vowel")), new SymbolicFeature("voice", new FeatureSymbol("voice+"), new FeatureSymbol("voice-")), new SymbolicFeature("height", new FeatureSymbol("close"), new FeatureSymbol("near-close"), new FeatureSymbol("close-mid"), new FeatureSymbol("mid"), new FeatureSymbol("open-mid"), new FeatureSymbol("near-open"), new FeatureSymbol("open")), new SymbolicFeature("backness", new FeatureSymbol("front"), new FeatureSymbol("near-front"), new FeatureSymbol("central"), new FeatureSymbol("near-back"), new FeatureSymbol("back")), new SymbolicFeature("round", new FeatureSymbol("round+"), new FeatureSymbol("round-")) }; _segmentPool = new SegmentPool(); _segmenter = new Segmenter() { Consonants = { { "c", FeatureStruct.New(_featSys).Symbol("palatal").Symbol("stop").Symbol("voice-").Value }, { "b", FeatureStruct.New(_featSys).Symbol("bilabial").Symbol("stop").Symbol("voice+").Value }, { "r", FeatureStruct.New(_featSys).Symbol("alveolar").Symbol("trill").Symbol("voice+").Value } }, Vowels = { { "a", FeatureStruct.New(_featSys).Symbol("open").Symbol("front").Symbol("round-").Symbol("open-vowel").Symbol("voice+").Value } }, Boundaries = { "-" }, Modifiers = { "\u0303", "\u0308" }, Joiners = { "\u0361" } }; var syllabifier = new SimpleSyllabifier(false, false); var meaning = new Meaning("test", null); var v1 = new Variety("variety1"); _word1 = new Word("car", meaning); _segmenter.Segment(_word1); v1.Words.Add(_word1); syllabifier.Process(v1); var v2 = new Variety("variety2"); _word2 = new Word("bar", meaning); _segmenter.Segment(_word2); v2.Words.Add(_word2); syllabifier.Process(v2); var vp = new VarietyPair(v1, v2); vp.CognateSoundCorrespondenceFrequencyDistribution = new ConditionalFrequencyDistribution <SoundContext, Ngram <Segment> >(); vp.CognateSoundCorrespondenceFrequencyDistribution[_word1.Shape.First.ToSoundContext(_segmentPool, Enumerable.Empty <SoundClass>())].Increment(_segmentPool.Get(_word2.Shape.First)); vp.CognateSoundCorrespondenceProbabilityDistribution = new ConditionalProbabilityDistribution <SoundContext, Ngram <Segment> >(vp.CognateSoundCorrespondenceFrequencyDistribution, (sc, fd) => new MaxLikelihoodProbabilityDistribution <Ngram <Segment> >(fd)); v1.VarietyPairs.VarietyPairAdded(vp); v2.VarietyPairs.VarietyPairAdded(vp); }
protected void AssertSyntacticFeatureStructsEqual(IEnumerable<Word> words, FeatureStruct expected) { Assert.That(words, Has.All.Property("SyntacticFeatureStruct").EqualTo(expected).Using(FreezableEqualityComparer<FeatureStruct>.Default)); }
internal Input(FeatureStruct fs, int enqueueCount) : this(fs, Enumerable.Empty <FeatureStruct>(), enqueueCount) { }
private void AddSegDef(CharacterDefinitionTable table, FeatureSystem phoneticFeatSys, string strRep, params string[] symbols) { var fs = new FeatureStruct(); foreach (string symbolID in symbols) { FeatureSymbol symbol = phoneticFeatSys.GetSymbol(symbolID); fs.AddValue(symbol.Feature, new SymbolicFeatureValue(symbol)); } table.AddSegment(strRep, fs); }
public void Transduce() { var fst = new Fst <AnnotatedStringData, int>(_operations) { UseUnification = false }; fst.StartState = fst.CreateAcceptingState(); fst.StartState.Arcs.Add(FeatureStruct.New(PhoneticFeatSys).Symbol("nas-", "nas?").Value, fst.StartState); fst.StartState.Arcs.Add(FeatureStruct.New(PhoneticFeatSys).Symbol("nas+").Symbol("cor+", "cor-").Value, fst.StartState); State <AnnotatedStringData, int> s1 = fst.StartState.Arcs.Add(FeatureStruct.New(PhoneticFeatSys).Symbol("cor?").Symbol("nas+").Value, FeatureStruct.New(PhoneticFeatSys).Symbol("cor-").Value, fst.CreateState()); s1.Arcs.Add(FeatureStruct.New(PhoneticFeatSys).Symbol("cor-").Value, fst.StartState); State <AnnotatedStringData, int> s2 = fst.StartState.Arcs.Add(FeatureStruct.New(PhoneticFeatSys).Symbol("cor?").Symbol("nas+").Value, FeatureStruct.New(PhoneticFeatSys).Symbol("cor+").Value, fst.CreateAcceptingState()); s2.Arcs.Add(FeatureStruct.New(PhoneticFeatSys).Symbol("cor?").Symbol("nas+").Value, FeatureStruct.New(PhoneticFeatSys).Symbol("cor+").Value, s2); s2.Arcs.Add(FeatureStruct.New(PhoneticFeatSys).Symbol("nas-", "nas?").Symbol("cor+", "cor?").Value, fst.StartState); s2.Arcs.Add(FeatureStruct.New(PhoneticFeatSys).Symbol("nas+").Symbol("cor+").Value, fst.StartState); s2.Arcs.Add(FeatureStruct.New(PhoneticFeatSys).Symbol("cor?").Symbol("nas+").Value, FeatureStruct.New(PhoneticFeatSys).Symbol("cor-").Value, s1); Fst <AnnotatedStringData, int> dfst = fst.Determinize(); AnnotatedStringData data = CreateStringData("caNp"); FstResult <AnnotatedStringData, int> result; Assert.That(dfst.Transduce(data, data.Annotations.First, null, true, true, true, out result), Is.True); Assert.That(result.Output.String, Is.EqualTo("camp")); data = CreateStringData("caN"); Assert.That(dfst.Transduce(data, data.Annotations.First, null, true, true, true, out result), Is.True); Assert.That(result.Output.String, Is.EqualTo("can")); data = CreateStringData("carp"); Assert.That(dfst.Transduce(data, data.Annotations.First, null, true, true, true, out result), Is.True); Assert.That(result.Output.String, Is.EqualTo("carp")); fst = new Fst <AnnotatedStringData, int>(_operations) { UseUnification = false }; fst.StartState = fst.CreateAcceptingState(); s1 = fst.StartState.Arcs.Add(FeatureStruct.New(PhoneticFeatSys).Symbol("cons+").Value, fst.CreateState()) .Arcs.Add(FeatureStruct.New(PhoneticFeatSys).Symbol("cons-").Value, fst.CreateState()); s2 = s1.Arcs.Add(FeatureStruct.New(PhoneticFeatSys).Symbol("nas+").Value, null, fst.CreateState()); State <AnnotatedStringData, int> s3 = s1.Arcs.Add(FeatureStruct.New(PhoneticFeatSys).Symbol("voice-").Value, fst.CreateState()); s3.Arcs.Add(null, FeatureStruct.New(PhoneticFeatSys).Symbol(Bdry).Feature("strRep").EqualTo(".").Value, s2); s3.Arcs.Add(null, FeatureStruct.New(PhoneticFeatSys).Symbol(Bdry).Feature("strRep").EqualTo("+").Value, fst.CreateState()) .Arcs.Add(null, FeatureStruct.New(PhoneticFeatSys).Symbol(Bdry).Feature("strRep").EqualTo(".").Value, s2); s2.Arcs.Add(FeatureStruct.New(PhoneticFeatSys).Symbol("cons+").Value, fst.CreateAcceptingState()); dfst = fst.Determinize(); data = CreateStringData("camp"); Assert.That(dfst.Transduce(data, data.Annotations.First, null, true, true, true, out result), Is.True); Assert.That(result.Output.String, Is.EqualTo("cap")); data = CreateStringData("casp"); IEnumerable <FstResult <AnnotatedStringData, int> > results; Assert.That(dfst.Transduce(data, data.Annotations.First, null, true, true, true, out results), Is.True); FstResult <AnnotatedStringData, int>[] resultsArray = results.ToArray(); Assert.That(resultsArray.Length, Is.EqualTo(2)); Assert.That(resultsArray.Select(r => r.Output.String), Is.EquivalentTo(new [] { "cas+.p", "cas.p" })); }
internal Input(FeatureStruct fs, IEnumerable <FeatureStruct> negatedFSs, int enqueueCount) { _fs = fs; _negatedFSs = new HashSet <FeatureStruct>(negatedFSs, FreezableEqualityComparer <FeatureStruct> .Default); _enqueueCount = enqueueCount; }
public void IsDeterminizable() { var featSys = new FeatureSystem { new StringFeature("A"), new StringFeature("B"), new StringFeature("C"), new StringFeature("D"), new StringFeature("E"), new StringFeature("F") }; var fst = new Fst <AnnotatedStringData, int>(_operations); fst.StartState = fst.CreateState(); State <AnnotatedStringData, int> s1 = fst.StartState.Arcs.Add(FeatureStruct.New(featSys).Feature("A").EqualTo("true").Value, FeatureStruct.New(featSys).Feature("E").EqualTo("true").Value, fst.CreateState()); State <AnnotatedStringData, int> s2 = fst.StartState.Arcs.Add(FeatureStruct.New(featSys).Feature("A").EqualTo("true").Value, FeatureStruct.New(featSys).Feature("F").EqualTo("true").Value, fst.CreateState()); State <AnnotatedStringData, int> s3 = s1.Arcs.Add(FeatureStruct.New(featSys).Feature("B").EqualTo("true").Value, FeatureStruct.New(featSys).Feature("D").EqualTo("true").Value, fst.CreateState()); s2.Arcs.Add(FeatureStruct.New(featSys).Feature("C").EqualTo("true").Value, FeatureStruct.New(featSys).Feature("D").EqualTo("true").Value, s3); State <AnnotatedStringData, int> s4 = s3.Arcs.Add(FeatureStruct.New(featSys).Feature("A").EqualTo("true").Value, FeatureStruct.New(featSys).Feature("A").EqualTo("true").Value, fst.CreateAcceptingState()); Assert.That(fst.IsDeterminizable, Is.True); s4.Arcs.Add(FeatureStruct.New(featSys).Feature("A").EqualTo("true").Value, FeatureStruct.New(featSys).Feature("A").EqualTo("true").Value, s4); Assert.That(fst.IsDeterminizable, Is.False); }
private static XElement CreateInflFeaturesElement(string name, FeatureStruct fs) { return new XElement(name, fs.GetValue<FeatureStruct>("head").ToString().Replace(",", "")); }
public void Determinize() { var featSys = new FeatureSystem { new StringFeature("A"), new StringFeature("B"), new StringFeature("C"), new StringFeature("D"), new StringFeature("E"), new StringFeature("F") }; var nfst = new Fst <AnnotatedStringData, int>(_operations); nfst.StartState = nfst.CreateState(); State <AnnotatedStringData, int> s1 = nfst.StartState.Arcs.Add(FeatureStruct.New(featSys).Feature("A").EqualTo("true").Value, FeatureStruct.New(featSys).Feature("C").EqualTo("true").Value, nfst.CreateState()); State <AnnotatedStringData, int> sa = s1.Arcs.Add(FeatureStruct.New(featSys).Feature("D").EqualTo("true").Value, FeatureStruct.New(featSys).Feature("E").EqualTo("true").Value, nfst.CreateAcceptingState()); State <AnnotatedStringData, int> s2 = nfst.StartState.Arcs.Add(FeatureStruct.New(featSys).Feature("A").EqualTo("true").Value, FeatureStruct.New(featSys).Feature("B").EqualTo("true").Value, nfst.CreateState()); State <AnnotatedStringData, int> s3 = s2.Arcs.Add(FeatureStruct.New(featSys).Value, FeatureStruct.New(featSys).Value, nfst.CreateState()); s3.Arcs.Add(FeatureStruct.New(featSys).Feature("B").EqualTo("true").Value, FeatureStruct.New(featSys).Feature("B").EqualTo("true").Value, sa); Fst <AnnotatedStringData, int> dfst; Assert.That(nfst.TryDeterminize(out dfst), Is.True); }
private void EditSoundClass() { var currentNC = _selectedSoundClass.DomainSoundClass as NaturalClass; if (currentNC != null) { var vm = new EditNaturalClassViewModel(_projectService.Project.FeatureSystem, _soundClasses.Select(nc => nc.DomainSoundClass), currentNC); if (_dialogService.ShowModalDialog(this, vm) == true) { var fs = new FeatureStruct(); fs.AddValue(CogFeatureSystem.Type, vm.Type == SoundType.Consonant ? CogFeatureSystem.ConsonantType : CogFeatureSystem.VowelType); foreach (FeatureViewModel feature in vm.ActiveFeatures) fs.AddValue(feature.DomainFeature, feature.SelectedValue.DomainSymbol); var newNaturalClass = new SoundClassViewModel(new NaturalClass(vm.Name, fs), _selectedSoundClass.Sonority); int index = _soundClasses.IndexOf(_selectedSoundClass); IsChanged = true; _soundClasses[index] = newNaturalClass; SelectedSoundClass = newNaturalClass; } } else { var currentUnc = _selectedSoundClass.DomainSoundClass as UnnaturalClass; if (currentUnc != null) { var vm = new EditUnnaturalClassViewModel(_dialogService, _projectService.Project.Segmenter, _soundClasses.Select(nc => nc.DomainSoundClass), currentUnc); if (_dialogService.ShowModalDialog(this, vm) == true) { var newUnnaturalClass = new SoundClassViewModel(new UnnaturalClass(vm.Name, vm.Segments, vm.IgnoreModifiers, _projectService.Project.Segmenter), _selectedSoundClass.Sonority); int index = _soundClasses.IndexOf(_selectedSoundClass); IsChanged = true; _soundClasses[index] = newUnnaturalClass; SelectedSoundClass = newUnnaturalClass; } } } }
public void Compose() { var featSys = new FeatureSystem { new StringFeature("value") }; var fst1 = new Fst <AnnotatedStringData, int>(_operations); fst1.StartState = fst1.CreateState(); State <AnnotatedStringData, int> s1 = fst1.StartState.Arcs.Add(FeatureStruct.New(featSys).Feature("value").EqualTo("a").Value, FeatureStruct.New(featSys).Feature("value").EqualTo("x").Value, fst1.CreateAcceptingState()); s1.Arcs.Add(FeatureStruct.New(featSys).Feature("value").EqualTo("b").Value, FeatureStruct.New(featSys).Feature("value").EqualTo("y").Value, s1); var fst2 = new Fst <AnnotatedStringData, int>(_operations); fst2.StartState = fst2.CreateAcceptingState(); fst2.StartState.Arcs.Add(FeatureStruct.New(featSys).Feature("value").EqualTo("x").Value, null, fst2.StartState); fst2.StartState.Arcs.Add(FeatureStruct.New(featSys).Feature("value").EqualTo("y").Value, FeatureStruct.New(featSys).Feature("value").EqualTo("z").Value, fst2.StartState); Fst <AnnotatedStringData, int> composedFsa = fst1.Compose(fst2); var writer = new StringWriter(); composedFsa.ToGraphViz(writer); Assert.That(writer.ToString().Replace("\r\n", "\n"), Is.EqualTo(@"digraph G { 0 [shape=""diamond"", color=""green""]; 0 -> 1 [label=""[value:\""a\""],1:ε""]; 1 [shape=""circle"", color=""red"", peripheries=""2""]; 1 -> 1 [label=""[value:\""b\""],1:([value:\""z\""],∪)""]; } ".Replace("\r\n", "\n"))); }
public override int Delta(FeatureStruct fs1, FeatureStruct fs2) { return(_scorer.Delta(fs1, fs2)); }
public void StemNames() { var any = FeatureStruct.New().Symbol(HCFeatureSystem.Segment).Value; var edSuffix = new AffixProcessRule { Name = "ed_suffix", Gloss = "1", RequiredSyntacticFeatureStruct = FeatureStruct.New(Language.SyntacticFeatureSystem).Symbol("V").Value, OutSyntacticFeatureStruct = FeatureStruct.New(Language.SyntacticFeatureSystem) .Feature(Head).EqualTo(head => head .Feature("pers").EqualTo("1")).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); var tSuffix = new AffixProcessRule { Name = "t_suffix", Gloss = "2", RequiredSyntacticFeatureStruct = FeatureStruct.New(Language.SyntacticFeatureSystem).Symbol("V").Value, OutSyntacticFeatureStruct = FeatureStruct.New(Language.SyntacticFeatureSystem) .Feature(Head).EqualTo(head => head .Feature("pers").EqualTo("2")).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); var sSuffix = new AffixProcessRule { Name = "s_suffix", Gloss = "3", RequiredSyntacticFeatureStruct = FeatureStruct.New(Language.SyntacticFeatureSystem).Symbol("V").Value, OutSyntacticFeatureStruct = FeatureStruct.New(Language.SyntacticFeatureSystem) .Feature(Head).EqualTo(head => head .Feature("pers").EqualTo("3")).Value }; sSuffix.Allomorphs.Add(new AffixProcessAllomorph { Lhs = { Pattern <Word, ShapeNode> .New("1").Annotation(any).OneOrMore.Value }, Rhs = { new CopyFromInput("1"), new InsertSegments(Table3, "+s") } }); Morphophonemic.MorphologicalRules.Add(sSuffix); var morpher = new Morpher(SpanFactory, TraceManager, Language); AssertMorphsEqual(morpher.ParseWord("sanɯd")); AssertMorphsEqual(morpher.ParseWord("sant")); AssertMorphsEqual(morpher.ParseWord("sans")); AssertMorphsEqual(morpher.ParseWord("san"), "stemname"); AssertMorphsEqual(morpher.ParseWord("sadɯd"), "stemname 1"); AssertMorphsEqual(morpher.ParseWord("sadt"), "stemname 2"); AssertMorphsEqual(morpher.ParseWord("sads")); AssertMorphsEqual(morpher.ParseWord("sad")); AssertMorphsEqual(morpher.ParseWord("sapɯd"), "stemname 1"); AssertMorphsEqual(morpher.ParseWord("sapt")); AssertMorphsEqual(morpher.ParseWord("saps"), "stemname 3"); AssertMorphsEqual(morpher.ParseWord("sap")); }