/// <summary> /// Gets a valid binding between the specified variables and the feature values /// currently set on the specified segment. It adds the variable values to the varFeats of /// instantiated variables. /// </summary> /// <param name="variables">The variables.</param> /// <param name="seg">The segment.</param> /// <param name="instantiatedVars">The instantiated variables.</param> /// <returns><c>true</c> if a valid binding was found, otherwise <c>false</c></returns> public bool GetBinding(IDictionary<string, bool> variables, Segment seg, VariableValues instantiatedVars) { foreach (KeyValuePair<string, bool> varPolarity in variables) { if (!GetBinding(varPolarity.Key, varPolarity.Value, seg, instantiatedVars)) return false; } return true; }
/// <summary> /// Gets a valid binding between the specified variable and the feature values /// currently set on the specified segment. It adds the variable value to the varFeats of /// instantiated variables. /// </summary> /// <param name="variable">The variable.</param> /// <param name="polarity">The variable polarity.</param> /// <param name="seg">The segment.</param> /// <param name="instantiatedVars">The instantiated variables.</param> /// <returns><c>true</c> if a valid binding was found, otherwise <c>false</c></returns> public bool GetBinding(string variable, bool polarity, Segment seg, VariableValues instantiatedVars) { bool match = false; foreach (FeatureValue value in GetVarFeatValue(variable, polarity, instantiatedVars)) { if (seg.FeatureValues.Get(value)) { instantiatedVars.Add(variable, value); match = true; break; } } return match; }
/// <summary> /// Applies the RHS to the matched segments. /// </summary> /// <param name="dir">The direction.</param> /// <param name="match">The matched segments.</param> /// <param name="instantiatedVars">The instantiated variables.</param> public void ApplyRHS(Direction dir, IList<PhoneticShapeNode> match, VariableValues instantiatedVars) { switch (Type) { case ChangeType.FEATURE: int i = 0; for (PhoneticPatternNode pseqNode = m_rhs.GetFirst(dir); pseqNode != null; pseqNode = pseqNode.GetNext(dir)) { switch (pseqNode.Type) { case PhoneticPatternNode.NodeType.SIMP_CTXT: SimpleContext ctxt = pseqNode as SimpleContext; // match[i] should be a segment, should I check that here? while (match[i].Type == PhoneticShapeNode.NodeType.BOUNDARY) i++; Segment seg = match[i] as Segment; ctxt.Apply(seg, instantiatedVars); // marked the segment as altered seg.IsClean = false; break; case PhoneticPatternNode.NodeType.BDRY_CTXT: // boundaries should match, should I check that here? break; } i++; } break; case ChangeType.NARROW: ApplyInsertion(dir, match, instantiatedVars); // remove matching segments foreach (PhoneticShapeNode node in match) node.Remove(); break; case ChangeType.EPENTHESIS: // insert new segments or boundaries ApplyInsertion(dir, match, instantiatedVars); break; } }
/// <summary> /// Replaces all of the values with the specified values. /// </summary> /// <param name="varValues">The variable values.</param> public void ReplaceValues(VariableValues varValues) { m_values.Clear(); foreach (KeyValuePair<string, List<FeatureValue>> kvp in varValues.m_values) m_values.Add(kvp.Key, kvp.Value); }
/// <summary> /// Enumerates thru all of the possible values for the specified variable. /// </summary> /// <param name="variableName">The variable.</param> /// <param name="polarity">The variable polarity.</param> /// <param name="instantiatedVars">The instantiated variables.</param> /// <returns>An enumerable of feature values.</returns> IEnumerable<FeatureValue> GetVarFeatValue(string variableName, bool polarity, VariableValues instantiatedVars) { Feature feature = m_varFeatures[variableName]; ICollection<FeatureValue> varValues = instantiatedVars.GetValues(variableName); if (varValues.Count > 0) { // variable is instantiated, so only check already instantiated values foreach (FeatureValue value in GetCurVarFeatValue(feature, varValues, polarity)) yield return value; } else { foreach (FeatureValue value in feature.PossibleValues) { // if polarity is true, then values must be the same, otherwise they must be different if (polarity) { yield return value; } else { foreach (FeatureValue value2 in feature.PossibleValues) { if (value2 != value) yield return value2; } } } } }
/// <summary> /// Applies the specified variables that occur in the instantiated variables to the specified feature bundle. /// </summary> /// <param name="fb">The feature bundle.</param> /// <param name="variables">The variables.</param> /// <param name="instantiatedVars">The instantiated variables.</param> public void ApplyCurrent(FeatureBundle fb, IDictionary<string, bool> variables, VariableValues instantiatedVars) { foreach (KeyValuePair<string, bool> varPolarity in variables) { Feature feature = m_varFeatures[varPolarity.Key]; ICollection<FeatureValue> varValues = instantiatedVars.GetValues(varPolarity.Key); if (varValues.Count > 0) { foreach (FeatureValue value in GetCurVarFeatValue(feature, varValues, varPolarity.Value)) fb.Set(value, true); } } }
protected override void UnapplyFeatures(Segment seg, VariableValues instantiatedVars) { // set the context's anti features on the segment seg.FeatureValues.Apply(m_antiFeatureValues, true); m_alphaVars.Apply(seg.FeatureValues, m_antiVariables, instantiatedVars, true); }
public bool MatchEnvEmpty(PhoneticShapeNode node, Direction dir, ModeType mode, VariableValues instantiatedVars) { PhoneticShapeNode leftNode = null; PhoneticShapeNode rightNode = null; switch (dir) { case Direction.LEFT: rightNode = node; leftNode = node.GetNext(Direction.LEFT); break; case Direction.RIGHT: rightNode = node.GetNext(Direction.RIGHT); leftNode = node; break; } // in case this is an epenthesis rule, we want to ensure that the segment to the right // of where we're going to do the epenthesis is not a boundary marker, unless the // environment calls for one. if (mode == ModeType.SYNTHESIS && m_env.RightEnvironment != null && m_env.RightEnvironment.Count > 0) { if (rightNode.Type == PhoneticShapeNode.NodeType.BOUNDARY && m_env.RightEnvironment.First.Type != PhoneticPatternNode.NodeType.BDRY_CTXT) return false; } // there is a small difference between legacy HC and HC.NET in matching environments when the // analysis target is empty and one of the environments is empty. In this case, legacy HC does // not try to skip the initial optional segments when matching the right environment. I think // this will cause HC.NET to overproduce a little more during analysis, which isn't that big of a // deal if (!m_env.IsMatch(leftNode, rightNode, mode, instantiatedVars)) return false; // remove ambiguous variables instantiatedVars.RemoveAmbiguousVariables(); return true; }
protected abstract void UnapplyFeatures(Segment seg, VariableValues instantiatedVars);
/// <summary> /// Checks if the specified phonetic shape node matches this simple context. /// </summary> /// <param name="node">The phonetic shape node.</param> /// <param name="dir">The direction.</param> /// <param name="mode">The mode.</param> /// <param name="instantiatedVars">The instantiated variables.</param> /// <returns>All matches.</returns> internal override IList <Match> Match(PhoneticShapeNode node, Direction dir, ModeType mode, VariableValues instantiatedVars) { switch (node.Type) { case PhoneticShapeNode.NodeType.BOUNDARY: // only check boundaries in synthesis mode when the pattern is a target, // otherwise skip if (mode == ModeType.SYNTHESIS) { if (Owner.IsTarget) { return(new List <Match>()); } else { IList <Match> bdryMatches = Match(node.GetNext(dir), dir, mode, instantiatedVars); foreach (Match match in bdryMatches) { match.Add(node, m_partition); } return(bdryMatches); } } else { return(Match(node.GetNext(dir), dir, mode, instantiatedVars)); } case PhoneticShapeNode.NodeType.MARGIN: Margin margin = node as Margin; if (dir == margin.MarginType) { // we are at the end of the shape, so no match return(new List <Match>()); } else { return(Match(node.GetNext(dir), dir, mode, instantiatedVars)); } case PhoneticShapeNode.NodeType.SEGMENT: Segment seg = node as Segment; if (mode == ModeType.SYNTHESIS && Owner.IsTarget) { // check segment to see if it has already been altered by another // subrule, only matters for simultaneously applying rules if (!seg.IsClean) { return(new List <Match>()); } } VariableValues tempVars = instantiatedVars.Clone(); if (m_featSys.HasFeatures) { if (!IsFeatureMatch(seg, tempVars, mode)) { return(new List <Match>()); } } else { if (!IsSegmentMatch(seg)) { return(new List <Match>()); } } // move to the next node IList <Match> segMatches = MatchNext(node, dir, mode, tempVars); foreach (Match match in segMatches) { match.Add(node, m_partition); } return(segMatches); } return(new List <Match>()); }
/// <summary> /// Copy constructor. /// </summary> /// <param name="varValues">The variable values.</param> public VariableValues(VariableValues varValues) { m_values = new Dictionary <string, List <FeatureValue> >(varValues.m_values); }
/// <summary> /// Enumerates thru all of the possible values for the specified variable. /// </summary> /// <param name="variableName">The variable.</param> /// <param name="polarity">The variable polarity.</param> /// <param name="instantiatedVars">The instantiated variables.</param> /// <returns>An enumerable of feature values.</returns> IEnumerable <FeatureValue> GetVarFeatValue(string variableName, bool polarity, VariableValues instantiatedVars) { Feature feature = m_varFeatures[variableName]; ICollection <FeatureValue> varValues = instantiatedVars.GetValues(variableName); if (varValues.Count > 0) { // variable is instantiated, so only check already instantiated values foreach (FeatureValue value in GetCurVarFeatValue(feature, varValues, polarity)) { yield return(value); } } else { foreach (FeatureValue value in feature.PossibleValues) { // if polarity is true, then values must be the same, otherwise they must be different if (polarity) { yield return(value); } else { foreach (FeatureValue value2 in feature.PossibleValues) { if (value2 != value) { yield return(value2); } } } } } }
/// <summary> /// Applies the specified variables that occur in the instantiated variables to the specified feature bundle. /// </summary> /// <param name="fb">The feature bundle.</param> /// <param name="variables">The variables.</param> /// <param name="instantiatedVars">The instantiated variables.</param> public void ApplyCurrent(FeatureBundle fb, IDictionary <string, bool> variables, VariableValues instantiatedVars) { foreach (KeyValuePair <string, bool> varPolarity in variables) { Feature feature = m_varFeatures[varPolarity.Key]; ICollection <FeatureValue> varValues = instantiatedVars.GetValues(varPolarity.Key); if (varValues.Count > 0) { foreach (FeatureValue value in GetCurVarFeatValue(feature, varValues, varPolarity.Value)) { fb.Set(value, true); } } } }
/// <summary> /// Gets all valid bindings between the specified variables and the feature values /// currently set on the specified segment. It adds the variable values to the varFeats of /// instantiated variables. /// </summary> /// <param name="variables">The variables.</param> /// <param name="seg">The segment.</param> /// <param name="instantiatedVars">The instantiated variables.</param> /// <returns><c>true</c> if a valid binding was found, otherwise <c>false</c></returns> public bool GetAllBindings(IDictionary <string, bool> variables, Segment seg, VariableValues instantiatedVars) { foreach (KeyValuePair <string, bool> varPolarity in variables) { List <FeatureValue> valuesToAdd = new List <FeatureValue>(); foreach (FeatureValue value in GetVarFeatValue(varPolarity.Key, varPolarity.Value, instantiatedVars)) { if (seg.FeatureValues.Get(value)) { valuesToAdd.Add(value); } } if (valuesToAdd.Count == 0) { return(false); } foreach (FeatureValue value in valuesToAdd) { instantiatedVars.Add(varPolarity.Key, value); } } return(true); }
void UnapplyRHS(Direction dir, IList<PhoneticShapeNode> match, VariableValues instantiatedVars) { switch (Type) { case ChangeType.FEATURE: int i = 0; // if there are no phonetic features, unapply using the LHS, since we are simply replacing PhoneticPattern unappPattern = m_rule.Morpher.PhoneticFeatureSystem.HasFeatures ? m_analysisTarget : m_rule.m_lhs; for (PhoneticPatternNode pseqNode = unappPattern.GetFirst(dir); pseqNode != null; pseqNode = pseqNode.GetNext(dir)) { switch (pseqNode.Type) { case PhoneticPatternNode.NodeType.SIMP_CTXT: SimpleContext ctxt = pseqNode as SimpleContext; // match[i] should be a segment, should I check that here? Segment seg = match[i] as Segment; ctxt.Unapply(seg, instantiatedVars); break; case PhoneticPatternNode.NodeType.BDRY_CTXT: // skip boundaries continue; } i++; } break; case ChangeType.EPENTHESIS: // do not remove epenthesized segments, since it is possible that they will not // be epenthesized during synthesis, we just mark them as optional foreach (PhoneticShapeNode node in match) node.IsOptional = true; break; } }
bool MatchAnalysisTarget(PhoneticShapeNode node, Direction dir, out Match match) { // check analysis target IList<Match> matches; VariableValues instantiatedVars = new VariableValues(m_rule.m_alphaVars); if (!m_analysisTarget.IsMatch(node, dir, ModeType.ANALYSIS, instantiatedVars, out matches)) { match = null; return false; } match = matches[0]; // check vacuous unapplication // even if the subrule matches, we do not want to successfully unapply if no real changes are // going to be made to the phonetic shape if (!CheckVacuousUnapplication(match, dir)) { match = null; return false; } // finally, check environment if (!MatchEnvNonempty(match.EntireMatch, dir, ModeType.ANALYSIS, match.VariableValues)) { match = null; return false; } return true; }
protected abstract Segment ApplyInsertionFeatures(VariableValues instantiatedVars);
/// <summary> /// Unapplies this subrule to the input word analysis. /// </summary> /// <param name="input">The input word analysis.</param> /// <param name="output">The output word analyses.</param> /// <returns><c>true</c> if the subrule was successfully unapplied, otherwise <c>false</c></returns> public bool Unapply(WordAnalysis input, out ICollection<WordAnalysis> output) { VariableValues instantiatedVars = new VariableValues(m_alphaVars); IList<Match> matches; m_transform.RHSTemplate.IsMatch(input.Shape.First, Direction.RIGHT, ModeType.ANALYSIS, instantiatedVars, out matches); List<WordAnalysis> outputList = new List<WordAnalysis>(); output = outputList; foreach (Match match in matches) { PhoneticShape headShape; PhoneticShape nonHeadShape; UnapplyRHS(match, out headShape, out nonHeadShape); // for computational complexity reasons, we ensure that the non-head is a root, otherwise we assume it is not // a valid analysis and throw it away foreach (LexEntry.RootAllomorph allo in Morpheme.Stratum.SearchEntries(nonHeadShape)) { // check to see if this is a duplicate of another output analysis, this is not strictly necessary, but // it helps to reduce the search space bool add = true; for (int i = 0; i < output.Count; i++) { if (headShape.Duplicates(outputList[i].Shape) && allo == outputList[i].NonHead.RootAllomorph) { if (headShape.Count > outputList[i].Shape.Count) // if this is a duplicate and it is longer, then use this analysis and remove the previous one outputList.RemoveAt(i); else // if it is shorter, then do not add it to the output list add = false; break; } } if (add) { WordAnalysis wa = input.Clone(); wa.Shape = headShape; wa.NonHead = new WordAnalysis(nonHeadShape, wa.Stratum, null); wa.NonHead.RootAllomorph = allo; output.Add(wa); } } } return outputList.Count > 0; }
protected override void UnapplyFeatures(Segment seg, VariableValues instantiatedVars) { // set the context's anti features on the segment seg.FeatureValues.Apply(m_antiFeatureValues, true); m_alphaVars.Apply(seg.FeatureValues, m_antiVariables, instantiatedVars, true); }
/// <summary> /// Gets all valid bindings between the specified variables and the feature values /// currently set on the specified segment. It adds the variable values to the varFeats of /// instantiated variables. /// </summary> /// <param name="variables">The variables.</param> /// <param name="seg">The segment.</param> /// <param name="instantiatedVars">The instantiated variables.</param> /// <returns><c>true</c> if a valid binding was found, otherwise <c>false</c></returns> public bool GetAllBindings(IDictionary<string, bool> variables, Segment seg, VariableValues instantiatedVars) { foreach (KeyValuePair<string, bool> varPolarity in variables) { List<FeatureValue> valuesToAdd = new List<FeatureValue>(); foreach (FeatureValue value in GetVarFeatValue(varPolarity.Key, varPolarity.Value, instantiatedVars)) { if (seg.FeatureValues.Get(value)) valuesToAdd.Add(value); } if (valuesToAdd.Count == 0) return false; foreach (FeatureValue value in valuesToAdd) instantiatedVars.Add(varPolarity.Key, value); } return true; }
protected override Segment ApplyInsertionFeatures(VariableValues instantiatedVars) { // copy over the context's features FeatureBundle feats = new FeatureBundle(m_featureValues); // apply the context's variable features to the segment's features m_alphaVars.Apply(feats, m_variables, instantiatedVars, true); return new Segment(ToString(), feats); }
/// <summary> /// Applies the specified variables to the specified feature bundle. /// </summary> /// <param name="fb">The feature bundle.</param> /// <param name="variables">The variables.</param> /// <param name="instantiatedVars">The instantiated variables.</param> /// <param name="val">if <c>true</c> the feature bundle values will be set, otherwise they will be unset.</param> public void Apply(FeatureBundle fb, IDictionary<string, bool> variables, VariableValues instantiatedVars, bool val) { foreach (KeyValuePair<string, bool> varPolarity in variables) { foreach (FeatureValue value in GetVarFeatValue(varPolarity.Key, varPolarity.Value, instantiatedVars)) fb.Set(value, val); } }
protected override Segment UnapplyDeletionFeatures(VariableValues instantiatedVars) { // in analysis mode, we set all of the feature values FeatureBundle feats = new FeatureBundle(true, m_featSys); // then unset each anti feature feats.Apply(m_antiFeatureValues, false); m_alphaVars.ApplyCurrent(feats, m_antiVariables, instantiatedVars); return new Segment(ToString(), feats); }
/// <summary> /// Copy constructor. /// </summary> /// <param name="varValues">The variable values.</param> public VariableValues(VariableValues varValues) { m_values = new Dictionary<string, List<FeatureValue>>(varValues.m_values); }
public override bool IsUnapplicationVacuous(Segment seg, VariableValues instantiatedVars) { if (base.IsUnapplicationVacuous(seg, instantiatedVars)) return true; // check if the context's anti variables have already been set if (!m_alphaVars.GetBinding(m_antiVariables, seg, instantiatedVars.Clone())) return true; return false; }
void Untruncate(PhoneticPattern lhs, PhoneticShape output, bool optional, VariableValues instantiatedVars) { // create segments from the LHS partition pattern and append them to the output foreach (PhoneticPatternNode node in lhs) { switch (node.Type) { case PhoneticPatternNode.NodeType.SIMP_CTXT: SimpleContext ctxt = node as SimpleContext; Segment newSeg = ctxt.UnapplyDeletion(instantiatedVars); newSeg.IsOptional = optional; output.Add(newSeg); break; case PhoneticPatternNode.NodeType.PATTERN: NestedPhoneticPattern nestedPattern = node as NestedPhoneticPattern; // untruncate nested partitions the maximum number of times it can occur, // marking any segments that occur after the minimum number of occurrences // as optional for (int j = 0; j < nestedPattern.MaxOccur; j++) Untruncate(nestedPattern.Pattern, output, j >= nestedPattern.MinOccur, instantiatedVars); break; case PhoneticPatternNode.NodeType.BDRY_CTXT: // skip boundaries break; } } }
/// <summary> /// Checks if the specified phonetic shape node matches this boundary context. /// </summary> /// <param name="node">The phonetic shape node.</param> /// <param name="dir">The direction.</param> /// <param name="mode">The mode.</param> /// <param name="instantiatedVars">The instantiated variables.</param> /// <returns>All matches.</returns> internal override IList<Match> Match(PhoneticShapeNode node, Direction dir, ModeType mode, VariableValues instantiatedVars) { // only match boundaries in synthesis mode if (mode == ModeType.SYNTHESIS) { switch (node.Type) { case PhoneticShapeNode.NodeType.BOUNDARY: Boundary bdry = node as Boundary; // check if string representations match if (m_bdryDef.StrRep != bdry.BoundaryDefinition.StrRep) return new List<Match>(); // move to next node IList<Match> matches = MatchNext(node, dir, mode, instantiatedVars); foreach (Match match in matches) match.Add(node, m_partition); return matches; case PhoneticShapeNode.NodeType.MARGIN: Margin margin = node as Margin; if (dir == margin.MarginType) // we are at the end of the phonetic shape, so it does not match return new List<Match>(); else return Match(GetNextShapeNode(node, dir), dir, mode, instantiatedVars); } return new List<Match>(); } else { PhoneticPatternNode n = GetNext(dir); if (n == null) { // this was the last node in the pattern, so we have a match List<Match> matches = new List<Match>(); matches.Add(new Match(Owner, instantiatedVars)); return matches; } else { return n.Match(node, dir, mode, instantiatedVars); } } }
/// <summary> /// Unapplies this subrule to the input word analysis. /// </summary> /// <param name="input">The input word analysis.</param> /// <param name="output">The output word analyses.</param> /// <returns><c>true</c> if the subrule was successfully unapplied, otherwise <c>false</c></returns> public bool Unapply(WordAnalysis input, out ICollection<WordAnalysis> output) { VariableValues instantiatedVars = new VariableValues(m_alphaVars); IList<Match> matches; m_transform.RHSTemplate.IsMatch(input.Shape.First, Direction.RIGHT, ModeType.ANALYSIS, instantiatedVars, out matches); List<WordAnalysis> outputList = new List<WordAnalysis>(); output = outputList; foreach (Match match in matches) { PhoneticShape shape = UnapplyRHS(match); if (shape.Count > 2) { // check to see if this is a duplicate of another output analysis, this is not strictly necessary, but // it helps to reduce the search space bool add = true; for (int i = 0; i < output.Count; i++) { if (shape.Duplicates(outputList[i].Shape)) { if (shape.Count > outputList[i].Shape.Count) // if this is a duplicate and it is longer, then use this analysis and remove the previous one outputList.RemoveAt(i); else // if it is shorter, then do not add it to the output list add = false; break; } } if (add) { WordAnalysis wa = input.Clone(); wa.Shape = shape; output.Add(wa); } } } return outputList.Count > 0; }
protected override void ApplyFeatures(Segment seg, VariableValues instantiatedVars) { seg.SegmentDefinition = m_segDef; seg.FeatureValues.SetAll(false); seg.FeatureValues.Apply(m_featureValues, true); }
void ApplyInsertion(Direction dir, IList<PhoneticShapeNode> match, VariableValues instantiatedVars) { PhoneticShapeNode cur = match[match.Count - 1]; for (PhoneticPatternNode pseqNode = m_rhs.GetFirst(dir); pseqNode != null; pseqNode = pseqNode.GetNext(dir)) { PhoneticShapeNode newNode = null; switch (pseqNode.Type) { case PhoneticPatternNode.NodeType.SIMP_CTXT: SimpleContext ctxt = pseqNode as SimpleContext; newNode = ctxt.ApplyInsertion(instantiatedVars); break; case PhoneticPatternNode.NodeType.BDRY_CTXT: newNode = new Boundary(pseqNode as BoundaryContext); break; } if (newNode != null) { try { cur.Insert(newNode, dir); } catch (InvalidOperationException ioe) { MorphException me = new MorphException(MorphException.MorphErrorType.TOO_MANY_SEGS, m_rule.Morpher, string.Format(HCStrings.kstidTooManySegs, m_rule.ID), ioe); me.Data["rule"] = m_rule.ID; throw me; } cur = newNode; } } }
protected override void UnapplyFeatures(Segment seg, VariableValues instantiatedVars) { seg.FeatureValues.Apply(m_antiFeatureValues, true); }
bool FindNextMatchRHS(PhoneticShapeNode node, Direction dir, out Match match) { for (; node != node.Owner.GetLast(dir); node = node.GetNext(dir)) { if (node.Type == PhoneticShapeNode.NodeType.BOUNDARY) continue; if (m_analysisTarget.Count == 0) { // if the analysis target is empty (deletion rule), // just check environment VariableValues instantiatedVars = new VariableValues(m_rule.m_alphaVars); if (MatchEnvEmpty(node, dir, ModeType.ANALYSIS, instantiatedVars)) { match = new Match(instantiatedVars); match.Add(node); return true; } } else { // analysis target is non-empty, check everything if (MatchAnalysisTarget(node, dir, out match)) return true; } } match = null; return false; }
protected override Segment ApplyInsertionFeatures(VariableValues instantiatedVars) { return new Segment(m_segDef, m_featureValues.Clone()); }
public bool MatchEnvNonempty(IList<PhoneticShapeNode> match, Direction dir, ModeType mode, VariableValues instantiatedVars) { PhoneticShapeNode leftNode = null; PhoneticShapeNode rightNode = null; switch (dir) { case Direction.LEFT: rightNode = match[0].GetNext(Direction.RIGHT); leftNode = match[match.Count - 1].GetNext(Direction.LEFT); break; case Direction.RIGHT: rightNode = match[match.Count - 1].GetNext(Direction.RIGHT); leftNode = match[0].GetNext(Direction.LEFT); break; } if (!m_env.IsMatch(leftNode, rightNode, mode, instantiatedVars)) return false; return true; }
protected override Segment UnapplyDeletionFeatures(VariableValues instantiatedVars) { FeatureBundle feats = new FeatureBundle(false, m_featSys); feats.AddAntiValues(m_antiFeatureValues); return new Segment(m_segDef, feats); }
bool FindNextMatchLHS(PhoneticShapeNode node, Direction dir, out Match match) { for (; node != node.Owner.GetLast(dir); node = node.GetNext(dir)) { VariableValues instantiatedVars = new VariableValues(m_alphaVars); if (m_lhs.Count == 0) { // epenthesis rules always match the LHS match = new Match(instantiatedVars); match.Add(node); return true; } else { IList<Match> matches; if (m_lhs.IsMatch(node, dir, ModeType.SYNTHESIS, instantiatedVars, out matches)) { match = matches[0]; return true; } } } match = null; return false; }
/// <summary> /// Gets all valid bindings between the specified variables and the feature values /// currently set on the specified segment. It adds the variable values to the varFeats of /// instantiated variables. /// </summary> /// <param name="variables">The variables.</param> /// <param name="seg">The segment.</param> /// <param name="instantiatedVars">The instantiated variables.</param> /// <returns><c>true</c> if a valid binding was found, otherwise <c>false</c></returns> public bool GetAllBindings(IDictionary<string, bool> variables, Segment seg, VariableValues instantiatedVars) { foreach (KeyValuePair<string, bool> varPolarity in variables) { bool match = false; foreach (FeatureValue value in GetVarFeatValue(varPolarity.Key, varPolarity.Value, instantiatedVars)) { if (seg.FeatureValues.Get(value)) { instantiatedVars.Add(varPolarity.Key, value); match = true; } } if (!match) return false; } return true; }
/// <summary> /// Applies this subrule to the specified word synthesis. /// </summary> /// <param name="input">The input word synthesis.</param> /// <param name="output">The output word synthesis.</param> /// <returns><c>true</c> if the subrule was successfully applied, otherwise <c>false</c></returns> public bool Apply(WordSynthesis input, out WordSynthesis output) { output = null; // check MPR features if ((m_requiredMPRFeatures != null && m_requiredMPRFeatures.Count > 0 && !m_requiredMPRFeatures.IsMatch(input.MPRFeatures)) || (m_excludedMPRFeatures != null && m_excludedMPRFeatures.Count > 0 && m_excludedMPRFeatures.IsMatch(input.MPRFeatures))) return false; VariableValues instantiatedVars = new VariableValues(m_alphaVars); IList<Match> headMatches, nonHeadMatches; if (m_headLhsTemp.IsMatch(input.Shape.First, Direction.RIGHT, ModeType.SYNTHESIS, instantiatedVars, out headMatches) && m_nonHeadLhsTemp.IsMatch(input.NonHead.Shape.First, Direction.RIGHT, ModeType.SYNTHESIS, instantiatedVars, out nonHeadMatches)) { output = input.Clone(); ApplyRHS(headMatches[0], nonHeadMatches[0], input, output); if (m_outputMPRFeatures != null) output.MPRFeatures.AddOutput(m_outputMPRFeatures); return true; } return false; }
/// <summary> /// Gets all valid bindings between the specified variables and the feature values /// currently set on the specified segment. It adds the variable values to the varFeats of /// instantiated variables. /// </summary> /// <param name="variables">The variables.</param> /// <param name="seg">The segment.</param> /// <param name="instantiatedVars">The instantiated variables.</param> /// <returns><c>true</c> if a valid binding was found, otherwise <c>false</c></returns> public bool GetAllBindings(IDictionary <string, bool> variables, Segment seg, VariableValues instantiatedVars) { foreach (KeyValuePair <string, bool> varPolarity in variables) { bool match = false; foreach (FeatureValue value in GetVarFeatValue(varPolarity.Key, varPolarity.Value, instantiatedVars)) { if (seg.FeatureValues.Get(value)) { instantiatedVars.Add(varPolarity.Key, value); match = true; } } if (!match) { return(false); } } return(true); }