public void Apply() { var pattern = Pattern <StringData, 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 ruleSpec = new DefaultPatternRuleSpec <StringData, int>(pattern, (PatternRule <StringData, int> r, Match <StringData, int> match, out StringData output) => { 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-").Value); } output = match.Input; return(target.Span.End); }); var rule = new PatternRule <StringData, int>(SpanFactory, ruleSpec); StringData inputWord = CreateStringData("fazk"); Assert.IsTrue(rule.Apply(inputWord).Any()); }
void IPhonologicalPatternSubruleSpec.ApplyRhs(Match <Word, ShapeNode> targetMatch, Span <ShapeNode> span, VariableBindings varBindings) { ShapeNode start = null, end = null; foreach (GroupCapture <ShapeNode> gc in targetMatch.GroupCaptures) { if (start == null || gc.Span.Start.CompareTo(start) < 0) { start = gc.Span.Start; } if (end == null || gc.Span.End.CompareTo(end) > 0) { end = gc.Span.End; } } Debug.Assert(start != null && end != null); GroupCapture <ShapeNode> leftGroup = targetMatch.GroupCaptures[_leftGroupName]; GroupCapture <ShapeNode> rightGroup = targetMatch.GroupCaptures[_rightGroupName]; foreach (Tuple <ShapeNode, ShapeNode> tuple in targetMatch.Input.Shape.GetNodes(leftGroup.Span).Zip(targetMatch.Input.Shape.GetNodes(rightGroup.Span))) { if (tuple.Item1.Type() != HCFeatureSystem.Segment || tuple.Item2.Type() != HCFeatureSystem.Segment) { continue; } FeatureStruct fs = tuple.Item1.Annotation.FeatureStruct.DeepClone(); tuple.Item1.Annotation.FeatureStruct.Union(tuple.Item2.Annotation.FeatureStruct); tuple.Item1.SetDirty(true); tuple.Item2.Annotation.FeatureStruct.Union(fs); tuple.Item2.SetDirty(true); } }
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 override IEnumerable <Tuple <ShapeNode, ShapeNode> > Apply(Match <Word, ShapeNode> match, Word output) { var mappings = new List <Tuple <ShapeNode, ShapeNode> >(); GroupCapture <ShapeNode> inputGroup = match.GroupCaptures[PartName]; if (inputGroup.Success) { foreach (ShapeNode inputNode in GetSkippedOptionalNodes(match.Input.Shape, inputGroup.Span).Concat(match.Input.Shape.GetNodes(inputGroup.Span))) { ShapeNode outputNode = inputNode.DeepClone(); output.Shape.Add(outputNode); mappings.Add(Tuple.Create(inputNode, outputNode)); } } return(mappings); }
public override IEnumerable <Tuple <ShapeNode, ShapeNode> > Apply(Match <Word, ShapeNode> match, Word output) { var mappings = new List <Tuple <ShapeNode, ShapeNode> >(); GroupCapture <ShapeNode> inputGroup = match.GroupCaptures[PartName]; foreach (ShapeNode inputNode in GetSkippedOptionalNodes(match.Input.Shape, inputGroup.Span).Concat(match.Input.Shape.GetNodes(inputGroup.Span))) { ShapeNode outputNode = inputNode.DeepClone(); if (outputNode.Annotation.Type() == (FeatureSymbol)_simpleCtxt.FeatureStruct.GetValue(HCFeatureSystem.Type)) { outputNode.Annotation.FeatureStruct.PriorityUnion(_simpleCtxt.FeatureStruct, match.VariableBindings); } output.Shape.Add(outputNode); mappings.Add(Tuple.Create(inputNode, outputNode)); } return(mappings); }
public void ApplyRhs(Match <Word, ShapeNode> targetMatch, Range <ShapeNode> range, VariableBindings varBindings) { ShapeNode start = null, end = null; foreach (GroupCapture <ShapeNode> gc in targetMatch.GroupCaptures) { if (start == null || gc.Range.Start.CompareTo(start) < 0) { start = gc.Range.Start; } if (end == null || gc.Range.End.CompareTo(end) > 0) { end = gc.Range.End; } } Debug.Assert(start != null && end != null); var morphs = targetMatch.Input.Morphs.Where(ann => ann.Range.Overlaps(start, end)) .Select(ann => new { Annotation = ann, Children = ann.Children.ToList() }).ToArray(); foreach (var morph in morphs) { morph.Annotation.Remove(); } GroupCapture <ShapeNode> leftGroup = targetMatch.GroupCaptures[_leftGroupName]; GroupCapture <ShapeNode> rightGroup = targetMatch.GroupCaptures[_rightGroupName]; ShapeNode beforeRightGroup = rightGroup.Range.Start.Prev; MoveNodesAfter(targetMatch.Input.Shape, leftGroup.Range.End, rightGroup.Range); MoveNodesAfter(targetMatch.Input.Shape, beforeRightGroup, leftGroup.Range); foreach (var morph in morphs) { Annotation <ShapeNode>[] children = morph.Children.OrderBy(ann => ann.Range).ToArray(); var newMorphAnn = new Annotation <ShapeNode>(Range <ShapeNode> .Create(children[0].Range.Start, children[children.Length - 1].Range.Start), morph.Annotation.FeatureStruct); newMorphAnn.Children.AddRange(morph.Children); targetMatch.Input.Annotations.Add(newMorphAnn, false); } }
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); }