Пример #1
0
			/// <summary>
			/// Initializes a new instance of the <see cref="Subrule"/> class.
			/// </summary>
			/// <param name="rhs">The RHS.</param>
			/// <param name="env">The environment.</param>
			/// <param name="rule">The phonological rule.</param>
			/// <exception cref="System.ArgumentException">Thrown when the size of the RHS is greater than the
			/// size of the specified rule's LHS and the LHS's size is greater than 1. A standard phonological
			/// rule does not currently support this type of widening.</exception>
			public Subrule(PhoneticPattern rhs, Environment env, StandardPhonologicalRule rule)
			{
				m_rhs = rhs;
				m_env = env;
				m_rule = rule;

				switch (Type)
				{
					case ChangeType.NARROW:
					case ChangeType.EPENTHESIS:
						// analysis target is a copy of the RHS, because there is no LHS
						m_analysisTarget = m_rhs.Clone();
						break;

					case ChangeType.WIDEN:
						// before generating the analysis we must extend the length of the LHS
						// to match the length of the RHS
						PhoneticPattern lhs = m_rule.m_lhs.Clone();
						while (lhs.Count != m_rhs.Count)
							lhs.Add(lhs.First.Clone());
						m_analysisTarget = m_rhs.Combine(lhs);
						break;

					case ChangeType.FEATURE:
						m_analysisTarget = m_rhs.Combine(m_rule.m_lhs);
						break;

					case ChangeType.UNKNOWN:
						throw new ArgumentException(HCStrings.kstidInvalidSubruleType, "rhs");
				}
			}
Пример #2
0
			/// <summary>
			/// Initializes a new instance of the <see cref="Subrule"/> class.
			/// </summary>
			/// <param name="id">The id.</param>
			/// <param name="desc">The description.</param>
			/// <param name="morpher">The morpher.</param>
			/// <param name="headLhs">The head LHS.</param>
			/// <param name="nonHeadLhs">The non-head LHS.</param>
			/// <param name="rhs">The RHS.</param>
			/// <param name="alphaVars">The alpha variables.</param>
			public Subrule(string id, string desc, Morpher morpher, IEnumerable<PhoneticPattern> headLhs,
				IEnumerable<PhoneticPattern> nonHeadLhs, IEnumerable<MorphologicalOutput> rhs, AlphaVariables alphaVars)
				: base (id, desc, morpher)
			{
				m_alphaVars = alphaVars;

				List<PhoneticPattern> lhs = new List<PhoneticPattern>();
				lhs.AddRange(headLhs);
				lhs.AddRange(nonHeadLhs);

				m_transform = new MorphologicalTransform(lhs, rhs, MorphologicalTransform.RedupMorphType.IMPLICIT);

				// the LHS template is generated by simply concatenating all of the
				// LHS partitions; it matches the entire word, so we check for both the
				// left and right margins.
				m_headLhsTemp = new PhoneticPattern();
				m_headLhsTemp.Add(new MarginContext(Direction.LEFT));
				int partition = 0;
				foreach (PhoneticPattern pat in headLhs)
					m_headLhsTemp.AddPartition(pat, partition++);
				m_headLhsTemp.Add(new MarginContext(Direction.RIGHT));

				m_firstNonHeadPartition = partition;
				m_nonHeadLhsTemp = new PhoneticPattern();
				m_nonHeadLhsTemp.Add(new MarginContext(Direction.LEFT));
				foreach (PhoneticPattern pat in nonHeadLhs)
					m_nonHeadLhsTemp.AddPartition(pat, partition++);
				m_nonHeadLhsTemp.Add(new MarginContext(Direction.RIGHT));
			}
			/// <summary>
			/// Initializes a new instance of the <see cref="Subrule"/> class.
			/// </summary>
			/// <param name="id">The id.</param>
			/// <param name="desc">The description.</param>
			/// <param name="morpher">The morpher.</param>
			/// <param name="lhs">The LHS.</param>
			/// <param name="rhs">The RHS.</param>
			/// <param name="alphaVars">The alpha variables.</param>
			/// <param name="redupMorphType">The full reduplication type.</param>
			public Subrule(string id, string desc, Morpher morpher, IEnumerable<PhoneticPattern> lhs,
				IEnumerable<MorphologicalOutput> rhs, AlphaVariables alphaVars, MorphologicalTransform.RedupMorphType redupMorphType)
				: base (id, desc, morpher)
			{
				m_alphaVars = alphaVars;

				m_transform = new MorphologicalTransform(lhs, rhs, redupMorphType);

				// the LHS template is generated by simply concatenating all of the
				// LHS partitions; it matches the entire word, so we check for both the
				// left and right margins.
				m_lhsTemp = new PhoneticPattern();
				m_lhsTemp.Add(new MarginContext(Direction.LEFT));
				int partition = 0;
				foreach (PhoneticPattern pat in lhs)
				{
					m_lhsTemp.AddPartition(pat, partition, m_transform.IsGreedy(partition));
					partition++;
				}
				m_lhsTemp.Add(new MarginContext(Direction.RIGHT));
			}
Пример #4
0
		/// <summary>
		/// Initializes a new instance of the <see cref="MorphologicalTransform"/> class.
		/// </summary>
		/// <param name="lhs">The LHS.</param>
		/// <param name="rhs">The RHS.</param>
		public MorphologicalTransform(IEnumerable<PhoneticPattern> lhs, IEnumerable<MorphologicalOutput> rhs, RedupMorphType redupMorphType)
		{
			m_lhs = new List<PhoneticPattern>(lhs);
			m_rhs = new List<MorphologicalOutput>(rhs);
			m_modifyFromCtxts = new Dictionary<int, SimpleContext>();

			// reduplication flags for each morphological output record
			CheckReduplication(redupMorphType);

			m_rhsTemp = new PhoneticPattern();
			m_modifyFromCtxts = new Dictionary<int, SimpleContext>();
			m_rhsTemp.Add(new MarginContext(Direction.LEFT));
			for (int i = 0; i < m_rhs.Count; i++)
				m_rhs[i].GenerateRHSTemplate(m_rhsTemp, m_lhs, m_modifyFromCtxts);
			m_rhsTemp.Add(new MarginContext(Direction.RIGHT));
		}
Пример #5
0
			/// <summary>
			/// Checks for overlap of features between the specified simple context and the specified
			/// environment.
			/// </summary>
			/// <param name="ctxt">The simple context.</param>
			/// <param name="envSeq">The environment.</param>
			/// <returns>
			/// 	<c>true</c> if there is no overlap, otherwise <c>false</c>.
			/// </returns>
			bool IsNonSelfOpaquing(SimpleContext ctxt, PhoneticPattern env)
			{
				foreach (PhoneticPatternNode node in env)
				{
					switch (node.Type)
					{
						case PhoneticPatternNode.NodeType.SIMP_CTXT:
							SimpleContext envCtxt = node as SimpleContext;
							if (!envCtxt.FeatureValues.IsDisjoint(ctxt.AntiFeatureValues))
								return false;
							break;

						case PhoneticPatternNode.NodeType.BDRY_CTXT:
							break;

						case PhoneticPatternNode.NodeType.PATTERN:
							NestedPhoneticPattern optSeq = node as NestedPhoneticPattern;
							if (!IsNonSelfOpaquing(ctxt, optSeq.Pattern))
								return false;
							break;
					}
				}

				return true;
			}
Пример #6
0
		bool ProcessIterative(PhoneticShape input, Direction dir, PhoneticPattern ptemp, ModeType mode)
		{
			bool reordered = false;
			PhoneticShapeNode node = input.GetFirst(dir);
			Match match;
			// iterate thru each match
			while (FindNextMatch(node, dir, ptemp, mode, out match))
			{
				// reorder the matching segments
				Reorder(dir, match);
				reordered = true;
				IList<PhoneticShapeNode> nodes = match.EntireMatch;
				node = nodes[nodes.Count - 1].GetNext(dir);
			}

			return reordered;
		}
Пример #7
0
		bool FindNextMatch(PhoneticShapeNode node, Direction dir, PhoneticPattern ptemp, ModeType mode,
			out Match match)
		{
			for (; node != node.Owner.GetLast(dir); node = node.GetNext(dir))
			{
				if (mode == ModeType.ANALYSIS && node.Type == PhoneticShapeNode.NodeType.BOUNDARY)
					continue;

				IList<Match> matches;
				if (ptemp.IsMatch(node, dir, mode, out matches))
				{
					match = matches[0];
					return true;
				}
			}

			match = null;
			return false;
		}
Пример #8
0
		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;
				}
			}
		}
Пример #9
0
		/// <summary>
		/// Generates the RHS template of a morphological rule.
		/// </summary>
		/// <param name="rhsTemp">The RHS template.</param>
		/// <param name="lhs">The LHS.</param>
		/// <param name="modifyFromCtxts">The modify-from contexts.</param>
		/// <param name="redup">The reduplication flag.</param>
		public override void GenerateRHSTemplate(PhoneticPattern rhsTemp, IList<PhoneticPattern> lhs,
			IDictionary<int, SimpleContext> modifyFromCtxts)
		{
			// copy LHS partition over the RHS, only indicate the partition if this is
			// the first time this partition is being copied
			rhsTemp.AddPartition(lhs[m_partition], m_redup ? -1 : m_partition);
		}
Пример #10
0
		public void Reset()
		{
			m_multApplication = MultAppOrder.LR_ITERATIVE;
			m_alphaVars = null;
			m_lhs = null;
			m_subrules.Clear();
		}
Пример #11
0
		void LoadPSeq(PhoneticPattern pattern, XmlElement pseqNode, AlphaVariables alphaVars, Dictionary<string, string> varFeatIds,
			Dictionary<string, int> partIds)
		{
			if (pseqNode == null)
				return;

			foreach (XmlNode recNode in pseqNode.ChildNodes)
			{
				if (recNode.NodeType != XmlNodeType.Element)
					continue;

				XmlElement recElem = recNode as XmlElement;
				IEnumerable<PhoneticPatternNode> nodes = null;
				switch (recElem.Name)
				{
					case "SimpleContext":
						nodes = LoadNatClassCtxtPSeq(recElem, alphaVars, varFeatIds);
						break;

					case "BoundaryMarker":
						nodes = LoadBdryCtxt(recElem);
						break;

					case "Segment":
						nodes = LoadSegCtxt(recElem);
						break;

					case "OptionalSegmentSequence":
						nodes = LoadOptSeq(recElem, alphaVars, varFeatIds, pattern.IsTarget);
						break;

					case "Segments":
						nodes = LoadSegCtxts(recElem);
						break;
				}

				int partition = -1;
				string id = recElem.GetAttribute("id");
				if (partIds != null && !string.IsNullOrEmpty(id))
					partition = partIds[id];
				pattern.AddPartition(nodes, partition);
			}
		}
Пример #12
0
		PhoneticPattern GenerateChangePartition(PhoneticPattern lhs, PhoneticPattern rhs)
		{
			PhoneticPattern result = new PhoneticPattern();
			foreach (PhoneticPatternNode node in lhs)
			{
				switch (node.Type)
				{
					case PhoneticPatternNode.NodeType.SIMP_CTXT:
						PhoneticPattern temp = new PhoneticPattern();
						temp.Add(node.Clone());
						// generates the RHS template the same way that phonological rules generate their
						// RHS analysis targets
						result.AddMany(rhs.Combine(temp));
						break;

					case PhoneticPatternNode.NodeType.PATTERN:
						NestedPhoneticPattern nestedPattern = node as NestedPhoneticPattern;
						PhoneticPattern pattern = GenerateChangePartition(nestedPattern.Pattern, rhs);
						NestedPhoneticPattern newNestedPattern = new NestedPhoneticPattern(pattern, nestedPattern.MinOccur,
							nestedPattern.MaxOccur);
						result.Add(newNestedPattern);
						break;
				}
			}
			return result;
		}
Пример #13
0
		/// <summary>
		/// Generates the RHS template.
		/// </summary>
		/// <param name="rhsTemp">The RHS template.</param>
		/// <param name="lhs">The LHS.</param>
		/// <param name="modifyFromCtxts">The modify-from contexts.</param>
		/// <param name="redup">The reduplication flag.</param>
		public override void GenerateRHSTemplate(PhoneticPattern rhsTemp, IList<PhoneticPattern> lhs,
			IDictionary<int, SimpleContext> modifyFromCtxts)
		{
			for (PhoneticShapeNode node = m_pshape.Begin; node != m_pshape.Last; node = node.Next)
			{
				// create contexts from the segments and boundaries in the phonetic shape
				// and append them to the RHS template
				switch (node.Type)
				{
					case PhoneticShapeNode.NodeType.SEGMENT:
						rhsTemp.Add(new SegmentContext(node as Segment));
						break;

					case PhoneticShapeNode.NodeType.BOUNDARY:
						rhsTemp.Add(new BoundaryContext(node as Boundary));
						break;
				}
			}
		}
Пример #14
0
		/// <summary>
		/// Generates the RHS template of a morphological rule.
		/// </summary>
		/// <param name="rhsTemp">The RHS template.</param>
		/// <param name="lhs">The LHS.</param>
		/// <param name="modifyFromCtxts">The modify-from contexts.</param>
		/// <param name="redup">The reduplication flag.</param>
		public override void GenerateRHSTemplate(PhoneticPattern rhsTemp, IList<PhoneticPattern> lhs,
			IDictionary<int, SimpleContext> modifyFromCtxts)
		{
			PhoneticPattern ctxtPattern = new PhoneticPattern();
			ctxtPattern.Add(m_ctxt);
			// combines the simple context with all of the simple contexts on the LHS
			// and adds the results to the RHS template
			PhoneticPattern pattern = GenerateChangePartition(lhs[m_partition], ctxtPattern);
			rhsTemp.AddPartition(pattern, m_redup ? -1 : m_partition);
			// add context to the modify-from contexts
			modifyFromCtxts[m_partition] = m_ctxt;
		}
Пример #15
0
		/// <summary>
		/// Generates the RHS template of a morphological rule.
		/// </summary>
		/// <param name="rhsTemp">The RHS template.</param>
		/// <param name="lhs">The LHS.</param>
		/// <param name="modifyFromCtxts">The modify-from contexts.</param>
		/// <param name="redup">The reduplication flag.</param>
		public override void GenerateRHSTemplate(PhoneticPattern rhsTemp, IList<PhoneticPattern> lhs,
			IDictionary<int, SimpleContext> modifyFromCtxts)
		{
			rhsTemp.Add(m_ctxt.Clone());
		}
Пример #16
0
		void LoadPSubrule(XmlElement psubruleNode, StandardPhonologicalRule prule, Dictionary<string, string> varFeatIds)
		{
			XmlElement structElem = psubruleNode.SelectSingleNode("PhonologicalSubruleStructure[@isActive='yes']") as XmlElement;
			PhoneticPattern rhs = new PhoneticPattern(true);
			LoadPSeq(rhs, structElem.SelectSingleNode("PhoneticOutput/PhoneticSequence") as XmlElement, prule.AlphaVariables,
				varFeatIds, null);

			Environment env = LoadEnv(structElem.SelectSingleNode("Environment"), prule.AlphaVariables, varFeatIds);

			StandardPhonologicalRule.Subrule sr = null;
			try
			{
				sr = new StandardPhonologicalRule.Subrule(rhs, env, prule);
			}
			catch (ArgumentException ae)
			{
				LoadException le = new LoadException(LoadException.LoadErrorType.INVALID_SUBRULE_TYPE, this,
					HCStrings.kstidInvalidSubruleType, ae);
				le.Data["rule"] = prule.ID;
				throw le;
			}

			sr.RequiredPOSs = LoadPOSs(psubruleNode.GetAttribute("requiredPartsOfSpeech"));

			sr.RequiredMPRFeatures = LoadMPRFeatures(psubruleNode.GetAttribute("requiredMPRFeatures"));
			sr.ExcludedMPRFeatures = LoadMPRFeatures(psubruleNode.GetAttribute("excludedMPRFeatures"));

			prule.AddSubrule(sr);
		}
Пример #17
0
		PhoneticPattern LoadPTemp(XmlElement ptempNode, AlphaVariables varFeats, Dictionary<string, string> varFeatIds,
			Dictionary<string, int> partIds)
		{
			if (ptempNode == null)
				return null;

			bool initial = ptempNode.GetAttribute("initialBoundaryCondition") == "true";
			bool final = ptempNode.GetAttribute("finalBoundaryCondition") == "true";
			PhoneticPattern pattern = new PhoneticPattern();
			if (initial)
				pattern.Add(new MarginContext(Direction.LEFT));
			LoadPSeq(pattern, ptempNode.SelectSingleNode("PhoneticSequence") as XmlElement, varFeats,
				varFeatIds, partIds);
			if (final)
				pattern.Add(new MarginContext(Direction.RIGHT));

			return pattern;
		}
Пример #18
0
		IEnumerable<PhoneticPatternNode> LoadOptSeq(XmlElement optSeqNode, AlphaVariables varFeats,
			Dictionary<string, string> varFeatIds, bool isTarget)
		{
			string minStr = optSeqNode.GetAttribute("min");
			int min = string.IsNullOrEmpty(minStr) ? 0 : Convert.ToInt32(minStr);
			string maxStr = optSeqNode.GetAttribute("max");
			int max = string.IsNullOrEmpty(maxStr) ? -1 : Convert.ToInt32(maxStr);
			PhoneticPattern pattern = new PhoneticPattern(isTarget);
			LoadPSeq(pattern, optSeqNode, varFeats, varFeatIds, null);
			yield return new NestedPhoneticPattern(pattern, min, max);
		}
Пример #19
0
		/// <summary>
		/// Generates the RHS template of a morphological rule. If the record
		/// modifies the input using a simple context, it should add that context
		/// to varFeats of modify-from contexts. It is used during unapplication.
		/// The reduplication flags are used to indicate that the same input partition
		/// is being copied multiple times.
		/// </summary>
		/// <param name="rhsTemp">The RHS template.</param>
		/// <param name="lhs">The LHS.</param>
		/// <param name="modifyFromCtxts">The modify-from contexts.</param>
		/// <param name="redup">The reduplication flag.</param>
		public abstract void GenerateRHSTemplate(PhoneticPattern rhsTemp, IList<PhoneticPattern> lhs,
			IDictionary<int, SimpleContext> modifyFromCtxts);
Пример #20
0
		List<PhoneticPattern> LoadReqPhoneticInput(XmlNode reqPhonInputNode, int partition, AlphaVariables varFeats, Dictionary<string, string> varFeatIds,
			Dictionary<string, int> partIds)
		{
			List<PhoneticPattern> lhsList = new List<PhoneticPattern>();
			XmlNodeList pseqList = reqPhonInputNode.SelectNodes("PhoneticSequence");
			foreach (XmlNode pseqNode in pseqList)
			{
				XmlElement pseqElem = pseqNode as XmlElement;
				PhoneticPattern pattern = new PhoneticPattern();
				LoadPSeq(pattern, pseqElem, varFeats, varFeatIds, null);
				lhsList.Add(pattern);
				partIds[pseqElem.GetAttribute("id")] = partition++;
			}
			return lhsList;
		}