Example #1
0
		/// <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;
		}
Example #2
0
		/// <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;
				}
			}
Example #4
0
		/// <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);
		}
Example #5
0
		/// <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;
						}
					}
				}
			}
		}
Example #6
0
		/// <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);
				}
			}
		}
Example #7
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);
 }
			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;
			}
Example #9
0
 protected abstract void UnapplyFeatures(Segment seg, VariableValues instantiatedVars);
Example #10
0
        /// <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;
			}
Example #17
0
 protected abstract Segment ApplyInsertionFeatures(VariableValues instantiatedVars);
Example #18
0
			/// <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;
			}
Example #19
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);
		}
Example #20
0
		/// <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;
		}
Example #21
0
		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);
		}
Example #22
0
		/// <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);
			}
		}
Example #23
0
		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);
		}
Example #24
0
		/// <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);
		}
Example #25
0
		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;
				}
			}
		}
Example #27
0
		/// <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;
			}
Example #29
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;
					}
				}
			}
Example #31
0
		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;
			}
Example #33
0
		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;
			}
Example #35
0
		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;
		}
Example #37
0
		/// <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;
		}
Example #38
0
			/// <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;
			}
Example #39
0
        /// <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);
        }